SUPERB
Flows

Flows

The top tier of superb: one module per thing you work with, each a set of free functions over a Session. Every page opens with a full example.

flowdoespage
sessioncreate, open, save; import audio; tempo, meter, loop range; undosession
trackadd, fader, pan, mute, solo, arm, monitor, route, meter, archivetrack
clipaudio or MIDI on a track: add, move, split, trim, fade, mute; notesclip
markernamed places on the timelinemarker
transportstart, stop, seek, loop; the playheadtransport
senda copy of a track into a bussend
midiplay notes from code; connect a keyboardmidi
recordrecord onto armed tracks; punch points; recover after a crashrecord
metronomethe click; a count-inmetronome
exportbounce to WAV; a stem setexport
devicesspeakers, inputs, MIDI portsdevices

quick-start.md maps tasks to functions. flows/<flow>.ref.md is the generated reference for each page.

Example

use superb::primitives::session::TrackKind;
use superb::primitives::{Result, SampleRate, TimePosition};
use superb::{clip, export, session, track, transport};

fn main() -> Result<()> {
    let rate = SampleRate::HZ_48K;
    let mut session = session::create(std::env::temp_dir().join("demo"), rate, 256)?;

    let vox = track::add(&mut session, "vox", TrackKind::Audio)?;
    let vocal = session::import_audio(&mut session, "/music/vocal.wav")?;   // into audio/vocal.wav
    clip::add(&mut session, vox, vocal.key, TimePosition::ZERO)?;
    track::volume(&mut session, vox, -6.0)?;

    transport::start(&mut session)?;
    let heard = session::steps::render_blocks(&mut session, 8)?;   // no sound card needed
    println!("peak {:.3}", heard.peak());

    let mix = session::layout(&session).bounce("mix");               // bounces/mix.wav
    export::bounce(&mut session, mix, export::Bounce::default())?;
    session::save(&mut session)?;
    Ok(())
}

How it works

pub struct Session {
    pub memory: Memory,              // tracks, clips, routing, tempo: what gets saved
    pub history: UndoStack<Memory>,  // every edit goes through here
    pub audio: AudioCache,           // the audio clips play, keyed by path
    pub folder: PathBuf,             // the session folder
    pub engine: EngineHandle,        // control side of the running engine
    pub mixer: MixerHandles,         // live strip and send controls from the last rebuild
    pub recording: Option<Recording>,
    // ...
}
  • Verbs take &mut Session. A verb does one job by calling primitives in a fixed order; its rustdoc ends with Made of: naming them. When a verb is not what you want, call the primitives yourself.
  • Edits undo, state does not. Adding, moving, levels are edits on session.history. Mute, solo, arm, monitor, input, looping, the click and the playhead are state: heard at the next block, never an undo step, saved only once session::state_file names a file.
  • Drags coalesce. Moves of one control within half a second (Session::COALESCE_WINDOW) are one undo step. session.history.seal() ends the step now.
  • The mixer follows the memory. Edits that change its shape (a track, a clip, a send, a route, monitoring) rebuild it: at once while a device plays, otherwise at the next transport::start or render_blocks. Levels and state reach the live controls without a rebuild.
  • Commands land at the next block. transport::state right after transport::start still says Stopped. The playhead is the exception: after transport::seek it reads the new place at once.
  • No hardware needed. session::steps::render_blocks stands in for the sound card; export renders offline; record::start takes a queue you fill. The devices feature adds real outputs and inputs.

On this page