Expand description
§vibelang-core2
A clean, trait-based runtime for VibeLang that is generic over synthesis backends.
This crate provides the core audio engine for VibeLang, handling timing, scheduling, audio graph management, and communication with synthesis backends like SuperCollider.
§Design Goals
- Simplicity: One core type (
Runtime<B>) with clear responsibilities - Modularity: Feature traits with handler delegation for testability
- Platform-agnostic: Works for native (scsynth) and WASM (WebAudio)
- Async-first: Uses async channels and traits for cross-platform compatibility
- Type-safe: Newtype IDs prevent mixing up different resource types
§Architecture Overview
┌─────────────────────────────────────────────────────────────┐
│ Runtime<B> │
│ ┌─────────────┐ ┌──────────────┐ ┌───────────────────┐ │
│ │ Message │──│ Handlers │──│ Backend<B> │ │
│ │ Channel │ │ (dispatch) │ │ (scsynth/WASM) │ │
│ └─────────────┘ └──────────────┘ └───────────────────┘ │
│ │ │ │ │
│ ┌──────▼──────┐ ┌──────▼──────┐ ┌─────────▼─────────┐ │
│ │ Transport │ │ Groups │ │ Voices │ │
│ │ Clock/Tempo │ │ Routing │ │ Patterns │ │
│ └─────────────┘ └─────────────┘ │ Melodies │ │
│ └───────────────────┘ │
└─────────────────────────────────────────────────────────────┘The Runtime is generic over a Backend trait, allowing different synthesis
engines to be used interchangeably. All operations are performed via Messages
sent through an async channel, which the runtime dispatches to feature handlers.
§Quick Start
use vibelang_core::{Runtime, Message, GroupId, VoiceId, VoiceConfig};
use vibelang_core::message::{TransportMessage, GroupMessage, VoiceMessage};
use vibelang_core::backends::{ScsynthBackend, ScsynthProcess, ScsynthConfig};
use std::time::Duration;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// 1. Start the scsynth process
let process = ScsynthProcess::spawn(ScsynthConfig::default())?;
process.wait_startup(Duration::from_secs(2)).await;
// 2. Connect to scsynth and create the runtime
let backend = ScsynthBackend::connect(&process.addr()).await?;
let mut runtime = Runtime::new(backend);
let handle = runtime.handle();
// 3. Spawn the runtime loop
tokio::spawn(async move {
runtime.run().await;
});
// 4. Send messages to control audio
handle.send(TransportMessage::SetTempo { bpm: 128.0 }.into()).await?;
handle.send(GroupMessage::Create { id: GroupId::new(1), name: "main".to_string(), parent: None }.into()).await?;
handle.send(TransportMessage::Start.into()).await?;
Ok(())
}§Feature Flags
native(default): Enables native platform support with scsynth backendmidi: Enables MIDI device enumeration and I/O via midir
§Module Overview
| Module | Description |
|---|---|
types | Type-safe IDs (NodeId, GroupId, etc.), time types (Beat, Duration) |
traits | Feature trait definitions (Transport, Groups, Voices, etc.) |
handlers | Trait implementations that manage state and backend calls |
backends | Backend implementations (ScsynthBackend, process management) |
synthdefs | Built-in SynthDef generation for essential audio routing |
§Key Concepts
§Messages
All runtime mutations happen through Messages. Messages are organized by feature:
TransportMessage: Tempo, time signature, play/stopGroupMessage: Audio bus groups for mixingVoiceMessage: Synth voice creation and triggeringPatternMessage: Step sequencer patternsMelodyMessage: Note sequences with timing
§Groups and Routing
Audio flows through a hierarchy of groups. Each group has its own audio bus,
and system_link_audio synths route audio from child buses to parent buses:
Group 1 (drums) ──┐
├──► Main Output (bus 0)
Group 2 (bass) ──┘§Timing
The Beat type uses fixed-point arithmetic (16 fractional bits) for
sample-accurate timing without floating-point drift over long sessions.
Re-exports§
pub use audio::AudioConnector;pub use audio::AudioError;pub use audio::PortDirection;pub use audio::PortMatcher;pub use message::EffectMessage;pub use message::FadeMessage;pub use message::GroupMessage;pub use message::MelodyMessage;pub use message::Message;pub use message::PatternMessage;pub use message::ReloadMessage;pub use message::SampleMessage;pub use message::SequenceMessage;pub use message::SyncMessage;pub use message::SynthDefMessage;pub use message::TransportMessage;pub use message::VoiceMessage;pub use backends::setup_metering;pub use backends::setup_node_tracking;pub use backends::ProcessError;pub use backends::ScsynthBackend;pub use backends::ScsynthConfig;pub use backends::ScsynthProcess;pub use types::ids::BufferId;pub use types::ids::BusId;pub use types::ids::EffectId;pub use types::ids::GroupId;pub use types::ids::MelodyId;pub use types::ids::NodeId;pub use types::ids::PatternId;pub use types::ids::SampleId;pub use types::ids::SequenceId;pub use types::ids::VoiceId;pub use types::params::ParamMap;pub use types::time::Beat;pub use types::time::Duration;pub use types::time::TimeSignature;pub use types::ids::MidiDeviceId;pub use traits::Clip;pub use traits::FadeConfig;pub use traits::FadeCurve;pub use traits::FadeTarget;pub use traits::MelodyConfig;pub use traits::NoteEvent;pub use traits::PatternConfig;pub use traits::SampleConfig;pub use traits::SampleInfo;pub use traits::SequenceConfig;pub use traits::SfzConfig;pub use traits::Step;pub use traits::VoiceConfig;pub use traits::Effects;pub use traits::Fades;pub use traits::Groups;pub use traits::Melodies;pub use traits::Patterns;pub use traits::Samples;pub use traits::Sequences;pub use traits::SynthDefs;pub use traits::Transport;pub use traits::Voices;pub use validation::limits;pub use validation::Validate;pub use traits::Midi;pub use traits::MidiDeviceInfo;pub use midi::decode_packed_midi;pub use midi::pack_cc;pub use midi::pack_note_off;pub use midi::pack_note_on;pub use midi::pack_pitch_bend;pub use midi::parse_note_name;pub use midi::CallbackData;pub use midi::CallbackType;pub use midi::CcRouteBuilder;pub use midi::KeyboardRouteBuilder;pub use midi::MidiCallbacks;pub use midi::MidiData;pub use midi::MidiDeviceSender;pub use midi::MidiRealtimeConfig;pub use midi::MidiRealtimeService;pub use midi::MidiRealtimeStats;pub use midi::NoteRouteBuilder;pub use midi::ParameterCurve;pub use midi::QueuedMidiEvent;pub use midi::StoredCallback;pub use midi::VelocityCurve;pub use midi::VelocityMapping;pub use handlers::MidiEventNotification;pub use handlers::MidiHandler;pub use handlers::MidiMessage;
Modules§
- audio
- Audio connection management for VibeLang.
- backends
- Backend implementations for different synthesis engines.
- compat
- Platform compatibility layer for WASM and native targets.
- handlers
- Feature handlers for vibelang-core2.
- message
- Message types for runtime communication.
- midi
- MIDI infrastructure for vibelang-core2.
- reload
- Live reloading support for vibelang-core2.
- synthdefs
- Built-in SynthDef generation.
- traits
- Feature traits for vibelang-core2.
- trigger_
ids - SendTrig IDs for MIDI message types.
- types
- Core types for vibelang-core2.
- validation
- Validation utilities for vibelang-core2.
Structs§
- Active
Fade - An active fade operation.
- Buffer
Info - Information about a loaded audio buffer.
- Effect
State - Internal state for an effect.
- Group
State - Internal state for a group.
- Melody
State - Internal state for a melody.
- Meter
Level - Meter level for a group’s audio output.
- Pattern
State - Internal state for a pattern.
- Runtime
- The VibeLang runtime, generic over a synthesis backend.
- Runtime
Handle - A cloneable handle for sending messages to the runtime.
- Sequence
State - Internal state for a sequence.
- SfzInstrument
State - Internal state for a loaded SFZ instrument.
- SfzRegion
State - State for a single SFZ region (sample mapping).
- State
- Complete runtime state.
- Transport
Snapshot - Lock-free transport state snapshot.
- Voice
State - Internal state for a voice.
Enums§
- AddAction
- Where to place a new node relative to a target node.
- Error
- Unified error type for vibelang-core2 operations.
- Midi
Trigger Type - Types of MIDI trigger messages.
Traits§
- Backend
- Core synthesis backend abstraction.
Type Aliases§
- Result
- Result type alias using [
Error].