This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nRFX based PDM to PCM implementation (I2S example)

Hello,

I am currently interfacing my nRF52840 DK with i2S based MP34DT05 sensor. I am using nrfx i2s driver's for interfacing with sensor. I am using master clk of 2MHz, LCLK 16KHZ. 

My sensor output PDM data. In my project I am recording audio samples on left channel, so I am currently getting 2*16bit of left data per 32bits as shown in nrf docs. I have got 16bit recorded samples in buffer, but to how to convert this pdm data in pcm format. 

Normally we need to divide the PDM data with a decimation factor, but in I2S we already are dividing the bit sampling rate with ratio value. So is the output from the I2S itself is decimated PCM ?  

Or can anyone give a example of how to convert the PDM to PCM data. Any sort of help is dually appreciated. 

Parents
No Data
Reply
  • If you find any bug in above code kindly mention or have any another tricks than please help because i can't recognize voice patterns just on the basis of 2-3 sec audio.

    I think it would make things easier if you use some data structures to help organize the PCM buffers. Specifically, I recommend using a memory slab for allocating PCM buffers, and a queue/FIFO to enqueue PCM buffers that have been filled.

    Let's say your algorithm runs on audio block sizes of 100 milliseconds, at 16 kHz sampling rate, this means each audio block is 3200 bytes. You would then define a memory slab of size X * 3200. X can be any number that fits within total memory. Note that it is probably best to define a struct for your audio data, which contains the int16_t audio buffer, plus the fifo_reserved data field, plus whatever else might be useful.

    In the PDM event hander, when a new buffer is requested, you try to allocate a new buffer from the slab (k_mem_slab_alloc). If this fails, you can log the error.

    In the PDM event handler, when a freshly filled buffer is released, you put the pointer to this buffer in the FIFO (k_fifo_put).

    Your algorithm can run as soon as there is one or more items in the FIFO (k_fifo_get).

    Once the algorithm has finished processing one audio buffer, it will release it back to the memory slab (k_mem_slab_free).

    This way your algorithm will always process the audio in order, and it is easy to see if you have a bottleneck somewhere.

    If you have multiple consumers of your audio data (e.g. local algorithm plus UART printout), this can be solved by adding a reference counter to the audio buffer struct.

Children
No Data
Related