diff --git a/src/arch/xtensa/configs/apollolake_defconfig b/src/arch/xtensa/configs/apollolake_defconfig index 2c2aa1b231f5..daa761ca5f16 100644 --- a/src/arch/xtensa/configs/apollolake_defconfig +++ b/src/arch/xtensa/configs/apollolake_defconfig @@ -8,3 +8,4 @@ CONFIG_PERFORMANCE_COUNTERS=y CONFIG_COMP_SRC_SMALL=y CONFIG_COMP_TDFB=n CONFIG_COMP_TONE=n +CONFIG_COMP_LEGACY_INTERFACE=y diff --git a/src/arch/xtensa/configs/baytrail_defconfig b/src/arch/xtensa/configs/baytrail_defconfig index 13366b50c13a..026e9301a776 100644 --- a/src/arch/xtensa/configs/baytrail_defconfig +++ b/src/arch/xtensa/configs/baytrail_defconfig @@ -14,3 +14,4 @@ CONFIG_OPTIMIZE_FOR_SIZE=y CONFIG_HAVE_AGENT=n CONFIG_DEBUG_MEMORY_USAGE_SCAN=n CONFIG_TRACE_FILTERING_ADAPTIVE=n +CONFIG_COMP_LEGACY_INTERFACE=y diff --git a/src/arch/xtensa/configs/baytrail_gcc_defconfig b/src/arch/xtensa/configs/baytrail_gcc_defconfig index c39486fdbafa..dcca748dcc9a 100644 --- a/src/arch/xtensa/configs/baytrail_gcc_defconfig +++ b/src/arch/xtensa/configs/baytrail_gcc_defconfig @@ -14,3 +14,4 @@ CONFIG_HAVE_AGENT=n CONFIG_DEBUG_MEMORY_USAGE_SCAN=n CONFIG_TRACE_FILTERING_ADAPTIVE=n CONFIG_OPTIMIZE_FOR_SIZE=y +CONFIG_COMP_LEGACY_INTERFACE=y diff --git a/src/arch/xtensa/configs/cannonlake_defconfig b/src/arch/xtensa/configs/cannonlake_defconfig index a49f550c35c1..5bbba2e3981d 100644 --- a/src/arch/xtensa/configs/cannonlake_defconfig +++ b/src/arch/xtensa/configs/cannonlake_defconfig @@ -5,3 +5,4 @@ CONFIG_INTEL_ALH=y CONFIG_LP_MEMORY_BANKS=1 CONFIG_HP_MEMORY_BANKS=47 CONFIG_PERFORMANCE_COUNTERS=y +CONFIG_COMP_LEGACY_INTERFACE=y diff --git a/src/arch/xtensa/configs/cannonlake_gcc_defconfig b/src/arch/xtensa/configs/cannonlake_gcc_defconfig index 98c4591c4208..bb9c53394a7b 100644 --- a/src/arch/xtensa/configs/cannonlake_gcc_defconfig +++ b/src/arch/xtensa/configs/cannonlake_gcc_defconfig @@ -5,3 +5,4 @@ CONFIG_INTEL_ALH=y CONFIG_CAVS_LPS=y CONFIG_LP_MEMORY_BANKS=1 CONFIG_HP_MEMORY_BANKS=47 +CONFIG_COMP_LEGACY_INTERFACE=y diff --git a/src/arch/xtensa/configs/cherrytrail_defconfig b/src/arch/xtensa/configs/cherrytrail_defconfig index 1692f7fcb0c4..fb8515f870dd 100644 --- a/src/arch/xtensa/configs/cherrytrail_defconfig +++ b/src/arch/xtensa/configs/cherrytrail_defconfig @@ -14,3 +14,4 @@ CONFIG_OPTIMIZE_FOR_SIZE=y CONFIG_HAVE_AGENT=n CONFIG_DEBUG_MEMORY_USAGE_SCAN=n CONFIG_TRACE_FILTERING_ADAPTIVE=n +CONFIG_COMP_LEGACY_INTERFACE=y diff --git a/src/arch/xtensa/configs/cherrytrail_gcc_defconfig b/src/arch/xtensa/configs/cherrytrail_gcc_defconfig index 63401de0bca3..1d71763fa3b1 100644 --- a/src/arch/xtensa/configs/cherrytrail_gcc_defconfig +++ b/src/arch/xtensa/configs/cherrytrail_gcc_defconfig @@ -15,3 +15,4 @@ CONFIG_HAVE_AGENT=n CONFIG_DEBUG_MEMORY_USAGE_SCAN=n CONFIG_TRACE_FILTERING_ADAPTIVE=n CONFIG_OPTIMIZE_FOR_SIZE=y +CONFIG_COMP_LEGACY_INTERFACE=y diff --git a/src/arch/xtensa/configs/icelake_defconfig b/src/arch/xtensa/configs/icelake_defconfig index 0f3a659cbe2a..32bc42104ca8 100644 --- a/src/arch/xtensa/configs/icelake_defconfig +++ b/src/arch/xtensa/configs/icelake_defconfig @@ -4,3 +4,4 @@ CONFIG_INTEL_SSP=y CONFIG_INTEL_ALH=y CONFIG_LP_MEMORY_BANKS=1 CONFIG_HP_MEMORY_BANKS=47 +CONFIG_COMP_LEGACY_INTERFACE=y diff --git a/src/arch/xtensa/configs/jasperlake_defconfig b/src/arch/xtensa/configs/jasperlake_defconfig index f83bd69b8236..b5ca51b65ad8 100644 --- a/src/arch/xtensa/configs/jasperlake_defconfig +++ b/src/arch/xtensa/configs/jasperlake_defconfig @@ -5,3 +5,4 @@ CONFIG_INTEL_SSP=y CONFIG_CORE_COUNT=2 CONFIG_LP_MEMORY_BANKS=1 CONFIG_HP_MEMORY_BANKS=16 +CONFIG_COMP_LEGACY_INTERFACE=y diff --git a/src/audio/CMakeLists.txt b/src/audio/CMakeLists.txt index b04f5c279194..fc4e5df59eeb 100644 --- a/src/audio/CMakeLists.txt +++ b/src/audio/CMakeLists.txt @@ -8,9 +8,6 @@ if(NOT CONFIG_LIBRARY) buffer.c channel_map.c ) - if(CONFIG_COMP_VOLUME) - add_subdirectory(volume) - endif() if(CONFIG_COMP_SRC) add_subdirectory(src) endif() @@ -178,10 +175,10 @@ check_optimization(fma -mfma -ftree-vectorize -DOPS_FMA) check_optimization(hifi2ep -mhifi2ep "" -DOPS_HIFI2EP) check_optimization(hifi3 -mhifi3 "" -DOPS_HIFI3) -set(sof_audio_modules volume mixer src asrc eq-fir eq-iir dcblock crossover tdfb drc multiband_drc) +set(sof_audio_modules mixer volume src asrc eq-fir eq-iir dcblock crossover tdfb drc multiband_drc) # sources for each module -set(volume_sources volume/volume.c volume/volume_generic.c) +set(volume_sources module_adapter/module_adapter.c module_adapter/module/generic.c module_adapter/module/volume/volume.c module_adapter/module/volume/volume_generic.c) 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) diff --git a/src/audio/Kconfig b/src/audio/Kconfig index d5e8ccb11c5c..1936e115c5e1 100644 --- a/src/audio/Kconfig +++ b/src/audio/Kconfig @@ -31,12 +31,6 @@ config COMP_ARIA Currently ARIA introduces gain transition and algorithmic latency equal to 1 ms. -config COMP_VOLUME - bool "Volume component" - default y - help - Select for Volume component - config COMP_UP_DOWN_MIXER bool "UP_DOWN_MIXER component" default n @@ -51,43 +45,6 @@ config COMP_UP_DOWN_MIXER Downmixing for mono output: 4.0, Quatro, 3.1, 2 -> 1 -if COMP_VOLUME - -config COMP_VOLUME_WINDOWS_FADE - bool "Windows Fade shape volume transitions support" - help - This option enables volume ramp shape that follows - power of 1.75. The shape is not linear, not logarithmic. - The power function uses a lookup table that consumes - 256 bytes. The topology must set volume ramp token to - SOF_VOLUME_WINDOWS_FADE for the volume instance to use - this ramp shape. - -config COMP_VOLUME_LINEAR_RAMP - bool "Linear ramp volume transitions support" - default y - depends on IPC_MAJOR_3 - help - This option enables volume linear ramp shape. - -config COMP_PEAK_VOL - bool "Report peak vol data to host" - default y - depends on IPC_MAJOR_4 - help - This option enables reporting to host peak vol regs. - See: struct ipc4_peak_volume_regs - -config COMP_GAIN - bool "GAIN component" - default y - depends on IPC_MAJOR_4 - help - This option enables gain to change volume. It works - as peak volume without updating peak vol to host - -endif # volume - config COMP_SRC bool "SRC component" default y @@ -448,7 +405,7 @@ config COMP_TDFB config COMP_MODULE_ADAPTER bool "Module adapter" - default n + default y help This component is an adapter between SoF components and any external third party codecs/libraries. In order to make use of it the library itself should @@ -457,6 +414,12 @@ config COMP_MODULE_ADAPTER "src\include\sof\audio\module_adapter\interfaces.h". It is possible to link several different codecs and use them in parallel. +config COMP_LEGACY_INTERFACE + bool "Use legacy component driver interface" + default n + help + Use the legacy component driver interface for component instead of the module adapter. + rsource "module_adapter/Kconfig" config COMP_IGO_NR diff --git a/src/audio/module_adapter/CMakeLists.txt b/src/audio/module_adapter/CMakeLists.txt index cb0509d4a344..5e7b2b3b4a6a 100644 --- a/src/audio/module_adapter/CMakeLists.txt +++ b/src/audio/module_adapter/CMakeLists.txt @@ -1,66 +1,76 @@ # SPDX-License-Identifier: BSD-3-Clause -add_local_sources(sof module_adapter.c module/generic.c) +if(NOT CONFIG_LIBRARY) + if (CONFIG_IPC_MAJOR_4 OR CONFIG_CADENCE_CODEC OR (NOT CONFIG_COMP_LEGACY_INTERFACE)) + add_local_sources(sof module_adapter.c module/generic.c) + endif() -if(CONFIG_CADENCE_CODEC) -add_local_sources(sof module/cadence.c) + if(CONFIG_COMP_VOLUME) + add_local_sources(sof module/volume/volume_generic.c module/volume/volume_hifi3.c module/volume/volume.c) + endif() -if(CONFIG_CADENCE_CODEC_WRAPPER) -sof_add_static_library(codec_wrapper_lib ${CONFIG_CADENCE_CODEC_WRAPPER_LIB}) -endif() + if(CONFIG_CADENCE_CODEC) + add_local_sources(sof module/cadence.c) -if(CONFIG_CADENCE_CODEC_AAC_DEC) -sof_add_static_library(xa_aac_dec ${CONFIG_CADENCE_CODEC_AAC_DEC_LIB}) -endif() + if(CONFIG_CADENCE_CODEC_WRAPPER) + sof_add_static_library(codec_wrapper_lib ${CONFIG_CADENCE_CODEC_WRAPPER_LIB}) + endif() -if(CONFIG_CADENCE_CODEC_BSAC_DEC) -sof_add_static_library(xa_bsac_dec ${CONFIG_CADENCE_CODEC_BSAC_DEC_LIB}) -endif() + if(CONFIG_CADENCE_CODEC_AAC_DEC) + sof_add_static_library(xa_aac_dec ${CONFIG_CADENCE_CODEC_AAC_DEC_LIB}) + endif() + if(CONFIG_CADENCE_CODEC_BSAC_DEC) + sof_add_static_library(xa_bsac_dec ${CONFIG_CADENCE_CODEC_BSAC_DEC_LIB}) + endif() -if(CONFIG_CADENCE_CODEC_DAB_DEC) -sof_add_static_library(xa_dab_dec ${CONFIG_CADENCE_CODEC_DAB_DEC_LIB}) -endif() + if(CONFIG_CADENCE_CODEC_DAB_DEC) + sof_add_static_library(xa_dab_dec ${CONFIG_CADENCE_CODEC_DAB_DEC_LIB}) + endif() -if(CONFIG_CADENCE_CODEC_DRM_DEC) -sof_add_static_library(xa_drm_dec ${CONFIG_CADENCE_CODEC_DRM_DEC_LIB}) -endif() + if(CONFIG_CADENCE_CODEC_DRM_DEC) + sof_add_static_library(xa_drm_dec ${CONFIG_CADENCE_CODEC_DRM_DEC_LIB}) + endif() -if(CONFIG_CADENCE_CODEC_MP3_DEC) -sof_add_static_library(xa_mp3_dec ${CONFIG_CADENCE_CODEC_MP3_DEC_LIB}) -endif() + if(CONFIG_CADENCE_CODEC_MP3_DEC) + sof_add_static_library(xa_mp3_dec ${CONFIG_CADENCE_CODEC_MP3_DEC_LIB}) + endif() -if(CONFIG_CADENCE_CODEC_SBC_DEC) -sof_add_static_library(xa_sbc_dec ${CONFIG_CADENCE_CODEC_SBC_DEC_LIB}) -endif() -if(CONFIG_CADENCE_CODEC_VORBIS_DEC) - sof_add_static_library(xa_vorbis_dec ${CONFIG_CADENCE_CODEC_VORBIS_DEC_LIB}) -endif() + if(CONFIG_CADENCE_CODEC_SBC_DEC) + sof_add_static_library(xa_sbc_dec ${CONFIG_CADENCE_CODEC_SBC_DEC_LIB}) + endif() -if(CONFIG_CADENCE_CODEC_SRC_PP) - sof_add_static_library(xa_src_pp ${CONFIG_CADENCE_CODEC_SRC_PP_LIB}) -endif() + if(CONFIG_CADENCE_CODEC_VORBIS_DEC) + sof_add_static_library(xa_vorbis_dec ${CONFIG_CADENCE_CODEC_VORBIS_DEC_LIB}) + endif() -endif() + if(CONFIG_CADENCE_CODEC_SRC_PP) + sof_add_static_library(xa_src_pp ${CONFIG_CADENCE_CODEC_SRC_PP_LIB}) + endif() -if(CONFIG_PASSTHROUGH_CODEC) -add_local_sources(sof module/passthrough.c) -endif() + endif() -if(CONFIG_WAVES_CODEC) -add_local_sources(sof module/waves.c) -sof_add_static_library(MaxxChrome ${CMAKE_CURRENT_LIST_DIR}/lib/release/libMaxxChrome.a) -# folder with Waves API must be among include directories -target_include_directories(sof PUBLIC ${CMAKE_CURRENT_LIST_DIR}/../../include/sof/audio/) -endif() + if(CONFIG_PASSTHROUGH_CODEC) + add_local_sources(sof module/passthrough.c) + endif() + + if(CONFIG_WAVES_CODEC) + add_local_sources(sof module/waves.c) + sof_add_static_library(MaxxChrome ${CMAKE_CURRENT_LIST_DIR}/lib/release/libMaxxChrome.a) + # folder with Waves API must be among include directories + target_include_directories(sof PUBLIC ${CMAKE_CURRENT_LIST_DIR}/../../include/sof/audio/) + endif() + + if(CONFIG_DTS_CODEC) + add_local_sources(sof module/dts.c) + target_compile_definitions(sof PRIVATE -DDTS_MATH_INT32 -DDTS_XTENSA) + target_include_directories(sof PRIVATE ${CMAKE_CURRENT_LIST_DIR}/../../include/sof/audio/dts/) + sof_add_static_library(DtsCodec ${CMAKE_CURRENT_LIST_DIR}/lib/release/libdts-sof-interface-i32.a) + endif() -if(CONFIG_DTS_CODEC) -add_local_sources(sof module/dts.c) -target_compile_definitions(sof PRIVATE -DDTS_MATH_INT32 -DDTS_XTENSA) -target_include_directories(sof PRIVATE ${CMAKE_CURRENT_LIST_DIR}/../../include/sof/audio/dts/) -sof_add_static_library(DtsCodec ${CMAKE_CURRENT_LIST_DIR}/lib/release/libdts-sof-interface-i32.a) + return() endif() diff --git a/src/audio/module_adapter/Kconfig b/src/audio/module_adapter/Kconfig index f2876f942e4f..7f5bd64ca694 100644 --- a/src/audio/module_adapter/Kconfig +++ b/src/audio/module_adapter/Kconfig @@ -11,6 +11,50 @@ menu "Processing modules" This will cause codec adapter component to include header files specific to CADENCE base codecs. + config COMP_VOLUME + bool "Volume component" + default y + depends on COMP_MODULE_ADAPTER + help + Select for Volume component + +if COMP_VOLUME + +config COMP_VOLUME_WINDOWS_FADE + bool "Windows Fade shape volume transitions support" + help + This option enables volume ramp shape that follows + power of 1.75. The shape is not linear, not logarithmic. + The power function uses a lookup table that consumes + 256 bytes. The topology must set volume ramp token to + SOF_VOLUME_WINDOWS_FADE for the volume instance to use + this ramp shape. + +config COMP_VOLUME_LINEAR_RAMP + bool "Linear ramp volume transitions support" + default y + depends on IPC_MAJOR_3 + help + This option enables volume linear ramp shape. + +config COMP_PEAK_VOL + bool "Report peak vol data to host" + default y + depends on IPC_MAJOR_4 + help + This option enables reporting to host peak vol regs. + See: struct ipc4_peak_volume_regs + +config COMP_GAIN + bool "GAIN component" + default y + depends on IPC_MAJOR_4 + help + This option enables gain to change volume. It works + as peak volume without updating peak vol to host + +endif # volume + if CADENCE_CODEC config CADENCE_CODEC_WRAPPER bool 'Cadence codec wrapper' diff --git a/src/audio/module_adapter/module/dts.c b/src/audio/module_adapter/module/dts.c index 0afb402fa1ce..a4af759ca18e 100644 --- a/src/audio/module_adapter/module/dts.c +++ b/src/audio/module_adapter/module/dts.c @@ -379,6 +379,8 @@ static int dts_codec_free(struct processing_module *mod) if (ret) comp_err(dev, "dts_codec_free() failed %d %d", ret, dts_result); + module_free_all_memory(mod); + comp_dbg(dev, "dts_codec_free() done"); return ret; diff --git a/src/audio/module_adapter/module/generic.c b/src/audio/module_adapter/module/generic.c index a330359ca0fa..8634f3b18bb7 100644 --- a/src/audio/module_adapter/module/generic.c +++ b/src/audio/module_adapter/module/generic.c @@ -311,8 +311,6 @@ int module_free(struct processing_module *mod) comp_warn(mod->dev, "module_free(): error: %d for %d", ret, dev_comp_id(mod->dev)); - /* Free all memory requested by module */ - module_free_all_memory(mod); /* Free all memory shared by module_adapter & module */ md->cfg.avail = false; md->cfg.size = 0; diff --git a/src/audio/volume/volume.c b/src/audio/module_adapter/module/volume/volume.c similarity index 73% rename from src/audio/volume/volume.c rename to src/audio/module_adapter/module/volume/volume.c index b93dd747521a..fe0546ed9ce2 100644 --- a/src/audio/volume/volume.c +++ b/src/audio/module_adapter/module/volume/volume.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -44,8 +45,6 @@ #include #include -static const struct comp_driver comp_volume; - LOG_MODULE_REGISTER(volume, CONFIG_SOF_LOG_LEVEL); #if CONFIG_IPC_MAJOR_3 @@ -231,9 +230,9 @@ const struct comp_zc_func_map zc_func_map[] = { * \param[in] ramp_time Time spent since ramp start as milliseconds Q29.3 * \param[in] channel Current channel to update */ -static int32_t volume_linear_ramp(struct comp_dev *dev, int32_t ramp_time, int channel) +static int32_t volume_linear_ramp(struct processing_module *mod, int32_t ramp_time, int channel) { - struct vol_data *cd = comp_get_drvdata(dev); + struct vol_data *cd = module_get_private_data(mod); return cd->rvolume[channel] + ramp_time * cd->ramp_coef[channel]; } @@ -247,9 +246,10 @@ static int32_t volume_linear_ramp(struct comp_dev *dev, int32_t ramp_time, int c * \param[in] channel Current channel to update */ -static int32_t volume_windows_fade_ramp(struct comp_dev *dev, int32_t ramp_time, int channel) +static int32_t volume_windows_fade_ramp(struct processing_module *mod, int32_t ramp_time, + int channel) { - struct vol_data *cd = comp_get_drvdata(dev); + struct vol_data *cd = module_get_private_data(mod); int32_t time_ratio; /* Q2.30 */ int32_t pow_value; /* Q2.30 */ int32_t volume_delta = cd->tvolume[channel] - cd->rvolume[channel]; /* Q16.16 */ @@ -264,9 +264,10 @@ static int32_t volume_windows_fade_ramp(struct comp_dev *dev, int32_t ramp_time, * \brief Ramps volume changes over time. * \param[in,out] dev Volume base component device. */ -static void volume_ramp(struct comp_dev *dev) +static void volume_ramp(struct processing_module *mod) { - struct vol_data *cd = comp_get_drvdata(dev); + struct vol_data *cd = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; int32_t vol; int32_t ramp_time; int i; @@ -304,7 +305,7 @@ static void volume_ramp(struct comp_dev *dev) * calculated from previous gain and ramp time. The slope * coefficient is calculated in volume_set_chan(). */ - vol = cd->ramp_func(dev, ramp_time, i); + vol = cd->ramp_func(mod, ramp_time, i); if (cd->volume[i] < cd->tvolume[i]) { /* ramp up, check if ramp completed */ if (vol >= cd->tvolume[i] || vol >= cd->vol_max) { @@ -361,12 +362,33 @@ static void reset_state(struct vol_data *cd) } #if CONFIG_IPC_MAJOR_3 -static int init_volume(struct comp_dev *dev, struct comp_ipc_config *config, void *spec) +static int volume_init(struct processing_module *mod) { - struct ipc_config_volume *vol = spec; - struct vol_data *cd = comp_get_drvdata(dev); + struct module_data *md = &mod->priv; + struct comp_dev *dev = mod->dev; + struct module_config *cfg = &md->cfg; + struct ipc_config_volume *vol = cfg->data; + struct vol_data *cd; + const size_t vol_size = sizeof(int32_t) * SOF_IPC_MAX_CHANNELS * 4; int i; + cd = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, sizeof(struct vol_data)); + if (!cd) + return -ENOMEM; + + /* + * malloc memory to store current volume 4 times to ensure the address + * is 8-byte aligned for multi-way xtensa intrinsic operations. + */ + cd->vol = rmalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, vol_size); + if (!cd->vol) { + rfree(cd); + comp_err(dev, "volume_init(): Failed to allocate %d", vol_size); + return -ENOMEM; + } + + md->private = cd; + /* Set the default volumes. If IPC sets min_value or max_value to * not-zero, use them. Otherwise set to internal limits and notify * ramp step calculation about assumed range with the range set to @@ -427,6 +449,8 @@ static int init_volume(struct comp_dev *dev, struct comp_ipc_config *config, voi #endif default: comp_err(dev, "volume_new(): invalid ramp type %d", vol->ramp); + rfree(cd); + rfree(cd->vol); return -EINVAL; } @@ -509,14 +533,35 @@ static inline void init_ramp(struct vol_data *cd, uint32_t curve_duration, uint3 } } -static int init_volume(struct comp_dev *dev, struct comp_ipc_config *config, void *spec) +static int volume_init(struct processing_module *mod) { - struct ipc4_peak_volume_module_cfg *vol = spec; - struct vol_data *cd = comp_get_drvdata(dev); + struct module_data *md = &mod->priv; + struct module_config *cfg = &md->cfg; + struct comp_dev *dev = mod->dev; + struct ipc4_peak_volume_module_cfg *vol = cfg->data; + struct vol_data *cd; + const size_t vol_size = sizeof(int32_t) * SOF_IPC_MAX_CHANNELS * 4; uint32_t channels_count; uint8_t channel_cfg; uint8_t channel; + cd = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, sizeof(struct vol_data)); + if (!cd) + return -ENOMEM; + + /* + * malloc memory to store current volume 4 times to ensure the address + * is 8-byte aligned for multi-way xtensa intrinsic operations. + */ + cd->vol = rmalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, vol_size); + if (!cd->vol) { + rfree(cd); + comp_err(dev, "volume_init(): Failed to allocate %d", vol_size); + return -ENOMEM; + } + + md->private = cd; + mailbox_hostbox_read(&cd->base, sizeof(cd->base), 0, sizeof(cd->base)); channels_count = cd->base.audio_fmt.channels_count; @@ -539,7 +584,8 @@ static int init_volume(struct comp_dev *dev, struct comp_ipc_config *config, voi init_ramp(cd, vol->config[0].curve_duration, vol->config[0].target_volume); cd->mailbox_offset = offsetof(struct ipc4_fw_registers, peak_vol_regs); - cd->mailbox_offset += IPC4_INST_ID(config->id) * sizeof(struct ipc4_peak_volume_regs); + cd->mailbox_offset += + IPC4_INST_ID(dev_comp_id(dev)) * sizeof(struct ipc4_peak_volume_regs); reset_state(cd); @@ -576,68 +622,14 @@ static inline void prepare_ramp(struct comp_dev *dev, struct vol_data *cd) cd->vol_ramp_frames = dev->frames / (dev->period / ramp_update_us); } -/** - * \brief Creates volume component. - * - * \return Pointer to volume base component device. - */ -static struct comp_dev *volume_new(const struct comp_driver *drv, - struct comp_ipc_config *config, - void *spec) -{ - struct comp_dev *dev; - struct vol_data *cd; - const size_t vol_size = sizeof(int32_t) * SOF_IPC_MAX_CHANNELS * 4; - int ret; - - comp_cl_dbg(&comp_volume, "volume_new()"); - - dev = comp_alloc(drv, sizeof(*dev)); - if (!dev) - return NULL; - - dev->ipc_config = *config; - list_init(&dev->bsource_list); - list_init(&dev->bsink_list); - - cd = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, - sizeof(struct vol_data)); - if (!cd) - goto fail; - - /* malloc memory to store current volume 4 times to ensure the address - * is 8-byte aligned for multi-way xtensa intrinsic operations. - */ - cd->vol = rmalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, vol_size); - if (!cd->vol) { - comp_err(dev, "volume_new(): Failed to allocate %d", vol_size); - goto cd_fail; - } - - comp_set_drvdata(dev, cd); - - ret = init_volume(dev, config, spec); - if (ret < 0) - goto cd_fail; - - dev->state = COMP_STATE_READY; - return dev; - -cd_fail: - rfree(cd->vol); - rfree(cd); -fail: - rfree(dev); - return NULL; -} - /** * \brief Frees volume component. * \param[in,out] dev Volume base component device. */ -static void volume_free(struct comp_dev *dev) +static int volume_free(struct processing_module *mod) { - struct vol_data *cd = comp_get_drvdata(dev); + struct vol_data *cd = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; #if CONFIG_IPC_MAJOR_4 struct ipc4_peak_volume_regs regs; @@ -650,22 +642,24 @@ static void volume_free(struct comp_dev *dev) rfree(cd->vol); rfree(cd); - rfree(dev); + + return 0; } /** * \brief Sets channel target volume. - * \param[in,out] dev Volume base component device. + * \param[in,out] mod Volume processing module handle * \param[in] chan Channel number. * \param[in] vol Target volume. * \param[in] constant_rate_ramp When true do a constant rate * and variable time length ramp. When false do * a fixed length and variable rate ramp. */ -static inline int volume_set_chan(struct comp_dev *dev, int chan, +static inline int volume_set_chan(struct processing_module *mod, int chan, int32_t vol, bool constant_rate_ramp) { - struct vol_data *cd = comp_get_drvdata(dev); + struct vol_data *cd = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; int32_t v = vol; int32_t delta; int32_t delta_abs; @@ -749,13 +743,13 @@ static inline int volume_set_chan(struct comp_dev *dev, int chan, * \param[in,out] dev Volume base component device. * \param[in] chan Channel number. */ -static inline void volume_set_chan_mute(struct comp_dev *dev, int chan) +static inline void volume_set_chan_mute(struct processing_module *mod, int chan) { - struct vol_data *cd = comp_get_drvdata(dev); + struct vol_data *cd = module_get_private_data(mod); if (!cd->muted[chan]) { cd->mvolume[chan] = cd->tvolume[chan]; - volume_set_chan(dev, chan, 0, true); + volume_set_chan(mod, chan, 0, true); cd->muted[chan] = true; } } @@ -765,50 +759,50 @@ static inline void volume_set_chan_mute(struct comp_dev *dev, int chan) * \param[in,out] dev Volume base component device. * \param[in] chan Channel number. */ -static inline void volume_set_chan_unmute(struct comp_dev *dev, int chan) +static inline void volume_set_chan_unmute(struct processing_module *mod, int chan) { - struct vol_data *cd = comp_get_drvdata(dev); + struct vol_data *cd = module_get_private_data(mod); if (cd->muted[chan]) { cd->muted[chan] = false; - volume_set_chan(dev, chan, cd->mvolume[chan], true); + volume_set_chan(mod, chan, cd->mvolume[chan], true); } } #if CONFIG_IPC_MAJOR_3 -/** - * \brief Sets volume control command. - * \param[in,out] dev Volume base component device. - * \param[in,out] cdata Control command data. - * \return Error code. - */ -static int volume_ctrl_set_cmd(struct comp_dev *dev, - struct sof_ipc_ctrl_data *cdata) +static int volume_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 vol_data *cd = comp_get_drvdata(dev); + struct sof_ipc_ctrl_data *cdata = (struct sof_ipc_ctrl_data *)fragment; + struct vol_data *cd = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; uint32_t val; uint32_t ch; int j; int ret = 0; + comp_dbg(dev, "volume_set_config()"); + /* validate */ if (cdata->num_elems == 0 || cdata->num_elems > SOF_IPC_MAX_CHANNELS) { - comp_err(dev, "volume_ctrl_set_cmd(): invalid cdata->num_elems"); + comp_err(dev, "volume_set_config(): invalid cdata->num_elems"); return -EINVAL; } switch (cdata->cmd) { case SOF_CTRL_CMD_VOLUME: - comp_dbg(dev, "volume_ctrl_set_cmd(), SOF_CTRL_CMD_VOLUME, cdata->comp_id = %u", + comp_dbg(dev, "volume_set_config(), SOF_CTRL_CMD_VOLUME, cdata->comp_id = %u", cdata->comp_id); for (j = 0; j < cdata->num_elems; j++) { ch = cdata->chanv[j].channel; val = cdata->chanv[j].value; - comp_info(dev, "volume_ctrl_set_cmd(), channel = %d, value = %u", + comp_info(dev, "volume_set_config(), channel = %d, value = %u", ch, val); if (ch >= SOF_IPC_MAX_CHANNELS) { - comp_err(dev, "volume_ctrl_set_cmd(), illegal channel = %d", + comp_err(dev, "volume_set_config(), illegal channel = %d", ch); return -EINVAL; } @@ -816,7 +810,7 @@ static int volume_ctrl_set_cmd(struct comp_dev *dev, if (cd->muted[ch]) { cd->mvolume[ch] = val; } else { - ret = volume_set_chan(dev, ch, val, true); + ret = volume_set_chan(mod, ch, val, true); if (ret) return ret; } @@ -824,17 +818,17 @@ static int volume_ctrl_set_cmd(struct comp_dev *dev, if (!cd->vol_ramp_active) { cd->ramp_finished = false; - volume_ramp(dev); + volume_ramp(mod); } break; case SOF_CTRL_CMD_SWITCH: - comp_dbg(dev, "volume_ctrl_set_cmd(), SOF_CTRL_CMD_SWITCH, cdata->comp_id = %u", + comp_dbg(dev, "volume_set_config(), SOF_CTRL_CMD_SWITCH, cdata->comp_id = %u", cdata->comp_id); for (j = 0; j < cdata->num_elems; j++) { ch = cdata->chanv[j].channel; val = cdata->chanv[j].value; - comp_info(dev, "volume_ctrl_set_cmd(), channel = %d, value = %u", + comp_info(dev, "volume_set_config(), channel = %d, value = %u", ch, val); if (ch >= SOF_IPC_MAX_CHANNELS) { comp_err(dev, "volume_ctrl_set_cmd(), illegal channel = %d", @@ -843,40 +837,39 @@ static int volume_ctrl_set_cmd(struct comp_dev *dev, } if (val) - volume_set_chan_unmute(dev, ch); + volume_set_chan_unmute(mod, ch); else - volume_set_chan_mute(dev, ch); + volume_set_chan_mute(mod, ch); } if (!cd->vol_ramp_active) { cd->ramp_finished = false; - volume_ramp(dev); + volume_ramp(mod); } break; default: - comp_err(dev, "volume_ctrl_set_cmd(): invalid cdata->cmd"); + comp_err(dev, "volume_set_config(): invalid cdata->cmd"); return -EINVAL; } return 0; } -/** - * \brief Gets volume control command. - * \param[in,out] dev Volume base component device. - * \param[in,out] cdata Control command data. - * \return Error code. - */ -static int volume_ctrl_get_cmd(struct comp_dev *dev, - struct sof_ipc_ctrl_data *cdata, int size) +static int volume_get_config(struct processing_module *mod, + uint32_t config_id, uint32_t *data_offset_size, + uint8_t *fragment, size_t fragment_size) { - struct vol_data *cd = comp_get_drvdata(dev); + struct sof_ipc_ctrl_data *cdata = (struct sof_ipc_ctrl_data *)fragment; + struct vol_data *cd = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; int j; + comp_dbg(dev, "volume_get_config()"); + /* validate */ if (cdata->num_elems == 0 || cdata->num_elems > SOF_IPC_MAX_CHANNELS) { - comp_err(dev, "volume_ctrl_get_cmd(): invalid cdata->num_elems %u", + comp_err(dev, "volume_get_config(): invalid cdata->num_elems %u", cdata->num_elems); return -EINVAL; } @@ -886,7 +879,7 @@ static int volume_ctrl_get_cmd(struct comp_dev *dev, for (j = 0; j < cdata->num_elems; j++) { cdata->chanv[j].channel = j; cdata->chanv[j].value = cd->tvolume[j]; - comp_info(dev, "volume_ctrl_get_cmd(), channel = %u, value = %u", + comp_info(dev, "volume_get_config(), channel = %u, value = %u", cdata->chanv[j].channel, cdata->chanv[j].value); } @@ -895,110 +888,52 @@ static int volume_ctrl_get_cmd(struct comp_dev *dev, for (j = 0; j < cdata->num_elems; j++) { cdata->chanv[j].channel = j; cdata->chanv[j].value = !cd->muted[j]; - comp_info(dev, "volume_ctrl_get_cmd(), channel = %u, value = %u", + comp_info(dev, "volume_get_config(), channel = %u, value = %u", cdata->chanv[j].channel, cdata->chanv[j].value); } break; default: - comp_err(dev, "volume_ctrl_get_cmd(): invalid cdata->cmd"); + comp_err(dev, "volume_get_config(): invalid cdata->cmd"); return -EINVAL; } return 0; } -/** - * \brief Used to pass standard and bespoke commands (with data) to component. - * \param[in,out] dev Volume base component device. - * \param[in] cmd Command type. - * \param[in,out] data Control command data. - * \return Error code. - */ -static int volume_cmd(struct comp_dev *dev, int cmd, void *data, - int max_data_size) -{ - struct sof_ipc_ctrl_data *cdata = ASSUME_ALIGNED(data, 4); - - comp_dbg(dev, "volume_cmd()"); - - switch (cmd) { - case COMP_CMD_SET_VALUE: - return volume_ctrl_set_cmd(dev, cdata); - case COMP_CMD_GET_VALUE: - return volume_ctrl_get_cmd(dev, cdata, max_data_size); - default: - return -EINVAL; - } -} - /* CONFIG_IPC_MAJOR_3 */ #elif CONFIG_IPC_MAJOR_4 -/** - * \brief Used to pass standard and bespoke commands (with data) to component. - * \param[in,out] dev Volume base component device. - * \param[in] cmd Command type. - * \param[in,out] data Control command data. - * \return Error code. - */ -static int volume_cmd(struct comp_dev *dev, int cmd, void *data, - int max_data_size) +static int volume_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 ipc4_peak_volume_config *cdata = ASSUME_ALIGNED(data, 8); - struct vol_data *cd = comp_get_drvdata(dev); - uint32_t channels_count = cd->base.audio_fmt.channels_count; - int i; - - comp_dbg(dev, "volume_cmd()"); - - cdata->target_volume = convert_volume_ipc4_to_ipc3(dev, cdata->target_volume); - - /* In IPC4 driver sends curve_duration in hundred of ns - it should be - * converted into ms value required by firmware - */ - cd->initial_ramp = Q_MULTSR_32X32(cdata->curve_duration, Q_CONVERT_FLOAT(1.0 / 10000, 31), - 0, 31, 0); - - switch (cmd) { - case IPC4_VOLUME: - if (cdata->channel_id == IPC4_ALL_CHANNELS_MASK) { - for (i = 0; i < channels_count; i++) - set_volume_ipc4(cd, i, cdata->target_volume, - cdata->curve_type, - cdata->curve_duration); - } else { - set_volume_ipc4(cd, cdata->channel_id, - cdata->target_volume, cdata->curve_type, - cdata->curve_duration); - } - break; - default: - return -EINVAL; - } + struct vol_data *cd = module_get_private_data(mod); + struct module_data *md = &mod->priv; + struct comp_dev *dev = mod->dev; + struct ipc4_peak_volume_config *cdata; + int i, ret; - return 0; -} + comp_dbg(dev, "volume_set_config()"); -static int volume_set_large_config(struct comp_dev *dev, uint32_t param_id, - bool first_block, - bool last_block, - uint32_t data_offset, - char *data) -{ - struct vol_data *cd = comp_get_drvdata(dev); - struct ipc4_peak_volume_config *cdata; - int i; + ret = module_set_configuration(mod, config_id, pos, data_offset_size, fragment, + fragment_size, response, response_size); + if (ret < 0) + return ret; - comp_dbg(dev, "volume_set_large_config()"); + /* return if more fragments are expected or if the module is not prepared */ + if ((pos != MODULE_CFG_FRAGMENT_LAST && pos != MODULE_CFG_FRAGMENT_SINGLE) || + md->state < MODULE_IDLE) + return 0; - cdata = (struct ipc4_peak_volume_config *)ASSUME_ALIGNED(data, 8); + cdata = (struct ipc4_peak_volume_config *)ASSUME_ALIGNED(fragment, 8); dcache_invalidate_region(cdata, sizeof(*cdata)); cdata->target_volume = convert_volume_ipc4_to_ipc3(dev, cdata->target_volume); init_ramp(cd, cdata->curve_duration, cdata->target_volume); cd->ramp_finished = true; - switch (param_id) { + switch (config_id) { case IPC4_VOLUME: if (cdata->channel_id == IPC4_ALL_CHANNELS_MASK) { for (i = 0; i < cd->channels; i++) { @@ -1007,7 +942,7 @@ static int volume_set_large_config(struct comp_dev *dev, uint32_t param_id, cdata->curve_duration); cd->volume[i] = cd->vol_min; - volume_set_chan(dev, i, cd->tvolume[i], true); + volume_set_chan(mod, i, cd->tvolume[i], true); if (cd->volume[i] != cd->tvolume[i]) cd->ramp_finished = false; } @@ -1017,7 +952,7 @@ static int volume_set_large_config(struct comp_dev *dev, uint32_t param_id, cdata->curve_duration); cd->volume[cdata->channel_id] = cd->vol_min; - volume_set_chan(dev, cdata->channel_id, cd->tvolume[cdata->channel_id], + volume_set_chan(mod, cdata->channel_id, cd->tvolume[cdata->channel_id], true); if (cd->volume[cdata->channel_id] != cd->tvolume[cdata->channel_id]) cd->ramp_finished = false; @@ -1027,28 +962,27 @@ static int volume_set_large_config(struct comp_dev *dev, uint32_t param_id, break; default: - comp_err(dev, "unsupported param %d", param_id); + comp_err(dev, "unsupported param %d", config_id); return -EINVAL; } return 0; } -static int volume_get_large_config(struct comp_dev *dev, uint32_t param_id, - bool first_block, - bool last_block, - uint32_t *data_offset, - char *data) +static int volume_get_config(struct processing_module *mod, + uint32_t config_id, uint32_t *data_offset_size, + uint8_t *fragment, size_t fragment_size) { - struct vol_data *cd = comp_get_drvdata(dev); + struct vol_data *cd = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; struct ipc4_peak_volume_config *cdata; int i; comp_dbg(dev, "volume_get_large_config()"); - cdata = (struct ipc4_peak_volume_config *)ASSUME_ALIGNED(data, 8); + cdata = (struct ipc4_peak_volume_config *)ASSUME_ALIGNED(fragment, 8); - switch (param_id) { + switch (config_id) { case IPC4_VOLUME: for (i = 0; i < cd->channels; i++) { uint32_t volume = cd->peak_regs.target_volume_[i]; @@ -1056,20 +990,22 @@ static int volume_get_large_config(struct comp_dev *dev, uint32_t param_id, cdata[i].channel_id = i; cdata[i].target_volume = convert_volume_ipc3_to_ipc4(volume); } - *data_offset = sizeof(*cdata) * cd->channels; + *data_offset_size = sizeof(*cdata) * cd->channels; break; default: - comp_err(dev, "unsupported param %d", param_id); + comp_err(dev, "unsupported param %d", config_id); return -EINVAL; } return 0; } -static int volume_params(struct comp_dev *dev, struct sof_ipc_stream_params *params) +static int volume_params(struct processing_module *mod) { - struct vol_data *cd = comp_get_drvdata(dev); + struct vol_data *cd = module_get_private_data(mod); + struct sof_ipc_stream_params *params = mod->stream_params; struct sof_ipc_stream_params vol_params; + struct comp_dev *dev = mod->dev; struct comp_buffer *sinkb; uint32_t valid_fmt; int i; @@ -1099,19 +1035,6 @@ static int volume_params(struct comp_dev *dev, struct sof_ipc_stream_params *par } #endif /* CONFIG_IPC_MAJOR_4 */ -/** - * \brief Sets volume component state. - * \param[in,out] dev Volume base component device. - * \param[in] cmd Command type. - * \return Error code. - */ -static int volume_trigger(struct comp_dev *dev, int cmd) -{ - comp_dbg(dev, "volume_trigger()"); - - return comp_set_state(dev, cmd); -} - static void volume_update_current_vol_ipc4(struct vol_data *cd) { #if CONFIG_IPC_MAJOR_4 @@ -1129,64 +1052,42 @@ static void volume_update_current_vol_ipc4(struct vol_data *cd) * \param[in,out] dev Volume base component device. * \return Error code. */ -static int volume_copy(struct comp_dev *dev) +static int volume_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 c; - struct vol_data *cd = comp_get_drvdata(dev); - struct comp_buffer *source; - struct comp_buffer *sink; - uint32_t source_bytes; - uint32_t sink_bytes; + struct vol_data *cd = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; + uint32_t avail_frames = input_buffers[0].size; uint32_t frames; int64_t prev_sum = 0; - comp_dbg(dev, "volume_copy()"); + comp_dbg(dev, "volume_process()"); - source = list_first_item(&dev->bsource_list, struct comp_buffer, - sink_list); - sink = list_first_item(&dev->bsink_list, struct comp_buffer, - source_list); - - /* Get aligned source, sink, number of frames etc. to process. */ - comp_get_copy_limits_with_lock_frame_aligned(source, sink, &c); - - comp_dbg(dev, "volume_copy(), source_bytes = 0x%x, sink_bytes = 0x%x", - c.source_bytes, c.sink_bytes); - - while (c.frames) { + while (avail_frames) { volume_update_current_vol_ipc4(cd); - if (cd->ramp_finished || cd->vol_ramp_frames > c.frames) { + if (cd->ramp_finished || cd->vol_ramp_frames > avail_frames) { /* without ramping process all at once */ - frames = c.frames; + frames = avail_frames; } else if (cd->ramp_type == SOF_VOLUME_LINEAR_ZC) { /* with ZC ramping look for next ZC offset */ - frames = cd->zc_get(&source->stream, - cd->vol_ramp_frames, &prev_sum); + frames = cd->zc_get(input_buffers[0].data, cd->vol_ramp_frames, &prev_sum); } else { /* without ZC process max ramp chunk */ frames = cd->vol_ramp_frames; } - source_bytes = frames * c.source_frame_bytes; - sink_bytes = frames * c.sink_frame_bytes; - /* copy and scale volume */ - buffer_stream_invalidate(source, source_bytes); - cd->scale_vol(dev, &sink->stream, &source->stream, frames); - buffer_stream_writeback(sink, sink_bytes); - - /* calculate new free and available */ - comp_update_buffer_produce(sink, sink_bytes); - comp_update_buffer_consume(source, source_bytes); + cd->scale_vol(mod, &input_buffers[0], &output_buffers[0], frames); if (cd->vol_ramp_active) cd->vol_ramp_elapsed_frames += frames; if (!cd->ramp_finished) - volume_ramp(dev); + volume_ramp(mod); - c.frames -= frames; + avail_frames -= frames; } return 0; @@ -1256,9 +1157,11 @@ static void volume_set_alignment(struct audio_stream *source, * Volume component is usually first and last in pipelines so it makes sense * to also do some type of conversion here. */ -static int volume_prepare(struct comp_dev *dev) +static int volume_prepare(struct processing_module *mod) { - struct vol_data *cd = comp_get_drvdata(dev); + struct vol_data *cd = module_get_private_data(mod); + struct module_data *md = &mod->priv; + struct comp_dev *dev = mod->dev; struct comp_buffer *sinkb; struct comp_buffer *sourceb; uint32_t sink_period_bytes; @@ -1267,12 +1170,11 @@ static int volume_prepare(struct comp_dev *dev) comp_dbg(dev, "volume_prepare()"); - ret = comp_set_state(dev, COMP_TRIGGER_PREPARE); +#if CONFIG_IPC_MAJOR_4 + ret = volume_params(mod); if (ret < 0) return ret; - - if (ret == COMP_STATUS_STATE_ALREADY_SET) - return PPL_STATUS_PATH_STOP; +#endif /* volume component will only ever have 1 sink and source buffer */ sinkb = list_first_item(&dev->bsink_list, @@ -1325,13 +1227,26 @@ static int volume_prepare(struct comp_dev *dev) cd->sample_rate = sinkb->stream.rate; for (i = 0; i < cd->channels; i++) { cd->volume[i] = cd->vol_min; - volume_set_chan(dev, i, cd->tvolume[i], false); + volume_set_chan(mod, i, cd->tvolume[i], false); if (cd->volume[i] != cd->tvolume[i]) cd->ramp_finished = false; } prepare_ramp(dev, cd); + /* + * volume component does not do any format conversion, so use the buffer size for source + * and sink + */ + md->mpd.in_buff_size = sink_period_bytes; + md->mpd.out_buff_size = sink_period_bytes; + + /* + * also set the simple_copy flag as the volume component always produces period_bytes + * every period and has only 1 input/output buffer + */ + mod->simple_copy = true; + return 0; err: @@ -1344,12 +1259,207 @@ static int volume_prepare(struct comp_dev *dev) * \param[in,out] dev Volume base component device. * \return Error code. */ -static int volume_reset(struct comp_dev *dev) +static int volume_reset(struct processing_module *mod) { - struct vol_data *cd = comp_get_drvdata(dev); + struct vol_data *cd = module_get_private_data(mod); + struct comp_dev *dev = mod->dev; comp_dbg(dev, "volume_reset()"); reset_state(cd); + return 0; +} + +#if CONFIG_COMP_LEGACY_INTERFACE + +static const struct comp_driver comp_volume; + +static struct comp_dev *volume_new(const struct comp_driver *drv, + struct comp_ipc_config *config, + void *spec) +{ + struct processing_module *mod; + struct module_config *dst; + struct module_data *md; + struct comp_dev *dev; + int ret; + + comp_cl_dbg(&comp_volume, "volume_new()"); + + dev = comp_alloc(drv, sizeof(*dev)); + if (!dev) + return NULL; + + dev->ipc_config = *config; + + mod = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, sizeof(*mod)); + if (!mod) { + comp_err(dev, "module_adapter_new(), failed to allocate memory for module"); + goto fail; + } + + comp_set_drvdata(dev, mod); + mod->dev = dev; + + md = &mod->priv; + dst = &md->cfg; + dst->data = rballoc(0, SOF_MEM_CAPS_RAM, sizeof(struct ipc_config_volume)); + if (!dst->data) { + ret = -ENOMEM; + goto mod_free; + } + + ret = memcpy_s(dst->data, sizeof(struct ipc_config_volume), spec, + sizeof(struct ipc_config_volume)); + if (ret < 0) + goto mod_free; + dst->size = sizeof(struct ipc_config_volume); + dst->avail = true; + + ret = volume_init(mod); + if (ret < 0) + goto mod_free; + + dev->state = COMP_STATE_READY; + return dev; +mod_free: + rfree(mod); +fail: + rfree(dev); + return NULL; +} + +static void volume_legacy_free(struct comp_dev *dev) +{ + struct processing_module *mod = comp_get_drvdata(dev); + + comp_dbg(dev, "volume_legacy_free()"); + + volume_free(mod); + + rfree(mod); + rfree(dev); +} + +static int volume_cmd(struct comp_dev *dev, int cmd, void *data, + int max_data_size) +{ + struct sof_ipc_ctrl_data *cdata = ASSUME_ALIGNED(data, 4); + struct processing_module *mod = comp_get_drvdata(dev); + + comp_dbg(dev, "volume_cmd()"); + + switch (cmd) { + case COMP_CMD_SET_VALUE: + return volume_set_config(mod, 0, 0, 0, (const uint8_t *)cdata, 0, NULL, 0); + case COMP_CMD_GET_VALUE: + return volume_get_config(mod, 0, NULL, (uint8_t *)cdata, max_data_size); + default: + return -EINVAL; + } +} + +/** + * \brief Sets volume component state. + * \param[in,out] dev Volume base component device. + * \param[in] cmd Command type. + * \return Error code. + */ +static int volume_trigger(struct comp_dev *dev, int cmd) +{ + comp_dbg(dev, "volume_trigger()"); + + return comp_set_state(dev, cmd); +} + +/** + * \brief Copies and processes stream data. + * \param[in,out] dev Volume base component device. + * \return Error code. + */ +static int volume_copy(struct comp_dev *dev) +{ + struct processing_module *mod = comp_get_drvdata(dev); + struct comp_copy_limits c; + struct comp_buffer *source; + struct comp_buffer *sink; + struct input_stream_buffer input_buffer; + struct output_stream_buffer output_buffer; + uint32_t source_bytes; + int ret; + + comp_dbg(dev, "volume_copy()"); + + source = list_first_item(&dev->bsource_list, struct comp_buffer, + sink_list); + sink = list_first_item(&dev->bsink_list, struct comp_buffer, + source_list); + + /* Get aligned source, sink, number of frames etc. to process. */ + comp_get_copy_limits_with_lock_frame_aligned(source, sink, &c); + + comp_dbg(dev, "volume_copy(), source_bytes = 0x%x, sink_bytes = 0x%x", + c.source_bytes, c.sink_bytes); + + source_bytes = c.frames * c.source_frame_bytes; + buffer_stream_invalidate(source, source_bytes); + + input_buffer.size = c.frames; + input_buffer.data = &source->stream; + input_buffer.consumed = 0; + output_buffer.size = 0; + output_buffer.data = &sink->stream; + + ret = volume_process(mod, &input_buffer, 1, &output_buffer, 1); + if (ret < 0) + return ret; + + buffer_stream_writeback(sink, output_buffer.size); + + /* calculate new free and available */ + comp_update_buffer_produce(sink, output_buffer.size); + comp_update_buffer_consume(source, input_buffer.consumed); + + return 0; +} + +/** + * \brief Prepares volume component for processing. + * \param[in,out] dev Volume base component device. + * \return Error code. + * + * Volume component is usually first and last in pipelines so it makes sense + * to also do some type of conversion here. + */ +static int volume_legacy_prepare(struct comp_dev *dev) +{ + struct processing_module *mod = comp_get_drvdata(dev); + int ret; + + ret = comp_set_state(dev, COMP_TRIGGER_PREPARE); + if (ret < 0) + return ret; + + if (ret == COMP_STATUS_STATE_ALREADY_SET) + return PPL_STATUS_PATH_STOP; + + ret = volume_prepare(mod); + if (ret < 0) + return ret; + + return 0; +} + +/** + * \brief Resets volume component. + * \param[in,out] dev Volume base component device. + * \return Error code. + */ +static int volume_legacy_reset(struct comp_dev *dev) +{ + struct processing_module *mod = comp_get_drvdata(dev); + + comp_dbg(dev, "volume_legacy_reset()"); + volume_reset(mod); comp_set_state(dev, COMP_TRIGGER_RESET); return 0; } @@ -1360,18 +1470,13 @@ static const struct comp_driver comp_volume = { .uid = SOF_RT_UUID(volume_uuid), .tctx = &volume_tr, .ops = { - .create = volume_new, - .free = volume_free, + .create = volume_new, + .free = volume_legacy_free, .cmd = volume_cmd, .trigger = volume_trigger, .copy = volume_copy, - .prepare = volume_prepare, - .reset = volume_reset, -#if CONFIG_IPC_MAJOR_4 - .params = volume_params, - .set_large_config = volume_set_large_config, - .get_large_config = volume_get_large_config, -#endif + .prepare = volume_legacy_prepare, + .reset = volume_legacy_reset, }, }; @@ -1389,39 +1494,30 @@ UT_STATIC void sys_comp_volume_init(void) } DECLARE_MODULE(sys_comp_volume_init); - -#if CONFIG_COMP_GAIN -/** \brief gain component definition. */ -static const struct comp_driver comp_gain = { - .type = SOF_COMP_VOLUME, - .uid = SOF_RT_UUID(gain_uuid), - .tctx = &gain_tr, - .ops = { - .create = volume_new, - .free = volume_free, - .cmd = volume_cmd, - .trigger = volume_trigger, - .copy = volume_copy, - .prepare = volume_prepare, - .reset = volume_reset, - .params = volume_params, - .set_large_config = volume_set_large_config, - .get_large_config = volume_get_large_config, - }, +#else +static struct module_interface volume_interface = { + .init = volume_init, + .prepare = volume_prepare, + .process = volume_process, + .set_configuration = volume_set_config, + .get_configuration = volume_get_config, + .reset = volume_reset, + .free = volume_free }; -static SHARED_DATA struct comp_driver_info comp_gain_info = { - .drv = &comp_gain, -}; +DECLARE_MODULE_ADAPTER(volume_interface, volume_uuid, volume_tr); -/** - * \brief Initializes gain component. - */ -UT_STATIC void sys_comp_gain_init(void) -{ - comp_register(platform_shared_get(&comp_gain_info, - sizeof(comp_gain_info))); -} +#if CONFIG_COMP_GAIN +static struct module_interface gain_interface = { + .init = volume_init, + .prepare = volume_prepare, + .process = volume_process, + .set_configuration = volume_set_config, + .get_configuration = volume_get_config, + .reset = volume_reset, + .free = volume_free +}; -DECLARE_MODULE(sys_comp_gain_init); +DECLARE_MODULE_ADAPTER(gain_interface, gain_uuid, gain_tr); +#endif #endif diff --git a/src/audio/volume/volume_generic.c b/src/audio/module_adapter/module/volume/volume_generic.c similarity index 82% rename from src/audio/volume/volume_generic.c rename to src/audio/module_adapter/module/volume/volume_generic.c index 7f64ee226dd2..8c6865e028c0 100644 --- a/src/audio/volume/volume_generic.c +++ b/src/audio/module_adapter/module/volume/volume_generic.c @@ -52,10 +52,12 @@ static inline int32_t vol_mult_s24_to_s24(int32_t x, int32_t vol) * Copy and scale volume from 24/32 bit source buffer * to 24/32 bit destination buffer. */ -static void vol_s24_to_s24(struct comp_dev *dev, struct audio_stream *sink, - const struct audio_stream *source, uint32_t frames) +static void vol_s24_to_s24(struct processing_module *mod, struct input_stream_buffer *bsource, + struct output_stream_buffer *bsink, uint32_t frames) { - struct vol_data *cd = comp_get_drvdata(dev); + struct vol_data *cd = module_get_private_data(mod); + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; int32_t vol; int32_t *x, *x0; int32_t *y, *y0; @@ -68,6 +70,9 @@ static void vol_s24_to_s24(struct comp_dev *dev, struct audio_stream *sink, 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); while (remaining_samples) { nmax = VOL_BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(source, x)); n = MIN(remaining_samples, nmax); @@ -110,10 +115,12 @@ static void vol_s24_to_s24(struct comp_dev *dev, struct audio_stream *sink, * Copy and scale volume from 32 bit source buffer * to 32 bit destination buffer. */ -static void vol_s32_to_s32(struct comp_dev *dev, struct audio_stream *sink, - const struct audio_stream *source, uint32_t frames) +static void vol_s32_to_s32(struct processing_module *mod, struct input_stream_buffer *bsource, + struct output_stream_buffer *bsink, uint32_t frames) { - struct vol_data *cd = comp_get_drvdata(dev); + struct vol_data *cd = module_get_private_data(mod); + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; int32_t vol; int32_t *x, *x0; int32_t *y, *y0; @@ -126,6 +133,8 @@ static void vol_s32_to_s32(struct comp_dev *dev, struct audio_stream *sink, 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); while (remaining_samples) { nmax = VOL_BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(source, x)); n = MIN(remaining_samples, nmax); @@ -173,10 +182,12 @@ static void vol_s32_to_s32(struct comp_dev *dev, struct audio_stream *sink, * Copy and scale volume from 16 bit source buffer * to 16 bit destination buffer. */ -static void vol_s16_to_s16(struct comp_dev *dev, struct audio_stream *sink, - const struct audio_stream *source, uint32_t frames) +static void vol_s16_to_s16(struct processing_module *mod, struct input_stream_buffer *bsource, + struct output_stream_buffer *bsink, uint32_t frames) { - struct vol_data *cd = comp_get_drvdata(dev); + struct vol_data *cd = module_get_private_data(mod); + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; int32_t vol; int16_t *x, *x0; int16_t *y, *y0; @@ -189,6 +200,9 @@ static void vol_s16_to_s16(struct comp_dev *dev, struct audio_stream *sink, 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); while (remaining_samples) { nmax = VOL_BYTES_TO_S16_SAMPLES(audio_stream_bytes_without_wrap(source, x)); n = MIN(remaining_samples, nmax); diff --git a/src/audio/volume/volume_hifi3.c b/src/audio/module_adapter/module/volume/volume_hifi3.c similarity index 88% rename from src/audio/volume/volume_hifi3.c rename to src/audio/module_adapter/module/volume/volume_hifi3.c index e46bf672bea4..48df13cc4e43 100644 --- a/src/audio/volume/volume_hifi3.c +++ b/src/audio/module_adapter/module/volume/volume_hifi3.c @@ -59,11 +59,12 @@ static inline void peak_vol_calc(struct vol_data *cd, ae_f32x2 out_sample, size_ * \param[in,out] source Source buffer. * \param[in] frames Number of frames to process. */ -static void vol_s24_to_s24_s32(struct comp_dev *dev, struct audio_stream *sink, - const struct audio_stream *source, - uint32_t frames) +static void vol_s24_to_s24_s32(struct processing_module *mod, struct input_stream_buffer *bsource, + struct output_stream_buffer *bsink, uint32_t frames) { - struct vol_data *cd = comp_get_drvdata(dev); + struct vol_data *cd = module_get_private_data(mod); + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; ae_f32x2 in_sample = AE_ZERO32(); ae_f32x2 out_sample = AE_ZERO32(); ae_f32x2 volume = AE_ZERO32(); @@ -91,6 +92,9 @@ static void vol_s24_to_s24_s32(struct comp_dev *dev, struct audio_stream *sink, AE_SETCBEGIN0(buf); AE_SETCEND0(buf_end); + bsource->consumed += VOL_S32_SAMPLES_TO_BYTES(samples); + bsink->size += VOL_S32_SAMPLES_TO_BYTES(samples); + while (samples) { m = VOL_BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(source, in)); n = MIN(m, samples); @@ -139,16 +143,17 @@ static void vol_s24_to_s24_s32(struct comp_dev *dev, struct audio_stream *sink, #if CONFIG_FORMAT_S32LE /** * \brief HiFi3 enabled volume processing from 32 bit to 24/32 or 32 bit. - * \param[in,out] dev Volume base component device. + * \param[in,out] mod Pointer to struct processing_module * \param[in,out] sink Destination buffer. * \param[in,out] source Source buffer. * \param[in] frames Number of frames to process. */ -static void vol_s32_to_s24_s32(struct comp_dev *dev, struct audio_stream *sink, - const struct audio_stream *source, - uint32_t frames) +static void vol_s32_to_s24_s32(struct processing_module *mod, struct input_stream_buffer *bsource, + struct output_stream_buffer *bsink, uint32_t frames) { - struct vol_data *cd = comp_get_drvdata(dev); + struct vol_data *cd = module_get_private_data(mod); + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; ae_f32x2 in_sample = AE_ZERO32(); ae_f32x2 out_sample = AE_ZERO32(); ae_f32x2 volume = AE_ZERO32(); @@ -160,8 +165,8 @@ static void vol_s32_to_s24_s32(struct comp_dev *dev, struct audio_stream *sink, ae_f32x2 *vol; ae_valign inu = AE_ZALIGN64(); ae_valign outu = AE_ZALIGN64(); - const int inc = sizeof(ae_f32x2); const int channels_count = sink->channels; + const int inc = sizeof(ae_f32x2); int samples = channels_count * frames; ae_f32x2 *in = (ae_f32x2 *)source->r_ptr; ae_f32x2 *out = (ae_f32x2 *)sink->w_ptr; @@ -177,6 +182,10 @@ static void vol_s32_to_s24_s32(struct comp_dev *dev, struct audio_stream *sink, /* Set buf who stores the volume gain data as circular buffer */ AE_SETCBEGIN0(buf); AE_SETCEND0(buf_end); + + bsource->consumed += VOL_S32_SAMPLES_TO_BYTES(samples); + bsink->size += VOL_S32_SAMPLES_TO_BYTES(samples); + while (samples) { m = VOL_BYTES_TO_S32_SAMPLES(audio_stream_bytes_without_wrap(source, in)); n = MIN(m, samples); @@ -233,10 +242,12 @@ static void vol_s32_to_s24_s32(struct comp_dev *dev, struct audio_stream *sink, * \param[in,out] source Source buffer. * \param[in] frames Number of frames to process. */ -static void vol_s16_to_s16(struct comp_dev *dev, struct audio_stream *sink, - const struct audio_stream *source, uint32_t frames) +static void vol_s16_to_s16(struct processing_module *mod, struct input_stream_buffer *bsource, + struct output_stream_buffer *bsink, uint32_t frames) { - struct vol_data *cd = comp_get_drvdata(dev); + struct vol_data *cd = module_get_private_data(mod); + struct audio_stream *source = bsource->data; + struct audio_stream *sink = bsink->data; ae_f32x2 volume0 = AE_ZERO32(); ae_f32x2 volume1 = AE_ZERO32(); ae_f32x2 out_sample0 = AE_ZERO32(); @@ -267,6 +278,7 @@ static void vol_s16_to_s16(struct comp_dev *dev, struct audio_stream *sink, /* Set buf as circular buffer */ AE_SETCBEGIN0(buf); AE_SETCEND0(buf_end); + while (samples) { m = VOL_BYTES_TO_S16_SAMPLES(audio_stream_bytes_without_wrap(source, in)); n = MIN(m, samples); @@ -312,6 +324,8 @@ static void vol_s16_to_s16(struct comp_dev *dev, struct audio_stream *sink, } AE_SA64POS_FP(outu, out); samples -= n; + bsource->consumed += VOL_S16_SAMPLES_TO_BYTES(n); + bsink->size += VOL_S16_SAMPLES_TO_BYTES(n); in = audio_stream_wrap(source, in); out = audio_stream_wrap(sink, out); } diff --git a/src/audio/module_adapter/module/waves.c b/src/audio/module_adapter/module/waves.c index 499c4bbf46ee..46d504ce8152 100644 --- a/src/audio/module_adapter/module/waves.c +++ b/src/audio/module_adapter/module/waves.c @@ -821,10 +821,7 @@ static int waves_codec_reset(struct processing_module *mod) static int waves_codec_free(struct processing_module *mod) { - /* codec is using codec_adapter method module_allocate_memory for all allocations - * codec_adapter will free it all on component free call - * nothing to do here - */ + module_free_all_memory(mod); comp_dbg(mod->dev, "waves_codec_free()"); return 0; } diff --git a/src/audio/module_adapter/module_adapter.c b/src/audio/module_adapter/module_adapter.c index a31c12ba1bb9..1283dd7217df 100644 --- a/src/audio/module_adapter/module_adapter.c +++ b/src/audio/module_adapter/module_adapter.c @@ -35,14 +35,29 @@ struct comp_dev *module_adapter_new(const struct comp_driver *drv, int ret; struct comp_dev *dev; struct processing_module *mod; - struct ipc_config_process *ipc_module_adapter = spec; unsigned char *data; uint32_t size; - comp_cl_dbg(drv, "module_adapter_new() start"); + switch (config->type) { + case SOF_COMP_VOLUME: + { + struct ipc_config_volume *ipc_volume = spec; - size = ipc_module_adapter->size; - data = ipc_module_adapter->data; + size = sizeof(*ipc_volume); + data = spec; + break; + } + default: + { + struct ipc_config_process *ipc_module_adapter = spec; + + size = ipc_module_adapter->size; + data = ipc_module_adapter->data; + break; + } + } + + comp_cl_dbg(drv, "module_adapter_new() start"); if (!config) { comp_cl_err(drv, "module_adapter_new(), wrong input params! drv = %x config = %x", @@ -205,6 +220,29 @@ int module_adapter_prepare(struct comp_dev *dev) return -ENOMEM; } + /* allocate memory for output buffers */ + mod->output_buffers = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, + sizeof(*mod->output_buffers) * mod->num_output_buffers); + if (!mod->output_buffers) { + comp_err(dev, "module_adapter_prepare(): failed to allocate output buffers"); + ret = -ENOMEM; + goto in_free; + } + + /* + * no need to allocate intermediate sink buffers if the module produces only period bytes + * every period and has only 1 input and 1 output buffer + */ + if (mod->simple_copy) { + struct comp_buffer *source, *sink; + + source = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); + sink = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); + mod->input_buffers[0].data = &source->stream; + mod->output_buffers[0].data = &sink->stream; + return 0; + } + /* allocate memory for input buffer data */ list_for_item(blist, &dev->bsource_list) { size_t size = MAX(mod->deep_buff_bytes, mod->period_bytes); @@ -218,15 +256,6 @@ int module_adapter_prepare(struct comp_dev *dev) i++; } - /* allocate memory for output buffers */ - mod->output_buffers = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, - sizeof(*mod->output_buffers) * mod->num_output_buffers); - if (!mod->output_buffers) { - comp_err(dev, "module_adapter_prepare(): failed to allocate output buffers"); - ret = -ENOMEM; - goto in_free; - } - /* allocate memory for output buffer data */ i = 0; list_for_item(blist, &dev->bsink_list) { @@ -456,26 +485,19 @@ static void module_copy_samples(struct comp_dev *dev, struct comp_buffer *src_bu static void module_adapter_process_output(struct comp_dev *dev) { struct processing_module *mod = comp_get_drvdata(dev); - struct module_data *md = &mod->priv; struct comp_buffer *sink; struct list_item *blist; int i; /* - * When a module produces only period_bytes every period, skip copying the produced - * samples to the intermediate buffer and copy to the sink buffer directly + * When a module produces only period_bytes every period, the produced samples are written + * to the output buffer stream directly. So, just writeback buffer stream and reset size. */ - if (md->mpd.out_buff_size == mod->period_bytes) { - i = 0; - list_for_item(blist, &dev->bsink_list) { - sink = container_of(blist, struct comp_buffer, source_list); - ca_copy_from_module_to_sink(&sink->stream, mod->output_buffers[i].data, - mod->output_buffers[i].size); - buffer_stream_writeback(sink, mod->output_buffers[i].size); - audio_stream_produce(&sink->stream, mod->output_buffers[i].size); - mod->output_buffers[i].size = 0; - i++; - } + if (mod->simple_copy) { + sink = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); + buffer_stream_writeback(sink, mod->output_buffers[0].size); + comp_update_buffer_produce(sink, mod->output_buffers[0].size); + mod->output_buffers[0].size = 0; return; } @@ -524,38 +546,59 @@ int module_adapter_copy(struct comp_dev *dev) struct comp_buffer *sink; struct processing_module *mod = comp_get_drvdata(dev); struct module_data *md = &mod->priv; + struct comp_copy_limits c; struct list_item *blist; size_t size = MAX(mod->deep_buff_bytes, mod->period_bytes); uint32_t min_free_frames = UINT_MAX; int ret, i = 0; - /* get the least number of free frames from all sinks */ - list_for_item(blist, &mod->sink_buffer_list) { - sink = container_of(blist, struct comp_buffer, sink_list); - min_free_frames = MIN(min_free_frames, - audio_stream_get_free_frames(&sink->stream)); - } + comp_info(dev, "module_adapter_copy(): start"); - /* copy source samples into input buffer */ - list_for_item(blist, &dev->bsource_list) { - uint32_t bytes_to_process; - int frames, source_frame_bytes; + source = list_first_item(&dev->bsource_list, struct comp_buffer, sink_list); + sink = list_first_item(&dev->bsink_list, struct comp_buffer, source_list); - source = container_of(blist, struct comp_buffer, sink_list); + /* + * Simplify calculation of bytes_to_process for modules that produce period_bytes every + * period and have only 1 source and 1 sink buffer + */ + if (mod->simple_copy) { + comp_get_copy_limits_with_lock_frame_aligned(source, sink, &c); + buffer_stream_invalidate(source, c.frames * c.source_frame_bytes); + + /* note that the size is in number of frames not the number of bytes */ + mod->input_buffers[0].size = c.frames; + mod->input_buffers[0].consumed = 0; + mod->output_buffers[0].size = 0; + } else { + list_for_item(blist, &mod->sink_buffer_list) { + sink = container_of(blist, struct comp_buffer, sink_list); + min_free_frames = MIN(min_free_frames, + audio_stream_get_free_frames(&sink->stream)); + } - source = buffer_acquire(source); - frames = MIN(min_free_frames, audio_stream_get_avail_frames(&source->stream)); - source_frame_bytes = audio_stream_frame_bytes(&source->stream); - source = buffer_release(source); + /* copy source samples into input buffer */ + list_for_item(blist, &dev->bsource_list) { + uint32_t bytes_to_process; + int frames, source_frame_bytes; - bytes_to_process = MIN(frames * source_frame_bytes, md->mpd.in_buff_size); + source = container_of(blist, struct comp_buffer, sink_list); - buffer_stream_invalidate(source, bytes_to_process); - mod->input_buffers[i].size = bytes_to_process; - mod->input_buffers[i].consumed = 0; - ca_copy_from_source_to_module(&source->stream, mod->input_buffers[i].data, - md->mpd.in_buff_size, bytes_to_process); - i++; + source = buffer_acquire(source); + frames = MIN(min_free_frames, + audio_stream_get_avail_frames(&source->stream)); + source_frame_bytes = audio_stream_frame_bytes(&source->stream); + source = buffer_release(source); + + bytes_to_process = MIN(frames * source_frame_bytes, md->mpd.in_buff_size); + + buffer_stream_invalidate(source, bytes_to_process); + mod->input_buffers[i].size = bytes_to_process; + mod->input_buffers[i].consumed = 0; + + ca_copy_from_source_to_module(&source->stream, mod->input_buffers[i].data, + md->mpd.in_buff_size, bytes_to_process); + i++; + } } ret = module_process(mod, mod->input_buffers, mod->num_input_buffers, @@ -570,15 +613,21 @@ int module_adapter_copy(struct comp_dev *dev) ret = 0; } - /* consume from all input buffers */ - i = 0; - list_for_item(blist, &dev->bsource_list) { - source = container_of(blist, struct comp_buffer, sink_list); - comp_update_buffer_consume(source, mod->input_buffers[i].consumed); - bzero(mod->input_buffers[i].data, size); - mod->input_buffers[i].size = 0; - mod->input_buffers[i].consumed = 0; - i++; + if (mod->simple_copy) { + comp_update_buffer_consume(source, mod->input_buffers[0].consumed); + mod->input_buffers[0].size = 0; + mod->input_buffers[0].consumed = 0; + } else { + i = 0; + /* consume from all input buffers */ + list_for_item(blist, &dev->bsource_list) { + source = container_of(blist, struct comp_buffer, sink_list); + comp_update_buffer_consume(source, mod->input_buffers[i].consumed); + bzero(mod->input_buffers[i].data, size); + mod->input_buffers[i].size = 0; + mod->input_buffers[i].consumed = 0; + i++; + } } module_adapter_process_output(dev); @@ -589,7 +638,8 @@ int module_adapter_copy(struct comp_dev *dev) mod->output_buffers[i].size = 0; for (i = 0; i < mod->num_input_buffers; i++) { - bzero(mod->input_buffers[i].data, size); + if (!mod->simple_copy) + bzero(mod->input_buffers[i].data, size); mod->input_buffers[i].size = 0; mod->input_buffers[i].consumed = 0; } @@ -733,13 +783,15 @@ int module_adapter_reset(struct comp_dev *dev) comp_err(dev, "module_adapter_reset(): failed with error: %d", ret); } - for (i = 0; i < mod->num_output_buffers; i++) - rfree(mod->output_buffers[i].data); + if (!mod->simple_copy) + for (i = 0; i < mod->num_output_buffers; i++) + rfree(mod->output_buffers[i].data); rfree(mod->output_buffers); - for (i = 0; i < mod->num_input_buffers; i++) - rfree(mod->input_buffers[i].data); + if (!mod->simple_copy) + for (i = 0; i < mod->num_input_buffers; i++) + rfree(mod->input_buffers[i].data); rfree(mod->input_buffers); diff --git a/src/audio/volume/CMakeLists.txt b/src/audio/volume/CMakeLists.txt deleted file mode 100644 index a39492b7b26b..000000000000 --- a/src/audio/volume/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -# SPDX-License-Identifier: BSD-3-Clause - -add_local_sources(sof volume_generic.c volume_hifi3.c volume.c) diff --git a/src/include/sof/audio/module_adapter/module/generic.h b/src/include/sof/audio/module_adapter/module/generic.h index e356758fad78..c21f44dc5b5b 100644 --- a/src/include/sof/audio/module_adapter/module/generic.h +++ b/src/include/sof/audio/module_adapter/module/generic.h @@ -293,6 +293,11 @@ struct processing_module { struct output_stream_buffer *output_buffers; uint32_t num_input_buffers; /**< number of input buffers */ uint32_t num_output_buffers; /**< number of output buffers */ + /* + * flag set by a module when it has 1 input buffer and 1 output buffer and produces + * period_bytes every copy + */ + bool simple_copy; }; /*****************************************************************************/ diff --git a/src/include/sof/audio/volume.h b/src/include/sof/audio/volume.h index 6fb50e27cd01..3862f9bba7e7 100644 --- a/src/include/sof/audio/volume.h +++ b/src/include/sof/audio/volume.h @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -105,12 +106,14 @@ struct sof_ipc_ctrl_value_chan; #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 */ -typedef void (*vol_scale_func)(struct comp_dev *dev, struct audio_stream *sink, - const struct audio_stream *source, - uint32_t frames); +typedef void (*vol_scale_func)(struct processing_module *mod, struct input_stream_buffer *source, + struct output_stream_buffer *sink, uint32_t frames); /** * \brief volume interface for function getting nearest zero crossing frame @@ -122,7 +125,7 @@ typedef uint32_t (*vol_zc_func)(const struct audio_stream *source, * \brief Function for volume ramp shape function */ -typedef int32_t (*vol_ramp_func)(struct comp_dev *dev, int32_t ramp_time, int channel); +typedef int32_t (*vol_ramp_func)(struct processing_module *mod, int32_t ramp_time, int channel); struct vol_data { #if CONFIG_IPC_MAJOR_4 @@ -207,7 +210,8 @@ static inline vol_scale_func vol_get_processing_function(struct comp_dev *dev) { LOG_MODULE_DECLARE(volume, CONFIG_SOF_LOG_LEVEL); - struct vol_data *cd = comp_get_drvdata(dev); + struct processing_module *mod = comp_get_drvdata(dev); + struct vol_data *cd = module_get_private_data(mod); switch (cd->base.audio_fmt.depth) { case IPC4_DEPTH_16BIT: @@ -231,7 +235,11 @@ static inline void peak_vol_update(struct vol_data *cd) } #ifdef UNIT_TEST +#if CONFIG_COMP_LEGACY_INTERFACE void sys_comp_volume_init(void); +#else +void sys_comp_module_volume_interface_init(void); +#endif #endif #endif /* __SOF_AUDIO_VOLUME_H__ */ diff --git a/src/include/sof/lib/uuid.h b/src/include/sof/lib/uuid.h index 0d8ae0d1476e..887a6124dc92 100644 --- a/src/include/sof/lib/uuid.h +++ b/src/include/sof/lib/uuid.h @@ -55,19 +55,6 @@ struct sof_uuid_entry { const char name[UUID_NAME_MAX_LEN]; }; -#if CONFIG_LIBRARY -#define DECLARE_SOF_UUID(entity_name, uuid_name, \ - va, vb, vc, \ - vd0, vd1, vd2, vd3, vd4, vd5, vd6, vd7) -#define DECLARE_SOF_RT_UUID(entity_name, uuid_name, \ - va, vb, vc, \ - vd0, vd1, vd2, vd3, vd4, vd5, vd6, vd7) - -#define SOF_UUID(uuid_name) 0 -#define SOF_RT_UUID(uuid_name) NULL - -#else - /** \brief Declares UUID (aaaaaaaa-bbbb-cccc-d0d1-d2d3d4d5d6d7) and name. * * UUID value from variables declared with this macro are unaccessible in @@ -139,7 +126,6 @@ struct sof_uuid_entry { * \param uuid_name UUID symbol name declared with DECLARE_SOF_RT_UUID(). */ #define SOF_RT_UUID(uuid_name) (&(uuid_name)) -#endif /** @}*/ diff --git a/test/cmocka/src/audio/volume/CMakeLists.txt b/test/cmocka/src/audio/volume/CMakeLists.txt index 063308f5b037..e5f7051e8a6e 100644 --- a/test/cmocka/src/audio/volume/CMakeLists.txt +++ b/test/cmocka/src/audio/volume/CMakeLists.txt @@ -12,9 +12,11 @@ target_include_directories(volume_process PRIVATE ${PROJECT_SOURCE_DIR}/src/audi add_compile_options(-DUNIT_TEST) add_library(audio_for_volume STATIC - ${PROJECT_SOURCE_DIR}/src/audio/volume/volume.c - ${PROJECT_SOURCE_DIR}/src/audio/volume/volume_generic.c - ${PROJECT_SOURCE_DIR}/src/audio/volume/volume_hifi3.c + ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module/volume/volume.c + ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module/volume/volume_generic.c + ${PROJECT_SOURCE_DIR}/src/audio/module_adapter/module/volume/volume_hifi3.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/audio/buffer.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc3/helper.c ${PROJECT_SOURCE_DIR}/src/ipc/ipc-common.c diff --git a/test/cmocka/src/audio/volume/volume_process.c b/test/cmocka/src/audio/volume/volume_process.c index 0412e7c10d4e..408b3dc16e77 100644 --- a/test/cmocka/src/audio/volume/volume_process.c +++ b/test/cmocka/src/audio/volume/volume_process.c @@ -12,6 +12,7 @@ #include #include #include +#include #include /* Add macro for a volume test level. The levels to test with this code @@ -30,10 +31,15 @@ #define INT24_MIN -8388608 struct vol_test_state { - struct comp_dev *dev; + struct processing_module *mod; struct comp_buffer *sink; struct comp_buffer *source; - void (*verify)(struct comp_dev *dev, struct comp_buffer *sink, struct comp_buffer *source); + struct input_stream_buffer *input; + struct output_stream_buffer *output; + size_t size; + uint32_t channels; + void (*verify)(struct processing_module *mod, struct comp_buffer *sink, + struct comp_buffer *source); }; struct vol_test_parameters { @@ -43,7 +49,8 @@ struct vol_test_parameters { uint32_t buffer_size_ms; uint32_t source_format; uint32_t sink_format; - void (*verify)(struct comp_dev *dev, struct comp_buffer *sink, struct comp_buffer *source); + void (*verify)(struct processing_module *mod, struct comp_buffer *sink, + struct comp_buffer *source); }; static void set_volume(int32_t *vol, int32_t value, uint32_t channels) @@ -58,6 +65,8 @@ static int setup(void **state) { struct vol_test_parameters *parameters = *state; struct vol_test_state *vol_state; + struct module_data *md; + struct comp_dev *dev; struct vol_data *cd; uint32_t size = 0; @@ -65,12 +74,16 @@ static int setup(void **state) vol_state = test_malloc(sizeof(*vol_state)); /* allocate and set new device */ - vol_state->dev = test_malloc(sizeof(struct comp_dev)); - vol_state->dev->frames = parameters->frames; + vol_state->mod = test_malloc(sizeof(struct processing_module)); + dev = test_malloc(sizeof(struct comp_dev)); + dev->frames = parameters->frames; /* allocate and set new data */ + vol_state->mod->dev = dev; cd = test_malloc(sizeof(*cd)); - comp_set_drvdata(vol_state->dev, cd); + md = &vol_state->mod->priv; + comp_set_drvdata(dev, vol_state->mod); + md->private = cd; /* malloc memory to store current volume 4 times to ensure the address * is 8-byte aligned for multi-way xtensa intrinsic operations. @@ -79,25 +92,33 @@ static int setup(void **state) cd->vol = test_malloc(vol_size); - list_init(&vol_state->dev->bsource_list); - list_init(&vol_state->dev->bsink_list); + list_init(&dev->bsource_list); + list_init(&dev->bsink_list); /* allocate new sink buffer */ size = parameters->frames * get_frame_bytes(parameters->sink_format, parameters->channels) * parameters->buffer_size_ms; + vol_state->size = size; + vol_state->channels = parameters->channels; - vol_state->sink = create_test_sink(vol_state->dev, 0, parameters->sink_format, + vol_state->sink = create_test_sink(dev, 0, parameters->sink_format, parameters->channels, size); /* allocate new source buffer */ size = parameters->frames * get_frame_bytes(parameters->source_format, parameters->channels) * parameters->buffer_size_ms; - vol_state->source = create_test_source(vol_state->dev, 0, parameters->source_format, + vol_state->source = create_test_source(dev, 0, parameters->source_format, parameters->channels, size); + /* allocate intermediate buffers */ + vol_state->input = test_malloc(sizeof(struct input_stream_buffer)); + vol_state->input->data = &vol_state->source->stream; + vol_state->output = test_malloc(sizeof(struct output_stream_buffer)); + vol_state->output->data = &vol_state->sink->stream; + /* set processing function and volume */ - cd->scale_vol = vol_get_processing_function(vol_state->dev); + cd->scale_vol = vol_get_processing_function(dev); set_volume(cd->volume, parameters->volume, parameters->channels); /* assigns verification function */ @@ -112,12 +133,15 @@ static int setup(void **state) static int teardown(void **state) { struct vol_test_state *vol_state = *state; - struct vol_data *cd = comp_get_drvdata(vol_state->dev); + struct vol_data *cd = module_get_private_data(vol_state->mod); /* free everything */ test_free(cd->vol); test_free(cd); - test_free(vol_state->dev); + test_free(vol_state->mod->dev); + test_free(vol_state->mod); + test_free(vol_state->input); + test_free(vol_state->output); free_test_sink(vol_state->sink); free_test_source(vol_state->source); test_free(vol_state); @@ -141,10 +165,10 @@ static void fill_source_s16(struct vol_test_state *vol_state) } } -static void verify_s16_to_s16(struct comp_dev *dev, struct comp_buffer *sink, +static void verify_s16_to_s16(struct processing_module *mod, struct comp_buffer *sink, struct comp_buffer *source) { - struct vol_data *cd = comp_get_drvdata(dev); + struct vol_data *cd = module_get_private_data(mod); const int16_t *src = (int16_t *)source->stream.r_ptr; const int16_t *dst = (int16_t *)sink->stream.w_ptr; double processed; @@ -190,11 +214,11 @@ static void fill_source_s24(struct vol_test_state *vol_state) } } -static void verify_s24_to_s24_s32(struct comp_dev *dev, +static void verify_s24_to_s24_s32(struct processing_module *mod, struct comp_buffer *sink, struct comp_buffer *source) { - struct vol_data *cd = comp_get_drvdata(dev); + struct vol_data *cd = module_get_private_data(mod); const int32_t *src = (int32_t *)source->stream.r_ptr; const int32_t *dst = (int32_t *)sink->stream.w_ptr; double processed; @@ -247,11 +271,11 @@ static void fill_source_s32(struct vol_test_state *vol_state) } } -static void verify_s32_to_s24_s32(struct comp_dev *dev, +static void verify_s32_to_s24_s32(struct processing_module *mod, struct comp_buffer *sink, struct comp_buffer *source) { - struct vol_data *cd = comp_get_drvdata(dev); + struct vol_data *cd = module_get_private_data(mod); double processed; const int32_t *src = (int32_t *)source->stream.r_ptr; const int32_t *dst = (int32_t *)sink->stream.w_ptr; @@ -380,7 +404,8 @@ static void verify_sX_to_s16(struct comp_dev *dev, struct comp_buffer *sink, static void test_audio_vol(void **state) { struct vol_test_state *vol_state = *state; - struct vol_data *cd = comp_get_drvdata(vol_state->dev); + struct processing_module *mod = vol_state->mod; + struct vol_data *cd = module_get_private_data(mod); switch (vol_state->sink->stream.frame_fmt) { case SOF_IPC_FRAME_S16_LE: @@ -398,10 +423,12 @@ static void test_audio_vol(void **state) break; } - cd->scale_vol(vol_state->dev, &vol_state->sink->stream, - &vol_state->source->stream, vol_state->dev->frames); + vol_state->input->consumed = 0; + vol_state->output->size = 0; + + cd->scale_vol(mod, vol_state->input, vol_state->output, mod->dev->frames); - vol_state->verify(vol_state->dev, vol_state->sink, vol_state->source); + vol_state->verify(mod, vol_state->sink, vol_state->source); } static struct vol_test_parameters parameters[] = { diff --git a/tools/tplg_parser/include/tplg_parser/topology.h b/tools/tplg_parser/include/tplg_parser/topology.h index 6f12df9c9e12..4d090e89fa50 100644 --- a/tools/tplg_parser/include/tplg_parser/topology.h +++ b/tools/tplg_parser/include/tplg_parser/topology.h @@ -142,9 +142,8 @@ int get_token_dai_type(void *elem, void *object, uint32_t offset, /* Component extended tokens */ static const struct sof_topology_token comp_ext_tokens[] = { - {SOF_TKN_COMP_UUID, - SND_SOC_TPLG_TUPLE_TYPE_UUID, get_token_uuid, - offsetof(struct sof_ipc_comp_ext, uuid), 0}, + {SOF_TKN_COMP_UUID, SND_SOC_TPLG_TUPLE_TYPE_UUID, get_token_uuid, 0, 0}, + }; struct sof_dai_types { @@ -182,8 +181,7 @@ int tplg_create_pcm(struct tplg_context *ctx, int dir, struct sof_ipc_comp_host *host); int tplg_create_dai(struct tplg_context *ctx, struct sof_ipc_comp_dai *comp_dai); -int tplg_create_pga(struct tplg_context *ctx, - struct sof_ipc_comp_volume *volume); +int tplg_create_pga(struct tplg_context *ctx, struct sof_ipc_comp_volume *volume); int tplg_create_pipeline(struct tplg_context *ctx, struct sof_ipc_pipe_new *pipeline); int tplg_create_single_control(struct snd_soc_tplg_ctl_hdr **ctl, char **priv, diff --git a/tools/tplg_parser/pga.c b/tools/tplg_parser/pga.c index 05fdcdebac4d..a350c7088b6f 100644 --- a/tools/tplg_parser/pga.c +++ b/tools/tplg_parser/pga.c @@ -40,6 +40,7 @@ int tplg_create_pga(struct tplg_context *ctx, struct sof_ipc_comp_volume *volume FILE *file = ctx->file; int size = ctx->widget->priv.size; int comp_id = ctx->comp_id; + char uuid[UUID_SIZE]; int ret; /* allocate memory for vendor tuple array */ @@ -93,16 +94,28 @@ int tplg_create_pga(struct tplg_context *ctx, struct sof_ipc_comp_volume *volume return -EINVAL; } + /* parse uuid token */ + ret = sof_parse_tokens(uuid, comp_ext_tokens, + ARRAY_SIZE(comp_ext_tokens), array, + array->size); + if (ret != 0) { + fprintf(stderr, "error: parse pga uuid token %d\n", size); + free(array); + return -EINVAL; + } + total_array_size += array->size; } /* configure volume */ volume->comp.hdr.cmd = SOF_IPC_GLB_TPLG_MSG | SOF_IPC_TPLG_COMP_NEW; volume->comp.id = comp_id; - volume->comp.hdr.size = sizeof(struct sof_ipc_comp_volume); + volume->comp.hdr.size = sizeof(struct sof_ipc_comp_volume) + UUID_SIZE; volume->comp.type = SOF_COMP_VOLUME; volume->comp.pipeline_id = ctx->pipeline_id; + volume->comp.ext_data_length = UUID_SIZE; volume->config.hdr.size = sizeof(struct sof_ipc_comp_config); + memcpy(volume + 1, &uuid, UUID_SIZE); free(array); return 0; @@ -112,7 +125,8 @@ int tplg_create_pga(struct tplg_context *ctx, struct sof_ipc_comp_volume *volume int tplg_register_pga(struct tplg_context *ctx) { struct sof *sof = ctx->sof; - struct sof_ipc_comp_volume volume = {}; + struct sof_ipc_comp *comp; + struct sof_ipc_comp_volume *volume; struct snd_soc_tplg_ctl_hdr *ctl = NULL; struct snd_soc_tplg_mixer_control *mixer_ctl; char *priv_data = NULL; @@ -124,14 +138,23 @@ int tplg_register_pga(struct tplg_context *ctx) int channels = 0; int ret = 0; - ret = tplg_create_pga(ctx, &volume); + volume = malloc(sizeof(*volume) + UUID_SIZE); + if (!volume) + return -ENOMEM; + + memset(volume, 0, sizeof(*volume) + UUID_SIZE); + + comp = &volume->comp; + + ret = tplg_create_pga(ctx, volume); if (ret < 0) - return ret; + goto err; /* Only one control is supported*/ if (ctx->widget->num_kcontrols > 1) { fprintf(stderr, "error: more than one kcontrol defined\n"); - return -EINVAL; + ret = -EINVAL; + goto err; } /* Get control into ctl and priv_data */ @@ -139,7 +162,7 @@ int tplg_register_pga(struct tplg_context *ctx) ret = tplg_create_single_control(&ctl, &priv_data, ctx->file); if (ret < 0) { fprintf(stderr, "error: failed control load\n"); - return ret; + goto err; } /* Get volume scale */ @@ -152,19 +175,22 @@ int tplg_register_pga(struct tplg_context *ctx) vol_min_db = 0.01 * vol_min; vol_max_db = 0.01 * (vol_maxs * vol_step) + vol_min_db; - volume.min_value = round(pow(10, vol_min_db / 20.0) * 65535); - volume.max_value = round(pow(10, vol_max_db / 20.0) * 65536); - volume.channels = channels; + volume->min_value = round(pow(10, vol_min_db / 20.0) * 65535); + volume->max_value = round(pow(10, vol_max_db / 20.0) * 65536); + volume->channels = channels; free(ctl); free(priv_data); /* load volume component */ - register_comp(volume.comp.type, NULL); - if (ipc_comp_new(sof->ipc, ipc_to_comp_new(&volume)) < 0) { + register_comp(comp->type, NULL); + if (ipc_comp_new(sof->ipc, ipc_to_comp_new(comp)) < 0) { fprintf(stderr, "error: new pga comp\n"); - return -EINVAL; + ret = -EINVAL; + goto err; } - return 0; +err: + free(volume); + return ret; } diff --git a/zephyr/CMakeLists.txt b/zephyr/CMakeLists.txt index 8b0d160b1537..dbc25a3537f9 100644 --- a/zephyr/CMakeLists.txt +++ b/zephyr/CMakeLists.txt @@ -46,6 +46,7 @@ zephyr_interface_library_named(SOF) set(SOF_SRC_PATH "../src") set(SOF_PLATFORM_PATH "${SOF_SRC_PATH}/platform") set(SOF_AUDIO_PATH "${SOF_SRC_PATH}/audio") +set(SOF_AUDIO_MODULES_PATH "${SOF_SRC_PATH}/audio/module_adapter/module") set(SOF_SAMPLES_PATH "${SOF_SRC_PATH}/samples") set(SOF_LIB_PATH "${SOF_SRC_PATH}/lib") set(SOF_DRIVERS_PATH "${SOF_SRC_PATH}/drivers") @@ -620,9 +621,9 @@ zephyr_library_sources_ifdef(CONFIG_SAMPLE_KEYPHRASE ) zephyr_library_sources_ifdef(CONFIG_COMP_VOLUME - ${SOF_AUDIO_PATH}/volume/volume_hifi3.c - ${SOF_AUDIO_PATH}/volume/volume_generic.c - ${SOF_AUDIO_PATH}/volume/volume.c + ${SOF_AUDIO_MODULES_PATH}/volume/volume_hifi3.c + ${SOF_AUDIO_MODULES_PATH}/volume/volume_generic.c + ${SOF_AUDIO_MODULES_PATH}/volume/volume.c ) zephyr_library_sources_ifdef(CONFIG_COMP_MODULE_ADAPTER @@ -644,7 +645,7 @@ zephyr_library_import(xa_aac_dec ${CONFIG_CADENCE_CODEC_AAC_DEC_LIB}) endif() zephyr_library_sources_ifdef(CONFIG_PASSTHROUGH_CODEC - ${SOF_AUDIO_PATH}/codec_adapter/codec/passthrough.c + ${SOF_AUDIO_MODULES_PATH}/passthrough.c ) endif() diff --git a/zephyr/wrapper.c b/zephyr/wrapper.c index 92a7df5a36bd..f260176aa79d 100644 --- a/zephyr/wrapper.c +++ b/zephyr/wrapper.c @@ -440,7 +440,6 @@ static void sys_module_init(void) * constructors directly atm. */ -void sys_comp_volume_init(void); void sys_comp_host_init(void); void sys_comp_mixer_init(void); void sys_comp_dai_init(void); @@ -460,7 +459,12 @@ void sys_comp_basefw_init(void); void sys_comp_copier_init(void); void sys_comp_module_cadence_interface_init(void); void sys_comp_module_passthrough_interface_init(void); -void sys_comp_gain_init(void); +#if CONFIG_COMP_LEGACY_INTERFACE +void sys_comp_volume_init(void); +#else +void sys_comp_module_volume_interface_init(void); +#endif +void sys_comp_module_gain_interface_init(void); void sys_comp_mixin_init(void); /* Zephyr redefines log_message() and mtrace_printf() which leaves @@ -500,10 +504,14 @@ int task_main_start(struct sof *sof) sys_comp_host_init(); if (IS_ENABLED(CONFIG_COMP_VOLUME)) { +#if CONFIG_COMP_LEGACY_INTERFACE sys_comp_volume_init(); +#else + sys_comp_module_volume_interface_init(); +#endif if (IS_ENABLED(CONFIG_IPC_MAJOR_4)) - sys_comp_gain_init(); + sys_comp_module_gain_interface_init(); } if (IS_ENABLED(CONFIG_COMP_MIXER)) {