Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 22 additions & 5 deletions microphone/drv_audio_pdm.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "storage.h"
#include "audio_switch.h"
#include "sampling_lib.h"
#include "systick_lib.h"

ret_code_t err_code;

Expand All @@ -29,13 +30,13 @@ nrf_pdm_mode_t local_mode;
uint32_t local_freq;
uint8_t local_gain_l;
uint8_t local_gain_r;

uint64_t timestamp_buffer[PDM_BUF_NUM] = {0};

int16_t subsampled[PDM_BUF_SIZE/DECIMATION];
float filter_weight[DECIMATION];
static uint64_t recording_start_timestamp;


static void process_audio_buffer(void)
static void process_audio_buffer(uint8_t buffer_index)
{
switch (audio_switch_position)
{
Expand All @@ -47,6 +48,7 @@ static void process_audio_buffer(void)
{
data_source_info.data_source = AUDIO;
data_source_info.audio_source_info.audio_buffer_length = PDM_BUF_SIZE*2;
data_source_info.audio_source_info.buffer_index = buffer_index;
err_code = app_sched_event_put(&data_source_info, sizeof(data_source_info), sd_write);
APP_ERROR_CHECK(err_code);
}
Expand All @@ -69,6 +71,7 @@ static void process_audio_buffer(void)
}

data_source_info.data_source = AUDIO;
data_source_info.audio_source_info.buffer_index = buffer_index;
data_source_info.audio_source_info.audio_buffer = subsampled;
data_source_info.audio_source_info.audio_buffer_length = (PDM_BUF_SIZE/DECIMATION)*2; //sizeof(subsampled);
err_code = app_sched_event_put(&data_source_info, sizeof(data_source_info), sd_write);
Expand Down Expand Up @@ -101,8 +104,19 @@ static void drv_audio_pdm_event_handler(nrfx_pdm_evt_t const * const p_evt)
{
pdm_buf[l].released = true;
data_source_info.audio_source_info.audio_buffer = &pdm_buf[l].mic_buf;
if (l == 0 && timestamp_buffer[l] == 0) {
// First buffer, set timestamp to recording start timestamp
timestamp_buffer[l] = recording_start_timestamp;
} else {
// Subsequent buffers
// t_rec_i = t_release_i - (PDM_BUF_SIZE / effective_sampling_rate) * 1000
const uint32_t base_sample_rate = 20000; // 20kHz
uint64_t current_time = systick_get_millis();
uint32_t buffer_duration = (PDM_BUF_SIZE / base_sample_rate) * 1000;
Comment on lines +113 to +115
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sample rate can be a compile-time constant, and the result from the operation PDM_BUF_SIZE / base_sample_rate) * 1000 could be too due to const evaluation if this calc was in a macro instead.

Not functionally different but I would expect that to yield better performance by a slight margin.
Perhaps the calculation of these can be combined with this calculation: https://docs.nordicsemi.com/bundle/ps_nrf5340/page/pdm.html
you could move the value for pdfm_cfg.clock_freq in drv_audio_pdm.c to a define.

You could also take advantage that this now supports C23 and constexpr can be used

timestamp_buffer[l] = current_time - buffer_duration;
}
NRF_LOG_INFO("pdm buf %d", pdm_buf[l].mic_buf[0]);
process_audio_buffer();
process_audio_buffer(l);
break;
}
}
Expand All @@ -123,9 +137,11 @@ static void drv_audio_pdm_event_handler(nrfx_pdm_evt_t const * const p_evt)
}
}

ret_code_t drv_audio_init(nrf_pdm_mode_t mode)
ret_code_t drv_audio_init(nrf_pdm_mode_t mode, uint64_t timestamp)
{

recording_start_timestamp = timestamp;

switch (mode)
{
case 0: //stereo
Expand Down Expand Up @@ -165,6 +181,7 @@ ret_code_t drv_audio_init(nrf_pdm_mode_t mode)
//! position. The HW in the uC is designed for this frequency but Nordic
//! does not support it oficially as it's not considered tested enough
//! https://devzone.nordicsemi.com/f/nordic-q-a/15150/single-pdm-microphone-at-higher-pcm-sampling-rate
//! NOTE: Change the clock frequency in the `drv_audio_pdm_event_handler` function if this is changed.
pdm_cfg.clock_freq = 0x0A000000UL;
local_freq = pdm_cfg.clock_freq;

Expand Down
2 changes: 1 addition & 1 deletion microphone/drv_audio_pdm.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ int8_t drv_audio_get_gain_l(void);
int8_t drv_audio_get_gain_r(void);
int16_t drv_audio_get_pdm_freq(void);

ret_code_t drv_audio_init(nrf_pdm_mode_t mode);
ret_code_t drv_audio_init(nrf_pdm_mode_t mode, uint64_t timestamp);

#endif /* __DRV_AUDIO_PDM_H__ */
1 change: 1 addition & 0 deletions rythmbadge/request_handler_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ static ret_code_t receive_notification_fifo_peek(receive_notification_t* receive
}

uint8_t tmp[notification_size];
memset(tmp, 0, sizeof(tmp));
for(uint32_t i = 0; i < notification_size; i++) {
app_fifo_peek(&receive_notification_fifo, i + index*notification_size, &(tmp[i]));
}
Expand Down
6 changes: 5 additions & 1 deletion rythmbadge/sampling_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "led.h"

static sampling_configuration_t sampling_configuration;
extern uint64_t timestamp_buffer[PDM_BUF_NUM];

ret_code_t sampling_init(void)
{
Expand Down Expand Up @@ -104,7 +105,10 @@ ret_code_t sampling_start_microphone(nrf_pdm_mode_t mode)
if (audio_switch_get_position()==OFF)
return ret;

ret = drv_audio_init(mode);
memset(timestamp_buffer, 0, sizeof(timestamp_buffer));
uint64_t initial_recording_timestamp = systick_get_millis();

ret = drv_audio_init(mode, initial_recording_timestamp);
if(ret != NRF_SUCCESS) return ret;

ret = storage_open_file(AUDIO);
Expand Down
39 changes: 38 additions & 1 deletion sd_card/storage.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,10 @@ FATFS fs;
DIR dir;
FILINFO fno;
FIL audio_file_handle;
FIL audio_metadata_file_handle;
FIL imu_file_handle[MAX_IMU_SOURCES];
FIL scanner_file_handle;

extern uint64_t timestamp_buffer[PDM_BUF_NUM];

void sd_write(void * p_event_data, uint16_t event_size)
{
Expand All @@ -56,6 +57,20 @@ void sd_write(void * p_event_data, uint16_t event_size)
{
NRF_LOG_INFO("Audio write to sd failed: %d", ff_result);
}

if (!audio_metadata_file_handle.err)
{
audio_metadata_t audio_metadata_record;
audio_metadata_record.timestamp = timestamp_buffer[data_source_info.audio_source_info.buffer_index];

ff_result = f_write(&audio_metadata_file_handle, &audio_metadata_record, sizeof(audio_metadata_t), NULL);
if (ff_result != FR_OK)
{
NRF_LOG_INFO("Audio timestamp write to sd failed: %d", ff_result);
}
}


app_timer_stop(f_write_timeout_timer);
}
else if (data_source_info.data_source == IMU && !imu_file_handle[data_source_info.imu_source_info.imu_source].err)
Expand Down Expand Up @@ -102,6 +117,8 @@ static void f_sync_timeout_handler(void* p_context)
}
if (!audio_file_handle.err)
ff_result |= f_sync(&audio_file_handle);
if (!audio_metadata_file_handle.err)
ff_result |= f_sync(&audio_metadata_file_handle);
if (!scanner_file_handle.err)
ff_result |= f_sync(&scanner_file_handle);

Expand All @@ -123,6 +140,14 @@ uint32_t storage_close_file(data_source_t source)
NRF_LOG_INFO("close audio file error: %d", ff_result);
return -1;
}

audio_metadata_file_handle.err = 1;
ff_result = f_close(&audio_metadata_file_handle);
if (ff_result)
{
NRF_LOG_INFO("close audio timestamp file error: %d", ff_result);
return -1;
}
}
if (source == IMU)
{
Expand Down Expand Up @@ -288,6 +313,7 @@ uint32_t storage_init(void)
for (uint8_t sensor=0; sensor<MAX_IMU_SOURCES; sensor++)
imu_file_handle[sensor].err = 1;
audio_file_handle.err = 1;
audio_metadata_file_handle.err = 1;
scanner_file_handle.err = 1;
// Create the f_sync repeated timer
ret = app_timer_create(&f_sync_timer, APP_TIMER_MODE_REPEATED, f_sync_timeout_handler);
Expand Down Expand Up @@ -333,6 +359,7 @@ uint32_t storage_open_file(data_source_t source)
uint64_t millis = systick_get_millis();
uint32_t seconds = millis/1000;
TCHAR filename[50] = {};
TCHAR metadata_filename[55] = {};
NRF_LOG_INFO("SD: seconds: %ld", seconds);
NRF_LOG_INFO("SD: source: %d", source);
if (source == AUDIO)
Expand Down Expand Up @@ -366,6 +393,16 @@ uint32_t storage_open_file(data_source_t source)
return -1;
}
audio_file_handle.err = 0;

sprintf(metadata_filename, "%s.d", filename);
ff_result = f_open(&audio_metadata_file_handle, metadata_filename, FA_WRITE | FA_CREATE_ALWAYS);
NRF_LOG_INFO("SD Audio Metadata: ff_result: %d", ff_result);
if (ff_result != FR_OK)
{
NRF_LOG_INFO("SD Audio Metadata: Unable to open or create file: %d", metadata_filename);
return -1;
}
audio_metadata_file_handle.err = 0;
}
if (source == IMU)
{
Expand Down
5 changes: 5 additions & 0 deletions sd_card/storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,15 @@ typedef struct {
} imu_source_info_t;

typedef struct {
uint8_t buffer_index;
uint16_t audio_buffer_length;
const void * audio_buffer;
} audio_source_info_t;

typedef struct __attribute__((__packed__)) {
uint64_t timestamp;
} audio_metadata_t;

typedef struct __attribute__((__packed__)) {
data_source_t data_source;
union{
Expand Down