| 
							- // Copyright 2021 Jean Pierre Cimalando
 - //
 - // Licensed under the Apache License, Version 2.0 (the "License");
 - // you may not use this file except in compliance with the License.
 - // You may obtain a copy of the License at
 - //
 - //     http://www.apache.org/licenses/LICENSE-2.0
 - //
 - // Unless required by applicable law or agreed to in writing, software
 - // distributed under the License is distributed on an "AS IS" BASIS,
 - // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 - // See the License for the specific language governing permissions and
 - // limitations under the License.
 - //
 - // SPDX-License-Identifier: Apache-2.0
 - //
 - 
 - #pragma once
 - #if !defined(YSFX_INCLUDED_YSFX_H)
 - #define YSFX_INCLUDED_YSFX_H
 - 
 - #include <stdio.h>
 - #include <stddef.h>
 - #include <stdint.h>
 - #include <stdbool.h>
 - #if defined(_WIN32)
 - #   include <wchar.h>
 - #endif
 - 
 - //------------------------------------------------------------------------------
 - 
 - #ifdef __cplusplus
 - extern "C" {
 - #endif
 - 
 - #if !defined(YSFX_API)
 - #   if defined(_WIN32) && defined(YSFX_DLL_BUILD)
 - #       define YSFX_API __declspec(dllexport)
 - #   elif defined(__GNUC__)
 - #       define YSFX_API __attribute__((visibility("default")))
 - #   else
 - #       define YSFX_API
 - #   endif
 - #endif
 - 
 - //------------------------------------------------------------------------------
 - // YSFX definitions
 - 
 - typedef double ysfx_real;
 - 
 - enum {
 -     ysfx_max_sliders = 64,
 -     ysfx_max_channels = 64,
 -     ysfx_max_midi_buses = 16,
 -     ysfx_max_triggers = 10,
 - };
 - 
 - typedef enum ysfx_log_level_e {
 -     ysfx_log_info,
 -     ysfx_log_warning,
 -     ysfx_log_error,
 - } ysfx_log_level;
 - 
 - typedef void (ysfx_log_reporter_t)(intptr_t userdata, ysfx_log_level level, const char *message);
 - 
 - //------------------------------------------------------------------------------
 - // YSFX configuration
 - 
 - typedef struct ysfx_config_s ysfx_config_t;
 - typedef struct ysfx_audio_format_s ysfx_audio_format_t;
 - 
 - // create a new configuration
 - YSFX_API ysfx_config_t *ysfx_config_new();
 - // delete a configuration
 - YSFX_API void ysfx_config_free(ysfx_config_t *config);
 - // increase the reference counter
 - YSFX_API void ysfx_config_add_ref(ysfx_config_t *config);
 - // set the path of the import root, a folder usually named "Effects"
 - YSFX_API void ysfx_set_import_root(ysfx_config_t *config, const char *root);
 - // set the path of the data root, a folder usually named "Data"
 - YSFX_API void ysfx_set_data_root(ysfx_config_t *config, const char *root);
 - // get the path of the import root, a folder usually named "Effects"
 - YSFX_API const char *ysfx_get_import_root(ysfx_config_t *config);
 - // get the path of the data root, a folder usually named "Data"
 - YSFX_API const char *ysfx_get_data_root(ysfx_config_t *config);
 - // guess the undefined root folders, based on the path to the JSFX file
 - YSFX_API void ysfx_guess_file_roots(ysfx_config_t *config, const char *sourcepath);
 - // register an audio format into the system
 - YSFX_API void ysfx_register_audio_format(ysfx_config_t *config, ysfx_audio_format_t *afmt);
 - // register the builtin audio formats (at least WAV file support)
 - YSFX_API void ysfx_register_builtin_audio_formats(ysfx_config_t *config);
 - // set the log reporting function
 - YSFX_API void ysfx_set_log_reporter(ysfx_config_t *config, ysfx_log_reporter_t *reporter);
 - // set the callback user data
 - YSFX_API void ysfx_set_user_data(ysfx_config_t *config, intptr_t userdata);
 - 
 - // get a string which textually represents the log level
 - YSFX_API const char *ysfx_log_level_string(ysfx_log_level level);
 - 
 - //------------------------------------------------------------------------------
 - // YSFX effect
 - 
 - typedef struct ysfx_s ysfx_t;
 - 
 - // create a new effect, taking a reference to config
 - YSFX_API ysfx_t *ysfx_new(ysfx_config_t *config);
 - // delete an effect
 - YSFX_API void ysfx_free(ysfx_t *fx);
 - // increase the reference counter
 - YSFX_API void ysfx_add_ref(ysfx_t *fx);
 - 
 - // get the configuration
 - YSFX_API ysfx_config_t *ysfx_get_config(ysfx_t *fx);
 - 
 - typedef enum ysfx_load_option_e {
 -     // skip imports; useful just for accessing header information and nothing else
 -     ysfx_load_ignoring_imports = 1,
 - } ysfx_load_option_t;
 - 
 - // load the source code from file without compiling
 - YSFX_API bool ysfx_load_file(ysfx_t *fx, const char *filepath, uint32_t loadopts);
 - // unload the source code and any compiled code
 - YSFX_API void ysfx_unload(ysfx_t *fx);
 - // check whether the effect is loaded
 - YSFX_API bool ysfx_is_loaded(ysfx_t *fx);
 - 
 - // get the name of the effect
 - YSFX_API const char *ysfx_get_name(ysfx_t *fx);
 - // get the path of the file which is loaded
 - YSFX_API const char *ysfx_get_file_path(ysfx_t *fx);
 - // get the author of the effect
 - YSFX_API const char *ysfx_get_author(ysfx_t *fx);
 - // get the number of tags of the effect
 - #define ysfx_get_num_tags(fx) ysfx_get_tags((fx), NULL, 0)
 - // get the list of tags of the effect
 - YSFX_API uint32_t ysfx_get_tags(ysfx_t *fx, const char **dest, uint32_t destsize);
 - // get a single tag of the effect
 - YSFX_API const char *ysfx_get_tag(ysfx_t *fx, uint32_t index);
 - // get the number of inputs
 - YSFX_API uint32_t ysfx_get_num_inputs(ysfx_t *fx);
 - // get the number of outputs
 - YSFX_API uint32_t ysfx_get_num_outputs(ysfx_t *fx);
 - // get the name of the input
 - YSFX_API const char *ysfx_get_input_name(ysfx_t *fx, uint32_t index);
 - // get the name of the output
 - YSFX_API const char *ysfx_get_output_name(ysfx_t *fx, uint32_t index);
 - // get whether this effect wants metering
 - YSFX_API bool ysfx_wants_meters(ysfx_t *fx);
 - // get requested dimensions of the graphics area; 0 means host should decide
 - YSFX_API bool ysfx_get_gfx_dim(ysfx_t *fx, uint32_t dim[2]);
 - 
 - typedef enum ysfx_section_type_e {
 -     ysfx_section_init = 1,
 -     ysfx_section_slider = 2,
 -     ysfx_section_block = 3,
 -     ysfx_section_sample = 4,
 -     ysfx_section_gfx = 5,
 -     ysfx_section_serialize = 6,
 - } ysfx_section_type_t;
 - 
 - // get whether the source has the given section
 - YSFX_API bool ysfx_has_section(ysfx_t *fx, uint32_t type);
 - 
 - typedef struct ysfx_slider_range_s {
 -     ysfx_real def;
 -     ysfx_real min;
 -     ysfx_real max;
 -     ysfx_real inc;
 - } ysfx_slider_range_t;
 - 
 - // determine if slider exists; call from 0 to max-1 to scan available ones
 - YSFX_API bool ysfx_slider_exists(ysfx_t *fx, uint32_t index);
 - // get the name of a slider
 - YSFX_API const char *ysfx_slider_get_name(ysfx_t *fx, uint32_t index);
 - // get the range of a slider
 - YSFX_API bool ysfx_slider_get_range(ysfx_t *fx, uint32_t index, ysfx_slider_range_t *range);
 - // get whether the slider is an enumeration
 - YSFX_API bool ysfx_slider_is_enum(ysfx_t *fx, uint32_t index);
 - // get the number of labels for the enumeration slider
 - #define ysfx_slider_get_enum_size(fx, index) ysfx_slider_get_enum_names((fx), (index), NULL, 0)
 - // get the list of labels for the enumeration slider
 - YSFX_API uint32_t ysfx_slider_get_enum_names(ysfx_t *fx, uint32_t index, const char **dest, uint32_t destsize);
 - // get a single label for the enumeration slider
 - YSFX_API const char *ysfx_slider_get_enum_name(ysfx_t *fx, uint32_t slider_index, uint32_t enum_index);
 - // get whether the slider is a path (implies enumeration)
 - YSFX_API bool ysfx_slider_is_path(ysfx_t *fx, uint32_t index);
 - // get whether the slider is initially visible
 - YSFX_API bool ysfx_slider_is_initially_visible(ysfx_t *fx, uint32_t index);
 - 
 - // get the value of the slider
 - YSFX_API ysfx_real ysfx_slider_get_value(ysfx_t *fx, uint32_t index);
 - // set the value of the slider, and call @slider later if value has changed
 - YSFX_API void ysfx_slider_set_value(ysfx_t *fx, uint32_t index, ysfx_real value);
 - 
 - typedef enum ysfx_compile_option_e {
 -     // skip compiling the @serialize section
 -     ysfx_compile_no_serialize = 1 << 0,
 -     // skip compiling the @gfx section
 -     ysfx_compile_no_gfx = 1 << 1,
 - } ysfx_compile_option_t;
 - 
 - // compile the previously loaded source
 - YSFX_API bool ysfx_compile(ysfx_t *fx, uint32_t compileopts);
 - // check whether the effect is compiled
 - YSFX_API bool ysfx_is_compiled(ysfx_t *fx);
 - 
 - // get the block size
 - YSFX_API uint32_t ysfx_get_block_size(ysfx_t *fx);
 - // get the sample rate
 - YSFX_API ysfx_real ysfx_get_sample_rate(ysfx_t *fx);
 - // update the block size; don't forget to call @init
 - YSFX_API void ysfx_set_block_size(ysfx_t *fx, uint32_t blocksize);
 - // update the sample rate; don't forget to call @init
 - YSFX_API void ysfx_set_sample_rate(ysfx_t *fx, ysfx_real samplerate);
 - 
 - // set the capacity of the MIDI buffer
 - YSFX_API void ysfx_set_midi_capacity(ysfx_t *fx, uint32_t capacity, bool extensible);
 - 
 - // activate and invoke @init
 - YSFX_API void ysfx_init(ysfx_t *fx);
 - 
 - // get the output latency
 - YSFX_API ysfx_real ysfx_get_pdc_delay(ysfx_t *fx);
 - // get the range of channels where output latency applies (end not included)
 - YSFX_API void ysfx_get_pdc_channels(ysfx_t *fx, uint32_t channels[2]);
 - // get whether the output latency applies to MIDI as well
 - YSFX_API bool ysfx_get_pdc_midi(ysfx_t *fx);
 - 
 - typedef enum ysfx_playback_state_e {
 -     ysfx_playback_error = 0,
 -     ysfx_playback_playing = 1,
 -     ysfx_playback_paused = 2,
 -     ysfx_playback_recording = 5,
 -     ysfx_playback_recording_paused = 6,
 - } ysfx_playback_state_t;
 - 
 - typedef struct ysfx_time_info_s {
 -     // tempo in beats/minute
 -     ysfx_real tempo;
 -     // state of the playback (ysfx_playback_state_t)
 -     uint32_t playback_state;
 -     // time position in seconds
 -     ysfx_real time_position;
 -     // time position in beats
 -     ysfx_real beat_position;
 -     // time signature in fraction form
 -     uint32_t time_signature[2];
 - } ysfx_time_info_t;
 - 
 - // update time information; do this before processing the cycle
 - YSFX_API void ysfx_set_time_info(ysfx_t *fx, const ysfx_time_info_t *info);
 - 
 - typedef struct ysfx_midi_event_s {
 -     // the bus number
 -     uint32_t bus;
 -     // the frame when it happens within the cycle
 -     uint32_t offset;
 -     // the size of the message
 -     uint32_t size;
 -     // the contents of the message
 -     const uint8_t *data;
 - } ysfx_midi_event_t;
 - 
 - // send MIDI, it will be processed during the cycle
 - YSFX_API bool ysfx_send_midi(ysfx_t *fx, const ysfx_midi_event_t *event);
 - // receive MIDI, after having processed the cycle
 - YSFX_API bool ysfx_receive_midi(ysfx_t *fx, ysfx_midi_event_t *event);
 - // receive MIDI from a single bus (do not mix with API above, use either)
 - YSFX_API bool ysfx_receive_midi_from_bus(ysfx_t *fx, uint32_t bus, ysfx_midi_event_t *event);
 - 
 - // send a trigger, it will be processed during the cycle
 - YSFX_API bool ysfx_send_trigger(ysfx_t *fx, uint32_t index);
 - 
 - // get a bit mask of sliders whose values must be redisplayed, and clear it to zero
 - YSFX_API uint64_t ysfx_fetch_slider_changes(ysfx_t *fx);
 - // get a bit mask of sliders whose values must be automated, and clear it to zero
 - YSFX_API uint64_t ysfx_fetch_slider_automations(ysfx_t *fx);
 - // get a bit mask of sliders currently visible
 - YSFX_API uint64_t ysfx_get_slider_visibility(ysfx_t *fx);
 - 
 - // process a cycle in 32-bit float
 - YSFX_API void ysfx_process_float(ysfx_t *fx, const float *const *ins, float *const *outs, uint32_t num_ins, uint32_t num_outs, uint32_t num_frames);
 - // process a cycle in 64-bit float
 - YSFX_API void ysfx_process_double(ysfx_t *fx, const double *const *ins, double *const *outs, uint32_t num_ins, uint32_t num_outs, uint32_t num_frames);
 - 
 - typedef struct ysfx_state_slider_s {
 -     // index of the slider
 -     uint32_t index;
 -     // value of the slider
 -     ysfx_real value;
 - } ysfx_state_slider_t;
 - 
 - typedef struct ysfx_state_s {
 -     // values of the sliders
 -     ysfx_state_slider_t *sliders;
 -     // number of sliders
 -     uint32_t slider_count;
 -     // serialized data
 -     uint8_t *data;
 -     // size of serialized data
 -     size_t data_size;
 - } ysfx_state_t;
 - 
 - // load state
 - YSFX_API bool ysfx_load_state(ysfx_t *fx, ysfx_state_t *state);
 - // save current state; release this object when done
 - YSFX_API ysfx_state_t *ysfx_save_state(ysfx_t *fx);
 - // release a saved state object
 - YSFX_API void ysfx_state_free(ysfx_state_t *state);
 - // duplicate a state object
 - YSFX_API ysfx_state_t *ysfx_state_dup(ysfx_state_t *state);
 - 
 - typedef struct ysfx_preset_s {
 -     // name of the preset
 -     char *name;
 -     // state of the preset
 -     ysfx_state_t *state;
 - } ysfx_preset_t;
 - 
 - typedef struct ysfx_bank_s {
 -     // name of the bank
 -     char *name;
 -     // list of presets
 -     ysfx_preset_t *presets;
 -     // number of programs
 -     uint32_t preset_count;
 - } ysfx_bank_t;
 - 
 - // get the path of the RPL preset bank of the loaded JSFX, if present
 - YSFX_API const char *ysfx_get_bank_path(ysfx_t *fx);
 - // read a preset bank from RPL file
 - YSFX_API ysfx_bank_t *ysfx_load_bank(const char *path);
 - // free a preset bank
 - YSFX_API void ysfx_bank_free(ysfx_bank_t *bank);
 - 
 - // type of a function which can enumerate VM variables; returning 0 ends the search
 - typedef int (ysfx_enum_vars_callback_t)(const char *name, ysfx_real *var, void *userdata);
 - // enumerate all variables currently in the VM
 - YSFX_API void ysfx_enum_vars(ysfx_t *fx, ysfx_enum_vars_callback_t *callback, void *userdata);
 - // find a single variable in the VM
 - YSFX_API ysfx_real *ysfx_find_var(ysfx_t *fx, const char *name);
 - // read a chunk of virtual memory from the VM
 - YSFX_API void ysfx_read_vmem(ysfx_t *fx, uint32_t addr, ysfx_real *dest, uint32_t count);
 - 
 - //------------------------------------------------------------------------------
 - // YSFX graphics
 - 
 - // NOTE: all `ysfx_gfx_*` functions must be invoked from a dedicated UI thread
 - 
 - typedef struct ysfx_gfx_config_s {
 -     // opaque user data passed to callbacks
 -     void *user_data;
 -     // the width of the frame buffer (having the scale factor applied)
 -     uint32_t pixel_width;
 -     // the height of the frame buffer (having the scale factor applied)
 -     uint32_t pixel_height;
 -     // the distance in bytes between lines; if 0, it defaults to (4*width)
 -     // currently it is required to be a multiple of 4
 -     uint32_t pixel_stride;
 -     // the pixel data of the frame buffer, of size (stride*height) bytes
 -     // the byte order in little-endian is 'BGRA', big-endian is 'ARGB'
 -     uint8_t *pixels;
 -     // the scale factor of the display; 1.0 or greater, 2.0 for Retina display
 -     ysfx_real scale_factor;
 -     // show a menu and run it synchronously; returns an item ID >= 1, or 0 if none
 -     int32_t (*show_menu)(void *user_data, const char *menu_spec, int32_t xpos, int32_t ypos);
 -     // change the cursor
 -     void (*set_cursor)(void *user_data, int32_t cursor);
 -     // if index is not -1, get the dropped file at this index (otherwise null)
 -     // if index is -1, clear the list of dropped files, and return null
 -     const char *(*get_drop_file)(void *user_data, int32_t index);
 - } ysfx_gfx_config_t;
 - 
 - // set up the graphics rendering
 - YSFX_API void ysfx_gfx_setup(ysfx_t *fx, ysfx_gfx_config_t *gc);
 - // get whether the current effect is requesting Retina support
 - YSFX_API bool ysfx_gfx_wants_retina(ysfx_t *fx);
 - // push a key to the input queue
 - YSFX_API void ysfx_gfx_add_key(ysfx_t *fx, uint32_t mods, uint32_t key, bool press);
 - // update mouse information; position is relative to canvas; wheel should be in steps normalized to ±1.0
 - YSFX_API void ysfx_gfx_update_mouse(ysfx_t *fx, uint32_t mods, int32_t xpos, int32_t ypos, uint32_t buttons, ysfx_real wheel, ysfx_real hwheel);
 - // invoke @gfx to paint the graphics; returns whether the framer buffer is modified
 - YSFX_API bool ysfx_gfx_run(ysfx_t *fx);
 - 
 - //------------------------------------------------------------------------------
 - // YSFX key map
 - 
 - // these key definitions match those of pugl
 - 
 - enum {
 -     ysfx_mod_shift = 1 << 0,
 -     ysfx_mod_ctrl = 1 << 1,
 -     ysfx_mod_alt = 1 << 2,
 -     ysfx_mod_super = 1 << 3,
 - };
 - 
 - enum {
 -     ysfx_key_backspace = 0x08,
 -     ysfx_key_escape = 0x1b,
 -     ysfx_key_delete = 0x7f,
 - 
 -     ysfx_key_f1 = 0xe000,
 -     ysfx_key_f2,
 -     ysfx_key_f3,
 -     ysfx_key_f4,
 -     ysfx_key_f5,
 -     ysfx_key_f6,
 -     ysfx_key_f7,
 -     ysfx_key_f8,
 -     ysfx_key_f9,
 -     ysfx_key_f10,
 -     ysfx_key_f11,
 -     ysfx_key_f12,
 -     ysfx_key_left,
 -     ysfx_key_up,
 -     ysfx_key_right,
 -     ysfx_key_down,
 -     ysfx_key_page_up,
 -     ysfx_key_page_down,
 -     ysfx_key_home,
 -     ysfx_key_end,
 -     ysfx_key_insert,
 - };
 - 
 - enum {
 -     ysfx_button_left = 1 << 0,
 -     ysfx_button_middle = 1 << 1,
 -     ysfx_button_right = 1 << 2,
 - };
 - 
 - //------------------------------------------------------------------------------
 - // YSFX menu
 - 
 - typedef struct ysfx_menu_insn_s ysfx_menu_insn_t;
 - 
 - typedef struct ysfx_menu_s {
 -     // list of instructions to build a menu
 -     ysfx_menu_insn_t *insns;
 -     // number of menu instructions
 -     uint32_t insn_count;
 - } ysfx_menu_t;
 - 
 - typedef enum ysfx_menu_opcode_e {
 -     // appends an item
 -     ysfx_menu_item,
 -     // appends a separator
 -     ysfx_menu_separator,
 -     // appends a submenu and enters
 -     ysfx_menu_sub,
 -     // terminates a submenu and leaves
 -     ysfx_menu_endsub,
 - } ysfx_menu_opcode_t;
 - 
 - typedef enum ysfx_menu_item_flag_e {
 -     // whether the item is disabled (grayed out)
 -     ysfx_menu_item_disabled = 1 << 0,
 -     // whether the item is checked
 -     ysfx_menu_item_checked = 1 << 1,
 - } ysfx_menu_item_flag_t;
 - 
 - typedef struct ysfx_menu_insn_s {
 -     // operation code of this instruction
 -     ysfx_menu_opcode_t opcode;
 -     // unique identifier, greater than 0 (opcodes: item)
 -     uint32_t id;
 -     // name (opcodes: item, sub/endsub)
 -     const char *name;
 -     // combination of item flags (opcodes: item, sub/endsub)
 -     uint32_t item_flags;
 - } ysfx_menu_insn_t;
 - 
 - // parse a string which describes a popup menu (cf. `gfx_showmenu`)
 - YSFX_API ysfx_menu_t *ysfx_parse_menu(const char *text);
 - // free a menu
 - YSFX_API void ysfx_menu_free(ysfx_menu_t *menu);
 - 
 - //------------------------------------------------------------------------------
 - // YSFX audio formats
 - 
 - typedef struct ysfx_audio_reader_s ysfx_audio_reader_t;
 - 
 - typedef struct ysfx_audio_file_info_s {
 -     uint32_t channels;
 -     ysfx_real sample_rate;
 - } ysfx_audio_file_info_t;
 - 
 - typedef struct ysfx_audio_format_s {
 -     // quickly checks if this format would be able to handle the given file
 -     bool (*can_handle)(const char *path);
 -     // open an audio file of this format for reading
 -     ysfx_audio_reader_t *(*open)(const char *path);
 -     // close the audio file
 -     void (*close)(ysfx_audio_reader_t *reader);
 -     // get the sample rate and the channel count
 -     ysfx_audio_file_info_t (*info)(ysfx_audio_reader_t *reader);
 -     // get the number of samples left to read
 -     uint64_t (*avail)(ysfx_audio_reader_t *reader);
 -     // move the read pointer back to the beginning
 -     void (*rewind)(ysfx_audio_reader_t *reader);
 -     // read the next block of samples
 -     uint64_t (*read)(ysfx_audio_reader_t *reader, ysfx_real *samples, uint64_t count);
 - } ysfx_audio_format_t;
 - 
 - //------------------------------------------------------------------------------
 - 
 - #ifdef __cplusplus
 - } // extern "C"
 - #endif
 - 
 - //------------------------------------------------------------------------------
 - // YSFX RAII helpers
 - 
 - #if defined(__cplusplus) && (__cplusplus >= 201103L || (defined(_MSC_VER) && _MSVC_LANG >= 201103L))
 - #include <memory>
 - 
 - #define YSFX_DEFINE_AUTO_PTR(aptr, styp, freefn)                \
 -     struct aptr##_deleter {                                     \
 -         void operator()(styp *x) const noexcept { freefn(x); }  \
 -     };                                                          \
 -     using aptr = std::unique_ptr<styp, aptr##_deleter>
 - 
 - YSFX_DEFINE_AUTO_PTR(ysfx_config_u, ysfx_config_t, ysfx_config_free);
 - YSFX_DEFINE_AUTO_PTR(ysfx_u, ysfx_t, ysfx_free);
 - YSFX_DEFINE_AUTO_PTR(ysfx_state_u, ysfx_state_t, ysfx_state_free);
 - YSFX_DEFINE_AUTO_PTR(ysfx_bank_u, ysfx_bank_t, ysfx_bank_free);
 - YSFX_DEFINE_AUTO_PTR(ysfx_menu_u, ysfx_menu_t, ysfx_menu_free);
 - #endif // defined(__cplusplus) && (__cplusplus >= 201103L || (defined(_MSC_VER) && _MSVC_LANG >= 201103L))
 - 
 - //------------------------------------------------------------------------------
 - 
 - #endif // !defined(YSFX_INCLUDED_YSFX_H)
 
 
  |