Skip to content

Route the spectral kernels onto DspTap's shared real FFT#19

Merged
tap merged 2 commits into
mainfrom
claude/shared-code-submodule-strategy-rdel5d
Jul 21, 2026
Merged

Route the spectral kernels onto DspTap's shared real FFT#19
tap merged 2 commits into
mainfrom
claude/shared-code-submodule-strategy-rdel5d

Conversation

@tap

@tap tap commented Jul 21, 2026

Copy link
Copy Markdown
Owner

The spectral kernels (conv_engine / stft / nr / spectra) carried a private complex radix-2 Cooley–Tukey FFT (fft.h). They now share DspTap's real FFT (tap::dsp::real_fft) — the split-radix Ooura transform, plus the per-target vDSP (Apple) and CMSIS-Helium (Cortex-M55) float32 backends.

Changes

  • Wire in DspTap: pin the tap/dsptap submodule, add_subdirectory + link tap::dsp; the install/export and the C-ABI / standalone tool builds pull it in too.
  • stft: forward/inverse via real_fft in the packed layout; the spectral op now operates on the N/2+1-bin half-spectrum (the scaffold unpacks/repacks around it).
  • nr: gates the half-spectrum (loop-bound change only).
  • spectra: remaps the half-spectrum and lets the real inverse mirror the rest — its hand-rolled Hermitian mirror is gone.
  • conv_engine: IR/FDL spectra stored in the packed half-spectrum, overlap-save multiply-accumulate done on it — half the spectral memory and half the MAC.
  • Retire fft.h and fft_test.cpp (DspTap owns the real-FFT contract tests); spectra_test's peak-bin analysis uses real_fft directly.
  • Add bench/fft_bench.cpp — a before/after round-trip benchmark against a baseline copy of the retired radix-2 routine.

Correctness

A product of two Hermitian spectra is Hermitian, so the exp(+i) sign convention and the 2/N inverse cancel through forward→multiply→inverse — the convolution is bit-for-bit the same operation. All kernel tests pass, including the conv_engine reference-convolution test (888,631 assertions / 132 cases).

Performance

fft_bench measures ~6.5× per transform on x86 double (split-radix + real-vs-complex), before the vDSP/CMSIS backends add a further ~3× on Apple/Arm.

Note

Downstream, TapTools-Max's tap.convolve~ / tap.nr~ / tap.spectra~ will need to link tap::dsp (the Ooura static lib) once its kernel submodule is bumped to this — a mechanical wrapper follow-up.

🤖 Generated with Claude Code

https://claude.ai/code/session_01MRTDgYKY38WH8Bqz17W9k1


Generated by Claude Code

claude added 2 commits July 21, 2026 20:00
The spectral kernels (conv_engine / stft / nr / spectra) carried a private
complex radix-2 Cooley–Tukey FFT (fft.h). They now share DspTap's real FFT
(tap::dsp::real_fft) — the split-radix Ooura transform, plus the per-target
vDSP (Apple) and CMSIS-Helium (Cortex-M55) float32 backends.

- Pin the tap/dsptap submodule and wire it into the build (add_subdirectory +
  link tap::dsp); the C ABI and standalone tool builds pull it in too.
- stft: forward/inverse via real_fft in the packed layout; the spectral op now
  operates on the N/2+1-bin half-spectrum (the scaffold unpacks/repacks around
  it). nr and spectra follow — nr gates the half-spectrum, spectra remaps it
  and lets the real inverse mirror the rest (its hand-rolled Hermitian mirror
  is gone).
- conv_engine: store IR/FDL spectra in the packed half-spectrum and do the
  overlap-save multiply-accumulate on it — half the spectral memory and half
  the MAC. A product of two Hermitian spectra is Hermitian, so the exp(+i)
  convention and the 2/N inverse cancel through forward→multiply→inverse and
  the convolution is bit-for-bit the same operation (the reference-convolution
  test confirms it).
- Retire fft.h and fft_test.cpp; the DspTap real FFT has its own contract tests
  in the DspTap repo. spectra_test's peak-bin analysis uses real_fft directly.
- Add bench/fft_bench.cpp — a before/after round-trip benchmark vs a baseline
  copy of the retired radix-2 routine. On x86 double it measures ~6.5x per
  transform (split-radix + real-vs-complex); Apple/Arm add the backend win.

All kernel tests pass (conv_engine reference convolution, nr, spectra, plus
the rest of the battery).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MRTDgYKY38WH8Bqz17W9k1
- build.yml now checks out submodules recursively so the dsptap submodule
  (the spectral kernels' FFT) is present at configure time.
- Reflow bench/fft_bench.cpp with clang-format-18 (it was added after the
  earlier format pass, so it slipped the gate).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MRTDgYKY38WH8Bqz17W9k1
@tap
tap merged commit 15b35ab into main Jul 21, 2026
12 checks passed
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.

2 participants