feat(anvil): add Ghost harmonics and Phone listen

Ghost adds the sub's harmonics 2–10 above Ghost from, so phones hear the
note. The band above the split is measured per harmonic and only missing
harmonics are filled, so added ones cannot cancel the patch's own. The sub
level does not change. Phone monitors the output in mono, 400 Hz–7 kHz.
This commit is contained in:
nvrl committed 2026-11-06 13:46:15 +01:00
1 parent 4f1e237d66
commit e7f3346077
12 files changed
+489 -50

No files matched your search

+9
View File
@@ -1,5 +1,14 @@
# Anvil changelog
## Unreleased
- Add Ghost harmonics: **Ghost** and **Ghost from** add the sub's harmonics 2–10
above a chosen frequency, so phones hear the note. Anvil measures the patch's own
harmonics above the split and fills only the ones that are missing. The sub level
does not change.
- Add **Phone**, a listen mode: mono, band-limited to 400 Hz–7 kHz. Not saved.
- Show the patch's harmonics and the added ones in an inset in the scope.
## 0.2.0
- Change the CLAP ID to `io.narl.bass-foundry.anvil`. Hosts see this as a new
+26 -1
View File
@@ -28,12 +28,37 @@ redistributed packages.
**Retrigger** on, every note starts at this phase.
5. Turn on **Solo sub** to hear only the new sub; the scope shows the original
low band (grey) against the new sub (accent).
6. Turn on **Phone** to check the drop the way phones and laptop speakers play
it: mono, nothing below 400 Hz. A clean sub vanishes there. If the note
disappears with it, raise **Ghost**.
### Ghost harmonics
Phone speakers play almost nothing below 300–500 Hz. A clean 50 Hz sub sends all
its energy below that, so on a phone the note is gone. The ear rebuilds a note's
pitch from its harmonics, so harmonics alone carry the note.
**Ghost** adds the sub's harmonics 2–10 above **Ghost from**, falling 1/k like a
saw. At 100 %, harmonic k sits at 2/k of the sub's level. They fade in over half
an octave above Ghost from, and never reach below Split. The sub itself does not
change, so the weight on a club system stays where Sub level puts it.
Anvil measures each harmonic of the patch above the split and adds only what is
missing. A harmonic the patch already has meets an added one at an unrelated
phase and could cancel it, so Ghost leaves those alone. The inset in the scope
shows both, per harmonic: what the patch carries (grey) and what Ghost adds
(accent). A riddim patch usually needs little; 808s and clean sine subs need the
most. Each new note is measured from its first 60 ms; during that time every
harmonic counts as missing.
Drive works differently: it saturates the sine itself, adds only odd harmonics,
and changes the sub's own shape.
Other controls:
- **Dynamics** at 0 % holds the level for the whole note. Raise it to let the sub
follow the original's volume shape, for example a wobble.
- **Drive** adds upper harmonics so the sub reads on phones and laptops.
- **Drive** saturates the sine: odd harmonics and a thicker sub.
- **Octave** moves the sub against the detected note. Use −1 for a bass played
one octave up.
- **Glide** slides between overlapping notes; 0 jumps.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 243 KiB

After

Width:  |  Height:  |  Size: 262 KiB

+10 -19
View File
@@ -217,22 +217,13 @@ one period of the note, so heavy settings do not ripple at f0. See [Planish](pla
*offset audition*: a sweep of sub offsets against the kick (−30 to +30 ms,
then finer) and a marker for where the hit is heard, kept apart from the
low-band cancellation reading (problem 21). A sub shape from sine to rounded
triangle. A note attack counted in cycles. *Ghost harmonics*: harmonics 2–5
of the sub sine above a cutoff you set, with weights that follow the
patch's own harmonic slope, so phones hear the note; separate from the sub
level, so the physical sub does not change (problem 19). A *small speaker*
listen button that band-limits the output to judge it. Design checks before
building Ghost: Anvil's Drive already adds harmonics without
intermodulation (one sine through tanh), but only odd ones and it changes
the fundamental; harmonics 2–5 of a 50 Hz sub (100–250 Hz) still sit under a
phone's cutoff (often 300–500 Hz), so Ghost needs a "from" frequency and
harmonics up to about 10; and generated harmonics at k·f0 add to the
patch's own harmonics at the same frequencies with unrelated phase, so they
can cancel. The paper boosts harmonics that exist and generates only missing
ones: Lathe already boosts existing ones, so Ghost should fill only
harmonics the patch lacks above the split (measure the high band per
harmonic, as `common-dsp` `meter.rs` does). Most useful on 808s and clean
subs; a riddim patch already carries its note in the mids.
triangle. A note attack counted in cycles. *Ghost harmonics* and the
*Phone* listen are done (unreleased, see [Anvil](anvil/README.md)): harmonics
2–10 above a "from" frequency, filled only where the patch lacks them, with
the sub level unchanged (problem 19). Open for Ghost: weights that follow the
patch's own harmonic slope instead of a fixed 1/k; measuring a new note's
harmonics from the lookahead, so its first 60 ms do not count them as
missing; a listening check on an 808 over a real phone.
- **Lathe**: A/B gain snapshots with one automatable Morph parameter. A
keyswitch note that selects the drawn shape (EQ switch-ups without
automation). A dynamic mode per harmonic.
@@ -270,9 +261,9 @@ one period of the note, so heavy settings do not ripple at f0. See [Planish](pla
3. Planish (done, released 0.1.0), then Quench and Ballast: they fill the mix
and master gap.
- In parallel, from the research findings, in this order: Weld delay
spread (done, unreleased); the fatness lane, as the first Assay piece;
Anvil Ghost harmonics and small speaker listen; Braze; Anvil Kick lock
with offset audition.
spread (done, unreleased); the fatness lane, as the first Assay piece
(prototype `scripts/fatness.py`); Anvil Ghost harmonics and Phone listen
(done, unreleased); Braze; Anvil Kick lock with offset audition.
4. Forge, when enough modules exist.
5. Assay, one plugin for the display-only ideas.
6. Texture plugins (Anneal, Swarf, Etch, Bellows) and the note-keyed sequencer.