diff options
Diffstat (limited to 'src/LV2-render_internal.h')
| -rw-r--r-- | src/LV2-render_internal.h | 280 |
1 files changed, 280 insertions, 0 deletions
diff --git a/src/LV2-render_internal.h b/src/LV2-render_internal.h new file mode 100644 index 0000000..cac20b0 --- /dev/null +++ b/src/LV2-render_internal.h @@ -0,0 +1,280 @@ + +#ifndef JALV_INTERNAL_H +#define JALV_INTERNAL_H + +#include <stdlib.h> +#include <string.h> + +#include <jack/jack.h> +#include <jack/ringbuffer.h> + +#include "lilv/lilv.h" +#include "serd/serd.h" + +#include "lv2/lv2plug.in/ns/ext/atom/atom.h" +#include "lv2/lv2plug.in/ns/ext/atom/forge.h" +#include "lv2/lv2plug.in/ns/ext/log/log.h" +#include "lv2/lv2plug.in/ns/ext/midi/midi.h" +#include "lv2/lv2plug.in/ns/ext/resize-port/resize-port.h" +#include "lv2/lv2plug.in/ns/ext/state/state.h" +#include "lv2/lv2plug.in/ns/ext/urid/urid.h" +#include "lv2/lv2plug.in/ns/ext/worker/worker.h" + +#include "zix/sem.h" +#include "zix/thread.h" + +#include "sratom/sratom.h" + +#include "lv2_evbuf.h" +#include "symap.h" + +#ifdef __cplusplus +extern "C" { +#endif + +enum PortFlow { + FLOW_UNKNOWN, + FLOW_INPUT, + FLOW_OUTPUT +}; + +enum PortType { + TYPE_UNKNOWN, + TYPE_CONTROL, + TYPE_AUDIO, + TYPE_EVENT +}; + +struct Port { + const LilvPort* lilv_port; + enum PortType type; + enum PortFlow flow; + jack_port_t* jack_port; ///< For audio/MIDI ports, otherwise NULL + LV2_Evbuf* evbuf; ///< For MIDI ports, otherwise NULL + void* widget; ///< Control widget, if applicable + size_t buf_size; ///< Custom buffer size, or 0 + uint32_t index; ///< Port index + float control; ///< For control ports, otherwise 0.0f + bool old_api; ///< True for event, false for atom +}; + +/** + Control change event, sent through ring buffers for UI updates. +*/ +typedef struct { + uint32_t index; + uint32_t protocol; + uint32_t size; + uint8_t body[]; +} ControlChange; + +typedef struct { + char* uuid; ///< Session UUID + char* load; ///< Path for state to load + char** controls; ///< Control values + uint32_t buffer_size; ///< Plugin <= >UI communication buffer size + double update_rate; ///< UI update rate in Hz + int dump; ///< Dump communication iff true + int generic_ui; ///< Use generic UI iff true + int show_hidden; ///< Show controls for notOnGUI ports + int no_menu; ///< Hide menu iff true + int show_ui; ///< Show non-embedded UI + int print_controls; ///< Print control changes to stdout +} JalvOptions; + +typedef struct { + LV2_URID atom_Float; + LV2_URID atom_Int; + LV2_URID atom_eventTransfer; + LV2_URID bufsz_maxBlockLength; + LV2_URID bufsz_minBlockLength; + LV2_URID bufsz_sequenceSize; + LV2_URID log_Trace; + LV2_URID midi_MidiEvent; + LV2_URID param_sampleRate; + LV2_URID patch_Set; + LV2_URID patch_property; + LV2_URID patch_value; + LV2_URID time_Position; + LV2_URID time_bar; + LV2_URID time_barBeat; + LV2_URID time_beatUnit; + LV2_URID time_beatsPerBar; + LV2_URID time_beatsPerMinute; + LV2_URID time_frame; + LV2_URID time_speed; + LV2_URID ui_updateRate; +} JalvURIDs; + +typedef struct { + LilvNode* atom_AtomPort; + LilvNode* atom_Chunk; + LilvNode* atom_Sequence; + LilvNode* ev_EventPort; + LilvNode* lv2_AudioPort; + LilvNode* lv2_ControlPort; + LilvNode* lv2_InputPort; + LilvNode* lv2_OutputPort; + LilvNode* lv2_connectionOptional; + LilvNode* lv2_control; + LilvNode* lv2_name; + LilvNode* midi_MidiEvent; + LilvNode* pg_group; + LilvNode* pset_Preset; + LilvNode* rdfs_label; + LilvNode* rsz_minimumSize; + LilvNode* work_interface; + LilvNode* work_schedule; + LilvNode* end; ///< NULL terminator for easy freeing of entire structure +} JalvNodes; + +typedef enum { + JALV_RUNNING, + JALV_PAUSE_REQUESTED, + JALV_PAUSED +} JalvPlayState; + +typedef struct { + jack_ringbuffer_t* requests; ///< Requests to the worker + jack_ringbuffer_t* responses; ///< Responses from the worker + void* response; ///< Worker response buffer + ZixSem sem; ///< Worker semaphore + ZixThread thread; ///< Worker thread + const LV2_Worker_Interface* iface; ///< Plugin worker interface +} JalvWorker; + +typedef struct { + JalvOptions opts; ///< Command-line options + JalvURIDs urids; ///< URIDs + JalvNodes nodes; ///< Nodes + LV2_Atom_Forge forge; ///< Atom forge + const char* prog_name; ///< Program name (argv[0]) + LilvWorld* world; ///< Lilv World + LV2_URID_Map map; ///< URI => Int map + LV2_URID_Unmap unmap; ///< Int => URI map + Sratom* sratom; ///< Atom serialiser + Sratom* ui_sratom; ///< Atom serialiser for UI thread + Symap* symap; ///< URI map + ZixSem symap_lock; ///< Lock for URI map + jack_client_t* jack_client; ///< Jack client + jack_ringbuffer_t* ui_events; ///< Port events from UI + jack_ringbuffer_t* plugin_events; ///< Port events from plugin + void* ui_event_buf; ///< Buffer for reading UI port events + JalvWorker worker; ///< Worker thread implementation + ZixSem* done; ///< Exit semaphore + ZixSem paused; ///< Paused signal from process thread + JalvPlayState play_state; ///< Current play state + char* temp_dir; ///< Temporary plugin state directory + char* save_dir; ///< Plugin save directory + const LilvPlugin* plugin; ///< Plugin class (RDF data) + LilvUIs* uis; ///< All plugin UIs (RDF data) + const LilvUI* ui; ///< Plugin UI (RDF data) + const LilvNode* ui_type; ///< Plugin UI type (unwrapped) + LilvInstance* instance; ///< Plugin instance (shared library) + void* window; ///< Window (if applicable) + struct Port* ports; ///< Port array of size num_ports + uint32_t block_length; ///< Jack buffer size (block length) + size_t midi_buf_size; ///< Size of MIDI port buffers + uint32_t control_in; ///< Index of control input port + uint32_t num_ports; ///< Size of the two following arrays: + uint32_t longest_sym; ///< Longest port symbol + float ui_update_hz; ///< Frequency of UI updates + jack_nframes_t sample_rate; ///< Sample rate + jack_nframes_t event_delta_t; ///< Frames since last update sent to UI + uint32_t midi_event_id; ///< MIDI event class ID in event context + jack_nframes_t position; ///< Transport position in frames + float bpm; ///< Transport tempo in beats per minute + bool rolling; ///< Transport speed (0=stop, 1=play) + bool buf_size_set; ///< True iff buffer size callback fired + bool exit; ///< True iff execution is finished +} Jalv; + +int +jalv_init(int* argc, char*** argv, JalvOptions* opts); + +void +jalv_create_ports(Jalv* jalv); + +struct Port* +jalv_port_by_symbol(Jalv* jalv, const char* sym); + +typedef int (*PresetSink)(Jalv* jalv, + const LilvNode* node, + const LilvNode* title, + void* data); + +int +jalv_load_presets(Jalv* jalv, PresetSink sink, void* data); + +int +jalv_unload_presets(Jalv* jalv); + +int +jalv_apply_preset(Jalv* jalv, const LilvNode* preset); + +int +jalv_save_preset(Jalv* jalv, + const char* dir, + const char* uri, + const char* label, + const char* filename); + +void +jalv_save(Jalv* jalv, const char* dir); + +void +jalv_save_port_values(Jalv* jalv, + SerdWriter* writer, + const SerdNode* subject); +char* +jalv_make_path(LV2_State_Make_Path_Handle handle, + const char* path); + +void +jalv_apply_state(Jalv* jalv, LilvState* state); + +char* +atom_to_turtle(LV2_URID_Unmap* unmap, + const SerdNode* subject, + const SerdNode* predicate, + const LV2_Atom* atom); + +static inline char* +jalv_strdup(const char* str) +{ + const size_t len = strlen(str); + char* copy = (char*)malloc(len + 1); + memcpy(copy, str, len + 1); + return copy; +} + +static inline char* +jalv_strjoin(const char* a, const char* b) +{ + const size_t a_len = strlen(a); + const size_t b_len = strlen(b); + char* const out = (char*)malloc(a_len + b_len + 1); + + memcpy(out, a, a_len); + memcpy(out + a_len, b, b_len); + out[a_len + b_len] = '\0'; + + return out; +} + +int +jalv_printf(LV2_Log_Handle handle, + LV2_URID type, + const char* fmt, ...); + +int +jalv_vprintf(LV2_Log_Handle handle, + LV2_URID type, + const char* fmt, + va_list ap); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // JALV_INTERNAL_H |
