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 <stdint.h>
16#include <string.h>
17
18#include "utils/types.h"
19
20#include "zix/sem.h"
21
22#ifdef HAVE_JACK
23# include "weak_libjack.h"
24#endif
25
26#include <gtk/gtk.h>
27
28#include "ext/midilib/src/midifile.h"
29
30typedef struct ChordDescriptor ChordDescriptor;
31
39#define MAX_MIDI_EVENTS 2560
40
44typedef struct MidiEvent
45{
48
50 gint64 systime;
51
54
55 size_t raw_buffer_sz;
56
57} MidiEvent;
58
59typedef struct MidiEvents MidiEvents;
60typedef struct Port Port;
61
67typedef struct MidiEvents
68{
71
74
83 int num_queued_events;
84
86 ZixSem access_sem;
87
89
94typedef struct MidiEventHeader
95{
96 uint64_t time;
97 size_t size;
99
103void
105
111
115static inline void
116midi_event_copy (MidiEvent * dest, MidiEvent * src)
117{
118 memcpy (dest, src, sizeof (MidiEvent));
119}
120
121NONNULL void
122midi_event_set_velocity (MidiEvent * ev, midi_byte_t vel);
123
124void
125midi_event_print (const MidiEvent * ev);
126
127PURE static inline bool
128midi_events_are_equal (const MidiEvent * src, const MidiEvent * dest)
129{
130 return dest->time == src->time && dest->raw_buffer[0] == src->raw_buffer[0]
131 && dest->raw_buffer[1] == src->raw_buffer[1]
132 && dest->raw_buffer[2] == src->raw_buffer[2];
133}
134
135void
136midi_events_print (MidiEvents * self, const int queued);
137
147void
149 MidiEvents * dest,
150 MidiEvents * src,
151 const nframes_t local_offset,
152 const nframes_t nframes,
153 bool queued);
154
161void
163 MidiEvents * dest,
164 MidiEvents * src,
165 const nframes_t local_offset,
166 const nframes_t nframes,
167 bool queued);
168
180OPTIMIZE_O3
181void
183 MidiEvents * dest,
184 MidiEvents * src,
185 int * channels,
186 const nframes_t start_frame,
187 const nframes_t nframes,
188 bool queued);
189
196void
198 MidiEvents * self,
199 midi_byte_t channel,
200 midi_byte_t note_pitch,
201 midi_byte_t velocity,
202 midi_time_t time,
203 int queued);
204
208void
210 MidiEvents * self,
211 const ChordDescriptor * descr,
212 midi_byte_t channel,
213 midi_byte_t velocity,
214 midi_time_t time,
215 bool queued);
216
220void
222 MidiEvents * self,
223 const ChordDescriptor * descr,
224 midi_byte_t channel,
225 midi_time_t time,
226 bool queued);
227
233void
235 MidiEvents * self,
236 midi_byte_t channel,
237 midi_byte_t volume,
238 midi_time_t time,
239 bool queued);
240
248int
249midi_events_has_note_on (MidiEvents * self, int check_main, int check_queued);
250
251static inline bool
252midi_events_has_any (MidiEvents * self, bool check_queued)
253{
254 return (check_queued ? self->num_queued_events : self->num_events) > 0;
255}
256
263void
265 MidiEvents * self,
266 midi_time_t time,
267 midi_byte_t * buf,
268 int buf_size,
269 int queued);
270
277void
279 MidiEvents * self,
280 midi_byte_t channel,
281 midi_byte_t note_pitch,
282 midi_time_t time,
283 int queued);
284
291void
293 MidiEvents * self,
294 midi_byte_t channel,
295 midi_byte_t controller,
296 midi_byte_t control,
297 midi_time_t time,
298 int queued);
299
305void
307 MidiEvents * self,
308 int64_t total_sixteenths,
309 midi_time_t time,
310 bool queued);
311
312void
313midi_events_add_raw (
314 MidiEvents * self,
315 uint8_t * buf,
316 size_t buf_sz,
317 midi_time_t time,
318 bool queued);
319
327void
329 MidiEvents * self,
330 midi_byte_t channel,
331 uint32_t pitchbend,
332 midi_time_t time,
333 bool queued);
334
335void
336midi_events_add_channel_pressure (
337 MidiEvents * self,
338 midi_byte_t channel,
339 midi_byte_t value,
340 midi_time_t time,
341 bool queued);
342
346void
348 MidiEvents * self,
349 midi_byte_t channel,
350 midi_time_t time,
351 bool queued);
352
356NONNULL void
358
362NONNULL void
363midi_events_panic (MidiEvents * self, bool queued);
364
365NONNULL void
366midi_events_write_to_midi_file (
367 const MidiEvents * self,
368 MIDI_FILE * mf,
369 int midi_track);
370
376void
377midi_events_clear (MidiEvents * midi_events, int queued);
378
385void
386midi_events_clear_duplicates (MidiEvents * midi_events, const int queued);
387
391void
393
398int
399midi_events_check_for_note_on (MidiEvents * midi_events, int note, int queued);
400
405int
406midi_events_delete_note_on (MidiEvents * midi_events, int note, int queued);
407
408#ifdef HAVE_JACK
412void
413midi_events_copy_to_jack (
414 MidiEvents * self,
415 const nframes_t local_start_frames,
416 const nframes_t nframes,
417 void * buff);
418#endif
419
423void
424midi_events_sort (MidiEvents * self, const bool queued);
425
430void
432 MidiEvents * self,
433 const int queued,
434 const midi_byte_t channel);
435
436void
437midi_events_delete_event (
438 MidiEvents * events,
439 const MidiEvent * ev,
440 const bool queued);
441
448void
449midi_events_panic_all (const bool queued);
450
454void
456
461#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:39
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:35
uint32_t midi_time_t
MIDI time in global frames.
Definition types.h:41
uint8_t midi_byte_t
MIDI byte.
Definition types.h:32
String utilities.
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:95
Timed MIDI event.
Definition midi_event.h:45
midi_byte_t raw_buffer[3]
Raw MIDI data.
Definition midi_event.h:53
gint64 systime
Time using g_get_monotonic_time ().
Definition midi_event.h:50
midi_time_t time
Time of the MIDI event, in frames from the start of the current cycle.
Definition midi_event.h:47
Container for passing midi events through ports.
Definition midi_event.h:68
int num_events
Event count.
Definition midi_event.h:70
MidiEvent events[MAX_MIDI_EVENTS]
Events to use in this cycle.
Definition midi_event.h:73
ZixSem access_sem
Semaphore for exclusive read/write.
Definition midi_event.h:86
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:82
Must ONLY be created via port_new()
Definition port.h:138
Custom types.