Skip to content

Commit 001fb7d

Browse files
committed
MIDI: support virtual wires/plug
Allow to specify the number of virtual wires/plugs to be created for the MIDI interface. Initializing the MIDI device with: Adafruit_USBD_MIDI usb_midi(3); xports a single device with three separate ports/jacks/wires. The ID (4 bit) of the jack/port is carried in the header packet of the USB MIDI wire message.
1 parent aec6460 commit 001fb7d

File tree

2 files changed

+53
-8
lines changed

2 files changed

+53
-8
lines changed

src/Adafruit_USBD_MIDI.cpp

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,14 @@
3333
#define EPIN 0x80
3434
#define EPSIZE 64
3535

36-
Adafruit_USBD_MIDI::Adafruit_USBD_MIDI(void)
36+
Adafruit_USBD_MIDI::Adafruit_USBD_MIDI(void) :
37+
_n_cables(1)
3738
{
39+
}
3840

41+
Adafruit_USBD_MIDI::Adafruit_USBD_MIDI(uint8_t n_cables) :
42+
_n_cables(n_cables)
43+
{
3944
}
4045

4146
bool Adafruit_USBD_MIDI::begin(void)
@@ -47,12 +52,49 @@ bool Adafruit_USBD_MIDI::begin(void)
4752

4853
uint16_t Adafruit_USBD_MIDI::getDescriptor(uint8_t itfnum, uint8_t* buf, uint16_t bufsize)
4954
{
50-
// usb core will automatically update endpoint number
51-
uint8_t desc[] = { TUD_MIDI_DESCRIPTOR(itfnum, 0, EPOUT, EPIN, EPSIZE) };
52-
uint16_t const len = sizeof(desc);
55+
uint16_t len = 0;
56+
57+
if (bufsize < TUD_MIDI_DESC_HEAD_LEN + TUD_MIDI_DESC_JACK_LEN * _n_cables + TUD_MIDI_DESC_EP_LEN(_n_cables) * 2)
58+
return 0;
59+
60+
{
61+
uint8_t desc[] = { TUD_MIDI_DESC_HEAD(itfnum, 0, _n_cables) };
62+
memcpy(buf + len, desc, sizeof(desc));
63+
len += sizeof(desc);
64+
}
65+
66+
for (uint8_t i = 1; i <= _n_cables; i++) {
67+
uint8_t jack[] = { TUD_MIDI_DESC_JACK(i) };
68+
memcpy(buf + len, jack, sizeof(jack));
69+
len += sizeof(jack);
70+
}
71+
72+
// Endpoint OUT + jack mapping - usb core will automatically update endpoint number
73+
{
74+
uint8_t desc[] = { TUD_MIDI_DESC_EP(EPOUT, EPSIZE, _n_cables) };
75+
memcpy(buf + len, desc, sizeof(desc));
76+
len += sizeof(desc);
77+
}
78+
79+
for (uint8_t i = 1; i <= _n_cables; i++) {
80+
uint8_t jack[] = { TUD_MIDI_JACKID_IN_EMB(i) };
81+
memcpy(buf + len, jack, sizeof(jack));
82+
len += sizeof(jack);
83+
}
84+
85+
// Endpoint IN + jack mapping - usb core will automatically update endpoint number
86+
{
87+
uint8_t desc[] = { TUD_MIDI_DESC_EP(EPIN, EPSIZE, _n_cables) };
88+
memcpy(buf + len, desc, sizeof(desc));
89+
len += sizeof(desc);
90+
}
91+
92+
for (uint8_t i = 1; i <= _n_cables; i++) {
93+
uint8_t jack[] = { TUD_MIDI_JACKID_OUT_EMB(i) };
94+
memcpy(buf + len, jack, sizeof(jack));
95+
len += sizeof(jack);
96+
}
5397

54-
if ( bufsize < len ) return 0;
55-
memcpy(buf, desc, len);
5698
return len;
5799
}
58100

@@ -85,4 +127,3 @@ void Adafruit_USBD_MIDI::flush (void)
85127

86128
#endif
87129

88-

src/Adafruit_USBD_MIDI.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class Adafruit_USBD_MIDI : public Stream, Adafruit_USBD_Interface
3131
{
3232
public:
3333
Adafruit_USBD_MIDI(void);
34+
Adafruit_USBD_MIDI(uint8_t n_cables);
3435

3536
bool begin(void);
3637

@@ -44,8 +45,11 @@ class Adafruit_USBD_MIDI : public Stream, Adafruit_USBD_Interface
4445
virtual int peek ( void );
4546
virtual void flush ( void );
4647

47-
// fron Adafruit_USBD_Interface
48+
// from Adafruit_USBD_Interface
4849
virtual uint16_t getDescriptor(uint8_t itfnum, uint8_t* buf, uint16_t bufsize);
50+
51+
private:
52+
uint8_t _n_cables;
4953
};
5054

5155
#endif /* ADAFRUIT_USBD_MIDI_H_ */

0 commit comments

Comments
 (0)