1 /*
2  * Carla Native Plugin API
3  * Copyright (C) 2012-2019 Filipe Coelho <falktx@falktx.com>
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of
8  * the License, or any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * For a full copy of the GNU General Public License see the doc/GPL.txt file.
16  */
17 
18 #ifndef CARLA_NATIVE_H_INCLUDED
19 #define CARLA_NATIVE_H_INCLUDED
20 
21 #include "CarlaDefines.h"
22 #include <stddef.h>
23 #include <stdint.h>
24 
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28 
29 /*!
30  * @defgroup CarlaNativeAPI Carla Native API
31  *
32  * The Carla Native API
33  * @{
34  */
35 
36 typedef void* NativeHostHandle;
37 typedef void* NativePluginHandle;
38 
39 /* ------------------------------------------------------------------------------------------------------------
40  * enums */
41 
42 typedef enum {
43     NATIVE_PLUGIN_CATEGORY_NONE       = 0, /** Null plugin category.                                     */
44     NATIVE_PLUGIN_CATEGORY_SYNTH      = 1, /** A synthesizer or generator.                               */
45     NATIVE_PLUGIN_CATEGORY_DELAY      = 2, /** A delay or reverberator.                                  */
46     NATIVE_PLUGIN_CATEGORY_EQ         = 3, /** An equalizer.                                             */
47     NATIVE_PLUGIN_CATEGORY_FILTER     = 4, /** A filter.                                                 */
48     NATIVE_PLUGIN_CATEGORY_DISTORTION = 5, /** A distortion plugin.                                      */
49     NATIVE_PLUGIN_CATEGORY_DYNAMICS   = 6, /** A 'dynamic' plugin (amplifier, compressor, gate, etc).    */
50     NATIVE_PLUGIN_CATEGORY_MODULATOR  = 7, /** A 'modulator' plugin (chorus, flanger, phaser, etc).      */
51     NATIVE_PLUGIN_CATEGORY_UTILITY    = 8, /** An 'utility' plugin (analyzer, converter, mixer, etc).    */
52     NATIVE_PLUGIN_CATEGORY_OTHER      = 9  /** Misc plugin (used to check if the plugin has a category). */
53 } NativePluginCategory;
54 
55 typedef enum {
56     NATIVE_PLUGIN_IS_RTSAFE            = 1 <<  0,
57     NATIVE_PLUGIN_IS_SYNTH             = 1 <<  1,
58     NATIVE_PLUGIN_HAS_UI               = 1 <<  2,
59     NATIVE_PLUGIN_NEEDS_FIXED_BUFFERS  = 1 <<  3,
60     NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD = 1 <<  4,
61     NATIVE_PLUGIN_NEEDS_UI_OPEN_SAVE   = 1 <<  6,
62     NATIVE_PLUGIN_USES_MULTI_PROGS     = 1 <<  7, /** has 1 program per midi channel         */
63     NATIVE_PLUGIN_USES_PANNING         = 1 <<  8, /** uses stereo balance if unset (default) */
64     NATIVE_PLUGIN_USES_STATE           = 1 <<  9,
65     NATIVE_PLUGIN_USES_TIME            = 1 << 10,
66     NATIVE_PLUGIN_USES_PARENT_ID       = 1 << 11, /** can set transient hint to parent       */
67     NATIVE_PLUGIN_HAS_INLINE_DISPLAY   = 1 << 12,
68     NATIVE_PLUGIN_USES_CONTROL_VOLTAGE = 1 << 13,
69     NATIVE_PLUGIN_REQUESTS_IDLE        = 1 << 15,
70     NATIVE_PLUGIN_USES_UI_SIZE         = 1 << 16
71 } NativePluginHints;
72 
73 typedef enum {
74     NATIVE_PLUGIN_SUPPORTS_NOTHING          = 0,
75     NATIVE_PLUGIN_SUPPORTS_PROGRAM_CHANGES  = 1 << 0, /** handles MIDI programs internally instead of host-exposed/exported */
76     NATIVE_PLUGIN_SUPPORTS_CONTROL_CHANGES  = 1 << 1,
77     NATIVE_PLUGIN_SUPPORTS_CHANNEL_PRESSURE = 1 << 2,
78     NATIVE_PLUGIN_SUPPORTS_NOTE_AFTERTOUCH  = 1 << 3,
79     NATIVE_PLUGIN_SUPPORTS_PITCHBEND        = 1 << 4,
80     NATIVE_PLUGIN_SUPPORTS_ALL_SOUND_OFF    = 1 << 5,
81     NATIVE_PLUGIN_SUPPORTS_EVERYTHING       = (1 << 6)-1
82 } NativePluginSupports;
83 
84 typedef enum {
85     NATIVE_PARAMETER_DESIGNATION_NONE = 0,
86     NATIVE_PARAMETER_DESIGNATION_ENABLED
87 } NativeParameterDesignations;
88 
89 typedef enum {
90     NATIVE_PARAMETER_IS_OUTPUT        = 1 << 0,
91     NATIVE_PARAMETER_IS_ENABLED       = 1 << 1,
92     NATIVE_PARAMETER_IS_AUTOMABLE     = 1 << 2,
93     NATIVE_PARAMETER_IS_BOOLEAN       = 1 << 3,
94     NATIVE_PARAMETER_IS_INTEGER       = 1 << 4,
95     NATIVE_PARAMETER_IS_LOGARITHMIC   = 1 << 5,
96     NATIVE_PARAMETER_USES_SAMPLE_RATE = 1 << 6,
97     NATIVE_PARAMETER_USES_SCALEPOINTS = 1 << 7,
98     NATIVE_PARAMETER_USES_DESIGNATION = 1 << 8
99 } NativeParameterHints;
100 
101 typedef enum {
102     NATIVE_PLUGIN_OPCODE_NULL                = 0, /** nothing                  */
103     NATIVE_PLUGIN_OPCODE_BUFFER_SIZE_CHANGED = 1, /** uses value               */
104     NATIVE_PLUGIN_OPCODE_SAMPLE_RATE_CHANGED = 2, /** uses opt                 */
105     NATIVE_PLUGIN_OPCODE_OFFLINE_CHANGED     = 3, /** uses value (0=off, 1=on) */
106     NATIVE_PLUGIN_OPCODE_UI_NAME_CHANGED     = 4, /** uses ptr                 */
107     NATIVE_PLUGIN_OPCODE_GET_INTERNAL_HANDLE = 5, /** nothing                  */
108     NATIVE_PLUGIN_OPCODE_IDLE                = 6, /** nothing                  */
109     NATIVE_PLUGIN_OPCODE_UI_MIDI_EVENT       = 7, /** uses ptr                 */
110     NATIVE_PLUGIN_OPCODE_HOST_USES_EMBED     = 8  /** nothing                  */
111 } NativePluginDispatcherOpcode;
112 
113 typedef enum {
114     NATIVE_HOST_OPCODE_NULL                  = 0,  /** nothing                                           */
115     NATIVE_HOST_OPCODE_UPDATE_PARAMETER      = 1,  /** uses index, -1 for all                            */
116     NATIVE_HOST_OPCODE_UPDATE_MIDI_PROGRAM   = 2,  /** uses index, -1 for all; may use value for channel */
117     NATIVE_HOST_OPCODE_RELOAD_PARAMETERS     = 3,  /** nothing                                           */
118     NATIVE_HOST_OPCODE_RELOAD_MIDI_PROGRAMS  = 4,  /** nothing                                           */
119     NATIVE_HOST_OPCODE_RELOAD_ALL            = 5,  /** nothing                                           */
120     NATIVE_HOST_OPCODE_UI_UNAVAILABLE        = 6,  /** nothing                                           */
121     NATIVE_HOST_OPCODE_HOST_IDLE             = 7,  /** nothing                                           */
122     NATIVE_HOST_OPCODE_INTERNAL_PLUGIN       = 8,  /** nothing                                           */
123     NATIVE_HOST_OPCODE_QUEUE_INLINE_DISPLAY  = 9,  /** nothing                                           */
124     NATIVE_HOST_OPCODE_UI_TOUCH_PARAMETER    = 10, /** uses index, value as bool                         */
125     NATIVE_HOST_OPCODE_REQUEST_IDLE          = 11, /** nothing                                           */
126     NATIVE_HOST_OPCODE_GET_FILE_PATH         = 12, /** uses ptr as string for file type                  */
127     NATIVE_HOST_OPCODE_UI_RESIZE             = 13, /** uses index and value                              */
128     NATIVE_HOST_OPCODE_PREVIEW_BUFFER_DATA   = 14  /** uses index as type, value as size, and ptr        */
129 } NativeHostDispatcherOpcode;
130 
131 /* ------------------------------------------------------------------------------------------------------------
132  * base structs */
133 
134 typedef struct {
135     const char* label;
136     float value;
137 } NativeParameterScalePoint;
138 
139 typedef struct {
140     float def;
141     float min;
142     float max;
143     float step;
144     float stepSmall;
145     float stepLarge;
146 } NativeParameterRanges;
147 
148 #define PARAMETER_RANGES_DEFAULT_STEP       0.01f
149 #define PARAMETER_RANGES_DEFAULT_STEP_SMALL 0.0001f
150 #define PARAMETER_RANGES_DEFAULT_STEP_LARGE 0.1f
151 
152 typedef struct {
153     NativeParameterHints hints;
154     const char* name;
155     const char* unit;
156     NativeParameterRanges ranges;
157 
158     uint32_t scalePointCount;
159     const NativeParameterScalePoint* scalePoints;
160 
161     const char* comment;
162     const char* groupName;
163 
164     uint designation;
165 } NativeParameter;
166 
167 typedef struct {
168     uint32_t time;
169     uint8_t  port;
170     uint8_t  size;
171     uint8_t  data[4];
172 } NativeMidiEvent;
173 
174 typedef struct {
175     uint32_t bank;
176     uint32_t program;
177     const char* name;
178 } NativeMidiProgram;
179 
180 typedef struct {
181     bool valid;
182 
183     int32_t bar;  /** current bar              */
184     int32_t beat; /** current beat-within-bar  */
185     double  tick; /** current tick-within-beat */
186     double  barStartTick;
187 
188     float beatsPerBar; /** time signature "numerator"  */
189     float beatType;    /** time signature "denominator" */
190 
191     double ticksPerBeat;
192     double beatsPerMinute;
193 } NativeTimeInfoBBT;
194 
195 typedef struct {
196     bool playing;
197     uint64_t frame;
198     uint64_t usecs;
199     NativeTimeInfoBBT bbt;
200 } NativeTimeInfo;
201 
202 typedef struct {
203     unsigned char* data;
204     int width;
205     int height;
206     int stride;
207 } NativeInlineDisplayImageSurface;
208 
209 typedef struct {
210     float minimum, maximum;
211 } NativePortRange;
212 
213 /* ------------------------------------------------------------------------------------------------------------
214  * HostDescriptor */
215 
216 typedef struct {
217     NativeHostHandle handle;
218     const char* resourceDir;
219     const char* uiName;
220     uintptr_t   uiParentId;
221 
222     uint32_t (*get_buffer_size)(NativeHostHandle handle);
223     double   (*get_sample_rate)(NativeHostHandle handle);
224     bool     (*is_offline)(NativeHostHandle handle);
225 
226     const NativeTimeInfo* (*get_time_info)(NativeHostHandle handle);
227     bool                  (*write_midi_event)(NativeHostHandle handle, const NativeMidiEvent* event);
228 
229     void (*ui_parameter_changed)(NativeHostHandle handle, uint32_t index, float value);
230     void (*ui_midi_program_changed)(NativeHostHandle handle, uint8_t channel, uint32_t bank, uint32_t program);
231     void (*ui_custom_data_changed)(NativeHostHandle handle, const char* key, const char* value);
232     void (*ui_closed)(NativeHostHandle handle);
233 
234     const char* (*ui_open_file)(NativeHostHandle handle, bool isDir, const char* title, const char* filter);
235     const char* (*ui_save_file)(NativeHostHandle handle, bool isDir, const char* title, const char* filter);
236 
237     intptr_t (*dispatcher)(NativeHostHandle handle,
238                            NativeHostDispatcherOpcode opcode, int32_t index, intptr_t value, void* ptr, float opt);
239 
240 } NativeHostDescriptor;
241 
242 /* ------------------------------------------------------------------------------------------------------------
243  * PluginDescriptor */
244 
245 typedef struct _NativePluginDescriptor {
246     const NativePluginCategory category;
247     const NativePluginHints hints;
248     const NativePluginSupports supports;
249     const uint32_t audioIns;
250     const uint32_t audioOuts;
251     const uint32_t midiIns;
252     const uint32_t midiOuts;
253     const uint32_t paramIns;
254     const uint32_t paramOuts;
255     const char* const name;
256     const char* const label;
257     const char* const maker;
258     const char* const copyright;
259 
260     NativePluginHandle (*instantiate)(const NativeHostDescriptor* host);
261     void               (*cleanup)(NativePluginHandle handle);
262 
263     uint32_t               (*get_parameter_count)(NativePluginHandle handle);
264     const NativeParameter* (*get_parameter_info)(NativePluginHandle handle, uint32_t index);
265     float                  (*get_parameter_value)(NativePluginHandle handle, uint32_t index);
266 
267     uint32_t                 (*get_midi_program_count)(NativePluginHandle handle);
268     const NativeMidiProgram* (*get_midi_program_info)(NativePluginHandle handle, uint32_t index);
269 
270     void (*set_parameter_value)(NativePluginHandle handle, uint32_t index, float value);
271     void (*set_midi_program)(NativePluginHandle handle, uint8_t channel, uint32_t bank, uint32_t program);
272     void (*set_custom_data)(NativePluginHandle handle, const char* key, const char* value);
273 
274     void (*ui_show)(NativePluginHandle handle, bool show);
275     void (*ui_idle)(NativePluginHandle handle);
276 
277     void (*ui_set_parameter_value)(NativePluginHandle handle, uint32_t index, float value);
278     void (*ui_set_midi_program)(NativePluginHandle handle, uint8_t channel, uint32_t bank, uint32_t program);
279     void (*ui_set_custom_data)(NativePluginHandle handle, const char* key, const char* value);
280 
281     void (*activate)(NativePluginHandle handle);
282     void (*deactivate)(NativePluginHandle handle);
283 
284     /* FIXME for v3.0, use const for the input buffer */
285     void (*process)(NativePluginHandle handle,
286                     float** inBuffer, float** outBuffer, uint32_t frames,
287                     const NativeMidiEvent* midiEvents, uint32_t midiEventCount);
288 
289     char* (*get_state)(NativePluginHandle handle);
290     void  (*set_state)(NativePluginHandle handle, const char* data);
291 
292     intptr_t (*dispatcher)(NativePluginHandle handle,
293                            NativePluginDispatcherOpcode opcode, int32_t index, intptr_t value, void* ptr, float opt);
294 
295     /* placed at the end for backwards compatibility. only valid if NATIVE_PLUGIN_HAS_INLINE_DISPLAY is set */
296     const NativeInlineDisplayImageSurface* (*render_inline_display)(NativePluginHandle handle,
297                                                                     uint32_t width, uint32_t height);
298 
299     /* placed at the end for backwards compatibility. only valid if NATIVE_PLUGIN_USES_CONTROL_VOLTAGE is set */
300     const uint32_t cvIns;
301     const uint32_t cvOuts;
302     const char* (*get_buffer_port_name)(NativePluginHandle handle, uint32_t index, bool isOutput);
303     const NativePortRange* (*get_buffer_port_range)(NativePluginHandle handle, uint32_t index, bool isOutput);
304 
305     /* placed at the end for backwards compatibility. only valid if NATIVE_PLUGIN_USES_UI_SIZE is set */
306     uint16_t ui_width, ui_height;
307 
308 } NativePluginDescriptor;
309 
310 /* ------------------------------------------------------------------------------------------------------------
311  * Register plugin */
312 
313 /** Implemented by host */
314 extern void carla_register_native_plugin(const NativePluginDescriptor* desc);
315 
316 /** Called once on host init */
317 void carla_register_all_native_plugins(void);
318 
319 /** Get meta-data only */
320 CARLA_EXPORT
321 const NativePluginDescriptor* carla_get_native_plugins_data(uint32_t* count);
322 
323 /* ------------------------------------------------------------------------------------------------------------ */
324 
325 /**@}*/
326 
327 #ifdef __cplusplus
328 } /* extern "C" */
329 #endif
330 
331 #endif /* CARLA_NATIVE_H_INCLUDED */
332