Aria (Automatic Regressive Input Amplifier) Architecture#
The Aria (Automatic Regressive Input Amplifier) subsystem in Sound Open Firmware (SOF) is a specialized, intelligent dynamic range pre-amplifier and lookahead peak limiter. Designed primarily for capture pipelines (such as microphone front-ends and far-field speech recognition) and sensitive playback chains, Aria applies a selectable target pre-amplification boost (\(0\text{ dB}\), \(+6\text{ dB}\), \(+12\text{ dB}\), or \(+18\text{ dB}\)) to incoming audio signals. When high-amplitude signals or abrupt transient bursts enter the pipeline, Aria automatically and regressively ducks the gain below the target, ensuring that peak signal amplitudes never exceed \(0\text{ dBFS}\) (\(A_{FS} = \text{0x007fffff}\) in 24-bit container format) without introducing clipping or digital saturation.
To perform artifact-free gain modulation, Aria integrates an internal circular delay buffer introducing exactly \(1\text{ ms}\) of lookahead algorithmic latency. This lookahead window allows the gain calculation engine to inspect future audio peaks before they reach the output, computing an optimal attenuation curve that is applied via sample-by-sample linear interpolation, totally eliminating zipper noise and transient overshoot.
Architectural Overview & Functional Role#
In modern digital signal processing pipelines, capture front-ends must accommodate a wide dynamic range of acoustic inputs—from faint whispers in distant microphone arrays to loud shouts or unexpected acoustic shocks. Conventional static gain stages and traditional automatic gain controls present fundamental trade-offs:
Static Linear Gain Stages: Applying a fixed pre-amplification gain (e.g. \(+12\text{ dB}\)) boosts quiet signals into the optimal operating range of downstream automatic speech recognition (ASR) engines, but inevitably causes harsh digital clipping whenever loud acoustic transients enter the analog-to-digital converter (ADC).
Dynamic Range Compressors (DRC): Standard wideband or multiband compressors can manage high amplitudes, but rely on complex envelope followers (attack/release filters) and non-linear logarithmic curve mappings. When an unexpected transient occurs, feedback compressors cannot react instantaneously without significant lookahead buffers, leading to either initial transient clipping or prolonged gain pumping.
Automatic Gain Control (AGC): AGC systems operate on long time horizons (typically 100 to 500 ms). While effective for slow vocal level drift, they are too sluggish to protect against sudden peak clipping.
The Aria component resolves this challenge by operating as an Automatic Regressive Input Amplifier:
Target Linear Pre-amplification: Under nominal conditions where the signal resides safely within available headroom, Aria acts as a fixed linear pre-amplifier, applying the configured target gain of \(0\text{ dB}\), \(+6\text{ dB}\), \(+12\text{ dB}\), or \(+18\text{ dB}\).
Instantaneous Regressive Back-off: When the peak amplitude of an incoming block exceeds the headroom threshold, the amplification factor automatically regresses (attenuates) in exact proportion to the peak overshoot:
\[G_{regressive} = \frac{A_{FS}}{\text{Peak Amplitude}}\]This guarantees that the peak output amplitude is locked at \(A_{FS}\), completely preventing digital overflow.
Deterministic 1 ms Lookahead Latency: By buffering \(1\text{ ms}\) of audio in an internal circular buffer, the peak detection engine evaluates incoming frames in advance. Gain transitions are smoothly interpolated across the entire frame window, eliminating step discontinuities.
Figure 175 SOF Aria Subsystem Architecture: Lookahead Buffer, Dynamic Regressive Amplifier & Linear Ramp Engine#
Comparison with Other SOF Modules#
To clarify when Aria should be instantiated in an audio graph rather than alternative processing blocks, the following table summarizes functional boundaries across related SOF components:
Subsystem |
Primary Operating Mode |
Dynamic Reaction Speed |
Typical Deployment Target |
|---|---|---|---|
Aria |
Target gain (\(0/6/12/18\text{ dB}\)) with instant regressive back-off |
Instantaneous lookahead (\(1\text{ ms}\) pre-transient interpolation) |
Microphone capture front-ends and sensitive playback endpoints |
Volume |
User-controlled linear/logarithmic gain slider (\(-\infty\) to \(0\text{ dB}\)) |
User-paced smooth ramp (typically \(16\text{ ms}\) to \(500\text{ ms}\)) |
Main and per-stream loudness controls |
DRC |
Multi-segment compression knee with ratio, threshold, and makeup gain |
Envelope-follower driven attack (\(1\text{ ms}\) to \(20\text{ ms}\)) and release (\(50\text{ ms}\) to \(1000\text{ ms}\)) |
Speaker overload protection and studio post-processing compression |
Smart Amp |
Physical electro-mechanical-thermal speaker excursion modeling |
Fast non-linear displacement tracking with slow thermal decay |
Micro-speaker protection in mobile and thin laptops |
Mathematical Foundations & Regressive Dynamic Headroom#
Aria operates strictly on 24-bit audio packaged inside 32-bit containers (SOF_IPC_FRAME_S24_4LE). In this encoding, sample values occupy the 24 least significant bits, sign-extended to 32 bits:
The positive full-scale maximum amplitude is denoted as:
Target Gain Parameterization#
The target pre-amplification boost is configured via the unsigned integer parameter \(\text{att} \in \{0, 1, 2, 3\}\):
Parameter \(\text{att}\) |
Linear Multiplier \(2^{\text{att}}\) |
Decibel Boost \(G_{target}\) |
Permissible Input Headroom \(A_{thresh}\) |
|---|---|---|---|
0 |
\(1.0\times\) (\(2^0\)) |
\(0.00\text{ dB}\) (Bypass) |
\(A_{FS} = \text{0x007FFFFF} = 8,388,607\) (\(0.00\text{ dBFS}\)) |
1 |
\(2.0\times\) (\(2^1\)) |
\(+6.02\text{ dB}\) |
\(A_{FS} / 2 = \text{0x003FFFFF} = 4,194,303\) (\(-6.02\text{ dBFS}\)) |
2 |
\(4.0\times\) (\(2^2\)) |
\(+12.04\text{ dB}\) |
\(A_{FS} / 4 = \text{0x001FFFFF} = 2,097,151\) (\(-12.04\text{ dBFS}\)) |
3 |
\(8.0\times\) (\(2^3\)) |
\(+18.06\text{ dB}\) |
\(A_{FS} / 8 = \text{0x000FFFFF} = 1,048,575\) (\(-18.06\text{ dBFS}\)) |
Headroom Threshold & Regressive Gain Derivation#
To prevent any sample from exceeding \(A_{FS}\) when amplified by \(2^{\text{att}}\), the linear input threshold is:
For every processing chunk (e.g. 48 frames at 48 kHz, spanning \(1\text{ ms}\)), the algorithm detects the peak absolute amplitude across all channels:
The mathematical gain computation distinguishes between two regimes:
Unclipped Linear Regime (\(\text{max\_data} \le A_{thresh}\)): The signal fits completely within available headroom. The raw 64-bit gain word is set to:
\[\text{gain} = 2^{\text{att} + 32} - 1\]When normalized into a 32-bit state variable, it yields full fractional scale:
\[g = \text{gain} \gg (\text{att} + 1) = 2^{31} - 1 = \text{0x7FFFFFFF}\]Regressive Compression Regime (\(\text{max\_data} > A_{thresh}\)): Applying the target boost would push the output past \(A_{FS}\). The raw gain word is dynamically calculated via 64-bit integer division:
\[\text{gain} = \left\lfloor \frac{A_{FS} \cdot 2^{32}}{\text{max\_data}} \right\rfloor = \left\lfloor \frac{\text{0x007FFFFF} \cdot 2^{32}}{\text{max\_data}} \right\rfloor\]The normalized gain state is then scaled:
\[g = \text{gain} \gg (\text{att} + 1) = \left\lfloor \frac{\text{0x007FFFFF} \cdot 2^{31}}{\text{max\_data} \cdot 2^{\text{att}}} \right\rfloor\]
Dynamic Shift Output Scaling#
During output sample synthesis, the sample multiplication applies a dynamic right-shift determined by:
The output sample \(y[n, ch]\) is generated by multiplying the input sample by the normalized gain and right-shifting:
Mathematical Proof of Anti-Clipping Clamping#
Evaluating this equation in the regressive regime where \(\text{max\_data} > A_{thresh}\):
For the peak sample in the chunk (\(|x[n, ch]| = \text{max\_data}\)):
The peak output is clamped exactly to \(0\text{ dBFS}\), guaranteeing that no digital overflow occurs regardless of the input burst magnitude.
Figure 176 Mathematical Dynamics: Target Gain Boost (0/6/12/18 dB), Headroom Thresholds & Regressive Ducking Curve#
1 ms Lookahead Circular Buffer & Latency Phasing#
A fundamental problem in conventional peak limiters is that gain reduction is triggered after or at the arrival of a peak, causing either initial overshoot clipping or unnatural transient distortion. Aria completely eliminates this issue by introducing a 1 ms lookahead window realized through an internal circular delay buffer.
Buffer Sizing & Memory Layout#
The circular buffer is allocated during component initialization (aria_init()) to hold exactly \(1\text{ ms}\) of audio across all channels:
where:
\(\text{chan\_cnt}\) is the number of audio channels (e.g. 2 for stereo, 4 for quad mic array).
\(\text{smpl\_group\_cnt}\) is the number of samples per channel in \(1\text{ ms}\) (e.g. 48 samples at 48 kHz).
The buffer is aligned to 8-byte boundaries (2 samples of 32-bit audio) to satisfy SIMD vector memory alignment requirements.
An offset variable is tracked:
ensuring that the circular buffer read and write pointers maintain invariant alignment throughout runtime execution.
Phased Execution Cycle (The 4-Step Pipeline)#
In every processing tick of aria_process_data(), Aria executes four consecutive operations:
Step 1: Lookahead Peak Inspection (\(t + 1\text{ ms}\)): The function
aria_algo_calc_gain()inspects the future incoming frames insource. It scans all channels, calculates the peak absolute value \(\text{max\_data}\), evaluates whether regressive compression is required, and stores the computed gain into the gain history table at:\[\text{gain\_idx} = \text{sof\_aria\_index\_tab}[\text{cd->gain\_state} + 1]\]Step 2: Delayed Audio Retrieval & Gain Application (\(t\)): The function
cd->aria_get_datareads the past audio stored in the circular buffer atcd->data_ptr(which entered the buffer \(1\text{ ms}\) prior). It linearly interpolates the gain across the block and writes the protected, amplified audio tosink.Step 3: History Buffer Ingestion: The function
cir_buf_copy()transfers the future incoming audio fromsourceinto the circular buffer atcd->data_ptr, storing it as history for processing in the subsequent millisecond.Step 4: Circular Pointer Wrap: The circular pointer is advanced by the chunk sample size and wrapped using
cir_buf_wrap():\[\text{cd->data\_ptr} = \text{cir\_buf\_wrap}(\text{cd->data\_ptr} + \text{sample\_size}, \text{cd->data\_addr}, \text{cd->data\_end})\]
Bypass Invariance#
When \(\text{att} == 0\), Aria operates in bypass mode. Rather than short-circuiting the buffer, aria_process_data() routes audio through the circular delay buffer without applying gain multipliers:
if (cd->att) {
aria_algo_calc_gain(cd, sof_aria_index_tab[cd->gain_state + 1], source, frames);
cd->aria_get_data(mod, sink, frames);
} else {
cir_buf_copy(cd->data_ptr, cd->data_addr, cd->data_end,
sink->w_ptr, sink->addr, sink->end_addr,
data_size);
}
This design ensures that the pipeline latency is strictly invariant at 1 ms, preventing downstream phase misalignments or timestamp discontinuities when switching attenuation modes on the fly.
Figure 177 Lookahead Buffer Timing & 1 ms Lookahead Latency Phasing (Future Peak Detection vs Delayed Stream Application)#
Multi-State Gain Follower & Per-Sample Linear Interpolation#
Abrupt gain changes between consecutive processing chunks produce audible discontinuities known as zipper noise and generate high-frequency distortion harmonics. To ensure acoustic transparency, Aria utilizes a 10-state sliding gain tracking table and continuous per-sample linear interpolation.
Sliding Gain History Table#
Aria maintains 10 historical gain values in the array:
int32_t gains[ARIA_MAX_GAIN_STATES]; // ARIA_MAX_GAIN_STATES = 10
To eliminate expensive runtime modulo arithmetic (\(\% 10\)), indexing is performed via a pre-computed lookup table:
const int32_t sof_aria_index_tab[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
0, 1, 2, 3
};
Lookahead Minimum-Envelope Search#
When determining the starting gain (\(\text{gain\_begin}\)) and ending gain (\(\text{gain\_end}\)) for the current \(1\text{ ms}\) chunk, Aria searches across a multi-state window for the minimum gain value:
int32_t gain_state_add_2 = cd->gain_state + 2;
int32_t gain_state_add_3 = cd->gain_state + 3;
int32_t gain_begin = cd->gains[sof_aria_index_tab[gain_state_add_2]];
int32_t gain_end = cd->gains[sof_aria_index_tab[gain_state_add_3]];
for (i = 1; i < ARIA_MAX_GAIN_STATES - 1; i++) {
if (cd->gains[sof_aria_index_tab[gain_state_add_2 + i]] < gain_begin)
gain_begin = cd->gains[sof_aria_index_tab[gain_state_add_2 + i]];
if (cd->gains[sof_aria_index_tab[gain_state_add_3 + i]] < gain_end)
gain_end = cd->gains[sof_aria_index_tab[gain_state_add_3 + i]];
}
By tracking the minimum gain across states, Aria establishes a lookahead attack envelope:
If an impending peak requires severe gain reduction, \(\text{gain\_begin}\) and \(\text{gain\_end}\) are pulled downward before the peak reaches the output.
The gain ramps down smoothly toward the required attenuation, so that the signal is already safely compressed when the peak transient hits the output multiplier.
Conversely, when transitioning out of a transient into quiet audio, the gain recovers smoothly across subsequent blocks without abrupt pumping.
Continuous Per-Sample Linear Interpolation#
Once \(\text{gain\_begin}\) and \(\text{gain\_end}\) are determined, Aria computes the per-sample ramp increment:
The gain accumulator starts at \(\text{gain} = \text{gain\_begin}\). For every sample group, the current gain is applied and then updated:
This ensures \(C^0\) continuity across the entire audio stream, completely eliminating zipper noise.
Figure 178 Multi-State Gain Follower & Linear Interpolation Ramp (Minimum-Envelope Search & Per-Sample Stepping)#
Tensilica HiFi SIMD Acceleration & Hardware Circular Buffers#
The computational throughput of the Aria component is heavily optimized using Cadence Tensilica HiFi SIMD instruction sets, delivering distinct implementations across Generic Scalar C, HiFi3 / HiFi4, and HiFi5.
Generic Scalar Implementation (aria_generic.c)#
The scalar C fallback performs signed 24-bit sign-extension and fixed-point fractional multiplication:
in_sample = sign_extend_s24(*in++);
out[ch] = q_multsr_sat_32x32_24(in_sample, gain, shift);
While fully functional and portable across any processor architecture (including RISC-V and ARM), the scalar loops require branching for circular wrapping and sample-by-sample clamping.
Tensilica HiFi3 / HiFi4 Acceleration (aria_hifi3.c)#
The HiFi3/4 kernel introduces vectorized peak detection, odd/even channel specialization, and symmetric rounding:
Vector Absolute Maximum in a Single Instruction: In
aria_algo_calc_gain(), the future sample stream is scanned using 64-bit vector alignment loads (AE_LA64_PP) and theAE_MAXABS32Sinstruction, which simultaneously computes the absolute value and compares it against the running maximum across dual 32-bit SIMD lanes in a single cycle:AE_LA32X2_IP(in_sample, inu, in); max_data = AE_MAXABS32S(max_data, AE_SLAI32(in_sample, 8));
Channel Specialization (Odd vs Even Channels): To maximize vector register utilization,
aria_algo_get_data_func()dynamically binds eitheraria_algo_get_data_odd_channel()oraria_algo_get_data_even_channel(): - Even Channels (Stereo, Quad, 8ch): Samples are processed in pairs (\(\text{ch} += 2\)). Dual 32-bit vector registersAE_LA32X2_IPfeed high and low 32x32 multipliers:out1 = AE_MUL32_HH(in_sample, gain); out1 = AE_SRAA64(out1, shift_bits); out2 = AE_MUL32_LL(in_sample, gain); out2 = AE_SRAA64(out2, shift_bits);
Odd Channels (Mono, 3ch, 5ch): Samples are processed individually with single-lane instructions (
AE_L32_XPandAE_S32_L_XP).
Symmetric Rounding and Saturation: Intermediate products are rounded from 48-bit fixed-point back to 24-bit signed representation using
AE_ROUND24X2F48SSYM, guaranteeing bit-exact symmetry and preventing negative DC bias accumulation.
Tensilica HiFi5 Hardware Circular Addressing (aria_hifi5.c)#
On Intel platforms equipped with Tensilica HiFi5 cores (such as Panther Lake and Lunar Lake), Aria achieves maximal memory throughput by leveraging dedicated Hardware Circular Addressing Registers:
Hardware Circular Buffer Setup: HiFi5 features dedicated circular addressing pointer registers
AE_SETCBEGIN0,AE_SETCEND0for the input delay buffer, andAE_SETCBEGIN1,AE_SETCEND1for the sink buffer:set_circular_buf0(cd->data_addr, cd->data_end); set_circular_buf1(audio_stream_get_addr(sink), audio_stream_get_end_addr(sink));
Zero-Overhead Automatic Address Wrapping: When loading and storing samples, the specialized circular instructions
AE_L32X2_XCandAE_S32X2_XC1automatically wrap the memory pointer back to the buffer start address when the end boundary is reached:AE_L32X2_XC(in_sample, in, inc); ... AE_S32X2_XC1(out_sample, out, inc);
This completely eliminates runtime boundary checking, pointer masking, and branch instructions inside the inner DSP audio loop.
128-Bit SIMD Vector Pipelines: In the peak detection stage, HiFi5 utilizes 128-bit vector loads (
AE_LA128_PPandAE_LA32X2X2_IP), processing 4 32-bit audio samples simultaneously per instruction cycle.
Figure 179 Tensilica HiFi3/HiFi4 vs HiFi5 SIMD Acceleration (Dual-Channel Multipliers vs Hardware Circular Buffering AE_SETCBEGIN)#
IPC4 Modular Interface, LLEXT Packaging & Topology 2 Graph#
Aria is fully compliant with the Intel IPC4 firmware architecture and supports both static compilation into the core firmware binary and modular dynamic loading via Zephyr Loadable Linkable Extensions (LLEXT).
IPC4 Configuration Structures#
The module configuration structure is defined in aria.h:
struct ipc4_aria_module_cfg {
struct ipc4_base_module_cfg base_cfg;
uint32_t attenuation;
} __packed __aligned(8);
base_cfg: Standard IPC4 base module configuration specifying input/output buffer sizes, audio stream format (\(\text{depth} = 32\), \(\text{valid\_depth} = 24\)), and channel count.attenuation: The target attenuation/boost mode (\(\text{att} \in \{0, 1, 2, 3\}\)). If the host provides a value greater thanARIA_MAX_ATT(3), the firmware clamps it to 3 and emits a warning trace.
Runtime Control Parameter#
Aria supports dynamic runtime adjustment of target attenuation without tearing down the audio pipeline via IPC4 large configuration messages:
Parameter ID:
ARIA_SET_ATTENUATION(1).Payload: 32-bit unsigned integer representing the new attenuation setting (
cd->att).When received in
aria_set_config(), the firmware immediately updatescd->attand recomputes the baseline gain states viaaria_set_gains().
Modular LLEXT Packaging#
When built as a loadable module (CONFIG_COMP_ARIA = "m"), Aria is compiled into an independent ELF shared object (aria.llext) and exported with a signed module manifest:
static const struct sof_man_module_manifest mod_manifest __section(".module") __used =
SOF_LLEXT_MODULE_MANIFEST("ARIA", &aria_interface, 1, SOF_REG_UUID(aria), 8);
Module Name:
"ARIA"Interface Structure:
aria_interfaceModule Version:
1Component UUID:
6d:16:f7:99:2c:37:ef:43:81:f6:22:00:7a:a1:5f:03Stack Size: 8 KB
Platform Performance Profiles (aria.toml)#
The configuration file src/audio/aria/aria.toml specifies processing constraints and Cycles Per Chunk (CPC) metrics across various operational frame sizes:
Chunk Frames |
Cycles Per Chunk (CPC) |
Input Buffer Size (IBS) |
Output Buffer Size (OBS) |
|---|---|---|---|
16 frames |
1,063,000 CPS |
16 samples |
21 samples |
32 frames |
2,680,000 CPS |
32 samples |
42 samples |
64 frames |
3,591,000 CPS |
64 samples |
85 samples |
96 frames |
4,477,000 CPS |
96 samples |
128 samples |
192 frames |
7,195,000 CPS |
192 samples |
192 samples |
ALSA Topology 2 Integration#
In ALSA Topology 2, Aria is declared as an audio effect widget in tools/topology/topology2/include/components/aria.conf:
Class.Widget."aria" {
DefineAttribute."index" {}
<include/components/widget-common.conf>
DefineAttribute."cpc" {
token_ref "comp.word"
}
DefineAttribute."is_pages" {
token_ref "comp.word"
}
Object.Control.bytes."1" {
!access [ tlv_read tlv_callback ]
Object.Base.extops.1 {
name "extctl"
get 258
put 0
}
max 4096
}
uuid "6d:16:f7:99:2c:37:ef:43:81:f6:22:00:7a:a1:5f:03"
type "effect"
no_pm "true"
cpc 5000
is_pages 1
num_input_pins 1
num_output_pins 1
}
Aria is integrated into audio playback and capture pipelines, such as topology2/include/pipelines/cavs/mixout-aria-gain-mixin-playback.conf:
Object.Base {
route.1 {
source mixout.$index.1
sink aria.$index.1
}
route.2 {
source aria.$index.1
sink gain.$index.1
}
route.3 {
source gain.$index.1
sink mixin.$index.1
}
}
Tuning Blobs via Octave/MATLAB (sof_aria_blobs.m)#
To generate pre-compiled binary configuration blobs for ALSA topology generation, SOF provides the Octave script src/audio/aria/tune/sof_aria_blobs.m. It constructs ABI-compliant configuration containers for:
passthrough.conf: Sets \(\text{att} = 0\) (Bypass, 0 dB).param_1.conf: Sets \(\text{att} = 1\) (+6 dB).param_2.conf: Sets \(\text{att} = 2\) (+12 dB).param_3.conf: Sets \(\text{att} = 3\) (+18 dB).
Figure 180 IPC4 Configuration Architecture & LLEXT Modular Packaging#
Figure 181 End-to-End Audio Graph & Topology 2 Integration (mixout-aria-gain-mixin Playback Pipeline)#
Factory Bringup, Acoustic Quality & Verification Runbook#
This section outlines an end-to-end engineering verification procedure to validate Aria functionality, dynamic boost accuracy, regressive anti-clipping clamping, and latency invariance on physical DUTs (such as Panther Lake, Meteor Lake, or Tiger Lake).
1. Topology Compilation & Deployment#
Verify that the target topology includes the Aria widget and compiles cleanly:
# Step 1: Export tuning blobs using GNU Octave
cd tools/tune/aria
octave --no-gui sof_aria_blobs.m
# Step 2: Compile ALSA Topology 2 binary
cd ../../topology/topology2
alsatplg -c development/sof-mtl-sdw-benchmark-aria24-simplejack.conf \
-o sof-mtl-sdw-benchmark-aria24-simplejack.tplg
# Step 3: Deploy topology to target DUT
scp sof-mtl-sdw-benchmark-aria24-simplejack.tplg root@<dut-ip>:/lib/firmware/intel/sof-ipc4/
2. Driver Reload & DSP Initialization Check#
Reload the kernel sound driver and inspect dmesg to verify module instantiation:
# Reload SOF audio driver on DUT
ssh root@<dut-ip> 'modprobe -r snd_sof_pci_intel_mtl && modprobe snd_sof_pci_intel_mtl'
# Check dmesg for Aria registration and UUID confirmation
ssh root@<dut-ip> 'dmesg | grep -i aria'
Expected output:
sof-audio-pci-intel-mtl: module ARIA [6d16f799-2c37-43ef-81f6-22007aa15f03] loaded
sof-audio-pci-intel-mtl: aria.1.1: created with attenuation = 1 (target +6 dB)
3. Dynamic Range & Linear Pre-amplification Verification#
Verify that low-amplitude audio receives the exact target boost across all attenuation modes:
# Generate 1 kHz test tone at -30 dBFS (well below all headroom thresholds)
sox -n -r 48000 -c 2 -b 24 test_tone_minus30dBFS.wav synth 5 sine 1000 vol -30dB
# Play test tone through Aria playback pipeline
ssh root@<dut-ip> 'aplay -D hw:0,0 test_tone_minus30dBFS.wav'
# Check output level across attenuation modes via amixer
# Mode 0 (att = 0, 0 dB): Output level must equal -30.0 dBFS
# Mode 1 (att = 1, +6 dB): Output level must equal -24.0 dBFS (+/- 0.1 dB)
# Mode 2 (att = 2, +12 dB): Output level must equal -18.0 dBFS (+/- 0.1 dB)
# Mode 3 (att = 3, +18 dB): Output level must equal -12.0 dBFS (+/- 0.1 dB)
4. Transient Shock & Anti-Clipping Clamping Verification#
Verify that full-scale signals and loud acoustic transients are strictly clamped to \(0\text{ dBFS}\) without digital wrap-around:
# Generate high-amplitude burst signal at -3 dBFS
sox -n -r 48000 -c 2 -b 24 test_burst.wav synth 3 sine 1000 vol -3dB
# Set Aria to maximum boost mode (att = 3, target +18 dB)
ssh root@<dut-ip> 'amixer -c 0 cset name="aria.1.1.extctl" 3'
# In a naive amplifier, -3 dBFS + 18 dB = +15 dBFS (massive digital clipping)
# In Aria, output peak must clamp strictly to 0.00 dBFS (0x007FFFFF)
ssh root@<dut-ip> 'aplay -D hw:0,0 test_burst.wav'
# Record capture loopback and verify maximum peak using sox
sox recorded_output.wav -n stats
Expected verification statistics:
Pk lev dB 0.00
Max amp 0.999999
Min amp -0.999999
Zero crossings 6000
Flat factor 0.00 <-- Verifies zero flat-top clipping distortion!
5. 1 ms Lookahead Latency Invariance Verification#
Measure group delay through the pipeline with Aria in bypass (\(\text{att} = 0\)) versus active (\(\text{att} = 2\)):
# Measure impulse response latency with cross-correlation
python3 -c '
import numpy as np, scipy.io.wavfile as wf
rate, ref = wf.read("impulse_ref.wav")
rate, cap = wf.read("impulse_cap.wav")
corr = np.correlate(cap[:,0], ref[:,0], mode="full")
delay_ms = (np.argmax(corr) - len(ref) + 1) / rate * 1000.0
print(f"Measured Algorithmic Delay: {delay_ms:.3f} ms")
'
The measured delay delta between bypass and active mode must be identically 0.000 ms, confirming that the circular delay buffer maintains constant pipeline latency.