cancel
Showing results for 
Search instead for 
Did you mean: 

How does PDM2PCM library works?

Riccardo Laiolo
Associate
Posted on February 04, 2018 at 19:07

Hi STCommunity, I'm using a Nucleo F446RE and I have to convert a PDM bitstream from a pair of mems microphones (CCA02M1 eval board) intoPCM. Does anyone know how the latest PDM2PCM library (rev. 3.0.0) works? The application note is updated to the rev. 1.0.0 (2011) and the latest revision is not backward compatible.

This is my filter setup code

hfilter.bit_order=PDM_FILTER_BIT_ORDER_MSB;// Source PDM stream format(?)
hfilter.endianness=PDM_FILTER_ENDIANNESS_LE;// F4 endianness (?)
hfilter.high_pass_tap=;// I have no clue how to set this
hfilter.in_ptr_channels=2;
hfilter.out_ptr_channels=2;
PDM_Filter_Init(&hfilter);
filtconf.decimation_factor=PDM_FILTER_DEC_FACTOR_128;// Target sample rate is 16kHz, PDM sample rate is 16k*128=2.048MHz
filtconf.mic_gain=0;
filtconf.output_samples_number=PCMbufflen/2;
PDM_Filter_setConfig(&hfilter, &filtconf);�?�?�?�?�?�?�?�?�?�?�?

I have some concerns about ... well, about everything.

I'm not sure about the endianness and the bit order parameters. I suppose they should be correct, but meh...

I have no clue at all how to set thehigh_pass_tap parameter.

Here is the main code. Data acquisition from I2S isin DMA circular mode on a buffer 2*I2Sbufflen long (the half transfer function is identical)

void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s)
{
uint32_t index = 0;
volatile uint16_t * DataTempI2S = &(I2S_InternalBuffer[I2Sbufflen]);
/* From bit interleaved buffer (DataTempI2S) to byte interleaved buffer (PDMbuff) */
/* (Copied from a working example) */
uint8_t a,b=0;
for(index=0; index<I2Sbufflen; index++) 
{
a = ((uint8_t *)(DataTempI2S))[(index*2)];
b = ((uint8_t *)(DataTempI2S))[(index*2)+1];
((uint8_t *)(PDMbuff))[(index*2)] = Channel_Demux[a & CHANNEL_DEMUX_MASK] | Channel_Demux[b & CHANNEL_DEMUX_MASK] << 4;;
((uint8_t *)(PDMbuff))[(index*2)+1] = Channel_Demux[(a>>1) & CHANNEL_DEMUX_MASK] |Channel_Demux[(b>>1) & CHANNEL_DEMUX_MASK] << 4;
}
/* -------------- */

uint8_t retval;
if ((retval = AudioProcess((uint16_t *)PDMbuff, (uint16_t *)PCMbuff))!=0)
{
HAL_UART_Transmit(&huart2,&A,1,1000);
}
else
{
/* uart bitrate = 921600bps, more than enough to stream the 16kHz PCM */
//HAL_UART_Transmit(&huart2,(uint8_t *)PCMbuff,sizeof(uint16_t)*32,1000);
HAL_UART_Transmit_DMA(&huart2,(uint8_t *)PCMbuff,PCMbufflen);
}
}

uint8_t AudioProcess(uint16_t *PDMBuf, uint16_t *PCMBuf)
{
PDM_Filter(PDMBuf,PCMBuf,&hfiltro); // PDM_Filter on even and odd bytes to convert both channels
return(PDM_Filter(PDMBuf+1,PCMBuf+1,&hfiltro)); // return PDM_Filter exit status
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

Recap, the main issues are:

- I can't figure what 'high_pass_tap' parameter does;

- Importing the serial dump file into audacity there is nothing that resemble the actual sound activity (me blowing into the microphones) and resetting the MCU the behaviour changes! Sometimes in the waveform there are the 'blobs' that could be me blowing but it's heavily distorted.

#pdm #stm32-f4 #pdm2pcm #audio-middleware
0 REPLIES 0