WIP: multi-slot WOV arbiter with VAD gate and D0I3/S0iX support - #11107
Draft
lgirdwood wants to merge 25 commits into
Draft
WIP: multi-slot WOV arbiter with VAD gate and D0I3/S0iX support#11107lgirdwood wants to merge 25 commits into
lgirdwood wants to merge 25 commits into
Conversation
lgirdwood
force-pushed
the
feature/wov-multi-kpb-v2
branch
4 times, most recently
from
August 26, 2026 14:54
653a1b9 to
b656712
Compare
Member
Author
lgirdwood
force-pushed
the
feature/wov-multi-kpb-v2
branch
from
September 3, 2026 20:18
2a1c8ea to
5017c6c
Compare
…ynamic sample rates - Add downstream WOV detector client notification and buffer drainage - Support configurable history buffer depth - Add dynamic sample rate calculations supporting both 16kHz and 48kHz Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
- Add multi-slot WOV arbiter component - Support mono-to-stereo channel expansion and sample width casting - Implement period-bounded zero-fill pacing during idle/startup - Add single-source default slot 0 routing Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
lgirdwood
force-pushed
the
feature/wov-multi-kpb-v2
branch
from
September 6, 2026 18:34
2a3cfc8 to
89bba02
Compare
- Add multi-slot WOV test framework with DP thread scheduling - Add per-slot wov_mute switch kcontrol - Update sink buffer pacing and threshold calculation for bench test Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
…anifests - Add dmic-wov-multi-manifest.conf: 48kHz 4ch DAI copier matching hardware NHLT with in-DSP SRC downsampler (48kHz -> 16kHz), 16kHz KPB, dual WOV detectors, and regular ALSA PCM capture via host-copier (hw:0,11) - Add multi-slot WOV manifests for HDA and SSP0/1/2 - Add regular stereo (dmic-regular-manifest.conf) and dual stereo (dmic-dual-regular-manifest.conf) 48kHz DMIC capture manifests - Add widget and pipeline definitions for KPB and WOV arbiter - Add capture_compatible_d0i3 support to host-copier Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
…suite wov_capture_app: self-contained zero-dependency C host application using direct Linux ALSA kernel UAPI ioctls (/dev/snd/pcmC%uD%uc). - Dynamic HW/SW parameter negotiation adapting to driver-selected periods - Signal metrics calculation (DC offset, AC RMS, Peak amplitude, Peak dBFS) - Valid RIFF WAV file generation with precise byte headers wov_daemon.py: Python multi-cycle test runner with DSP runtime PM D3 autosuspend / wake cycle verification. Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
lgirdwood
force-pushed
the
feature/wov-multi-kpb-v2
branch
from
September 6, 2026 18:58
89bba02 to
536d447
Compare
- Add dmic-wov-multi-ptl-manifest.conf and dmic-wov-multi-wcl-manifest.conf matching the TGL multi-slot WOV architecture (48kHz 4ch DAI copier, in-DSP SRC downsampler 48kHz -> 16kHz, 16kHz KPB, 3 WOV detector slots, and regular ALSA PCM capture via host-copier on hw:0,11). - Add platform/intel/wcl.conf for Wildcat Lake with DMIC_DRIVER_VERSION 5 and SSP_BLOB_VERSION 0x300. - Add sof-ptl-dmic-wov-multi and sof-wcl-dmic-wov-multi targets to production/tplg-targets-ace3.cmake. - Add wcl platform support to sof-hda-generic-wov-manifest.conf. Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
…for TGL, PTL, WCL - Add dmic-wov-multi-4ch-manifest.conf (TGL), dmic-wov-multi-ptl-4ch-manifest.conf (PTL), and dmic-wov-multi-wcl-4ch-manifest.conf (WCL) opening DMIC directly at 16kHz with 4 channels without SRC downsampler. - Add embedded 4-channel 16kHz DMIC NHLT configuration tables via alsatplg nhlt plugin to override buggy BIOS NHLT tables on DUTs. - Register sof-tgl-dmic-wov-multi-4ch in tplg-targets-cavs25.cmake, and sof-ptl-dmic-wov-multi-4ch / sof-wcl-dmic-wov-multi-4ch in tplg-targets-ace3.cmake. - Update detect_test component in DSP firmware to support 4-channel audio streams and multi-channel DP buffer downmixing. - Update wov_multi_slot_test.py to support configurable channel count (-c 4). - Verified on Spider DUT with 100% pass across all multi-slot trigger cycles and audio captures. Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
- Document embedded NHLT table generation via alsatplg nhlt preprocessor plugin (PREPROCESS_PLUGINS "nhlt") for native 16kHz 4-channel DMIC. - Document Linux SOF kernel driver BIOS NHLT override mechanism (snd_sof_intel_hda_common.sof_use_tplg_nhlt=1). - Add DUT modprobe reload and verification instructions to wov_arbiter and topology2 READMEs. Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
…, and teardown fixes
Add missing components to WCL modules overlay: CONFIG_COMP_TDFB=m CONFIG_COMP_VOLUME=m Signed-off-by: Naveen Manohar <naveen.m@intel.com>
Commit "topology: kpb: add topology-configurable history" added IncludeByKey.KPB_BUFF_TIME_MS to kpb widget class but only defined KPB_BUFF_TIME_MS in dmic-wov-multi-manifest.cf All topologies that includes kpb.conf without manifest fails to build. Add a "none" default to common_definitions.conf. Log Before: No variable defined for KPB_BUFF_TIME_MS Failed to process includes Failed to process conditional includes in input config FAILED: [code=1] .../sof-dmic-4ch-wov.tplg After: [0/2] Generating sof-dmic-4ch-wov.tplg Signed-off-by: Naveen Manohar <naveen.m@intel.com>
Add a standalone feature manifest (dmic-wov-feature.conf) for the WoV/KPB pipeline, loaded on top of the function topology via feature_topologies. Add single platform-agnostic feature topology target, sof-dmic-4ch-wov, in tplg-targets-ace3.cmake so it can be shared across PTL (rt721/rt722) and WCL. Signed-off-by: Naveen Manohar <naveen.m@intel.com>
WCL RVP's UEFI BIOS for ALOS publishes no NHLT ACPI table, so DSP has no DMIC hardware conf & PCM 11 failed hw_params with EINVAL for every format. Use topology-embedded NHLT override instead, which kernel already accepts via sof_use_tplg_nhlt=1. 3 fixes are needed to make WCL 4-ch multi-slot WoV topology load on this platform: - Wire wov_arbiter.toml into WCL rimage config. The module & TOML were added upstream but never included by any plt, so FW manifest carried no WOVARB entry with kernel log: "failed to find module info for widget wov-arbiter.104.1". - Enable CONFIG_COMP_WOV_ARBITER defaults to n, disable CONFIG_COMP_GOOGLE_HOTWORD_DETECT which needs proprietary hotword_dsp_api.h and has no ACE30 library build. - Retarget manifest from dmic01->dmic16k. dmic01 is already claimed by base topology sof-wcl-dmic-4ch-id5.tplg and a feature topology cannot rebind a bound BE; attempting it failed snd_soc_component_probe(). - Reduce KPB_BUFF_TIME_MS from 6000 to 2100, as 6000 ms of 4ch/32-bit/16 kHz history is 1536000B exceeds DSP heap. PCM11 now enumerates as "DMIC Multi-WOV 4CH", topology loads without error & hw_params/prepare succeed. Signed-off-by: Naveen Manohar <naveen.m@intel.com>
ecns.toml exists (added upstream) but was only included for PTL and TGL in tools/rimage/config/*.toml.h, not WCL. CONFIG_COMP_ECNS also defaults to n. Building WCL with the module compiled in but its TOML unregistered fails at compile time: error: '_UUIDREG_ecns' undeclared here (not in a function) #define SOF_REG_UUID(name) _UUIDREG_##name ... SOF_DEFINE_REG_UUID(ecns); _UUIDREG_ecns is generated from src/audio/ecns/ecns.toml via scripts/gen-uuid-reg.py against sof/uuid-registry.txt, which already has an ecns entry; the include was simply missing for this platform, same gap as wov_arbiter fixed earlier for WCL. Wire ecns.toml into wcl.toml.h under CONFIG_COMP_ECNS and enable the Kconfig for WCL. Build now succeeds; the firmware manifest carries: name = "ECNS" uuid = "214f8a6c-493a-4b1e-8b1e-0d3b6f8a2c15" Signed-off-by: Naveen Manohar <naveen.m@intel.com>
Add ECNS processing pipeline to WCL multi-slot WoV-topology Route mono ECNS output through 2100 ms KPB & WoV arbiter to PCM 11 and expose the stereo ECNS output on PCM 12. Keep WCL NHLT-override DMIC configuration & 3 WoV detector routes. Post-ECNS mono 16-bit KPB buffer requires 67.2kb. Signed-off-by: Naveen Manohar <naveen.m@intel.com>
…scoring kcontrols - Integrate microWakeWord (MWW) from PR 11135 to replace test WOV modules. - Single unified codebase across 3 concurrent keyword spotters: * Slot 0: strawberry * Slot 1: banana * Slot 2: orange - Add 2 Hz read-only volatile enum scoring kcontrol per MWW instance (MWW 101 Score, MWW 102 Score, MWW 103 Score) with IPC4 notifications. - Unify multi-slot topology across PTL, TGL, and WCL targets. - Verified on Aphid DUT (PTL): all modules loaded in DAPM, dynamic power transitions confirmed, and real-time score updates validated.
Patch for changes: - Enable WCL MWW prerequisites and memory budget. - Register mww.toml in the WCL rimage configuration. - Remove stale TFLM source entries absent from the required dependency tree. - Build strawberry, banana, and orange fruit models. - Generate & deploy MWW UUID module: 4067FE1D-CD63-4877-966B-A06DED1719CE.bin Signed-off-by: Naveen Manohar <naveen.m@intel.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Multi-Slot Wake-On-Voice (WOV) Architecture & Arbitration
Overview
The Multi-Slot WOV subsystem lets a single DMIC feed up to 3 concurrent keyword detectors
running on the DSP. A single shared KPB sits between the VAD gate and the fan-out mixin,
recording a pre-roll window (6 seconds on TigerLake, 2.1 seconds on other platforms) for all
three slots in one 192 KB ring buffer — versus 576 KB in a per-slot design. When any detector
fires the
wov_arbiterdrains the KPB ring buffer to the host via an ALSA compress device andpauses the other detectors. When the host closes the stream the arbiter resumes all detectors.
The ALSA compress framework (
snd_compr) decouples HDA DMA from the audio sample-rate clock.During the pre-roll burst the KPB draining EDF task fills HDA DMA fragments as fast as the bus allows
rather than at the rate-locked 16 kHz × sample-size pace of a regular PCM device.
After the pre-roll drains the live DMIC stream continues over the same compress device at realtime rate.
This design keeps host DMA live and eliminates the wakeup latency normally incurred by starting
DMA after detection.
System Architecture
Component Graph
graph TD subgraph P100["Pipeline 100 — Capture, Gating & Pre-Roll (Core 0)"] DAI["DAI Copier\nHDA Analog\ndai_index=1"] VAD["vad_gate\n(energy estimator)"] KPB["kpb\n**shared** 192 KB ring buffer\n(6 s pre-roll for all slots)"] MIX["mixin\n(1→3 fan-out)"] DAI --> VAD --> KPB --> MIX end subgraph P101["Pipeline 101 — Slot 0 (Core 0)"] MO0["mixout 0"] D0["detect_test\nSlot 0\n(Male 80–170 Hz)"] MO0 --> D0 end subgraph P102["Pipeline 102 — Slot 1 (Core 0)"] MO1["mixout 1"] D1["detect_test\nSlot 1\n(Female 175–270 Hz)"] MO1 --> D1 end subgraph P103["Pipeline 103 — Slot 2 (Core 1)"] MO2["mixout 2"] D2["detect_test\nSlot 2\n(Child 275–500 Hz)"] MO2 --> D2 end subgraph P104["Pipeline 104 — Arbitration & Host Capture (Core 0)"] ARB["wov_arbiter\n(first-wins)"] HC["host-copier\ncomprC0D11\n'DMIC Multi-WOV'"] ARB --> HC end MIX --> MO0 MIX --> MO1 MIX --> MO2 D0 --> ARB D1 --> ARB D2 --> ARB D0 -- "Notifier WOV_DETECT\n(slot_id=0)" --> ARB D1 -- "Notifier WOV_DETECT\n(slot_id=1)" --> ARB D2 -- "Notifier WOV_DETECT\n(slot_id=2)" --> ARB ARB -- "Notifier WOV_CTRL\n(PAUSE/RESUME)" --> D0 ARB -- "Notifier WOV_CTRL\n(PAUSE/RESUME)" --> D1 ARB -- "Notifier WOV_CTRL\n(PAUSE/RESUME)" --> D2 %% Row layout hints (invisible ~~~ edges — dagre rank control) %% Row 0: P100 | Row 1: P101 / P102 / P103 | Row 2: P104 KPB ~~~ MO0 MO0 ~~~ ARB style VAD fill:#2d5a27,stroke:#555 style KPB fill:#4a3a00,stroke:#555 style ARB fill:#1c4966,stroke:#555 style D0 fill:#663300,stroke:#555 style D1 fill:#660033,stroke:#555 style D2 fill:#003366,stroke:#555Pipeline State Transitions & Re-Arm Cycle
Usage Flow (Compress Device Open Once)
The compress device is opened once at startup and kept open across all WOV cycles.
No pipeline close/reopen is needed between triggers.
WOV Trigger Sequence
DSP-Initiated Re-Arm (VAD Silence Path)
This is the no-reset re-arm: compress device stays open, pipeline stays RUNNING.
Between-Cycle Re-Arm (Drain + VAD Gate Kcontrol)
The compress device stays RUNNING across all WOV cycles — no
compress_stop()/compress_start()is issued between triggers. The host re-arms by draining andpolling the
vad_gate_status_100kcontrol:State Transition Summary
SOF Notifier Inter-Module Signaling
The SOF Notifier system (
src/include/sof/lib/notifier.h) is SOF's intra-DSPpublish/subscribe bus. It works on all platforms (no
CONFIG_AMSrequired) andis already used for KPB client events. Signals are delivered synchronously to
all registered listeners on the calling core.
Signal Catalog
NOTIFIER_ID_WOV_DETECTstruct wov_detect_notif { uint8_t slot_id; }NOTIFIER_ID_WOV_CTRLstruct wov_ctrl_notif { uint8_t cmd; }NOTIFIER_ID_VAD_SILENCENULL(no payload)cmdvalues:WOV_ARB_CMD_PAUSE,WOV_ARB_CMD_RESUME(defined inwov_arbiter.h).NOTIFIER_ID_VAD_SILENCEis fired byvad_update_energy()when the IIR energy dropsbelow threshold for
hangover_framesconsecutive frames. The arbiter'sarb_on_vad_silence()callback handles it: resetsactive_slot = WOV_ARB_NO_ACTIVEand broadcasts
WOV_ARB_CMD_RESUMEto all detectors so they re-arm without anypipeline RESET or compress device close/reopen.
Full Detect-to-Drain Sequence
sequenceDiagram autonumber participant DMIC as DMIC (HW) participant KPB as KPB (shared P100) participant DET as detect_test (slot N) participant ARB as wov_arbiter participant HOST as Host Compress (comprC0D11) participant OTHER as detect_test (slots ≠ N) Note over DMIC,OTHER: Listening state — shared KPB accumulating pre-roll for all slots loop Every 1 ms (LL period) DMIC->>KPB: DAI DMA frames KPB->>DET: sel_sink copy end loop Every 20 ms (DP batch) DET->>DET: run algorithm on 320-frame batch end Note over DET,ARB: Keyword detected on slot N DET->>HOST: ① IPC4 SOF_IPC4_NOTIFY_PHRASE_DETECTED\n (word_id = slot_id) DET->>KPB: ② notifier_event(WOV_DETECT) [KPB already wired via kpb_client] DET->>ARB: ③ notifier_event(NOTIFIER_ID_WOV_DETECT, slot_id=N) ARB->>ARB: active_slot = N ARB->>OTHER: notifier_event(NOTIFIER_ID_WOV_CTRL, cmd=PAUSE) OTHER->>OTHER: cd->paused = true\n(stops DP batching) KPB->>ARB: stream pre-roll (up to 6 s) via host_sink ARB->>HOST: route slot-N audio to host PCM Note over HOST,ARB: Host finishes reading / closes PCM HOST->>ARB: trigger STOP (ALSA hw_free / snd_pcm_close) ARB->>ARB: active_slot = NO_ACTIVE ARB->>OTHER: notifier_event(NOTIFIER_ID_WOV_CTRL, cmd=RESUME) ARB->>DET: notifier_event(NOTIFIER_ID_WOV_CTRL, cmd=RESUME) OTHER->>OTHER: cd->paused = false\ncd->detected = 0\nresumed listening