Skip to content

Audio Mixer HAL Routing and Connectivity Test Direction

Ulrond edited this page Sep 17, 2026 · 2 revisions

A proposed direction for testing a vendor's com.rdk.hal.audiomixer implementation: verify that each configured input reaches exactly the mixers and output ports it is routed to, at the commanded level, and nowhere else.

Applies to interface version 0.3.0.0 (audiomixer/current).


Why test at this layer

The audio mixer HAL is the routing plane between audio producers (audio sinks, application audio, HDMI/composite inputs) and the physical output ports. A suite that drives the HAL directly isolates the vendor implementation from everything above it: if the plumbing is right here, routing failures higher up are wiring rather than mixer faults.

The suite qualifies the HAL contract, not the SoC. The test matrix is derived at runtime from what the implementation advertises — Capabilities.inputs, getAudioOutputPortIds(), per-port OutputPortCapabilities — and every advertised combination must pass. Unadvertised combinations are skipped with a recorded reason. The only per-platform configuration the suite accepts is physical rig wiring for the external-stimulus tier.

The suite exercises the routing plane with synthetic stereo PCM markers only. Audio format processing (MS12/DAP, passthrough formats) is a separate conformance area and is not exercised here.


Surface under test

Interface Role in this suite
IAudioMixerManager Enumerate mixers (getAudioMixerIds(), getAudioMixer())
IAudioMixer getCapabilities(), getAudioOutputPortIds(), open()/close(), getInputRouting() readback
IAudioMixerController setInputRouting(), setInputVolume(), setInputVolumeRamp(), lifecycle (start/stop/flush)
InputRouting Routing entry: {AudioSourceType, sourceIndex}
AudioSourceType AUDIO_SINK, HDMI_INPUT, COMPOSITE_INPUT, APPLICATION_AUDIO
IAudioOutputPort / IAudioOutputPortController Per-port state, ENABLED/MUTE/VOLUME properties, capture access
IAudioCapture / IAudioCaptureListener Observation point: shared-memory PCM tap per output port

IAudioCapture is obtained per output port via IAudioOutputPortController.getAudioCapture() and gated by OutputPortCapabilities.supportsAudioCapture. Where a port advertises capture, mixer-to-port fan-out is verified in-system; ports without capture support are verified by physical loopback in the external-stimulus tier.


Method — marker injection

Each active input carries a unique, machine-detectable marker: a pure tone at a distinct non-harmonically-related frequency (997 Hz, 1201 Hz, 1499 Hz, 1741 Hz, ...), stereo PCM, 48 kHz, −20 dBFS, generated by the harness. AUDIO_SINK and APPLICATION_AUDIO markers are injected through the corresponding com.rdk.hal.audiosink instances; HDMI_INPUT and COMPOSITE_INPUT markers require external stimulus. The captured output is analysed with a per-frequency Goertzel detector — ~100 lines of dependency-free C++, deterministic, CI-friendly.

flowchart LR
    subgraph Harness["Test harness"]
        GEN["Marker generators<br/>997 Hz / 1201 Hz / 1499 Hz"]
        DET["Goertzel detector<br/>per marker frequency"]
    end
    subgraph HAL["audiomixer HAL"]
        IN0["Input 0<br/>AUDIO_SINK 0"]
        IN1["Input 1<br/>AUDIO_SINK 1"]
        IN2["Input 2<br/>APPLICATION_AUDIO"]
        MIX["IAudioMixer<br/>setInputRouting()"]
        P0["Output port HDMI"]
        P1["Output port SPEAKERS"]
        CAP["IAudioCapture<br/>per-port PCM tap"]
    end
    GEN --> IN0 & IN1 & IN2
    IN0 & IN1 & IN2 --> MIX
    MIX --> P0 & P1
    P0 & P1 --> CAP
    CAP --> DET
Loading

Four metrics decide pass/fail:

Metric Definition Pass criterion
Presence Level of a routed input's marker at the observed output ≥ −30 dBFS (marker injected at −20 dBFS; margin absorbs mixer headroom scaling)
Isolation Level of every non-routed input's marker at the observed output ≤ −60 dBFS
Level tracking Measured marker level delta after setInputVolume() / setInputVolumeRamp() / MUTE Delta matches commanded change ±1 dB; MUTE and MixingMode.MUTED drive the marker below −60 dBFS
Switch latency Time from setInputRouting() return to old marker gone and new marker present at the capture point Recorded and reported; threshold set per requirement clause, not per SoC

The presence/isolation pair is the core of the suite: presence proves the commanded route exists; isolation proves no un-commanded route exists. Isolation is measured on every test, not only in dedicated cross-talk cases — every capture window is checked for all markers currently being injected anywhere in the system.


Tier 1 — contract tests (no audio path)

Interface-level tests against the AIDL contract. These run against any implementation, including a reference stub on an x86 simulation.

ID Test Pass criterion
AMX-T1-001 Enumerate mixers getAudioMixerIds() non-empty; getAudioMixer() non-null for each advertised id, null for others
AMX-T1-002 Capabilities honesty getCapabilities().inputs non-empty; each MixerInput declares supportedContentTypes and supportedCodecs
AMX-T1-003 Open/close lifecycle open() returns controller in READY; second open() on same mixer per contract; close() with foreign controller returns false
AMX-T1-004 Routing readback For every valid InputRouting[] combination derived from capabilities: setInputRouting() returns true and getInputRouting() returns the identical array
AMX-T1-005 Routing rejection Out-of-range sourceIndex, AudioSourceType not offered by any MixerInput, duplicate entries: setInputRouting() returns false and prior routing is retained
AMX-T1-006 Volume bounds setInputVolume() rejects out-of-range inputIndex; getInputVolume() reads back the set value
AMX-T1-007 State machine start/stop/flush sequences drive the documented State transitions; event listener receives each transition exactly once
AMX-T1-008 Listener lifecycle Register/unregister pairs; unregistered listener receives no further events
AMX-T1-009 Secure open open(secure=true) honoured only when Capabilities.supportsSecure; capture from a secure mixer is denied or zero-filled per contract

Tier 2 — in-system connectivity tests

Markers flowing, observed at the per-port capture tap, on target hardware. The routing matrix is generated at runtime: every advertised {input source} x {mixer id} x {capture-capable output port} combination.

ID Test Pass criterion
AMX-T2-001 Single route presence One input routed to one mixer: marker present at every port fed by that mixer, all four metrics pass
AMX-T2-002 Full matrix sweep Every advertised input x mixer x port combination in turn: presence + isolation on each
AMX-T2-003 Concurrent isolation Two inputs routed to different mixers simultaneously: each port carries only its own mixer's marker; both isolation floors hold
AMX-T2-004 Multi-input mix Two inputs routed to the same mixer: both markers present at the mixer's ports at commanded relative levels
AMX-T2-005 Route switch Routing changed while started: old marker decays below floor, new marker appears; switch latency recorded; no capture gap longer than one buffer period
AMX-T2-006 Volume and ramp setInputVolume() steps and setInputVolumeRamp() curves measured against level-tracking criterion; ramp completes within overMs ±1 buffer period
AMX-T2-007 Mixing modes MUTED/DUCKED/SOLO/MIXED_OVERRIDE each verified by measured level per mode definition
AMX-T2-008 Port property plumbing Per-port ENABLED=false and MUTE=true drive that port's marker below floor while other ports are unaffected
AMX-T2-009 Flush and discontinuity flush()/signalDiscontinuity() during flow: marker resumes, no stale audio from before the flush appears after it
AMX-T2-010 Soak sweep AMX-T2-002 repeated for N cycles (default 100): no drift in presence level, no isolation degradation, no underflow/overflow growth (METRIC_UNDERFLOWS/METRIC_OVERFLOWS)

Tier 3 — external-stimulus tests

Only where the marker must cross a physical connector. Rig wiring (which connector loops to which capture device) is the single permitted per-platform configuration input.

ID Test Pass criterion
AMX-T3-001 HDMI input routing External source plays a marker into HDMI_INPUT; routed per AMX-T2-001; presence + isolation at capture-capable ports
AMX-T3-002 Composite input routing As AMX-T3-001 for COMPOSITE_INPUT where advertised
AMX-T3-003 Physical port verification For ports with supportsAudioCapture=false: physical loopback (HDMI/SPDIF into an external capture card) confirms presence + isolation at the connector

Suite rules

  • Every test derives its parameter set from runtime capability enumeration. A hard-coded mixer id, port name, or input count anywhere in the suite is a defect in the suite.
  • An advertised capability that fails is a HAL compliance failure; there is no per-SoC waiver table or expected-results file.
  • Skips are recorded with the capability field that gated them, so the per-SoC report distinguishes "not advertised" from "not run".
  • Test signals are harness-generated PCM only; no licensed content, no encoded formats.
  • Property.DEBUG_TAP_ENABLED may be used as a supplementary engineering tap during failure triage; pass/fail is decided only at the IAudioCapture observation point defined per test.

Clone this wiki locally