MIDI input
This commit is contained in:
parent
94ade20143
commit
8ef4371711
@ -2,19 +2,83 @@
|
|||||||
|
|
||||||
// MIDI UART Pins (GP0/GP1)
|
// MIDI UART Pins (GP0/GP1)
|
||||||
#define PIN_MIDI_TX 0
|
#define PIN_MIDI_TX 0
|
||||||
|
#define PIN_MIDI_RX 1
|
||||||
|
|
||||||
MidiDriver midi;
|
MidiDriver midi;
|
||||||
|
|
||||||
MidiDriver::MidiDriver() {
|
MidiDriver::MidiDriver() : lastInputNote(-1), lastInputVelocity(0), _runningStatus(0), _byteIndex(0), _data1(0), _data2(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MidiDriver::begin() {
|
void MidiDriver::begin() {
|
||||||
mutex_init(&_mutex);
|
mutex_init(&_mutex);
|
||||||
Serial1.setTX(PIN_MIDI_TX);
|
Serial1.setTX(PIN_MIDI_TX);
|
||||||
|
Serial1.setRX(PIN_MIDI_RX);
|
||||||
Serial1.begin(31250);
|
Serial1.begin(31250);
|
||||||
Serial.println(F("MIDI Serial initialized on GP0/GP1"));
|
Serial.println(F("MIDI Serial initialized on GP0/GP1"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MidiDriver::update() {
|
||||||
|
while (Serial1.available()) {
|
||||||
|
uint8_t b = Serial1.read();
|
||||||
|
Serial1.write(b); // Soft THRU: Merge input with output
|
||||||
|
|
||||||
|
// Realtime messages don't affect running status
|
||||||
|
if (b >= 0xF8) continue;
|
||||||
|
|
||||||
|
if (b >= 0x80) {
|
||||||
|
_runningStatus = b;
|
||||||
|
_byteIndex = 0;
|
||||||
|
} else if (_runningStatus) {
|
||||||
|
if (_byteIndex == 0) {
|
||||||
|
_data1 = b;
|
||||||
|
_byteIndex++;
|
||||||
|
|
||||||
|
// Handle 2-byte messages (Program Change 0xC0, Channel Pressure 0xD0)
|
||||||
|
uint8_t type = _runningStatus & 0xF0;
|
||||||
|
if (type == 0xC0 || type == 0xD0) {
|
||||||
|
_byteIndex = 0; // Message complete
|
||||||
|
}
|
||||||
|
} else if (_byteIndex == 1) {
|
||||||
|
_data2 = b;
|
||||||
|
_byteIndex = 0; // Message complete
|
||||||
|
|
||||||
|
uint8_t channel = (_runningStatus & 0x0F) + 1;
|
||||||
|
uint8_t type = _runningStatus & 0xF0;
|
||||||
|
if (type == 0x90) {
|
||||||
|
if (_data2 > 0) {
|
||||||
|
// Serial.print(F("Note On CH"));
|
||||||
|
// Serial.print(channel);
|
||||||
|
// Serial.print(F(": "));
|
||||||
|
// Serial.print(_data1);
|
||||||
|
// Serial.print(F(" Vel: "));
|
||||||
|
// Serial.println(_data2);
|
||||||
|
lastInputNote = _data1;
|
||||||
|
lastInputVelocity = _data2;
|
||||||
|
} else {
|
||||||
|
// Serial.print(F("Note Off CH"));
|
||||||
|
// Serial.print(channel);
|
||||||
|
// Serial.print(F(": "));
|
||||||
|
// Serial.println(_data1);
|
||||||
|
if (lastInputNote == _data1) {
|
||||||
|
lastInputNote = -1; // Note On vel 0 is Note Off
|
||||||
|
lastInputVelocity = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (type == 0x80) {
|
||||||
|
// Serial.print(F("Note Off CH"));
|
||||||
|
// Serial.print(channel);
|
||||||
|
// Serial.print(F(": "));
|
||||||
|
// Serial.println(_data1);
|
||||||
|
if (lastInputNote == _data1) {
|
||||||
|
lastInputNote = -1;
|
||||||
|
lastInputVelocity = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MidiDriver::lock() {
|
void MidiDriver::lock() {
|
||||||
mutex_enter_blocking(&_mutex);
|
mutex_enter_blocking(&_mutex);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,6 +8,10 @@ class MidiDriver {
|
|||||||
public:
|
public:
|
||||||
MidiDriver();
|
MidiDriver();
|
||||||
void begin();
|
void begin();
|
||||||
|
void update();
|
||||||
|
|
||||||
|
volatile int lastInputNote;
|
||||||
|
volatile int lastInputVelocity;
|
||||||
|
|
||||||
void sendNoteOn(uint8_t note, uint8_t velocity, uint8_t channel);
|
void sendNoteOn(uint8_t note, uint8_t velocity, uint8_t channel);
|
||||||
void sendNoteOff(uint8_t note, uint8_t channel);
|
void sendNoteOff(uint8_t note, uint8_t channel);
|
||||||
@ -19,6 +23,10 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
mutex_t _mutex;
|
mutex_t _mutex;
|
||||||
|
uint8_t _runningStatus;
|
||||||
|
uint8_t _byteIndex;
|
||||||
|
uint8_t _data1;
|
||||||
|
uint8_t _data2;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern MidiDriver midi;
|
extern MidiDriver midi;
|
||||||
|
|||||||
@ -129,6 +129,7 @@ static void handlePlayback() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void loopPlayback() {
|
void loopPlayback() {
|
||||||
|
midi.update();
|
||||||
if (needsPanic) {
|
if (needsPanic) {
|
||||||
for (int i=0; i<NUM_TRACKS; i++) {
|
for (int i=0; i<NUM_TRACKS; i++) {
|
||||||
midi.panic(midiChannels[i]);
|
midi.panic(midiChannels[i]);
|
||||||
|
|||||||
@ -50,13 +50,16 @@ Make sure to establish a **common ground** by connecting the ground from your ex
|
|||||||
| GND | External 5V Supply - | External Power Ground |
|
| GND | External 5V Supply - | External Power Ground |
|
||||||
| (Matrix GND) | GND (Pin 18) | Common Ground with Pico |
|
| (Matrix GND) | GND (Pin 18) | Common Ground with Pico |
|
||||||
+----------------------+------------------------+-----------------------------+
|
+----------------------+------------------------+-----------------------------+
|
||||||
| MIDI DIN (Serial) | | |
|
| MIDI OUT (Serial) | | |
|
||||||
| TX (MIDI OUT) | GP0 (Pin 1) | To DIN Pin 5 (via 220 ohm) |
|
| TX (MIDI OUT) | GP0 (Pin 1) | To DIN Pin 5 (via 220 ohm) |
|
||||||
|
| MIDI IN (Serial) | | (optional!) |
|
||||||
|
| RX (MIDI IN) | GP1 (Pin 2) | To DIN Pin 3 (optoisolator) |
|
||||||
+----------------------+------------------------+-----------------------------+
|
+----------------------+------------------------+-----------------------------+
|
||||||
|
|
||||||
|
|
||||||
**MIDI Hardware Note**:
|
**MIDI Hardware Note**:
|
||||||
* **MIDI OUT**: Connect **GP0** to DIN Pin 5 via a 220Ω resistor. Connect DIN Pin 4 to 3.3V (3V3) via a 220Ω resistor. Connect DIN Pin 2 to GND.
|
* **MIDI OUT**: Connect **GP0** to DIN Pin 5 via a 220Ω resistor. Connect DIN Pin 4 to 3.3V (3V3) via a 220Ω resistor. Connect DIN Pin 2 to GND.
|
||||||
|
* **MIDI IN**: Optional! Uses a 6N137 optocoupler based on [this guide](https://www.kieranreck.co.uk/MIDI-6N137-vs-6N138-vs-6N139/). Connect the optocoupler output to **GP1**.
|
||||||
|
|
||||||
Once everything is wired up, you can upload the code and your tracker should be ready to go!
|
Once everything is wired up, you can upload the code and your tracker should be ready to go!
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user