sustain pedal checkpoint
This commit is contained in:
@@ -56,30 +56,59 @@ void MidiController::midiCallback(double /*deltaTime*/, std::vector<unsigned cha
|
|||||||
|
|
||||||
void MidiController::handleMessage(const std::vector<unsigned char>& msg) {
|
void MidiController::handleMessage(const std::vector<unsigned char>& msg) {
|
||||||
unsigned char status = msg[0] & 0xF0;
|
unsigned char status = msg[0] & 0xF0;
|
||||||
|
unsigned char data1 = msg[1];
|
||||||
|
unsigned char data2 = msg[2];
|
||||||
|
|
||||||
if (status == 0xFE) return;
|
if(status == 0xFE) return;
|
||||||
if (status == 0xF8) 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 note = msg.size() > 1 ? msg[1] : 0;
|
||||||
unsigned char vel = msg.size() > 2 ? msg[2] : 0;
|
unsigned char vel = msg.size() > 2 ? msg[2] : 0;
|
||||||
|
|
||||||
// Note On (velocity > 0)
|
// Note On (velocity > 0)
|
||||||
if (status == 0x90 && vel > 0) {
|
if (status == 0x90 && vel > 0) {
|
||||||
|
noteOn(note, vel);
|
||||||
|
}
|
||||||
|
// Note Off (or Note On with velocity 0)
|
||||||
|
else if (status == 0x80 || (status == 0x90 && vel == 0)) {
|
||||||
|
noteOff(note);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void MidiController::noteOn(uint8_t note, uint8_t vel) {
|
||||||
noteQueue_.push({
|
noteQueue_.push({
|
||||||
NoteEventType::NoteOn,
|
NoteEventType::NoteOn,
|
||||||
static_cast<uint8_t>(note),
|
static_cast<uint8_t>(note),
|
||||||
vel / 127.0f,
|
vel / 127.0f,
|
||||||
std::chrono::high_resolution_clock::now()
|
std::chrono::high_resolution_clock::now()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// Note Off (or Note On with velocity 0)
|
|
||||||
else if (status == 0x80 || (status == 0x90 && vel == 0)) {
|
void MidiController::noteOff(uint8_t note) {
|
||||||
noteQueue_.push({
|
noteQueue_.push({
|
||||||
NoteEventType::NoteOff,
|
NoteEventType::NoteOff,
|
||||||
static_cast<uint8_t>(note),
|
static_cast<uint8_t>(note),
|
||||||
0.0f,
|
0.0f,
|
||||||
std::chrono::high_resolution_clock::now()
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <RtMidi.h>
|
#include <RtMidi.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "NoteQueue.h"
|
#include "NoteQueue.h"
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
class MidiController {
|
class MidiController {
|
||||||
public:
|
public:
|
||||||
@@ -22,7 +23,14 @@ private:
|
|||||||
);
|
);
|
||||||
|
|
||||||
void handleMessage(const std::vector<unsigned char>& msg);
|
void handleMessage(const std::vector<unsigned char>& msg);
|
||||||
|
void handleSustain(bool down);
|
||||||
|
void noteOn(uint8_t note, uint8_t vel);
|
||||||
|
void noteOff(uint8_t note);
|
||||||
|
|
||||||
std::unique_ptr<RtMidiIn> midiIn_;
|
std::unique_ptr<RtMidiIn> midiIn_;
|
||||||
NoteQueue& noteQueue_;
|
NoteQueue& noteQueue_;
|
||||||
|
|
||||||
|
bool sustainDown_ = false;
|
||||||
|
std::unordered_set<uint8_t> sustainedNotes_;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user