diff --git a/src/audio/selector/selector.c b/src/audio/selector/selector.c index 3383b211dbb9..0b9a0df55d5d 100644 --- a/src/audio/selector/selector.c +++ b/src/audio/selector/selector.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -450,9 +451,9 @@ static int selector_copy(struct comp_dev *dev) { struct comp_data *cd = comp_get_drvdata(dev); struct comp_buffer *sink, *source; - uint32_t frames; - uint32_t source_bytes; - uint32_t sink_bytes; + struct sof_source *src; + struct sof_sink *snk; + size_t frames; comp_dbg(dev, "entry"); @@ -460,26 +461,22 @@ static int selector_copy(struct comp_dev *dev) source = comp_dev_get_first_data_producer(dev); sink = comp_dev_get_first_data_consumer(dev); - if (!audio_stream_get_avail(&source->stream)) - return PPL_STATUS_PATH_STOP; + src = audio_buffer_get_source(&source->audio_buffer); + snk = audio_buffer_get_sink(&sink->audio_buffer); - frames = audio_stream_avail_frames(&source->stream, &sink->stream); - source_bytes = frames * audio_stream_frame_bytes(&source->stream); - sink_bytes = frames * audio_stream_frame_bytes(&sink->stream); + if (!source_get_data_available(src)) + return PPL_STATUS_PATH_STOP; - comp_dbg(dev, "source_bytes = 0x%x, sink_bytes = 0x%x", - source_bytes, sink_bytes); + frames = MIN(source_get_data_frames_available(src), + sink_get_free_frames(snk)); - /* copy selected channels from in to out */ - buffer_stream_invalidate(source, source_bytes); - cd->sel_func(dev, &sink->stream, &source->stream, frames); - buffer_stream_writeback(sink, sink_bytes); + comp_dbg(dev, "frames = 0x%zx", frames); - /* calculate new free and available */ - comp_update_buffer_produce(sink, sink_bytes); - comp_update_buffer_consume(source, source_bytes); + if (!frames) + return 0; - return 0; + /* copy selected channels from in to out */ + return cd->sel_func(dev, snk, src, frames); } /** @@ -1021,15 +1018,11 @@ static int selector_find_coefficients(struct processing_module *mod) * \return Error code. */ static int selector_process(struct processing_module *mod, - struct input_stream_buffer *input_buffers, - int num_input_buffers, - struct output_stream_buffer *output_buffers, - int num_output_buffers) + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) { - struct audio_stream *source; - struct audio_stream *sink; struct comp_data *cd = module_get_private_data(mod); - uint32_t avail_frames = input_buffers[0].size; + size_t frames; int ret; comp_dbg(mod->dev, "entry"); @@ -1041,19 +1034,17 @@ static int selector_process(struct processing_module *mod, return ret; } - if (cd->passthrough) { - source = input_buffers->data; - sink = output_buffers->data; - audio_stream_copy(source, 0, sink, 0, avail_frames * cd->config.in_channels_count); - module_update_buffer_position(input_buffers, output_buffers, avail_frames); + frames = MIN(source_get_data_frames_available(sources[0]), + sink_get_free_frames(sinks[0])); + if (!frames) return 0; - } - if (avail_frames) - /* copy selected channels from in to out */ - cd->sel_func(mod, input_buffers, output_buffers, avail_frames); + if (cd->passthrough) + return source_to_sink_copy(sources[0], sinks[0], false, + frames * source_get_frame_bytes(sources[0])); - return 0; + /* copy selected channels from in to out */ + return cd->sel_func(mod, sources[0], sinks[0], frames); } /** @@ -1157,7 +1148,7 @@ static int selector_reset(struct processing_module *mod) static const struct module_interface selector_interface = { .init = selector_init, .prepare = selector_prepare, - .process_audio_stream = selector_process, + .process = selector_process, .set_configuration = selector_set_config, .get_configuration = selector_get_config, .reset = selector_reset, diff --git a/src/audio/selector/selector_generic.c b/src/audio/selector/selector_generic.c index 5b4d8d8f5edd..2e580306f54b 100644 --- a/src/audio/selector/selector_generic.c +++ b/src/audio/selector/selector_generic.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -21,9 +22,6 @@ LOG_MODULE_DECLARE(selector, CONFIG_SOF_LOG_LEVEL); -#define BYTES_TO_S16_SAMPLES 1 -#define BYTES_TO_S32_SAMPLES 2 - #if CONFIG_IPC_MAJOR_3 #if CONFIG_FORMAT_S16LE /** @@ -33,37 +31,51 @@ LOG_MODULE_DECLARE(selector, CONFIG_SOF_LOG_LEVEL); * \param[in,out] source Source buffer. * \param[in] frames Number of frames to process. */ -static void sel_s16le_1ch(struct comp_dev *dev, struct audio_stream *sink, - const struct audio_stream *source, uint32_t frames) +static int sel_s16le_1ch(struct comp_dev *dev, struct sof_sink *sink, struct sof_source *source, + size_t frames) { struct comp_data *cd = comp_get_drvdata(dev); - int16_t *src = audio_stream_get_rptr(source); - int16_t *dest = audio_stream_get_wptr(sink); - int16_t *src_ch; - int nmax; - int i; - int n; - int processed = 0; - const int source_frame_bytes = audio_stream_frame_bytes(source); - const unsigned int nch = audio_stream_get_channels(source); const unsigned int sel_channel = cd->config.sel_channel; /* 0 to nch - 1 */ + const int source_frame_bytes = source_get_frame_bytes(source); + const unsigned int nch = source_get_channels(source); + const int16_t *src, *src_start, *src_ch; + int16_t *dst, *dst_start; + int src_samples, dst_samples; + size_t i, n, processed = 0; + int ret; + + ret = source_get_data_s16(source, frames * source_frame_bytes, &src, &src_start, + &src_samples); + if (ret) + return ret; + + ret = sink_get_buffer_s16(sink, frames * sizeof(*dst), &dst, &dst_start, &dst_samples); + if (ret) { + source_release_data(source, 0); + return ret; + } while (processed < frames) { n = frames - processed; - nmax = audio_stream_bytes_without_wrap(source, src) / source_frame_bytes; - n = MIN(n, nmax); - nmax = audio_stream_bytes_without_wrap(sink, dest) >> BYTES_TO_S16_SAMPLES; - n = MIN(n, nmax); + n = MIN(n, (cir_buf_samples_to_wrap_s16(src, src_start, src_samples) / nch)); + n = MIN(n, cir_buf_samples_to_wrap_s16(dst, dst_start, dst_samples)); src_ch = src + sel_channel; for (i = 0; i < n; i++) { - *dest = *src_ch; + *dst = *src_ch; src_ch += nch; - dest++; + dst++; } - src = audio_stream_wrap(source, src + nch * n); - dest = audio_stream_wrap(sink, dest); + + src += n * nch; + if (src >= src_start + src_samples) + src = src_start; + if (dst >= dst_start + dst_samples) + dst = dst_start; processed += n; } + + return release_source_and_commit_sink(source, frames * source_frame_bytes, + sink, frames * sizeof(*dst)); } /** @@ -73,27 +85,43 @@ static void sel_s16le_1ch(struct comp_dev *dev, struct audio_stream *sink, * \param[in,out] source Source buffer. * \param[in] frames Number of frames to process. */ -static void sel_s16le_nch(struct comp_dev *dev, struct audio_stream *sink, - const struct audio_stream *source, uint32_t frames) +static int sel_s16le_nch(struct comp_dev *dev, struct sof_sink *sink, + struct sof_source *source, size_t frames) { - int8_t *src = audio_stream_get_rptr(source); - int8_t *dst = audio_stream_get_wptr(sink); - int bmax; - int b; - int bytes_copied = 0; - const int bytes_total = frames * audio_stream_frame_bytes(source); - - while (bytes_copied < bytes_total) { - b = bytes_total - bytes_copied; - bmax = audio_stream_bytes_without_wrap(source, src); - b = MIN(b, bmax); - bmax = audio_stream_bytes_without_wrap(sink, dst); - b = MIN(b, bmax); - memcpy_s(dst, b, src, b); - src = audio_stream_wrap(source, src + b); - dst = audio_stream_wrap(sink, dst + b); - bytes_copied += b; + const size_t frame_bytes = source_get_frame_bytes(source); + const unsigned int nch = source_get_channels(source); + const int16_t *src, *src_start; + int16_t *dst, *dst_start; + int src_samples, dst_samples; + size_t n, processed = 0; + int ret; + + ret = source_get_data_s16(source, frames * frame_bytes, &src, &src_start, &src_samples); + if (ret) + return ret; + + ret = sink_get_buffer_s16(sink, frames * frame_bytes, &dst, &dst_start, &dst_samples); + if (ret) { + source_release_data(source, 0); + return ret; } + + while (processed < frames) { + n = frames - processed; + n = MIN(n, (cir_buf_samples_to_wrap_s16(src, src_start, src_samples) / nch)); + n = MIN(n, (cir_buf_samples_to_wrap_s16(dst, dst_start, dst_samples) / nch)); + memcpy_s(dst, n * frame_bytes, src, n * frame_bytes); + src += n * nch; + dst += n * nch; + if (src >= src_start + src_samples) + src = src_start; + if (dst >= dst_start + dst_samples) + dst = dst_start; + processed += n; + } + + return release_source_and_commit_sink(source, frames * frame_bytes, + sink, frames * frame_bytes); } #endif /* CONFIG_FORMAT_S16LE */ @@ -105,37 +133,50 @@ static void sel_s16le_nch(struct comp_dev *dev, struct audio_stream *sink, * \param[in,out] source Source buffer. * \param[in] frames Number of frames to process. */ -static void sel_s32le_1ch(struct comp_dev *dev, struct audio_stream *sink, - const struct audio_stream *source, uint32_t frames) +static int sel_s32le_1ch(struct comp_dev *dev, struct sof_sink *sink, struct sof_source *source, + size_t frames) { struct comp_data *cd = comp_get_drvdata(dev); - int32_t *src = audio_stream_get_rptr(source); - int32_t *dest = audio_stream_get_wptr(sink); - int32_t *src_ch; - int nmax; - int i; - int n; - int processed = 0; - const int source_frame_bytes = audio_stream_frame_bytes(source); - const unsigned int nch = audio_stream_get_channels(source); const unsigned int sel_channel = cd->config.sel_channel; /* 0 to nch - 1 */ + const int source_frame_bytes = source_get_frame_bytes(source); + const unsigned int nch = source_get_channels(source); + const int32_t *src, *src_ch, *src_start; + int32_t *dst, *dst_start; + int src_samples, dst_samples; + size_t i, n, processed = 0; + int ret; + + ret = source_get_data_s32(source, frames * source_frame_bytes, &src, &src_start, + &src_samples); + if (ret) + return ret; + + ret = sink_get_buffer_s32(sink, frames * sizeof(int32_t), &dst, &dst_start, &dst_samples); + if (ret) { + source_release_data(source, 0); + return ret; + } while (processed < frames) { n = frames - processed; - nmax = audio_stream_bytes_without_wrap(source, src) / source_frame_bytes; - n = MIN(n, nmax); - nmax = audio_stream_bytes_without_wrap(sink, dest) >> BYTES_TO_S32_SAMPLES; - n = MIN(n, nmax); + n = MIN(n, cir_buf_samples_to_wrap_s32(src, src_start, src_samples) / nch); + n = MIN(n, cir_buf_samples_to_wrap_s32(dst, dst_start, dst_samples)); src_ch = src + sel_channel; for (i = 0; i < n; i++) { - *dest = *src_ch; + *dst = *src_ch; src_ch += nch; - dest++; + dst++; } - src = audio_stream_wrap(source, src + nch * n); - dest = audio_stream_wrap(sink, dest); + src += nch * n; + if (src >= src_start + src_samples) + src = src_start; + if (dst >= dst_start + dst_samples) + dst = dst_start; processed += n; } + + return release_source_and_commit_sink(source, frames * source_frame_bytes, + sink, frames * source_frame_bytes); } /** @@ -145,27 +186,45 @@ static void sel_s32le_1ch(struct comp_dev *dev, struct audio_stream *sink, * \param[in,out] source Source buffer. * \param[in] frames Number of frames to process. */ -static void sel_s32le_nch(struct comp_dev *dev, struct audio_stream *sink, - const struct audio_stream *source, uint32_t frames) +static int sel_s32le_nch(struct comp_dev *dev, struct sof_sink *sink, struct sof_source *source, + size_t frames) { - int8_t *src = audio_stream_get_rptr(source); - int8_t *dst = audio_stream_get_wptr(sink); - int bmax; - int b; - int bytes_copied = 0; - const int bytes_total = frames * audio_stream_frame_bytes(source); - - while (bytes_copied < bytes_total) { - b = bytes_total - bytes_copied; - bmax = audio_stream_bytes_without_wrap(source, src); - b = MIN(b, bmax); - bmax = audio_stream_bytes_without_wrap(sink, dst); - b = MIN(b, bmax); - memcpy_s(dst, b, src, b); - src = audio_stream_wrap(source, src + b); - dst = audio_stream_wrap(sink, dst + b); - bytes_copied += b; + const int frame_bytes = source_get_frame_bytes(source); + const unsigned int nch = source_get_channels(source); + const int32_t *src, *src_start; + int32_t *dst, *dst_start; + int src_samples, dst_samples; + size_t n, processed = 0; + int ret; + + ret = source_get_data_s32(source, frames * frame_bytes, + &src, &src_start, &src_samples); + if (ret) + return ret; + + ret = sink_get_buffer_s32(sink, frames * frame_bytes, + &dst, &dst_start, &dst_samples); + if (ret) { + source_release_data(source, 0); + return ret; } + + while (processed < frames) { + n = frames - processed; + n = MIN(n, cir_buf_samples_to_wrap_s32(src, src_start, src_samples) / nch); + n = MIN(n, cir_buf_samples_to_wrap_s32(dst, dst_start, dst_samples) / nch); + memcpy_s(dst, n * frame_bytes, src, n * frame_bytes); + src += n * nch; + dst += n * nch; + if (src >= src_start + src_samples) + src = src_start; + if (dst >= dst_start + dst_samples) + dst = dst_start; + processed += n; + } + + return release_source_and_commit_sink(source, frames * frame_bytes, + sink, frames * frame_bytes); } #endif /* CONFIG_FORMAT_S24LE || CONFIG_FORMAT_S32LE */ @@ -180,7 +239,7 @@ static void sel_s32le_nch(struct comp_dev *dev, struct audio_stream *sink, * \param[in] coeffs_config IPC4 micsel config with Q10 coefficients. */ static void process_frame_s16le(int16_t dst[], int dst_channels, - int16_t src[], int src_channels, + const int16_t src[], int src_channels, struct ipc4_selector_coeffs_config *coeffs_config) { int32_t accum; @@ -203,41 +262,53 @@ static void process_frame_s16le(int16_t dst[], int dst_channels, * \param[in,out] bsink Sink buffer. * \param[in] frames Number of frames to process. */ -static void sel_s16le(struct processing_module *mod, struct input_stream_buffer *bsource, - struct output_stream_buffer *bsink, uint32_t frames) +static int sel_s16le(struct processing_module *mod, struct sof_source *source, + struct sof_sink *sink, size_t frames) { struct comp_data *cd = module_get_private_data(mod); - struct audio_stream *source = bsource->data; - struct audio_stream *sink = bsink->data; - int16_t *src = audio_stream_get_rptr(source); - int16_t *dest = audio_stream_get_wptr(sink); - int nmax; - int i; - int n; - int processed = 0; - int source_frame_bytes = audio_stream_frame_bytes(source); - int sink_frame_bytes = audio_stream_frame_bytes(sink); - int n_chan_source = MIN(SEL_SOURCE_CHANNELS_MAX, audio_stream_get_channels(source)); - int n_chan_sink = MIN(SEL_SINK_CHANNELS_MAX, audio_stream_get_channels(sink)); + const int n_chan_source = MIN(SEL_SOURCE_CHANNELS_MAX, (int)source_get_channels(source)); + const int n_chan_sink = MIN(SEL_SINK_CHANNELS_MAX, (int)sink_get_channels(sink)); + const int source_frame_bytes = source_get_frame_bytes(source); + const unsigned int src_channels = source_get_channels(source); + const unsigned int dst_channels = sink_get_channels(sink); + const int sink_frame_bytes = sink_get_frame_bytes(sink); + const int16_t *src, *src_start; + int16_t *dst, *dst_start; + int src_samples, dst_samples; + size_t i, n, processed = 0; + int ret; + + ret = source_get_data_s16(source, frames * source_frame_bytes, + &src, &src_start, &src_samples); + if (ret) + return ret; + + ret = sink_get_buffer_s16(sink, frames * sink_frame_bytes, + &dst, &dst_start, &dst_samples); + if (ret) { + source_release_data(source, 0); + return ret; + } while (processed < frames) { n = frames - processed; - nmax = audio_stream_bytes_without_wrap(source, src) / source_frame_bytes; - n = MIN(n, nmax); - nmax = audio_stream_bytes_without_wrap(sink, dest) / sink_frame_bytes; - n = MIN(n, nmax); + n = MIN(n, cir_buf_samples_to_wrap_s16(src, src_start, src_samples) / src_channels); + n = MIN(n, cir_buf_samples_to_wrap_s16(dst, dst_start, dst_samples) / dst_channels); for (i = 0; i < n; i++) { - process_frame_s16le(dest, n_chan_sink, src, n_chan_source, + process_frame_s16le(dst, n_chan_sink, src, n_chan_source, &cd->coeffs_config); - src += audio_stream_get_channels(source); - dest += audio_stream_get_channels(sink); + src += src_channels; + dst += dst_channels; } - src = audio_stream_wrap(source, src); - dest = audio_stream_wrap(sink, dest); + if (src >= src_start + src_samples) + src = src_start; + if (dst >= dst_start + dst_samples) + dst = dst_start; processed += n; } - module_update_buffer_position(bsource, bsink, frames); + return release_source_and_commit_sink(source, frames * source_frame_bytes, + sink, frames * sink_frame_bytes); } #endif /* CONFIG_FORMAT_S16LE */ @@ -251,7 +322,7 @@ static void sel_s16le(struct processing_module *mod, struct input_stream_buffer * \param[in] coeffs_config IPC4 micsel config with Q10 coefficients. */ static void process_frame_s24le(int32_t dst[], int dst_channels, - int32_t src[], int src_channels, + const int32_t src[], int src_channels, struct ipc4_selector_coeffs_config *coeffs_config) { int64_t accum; @@ -276,41 +347,53 @@ static void process_frame_s24le(int32_t dst[], int dst_channels, * \param[in,out] bsink Sink buffer. * \param[in] frames Number of frames to process. */ -static void sel_s24le(struct processing_module *mod, struct input_stream_buffer *bsource, - struct output_stream_buffer *bsink, uint32_t frames) +static int sel_s24le(struct processing_module *mod, struct sof_source *source, + struct sof_sink *sink, size_t frames) { struct comp_data *cd = module_get_private_data(mod); - struct audio_stream *source = bsource->data; - struct audio_stream *sink = bsink->data; - int32_t *src = audio_stream_get_rptr(source); - int32_t *dest = audio_stream_get_wptr(sink); - int nmax; - int i; - int n; - int processed = 0; - int source_frame_bytes = audio_stream_frame_bytes(source); - int sink_frame_bytes = audio_stream_frame_bytes(sink); - int n_chan_source = MIN(SEL_SOURCE_CHANNELS_MAX, audio_stream_get_channels(source)); - int n_chan_sink = MIN(SEL_SINK_CHANNELS_MAX, audio_stream_get_channels(sink)); + const int n_chan_source = MIN(SEL_SOURCE_CHANNELS_MAX, (int)source_get_channels(source)); + const int n_chan_sink = MIN(SEL_SINK_CHANNELS_MAX, (int)sink_get_channels(sink)); + const int source_frame_bytes = source_get_frame_bytes(source); + const unsigned int src_channels = source_get_channels(source); + const unsigned int dst_channels = sink_get_channels(sink); + const int sink_frame_bytes = sink_get_frame_bytes(sink); + const int32_t *src, *src_start; + int32_t *dst, *dst_start; + int src_samples, dst_samples; + size_t i, n, processed = 0; + int ret; + + ret = source_get_data_s32(source, frames * source_frame_bytes, + &src, &src_start, &src_samples); + if (ret) + return ret; + + ret = sink_get_buffer_s32(sink, frames * sink_frame_bytes, + &dst, &dst_start, &dst_samples); + if (ret) { + source_release_data(source, 0); + return ret; + } while (processed < frames) { n = frames - processed; - nmax = audio_stream_bytes_without_wrap(source, src) / source_frame_bytes; - n = MIN(n, nmax); - nmax = audio_stream_bytes_without_wrap(sink, dest) / sink_frame_bytes; - n = MIN(n, nmax); + n = MIN(n, cir_buf_samples_to_wrap_s32(src, src_start, src_samples) / src_channels); + n = MIN(n, cir_buf_samples_to_wrap_s32(dst, dst_start, dst_samples) / dst_channels); for (i = 0; i < n; i++) { - process_frame_s24le(dest, n_chan_sink, src, n_chan_source, + process_frame_s24le(dst, n_chan_sink, src, n_chan_source, &cd->coeffs_config); - src += audio_stream_get_channels(source); - dest += audio_stream_get_channels(sink); + src += src_channels; + dst += dst_channels; } - src = audio_stream_wrap(source, src); - dest = audio_stream_wrap(sink, dest); + if (src >= src_start + src_samples) + src = src_start; + if (dst >= dst_start + dst_samples) + dst = dst_start; processed += n; } - module_update_buffer_position(bsource, bsink, frames); + return release_source_and_commit_sink(source, frames * source_frame_bytes, + sink, frames * sink_frame_bytes); } #endif /* CONFIG_FORMAT_S24LE */ @@ -324,7 +407,7 @@ static void sel_s24le(struct processing_module *mod, struct input_stream_buffer * \param[in] coeffs_config IPC4 micsel config with Q10 coefficients. */ static void process_frame_s32le(int32_t dst[], int dst_channels, - int32_t src[], int src_channels, + const int32_t src[], int src_channels, struct ipc4_selector_coeffs_config *coeffs_config) { int64_t accum; @@ -347,41 +430,53 @@ static void process_frame_s32le(int32_t dst[], int dst_channels, * \param[in,out] bsink Sink buffer. * \param[in] frames Number of frames to process. */ -static void sel_s32le(struct processing_module *mod, struct input_stream_buffer *bsource, - struct output_stream_buffer *bsink, uint32_t frames) +static int sel_s32le(struct processing_module *mod, struct sof_source *source, + struct sof_sink *sink, size_t frames) { struct comp_data *cd = module_get_private_data(mod); - struct audio_stream *source = bsource->data; - struct audio_stream *sink = bsink->data; - int32_t *src = audio_stream_get_rptr(source); - int32_t *dest = audio_stream_get_wptr(sink); - int nmax; - int i; - int n; - int processed = 0; - int source_frame_bytes = audio_stream_frame_bytes(source); - int sink_frame_bytes = audio_stream_frame_bytes(sink); - int n_chan_source = MIN(SEL_SOURCE_CHANNELS_MAX, audio_stream_get_channels(source)); - int n_chan_sink = MIN(SEL_SINK_CHANNELS_MAX, audio_stream_get_channels(sink)); + const unsigned int n_chan_source = MIN(SEL_SOURCE_CHANNELS_MAX, source_get_channels(source)); + const unsigned int n_chan_sink = MIN(SEL_SINK_CHANNELS_MAX, sink_get_channels(sink)); + const int source_frame_bytes = source_get_frame_bytes(source); + const unsigned int src_channels = source_get_channels(source); + const unsigned int dst_channels = sink_get_channels(sink); + const int sink_frame_bytes = sink_get_frame_bytes(sink); + const int32_t *src, *src_start; + int32_t *dst, *dst_start; + int src_samples, dst_samples; + size_t i, n, processed = 0; + int ret; + + ret = source_get_data_s32(source, frames * source_frame_bytes, + &src, &src_start, &src_samples); + if (ret) + return ret; + + ret = sink_get_buffer_s32(sink, frames * sink_frame_bytes, + &dst, &dst_start, &dst_samples); + if (ret) { + source_release_data(source, 0); + return ret; + } while (processed < frames) { n = frames - processed; - nmax = audio_stream_bytes_without_wrap(source, src) / source_frame_bytes; - n = MIN(n, nmax); - nmax = audio_stream_bytes_without_wrap(sink, dest) / sink_frame_bytes; - n = MIN(n, nmax); + n = MIN(n, cir_buf_samples_to_wrap_s32(src, src_start, src_samples) / src_channels); + n = MIN(n, cir_buf_samples_to_wrap_s32(dst, dst_start, dst_samples) / dst_channels); for (i = 0; i < n; i++) { - process_frame_s32le(dest, n_chan_sink, src, n_chan_source, + process_frame_s32le(dst, n_chan_sink, src, n_chan_source, &cd->coeffs_config); - src += audio_stream_get_channels(source); - dest += audio_stream_get_channels(sink); + src += src_channels; + dst += dst_channels; } - src = audio_stream_wrap(source, src); - dest = audio_stream_wrap(sink, dest); + if (src >= src_start + src_samples) + src = src_start; + if (dst >= dst_start + dst_samples) + dst = dst_start; processed += n; } - module_update_buffer_position(bsource, bsink, frames); + return release_source_and_commit_sink(source, frames * source_frame_bytes, + sink, frames * sink_frame_bytes); } #endif /* CONFIG_FORMAT_S32LE */ #endif diff --git a/src/audio/sink_source_utils.c b/src/audio/sink_source_utils.c index 1fb86df386c2..9b01753f8670 100644 --- a/src/audio/sink_source_utils.c +++ b/src/audio/sink_source_utils.c @@ -13,6 +13,19 @@ #include #include +int release_source_and_commit_sink(struct sof_source *source, size_t free_size, + struct sof_sink *sink, size_t commit_size) +{ + int src_ret; + int sink_ret; + + src_ret = source_release_data(source, free_size); + sink_ret = sink_commit_buffer(sink, (src_ret ? 0 : commit_size)); + + return src_ret ? src_ret : sink_ret; +} +EXPORT_SYMBOL(release_source_and_commit_sink); + int source_to_sink_copy(struct sof_source *source, struct sof_sink *sink, bool free, size_t size) { diff --git a/src/include/sof/audio/selector.h b/src/include/sof/audio/selector.h index fd413badab7f..6d764dbe67c7 100644 --- a/src/include/sof/audio/selector.h +++ b/src/include/sof/audio/selector.h @@ -57,8 +57,8 @@ struct comp_dev; #if CONFIG_IPC_MAJOR_4 /** \brief selector processing function interface */ -typedef void (*sel_func)(struct processing_module *mod, struct input_stream_buffer *bsource, - struct output_stream_buffer *bsink, uint32_t frames); +typedef int (*sel_func)(struct processing_module *mod, struct sof_source *source, + struct sof_sink *sink, size_t frames); /** \brief IPC4 configuration IDs for selector. */ enum ipc4_selector_config_id { @@ -109,8 +109,8 @@ struct sof_selector_avs_ipc4_config { }; #else -typedef void (*sel_func)(struct comp_dev *dev, struct audio_stream *sink, - const struct audio_stream *source, uint32_t frames); +typedef int (*sel_func)(struct comp_dev *dev, struct sof_sink *sink, + struct sof_source *source, size_t frames); #endif /** \brief Selector component private data. */ diff --git a/src/include/sof/audio/sink_source_utils.h b/src/include/sof/audio/sink_source_utils.h index 2d31666ac383..5e0e85ba73ce 100644 --- a/src/include/sof/audio/sink_source_utils.h +++ b/src/include/sof/audio/sink_source_utils.h @@ -11,6 +11,23 @@ #include #include +/** + * release processed data from source and commit produced data to sink + * + * @param source the data source to release data from + * @param free_size number of bytes to be released (freed) from the source + * @param sink the data target to commit data to + * @param commit_size number of bytes to be committed to the sink + * + * @return 0 on success; + * on error, the error code returned by source_release_data() takes + * precedence, otherwise the error code returned by sink_commit_buffer() + * is returned. The sink is always committed regardless of the source + * release result. + */ +int release_source_and_commit_sink(struct sof_source *source, size_t free_size, + struct sof_sink *sink, size_t commit_size); + /** * copy bytes from source to sink * diff --git a/test/cmocka/src/audio/selector/selector_test.c b/test/cmocka/src/audio/selector/selector_test.c index 4bcc8df7fea5..1f537692c8ff 100644 --- a/test/cmocka/src/audio/selector/selector_test.c +++ b/test/cmocka/src/audio/selector/selector_test.c @@ -111,10 +111,6 @@ struct sel_test_state { struct processing_module *mod; struct comp_buffer *sink; struct comp_buffer *source; - struct input_stream_buffer *input; - struct output_stream_buffer *output; - size_t size; - uint32_t channels; void (*verify)(struct processing_module *mod, struct audio_stream *sink, struct audio_stream *source); }; @@ -171,7 +167,6 @@ static int setup(void **state) /* allocate new sink buffer */ size = parameters->frames * get_frame_bytes(parameters->sink_format, parameters->out_channels) * parameters->buffer_size_ms; - sel_state->size = size; sel_state->sink = create_test_sink(dev, 0, parameters->sink_format, parameters->out_channels, size); @@ -182,11 +177,6 @@ static int setup(void **state) sel_state->source = create_test_source(dev, 0, parameters->source_format, parameters->in_channels, size); - sel_state->input = test_malloc(sizeof(struct input_stream_buffer)); - sel_state->input->data = &sel_state->source->stream; - sel_state->output = test_malloc(sizeof(struct output_stream_buffer)); - sel_state->output->data = &sel_state->sink->stream; - /* assigns verification function */ sel_state->verify = parameters->verify; @@ -205,8 +195,6 @@ static int teardown(void **state) test_free(cd); test_free(sel_state->mod->dev); test_free(sel_state->mod); - test_free(sel_state->input); - test_free(sel_state->output); free_test_sink(sel_state->sink); free_test_source(sel_state->source); test_free(sel_state); @@ -418,6 +406,9 @@ static void verify_s32le_4ch_to_4ch(struct processing_module *mod, static void test_audio_sel(void **state) { struct sel_test_state *sel_state = *state; + struct sof_source *source = audio_buffer_get_source(&sel_state->source->audio_buffer); + struct sof_sink *sink = audio_buffer_get_sink(&sel_state->sink->audio_buffer); + int ret; #if CONFIG_IPC_MAJOR_3 struct comp_data *cd = comp_get_drvdata(sel_state->dev); #else @@ -447,17 +438,14 @@ static void test_audio_sel(void **state) } #if CONFIG_IPC_MAJOR_3 - cd->sel_func(sel_state->dev, &sel_state->sink->stream, &sel_state->source->stream, - sel_state->dev->frames); + ret = cd->sel_func(sel_state->dev, sink, source, sel_state->dev->frames); + assert_int_equal(ret, 0); sel_state->verify(sel_state->dev, &sel_state->sink->stream, &sel_state->source->stream); #else - sel_state->input->consumed = 0; - sel_state->output->size = 0; - - cd->sel_func(mod, sel_state->input, sel_state->output, - mod->dev->frames); + ret = cd->sel_func(mod, source, sink, mod->dev->frames); + assert_int_equal(ret, 0); sel_state->verify(mod, &sel_state->sink->stream, &sel_state->source->stream); #endif