Skip to content

pipeline: introduce declarative static topology definition and loader - #11266

Draft
lgirdwood wants to merge 1 commit into
thesofproject:mainfrom
lgirdwood:topic/static-pipeline-api
Draft

lgirdwood wants to merge 1 commit into
thesofproject:mainfrom
lgirdwood:topic/static-pipeline-api

Conversation

@lgirdwood

Copy link
Copy Markdown
Member

Summary

Add support for declarative static audio pipelines in Sound Open Firmware.
In microcontroller, hostless, and standalone embedded environments (such as ESP32-P4/S3/C6, PJRC Teensy 4.1, Nordic nRF54, RP2350, smart speakers, and audio bridges), there is no dynamic IPC host driver (Linux ALSA/SoundWire or Windows) to construct topologies at runtime.

Key Additions & Features

  1. Declarative Topology Structures & Macros (<sof/audio/pipeline/static_pipeline.h>):

    • Full Doxygen API docblocks covering all structures, fields, enums, macros, and public APIs.
    • Comprehensive sample rate bitmasks (SOF_STATIC_RATE_*) aligned with SOF_RATE_* and format bitmasks (SOF_STATIC_FMT_*) aligned with enum sof_ipc_frame.
    • Concise constructor macros (SOF_STATIC_MODULE, SOF_STATIC_MODULE_RATE_CONV, SOF_STATIC_ENDPOINT_DAI, SOF_STATIC_ENDPOINT_USB) for clean declarative pipeline definition.
  2. Ops-Driven Decoupled Architecture:

    • Generic headers and loader engine have zero per-module logic or dependencies.
    • Audio processing modules define and self-register their static operations (struct sof_static_module_ops) providing .create, .apply_volume, .apply_switch, and .apply_enum callbacks directly in their own source files (SRC, ASRC, Volume/Gain, Level Multiplier, Selector, EQ IIR, DRC, and TDFB) using DECLARE_STATIC_MODULE_OPS().
  3. Generic Module Registry & Base IPC4 Config Synthesizer (static_pipeline_modules.c):

    • Generic ops registry with structured error logging on lookup failures.
    • Base IPC4 config synthesizer (sof_static_init_base_cfg) generating standard IPC4 base module configurations (struct ipc4_base_module_cfg) on behalf of the absent host, calculating IBS/OBS and channel mapping from declarative capabilities and periods.
  4. Dynamic Format & Rate Negotiation:

    • Dynamically resolves primary stream sample rates from topology descriptors, removing hardcoded defaults.
    • Supports sample rate converters (SRC/ASRC), up/down mixers, and format conversions with per-buffer rate/channel inheritance.
  5. Static Topology Loader Engine (static_pipeline_loader.c):

    • Instantiates native SOF pipelines, components, intermediate buffers, routes, and kcontrols directly at boot.
    • Component preparation and parameter negotiation to ensure all processing modules reach ready state prior to streaming.
    • Comprehensive inline comments on every code block explaining the action and rationale.
  6. Dedicated Pipeline Control & Trigger Safety:

    • Separate start/stop routines (sof_static_pipeline_start, sof_static_pipeline_stop).
    • Strict abort on pipeline_prepare() failure preventing triggers on uninitialized circular buffers.
    • UAC2 terminal dispatch routing directly to modular start/stop helpers.
    • Decoupled custom kcontrol callback handler for board- and platform-specific controls.
  7. Kconfig & Build Integration:

    • CONFIG_STATIC_PIPELINE Kconfig option and CMakeLists integration.
  8. Developer Documentation:

    • Comprehensive architectural guide, API references, and step-by-step tutorial with multi-rate SRC examples in src/audio/pipeline/README.md.

Add support for declarative static audio pipelines in Sound Open Firmware.
In microcontroller, hostless, and standalone embedded environments (such
as ESP32-P4/S3/C6, PJRC Teensy 4.1, Nordic nRF54, RP2350, smart speakers,
and audio bridges), there is no dynamic IPC host driver (Linux ALSA/SoundWire
or Windows) to build topologies at runtime.

This introduces:
1. Declarative topology structures, capability flags, and constructor
   macros in <sof/audio/pipeline/static_pipeline.h> with full Doxygen
   docblocks covering all structures, fields, enums, macros, and public
   APIs. Complete sample rate masks (8k through 384k) aligned with
   SOF_RATE_* and frame format masks aligned with enum sof_ipc_frame.
2. Ops-driven static module architecture: generic headers and loader
   engine are 100% decoupled from individual audio processing components.
   Audio processing modules define and register their own operations
   (struct sof_static_module_ops) providing .create, .apply_volume,
   .apply_switch, and .apply_enum callbacks directly in their own source
   files (SRC, ASRC, Volume/Gain, Level Multiplier, Selector, EQ IIR,
   DRC, and TDFB) using DECLARE_STATIC_MODULE_OPS().
3. Generic module operations registry and base IPC4 config synthesizer
   in static_pipeline_modules.c: completely generic infrastructure for
   ops registration, lookup with error logging, base configuration
   synthesis with macros for IPC4 channel maps, and default fallback
   component instantiation.
4. Concise, generic constructor macros (SOF_STATIC_MODULE,
   SOF_STATIC_MODULE_RATE_CONV, SOF_STATIC_ENDPOINT_DAI, and
   SOF_STATIC_ENDPOINT_USB) allowing clean, compact topology definitions
   for any audio processing module and DAI endpoint.
5. Modular IPC configuration and base config synthesizer: synthesizes
   standard IPC4 base module configurations (struct ipc4_base_module_cfg)
   on behalf of the absent host, calculating input and output buffer sizes
   (IBS/OBS) dynamically from component capabilities and pipeline periods.
6. Dynamic multi-rate, multi-channel, and format negotiation: eliminates
   hardcoded sample rates and channel counts in buffer initialization and
   pipeline/component prepare, supporting sample rate converters (SRC/ASRC),
   up/down mixers, and format conversions with per-buffer rate/channel inheritance.
7. Generic static topology loader engine in static_pipeline_loader.c
   to parse and instantiate native SOF components, buffers, routes,
   and kcontrols directly at boot.
8. Component preparation and parameter negotiation to ensure all
   processing modules reach ready state prior to streaming.
9. Direct pipeline start, stop, and trigger control with separate
   start/stop execution paths (sof_static_pipeline_start,
   sof_static_pipeline_stop), strict error checking preventing triggers
   on prepare failures, state validation, and copy task management.
10. Decoupled custom kcontrol callback handler to support platform-
    and board-specific controls without polluting core audio modules.
11. CONFIG_STATIC_PIPELINE Kconfig option and CMakeLists.txt integration.
12. Comprehensive developer documentation, architecture overview, and
    step-by-step tutorial with multi-rate SRC examples in
    src/audio/pipeline/README.md.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
@lgirdwood
lgirdwood force-pushed the topic/static-pipeline-api branch from 2fc03a7 to 5c11182 Compare October 5, 2026 21:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants