docs/chain.md gives the plugin order for a bass track and the bus, the latency each plugin adds, and the measured octave error of downstream note trackers after Knurl: from C2 up the tracker reads an octave low about 85 % of the time, and timing jitter adds 5-25 false note starts per second. Knurl and Anvil guides point there and recommend MIDI as the pitch source after Knurl. docs/ideas.md gains the production-flow audit, next steps for every released plugin, new ideas (Forge, Planish, Quench, Scribe, Bevel, Peen) and a build order.
200 lines
10 KiB
Markdown
200 lines
10 KiB
Markdown
# Bass Foundry
|
|
|
|
**Rust CLAP plugins for writing, designing and mixing bass music in FL Studio.**
|
|
|
|
Website: [fl.narl.io](https://fl.narl.io)
|
|
|
|

|
|

|
|

|
|

|
|

|
|
|
|
Riddim and dubstep basses change patch on every switch-up. Fixed-frequency tools
|
|
then act differently on every note: the sub jumps, an EQ cut lands on another
|
|
harmonic, the distortion gets fizzy on one note and dull on the next. Most plugins
|
|
in this suite follow the played note, so a setting means the same thing on every
|
|
note. Each plugin is a separate product with its own version, guide and release.
|
|
|
|
## Plugins
|
|
|
|
| Plugin | What it does | Load it on | Latency | Docs |
|
|
| --- | --- | --- | --- | --- |
|
|
| **[Rivet](docs/rivet/README.md)** | Tells a MIDI motif as a story on a storyboard of roles and joins the seams into one phrase | Channel Rack | none | [Guide](docs/rivet/README.md) · [Changes](docs/rivet/CHANGELOG.md) |
|
|
| **[Patina](docs/patina/README.md)** | Smooths harsh, ringing resonances while plain harmonic tone and transients pass | Any mixer track | one analysis frame | [Guide](docs/patina/README.md) · [Changes](docs/patina/CHANGELOG.md) |
|
|
| **[Anvil](docs/anvil/README.md)** | Replaces the sub with a clean mono sine: one level and one start phase on every note | Bass bus | 80 ms | [Guide](docs/anvil/README.md) · [Changes](docs/anvil/CHANGELOG.md) |
|
|
| **[Crucible](docs/crucible/README.md)** | Records the last bars all the time, then slices, cleans and exports key-labelled samples with one button | End of the chain to resample | none | [Guide](docs/crucible/README.md) · [Changes](docs/crucible/CHANGELOG.md) |
|
|
| **[Lathe](docs/lathe/README.md)** | EQ with one band on each harmonic of the played note: a cut on harmonic 3 stays on harmonic 3 | Bass, after the synth | ≈ 67 ms | [Guide](docs/lathe/README.md) · [Changes](docs/lathe/CHANGELOG.md) |
|
|
| **[Temper](docs/temper/README.md)** | Distortion that drives every note the same: level and tone filters follow the note | Bass | ≈ 67 ms + oversampling | [Guide](docs/temper/README.md) · [Changes](docs/temper/CHANGELOG.md) |
|
|
| **[Weld](docs/weld/README.md)** | Phase-aligns one bass layer to another layer through the sidechain, so the layers sum in the mids instead of cancelling | One layer's track, other layer as sidechain | none | [Guide](docs/weld/README.md) · [Changes](docs/weld/CHANGELOG.md) |
|
|
| **[Knurl](docs/knurl/README.md)** | Gives every cycle of the note its own level, timing and grit: in-tune subharmonic growl, rattle and fry on every note | Bass | ≈ 71 ms | [Guide](docs/knurl/README.md) · [Changes](docs/knurl/CHANGELOG.md) |
|
|
|
|
Plugins with latency report it to the host, so FL Studio compensates the delay.
|
|
Anvil, Lathe, Temper and Knurl 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
|
|
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.
|
|
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*.
|
|
|
|
## Editors
|
|
|
|
<table>
|
|
<tr>
|
|
<td width="50%"><a href="docs/rivet/README.md"><img src="docs/rivet/assets/editor.png" alt="Rivet editor"></a><br><b>Rivet</b>: storyboard composition</td>
|
|
<td width="50%"><a href="docs/patina/README.md"><img src="docs/patina/assets/editor.png" alt="Patina editor"></a><br><b>Patina</b>: resonance smoothing</td>
|
|
</tr>
|
|
<tr>
|
|
<td><a href="docs/anvil/README.md"><img src="docs/anvil/assets/editor.png" alt="Anvil editor"></a><br><b>Anvil</b>: sub anchor</td>
|
|
<td><a href="docs/crucible/README.md"><img src="docs/crucible/assets/editor.png" alt="Crucible editor"></a><br><b>Crucible</b>: resampler</td>
|
|
</tr>
|
|
<tr>
|
|
<td><a href="docs/lathe/README.md"><img src="docs/lathe/assets/editor.png" alt="Lathe editor"></a><br><b>Lathe</b>: harmonic EQ</td>
|
|
<td><a href="docs/temper/README.md"><img src="docs/temper/assets/editor.png" alt="Temper editor"></a><br><b>Temper</b>: tracked distortion</td>
|
|
</tr>
|
|
<tr>
|
|
<td><a href="docs/weld/README.md"><img src="docs/weld/assets/editor.png" alt="Weld editor"></a><br><b>Weld</b>: layer phase alignment</td>
|
|
<td><a href="docs/knurl/README.md"><img src="docs/knurl/assets/editor.png" alt="Knurl editor"></a><br><b>Knurl</b>: cycle texture</td>
|
|
</tr>
|
|
</table>
|
|
|
|
The previews are rendered headless from the real editor code by
|
|
`tools/editor-check`, so they match what the plugin draws.
|
|
|
|
## Install
|
|
|
|
1. Open the plugin's release on Gitea. Every plugin has its own release tag,
|
|
for example `lathe-v0.1.0`.
|
|
2. Download `<plugin>-windows-x86_64-<version>.zip`. You can check it against
|
|
the `.zip.sha256` file next to it.
|
|
3. Extract the ZIP and copy the `.clap` file into:
|
|
|
|
```text
|
|
C:\Program Files\Common Files\CLAP\
|
|
```
|
|
|
|
4. In FL Studio 2024.1 or newer, open **Options → Manage plugins**, enable
|
|
**Verify plugins**, and click **Find installed plugins**.
|
|
5. Load Rivet in the Channel Rack. Load the other plugins in mixer effect slots.
|
|
|
|
Keep the font license (`licenses/`) with redistributed packages.
|
|
|
|
Every branch and pull-request pipeline also builds a combined Windows preview
|
|
ZIP, `bass-foundry-windows-x86_64.zip`, in its **windows** job. Use it to test unreleased changes.
|
|
|
|
> **Upgrading from an earlier build?** The CLAP IDs changed from
|
|
> `io.storyboard.*` to `io.narl.bass-foundry.<product>`, so hosts see each
|
|
> plugin as new. Delete the old `.clap` files, rescan, and add the plugins again
|
|
> in existing projects. Motif Storyboard and Resonance Compressor are now Rivet
|
|
> and Patina, and the vendor is "Bass Foundry".
|
|
|
|
## Build from source
|
|
|
|
You need:
|
|
|
|
- Rust stable and Python 3.11 or newer.
|
|
- For the Windows target on Linux: the `x86_64-pc-windows-gnu` Rust target and
|
|
MinGW (`x86_64-w64-mingw32-gcc`).
|
|
- For the native wrapper tests on Linux: pkg-config and the X11/XCB and OpenGL
|
|
development headers. Rivet's optional standalone also needs ALSA/JACK headers.
|
|
|
|
```sh
|
|
# Tests for all engines, editors and tools
|
|
cargo test --workspace --locked
|
|
|
|
# Formatting, tests and lints for one product, including its CLAP wrapper
|
|
python3 scripts/check-plugin.py --plugin lathe
|
|
|
|
# Windows build, then the ZIPs (all plugins, or --plugin <name>)
|
|
python3 scripts/build-plugin.py --plugin lathe --target x86_64-pc-windows-gnu
|
|
python3 scripts/package-windows.py
|
|
|
|
# Headless editor preview
|
|
cargo run --manifest-path tools/editor-check/Cargo.toml -- target/editor/lathe.png --plugin lathe
|
|
```
|
|
|
|
Plugin names for the scripts are `rivet`, `patina`, `anvil`, `crucible`,
|
|
`lathe`, `temper`, `weld` and `knurl`. Builds go to `dist/<target>/<Name>.clap`. No
|
|
script installs anything into a DAW. [Development and testing](docs/development.md)
|
|
has the full command list.
|
|
|
|
## Quality checks
|
|
|
|
Every push and pull request runs these checks in CI
|
|
(`.gitea/workflows/check.yml`):
|
|
|
|
- **Engine tests.** Every engine has tests for its signal behaviour and latency
|
|
against measured targets.
|
|
- **Realtime safety.** Every audio effect has a test that fails if the audio
|
|
thread allocates memory.
|
|
- **Host tests.** Each wrapper is loaded through the exported CLAP ABI, without
|
|
a DAW. The tests check the ports, the reported latency, state save and load,
|
|
and processing at 44.1, 48 and 96 kHz.
|
|
- **Lints.** `rustfmt` and `clippy -D warnings` for every package and wrapper.
|
|
- **Editor previews.** All editors are rendered headless and kept as CI
|
|
artifacts.
|
|
- **Windows builds.** Every `.clap` is cross-compiled and packaged.
|
|
|
|
Release ZIPs are deterministic and contain checksums for every file. Things CI
|
|
cannot check stay manual: FL Studio routing, native window behaviour, and
|
|
listening.
|
|
|
|
## Repository
|
|
|
|
```text
|
|
plugins/
|
|
catalog.json Product metadata for the build, check and release tools
|
|
rivet/ core · midi · app · preview · plugin
|
|
patina/ core · ui · render · plugin
|
|
anvil/ core · ui · plugin
|
|
crucible/ core · ui · plugin
|
|
lathe/ core · ui · plugin
|
|
temper/ core · ui · plugin
|
|
weld/ core · ui · plugin
|
|
knurl/ core · ui · plugin
|
|
common/
|
|
ui/ Shared look: palette, embedded fonts, knobs, panels, meters
|
|
dsp/ Shared filters, pitch tracking, oversampling, meters, WAV files
|
|
tools/editor-check/ Headless editor renderer for visual QA
|
|
scripts/ Build, check, packaging, release and analysis tools
|
|
docs/<plugin>/ Guide, changelog and editor preview for each plugin
|
|
docs/ideas.md Problems in bass-music production and the plugin ideas for them
|
|
references/ Local reference audio; never distributed
|
|
website/ The fl.narl.io site: Astro, nginx container, reads catalog and previews
|
|
```
|
|
|
|
Each product follows the same split:
|
|
|
|
- `core` is the engine. It is plain Rust, does not depend on a plugin SDK, and
|
|
is tested on its own.
|
|
- `ui` is the egui editor, built on `common-ui`.
|
|
- `plugin` is the CLAP wrapper on a pinned NIH-plug revision.
|
|
|
|
The root Cargo workspace holds the engines, editors and tools. Each wrapper is
|
|
its own workspace with its own lockfile, so SDK dependencies stay separate.
|
|
`plugins/catalog.json` is the single list of products. The scripts and CI read
|
|
it, so adding a plugin starts there.
|
|
|
|
## Releases
|
|
|
|
Each plugin is versioned and released on its own. Its version is the `version`
|
|
in `plugins/<plugin>/plugin/Cargo.toml`. A tag `<plugin>-v<version>`, for example
|
|
`temper-v0.1.0`, starts the release workflow. The workflow builds, checks and
|
|
publishes that plugin's Windows ZIP to a Gitea release. See
|
|
[docs/releases.md](docs/releases.md).
|
|
|
|
## Roadmap
|
|
|
|
[docs/ideas.md](docs/ideas.md) lists the production problems the suite targets,
|
|
the released plugins and the ideas for the next ones.
|
|
|
|
## License
|
|
|
|
ISC, see [LICENSE](LICENSE). The embedded Roboto Condensed fonts are under the
|
|
SIL Open Font License ([OFL.txt](plugins/common/ui/assets/OFL.txt)).
|