Skip to main content
Visitor II
July 29, 2025
Solved

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

  • July 29, 2025
  • 1 reply
  • 455 views

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?


Edited to apply source code formatting - please see How to insert source code for future reference.

    This topic has been closed for replies.
    Best answer by Saeid

    Hi @Saket_Om thank you so much for your reply. Actually, I was following this tutorial and I could manage to fix my problem.  Here is the link: TinyML - STM32 Audio Recording For Speech Recognition - Part 1 -
    My problem was RightShiftbit. I changed it from 0 to 0x03 and it fixed my issue. 

    1 reply

    Technical Moderator
    August 11, 2025

    Hello @Saeid 

    Is the sample rate parameter for the .WAV file in your Python script correctly set to 16,000 Hz?

    SaeidAuthorAnswer
    Visitor II
    August 24, 2025

    Hi @Saket_Om thank you so much for your reply. Actually, I was following this tutorial and I could manage to fix my problem.  Here is the link: TinyML - STM32 Audio Recording For Speech Recognition - Part 1 -
    My problem was RightShiftbit. I changed it from 0 to 0x03 and it fixed my issue.