DPF

DISTRHO Plugin Framework
Log | Files | Refs | Submodules | README | LICENSE

events.h (9996B)


      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