40 std::function<void(uint8_t channel, uint8_t note)>
on_note_off;
47 auto msg =
event.message;
50 uint8_t ch = msg.getChannel0to15();
51 uint8_t note = msg.getNoteNumber();
52 uint8_t vel = msg.getVelocity();
59 set_key(ch, note, vel);
62 }
else if (msg.isNoteOff()) {
63 uint8_t ch = msg.getChannel0to15();
64 uint8_t note = msg.getNoteNumber();
67 }
else if (msg.isController()) {
68 const uint8_t cc = msg.getControllerNumber();
69 if (cc == 120 || cc == 123)
80 uint8_t
velocity(uint8_t channel, uint8_t note)
const {
81 if (channel >= 16 || note >= 128)
return 0;
82 return state_[channel][note];
87 if (channel >= 16)
return 0;
89 for (
int i = 0; i < 128; ++i) {
90 if (state_[channel][i] > 0) ++count;
98 for (
int ch = 0; ch < 16; ++ch) count += notes_held(static_cast<uint8_t>(ch));
104 for (
int ch = 0; ch < 16; ++ch) {
105 for (
int n = 0; n < 128; ++n) {
106 if (state_[ch][n] > 0)
return true;
114 if (channel >= 16)
return -1;
115 for (
int i = 0; i < 128; ++i) {
116 if (state_[channel][i] > 0)
return i;
123 if (channel >= 16)
return -1;
124 for (
int i = 127; i >= 0; --i) {
125 if (state_[channel][i] > 0)
return i;
132 for (
int ch = 0; ch < 16; ++ch) {
133 for (
int n = 0; n < 128; ++n) {
134 if (state_[ch][n] > 0) {
137 static_cast<uint8_t
>(n));
145 if (channel >= 16)
return;
146 for (
int n = 0; n < 128; ++n) {
147 if (state_[channel][n] > 0) {
148 state_[channel][n] = 0;
156 for (
auto& ch : state_) ch.fill(0);
160 std::array<std::array<uint8_t, 128>, 16> state_{};
162 void set_key(uint8_t ch, uint8_t note, uint8_t vel) {
163 if (ch < 16 && note < 128) state_[ch][note] = vel;
Tracks the state of all 128 MIDI keys across 16 channels.
Definition keyboard_state.hpp:35
bool any_notes_held() const
Check if any note is held on any channel.
Definition keyboard_state.hpp:103
uint8_t velocity(uint8_t channel, uint8_t note) const
Get the velocity of a held note (0 if not held).
Definition keyboard_state.hpp:80
int total_notes_held() const
Count total notes held across all channels.
Definition keyboard_state.hpp:96
void reset()
Reset all state without firing callbacks.
Definition keyboard_state.hpp:155
std::function< void(uint8_t channel, uint8_t note)> on_note_off
Called when a note turns off.
Definition keyboard_state.hpp:40
void all_notes_off()
Release all notes on all channels.
Definition keyboard_state.hpp:131
int highest_note(uint8_t channel) const
Get the highest held note on a channel (-1 if none).
Definition keyboard_state.hpp:122
std::function< void(uint8_t channel, uint8_t note, uint8_t velocity)> on_note_on
Called when a note turns on.
Definition keyboard_state.hpp:38
int lowest_note(uint8_t channel) const
Get the lowest held note on a channel (-1 if none).
Definition keyboard_state.hpp:113
void process(const MidiEvent &event)
Process a MIDI event.
Definition keyboard_state.hpp:46
int notes_held(uint8_t channel) const
Count how many notes are currently held on a channel.
Definition keyboard_state.hpp:86
bool is_note_on(uint8_t channel, uint8_t note) const
Check if a specific note is currently held on a channel.
Definition keyboard_state.hpp:75
void all_notes_off(uint8_t channel)
Release all notes on a specific channel.
Definition keyboard_state.hpp:144
Definition custom_node_events.hpp:26
Timestamped MIDI event combining a choc::midi::ShortMessage with timing info.
Definition message.hpp:32