Trouble extracting data using DMIC

Hi there!

I am using the DMIC sample on a nrf5340dk. I have got it working, and now I want to develop it further. I want to record some sound and then transfer it to my PC. I have a lot of questions that I struggle with finding the answers to.

Now I understand that the data stored should already be stored as PCM data. So I can easily convert them to WAV files with a script on my PC. Is this correct?

When I record now I can leave it one for multiple seconds, but the data collected only corresponds to a few milliseconds. I suspect this is due to a lot of time being used logging to the console. The way I do it now, is that I log the collected data to the console, and then extract it onto the PC from there. However I can imagine this is quite slow. I was thinking of printing it out after the recording is done instead. But I struggle with understanding how the memory allocation in this sample works. I use:

void *buffer;

But this buffer get owerwritten with new data. How do I go about not overwriting the data and retrieving it later? (The recording does not need to be longer than a few seconds, maybe even shorter)

I also struggle with understanding the part the memory slab plays in the program. Defined as:

K_MEM_SLAB_DEFINE_STATIC(mem_slab, MAX_BLOCK_SIZE, BLOCK_COUNT, 4);
Parents
  • I have manged to access the data. What I really need is a way to quickly transfer the data to my PC, about 16000*2 = 32kbytes/sec (sampling frequency multiplied with bytes per sample). I was planning to log everything to a terminal window. But it seems like it can't keep up. I got the error:  --- 3171 messages dropped ---.

    Might it be possible to use UART for this? Or is there something else?

  • Hi 

    What is your UART baudrate? 

    32kBytes/sec equals 256 kbps, which means you need to use a baudrate that is at a minimum 288 kbaud (to make room for the stop bit). Realistically though I would recommend at least 460800 baud, to have some overhead. 

    Secondly, how do you output the data? 

    If you use the LOG API and convert the raw audio data to ASCII then you are multiplying the amount of data significantly, since each raw byte becomes multiple bytes over the UART. Then you will surely not have enough bandwidth. 

    But this buffer get owerwritten with new data. How do I go about not overwriting the data and retrieving it later? (The recording does not need to be longer than a few seconds, maybe even shorter)

    If you only need to store a couple of seconds of data you can copy it into a larger secondary buffer. If your math is correct then 3 seconds of data equals 96kB. The nRF5340 appcore has 512kB of RAM in total, so setting aside 96kB for data storage should be fine. 

    I also struggle with understanding the part the memory slab plays in the program. Defined as:

    The DMIC driver will use the memory slab to allocate buffers for the PDM interface automatically in the PDM event handler, to ensure that the buffers are provided fast enough to avoid gaps in the data. All the application has to do is to free the buffers again after the data is processed, which you can see in the do_pdm_transfer(..) function in main.c. 

    The documentation for the driver is a bit slim, so in order to check out the details of the implementation you might want to just look at the source, zephyr/drivers/audio/dmic_nrfx_pdm.c. For instance to see how the buffers are allocated you can have a look here

    Best regards
    Torbjørn

  • Hi Timon

    Sorry for the slow response, I just got back from vacation. 

    Are you still having issues with this? 

    Does the data look the same whether or not the PDM mic is connected? 

    The PDM interface is not able to detect if anything is connected or not, so the example should run just as well regardless, but the data should reflect the state of the pin (most likely permanently high or low, unless it is floating between the two states).

    Best regards
    Torbjørn 

  • Hi Torbjørn, no worries!
    I opened a seperate issue here: PDM / DMIC not giving any sensible output
    That is good to know that there is no data detection being made, then I probably just get random memory without anything connected.
    I poked around a bit more and am able to extract actual audio data but am still experiencing weird popping artifacts that overlay the recording and shift my samples "up".
    If you have seen that before any pointers would be useful, I'm pretty sure that its related to how I handle the buffer and the mic streaming.

  • Hi Timon

    The case should be assigned shortly. If you are still struggling with this after new year I can take a look at it also. In the mean time happy holidays Slight smile

    Best regards
    Torbjørn

  • Is there already a working solution for that issue? I am still struggling with the same problem

Reply Children
  • I had build a simple example that sends data out via Serial as ASCI HEX strings.
    It's not efficient but was an easy way for prototyping.
    You can find that project attached in this issue but I would recommend you use the fixed example Torbjørn posted in the accepted answer:
    RE: DMIC pop / click sounds between each memory block

    Just capture the Serial output on your computer and use the included Python script to convert it into raw PCM data that you can then import into Audacity or Adobe Audition for playback.

    If you get repeated data or junk data then you likely have a hardware issue, the pdm driver returns data no matter if there is a microphone attached or not, so you might just be reading whatever happens to be in uninitialized memory.

Related