SUPERB
Flows

record reference

Generated from the source by scripts/reference.py. Do not edit this file. The short page, with the examples, is [record](record.md).

Reference

Every function of the record flow: what it takes, what it returns, what it refuses, and how it undoes. A Result<T> is Ok(T) or a SuperbError; the errors listed are the ones you can cause.

start

pub fn start(session: &mut Session, source: Source) -> Result<()>

Starts recording from source onto every armed track. Recording begins at the playhead, or at the punch-in point when one is set ahead of it (punch_in): the transport rolls from where it is and drops into record there. With a punch-out point (punch_out) it drops out of record there and keeps playing; stop finishes either way. A recording that starts at the playhead gets the metronome's count-in (metronome::count_in): the transport rolls that many bars early with the click sounding. Every armed audio track gets its file in the session folder now (audio/vox 1.wav, with a .recording tag beside it) and the audio streams into it from the first block.

Takes

  • session: &mut Session — the open session, borrowed mutably
  • source: Source — Source::Device(Some(name)) or Source::Device(None) for the default input (feature devices); Source::Queue { blocks, channels } for audio you push yourself

Returns Result<()> — nothing; session.recording holds the recording until stop

Errors a recording already running; no armed track; the device input cannot be opened; the command queue is full.

Undo none: not an edit until stop.

Made of track::armed tracks → for a device, devices::input if needed and its recording queue → a wav::Writer and a tag per armed audio track → a collector thread for a device → session::steps::rebuild when needed → EngineHandle::send(SetPunch) → EngineHandle::send(Record), or Play when the punch-in is ahead → transport::playhead for where it all started.

Example

record::start(&mut session, record::Source::Device(None))?;   // the default input
// ... play ...
let clips = record::stop(&mut session)?;

punch_in

pub fn punch_in(session: &mut Session, at: Option<TimePosition>) -> Result<()>

Sets or clears the punch-in point: where the next recording begins when it lies ahead of the playhead. Saved with the session; an edit that coalesces like a drag.

Takes

  • session: &mut Session — the open session, borrowed mutably
  • at: Option<TimePosition> — Some(position) where the next recording drops in; None clears it

Returns Result<()> — nothing

Errors never in practice.

Undo one undo step per drag: calls within Session::COALESCE_WINDOW (half a second) merge.

Made of SetPunch through session::edit.

Example

record::punch_in(&mut session, Some(TimePosition::from_seconds(16.0, rate)))?;

punch_out

pub fn punch_out(session: &mut Session, at: Option<TimePosition>) -> Result<()>

Sets or clears the punch-out point: where a recording drops out of record on its own and keeps playing. Saved with the session; an edit that coalesces like a drag.

Takes

  • session: &mut Session — the open session, borrowed mutably
  • at: Option<TimePosition> — Some(position) where the recording drops out; None clears it

Returns Result<()> — nothing

Errors never in practice.

Undo one undo step per drag: calls within Session::COALESCE_WINDOW (half a second) merge.

Made of SetPunch through session::edit.

Example

record::punch_out(&mut session, Some(TimePosition::from_seconds(24.0, rate)))?;

collect

pub fn collect(session: &mut Session) -> usize

Writes waiting audio blocks to the recording's files when the source is a queue (Source::Queue), and takes the MIDI that arrived since the last call either way; a device recording's audio has its own thread. Returns the frames captured in total, or zero when nothing is recording. session::steps::render_blocks calls this after every block; with a device driving the engine, call it from a timer during long takes, so the MIDI queue (MIDI_CAPTURE_CAPACITY messages) never fills.

Takes

  • session: &mut Session — the open session, borrowed mutably

Returns usize — the audio frames gathered so far, or zero when nothing is recording

Errors never.

Undo none.

Example

let frames = record::collect(&mut session);   // call from a timer while a device drives the engine

stop

pub fn stop(session: &mut Session) -> Result<Vec<ClipId>>

Stops the recording and the transport, finishes the files and places one clip per armed track. An audio clip refers to its track's file (audio/vox 1.wav, so it is named vox 1) from the punch-in point: what was captured before it (the roll towards it, a count-in) stays in the file ahead of the clip's offset, and what came after the punch-out stays past its end, so the clip can be trimmed out over it later like any other. The file holds the channels the track's Input selects (tracks without one get the whole capture). A device take lands where it was played: the file's first frame is placed by the device clock, and a capture that began after the transport rolled gives a clip that starts that much later. Returns the new clips (none if nothing was captured). The whole placement is one undo step called "Record": undoing it removes the clips and deletes the files it wrote, redo writes them again from the audio kept in memory.

Takes

  • session: &mut Session — the open session, borrowed mutably

Returns Result<Vec<ClipId>> — the ids of the clips placed, one per armed track that got something (audio inside the punch points, or notes that arrived)

Errors nothing recording; a file cannot be finished or read back; the collector thread failed.

Undo one step labelled "Record": undo removes the clips and deletes the files they wrote, redo writes them again; rebuilds the mixer (at once while a device plays, otherwise at the next start).

Made of EngineHandle::send(Stop) → drain the queue or Collector::finish (and hand the audio input its queue back) → wav::Writer::finish per file, tags removed → the file's first frame lined up with the RollStart when the device clock gives one → per track, the clip's start, offset into the file and length from the punch points → wav::read into AudioCache::insert_shared → clip::add, inside one undo group; rebuilds the mixer so the clips play back on their strips.

Example

let clips = record::stop(&mut session)?;

unfinished

pub fn unfinished(session: &Session) -> Vec<PathBuf>

Recordings a crash left unfinished in the session folder: files that still have their .recording tag beside them, as keys (audio/vox 1.wav). recover places them; until then they are not clips and session::open only notes them in the log.

Takes

  • session: &Session — the open session, borrowed

Returns Vec<PathBuf> — the files a crash left unfinished, as keys into the session folder (audio/vox 1.wav); empty when there are none

Errors never; a query.

Undo none.

Example

for key in record::unfinished(&session) { println!("unfinished: {}", key.display()); }

recover

pub fn recover(session: &mut Session) -> Result<Vec<ClipId>>

Places the recordings a crash left unfinished (unfinished): each file's header is finished in place (wav::repair), its audio loaded, and a clip placed on the track it was recording for, from the punch-in point the tag remembers, lined up as if the capture began where the transport rolled (the device clock that would say otherwise is gone with the crash). The tags are removed; the files stay, and the placement is one undo step called "Recover" whose undo removes the clips but deletes nothing. A tag whose track is gone, or whose file cannot be read, is left where it is and noted in the log. Refused while a recording runs.

Takes

  • session: &mut Session — the open session, borrowed mutably

Returns Result<Vec<ClipId>> — the ids of the clips placed, one per unfinished file whose track still exists

Errors a recording running; a clip cannot be placed.

Undo one step labelled "Recover": undo removes the clips and deletes nothing; rebuilds the mixer (at once while a device plays, otherwise at the next start).

Made of the tags in audio/ → wav::repair → wav::read into AudioCache::insert_shared → AddClip through session::structural per file, inside one undo group; rebuilds the mixer.

Example

let placed = record::recover(&mut session)?;   // after session::open noted unfinished recordings

Types

Source

Where a recording's audio comes from.

Variants

  • Device(Option<String>) — The session's audio input (devices::input). If it is not open yet, this opens it on the named device (None for the default). Every channel the input carries is captured, and a thread gathers the audio until stop; each track keeps the channel(s) its track::input names.
  • Queue { blocks: CaptureConsumer, channels: usize } — A capture queue you fill yourself (a file, a generator, a test) with blocks of channels channels. Blocks wait on the queue until collect runs; session::steps::render_blocks does that after every block, so an offline program never calls it.

Recording

A recording in progress: what Session::recording holds between start and stop. Its audio is on disk from the first block: one WAV file per armed audio track in the session folder (audio/vox 1.wav), written as the blocks arrive and flushed about once a second, so a crash costs a second of audio, not the take, and the take never has to fit in memory. The counters here are what an application shows while it records: frames captured and sealed on disk, blocks dropped, disk errors, the level of the latest block, and how long ago it came.

Methods

  • fn frames(&self) -> usize — Frames captured so far: handed to the files, not all on disk yet.
  • fn sealed_frames(&self) -> u64 — Frames on disk for good in every file of the recording: written, synced and covered by a header a reader accepts. Everything before this frame survives a crash and will never change, so an uploader can ship the byte range it covers. Advances about once a second.
  • fn disk_errors(&self) -> u64 — Writes that failed across the files (disk full, file gone, I/O error). Anything above zero means a gap in a file; the recording keeps draining its queue so the audio thread is never held up, and the application decides whether to stop.
  • fn dropped(&self) -> u64 — Blocks the input side could not queue because the queue was full. Anything above zero means a gap in the recording.
  • fn peaks(&self) -> Vec<f32> — Peak per captured channel of the latest block, 0.0 to 1.0 and above when clipping; all zero before the first block.
  • fn since_last_block(&self) -> Option<core::time::Duration> — How long ago the last block arrived; None before the first. A value that keeps growing while the transport rolls means the source went quiet: the device was unplugged, or nothing feeds the queue.
  • fn files(&self) -> &[PathBuf] — The files being written, one per armed audio track, as keys into the session folder (audio/vox 1.wav). They exist from start on, grow as the recording runs, and are the clips' audio after stop.
  • fn started_at(&self) -> TimePosition — Where the transport started rolling: at or before the punch-in.
  • fn punch_in(&self) -> TimePosition — Where the recording begins and the clips will start.
  • fn punch_out(&self) -> Option<TimePosition> — Where the recording ends on its own, if a punch-out point was set.
  • fn tracks(&self) -> &[TrackId] — The tracks that were armed when it started; each gets a clip.
  • fn channels(&self) -> usize — Audio channels being captured; zero when no audio track is armed.
  • fn midi_messages(&self) -> usize — Incoming MIDI messages gathered so far.

On this page