Firmament — User Manual

Open the heavens — a stereo widener and imager for lush orchestral layers.

What Firmament is

Firmament is a Mid/Side stereo widener and imager. It is one of the twelve plugins in the Basilica Audio heavy-music suite, and its job in that suite (and in any mix) is to take content that already has stereo information - strings, choirs, synth pads, doubled/layered guitars, ambience returns - and control how wide it feels, without ever compromising how the mix folds down to mono (club PA, phone speaker, a broadcast mono-check, a bass player checking their part in mono).

Firmament does not create stereo width out of a genuinely mono signal by itself (Width and Low Width can only scale what stereo difference is already present in the input) - the exceptions are Haas Mode and Decorrelate, which can create a sense of width from mono-compatible material. Haas Mode and Classic Decorrelate do so at the cost of some of the exact mono-sum guarantee the rest of the plugin provides (Haas costs the most, Classic Decorrelate much less - see below). The v0.3.0 Velvet Dense/Sparse Decorrelate modes close that gap entirely: they synthesize width from published velvet-noise decorrelator designs while leaving the mono fold-down bit-for-bit identical to the input's own - widening from mono with zero mono-compatibility cost.

v0.2.0 also revised how Auto Mono Safety reacts (calmer ballistics, a dead-zone around zero correlation, a user-adjustable floor, and an optional per-band mode) and widened Bass Mono Freq's range - see the parameter reference and docs/design-brief.md/docs/research-notes.md for the full research behind these changes. Every new parameter defaults to a value that reproduces v0.1.1's behaviour exactly, so nothing changes unless you explicitly opt in.

v0.3.0 upgrades Decorrelate with two velvet-noise modes (published DAFx-conference decorrelator designs) that - unlike Classic Decorrelate and unlike any Haas trick - are fully mono-sum-safe by construction: fold the output down to mono and you get bit-for-bit the input's own mono sum, at any Velvet amount. It also adds a Bass Mono Mode selector (Phase Matched for a seam-free crossover; Linear Phase for mastering-grade zero phase rotation, at the cost of latency), a third width band (High Split / High Width), a faster Dynamic safety response with compressor-style ballistics, opt-in Width Compensation (equal-power loudness across the Width range), and a Mono Audition monitor switch. As always, every new parameter defaults to exact v0.2.0 behaviour.

Where it sits in a heavy production chain

Firmament is a width/imaging tool, which places it toward the back end of a channel or bus chain, after tone-shaping and dynamics have already been decided:

  1. Corrective/tonal EQ, compression, saturation (e.g. overture, tenebrae, other suite members) - shape the sound first.
  2. Firmament - decide how wide it should feel, once the tone is set.
  3. Reverb/delay sends, final bus processing - width decisions made before verb affect how the reverb tail itself is perceived; some engineers prefer to widen after the reverb return instead, which is a valid alternative depending on the source.

Typical placements in a heavy-music production:

Signal flow (plain-language version)

See docs/architecture.md for the full technical breakdown (Mermaid diagram, exact math, the Linkwitz-Riley crossover's real magnitude/phase behaviour, real-time-safety details). In short:

  1. The input is split into Mid (mono content, (L+R)/2) and Side (stereo difference content, (L-R)/2).
  2. If Bass Mono is off, Width scales the whole Side signal by a single amount.
  3. If Bass Mono is engaged, Side is split into a low band (below the Bass Mono frequency) and the rest; Low Width scales the low band. If High Split (v0.3.0) is also engaged, the rest is split again into a mid band (Width) and a high band (High Width) - a 3-band imager. Bass Mono Mode (v0.3.0) decides how the Mid path relates to the split: untouched (Classic), phase-matched through a companion allpass (Phase Matched), or time-aligned with a linear-phase FIR split (Linear Phase, with reported latency).
  4. If Auto Mono Safety is on, Side is further attenuated automatically whenever the input is heavily out-of-phase enough to leave a small dead-zone around zero correlation (a safety net against mono cancellation), on top of whatever the width controls already did - either as one global reading, or (if Auto Mono Safety Multiband is also on and Bass Mono is engaged) independently per band, and either with calm meter ballistics (Smooth) or fast compressor-style ballistics (Dynamic, v0.3.0).
  5. Mid and the processed Side are recombined back into Left/Right. In Classic bass-mono mode, Mid is never touched by any of the above - and the Phase Matched/Linear Phase modes only ever change Mid's phase/timing, never its content - this is what guarantees the mono-fold-down safety described below.
  6. If Width Comp (v0.3.0) is on, an equal-power makeup gain compensates the level change Width introduces.
  7. If Decorrelate is on: in Classic mode the Right channel is processed through an allpass network and blended in by Decorrelate Amount; in the Velvet modes (v0.3.0) both channels receive velvet-noise-diffused stereo-difference content instead - fully mono-sum-safe. Otherwise, if Haas Mode is on, the Right channel is delayed slightly relative to Left (Decorrelate and Haas are mutually exclusive) - applied last, before the final trim.
  8. Output trims the overall level; Mono Audition (v0.3.0), when engaged, replaces both channels with the exact mono fold-down for checking.

Reported latency

Firmament is latency-asymmetric by mode, and only by one mode. getLatencySamples() reports exactly this:

Bass Mono Mode Reported latency
Classic 0
Phase Matched 0
Linear Phase N/2 samples — 2048 at 48 kHz

Everywhere else in the chain the story is the same zero: the crossovers are Linkwitz-Riley IIR structures, the Classic Decorrelate allpass cascade is a direct-form biquad chain, the Velvet Dense/Sparse decorrelators are zero-latency sparse FIRs, and Haas Mode's delay is a deliberate relative channel offset rather than a processing artifact a host needs to compensate for - none of these add reported latency, at any setting, at any sample rate. Only Linear Phase Bass Mono differs: its FIR complementary crossover reports N/2 samples, where N = 4096 * fs / 48000 rounded to even, so the figure scales with sample rate (2048 at 48 kHz; correspondingly more or less at other rates), and it is reported dynamically, off the audio thread, via a 50 ms message-thread servicing timer rather than the audio callback. Switching to or from Linear Phase mid-playback applies a brief (~5 ms) mute and may cause your host to renegotiate plugin delay compensation - some hosts click while doing so, which is why the Tips below recommend picking the mode before a render pass rather than automating it. A click-free transition across a latency change is not achievable in principle.

Parameter reference

Parameter Range Default Unit What it does
Width 0-200 100 % Scales the Side (stereo-difference) signal. 100% is the input's original stereo image, unmodified. 0% collapses everything to mono (Side silenced). 200% doubles the Side channel's amplitude for a maximally wide, sometimes "hyped"/artificial-feeling image - useful in small doses, easy to overdo on a whole mix. When Bass Mono is engaged, Width governs only the band above the Bass Mono frequency.
Bass Mono Freq 0-600 0 (off) Hz The crossover frequency below which Low Width (rather than Width) governs the Side signal. At 0 Hz (off), the whole spectrum is a single band governed by Width alone. Typical settings sit in the 80-200 Hz range - low enough to leave kick/bass/low-guitar fundamentals centered, high enough to still catch the "boxy" low-mid stereo smear some wide reverbs/pads produce. The 500-600 Hz top of the range is a lower-confidence, reasoned extension (see docs/research-notes.md) for material where you want stereo control noticeably higher up than the usual bass-mono corner.
Low Width 0-200 0 % Independent width scale for the band below Bass Mono Freq - only audible while Bass Mono Freq is above 0 Hz. At the default of 0%, the low band is forced to mono, exactly like a classic "bass mono" utility - the standard mastering-bus move to keep sub-bass energy centered and translate well on smaller systems. Raise it above 0% if you specifically want some width to survive down low (rare, but occasionally useful for very wide pad/drone material where even the low end should breathe a little).
Auto Mono Safety off/on off - When on, automatically reins in the Side signal whenever the input is heavily out-of-phase (correlation trending below a small dead-zone around zero, not any negative reading at all - an occasional small deviation is treated as insignificant), independent of and on top of Width/Low Width. A safety net for automated Width or aggressive settings on unpredictable source material; it never affects Mid, so it cannot break Firmament's mono-fold-down guarantee - it only ever reins in how wide Side gets. Leave it off if you are dialling in Width by ear and want full manual control; turn it on as a safety net on busses you can't constantly monitor.
Auto Mono Safety Floor -24 to 0 -9.1 dB The minimum Side gain Auto Mono Safety reaches at fully out-of-phase (worst-case) correlation - only relevant while Auto Mono Safety is on. -9.1 dB is the historical default (a gentle, audible-but-not-drastic safety net); lower it (toward -24 dB) for a firmer net on wide/exposed settings, or raise it (toward 0 dB) if you want the safety net to barely do anything even when it does engage.
Auto Mono Safety Multiband off/on off - Only relevant while both Auto Mono Safety and Bass Mono Freq are on. When engaged, Auto Mono Safety reasons about the low and high bands (split at Bass Mono Freq) independently instead of one global correlation reading - useful on a master bus where the low end is already safely centered (Bass Mono/Low Width) and you don't want an unrelated phase problem in the highs to needlessly dull the low end too (or vice versa). Off by default, since it changes Auto Mono Safety's behaviour whenever both features are engaged together.
Haas Mode off/on off - Enables an alternative widening technique: delays the Right channel by Haas Time relative to Left, after the Mid/Side stage. This can widen genuinely mono-compatible material (it works even at Width = 0%) - but unlike Width/Low Width, it does not preserve an exact mono-sum match with the input (summing two time-offset channels produces comb filtering on mono fold-down). Use it deliberately, and always check a mono fold-down before committing if translation matters for the target (e.g. broadcast, club systems). Mutually exclusive with Decorrelate - if both are on, Decorrelate takes effect and Haas Mode's delay is bypassed.
Haas Time 0-40 20 ms The Left/Right delay Haas Mode applies, only audible while Haas Mode is on. Short times (5-15 ms) read as subtle widening; the 15-35 ms "precedence effect" zone reads as a strong, immersive width; times approaching 40 ms start to read as a discrete slap/echo rather than width - back off if you hear a distinct repeat rather than a wider image.
Decorrelate off/on off - A gentler alternative to Haas Mode for widening near-mono material (a mono-tracked lead, a narrow pad): a network of allpass filters processes the Right channel instead of delaying it. Like Haas Mode, this is not mono-sum-safe - it is a second, smaller, deliberate exception to Firmament's mono-fold-down guarantee, not "mono-safe" - but its documented cost is mild spectral ripple rather than Haas Mode's deep comb-filter notches. Mutually exclusive with Haas Mode - if both are on, Decorrelate takes effect and Haas Mode's delay is bypassed.
Decorrelate Amount 0-100 50 % How much of the allpass-processed signal blends into the Right channel, only audible while Decorrelate is on. Higher values widen more but cost more mono-fold-down ripple; lower values are subtler and gentler.
Output -24 to +24 0 dB Final output trim, applied after everything else (including Haas Mode/Decorrelate). Firmament has no built-in limiter or ceiling - Width/Low Width above 100% and Output above 0 dB can both add gain, so use this to compensate level changes introduced by extreme Width settings, not as a general-purpose gain/makeup stage.
Decorrelate Mode (v0.3.0) Classic / Velvet Dense / Velvet Sparse Classic - Selects the Decorrelate algorithm. Classic is the v0.2.0 Right-channel allpass cascade, unchanged (a small, documented mono-fold-down cost). Velvet Dense and Velvet Sparse use published optimized velvet-noise decorrelator pairs (DAFx-18) on both channels, and are fully mono-sum-safe: the mono fold-down of the output is exactly the input's own mono sum at any Amount, because only the stereo-difference content is synthesized - the mono content is never touched. Dense (30 taps) is the smoothest; Sparse (15 taps) is slightly more coloured between the channels but costs half the CPU. Switching modes is a click-free 50 ms crossfade.
Bass Mono Mode (v0.3.0) Classic / Phase Matched / Linear Phase Classic - How the bass-mono crossover treats the Mid path (only relevant while Bass Mono Freq is above 0 Hz). Classic is exactly the v0.2.0 behaviour. Phase Matched additionally passes Mid through a companion allpass that tracks the crossover's phase exactly, making the low/high seam phase-coherent across the whole spectrum (per-channel response flat within +/-0.1 dB, inter-path phase within 1 degree - measured, not claimed). Linear Phase switches the Side split to a mastering-grade linear-phase FIR crossover with zero phase rotation and perfect reconstruction - at the cost of latency (2048 samples at 48 kHz, reported to the host for automatic compensation). Switching to/from Linear Phase mid-playback applies a very short mute and may cause your host to renegotiate latency - some hosts click; prefer choosing the mode before a render pass.
High Split (v0.3.0) 0 + 500-8000 0 (off) Hz A second crossover on the Side signal, above the bass-mono split, turning the width stage into a 3-band imager: Low Width below Bass Mono Freq, Width between the two crossovers, High Width above High Split. At 0 Hz (off) nothing changes. Internally kept at least an octave above Bass Mono Freq whenever both are engaged. Most useful in the 1-4 kHz range (e.g. keep the mids' width as-is while opening or reining in cymbal/air content separately).
High Width (v0.3.0) 0-200 100 % Width scale for the band above High Split - only audible while High Split is above 0 Hz. Same semantics as Width (100% = unchanged, 0% = mono, 200% = doubled Side).
Safety Response (v0.3.0) Smooth / Dynamic Smooth - Auto Mono Safety's reaction speed. Smooth is exactly the v0.2.0 behaviour: the 300 ms meter-ballistics estimate drives the attenuation map directly - calm, but a short anti-phase transient can slip through. Dynamic detects on a fast 30 ms estimator and moves the gain with compressor-style ballistics (5 ms attack to 90% of the needed attenuation, 250 ms release) - it catches anti-phase transients Smooth lets through, while releasing gently once the material recovers. Works in both broadband and Multiband safety modes.
Width Comp (v0.3.0) off/on off - Equal-power width compensation: applies a makeup gain of 1/sqrt(a^2+b^2) (from the broadband Width only) so overall loudness stays constant as you sweep Width - without it, Width 200% is measurably hotter and 0% quieter, which biases "wider sounds better" A/B judgements. Off by default (the mastering convention is that width changes side level only). Note: computed from the broadband Width parameter alone; with the multiband splits engaged, Low/High Width don't enter the formula.
Mono Audition (v0.3.0) off/on off - Monitor switch: auditions the exact mono fold-down (L+R)/2 on both channels, after everything else, with a click-free crossfade. This is the "always A/B in mono" tip as a one-click button. A monitoring control, not a mix decision - it is excluded from factory presets, but it is automatable if you want a mono-check section in a template.

Tips

Presets

Firmament ships with thirteen factory presets covering common use cases (orchestral/choir width, doubled rhythm glue, master-bus bass-mono, automated-width safety nets, one showcase preset each for Decorrelate and Haas Mode, and - new in v0.3.0 - Velvet Width, Mastering: Linear Phase Bass Mono, and Three-Band Imager) - see docs/presets.md for the full list and the intent behind each. The preset bar docked at the top of the plugin window lets you browse factory/user presets, save your own, rename/delete user presets, import/export single presets or a whole bank (a zip of your user presets), and set a preset as the default that loads on a fresh instance. Presets are a layer on top of your host's own plugin-state save mechanism, not a replacement for it - your DAW session still saves whatever state is currently loaded either way.

Under the hood

The reasoning and full technical detail live in docs/architecture.md; the numbers below are what the automated test suite actually enforces on every push.

Mono compatibility is structural, not tuned. Firmament encodes to Mid/Side (mid = (L+R)/2, side = (L-R)/2) and decodes as left = mid + side, right = mid - side. Every width control - Width, Low Width, High Width, Auto Mono Safety - only ever scales Side; in Classic bass-mono mode Mid is never touched by any of them. Because decode is always left + right == 2*mid regardless of what Side is, the mono downmix of the output equals the mono downmix of the input at any width setting, including 0% and 200%. This is checked at the codec level directly, at the engine across a spread of settings, and independently for every stage that could plausibly break it - multiband width, Auto Mono Safety, and the third width band.

Velvet-noise decorrelation had to resolve a real contradiction, not just implement a published design. The published optimized velvet-noise decorrelator pairs (coefficients transcribed as data from the open-access paper's own tables, no third-party code) decorrelate well individually, but their sum carries a real ~17 dB notch around 320 Hz at 48 kHz - because the optimization that produced them constrains each filter's own flatness and the pair's coherence, but never the pair's sum. Applied as a raw per-channel wet mix, that notch would show up directly in the mono fold-down. Firmament instead keeps the widening half of the topology intact but pins the mono content dry: S' = (1-d)S + d*(A(L) - B(R))/2, M' = M. The result is a decorrelator whose mono compatibility is structural rather than tuned - measured fold-down dip ~0.0000003 dB at Velvet Dense, Width 150%, Amount 100%, against 16.2 dB for a Haas-style control on the identical program - and both channels are genuinely processed rather than only one, unlike Classic mode.

Phase Matched proves its own claim with a negative control. Rather than hand-rolling a second-order allpass to track the crossover's phase, Phase Matched wraps the same Linkwitz-Riley filter class in its own documented allpass mode, so the companion Mid path shares the identical internal state equations and coefficients as the crossover itself - the phase-tracking guarantee holds by construction, not by careful duplication. The test that proves it re-runs the same phase-tracking assertion with the companion allpass replaced by unity and requires that run to fail - it measures 179.8 degrees of phase error there, against 5e-6 degrees when the real allpass is in place, which is a guard against the test silently no longer measuring anything.

Linear Phase is a genuine perfect-reconstruction FIR pair, not an approximation: a Kaiser-windowed sinc lowpass on the mono Side stream, with the high band and the Mid path both delayed to match. Measured residual against a pure N/2-sample delay: ~7e-9. Group delay deviates from flat by 0.0002 samples across 20 Hz - 20 kHz. The kernel is recomputed on the message thread and installed via a single Convolution::loadImpulseResponse call, which handles its own background loading and output crossfade, rather than a hand-rolled double buffer - deliberately, because JUCE's plain FIR filter class cannot have its coefficients reassigned from the message thread while the audio thread reads them without a data race.

Three-band width sums flat because the low band gets phase-corrected before the sum. Standard 3-way Linkwitz-Riley practice, and the detail naive 3-band splits usually get wrong: the low band passes an allpass matched to the high split before the band sum, so all three bands carry identical phase there. Measured band-sum deviation: within ±0.1 dB, in both the 3-band case and the high-split-alone 2-band case.

The correlation guard's energy gate exists because of a real trap. A leaky Pearson correlation ratio is invariant under silence - numerator and denominator decay at the same rate, so the ratio never moves. Every correlation estimator in the plugin - the display meters and the Dynamic safety detector alike - therefore decays its estimate toward zero below an energy gate; without it, meters would read ±1 on silence and the Dynamic guard could latch at maximum attenuation after an anti-phase burst and never release. Dynamic's own ballistics are specified and measured as times to 90% settling (5 ms attack, 250 ms release) rather than raw time constants, because a raw-time-constant reading of the original specification turned out to be unsatisfiable - a 250 ms time constant only reaches 90% recovery after roughly 575 ms, not 250.

Engineering hygiene: zero heap allocations on the audio thread, proven under a replaced allocator across every decorrelate/bass-mono/safety mode combination, including mode switches inside the guarded region and the Linear Phase path swap's reset(). Every conditional DSP stage runs on every sample regardless of whether it is currently engaged - only the output selection is gated - because gating the processing call itself once left filter state frozen rather than decaying, producing an audible transient the one time it shipped that way (fixed in v0.1.1). Every input sample is checked for NaN/Inf and zeroed before it reaches the M/S encode, because the crossover's IIR state and the correlation estimator's leaky integrators would otherwise carry a single poisoned sample forward indefinitely. Sessions from v0.1.x and v0.2.0 load with every stored value intact, verified both as a same-binary tolerance-0 null and against a frozen, checked-in v0.2.0 reference render.

Known limitations

Research-derived voicing (honesty note)

Firmament's default values and ranges (Bass Mono Freq's 80-200 Hz "typical" range, the Linkwitz-Riley crossover order, the Haas Time window, Auto Mono Safety's ballistics/dead-zone, Decorrelate's approach) are research-derived from public manuals, developer/product documentation, mastering-forum and trade-press consensus, and acoustics/psychoacoustics literature (see docs/research-notes.md for the full sourcing) - not measured against any commercial stereo-widener plugin's actual audio output, and no proprietary DSP algorithm from any other vendor was inspected, decompiled, or approximated. docs/design-brief.md documents exactly which numbers are directly sourced, which are sourced-but-lower-confidence, and which are reasoned choices where a source establishes a principle but not an exact number.

The editor

Firmament ships the suite's M3 vector editor: a fully runtime-drawn black/gold surface (no bitmap assets) with pointer knobs on engraved scale rings, lamp toggles, and five section panels laid out in signal-flow order - Width (the core M/S scale and its equal-power compensation switch), Bands (the two Side-path crossovers and per-band widths), Mono Safety, Widen (Decorrelate and Haas), and Output. Choice parameters (Bass Mono Mode, Decorrelate Mode, Safety Response) are detented knobs that snap to and announce their mode names.

Two needle meters show the engine's correlation estimates live: IN (the broadband input correlation that also drives Auto Mono Safety) on the Width panel and OUT (post-processing) on the Output panel, both on a -1...+1 scale with gentle meter ballistics. +1 means fully mono-compatible; readings pinned toward -1 warn that the output would cancel on a mono fold-down.

Accessibility

The editor is built to WCAG 2.1 AA: