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

USB Audio Half Used Packets

I am looking at the audio data received from USB.  Every packet is only half filled.  That is, the first 96 samples have valid data and the second 96 contain zeros.  I am using the usbd_audio project.  What is going on here?

This is stereo audio; every packet contains 48 samples of Left audio, 48 samples of Right audio, and 96 samples of zeros.  The Left and Right samples are interleaved every other sample.

Why are there 96 samples of zeros?

I am using SDK 15

  • Stereo.  When you do stereo the samples are interleaved.  Therefore, more specifically, the packet contains 48 samples of left and 48 samples of right.

  • Hi,

     

    Sorry for the late reply. Are you still seeing this issue?

    Which version of the nRF52840 are you using? Note that engineering A (pca10056 v0.9.x and lower) workarounds have been removed from SDK 15.

    Also, have you edited the example in any way? I see that all samples in the m_temp_buffer is filled up with non-zero values.

    The example is setup with a buffer size of 48 (times 2 for stereo, equals 192 bytes on the USB descriptor side), so I do not see how you should see 96 samples of zeroes unless the audio stream is such.

     

    Best regards,

    Håkon

  • Thanks for responding!  Yes, I am still seeing this.  I am thinking it is a matter of buffer size definition.

    I have only added code to aggregate the samples into a lager buffer.

    #define GRAB_DATA
    #ifdef GRAB_DATA
    static int16_t muchLargerBuffer[1000];
    static unsigned int bigCount = 0;
    static unsigned int smallCount = 0;
    #endif
    
    
    /**
     * @brief User event handler @ref app_usbd_audio_user_ev_handler_t (headphones)
     */
    static void hp_audio_user_ev_handler(app_usbd_class_inst_t const * p_inst,
                                         app_usbd_audio_user_event_t   event)
    {
        app_usbd_audio_t const * p_audio = app_usbd_audio_class_get(p_inst);
        UNUSED_VARIABLE(p_audio);
        switch (event)
        {
            case APP_USBD_AUDIO_USER_EVT_CLASS_REQ:
                hp_audio_user_class_req(p_inst);
                break;
            case APP_USBD_AUDIO_USER_EVT_RX_DONE:
            {
                ret_code_t ret;
                /* Block from headphones copied into buffer, send it into microphone input */
                #ifdef GRAB_DATA
                if(bigCount<99000){
                    bigCount += m_temp_buffer_size;
                }
                else if(bigCount<100000){
                    memcpy(muchLargerBuffer+smallCount, m_temp_buffer, m_temp_buffer_size);
                    bigCount += m_temp_buffer_size;
                    smallCount += m_temp_buffer_size;
                }
                else{
                    NRF_LOG_INFO("Stop Here!");
                }
                #endif
                ret = app_usbd_audio_class_tx_start(&m_app_audio_microphone.base, m_temp_buffer, m_temp_buffer_size);
                if (NRF_SUCCESS == ret)
                {
                    bsp_board_led_invert(LED_AUDIO_RX);
                }
                break;
            }
            default:
                break;
        }
    }

    The size of the buffer, m_temp_buffer, is 2*48=96 but the size of the data sent is 192.  More specifically, m_temp_buffer_size is found to be 192 when watched in the debugger.

    I see 192 pop up in one more place, at the audio class definition.  However, I am not sure what the "Endpoint size" is supposed to be the size of any way.

    So it looks like data I am getting delivered is 96 bytes in size, like I would expect, but the size that is sent through to the usbd audio class is double that, which doesn't make sense.

  • Hi,

     

    This is the code that fetches the EP size and sets 192 bytes to m_temp_buffer_size:

    size_t rx_size = app_usbd_audio_class_rx_size_get(&m_app_audio_headphone.base);
    m_temp_buffer_size = rx_size;

    Which in turn checks that specific endpoint and returns the OUT SIZE (read from NRF_USBD->SIZE.ISOOUT, since this is an isochronous transfer) which the PC sends:

    size_t app_usbd_audio_class_rx_size_get(app_usbd_class_inst_t const * p_inst)
    {
        nrf_drv_usbd_ep_t ep_addr;
    
        ep_addr = ep_iso_addr_get(p_inst);
        ASSERT(NRF_USBD_EPISO_CHECK(ep_addr));
    
        return (size_t)nrf_drv_usbd_epout_size_get(ep_addr);
    }

     

    Remember that "int16_t m_temp_buffer[96];" will be equal to 192 bytes in memory.

     

    Best regards,

    Håkon

Related