12s with DMA to play Audio in two ram buffers

Hi Nordic,

can you provide sample code on EasyDMA with I2S peripheral to play 120k audio with two ram buffers.

Parents
  • Check out this reply https://devzone.nordicsemi.com/support-private/support/282038#permalink=720949, where I point to some i2s samples. Find the sample that suits you the best and modify it according to your needs.

    Best regards,

    Simon

  •  audio data i taken in ram.

    like this way i am try to use ram buffers and play Audio .My audio configuration is 8kHz, stereo with 16 bits per sample.

    can you provide better solution for this Dma handling with two Ram buffers.

    Any and all advice would be highly helpful.

    int PlaybackPosition = I2S_DATA_BLOCK_WORDS;

    uint8_t Audio_data[]={0x52, 0x49, 0x46, 0x46, 0xC6, 0x07, 0x01, 0x00, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6D, 0x74, 0x20,
    0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x40, 0x1F, 0x00, 0x00, 0x00, 0x7D, 0x00, 0x00,
    0x04, 0x00, 0x10, 0x00, 0x00, 0x00, 0x64, 0x61, 0x74, 0x61, 0xA0, 0x07, 0x01, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,....}

    config.sdout_pin = I2S_SDOUT_PIN;
    config.sck_pin = I2S_CONFIG_SCK_PIN;
    config.lrck_pin = I2S_CONFIG_LRCK_PIN;
    config.mck_pin = I2S_CONFIG_MCK_PIN;
    config.mode = I2S_CONFIG_MODE_MODE_Master;
    config.alignment = I2S_CONFIG_ALIGN_ALIGN_Left; //it always should be in left_justified
    config.format = NRF_I2S_FORMAT_ALIGNED;
    config.sample_width = NRF_I2S_SWIDTH_16BIT;
    config.channels = I2S_CONFIG_CHANNELS_CHANNELS_Stereo;
    config.mck_setup = NRF_I2S_MCK_32MDIV8;
    config.ratio = NRF_I2S_RATIO_256X;              // it depends upon audio sample 8K,16K..
    config.channels = NRF_I2S_CHANNELS_STEREO;
    err_code = nrf_drv_i2s_init(&config, data_handler);
    APP_ERROR_CHECK(err_code);


    for (;;)
    {
    m_blocks_transferred = 0;
    mp_block_to_fill = NULL;

    /* Initialize the data buffer */
    for(uint16_t i=0; i < I2S_DATA_BLOCK_WORDS; i++)
    {

    m_buffer_tx[0][i]= *(Audio_data +i); 

    }
    nrf_drv_i2s_buffers_t const initial_buffers = {
    .p_tx_buffer = m_buffer_tx[0],
    .p_rx_buffer = NULL,
    };

    err_code = nrf_drv_i2s_start(&initial_buffers,512,0); //here starting the i2s
    APP_ERROR_CHECK(err_code);

    do {
    // Wait for an event.
    __WFE();
    // Clear the event register.
    __SEV();
    __WFE();

    /***********************************/
    if (mp_block_to_fill)
    {
    for(int i = 0; i < I2S_DATA_BLOCK_WORDS; i++)
    {
    m_buffer_tx[1][i] = *(Audio_data +PlaybackPosition);
    PlaybackPosition++;
    NRF_LOG_INFO("Loop buffer %04x", m_buffer_tx[1][i]);
    mp_block_to_fill = NULL;
    }
    ++m_blocks_transferred;

    }
    /*******************************/
    } while (m_blocks_transferred < BLOCKS_TO_TRANSFER);
    nrf_drv_i2s_stop();

    static void data_handler(nrf_drv_i2s_buffers_t const * p_released,
    uint32_t status)
    {
    // 'nrf_drv_i2s_next_buffers_set' is called directly from the handler
    // each time next buffers are requested, so data corruption is not
    // expected.
    ASSERT(p_released);

    // When the handler is called after the transfer has been stopped
    // (no next buffers are needed, only the used buffers are to be
    // released), there is nothing to do.
    if (!(status & NRFX_I2S_STATUS_NEXT_BUFFERS_NEEDED))
    {
    return;
    }

    // First call of this handler occurs right after the transfer is started.
    // No data has been transferred yet at this point, so there is nothing to
    // check. Only the buffers for the next part of the transfer should be
    // provided.
    if (!p_released->p_rx_buffer)
    {
    NRF_LOG_INFO("Next TX buffer.");

    nrf_drv_i2s_buffers_t const next_buffers = {
    .p_rx_buffer = NULL,
    .p_tx_buffer =m_buffer_tx[1],
    };
    APP_ERROR_CHECK(nrf_drv_i2s_next_buffers_set(&next_buffers));

    mp_block_to_fill =m_buffer_tx[1];
    }

    }

  • Hello, I'll just let you know that I'm working with setting together a simple sample.

    Best regards,

    Simon

  • Hello, got any progress?

    i2s_loopback.zip

    I'm trying to set up an I2S loopback sample (using two ram buffers) based on the test zephyr\tests\drivers\i2s\i2s_api\src\main.c, but I haven't been able to make it work quite yet. I'm not able to read out the data that is sent. However, I figured it was better to share something than nothing.

Reply Children
No Data
Related