Skip to content

Commit dae8b0b

Browse files
softwareckikv2019i
authored andcommitted
ring_buffer: Increase buffer size to prevent a DP module starvation
Increase buffer size to 3 times max_ibs_obs to prevent starving a DP module that process different block sizes in different periods (44.1 kHz case). Signed-off-by: Adrian Warecki <adrian.warecki@intel.com>
1 parent f4cd55c commit dae8b0b

1 file changed

Lines changed: 43 additions & 2 deletions

File tree

src/audio/buffers/ring_buffer.c

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -289,8 +289,49 @@ struct ring_buffer *ring_buffer_create(size_t min_available, size_t min_free_spa
289289

290290
uint32_t max_ibs_obs = MAX(min_available, min_free_space);
291291

292-
/* calculate required buffer size */
293-
ring_buffer->data_buffer_size = 2 * max_ibs_obs;
292+
/* Calculate required buffer size. This buffer must hold at least three times max_ibs_obs
293+
* bytes to avoid starving the DP modules that process different block sizes in different
294+
* periods (44.1 kHz case).
295+
*
296+
* The following example consists of one pipeline processed on core 0. One of the modules
297+
* of this pipeline is a DP module, which processing is performed on core 1.
298+
* DP module threads are started after LL processing on a given core is completed.
299+
*
300+
* An example of a DP module is src lite, which converts a 32-bit stereo stream with
301+
* a sampling rate of 44.1 kHz to a rate of 16 kHz. With a period of 1 ms, the module should
302+
* process 44.1 frames. In reality, this module processes 42 frames (336 bytes) for
303+
* 9 periods and then processes 63 frames (504 bytes) for the tenth period. In this way,
304+
* on average, over 10 periods, the module processes 44.1 frames.
305+
*
306+
* Consider the case of a 768-byte buffer (max_ibs_obs = 384) that is completely filled
307+
* with samples. In the first period, the module consumes 336 bytes. The buffer is not
308+
* replenished because the consumption occurred in the DP cycle, which is executed after
309+
* the LL cycle. Data is transferred between modules in the pipeline during the LL cycle.
310+
* The figure below shows the next period of the ongoing processing.
311+
*
312+
* /-----------------------------------------------------------------\
313+
* | Core 0 | [ LL 0 (B) ] [ DP 0 ] |
314+
* |------------------------------------------------------------------
315+
* | Core 1 | [ LL 1 ] (A) [ DP 1 ] (C) |
316+
* \-----------------------------------------------------------------/
317+
*
318+
* A. The DP module on core 1 has 432 bytes available in the input buffer, so it can only
319+
* process a block of 336 bytes. It is unable to process a block of 502 bytes.
320+
* The module starts processing data.
321+
*
322+
* B. Pipeline processing on core 0 reaches the point where more data is delivered to
323+
* the DP module source buffer, and processed data is received from the sink buffer.
324+
* The source buffer has 336 free bytes, and that is how many are copied.
325+
*
326+
* C. The DP module finishes processing data and flushes 336 bytes from the source buffer.
327+
* Since this buffer has just been completely filled, there are again left only
328+
* 432 bytes available at the end of the period.
329+
*
330+
* As shown in the above example, the DP module will eventually be starved, causing a glitch
331+
* in the output signal. To resolve this situation and allow the module to process
332+
* correctly, it is necessary to allocate a buffer three times larger than max_ibs_obs.
333+
*/
334+
ring_buffer->data_buffer_size = 3 * max_ibs_obs;
294335

295336
/* allocate data buffer - always in cached memory alias */
296337
ring_buffer->data_buffer_size =

0 commit comments

Comments
 (0)