Skip to content

audio: math: add ARM Cortex-M DSP and SIMD optimizations - #11301

Open
lgirdwood wants to merge 13 commits into
thesofproject:mainfrom
lgirdwood:topic/arm-simd
Open

lgirdwood wants to merge 13 commits into
thesofproject:mainfrom
lgirdwood:topic/arm-simd

Conversation

@lgirdwood

Copy link
Copy Markdown
Member

Description

This series introduces architecture-accelerated DSP and SIMD optimizations for ARM Cortex-M cores (CONFIG_ARM, ARMv7E-M / Cortex-M7 / Cortex-M4 DSP instruction set).

Previously, these optimizations were developed within board-bringup branches (such as feature/teensy41-sof-port and feature/rp2350-sof-port) alongside board definitions, static topologies, and USB classes. To facilitate focused review and upstream merging, this series isolates the generic audio processing and math kernels into 13 clean, atomic, module-by-module commits rebased on upstream main.

All board, platform, and application-specific code has been eliminated. The optimizations leverage portable Cortex-M DSP intrinsics and inline assembly primitives (such as single-cycle SMLAL, SMULBB/SMULTT, SMLAD/SMLALD, SMMULR, PKHBT, QADD16, QADD, CLZ, and branchless SSAT), with complete generic C fallback implementations provided for host compilation and non-ARM targets.


Module-by-Module Summary

  1. include: common: introduce ARM SIMD configuration macros

    • Defines SOF_CONFIG_ARM_SIMD(component), SOF_USE_ARM_SIMD(component), SOF_CONFIG_ARM_FPU(component), and SOF_USE_ARM_FPU(component) mirroring SOF_CONFIG_HIFI / SOF_USE_HIFI for compile-time optimization selection.
  2. include: audio: add ARM Cortex-M DSP intrinsics and inline assembly primitives

    • Adds src/include/sof/audio/arm_simd.h providing portable Cortex-M DSP intrinsics and inline assembly:
      • Branchless saturation: arm_sat_s16, arm_sat_s24, arm_sat_q31 (SSAT)
      • Saturating arithmetic: arm_qadd16, arm_qsub16, arm_qadd, arm_qsub
      • 16-bit and 32-bit multipliers: arm_smulbb, arm_smultt, arm_smmulr
      • Multiply-accumulate: arm_smlal, arm_smlad, arm_smlald, arm_smlawb, arm_smlawt
      • Halfword packing and extension: arm_pkhbt, arm_sxth
      • Leading zero count: arm_clz
      • Generic C fallback implementations when building for non-ARM or host.
  3. math: iir: add ARM Cortex-M DSP cascaded DF1 and DF2T biquad filtering

    • Implements Direct Form 1 (iir_df1_arm.c) and Transposed Direct Form 2 (iir_df2t_arm.c) biquads.
    • Single-cycle 5-term MAC throughput using SMLAL 64-bit accumulators.
    • Branchless saturation with ARM SSAT (arm_sat_q31).
    • Specialized 4th order (2 biquads in series) unrolled kernel.
    • Dispatch headers iir_df1_arm.h and iir_df2t_arm.h for fast inlining. Adds CONFIG_FILTER_ARM_SIMD.
  4. math: fir: add ARM Cortex-M DSP unrolled FIR filtering

    • Implements unrolled FIR filtering in fir_arm.c.
    • Single-cycle SMLAL 64-bit MAC accumulator with 4-tap unrolled loop for fir_32x16.
    • Dual-sample parallel filtering kernel fir_32x16_2x.
    • Guards generic fallback definitions in fir_generic.h.
  5. audio: volume: add ARM Cortex-M DSP packed vector volume scaling

    • Implements volume_arm.c and volume_arm_with_peakvol.c:
      • Packed S16 dual halfword unpack/multiply/saturate/pack using SMULBB, SMULTT, arm_sat_s16, and PKHBT.
      • Fast S24 and S32 scaling using SMMULR (arm_smmulr).
      • Single-precision floating point processing with hardware FPU.
      • Optimized peak volume tracking in volume_arm_with_peakvol.c. Adds CONFIG_VOLUME_ARM_SIMD.
  6. audio: eq_iir: add ARM Cortex-M DSP block-accelerated processing

    • Implements block processing (EQ_IIR_BLOCK_SIZE = 64) keeping filter delay states (y_n2, y_n1, x_n2, x_n1) and coefficients in registers across each block, eliminating ~98% of RAM load/store traffic.
    • Inlines biquad loop eliminating external call dispatches.
    • Fast branchless saturation for S16, S24, and S32 formats via SSAT. Adds CONFIG_EQ_IIR_ARM_SIMD.
  7. audio: drc: add ARM Cortex-M DSP fast polynomial math and compression

    • Implements drc_math_arm.c with Horner's polynomial evaluations for: log10_fixed, drc_lin2db_fixed, drc_log_fixed, drc_asin_fixed, drc_inv_fixed leveraging ARM CLZ and branchless saturation.
    • Fast knee_curveK, volume gain, and envelope tracking.
    • Implements drc_arm.c with unrolled output compression. Adds CONFIG_DRC_ARM_SIMD.
  8. audio: eq_fir: add ARM Cortex-M DSP parallel 2x filtering

    • Implements eq_fir_arm.c providing eq_fir_2x_s16, eq_fir_2x_s24, and eq_fir_2x_s32 accelerating 2x parallel filtering.
    • Routes to 2x processing when SOF_USE_ARM_SIMD(FILTER) is enabled.
    • Branchless saturation with arm_sat_s16 and sat_int24.
  9. audio: mixer: add ARM Cortex-M DSP saturating stream summation

    • Implements mixer_arm.c:
      • Packed dual 16-bit saturating addition using arm_qadd16.
      • 32-bit saturating addition using arm_qadd.
      • Branchless 24-bit saturation via arm_sat_s24.
      • Single-precision floating point mixing with FPU vector adds. Adds CONFIG_MIXER_ARM_SIMD.
  10. audio: mixin_mixout: add ARM Cortex-M DSP channel mixing and scaling

    • Implements mixin_mixout_arm.c:
      • Fast channel mixing and gain scaling with saturating adds (arm_qadd16, arm_qadd, arm_sat_s24).
      • 32x32 hardware multiply with 64-bit accumulators.
      • Float vector processing using hardware FPU.
    • Guards generic fallback implementations in mixin_mixout_generic.c. Adds CONFIG_MIXIN_MIXOUT_ARM_SIMD.
  11. audio: dcblock: add ARM Cortex-M DSP filter acceleration

    • Implements dcblock_arm.c:
      • Accelerates single-pole highpass filter using 64-bit MAC and branchless arm_sat_q31, arm_sat_s16, and arm_sat_s24.
      • Hardware FPU accelerated float processing (dcblock_float_arm).
    • Guards generic fallback implementations in dcblock_generic.c. Adds CONFIG_DCBLOCK_ARM_SIMD.
  12. audio: level_multiplier: add ARM Cortex-M DSP gain scaling

    • Implements level_multiplier-arm.c:
      • S16 unpack, multiply, saturate, and pack via SMULBB/SMULTT and PKHBT.
      • Fast S24 and S32 scaling with arm_smmulr and arm_sat_q31.
      • Hardware float vector gain scaling.
    • Guards generic fallback implementations in level_multiplier-generic.c.
  13. audio: pcm_converter: add ARM Cortex-M DSP format conversion routines

    • Adds CONFIG_FORMAT_CONVERT_ARM_SIMD in audio Kconfig and defines PCM_CONVERTER_ARM_SIMD in pcm_converter.h.
    • Implements pcm_converter_arm.c:
      • Fast integer format conversions (S16, S24, S32) using SXTH, PKHBT, SSAT, and sign extension.
      • Float-to-integer and integer-to-float conversions with hardware FPU.
      • Linear and circular buffer conversion routines with IPC3 and IPC4 dispatch tables (pcm_func_map, pcm_func_vc_map).

Verification

  • Toolchain: Built with standard upstream Zephyr SDK GCC (arm-zephyr-eabi).
  • Target Architecture: ARM Cortex-M7 (NXP i.MX RT1062) and Cortex-M33 (Raspberry Pi RP2350).
  • Hardware: Validated on physical PJRC Teensy 4.1 hardware audio bridges with automated S/PDIF hardware loopback testing (1000 Hz sine @ 48 kHz, 140.81 dB SNR, 0 dropped frames).

Copilot AI balanced review requested due to automatic review settings October 13, 2026 14:11

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

The optimized paths contain build failures, unsupported dispatch gaps, arithmetic errors, and potential buffer overflow.

10 open findings
What changed in this PR

Adds ARM Cortex-M DSP/SIMD implementations for audio processing and fixed-point math, with Kconfig and build-system dispatch.

Changes:

  • Adds ARM DSP primitives and optimized FIR/IIR kernels.
  • Accelerates volume, EQ, DRC, mixer, DC-block, level-multiplier, and PCM conversion paths.
  • Adds ARM-specific configuration and source selection.
File Description
src/​math/​Kconfig.simd Adds ARM filter selection.
src/​math/​Kconfig Adds ARM IIR/FIR configuration.
src/​math/​iir_df2t_arm.c Implements ARM DF2T filtering.
src/​math/​iir_df1_arm.c Implements ARM DF1 filtering.
src/​math/​fir_arm.c Implements ARM FIR kernels.
src/​math/​CMakeLists.txt Builds ARM math sources.
src/​include/​sof/​math/​iir_df2t.h Dispatches ARM DF2T helpers.
src/​include/​sof/​math/​iir_df2t_arm.h Adds ARM DF2T format wrappers.
src/​include/​sof/​math/​iir_df1.h Dispatches ARM DF1 helpers.
src/​include/​sof/​math/​iir_df1_arm.h Adds ARM DF1 format wrappers.
src/​include/​sof/​math/​fir_generic.h Exposes FIR declarations for ARM.
src/​include/​sof/​common.h Adds ARM optimization macros.
src/​include/​sof/​audio/​pcm_converter.h Selects ARM PCM conversion.
src/​include/​sof/​audio/​arm_simd.h Adds ARM DSP primitives.
src/​audio/​volume/​volume_arm.c Adds ARM volume scaling.
src/​audio/​volume/​volume_arm_with_peakvol.c Adds ARM scaling with metering.
src/​audio/​volume/​Kconfig.simd Configures ARM volume SIMD.
src/​audio/​volume/​CMakeLists.txt Selects ARM volume sources.
src/​audio/​pcm_converter/​pcm_converter_arm.c Adds ARM PCM conversions.
src/​audio/​pcm_converter/​CMakeLists.txt Builds ARM PCM converter.
src/​audio/​mixin_mixout/​mixin_mixout_generic.c Excludes generic ARM path.
src/​audio/​mixin_mixout/​mixin_mixout_arm.c Adds ARM mixin/mixout processing.
src/​audio/​mixin_mixout/​Kconfig Configures ARM mixin/mixout.
src/​audio/​mixin_mixout/​CMakeLists.txt Builds ARM mixin/mixout.
src/​audio/​mixer/​mixer.h Selects ARM mixer implementation.
src/​audio/​mixer/​mixer_arm.c Adds ARM mixer kernels.
src/​audio/​mixer/​Kconfig Configures ARM mixer.
src/​audio/​mixer/​CMakeLists.txt Builds ARM mixer.
src/​audio/​level_multiplier/​level_multiplier-generic.c Excludes generic ARM path.
src/​audio/​level_multiplier/​level_multiplier-arm.c Adds ARM gain scaling.
src/​audio/​level_multiplier/​CMakeLists.txt Builds ARM level multiplier.
src/​audio/​Kconfig Configures ARM format conversion.
src/​audio/​eq_iir/​Kconfig.simd Configures ARM EQ IIR.
src/​audio/​eq_iir/​Kconfig Includes SIMD configuration.
src/​audio/​eq_iir/​eq_iir_arm.c Adds block-based ARM EQ IIR.
src/​audio/​eq_iir/​CMakeLists.txt Selects ARM EQ IIR.
src/​audio/​eq_fir/​eq_fir.h Enables ARM FIR dispatch.
src/​audio/​eq_fir/​eq_fir_generic.c Retains shared ARM processing.
src/​audio/​eq_fir/​eq_fir_arm.c Adds paired ARM EQ FIR processing.
src/​audio/​eq_fir/​CMakeLists.txt Builds ARM EQ FIR.
src/​audio/​drc/​Kconfig.simd Configures ARM DRC.
src/​audio/​drc/​drc_math.h Adds ARM DRC math helpers.
src/​audio/​drc/​drc_math_arm.c Implements ARM fixed-point DRC math.
src/​audio/​drc/​drc_generic.c Connects shared ARM DRC flow.
src/​audio/​drc/​drc_arm.c Adds ARM compression kernels.
src/​audio/​drc/​CMakeLists.txt Builds ARM DRC sources.
src/​audio/​dcblock/​Kconfig Configures ARM DC blocking.
src/​audio/​dcblock/​dcblock_generic.c Excludes generic ARM path.
src/​audio/​dcblock/​dcblock_arm.c Adds ARM DC-block processing.
src/​audio/​dcblock/​CMakeLists.txt Builds ARM DC-block source.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/audio/eq_iir/eq_iir_arm.c Outdated
Comment thread src/audio/eq_iir/eq_iir_arm.c Outdated
Comment thread src/audio/level_multiplier/level_multiplier-arm.c Outdated
Comment thread src/audio/volume/volume_arm.c Outdated
Comment thread src/audio/volume/volume_arm_with_peakvol.c
Comment thread src/include/sof/audio/arm_simd.h Outdated
Comment thread src/include/sof/audio/arm_simd.h
Comment thread src/math/fir_arm.c Outdated
Comment thread src/audio/drc/drc_arm.c
Comment thread src/audio/pcm_converter/pcm_converter_arm.c
Define SOF_CONFIG_ARM_SIMD, SOF_USE_ARM_SIMD, SOF_CONFIG_ARM_FPU, and
SOF_USE_ARM_FPU macros in common.h mirroring SOF_CONFIG_HIFI and
SOF_USE_HIFI to allow compile-time selection of architecture-accelerated
ARM Cortex-M DSP SIMD and FPU processing kernels across audio modules and
math libraries.

Signed-off-by: Liam Girdwood <lgirdwood@gmail.com>
…rimitives

Add src/include/sof/audio/arm_simd.h providing portable Cortex-M DSP
intrinsics and inline assembly primitives:
- Branchless saturation: arm_sat_s16, arm_sat_s24, arm_sat_q31 (SSAT)
- Saturating arithmetic: arm_qadd16, arm_qsub16, arm_qadd, arm_qsub
- 16-bit and 32-bit multipliers: arm_smulbb, arm_smultt, arm_smmulr
- Multiply-accumulate: arm_smlal, arm_smlad, arm_smlald, arm_smlawb, arm_smlawt
- Halfword packing and extension: arm_pkhbt, arm_sxth
- Leading zero count: arm_clz
- Generic C fallback implementations when building for non-ARM or host

Signed-off-by: Liam Girdwood <lgirdwood@gmail.com>
Implement Direct Form 1 (DF1) and Transposed Direct Form 2 (DF2T)
biquad filtering kernels optimized for ARM Cortex-M DSP architectures:
- Single-cycle 5-term MAC throughput using SMLAL 64-bit accumulators.
- Branchless saturation with ARM SSAT (arm_sat_q31).
- Specialized 4th order (2 biquads in series) unrolled kernel.
- Dispatch headers iir_df1_arm.h and iir_df2t_arm.h for fast inlining.
- Add CONFIG_FILTER_ARM_SIMD choice option in math Kconfig and Kconfig.simd.

Signed-off-by: Liam Girdwood <lgirdwood@gmail.com>
@lgirdwood

Copy link
Copy Markdown
Member Author

PR Update & Review Comments Resolution

The series has been rebased and updated on branch topic/arm-simd. All 10 review findings have been resolved across the individual commits:

  1. arm_simd.h Inline Assembly & Fallbacks:

    • Gated Cortex-M DSP assembly behind #if (defined(__arm__) || defined(__thumb__) || defined(CONFIG_ARM)) && defined(__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1).
    • Added portable C fallbacks for arm_qsub16, arm_qsub, arm_smlawb, and arm_smlawt.
    • Updated arm_pkhbt under GCC to a statement expression macro to ensure constant propagation for the immediate shift constraint ("I") at all optimization levels.
  2. fir_arm.c Delay Line Bounds:

    • Updated fir_32x16_2x to wrap circular delay line indexing for the second sample independently (fir->rwi == length ? 0 : fir->rwi), preventing out-of-bounds writes when rwi == length - 1.
  3. volume_arm.c & volume_arm_with_peakvol.c Precision & Clamping:

    • Widened Q8.16 intermediate multiplication to 64-bit (int64_t)x * vol with 16-bit saturation in vol_mult_s16.
    • Clamped vol_mult_s24 output to 24-bit range with arm_sat_s24.
    • Included <math.h> for fabsf() in volume_arm_with_peakvol.c.
  4. eq_iir_arm.c Headroom, Cleanup, & Unused Helpers:

    • Widened parallel accumulation buffers to int64_t accum[EQ_IIR_BLOCK_SIZE] in S16, S24, and S32 block processing loops and applied Q_SHIFT_RND on widened accumulators prior to saturation.
    • Removed unused/unsupported #if CONFIG_FORMAT_FLOAT routines and float delay line cleanup.
    • Guarded iir_df1_process_block_s16/s24/s32 with CONFIG_FORMAT_S16LE/S24LE/S32LE to avoid unused function warnings when formats are unselected.
  5. drc_arm.c Peak Detector Overflow:

    • Protected against signed integer overflow on INT32_MIN negation in S16 and S32 peak detector loops.
  6. level_multiplier-arm.c Function Signatures:

    • Changed int x_size, y_size to size_t x_size, y_size across all processing routines to match level_multiplier_process function pointer prototypes.
  7. pcm_converter_arm.c Conversion Table Coverage:

    • Added complete set of format conversion routines (U8, A-law, mu-law, S24_3LE, S24_4LE_MSB, S16_C32_AND_S24_C32, S24_C24_AND_S24_C32) and populated entries in both pcm_func_map and pcm_func_vc_map.

Verification:
All 10 ARM SIMD source files compile cleanly with -Wall -Werror under arm-zephyr-eabi-gcc for both Cortex-M7 (DSP SIMD path) and Cortex-M0 (pure C fallback path) across both -O0 and -O2.

@intel-sofci

intel-sofci commented Oct 13, 2026 •

Copy link
Copy Markdown

PR 11301: test results

Run date: 2026-10-13 15:58 UTC

Tested commit: 2d8d2d83f4c9cf457abed5fe6a388fc763cbfba6

mtl pass rate lnl pass rate ptl pass rate wcl pass rate nvl pass rate

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Comment on lines +890 to +897
for (i = 0; i < n; i += 2) {
*dst = (*src >> 8) & 0xFFFF;
dst++;
*dst = ((*src & 0xFF) << 8) | ((*(src + 1) >> 16) & 0xFF);
dst++;
*dst = *(src + 1) & 0xFFFF;
dst++;
src += 2;

@lgirdwood lgirdwood Oct 13, 2026 •

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.

Fixed. Changed the loop condition in pcm_convert_s24_c32_to_s24_c24_link_gtw to i + 1 < n so only complete pairs are processed by the two-sample packer. Moved the single odd trailing sample handler inside each circular-buffer chunk (if (i < n)), and removed the invalid post-loop if (i > n) check.

Comment thread src/math/fir_arm.c Outdated
Comment on lines +118 to +125
uint32_t c01 = *(const uint32_t *)coef;
uint32_t c23 = *(const uint32_t *)(coef + 2);
coef += 4;

int16_t c0 = (int16_t)c01;
int16_t c1 = (int16_t)(c01 >> 16);
int16_t c2 = (int16_t)c23;
int16_t c3 = (int16_t)(c23 >> 16);

@lgirdwood lgirdwood Oct 13, 2026 •

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.

Fixed. Replaced 32-bit pointer casts and dereferences with direct 16-bit coefficient loads (c0 = coef[0]; c1 = coef[1]; c2 = coef[2]; c3 = coef[3];) in both circular segments of fir_32x16 and fir_32x16_2x, avoiding unaligned memory accesses and strict-aliasing violations.

n = MIN(n, nmax);

for (i = 0; i < n; i++) {
dst[i] = arm_sat_q31((int64_t)(src[i] * scale));

@lgirdwood lgirdwood Oct 13, 2026 •

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.

Fixed. Added explicit float range checks against INT32_MAX (val >= 2147483647.0f) and INT32_MIN (val <= -2147483648.0f), mapped NaN to 0, and applied matching protections across float-to-integer converters in pcm_converter_arm.c before integer conversion.

Comment on lines +200 to +201
static void vol_s24_to_s24(struct processing_module *mod, struct cir_buf_source *source,
struct cir_buf_sink *sink, uint32_t frames, uint32_t attenuation)

@lgirdwood lgirdwood Oct 13, 2026 •

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.

Fixed. Introduced sat_peak_shift() helper with wide 64-bit shifting and saturation to INT32_MAX. Applied sat_peak_shift(peak, attenuation + PEAK_24S_32C_ADJUST) to S24 peak meters, and sat_peak_shift(peak, attenuation) to S32 and float peak meters across both active volume scaling and passthrough loops.

Comment on lines +388 to +391
peak_l = MAX(abs(x0), peak_l);
peak_r = MAX(abs(x1), peak_r);
peak_l = MAX(abs(x2), peak_l);
peak_r = MAX(abs(x3), peak_r);

@lgirdwood lgirdwood Oct 13, 2026 •

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.

Fixed. Added sat_abs_s32() helper that maps INT32_MIN to INT32_MAX, and replaced abs() calls with sat_abs_s32() across all S32 peak volume calculations in active and passthrough paths.

Implement unrolled FIR filtering kernels in fir_arm.c optimized for
ARM Cortex-M DSP architectures:
- Single-cycle SMLAL 64-bit MAC accumulator.
- 4-tap unrolled loop for fir_32x16.
- Dual-sample parallel filtering kernel fir_32x16_2x.
- Guard generic fallback definitions in fir_generic.h.

Signed-off-by: Liam Girdwood <lgirdwood@gmail.com>
Accelerate volume scaling on ARM Cortex-M DSP architectures:
- Add CONFIG_VOLUME_ARM_SIMD choice option in Kconfig.simd.
- Implement volume_arm.c and volume_arm_with_peakvol.c:
  * Packed S16 dual halfword unpack/multiply/saturate/pack using
    SMULBB, SMULTT, arm_sat_s16, and PKHBT.
  * Fast S24 and S32 scaling using SMMULR / arm_smmulr.
  * Single-precision floating point processing with hardware FPU.
  * Optimized peak volume tracking in volume_arm_with_peakvol.c.

Signed-off-by: Liam Girdwood <lgirdwood@gmail.com>
Implement block-accelerated IIR equalizer for ARM Cortex-M architectures:
- Add CONFIG_EQ_IIR_ARM_SIMD Kconfig option.
- Implement eq_iir_arm.c:
  * Block vector processing kernel keeping filter delay states
    (y_n2, y_n1, x_n2, x_n1) and biquad coefficients in CPU registers
    across each 64-sample block.
  * Inlines biquad loop eliminating external call dispatches.
  * Fast branchless saturation for S16, S24, and S32 formats via SSAT.

Signed-off-by: Liam Girdwood <lgirdwood@gmail.com>
Implement ARM Cortex-M DSP optimizations for Dynamic Range Compressor:
- Add CONFIG_DRC_ARM_SIMD choice option in DRC Kconfig.simd.
- Implement drc_math_arm.c with Horner's polynomial evaluations for:
  log10_fixed, drc_lin2db_fixed, drc_log_fixed, drc_asin_fixed, drc_inv_fixed
  leveraging ARM CLZ (count leading zeros) and branchless saturation.
- Implement fast knee_curveK, volume_gain, and envelope tracking.
- Implement drc_arm.c with unrolled output compression.
- Update drc_generic.c guards for SOF_USE_ARM_SIMD(DRC).

Signed-off-by: Liam Girdwood <lgirdwood@gmail.com>
Implement ARM Cortex-M DSP optimizations for FIR Equalizer:
- Implement eq_fir_arm.c providing eq_fir_2x_s16, eq_fir_2x_s24,
  and eq_fir_2x_s32 accelerating 2x parallel filtering.
- Route to 2x processing when SOF_USE_ARM_SIMD(FILTER) is enabled.
- Branchless saturation with arm_sat_s16 and sat_int24.

Signed-off-by: Liam Girdwood <lgirdwood@gmail.com>
Implement ARM Cortex-M DSP optimizations for mixer module:
- Add CONFIG_MIXER_ARM_SIMD Kconfig option.
- Implement mixer_arm.c:
  * Packed dual 16-bit saturating addition using arm_qadd16.
  * 32-bit saturating addition using arm_qadd.
  * Branchless 24-bit saturation via arm_sat_s24.
  * Single-precision floating point mixing with FPU vector adds.
- Update mixer.h to undefine MIXER_GENERIC when CONFIG_MIXER_ARM_SIMD is set.

Signed-off-by: Liam Girdwood <lgirdwood@gmail.com>
Implement ARM Cortex-M DSP optimizations for mixin_mixout module:
- Add CONFIG_MIXIN_MIXOUT_ARM_SIMD choice option in Kconfig.
- Implement mixin_mixout_arm.c:
  * Fast channel mixing and gain scaling with saturating adds (arm_qadd16,
    arm_qadd, arm_sat_s24).
  * 32x32 hardware multiply with 64-bit accumulators.
  * Float vector processing using hardware FPU.
- Guard generic fallback implementations in mixin_mixout_generic.c.

Signed-off-by: Liam Girdwood <lgirdwood@gmail.com>
Implement ARM Cortex-M DSP optimizations for DC blocking filter:
- Add CONFIG_DCBLOCK_ARM_SIMD choice option in Kconfig.
- Implement dcblock_arm.c:
  * Accelerate single-pole highpass filter using 64-bit MAC and
    branchless arm_sat_q31, arm_sat_s16, and arm_sat_s24.
  * Hardware FPU accelerated float processing (dcblock_float_arm).
- Guard generic fallback implementations in dcblock_generic.c.

Signed-off-by: Liam Girdwood <lgirdwood@gmail.com>
Implement ARM Cortex-M DSP optimizations for level_multiplier module:
- Implement level_multiplier-arm.c:
  * S16 unpack, multiply, saturate, and pack via SMULBB/SMULTT and PKHBT.
  * Fast S24 and S32 scaling with arm_smmulr and arm_sat_q31.
  * Hardware float vector gain scaling.
- Guard generic fallback implementations in level_multiplier-generic.c.

Signed-off-by: Liam Girdwood <lgirdwood@gmail.com>
Implement ARM Cortex-M DSP optimizations for PCM format conversion:
- Add CONFIG_FORMAT_CONVERT_ARM_SIMD Kconfig option in audio Kconfig.
- Define PCM_CONVERTER_ARM_SIMD in pcm_converter.h.
- Implement pcm_converter_arm.c:
  * Fast integer format conversions (S16, S24, S32) using SXTH,
    PKHBT, SSAT, and sign extension.
  * Float-to-integer and integer-to-float conversions with hardware FPU.
  * Linear and circular buffer conversion routines with IPC3 and IPC4
    dispatch tables (pcm_func_map, pcm_func_vc_map).

Signed-off-by: Liam Girdwood <lgirdwood@gmail.com>
@lgirdwood

Copy link
Copy Markdown
Member Author

All latest Copilot code review comments have been examined, resolved, and verified:

  1. pcm_converter_arm.c:897 (Odd-Sample Link Gateway Handling):

    • Updated pcm_convert_s24_c32_to_s24_c24_link_gtw loop condition to i + 1 < n to only process complete pairs.
    • Moved odd trailing sample processing inside each circular chunk (if (i < n)), eliminating out-of-bounds reads/writes and removed the post-loop if (i > n).
  2. fir_arm.c:125, 226 (Coefficient Pointer Misalignment):

    • Replaced 32-bit pointer casts and dereferences with direct 16-bit loads (c0 = coef[0]; c1 = coef[1]; c2 = coef[2]; c3 = coef[3];) in both circular segments of fir_32x16 and fir_32x16_2x.
    • Eliminates unaligned memory accesses and strict-aliasing issues when tap count produces 2-byte alignment.
  3. pcm_converter_arm.c:607 (Float Saturation and NaN Handling):

    • Clamped float values against normalized signed ranges (INT32_MAX/INT32_MIN, INT24_MAX/INT24_MIN, INT16_MAX/INT16_MIN) before integer conversion.
    • Handled +INFINITY, -INFINITY, and mapped NaN to 0 across float-to-integer conversion paths.
  4. volume_arm_with_peakvol.c:201 (Attenuation Gain Shift):

    • Added sat_peak_shift() with wide 64-bit shifting and saturation to INT32_MAX.
    • Applied sat_peak_shift(peak, attenuation + PEAK_24S_32C_ADJUST) to S24 meters, and sat_peak_shift(peak, attenuation) to S32 and float meters in scaling and passthrough paths.
  5. volume_arm_with_peakvol.c:391 (INT32_MIN Absolute Value Saturation):

    • Added sat_abs_s32() helper mapping INT32_MIN to INT32_MAX.
    • Replaced all S32 abs() calls with sat_abs_s32() across active and passthrough loops.

Branch topic/arm-simd rebased onto origin/main with clean modular commits, Author/Committer set to Liam Girdwood <lgirdwood@gmail.com> with matching Signed-off-by, compile-verified with ARM GCC (-Wall -Werror), and force-pushed.

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.

3 participants