commit 880349a3b90cc7be9d46982a863c8362c6cd16a5
parent 242e0d2788795aad869b612d48f0be3ee6f99494
Author: falkTX <falktx@falktx.com>
Date: Tue, 11 May 2021 16:37:25 +0100
Initial implementation of travesty, pure C interface to vst3
Signed-off-by: falkTX <falktx@falktx.com>
Diffstat:
11 files changed, 1159 insertions(+), 0 deletions(-)
diff --git a/distrho/src/travesty/README.txt b/distrho/src/travesty/README.txt
@@ -0,0 +1,9 @@
+This folder contains a pure C interface to Steinberg VST3 SDK, codenamed "travesty".
+Name is a play on words from morphing "vestige" (the good old free VST2 reverse-engineered header file) and "three".
+
+The main target is to be able to create VST3-compatible plugins without a bloated SDK.
+Everything that is required for plugins fits in a few small header files.
+Also, being able to build VST3-compatible plugins in pure C code, something not possible with the original SDK.
+
+Please note this project is still a work in progress.
+Use at your own risk, and please report any issues to https://github.com/DISTRHO/DPF/.
diff --git a/distrho/src/travesty/align_pop.h b/distrho/src/travesty/align_pop.h
@@ -0,0 +1,23 @@
+/*
+ * travesty, pure C interface to steinberg VST3 SDK
+ * Copyright (C) 2021 Filipe Coelho <falktx@falktx.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any purpose with
+ * or without fee is hereby granted, provided that the above copyright notice and this
+ * permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#if defined(__APPLE__) || defined(_WIN32)
+# pragma pack(pop)
+#endif
+
+#if defined(__APPLE__)
+# pragma GCC diagnostic pop
+#endif
diff --git a/distrho/src/travesty/align_push.h b/distrho/src/travesty/align_push.h
@@ -0,0 +1,37 @@
+/*
+ * travesty, pure C interface to steinberg VST3 SDK
+ * Copyright (C) 2021 Filipe Coelho <falktx@falktx.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any purpose with
+ * or without fee is hereby granted, provided that the above copyright notice and this
+ * permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#if defined(__APPLE__)
+
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wunknown-warning-option"
+# pragma GCC diagnostic ignored "-Wpragma-pack"
+# if defined(__LP64__) || defined(_LP64)
+# pragma pack(push, 16)
+# else
+# pragma pack(push, 1)
+# endif
+
+#elif defined(_WIN32)
+
+# pragma pack(push)
+# if defined(_WIN64) || defined(_M_ARM64)
+# pragma pack(16)
+# else
+# pragma pack(8)
+# endif
+
+#endif
diff --git a/distrho/src/travesty/audio_processor.h b/distrho/src/travesty/audio_processor.h
@@ -0,0 +1,270 @@
+/*
+ * travesty, pure C interface to steinberg VST3 SDK
+ * Copyright (C) 2021 Filipe Coelho <falktx@falktx.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any purpose with
+ * or without fee is hereby granted, provided that the above copyright notice and this
+ * permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#pragma once
+
+#include "base.h"
+#include "events.h"
+
+#include "align_push.h"
+
+/**
+ * speakers
+ */
+
+typedef uint64_t v3_speaker_arrangement;
+
+enum {
+ V3_SPEAKER_L = 1,
+ V3_SPEAKER_R = 1 << 1
+};
+
+/**
+ * process setup
+ */
+
+enum v3_process_mode {
+ V3_REALTIME,
+ V3_PREFETCH,
+ V3_OFFLINE
+};
+
+inline static const char *
+v3_process_mode_str(int32_t d)
+{
+ switch (d) {
+ case V3_REALTIME: return "V3_REALTIME";
+ case V3_PREFETCH: return "V3_PREFETCH";
+ case V3_OFFLINE: return "V3_OFFLINE";
+ default: return "[unknown]";
+ }
+}
+
+enum {
+ V3_SAMPLE_32,
+ V3_SAMPLE_64
+};
+
+inline static const char *
+v3_sample_size_str(int32_t d)
+{
+ switch (d) {
+ case V3_SAMPLE_32: return "V3_SAMPLE_32";
+ case V3_SAMPLE_64: return "V3_SAMPLE_64";
+ default: return "[unknown]";
+ }
+}
+
+struct v3_process_setup {
+ int32_t process_mode;
+ int32_t symbolic_sample_size;
+ int32_t max_block_size;
+ double sample_rate;
+};
+
+/**
+ * param changes
+ */
+
+struct v3_param_value_queue {
+ struct v3_funknown;
+
+ V3_API v3_param_id (*get_param_id)(void *self);
+ V3_API int32_t (*get_point_count)(void *self);
+
+ V3_API v3_result (*get_point)
+ (void *self, int32_t idx, int32_t *sample_offset, double *value);
+ V3_API v3_result (*add_point)
+ (void *self, int32_t sample_offset, double value, int32_t *idx);
+};
+
+static const v3_tuid v3_param_value_queue_iid =
+ V3_ID(0x01263A18, 0xED074F6F, 0x98C9D356, 0x4686F9BA);
+
+struct v3_param_changes {
+ struct v3_funknown;
+
+ V3_API int32_t (*get_param_count)(void *self);
+
+ V3_API struct v3_param_value_queue **(*get_param_data)
+ (void *self, int32_t idx);
+
+ V3_API struct v3_param_value_queue **(*add_param_data)
+ (void *self, v3_param_id *id, int32_t *index);
+};
+
+static const v3_tuid v3_param_changes_iid =
+ V3_ID(0xA4779663, 0x0BB64A56, 0xB44384A8, 0x466FEB9D);
+
+/**
+ * process context
+ */
+
+struct v3_frame_rate {
+ uint32_t fps;
+ uint32_t flags;
+};
+
+struct v3_chord {
+ uint8_t key_note;
+ uint8_t root_note;
+
+ int16_t chord_mask;
+};
+
+enum {
+ V3_PROCESS_CTX_PLAYING = 1 << 1,
+ V3_PROCESS_CTX_CYCLE_ACTIVE = 1 << 2,
+ V3_PROCESS_CTX_RECORDING = 1 << 3,
+
+ V3_PROCESS_CTX_SYSTEM_TIME_VALID = 1 << 8,
+ V3_PROCESS_CTX_CONT_TIME_VALID = 1 << 17,
+ V3_PROCESS_CTX_PROJECT_TIME_VALID = 1 << 9,
+
+ V3_PROCESS_CTX_BAR_POSITION_VALID = 1 << 11,
+ V3_PROCESS_CTX_CYCLE_VALID = 1 << 12,
+
+ V3_PROCESS_CTX_TEMPO_VALID = 1 << 10,
+ V3_PROCESS_CTX_TIME_SIG_VALID = 1 << 13,
+ V3_PROCESS_CTX_CHORD_VALID = 1 << 18,
+
+ V3_PROCESS_CTX_SMPTE_VALID = 1 << 14,
+
+ V3_PROCESS_CTX_NEXT_CLOCK_VALID = 1 << 15
+};
+
+struct v3_process_context {
+ uint32_t state;
+
+ double sample_rate;
+ int64_t project_time_in_samples; // with loop
+
+ int64_t system_time_ns;
+ int64_t continuous_time_in_samples; // without loop? unclear
+
+ double project_time_quarters;
+ double bar_position_quarters;
+ double cycle_start_quarters;
+ double cycle_end_quarters;
+
+ double bpm;
+
+ int32_t time_sig_numerator;
+ int32_t time_sig_denom;
+
+ struct v3_chord chord;
+
+ int32_t smpte_offset_subframes;
+ struct v3_frame_rate frame_rate;
+
+ int32_t samples_to_next_clock;
+};
+
+/**
+ * process context requirements
+ */
+
+enum {
+ V3_PROCESS_CTX_NEED_SYSTEM_TIME = 1 << 0,
+ V3_PROCESS_CTX_NEED_CONTINUOUS_TIME = 1 << 1,
+ V3_PROCESS_CTX_NEED_PROJECT_TIME = 1 << 2,
+ V3_PROCESS_CTX_NEED_BAR_POSITION = 1 << 3,
+ V3_PROCESS_CTX_NEED_CYCLE = 1 << 4,
+ V3_PROCESS_CTX_NEED_NEXT_CLOCK = 1 << 5,
+ V3_PROCESS_CTX_NEED_TEMPO = 1 << 6,
+ V3_PROCESS_CTX_NEED_TIME_SIG = 1 << 7,
+ V3_PROCESS_CTX_NEED_CHORD = 1 << 8,
+ V3_PROCESS_CTX_NEED_FRAME_RATE = 1 << 9,
+ V3_PROCESS_CTX_NEED_TRANSPORT_STATE = 1 << 10
+};
+
+struct v3_process_context_requirements {
+ struct v3_funknown;
+
+ V3_API uint32_t (*get_process_context_requirements)(void *self);
+};
+
+static const v3_tuid v3_process_context_requirements_iid =
+ V3_ID(0x2A654303, 0xEF764E3D, 0x95B5FE83, 0x730EF6D0);
+
+/**
+ * process data and context
+ */
+
+struct v3_audio_bus_buffers {
+ int32_t num_channels;
+ uint64_t channel_silence_bitset;
+
+ union {
+ float **channel_buffers_32;
+ double **channel_buffers_64;
+ };
+};
+
+struct v3_process_data {
+ int32_t process_mode;
+ int32_t symbolic_sample_size;
+
+ int32_t nframes;
+
+ int32_t num_input_buses;
+ int32_t num_output_buses;
+
+ struct v3_audio_bus_buffers *inputs;
+ struct v3_audio_bus_buffers *outputs;
+
+ struct v3_param_changes **input_params;
+ struct v3_param_changes **output_params;
+
+ struct v3_event_list **input_events;
+ struct v3_event_list **output_events;
+
+ struct v3_process_context *ctx;
+};
+
+/**
+ * audio processor
+ */
+
+struct v3_audio_processor {
+ struct v3_funknown;
+
+ V3_API v3_result (*set_bus_arrangements)
+ (void *self, v3_speaker_arrangement *inputs, int32_t num_inputs,
+ v3_speaker_arrangement *outputs, int32_t num_outputs);
+ V3_API v3_result (*get_bus_arrangement)
+ (void *self, int32_t bus_direction, int32_t idx, v3_speaker_arrangement *);
+
+ V3_API v3_result (*can_process_sample_size)
+ (void *self, int32_t symbolic_sample_size);
+
+ V3_API uint32_t (*get_latency_samples)(void *self);
+
+ V3_API v3_result (*setup_processing)
+ (void *self, struct v3_process_setup *);
+ V3_API v3_result (*set_processing)
+ (void *self, v3_bool state);
+
+ V3_API v3_result (*process)
+ (void *self, struct v3_process_data *);
+
+ V3_API uint32_t (*get_tail_samples)(void *self);
+};
+
+static const v3_tuid v3_audio_processor_iid =
+ V3_ID(0x42043F99, 0xB7DA453C, 0xA569E79D, 0x9AAEC33D);
+
+#include "align_pop.h"
diff --git a/distrho/src/travesty/base.h b/distrho/src/travesty/base.h
@@ -0,0 +1,153 @@
+/*
+ * travesty, pure C interface to steinberg VST3 SDK
+ * Copyright (C) 2021 Filipe Coelho <falktx@falktx.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any purpose with
+ * or without fee is hereby granted, provided that the above copyright notice and this
+ * permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <string.h>
+
+/**
+ * various types
+ */
+
+typedef int32_t v3_result;
+
+typedef int16_t v3_str_128[128];
+typedef uint8_t v3_bool;
+
+typedef uint32_t v3_param_id;
+
+
+/**
+ * low-level ABI nonsense
+ */
+
+typedef uint8_t v3_tuid[16];
+
+inline static int
+v3_tuid_match(const v3_tuid a, const v3_tuid b)
+{
+ return !memcmp(a, b, sizeof(v3_tuid));
+}
+
+#if defined(_WIN32)
+# define V3_COM_COMPAT 1
+# define V3_API __stdcall
+#else
+# define V3_COM_COMPAT 0
+# define V3_API
+#endif
+
+#if V3_COM_COMPAT
+enum {
+ V3_NO_INTERFACE = 0x80004002L,
+ V3_OK = 0,
+ V3_TRUE = 0,
+ V3_FALSE = 1,
+ V3_INVALID_ARG = 0x80070057L,
+ V3_NOT_IMPLEMENTED = 0x80004001L,
+ V3_INTERNAL_ERR = 0x80004005L,
+ V3_NOT_INITIALISED = 0x8000FFFFL,
+ V3_NOMEM = 0x8007000EL
+};
+
+# define V3_ID(a, b, c, d) { \
+ ((a) & 0x000000FF), \
+ ((a) & 0x0000FF00) >> 8, \
+ ((a) & 0x00FF0000) >> 16, \
+ ((a) & 0xFF000000) >> 24, \
+ \
+ ((b) & 0x00FF0000) >> 16, \
+ ((b) & 0xFF000000) >> 24, \
+ ((b) & 0x000000FF), \
+ ((b) & 0x0000FF00) >> 8, \
+ \
+ ((c) & 0xFF000000) >> 24, \
+ ((c) & 0x00FF0000) >> 16, \
+ ((c) & 0x0000FF00) >> 8, \
+ ((c) & 0x000000FF), \
+ \
+ ((d) & 0xFF000000) >> 24, \
+ ((d) & 0x00FF0000) >> 16, \
+ ((d) & 0x0000FF00) >> 8, \
+ ((d) & 0x000000FF), \
+}
+
+#else // V3_COM_COMPAT
+enum {
+ V3_NO_INTERFACE = -1,
+ V3_OK,
+ V3_TRUE = V3_OK,
+ V3_FALSE,
+ V3_INVALID_ARG,
+ V3_NOT_IMPLEMENTED,
+ V3_INTERNAL_ERR,
+ V3_NOT_INITIALISED,
+ V3_NOMEM
+};
+
+# define V3_ID(a, b, c, d) { \
+ ((a) & 0xFF000000) >> 24, \
+ ((a) & 0x00FF0000) >> 16, \
+ ((a) & 0x0000FF00) >> 8, \
+ ((a) & 0x000000FF), \
+ \
+ ((b) & 0xFF000000) >> 24, \
+ ((b) & 0x00FF0000) >> 16, \
+ ((b) & 0x0000FF00) >> 8, \
+ ((b) & 0x000000FF), \
+ \
+ ((c) & 0xFF000000) >> 24, \
+ ((c) & 0x00FF0000) >> 16, \
+ ((c) & 0x0000FF00) >> 8, \
+ ((c) & 0x000000FF), \
+ \
+ ((d) & 0xFF000000) >> 24, \
+ ((d) & 0x00FF0000) >> 16, \
+ ((d) & 0x0000FF00) >> 8, \
+ ((d) & 0x000000FF), \
+}
+#endif // V3_COM_COMPAT
+
+/**
+ * funknown
+ */
+
+struct v3_funknown {
+ V3_API v3_result (*query_interface)
+ (void *self, const v3_tuid iid, void **obj);
+
+ V3_API uint32_t (*ref)(void *self);
+ V3_API uint32_t (*unref)(void *self);
+};
+
+static const v3_tuid v3_funknown_iid =
+ V3_ID(0x00000000, 0x00000000, 0xC0000000, 0x00000046);
+
+/**
+ * plugin base
+ */
+
+struct v3_plugin_base {
+ struct v3_funknown;
+
+ V3_API v3_result (*initialise)
+ (void *self, struct v3_funknown *context);
+ V3_API v3_result (*terminate)(void *self);
+};
+
+static const v3_tuid v3_plugin_base_iid =
+ V3_ID(0x22888DDB, 0x156E45AE, 0x8358B348, 0x08190625);
diff --git a/distrho/src/travesty/bstream.h b/distrho/src/travesty/bstream.h
@@ -0,0 +1,41 @@
+/*
+ * travesty, pure C interface to steinberg VST3 SDK
+ * Copyright (C) 2021 Filipe Coelho <falktx@falktx.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any purpose with
+ * or without fee is hereby granted, provided that the above copyright notice and this
+ * permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#pragma once
+
+#include "base.h"
+
+enum v3_seek_mode {
+ V3_SEEK_SET = 0,
+ V3_SEEK_CUR,
+ V3_SEEK_END
+};
+
+struct v3_bstream {
+ struct v3_funknown;
+
+ V3_API v3_result (*read)
+ (void *self, void *buffer, int32_t num_bytes, int32_t *bytes_read);
+ V3_API v3_result (*write)
+ (void *self, void *buffer, int32_t num_bytes, int32_t *bytes_written);
+ V3_API v3_result (*seek)
+ (void *self, int64_t pos, int32_t seek_mode, int64_t *result);
+ V3_API v3_result (*tell)
+ (void *self, int64_t *pos);
+};
+
+static const v3_tuid v3_bstream_iid =
+ V3_ID(0xC3BF6EA2, 0x30994752, 0x9B6BF990, 0x1EE33E9B);
diff --git a/distrho/src/travesty/component.h b/distrho/src/travesty/component.h
@@ -0,0 +1,117 @@
+/*
+ * travesty, pure C interface to steinberg VST3 SDK
+ * Copyright (C) 2021 Filipe Coelho <falktx@falktx.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any purpose with
+ * or without fee is hereby granted, provided that the above copyright notice and this
+ * permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#pragma once
+
+#include "base.h"
+#include "bstream.h"
+
+#include "align_push.h"
+
+/**
+ * buses
+ */
+
+enum v3_media_types {
+ V3_AUDIO = 0,
+ V3_EVENT
+};
+
+inline static const char *
+v3_media_type_str(int32_t type)
+{
+ switch (type) {
+ case V3_AUDIO: return "V3_AUDIO";
+ case V3_EVENT: return "V3_EVENT";
+ default: return "[unknown]";
+ }
+}
+
+enum v3_bus_direction {
+ V3_INPUT = 0,
+ V3_OUTPUT
+};
+
+inline static const char *
+v3_bus_direction_str(int32_t d)
+{
+ switch (d) {
+ case V3_INPUT: return "V3_INPUT";
+ case V3_OUTPUT: return "V3_OUTPUT";
+ default: return "[unknown]";
+ }
+}
+
+enum v3_bus_types {
+ V3_MAIN = 0,
+ V3_AUX
+};
+
+enum v3_bus_flags {
+ V3_DEFAULT_ACTIVE = 1,
+ V3_IS_CONTROL_VOLTAGE = 1 << 1
+};
+
+struct v3_bus_info {
+ int32_t media_type;
+ int32_t direction;
+ int32_t channel_count;
+
+ v3_str_128 bus_name;
+ int32_t bus_type;
+ uint32_t flags;
+};
+
+/**
+ * component
+ */
+
+struct v3_routing_info;
+
+struct v3_component {
+ struct v3_plugin_base;
+
+ V3_API v3_result (*get_controller_class_id)
+ (void *self, v3_tuid class_id);
+
+ V3_API v3_result (*set_io_mode)
+ (void *self, int32_t io_mode);
+
+ V3_API int32_t (*get_bus_count)
+ (void *self, int32_t media_type, int32_t bus_direction);
+ V3_API v3_result (*get_bus_info)
+ (void *self, int32_t media_type, int32_t bus_direction,
+ int32_t bus_idx, struct v3_bus_info *bus_info);
+ V3_API v3_result (*get_routing_info)
+ (void *self, struct v3_routing_info *input,
+ struct v3_routing_info *output);
+ V3_API v3_result (*activate_bus)
+ (void *self, int32_t media_type, int32_t bus_direction,
+ int32_t bus_idx, v3_bool state);
+
+ V3_API v3_result (*set_active)
+ (void *self, v3_bool state);
+
+ V3_API v3_result (*set_state)
+ (void *self, struct v3_bstream **);
+ V3_API v3_result (*get_state)
+ (void *self, struct v3_bstream **);
+};
+
+static const v3_tuid v3_component_iid =
+ V3_ID(0xE831FF31, 0xF2D54301, 0x928EBBEE, 0x25697802);
+
+#include "align_pop.h"
diff --git a/distrho/src/travesty/edit_controller.h b/distrho/src/travesty/edit_controller.h
@@ -0,0 +1,113 @@
+/*
+ * travesty, pure C interface to steinberg VST3 SDK
+ * Copyright (C) 2021 Filipe Coelho <falktx@falktx.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any purpose with
+ * or without fee is hereby granted, provided that the above copyright notice and this
+ * permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#pragma once
+
+#include "base.h"
+#include "bstream.h"
+#include "view.h"
+
+#include "align_push.h"
+
+/**
+ * component handler
+ */
+
+struct v3_component_handler {
+ struct v3_funknown;
+
+ V3_API v3_result (*begin_edit)
+ (void *self, v3_param_id);
+ V3_API v3_result (*perform_edit)
+ (void *self, v3_param_id, double value_normalised);
+ V3_API v3_result (*end_edit)
+ (void *self, v3_param_id);
+
+ V3_API v3_result (*restart_component)
+ (void *self, int32_t flags);
+};
+
+static const v3_tuid v3_component_handler_iid =
+ V3_ID(0x93A0BEA3, 0x0BD045DB, 0x8E890B0C, 0xC1E46AC6);
+
+/**
+ * edit controller
+ */
+
+enum {
+ V3_PARAM_CAN_AUTOMATE = 1,
+ V3_PARAM_READ_ONLY = 1 << 1,
+ V3_PARAM_WRAP_AROUND = 1 << 2,
+ V3_PARAM_IS_LIST = 1 << 3,
+ V3_PARAM_IS_HIDDEN = 1 << 4,
+ V3_PARAM_PROGRAM_CHANGE = 1 << 15,
+ V3_PARAM_IS_BYPASS = 1 << 16
+};
+
+struct v3_param_info {
+ v3_param_id param_id;
+
+ v3_str_128 title;
+ v3_str_128 short_title;
+ v3_str_128 units;
+
+ int32_t step_count;
+
+ double default_normalised_value;
+
+ int32_t unit_id;
+ int32_t flags;
+};
+
+struct v3_edit_controller {
+ struct v3_plugin_base;
+
+ V3_API v3_result (*set_component_state)
+ (void *self, struct v3_bstream *);
+ V3_API v3_result (*set_state)
+ (void *self, struct v3_bstream *);
+ V3_API v3_result (*get_state)
+ (void *self, struct v3_bstream *);
+
+ V3_API int32_t (*get_parameter_count)(void *self);
+ V3_API v3_result (*get_param_info)
+ (void *self, int32_t param_idx, struct v3_param_info *);
+
+ V3_API v3_result (*get_param_string_for_value)
+ (void *self, v3_param_id, double normalised, v3_str_128 output);
+ V3_API v3_result (*get_param_value_for_string)
+ (void *self, v3_param_id, int16_t *input, double *output);
+
+ V3_API double (*normalised_param_to_plain)
+ (void *self, v3_param_id, double normalised);
+ V3_API double (*plain_param_to_normalised)
+ (void *self, v3_param_id, double normalised);
+
+ V3_API double (*get_param_normalised)(void *self, v3_param_id);
+ V3_API v3_result (*set_param_normalised)
+ (void *self, v3_param_id, double normalised);
+
+ V3_API v3_result (*set_component_handler)
+ (void *self, struct v3_component_handler **);
+
+ V3_API struct v3_plug_view **(*create_view)
+ (void *self, const char *name);
+};
+
+static const v3_tuid v3_edit_controller_iid =
+ V3_ID(0xDCD7BBE3, 0x7742448D, 0xA874AACC, 0x979C759E);
+
+#include "align_pop.h"
diff --git a/distrho/src/travesty/events.h b/distrho/src/travesty/events.h
@@ -0,0 +1,164 @@
+/*
+ * travesty, pure C interface to steinberg VST3 SDK
+ * Copyright (C) 2021 Filipe Coelho <falktx@falktx.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any purpose with
+ * or without fee is hereby granted, provided that the above copyright notice and this
+ * permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#pragma once
+
+#include "base.h"
+
+#include "align_push.h"
+
+/**
+ * note events
+ *
+ * i know there's others, but we don't need them right now. whatever.
+ * handle them later.
+ */
+
+struct v3_event_note_on {
+ int16_t channel;
+ int16_t pitch; // MIDI note number
+
+ float tuning;
+ float velocity;
+
+ int32_t length;
+ int32_t note_id;
+};
+
+struct v3_event_note_off {
+ int16_t channel;
+ int16_t pitch; // MIDI note number
+
+ float velocity;
+
+ int32_t note_id;
+ float tuning;
+};
+
+struct v3_event_data {
+ uint32_t size;
+ uint32_t type;
+
+ const uint8_t *bytes;
+};
+
+struct v3_event_poly_pressure {
+ int16_t channel;
+ int16_t pitch;
+
+ float pressure;
+ int32_t note_id;
+};
+
+struct v3_event_chord {
+ int16_t root;
+ int16_t bass_note;
+ int16_t mask;
+
+ uint16_t text_len;
+ const int16_t *text;
+};
+
+struct v3_event_scale {
+ int16_t root;
+ int16_t mask;
+
+ uint16_t text_len;
+ const int16_t *text;
+};
+
+struct v3_event_legacy_midi_cc_out {
+ uint8_t cc_number;
+
+ int8_t channel;
+ int8_t value;
+ int8_t value2;
+};
+
+struct v3_event_note_expression_value {
+ uint32_t type_id;
+ int32_t note_id;
+ double value;
+};
+
+struct v3_event_note_expression_text {
+ int32_t note_id;
+
+ uint32_t text_len;
+ const int16_t *text;
+};
+
+/**
+ * event
+ */
+
+enum v3_event_flags {
+ V3_EVENT_IS_LIVE = 1
+};
+
+enum v3_event_type {
+ V3_EVENT_NOTE_ON = 0,
+ V3_EVENT_NOTE_OFF = 1,
+ V3_EVENT_DATA = 2,
+ V3_EVENT_POLY_PRESSURE = 3,
+ V3_EVENT_NOTE_EXP_VALUE = 4,
+ V3_EVENT_NOTE_EXP_TEXT = 5,
+ V3_EVENT_CHORD = 6,
+ V3_EVENT_SCALE = 7,
+
+ V3_EVENT_LEGACY_MIDI_CC_OUT = 65535
+};
+
+struct v3_event {
+ int32_t bus_index;
+ int32_t sample_offset;
+
+ double ppq_position;
+ uint16_t flags;
+
+ uint16_t type;
+
+ union {
+ struct v3_event_note_on note_on;
+ struct v3_event_note_off note_off;
+ struct v3_event_data data;
+ struct v3_event_poly_pressure poly_pressure;
+ struct v3_event_chord chord;
+ struct v3_event_scale scale;
+ struct v3_event_legacy_midi_cc_out midi_cc_out;
+ struct v3_event_note_expression_value note_exp_value;
+ struct v3_event_note_expression_text note_exp_text;
+ };
+};
+
+/**
+ * event list
+ */
+
+struct v3_event_list {
+ struct v3_funknown;
+
+ V3_API uint32_t (*get_event_count)(void *self);
+ V3_API v3_result (*get_event)
+ (void *self, int32_t idx, struct v3_event *);
+ V3_API v3_result (*add_event)
+ (void *self, struct v3_event *);
+};
+
+static const v3_tuid v3_event_list_iid =
+ V3_ID(0x3A2C4214, 0x346349FE, 0xB2C4F397, 0xB9695A44);
+
+#include "align_pop.h"
diff --git a/distrho/src/travesty/factory.h b/distrho/src/travesty/factory.h
@@ -0,0 +1,115 @@
+/*
+ * travesty, pure C interface to steinberg VST3 SDK
+ * Copyright (C) 2021 Filipe Coelho <falktx@falktx.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any purpose with
+ * or without fee is hereby granted, provided that the above copyright notice and this
+ * permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#pragma once
+
+#include "base.h"
+
+/**
+ * plugin factory v1
+ */
+
+struct v3_factory_info {
+ char vendor[64];
+ char url[256];
+ char email[128];
+ int32_t flags;
+};
+
+struct v3_class_info {
+ v3_tuid class_id;
+ int32_t cardinality; // set to 0x7FFFFFFF
+ char category[32];
+ char name[64];
+};
+
+struct v3_plugin_factory {
+ struct v3_funknown;
+
+ V3_API v3_result (*get_factory_info)
+ (void *self, struct v3_factory_info *);
+
+ V3_API int32_t (*num_classes)(void *self);
+
+ V3_API v3_result (*get_class_info)
+ (void *self, int32_t idx, struct v3_class_info *);
+
+ V3_API v3_result (*create_instance)
+ (void *self, const char *class_id, const char *_iid, void **instance);
+};
+
+static const v3_tuid v3_plugin_factory_iid =
+ V3_ID(0x7A4D811C, 0x52114A1F, 0xAED9D2EE, 0x0B43BF9F);
+
+/**
+ * plugin factory v2
+ */
+
+struct v3_class_info_2 {
+ v3_tuid class_id;
+ int32_t cardinality; // set to 0x7FFFFFFF
+ char category[32];
+ char name[64];
+
+ uint32_t class_flags;
+ char sub_categories[128];
+ char vendor[64];
+ char version[64];
+ char sdk_version[64];
+};
+
+struct v3_plugin_factory_2 {
+ struct v3_plugin_factory;
+
+ V3_API v3_result (*get_class_info_2)
+ (void *self, int32_t idx, struct v3_class_info_2 *);
+};
+
+static const v3_tuid v3_plugin_factory_2_iid =
+ V3_ID(0x0007B650, 0xF24B4C0B, 0xA464EDB9, 0xF00B2ABB);
+
+/**
+ * plugin factory v3
+ * (we got it right this time I swear)
+ *
+ * same as above, but "unicode" (really just utf-16, thanks microsoft!)
+ */
+
+struct v3_class_info_3 {
+ v3_tuid class_id;
+ int32_t cardinality; // set to 0x7FFFFFFF
+ char category[32];
+ int16_t name[64];
+
+ uint32_t class_flags;
+ char sub_categories[128];
+ int16_t vendor[64];
+ int16_t version[64];
+ int16_t sdk_version[64];
+};
+
+struct v3_plugin_factory_3 {
+ struct v3_plugin_factory;
+
+ V3_API v3_result (*get_class_info_utf16)
+ (void *self, int32_t idx, struct v3_class_info_3 *);
+
+ V3_API v3_result (*set_host_context)
+ (void *self, struct v3_funknown *host);
+};
+
+static const v3_tuid v3_plugin_factory_3_iid =
+ V3_ID(0x4555A2AB, 0xC1234E57, 0x9B122910, 0x36878931);
diff --git a/distrho/src/travesty/view.h b/distrho/src/travesty/view.h
@@ -0,0 +1,117 @@
+/*
+ * travesty, pure C interface to steinberg VST3 SDK
+ * Copyright (C) 2021 Filipe Coelho <falktx@falktx.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any purpose with
+ * or without fee is hereby granted, provided that the above copyright notice and this
+ * permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#pragma once
+
+#include "base.h"
+
+/**
+ * base IPlugFrame stuff
+ */
+
+struct v3_view_rect {
+ int32_t left;
+ int32_t top;
+ int32_t right;
+ int32_t bottom;
+};
+
+#define V3_VIEW_PLATFORM_TYPE_HWND "HWND"
+#define V3_VIEW_PLATFORM_TYPE_NSVIEW "NSView"
+#define V3_VIEW_PLATFORM_TYPE_X11 "X11EmbedWindowID"
+
+#if defined(__APPLE__)
+# define V3_VIEW_PLATFORM_TYPE_NATIVE V3_VIEW_PLATFORM_TYPE_NSVIEW
+#elif defined(_WIN32)
+# define V3_VIEW_PLATFORM_TYPE_NATIVE V3_VIEW_PLATFORM_TYPE_HWND
+#else
+# define V3_VIEW_PLATFORM_TYPE_NATIVE V3_VIEW_PLATFORM_TYPE_X11
+#endif
+
+struct v3_plug_frame;
+
+struct v3_plug_view {
+ struct v3_funknown;
+
+ V3_API v3_result (*is_platform_type_supported)
+ (void *self, const char *platform_type);
+
+ V3_API v3_result (*attached)
+ (void *self, void *parent, const char *platform_type);
+ V3_API v3_result (*removed)(void *self);
+
+ V3_API v3_result (*on_wheel)(void *self, float distance);
+ V3_API v3_result (*on_key_down)
+ (void *self, int16_t key_char, int16_t key_code, int16_t modifiers);
+ V3_API v3_result (*on_key_up)
+ (void *self, int16_t key_char, int16_t key_code, int16_t modifiers);
+
+ V3_API v3_result (*get_size)
+ (void *self, struct v3_view_rect *);
+ V3_API v3_result (*set_size)
+ (void *self, struct v3_view_rect *);
+
+ V3_API v3_result (*on_focus)
+ (void *self, v3_bool state);
+
+ V3_API v3_result (*set_frame)
+ (void *self, struct v3_plug_frame *);
+ V3_API v3_result (*can_resize)(void *self);
+ V3_API v3_result (*check_size_constraint)
+ (void *self, struct v3_view_rect *);
+};
+
+static const v3_tuid v3_plug_view_iid =
+ V3_ID(0x5BC32507, 0xD06049EA, 0xA6151B52, 0x2B755B29);
+
+struct v3_plug_frame {
+ struct v3_funknown;
+
+ V3_API v3_result (*resize_view)
+ (void *self, struct v3_plug_view *, struct v3_view_rect *);
+};
+
+static const v3_tuid v3_plug_frame_iid =
+ V3_ID(0x367FAF01, 0xAFA94693, 0x8D4DA2A0, 0xED0882A3);
+
+/**
+ * steinberg content scaling support
+ * (same IID/iface as presonus view scaling)
+ */
+
+struct v3_plug_view_content_scale_steinberg {
+ struct v3_funknown;
+
+ V3_API v3_result (*set_content_scale_factor)
+ (void *self, float factor);
+};
+
+static const v3_tuid v3_plug_view_content_scale_steinberg_iid =
+ V3_ID(0x65ED9690, 0x8AC44525, 0x8AADEF7A, 0x72EA703F);
+
+/**
+ * support for querying the view to find what control is underneath the mouse
+ */
+
+struct v3_plug_view_param_finder {
+ struct v3_funknown;
+
+ V3_API v3_result (*find_parameter)
+ (void *self, int32_t x, int32_t y, v3_param_id *);
+};
+
+static const v3_tuid v3_plug_view_param_finder_iid =
+ V3_ID(0x0F618302, 0x215D4587, 0xA512073C, 0x77B9D383);