USB-MIDI #477
Replies: 5 comments 2 replies
-
There's no need to modify any core files. All you do is set the configuration to "custom" and then build your profile in the sketch. You can have whatever combination of devices you like then. Here's an example that I have dug out of my archive. It's longer than it needs to be for an example, but hey ho... USBFS usbDevice;
USBManager USB(usbDevice, 0xf055, 0x1234, "chipKIT", "My Midi Dongle");
Audio_MIDI midi;
CDCACM uSerial;
const char *controlNames[] = {
"Bank Select",
"Modulation Wheel or Lever",
"Breath Controller",
"Undefined",
"Foot Controller",
"Portamento Time",
"Data Entry MSB",
"Channel Volume (formerly Main Volume)",
"Balance",
"Undefined",
"Pan",
"Expression Controller",
"Effect Control 1",
"Effect Control 2",
"Undefined",
"Undefined",
"General Purpose Controller 1",
"General Purpose Controller 2",
"General Purpose Controller 3",
"General Purpose Controller 4",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"LSB for Control 0 (Bank Select)",
"LSB for Control 1 (Modulation Wheel or Lever)",
"LSB for Control 2 (Breath Controller)",
"LSB for Control 3 (Undefined)",
"LSB for Control 4 (Foot Controller)",
"LSB for Control 5 (Portamento Time)",
"LSB for Control 6 (Data Entry)",
"LSB for Control 7 (Channel Volume, formerly Main Volume)",
"LSB for Control 8 (Balance)",
"LSB for Control 9 (Undefined)",
"LSB for Control 10 (Pan)",
"LSB for Control 11 (Expression Controller)",
"LSB for Control 12 (Effect control 1)",
"LSB for Control 13 (Effect control 2)",
"LSB for Control 14 (Undefined)",
"LSB for Control 15 (Undefined)",
"LSB for Control 16 (General Purpose Controller 1)",
"LSB for Control 17 (General Purpose Controller 2)",
"LSB for Control 18 (General Purpose Controller 3)",
"LSB for Control 19 (General Purpose Controller 4)",
"LSB for Control 20 (Undefined)",
"LSB for Control 21 (Undefined)",
"LSB for Control 22 (Undefined)",
"LSB for Control 23 (Undefined)",
"LSB for Control 24 (Undefined)",
"LSB for Control 25 (Undefined)",
"LSB for Control 26 (Undefined)",
"LSB for Control 27 (Undefined)",
"LSB for Control 28 (Undefined)",
"LSB for Control 29 (Undefined)",
"LSB for Control 30 (Undefined)",
"LSB for Control 31 (Undefined)",
"Damper Pedal on/off (Sustain)",
"Portamento On/Off",
"Sostenuto On/Off",
"Soft Pedal On/Off",
"Legato Footswitch",
"Hold 2",
"Sound Controller 1 (default: Sound Variation)",
"Sound Controller 2 (default: Timbre/Harmonic Intens.)",
"Sound Controller 3 (default: Release Time)",
"Sound Controller 4 (default: Attack Time)",
"Sound Controller 5 (default: Brightness)",
"Sound Controller 6 (default: Decay Time - see MMA RP-021)",
"Sound Controller 7 (default: Vibrato Rate - see MMA RP-021)",
"Sound Controller 8 (default: Vibrato Depth - see MMA RP-021)",
"Sound Controller 9 (default: Vibrato Delay - see MMA RP-021)",
"Sound Controller 10 (default undefined - see MMA RP-021)",
"General Purpose Controller 5",
"General Purpose Controller 6",
"General Purpose Controller 7",
"General Purpose Controller 8",
"Portamento Control",
"Undefined",
"Undefined",
"Undefined",
"High Resolution Velocity Prefix",
"Undefined",
"Undefined",
"Effects 1 Depth",
"Effects 2 Depth (formerly Tremolo Depth)",
"Effects 3 Depth",
"Effects 4 Depth (formerly Celeste t Depth)",
"Effects 5 Depth (formerly Phaser Depth)",
"Data Increment (Data Entry +1) (see MMA RP-018)",
"Data Decrement (Data Entry -1) (see MMA RP-018)",
"Non-Registered Parameter Number (NRPN) - LSB",
"Non-Registered Parameter Number (NRPN) - MSB",
"Registered Parameter Number (RPN) - LSB*",
"Registered Parameter Number (RPN) - MSB*",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"[Channel Mode Message] All Sound Off",
"[Channel Mode Message] Reset All Controllers",
"[Channel Mode Message] Local Control On/Off",
"[Channel Mode Message] All Notes Off",
"[Channel Mode Message] Omni Mode Off (+ all notes off)",
"[Channel Mode Message] Omni Mode On (+ all notes off)",
"[Channel Mode Message] Mono Mode On (+ poly off, + all notes off)",
"[Channel Mode Message] Poly Mode On (+ mono off, +all notes off)",
};
volatile uint8_t notes[16][128] = {0};
const char *messageName(int n) {
switch (n) {
case 0x08: return "Note Off";
case 0x09: return "Note On";
case 0x0A: return "Polyphonic Pressure";
case 0x0B: return "Control Change";
case 0x0C: return "Program Change";
case 0x0D: return "Channel Pressure";
case 0x0E: return "Pitch Bend";
case 0x0F: return "System";
}
return "Unknown";
}
void updateNotes() {
uSerial.print("\e[0;0H");
for (int j = 0; j < 16; j++) {
for (int i = 0; i < 128; i++) {
if (uSerial.print(notes[j][i] > 0 ? '#' : '.'));
}
uSerial.println();
}
}
void processMessage(uint8_t status, uint8_t d0, uint8_t d1) {
uint8_t messageType = status >> 4;
uint8_t channelNumber = status & 0x0F;
if (messageType == 0x0B) {
uSerial.printf("Channel %d %s => %d \r\n", channelNumber, controlNames[d0], d1);
} else if (messageType == 0x09) {
notes[channelNumber][d0] = d1;
} else {
uSerial.printf("Channel %d, %s: %02x %02x\r\n", channelNumber, messageName(messageType), d0, d1);
}
}
void setup() {
midi.onMidiMessage(processMessage);
USB.addDevice(midi);
USB.addDevice(uSerial);
USB.begin();
}
void loop() {
while (uSerial.available()) {
uSerial.read();
}
updateNotes();
} It only does reception in there, but you can use |
Beta Was this translation helpful? Give feedback.
-
Matt, Brilliant work, got this running on a Fubarino Mini 2.0. I installed vmpk in Linux was able to see My Midi Dongle in the connections. I commented out updateNotes(); so that events don't scroll off the screen so fast. I can see lots of midi message pitch / mod wheel / program change / note off. But for some reason I'm not getting any note on (or unknown) messages. It may be a configuration issue with vmpk, as I've never used it before. Jacob |
Beta Was this translation helpful? Give feedback.
-
That's so cool. Do you have a demo of the project?
Happy New Year!!!
-_Rick
…On Thu, Jan 6, 2022 at 12:53 PM Jacob Christ ***@***.***> wrote:
At, just realized you were intercepting note on messages to update the
array... They are there!!!! Matt this library just ruined my weekends as I
can see no end to the fun!
Jacob
—
Reply to this email directly, view it on GitHub
<#477 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AABV3ZATMR4F5K4WV55BUM3UUXJKPANCNFSM5LLOTUTQ>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***
com>
--
Co-founder
Fair Use Building and Research (FUBAR) Labs
http://fubarlabs.org
|
Beta Was this translation helpful? Give feedback.
-
I'll give it a go!
-_Rick
…On Thu, Jan 6, 2022 at 1:13 PM Jacob Christ ***@***.***> wrote:
Rick,
Its just the code that Matt dropped in the above. I modified it to just
show the messages as they are coming in like this;
USBFS usbDevice;
USBManager USB(usbDevice, 0xf055, 0x1234, "chipKIT", "My Midi Dongle");
Audio_MIDI midi;
CDCACM uSerial;
const char *controlNames[] = {
"Bank Select",
"Modulation Wheel or Lever",
"Breath Controller",
"Undefined",
"Foot Controller",
"Portamento Time",
"Data Entry MSB",
"Channel Volume (formerly Main Volume)",
"Balance",
"Undefined",
"Pan",
"Expression Controller",
"Effect Control 1",
"Effect Control 2",
"Undefined",
"Undefined",
"General Purpose Controller 1",
"General Purpose Controller 2",
"General Purpose Controller 3",
"General Purpose Controller 4",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"LSB for Control 0 (Bank Select)",
"LSB for Control 1 (Modulation Wheel or Lever)",
"LSB for Control 2 (Breath Controller)",
"LSB for Control 3 (Undefined)",
"LSB for Control 4 (Foot Controller)",
"LSB for Control 5 (Portamento Time)",
"LSB for Control 6 (Data Entry)",
"LSB for Control 7 (Channel Volume, formerly Main Volume)",
"LSB for Control 8 (Balance)",
"LSB for Control 9 (Undefined)",
"LSB for Control 10 (Pan)",
"LSB for Control 11 (Expression Controller)",
"LSB for Control 12 (Effect control 1)",
"LSB for Control 13 (Effect control 2)",
"LSB for Control 14 (Undefined)",
"LSB for Control 15 (Undefined)",
"LSB for Control 16 (General Purpose Controller 1)",
"LSB for Control 17 (General Purpose Controller 2)",
"LSB for Control 18 (General Purpose Controller 3)",
"LSB for Control 19 (General Purpose Controller 4)",
"LSB for Control 20 (Undefined)",
"LSB for Control 21 (Undefined)",
"LSB for Control 22 (Undefined)",
"LSB for Control 23 (Undefined)",
"LSB for Control 24 (Undefined)",
"LSB for Control 25 (Undefined)",
"LSB for Control 26 (Undefined)",
"LSB for Control 27 (Undefined)",
"LSB for Control 28 (Undefined)",
"LSB for Control 29 (Undefined)",
"LSB for Control 30 (Undefined)",
"LSB for Control 31 (Undefined)",
"Damper Pedal on/off (Sustain)",
"Portamento On/Off",
"Sostenuto On/Off",
"Soft Pedal On/Off",
"Legato Footswitch",
"Hold 2",
"Sound Controller 1 (default: Sound Variation)",
"Sound Controller 2 (default: Timbre/Harmonic Intens.)",
"Sound Controller 3 (default: Release Time)",
"Sound Controller 4 (default: Attack Time)",
"Sound Controller 5 (default: Brightness)",
"Sound Controller 6 (default: Decay Time - see MMA RP-021)",
"Sound Controller 7 (default: Vibrato Rate - see MMA RP-021)",
"Sound Controller 8 (default: Vibrato Depth - see MMA RP-021)",
"Sound Controller 9 (default: Vibrato Delay - see MMA RP-021)",
"Sound Controller 10 (default undefined - see MMA RP-021)",
"General Purpose Controller 5",
"General Purpose Controller 6",
"General Purpose Controller 7",
"General Purpose Controller 8",
"Portamento Control",
"Undefined",
"Undefined",
"Undefined",
"High Resolution Velocity Prefix",
"Undefined",
"Undefined",
"Effects 1 Depth",
"Effects 2 Depth (formerly Tremolo Depth)",
"Effects 3 Depth",
"Effects 4 Depth (formerly Celeste t Depth)",
"Effects 5 Depth (formerly Phaser Depth)",
"Data Increment (Data Entry +1) (see MMA RP-018)",
"Data Decrement (Data Entry -1) (see MMA RP-018)",
"Non-Registered Parameter Number (NRPN) - LSB",
"Non-Registered Parameter Number (NRPN) - MSB",
"Registered Parameter Number (RPN) - LSB*",
"Registered Parameter Number (RPN) - MSB*",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"Undefined",
"[Channel Mode Message] All Sound Off",
"[Channel Mode Message] Reset All Controllers",
"[Channel Mode Message] Local Control On/Off",
"[Channel Mode Message] All Notes Off",
"[Channel Mode Message] Omni Mode Off (+ all notes off)",
"[Channel Mode Message] Omni Mode On (+ all notes off)",
"[Channel Mode Message] Mono Mode On (+ poly off, + all notes off)",
"[Channel Mode Message] Poly Mode On (+ mono off, +all notes off)",
};
volatile uint8_t notes[16][128] = {0};
const char *messageName(int n) {
switch (n) {
case 0x08: return "Note Off";
case 0x09: return "Note On";
case 0x0A: return "Polyphonic Pressure";
case 0x0B: return "Control Change";
case 0x0C: return "Program Change";
case 0x0D: return "Channel Pressure";
case 0x0E: return "Pitch Bend";
case 0x0F: return "System";
}
return "Unknown";
}
void updateNotes() {
uSerial.print("\e[0;0H");
for (int j = 0; j < 16; j++) {
for (int i = 0; i < 128; i++) {
if (uSerial.print(notes[j][i] > 0 ? '#' : '.'));
}
uSerial.println();
}
}
void processMessage(uint8_t status, uint8_t d0, uint8_t d1) {
uint8_t messageType = status >> 4;
uint8_t channelNumber = status & 0x0F;
if (messageType == 0x0B) {
uSerial.printf("Channel %d %s => %d \r\n", channelNumber, controlNames[d0], d1);
// } else if (messageType == 0x09) {
// notes[channelNumber][d0] = d1;
} else {
uSerial.printf("Channel %d, %s: %02x %02x\r\n", channelNumber, messageName(messageType), d0, d1);
}
}
void setup() {
midi.onMidiMessage(processMessage);
USB.addDevice(midi);
USB.addDevice(uSerial);
USB.begin();
}
void loop() {
while (uSerial.available()) {
uSerial.read();
}
//updateNotes();
}
Jacob
—
Reply to this email directly, view it on GitHub
<#477 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AABV3ZEMXG5VCUOOHX5OOILUUXLTJANCNFSM5LLOTUTQ>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
You are receiving this because you commented.Message ID:
***@***.***>
--
Co-founder
Fair Use Building and Research (FUBAR) Labs
http://fubarlabs.org
|
Beta Was this translation helpful? Give feedback.
-
Great. Glad it's working. Just be warned of a trap I fell into with Midi once: there's two ways of "stopping" a note, and different systems use them differently.
You have to be sure to handle both options when receiving data or you may suddenly find that you have notes hanging. There's also an "all notes off" message that many devices just completely ignore, so some systems send a big blast of "Note C0 off, Note D0 off, Note E0 off...etc to switch off all the notes. It's messy. Such a shame that this "standard" has no discernible standard to it... ;) |
Beta Was this translation helpful? Give feedback.
-
Matt,
Is is possible to use a USB MIDI object? It looks like a new USB Device needs to be added to the menu in the IDE so as to select a define at the bottom of the USB.h file. I tired dropping in a MIDI object in the hopes that your a genius and would make the descriptors just work..
My code complies when I add: MIDI.begin(); but I don't seen the MIDI device enumerate:
Jacob
Beta Was this translation helpful? Give feedback.
All reactions