Skip to content

Commit f0acba4

Browse files
authored
Merge pull request #215 from kaysievers/midi-port-names
MIDI: support port name strings
2 parents 4bcc82a + 466355c commit f0acba4

File tree

5 files changed

+79
-2
lines changed

5 files changed

+79
-2
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*********************************************************************
2+
Adafruit invests time and resources providing this open source code,
3+
please support Adafruit and open-source hardware by purchasing
4+
products from Adafruit!
5+
6+
MIT license, check LICENSE for more information
7+
Copyright (c) 2019 Ha Thach for Adafruit Industries
8+
All text above, and the splash screen below must be included in
9+
any redistribution
10+
*********************************************************************/
11+
12+
// This sketch is enumerated as USB MIDI device with multiple ports
13+
// and how to set their name
14+
15+
#include <Arduino.h>
16+
#include <Adafruit_TinyUSB.h>
17+
#include <MIDI.h>
18+
19+
// USB MIDI object with 3 ports
20+
Adafruit_USBD_MIDI usb_midi(3);
21+
22+
void setup()
23+
{
24+
pinMode(LED_BUILTIN, OUTPUT);
25+
26+
#if defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_RP2040)
27+
// Manual begin() is required on core without built-in support for TinyUSB such as mbed rp2040
28+
TinyUSB_Device_Init(0);
29+
#endif
30+
31+
// Set name for each cable, must be done before usb_midi.begin()
32+
usb_midi.setCableName(1, "Keyboard");
33+
usb_midi.setCableName(2, "Drum Pads");
34+
usb_midi.setCableName(3, "Lights");
35+
36+
usb_midi.begin();
37+
}
38+
39+
void loop()
40+
{
41+
digitalWrite(LED_BUILTIN, HIGH);
42+
delay(1000);
43+
44+
digitalWrite(LED_BUILTIN, LOW);
45+
delay(1000);
46+
}

src/arduino/Adafruit_USBD_Device.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,18 @@ void Adafruit_USBD_Device::setSerialDescriptor(const char *s) {
126126
_desc_str_arr[STRID_SERIAL] = s;
127127
}
128128

129+
// Add a string descriptor to the device's pool
130+
// Return string index
131+
uint8_t Adafruit_USBD_Device::addStringDescriptor(const char *s) {
132+
if (_desc_str_count >= STRING_DESCRIPTOR_MAX || s == NULL) {
133+
return 0;
134+
}
135+
136+
uint8_t index = _desc_str_count++;
137+
_desc_str_arr[index] = s;
138+
return index;
139+
}
140+
129141
void Adafruit_USBD_Device::task(void) { tud_task(); }
130142

131143
bool Adafruit_USBD_Device::mounted(void) { return tud_mounted(); }

src/arduino/Adafruit_USBD_Device.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434

3535
class Adafruit_USBD_Device {
3636
private:
37-
enum { STRING_DESCRIPTOR_MAX = 8 };
37+
enum { STRING_DESCRIPTOR_MAX = 12 };
3838

3939
// Device descriptor
4040
tusb_desc_device_t _desc_device __attribute__((aligned(4)));
@@ -88,6 +88,8 @@ class Adafruit_USBD_Device {
8888
void setSerialDescriptor(const char *s);
8989
uint8_t getSerialDescriptor(uint16_t *serial_utf16);
9090

91+
uint8_t addStringDescriptor(const char *s);
92+
9193
//------------- Control -------------//
9294

9395
bool begin(uint8_t rhport = 0);

src/arduino/midi/Adafruit_USBD_MIDI.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ static uint16_t midi_load_descriptor(uint8_t *dst, uint8_t *itf) {
5858

5959
Adafruit_USBD_MIDI::Adafruit_USBD_MIDI(uint8_t n_cables) {
6060
_n_cables = n_cables;
61+
memset(_cable_name_strid, 0, sizeof(_cable_name_strid));
6162

6263
#ifdef ARDUINO_ARCH_ESP32
6364
// ESP32 requires setup configuration descriptor within constructor
@@ -69,6 +70,17 @@ Adafruit_USBD_MIDI::Adafruit_USBD_MIDI(uint8_t n_cables) {
6970

7071
void Adafruit_USBD_MIDI::setCables(uint8_t n_cables) { _n_cables = n_cables; }
7172

73+
bool Adafruit_USBD_MIDI::setCableName(uint8_t cable_id, const char *str) {
74+
if (cable_id == 0 || cable_id > sizeof(_cable_name_strid)) {
75+
return false;
76+
}
77+
78+
uint8_t strid = TinyUSBDevice.addStringDescriptor(str);
79+
_cable_name_strid[cable_id] = strid;
80+
81+
return strid > 0;
82+
}
83+
7284
bool Adafruit_USBD_MIDI::begin(void) {
7385
if (!TinyUSBDevice.addInterface(*this)) {
7486
return false;
@@ -105,7 +117,7 @@ uint16_t Adafruit_USBD_MIDI::makeItfDesc(uint8_t itfnum, uint8_t *buf,
105117

106118
// Jack
107119
for (uint8_t i = 1; i <= _n_cables; i++) {
108-
uint8_t jack[] = {TUD_MIDI_DESC_JACK(i)};
120+
uint8_t jack[] = {TUD_MIDI_DESC_JACK_DESC(i, _cable_name_strid[i])};
109121
memcpy(buf + len, jack, sizeof(jack));
110122
len += sizeof(jack);
111123
}

src/arduino/midi/Adafruit_USBD_MIDI.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ class Adafruit_USBD_MIDI : public Stream, public Adafruit_USBD_Interface {
3434

3535
void setCables(uint8_t n_cables);
3636

37+
// Set the cable number with a USB device descriptor string
38+
// Note: per MIDI specs cable_id (or jackid/elementid) starting from 1. 0 is
39+
// reserved for undefined ID.
40+
bool setCableName(uint8_t cable_id, const char *str);
3741
bool begin(void);
3842

3943
// for MIDI library
@@ -65,6 +69,7 @@ class Adafruit_USBD_MIDI : public Stream, public Adafruit_USBD_Interface {
6569

6670
private:
6771
uint8_t _n_cables;
72+
uint8_t _cable_name_strid[8];
6873
};
6974

7075
#endif /* ADAFRUIT_USBD_MIDI_H_ */

0 commit comments

Comments
 (0)