T4 Using USB Host with MIDI?

Status
Not open for further replies.

blakeAlbion

Well-known member
Hello!

I have a Teensy USB Host adapter, and I have a Waldorf Blofeld with USB Midi support.
I am working on a MIDI Controller made especially for all the knobs in a Blofeld. It would be nice to use the USB port on the Blofeld so the 5-pin MIDI ports are still free for studio use.
Can I host the Blofeld on my Teensy and both send and receive MIDI messages using the "standard" MIDI library?
I am looking to port my prototype, done on a DUE, to Teensy 4.1. In the Arduino Due, I could never successfully send MIDI when using an OTG USB adapter on the "native USB" port.

If the answer is "no" I will simply limit this to 5-pin MIDI.

Thanks,

Ben
 
Can I host the Blofeld on my Teensy and both send and receive MIDI messages using the "standard" MIDI library?n

@blakeAlbion:

I am not familiar with the specific piece of equipment that you called out (Waldorf Blofeld), but maybe if I describe how portions of my updated TeensyMIDIPolySynth have been confirmed to work, it might provide some potential clues towards answering your question:

Using a Teensy 4.x, I have received MIDI in from all of the following interfaces:

1) USB (connecting a PC, running a MIDI player)
2) USBhost (from a USB MIDI keyboard plugged into the USBhost port, either playing it or running its sequencer...also from one Teensy 4.x USB sending MIDI to another Teensy 4.x USBhost receiving MIDI)
3) standard 5-pin DIN (traditional MIDI, connecting a USB-to-MIDI adapter on the PC & feeding the 6N138 circuit shown on the MIDI webpage...also connecting the USB-to-MIDI adapter to the USBhost on the Teensy 4.x & connecting an additional traditional 5-pin DIN device to the USB-to-MIDI adapter, with the additional device playing thru this chain of connections to the Teensy 4.x)

When receiving MIDI input from any of these interfaces, these MIDI messages can be sent back out any/all of these interfaces using the standard MIDI library. With the exception of the traditional 5-pin DIN (which has software control of MIDI-thru), most of the interfaces require making a specific function call [sendXXX()] that sends the message(s) back out (at least, that's the case with the way that I have implemented it so I can provide enable/disable control the MIDI-thru on each of these interfaces).

So, based upon what I've seen and/or implemented, I'd say that, as long as the Teensy USBhost interface recognizes your specific device, then you should be able to accomplish what you are after (if I am understanding correctly). Note that there have been reports of some devices showing up as multiple USB "endpoints", so you may want to search the forum around that topic if you suspect that kind of behavior with your device connected via USB.

Good luck & have fun !!

Mark J Culross
KD5RXT
 
Thanks!
I guess what I am trying to understand is, is there any functional difference between "MIDI over USB" and "MIDI over USB via USB HOST"?
I made a Teensy drum machine and I have USB MIDI support in that project. It just works. I get a kick out of seeing "Teensy" show up in the MIDI port selector in Ableton. If "USB Host" mode is the same, I should be ready to rock.

But, if the Teensy is the USB host, does MIDI work the same way? Is it supported?
(sorry if you already answered my question)
 
But, if the Teensy is the USB host, does MIDI work the same way? Is it supported?
(sorry if you already answered my question)

I think the short answer is yes. Other than declaring the use of the specific devices (usb, usbhost, midi) & making calls using the specific device names [usb.sendNoteOn(), usbhost.sendNoteOn(), midi.sendNoteOn()], all else should be the same. Let me get to my other computer (normally, I push intermediate versions out to my Google Drive for "off-site archiving/backup", which makes it easy to access from any of my computers, but I've been having so much fun lately that I've been remiss in doing so . . . not intending to invite Murphy to the party with that comment !!) & I'll include a few specific code snippets to see if I can definitively answer your question . . .

Mark J Culross
KD5RXT
 
Includes for the different devices:

Code:
#include <USBHost_t36.h>
#include <MIDI.h>

Declaring the different devices (I threw the hub in there just in case I decided to connect a USB hub on the USBhost port . . . I think that's what it's doing for me, but I have not specifically verified that):

Code:
USBHost thisUSB;
USBHub hub1(thisUSB);
USBHub hub2(thisUSB);
MIDIDevice_BigBuffer usbhostMIDI(thisUSB);

Initialize the traditional 5-pin DIN MIDI (on pins 0 & 1):

Code:
MIDI_CREATE_DEFAULT_INSTANCE();

Set the callbacks for the usb device (using NoteOn as just one example):

Code:
   usbMIDI.setHandleNoteOn(USBhandleNoteOn);

Set the callbacks for the traditional 5-pin DIN MIDI device (using NoteOn as just one example):

Code:
   MIDI.setHandleNoteOn(MIDIhandleNoteOn);

Set the callbacks for the USBhost device (using NoteOn as jut one example):

Code:
   usbhostMIDI.setHandleNoteOn(USBhandleNoteOn);

Start the devices (not sure why there isn't a corresponding begin call for the USB MIDI device):

Code:
   // start the USBhost for MIDI inputs/devices
   usbhostMIDI.begin();

   // Initiate MIDI communications, listen to all channels
   MIDI.begin(MIDI_CHANNEL_OMNI);

For each type of MIDI message (I'll use AfterTouchPoly as just one example), I have a common low-level handler for each type of message [e.g. handleAfterTouchPoly()], with a separate high-level handler for each type of interface, for example, you can see this one forwarding the message selectively to the other interfaces:

Code:
// MIDI message callback - after touch poly via USB
void USBhandleAfterTouchPoly(midi::DataByte note, midi::DataByte pressure, midi::Channel channel)
{
   if (midiFWDtoMIDIButton.activated)
   {
      // echo the After Touch Poly message to MIDI out
      MIDI.sendAfterTouch(pressure, channel);
   }

   if (midiFWDtoHOSTButton.activated)
   {
      // echo the After Touch Poly message to usbhostMIDI out
      usbhostMIDI.sendAfterTouch(pressure, channel);
   }

   handleAfterTouchPoly(note, pressure, channel);
}  // USBhandleAfterTouchPoly()

Hope that helps to see at least what I have done, & if I'm lucky, I'm even closer to answering your question & not just muddying the waters even further !!

Mark J Culross
KD5RXT
 
Last edited:
To try answering your question....

I guess what I am trying to understand is, is there any functional difference between "MIDI over USB" and "MIDI over USB via USB HOST"?

This really depends on what you meant by "functional difference".

The short answer is they use exactly the same communication. I have made every effort to keep the functions you use as close as possible to each other and to the MIDI library (normally for 5 pin DIN serial MIDI).

Obviously there are differences between USB device and USB host. On the hardware side, you can plug a USB hub into Teensy 3.6, 4.1 (or 4.0 if you connect to the 2 tiny pads) and then plug several USB MIDI devices into the hub. USB device mode can only work with a single computer (or whatever USB host, including another Teensy). On the software side, with device mode you get a single pre-defined instance named "usbMIDI", because you can only talk to 1 host. In host mode, you create as many instances as you like and you choose the names. You also choose whether to use the normal name with works with only 12 Mbit speed devices or "BigBuffer" which supports 12 or 480 Mbit, but uses more of Teensy's memory. In device mode, the same "usbMIDI" instance has big buffers on Teensy 4.0 & 4.1 where USB can run at 480 Mbit, and small buffers on Teensy 3.x where the USB is only 12 Mbit. The USB host instances inherit some generic functions from the host library which let you read the ID numbers and name of whatever USB device connects, whereas in device mode the name Teensy sends to your PC can be changed with some special code, but it's not the sort of thing you can do as dynamically as your program runs, because it has to be built into the code so Teensy can send it to your PC (or whatever USB host) when the host wants.

Whether any of that is considered "functional difference", I'm not sure.


But, if the Teensy is the USB host, does MIDI work the same way? Is it supported?

As far as sending and receiving MIDI messages, both can send MIDI messages in both directions, though the most common usage is for MIDI messages to flow from device to host.

I have tried to keep the API as similar as possible, so any code you write for USB device mode should be easy to use with USBHost_t36 if you just change the instance name, and of course create an instance of the host library's device driver with that name.

But if you follow the most common way of doing things, typically USB MIDI devices transmit MIDI messages which represent events from human interaction, like touching buttons / keys or turning knobs or pressing pedals. Normally messages from host to device are for showing status to humans, like changing LED state & color. You're not limited to doing only those things... you can send any MIDI messages you like in either direction. But if you're building a system and especially if it will be used by other people, generally following well established conventions really helps people to understand how to use a system.
 
Thanks, PaulStoffregen!

I have been thinking about using various USB MIDI controllers directly with Teensy Audio projects (pads, mixing surfaces). This looks like a green light.
BTW, if I wanted to have more than one USB host socket, is it as simple as splitting the signal, or do I need a dedicated hub chip?
 
Status
Not open for further replies.
Back
Top