MUFF WIGGLER Forum Index
 FAQ & Terms of UseFAQ & Terms Of Use   Wiggler RadioMW Radio   Muff Wiggler TwitterTwitter   Support the site @ PatreonPatreon 
 SearchSearch   RegisterSign up   Log inLog in 
WIGGLING 'LITE' IN GUEST MODE

Design of an 8 channel MIDI switch and questions
MUFF WIGGLER Forum Index -> Music Tech DIY  
Author Design of an 8 channel MIDI switch and questions
Grumble
Hello,

I'm in the process of designing a MIDI switch for my modular.
Reason is that I have several modules with a midi input, and want to be able to connect a device (e.g. a midi player on my PC ) that addresses multiple channels (= multiple modules in my synth) I am designing a module that puts out 8 midi channels.
Already a basic switch is working on my breadboard with 4 channels, for the proof of concept.
What I do in this proof of concept, is using an arduino to have the channel number output to a 74LS138 and feed the midi output of the arduino into the enable input of the 74LS138 and the outputs of the 74LS138 to a midi connector of the channel I want to address.
Also every channel gives out a trigger pulse (not in the schematics, and I could change this in a gate)

I have "some" knowledge about Midi, but maybe there is something I MUST implement to make this switch more useful, anybody some ideas, comments?
berenie
Are you separating midi channels with the arduino? thus filtering out midi data?

The word ''switch'' is a bit confusing here.. unless you are switching on / off or choosing midi outputs?

if its simply a utility thing what is the problem with midi thru (box) hmmm.....
sneak-thief
I highly doubt that multiplexing a single 31.25kpbs serial output to 8 destinations with 8 different data streams is going to work, especially not with an arduino uno/nano.
Grumble
By "switch" I mean that data for channel 1 is going to midi out 1, data for channel 2 is going to midi out 2 etc.
But to make things less complicated I just send the three bytes for note on and note off data.
And so far it is working with 4 data streams, so why not 8.. (see the schematics)
btw: I'm not using the arduino ide, but program the processor directly with Atmel Studio.
Grumble
sneak-thief wrote:
I highly doubt that multiplexing a single 31.25kpbs serial output to 8 destinations with 8 different data streams is going to work, especially not with an arduino uno/nano.

It really is not a problem doing 8 channels or even 32 channels with an Arduino Nano/Uno.
Look at the schematic...
Graham Hinton
Grumble wrote:

It really is not a problem doing 8 channels or even 32 channels with an Arduino Nano/Uno.
Look at the schematic...


How are you going to detect that a message has finished before switching and sending another?
If you truncate a message all hell can break loose.
Grumble
First I check if the received byte contains 0x90 (note-on) or 0x80 (note-off), if that is the case I send the lowest 4 bits to the 74LS138 (being the channel number) and then I send the received byte via the uart of the Arduino to the enable input of the 74LS138 thus sending this byte to the desired channel.
After this I know that there are 2 more bytes to be expected, and these bytes are also copied to the output of the uart and sent to the desired channel.
Only snag is that some keyboards (like my old target keyboard) doesn't send note-off but just a note-on with 0 velocity. But I take that into account.
So the "switch" is pointing at a certain channel until it is changed by a note-on or note-off for a different channel.
Graham Hinton
Grumble wrote:
So the "switch" is pointing at a certain channel until it is changed by a note-on or note-off for a different channel.


When that happens you may still be transmitting the previous data. As MIDI is lsb first, any corruption turns it into status bytes. You need to know that the UART Tx queue is emptied.
Grumble
ok good point, will check for that
Synthiq
Normally you just set the first module to MIDI channel 1 and the second to channel 2 and so on and send the same data to all of them in parallel (or in series with MIDI-THRU to MIDI-IN between modules). Are the MIDI channels fixed in your case so you can't do that here?
xythyl
So instead of setting the channel number on the midi inputs and using a midi thru box, you're having the box output to a predetermined channel for each output? Wouldn't the midi thru box be easier? Unless the midi channel can't be changed on the inputs.
Graham Hinton
Grumble wrote:
ok good point, will check for that


You will need to check the Transmit Complete (TXC) flag before changing the switch. This raises the problem of what to do with incoming messages while waiting... The Atmega328 does have a receive FIFO, but I couldn't see how long that is in the datasheet.

The worst case to deal with is the burst of messages that sequencers tend to emit when you hit Stop, especially if it is Running Status and you are adding the Status bytes, hence getting further delayed. You only have to drop one byte and everything gets out of step and receiving modules get stuck with, e.g, random Pitchbends and Controllers (from corrupted data) that can only be cleared by powering down.

One of the difficulties in processing MIDI is that you have to be able to deal with anything and everything that can come down the cable. You can't just pick the parts you are interested in and ignore the rest. It may be a trivial application, but it's non-trivial programming and debugging.
Grumble
The modules that have midi input are fixed. They all used to react to channel 0 but I have changed that and now they react to all channels, but get only the data for the channel I want them to.
My argument for doing it this way is that since a modular is never finished and every module sounds different (mainly because I design and build them) I feel the need for patching the channels.
Besides that: I can't play keyboard so I'm depending on midi files from others and this way I can choose the best sounding module for the channels in the midi file.
Grumble
Quote:
One of the difficulties in processing MIDI is that you have to be able to deal with anything and everything that can come down the cable.

Well... no. I just need the note-on and note-off messages with their accompanying two bytes (note number and velocity) because these are the commands my modules understand.
And I'm just going to use it on my synth anyway...
Synthiq
Graham Hinton wrote:
The Atmega328 does have a receive FIFO, but I couldn't see how long that is in the datasheet.

Buried in the description of the USART, the datasheet says the receiver has a shift register and a two level buffer.

Ideally, the data rate at the input and output are the same so input data can be processed and sent out at the same rate as they are received and there should be no buffer issues. In reality, the oscillator frequencies in the sender and receiver differ somewhat. If both are crystal controlled the difference is quite small and even if the incoming data stream is faster than the outgoing stream, it will take thousands of bytes before the outgoing stream lags even one byte behind but can be much worse if an internal 1% oscillator is used. Another issue that will slow down the output stream is the fact that the processor has to wait to the end of a byte before it can switch to another output and then transmit another byte. This small gap between bytes will add up to another delay. If either of these cause problems it may be necessary to add a buffer that holds the bytes that can't be transmitted fast enough. This is really only a problem if you expect a more or less continuous MIDI stream but can be ignored if you only receive a MIDI message every few milliseconds or so.
Grumble
In my code the output to the UART is far less than the input of the UART because I only use the three bytes for the note-on and note-off messages, all other data is filtered out because my modules have no clue what to do with these, they are quite stupid and ignorant meh
Basically what I do is wait for note-on, output the channel number to the multiplexer (74LS138), output the received byte to the UART, make the trigger or gate for this channel high, wait for the note-number, send this to the UART, wait for the velocity and send this to the UART and make the trigger for this channel low.
Next is to wait for the note-off, output the channel number to the multiplexer (74LS138), output the received byte to the UART, wait for the note-number, send this to the UART, wait for the velocity and send this to the UART and make the gate for this channel low.
So my guess is that there is no need for a fifo, because of the very small amount of time between receiving and sending. I use no interrupts, this is all done by polling the register saying there has been data received.
sneak-thief
What is your time worth for this experiment?

Why not simply take the incoming midi and split it 8 ways with logic gates / buffers and buy 7 more arduinos for $10.

That way you can customize the output of each arduino and not have to ever worry about midi jitter or garbled data.

http://www.ebay.com/itm/Pro-Mini-atmega168-3-3V-8M-Arduino-Compatible- Nano-replace-Atmega328-M123-/301741888321?epid=1948501471&hash=item464 137d341:g:jCQAAOSwyvBV-NDf
Grumble
Maybe you should look at my synth Mr. Green
Besides, it's my hobby, I don't calculate in time, just in fun (and money of course d'oh! )
sneak-thief
Yup, I also have a DIY-only setup that I built over a decade... http://sneak-thief.com/modular/spring-2014-modular.jpg

So at least from my perspective, troubleshooting notes that hang and midi jitter isn't in my list of fun things, even from a hardcore diy-perspective.
MUFF WIGGLER Forum Index -> Music Tech DIY  
Page 1 of 1
Powered by phpBB © phpBB Group