BUFFER SIZE OF I2S

Hi Engineers,

I am developing an application which is kind of similar to an MP3 player.

I am reading an audio file of wav format from SD card using fatfs library f_read() function with buffer size of 1024 bytes.

and I am transmitting the buffer through i2s. What I found is the audio file is playing with more speed as expected and also experiencing

some pop and tick sounds. The clock configurations are all fine as LRCK is 44100, SWIDTH 16bit stereo.

I tried different sizes of buffer but still it didn't make any difference rather some speed variations.

Can anyone help me out solving this issue.

Thanks and regards,

Ajmal

Parents
  • Ajmal, 

    Can you post some code snippets on how you are using f_read? Is it being read in a timer callback or in the I2C interrupt context?

  • while(bytes_written < file_size[file_number])
    {
    
    ff_result = f_read(&file, (void *)Buff, sizeof(Buff), (UINT *)&bytes_written);
    if(ff_result != FR_OK)
    {
    NRF_LOG_RAW_INFO("%s", Buff);
    }
    
    prepare_tx_data(m_buffer_tx[0]);
    
    nrf_drv_i2s_buffers_t const initial_buffers = {
    .p_tx_buffer = m_buffer_tx[0]
    };
    
    err_code = nrf_drv_i2s_start(&initial_buffers,I2S_DATA_BLOCK_WORDS, 0);
    APP_ERROR_CHECK(err_code);
    
    file_size[file_number] -= bytes_written 
    }//end of for loop 2
    
    (void) f_close(&file);
    
    
    
    static void prepare_tx_data(uint32_t * p_block)
    {
    
    
    for ( uint32_t i = 0; i < I2S_DATA_BLOCK_WORDS; i++)
    {
    
    uint32_t * p_word = &p_block[i];
    ((uint32_t *)p_word)[0] = Buff[i];
    }
    
    }
    
    
    
    static void data_handler(nrf_i2s_event_t const * p_released,
    uint32_t status)
    {
    //handler for i2s_init
    
    if(NRF_I2S_EVENT_RXPTRUPD != 0)
    {
    prepare_tx_data(m_buffer_tx[0]);
    } 
    }

    Hi Susheel, 

    I am not using any timer. Please suggest me how it should be done.

    Thanks, and regards.

    Ajmal

  • You do  not seem to be waiting for the previous transaction to complete before initiating new transaction. 

    Can you replace your while loop like below to try to synchronize writes only when you know that there is a wakeup from I2S activity (assuming no other activity wakes your chip)

    do
    {
            // Wait for an event.
    		__WFE();
    		// Clear the event register.
    		__SEV();
    		__WFE();
    			
    		ff_result = f_read(&file, (void *)Buff, sizeof(Buff), (UINT *)&bytes_written);
    		if(ff_result != FR_OK)
    		{
    		NRF_LOG_RAW_INFO("%s", Buff);
    		}
    
    		prepare_tx_data(m_buffer_tx[0]);
    
    		nrf_drv_i2s_buffers_t const initial_buffers = {
    		.p_tx_buffer = m_buffer_tx[0]
    		};
    
    		err_code = nrf_drv_i2s_start(&initial_buffers,I2S_DATA_BLOCK_WORDS, 0);
    		APP_ERROR_CHECK(err_code);
    
    		file_size[file_number] -= bytes_written 
    }while(bytes_written < file_size[file_number])//end of for loop 2

Reply
  • You do  not seem to be waiting for the previous transaction to complete before initiating new transaction. 

    Can you replace your while loop like below to try to synchronize writes only when you know that there is a wakeup from I2S activity (assuming no other activity wakes your chip)

    do
    {
            // Wait for an event.
    		__WFE();
    		// Clear the event register.
    		__SEV();
    		__WFE();
    			
    		ff_result = f_read(&file, (void *)Buff, sizeof(Buff), (UINT *)&bytes_written);
    		if(ff_result != FR_OK)
    		{
    		NRF_LOG_RAW_INFO("%s", Buff);
    		}
    
    		prepare_tx_data(m_buffer_tx[0]);
    
    		nrf_drv_i2s_buffers_t const initial_buffers = {
    		.p_tx_buffer = m_buffer_tx[0]
    		};
    
    		err_code = nrf_drv_i2s_start(&initial_buffers,I2S_DATA_BLOCK_WORDS, 0);
    		APP_ERROR_CHECK(err_code);
    
    		file_size[file_number] -= bytes_written 
    }while(bytes_written < file_size[file_number])//end of for loop 2

Children
Related