SUPERB
Flows

record

Start a recording, stop it, get a clip on every armed track.

Example

From a real input, with the devices feature:

use superb::primitives::session::{Input, TrackKind};
use superb::primitives::{Result, SampleRate, TimePosition};
use superb::{devices, record, session, track, transport};

fn main() -> Result<()> {
    let rate = SampleRate::HZ_48K;
    let mut session = session::create(std::env::temp_dir().join("take"), rate, 256)?;
    let vox = track::add(&mut session, "vox", TrackKind::Audio)?;
    track::arm(&mut session, vox, true)?;
    track::input(&mut session, vox, Some(Input::Mono(0)))?;   // the first input channel, mono
    track::monitor(&mut session, vox, true)?;                  // hear yourself

    devices::output(&mut session, None)?;
    record::punch_in(&mut session, Some(TimePosition::from_seconds(4.0, rate)))?;
    record::start(&mut session, record::Source::Device(None))?;   // rolls now, records from 4 s
    std::thread::sleep(std::time::Duration::from_secs(10));
    if let Some(r) = &session.recording {
        println!("{} frames, {} dropped, {} disk errors", r.frames(), r.dropped(), r.disk_errors());
    }

    let clips = record::stop(&mut session)?;              // one clip per armed track, one undo step
    let clip = session.memory.clip(clips[0])?;
    println!("{} at {:.1} s, {:.1} s long", clip.name,
        clip.start().to_seconds(rate), clip.length().to_seconds(rate));
    Ok(())
}

Offline, from a queue you fill yourself:

use superb::primitives::buffers::PlanarBuffer;
use superb::primitives::io::capture::capture_queue;
use superb::primitives::session::TrackKind;
use superb::primitives::{Result, SampleRate};
use superb::{record, session, track, transport};

fn main() -> Result<()> {
    let rate = SampleRate::HZ_48K;
    let mut session = session::create(std::env::temp_dir().join("offline-take"), rate, 256)?;
    let vox = track::add(&mut session, "vox", TrackKind::Audio)?;
    track::arm(&mut session, vox, true)?;
    transport::start(&mut session)?;

    let (mut mic, blocks) = capture_queue(1, 256, 64)?;         // one channel, blocks of 256 frames
    record::start(&mut session, record::Source::Queue { blocks, channels: 1 })?;
    let mut block = PlanarBuffer::new(1, 256);
    block.fill(0.25);                                            // stands in for a microphone
    for n in 0..100u64 {
        mic.push(&block, n * 256 * 1_000_000 / rate.hz() as u64);   // when it was captured, in µs
        session::steps::render_blocks(&mut session, 1)?;        // renders and collects
    }
    let clips = record::stop(&mut session)?;
    println!("{} clip, {} frames", clips.len(), session.memory.clip(clips[0])?.length().samples());
    Ok(())
}

cargo run --example record_take runs the offline version end to end.

Verbs

verbdoes
start(session, Source)record onto every armed track from the playhead, or from punch_in when it lies ahead
stop(session) -> Vec<ClipId>stop, finish the files, place the clips; one undo step
punch_in / punch_out(session, Option<at>)where the next recording drops in and out; edits
collect(session) -> framesdrain the queue into the files; render_blocks calls it, a device recording has its own thread
unfinished(session) -> Vec<PathBuf>files a crash left behind
recover(session) -> Vec<ClipId>finish them and place their clips
Sourcerecords from
Source::Device(Option<name>)the audio input (devices::input, opened if needed); feature devices
Source::Queue { blocks, channels }a capture queue you push into (capture_queue gives both ends)

session.recording holds the Recording while it runs: frames(), sealed_frames(), dropped(), disk_errors(), peaks(), files(), started_at(), punch_in(), punch_out().

Every signature, argument, error and undo step: record reference.

Notes

  • Each armed audio track gets its own 32-bit float WAV in audio/, written block by block from the first moment, so a crash costs about a second. Armed MIDI tracks get a clip of the notes that arrived.
  • With metronome::count_in set, a recording that starts at the playhead rolls that many bars early with the click.
  • A device take is lined up with the transport by the device clock, so the buffers in and out never shift it.
  • Undoing a recording removes its clips and deletes its files; redo writes them again. recover deletes nothing.
  • Loop recording is not there yet.

On this page