cancel
Showing results for 
Search instead for 
Did you mean: 

B-L4S5I-IOT01A - Record 16 kHz audio with DFSDM

Saeid
Visitor

Hi ST community,

I am using the B-L4S5I-IOT01A board to record 3 sec of 16 kHz audio using DFSDM + DMA, and then transmit it offline via UART (after recording is complete). Since two MP34DT01-M microphones are connected to DFSDM Channel 2, I configured Filter 0 to use only one microphone. I am using a Python script to receive the DFSDM data and save it in .WAV format. I am able to record 3 sec of audio; however, when I play the audio on my laptop, it seems to play at 10× speed.

Here is my code :

------------------------------------

#define SAMPLE_RATE 16000

#define RECORD_SECONDS 3

#define TOTAL_SAMPLES (SAMPLE_RATE * RECORD_SECONDS)

#define DFSDM_BUFFER_SIZE TOTAL_SAMPLES

#define UART_TX_TIMEOUT 1000

static int32_t dfsdm_rec_buf[DFSDM_BUFFER_SIZE]; // Raw 32-bit DFSDM samples

static int16_t audio_output[DFSDM_BUFFER_SIZE]; // 16-bit PCM samples

static volatile bool record_done = false;

 

extern DFSDM_Filter_HandleTypeDef hdfsdm1_filter0;

extern UART_HandleTypeDef huart1;

 

int16_t clamp(int32_t val, int32_t min, int32_t max) {

if (val < min) return min;

else if (val > max) return max;

return (int16_t)val;

}

 

// DMA complete callback

void HAL_DFSDM_FilterRegConvCpltCallback(DFSDM_Filter_HandleTypeDef *hdfsdm_filter) {

if (hdfsdm_filter == &hdfsdm1_filter0) {

record_done = true;

}

}

 

void StartMonoRecordingAndTransmitOffline(void) {

// Start DFSDM + DMA

if (HAL_DFSDM_FilterRegularStart_DMA(&hdfsdm1_filter0, dfsdm_rec_buf, DFSDM_BUFFER_SIZE) != HAL_OK) {

Error_Handler();

}

// Wait for 3 seconds of recording

while (!record_done);

 

// Stop DFSDM

HAL_DFSDM_FilterRegularStop_DMA(&hdfsdm1_filter0);

 

// Convert 24-bit DFSDM -> int16 PCM

for (uint32_t i = 0; i < DFSDM_BUFFER_SIZE; i++) {

audio_output[i] = clamp(dfsdm_rec_buf[i] >> 8, -32768, 32767);

}

 

// Transmit via UART in 512-sample chunks

for (uint32_t offset = 0; offset < DFSDM_BUFFER_SIZE; offset += 512) {

HAL_UART_Transmit(&huart1,

(uint8_t*)&audio_output[offset],

512 * sizeof(int16_t),

UART_TX_TIMEOUT);

HAL_Delay(100); // Prevent PC UART buffer overflow

}

 

record_done = false;

}

 

int main(void)

{

HAL_Init();

SystemClock_Config();

MX_GPIO_Init();

MX_DMA_Init();

MX_DFSDM1_Init();

MX_USART1_UART_Init();

 

HAL_Delay(500); // Optional: wait for PC UART terminal to get ready

StartMonoRecordingAndTransmitOffline();

 

while (1) {

 

}

}

 

Here is my DFSDM1 setting :

  • Source: System Clock: 80Mhz
  • Divider: 25 → 80 MHz / 25 = 3.2 MHz MIC_CLK
  • Oversampling: 200   
  • → 3.2 MHz / 200 = 16 kHz sample rate 

/* USER CODE END DFSDM1_Init 1 */

hdfsdm1_filter0.Instance = DFSDM1_Filter0;

hdfsdm1_filter0.Init.RegularParam.Trigger = DFSDM_FILTER_SW_TRIGGER;

hdfsdm1_filter0.Init.RegularParam.FastMode = DISABLE;

hdfsdm1_filter0.Init.RegularParam.DmaMode = ENABLE;

hdfsdm1_filter0.Init.FilterParam.SincOrder = DFSDM_FILTER_SINC3_ORDER;

hdfsdm1_filter0.Init.FilterParam.Oversampling = 200;

hdfsdm1_filter0.Init.FilterParam.IntOversampling = 1;

if (HAL_DFSDM_FilterInit(&hdfsdm1_filter0) != HAL_OK)

{

Error_Handler();

}

hdfsdm1_filter1.Instance = DFSDM1_Filter1;

hdfsdm1_filter1.Init.RegularParam.Trigger = DFSDM_FILTER_SW_TRIGGER;

hdfsdm1_filter1.Init.RegularParam.FastMode = DISABLE;

hdfsdm1_filter1.Init.RegularParam.DmaMode = DISABLE;

hdfsdm1_filter1.Init.InjectedParam.Trigger = DFSDM_FILTER_SW_TRIGGER;

hdfsdm1_filter1.Init.InjectedParam.ScanMode = DISABLE;

hdfsdm1_filter1.Init.InjectedParam.DmaMode = DISABLE;

hdfsdm1_filter1.Init.InjectedParam.ExtTrigger = DFSDM_FILTER_EXT_TRIG_TIM1_TRGO;

hdfsdm1_filter1.Init.InjectedParam.ExtTriggerEdge = DFSDM_FILTER_EXT_TRIG_RISING_EDGE;

hdfsdm1_filter1.Init.FilterParam.SincOrder = DFSDM_FILTER_FASTSINC_ORDER;

hdfsdm1_filter1.Init.FilterParam.Oversampling = 1;

hdfsdm1_filter1.Init.FilterParam.IntOversampling = 1;

if (HAL_DFSDM_FilterInit(&hdfsdm1_filter1) != HAL_OK)

{

Error_Handler();

}

hdfsdm1_channel2.Instance = DFSDM1_Channel2;

hdfsdm1_channel2.Init.OutputClock.Activation = ENABLE;

hdfsdm1_channel2.Init.OutputClock.Selection = DFSDM_CHANNEL_OUTPUT_CLOCK_SYSTEM;

hdfsdm1_channel2.Init.OutputClock.Divider = 25;

hdfsdm1_channel2.Init.Input.Multiplexer = DFSDM_CHANNEL_EXTERNAL_INPUTS;

hdfsdm1_channel2.Init.Input.DataPacking = DFSDM_CHANNEL_STANDARD_MODE;

hdfsdm1_channel2.Init.Input.Pins = DFSDM_CHANNEL_SAME_CHANNEL_PINS;

hdfsdm1_channel2.Init.SerialInterface.Type = DFSDM_CHANNEL_SPI_RISING;

hdfsdm1_channel2.Init.SerialInterface.SpiClock = DFSDM_CHANNEL_SPI_CLOCK_INTERNAL;

hdfsdm1_channel2.Init.Awd.FilterOrder = DFSDM_CHANNEL_FASTSINC_ORDER;

hdfsdm1_channel2.Init.Awd.Oversampling = 1;

hdfsdm1_channel2.Init.Offset = 0;

hdfsdm1_channel2.Init.RightBitShift = 8;

 

 

Can someone explain what might be causing this issue?

 

 

0 REPLIES 0