Page 1 of 1

I2S wrong buffering method

Posted: Sat Jul 06, 2019 9:35 pm
by philippe_44
I have an application that plays audio using I2S (I'm using the latest IDF on the master branch). It works, but I needed to dig into some details for my use case which requires audio synchronization and some of what I see in i2s.c makes no sense to me.

What I understand is that through i2s_drive_install, a series of buffers are created as well as a queue. The interrupt handler feeds the DMA with these buffers and every time it has consumed a buffer, it puts is to the queue.

When i2s_write is called, it looks at the current buffer and if it is full or none is available, it waits for one to be produced (as long as required by the tick_to_wait parameter).

Now, the logical behavior for an application is to be able to fill the set of buffer in a burst at the beginning and then call i2s_write with new data and be regulated by this call.

The problem I'm having is that the initialization code of i2s_driver_install or i2s_start does not queue ANY buffers to start with, so we start in a "full" position and a call to i2s_write will block on the queue waiting until the i2s handler produces ONE buffer (it's alos easy to verify by calling i2s_stop and trying i2s_write).

As a result, instead of being able to insert audio in a burst, we have to wait for the i2s DMA handler to insert AT LEAST one buffer in the queue and then we insert audio "at the pointy edge of real time". This is of course terrible for any application that does anything else than a busy loop calling i2s_write all the time. It very much negates the idea of a set of buffers.

Am I missing something or shouldn't all the buffers be inserted in the queue when the i2s_start is called? (or something similar)