songbird-export
Offline audio rendering — master export, stem export, track bounce, and.bird-file rendering.
This crate renders audio from the engine graph to WAV files without real-time constraints. It processes the entire timeline (or a time range) as fast as possible and writes the result to disk.
Module Map
Public API (top-level functions)
export_master(path, &mut graph, &mut transport, &ExportConfig, progress)— full mixdown to a stereo WAV.export_stem(path, &mut graph, &mut transport, &StemExportConfig, progress)— solo a node, render to WAV, restore solo.export_all_stems(output_dir, &mut graph, &mut transport, &ExportConfig, &[NodeId], StemMode)— one WAV per node.bounce::bounce_track(&mut graph, &mut transport, NodeId, name, &BounceConfig, progress)— per-track bounce, optional normalization.trim_silence_file(input, output, threshold)— post-process trim of an existing WAV.bird_render::render_bird_to_wav(&source, output_str, &BirdRenderConfig, progress)— full session build + render from.birdtext.write_wav/write_wav_dithered— TPDF dither when reducing to 16/24-bit; bypass for 32-bit float.
How it’s wired
The sync engine calls into this crate viaEngineBackend methods on AppState:
| Sync command | Backend method | Renders via |
|---|---|---|
export.master | export_master_mix | export_master |
export.master_with_lane | export_master_with_lane | export_master (with swap_audition_lanes first) |
export.stem | export_stem | export_stem |
export.all_stems | export_stems | export_stem per track |
export.bounce_track | bounce_track | bounce_track |
notifications channel
(notifications:export_progress, notifications:export_done).
Known limitation: take-lane filtering during offline export
The two render entry points work differently:bird_render::render_bird_to_wavruns the full pipeline —session.scheduler.schedule(...)thensession.graph.process_with_clips(...)— so clips on the timeline are dispatched correctly. This is the pathsongbird-cli renderuses.export_master(used by allexport.*channel commands today) callsgraph.processdirectly without driving the scheduler. It only renders signals already flowing through the live graph (running synths, monitored input).
controller.swap_audition_lanes(...) has no effect on the rendered file today. export.master_with_lane is fully wired (snapshot, swap, restore), produces a uniquely-named output file, and is correct on the IPC seam — but the audio inside that file is the same as export.master until the offline export gains scheduler integration.
When the offline export path is upgraded to drive the scheduler, lane variations and stem-from-clips will start producing distinct content with no API changes.