Oh mmm… But impossible difficult?
I would create two separate ring buffers for incoming data on the USB and DIN port and assign timestamps to the messages.
On the receive routine (there’s one for each input)
- get byte
- track running status
- when a message is complete, insert it into the ring buffer
Then on the send-routine
- look at the two messages on the tail of both buffers, and determine which of the two messages has the lower timestamp
- send that message
Whenever one of the two messages is a sysex-start message: Go into sysex mode, where only messages from one buffer are sent until the sysex string is over.
Yes, there is a chance for buffer overflow, but that’s there with usb midi to din midi converters anyway.
Doesn’t look too difficult at the first glance. Am I missing something?
Will the resolution of whatever clock you use for timestamping be sufficient? I’ve found that using a globally incremented counter can be cheaper than getting a timestamp, but YMMV.
You could decide to re-order messages to give MIDI Clock priority over everything else. Or maybe not.
Some controllers and a lot of software will continue to generate MIDI CC messages for the controller number even when the controller value doesn’t change. You can test for this by drawing a long continuous curve in Ableton Live, for example. This seems a case of lazy programming, because even though it won’t be an issue with MIDI-over-USB, this can easily clog up classic DIN MIDI. You could improve this be dropping subsequent messages with the same controller number and value when going from USB to DIN.
“a globally incremented counter”
Yea, I thought that as well, right after I posted my message. Way better than a timestamp.
Yeah I actually use ring buffers. In the version with only incoming USB ports and outgoing DIN I used only 1 ring buffer which is filled by both the USBs and drained by the DIN sending thread. USB messages always arrive completely (beside sysex), so it’s easy. But now, DIN IN arrives slowly byte for byte… I need an own buffer for this.
I consider to bypass the clock byte to the tail of the ring buffer (and cut the non-master clock bytes).
In the end you could receive serveral “active sensing” bytes (0xfe) which all have to cut and a new active sensing message has to create on top of all.
For timing I’ll use a 1 ms hardware timer.
Fortunately, the box is not designed to receive Ableton Live signals.
1ms timer… Isn’t that way too slow for any serious usb midi stuff? Heck, even a standard 31250baud midi message with running status (2bytes) is faster than 1ms. Why not simply use a global counter?
I wanted to use the 1 ms timer for creating the active sensing message which is 300 ms each. If I need midi message timing I could use the 1 us hardware timer. In fact if I feed the out-buffer from the 3 in-threads it’s a first come first serve without the need of a timestamp.
You need the timestamp (or better: a global counter) for determining what to send first, when mutiple in-queues have data available. Unless, of course, you want to give priority to a specific port.
In my approach each message goes instantly to the head of the out-queue when it’s arrived - so they are transmitted in the order of appearance automatically. The RTOS runs 4 threads: 3 reading threads filling the transmission queue and 1 writing thread draining the queue.
firmware v1 is working (2 hosted USB MIDI controllers merged into 1 DIN MIDI OUT).
(look for the attached .c file, in color pdf for convenience)
hardware v1 finalized, parts, pcbs, and cases ordered.
shiftr volunteered for beta testing (thanks!)
Would be interested in one of these when it’s finished!
+1 watching this thread!
Bookmarked Interested in a populated PCB!
I’d be in for a beta test as well, but I can’t solder anything atm.
Count me in!
I’ve been fooling around with arduino to free my Push from the computer. Your solution looks much neater!
The first small production batch is ready to release into the wild. It’s name is USBpal.
- connects USB-only keyboards or controller to DIN-MIDI synths
- hosts (and powers) 1 or 2 MIDI class compliant USB controller
- merges and transmits MIDI messages to legacy DIN MIDI out
- the device sending the first MIDI clock message will be treated as clock master; clock messages from a second device (if connected) will be blocked
- supports MIDI running status
- mini-USB socket for 5V DC in
- supports firmware update via USB memory stick
- comes in 3 options: ready-to-run in full metal case, ready-to-run populated PCB, bare PCB
- full open source; everybody is welcome to contribute or extend
- new development from scratch; teething troubles cannot be ruled out
- beta-tester @shiftr reported some latency in the range of 10 ms in his setup. I could not find a reason, my feeling is the keyboard play is pretty responsive
- heavy USB-MIDI traffic could overload the DIN MIDI; it’s not a bug, it’s due to the different speed specifications
- I need input from the first adopters to optimize (if)
- firmware implementation of the hidden DIN-MIDI IN
- I discovered that certain non-class compliant devices could also be handled
- I have ideas for easter eggs
Images and sources (firmware and hardware):
USBpal_source.zip (247.3 KB)
Interested parties please PM.
Prices here. Shipping around 5 € worldwide (the pcb even less).
As Picard says i have one and tested it.
I also have a KENTON USB host. I compared it to that.
The USBpal is better in that it will run some USB devices the KENTON won’t. (e.g. the Korg Microkeys)
And it can use 2 (!) controllers at the same time . So you can plug in a keyboard and a knob or fader controller.
Downside is that it feels a slightly less responsive than the KENTON. Like a small amount of latency. Maybe most people won’t notice and especially not if don’t try to compare it to something else. If it is open source maybe someone will find out ?
I was thinking of a way to measure it but i don’t know of a way to inject controlled USB midi into the thing yet.
Thanks Shiftr. That’s also my hope that the community would contribute some USB-programming hints.
PM’d. Exciting! Do you have a BOM?
edit: Aha Eagle files in the zip! I can use those for a BOM.