lathoub / Arduino-USBMIDI

Allows a microcontroller, with native USB capabilities, to appear as a MIDI device over USB to a connected computer
MIT License
148 stars 11 forks source link

Is it possible to have 2 USB MIDI ports in different cables numbers? #3

Open sanotronics opened 3 years ago

sanotronics commented 3 years ago

Hi!

I am trying to make my device show 2 different USB-MIDI ports to the computer.

Is this possible?

I am trying like this:

USBMIDI_CREATE_DEFAULT_INSTANCE()
USBMIDI_CREATE_INSTANCE(4, MIDIOUT)

and then

MIDI.begin(MIDI_CHANNEL_OMNI); 
MIDI.turnThruOff(); 

MIDIOUT.begin(MIDI_CHANNEL_OMNI); 
MIDIOUT.turnThruOff(); 

But I only see the first MIDI port.

In the examples I see that there is one for a Hardware MIDI and USB midi ports, but I don't see an example with 2 USB ports.

Thanks!

sanotronics commented 3 years ago

I just found this one in the repo (i had an outdated version downloaded) https://github.com/lathoub/Arduino-USBMIDI/blob/master/examples/SysEx_Teensy4.1/SysEx_Teensy4.1.ino

but I don't see the USB ports when I load it to my board (Arduino M0 based)

lathoub commented 3 years ago

Hi @sanotronics Cable's are indeed the way to go. This lib using the underlying MIDIUSB lib for all USB heavylifting. Have you tried to get the M0 to work in that?

sanotronics commented 3 years ago

Hi!

I am using the code I paste below compiling for my board to try and make it work. It is derived from the example I linked before The USB stuff is there cause I made changes to the main.cpp, so I can set the name of the device and set PID from an EEPROM configuration.

The MIDI instance on cable 0 works alright, I can see it and I can see the incoming MIDI messages. The second MIDI instance I cannot see it as a separate port.

Maybe I am missing something of the theory but I'd expect the second port/cable to appear as a "KilomuxV2-2" or something similar to the original name of the USB-MIDI device. If this weren't the case, then how would I address each cable separately from a DAW, for example?

Thanks for the help!

#include <USB-MIDI.h>

byte sysex11[] = { 0xF0, 0x43, 0x20, 0x7E, 0x4C, 0x4D, 0x20, 0x20, 0x38, 0x39, 0xF7 };
byte sysex15[] = { 0xF0, 0x43, 0x20, 0x7E, 0x4C, 0x4D, 0x20, 0x20, 0x38, 0x39, 0x37, 0x33, 0x50, 0x4D, 0xF7 };

// Make sure the USB-TYPE is set to MIDIx4 in Tools
USBMIDI_CREATE_INSTANCE(0, MIDI1) // Cable 0
USBMIDI_CREATE_INSTANCE(1, MIDI2) // Cable 1

// DEFINITIONS FOR USB INITIALIZATION
#define MICROCHIP_VID         0x04D8  // Microchip's USB sub-licensing program (https://www.microchip.com/usblicensing)
#define DEFAULT_PID           0xEBCA  // Assigned to Yaeltex

// Arduino core definitions for product name, manufacturer name, and PIDs
extern uint8_t STRING_PRODUCT[];
extern uint8_t STRING_MANUFACTURER[];
extern DeviceDescriptor USB_DeviceDescriptorB;
extern DeviceDescriptor USB_DeviceDescriptor;

unsigned long t0 = millis();

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void setup()
{
  // MODIFY DESCRIPTORS TO RENAME CONTROLLER
  strcpy((char*)STRING_PRODUCT, "KilomuxV2");
  strcpy((char*)STRING_MANUFACTURER, "Yaeltex");
  USB_DeviceDescriptor.idVendor = MICROCHIP_VID;
  USB_DeviceDescriptorB.idVendor = MICROCHIP_VID;
  USB_DeviceDescriptor.idProduct = DEFAULT_PID;
  USB_DeviceDescriptorB.idProduct = DEFAULT_PID;

  // INIT USB DEVICE (this was taken from Arduino zero's core main.cpp - It was done before setup())
  #if defined(USBCON)
    USBDevice.init();
    USBDevice.attach();
  #endif

  MIDI1.begin(1);
  MIDI2.begin(1);
}

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void loop()
{
  // Listen to incoming notes
  //MIDI1.read();
 //MIDI2.read();

  // send 10 SysEx per second
  if ((millis() - t0) > 400)
  {
    t0 = millis();

    MIDI1.sendSysEx(sizeof(sysex11), sysex11, true);
    MIDI2.sendSysEx(sizeof(sysex15), sysex15, true);
  }

}
sanotronics commented 3 years ago

I also tried to change the cable number to something different than 0 on the first port and then I still see the port on the midi monitor but not the Sysex messages.

And if I set the second instance to cable 0 (MIDI2) I see the sysex15 message in the monitor, instead of the sysex11.

If I set both instances to cable 0, both messages, sysex11 and sysex15 arrive.

Could only cable 0 be working properly?

sanotronics commented 3 years ago

It'd be really useful to get to the bottom of this, please @lathoub can you tell me if for you this just works and you see 2 USB-MIDI ports on your computer just by defining two instances of the MIDI objects?

thanks

BobKerns commented 3 years ago

I've been trying to do the same thing—OSX Catalina, Seeeduiono XIAO. Oddly, the cable # doesn't seem to actually matter—usually. I saw some inconsistent results that seemed to suggest that the order of definition mattered, but wasn't able to reproduce it.

But when I feel back again to a single cable, and tried a cable # of 7 to confirm the cable # doesn't matter for this report, the result was it killed my box (as in, now I have to perform surgery on a sealed box to get it back to the bootloader—yeah, I lost the bet that I'd not ever have to do that again!)

This suggests to me an inconsistency in how it's registering and accessing by cable #.

And possibly an easily-reproduced test case: Allocate a single cable with idx 7 (or perhaps other indexes depending on memory layout) but no cable 0.

I hope that helps—and wish me luck on opening this sealed Altoid box, if you can stop laughing! LOL

BobKerns commented 3 years ago

Alas, it appears to not be so easily reproduced. It only took me about 10 minutes to get into my Altoid box; the debonder solution was impressive! But a bare cable 7 seems to work, so I may not have added much information here.

I do know the Mac supports multiple virtual cables via USB, as my Prosonus ATOM SQ manages the feat.

BobKerns commented 3 years ago

One more bit of info: the cable # does matter for receive.