.. _stdlib_strudel_player: =============================================================== Top-level playback harness: tracks, BPM/CPS, and threaded audio =============================================================== .. das:module:: strudel_player Module strudel_player ++++++++++ Structures ++++++++++ .. _struct-strudel_player-AudioChunk: .. das:attribute:: AudioChunk :Fields: * **samples** : array - Interleaved stereo PCM samples for one chunk. +++++++++ Lifecycle +++++++++ * :ref:`strudel_create_channel () ` * :ref:`strudel_init (fn: function\<():void\>; cmd_fn: function\<(cmd:string):void\> = @@strudel_noop_cmd) ` * :ref:`strudel_shutdown () ` .. _function-strudel_player_strudel_create_channel: .. das:function:: strudel_create_channel() Create the PCM stream for main-thread playback. Call once after audio_system_create() and before strudel_tick. .. _function-strudel_player_strudel_init_function_ls__c_void_gr__function_ls_cmd_c_string_c_void_gr_: .. das:function:: 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 * **cmd_fn** : function<(cmd:string):void> .. _function-strudel_player_strudel_shutdown: .. das:function:: 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. ++++++++++++++++ Playback control ++++++++++++++++ * :ref:`strudel_command (cmd: string) ` * :ref:`strudel_noop_cmd (cmd: string) ` * :ref:`strudel_play (cmd_fn: function\<(cmd:string):void\> = @@strudel_noop_cmd) ` * :ref:`strudel_set_pause (paused: bool) ` * :ref:`strudel_tick () ` * :ref:`strudel_tick_offline () ` .. _function-strudel_player_strudel_command_string: .. das:function:: 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 .. _function-strudel_player_strudel_noop_cmd_string: .. das:function:: strudel_noop_cmd(cmd: string) No-op command handler — default argument when no user command dispatcher is needed. :Arguments: * **cmd** : string .. _function-strudel_player_strudel_play_function_ls_cmd_c_string_c_void_gr_: .. das:function:: 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> .. _function-strudel_player_strudel_set_pause_bool: .. das:function:: strudel_set_pause(paused: bool) Pause or resume audio output. :Arguments: * **paused** : bool .. _function-strudel_player_strudel_tick: .. das:function:: 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. .. _function-strudel_player_strudel_tick_offline: .. das:function:: 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. ++++++++++++++++ Tempo and timing ++++++++++++++++ * :ref:`strudel_get_playback_time () : tuple\ ` * :ref:`strudel_set_bpm (bpm: double) ` * :ref:`strudel_set_cps (cps: double) ` * :ref:`strudel_set_look_ahead (look_ahead: float) ` .. _function-strudel_player_strudel_get_playback_time: .. das:function:: strudel_get_playback_time() : tuple 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. .. _function-strudel_player_strudel_set_bpm_double: .. das:function:: 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 .. _function-strudel_player_strudel_set_cps_double: .. das:function:: strudel_set_cps(cps: double) Set tempo directly in cycles per second. Safe to call from the main thread. :Arguments: * **cps** : double .. _function-strudel_player_strudel_set_look_ahead_float: .. das:function:: strudel_set_look_ahead(look_ahead: float) Set how far ahead (in seconds) to query the pattern for upcoming events. :Arguments: * **look_ahead** : float ++++++ Volume ++++++ * :ref:`strudel_set_volume (volume: float; time: float = 0f) ` .. _function-strudel_player_strudel_set_volume_float_float: .. das:function:: 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 +++++++++++++ Asset loading +++++++++++++ * :ref:`strudel_get_sf2_path () : string ` * :ref:`strudel_has_sf2 () : bool ` * :ref:`strudel_load_sample_dir (root: string) ` * :ref:`strudel_load_sf2 (path: string) : bool ` * :ref:`strudel_load_sound (path: string; name: string) ` .. _function-strudel_player_strudel_get_sf2_path: .. das:function:: strudel_get_sf2_path() : string Return the path of the currently loaded SoundFont (empty string if none). .. _function-strudel_player_strudel_has_sf2: .. das:function:: strudel_has_sf2() : bool Return true if a SoundFont has been loaded. .. _function-strudel_player_strudel_load_sample_dir_string: .. das:function:: strudel_load_sample_dir(root: string) Load every audio file under root as a named sample (filename becomes the sound name). :Arguments: * **root** : string .. _function-strudel_player_strudel_load_sf2_string: .. das:function:: strudel_load_sf2(path: string) : bool Load a SoundFont (.sf2) file for SF2-based synthesis. Returns true on success. :Arguments: * **path** : string .. _function-strudel_player_strudel_load_sound_string_string: .. das:function:: 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 ++++++++++++++++ Track management ++++++++++++++++ * :ref:`strudel_add_track (var pat: Pattern; gain: float = 1f) : int ` * :ref:`strudel_fade_track (idx: int; target_gain: float; time: float) ` * :ref:`strudel_remove_track (idx: int) ` .. _function-strudel_player_strudel_add_track_Pattern_float: .. das:function:: 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** : :ref:`Pattern ` * **gain** : float .. _function-strudel_player_strudel_fade_track_int_float_float: .. das:function:: 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 .. _function-strudel_player_strudel_remove_track_int: .. das:function:: strudel_remove_track(idx: int) Remove a track by index (shuts down its scheduler and sets the slot to null). :Arguments: * **idx** : int +++++++++++++++++++ State serialization +++++++++++++++++++ * :ref:`strudel_restore_sf2_state (data: array\) ` * :ref:`strudel_restore_state (data: array\) ` * :ref:`strudel_save_sf2_state () : array\ ` * :ref:`strudel_save_state () : array\ ` .. _function-strudel_player_strudel_restore_sf2_state_array_ls_uint8_gr_: .. das:function:: strudel_restore_sf2_state(data: array) Restore a previously serialized SoundFont from a byte array (no-op on empty data). :Arguments: * **data** : array .. _function-strudel_player_strudel_restore_state_array_ls_uint8_gr_: .. das:function:: strudel_restore_state(data: array) Restore previously saved playback state (wall time, CPS, sample bank) from a byte array. :Arguments: * **data** : array .. _function-strudel_player_strudel_save_sf2_state: .. das:function:: strudel_save_sf2_state() : array Serialize the currently loaded SoundFont to a byte array (empty if none loaded). .. _function-strudel_player_strudel_save_state: .. das:function:: strudel_save_state() : array Serialize playback state (wall time, CPS, sample bank) into a byte array; shuts down playback first. +++++++++++++++++++++ Debug and diagnostics +++++++++++++++++++++ * :ref:`strudel_debug_master_peak () ` * :ref:`strudel_debug_memory (enabled: bool) ` * :ref:`strudel_debug_output_peak () ` * :ref:`strudel_debug_sample_peaks () ` * :ref:`strudel_debug_voices () ` * :ref:`strudel_reset_memory_baseline () ` .. _function-strudel_player_strudel_debug_master_peak: .. das:function:: strudel_debug_master_peak() Log the peak amplitude of the current master PCM buffer (debug helper, main-thread mode). .. _function-strudel_player_strudel_debug_memory_bool: .. das:function:: strudel_debug_memory(enabled: bool) Enable or disable periodic heap/string-memory logging during playback. :Arguments: * **enabled** : bool .. _function-strudel_player_strudel_debug_output_peak: .. das:function:: strudel_debug_output_peak() Log the peak amplitude of each track's scheduler output (debug helper). .. _function-strudel_player_strudel_debug_sample_peaks: .. das:function:: strudel_debug_sample_peaks() Log the peak amplitude of every loaded sample in the bank (debug helper). .. _function-strudel_player_strudel_debug_voices: .. das:function:: strudel_debug_voices() Log the number of active sample/oscillator voices on each track (debug helper). .. _function-strudel_player_strudel_reset_memory_baseline: .. das:function:: 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.