Skip to content

M1: DSP completion (compressor, listen mode, 4-voice doubler) + docs + tests#8

Merged
yves-vogl merged 6 commits into
mainfrom
feat/m1-dsp-docs
Jul 14, 2026
Merged

M1: DSP completion (compressor, listen mode, 4-voice doubler) + docs + tests#8
yves-vogl merged 6 commits into
mainfrom
feat/m1-dsp-docs

Conversation

@yves-vogl

Copy link
Copy Markdown
Contributor

Summary

Implements the M1 "DSP completion & test coverage" milestone and prepares Seraph for a v0.1.0 tag.

DSP (Complete and refine the DSP, #1)

  • Gentle Compressor (Comp, 0-100%): a new, hand-rolled, zero-latency, feed-forward broadband downward compressor inserted between Air and the Doubler, so all four doubled voices track a consistent main signal. Comp == 0% is a bit-exact bypass (same convention as DeEss/Double). No auto makeup gain - Output compensates.
  • De-Ess Listen (DeEssListen, bool): solos the de-esser's detected sibilance band so DeEssFreq can be tuned by ear, independent of the current DeEss amount.
  • Doubler extended from 2 to 4 voices, each with its own fixed per-voice pan position (a small-choir spread reached at DoubleWidth == 100%), replacing the single symmetric L/R pair. Gain-staging is compensated (2/numVoices) so it reduces to the exact original 2-voice behaviour at numVoices == 2.
  • Both new GUI controls (Comp knob, De-Ess Listen toggle) are wired into the v0.1 slider editor.

Deferred (issue #1 left open): true formant-preserving detune (LPC/cepstral spectral-envelope correction). This is a substantially larger DSP feature that doesn't fit safely into the doubler's modulated-delay architecture without risking the plugin's zero-latency and bit-exact-bypass invariants. Full reasoning in docs/architecture.md's Doubler section and in the issue comment.

Tests (Broaden test coverage, #2)

Catch2 suite grown from 18 to 28 test cases:

  • Sample-rate sweeps (44.1-192 kHz) for both the null test and the full chain at hot settings, plus prepareToPlay sample-rate-change robustness.
  • Mono/stereo bus-layout coverage, including rejected layouts (mono/stereo mismatch, quad).
  • A ~10.7 s simulated long-run stability sweep (4000 blocks, slowly modulated frequency) checking for NaN/Inf and unbounded growth.
  • Dedicated coverage for the three new DSP items above (compressor gain reduction + bypass, listen-mode output, four-voice doubler stereo image).
  • Extended the existing extreme-parameter, rapid-automation, and state-round-trip tests to cover the two new parameters.
  • All 28 tests run in ~5 s locally.

Docs

  • New docs/manual.md: full user manual (what Seraph is, where it sits in a symphonic-metal vocal chain, signal flow, complete parameter reference, mixing tips).
  • docs/architecture.md, README.md, CLAUDE.md updated to match the new signal path and parameter set.
  • CHANGELOG.md: Unreleased content moved into a new [0.1.0] - 2026-07-14 section documenting everything above, including the deferral.

Version

CMakeLists.txt's project(Seraph VERSION 0.1.0 ...) was already 0.1.0 - no change needed.

Test plan

  • cmake --build build --target Tests Seraph_Standalone --parallel 3 - clean build, no warnings on touched files.
  • ctest --test-dir build --output-on-failure - 28/28 tests pass locally (~5 s).
  • CI (macOS + Windows, pluginval strictness 10 + auval) will run on this PR.

Closes #2

Adds two new DSP stages requested for M1: a sibilance-listen/solo mode
on the de-esser (DeEssListen) for tuning DeEssFreq by ear, and a
hand-rolled, zero-latency, bit-exact-bypassable broadband downward
compressor (GentleCompressor, Comp 0-100%) inserted between Air and
the Doubler for glue before the signal is duplicated into doubled
voices. Wires both through SeraphEngine, PluginProcessor's APVTS
plumbing, and the v0.1 slider/toggle editor.
Grows Doubler from a symmetric two-voice L/R pair to four
independently modulated voices, each at its own fixed pan position
(a small-choir spread reached at DoubleWidth == 100%) rather than a
single hard-panned pair. Gain-staging is compensated via a 2/numVoices
factor so the added level exactly matches the original two-voice
design when numVoices == 2. The outer pair keeps its original base
delay/LFO-rate constants; two new inner voices were added at distinct
delays and rates so all four voices decorrelate over time.

True formant-preserving detune (the other part of the M1 doubler ask)
is deferred - see docs/architecture.md and the M1 issue comment for
the reasoning.
Extends coverage for the new DSP (GentleCompressor gain reduction and
bit-exact bypass, De-Ess Listen output, four-voice doubler stereo
image) and adds the M1 "broaden test coverage" scope in a new
CoverageTests.cpp: a null-test sweep and a hot-settings finite-output
sweep across the full documented sample-rate range (44.1-192 kHz),
prepareToPlay sample-rate-change robustness, mono/stereo/rejected bus
layouts, and a ~10.7 s simulated long-run stability sweep with a
slowly modulated frequency checking for NaN/Inf and unbounded growth.
Also extends the existing extreme-parameter, rapid-automation, and
state-round-trip tests to cover the two new parameters. All 28 tests
run in ~5 s locally.
Adds docs/manual.md: what Seraph is, where it sits in a
symphonic-metal vocal chain, signal flow, a full parameter reference
(name/range/default/unit/musical purpose), and mixing tips. Updates
docs/architecture.md's diagram and per-stage sections for the Gentle
Compressor and De-Ess Listen additions and the four-voice doubler
(including the formant-preserving-detune deferral note), README's
feature list/parameter table, and CLAUDE.md's Status/DSP sections to
match the current signal path.
Documents the M1 DSP additions (Gentle Compressor, De-Ess Listen,
four-voice doubler), the broadened test suite, and the new user
manual, plus the formant-preserving-detune deferral, under a new
[0.1.0] - 2026-07-14 section per Keep a Changelog. CMakeLists.txt's
project/plugin version was already 0.1.0.
src/dsp/GentleCompressor.{h,cpp} (the compressor implementation added
in f886590) were left untracked by mistake; the build only worked
locally because they were already on disk. Adds them now.
@yves-vogl
yves-vogl merged commit aa81ae3 into main Jul 14, 2026
2 checks passed
@yves-vogl
yves-vogl deleted the feat/m1-dsp-docs branch July 14, 2026 16:20
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.

Broaden test coverage

1 participant