10#include "utils/types.h"
12#include <crill/spin_mutex.h>
16class MidiMessageSequence;
24constexpr int MAX_MIDI_EVENTS = 2560;
33 MidiEvent () =
default;
39 : raw_buffer_sz_ (3),
time_ (time)
54 uint_fast8_t raw_buffer_sz_ = 0;
69 && lhs.raw_buffer_sz_ == rhs.raw_buffer_sz_;
77class MidiEventVector final
80 MidiEventVector () { events_.reserve (MAX_MIDI_EVENTS); }
85 using Iterator = std::vector<MidiEvent>::iterator;
86 using ConstIterator = std::vector<MidiEvent>::const_iterator;
91 const std::lock_guard<crill::spin_mutex> lock (lock_);
92 return events_.begin ();
97 const std::lock_guard<crill::spin_mutex> lock (lock_);
98 return events_.end ();
101 void erase (Iterator it, Iterator it_end)
103 const std::lock_guard<crill::spin_mutex> lock (lock_);
104 events_.erase (it, it_end);
107 ConstIterator begin ()
const
109 const std::lock_guard<crill::spin_mutex> lock (lock_);
110 return events_.begin ();
113 ConstIterator end ()
const
115 const std::lock_guard<crill::spin_mutex> lock (lock_);
116 return events_.end ();
121 const std::lock_guard<crill::spin_mutex> lock (lock_);
122 events_.push_back (ev);
125 void push_back (
const std::vector<MidiEvent> &events)
127 const std::lock_guard<crill::spin_mutex> lock (lock_);
128 events_.insert (events_.end (), events.begin (), events.end ());
133 const std::lock_guard<crill::spin_mutex> lock (lock_);
135 events_.erase (events_.begin ());
141 const std::lock_guard<crill::spin_mutex> lock (lock_);
149 const std::lock_guard<crill::spin_mutex> lock (lock_);
155 const std::lock_guard<crill::spin_mutex> lock (lock_);
156 return events_.size ();
161 const std::lock_guard<crill::spin_mutex> lock (lock_);
162 return events_.front ();
167 const std::lock_guard<crill::spin_mutex> lock (lock_);
168 return events_.back ();
173 const std::lock_guard<crill::spin_mutex> lock (lock_);
174 return events_.at (index);
177 void swap (MidiEventVector &other)
179 const std::lock_guard<crill::spin_mutex> lock (lock_);
180 events_.swap (other.events_);
183 void remove_if (std::function<
bool (
const MidiEvent &)> predicate)
185 const std::lock_guard<crill::spin_mutex> lock (lock_);
189 std::remove_if (events_.begin (), events_.end (), std::move (predicate));
190 events_.erase (it, events_.end ());
198 remove_if ([&event] (
const MidiEvent &e) {
return e == event; });
201 void foreach_event (std::function<
void (
const MidiEvent &)> func)
const
203 const std::lock_guard<crill::spin_mutex> lock (lock_);
204 std::ranges::for_each (events_, func);
207 size_t capacity ()
const
209 const std::lock_guard<crill::spin_mutex> lock (lock_);
210 return events_.capacity ();
223 const MidiEventVector &src,
224 std::optional<std::array<bool, 16>> channels,
237 using NotePitchToChordDescriptorFunc =
238 std::function<
const ChordDescriptor *(
midi_byte_t)>;
247 const MidiEventVector &src,
248 NotePitchToChordDescriptorFunc note_number_to_chord_descriptor,
269 const ChordDescriptor &descr,
278 const ChordDescriptor &descr,
297 bool has_note_on (
bool check_main,
bool check_queued);
300 bool has_any ()
const {
return !empty (); }
301 bool empty ()
const {
return size () == 0; }
338 void add_raw (
const uint8_t * buf,
size_t buf_sz,
midi_time_t time);
346 push_back (
MidiEvent (byte1, byte2, byte3, time));
393 juce::MidiMessageSequence &sequence,
394 bool update_matched_pairs)
const;
405 bool check_for_note_on (
int note);
411 bool delete_note_on (
int note);
425 void delete_event (
const MidiEvent * ev);
428 std::vector<MidiEvent> events_;
431 mutable crill::spin_mutex lock_;
A ChordDescriptor describes a chord and is not linked to any specific object by itself.
A lock-free thread-safe vector of MidiEvents.
void panic()
Must only be called from the UI thread.
void add_all_notes_off(midi_byte_t channel, midi_time_t time, bool with_lock)
Queues MIDI note off to event queue.
void set_channel(midi_byte_t channel)
Sets the given MIDI channel on all applicable MIDI events.
void sort()
Sorts the MidiEvents by time.
void add_note_offs_from_chord_descr(const ChordDescriptor &descr, midi_byte_t channel, midi_time_t time)
Adds a note off for each note in the chord.
void add_song_pos(int64_t total_sixteenths, midi_time_t time)
Adds a song position event to the queue.
void add_note_ons_from_chord_descr(const ChordDescriptor &descr, midi_byte_t channel, midi_byte_t velocity, midi_time_t time)
Adds a note on for each note in the chord.
void add_note_off(midi_byte_t channel, midi_byte_t note_pitch, midi_time_t time)
Adds a note off event to the given MidiEvents.
void append_w_filter(const MidiEventVector &src, std::optional< std::array< bool, 16 > > channels, nframes_t local_offset, nframes_t nframes)
Appends the events from src.
void remove(const MidiEvent &event)
Removes all events that match event.
void add_cc_volume(midi_byte_t channel, midi_byte_t volume, midi_time_t time)
Add CC volume event.
void add_note_on(midi_byte_t channel, midi_byte_t note_pitch, midi_byte_t velocity, midi_time_t time)
Adds a note on event to the given MidiEvents.
void panic_without_lock(midi_time_t time)
Adds a note off message to every MIDI channel.
void add_pitchbend(midi_byte_t channel, uint32_t pitchbend, midi_time_t time)
Adds a control event to the given MidiEvents.
void write_to_midi_sequence(juce::MidiMessageSequence &sequence, bool update_matched_pairs) const
Writes the events to a MIDI sequence.
void add_control_change(midi_byte_t channel, midi_byte_t controller, midi_byte_t control, midi_time_t time)
Adds a control event to the given MidiEvents.
void append(const MidiEventVector &src, nframes_t local_offset, nframes_t nframes)
Appends the events from src.
void add_event_from_buf(midi_time_t time, midi_byte_t *buf, int buf_size)
Parses a MidiEvent from a raw MIDI buffer.
void clear_duplicates()
Clears duplicates.
void transform_chord_and_append(const MidiEventVector &src, NotePitchToChordDescriptorFunc note_number_to_chord_descriptor, midi_byte_t velocity_to_use, nframes_t local_offset, nframes_t nframes)
Transforms the given MIDI input to the MIDI notes of the corresponding chord.
Container for passing midi events through ports.
MidiEventVector active_events_
Events to use in this cycle.
void dequeue(nframes_t local_offset, nframes_t nframes)
Copies the queue contents to the original struct.
MidiEventVector queued_events_
For queueing events from the GUI or from hardware, since they run in different threads.
uint32_t nframes_t
Frame count.
uint32_t midi_time_t
MIDI time in global frames.
uint8_t midi_byte_t
MIDI byte.
midi_time_t time_
Time of the MIDI event, in frames from the start of the current cycle.
std::array< midi_byte_t, 3 > raw_buffer_
Raw MIDI data.
std::int64_t systime_
Time using g_get_monotonic_time().