Add initial bits for Qt6 support
[carla.git] / source / modules / ysfx / include / ysfx.h
blobd6fdce73f96cd85655666a371b09acc948acaef4
1 // Copyright 2021 Jean Pierre Cimalando
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 // SPDX-License-Identifier: Apache-2.0
18 #pragma once
19 #if !defined(YSFX_INCLUDED_YSFX_H)
20 #define YSFX_INCLUDED_YSFX_H
22 #include <stdio.h>
23 #include <stddef.h>
24 #include <stdint.h>
25 #include <stdbool.h>
26 #if defined(_WIN32)
27 # include <wchar.h>
28 #endif
30 //------------------------------------------------------------------------------
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
36 #if !defined(YSFX_API)
37 # if defined(_WIN32) && defined(YSFX_DLL_BUILD)
38 # define YSFX_API __declspec(dllexport)
39 # elif defined(__GNUC__)
40 # define YSFX_API __attribute__((visibility("default")))
41 # else
42 # define YSFX_API
43 # endif
44 #endif
46 //------------------------------------------------------------------------------
47 // YSFX definitions
49 typedef double ysfx_real;
51 enum {
52 ysfx_max_sliders = 64,
53 ysfx_max_channels = 64,
54 ysfx_max_midi_buses = 16,
55 ysfx_max_triggers = 10,
58 typedef enum ysfx_log_level_e {
59 ysfx_log_info,
60 ysfx_log_warning,
61 ysfx_log_error,
62 } ysfx_log_level;
64 typedef void (ysfx_log_reporter_t)(intptr_t userdata, ysfx_log_level level, const char *message);
66 //------------------------------------------------------------------------------
67 // YSFX configuration
69 typedef struct ysfx_config_s ysfx_config_t;
70 typedef struct ysfx_audio_format_s ysfx_audio_format_t;
72 // create a new configuration
73 YSFX_API ysfx_config_t *ysfx_config_new();
74 // delete a configuration
75 YSFX_API void ysfx_config_free(ysfx_config_t *config);
76 // increase the reference counter
77 YSFX_API void ysfx_config_add_ref(ysfx_config_t *config);
78 // set the path of the import root, a folder usually named "Effects"
79 YSFX_API void ysfx_set_import_root(ysfx_config_t *config, const char *root);
80 // set the path of the data root, a folder usually named "Data"
81 YSFX_API void ysfx_set_data_root(ysfx_config_t *config, const char *root);
82 // get the path of the import root, a folder usually named "Effects"
83 YSFX_API const char *ysfx_get_import_root(ysfx_config_t *config);
84 // get the path of the data root, a folder usually named "Data"
85 YSFX_API const char *ysfx_get_data_root(ysfx_config_t *config);
86 // guess the undefined root folders, based on the path to the JSFX file
87 YSFX_API void ysfx_guess_file_roots(ysfx_config_t *config, const char *sourcepath);
88 // register an audio format into the system
89 YSFX_API void ysfx_register_audio_format(ysfx_config_t *config, ysfx_audio_format_t *afmt);
90 // register the builtin audio formats (at least WAV file support)
91 YSFX_API void ysfx_register_builtin_audio_formats(ysfx_config_t *config);
92 // set the log reporting function
93 YSFX_API void ysfx_set_log_reporter(ysfx_config_t *config, ysfx_log_reporter_t *reporter);
94 // set the callback user data
95 YSFX_API void ysfx_set_user_data(ysfx_config_t *config, intptr_t userdata);
97 // get a string which textually represents the log level
98 YSFX_API const char *ysfx_log_level_string(ysfx_log_level level);
100 //------------------------------------------------------------------------------
101 // YSFX effect
103 typedef struct ysfx_s ysfx_t;
105 // create a new effect, taking a reference to config
106 YSFX_API ysfx_t *ysfx_new(ysfx_config_t *config);
107 // delete an effect
108 YSFX_API void ysfx_free(ysfx_t *fx);
109 // increase the reference counter
110 YSFX_API void ysfx_add_ref(ysfx_t *fx);
112 // get the configuration
113 YSFX_API ysfx_config_t *ysfx_get_config(ysfx_t *fx);
115 typedef enum ysfx_load_option_e {
116 // skip imports; useful just for accessing header information and nothing else
117 ysfx_load_ignoring_imports = 1,
118 } ysfx_load_option_t;
120 // load the source code from file without compiling
121 YSFX_API bool ysfx_load_file(ysfx_t *fx, const char *filepath, uint32_t loadopts);
122 // unload the source code and any compiled code
123 YSFX_API void ysfx_unload(ysfx_t *fx);
124 // check whether the effect is loaded
125 YSFX_API bool ysfx_is_loaded(ysfx_t *fx);
127 // get the name of the effect
128 YSFX_API const char *ysfx_get_name(ysfx_t *fx);
129 // get the path of the file which is loaded
130 YSFX_API const char *ysfx_get_file_path(ysfx_t *fx);
131 // get the author of the effect
132 YSFX_API const char *ysfx_get_author(ysfx_t *fx);
133 // get the number of tags of the effect
134 #define ysfx_get_num_tags(fx) ysfx_get_tags((fx), NULL, 0)
135 // get the list of tags of the effect
136 YSFX_API uint32_t ysfx_get_tags(ysfx_t *fx, const char **dest, uint32_t destsize);
137 // get a single tag of the effect
138 YSFX_API const char *ysfx_get_tag(ysfx_t *fx, uint32_t index);
139 // get the number of inputs
140 YSFX_API uint32_t ysfx_get_num_inputs(ysfx_t *fx);
141 // get the number of outputs
142 YSFX_API uint32_t ysfx_get_num_outputs(ysfx_t *fx);
143 // get the name of the input
144 YSFX_API const char *ysfx_get_input_name(ysfx_t *fx, uint32_t index);
145 // get the name of the output
146 YSFX_API const char *ysfx_get_output_name(ysfx_t *fx, uint32_t index);
147 // get whether this effect wants metering
148 YSFX_API bool ysfx_wants_meters(ysfx_t *fx);
149 // get requested dimensions of the graphics area; 0 means host should decide
150 YSFX_API bool ysfx_get_gfx_dim(ysfx_t *fx, uint32_t dim[2]);
152 typedef enum ysfx_section_type_e {
153 ysfx_section_init = 1,
154 ysfx_section_slider = 2,
155 ysfx_section_block = 3,
156 ysfx_section_sample = 4,
157 ysfx_section_gfx = 5,
158 ysfx_section_serialize = 6,
159 } ysfx_section_type_t;
161 // get whether the source has the given section
162 YSFX_API bool ysfx_has_section(ysfx_t *fx, uint32_t type);
164 typedef struct ysfx_slider_range_s {
165 ysfx_real def;
166 ysfx_real min;
167 ysfx_real max;
168 ysfx_real inc;
169 } ysfx_slider_range_t;
171 // determine if slider exists; call from 0 to max-1 to scan available ones
172 YSFX_API bool ysfx_slider_exists(ysfx_t *fx, uint32_t index);
173 // get the name of a slider
174 YSFX_API const char *ysfx_slider_get_name(ysfx_t *fx, uint32_t index);
175 // get the range of a slider
176 YSFX_API bool ysfx_slider_get_range(ysfx_t *fx, uint32_t index, ysfx_slider_range_t *range);
177 // get whether the slider is an enumeration
178 YSFX_API bool ysfx_slider_is_enum(ysfx_t *fx, uint32_t index);
179 // get the number of labels for the enumeration slider
180 #define ysfx_slider_get_enum_size(fx, index) ysfx_slider_get_enum_names((fx), (index), NULL, 0)
181 // get the list of labels for the enumeration slider
182 YSFX_API uint32_t ysfx_slider_get_enum_names(ysfx_t *fx, uint32_t index, const char **dest, uint32_t destsize);
183 // get a single label for the enumeration slider
184 YSFX_API const char *ysfx_slider_get_enum_name(ysfx_t *fx, uint32_t slider_index, uint32_t enum_index);
185 // get whether the slider is a path (implies enumeration)
186 YSFX_API bool ysfx_slider_is_path(ysfx_t *fx, uint32_t index);
187 // get whether the slider is initially visible
188 YSFX_API bool ysfx_slider_is_initially_visible(ysfx_t *fx, uint32_t index);
190 // get the value of the slider
191 YSFX_API ysfx_real ysfx_slider_get_value(ysfx_t *fx, uint32_t index);
192 // set the value of the slider, and call @slider later if value has changed
193 YSFX_API void ysfx_slider_set_value(ysfx_t *fx, uint32_t index, ysfx_real value);
195 typedef enum ysfx_compile_option_e {
196 // skip compiling the @serialize section
197 ysfx_compile_no_serialize = 1 << 0,
198 // skip compiling the @gfx section
199 ysfx_compile_no_gfx = 1 << 1,
200 } ysfx_compile_option_t;
202 // compile the previously loaded source
203 YSFX_API bool ysfx_compile(ysfx_t *fx, uint32_t compileopts);
204 // check whether the effect is compiled
205 YSFX_API bool ysfx_is_compiled(ysfx_t *fx);
207 // get the block size
208 YSFX_API uint32_t ysfx_get_block_size(ysfx_t *fx);
209 // get the sample rate
210 YSFX_API ysfx_real ysfx_get_sample_rate(ysfx_t *fx);
211 // update the block size; don't forget to call @init
212 YSFX_API void ysfx_set_block_size(ysfx_t *fx, uint32_t blocksize);
213 // update the sample rate; don't forget to call @init
214 YSFX_API void ysfx_set_sample_rate(ysfx_t *fx, ysfx_real samplerate);
216 // set the capacity of the MIDI buffer
217 YSFX_API void ysfx_set_midi_capacity(ysfx_t *fx, uint32_t capacity, bool extensible);
219 // activate and invoke @init
220 YSFX_API void ysfx_init(ysfx_t *fx);
222 // get the output latency
223 YSFX_API ysfx_real ysfx_get_pdc_delay(ysfx_t *fx);
224 // get the range of channels where output latency applies (end not included)
225 YSFX_API void ysfx_get_pdc_channels(ysfx_t *fx, uint32_t channels[2]);
226 // get whether the output latency applies to MIDI as well
227 YSFX_API bool ysfx_get_pdc_midi(ysfx_t *fx);
229 typedef enum ysfx_playback_state_e {
230 ysfx_playback_error = 0,
231 ysfx_playback_playing = 1,
232 ysfx_playback_paused = 2,
233 ysfx_playback_recording = 5,
234 ysfx_playback_recording_paused = 6,
235 } ysfx_playback_state_t;
237 typedef struct ysfx_time_info_s {
238 // tempo in beats/minute
239 ysfx_real tempo;
240 // state of the playback (ysfx_playback_state_t)
241 uint32_t playback_state;
242 // time position in seconds
243 ysfx_real time_position;
244 // time position in beats
245 ysfx_real beat_position;
246 // time signature in fraction form
247 uint32_t time_signature[2];
248 } ysfx_time_info_t;
250 // update time information; do this before processing the cycle
251 YSFX_API void ysfx_set_time_info(ysfx_t *fx, const ysfx_time_info_t *info);
253 typedef struct ysfx_midi_event_s {
254 // the bus number
255 uint32_t bus;
256 // the frame when it happens within the cycle
257 uint32_t offset;
258 // the size of the message
259 uint32_t size;
260 // the contents of the message
261 const uint8_t *data;
262 } ysfx_midi_event_t;
264 // send MIDI, it will be processed during the cycle
265 YSFX_API bool ysfx_send_midi(ysfx_t *fx, const ysfx_midi_event_t *event);
266 // receive MIDI, after having processed the cycle
267 YSFX_API bool ysfx_receive_midi(ysfx_t *fx, ysfx_midi_event_t *event);
268 // receive MIDI from a single bus (do not mix with API above, use either)
269 YSFX_API bool ysfx_receive_midi_from_bus(ysfx_t *fx, uint32_t bus, ysfx_midi_event_t *event);
271 // send a trigger, it will be processed during the cycle
272 YSFX_API bool ysfx_send_trigger(ysfx_t *fx, uint32_t index);
274 // get a bit mask of sliders whose values must be redisplayed, and clear it to zero
275 YSFX_API uint64_t ysfx_fetch_slider_changes(ysfx_t *fx);
276 // get a bit mask of sliders whose values must be automated, and clear it to zero
277 YSFX_API uint64_t ysfx_fetch_slider_automations(ysfx_t *fx);
278 // get a bit mask of sliders currently visible
279 YSFX_API uint64_t ysfx_get_slider_visibility(ysfx_t *fx);
281 // process a cycle in 32-bit float
282 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);
283 // process a cycle in 64-bit float
284 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);
286 typedef struct ysfx_state_slider_s {
287 // index of the slider
288 uint32_t index;
289 // value of the slider
290 ysfx_real value;
291 } ysfx_state_slider_t;
293 typedef struct ysfx_state_s {
294 // values of the sliders
295 ysfx_state_slider_t *sliders;
296 // number of sliders
297 uint32_t slider_count;
298 // serialized data
299 uint8_t *data;
300 // size of serialized data
301 size_t data_size;
302 } ysfx_state_t;
304 // load state
305 YSFX_API bool ysfx_load_state(ysfx_t *fx, ysfx_state_t *state);
306 // save current state; release this object when done
307 YSFX_API ysfx_state_t *ysfx_save_state(ysfx_t *fx);
308 // release a saved state object
309 YSFX_API void ysfx_state_free(ysfx_state_t *state);
310 // duplicate a state object
311 YSFX_API ysfx_state_t *ysfx_state_dup(ysfx_state_t *state);
313 typedef struct ysfx_preset_s {
314 // name of the preset
315 char *name;
316 // state of the preset
317 ysfx_state_t *state;
318 } ysfx_preset_t;
320 typedef struct ysfx_bank_s {
321 // name of the bank
322 char *name;
323 // list of presets
324 ysfx_preset_t *presets;
325 // number of programs
326 uint32_t preset_count;
327 } ysfx_bank_t;
329 // get the path of the RPL preset bank of the loaded JSFX, if present
330 YSFX_API const char *ysfx_get_bank_path(ysfx_t *fx);
331 // read a preset bank from RPL file
332 YSFX_API ysfx_bank_t *ysfx_load_bank(const char *path);
333 // free a preset bank
334 YSFX_API void ysfx_bank_free(ysfx_bank_t *bank);
336 // type of a function which can enumerate VM variables; returning 0 ends the search
337 typedef int (ysfx_enum_vars_callback_t)(const char *name, ysfx_real *var, void *userdata);
338 // enumerate all variables currently in the VM
339 YSFX_API void ysfx_enum_vars(ysfx_t *fx, ysfx_enum_vars_callback_t *callback, void *userdata);
340 // find a single variable in the VM
341 YSFX_API ysfx_real *ysfx_find_var(ysfx_t *fx, const char *name);
342 // read a chunk of virtual memory from the VM
343 YSFX_API void ysfx_read_vmem(ysfx_t *fx, uint32_t addr, ysfx_real *dest, uint32_t count);
345 //------------------------------------------------------------------------------
346 // YSFX graphics
348 // NOTE: all `ysfx_gfx_*` functions must be invoked from a dedicated UI thread
350 typedef struct ysfx_gfx_config_s {
351 // opaque user data passed to callbacks
352 void *user_data;
353 // the width of the frame buffer (having the scale factor applied)
354 uint32_t pixel_width;
355 // the height of the frame buffer (having the scale factor applied)
356 uint32_t pixel_height;
357 // the distance in bytes between lines; if 0, it defaults to (4*width)
358 // currently it is required to be a multiple of 4
359 uint32_t pixel_stride;
360 // the pixel data of the frame buffer, of size (stride*height) bytes
361 // the byte order in little-endian is 'BGRA', big-endian is 'ARGB'
362 uint8_t *pixels;
363 // the scale factor of the display; 1.0 or greater, 2.0 for Retina display
364 ysfx_real scale_factor;
365 // show a menu and run it synchronously; returns an item ID >= 1, or 0 if none
366 int32_t (*show_menu)(void *user_data, const char *menu_spec, int32_t xpos, int32_t ypos);
367 // change the cursor
368 void (*set_cursor)(void *user_data, int32_t cursor);
369 // if index is not -1, get the dropped file at this index (otherwise null)
370 // if index is -1, clear the list of dropped files, and return null
371 const char *(*get_drop_file)(void *user_data, int32_t index);
372 } ysfx_gfx_config_t;
374 // set up the graphics rendering
375 YSFX_API void ysfx_gfx_setup(ysfx_t *fx, ysfx_gfx_config_t *gc);
376 // get whether the current effect is requesting Retina support
377 YSFX_API bool ysfx_gfx_wants_retina(ysfx_t *fx);
378 // push a key to the input queue
379 YSFX_API void ysfx_gfx_add_key(ysfx_t *fx, uint32_t mods, uint32_t key, bool press);
380 // update mouse information; position is relative to canvas; wheel should be in steps normalized to ±1.0
381 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);
382 // invoke @gfx to paint the graphics; returns whether the framer buffer is modified
383 YSFX_API bool ysfx_gfx_run(ysfx_t *fx);
385 //------------------------------------------------------------------------------
386 // YSFX key map
388 // these key definitions match those of pugl
390 enum {
391 ysfx_mod_shift = 1 << 0,
392 ysfx_mod_ctrl = 1 << 1,
393 ysfx_mod_alt = 1 << 2,
394 ysfx_mod_super = 1 << 3,
397 enum {
398 ysfx_key_backspace = 0x08,
399 ysfx_key_escape = 0x1b,
400 ysfx_key_delete = 0x7f,
402 ysfx_key_f1 = 0xe000,
403 ysfx_key_f2,
404 ysfx_key_f3,
405 ysfx_key_f4,
406 ysfx_key_f5,
407 ysfx_key_f6,
408 ysfx_key_f7,
409 ysfx_key_f8,
410 ysfx_key_f9,
411 ysfx_key_f10,
412 ysfx_key_f11,
413 ysfx_key_f12,
414 ysfx_key_left,
415 ysfx_key_up,
416 ysfx_key_right,
417 ysfx_key_down,
418 ysfx_key_page_up,
419 ysfx_key_page_down,
420 ysfx_key_home,
421 ysfx_key_end,
422 ysfx_key_insert,
425 enum {
426 ysfx_button_left = 1 << 0,
427 ysfx_button_middle = 1 << 1,
428 ysfx_button_right = 1 << 2,
431 //------------------------------------------------------------------------------
432 // YSFX menu
434 typedef struct ysfx_menu_insn_s ysfx_menu_insn_t;
436 typedef struct ysfx_menu_s {
437 // list of instructions to build a menu
438 ysfx_menu_insn_t *insns;
439 // number of menu instructions
440 uint32_t insn_count;
441 } ysfx_menu_t;
443 typedef enum ysfx_menu_opcode_e {
444 // appends an item
445 ysfx_menu_item,
446 // appends a separator
447 ysfx_menu_separator,
448 // appends a submenu and enters
449 ysfx_menu_sub,
450 // terminates a submenu and leaves
451 ysfx_menu_endsub,
452 } ysfx_menu_opcode_t;
454 typedef enum ysfx_menu_item_flag_e {
455 // whether the item is disabled (grayed out)
456 ysfx_menu_item_disabled = 1 << 0,
457 // whether the item is checked
458 ysfx_menu_item_checked = 1 << 1,
459 } ysfx_menu_item_flag_t;
461 typedef struct ysfx_menu_insn_s {
462 // operation code of this instruction
463 ysfx_menu_opcode_t opcode;
464 // unique identifier, greater than 0 (opcodes: item)
465 uint32_t id;
466 // name (opcodes: item, sub/endsub)
467 const char *name;
468 // combination of item flags (opcodes: item, sub/endsub)
469 uint32_t item_flags;
470 } ysfx_menu_insn_t;
472 // parse a string which describes a popup menu (cf. `gfx_showmenu`)
473 YSFX_API ysfx_menu_t *ysfx_parse_menu(const char *text);
474 // free a menu
475 YSFX_API void ysfx_menu_free(ysfx_menu_t *menu);
477 //------------------------------------------------------------------------------
478 // YSFX audio formats
480 typedef struct ysfx_audio_reader_s ysfx_audio_reader_t;
482 typedef struct ysfx_audio_file_info_s {
483 uint32_t channels;
484 ysfx_real sample_rate;
485 } ysfx_audio_file_info_t;
487 typedef struct ysfx_audio_format_s {
488 // quickly checks if this format would be able to handle the given file
489 bool (*can_handle)(const char *path);
490 // open an audio file of this format for reading
491 ysfx_audio_reader_t *(*open)(const char *path);
492 // close the audio file
493 void (*close)(ysfx_audio_reader_t *reader);
494 // get the sample rate and the channel count
495 ysfx_audio_file_info_t (*info)(ysfx_audio_reader_t *reader);
496 // get the number of samples left to read
497 uint64_t (*avail)(ysfx_audio_reader_t *reader);
498 // move the read pointer back to the beginning
499 void (*rewind)(ysfx_audio_reader_t *reader);
500 // read the next block of samples
501 uint64_t (*read)(ysfx_audio_reader_t *reader, ysfx_real *samples, uint64_t count);
502 } ysfx_audio_format_t;
504 //------------------------------------------------------------------------------
506 #ifdef __cplusplus
507 } // extern "C"
508 #endif
510 //------------------------------------------------------------------------------
511 // YSFX RAII helpers
513 #if defined(__cplusplus) && (__cplusplus >= 201103L || (defined(_MSC_VER) && _MSVC_LANG >= 201103L))
514 #include <memory>
516 #define YSFX_DEFINE_AUTO_PTR(aptr, styp, freefn) \
517 struct aptr##_deleter { \
518 void operator()(styp *x) const noexcept { freefn(x); } \
519 }; \
520 using aptr = std::unique_ptr<styp, aptr##_deleter>
522 YSFX_DEFINE_AUTO_PTR(ysfx_config_u, ysfx_config_t, ysfx_config_free);
523 YSFX_DEFINE_AUTO_PTR(ysfx_u, ysfx_t, ysfx_free);
524 YSFX_DEFINE_AUTO_PTR(ysfx_state_u, ysfx_state_t, ysfx_state_free);
525 YSFX_DEFINE_AUTO_PTR(ysfx_bank_u, ysfx_bank_t, ysfx_bank_free);
526 YSFX_DEFINE_AUTO_PTR(ysfx_menu_u, ysfx_menu_t, ysfx_menu_free);
527 #endif // defined(__cplusplus) && (__cplusplus >= 201103L || (defined(_MSC_VER) && _MSVC_LANG >= 201103L))
529 //------------------------------------------------------------------------------
531 #endif // !defined(YSFX_INCLUDED_YSFX_H)