Python
The deterministic tono engine plus its live runtime, from Python: typed songs, numpy renders, and a speaker-owning engine — the tono module from crates/tono-py.
Install (build from source only)
Never published to PyPI (the name is taken), and no prebuilt wheels for now — build-from-source only until users ask for wheels. Requires stable Rust and CPython 3.9+ (abi3: one wheel per platform covers every 3.9+).
pip install maturin
maturin develop -m crates/tono-py/Cargo.toml # the `tono` module in your env
python3 crates/tono-py/tests/smoke.py # the determinism smoke test
maturin build --release -m crates/tono-py/Cargo.toml # abi3 wheel → target/wheels/Compile a song
import tono
song = tono.Song("night-drive", tempo=122.0)
bass = song.track("bass", tono.instruments.bass("finger"))
riff = tono.Pattern(bars=1)
riff.notes(["C2", "C2", "Eb2", "G2"], durations=0.5)
song.arrange(bass, riff, bars=range(4))
program = song.compile(sample_rate=48000) # tono.CompileError carries .diagnostics
audio = program.render() # np.float32, shape (frames, 2), L/RTyped Song / Pattern / Program wrap the native Rust model: no JSON, py.typed stubs in the wheel, and the same canonical program hash an equivalent Rust song compiles to. program.save(path) / tono.Program.load(path) ship the hashed bundle.
Run it live
with tono.Performance(program, headless=True) as perf: # or headless=False for speakers
perf.play()
perf.set_gain(0.8, at=tono.next_bar())
perf.transition("chorus", at=tono.next_bar()) # a named section
audio = perf.fill(program.sample_rate * 10) # stereo (frames, 2), float32
print(perf.metrics()) # frames, commands, queue depth, …Commands schedule at frames, beats, bars, markers, sections, tono.next_beat(), or tono.next_bar() — and execute at exact frames, never waiting on Python to wake up. Seeks, loops, crossfaded swaps, stingers, capture/replay, and snapshots work the same in both modes.
Runnable examples
All in crates/tono-py/examples/:
night_drive.py— the typed API end to end: compose, compile, render, and run a program live with scheduled commands.golden_hour.py— a produced 16-bar track; compiles, renders, and bouncesgolden_hour.wavyou can play.fur_elise.py— Beethoven's bagatelle on the sampled grand: 3/8 meter map with a pickup, a tempo-map ritardando, per-note dynamics.monsoon_melody.py— an original Bollywood-style ballad: flute over nylon-guitar arpeggios, a swung half-time kit, a glockenspiel-shadowed lift.neon_rush.py— an original synthwave racer: euclidean claps, probability hats, a 16th-note octave bass.noir_lounge.py— an original jazz-noir theme: heavy swing, walking bass, rootless Rhodes stabs.emerald_vale.py— an original fantasy-village pastoral: a true 6/8 meter map, nylon harp-rolls.puzzle_menu.py— an original puzzle/menu theme built by pattern transforms.live_pygame.py— live procedural audio for a Python game loop in ~10 lines.render_numpy.py— the pull API: render to a numpy array and use it anywhere.
