From c06d193b1801b8b27e8b519e8951773687885fe0 Mon Sep 17 00:00:00 2001 From: Nils Pukropp Date: Fri, 6 Nov 2026 12:51:49 +0100 Subject: [PATCH] feat(planish): add Planish harmonic OTT Upward and downward compression in four bands whose edges are harmonic numbers of the tracked note (default 1, 2-4, 5-16, 17 and up), so the same setting squashes the same harmonics on every note. A fixed-band OTT puts harmonic 2 of F1 and of C2 in different bands. - Three Linkwitz-Riley splits at sqrt(k(k+1)) x f0 with allpass compensation; at Depth 0 the bands sum within 0.05 dB. - Band level is the RMS over one period of the note, so heavy settings do not ripple at f0: a 40 Hz sine at Drive +12 dB, Time 10 % gets no harmonics above -110 dB. - At Depth 100 % on a saw, harmonics 1-12 change by the same amount on F1, C2 and G2 (within 0.2 dB). - Depth, Drive (on the detector only), Upward, Downward, Time, a gain per band; edges Low 1-8, Mid 2-16, High 3-48 with four splits. - Pitch from audio with about 67 ms lookahead, or from MIDI. - Editor: harmonic ruler with draggable edges, level and gain per band. - Catalog, workflows, editor-check, docs, signal chain and site copy. --- .gitea/workflows/check.yml | 4 +- .gitea/workflows/release.yml | 2 +- Cargo.lock | 19 + Cargo.toml | 6 +- README.md | 13 +- docs/chain.md | 16 +- docs/development.md | 5 +- docs/ideas.md | 18 +- docs/planish/CHANGELOG.md | 14 + docs/planish/README.md | 97 + docs/planish/assets/editor.png | Bin 0 -> 314427 bytes docs/releases.md | 1 + plugins/catalog.json | 17 + plugins/planish/core/Cargo.toml | 12 + plugins/planish/core/src/lib.rs | 412 ++++ plugins/planish/core/src/settings.rs | 128 ++ plugins/planish/core/tests/dsp.rs | 309 +++ plugins/planish/core/tests/realtime.rs | 71 + plugins/planish/plugin/Cargo.lock | 2381 ++++++++++++++++++++++++ plugins/planish/plugin/Cargo.toml | 25 + plugins/planish/plugin/src/lib.rs | 185 ++ plugins/planish/plugin/src/params.rs | 192 ++ plugins/planish/plugin/tests/host.rs | 214 +++ plugins/planish/ui/Cargo.toml | 11 + plugins/planish/ui/src/lib.rs | 507 +++++ tools/editor-check/Cargo.lock | 20 + tools/editor-check/Cargo.toml | 2 + tools/editor-check/src/main.rs | 39 +- website/src/data/plugins.ts | 15 + 29 files changed, 4707 insertions(+), 28 deletions(-) create mode 100644 docs/planish/CHANGELOG.md create mode 100644 docs/planish/README.md create mode 100644 docs/planish/assets/editor.png create mode 100644 plugins/planish/core/Cargo.toml create mode 100644 plugins/planish/core/src/lib.rs create mode 100644 plugins/planish/core/src/settings.rs create mode 100644 plugins/planish/core/tests/dsp.rs create mode 100644 plugins/planish/core/tests/realtime.rs create mode 100644 plugins/planish/plugin/Cargo.lock create mode 100644 plugins/planish/plugin/Cargo.toml create mode 100644 plugins/planish/plugin/src/lib.rs create mode 100644 plugins/planish/plugin/src/params.rs create mode 100644 plugins/planish/plugin/tests/host.rs create mode 100644 plugins/planish/ui/Cargo.toml create mode 100644 plugins/planish/ui/src/lib.rs diff --git a/.gitea/workflows/check.yml b/.gitea/workflows/check.yml index 0a91601..32e0234 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, knurl] + plugin: [rivet, patina, anvil, crucible, lathe, temper, weld, knurl, planish] steps: - uses: https://github.com/actions/checkout@v4 with: @@ -62,6 +62,7 @@ jobs: 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 + cargo run --manifest-path tools/editor-check/Cargo.toml --locked -- target/editor/planish.png --plugin planish - uses: https://github.com/actions/upload-artifact@v3-node20 with: name: editor-previews @@ -93,6 +94,7 @@ jobs: 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/build-plugin.py --plugin planish --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 9ea3625..60e5c9a 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*", "knurl-v*"] + tags: ["rivet-v*", "patina-v*", "anvil-v*", "crucible-v*", "lathe-v*", "temper-v*", "weld-v*", "knurl-v*", "planish-v*"] permissions: contents: read diff --git a/Cargo.lock b/Cargo.lock index 80a45a7..6b8583d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -327,6 +327,25 @@ dependencies = [ "patina-core", ] +[[package]] +name = "planish-core" +version = "0.1.0" +dependencies = [ + "common-dsp", + "serde", + "serde_json", +] + +[[package]] +name = "planish-ui" +version = "0.1.0" +dependencies = [ + "common-dsp", + "common-ui", + "egui", + "planish-core", +] + [[package]] name = "primal-check" version = "0.3.4" diff --git a/Cargo.toml b/Cargo.toml index 9f38650..bb4a0fa 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/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"] +members = ["plugins/common/ui", "plugins/common/dsp", "plugins/anvil/core", "plugins/anvil/ui", "plugins/lathe/core", "plugins/lathe/ui", "plugins/temper/core", "plugins/temper/ui", "plugins/weld/core", "plugins/weld/ui", "plugins/knurl/core", "plugins/knurl/ui", "plugins/planish/core", "plugins/planish/ui", "plugins/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", "plugins/planish/plugin"] [workspace.package] edition = "2021" @@ -26,6 +26,8 @@ opt-level = 2 opt-level = 2 [profile.dev.package.knurl-core] opt-level = 2 +[profile.dev.package.planish-core] +opt-level = 2 [profile.dev.package.weld-core] opt-level = 2 diff --git a/README.md b/README.md index ea666d0..6ba78ee 100644 --- a/README.md +++ b/README.md @@ -28,9 +28,10 @@ note. Each plugin is a separate product with its own version, guide and release. | **[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) | +| **[Planish](docs/planish/README.md)** | Upward and downward compression (OTT) in bands set by harmonic number: band 2 holds harmonics 2–4 on every note | Bass | ≈ 67 ms | [Guide](docs/planish/README.md) · [Changes](docs/planish/CHANGELOG.md) | Plugins with latency report it to the host, so FL Studio compensates the delay. -Anvil, Lathe, Temper and Knurl detect pitch from the audio. They can also take the +Anvil, Lathe, Temper, Knurl and Planish detect pitch from the audio. They can also take the pitch from MIDI. The order of the plugins matters: see [Signal chain](docs/chain.md). The names come from metalwork: a **rivet** joins pieces; **patina** changes a @@ -38,7 +39,8 @@ 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; -**knurling** presses a ridged grip pattern into a surface. +**knurling** presses a ridged grip pattern into a surface; **planishing** +hammers a surface smooth and even. 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*. @@ -61,6 +63,10 @@ finished. Hosts list the plugins under the vendor name *Bass Foundry*. Weld editor
Weld: layer phase alignment Knurl editor
Knurl: cycle texture + + Planish editor
Planish: harmonic OTT + + The previews are rendered headless from the real editor code by @@ -119,7 +125,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`, `weld` and `knurl`. Builds go to `dist//.clap`. No +`lathe`, `temper`, `weld`, `knurl` and `planish`. Builds go to `dist//.clap`. No script installs anything into a DAW. [Development and testing](docs/development.md) has the full command list. @@ -157,6 +163,7 @@ plugins/ temper/ core · ui · plugin weld/ core · ui · plugin knurl/ core · ui · plugin + planish/ 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/chain.md b/docs/chain.md index c241ff3..ddb7743 100644 --- a/docs/chain.md +++ b/docs/chain.md @@ -1,18 +1,21 @@ # Signal chain -The order of the Bass Foundry plugins in a chain matters. Anvil, Lathe, Temper -and Knurl each detect the pitch from the audio they receive. If a plugin earlier +The order of the Bass Foundry plugins in a chain matters. Anvil, Lathe, Temper, +Knurl and Planish each detect the pitch from the audio they receive. If a plugin earlier in the chain changes the audio, the pitch detection after it can go wrong. ## Recommended order ```text -bass track: synth → Lathe → Temper → Knurl → Patina → Weld +bass track: synth → Lathe → Temper → Planish → Knurl → Patina → Weld bass bus: Anvil → (bus compression, clipping) → Crucible ``` - **Lathe and Temper before Knurl.** They hear the plain synth, where the pitch is clear. +- **Planish after the distortion, before Knurl.** OTT usually comes after + distortion. Planish's band edges follow the tracked note, so it also needs a + clear pitch: after Knurl, use MIDI. - **Knurl last among the tracked plugins.** See below. - **Patina after the tracked plugins.** It does not detect pitch, so the order does not change its result. @@ -35,15 +38,16 @@ tracker on a saw bass: - Below C2 the false sub-octave is under 30 Hz, out of the detection range, so low notes are tracked correctly. - Level and time jitter add 5–25 false note starts per second. Anvil restarts - its phase on each, Lathe and Temper retune on each. + its phase on each, Lathe, Temper and Planish retune on each. When a tracked plugin must come after Knurl, select **MIDI** as its pitch source and route the bass's MIDI notes to it. ## Latency -Each tracked plugin adds its own lookahead: Anvil 80 ms, Lathe and Temper about -67 ms, Knurl about 71 ms, Patina about 45 ms. A full chain is about 330 ms. FL +Each tracked plugin adds its own lookahead: Anvil 80 ms, Lathe, Temper and +Planish about 67 ms, Knurl about 71 ms, Patina about 45 ms. A full chain is +about 400 ms. FL Studio compensates this for playback and rendering, but playing a MIDI keyboard through the full chain is not practical. Write with a shorter chain and add the rest for the mix. diff --git a/docs/development.md b/docs/development.md index c40fa12..1b9f8ad 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, Temper and Knurl, 4× oversampling, meters and WAV files. + Lathe, Temper, Knurl and Planish, 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 @@ -45,7 +45,7 @@ python3 -m unittest discover -s scripts/tests -v ``` Products: `rivet`, `patina`, `anvil`, `crucible`, `lathe`, `temper`, `weld`, -`knurl`. +`knurl`, `planish`. `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 @@ -144,6 +144,7 @@ identify plugins by CLAP ID, so the vendor name does not affect saved projects. | Temper | (new) | `io.narl.bass-foundry.temper` | | Weld | (new) | `io.narl.bass-foundry.weld` | | Knurl | (new) | `io.narl.bass-foundry.knurl` | +| Planish | (new) | `io.narl.bass-foundry.planish` | CLAP IDs use the form `io.narl.bass-foundry.`. Builds tagged before this scheme used `io.storyboard.*` IDs; hosts treat the new IDs as different diff --git a/docs/ideas.md b/docs/ideas.md index 18c43db..cb69f2b 100644 --- a/docs/ideas.md +++ b/docs/ideas.md @@ -131,6 +131,14 @@ 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). +### Planish — harmonic OTT (problem 16) + +Upward and downward compression in four bands whose edges are harmonic numbers +of the tracked note (default 1, 2–4, 5–16, 17 and up), so the same setting +squashes the same harmonics on every note. Each band's level is measured over +one period of the note, so heavy settings do not ripple at f0. Built, not yet +released. See [Planish](planish/README.md). + ## Next for released plugins - **Anvil**: *Kick lock*: the kick through the sidechain ducks the sub on each @@ -167,7 +175,8 @@ is the same on every note. Slow per-harmonic drift is postponed. See Patina already cut fixed formants on every note, but it also cut a boosted harmonic as hard (5.7 dB), at a position that moved with the note. Open: MIDI as the pitch source. -3. Planish, then Quench and Ballast: they fill the mix and master gap. +3. Planish (done, unreleased), then Quench and Ballast: they fill the mix and + master gap. 4. Forge, when enough modules exist. 5. Assay, one plugin for the display-only ideas. 6. Texture plugins (Anneal, Swarf, Etch, Bellows) and the note-keyed sequencer. @@ -185,13 +194,6 @@ before Knurl) and the repeated MIDI routing. The standalone plugins stay. Sharing one tracker between separate `.clap` files would need named shared memory across DLLs, which is fragile; one strip is simpler. -### Planish — OTT on harmonic numbers (problem 16) - -Planishing smooths metal with a hammer. Upward and downward compression in -bands whose edges are harmonic numbers of the tracked note (for example 1, -2–4, 5–16, 17 and up) instead of fixed Hz. OTT is on almost every riddim patch, -and with fixed bands it acts differently on every note. - ### Quench — sub-safe clipper (problem 17) Quenching hardens hot metal in one fast step. Quench clips only above a split diff --git a/docs/planish/CHANGELOG.md b/docs/planish/CHANGELOG.md new file mode 100644 index 0000000..e593475 --- /dev/null +++ b/docs/planish/CHANGELOG.md @@ -0,0 +1,14 @@ +# Planish changelog + +## 0.1.0 + +- Introduce Planish, upward and downward compression in four bands whose edges + are harmonic numbers of the played note. +- Band edges set by harmonic (Low 1–8, Mid 2–16, High 3–48), with splits + Classic, Sub + body, Tight and Wide top, or dragged on the harmonic ruler. +- Depth, Drive, Upward, Downward, Time and a gain per band. +- Band level measured over one period of the note, so heavy compression does + not ripple at the fundamental. +- Detect pitch and note starts from the audio with about 67 ms of latency, or + follow MIDI notes sent to the effect. +- Editor shows the bands on a harmonic ruler and each band's level and gain. diff --git a/docs/planish/README.md b/docs/planish/README.md new file mode 100644 index 0000000..a07fb43 --- /dev/null +++ b/docs/planish/README.md @@ -0,0 +1,97 @@ +# Planish + +Planish is upward and downward compression (OTT) in four bands whose edges are +harmonic numbers of the played note. Current version **0.1.0**. + +Planishing hammers a metal surface smooth and even. OTT does the same to a bass: +it pushes loud bands down and lifts quiet ones, and it is on almost every riddim +patch. A normal OTT splits the bands at fixed frequencies, though. A split at +88 Hz and 2.5 kHz puts harmonic 2 of F1 in the low band but harmonic 2 of C2 in +the mid band, so the same setting squashes different harmonics on every note. +Planish moves its band edges with the note: with the default split, band 1 is +the fundamental, band 2 harmonics 2–4, band 3 harmonics 5–16 and band 4 +everything above, on F1 as on G2. + +![Planish](assets/editor.png) + +## Install on Windows + +Copy `Planish.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 Planish 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 Planish tracks. The ruler at the + top shows harmonics 1–64 and the four bands; the columns below show each + band's level (steel) and gain (pink for a cut, blue for a lift). +2. Choose a split, or drag an edge on the ruler: + - **Classic** (1, 2–4, 5–16, 17+, the default): fundamental on its own. + - **Sub + body** (1–2, 3–6, 7–24, 25+): the octave stays with the sub. + - **Tight** (1, 2, 3–8, 9+): close control of the first harmonics. + - **Wide top** (1, 2–3, 4–32, 33+): one big mid band, the top is fizz only. +3. Set the amount: + - **Depth** blends each band with its compressed copy. 0 % is a clean sum + of the bands; the default is 50 %. + - **Drive** moves the band levels against the thresholds: more drive, more + squash. It does not change the level by itself. + - **Upward** and **Downward** scale the two directions. Downward pushes a + band above −30 dB down at about 20:1; Upward lifts a band below −42 dB at + about 4:1, by at most 24 dB. + - **Time** scales every attack and release. Lower bands are slower: at + 100 %, attack is 30, 15, 8 and 4 ms and release 200, 160, 120 and 90 ms + from band 1 to band 4. +4. **Band 1–4** set each band's gain after its compressor. Like the + compression, they are scaled by Depth. + +**Output** trims the level. **Bypass** crossfades to the delayed dry signal. + +### Pitch from MIDI + +For basses whose fundamental is unclear (heavy FM, formant or noise patches), +and when Planish comes after Knurl, select **MIDI** and route the bass's MIDI +notes to Planish. In FL Studio, set the bass channel's MIDI output port and +Planish'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; +it is off by default, because the level is measured over one period of the +pitch in use, and a detuned patch fits its real period better. + +## Measured + +- At Depth 0 the bands sum flat: sines from 35 Hz to 12 kHz come out within + 0.05 dB. +- The same setting changes the same harmonics on every note. At Depth 100 % + on a saw bass, harmonic 1 is cut by 13.6 dB on F1, C2 and G2; harmonics 1–12 + differ by less than 0.2 dB between the three notes. +- No ripple at the fundamental. A 40 Hz sine at Drive +12 dB and Time 10 % gets + no harmonics above −110 dB. + +## Timing and limits + +Planish delays the audio by about 67 ms of pitch-detection lookahead and +reports it to the host for delay compensation, so the edges are on the new note +when its attack leaves the plugin. Pitch range is 30–500 Hz, one note at a time. +Before the first note the edges sit on 55 Hz; between notes they hold the last +note. + +An edge is a slope, not a wall. The crossovers are 24 dB per octave, so the +harmonics next to an edge partly reach the next band, by the same amount on +every note. Both channels get the same gain per band, so the stereo image does +not move. Quiet signals below about −84 dB are not lifted, so noise floors and +tails stay down. + +Planish detects the pitch like Lathe and Temper. Put it before Knurl, or use +MIDI: see [Signal chain](../chain.md). + +## How it works + +A note tracker (shared with Anvil, Lathe, Temper and Knurl) detects pitch and +note starts ahead of the delayed audio. Three Linkwitz–Riley crossovers split +the signal at √(k(k+1)) × f0, halfway in log frequency between harmonic k and +k+1, and allpasses keep the lower bands in phase with the upper ones, so the +bands sum to an allpass. The crossovers retune every 16 samples and glide with +**Smooth** on bends. Each band's level is the RMS over exactly one period of +the note, so a steady note gives a steady level and the gain does not wobble +at f0. The level goes through attack and release smoothing, then a static +curve with an upward and a downward threshold sets the gain. diff --git a/docs/planish/assets/editor.png b/docs/planish/assets/editor.png new file mode 100644 index 0000000000000000000000000000000000000000..7783fe13bc26a4132139e1fb17a15b7b52dd09c1 GIT binary patch literal 314427 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ℜr1BO;B$=WLW_Fd2?VR_7&MUQZ}W=F${g%o#3%yq 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

{Y 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 oQZR_{l3a8Dqmy4a16;4_6PqBe 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 v2U|_;w>5K?UM>P@r`K{6;UKkabu=? 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 literal 0 HcmV?d00001 diff --git a/docs/releases.md b/docs/releases.md index 2d00caf..55b1d2d 100644 --- a/docs/releases.md +++ b/docs/releases.md @@ -15,6 +15,7 @@ workflows are in `.gitea/workflows/`. A plugin's version is the `version` in | Temper | `temper-v0.2.0` | `temper-windows-x86_64-0.2.0.zip` | | Weld | `weld-v0.2.0` | `weld-windows-x86_64-0.2.0.zip` | | Knurl | `knurl-v0.2.0` | `knurl-windows-x86_64-0.2.0.zip` | +| Planish | `planish-v0.1.0` | `planish-windows-x86_64-0.1.0.zip` | ## Make a release diff --git a/plugins/catalog.json b/plugins/catalog.json index 4c53977..604741e 100644 --- a/plugins/catalog.json +++ b/plugins/catalog.json @@ -131,5 +131,22 @@ "knurl-core", "knurl-ui" ] + }, + "planish": { + "name": "Planish", + "description": "Upward and downward compression in bands set by harmonic number, the same on every note", + "manifest": "plugins/planish/plugin/Cargo.toml", + "library": "planish", + "documentation": "docs/planish", + "clap_id": "io.narl.bass-foundry.planish", + "licenses": { + "plugins/common/ui/assets/OFL.txt": "licenses/Roboto-OFL.txt" + }, + "packages": [ + "common-ui", + "common-dsp", + "planish-core", + "planish-ui" + ] } } diff --git a/plugins/planish/core/Cargo.toml b/plugins/planish/core/Cargo.toml new file mode 100644 index 0000000..c325c9e --- /dev/null +++ b/plugins/planish/core/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "planish-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/planish/core/src/lib.rs b/plugins/planish/core/src/lib.rs new file mode 100644 index 0000000..ed0b7dd --- /dev/null +++ b/plugins/planish/core/src/lib.rs @@ -0,0 +1,412 @@ +//! Upward and downward compression in four bands whose edges are harmonic numbers of the +//! played note, so the same setting squashes the same harmonics on every note. +//! +//! The crossovers are Linkwitz–Riley splits retuned to the tracked fundamental, with allpass +//! compensation, so the bands sum flat. An edge sits halfway (in log frequency) between two +//! harmonics. It is a slope, not a wall: neighbours of an edge partly reach the next band, by +//! the same amount on every note. Each band's level is measured over exactly one period +//! of the note: a steady note gives a steady level, and the gain does not ripple at the +//! fundamental. The audio path is delayed by the tracker's lookahead, so the edges are on the +//! new note when its attack leaves the plugin. +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::{Settings, Source, BANDS, GAIN_MAX, GAIN_MIN, TOP_MAX}; + +pub const MIN_HZ: f32 = TrackerConfig::BASS.min_hz; +pub const MAX_HZ: f32 = TrackerConfig::BASS.max_hz; +/// Fundamental the edges sit on before the first note. +pub const FALLBACK_HZ: f32 = 55.; +/// Band levels are RMS over one period: a sine with peak 1 reads −3 dB. +pub const DOWN_THRESHOLD: f32 = -30.; +pub const UP_THRESHOLD: f32 = -42.; +/// Gain change per dB beyond the threshold at 100 %: about 20:1 downward, 4:1 upward. +const DOWN_SLOPE: f32 = 0.95; +const UP_SLOPE: f32 = 0.75; +/// Most lift a band can get. +pub const UP_MAX: f32 = 24.; +/// Below this level the lift fades out, so silence and noise floors are not raised. +pub const FLOOR: f32 = -84.; +const FLOOR_FADE: f32 = 12.; +/// Attack and release at Time 100 %, bottom band first: lower bands move slower. +pub const ATTACK_MS: [f32; BANDS] = [30., 15., 8., 4.]; +pub const RELEASE_MS: [f32; BANDS] = [200., 160., 120., 90.]; +/// Filter coefficients are recomputed this often, in samples. +const RETUNE: usize = 16; +const Q: f32 = std::f32::consts::FRAC_1_SQRT_2; +const SILENT: f32 = -120.; + +#[derive(Clone, Copy, Debug)] +pub struct AnalyzerFrame { + /// Fundamental the edges are tuned to, 0 before the first note. + pub hz: f32, + /// Sounding note, rounded; None between notes. + pub note: Option, + /// Crossover frequencies in Hz between the bands. + pub edges: [f32; BANDS - 1], + /// Band level plus Drive, in dB RMS, as the compressors see it. + pub levels: [f32; BANDS], + /// Gain of each compressor in dB at full depth, before the band gains. + pub gains: [f32; BANDS], + pub latency: u32, + pub sample_rate: f32, +} +impl Default for AnalyzerFrame { + fn default() -> Self { + Self { + hz: 0., + note: None, + edges: [0.; BANDS - 1], + levels: [SILENT; BANDS], + gains: [0.; BANDS], + latency: 0, + sample_rate: 48000., + } + } +} + +/// Gain in dB for a band level in dB, at the given upward and downward amounts (0–1). +pub fn compressor_gain(level: f32, upward: f32, downward: f32) -> f32 { + let down = if level > DOWN_THRESHOLD { + -(level - DOWN_THRESHOLD) * DOWN_SLOPE * downward + } else { + 0. + }; + let up = if level < UP_THRESHOLD { + let fade = ((level - FLOOR) / FLOOR_FADE).clamp(0., 1.); + let fade = fade * fade * (3. - 2. * fade); + ((UP_THRESHOLD - level) * UP_SLOPE * upward).min(UP_MAX) * fade + } else { + 0. + }; + down + up +} + +/// Mean of the last `n` values, with `n` changed only after a full window so the running sum +/// can be refreshed in the same step. Allocation-free after `new`. +struct Window { + ring: Vec, + at: usize, + n: usize, + next: usize, + count: usize, + sum: f32, +} +impl Window { + fn new(capacity: usize) -> Self { + Self { + ring: vec![0.; capacity + 1], + at: 0, + n: 1, + next: 1, + count: 0, + sum: 0., + } + } + fn set_len(&mut self, n: usize) { + self.next = n.clamp(1, self.ring.len() - 1); + } + fn push(&mut self, v: f32) -> f32 { + let cap = self.ring.len(); + self.sum += v - self.ring[(self.at + cap - self.n) % cap]; + self.ring[self.at] = v; + self.at = (self.at + 1) % cap; + self.count += 1; + if self.count >= self.n { + // Exact sum over the new length: no drift, and a length change takes effect here. + self.count = 0; + self.n = self.next; + self.sum = (1..=self.n) + .map(|i| self.ring[(self.at + cap - i) % cap]) + .sum(); + } + self.sum.max(0.) / self.n as f32 + } + fn reset(&mut self) { + self.ring.fill(0.); + self.sum = 0.; + self.count = 0; + } +} + +/// Filter state of one channel: three LR4 splits and the allpasses that keep the lower bands +/// in phase with the upper ones. +#[derive(Clone, Copy, Default)] +struct Channel { + low: [[Svf; 2]; BANDS - 1], + high: [[Svf; 2]; BANDS - 1], + /// Band 1 through the allpasses of splits 2 and 3, band 2 through split 3. + phase: [Svf; 3], +} +impl Channel { + // Bands, splits and channels index several parallel arrays at once. + #[allow(clippy::needless_range_loop)] + fn split(&mut self, c: &Coefs, x: f32) -> [f32; BANDS] { + let mut rest = x; + let mut bands = [0.; BANDS]; + for s in 0..BANDS - 1 { + let l = self.low[s][0].process(&c.low[s], rest); + bands[s] = self.low[s][1].process(&c.low[s], l); + let h = self.high[s][0].process(&c.high[s], rest); + rest = self.high[s][1].process(&c.high[s], h); + } + bands[BANDS - 1] = rest; + let b0 = self.phase[0].process(&c.all[1], bands[0]); + bands[0] = self.phase[1].process(&c.all[2], b0); + bands[1] = self.phase[2].process(&c.all[2], bands[1]); + bands + } +} +#[derive(Clone, Copy)] +struct Coefs { + low: [SvfCoef; BANDS - 1], + high: [SvfCoef; BANDS - 1], + all: [SvfCoef; BANDS - 1], +} + +pub struct Engine { + rate: f32, + channels: usize, + settings: Settings, + latency: usize, + delay: Vec<[f32; 2]>, + delay_at: usize, + tracker: Tracker, + pitch: PitchFollower, + hz: f32, + hz_coef: f32, + countdown: usize, + edges: [f32; BANDS - 1], + coefs: Coefs, + state: [Channel; 2], + windows: [Window; BANDS], + levels: [f32; BANDS], + gains: [f32; BANDS], + attack: [f32; BANDS], + release: [f32; BANDS], + smooth: f32, + depth: f32, + drive: f32, + band_gains: [f32; BANDS], + output: f32, + bypass: f32, + /// Smoothed controls start at the next settings instead of gliding from defaults. + fresh: bool, +} + +/// One-pole step that lands exactly on the target, so switched states end bit-exact. +fn approach(value: &mut f32, target: f32, coef: f32) { + *value += (target - *value) * coef; + if (target - *value).abs() < 1e-6 { + *value = target; + } +} + +impl Engine { + pub fn new(rate: f32, channels: usize) -> Result { + if !(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 latency = tracker.latency(); + let period = (rate / MIN_HZ.min(FALLBACK_HZ)).ceil() as usize + 1; + let identity = SvfCoef::IDENTITY; + let mut e = Self { + rate, + channels, + settings: Settings::default(), + latency, + delay: vec![[0.; 2]; latency + 1], + delay_at: 0, + tracker, + pitch: PitchFollower::default(), + hz: 0., + hz_coef: 1., + countdown: 0, + edges: [0.; BANDS - 1], + coefs: Coefs { + low: [identity; BANDS - 1], + high: [identity; BANDS - 1], + all: [identity; BANDS - 1], + }, + state: [Channel::default(); 2], + windows: std::array::from_fn(|_| Window::new(period)), + levels: [SILENT; BANDS], + gains: [0.; BANDS], + attack: [1.; BANDS], + release: [1.; BANDS], + smooth: coefficient(rate, 10.), + depth: 0., + drive: 0., + band_gains: [1.; BANDS], + output: 1., + bypass: 0., + fresh: true, + }; + e.set_settings(Settings::default())?; + e.fresh = true; + e.retune(); + Ok(e) + } + pub fn latency_samples(&self) -> u32 { + self.latency 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, s.smooth > 0.); + self.hz_coef = coefficient(self.rate, s.smooth / 3.); + if s.time != self.settings.time || self.fresh { + let scale = s.time * 0.01; + for b in 0..BANDS { + self.attack[b] = coefficient(self.rate, ATTACK_MS[b] * scale); + self.release[b] = coefficient(self.rate, RELEASE_MS[b] * scale); + } + } + if s.tops() != self.settings.tops() { + self.countdown = 0; + } + self.settings = s; + if std::mem::take(&mut self.fresh) { + self.depth = s.depth * 0.01; + self.drive = s.drive; + self.band_gains = s.gains.map(db_to_gain); + self.output = db_to_gain(s.output); + self.bypass = f32::from(s.bypass); + } + Ok(()) + } + pub fn reset(&mut self) { + self.delay.fill([0.; 2]); + self.tracker.reset(); + self.state = [Channel::default(); 2]; + for w in &mut self.windows { + w.reset(); + } + self.levels = [SILENT; BANDS]; + self.gains = [0.; BANDS]; + self.countdown = 0; + 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); + } + /// Fundamental the edges follow: the tracked note, or the fallback before the first one. + fn root(&self) -> f32 { + if self.hz > 0. { + self.hz + } else { + FALLBACK_HZ + } + } + // Bands, splits and channels index several parallel arrays at once. + #[allow(clippy::needless_range_loop)] + fn retune(&mut self) { + let root = self.root(); + let tops = self.settings.tops(); + for s in 0..BANDS - 1 { + // Geometric middle: the harmonics on both sides of an edge lose the same amount. + let k = tops[s] as f32; + let hz = ((k * (k + 1.)).sqrt() * root).clamp(10., 0.45 * self.rate); + self.edges[s] = hz; + self.coefs.low[s] = SvfCoef::lowpass(self.rate, hz, Q); + self.coefs.high[s] = SvfCoef::highpass(self.rate, hz, Q); + self.coefs.all[s] = SvfCoef::allpass(self.rate, hz, Q); + } + let period = (self.rate / root).round() as usize; + for w in &mut self.windows { + w.set_len(period); + } + } + // Bands, splits and channels index several parallel arrays at once. + #[allow(clippy::needless_range_loop)] + 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 len = self.delay.len(); + self.delay[self.delay_at] = x; + self.delay_at = (self.delay_at + 1) % len; + let y = self.delay[self.delay_at]; + + let (hz, jump) = self.pitch.step(self.hz_coef); + self.hz = hz; + if jump || self.countdown == 0 { + self.retune(); + self.countdown = RETUNE; + } + self.countdown -= 1; + + let s = self.settings; + approach(&mut self.depth, s.depth * 0.01, self.smooth); + approach(&mut self.drive, s.drive, self.smooth); + for b in 0..BANDS { + approach(&mut self.band_gains[b], db_to_gain(s.gains[b]), self.smooth); + } + approach(&mut self.output, db_to_gain(s.output), self.smooth); + approach(&mut self.bypass, f32::from(s.bypass), self.smooth); + + let mut bands = [[0.; BANDS]; 2]; + for c in 0..self.channels { + bands[c] = self.state[c].split(&self.coefs, y[c]); + } + let (up, down) = (s.upward * 0.01, s.downward * 0.01); + let mut wet = [0.; 2]; + for b in 0..BANDS { + let power = if self.channels == 2 { + 0.5 * (bands[0][b] * bands[0][b] + bands[1][b] * bands[1][b]) + } else { + bands[0][b] * bands[0][b] + }; + let level = 10. * (self.windows[b].push(power) + 1e-12).log10() + self.drive; + let coef = if level > self.levels[b] { + self.attack[b] + } else { + self.release[b] + }; + self.levels[b] += (level - self.levels[b]) * coef; + self.gains[b] = compressor_gain(self.levels[b], up, down); + let g = 1. + self.depth * (db_to_gain(self.gains[b]) * self.band_gains[b] - 1.); + for c in 0..self.channels { + wet[c] += bands[c][b] * g; + } + } + let mut out = [0.; 2]; + for c in 0..self.channels { + out[c] = wet[c] * self.output * (1. - self.bypass) + y[c] * self.bypass; + } + out + } + pub fn take_analyzer(&self) -> AnalyzerFrame { + let mut f = AnalyzerFrame { + hz: self.hz, + edges: self.edges, + levels: self.levels, + gains: self.gains, + latency: self.latency as u32, + sample_rate: self.rate, + ..AnalyzerFrame::default() + }; + if self.tracker.sounding() && self.hz > 0. { + f.note = Some(hz_to_midi(self.hz).round().clamp(0., 127.) as u8); + } + f + } +} diff --git a/plugins/planish/core/src/settings.rs b/plugins/planish/core/src/settings.rs new file mode 100644 index 0000000..f075847 --- /dev/null +++ b/plugins/planish/core/src/settings.rs @@ -0,0 +1,128 @@ +//! Host-independent controls. Levels in dB, times in milliseconds, amounts in percent. +use serde::{Deserialize, Serialize}; + +/// Bands: the fundamental, low harmonics, mid harmonics and the top. +pub const BANDS: usize = 4; +pub const GAIN_MIN: f32 = -24.; +pub const GAIN_MAX: f32 = 24.; +/// Highest harmonic a band edge can be set to. +pub const TOP_MAX: u32 = 48; + +#[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)] +#[serde(deny_unknown_fields)] +pub struct Settings { + pub source: Source, + /// Highest harmonic in the bottom band. 1 keeps the fundamental on its own. + pub low: u32, + /// Highest harmonic in the second band. + pub mid: u32, + /// Highest harmonic in the third band; everything above is the top band. + pub high: u32, + /// Share of the compressed signal, per band, against the dry band. + pub depth: f32, + /// Scales every attack and release time. + pub time: f32, + /// Amount of upward compression: quiet bands are lifted. + pub upward: f32, + /// Amount of downward compression: loud bands are pushed down. + pub downward: f32, + /// Gain on the level the compressors see, not on the audio: moves the band levels against + /// the thresholds. More drive means more squash; at Depth 0 it changes nothing. + pub drive: f32, + /// Gain of each band after its compressor, bottom band first. + pub gains: [f32; BANDS], + /// Retune time when the pitch slides or bends. + pub smooth: f32, + /// Detection threshold in dBFS for note starts (Audio source). + pub gate: f32, + /// Round detected pitch to the nearest semitone. Off by default: the level window is one + /// period of the pitch in use, and a detuned note then gets a window that does not fit. + pub snap: bool, + pub output: f32, + pub bypass: bool, +} +impl Default for Settings { + fn default() -> Self { + Self { + source: Source::Audio, + low: 1, + mid: 4, + high: 16, + depth: 50., + time: 100., + upward: 100., + downward: 100., + drive: 0., + gains: [0.; BANDS], + smooth: 10., + gate: -42., + snap: false, + output: 0., + bypass: false, + } + } +} +impl Settings { + pub fn validate(&self) -> Result<(), &'static str> { + let finite = [ + self.depth, + self.time, + self.upward, + self.downward, + self.drive, + self.smooth, + self.gate, + self.output, + ] + .iter() + .chain(self.gains.iter()) + .all(|v| v.is_finite()); + if !finite { + return Err("non-finite setting"); + } + let ok = (1..=8).contains(&self.low) + && (2..=16).contains(&self.mid) + && (3..=TOP_MAX).contains(&self.high) + && self.gains.iter().all(|g| (GAIN_MIN..=GAIN_MAX).contains(g)) + && (0.0..=100.).contains(&self.depth) + && (10.0..=1000.).contains(&self.time) + && (0.0..=100.).contains(&self.upward) + && (0.0..=100.).contains(&self.downward) + && (-24.0..=24.).contains(&self.drive) + && (0.0..=100.).contains(&self.smooth) + && (-60.0..=-20.).contains(&self.gate) + && (-24.0..=24.).contains(&self.output); + if ok { + Ok(()) + } else { + Err("setting out of range") + } + } + /// Highest harmonic of the bottom three bands, in rising order. Host automation can set + /// the edges in any order, so a lower edge pushes the next one up instead of failing. + pub fn tops(&self) -> [u32; BANDS - 1] { + let low = self.low.clamp(1, 8); + let mid = self.mid.max(low + 1); + let high = self.high.max(mid + 1); + [low, mid, high] + } + /// Text for the harmonics of `band`, like "1", "2–4" or "17+". + pub fn band_label(&self, band: usize) -> String { + let t = self.tops(); + let first = if band == 0 { 1 } else { t[band - 1] + 1 }; + match band { + 3 => format!("{first}+"), + _ if first == t[band] => format!("{first}"), + _ => format!("{first}–{}", t[band]), + } + } +} diff --git a/plugins/planish/core/tests/dsp.rs b/plugins/planish/core/tests/dsp.rs new file mode 100644 index 0000000..f9ea1d0 --- /dev/null +++ b/plugins/planish/core/tests/dsp.rs @@ -0,0 +1,309 @@ +use common_dsp::meter::HarmonicMeter; +use common_dsp::Saw; +use planish_core::{compressor_gain, Engine, Settings, Source, BANDS}; +use std::f32::consts::{PI, TAU}; + +const RATE: f32 = 48000.; + +fn engine(s: Settings) -> (Engine, usize) { + let mut e = Engine::new(RATE, 2).unwrap(); + e.set_settings(s).unwrap(); + let l = e.latency_samples() as usize; + (e, l) +} +fn saw(hz: f32, seconds: f32, amp: f32) -> Vec { + let mut s = Saw::new(RATE, hz); + (0..(seconds * RATE) as usize) + .map(|_| s.sample() * amp) + .collect() +} +/// Sum of sines `(harmonic, amplitude)` on `hz`, with the phase in f64 so long signals stay +/// clean. +fn tones(hz: f32, seconds: f32, parts: &[(usize, f32)]) -> Vec { + (0..(seconds * RATE) as usize) + .map(|i| { + let t = i as f64 / RATE as f64; + parts + .iter() + .map(|&(k, a)| { + let phase = (TAU as f64 * hz as f64 * k as f64 * t) % (TAU as f64); + a * (phase as f32).sin() + }) + .sum() + }) + .collect() +} +fn sine(hz: f32, seconds: f32, amp: f32) -> Vec { + tones(hz, seconds, &[(1, amp)]) +} +fn render(e: &mut Engine, x: &[f32]) -> Vec { + x.iter().map(|&v| e.process_sample([v, v])[0]).collect() +} +/// Harmonic levels of the last complete window of `x`. +fn harmonics(x: &[f32], hz: f32) -> [f32; 32] { + let mut m = HarmonicMeter::new(RATE, 85.); + for &v in x { + m.push(v, hz); + } + *m.levels() +} +fn rms_db(x: &[f32]) -> f32 { + let p: f32 = x.iter().map(|v| v * v).sum::() / x.len() as f32; + 10. * (p + 1e-20).log10() +} +fn uncompressed() -> Settings { + Settings { + depth: 0., + ..Settings::default() + } +} + +#[test] +fn bands_sum_flat_without_compression() { + for hz in [35., 80., 250., 1000., 4000., 12000.] { + let x = sine(hz, 0.6, 0.5); + let (mut e, l) = engine(uncompressed()); + let y = render(&mut e, &x); + let tail = y.len() / 2; + let d = rms_db(&y[tail..]) - rms_db(&x[tail - l..x.len() - l]); + assert!(d.abs() < 0.05, "{hz} Hz: {d:+.3} dB"); + } +} + +#[test] +fn band_edges_sit_between_the_same_harmonics_on_every_note() { + // A saw with amplitude a has harmonic k at 2a/(πk). Band 1 holds harmonic 1 minus what + // its slope gives away; the split of the series between the bands is the same on every + // note. + let a = 0.5; + let fundamental = 10. * ((2. * a / PI).powi(2) / 2.).log10(); + let mut first: Option<[f32; BANDS]> = None; + for hz in [43.65, 65.41, 130.81] { + let (mut e, _) = engine(uncompressed()); + render(&mut e, &saw(hz, 1., a)); + let f = e.take_analyzer(); + assert!((f.hz - hz).abs() < 0.5, "{hz}: tracked {}", f.hz); + assert!((f.edges[0] - 2f32.sqrt() * hz).abs() < 1., "{:?}", f.edges); + assert!((f.edges[1] - 20f32.sqrt() * hz).abs() < 2., "{:?}", f.edges); + assert!( + (f.levels[0] - fundamental).abs() < 2.5, + "{hz}: {:?}", + f.levels + ); + let levels = *first.get_or_insert(f.levels); + // The top band also holds the saw's own roll-off near Nyquist, which is not harmonic. + for (b, tolerance) in [0.4, 0.4, 0.4, 1.].into_iter().enumerate() { + let d = f.levels[b] - levels[b]; + assert!(d.abs() < tolerance, "{hz}: {:?} vs {levels:?}", f.levels); + } + } +} + +#[test] +fn the_same_setting_changes_the_same_harmonics_on_every_note() { + let s = Settings { + depth: 100., + ..Settings::default() + }; + let notes = [43.65, 65.41, 98.]; + let mut changes = Vec::new(); + for hz in notes { + let x = saw(hz, 1.5, 0.5); + let (mut e, l) = engine(s); + let y = render(&mut e, &x); + let a = harmonics(&x[..x.len() - l], hz); + let b = harmonics(&y[l..], hz); + changes.push((0..12).map(|k| b[k] - a[k]).collect::>()); + } + // Compression must actually happen for the comparison to mean anything. + assert!(changes[0][0] < -6., "{:?}", changes[0]); + for (n, c) in changes.iter().enumerate().skip(1) { + for k in 0..12 { + let d = c[k] - changes[0][k]; + assert!( + d.abs() < 1.5, + "note {n} harmonic {}: {c:?} vs {:?}", + k + 1, + changes[0] + ); + } + } +} + +#[test] +fn upward_lifts_a_quiet_band_and_downward_pushes_a_loud_one() { + // Loud fundamental in band 1, a quiet 8th harmonic in band 3. + let hz = 55.; + let x = tones(hz, 1.5, &[(1, 0.7), (8, 0.003)]); + let a = harmonics(&x, hz); + let run = |upward: f32, downward: f32| { + let s = Settings { + depth: 100., + upward, + downward, + ..Settings::default() + }; + let (mut e, l) = engine(s); + let y = render(&mut e, &x); + let b = harmonics(&y[l..], hz); + [b[0] - a[0], b[7] - a[7]] + }; + let [body, top] = run(100., 0.); + assert!(body.abs() < 0.5 && top > 5., "upward: {body:+.2} {top:+.2}"); + let [body, top] = run(0., 100.); + assert!( + body < -10. && top.abs() < 1., + "downward: {body:+.2} {top:+.2}" + ); +} + +/// Level in dB of harmonic `k` of `hz` in `x`, over whole periods (Goertzel). +fn partial(x: &[f32], hz: f32, k: usize) -> f32 { + let w = TAU as f64 * hz as f64 * k as f64 / RATE as f64; + let (mut re, mut im) = (0f64, 0f64); + for (i, &v) in x.iter().enumerate() { + re += v as f64 * (w * i as f64).cos(); + im += v as f64 * (w * i as f64).sin(); + } + let amp = 2. * (re * re + im * im).sqrt() / x.len() as f64; + 20. * (amp + 1e-12).log10() as f32 +} + +#[test] +fn heavy_compression_does_not_ripple_at_the_fundamental() { + // A per-period level is steady on a steady note, so even fast, hard compression adds no + // harmonics to a sine. 40 Hz has a period of exactly 1200 samples; Snap is off so the + // window is the measured period, not the nearest semitone's. + let hz = 40.; + let x = sine(hz, 1.5, 0.5); + let distortion = |depth: f32| { + let s = Settings { + depth, + drive: 12., + time: 10., + snap: false, + ..Settings::default() + }; + let (mut e, _) = engine(s); + let y = render(&mut e, &x); + let tail = &y[y.len() - 24000..]; + let fundamental = partial(tail, hz, 1); + (2..6) + .map(|k| partial(tail, hz, k) - fundamental) + .fold(f32::MIN, f32::max) + }; + let (dry, squashed) = (distortion(0.), distortion(100.)); + assert!(squashed < -80., "{squashed:.1} dB (dry {dry:.1} dB)"); +} + +#[test] +fn silence_and_noise_floors_are_not_lifted() { + assert_eq!(compressor_gain(-120., 1., 1.), 0.); + assert!(compressor_gain(-60., 1., 1.) > 10.); + let s = Settings { + depth: 100., + ..Settings::default() + }; + let x = saw(55., 1., 2e-5); + let (mut e, l) = engine(s); + let y = render(&mut e, &x); + let tail = y.len() / 2; + let d = rms_db(&y[tail..]) - rms_db(&x[tail - l..x.len() - l]); + assert!(d < 2., "{d:+.2} dB"); +} + +#[test] +fn bypass_passes_the_delayed_input_exactly() { + let s = Settings { + depth: 100., + bypass: true, + ..Settings::default() + }; + let x = saw(55., 0.5, 0.5); + let (mut e, l) = engine(s); + let y = render(&mut e, &x); + for i in l..x.len() { + assert_eq!(y[i], x[i - l]); + } +} + +#[test] +fn note_changes_do_not_click() { + let s = Settings { + depth: 100., + ..Settings::default() + }; + let mut x = saw(43.65, 0.5, 0.5); + x.extend(saw(58.27, 0.5, 0.5)); + x.extend(saw(87.31, 0.5, 0.5)); + let (mut e, _) = engine(s); + let y = render(&mut e, &x); + let step = y + .windows(2) + .map(|w| (w[1] - w[0]).abs()) + .fold(0f32, f32::max); + let in_step = x + .windows(2) + .map(|w| (w[1] - w[0]).abs()) + .fold(0f32, f32::max); + assert!(y.iter().all(|v| v.is_finite())); + assert!(step < 2. * in_step, "{step} vs {in_step}"); +} + +#[test] +fn midi_source_moves_the_edges_at_the_delayed_note_time() { + let s = Settings { + source: Source::Midi, + ..uncompressed() + }; + let (mut e, l) = engine(s); + // 43.65 Hz is MIDI 29. + e.note_on(29); + render(&mut e, &saw(43.65, l as f32 / RATE - 0.002, 0.5)); + assert_eq!(e.take_analyzer().hz, 0.); + render(&mut e, &saw(43.65, 0.01, 0.5)); + let f = e.take_analyzer(); + assert_eq!(f.note, Some(29)); + assert!( + (f.edges[0] - 2f32.sqrt() * 43.65).abs() < 0.2, + "{:?}", + f.edges + ); +} + +#[test] +fn edges_in_the_wrong_order_are_pushed_up() { + let s = Settings { + low: 4, + mid: 3, + high: 3, + ..Settings::default() + }; + assert!(s.validate().is_ok()); + assert_eq!(s.tops(), [4, 5, 6]); + assert_eq!(s.band_label(0), "1–4"); + assert_eq!(s.band_label(1), "5"); + assert_eq!(s.band_label(3), "7+"); + let d = Settings::default(); + let labels: Vec = (0..BANDS).map(|b| d.band_label(b)).collect(); + assert_eq!(labels, ["1", "2–4", "5–16", "17+"]); +} + +#[test] +fn settings_are_validated_and_serialise() { + let s = Settings::default(); + let json = serde_json::to_string(&s).unwrap(); + assert_eq!(serde_json::from_str::(&json).unwrap(), s); + let mut bad = s; + bad.gains[2] = 40.; + assert!(bad.validate().is_err()); + bad = s; + bad.low = 0; + assert!(bad.validate().is_err()); + bad = s; + bad.time = f32::NAN; + assert!(bad.validate().is_err()); + let mut e = Engine::new(RATE, 2).unwrap(); + assert!(e.set_settings(bad).is_err()); + assert_eq!(e.settings(), s); +} diff --git a/plugins/planish/core/tests/realtime.rs b/plugins/planish/core/tests/realtime.rs new file mode 100644 index 0000000..c694a70 --- /dev/null +++ b/plugins/planish/core/tests/realtime.rs @@ -0,0 +1,71 @@ +use planish_core::{Engine, Settings, Source}; +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 processing_notes_settings_and_analysis_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.gains[(i / 4800) % 4] = -6.; + settings.low = 1 + ((i / 4800) % 3) as u32; + settings.time = 10. + ((i / 4800) % 5) as f32 * 100.; + settings.depth = 100.; + settings.source = if i > 48000 { + Source::Midi + } else { + Source::Audio + }; + 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/planish/plugin/Cargo.lock b/plugins/planish/plugin/Cargo.lock new file mode 100644 index 0000000..13d4e70 --- /dev/null +++ b/plugins/planish/plugin/Cargo.lock @@ -0,0 +1,2381 @@ +# 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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ff2a8126fff0f8c839080d619675a585e61720bb12d2baceae45769fd66f155" +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 = "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 = "planish" +version = "0.1.0" +dependencies = [ + "clap-sys", + "crossbeam-queue", + "nih_plug", + "nih_plug_egui", + "planish-core", + "planish-ui", + "serde_json", +] + +[[package]] +name = "planish-core" +version = "0.1.0" +dependencies = [ + "common-dsp", + "serde", +] + +[[package]] +name = "planish-ui" +version = "0.1.0" +dependencies = [ + "common-dsp", + "common-ui", + "egui", + "planish-core", +] + +[[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/planish/plugin/Cargo.toml b/plugins/planish/plugin/Cargo.toml new file mode 100644 index 0000000..e7177cb --- /dev/null +++ b/plugins/planish/plugin/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "planish" +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" } +planish-core = { path = "../core" } +planish-ui = { path = "../ui" } +crossbeam-queue = "0.3" + +[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/planish/plugin/src/lib.rs b/plugins/planish/plugin/src/lib.rs new file mode 100644 index 0000000..4ec022b --- /dev/null +++ b/plugins/planish/plugin/src/lib.rs @@ -0,0 +1,185 @@ +//! CLAP audio effect. All DSP state is owned by the processing thread. +mod params; +use crossbeam_queue::ArrayQueue; +use nih_plug::prelude::*; +use nih_plug_egui::{create_egui_editor, egui}; +use params::{PlanishParams, FLOATS}; +use planish_core::{AnalyzerFrame, Engine}; +use std::sync::Arc; + +struct EditorData { + ui: planish_ui::State, + gestures: [bool; FLOATS], +} +pub struct Planish { + params: Arc, + analyzer: Arc>, + engine: Option, + publish_count: usize, + publish_interval: usize, +} +impl Default for Planish { + fn default() -> Self { + Self { + params: Arc::new(PlanishParams::default()), + analyzer: Arc::new(ArrayQueue::new(2)), + engine: None, + publish_count: 0, + publish_interval: 1600, + } + } +} +impl Plugin for Planish { + const NAME: &'static str = "Planish"; + 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: planish_ui::State::default(), + gestures: [false; FLOATS], + }, + |ctx, _| planish_ui::style(ctx), + move |ctx, setter, data| { + while let Some(frame) = analyzer.pop() { + data.ui.accept_frame(frame); + } + let before = params.settings(); + let mut edited = before; + nih_plug_egui::resizable_window::ResizableWindow::new("planish-editor") + .min_size(egui::vec2( + planish_ui::WIDTH as f32 - 80., + planish_ui::HEIGHT as f32 - 40., + )) + .show(ctx, ¶ms.editor, |ui| { + planish_ui::show(ui, &mut edited, &mut data.ui) + }); + params.apply( + setter, + &before, + &edited, + data.ui.gesture_active, + &mut data.gestures, + ); + // Band meters follow 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(); + 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(); + 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 compressor release must drain after input stops. + ProcessStatus::KeepAlive + } +} +impl ClapPlugin for Planish { + const CLAP_ID: &'static str = "io.narl.bass-foundry.planish"; + const CLAP_DESCRIPTION: Option<&'static str> = Some( + "Upward and downward compression in bands set by harmonic number, the same on 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::Compressor, + ClapFeature::Stereo, + ClapFeature::Mono, + ]; +} +nih_export_clap!(Planish); diff --git a/plugins/planish/plugin/src/params.rs b/plugins/planish/plugin/src/params.rs new file mode 100644 index 0000000..64abbd9 --- /dev/null +++ b/plugins/planish/plugin/src/params.rs @@ -0,0 +1,192 @@ +use nih_plug::prelude::*; +use nih_plug_egui::EguiState; +use planish_core::{Settings, Source, BANDS, GAIN_MAX, GAIN_MIN, TOP_MAX}; +use std::sync::Arc; + +#[derive(Enum, Debug, PartialEq, Eq, Clone, Copy)] +pub enum SourceParam { + #[id = "audio"] + Audio, + #[id = "midi"] + #[name = "MIDI"] + Midi, +} +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) +} +fn edge(name: &str, v: u32, min: i32, max: i32) -> IntParam { + IntParam::new(name, v as i32, IntRange::Linear { min, max }) +} +/// Continuous controls, in the order of the gesture slots. +pub const FLOATS: usize = 12; + +#[derive(Params)] +pub struct PlanishParams { + #[persist = "editor"] + pub editor: Arc, + #[id = "source"] + pub source: EnumParam, + #[id = "depth"] + pub depth: FloatParam, + #[id = "time"] + pub time: FloatParam, + #[id = "upward"] + pub upward: FloatParam, + #[id = "downward"] + pub downward: FloatParam, + #[id = "drive"] + pub drive: FloatParam, + #[id = "gain-1"] + pub gain_1: FloatParam, + #[id = "gain-2"] + pub gain_2: FloatParam, + #[id = "gain-3"] + pub gain_3: FloatParam, + #[id = "gain-4"] + pub gain_4: FloatParam, + #[id = "smooth"] + pub smooth: FloatParam, + #[id = "gate"] + pub gate: FloatParam, + #[id = "output"] + pub output: FloatParam, + #[id = "low"] + pub low: IntParam, + #[id = "mid"] + pub mid: IntParam, + #[id = "high"] + pub high: IntParam, + #[id = "snap"] + pub snap: BoolParam, + #[id = "bypass"] + pub bypass: BoolParam, +} +impl Default for PlanishParams { + fn default() -> Self { + let d = Settings::default(); + let gain = |n: usize| linear(&format!("Band {n} gain"), 0., GAIN_MIN, GAIN_MAX, " dB"); + Self { + editor: EguiState::from_size(planish_ui::WIDTH, planish_ui::HEIGHT), + source: EnumParam::new("Pitch source", SourceParam::Audio), + depth: linear("Depth", d.depth, 0., 100., " %"), + time: linear("Time", d.time, 10., 1000., " %"), + upward: linear("Upward", d.upward, 0., 100., " %"), + downward: linear("Downward", d.downward, 0., 100., " %"), + drive: linear("Drive", d.drive, -24., 24., " dB"), + gain_1: gain(1), + gain_2: gain(2), + gain_3: gain(3), + gain_4: gain(4), + smooth: linear("Smooth", d.smooth, 0., 100., " ms"), + gate: linear("Gate", d.gate, -60., -20., " dB"), + output: linear("Output", d.output, -24., 24., " dB"), + low: edge("Low edge", d.low, 1, 8), + mid: edge("Mid edge", d.mid, 2, 16), + high: edge("High edge", d.high, 3, TOP_MAX as i32), + snap: BoolParam::new("Snap to semitone", d.snap), + bypass: BoolParam::new("Bypass", false).make_bypass(), + } + } +} +impl PlanishParams { + pub fn settings(&self) -> Settings { + let gains = [&self.gain_1, &self.gain_2, &self.gain_3, &self.gain_4]; + Settings { + source: match self.source.value() { + SourceParam::Audio => Source::Audio, + SourceParam::Midi => Source::Midi, + }, + low: self.low.value() as u32, + mid: self.mid.value() as u32, + high: self.high.value() as u32, + depth: self.depth.value(), + time: self.time.value(), + upward: self.upward.value(), + downward: self.downward.value(), + drive: self.drive.value(), + gains: std::array::from_fn::(|b| gains[b].value()), + smooth: self.smooth.value(), + gate: self.gate.value(), + snap: self.snap.value(), + output: self.output.value(), + bypass: self.bypass.value(), + } + } + fn floats(&self) -> [&FloatParam; FLOATS] { + [ + &self.depth, + &self.time, + &self.upward, + &self.downward, + &self.drive, + &self.gain_1, + &self.gain_2, + &self.gain_3, + &self.gain_4, + &self.smooth, + &self.gate, + &self.output, + ] + } + fn values(s: &Settings) -> [f32; FLOATS] { + [ + s.depth, s.time, s.upward, s.downward, s.drive, s.gains[0], s.gains[1], s.gains[2], + s.gains[3], s.smooth, s.gate, s.output, + ] + } + /// Pushes every changed editor value to the host. Continuous controls hold one gesture + /// while the pointer is down; switches and edges are set in a single gesture. + pub fn apply( + &self, + setter: &ParamSetter, + old: &Settings, + new: &Settings, + dragging: bool, + open: &mut [bool; FLOATS], + ) { + let pairs = Self::values(old).into_iter().zip(Self::values(new)); + for (i, (p, (a, b))) in self.floats().into_iter().zip(pairs).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; + } + } + for (p, a, b) in [ + (&self.low, old.low, new.low), + (&self.mid, old.mid, new.mid), + (&self.high, old.high, new.high), + ] { + if a != b { + setter.begin_set_parameter(p); + setter.set_parameter(p, b as i32); + setter.end_set_parameter(p); + } + } + for (p, a, b) in [ + (&self.snap, old.snap, new.snap), + (&self.bypass, old.bypass, new.bypass), + ] { + if a != b { + setter.begin_set_parameter(p); + setter.set_parameter(p, b); + setter.end_set_parameter(p); + } + } + if new.source != old.source { + let v = match new.source { + Source::Audio => SourceParam::Audio, + Source::Midi => SourceParam::Midi, + }; + setter.begin_set_parameter(&self.source); + setter.set_parameter(&self.source, v); + setter.end_set_parameter(&self.source); + } + } +} diff --git a/plugins/planish/plugin/tests/host.rs b/plugins/planish/plugin/tests/host.rs new file mode 100644 index 0000000..5554f81 --- /dev/null +++ b/plugins/planish/plugin/tests/host.rs @@ -0,0 +1,214 @@ +//! 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 = &planish::clap_entry; + assert!(entry.init.unwrap()(c"planish.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"Planish"); + assert_eq!( + CStr::from_ptr((*descriptor).id), + c"io.narl.bass-foundry.planish" + ); + 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; + // Depth 0 makes the processed signal a pure crossover sum: the tone must pass flat. + envelope.params.insert("depth".into(), ParamValue::F32(0.)); + envelope + .params + .insert("gain-2".into(), ParamValue::F32(-6.)); + envelope.params.insert("low".into(), ParamValue::I32(2)); + envelope.params.insert("high".into(), ParamValue::I32(24)); + envelope + .params + .insert("snap".into(), ParamValue::Bool(true)); + envelope + .params + .insert("source".into(), ParamValue::String("midi".into())); + 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() + ); + 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: two periods of the lowest detected note (30 Hz). + assert!((delay as f64 / rate - 0.067).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); + // A 1 kHz tone through the crossovers, at depth 0. + 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/planish/ui/Cargo.toml b/plugins/planish/ui/Cargo.toml new file mode 100644 index 0000000..f598612 --- /dev/null +++ b/plugins/planish/ui/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "planish-ui" +version = "0.1.0" +edition.workspace = true +license.workspace = true + +[dependencies] +egui = "0.31.1" +planish-core = { path = "../core" } +common-ui = { path = "../../common/ui" } +common-dsp = { path = "../../common/dsp" } diff --git a/plugins/planish/ui/src/lib.rs b/plugins/planish/ui/src/lib.rs new file mode 100644 index 0000000..7e60570 --- /dev/null +++ b/plugins/planish/ui/src/lib.rs @@ -0,0 +1,507 @@ +//! Planish 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 planish_core::{ + AnalyzerFrame, Settings, Source, BANDS, DOWN_THRESHOLD, FALLBACK_HZ, FLOOR, GAIN_MAX, GAIN_MIN, + TOP_MAX, UP_MAX, UP_THRESHOLD, +}; + +pub use common_ui::style; +pub const WIDTH: u32 = 1040; +pub const HEIGHT: u32 = 650; + +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, + /// Band edge being dragged on the harmonic ruler. + dragging: Option, +} +impl Default for State { + fn default() -> Self { + Self { + analyzer: AnalyzerFrame::default(), + gesture_active: false, + help: DEFAULT_HELP.into(), + dragging: None, + } + } +} +const DEFAULT_HELP: &str = + "Band edges are harmonic numbers: band 2 holds harmonics 2–4 on every note, wherever they are in Hz."; +impl State { + pub fn accept_frame(&mut self, frame: AnalyzerFrame) { + let old = self.analyzer; + self.analyzer = frame; + // Levels fall smoothly so bars stay readable between frames. + for b in 0..BANDS { + self.analyzer.levels[b] = frame.levels[b].max(old.levels[b] - 3.); + } + } +} +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, + size: f32, + help: &str, +) { + ui.vertical_centered(|ui| { + let r = rotary(ui, name, value, range, default, unit, size, ACCENT); + hint(&r, state, help); + }); +} + +const GRID: Color32 = Color32::from_rgb(24, 26, 30); +/// One colour per band, bottom band first. +const BAND_COLORS: [Color32; BANDS] = [ + Color32::from_rgb(255, 1, 96), + Color32::from_rgb(226, 120, 64), + Color32::from_rgb(126, 167, 216), + Color32::from_rgb(184, 192, 204), +]; +/// Harmonics shown on the ruler: 1 to 64 on a log scale. +const RULER_MAX: f32 = 64.; +const LEVEL_TOP: f32 = 0.; +const TOP: f32 = 330.; + +fn ruler_x(rect: Rect, harmonic: f32) -> f32 { + rect.left() + rect.width() * (harmonic.max(1.).log2() / RULER_MAX.log2()) +} +fn x_ruler(rect: Rect, x: f32) -> f32 { + 2f32.powf((x - rect.left()) / rect.width() * RULER_MAX.log2()) +} +fn level_y(rect: Rect, db: f32) -> f32 { + let t = (db - FLOOR) / (LEVEL_TOP - FLOOR); + rect.bottom() - rect.height() * t.clamp(0., 1.) +} +fn gain_y(rect: Rect, db: f32) -> f32 { + let t = (db - GAIN_MIN) / (GAIN_MAX - GAIN_MIN); + rect.bottom() - rect.height() * t.clamp(0., 1.) +} +fn edge_mut(settings: &mut Settings, edge: usize) -> &mut u32 { + match edge { + 0 => &mut settings.low, + 1 => &mut settings.mid, + _ => &mut settings.high, + } +} +fn edge_range(edge: usize) -> (u32, u32) { + match edge { + 0 => (1, 8), + 1 => (2, 16), + _ => (3, TOP_MAX), + } +} + +/// Harmonic ruler with draggable band edges, then one column per band with its level, +/// thresholds and compressor gain. +fn band_display(ui: &mut egui::Ui, settings: &mut Settings, state: &mut State, height: f32) { + let size = Vec2::new(ui.available_width(), height); + let (outer, response) = ui.allocate_exact_size(size, Sense::click_and_drag()); + let p = ui.painter_at(outer); + p.rect_filled(outer, 2., SCREEN); + let ruler = Rect::from_min_max( + outer.left_top() + Vec2::new(16., 26.), + Pos2::new(outer.right() - 16., outer.top() + 62.), + ); + let columns = Rect::from_min_max( + Pos2::new(outer.left() + 40., ruler.bottom() + 34.), + Pos2::new(outer.right() - 40., outer.bottom() - 34.), + ); + let tops = settings.tops(); + let f = state.analyzer; + let root = if f.hz > 0. { f.hz } else { FALLBACK_HZ }; + + // Ruler: band spans, harmonic ticks, and edges between harmonics. + let edge_at = |k: u32| ((k * (k + 1)) as f32).sqrt(); + let mut from = 1f32; + for b in 0..BANDS { + let to = if b < BANDS - 1 { + edge_at(tops[b]) + } else { + RULER_MAX + }; + let span = Rect::from_min_max( + Pos2::new(ruler_x(ruler, from), ruler.top() + 14.), + Pos2::new(ruler_x(ruler, to), ruler.bottom()), + ); + p.rect_filled(span, 1., BAND_COLORS[b].gamma_multiply(0.22)); + p.text( + span.center_top() + Vec2::new(0., -2.), + egui::Align2::CENTER_BOTTOM, + format!("BAND {} · {}", b + 1, settings.band_label(b)), + FontId::proportional(10.), + BAND_COLORS[b], + ); + from = to; + } + for k in 1..=RULER_MAX as u32 { + let x = ruler_x(ruler, k as f32); + let major = k.is_power_of_two() || k <= 8; + let tick = if major { 10. } else { 5. }; + p.line_segment( + [ + Pos2::new(x, ruler.bottom() - tick), + Pos2::new(x, ruler.bottom()), + ], + Stroke::new(1.0_f32, if major { MUTED } else { DIM }), + ); + if major { + p.text( + Pos2::new(x, ruler.bottom() + 3.), + egui::Align2::CENTER_TOP, + format!("{k}"), + FontId::proportional(10.), + MUTED, + ); + } + } + let nearest = |x: f32| { + (0..BANDS - 1) + .min_by(|&a, &b| { + let da = (ruler_x(ruler, edge_at(tops[a])) - x).abs(); + let db = (ruler_x(ruler, edge_at(tops[b])) - x).abs(); + da.total_cmp(&db) + }) + .unwrap_or(0) + }; + let hover_edge = response + .hover_pos() + .filter(|p| p.y < ruler.bottom() + 16.) + .map(|p| nearest(p.x)); + if response.drag_started() { + state.dragging = response + .interact_pointer_pos() + .filter(|p| p.y < ruler.bottom() + 16.) + .map(|p| nearest(p.x)); + } + if let (Some(edge), Some(pos)) = (state.dragging, response.interact_pointer_pos()) { + let (lo, hi) = edge_range(edge); + // The edge above harmonic k sits at √(k(k+1)), so k is the harmonic below the pointer. + let k = (x_ruler(ruler, pos.x) - 0.5) + .round() + .clamp(lo as f32, hi as f32) as u32; + *edge_mut(settings, edge) = k; + // Keep the order visible while dragging: the other edges make room. + let t = settings.tops(); + settings.low = t[0]; + settings.mid = t[1].min(16); + settings.high = t[2]; + } + if !response.dragged() { + state.dragging = None; + } + for (e, &top) in settings.tops().iter().enumerate() { + let x = ruler_x(ruler, edge_at(top)); + let active = state.dragging == Some(e) || hover_edge == Some(e); + p.line_segment( + [ + Pos2::new(x, ruler.top() + 10.), + Pos2::new(x, ruler.bottom() + 2.), + ], + Stroke::new( + if active { 2.5_f32 } else { 1.5 }, + if active { TEXT } else { STEEL }, + ), + ); + } + + // Columns: level (steel) against the thresholds, gain (accent cut, blue lift). + for db in [0., -12., -24., -36., -48., -60., -72.] { + let y = level_y(columns, db); + p.line_segment( + [Pos2::new(columns.left(), y), Pos2::new(columns.right(), y)], + Stroke::new(1.0_f32, GRID), + ); + p.text( + Pos2::new(outer.left() + 8., y), + egui::Align2::LEFT_CENTER, + format!("{db:.0}"), + FontId::proportional(10.), + DIM, + ); + } + // Gain scale on the right, for the bars. + for db in [24., 12., 0., -12., -24.] { + p.text( + Pos2::new(outer.right() - 8., gain_y(columns, db)), + egui::Align2::RIGHT_CENTER, + if db == 0. { + "0".into() + } else { + format!("{db:+.0}") + }, + FontId::proportional(10.), + if db == 0. { MUTED } else { DIM }, + ); + } + let col = columns.width() / BANDS as f32; + let depth = settings.depth * 0.01; + for b in 0..BANDS { + let x0 = columns.left() + col * b as f32; + let level = Rect::from_min_max( + Pos2::new(x0 + col * 0.14, level_y(columns, f.levels[b])), + Pos2::new(x0 + col * 0.44, columns.bottom()), + ); + if level.height() > 0.5 { + p.rect_filled(level, 1., STEEL.gamma_multiply(0.8)); + } + for (db, amount, color) in [ + (DOWN_THRESHOLD, settings.downward, ACCENT), + (UP_THRESHOLD, settings.upward, FOCUS), + ] { + if amount > 0. { + let y = level_y(columns, db); + p.line_segment( + [Pos2::new(x0 + col * 0.08, y), Pos2::new(x0 + col * 0.5, y)], + Stroke::new(1.0_f32, color.gamma_multiply(0.8)), + ); + } + } + // The same blend as the engine: Depth mixes the band with its compressed copy. + let wet = 10f32.powf((f.gains[b] + settings.gains[b]) / 20.); + let gain = 20. * (1. + depth * (wet - 1.)).max(1e-6).log10(); + let zero = gain_y(columns, 0.); + let y = gain_y(columns, gain); + let bar = Rect::from_min_max( + Pos2::new(x0 + col * 0.56, zero.min(y)), + Pos2::new(x0 + col * 0.86, zero.max(y)), + ); + p.line_segment( + [ + Pos2::new(x0 + col * 0.52, zero), + Pos2::new(x0 + col * 0.9, zero), + ], + Stroke::new(1.0_f32, EDGE), + ); + if bar.height() >= 1. { + p.rect_filled(bar, 1., if gain < 0. { ACCENT } else { FOCUS }); + } + let hz = |k: f32| k * root; + let low = if b == 0 { 1. } else { edge_at(tops[b - 1]) }; + let range = if b < BANDS - 1 { + format!("{:.0}–{:.0} Hz", hz(low), hz(edge_at(tops[b]))) + } else { + format!("{:.0} Hz +", hz(low)) + }; + p.text( + Pos2::new(x0 + col * 0.5, columns.bottom() + 6.), + egui::Align2::CENTER_TOP, + format!("{} · {gain:+.1} dB", settings.band_label(b)), + FontId::proportional(11.), + BAND_COLORS[b], + ); + p.text( + Pos2::new(x0 + col * 0.5, columns.bottom() + 20.), + egui::Align2::CENTER_TOP, + range, + FontId::proportional(10.), + MUTED, + ); + } + p.text( + Pos2::new(outer.right() - 8., ruler.bottom() + 18.), + egui::Align2::RIGHT_TOP, + "LEVEL dB · GAIN dB", + FontId::proportional(11.), + MUTED, + ); + p.text( + outer.left_top() + Vec2::new(8., 6.), + egui::Align2::LEFT_TOP, + "HARMONIC", + FontId::proportional(11.), + MUTED, + ); + p.rect_stroke( + outer, + 2., + Stroke::new(1.0_f32, EDGE), + egui::StrokeKind::Inside, + ); + if let Some(e) = state.dragging.or(hover_edge) { + let k = tops[e]; + state.help = format!( + "Edge between harmonics {k} and {}: {:.0} Hz on this note. Drag to move it.", + k + 1, + edge_at(k) * root, + ); + } else if response.hovered() { + state.help = format!( + "Level plus Drive (steel) against the upward (blue) and downward (pink) thresholds; bar: band gain. Lift is at most {UP_MAX:.0} dB." + ); + } +} + +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, "PLANISH", "HARMONIC OTT", |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.); + let frame = state.analyzer; + ui.horizontal_top(|ui| { + panel(ui, |ui| { + ui.set_width(210.); + ui.set_min_height(TOP); + ui.vertical(|ui| note_panel(ui, settings, state, &frame)); + }); + ui.add_space(4.); + panel(ui, |ui| { + ui.set_width(ui.available_width()); + band_display(ui, settings, state, TOP); + }); + }); + 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)); +} + +/// Label, help text and band edges (highest harmonic of bands 1–3). +type Split = (&'static str, &'static str, [u32; 3]); + +fn note_panel( + ui: &mut egui::Ui, + settings: &mut Settings, + state: &mut State, + frame: &AnalyzerFrame, +) { + 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(), + format!("no note yet · edges on {FALLBACK_HZ:.0} Hz"), + ), + }; + 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).monospace().size(14.).color(MUTED)); + ui.add_space(6.); + ui.label( + RichText::new(format!( + "{:.0} ms lookahead · {}", + frame.latency as f32 / frame.sample_rate * 1000., + match settings.source { + Source::Audio => "detecting pitch", + Source::Midi => "following MIDI", + } + )) + .size(12.) + .color(MUTED), + ); + ui.add_space(14.); + caption(ui, "SPLITS"); + let splits: [Split; 4] = [ + ( + "CLASSIC", + "Fundamental alone, body 2–4, mids 5–16, top 17 and up.", + [1, 4, 16], + ), + ( + "SUB + BODY", + "Harmonics 1–2 together, so the octave stays locked to the sub.", + [2, 6, 24], + ), + ( + "TIGHT", + "Narrow low bands for close control of the first harmonics.", + [1, 2, 8], + ), + ( + "WIDE TOP", + "One big mid band, a top that starts high: fizz only.", + [1, 3, 32], + ), + ]; + ui.horizontal_wrapped(|ui| { + for (label, help, [low, mid, high]) in splits { + let on = settings.tops() == [low, mid, high]; + let r = ui.selectable_label(on, RichText::new(label).size(12.)); + if r.clicked() { + settings.low = low; + settings.mid = mid; + settings.high = high; + } + hint(&r, state, help); + } + }); + ui.add_space(10.); + let r = ui.selectable_label(settings.snap, RichText::new("SNAP TO SEMITONE").size(13.)); + if r.clicked() { + settings.snap = !settings.snap; + } + hint( + &r, + state, + "Round the detected pitch. Off keeps the level window on the real period, which is steadier on detuned patches.", + ); +} + +fn controls(ui: &mut egui::Ui, settings: &mut Settings, state: &mut State) { + let d = Settings::default(); + ui.columns(12, |c| { + knob(&mut c[0], state, "Drive", &mut settings.drive, -24. ..=24., d.drive, " dB", 64., + "Pushes the band levels against the thresholds: more drive, more squash. It does not change the level by itself."); + knob(&mut c[1], state, "Depth", &mut settings.depth, 0. ..=100., d.depth, " %", 64., + "How much of the compression is applied. 0 % is a clean crossover sum."); + knob(&mut c[2], state, "Upward", &mut settings.upward, 0. ..=100., d.upward, " %", 64., + "Lift for bands below the upward threshold: brings up quiet harmonics."); + knob(&mut c[3], state, "Downward", &mut settings.downward, 0. ..=100., d.downward, " %", 64., + "Cut for bands above the downward threshold: holds loud harmonics down."); + knob(&mut c[4], state, "Time", &mut settings.time, 10. ..=1000., d.time, " %", 64., + "Scales every attack and release. Lower bands are slower than higher ones."); + for b in 0..BANDS { + let name = format!("Band {}", b + 1); + let help = format!( + "Gain of band {} (harmonics {}) after its compressor, scaled by Depth.", + b + 1, + settings.band_label(b) + ); + knob(&mut c[5 + b], state, &name, &mut settings.gains[b], GAIN_MIN..=GAIN_MAX, + d.gains[b], " dB", 54., &help); + } + knob(&mut c[9], state, "Smooth", &mut settings.smooth, 0. ..=100., d.smooth, " ms", 54., + "Retune time for slides and bends. New notes always retune at once."); + knob(&mut c[10], state, "Gate", &mut settings.gate, -60. ..=-20., d.gate, " dB", 54., + "Input level that counts as a note. Raise it if tails retrigger."); + knob(&mut c[11], state, "Output", &mut settings.output, -24. ..=24., d.output, " dB", 54., + "Output trim."); + }); +} diff --git a/tools/editor-check/Cargo.lock b/tools/editor-check/Cargo.lock index 7610c80..9a86dbd 100644 --- a/tools/editor-check/Cargo.lock +++ b/tools/editor-check/Cargo.lock @@ -164,6 +164,8 @@ dependencies = [ "lathe-ui", "patina-core", "patina-ui", + "planish-core", + "planish-ui", "rivet-app", "rivet-core", "rivet-midi", @@ -430,6 +432,24 @@ dependencies = [ "patina-core", ] +[[package]] +name = "planish-core" +version = "0.1.0" +dependencies = [ + "common-dsp", + "serde", +] + +[[package]] +name = "planish-ui" +version = "0.1.0" +dependencies = [ + "common-dsp", + "common-ui", + "egui", + "planish-core", +] + [[package]] name = "png" version = "0.18.1" diff --git a/tools/editor-check/Cargo.toml b/tools/editor-check/Cargo.toml index 7171e32..c918ceb 100644 --- a/tools/editor-check/Cargo.toml +++ b/tools/editor-check/Cargo.toml @@ -25,5 +25,7 @@ temper-core = { path = "../../plugins/temper/core" } temper-ui = { path = "../../plugins/temper/ui" } knurl-core = { path = "../../plugins/knurl/core" } knurl-ui = { path = "../../plugins/knurl/ui" } +planish-core = { path = "../../plugins/planish/core" } +planish-ui = { path = "../../plugins/planish/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 3418123..21ca8a4 100644 --- a/tools/editor-check/src/main.rs +++ b/tools/editor-check/src/main.rs @@ -11,11 +11,13 @@ fn main() { .map(|a| a[1].as_str()) .unwrap_or("rivet"); if ![ - "rivet", "patina", "anvil", "crucible", "lathe", "temper", "weld", "knurl", + "rivet", "patina", "anvil", "crucible", "lathe", "temper", "weld", "knurl", "planish", ] .contains(&plugin) { - eprintln!("Use --plugin rivet, patina, anvil, crucible, lathe, temper, weld or knurl"); + eprintln!( + "Use --plugin rivet, patina, anvil, crucible, lathe, temper, weld, knurl or planish" + ); std::process::exit(2); } let patina = plugin == "patina" || args.iter().any(|arg| arg == "--resonance"); @@ -26,7 +28,10 @@ fn main() { let temper = plugin == "temper"; let weld = plugin == "weld"; let knurl = plugin == "knurl"; - let (width, height) = if knurl { + let planish = plugin == "planish"; + let (width, height) = if planish { + (planish_ui::WIDTH, planish_ui::HEIGHT) + } else if knurl { (knurl_ui::WIDTH, knurl_ui::HEIGHT) } else if weld { (weld_ui::WIDTH, weld_ui::HEIGHT) @@ -165,6 +170,26 @@ fn main() { } knurl_state.accept_frame(engine.take_analyzer()); } + let mut planish_settings = planish_core::Settings { + depth: 80., + gains: [0., 2., 3., -2.], + ..Default::default() + }; + let mut planish_state = planish_ui::State::default(); + if planish { + // A distorted F1 saw bass: loud body, thin top, so both directions work. + let mut engine = planish_core::Engine::new(48000., 2).unwrap(); + engine.set_settings(planish_settings).unwrap(); + let mut saw = common_dsp::Saw::new(48000., 43.65); + for i in 0..36000 { + let x = (saw.sample() * 1.6).tanh() * 0.4; + engine.process_sample([x, x]); + if i % 1600 == 0 { + planish_state.accept_frame(engine.take_analyzer()); + } + } + planish_state.accept_frame(engine.take_analyzer()); + } let mut weld_settings = weld_core::Settings::default(); let mut weld_state = weld_ui::State::default(); if weld { @@ -294,7 +319,9 @@ fn main() { let session_motif = session.motifs[0].id; shared.replace(session).unwrap(); let ctx = egui::Context::default(); - if knurl { + if planish { + planish_ui::style(&ctx); + } else if knurl { knurl_ui::style(&ctx); } else if weld { weld_ui::style(&ctx); @@ -331,7 +358,9 @@ fn main() { }, |ui| { egui::CentralPanel::default().show(ui, |ui| { - if knurl { + if planish { + planish_ui::show(ui, &mut planish_settings, &mut planish_state); + } else 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); diff --git a/website/src/data/plugins.ts b/website/src/data/plugins.ts index 392792a..29a0a6a 100644 --- a/website/src/data/plugins.ts +++ b/website/src/data/plugins.ts @@ -169,6 +169,21 @@ const COPY: Record = { latency: '≈ 71 ms', tracksNotes: true, }, + planish: { + role: 'Harmonic OTT', + metal: 'Planishing hammers a metal surface smooth and even.', + problem: + 'OTT splits its bands at fixed frequencies: harmonic 2 of F1 lands in the low band, harmonic 2 of C2 in the mids. The same setting squashes different harmonics on every note.', + points: [ + 'Upward and downward compression in four bands.', + 'Band edges are harmonic numbers: band 2 holds harmonics 2–4 on every note.', + 'Level measured over one period of the note, so heavy settings do not ripple.', + 'Depth, Drive, Time and a gain per band. Pitch from the audio, or from MIDI.', + ], + loadOn: 'Bass, after the distortion', + latency: '≈ 67 ms', + tracksNotes: true, + }, }; export interface Plugin extends Copy {