Audio: mux: split mux code with ipc3 and ipc4

This is a clean up, purpose is de-cluster headers, toml files,
Readme.md etc per module basis, since today everything is
scattered in current code base.

Signed-off-by: Baofeng Tian <baofeng.tian@intel.com>
This commit is contained in:
Baofeng Tian 2023-12-08 16:33:14 +08:00 committed by Kai Vehmanen
parent 11a806bffe
commit ae464443c8
11 changed files with 299 additions and 203 deletions

View File

@ -184,6 +184,7 @@ if(CONFIG_IPC_MAJOR_3)
set(tdfb_sources tdfb/tdfb_ipc3.c)
set(tdfb_sources multiband_drc/multiband_drc_ipc3.c)
set(dcblock_sources dcblock/dcblock_ipc3.c)
set(mux_sources mux/mux_ipc3.c)
elseif(CONFIG_IPC_MAJOR_4)
set(volume_sources volume/volume.c volume/volume_generic.c volume/volume_ipc4.c)
set(asrc_sources asrc/asrc_ipc4.c)
@ -193,6 +194,7 @@ elseif(CONFIG_IPC_MAJOR_4)
set(tdfb_sources tdfb/tdfb_ipc4.c)
set(tdfb_sources multiband_drc/multiband_drc_ipc4.c)
set(dcblock_sources dcblock/dcblock_ipc4.c)
set(mux_sources mux/mux_ipc4.c)
endif()
set(mixer_sources ${mixer_src})
set(asrc_sources asrc/asrc.c asrc/asrc_farrow.c asrc/asrc_farrow_generic.c)

View File

@ -1,3 +1,10 @@
# SPDX-License-Identifier: BSD-3-Clause
add_local_sources(sof mux.c mux_generic.c)
if(CONFIG_IPC_MAJOR_3)
add_local_sources(sof mux_ipc3.c)
elseif(CONFIG_IPC_MAJOR_4)
add_local_sources(sof mux_ipc4.c)
endif()

View File

@ -33,28 +33,8 @@
#include "mux.h"
#define MUX_BLOB_STREAMS_SIZE (MUX_MAX_STREAMS * sizeof(struct mux_stream_data))
#define MUX_BLOB_MAX_SIZE (sizeof(struct sof_mux_config) + MUX_BLOB_STREAMS_SIZE)
LOG_MODULE_REGISTER(muxdemux, CONFIG_SOF_LOG_LEVEL);
#if CONFIG_IPC_MAJOR_3
/* c607ff4d-9cb6-49dc-b678-7da3c63ea557 */
DECLARE_SOF_RT_UUID("mux", mux_uuid, 0xc607ff4d, 0x9cb6, 0x49dc,
0xb6, 0x78, 0x7d, 0xa3, 0xc6, 0x3e, 0xa5, 0x57);
#else
/* 64ce6e35-857a-4878-ace8-e2a2f42e3069 */
DECLARE_SOF_RT_UUID("mux", mux_uuid, 0x64ce6e35, 0x857a, 0x4878,
0xac, 0xe8, 0xe2, 0xa2, 0xf4, 0x2e, 0x30, 0x69);
#endif
DECLARE_TR_CTX(mux_tr, SOF_UUID(mux_uuid), LOG_LEVEL_INFO);
/* c4b26868-1430-470e-a089-15d1c77f851a */
DECLARE_SOF_RT_UUID("demux", demux_uuid, 0xc4b26868, 0x1430, 0x470e,
0xa0, 0x89, 0x15, 0xd1, 0xc7, 0x7f, 0x85, 0x1a);
DECLARE_TR_CTX(demux_tr, SOF_UUID(demux_uuid), LOG_LEVEL_INFO);
/*
* Check that we are not configuring routing matrix for mixing.
*
@ -62,7 +42,7 @@ DECLARE_TR_CTX(demux_tr, SOF_UUID(demux_uuid), LOG_LEVEL_INFO);
* have 1's in corresponding matrix indices. Also single stream matrix can't
* have 1's in same column as that corresponds to mixing also.
*/
static bool mux_mix_check(struct sof_mux_config *cfg)
bool mux_mix_check(struct sof_mux_config *cfg)
{
bool channel_set;
int i;
@ -102,109 +82,6 @@ static bool mux_mix_check(struct sof_mux_config *cfg)
return false;
}
#if CONFIG_IPC_MAJOR_3
static int mux_set_values(struct processing_module *mod)
{
struct comp_data *cd = module_get_private_data(mod);
struct comp_dev *dev = mod->dev;
struct sof_mux_config *cfg = &cd->config;
unsigned int i;
unsigned int j;
comp_dbg(dev, "mux_set_values()");
/* check if number of streams configured doesn't exceed maximum */
if (cfg->num_streams > MUX_MAX_STREAMS) {
comp_err(dev, "mux_set_values(): configured number of streams (%u) exceeds maximum = "
META_QUOTE(MUX_MAX_STREAMS), cfg->num_streams);
return -EINVAL;
}
/* check if all streams configured have distinct IDs */
for (i = 0; i < cfg->num_streams; i++) {
for (j = i + 1; j < cfg->num_streams; j++) {
if (cfg->streams[i].pipeline_id ==
cfg->streams[j].pipeline_id) {
comp_err(dev, "mux_set_values(): multiple configured streams have same pipeline ID = %u",
cfg->streams[i].pipeline_id);
return -EINVAL;
}
}
}
for (i = 0; i < cfg->num_streams; i++) {
for (j = 0 ; j < PLATFORM_MAX_CHANNELS; j++) {
if (popcount(cfg->streams[i].mask[j]) > 1) {
comp_err(dev, "mux_set_values(): mux component is not able to mix channels");
return -EINVAL;
}
}
}
if (dev->ipc_config.type == SOF_COMP_MUX) {
if (mux_mix_check(cfg))
comp_err(dev, "mux_set_values(): mux component is not able to mix channels");
}
for (i = 0; i < cfg->num_streams; i++) {
cd->config.streams[i].pipeline_id = cfg->streams[i].pipeline_id;
for (j = 0; j < PLATFORM_MAX_CHANNELS; j++)
cd->config.streams[i].mask[j] = cfg->streams[i].mask[j];
}
cd->config.num_streams = cfg->num_streams;
if (dev->ipc_config.type == SOF_COMP_MUX)
mux_prepare_look_up_table(mod);
else
demux_prepare_look_up_table(mod);
if (dev->state > COMP_STATE_INIT) {
if (dev->ipc_config.type == SOF_COMP_MUX)
cd->mux = mux_get_processing_function(mod);
else
cd->demux = demux_get_processing_function(mod);
}
return 0;
}
#endif /* CONFIG_IPC_MAJOR_3 */
#if CONFIG_IPC_MAJOR_4
static int build_config(struct processing_module *mod)
{
struct comp_dev *dev = mod->dev;
struct comp_data *cd = module_get_private_data(mod);
int mask = 1;
int i;
dev->ipc_config.type = SOF_COMP_MUX;
cd->config.num_streams = MUX_MAX_STREAMS;
/* clear masks */
for (i = 0; i < cd->config.num_streams; i++)
memset(cd->config.streams[i].mask, 0, sizeof(cd->config.streams[i].mask));
/* Setting masks for streams */
for (i = 0; i < cd->md.base_cfg.audio_fmt.channels_count; i++) {
cd->config.streams[0].mask[i] = mask;
mask <<= 1;
}
for (i = 0; i < cd->md.reference_format.channels_count; i++) {
cd->config.streams[1].mask[i] = mask;
mask <<= 1;
}
/* validation of matrix mixing */
if (mux_mix_check(&cd->config)) {
comp_err(dev, "build_config(): mux component is not able to mix channels");
return -EINVAL;
}
return 0;
}
#endif
static int mux_demux_common_init(struct processing_module *mod)
{
struct module_data *module_data = &mod->priv;
@ -265,73 +142,6 @@ static int demux_init(struct processing_module *mod)
return mux_demux_common_init(mod);
}
#if CONFIG_IPC_MAJOR_4
/* In ipc4 case param is figured out by module config so we need to first
* set up param then verify param. BTW for IPC3 path, the param is sent by
* host driver.
*/
static void set_mux_params(struct processing_module *mod)
{
struct sof_ipc_stream_params *params = mod->stream_params;
struct comp_data *cd = module_get_private_data(mod);
struct comp_dev *dev = mod->dev;
struct comp_buffer *sink, *source;
struct list_item *source_list;
int j;
const uint32_t byte_align = 1;
const uint32_t frame_align_req = 1;
params->direction = dev->direction;
params->channels = cd->md.base_cfg.audio_fmt.channels_count;
params->rate = cd->md.base_cfg.audio_fmt.sampling_frequency;
params->sample_container_bytes = cd->md.base_cfg.audio_fmt.depth / 8;
params->sample_valid_bytes = cd->md.base_cfg.audio_fmt.valid_bit_depth / 8;
params->buffer_fmt = cd->md.base_cfg.audio_fmt.interleaving_style;
params->buffer.size = cd->md.base_cfg.ibs;
params->no_stream_position = 1;
/* There are two input pins and one output pin in the mux.
* For the first input we assign parameters from base_cfg,
* for the second from reference_format
* and for sink output_format.
*/
/* update sink format */
if (!list_is_empty(&dev->bsink_list)) {
sink = list_first_item(&dev->bsink_list, struct comp_buffer, source_list);
audio_stream_init_alignment_constants(byte_align, frame_align_req,
&sink->stream);
if (!sink->hw_params_configured) {
ipc4_update_buffer_format(sink, &cd->md.output_format);
params->frame_fmt = audio_stream_get_frm_fmt(&sink->stream);
}
}
/* update each source format */
if (!list_is_empty(&dev->bsource_list)) {
struct ipc4_audio_format *audio_fmt;
list_for_item(source_list, &dev->bsource_list)
{
source = container_of(source_list, struct comp_buffer, sink_list);
audio_stream_init_alignment_constants(byte_align, frame_align_req,
&source->stream);
j = buf_get_id(source);
cd->config.streams[j].pipeline_id = source->pipeline_id;
if (j == BASE_CFG_QUEUED_ID)
audio_fmt = &cd->md.base_cfg.audio_fmt;
else
audio_fmt = &cd->md.reference_format;
ipc4_update_buffer_format(source, audio_fmt);
}
}
mux_prepare_look_up_table(mod);
}
#endif /* CONFIG_IPC_MAJOR_4 */
static int mux_free(struct processing_module *mod)
{
@ -583,18 +393,10 @@ static int mux_prepare(struct processing_module *mod,
memcpy_s(&cd->config, MUX_BLOB_MAX_SIZE, config, blob_size);
#if CONFIG_IPC_MAJOR_4
ret = build_config(mod);
#else
ret = mux_set_values(mod);
#endif
ret = mux_params(mod);
if (ret < 0)
return ret;
#if CONFIG_IPC_MAJOR_4
set_mux_params(mod);
#endif
if (dev->ipc_config.type == SOF_COMP_MUX)
cd->mux = mux_get_processing_function(mod);
else

View File

@ -16,11 +16,14 @@
#if CONFIG_COMP_MUX
#include <sof/audio/module_adapter/module/generic.h>
#include <sof/common.h>
#include <sof/platform.h>
#include <sof/trace/trace.h>
#include <sof/ut.h>
#include <sof/lib/uuid.h>
#include <user/trace.h>
#include <module/module/base.h>
#include <stdint.h>
#if CONFIG_IPC_MAJOR_4
#include <ipc4/base-config.h>
@ -210,6 +213,17 @@ void sys_comp_module_demux_interface_init(void);
#endif /* UNIT_TEST */
#define MUX_BLOB_STREAMS_SIZE (MUX_MAX_STREAMS * sizeof(struct mux_stream_data))
#define MUX_BLOB_MAX_SIZE (sizeof(struct sof_mux_config) + MUX_BLOB_STREAMS_SIZE)
extern const struct sof_uuid mux_uuid;
extern const struct sof_uuid demux_uuid;
extern struct tr_ctx mux_tr;
extern struct tr_ctx demux_tr;
bool mux_mix_check(struct sof_mux_config *cfg);
int mux_params(struct processing_module *mod);
#endif /* CONFIG_COMP_MUX */
#endif /* __SOF_AUDIO_MUX_H__ */

107
src/audio/mux/mux_ipc3.c Normal file
View File

@ -0,0 +1,107 @@
// SPDX-License-Identifier: BSD-3-Clause
//
// Copyright(c) 2016 Intel Corporation. All rights reserved.
//
// Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
// Artur Kloniecki <arturx.kloniecki@linux.intel.com>
#if CONFIG_COMP_MUX
#include <sof/audio/module_adapter/module/generic.h>
#include <sof/audio/component.h>
#include <module/module/base.h>
#include <sof/trace/trace.h>
#include <sof/trace/preproc.h>
#include <sof/lib/uuid.h>
#include <sof/common.h>
#include <sof/platform.h>
#include <ipc/topology.h>
#include <errno.h>
#include "mux.h"
LOG_MODULE_DECLARE(muxdemux, CONFIG_SOF_LOG_LEVEL);
/* c607ff4d-9cb6-49dc-b678-7da3c63ea557 */
DECLARE_SOF_RT_UUID("mux", mux_uuid, 0xc607ff4d, 0x9cb6, 0x49dc,
0xb6, 0x78, 0x7d, 0xa3, 0xc6, 0x3e, 0xa5, 0x57);
DECLARE_TR_CTX(mux_tr, SOF_UUID(mux_uuid), LOG_LEVEL_INFO);
/* c4b26868-1430-470e-a089-15d1c77f851a */
DECLARE_SOF_RT_UUID("demux", demux_uuid, 0xc4b26868, 0x1430, 0x470e,
0xa0, 0x89, 0x15, 0xd1, 0xc7, 0x7f, 0x85, 0x1a);
DECLARE_TR_CTX(demux_tr, SOF_UUID(demux_uuid), LOG_LEVEL_INFO);
static int mux_set_values(struct processing_module *mod)
{
struct comp_data *cd = module_get_private_data(mod);
struct comp_dev *dev = mod->dev;
struct sof_mux_config *cfg = &cd->config;
unsigned int i;
unsigned int j;
comp_dbg(dev, "mux_set_values()");
/* check if number of streams configured doesn't exceed maximum */
if (cfg->num_streams > MUX_MAX_STREAMS) {
comp_err(dev, "mux_set_values(): configured number of streams (%u) exceeds maximum = "
META_QUOTE(MUX_MAX_STREAMS), cfg->num_streams);
return -EINVAL;
}
/* check if all streams configured have distinct IDs */
for (i = 0; i < cfg->num_streams; i++) {
for (j = i + 1; j < cfg->num_streams; j++) {
if (cfg->streams[i].pipeline_id ==
cfg->streams[j].pipeline_id) {
comp_err(dev, "mux_set_values(): multiple configured streams have same pipeline ID = %u",
cfg->streams[i].pipeline_id);
return -EINVAL;
}
}
}
for (i = 0; i < cfg->num_streams; i++) {
for (j = 0 ; j < PLATFORM_MAX_CHANNELS; j++) {
if (popcount(cfg->streams[i].mask[j]) > 1) {
comp_err(dev, "mux_set_values(): mux component is not able to mix channels");
return -EINVAL;
}
}
}
if (dev->ipc_config.type == SOF_COMP_MUX) {
if (mux_mix_check(cfg))
comp_err(dev, "mux_set_values(): mux component is not able to mix channels");
}
for (i = 0; i < cfg->num_streams; i++) {
cd->config.streams[i].pipeline_id = cfg->streams[i].pipeline_id;
for (j = 0; j < PLATFORM_MAX_CHANNELS; j++)
cd->config.streams[i].mask[j] = cfg->streams[i].mask[j];
}
cd->config.num_streams = cfg->num_streams;
if (dev->ipc_config.type == SOF_COMP_MUX)
mux_prepare_look_up_table(mod);
else
demux_prepare_look_up_table(mod);
if (dev->state > COMP_STATE_INIT) {
if (dev->ipc_config.type == SOF_COMP_MUX)
cd->mux = mux_get_processing_function(mod);
else
cd->demux = demux_get_processing_function(mod);
}
return 0;
}
int mux_params(struct processing_module *mod)
{
return mux_set_values(mod);
}
#endif /* CONFIG_COMP_MUX */

148
src/audio/mux/mux_ipc4.c Normal file
View File

@ -0,0 +1,148 @@
// SPDX-License-Identifier: BSD-3-Clause
//
// Copyright(c) 2016 Intel Corporation. All rights reserved.
//
// Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
// Artur Kloniecki <arturx.kloniecki@linux.intel.com>
#if CONFIG_COMP_MUX
#include <sof/audio/module_adapter/module/generic.h>
#include <sof/audio/audio_stream.h>
#include <sof/audio/component.h>
#include <sof/audio/buffer.h>
#include <sof/trace/trace.h>
#include <sof/lib/uuid.h>
#include <sof/list.h>
#include <ipc/stream.h>
#include <module/module/base.h>
#include <module/ipc4/base-config.h>
#include <errno.h>
#include "mux.h"
LOG_MODULE_DECLARE(muxdemux, CONFIG_SOF_LOG_LEVEL);
/* 64ce6e35-857a-4878-ace8-e2a2f42e3069 */
DECLARE_SOF_RT_UUID("mux", mux_uuid, 0x64ce6e35, 0x857a, 0x4878,
0xac, 0xe8, 0xe2, 0xa2, 0xf4, 0x2e, 0x30, 0x69);
DECLARE_TR_CTX(mux_tr, SOF_UUID(mux_uuid), LOG_LEVEL_INFO);
/* c4b26868-1430-470e-a089-15d1c77f851a */
DECLARE_SOF_RT_UUID("demux", demux_uuid, 0xc4b26868, 0x1430, 0x470e,
0xa0, 0x89, 0x15, 0xd1, 0xc7, 0x7f, 0x85, 0x1a);
DECLARE_TR_CTX(demux_tr, SOF_UUID(demux_uuid), LOG_LEVEL_INFO);
static int build_config(struct processing_module *mod)
{
struct comp_dev *dev = mod->dev;
struct comp_data *cd = module_get_private_data(mod);
int mask = 1;
int i;
dev->ipc_config.type = SOF_COMP_MUX;
cd->config.num_streams = MUX_MAX_STREAMS;
/* clear masks */
for (i = 0; i < cd->config.num_streams; i++)
memset(cd->config.streams[i].mask, 0, sizeof(cd->config.streams[i].mask));
/* Setting masks for streams */
for (i = 0; i < cd->md.base_cfg.audio_fmt.channels_count; i++) {
cd->config.streams[0].mask[i] = mask;
mask <<= 1;
}
for (i = 0; i < cd->md.reference_format.channels_count; i++) {
cd->config.streams[1].mask[i] = mask;
mask <<= 1;
}
/* validation of matrix mixing */
if (mux_mix_check(&cd->config)) {
comp_err(dev, "build_config(): mux component is not able to mix channels");
return -EINVAL;
}
return 0;
}
/* In ipc4 case param is figured out by module config so we need to first
* set up param then verify param. BTW for IPC3 path, the param is sent by
* host driver.
*/
static void set_mux_params(struct processing_module *mod)
{
struct sof_ipc_stream_params *params = mod->stream_params;
struct comp_data *cd = module_get_private_data(mod);
struct comp_dev *dev = mod->dev;
struct comp_buffer *sink, *source;
struct list_item *source_list;
int j;
const uint32_t byte_align = 1;
const uint32_t frame_align_req = 1;
params->direction = dev->direction;
params->channels = cd->md.base_cfg.audio_fmt.channels_count;
params->rate = cd->md.base_cfg.audio_fmt.sampling_frequency;
params->sample_container_bytes = cd->md.base_cfg.audio_fmt.depth / 8;
params->sample_valid_bytes = cd->md.base_cfg.audio_fmt.valid_bit_depth / 8;
params->buffer_fmt = cd->md.base_cfg.audio_fmt.interleaving_style;
params->buffer.size = cd->md.base_cfg.ibs;
params->no_stream_position = 1;
/* There are two input pins and one output pin in the mux.
* For the first input we assign parameters from base_cfg,
* for the second from reference_format
* and for sink output_format.
*/
/* update sink format */
if (!list_is_empty(&dev->bsink_list)) {
sink = list_first_item(&dev->bsink_list, struct comp_buffer, source_list);
audio_stream_init_alignment_constants(byte_align, frame_align_req,
&sink->stream);
if (!sink->hw_params_configured) {
ipc4_update_buffer_format(sink, &cd->md.output_format);
params->frame_fmt = audio_stream_get_frm_fmt(&sink->stream);
}
}
/* update each source format */
if (!list_is_empty(&dev->bsource_list)) {
struct ipc4_audio_format *audio_fmt;
list_for_item(source_list, &dev->bsource_list)
{
source = container_of(source_list, struct comp_buffer, sink_list);
audio_stream_init_alignment_constants(byte_align, frame_align_req,
&source->stream);
j = buf_get_id(source);
cd->config.streams[j].pipeline_id = source->pipeline_id;
if (j == BASE_CFG_QUEUED_ID)
audio_fmt = &cd->md.base_cfg.audio_fmt;
else
audio_fmt = &cd->md.reference_format;
ipc4_update_buffer_format(source, audio_fmt);
}
}
mux_prepare_look_up_table(mod);
}
int mux_params(struct processing_module *mod)
{
int ret;
ret = build_config(mod);
if (ret < 0)
return ret;
set_mux_params(mod);
return ret;
}
#endif /* CONFIG_COMP_MUX */

View File

@ -10,6 +10,7 @@ add_library(
audio_mux
STATIC
${PROJECT_SOURCE_DIR}/src/audio/mux/mux.c
${PROJECT_SOURCE_DIR}/src/audio/mux/mux_ipc3.c
${PROJECT_SOURCE_DIR}/src/audio/mux/mux_generic.c
${PROJECT_SOURCE_DIR}/src/audio/component.c
${PROJECT_SOURCE_DIR}/src/audio/data_blob.c
@ -48,3 +49,8 @@ cmocka_test(
demux_copy
demux_copy.c
)
target_include_directories(audio_mux PRIVATE ${PROJECT_SOURCE_DIR}/src/audio)
target_include_directories(mux_get_processing_function PRIVATE ${PROJECT_SOURCE_DIR}/src/audio)
target_include_directories(mux_copy PRIVATE ${PROJECT_SOURCE_DIR}/src/audio)
target_include_directories(demux_copy PRIVATE ${PROJECT_SOURCE_DIR}/src/audio)

View File

@ -10,7 +10,7 @@
#include <sof/audio/module_adapter/module/generic.h>
#include <sof/audio/component_ext.h>
#include <sof/audio/format.h>
#include <sof/audio/mux.h>
#include <mux/mux.h>
#include <stdarg.h>
#include <stddef.h>

View File

@ -10,7 +10,7 @@
#include <sof/audio/module_adapter/module/generic.h>
#include <sof/audio/component_ext.h>
#include <sof/audio/format.h>
#include <sof/audio/mux.h>
#include <mux/mux.h>
#include <stdarg.h>
#include <stddef.h>

View File

@ -9,7 +9,7 @@
#include <sof/audio/module_adapter/module/generic.h>
#include <sof/audio/component_ext.h>
#include <sof/audio/mux.h>
#include <mux/mux.h>
#include <stdarg.h>
#include <stddef.h>

View File

@ -812,6 +812,16 @@ zephyr_library_sources_ifdef(CONFIG_COMP_MUX
${SOF_AUDIO_PATH}/mux/mux_generic.c
)
if(CONFIG_IPC_MAJOR_3)
zephyr_library_sources_ifdef(CONFIG_COMP_MUX
${SOF_AUDIO_PATH}/mux/mux_ipc3.c
)
elseif(CONFIG_IPC_MAJOR_4)
zephyr_library_sources_ifdef(CONFIG_COMP_MUX
${SOF_AUDIO_PATH}/mux/mux_ipc4.c
)
endif()
zephyr_library_sources_ifdef(CONFIG_COMP_GOOGLE_HOTWORD_DETECT
${SOF_AUDIO_PATH}/google/google_hotword_detect.c
)