songbird-engine
Core audio engine — graph, transport, scheduling, automation, mixing, and IPC types. This is the largest crate in the workspace (~70K lines, 2,170 tests) and contains all the runtime logic for audio processing, MIDI routing, clip playback, and the type definitions shared between the engine and the Tauri IPC layer.See also: ../../ARCHITECTURE.md for the full architecture reference and threading model.
Module Map
songbird-engine/src/
├── graph.rs — AudioGraph DAG, AudioNode, Connection, topological sort, parallel processing
├── transport.rs — Play/stop/record/loop/seek, metronome, sample-accurate advance
├── tempo_map.rs — BPM ↔ seconds/beats conversion, tempo automation
├── clip_scheduler.rs — Timeline clip playback (MIDI + audio), beat-based scheduling
├── clip_launcher.rs — Session view: ClipSlot, Scene, LaunchQuantize, FollowAction
├── automation.rs — AutomationLane, AutomationPoint, breakpoint envelopes
├── automation_curve.rs — Bezier/spline interpolation for smooth automation curves
├── mixer.rs — Mixer model: TrackType, sends, groups, bus routing
├── mixer_snapshot.rs — Capture/recall full mixer state
├── audio_io.rs — cpal AudioDevice abstraction
├── ring_buffer.rs — Lock-free SPSC ring buffer for engine↔UI commands/events
├── engine_controller.rs — EngineController (real-time) + OfflineEngineController (offline/testing)
├── project_loader.rs — Bird→EngineSession loader (full pipeline orchestrator)
├── ipc_types.rs — 87+ IPC response types (TransportInfo, TrackInfo, ExportResponse, ...)
├── event_bridge.rs — Engine → UI event channel (metering, transport state pushes)
├── plugin_chain.rs — Nested plugin chain (ChainNode: Plugin | Container)
├── plugin_host.rs — Plugin hosting utilities (parameter caching, state management)
├── midi_router.rs — MIDI event routing, filtering, velocity curves
├── midi_utils.rs — MIDI utility functions (note names, frequency conversion)
├── midi_effects.rs — MIDI effects (arpeggiator, chord, transpose, etc.)
├── midi_clock.rs — MIDI clock sync (send/receive)
├── midi_device.rs — MIDI device enumeration and management
├── midi_learn.rs — MIDI learn (parameter ↔ CC mapping)
├── modulation.rs — Modulation matrix (LFO → parameter routing)
├── sidechain.rs — Sidechain routing (key input, detector)
├── pdc.rs — Plugin delay compensation
├── metering.rs — Level metering (peak, RMS, LUFS)
├── audio_analysis.rs — Spectrum analysis, FFT, frequency detection
├── audio_bus.rs — Audio bus routing model
├── audio_file.rs — Audio file loading/decoding
├── audio_quantize.rs — Audio-to-grid quantization
├── time_stretch.rs — Time stretching / pitch shifting
├── tempo_detection.rs — BPM detection from audio
├── sample_rate_convert.rs — Sample rate conversion
├── normalization.rs — Audio normalization (peak, LUFS)
├── crossfade.rs — Crossfade curves (equal power, linear, S-curve)
├── fade_handle.rs — Fade in/out handles on clips
├── bounce.rs — Track bounce (render in place)
├── track_freeze.rs — Track freeze/unfreeze
├── track_group.rs — Track grouping (link volume, mute, solo)
├── track_template.rs — Track template save/load
├── clip_effects.rs — Per-clip effect chain
├── comping.rs — Comp lane management (take recording)
├── surround.rs — Surround/spatial audio routing
├── groove.rs — Groove templates (swing, humanize)
├── macro_controls.rs — Macro knob → multi-parameter mapping
├── controller_profile.rs — Hardware controller profiles
├── input_monitor.rs — Input monitoring (direct, software)
├── preset_browser.rs — Preset browsing and search
├── warp_marker.rs — Audio warp markers (like Ableton's warp)
├── arrangement_marker.rs — Arrangement markers and regions
├── time_signature.rs — Time signature model
├── thread_pool.rs — Audio thread pool management
├── diagnostics.rs — Engine diagnostics (CPU, buffer stats)
├── signal_router.rs — Signal routing matrix
├── undo_redo.rs — Engine-level undo/redo
├── send_return.rs — Send/return routing (SendReturnRouter, RoutingResult)
├── send_return_automation.rs — Send/return gain automation
└── [test modules] — 12+ test files (see below)
Core Types
AudioGraph
Connection-based directed acyclic graph with topological sort and parallel processing.let mut graph = AudioGraph::new();
let node_a = graph.add_node("Synth");
let node_b = graph.add_node("Reverb");
graph.connect(Connection::new(node_a, node_b, 0, 0)); // port 0 → port 0
graph.rebuild_topology(); // Kahn's algorithm, caches levels + scratch buffers
graph.process(num_samples, sample_rate); // rayon parallel per level
- Connection ports — each connection has
from_portandto_portindices, enabling sidechain routing - LatencyHint — per-node hint (
RealTime,Buffered,Offline) for future ASIO-Guard-style dual-path rendering - Parallel levels — nodes at the same topological level execute concurrently via
rayon::scope - ScratchPool — pre-allocated per-node buffers, zero allocation during
process()
Transport
let mut transport = Transport::new(44100.0);
transport.set_bpm(128.0);
transport.play();
let (start, end) = transport.advance(512); // returns consumed time range
transport.set_loop(true, 0.0, 4.0); // loop 0-4 seconds
transport.set_metronome(true); // enable click track
AutomationState
let mut auto = AutomationState::new();
let lane = auto.get_or_create_lane(0, 0, "volume");
lane.add_point(AutomationPoint::new(0.0, 0.5)); // beat 0 → 0.5
lane.add_point(AutomationPoint::new(4.0, 1.0)); // beat 4 → 1.0
let value = lane.value_at_beat(2.0); // interpolated: 0.75
IPC Types
87+ strongly-typed response structs for all Tauri IPC commands:// All IPC responses use this wrapper
pub struct IpcResult<T: Serialize> {
pub ok: bool,
pub data: Option<T>,
pub error: Option<String>,
}
// Example response types
pub struct TransportInfo { pub state: String, pub position: f64, pub bpm: f64, ... }
pub struct TrackInfo { pub id: usize, pub name: String, pub volume: f64, ... }
pub struct ExportResponse { pub path: String, pub duration: f64, pub format: String, ... }
Test Suites
| File | Tests | Purpose |
|---|---|---|
engine_controller.rs | 179 | Offline rendering, callbacks, cross-crate integration, robustness hardening |
project_loader.rs | 60 | Bird→EngineSession loading, routing, plugins, edge cases |
e2e_tests.rs | 15 | Full engine pipeline tests |
engine_e2e_tests.rs | 15 | End-to-end: transport → graph → clips → output |
audio_output_tests.rs | 25 | Waveform correctness, golden output, DSP parity |
ipc_roundtrip_tests.rs | 87 | Serialize/deserialize all IPC response types |
ipc_workflow_tests.rs | 15 | Full user workflows through IPC layer |
ipc_handler_coverage_tests.rs | 54 | All 202+ Tauri command handlers wired |
edge_case_tests.rs | 25 | NaN, Inf, empty buffers, extreme values |
stress_tests.rs | 15 | Concurrent mutations, MIDI floods, large graphs |
perf_tests.rs | 15 | Graph throughput, parallel speedup, zero-alloc |
rt_safety_tests.rs | 25 | Zero allocation in audio callback path |
bird_engine_integration_tests.rs | — | Bird→engine integration tests |
bird_enhancements_e2e_tests.rs | — | Bird format enhancements E2E |
session_pipeline_e2e_tests.rs | — | Session pipeline E2E tests |
cargo test -p songbird-engine # All engine tests
cargo test -p songbird-engine -- e2e # E2E tests only
cargo test -p songbird-engine -- audio_output # Audio verification only