17.9. Top-level playback harness: tracks, BPM/CPS, and threaded audio
Module strudel_player
17.9.1. Structures
- AudioChunk
- Fields:
samples : array<float> - Interleaved stereo PCM samples for one chunk.
17.9.2. Lifecycle
- strudel_create_channel()
Create the PCM stream for main-thread playback. Call once after audio_system_create() and before strudel_tick.
- strudel_init(fn: function<():void>; cmd_fn: function<(cmd:string):void> = @@strudel_noop_cmd)
Spawn the strudel playback thread and inject shared resources (sample bank, SF2, audio channel). fn runs on the new thread — it should add tracks and call strudel_play(). Call from main thread only.
- Arguments:
fn : function<void>
cmd_fn : function<(cmd:string):void>
- strudel_shutdown()
Shut down playback: signal the strudel thread to stop, release channels/lockboxes, free all tracks. Safe to call from the main thread; also finalizes memory/utilization stats.
17.9.3. Playback control
- strudel_command(cmd: string)
Send a user command string from the main thread to the strudel playback thread. The command is dispatched to the cmd_fn passed to strudel_init.
- Arguments:
cmd : string
- strudel_noop_cmd(cmd: string)
No-op command handler — default argument when no user command dispatcher is needed.
- Arguments:
cmd : string
- strudel_play(cmd_fn: function<(cmd:string):void> = @@strudel_noop_cmd)
Blocking multi-track tick loop for threaded playback. Runs on the strudel thread (spawned by strudel_init); dispatches incoming user commands via cmd_fn until shutdown.
- Arguments:
cmd_fn : function<(cmd:string):void>
- strudel_set_pause(paused: bool)
Pause or resume audio output.
- Arguments:
paused : bool
- strudel_tick()
Single main-thread tick: query all tracks, render audio, mix, append to the PCM stream. Call from your render loop; self-regulating — skips when the audio buffer has enough data queued.
- strudel_tick_offline()
Offline tick: same as strudel_tick but without an audio driver. Renders into g_master_pcm and advances g_wall_time; call in a tight loop for offline WAV rendering.
17.9.4. Tempo and timing
- strudel_get_playback_time(): tuple<double;double>
Get current playback wall-clock time and tempo as (wall_time, cps). In threaded mode reads from a lockbox; in main-thread mode uses the hardware consumed position (smooth, matches what you hear) and lags g_wall_time by the audio buffer depth.
- strudel_set_bpm(bpm: double)
Set tempo in beats per minute (assumes 4 beats per cycle). Safe to call from the main thread.
- Arguments:
bpm : double
- strudel_set_cps(cps: double)
Set tempo directly in cycles per second. Safe to call from the main thread.
- Arguments:
cps : double
- strudel_set_look_ahead(look_ahead: float)
Set how far ahead (in seconds) to query the pattern for upcoming events.
- Arguments:
look_ahead : float
17.9.5. Volume
- strudel_set_volume(volume: float; time: float = 0f)
Set the master playback volume, optionally ramping to it over the given time in seconds.
- Arguments:
volume : float
time : float
17.9.6. Asset loading
- strudel_get_sf2_path(): string
Return the path of the currently loaded SoundFont (empty string if none).
- strudel_has_sf2(): bool
Return true if a SoundFont has been loaded.
- strudel_load_sample_dir(root: string)
Load every audio file under root as a named sample (filename becomes the sound name).
- Arguments:
root : string
- strudel_load_sf2(path: string): bool
Load a SoundFont (.sf2) file for SF2-based synthesis. Returns true on success.
- Arguments:
path : string
- strudel_load_sound(path: string; name: string)
Load a single audio sample from disk and register it under the given name. Duplicates are ignored.
- Arguments:
path : string
name : string
17.9.7. Track management
- strudel_add_track(pat: Pattern; gain: float = 1f): int
Add a track playing the given pattern at the given gain. Returns its index (matches g_vis_index for visualizer combinators).
- Arguments:
pat : Pattern
gain : float
- strudel_fade_track(idx: int; target_gain: float; time: float)
Fade a track’s gain to target_gain over the given time in seconds (time=0 snaps instantly).
- Arguments:
idx : int
target_gain : float
time : float
- strudel_remove_track(idx: int)
Remove a track by index (shuts down its scheduler and sets the slot to null).
- Arguments:
idx : int
17.9.8. State serialization
- strudel_restore_sf2_state(data: array<uint8>)
Restore a previously serialized SoundFont from a byte array (no-op on empty data).
- Arguments:
data : array<uint8>
- strudel_restore_state(data: array<uint8>)
Restore previously saved playback state (wall time, CPS, sample bank) from a byte array.
- Arguments:
data : array<uint8>
- strudel_save_sf2_state(): array<uint8>
Serialize the currently loaded SoundFont to a byte array (empty if none loaded).
- strudel_save_state(): array<uint8>
Serialize playback state (wall time, CPS, sample bank) into a byte array; shuts down playback first.
17.9.9. Debug and diagnostics
- strudel_debug_master_peak()
Log the peak amplitude of the current master PCM buffer (debug helper, main-thread mode).
- strudel_debug_memory(enabled: bool)
Enable or disable periodic heap/string-memory logging during playback.
- Arguments:
enabled : bool
- strudel_debug_output_peak()
Log the peak amplitude of each track’s scheduler output (debug helper).
- strudel_debug_sample_peaks()
Log the peak amplitude of every loaded sample in the bank (debug helper).
- strudel_debug_voices()
Log the number of active sample/oscillator voices on each track (debug helper).
- strudel_reset_memory_baseline()
Reset memory-tracking baseline to the current heap state. Call after all one-time setup (audio stream, pattern, tracks) so only playback growth is measured.