Files
bass-foundry/docs/rivet/README.md
T
nvrl 340ff13342
Check and Windows preview / check (anvil) (push) Successful in 2m22s
Check and Windows preview / check (crucible) (push) Successful in 1m55s
Check and Windows preview / check (knurl) (push) Successful in 1m42s
Check and Windows preview / check (lathe) (push) Successful in 1m41s
Check and Windows preview / check (patina) (push) Successful in 2m43s
Check and Windows preview / check (planish) (push) Successful in 2m20s
Check and Windows preview / check (rivet) (push) Successful in 1m42s
Check and Windows preview / check (temper) (push) Successful in 1m39s
Check and Windows preview / check (weld) (push) Successful in 2m40s
Check and Windows preview / previews (push) Successful in 1m37s
Check and Windows preview / windows (push) Successful in 2m34s
Independent plugin release / publish (push) Successful in 9s
Independent plugin release / plan (push) Successful in 7s
Independent plugin release / build (push) Successful in 3m8s
chore: release Crucible 0.3.0, Patina 0.4.0 and Planish 0.1.0
- Crucible 0.3.0: Keep takes.
- Patina 0.4.0: Tone guard and the Bass line preset.
- Planish 0.1.0 is already at its first version.
- Update the current version in every plugin guide; several still named an
  older release.
2026-11-06 12:58:53 +01:00

153 lines
8.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Rivet
Rivet joins short motifs into connected musical phrases, like a fastener joining
individual pieces. Formerly **Motif Storyboard**; current version **0.5.0**.
A Rust composition companion for a producer developing their own melodic ideas.
Version 0.4 is built around a **storyboard**: a timeline of blocks that tell one
short idea as a story. Each block has a role (statement, answer, departure,
return, rest) and a length; Rivet writes each block from your motif and joins the
seams so the result plays as one phrase.
![Rivet editor](assets/editor.png)
## Write with it
1. **Bring in a motif.** Import a monophonic MIDI clip of one to eight bars, or
press **Demo**. The bin on the left holds up to 16 motifs. When the bin is
empty, the file's time signature and tempo become the session's.
2. **Lock what defines it.** Select the motif; the big roll shows it. Click notes
to lock the whole note, its pitch only, or its rhythm only. Locked notes
survive into every block.
3. **Lay out the story.** A new motif starts as an arc: statement, answer,
departure, return. **Build from this motif** applies other templates
(question and answer, breathe with rests, build with two departures).
**Add block** inserts any role after the selected block. Blocks are 1–8 bars;
a storyboard holds up to 32 bars in 2/4, 3/4, 4/4, 5/4, 6/8, 7/8 or 12/8.
4. **Shape each block.** Click a block in the timeline or the roll. The inspector
on the right sets its role, motif, length and how it hands over to the next
block. It also lists up to three options written for that role; click one to
use it, or **Audition** it alone. **Another take** writes three new options
for that block only. **Keep** freezes a block so later changes to key, reach
or harmony leave it alone.
5. **Join the seams.** Click the small circle between two blocks to cycle its
join: **Cut** (as written), **Breath** (the last note ends early to leave
air), **Pickup** (two short notes lead into the next block) or **Approach**
(the last note steps next to the next block's first note).
6. **Play and export.** **Play** (or Space) loops the whole storyboard. While it
plays, edits are heard from the next bar line. **Export MIDI…** writes the
storyboard to drag into FL Studio. **Undo**/**Redo** (Ctrl+Z, Ctrl+Shift+Z)
step back through the last 32 edits.
The tabs under the roll hold the less frequent settings:
- **Generation**: reach (how far options move from the motif), keep groove,
keep contour, a settled or open ending for the last block, the register, the
seed, and the audition output.
- **Harmony**: import a chord or bass MIDI track, or start from an editable
progression. Harmony guides strong notes and arrivals; audition plays the
melody only. Imported voicings keep their pitch classes; Rivet does not guess
chord names.
- **Sound roles**: split the phrase between two synth parts (see below).
Options come from eight transformation families: displaced groove, fragment,
room to breathe, short call and long answer, familiar return, changed ending,
higher peak and held back. Each role prefers the families that fit it, and the
statement always offers the motif as written. Options are deterministic for a
given seed, take and position; they are suggestions, not promises of an emotion.
## Audition and commit
**Internal voice** provides two simple reference voices. **MIDI output** sends
notes and optional CC curves on the configured channels to routed external synths
and mutes the internal voice. Solo defaults to channel 1.
Looping is optional and enabled for new sessions. When audition is already
running, another selection waits until the next bar line. Note-offs precede repeated same-pitch note-ons; stop, replacement,
loop boundaries, reset, restoration, and mode changes release active output notes
on the processing thread. Queued auditions are canceled by Stop.
**Host tempo** follows tempo, with the local BPM as fallback. It does not align
the initial audition to the DAW's song position: start it at the desired point
in the project loop. Host start never initiates audition; host stop silences it.
Exported MIDI is in musical ticks and carries the local BPM as its tempo event.
Native OS MIDI drag-out is not implemented; export files to commit a phrase.
See [FL Studio setup and acceptance checks](fl-studio.md).
Open **Sound roles** to pass existing notes between two
patches: alternate events, alternate question/answer bars, or divide strong beats
from replies. These modes distribute a monophonic phrase rather than generate
a second independent melody. Assign separate MIDI channels and explicitly map
each optional CC lane to a synth macro. Curves are normalized over the whole
phrase, with editable points and rise/fall/arch/pulse starting shapes.
Names describe your intent; the plugin does not infer feelings.
Patch profiles set register offset, gate, velocity, and estimated attack/release.
MIDI audition uses a short warmup for early triggers. Re-audition after a tempo
change to recompile millisecond offsets. Compensation estimates trigger timing;
it does not measure patch latency or model its sound. Default export retains
musical positions; compensated export adds one bar of lead-in. Role tracks carry
names, channels, and CC curves. Stop resets mapped controllers to their chosen
stop values. Internal audition does not reproduce mapped timbre.
See [the theory and producer workflow](theory/README.md).
Sessions save inside the host project and can be saved/loaded as JSON. Sessions
from versions 0.1–0.3 open as a storyboard: the old source motif becomes the
first motif in the bin, a kept phrase and saved gestures follow it, and an
eight-bar phrase becomes an arc (a four-bar phrase becomes statement and return).
Branch history is not carried over; undo replaces it. JSON state is bounded at
16 MiB. File export/save refuses to silently overwrite an existing file.
## Build and offline preview
Run from the repository root:
```sh
cargo run -p rivet-preview -- demo /tmp/rivet-demo
cargo run -p rivet-preview -- develop motif.mid 0 /tmp/phrase
cargo run -p rivet-preview -- develop motif.mid 0 /tmp/with-chords chords.mid 0
cargo run -p rivet-preview -- session saved-session.json /tmp/rendered-session
python scripts/build-plugin.py --plugin rivet --target x86_64-pc-windows-gnu
```
The preview builds an arc storyboard from the motif and writes the motif and
storyboard as MIDI, a session JSON, a WAV render using the same engine as the
plugin, and a table of blocks with their chosen options. Track indices exclude conductor-only tracks and start at
zero. Optional harmony arguments accept a separate polyphonic MIDI file.
See [development](../development.md) for checks, dependencies, architecture, and
[releases](../releases.md) for independent release tags.
## Design and references
[Theory findings and implemented design](theory/README.md) connect the research
to practical controls. [Implementation plan](implementation.md) records the musical and technical
choices. [Devath reference measurements](research/devath.md) document
analysis of the seven supplied FLACs, with reproducible plots and explicit limits.
Original reference audio is excluded from source distribution.
- `rivet-core`: meters, motifs, the storyboard (blocks, roles, joins, templates),
role-aware option writing, harmonic context, session migration, and bounded
playback clips.
- `rivet-midi`: bounded SMF 0/1 import/export. Rejects SMPTE, unsupported meters,
incomplete notes, and timing not exactly representable at 960 PPQ. Reports
ignored controllers/pitch bends. Polyphonic tracks work as harmonic context;
motif import requires monophony.
- `rivet-app`: worker jobs, revision handling, bounded queues, sample-accurate
preview/MIDI scheduling, and Windows/Zenity dialogs.
- `rivet`: CLAP wrapper, host persistence, editor, and standalone.
Tests cover musical constraints/diversity, harmony, every meter, storyboard
limits, joins, kept blocks, legacy state migration,
MIDI round trips, sample timing, looping, queued switches, note releases, and
zero allocation/deallocation during rendering and queued clip replacement. The
CLAP ABI test verifies discovery, note-output port exposure, state restoration,
and silent startup at several sample rates and buffer sizes.
## Existing projects
The CLAP ID is now `io.narl.bass-foundry.rivet` (earlier builds used
`io.storyboard.motif`). Hosts treat Rivet as a new plugin, so add it again in
projects saved with an earlier build. The `story-session-v1` host field and the
session JSON format are preserved, so saved sessions still open. Delete the old
plugin file, place `Rivet.clap`, and rescan FL Studio.