From 001fb7d99bf7c423f02f9c08d3cf6b77131506f0 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 27 Sep 2019 10:06:22 +0200 Subject: [PATCH] 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. --- src/Adafruit_USBD_MIDI.cpp | 55 +++++++++++++++++++++++++++++++++----- src/Adafruit_USBD_MIDI.h | 6 ++++- 2 files changed, 53 insertions(+), 8 deletions(-) diff --git a/src/Adafruit_USBD_MIDI.cpp b/src/Adafruit_USBD_MIDI.cpp index d7ea500a..562bb869 100644 --- a/src/Adafruit_USBD_MIDI.cpp +++ b/src/Adafruit_USBD_MIDI.cpp @@ -33,9 +33,14 @@ #define EPIN 0x80 #define EPSIZE 64 -Adafruit_USBD_MIDI::Adafruit_USBD_MIDI(void) +Adafruit_USBD_MIDI::Adafruit_USBD_MIDI(void) : + _n_cables(1) { +} +Adafruit_USBD_MIDI::Adafruit_USBD_MIDI(uint8_t n_cables) : + _n_cables(n_cables) +{ } bool Adafruit_USBD_MIDI::begin(void) @@ -47,12 +52,49 @@ bool Adafruit_USBD_MIDI::begin(void) uint16_t Adafruit_USBD_MIDI::getDescriptor(uint8_t itfnum, uint8_t* buf, uint16_t bufsize) { - // usb core will automatically update endpoint number - uint8_t desc[] = { TUD_MIDI_DESCRIPTOR(itfnum, 0, EPOUT, EPIN, EPSIZE) }; - uint16_t const len = sizeof(desc); + uint16_t len = 0; + + if (bufsize < TUD_MIDI_DESC_HEAD_LEN + TUD_MIDI_DESC_JACK_LEN * _n_cables + TUD_MIDI_DESC_EP_LEN(_n_cables) * 2) + return 0; + + { + uint8_t desc[] = { TUD_MIDI_DESC_HEAD(itfnum, 0, _n_cables) }; + memcpy(buf + len, desc, sizeof(desc)); + len += sizeof(desc); + } + + for (uint8_t i = 1; i <= _n_cables; i++) { + uint8_t jack[] = { TUD_MIDI_DESC_JACK(i) }; + memcpy(buf + len, jack, sizeof(jack)); + len += sizeof(jack); + } + + // Endpoint OUT + jack mapping - usb core will automatically update endpoint number + { + uint8_t desc[] = { TUD_MIDI_DESC_EP(EPOUT, EPSIZE, _n_cables) }; + memcpy(buf + len, desc, sizeof(desc)); + len += sizeof(desc); + } + + for (uint8_t i = 1; i <= _n_cables; i++) { + uint8_t jack[] = { TUD_MIDI_JACKID_IN_EMB(i) }; + memcpy(buf + len, jack, sizeof(jack)); + len += sizeof(jack); + } + + // Endpoint IN + jack mapping - usb core will automatically update endpoint number + { + uint8_t desc[] = { TUD_MIDI_DESC_EP(EPIN, EPSIZE, _n_cables) }; + memcpy(buf + len, desc, sizeof(desc)); + len += sizeof(desc); + } + + for (uint8_t i = 1; i <= _n_cables; i++) { + uint8_t jack[] = { TUD_MIDI_JACKID_OUT_EMB(i) }; + memcpy(buf + len, jack, sizeof(jack)); + len += sizeof(jack); + } - if ( bufsize < len ) return 0; - memcpy(buf, desc, len); return len; } @@ -85,4 +127,3 @@ void Adafruit_USBD_MIDI::flush (void) #endif - diff --git a/src/Adafruit_USBD_MIDI.h b/src/Adafruit_USBD_MIDI.h index 3ff8dee7..4b8d988f 100644 --- a/src/Adafruit_USBD_MIDI.h +++ b/src/Adafruit_USBD_MIDI.h @@ -31,6 +31,7 @@ class Adafruit_USBD_MIDI : public Stream, Adafruit_USBD_Interface { public: Adafruit_USBD_MIDI(void); + Adafruit_USBD_MIDI(uint8_t n_cables); bool begin(void); @@ -44,8 +45,11 @@ class Adafruit_USBD_MIDI : public Stream, Adafruit_USBD_Interface virtual int peek ( void ); virtual void flush ( void ); - // fron Adafruit_USBD_Interface + // from Adafruit_USBD_Interface virtual uint16_t getDescriptor(uint8_t itfnum, uint8_t* buf, uint16_t bufsize); + + private: + uint8_t _n_cables; }; #endif /* ADAFRUIT_USBD_MIDI_H_ */