Examples
mix_session
examples/flows/mix_session.rs, the whole program
Run it with cargo run --example mix_session (see the examples for the features some need).
//! `track` is add, volume, pan, mute, solo, route. `send` is a copy of a
//! track into a bus.
//!
//! ```text
//! track::add / volume / pan / mute / solo / route / peak
//! send::add / level / enable
//! ```
//!
//! ```text
//! track::volume(&mut session, gtr, -6.0)?;
//! track::pan(&mut session, vox, -1.0)?;
//! track::mute(&mut session, gtr, true)?;
//! send::add(&mut session, vox, room, -6.0, SendTap::PostFader)?;
//! track::route(&mut session, gtr, Some(room))?;
//! ```
//!
//! ```text
//! cargo run --example mix_session
//! ```
use superb::primitives::buffers::PlanarBuffer;
use superb::primitives::mixer::{PanLaw, SendTap};
use superb::primitives::session::TrackKind;
use superb::primitives::{Result, SampleRate, TimePosition};
use superb::session::Session;
use superb::{clip, send, session, track, transport};
/// Peak of channel 0 on the last of 4 blocks (a fader ramp has finished).
fn level(session: &mut Session) -> Result<f32> {
let audio = session::steps::render_blocks(session, 4)?;
let last = audio.frames() - session.engine.max_frames();
Ok(audio.channel(0)[last..]
.iter()
.fold(0.0f32, |m, s| m.max(s.abs())))
}
fn main() -> Result<()> {
let rate = SampleRate::HZ_48K;
let mut session = session::create(std::env::temp_dir().join("mix_session.superb"), rate, 128)?;
let vox = track::add(&mut session, "vox", TrackKind::Audio)?;
let gtr = track::add(&mut session, "gtr", TrackKind::Audio)?;
// 4 s of DC 0.25 on both tracks. Balance pan so centre is unity.
let mut tone = PlanarBuffer::new(2, rate.hz() as usize * 4);
tone.fill(0.25);
session.audio.insert("audio/tone.wav", tone);
for t in [vox, gtr] {
clip::add(&mut session, t, "audio/tone.wav", TimePosition::ZERO)?;
}
transport::start(&mut session)?;
for (_, strip) in &session.mixer.strips {
strip.set_pan_law(PanLaw::Balance);
}
println!("both tracks at 0 dB: {:.3}", level(&mut session)?);
// gtr fader to −6 dB. Moves in one undo step.
for db in [-2.0, -4.0, -6.0] {
track::volume(&mut session, gtr, db)?;
}
session.history.seal();
println!("gtr at -6 dB: {:.3}", level(&mut session)?);
println!("undo steps so far: {}", session.history.undo_len());
// vox hard left.
track::pan(&mut session, vox, -1.0)?;
let audio = session::steps::render_blocks(&mut session, 4)?;
let n = audio.frames() - 1;
println!(
"vox hard left: L {:.3} R {:.3}",
audio.channel(0)[n],
audio.channel(1)[n]
);
track::pan(&mut session, vox, 0.0)?;
track::mute(&mut session, gtr, true)?;
println!("gtr muted: {:.3}", level(&mut session)?);
track::mute(&mut session, gtr, false)?;
track::solo(&mut session, gtr, true)?;
println!("gtr soloed: {:.3}", level(&mut session)?);
track::solo(&mut session, gtr, false)?;
// Bus "room". Post-fader send from each at −6 dB.
let room = track::add(&mut session, "room", TrackKind::Bus)?;
let vox_send = send::add(&mut session, vox, room, -6.0, SendTap::PostFader)?;
let _gtr_send = send::add(&mut session, gtr, room, -6.0, SendTap::PostFader)?;
session::steps::rebuild(&mut session)?;
for (_, strip) in &session.mixer.strips {
strip.set_pan_law(PanLaw::Balance);
}
println!("plus bus with two sends: {:.3}", level(&mut session)?);
send::level(&mut session, vox_send, -12.0)?;
println!("vox send at -12 dB: {:.3}", level(&mut session)?);
send::enable(&mut session, vox_send, false)?;
println!("vox send off: {:.3}", level(&mut session)?);
// gtr through the bus; bus fader −6 dB.
track::route(&mut session, gtr, Some(room))?;
session::steps::rebuild(&mut session)?;
for (_, strip) in &session.mixer.strips {
strip.set_pan_law(PanLaw::Balance);
}
track::volume(&mut session, room, -6.0)?;
println!("gtr via bus at -6 dB: {:.3}", level(&mut session)?);
let [l, r] = track::peak(&session, room).expect("room meter");
println!("room bus meter: L {l:.3} R {r:.3}");
// Undo back to two tracks and two clips.
while session.history.undo_len() > 4 {
session::undo(&mut session)?;
}
println!(
"after undo: gtr {} dB, {} tracks, gtr sends {}",
session.memory.track(gtr)?.state.volume_db,
session.memory.track_count(),
session.memory.track(gtr)?.sends().len()
);
Ok(())
}