Zrythm
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
midi_event.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: © 2018-2023 Alexandros Theodotou <alex@zrythm.org>
2// SPDX-License-Identifier: LicenseRef-ZrythmLicense
3
10#ifndef __AUDIO_MIDI_EVENT_H__
11#define __AUDIO_MIDI_EVENT_H__
12
13#include "zrythm-config.h"
14
15#include <cstdint>
16#include <cstring>
17
18#include "utils/types.h"
19
20#include "ext/midilib/src/midifile.h"
21#include "gtk_wrapper.h"
22#include "zix/sem.h"
23
24typedef struct ChordDescriptor ChordDescriptor;
25
33#define MAX_MIDI_EVENTS 2560
34
38typedef struct MidiEvent
39{
42
44 gint64 systime;
45
48
49 size_t raw_buffer_sz;
50
51} MidiEvent;
52
53typedef struct MidiEvents MidiEvents;
54typedef struct Port Port;
55
61typedef struct MidiEvents
62{
65
68
77 int num_queued_events;
78
80 ZixSem access_sem;
81
83
88typedef struct MidiEventHeader
89{
90 uint64_t time;
91 size_t size;
93
97void
99
105
109static inline void
110midi_event_copy (MidiEvent * dest, MidiEvent * src)
111{
112 memcpy (dest, src, sizeof (MidiEvent));
113}
114
115NONNULL void
116midi_event_set_velocity (MidiEvent * ev, midi_byte_t vel);
117
118void
119midi_event_print (const MidiEvent * ev);
120
121static inline bool
122midi_events_are_equal (const MidiEvent * src, const MidiEvent * dest)
123{
124 return dest->time == src->time && dest->raw_buffer[0] == src->raw_buffer[0]
125 && dest->raw_buffer[1] == src->raw_buffer[1]
126 && dest->raw_buffer[2] == src->raw_buffer[2];
127}
128
129void
130midi_events_print (MidiEvents * self, const int queued);
131
141void
143 MidiEvents * dest,
144 MidiEvents * src,
145 const nframes_t local_offset,
146 const nframes_t nframes,
147 bool queued);
148
155void
157 MidiEvents * dest,
158 MidiEvents * src,
159 const nframes_t local_offset,
160 const nframes_t nframes,
161 bool queued);
162
174OPTIMIZE_O3
175void
177 MidiEvents * dest,
178 MidiEvents * src,
179 int * channels,
180 const nframes_t start_frame,
181 const nframes_t nframes,
182 bool queued);
183
190void
192 MidiEvents * self,
193 midi_byte_t channel,
194 midi_byte_t note_pitch,
195 midi_byte_t velocity,
196 midi_time_t time,
197 int queued);
198
202void
204 MidiEvents * self,
205 const ChordDescriptor * descr,
206 midi_byte_t channel,
207 midi_byte_t velocity,
208 midi_time_t time,
209 bool queued);
210
214void
216 MidiEvents * self,
217 const ChordDescriptor * descr,
218 midi_byte_t channel,
219 midi_time_t time,
220 bool queued);
221
227void
229 MidiEvents * self,
230 midi_byte_t channel,
231 midi_byte_t volume,
232 midi_time_t time,
233 bool queued);
234
242int
243midi_events_has_note_on (MidiEvents * self, int check_main, int check_queued);
244
245static inline bool
246midi_events_has_any (MidiEvents * self, bool check_queued)
247{
248 return (check_queued ? self->num_queued_events : self->num_events) > 0;
249}
250
257void
259 MidiEvents * self,
260 midi_time_t time,
261 midi_byte_t * buf,
262 int buf_size,
263 int queued);
264
271void
273 MidiEvents * self,
274 midi_byte_t channel,
275 midi_byte_t note_pitch,
276 midi_time_t time,
277 int queued);
278
285void
287 MidiEvents * self,
288 midi_byte_t channel,
289 midi_byte_t controller,
290 midi_byte_t control,
291 midi_time_t time,
292 int queued);
293
299void
301 MidiEvents * self,
302 int64_t total_sixteenths,
303 midi_time_t time,
304 bool queued);
305
306void
307midi_events_add_raw (
308 MidiEvents * self,
309 uint8_t * buf,
310 size_t buf_sz,
311 midi_time_t time,
312 bool queued);
313
321void
323 MidiEvents * self,
324 midi_byte_t channel,
325 uint32_t pitchbend,
326 midi_time_t time,
327 bool queued);
328
329void
330midi_events_add_channel_pressure (
331 MidiEvents * self,
332 midi_byte_t channel,
333 midi_byte_t value,
334 midi_time_t time,
335 bool queued);
336
340void
342 MidiEvents * self,
343 midi_byte_t channel,
344 midi_time_t time,
345 bool queued);
346
350NONNULL void
352
356NONNULL void
357midi_events_panic (MidiEvents * self, bool queued);
358
359NONNULL void
360midi_events_write_to_midi_file (
361 const MidiEvents * self,
362 MIDI_FILE * mf,
363 int midi_track);
364
370void
371midi_events_clear (MidiEvents * midi_events, int queued);
372
379void
380midi_events_clear_duplicates (MidiEvents * midi_events, const int queued);
381
385void
387
392int
393midi_events_check_for_note_on (MidiEvents * midi_events, int note, int queued);
394
399int
400midi_events_delete_note_on (MidiEvents * midi_events, int note, int queued);
401
402#ifdef HAVE_JACK
406void
407midi_events_copy_to_jack (
408 MidiEvents * self,
409 const nframes_t local_start_frames,
410 const nframes_t nframes,
411 void * buff);
412#endif
413
417void
418midi_events_sort (MidiEvents * self, const bool queued);
419
424void
426 MidiEvents * self,
427 const int queued,
428 const midi_byte_t channel);
429
430void
431midi_events_delete_event (
432 MidiEvents * events,
433 const MidiEvent * ev,
434 const bool queued);
435
442void
443midi_events_panic_all (const bool queued);
444
448void
450
455#endif
void midi_events_clear(MidiEvents *midi_events, int queued)
Clears midi events.
void midi_events_add_control_change(MidiEvents *self, midi_byte_t channel, midi_byte_t controller, midi_byte_t control, midi_time_t time, int queued)
Adds a control event to the given MidiEvents.
MidiEvents * midi_events_new(void)
Allocates and inits a MidiEvents struct.
int midi_events_delete_note_on(MidiEvents *midi_events, int note, int queued)
Deletes the midi event with a note on signal from the queue, and returns if it deleted or not.
void midi_events_append(MidiEvents *dest, MidiEvents *src, const nframes_t local_offset, const nframes_t nframes, bool queued)
Appends the events from src to dest.
void midi_events_sort(MidiEvents *self, const bool queued)
Sorts the MidiEvents by time.
NONNULL void midi_events_panic_without_lock(MidiEvents *self, bool queued)
Adds a note off message to every MIDI channel.
void midi_events_panic_all(const bool queued)
Queues MIDI note off to event queues.
void midi_events_free(MidiEvents *self)
Frees the MIDI events.
void midi_events_add_note_offs_from_chord_descr(MidiEvents *self, const ChordDescriptor *descr, midi_byte_t channel, midi_time_t time, bool queued)
Adds a note off for each note in the chord.
void midi_events_clear_duplicates(MidiEvents *midi_events, const int queued)
Clears duplicates.
int midi_events_has_note_on(MidiEvents *self, int check_main, int check_queued)
Returrns if the MidiEvents have any note on events.
void midi_events_add_event_from_buf(MidiEvents *self, midi_time_t time, midi_byte_t *buf, int buf_size, int queued)
Parses a MidiEvent from a raw MIDI buffer.
NONNULL void midi_events_panic(MidiEvents *self, bool queued)
Must only be called from the UI thread.
void midi_events_init(MidiEvents *self)
Inits the MidiEvents struct.
void midi_events_transform_chord_and_append(MidiEvents *dest, MidiEvents *src, const nframes_t local_offset, const nframes_t nframes, bool queued)
Transforms the given MIDI input to the MIDI notes of the corresponding chord.
void midi_events_add_note_ons_from_chord_descr(MidiEvents *self, const ChordDescriptor *descr, midi_byte_t channel, midi_byte_t velocity, midi_time_t time, bool queued)
Adds a note on for each note in the chord.
int midi_events_check_for_note_on(MidiEvents *midi_events, int note, int queued)
Returns if a note on event for the given note exists in the given events.
#define MAX_MIDI_EVENTS
Max events to hold in queues.
Definition midi_event.h:33
void midi_events_add_cc_volume(MidiEvents *self, midi_byte_t channel, midi_byte_t volume, midi_time_t time, bool queued)
Add CC volume event.
void midi_events_add_note_off(MidiEvents *self, midi_byte_t channel, midi_byte_t note_pitch, midi_time_t time, int queued)
Adds a note off event to the given MidiEvents.
void midi_events_dequeue(MidiEvents *midi_events)
Copies the queue contents to the original struct.
void midi_events_add_pitchbend(MidiEvents *self, midi_byte_t channel, uint32_t pitchbend, midi_time_t time, bool queued)
Adds a control event to the given MidiEvents.
OPTIMIZE_O3 void midi_events_append_w_filter(MidiEvents *dest, MidiEvents *src, int *channels, const nframes_t start_frame, const nframes_t nframes, bool queued)
Appends the events from src to dest.
void midi_events_add_all_notes_off(MidiEvents *self, midi_byte_t channel, midi_time_t time, bool queued)
Queues MIDI note off to event queue.
void midi_events_add_note_on(MidiEvents *self, midi_byte_t channel, midi_byte_t note_pitch, midi_byte_t velocity, midi_time_t time, int queued)
Adds a note on event to the given MidiEvents.
void midi_events_add_song_pos(MidiEvents *self, int64_t total_sixteenths, midi_time_t time, bool queued)
Adds a song position event to the queue.
void midi_events_set_channel(MidiEvents *self, const int queued, const midi_byte_t channel)
Sets the given MIDI channel on all applicable MIDI events.
uint32_t nframes_t
Frame count.
Definition types.h:39
uint32_t midi_time_t
MIDI time in global frames.
Definition types.h:45
uint8_t midi_byte_t
MIDI byte.
Definition types.h:36
A ChordDescriptor describes a chord and is not linked to any specific object by itself.
Used by Windows MME and RtMidi when adding events to the ring.
Definition midi_event.h:89
Timed MIDI event.
Definition midi_event.h:39
midi_byte_t raw_buffer[3]
Raw MIDI data.
Definition midi_event.h:47
gint64 systime
Time using g_get_monotonic_time ().
Definition midi_event.h:44
midi_time_t time
Time of the MIDI event, in frames from the start of the current cycle.
Definition midi_event.h:41
Container for passing midi events through ports.
Definition midi_event.h:62
int num_events
Event count.
Definition midi_event.h:64
MidiEvent events[MAX_MIDI_EVENTS]
Events to use in this cycle.
Definition midi_event.h:67
ZixSem access_sem
Semaphore for exclusive read/write.
Definition midi_event.h:80
MidiEvent queued_events[MAX_MIDI_EVENTS]
For queueing events from the GUI or from hardware, since they run in different threads.
Definition midi_event.h:76
Must ONLY be created via port_new()
Definition port.h:136
Custom types.