Skip to content

Commit 2f8bcfd

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 65bad5c commit 2f8bcfd

File tree

2 files changed

+24
-23
lines changed

2 files changed

+24
-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: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1332,19 +1332,15 @@ int dai_zephyr_multi_endpoint_copy(struct dai_data **dd, struct comp_dev *dev,
13321332
struct comp_buffer *multi_endpoint_buffer,
13331333
int num_endpoints)
13341334
{
1335-
uint32_t avail_bytes = UINT32_MAX;
1336-
uint32_t free_bytes = UINT32_MAX;
1337-
uint32_t frames;
1338-
uint32_t src_frames, sink_frames;
13391335
uint32_t frame_bytes;
1336+
uint32_t frames_aligned;
1337+
uint32_t frames = UINT32_MAX;
13401338
int ret, i;
13411339
int direction;
13421340

13431341
if (!num_endpoints || !dd || !multi_endpoint_buffer)
13441342
return 0;
13451343

1346-
frame_bytes = audio_stream_frame_bytes(&dd[0]->dma_buffer->stream);
1347-
13481344
direction = dev->direction;
13491345

13501346
/* calculate min available/free from all endpoint DMA buffers */
@@ -1359,37 +1355,40 @@ int dai_zephyr_multi_endpoint_copy(struct dai_data **dd, struct comp_dev *dev,
13591355
case -EPIPE:
13601356
/* DMA status can return -EPIPE and current status content if xrun occurs */
13611357
if (direction == SOF_IPC_STREAM_PLAYBACK)
1362-
comp_dbg(dev, "dai_zephyr_multi_endpoint_copy(): dma_get_status() underrun occurred, endpoint: %d ret = %u",
1358+
comp_dbg(dev, "dma_get_status() underrun occurred endpoint: %d ret = %u",
13631359
i, ret);
13641360
else
1365-
comp_dbg(dev, "dai_zephyr_multi_endpoint_copy(): dma_get_status() overrun occurred, enpdoint: %d ret = %u",
1361+
comp_dbg(dev, "dma_get_status() overrun occurred, enpdoint: %d ret = %u",
13661362
i, ret);
13671363
break;
13681364
default:
13691365
return ret;
13701366
}
13711367

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

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

0 commit comments

Comments
 (0)