Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions src/audio/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,49 @@ config HOST_DMA_IPC_POSITION_UPDATES
by sending an IPC message whenever one period of audio is transferred.
Most platforms provide more efficient ways to query the DMA status.

config STATIC_PIPELINE
bool "Declarative Static Audio Pipeline Loader"
depends on IPC_MAJOR_4
default n
help
Enable support for declarative static audio pipelines in Sound
Open Firmware. This provides a compile-time and runtime loader
engine for hostless, microcontroller, and standalone embedded
targets that do not rely on dynamic IPC topology messages from
a host operating system.

config STATIC_PIPELINE_MAX_PIPELINES
int "Maximum static pipelines"
default 16
depends on STATIC_PIPELINE
help
Maximum number of static audio pipelines tracked by the static
pipeline loader. Memory-constrained embedded devices can lower this.

config STATIC_PIPELINE_MAX_COMPS
int "Maximum static components"
default 64
depends on STATIC_PIPELINE
help
Maximum number of static audio components tracked by the static
pipeline loader.

config STATIC_PIPELINE_MAX_BUFFERS
int "Maximum static audio buffers"
default 64
depends on STATIC_PIPELINE
help
Maximum number of static intermediate audio buffers tracked by
the static pipeline loader.

config STATIC_PIPELINE_MAX_CONTROLS
int "Maximum static controls"
default 64
depends on STATIC_PIPELINE
help
Maximum number of static kcontrols tracked by the static
pipeline loader.

config COMP_CHAIN_DMA
bool "Chain DMA component"
depends on IPC_MAJOR_4
Expand Down
35 changes: 35 additions & 0 deletions src/audio/asrc/asrc.c
Original file line number Diff line number Diff line change
Expand Up @@ -846,4 +846,39 @@ SOF_LLEXT_BUILDINFO;
DECLARE_MODULE_ADAPTER(asrc_interface, ASRC_UUID, asrc_tr);
SOF_MODULE_INIT(asrc, sys_comp_module_asrc_interface_init);

#if CONFIG_STATIC_PIPELINE
#include <sof/audio/pipeline/static_pipeline.h>

#if CONFIG_IPC_MAJOR_4
#include "asrc_ipc4.h"

static struct comp_dev *asrc_static_create(const struct comp_driver *drv,
struct comp_ipc_config *cfg,
const struct sof_static_comp *cdesc,
uint32_t period_us)
{
struct ipc4_asrc_module_cfg asrc_cfg;

memset(&asrc_cfg, 0, sizeof(asrc_cfg));
sof_static_init_base_cfg(&asrc_cfg.base, cdesc, period_us);
asrc_cfg.out_freq = (enum ipc4_sampling_frequency)(cdesc->caps.sink_rate ?
cdesc->caps.sink_rate :
cdesc->caps.default_rate);

struct ipc_config_process spec = {
.size = sizeof(asrc_cfg),
.data = (const uint8_t *)&asrc_cfg,
};
return drv->ops.create(drv, cfg, &spec);
}

static struct sof_static_module_ops asrc_static_ops = {
.uuid = &ASRC_UUID,
.create = asrc_static_create,
};

DECLARE_STATIC_MODULE_OPS(asrc, &asrc_static_ops);
#endif /* CONFIG_IPC_MAJOR_4 */
#endif /* CONFIG_STATIC_PIPELINE */

#endif
23 changes: 23 additions & 0 deletions src/audio/component.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,29 @@ int comp_set_adapter_ops(const struct comp_driver *drv, const struct module_inte
return -ENODEV;
}

const struct comp_driver *comp_driver_find(const struct sof_uuid *uuid, uint32_t type)
{
struct comp_driver_list *drivers = comp_drivers_get();
struct list_item *clist;

if (!drivers)
return NULL;

list_for_item(clist, &drivers->list) {
struct comp_driver_info *info = container_of(clist, struct comp_driver_info, list);

/* Match by UUID if provided (used for audio processing modules) */
if (uuid && info->drv->uid && !memcmp(info->drv->uid, uuid, UUID_SIZE))
return info->drv;

/* Match by driver type if no UUID is specified (used for Host and DAI endpoints) */
if (!uuid && info->drv->type == type)
return info->drv;
}

return NULL;
}

/* NOTE: Keep the component state diagram up to date:
* sof-docs/developer_guides/firmware/components/images/comp-dev-states.pu
*/
Expand Down
33 changes: 33 additions & 0 deletions src/audio/drc/drc.c
Original file line number Diff line number Diff line change
Expand Up @@ -481,4 +481,37 @@ SOF_LLEXT_BUILDINFO;
DECLARE_MODULE_ADAPTER(drc_interface, drc_uuid, drc_tr);
SOF_MODULE_INIT(drc, sys_comp_module_drc_interface_init);

#if CONFIG_STATIC_PIPELINE
#include <sof/audio/pipeline/static_pipeline.h>

static int drc_static_apply_switch(struct comp_dev *dev, uint32_t channels, int32_t val)
{
struct processing_module *mod = comp_mod(dev);

if (!mod) {
comp_err(dev, "drc_static_apply_switch: NULL processing module");
return -EINVAL;
}

struct drc_comp_data *cd = module_get_private_data(mod);

if (!cd) {
comp_err(dev, "drc_static_apply_switch: NULL private data");
return -EINVAL;
}

/* Update switch state and recompute active enabled state immediately */
cd->enable_switch = (val != 0);
cd->enabled = cd->config && cd->config->params.enabled && cd->enable_switch;
return 0;
}

static struct sof_static_module_ops drc_static_ops = {
.uuid = &drc_uuid,
.apply_switch = drc_static_apply_switch,
};

DECLARE_STATIC_MODULE_OPS(drc, &drc_static_ops);
#endif /* CONFIG_STATIC_PIPELINE */

#endif
87 changes: 87 additions & 0 deletions src/audio/eq_iir/eq_iir.c
Original file line number Diff line number Diff line change
Expand Up @@ -258,4 +258,91 @@ DECLARE_TR_CTX(eq_iir_tr, SOF_UUID(eq_iir_uuid), LOG_LEVEL_INFO);
DECLARE_MODULE_ADAPTER(eq_iir_interface, eq_iir_uuid, eq_iir_tr);
SOF_MODULE_INIT(eq_iir, sys_comp_module_eq_iir_interface_init);

#if CONFIG_STATIC_PIPELINE
#include <sof/audio/pipeline/static_pipeline.h>

static int eq_iir_static_apply_switch(struct comp_dev *dev, uint32_t channels, int32_t val)
{
struct processing_module *mod = comp_mod(dev);

if (!mod) {
comp_err(dev, "eq_iir_static_apply_switch: NULL processing module");
return -EINVAL;
}

struct comp_data *cd = module_get_private_data(mod);

if (!cd) {
comp_err(dev, "eq_iir_static_apply_switch: NULL private data");
return -EINVAL;
}

if (val == 0) {
/* Disable EQ by engaging pass-through routine */
cd->eq_iir_func = eq_iir_pass;
} else if (cd->iir_delay_size) {
/* Re-enable EQ processing matching configured valid bit depth */
unsigned int valid_bit_depth = mod->priv.cfg.base_cfg.audio_fmt.valid_bit_depth;

switch (valid_bit_depth) {
#if CONFIG_FORMAT_S16LE
case IPC4_DEPTH_16BIT:
cd->eq_iir_func = eq_iir_s16_default;
break;
#endif
#if CONFIG_FORMAT_S24LE
case IPC4_DEPTH_24BIT:
cd->eq_iir_func = eq_iir_s24_default;
break;
#endif
#if CONFIG_FORMAT_S32LE
case IPC4_DEPTH_32BIT:
cd->eq_iir_func = eq_iir_s32_default;
break;
#endif
default:
/* Fallback inspecting producer stream frame format */
{
struct comp_buffer *sourceb = comp_dev_get_first_data_producer(dev);
enum sof_ipc_frame fmt = sourceb ?
audio_stream_get_frm_fmt(&sourceb->stream) :
SOF_IPC_FRAME_S32_LE;

switch (fmt) {
#if CONFIG_FORMAT_S16LE
case SOF_IPC_FRAME_S16_LE:
cd->eq_iir_func = eq_iir_s16_default;
break;
#endif
#if CONFIG_FORMAT_S24LE
case SOF_IPC_FRAME_S24_4LE:
case SOF_IPC_FRAME_S24_3LE:
cd->eq_iir_func = eq_iir_s24_default;
break;
#endif
default:
#if CONFIG_FORMAT_S32LE
cd->eq_iir_func = eq_iir_s32_default;
#elif CONFIG_FORMAT_S16LE
cd->eq_iir_func = eq_iir_s16_default;
#else
cd->eq_iir_func = eq_iir_pass;
#endif
break;
}
}
break;
}
}
return 0;
}

static struct sof_static_module_ops eq_iir_static_ops = {
.uuid = &eq_iir_uuid,
.apply_switch = eq_iir_static_apply_switch,
};

DECLARE_STATIC_MODULE_OPS(eq_iir, &eq_iir_static_ops);
#endif /* CONFIG_STATIC_PIPELINE */

#endif
52 changes: 52 additions & 0 deletions src/audio/level_multiplier/level_multiplier.c
Original file line number Diff line number Diff line change
Expand Up @@ -204,4 +204,56 @@ DECLARE_TR_CTX(level_multiplier_tr, SOF_UUID(level_multiplier_uuid), LOG_LEVEL_I
DECLARE_MODULE_ADAPTER(level_multiplier_interface, level_multiplier_uuid, level_multiplier_tr);
SOF_MODULE_INIT(level_multiplier, sys_comp_module_level_multiplier_interface_init);

#if CONFIG_STATIC_PIPELINE
#include <sof/audio/pipeline/static_pipeline.h>

static int lm_static_apply_volume(struct comp_dev *dev, uint32_t channels, int32_t val)
{
struct processing_module *mod = comp_mod(dev);

if (!mod) {
comp_err(dev, "lm_static_apply_volume: NULL processing module");
return -EINVAL;
Comment thread
lgirdwood marked this conversation as resolved.
}

struct level_multiplier_comp_data *cd = module_get_private_data(mod);

if (!cd) {
comp_err(dev, "lm_static_apply_volume: NULL private data");
return -EINVAL;
}

cd->gain = val;
return 0;
}

static int lm_static_apply_switch(struct comp_dev *dev, uint32_t channels, int32_t val)
{
struct processing_module *mod = comp_mod(dev);

if (!mod) {
comp_err(dev, "lm_static_apply_switch: NULL processing module");
return -EINVAL;
}

struct level_multiplier_comp_data *cd = module_get_private_data(mod);

if (!cd) {
comp_err(dev, "lm_static_apply_switch: NULL private data");
return -EINVAL;
}

cd->gain = (val == 0) ? 0 : LEVEL_MULTIPLIER_GAIN_ONE;
return 0;
}

static struct sof_static_module_ops lm_static_ops = {
.uuid = &level_multiplier_uuid,
.apply_volume = lm_static_apply_volume,
.apply_switch = lm_static_apply_switch,
};

DECLARE_STATIC_MODULE_OPS(level_multiplier, &lm_static_ops);
#endif /* CONFIG_STATIC_PIPELINE */

#endif
6 changes: 6 additions & 0 deletions src/audio/pipeline/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,9 @@ add_local_sources(sof
pipeline-xrun.c
pipeline-schedule.c
)

add_local_sources_ifdef(CONFIG_STATIC_PIPELINE sof
static_pipeline_loader.c
static_pipeline_modules.c
static_pipeline_uac2.c
)
Loading
Loading