Skip to content

WIP: audio/topology: add multi-KPB WOV arbiter for 3-keyword DMIC capture#11022

Draft
lgirdwood wants to merge 3 commits into
thesofproject:mainfrom
lgirdwood:feature/wov-multi-kpb
Draft

WIP: audio/topology: add multi-KPB WOV arbiter for 3-keyword DMIC capture#11022
lgirdwood wants to merge 3 commits into
thesofproject:mainfrom
lgirdwood:feature/wov-multi-kpb

Conversation

@lgirdwood

Copy link
Copy Markdown
Member

Adds a new WOV arbiter component and multi-KPB topology to support three simultaneous wake-word detectors sharing a single DMIC, with exclusive host PCM drain arbitration when any keyword fires.

New component: src/audio/wov_arbiter/

  • 3 input pins (one per KPB host-sink), 1 output pin (to host copier)
  • AMS subscriber for AMS_WOV_DETECT_MSG_UUID: activates the triggering slot and broadcasts WOV_CTRL PAUSE to sibling detectors
  • On trigger(STOP): deactivates and broadcasts WOV_CTRL RESUME so all detectors return to listening
  • Idle inputs are silently drained to prevent buffer stalls
  • UUID 4a5b6c7d-8e9f-4a1b-2c3d-4e5f60718293 registered in uuid-registry

AMS additions (ams_msg.h):

  • AMS_WOV_DETECT_MSG_UUID: detector -> arbiter on keyword detect
  • AMS_WOV_CTRL_MSG_UUID: arbiter -> detectors for pause/resume control

detect_test extensions:

  • IPC4_DETECT_TEST_SET_WOV_SLOT large-config param assigns a slot id (0-2)
  • On detection: also sends AMS_WOV_DETECT_MSG_UUID with slot_id to arbiter
  • AMS consumer for WOV_CTRL: sets paused flag; copy() drains buffer without running the detector when paused
  • The existing energy-threshold detector fires on a hand clap, making detect_test a ready-to-use lab test stub for this topology

Topology: tools/topology/topology2/platform/intel/dmic-wov-multi.conf

  • Pipeline 100 (Core 0): DMIC Copier -> Mixin (fan-out to 3 Mixouts)
  • Pipelines 101-102 (Core 0): Mixout -> KPB -> detect_test (slots 0-1)
  • Pipeline 103 (Core 1): Mixout -> KPB -> detect_test (slot 2)
  • Pipeline 104 (Core 0): WOV Arbiter -> Host Copier (single PCM stream)
  • KPB output_pin_binding: pin 0 -> detector (sel_sink), pin 1 -> arbiter (host_sink)

Requires: CONFIG_COMP_WOV_ARBITER, CONFIG_COMP_KPB, CONFIG_COMP_MIXIN_MIXOUT,
CONFIG_AMS, CONFIG_COMP_KWD_DETECT

@lgirdwood lgirdwood left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some opens.

Comment thread src/audio/wov_arbiter/wov_arbiter.c
Comment thread src/audio/wov_arbiter/wov_arbiter.c
Comment thread src/audio/CMakeLists.txt Outdated
Comment thread src/audio/Kconfig Outdated
Comment thread src/include/sof/audio/wov_arbiter.h Outdated
Comment thread uuid-registry.txt Outdated
Adds a new WOV arbiter component and multi-KPB topology to support three
simultaneous wake-word detectors sharing a single DMIC, with exclusive
host PCM drain arbitration when any keyword fires.

New component: src/audio/wov_arbiter/
- 3 input pins (one per KPB host-sink), 1 output pin (to host copier)
- AMS subscriber for AMS_WOV_DETECT_MSG_UUID: activates the triggering
  slot and broadcasts WOV_CTRL PAUSE to sibling detectors
- On trigger(STOP): deactivates and broadcasts WOV_CTRL RESUME so all
  detectors return to listening
- Idle inputs are silently drained to prevent buffer stalls
- UUID 4a5b6c7d-8e9f-4a1b-2c3d-4e5f60718293 registered in uuid-registry

AMS additions (ams_msg.h):
- AMS_WOV_DETECT_MSG_UUID: detector -> arbiter on keyword detect
- AMS_WOV_CTRL_MSG_UUID:   arbiter -> detectors for pause/resume control

detect_test extensions:
- IPC4_DETECT_TEST_SET_WOV_SLOT large-config param assigns a slot id (0-2)
- On detection: also sends AMS_WOV_DETECT_MSG_UUID with slot_id to arbiter
- AMS consumer for WOV_CTRL: sets paused flag; copy() drains buffer
  without running the detector when paused
- The existing energy-threshold detector fires on a hand clap, making
  detect_test a ready-to-use lab test stub for this topology

Topology: tools/topology/topology2/platform/intel/dmic-wov-multi.conf
- Pipeline 100 (Core 0): DMIC Copier -> Mixin (fan-out to 3 Mixouts)
- Pipelines 101-102 (Core 0): Mixout -> KPB -> detect_test (slots 0-1)
- Pipeline 103 (Core 1): Mixout -> KPB -> detect_test (slot 2)
- Pipeline 104 (Core 0): WOV Arbiter -> Host Copier (single PCM stream)
- KPB output_pin_binding: pin 0 -> detector (sel_sink),
                          pin 1 -> arbiter (host_sink)

Requires: CONFIG_COMP_WOV_ARBITER, CONFIG_COMP_KPB, CONFIG_COMP_MIXIN_MIXOUT,
          CONFIG_AMS, CONFIG_COMP_KWD_DETECT

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@lgirdwood
lgirdwood force-pushed the feature/wov-multi-kpb branch from 49f3dc6 to c3c7161 Compare July 22, 2026 13:13
lrgirdwo and others added 2 commits July 22, 2026 15:26
Adds a new lightweight vad_gate module that inserts between the DMIC
copier and the Mixin fan-out in the multi-WOV capture pipeline.

The gate runs a first-order IIR energy estimator on each audio frame
(same pattern as detect_test.c's activation tracker) and manages two
states:

  SPEECH  — voice onset detected (onset_frames consecutive frames above
             threshold); audio is passed through to the Mixin → KPB →
             WOV chain which begins buffering.

  SILENCE — energy drops for hangover_frames consecutive frames; the
             gate drains its DMIC input to prevent DAI DMA stall but
             returns PPL_STATUS_PATH_STOP so the downstream Mixin and
             all three KPB/WOV pipelines idle without consuming CPU.

Tunable at runtime via IPC4 SET_LARGE_CONFIG (threshold, onset_frames,
hangover_frames, energy_shift).

Changes:
  - src/audio/vad_gate/vad_gate.c        — new component
  - src/audio/vad_gate/CMakeLists.txt
  - src/audio/vad_gate/Kconfig
  - src/include/sof/audio/vad_gate.h     — config struct + defaults
  - src/audio/Kconfig                    — CONFIG_COMP_VAD_GATE rsource
  - src/audio/CMakeLists.txt             — conditional subdirectory
  - uuid-registry.txt                    — vad_gate UUID
  - include/components/vad-gate.conf     — topology2 widget class
  - dmic-wov-multi.conf                  — pipeline 100: copier → vad-gate → mixin

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The ams_msg_callback_fn type is:
  void (*)(const struct ams_message_payload *const, void *)

The on_wov_ctrl() and arb_on_detect() callbacks were written with the
old four-argument form (msg_type_id, message, message_size, ctx) which
no longer matches the typedef, causing build failures on mtl/tgl/lnl.

Also fix the payload field access inside those callbacks:
  p->payload_size → p->message_length
  p->payload      → p->message

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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