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:
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.