Up/Down Channel Mixer (Spatial Channel Converter) Architecture#

The Up/Down Channel Mixer (up_down_mixer, component UUID UUIDREG_STR_UP_DOWN_MIXER) is Sound Open Firmware’s specialized spatial audio format transformation engine. It provides deterministic, format-aware conversion between heterogenous multi-channel spatial layouts, bridging high-channel-count cinematic audio streams (such as 5.1 and 7.1 surround sound) and constrained endpoint transducers (such as stereo headphones, dual-speaker laptops, or mono smart speakers), as well as upmixing narrow streams across multi-transducer arrays.

Role of Spatial Channel Conversion in Audio DSP Architectures#

Modern audio architectures interact with a diverse spectrum of physical transducer configurations and multimedia formats. While streaming media, gaming titles, and broadcast audio are frequently authored and distributed in multi-channel surround formats (e.g., 5.1 or 7.1 surround sound), client playback endpoints vary drastically in their physical capabilities:

  • Mobile & Thin-Client Laptops: Dual micro-speakers (Stereo 2.0) or single speaker (Mono 1.0).

  • Headphones & Headsets: Binaural stereo playback requiring accurate spatial fold-down.

  • Soundbars & Subwoofers: 2.1, 3.0, or 3.1 channel configurations with discrete center dialogue and low-frequency effect (LFE) channels.

  • Automotive & Premium Home Theaters: 5.1, 7.1, or custom multi-speaker surrounds.

Without an autonomous, hardware-accelerated spatial channel converter in the audio DSP pipeline, the operating system must either discard non-rendered channels—destroying critical dialogue, ambient cues, and dynamic impact—or force software-based host CPU downmixing, increasing host power consumption and preventing low-power DSP offload.

Spatial Transformation Requirements#

  1. Downmixing (Surround Fold-Down): Collapsing multi-channel surround streams (such as 7.1, 5.1, 4.0, or 3.0) into stereo or mono endpoints. The conversion must preserve dialogue intelligibility (centered speech), low-frequency impacts (LFE), and directional surround panning without introducing acoustic phase cancellation, frequency discoloration, or digital clipping.

  2. Upmixing (Soundstage Expansion): Expanding narrow-channel content (mono or stereo music/voice streams) across multi-speaker arrays (such as 5.1 or 7.1 surround configurations). This provides immersive acoustic fill while preserving proper front left/right stereo imaging and preventing phantom center artifacts.

  3. Format & Container Bridging: Operating seamlessly across 16-bit (IPC4_DEPTH_16BIT) and 32-bit (IPC4_DEPTH_32BIT container with 24-bit or 32-bit valid data) audio streams, with support for arbitrary spatial slot assignments via dynamic 4-bit nibble channel mapping.

Mathematical Foundations: Matrix Downmixing, ITU-R BS.775 & Headroom Scaling#

Downmixing a multi-channel soundfield to a smaller speaker configuration requires matrix multiplication. Each output channel is synthesized as a linear combination of weighted input channels.

Standard Lo/Ro Surround Downmix Formulation#

Under the international standard ITU-R BS.775 for multichannel stereophonic sound systems, the conventional Left-only / Right-only (Lo/Ro) downmixing matrix collapses a 5.1 surround stream into stereo:

\[ \begin{align}\begin{aligned}L_{\text{out}} = c_L \cdot L + c_C \cdot C + c_R \cdot 0 + c_{Ls} \cdot Ls + c_{Rs} \cdot 0 + c_{\text{LFE}} \cdot \text{LFE}\\R_{\text{out}} = c_L \cdot 0 + c_C \cdot C + c_R \cdot R + c_{Ls} \cdot 0 + c_{Rs} \cdot Rs + c_{\text{LFE}} \cdot \text{LFE}\end{aligned}\end{align} \]

Under standard unscaled conditions, the acoustic weighting coefficients are:

  • Left & Right Front: Unity gain (\(c_L = c_R = 1.0 = 0.0\text{ dB}\)).

  • Center (Dialogue): Attenuated by \(-3.01\text{ dB}\) (\(c_C = 1/\sqrt{2} \approx 0.7071\)) so that acoustic power is equally split between left and right transducers.

  • Surrounds (Ls, Rs): Attenuated by \(-3.01\text{ dB}\) (\(c_{Ls} = c_{Rs} = 1/\sqrt{2} \approx 0.7071\)) to preserve ambient balance without overpowering front staging.

  • Low-Frequency Effects (LFE): Muted (\(c_{\text{LFE}} = 0.0\)), in strict accordance with ITU-R BS.775 to prevent severe low-frequency intermodulation distortion in small consumer speaker cones lacking dedicated subwoofers.

The Headroom Normalization Dilemma#

While the unscaled ITU-R BS.775 matrix preserves perceived acoustic loudness for typical un-correlated material, it poses a severe risk of catastrophic digital clipping in fixed-point embedded DSP architectures.

Consider a worst-case scenario where full-scale correlated audio peaks (\(0.0\text{ dBFS} = 1.0\)) occur simultaneously across the Left, Center, and Left Surround channels:

\[L_{\text{peak}} = 1.0 \cdot L + 0.7071 \cdot C + 0.7071 \cdot Ls = 1.0 + 0.7071 + 0.7071 = 2.4142 \quad (+7.65\text{ dBFS})\]

In integer PCM arithmetic (whether 16-bit or 32-bit), any value exceeding \(+1.0\) undergoes harsh saturation clipping, producing intolerable acoustic harmonic distortion.

Mathematical Derivation of Scaled Anti-Clipping Coefficients#

To eliminate digital clipping without requiring a dynamic range compressor (DRC) or high-latency limiter, SOF provides Headroom-Scaled Anti-Clipping Coefficients (k_scaled_lo_ro_downmix32bit).

The normalization scalar \(S\) is derived by taking the reciprocal of the maximum possible accumulated channel gain:

\[S = \frac{1}{1 + \frac{1}{\sqrt{2}} + \frac{1}{\sqrt{2}}} = \frac{1}{1 + \sqrt{2}} = \frac{1}{2.41421356} \approx 0.41421356 \quad (-7.655\text{ dB})\]

Applying this scaling factor across the matrix coefficients yields:

\[ \begin{align}\begin{aligned}c_L = 1.0 \times S = 0.41421356 \approx 0.414\\c_C = \frac{1}{\sqrt{2}} \times S = \frac{0.70710678}{2.41421356} \approx 0.2928932 \approx 0.293\\c_{Ls} = \frac{1}{\sqrt{2}} \times S = \frac{0.70710678}{2.41421356} \approx 0.2928932 \approx 0.293\end{aligned}\end{align} \]

Evaluating the worst-case coherent peak with these scaled coefficients:

\[L_{\text{peak, scaled}} = 0.41421356 + 0.2928932 + 0.2928932 = 1.00000000 \quad (0.0\text{ dBFS})\]

The sum of maximum positive gains is exactly unity (1.0). As a result, digital clipping is mathematically impossible, even when all surround channels drive simultaneous \(0\text{ dBFS}\) square waves.

Half-Scaled Coefficients for 3.0 / 3.1 Downmixing#

When downmixing 3.0 (Left, Center, Right) or 3.1 (Left, Center, Right, LFE) streams to stereo, surround channels are absent. Downscaling by \(1/(1+\sqrt{2})\) would needlessly penalize dynamic range. Instead, the Half-Scaled Anti-Clipping Coefficients (k_half_scaled_lo_ro_downmix32bit) normalize over front channels only:

\[ \begin{align}\begin{aligned}S_{3.0} = \frac{1}{1 + \frac{1}{\sqrt{2}}} = \frac{1}{1.70710678} \approx 0.5857864 \approx 0.586\\c_L = 1.0 \times S_{3.0} \approx 0.586, \quad c_C = \frac{1}{\sqrt{2}} \times S_{3.0} \approx 0.414\\L_{\text{peak, 3.0}} = 0.586 + 0.414 = 1.000 \quad (0.0\text{ dBFS})\end{aligned}\end{align} \]

Quatro-to-Mono Scaled Coefficients#

When collapsing 4-channel surround (Quatro: L, R, Ls, Rs) or 4.0 (L, C, R, Cs) into a single mono channel, all four active channels are summed:

\[ \begin{align}\begin{aligned}S_{\text{quatro}} = \frac{1}{2 + \sqrt{2}} = \frac{1}{3.41421356} \approx 0.2928932 \approx 0.293\\c_L = c_R = 0.293, \quad c_{Ls} = c_{Rs} = 0.207\\\text{Mono}_{\text{peak}} = 0.293 + 0.293 + 0.207 + 0.207 = 1.000 \quad (0.0\text{ dBFS})\end{aligned}\end{align} \]

Figure 210 illustrates the mathematical model comparing unscaled ITU-R BS.775 downmixing against headroom-scaled normalization, showing how coherent peaks are contained within the valid dynamic range.

Diagram of Mathematical Model of Surround Downmixing

Figure 169 Mathematical Model of Surround Downmixing: ITU-R BS.775 Summation & Headroom-Preserving Anti-Clipping Coefficients#

Fixed-Point Coefficient Precision & Representation#

Coefficients are pre-computed in header file src/audio/up_down_mixer/up_down_mixer_coef.h using integer macros to eliminate floating-point runtime division:

  • 32-Bit Fixed-Point (\(Q1.31\)):

    #define COMPUTE_COEFF_32BIT(counter, denominator) ((0x7fffffffULL * (counter)) / (denominator))
    
  • 16-Bit Fixed-Point (\(Q1.15\)):

    #define COMPUTE_COEFF_16BIT(counter, denominator) ((0x7fffULL * (counter)) / (denominator))
    

Table 18 summarizes the pre-computed coefficient sets implemented in SOF:

Table 19 SOF Up/Down Mixer Pre-Computed Coefficient Sets (up_down_mixer_coef.h)#

Coefficient Array

\(c_L\)

\(c_C\)

\(c_R\)

\(c_{Ls}\)

\(c_{Rs}\)

\(c_{\text{LFE}}\)

k_lo_ro_downmix32bit

1.000 (0x7FFFFFFF)

0.707 (0x5A827999)

1.000 (0x7FFFFFFF)

0.707 (0x5A827999)

0.707 (0x5A827999)

0.000 (0x00000000)

k_scaled_lo_ro_downmix32bit

0.414 (0x35000000)

0.293 (0x25800000)

0.414 (0x35000000)

0.293 (0x25800000)

0.293 (0x25800000)

0.000 (0x00000000)

k_half_scaled_lo_ro_downmix32bit

0.586 (0x4B000000)

0.414 (0x35000000)

0.586 (0x4B000000)

0.414 (0x35000000)

0.414 (0x35000000)

0.000 (0x00000000)

k_quatro_mono_scaled_lo_ro_downmix32bit

0.293 (0x25800000)

0.207 (0x1A800000)

0.293 (0x25800000)

0.207 (0x1A800000)

0.207 (0x1A800000)

0.000 (0x00000000)

Spatial Channel Layouts, 4-Bit Nibble Bitmasks & Dynamic Mapping#

Spatial audio processing components cannot assume fixed channel ordering in physical RAM. Hardware serial DAIs, soundcards, and third-party host software frequently permute channel slots (e.g., SMPTE [L, R, C, LFE, Ls, Rs] vs Film [L, C, R, Ls, Rs, LFE]).

The 32-Bit Nibble Map Format#

To achieve complete independence from physical memory ordering, SOF implements a packed 32-bit channel map (channel_map, defined in up_down_mixer_ipc4.h).

Each 32-bit integer encodes eight 4-bit nibbles. Each nibble directly specifies the spatial channel identity residing at that particular interleaved frame offset:

\[\text{channel\_map} = \sum_{i=0}^{7} \left( \text{ChannelIdentity}_i \ll (4 \times i) \right)\]

The spatial identities correspond to enum ipc4_channel_index:

  • CHANNEL_LEFT = 0x0

  • CHANNEL_CENTER = 0x1

  • CHANNEL_RIGHT = 0x2

  • CHANNEL_LEFT_SURROUND = 0x3

  • CHANNEL_RIGHT_SURROUND = 0x4

  • CHANNEL_LFE = 0x5

  • CHANNEL_LEFT_SIDE = 0x6

  • CHANNEL_RIGHT_SIDE = 0x7

  • Unused / invalid channel slots are padded with 0xF.

Channel Map Construction#

The inline helper create_channel_map() generates standardized bitmasks for all recognized IPC4 channel layouts:

static inline channel_map create_channel_map(enum ipc4_channel_config channel_config)
{
    switch (channel_config) {
    case IPC4_CHANNEL_CONFIG_MONO:
        return (0xFFFFFFF0 | CHANNEL_CENTER);
    case IPC4_CHANNEL_CONFIG_STEREO:
        return (0xFFFFFF00 | CHANNEL_LEFT | (CHANNEL_RIGHT << 4));
    case IPC4_CHANNEL_CONFIG_2_POINT_1:
        return (0xFFFFF000 | CHANNEL_LEFT | (CHANNEL_RIGHT << 4) | (CHANNEL_LFE << 8));
    case IPC4_CHANNEL_CONFIG_3_POINT_0:
        return (0xFFFFF000 | CHANNEL_LEFT | (CHANNEL_CENTER << 4) | (CHANNEL_RIGHT << 8));
    case IPC4_CHANNEL_CONFIG_3_POINT_1:
        return (0xFFFF0000 | CHANNEL_LEFT | (CHANNEL_CENTER << 4) | (CHANNEL_RIGHT << 8)
                           | (CHANNEL_LFE << 12));
    case IPC4_CHANNEL_CONFIG_QUATRO:
        return (0xFFFF0000 | CHANNEL_LEFT | (CHANNEL_RIGHT << 4)
                           | (CHANNEL_LEFT_SURROUND << 8) | (CHANNEL_RIGHT_SURROUND << 12));
    case IPC4_CHANNEL_CONFIG_4_POINT_0:
        return (0xFFFF0000 | CHANNEL_LEFT | (CHANNEL_CENTER << 4) | (CHANNEL_RIGHT << 8)
                           | (CHANNEL_CENTER_SURROUND << 12));
    case IPC4_CHANNEL_CONFIG_5_POINT_0:
        return (0xFFF00000 | CHANNEL_LEFT | (CHANNEL_CENTER << 4) | (CHANNEL_RIGHT << 8)
                           | (CHANNEL_LEFT_SURROUND << 12) | (CHANNEL_RIGHT_SURROUND << 16));
    case IPC4_CHANNEL_CONFIG_5_POINT_1:
        return (0xFF000000 | CHANNEL_LEFT | (CHANNEL_CENTER << 4) | (CHANNEL_RIGHT << 8)
                           | (CHANNEL_LEFT_SURROUND << 12) | (CHANNEL_RIGHT_SURROUND << 16)
                           | (CHANNEL_LFE << 20));
    case IPC4_CHANNEL_CONFIG_7_POINT_1:
        return (CHANNEL_LEFT | (CHANNEL_CENTER << 4) | (CHANNEL_RIGHT << 8)
                             | (CHANNEL_LEFT_SURROUND << 12) | (CHANNEL_RIGHT_SURROUND << 16)
                             | (CHANNEL_LFE << 20) | (CHANNEL_LEFT_SIDE << 24)
                             | (CHANNEL_RIGHT_SIDE << 28));
    default:
        return 0xFFFFFFFF;
    }
}

Dynamic Slot Resolution#

During algorithm initialization and execution, the helper get_channel_location() rapidly extracts the byte offset of any desired channel from the active map:

static inline uint8_t get_channel_location(const channel_map map,
                                           const enum ipc4_channel_index channel)
{
    uint8_t offset = 0xF;
    for (uint8_t i = 0; i < 8; i++) {
        if (((map >> (i * 4)) & 0xF) == (uint8_t)channel) {
            offset = i;
            break;
        }
    }
    return offset;
}

Figure 211 illustrates how a 5.1 channel map is packed into 4-bit nibbles and subsequently decoded into pointer strides for processing loops.

Diagram of Channel Mapping Architecture

Figure 170 Channel Mapping Architecture: 4-Bit Nibble Bitmask Encoding & Dynamic Spatial Slot Location#

Upmixing Architectures: Mono & Stereo Soundstage Expansion#

In addition to downmixing, the Up/Down Mixer component serves as SOF’s high-efficiency spatial upmixer. Upmixing expands narrow-channel audio across surround sound speaker topologies without incurring heavy latency or computational overhead.

Mono-to-5.1 Upmixing Engine#

When a single-channel mono speech or communication stream is delivered to a 5.1 surround sound endpoint (implemented in upmix32bit_1_to_5_1 and upmix16bit_1_to_5_1):

\[ \begin{align}\begin{aligned}L_{\text{out}}[i] = \text{Mono}_{\text{in}}[i]\\R_{\text{out}}[i] = \text{Mono}_{\text{in}}[i]\\Ls_{\text{out}}[i] = \text{Mono}_{\text{in}}[i]\\Rs_{\text{out}}[i] = \text{Mono}_{\text{in}}[i]\\C_{\text{out}}[i] = 0\\\text{LFE}_{\text{out}}[i] = 0\end{aligned}\end{align} \]
  • Acoustic Rationale: Replicating the signal into the left, right, and surround speakers creates an enveloping, diffuse soundfield without acoustic localization bias. The center channel is explicitly cleared to avoid acoustic point-source beaming, and LFE is cleared to prevent sub-bass transducer over-excursion.

  • 16-bit Conversion: For 16-bit input streams, samples are upshifted to 32-bit MSB alignment via the Tensilica intrinsic AE_MOVINT32_FROMINT16(in_ptr[i]) << 16.

Stereo 2.0-to-5.1 Upmixing Engine#

When conventional stereo audio is played over a 5.1 home theater or automotive soundstage (implemented in upmix32bit_2_0_to_5_1 and upmix16bit_2_0_to_5_1):

\[ \begin{align}\begin{aligned}L_{\text{out}}[i] = L_{\text{in}}[i], \quad R_{\text{out}}[i] = R_{\text{in}}[i]\\Ls_{\text{out}}[i] = L_{\text{in}}[i], \quad Rs_{\text{out}}[i] = R_{\text{in}}[i]\\C_{\text{out}}[i] = 0, \quad \text{LFE}_{\text{out}}[i] = 0\end{aligned}\end{align} \]
  • Side-Channel Fallback: If the target configuration uses side surround speakers (CHANNEL_LEFT_SIDE, CHANNEL_RIGHT_SIDE) rather than rear surrounds (CHANNEL_LEFT_SURROUND, CHANNEL_RIGHT_SURROUND), the engine automatically detects this condition and routes surround channels to the side slots.

Stereo 2.0-to-7.1 Upmixing Engine#

For 8-channel surround systems (upmix32bit_2_0_to_7_1), stereo audio is distributed to the front and rear soundstage while preserving zero-energy in the center, LFE, and side speakers:

\[ \begin{align}\begin{aligned}L_{\text{out}}[i] = L_{\text{in}}[i], \quad R_{\text{out}}[i] = R_{\text{in}}[i]\\Ls_{\text{out}}[i] = L_{\text{in}}[i], \quad Rs_{\text{out}}[i] = R_{\text{in}}[i]\\C_{\text{out}}[i] = 0, \quad \text{LFE}_{\text{out}}[i] = 0, \quad \text{LeftSide}_{\text{out}}[i] = 0, \quad \text{RightSide}_{\text{out}}[i] = 0\end{aligned}\end{align} \]

Zero-Latency Shift Copiers#

When the channel count remains unchanged but container widths must be upgraded from 16-bit to 32-bit MSB alignment, the Up/Down Mixer executes optimized shift copiers (shiftcopy16bit_mono, shiftcopy16bit_stereo, shiftcopy32bit_mono, shiftcopy32bit_stereo). These provide direct linear memory copy operations with single-cycle sign extension and zero algorithmic latency.

Figure 212 illustrates the dataflow for Mono-to-5.1, Stereo-to-5.1, and Stereo-to-7.1 upmixing paths.

Diagram of Surround Upmixing Dataflow

Figure 171 Surround Upmixing Dataflow: Mono/Stereo to 5.1 and 7.1 Channel Soundstage Expansion#

Cadence Tensilica HiFi3/HiFi4 SIMD Vector Acceleration#

Audio downmixing algorithms are fundamentally bound by memory bandwidth and multiply-accumulate (MAC) pipeline efficiency. When collapsing 6 or 8 channels of 32-bit audio at 48 kHz or 96 kHz, scalar execution would consume excessive CPU cycles and drain battery power.

SOF implements highly optimized assembly pipelines in src/audio/up_down_mixer/up_down_mixer_hifi3.c, targeting Cadence Tensilica HiFi3 and HiFi4 DSP architectures.

Mitigating Register Pressure: The 8-Register Constraint#

The Tensilica HiFi3 architecture provides eight 32-bit/48-bit audio vector registers (the AE_P register file: p0 through p7).

A naive implementation of a 6-channel 5.1 downmixing loop requires:

  • 6 distinct downmix coefficients (\(c_L, c_C, c_R, c_{Ls}, c_{Rs}, c_{\text{LFE}}\)).

  • 6 concurrent input sample channels.

  • 2 output accumulator registers (\(L_{\text{out}}, R_{\text{out}}\)).

This would demand 14 simultaneous registers, causing severe register spilling to stack memory and destroying inner loop throughput.

To overcome this bottleneck, SOF implements an innovative Vector Coefficient Packing technique:

/* Load 32-bit coefficients */
ae_int32x2 P_coefficient_left = AE_L32_X((ae_int32 *)cd->downmix_coefficients, CHANNEL_LEFT << 2);
ae_int32x2 P_coefficient_center = AE_L32_X((ae_int32 *)cd->downmix_coefficients, CHANNEL_CENTER << 2);
ae_int32x2 P_coefficient_right = AE_L32_X((ae_int32 *)cd->downmix_coefficients, CHANNEL_RIGHT << 2);
ae_int32x2 P_coefficient_left_surround = AE_L32_X((ae_int32 *)cd->downmix_coefficients, CHANNEL_LEFT_SURROUND << 2);
ae_int32x2 P_coefficient_right_surround = AE_L32_X((ae_int32 *)cd->downmix_coefficients, CHANNEL_RIGHT_SURROUND << 2);
ae_int32x2 P_coefficient_lfe = AE_L32_X((ae_int32 *)cd->downmix_coefficients, CHANNEL_LFE << 2);

/* Combine 6 coefficients into 3 dual-vector registers using AE_SEL32_LL */
P_coefficient_left_right = AE_SEL32_LL(P_coefficient_left, P_coefficient_right);
P_coefficient_left_s_right_s = AE_SEL32_LL(P_coefficient_left_surround, P_coefficient_right_surround);
P_coefficient_center_lfe = AE_SEL32_LL(P_coefficient_center, P_coefficient_lfe);

By packing pairs of 32-bit coefficients into single dual-element ae_int32x2 registers, the entire coefficient matrix is held in only three registers, liberating five registers for streaming sample buffers and 64-bit accumulators!

Pipelined Inner Loop Execution (3.1 Downmix Example)#

The inner processing loop for 3.1-to-stereo downmixing demonstrates the pipelined SIMD execution:

while (input_left < end_input_left) {
    ae_f64 Q_tmp_left;
    ae_f64 Q_tmp_right;

    /* Load Left and multiply by Left/Right packed coefficient */
    AE_L32_IP(P_input_left, input_left, 4 * sizeof(ae_int32));
    Q_tmp_left = AE_MULF32S_LH(P_input_left, P_coefficient_left_right);

    /* Load Center and multiply-accumulate to Left, multiply to Right */
    AE_L32_IP(P_input_center, input_center, 4 * sizeof(ae_int32));
    AE_MULAF32S_LH(Q_tmp_left, P_input_center, P_coefficient_center_lfe);
    Q_tmp_right = AE_MULF32S_LH(P_input_center, P_coefficient_center_lfe);

    /* Load Right and multiply-accumulate to Right */
    AE_L32_IP(P_input_right, input_right, 4 * sizeof(ae_int32));
    AE_MULAF32S_LL(Q_tmp_right, P_input_right, P_coefficient_left_right);

    /* Load LFE and multiply-accumulate to both Left and Right */
    AE_L32_IP(P_input_lfe, input_lfe, 4 * sizeof(ae_int32));
    AE_MULAF32S_LL(Q_tmp_left, P_input_lfe, P_coefficient_center_lfe);
    AE_MULAF32S_LL(Q_tmp_right, P_input_lfe, P_coefficient_center_lfe);

    /* Perform 64-to-32-bit symmetric rounding and saturation */
    P_output_left = AE_ROUND32F64SSYM(Q_tmp_left);
    P_output_right = AE_ROUND32F64SSYM(Q_tmp_right);

    /* Store to interleaved stereo output buffer */
    AE_S32_L_IP(P_output_left, output_left, 2 * sizeof(ae_int32));
    AE_S32_L_IP(P_output_right, output_right, 2 * sizeof(ae_int32));
}

Key HiFi3 SIMD Primitives Used: * AE_L32_IP: Aligned 32-bit vector load with auto-incrementing stride pointer. * AE_MULF32S_LH: 32x32-bit fractional multiplication extracting the high 32 bits into a 64-bit accumulator. * AE_MULAF32S_LL / AE_MULAF32S_LH: 32x32-bit fractional multiply-accumulate. * AE_ROUND32F64SSYM: High-precision symmetric rounding converting 64-bit accumulators back to 32-bit words with automatic clamping. * AE_S32_L_IP: Aligned 32-bit vector store with auto-incrementing stride pointer.

Figure 213 illustrates the register packing and pipelined multiply-accumulate execution on Cadence HiFi3 hardware.

Diagram of Tensilica HiFi3 SIMD Vector Pipelining

Figure 172 Tensilica HiFi3 SIMD Vector Pipelining: Register-Packed Coefficients & 64-Bit Symmetric MAC Execution#

IPC4 Interface, Module Configuration & Intel Architecture Integration#

The Up/Down Mixer is authored strictly according to the modern SOF IPC4 Module Adapter API, enabling dynamic pipeline deployment, firmware-level relocatable execution (LLEXT), and tight runtime control.

Configuration Container (ipc4_up_down_mixer_module_cfg)#

The configuration payload is transferred from host userspace or ALSA topology via struct ipc4_up_down_mixer_module_cfg (defined in up_down_mixer_ipc4.h):

struct ipc4_up_down_mixer_module_cfg {
    struct ipc4_base_module_cfg base_cfg;

    /* Output Channel Configuration (Mono, Stereo, 5.1, 7.1) */
    enum ipc4_channel_config out_channel_config;

    /* Selects which coefficients are used */
    enum up_down_mix_coeff_select coefficients_select;

    /* Optional custom coefficients array (8 elements) */
    int32_t coefficients[UP_DOWN_MIX_COEFFS_LENGTH];

    /* Optional custom channel map for non-standard layouts */
    channel_map channel_map;
} __packed __aligned(8);

Coefficient Selection Modes#

The parameter coefficients_select governs how mixing coefficients are resolved:

  1. DEFAULT_COEFFICIENTS (0): SOF automatically inspects the input audio format (base_cfg.audio_fmt.ch_cfg) and output channel layout (out_channel_config) and assigns the optimal pre-computed table:

    • Mono, Stereo, and Dual Mono inputs \(\to\) k_lo_ro_downmix32bit.

    • 3.0 and 3.1 inputs \(\to\) k_half_scaled_lo_ro_downmix32bit.

    • Quatro to Mono \(\to\) k_quatro_mono_scaled_lo_ro_downmix32bit.

    • 4.0, 5.0, 5.1, and 7.1 inputs \(\to\) k_scaled_lo_ro_downmix32bit.

  2. CUSTOM_COEFFICIENTS (1): Overrides default coefficients with the 8-element user-supplied array in coefficients[], formatted in \(Q1.31\).

  3. DEFAULT_COEFFICIENTS_WITH_CHANNEL_MAP (2): Uses standard pre-computed coefficients, but overrides the channel indexing with the user-provided 32-bit channel_map.

  4. CUSTOM_COEFFICIENTS_WITH_CHANNEL_MAP (3): Employs both custom coefficients and a custom channel map for proprietary hardware speaker topologies.

Intel Hardware Platform Profiles (up_down_mixer.toml)#

The deployment parameters across modern Intel hardware generations (Meteor Lake, Lunar Lake, Arrow Lake, Panther Lake ACE 3.0 / ACE 4.0) are maintained in up_down_mixer.toml:

Table 20 Up/Down Mixer Platform Performance Profiles (up_down_mixer.toml)#

Platform Architecture

DSP Engine

Cycles Per Chunk (CPC)

Input Buffer Size (IBS)

Output Buffer Size (OBS)

Meteor Lake (MTL)

ACE 1.5 (cAVS 2.5+)

2,468 – 5,440

192 – 1,536 bytes

192 – 1,152 bytes

Lunar Lake (LNL)

ACE 2.0

3,604 – 7,792

192 – 1,536 bytes

192 – 1,536 bytes

Panther Lake (PTL)

ACE 3.0 / ACE 4.0

4,355 – 9,177

192 – 1,536 bytes

192 – 1,536 bytes

Figure 214 depicts the IPC4 configuration lifecycle and coefficient selection engine.

Diagram of IPC4 Configuration Lifecycle

Figure 173 IPC4 Configuration Lifecycle & Coefficient Selection Engine (Default vs Custom Matrices)#

ALSA Topology Integration, Routing Pipelines & Verification Runbook#

The Up/Down Channel Mixer is declared in ALSA Topology 2 files as an autonomous processing widget.

Topology 2 Widget Declaration#

In topology definitions (e.g., tools/topology/topology2/cavs/up_down_mixer.conf), the module is instantiated using its standard configuration schema:

Object.Widget.up_down_mixer."0" {
    index 1
    type "up_down_mixer"
    no_pm 1
    core 0

    # UUID binding matching UUIDREG_STR_UP_DOWN_MIXER
    uuid "3a:4b:5c:6d:7e:8f:9a:bc:de:f0:12:34:56:78:9a:bc"

    # Audio format configuration
    format s32le
    channels 6
    rate 48000
}

End-to-End Multi-Channel Playback Pipeline#

Figure 215 illustrates a complete real-world surround sound playback pipeline in Sound Open Firmware, routing a 5.1 cinematic audio stream to a stereo headphone or dual-speaker DAC.

Diagram of End-to-End Surround Media Playback Pipeline

Figure 174 End-to-End Surround Media Playback Pipeline: 5.1 Downmixing to Stereo Headphone & Speaker DAC#

Automated Audio Quality Verification Runbook#

To verify spatial downmixing performance, channel isolation, and clipping immunity on target hardware (such as Tiger Lake, Arrow Lake, or Panther Lake DUTs):

  1. Deploy 5.1 Downmix Topology: Deploy a firmware pipeline containing the Up/Down Mixer bound between host playback and stereo DAI endpoints:

    # Configure ALSA state with 5.1 downmixing enabled
    alsactl -f /var/lib/alsa/asound.state restore
    
  2. Generate Multi-Channel Orthogonal Test Tones: Synthesize a 6-channel 48 kHz 32-bit WAV file containing isolated 997 Hz sinusoids sequentially activated across individual channels:

    • 0.0s to 1.0s: Left Channel Only (\(-6\text{ dBFS}\))

    • 1.0s to 2.0s: Center Channel Only (\(-6\text{ dBFS}\))

    • 2.0s to 3.0s: Right Channel Only (\(-6\text{ dBFS}\))

    • 3.0s to 4.0s: Left Surround Only (\(-6\text{ dBFS}\))

    • 4.0s to 5.0s: Right Surround Only (\(-6\text{ dBFS}\))

    • 5.0s to 6.0s: LFE Subwoofer Only (\(-6\text{ dBFS}\))

  3. Playback and Hardware Loopback Capture: Stream the 6-channel WAV through SOF while capturing the stereo DAI output via an external hardware bridge (e.g., ESP32-P4 or Teensy 4.1):

    # Playback 6-channel stream on DUT
    aplay -Dhw:0,0 -c 6 -r 48000 -f S32_LE /tmp/multichannel_test.wav &
    
    # Capture stereo fold-down stream on external loopback bridge
    arecord -Dhw:CARD=Bridge,DEV=0 -c 2 -r 48000 -f S32_LE -d 7 /tmp/downmix_capture.wav
    
  4. Verify Attenuation & Channel Isolation Metrics: Execute automated Python spectral analysis on /tmp/downmix_capture.wav:

    • Left/Right Isolation: When Left is active, Right channel leakage must be \(< -80\text{ dBFS}\).

    • Center Channel Split: Center energy must appear in both Left and Right output channels with equal power (\(\pm 0.1\text{ dB}\) matching).

    • LFE Attenuation: When LFE is active, output level must remain at the noise floor (\(< -90\text{ dBFS}\)).

    • Anti-Clipping Headroom: Play a coherent \(0\text{ dBFS}\) burst across all channels simultaneously; confirm that captured stereo output does not exceed \(0.0\text{ dBFS}\) and exhibits \(\text{THD+N} < -95\text{ dB}\).