diff --git a/app/boards/intel_adsp_ace15_mtpm.conf b/app/boards/intel_adsp_ace15_mtpm.conf index ac1a3c846441..7f0938bbdd5b 100644 --- a/app/boards/intel_adsp_ace15_mtpm.conf +++ b/app/boards/intel_adsp_ace15_mtpm.conf @@ -3,6 +3,7 @@ CONFIG_IPC_MAJOR_4=y CONFIG_COMP_SRC=y CONFIG_COMP_SRC_IPC4_FULL_MATRIX=y +CONFIG_COMP_SRC_LITE=y CONFIG_COMP_DRC=y CONFIG_COMP_CROSSOVER=y CONFIG_COMP_MULTIBAND_DRC=y diff --git a/src/audio/Kconfig b/src/audio/Kconfig index 8c533713419a..b05957a835d3 100644 --- a/src/audio/Kconfig +++ b/src/audio/Kconfig @@ -126,6 +126,18 @@ config COMP_SRC help Select for SRC component +config COMP_SRC_LITE + bool "SRC_LITE component" + default y + help + Select for SRC_LITE component + which only supports a subset of conversions + supported by the SRC module: + 48 -> 16kHz + 44.1 -> 16 kHz + 32 -> 16 kHz + 44.1 -> 48 + config COMP_STUBS bool "Build all selected third-party (3P) components with stubs" default n diff --git a/src/audio/src/coef/src_lite_ipc4_int32_define.h b/src/audio/src/coef/src_lite_ipc4_int32_define.h new file mode 100644 index 000000000000..c690f3c7338f --- /dev/null +++ b/src/audio/src/coef/src_lite_ipc4_int32_define.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2023 Intel Corporation. All rights reserved. + * + * Author: Fabiola Jasinska + */ + +#ifndef __SOF_AUDIO_COEFFICIENTS_SRC_SRC_IPC4_INT32_DEFINE_H__ +#define __SOF_AUDIO_COEFFICIENTS_SRC_SRC_IPC4_INT32_DEFINE_H__ + +/* SRC constants */ +#define MAX_FIR_DELAY_SIZE 730 +#define MAX_OUT_DELAY_SIZE 900 +#define MAX_BLK_IN 80 +#define MAX_BLK_OUT 40 +#define NUM_IN_FS 16 +#define NUM_OUT_FS 10 +#define STAGE1_TIMES_MAX 32 +#define STAGE2_TIMES_MAX 32 +#define STAGE_BUF_SIZE 672 +#define NUM_ALL_COEFFICIENTS 69224 + +#endif /* __SOF_AUDIO_COEFFICIENTS_SRC_SRC_IPC4_INT32_DEFINE_H__ */ diff --git a/src/audio/src/coef/src_lite_ipc4_int32_table.h b/src/audio/src/coef/src_lite_ipc4_int32_table.h new file mode 100644 index 000000000000..add255e6bf2f --- /dev/null +++ b/src/audio/src/coef/src_lite_ipc4_int32_table.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2023 Intel Corporation. All rights reserved. + * + */ + +/** \cond GENERATED_BY_TOOLS_TUNE_SRC */ + +#ifndef __SOF_AUDIO_COEFFICIENTS_SRC_src_IPC4_INT32_TABLE_H__ +#define __SOF_AUDIO_COEFFICIENTS_SRC_src_IPC4_INT32_TABLE_H__ + +/* SRC conversions */ +#include "src_ipc4_int32_1_2_4535_5000.h" +#include "src_ipc4_int32_10_21_3455_5000.h" +#include "src_ipc4_int32_1_3_4535_5000.h" +#include "src_ipc4_int32_3_2_4535_5000.h" +#include "src_ipc4_int32_8_7_4535_5000.h" +#include "src_ipc4_int32_16_21_4535_5000.h" +#include "src_ipc4_int32_20_21_4167_5000.h" +#include "../src.h" +#include + +/* SRC table */ +int32_t src_fir_one = 1073741824; +struct src_stage src_int32_1_1_0_0 = { 0, 0, 1, 1, 1, 1, 1, 0, -1, &src_fir_one }; +struct src_stage src_int32_0_0_0_0 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, &src_fir_one }; +int src_in_fs[3] = { 32000, 44100, 48000}; +int src_out_fs[2] = {16000, 48000}; + +struct src_stage *src_table1[2][3] = { + { &src_int32_1_2_4535_5000, &src_int32_10_21_3455_5000, + &src_int32_1_3_4535_5000 }, + { &src_int32_3_2_4535_5000, &src_int32_8_7_4535_5000, &src_int32_1_1_0_0 } +}; + +struct src_stage *src_table2[2][3] = { + { &src_int32_1_1_0_0, &src_int32_16_21_4535_5000, &src_int32_1_1_0_0 }, + { &src_int32_1_1_0_0, &src_int32_20_21_4167_5000, &src_int32_1_1_0_0 } +}; + +#endif /* __SOF_AUDIO_COEFFICIENTS_SRC_src_IPC4_INT32_TABLE_H__ */ + +/** \endcond */ diff --git a/src/audio/src/src.c b/src/audio/src/src.c index d1966efe5e4e..0be34245189a 100644 --- a/src/audio/src/src.c +++ b/src/audio/src/src.c @@ -41,7 +41,10 @@ #include "src.h" #include "src_config.h" -#if SRC_SHORT || CONFIG_COMP_SRC_TINY +#ifdef SRC_LITE +#include "coef/src_lite_ipc4_int32_define.h" +#include "coef/src_lite_ipc4_int32_table.h" +#elif SRC_SHORT || CONFIG_COMP_SRC_TINY #include "coef/src_tiny_int16_define.h" #include "coef/src_tiny_int16_table.h" #elif CONFIG_COMP_SRC_SMALL @@ -63,34 +66,9 @@ LOG_MODULE_REGISTER(src, CONFIG_SOF_LOG_LEVEL); -/* Calculates the needed FIR delay line length */ -static int src_fir_delay_length(struct src_stage *s) -{ - return s->subfilter_length + (s->num_of_subfilters - 1) * s->idm - + s->blk_in; -} - -/* Calculates the FIR output delay line length */ -static int src_out_delay_length(struct src_stage *s) -{ - return 1 + (s->num_of_subfilters - 1) * s->odm; -} - -/* Returns index of a matching sample rate */ -static int src_find_fs(int fs_list[], int list_length, int fs) -{ - int i; - - for (i = 0; i < list_length; i++) { - if (fs_list[i] == fs) - return i; - } - return -EINVAL; -} - /* Calculates buffers to allocate for a SRC mode */ -static int src_buffer_lengths(struct comp_dev *dev, struct comp_data *cd, - int nch) +int src_buffer_lengths(struct comp_dev *dev, struct comp_data *cd, + int nch) { struct src_stage *stage1; struct src_stage *stage2; @@ -172,15 +150,9 @@ static int src_buffer_lengths(struct comp_dev *dev, struct comp_data *cd, return 0; } -static void src_state_reset(struct src_state *state) -{ - state->fir_delay_size = 0; - state->out_delay_size = 0; -} - -static int init_stages(struct src_stage *stage1, struct src_stage *stage2, - struct polyphase_src *src, struct src_param *p, - int n, int32_t *delay_lines_start) +int init_stages(struct src_stage *stage1, struct src_stage *stage2, + struct polyphase_src *src, struct src_param *p, + int n, int32_t *delay_lines_start) { /* Clear FIR state */ src_state_reset(&src->state1); @@ -244,15 +216,6 @@ static int init_stages(struct src_stage *stage1, struct src_stage *stage2, return 0; } -void src_polyphase_reset(struct polyphase_src *src) -{ - src->number_of_stages = 0; - src->stage1 = NULL; - src->stage2 = NULL; - src_state_reset(&src->state1); - src_state_reset(&src->state2); -} - int src_polyphase_init(struct polyphase_src *src, struct src_param *p, int32_t *delay_lines_start) { @@ -291,16 +254,9 @@ int src_polyphase_init(struct polyphase_src *src, struct src_param *p, return n_stages; } -/* Fallback function */ -int src_fallback(struct comp_data *cd, struct sof_source *source, - struct sof_sink *sink) -{ - return 0; -} - /* Normal 2 stage SRC */ -static int src_2s(struct comp_data *cd, - struct sof_source *source, struct sof_sink *sink) +int src_2s(struct comp_data *cd, + struct sof_source *source, struct sof_sink *sink) { struct src_stage_prm s1; struct src_stage_prm s2; @@ -401,8 +357,8 @@ static int src_2s(struct comp_data *cd, } /* 1 stage SRC for simple conversions */ -static int src_1s(struct comp_data *cd, struct sof_source *source, - struct sof_sink *sink) +int src_1s(struct comp_data *cd, struct sof_source *source, + struct sof_sink *sink) { struct src_stage_prm s1; int ret; @@ -441,8 +397,8 @@ static int src_1s(struct comp_data *cd, struct sof_source *source, } /* A fast copy function for same in and out rate */ -static int src_copy_sxx(struct comp_data *cd, struct sof_source *source, - struct sof_sink *sink) +int src_copy_sxx(struct comp_data *cd, struct sof_source *source, + struct sof_sink *sink) { int frames = cd->param.blk_in; @@ -468,7 +424,7 @@ void src_set_alignment(struct sof_source *source, struct sof_sink *sink) sink_set_alignment_constants(sink, byte_align, frame_align_req); } -static int src_verify_params(struct processing_module *mod) +int src_verify_params(struct processing_module *mod) { struct sof_ipc_stream_params *params = mod->stream_params; struct comp_data *cd = module_get_private_data(mod); @@ -505,9 +461,9 @@ static int src_verify_params(struct processing_module *mod) return ret; } -static bool src_get_copy_limits(struct comp_data *cd, - struct sof_source *source, - struct sof_sink *sink) +bool src_get_copy_limits(struct comp_data *cd, + struct sof_source *source, + struct sof_sink *sink) { struct src_param *sp; struct src_stage *s1; @@ -549,9 +505,9 @@ static bool src_get_copy_limits(struct comp_data *cd, return true; } -static int src_params_general(struct processing_module *mod, - struct sof_source *source, - struct sof_sink *sink) +int src_params_general(struct processing_module *mod, + struct sof_source *source, + struct sof_sink *sink) { struct comp_data *cd = module_get_private_data(mod); struct comp_dev *dev = mod->dev; @@ -652,9 +608,9 @@ static int src_params_general(struct processing_module *mod, return 0; } -static int src_prepare(struct processing_module *mod, - struct sof_source **sources, int num_of_sources, - struct sof_sink **sinks, int num_of_sinks) +int src_prepare(struct processing_module *mod, + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) { int ret; @@ -671,18 +627,18 @@ static int src_prepare(struct processing_module *mod, } -static bool src_is_ready_to_process(struct processing_module *mod, - struct sof_source **sources, int num_of_sources, - struct sof_sink **sinks, int num_of_sinks) +bool src_is_ready_to_process(struct processing_module *mod, + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) { struct comp_data *cd = module_get_private_data(mod); return src_get_copy_limits(cd, sources[0], sinks[0]); } -static int src_process(struct processing_module *mod, - struct sof_source **sources, int num_of_sources, - struct sof_sink **sinks, int num_of_sinks) +int src_process(struct processing_module *mod, + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) { struct comp_data *cd = module_get_private_data(mod); @@ -697,21 +653,21 @@ static int src_process(struct processing_module *mod, return cd->src_func(cd, sources[0], sinks[0]); } -static int src_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) +int src_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) { return -EINVAL; } -static int src_get_config(struct processing_module *mod, uint32_t config_id, - uint32_t *data_offset_size, uint8_t *fragment, size_t fragment_size) +int src_get_config(struct processing_module *mod, uint32_t config_id, + uint32_t *data_offset_size, uint8_t *fragment, size_t fragment_size) { return -EINVAL; } -static int src_reset(struct processing_module *mod) +int src_reset(struct processing_module *mod) { struct comp_data *cd = module_get_private_data(mod); @@ -723,7 +679,7 @@ static int src_reset(struct processing_module *mod) return 0; } -static int src_free(struct processing_module *mod) +int src_free(struct processing_module *mod) { struct comp_data *cd = module_get_private_data(mod); diff --git a/src/audio/src/src.h b/src/audio/src/src.h index fe2170ab1714..5d1d543214d2 100644 --- a/src/audio/src/src.h +++ b/src/audio/src/src.h @@ -104,7 +104,14 @@ static inline void src_dec_wrap_s16(int16_t **ptr, int16_t *addr, size_t size) } #endif /* CONFIG_FORMAT_S16LE */ -void src_polyphase_reset(struct polyphase_src *src); +static inline void src_polyphase_reset(struct polyphase_src *src) +{ + src->number_of_stages = 0; + src->stage1 = NULL; + src->stage2 = NULL; + src_state_reset(&src->state1); + src_state_reset(&src->state2); +} int src_polyphase_init(struct polyphase_src *src, struct src_param *p, int32_t *delay_lines_start); @@ -173,6 +180,45 @@ int src_stream_pcm_source_rate_check(struct ipc_config_src cfg, struct sof_ipc_stream_params *params); #endif /* CONFIG_IPC_MAJOR_4 */ +/* Calculates the needed FIR delay line length */ +static inline int src_fir_delay_length(struct src_stage *s) +{ + return s->subfilter_length + (s->num_of_subfilters - 1) * s->idm + + s->blk_in; +} + +/* Calculates the FIR output delay line length */ +static inline int src_out_delay_length(struct src_stage *s) +{ + return 1 + (s->num_of_subfilters - 1) * s->odm; +} + +/* Returns index of a matching sample rate */ +static inline int src_find_fs(int fs_list[], int list_length, int fs) +{ + int i; + + for (i = 0; i < list_length; i++) { + if (fs_list[i] == fs) + return i; + } + return -EINVAL; +} + +static inline void src_state_reset(struct src_state *state) +{ + state->fir_delay_size = 0; + state->out_delay_size = 0; +} + +/* Fallback function */ +static inline int src_fallback(struct comp_data *cd, + struct sof_source *source, + struct sof_sink *sink) +{ + return 0; +} + int src_rate_check(const void *spec); int src_set_params(struct processing_module *mod, struct sof_sink *sink); @@ -182,9 +228,45 @@ int src_prepare_general(struct processing_module *mod, struct sof_source *source, struct sof_sink *sink); int src_init(struct processing_module *mod); -int src_fallback(struct comp_data *cd, struct sof_source *source, + +int src_buffer_lengths(struct comp_dev *dev, struct comp_data *cd, + int nch); +int init_stages(struct src_stage *stage1, struct src_stage *stage2, + struct polyphase_src *src, struct src_param *p, + int n, int32_t *delay_lines_start); +int src_1s(struct comp_data *cd, struct sof_source *source, + struct sof_sink *sink); +int src_copy_sxx(struct comp_data *cd, struct sof_source *source, struct sof_sink *sink); +int src_verify_params(struct processing_module *mod); + +bool src_get_copy_limits(struct comp_data *cd, + struct sof_source *source, + struct sof_sink *sink); +int src_params_general(struct processing_module *mod, + struct sof_source *source, + struct sof_sink *sink); +int src_prepare(struct processing_module *mod, + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks); +int src_2s(struct comp_data *cd, + struct sof_source *source, struct sof_sink *sink); + +bool src_is_ready_to_process(struct processing_module *mod, + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks); +int src_process(struct processing_module *mod, + struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks); +int src_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); +int src_get_config(struct processing_module *mod, uint32_t config_id, + uint32_t *data_offset_size, uint8_t *fragment, size_t fragment_size); +int src_free(struct processing_module *mod); +int src_reset(struct processing_module *mod); extern const struct sof_uuid src_uuid; extern struct tr_ctx src_tr; diff --git a/src/audio/src/src_lite.c b/src/audio/src/src_lite.c new file mode 100644 index 000000000000..5b6bf40f832a --- /dev/null +++ b/src/audio/src/src_lite.c @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: BSD-3-Clause +// +// Copyright(c) 2023 Intel Corporation. All rights reserved. +// +// Author: Fabiola Jasinska + +#include +#include "src.h" +#include "src_config.h" + +#define SRC_LITE 1 + +LOG_MODULE_REGISTER(src_lite, CONFIG_SOF_LOG_LEVEL); + +static const struct module_interface src_lite_interface = { + .init = src_init, + .prepare = src_prepare, + .process = src_process, + .is_ready_to_process = src_is_ready_to_process, + .set_configuration = src_set_config, + .get_configuration = src_get_config, + .reset = src_reset, + .free = src_free, +}; + +DECLARE_SOF_RT_UUID("src_lite", src_lite_uuid, 0x33441051, 0x44CD, 0x466A, + 0x83, 0xA3, 0x17, 0x84, 0x78, 0x70, 0x8A, 0xEA); + +DECLARE_TR_CTX(src_lite_tr, SOF_UUID(src_lite_uuid), LOG_LEVEL_INFO); + +DECLARE_MODULE_ADAPTER(src_lite_interface, src_lite_uuid, src_lite_tr); +SOF_MODULE_INIT(src_lite, sys_comp_module_src_lite_interface_init); diff --git a/tools/rimage/config/mtl.toml b/tools/rimage/config/mtl.toml index 453b0df89dbd..d85f797f627e 100644 --- a/tools/rimage/config/mtl.toml +++ b/tools/rimage/config/mtl.toml @@ -57,7 +57,7 @@ name = "ADSPFW" load_offset = "0x40000" [module] -count = 26 +count = 27 [[module.entry]] name = "BRNGUP" uuid = "2B79E4F3-4675-F649-89DF-3BC194A91AEB" @@ -649,3 +649,44 @@ count = 26 # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] mod_cfg = [0, 0, 0, 0, 296, 5000000, 384, 384, 0, 5000, 0] + + # SRC lite module config + [[module.entry]] + name = "SRC_LITE" + uuid = "33441051-44CD-466A-83A3-178478708AEA" + affinity_mask = "0x1" + #instance_count = "10" + domain_types = "0" + load_type = "0" + module_type = "0x1F" + auto_start = "0" + sched_caps = [1, 0x00008000] + + # pin = [dir, type, sample rate, size, container, channel-cfg] + pin = [0, 0, 0xffff, 0xc, 0x8, 0x05ff, + 1, 0, 0xf6c9, 0xc, 0x8, 0x05ff] + + # mod_cfg [PAR_0 PAR_1 PAR_2 PAR_3 IS_BYTES CPS IBS OBS MOD_FLAGS CPC OBLS] + mod_cfg = [0, 0, 0, 0, 12832, 1365500, 0, 0, 0, 1365, 0, + 1, 0, 0, 0, 12832, 2302300, 0, 0, 0, 2302, 0, + 2, 0, 0, 0, 12832, 3218200, 0, 0, 0, 3218, 0, + 3, 0, 0, 0, 12832, 4169700, 0, 0, 0, 4169, 0, + 4, 0, 0, 0, 12832, 5095100, 0, 0, 0, 5095, 0, + 5, 0, 0, 0, 12832, 6014800, 0, 0, 0, 6014, 0, + 6, 0, 0, 0, 12832, 6963500, 0, 0, 0, 6963, 0, + 7, 0, 0, 0, 12832, 7791000, 0, 0, 0, 7791, 0, + 8, 0, 0, 0, 12832, 8843000, 0, 0, 0, 8843, 0, + 9, 0, 0, 0, 12832, 9755100, 0, 0, 0, 9755, 0, + 10, 0, 0, 0, 12832, 10726500, 0, 0, 0, 10726, 0, + 11, 0, 0, 0, 12832, 11624100, 0, 0, 0, 11624, 0, + 12, 0, 0, 0, 12832, 12518700, 0, 0, 0, 12518, 0, + 13, 0, 0, 0, 12832, 13555000, 0, 0, 0, 13555, 0, + 14, 0, 0, 0, 12832, 14144500, 0, 0, 0, 14144, 0, + 15, 0, 0, 0, 12832, 15809800, 0, 0, 0, 15809, 0, + 16, 0, 0, 0, 12832, 16749000, 0, 0, 0, 16749, 0, + 17, 0, 0, 0, 12832, 18433500, 0, 0, 0, 18433, 0, + 18, 0, 0, 0, 12832, 19425900, 0, 0, 0, 19425, 0, + 19, 0, 0, 0, 12832, 20396900, 0, 0, 0, 20396, 0, + 20, 0, 0, 0, 12832, 20881000, 0, 0, 0, 20881, 0, + 21, 0, 0, 0, 12832, 23431000, 0, 0, 0, 23431, 0, + 22, 0, 0, 0, 12832, 30471000, 0, 0, 0, 30471, 0] \ No newline at end of file diff --git a/zephyr/CMakeLists.txt b/zephyr/CMakeLists.txt index 8deca5155919..b398b59b17db 100644 --- a/zephyr/CMakeLists.txt +++ b/zephyr/CMakeLists.txt @@ -600,6 +600,9 @@ elseif(CONFIG_IPC_MAJOR_4) ) endif() +zephyr_library_sources_ifdef(CONFIG_COMP_SRC_LITE + ${SOF_AUDIO_PATH}/src/src_lite.c +) zephyr_library_sources_ifdef(CONFIG_COMP_BASEFW_IPC4 ${SOF_AUDIO_PATH}/base_fw.c )