diff --git a/src/audio/CMakeLists.txt b/src/audio/CMakeLists.txt index 9a6a0479ee58..9ca9866da07d 100644 --- a/src/audio/CMakeLists.txt +++ b/src/audio/CMakeLists.txt @@ -204,7 +204,7 @@ set(mixer_sources mixer.c) set(src_sources src/src.c src/src_generic.c) set(asrc_sources asrc/asrc.c asrc/asrc_farrow.c asrc/asrc_farrow_generic.c) set(eq-fir_sources eq_fir/eq_fir.c eq_fir/eq_fir_generic.c) -set(eq-iir_sources eq_iir/eq_iir.c) +set(eq-iir_sources module_adapter/module_adapter.c module_adapter/module/generic.c eq_iir/eq_iir.c) set(dcblock_sources dcblock/dcblock.c dcblock/dcblock_generic.c) set(crossover_sources crossover/crossover.c crossover/crossover_generic.c) set(tdfb_sources tdfb/tdfb.c tdfb/tdfb_generic.c tdfb/tdfb_direction.c) diff --git a/src/audio/Kconfig b/src/audio/Kconfig index f7de80aa50de..9e68c827ff8c 100644 --- a/src/audio/Kconfig +++ b/src/audio/Kconfig @@ -133,6 +133,7 @@ config COMP_IIR bool "IIR component" select COMP_BLOB default y + depends on COMP_MODULE_ADAPTER select MATH_IIR_DF2T help Select for IIR component diff --git a/src/audio/data_blob.c b/src/audio/data_blob.c index 67d924d88d86..a2bedeecbfdb 100644 --- a/src/audio/data_blob.c +++ b/src/audio/data_blob.c @@ -4,6 +4,7 @@ // // Author: Jyri Sarha +#include #include #include #include @@ -148,6 +149,129 @@ int comp_init_data_blob(struct comp_data_blob_handler *blob_handler, return 0; } +int comp_data_blob_set(struct comp_data_blob_handler *blob_handler, + enum module_cfg_fragment_position pos, uint32_t data_offset_size, + const uint8_t *fragment, size_t fragment_size) +{ + int ret; + + if (!blob_handler) + return -EINVAL; + + comp_dbg(blob_handler->dev, "comp_data_blob_set_cmd() pos = %d, fragment size = %d", + pos, fragment_size); + + /* Check that there is no work-in-progress previous request */ + if (blob_handler->data_new && + (pos == MODULE_CFG_FRAGMENT_FIRST || pos == MODULE_CFG_FRAGMENT_SINGLE)) { + comp_err(blob_handler->dev, "comp_data_blob_set_cmd(), busy with previous request"); + return -EBUSY; + } + + /* In single blob mode the component can not be reconfigured if the component is active. + */ + if (blob_handler->single_blob && blob_handler->dev->state == COMP_STATE_ACTIVE) { + comp_err(blob_handler->dev, "comp_data_blob_set_cmd(), on the fly updates forbidden in single blob mode"); + return -EBUSY; + } + + /* in case when the current package is the first, we should allocate + * memory for whole model data + */ + if (pos == MODULE_CFG_FRAGMENT_FIRST || pos == MODULE_CFG_FRAGMENT_SINGLE) { + /* in case when required model size is equal to zero we do not + * allocate memory and should just return 0. + * + * Set cmd with cdata->data->size equal to 0 is possible in + * following situation: + * 1. At first boot and topology parsing stage, the driver will + * read all initial values of DSP kcontrols via IPC. Driver send + * get_model() cmd to components. If we do not initialize + * component earlier driver will get "model" with size 0. + * 2. When resuming from runtime suspended, the driver will + * restore all pipelines and kcontrols, for the tlv binary + * kcontrols, it will call the set_model() with the cached value + * and size (0 if it is not updated by any actual end user + * sof-ctl settings) - basically driver will send set_model() + * command with size equal to 0. + */ + if (!fragment_size) + return 0; + + if (blob_handler->single_blob) { + if (data_offset_size != blob_handler->data_size) { + blob_handler->free(blob_handler->data); + blob_handler->data = NULL; + } else { + blob_handler->data_new = blob_handler->data; + blob_handler->data = NULL; + } + } + + if (!blob_handler->data_new) { + blob_handler->data_new = blob_handler->alloc(data_offset_size); + if (!blob_handler->data_new) { + comp_err(blob_handler->dev, "comp_data_blob_set_cmd(): blob_handler->data_new allocation failed."); + return -ENOMEM; + } + } + + blob_handler->new_data_size = data_offset_size; + blob_handler->data_ready = false; + blob_handler->data_pos = 0; + } + + /* return an error in case when we do not have allocated memory for model data */ + if (!blob_handler->data_new) { + comp_err(blob_handler->dev, "comp_data_blob_set_cmd(): buffer not allocated"); + return -ENOMEM; + } + + ret = memcpy_s((char *)blob_handler->data_new + blob_handler->data_pos, + blob_handler->new_data_size - blob_handler->data_pos, + fragment, fragment_size); + if (ret) { + comp_err(blob_handler->dev, "comp_data_blob_set_cmd(): failed to copy fragment"); + return ret; + } + + blob_handler->data_pos += fragment_size; + + if (pos == MODULE_CFG_FRAGMENT_SINGLE || pos == MODULE_CFG_FRAGMENT_LAST) { + comp_dbg(blob_handler->dev, "comp_data_blob_set_cmd(): final package received"); + + /* If component state is READY we can omit old + * configuration immediately. When in playback/capture + * the new configuration presence is checked in copy(). + */ + if (blob_handler->dev->state == COMP_STATE_READY) { + blob_handler->free(blob_handler->data); + blob_handler->data = NULL; + } + + /* If there is no existing configuration the received + * can be set to current immediately. It will be + * applied in prepare() when streaming starts. + */ + if (!blob_handler->data) { + blob_handler->data = blob_handler->data_new; + blob_handler->data_size = blob_handler->new_data_size; + + blob_handler->data_new = NULL; + + /* The new configuration has been applied */ + blob_handler->data_ready = false; + blob_handler->new_data_size = 0; + blob_handler->data_pos = 0; + } else { + /* The new configuration is ready to be applied */ + blob_handler->data_ready = true; + } + } + + return 0; +} + int comp_data_blob_set_cmd(struct comp_data_blob_handler *blob_handler, struct sof_ipc_ctrl_data *cdata) { diff --git a/src/audio/eq_iir/CMakeLists.txt b/src/audio/eq_iir/CMakeLists.txt index 498946370528..5c9f73ee4e00 100644 --- a/src/audio/eq_iir/CMakeLists.txt +++ b/src/audio/eq_iir/CMakeLists.txt @@ -1,3 +1,3 @@ # SPDX-License-Identifier: BSD-3-Clause -add_local_sources(sof eq_iir.c) +add_local_sources(sof ../module_adapter/module_adapter.c ../module_adapter/module/generic.c eq_iir.c) diff --git a/src/audio/eq_iir/eq_iir.c b/src/audio/eq_iir/eq_iir.c index 704b4827a9a0..b87bdd90d43b 100644 --- a/src/audio/eq_iir/eq_iir.c +++ b/src/audio/eq_iir/eq_iir.c @@ -7,6 +7,7 @@ // Keyon Jie #include +#include #include #include #include @@ -34,8 +35,6 @@ #include #include -static const struct comp_driver comp_eq_iir; - LOG_MODULE_REGISTER(eq_iir, CONFIG_SOF_LOG_LEVEL); /* 5150c0e6-27f9-4ec8-8351-c705b642d12f */ @@ -60,11 +59,12 @@ struct comp_data { * EQ IIR algorithm code */ -static void eq_iir_s16_default(const struct comp_dev *dev, - const struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink, uint32_t frames) +static void eq_iir_s16_default(struct processing_module *mod, struct input_stream_buffer *bsource, + struct output_stream_buffer *bsink, uint32_t frames) { - struct comp_data *cd = comp_get_drvdata(dev); + struct comp_data *cd = module_get_private_data(mod); + struct audio_stream __sparse_cache *source = bsource->data; + struct audio_stream __sparse_cache *sink = bsink->data; struct iir_state_df2t *filter; int16_t *x0; int16_t *y0; @@ -80,6 +80,9 @@ static void eq_iir_s16_default(const struct comp_dev *dev, const int samples = frames * nch; int processed = 0; + module_update_processing_position(bsource, bsink, SOF_IPC_FRAME_S16_LE, + SOF_IPC_FRAME_S16_LE, samples); + x = source->r_ptr; y = sink->w_ptr; while (processed < samples) { @@ -107,11 +110,12 @@ static void eq_iir_s16_default(const struct comp_dev *dev, #if CONFIG_FORMAT_S24LE -static void eq_iir_s24_default(const struct comp_dev *dev, - const struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink, uint32_t frames) +static void eq_iir_s24_default(struct processing_module *mod, struct input_stream_buffer *bsource, + struct output_stream_buffer *bsink, uint32_t frames) { - struct comp_data *cd = comp_get_drvdata(dev); + struct comp_data *cd = module_get_private_data(mod); + struct audio_stream __sparse_cache *source = bsource->data; + struct audio_stream __sparse_cache *sink = bsink->data; struct iir_state_df2t *filter; int32_t *x0; int32_t *y0; @@ -127,6 +131,9 @@ static void eq_iir_s24_default(const struct comp_dev *dev, const int samples = frames * nch; int processed = 0; + module_update_processing_position(bsource, bsink, SOF_IPC_FRAME_S32_LE, + SOF_IPC_FRAME_S32_LE, samples); + x = source->r_ptr; y = sink->w_ptr; while (processed < samples) { @@ -154,11 +161,12 @@ static void eq_iir_s24_default(const struct comp_dev *dev, #if CONFIG_FORMAT_S32LE -static void eq_iir_s32_default(const struct comp_dev *dev, - const struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink, uint32_t frames) +static void eq_iir_s32_default(struct processing_module *mod, struct input_stream_buffer *bsource, + struct output_stream_buffer *bsink, uint32_t frames) { - struct comp_data *cd = comp_get_drvdata(dev); + struct comp_data *cd = module_get_private_data(mod); + struct audio_stream __sparse_cache *source = bsource->data; + struct audio_stream __sparse_cache *sink = bsink->data; struct iir_state_df2t *filter; int32_t *x0; int32_t *y0; @@ -174,6 +182,9 @@ static void eq_iir_s32_default(const struct comp_dev *dev, const int samples = frames * nch; int processed = 0; + module_update_processing_position(bsource, bsink, SOF_IPC_FRAME_S32_LE, + SOF_IPC_FRAME_S32_LE, samples); + x = source->r_ptr; y = sink->w_ptr; while (processed < samples) { @@ -200,11 +211,13 @@ static void eq_iir_s32_default(const struct comp_dev *dev, #endif /* CONFIG_FORMAT_S32LE */ #if CONFIG_FORMAT_S32LE && CONFIG_FORMAT_S16LE -static void eq_iir_s32_16_default(const struct comp_dev *dev, - const struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink, uint32_t frames) +static void eq_iir_s32_16_default(struct processing_module *mod, + struct input_stream_buffer *bsource, + struct output_stream_buffer *bsink, uint32_t frames) { - struct comp_data *cd = comp_get_drvdata(dev); + struct comp_data *cd = module_get_private_data(mod); + struct audio_stream __sparse_cache *source = bsource->data; + struct audio_stream __sparse_cache *sink = bsink->data; struct iir_state_df2t *filter; int32_t *x0; int16_t *y0; @@ -220,6 +233,9 @@ static void eq_iir_s32_16_default(const struct comp_dev *dev, const int samples = frames * nch; int processed = 0; + module_update_processing_position(bsource, bsink, SOF_IPC_FRAME_S32_LE, + SOF_IPC_FRAME_S16_LE, samples); + x = source->r_ptr; y = sink->w_ptr; while (processed < samples) { @@ -246,11 +262,13 @@ static void eq_iir_s32_16_default(const struct comp_dev *dev, #endif /* CONFIG_FORMAT_S32LE && CONFIG_FORMAT_S16LE */ #if CONFIG_FORMAT_S32LE && CONFIG_FORMAT_S24LE -static void eq_iir_s32_24_default(const struct comp_dev *dev, - const struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink, uint32_t frames) +static void eq_iir_s32_24_default(struct processing_module *mod, + struct input_stream_buffer *bsource, + struct output_stream_buffer *bsink, uint32_t frames) { - struct comp_data *cd = comp_get_drvdata(dev); + struct comp_data *cd = module_get_private_data(mod); + struct audio_stream __sparse_cache *source = bsource->data; + struct audio_stream __sparse_cache *sink = bsink->data; struct iir_state_df2t *filter; int32_t *x0; int32_t *y0; @@ -266,6 +284,9 @@ static void eq_iir_s32_24_default(const struct comp_dev *dev, const int samples = frames * nch; int processed = 0; + module_update_processing_position(bsource, bsink, SOF_IPC_FRAME_S32_LE, + SOF_IPC_FRAME_S32_LE, samples); + x = source->r_ptr; y = sink->w_ptr; while (processed < samples) { @@ -291,20 +312,28 @@ static void eq_iir_s32_24_default(const struct comp_dev *dev, } #endif /* CONFIG_FORMAT_S32LE && CONFIG_FORMAT_S24LE */ -static void eq_iir_pass(const struct comp_dev *dev, - const struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink, - uint32_t frames) +static void eq_iir_pass(struct processing_module *mod, struct input_stream_buffer *bsource, + struct output_stream_buffer *bsink, uint32_t frames) { + struct audio_stream __sparse_cache *source = bsource->data; + struct audio_stream __sparse_cache *sink = bsink->data; + + if (source->frame_fmt == SOF_IPC_FRAME_S16_LE) + module_update_processing_position(bsource, bsink, SOF_IPC_FRAME_S16_LE, + SOF_IPC_FRAME_S16_LE, frames * source->channels); + else + module_update_processing_position(bsource, bsink, SOF_IPC_FRAME_S32_LE, + SOF_IPC_FRAME_S32_LE, frames * source->channels); + audio_stream_copy(source, 0, sink, 0, frames * source->channels); } #if CONFIG_FORMAT_S16LE && CONFIG_FORMAT_S32LE -static void eq_iir_s32_s16_pass(const struct comp_dev *dev, - const struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink, - uint32_t frames) +static void eq_iir_s32_s16_pass(struct processing_module *mod, struct input_stream_buffer *bsource, + struct output_stream_buffer *bsink, uint32_t frames) { + struct audio_stream __sparse_cache *source = bsource->data; + struct audio_stream __sparse_cache *sink = bsink->data; int32_t *x = source->r_ptr; int16_t *y = sink->w_ptr; int nmax; @@ -312,10 +341,13 @@ static void eq_iir_s32_s16_pass(const struct comp_dev *dev, int i; int remaining_samples = frames * source->channels; + module_update_processing_position(bsource, bsink, SOF_IPC_FRAME_S32_LE, + SOF_IPC_FRAME_S16_LE, remaining_samples); + while (remaining_samples) { - nmax = EQ_IIR_BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(source, x)); + nmax = BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(source, x)); n = MIN(remaining_samples, nmax); - nmax = EQ_IIR_BYTES_TO_S16_SAMPLES(audio_stream_bytes_without_wrap(sink, y)); + nmax = BYTES_TO_S16_SAMPLES(audio_stream_bytes_without_wrap(sink, y)); n = MIN(n, nmax); for (i = 0; i < n; i++) { *y = sat_int16(Q_SHIFT_RND(*x, 31, 15)); @@ -330,11 +362,11 @@ static void eq_iir_s32_s16_pass(const struct comp_dev *dev, #endif /* CONFIG_FORMAT_S16LE && CONFIG_FORMAT_S32LE */ #if CONFIG_FORMAT_S24LE && CONFIG_FORMAT_S32LE -static void eq_iir_s32_s24_pass(const struct comp_dev *dev, - const struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink, - uint32_t frames) +static void eq_iir_s32_s24_pass(struct processing_module *mod, struct input_stream_buffer *bsource, + struct output_stream_buffer *bsink, uint32_t frames) { + struct audio_stream __sparse_cache *source = bsource->data; + struct audio_stream __sparse_cache *sink = bsink->data; int32_t *x = source->r_ptr; int32_t *y = sink->w_ptr; int nmax; @@ -342,10 +374,13 @@ static void eq_iir_s32_s24_pass(const struct comp_dev *dev, int i; int remaining_samples = frames * source->channels; + module_update_processing_position(bsource, bsink, SOF_IPC_FRAME_S32_LE, + SOF_IPC_FRAME_S32_LE, remaining_samples); + while (remaining_samples) { - nmax = EQ_IIR_BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(source, x)); + nmax = BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(source, x)); n = MIN(remaining_samples, nmax); - nmax = EQ_IIR_BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(sink, y)); + nmax = BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(sink, y)); n = MIN(n, nmax); for (i = 0; i < n; i++) { *y = sat_int24(Q_SHIFT_RND(*x, 31, 23)); @@ -444,11 +479,14 @@ static void eq_iir_free_delaylines(struct comp_data *cd) iir[i].delay = NULL; } -static int eq_iir_init_coef(struct sof_eq_iir_config *config, - struct iir_state_df2t *iir, int nch) +static int eq_iir_init_coef(struct processing_module *mod, int nch) { + struct comp_data *cd = module_get_private_data(mod); + struct sof_eq_iir_config *config = cd->config; + struct iir_state_df2t *iir = cd->iir; struct sof_eq_iir_header_df2t *lookup[SOF_EQ_IIR_MAX_RESPONSES]; struct sof_eq_iir_header_df2t *eq; + struct comp_dev *dev = mod->dev; int32_t *assign_response; int32_t *coef_data; int size_sum = 0; @@ -457,19 +495,18 @@ static int eq_iir_init_coef(struct sof_eq_iir_config *config, int j; int s; - comp_cl_info(&comp_eq_iir, "eq_iir_init_coef(), response assign for %u channels, %u responses", - config->channels_in_config, - config->number_of_responses); + comp_info(dev, "eq_iir_init_coef(), response assign for %u channels, %u responses", + config->channels_in_config, config->number_of_responses); /* Sanity checks */ if (nch > PLATFORM_MAX_CHANNELS || config->channels_in_config > PLATFORM_MAX_CHANNELS || !config->channels_in_config) { - comp_cl_err(&comp_eq_iir, "eq_iir_init_coef(), invalid channels count"); + comp_err(dev, "eq_iir_init_coef(), invalid channels count"); return -EINVAL; } if (config->number_of_responses > SOF_EQ_IIR_MAX_RESPONSES) { - comp_cl_err(&comp_eq_iir, "eq_iir_init_coef(), # of resp exceeds max"); + comp_err(dev, "eq_iir_init_coef(), # of resp exceeds max"); return -EINVAL; } @@ -504,15 +541,14 @@ static int eq_iir_init_coef(struct sof_eq_iir_config *config, /* Initialize EQ channel to bypass and continue with * next channel response. */ - comp_cl_info(&comp_eq_iir, "eq_iir_init_coef(), ch %d is set to bypass", - i); + comp_info(dev, "eq_iir_init_coef(), ch %d is set to bypass", i); iir_reset_df2t(&iir[i]); continue; } if (resp >= config->number_of_responses) { - comp_cl_info(&comp_eq_iir, "eq_iir_init_coef(), requested response %d exceeds defined", - resp); + comp_info(dev, "eq_iir_init_coef(), requested response %d exceeds defined", + resp); return -EINVAL; } @@ -522,14 +558,13 @@ static int eq_iir_init_coef(struct sof_eq_iir_config *config, if (s > 0) { size_sum += s; } else { - comp_cl_info(&comp_eq_iir, "eq_iir_init_coef(), sections count %d exceeds max", - eq->num_sections); + comp_info(dev, "eq_iir_init_coef(), sections count %d exceeds max", + eq->num_sections); return -EINVAL; } iir_init_coef_df2t(&iir[i], eq); - comp_cl_info(&comp_eq_iir, "eq_iir_init_coef(), ch %d is set to response %d", - i, resp); + comp_info(dev, "eq_iir_init_coef(), ch %d is set to response %d", i, resp); } return size_sum; @@ -550,15 +585,17 @@ static void eq_iir_init_delay(struct iir_state_df2t *iir, } } -static int eq_iir_setup(struct comp_data *cd, int nch) +static int eq_iir_setup(struct processing_module *mod, int nch) { + struct comp_data *cd = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; int delay_size; /* Free existing IIR channels data if it was allocated */ eq_iir_free_delaylines(cd); /* Set coefficients for each channel EQ from coefficient blob */ - delay_size = eq_iir_init_coef(cd->config, cd->iir, nch); + delay_size = eq_iir_init_coef(mod, nch); if (delay_size < 0) return delay_size; /* Contains error code */ @@ -572,7 +609,7 @@ static int eq_iir_setup(struct comp_data *cd, int nch) cd->iir_delay = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, delay_size); if (!cd->iir_delay) { - comp_cl_err(&comp_eq_iir, "eq_iir_setup(), delay allocation fail"); + comp_err(dev, "eq_iir_setup(), delay allocation fail"); return -ENOMEM; } @@ -587,40 +624,28 @@ static int eq_iir_setup(struct comp_data *cd, int nch) /* * End of EQ setup code. Next the standard component methods. */ - -static struct comp_dev *eq_iir_new(const struct comp_driver *drv, - struct comp_ipc_config *config, - void *spec) +static int eq_iir_init(struct processing_module *mod) { - struct comp_dev *dev = NULL; - struct comp_data *cd = NULL; - struct ipc_config_process *ipc_iir = spec; - size_t bs = ipc_iir->size; - int i; - int ret; + struct module_data *md = &mod->priv; + struct comp_dev *dev = mod->dev; + struct module_config *cfg = &md->cfg; + struct comp_data *cd; + size_t bs = cfg->size; + int i, ret; - comp_cl_info(&comp_eq_iir, "eq_iir_new()"); + comp_info(dev, "eq_iir_init()"); - /* Check first before proceeding with dev and cd that coefficients - * blob size is sane. - */ + /* Check first before proceeding with dev and cd that coefficients blob size is sane */ if (bs > SOF_EQ_IIR_MAX_SIZE) { - comp_cl_err(&comp_eq_iir, "eq_iir_new(), coefficients blob size %u exceeds maximum", - bs); - return NULL; + comp_err(dev, "eq_iir_init(), coefficients blob size %u exceeds maximum", bs); + return -EINVAL; } - dev = comp_alloc(drv, sizeof(*dev)); - if (!dev) - return NULL; - dev->ipc_config = *config; - cd = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, sizeof(*cd)); if (!cd) - goto fail; - - comp_set_drvdata(dev, cd); + return -ENOMEM; + md->private = cd; cd->eq_iir_func = NULL; cd->iir_delay = NULL; cd->iir_delay_size = 0; @@ -628,36 +653,40 @@ static struct comp_dev *eq_iir_new(const struct comp_driver *drv, /* component model data handler */ cd->model_handler = comp_data_blob_handler_new(dev); if (!cd->model_handler) { - comp_cl_err(&comp_eq_iir, "eq_iir_new(): comp_data_blob_handler_new() failed."); - goto cd_fail; + comp_err(dev, "eq_iir_init(): comp_data_blob_handler_new() failed."); + ret = -ENOMEM; + goto err; } /* Allocate and make a copy of the coefficients blob and reset IIR. If * the EQ is configured later in run-time the size is zero. */ - ret = comp_init_data_blob(cd->model_handler, bs, ipc_iir->data); + ret = comp_init_data_blob(cd->model_handler, bs, cfg->data); if (ret < 0) { - comp_cl_err(&comp_eq_iir, "eq_iir_new(): comp_init_data_blob() failed."); - goto cd_fail; + comp_err(dev, "eq_iir_init(): comp_init_data_blob() failed with error: %d", ret); + comp_data_blob_handler_free(cd->model_handler); + goto err; } for (i = 0; i < PLATFORM_MAX_CHANNELS; i++) iir_reset_df2t(&cd->iir[i]); - dev->state = COMP_STATE_READY; - return dev; + /* + * 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; -cd_fail: - comp_data_blob_handler_free(cd->model_handler); + return 0; +err: rfree(cd); -fail: - rfree(dev); - return NULL; + return ret; } -static void eq_iir_free(struct comp_dev *dev) +static int eq_iir_free(struct processing_module *mod) { - struct comp_data *cd = comp_get_drvdata(dev); + struct comp_data *cd = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; comp_info(dev, "eq_iir_free()"); @@ -665,7 +694,7 @@ static void eq_iir_free(struct comp_dev *dev) comp_data_blob_handler_free(cd->model_handler); rfree(cd); - rfree(dev); + return 0; } static int eq_iir_verify_params(struct comp_dev *dev, @@ -704,250 +733,158 @@ static int eq_iir_verify_params(struct comp_dev *dev, return 0; } -/* set component audio stream parameters */ -static int eq_iir_params(struct comp_dev *dev, - struct sof_ipc_stream_params *params) -{ - int err; - - comp_info(dev, "eq_iir_params()"); - - err = eq_iir_verify_params(dev, params); - if (err < 0) { - comp_err(dev, "eq_iir_params(): pcm params verification failed."); - return -EINVAL; - } - - /* All configuration work is postponed to prepare(). */ - return 0; -} - -static int iir_cmd_get_data(struct comp_dev *dev, - struct sof_ipc_ctrl_data *cdata, int max_size) -{ - struct comp_data *cd = comp_get_drvdata(dev); - int ret = 0; - - switch (cdata->cmd) { - case SOF_CTRL_CMD_BINARY: - comp_info(dev, "iir_cmd_get_data(), SOF_CTRL_CMD_BINARY"); - ret = comp_data_blob_get_cmd(cd->model_handler, cdata, - max_size); - break; - default: - comp_err(dev, "iir_cmd_get_data(), invalid command"); - ret = -EINVAL; - break; - } - return ret; -} - -static int iir_cmd_set_data(struct comp_dev *dev, - struct sof_ipc_ctrl_data *cdata) -{ - struct comp_data *cd = comp_get_drvdata(dev); - int ret = 0; - - switch (cdata->cmd) { - case SOF_CTRL_CMD_BINARY: - comp_info(dev, "iir_cmd_set_data(), SOF_CTRL_CMD_BINARY"); - ret = comp_data_blob_set_cmd(cd->model_handler, cdata); - break; - default: - comp_err(dev, "iir_cmd_set_data(), invalid command"); - ret = -EINVAL; - break; - } - - return ret; -} - /* used to pass standard and bespoke commands (with data) to component */ -static int eq_iir_cmd(struct comp_dev *dev, int cmd, void *data, - int max_data_size) -{ - struct sof_ipc_ctrl_data *cdata = ASSUME_ALIGNED(data, 4); - int ret = 0; - - comp_info(dev, "eq_iir_cmd()"); - - switch (cmd) { - case COMP_CMD_SET_DATA: - ret = iir_cmd_set_data(dev, cdata); - break; - case COMP_CMD_GET_DATA: - ret = iir_cmd_get_data(dev, cdata, max_data_size); - break; - default: - comp_err(dev, "eq_iir_cmd(), invalid command"); - ret = -EINVAL; - } - - return ret; -} - -static int eq_iir_trigger(struct comp_dev *dev, int cmd) +static int eq_iir_set_config(struct processing_module *mod, uint32_t config_id, + enum module_cfg_fragment_position pos, uint32_t data_offset_size, + const uint8_t *fragment, size_t fragment_size, uint8_t *response, + size_t response_size) { - struct comp_data *cd = comp_get_drvdata(dev); + struct comp_data *cd = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; - comp_info(dev, "eq_iir_trigger()"); + comp_info(dev, "eq_iir_set_config()"); - if ((cmd == COMP_TRIGGER_START || cmd == COMP_TRIGGER_RELEASE) && !cd->eq_iir_func) { - comp_cl_err(&comp_eq_iir, "eq_iir_func is not set"); - return -EINVAL; - } - - return comp_set_state(dev, cmd); + return comp_data_blob_set(cd->model_handler, pos, data_offset_size, fragment, + fragment_size); } -static void eq_iir_process(struct comp_dev *dev, struct comp_buffer __sparse_cache *source, - struct comp_buffer __sparse_cache *sink, int frames, - uint32_t source_bytes, uint32_t sink_bytes) +static int eq_iir_get_config(struct processing_module *mod, + uint32_t config_id, uint32_t *data_offset_size, + uint8_t *fragment, size_t fragment_size) { - struct comp_data *cd = comp_get_drvdata(dev); - - buffer_stream_invalidate(source, source_bytes); + struct sof_ipc_ctrl_data *cdata = (struct sof_ipc_ctrl_data *)fragment; + struct comp_data *cd = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; - cd->eq_iir_func(dev, &source->stream, &sink->stream, frames); + comp_info(dev, "eq_iir_get_config()"); - buffer_stream_writeback(sink, sink_bytes); - - /* calc new free and available */ - comp_update_buffer_cached_consume(source, source_bytes); - comp_update_buffer_cached_produce(sink, sink_bytes); + return comp_data_blob_get_cmd(cd->model_handler, cdata, fragment_size); } -/* copy and process stream data from source to sink buffers */ -static int eq_iir_copy(struct comp_dev *dev) +static int eq_iir_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 comp_copy_limits cl; - struct comp_data *cd = comp_get_drvdata(dev); - struct comp_buffer *sourceb, *sinkb; - struct comp_buffer __sparse_cache *source_c, *sink_c; + struct comp_data *cd = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; int ret; - comp_dbg(dev, "eq_iir_copy()"); - - sourceb = list_first_item(&dev->bsource_list, struct comp_buffer, - sink_list); - source_c = buffer_acquire(sourceb); - /* Check for changed configuration */ if (comp_is_new_data_blob_available(cd->model_handler)) { cd->config = comp_get_data_blob(cd->model_handler, NULL, NULL); - ret = eq_iir_setup(cd, source_c->stream.channels); + ret = eq_iir_setup(mod, mod->stream_params->channels); if (ret < 0) { - comp_err(dev, "eq_iir_copy(), failed IIR setup"); - buffer_release(source_c); - + comp_err(dev, "eq_iir_process(), failed IIR setup"); return ret; } } - sinkb = list_first_item(&dev->bsink_list, struct comp_buffer, - source_list); - sink_c = buffer_acquire(sinkb); - - /* Get source, sink, number of frames etc. to process. */ - comp_get_copy_limits(source_c, sink_c, &cl); - - /* Run EQ function */ - eq_iir_process(dev, source_c, sink_c, cl.frames, cl.source_bytes, - cl.sink_bytes); + cd->eq_iir_func(mod, &input_buffers[0], &output_buffers[0], input_buffers[0].size); + return 0; +} - buffer_release(sink_c); - buffer_release(source_c); +/** + * \brief Set EQ IIR frames alignment limit. + * \param[in,out] source Structure pointer of source. + * \param[in,out] sink Structure pointer of sink. + */ +static void eq_iir_set_alignment(struct audio_stream *source, struct audio_stream *sink) +{ + const uint32_t byte_align = 1; + const uint32_t frame_align_req = 1; - return 0; + audio_stream_init_alignment_constants(byte_align, frame_align_req, source); + audio_stream_init_alignment_constants(byte_align, frame_align_req, sink); } -static int eq_iir_prepare(struct comp_dev *dev) +static int eq_iir_prepare(struct processing_module *mod) { - struct comp_data *cd = comp_get_drvdata(dev); + struct comp_data *cd = module_get_private_data(mod); + struct module_data *md = &mod->priv; struct comp_buffer *sourceb, *sinkb; struct comp_buffer __sparse_cache *source_c, *sink_c; + struct comp_dev *dev = mod->dev; enum sof_ipc_frame source_format; enum sof_ipc_frame sink_format; - uint32_t sink_period_bytes; + uint32_t sink_period_bytes, source_period_bytes; int ret; - comp_info(dev, "eq_iir_prepare()"); - - ret = comp_set_state(dev, COMP_TRIGGER_PREPARE); + ret = eq_iir_verify_params(dev, mod->stream_params); if (ret < 0) return ret; - if (ret == COMP_STATUS_STATE_ALREADY_SET) - return PPL_STATUS_PATH_STOP; + comp_info(dev, "eq_iir_prepare()"); /* EQ 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); + 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); - /* get source data format */ - source_format = source_c->stream.frame_fmt; + eq_iir_set_alignment(&source_c->stream, &sink_c->stream); - /* get sink data format and period bytes */ + /* get source and sink data format */ + source_format = source_c->stream.frame_fmt; sink_format = sink_c->stream.frame_fmt; - sink_period_bytes = audio_stream_period_bytes(&sink_c->stream, - dev->frames); + source_period_bytes = audio_stream_period_bytes(&source_c->stream, dev->frames); + sink_period_bytes = audio_stream_period_bytes(&sink_c->stream, dev->frames); if (sink_c->stream.size < sink_period_bytes) { comp_err(dev, "eq_iir_prepare(): sink buffer size %d is insufficient < %d", sink_c->stream.size, sink_period_bytes); - ret = -ENOMEM; - goto out; + buffer_release(sink_c); + buffer_release(source_c); + return -ENOMEM; } + md->mpd.in_buff_size = source_period_bytes; + md->mpd.out_buff_size = sink_period_bytes; + cd->config = comp_get_data_blob(cd->model_handler, NULL, NULL); /* Initialize EQ */ comp_info(dev, "eq_iir_prepare(), source_format=%d, sink_format=%d", source_format, sink_format); + if (cd->config) { - ret = eq_iir_setup(cd, source_c->stream.channels); + ret = eq_iir_setup(mod, source_c->stream.channels); + buffer_release(sink_c); + buffer_release(source_c); if (ret < 0) { comp_err(dev, "eq_iir_prepare(), setup failed."); - goto out; + return ret; } cd->eq_iir_func = eq_iir_find_func(source_format, sink_format, fm_configured, ARRAY_SIZE(fm_configured)); if (!cd->eq_iir_func) { comp_err(dev, "eq_iir_prepare(), No proc func"); - ret = -EINVAL; - goto out; + return -EINVAL; } comp_info(dev, "eq_iir_prepare(), IIR is configured."); - } else { - cd->eq_iir_func = eq_iir_find_func(source_format, sink_format, fm_passthrough, - ARRAY_SIZE(fm_passthrough)); - if (!cd->eq_iir_func) { - comp_err(dev, "eq_iir_prepare(), No pass func"); - ret = -EINVAL; - goto out; - } - comp_info(dev, "eq_iir_prepare(), pass-through mode."); - } -out: - if (ret < 0) - comp_set_state(dev, COMP_TRIGGER_RESET); + return 0; + } buffer_release(sink_c); buffer_release(source_c); - return ret; + cd->eq_iir_func = eq_iir_find_func(source_format, sink_format, fm_passthrough, + ARRAY_SIZE(fm_passthrough)); + if (!cd->eq_iir_func) { + comp_err(dev, "eq_iir_prepare(), No pass func"); + return -EINVAL; + } + comp_info(dev, "eq_iir_prepare(), pass-through mode."); + + return 0; } -static int eq_iir_reset(struct comp_dev *dev) +static int eq_iir_reset(struct processing_module *mod) { + struct comp_data *cd = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; int i; - struct comp_data *cd = comp_get_drvdata(dev); comp_info(dev, "eq_iir_reset()"); @@ -957,34 +894,17 @@ static int eq_iir_reset(struct comp_dev *dev) for (i = 0; i < PLATFORM_MAX_CHANNELS; i++) iir_reset_df2t(&cd->iir[i]); - comp_set_state(dev, COMP_TRIGGER_RESET); return 0; } -static const struct comp_driver comp_eq_iir = { - .type = SOF_COMP_EQ_IIR, - .uid = SOF_RT_UUID(eq_iir_uuid), - .tctx = &eq_iir_tr, - .ops = { - .create = eq_iir_new, - .free = eq_iir_free, - .params = eq_iir_params, - .cmd = eq_iir_cmd, - .trigger = eq_iir_trigger, - .copy = eq_iir_copy, - .prepare = eq_iir_prepare, - .reset = eq_iir_reset, - }, -}; - -static SHARED_DATA struct comp_driver_info comp_eq_iir_info = { - .drv = &comp_eq_iir, +static struct module_interface eq_iir_interface = { + .init = eq_iir_init, + .prepare = eq_iir_prepare, + .process = eq_iir_process, + .set_configuration = eq_iir_set_config, + .get_configuration = eq_iir_get_config, + .reset = eq_iir_reset, + .free = eq_iir_free }; -UT_STATIC void sys_comp_eq_iir_init(void) -{ - comp_register(platform_shared_get(&comp_eq_iir_info, - sizeof(comp_eq_iir_info))); -} - -DECLARE_MODULE(sys_comp_eq_iir_init); +DECLARE_MODULE_ADAPTER(eq_iir_interface, eq_iir_uuid, eq_iir_tr); diff --git a/src/audio/module_adapter/module/volume/volume.c b/src/audio/module_adapter/module/volume/volume.c index 8c0fc92e8b09..37c6a7a60980 100644 --- a/src/audio/module_adapter/module/volume/volume.c +++ b/src/audio/module_adapter/module/volume/volume.c @@ -88,7 +88,7 @@ static uint32_t vol_zc_get_s16(const struct audio_stream __sparse_cache *source, x = audio_stream_wrap(source, x + remaining_samples - 1); /* Go to last channel */ while (remaining_samples) { bytes = audio_stream_rewind_bytes_without_wrap(source, x); - nmax = VOL_BYTES_TO_S16_SAMPLES(bytes) + 1; + nmax = BYTES_TO_S16_SAMPLES(bytes) + 1; n = MIN(nmax, remaining_samples); for (i = 0; i < n; i += nch) { sum = 0; @@ -136,7 +136,7 @@ static uint32_t vol_zc_get_s24(const struct audio_stream __sparse_cache *source, x = audio_stream_wrap(source, x + remaining_samples - 1); /* Go to last channel */ while (remaining_samples) { bytes = audio_stream_rewind_bytes_without_wrap(source, x); - nmax = VOL_BYTES_TO_S32_SAMPLES(bytes) + 1; + nmax = BYTES_TO_S32_SAMPLES(bytes) + 1; n = MIN(nmax, remaining_samples); for (i = 0; i < n; i += nch) { sum = 0; @@ -184,7 +184,7 @@ static uint32_t vol_zc_get_s32(const struct audio_stream __sparse_cache *source, x = audio_stream_wrap(source, x + remaining_samples - 1); /* Go to last channel */ while (remaining_samples) { bytes = audio_stream_rewind_bytes_without_wrap(source, x); - nmax = VOL_BYTES_TO_S32_SAMPLES(bytes) + 1; + nmax = BYTES_TO_S32_SAMPLES(bytes) + 1; n = MIN(nmax, remaining_samples); for (i = 0; i < n; i += nch) { sum = 0; diff --git a/src/audio/module_adapter/module/volume/volume_generic.c b/src/audio/module_adapter/module/volume/volume_generic.c index 498339b02311..3f0df59922cb 100644 --- a/src/audio/module_adapter/module/volume/volume_generic.c +++ b/src/audio/module_adapter/module/volume/volume_generic.c @@ -71,12 +71,12 @@ static void vol_s24_to_s24(struct processing_module *mod, struct input_stream_bu x = source->r_ptr; y = sink->w_ptr; - bsource->consumed += VOL_S32_SAMPLES_TO_BYTES(remaining_samples); - bsink->size += VOL_S32_SAMPLES_TO_BYTES(remaining_samples); + module_update_processing_position(bsource, bsink, SOF_IPC_FRAME_S32_LE, + SOF_IPC_FRAME_S32_LE, remaining_samples); while (remaining_samples) { - nmax = VOL_BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(source, x)); + nmax = BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(source, x)); n = MIN(remaining_samples, nmax); - nmax = VOL_BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(sink, y)); + nmax = BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(sink, y)); n = MIN(n, nmax); for (j = 0; j < nch; j++) { x0 = x + j; @@ -133,12 +133,12 @@ static void vol_s32_to_s32(struct processing_module *mod, struct input_stream_bu x = source->r_ptr; y = sink->w_ptr; - bsource->consumed += VOL_S32_SAMPLES_TO_BYTES(remaining_samples); - bsink->size += VOL_S32_SAMPLES_TO_BYTES(remaining_samples); + module_update_processing_position(bsource, bsink, SOF_IPC_FRAME_S32_LE, + SOF_IPC_FRAME_S32_LE, remaining_samples); while (remaining_samples) { - nmax = VOL_BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(source, x)); + nmax = BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(source, x)); n = MIN(remaining_samples, nmax); - nmax = VOL_BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(sink, y)); + nmax = BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(sink, y)); n = MIN(n, nmax); /* Note: on Xtensa processing one channel volume at time performed slightly * better than simpler interleaved code version (average 19 us vs. 20 us). @@ -201,12 +201,12 @@ static void vol_s16_to_s16(struct processing_module *mod, struct input_stream_bu x = source->r_ptr; y = sink->w_ptr; - bsource->consumed += VOL_S16_SAMPLES_TO_BYTES(remaining_samples); - bsink->size += VOL_S16_SAMPLES_TO_BYTES(remaining_samples); + module_update_processing_position(bsource, bsink, SOF_IPC_FRAME_S16_LE, + SOF_IPC_FRAME_S16_LE, remaining_samples); while (remaining_samples) { - nmax = VOL_BYTES_TO_S16_SAMPLES(audio_stream_bytes_without_wrap(source, x)); + nmax = BYTES_TO_S16_SAMPLES(audio_stream_bytes_without_wrap(source, x)); n = MIN(remaining_samples, nmax); - nmax = VOL_BYTES_TO_S16_SAMPLES(audio_stream_bytes_without_wrap(sink, y)); + nmax = BYTES_TO_S16_SAMPLES(audio_stream_bytes_without_wrap(sink, y)); n = MIN(n, nmax); for (j = 0; j < nch; j++) { x0 = x + j; diff --git a/src/audio/module_adapter/module/volume/volume_hifi3.c b/src/audio/module_adapter/module/volume/volume_hifi3.c index 727a74a50983..66754ae6b238 100644 --- a/src/audio/module_adapter/module/volume/volume_hifi3.c +++ b/src/audio/module_adapter/module/volume/volume_hifi3.c @@ -92,13 +92,13 @@ static void vol_s24_to_s24_s32(struct processing_module *mod, struct input_strea AE_SETCBEGIN0(buf); AE_SETCEND0(buf_end); - bsource->consumed += VOL_S32_SAMPLES_TO_BYTES(samples); - bsink->size += VOL_S32_SAMPLES_TO_BYTES(samples); + module_update_processing_position(bsource, bsink, SOF_IPC_FRAME_S32_LE, + SOF_IPC_FRAME_S32_LE, samples); while (samples) { - m = VOL_BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(source, in)); + m = BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(source, in)); n = MIN(m, samples); - m = VOL_BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(sink, out)); + m = BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(sink, out)); n = MIN(m, n); inu = AE_LA64_PP(in); /* process two continuous sample data once */ @@ -183,13 +183,13 @@ static void vol_s32_to_s24_s32(struct processing_module *mod, struct input_strea AE_SETCBEGIN0(buf); AE_SETCEND0(buf_end); - bsource->consumed += VOL_S32_SAMPLES_TO_BYTES(samples); - bsink->size += VOL_S32_SAMPLES_TO_BYTES(samples); + module_update_processing_position(bsource, bsink, SOF_IPC_FRAME_S32_LE, + SOF_IPC_FRAME_S32_LE, samples); while (samples) { - m = VOL_BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(source, in)); + m = BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(source, in)); n = MIN(m, samples); - m = VOL_BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(sink, out)); + m = BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(sink, out)); n = MIN(m, n); inu = AE_LA64_PP(in); /* process two continuous sample data once */ @@ -280,9 +280,9 @@ static void vol_s16_to_s16(struct processing_module *mod, struct input_stream_bu AE_SETCEND0(buf_end); while (samples) { - m = VOL_BYTES_TO_S16_SAMPLES(audio_stream_bytes_without_wrap(source, in)); + m = BYTES_TO_S16_SAMPLES(audio_stream_bytes_without_wrap(source, in)); n = MIN(m, samples); - m = VOL_BYTES_TO_S16_SAMPLES(audio_stream_bytes_without_wrap(sink, out)); + m = BYTES_TO_S16_SAMPLES(audio_stream_bytes_without_wrap(sink, out)); n = MIN(m, n); inu = AE_LA64_PP(in); for (i = 0; i < n; i += 4) { @@ -324,8 +324,8 @@ static void vol_s16_to_s16(struct processing_module *mod, struct input_stream_bu } AE_SA64POS_FP(outu, out); samples -= n; - bsource->consumed += VOL_S16_SAMPLES_TO_BYTES(n); - bsink->size += VOL_S16_SAMPLES_TO_BYTES(n); + module_update_processing_position(bsource, bsink, SOF_IPC_FRAME_S16_LE, + SOF_IPC_FRAME_S16_LE, n); in = audio_stream_wrap(source, in); out = audio_stream_wrap(sink, out); } diff --git a/src/audio/pcm_converter/pcm_converter_generic.c b/src/audio/pcm_converter/pcm_converter_generic.c index 1b9e61eb5d85..daca26775ad8 100644 --- a/src/audio/pcm_converter/pcm_converter_generic.c +++ b/src/audio/pcm_converter/pcm_converter_generic.c @@ -26,9 +26,6 @@ #include #include -#define BYTES_TO_S16_SAMPLES 1 -#define BYTES_TO_S32_SAMPLES 2 - #if CONFIG_PCM_CONVERTER_FORMAT_S16LE && CONFIG_PCM_CONVERTER_FORMAT_S24LE static int pcm_convert_s16_to_s24(const struct audio_stream __sparse_cache *source, @@ -46,9 +43,9 @@ static int pcm_convert_s16_to_s24(const struct audio_stream __sparse_cache *sour src = audio_stream_wrap(source, src); dst = audio_stream_wrap(sink, dst); n = samples - processed; - nmax = audio_stream_bytes_without_wrap(source, src) >> BYTES_TO_S16_SAMPLES; + nmax = BYTES_TO_S16_SAMPLES(audio_stream_bytes_without_wrap(source, src)); n = MIN(n, nmax); - nmax = audio_stream_bytes_without_wrap(sink, dst) >> BYTES_TO_S32_SAMPLES; + nmax = BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(sink, dst)); n = MIN(n, nmax); for (i = 0; i < n; i++) { *dst = *src << 8; @@ -75,9 +72,9 @@ static int pcm_convert_s24_to_s16(const struct audio_stream __sparse_cache *sour src = audio_stream_wrap(source, src); dst = audio_stream_wrap(sink, dst); n = samples - processed; - nmax = audio_stream_bytes_without_wrap(source, src) >> BYTES_TO_S32_SAMPLES; + nmax = BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(source, src)); n = MIN(n, nmax); - nmax = audio_stream_bytes_without_wrap(sink, dst) >> BYTES_TO_S16_SAMPLES; + nmax = BYTES_TO_S16_SAMPLES(audio_stream_bytes_without_wrap(sink, dst)); n = MIN(n, nmax); for (i = 0; i < n; i++) { *dst = sat_int16(Q_SHIFT_RND(sign_extend_s24(*src), 23, 15)); @@ -108,9 +105,9 @@ static int pcm_convert_s16_to_s32(const struct audio_stream __sparse_cache *sour src = audio_stream_wrap(source, src); dst = audio_stream_wrap(sink, dst); n = samples - processed; - nmax = audio_stream_bytes_without_wrap(source, src) >> BYTES_TO_S16_SAMPLES; + nmax = BYTES_TO_S16_SAMPLES(audio_stream_bytes_without_wrap(source, src)); n = MIN(n, nmax); - nmax = audio_stream_bytes_without_wrap(sink, dst) >> BYTES_TO_S32_SAMPLES; + nmax = BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(sink, dst)); n = MIN(n, nmax); for (i = 0; i < n; i++) { *dst = *src << 16; @@ -137,9 +134,9 @@ static int pcm_convert_s32_to_s16(const struct audio_stream __sparse_cache *sour src = audio_stream_wrap(source, src); dst = audio_stream_wrap(sink, dst); n = samples - processed; - nmax = audio_stream_bytes_without_wrap(source, src) >> BYTES_TO_S32_SAMPLES; + nmax = BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(source, src)); n = MIN(n, nmax); - nmax = audio_stream_bytes_without_wrap(sink, dst) >> BYTES_TO_S16_SAMPLES; + nmax = BYTES_TO_S16_SAMPLES(audio_stream_bytes_without_wrap(sink, dst)); n = MIN(n, nmax); for (i = 0; i < n; i++) { *dst = sat_int16(Q_SHIFT_RND(*src, 31, 15)); @@ -170,9 +167,9 @@ static int pcm_convert_s24_to_s32(const struct audio_stream __sparse_cache *sour src = audio_stream_wrap(source, src); dst = audio_stream_wrap(sink, dst); n = samples - processed; - nmax = audio_stream_bytes_without_wrap(source, src) >> BYTES_TO_S32_SAMPLES; + nmax = BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(source, src)); n = MIN(n, nmax); - nmax = audio_stream_bytes_without_wrap(sink, dst) >> BYTES_TO_S32_SAMPLES; + nmax = BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(sink, dst)); n = MIN(n, nmax); for (i = 0; i < n; i++) { *dst = *src << 8; @@ -199,9 +196,9 @@ static int pcm_convert_s32_to_s24(const struct audio_stream __sparse_cache *sour src = audio_stream_wrap(source, src); dst = audio_stream_wrap(sink, dst); n = samples - processed; - nmax = audio_stream_bytes_without_wrap(source, src) >> BYTES_TO_S32_SAMPLES; + nmax = BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(source, src)); n = MIN(n, nmax); - nmax = audio_stream_bytes_without_wrap(sink, dst) >> BYTES_TO_S32_SAMPLES; + nmax = BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(sink, dst)); n = MIN(n, nmax); for (i = 0; i < n; i++) { *dst = sat_int24(Q_SHIFT_RND(*src, 31, 23)); @@ -543,9 +540,9 @@ static int pcm_convert_s16_c16_to_s16_c32(const struct audio_stream __sparse_cac src = audio_stream_wrap(source, src); dst = audio_stream_wrap(sink, dst); n = samples - processed; - nmax = audio_stream_bytes_without_wrap(source, src) >> BYTES_TO_S16_SAMPLES; + nmax = BYTES_TO_S16_SAMPLES(audio_stream_bytes_without_wrap(source, src)); n = MIN(n, nmax); - nmax = audio_stream_bytes_without_wrap(sink, dst) >> BYTES_TO_S32_SAMPLES; + nmax = BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(sink, dst)); n = MIN(n, nmax); for (i = 0; i < n; i++) { *dst = *src; @@ -572,9 +569,9 @@ static int pcm_convert_s16_c32_to_s16_c16(const struct audio_stream __sparse_cac src = audio_stream_wrap(source, src); dst = audio_stream_wrap(sink, dst); n = samples - processed; - nmax = audio_stream_bytes_without_wrap(source, src) >> BYTES_TO_S32_SAMPLES; + nmax = BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(source, src)); n = MIN(n, nmax); - nmax = audio_stream_bytes_without_wrap(sink, dst) >> BYTES_TO_S16_SAMPLES; + nmax = BYTES_TO_S16_SAMPLES(audio_stream_bytes_without_wrap(sink, dst)); n = MIN(n, nmax); for (i = 0; i < n; i++) { *dst = *src & 0xffff; @@ -602,9 +599,9 @@ static int pcm_convert_s16_c32_to_s32_c32(const struct audio_stream __sparse_cac src = audio_stream_wrap(source, src); dst = audio_stream_wrap(sink, dst); n = samples - processed; - nmax = audio_stream_bytes_without_wrap(source, src) >> BYTES_TO_S32_SAMPLES; + nmax = BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(source, src)); n = MIN(n, nmax); - nmax = audio_stream_bytes_without_wrap(sink, dst) >> BYTES_TO_S32_SAMPLES; + nmax = BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(sink, dst)); n = MIN(n, nmax); for (i = 0; i < n; i++) { *dst = *src << 16; @@ -631,9 +628,9 @@ static int pcm_convert_s32_c32_to_s16_c32(const struct audio_stream __sparse_cac src = audio_stream_wrap(source, src); dst = audio_stream_wrap(sink, dst); n = samples - processed; - nmax = audio_stream_bytes_without_wrap(source, src) >> BYTES_TO_S32_SAMPLES; + nmax = BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(source, src)); n = MIN(n, nmax); - nmax = audio_stream_bytes_without_wrap(sink, dst) >> BYTES_TO_S32_SAMPLES; + nmax = BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(sink, dst)); n = MIN(n, nmax); for (i = 0; i < n; i++) { *dst = sat_int16(Q_SHIFT_RND(*src, 31, 15)); @@ -661,9 +658,9 @@ static int pcm_convert_s16_c32_to_s24_c32(const struct audio_stream __sparse_cac src = audio_stream_wrap(source, src); dst = audio_stream_wrap(sink, dst); n = samples - processed; - nmax = audio_stream_bytes_without_wrap(source, src) >> BYTES_TO_S32_SAMPLES; + nmax = BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(source, src)); n = MIN(n, nmax); - nmax = audio_stream_bytes_without_wrap(sink, dst) >> BYTES_TO_S32_SAMPLES; + nmax = BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(sink, dst)); n = MIN(n, nmax); for (i = 0; i < n; i++) { *dst = *src << 8; @@ -690,9 +687,9 @@ static int pcm_convert_s24_c32_to_s16_c32(const struct audio_stream __sparse_cac src = audio_stream_wrap(source, src); dst = audio_stream_wrap(sink, dst); n = samples - processed; - nmax = audio_stream_bytes_without_wrap(source, src) >> BYTES_TO_S32_SAMPLES; + nmax = BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(source, src)); n = MIN(n, nmax); - nmax = audio_stream_bytes_without_wrap(sink, dst) >> BYTES_TO_S32_SAMPLES; + nmax = BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(sink, dst)); n = MIN(n, nmax); for (i = 0; i < n; i++) { *dst = sat_int16(Q_SHIFT_RND(sign_extend_s24(*src & 0xffffff), 23, 15)); @@ -723,7 +720,7 @@ static int pcm_convert_s24_c24_to_s24_c32(const struct audio_stream __sparse_cac n = samples - processed; nmax = audio_stream_bytes_without_wrap(source, src) / 3; n = MIN(n, nmax); - nmax = audio_stream_bytes_without_wrap(sink, dst) >> BYTES_TO_S32_SAMPLES; + nmax = BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(sink, dst)); n = MIN(n, nmax); for (i = 0; i < n; i += 1) { *dst = (*(src + 2) << 24) | (*(src + 1) << 16) | (*(src + 0) << 8); @@ -751,7 +748,7 @@ static int pcm_convert_s24_c32_to_s24_c24(const struct audio_stream __sparse_cac src = audio_stream_wrap(source, src); dst = audio_stream_wrap(sink, dst); n = samples - processed; - nmax = audio_stream_bytes_without_wrap(source, src) >> BYTES_TO_S32_SAMPLES; + nmax = BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(source, src)); n = MIN(n, nmax); nmax = audio_stream_bytes_without_wrap(sink, dst) / 3; n = MIN(n, nmax); @@ -785,7 +782,7 @@ static int pcm_convert_s24_c32_to_s24_c24_link_gtw(const struct audio_stream __s src = audio_stream_wrap(source, src); dst = audio_stream_wrap(sink, dst); n = samples - processed; - nmax = audio_stream_bytes_without_wrap(source, src) >> BYTES_TO_S32_SAMPLES; + nmax = BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(source, src)); n = MIN(n, nmax); nmax = audio_stream_bytes_without_wrap(sink, dst) / 3; n = MIN(n, nmax); diff --git a/src/audio/selector/selector_generic.c b/src/audio/selector/selector_generic.c index b9b3d9bb9b13..230b97a0962c 100644 --- a/src/audio/selector/selector_generic.c +++ b/src/audio/selector/selector_generic.c @@ -20,9 +20,6 @@ LOG_MODULE_DECLARE(selector, CONFIG_SOF_LOG_LEVEL); -#define BYTES_TO_S16_SAMPLES 1 -#define BYTES_TO_S32_SAMPLES 2 - #if CONFIG_FORMAT_S16LE /** * \brief Channel selection for 16 bit, 1 channel data format. @@ -50,7 +47,7 @@ static void sel_s16le_1ch(struct comp_dev *dev, struct audio_stream __sparse_cac 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; + nmax = BYTES_TO_S16_SAMPLES(audio_stream_bytes_without_wrap(sink, dest)); n = MIN(n, nmax); src_ch = src + sel_channel; for (i = 0; i < n; i++) { @@ -122,7 +119,7 @@ static void sel_s32le_1ch(struct comp_dev *dev, struct audio_stream __sparse_cac 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; + nmax = BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(sink, dest)); n = MIN(n, nmax); src_ch = src + sel_channel; for (i = 0; i < n; i++) { diff --git a/src/include/sof/audio/data_blob.h b/src/include/sof/audio/data_blob.h index 9b8575395acb..03455444338f 100644 --- a/src/include/sof/audio/data_blob.h +++ b/src/include/sof/audio/data_blob.h @@ -8,6 +8,7 @@ #ifndef __SOF_AUDIO_DATA_BLOB_H__ #define __SOF_AUDIO_DATA_BLOB_H__ +#include #include struct comp_dev; @@ -62,6 +63,19 @@ int comp_init_data_blob(struct comp_data_blob_handler *blob_handler, */ int comp_data_blob_set_cmd(struct comp_data_blob_handler *blob_handler, struct sof_ipc_ctrl_data *cdata); + +/** + * Handles IPC set command. + * + * @param blob_handler: Data blob handler + * @param pos position: of the data fragment + * @param data_offset_size: offset of the fragment in the whole data + * @param fragment: pointer to the fragment data + * @param fragment_size: size of the fragment data + */ +int comp_data_blob_set(struct comp_data_blob_handler *blob_handler, + enum module_cfg_fragment_position pos, uint32_t data_offset_size, + const uint8_t *fragment, size_t fragment_size); /** * Handles IPC get command. * @param blob_handler Data blob handler diff --git a/src/include/sof/audio/eq_iir/eq_iir.h b/src/include/sof/audio/eq_iir/eq_iir.h index 8969b027d290..001c2948874c 100644 --- a/src/include/sof/audio/eq_iir/eq_iir.h +++ b/src/include/sof/audio/eq_iir/eq_iir.h @@ -11,20 +11,15 @@ #define __SOF_AUDIO_EQ_IIR_EQ_IIR_H__ #include +#include #include -/** \brief Macros to convert without division bytes count to samples count */ -#define EQ_IIR_BYTES_TO_S16_SAMPLES(b) ((b) >> 1) -#define EQ_IIR_BYTES_TO_S32_SAMPLES(b) ((b) >> 2) - struct audio_stream; struct comp_dev; /** \brief Type definition for processing function select return value. */ -typedef void (*eq_iir_func)(const struct comp_dev *dev, - const struct audio_stream __sparse_cache *source, - struct audio_stream __sparse_cache *sink, - uint32_t frames); +typedef void (*eq_iir_func)(struct processing_module *mod, struct input_stream_buffer *bsource, + struct output_stream_buffer *bsink, uint32_t frames); /** \brief IIR EQ processing functions map item. */ struct eq_iir_func_map { @@ -34,7 +29,7 @@ struct eq_iir_func_map { }; #ifdef UNIT_TEST -void sys_comp_eq_iir_init(void); +void sys_comp_module_eq_iir_interface_init(void); #endif #endif /* __SOF_AUDIO_EQ_IIR_EQ_IIR_H__ */ diff --git a/src/include/sof/audio/format.h b/src/include/sof/audio/format.h index b1fed587e63e..4d4095b317c6 100644 --- a/src/include/sof/audio/format.h +++ b/src/include/sof/audio/format.h @@ -94,6 +94,12 @@ #define SATP_INT32(x) (((x) > INT32_MAX) ? INT32_MAX : (x)) #define SATM_INT32(x) (((x) < INT32_MIN) ? INT32_MIN : (x)) +/** \brief Macros to convert from bytes count to samples count and vice-versa */ +#define BYTES_TO_S16_SAMPLES(b) ((b) >> 1) +#define BYTES_TO_S32_SAMPLES(b) ((b) >> 2) +#define S16_SAMPLES_TO_BYTES(s) ((s) << 1) +#define S32_SAMPLES_TO_BYTES(s) ((s) << 2) + /* Inline functions */ #if __AUDIO_FORMAT_GENERIC__ diff --git a/src/include/sof/audio/module_adapter/module/generic.h b/src/include/sof/audio/module_adapter/module/generic.h index 2599e6a914b6..3425cbbad4fd 100644 --- a/src/include/sof/audio/module_adapter/module/generic.h +++ b/src/include/sof/audio/module_adapter/module/generic.h @@ -13,7 +13,6 @@ #define __SOF_AUDIO_MODULE_GENERIC__ #include -#include #include #include @@ -335,4 +334,29 @@ int module_set_large_config(struct comp_dev *dev, uint32_t param_id, bool first_ int module_get_large_config(struct comp_dev *dev, uint32_t param_id, bool first_block, bool last_block, uint32_t *data_offset, char *data); +static inline void +module_update_processing_position(struct input_stream_buffer *input, + struct output_stream_buffer *output, + enum sof_ipc_frame input_frame_fmt, + enum sof_ipc_frame output_frame_fmt, int samples) +{ + switch (input_frame_fmt) { + case SOF_IPC_FRAME_S16_LE: + input->consumed += S16_SAMPLES_TO_BYTES(samples); + break; + default: + input->consumed += S32_SAMPLES_TO_BYTES(samples); + break; + } + + switch (output_frame_fmt) { + case SOF_IPC_FRAME_S16_LE: + output->size += S16_SAMPLES_TO_BYTES(samples); + break; + default: + output->size += S32_SAMPLES_TO_BYTES(samples); + break; + } +} + #endif /* __SOF_AUDIO_MODULE_GENERIC__ */ diff --git a/src/include/sof/audio/volume.h b/src/include/sof/audio/volume.h index 56873388d955..bf4c39fd936d 100644 --- a/src/include/sof/audio/volume.h +++ b/src/include/sof/audio/volume.h @@ -102,13 +102,6 @@ struct sof_ipc_ctrl_value_chan; /** \brief Volume minimum value. */ #define VOL_MIN 0 -/** \brief Macros to convert without division bytes count to samples count */ -#define VOL_BYTES_TO_S16_SAMPLES(b) ((b) >> 1) -#define VOL_BYTES_TO_S32_SAMPLES(b) ((b) >> 2) - -#define VOL_S16_SAMPLES_TO_BYTES(s) ((s) << 1) -#define VOL_S32_SAMPLES_TO_BYTES(s) ((s) << 2) - /** * \brief volume processing function interface */ diff --git a/src/ipc/ipc3/helper.c b/src/ipc/ipc3/helper.c index 57fdd6fff58f..a1e0addae655 100644 --- a/src/ipc/ipc3/helper.c +++ b/src/ipc/ipc3/helper.c @@ -277,7 +277,15 @@ static void comp_specific_builder(struct sof_ipc_comp *comp, case SOF_COMP_NONE: config->process.type = proc->type; config->process.size = proc->size; +#ifdef UNIT_TEST + config->process.data = proc->data + comp->ext_data_length; +#else +#if CONFIG_LIBRARY + config->process.data = proc->data + comp->ext_data_length; +#else config->process.data = proc->data; +#endif +#endif break; default: break; diff --git a/test/cmocka/src/audio/eq_iir/CMakeLists.txt b/test/cmocka/src/audio/eq_iir/CMakeLists.txt index 62fb12e6cfe0..a6b8abea54b5 100644 --- a/test/cmocka/src/audio/eq_iir/CMakeLists.txt +++ b/test/cmocka/src/audio/eq_iir/CMakeLists.txt @@ -13,9 +13,12 @@ add_compile_options(-DUNIT_TEST) add_library(audio_for_eq_iir STATIC ${PROJECT_SOURCE_DIR}/src/audio/eq_iir/eq_iir.c + ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module_adapter.c + ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module/generic.c ${PROJECT_SOURCE_DIR}/src/math/iir.c ${PROJECT_SOURCE_DIR}/src/math/iir_df2t_generic.c ${PROJECT_SOURCE_DIR}/src/math/iir_df2t_hifi3.c + ${PROJECT_SOURCE_DIR}/src/math/numbers.c ${PROJECT_SOURCE_DIR}/src/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/audio/component.c ${PROJECT_SOURCE_DIR}/src/audio/data_blob.c 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 08294e167ee7..06810cdadc81 100644 --- a/test/cmocka/src/audio/eq_iir/eq_iir_process.c +++ b/test/cmocka/src/audio/eq_iir/eq_iir_process.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "../../util.h" #include "../../../include/cmocka_chirp_2ch.h" @@ -53,13 +54,14 @@ struct test_data { struct comp_buffer *sink; struct comp_buffer *source; struct test_parameters *params; + struct processing_module *mod; bool continue_loop; }; static int setup_group(void **state) { sys_comp_init(sof_get()); - sys_comp_eq_iir_init(); + sys_comp_module_eq_iir_interface_init(); return 0; } @@ -69,20 +71,27 @@ static struct sof_ipc_comp_process *create_eq_iir_comp_ipc(struct test_data *td) struct sof_eq_iir_config *eq; size_t ipc_size = sizeof(struct sof_ipc_comp_process); struct sof_abi_hdr *blob = (struct sof_abi_hdr *)iir_coef_2ch; - - ipc = calloc(1, ipc_size + blob->size); - eq = (struct sof_eq_iir_config *)&ipc->data; - ipc->comp.hdr.size = sizeof(struct sof_ipc_comp_process); + const struct sof_uuid uuid = { + .a = 0x5150c0e6, .b = 0x27f9, .c = 0x4ec8, + .d = {0x83, 0x51, 0xc7, 0x05, 0xb6, 0x42, 0xd1, 0x2f} + }; + + ipc = calloc(1, ipc_size + blob->size + SOF_UUID_SIZE); + memcpy(ipc + 1, &uuid, SOF_UUID_SIZE); + eq = (struct sof_eq_iir_config *)((char *)(ipc + 1) + SOF_UUID_SIZE); + ipc->comp.hdr.size = ipc_size + SOF_UUID_SIZE; ipc->comp.type = SOF_COMP_EQ_IIR; ipc->config.hdr.size = sizeof(struct sof_ipc_comp_config); ipc->size = blob->size; + ipc->comp.ext_data_length = SOF_UUID_SIZE; memcpy_s(eq, blob->size, blob->data, blob->size); return ipc; } -static void prepare_sink(struct test_data *td) +static void prepare_sink(struct test_data *td, struct processing_module *mod) { struct test_parameters *parameters = td->params; + struct module_data *md = &mod->priv; size_t size; size_t free; @@ -90,18 +99,25 @@ static void prepare_sink(struct test_data *td) size = parameters->frames * get_frame_bytes(parameters->sink_format, parameters->channels) * parameters->buffer_size_mult; + md->mpd.out_buff_size = parameters->frames * get_frame_bytes(parameters->sink_format, + parameters->channels); + td->sink = create_test_sink(td->dev, 0, parameters->sink_format, parameters->channels, size); free = audio_stream_get_free_bytes(&td->sink->stream); assert_int_equal(free, size); } -static void prepare_source(struct test_data *td) +static void prepare_source(struct test_data *td, struct processing_module *mod) { struct test_parameters *parameters = td->params; + struct module_data *md = &mod->priv; size_t size; size_t free; + md->mpd.in_buff_size = parameters->frames * get_frame_bytes(parameters->source_format, + parameters->channels); + size = parameters->frames * get_frame_bytes(parameters->source_format, parameters->channels) * parameters->buffer_size_mult; @@ -114,8 +130,10 @@ static void prepare_source(struct test_data *td) static int setup(void **state) { struct test_parameters *params = *state; + struct processing_module *mod; struct test_data *td; struct sof_ipc_comp_process *ipc; + struct comp_dev *dev; int ret; td = test_malloc(sizeof(*td)); @@ -131,18 +149,31 @@ static int setup(void **state) buffer_fill_data.idx = 0; buffer_verify_data.idx = 0; - td->dev = comp_new((struct sof_ipc_comp *)ipc); + dev = comp_new((struct sof_ipc_comp *)ipc); free(ipc); - if (!td->dev) + if (!dev) return -EINVAL; - prepare_sink(td); - prepare_source(td); - ret = comp_prepare(td->dev); + td->dev = dev; + mod = comp_get_drvdata(dev); + + prepare_sink(td, mod); + prepare_source(td, mod); + + /* allocate intermediate buffers */ + mod->input_buffers = test_malloc(sizeof(struct input_stream_buffer)); + mod->input_buffers[0].data = &td->source->stream; + mod->output_buffers = test_malloc(sizeof(struct output_stream_buffer)); + mod->output_buffers[0].data = &td->sink->stream; + mod->stream_params = test_malloc(sizeof(struct sof_ipc_stream_params)); + mod->period_bytes = get_frame_bytes(params->source_format, params->channels) * 48000 / 1000; + + ret = module_prepare(mod); if (ret) return ret; td->continue_loop = true; + *state = td; return 0; } @@ -150,7 +181,11 @@ static int setup(void **state) static int teardown(void **state) { struct test_data *td = *state; + struct processing_module *mod = comp_get_drvdata(td->dev); + test_free(mod->input_buffers); + test_free(mod->output_buffers); + test_free(mod->stream_params); test_free(td->params); free_test_source(td->source); free_test_sink(td->sink); @@ -162,6 +197,7 @@ static int teardown(void **state) #if CONFIG_FORMAT_S16LE static void fill_source_s16(struct test_data *td, int frames_max) { + struct processing_module *mod = comp_get_drvdata(td->dev); struct comp_dev *dev = td->dev; struct comp_buffer *sb; struct audio_stream *ss; @@ -190,10 +226,13 @@ static void fill_source_s16(struct test_data *td, int frames_max) bytes_total = samples_processed * audio_stream_sample_bytes(ss); comp_update_buffer_produce(sb, bytes_total); } + + mod->input_buffers[0].size = samples_processed / ss->channels; } static void verify_sink_s16(struct test_data *td) { + struct processing_module *mod = comp_get_drvdata(td->dev); struct comp_dev *dev = td->dev; struct comp_buffer *sb; struct audio_stream *ss; @@ -202,13 +241,11 @@ static void verify_sink_s16(struct test_data *td) int32_t out; int16_t *x; int samples; - int frames; int i; sb = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); ss = &sb->stream; - frames = audio_stream_get_avail_frames(ss); - samples = frames * ss->channels; + samples = mod->output_buffers[0].size >> 1; for (i = 0; i < samples; i++) { x = audio_stream_read_frag_s16(ss, i); out = *x; @@ -217,15 +254,13 @@ static void verify_sink_s16(struct test_data *td) if (delta > ERROR_TOLERANCE_S16 || delta < -ERROR_TOLERANCE_S16) assert_int_equal(out, ref); } - - if (frames > 0) - comp_update_buffer_consume(sb, frames * audio_stream_frame_bytes(ss)); } #endif /* CONFIG_FORMAT_S16LE */ #if CONFIG_FORMAT_S24LE static void fill_source_s24(struct test_data *td, int frames_max) { + struct processing_module *mod = comp_get_drvdata(td->dev); struct comp_dev *dev = td->dev; struct comp_buffer *sb; struct audio_stream *ss; @@ -254,10 +289,13 @@ static void fill_source_s24(struct test_data *td, int frames_max) bytes_total = samples_processed * audio_stream_sample_bytes(ss); comp_update_buffer_produce(sb, bytes_total); } + + mod->input_buffers[0].size = samples_processed / ss->channels; } static void verify_sink_s24(struct test_data *td) { + struct processing_module *mod = comp_get_drvdata(td->dev); struct comp_dev *dev = td->dev; struct comp_buffer *sb; struct audio_stream *ss; @@ -266,13 +304,11 @@ static void verify_sink_s24(struct test_data *td) int32_t out; int32_t *x; int samples; - int frames; int i; sb = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); ss = &sb->stream; - frames = audio_stream_get_avail_frames(ss); - samples = frames * ss->channels; + samples = mod->output_buffers[0].size >> 2; for (i = 0; i < samples; i++) { x = audio_stream_read_frag_s32(ss, i); out = (*x << 8) >> 8; /* Make sure there's no 24 bit overflow */ @@ -281,15 +317,13 @@ static void verify_sink_s24(struct test_data *td) if (delta > ERROR_TOLERANCE_S24 || delta < -ERROR_TOLERANCE_S24) assert_int_equal(out, ref); } - - if (frames > 0) - comp_update_buffer_consume(sb, frames * audio_stream_frame_bytes(ss)); } #endif /* CONFIG_FORMAT_S24LE */ #if CONFIG_FORMAT_S32LE static void fill_source_s32(struct test_data *td, int frames_max) { + struct processing_module *mod = comp_get_drvdata(td->dev); struct comp_dev *dev = td->dev; struct comp_buffer *sb; struct audio_stream *ss; @@ -318,10 +352,13 @@ static void fill_source_s32(struct test_data *td, int frames_max) bytes_total = samples_processed * audio_stream_sample_bytes(ss); comp_update_buffer_produce(sb, bytes_total); } + + mod->input_buffers[0].size = samples_processed / ss->channels; } static void verify_sink_s32(struct test_data *td) { + struct processing_module *mod = comp_get_drvdata(td->dev); struct comp_dev *dev = td->dev; struct comp_buffer *sb; struct audio_stream *ss; @@ -330,13 +367,11 @@ static void verify_sink_s32(struct test_data *td) int32_t out; int32_t *x; int samples; - int frames; int i; sb = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); ss = &sb->stream; - frames = audio_stream_get_avail_frames(ss); - samples = frames * ss->channels; + samples = mod->output_buffers[0].size >> 2; for (i = 0; i < samples; i++) { x = audio_stream_read_frag_s32(ss, i); out = *x; @@ -345,9 +380,6 @@ static void verify_sink_s32(struct test_data *td) if (delta > ERROR_TOLERANCE_S32 || delta < -ERROR_TOLERANCE_S32) assert_int_equal(out, ref); } - - if (frames > 0) - comp_update_buffer_consume(sb, frames * audio_stream_frame_bytes(ss)); } #endif /* CONFIG_FORMAT_S32LE */ @@ -366,6 +398,8 @@ static int frames_jitter(int frames) static void test_audio_eq_iir(void **state) { struct test_data *td = *state; + struct processing_module *mod = comp_get_drvdata(td->dev); + struct comp_buffer *source = td->source; struct comp_buffer *sink = td->sink; int ret; @@ -390,9 +424,14 @@ static void test_audio_eq_iir(void **state) break; } - ret = comp_copy(td->dev); + mod->input_buffers[0].consumed = 0; + mod->output_buffers[0].size = 0; + ret = module_process(mod, mod->input_buffers, 1, mod->output_buffers, 1); assert_int_equal(ret, 0); + 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) { case SOF_IPC_FRAME_S16_LE: verify_sink_s16(td); @@ -407,6 +446,8 @@ static void test_audio_eq_iir(void **state) assert(0); break; } + + comp_update_buffer_consume(sink, mod->output_buffers[0].size); } } diff --git a/tools/tplg_parser/process.c b/tools/tplg_parser/process.c index d0c3fc339db8..d24e5d5b4f56 100644 --- a/tools/tplg_parser/process.c +++ b/tools/tplg_parser/process.c @@ -385,10 +385,12 @@ int tplg_create_process(struct tplg_context *ctx, /* configure asrc */ process->comp.hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_COMP_NEW; process->comp.id = comp_id; - process->comp.hdr.size = sizeof(struct sof_ipc_comp_asrc); + process->comp.hdr.size = sizeof(struct sof_ipc_comp_process) + UUID_SIZE; process->comp.type = tplg_get_process_type(process->type); process->comp.pipeline_id = ctx->pipeline_id; process->config.hdr.size = sizeof(struct sof_ipc_comp_config); + process->comp.ext_data_length = UUID_SIZE; + memcpy(process + 1, comp_ext, UUID_SIZE); free(array); return 0; @@ -397,14 +399,14 @@ int tplg_create_process(struct tplg_context *ctx, static int process_init_data(struct sof_ipc_comp_process **process_ipc, struct sof_ipc_comp_process *process) { - *process_ipc = malloc(sizeof(struct sof_ipc_comp_process)); + *process_ipc = malloc(sizeof(struct sof_ipc_comp_process) + UUID_SIZE); if (!(*process_ipc)) { fprintf(stderr, "error: Failed to allocate IPC\n"); return -errno; } /* Copy header */ - memcpy(*process_ipc, process, sizeof(struct sof_ipc_comp_process)); + memcpy(*process_ipc, process, sizeof(struct sof_ipc_comp_process) + UUID_SIZE); (*process_ipc)->size = 0; return 0; } @@ -424,7 +426,7 @@ static int process_append_data(struct sof_ipc_comp_process **process_ipc, } /* Size is process IPC plus private data minus ABI header */ - ipc_size = sizeof(struct sof_ipc_comp_process); + ipc_size = sizeof(struct sof_ipc_comp_process) + UUID_SIZE; if (ctl->ops.info == SND_SOC_TPLG_CTL_BYTES) { bytes_ctl = (struct snd_soc_tplg_bytes_control *)ctl; size = bytes_ctl->priv.size - sizeof(struct sof_abi_hdr); @@ -437,10 +439,10 @@ static int process_append_data(struct sof_ipc_comp_process **process_ipc, } /* Copy header */ - memcpy(*process_ipc, process, sizeof(struct sof_ipc_comp_process)); + memcpy(*process_ipc, process, sizeof(struct sof_ipc_comp_process) + UUID_SIZE); /* Copy configuration data, need to strip ABI header*/ - memcpy((char *)*process_ipc + sizeof(struct sof_ipc_comp_process), + memcpy((char *)*process_ipc + sizeof(struct sof_ipc_comp_process) + UUID_SIZE, priv_data + sizeof(struct sof_abi_hdr), size); (*process_ipc)->size = size; return 0; @@ -451,7 +453,7 @@ int load_process(struct tplg_context *ctx) { struct sof *sof = ctx->sof; struct snd_soc_tplg_dapm_widget *widget = ctx->widget; - struct sof_ipc_comp_process process = {0}; + struct sof_ipc_comp_process *process; struct sof_ipc_comp_process *process_ipc = NULL; struct snd_soc_tplg_ctl_hdr *ctl = NULL; struct sof_ipc_comp_ext comp_ext; @@ -459,14 +461,15 @@ int load_process(struct tplg_context *ctx) int ret = 0; int i; - ret = tplg_create_process(ctx, &process, &comp_ext); - if (ret < 0) - return ret; + process = malloc(sizeof(*process) + UUID_SIZE); + if (!process) + return -ENOMEM; - printf("debug uuid:\n"); - for (i = 0; i < SOF_UUID_SIZE; i++) - printf("%u ", comp_ext.uuid[i]); - printf("\n"); + memset(process, 0, sizeof(*process) + UUID_SIZE); + + ret = tplg_create_process(ctx, process, &comp_ext); + if (ret < 0) + goto err; /* Get control into ctl and priv_data */ for (i = 0; i < widget->num_kcontrols; i++) { @@ -474,27 +477,27 @@ int load_process(struct tplg_context *ctx) if (ret < 0) { fprintf(stderr, "error: failed control load\n"); - return ret; + goto err; } /* Merge process and priv_data into process_ipc */ if (priv_data) - ret = process_append_data(&process_ipc, &process, ctl, priv_data); + ret = process_append_data(&process_ipc, process, ctl, priv_data); free(ctl); free(priv_data); if (ret) { fprintf(stderr, "error: private data append failed\n"); free(process_ipc); - return ret; + goto err; } } /* Default IPC without appended data */ if (!process_ipc) { - ret = process_init_data(&process_ipc, &process); + ret = process_init_data(&process_ipc, process); if (ret) - return ret; + goto err; } /* load process component */ @@ -507,5 +510,7 @@ int load_process(struct tplg_context *ctx) if (ret < 0) fprintf(stderr, "error: new process comp\n"); +err: + free(process); return ret; } diff --git a/zephyr/wrapper.c b/zephyr/wrapper.c index ba90e0e07e27..5a2b771eb43b 100644 --- a/zephyr/wrapper.c +++ b/zephyr/wrapper.c @@ -452,7 +452,7 @@ void sys_comp_eq_fir_init(void); void sys_comp_keyword_init(void); void sys_comp_asrc_init(void); void sys_comp_dcblock_init(void); -void sys_comp_eq_iir_init(void); +void sys_comp_module_eq_iir_interface_init(void); void sys_comp_kpb_init(void); void sys_comp_smart_amp_init(void); void sys_comp_basefw_init(void); @@ -552,7 +552,7 @@ int task_main_start(struct sof *sof) sys_comp_eq_fir_init(); if (IS_ENABLED(CONFIG_COMP_IIR)) - sys_comp_eq_iir_init(); + sys_comp_module_eq_iir_interface_init(); if (IS_ENABLED(CONFIG_SAMPLE_KEYPHRASE)) sys_comp_keyword_init();