Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.1.0] - 2026-07-14

### Added

- Project bootstrap: README, license, contributing guide, architecture and build docs, ADRs, and CI workflow.
- Full v1.0 `AudioProcessorValueTreeState` parameter layout (frozen parameter IDs) covering IO/global, noise gate, crossover, low band, high band, EQ, and IR loader.
- LR4 (Linkwitz-Riley 4th order) crossover band-split (`src/dsp/Crossover`), flat-sum tested, with a latency-compensation framework/seam in the processor.
- **DSP completion (M1):** the full v1.0 signal path is wired and live:
- Full-band input noise gate (`src/dsp/NoiseGateStage`), off by default.
- Low-band parallel ("New York style") compressor with makeup gain and wet/dry mix (`src/dsp/ParallelCompressor`).
- High-band distortion engine (`src/dsp/Voicing`) with three selectable voicings — **Gnaw** (op-amp hard clip), **Wool** (cascaded soft-clip fuzz with mid scoop), **Razor** (tight overdrive: pre-clip highpass, soft clip, mid hump) — each running its nonlinear shaping stage 4x oversampled (FIR half-band equiripple) to control aliasing, with drive, tone, and clean/distorted blend controls.
- Post-sum 4-band EQ (`src/dsp/BandEQ`: LowShelf / Peak / Peak / HighShelf), off by default.
- Cab-sim IR loader (`src/dsp/IRLoader`, `juce::dsp::Convolution`-based), off by default, safe-by-default (bit-exact passthrough with no IR loaded, at every session sample rate); `loadImpulseResponse()` is the DSP-side seam a future GUI/preset system will call to load user or factory IRs.
- Latency compensation extended to cover the high band's oversampling latency: reported to the host via `setLatencySamples`, low band delay-compensated to match, high band's own clean/distorted `DryWetMixer` blend delay-compensated too.
- `src/dsp/RealtimeCoefficients.h`: shared real-time-safe (zero-allocation) `juce::dsp::IIR` coefficient update helper, used by `BandEQ` and `Voicing`'s mid/tone filters.
- Broadened Catch2 test suite (issue #43): dedicated test files for every new DSP stage (`NoiseGateTests`, `ParallelCompressorTests`, `VoicingTests`, `BandEQTests`, `IRLoaderTests`), plus sample-rate sweeps (44.1–192 kHz), mono/stereo bus-configuration tests, extreme-parameter-automation and long-run NaN/Inf stability soak tests (`SampleRateAndRobustnessTests`). Existing gain-staging/latency/passthrough tests updated to account for the now-live (non-transparent-by-default) compressor and voicing stages.
- `docs/manual.md`: full user manual — what the plugin is, where it sits in a symphonic-metal chain, signal-flow description, complete parameter reference, and usage tips.

### Changed

- `docs/architecture.md`: signal-flow diagram and module map updated to match the new full signal path; new sections documenting the real-time-safe filter-coefficient pattern, the IR loader's safe-by-default behaviour, and the extended latency-compensation design (including the `DryWetMixer` priming gotcha).
- `README.md`: feature list, signal-flow diagram, and roadmap table updated to match the live DSP and the project's actual milestone scheme (M1 DSP completion & test coverage → M2 presets & state → M3 GUI & accessibility → M4 release).
14 changes: 8 additions & 6 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ Per-repo working memory for Claude Code sessions on this plugin. Part of the **M
## What this is
Twist Your Guts is a Parallax-style **parallel bass processor** for metal: it LR4-splits the bass into low/high bands, parallel-compresses the lows, runs the highs through selectable distortion voicings, then sums back through a 4-band EQ and an IR cabinet loader. AU / VST3 / Standalone.

## Status (pre-1.0)
M0 bootstrap complete (scaffold, CI, docs, ADRs). The LR4 crossover + latency framework is the first DSP landed with tests; the full v1.0 signal path (compressor, distortion voicings, gate, EQ, IR loader) is in progress. See GitHub **milestones/issues** for open work, and `README.md` for the full v1.0 feature scope and signal-flow diagram.

## DSP (v1.0 target)
`Input Trim → Gate → LR4 split (60–1000 Hz) → [Low: parallel comp] + [High: distortion voicing (Gnaw/Wool/Razor) → drive → tone → blend] → delay-compensated sum → 4-band EQ → IR loader → Output`.
- Crossover already implemented in `src/dsp/Crossover.{h,cpp}` (LR4, flat-sum tested) — this is the canonical crossover the suite's `triptych` multiband reuses.
## Status (pre-1.0, v0.1.0)
M0 bootstrap and M1 "DSP completion & test coverage" are both done: the full v1.0 signal path is wired and tested (gate, LR4 crossover, parallel low-band compressor, three oversampled high-band voicings, post-sum 4-band EQ, IR loader, latency compensation). Not yet done: preset manager/versioned state (M2), custom GUI/metering/accessibility (M3), signing/notarization/v1.0.0 release (M4). Voicing character (drive-gain ranges, mid-filter hump/scoop settings) is engineering-tuned, not yet ear-tuned against reference material. IR loader has no bundled factory IRs and no GUI file browser yet (DSP engine is fully live; file-loading is a `loadImpulseResponse()` seam a future GUI/preset system will call). See GitHub **milestones/issues** for open work, `README.md` for the feature scope and signal-flow diagram, and `docs/manual.md` for the full parameter reference.

## DSP (v1.0 target — fully wired as of M1)
`Input Trim → Gate → LR4 split (60–1000 Hz) → [Low: parallel comp → makeup → mix → level] + [High: voicing (Gnaw/Wool/Razor, 4x oversampled) → drive → tone → blend → level] → delay-compensated sum → 4-band EQ → IR loader → optional safety clip → Output Trim`.
- Each stage lives in its own `src/dsp/*.{h,cpp}` class with a dedicated Catch2 test file: `Crossover` (LR4 split/sum, flat-sum tested — canonical crossover the suite's `triptych` multiband reuses), `NoiseGateStage`, `ParallelCompressor`, `Voicing` (oversampling + latency reporting), `BandEQ`, `IRLoader`.
- `src/dsp/RealtimeCoefficients.h`: shared helper for updating `juce::dsp::IIR` filter coefficients from the audio thread without heap allocation (`ArrayCoefficients` stack-only computation + in-place raw-storage write). Used by `BandEQ` and `Voicing`.
- Latency: only `Voicing`'s 4x oversampling adds sample latency; reported via `setLatencySamples`, low band delay-compensated to match. See `docs/architecture.md`'s "Latency compensation" section, including the `DryWetMixer` priming gotcha.
- Params via APVTS (`src/params/`).

## Build & test
Expand Down
65 changes: 40 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,27 @@
[![CI](https://github.com/yves-vogl/twist-your-guts/actions/workflows/ci.yml/badge.svg)](https://github.com/yves-vogl/twist-your-guts/actions/workflows/ci.yml)
[![License: AGPL v3](https://img.shields.io/badge/License-AGPL%20v3-blue.svg)](https://www.gnu.org/licenses/agpl-3.0)

> **Work in progress.** Twist Your Guts is pre-1.0 and under active development. There are no built binaries or releases yet — building from source is currently the only way to run it. Expect breaking changes until v1.0.0 ships (see [Roadmap](#roadmap)).
> **Work in progress.** Twist Your Guts is pre-1.0 and under active development (v0.1.0). There are no built binaries or releases yet — building from source is currently the only way to run it. Expect breaking changes until v1.0.0 ships (see [Roadmap](#roadmap)).

## What it is

Twist Your Guts is a Parallax-style bass plugin built on JUCE 8. It splits your bass signal into low and high bands with a linear-phase-adjacent Linkwitz-Riley crossover, compresses the low band in parallel, and runs the high band through a choice of three distortion voicings before summing everything back together through a 4-band EQ and an impulse-response (cab sim) loader.
Twist Your Guts is a Parallax-style bass plugin built on JUCE 8. It splits your bass signal into low and high bands with a linear-phase-adjacent Linkwitz-Riley crossover, compresses the low band in parallel, and runs the high band through a choice of three distortion voicings before summing everything back together through a 4-band EQ and an impulse-response (cab sim) loader. See [`docs/manual.md`](docs/manual.md) for the full parameter reference and usage tips.

## Features (v1.0 scope)
## Features

- **Noise gate** — full-band, ahead of the crossover split
- **LR4 crossover band-split** — 4th-order Linkwitz-Riley split, adjustable 60 Hz – 1000 Hz (default 250 Hz)
- **Low band**: parallel compressor with wet/dry mix and output level
- **High band**: three distortion voicings, each with independent drive/tone
- **Gnaw** — hard clip
- **Wool** — fuzz
- **Razor** — tight overdrive
- **Low band**: parallel ("New York style") compressor with makeup gain, wet/dry mix, and output level
- **High band**: three distortion voicings, each 4x oversampled to keep aliasing under control, with independent drive/tone
- **Gnaw** — op-amp-style hard clip
- **Wool** — cascaded soft-clip fuzz with a mid scoop
- **Razor** — tight overdrive: pre-clip highpass, soft clip, mid hump
- Clean/distorted blend control per voicing, plus output level
- **Noise gate** on the input stage
- **4-band EQ** post-sum
- **IR loader** (cabinet simulation) on the output stage
- **Presets** with full state save/recall
- **Metering** throughout the signal chain
- **4-band EQ** post-sum (LowShelf / Peak / Peak / HighShelf)
- **IR loader** (cabinet simulation) on the output stage — convolution engine is live; bundled factory IRs and a GUI file browser land in a later milestone
- **Delay-compensated signal path** — the high band's oversampling latency is reported to the host and the low band is time-aligned to match
- **Presets** with full state save/recall *(planned — a dedicated preset manager/versioning scheme is a later milestone; APVTS state save/load already round-trips today)*
- **Metering** throughout the signal chain *(planned, alongside the custom GUI)*

## Signal flow

Expand All @@ -34,8 +35,9 @@ Input Trim → Gate → LR4 Split (60–1000 Hz, default 250 Hz)
┌─────────────┴─────────────┐
│ │
Low band High band
Comp → Mix → Level Voicing → Drive → Tone → Blend → Level
│ │
Parallel Comp Voicing → Drive → Tone → Blend
→ Makeup → Mix │
│→ Level → Level
└─────────────┬─────────────┘
Sum (delay-compensated)
Expand All @@ -44,10 +46,26 @@ Input Trim → Gate → LR4 Split (60–1000 Hz, default 250 Hz)
IR loader
Output
Safety Clip (optional)
Output Trim
```

The high band runs through oversampling for the distortion stage; the low band is delay-compensated to stay time-aligned with it before the sum. See [`docs/architecture.md`](docs/architecture.md) for the full breakdown, including the latency-compensation strategy.
The high band runs 4x oversampled for the distortion stage; the low band is delay-compensated to stay time-aligned with it before the sum. See [`docs/architecture.md`](docs/architecture.md) for the full breakdown, including the latency-compensation strategy, and [`docs/manual.md`](docs/manual.md) for the full parameter reference.

## Parameters

See [`docs/manual.md`](docs/manual.md) for the complete, musically-annotated parameter reference. Summary:

| Section | Parameters |
|---|---|
| IO / Global | Input Gain, Output Gain, Bypass, Safety Clip |
| Noise Gate | Enable, Threshold, Ratio, Attack, Release |
| Crossover | Frequency (60–1000 Hz) |
| Low band | Comp Threshold/Ratio/Attack/Release/Makeup/Mix, Level |
| High band | Voicing (Gnaw/Wool/Razor), Drive, Tone, Blend, Level |
| EQ | Enable, Low Shelf Freq/Gain, Peak 1 Freq/Gain/Q, Peak 2 Freq/Gain/Q, High Shelf Freq/Gain |
| IR loader | Enable, Mix |

## Installation

Expand Down Expand Up @@ -87,14 +105,11 @@ ctest --test-dir build --output-on-failure

| Milestone | Description | Status |
|---|---|---|
| M0 | Bootstrap — project skeleton, CI, docs | In progress |
| M1 | DSP core — crossover + latency framework | Planned |
| M2 | Dynamics — gate + compressor | Planned |
| M3 | Distortion engine — oversampling, 3 voicings | Planned |
| M4 | EQ + IR loader | Planned |
| M5 | State & presets | Planned |
| M6 | Custom GUI | Planned |
| M7 | Release engineering — signing, notarization, installers, v1.0.0 | Planned |
| M0 | Bootstrap — project skeleton, CI, docs | Done |
| M1 | DSP completion & test coverage — gate, crossover, parallel compressor, 3 voicings (oversampled), 4-band EQ, IR loader, latency compensation, broadened test suite | Done (v0.1.0) |
| M2 | Presets & state recall — preset manager, factory presets, versioned state | Planned |
| M3 | GUI & accessibility — custom LookAndFeel, metering UI, accessibility pass | Planned |
| M4 | Release: signing, notarization, v1.0.0 — installers, tagged release | Planned |

## License

Expand Down
Loading
Loading