| Crates.io | vibelang-dsp |
| lib.rs | vibelang-dsp |
| version | 0.3.0 |
| created_at | 2025-12-03 10:12:21.520176+00 |
| updated_at | 2026-01-12 17:54:53.361568+00 |
| description | SynthDef generation and UGen DSL for VibeLang |
| homepage | |
| repository | https://github.com/trusch/vibelang |
| max_upload_size | |
| id | 1963758 |
| size | 418,788 |
SynthDef generation and UGen DSL for VibeLang.
vibelang-dsp provides the synthesis definition layer for VibeLang. It enables creating SuperCollider-compatible SynthDefs using a Rust DSL that's also exposed to Rhai scripts.
Key features:
.vibe scripts┌─────────────────────────────────────────┐
│ define_synthdef() │
│ (Rhai or Rust closure) │
└────────────────┬────────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ GraphBuilder │
│ (Thread-local active builder pattern) │
└────────────────┬────────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ GraphIR │
│ (UGens, Inputs, Parameters) │
└────────────────┬────────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ encode_synthdef() │
│ (Binary scsyndef format) │
└─────────────────────────────────────────┘
graph/ - Synthesis Graph IRCore types for representing synthesis graphs:
use vibelang_dsp::graph::{Rate, GraphIR, UGenNode};
// Rates: Scalar < Control < Audio
let rate = Rate::Audio;
// Build graphs with the builder pattern
rhainodes/ - NodeRef OperationsNodeRef wraps graph nodes with operator overloading:
use vibelang_dsp::NodeRef;
// Arithmetic operations create new graph nodes
let mixed = osc1 + osc2;
let scaled = osc * 0.5;
let detuned = freq * 1.01;
builder/ - SynthDef BuilderCreate synthdefs with closures:
use vibelang_dsp::SynthDef;
let synthdef = SynthDef::new("my_synth")
.param("freq", 440.0)
.param("amp", 0.5)
.body(|freq, amp| {
let osc = sin_osc_ar(freq);
osc * amp
});
ugens/ - UGen LibraryAuto-generated from ugen_manifests/*.json:
// Oscillators
sin_osc_ar(freq)
saw_ar(freq)
pulse_ar(freq, width)
// Filters
rlpf_ar(input, freq, q)
rhpf_ar(input, freq, q)
moog_ff_ar(input, freq, gain)
// Envelopes
env_gen_ar(env, gate)
// Delays & Effects
delay_l_ar(input, max_delay, delay_time)
comb_l_ar(input, max_delay, delay_time, decay)
// And 100+ more...
helpers/ - High-Level DSP Functionsuse vibelang_dsp::helpers::*;
// Envelope generation
let env = env_adsr(0.01, 0.1, 0.7, 0.3);
let eg = env_gen(env, gate, 2.0); // done_action=2
// Signal utilities
let sum = mix(vec![osc1, osc2, osc3]);
let channels = channels(stereo_ugen, 2);
// Audio I/O
let input = in_ar(0);
replace_out_ar(0, output);
encoder/ - Binary Encodinguse vibelang_dsp::encode_synthdef;
let graph_ir = synthdef.build()?;
let binary = encode_synthdef("name", &graph_ir)?;
// binary is SuperCollider-compatible scsyndef format
In .vibe scripts:
define_synthdef("bass")
.param("freq", 110.0)
.param("amp", 0.5)
.param("gate", 1.0)
.body(|freq, amp, gate| {
let osc = saw_ar(freq) + saw_ar(freq * 1.01);
let filt = rlpf_ar(osc, 800.0, 0.3);
let env = env_adsr(0.01, 0.1, 0.5, 0.2);
let env = NewEnvGenBuilder(env, gate)
.with_done_action(2.0)
.build();
filt * env * amp
});
UGens are generated at build time from JSON manifests:
ugen_manifests/
├── oscillators.json
├── filters.json
├── envelopes.json
├── delays.json
└── ...
The build.rs script generates src/ugens/generated.rs containing all UGen wrapper functions.
ugen_manifests/MIT OR Apache-2.0