Examples
new_session
examples/flows/new_session.rs, the whole program
Run it with cargo run --example new_session (see the examples for the features some need).
//! `session` is create, open, save, tempo, undo. `track::add` and
//! `clip::add` put tracks and clips in the Memory.
//!
//! ```text
//! session::create / open / save / set_tempo / undo / redo
//! track::add
//! clip::add / move_to
//! marker::add
//! ```
//!
//! ```text
//! let mut session = session::create(&folder, SampleRate::HZ_48K, 256)?;
//! let vox = track::add(&mut session, "vox", TrackKind::Audio)?;
//! clip::add(&mut session, vox, "audio/take.wav", TimePosition::ZERO)?;
//! session::save(&mut session)?;
//! let again = session::open(&folder, 256)?;
//! ```
//!
//! ```text
//! cargo run --example new_session
//! ```
use superb::primitives::buffers::PlanarBuffer;
use superb::primitives::session::{MidiNote, TrackKind};
use superb::primitives::{BeatPosition, Result, SampleRate, TimePosition};
use superb::{clip, marker, session, track};
fn main() -> Result<()> {
// Folder at 48 kHz, blocks of 256. Tempo 120.
let folder = std::env::temp_dir().join("My first session");
let mut session = session::create(&folder, SampleRate::HZ_48K, 256)?;
let rate = session.memory.sample_rate();
// Audio track and MIDI track.
let vox = track::add(&mut session, "vox", TrackKind::Audio)?;
let keys = track::add(&mut session, "keys", TrackKind::Midi)?;
// 1 s of 220 Hz sine at 0.3, stereo, keyed "audio/vox-take-1.wav".
let mut take = PlanarBuffer::new(2, rate.hz() as usize);
for ch in 0..2 {
for (i, s) in take.channel_mut(ch).iter_mut().enumerate() {
let t = i as f32 / rate.hz() as f32;
*s = 0.3 * (t * 220.0 * core::f32::consts::TAU).sin();
}
}
session.audio.insert("audio/vox-take-1.wav", take);
// Clip at 0.5 s, named "vox-take-1".
let clip = clip::add(
&mut session,
vox,
"audio/vox-take-1.wav",
TimePosition::from_seconds(0.5, rate),
)?;
// Four notes a beat apart, each 0.9 beats, velocity 96.
let notes: Vec<MidiNote> = [60u8, 64, 67, 72]
.iter()
.enumerate()
.map(|(i, ¬e)| MidiNote {
beat: i as f64,
length: 0.9,
note,
velocity: 96,
channel: 0,
})
.collect();
clip::add(&mut session, keys, notes, TimePosition::ZERO)?;
// Tempo 100. Marker "verse" at 0.5 s.
session::set_tempo(&mut session, 100.0)?;
marker::add(&mut session, "verse", TimePosition::from_seconds(0.5, rate))?;
println!(
"{}: {} tracks, {} clips, {} bpm",
session.memory.name(),
session.memory.track_count(),
session.memory.clip_count(),
session.memory.tempo_map().tempo_at(BeatPosition::ZERO)
);
// Move the vox clip to 2.0 s. Undo / redo that move.
clip::move_to(
&mut session,
clip,
vox,
TimePosition::from_seconds(2.0, rate),
)?;
session.history.seal();
println!(
"clip now starts at {:.2} s",
session.memory.clip(clip)?.start().to_seconds(rate)
);
session::undo(&mut session)?;
println!(
"after undo: {:.2} s",
session.memory.clip(clip)?.start().to_seconds(rate)
);
session::redo(&mut session)?;
println!(
"after redo: {:.2} s",
session.memory.clip(clip)?.start().to_seconds(rate)
);
// save writes memory.json and audio/vox-take-1.wav.
println!("saved? {}", session.history.is_clean());
session::save(&mut session)?;
println!(
"saved? {} -> {}",
session.history.is_clean(),
folder.display()
);
// open reads it back.
let again = session::open(&folder, 256)?;
println!(
"reopened {:?}: {} tracks, {} clips, {} audio file(s), marker {:?} at {:.2} s",
again.memory.name(),
again.memory.track_count(),
again.memory.clip_count(),
again.audio.len(),
again.memory.markers()[0].name,
again.memory.markers()[0].position().to_seconds(rate)
);
Ok(())
}