feat(knurl): add Knurl cycle texture
Check and Windows preview / check (anvil) (push) Successful in 2m1s
Check and Windows preview / check (crucible) (push) Successful in 1m31s
Check and Windows preview / check (knurl) (push) Successful in 2m4s
Check and Windows preview / check (lathe) (push) Successful in 1m27s
Check and Windows preview / check (patina) (push) Successful in 1m54s
Check and Windows preview / check (rivet) (push) Successful in 1m30s
Check and Windows preview / check (temper) (push) Successful in 1m31s
Check and Windows preview / check (weld) (push) Successful in 2m31s
Check and Windows preview / previews (push) Successful in 1m26s
Independent plugin release / plan (push) Successful in 7s
Check and Windows preview / windows (push) Successful in 2m26s
Independent plugin release / build (push) Successful in 3m0s
Independent plugin release / publish (push) Successful in 8s

Knurl follows the played note and treats every cycle of the wave on its
own: a repeating level pattern over 1-16 cycles makes subharmonics in tune
with every note, random level and timing per cycle add rattle, and a noise
burst per cycle, highpassed at a multiple of f0, adds grit. Amounts are
counted in cycles, so the texture is the same on F1 and on C2.

- Cycle clock from the shared note tracker, restarted at each note; the
  audio is delayed by the lookahead plus 4.2 ms of timing-jitter headroom.
- Per-cycle randomness from a hash of the cycle number: Same every note
  or Free.
- Patterns Off, Double, Triple, Fry (default), Gallop, Stutter or drawn;
  grit switchable per step. Pattern persisted as knurl-pattern.
- Editor: last eight cycles overlaid, pattern bars with the playing step.
- Tests match the prototype: Double gives f0/2 at -8.19 dB, Triple f0/3
  at -10.68 dB, equal on F1 and C2, no added clicks, bit-exact when off,
  no allocation on the audio thread.
This commit is contained in:
nvrl committed 2026-11-06 08:49:11 +01:00
1 parent f4c0a833e6
commit 5cc3770737
27 files changed
+4699 -33

No files matched your search

+4 -2
View File
@@ -25,7 +25,7 @@ Patina has `render` for offline WAV evaluation. The shared crates are:
- `common-ui`: palette, embedded fonts, header, panels, knobs, meters.
- `common-dsp`: filters, YIN pitch tracking, the note tracker used by Anvil,
Lathe and Temper, 4× oversampling, meters and WAV files.
Lathe, Temper and Knurl, 4× oversampling, meters and WAV files.
The wrappers stay separate workspaces, each with its own lockfile, so the
NIH-plug Git dependency stays out of the root workspace. Host identities and
@@ -44,7 +44,8 @@ python3 scripts/check-plugin.py --plugin <product>
python3 -m unittest discover -s scripts/tests -v
```
Products: `rivet`, `patina`, `anvil`, `crucible`, `lathe`, `temper`, `weld`.
Products: `rivet`, `patina`, `anvil`, `crucible`, `lathe`, `temper`, `weld`,
`knurl`.
`check-plugin.py` runs formatting, tests and clippy for one product's packages
and its wrapper, without compiling the other products. Run it for every product
@@ -142,6 +143,7 @@ identify plugins by CLAP ID, so the vendor name does not affect saved projects.
| Lathe | (new) | `io.storyboard.harmonic-eq` |
| Temper | (new) | `io.storyboard.tracked-distortion` |
| Weld | (new) | `io.storyboard.layer-align` |
| Knurl | (new) | `io.storyboard.cycle-texture` |
The `io.storyboard.` prefix is historical and stays, because changing a CLAP ID
breaks existing projects. Rivet keeps `story-session-v1` and its session