From 5cc37707374b8a19fa470ae7a4743744211d304b Mon Sep 17 00:00:00 2001 From: Nils Pukropp Date: Fri, 6 Nov 2026 08:47:29 +0100 Subject: [PATCH] feat(knurl): add Knurl cycle texture 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. --- .gitea/workflows/check.yml | 4 +- .gitea/workflows/release.yml | 2 +- Cargo.lock | 19 + Cargo.toml | 7 +- README.md | 11 +- docs/development.md | 6 +- docs/ideas.md | 28 +- docs/knurl/CHANGELOG.md | 14 + docs/knurl/README.md | 86 + docs/knurl/assets/editor.png | Bin 0 -> 297754 bytes docs/releases.md | 1 + plugins/catalog.json | 16 + plugins/knurl/core/Cargo.toml | 12 + plugins/knurl/core/src/lib.rs | 406 +++++ plugins/knurl/core/src/settings.rs | 166 ++ plugins/knurl/core/tests/dsp.rs | 232 +++ plugins/knurl/core/tests/realtime.rs | 70 + plugins/knurl/plugin/Cargo.lock | 2382 ++++++++++++++++++++++++++ plugins/knurl/plugin/Cargo.toml | 26 + plugins/knurl/plugin/src/lib.rs | 195 +++ plugins/knurl/plugin/src/params.rs | 255 +++ plugins/knurl/plugin/tests/host.rs | 227 +++ plugins/knurl/ui/Cargo.toml | 11 + plugins/knurl/ui/src/lib.rs | 501 ++++++ tools/editor-check/Cargo.lock | 20 + tools/editor-check/Cargo.toml | 2 + tools/editor-check/src/main.rs | 33 +- 27 files changed, 4699 insertions(+), 33 deletions(-) create mode 100644 docs/knurl/CHANGELOG.md create mode 100644 docs/knurl/README.md create mode 100644 docs/knurl/assets/editor.png create mode 100644 plugins/knurl/core/Cargo.toml create mode 100644 plugins/knurl/core/src/lib.rs create mode 100644 plugins/knurl/core/src/settings.rs create mode 100644 plugins/knurl/core/tests/dsp.rs create mode 100644 plugins/knurl/core/tests/realtime.rs create mode 100644 plugins/knurl/plugin/Cargo.lock create mode 100644 plugins/knurl/plugin/Cargo.toml create mode 100644 plugins/knurl/plugin/src/lib.rs create mode 100644 plugins/knurl/plugin/src/params.rs create mode 100644 plugins/knurl/plugin/tests/host.rs create mode 100644 plugins/knurl/ui/Cargo.toml create mode 100644 plugins/knurl/ui/src/lib.rs diff --git a/.gitea/workflows/check.yml b/.gitea/workflows/check.yml index a546b90..0a91601 100644 --- a/.gitea/workflows/check.yml +++ b/.gitea/workflows/check.yml @@ -22,7 +22,7 @@ jobs: strategy: fail-fast: false matrix: - plugin: [rivet, patina, anvil, crucible, lathe, temper, weld] + plugin: [rivet, patina, anvil, crucible, lathe, temper, weld, knurl] steps: - uses: https://github.com/actions/checkout@v4 with: @@ -61,6 +61,7 @@ jobs: cargo run --manifest-path tools/editor-check/Cargo.toml --locked -- target/editor/lathe.png --plugin lathe cargo run --manifest-path tools/editor-check/Cargo.toml --locked -- target/editor/temper.png --plugin temper cargo run --manifest-path tools/editor-check/Cargo.toml --locked -- target/editor/weld.png --plugin weld + cargo run --manifest-path tools/editor-check/Cargo.toml --locked -- target/editor/knurl.png --plugin knurl - uses: https://github.com/actions/upload-artifact@v3-node20 with: name: editor-previews @@ -91,6 +92,7 @@ jobs: python3 scripts/build-plugin.py --plugin lathe --target x86_64-pc-windows-gnu python3 scripts/build-plugin.py --plugin temper --target x86_64-pc-windows-gnu python3 scripts/build-plugin.py --plugin weld --target x86_64-pc-windows-gnu + python3 scripts/build-plugin.py --plugin knurl --target x86_64-pc-windows-gnu python3 scripts/package-windows.py - uses: https://github.com/actions/upload-artifact@v3-node20 with: diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index e25073a..9ea3625 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -1,7 +1,7 @@ name: Independent plugin release on: push: - tags: ["rivet-v*", "patina-v*", "anvil-v*", "crucible-v*", "lathe-v*", "temper-v*", "weld-v*"] + tags: ["rivet-v*", "patina-v*", "anvil-v*", "crucible-v*", "lathe-v*", "temper-v*", "weld-v*", "knurl-v*"] permissions: contents: read diff --git a/Cargo.lock b/Cargo.lock index b014de6..121bd91 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -170,6 +170,25 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +[[package]] +name = "knurl-core" +version = "0.1.0" +dependencies = [ + "common-dsp", + "serde", + "serde_json", +] + +[[package]] +name = "knurl-ui" +version = "0.1.0" +dependencies = [ + "common-dsp", + "common-ui", + "egui", + "knurl-core", +] + [[package]] name = "lathe-core" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 7b1f391..9f38650 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [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/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/rivet/plugin", "tools/editor-check", "plugins/patina/plugin", "plugins/anvil/plugin", "plugins/crucible/plugin", "plugins/lathe/plugin", "plugins/temper/plugin", "plugins/weld/plugin"] +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/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/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"] [workspace.package] edition = "2021" @@ -24,5 +24,8 @@ opt-level = 2 opt-level = 2 [profile.dev.package.temper-core] opt-level = 2 +[profile.dev.package.knurl-core] +opt-level = 2 + [profile.dev.package.weld-core] opt-level = 2 diff --git a/README.md b/README.md index 07e5ba9..ba3021d 100644 --- a/README.md +++ b/README.md @@ -25,16 +25,18 @@ note. Each plugin is a separate product with its own version, guide and release. | **[Lathe](docs/lathe/README.md)** | EQ with one band on each harmonic of the played note: a cut on harmonic 3 stays on harmonic 3 | Bass, after the synth | ≈ 67 ms | [Guide](docs/lathe/README.md) · [Changes](docs/lathe/CHANGELOG.md) | | **[Temper](docs/temper/README.md)** | Distortion that drives every note the same: level and tone filters follow the note | Bass | ≈ 67 ms + oversampling | [Guide](docs/temper/README.md) · [Changes](docs/temper/CHANGELOG.md) | | **[Weld](docs/weld/README.md)** | Phase-aligns one bass layer to another layer through the sidechain, so the layers sum in the mids instead of cancelling | One layer's track, other layer as sidechain | none | [Guide](docs/weld/README.md) · [Changes](docs/weld/CHANGELOG.md) | +| **[Knurl](docs/knurl/README.md)** | Gives every cycle of the note its own level, timing and grit: in-tune subharmonic growl, rattle and fry on every note | Bass | ≈ 71 ms | [Guide](docs/knurl/README.md) · [Changes](docs/knurl/CHANGELOG.md) | Plugins with latency report it to the host, so FL Studio compensates the delay. -Anvil, Lathe and Temper detect pitch from the audio. They can also take the +Anvil, Lathe, Temper and Knurl detect pitch from the audio. They can also take the pitch from MIDI. The names come from metalwork: a **rivet** joins pieces; **patina** changes a surface and keeps its character; an **anvil** is the solid base that everything is struck on; a **crucible** melts material down to be cast again; a **lathe** turns a piece so each cut lands the same all the way round; **tempering** sets -how hard and how tough a metal ends up; a **weld** fuses two pieces into one. +how hard and how tough a metal ends up; a **weld** fuses two pieces into one; +**knurling** presses a ridged grip pattern into a surface. The suite is the **foundry**: the workshop where the bass gets cast, shaped and finished. Hosts list the plugins under the vendor name *Bass Foundry*. @@ -55,7 +57,7 @@ finished. Hosts list the plugins under the vendor name *Bass Foundry*. Weld editor
Weld: layer phase alignment - + Knurl editor
Knurl: cycle texture @@ -115,7 +117,7 @@ cargo run --manifest-path tools/editor-check/Cargo.toml -- target/editor/lathe.p ``` Plugin names for the scripts are `rivet`, `patina`, `anvil`, `crucible`, -`lathe`, `temper` and `weld`. Builds go to `dist//.clap`. No +`lathe`, `temper`, `weld` and `knurl`. Builds go to `dist//.clap`. No script installs anything into a DAW. [Development and testing](docs/development.md) has the full command list. @@ -152,6 +154,7 @@ plugins/ lathe/ core · ui · plugin temper/ core · ui · plugin weld/ core · ui · plugin + knurl/ core · ui · plugin common/ ui/ Shared look: palette, embedded fonts, knobs, panels, meters dsp/ Shared filters, pitch tracking, oversampling, meters, WAV files diff --git a/docs/development.md b/docs/development.md index 4466d70..7c256e0 100644 --- a/docs/development.md +++ b/docs/development.md @@ -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 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 diff --git a/docs/ideas.md b/docs/ideas.md index a794618..5209880 100644 --- a/docs/ideas.md +++ b/docs/ideas.md @@ -75,6 +75,14 @@ delay), so the layers sum instead of cancel. A display shows how much level the cancellation cost and how much Weld recovered. Anvil solves the sub band; Weld solves the mids. See [Weld](weld/README.md). +### Knurl — cycle texture (problems 11, 13) + +Follows the played note and treats every cycle on its own: a repeating level +pattern (in-tune subharmonics), random level and timing per cycle, and a noise +burst per cycle tuned to the note. Amounts are counted in cycles, so the texture +is the same on every note. Slow per-harmonic drift is postponed. See +[Knurl](knurl/README.md). + ## Ideas ### Ballast — switch-up loudness leveller (problem 2) @@ -113,27 +121,11 @@ bars 2–4". No name yet. ## Texture ideas -These ideas target problems 11–15. Most of them reuse the note tracker in +These ideas target problems 11–15; Knurl, the first of them, is released above. +Most of them reuse the note tracker in `common-dsp`, so a texture setting means the same thing on every note, the same way Lathe and Temper work. -### Knurl — pitch-synchronous grit (problems 11, 13) - -Knurling presses a ridged pattern into metal. Knurl cuts the signal into single -pitch periods with the note tracker and changes each period on its own: - -- level and timing jitter per cycle; -- short noise bursts locked to the cycle; -- period doubling and tripling (a cycle pattern such as "loud, quiet, quiet"), - which gives the subharmonic rattle and growl of riddim basses; -- slow random drift of each harmonic's level and phase, which brings movement - into a printed resample without widening it. - -Rates are in cycles, not in Hz or tempo, so the grit has the same grain on F1 -and on C2. A pattern editor sets 1–16 cycles. Everything is mono-safe. Latency -is the tracker lookahead, about 67 ms. Recommended first texture build: it is -new, small, and reuses Lathe's tracking. - ### Anneal — tone and grit split (problem 12) Annealing changes how a metal behaves without changing its shape. Anneal diff --git a/docs/knurl/CHANGELOG.md b/docs/knurl/CHANGELOG.md new file mode 100644 index 0000000..342bb47 --- /dev/null +++ b/docs/knurl/CHANGELOG.md @@ -0,0 +1,14 @@ +# Knurl changelog + +## 0.1.0 + +- Introduce Knurl, texture per cycle of the played note. +- Step patterns over 1–16 cycles make subharmonics in tune with every note: + Off, Double, Triple, Fry, Gallop, Stutter, or a drawn pattern. +- Random level and timing per cycle, and a noise burst per cycle tuned to the + note (Tone, Position, Length), switchable per step. +- Same every note or Free random sequences. +- Detect pitch and note starts from the audio with about 71 ms of latency, or + follow MIDI notes sent to the effect. +- Editor shows the last eight cycles overlaid and the pattern with the playing + step. diff --git a/docs/knurl/README.md b/docs/knurl/README.md new file mode 100644 index 0000000..e770550 --- /dev/null +++ b/docs/knurl/README.md @@ -0,0 +1,86 @@ +# Knurl + +Knurl gives every cycle of the note its own level, timing and grit. Current +version **0.1.0**. + +Knurling presses a ridged pattern into metal. Riddim and dubstep basses get their +character the same way, from surface texture: rattle, growl, fry, grit. Usually +that texture comes from long chains of distortion, comb filters, formants and +resampling, and it changes from note to note. Knurl works on single cycles of the +wave instead. It follows the played note and treats each cycle on its own, and +every amount is counted in cycles, not in Hz or tempo. So the texture has the +same grain on F1 and on C2. + +![Knurl](assets/editor.png) + +## Install on Windows + +Copy `Knurl.clap` into `C:\Program Files\Common Files\CLAP\`. In FL Studio 2024.1 +or newer, open Options → Manage plugins, enable Verify plugins, and Find installed +plugins. Load Knurl in a mixer slot of the bass. Keep the font license with +redistributed packages. + +## Work with it + +1. Play the bass. The note readout shows what Knurl tracks; the scope overlays + the last eight cycles of the output, so the texture is visible cycle by cycle. +2. Choose a **Pattern**. The pattern sets the level of each cycle and repeats: + - **Double** (0, −9 dB): every second cycle quieter. This makes a sub-octave + growl, exactly in tune, about 8 dB under the fundamental. + - **Triple** (0, −12, −12 dB): a growl an octave and a fifth down. + - **Fry** (0, −14, −5, −14 dB, the default): an uneven vocal-fry rattle. + - **Gallop** and **Stutter**: rhythmic patterns over six and eight cycles. + - **Off**: every cycle at full level. +3. Draw your own pattern on the bars: drag a bar to set the level of that cycle, + double-click to reset it. **Steps** sets the length (1–16 cycles). +4. Add surface: + - **Level** gives every cycle a random level (standard deviation in dB). + - **Time** moves every cycle a little in time (percent of a period): rattle + and scrape. + - **Grit** adds a short noise burst inside every cycle. **Tone** sets its + lowest frequency in harmonics of the note, **Position** where in the cycle + it sits, and **Length** how long it is. The squares under the pattern bars + switch the burst per step. +5. **Edge** sets how soft each step change is. Low values are sharper and + buzzier; high values smoother. + +**Random**: **Same every note** (default) restarts every random sequence at each +note, so identical notes sound identical, which keeps a riddim line tight. +**Free** lets the sequences run on, so every note differs. + +**Mix** blends with the delayed dry signal; **Output** trims the level. + +### Pitch from MIDI + +For basses whose fundamental is unclear (heavy FM, formant or noise patches), +select **MIDI** and route the bass's MIDI notes to Knurl. In FL Studio, set the +bass channel's MIDI output port and Knurl's input port to the same number. +**Gate** sets the input level that counts as a note in AUDIO mode; **Snap to +semitone** rounds the detected pitch (turn it off for slides). + +## Timing and limits + +Knurl delays the audio by about 71 ms: 67 ms of pitch-detection lookahead plus +4 ms of room for the timing jitter. The delay is reported to the host for delay +compensation, so the cycle clock knows every note before its attack leaves the +plugin. The cycle clock restarts at every note start, so the pattern always +begins with step 1 on the attack. Pitch range is 30–500 Hz, one note at a time. +Between notes the effects fade out over 20 ms, so tails stay clean. + +Knurl works per cycle of the tracked pitch; it does not look for cycle borders in +the waveform. With a stable pitch that is the same thing. With heavy pitch +modulation inside a note the pattern follows the tracked pitch, which can lag a +fast bend. Both channels get the same treatment, so the effect is mono-safe. + +## How it works + +A note tracker (shared with Anvil, Lathe and Temper) detects pitch and note +starts ahead of the delayed audio. A cycle clock starts at 0 on every note and +advances by f0 / sample rate. Each cycle gets its step gain and its random level +and time offset from a hash of the cycle number, so the result is deterministic. +Step changes are raised-cosine crossfades over the last **Edge** of a cycle; +level jitter crossfades over half a cycle and time jitter over the whole cycle, +read from the delay line with cubic interpolation. The grit is white noise +through a state-variable highpass at **Tone** × f0, shaped by a sin² window and +scaled to the input level. There is no nonlinearity, so no oversampling is +needed. diff --git a/docs/knurl/assets/editor.png b/docs/knurl/assets/editor.png new file mode 100644 index 0000000000000000000000000000000000000000..ee529b5f0d264a2b0b1747e25b99586542c10cf8 GIT binary patch literal 297754 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�xL7aPT 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 literal 0 HcmV?d00001 diff --git a/docs/releases.md b/docs/releases.md index 8cd64cb..2a2415b 100644 --- a/docs/releases.md +++ b/docs/releases.md @@ -14,6 +14,7 @@ workflows are in `.gitea/workflows/`. A plugin's version is the `version` in | Lathe | `lathe-v0.1.0` | `lathe-windows-x86_64-0.1.0.zip` | | Temper | `temper-v0.1.0` | `temper-windows-x86_64-0.1.0.zip` | | Weld | `weld-v0.1.0` | `weld-windows-x86_64-0.1.0.zip` | +| Knurl | `knurl-v0.1.0` | `knurl-windows-x86_64-0.1.0.zip` | ## Make a release diff --git a/plugins/catalog.json b/plugins/catalog.json index d00b722..cd62aac 100644 --- a/plugins/catalog.json +++ b/plugins/catalog.json @@ -114,5 +114,21 @@ "weld-core", "weld-ui" ] + }, + "knurl": { + "name": "Knurl", + "description": "Give every cycle of the note its own level, timing and grit", + "manifest": "plugins/knurl/plugin/Cargo.toml", + "library": "knurl", + "documentation": "docs/knurl", + "clap_id": "io.storyboard.cycle-texture", + "licenses": { + "plugins/common/ui/assets/OFL.txt": "licenses/Roboto-OFL.txt" + }, + "packages": [ + "common-ui", + "knurl-core", + "knurl-ui" + ] } } diff --git a/plugins/knurl/core/Cargo.toml b/plugins/knurl/core/Cargo.toml new file mode 100644 index 0000000..562b805 --- /dev/null +++ b/plugins/knurl/core/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "knurl-core" +version = "0.1.0" +edition.workspace = true +license.workspace = true + +[dependencies] +common-dsp = { path = "../../common/dsp" } +serde = { workspace = true } + +[dev-dependencies] +serde_json = { workspace = true } diff --git a/plugins/knurl/core/src/lib.rs b/plugins/knurl/core/src/lib.rs new file mode 100644 index 0000000..5fb3d3f --- /dev/null +++ b/plugins/knurl/core/src/lib.rs @@ -0,0 +1,406 @@ +//! Knurl: texture per cycle of the played note. A cycle clock follows the tracked pitch and +//! restarts at every note; each cycle gets its own step gain (a repeating pattern that +//! makes subharmonics), a random level and timing, and a noise burst tuned to the note. +//! Every amount is counted in cycles, so the texture has the same grain on every note. +//! +//! The audio path is delayed by the tracker lookahead plus the timing-jitter headroom, so +//! the clock already knows each note when its attack leaves the plugin. Allocation-free +//! after `new`; mono-safe (both channels get the same treatment). +mod settings; +use common_dsp::svf::{Svf, SvfCoef}; +use common_dsp::tracker::{PitchFollower, Tracker, TrackerConfig}; +use common_dsp::{coefficient, db_to_gain, hz_to_midi}; +pub use settings::{Seed, Settings, Source, GRIT_OFF, PATTERNS, STEPS, STEP_MIN}; + +/// Cycles kept for the editor's scope, and points per cycle. +pub const SCOPE_CYCLES: usize = 8; +pub const SCOPE_POINTS: usize = 64; +/// Timing jitter can move a cycle by at most this share of the lowest period. +const JITTER_HEADROOM: f32 = 0.125; +/// Effects fade in and out with the note over this time. +const FADE_MS: f32 = 20.; +/// The grit filter is retuned this often, in samples. +const RETUNE: usize = 16; +/// Level follower for scaling the grit to the input. +const LEVEL_MS: f32 = 30.; + +#[derive(Clone, Copy, Debug)] +pub struct AnalyzerFrame { + /// Fundamental the clock follows, 0 before the first note. + pub hz: f32, + /// Sounding note, rounded; None between notes. + pub note: Option, + /// Pattern step of the newest cycle. + pub step: usize, + /// Output of the last `SCOPE_CYCLES` cycles, oldest first, each resampled to + /// `SCOPE_POINTS` points. + pub scope: [[f32; SCOPE_POINTS]; SCOPE_CYCLES], + /// True when the scope holds cycles of a sounding note. + pub scope_valid: bool, + pub input_db: f32, + pub output_db: f32, + pub latency: u32, + pub sample_rate: f32, +} +impl Default for AnalyzerFrame { + fn default() -> Self { + Self { + hz: 0., + note: None, + step: 0, + scope: [[0.; SCOPE_POINTS]; SCOPE_CYCLES], + scope_valid: false, + input_db: -120., + output_db: -120., + latency: 0, + sample_rate: 48000., + } + } +} + +/// Deterministic per-cycle randomness: a hash of (stream, note seed, cycle). +fn hash(stream: u64, seed: u64, cycle: u64) -> u64 { + let mut z = stream + .wrapping_mul(0x9E37_79B9_7F4A_7C15) + .wrapping_add(seed.wrapping_mul(0xBF58_476D_1CE4_E5B9)) + .wrapping_add(cycle.wrapping_mul(0x94D0_49BB_1331_11EB)); + z = (z ^ (z >> 30)).wrapping_mul(0xBF58_476D_1CE4_E5B9); + z = (z ^ (z >> 27)).wrapping_mul(0x94D0_49BB_1331_11EB); + z ^ (z >> 31) +} +fn uniform(stream: u64, seed: u64, cycle: u64) -> f32 { + (hash(stream, seed, cycle) >> 40) as f32 / (1u64 << 24) as f32 +} +/// Approximately normal, clamped to ±3 (sum of four uniforms, unit variance). +fn normal(stream: u64, seed: u64, cycle: u64) -> f32 { + let s: f32 = (0..4).map(|i| uniform(stream, seed, cycle * 4 + i)).sum(); + ((s - 2.) * 3f32.sqrt()).clamp(-3., 3.) +} +/// Raised-cosine weight of the next cycle's value: 0 until `1 − width` of the cycle, then +/// rising to 1 at the boundary. +fn edge(frac: f32, width: f32) -> f32 { + let t = ((frac - (1. - width)) / width).clamp(0., 1.); + 0.5 - 0.5 * (std::f32::consts::PI * t).cos() +} + +const LEVEL: u64 = 1; +const TIME: u64 = 2; +const NOISE: u64 = 3; + +/// What the clock needs, delayed by the jitter headroom so it lines up with the audio. +#[derive(Clone, Copy, Default)] +struct Pitch { + hz: f32, + start: bool, + sounding: bool, +} + +pub struct Engine { + rate: f32, + channels: usize, + settings: Settings, + /// Tracker lookahead. + lookahead: usize, + /// Largest timing offset in samples, either way. + headroom: usize, + tracker: Tracker, + pitch: PitchFollower, + pitch_line: Vec, + pitch_at: usize, + audio: Vec<[f32; 2]>, + audio_at: usize, + // Cycle clock. + phase: f64, + cycle: u64, + note_seed: u64, + notes: u64, + noise_at: u64, + amount: f32, + fade: f32, + // Grit. + grit_coef: SvfCoef, + grit_filter: Svf, + countdown: usize, + level: f32, + level_coef: f32, + // Smoothed controls. + smooth: f32, + mix: f32, + output: f32, + bypass: f32, + fresh: bool, + // Editor. + scope: [[f32; SCOPE_POINTS]; SCOPE_CYCLES], + scope_valid: bool, + meter_in: f64, + meter_out: f64, + meter_count: usize, +} + +impl Engine { + pub fn new(rate: f32, channels: usize) -> Result { + if !(rate.is_finite() && (8000.0..=768000.).contains(&rate)) { + return Err("unsupported sample rate"); + } + if !(1..=2).contains(&channels) { + return Err("unsupported channel count"); + } + let tracker = Tracker::new(rate, TrackerConfig::BASS); + let lookahead = tracker.latency(); + let headroom = (JITTER_HEADROOM * rate / TrackerConfig::BASS.min_hz).ceil() as usize; + let settings = Settings::default(); + let mut e = Self { + rate, + channels, + settings, + lookahead, + headroom, + tracker, + pitch: PitchFollower::default(), + pitch_line: vec![Pitch::default(); headroom + 1], + pitch_at: 0, + // Reads reach `lookahead + 2·headroom` back, plus the interpolation taps. + audio: vec![[0.; 2]; lookahead + 2 * headroom + 4], + audio_at: 0, + phase: 0., + cycle: 0, + note_seed: 0, + notes: 0, + noise_at: 0, + amount: 0., + fade: coefficient(rate, FADE_MS), + grit_coef: SvfCoef::IDENTITY, + grit_filter: Svf::default(), + countdown: 0, + level: 0., + level_coef: coefficient(rate, LEVEL_MS), + smooth: coefficient(rate, 10.), + mix: 1., + output: 1., + bypass: 0., + fresh: true, + scope: [[0.; SCOPE_POINTS]; SCOPE_CYCLES], + scope_valid: false, + meter_in: 0., + meter_out: 0., + meter_count: 0, + }; + e.set_settings(settings)?; + e.fresh = true; + Ok(e) + } + pub fn latency_samples(&self) -> u32 { + (self.lookahead + self.headroom) as u32 + } + pub fn channels(&self) -> usize { + self.channels + } + pub fn settings(&self) -> Settings { + self.settings + } + pub fn set_settings(&mut self, s: Settings) -> Result<(), &'static str> { + s.validate()?; + self.tracker.set(s.source == Source::Midi, s.gate, false); + self.settings = s; + if std::mem::take(&mut self.fresh) { + self.mix = s.mix * 0.01; + self.output = db_to_gain(s.output); + self.bypass = f32::from(s.bypass); + } + Ok(()) + } + pub fn reset(&mut self) { + self.audio.fill([0.; 2]); + self.pitch_line.fill(Pitch::default()); + self.pitch = PitchFollower::default(); + self.tracker.reset(); + self.grit_filter.reset(); + self.phase = 0.; + self.cycle = 0; + self.notes = 0; + self.note_seed = 0; + self.noise_at = 0; + self.amount = 0.; + self.level = 0.; + self.countdown = 0; + self.scope_valid = false; + self.fresh = true; + } + pub fn note_on(&mut self, note: u8) { + self.tracker.note_on(note); + } + pub fn note_off(&mut self, note: u8) { + self.tracker.note_off(note); + } + /// The audio `back` samples (fractional) before the newest one, cubic Hermite. + #[inline] + fn read(&self, back: f32) -> [f32; 2] { + let len = self.audio.len(); + let whole = back.floor(); + let t = back - whole; + let base = whole as usize; + let at = |back: usize| self.audio[(self.audio_at + len - back % len) % len]; + // y0 is one sample newer than y1; y2 and y3 are older. + let (newer, p1, p2, p3) = (at(base.max(1) - 1), at(base), at(base + 1), at(base + 2)); + let mut out = [0.; 2]; + for c in 0..2 { + let (y0, y1, y2, y3) = (newer[c], p1[c], p2[c], p3[c]); + let c1 = 0.5 * (y2 - y0); + let c2 = y0 - 2.5 * y1 + 2. * y2 - 0.5 * y3; + let c3 = 0.5 * (y3 - y0) + 1.5 * (y1 - y2); + out[c] = ((c3 * t + c2) * t + c1) * t + y1; + } + out + } + pub fn process_sample(&mut self, x: [f32; 2]) -> [f32; 2] { + let mono = if self.channels == 2 { + 0.5 * (x[0] + x[1]) + } else { + x[0] + }; + let (pitch, snap) = (&mut self.pitch, self.settings.snap); + self.tracker.process(mono, |e| pitch.event(snap, e)); + let (hz, jump) = self.pitch.step(1.); + // Tracker events are timed for `lookahead`; the audio leaves `headroom` later. + let len = self.pitch_line.len(); + self.pitch_line[self.pitch_at] = Pitch { + hz, + start: jump, + sounding: self.tracker.sounding(), + }; + self.pitch_at = (self.pitch_at + 1) % len; + let p = self.pitch_line[self.pitch_at]; + + let len = self.audio.len(); + self.audio_at = (self.audio_at + 1) % len; + self.audio[self.audio_at] = x; + let centre = (self.lookahead + self.headroom) as f32; + let dry = self.read(centre); + + // Cycle clock. + if p.start { + self.phase = 0.; + self.cycle = 0; + self.notes += 1; + self.noise_at = 0; + self.note_seed = match self.settings.seed { + Seed::Same => 0, + Seed::Free => self.notes, + }; + self.countdown = 0; + } + let active = p.sounding && p.hz > 0.; + self.amount += (f32::from(active) - self.amount) * self.fade; + let s = self.settings; + let frac = self.phase.fract() as f32; + let c = self.cycle; + let seed = self.note_seed; + let step = |k: u64| (k % s.steps as u64) as usize; + + // Pattern and level jitter, crossfaded into the next cycle. + let w = edge(frac, s.edge * 0.01); + let jitter_w = edge(frac, 0.5); + let pattern = |k: u64| db_to_gain(s.pattern[step(k)]); + let wobble = |k: u64| db_to_gain(s.level_jitter * normal(LEVEL, seed, k)); + let gain = (pattern(c) * (1. - w) + pattern(c + 1) * w) + * (wobble(c) * (1. - jitter_w) + wobble(c + 1) * jitter_w); + let gain = 1. + self.amount * (gain - 1.); + + // Timing jitter: an offset per cycle, blended across the whole cycle. + let period = if p.hz > 0. { self.rate / p.hz } else { 0. }; + let shift = |k: u64| normal(TIME, seed, k) * s.time_jitter * 0.01 * period; + let tw = edge(frac, 1.); + let offset = (shift(c) * (1. - tw) + shift(c + 1) * tw) * self.amount; + let offset = offset.clamp(-(self.headroom as f32), self.headroom as f32); + let moved = if offset == 0. { + dry + } else { + self.read(centre + offset) + }; + + // Grit: noise above `tone` harmonics, in a sin² window at `position` of each cycle. + let mut grit = 0.; + if s.grit > GRIT_OFF && p.hz > 0. && s.grit_steps[step(c)] { + if self.countdown == 0 { + let f = (s.tone * p.hz).min(0.45 * self.rate); + self.grit_coef = SvfCoef::highpass(self.rate, f, std::f32::consts::FRAC_1_SQRT_2); + self.countdown = RETUNE; + } + self.countdown -= 1; + self.noise_at = self.noise_at.wrapping_add(1); + let n = 2. * uniform(NOISE, seed, self.noise_at) - 1.; + let hp = self.grit_filter.process(&self.grit_coef, n * 3f32.sqrt()); + let d = (frac - s.position * 0.01).rem_euclid(1.); + let l = s.length * 0.01; + if d < l { + let window = (std::f32::consts::PI * d / l).sin().powi(2); + grit = hp * window * self.level.sqrt() * db_to_gain(s.grit) * self.amount; + } + } + let m = if self.channels == 2 { + 0.5 * (dry[0] + dry[1]) + } else { + dry[0] + }; + self.level += (m * m - self.level) * self.level_coef; + // Advance the clock. + if p.hz > 0. { + self.phase += (p.hz / self.rate) as f64; + let whole = self.phase.floor() as u64; + if whole > 0 { + self.phase -= whole as f64; + self.cycle += whole; + self.scope + .rotate_left(whole.min(SCOPE_CYCLES as u64) as usize); + self.scope[SCOPE_CYCLES - 1] = [0.; SCOPE_POINTS]; + } + } + + self.mix += (s.mix * 0.01 - self.mix) * self.smooth; + self.output += (db_to_gain(s.output) - self.output) * self.smooth; + self.bypass += (f32::from(s.bypass) - self.bypass) * self.smooth; + let mut out = [0.; 2]; + for ch in 0..self.channels { + let wet = moved[ch] * gain + grit; + let mixed = (self.mix * wet + (1. - self.mix) * dry[ch]) * self.output; + out[ch] = mixed * (1. - self.bypass) + dry[ch] * self.bypass; + } + let o = if self.channels == 2 { + 0.5 * (out[0] + out[1]) + } else { + out[0] + }; + if active { + let i = ((frac * SCOPE_POINTS as f32) as usize).min(SCOPE_POINTS - 1); + self.scope[SCOPE_CYCLES - 1][i] = o; + self.scope_valid = true; + } + self.meter_in += (m * m) as f64; + self.meter_out += (o * o) as f64; + self.meter_count += 1; + out + } + /// Editor data; levels are averaged since the previous call. + pub fn take_analyzer(&mut self) -> AnalyzerFrame { + let n = self.meter_count.max(1) as f64; + let db = |p: f64| (10. * (p / n).max(1e-12).log10()).max(-120.) as f32; + let mut f = AnalyzerFrame { + hz: self.pitch.hz(), + note: None, + step: (self.cycle % self.settings.steps as u64) as usize, + scope: self.scope, + scope_valid: self.scope_valid, + input_db: db(self.meter_in), + output_db: db(self.meter_out), + latency: self.latency_samples(), + sample_rate: self.rate, + }; + if self.tracker.sounding() && f.hz > 0. { + f.note = Some(hz_to_midi(f.hz).round().clamp(0., 127.) as u8); + } + self.meter_in = 0.; + self.meter_out = 0.; + self.meter_count = 0; + f + } +} diff --git a/plugins/knurl/core/src/settings.rs b/plugins/knurl/core/src/settings.rs new file mode 100644 index 0000000..ff5c5a3 --- /dev/null +++ b/plugins/knurl/core/src/settings.rs @@ -0,0 +1,166 @@ +//! Host-independent controls. Gains in dB; amounts relative to one cycle in percent. +use serde::{Deserialize, Serialize}; + +/// Pattern steps: one per cycle, repeating. +pub const STEPS: usize = 16; +pub const STEP_MIN: f32 = -24.; +/// Grit at or below this level is off. +pub const GRIT_OFF: f32 = -60.; + +#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Default)] +pub enum Source { + /// Pitch and note starts are detected from the incoming bass. + #[default] + Audio, + /// Notes come from MIDI note input. + Midi, +} + +#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Default)] +pub enum Seed { + /// Every note gets the same random sequence, so identical notes sound identical. + #[default] + Same, + /// The random sequences keep running from note to note. + Free, +} + +#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)] +#[serde(deny_unknown_fields)] +pub struct Settings { + pub source: Source, + /// Gain per pattern step, 0 down to `STEP_MIN`. + pub pattern: [f32; STEPS], + /// Steps that get a grit burst. + pub grit_steps: [bool; STEPS], + /// Pattern length in cycles, 1..=STEPS. + pub steps: usize, + /// Crossfade into the next step, as a share of a cycle. + pub edge: f32, + /// Random level per cycle, standard deviation in dB. + pub level_jitter: f32, + /// Random timing per cycle, standard deviation in percent of a period. + pub time_jitter: f32, + /// Grit burst level relative to the input, dB; `GRIT_OFF` or lower is off. + pub grit: f32, + /// Grit highpass, in harmonics of the note. + pub tone: f32, + /// Where in the cycle the grit burst sits, percent. + pub position: f32, + /// Grit burst length, percent of a cycle. + pub length: f32, + pub seed: Seed, + /// Detection threshold in dBFS for note starts (Audio source). + pub gate: f32, + /// Round detected pitch to the nearest semitone. + pub snap: bool, + pub mix: f32, + pub output: f32, + pub bypass: bool, +} + +/// Named step patterns: (name, help, gains). Missing steps are 0 dB. +pub const PATTERNS: [(&str, &str, &[f32]); 6] = [ + ("Off", "Every cycle at full level.", &[0.]), + ( + "Double", + "Every second cycle quieter: a sub-octave growl.", + &[0., -9.], + ), + ( + "Triple", + "One loud cycle, two quiet: a growl an octave and a fifth down.", + &[0., -12., -12.], + ), + ( + "Fry", + "Uneven four-cycle pattern: vocal-fry rattle.", + &[0., -14., -5., -14.], + ), + ( + "Gallop", + "Loud, quiet, loud, then three quiet: a rolling gallop.", + &[0., -18., 0., -18., -18., -18.], + ), + ( + "Stutter", + "Bursts of cycles with gaps: a gated stutter.", + &[0., 0., -24., -24., 0., -24., -24., -24.], + ), +]; + +impl Settings { + /// Applies a named pattern: its gains, its length, grit on every step. + pub fn apply_pattern(&mut self, gains: &[f32]) { + self.pattern = [0.; STEPS]; + for (p, g) in self.pattern.iter_mut().zip(gains) { + *p = *g; + } + self.steps = gains.len().clamp(1, STEPS); + } +} + +impl Default for Settings { + fn default() -> Self { + let mut s = Self { + source: Source::Audio, + pattern: [0.; STEPS], + grit_steps: [true; STEPS], + steps: 1, + edge: 15., + level_jitter: 1., + time_jitter: 3., + grit: -9., + tone: 12., + position: 10., + length: 12., + seed: Seed::Same, + gate: -42., + snap: true, + mix: 100., + output: 0., + bypass: false, + }; + s.apply_pattern(PATTERNS[3].2); + s + } +} +impl Settings { + pub fn validate(&self) -> Result<(), &'static str> { + let finite = [ + self.edge, + self.level_jitter, + self.time_jitter, + self.grit, + self.tone, + self.position, + self.length, + self.gate, + self.mix, + self.output, + ] + .iter() + .chain(self.pattern.iter()) + .all(|v| v.is_finite()); + if !finite { + return Err("non-finite setting"); + } + let ok = self.pattern.iter().all(|g| (STEP_MIN..=0.).contains(g)) + && (1..=STEPS).contains(&self.steps) + && (5.0..=50.).contains(&self.edge) + && (0.0..=6.).contains(&self.level_jitter) + && (0.0..=10.).contains(&self.time_jitter) + && (GRIT_OFF..=0.).contains(&self.grit) + && (4.0..=64.).contains(&self.tone) + && (0.0..=100.).contains(&self.position) + && (2.0..=50.).contains(&self.length) + && (-60.0..=-20.).contains(&self.gate) + && (0.0..=100.).contains(&self.mix) + && (-12.0..=12.).contains(&self.output); + if ok { + Ok(()) + } else { + Err("setting out of range") + } + } +} diff --git a/plugins/knurl/core/tests/dsp.rs b/plugins/knurl/core/tests/dsp.rs new file mode 100644 index 0000000..2d1a27c --- /dev/null +++ b/plugins/knurl/core/tests/dsp.rs @@ -0,0 +1,232 @@ +use common_dsp::{midi_to_hz, Saw}; +use knurl_core::{Engine, Seed, Settings, Source, GRIT_OFF, PATTERNS}; + +const RATE: f32 = 48000.; + +/// A tanh saw bass at `note`, as the prototype used. +fn bass(note: u8, n: usize) -> Vec { + let mut saw = Saw::new(RATE, midi_to_hz(note as f32)); + (0..n).map(|_| (2.2 * saw.sample()).tanh() * 0.5).collect() +} +fn plain() -> Settings { + let mut s = Settings { + source: Source::Midi, + level_jitter: 0., + time_jitter: 0., + grit: GRIT_OFF, + ..Settings::default() + }; + s.apply_pattern(PATTERNS[0].2); + s +} +/// Runs one held note from sample 0 and returns the output, aligned to the input. +fn run(settings: Settings, note: u8, input: &[f32]) -> Vec { + let mut engine = Engine::new(RATE, 1).unwrap(); + engine.set_settings(settings).unwrap(); + let latency = engine.latency_samples() as usize; + engine.note_on(note); + let mut out: Vec = input + .iter() + .chain(std::iter::repeat_n(&0., latency)) + .map(|&x| engine.process_sample([x, 0.])[0]) + .collect(); + out.drain(..latency); + out +} +/// Level of the component at `hz` (single-bin DFT with a Hann window), dB. +fn level(x: &[f32], hz: f32) -> f64 { + let n = x.len(); + let (mut re, mut im) = (0f64, 0f64); + for (i, &v) in x.iter().enumerate() { + let w = 0.5 - 0.5 * (std::f64::consts::TAU * i as f64 / n as f64).cos(); + let a = std::f64::consts::TAU * hz as f64 * i as f64 / RATE as f64; + re += w * v as f64 * a.cos(); + im -= w * v as f64 * a.sin(); + } + 10. * (re * re + im * im).max(1e-30).log10() +} +fn subharmonic(out: &[f32], note: u8, divisor: f32) -> f64 { + let f = midi_to_hz(note as f32); + let seg = &out[4800..out.len() - 4800]; + level(seg, f / divisor) - level(seg, f) +} +fn max_step(x: &[f32]) -> f32 { + x.windows(2).map(|w| (w[1] - w[0]).abs()).fold(0., f32::max) +} + +#[test] +fn everything_off_is_the_delayed_input() { + let input = bass(29, 24000); + let out = run(plain(), 29, &input); + assert_eq!(out, input); +} + +#[test] +fn patterns_make_tuned_subharmonics_without_clicks() { + let input = bass(29, 48000); + let base = run(plain(), 29, &input); + assert!(subharmonic(&base, 29, 2.) < -50.); + for (pattern, divisor, expected) in [(1, 2., -8.2), (2, 3., -10.7)] { + let mut s = plain(); + s.apply_pattern(PATTERNS[pattern].2); + let out = run(s, 29, &input); + let sub = subharmonic(&out, 29, divisor); + assert!( + (sub - expected).abs() < 0.5, + "{}: {sub}", + PATTERNS[pattern].0 + ); + assert!( + max_step(&out) <= 1.05 * max_step(&input), + "{}", + PATTERNS[pattern].0 + ); + } +} + +#[test] +fn the_texture_is_the_same_on_every_note() { + let mut s = plain(); + s.apply_pattern(PATTERNS[1].2); + let low = run(s, 29, &bass(29, 48000)); + let high = run(s, 36, &bass(36, 48000)); + let (a, b) = (subharmonic(&low, 29, 2.), subharmonic(&high, 36, 2.)); + assert!((a - b).abs() < 0.3, "F1 {a} C2 {b}"); +} + +#[test] +fn same_seed_repeats_every_note_and_free_does_not() { + for (seed, identical) in [(Seed::Same, true), (Seed::Free, false)] { + let s = Settings { + source: Source::Midi, + seed, + ..Settings::default() + }; + let mut engine = Engine::new(RATE, 2).unwrap(); + engine.set_settings(s).unwrap(); + let latency = engine.latency_samples() as usize; + let note = bass(29, 12000); + let mut out = Vec::new(); + let starts = [0, 36000]; + for i in 0..72000 + latency { + if starts.contains(&i) { + engine.note_on(29); + } + if i == starts[0] + 12000 || i == starts[1] + 12000 { + engine.note_off(29); + } + let k = starts + .iter() + .filter(|&&s| i >= s) + .map(|&s| i - s) + .min() + .unwrap(); + let x = note.get(k).copied().unwrap_or(0.); + out.push(engine.process_sample([x, x])[0]); + } + let first = &out[latency..latency + 12000]; + let second = &out[starts[1] + latency..starts[1] + latency + 12000]; + let largest = first + .iter() + .zip(second) + .map(|(a, b)| (a - b).abs()) + .fold(0f32, f32::max); + if identical { + assert!(largest < 1e-4, "{seed:?}: {largest}"); + } else { + assert!(largest > 1e-2, "{seed:?}: {largest}"); + } + assert!(out.iter().all(|v| v.is_finite())); + } +} + +#[test] +fn grit_follows_the_input_level_and_stops_with_the_note() { + let mut s = plain(); + s.grit = -6.; + let input = bass(29, 24000); + let out = run(s, 29, &input); + let noise: f64 = out + .iter() + .zip(&input) + .skip(4800) + .map(|(o, i)| ((o - i) as f64).powi(2)) + .sum::() + / (out.len() - 4800) as f64; + let signal: f64 = input + .iter() + .skip(4800) + .map(|v| (*v as f64).powi(2)) + .sum::() + / (out.len() - 4800) as f64; + let ratio = 10. * (noise / signal).log10(); + // −6 dB bursts over 12 % of each cycle; the sin² window keeps 3/8 of the power: + // −6 + 10·log10(0.12 · 0.375) = −19.5 dB. + assert!((ratio + 19.5).abs() < 1.5, "{ratio}"); + + // Silence in, silence out: no grit without a note, and no NaN. + let mut engine = Engine::new(RATE, 2).unwrap(); + engine.set_settings(Settings::default()).unwrap(); + for _ in 0..48000 { + let out = engine.process_sample([0., 0.]); + assert_eq!(out, [0., 0.]); + } +} + +#[test] +fn audio_source_finds_the_note_and_reports_latency() { + let mut s = plain(); + s.source = Source::Audio; + s.apply_pattern(PATTERNS[1].2); + let mut engine = Engine::new(RATE, 1).unwrap(); + engine.set_settings(s).unwrap(); + let latency = engine.latency_samples() as usize; + // About 67 ms of lookahead plus 4.2 ms of jitter headroom. + assert!((latency as f32 / RATE - 0.071).abs() < 0.005, "{latency}"); + let input = bass(29, 48000); + let mut out: Vec = input + .iter() + .map(|&x| engine.process_sample([x, 0.])[0]) + .collect(); + out.drain(..latency); + let frame = engine.take_analyzer(); + assert_eq!(frame.note, Some(29)); + assert!(frame.scope_valid); + let sub = subharmonic(&out[..out.len() - 4800], 29, 2.); + assert!(sub > -14., "{sub}"); +} + +#[test] +fn invalid_settings_are_rejected() { + let mut engine = Engine::new(RATE, 2).unwrap(); + for bad in [ + Settings { + steps: 0, + ..Settings::default() + }, + Settings { + edge: 60., + ..Settings::default() + }, + Settings { + grit: f32::NAN, + ..Settings::default() + }, + Settings { + time_jitter: 11., + ..Settings::default() + }, + ] { + assert!(engine.set_settings(bad).is_err()); + } + let mut s = Settings::default(); + s.pattern[3] = -30.; + assert!(engine.set_settings(s).is_err()); + assert!(Engine::new(1000., 2).is_err()); + assert!(Engine::new(48000., 3).is_err()); + let json = serde_json::to_string(&Settings::default()).unwrap(); + assert_eq!( + serde_json::from_str::(&json).unwrap(), + Settings::default() + ); +} diff --git a/plugins/knurl/core/tests/realtime.rs b/plugins/knurl/core/tests/realtime.rs new file mode 100644 index 0000000..3dc85ba --- /dev/null +++ b/plugins/knurl/core/tests/realtime.rs @@ -0,0 +1,70 @@ +use knurl_core::{Engine, Seed, Settings, Source, PATTERNS}; +use std::{ + alloc::{GlobalAlloc, Layout, System}, + cell::Cell, +}; + +struct CheckedAllocator; +thread_local! { + static CHECK:Cell=const {Cell::new(false)}; + static OPERATIONS:Cell=const {Cell::new(0)}; +} +fn record() { + if CHECK.try_with(Cell::get).unwrap_or(false) { + let _ = OPERATIONS.try_with(|n| n.set(n.get() + 1)); + } +} +unsafe impl GlobalAlloc for CheckedAllocator { + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + record(); + unsafe { System.alloc(layout) } + } + unsafe fn dealloc(&self, pointer: *mut u8, layout: Layout) { + record(); + unsafe { System.dealloc(pointer, layout) } + } + unsafe fn realloc(&self, pointer: *mut u8, layout: Layout, size: usize) -> *mut u8 { + record(); + unsafe { System.realloc(pointer, layout, size) } + } +} +#[global_allocator] +static ALLOCATOR: CheckedAllocator = CheckedAllocator; + +#[test] +fn notes_patterns_grit_and_jitter_do_not_allocate_or_free() { + let mut engine = Engine::new(48000., 2).unwrap(); + let mut settings = Settings::default(); + engine.set_settings(settings).unwrap(); + CHECK.with(|v| v.set(true)); + for i in 0..96000 { + if i % 4800 == 0 { + settings.apply_pattern(PATTERNS[(i / 4800) % PATTERNS.len()].2); + settings.seed = if i > 48000 { Seed::Free } else { Seed::Same }; + settings.source = if (i / 4800) % 3 == 0 { + Source::Midi + } else { + Source::Audio + }; + settings.time_jitter = ((i / 4800) % 10) as f32; + engine.set_settings(settings).unwrap(); + engine.note_on(30 + (i / 4800 % 12) as u8); + } + if i % 4800 == 2400 { + engine.note_off(30 + (i / 4800 % 12) as u8); + } + let t = i as f32 / 48000.; + let x = if (i / 2400) % 2 == 0 { + (std::f32::consts::TAU * 55. * t).sin() * 0.5 + } else { + 0. + }; + std::hint::black_box(engine.process_sample([x, x])); + if i % 1600 == 0 { + std::hint::black_box(engine.take_analyzer()); + } + } + engine.reset(); + CHECK.with(|v| v.set(false)); + assert_eq!(OPERATIONS.with(Cell::get), 0); +} diff --git a/plugins/knurl/plugin/Cargo.lock b/plugins/knurl/plugin/Cargo.lock new file mode 100644 index 0000000..a748606 --- /dev/null +++ b/plugins/knurl/plugin/Cargo.lock @@ -0,0 +1,2382 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "ab_glyph" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01c0457472c38ea5bd1c3b5ada5e368271cb550be7a4ca4a0b4634e9913f6cc2" +dependencies = [ + "ab_glyph_rasterizer", + "owned_ttf_parser", +] + +[[package]] +name = "ab_glyph_rasterizer" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "366ffbaa4442f4684d91e2cd7c5ea7c4ed8add41959a31447066e279e432b618" + +[[package]] +name = "addr2line" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e567177890eb1617b1f774005b66b26b2377afd138a2ca37aae7d8f0c81429d4" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "android-activity" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f2a1bb052857d5dd49572219344a7332b31b76405648eabac5bc68978251bcd" +dependencies = [ + "android-properties", + "bitflags 2.13.2", + "cc", + "jni", + "libc", + "log", + "ndk", + "ndk-context", + "ndk-sys", + "num_enum", + "thiserror 2.0.21", +] + +[[package]] +name = "android-properties" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" + +[[package]] +name = "anyhow" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" + +[[package]] +name = "anymap3" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5dfbc6d8d2675589ccbe4d0fd61df2419075625f8c1a62325e718e2b0049f9" + +[[package]] +name = "as-raw-xcb-connection" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "atomic_float" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62af46d040ba9df09edc6528dae9d8e49f5f3e82f55b7d2ec31a733c38dbc49d" + +[[package]] +name = "atomic_refcell" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21e4227379beff4205943696e6c3e0cd809bacdf3f0edd6e3dd153e2269571a4" + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "backtrace" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f4220217f3288537b83684130f42fad43320b1c3b805f1910d683d52ded24f" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-link", +] + +[[package]] +name = "baseview" +version = "0.1.0" +source = "git+https://github.com/RustAudio/baseview.git?rev=9a0b42c09d712777b2edb4c5e0cb6baf21e988f0#9a0b42c09d712777b2edb4c5e0cb6baf21e988f0" +dependencies = [ + "cocoa", + "core-foundation", + "keyboard-types", + "nix", + "objc", + "raw-window-handle 0.5.2", + "uuid", + "winapi", + "x11", + "x11rb", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06" + +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + +[[package]] +name = "block2" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" +dependencies = [ + "objc2", +] + +[[package]] +name = "bumpalo" +version = "3.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" + +[[package]] +name = "bytemuck" +version = "1.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95832e849adfb21180ccb6826a99da14e5d266ae5c2e668e1602cf234f153797" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a1f896587b6f2c069c73d2f0913e2d590c3990285cd2f0b6aa02b786b4c679c" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.9", +] + +[[package]] +name = "bytes" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" + +[[package]] +name = "calloop" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" +dependencies = [ + "bitflags 2.13.2", + "log", + "polling", + "rustix 0.38.44", + "slab", + "thiserror 1.0.69", +] + +[[package]] +name = "cc" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "375989decec1a0fa424442bed520fa12ede43a48475ce8c7417d2c69b32b5f6b" +dependencies = [ + "find-msvc-tools", + "jobserver", + "libc", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600" + +[[package]] +name = "cfg_aliases" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527" + +[[package]] +name = "clap-sys" +version = "0.5.0" +source = "git+https://github.com/micahrj/clap-sys.git?rev=25d7f53fdb6363ad63fbd80049cb7a42a97ac156#25d7f53fdb6363ad63fbd80049cb7a42a97ac156" + +[[package]] +name = "clipboard-win" +version = "5.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "052af7878466feccda12ba7a6a67d019d712f296809559b47c12c8cc196d3a9a" +dependencies = [ + "error-code", +] + +[[package]] +name = "cocoa" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f425db7937052c684daec3bd6375c8abe2d146dca4b8b143d6db777c39138f3a" +dependencies = [ + "bitflags 1.3.2", + "block", + "cocoa-foundation", + "core-foundation", + "core-graphics 0.22.3", + "foreign-types 0.3.2", + "libc", + "objc", +] + +[[package]] +name = "cocoa-foundation" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c6234cbb2e4c785b456c0644748b1ac416dd045799740356f8363dfe00c93f7" +dependencies = [ + "bitflags 1.3.2", + "block", + "core-foundation", + "core-graphics-types", + "libc", + "objc", +] + +[[package]] +name = "combine" +version = "4.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4356eba6976435498d05a311ee9fc486da3bc81c200d3f0d7dd9703b41913f92" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "common-dsp" +version = "0.1.0" + +[[package]] +name = "common-ui" +version = "0.1.0" +dependencies = [ + "egui", +] + +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "copypasta" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e6811e17f81fe246ef2bc553f76b6ee6ab41a694845df1d37e52a92b7bbd38a" +dependencies = [ + "clipboard-win", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "x11-clipboard", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "core-graphics" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-graphics-types", + "foreign-types 0.3.2", + "libc", +] + +[[package]] +name = "core-graphics" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-graphics-types", + "foreign-types 0.5.0", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "libc", +] + +[[package]] +name = "crossbeam" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e71406cd8807725f7ac2f999a4cdd32e98f829fdf65f528343cebf945e41df1e" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-epoch", + "crossbeam-queue", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98b0cc327b5bc766e7fda9c9260cc0fa81b43a8e240440422dff70788e3f9ef1" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622f3fc73690be383c7214310406f28a90e6edeadc3cea882f9d71e495b9711a" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc74980687109a3b14c72fd458107bf0baa1da1a1a805e178d15501ba9b86d9d" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-queue" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03e8bd762f7479489c70ed6c768ddca99d7296857de437a68dcb2a94365b3fae" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31eee39dddec8330830986fcd7625edb5a24ec90ea038215273bbc3adb08ac6" + +[[package]] +name = "cursor-icon" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f" + +[[package]] +name = "deranged" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e9de72ce2ad1f90dc62fa25f0f430ef85eb4b0d8fa0be4f30373bc40a21d28e" + +[[package]] +name = "dispatch" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" + +[[package]] +name = "dlib" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab8ecd87370524b461f8557c119c405552c396ed91fc0a8eec68679eab26f94a" +dependencies = [ + "libloading", +] + +[[package]] +name = "dpi" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" + +[[package]] +name = "ecolor" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc4feb366740ded31a004a0e4452fbf84e80ef432ecf8314c485210229672fd1" +dependencies = [ + "bytemuck", + "emath", +] + +[[package]] +name = "egui" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25dd34cec49ab55d85ebf70139cb1ccd29c977ef6b6ba4fe85489d6877ee9ef3" +dependencies = [ + "ahash", + "bitflags 2.13.2", + "emath", + "epaint", + "nohash-hasher", + "profiling", +] + +[[package]] +name = "egui-baseview" +version = "0.5.0" +source = "git+https://github.com/BillyDM/egui-baseview.git?rev=ec70c3fe6b2f070dcacbc22924431edbe24bd1c0#ec70c3fe6b2f070dcacbc22924431edbe24bd1c0" +dependencies = [ + "baseview", + "copypasta", + "egui", + "egui_glow", + "keyboard-types", + "log", + "open", + "raw-window-handle 0.5.2", + "thiserror 2.0.21", +] + +[[package]] +name = "egui_glow" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "910906e3f042ea6d2378ec12a6fd07698e14ddae68aed2d819ffe944a73aab9e" +dependencies = [ + "ahash", + "bytemuck", + "egui", + "glow", + "log", + "memoffset 0.9.1", + "profiling", + "wasm-bindgen", + "web-sys", + "winit", +] + +[[package]] +name = "emath" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e4cadcff7a5353ba72b7fea76bf2122b5ebdbc68e8155aa56dfdea90083fe1b" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "epaint" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fcc0f5a7c613afd2dee5e4b30c3e6acafb8ad6f0edb06068811f708a67c562" +dependencies = [ + "ab_glyph", + "ahash", + "bytemuck", + "ecolor", + "emath", + "epaint_default_fonts", + "nohash-hasher", + "parking_lot", + "profiling", +] + +[[package]] +name = "epaint_default_fonts" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7e7a64c02cf7a5b51e745a9e45f60660a286f151c238b9d397b3e923f5082f" + +[[package]] +name = "equivalent" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00d174d5400e5e8fd687ad1049e2f578285fa914201b1af7e8b112a4546bd826" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "error-code" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5343afd4a8365a643ac588dab4cf234a190c7f6c88c9f6dd6ffe00837661b7" + +[[package]] +name = "find-msvc-tools" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c66915cc5391097de7a2b0b972e8505aa33c0df401fd3a6811dbdb32881ba48" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared 0.1.1", +] + +[[package]] +name = "foreign-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared 0.3.1", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea5190182e6915eb873ddbc16e23b711b6eb1f9c00a0d0a3a91b5f6228475225" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.9", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "foreign-types-shared" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" + +[[package]] +name = "futures-core" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" + +[[package]] +name = "futures-task" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" + +[[package]] +name = "futures-util" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "slab", +] + +[[package]] +name = "gethostname" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8" +dependencies = [ + "rustix 1.1.6", + "windows-link", +] + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "getrandom" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" +dependencies = [ + "cfg-if", + "libc", + "r-efi", +] + +[[package]] +name = "gimli" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1033caf0b349c518623b5396bfb2cf0bddf44f0306d543a250e5743297aafd10" + +[[package]] +name = "glow" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5e5ea60d70410161c8bf5da3fdfeaa1c72ed2c15f8bbb9d19fe3a4fad085f08" +dependencies = [ + "js-sys", + "slotmap", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17592d60ebacc7d5e169f4663c5f84f9161cc90328abcfe8456f41e4dfcb284" + +[[package]] +name = "indexmap" +version = "2.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "is-docker" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "928bae27f42bc99b60d9ac7334e3a21d10ad8f1835a4e12ec3ec0464765ed1b3" +dependencies = [ + "once_cell", +] + +[[package]] +name = "is-wsl" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "173609498df190136aa7dea1a91db051746d339e18476eed5ca40521f02d7aa5" +dependencies = [ + "is-docker", + "once_cell", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "jni" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498" +dependencies = [ + "cfg-if", + "combine", + "jni-macros", + "jni-sys 0.4.1", + "log", + "simd_cesu8", + "thiserror 2.0.21", + "walkdir", + "windows-link", +] + +[[package]] +name = "jni-macros" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "simd_cesu8", + "syn 2.0.119", +] + +[[package]] +name = "jni-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41a652e1f9b6e0275df1f15b32661cf0d4b78d4d87ddec5e0c3c20f097433258" +dependencies = [ + "jni-sys 0.4.1", +] + +[[package]] +name = "jni-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" +dependencies = [ + "jni-sys-macros", +] + +[[package]] +name = "jni-sys-macros" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" +dependencies = [ + "quote", + "syn 2.0.119", +] + +[[package]] +name = "jobserver" +version = "0.1.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" +dependencies = [ + "getrandom 0.4.3", + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dc09d2154098bbf4ef54eab6b117a3c24cbbffe94046b16ee6d6d4510584d3a" +dependencies = [ + "cfg-if", + "futures-util", + "wasm-bindgen", +] + +[[package]] +name = "keyboard-types" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7668b7cff6a51fe61cdde64cd27c8a220786f399501b57ebe36f7d8112fd68" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "knurl" +version = "0.1.0" +dependencies = [ + "clap-sys", + "crossbeam-queue", + "knurl-core", + "knurl-ui", + "nih_plug", + "nih_plug_egui", + "serde", + "serde_json", +] + +[[package]] +name = "knurl-core" +version = "0.1.0" +dependencies = [ + "common-dsp", + "serde", +] + +[[package]] +name = "knurl-ui" +version = "0.1.0" +dependencies = [ + "common-dsp", + "common-ui", + "egui", + "knurl-core", +] + +[[package]] +name = "libc" +version = "0.2.191" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65cd87c9a6d60536580b316ad985726104730a5151c99845f2490428ef91240a" + +[[package]] +name = "libloading" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" +dependencies = [ + "cfg-if", + "windows-link", +] + +[[package]] +name = "libredox" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61ff90caf6077a803a240f62fdbe88645a890bbca49ef8174c3cb0404362171d" +dependencies = [ + "bitflags 2.13.2", + "libc", + "plain", + "redox_syscall 0.9.5", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + +[[package]] +name = "linux-raw-sys" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d15f86d12da44cd8d4ec3c73984537eb7f4cadcb9776a575a0a8a05ca11005c" + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "midi-consts" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f2dd5c7f8aaf48a76e389068ab25ed80bdbc226b887f9013844c415698c9952" + +[[package]] +name = "miniz_oxide" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b63fbc4a50860e98e7b2aa7804ded1db5cbc3aff9193adaff57a6931bf7c4b4c" +dependencies = [ + "adler2", +] + +[[package]] +name = "ndk" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" +dependencies = [ + "bitflags 2.13.2", + "jni-sys 0.3.1", + "log", + "ndk-sys", + "num_enum", + "raw-window-handle 0.6.2", + "thiserror 1.0.69", +] + +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + +[[package]] +name = "ndk-sys" +version = "0.6.0+11769913" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" +dependencies = [ + "jni-sys 0.3.1", +] + +[[package]] +name = "nih_log" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0cdb52ef79af48ae110401c883bdb9c15e0306a99ab6ecf18bc52068b668e54" +dependencies = [ + "atty", + "log", + "once_cell", + "termcolor", + "time", + "windows", +] + +[[package]] +name = "nih_plug" +version = "0.0.0" +source = "git+https://github.com/robbert-vdh/nih-plug.git?rev=de421011f41a6d10fc8c7a6084e4f4dee0143683#de421011f41a6d10fc8c7a6084e4f4dee0143683" +dependencies = [ + "anyhow", + "anymap3", + "atomic_float", + "atomic_refcell", + "backtrace", + "bitflags 1.3.2", + "cfg-if", + "clap-sys", + "core-foundation", + "crossbeam", + "libc", + "log", + "midi-consts", + "nih_log", + "nih_plug_derive", + "objc", + "parking_lot", + "raw-window-handle 0.5.2", + "serde", + "serde_json", + "widestring", + "windows", +] + +[[package]] +name = "nih_plug_derive" +version = "0.1.0" +source = "git+https://github.com/robbert-vdh/nih-plug.git?rev=de421011f41a6d10fc8c7a6084e4f4dee0143683#de421011f41a6d10fc8c7a6084e4f4dee0143683" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "nih_plug_egui" +version = "0.0.0" +source = "git+https://github.com/robbert-vdh/nih-plug.git?rev=de421011f41a6d10fc8c7a6084e4f4dee0143683#de421011f41a6d10fc8c7a6084e4f4dee0143683" +dependencies = [ + "baseview", + "crossbeam", + "egui-baseview", + "nih_plug", + "parking_lot", + "raw-window-handle 0.5.2", + "serde", +] + +[[package]] +name = "nix" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4916f159ed8e5de0082076562152a76b7a1f64a01fd9d1e0fea002c37624faf" +dependencies = [ + "bitflags 1.3.2", + "cc", + "cfg-if", + "libc", + "memoffset 0.6.5", +] + +[[package]] +name = "nohash-hasher" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" + +[[package]] +name = "num-conv" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" + +[[package]] +name = "num_enum" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0bca838442ec211fa11de3a8b0e0e8f3a4522575b5c4c06ed722e005036f26" +dependencies = [ + "num_enum_derive", + "rustversion", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "num_threads" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cabcc654086861f9e1bc5115258de62ef92c79b20f4615a1b0cc57c4e82027d4" +dependencies = [ + "libc", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", +] + +[[package]] +name = "objc-sys" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" + +[[package]] +name = "objc2" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d5490aaf8f1d7cf7688dfa9b0ce07900e168852c45cd2c03f534dfd27cfd0b" +dependencies = [ + "objc-sys", + "objc2-encode", +] + +[[package]] +name = "objc2-app-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" +dependencies = [ + "bitflags 2.13.2", + "block2", + "libc", + "objc2", + "objc2-core-data", + "objc2-core-image", + "objc2-foundation", + "objc2-quartz-core", +] + +[[package]] +name = "objc2-cloud-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" +dependencies = [ + "bitflags 2.13.2", + "block2", + "objc2", + "objc2-core-location", + "objc2-foundation", +] + +[[package]] +name = "objc2-contacts" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" +dependencies = [ + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-data" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" +dependencies = [ + "bitflags 2.13.2", + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-image" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" +dependencies = [ + "block2", + "objc2", + "objc2-foundation", + "objc2-metal", +] + +[[package]] +name = "objc2-core-location" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" +dependencies = [ + "block2", + "objc2", + "objc2-contacts", + "objc2-foundation", +] + +[[package]] +name = "objc2-encode" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" + +[[package]] +name = "objc2-foundation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" +dependencies = [ + "bitflags 2.13.2", + "block2", + "dispatch", + "libc", + "objc2", +] + +[[package]] +name = "objc2-link-presentation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" +dependencies = [ + "block2", + "objc2", + "objc2-app-kit", + "objc2-foundation", +] + +[[package]] +name = "objc2-metal" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" +dependencies = [ + "bitflags 2.13.2", + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-quartz-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" +dependencies = [ + "bitflags 2.13.2", + "block2", + "objc2", + "objc2-foundation", + "objc2-metal", +] + +[[package]] +name = "objc2-symbols" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc" +dependencies = [ + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-ui-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" +dependencies = [ + "bitflags 2.13.2", + "block2", + "objc2", + "objc2-cloud-kit", + "objc2-core-data", + "objc2-core-image", + "objc2-core-location", + "objc2-foundation", + "objc2-link-presentation", + "objc2-quartz-core", + "objc2-symbols", + "objc2-uniform-type-identifiers", + "objc2-user-notifications", +] + +[[package]] +name = "objc2-uniform-type-identifiers" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe" +dependencies = [ + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-user-notifications" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" +dependencies = [ + "bitflags 2.13.2", + "block2", + "objc2", + "objc2-core-location", + "objc2-foundation", +] + +[[package]] +name = "object" +version = "0.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd229a0361b9d0d4396176e02d65897f487eebeab7caa6d443855ee152ca0b9c" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "open" +version = "5.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d8c8b8e725ad26404d6896eb2f064294a0a7b4f1d9120210d85544684c4ca95" +dependencies = [ + "is-wsl", + "libc", +] + +[[package]] +name = "orbclient" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5df339f526ea9a60e371768d50efc2f2508c7203290731565d1f7a6f71d21747" +dependencies = [ + "libc", + "libredox", +] + +[[package]] +name = "owned_ttf_parser" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36820e9051aca1014ddc75770aab4d68bc1e9e632f0f5627c4086bc216fb583b" +dependencies = [ + "ttf-parser", +] + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.5.18", + "smallvec", + "windows-link", +] + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "pin-project" +version = "1.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "pkg-config" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548" + +[[package]] +name = "plain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" + +[[package]] +name = "polling" +version = "3.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi 0.5.3", + "pin-project-lite", + "rustix 1.1.6", + "windows-sys 0.61.2", +] + +[[package]] +name = "powerfmt" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a6394b9e965e73d0a289ee54f589087e2c676aedf60885baf52c76b771e4958" + +[[package]] +name = "proc-macro-crate" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "profiling" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d595e54a326bc53c1c197b32d295e14b169e3cfeaa8dc82b529f947fba6bcf5" + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + +[[package]] +name = "raw-window-handle" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" + +[[package]] +name = "raw-window-handle" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags 2.13.2", +] + +[[package]] +name = "redox_syscall" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "580c875845b41ecb1564ad1ae4703044cef774145e3d7a94dc2b3fa7c97868fd" +dependencies = [ + "bitflags 2.13.2", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b74b56ffa8bb2830709a538c2cbcae9aa062db0d2a42563bfb09bdaae44020eb" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.38.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +dependencies = [ + "bitflags 2.13.2", + "errno", + "libc", + "linux-raw-sys 0.4.15", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustix" +version = "1.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5e76742e5294153d4dde1207dbec5bdd81eef6fabdc0d2118babadabfd858aa" +dependencies = [ + "bitflags 2.13.2", + "errno", + "libc", + "linux-raw-sys 0.12.1", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustversion" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + +[[package]] +name = "serde" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.9", +] + +[[package]] +name = "serde_json" +version = "1.0.154" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7e9cc8b1b85264074fbcc02a88680c4096b1e47df8f739dceb03bf482f04bd6" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + +[[package]] +name = "simd_cesu8" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11031e251abf8611c80f460e19dbdeb54a66db918e49c65a7065b46ac7aec520" +dependencies = [ + "rustc_version", + "simdutf8", +] + +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "slotmap" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdd58c3c93c3d278ca835519292445cb4b0d4dc59ccfdf7ceadaab3f8aeb4038" +dependencies = [ + "version_check", +] + +[[package]] +name = "smallvec" +version = "1.16.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0d5d4b1981b8bbbb7aed204cae5726d683d5d6ac7e74ec54122ea28f315e7c8" + +[[package]] +name = "smol_str" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" +dependencies = [ + "serde", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.119" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "3.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d78c8dee4c7bf0e14673097256fed6142ce9d3b85a408189d07482442145823b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09e52cb86a36cede5cb101bf8908837b3e4c6e5e59fe7fd85c23fb56200d189e" +dependencies = [ + "thiserror-impl 2.0.21", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe5197923287db20a58125f0bc85c062f7f2c892de97b18c356f9efb14b28524" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.9", +] + +[[package]] +name = "time" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb87b95ec50ddfa440816d227a17b2ccbdda963a316a727fda0fc4334f7d134" +dependencies = [ + "deranged", + "libc", + "num-conv", + "num_threads", + "powerfmt", + "serde_core", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" + +[[package]] +name = "time-macros" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e689342a48d2ea927c87ea50cabf8594854bf940e9310208848d680d668ed85" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tokio" +version = "1.54.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b52fd3255258d26fac7264ab5a76b53c13367136dc011d3d6ad4f8ed070396a3" +dependencies = [ + "pin-project-lite", +] + +[[package]] +name = "toml_datetime" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b86d767906c6c42421dcba507eb9d203e779497710a47782a224bb871653053" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.25.18+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec6e78bd70db9420d8d212fa9dc97f116448a1ceff5d00eabb991d407e21396" +dependencies = [ + "indexmap", + "toml_datetime", + "toml_parser", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.1.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baa693a8032d7e1cada7d0041e96126df243179ff061456783ac7f12bda4744c" +dependencies = [ + "winnow", +] + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" + +[[package]] +name = "ttf-parser" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31" + +[[package]] +name = "unicode-ident" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2c754d6c33795a1c324727428e5a7dedb5b06195f9890bdbcba760d3e246563" + +[[package]] +name = "unicode-segmentation" +version = "1.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" + +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +dependencies = [ + "getrandom 0.2.17", +] + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasm-bindgen" +version = "0.2.130" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0181c14ddd6c7b8b0b0132a5f1ea2f32be0d893cd3ea97b6e3b28886b8a3d1c" +dependencies = [ + "cfg-if", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e14e0327cb5368ad60ccb22d04a9827a693c95a926d8d125e9fa39e0baec501" +dependencies = [ + "js-sys", + "tokio", + "wasm-bindgen", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.130" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e931a02a39abdbf66966fc35902b5ed58344750a70885bed4ebb3d8eaf28ed9" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.130" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ca4b54280e455bd831e33a6b8e734baf432fe63fbc35c42ac14ce67a043a53a" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn 3.0.9", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.130" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b1f9c3798725016c6ee5f2f57869ec0831e8bbc0ab0310a86e787e97f41389e" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "web-sys" +version = "0.3.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7d179596ff5ec0f6de4db64d54011bde6289cc49603d3a6e4ce3f329207ab88" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "widestring" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72069c3113ab32ab29e5584db3c6ec55d416895e60715417b5b883a357c3e471" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e745dab35a0c4c77aa3ce42d595e13d2003d6902d6b08c9ef5fc326d08da12b" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winit" +version = "0.30.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6755fa58a9f8350bd1e472d4c3fcc25f824ec358933bba33306d0b63df5978d" +dependencies = [ + "android-activity", + "atomic-waker", + "bitflags 2.13.2", + "block2", + "bytemuck", + "calloop", + "cfg_aliases", + "concurrent-queue", + "core-foundation", + "core-graphics 0.23.2", + "cursor-icon", + "dpi", + "js-sys", + "libc", + "ndk", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "objc2-ui-kit", + "orbclient", + "percent-encoding", + "pin-project", + "raw-window-handle 0.6.2", + "redox_syscall 0.4.1", + "rustix 0.38.44", + "smol_str", + "tracing", + "unicode-segmentation", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "web-time", + "windows-sys 0.52.0", + "x11-dl", + "x11rb", + "xkbcommon-dl", +] + +[[package]] +name = "winnow" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3b93199df0ab874cdf0c6a94f0a0dc3423fe41f1cafb62b8bd7b1deb277aef" +dependencies = [ + "memchr", +] + +[[package]] +name = "x11" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "502da5464ccd04011667b11c435cb992822c2c0dbde1770c988480d312a0db2e" +dependencies = [ + "libc", + "pkg-config", +] + +[[package]] +name = "x11-clipboard" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "662d74b3d77e396b8e5beb00b9cad6a9eccf40b2ef68cc858784b14c41d535a3" +dependencies = [ + "libc", + "x11rb", +] + +[[package]] +name = "x11-dl" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" +dependencies = [ + "libc", + "once_cell", + "pkg-config", +] + +[[package]] +name = "x11rb" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9993aa5be5a26815fe2c3eacfc1fde061fc1a1f094bf1ad2a18bf9c495dd7414" +dependencies = [ + "as-raw-xcb-connection", + "gethostname", + "libc", + "libloading", + "once_cell", + "rustix 1.1.6", + "x11rb-protocol", + "xcursor", +] + +[[package]] +name = "x11rb-protocol" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd" + +[[package]] +name = "xcursor" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "163b33ed8786455e2fa5d72f554057ce3f3182425434f756cd39c99839d88e23" + +[[package]] +name = "xkbcommon-dl" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" +dependencies = [ + "bitflags 2.13.2", + "dlib", + "log", + "once_cell", + "xkeysym", +] + +[[package]] +name = "xkeysym" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" + +[[package]] +name = "zerocopy" +version = "0.8.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5fe1f8f1b06191a00962174c61aa5005e0bb391a6d80d07e24d115c01a92ed8" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "863ad3ac83293fb4d740aedbfdc9240dd8d1a50c1099acd76ce80ce7c7230c7f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/plugins/knurl/plugin/Cargo.toml b/plugins/knurl/plugin/Cargo.toml new file mode 100644 index 0000000..9c94cc0 --- /dev/null +++ b/plugins/knurl/plugin/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "knurl" +version = "0.1.0" +edition = "2021" +license = "ISC" + +[workspace] + +[lib] +crate-type = ["cdylib", "rlib"] + +[dependencies] +nih_plug = { git = "https://github.com/robbert-vdh/nih-plug.git", rev = "de421011f41a6d10fc8c7a6084e4f4dee0143683", default-features = false } +nih_plug_egui = { git = "https://github.com/robbert-vdh/nih-plug.git", rev = "de421011f41a6d10fc8c7a6084e4f4dee0143683" } +knurl-core = { path = "../core" } +knurl-ui = { path = "../ui" } +crossbeam-queue = "0.3" +serde = { version = "1", features = ["derive"] } + +[dev-dependencies] +clap-sys = { git = "https://github.com/micahrj/clap-sys.git", rev = "25d7f53fdb6363ad63fbd80049cb7a42a97ac156" } +serde_json = "1" + +[profile.release] +lto = "thin" +strip = "symbols" diff --git a/plugins/knurl/plugin/src/lib.rs b/plugins/knurl/plugin/src/lib.rs new file mode 100644 index 0000000..f4da474 --- /dev/null +++ b/plugins/knurl/plugin/src/lib.rs @@ -0,0 +1,195 @@ +//! CLAP audio effect. All DSP state is owned by the processing thread. +mod params; +use crossbeam_queue::ArrayQueue; +use knurl_core::{AnalyzerFrame, Engine}; +use nih_plug::prelude::*; +use nih_plug_egui::{create_egui_editor, egui}; +use params::{KnurlParams, Pattern, GESTURES}; +use std::sync::Arc; + +struct EditorData { + ui: knurl_ui::State, + gestures: [bool; GESTURES], +} +pub struct Knurl { + params: Arc, + analyzer: Arc>, + engine: Option, + pattern: Pattern, + publish_count: usize, + publish_interval: usize, +} +impl Default for Knurl { + fn default() -> Self { + Self { + params: Arc::new(KnurlParams::default()), + analyzer: Arc::new(ArrayQueue::new(2)), + engine: None, + pattern: Pattern::default(), + publish_count: 0, + publish_interval: 1600, + } + } +} +impl Plugin for Knurl { + const NAME: &'static str = "Knurl"; + const VENDOR: &'static str = "Bass Foundry"; + const URL: &'static str = ""; + const EMAIL: &'static str = ""; + const VERSION: &'static str = env!("CARGO_PKG_VERSION"); + const AUDIO_IO_LAYOUTS: &'static [AudioIOLayout] = &[ + AudioIOLayout { + main_input_channels: NonZeroU32::new(2), + main_output_channels: NonZeroU32::new(2), + ..AudioIOLayout::const_default() + }, + AudioIOLayout { + main_input_channels: NonZeroU32::new(1), + main_output_channels: NonZeroU32::new(1), + ..AudioIOLayout::const_default() + }, + ]; + const MIDI_INPUT: MidiConfig = MidiConfig::Basic; + const SAMPLE_ACCURATE_AUTOMATION: bool = false; + type SysExMessage = (); + type BackgroundTask = (); + fn params(&self) -> Arc { + self.params.clone() + } + fn editor(&mut self, _: AsyncExecutor) -> Option> { + let params = self.params.clone(); + let analyzer = self.analyzer.clone(); + create_egui_editor( + params.editor.clone(), + EditorData { + ui: knurl_ui::State::default(), + gestures: [false; GESTURES], + }, + |ctx, _| knurl_ui::style(ctx), + move |ctx, setter, data| { + while let Some(frame) = analyzer.pop() { + data.ui.accept_frame(frame); + } + let current = params.pattern(); + let before = params.settings(¤t); + let mut edited = before; + nih_plug_egui::resizable_window::ResizableWindow::new("knurl-editor") + .min_size(egui::vec2( + knurl_ui::WIDTH as f32 - 80., + knurl_ui::HEIGHT as f32 - 40., + )) + .show(ctx, ¶ms.editor, |ui| { + knurl_ui::show(ui, &mut edited, &mut data.ui) + }); + params.apply( + setter, + &before, + &edited, + data.ui.gesture_active, + &mut data.gestures, + ); + // The scope follows the audio. + ctx.request_repaint_after(std::time::Duration::from_millis(40)); + }, + ) + } + fn initialize( + &mut self, + layout: &AudioIOLayout, + config: &BufferConfig, + context: &mut impl InitContext, + ) -> bool { + let Ok(mut engine) = Engine::new( + config.sample_rate, + layout.main_input_channels.map_or(0, |v| v.get() as usize), + ) else { + return false; + }; + let settings = self.params.settings(&self.pattern); + self.pattern = Pattern { + gains: settings.pattern, + grit: settings.grit_steps, + }; + if engine.set_settings(settings).is_err() { + return false; + } + context.set_latency_samples(engine.latency_samples()); + self.publish_interval = (config.sample_rate / 30.) as usize; + self.engine = Some(engine); + true + } + fn reset(&mut self) { + if let Some(e) = self.engine.as_mut() { + e.reset(); + } + self.publish_count = 0; + } + fn process( + &mut self, + buffer: &mut Buffer, + _: &mut AuxiliaryBuffers, + context: &mut impl ProcessContext, + ) -> ProcessStatus { + let Some(engine) = self.engine.as_mut() else { + return ProcessStatus::Normal; + }; + let settings = self.params.settings(&self.pattern); + self.pattern = Pattern { + gains: settings.pattern, + grit: settings.grit_steps, + }; + let _ = engine.set_settings(settings); + let mut next = context.next_event(); + for (index, mut sample) in buffer.iter_samples().enumerate() { + while let Some(event) = next { + if event.timing() as usize > index { + break; + } + match event { + NoteEvent::NoteOn { note, velocity, .. } if velocity > 0. => { + engine.note_on(note) + } + NoteEvent::NoteOn { note, .. } | NoteEvent::NoteOff { note, .. } => { + engine.note_off(note) + } + NoteEvent::Choke { note, .. } => engine.note_off(note), + _ => {} + } + next = context.next_event(); + } + let x = [ + *sample.get_mut(0).unwrap(), + if engine.channels() == 2 { + *sample.get_mut(1).unwrap() + } else { + 0. + }, + ]; + let out = engine.process_sample(x); + for (c, value) in sample.into_iter().enumerate() { + *value = out[c]; + } + self.publish_count += 1; + if self.publish_count >= self.publish_interval { + self.analyzer.force_push(engine.take_analyzer()); + self.publish_count = 0; + } + } + // The lookahead delay and filter tails must drain after input stops. + ProcessStatus::KeepAlive + } +} +impl ClapPlugin for Knurl { + const CLAP_ID: &'static str = "io.storyboard.cycle-texture"; + const CLAP_DESCRIPTION: Option<&'static str> = + Some("Texture per cycle of the played note: patterns, jitter and grit that fit every note"); + const CLAP_MANUAL_URL: Option<&'static str> = None; + const CLAP_SUPPORT_URL: Option<&'static str> = None; + const CLAP_FEATURES: &'static [ClapFeature] = &[ + ClapFeature::AudioEffect, + ClapFeature::Distortion, + ClapFeature::Stereo, + ClapFeature::Mono, + ]; +} +nih_export_clap!(Knurl); diff --git a/plugins/knurl/plugin/src/params.rs b/plugins/knurl/plugin/src/params.rs new file mode 100644 index 0000000..0a2edab --- /dev/null +++ b/plugins/knurl/plugin/src/params.rs @@ -0,0 +1,255 @@ +use knurl_core::{Seed, Settings, Source, GRIT_OFF, STEPS, STEP_MIN}; +use nih_plug::prelude::*; +use nih_plug_egui::EguiState; +use std::sync::{Arc, RwLock}; + +#[derive(Enum, Debug, PartialEq, Eq, Clone, Copy)] +pub enum SourceParam { + #[id = "audio"] + Audio, + #[id = "midi"] + #[name = "MIDI"] + Midi, +} +#[derive(Enum, Debug, PartialEq, Eq, Clone, Copy)] +pub enum SeedParam { + #[id = "same"] + #[name = "Same every note"] + Same, + #[id = "free"] + Free, +} +fn linear(name: &str, v: f32, min: f32, max: f32, unit: &'static str) -> FloatParam { + FloatParam::new(name, v, FloatRange::Linear { min, max }).with_unit(unit) +} +/// Continuous controls, in the order of the gesture slots. +const FLOATS: usize = 10; +pub const GESTURES: usize = FLOATS; + +/// The drawn pattern: step gains and grit switches. Saved with the project, not automation. +#[derive(Debug, Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct Pattern { + pub gains: [f32; STEPS], + pub grit: [bool; STEPS], +} +impl Default for Pattern { + fn default() -> Self { + let d = Settings::default(); + Self { + gains: d.pattern, + grit: d.grit_steps, + } + } +} + +#[derive(Params)] +pub struct KnurlParams { + #[persist = "editor"] + pub editor: Arc, + #[persist = "knurl-pattern"] + pub pattern: RwLock, + #[id = "source"] + pub source: EnumParam, + #[id = "seed"] + pub seed: EnumParam, + #[id = "steps"] + pub steps: IntParam, + #[id = "edge"] + pub edge: FloatParam, + #[id = "level-jitter"] + pub level_jitter: FloatParam, + #[id = "time-jitter"] + pub time_jitter: FloatParam, + #[id = "grit"] + pub grit: FloatParam, + #[id = "tone"] + pub tone: FloatParam, + #[id = "position"] + pub position: FloatParam, + #[id = "length"] + pub length: FloatParam, + #[id = "gate"] + pub gate: FloatParam, + #[id = "mix"] + pub mix: FloatParam, + #[id = "output"] + pub output: FloatParam, + #[id = "snap"] + pub snap: BoolParam, + #[id = "bypass"] + pub bypass: BoolParam, +} +impl Default for KnurlParams { + fn default() -> Self { + let d = Settings::default(); + Self { + editor: EguiState::from_size(knurl_ui::WIDTH, knurl_ui::HEIGHT), + pattern: RwLock::new(Pattern::default()), + source: EnumParam::new("Pitch source", SourceParam::Audio), + seed: EnumParam::new("Random", SeedParam::Same), + steps: IntParam::new( + "Steps", + d.steps as i32, + IntRange::Linear { + min: 1, + max: STEPS as i32, + }, + ), + edge: linear("Edge", d.edge, 5., 50., " %"), + level_jitter: linear("Level jitter", d.level_jitter, 0., 6., " dB"), + time_jitter: linear("Time jitter", d.time_jitter, 0., 10., " %"), + grit: linear("Grit", d.grit, GRIT_OFF, 0., " dB").with_value_to_string(Arc::new(|v| { + if v <= GRIT_OFF { + "Off".into() + } else { + format!("{v:.1}") + } + })), + tone: FloatParam::new( + "Tone", + d.tone, + FloatRange::Skewed { + min: 4., + max: 64., + factor: FloatRange::skew_factor(-1.), + }, + ) + .with_unit(" ×f0"), + position: linear("Position", d.position, 0., 100., " %"), + length: linear("Length", d.length, 2., 50., " %"), + gate: linear("Gate", d.gate, -60., -20., " dB"), + mix: linear("Mix", d.mix, 0., 100., " %"), + output: linear("Output", d.output, -12., 12., " dB"), + snap: BoolParam::new("Snap to semitone", d.snap), + bypass: BoolParam::new("Bypass", false).make_bypass(), + } + } +} +impl KnurlParams { + /// Current settings. The pattern falls back to `last` when the editor holds the lock, + /// so the audio thread never waits. + pub fn settings(&self, last: &Pattern) -> Settings { + let pattern = self.pattern.try_read().map(|p| *p).unwrap_or(*last); + Settings { + source: match self.source.value() { + SourceParam::Audio => Source::Audio, + SourceParam::Midi => Source::Midi, + }, + pattern: pattern.gains.map(|g| { + if g.is_finite() { + g.clamp(STEP_MIN, 0.) + } else { + 0. + } + }), + grit_steps: pattern.grit, + steps: self.steps.value().clamp(1, STEPS as i32) as usize, + edge: self.edge.value(), + level_jitter: self.level_jitter.value(), + time_jitter: self.time_jitter.value(), + grit: self.grit.value(), + tone: self.tone.value(), + position: self.position.value(), + length: self.length.value(), + seed: match self.seed.value() { + SeedParam::Same => Seed::Same, + SeedParam::Free => Seed::Free, + }, + gate: self.gate.value(), + snap: self.snap.value(), + mix: self.mix.value(), + output: self.output.value(), + bypass: self.bypass.value(), + } + } + pub fn pattern(&self) -> Pattern { + self.pattern.read().map(|p| *p).unwrap_or_default() + } + fn floats(&self) -> [&FloatParam; FLOATS] { + [ + &self.edge, + &self.level_jitter, + &self.time_jitter, + &self.grit, + &self.tone, + &self.position, + &self.length, + &self.gate, + &self.mix, + &self.output, + ] + } + /// Pushes every changed editor value to the host. Continuous controls hold one gesture + /// while the pointer is down; switches are set in a single gesture. The pattern is + /// stored directly. + pub fn apply( + &self, + setter: &ParamSetter, + old: &Settings, + new: &Settings, + dragging: bool, + open: &mut [bool; FLOATS], + ) { + if new.pattern != old.pattern || new.grit_steps != old.grit_steps { + if let Ok(mut p) = self.pattern.write() { + *p = Pattern { + gains: new.pattern, + grit: new.grit_steps, + }; + } + } + let values = [ + (old.edge, new.edge), + (old.level_jitter, new.level_jitter), + (old.time_jitter, new.time_jitter), + (old.grit, new.grit), + (old.tone, new.tone), + (old.position, new.position), + (old.length, new.length), + (old.gate, new.gate), + (old.mix, new.mix), + (old.output, new.output), + ]; + for (i, (p, (a, b))) in self.floats().into_iter().zip(values).enumerate() { + if a != b { + if !open[i] { + open[i] = true; + setter.begin_set_parameter(p); + } + setter.set_parameter(p, b); + } + if !dragging && open[i] { + setter.end_set_parameter(p); + open[i] = false; + } + } + fn switch(setter: &ParamSetter, p: &P, v: P::Plain) { + setter.begin_set_parameter(p); + setter.set_parameter(p, v); + setter.end_set_parameter(p); + } + if new.steps != old.steps { + switch(setter, &self.steps, new.steps as i32); + } + if new.snap != old.snap { + switch(setter, &self.snap, new.snap); + } + if new.bypass != old.bypass { + switch(setter, &self.bypass, new.bypass); + } + if new.source != old.source { + let v = match new.source { + Source::Audio => SourceParam::Audio, + Source::Midi => SourceParam::Midi, + }; + switch(setter, &self.source, v); + } + if new.seed != old.seed { + let v = match new.seed { + Seed::Same => SeedParam::Same, + Seed::Free => SeedParam::Free, + }; + switch(setter, &self.seed, v); + } + } +} diff --git a/plugins/knurl/plugin/tests/host.rs b/plugins/knurl/plugin/tests/host.rs new file mode 100644 index 0000000..9cfba7c --- /dev/null +++ b/plugins/knurl/plugin/tests/host.rs @@ -0,0 +1,227 @@ +//! Exercise the actual exported CLAP ABI without requiring a GUI or installed DAW. +use clap_sys::{ + audio_buffer::*, + events::*, + ext::{audio_ports::*, latency::*, state::*}, + factory::plugin_factory::*, + host::*, + process::*, + stream::*, + version::*, +}; +use std::{ + ffi::{c_char, c_void, CStr}, + io::{Cursor, Read}, + ptr, +}; + +unsafe extern "C" fn extension(_: *const clap_host, _: *const c_char) -> *const c_void { + ptr::null() +} +unsafe extern "C" fn request(_: *const clap_host) {} +unsafe extern "C" fn count(_: *const clap_input_events) -> u32 { + 0 +} +unsafe extern "C" fn event(_: *const clap_input_events, _: u32) -> *const clap_event_header { + ptr::null() +} +unsafe extern "C" fn push(_: *const clap_output_events, _: *const clap_event_header) -> bool { + true +} +unsafe extern "C" fn write(stream: *const clap_ostream, buffer: *const c_void, size: u64) -> i64 { + // SAFETY: The test owns the Vec for the entire synchronous save call. + let bytes = unsafe { &mut *((*stream).ctx as *mut Vec) }; + bytes.extend_from_slice(unsafe { + std::slice::from_raw_parts(buffer as *const u8, size as usize) + }); + size as i64 +} +unsafe extern "C" fn read(stream: *const clap_istream, buffer: *mut c_void, size: u64) -> i64 { + // SAFETY: The test owns the Cursor; the wrapper supplies writable stream storage. + let cursor = unsafe { &mut *((*stream).ctx as *mut Cursor>) }; + cursor + .read(unsafe { std::slice::from_raw_parts_mut(buffer as *mut u8, size as usize) }) + .unwrap() as i64 +} + +#[test] +fn effect_ports_state_latency_and_audio_lifecycle() { + // SAFETY: All callbacks, strings, streams, buffers, and the host outlive their + // synchronous ABI calls. Activation/processing/destruction follow CLAP order. + unsafe { + let entry = &knurl::clap_entry; + assert!(entry.init.unwrap()(c"knurl.clap".as_ptr())); + let factory = entry.get_factory.unwrap()(CLAP_PLUGIN_FACTORY_ID.as_ptr()) + as *const clap_plugin_factory; + assert!(!factory.is_null()); + let factory = &*factory; + assert_eq!(factory.get_plugin_count.unwrap()(factory), 1); + let descriptor = factory.get_plugin_descriptor.unwrap()(factory, 0); + assert!(!descriptor.is_null()); + assert_eq!(CStr::from_ptr((*descriptor).name), c"Knurl"); + assert_eq!( + CStr::from_ptr((*descriptor).id), + c"io.storyboard.cycle-texture" + ); + assert!(factory.get_plugin_descriptor.unwrap()(factory, 1).is_null()); + let host = clap_host { + clap_version: CLAP_VERSION, + host_data: ptr::null_mut(), + name: c"Storyboard test host".as_ptr(), + vendor: c"Tests".as_ptr(), + url: c"".as_ptr(), + version: c"1.0".as_ptr(), + get_extension: Some(extension), + request_restart: Some(request), + request_process: Some(request), + request_callback: Some(request), + }; + let plugin = factory.create_plugin.unwrap()(factory, &host, (*descriptor).id); + assert!(!plugin.is_null()); + let p = &*plugin; + assert!(p.init.unwrap()(plugin)); + let ports = p.get_extension.unwrap()(plugin, CLAP_EXT_AUDIO_PORTS.as_ptr()) + as *const clap_plugin_audio_ports; + assert!(!ports.is_null()); + assert_eq!((*ports).count.unwrap()(plugin, false), 1); + assert_eq!((*ports).count.unwrap()(plugin, true), 1); + let latency = p.get_extension.unwrap()(plugin, CLAP_EXT_LATENCY.as_ptr()) + as *const clap_plugin_latency; + assert!(!latency.is_null()); + let state = + p.get_extension.unwrap()(plugin, CLAP_EXT_STATE.as_ptr()) as *const clap_plugin_state; + assert!(!state.is_null()); + let state = &*state; + let save = || { + let mut bytes = Vec::new(); + let stream = clap_ostream { + ctx: &mut bytes as *mut Vec as *mut c_void, + write: Some(write), + }; + assert!(state.save.unwrap()(plugin, &stream)); + bytes + }; + let mut envelope: nih_plug::prelude::PluginState = + serde_json::from_slice(&save()[8..]).unwrap(); + use nih_plug::wrapper::state::ParamValue; + envelope.params.insert("edge".into(), ParamValue::F32(30.)); + envelope.params.insert("steps".into(), ParamValue::I32(3)); + envelope + .params + .insert("seed".into(), ParamValue::String("free".into())); + envelope + .params + .insert("source".into(), ParamValue::String("midi".into())); + // Pitch from MIDI and no note arrives, so the audio check below sees the dry input + // even with a pattern set. + envelope + .params + .insert("level-jitter".into(), ParamValue::F32(0.)); + envelope + .params + .insert("time-jitter".into(), ParamValue::F32(0.)); + envelope.params.insert("grit".into(), ParamValue::F32(-60.)); + let (gains, grit) = ([-6f32; 16], [true; 16]); + let mut pattern = serde_json::json!({ "gains": gains, "grit": grit }); + pattern["grit"][5] = false.into(); + envelope + .fields + .insert("knurl-pattern".into(), pattern.to_string()); + let encoded = serde_json::to_vec(&envelope).unwrap(); + let mut framed = (encoded.len() as u64).to_le_bytes().to_vec(); + framed.extend_from_slice(&encoded); + let mut bytes = Cursor::new(framed); + let stream = clap_istream { + ctx: &mut bytes as *mut Cursor> as *mut c_void, + read: Some(read), + }; + assert!(state.load.unwrap()(plugin, &stream)); + let restored: nih_plug::prelude::PluginState = + serde_json::from_slice(&save()[8..]).unwrap(); + assert_eq!( + serde_json::to_value(&restored.params).unwrap(), + serde_json::to_value(&envelope.params).unwrap() + ); + let saved: serde_json::Value = + serde_json::from_str(&restored.fields["knurl-pattern"]).unwrap(); + assert_eq!(saved, pattern); + for rate in [44100., 48000., 96000.] { + assert!(p.activate.unwrap()(plugin, rate, 1, 512)); + let delay = (*latency).get.unwrap()(plugin) as usize; + // About 67 ms lookahead plus 4.2 ms of timing-jitter headroom. + assert!((delay as f64 / rate - 0.071).abs() < 0.01, "{delay}"); + assert!(p.start_processing.unwrap()(plugin)); + let total = delay + 9600; + let mut position = 0; + let (mut energy_in, mut energy_out) = (0f64, 0f64); + while position < total { + let frames = [1, 127, 512, 31][position % 4].min(total - position); + // With no MIDI note and every effect off, a tone passes through unchanged. + let tone = |n: usize| { + 0.25 * (std::f64::consts::TAU * 1000. * n as f64 / rate).sin() as f32 + }; + let mut input_left = [0f32; 512]; + let mut input_right = [0f32; 512]; + for i in 0..frames { + input_left[i] = tone(position + i); + input_right[i] = -tone(position + i); + } + let mut left = [0f32; 512]; + let mut right = [0f32; 512]; + let mut in_channels = [input_left.as_mut_ptr(), input_right.as_mut_ptr()]; + let mut out_channels = [left.as_mut_ptr(), right.as_mut_ptr()]; + let incoming = clap_audio_buffer { + data32: in_channels.as_mut_ptr(), + data64: ptr::null_mut(), + channel_count: 2, + latency: 0, + constant_mask: 0, + }; + let mut outgoing_audio = clap_audio_buffer { + data32: out_channels.as_mut_ptr(), + data64: ptr::null_mut(), + channel_count: 2, + latency: 0, + constant_mask: 0, + }; + let input = clap_input_events { + ctx: ptr::null_mut(), + size: Some(count), + get: Some(event), + }; + let outgoing = clap_output_events { + ctx: ptr::null_mut(), + try_push: Some(push), + }; + let process = clap_process { + steady_time: position as i64, + frames_count: frames as u32, + transport: ptr::null(), + audio_inputs: &incoming, + audio_outputs: &mut outgoing_audio, + audio_inputs_count: 1, + audio_outputs_count: 1, + in_events: &input, + out_events: &outgoing, + }; + assert_ne!(p.process.unwrap()(plugin, &process), CLAP_PROCESS_ERROR); + for i in 0..frames { + let n = position + i; + if n < delay { + assert!(left[i].abs() < 1e-6, "output before the lookahead"); + } else if n > delay + 4800 { + energy_in += (tone(n - delay) as f64).powi(2); + energy_out += (left[i] as f64).powi(2) + (right[i] as f64).powi(2); + } + } + position += frames; + } + let ratio_db = 10. * (energy_out / (2. * energy_in)).log10(); + assert!(ratio_db.abs() < 0.2, "{ratio_db}"); + p.stop_processing.unwrap()(plugin); + p.deactivate.unwrap()(plugin); + } + p.destroy.unwrap()(plugin); + entry.deinit.unwrap()(); + } +} diff --git a/plugins/knurl/ui/Cargo.toml b/plugins/knurl/ui/Cargo.toml new file mode 100644 index 0000000..b769231 --- /dev/null +++ b/plugins/knurl/ui/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "knurl-ui" +version = "0.1.0" +edition.workspace = true +license.workspace = true + +[dependencies] +egui = "0.31.1" +knurl-core = { path = "../core" } +common-ui = { path = "../../common/ui" } +common-dsp = { path = "../../common/dsp" } diff --git a/plugins/knurl/ui/src/lib.rs b/plugins/knurl/ui/src/lib.rs new file mode 100644 index 0000000..880a25e --- /dev/null +++ b/plugins/knurl/ui/src/lib.rs @@ -0,0 +1,501 @@ +//! Knurl editor, shared by the CLAP wrapper and the headless renderer. +use common_ui::*; +use egui::{self, Color32, FontId, Pos2, Rect, RichText, Sense, Stroke, Vec2}; +use knurl_core::{ + AnalyzerFrame, Seed, Settings, Source, GRIT_OFF, PATTERNS, SCOPE_CYCLES, SCOPE_POINTS, STEPS, + STEP_MIN, +}; + +pub use common_ui::style; +pub const WIDTH: u32 = 1040; +pub const HEIGHT: u32 = 650; + +const GRID: Color32 = Color32::from_rgb(24, 26, 30); +const TOP: f32 = 316.; + +pub struct State { + pub analyzer: AnalyzerFrame, + /// True while a pointer button is held, so knob drags become one host gesture. + pub gesture_active: bool, + pub help: String, +} +impl Default for State { + fn default() -> Self { + Self { + analyzer: AnalyzerFrame::default(), + gesture_active: false, + help: DEFAULT_HELP.into(), + } + } +} +const DEFAULT_HELP: &str = + "Every cycle of the note gets its own level, timing and grit. Counted in cycles, so it fits every note."; +impl State { + pub fn accept_frame(&mut self, frame: AnalyzerFrame) { + let old = self.analyzer; + self.analyzer = frame; + self.analyzer.input_db = frame.input_db.max(old.input_db - 3.); + self.analyzer.output_db = frame.output_db.max(old.output_db - 3.); + // Keep the last scope between notes. + if !frame.scope_valid && old.scope_valid { + self.analyzer.scope = old.scope; + self.analyzer.scope_valid = true; + } + } +} +fn hint(r: &egui::Response, state: &mut State, text: &str) { + if r.hovered() || r.has_focus() { + state.help = text.into(); + } +} +#[allow(clippy::too_many_arguments)] +fn knob( + ui: &mut egui::Ui, + state: &mut State, + name: &str, + value: &mut f32, + range: std::ops::RangeInclusive, + default: f32, + unit: &str, + help: &str, +) { + ui.vertical_centered(|ui| { + let r = rotary(ui, name, value, range, default, unit, 58., ACCENT); + hint(&r, state, help); + }); +} + +pub fn show(ui: &mut egui::Ui, settings: &mut Settings, state: &mut State) { + backdrop(ui); + state.help = DEFAULT_HELP.into(); + state.gesture_active = ui.input(|i| i.pointer.any_down()); + ui.add_space(2.); + header(ui, "KNURL", "CYCLE TEXTURE", |ui| { + let r = ui + .selectable_label(settings.bypass, RichText::new("BYPASS").size(13.)) + .on_hover_text("Crossfade to the delayed dry signal."); + if r.clicked() { + settings.bypass = !settings.bypass; + } + ui.separator(); + for (source, label) in [(Source::Midi, "MIDI"), (Source::Audio, "AUDIO")] { + let r = ui.selectable_label(settings.source == source, RichText::new(label).size(13.)); + if r.clicked() { + settings.source = source; + } + } + caption(ui, "PITCH FROM"); + }); + ui.add_space(6.); + ui.horizontal_top(|ui| { + panel(ui, |ui| { + ui.set_width(210.); + ui.set_min_height(TOP); + ui.vertical(|ui| note_panel(ui, settings, state)); + }); + ui.add_space(4.); + panel(ui, |ui| { + ui.set_width(ui.available_width()); + ui.vertical(|ui| { + let frame = state.analyzer; + scope(ui, &frame, 140.); + ui.add_space(4.); + pattern_editor(ui, settings, state, TOP - 144.); + }); + }); + }); + ui.add_space(6.); + panel(ui, |ui| { + ui.set_width(ui.available_width()); + ui.vertical(|ui| controls(ui, settings, state)); + }); + ui.separator(); + ui.label(RichText::new(&state.help).color(MUTED)); +} + +fn note_panel(ui: &mut egui::Ui, settings: &mut Settings, state: &mut State) { + let frame = state.analyzer; + caption(ui, "NOTE"); + let (name, hz) = match frame.note { + Some(n) if frame.hz > 0. => (common_dsp::note_name(n), format!("{:.1} Hz", frame.hz)), + _ if frame.hz > 0. => ("—".into(), format!("holding {:.1} Hz", frame.hz)), + _ => ("—".into(), "no note yet".into()), + }; + ui.label( + RichText::new(name) + .font(FontId::new(54., egui::FontFamily::Name("medium".into()))) + .color(if frame.note.is_some() { TEXT } else { DIM }), + ); + ui.label(RichText::new(hz).size(13.).color(MUTED)); + if frame.hz > 0. { + ui.label( + RichText::new(format!("one cycle = {:.1} ms", 1000. / frame.hz)) + .size(12.) + .color(DIM), + ); + } + ui.add_space(10.); + meter(ui, "IN", frame.input_db, STEEL, 110.); + meter(ui, "OUT", frame.output_db, ACCENT, 110.); + ui.add_space(10.); + caption(ui, "RANDOM"); + ui.horizontal(|ui| { + for (seed, label, help) in [ + ( + Seed::Same, + "SAME EVERY NOTE", + "Every note gets the same random sequence: identical notes sound identical.", + ), + ( + Seed::Free, + "FREE", + "The random sequences keep running, so every note differs.", + ), + ] { + let r = ui.selectable_label(settings.seed == seed, RichText::new(label).size(12.)); + if r.clicked() { + settings.seed = seed; + } + hint(&r, state, help); + } + }); + ui.add_space(6.); + let r = ui.checkbox( + &mut settings.snap, + RichText::new("Snap to semitone").size(12.), + ); + hint( + &r, + state, + "Round the detected pitch. Turn it off for slides.", + ); +} + +/// The last cycles of the output, overlaid; the newest is brightest. +fn scope(ui: &mut egui::Ui, frame: &AnalyzerFrame, height: f32) { + let (outer, _) = + ui.allocate_exact_size(Vec2::new(ui.available_width(), height), Sense::hover()); + let p = ui.painter_at(outer); + p.rect_filled(outer, 2., SCREEN); + p.text( + outer.left_top() + Vec2::new(8., 5.), + egui::Align2::LEFT_TOP, + format!("LAST {SCOPE_CYCLES} CYCLES, OVERLAID"), + FontId::proportional(10.), + MUTED, + ); + let plot = Rect::from_min_max( + outer.left_top() + Vec2::new(10., 20.), + outer.right_bottom() - Vec2::new(10., 8.), + ); + for t in [0.25f32, 0.5, 0.75] { + let x = plot.left() + plot.width() * t; + p.line_segment( + [Pos2::new(x, plot.top()), Pos2::new(x, plot.bottom())], + Stroke::new(1.0_f32, GRID), + ); + } + p.line_segment( + [ + Pos2::new(plot.left(), plot.center().y), + Pos2::new(plot.right(), plot.center().y), + ], + Stroke::new(1.0_f32, EDGE), + ); + if !frame.scope_valid { + p.text( + plot.center(), + egui::Align2::CENTER_CENTER, + "play a note", + FontId::proportional(12.), + DIM, + ); + return; + } + let peak = frame + .scope + .iter() + .flatten() + .fold(1e-6f32, |m, v| m.max(v.abs())); + // The newest cycle is still being written; draw the complete ones. + for (age, cycle) in frame.scope[..SCOPE_CYCLES - 1].iter().enumerate() { + let alpha = 0.2 + 0.8 * age as f32 / (SCOPE_CYCLES - 2) as f32; + let color = if age == SCOPE_CYCLES - 2 { + ACCENT + } else { + STEEL.gamma_multiply(alpha * 0.6) + }; + let points: Vec = cycle + .iter() + .enumerate() + .map(|(i, v)| { + Pos2::new( + plot.left() + plot.width() * i as f32 / (SCOPE_POINTS - 1) as f32, + plot.center().y - plot.height() * 0.48 * v / peak, + ) + }) + .collect(); + p.add(egui::Shape::line( + points, + Stroke::new( + if age == SCOPE_CYCLES - 2 { + 2.0_f32 + } else { + 1.0 + }, + color, + ), + )); + } +} + +fn step_y(rect: Rect, db: f32) -> f32 { + rect.top() + rect.height() * (db / STEP_MIN).clamp(0., 1.) +} + +/// One bar per step: drag to set its level, double-click to reset; the square below a bar +/// switches its grit burst. +fn pattern_editor(ui: &mut egui::Ui, settings: &mut Settings, state: &mut State, height: f32) { + let (outer, response) = ui.allocate_exact_size( + Vec2::new(ui.available_width(), height), + Sense::click_and_drag(), + ); + let p = ui.painter_at(outer); + p.rect_filled(outer, 2., SCREEN); + p.text( + outer.left_top() + Vec2::new(8., 5.), + egui::Align2::LEFT_TOP, + "PATTERN: LEVEL PER CYCLE", + FontId::proportional(10.), + MUTED, + ); + let bars = Rect::from_min_max( + outer.left_top() + Vec2::new(34., 22.), + Pos2::new(outer.right() - 10., outer.bottom() - 26.), + ); + let toggles_y = outer.bottom() - 16.; + let col = bars.width() / STEPS as f32; + let column = + |x: f32| (((x - bars.left()) / col).floor() as isize).clamp(0, STEPS as isize - 1) as usize; + if response.hovered() { + state.help = "Drag a bar to set the level of that cycle; double-click resets it. The squares switch grit per step.".into(); + } + if let Some(pos) = response.interact_pointer_pos() { + let k = column(pos.x); + if pos.y > bars.bottom() + 2. { + if response.clicked() { + settings.grit_steps[k] = !settings.grit_steps[k]; + } + } else if response.double_clicked() { + settings.pattern[k] = 0.; + } else if response.dragged() || response.clicked() { + let t = ((pos.y - bars.top()) / bars.height()).clamp(0., 1.); + let db = t * STEP_MIN; + settings.pattern[k] = if db > -0.5 { 0. } else { db.round() }; + if k >= settings.steps { + settings.steps = k + 1; + } + } + } + for db in [0f32, -6., -12., -18., -24.] { + let y = step_y(bars, db); + p.line_segment( + [Pos2::new(bars.left(), y), Pos2::new(bars.right(), y)], + Stroke::new(1.0_f32, GRID), + ); + p.text( + Pos2::new(outer.left() + 6., y), + egui::Align2::LEFT_CENTER, + if db == 0. { + "0".into() + } else { + format!("{db:.0}") + }, + FontId::proportional(10.), + DIM, + ); + } + let current = state.analyzer.step; + let playing = state.analyzer.note.is_some(); + for k in 0..STEPS { + let on = k < settings.steps; + let x0 = bars.left() + k as f32 * col + 3.; + let x1 = x0 + col - 6.; + let top = step_y(bars, settings.pattern[k]); + let color = if !on { + DIM.gamma_multiply(0.5) + } else if playing && k == current { + TEXT + } else { + ACCENT + }; + p.rect_filled( + Rect::from_min_max( + Pos2::new(x0, top.min(bars.bottom() - 2.)), + Pos2::new(x1, bars.bottom()), + ), + 1., + color.gamma_multiply(if on { 0.85 } else { 0.4 }), + ); + let grit = settings.grit_steps[k] && settings.grit > GRIT_OFF; + let square = Rect::from_center_size(Pos2::new((x0 + x1) / 2., toggles_y), Vec2::splat(9.)); + if settings.grit_steps[k] { + p.rect_filled(square, 1., if grit && on { FOCUS } else { DIM }); + } else { + p.rect_stroke( + square, + 1., + Stroke::new(1.0_f32, DIM), + egui::StrokeKind::Inside, + ); + } + } + p.text( + Pos2::new(outer.left() + 6., toggles_y), + egui::Align2::LEFT_CENTER, + "grit", + FontId::proportional(10.), + DIM, + ); +} + +fn controls(ui: &mut egui::Ui, settings: &mut Settings, state: &mut State) { + let d = Settings::default(); + ui.horizontal(|ui| { + caption(ui, "PATTERN"); + for (name, help, gains) in PATTERNS { + let selected = settings.steps == gains.len() + && settings.pattern[..gains.len()] + .iter() + .zip(gains) + .all(|(a, b)| a == b); + let r = ui.selectable_label(selected, RichText::new(name.to_uppercase()).size(13.)); + if r.clicked() { + settings.apply_pattern(gains); + } + hint(&r, state, help); + } + ui.add_space(24.); + caption(ui, "STEPS"); + let minus = ui.button(RichText::new("−").size(14.)); + if minus.clicked() && settings.steps > 1 { + settings.steps -= 1; + } + ui.label( + RichText::new(format!("{:>2}", settings.steps)) + .monospace() + .size(14.) + .color(TEXT), + ); + let plus = ui.button(RichText::new("+").size(14.)); + if plus.clicked() && settings.steps < STEPS { + settings.steps += 1; + } + let help = "Pattern length in cycles. 2 makes a sub-octave, 3 an octave and a fifth down."; + hint(&minus, state, help); + hint(&plus, state, help); + }); + ui.add_space(4.); + ui.columns(10, |c| { + knob( + &mut c[0], + state, + "Edge", + &mut settings.edge, + 5. ..=50., + d.edge, + " %", + "How soft each step change is, as a share of a cycle. Low is sharper and buzzier.", + ); + knob( + &mut c[1], + state, + "Level", + &mut settings.level_jitter, + 0. ..=6., + d.level_jitter, + " dB", + "Random level per cycle: a rough, living surface.", + ); + knob( + &mut c[2], + state, + "Time", + &mut settings.time_jitter, + 0. ..=10., + d.time_jitter, + " %", + "Random timing per cycle, in percent of a period: rattle and scrape.", + ); + knob( + &mut c[3], + state, + "Grit", + &mut settings.grit, + GRIT_OFF..=0., + d.grit, + " dB", + "Level of the noise burst in each cycle, relative to the input. Fully left is off.", + ); + knob( + &mut c[4], + state, + "Tone", + &mut settings.tone, + 4. ..=64., + d.tone, + " ×f0", + "Lowest frequency of the grit, in harmonics of the note.", + ); + knob( + &mut c[5], + state, + "Position", + &mut settings.position, + 0. ..=100., + d.position, + " %", + "Where in the cycle the grit burst sits.", + ); + knob( + &mut c[6], + state, + "Length", + &mut settings.length, + 2. ..=50., + d.length, + " %", + "Length of the grit burst, as a share of a cycle.", + ); + knob( + &mut c[7], + state, + "Gate", + &mut settings.gate, + -60. ..=-20., + d.gate, + " dB", + "Input level that counts as a note (AUDIO). Raise it if tails retrigger.", + ); + knob( + &mut c[8], + state, + "Mix", + &mut settings.mix, + 0. ..=100., + d.mix, + " %", + "Blend with the delayed dry signal.", + ); + knob( + &mut c[9], + state, + "Output", + &mut settings.output, + -12. ..=12., + d.output, + " dB", + "Output trim.", + ); + }); +} diff --git a/tools/editor-check/Cargo.lock b/tools/editor-check/Cargo.lock index d719d79..0877146 100644 --- a/tools/editor-check/Cargo.lock +++ b/tools/editor-check/Cargo.lock @@ -158,6 +158,8 @@ dependencies = [ "crucible-ui", "egui", "image", + "knurl-core", + "knurl-ui", "lathe-core", "lathe-ui", "patina-core", @@ -252,6 +254,24 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +[[package]] +name = "knurl-core" +version = "0.1.0" +dependencies = [ + "common-dsp", + "serde", +] + +[[package]] +name = "knurl-ui" +version = "0.1.0" +dependencies = [ + "common-dsp", + "common-ui", + "egui", + "knurl-core", +] + [[package]] name = "lathe-core" version = "0.1.0" diff --git a/tools/editor-check/Cargo.toml b/tools/editor-check/Cargo.toml index 64b0127..7171e32 100644 --- a/tools/editor-check/Cargo.toml +++ b/tools/editor-check/Cargo.toml @@ -23,5 +23,7 @@ lathe-core = { path = "../../plugins/lathe/core" } lathe-ui = { path = "../../plugins/lathe/ui" } temper-core = { path = "../../plugins/temper/core" } temper-ui = { path = "../../plugins/temper/ui" } +knurl-core = { path = "../../plugins/knurl/core" } +knurl-ui = { path = "../../plugins/knurl/ui" } weld-core = { path = "../../plugins/weld/core" } weld-ui = { path = "../../plugins/weld/ui" } diff --git a/tools/editor-check/src/main.rs b/tools/editor-check/src/main.rs index f735f97..3418123 100644 --- a/tools/editor-check/src/main.rs +++ b/tools/editor-check/src/main.rs @@ -11,11 +11,11 @@ fn main() { .map(|a| a[1].as_str()) .unwrap_or("rivet"); if ![ - "rivet", "patina", "anvil", "crucible", "lathe", "temper", "weld", + "rivet", "patina", "anvil", "crucible", "lathe", "temper", "weld", "knurl", ] .contains(&plugin) { - eprintln!("Use --plugin rivet, patina, anvil, crucible, lathe, temper or weld"); + eprintln!("Use --plugin rivet, patina, anvil, crucible, lathe, temper, weld or knurl"); std::process::exit(2); } let patina = plugin == "patina" || args.iter().any(|arg| arg == "--resonance"); @@ -25,7 +25,10 @@ fn main() { let lathe = plugin == "lathe"; let temper = plugin == "temper"; let weld = plugin == "weld"; - let (width, height) = if weld { + let knurl = plugin == "knurl"; + let (width, height) = if knurl { + (knurl_ui::WIDTH, knurl_ui::HEIGHT) + } else if weld { (weld_ui::WIDTH, weld_ui::HEIGHT) } else if temper { (temper_ui::WIDTH, temper_ui::HEIGHT) @@ -146,6 +149,22 @@ fn main() { } temper_state.accept_frame(engine.take_analyzer()); } + let mut knurl_settings = knurl_core::Settings::default(); + let mut knurl_state = knurl_ui::State::default(); + if knurl { + // An F1 saw bass with the default Fry pattern, jitter and grit. + let mut engine = knurl_core::Engine::new(48000., 2).unwrap(); + engine.set_settings(knurl_settings).unwrap(); + let mut saw = common_dsp::Saw::new(48000., 43.65); + for i in 0..36000 { + let x = (saw.sample() * 2.2).tanh() * 0.5; + engine.process_sample([x, x]); + if i % 1600 == 0 { + knurl_state.accept_frame(engine.take_analyzer()); + } + } + knurl_state.accept_frame(engine.take_analyzer()); + } let mut weld_settings = weld_core::Settings::default(); let mut weld_state = weld_ui::State::default(); if weld { @@ -275,7 +294,9 @@ fn main() { let session_motif = session.motifs[0].id; shared.replace(session).unwrap(); let ctx = egui::Context::default(); - if weld { + if knurl { + knurl_ui::style(&ctx); + } else if weld { weld_ui::style(&ctx); } else if temper { temper_ui::style(&ctx); @@ -310,7 +331,9 @@ fn main() { }, |ui| { egui::CentralPanel::default().show(ui, |ui| { - if weld { + if knurl { + knurl_ui::show(ui, &mut knurl_settings, &mut knurl_state); + } else if weld { weld_ui::show(ui, &mut weld_settings, &mut weld_state); } else if temper { temper_ui::show(ui, &mut temper_settings, &mut temper_state);