cancel
Showing results for 
Search instead for 
Did you mean: 

STM32f4 DSP converting int16 to float32 results in very large values

DSimp.1
Associate III

Hello, I am trying to record MEMS microphone data using STM32F4-DISC board. I used BSP and CMSIS-DSP libraries to gather data and calculate FFT of recorded signal. I save my recordings in 
static q15_t TempBuffer[2048];  and I want to cinvert this buffer to float32_t type to pass it to  arm_rfft_fast_f32() func. I was trying to use this function arm_q15_to_float(TempBuffer, TempBuffer_f32, 2048); but the results are way off. TempBuffer values are going from 3276 to -3276 but after converting  it to  float, I get very large values (around 100000 larger), and after calculating FFT I get very large FFT amplitude values. I try to record Sin wave of a 1Khz. In TempBuffer I can see fluctating values, but FFT doesn't show any peaks. Any ideas how to correctly should I convert data? I will add  code where all the conversion is taking place:

#define TEMP_BUFFER_SIZE 2048 //Signal buffer for one channel
#define PCM_OUT_SIZE 16000/1000
#define INTERNAL_BUFF_SIZE 128*16000/16000*1

static uint16_t InternalBuffer[128*16000/16000*1];
static float32_t RecBuf[16000/1000*2];

static q15_t TempBuffer[2048]; // Temp int buffer
static float32_t TempBuffer_f32[2048] = {0}; // Temp float buffer
volatile uint32_t ITCounter = 0; //Counter for the transfer to OutputBuffer



void BSP_AUDIO_IN_HalfTransfer_CallBack(void)
{
/* PDM to PCM data convert */
BSP_AUDIO_IN_PDMToPCM((uint16_t*)&InternalBuffer[0], (uint16_t*)&RecBuf[0]);

/* Copy PCM data in internal buffer */
memcpy((uint16_t*)&TempBuffer[ITCounter * (PCM_OUT_SIZE*2)], RecBuf, PCM_OUT_SIZE*4);

if(ITCounter == (TEMP_BUFFER_SIZE/(PCM_OUT_SIZE*2))-1)
ITCounter = 0;
else
ITCounter++;
}

void BSP_AUDIO_IN_TransferComplete_CallBack(void)
{
/* PDM to PCM data convert */
BSP_AUDIO_IN_PDMToPCM((uint16_t*)&InternalBuffer[INTERNAL_BUFF_SIZE/2], (uint16_t*)&RecBuf[0]);

/* Copy PCM data in internal buffer */
memcpy((uint16_t*)&TempBuffer[ITCounter * (PCM_OUT_SIZE*2)], RecBuf, PCM_OUT_SIZE*4);

if(ITCounter == (TEMP_BUFFER_SIZE/(PCM_OUT_SIZE*2))-1) {
ITCounter = 0;

arm_q15_to_float(TempBuffer, TempBuffer_f32, TEMP_BUFFER_SIZE);
FFT_calculation(TempBuffer_f32);
}
else
ITCounter++;


HAL_GPIO_TogglePin(LD6_GPIO_Port, LD6_Pin);

}
2 REPLIES 2

There's a code posting tool click ... then </> icons

In i16 space q15 will span 32767 to -32768 which should translate to +1.0f to -1.0f in float space.

Your illustration / explanation is going to work a lot better if you dump the bytes in memory so this can be replicated.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
DSimp.1
Associate III

I will add variable values, maybe that would help:

DSimp1_0-1701885860807.pngDSimp1_1-1701885875455.png