comparison DPF-Prymula-audioplugins/dpf/distrho/src/clap/events.h @ 3:84e66ea83026

DPF-Prymula-audioplugins-0.231015-2
author prymula <prymula76@outlook.com>
date Mon, 16 Oct 2023 21:53:34 +0200
parents
children
comparison
equal deleted inserted replaced
2:cf2cb71d31dd 3:84e66ea83026
1 #pragma once
2
3 #include "private/std.h"
4 #include "fixedpoint.h"
5 #include "id.h"
6
7 #ifdef __cplusplus
8 extern "C" {
9 #endif
10
11 // event header
12 // must be the first attribute of the event
13 typedef struct clap_event_header {
14 uint32_t size; // event size including this header, eg: sizeof (clap_event_note)
15 uint32_t time; // sample offset within the buffer for this event
16 uint16_t space_id; // event space, see clap_host_event_registry
17 uint16_t type; // event type
18 uint32_t flags; // see clap_event_flags
19 } clap_event_header_t;
20
21 // The clap core event space
22 static const CLAP_CONSTEXPR uint16_t CLAP_CORE_EVENT_SPACE_ID = 0;
23
24 enum clap_event_flags {
25 // Indicate a live user event, for example a user turning a physical knob
26 // or playing a physical key.
27 CLAP_EVENT_IS_LIVE = 1 << 0,
28
29 // Indicate that the event should not be recorded.
30 // For example this is useful when a parameter changes because of a MIDI CC,
31 // because if the host records both the MIDI CC automation and the parameter
32 // automation there will be a conflict.
33 CLAP_EVENT_DONT_RECORD = 1 << 1,
34 };
35
36 // Some of the following events overlap, a note on can be expressed with:
37 // - CLAP_EVENT_NOTE_ON
38 // - CLAP_EVENT_MIDI
39 // - CLAP_EVENT_MIDI2
40 //
41 // The preferred way of sending a note event is to use CLAP_EVENT_NOTE_*.
42 //
43 // The same event must not be sent twice: it is forbidden to send a the same note on
44 // encoded with both CLAP_EVENT_NOTE_ON and CLAP_EVENT_MIDI.
45 //
46 // The plugins are encouraged to be able to handle note events encoded as raw midi or midi2,
47 // or implement clap_plugin_event_filter and reject raw midi and midi2 events.
48 enum {
49 // NOTE_ON and NOTE_OFF represent a key pressed and key released event, respectively.
50 // A NOTE_ON with a velocity of 0 is valid and should not be interpreted as a NOTE_OFF.
51 //
52 // NOTE_CHOKE is meant to choke the voice(s), like in a drum machine when a closed hihat
53 // chokes an open hihat. This event can be sent by the host to the plugin. Here are two use cases:
54 // - a plugin is inside a drum pad in Bitwig Studio's drum machine, and this pad is choked by
55 // another one
56 // - the user double clicks the DAW's stop button in the transport which then stops the sound on
57 // every tracks
58 //
59 // NOTE_END is sent by the plugin to the host. The port, channel, key and note_id are those given
60 // by the host in the NOTE_ON event. In other words, this event is matched against the
61 // plugin's note input port.
62 // NOTE_END is useful to help the host to match the plugin's voice life time.
63 //
64 // When using polyphonic modulations, the host has to allocate and release voices for its
65 // polyphonic modulator. Yet only the plugin effectively knows when the host should terminate
66 // a voice. NOTE_END solves that issue in a non-intrusive and cooperative way.
67 //
68 // CLAP assumes that the host will allocate a unique voice on NOTE_ON event for a given port,
69 // channel and key. This voice will run until the plugin will instruct the host to terminate
70 // it by sending a NOTE_END event.
71 //
72 // Consider the following sequence:
73 // - process()
74 // Host->Plugin NoteOn(port:0, channel:0, key:16, time:t0)
75 // Host->Plugin NoteOn(port:0, channel:0, key:64, time:t0)
76 // Host->Plugin NoteOff(port:0, channel:0, key:16, t1)
77 // Host->Plugin NoteOff(port:0, channel:0, key:64, t1)
78 // # on t2, both notes did terminate
79 // Host->Plugin NoteOn(port:0, channel:0, key:64, t3)
80 // # Here the plugin finished processing all the frames and will tell the host
81 // # to terminate the voice on key 16 but not 64, because a note has been started at t3
82 // Plugin->Host NoteEnd(port:0, channel:0, key:16, time:ignored)
83 //
84 // These four events use clap_event_note.
85 CLAP_EVENT_NOTE_ON,
86 CLAP_EVENT_NOTE_OFF,
87 CLAP_EVENT_NOTE_CHOKE,
88 CLAP_EVENT_NOTE_END,
89
90 // Represents a note expression.
91 // Uses clap_event_note_expression.
92 CLAP_EVENT_NOTE_EXPRESSION,
93
94 // PARAM_VALUE sets the parameter's value; uses clap_event_param_value.
95 // PARAM_MOD sets the parameter's modulation amount; uses clap_event_param_mod.
96 //
97 // The value heard is: param_value + param_mod.
98 //
99 // In case of a concurrent global value/modulation versus a polyphonic one,
100 // the voice should only use the polyphonic one and the polyphonic modulation
101 // amount will already include the monophonic signal.
102 CLAP_EVENT_PARAM_VALUE,
103 CLAP_EVENT_PARAM_MOD,
104
105 // Indicates that the user started or finished adjusting a knob.
106 // This is not mandatory to wrap parameter changes with gesture events, but this improves
107 // the user experience a lot when recording automation or overriding automation playback.
108 // Uses clap_event_param_gesture.
109 CLAP_EVENT_PARAM_GESTURE_BEGIN,
110 CLAP_EVENT_PARAM_GESTURE_END,
111
112 CLAP_EVENT_TRANSPORT, // update the transport info; clap_event_transport
113 CLAP_EVENT_MIDI, // raw midi event; clap_event_midi
114 CLAP_EVENT_MIDI_SYSEX, // raw midi sysex event; clap_event_midi_sysex
115 CLAP_EVENT_MIDI2, // raw midi 2 event; clap_event_midi2
116 };
117
118 // Note on, off, end and choke events.
119 // In the case of note choke or end events:
120 // - the velocity is ignored.
121 // - key and channel are used to match active notes, a value of -1 matches all.
122 typedef struct clap_event_note {
123 clap_event_header_t header;
124
125 int32_t note_id; // -1 if unspecified, otherwise >=0
126 int16_t port_index;
127 int16_t channel; // 0..15
128 int16_t key; // 0..127
129 double velocity; // 0..1
130 } clap_event_note_t;
131
132 enum {
133 // with 0 < x <= 4, plain = 20 * log(x)
134 CLAP_NOTE_EXPRESSION_VOLUME,
135
136 // pan, 0 left, 0.5 center, 1 right
137 CLAP_NOTE_EXPRESSION_PAN,
138
139 // relative tuning in semitone, from -120 to +120
140 CLAP_NOTE_EXPRESSION_TUNING,
141
142 // 0..1
143 CLAP_NOTE_EXPRESSION_VIBRATO,
144 CLAP_NOTE_EXPRESSION_EXPRESSION,
145 CLAP_NOTE_EXPRESSION_BRIGHTNESS,
146 CLAP_NOTE_EXPRESSION_PRESSURE,
147 };
148 typedef int32_t clap_note_expression;
149
150 typedef struct clap_event_note_expression {
151 clap_event_header_t header;
152
153 clap_note_expression expression_id;
154
155 // target a specific note_id, port, key and channel, -1 for global
156 int32_t note_id;
157 int16_t port_index;
158 int16_t channel;
159 int16_t key;
160
161 double value; // see expression for the range
162 } clap_event_note_expression_t;
163
164 typedef struct clap_event_param_value {
165 clap_event_header_t header;
166
167 // target parameter
168 clap_id param_id; // @ref clap_param_info.id
169 void *cookie; // @ref clap_param_info.cookie
170
171 // target a specific note_id, port, key and channel, -1 for global
172 int32_t note_id;
173 int16_t port_index;
174 int16_t channel;
175 int16_t key;
176
177 double value;
178 } clap_event_param_value_t;
179
180 typedef struct clap_event_param_mod {
181 clap_event_header_t header;
182
183 // target parameter
184 clap_id param_id; // @ref clap_param_info.id
185 void *cookie; // @ref clap_param_info.cookie
186
187 // target a specific note_id, port, key and channel, -1 for global
188 int32_t note_id;
189 int16_t port_index;
190 int16_t channel;
191 int16_t key;
192
193 double amount; // modulation amount
194 } clap_event_param_mod_t;
195
196 typedef struct clap_event_param_gesture {
197 clap_event_header_t header;
198
199 // target parameter
200 clap_id param_id; // @ref clap_param_info.id
201 } clap_event_param_gesture_t;
202
203 enum clap_transport_flags {
204 CLAP_TRANSPORT_HAS_TEMPO = 1 << 0,
205 CLAP_TRANSPORT_HAS_BEATS_TIMELINE = 1 << 1,
206 CLAP_TRANSPORT_HAS_SECONDS_TIMELINE = 1 << 2,
207 CLAP_TRANSPORT_HAS_TIME_SIGNATURE = 1 << 3,
208 CLAP_TRANSPORT_IS_PLAYING = 1 << 4,
209 CLAP_TRANSPORT_IS_RECORDING = 1 << 5,
210 CLAP_TRANSPORT_IS_LOOP_ACTIVE = 1 << 6,
211 CLAP_TRANSPORT_IS_WITHIN_PRE_ROLL = 1 << 7,
212 };
213
214 typedef struct clap_event_transport {
215 clap_event_header_t header;
216
217 uint32_t flags; // see clap_transport_flags
218
219 clap_beattime song_pos_beats; // position in beats
220 clap_sectime song_pos_seconds; // position in seconds
221
222 double tempo; // in bpm
223 double tempo_inc; // tempo increment for each samples and until the next
224 // time info event
225
226 clap_beattime loop_start_beats;
227 clap_beattime loop_end_beats;
228 clap_sectime loop_start_seconds;
229 clap_sectime loop_end_seconds;
230
231 clap_beattime bar_start; // start pos of the current bar
232 int32_t bar_number; // bar at song pos 0 has the number 0
233
234 uint16_t tsig_num; // time signature numerator
235 uint16_t tsig_denom; // time signature denominator
236 } clap_event_transport_t;
237
238 typedef struct clap_event_midi {
239 clap_event_header_t header;
240
241 uint16_t port_index;
242 uint8_t data[3];
243 } clap_event_midi_t;
244
245 typedef struct clap_event_midi_sysex {
246 clap_event_header_t header;
247
248 uint16_t port_index;
249 const uint8_t *buffer; // midi buffer
250 uint32_t size;
251 } clap_event_midi_sysex_t;
252
253 // While it is possible to use a series of midi2 event to send a sysex,
254 // prefer clap_event_midi_sysex if possible for efficiency.
255 typedef struct clap_event_midi2 {
256 clap_event_header_t header;
257
258 uint16_t port_index;
259 uint32_t data[4];
260 } clap_event_midi2_t;
261
262 // Input event list, events must be sorted by time.
263 typedef struct clap_input_events {
264 void *ctx; // reserved pointer for the list
265
266 // returns the number of events in the list
267 uint32_t(CLAP_ABI *size)(const struct clap_input_events *list);
268
269 // Don't free the returned event, it belongs to the list
270 const clap_event_header_t *(CLAP_ABI *get)(const struct clap_input_events *list, uint32_t index);
271 } clap_input_events_t;
272
273 // Output event list, events must be sorted by time.
274 typedef struct clap_output_events {
275 void *ctx; // reserved pointer for the list
276
277 // Pushes a copy of the event
278 // returns false if the event could not be pushed to the queue (out of memory?)
279 bool(CLAP_ABI *try_push)(const struct clap_output_events *list,
280 const clap_event_header_t *event);
281 } clap_output_events_t;
282
283 #ifdef __cplusplus
284 }
285 #endif