-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
fe71053
commit 7cde60e
Showing
2 changed files
with
91 additions
and
60 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,38 +1,33 @@ | ||
#ifndef __MIDI_INPUT_USB__H__ | ||
#define __MIDI_INPUT_USB__H__ | ||
#ifndef MIDI_INPUT_USB_H | ||
#define MIDI_INPUT_USB_H | ||
|
||
#include <functional> | ||
#include <stdint.h> | ||
|
||
#include "pico/stdlib.h" | ||
#include "hardware/uart.h" | ||
#include "project_config.h" | ||
#include "tusb.h" | ||
|
||
class MIDIInputUSB | ||
{ | ||
class MIDIInputUSB { | ||
public: | ||
MIDIInputUSB() { | ||
|
||
} | ||
|
||
void process(); | ||
|
||
// Callback setters | ||
void setNoteOnCallback(void (*callback)(uint8_t, uint8_t, uint8_t)); | ||
void setNoteOffCallback(void (*callback)(uint8_t, uint8_t, uint8_t)); | ||
void setCCCallback(void (*callback)(uint8_t, uint8_t, uint8_t)); | ||
void setPitchBendCallback(void (*callback)(uint16_t, uint8_t)); | ||
void setAftertouchCallback(void (*callback)(uint8_t, uint8_t)); | ||
void setChannelPressureCallback(void (*callback)(uint8_t, uint8_t)); | ||
|
||
private: | ||
const char MIDICH = 1; | ||
|
||
char MIDIRunningStatus; | ||
char MIDINote; | ||
char MIDILevel; | ||
|
||
void (*MIDINoteOnCallback)(uint8_t, uint8_t, uint8_t); | ||
void (*MIDINoteOffCallback)(uint8_t, uint8_t, uint8_t); | ||
void (*MIDICCCallback)(uint8_t, uint8_t, uint8_t); | ||
|
||
void midi_task(); | ||
// MIDI processing function | ||
void process(); | ||
|
||
private: | ||
// Callback function pointers using std::function for flexibility | ||
std::function<void(uint8_t, uint8_t, uint8_t)> MIDINoteOnCallback = nullptr; | ||
std::function<void(uint8_t, uint8_t, uint8_t)> MIDINoteOffCallback = nullptr; | ||
std::function<void(uint8_t, uint8_t, uint8_t)> MIDICCCallback = nullptr; | ||
std::function<void(uint16_t, uint8_t)> MIDIPitchBendCallback = nullptr; | ||
std::function<void(uint8_t, uint8_t)> MIDIAftertouchCallback = nullptr; | ||
std::function<void(uint8_t, uint8_t)> MIDIChannelPressureCallback = nullptr; | ||
|
||
// Helper function for parsing pitch bend data | ||
uint16_t parsePitchBend(const uint8_t* packet); | ||
}; | ||
|
||
#endif // __MIDI_INPUT_USB_H__ | ||
#endif // MIDI_INPUT_USB_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,55 +1,91 @@ | ||
#include "midi_input_usb.h" | ||
#include "tusb.h" // Assuming you're using TinyUSB | ||
|
||
void MIDIInputUSB::setNoteOnCallback(void (*callback)(uint8_t, uint8_t, uint8_t)) | ||
{ | ||
// Setters for the various MIDI callbacks | ||
void MIDIInputUSB::setNoteOnCallback(void (*callback)(uint8_t, uint8_t, uint8_t)) { | ||
MIDINoteOnCallback = callback; | ||
} | ||
|
||
void MIDIInputUSB::setNoteOffCallback(void (*callback)(uint8_t, uint8_t, uint8_t)) | ||
{ | ||
void MIDIInputUSB::setNoteOffCallback(void (*callback)(uint8_t, uint8_t, uint8_t)) { | ||
MIDINoteOffCallback = callback; | ||
} | ||
|
||
void MIDIInputUSB::setCCCallback(void (*callback)(uint8_t, uint8_t, uint8_t)) | ||
{ | ||
void MIDIInputUSB::setCCCallback(void (*callback)(uint8_t, uint8_t, uint8_t)) { | ||
MIDICCCallback = callback; | ||
} | ||
|
||
void MIDIInputUSB::process() | ||
{ | ||
void MIDIInputUSB::setPitchBendCallback(void (*callback)(uint16_t, uint8_t)) { | ||
MIDIPitchBendCallback = callback; | ||
} | ||
|
||
void MIDIInputUSB::setAftertouchCallback(void (*callback)(uint8_t, uint8_t)) { | ||
MIDIAftertouchCallback = callback; | ||
} | ||
|
||
void MIDIInputUSB::setChannelPressureCallback(void (*callback)(uint8_t, uint8_t)) { | ||
MIDIChannelPressureCallback = callback; | ||
} | ||
|
||
// Helper function to parse pitch bend data | ||
uint16_t MIDIInputUSB::parsePitchBend(const uint8_t* packet) { | ||
// Combine the two data bytes into a 14-bit pitch bend value | ||
return (packet[2] << 7) | packet[1]; | ||
} | ||
|
||
void MIDIInputUSB::process() { | ||
uint8_t packet[4]; | ||
while (tud_midi_available()) | ||
{ | ||
|
||
while (tud_midi_available()) { | ||
tud_midi_stream_read(packet, 3); | ||
|
||
#ifdef DEBUG_MIID | ||
#ifdef DEBUG_MIDI | ||
printf("%02X %02X %02X %02X\n", packet[0], packet[1], packet[2], packet[3]); | ||
#endif | ||
|
||
if (packet[0] >> 4 == 0x8 || packet[0] >> 4 == 0x9) | ||
{ | ||
if (packet[0] >> 4 == 0x8) | ||
{ | ||
if (MIDINoteOffCallback != NULL) | ||
{ | ||
MIDINoteOffCallback(packet[1], packet[2], packet[0] & 0xF); | ||
uint8_t status = packet[0] >> 4; | ||
uint8_t channel = packet[0] & 0xF; | ||
|
||
switch (status) { | ||
case 0x8: // Note Off | ||
if (MIDINoteOffCallback != nullptr) { | ||
MIDINoteOffCallback(packet[1], packet[2], channel); | ||
} | ||
} | ||
else if(packet[0] >> 4 == 0x9) | ||
{ | ||
if (MIDINoteOnCallback != NULL) | ||
{ | ||
MIDINoteOnCallback(packet[1], packet[2], packet[0] & 0xF); | ||
break; | ||
|
||
case 0x9: // Note On | ||
if (MIDINoteOnCallback != nullptr) { | ||
MIDINoteOnCallback(packet[1], packet[2], channel); | ||
} | ||
} | ||
break; | ||
|
||
} | ||
else if (packet[0] >> 4 == 0xB) | ||
{ | ||
if (MIDICCCallback != NULL) | ||
{ | ||
MIDICCCallback(packet[1], packet[2], packet[0] & 0xF); | ||
} | ||
case 0xB: // Control Change | ||
if (MIDICCCallback != nullptr) { | ||
MIDICCCallback(packet[1], packet[2], channel); | ||
} | ||
break; | ||
|
||
case 0xE: // Pitch Bend | ||
if (MIDIPitchBendCallback != nullptr) { | ||
uint16_t pitchBendValue = parsePitchBend(packet); | ||
MIDIPitchBendCallback(pitchBendValue, channel); | ||
} | ||
break; | ||
|
||
case 0xA: // Polyphonic Aftertouch | ||
if (MIDIAftertouchCallback != nullptr) { | ||
MIDIAftertouchCallback(packet[1], packet[2]); | ||
} | ||
break; | ||
|
||
case 0xD: // Channel Pressure (Aftertouch) | ||
if (MIDIChannelPressureCallback != nullptr) { | ||
MIDIChannelPressureCallback(packet[1], channel); | ||
} | ||
break; | ||
|
||
default: | ||
// Handle other types of MIDI messages if needed | ||
break; | ||
} | ||
} | ||
} |