Creating WAVE file from PCM data

Hi

I'm using the PDM module to capture audio through MP34DB02 PDM microphone (here's the datasheet). I set the clock frequency to default 1.032 MHz and a gain of +4 dB with mono configuration and left channel connection.

I get the PCM output to display through NUS and save the data as text file. I have validated the data and it reacts as I want it to. Now I need to figure out a way to save it as a .pcm file or convert the text file with the PCM output to a .pcm file and then to a .wav file.

I'm using a custom board based on nrf52832 board with SDK 17. Here's the code I put together based on things I learned on this forum and infocenter:

ret_code_t drv_audio_enable(void)
    {
        nrf_delay_ms(100);
        
        //Start audio capture
        return nrfx_pdm_start();
        
    }


ret_code_t drv_audio_disable(void)
    {
        ret_code_t status;

        //Stop audio capture
        status = nrfx_pdm_stop();
        if(status!= NRF_SUCCESS)
        {
          return status;
        }
                
        return NRF_SUCCESS;
    }


static void drv_audio_pdm_event_handler(nrfx_pdm_evt_t const * const p_evt)
{
      if(p_evt->buffer_requested)
      {
          nrfx_pdm_buffer_set(pdm_buf, CONFIG_PDM_BUFFER_SIZE_SAMPLES);
      }

      if(p_evt->buffer_released)
            { 
                for(i=0;i<DISP_BUFFER_SIZE;i++)
                {
                  disp_pdm_buf[i]=pdm_buf[i];
                }
            }
    
}


ret_code_t drv_audio_init()
{
    nrfx_pdm_config_t pdm_cfg = NRF_DRV_PDM_DEFAULT_CONFIG(clk_audio,dout);
                                                       
    ret_code_t err_code; // a variable to hold error code value
    pdm_cfg.gain_l      = CONFIG_PDM_GAIN;
    pdm_cfg.gain_r      = CONFIG_PDM_GAIN;
    pdm_cfg.edge        = NRF_PDM_EDGE_LEFTFALLING;
   
    
    nrf_gpio_cfg_output(lrsel);
    nrf_gpio_pin_clear(lrsel);
    
    //Initialize PDM driver
    nrfx_pdm_init(&pdm_cfg, drv_audio_pdm_event_handler);
}


/**@brief Application main function.
 */
int main(void)
{//1

    int count=1,i=0,j=0;
    nrf_gpio_pin_dir_set(ledPin,NRF_GPIO_PIN_DIR_OUTPUT);
    
    log_init();
    timers_init();
 
    power_management_init();
    ble_stack_init();
    gap_params_init();
    gatt_init();
    services_init();
    advertising_init();
    conn_params_init();

    advertising_start();
  

    nrf_delay_ms(3000);
    sprintf(lcdtext,"\n\n\tStarting application...\n");BLE_TEXT(lcdtext);
    nrf_delay_ms(1000);
    APP_ERROR_CHECK(drv_audio_init());
    
    drv_audio_enable();    
    nrf_delay_ms(2000);
    drv_audio_disable();
    
    for(i=0;i<DISP_BUFFER_SIZE;i++)
    { 
     sprintf(lcdtext,"%hx,",disp_pdm_buf[i]);BLE_TEXT(lcdtext);
    }

  }
}

This is the output I get for a 2 sec sampling:

13c,10d,9b,5f,fff8,ffb0,ffbf,ff2c,ff2a,ff0c,ff28,ff3c,ff78,ff88,ffbc,22,ffbf,ff3c,52,66,fff7,ff18,43,93,ffcb,ff59,ffec,119,1e,ff20,d5,165,fee9,ff8,ffaa,49,71,ff59,ffc1,ca,d9,ff98,ff36,b7,b4,ff8a,ffb7,e3,ff99,96,ff16,ff92,1c,ffaf,ff64,ff9f,f9,ffd8ff40,2d,115,70,ff60,d,63,ffb8,ff17,ff39,b5,5f,ff51,ff22,bd,ae,ff30,ff68,4b,b7,ff71,ff41,7a,8c,fed8,44,163,53,ffae,fef3,fff3,115,ff6e,ff4d,ffb,12d,ffbb,ff5c,ff43,d4,ffc1,ff7c,52,61,ff9c,ff0,ffb4,7b,ffcb,ff2,ff52,8e,28,ff45,ff6d,c1,c3,ff08,ffaa,d3,79,ff78,ffc1,ca,83,ff93,ff34,b7,b4,ffbc,ff30,ff94,ff99,96,ff8,ff2b,fc

Question 1: How do I convert this into a playable audio file from text? I tried saving the text file as a .pcm data and running it on Audacity on 8kHz sampling rate and 16 bit samples but can only hear noise. I found code to convert PCM data to WAVE format by using files but we can't create or access files through the microcontroller.

You need to sample at a rate of two times the highest frequency you intend to capture. With default decimation ratio of 64, we are sampling at 16.125 kHz for default clock frequency of 1.032 MHz. That would mean the highest frequency of data that can be captured with this setting is around 8kHz.

We can find the number samples created for each second of audio data as (sampling rate x no. of seconds) 

If the PCM output sampling rate by default is 16kHz, for 2 seconds, that would mean 32000 samples.

Question 2: Why am I not getting enough samples? Is there something wrong with the way I store and display the PCM data?

I tried going through the Thingy 52 and Smart Remote documentation but couldn't find anything I can use with the set-up we have. Could you point to any other resources that can help me with these issues? Thanks in anticipation.

Regards

Raj

Parents
  • Hi Raj

    I will help Håkon out with this case. 

    The PDM module is giving you the PCM data directly, no conversion is necessary. I believe the problem in your case is that you are converting the PCM samples to a text (ASCII) string, which will alter the data. 

    It should be possible to output the PCM data on the UART directly, so that you can simply open it as a PCM file in Audacity, but be aware that not all terminal applications are designed to be used with non ASCII data. You should try to find if there is a function in your terminal to store the incoming data as a binary file directly, without applying any string conversions, number formatting etc. 

    Question 2: Why am I not getting enough samples? Is there something wrong with the way I store and display the PCM data?

    To me it looks like you are just overwriting the values in the disp_pdm_buf buffer over and over each time the pdm event handler is called, and then after you are done sampling you will just print the final state of this buffer (which will be the last bytes of the 2 second sampling sequence). 

    Instead what you should do is create a larger buffer in the application, and copy data into a different part of the buffer each time the event handler is called. 

    I would also recommend using memcpy(..) to copy data from one buffer to the next, rather than running a for loop. 

    Best regards
    Torbjørn

  • Thanks for your response Torbjørn. I'll incorporate your suggestions and get back to you. Thank you.

    Regards

    Raj

  • Hi Raj

    I am happy to help. If you have more questions later on just let me know. 

    Best regards
    Torbjørn

  • My issue is similar
    I am using sd card to store the pcm data in a .pcm file and than playing that file on Audacity but either its noise or silence 
    It would be great if u can help me regarding this 
    I am attaching my code for reference.

    8345.inmp621_mic.zip

Reply Children
Related