From f4cfc7a791a41d3f867e2d3d33dcae7d270107d3 Mon Sep 17 00:00:00 2001 From: Serhiy Katsyuba Date: Tue, 21 Nov 2023 16:41:09 +0100 Subject: [PATCH 1/9] ipc4: mixin/mixout: Remove redundant mute channel impl Mute channel functionality was previously used as part of channel remapping feature. Since that feature was removed some time ago mute channel functionality is no longer used and is just a leftover from not fully completed cleanup. Signed-off-by: Serhiy Katsyuba --- src/audio/mixin_mixout/mixin_mixout.c | 5 +- src/audio/mixin_mixout/mixin_mixout.h | 24 ------ src/audio/mixin_mixout/mixin_mixout_generic.c | 73 +------------------ src/audio/mixin_mixout/mixin_mixout_hifi3.c | 65 +---------------- 4 files changed, 7 insertions(+), 160 deletions(-) diff --git a/src/audio/mixin_mixout/mixin_mixout.c b/src/audio/mixin_mixout/mixin_mixout.c index 0847007bfa40..c44d3fe14824 100644 --- a/src/audio/mixin_mixout/mixin_mixout.c +++ b/src/audio/mixin_mixout/mixin_mixout.c @@ -76,7 +76,6 @@ struct mixin_sink_config { /* mixin component private data */ struct mixin_data { normal_mix_func normal_mix_channel; - mute_func mute_channel; struct mixin_sink_config sink_config[MIXIN_MAX_SINKS]; }; @@ -510,7 +509,6 @@ static int mixin_reset(struct processing_module *mod) comp_dbg(dev, "mixin_reset()"); mixin_data->normal_mix_channel = NULL; - mixin_data->mute_channel = NULL; return 0; } @@ -636,14 +634,13 @@ static int mixin_prepare(struct processing_module *mod, case SOF_IPC_FRAME_S24_4LE: case SOF_IPC_FRAME_S32_LE: md->normal_mix_channel = normal_mix_get_processing_function(fmt); - md->mute_channel = mute_mix_get_processing_function(fmt); break; default: comp_err(dev, "unsupported data format %d", fmt); return -EINVAL; } - if (!md->normal_mix_channel || !md->mute_channel) { + if (!md->normal_mix_channel) { comp_err(dev, "have not found the suitable processing function"); return -EINVAL; } diff --git a/src/audio/mixin_mixout/mixin_mixout.h b/src/audio/mixin_mixout/mixin_mixout.h index 49184e2aa51b..c1fda1f46aff 100644 --- a/src/audio/mixin_mixout/mixin_mixout.h +++ b/src/audio/mixin_mixout/mixin_mixout.h @@ -110,19 +110,12 @@ typedef void (*normal_mix_func)(struct audio_stream *sink, int32_t start_frame, const struct audio_stream *source, int32_t frame_count, uint16_t gain); -/** - * \brief mixin_mixout mute processing function interface - */ -typedef void (*mute_func) (struct audio_stream *stream, int32_t channel_index, - int32_t start_frame, int32_t mixed_frames, int32_t frame_count); - /** * @brief mixin_mixout processing functions map. */ struct mix_func_map { uint16_t frame_fmt; /* frame format */ normal_mix_func normal_func; /* normal mode mixin_mixout processing function */ - mute_func mute_func; /* mute processing function */ }; extern const struct mix_func_map mix_func_map[]; @@ -144,21 +137,4 @@ static inline normal_mix_func normal_mix_get_processing_function(int fmt) return NULL; } -/** - * \brief Retrievies normal mode mixer processing function. - * \param[in] fmt stream PCM frame format - */ -static inline mute_func mute_mix_get_processing_function(int fmt) -{ - int i; - - /* map the mute function for source and sink buffers */ - for (i = 0; i < mix_count; i++) { - if (fmt == mix_func_map[i].frame_fmt) - return mix_func_map[i].mute_func; - } - - return NULL; -} - #endif /* __SOF_IPC4_MIXIN_MIXOUT_H__ */ diff --git a/src/audio/mixin_mixout/mixin_mixout_generic.c b/src/audio/mixin_mixout/mixin_mixout_generic.c index 793a7f5d12c7..bd7105823de9 100644 --- a/src/audio/mixin_mixout/mixin_mixout_generic.c +++ b/src/audio/mixin_mixout/mixin_mixout_generic.c @@ -61,38 +61,6 @@ static void normal_mix_channel_s16(struct audio_stream *sink, int32_t start_fram src += n; } } - -static void mute_channel_s16(struct audio_stream *stream, int32_t channel_index, - int32_t start_frame, int32_t mixed_frames, int32_t frame_count) -{ - int32_t skip_mixed_frames, n, left_frames, i, channel_count, frames, samples; - int16_t *ptr; - - assert(mixed_frames >= start_frame); - skip_mixed_frames = mixed_frames - start_frame; - - if (frame_count <= skip_mixed_frames) - return; - frame_count -= skip_mixed_frames; - channel_count = audio_stream_get_channels(stream); - /* audio_stream_wrap() is needed here and it is just below in a loop */ - ptr = (int16_t *)audio_stream_get_wptr(stream) + - mixed_frames * audio_stream_get_channels(stream) + - channel_index; - - for (left_frames = frame_count; left_frames; left_frames -= frames) { - ptr = audio_stream_wrap(stream, ptr); - n = audio_stream_samples_without_wrap_s16(stream, ptr); - samples = left_frames * channel_count; - n = MIN(samples, n); - frames = 0; - for (i = 0; i < n; i += channel_count) { - *ptr = 0; - ptr += channel_count; - frames++; - } - } -} #endif /* CONFIG_FORMAT_S16LE */ #if CONFIG_FORMAT_S24LE @@ -198,50 +166,15 @@ static void normal_mix_channel_s32(struct audio_stream *sink, int32_t start_fram #endif /* CONFIG_FORMAT_S32LE */ -#if CONFIG_FORMAT_S32LE || CONFIG_FORMAT_S24LE -static void mute_channel_s32(struct audio_stream *stream, int32_t channel_index, - int32_t start_frame, int32_t mixed_frames, int32_t frame_count) -{ - int32_t skip_mixed_frames, left_frames, n, channel_count, i, frames, samples; - int32_t *ptr; - - assert(mixed_frames >= start_frame); - skip_mixed_frames = mixed_frames - start_frame; - - if (frame_count <= skip_mixed_frames) - return; - frame_count -= skip_mixed_frames; - channel_count = audio_stream_get_channels(stream); - - ptr = (int32_t *)audio_stream_get_wptr(stream) + - mixed_frames * audio_stream_get_channels(stream) + - channel_index; - - for (left_frames = frame_count; left_frames > 0; left_frames -= frames) { - ptr = audio_stream_wrap(stream, ptr); - n = audio_stream_samples_without_wrap_s32(stream, ptr); - samples = left_frames * channel_count; - n = MIN(samples, n); - frames = 0; - for (i = 0; i < n; i += channel_count) { - *ptr = 0; - ptr += channel_count; - frames++; - } - } -} - -#endif - const struct mix_func_map mix_func_map[] = { #if CONFIG_FORMAT_S16LE - { SOF_IPC_FRAME_S16_LE, normal_mix_channel_s16, mute_channel_s16}, + { SOF_IPC_FRAME_S16_LE, normal_mix_channel_s16 }, #endif #if CONFIG_FORMAT_S24LE - { SOF_IPC_FRAME_S24_4LE, normal_mix_channel_s24, mute_channel_s32}, + { SOF_IPC_FRAME_S24_4LE, normal_mix_channel_s24 }, #endif #if CONFIG_FORMAT_S32LE - { SOF_IPC_FRAME_S32_LE, normal_mix_channel_s32, mute_channel_s32} + { SOF_IPC_FRAME_S32_LE, normal_mix_channel_s32 } #endif }; diff --git a/src/audio/mixin_mixout/mixin_mixout_hifi3.c b/src/audio/mixin_mixout/mixin_mixout_hifi3.c index c5a44251e335..636857790b1d 100644 --- a/src/audio/mixin_mixout/mixin_mixout_hifi3.c +++ b/src/audio/mixin_mixout/mixin_mixout_hifi3.c @@ -104,34 +104,6 @@ static void normal_mix_channel_s16(struct audio_stream *sink, int32_t start_fram } } } - -static void mute_channel_s16(struct audio_stream *stream, int32_t channel_index, - int32_t start_frame, int32_t mixed_frames, int32_t frame_count) -{ - int skip_mixed_frames, left_frames; - int off = audio_stream_get_channels(stream) * sizeof(ae_int16); - ae_int16 *ptr; - ae_int16x4 zero = AE_ZERO16(); - - assert(mixed_frames >= start_frame); - skip_mixed_frames = mixed_frames - start_frame; - - if (frame_count <= skip_mixed_frames) - return; - frame_count -= skip_mixed_frames; - - AE_SETCBEGIN0(audio_stream_get_addr(stream)); - AE_SETCEND0(audio_stream_get_end_addr(stream)); - - /* audio_stream_wrap() is needed here and it is just below in a loop */ - ptr = (ae_int16 *)audio_stream_get_wptr(stream) + - mixed_frames * audio_stream_get_channels(stream) + - channel_index; - ptr = audio_stream_wrap(stream, ptr); - - for (left_frames = frame_count ; left_frames; left_frames--) - AE_S16_0_XC(zero, ptr, off); -} #endif /* CONFIG_FORMAT_S16LE */ #if CONFIG_FORMAT_S24LE @@ -315,46 +287,15 @@ static void normal_mix_channel_s32(struct audio_stream *sink, int32_t start_fram #endif /* CONFIG_FORMAT_S32LE */ -#if CONFIG_FORMAT_S32LE || CONFIG_FORMAT_S24LE -static void mute_channel_s32(struct audio_stream *stream, int32_t channel_index, - int32_t start_frame, int32_t mixed_frames, int32_t frame_count) -{ - int skip_mixed_frames, left_frames; - ae_int32 *ptr; - int off = audio_stream_get_channels(stream) * sizeof(ae_int32); - ae_int32x2 zero = AE_ZERO32(); - - assert(mixed_frames >= start_frame); - skip_mixed_frames = mixed_frames - start_frame; - - if (frame_count <= skip_mixed_frames) - return; - frame_count -= skip_mixed_frames; - - AE_SETCBEGIN0(audio_stream_get_addr(stream)); - AE_SETCEND0(audio_stream_get_end_addr(stream)); - - /* audio_stream_wrap() is needed here and it is just below in a loop */ - ptr = (ae_int32 *)audio_stream_get_wptr(stream) + - mixed_frames * audio_stream_get_channels(stream) + - channel_index; - ptr = audio_stream_wrap(stream, ptr); - - for (left_frames = frame_count ; left_frames > 0; left_frames--) - AE_S32_L_XC(zero, ptr, off); -} - -#endif - const struct mix_func_map mix_func_map[] = { #if CONFIG_FORMAT_S16LE - { SOF_IPC_FRAME_S16_LE, normal_mix_channel_s16, mute_channel_s16}, + { SOF_IPC_FRAME_S16_LE, normal_mix_channel_s16 }, #endif #if CONFIG_FORMAT_S24LE - { SOF_IPC_FRAME_S24_4LE, normal_mix_channel_s24, mute_channel_s32}, + { SOF_IPC_FRAME_S24_4LE, normal_mix_channel_s24 }, #endif #if CONFIG_FORMAT_S32LE - { SOF_IPC_FRAME_S32_LE, normal_mix_channel_s32, mute_channel_s32} + { SOF_IPC_FRAME_S32_LE, normal_mix_channel_s32 } #endif }; From e0cc602b2fc84ed3be419dfa28c0f8c112399bca Mon Sep 17 00:00:00 2001 From: Serhiy Katsyuba Date: Tue, 21 Nov 2023 19:00:20 +0100 Subject: [PATCH 2/9] ipc4: mixin/mixout: Simplify naming after remapping mode been removed Previously we had "normal" and "channel remapping" modes. Since channel remapping mode was removed, "normal" is the only supported mode, no need to prepend names with "normal". Signed-off-by: Serhiy Katsyuba --- src/audio/mixin_mixout/mixin_mixout.c | 38 +++++++--------- src/audio/mixin_mixout/mixin_mixout.h | 24 +++++----- src/audio/mixin_mixout/mixin_mixout_generic.c | 45 +++++-------------- src/audio/mixin_mixout/mixin_mixout_hifi3.c | 45 +++++-------------- 4 files changed, 52 insertions(+), 100 deletions(-) diff --git a/src/audio/mixin_mixout/mixin_mixout.c b/src/audio/mixin_mixout/mixin_mixout.c index c44d3fe14824..b9efa59d0a60 100644 --- a/src/audio/mixin_mixout/mixin_mixout.c +++ b/src/audio/mixin_mixout/mixin_mixout.c @@ -75,7 +75,7 @@ struct mixin_sink_config { /* mixin component private data */ struct mixin_data { - normal_mix_func normal_mix_channel; + mix_func mix; struct mixin_sink_config sink_config[MIXIN_MAX_SINKS]; }; @@ -182,10 +182,10 @@ static int mixout_free(struct processing_module *mod) return 0; } -static int mix_and_remap(struct comp_dev *dev, const struct mixin_data *mixin_data, - uint16_t sink_index, struct audio_stream *sink, - uint32_t start_frame, uint32_t mixed_frames, - const struct audio_stream *source, uint32_t frame_count) +static int mix(struct comp_dev *dev, const struct mixin_data *mixin_data, + uint16_t sink_index, struct audio_stream *sink, + uint32_t start_frame, uint32_t mixed_frames, + const struct audio_stream *source, uint32_t frame_count) { const struct mixin_sink_config *sink_config; @@ -197,17 +197,11 @@ static int mix_and_remap(struct comp_dev *dev, const struct mixin_data *mixin_da sink_config = &mixin_data->sink_config[sink_index]; - /* Mix streams. mix_channel() is reused here to mix streams, not individual - * channels. To do so, (multichannel) stream is treated as single channel: - * channel count is passed as 1, channel index is 0, frame indices (start_frame - * and mixed_frame) and frame count are multiplied by real stream channel count. - */ - mixin_data->normal_mix_channel(sink, start_frame * audio_stream_get_channels(sink), - mixed_frames * audio_stream_get_channels(sink), - source, - frame_count * audio_stream_get_channels(sink), - sink_config->gain); - + mixin_data->mix(sink, start_frame * audio_stream_get_channels(sink), + mixed_frames * audio_stream_get_channels(sink), + source, + frame_count * audio_stream_get_channels(sink), + sink_config->gain); return 0; } @@ -395,9 +389,9 @@ static int mixin_process(struct processing_module *mod, * sink buffer has some data (written by another mixin) mix that data * with source data. */ - ret = mix_and_remap(dev, mixin_data, sinks_ids[i], &sink->stream, - start_frame, mixout_data->mixed_frames, - input_buffers[0].data, frames_to_copy); + ret = mix(dev, mixin_data, sinks_ids[i], &sink->stream, + start_frame, mixout_data->mixed_frames, + input_buffers[0].data, frames_to_copy); if (ret < 0) { return ret; } @@ -508,7 +502,7 @@ static int mixin_reset(struct processing_module *mod) comp_dbg(dev, "mixin_reset()"); - mixin_data->normal_mix_channel = NULL; + mixin_data->mix = NULL; return 0; } @@ -633,14 +627,14 @@ static int mixin_prepare(struct processing_module *mod, case SOF_IPC_FRAME_S16_LE: case SOF_IPC_FRAME_S24_4LE: case SOF_IPC_FRAME_S32_LE: - md->normal_mix_channel = normal_mix_get_processing_function(fmt); + md->mix = mixin_get_processing_function(fmt); break; default: comp_err(dev, "unsupported data format %d", fmt); return -EINVAL; } - if (!md->normal_mix_channel) { + if (!md->mix) { comp_err(dev, "have not found the suitable processing function"); return -EINVAL; } diff --git a/src/audio/mixin_mixout/mixin_mixout.h b/src/audio/mixin_mixout/mixin_mixout.h index c1fda1f46aff..3c6997b0f526 100644 --- a/src/audio/mixin_mixout/mixin_mixout.h +++ b/src/audio/mixin_mixout/mixin_mixout.h @@ -103,35 +103,35 @@ struct ipc4_mixer_mode_config { } __packed __aligned(4); /** - * \brief normal mode mixin_mixout processing function interface + * \brief mixin processing function interface */ -typedef void (*normal_mix_func)(struct audio_stream *sink, int32_t start_frame, - int32_t mixed_frames, - const struct audio_stream *source, - int32_t frame_count, uint16_t gain); +typedef void (*mix_func)(struct audio_stream *sink, int32_t start_frame, + int32_t mixed_frames, + const struct audio_stream *source, + int32_t frame_count, uint16_t gain); /** - * @brief mixin_mixout processing functions map. + * @brief mixin processing functions map. */ struct mix_func_map { - uint16_t frame_fmt; /* frame format */ - normal_mix_func normal_func; /* normal mode mixin_mixout processing function */ + uint16_t frame_fmt; /* frame format */ + mix_func func; /* mixin processing function */ }; extern const struct mix_func_map mix_func_map[]; extern const size_t mix_count; /** - * \brief Retrievies normal mode mixer processing function. + * \brief Retrievies mixin processing function. * \param[in] fmt stream PCM frame format */ -static inline normal_mix_func normal_mix_get_processing_function(int fmt) +static inline mix_func mixin_get_processing_function(int fmt) { int i; - /* map the normal mode mixin_mixout function for source and sink buffers */ + /* map mixin processing function for source and sink buffers */ for (i = 0; i < mix_count; i++) { if (fmt == mix_func_map[i].frame_fmt) - return mix_func_map[i].normal_func; + return mix_func_map[i].func; } return NULL; diff --git a/src/audio/mixin_mixout/mixin_mixout_generic.c b/src/audio/mixin_mixout/mixin_mixout_generic.c index bd7105823de9..04184a0d06bc 100644 --- a/src/audio/mixin_mixout/mixin_mixout_generic.c +++ b/src/audio/mixin_mixout/mixin_mixout_generic.c @@ -12,16 +12,9 @@ #ifdef MIXIN_MIXOUT_GENERIC #if CONFIG_FORMAT_S16LE -/* Instead of using audio_stream_get_channels(sink) and audio_stream_get_channels(source), - * sink_channel_count and source_channel_count are supplied as parameters. This is done to reuse - * the function to also mix an entire stream. In this case the function is called with fake stream - * parameters: multichannel stream is treated as single channel and so the entire stream - * contents is mixed. - */ -static void normal_mix_channel_s16(struct audio_stream *sink, int32_t start_frame, - int32_t mixed_frames, - const struct audio_stream *source, - int32_t frame_count, uint16_t gain) +static void mix_s16(struct audio_stream *sink, int32_t start_frame, int32_t mixed_frames, + const struct audio_stream *source, + int32_t frame_count, uint16_t gain) { int32_t frames_to_mix, frames_to_copy, left_frames; int32_t n, nmax, i; @@ -64,16 +57,9 @@ static void normal_mix_channel_s16(struct audio_stream *sink, int32_t start_fram #endif /* CONFIG_FORMAT_S16LE */ #if CONFIG_FORMAT_S24LE -/* Instead of using audio_stream_get_channels(sink) and audio_stream_get_channels(source), - * sink_channel_count and source_channel_count are supplied as parameters. This is done to reuse - * the function to also mix an entire stream. In this case the function is called with fake stream - * parameters: multichannel stream is treated as single channel and so the entire stream - * contents is mixed. - */ -static void normal_mix_channel_s24(struct audio_stream *sink, int32_t start_frame, - int32_t mixed_frames, - const struct audio_stream *source, - int32_t frame_count, uint16_t gain) +static void mix_s24(struct audio_stream *sink, int32_t start_frame, int32_t mixed_frames, + const struct audio_stream *source, + int32_t frame_count, uint16_t gain) { int32_t frames_to_mix, frames_to_copy, left_frames; int32_t n, nmax, i; @@ -116,16 +102,9 @@ static void normal_mix_channel_s24(struct audio_stream *sink, int32_t start_fram #endif /* CONFIG_FORMAT_S24LE */ #if CONFIG_FORMAT_S32LE -/* Instead of using audio_stream_get_channels(sink) and audio_stream_get_channels(source), - * sink_channel_count and source_channel_count are supplied as parameters. This is done to reuse - * the function to also mix an entire stream. In this case the function is called with fake stream - * parameters: multichannel stream is treated as single channel and so the entire stream - * contents is mixed. - */ -static void normal_mix_channel_s32(struct audio_stream *sink, int32_t start_frame, - int32_t mixed_frames, - const struct audio_stream *source, - int32_t frame_count, uint16_t gain) +static void mix_s32(struct audio_stream *sink, int32_t start_frame, int32_t mixed_frames, + const struct audio_stream *source, + int32_t frame_count, uint16_t gain) { int32_t frames_to_mix, frames_to_copy, left_frames; int32_t n, nmax, i; @@ -168,13 +147,13 @@ static void normal_mix_channel_s32(struct audio_stream *sink, int32_t start_fram const struct mix_func_map mix_func_map[] = { #if CONFIG_FORMAT_S16LE - { SOF_IPC_FRAME_S16_LE, normal_mix_channel_s16 }, + { SOF_IPC_FRAME_S16_LE, mix_s16 }, #endif #if CONFIG_FORMAT_S24LE - { SOF_IPC_FRAME_S24_4LE, normal_mix_channel_s24 }, + { SOF_IPC_FRAME_S24_4LE, mix_s24 }, #endif #if CONFIG_FORMAT_S32LE - { SOF_IPC_FRAME_S32_LE, normal_mix_channel_s32 } + { SOF_IPC_FRAME_S32_LE, mix_s32 } #endif }; diff --git a/src/audio/mixin_mixout/mixin_mixout_hifi3.c b/src/audio/mixin_mixout/mixin_mixout_hifi3.c index 636857790b1d..6b352f2a97e1 100644 --- a/src/audio/mixin_mixout/mixin_mixout_hifi3.c +++ b/src/audio/mixin_mixout/mixin_mixout_hifi3.c @@ -11,16 +11,9 @@ #ifdef MIXIN_MIXOUT_HIFI3 #if CONFIG_FORMAT_S16LE -/* Instead of using audio_stream_get_channels(sink) and audio_stream_get_channels(source), - * sink_channel_count and source_channel_count are supplied as parameters. This is done to reuse - * the function to also mix an entire stream. In this case the function is called with fake stream - * parameters: multichannel stream is treated as single channel and so the entire stream - * contents is mixed. - */ -static void normal_mix_channel_s16(struct audio_stream *sink, int32_t start_frame, - int32_t mixed_frames, - const struct audio_stream *source, - int32_t frame_count, uint16_t gain) +static void mix_s16(struct audio_stream *sink, int32_t start_frame, int32_t mixed_frames, + const struct audio_stream *source, + int32_t frame_count, uint16_t gain) { int frames_to_mix, frames_to_copy, left_frames; int n, nmax, i, m, left; @@ -107,16 +100,9 @@ static void normal_mix_channel_s16(struct audio_stream *sink, int32_t start_fram #endif /* CONFIG_FORMAT_S16LE */ #if CONFIG_FORMAT_S24LE -/* Instead of using audio_stream_get_channels(sink) and audio_stream_get_channels(source), - * sink_channel_count and source_channel_count are supplied as parameters. This is done to reuse - * the function to also mix an entire stream. In this case the function is called with fake stream - * parameters: multichannel stream is treated as single channel and so the entire stream - * contents is mixed. - */ -static void normal_mix_channel_s24(struct audio_stream *sink, int32_t start_frame, - int32_t mixed_frames, - const struct audio_stream *source, - int32_t frame_count, uint16_t gain) +static void mix_s24(struct audio_stream *sink, int32_t start_frame, int32_t mixed_frames, + const struct audio_stream *source, + int32_t frame_count, uint16_t gain) { int frames_to_mix, frames_to_copy, left_frames; int n, nmax, i, m, left; @@ -197,16 +183,9 @@ static void normal_mix_channel_s24(struct audio_stream *sink, int32_t start_fram #endif /* CONFIG_FORMAT_S24LE */ #if CONFIG_FORMAT_S32LE -/* Instead of using audio_stream_get_channels(sink) and audio_stream_get_channels(source), - * sink_channel_count and source_channel_count are supplied as parameters. This is done to reuse - * the function to also mix an entire stream. In this case the function is called with fake stream - * parameters: multichannel stream is treated as single channel and so the entire stream - * contents is mixed. - */ -static void normal_mix_channel_s32(struct audio_stream *sink, int32_t start_frame, - int32_t mixed_frames, - const struct audio_stream *source, - int32_t frame_count, uint16_t gain) +static void mix_s32(struct audio_stream *sink, int32_t start_frame, int32_t mixed_frames, + const struct audio_stream *source, + int32_t frame_count, uint16_t gain) { int frames_to_mix, frames_to_copy, left_frames; int n, nmax, i, m, left; @@ -289,13 +268,13 @@ static void normal_mix_channel_s32(struct audio_stream *sink, int32_t start_fram const struct mix_func_map mix_func_map[] = { #if CONFIG_FORMAT_S16LE - { SOF_IPC_FRAME_S16_LE, normal_mix_channel_s16 }, + { SOF_IPC_FRAME_S16_LE, mix_s16 }, #endif #if CONFIG_FORMAT_S24LE - { SOF_IPC_FRAME_S24_4LE, normal_mix_channel_s24 }, + { SOF_IPC_FRAME_S24_4LE, mix_s24 }, #endif #if CONFIG_FORMAT_S32LE - { SOF_IPC_FRAME_S32_LE, normal_mix_channel_s32 } + { SOF_IPC_FRAME_S32_LE, mix_s32 } #endif }; From bef97e92a84113e3c4522167c5e2404c29cfe2a2 Mon Sep 17 00:00:00 2001 From: Serhiy Katsyuba Date: Wed, 22 Nov 2023 12:59:33 +0100 Subject: [PATCH 3/9] ipc4: mixin/mixout: Fix naming after channel remapping removal Previously when channel remapping was supported processing was done iterating by frames. After channel remapping was removed processing was changed to iterate by samples, however, for some reason the code still uses confusing "frame" variables. Signed-off-by: Serhiy Katsyuba --- src/audio/mixin_mixout/mixin_mixout.h | 6 +- src/audio/mixin_mixout/mixin_mixout_generic.c | 72 +++++++++---------- src/audio/mixin_mixout/mixin_mixout_hifi3.c | 66 ++++++++--------- 3 files changed, 72 insertions(+), 72 deletions(-) diff --git a/src/audio/mixin_mixout/mixin_mixout.h b/src/audio/mixin_mixout/mixin_mixout.h index 3c6997b0f526..6b097df99b16 100644 --- a/src/audio/mixin_mixout/mixin_mixout.h +++ b/src/audio/mixin_mixout/mixin_mixout.h @@ -105,10 +105,10 @@ struct ipc4_mixer_mode_config { /** * \brief mixin processing function interface */ -typedef void (*mix_func)(struct audio_stream *sink, int32_t start_frame, - int32_t mixed_frames, +typedef void (*mix_func)(struct audio_stream *sink, int32_t start_sample, + int32_t mixed_samples, const struct audio_stream *source, - int32_t frame_count, uint16_t gain); + int32_t sample_count, uint16_t gain); /** * @brief mixin processing functions map. diff --git a/src/audio/mixin_mixout/mixin_mixout_generic.c b/src/audio/mixin_mixout/mixin_mixout_generic.c index 04184a0d06bc..3c9895d18d45 100644 --- a/src/audio/mixin_mixout/mixin_mixout_generic.c +++ b/src/audio/mixin_mixout/mixin_mixout_generic.c @@ -12,28 +12,28 @@ #ifdef MIXIN_MIXOUT_GENERIC #if CONFIG_FORMAT_S16LE -static void mix_s16(struct audio_stream *sink, int32_t start_frame, int32_t mixed_frames, +static void mix_s16(struct audio_stream *sink, int32_t start_sample, int32_t mixed_samples, const struct audio_stream *source, - int32_t frame_count, uint16_t gain) + int32_t sample_count, uint16_t gain) { - int32_t frames_to_mix, frames_to_copy, left_frames; + int32_t samples_to_mix, samples_to_copy, left_samples; int32_t n, nmax, i; /* audio_stream_wrap() is required and is done below in a loop */ - int16_t *dst = (int16_t *)audio_stream_get_wptr(sink) + start_frame; + int16_t *dst = (int16_t *)audio_stream_get_wptr(sink) + start_sample; int16_t *src = audio_stream_get_rptr(source); - assert(mixed_frames >= start_frame); - frames_to_mix = mixed_frames - start_frame; - frames_to_mix = MIN(frames_to_mix, frame_count); - frames_to_copy = frame_count - frames_to_mix; + assert(mixed_samples >= start_sample); + samples_to_mix = mixed_samples - start_sample; + samples_to_mix = MIN(samples_to_mix, sample_count); + samples_to_copy = sample_count - samples_to_mix; - for (left_frames = frames_to_mix; left_frames > 0; left_frames -= n) { + for (left_samples = samples_to_mix; left_samples > 0; left_samples -= n) { src = audio_stream_wrap(source, src); dst = audio_stream_wrap(sink, dst); /* calculate the remaining samples*/ nmax = audio_stream_samples_without_wrap_s16(source, src); - n = MIN(left_frames, nmax); + n = MIN(left_samples, nmax); nmax = audio_stream_samples_without_wrap_s16(sink, dst); n = MIN(n, nmax); for (i = 0; i < n; i++) { @@ -42,11 +42,11 @@ static void mix_s16(struct audio_stream *sink, int32_t start_frame, int32_t mixe } } - for (left_frames = frames_to_copy; left_frames > 0; left_frames -= n) { + for (left_samples = samples_to_copy; left_samples > 0; left_samples -= n) { src = audio_stream_wrap(source, src); dst = audio_stream_wrap(sink, dst); nmax = audio_stream_samples_without_wrap_s16(source, src); - n = MIN(left_frames, nmax); + n = MIN(left_samples, nmax); nmax = audio_stream_samples_without_wrap_s16(sink, dst); n = MIN(n, nmax); memcpy_s(dst, n * sizeof(int16_t), src, n * sizeof(int16_t)); @@ -57,27 +57,27 @@ static void mix_s16(struct audio_stream *sink, int32_t start_frame, int32_t mixe #endif /* CONFIG_FORMAT_S16LE */ #if CONFIG_FORMAT_S24LE -static void mix_s24(struct audio_stream *sink, int32_t start_frame, int32_t mixed_frames, +static void mix_s24(struct audio_stream *sink, int32_t start_sample, int32_t mixed_samples, const struct audio_stream *source, - int32_t frame_count, uint16_t gain) + int32_t sample_count, uint16_t gain) { - int32_t frames_to_mix, frames_to_copy, left_frames; + int32_t samples_to_mix, samples_to_copy, left_samples; int32_t n, nmax, i; /* audio_stream_wrap() is required and is done below in a loop */ - int32_t *dst = (int32_t *)audio_stream_get_wptr(sink) + start_frame; + int32_t *dst = (int32_t *)audio_stream_get_wptr(sink) + start_sample; int32_t *src = audio_stream_get_rptr(source); - assert(mixed_frames >= start_frame); - frames_to_mix = mixed_frames - start_frame; - frames_to_mix = MIN(frames_to_mix, frame_count); - frames_to_copy = frame_count - frames_to_mix; + assert(mixed_samples >= start_sample); + samples_to_mix = mixed_samples - start_sample; + samples_to_mix = MIN(samples_to_mix, sample_count); + samples_to_copy = sample_count - samples_to_mix; - for (left_frames = frames_to_mix; left_frames > 0; left_frames -= n) { + for (left_samples = samples_to_mix; left_samples > 0; left_samples -= n) { src = audio_stream_wrap(source, src); dst = audio_stream_wrap(sink, dst); /* calculate the remaining samples*/ nmax = audio_stream_samples_without_wrap_s24(source, src); - n = MIN(left_frames, nmax); + n = MIN(left_samples, nmax); nmax = audio_stream_samples_without_wrap_s24(sink, dst); n = MIN(n, nmax); for (i = 0; i < n; i++) { @@ -86,11 +86,11 @@ static void mix_s24(struct audio_stream *sink, int32_t start_frame, int32_t mixe } } - for (left_frames = frames_to_copy; left_frames > 0; left_frames -= n) { + for (left_samples = samples_to_copy; left_samples > 0; left_samples -= n) { src = audio_stream_wrap(source, src); dst = audio_stream_wrap(sink, dst); nmax = audio_stream_samples_without_wrap_s24(source, src); - n = MIN(left_frames, nmax); + n = MIN(left_samples, nmax); nmax = audio_stream_samples_without_wrap_s24(sink, dst); n = MIN(n, nmax); memcpy_s(dst, n * sizeof(int32_t), src, n * sizeof(int32_t)); @@ -102,26 +102,26 @@ static void mix_s24(struct audio_stream *sink, int32_t start_frame, int32_t mixe #endif /* CONFIG_FORMAT_S24LE */ #if CONFIG_FORMAT_S32LE -static void mix_s32(struct audio_stream *sink, int32_t start_frame, int32_t mixed_frames, +static void mix_s32(struct audio_stream *sink, int32_t start_sample, int32_t mixed_samples, const struct audio_stream *source, - int32_t frame_count, uint16_t gain) + int32_t sample_count, uint16_t gain) { - int32_t frames_to_mix, frames_to_copy, left_frames; + int32_t samples_to_mix, samples_to_copy, left_samples; int32_t n, nmax, i; - int32_t *dst = (int32_t *)audio_stream_get_wptr(sink) + start_frame; + int32_t *dst = (int32_t *)audio_stream_get_wptr(sink) + start_sample; int32_t *src = audio_stream_get_rptr(source); - assert(mixed_frames >= start_frame); - frames_to_mix = mixed_frames - start_frame; - frames_to_mix = MIN(frames_to_mix, frame_count); - frames_to_copy = frame_count - frames_to_mix; + assert(mixed_samples >= start_sample); + samples_to_mix = mixed_samples - start_sample; + samples_to_mix = MIN(samples_to_mix, sample_count); + samples_to_copy = sample_count - samples_to_mix; - for (left_frames = frames_to_mix; left_frames > 0; left_frames -= n) { + for (left_samples = samples_to_mix; left_samples > 0; left_samples -= n) { src = audio_stream_wrap(source, src); dst = audio_stream_wrap(sink, dst); /* calculate the remaining samples*/ nmax = audio_stream_samples_without_wrap_s32(source, src); - n = MIN(left_frames, nmax); + n = MIN(left_samples, nmax); nmax = audio_stream_samples_without_wrap_s32(sink, dst); n = MIN(n, nmax); for (i = 0; i < n; i++) { @@ -130,11 +130,11 @@ static void mix_s32(struct audio_stream *sink, int32_t start_frame, int32_t mixe } } - for (left_frames = frames_to_copy; left_frames > 0; left_frames -= n) { + for (left_samples = samples_to_copy; left_samples > 0; left_samples -= n) { src = audio_stream_wrap(source, src); dst = audio_stream_wrap(sink, dst); nmax = audio_stream_samples_without_wrap_s32(source, src); - n = MIN(left_frames, nmax); + n = MIN(left_samples, nmax); nmax = audio_stream_samples_without_wrap_s32(sink, dst); n = MIN(n, nmax); memcpy_s(dst, n * sizeof(int32_t), src, n * sizeof(int32_t)); diff --git a/src/audio/mixin_mixout/mixin_mixout_hifi3.c b/src/audio/mixin_mixout/mixin_mixout_hifi3.c index 6b352f2a97e1..c03e43779b11 100644 --- a/src/audio/mixin_mixout/mixin_mixout_hifi3.c +++ b/src/audio/mixin_mixout/mixin_mixout_hifi3.c @@ -11,11 +11,11 @@ #ifdef MIXIN_MIXOUT_HIFI3 #if CONFIG_FORMAT_S16LE -static void mix_s16(struct audio_stream *sink, int32_t start_frame, int32_t mixed_frames, +static void mix_s16(struct audio_stream *sink, int32_t start_sample, int32_t mixed_samples, const struct audio_stream *source, - int32_t frame_count, uint16_t gain) + int32_t sample_count, uint16_t gain) { - int frames_to_mix, frames_to_copy, left_frames; + int samples_to_mix, samples_to_copy, left_samples; int n, nmax, i, m, left; ae_int16x4 in_sample; ae_int16x4 out_sample; @@ -25,20 +25,20 @@ static void mix_s16(struct audio_stream *sink, int32_t start_frame, int32_t mixe ae_valign outu1 = AE_ZALIGN64(); ae_valign outu2 = AE_ZALIGN64(); /* audio_stream_wrap() is required and is done below in a loop */ - ae_int16 *dst = (ae_int16 *)audio_stream_get_wptr(sink) + start_frame; + ae_int16 *dst = (ae_int16 *)audio_stream_get_wptr(sink) + start_sample; ae_int16 *src = audio_stream_get_rptr(source); - assert(mixed_frames >= start_frame); - frames_to_mix = AE_MIN_32_signed(mixed_frames - start_frame, frame_count); - frames_to_copy = frame_count - frames_to_mix; + assert(mixed_samples >= start_sample); + samples_to_mix = AE_MIN_32_signed(mixed_samples - start_sample, sample_count); + samples_to_copy = sample_count - samples_to_mix; n = 0; - for (left_frames = frames_to_mix; left_frames > 0; left_frames -= n) { + for (left_samples = samples_to_mix; left_samples > 0; left_samples -= n) { src = audio_stream_wrap(source, src + n); dst = audio_stream_wrap(sink, dst + n); /* calculate the remaining samples*/ nmax = audio_stream_samples_without_wrap_s16(source, src); - n = AE_MIN_32_signed(left_frames, nmax); + n = AE_MIN_32_signed(left_samples, nmax); nmax = audio_stream_samples_without_wrap_s16(sink, dst); n = AE_MIN_32_signed(n, nmax); in = (ae_int16x4 *)src; @@ -68,12 +68,12 @@ static void mix_s16(struct audio_stream *sink, int32_t start_frame, int32_t mixe } } - for (left_frames = frames_to_copy; left_frames > 0; left_frames -= n) { + for (left_samples = samples_to_copy; left_samples > 0; left_samples -= n) { src = audio_stream_wrap(source, src + n); dst = audio_stream_wrap(sink, dst + n); /* calculate the remaining samples*/ nmax = audio_stream_samples_without_wrap_s16(source, src); - n = AE_MIN_32_signed(left_frames, nmax); + n = AE_MIN_32_signed(left_samples, nmax); nmax = audio_stream_samples_without_wrap_s16(sink, dst); n = AE_MIN_32_signed(n, nmax); in = (ae_int16x4 *)src; @@ -100,11 +100,11 @@ static void mix_s16(struct audio_stream *sink, int32_t start_frame, int32_t mixe #endif /* CONFIG_FORMAT_S16LE */ #if CONFIG_FORMAT_S24LE -static void mix_s24(struct audio_stream *sink, int32_t start_frame, int32_t mixed_frames, +static void mix_s24(struct audio_stream *sink, int32_t start_sample, int32_t mixed_samples, const struct audio_stream *source, - int32_t frame_count, uint16_t gain) + int32_t sample_count, uint16_t gain) { - int frames_to_mix, frames_to_copy, left_frames; + int samples_to_mix, samples_to_copy, left_samples; int n, nmax, i, m, left; ae_int32x2 in_sample; ae_int32x2 out_sample; @@ -114,20 +114,20 @@ static void mix_s24(struct audio_stream *sink, int32_t start_frame, int32_t mixe ae_valign outu1 = AE_ZALIGN64(); ae_valign outu2 = AE_ZALIGN64(); /* audio_stream_wrap() is required and is done below in a loop */ - int32_t *dst = (int32_t *)audio_stream_get_wptr(sink) + start_frame; + int32_t *dst = (int32_t *)audio_stream_get_wptr(sink) + start_sample; int32_t *src = audio_stream_get_rptr(source); - assert(mixed_frames >= start_frame); - frames_to_mix = AE_MIN_32_signed(mixed_frames - start_frame, frame_count); - frames_to_copy = frame_count - frames_to_mix; + assert(mixed_samples >= start_sample); + samples_to_mix = AE_MIN_32_signed(mixed_samples - start_sample, sample_count); + samples_to_copy = sample_count - samples_to_mix; n = 0; - for (left_frames = frames_to_mix; left_frames > 0; left_frames -= n) { + for (left_samples = samples_to_mix; left_samples > 0; left_samples -= n) { src = audio_stream_wrap(source, src + n); dst = audio_stream_wrap(sink, dst + n); /* calculate the remaining samples*/ nmax = audio_stream_samples_without_wrap_s24(source, src); - n = AE_MIN_32_signed(left_frames, nmax); + n = AE_MIN_32_signed(left_samples, nmax); nmax = audio_stream_samples_without_wrap_s24(sink, dst); n = AE_MIN_32_signed(n, nmax); in = (ae_int32x2 *)src; @@ -155,11 +155,11 @@ static void mix_s24(struct audio_stream *sink, int32_t start_frame, int32_t mixe } } - for (left_frames = frames_to_copy; left_frames > 0; left_frames -= n) { + for (left_samples = samples_to_copy; left_samples > 0; left_samples -= n) { src = audio_stream_wrap(source, src + n); dst = audio_stream_wrap(sink, dst + n); nmax = audio_stream_samples_without_wrap_s24(source, src); - n = AE_MIN_32_signed(left_frames, nmax); + n = AE_MIN_32_signed(left_samples, nmax); nmax = audio_stream_samples_without_wrap_s24(sink, dst); n = AE_MIN_32_signed(n, nmax); in = (ae_int32x2 *)src; @@ -183,11 +183,11 @@ static void mix_s24(struct audio_stream *sink, int32_t start_frame, int32_t mixe #endif /* CONFIG_FORMAT_S24LE */ #if CONFIG_FORMAT_S32LE -static void mix_s32(struct audio_stream *sink, int32_t start_frame, int32_t mixed_frames, +static void mix_s32(struct audio_stream *sink, int32_t start_sample, int32_t mixed_samples, const struct audio_stream *source, - int32_t frame_count, uint16_t gain) + int32_t sample_count, uint16_t gain) { - int frames_to_mix, frames_to_copy, left_frames; + int samples_to_mix, samples_to_copy, left_samples; int n, nmax, i, m, left; ae_int32x2 in_sample; ae_int32x2 out_sample; @@ -197,20 +197,20 @@ static void mix_s32(struct audio_stream *sink, int32_t start_frame, int32_t mixe ae_valign outu1 = AE_ZALIGN64(); ae_valign outu2 = AE_ZALIGN64(); /* audio_stream_wrap() is required and is done below in a loop */ - int32_t *dst = (int32_t *)audio_stream_get_wptr(sink) + start_frame; + int32_t *dst = (int32_t *)audio_stream_get_wptr(sink) + start_sample; int32_t *src = audio_stream_get_rptr(source); - assert(mixed_frames >= start_frame); - frames_to_mix = AE_MIN_32_signed(mixed_frames - start_frame, frame_count); - frames_to_copy = frame_count - frames_to_mix; + assert(mixed_samples >= start_sample); + samples_to_mix = AE_MIN_32_signed(mixed_samples - start_sample, sample_count); + samples_to_copy = sample_count - samples_to_mix; n = 0; - for (left_frames = frames_to_mix; left_frames > 0; left_frames -= n) { + for (left_samples = samples_to_mix; left_samples > 0; left_samples -= n) { src = audio_stream_wrap(source, src + n); dst = audio_stream_wrap(sink, dst + n); /* calculate the remaining samples*/ nmax = audio_stream_samples_without_wrap_s32(source, src); - n = AE_MIN_32_signed(left_frames, nmax); + n = AE_MIN_32_signed(left_samples, nmax); nmax = audio_stream_samples_without_wrap_s32(sink, dst); n = AE_MIN_32_signed(n, nmax); in = (ae_int32x2 *)src; @@ -237,12 +237,12 @@ static void mix_s32(struct audio_stream *sink, int32_t start_frame, int32_t mixe } } - for (left_frames = frames_to_copy; left_frames > 0; left_frames -= n) { + for (left_samples = samples_to_copy; left_samples > 0; left_samples -= n) { src = audio_stream_wrap(source, src + n); dst = audio_stream_wrap(sink, dst + n); /* calculate the remaining samples*/ nmax = audio_stream_samples_without_wrap_s32(source, src); - n = AE_MIN_32_signed(left_frames, nmax); + n = AE_MIN_32_signed(left_samples, nmax); nmax = audio_stream_samples_without_wrap_s32(sink, dst); n = AE_MIN_32_signed(n, nmax); in = (ae_int32x2 *)src; From 43b6c1b11cf336d7e6afaf0c212939b0d5f4cddf Mon Sep 17 00:00:00 2001 From: Serhiy Katsyuba Date: Mon, 27 Nov 2023 19:00:41 +0100 Subject: [PATCH 4/9] ipc4: mixin/mixout: Modify .process() impl to use sink/source API Modifications to mixin/mixout .process() and .reset() implementations to switch to use sink/source API. Signed-off-by: Serhiy Katsyuba --- src/audio/mixin_mixout/mixin_mixout.c | 306 +++++++++++------- src/audio/mixin_mixout/mixin_mixout.h | 11 +- src/audio/mixin_mixout/mixin_mixout_generic.c | 76 ++--- src/audio/mixin_mixout/mixin_mixout_hifi3.c | 78 ++--- src/include/sof/audio/audio_stream.h | 23 ++ 5 files changed, 294 insertions(+), 200 deletions(-) diff --git a/src/audio/mixin_mixout/mixin_mixout.c b/src/audio/mixin_mixout/mixin_mixout.c index b9efa59d0a60..797807419f89 100644 --- a/src/audio/mixin_mixout/mixin_mixout.c +++ b/src/audio/mixin_mixout/mixin_mixout.c @@ -103,6 +103,15 @@ struct mixout_data { * by mixin but not yet produced in mixout. */ struct pending_frames pending_frames[MIXOUT_MAX_SOURCES]; + + /* + * When several mixins are connected to one mixout (a typical case) mixout sink + * buffer is acquired (via sink_get_buffer() call) in mixin_process() of first + * mixin. Other connected mixins just use a pointer to the buffer stored below. + * The buffer is released (committed by sink_commit_buffer() call) in mixout_process(). + */ + struct cir_buf_ptr acquired_buf; + uint32_t acquired_buf_free_frames; }; /* NULL is also a valid mixin argument: in such case the function returns first unused entry */ @@ -183,9 +192,9 @@ static int mixout_free(struct processing_module *mod) } static int mix(struct comp_dev *dev, const struct mixin_data *mixin_data, - uint16_t sink_index, struct audio_stream *sink, - uint32_t start_frame, uint32_t mixed_frames, - const struct audio_stream *source, uint32_t frame_count) + uint16_t sink_index, struct cir_buf_ptr *sink, + uint32_t start_sample, uint32_t mixed_samples, + const struct cir_buf_ptr *source, uint32_t sample_count) { const struct mixin_sink_config *sink_config; @@ -197,37 +206,32 @@ static int mix(struct comp_dev *dev, const struct mixin_data *mixin_data, sink_config = &mixin_data->sink_config[sink_index]; - mixin_data->mix(sink, start_frame * audio_stream_get_channels(sink), - mixed_frames * audio_stream_get_channels(sink), - source, - frame_count * audio_stream_get_channels(sink), - sink_config->gain); + mixin_data->mix(sink, start_sample, mixed_samples, + source, sample_count, sink_config->gain); return 0; } /* mix silence into stream, i.e. set not yet mixed data in stream to zero */ -static void silence(struct audio_stream *stream, uint32_t start_frame, - uint32_t mixed_frames, uint32_t frame_count) +static void silence(struct cir_buf_ptr *stream, uint32_t start_offset, + uint32_t mixed_bytes, uint32_t size) { - uint32_t skip_mixed_frames; + uint32_t skip_mixed_bytes; uint8_t *ptr; - uint32_t size; int n; - assert(mixed_frames >= start_frame); - skip_mixed_frames = mixed_frames - start_frame; + assert(mixed_bytes >= start_offset); + skip_mixed_bytes = mixed_bytes - start_offset; - if (frame_count <= skip_mixed_frames) + if (size <= skip_mixed_bytes) return; - size = audio_stream_period_bytes(stream, frame_count - skip_mixed_frames); - ptr = (uint8_t *)audio_stream_get_wptr(stream) + - audio_stream_period_bytes(stream, mixed_frames); + size -= skip_mixed_bytes; + ptr = (uint8_t *)stream->ptr + mixed_bytes; while (size) { - ptr = audio_stream_wrap(stream, ptr); - n = MIN(audio_stream_bytes_without_wrap(stream, ptr), size); + ptr = cir_buf_wrap(ptr, stream->buf_start, stream->buf_end); + n = MIN((uint8_t *)stream->buf_end - ptr, size); memset(ptr, 0, n); size -= n; ptr += n; @@ -251,31 +255,28 @@ static void silence(struct audio_stream *stream, uint32_t start_frame, * was actually mixed and so xxx_produce() is called for that amount. */ static int mixin_process(struct processing_module *mod, - struct input_stream_buffer *input_buffers, int num_input_buffers, - struct output_stream_buffer *output_buffers, int num_output_buffers) + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) { struct mixin_data *mixin_data = module_get_private_data(mod); struct comp_dev *dev = mod->dev; uint32_t source_avail_frames, sinks_free_frames; - struct comp_dev *active_mixouts[MIXIN_MAX_SINKS]; + struct processing_module *active_mixouts[MIXIN_MAX_SINKS]; uint16_t sinks_ids[MIXIN_MAX_SINKS]; - uint32_t bytes_to_consume_from_source_buf; + uint32_t bytes_to_consume = 0; uint32_t frames_to_copy; struct pending_frames *pending_frames; int i, ret; + struct cir_buf_ptr source_ptr; comp_dbg(dev, "mixin_process()"); - source_avail_frames = audio_stream_get_avail_frames(input_buffers[0].data); + source_avail_frames = source_get_data_frames_available(sources[0]); sinks_free_frames = INT32_MAX; - /* block mixin pipeline until at least one mixout pipeline started */ - if (num_output_buffers == 0) - return 0; - - if (num_output_buffers > MIXIN_MAX_SINKS) { - comp_err(dev, "mixin_process(): Invalid output buffer count %d", - num_output_buffers); + if (num_of_sinks > MIXIN_MAX_SINKS) { + comp_err(dev, "mixin_process(): Invalid output sink count %d", + num_of_sinks); return -EINVAL; } @@ -283,27 +284,54 @@ static int mixin_process(struct processing_module *mod, * it is a nimimal value among frames available in source buffer * and frames free in each connected mixout sink buffer. */ - for (i = 0; i < num_output_buffers; i++) { - struct comp_buffer *unused_in_between_buf_c; + for (i = 0; i < num_of_sinks; i++) { + struct audio_stream *stream; + struct comp_buffer *unused_in_between_buf; struct comp_dev *mixout; - uint16_t sink_id; - struct comp_buffer *sink; + struct sof_sink *mixout_sink; struct mixout_data *mixout_data; struct processing_module *mixout_mod; uint32_t free_frames; + /* WORKAROUND: since mixin is always connected to mixout, we can safely assume + * mixin sink interface is implemented via comp_buffer. This is, of course, + * not the case for other modules. + * TODO: find out a solution to reach mixout without knowledge of mixin + * sof_sink implementation. + */ + stream = container_of(sinks[i], struct audio_stream, sink_api); /* unused buffer between mixin and mixout */ - unused_in_between_buf_c = container_of(output_buffers[i].data, - struct comp_buffer, stream); - mixout = unused_in_between_buf_c->sink; - sink_id = IPC4_SRC_QUEUE_ID(buf_get_id(unused_in_between_buf_c)); - - active_mixouts[i] = mixout; - sinks_ids[i] = sink_id; + unused_in_between_buf = container_of(stream, struct comp_buffer, stream); + mixout = unused_in_between_buf->sink; - sink = list_first_item(&mixout->bsink_list, struct comp_buffer, source_list); + /* Skip non-active mixout like it is not connected so it does not + * block other possibly connected mixouts. In addition, non-active + * mixouts might have their sink buffer/interface not yet configured. + */ + if (mixout->state != COMP_STATE_ACTIVE) { + active_mixouts[i] = NULL; + continue; + } mixout_mod = comp_get_drvdata(mixout); + active_mixouts[i] = mixout_mod; + mixout_sink = mixout_mod->sinks[0]; + + /* mixout might be created on another pipeline. Its sink stream params are usually + * configured in .prepare(). It is possible that such .prepare() was not yet called + * for mixout pipeline. Hence the check above if mixout state is active. However, + * let's just in case check here if sink stream params are really configured as + * proceeding with unconfigured sink will lead to hard to debug bugs. + * Unconfigured stream params are filled with zeros. + * TODO: introduce something like sink_is_configured() ? + */ + if (!mixout_sink || sink_get_channels(mixout_sink) == 0) { + comp_err(dev, "mixout sink not configured!"); + return -EINVAL; + } + + sinks_ids[i] = IPC4_SRC_QUEUE_ID(buf_get_id(unused_in_between_buf)); + mixout_data = module_get_private_data(mixout_mod); pending_frames = get_mixin_pending_frames(mixout_data, dev); if (!pending_frames) { @@ -311,16 +339,14 @@ static int mixin_process(struct processing_module *mod, return -EINVAL; } - /* Normally this should never happen as we checked above - * that mixout is in active state and so its sink buffer - * should be already initialized in mixout .params(). + /* In theory, though unlikely, mixout sink can be connected to some module on + * another core. In this case free space in mixout sink buffer can suddenly increase + * (data consumed on another core) after the buffer was already acquired. Let's only + * access free space that was at the moment of acquiring the buffer. */ - if (!sink->hw_params_configured) { - comp_err(dev, "Uninitialized mixout sink buffer!"); - return -EINVAL; - } - - free_frames = audio_stream_get_free_frames(&sink->stream); + free_frames = mixout_data->acquired_buf.ptr ? + mixout_data->acquired_buf_free_frames : + sink_get_free_frames(mixout_sink); /* mixout sink buffer may still have not yet produced data -- data * consumed and written there by mixin on previous mixin_process() run. @@ -330,40 +356,39 @@ static int mixin_process(struct processing_module *mod, sinks_free_frames = MIN(sinks_free_frames, free_frames - pending_frames->frames); } + if (sinks_free_frames == 0 || sinks_free_frames == INT32_MAX) + return 0; + if (source_avail_frames > 0) { - struct comp_buffer *source_c; + size_t buf_size; frames_to_copy = MIN(source_avail_frames, sinks_free_frames); - bytes_to_consume_from_source_buf = - audio_stream_period_bytes(input_buffers[0].data, frames_to_copy); - if (bytes_to_consume_from_source_buf > 0) { - input_buffers[0].consumed = bytes_to_consume_from_source_buf; - source_c = container_of(input_buffers[0].data, struct comp_buffer, - stream); - buffer_stream_invalidate(source_c, bytes_to_consume_from_source_buf); - } + bytes_to_consume = frames_to_copy * source_get_frame_bytes(sources[0]); + + source_get_data(sources[0], bytes_to_consume, (const void **)&source_ptr.ptr, + (const void **)&source_ptr.buf_start, &buf_size); + source_ptr.buf_end = (uint8_t *)source_ptr.buf_start + buf_size; } else { /* if source does not produce any data -- do NOT block mixing but generate * silence as that source output. * * here frames_to_copy is silence size. + * + * FIXME: does not work properly for freq like 44.1 kHz. */ frames_to_copy = MIN(dev->frames, sinks_free_frames); } /* iterate over all connected mixouts and mix source data into each mixout sink buffer */ - for (i = 0; i < num_output_buffers; i++) { - struct comp_dev *mixout; - struct comp_buffer *sink; + for (i = 0; i < num_of_sinks; i++) { struct mixout_data *mixout_data; struct processing_module *mixout_mod; uint32_t start_frame; - uint32_t writeback_size; - mixout = active_mixouts[i]; - sink = list_first_item(&mixout->bsink_list, struct comp_buffer, source_list); + mixout_mod = active_mixouts[i]; + if (!mixout_mod) + continue; - mixout_mod = comp_get_drvdata(mixout); mixout_data = module_get_private_data(mixout_mod); pending_frames = get_mixin_pending_frames(mixout_data, dev); if (!pending_frames) { @@ -377,56 +402,70 @@ static int mixin_process(struct processing_module *mod, */ start_frame = pending_frames->frames; + /* mixout sink buffer is acquired here by its first connected mixin and is + * released in mixout_process(). Other connected mixins just use a pointer + * stored in mixout_data->acquired_buf. + */ + if (!mixout_data->acquired_buf.ptr) { + struct sof_sink *sink = mixout_mod->sinks[0]; + uint32_t free_bytes = sink_get_free_size(sink); + uint32_t buf_size; + + sink_get_buffer(sink, free_bytes, &mixout_data->acquired_buf.ptr, + &mixout_data->acquired_buf.buf_start, &buf_size); + mixout_data->acquired_buf.buf_end = + (uint8_t *)mixout_data->acquired_buf.buf_start + buf_size; + mixout_data->acquired_buf_free_frames = + free_bytes / sink_get_frame_bytes(sink); + } + /* if source does not produce any data but mixin is in active state -- generate * silence instead of that source data */ if (source_avail_frames == 0) { + uint32_t frame_bytes = sink_get_frame_bytes(mixout_mod->sinks[0]); + /* generate silence */ - silence(&sink->stream, start_frame, mixout_data->mixed_frames, - frames_to_copy); + silence(&mixout_data->acquired_buf, start_frame * frame_bytes, + mixout_data->mixed_frames * frame_bytes, + frames_to_copy * frame_bytes); } else { + uint32_t channel_count = sink_get_channels(mixout_mod->sinks[0]); + /* basically, if sink buffer has no data -- copy source data there, if * sink buffer has some data (written by another mixin) mix that data * with source data. */ - ret = mix(dev, mixin_data, sinks_ids[i], &sink->stream, - start_frame, mixout_data->mixed_frames, - input_buffers[0].data, frames_to_copy); - if (ret < 0) { + ret = mix(dev, mixin_data, sinks_ids[i], &mixout_data->acquired_buf, + start_frame * channel_count, + mixout_data->mixed_frames * channel_count, + &source_ptr, frames_to_copy * channel_count); + if (ret < 0) return ret; - } } - /* it would be better to writeback memory region starting from start_frame and - * of frames_to_copy size (converted to bytes, of course). However, seems - * there is no appropreate API. Anyway, start_frame would be 0 most of the time. - */ - writeback_size = audio_stream_period_bytes(&sink->stream, - frames_to_copy + start_frame); - if (writeback_size > 0) - buffer_stream_writeback(sink, writeback_size); - pending_frames->frames += frames_to_copy; if (frames_to_copy + start_frame > mixout_data->mixed_frames) mixout_data->mixed_frames = frames_to_copy + start_frame; } + if (bytes_to_consume) + source_release_data(sources[0], bytes_to_consume); + return 0; } -/* mixout just calls xxx_produce() on data mixed into its sink buffer by - * mixins. - */ +/* mixout just commits its sink buffer with data already mixed by mixins */ static int mixout_process(struct processing_module *mod, - struct input_stream_buffer *input_buffers, int num_input_buffers, - struct output_stream_buffer *output_buffers, int num_output_buffers) + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) { struct comp_dev *dev = mod->dev; struct mixout_data *md; uint32_t frames_to_produce = INT32_MAX; + uint32_t bytes_to_produce; struct pending_frames *pending_frames; - uint32_t sink_bytes; int i; comp_dbg(dev, "mixout_process()"); @@ -437,38 +476,42 @@ static int mixout_process(struct processing_module *mod, * (i.e., mixed into mixout sink buffer). That is the amount that can/should be * produced now. */ - for (i = 0; i < num_input_buffers; i++) { + for (i = 0; i < num_of_sources; i++) { const struct audio_stream *source_stream; struct comp_buffer *unused_in_between_buf; - struct comp_dev *source; + struct comp_dev *mixin; - source_stream = input_buffers[i].data; + /* WORKAROUND: since mixin is always connected to mixout, we can safely assume + * mixout source interface is implemented via comp_buffer. This is, of course, + * not the case for other modules. + * TODO: find out a solution to reach mixin without knowledge of mixout + * sof_source implementation. + */ + source_stream = container_of(sources[i], struct audio_stream, source_api); unused_in_between_buf = container_of(source_stream, struct comp_buffer, stream); + mixin = unused_in_between_buf->source; - source = unused_in_between_buf->source; - - pending_frames = get_mixin_pending_frames(md, source); + pending_frames = get_mixin_pending_frames(md, mixin); if (!pending_frames) continue; - if (source->state == COMP_STATE_ACTIVE || pending_frames->frames) + if (mixin->state == COMP_STATE_ACTIVE || pending_frames->frames) frames_to_produce = MIN(frames_to_produce, pending_frames->frames); } if (frames_to_produce > 0 && frames_to_produce < INT32_MAX) { - for (i = 0; i < num_input_buffers; i++) { + for (i = 0; i < num_of_sources; i++) { const struct audio_stream *source_stream; struct comp_buffer *unused_in_between_buf; - struct comp_dev *source; + struct comp_dev *mixin; - source_stream = input_buffers[i].data; + source_stream = container_of(sources[i], struct audio_stream, source_api); unused_in_between_buf = container_of(source_stream, struct comp_buffer, stream); + mixin = unused_in_between_buf->source; - source = unused_in_between_buf->source; - - pending_frames = get_mixin_pending_frames(md, source); + pending_frames = get_mixin_pending_frames(md, mixin); if (!pending_frames) continue; @@ -481,17 +524,27 @@ static int mixout_process(struct processing_module *mod, assert(md->mixed_frames >= frames_to_produce); md->mixed_frames -= frames_to_produce; - sink_bytes = frames_to_produce * - audio_stream_frame_bytes(output_buffers[0].data); - output_buffers[0].size = sink_bytes; + bytes_to_produce = frames_to_produce * sink_get_frame_bytes(sinks[0]); } else { - sink_bytes = dev->frames * audio_stream_frame_bytes(output_buffers[0].data); - if (!audio_stream_set_zero(output_buffers[0].data, sink_bytes)) - output_buffers[0].size = sink_bytes; - else - output_buffers[0].size = 0; + /* FIXME: does not work properly for freq like 44.1 kHz */ + bytes_to_produce = dev->frames * sink_get_frame_bytes(sinks[0]); + bytes_to_produce = MIN(bytes_to_produce, sink_get_free_size(sinks[0])); + + if (!md->acquired_buf.ptr) { + size_t buf_size; + + sink_get_buffer(sinks[0], bytes_to_produce, &md->acquired_buf.ptr, + &md->acquired_buf.buf_start, &buf_size); + md->acquired_buf.buf_end = (uint8_t *)md->acquired_buf.buf_start + buf_size; + } + + cir_buf_set_zero(md->acquired_buf.ptr, md->acquired_buf.buf_start, + md->acquired_buf.buf_end, bytes_to_produce); } + sink_commit_buffer(sinks[0], bytes_to_produce); + md->acquired_buf.ptr = NULL; + return 0; } @@ -510,20 +563,31 @@ static int mixin_reset(struct processing_module *mod) static int mixout_reset(struct processing_module *mod) { struct comp_dev *dev = mod->dev; - struct list_item *blist; comp_dbg(dev, "mixout_reset()"); /* FIXME: move this to module_adapter_reset() */ if (dev->pipeline->source_comp->direction == SOF_IPC_STREAM_PLAYBACK) { - list_for_item(blist, &dev->bsource_list) { - struct comp_buffer *source; + int i; + + for (i = 0; i < mod->num_of_sources; i++) { + const struct audio_stream *source_stream; + const struct comp_buffer *source_buf; bool stop; - /* FIXME: this is racy and implicitly protected by serialised IPCs */ - source = container_of(blist, struct comp_buffer, sink_list); - stop = (dev->pipeline == source->source->pipeline && - source->source->state > COMP_STATE_PAUSED); + /* WORKAROUND: since mixin is always connected to mixout, we can safely + * assume mixout source interface is implemented via comp_buffer. This is, + * of course, not the case for other modules. + * TODO: find out a solution to reach mixin without knowledge of mixout + * sof_source implementation. + */ + source_stream = container_of(mod->sources[i], + struct audio_stream, source_api); + source_buf = container_of(source_stream, struct comp_buffer, + stream); + + stop = (dev->pipeline == source_buf->source->pipeline && + source_buf->source->state > COMP_STATE_PAUSED); if (stop) /* should not reset the downstream components */ @@ -896,7 +960,7 @@ static int mixin_set_config(struct processing_module *mod, uint32_t config_id, static const struct module_interface mixin_interface = { .init = mixin_init, .prepare = mixin_prepare, - .process_audio_stream = mixin_process, + .process = mixin_process, .set_configuration = mixin_set_config, .reset = mixin_reset, .free = mixin_free @@ -908,7 +972,7 @@ SOF_MODULE_INIT(mixin, sys_comp_module_mixin_interface_init); static const struct module_interface mixout_interface = { .init = mixout_init, .prepare = mixout_prepare, - .process_audio_stream = mixout_process, + .process = mixout_process, .reset = mixout_reset, .free = mixout_free, .bind = mixout_bind, diff --git a/src/audio/mixin_mixout/mixin_mixout.h b/src/audio/mixin_mixout/mixin_mixout.h index 6b097df99b16..8ac844383917 100644 --- a/src/audio/mixin_mixout/mixin_mixout.h +++ b/src/audio/mixin_mixout/mixin_mixout.h @@ -102,12 +102,19 @@ struct ipc4_mixer_mode_config { struct ipc4_mixer_mode_sink_config mixer_mode_sink_configs[1]; } __packed __aligned(4); +/* Pointer to data in circular buffer together with buffer boundaries */ +struct cir_buf_ptr { + void *buf_start; + void *buf_end; + void *ptr; +}; + /** * \brief mixin processing function interface */ -typedef void (*mix_func)(struct audio_stream *sink, int32_t start_sample, +typedef void (*mix_func)(struct cir_buf_ptr *sink, int32_t start_sample, int32_t mixed_samples, - const struct audio_stream *source, + const struct cir_buf_ptr *source, int32_t sample_count, uint16_t gain); /** diff --git a/src/audio/mixin_mixout/mixin_mixout_generic.c b/src/audio/mixin_mixout/mixin_mixout_generic.c index 3c9895d18d45..c69305073660 100644 --- a/src/audio/mixin_mixout/mixin_mixout_generic.c +++ b/src/audio/mixin_mixout/mixin_mixout_generic.c @@ -12,16 +12,16 @@ #ifdef MIXIN_MIXOUT_GENERIC #if CONFIG_FORMAT_S16LE -static void mix_s16(struct audio_stream *sink, int32_t start_sample, int32_t mixed_samples, - const struct audio_stream *source, +static void mix_s16(struct cir_buf_ptr *sink, int32_t start_sample, int32_t mixed_samples, + const struct cir_buf_ptr *source, int32_t sample_count, uint16_t gain) { int32_t samples_to_mix, samples_to_copy, left_samples; int32_t n, nmax, i; - /* audio_stream_wrap() is required and is done below in a loop */ - int16_t *dst = (int16_t *)audio_stream_get_wptr(sink) + start_sample; - int16_t *src = audio_stream_get_rptr(source); + /* cir_buf_wrap() is required and is done below in a loop */ + int16_t *dst = (int16_t *)sink->ptr + start_sample; + int16_t *src = source->ptr; assert(mixed_samples >= start_sample); samples_to_mix = mixed_samples - start_sample; @@ -29,12 +29,12 @@ static void mix_s16(struct audio_stream *sink, int32_t start_sample, int32_t mix samples_to_copy = sample_count - samples_to_mix; for (left_samples = samples_to_mix; left_samples > 0; left_samples -= n) { - src = audio_stream_wrap(source, src); - dst = audio_stream_wrap(sink, dst); + src = cir_buf_wrap(src, source->buf_start, source->buf_end); + dst = cir_buf_wrap(dst, sink->buf_start, sink->buf_end); /* calculate the remaining samples*/ - nmax = audio_stream_samples_without_wrap_s16(source, src); + nmax = (int16_t *)source->buf_end - src; n = MIN(left_samples, nmax); - nmax = audio_stream_samples_without_wrap_s16(sink, dst); + nmax = (int16_t *)sink->buf_end - dst; n = MIN(n, nmax); for (i = 0; i < n; i++) { *dst = sat_int16(*dst + *src++); @@ -43,11 +43,11 @@ static void mix_s16(struct audio_stream *sink, int32_t start_sample, int32_t mix } for (left_samples = samples_to_copy; left_samples > 0; left_samples -= n) { - src = audio_stream_wrap(source, src); - dst = audio_stream_wrap(sink, dst); - nmax = audio_stream_samples_without_wrap_s16(source, src); + src = cir_buf_wrap(src, source->buf_start, source->buf_end); + dst = cir_buf_wrap(dst, sink->buf_start, sink->buf_end); + nmax = (int16_t *)source->buf_end - src; n = MIN(left_samples, nmax); - nmax = audio_stream_samples_without_wrap_s16(sink, dst); + nmax = (int16_t *)sink->buf_end - dst; n = MIN(n, nmax); memcpy_s(dst, n * sizeof(int16_t), src, n * sizeof(int16_t)); dst += n; @@ -57,15 +57,15 @@ static void mix_s16(struct audio_stream *sink, int32_t start_sample, int32_t mix #endif /* CONFIG_FORMAT_S16LE */ #if CONFIG_FORMAT_S24LE -static void mix_s24(struct audio_stream *sink, int32_t start_sample, int32_t mixed_samples, - const struct audio_stream *source, +static void mix_s24(struct cir_buf_ptr *sink, int32_t start_sample, int32_t mixed_samples, + const struct cir_buf_ptr *source, int32_t sample_count, uint16_t gain) { int32_t samples_to_mix, samples_to_copy, left_samples; int32_t n, nmax, i; - /* audio_stream_wrap() is required and is done below in a loop */ - int32_t *dst = (int32_t *)audio_stream_get_wptr(sink) + start_sample; - int32_t *src = audio_stream_get_rptr(source); + /* cir_buf_wrap() is required and is done below in a loop */ + int32_t *dst = (int32_t *)sink->ptr + start_sample; + int32_t *src = source->ptr; assert(mixed_samples >= start_sample); samples_to_mix = mixed_samples - start_sample; @@ -73,12 +73,12 @@ static void mix_s24(struct audio_stream *sink, int32_t start_sample, int32_t mix samples_to_copy = sample_count - samples_to_mix; for (left_samples = samples_to_mix; left_samples > 0; left_samples -= n) { - src = audio_stream_wrap(source, src); - dst = audio_stream_wrap(sink, dst); + src = cir_buf_wrap(src, source->buf_start, source->buf_end); + dst = cir_buf_wrap(dst, sink->buf_start, sink->buf_end); /* calculate the remaining samples*/ - nmax = audio_stream_samples_without_wrap_s24(source, src); + nmax = (int32_t *)source->buf_end - src; n = MIN(left_samples, nmax); - nmax = audio_stream_samples_without_wrap_s24(sink, dst); + nmax = (int32_t *)sink->buf_end - dst; n = MIN(n, nmax); for (i = 0; i < n; i++) { *dst = sat_int24(sign_extend_s24(*dst) + sign_extend_s24(*src++)); @@ -87,11 +87,11 @@ static void mix_s24(struct audio_stream *sink, int32_t start_sample, int32_t mix } for (left_samples = samples_to_copy; left_samples > 0; left_samples -= n) { - src = audio_stream_wrap(source, src); - dst = audio_stream_wrap(sink, dst); - nmax = audio_stream_samples_without_wrap_s24(source, src); + src = cir_buf_wrap(src, source->buf_start, source->buf_end); + dst = cir_buf_wrap(dst, sink->buf_start, sink->buf_end); + nmax = (int32_t *)source->buf_end - src; n = MIN(left_samples, nmax); - nmax = audio_stream_samples_without_wrap_s24(sink, dst); + nmax = (int32_t *)sink->buf_end - dst; n = MIN(n, nmax); memcpy_s(dst, n * sizeof(int32_t), src, n * sizeof(int32_t)); dst += n; @@ -102,14 +102,14 @@ static void mix_s24(struct audio_stream *sink, int32_t start_sample, int32_t mix #endif /* CONFIG_FORMAT_S24LE */ #if CONFIG_FORMAT_S32LE -static void mix_s32(struct audio_stream *sink, int32_t start_sample, int32_t mixed_samples, - const struct audio_stream *source, +static void mix_s32(struct cir_buf_ptr *sink, int32_t start_sample, int32_t mixed_samples, + const struct cir_buf_ptr *source, int32_t sample_count, uint16_t gain) { int32_t samples_to_mix, samples_to_copy, left_samples; int32_t n, nmax, i; - int32_t *dst = (int32_t *)audio_stream_get_wptr(sink) + start_sample; - int32_t *src = audio_stream_get_rptr(source); + int32_t *dst = (int32_t *)sink->ptr + start_sample; + int32_t *src = source->ptr; assert(mixed_samples >= start_sample); samples_to_mix = mixed_samples - start_sample; @@ -117,12 +117,12 @@ static void mix_s32(struct audio_stream *sink, int32_t start_sample, int32_t mix samples_to_copy = sample_count - samples_to_mix; for (left_samples = samples_to_mix; left_samples > 0; left_samples -= n) { - src = audio_stream_wrap(source, src); - dst = audio_stream_wrap(sink, dst); + src = cir_buf_wrap(src, source->buf_start, source->buf_end); + dst = cir_buf_wrap(dst, sink->buf_start, sink->buf_end); /* calculate the remaining samples*/ - nmax = audio_stream_samples_without_wrap_s32(source, src); + nmax = (int32_t *)source->buf_end - src; n = MIN(left_samples, nmax); - nmax = audio_stream_samples_without_wrap_s32(sink, dst); + nmax = (int32_t *)sink->buf_end - dst; n = MIN(n, nmax); for (i = 0; i < n; i++) { *dst = sat_int32((int64_t)*dst + (int64_t)*src++); @@ -131,11 +131,11 @@ static void mix_s32(struct audio_stream *sink, int32_t start_sample, int32_t mix } for (left_samples = samples_to_copy; left_samples > 0; left_samples -= n) { - src = audio_stream_wrap(source, src); - dst = audio_stream_wrap(sink, dst); - nmax = audio_stream_samples_without_wrap_s32(source, src); + src = cir_buf_wrap(src, source->buf_start, source->buf_end); + dst = cir_buf_wrap(dst, sink->buf_start, sink->buf_end); + nmax = (int32_t *)source->buf_end - src; n = MIN(left_samples, nmax); - nmax = audio_stream_samples_without_wrap_s32(sink, dst); + nmax = (int32_t *)sink->buf_end - dst; n = MIN(n, nmax); memcpy_s(dst, n * sizeof(int32_t), src, n * sizeof(int32_t)); dst += n; diff --git a/src/audio/mixin_mixout/mixin_mixout_hifi3.c b/src/audio/mixin_mixout/mixin_mixout_hifi3.c index c03e43779b11..369ede78d36a 100644 --- a/src/audio/mixin_mixout/mixin_mixout_hifi3.c +++ b/src/audio/mixin_mixout/mixin_mixout_hifi3.c @@ -11,8 +11,8 @@ #ifdef MIXIN_MIXOUT_HIFI3 #if CONFIG_FORMAT_S16LE -static void mix_s16(struct audio_stream *sink, int32_t start_sample, int32_t mixed_samples, - const struct audio_stream *source, +static void mix_s16(struct cir_buf_ptr *sink, int32_t start_sample, int32_t mixed_samples, + const struct cir_buf_ptr *source, int32_t sample_count, uint16_t gain) { int samples_to_mix, samples_to_copy, left_samples; @@ -24,9 +24,9 @@ static void mix_s16(struct audio_stream *sink, int32_t start_sample, int32_t mix ae_valign inu = AE_ZALIGN64(); ae_valign outu1 = AE_ZALIGN64(); ae_valign outu2 = AE_ZALIGN64(); - /* audio_stream_wrap() is required and is done below in a loop */ - ae_int16 *dst = (ae_int16 *)audio_stream_get_wptr(sink) + start_sample; - ae_int16 *src = audio_stream_get_rptr(source); + /* cir_buf_wrap() is required and is done below in a loop */ + ae_int16 *dst = (ae_int16 *)sink->ptr + start_sample; + ae_int16 *src = source->ptr; assert(mixed_samples >= start_sample); samples_to_mix = AE_MIN_32_signed(mixed_samples - start_sample, sample_count); @@ -34,12 +34,12 @@ static void mix_s16(struct audio_stream *sink, int32_t start_sample, int32_t mix n = 0; for (left_samples = samples_to_mix; left_samples > 0; left_samples -= n) { - src = audio_stream_wrap(source, src + n); - dst = audio_stream_wrap(sink, dst + n); + src = cir_buf_wrap(src + n, source->buf_start, source->buf_end); + dst = cir_buf_wrap(dst + n, sink->buf_start, sink->buf_end); /* calculate the remaining samples*/ - nmax = audio_stream_samples_without_wrap_s16(source, src); + nmax = (ae_int16 *)source->buf_end - src; n = AE_MIN_32_signed(left_samples, nmax); - nmax = audio_stream_samples_without_wrap_s16(sink, dst); + nmax = (ae_int16 *)sink->buf_end - dst; n = AE_MIN_32_signed(n, nmax); in = (ae_int16x4 *)src; out = (ae_int16x4 *)dst; @@ -69,12 +69,12 @@ static void mix_s16(struct audio_stream *sink, int32_t start_sample, int32_t mix } for (left_samples = samples_to_copy; left_samples > 0; left_samples -= n) { - src = audio_stream_wrap(source, src + n); - dst = audio_stream_wrap(sink, dst + n); + src = cir_buf_wrap(src + n, source->buf_start, source->buf_end); + dst = cir_buf_wrap(dst + n, sink->buf_start, sink->buf_end); /* calculate the remaining samples*/ - nmax = audio_stream_samples_without_wrap_s16(source, src); + nmax = (ae_int16 *)source->buf_end - src; n = AE_MIN_32_signed(left_samples, nmax); - nmax = audio_stream_samples_without_wrap_s16(sink, dst); + nmax = (ae_int16 *)sink->buf_end - dst; n = AE_MIN_32_signed(n, nmax); in = (ae_int16x4 *)src; out = (ae_int16x4 *)dst; @@ -100,8 +100,8 @@ static void mix_s16(struct audio_stream *sink, int32_t start_sample, int32_t mix #endif /* CONFIG_FORMAT_S16LE */ #if CONFIG_FORMAT_S24LE -static void mix_s24(struct audio_stream *sink, int32_t start_sample, int32_t mixed_samples, - const struct audio_stream *source, +static void mix_s24(struct cir_buf_ptr *sink, int32_t start_sample, int32_t mixed_samples, + const struct cir_buf_ptr *source, int32_t sample_count, uint16_t gain) { int samples_to_mix, samples_to_copy, left_samples; @@ -113,9 +113,9 @@ static void mix_s24(struct audio_stream *sink, int32_t start_sample, int32_t mix ae_valign inu = AE_ZALIGN64(); ae_valign outu1 = AE_ZALIGN64(); ae_valign outu2 = AE_ZALIGN64(); - /* audio_stream_wrap() is required and is done below in a loop */ - int32_t *dst = (int32_t *)audio_stream_get_wptr(sink) + start_sample; - int32_t *src = audio_stream_get_rptr(source); + /* cir_buf_wrap() is required and is done below in a loop */ + int32_t *dst = (int32_t *)sink->ptr + start_sample; + int32_t *src = source->ptr; assert(mixed_samples >= start_sample); samples_to_mix = AE_MIN_32_signed(mixed_samples - start_sample, sample_count); @@ -123,12 +123,12 @@ static void mix_s24(struct audio_stream *sink, int32_t start_sample, int32_t mix n = 0; for (left_samples = samples_to_mix; left_samples > 0; left_samples -= n) { - src = audio_stream_wrap(source, src + n); - dst = audio_stream_wrap(sink, dst + n); + src = cir_buf_wrap(src + n, source->buf_start, source->buf_end); + dst = cir_buf_wrap(dst + n, sink->buf_start, sink->buf_end); /* calculate the remaining samples*/ - nmax = audio_stream_samples_without_wrap_s24(source, src); + nmax = (int32_t *)source->buf_end - src; n = AE_MIN_32_signed(left_samples, nmax); - nmax = audio_stream_samples_without_wrap_s24(sink, dst); + nmax = (int32_t *)sink->buf_end - dst; n = AE_MIN_32_signed(n, nmax); in = (ae_int32x2 *)src; out = (ae_int32x2 *)dst; @@ -156,11 +156,11 @@ static void mix_s24(struct audio_stream *sink, int32_t start_sample, int32_t mix } for (left_samples = samples_to_copy; left_samples > 0; left_samples -= n) { - src = audio_stream_wrap(source, src + n); - dst = audio_stream_wrap(sink, dst + n); - nmax = audio_stream_samples_without_wrap_s24(source, src); + src = cir_buf_wrap(src + n, source->buf_start, source->buf_end); + dst = cir_buf_wrap(dst + n, sink->buf_start, sink->buf_end); + nmax = (int32_t *)source->buf_end - src; n = AE_MIN_32_signed(left_samples, nmax); - nmax = audio_stream_samples_without_wrap_s24(sink, dst); + nmax = (int32_t *)sink->buf_end - dst; n = AE_MIN_32_signed(n, nmax); in = (ae_int32x2 *)src; out = (ae_int32x2 *)dst; @@ -183,8 +183,8 @@ static void mix_s24(struct audio_stream *sink, int32_t start_sample, int32_t mix #endif /* CONFIG_FORMAT_S24LE */ #if CONFIG_FORMAT_S32LE -static void mix_s32(struct audio_stream *sink, int32_t start_sample, int32_t mixed_samples, - const struct audio_stream *source, +static void mix_s32(struct cir_buf_ptr *sink, int32_t start_sample, int32_t mixed_samples, + const struct cir_buf_ptr *source, int32_t sample_count, uint16_t gain) { int samples_to_mix, samples_to_copy, left_samples; @@ -196,9 +196,9 @@ static void mix_s32(struct audio_stream *sink, int32_t start_sample, int32_t mix ae_valign inu = AE_ZALIGN64(); ae_valign outu1 = AE_ZALIGN64(); ae_valign outu2 = AE_ZALIGN64(); - /* audio_stream_wrap() is required and is done below in a loop */ - int32_t *dst = (int32_t *)audio_stream_get_wptr(sink) + start_sample; - int32_t *src = audio_stream_get_rptr(source); + /* cir_buf_wrap() is required and is done below in a loop */ + int32_t *dst = (int32_t *)sink->ptr + start_sample; + int32_t *src = source->ptr; assert(mixed_samples >= start_sample); samples_to_mix = AE_MIN_32_signed(mixed_samples - start_sample, sample_count); @@ -206,12 +206,12 @@ static void mix_s32(struct audio_stream *sink, int32_t start_sample, int32_t mix n = 0; for (left_samples = samples_to_mix; left_samples > 0; left_samples -= n) { - src = audio_stream_wrap(source, src + n); - dst = audio_stream_wrap(sink, dst + n); + src = cir_buf_wrap(src + n, source->buf_start, source->buf_end); + dst = cir_buf_wrap(dst + n, sink->buf_start, sink->buf_end); /* calculate the remaining samples*/ - nmax = audio_stream_samples_without_wrap_s32(source, src); + nmax = (int32_t *)source->buf_end - src; n = AE_MIN_32_signed(left_samples, nmax); - nmax = audio_stream_samples_without_wrap_s32(sink, dst); + nmax = (int32_t *)sink->buf_end - dst; n = AE_MIN_32_signed(n, nmax); in = (ae_int32x2 *)src; out = (ae_int32x2 *)dst; @@ -238,12 +238,12 @@ static void mix_s32(struct audio_stream *sink, int32_t start_sample, int32_t mix } for (left_samples = samples_to_copy; left_samples > 0; left_samples -= n) { - src = audio_stream_wrap(source, src + n); - dst = audio_stream_wrap(sink, dst + n); + src = cir_buf_wrap(src + n, source->buf_start, source->buf_end); + dst = cir_buf_wrap(dst + n, sink->buf_start, sink->buf_end); /* calculate the remaining samples*/ - nmax = audio_stream_samples_without_wrap_s32(source, src); + nmax = (int32_t *)source->buf_end - src; n = AE_MIN_32_signed(left_samples, nmax); - nmax = audio_stream_samples_without_wrap_s32(sink, dst); + nmax = (int32_t *)sink->buf_end - dst; n = AE_MIN_32_signed(n, nmax); in = (ae_int32x2 *)src; out = (ae_int32x2 *)dst; diff --git a/src/include/sof/audio/audio_stream.h b/src/include/sof/audio/audio_stream.h index 09bfb68a038d..cb2bcd4967db 100644 --- a/src/include/sof/audio/audio_stream.h +++ b/src/include/sof/audio/audio_stream.h @@ -984,6 +984,29 @@ static inline int audio_stream_set_zero(struct audio_stream *buffer, uint32_t by return 0; } +/** + * Writes zeros to circular buffer in range [ptr, ptr+bytes] with rollover if necessary. + * @param ptr Pointer inside circular biffer to start writing from. + * @param buf_addr Start of the circular buffer. + * @param buf_end End of the circular buffer. + * @param bytes Size of the fragment to write zeros. + */ +static inline void cir_buf_set_zero(void *ptr, void *buf_addr, void *buf_end, uint32_t bytes) +{ + uint32_t head_size = bytes; + uint32_t tail_size = 0; + + /* check for potential wrap */ + if ((char *)ptr + bytes > (char *)buf_end) { + head_size = (char *)buf_end - (char *)ptr; + tail_size = bytes - head_size; + } + + memset(ptr, 0, head_size); + if (tail_size) + memset(buf_addr, 0, tail_size); +} + static inline void audio_stream_fmt_conversion(enum ipc4_bit_depth depth, enum ipc4_bit_depth valid, enum sof_ipc_frame *frame_fmt, From 2c05d313f69621e5033268d179fc3813b2b2320e Mon Sep 17 00:00:00 2001 From: Serhiy Katsyuba Date: Fri, 1 Dec 2023 12:55:51 +0100 Subject: [PATCH 5/9] ipc4: mixin/mixout: Remove redundant channel setup In channel remapping mode mixin sinks could have different number of channels. Since channel remapping mode has been removed, no need to support individual channel number setup for each sink. Signed-off-by: Serhiy Katsyuba --- src/audio/mixin_mixout/mixin_mixout.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/src/audio/mixin_mixout/mixin_mixout.c b/src/audio/mixin_mixout/mixin_mixout.c index 797807419f89..bdca194af50e 100644 --- a/src/audio/mixin_mixout/mixin_mixout.c +++ b/src/audio/mixin_mixout/mixin_mixout.c @@ -602,7 +602,6 @@ static int mixout_reset(struct processing_module *mod) static int mixin_params(struct processing_module *mod) { struct sof_ipc_stream_params *params = mod->stream_params; - struct mixin_data *md = module_get_private_data(mod); struct comp_dev *dev = mod->dev; struct list_item *blist; int ret; @@ -617,26 +616,12 @@ static int mixin_params(struct processing_module *mod) list_for_item(blist, &dev->bsink_list) { struct comp_buffer *sink; enum sof_ipc_frame frame_fmt, valid_fmt; - uint16_t sink_id; sink = buffer_from_list(blist, PPL_DIR_DOWNSTREAM); audio_stream_set_channels(&sink->stream, mod->priv.cfg.base_cfg.audio_fmt.channels_count); - /* Applying channel remapping may produce sink stream with channel count - * different from source channel count. - */ - sink_id = IPC4_SRC_QUEUE_ID(buf_get_id(sink)); - if (sink_id >= MIXIN_MAX_SINKS) { - comp_err(dev, "Sink index out of range: %u, max sink count: %u", - (uint32_t)sink_id, MIXIN_MAX_SINKS); - return -EINVAL; - } - if (md->sink_config[sink_id].mixer_mode == IPC4_MIXER_CHANNEL_REMAPPING_MODE) - audio_stream_set_channels(&sink->stream, - md->sink_config[sink_id].output_channel_count); - /* comp_verify_params() does not modify valid_sample_fmt (a BUG?), * let's do this here */ @@ -649,8 +634,7 @@ static int mixin_params(struct processing_module *mod) audio_stream_set_valid_fmt(&sink->stream, valid_fmt); } - /* use BUFF_PARAMS_CHANNELS to skip updating channel count */ - ret = comp_verify_params(dev, BUFF_PARAMS_CHANNELS, params); + ret = comp_verify_params(dev, 0, params); if (ret < 0) { comp_err(dev, "mixin_params(): comp_verify_params() failed!"); return -EINVAL; From 38b0d655c539d84e776f0bcbcf568f75eebd8fe0 Mon Sep 17 00:00:00 2001 From: Serhiy Katsyuba Date: Fri, 1 Dec 2023 13:29:43 +0100 Subject: [PATCH 6/9] ipc4: mixin/mixout: Remove redundant buf size check The removed code may falsely fail for freq like 44.1 kHz. Also, we generally do not check for sufficient buffer size in module .prepare() handler. That should be/is done elsewhere. No need to do the exception for mixout component. Signed-off-by: Serhiy Katsyuba --- src/audio/mixin_mixout/mixin_mixout.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/audio/mixin_mixout/mixin_mixout.c b/src/audio/mixin_mixout/mixin_mixout.c index bdca194af50e..625ed30349d7 100644 --- a/src/audio/mixin_mixout/mixin_mixout.c +++ b/src/audio/mixin_mixout/mixin_mixout.c @@ -696,7 +696,6 @@ static int mixout_params(struct processing_module *mod) struct comp_buffer *sink; struct comp_dev *dev = mod->dev; enum sof_ipc_frame frame_fmt, valid_fmt; - uint32_t sink_period_bytes, sink_stream_size; int ret; comp_dbg(dev, "mixout_params()"); @@ -720,23 +719,6 @@ static int mixout_params(struct processing_module *mod) audio_stream_set_valid_fmt(&sink->stream, valid_fmt); audio_stream_set_channels(&sink->stream, params->channels); - sink_stream_size = audio_stream_get_size(&sink->stream); - - /* calculate period size based on config */ - sink_period_bytes = audio_stream_period_bytes(&sink->stream, - dev->frames); - - if (sink_period_bytes == 0) { - comp_err(dev, "mixout_params(): period_bytes = 0"); - return -EINVAL; - } - - if (sink_stream_size < sink_period_bytes) { - comp_err(dev, "mixout_params(): sink buffer size %d is insufficient < %d", - sink_stream_size, sink_period_bytes); - return -ENOMEM; - } - return 0; } From 968bd262a086ce6302fbbd6a29518c286a4886c1 Mon Sep 17 00:00:00 2001 From: Serhiy Katsyuba Date: Fri, 1 Dec 2023 16:21:39 +0100 Subject: [PATCH 7/9] ipc4: mixin/mixout: Modify .prepare() to use sink/source API Modification of mixin/mixout .prepare() handler to use sink/source API. Signed-off-by: Serhiy Katsyuba --- src/audio/mixin_mixout/mixin_mixout.c | 43 +++++++++++++++++---------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/src/audio/mixin_mixout/mixin_mixout.c b/src/audio/mixin_mixout/mixin_mixout.c index 625ed30349d7..ec575cc0073a 100644 --- a/src/audio/mixin_mixout/mixin_mixout.c +++ b/src/audio/mixin_mixout/mixin_mixout.c @@ -603,7 +603,7 @@ static int mixin_params(struct processing_module *mod) { struct sof_ipc_stream_params *params = mod->stream_params; struct comp_dev *dev = mod->dev; - struct list_item *blist; + int i; int ret; comp_dbg(dev, "mixin_params()"); @@ -613,14 +613,27 @@ static int mixin_params(struct processing_module *mod) /* Buffers between mixins and mixouts are not used (mixin writes data directly to mixout * sink). But, anyway, let's setup these buffers properly just in case. */ - list_for_item(blist, &dev->bsink_list) { - struct comp_buffer *sink; - enum sof_ipc_frame frame_fmt, valid_fmt; - sink = buffer_from_list(blist, PPL_DIR_DOWNSTREAM); + /* FIXME: there are 2 problems with the loop below: + * + * (1) struct sof_audio_stream_params contains two frame format members: frame_fmt + * and valid_sample_fmt both of type enum sof_ipc_frame. That is excessive as + * enum sof_ipc_frame describes both container and sample size and so having one + * variable of this type is enough. frame_fmt is set by comp_verify_params(), however, + * valid_sample_fmt does not. Hence valid_sample_fmt is set below in a loop. If mess + * with having both frame_fmt and valid_sample_fmt in SOF is solved when this loop can + * be removed. + * + * (2) comp_verify_params() setup sink buffers for playback pipeline and source buffers + * for capture pipelines. So in case problem (1) is solved the loop is only needed if + * mixin is on capture pipeline and mixout is in playback pipeline. Such topology seems + * makes not much sense and probably never used. In all other cases comp_verify_params() + * will be sufficient to setup buffers and so the loop below may be removed. + */ + for (i = 0; i < mod->num_of_sinks; i++) { + enum sof_ipc_frame frame_fmt, valid_fmt; - audio_stream_set_channels(&sink->stream, - mod->priv.cfg.base_cfg.audio_fmt.channels_count); + sink_set_channels(mod->sinks[i], mod->priv.cfg.base_cfg.audio_fmt.channels_count); /* comp_verify_params() does not modify valid_sample_fmt (a BUG?), * let's do this here @@ -630,8 +643,8 @@ static int mixin_params(struct processing_module *mod) &frame_fmt, &valid_fmt, mod->priv.cfg.base_cfg.audio_fmt.s_type); - audio_stream_set_frm_fmt(&sink->stream, frame_fmt); - audio_stream_set_valid_fmt(&sink->stream, valid_fmt); + sink_set_frm_fmt(mod->sinks[i], frame_fmt); + sink_set_valid_fmt(mod->sinks[i], valid_fmt); } ret = comp_verify_params(dev, 0, params); @@ -657,7 +670,6 @@ static int mixin_prepare(struct processing_module *mod, { struct mixin_data *md = module_get_private_data(mod); struct comp_dev *dev = mod->dev; - struct comp_buffer *sink; enum sof_ipc_frame fmt; int ret; @@ -667,8 +679,7 @@ static int mixin_prepare(struct processing_module *mod, if (ret < 0) return ret; - sink = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - fmt = audio_stream_get_valid_fmt(&sink->stream); + fmt = sink_get_valid_fmt(sinks[0]); /* currently inactive so setup mixer */ switch (fmt) { @@ -693,7 +704,6 @@ static int mixin_prepare(struct processing_module *mod, static int mixout_params(struct processing_module *mod) { struct sof_ipc_stream_params *params = mod->stream_params; - struct comp_buffer *sink; struct comp_dev *dev = mod->dev; enum sof_ipc_frame frame_fmt, valid_fmt; int ret; @@ -708,7 +718,9 @@ static int mixout_params(struct processing_module *mod) return -EINVAL; } - sink = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); + /* FIXME: the code below could/should be removed once mess with having both frame_fmt + * and valid_sample_fmt is solved (see comment in mixin_params()). + */ /* comp_verify_params() does not modify valid_sample_fmt (a BUG?), let's do this here */ audio_stream_fmt_conversion(mod->priv.cfg.base_cfg.audio_fmt.depth, @@ -716,8 +728,7 @@ static int mixout_params(struct processing_module *mod) &frame_fmt, &valid_fmt, mod->priv.cfg.base_cfg.audio_fmt.s_type); - audio_stream_set_valid_fmt(&sink->stream, valid_fmt); - audio_stream_set_channels(&sink->stream, params->channels); + sink_set_valid_fmt(mod->sinks[0], valid_fmt); return 0; } From 7322f615765900bf34c76324fcd818f49607329f Mon Sep 17 00:00:00 2001 From: Rander Wang Date: Fri, 8 Dec 2023 17:30:42 +0800 Subject: [PATCH 8/9] module: prepare sink & source in bind & unbind function Module will update source & sink information when bind & unbind event happen. Signed-off-by: Rander Wang --- .../module_adapter/module_adapter_ipc4.c | 35 +++++++++++++------ .../sof/audio/module_adapter/module/modules.h | 2 ++ 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/audio/module_adapter/module_adapter_ipc4.c b/src/audio/module_adapter/module_adapter_ipc4.c index 65ca8e806e3f..ad3617b1ca23 100644 --- a/src/audio/module_adapter/module_adapter_ipc4.c +++ b/src/audio/module_adapter/module_adapter_ipc4.c @@ -155,22 +155,35 @@ int module_adapter_get_attribute(struct comp_dev *dev, uint32_t type, void *valu return 0; } -static bool module_adapter_multi_sink_source_check(struct comp_dev *dev) +static bool module_adapter_multi_sink_source_prepare(struct comp_dev *dev) { struct processing_module *mod = comp_get_drvdata(dev); struct list_item *blist; - int num_sources = 0; - int num_sinks = 0; + int i; + + /* acquire all sink and source buffers, get handlers to sink/source API */ + i = 0; + list_for_item(blist, &dev->bsink_list) { + struct comp_buffer *sink_buffer = + container_of(blist, struct comp_buffer, source_list); + mod->sinks[i] = audio_stream_get_sink(&sink_buffer->stream); + i++; + } + mod->num_of_sinks = i; - list_for_item(blist, &dev->bsource_list) - num_sources++; + i = 0; + list_for_item(blist, &dev->bsource_list) { + struct comp_buffer *source_buffer = + container_of(blist, struct comp_buffer, sink_list); - list_for_item(blist, &dev->bsink_list) - num_sinks++; + mod->sources[i] = audio_stream_get_source(&source_buffer->stream); + i++; + } + mod->num_of_sources = i; - comp_dbg(dev, "num_sources=%d num_sinks=%d", num_sources, num_sinks); + comp_dbg(dev, "num_sources=%d num_sinks=%d", mod->num_of_sinks, mod->num_of_sinks); - if (num_sources != 1 || num_sinks != 1) + if (mod->num_of_sinks != 1 || mod->num_of_sinks != 1) return true; /* re-assign the source/sink modules */ @@ -190,7 +203,7 @@ int module_adapter_bind(struct comp_dev *dev, void *data) if (ret < 0) return ret; - mod->stream_copy_single_to_single = !module_adapter_multi_sink_source_check(dev); + mod->stream_copy_single_to_single = !module_adapter_multi_sink_source_prepare(dev); return 0; } @@ -204,7 +217,7 @@ int module_adapter_unbind(struct comp_dev *dev, void *data) if (ret < 0) return ret; - mod->stream_copy_single_to_single = !module_adapter_multi_sink_source_check(dev); + mod->stream_copy_single_to_single = !module_adapter_multi_sink_source_prepare(dev); return 0; } diff --git a/src/include/sof/audio/module_adapter/module/modules.h b/src/include/sof/audio/module_adapter/module/modules.h index ae514bcbf09e..bcfe2a6ae795 100644 --- a/src/include/sof/audio/module_adapter/module/modules.h +++ b/src/include/sof/audio/module_adapter/module/modules.h @@ -66,6 +66,8 @@ static inline void declare_dynamic_module_adapter(struct comp_driver *drv, drv->ops.set_large_config = module_set_large_config; drv->ops.get_large_config = module_get_large_config; drv->ops.get_attribute = module_adapter_get_attribute; + drv->ops.bind = module_adapter_bind; + drv->ops.unbind = module_adapter_unbind; } #endif /* __SOF_AUDIO_MODULES__ */ From 35ca9e40d7a66475efdc846b99f15193ea2d84dd Mon Sep 17 00:00:00 2001 From: Rander Wang Date: Fri, 8 Dec 2023 17:31:34 +0800 Subject: [PATCH 9/9] module_adapter: remove duplicate source & sink prepare in prepare function It is done in bind function. Signed-off-by: Marcin Szkudlinski --- src/audio/module_adapter/module_adapter.c | 42 +++-------------------- 1 file changed, 5 insertions(+), 37 deletions(-) diff --git a/src/audio/module_adapter/module_adapter.c b/src/audio/module_adapter/module_adapter.c index e30c6cbc51cb..a7753f9776c6 100644 --- a/src/audio/module_adapter/module_adapter.c +++ b/src/audio/module_adapter/module_adapter.c @@ -119,39 +119,6 @@ struct comp_dev *module_adapter_new(const struct comp_driver *drv, return NULL; } -static int module_adapter_sink_src_prepare(struct comp_dev *dev) -{ - struct processing_module *mod = comp_get_drvdata(dev); - struct list_item *blist; - int ret; - int i; - - /* acquire all sink and source buffers, get handlers to sink/source API */ - i = 0; - list_for_item(blist, &dev->bsink_list) { - struct comp_buffer *sink_buffer = - container_of(blist, struct comp_buffer, source_list); - mod->sinks[i] = audio_stream_get_sink(&sink_buffer->stream); - i++; - } - mod->num_of_sinks = i; - - i = 0; - list_for_item(blist, &dev->bsource_list) { - struct comp_buffer *source_buffer = - container_of(blist, struct comp_buffer, sink_list); - - mod->sources[i] = audio_stream_get_source(&source_buffer->stream); - i++; - } - mod->num_of_sources = i; - - /* Prepare module */ - ret = module_prepare(mod, mod->sources, mod->num_of_sources, mod->sinks, mod->num_of_sinks); - - return ret; -} - #if CONFIG_ZEPHYR_DP_SCHEDULER static int module_adapter_dp_queue_prepare(struct comp_dev *dev) { @@ -171,7 +138,7 @@ static int module_adapter_dp_queue_prepare(struct comp_dev *dev) list_init(&mod->dp_queue_ll_to_dp_list); list_init(&mod->dp_queue_dp_to_ll_list); - ret = module_adapter_sink_src_prepare(dev); + ret = module_prepare(mod, mod->sources, mod->num_of_sources, mod->sinks, mod->num_of_sinks); if (ret) return ret; @@ -198,7 +165,7 @@ static int module_adapter_dp_queue_prepare(struct comp_dev *dev) goto err; dp_queue_append_to_list(dp_queue, &mod->dp_queue_ll_to_dp_list); - /* it will override source pointers set by module_adapter_sink_src_prepare + /* it will override source pointers set before * module will use shadow dpQueue for processing */ mod->sources[i] = dp_queue_get_source(dp_queue); @@ -232,7 +199,7 @@ static int module_adapter_dp_queue_prepare(struct comp_dev *dev) goto err; dp_queue_append_to_list(dp_queue, &mod->dp_queue_dp_to_ll_list); - /* it will override sink pointers set by module_adapter_sink_src_prepare + /* it will override sink pointers set before * module will use shadow dpQueue for processing */ mod->sinks[i] = dp_queue_get_sink(dp_queue); @@ -328,7 +295,8 @@ int module_adapter_prepare(struct comp_dev *dev) else if (IS_PROCESSING_MODE_SINK_SOURCE(mod) && mod->dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_LL) - ret = module_adapter_sink_src_prepare(dev); + ret = module_prepare(mod, mod->sources, mod->num_of_sources, + mod->sinks, mod->num_of_sinks); else if ((IS_PROCESSING_MODE_RAW_DATA(mod) || IS_PROCESSING_MODE_AUDIO_STREAM(mod)) && mod->dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_LL)