From e153d75cfd69c31c8c4b1c5c5c8afabaf39f1e44 Mon Sep 17 00:00:00 2001 From: Marcin Szkudlinski Date: Mon, 15 May 2023 23:20:34 +0200 Subject: [PATCH 01/10] buffer: don't access stream internals add more functions to audio_stream internals Signed-off-by: Marcin Szkudlinski --- src/audio/asrc/asrc.c | 2 +- src/audio/buffer.c | 10 +++--- src/audio/copier/copier_generic.c | 8 ++--- src/audio/google/google_hotword_detect.c | 2 +- src/audio/host-zephyr.c | 2 +- src/audio/igo_nr/igo_nr.c | 3 +- src/audio/mixer/mixer.c | 2 +- .../module_adapter/module/volume/volume.c | 2 +- src/audio/rtnr/rtnr.c | 2 +- src/audio/selector/selector.c | 3 +- src/include/sof/audio/audio_stream.h | 12 +++++++ src/samples/audio/detect_test.c | 2 +- src/samples/audio/smart_amp_test_ipc3.c | 4 +-- src/samples/audio/smart_amp_test_ipc4.c | 9 +++--- test/cmocka/src/audio/eq_fir/eq_fir_process.c | 16 +++++----- test/cmocka/src/audio/eq_iir/eq_iir_process.c | 16 +++++----- .../audio/mux/mux_get_processing_function.c | 8 ++--- .../cmocka/src/audio/selector/selector_test.c | 8 ++--- test/cmocka/src/audio/volume/volume_process.c | 8 ++--- test/cmocka/src/math/fft/fft.c | 32 +++++++++---------- test/cmocka/src/util.h | 8 ++--- tools/testbench/file.c | 18 +++++------ 22 files changed, 96 insertions(+), 81 deletions(-) diff --git a/src/audio/asrc/asrc.c b/src/audio/asrc/asrc.c index afe6f807260e..ecdb4b371b00 100644 --- a/src/audio/asrc/asrc.c +++ b/src/audio/asrc/asrc.c @@ -555,7 +555,7 @@ static int asrc_params(struct comp_dev *dev, /* Don't change sink rate if value from IPC is 0 (auto detect) */ if (asrc_get_sink_rate(&cd->ipc_config)) - sink_c->stream.rate = asrc_get_sink_rate(&cd->ipc_config); + audio_stream_set_rate(&sink_c->stream, asrc_get_sink_rate(&cd->ipc_config)); /* set source/sink_frames/rate */ cd->source_rate = audio_stream_get_rate(&source_c->stream); diff --git a/src/audio/buffer.c b/src/audio/buffer.c index 18d2c90473d6..03cd60a3c1f3 100644 --- a/src/audio/buffer.c +++ b/src/audio/buffer.c @@ -65,8 +65,8 @@ struct comp_buffer *buffer_alloc(uint32_t size, uint32_t caps, uint32_t flags, u buffer_c->stream.addr = stream_addr; buffer_init(buffer_c, size, caps); - buffer_c->stream.underrun_permitted = !!(flags & SOF_BUF_UNDERRUN_PERMITTED); - buffer_c->stream.overrun_permitted = !!(flags & SOF_BUF_OVERRUN_PERMITTED); + audio_stream_set_underrun(&buffer_c->stream, !!(flags & SOF_BUF_UNDERRUN_PERMITTED)); + audio_stream_set_overrun(&buffer_c->stream, !!(flags & SOF_BUF_OVERRUN_PERMITTED)); buffer_release(buffer_c); @@ -170,15 +170,15 @@ bool buffer_params_match(struct comp_buffer __sparse_cache *buffer, assert(params); if ((flag & BUFF_PARAMS_FRAME_FMT) && - buffer->stream.frame_fmt != params->frame_fmt) + audio_stream_get_frm_fmt(&buffer->stream) != params->frame_fmt) return false; if ((flag & BUFF_PARAMS_RATE) && - buffer->stream.rate != params->rate) + audio_stream_get_rate(&buffer->stream) != params->rate) return false; if ((flag & BUFF_PARAMS_CHANNELS) && - buffer->stream.channels != params->channels) + audio_stream_get_channels(&buffer->stream) != params->channels) return false; return true; diff --git a/src/audio/copier/copier_generic.c b/src/audio/copier/copier_generic.c index 7d1e4a8522cc..4cee3dfaf4e9 100644 --- a/src/audio/copier/copier_generic.c +++ b/src/audio/copier/copier_generic.c @@ -62,15 +62,15 @@ void update_buffer_format(struct comp_buffer __sparse_cache *buf_c, enum sof_ipc_frame valid_fmt, frame_fmt; int i; - buf_c->stream.channels = fmt->channels_count; - buf_c->stream.rate = fmt->sampling_frequency; + audio_stream_set_channels(&buf_c->stream, fmt->channels_count); + audio_stream_set_rate(&buf_c->stream, fmt->sampling_frequency); audio_stream_fmt_conversion(fmt->depth, fmt->valid_bit_depth, &frame_fmt, &valid_fmt, fmt->s_type); - buf_c->stream.frame_fmt = frame_fmt; - buf_c->stream.valid_sample_fmt = valid_fmt; + audio_stream_set_frm_fmt(&buf_c->stream, frame_fmt); + audio_stream_set_valid_fmt(&buf_c->stream, valid_fmt); buf_c->buffer_fmt = fmt->interleaving_style; diff --git a/src/audio/google/google_hotword_detect.c b/src/audio/google/google_hotword_detect.c index 8faad2180e02..b948420ec36b 100644 --- a/src/audio/google/google_hotword_detect.c +++ b/src/audio/google/google_hotword_detect.c @@ -178,7 +178,7 @@ static int ghd_params(struct comp_dev *dev, sink_list); source_c = buffer_acquire(sourceb); - if (source_c->stream.channels != 1) { + if (audio_stream_get_channels(source_c->stream) != 1) { comp_err(dev, "ghd_params(): Only single-channel supported"); ret = -EINVAL; } else if (audio_stream_get_frm_fmt(&source_c->stream) != SOF_IPC_FRAME_S16_LE) { diff --git a/src/audio/host-zephyr.c b/src/audio/host-zephyr.c index d27477d1114e..725e982bc0e9 100644 --- a/src/audio/host-zephyr.c +++ b/src/audio/host-zephyr.c @@ -398,7 +398,7 @@ static uint32_t host_get_copy_bytes_normal(struct host_data *hd, struct comp_dev } dma_buf_c = buffer_acquire(hd->dma_buffer); - dma_sample_bytes = get_sample_bytes(dma_buf_c->stream.frame_fmt); + dma_sample_bytes = get_sample_bytes(audio_stream_get_frm_fmt(&dma_buf_c->stream)); buffer_release(dma_buf_c); buffer_c = buffer_acquire(buffer); diff --git a/src/audio/igo_nr/igo_nr.c b/src/audio/igo_nr/igo_nr.c index 56803a8985f4..6a0d4e147e78 100755 --- a/src/audio/igo_nr/igo_nr.c +++ b/src/audio/igo_nr/igo_nr.c @@ -402,7 +402,8 @@ static int32_t igo_nr_params(struct comp_dev *dev, cd->source_rate = audio_stream_get_rate(&source_c->stream); cd->sink_rate = audio_stream_get_rate(&sink_c->stream); - if (source_c->stream.channels != audio_stream_get_channels(&sink_c->stream)) { + if (audio_stream_get_channels(source_c->stream) != + audio_stream_get_channels(&sink_c->stream)) { comp_err(dev, "igo_nr_params(), mismatch source/sink stream channels"); cd->invalid_param = true; } diff --git a/src/audio/mixer/mixer.c b/src/audio/mixer/mixer.c index 773a0e1ef2e3..68853b23926d 100644 --- a/src/audio/mixer/mixer.c +++ b/src/audio/mixer/mixer.c @@ -200,7 +200,7 @@ static inline void mixer_set_frame_alignment(struct audio_stream __sparse_cache /* Xtensa intrinsics ask for 8-byte aligned. 5.1 format SSE audio * requires 16-byte aligned. */ - const uint32_t byte_align = source->channels == 6 ? 16 : 8; + const uint32_t byte_align = audio_stream_get_channels(source) == 6 ? 16 : 8; /*There is no limit for frame number, so set it as 1*/ const uint32_t frame_align_req = 1; diff --git a/src/audio/module_adapter/module/volume/volume.c b/src/audio/module_adapter/module/volume/volume.c index 2887243019b1..40938ad08391 100644 --- a/src/audio/module_adapter/module/volume/volume.c +++ b/src/audio/module_adapter/module/volume/volume.c @@ -1214,7 +1214,7 @@ static void volume_set_alignment(struct audio_stream __sparse_cache *source, * xtensa intrinsics ask for 8-byte aligned. 5.1 format SSE audio * requires 16-byte aligned. */ - const uint32_t byte_align = source->channels == 6 ? 16 : 8; + const uint32_t byte_align = audio_stream_get_channels(source) == 6 ? 16 : 8; /*There is no limit for frame number, so both source and sink set it to be 1*/ const uint32_t frame_align_req = 1; diff --git a/src/audio/rtnr/rtnr.c b/src/audio/rtnr/rtnr.c index 890756ecc660..2435420b1304 100644 --- a/src/audio/rtnr/rtnr.c +++ b/src/audio/rtnr/rtnr.c @@ -381,7 +381,7 @@ static int rtnr_params(struct comp_dev *dev, struct sof_ipc_stream_params *param /* set source/sink stream channels */ cd->sources_stream[0].channels = audio_stream_get_channels(&source_c->stream); - cd->sink_stream.channels = audio_stream_get_channels(&sink_c->stream); + audio_stream_set_channels(&cd->sink_stream, audio_stream_get_channels(&sink_c->stream)); /* set source/sink stream overrun/underrun permitted */ cd->sources_stream[0].overrun_permitted = audio_stream_get_overrun(&source_c->stream); diff --git a/src/audio/selector/selector.c b/src/audio/selector/selector.c index b2c5d1c92f1b..99e93b46007c 100644 --- a/src/audio/selector/selector.c +++ b/src/audio/selector/selector.c @@ -932,7 +932,8 @@ static int selector_prepare(struct processing_module *mod) * reduce channel count between source and sink */ comp_info(dev, "selector_prepare(): source sink channel = %u %u", - audio_stream_get_channels(&source_c->stream), sink_c->stream.channels); + audio_stream_get_channels(&source_c->stream), + audio_stream_get_channels(&sink_c->stream)); sink_size = audio_stream_get_size(&sink_c->stream); diff --git a/src/include/sof/audio/audio_stream.h b/src/include/sof/audio/audio_stream.h index 9a17cb229020..990e652601fa 100644 --- a/src/include/sof/audio/audio_stream.h +++ b/src/include/sof/audio/audio_stream.h @@ -201,6 +201,18 @@ static inline void audio_stream_set_channels(struct audio_stream __sparse_cache buf->channels = val; } +static inline void audio_stream_set_underrun(struct audio_stream __sparse_cache *buf, + bool underrun_permitted) +{ + buf->underrun_permitted = underrun_permitted; +} + +static inline void audio_stream_set_overrun(struct audio_stream __sparse_cache *buf, + bool overrun_permitted) +{ + buf->overrun_permitted = overrun_permitted; +} + /** * Retrieves readable address of a sample at specified index (see versions of * this macro specialized for various sample types). diff --git a/src/samples/audio/detect_test.c b/src/samples/audio/detect_test.c index 5c6903e07794..b35a826aa66c 100644 --- a/src/samples/audio/detect_test.c +++ b/src/samples/audio/detect_test.c @@ -225,7 +225,7 @@ static void default_detect_test(struct comp_dev *dev, if (cd->config.load_mips) { /* assuming count is a processing frame size in samples */ cycles_per_frame = (cd->config.load_mips * 1000000 * count) - / source->rate; + / audio_stream_get_rate(source); idelay(cycles_per_frame); } diff --git a/src/samples/audio/smart_amp_test_ipc3.c b/src/samples/audio/smart_amp_test_ipc3.c index a8c9e0898dde..b2056c6cb7d0 100644 --- a/src/samples/audio/smart_amp_test_ipc3.c +++ b/src/samples/audio/smart_amp_test_ipc3.c @@ -537,8 +537,8 @@ static int smart_amp_prepare(struct comp_dev *dev) if (sad->feedback_buf) { struct comp_buffer __sparse_cache *buf = buffer_acquire(sad->feedback_buf); - buf->stream.channels = sad->config.feedback_channels; - buf->stream.rate = audio_stream_get_rate(&buffer_c->stream); + audio_stream_set_channels(&buf->stream, sad->config.feedback_channels); + audio_stream_set_rate(&buf->stream, audio_stream_get_rate(&buffer_c->stream)); buffer_release(buf); } diff --git a/src/samples/audio/smart_amp_test_ipc4.c b/src/samples/audio/smart_amp_test_ipc4.c index 8e116445dc8e..88c630d316db 100644 --- a/src/samples/audio/smart_amp_test_ipc4.c +++ b/src/samples/audio/smart_amp_test_ipc4.c @@ -227,7 +227,7 @@ static int smart_amp_process_s16(struct processing_module *mod, int i; int j; - bsource->consumed += frames * source->channels * sizeof(int16_t); + bsource->consumed += frames * audio_stream_get_channels(source) * sizeof(int16_t); for (i = 0; i < frames; i++) { for (j = 0 ; j < sad->out_channels; j++) { if (chan_map[j] != -1) { @@ -260,7 +260,7 @@ static int smart_amp_process_s32(struct processing_module *mod, int i; int j; - bsource->consumed += frames * source->channels * sizeof(int32_t); + bsource->consumed += frames * audio_stream_get_channels(source) * sizeof(int32_t); for (i = 0; i < frames; i++) { for (j = 0 ; j < sad->out_channels; j++) { if (chan_map[j] != -1) { @@ -388,8 +388,9 @@ static int smart_amp_prepare(struct processing_module *mod) buffer_c = buffer_acquire(source_buffer); audio_stream_init_alignment_constants(1, 1, &buffer_c->stream); if (IPC4_SINK_QUEUE_ID(buffer_c->id) == SOF_SMART_AMP_FEEDBACK_QUEUE_ID) { - buffer_c->stream.channels = sad->config.feedback_channels; - buffer_c->stream.rate = mod->priv.cfg.base_cfg.audio_fmt.sampling_frequency; + audio_stream_set_channels(&buffer_c->stream, sad->config.feedback_channels); + audio_stream_set_rate(&buffer_c->stream, + mod->priv.cfg.base_cfg.audio_fmt.sampling_frequency); } buffer_release(buffer_c); } diff --git a/test/cmocka/src/audio/eq_fir/eq_fir_process.c b/test/cmocka/src/audio/eq_fir/eq_fir_process.c index 0097a2cf1469..e406a43526c8 100644 --- a/test/cmocka/src/audio/eq_fir/eq_fir_process.c +++ b/test/cmocka/src/audio/eq_fir/eq_fir_process.c @@ -214,7 +214,7 @@ static void fill_source_s16(struct test_data *td, int frames_max) sb = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); ss = &sb->stream; frames = MIN(audio_stream_get_free_frames(ss), frames_max); - samples = frames * ss->channels; + samples = frames * audio_stream_get_channels(ss); for (i = 0; i < samples; i++) { x = audio_stream_write_frag_s16(ss, i); *x = sat_int16(Q_SHIFT_RND(chirp_2ch[buffer_fill_data.idx++], 31, 15)); @@ -230,7 +230,7 @@ static void fill_source_s16(struct test_data *td, int frames_max) comp_update_buffer_produce(sb, bytes_total); } - mod->input_buffers[0].size = samples_processed / ss->channels; + mod->input_buffers[0].size = samples_processed / audio_stream_get_channels(ss); } static void verify_sink_s16(struct test_data *td) @@ -280,7 +280,7 @@ static void fill_source_s24(struct test_data *td, int frames_max) sb = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); ss = &sb->stream; frames = MIN(audio_stream_get_free_frames(ss), frames_max); - samples = frames * ss->channels; + samples = frames * audio_stream_get_channels(ss); for (i = 0; i < samples; i++) { x = audio_stream_write_frag_s32(ss, i); *x = sat_int24(Q_SHIFT_RND(chirp_2ch[buffer_fill_data.idx++], 31, 23)); @@ -296,7 +296,7 @@ static void fill_source_s24(struct test_data *td, int frames_max) comp_update_buffer_produce(sb, bytes_total); } - mod->input_buffers[0].size = samples_processed / ss->channels; + mod->input_buffers[0].size = samples_processed / audio_stream_get_channels(ss); } static void verify_sink_s24(struct test_data *td) @@ -346,7 +346,7 @@ static void fill_source_s32(struct test_data *td, int frames_max) sb = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); ss = &sb->stream; frames = MIN(audio_stream_get_free_frames(ss), frames_max); - samples = frames * ss->channels; + samples = frames * audio_stream_get_channels(ss); for (i = 0; i < samples; i++) { x = audio_stream_write_frag_s32(ss, i); *x = chirp_2ch[buffer_fill_data.idx++]; @@ -362,7 +362,7 @@ static void fill_source_s32(struct test_data *td, int frames_max) comp_update_buffer_produce(sb, bytes_total); } - mod->input_buffers[0].size = samples_processed / ss->channels; + mod->input_buffers[0].size = samples_processed / audio_stream_get_channels(ss); } static void verify_sink_s32(struct test_data *td) @@ -419,7 +419,7 @@ static void test_audio_eq_fir(void **state) while (td->continue_loop) { frames = frames_jitter(td->params->frames); - switch (source->stream.frame_fmt) { + switch (audio_stream_get_frm_fmt(&source->stream)) { case SOF_IPC_FRAME_S16_LE: fill_source_s16(td, frames); break; @@ -445,7 +445,7 @@ static void test_audio_eq_fir(void **state) comp_update_buffer_consume(source, mod->input_buffers[0].consumed); comp_update_buffer_produce(sink, mod->output_buffers[0].size); - switch (sink->stream.frame_fmt) { + switch (audio_stream_get_frm_fmt(&sink->stream)) { case SOF_IPC_FRAME_S16_LE: verify_sink_s16(td); break; diff --git a/test/cmocka/src/audio/eq_iir/eq_iir_process.c b/test/cmocka/src/audio/eq_iir/eq_iir_process.c index 697fc3554413..17aa622a7328 100644 --- a/test/cmocka/src/audio/eq_iir/eq_iir_process.c +++ b/test/cmocka/src/audio/eq_iir/eq_iir_process.c @@ -213,7 +213,7 @@ static void fill_source_s16(struct test_data *td, int frames_max) sb = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); ss = &sb->stream; frames = MIN(audio_stream_get_free_frames(ss), frames_max); - samples = frames * ss->channels; + samples = frames * audio_stream_get_channels(ss); for (i = 0; i < samples; i++) { x = audio_stream_write_frag_s16(ss, i); *x = sat_int16(Q_SHIFT_RND(chirp_2ch[buffer_fill_data.idx++], 31, 15)); @@ -229,7 +229,7 @@ static void fill_source_s16(struct test_data *td, int frames_max) comp_update_buffer_produce(sb, bytes_total); } - mod->input_buffers[0].size = samples_processed / ss->channels; + mod->input_buffers[0].size = samples_processed / audio_stream_get_channels(ss); } static void verify_sink_s16(struct test_data *td) @@ -276,7 +276,7 @@ static void fill_source_s24(struct test_data *td, int frames_max) sb = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); ss = &sb->stream; frames = MIN(audio_stream_get_free_frames(ss), frames_max); - samples = frames * ss->channels; + samples = frames * audio_stream_get_channels(ss); for (i = 0; i < samples; i++) { x = audio_stream_write_frag_s32(ss, i); *x = sat_int24(Q_SHIFT_RND(chirp_2ch[buffer_fill_data.idx++], 31, 23)); @@ -292,7 +292,7 @@ static void fill_source_s24(struct test_data *td, int frames_max) comp_update_buffer_produce(sb, bytes_total); } - mod->input_buffers[0].size = samples_processed / ss->channels; + mod->input_buffers[0].size = samples_processed / audio_stream_get_channels(ss); } static void verify_sink_s24(struct test_data *td) @@ -339,7 +339,7 @@ static void fill_source_s32(struct test_data *td, int frames_max) sb = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); ss = &sb->stream; frames = MIN(audio_stream_get_free_frames(ss), frames_max); - samples = frames * ss->channels; + samples = frames * audio_stream_get_channels(ss); for (i = 0; i < samples; i++) { x = audio_stream_write_frag_s32(ss, i); *x = chirp_2ch[buffer_fill_data.idx++]; @@ -355,7 +355,7 @@ static void fill_source_s32(struct test_data *td, int frames_max) comp_update_buffer_produce(sb, bytes_total); } - mod->input_buffers[0].size = samples_processed / ss->channels; + mod->input_buffers[0].size = samples_processed / audio_stream_get_channels(ss); } static void verify_sink_s32(struct test_data *td) @@ -409,7 +409,7 @@ static void test_audio_eq_iir(void **state) while (td->continue_loop) { frames = frames_jitter(td->params->frames); - switch (source->stream.frame_fmt) { + switch (audio_stream_get_frm_fmt(&source->stream)) { case SOF_IPC_FRAME_S16_LE: fill_source_s16(td, frames); break; @@ -434,7 +434,7 @@ static void test_audio_eq_iir(void **state) comp_update_buffer_consume(source, mod->input_buffers[0].consumed); comp_update_buffer_produce(sink, mod->output_buffers[0].size); - switch (sink->stream.frame_fmt) { + switch (audio_stream_get_frm_fmt(&sink->stream)) { case SOF_IPC_FRAME_S16_LE: verify_sink_s16(td); break; diff --git a/test/cmocka/src/audio/mux/mux_get_processing_function.c b/test/cmocka/src/audio/mux/mux_get_processing_function.c index 7dc9e99d1afd..1f9b744e6750 100644 --- a/test/cmocka/src/audio/mux/mux_get_processing_function.c +++ b/test/cmocka/src/audio/mux/mux_get_processing_function.c @@ -111,7 +111,7 @@ static void test_mux_get_processing_function_invalid_float(void **state) mux_func func = NULL; /* set frame format value to unsupported value */ - td->sink->stream.frame_fmt = SOF_IPC_FRAME_FLOAT; + audio_stream_set_frm_fmt(&td->sink->stream, SOF_IPC_FRAME_FLOAT); func = mux_get_processing_function(td->mod); @@ -125,7 +125,7 @@ static void test_mux_get_processing_function_valid_s16le(void **state) struct test_data *td = *state; mux_func func = NULL; - td->sink->stream.frame_fmt = SOF_IPC_FRAME_S16_LE; + audio_stream_set_frm_fmt(&td->sink->stream, SOF_IPC_FRAME_S16_LE); func = mux_get_processing_function(td->mod); @@ -139,7 +139,7 @@ static void test_mux_get_processing_function_valid_s24_4le(void **state) struct test_data *td = *state; mux_func func = NULL; - td->sink->stream.frame_fmt = SOF_IPC_FRAME_S24_4LE; + audio_stream_set_frm_fmt(&td->sink->stream, SOF_IPC_FRAME_S24_4LE); func = mux_get_processing_function(td->mod); @@ -153,7 +153,7 @@ static void test_mux_get_processing_function_valid_s32le(void **state) struct test_data *td = *state; mux_func func = NULL; - td->sink->stream.frame_fmt = SOF_IPC_FRAME_S32_LE; + audio_stream_set_frm_fmt(&td->sink->stream, SOF_IPC_FRAME_S32_LE); func = mux_get_processing_function(td->mod); diff --git a/test/cmocka/src/audio/selector/selector_test.c b/test/cmocka/src/audio/selector/selector_test.c index 478f88940b59..efab8045c01c 100644 --- a/test/cmocka/src/audio/selector/selector_test.c +++ b/test/cmocka/src/audio/selector/selector_test.c @@ -275,7 +275,7 @@ static void verify_s16le_2ch_to_2ch(struct processing_module *mod, { const uint16_t *src = (uint16_t *)source->r_ptr; const uint16_t *dst = (uint16_t *)sink->w_ptr; - uint32_t channels = source->channels; + uint32_t channels = audio_stream_get_channels(source); uint32_t channel; uint32_t i; double processed; @@ -300,7 +300,7 @@ static void verify_s16le_4ch_to_4ch(struct processing_module *mod, { const uint16_t *src = (uint16_t *)source->r_ptr; const uint16_t *dst = (uint16_t *)sink->w_ptr; - uint32_t channels = source->channels; + uint32_t channels = audio_stream_get_channels(source); uint32_t channel; uint32_t i; double processed; @@ -376,7 +376,7 @@ static void verify_s32le_2ch_to_2ch(struct processing_module *mod, { const uint32_t *src = (uint32_t *)source->r_ptr; const uint32_t *dst = (uint32_t *)sink->w_ptr; - uint32_t channels = source->channels; + uint32_t channels = audio_stream_get_channels(source); uint32_t channel; uint32_t i; uint32_t processed; @@ -401,7 +401,7 @@ static void verify_s32le_4ch_to_4ch(struct processing_module *mod, { const uint32_t *src = (uint32_t *)source->r_ptr; const uint32_t *dst = (uint32_t *)sink->w_ptr; - uint32_t channels = source->channels; + uint32_t channels = audio_stream_get_channels(source); uint32_t channel; uint32_t i; uint32_t processed; diff --git a/test/cmocka/src/audio/volume/volume_process.c b/test/cmocka/src/audio/volume/volume_process.c index daee756e5275..94d72a6fb8a1 100644 --- a/test/cmocka/src/audio/volume/volume_process.c +++ b/test/cmocka/src/audio/volume/volume_process.c @@ -116,7 +116,7 @@ static void verify_s16_to_s16(struct processing_module *mod, struct comp_buffer const int16_t *src = (int16_t *)source->stream.r_ptr; const int16_t *dst = (int16_t *)sink->stream.w_ptr; double processed; - int channels = sink->stream.channels; + int channels = audio_stream_get_channels(&sink->stream); int channel; int delta; int i; @@ -168,7 +168,7 @@ static void verify_s24_to_s24_s32(struct processing_module *mod, double processed; int32_t dst_sample; int32_t sample; - int channels = sink->stream.channels; + int channels = audio_stream_get_channels(&sink->stream); int channel; int delta; int i; @@ -225,7 +225,7 @@ static void verify_s32_to_s24_s32(struct processing_module *mod, const int32_t *dst = (int32_t *)sink->stream.w_ptr; int32_t dst_sample; int32_t sample; - int channels = sink->stream.channels; + int channels = audio_stream_get_channels(&sink->stream); int channel; int delta; int i; @@ -262,7 +262,7 @@ static void test_audio_vol(void **state) struct processing_module *mod = vol_state->mod; struct vol_data *cd = module_get_private_data(mod); - switch (vol_state->sinks[0]->stream.frame_fmt) { + switch (audio_stream_get_frm_fmt(&vol_state->sinks[0]->stream)) { case SOF_IPC_FRAME_S16_LE: fill_source_s16(vol_state); break; diff --git a/test/cmocka/src/math/fft/fft.c b/test/cmocka/src/math/fft/fft.c index 17986896fbab..653212c7bfc2 100644 --- a/test/cmocka/src/math/fft/fft.c +++ b/test/cmocka/src/math/fft/fft.c @@ -52,7 +52,7 @@ static void fft_real(struct comp_buffer *src, struct comp_buffer *dst, uint32_t struct fft_plan *plan; int i; - if (src->stream.channels != 1) + if (audio_stream_get_channels(&src->stream) != 1) return; if (src->stream.size < size * sizeof(int32_t) || @@ -106,7 +106,7 @@ static void ifft_complex(struct comp_buffer *src, struct comp_buffer *dst, uint3 struct fft_plan *plan; int i; - if (src->stream.channels != 1) + if (audio_stream_get_channels(&src->stream) != 1) return; if (src->stream.size < size * sizeof(struct icomplex32) || @@ -163,7 +163,7 @@ static void fft_real_2(struct comp_buffer *src, struct comp_buffer *dst1, struct fft_plan *plan; int i; - if (src->stream.channels != 2) + if (audio_stream_get_channels(&src->stream) != 2) return; if (src->stream.size < size * sizeof(int32_t) * 2 || @@ -280,7 +280,7 @@ static void test_math_fft_256(void **state) /* create sine wave */ get_sine_32(in, SINE_FREQ, SINE_FS, fft_size); - source->stream.channels = 1; + audio_stream_set_channels(&source->stream, 1); /* do fft transform */ fft_real(source, sink, fft_size); @@ -322,7 +322,7 @@ static void test_math_fft_512(void **state) /* create sine wave */ get_sine_32(in, SINE_FREQ, SINE_FS, fft_size); - source->stream.channels = 1; + audio_stream_set_channels(&source->stream, 1); /* do fft transform */ fft_real(source, sink, fft_size); @@ -364,7 +364,7 @@ static void test_math_fft_1024(void **state) /* create sine wave */ get_sine_32(in, SINE_FREQ, SINE_FS, fft_size); - source->stream.channels = 1; + audio_stream_set_channels(&source->stream, 1); /* do fft transform */ fft_real(source, sink, fft_size); @@ -405,12 +405,12 @@ static void test_math_fft_1024_ifft(void **state) (void)state; get_sine_32(in, SINE_FREQ, SINE_FS, fft_size); - source->stream.channels = 1; + audio_stream_set_channels(&source->stream, 1); /* do fft transform */ fft_real(source, intm, fft_size); - intm->stream.channels = 1; + audio_stream_set_channels(&intm->stream, 1); /* do ifft transform */ ifft_complex(intm, sink, fft_size); @@ -448,7 +448,7 @@ static void test_math_fft_512_2ch(void **state) *((int32_t *)source->stream.addr + 2 * i + 1) = input_samples[fft_size + i]; } - source->stream.channels = 2; + audio_stream_set_channels(&source->stream, 2); /* do fft transform */ fft_real_2(source, sink1, sink2, fft_size); @@ -482,7 +482,7 @@ static void fft_real_16(struct comp_buffer *src, struct comp_buffer *dst, uint32 struct fft_plan *plan; int i; - if (src->stream.channels != 1) + if (audio_stream_get_channels(&src->stream) != 1) return; if (src->stream.size < size * sizeof(int16_t) || @@ -536,7 +536,7 @@ static void ifft_complex_16(struct comp_buffer *src, struct comp_buffer *dst, ui struct fft_plan *plan; int i; - if (src->stream.channels != 1) + if (audio_stream_get_channels(&src->stream) != 1) return; if (src->stream.size < size * sizeof(struct icomplex16) || @@ -640,7 +640,7 @@ static void test_math_fft_256_16(void **state) /* create sine wave */ get_sine_16(in, SINE_FREQ, SINE_FS, fft_size); - source->stream.channels = 1; + audio_stream_set_channels(&source->stream, 1); /* do fft transform */ fft_real_16(source, sink, fft_size); @@ -682,7 +682,7 @@ static void test_math_fft_512_16(void **state) /* create sine wave */ get_sine_16(in, SINE_FREQ, SINE_FS, fft_size); - source->stream.channels = 1; + audio_stream_set_channels(&source->stream, 1); /* do fft transform */ fft_real_16(source, sink, fft_size); @@ -724,7 +724,7 @@ static void test_math_fft_1024_16(void **state) /* create sine wave */ get_sine_16(in, SINE_FREQ, SINE_FS, fft_size); - source->stream.channels = 1; + audio_stream_set_channels(&source->stream, 1); /* do fft transform */ fft_real_16(source, sink, fft_size); @@ -765,12 +765,12 @@ static void test_math_fft_1024_ifft_16(void **state) (void)state; get_sine_16(in, SINE_FREQ, SINE_FS, fft_size); - source->stream.channels = 1; + audio_stream_set_channels(&source->stream, 1); /* do fft transform */ fft_real_16(source, intm, fft_size); - intm->stream.channels = 1; + audio_stream_set_channels(&intm->stream, 1); /* do ifft transform */ ifft_complex_16(intm, sink, fft_size); diff --git a/test/cmocka/src/util.h b/test/cmocka/src/util.h index f08afc35422e..be540359395c 100644 --- a/test/cmocka/src/util.h +++ b/test/cmocka/src/util.h @@ -34,8 +34,8 @@ static inline struct comp_buffer *create_test_sink(struct comp_dev *dev, /* alloc sink and set default parameters */ buffer->sink = calloc(1, sizeof(struct comp_dev)); buffer->sink->state = COMP_STATE_PREPARE; - buffer->stream.frame_fmt = frame_fmt; - buffer->stream.channels = channels; + audio_stream_set_frm_fmt(&buffer->stream, frame_fmt); + audio_stream_set_channels(&buffer->stream, channels); return buffer; } @@ -69,8 +69,8 @@ static inline struct comp_buffer *create_test_source(struct comp_dev *dev, /* alloc source and set default parameters */ buffer->source = calloc(1, sizeof(struct comp_dev)); buffer->source->state = COMP_STATE_PREPARE; - buffer->stream.frame_fmt = frame_fmt; - buffer->stream.channels = channels; + audio_stream_set_frm_fmt(&buffer->stream, frame_fmt); + audio_stream_set_channels(&buffer->stream, channels); return buffer; } diff --git a/tools/testbench/file.c b/tools/testbench/file.c index 062848e85ad1..614ed011c9e1 100644 --- a/tools/testbench/file.c +++ b/tools/testbench/file.c @@ -429,12 +429,12 @@ static int file_s32(struct comp_dev *dev, struct audio_stream *sink, switch (cd->fs.mode) { case FILE_READ: /* read samples */ - nch = sink->channels; + nch = audio_stream_get_channels(sink); n_samples = read_samples_s32(cd, sink, frames * nch, SOF_IPC_FRAME_S32_LE); break; case FILE_WRITE: /* write samples */ - nch = source->channels; + nch = audio_stream_get_channels(source); n_samples = write_samples_s32(cd, source, frames * nch, SOF_IPC_FRAME_S32_LE); break; default: @@ -463,12 +463,12 @@ static int file_s16(struct comp_dev *dev, struct audio_stream *sink, switch (cd->fs.mode) { case FILE_READ: /* read samples */ - nch = sink->channels; + nch = audio_stream_get_channels(sink); n_samples = read_samples_s16(cd, sink, frames * nch); break; case FILE_WRITE: /* write samples */ - nch = source->channels; + nch = audio_stream_get_channels(source); n_samples = write_samples_s16(cd, source, frames * nch); break; default: @@ -497,12 +497,12 @@ static int file_s24(struct comp_dev *dev, struct audio_stream *sink, switch (cd->fs.mode) { case FILE_READ: /* read samples */ - nch = sink->channels; + nch = audio_stream_get_channels(sink); n_samples = read_samples_s32(cd, sink, frames * nch, SOF_IPC_FRAME_S24_4LE); break; case FILE_WRITE: /* write samples */ - nch = source->channels; + nch = audio_stream_get_channels(source); n_samples = write_samples_s32(cd, source, frames * nch, SOF_IPC_FRAME_S24_4LE); break; default: @@ -719,8 +719,8 @@ static int file_params(struct comp_dev *dev, /* set downstream buffer size */ stream = &buffer->stream; - samples = periods * dev->frames * stream->channels; - switch (stream->frame_fmt) { + samples = periods * dev->frames * audio_stream_get_channels(stream); + switch (audio_stream_get_frm_fmt(stream)) { case SOF_IPC_FRAME_S16_LE: ret = buffer_set_size(buffer, samples * sizeof(int16_t), 0); if (ret < 0) { @@ -757,7 +757,7 @@ static int file_params(struct comp_dev *dev, return -EINVAL; } - cd->sample_container_bytes = get_sample_bytes(stream->frame_fmt); + cd->sample_container_bytes = audio_stream_sample_bytes(stream); buffer_reset_pos(buffer, NULL); return 0; From d92202b0169c2c0157953913e10da5081a0ec712 Mon Sep 17 00:00:00 2001 From: Marcin Szkudlinski Date: Mon, 15 May 2023 23:36:05 +0200 Subject: [PATCH 02/10] stream: move all stream runtime parameters to a structure All stream parameters are now available as a single structure Signed-off-by: Marcin Szkudlinski --- src/include/sof/audio/audio_stream.h | 106 +++++++++++++++------------ 1 file changed, 60 insertions(+), 46 deletions(-) diff --git a/src/include/sof/audio/audio_stream.h b/src/include/sof/audio/audio_stream.h index 990e652601fa..9ca0a29dca65 100644 --- a/src/include/sof/audio/audio_stream.h +++ b/src/include/sof/audio/audio_stream.h @@ -30,6 +30,34 @@ * @{ */ +/** + * set of parameters describing audio stream + * this structure is shared between audio_stream.h and sink/source interface + * TODO: compressed formats + */ +struct sof_audio_stream_params { + enum sof_ipc_frame frame_fmt; /**< Sample data format */ + enum sof_ipc_frame valid_sample_fmt; + + uint32_t rate; /**< Number of data frames per second [Hz] */ + uint16_t channels; /**< Number of samples in each frame */ + + /** alignment limit of stream copy, this value indicates how many + * integer frames which can meet both byte align and frame align + * requirement. it should be set in component prepare or param functions + */ + uint16_t frame_align; + + /** + * alignment limit of stream copy, alignment is the frame_align_shift-th + * power of 2 bytes. it should be set in component prepare or param functions + */ + uint16_t frame_align_shift; + + bool overrun_permitted; /**< indicates whether overrun is permitted */ + bool underrun_permitted; /**< indicates whether underrun is permitted */ +}; + /** * Audio stream is a circular buffer aware of audio format of the data * in the buffer so provides API for reading and writing not only bytes, @@ -55,26 +83,7 @@ struct audio_stream { void *end_addr; /**< Buffer end address */ /* runtime stream params */ - enum sof_ipc_frame frame_fmt; /**< Sample data format */ - enum sof_ipc_frame valid_sample_fmt; - - uint32_t rate; /**< Number of data frames per second [Hz] */ - uint16_t channels; /**< Number of samples in each frame */ - - /** alignment limit of stream copy, this value indicates how many - * integer frames which can meet both byte align and frame align - * requirement. it should be set in component prepare or param functions - */ - uint16_t frame_align; - - /** - * alignment limit of stream copy, alignment is the frame_align_shift-th - * power of 2 bytes. it should be set in component prepare or param functions - */ - uint16_t frame_align_shift; - - bool overrun_permitted; /**< indicates whether overrun is permitted */ - bool underrun_permitted; /**< indicates whether underrun is permitted */ + struct sof_audio_stream_params runtime_stream_params; }; static inline void *audio_stream_get_rptr(const struct audio_stream __sparse_cache *buf) @@ -115,33 +124,33 @@ static inline uint32_t audio_stream_get_free(const struct audio_stream __sparse_ static inline enum sof_ipc_frame audio_stream_get_frm_fmt( const struct audio_stream __sparse_cache *buf) { - return buf->frame_fmt; + return buf->runtime_stream_params.frame_fmt; } static inline enum sof_ipc_frame audio_stream_get_valid_fmt( const struct audio_stream __sparse_cache *buf) { - return buf->valid_sample_fmt; + return buf->runtime_stream_params.valid_sample_fmt; } static inline uint32_t audio_stream_get_rate(const struct audio_stream __sparse_cache *buf) { - return buf->rate; + return buf->runtime_stream_params.rate; } static inline uint32_t audio_stream_get_channels(const struct audio_stream __sparse_cache *buf) { - return buf->channels; + return buf->runtime_stream_params.channels; } static inline bool audio_stream_get_underrun(const struct audio_stream __sparse_cache *buf) { - return buf->underrun_permitted; + return buf->runtime_stream_params.underrun_permitted; } static inline bool audio_stream_get_overrun(const struct audio_stream __sparse_cache *buf) { - return buf->overrun_permitted; + return buf->runtime_stream_params.overrun_permitted; } static inline void audio_stream_set_rptr(struct audio_stream __sparse_cache *buf, void *val) @@ -182,35 +191,35 @@ static inline void audio_stream_set_free(struct audio_stream __sparse_cache *buf static inline void audio_stream_set_frm_fmt(struct audio_stream __sparse_cache *buf, enum sof_ipc_frame val) { - buf->frame_fmt = val; + buf->runtime_stream_params.frame_fmt = val; } static inline void audio_stream_set_valid_fmt(struct audio_stream __sparse_cache *buf, enum sof_ipc_frame val) { - buf->valid_sample_fmt = val; + buf->runtime_stream_params.valid_sample_fmt = val; } static inline void audio_stream_set_rate(struct audio_stream __sparse_cache *buf, uint32_t val) { - buf->rate = val; + buf->runtime_stream_params.rate = val; } static inline void audio_stream_set_channels(struct audio_stream __sparse_cache *buf, uint16_t val) { - buf->channels = val; + buf->runtime_stream_params.channels = val; } static inline void audio_stream_set_underrun(struct audio_stream __sparse_cache *buf, bool underrun_permitted) { - buf->underrun_permitted = underrun_permitted; + buf->runtime_stream_params.underrun_permitted = underrun_permitted; } static inline void audio_stream_set_overrun(struct audio_stream __sparse_cache *buf, bool overrun_permitted) { - buf->overrun_permitted = overrun_permitted; + buf->runtime_stream_params.overrun_permitted = overrun_permitted; } /** @@ -324,9 +333,9 @@ static inline int audio_stream_set_params(struct audio_stream __sparse_cache *bu if (!params) return -EINVAL; - buffer->frame_fmt = params->frame_fmt; - buffer->rate = params->rate; - buffer->channels = params->channels; + buffer->runtime_stream_params.frame_fmt = params->frame_fmt; + buffer->runtime_stream_params.rate = params->rate; + buffer->runtime_stream_params.channels = params->channels; return 0; } @@ -338,7 +347,8 @@ static inline int audio_stream_set_params(struct audio_stream __sparse_cache *bu */ static inline uint32_t audio_stream_frame_bytes(const struct audio_stream __sparse_cache *buf) { - return get_frame_bytes(buf->frame_fmt, buf->channels); + return get_frame_bytes(buf->runtime_stream_params.frame_fmt, + buf->runtime_stream_params.channels); } /** @@ -348,7 +358,7 @@ static inline uint32_t audio_stream_frame_bytes(const struct audio_stream __spar */ static inline uint32_t audio_stream_sample_bytes(const struct audio_stream __sparse_cache *buf) { - return get_sample_bytes(buf->frame_fmt); + return get_sample_bytes(buf->runtime_stream_params.frame_fmt); } /** @@ -389,9 +399,11 @@ static inline void audio_stream_init_alignment_constants(const uint32_t byte_ali uint32_t process_size; uint32_t frame_size = audio_stream_frame_bytes(stream); - stream->frame_align = audio_stream_frame_align_get(byte_align, frame_align_req, frame_size); - process_size = stream->frame_align * frame_size; - stream->frame_align_shift = (is_power_of_2(process_size) ? 31 : 32) - clz(process_size); + stream->runtime_stream_params.frame_align = + audio_stream_frame_align_get(byte_align, frame_align_req, frame_size); + process_size = stream->runtime_stream_params.frame_align * frame_size; + stream->runtime_stream_params.frame_align_shift = + (is_power_of_2(process_size) ? 31 : 32) - clz(process_size); } /** @@ -457,7 +469,7 @@ audio_stream_get_avail_bytes(const struct audio_stream __sparse_cache *stream) * regular pace, but buffer will never be seen as completely empty by * clients, and in turn will not cause underrun/XRUN. */ - if (stream->underrun_permitted) + if (stream->runtime_stream_params.underrun_permitted) return stream->avail != 0 ? stream->avail : stream->size; return stream->avail; @@ -501,7 +513,7 @@ audio_stream_get_free_bytes(const struct audio_stream __sparse_cache *stream) * processed at regular pace, but buffer will never be seen as * completely full by clients, and in turn will not cause overrun/XRUN. */ - if (stream->overrun_permitted) + if (stream->runtime_stream_params.overrun_permitted) return stream->free != 0 ? stream->free : stream->size; return stream->free; @@ -608,10 +620,12 @@ static inline uint32_t audio_stream_avail_frames_aligned(const struct audio_stream __sparse_cache *source, const struct audio_stream __sparse_cache *sink) { - uint32_t src_frames = (audio_stream_get_avail_bytes(source) >> source->frame_align_shift) - * source->frame_align; - uint32_t sink_frames = (audio_stream_get_free_bytes(sink) >> sink->frame_align_shift) - * sink->frame_align; + uint32_t src_frames = (audio_stream_get_avail_bytes(source) >> + source->runtime_stream_params.frame_align_shift) * + source->runtime_stream_params.frame_align; + uint32_t sink_frames = (audio_stream_get_free_bytes(sink) >> + sink->runtime_stream_params.frame_align_shift) * + sink->runtime_stream_params.frame_align; return MIN(src_frames, sink_frames); } From b6a10bbf46e5643b9b0dd2305767ee264723d932 Mon Sep 17 00:00:00 2001 From: Marcin Szkudlinski Date: Fri, 9 Jun 2023 12:43:48 +0200 Subject: [PATCH 03/10] buffer: external modules use API to access buffer_fmt As no internals of audio_stream nor comp_buffer should be accessible directly, move all calls to buffer_fmt to API In addition, to let sink/source interface working, move the parameter to audio_stream structure Signed-off-by: Marcin Szkudlinski --- src/audio/aria/aria.c | 5 +++-- src/audio/buffer.c | 2 +- src/audio/copier/copier_generic.c | 6 +++--- src/audio/mux/mux.c | 10 +++++++--- src/audio/pipeline/pipeline-params.c | 2 +- src/audio/selector/selector.c | 4 ++-- src/audio/src/src.c | 3 ++- src/include/sof/audio/audio_stream.h | 13 +++++++++++++ src/include/sof/audio/buffer.h | 1 - src/ipc/ipc-helper.c | 2 +- src/samples/audio/smart_amp_test_ipc4.c | 2 +- 11 files changed, 34 insertions(+), 16 deletions(-) diff --git a/src/audio/aria/aria.c b/src/audio/aria/aria.c index 2a156ac6c8c7..68d7d9770b7a 100644 --- a/src/audio/aria/aria.c +++ b/src/audio/aria/aria.c @@ -221,12 +221,13 @@ static void aria_set_stream_params(struct comp_buffer *buffer, struct aria_data enum sof_ipc_frame valid_fmt, frame_fmt; buffer_c = buffer_acquire(buffer); - buffer_c->buffer_fmt = cd->base.audio_fmt.interleaving_style; + audio_stream_fmt_conversion(cd->base.audio_fmt.depth, cd->base.audio_fmt.valid_bit_depth, &frame_fmt, &valid_fmt, cd->base.audio_fmt.s_type); - + audio_stream_set_buffer_fmt(&buffer_c->stream, + cd->base.audio_fmt.interleaving_style); audio_stream_set_frm_fmt(&buffer_c->stream, frame_fmt); audio_stream_set_valid_fmt(&buffer_c->stream, valid_fmt); audio_stream_set_channels(&buffer_c->stream, cd->chan_cnt); diff --git a/src/audio/buffer.c b/src/audio/buffer.c index 03cd60a3c1f3..708848d050a0 100644 --- a/src/audio/buffer.c +++ b/src/audio/buffer.c @@ -155,7 +155,7 @@ int buffer_set_params(struct comp_buffer __sparse_cache *buffer, return -EINVAL; } - buffer->buffer_fmt = params->buffer_fmt; + audio_stream_set_buffer_fmt(&buffer->stream, params->buffer_fmt); for (i = 0; i < SOF_IPC_MAX_CHANNELS; i++) buffer->chmap[i] = params->chmap[i]; diff --git a/src/audio/copier/copier_generic.c b/src/audio/copier/copier_generic.c index 4cee3dfaf4e9..7af68a7f8497 100644 --- a/src/audio/copier/copier_generic.c +++ b/src/audio/copier/copier_generic.c @@ -71,8 +71,7 @@ void update_buffer_format(struct comp_buffer __sparse_cache *buf_c, audio_stream_set_frm_fmt(&buf_c->stream, frame_fmt); audio_stream_set_valid_fmt(&buf_c->stream, valid_fmt); - - buf_c->buffer_fmt = fmt->interleaving_style; + audio_stream_set_buffer_fmt(&buf_c->stream, fmt->interleaving_style); for (i = 0; i < SOF_IPC_MAX_CHANNELS; i++) buf_c->chmap[i] = (fmt->ch_map >> i * 4) & 0xf; @@ -238,7 +237,8 @@ int create_endpoint_buffer(struct comp_dev *parent_dev, audio_stream_set_rate(&buffer_c->stream, copier_cfg->base.audio_fmt.sampling_frequency); audio_stream_set_frm_fmt(&buffer_c->stream, config->frame_fmt); audio_stream_set_valid_fmt(&buffer_c->stream, valid_fmt); - buffer_c->buffer_fmt = copier_cfg->base.audio_fmt.interleaving_style; + audio_stream_set_buffer_fmt(&buffer_c->stream, + copier_cfg->base.audio_fmt.interleaving_style); for (i = 0; i < SOF_IPC_MAX_CHANNELS; i++) buffer_c->chmap[i] = (chan_map >> i * 4) & 0xf; diff --git a/src/audio/mux/mux.c b/src/audio/mux/mux.c index 3ebbf838ea72..90559144f571 100644 --- a/src/audio/mux/mux.c +++ b/src/audio/mux/mux.c @@ -305,7 +305,7 @@ static void set_mux_params(struct processing_module *mod) audio_stream_set_channels(&sink_c->stream, out_fmt.channels_count); audio_stream_set_rate(&sink_c->stream, out_fmt.sampling_frequency); - sink_c->buffer_fmt = out_fmt.interleaving_style; + audio_stream_set_buffer_fmt(&sink_c->stream, out_fmt.interleaving_style); params->frame_fmt = audio_stream_get_frm_fmt(&sink_c->stream); for (i = 0; i < SOF_IPC_MAX_CHANNELS; i++) @@ -337,7 +337,9 @@ static void set_mux_params(struct processing_module *mod) &frame_fmt, &valid_fmt, cd->md.base_cfg.audio_fmt.s_type); - source_c->buffer_fmt = cd->md.base_cfg.audio_fmt.interleaving_style; + audio_stream_set_buffer_fmt + (&source_c->stream, + cd->md.base_cfg.audio_fmt.interleaving_style); for (i = 0; i < SOF_IPC_MAX_CHANNELS; i++) source_c->chmap[i] = @@ -353,7 +355,9 @@ static void set_mux_params(struct processing_module *mod) &frame_fmt, &valid_fmt, cd->md.reference_format.s_type); - source_c->buffer_fmt = cd->md.reference_format.interleaving_style; + audio_stream_set_buffer_fmt + (&source_c->stream, + cd->md.reference_format.interleaving_style); for (i = 0; i < SOF_IPC_MAX_CHANNELS; i++) source_c->chmap[i] = diff --git a/src/audio/pipeline/pipeline-params.c b/src/audio/pipeline/pipeline-params.c index 253f958f3f67..43974e290fb4 100644 --- a/src/audio/pipeline/pipeline-params.c +++ b/src/audio/pipeline/pipeline-params.c @@ -137,7 +137,7 @@ static void pipeline_update_buffer_pcm_params(struct comp_buffer __sparse_cache struct sof_ipc_stream_params *params = data; int i; - params->buffer_fmt = buffer->buffer_fmt; + params->buffer_fmt = audio_stream_get_buffer_fmt(&buffer->stream); params->frame_fmt = audio_stream_get_frm_fmt(&buffer->stream); params->rate = audio_stream_get_rate(&buffer->stream); params->channels = audio_stream_get_channels(&buffer->stream); diff --git a/src/audio/selector/selector.c b/src/audio/selector/selector.c index 99e93b46007c..c2a588c65f51 100644 --- a/src/audio/selector/selector.c +++ b/src/audio/selector/selector.c @@ -709,7 +709,7 @@ static void set_selector_params(struct processing_module *mod, audio_stream_set_channels(&sink->stream, params->channels); audio_stream_set_rate(&sink->stream, params->rate); - sink->buffer_fmt = out_fmt->interleaving_style; + audio_stream_set_buffer_fmt(&sink->stream, out_fmt->interleaving_style); for (i = 0; i < SOF_IPC_MAX_CHANNELS; i++) sink->chmap[i] = (out_fmt->ch_map >> i * 4) & 0xf; @@ -741,7 +741,7 @@ static void set_selector_params(struct processing_module *mod, audio_stream_set_channels(&source->stream, in_fmt->channels_count); audio_stream_set_rate(&source->stream, in_fmt->sampling_frequency); - source->buffer_fmt = in_fmt->interleaving_style; + audio_stream_set_buffer_fmt(&source->stream, in_fmt->interleaving_style); for (i = 0; i < SOF_IPC_MAX_CHANNELS; i++) source->chmap[i] = (in_fmt->ch_map >> i * 4) & 0xf; diff --git a/src/audio/src/src.c b/src/audio/src/src.c index 193a17746219..f3c0a1a6b945 100644 --- a/src/audio/src/src.c +++ b/src/audio/src/src.c @@ -563,7 +563,8 @@ static void src_set_sink_params(struct comp_dev *dev, struct comp_buffer __spars audio_stream_set_valid_fmt(&sinkb->stream, valid_fmt); audio_stream_set_channels(&sinkb->stream, cd->ipc_config.base.audio_fmt.channels_count); - sinkb->buffer_fmt = cd->ipc_config.base.audio_fmt.interleaving_style; + audio_stream_set_buffer_fmt(&sinkb->stream, + cd->ipc_config.base.audio_fmt.interleaving_style); } #elif CONFIG_IPC_MAJOR_3 diff --git a/src/include/sof/audio/audio_stream.h b/src/include/sof/audio/audio_stream.h index 9ca0a29dca65..0ec7e55d320f 100644 --- a/src/include/sof/audio/audio_stream.h +++ b/src/include/sof/audio/audio_stream.h @@ -56,6 +56,8 @@ struct sof_audio_stream_params { bool overrun_permitted; /**< indicates whether overrun is permitted */ bool underrun_permitted; /**< indicates whether underrun is permitted */ + + uint32_t buffer_fmt; /**< enum sof_ipc_buffer_format */ }; /** @@ -148,6 +150,11 @@ static inline bool audio_stream_get_underrun(const struct audio_stream __sparse_ return buf->runtime_stream_params.underrun_permitted; } +static inline uint32_t audio_stream_get_buffer_fmt(struct audio_stream __sparse_cache *buf) +{ + return buf->runtime_stream_params.buffer_fmt; +} + static inline bool audio_stream_get_overrun(const struct audio_stream __sparse_cache *buf) { return buf->runtime_stream_params.overrun_permitted; @@ -222,6 +229,12 @@ static inline void audio_stream_set_overrun(struct audio_stream __sparse_cache * buf->runtime_stream_params.overrun_permitted = overrun_permitted; } +static inline void audio_stream_set_buffer_fmt(struct audio_stream __sparse_cache *buf, + uint32_t buffer_fmt) +{ + buf->runtime_stream_params.buffer_fmt = buffer_fmt; +} + /** * Retrieves readable address of a sample at specified index (see versions of * this macro specialized for various sample types). diff --git a/src/include/sof/audio/buffer.h b/src/include/sof/audio/buffer.h index c0fdc213d5d7..2eeef2d9f80a 100644 --- a/src/include/sof/audio/buffer.h +++ b/src/include/sof/audio/buffer.h @@ -154,7 +154,6 @@ struct comp_buffer { struct list_item sink_list; /* list in comp buffers */ /* runtime stream params */ - uint32_t buffer_fmt; /**< enum sof_ipc_buffer_format */ uint16_t chmap[SOF_IPC_MAX_CHANNELS]; /**< channel map - SOF_CHMAP_ */ bool hw_params_configured; /**< indicates whether hw params were set */ diff --git a/src/ipc/ipc-helper.c b/src/ipc/ipc-helper.c index a8fb4b41f548..00119ce5403c 100644 --- a/src/ipc/ipc-helper.c +++ b/src/ipc/ipc-helper.c @@ -85,7 +85,7 @@ static void comp_update_params(uint32_t flag, params->frame_fmt = audio_stream_get_frm_fmt(&buffer->stream); if (flag & BUFF_PARAMS_BUFFER_FMT) - params->buffer_fmt = buffer->buffer_fmt; + params->buffer_fmt = audio_stream_get_buffer_fmt(&buffer->stream); if (flag & BUFF_PARAMS_CHANNELS) params->channels = audio_stream_get_channels(&buffer->stream); diff --git a/src/samples/audio/smart_amp_test_ipc4.c b/src/samples/audio/smart_amp_test_ipc4.c index 88c630d316db..1e69b87e72b3 100644 --- a/src/samples/audio/smart_amp_test_ipc4.c +++ b/src/samples/audio/smart_amp_test_ipc4.c @@ -125,7 +125,7 @@ static void smart_amp_set_params(struct processing_module *mod) audio_stream_set_valid_fmt(&sink_c->stream, valid_fmt); audio_stream_set_channels(&sink_c->stream, out_fmt.channels_count); audio_stream_set_rate(&sink_c->stream, out_fmt.sampling_frequency); - sink_c->buffer_fmt = out_fmt.interleaving_style; + audio_stream_set_buffer_fmt(&sink_c->stream, out_fmt.interleaving_style); params->frame_fmt = audio_stream_get_frm_fmt(&sink_c->stream); sink_c->hw_params_configured = true; buffer_release(sink_c); From d93b0a4c2e7df1831c0e8b30b50e07afbe3bf619 Mon Sep 17 00:00:00 2001 From: Marcin Szkudlinski Date: Mon, 17 Apr 2023 13:11:56 +0200 Subject: [PATCH 04/10] pipeline2.0: introduce a source API this is a definition of API to source of audio data THE SOURCE is any component in the system that have data stored somehow and can give the data outside at request. The source API does not define who and how has produced the data The user - a module - sees this as a producer that PROVIDES data for processing The IMPLEMENTATION - audio_stream, DP Queue - sees this API as a destination it must send data to Examples of components that should expose source API: - DMIC. Data are coming from the outside world, stores in tmp buffer and can be presented to the rest of the system using source_api - a memory ring buffer Data are coming from other module (usually using sink_api, but it does not matter in fact) Signed-off-by: Marcin Szkudlinski --- src/audio/CMakeLists.txt | 1 + src/audio/source_api_helper.c | 167 +++++++++++++++++ src/include/sof/audio/source_api.h | 174 ++++++++++++++++++ .../sof/audio/source_api_implementation.h | 91 +++++++++ test/cmocka/src/audio/buffer/CMakeLists.txt | 5 + .../cmocka/src/audio/component/CMakeLists.txt | 1 + test/cmocka/src/audio/eq_fir/CMakeLists.txt | 1 + test/cmocka/src/audio/eq_iir/CMakeLists.txt | 1 + test/cmocka/src/audio/mixer/CMakeLists.txt | 1 + test/cmocka/src/audio/mux/CMakeLists.txt | 1 + .../src/audio/pcm_converter/CMakeLists.txt | 2 +- test/cmocka/src/audio/pipeline/CMakeLists.txt | 3 + test/cmocka/src/audio/selector/CMakeLists.txt | 1 + test/cmocka/src/audio/volume/CMakeLists.txt | 1 + test/cmocka/src/math/fft/CMakeLists.txt | 1 + zephyr/CMakeLists.txt | 1 + 16 files changed, 451 insertions(+), 1 deletion(-) create mode 100644 src/audio/source_api_helper.c create mode 100644 src/include/sof/audio/source_api.h create mode 100644 src/include/sof/audio/source_api_implementation.h diff --git a/src/audio/CMakeLists.txt b/src/audio/CMakeLists.txt index 90168d890522..bf03bba51fda 100644 --- a/src/audio/CMakeLists.txt +++ b/src/audio/CMakeLists.txt @@ -11,6 +11,7 @@ if((NOT CONFIG_LIBRARY) OR CONFIG_LIBRARY_STATIC) host-legacy.c component.c buffer.c + source_api_helper.c channel_map.c ) if(CONFIG_COMP_BLOB) diff --git a/src/audio/source_api_helper.c b/src/audio/source_api_helper.c new file mode 100644 index 000000000000..fbdc74afa397 --- /dev/null +++ b/src/audio/source_api_helper.c @@ -0,0 +1,167 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2023 Intel Corporation. All rights reserved. +// + +#include +#include +#include + +void source_init(struct sof_source __sparse_cache *source, const struct source_ops *ops, + struct sof_audio_stream_params *audio_stream_params) +{ + source->ops = ops; + source->requested_read_frag_size = 0; + source->audio_stream_params = audio_stream_params; +} + +size_t source_get_data_available(struct sof_source __sparse_cache *source) +{ + return source->ops->get_data_available(source); +} + +int source_get_data(struct sof_source __sparse_cache *source, size_t req_size, + void **data_ptr, void **buffer_start, size_t *buffer_size) +{ + int ret; + + if (source->requested_read_frag_size) + return -EBUSY; + + ret = source->ops->get_data(source, req_size, data_ptr, buffer_start, buffer_size); + + if (!ret) + source->requested_read_frag_size = req_size; + return ret; +} + +int source_release_data(struct sof_source __sparse_cache *source, size_t free_size) +{ + int ret; + + /* Check if anything was obtained before for reading by source_get_data */ + if (!source->requested_read_frag_size) + return -ENODATA; + + /* limit size of data to be freed to previously obtained size */ + if (free_size > source->requested_read_frag_size) + free_size = source->requested_read_frag_size; + + ret = source->ops->release_data(source, free_size); + + if (!ret) + source->requested_read_frag_size = 0; + + source->num_of_bytes_processed += free_size; + return ret; +} + +size_t source_get_num_of_processed_bytes(struct sof_source __sparse_cache *source) +{ + return source->num_of_bytes_processed; +} + +void source_reset_num_of_processed_bytes(struct sof_source __sparse_cache *source) +{ + source->num_of_bytes_processed = 0; +} + +enum sof_ipc_frame source_get_frm_fmt(struct sof_source __sparse_cache *source) +{ + return source->audio_stream_params->frame_fmt; +} + +enum sof_ipc_frame source_get_valid_fmt(struct sof_source __sparse_cache *source) +{ + return source->audio_stream_params->valid_sample_fmt; +} + +unsigned int source_get_rate(struct sof_source __sparse_cache *source) +{ + return source->audio_stream_params->rate; +} + +unsigned int source_get_channels(struct sof_source __sparse_cache *source) +{ + return source->audio_stream_params->channels; +} + +uint32_t source_get_buffer_fmt(struct sof_source __sparse_cache *source) +{ + return source->audio_stream_params->buffer_fmt; +} + +bool source_get_underrun(struct sof_source __sparse_cache *source) +{ + return source->audio_stream_params->underrun_permitted; +} + +int source_set_valid_fmt(struct sof_source __sparse_cache *source, + enum sof_ipc_frame valid_sample_fmt) +{ + source->audio_stream_params->valid_sample_fmt = valid_sample_fmt; + if (source->ops->on_audio_format_set) + return source->ops->on_audio_format_set(source); + return 0; +} + +int source_set_rate(struct sof_source __sparse_cache *source, unsigned int rate) +{ + source->audio_stream_params->rate = rate; + if (source->ops->on_audio_format_set) + return source->ops->on_audio_format_set(source); + return 0; +} + +int source_set_channels(struct sof_source __sparse_cache *source, unsigned int channels) +{ + source->audio_stream_params->channels = channels; + if (source->ops->on_audio_format_set) + return source->ops->on_audio_format_set(source); + return 0; +} + +int source_set_buffer_fmt(struct sof_source __sparse_cache *source, uint32_t buffer_fmt) +{ + source->audio_stream_params->buffer_fmt = buffer_fmt; + if (source->ops->on_audio_format_set) + return source->ops->on_audio_format_set(source); + return 0; +} + +int source_set_underrun(struct sof_source __sparse_cache *source, bool underrun_permitted) +{ + source->audio_stream_params->underrun_permitted = underrun_permitted; + if (source->ops->on_audio_format_set) + return source->ops->on_audio_format_set(source); + return 0; +} + +size_t source_get_frame_bytes(struct sof_source __sparse_cache *source) +{ + return get_frame_bytes(source_get_frm_fmt(source), + source_get_channels(source)); +} + +size_t source_get_data_frames_available(struct sof_source __sparse_cache *source) +{ + return source_get_data_available(source) / + source_get_frame_bytes(source); +} + +int source_set_params(struct sof_source __sparse_cache *source, + struct sof_ipc_stream_params *params, bool force_update) +{ + if (source->ops->audio_set_ipc_params) + return source->ops->audio_set_ipc_params(source, params, force_update); + return 0; +} + +int source_set_alignment_constants(struct sof_source __sparse_cache *source, + const uint32_t byte_align, + const uint32_t frame_align_req) +{ + if (source->ops->set_alignment_constants) + return source->ops->set_alignment_constants(source, byte_align, frame_align_req); + return 0; +} diff --git a/src/include/sof/audio/source_api.h b/src/include/sof/audio/source_api.h new file mode 100644 index 000000000000..ac13c286de64 --- /dev/null +++ b/src/include/sof/audio/source_api.h @@ -0,0 +1,174 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2023 Intel Corporation. All rights reserved. + * + */ + +#ifndef __SOF_SOURCE_API_H__ +#define __SOF_SOURCE_API_H__ + +#include +#include +#include +#include + +/** + * this is a definition of API to source of audio data + * + * THE SOURCE is any component in the system that have data stored somehow and can give the + * data outside at request. The source API does not define who and how has produced the data + * + * The user - a module - sees this as a producer that PROVIDES data for processing + * The IMPLEMENTATION - audio_stream, DP Queue - sees this API as a destination it must send data to + * * + * Examples of components that should expose source API: + * - DMIC + * Data are coming from the outside world, stores in tmp buffer and can be presented + * to the rest of the system using source_api + * - a memory ring buffer + * Data are coming from other module (usually using sink_api, but it does not matter in fact) + * + * The main advantage of using source API instead of just taking pointers to the data is that + * the data may be prepared at the moment the data receiver is requesting it. i.e. + * - cache may be written back/invalidated if necessary + * - data may be moved from circular to linear space + * - part of the buffer may be locked to prevent writing + * etc.etc. it depends on implementation of the data source + * + * Data in general are provided as a circular buffer and the data receiver should be able to + * deal with it. Of course if needed an implementation of source providing linear data can be + * implemented and used as a mid-layer for modules needing it. + * + * NOTE: the module should get a complete portion of data it needs for processing, process it + * than release. The reason is - the depending on the implementation, the calls may be + * expensive - may involve some data moving in memory, cache writebacks, etc. + */ + +/** definition of obfsfucated handler of source API */ +struct sof_source; + +/* forward def */ +struct sof_ipc_stream_params; + +/** + * Retrieves size of available data (in bytes) + * return number of bytes that are available for immediate use + */ +size_t source_get_data_available(struct sof_source __sparse_cache *source); + +/** + * Retrieves size of available data (in frames) + * return number of bytes that are available for immediate use + */ +size_t source_get_data_frames_available(struct sof_source __sparse_cache *source); + +/** + * Retrieves a fragment of circular data to be used by the caller (to read) + * After calling get_data, the data are guaranteed to be available + * for exclusive use (read only) + * if the provided pointers are cached, it is guaranteed that the caller may safely use it without + * any additional cache operations + * + * The caller MUST take care of data circularity based on provided pointers + * + * Depending on implementation - there may be a way to have several receivers of the same + * data, as long as the receiver respects that data are read-only and won'do anything + * fancy with cache handling itself + * + * some implementation data may be stored in linear buffer + * in that case: + * data_ptr = buffer_start + * buffer_end = data_ptr + req_size + * buffer_size = req_size + * + * and the data receiver may use it as usual, rollover will simple never occur + * NOTE! the caller MUST NOT assume that pointers to start/end of the circular buffer + * are constant. They may change between calls + * + * @param source a handler to source + * @param [in] req_size requested size of data. + * @param [out] data_ptr a pointer to data will be provided there + * @param [out] buffer_start pointer to circular buffer start + * @param [out] buffer_size size of circular buffer + * + * @retval -ENODATA if req_size is bigger than available data + */ +int source_get_data(struct sof_source __sparse_cache *source, size_t req_size, + void **data_ptr, void **buffer_start, size_t *buffer_size); + +/** + * Releases fragment previously obtained by source_get_data() + * Once called, the data are no longer available for the caller + * + * @param source a handler to source + * @param free_size amount of data that the caller declares as "never needed again" + * if free_size == 0 the source implementation MUST keep all data in memory and make them + * available again at next get_data() call + * if free_size is bigger than the amount of data obtained before by get_data(), only + * the amount obtained before will be freed. That means - if somebody obtained some data, + * processed it and won't need it again, it may simple call put_data with free_size==MAXINT + * + * @return proper error code (0 on success) + */ +int source_release_data(struct sof_source __sparse_cache *source, size_t free_size); + +/** + * Get total number of bytes processed by the source (meaning - freed by source_release_data()) + */ +size_t source_get_num_of_processed_bytes(struct sof_source __sparse_cache *source); + +/** + * sets counter of total number of bytes processed to zero + */ +void source_reset_num_of_processed_bytes(struct sof_source __sparse_cache *source); + +/** get size of a single audio frame (in bytes) */ +size_t source_get_frame_bytes(struct sof_source __sparse_cache *source); + +/** set of functions for retrieve audio parameters */ +enum sof_ipc_frame source_get_frm_fmt(struct sof_source __sparse_cache *source); +enum sof_ipc_frame source_get_valid_fmt(struct sof_source __sparse_cache *source); +unsigned int source_get_rate(struct sof_source __sparse_cache *source); +unsigned int source_get_channels(struct sof_source __sparse_cache *source); +uint32_t source_get_buffer_fmt(struct sof_source __sparse_cache *source); +bool source_get_underrun(struct sof_source __sparse_cache *source); + +/** set of functions for setting audio parameters */ +int source_set_valid_fmt(struct sof_source __sparse_cache *source, + enum sof_ipc_frame valid_sample_fmt); +int source_set_rate(struct sof_source __sparse_cache *source, unsigned int rate); +int source_set_channels(struct sof_source __sparse_cache *source, unsigned int channels); +int source_set_underrun(struct sof_source __sparse_cache *source, bool underrun_permitted); +int source_set_buffer_fmt(struct sof_source __sparse_cache *source, uint32_t buffer_fmt); + +/** + * initial set of audio parameters, provided in sof_ipc_stream_params + * + * @param source a handler to source + * @param params the set of parameters + * @param force_update tells the implementation that the params should override actual settings + * @return 0 if success + */ +int source_set_params(struct sof_source __sparse_cache *source, + struct sof_ipc_stream_params *params, bool force_update); + +/** + * Set frame_align_shift and frame_align of stream according to byte_align and + * frame_align_req alignment requirement. Once the channel number,frame size + * are determined, the frame_align and frame_align_shift are determined too. + * these two feature will be used in audio_stream_get_avail_frames_aligned + * to calculate the available frames. it should be called in component prepare + * or param functions only once before stream copy. if someone forgets to call + * this first, there would be unexampled error such as nothing is copied at all. + * + * @param source a handler to source + * @param byte_align Processing byte alignment requirement. + * @param frame_align_req Processing frames alignment requirement. + * + * @return 0 if success + */ +int source_set_alignment_constants(struct sof_source __sparse_cache *source, + const uint32_t byte_align, + const uint32_t frame_align_req); + +#endif /* __SOF_SOURCE_API_H__ */ diff --git a/src/include/sof/audio/source_api_implementation.h b/src/include/sof/audio/source_api_implementation.h new file mode 100644 index 000000000000..6007f8c3681c --- /dev/null +++ b/src/include/sof/audio/source_api_implementation.h @@ -0,0 +1,91 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2023 Intel Corporation. All rights reserved. + * + */ + +#ifndef __SOF_SOURCE_API_IMPLEMENTATION_H__ +#define __SOF_SOURCE_API_IMPLEMENTATION_H__ + +#include +#include +#include + +/* forward def */ +struct sof_audio_stream_params; + +/** + * this is a definition of internals of source API + * + * this file should be included by the implementations of source API + * + * The clients of stream API should use functions provided in source_api.h ONLY + * + */ + +struct source_ops { + /** + * see comment of source_get_data_available() + */ + size_t (*get_data_available)(struct sof_source __sparse_cache *source); + + /** + * see comment of source_get_data_available() + */ + int (*get_data)(struct sof_source __sparse_cache *source, size_t req_size, + void **data_ptr, void **buffer_start, size_t *buffer_size); + + /** + * see comment of source_release_data() + */ + int (*release_data)(struct sof_source __sparse_cache *source, size_t free_size); + + /** + * OPTIONAL: Notification to the source implementation about changes in audio format + * + * Once any of *audio_stream_params elements changes, the implementation of + * source may need to perform some extra operations. + * This callback will be called immediately after any change + * + * @retval 0 if success, negative if new parameteres are not supported + */ + int (*on_audio_format_set)(struct sof_source __sparse_cache *source); + + /** + * OPTIONAL + * see source_set_params comments + */ + int (*audio_set_ipc_params)(struct sof_source __sparse_cache *source, + struct sof_ipc_stream_params *params, bool force_update); + + /** + * OPTIONAL + * see comment for source_set_alignment_constants + */ + int (*set_alignment_constants)(struct sof_source __sparse_cache *source, + const uint32_t byte_align, + const uint32_t frame_align_req); +}; + +/** internals of source API. NOT TO BE MODIFIED OUTSIDE OF source_api_helper.h */ +struct sof_source { + const struct source_ops *ops; + size_t requested_read_frag_size; /** keeps size of data obtained by get_data() */ + size_t num_of_bytes_processed; /** processed bytes counter */ + struct sof_audio_stream_params *audio_stream_params; +}; + +/** + * Init of the API, must be called before any operation + * + * @param source pointer to the structure + * @param ops pointer to API operations + * @param audio_stream_params pointer to structure with audio parameters + * note that the audio_stream_params must be accessible by the caller core + * the implementation must ensure coherent access to the parameteres + * in case of i.e. cross core shared queue, it must be located in non-cached memory + */ +void source_init(struct sof_source __sparse_cache *source, const struct source_ops *ops, + struct sof_audio_stream_params *audio_stream_params); + +#endif /* __SOF_SOURCE_API_IMPLEMENTATION_H__ */ diff --git a/test/cmocka/src/audio/buffer/CMakeLists.txt b/test/cmocka/src/audio/buffer/CMakeLists.txt index 7f07e1abcb61..e506582d4889 100644 --- a/test/cmocka/src/audio/buffer/CMakeLists.txt +++ b/test/cmocka/src/audio/buffer/CMakeLists.txt @@ -4,6 +4,8 @@ cmocka_test(buffer_copy buffer_copy.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c + ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c @@ -21,6 +23,7 @@ cmocka_test(buffer_new ${PROJECT_SOURCE_DIR}/test/cmocka/src/common_mocks.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c @@ -38,6 +41,7 @@ cmocka_test(buffer_wrap ${PROJECT_SOURCE_DIR}/test/cmocka/src/common_mocks.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c @@ -55,6 +59,7 @@ cmocka_test(buffer_write ${PROJECT_SOURCE_DIR}/test/cmocka/src/common_mocks.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c diff --git a/test/cmocka/src/audio/component/CMakeLists.txt b/test/cmocka/src/audio/component/CMakeLists.txt index a5868d259cf6..eed4fe8e8120 100644 --- a/test/cmocka/src/audio/component/CMakeLists.txt +++ b/test/cmocka/src/audio/component/CMakeLists.txt @@ -10,6 +10,7 @@ cmocka_test(comp_set_state ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-graph.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-params.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-schedule.c diff --git a/test/cmocka/src/audio/eq_fir/CMakeLists.txt b/test/cmocka/src/audio/eq_fir/CMakeLists.txt index 8e53643c0a78..dcce0888e9d4 100644 --- a/test/cmocka/src/audio/eq_fir/CMakeLists.txt +++ b/test/cmocka/src/audio/eq_fir/CMakeLists.txt @@ -23,6 +23,7 @@ add_library(audio_for_eq_fir STATIC ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module/generic.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/component.c ${PROJECT_SOURCE_DIR}/src/audio/data_blob.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c diff --git a/test/cmocka/src/audio/eq_iir/CMakeLists.txt b/test/cmocka/src/audio/eq_iir/CMakeLists.txt index 33eeec8f44df..3582fc71a794 100644 --- a/test/cmocka/src/audio/eq_iir/CMakeLists.txt +++ b/test/cmocka/src/audio/eq_iir/CMakeLists.txt @@ -23,6 +23,7 @@ add_library(audio_for_eq_iir STATIC ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module/generic.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/component.c ${PROJECT_SOURCE_DIR}/src/audio/data_blob.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c diff --git a/test/cmocka/src/audio/mixer/CMakeLists.txt b/test/cmocka/src/audio/mixer/CMakeLists.txt index 6d997c5b66f9..6f9dcfa0e2d8 100644 --- a/test/cmocka/src/audio/mixer/CMakeLists.txt +++ b/test/cmocka/src/audio/mixer/CMakeLists.txt @@ -13,6 +13,7 @@ cmocka_test(mixer ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module/generic.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/component.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-graph.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-params.c diff --git a/test/cmocka/src/audio/mux/CMakeLists.txt b/test/cmocka/src/audio/mux/CMakeLists.txt index c7c8335a291d..4116e25669ea 100644 --- a/test/cmocka/src/audio/mux/CMakeLists.txt +++ b/test/cmocka/src/audio/mux/CMakeLists.txt @@ -14,6 +14,7 @@ add_library( ${PROJECT_SOURCE_DIR}/src/audio/component.c ${PROJECT_SOURCE_DIR}/src/audio/data_blob.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/math/numbers.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c diff --git a/test/cmocka/src/audio/pcm_converter/CMakeLists.txt b/test/cmocka/src/audio/pcm_converter/CMakeLists.txt index 8d6f0779d294..959f056716cd 100644 --- a/test/cmocka/src/audio/pcm_converter/CMakeLists.txt +++ b/test/cmocka/src/audio/pcm_converter/CMakeLists.txt @@ -7,13 +7,13 @@ if(CONFIG_FORMAT_FLOAT) ${PROJECT_SOURCE_DIR}/src/audio/pcm_converter/pcm_converter.c ${PROJECT_SOURCE_DIR}/src/audio/pcm_converter/pcm_converter_generic.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/component.c ${PROJECT_SOURCE_DIR}/src/audio/data_blob.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c - ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-graph.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-params.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-schedule.c diff --git a/test/cmocka/src/audio/pipeline/CMakeLists.txt b/test/cmocka/src/audio/pipeline/CMakeLists.txt index 88623ebe94d1..f58aec94c4c3 100644 --- a/test/cmocka/src/audio/pipeline/CMakeLists.txt +++ b/test/cmocka/src/audio/pipeline/CMakeLists.txt @@ -25,6 +25,7 @@ cmocka_test(pipeline_new ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-graph.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-params.c @@ -43,6 +44,7 @@ cmocka_test(pipeline_connect_upstream ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-graph.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-params.c @@ -61,6 +63,7 @@ cmocka_test(pipeline_free ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-graph.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-params.c diff --git a/test/cmocka/src/audio/selector/CMakeLists.txt b/test/cmocka/src/audio/selector/CMakeLists.txt index 41c7d68552e8..26e69d8665c2 100644 --- a/test/cmocka/src/audio/selector/CMakeLists.txt +++ b/test/cmocka/src/audio/selector/CMakeLists.txt @@ -16,6 +16,7 @@ add_library(audio_for_selector STATIC ${PROJECT_SOURCE_DIR}/src/audio/selector/selector.c ${PROJECT_SOURCE_DIR}/src/audio/selector/selector_generic.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c diff --git a/test/cmocka/src/audio/volume/CMakeLists.txt b/test/cmocka/src/audio/volume/CMakeLists.txt index 862dbe90c439..5d5cb112f8cf 100644 --- a/test/cmocka/src/audio/volume/CMakeLists.txt +++ b/test/cmocka/src/audio/volume/CMakeLists.txt @@ -20,6 +20,7 @@ add_library(audio_for_volume STATIC ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter.c ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module/generic.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c diff --git a/test/cmocka/src/math/fft/CMakeLists.txt b/test/cmocka/src/math/fft/CMakeLists.txt index fba558ddf84e..e6eb0afa1256 100644 --- a/test/cmocka/src/math/fft/CMakeLists.txt +++ b/test/cmocka/src/math/fft/CMakeLists.txt @@ -8,6 +8,7 @@ cmocka_test(fft ${PROJECT_SOURCE_DIR}/src/math/fft/fft_32.c ${PROJECT_SOURCE_DIR}/src/math/fft/fft_32_hifi3.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c + ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c diff --git a/zephyr/CMakeLists.txt b/zephyr/CMakeLists.txt index 9d92a67db85d..c9836615fc6b 100644 --- a/zephyr/CMakeLists.txt +++ b/zephyr/CMakeLists.txt @@ -394,6 +394,7 @@ zephyr_library_sources( ${SOF_AUDIO_PATH}/pcm_converter/pcm_converter.c ${SOF_AUDIO_PATH}/pcm_converter/pcm_converter_generic.c ${SOF_AUDIO_PATH}/buffer.c + ${SOF_AUDIO_PATH}/source_api_helper.c ${SOF_AUDIO_PATH}/component.c ${SOF_AUDIO_PATH}/pipeline/pipeline-graph.c ${SOF_AUDIO_PATH}/pipeline/pipeline-params.c From b11045c2f1cca3b36b967b3f5905435c8744d0cc Mon Sep 17 00:00:00 2001 From: Marcin Szkudlinski Date: Mon, 17 Apr 2023 13:28:54 +0200 Subject: [PATCH 05/10] pipeline2.0: introduce a sink API this is a definition of API to sink of audio data THE SINK is any component that can store data somehow and provide a buffer to be filled with data at request. The sink API does not define how the data will be processed/used The user - a module - sees this API as a destination it must send data to The IMPLEMENTATION - audio_stream, DP Queue - sees this as a producer that PROVIDES data for processing Examples of components that should expose SINK api - /dev/null all the data stored in sink buffer are just simply discarded - I2S sender Data stored in sink buffer will be sent to the external world - a memory ring buffer data stored in the buffer will be sent to another module (usually using source API, but it does not matter in fact). Signed-off-by: Marcin Szkudlinski --- src/audio/CMakeLists.txt | 1 + src/audio/sink_api_helper.c | 177 ++++++++++++++++++ src/include/sof/audio/sink_api.h | 163 ++++++++++++++++ .../sof/audio/sink_api_implementation.h | 91 +++++++++ test/cmocka/src/audio/buffer/CMakeLists.txt | 4 + .../cmocka/src/audio/component/CMakeLists.txt | 1 + test/cmocka/src/audio/eq_fir/CMakeLists.txt | 1 + test/cmocka/src/audio/eq_iir/CMakeLists.txt | 1 + test/cmocka/src/audio/mixer/CMakeLists.txt | 1 + test/cmocka/src/audio/mux/CMakeLists.txt | 1 + .../src/audio/pcm_converter/CMakeLists.txt | 1 + test/cmocka/src/audio/pipeline/CMakeLists.txt | 3 + test/cmocka/src/audio/selector/CMakeLists.txt | 1 + test/cmocka/src/audio/volume/CMakeLists.txt | 1 + test/cmocka/src/math/fft/CMakeLists.txt | 1 + zephyr/CMakeLists.txt | 1 + 16 files changed, 449 insertions(+) create mode 100644 src/audio/sink_api_helper.c create mode 100644 src/include/sof/audio/sink_api.h create mode 100644 src/include/sof/audio/sink_api_implementation.h diff --git a/src/audio/CMakeLists.txt b/src/audio/CMakeLists.txt index bf03bba51fda..7f5b17339642 100644 --- a/src/audio/CMakeLists.txt +++ b/src/audio/CMakeLists.txt @@ -12,6 +12,7 @@ if((NOT CONFIG_LIBRARY) OR CONFIG_LIBRARY_STATIC) component.c buffer.c source_api_helper.c + sink_api_helper.c channel_map.c ) if(CONFIG_COMP_BLOB) diff --git a/src/audio/sink_api_helper.c b/src/audio/sink_api_helper.c new file mode 100644 index 000000000000..b98e1c3cac7f --- /dev/null +++ b/src/audio/sink_api_helper.c @@ -0,0 +1,177 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2023 Intel Corporation. All rights reserved. +// + +#include +#include +#include + +void sink_init(struct sof_sink __sparse_cache *sink, const struct sink_ops *ops, + struct sof_audio_stream_params *audio_stream_params) +{ + sink->ops = ops; + sink->audio_stream_params = audio_stream_params; +} + +size_t sink_get_free_size(struct sof_sink __sparse_cache *sink) +{ + return sink->ops->get_free_size(sink); +} + +int sink_get_buffer(struct sof_sink __sparse_cache *sink, size_t req_size, + void **data_ptr, void **buffer_start, size_t *buffer_size) +{ + int ret; + + if (sink->requested_write_frag_size) + return -EBUSY; + + ret = sink->ops->get_buffer(sink, req_size, data_ptr, + buffer_start, buffer_size); + + if (!ret) + sink->requested_write_frag_size = req_size; + return ret; +} + +int sink_commit_buffer(struct sof_sink __sparse_cache *sink, size_t commit_size) +{ + int ret; + + /* check if there was a buffer obtained for writing by sink_get_buffer */ + if (!sink->requested_write_frag_size) + return -ENODATA; + + /* limit size of data to be committed to previously obtained size */ + if (commit_size > sink->requested_write_frag_size) + commit_size = sink->requested_write_frag_size; + + ret = sink->ops->commit_buffer(sink, commit_size); + + if (!ret) + sink->requested_write_frag_size = 0; + + sink->num_of_bytes_processed += commit_size; + return ret; +} + +size_t sink_get_num_of_processed_bytes(struct sof_sink __sparse_cache *sink) +{ + return sink->num_of_bytes_processed; +} + +void sink_reset_num_of_processed_bytes(struct sof_sink __sparse_cache *sink) +{ + sink->num_of_bytes_processed = 0; +} + +enum sof_ipc_frame sink_get_frm_fmt(struct sof_sink __sparse_cache *sink) +{ + return sink->audio_stream_params->frame_fmt; +} + +enum sof_ipc_frame sink_get_valid_fmt(struct sof_sink __sparse_cache *sink) +{ + return sink->audio_stream_params->valid_sample_fmt; +} + +uint32_t sink_get_rate(struct sof_sink __sparse_cache *sink) +{ + return sink->audio_stream_params->rate; +} + +uint32_t sink_get_channels(struct sof_sink __sparse_cache *sink) +{ + return sink->audio_stream_params->channels; +} + +uint32_t sink_get_buffer_fmt(struct sof_sink __sparse_cache *sink) +{ + return sink->audio_stream_params->buffer_fmt; +} + +bool sink_get_overrun(struct sof_sink __sparse_cache *sink) +{ + return sink->audio_stream_params->overrun_permitted; +} + +int sink_set_frm_fmt(struct sof_sink __sparse_cache *sink, enum sof_ipc_frame frame_fmt) +{ + sink->audio_stream_params->frame_fmt = frame_fmt; + + /* notify the implementation */ + if (sink->ops->on_audio_format_set) + return sink->ops->on_audio_format_set(sink); + return 0; +} + +int sink_set_valid_fmt(struct sof_sink __sparse_cache *sink, + enum sof_ipc_frame valid_sample_fmt) +{ + sink->audio_stream_params->valid_sample_fmt = valid_sample_fmt; + if (sink->ops->on_audio_format_set) + return sink->ops->on_audio_format_set(sink); + return 0; +} + +int sink_set_rate(struct sof_sink __sparse_cache *sink, unsigned int rate) +{ + sink->audio_stream_params->rate = rate; + if (sink->ops->on_audio_format_set) + return sink->ops->on_audio_format_set(sink); + return 0; +} + +int sink_set_channels(struct sof_sink __sparse_cache *sink, unsigned int channels) +{ + sink->audio_stream_params->channels = channels; + if (sink->ops->on_audio_format_set) + return sink->ops->on_audio_format_set(sink); + return 0; +} + +int sink_set_buffer_fmt(struct sof_sink __sparse_cache *sink, uint32_t buffer_fmt) +{ + sink->audio_stream_params->buffer_fmt = buffer_fmt; + if (sink->ops->on_audio_format_set) + return sink->ops->on_audio_format_set(sink); + return 0; +} + +int sink_set_overrun(struct sof_sink __sparse_cache *sink, bool overrun_permitted) +{ + sink->audio_stream_params->overrun_permitted = overrun_permitted; + if (sink->ops->on_audio_format_set) + return sink->ops->on_audio_format_set(sink); + return 0; +} + +size_t sink_get_frame_bytes(struct sof_sink __sparse_cache *sink) +{ + return get_frame_bytes(sink_get_frm_fmt(sink), + sink_get_channels(sink)); +} + +size_t sink_get_free_frames(struct sof_sink __sparse_cache *sink) +{ + return sink_get_free_size(sink) / + sink_get_frame_bytes(sink); +} + +int sink_set_params(struct sof_sink __sparse_cache *sink, + struct sof_ipc_stream_params *params, bool force_update) +{ + if (sink->ops->audio_set_ipc_params) + return sink->ops->audio_set_ipc_params(sink, params, force_update); + return 0; +} + +int sink_set_alignment_constants(struct sof_sink __sparse_cache *sink, + const uint32_t byte_align, + const uint32_t frame_align_req) +{ + if (sink->ops->set_alignment_constants) + return sink->ops->set_alignment_constants(sink, byte_align, frame_align_req); + return 0; +} diff --git a/src/include/sof/audio/sink_api.h b/src/include/sof/audio/sink_api.h new file mode 100644 index 000000000000..b8f1b0833f7b --- /dev/null +++ b/src/include/sof/audio/sink_api.h @@ -0,0 +1,163 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2023 Intel Corporation. All rights reserved. + * + */ + +#ifndef __SOF_SINK_API_H__ +#define __SOF_SINK_API_H__ + +#include +#include +#include +#include + +/** + * this is a definition of API to sink of audio data + * + * THE SINK is any component that can store data somehow and provide a buffer to be filled + * with data at request. The sink API does not define how the data will be processed/used + * + * The user - a module - sees this API as a destination it must send data to + * The IMPLEMENTATION - audio_stream, DP Queue - sees this as a producer that + * PROVIDES data for processing + * + * Examples of components that should expose SINK api + * - /dev/null + * all the data stored in sink buffer are just simply discarded + * - I2S sender + * Data stored in sink buffer will be sent to the external world + * - a memory ring buffer + * data stored in the buffer will be sent to another module (usually using source API, but it + * does not matter in fact). + * + * The main advantage of using sink API instead of just taking pointers to the buffers is that + * the buffer may be prepared at the moment the data producer is requesting it. i.e. + * - cache may be written back/invalidated if necessary + * - data may be moved to make linear space + * - part of the buffer may be locked to prevent reading + * etc.etc. it depends on implementation of the data sink + * + * NOTE: the module should get a complete portion of space it needs for processing, fill it + * than release. The reason is - the depending on the implementation, the calls may be + * expensive - may involve some data moving in memory, cache writebacks, etc. + * + */ + +/** definition of obfsfucated handler of sink API */ +struct sof_sink; + +/* forward def */ +struct sof_ipc_stream_params; + +/** + * Retrieves size of free space available in sink (in bytes) + * return number of free bytes in buffer available to immediate filling + */ +size_t sink_get_free_size(struct sof_sink __sparse_cache *sink); + +/** + * Retrieves size of free space available in sink (in frames) + * return number of free bytes in buffer available to immediate filling + */ +size_t sink_get_free_frames(struct sof_sink __sparse_cache *sink); + +/** + * Get a circular buffer to operate on (to write). + * + * Retrieves a fragment of circular data to be used by the caller + * After calling get_buffer, the space for data is guaranteed to be available + * for exclusive use on the caller core through provided pointer + * if the provided pointers are cached, it is guaranteed that the caller may safely use it without + * any additional cache operations + * The caller MUST take care of data circularity based on provided pointers + * + * @param sink a handler to sink + * @param [in] req_size requested size of space + * @param [out] data_ptr a pointer to the space will be provided there + * @param [out] buffer_start pointer to circular buffer start + * @param [out] buffer_size size of circular buffer + * + * @retval -ENODATA if req_size is bigger than free space + * + */ +int sink_get_buffer(struct sof_sink __sparse_cache *sink, size_t req_size, + void **data_ptr, void **buffer_start, size_t *buffer_size); + +/** + * Commits that the buffer previously obtained by get_buffer is filled with data + * and ready to be used + * + * @param sink a handler to sink + * @param commit_size amount of data that the caller declares as valid + * if commit_size is bigger than the amount of data obtained before by get_buffer(), only + * the amount obtained before will be committed. That means - if somebody obtained a buffer, + * filled it with data and wants to commit it in whole, it may simple call + * commit_buffer with commit_size==MAXINT + * @return proper error code (0 on success) + */ +int sink_commit_buffer(struct sof_sink __sparse_cache *sink, size_t commit_size); + +/** + * Get total number of bytes processed by the sink (meaning - committed by sink_commit_buffer()) + * + * @param sink a handler to sink + * @return total number of processed data + */ +size_t sink_get_num_of_processed_bytes(struct sof_sink __sparse_cache *sink); + +/** + * sets counter of total number of bytes processed to zero + */ +void sink_reset_num_of_processed_bytes(struct sof_sink __sparse_cache *sink); + +/** get size of a single audio frame (in bytes) */ +size_t sink_get_frame_bytes(struct sof_sink __sparse_cache *sink); + +/** set of functions for retrieve audio parameters */ +enum sof_ipc_frame sink_get_frm_fmt(struct sof_sink __sparse_cache *sink); +enum sof_ipc_frame sink_get_valid_fmt(struct sof_sink __sparse_cache *sink); +uint32_t sink_get_rate(struct sof_sink __sparse_cache *sink); +uint32_t sink_get_channels(struct sof_sink __sparse_cache *sink); +uint32_t sink_get_buffer_fmt(struct sof_sink __sparse_cache *sink); +bool sink_get_overrun(struct sof_sink __sparse_cache *sink); + +/** set of functions for setting audio parameters */ +int sink_set_frm_fmt(struct sof_sink __sparse_cache *sink, enum sof_ipc_frame frame_fmt); +int sink_set_valid_fmt(struct sof_sink __sparse_cache *sink, enum sof_ipc_frame valid_sample_fmt); +int sink_set_rate(struct sof_sink __sparse_cache *sink, unsigned int rate); +int sink_set_channels(struct sof_sink __sparse_cache *sink, unsigned int channels); +int sink_set_overrun(struct sof_sink __sparse_cache *sink, bool overrun_permitted); +int sink_set_buffer_fmt(struct sof_sink __sparse_cache *sink, uint32_t buffer_fmt); + +/** + * initial set of audio parameters, provided in sof_ipc_stream_params + * + * @param sink a handler to sink + * @param params the set of parameters + * @param force_update tells the implementation that the params should override actual settings + * @return 0 if success + */ +int sink_set_params(struct sof_sink __sparse_cache *sink, + struct sof_ipc_stream_params *params, bool force_update); + +/** + * Set frame_align_shift and frame_align of stream according to byte_align and + * frame_align_req alignment requirement. Once the channel number,frame size + * are determined, the frame_align and frame_align_shift are determined too. + * these two feature will be used in audio_stream_get_avail_frames_aligned + * to calculate the available frames. it should be called in component prepare + * or param functions only once before stream copy. if someone forgets to call + * this first, there would be unexampled error such as nothing is copied at all. + * + * @param sink a handler to sink + * @param byte_align Processing byte alignment requirement. + * @param frame_align_req Processing frames alignment requirement. + * + * @return 0 if success + */ +int sink_set_alignment_constants(struct sof_sink __sparse_cache *sink, + const uint32_t byte_align, + const uint32_t frame_align_req); + +#endif /* __SOF_SINK_API_H__ */ diff --git a/src/include/sof/audio/sink_api_implementation.h b/src/include/sof/audio/sink_api_implementation.h new file mode 100644 index 000000000000..eb1c63ce3847 --- /dev/null +++ b/src/include/sof/audio/sink_api_implementation.h @@ -0,0 +1,91 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2023 Intel Corporation. All rights reserved. + * + */ + +#ifndef __SOF_SINK_API_IMPLEMENTATION_H__ +#define __SOF_SINK_API_IMPLEMENTATION_H__ + +#include +#include +#include + +/* forward def */ +struct sof_audio_stream_params; + +/** + * this is a definition of internals of sink API + * + * this file should be included by the implementations of sink API + * + * The clients of stream API should use functions provided in sink_api.h ONLY + * + */ + +struct sink_ops { + /** + * see comment of sink_get_free_size() + */ + size_t (*get_free_size)(struct sof_sink __sparse_cache *sink); + + /** + * see comment of sink_get_buffer() + */ + int (*get_buffer)(struct sof_sink __sparse_cache *sink, size_t req_size, + void **data_ptr, void **buffer_start, size_t *buffer_size); + + /** + * see comment of sink_commit_buffer() + */ + int (*commit_buffer)(struct sof_sink __sparse_cache *sink, size_t commit_size); + + /** + * OPTIONAL: Notification to the sink implementation about changes in audio format + * + * Once any of *audio_stream_params elements changes, the implementation of + * sink may need to perform some extra operations. + * This callback will be called immediately after any change + * + * @retval 0 if success, negative if new parameters are not supported + */ + int (*on_audio_format_set)(struct sof_sink __sparse_cache *sink); + + /** + * OPTIONAL + * see sink_set_params comments + */ + int (*audio_set_ipc_params)(struct sof_sink __sparse_cache *sink, + struct sof_ipc_stream_params *params, bool force_update); + + /** + * OPTIONAL + * see comment for sink_set_alignment_constants + */ + int (*set_alignment_constants)(struct sof_sink __sparse_cache *sink, + const uint32_t byte_align, + const uint32_t frame_align_req); +}; + +/** internals of sink API. NOT TO BE MODIFIED OUTSIDE OF sink_api_helper.h */ +struct sof_sink { + const struct sink_ops *ops; /** operations interface */ + size_t requested_write_frag_size; /** keeps number of bytes requested by get_buffer() */ + size_t num_of_bytes_processed; /** processed bytes counter */ + struct sof_audio_stream_params *audio_stream_params; /** pointer to audio params */ +}; + +/** + * Init of the API, must be called before any operation + * + * @param sink pointer to the structure + * @param ops pointer to API operations + * @param audio_stream_params pointer to structure with audio parameters + * note that the audio_stream_params must be accessible by the caller core + * the implementation must ensure coherent access to the parameteres + * in case of i.e. cross core shared queue, it must be located in non-cached memory + */ +void sink_init(struct sof_sink __sparse_cache *sink, const struct sink_ops *ops, + struct sof_audio_stream_params *audio_stream_params); + +#endif /* __SOF_SINK_API_IMPLEMENTATION_H__ */ diff --git a/test/cmocka/src/audio/buffer/CMakeLists.txt b/test/cmocka/src/audio/buffer/CMakeLists.txt index e506582d4889..0d14c5bb86ca 100644 --- a/test/cmocka/src/audio/buffer/CMakeLists.txt +++ b/test/cmocka/src/audio/buffer/CMakeLists.txt @@ -5,6 +5,7 @@ cmocka_test(buffer_copy ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c + ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c @@ -24,6 +25,7 @@ cmocka_test(buffer_new ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c + ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c @@ -42,6 +44,7 @@ cmocka_test(buffer_wrap ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c + ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c @@ -60,6 +63,7 @@ cmocka_test(buffer_write ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c + ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c diff --git a/test/cmocka/src/audio/component/CMakeLists.txt b/test/cmocka/src/audio/component/CMakeLists.txt index eed4fe8e8120..72385c0a0143 100644 --- a/test/cmocka/src/audio/component/CMakeLists.txt +++ b/test/cmocka/src/audio/component/CMakeLists.txt @@ -11,6 +11,7 @@ cmocka_test(comp_set_state ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c + ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-graph.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-params.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-schedule.c diff --git a/test/cmocka/src/audio/eq_fir/CMakeLists.txt b/test/cmocka/src/audio/eq_fir/CMakeLists.txt index dcce0888e9d4..e1dd9f7fd65e 100644 --- a/test/cmocka/src/audio/eq_fir/CMakeLists.txt +++ b/test/cmocka/src/audio/eq_fir/CMakeLists.txt @@ -24,6 +24,7 @@ add_library(audio_for_eq_fir STATIC ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module/generic.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c + ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/component.c ${PROJECT_SOURCE_DIR}/src/audio/data_blob.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c diff --git a/test/cmocka/src/audio/eq_iir/CMakeLists.txt b/test/cmocka/src/audio/eq_iir/CMakeLists.txt index 3582fc71a794..6b98a07c8642 100644 --- a/test/cmocka/src/audio/eq_iir/CMakeLists.txt +++ b/test/cmocka/src/audio/eq_iir/CMakeLists.txt @@ -24,6 +24,7 @@ add_library(audio_for_eq_iir STATIC ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module/generic.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c + ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/component.c ${PROJECT_SOURCE_DIR}/src/audio/data_blob.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c diff --git a/test/cmocka/src/audio/mixer/CMakeLists.txt b/test/cmocka/src/audio/mixer/CMakeLists.txt index 6f9dcfa0e2d8..eaaaad80a1e6 100644 --- a/test/cmocka/src/audio/mixer/CMakeLists.txt +++ b/test/cmocka/src/audio/mixer/CMakeLists.txt @@ -14,6 +14,7 @@ cmocka_test(mixer ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module/generic.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c + ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/component.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-graph.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-params.c diff --git a/test/cmocka/src/audio/mux/CMakeLists.txt b/test/cmocka/src/audio/mux/CMakeLists.txt index 4116e25669ea..ed3c42eaa059 100644 --- a/test/cmocka/src/audio/mux/CMakeLists.txt +++ b/test/cmocka/src/audio/mux/CMakeLists.txt @@ -15,6 +15,7 @@ add_library( ${PROJECT_SOURCE_DIR}/src/audio/data_blob.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c + ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/math/numbers.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c diff --git a/test/cmocka/src/audio/pcm_converter/CMakeLists.txt b/test/cmocka/src/audio/pcm_converter/CMakeLists.txt index 959f056716cd..d88019810738 100644 --- a/test/cmocka/src/audio/pcm_converter/CMakeLists.txt +++ b/test/cmocka/src/audio/pcm_converter/CMakeLists.txt @@ -8,6 +8,7 @@ if(CONFIG_FORMAT_FLOAT) ${PROJECT_SOURCE_DIR}/src/audio/pcm_converter/pcm_converter_generic.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c + ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/component.c ${PROJECT_SOURCE_DIR}/src/audio/data_blob.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c diff --git a/test/cmocka/src/audio/pipeline/CMakeLists.txt b/test/cmocka/src/audio/pipeline/CMakeLists.txt index f58aec94c4c3..6819514f614c 100644 --- a/test/cmocka/src/audio/pipeline/CMakeLists.txt +++ b/test/cmocka/src/audio/pipeline/CMakeLists.txt @@ -26,6 +26,7 @@ cmocka_test(pipeline_new ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c + ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-graph.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-params.c @@ -45,6 +46,7 @@ cmocka_test(pipeline_connect_upstream ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c + ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-graph.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-params.c @@ -64,6 +66,7 @@ cmocka_test(pipeline_free ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c + ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-graph.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-params.c diff --git a/test/cmocka/src/audio/selector/CMakeLists.txt b/test/cmocka/src/audio/selector/CMakeLists.txt index 26e69d8665c2..a955f147ad4b 100644 --- a/test/cmocka/src/audio/selector/CMakeLists.txt +++ b/test/cmocka/src/audio/selector/CMakeLists.txt @@ -17,6 +17,7 @@ add_library(audio_for_selector STATIC ${PROJECT_SOURCE_DIR}/src/audio/selector/selector_generic.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c + ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c diff --git a/test/cmocka/src/audio/volume/CMakeLists.txt b/test/cmocka/src/audio/volume/CMakeLists.txt index 5d5cb112f8cf..7d50d0c7068f 100644 --- a/test/cmocka/src/audio/volume/CMakeLists.txt +++ b/test/cmocka/src/audio/volume/CMakeLists.txt @@ -21,6 +21,7 @@ add_library(audio_for_volume STATIC ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module/generic.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c + ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c diff --git a/test/cmocka/src/math/fft/CMakeLists.txt b/test/cmocka/src/math/fft/CMakeLists.txt index e6eb0afa1256..11c5edcd08c1 100644 --- a/test/cmocka/src/math/fft/CMakeLists.txt +++ b/test/cmocka/src/math/fft/CMakeLists.txt @@ -9,6 +9,7 @@ cmocka_test(fft ${PROJECT_SOURCE_DIR}/src/math/fft/fft_32_hifi3.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c + ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c diff --git a/zephyr/CMakeLists.txt b/zephyr/CMakeLists.txt index c9836615fc6b..a5345e69391f 100644 --- a/zephyr/CMakeLists.txt +++ b/zephyr/CMakeLists.txt @@ -395,6 +395,7 @@ zephyr_library_sources( ${SOF_AUDIO_PATH}/pcm_converter/pcm_converter_generic.c ${SOF_AUDIO_PATH}/buffer.c ${SOF_AUDIO_PATH}/source_api_helper.c + ${SOF_AUDIO_PATH}/sink_api_helper.c ${SOF_AUDIO_PATH}/component.c ${SOF_AUDIO_PATH}/pipeline/pipeline-graph.c ${SOF_AUDIO_PATH}/pipeline/pipeline-params.c From 8e4ec75621161187b445be69c15a801a59fa6bff Mon Sep 17 00:00:00 2001 From: Marcin Szkudlinski Date: Mon, 17 Apr 2023 15:41:00 +0200 Subject: [PATCH 06/10] pipeline2.0: introduce sink/source utilities There are many operations on sink/source that may be put into a common library. This is the place for it. Signed-off-by: Marcin Szkudlinski --- src/audio/CMakeLists.txt | 1 + src/audio/sink_source_utils.c | 73 +++++++++++++++++++ src/include/sof/audio/sink_source_utils.h | 25 +++++++ test/cmocka/src/audio/buffer/CMakeLists.txt | 4 + .../cmocka/src/audio/component/CMakeLists.txt | 1 + test/cmocka/src/audio/eq_fir/CMakeLists.txt | 1 + test/cmocka/src/audio/eq_iir/CMakeLists.txt | 1 + test/cmocka/src/audio/mixer/CMakeLists.txt | 1 + test/cmocka/src/audio/mux/CMakeLists.txt | 1 + .../src/audio/pcm_converter/CMakeLists.txt | 1 + test/cmocka/src/audio/pipeline/CMakeLists.txt | 3 + test/cmocka/src/audio/selector/CMakeLists.txt | 1 + test/cmocka/src/audio/volume/CMakeLists.txt | 1 + test/cmocka/src/math/fft/CMakeLists.txt | 1 + zephyr/CMakeLists.txt | 1 + 15 files changed, 116 insertions(+) create mode 100644 src/audio/sink_source_utils.c create mode 100644 src/include/sof/audio/sink_source_utils.h diff --git a/src/audio/CMakeLists.txt b/src/audio/CMakeLists.txt index 7f5b17339642..b43c303aaa8e 100644 --- a/src/audio/CMakeLists.txt +++ b/src/audio/CMakeLists.txt @@ -13,6 +13,7 @@ if((NOT CONFIG_LIBRARY) OR CONFIG_LIBRARY_STATIC) buffer.c source_api_helper.c sink_api_helper.c + sink_source_utils.c channel_map.c ) if(CONFIG_COMP_BLOB) diff --git a/src/audio/sink_source_utils.c b/src/audio/sink_source_utils.c new file mode 100644 index 000000000000..671c1752d544 --- /dev/null +++ b/src/audio/sink_source_utils.c @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2023 Intel Corporation. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include +#include + +int source_to_sink_copy(struct sof_source __sparse_cache *source, + struct sof_sink __sparse_cache *sink, bool free, size_t size) +{ + uint8_t *src_ptr; + uint8_t *src_begin; + uint8_t *src_end; + uint8_t *dst_ptr; + uint8_t *dst_begin; + uint8_t *dst_end; + size_t src_size, dst_size; + int ret; + + if (!size) + return 0; + if (size > source_get_data_available(source)) + return -EFBIG; + if (size > sink_get_free_size(sink)) + return -ENOSPC; + + ret = source_get_data(source, size, + (void **)&src_ptr, + (void **)&src_begin, + &src_size); + if (ret) + return ret; + + ret = sink_get_buffer(sink, size, + (void **)&dst_ptr, + (void **)&dst_begin, + &dst_size); + if (ret) { + source_release_data(source, 0); + return ret; + } + + src_end = src_begin + src_size; + dst_end = dst_begin + dst_size; + while (size) { + uint32_t src_to_buf_overlap = (uintptr_t)src_end - (uintptr_t)src_ptr; + uint32_t dst_to_buf_overlap = (uintptr_t)dst_end - (uintptr_t)dst_ptr; + uint32_t to_copy = MIN(src_to_buf_overlap, dst_to_buf_overlap); + + to_copy = MIN(to_copy, size); + ret = memcpy_s(dst_ptr, dst_to_buf_overlap, src_ptr, to_copy); + assert(!ret); + + size -= to_copy; + src_ptr += to_copy; + dst_ptr += to_copy; + if (to_copy == src_to_buf_overlap) + src_ptr = src_begin; + if (to_copy == dst_to_buf_overlap) + dst_ptr = dst_begin; + } + + source_release_data(source, free ? INT_MAX : 0); + sink_commit_buffer(sink, INT_MAX); + return 0; +} diff --git a/src/include/sof/audio/sink_source_utils.h b/src/include/sof/audio/sink_source_utils.h new file mode 100644 index 000000000000..8f550b1d2276 --- /dev/null +++ b/src/include/sof/audio/sink_source_utils.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2023 Intel Corporation. All rights reserved. + * + */ + +#ifndef SINK_SOURCE_UTILS_H +#define SINK_SOURCE_UTILS_H + +#include +#include + +/** + * copy bytes from source to sink + * + * @param source the data source + * @param sink the data target + * @param free if true, data from source will be freed + * if false, data will remain in the source + * @param size number of bytes to be copied + */ +int source_to_sink_copy(struct sof_source __sparse_cache *source, + struct sof_sink __sparse_cache *sink, bool free, size_t size); + +#endif /* SINK_SOURCE_UTILS_H */ diff --git a/test/cmocka/src/audio/buffer/CMakeLists.txt b/test/cmocka/src/audio/buffer/CMakeLists.txt index 0d14c5bb86ca..1683577c34b9 100644 --- a/test/cmocka/src/audio/buffer/CMakeLists.txt +++ b/test/cmocka/src/audio/buffer/CMakeLists.txt @@ -6,6 +6,7 @@ cmocka_test(buffer_copy ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c + ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c @@ -26,6 +27,7 @@ cmocka_test(buffer_new ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c + ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c @@ -45,6 +47,7 @@ cmocka_test(buffer_wrap ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c + ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c @@ -64,6 +67,7 @@ cmocka_test(buffer_write ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c + ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c diff --git a/test/cmocka/src/audio/component/CMakeLists.txt b/test/cmocka/src/audio/component/CMakeLists.txt index 72385c0a0143..7534a02706ec 100644 --- a/test/cmocka/src/audio/component/CMakeLists.txt +++ b/test/cmocka/src/audio/component/CMakeLists.txt @@ -12,6 +12,7 @@ cmocka_test(comp_set_state ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c + ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-graph.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-params.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-schedule.c diff --git a/test/cmocka/src/audio/eq_fir/CMakeLists.txt b/test/cmocka/src/audio/eq_fir/CMakeLists.txt index e1dd9f7fd65e..94c3ff0f4376 100644 --- a/test/cmocka/src/audio/eq_fir/CMakeLists.txt +++ b/test/cmocka/src/audio/eq_fir/CMakeLists.txt @@ -25,6 +25,7 @@ add_library(audio_for_eq_fir STATIC ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c + ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c ${PROJECT_SOURCE_DIR}/src/audio/component.c ${PROJECT_SOURCE_DIR}/src/audio/data_blob.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c diff --git a/test/cmocka/src/audio/eq_iir/CMakeLists.txt b/test/cmocka/src/audio/eq_iir/CMakeLists.txt index 6b98a07c8642..5d28dc64d65c 100644 --- a/test/cmocka/src/audio/eq_iir/CMakeLists.txt +++ b/test/cmocka/src/audio/eq_iir/CMakeLists.txt @@ -25,6 +25,7 @@ add_library(audio_for_eq_iir STATIC ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c + ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c ${PROJECT_SOURCE_DIR}/src/audio/component.c ${PROJECT_SOURCE_DIR}/src/audio/data_blob.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c diff --git a/test/cmocka/src/audio/mixer/CMakeLists.txt b/test/cmocka/src/audio/mixer/CMakeLists.txt index eaaaad80a1e6..41a568e47fb6 100644 --- a/test/cmocka/src/audio/mixer/CMakeLists.txt +++ b/test/cmocka/src/audio/mixer/CMakeLists.txt @@ -15,6 +15,7 @@ cmocka_test(mixer ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c + ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c ${PROJECT_SOURCE_DIR}/src/audio/component.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-graph.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-params.c diff --git a/test/cmocka/src/audio/mux/CMakeLists.txt b/test/cmocka/src/audio/mux/CMakeLists.txt index ed3c42eaa059..535c042a028e 100644 --- a/test/cmocka/src/audio/mux/CMakeLists.txt +++ b/test/cmocka/src/audio/mux/CMakeLists.txt @@ -16,6 +16,7 @@ add_library( ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c + ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c ${PROJECT_SOURCE_DIR}/src/math/numbers.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c diff --git a/test/cmocka/src/audio/pcm_converter/CMakeLists.txt b/test/cmocka/src/audio/pcm_converter/CMakeLists.txt index d88019810738..aad4e3b47bd2 100644 --- a/test/cmocka/src/audio/pcm_converter/CMakeLists.txt +++ b/test/cmocka/src/audio/pcm_converter/CMakeLists.txt @@ -9,6 +9,7 @@ if(CONFIG_FORMAT_FLOAT) ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c + ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c ${PROJECT_SOURCE_DIR}/src/audio/component.c ${PROJECT_SOURCE_DIR}/src/audio/data_blob.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c diff --git a/test/cmocka/src/audio/pipeline/CMakeLists.txt b/test/cmocka/src/audio/pipeline/CMakeLists.txt index 6819514f614c..9b3c17824c10 100644 --- a/test/cmocka/src/audio/pipeline/CMakeLists.txt +++ b/test/cmocka/src/audio/pipeline/CMakeLists.txt @@ -27,6 +27,7 @@ cmocka_test(pipeline_new ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c + ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-graph.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-params.c @@ -47,6 +48,7 @@ cmocka_test(pipeline_connect_upstream ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c + ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-graph.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-params.c @@ -67,6 +69,7 @@ cmocka_test(pipeline_free ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c + ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-graph.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-params.c diff --git a/test/cmocka/src/audio/selector/CMakeLists.txt b/test/cmocka/src/audio/selector/CMakeLists.txt index a955f147ad4b..a7f83fc652be 100644 --- a/test/cmocka/src/audio/selector/CMakeLists.txt +++ b/test/cmocka/src/audio/selector/CMakeLists.txt @@ -18,6 +18,7 @@ add_library(audio_for_selector STATIC ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c + ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c diff --git a/test/cmocka/src/audio/volume/CMakeLists.txt b/test/cmocka/src/audio/volume/CMakeLists.txt index 7d50d0c7068f..150d10b25282 100644 --- a/test/cmocka/src/audio/volume/CMakeLists.txt +++ b/test/cmocka/src/audio/volume/CMakeLists.txt @@ -22,6 +22,7 @@ add_library(audio_for_volume STATIC ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c + ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c diff --git a/test/cmocka/src/math/fft/CMakeLists.txt b/test/cmocka/src/math/fft/CMakeLists.txt index 11c5edcd08c1..08ebbcdaf6f5 100644 --- a/test/cmocka/src/math/fft/CMakeLists.txt +++ b/test/cmocka/src/math/fft/CMakeLists.txt @@ -10,6 +10,7 @@ cmocka_test(fft ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c + ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c diff --git a/zephyr/CMakeLists.txt b/zephyr/CMakeLists.txt index a5345e69391f..1e65a048409c 100644 --- a/zephyr/CMakeLists.txt +++ b/zephyr/CMakeLists.txt @@ -396,6 +396,7 @@ zephyr_library_sources( ${SOF_AUDIO_PATH}/buffer.c ${SOF_AUDIO_PATH}/source_api_helper.c ${SOF_AUDIO_PATH}/sink_api_helper.c + ${SOF_AUDIO_PATH}/sink_source_utils.c ${SOF_AUDIO_PATH}/component.c ${SOF_AUDIO_PATH}/pipeline/pipeline-graph.c ${SOF_AUDIO_PATH}/pipeline/pipeline-params.c From 0c025db8f5e6ebf8a9518d7743858c534a1460ed Mon Sep 17 00:00:00 2001 From: Marcin Szkudlinski Date: Mon, 17 Apr 2023 13:31:21 +0200 Subject: [PATCH 07/10] pipeline2.0: add source/sink api to audio_stream Make audio_stream capable of using pipeline2.0 sink and source API This change makes integration of sink/src api possible in incremental way Signed-off-by: Marcin Szkudlinski --- src/audio/CMakeLists.txt | 1 + src/audio/audio_stream.c | 175 ++++++++++++++++++ src/include/sof/audio/audio_stream.h | 43 +++-- test/cmocka/src/audio/buffer/CMakeLists.txt | 4 + .../cmocka/src/audio/component/CMakeLists.txt | 1 + test/cmocka/src/audio/eq_fir/CMakeLists.txt | 1 + test/cmocka/src/audio/eq_iir/CMakeLists.txt | 1 + test/cmocka/src/audio/mixer/CMakeLists.txt | 1 + test/cmocka/src/audio/mux/CMakeLists.txt | 1 + .../src/audio/pcm_converter/CMakeLists.txt | 1 + test/cmocka/src/audio/pipeline/CMakeLists.txt | 3 + test/cmocka/src/audio/selector/CMakeLists.txt | 1 + test/cmocka/src/audio/volume/CMakeLists.txt | 1 + test/cmocka/src/math/fft/CMakeLists.txt | 1 + zephyr/CMakeLists.txt | 1 + 15 files changed, 221 insertions(+), 15 deletions(-) create mode 100644 src/audio/audio_stream.c diff --git a/src/audio/CMakeLists.txt b/src/audio/CMakeLists.txt index b43c303aaa8e..7af7b41f9bc7 100644 --- a/src/audio/CMakeLists.txt +++ b/src/audio/CMakeLists.txt @@ -14,6 +14,7 @@ if((NOT CONFIG_LIBRARY) OR CONFIG_LIBRARY_STATIC) source_api_helper.c sink_api_helper.c sink_source_utils.c + audio_stream.c channel_map.c ) if(CONFIG_COMP_BLOB) diff --git a/src/audio/audio_stream.c b/src/audio/audio_stream.c new file mode 100644 index 000000000000..53fc62885c25 --- /dev/null +++ b/src/audio/audio_stream.c @@ -0,0 +1,175 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2023 Intel Corporation. All rights reserved. +// + +#include +#include + +static size_t audio_stream_get_free_size(struct sof_sink __sparse_cache *sink) +{ + struct audio_stream __sparse_cache *audio_stream = + attr_container_of(sink, struct audio_stream __sparse_cache, + sink_api, __sparse_cache); + + return audio_stream_get_free_bytes(audio_stream); +} + +static int audio_stream_get_buffer(struct sof_sink __sparse_cache *sink, size_t req_size, + void **data_ptr, void **buffer_start, size_t *buffer_size) +{ + struct audio_stream __sparse_cache *audio_stream = + attr_container_of(sink, struct audio_stream __sparse_cache, + sink_api, __sparse_cache); + + if (req_size > audio_stream_get_free_size(sink)) + return -ENODATA; + + /* get circular buffer parameters */ + *data_ptr = audio_stream->w_ptr; + *buffer_start = audio_stream->addr; + *buffer_size = audio_stream->size; + return 0; +} + +static int audio_stream_commit_buffer(struct sof_sink __sparse_cache *sink, size_t commit_size) +{ + struct audio_stream __sparse_cache *audio_stream = + attr_container_of(sink, struct audio_stream __sparse_cache, + sink_api, __sparse_cache); + + if (commit_size) + audio_stream_produce(audio_stream, commit_size); + + return 0; +} + +static size_t audio_stream_get_data_available(struct sof_source __sparse_cache *source) +{ + struct audio_stream __sparse_cache *audio_stream = + attr_container_of(source, struct audio_stream __sparse_cache, + source_api, __sparse_cache); + + return audio_stream_get_avail_bytes(audio_stream); +} + +static int audio_stream_get_data(struct sof_source __sparse_cache *source, size_t req_size, + void **data_ptr, void **buffer_start, size_t *buffer_size) +{ + struct audio_stream __sparse_cache *audio_stream = + attr_container_of(source, struct audio_stream __sparse_cache, + source_api, __sparse_cache); + + if (req_size > audio_stream_get_data_available(source)) + return -ENODATA; + + /* get circular buffer parameters */ + *data_ptr = audio_stream->r_ptr; + *buffer_start = audio_stream->addr; + *buffer_size = audio_stream->size; + return 0; +} + +static int audio_stream_release_data(struct sof_source __sparse_cache *source, size_t free_size) +{ + struct audio_stream __sparse_cache *audio_stream = + attr_container_of(source, struct audio_stream __sparse_cache, + source_api, __sparse_cache); + + if (free_size) + audio_stream_consume(audio_stream, free_size); + + return 0; +} + +static int audio_stream_set_ipc_params_source(struct sof_source __sparse_cache *source, + struct sof_ipc_stream_params *params, + bool force_update) +{ + struct audio_stream __sparse_cache *audio_stream = + attr_container_of(source, struct audio_stream __sparse_cache, + source_api, __sparse_cache); + struct comp_buffer __sparse_cache *buffer = + attr_container_of(audio_stream, struct comp_buffer __sparse_cache, + stream, __sparse_cache); + + return buffer_set_params(buffer, params, force_update); +} + +static int audio_stream_set_ipc_params_sink(struct sof_sink __sparse_cache *sink, + struct sof_ipc_stream_params *params, + bool force_update) +{ + struct audio_stream __sparse_cache *audio_stream = + attr_container_of(sink, struct audio_stream __sparse_cache, + sink_api, __sparse_cache); + struct comp_buffer __sparse_cache *buffer = + attr_container_of(audio_stream, struct comp_buffer __sparse_cache, + stream, __sparse_cache); + + return buffer_set_params(buffer, params, force_update); +} + +static int audio_stream_source_set_alignment_constants(struct sof_source __sparse_cache *source, + const uint32_t byte_align, + const uint32_t frame_align_req) +{ + struct audio_stream __sparse_cache *audio_stream = + attr_container_of(source, struct audio_stream __sparse_cache, + source_api, __sparse_cache); + + audio_stream_init_alignment_constants(byte_align, frame_align_req, audio_stream); + + return 0; +} + +static int audio_stream_sink_set_alignment_constants(struct sof_sink __sparse_cache *sink, + const uint32_t byte_align, + const uint32_t frame_align_req) +{ + struct audio_stream __sparse_cache *audio_stream = + attr_container_of(sink, struct audio_stream __sparse_cache, + sink_api, __sparse_cache); + + audio_stream_init_alignment_constants(byte_align, frame_align_req, audio_stream); + + return 0; +} + +static const struct source_ops audio_stream_source_ops = { + .get_data_available = audio_stream_get_data_available, + .get_data = audio_stream_get_data, + .release_data = audio_stream_release_data, + .audio_set_ipc_params = audio_stream_set_ipc_params_source, + .set_alignment_constants = audio_stream_source_set_alignment_constants +}; + +static const struct sink_ops audio_stream_sink_ops = { + .get_free_size = audio_stream_get_free_size, + .get_buffer = audio_stream_get_buffer, + .commit_buffer = audio_stream_commit_buffer, + .audio_set_ipc_params = audio_stream_set_ipc_params_sink, + .set_alignment_constants = audio_stream_sink_set_alignment_constants +}; + +void audio_stream_init(struct audio_stream __sparse_cache *audio_stream, + void *buff_addr, uint32_t size) +{ + audio_stream->size = size; + audio_stream->addr = buff_addr; + audio_stream->end_addr = (char *)audio_stream->addr + size; + + /* set the default alignment info. + * set byte_align as 1 means no alignment limit on byte. + * set frame_align as 1 means no alignment limit on frame. + */ + audio_stream_init_alignment_constants(1, 1, audio_stream); + + source_init(audio_stream_get_source(audio_stream), &audio_stream_source_ops, + (__sparse_force struct sof_audio_stream_params *) + &audio_stream->runtime_stream_params); + sink_init(audio_stream_get_sink(audio_stream), &audio_stream_sink_ops, + (__sparse_force struct sof_audio_stream_params *) + &audio_stream->runtime_stream_params); + audio_stream_reset(audio_stream); +} diff --git a/src/include/sof/audio/audio_stream.h b/src/include/sof/audio/audio_stream.h index 0ec7e55d320f..f366eeee4219 100644 --- a/src/include/sof/audio/audio_stream.h +++ b/src/include/sof/audio/audio_stream.h @@ -15,6 +15,10 @@ #define __SOF_AUDIO_AUDIO_STREAM_H__ #include +#include +#include +#include +#include #include #include #include @@ -73,8 +77,13 @@ struct sof_audio_stream_params { * consumption/production and update the buffer state by calling * audio_stream_consume()/audio_stream_produce() (just a single call following * series of reads/writes). + * + * Audio stream implements pipeline2.0 sink and source API */ struct audio_stream { + struct sof_source source_api; /**< source API, don't modify, use helper functions only */ + struct sof_sink sink_api; /**< sink API, don't modify, use helper functions only */ + /* runtime data */ uint32_t size; /**< Runtime buffer size in bytes (period multiple) */ uint32_t avail; /**< Available bytes for reading */ @@ -714,24 +723,12 @@ static inline void audio_stream_reset(struct audio_stream __sparse_cache *buffer /** * Initializes the buffer with specified memory block and size. - * @param buffer Buffer to initialize. + * @param audio_stream the audio_stream a to initialize. * @param buff_addr Address of the memory block to assign. * @param size Size of the memory block in bytes. */ -static inline void audio_stream_init(struct audio_stream __sparse_cache *buffer, - void *buff_addr, uint32_t size) -{ - buffer->size = size; - buffer->addr = buff_addr; - buffer->end_addr = (char *)buffer->addr + size; - - /* set the default alignment info. - * set byte_align as 1 means no alignment limit on byte. - * set frame_align as 1 means no alignment limit on frame. - */ - audio_stream_init_alignment_constants(1, 1, buffer); - audio_stream_reset(buffer); -} +void audio_stream_init(struct audio_stream __sparse_cache *audio_stream, + void *buff_addr, uint32_t size); /** * Invalidates (in DSP d-cache) the buffer in range [r_ptr, r_ptr+bytes], @@ -969,6 +966,22 @@ static inline void audio_stream_fmt_conversion(enum ipc4_bit_depth depth, *valid_fmt = SOF_IPC_FRAME_FLOAT; } } + +/** get a handler to source API + * NOTE! to use the handlers the buffer must be acquired by buffer_acquire + */ +static inline struct sof_source __sparse_cache * +audio_stream_get_source(struct audio_stream __sparse_cache *audio_stream) +{ + return &audio_stream->source_api; +} + +static inline struct sof_sink __sparse_cache * +audio_stream_get_sink(struct audio_stream __sparse_cache *audio_stream) +{ + return &audio_stream->sink_api; +} + /** @}*/ #endif /* __SOF_AUDIO_AUDIO_STREAM_H__ */ diff --git a/test/cmocka/src/audio/buffer/CMakeLists.txt b/test/cmocka/src/audio/buffer/CMakeLists.txt index 1683577c34b9..acc92539a5e6 100644 --- a/test/cmocka/src/audio/buffer/CMakeLists.txt +++ b/test/cmocka/src/audio/buffer/CMakeLists.txt @@ -7,6 +7,7 @@ cmocka_test(buffer_copy ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c + ${PROJECT_SOURCE_DIR}/src/audio/audio_stream.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c @@ -28,6 +29,7 @@ cmocka_test(buffer_new ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c + ${PROJECT_SOURCE_DIR}/src/audio/audio_stream.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c @@ -48,6 +50,7 @@ cmocka_test(buffer_wrap ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c + ${PROJECT_SOURCE_DIR}/src/audio/audio_stream.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c @@ -68,6 +71,7 @@ cmocka_test(buffer_write ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c + ${PROJECT_SOURCE_DIR}/src/audio/audio_stream.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c diff --git a/test/cmocka/src/audio/component/CMakeLists.txt b/test/cmocka/src/audio/component/CMakeLists.txt index 7534a02706ec..5eb4d19c3151 100644 --- a/test/cmocka/src/audio/component/CMakeLists.txt +++ b/test/cmocka/src/audio/component/CMakeLists.txt @@ -13,6 +13,7 @@ cmocka_test(comp_set_state ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c + ${PROJECT_SOURCE_DIR}/src/audio/audio_stream.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-graph.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-params.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-schedule.c diff --git a/test/cmocka/src/audio/eq_fir/CMakeLists.txt b/test/cmocka/src/audio/eq_fir/CMakeLists.txt index 94c3ff0f4376..af9fa80d0b60 100644 --- a/test/cmocka/src/audio/eq_fir/CMakeLists.txt +++ b/test/cmocka/src/audio/eq_fir/CMakeLists.txt @@ -26,6 +26,7 @@ add_library(audio_for_eq_fir STATIC ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c + ${PROJECT_SOURCE_DIR}/src/audio/audio_stream.c ${PROJECT_SOURCE_DIR}/src/audio/component.c ${PROJECT_SOURCE_DIR}/src/audio/data_blob.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c diff --git a/test/cmocka/src/audio/eq_iir/CMakeLists.txt b/test/cmocka/src/audio/eq_iir/CMakeLists.txt index 5d28dc64d65c..a72903d1c1df 100644 --- a/test/cmocka/src/audio/eq_iir/CMakeLists.txt +++ b/test/cmocka/src/audio/eq_iir/CMakeLists.txt @@ -26,6 +26,7 @@ add_library(audio_for_eq_iir STATIC ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c + ${PROJECT_SOURCE_DIR}/src/audio/audio_stream.c ${PROJECT_SOURCE_DIR}/src/audio/component.c ${PROJECT_SOURCE_DIR}/src/audio/data_blob.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c diff --git a/test/cmocka/src/audio/mixer/CMakeLists.txt b/test/cmocka/src/audio/mixer/CMakeLists.txt index 41a568e47fb6..e422dd6ebf96 100644 --- a/test/cmocka/src/audio/mixer/CMakeLists.txt +++ b/test/cmocka/src/audio/mixer/CMakeLists.txt @@ -16,6 +16,7 @@ cmocka_test(mixer ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c + ${PROJECT_SOURCE_DIR}/src/audio/audio_stream.c ${PROJECT_SOURCE_DIR}/src/audio/component.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-graph.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-params.c diff --git a/test/cmocka/src/audio/mux/CMakeLists.txt b/test/cmocka/src/audio/mux/CMakeLists.txt index 535c042a028e..59e3752599fc 100644 --- a/test/cmocka/src/audio/mux/CMakeLists.txt +++ b/test/cmocka/src/audio/mux/CMakeLists.txt @@ -17,6 +17,7 @@ add_library( ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c + ${PROJECT_SOURCE_DIR}/src/audio/audio_stream.c ${PROJECT_SOURCE_DIR}/src/math/numbers.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c diff --git a/test/cmocka/src/audio/pcm_converter/CMakeLists.txt b/test/cmocka/src/audio/pcm_converter/CMakeLists.txt index aad4e3b47bd2..13adc77e000c 100644 --- a/test/cmocka/src/audio/pcm_converter/CMakeLists.txt +++ b/test/cmocka/src/audio/pcm_converter/CMakeLists.txt @@ -10,6 +10,7 @@ if(CONFIG_FORMAT_FLOAT) ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c + ${PROJECT_SOURCE_DIR}/src/audio/audio_stream.c ${PROJECT_SOURCE_DIR}/src/audio/component.c ${PROJECT_SOURCE_DIR}/src/audio/data_blob.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c diff --git a/test/cmocka/src/audio/pipeline/CMakeLists.txt b/test/cmocka/src/audio/pipeline/CMakeLists.txt index 9b3c17824c10..c8219517c19f 100644 --- a/test/cmocka/src/audio/pipeline/CMakeLists.txt +++ b/test/cmocka/src/audio/pipeline/CMakeLists.txt @@ -28,6 +28,7 @@ cmocka_test(pipeline_new ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c + ${PROJECT_SOURCE_DIR}/src/audio/audio_stream.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-graph.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-params.c @@ -49,6 +50,7 @@ cmocka_test(pipeline_connect_upstream ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c + ${PROJECT_SOURCE_DIR}/src/audio/audio_stream.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-graph.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-params.c @@ -70,6 +72,7 @@ cmocka_test(pipeline_free ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c + ${PROJECT_SOURCE_DIR}/src/audio/audio_stream.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-graph.c ${PROJECT_SOURCE_DIR}/src/audio/pipeline/pipeline-params.c diff --git a/test/cmocka/src/audio/selector/CMakeLists.txt b/test/cmocka/src/audio/selector/CMakeLists.txt index a7f83fc652be..46be5bdac073 100644 --- a/test/cmocka/src/audio/selector/CMakeLists.txt +++ b/test/cmocka/src/audio/selector/CMakeLists.txt @@ -19,6 +19,7 @@ add_library(audio_for_selector STATIC ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c + ${PROJECT_SOURCE_DIR}/src/audio/audio_stream.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c diff --git a/test/cmocka/src/audio/volume/CMakeLists.txt b/test/cmocka/src/audio/volume/CMakeLists.txt index 150d10b25282..49e75a2e948a 100644 --- a/test/cmocka/src/audio/volume/CMakeLists.txt +++ b/test/cmocka/src/audio/volume/CMakeLists.txt @@ -23,6 +23,7 @@ add_library(audio_for_volume STATIC ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c + ${PROJECT_SOURCE_DIR}/src/audio/audio_stream.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-helper.c diff --git a/test/cmocka/src/math/fft/CMakeLists.txt b/test/cmocka/src/math/fft/CMakeLists.txt index 08ebbcdaf6f5..d21819848cd0 100644 --- a/test/cmocka/src/math/fft/CMakeLists.txt +++ b/test/cmocka/src/math/fft/CMakeLists.txt @@ -11,6 +11,7 @@ cmocka_test(fft ${PROJECT_SOURCE_DIR}/src/audio/source_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_api_helper.c ${PROJECT_SOURCE_DIR}/src/audio/sink_source_utils.c + ${PROJECT_SOURCE_DIR}/src/audio/audio_stream.c ${PROJECT_SOURCE_DIR}/test/cmocka/src/notifier_mocks.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c diff --git a/zephyr/CMakeLists.txt b/zephyr/CMakeLists.txt index 1e65a048409c..8b91d5e754d4 100644 --- a/zephyr/CMakeLists.txt +++ b/zephyr/CMakeLists.txt @@ -397,6 +397,7 @@ zephyr_library_sources( ${SOF_AUDIO_PATH}/source_api_helper.c ${SOF_AUDIO_PATH}/sink_api_helper.c ${SOF_AUDIO_PATH}/sink_source_utils.c + ${SOF_AUDIO_PATH}/audio_stream.c ${SOF_AUDIO_PATH}/component.c ${SOF_AUDIO_PATH}/pipeline/pipeline-graph.c ${SOF_AUDIO_PATH}/pipeline/pipeline-params.c From 88af40893c38a01edf5fbbfb5462fc84dbc3915d Mon Sep 17 00:00:00 2001 From: Marcin Szkudlinski Date: Tue, 18 Apr 2023 14:38:44 +0200 Subject: [PATCH 08/10] Pipeline2.0: change module API to use various data Target is to make all modules use sink/source API as data source and destination. However, current implementation of module adapter allows 2 other completely different interfaces to be used: "simple_copy" modules receive output_stream_buffer and input_stream_buffer table. void * data pointers from both structures point to audio_stream other fields in the structures are in fact not needed but are used "! simple_copy" modules receive output_stream_buffer and input_stream_buffer table. void * data pointers from both structures point to raw linear data to make transition smooth and easy, both legacy ways have been kept, just to make the code more clear - put at separate module API calls, Signed-off-by: Marcin Szkudlinski --- src/audio/buffer.c | 2 +- src/audio/eq_fir/eq_fir.c | 4 +- src/audio/eq_iir/eq_iir.c | 8 +- src/audio/mfcc/mfcc.c | 3 +- src/audio/mixer/mixer.c | 3 +- src/audio/mixin_mixout/mixin_mixout.c | 6 +- src/audio/module_adapter/module/cadence.c | 2 +- src/audio/module_adapter/module/dts.c | 2 +- src/audio/module_adapter/module/generic.c | 66 +++++++-- .../module_adapter/module/iadk_modules.c | 2 +- src/audio/module_adapter/module/passthrough.c | 2 +- .../module_adapter/module/volume/volume.c | 10 +- src/audio/module_adapter/module/waves.c | 2 +- src/audio/module_adapter/module_adapter.c | 135 +++++++++++++++--- src/audio/mux/mux.c | 5 +- src/audio/selector/selector.c | 7 +- src/audio/src/src.c | 4 +- src/audio/tdfb/tdfb.c | 3 +- src/audio/up_down_mixer/up_down_mixer.c | 3 +- .../sof/audio/module_adapter/module/generic.h | 15 +- .../module_adapter/module/module_interface.h | 54 ++++++- src/samples/audio/smart_amp_test_ipc4.c | 4 +- test/cmocka/src/audio/eq_fir/eq_fir_process.c | 3 +- test/cmocka/src/audio/eq_iir/eq_iir_process.c | 3 +- 24 files changed, 252 insertions(+), 96 deletions(-) diff --git a/src/audio/buffer.c b/src/audio/buffer.c index 708848d050a0..c468b93ca88c 100644 --- a/src/audio/buffer.c +++ b/src/audio/buffer.c @@ -62,7 +62,7 @@ struct comp_buffer *buffer_alloc(uint32_t size, uint32_t caps, uint32_t flags, u /* From here no more uncached access to the buffer object, except its list headers */ buffer_c = buffer_acquire(buffer); - buffer_c->stream.addr = stream_addr; + audio_stream_set_addr(&buffer_c->stream, stream_addr); buffer_init(buffer_c, size, caps); audio_stream_set_underrun(&buffer_c->stream, !!(flags & SOF_BUF_UNDERRUN_PERMITTED)); diff --git a/src/audio/eq_fir/eq_fir.c b/src/audio/eq_fir/eq_fir.c index 547964eed843..0b9e46f12b03 100644 --- a/src/audio/eq_fir/eq_fir.c +++ b/src/audio/eq_fir/eq_fir.c @@ -456,8 +456,6 @@ static int eq_fir_init(struct processing_module *mod) for (i = 0; i < PLATFORM_MAX_CHANNELS; i++) fir_reset(&cd->fir[i]); - mod->simple_copy = true; - return 0; err_init: @@ -641,7 +639,7 @@ static struct module_interface eq_fir_interface = { .free = eq_fir_free, .set_configuration = eq_fir_set_config, .get_configuration = eq_fir_get_config, - .process = eq_fir_process, + .process_audio_stream = eq_fir_process, .prepare = eq_fir_prepare, .reset = eq_fir_reset, }; diff --git a/src/audio/eq_iir/eq_iir.c b/src/audio/eq_iir/eq_iir.c index f6673ee162c7..5004e1324d36 100644 --- a/src/audio/eq_iir/eq_iir.c +++ b/src/audio/eq_iir/eq_iir.c @@ -670,12 +670,6 @@ static int eq_iir_init(struct processing_module *mod) for (i = 0; i < PLATFORM_MAX_CHANNELS; i++) iir_reset_df1(&cd->iir[i]); - /* - * set the simple_copy flag as the eq_iir component always produces period_bytes - * every period and has only 1 input/output buffer - */ - mod->simple_copy = true; - return 0; err: rfree(cd); @@ -967,7 +961,7 @@ static int eq_iir_reset(struct processing_module *mod) static struct module_interface eq_iir_interface = { .init = eq_iir_init, .prepare = eq_iir_prepare, - .process = eq_iir_process, + .process_audio_stream = eq_iir_process, .set_configuration = eq_iir_set_config, .get_configuration = eq_iir_get_config, .reset = eq_iir_reset, diff --git a/src/audio/mfcc/mfcc.c b/src/audio/mfcc/mfcc.c index a269615abb1e..744fafb36b9f 100644 --- a/src/audio/mfcc/mfcc.c +++ b/src/audio/mfcc/mfcc.c @@ -110,7 +110,6 @@ static int mfcc_init(struct processing_module *mod) goto err_init; } - mod->simple_copy = true; return 0; err_init: @@ -272,7 +271,7 @@ static struct module_interface mfcc_interface = { .free = mfcc_free, .set_configuration = mfcc_set_config, .get_configuration = mfcc_get_config, - .process = mfcc_process, + .process_audio_stream = mfcc_process, .prepare = mfcc_prepare, .reset = mfcc_reset, }; diff --git a/src/audio/mixer/mixer.c b/src/audio/mixer/mixer.c index 68853b23926d..f9b2f92ca204 100644 --- a/src/audio/mixer/mixer.c +++ b/src/audio/mixer/mixer.c @@ -55,7 +55,6 @@ static int mixer_init(struct processing_module *mod) mod_data->private = md; mod->verify_params_flags = BUFF_PARAMS_CHANNELS; - mod->simple_copy = true; mod->no_pause = true; return 0; } @@ -266,7 +265,7 @@ static int mixer_prepare(struct processing_module *mod) static struct module_interface mixer_interface = { .init = mixer_init, .prepare = mixer_prepare, - .process = mixer_process, + .process_audio_stream = mixer_process, .reset = mixer_reset, .free = mixer_free, }; diff --git a/src/audio/mixin_mixout/mixin_mixout.c b/src/audio/mixin_mixout/mixin_mixout.c index 7a3f91012e36..af081f491250 100644 --- a/src/audio/mixin_mixout/mixin_mixout.c +++ b/src/audio/mixin_mixout/mixin_mixout.c @@ -121,7 +121,6 @@ static int mixin_init(struct processing_module *mod) mod->priv.cfg.base_cfg.audio_fmt.s_type); dev->ipc_config.frame_fmt = frame_fmt; - mod->simple_copy = true; mod->skip_src_buffer_invalidate = true; return 0; @@ -150,7 +149,6 @@ static int mixout_init(struct processing_module *mod) mod->priv.cfg.base_cfg.audio_fmt.s_type); dev->ipc_config.frame_fmt = frame_fmt; - mod->simple_copy = true; mod->skip_sink_buffer_writeback = true; return 0; @@ -928,7 +926,7 @@ static int mixin_set_config(struct processing_module *mod, uint32_t config_id, static struct module_interface mixin_interface = { .init = mixin_init, .prepare = mixin_prepare, - .process = mixin_process, + .process_audio_stream = mixin_process, .set_configuration = mixin_set_config, .reset = mixin_reset, .free = mixin_free @@ -940,7 +938,7 @@ SOF_MODULE_INIT(mixin, sys_comp_module_mixin_interface_init); static struct module_interface mixout_interface = { .init = mixout_init, .prepare = mixout_prepare, - .process = mixout_process, + .process_audio_stream = mixout_process, .reset = mixout_reset, .free = mixout_free }; diff --git a/src/audio/module_adapter/module/cadence.c b/src/audio/module_adapter/module/cadence.c index 853005a8ad3f..5ae8715cac5a 100644 --- a/src/audio/module_adapter/module/cadence.c +++ b/src/audio/module_adapter/module/cadence.c @@ -749,7 +749,7 @@ cadence_codec_set_configuration(struct processing_module *mod, uint32_t config_i static struct module_interface cadence_interface = { .init = cadence_codec_init, .prepare = cadence_codec_prepare, - .process = cadence_codec_process, + .process_raw_data = cadence_codec_process, .set_configuration = cadence_codec_set_configuration, .reset = cadence_codec_reset, .free = cadence_codec_free diff --git a/src/audio/module_adapter/module/dts.c b/src/audio/module_adapter/module/dts.c index 71e2589b4ab9..c59e51990303 100644 --- a/src/audio/module_adapter/module/dts.c +++ b/src/audio/module_adapter/module/dts.c @@ -452,7 +452,7 @@ dts_codec_set_configuration(struct processing_module *mod, uint32_t config_id, static struct module_interface dts_interface = { .init = dts_codec_init, .prepare = dts_codec_prepare, - .process = dts_codec_process, + .process_raw_data = dts_codec_process, .set_configuration = dts_codec_set_configuration, .reset = dts_codec_reset, .free = dts_codec_free diff --git a/src/audio/module_adapter/module/generic.c b/src/audio/module_adapter/module/generic.c index bde580b66054..521152d2ee9a 100644 --- a/src/audio/module_adapter/module/generic.c +++ b/src/audio/module_adapter/module/generic.c @@ -94,8 +94,11 @@ int module_init(struct processing_module *mod, struct module_interface *interfac return -EIO; } - if (!interface->init || !interface->prepare || !interface->process || - !interface->reset || !interface->free) { + /*check interface, there must be one and only one of processing procedure */ + if (!interface->init || !interface->prepare || + !interface->reset || !interface->free || + (!!interface->process + !!interface->process_audio_stream + + !!interface->process_raw_data != 1)) { comp_err(dev, "module_init(): comp %d is missing mandatory interfaces", dev_comp_id(dev)); return -EIO; @@ -225,16 +228,17 @@ int module_prepare(struct processing_module *mod) return ret; } -int module_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) +int module_process_legacy(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 comp_dev *dev = mod->dev; int ret; struct module_data *md = &mod->priv; - comp_dbg(dev, "module_process() start"); + comp_dbg(dev, "module_process_legacy() start"); if (md->state != MODULE_IDLE) { comp_err(dev, "module_process(): wrong state of comp_id %x, state %d", @@ -245,15 +249,59 @@ int module_process(struct processing_module *mod, struct input_stream_buffer *in /* set state to processing */ md->state = MODULE_PROCESSING; - ret = md->ops->process(mod, input_buffers, num_input_buffers, output_buffers, - num_output_buffers); + if (md->ops->process_audio_stream) + ret = md->ops->process_audio_stream(mod, input_buffers, num_input_buffers, + output_buffers, num_output_buffers); + else if (md->ops->process_raw_data) + ret = md->ops->process_raw_data(mod, input_buffers, num_input_buffers, + output_buffers, num_output_buffers); + else + ret = -EOPNOTSUPP; + + if (ret && ret != -ENOSPC && ret != -ENODATA) { + comp_err(dev, "module_process() error %d: for comp %d", + ret, dev_comp_id(dev)); + return ret; + } + + comp_dbg(dev, "module_process_legacy() done"); + + /* reset state to idle */ + md->state = MODULE_IDLE; + return 0; +} + +int module_process_sink_src(struct processing_module *mod, + struct sof_source __sparse_cache **sources, int num_of_sources, + struct sof_sink __sparse_cache **sinks, int num_of_sinks) + +{ + struct comp_dev *dev = mod->dev; + int ret; + + struct module_data *md = &mod->priv; + + comp_dbg(dev, "module_process sink src() start"); + + if (md->state != MODULE_IDLE) { + comp_err(dev, "module_process(): wrong state of comp_id %x, state %d", + dev_comp_id(dev), md->state); + return -EPERM; + } + + /* set state to processing */ + md->state = MODULE_PROCESSING; + + assert(md->ops->process); + ret = md->ops->process(mod, sources, num_of_sources, sinks, num_of_sinks); + if (ret && ret != -ENOSPC && ret != -ENODATA) { comp_err(dev, "module_process() error %d: for comp %d", ret, dev_comp_id(dev)); return ret; } - comp_dbg(dev, "module_process() done"); + comp_dbg(dev, "module_process sink src() done"); /* reset state to idle */ md->state = MODULE_IDLE; diff --git a/src/audio/module_adapter/module/iadk_modules.c b/src/audio/module_adapter/module/iadk_modules.c index 8c728bba5594..3af85e271ab9 100644 --- a/src/audio/module_adapter/module/iadk_modules.c +++ b/src/audio/module_adapter/module/iadk_modules.c @@ -292,7 +292,7 @@ static int iadk_modules_reset(struct processing_module *mod) static struct module_interface iadk_interface = { .init = iadk_modules_init, .prepare = iadk_modules_prepare, - .process = iadk_modules_process, + .process_raw_data = iadk_modules_process, .set_processing_mode = iadk_modules_set_processing_mode, .get_processing_mode = iadk_modules_get_processing_mode, .set_configuration = iadk_modules_set_configuration, diff --git a/src/audio/module_adapter/module/passthrough.c b/src/audio/module_adapter/module/passthrough.c index 05d22eba5598..46b652adbecf 100644 --- a/src/audio/module_adapter/module/passthrough.c +++ b/src/audio/module_adapter/module/passthrough.c @@ -117,7 +117,7 @@ static int passthrough_codec_free(struct processing_module *mod) static struct module_interface passthrough_interface = { .init = passthrough_codec_init, .prepare = passthrough_codec_prepare, - .process = passthrough_codec_process, + .process_raw_data = passthrough_codec_process, .reset = passthrough_codec_reset, .free = passthrough_codec_free }; diff --git a/src/audio/module_adapter/module/volume/volume.c b/src/audio/module_adapter/module/volume/volume.c index 40938ad08391..48a167cf8b5f 100644 --- a/src/audio/module_adapter/module/volume/volume.c +++ b/src/audio/module_adapter/module/volume/volume.c @@ -1340,12 +1340,6 @@ static int volume_prepare(struct processing_module *mod) md->mpd.in_buff_size = sink_period_bytes; md->mpd.out_buff_size = sink_period_bytes; - /* - * also set the simple_copy flag as the volume component always produces period_bytes - * every period and has only 1 input/output buffer - */ - mod->simple_copy = true; - return 0; err: @@ -1611,7 +1605,7 @@ SOF_MODULE_INIT(volume, sys_comp_volume_init); static struct module_interface volume_interface = { .init = volume_init, .prepare = volume_prepare, - .process = volume_process, + .process_audio_stream = volume_process, .set_configuration = volume_set_config, .get_configuration = volume_get_config, .reset = volume_reset, @@ -1625,7 +1619,7 @@ SOF_MODULE_INIT(volume, sys_comp_module_volume_interface_init); static struct module_interface gain_interface = { .init = volume_init, .prepare = volume_prepare, - .process = volume_process, + .process_audio_stream = volume_process, .set_configuration = volume_set_config, .get_configuration = volume_get_config, .reset = volume_reset, diff --git a/src/audio/module_adapter/module/waves.c b/src/audio/module_adapter/module/waves.c index fa1613644599..5b0b61a970db 100644 --- a/src/audio/module_adapter/module/waves.c +++ b/src/audio/module_adapter/module/waves.c @@ -887,7 +887,7 @@ waves_codec_set_configuration(struct processing_module *mod, uint32_t config_id, static struct module_interface waves_interface = { .init = waves_codec_init, .prepare = waves_codec_prepare, - .process = waves_codec_process, + .process_raw_data = waves_codec_process, .set_configuration = waves_codec_set_configuration, .reset = waves_codec_reset, .free = waves_codec_free diff --git a/src/audio/module_adapter/module_adapter.c b/src/audio/module_adapter/module_adapter.c index fc0705ab9861..15d29970857f 100644 --- a/src/audio/module_adapter/module_adapter.c +++ b/src/audio/module_adapter/module_adapter.c @@ -23,6 +23,19 @@ LOG_MODULE_REGISTER(module_adapter, CONFIG_SOF_LOG_LEVEL); +/* + * helpers to determine processing type + * Needed till all the modules use PROCESSING_MODE_SINK_SOURCE + */ +#define IS_PROCESSING_MODE_AUDIO_STREAM(mod) \ + (!!((struct module_data *)&(mod)->priv)->ops->process_audio_stream) + +#define IS_PROCESSING_MODE_RAW_DATA(mod) \ + (!!((struct module_data *)&(mod)->priv)->ops->process_raw_data) + +#define IS_PROCESSING_MODE_SINK_SOURCE(mod) \ + (!!((struct module_data *)&(mod)->priv)->ops->process) + /* * \brief Create a module adapter component. * \param[in] drv - component driver pointer. @@ -240,7 +253,9 @@ int module_adapter_prepare(struct comp_dev *dev) return -EINVAL; } - if (mod->simple_copy && mod->num_input_buffers > 1 && mod->num_output_buffers > 1) { + /* check processing mode */ + if (IS_PROCESSING_MODE_AUDIO_STREAM(mod) && + mod->num_input_buffers > 1 && mod->num_output_buffers > 1) { comp_err(dev, "module_adapter_prepare(): Invalid use of simple_copy"); return -EINVAL; } @@ -276,7 +291,7 @@ int module_adapter_prepare(struct comp_dev *dev) * no need to allocate intermediate sink buffers if the module produces only period bytes * every period and has only 1 input and 1 output buffer */ - if (mod->simple_copy) + if (!IS_PROCESSING_MODE_RAW_DATA(mod)) return 0; /* Module is prepared, now we need to configure processing settings. @@ -710,7 +725,7 @@ module_single_source_setup(struct comp_dev *dev, return num_output_buffers; } -static int module_adapter_simple_copy(struct comp_dev *dev) +static int module_adapter_audio_stream_type_copy(struct comp_dev *dev) { struct comp_buffer __sparse_cache *source_c[PLATFORM_MAX_STREAMS]; struct comp_buffer __sparse_cache *sinks_c[PLATFORM_MAX_STREAMS]; @@ -746,11 +761,12 @@ static int module_adapter_simple_copy(struct comp_dev *dev) num_input_buffers = 1; } - ret = module_process(mod, mod->input_buffers, num_input_buffers, - mod->output_buffers, num_output_buffers); + ret = module_process_legacy(mod, mod->input_buffers, num_input_buffers, + mod->output_buffers, num_output_buffers); if (ret) { if (ret != -ENOSPC && ret != -ENODATA) { - comp_err(dev, "module_adapter_simple_copy() process failed with error: %x", + comp_err(dev, + "module_adapter_audio_stream_type_copy() failed with error: %x", ret); goto out; } @@ -825,7 +841,68 @@ static int module_adapter_simple_copy(struct comp_dev *dev) return ret; } -int module_adapter_copy(struct comp_dev *dev) +static int module_adapter_sink_source_copy(struct comp_dev *dev) +{ + struct comp_buffer __sparse_cache *source_buffers_c[PLATFORM_MAX_STREAMS]; + struct comp_buffer __sparse_cache *sinks_buffers_c[PLATFORM_MAX_STREAMS]; + struct sof_sink __sparse_cache *audio_sink[PLATFORM_MAX_STREAMS]; + struct sof_source __sparse_cache *audio_src[PLATFORM_MAX_STREAMS]; + struct processing_module *mod = comp_get_drvdata(dev); + struct list_item *blist; + uint32_t num_of_sources = 0; + uint32_t num_of_sinks = 0; + int ret; + + comp_dbg(dev, "module_adapter_sink_source_copy(): start"); + + /* acquire all sink and source buffers, get handlers to sink/source API */ + list_for_item(blist, &dev->bsink_list) { + struct comp_buffer *sink_buffer; + + sink_buffer = container_of(blist, struct comp_buffer, source_list); + sinks_buffers_c[num_of_sinks] = buffer_acquire(sink_buffer); + audio_sink[num_of_sinks] = + audio_stream_get_sink(&sinks_buffers_c[num_of_sinks]->stream); + sink_reset_num_of_processed_bytes(audio_sink[num_of_sinks]); + num_of_sinks++; + } + + list_for_item(blist, &dev->bsource_list) { + struct comp_buffer *source_buffer; + + source_buffer = container_of(blist, struct comp_buffer, sink_list); + source_buffers_c[num_of_sources] = buffer_acquire(source_buffer); + audio_src[num_of_sources] = + audio_stream_get_source(&source_buffers_c[num_of_sources]->stream); + source_reset_num_of_processed_bytes(audio_src[num_of_sources]); + num_of_sources++; + } + + ret = module_process_sink_src(mod, audio_src, num_of_sources, audio_sink, num_of_sinks); + + if (ret != -ENOSPC && ret != -ENODATA && ret) { + comp_err(dev, "module_adapter_sink_source_copy() process failed with error: %x", + ret); + } + + /* release all source buffers in reverse order */ + for (int i = num_of_sources - 1; i >= 0; i--) { + mod->total_data_consumed += source_get_num_of_processed_bytes(audio_src[i]); + buffer_release(source_buffers_c[i]); + } + + /* release all sink buffers in reverse order */ + for (int i = num_of_sinks - 1; i >= 0 ; i--) { + mod->total_data_produced += sink_get_num_of_processed_bytes(audio_sink[i]); + buffer_release(sinks_buffers_c[i]); + } + + comp_dbg(dev, "module_adapter_sink_source_copy(): done"); + + return ret; +} + +static int module_adapter_raw_data_type_copy(struct comp_dev *dev) { struct processing_module *mod = comp_get_drvdata(dev); struct module_data *md = &mod->priv; @@ -836,10 +913,7 @@ int module_adapter_copy(struct comp_dev *dev) uint32_t min_free_frames = UINT_MAX; int ret, i = 0; - comp_dbg(dev, "module_adapter_copy(): start"); - - if (mod->simple_copy) - return module_adapter_simple_copy(dev); + comp_dbg(dev, "module_adapter_raw_data_type_copy(): start"); list_for_item(blist, &mod->sink_buffer_list) { sink = container_of(blist, struct comp_buffer, sink_list); @@ -881,11 +955,12 @@ int module_adapter_copy(struct comp_dev *dev) i++; } - ret = module_process(mod, mod->input_buffers, mod->num_input_buffers, - mod->output_buffers, mod->num_output_buffers); + ret = module_process_legacy(mod, mod->input_buffers, mod->num_input_buffers, + mod->output_buffers, mod->num_output_buffers); if (ret) { if (ret != -ENOSPC && ret != -ENODATA) { - comp_err(dev, "module_adapter_copy() error %x: module processing failed", + comp_err(dev, + "module_adapter_raw_data_type_copy() %x: module processing failed", ret); goto out; } @@ -915,6 +990,8 @@ int module_adapter_copy(struct comp_dev *dev) module_adapter_process_output(dev); + comp_dbg(dev, "module_adapter_raw_data_type_copy(): done"); + return 0; out: @@ -926,10 +1003,29 @@ int module_adapter_copy(struct comp_dev *dev) mod->input_buffers[i].size = 0; mod->input_buffers[i].consumed = 0; } - + comp_dbg(dev, "module_adapter_raw_data_type_copy(): error %x", ret); return ret; } +int module_adapter_copy(struct comp_dev *dev) +{ + comp_dbg(dev, "module_adapter_copy(): start"); + + struct processing_module *mod = comp_get_drvdata(dev); + + if (IS_PROCESSING_MODE_AUDIO_STREAM(mod)) + return module_adapter_audio_stream_type_copy(dev); + + if (IS_PROCESSING_MODE_RAW_DATA(mod)) + return module_adapter_raw_data_type_copy(dev); + + if (IS_PROCESSING_MODE_SINK_SOURCE(mod)) + return module_adapter_sink_source_copy(dev); + + comp_err(dev, "module_adapter_copy(): unknown processing_data_type"); + return -EINVAL; +} + static int module_adapter_get_set_params(struct comp_dev *dev, struct sof_ipc_ctrl_data *cdata, bool set) { @@ -1135,16 +1231,13 @@ int module_adapter_reset(struct comp_dev *dev) return ret; } - if (!mod->simple_copy) + if (IS_PROCESSING_MODE_RAW_DATA(mod)) { for (i = 0; i < mod->num_output_buffers; i++) rfree((__sparse_force void *)mod->output_buffers[i].data); - - rfree(mod->output_buffers); - - if (!mod->simple_copy) for (i = 0; i < mod->num_input_buffers; i++) rfree((__sparse_force void *)mod->input_buffers[i].data); - + } + rfree(mod->output_buffers); rfree(mod->input_buffers); mod->num_input_buffers = 0; diff --git a/src/audio/mux/mux.c b/src/audio/mux/mux.c index 90559144f571..cbb0b745cf66 100644 --- a/src/audio/mux/mux.c +++ b/src/audio/mux/mux.c @@ -239,7 +239,6 @@ static int mux_init(struct processing_module *mod) } mod->verify_params_flags = BUFF_PARAMS_CHANNELS; - mod->simple_copy = true; mod->no_pause = true; return 0; @@ -704,7 +703,7 @@ static struct module_interface mux_interface = { .set_configuration = mux_set_config, .get_configuration = mux_get_config, .prepare = mux_prepare, - .process = mux_process, + .process_audio_stream = mux_process, .reset = mux_reset, .free = mux_free, }; @@ -717,7 +716,7 @@ static struct module_interface demux_interface = { .set_configuration = mux_set_config, .get_configuration = mux_get_config, .prepare = mux_prepare, - .process = demux_process, + .process_audio_stream = demux_process, .reset = mux_reset, .free = mux_free, }; diff --git a/src/audio/selector/selector.c b/src/audio/selector/selector.c index c2a588c65f51..9bc6d542e9ef 100644 --- a/src/audio/selector/selector.c +++ b/src/audio/selector/selector.c @@ -940,11 +940,6 @@ static int selector_prepare(struct processing_module *mod) md->mpd.in_buff_size = cd->source_period_bytes; md->mpd.out_buff_size = cd->sink_period_bytes; - /* Selector module has 1 input buffer and 1 output buffer and produces period_bytes - * every copy. Use 'simple copy' processing scheme. - */ - mod->simple_copy = true; - buffer_release(sink_c); buffer_release(source_c); @@ -1000,7 +995,7 @@ static int selector_reset(struct processing_module *mod) static struct module_interface selector_interface = { .init = selector_init, .prepare = selector_prepare, - .process = selector_process, + .process_audio_stream = selector_process, .set_configuration = selector_set_config, .get_configuration = selector_get_config, .reset = selector_reset, diff --git a/src/audio/src/src.c b/src/audio/src/src.c index f3c0a1a6b945..8e0116c100e4 100644 --- a/src/audio/src/src.c +++ b/src/audio/src/src.c @@ -1033,8 +1033,6 @@ static int src_init(struct processing_module *mod) mod->verify_params_flags = BUFF_PARAMS_RATE; #endif - mod->simple_copy = true; - return 0; } @@ -1122,7 +1120,7 @@ static int src_free(struct processing_module *mod) static struct module_interface src_interface = { .init = src_init, .prepare = src_prepare, - .process = src_process, + .process_audio_stream = src_process, .set_configuration = src_set_config, .get_configuration = src_get_config, .reset = src_reset, diff --git a/src/audio/tdfb/tdfb.c b/src/audio/tdfb/tdfb.c index c2f395ed7698..24479526b691 100644 --- a/src/audio/tdfb/tdfb.c +++ b/src/audio/tdfb/tdfb.c @@ -473,7 +473,6 @@ static int tdfb_init(struct processing_module *mod) * aspects TDFB is simple component type. */ mod->verify_params_flags = BUFF_PARAMS_CHANNELS; - mod->simple_copy = true; return 0; err: @@ -823,7 +822,7 @@ static struct module_interface tdfb_interface = { .free = tdfb_free, .set_configuration = tdfb_set_config, .get_configuration = tdfb_get_config, - .process = tdfb_process, + .process_audio_stream = tdfb_process, .prepare = tdfb_prepare, .reset = tdfb_reset, }; diff --git a/src/audio/up_down_mixer/up_down_mixer.c b/src/audio/up_down_mixer/up_down_mixer.c index 7d93ed0a548f..2959556e33fc 100644 --- a/src/audio/up_down_mixer/up_down_mixer.c +++ b/src/audio/up_down_mixer/up_down_mixer.c @@ -351,7 +351,6 @@ static int up_down_mixer_init(struct processing_module *mod) } mod_data->private = cd; - mod->simple_copy = true; cd->buf_in = rballoc(0, SOF_MEM_CAPS_RAM, mod->priv.cfg.base_cfg.ibs); cd->buf_out = rballoc(0, SOF_MEM_CAPS_RAM, mod->priv.cfg.base_cfg.obs); @@ -458,7 +457,7 @@ up_down_mixer_process(struct processing_module *mod, static struct module_interface up_down_mixer_interface = { .init = up_down_mixer_init, .prepare = up_down_mixer_prepare, - .process = up_down_mixer_process, + .process_audio_stream = up_down_mixer_process, .reset = up_down_mixer_reset, .free = up_down_mixer_free }; diff --git a/src/include/sof/audio/module_adapter/module/generic.h b/src/include/sof/audio/module_adapter/module/generic.h index f0bc0a4c539c..22bd45c1f8e6 100644 --- a/src/include/sof/audio/module_adapter/module/generic.h +++ b/src/include/sof/audio/module_adapter/module/generic.h @@ -184,11 +184,6 @@ struct processing_module { struct output_stream_buffer *output_buffers; uint32_t num_input_buffers; /**< number of input buffers */ uint32_t num_output_buffers; /**< number of output buffers */ - /* - * flag set by a module that produces period_bytes every copy. It can be used by modules - * that support 1:1, 1:N, N:1 sources:sinks configuration. - */ - bool simple_copy; /* module-specific flags for comp_verify_params() */ uint32_t verify_params_flags; @@ -225,9 +220,13 @@ void *module_allocate_memory(struct processing_module *mod, uint32_t size, uint3 int module_free_memory(struct processing_module *mod, void *ptr); void module_free_all_memory(struct processing_module *mod); int module_prepare(struct processing_module *mod); -int module_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); +int module_process_sink_src(struct processing_module *mod, + struct sof_source __sparse_cache **sources, int num_of_sources, + struct sof_sink __sparse_cache **sinks, int num_of_sinks); +int module_process_legacy(struct processing_module *mod, + struct input_stream_buffer *input_buffers, int num_input_buffers, + struct output_stream_buffer *output_buffers, + int num_output_buffers); int module_reset(struct processing_module *mod); int module_free(struct processing_module *mod); int module_set_configuration(struct processing_module *mod, diff --git a/src/include/sof/audio/module_adapter/module/module_interface.h b/src/include/sof/audio/module_adapter/module/module_interface.h index b3a187256e09..cd7622208649 100644 --- a/src/include/sof/audio/module_adapter/module/module_interface.h +++ b/src/include/sof/audio/module_adapter/module/module_interface.h @@ -14,6 +14,8 @@ #define __SOF_MODULE_INTERFACE__ #include +#include +#include /** * \enum module_cfg_fragment_position @@ -81,15 +83,57 @@ struct module_interface { * component preparation in .prepare() */ int (*prepare)(struct processing_module *mod); + /** - * Module specific processing procedure, called as part of module_adapter - * component copy in .copy(). This procedure is responsible to consume + * Module specific processing procedure + * This procedure is responsible to consume * samples provided by the module_adapter and produce/output the processed * ones back to module_adapter. + * + * there are 3 versions of the procedure, the difference is the format of + * input/output data + * + * the module MUST implement one and ONLY one of them + * + * process_audio_stream and process_raw_data are depreciated and will be removed + * once pipeline learns to use module API directly (without module adapter) + * modules that need such processing should use proper wrappers + * + * process + * - sources are handlers to source API struct source*[] + * - sinks are handlers to sink API struct sink*[] + */ + int (*process)(struct processing_module *mod, + struct sof_source __sparse_cache **sources, int num_of_sources, + struct sof_sink __sparse_cache **sinks, int num_of_sinks); + + /** + * process_audio_stream (depreciated) + * - sources are input_stream_buffer[] + * - sources[].data is a pointer to audio_stream structure + * - sinks are output_stream_buffer[] + * - sinks[].data is a pointer to audio_stream structure + * + * It can be used by modules that support 1:1, 1:N, N:1 sources:sinks configuration. + */ + int (*process_audio_stream)(struct processing_module *mod, + struct input_stream_buffer *input_buffers, + int num_input_buffers, + struct output_stream_buffer *output_buffers, + int num_output_buffers); + + /** + * process_raw_data (depreciated) + * - sources are input_stream_buffer[] + * - sources[].data is a pointer to raw audio data + * - sinks are output_stream_buffer[] + * - sinks[].data is a pointer to raw audio data */ - int (*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); + int (*process_raw_data)(struct processing_module *mod, + struct input_stream_buffer *input_buffers, + int num_input_buffers, + struct output_stream_buffer *output_buffers, + int num_output_buffers); /** * Set module configuration for the given configuration ID diff --git a/src/samples/audio/smart_amp_test_ipc4.c b/src/samples/audio/smart_amp_test_ipc4.c index 1e69b87e72b3..7900c1d6f4c4 100644 --- a/src/samples/audio/smart_amp_test_ipc4.c +++ b/src/samples/audio/smart_amp_test_ipc4.c @@ -76,8 +76,6 @@ static int smart_amp_init(struct processing_module *mod) memcpy_s(&sad->ipc4_cfg.output_pin, out_size, &base_cfg->base_cfg_ext.pin_formats[in_size], out_size); - mod->simple_copy = true; - return 0; sad_fail: @@ -412,7 +410,7 @@ static int smart_amp_prepare(struct processing_module *mod) static struct module_interface smart_amp_interface = { .init = smart_amp_init, .prepare = smart_amp_prepare, - .process = smart_amp_process, + .process_audio_stream = smart_amp_process, .set_configuration = smart_amp_set_config, .get_configuration = smart_amp_get_config, .reset = smart_amp_reset, diff --git a/test/cmocka/src/audio/eq_fir/eq_fir_process.c b/test/cmocka/src/audio/eq_fir/eq_fir_process.c index e406a43526c8..c725f64e3c71 100644 --- a/test/cmocka/src/audio/eq_fir/eq_fir_process.c +++ b/test/cmocka/src/audio/eq_fir/eq_fir_process.c @@ -439,7 +439,8 @@ static void test_audio_eq_fir(void **state) mod->input_buffers[0].consumed = 0; mod->output_buffers[0].size = 0; - ret = module_process(mod, mod->input_buffers, 1, mod->output_buffers, 1); + ret = module_process_legacy(mod, mod->input_buffers, 1, + mod->output_buffers, 1); assert_int_equal(ret, 0); comp_update_buffer_consume(source, mod->input_buffers[0].consumed); diff --git a/test/cmocka/src/audio/eq_iir/eq_iir_process.c b/test/cmocka/src/audio/eq_iir/eq_iir_process.c index 17aa622a7328..86295ad32b17 100644 --- a/test/cmocka/src/audio/eq_iir/eq_iir_process.c +++ b/test/cmocka/src/audio/eq_iir/eq_iir_process.c @@ -428,7 +428,8 @@ static void test_audio_eq_iir(void **state) mod->input_buffers[0].consumed = 0; mod->output_buffers[0].size = 0; - ret = module_process(mod, mod->input_buffers, 1, mod->output_buffers, 1); + ret = module_process_legacy(mod, mod->input_buffers, 1, + mod->output_buffers, 1); assert_int_equal(ret, 0); comp_update_buffer_consume(source, mod->input_buffers[0].consumed); From 5fdf11e9517e7ad85fe0373df0222b8a7dfcfa97 Mon Sep 17 00:00:00 2001 From: Marcin Szkudlinski Date: Mon, 12 Jun 2023 12:55:29 +0200 Subject: [PATCH 09/10] pipeline2.0: change module prepare API to use sink/src.c Module prepare is an operation that needs to set up sink and source according to needs. Therefore it must have access to sink/source handlers This commit adds handlers to API. In case the module uses legacy audio stream sink/source pointers will be NULLs and number of sinks/sources will be zero Signed-off-by: Marcin Szkudlinski --- src/audio/eq_fir/eq_fir.c | 4 +- src/audio/eq_iir/eq_iir.c | 4 +- src/audio/mfcc/mfcc.c | 4 +- src/audio/mixer/mixer.c | 4 +- src/audio/mixin_mixout/mixin_mixout.c | 8 ++- src/audio/module_adapter/module/cadence.c | 4 +- src/audio/module_adapter/module/dts.c | 4 +- src/audio/module_adapter/module/generic.c | 6 +- .../module_adapter/module/iadk_modules.c | 4 +- src/audio/module_adapter/module/passthrough.c | 4 +- .../module_adapter/module/volume/volume.c | 4 +- src/audio/module_adapter/module/waves.c | 4 +- src/audio/module_adapter/module_adapter.c | 55 ++++++++++++++++++- src/audio/mux/mux.c | 4 +- src/audio/selector/selector.c | 4 +- src/audio/tdfb/tdfb.c | 4 +- src/audio/up_down_mixer/up_down_mixer.c | 4 +- .../sof/audio/module_adapter/module/generic.h | 4 +- .../module_adapter/module/module_interface.h | 4 +- src/samples/audio/smart_amp_test_ipc4.c | 4 +- test/cmocka/src/audio/eq_fir/eq_fir_process.c | 2 +- test/cmocka/src/audio/eq_iir/eq_iir_process.c | 2 +- 22 files changed, 117 insertions(+), 24 deletions(-) diff --git a/src/audio/eq_fir/eq_fir.c b/src/audio/eq_fir/eq_fir.c index 0b9e46f12b03..98efc0f727b0 100644 --- a/src/audio/eq_fir/eq_fir.c +++ b/src/audio/eq_fir/eq_fir.c @@ -564,7 +564,9 @@ static void eq_fir_set_alignment(struct audio_stream __sparse_cache *source, audio_stream_init_alignment_constants(byte_align, frame_align_req, sink); } -static int eq_fir_prepare(struct processing_module *mod) +static int eq_fir_prepare(struct processing_module *mod, + struct sof_source __sparse_cache **sources, int num_of_sources, + struct sof_sink __sparse_cache **sinks, int num_of_sinks) { struct comp_data *cd = module_get_private_data(mod); struct comp_buffer *sourceb, *sinkb; diff --git a/src/audio/eq_iir/eq_iir.c b/src/audio/eq_iir/eq_iir.c index 5004e1324d36..a14f564e5728 100644 --- a/src/audio/eq_iir/eq_iir.c +++ b/src/audio/eq_iir/eq_iir.c @@ -879,7 +879,9 @@ static void eq_iir_set_passthrough_func(struct comp_data *cd, #endif } -static int eq_iir_prepare(struct processing_module *mod) +static int eq_iir_prepare(struct processing_module *mod, + struct sof_source __sparse_cache **sources, int num_of_sources, + struct sof_sink __sparse_cache **sinks, int num_of_sinks) { struct comp_data *cd = module_get_private_data(mod); struct comp_buffer *sourceb, *sinkb; diff --git a/src/audio/mfcc/mfcc.c b/src/audio/mfcc/mfcc.c index 744fafb36b9f..b93e49dab743 100644 --- a/src/audio/mfcc/mfcc.c +++ b/src/audio/mfcc/mfcc.c @@ -186,7 +186,9 @@ static void mfcc_set_alignment(struct audio_stream *source, struct audio_stream audio_stream_init_alignment_constants(byte_align, frame_align_req, sink); } -static int mfcc_prepare(struct processing_module *mod) +static int mfcc_prepare(struct processing_module *mod, + struct sof_source __sparse_cache **sources, int num_of_sources, + struct sof_sink __sparse_cache **sinks, int num_of_sinks) { struct mfcc_comp_data *cd = module_get_private_data(mod); struct comp_buffer *sourceb; diff --git a/src/audio/mixer/mixer.c b/src/audio/mixer/mixer.c index f9b2f92ca204..f7d967ca73a5 100644 --- a/src/audio/mixer/mixer.c +++ b/src/audio/mixer/mixer.c @@ -217,7 +217,9 @@ static inline void mixer_set_frame_alignment(struct audio_stream __sparse_cache audio_stream_init_alignment_constants(byte_align, frame_align_req, source); } -static int mixer_prepare(struct processing_module *mod) +static int mixer_prepare(struct processing_module *mod, + struct sof_source __sparse_cache **sources, int num_of_sources, + struct sof_sink __sparse_cache **sinks, int num_of_sinks) { struct mixer_data *md = module_get_private_data(mod); struct comp_buffer __sparse_cache *sink_c; diff --git a/src/audio/mixin_mixout/mixin_mixout.c b/src/audio/mixin_mixout/mixin_mixout.c index af081f491250..a4f969780fcd 100644 --- a/src/audio/mixin_mixout/mixin_mixout.c +++ b/src/audio/mixin_mixout/mixin_mixout.c @@ -686,7 +686,9 @@ static int mixin_params(struct processing_module *mod) * We should also make sure that we propagate the prepare call to downstream * if downstream is not currently active. */ -static int mixin_prepare(struct processing_module *mod) +static int mixin_prepare(struct processing_module *mod, + struct sof_source __sparse_cache **sources, int num_of_sources, + struct sof_sink __sparse_cache **sinks, int num_of_sinks) { struct mixin_data *md = module_get_private_data(mod); struct comp_dev *dev = mod->dev; @@ -805,7 +807,9 @@ static int mixout_params(struct processing_module *mod) return 0; } -static int mixout_prepare(struct processing_module *mod) +static int mixout_prepare(struct processing_module *mod, + struct sof_source __sparse_cache **sources, int num_of_sources, + struct sof_sink __sparse_cache **sinks, int num_of_sinks) { struct module_source_info __sparse_cache *mod_source_info; struct comp_dev *dev = mod->dev; diff --git a/src/audio/module_adapter/module/cadence.c b/src/audio/module_adapter/module/cadence.c index 5ae8715cac5a..250bf4373822 100644 --- a/src/audio/module_adapter/module/cadence.c +++ b/src/audio/module_adapter/module/cadence.c @@ -501,7 +501,9 @@ static int cadence_codec_init_process(struct processing_module *mod) return 0; } -static int cadence_codec_prepare(struct processing_module *mod) +static int cadence_codec_prepare(struct processing_module *mod, + struct sof_source __sparse_cache **sources, int num_of_sources, + struct sof_sink __sparse_cache **sinks, int num_of_sinks) { int ret = 0, mem_tabs_size; struct comp_dev *dev = mod->dev; diff --git a/src/audio/module_adapter/module/dts.c b/src/audio/module_adapter/module/dts.c index c59e51990303..a2d7cb54e24f 100644 --- a/src/audio/module_adapter/module/dts.c +++ b/src/audio/module_adapter/module/dts.c @@ -183,7 +183,9 @@ static int dts_codec_init(struct processing_module *mod) return ret; } -static int dts_codec_prepare(struct processing_module *mod) +static int dts_codec_prepare(struct processing_module *mod, + struct sof_source __sparse_cache **sources, int num_of_sources, + struct sof_sink __sparse_cache **sinks, int num_of_sinks) { int ret; struct comp_dev *dev = mod->dev; diff --git a/src/audio/module_adapter/module/generic.c b/src/audio/module_adapter/module/generic.c index 521152d2ee9a..ef29ec7c4c85 100644 --- a/src/audio/module_adapter/module/generic.c +++ b/src/audio/module_adapter/module/generic.c @@ -192,7 +192,9 @@ static int validate_config(struct module_config *cfg) return 0; } -int module_prepare(struct processing_module *mod) +int module_prepare(struct processing_module *mod, + struct sof_source __sparse_cache **sources, int num_of_sources, + struct sof_sink __sparse_cache **sinks, int num_of_sinks) { int ret; struct module_data *md = &mod->priv; @@ -205,7 +207,7 @@ int module_prepare(struct processing_module *mod) if (mod->priv.state < MODULE_INITIALIZED) return -EPERM; - ret = md->ops->prepare(mod); + ret = md->ops->prepare(mod, sources, num_of_sources, sinks, num_of_sinks); if (ret) { comp_err(dev, "module_prepare() error %d: module specific prepare failed, comp_id %d", ret, dev_comp_id(dev)); diff --git a/src/audio/module_adapter/module/iadk_modules.c b/src/audio/module_adapter/module/iadk_modules.c index 3af85e271ab9..bf7e9aa1cb45 100644 --- a/src/audio/module_adapter/module/iadk_modules.c +++ b/src/audio/module_adapter/module/iadk_modules.c @@ -117,7 +117,9 @@ static int iadk_modules_init(struct processing_module *mod) * configuration. Its internal structure is proprietary to the module implementation. * There is one assumption - all IADK modules utilize IPC4 protocol. */ -static int iadk_modules_prepare(struct processing_module *mod) +static int iadk_modules_prepare(struct processing_module *mod, + struct sof_source __sparse_cache **sources, int num_of_sources, + struct sof_sink __sparse_cache **sinks, int num_of_sinks) { struct comp_dev *dev = mod->dev; int ret = 0; diff --git a/src/audio/module_adapter/module/passthrough.c b/src/audio/module_adapter/module/passthrough.c index 46b652adbecf..a7e41c04ff65 100644 --- a/src/audio/module_adapter/module/passthrough.c +++ b/src/audio/module_adapter/module/passthrough.c @@ -20,7 +20,9 @@ static int passthrough_codec_init(struct processing_module *mod) return 0; } -static int passthrough_codec_prepare(struct processing_module *mod) +static int passthrough_codec_prepare(struct processing_module *mod, + struct sof_source __sparse_cache **sources, int num_of_sources, + struct sof_sink __sparse_cache **sinks, int num_of_sinks) { struct comp_dev *dev = mod->dev; struct module_data *codec = &mod->priv; diff --git a/src/audio/module_adapter/module/volume/volume.c b/src/audio/module_adapter/module/volume/volume.c index 48a167cf8b5f..f36b03da1590 100644 --- a/src/audio/module_adapter/module/volume/volume.c +++ b/src/audio/module_adapter/module/volume/volume.c @@ -1242,7 +1242,9 @@ static void volume_set_alignment(struct audio_stream __sparse_cache *source, * Volume component is usually first and last in pipelines so it makes sense * to also do some type of conversion here. */ -static int volume_prepare(struct processing_module *mod) +static int volume_prepare(struct processing_module *mod, + struct sof_source __sparse_cache **sources, int num_of_sources, + struct sof_sink __sparse_cache **sinks, int num_of_sinks) { struct vol_data *cd = module_get_private_data(mod); struct module_data *md = &mod->priv; diff --git a/src/audio/module_adapter/module/waves.c b/src/audio/module_adapter/module/waves.c index 5b0b61a970db..90b3a24a5919 100644 --- a/src/audio/module_adapter/module/waves.c +++ b/src/audio/module_adapter/module/waves.c @@ -688,7 +688,9 @@ static int waves_codec_init(struct processing_module *mod) return ret; } -static int waves_codec_prepare(struct processing_module *mod) +static int waves_codec_prepare(struct processing_module *mod, + struct sof_source __sparse_cache **sources, int num_of_sources, + struct sof_sink __sparse_cache **sinks, int num_of_sinks) { struct comp_dev *dev = mod->dev; int ret; diff --git a/src/audio/module_adapter/module_adapter.c b/src/audio/module_adapter/module_adapter.c index 15d29970857f..bece14f8c43d 100644 --- a/src/audio/module_adapter/module_adapter.c +++ b/src/audio/module_adapter/module_adapter.c @@ -165,6 +165,55 @@ 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 comp_buffer __sparse_cache *source_buffers_c[PLATFORM_MAX_STREAMS]; + struct comp_buffer __sparse_cache *sinks_buffers_c[PLATFORM_MAX_STREAMS]; + struct sof_sink __sparse_cache *audio_sink[PLATFORM_MAX_STREAMS]; + struct sof_source __sparse_cache *audio_src[PLATFORM_MAX_STREAMS]; + struct processing_module *mod = comp_get_drvdata(dev); + struct list_item *blist; + uint32_t num_of_sources = 0; + uint32_t num_of_sinks = 0; + int ret; + + /* acquire all sink and source buffers, get handlers to sink/source API */ + list_for_item(blist, &dev->bsink_list) { + struct comp_buffer *sink_buffer_uc; + + sink_buffer_uc = container_of(blist, struct comp_buffer, source_list); + sinks_buffers_c[num_of_sinks] = buffer_acquire(sink_buffer_uc); + audio_sink[num_of_sinks] = + audio_stream_get_sink(&sinks_buffers_c[num_of_sinks]->stream); + sink_reset_num_of_processed_bytes(audio_sink[num_of_sinks]); + num_of_sinks++; + } + + list_for_item(blist, &dev->bsource_list) { + struct comp_buffer *source_buffer_uc; + + source_buffer_uc = container_of(blist, struct comp_buffer, sink_list); + source_buffers_c[num_of_sources] = buffer_acquire(source_buffer_uc); + audio_src[num_of_sources] = + audio_stream_get_source(&source_buffers_c[num_of_sources]->stream); + source_reset_num_of_processed_bytes(audio_src[num_of_sources]); + num_of_sources++; + } + + /* Prepare module */ + ret = module_prepare(mod, audio_src, num_of_sources, audio_sink, num_of_sinks); + + /* release all source buffers in reverse order */ + for (int i = num_of_sources - 1; i >= 0; i--) + buffer_release(source_buffers_c[i]); + + /* release all sink buffers in reverse order */ + for (int i = num_of_sinks - 1; i >= 0 ; i--) + buffer_release(sinks_buffers_c[i]); + + return ret; +} + /* * \brief Prepare the module * \param[in] dev - component device pointer. @@ -189,7 +238,11 @@ int module_adapter_prepare(struct comp_dev *dev) comp_dbg(dev, "module_adapter_prepare() start"); /* Prepare module */ - ret = module_prepare(mod); + if (IS_PROCESSING_MODE_SINK_SOURCE(mod)) + ret = module_adapter_sink_src_prepare(dev); + else + ret = module_prepare(mod, NULL, 0, NULL, 0); + if (ret) { if (ret != PPL_STATUS_PATH_STOP) comp_err(dev, "module_adapter_prepare() error %x: module prepare failed", diff --git a/src/audio/mux/mux.c b/src/audio/mux/mux.c index cbb0b745cf66..5efcba876e0f 100644 --- a/src/audio/mux/mux.c +++ b/src/audio/mux/mux.c @@ -602,7 +602,9 @@ static int mux_reset(struct processing_module *mod) return 0; } -static int mux_prepare(struct processing_module *mod) +static int mux_prepare(struct processing_module *mod, + struct sof_source __sparse_cache **sources, int num_of_sources, + struct sof_sink __sparse_cache **sinks, int num_of_sinks) { struct comp_dev *dev = mod->dev; struct comp_data *cd = module_get_private_data(mod); diff --git a/src/audio/selector/selector.c b/src/audio/selector/selector.c index 9bc6d542e9ef..065c020cb87e 100644 --- a/src/audio/selector/selector.c +++ b/src/audio/selector/selector.c @@ -890,7 +890,9 @@ static int selector_process(struct processing_module *mod, * \param[in,out] mod Selector base module device. * \return Error code. */ -static int selector_prepare(struct processing_module *mod) +static int selector_prepare(struct processing_module *mod, + struct sof_source __sparse_cache **sources, int num_of_sources, + struct sof_sink __sparse_cache **sinks, int num_of_sinks) { struct comp_data *cd = module_get_private_data(mod); struct module_data *md = &mod->priv; diff --git a/src/audio/tdfb/tdfb.c b/src/audio/tdfb/tdfb.c index 24479526b691..d1b04b7faf42 100644 --- a/src/audio/tdfb/tdfb.c +++ b/src/audio/tdfb/tdfb.c @@ -725,7 +725,9 @@ static void tdfb_set_alignment(struct audio_stream __sparse_cache *source, audio_stream_init_alignment_constants(byte_align, frame_align_req, sink); } -static int tdfb_prepare(struct processing_module *mod) +static int tdfb_prepare(struct processing_module *mod, + struct sof_source __sparse_cache **sources, int num_of_sources, + struct sof_sink __sparse_cache **sinks, int num_of_sinks) { struct tdfb_comp_data *cd = module_get_private_data(mod); struct comp_buffer *sourceb, *sinkb; diff --git a/src/audio/up_down_mixer/up_down_mixer.c b/src/audio/up_down_mixer/up_down_mixer.c index 2959556e33fc..e1887865ac70 100644 --- a/src/audio/up_down_mixer/up_down_mixer.c +++ b/src/audio/up_down_mixer/up_down_mixer.c @@ -399,7 +399,9 @@ static int up_down_mixer_init(struct processing_module *mod) } /* just stubs for now. Remove these after making these ops optional in the module adapter */ -static int up_down_mixer_prepare(struct processing_module *mod) +static int up_down_mixer_prepare(struct processing_module *mod, + struct sof_source __sparse_cache **sources, int num_of_sources, + struct sof_sink __sparse_cache **sinks, int num_of_sinks) { struct up_down_mixer_data *cd = module_get_private_data(mod); struct comp_dev *dev = mod->dev; diff --git a/src/include/sof/audio/module_adapter/module/generic.h b/src/include/sof/audio/module_adapter/module/generic.h index 22bd45c1f8e6..fc4c8b9fd63c 100644 --- a/src/include/sof/audio/module_adapter/module/generic.h +++ b/src/include/sof/audio/module_adapter/module/generic.h @@ -219,7 +219,9 @@ int module_init(struct processing_module *mod, struct module_interface *interfac void *module_allocate_memory(struct processing_module *mod, uint32_t size, uint32_t alignment); int module_free_memory(struct processing_module *mod, void *ptr); void module_free_all_memory(struct processing_module *mod); -int module_prepare(struct processing_module *mod); +int module_prepare(struct processing_module *mod, + struct sof_source __sparse_cache **sources, int num_of_sources, + struct sof_sink __sparse_cache **sinks, int num_of_sinks); int module_process_sink_src(struct processing_module *mod, struct sof_source __sparse_cache **sources, int num_of_sources, struct sof_sink __sparse_cache **sinks, int num_of_sinks); diff --git a/src/include/sof/audio/module_adapter/module/module_interface.h b/src/include/sof/audio/module_adapter/module/module_interface.h index cd7622208649..dec02f3cfa5a 100644 --- a/src/include/sof/audio/module_adapter/module/module_interface.h +++ b/src/include/sof/audio/module_adapter/module/module_interface.h @@ -82,7 +82,9 @@ struct module_interface { * Module specific prepare procedure, called as part of module_adapter * component preparation in .prepare() */ - int (*prepare)(struct processing_module *mod); + int (*prepare)(struct processing_module *mod, + struct sof_source __sparse_cache **sources, int num_of_sources, + struct sof_sink __sparse_cache **sinks, int num_of_sinks); /** * Module specific processing procedure diff --git a/src/samples/audio/smart_amp_test_ipc4.c b/src/samples/audio/smart_amp_test_ipc4.c index 7900c1d6f4c4..e73ca26fdccd 100644 --- a/src/samples/audio/smart_amp_test_ipc4.c +++ b/src/samples/audio/smart_amp_test_ipc4.c @@ -364,7 +364,9 @@ static int smart_amp_reset(struct processing_module *mod) return 0; } -static int smart_amp_prepare(struct processing_module *mod) +static int smart_amp_prepare(struct processing_module *mod, + struct sof_source __sparse_cache **sources, int num_of_sources, + struct sof_sink __sparse_cache **sinks, int num_of_sinks) { struct smart_amp_data *sad = module_get_private_data(mod); struct comp_dev *dev = mod->dev; diff --git a/test/cmocka/src/audio/eq_fir/eq_fir_process.c b/test/cmocka/src/audio/eq_fir/eq_fir_process.c index c725f64e3c71..5cd53c1cfbe6 100644 --- a/test/cmocka/src/audio/eq_fir/eq_fir_process.c +++ b/test/cmocka/src/audio/eq_fir/eq_fir_process.c @@ -171,7 +171,7 @@ static int setup(void **state) mod->stream_params->channels = params->channels; mod->period_bytes = get_frame_bytes(params->source_format, params->channels) * 48000 / 1000; - ret = module_prepare(mod); + ret = module_prepare(mod, NULL, 0, NULL, 0); if (ret) return ret; diff --git a/test/cmocka/src/audio/eq_iir/eq_iir_process.c b/test/cmocka/src/audio/eq_iir/eq_iir_process.c index 86295ad32b17..b960a6997b14 100644 --- a/test/cmocka/src/audio/eq_iir/eq_iir_process.c +++ b/test/cmocka/src/audio/eq_iir/eq_iir_process.c @@ -170,7 +170,7 @@ static int setup(void **state) mod->stream_params->channels = params->channels; mod->period_bytes = get_frame_bytes(params->source_format, params->channels) * 48000 / 1000; - ret = module_prepare(mod); + ret = module_prepare(mod, NULL, 0, NULL, 0); if (ret) return ret; From b900d5e3748edb9b6a5b756f440d18d5dd30b307 Mon Sep 17 00:00:00 2001 From: Marcin Szkudlinski Date: Mon, 12 Jun 2023 12:57:49 +0200 Subject: [PATCH 10/10] src: POC - change src module to use sink/source API This is a porting of SRC module to use sink/src API To have src fully ported there's a need to get 100% independent of audio_stream and buffer.c This step is necessary because other implementations of sink/src, like DP Queue, may not be based on buffer implementation Signed-off-by: Marcin Szkudlinski --- src/audio/src/src.c | 333 ++++++++++++++++++-------------------------- 1 file changed, 132 insertions(+), 201 deletions(-) diff --git a/src/audio/src/src.c b/src/audio/src/src.c index 8e0116c100e4..3da1f7b9248d 100644 --- a/src/audio/src/src.c +++ b/src/audio/src/src.c @@ -15,6 +15,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -35,6 +38,7 @@ #include #include #include +#include #if SRC_SHORT || CONFIG_COMP_SRC_TINY #include @@ -97,12 +101,8 @@ struct comp_data { int sink_frames; int sample_container_bytes; int channels_count; - void (*src_func)(struct comp_dev *dev, - struct comp_data *cd, - const struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink, - int *consumed, - int *produced); + int (*src_func)(struct comp_data *cd, struct sof_source __sparse_cache *source, + struct sof_sink __sparse_cache *sink); void (*polyphase_func)(struct src_stage_prm *s); }; @@ -335,18 +335,15 @@ int src_polyphase_init(struct polyphase_src *src, struct src_param *p, } /* Fallback function */ -static void src_fallback(struct comp_dev *dev, struct comp_data *cd, - const struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink, int *n_read, int *n_written) +static int src_fallback(struct comp_data *cd, struct sof_source __sparse_cache *source, + struct sof_sink __sparse_cache *sink) { - *n_read = 0; - *n_written = 0; + return 0; } /* Normal 2 stage SRC */ -static void src_2s(struct comp_dev *dev, struct comp_data *cd, - const struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink, int *n_read, int *n_written) +static int src_2s(struct comp_data *cd, + struct sof_source __sparse_cache *source, struct sof_sink __sparse_cache *sink) { struct src_stage_prm s1; struct src_stage_prm s2; @@ -354,38 +351,47 @@ static void src_2s(struct comp_dev *dev, struct comp_data *cd, int s1_blk_out; int s2_blk_in; int s2_blk_out; - void *sbuf_addr = cd->delay_lines; + uint32_t n_read = 0, n_written = 0; + int ret; + uint8_t *buffer_start; void *sbuf_end_addr = &cd->delay_lines[cd->param.sbuf_length]; size_t sbuf_size = cd->param.sbuf_length * sizeof(int32_t); - int nch = audio_stream_get_channels(source); + /* chan sink == chan src therefore we only need to use one*/ + int nch = source_get_channels(source); int sbuf_free = cd->param.sbuf_length - cd->sbuf_avail; - int avail_b = audio_stream_get_avail_bytes(source); - int free_b = audio_stream_get_free_bytes(sink); + int avail_b = source_get_data_available(source); + int free_b = sink_get_free_size(sink); int sz = cd->sample_container_bytes; + uint32_t source_frag_size = cd->param.blk_in * source_get_frame_bytes(source); + uint32_t sink_frag_size = cd->param.blk_out * sink_get_frame_bytes(sink); + + ret = source_get_data(source, source_frag_size, + &s1.x_rptr, (void **)&buffer_start, &s1.x_size); + if (ret) + return ret; + s1.x_end_addr = buffer_start + s1.x_size; + + ret = sink_get_buffer(sink, sink_frag_size, + &s2.y_wptr, (void **)&buffer_start, &s2.y_size); + if (ret) { + source_release_data(source, 0); + return ret; + } + s2.y_end_addr = buffer_start + s2.y_size; - *n_read = 0; - *n_written = 0; - s1.x_end_addr = audio_stream_get_end_addr(source); - s1.x_size = audio_stream_get_size(source); - s1.y_addr = sbuf_addr; s1.y_end_addr = sbuf_end_addr; s1.y_size = sbuf_size; s1.state = &cd->src.state1; s1.stage = cd->src.stage1; - s1.x_rptr = audio_stream_get_rptr(source); s1.y_wptr = cd->sbuf_w_ptr; s1.nch = nch; s1.shift = cd->data_shift; s2.x_end_addr = sbuf_end_addr; s2.x_size = sbuf_size; - s2.y_addr = audio_stream_get_addr(sink); - s2.y_end_addr = audio_stream_get_end_addr(sink); - s2.y_size = audio_stream_get_size(sink); s2.state = &cd->src.state2; s2.stage = cd->src.stage2; s2.x_rptr = cd->sbuf_r_ptr; - s2.y_wptr = audio_stream_get_wptr(sink); s2.nch = nch; s2.shift = cd->data_shift; @@ -402,7 +408,6 @@ static void src_2s(struct comp_dev *dev, struct comp_data *cd, if (s1_blk_out > sbuf_free) { s1.times = sbuf_free / (cd->src.stage1->blk_out * nch); s1_blk_out = s1.times * cd->src.stage1->blk_out * nch; - comp_dbg(dev, "s1.times = %d", s1.times); } s1_blk_in = s1.times * cd->src.stage1->blk_in * nch; @@ -411,7 +416,7 @@ static void src_2s(struct comp_dev *dev, struct comp_data *cd, cd->sbuf_w_ptr = s1.y_wptr; cd->sbuf_avail += s1_blk_out; - *n_read += s1.times * cd->src.stage1->blk_in; + n_read += s1.times * cd->src.stage1->blk_in; } s2.times = cd->param.stage2_times; @@ -419,7 +424,6 @@ static void src_2s(struct comp_dev *dev, struct comp_data *cd, if (s2_blk_in > cd->sbuf_avail) { s2.times = cd->sbuf_avail / (cd->src.stage2->blk_in * nch); s2_blk_in = s2.times * cd->src.stage2->blk_in * nch; - comp_dbg(dev, "s2.times = %d", s2.times); } /* Test if second stage can be run with default block length. */ @@ -429,56 +433,71 @@ static void src_2s(struct comp_dev *dev, struct comp_data *cd, cd->sbuf_r_ptr = s2.x_rptr; cd->sbuf_avail -= s2_blk_in; - *n_written += s2.times * cd->src.stage2->blk_out; + n_written += s2.times * cd->src.stage2->blk_out; } + + /* commit the processed data */ + source_release_data(source, n_read * source_get_frame_bytes(source)); + sink_commit_buffer(sink, n_written * sink_get_frame_bytes(sink)); + return 0; } /* 1 stage SRC for simple conversions */ -static void src_1s(struct comp_dev *dev, struct comp_data *cd, - const struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink, int *n_read, int *n_written) +static int src_1s(struct comp_data *cd, struct sof_source __sparse_cache *source, + struct sof_sink __sparse_cache *sink) { struct src_stage_prm s1; + int ret; + uint8_t *buffer_start; + uint32_t source_frag_size = cd->param.blk_in * source_get_frame_bytes(source); + uint32_t sink_frag_size = cd->param.blk_out * sink_get_frame_bytes(sink); + + ret = source_get_data(source, source_frag_size, + &s1.x_rptr, (void **)&buffer_start, &s1.x_size); + if (ret) + return ret; + s1.x_end_addr = buffer_start + s1.x_size; + + ret = sink_get_buffer(sink, sink_frag_size, + &s1.y_wptr, (void **)&buffer_start, &s1.y_size); + if (ret) { + source_release_data(source, 0); + return ret; + } + s1.y_end_addr = buffer_start + s1.y_size; s1.times = cd->param.stage1_times; - s1.x_rptr = audio_stream_get_rptr(source); - s1.x_end_addr = audio_stream_get_end_addr(source); - s1.x_size = audio_stream_get_size(source); - s1.y_wptr = audio_stream_get_wptr(sink); - s1.y_end_addr = audio_stream_get_end_addr(sink); - s1.y_size = audio_stream_get_size(sink); s1.state = &cd->src.state1; s1.stage = cd->src.stage1; - s1.nch = audio_stream_get_channels(source); + s1.nch = source_get_channels(source); /* src channels must == sink channels */ s1.shift = cd->data_shift; cd->polyphase_func(&s1); - *n_read = cd->param.blk_in; - *n_written = cd->param.blk_out; + /* commit the processed data */ + source_release_data(source, UINT_MAX); + sink_commit_buffer(sink, UINT_MAX); + + return 0; } /* A fast copy function for same in and out rate */ -static void src_copy_sxx(struct comp_dev *dev, struct comp_data *cd, - const struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink, - int *n_read, int *n_written) +static int src_copy_sxx(struct comp_data *cd, struct sof_source __sparse_cache *source, + struct sof_sink __sparse_cache *sink) { int frames = cd->param.blk_in; - switch (audio_stream_get_frm_fmt(sink)) { + switch (source_get_frm_fmt(source)) { case SOF_IPC_FRAME_S16_LE: case SOF_IPC_FRAME_S24_4LE: case SOF_IPC_FRAME_S32_LE: - audio_stream_copy(source, 0, sink, 0, - frames * audio_stream_get_channels(source)); - *n_read = frames; - *n_written = frames; - break; + return source_to_sink_copy(source, sink, true, + frames * source_get_frame_bytes(source)); default: - *n_read = 0; - *n_written = 0; + break; } + + return -ENOTSUP; } #if CONFIG_IPC_MAJOR_4 @@ -512,15 +531,13 @@ static int src_stream_pcm_sink_rate_check(struct ipc4_config_src cfg, * set up param then verify param. BTW for IPC3 path, the param is sent by * host driver. */ -static int src_set_params(struct processing_module *mod) +static int src_set_params(struct processing_module *mod, struct sof_sink __sparse_cache *sink) { struct sof_ipc_stream_params src_params; struct sof_ipc_stream_params *params = mod->stream_params; struct comp_data *cd = module_get_private_data(mod); enum sof_ipc_frame frame_fmt, valid_fmt; struct comp_dev *dev = mod->dev; - struct comp_buffer *sinkb; - struct comp_buffer __sparse_cache *sink_c; int ret; src_params = *params; @@ -537,17 +554,14 @@ static int src_set_params(struct processing_module *mod) src_params.frame_fmt = frame_fmt; component_set_nearest_period_frames(dev, src_params.rate); - sinkb = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - sink_c = buffer_acquire(sinkb); - ret = buffer_set_params(sink_c, &src_params, true); - buffer_release(sink_c); + ret = sink_set_params(sink, &src_params, true); /* Update module stream_params */ params->rate = cd->ipc_config.sink_rate; return ret; } -static void src_set_sink_params(struct comp_dev *dev, struct comp_buffer __sparse_cache *sinkb) +static void src_set_sink_params(struct comp_dev *dev, struct sof_sink __sparse_cache *sink) { struct processing_module *mod = comp_get_drvdata(dev); struct comp_data *cd = module_get_private_data(mod); @@ -558,13 +572,10 @@ static void src_set_sink_params(struct comp_dev *dev, struct comp_buffer __spars cd->ipc_config.base.audio_fmt.valid_bit_depth, &frame_fmt, &valid_fmt, cd->ipc_config.base.audio_fmt.s_type); - - audio_stream_set_frm_fmt(&sinkb->stream, frame_fmt); - audio_stream_set_valid_fmt(&sinkb->stream, valid_fmt); - audio_stream_set_channels(&sinkb->stream, cd->ipc_config.base.audio_fmt.channels_count); - - audio_stream_set_buffer_fmt(&sinkb->stream, - cd->ipc_config.base.audio_fmt.interleaving_style); + sink_set_frm_fmt(sink, frame_fmt); + sink_set_valid_fmt(sink, valid_fmt); + sink_set_channels(sink, cd->ipc_config.base.audio_fmt.channels_count); + sink_set_buffer_fmt(sink, cd->ipc_config.base.audio_fmt.interleaving_style); } #elif CONFIG_IPC_MAJOR_3 @@ -598,35 +609,28 @@ static int src_stream_pcm_source_rate_check(struct ipc_config_src cfg, return 0; } -static int src_set_params(struct processing_module *mod) +static int src_set_params(struct processing_module *mod, struct sof_sink __sparse_cache *sink) { return 0; } -static void src_set_sink_params(struct comp_dev *dev, struct comp_buffer __sparse_cache *sinkb) {} +static void src_set_sink_params(struct comp_dev *dev, struct sof_sink __sparse_cache *sink) +{ + /* empty */ +} + #else #error "No or invalid IPC MAJOR version selected." #endif /* CONFIG_IPC_MAJOR_4 */ -static inline void src_update_buffer_position(struct input_stream_buffer *input_buffers, - struct output_stream_buffer *output_buffers, - int *n_read, int *n_written) -{ - struct audio_stream __sparse_cache *source = input_buffers->data; - struct audio_stream __sparse_cache *sink = output_buffers->data; - - input_buffers->consumed += audio_stream_frame_bytes(source) * (*n_read); - output_buffers->size += audio_stream_frame_bytes(sink) * (*n_written); -} - -static void src_set_alignment(struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink) +static void src_set_alignment(struct sof_source __sparse_cache *source, + struct sof_sink __sparse_cache *sink) { const uint32_t byte_align = 1; const uint32_t frame_align_req = 1; - audio_stream_init_alignment_constants(byte_align, frame_align_req, source); - audio_stream_init_alignment_constants(byte_align, frame_align_req, sink); + source_set_alignment_constants(source, byte_align, frame_align_req); + sink_set_alignment_constants(sink, byte_align, frame_align_req); } static int src_verify_params(struct processing_module *mod) @@ -667,8 +671,8 @@ static int src_verify_params(struct processing_module *mod) } static int src_get_copy_limits(struct comp_data *cd, - const struct audio_stream __sparse_cache *source, - const struct audio_stream __sparse_cache *sink) + struct sof_source __sparse_cache *source, + struct sof_sink __sparse_cache *sink) { struct src_param *sp; struct src_stage *s1; @@ -684,22 +688,20 @@ static int src_get_copy_limits(struct comp_data *cd, /* Calculate how many blocks can be processed with * available source and free sink frames amount. */ + frames_snk = sink_get_free_frames(sink); + frames_src = source_get_data_frames_available(source); if (s2->filter_length > 1) { /* Two polyphase filters case */ - frames_snk = audio_stream_get_free_frames(sink); frames_snk = MIN(frames_snk, cd->sink_frames + s2->blk_out); sp->stage2_times = frames_snk / s2->blk_out; - frames_src = audio_stream_get_avail_frames(source); frames_src = MIN(frames_src, cd->source_frames + s1->blk_in); sp->stage1_times = frames_src / s1->blk_in; sp->blk_in = sp->stage1_times * s1->blk_in; sp->blk_out = sp->stage2_times * s2->blk_out; } else { /* Single polyphase filter case */ - frames_snk = audio_stream_get_free_frames(sink); frames_snk = MIN(frames_snk, cd->sink_frames + s1->blk_out); sp->stage1_times = frames_snk / s1->blk_out; - frames_src = audio_stream_get_avail_frames(source); sp->stage1_times = MIN(sp->stage1_times, frames_src / s1->blk_in); sp->blk_in = sp->stage1_times * s1->blk_in; @@ -712,54 +714,12 @@ static int src_get_copy_limits(struct comp_data *cd, return 0; } -static int src_check_buffer_sizes(struct comp_dev *dev, struct comp_data *cd, - struct audio_stream __sparse_cache *source_stream, - struct audio_stream __sparse_cache *sink_stream) -{ - struct src_stage *s1 = cd->src.stage1; - struct src_stage *s2 = cd->src.stage2; - int stage1_times; - int stage2_times; - int blk_in; - int blk_out; - int n; - - if (s2->filter_length > 1) { - /* Two polyphase filters case */ - stage2_times = ceil_divide(cd->sink_frames, s2->blk_out); - stage1_times = ceil_divide(cd->source_frames, s1->blk_in); - blk_in = stage1_times * s1->blk_in; - blk_out = stage2_times * s2->blk_out; - } else { - /* Single polyphase filter case */ - stage1_times = ceil_divide(cd->sink_frames, s1->blk_out); - n = ceil_divide(cd->source_frames, s1->blk_in); - stage1_times = MAX(stage1_times, n); - blk_in = stage1_times * s1->blk_in; - blk_out = stage1_times * s1->blk_out; - } - - n = audio_stream_frame_bytes(source_stream) * (blk_in + cd->source_frames); - if (audio_stream_get_size(source_stream) < n) { - comp_warn(dev, "Source size %d is less than required %d", - audio_stream_get_size(source_stream), n); - } - - n = audio_stream_frame_bytes(sink_stream) * (blk_out + cd->sink_frames); - if (audio_stream_get_size(sink_stream) < n) { - comp_warn(dev, "Sink size %d is less than required %d", - audio_stream_get_size(sink_stream), n); - } - - return 0; -} - -static int src_params_general(struct processing_module *mod) +static int src_params_general(struct processing_module *mod, + struct sof_source __sparse_cache *source, + struct sof_sink __sparse_cache *sink) { struct comp_data *cd = module_get_private_data(mod); struct comp_dev *dev = mod->dev; - struct comp_buffer *sourceb, *sinkb; - struct comp_buffer __sparse_cache *source_c, *sink_c; size_t delay_lines_size; int32_t *buffer_start; int n; @@ -767,7 +727,7 @@ static int src_params_general(struct processing_module *mod) comp_info(dev, "src_params()"); - err = src_set_params(mod); + err = src_set_params(mod, sink); if (err < 0) { comp_err(dev, "src_params(): set params failed."); return err; @@ -779,18 +739,13 @@ static int src_params_general(struct processing_module *mod) return err; } - /* src components will only ever have 1 source and 1 sink buffer */ - sourceb = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); - sinkb = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - source_c = buffer_acquire(sourceb); - sink_c = buffer_acquire(sinkb); - src_set_sink_params(dev, sink_c); + src_set_sink_params(dev, sink); #if CONFIG_IPC_MAJOR_3 /* Set source/sink_rate/frames */ - cd->channels_count = audio_stream_get_channels(&source_c->stream); - cd->source_rate = audio_stream_get_rate(&source_c->stream); - cd->sink_rate = audio_stream_get_rate(&sink_c->stream); + cd->channels_count = source_get_channels(source); + cd->source_rate = source_get_rate(source); + cd->sink_rate = sink_get_rate(sink); cd->sample_container_bytes = mod->stream_params->sample_container_bytes; #endif comp_info(dev, "src_params(), source_rate = %u, sink_rate = %u", @@ -799,8 +754,7 @@ static int src_params_general(struct processing_module *mod) cd->sample_container_bytes, cd->channels_count, dev->frames); if (!cd->sink_rate) { comp_err(dev, "src_params(), zero sink rate"); - err = -EINVAL; - goto out; + return -EINVAL; } cd->source_frames = dev->frames * cd->source_rate / cd->sink_rate; @@ -810,7 +764,7 @@ static int src_params_general(struct processing_module *mod) err = src_buffer_lengths(dev, cd, cd->channels_count); if (err < 0) { comp_err(dev, "src_params(): src_buffer_lengths() failed"); - goto out; + return err; } /* @@ -822,8 +776,7 @@ static int src_params_general(struct processing_module *mod) if (delay_lines_size == 0) { comp_err(dev, "src_params(): delay_lines_size = 0"); - err = -EINVAL; - goto out; + return -EINVAL; } /* free any existing delay lines. TODO reuse if same size */ @@ -833,8 +786,7 @@ static int src_params_general(struct processing_module *mod) if (!cd->delay_lines) { comp_err(dev, "src_params(): failed to alloc cd->delay_lines, delay_lines_size = %u", delay_lines_size); - err = -EINVAL; - goto out; + return -EINVAL; } /* Clear all delay lines here */ @@ -866,43 +818,27 @@ static int src_params_general(struct processing_module *mod) */ comp_info(dev, "src_params(), missing coefficients for requested rates combination"); cd->src_func = src_fallback; - err = -EINVAL; + return -EINVAL; } -out: - buffer_release(sink_c); - buffer_release(source_c); - - return err; + return 0; } -static int src_prepare_general(struct processing_module *mod) +static int src_prepare_general(struct processing_module *mod, + struct sof_source __sparse_cache *source, + struct sof_sink __sparse_cache *sink) { struct comp_data *cd = module_get_private_data(mod); struct comp_dev *dev = mod->dev; - struct comp_buffer *sourceb, *sinkb; - struct comp_buffer __sparse_cache *source_c, *sink_c; - int ret; + int ret = 0; #if CONFIG_IPC_MAJOR_3 enum sof_ipc_frame source_format; enum sof_ipc_frame sink_format; #endif - /* SRC component will only ever have 1 source and 1 sink buffer */ - sourceb = list_first_item(&dev->bsource_list, - struct comp_buffer, sink_list); - sinkb = list_first_item(&dev->bsink_list, - struct comp_buffer, source_list); - - source_c = buffer_acquire(sourceb); - sink_c = buffer_acquire(sinkb); /* set align requirements */ - src_set_alignment(&source_c->stream, &sink_c->stream); - - ret = src_check_buffer_sizes(dev, cd, &source_c->stream, &sink_c->stream); - if (ret < 0) - goto out; + src_set_alignment(source, sink); #if CONFIG_IPC_MAJOR_4 switch (cd->ipc_config.base.audio_fmt.depth) { @@ -932,8 +868,8 @@ static int src_prepare_general(struct processing_module *mod) } #elif CONFIG_IPC_MAJOR_3 /* get source/sink data format */ - source_format = audio_stream_get_frm_fmt(&source_c->stream); - sink_format = audio_stream_get_frm_fmt(&sink_c->stream); + source_format = source_get_frm_fmt(source); + sink_format = sink_get_frm_fmt(sink); /* SRC supports S16_LE, S24_4LE and S32_LE formats */ if (source_format != sink_format) { @@ -973,9 +909,6 @@ static int src_prepare_general(struct processing_module *mod) if (ret < 0) comp_set_state(dev, COMP_TRIGGER_RESET); - buffer_release(sink_c); - buffer_release(source_c); - return ret; } @@ -1036,46 +969,44 @@ static int src_init(struct processing_module *mod) return 0; } -static int src_prepare(struct processing_module *mod) +static int src_prepare(struct processing_module *mod, + struct sof_source __sparse_cache **sources, int num_of_sources, + struct sof_sink __sparse_cache **sinks, int num_of_sinks) { int ret; comp_info(mod->dev, "src_prepare()"); - ret = src_params_general(mod); + if (num_of_sources != 1 || num_of_sinks != 1) + return -EINVAL; + + ret = src_params_general(mod, sources[0], sinks[0]); if (ret < 0) return ret; - return src_prepare_general(mod); + return src_prepare_general(mod, sources[0], sinks[0]); } static int src_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 __sparse_cache **sources, int num_of_sources, + struct sof_sink __sparse_cache **sinks, int num_of_sinks) { struct comp_data *cd = module_get_private_data(mod); struct comp_dev *dev = mod->dev; - /* src component needs 1 source and 1 sink buffer */ - struct audio_stream __sparse_cache *source_c = input_buffers[0].data; - struct audio_stream __sparse_cache *sink_c = output_buffers[0].data; - int consumed = 0; - int produced = 0; int ret; comp_dbg(dev, "src_process()"); - ret = src_get_copy_limits(cd, source_c, sink_c); + /* src component needs 1 source and 1 sink */ + ret = src_get_copy_limits(cd, sources[0], sinks[0]); if (ret) { comp_dbg(dev, "No data to process."); return 0; } - cd->src_func(dev, cd, source_c, sink_c, &consumed, &produced); - src_update_buffer_position(input_buffers, output_buffers, &consumed, &produced); - - comp_dbg(dev, "src_process(), consumed = %u, produced = %u", consumed, produced); + ret = cd->src_func(cd, sources[0], sinks[0]); - return 0; + return ret; } static int src_set_config(struct processing_module *mod, uint32_t config_id, @@ -1120,7 +1051,7 @@ static int src_free(struct processing_module *mod) static struct module_interface src_interface = { .init = src_init, .prepare = src_prepare, - .process_audio_stream = src_process, + .process = src_process, .set_configuration = src_set_config, .get_configuration = src_get_config, .reset = src_reset,