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

Why Thingy52 PDM sample code skip buffer ?

I am using thing SDK. And,following function is part of thingy SDK.
Could someone can explain why the following function needs skip 31 times?

static void drv_audio_pdm_event_handler(uint32_t *p_buffer, uint16_t length)
{
    ASSERT(length == CONFIG_PDM_BUFFER_SIZE_SAMPLES);

    if (m_skip_buffers)  //m_skip_buffers-->31
    {
        m_skip_buffers -= 1;
    }
    else
    {
        m_buffer_handler((int16_t *)p_buffer, length);//static void m_audio_buffer_handler(int16_t *p_buffer, uint16_t samples)
    }
}

Parents
  • Hi

    The m_skip_buffers counter is controlled by the following define in drv_audio_config.h:

    // <o> PDM Microphone Transient State Length [ms] <1-1000>
    // <i> Set the length of the PDM microphone transient state. In this state, the microphone produces invalid data after wakeup or after it is powered on.
    #define CONFIG_PDM_TRANSIENT_STATE_LEN 500

    Apparently some of these PDM microphones need some time after startup before they produce valid data, so to avoid unwanted clicks or noise when starting the microphone it is necessary to ignore the first 500ms of audio data produced. 

    Best regards
    Torbjørn

  • Hi overbekk

    Thank's for your response.

    I have another question. How to verify the data via the oscilloscope.

    I am going to use following C code to explain my question.

    static int validdata = 0;
    static void m_audio_buffer_handler(int16_t *p_buffer, uint16_t samples)
    {
        uint32_t     err_code;
        pdm_buf_t  * p_pdm_buf = NULL;
        uint32_t     pdm_buf_addr;
    	
    
    int8_t *ptr = (int8_t *)p_buffer;
    if(validdata < 1){
    	NRF_LOG_INFO("[%d] 0x%04x 0x%04x 0x%04x 0x%04x\r\n", samples, *p_buffer , *(p_buffer+1) , *(p_buffer+2), *(p_buffer+3));
    }
    validdata++;
    
        for(uint32_t i = 0; i < PDM_BUF_NUM; i++)
        {
            if ( m_pdm_buf[i].free == true )
            {
                m_pdm_buf[i].free    = false;
                m_pdm_buf[i].samples = samples;
                for (uint32_t j = 0; j < samples; j++)
                {
                    m_pdm_buf[i].buf[j] = p_buffer[j];
                }
                p_pdm_buf = &m_pdm_buf[i];
                pdm_buf_addr = (uint32_t)&m_pdm_buf[i];
    
                break;
            }
        }
    
        if (p_pdm_buf != NULL)
        {
            err_code = app_sched_event_put(&pdm_buf_addr, sizeof(pdm_buf_t *), m_audio_process);
            APP_ERROR_CHECK(err_code);
        }
        else
        {
            NRF_LOG_INFO("m_audio_buffer_handler: BUFFER FULL!!\r\n");
        }
    }

    drv_audio_pdm_event_handler() will skip invalid data then send valid data to m_audio_buffer_handler() to process.

    When I get CLK and DIN via an occilloscope's trigger function these data are invalid at the beginning(microphone wake up). Because occilloscope's trigger function can not get valid data so can not verify thes data with print out information .

    So,How to verify CLK and DIN via the oscilloscope ?

  • Hi

    I am a bit unsure what you are trying to do. 

    Do you want to trigger the scope once the first valid data is sent from the microphone?

    If so maybe you could set a GPIO in the drv_audio_pdm_event_handler(..) function once the m_skip_buffers counter reaches 0, and use this signal to trigger the oscilloscope?

    Best regards
    Torbjørn

  • Hi Overbekk

    Yes, thank you. You provide a good idea for me. I will try it.

    Best regards

    Louis

Reply Children
  • Hi Louis

    The best of luck. Just let me know if you have more questions Slight smile

    Best regards
    Torbjørn

  • Hi Overbekk

    The microphone I use is STmicro MP23DB01HP (L/R connected to GND as mono Left)

    GPIO-40 pull high for the trigger valid data (Once the m_skip_buffers counter reaches 0)

     

    But the data received still cannot match the data shown in the scope.

    Is there anything miss?

    static int buf_cnt = 0;
    static void drv_audio_pdm_event_handler(uint32_t *p_buffer, uint16_t length)
    {
    
        ASSERT(length == CONFIG_PDM_BUFFER_SIZE_SAMPLES);
    
        if (m_skip_buffers)
        {
            m_skip_buffers -= 1;
    if(m_skip_buffers == 0){
    printf("PULL HIGH\r\n");
    nrf_gpio_pin_write(40,1);
    }
        }
        else
        {
    if(buf_cnt < 1){		
    printf("[%d] 0x%08x 0x%08x 0x%08x 0x%08x\r\n", length, p_buffer[0] , p_buffer[1] , p_buffer[2], p_buffer[3]);		
    }
            m_buffer_handler((int16_t *)p_buffer, length);//m_audio_buffer_handler(bufer,length)
    buf_cnt++;
        }
    }
    

    Consol message:

    PULL HIGH

    [256] 0x00d000cf 0x00cc00d0 0x00ce00d2 0x00c900cf

  • Hi Louis

    The input from the microphone is run through a decimation filter, to make what is essentially a high frequency 1-bit stream into 16-bit PCM samples. 

    For this reason the data you see reported from the PDM module  will not match the data you see on the bus. 

    There is some more information on the decimation filter here

    Best regards
    Torbjørn

  • Hi Overbekk

    Sorry I can not understand your mean totally.

    May I check with you agin that  *p_buffer of drv_audio_pdm_event_handler() is raw data from digital microphone(PDM interface) ?

    If so the single(green line) of  occilloscope must match with *p_buffer . May I right ?

    Another question:

    drv_mic_data_handler() function will send PCM data(I mean is data be Encode ?) via BLE  to cellphone?

    Best regards

    Louis

  • Hi Louis

    No, the data from the microphone, and the data output by the PDM peripheral, is not the same. 

    The 1-bit PDM data is run through a low pass filter and decimated to provide the 16-bit PCM output. 

    For more information about this please refer to this and this

    Louis Wnag said:
    drv_mic_data_handler() function will send PCM data(I mean is data be Encode ?) via BLE  to cellphone?

    Yes. The actual sending of PDM data over the Bluetooth link is handled by the ble_tss_mic_set(..) function, which is called from drv_mic_data_handler(). 

    Best regards
    Torbjørn

Related