cancel
Showing results for 
Search instead for 
Did you mean: 

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

Saeid
Associate

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.

1 ACCEPTED SOLUTION

Accepted Solutions

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. 

View solution in original post

2 REPLIES 2
Saket_Om
ST Employee

Hello @Saeid 

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

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Saket_Om

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.