diff --git a/src/audio/CMakeLists.txt b/src/audio/CMakeLists.txt index daa529e42001..2494c7ba578e 100644 --- a/src/audio/CMakeLists.txt +++ b/src/audio/CMakeLists.txt @@ -185,6 +185,7 @@ if(CONFIG_IPC_MAJOR_3) set(tdfb_sources multiband_drc/multiband_drc_ipc3.c) set(dcblock_sources dcblock/dcblock_ipc3.c) set(mux_sources mux/mux_ipc3.c) + set(crossover_sources crossover/crossover_ipc3.c) elseif(CONFIG_IPC_MAJOR_4) set(volume_sources volume/volume.c volume/volume_generic.c volume/volume_ipc4.c) set(asrc_sources asrc/asrc_ipc4.c) @@ -195,6 +196,7 @@ elseif(CONFIG_IPC_MAJOR_4) set(tdfb_sources multiband_drc/multiband_drc_ipc4.c) set(dcblock_sources dcblock/dcblock_ipc4.c) set(mux_sources mux/mux_ipc4.c) + set(crossover_sources crossover/crossover_ipc4.c) endif() set(mixer_sources ${mixer_src}) set(asrc_sources asrc/asrc.c asrc/asrc_farrow.c asrc/asrc_farrow_generic.c) @@ -204,7 +206,7 @@ set(dcblock_sources dcblock/dcblock.c dcblock/dcblock_generic.c dcblock/dcblock_ set(crossover_sources crossover/crossover.c crossover/crossover_generic.c) set(tdfb_sources tdfb/tdfb.c tdfb/tdfb_generic.c tdfb/tdfb_direction.c) set(drc_sources drc/drc.c drc/drc_generic.c drc/drc_math_generic.c) -set(multiband_drc_sources multiband_drc/multiband_drc_generic.c crossover/crossover.c crossover/crossover_generic.c drc/drc.c drc/drc_generic.c drc/drc_math_generic.c multiband_drc/multiband_drc.c ) +set(multiband_drc_sources multiband_drc/multiband_drc_generic.c crossover/crossover.c drc/drc.c drc/drc_generic.c drc/drc_math_generic.c multiband_drc/multiband_drc.c ) set(mfcc_sources mfcc/mfcc.c mfcc/mfcc_setup.c mfcc/mfcc_common.c mfcc/mfcc_generic.c mfcc/mfcc_hifi4.c mfcc/mfcc_hifi3.c) set(mux_sources mux/mux.c mux/mux_generic.c) diff --git a/src/audio/crossover/CMakeLists.txt b/src/audio/crossover/CMakeLists.txt index 15a68035621e..c58c01460cd7 100644 --- a/src/audio/crossover/CMakeLists.txt +++ b/src/audio/crossover/CMakeLists.txt @@ -1,2 +1,7 @@ add_local_sources(sof crossover.c) add_local_sources(sof crossover_generic.c) +if(CONFIG_IPC_MAJOR_3) + add_local_sources(sof crossover_ipc3.c) +elseif(CONFIG_IPC_MAJOR_4) + add_local_sources(sof crossover_ipc4.c) +endif() diff --git a/src/audio/crossover/crossover.c b/src/audio/crossover/crossover.c index 4e89a9d05042..4bb0be6f239f 100644 --- a/src/audio/crossover/crossover.c +++ b/src/audio/crossover/crossover.c @@ -11,8 +11,7 @@ #include #include #include -#include -#include +#include #include #include #include @@ -30,13 +29,15 @@ #include #include #include -#include #include #include #include #include #include +#include "crossover_user.h" +#include "crossover.h" + LOG_MODULE_REGISTER(crossover, CONFIG_SOF_LOG_LEVEL); /* 948c9ad1-806a-4131-ad6c-b2bda9e35a9f */ @@ -45,43 +46,11 @@ DECLARE_SOF_RT_UUID("crossover", crossover_uuid, 0x948c9ad1, 0x806a, 0x4131, DECLARE_TR_CTX(crossover_tr, SOF_UUID(crossover_uuid), LOG_LEVEL_INFO); -static inline void crossover_free_config(struct sof_crossover_config **config) -{ - rfree(*config); - *config = NULL; -} - -/** - * \brief Reset the state of an LR4 filter. - */ -static inline void crossover_reset_state_lr4(struct iir_state_df2t *lr4) -{ - rfree(lr4->coef); - rfree(lr4->delay); - - lr4->coef = NULL; - lr4->delay = NULL; -} - -/** - * \brief Reset the state (coefficients and delay) of the crossover filter - * of a single channel. - */ -inline void crossover_reset_state_ch(struct crossover_state *ch_state) -{ - int i; - - for (i = 0; i < CROSSOVER_MAX_LR4; i++) { - crossover_reset_state_lr4(&ch_state->lowpass[i]); - crossover_reset_state_lr4(&ch_state->highpass[i]); - } -} - /** * \brief Reset the state (coefficients and delay) of the crossover filter * across all channels */ -static inline void crossover_reset_state(struct comp_data *cd) +static void crossover_reset_state(struct comp_data *cd) { int i; @@ -97,8 +66,8 @@ static inline void crossover_reset_state(struct comp_data *cd) * \return the position at which pipe_id is found in config->assign_sink. * -EINVAL if not found. */ -static int crossover_get_stream_index(struct processing_module *mod, - struct sof_crossover_config *config, uint32_t pipe_id) +int crossover_get_stream_index(struct processing_module *mod, + struct sof_crossover_config *config, uint32_t pipe_id) { int i; uint32_t *assign_sink = config->assign_sink; @@ -142,11 +111,7 @@ static int crossover_assign_sinks(struct processing_module *mod, unsigned int sink_id, state; sink = container_of(sink_list, struct comp_buffer, source_list); -#if CONFIG_IPC_MAJOR_4 - sink_id = cd->output_pin_index[j]; -#else - sink_id = sink->pipeline_id; -#endif + sink_id = crossover_get_sink_id(cd, sink->pipeline_id, j); state = sink->sink->state; if (state != dev->state) { j++; @@ -326,42 +291,6 @@ static int crossover_setup(struct processing_module *mod, int nch) return ret; } -#if CONFIG_IPC_MAJOR_4 -/* Note: Crossover needs to have in the rimage manifest the init_config set to 1 to let - * kernel know that the base_cfg_ext needs to be appended to the IPC payload. The - * Extension is needed to know the output pin indices. - */ -static int crossover_init_output_pins(struct processing_module *mod) -{ - struct comp_data *cd = module_get_private_data(mod); - struct comp_dev *dev = mod->dev; - const struct ipc4_base_module_extended_cfg *base_cfg = mod->priv.cfg.init_data; - uint16_t num_input_pins = base_cfg->base_cfg_ext.nb_input_pins; - uint16_t num_output_pins = base_cfg->base_cfg_ext.nb_output_pins; - struct ipc4_input_pin_format *input_pin; - struct ipc4_output_pin_format *output_pin; - int i; - - comp_dbg(dev, "Number of input pins %u, output pins %u", num_input_pins, num_output_pins); - - if (num_input_pins != 1 || num_output_pins > SOF_CROSSOVER_MAX_STREAMS) { - comp_err(dev, "Illegal number of pins %u %u", num_input_pins, num_output_pins); - return -EINVAL; - } - - input_pin = (struct ipc4_input_pin_format *)base_cfg->base_cfg_ext.pin_formats; - output_pin = (struct ipc4_output_pin_format *)(input_pin + 1); - cd->num_output_pins = num_output_pins; - comp_dbg(dev, "input pin index = %u", input_pin->pin_index); - for (i = 0; i < num_output_pins; i++) { - comp_dbg(dev, "output pin %d index = %u", i, output_pin[i].pin_index); - cd->output_pin_index[i] = output_pin[i].pin_index; - } - - return 0; -} -#endif - /** * \brief Creates a Crossover Filter component. * \return Pointer to Crossover Filter component device. @@ -405,13 +334,11 @@ static int crossover_init(struct processing_module *mod) goto cd_fail; } -#if CONFIG_IPC_MAJOR_4 - ret = crossover_init_output_pins(mod); + ret = crossover_output_pin_init(mod); if (ret < 0) { comp_err(dev, "crossover_init(): crossover_init_output_pins() failed."); goto cd_fail; } -#endif crossover_reset_state(cd); return 0; @@ -439,82 +366,6 @@ static int crossover_free(struct processing_module *mod) return 0; } -#if CONFIG_IPC_MAJOR_4 -/** - * \brief Check sink streams configuration for matching pin index for output pins - */ -static int crossover_check_sink_assign(struct processing_module *mod, - struct sof_crossover_config *config) -{ - struct comp_data *cd = module_get_private_data(mod); - struct comp_dev *dev = mod->dev; - uint32_t pin_index; - int num_assigned_sinks = 0; - int i, j; - uint8_t assigned_sinks[SOF_CROSSOVER_MAX_STREAMS] = {0}; - - for (j = 0; j < cd->num_output_pins; j++) { - pin_index = cd->output_pin_index[j]; - i = crossover_get_stream_index(mod, config, pin_index); - if (i < 0) { - comp_warn(dev, "crossover_check_sink_assign(), could not assign sink %u", - pin_index); - break; - } - - if (assigned_sinks[i]) { - comp_warn(dev, "crossover_check_sink_assign(), multiple sinks from pin %u are assigned", - pin_index); - break; - } - - assigned_sinks[i] = true; - num_assigned_sinks++; - } - - return num_assigned_sinks; -} -#else -/** - * \brief Check sink streams configuration for matching pipeline IDs - */ -static int crossover_check_sink_assign(struct processing_module *mod, - struct sof_crossover_config *config) -{ - struct comp_dev *dev = mod->dev; - struct comp_buffer *sink; - struct list_item *sink_list; - int num_assigned_sinks = 0; - uint8_t assigned_sinks[SOF_CROSSOVER_MAX_STREAMS] = {0}; - int i; - - list_for_item(sink_list, &dev->bsink_list) { - unsigned int pipeline_id; - - sink = container_of(sink_list, struct comp_buffer, source_list); - pipeline_id = sink->pipeline_id; - - i = crossover_get_stream_index(mod, config, pipeline_id); - if (i < 0) { - comp_warn(dev, "crossover_check_sink_assign(), could not assign sink %d", - pipeline_id); - break; - } - - if (assigned_sinks[i]) { - comp_warn(dev, "crossover_check_sink_assign(), multiple sinks from pipeline %d are assigned", - pipeline_id); - break; - } - - assigned_sinks[i] = true; - num_assigned_sinks++; - } - - return num_assigned_sinks; -} -#endif - /** * \brief Verifies that the config is formatted correctly. * @@ -563,20 +414,13 @@ static int crossover_set_config(struct processing_module *mod, uint32_t config_i size_t response_size) { struct comp_data *cd = module_get_private_data(mod); + int ret; comp_info(mod->dev, "crossover_set_config()"); -#if CONFIG_IPC_MAJOR_3 - /* TODO: This check seems to work only for IPC3, FW crash happens from reject from - * topology embedded blob. - */ - struct sof_ipc_ctrl_data *cdata = (struct sof_ipc_ctrl_data *)fragment; - - if (cdata->cmd != SOF_CTRL_CMD_BINARY) { - comp_err(mod->dev, "crossover_set_config(), invalid command"); - return -EINVAL; - } -#endif + ret = crossover_check_config(mod, fragment); + if (ret < 0) + return ret; return comp_data_blob_set(cd->model_handler, pos, data_offset_size, fragment, fragment_size); @@ -588,16 +432,13 @@ static int crossover_get_config(struct processing_module *mod, { struct comp_data *cd = module_get_private_data(mod); struct sof_ipc_ctrl_data *cdata = (struct sof_ipc_ctrl_data *)fragment; + int ret; comp_info(mod->dev, "crossover_get_config()"); -#if CONFIG_IPC_MAJOR_3 - - if (cdata->cmd != SOF_CTRL_CMD_BINARY) { - comp_err(mod->dev, "crossover_get_config(), invalid command"); - return -EINVAL; - } -#endif + ret = crossover_check_config(mod, fragment); + if (ret < 0) + return ret; return comp_data_blob_get_cmd(cd->model_handler, cdata, fragment_size); } @@ -678,32 +519,6 @@ static int crossover_process_audio_stream(struct processing_module *mod, return 0; } -#if CONFIG_IPC_MAJOR_4 -/** - * \brief IPC4 specific component prepare, updates source and sink buffers formats from base_cfg - */ -static void crossover_params(struct processing_module *mod) -{ - struct sof_ipc_stream_params *params = mod->stream_params; - struct comp_buffer *sinkb, *sourceb; - struct list_item *sink_list; - struct comp_dev *dev = mod->dev; - - comp_dbg(dev, "crossover_params()"); - - ipc4_base_module_cfg_to_stream_params(&mod->priv.cfg.base_cfg, params); - component_set_nearest_period_frames(dev, params->rate); - - sourceb = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); - ipc4_update_buffer_format(sourceb, &mod->priv.cfg.base_cfg.audio_fmt); - - list_for_item(sink_list, &dev->bsink_list) { - sinkb = container_of(sink_list, struct comp_buffer, source_list); - ipc4_update_buffer_format(sinkb, &mod->priv.cfg.base_cfg.audio_fmt); - } -} -#endif - /** * \brief Prepares Crossover Filter component for processing. * \param[in,out] dev Crossover Filter base component device. @@ -722,9 +537,7 @@ static int crossover_prepare(struct processing_module *mod, comp_info(dev, "crossover_prepare()"); -#if CONFIG_IPC_MAJOR_4 crossover_params(mod); -#endif /* Crossover has a variable number of sinks */ mod->max_sinks = SOF_CROSSOVER_MAX_STREAMS; diff --git a/src/include/sof/audio/crossover/crossover.h b/src/audio/crossover/crossover.h similarity index 76% rename from src/include/sof/audio/crossover/crossover.h rename to src/audio/crossover/crossover.h index cefe7de9271e..f193c058a375 100644 --- a/src/include/sof/audio/crossover/crossover.h +++ b/src/audio/crossover/crossover.h @@ -9,25 +9,15 @@ #include #include +#include #include -#include #include +#include "crossover_user.h" + struct comp_buffer; struct comp_dev; -/* Maximum number of LR4 highpass OR lowpass filters */ -#define CROSSOVER_MAX_LR4 3 -/* Number of delay slots allocated for LR4 Filters */ -#define CROSSOVER_NUM_DELAYS_LR4 4 - -/* Number of sinks for a 2 way crossover filter */ -#define CROSSOVER_2WAY_NUM_SINKS 2 -/* Number of sinks for a 3 way crossover filter */ -#define CROSSOVER_3WAY_NUM_SINKS 3 -/* Number of sinks for a 4 way crossover filter */ -#define CROSSOVER_4WAY_NUM_SINKS 4 - /** * The Crossover filter will have from 2 to 4 outputs. * Diagram of a 4-way Crossover filter (6 LR4 Filters). @@ -58,15 +48,6 @@ struct comp_dev; * */ -/** - * Stores the state of one channel of the Crossover filter - */ -struct crossover_state { - /* Store the state for each LR4 filter. */ - struct iir_state_df2t lowpass[CROSSOVER_MAX_LR4]; - struct iir_state_df2t highpass[CROSSOVER_MAX_LR4]; -}; - struct comp_data; typedef void (*crossover_process)(struct comp_data *cd, @@ -75,9 +56,6 @@ typedef void (*crossover_process)(struct comp_data *cd, int32_t num_sinks, uint32_t frames); -typedef void (*crossover_split)(int32_t in, int32_t out[], - struct crossover_state *state); - /* Crossover component private data */ struct comp_data { /**< filter state */ @@ -137,18 +115,6 @@ static inline crossover_process extern const crossover_split crossover_split_fnmap[]; extern const size_t crossover_split_fncount; -/** - * \brief Returns Crossover split function. - */ -static inline crossover_split crossover_find_split_func(int32_t num_sinks) -{ - if (num_sinks < CROSSOVER_2WAY_NUM_SINKS || - num_sinks > CROSSOVER_4WAY_NUM_SINKS) - return NULL; - // The functions in the map are offset by 2 indices. - return crossover_split_fnmap[num_sinks - CROSSOVER_2WAY_NUM_SINKS]; -} - /* * \brief Runs input in through the LR4 filter and returns it's output. */ @@ -159,4 +125,19 @@ static inline int32_t crossover_generic_process_lr4(int32_t in, return iir_df2t(lr4, in); } +static inline void crossover_free_config(struct sof_crossover_config **config) +{ + rfree(*config); + *config = NULL; +} + +int crossover_get_sink_id(struct comp_data *cd, uint32_t pipeline_id, uint32_t index); +int crossover_output_pin_init(struct processing_module *mod); +int crossover_check_sink_assign(struct processing_module *mod, + struct sof_crossover_config *config); +int crossover_check_config(struct processing_module *mod, const uint8_t *fragment); +void crossover_params(struct processing_module *mod); +int crossover_get_stream_index(struct processing_module *mod, + struct sof_crossover_config *config, uint32_t pipe_id); + #endif // __SOF_AUDIO_CROSSOVER_CROSSOVER_H__ diff --git a/src/audio/crossover/crossover_generic.c b/src/audio/crossover/crossover_generic.c index 0823ce85920f..694588b59f49 100644 --- a/src/audio/crossover/crossover_generic.c +++ b/src/audio/crossover/crossover_generic.c @@ -7,11 +7,12 @@ #include #include #include -#include #include #include #include +#include "crossover.h" + /* * \brief Splits x into two based on the coefficients set in the lp * and hp filters. The output of the lp is in y1, the output of diff --git a/src/audio/crossover/crossover_ipc3.c b/src/audio/crossover/crossover_ipc3.c new file mode 100644 index 000000000000..ea8fd32d02ef --- /dev/null +++ b/src/audio/crossover/crossover_ipc3.c @@ -0,0 +1,91 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2020 Google LLC. All rights reserved. +// +// Author: Sebastiano Carlucci + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "crossover_user.h" +#include "crossover.h" + +LOG_MODULE_DECLARE(crossover, CONFIG_SOF_LOG_LEVEL); + +int crossover_get_sink_id(struct comp_data *cd, uint32_t pipeline_id, uint32_t index) +{ + return pipeline_id; +} + +int crossover_output_pin_init(struct processing_module *mod) +{ + return 0; +} + +/** + * \brief Check sink streams configuration for matching pipeline IDs + */ +int crossover_check_sink_assign(struct processing_module *mod, + struct sof_crossover_config *config) +{ + struct comp_dev *dev = mod->dev; + struct comp_buffer *sink; + struct list_item *sink_list; + int num_assigned_sinks = 0; + uint8_t assigned_sinks[SOF_CROSSOVER_MAX_STREAMS] = {0}; + int i; + + list_for_item(sink_list, &dev->bsink_list) { + unsigned int pipeline_id; + + sink = container_of(sink_list, struct comp_buffer, source_list); + pipeline_id = sink->pipeline_id; + + i = crossover_get_stream_index(mod, config, pipeline_id); + if (i < 0) { + comp_warn(dev, "crossover_check_sink_assign(), could not assign sink %d", + pipeline_id); + break; + } + + if (assigned_sinks[i]) { + comp_warn(dev, "crossover_check_sink_assign(), multiple sinks from pipeline %d are assigned", + pipeline_id); + break; + } + + assigned_sinks[i] = true; + num_assigned_sinks++; + } + + return num_assigned_sinks; +} + +int crossover_check_config(struct processing_module *mod, const uint8_t *fragment) +{ + /* TODO: This check seems to work only for IPC3, FW crash happens from reject from + * topology embedded blob. + */ + struct sof_ipc_ctrl_data *cdata = (struct sof_ipc_ctrl_data *)fragment; + + if (cdata->cmd != SOF_CTRL_CMD_BINARY) { + comp_err(mod->dev, "crossover_set/get_config(), invalid command"); + return -EINVAL; + } + + return 0; +} + +/** + * \brief IPC4 specific component prepare, updates source and sink buffers formats from base_cfg + */ +void crossover_params(struct processing_module *mod) +{ +} diff --git a/src/audio/crossover/crossover_ipc4.c b/src/audio/crossover/crossover_ipc4.c new file mode 100644 index 000000000000..d0a8fe4adab2 --- /dev/null +++ b/src/audio/crossover/crossover_ipc4.c @@ -0,0 +1,129 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2020 Google LLC. All rights reserved. +// +// Author: Sebastiano Carlucci + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "crossover_user.h" +#include "crossover.h" + +LOG_MODULE_DECLARE(crossover, CONFIG_SOF_LOG_LEVEL); + +int crossover_get_sink_id(struct comp_data *cd, uint32_t pipeline_id, uint32_t index) +{ + return cd->output_pin_index[index]; +} + +/* Note: Crossover needs to have in the rimage manifest the init_config set to 1 to let + * kernel know that the base_cfg_ext needs to be appended to the IPC payload. The + * Extension is needed to know the output pin indices. + */ +int crossover_init_output_pins(struct processing_module *mod) +{ + struct comp_data *cd = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; + const struct ipc4_base_module_extended_cfg *base_cfg = mod->priv.cfg.init_data; + uint16_t num_input_pins = base_cfg->base_cfg_ext.nb_input_pins; + uint16_t num_output_pins = base_cfg->base_cfg_ext.nb_output_pins; + struct ipc4_input_pin_format *input_pin; + struct ipc4_output_pin_format *output_pin; + int i; + + comp_dbg(dev, "Number of input pins %u, output pins %u", num_input_pins, num_output_pins); + + if (num_input_pins != 1 || num_output_pins > SOF_CROSSOVER_MAX_STREAMS) { + comp_err(dev, "Illegal number of pins %u %u", num_input_pins, num_output_pins); + return -EINVAL; + } + + input_pin = (struct ipc4_input_pin_format *)base_cfg->base_cfg_ext.pin_formats; + output_pin = (struct ipc4_output_pin_format *)(input_pin + 1); + cd->num_output_pins = num_output_pins; + comp_dbg(dev, "input pin index = %u", input_pin->pin_index); + for (i = 0; i < num_output_pins; i++) { + comp_dbg(dev, "output pin %d index = %u", i, output_pin[i].pin_index); + cd->output_pin_index[i] = output_pin[i].pin_index; + } + + return 0; +} + +int crossover_output_pin_init(struct processing_module *mod) +{ + return crossover_init_output_pins(mod); +} + +/** + * \brief Check sink streams configuration for matching pin index for output pins + */ +int crossover_check_sink_assign(struct processing_module *mod, + struct sof_crossover_config *config) +{ + struct comp_data *cd = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; + uint32_t pin_index; + int num_assigned_sinks = 0; + int i, j; + uint8_t assigned_sinks[SOF_CROSSOVER_MAX_STREAMS] = {0}; + + for (j = 0; j < cd->num_output_pins; j++) { + pin_index = cd->output_pin_index[j]; + i = crossover_get_stream_index(mod, config, pin_index); + if (i < 0) { + comp_warn(dev, "crossover_check_sink_assign(), could not assign sink %u", + pin_index); + break; + } + + if (assigned_sinks[i]) { + comp_warn(dev, "crossover_check_sink_assign(), multiple sinks from pin %u are assigned", + pin_index); + break; + } + + assigned_sinks[i] = true; + num_assigned_sinks++; + } + + return num_assigned_sinks; +} + +int crossover_check_config(struct processing_module *mod, const uint8_t *fragment) +{ + return 0; +} + +/** + * \brief IPC4 specific component prepare, updates source and sink buffers formats from base_cfg + */ +void crossover_params(struct processing_module *mod) +{ + struct sof_ipc_stream_params *params = mod->stream_params; + struct comp_buffer *sinkb, *sourceb; + struct list_item *sink_list; + struct comp_dev *dev = mod->dev; + + comp_dbg(dev, "crossover_params()"); + + ipc4_base_module_cfg_to_stream_params(&mod->priv.cfg.base_cfg, params); + component_set_nearest_period_frames(dev, params->rate); + + sourceb = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); + ipc4_update_buffer_format(sourceb, &mod->priv.cfg.base_cfg.audio_fmt); + + list_for_item(sink_list, &dev->bsink_list) { + sinkb = container_of(sink_list, struct comp_buffer, source_list); + ipc4_update_buffer_format(sinkb, &mod->priv.cfg.base_cfg.audio_fmt); + } +} diff --git a/src/include/user/crossover.h b/src/audio/crossover/crossover_user.h similarity index 97% rename from src/include/user/crossover.h rename to src/audio/crossover/crossover_user.h index 445e48acfed2..5f6ba2b14044 100644 --- a/src/include/user/crossover.h +++ b/src/audio/crossover/crossover_user.h @@ -10,9 +10,7 @@ #include #include - -/* Maximum Number of sinks allowed in config */ -#define SOF_CROSSOVER_MAX_STREAMS 4 +#include /* Maximum number allowed in configuration blob */ #define SOF_CROSSOVER_MAX_SIZE 1024 diff --git a/src/audio/multiband_drc/multiband_drc.c b/src/audio/multiband_drc/multiband_drc.c index 17e68a46cb40..5454df29318a 100644 --- a/src/audio/multiband_drc/multiband_drc.c +++ b/src/audio/multiband_drc/multiband_drc.c @@ -5,7 +5,6 @@ // Author: Pin-chih Lin #include -#include #include #include #include @@ -14,6 +13,7 @@ #include #include #include +#include #include #include #include diff --git a/src/audio/multiband_drc/multiband_drc.h b/src/audio/multiband_drc/multiband_drc.h index 45e7e6b3e8ff..a1801f27ab6c 100644 --- a/src/audio/multiband_drc/multiband_drc.h +++ b/src/audio/multiband_drc/multiband_drc.h @@ -8,7 +8,7 @@ #define __SOF_AUDIO_MULTIBAND_DRC_MULTIBAND_DRC_H__ #include -#include +#include #include #include #include diff --git a/src/audio/multiband_drc/user/multiband_drc.h b/src/audio/multiband_drc/user/multiband_drc.h index 2422e6304fd5..ef07c33a00fd 100644 --- a/src/audio/multiband_drc/user/multiband_drc.h +++ b/src/audio/multiband_drc/user/multiband_drc.h @@ -9,8 +9,8 @@ #define __USER_MULTIBAND_DRC_H__ #include -#include #include +#include #include "../../drc/drc_user.h" diff --git a/src/include/module/crossover/crossover_common.h b/src/include/module/crossover/crossover_common.h new file mode 100644 index 000000000000..6cd4acddf85d --- /dev/null +++ b/src/include/module/crossover/crossover_common.h @@ -0,0 +1,84 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2023 Intel Corporation. All rights reserved. + * + * Author: Sebastiano Carlucci + */ + +#ifndef __SOF_CROSSOVER_COMMON_H__ +#define __SOF_CROSSOVER_COMMON_H__ + +#include +#include + +/* Number of sinks for a 2 way crossover filter */ +#define CROSSOVER_2WAY_NUM_SINKS 2 +/* Number of sinks for a 3 way crossover filter */ +#define CROSSOVER_3WAY_NUM_SINKS 3 +/* Number of sinks for a 4 way crossover filter */ +#define CROSSOVER_4WAY_NUM_SINKS 4 +/* Number of delay slots allocated for LR4 Filters */ +#define CROSSOVER_NUM_DELAYS_LR4 4 +/* Maximum number of LR4 highpass OR lowpass filters */ +#define CROSSOVER_MAX_LR4 3 +/* Maximum Number of sinks allowed in config */ +#define SOF_CROSSOVER_MAX_STREAMS 4 + +/** + * Stores the state of one channel of the Crossover filter + */ +struct crossover_state { + /* Store the state for each LR4 filter. */ + struct iir_state_df2t lowpass[CROSSOVER_MAX_LR4]; + struct iir_state_df2t highpass[CROSSOVER_MAX_LR4]; +}; + +typedef void (*crossover_split)(int32_t in, int32_t out[], + struct crossover_state *state); + +extern const crossover_split crossover_split_fnmap[]; + +/* crossover init function */ +int crossover_init_coef_ch(struct sof_eq_iir_biquad *coef, + struct crossover_state *ch_state, + int32_t num_sinks); + +/** + * \brief Reset the state of an LR4 filter. + */ +static inline void crossover_reset_state_lr4(struct iir_state_df2t *lr4) +{ + rfree(lr4->coef); + rfree(lr4->delay); + + lr4->coef = NULL; + lr4->delay = NULL; +} + +/** + * \brief Reset the state (coefficients and delay) of the crossover filter + * of a single channel. + */ +static inline void crossover_reset_state_ch(struct crossover_state *ch_state) +{ + int i; + + for (i = 0; i < CROSSOVER_MAX_LR4; i++) { + crossover_reset_state_lr4(&ch_state->lowpass[i]); + crossover_reset_state_lr4(&ch_state->highpass[i]); + } +} + +/** + * \brief Returns Crossover split function. + */ +static inline crossover_split crossover_find_split_func(int32_t num_sinks) +{ + if (num_sinks < CROSSOVER_2WAY_NUM_SINKS || + num_sinks > CROSSOVER_4WAY_NUM_SINKS) + return NULL; + // The functions in the map are offset by 2 indices. + return crossover_split_fnmap[num_sinks - CROSSOVER_2WAY_NUM_SINKS]; +} + +#endif /* __SOF_CROSSOVER_COMMON_H__ */ diff --git a/src/include/sof/audio/crossover/crossover_algorithm.h b/src/include/sof/audio/crossover/crossover_algorithm.h deleted file mode 100644 index ab7bcf96e4e2..000000000000 --- a/src/include/sof/audio/crossover/crossover_algorithm.h +++ /dev/null @@ -1,24 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * - * Copyright(c) 2020 Google LLC. All rights reserved. - * - * Author: Pin-chih Lin - */ -#ifndef __SOF_AUDIO_CROSSOVER_CROSSOVER_ALGORITHM_H__ -#define __SOF_AUDIO_CROSSOVER_CROSSOVER_ALGORITHM_H__ - -#include -#include -#include -#include -#include - -/* crossover reset function */ -void crossover_reset_state_ch(struct crossover_state *ch_state); - -/* crossover init function */ -int crossover_init_coef_ch(struct sof_eq_iir_biquad *coef, - struct crossover_state *ch_state, - int32_t num_sinks); - -#endif // __SOF_AUDIO_CROSSOVER_CROSSOVER_ALGORITHM_H__ diff --git a/zephyr/CMakeLists.txt b/zephyr/CMakeLists.txt index 783d5c7e41ff..0959e7012140 100644 --- a/zephyr/CMakeLists.txt +++ b/zephyr/CMakeLists.txt @@ -719,6 +719,16 @@ zephyr_library_sources_ifdef(CONFIG_COMP_CROSSOVER ${SOF_AUDIO_PATH}/crossover/crossover_generic.c ) +if(CONFIG_IPC_MAJOR_3) + zephyr_library_sources_ifdef(CONFIG_COMP_CROSSOVER + ${SOF_AUDIO_PATH}//crossover/crossover_ipc3.c + ) +elseif(CONFIG_IPC_MAJOR_4) + zephyr_library_sources_ifdef(CONFIG_COMP_CROSSOVER + ${SOF_AUDIO_PATH}//crossover/crossover_ipc4.c + ) +endif() + zephyr_library_sources_ifdef(CONFIG_COMP_DRC ${SOF_AUDIO_PATH}/drc/drc.c ${SOF_AUDIO_PATH}/drc/drc_generic.c