Files
bass-foundry/Cargo.toml
T
nvrl adfb2c0287 feat: stable note tracking, NOTE pitch source and unsure fallback
Producers found the tracked plugins jumpy: the shared tracker switched notes
after 10 ms and retuned every 5 ms, so growls and formant basses flickered
and every tracked plugin acted on wrong notes.

Shared tracker (common-dsp):
- A new note needs a steady read for 40 ms; an octave down 80 ms, an octave
  up 200 ms (an octave-up read still fits the note's period and counts as
  agreeing). Inside a note the tuning only moves past a 0.25 semitone
  deadband. Follow bends keeps the old fast behaviour as an option.
- A trust score turns the note unsure while reads disagree; Tracker::active
  and NoteState report it, and Fallback latches "step back" across note ends.
- Notes end when the window start stays below the gate's release level for
  20 ms, so short gaps between notes are seen without waiting for the gate.
- PitchSource replaces the old (midi, gate, glide) arguments: Audio, MIDI or
  Note mode (a set note, no detection), plus a key lock (minor, major, root
  only) that snaps reads to the key.
- stems.rs: synthetic stems (growls, wobble, reese, formant, 808 slide,
  layered drop, noise riser) and a score; examples/tracker_report scores the
  corpus or real WAV stems. On the corpus the old behaviour makes up to 28
  extra note starts per second; the stable default makes none.

Plugins:
- Anvil, Lathe, Temper, Knurl, Planish, Braze and Forge gain the NOTE pitch
  source, the key lock and Follow bends (shared common-params crate and a
  shared header switch in common-ui).
- Unsure tracking: Anvil brings the original sub back in place of the sine,
  Lathe passes the audio through, Knurl fades its texture out; Temper,
  Planish and Braze hold their last sure tuning. Readouts show the note only
  when it is sure.
- Anvil gains Mode: Replace or Enhance (keeps the original sub and adds the
  sine under it).
- Planish slides its band edges over 6 ms on a new note instead of snapping.
- Ballast defaults to Grid parts, which need no tracking.
2026-11-06 21:02:52 +01:00

40 lines
1.8 KiB
TOML

[workspace]
resolver = "2"
members = ["plugins/common/ui", "plugins/common/dsp", "plugins/anvil/core", "plugins/anvil/ui", "plugins/lathe/core", "plugins/lathe/ui", "plugins/temper/core", "plugins/temper/ui", "plugins/weld/core", "plugins/weld/ui", "plugins/knurl/core", "plugins/knurl/ui", "plugins/planish/core", "plugins/planish/ui", "plugins/braze/core", "plugins/braze/ui", "plugins/quench/core", "plugins/quench/ui", "plugins/ballast/core", "plugins/ballast/ui", "plugins/forge/core", "plugins/forge/ui", "plugins/crucible/core", "plugins/crucible/ui", "plugins/rivet/core", "plugins/rivet/midi", "plugins/rivet/preview", "plugins/rivet/app", "plugins/patina/core", "plugins/patina/render", "plugins/patina/ui"]
exclude = ["plugins/common/params", "plugins/rivet/plugin", "tools/editor-check", "plugins/patina/plugin", "plugins/anvil/plugin", "plugins/crucible/plugin", "plugins/lathe/plugin", "plugins/temper/plugin", "plugins/weld/plugin", "plugins/knurl/plugin", "plugins/planish/plugin"]
[workspace.package]
edition = "2021"
license = "ISC"
[workspace.dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
rivet-core = { path = "plugins/rivet/core" }
rivet-midi = { path = "plugins/rivet/midi" }
[profile.release]
lto = "thin"
strip = "symbols"
# Signal-level tests render seconds of audio; unoptimised DSP makes them crawl.
[profile.dev.package.common-dsp]
opt-level = 2
[profile.dev.package.lathe-core]
opt-level = 2
[profile.dev.package.temper-core]
opt-level = 2
[profile.dev.package.knurl-core]
opt-level = 2
[profile.dev.package.planish-core]
opt-level = 2
[profile.dev.package.weld-core]
opt-level = 2
[profile.dev.package.quench-core]
opt-level = 2
[profile.dev.package.ballast-core]
opt-level = 2
[profile.dev.package.forge-core]
opt-level = 2