From cf377cf3b044e8041b619a73eba2f1e5cc68fa54 Mon Sep 17 00:00:00 2001 From: Bliblank Date: Wed, 14 Jan 2026 19:38:48 -0600 Subject: [PATCH] sustain pedal checkpoint --- src/MidiController.cpp | 59 +++++++++++++++++++++++++++++++----------- src/MidiController.h | 8 ++++++ 2 files changed, 52 insertions(+), 15 deletions(-) diff --git a/src/MidiController.cpp b/src/MidiController.cpp index 3f4debd..267c1f5 100644 --- a/src/MidiController.cpp +++ b/src/MidiController.cpp @@ -56,30 +56,59 @@ void MidiController::midiCallback(double /*deltaTime*/, std::vector& msg) { unsigned char status = msg[0] & 0xF0; + unsigned char data1 = msg[1]; + unsigned char data2 = msg[2]; - if (status == 0xFE) return; - if (status == 0xF8) return; + if(status == 0xFE) return; + if(status == 0xF8) return; + + if(status == 0xB0 && data1 == 64) { + handleSustain(data2 >= 64); + std::cout << "sustain event: " << data2 << std::endl; + return; + } unsigned char note = msg.size() > 1 ? msg[1] : 0; unsigned char vel = msg.size() > 2 ? msg[2] : 0; // Note On (velocity > 0) if (status == 0x90 && vel > 0) { - noteQueue_.push({ - NoteEventType::NoteOn, - static_cast(note), - vel / 127.0f, - std::chrono::high_resolution_clock::now() - }); + noteOn(note, vel); } // Note Off (or Note On with velocity 0) else if (status == 0x80 || (status == 0x90 && vel == 0)) { - noteQueue_.push({ - NoteEventType::NoteOff, - static_cast(note), - 0.0f, - std::chrono::high_resolution_clock::now() - }); + noteOff(note); } -} \ No newline at end of file +} + +void MidiController::noteOn(uint8_t note, uint8_t vel) { + noteQueue_.push({ + NoteEventType::NoteOn, + static_cast(note), + vel / 127.0f, + std::chrono::high_resolution_clock::now() + }); +} + +void MidiController::noteOff(uint8_t note) { + noteQueue_.push({ + NoteEventType::NoteOff, + static_cast(note), + 0.0f, + std::chrono::high_resolution_clock::now() + }); +} + +void MidiController::handleSustain(bool down) { + if(down == sustainDown_) return; + + sustainDown_ = down; + + if(!sustainDown_) { + for(uint8_t note : sustainedNotes_) { + noteOff(note); + } + sustainedNotes_.clear(); + } +} diff --git a/src/MidiController.h b/src/MidiController.h index 3e2e1dd..dccad7e 100644 --- a/src/MidiController.h +++ b/src/MidiController.h @@ -4,6 +4,7 @@ #include #include #include "NoteQueue.h" +#include class MidiController { public: @@ -22,7 +23,14 @@ private: ); void handleMessage(const std::vector& msg); + void handleSustain(bool down); + void noteOn(uint8_t note, uint8_t vel); + void noteOff(uint8_t note); std::unique_ptr midiIn_; NoteQueue& noteQueue_; + + bool sustainDown_ = false; + std::unordered_set sustainedNotes_; + };