File: events.h

package info (click to toggle)
lsp-plugins 1.2.5-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 91,856 kB
  • sloc: cpp: 427,831; xml: 57,779; makefile: 9,961; php: 1,005; sh: 18
file content (286 lines) | stat: -rw-r--r-- 10,002 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
#pragma once

#include "private/std.h"
#include "fixedpoint.h"
#include "id.h"

#ifdef __cplusplus
extern "C" {
#endif

// event header
// must be the first attribute of the event
typedef struct clap_event_header {
   uint32_t size;     // event size including this header, eg: sizeof (clap_event_note)
   uint32_t time;     // sample offset within the buffer for this event
   uint16_t space_id; // event space, see clap_host_event_registry
   uint16_t type;     // event type
   uint32_t flags;    // see clap_event_flags
} clap_event_header_t;

// The clap core event space
static const CLAP_CONSTEXPR uint16_t CLAP_CORE_EVENT_SPACE_ID = 0;

enum clap_event_flags {
   // Indicate a live user event, for example a user turning a physical knob
   // or playing a physical key.
   CLAP_EVENT_IS_LIVE = 1 << 0,

   // Indicate that the event should not be recorded.
   // For example this is useful when a parameter changes because of a MIDI CC,
   // because if the host records both the MIDI CC automation and the parameter
   // automation there will be a conflict.
   CLAP_EVENT_DONT_RECORD = 1 << 1,
};

// Some of the following events overlap, a note on can be expressed with:
// - CLAP_EVENT_NOTE_ON
// - CLAP_EVENT_MIDI
// - CLAP_EVENT_MIDI2
//
// The preferred way of sending a note event is to use CLAP_EVENT_NOTE_*.
//
// The same event must not be sent twice: it is forbidden to send a the same note on
// encoded with both CLAP_EVENT_NOTE_ON and CLAP_EVENT_MIDI.
//
// The plugins are encouraged to be able to handle note events encoded as raw midi or midi2,
// or implement clap_plugin_event_filter and reject raw midi and midi2 events.
enum {
   // NOTE_ON and NOTE_OFF represent a key pressed and key released event, respectively.
   // A NOTE_ON with a velocity of 0 is valid and should not be interpreted as a NOTE_OFF.
   //
   // NOTE_CHOKE is meant to choke the voice(s), like in a drum machine when a closed hihat
   // chokes an open hihat. This event can be sent by the host to the plugin. Here are two use
   // cases:
   // - a plugin is inside a drum pad in Bitwig Studio's drum machine, and this pad is choked by
   //   another one
   // - the user double clicks the DAW's stop button in the transport which then stops the sound on
   //   every tracks
   //
   // NOTE_END is sent by the plugin to the host. The port, channel, key and note_id are those given
   // by the host in the NOTE_ON event. In other words, this event is matched against the
   // plugin's note input port.
   // NOTE_END is useful to help the host to match the plugin's voice life time.
   //
   // When using polyphonic modulations, the host has to allocate and release voices for its
   // polyphonic modulator. Yet only the plugin effectively knows when the host should terminate
   // a voice. NOTE_END solves that issue in a non-intrusive and cooperative way.
   //
   // CLAP assumes that the host will allocate a unique voice on NOTE_ON event for a given port,
   // channel and key. This voice will run until the plugin will instruct the host to terminate
   // it by sending a NOTE_END event.
   //
   // Consider the following sequence:
   // - process()
   //    Host->Plugin NoteOn(port:0, channel:0, key:16, time:t0)
   //    Host->Plugin NoteOn(port:0, channel:0, key:64, time:t0)
   //    Host->Plugin NoteOff(port:0, channel:0, key:16, t1)
   //    Host->Plugin NoteOff(port:0, channel:0, key:64, t1)
   //    # on t2, both notes did terminate
   //    Host->Plugin NoteOn(port:0, channel:0, key:64, t3)
   //    # Here the plugin finished processing all the frames and will tell the host
   //    # to terminate the voice on key 16 but not 64, because a note has been started at t3
   //    Plugin->Host NoteEnd(port:0, channel:0, key:16, time:ignored)
   //
   // These four events use clap_event_note.
   CLAP_EVENT_NOTE_ON,
   CLAP_EVENT_NOTE_OFF,
   CLAP_EVENT_NOTE_CHOKE,
   CLAP_EVENT_NOTE_END,

   // Represents a note expression.
   // Uses clap_event_note_expression.
   CLAP_EVENT_NOTE_EXPRESSION,

   // PARAM_VALUE sets the parameter's value; uses clap_event_param_value.
   // PARAM_MOD sets the parameter's modulation amount; uses clap_event_param_mod.
   //
   // The value heard is: param_value + param_mod.
   //
   // In case of a concurrent global value/modulation versus a polyphonic one,
   // the voice should only use the polyphonic one and the polyphonic modulation
   // amount will already include the monophonic signal.
   CLAP_EVENT_PARAM_VALUE,
   CLAP_EVENT_PARAM_MOD,

   // Indicates that the user started or finished adjusting a knob.
   // This is not mandatory to wrap parameter changes with gesture events, but this improves
   // the user experience a lot when recording automation or overriding automation playback.
   // Uses clap_event_param_gesture.
   CLAP_EVENT_PARAM_GESTURE_BEGIN,
   CLAP_EVENT_PARAM_GESTURE_END,

   CLAP_EVENT_TRANSPORT,  // update the transport info; clap_event_transport
   CLAP_EVENT_MIDI,       // raw midi event; clap_event_midi
   CLAP_EVENT_MIDI_SYSEX, // raw midi sysex event; clap_event_midi_sysex
   CLAP_EVENT_MIDI2,      // raw midi 2 event; clap_event_midi2
};

// Note on, off, end and choke events.
// In the case of note choke or end events:
// - the velocity is ignored.
// - key and channel are used to match active notes, a value of -1 matches all.
typedef struct clap_event_note {
   clap_event_header_t header;

   int32_t note_id; // -1 if unspecified, otherwise >=0
   int16_t port_index;
   int16_t channel;  // 0..15
   int16_t key;      // 0..127
   double  velocity; // 0..1
} clap_event_note_t;

enum {
   // with 0 < x <= 4, plain = 20 * log(x)
   CLAP_NOTE_EXPRESSION_VOLUME,

   // pan, 0 left, 0.5 center, 1 right
   CLAP_NOTE_EXPRESSION_PAN,

   // relative tuning in semitone, from -120 to +120
   CLAP_NOTE_EXPRESSION_TUNING,

   // 0..1
   CLAP_NOTE_EXPRESSION_VIBRATO,
   CLAP_NOTE_EXPRESSION_EXPRESSION,
   CLAP_NOTE_EXPRESSION_BRIGHTNESS,
   CLAP_NOTE_EXPRESSION_PRESSURE,
};
typedef int32_t clap_note_expression;

typedef struct clap_event_note_expression {
   clap_event_header_t header;

   clap_note_expression expression_id;

   // target a specific note_id, port, key and channel, -1 for global
   int32_t note_id;
   int16_t port_index;
   int16_t channel;
   int16_t key;

   double value; // see expression for the range
} clap_event_note_expression_t;

typedef struct clap_event_param_value {
   clap_event_header_t header;

   // target parameter
   clap_id param_id; // @ref clap_param_info.id
   void   *cookie;   // @ref clap_param_info.cookie

   // target a specific note_id, port, key and channel, -1 for global
   int32_t note_id;
   int16_t port_index;
   int16_t channel;
   int16_t key;

   double value;
} clap_event_param_value_t;

typedef struct clap_event_param_mod {
   clap_event_header_t header;

   // target parameter
   clap_id param_id; // @ref clap_param_info.id
   void   *cookie;   // @ref clap_param_info.cookie

   // target a specific note_id, port, key and channel, -1 for global
   int32_t note_id;
   int16_t port_index;
   int16_t channel;
   int16_t key;

   double amount; // modulation amount
} clap_event_param_mod_t;

typedef struct clap_event_param_gesture {
   clap_event_header_t header;

   // target parameter
   clap_id param_id; // @ref clap_param_info.id
} clap_event_param_gesture_t;

enum clap_transport_flags {
   CLAP_TRANSPORT_HAS_TEMPO = 1 << 0,
   CLAP_TRANSPORT_HAS_BEATS_TIMELINE = 1 << 1,
   CLAP_TRANSPORT_HAS_SECONDS_TIMELINE = 1 << 2,
   CLAP_TRANSPORT_HAS_TIME_SIGNATURE = 1 << 3,
   CLAP_TRANSPORT_IS_PLAYING = 1 << 4,
   CLAP_TRANSPORT_IS_RECORDING = 1 << 5,
   CLAP_TRANSPORT_IS_LOOP_ACTIVE = 1 << 6,
   CLAP_TRANSPORT_IS_WITHIN_PRE_ROLL = 1 << 7,
};

typedef struct clap_event_transport {
   clap_event_header_t header;

   uint32_t flags; // see clap_transport_flags

   clap_beattime song_pos_beats;   // position in beats
   clap_sectime  song_pos_seconds; // position in seconds

   double tempo;     // in bpm
   double tempo_inc; // tempo increment for each samples and until the next
                     // time info event

   clap_beattime loop_start_beats;
   clap_beattime loop_end_beats;
   clap_sectime  loop_start_seconds;
   clap_sectime  loop_end_seconds;

   clap_beattime bar_start;  // start pos of the current bar
   int32_t       bar_number; // bar at song pos 0 has the number 0

   uint16_t tsig_num;   // time signature numerator
   uint16_t tsig_denom; // time signature denominator
} clap_event_transport_t;

typedef struct clap_event_midi {
   clap_event_header_t header;

   uint16_t port_index;
   uint8_t  data[3];
} clap_event_midi_t;

typedef struct clap_event_midi_sysex {
   clap_event_header_t header;

   uint16_t       port_index;
   const uint8_t *buffer; // midi buffer
   uint32_t       size;
} clap_event_midi_sysex_t;

// While it is possible to use a series of midi2 event to send a sysex,
// prefer clap_event_midi_sysex if possible for efficiency.
typedef struct clap_event_midi2 {
   clap_event_header_t header;

   uint16_t port_index;
   uint32_t data[4];
} clap_event_midi2_t;

// Input event list, events must be sorted by time.
typedef struct clap_input_events {
   void *ctx; // reserved pointer for the list

   // returns the number of events in the list
   uint32_t(CLAP_ABI *size)(const struct clap_input_events *list);

   // Don't free the returned event, it belongs to the list
   const clap_event_header_t *(CLAP_ABI *get)(const struct clap_input_events *list, uint32_t index);
} clap_input_events_t;

// Output event list, events must be sorted by time.
typedef struct clap_output_events {
   void *ctx; // reserved pointer for the list

   // Pushes a copy of the event
   // returns false if the event could not be pushed to the queue (out of memory?)
   bool(CLAP_ABI *try_push)(const struct clap_output_events *list,
                            const clap_event_header_t       *event);
} clap_output_events_t;

#ifdef __cplusplus
}
#endif