prelim midi controller

This commit is contained in:
2025-12-29 00:44:43 -06:00
parent c045337fba
commit 4c6ec3a019
6 changed files with 144 additions and 4 deletions

78
src/MidiController.cpp Normal file
View File

@@ -0,0 +1,78 @@
#include "MidiController.h"
#include <iostream>
MidiController::MidiController(NoteQueue& queue) : noteQueue_(queue) {
try {
midiIn_ = std::make_unique<RtMidiIn>();
midiIn_->ignoreTypes(false, false, false);
} catch (RtMidiError& e) {
std::cerr << "RtMidi init failed: " << e.getMessage() << std::endl;
}
}
MidiController::~MidiController() {
close();
}
bool MidiController::openDefaultPort() {
if (!midiIn_) return false;
if (midiIn_->getPortCount() == 0) {
std::cerr << "No MIDI input ports available\n";
return false;
}
return openPort(0);
}
bool MidiController::openPort(unsigned int index) {
if (!midiIn_) return false;
try {
midiIn_->openPort(index);
midiIn_->setCallback(&MidiController::midiCallback, this);
std::cout << "Opened MIDI port: "
<< midiIn_->getPortName(index) << "\n";
return true;
} catch (RtMidiError& e) {
std::cerr << e.getMessage() << std::endl;
return false;
}
}
void MidiController::close() {
if (midiIn_ && midiIn_->isPortOpen()) {
midiIn_->closePort();
}
}
void MidiController::midiCallback(double /*deltaTime*/, std::vector<unsigned char>* message, void* userData) {
auto* self = static_cast<MidiController*>(userData);
if (!message || message->empty()) return;
self->handleMessage(*message);
}
void MidiController::handleMessage(const std::vector<unsigned char>& msg) {
unsigned char status = msg[0] & 0xF0;
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<uint8_t>(note),
vel / 127.0f
});
}
// Note Off (or Note On with velocity 0)
else if (status == 0x80 || (status == 0x90 && vel == 0)) {
noteQueue_.push({
NoteEventType::NoteOff,
static_cast<uint8_t>(note),
0.0f
});
}
// to have a peak :)
std::cout << msg[0] << std::endl;
}

28
src/MidiController.h Normal file
View File

@@ -0,0 +1,28 @@
#pragma once
#include <RtMidi.h>
#include <memory>
#include "NoteQueue.h"
class MidiController {
public:
explicit MidiController(NoteQueue& queue);
~MidiController();
bool openDefaultPort();
bool openPort(unsigned int index);
void close();
private:
static void midiCallback(
double deltaTime,
std::vector<unsigned char>* message,
void* userData
);
void handleMessage(const std::vector<unsigned char>& msg);
std::unique_ptr<RtMidiIn> midiIn_;
NoteQueue& noteQueue_;
};

View File

@@ -9,7 +9,8 @@ MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui_(new Ui::MainWindow),
audio_(new AudioEngine()),
keyboard_(audio_->noteQueue()) {
keyboard_(audio_->noteQueue()),
midi_(audio_->noteQueue()) {
// initialize ui
ui_->setupUi(this);

View File

@@ -5,6 +5,7 @@
#include <QKeyEvent>
#include "../synth/AudioEngine.h"
#include "../MidiController.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
@@ -30,5 +31,6 @@ private:
AudioEngine* audio_ = nullptr;
KeyboardController keyboard_;
MidiController midi_;
};