Skip to content
Draft
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
10 changes: 10 additions & 0 deletions src/audio/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,16 @@ 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"
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 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
26 changes: 26 additions & 0 deletions src/audio/drc/drc.c
Original file line number Diff line number Diff line change
Expand Up @@ -481,4 +481,30 @@ 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)
return -EINVAL;

struct drc_comp_data *cd = module_get_private_data(mod);

if (cd)
cd->enable_switch = (val != 0);

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
39 changes: 39 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,43 @@ 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)
return -EINVAL;

struct comp_data *cd = module_get_private_data(mod);

if (cd) {
if (val == 0) {
cd->eq_iir_func = eq_iir_pass;
} else if (cd->iir_delay_size) {
#if CONFIG_FORMAT_FLOAT
struct comp_buffer *sourceb = comp_dev_get_first_data_producer(dev);

if (sourceb && audio_stream_get_frm_fmt(&sourceb->stream) == SOF_IPC_FRAME_FLOAT)
cd->eq_iir_func = eq_iir_float_default;
else
cd->eq_iir_func = eq_iir_s16_default;
#else
cd->eq_iir_func = eq_iir_s16_default;
#endif
}
}
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
42 changes: 42 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,46 @@ 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)
return -EINVAL;

struct level_multiplier_comp_data *cd = module_get_private_data(mod);

if (cd)
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)
return -EINVAL;

struct level_multiplier_comp_data *cd = module_get_private_data(mod);

if (cd)
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