Skip to content

Commit 25fbae0

Browse files
committed
dai-zephyr: use frames aligned for multi-endpoint copy
When aggregating streams using dai_zephyr_multi_endpoint_copy() multiple glitches observed in audio streams with odd number of channels. Use audio_stream_avail_frames_aligned() for every dai in a loop to correctly calculate processing frames. Signed-off-by: Ievgen Ganakov <ievgen.ganakov@intel.com>
1 parent 3da8e64 commit 25fbae0

File tree

2 files changed

+25
-23
lines changed

2 files changed

+25
-23
lines changed

src/audio/copier/copier_generic.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,8 @@ int create_endpoint_buffer(struct comp_dev *dev,
208208
audio_stream_set_buffer_fmt(&buffer->stream,
209209
copier_cfg->base.audio_fmt.interleaving_style);
210210

211+
audio_stream_set_align(1, 1, &buffer->stream);
212+
211213
for (i = 0; i < SOF_IPC_MAX_CHANNELS; i++)
212214
buffer->chmap[i] = (chan_map >> i * 4) & 0xf;
213215

src/audio/dai-zephyr.c

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1334,19 +1334,15 @@ int dai_zephyr_multi_endpoint_copy(struct dai_data **dd, struct comp_dev *dev,
13341334
struct comp_buffer *multi_endpoint_buffer,
13351335
int num_endpoints)
13361336
{
1337-
uint32_t avail_bytes = UINT32_MAX;
1338-
uint32_t free_bytes = UINT32_MAX;
1339-
uint32_t frames;
1340-
uint32_t src_frames, sink_frames;
13411337
uint32_t frame_bytes;
1338+
uint32_t frames_aligned;
1339+
uint32_t frames = UINT32_MAX;
13421340
int ret, i;
13431341
int direction;
13441342

13451343
if (!num_endpoints || !dd || !multi_endpoint_buffer)
13461344
return 0;
13471345

1348-
frame_bytes = audio_stream_frame_bytes(&dd[0]->dma_buffer->stream);
1349-
13501346
direction = dev->direction;
13511347

13521348
/* calculate min available/free from all endpoint DMA buffers */
@@ -1361,37 +1357,41 @@ int dai_zephyr_multi_endpoint_copy(struct dai_data **dd, struct comp_dev *dev,
13611357
case -EPIPE:
13621358
/* DMA status can return -EPIPE and current status content if xrun occurs */
13631359
if (direction == SOF_IPC_STREAM_PLAYBACK)
1364-
comp_dbg(dev, "dai_zephyr_multi_endpoint_copy(): dma_get_status() underrun occurred, endpoint: %d ret = %u",
1360+
comp_dbg(dev, "dma_get_status() underrun occurred endpoint: %d ret = %u",
13651361
i, ret);
13661362
else
1367-
comp_dbg(dev, "dai_zephyr_multi_endpoint_copy(): dma_get_status() overrun occurred, enpdoint: %d ret = %u",
1363+
comp_dbg(dev, "dma_get_status() overrun occurred, enpdoint: %d ret = %u",
13681364
i, ret);
13691365
break;
13701366
default:
13711367
return ret;
13721368
}
13731369

1374-
avail_bytes = MIN(avail_bytes, stat.pending_length);
1375-
free_bytes = MIN(free_bytes, stat.free);
1376-
}
1377-
1378-
/* calculate minimum size to copy */
1379-
if (direction == SOF_IPC_STREAM_PLAYBACK) {
1380-
src_frames = audio_stream_get_avail_frames(&multi_endpoint_buffer->stream);
1381-
sink_frames = free_bytes / frame_bytes;
1382-
} else {
1383-
src_frames = avail_bytes / frame_bytes;
1384-
sink_frames = audio_stream_get_free_frames(&multi_endpoint_buffer->stream);
1370+
/* Use frames_aligned here to avoid glitches, especially for streams
1371+
* with odd number of channels. Update frames for every dai in a loop.
1372+
*/
1373+
if (direction == SOF_IPC_STREAM_PLAYBACK)
1374+
frames_aligned =
1375+
audio_stream_avail_frames_aligned(&multi_endpoint_buffer->stream,
1376+
&dd[i]->dma_buffer->stream);
1377+
else
1378+
frames_aligned =
1379+
audio_stream_avail_frames_aligned(&dd[i]->dma_buffer->stream,
1380+
&multi_endpoint_buffer->stream);
1381+
frames = MIN(frames, frames_aligned);
13851382
}
13861383

1387-
frames = MIN(src_frames, sink_frames);
1388-
13891384
/* limit bytes per copy to one period for the whole pipeline in order to avoid high load
13901385
* spike if FAST_MODE is enabled, then one period limitation is omitted. All dd's have the
13911386
* same period_bytes, so use the period_bytes from dd[0]
13921387
*/
1393-
if (!(dd[0]->ipc_config.feature_mask & BIT(IPC4_COPIER_FAST_MODE)))
1394-
frames = MIN(frames, dd[0]->period_bytes / frame_bytes);
1388+
if (!dd[0]->fast_mode) {
1389+
size_t period_frames = dd[0]->period_bytes /
1390+
audio_stream_frame_bytes(&dd[0]->dma_buffer->stream);
1391+
if (period_frames < frames)
1392+
frames = period_frames;
1393+
}
1394+
13951395
comp_dbg(dev, "dai_zephyr_multi_endpoint_copy(), dir: %d copy frames= 0x%x",
13961396
dev->direction, frames);
13971397

0 commit comments

Comments
 (0)