MIDI implementation

@ awgrover:

Because I am not familiar with C++ and Arduino programming I was looking for a solution to build flexible MIDI Controllers. Unfortunately no graphical user interface for Arduino supports MIDI Interfaces (Visuino does not and Ardublock Jerusalab is poor). It would be a outstanding feature for XOD if MIDI is supported. This was the reason I added this to my wishlist. There are some MIDI controllers on the market but doepfer controllers are not very flexible because of their hardware jumpers and Korg Kontrol-Series has only USB-connectors. It would be nice to have a solution at hand to build a small controller for sending control and programm change massages and note on / off to build custom made controller solutions. I believe this would be a big benefit for XOD if MIDI is implemented!!! :smiley:

1 Like

Good idea. It should not be so hard to add MIDI-interfacing nodes.

Now we are working on features to greatly simplify node libraries creation, publishing, and installation. They would be available in v0.16.0. After the release anyone (and me too) could try to implement and share the midi stuff.

1 Like

@dox, Would you like to work on this? (or would anyone else like to?)

I’m willing to provide some programming expertise to create the XOD nodes, but my MIDI knowledge is quite stale (20 years old!).

Designing the node(s) is the hardest part. We should use the XOD style to do things nicer, better, and in ways that would be hard/unthinkable in typical programming style. But, we also have the goal that the nodes make sense and are easily usable (especially by “non-programmer” types, let’s call them artists).

The obvious candidate to base this on is FortySevenEffects’s midi library:
https://playground.arduino.cc/Main/MIDILibrary, though github has the code and documentation intro / api.

There is also MIDIUSB, but I’m not clear on the utility of it (and it only works a certain types of arduinos): “appear as a MIDI peripheral over USB to a connected computer”.

The FortySevenEffects library works on the default hardware serial port (shared with USB, so interferes with console & programming), or a software serial port (you choose pins), or any other hardware port (mega’s have 3 or 4).

This project would take a while, as I would only work on it in bursts once or twice a week. I’m happy to lay out the project-plan, be the benevolent project-manager. You would have to help evaluate the library for suitability/completeness, do actual tests (I have no MIDI hardware at this time), help write documentation and tutorials. I would expect us to use github, and might be talked into other tools.

Yeah! Unfortunately my time is also limited (I play around with XOD during mybreakfast- and lunchtime…) but I have some MIDI stuff at home: Masterkeyboards and MIDI-Monitoring tools. So it is not the problem to do some tests. To write some documentation would be possible but my English is not the best… :face_with_raised_eyebrow: For me it is easier to write in German or to translate some tutorials into German.

Just a few thougths: What can MIDI do? The basic function is sending note on / off messages. If a note on message is sent a sound will be generated from a “MIDI-Generator” (e.g. Synthesizer, Expander, Drumbox etc.). If you want to play some music you need a keyboard with approx. 49 keys and up (to 88 keys). It makes no sense to build a masterkeyboard with an Arduino; you can buy this in better quality ready made from different manufacturers including velocity and aftertouch. BUT it makes sense to build a small controller sending note on / off messages just with a few buttons for e.g. controlling a software-beatbox. This is much easier to realize.
A very important thing is to control MIDI-Equipement with Program Change an Controller messages. Program Change Messages change the sounds from a “MIDI-Generator-Device”. GM Standard has 128 Sounds so you need max. 128 push buttons for controlling all of them (I build a box with 64 push buttons and a switch for selecting 0 - 63 and 64 - 127 in the past). So it would also be useful to have some nodes at hand for handling lots of buttons (resistor network, matrix scanner). Sending Bank Select Messages for mor than 128 sounds is optional.
Control Change Messages control different parameters of each sound (e.g. volume, vibrato etc…) Normally potentiometers or rotary encoders are used to do this job.
Another important application for an Arduino is to manipulate MIDI-Data. Incomming MIDI-Data can be manipulated in different ways: You can merge to inputs together to one output. You can e.g. transpose MIDI-Data on all channels or one channel only. You can filter Data e.g. remove all program change messages or remove all velocity messages.

These are the applications wich make most sense for artists.

I will check the linked MIDI libraries soon!

1 Like

MIDI Data is a serial protocol like RS232 and can be converted to USB. In the past MIDI-Devices had only 5-pole connectors. Later the 5 pole connectors dissappeared more and more and many devices had both (5 pole connector and USB Interface) or USB-Connector only. For example the KORG Nanokontol Series has USB-Connectors only because these devices are used to control virtual instruments (VST) only. This is a benefit of the computer technology: In the past everithing was set in hardware; instruments and recording equipment like sequencers. Today everything is available in software. There is no need to equip the hardware nowadays with 5 pole MIDI connectors, because you need an additional MIDI converter
https://www.thomann.de/de/thomann_midi_usb_1x1.htm?sid=b99245edfc1d03bf82d9ab2cc3630ccf
to connect it to a computer.
I bought a MIDI Shield https://www.ebay.de/itm/MIDI-Shield-Musical-Breakout-Board-Instrument-Digital-Interface-Adapter-Plate/272750438796?hash=item3f8131698c:g:HJUAAOSwN2VZXafh for my Arduino. In future I can connect it with my PC using this cheap MIDI Converter. It is not necessary to add a USB Interface to my Arduino.

@dox I made some design mockups. Look at github-xod-midi. I made a bunch of notes on it’s wiki.

This is meant as a starting point, I assume my design is not very good. Please look it over and then try to design better stuff!

Other interested parties should look too, and join in the discussion.

Hello awgrover!
Just a few notes on your nodes:

  • midi-music-note: Will be useful. Musicians know the note labelings but not the equivalent MIDI-note-number.
  • midi-note-on / off: MIDI note on requires always a MIDI note off message. Otherwise the sound will hung. For example: If you press a key on a keyboard (e.g. organ manual) the sound will stop if you release the key. Pressing the key sends note on and releasing sends note off. A extra node for note off is not required an should be implemented in the note node.

Reading MIDI Data seems complicated, because of the timing problems. Merging MIDI Data would be useful, but for the first steps would it be easier to limit the whole project to sending MIDI data only?

More comments will follow soon…

I suspect performance is going to be a problem. XOD runs slow!

Latency is a problem when you handle MIDI Data. Even Computers must be optimized (e.g. with ASIO drivers) for a minimum of latency time. But latency is only important if you play an Instrument or handle (incoming) MIDI data. Example: You play a virtual isntrument on a PC. Your masterkeyboard is the controller (sending note on/off). You use a seperate pedal (switch) as sustain pedal (sending controller messages). If you play on your masterkeyboard and the latency time is long the sound is delayed. The pedal works different: It takes some time to press the pedal down with your foot. When a key is pressed and the pedal is pressed afterwards the sound will “fade out”. So it does’nt matter if you press the pedal a few milliseconds earlier or later. The sound will always fade out as long the pedal is pressed.

Processing midi may be a problem.

A latency time of 5 ms is no problem. (I think my old XP Computers have 10 - 15 ms latency time; depending on the hardware). If incoming MIDI Data can not be processed it doesn’t matter. Sending data is good for the beginning. If Arduino can not handle this there will be another platform for this issue…

FortySevenEffect's library already defaults to Serial1 on Arduino's with multiple hardware serial ports. 

It seems the 5 pole connectors on the MIDI Shield are connected to the standard serial port (RX via optocoupler / TX directly).

But, that means somewhere, somebody has defined tempo and time-signature: another node?

MIDI can also send clock-data and timestamps to synchronize different kinds of equipement. (E.g. the beatbox in my organ can send MIDI clock data to adjust the tempo off an external sequencer). At this time it will not be necessary to create additional nodes for that. Many VST software instruments have a MIDI-learn function included. All necessary adjustments can be done with note on / off and controller (program change) messages. Example: All parameters (tempo, start/stop, volume etc.) of an software beatbox emulation can be adjusted by controller messages. Press MIDI learn --> move or press the controller (to send a message) --> the controller is automatically recognized and saved.

XOD likes to set all ranges as 0..1 decimal numbers.

Labeling notes is for musicians easier to understand. Conversion from note label to note number is useful. Internally it is easier to use note numbers. Controller / Program change values are from 0 - 127.

Important for Program Change: There are also Bank Select Messages for equipement with more than 127 sound presets. http://www.chromakinetics.com/handsonic/bank.htm

For sending basic MIDI Data there are only a few commands needed:

Here the direct link: https://www.midikits.net/midi_analyser/pitch_bend.htm

Just a last post how to build “artist”-friendly nodes (suggestions):

Control Change with Button-Node:
Input:
MIDI Channel
Controller Number
Value if true (Button pressed)
Value if false (Button released)
Trigger (Button)
Output:
MIDI-Data (when Button is pressed / released)

Control Change with Potentiometer / Fader-Node:
Input:
MIDI Channel
Controller Number
Lower Value
Upper Value
Analog In
Output:
MIDI-Data (when value changes)

Note with Button-Node:
Input:
MIDI Channel
Note Number
Velocity Value if true (Button pressed)
Velocity Value if false (Button released)
Trigger (Button)
Output:
MIDI-Data (when Button is pressed / released)

Program Change-Node 1:
Input:
MIDI Channel
Program Change Number
Output:
MIDI-Data (when Button is pressed)

Program Change-Node 2:
Input:
MIDI Channel
Bank MSB
Bank LSB
Program Change Number
Output:
MIDI-Data (when Button is pressed)

If Arduino can handle incoming MIDI Data the next step could be to add these Signals to an incoming MIDI data stream.

@awgrover: Thanks for your attention!

I’m finally working on this again, going to implement your suggestions.
See below for some questions.

[dox] dox https://forum.xod.io/u/dox
December 1

Just a last post how to build “artist”-friendly nodes (suggestions):

/Control Change with Button-Node:/
Input:
MIDI Channel
Controller Number
Value if true (Button pressed)
Value if false (Button released)
Trigger (Button)
Output:
MIDI-Data (when Button is pressed / released)

I don’t understand the output. Do you mean that it should send the
midi-control-change command? Or that the node has an output pin?

/Control Change with Potentiometer / Fader-Node:/
Input:
MIDI Channel
Controller Number
Lower Value
Upper Value
Analog In
Output:
MIDI-Data (when value changes)

How do Lower-Value and Upper-Value relate to the pot? Is that the range
(so the pot generates lower…upper)? What kind of rate control do we
need/want? We don’t want to send a change-control when the pot isn’t
moving do we (which would send every 20 or so milliseconds!)? How should
we average/smooth the pot’s value? They aren’t clean/stable!

/Note with Button-Node:/
Input:
MIDI Channel
Note Number
Velocity Value if true (Button pressed)
Velocity Value if false (Button released)
Trigger (Button)
Output:
MIDI-Data (when Button is pressed / released)

/Program Change-Node 1:/
Input:
MIDI Channel
Program Change Number
Output:
MIDI-Data (when Button is pressed)

/Program Change-Node 2:/
Input:
MIDI Channel
Bank MSB
Bank LSB
Program Change Number
Output:
MIDI-Data (when Button is pressed)

If Arduino can handle incoming MIDI Data the next step could be to add
these Signals to an incoming MIDI data stream.

The arduino can handle incoming. The question is how well the XOD
generated code can cope with it. I can set up some nodes and you can
experiment.

What about multiple MIDI interfaces? Some of these nodes already have a
lot of input pins.

What I mean is: The node outputs the MIDI-Data to the MIDI-Interface. I don’t know if it is necessary to have an output pin on the node. I even don’t know the output format (number, string). Let’s have a look at the I2C-nodes in xod/core: i2c-write has two input pins (byte, send) and only an “acknowledge” output (done) pin. Where is the data gone? I think it is internally merged to the I2C-Bus. There is no need for an extra I2C-Data-Out-Pin. Because I am not familiar with programming I don’t know the best way to handle MIDI-Data streams. All MIDI-Data must be internally merged together an send to an MIDI-Out-Connector. You can decide how this will be done. :blush:

Yes! (normally 0 - 127)

Normally MIDI data is only sent by a change of the value.

Yes, this can be a problem.

There are different ways to do this:
Some masterkeyboards / controllers use rotary encoders to change the values.
Hardware construction: A small capacitor can integrate the output signal and “smoothen” the output voltage.
MIDI uses 7-Bit and Arduino 12-Bit A/D-Processing. There is a little reserve. I have to test if interference signals can be a problem too.
Perhaps a “debounce-potentiometer” is needed? I have to test it.

There is another issue I forgot to mention: Normally MIDI-Data is a one way communication. Example: You have a fader / slider sending MIDI controller messages. When you power up your equipement the fader position is normally not recognized. Lets say the expander (MIDI receiver) sets this controller to default 0 when the unit is powered up. The expander will not send this information back to the controller and the controller will not move the fader to this position automatically! Lets say the fader (MIDI sender) is in middle position (approx. 64). When you move the fader up a little controller value 65 is sent (64 → 65). The expander recognizes this signal and sets the value also to 65. This is a jump from 0 to 65 and not from 64 to 65!
The best way to avoid this problem is to add a “pulse” input pin (like awg/values/boolean). When the system is powered up all values can be sent and the MIDI-receiver “knows” the exact value of each fader.

That’s rigth! Too much MIDI-Data causes problems.

The more, the better! :grin::grin::grin:
Do you mean MIDI-Interface = Serial Interface sending / receiving MIDI-Data? All combinations are possible: MIDI out only (for building a controller box or toy keyboard), in / out (controller data merged into incoming data), 2x in + out (two MIDI-in merged together), 2x in 2x out (two MIDI-in merged together and send to two MIDI out), etc…

Please look at, test, etc.: attached midi-example-3.xodball (7.7 KB), which requires new library (awg/x-midi) in https://github.com/xodio/xod (follow README for install).

Requires the FortySevenEffects/arduino_midi_library. See INSTALL below.

  • Library awg/x-midi has a “note” node. A single node to turn a note on and off.
  • I built a “note-button” out of that. Starts the note on button-push, stops the note on button-release. NB.: The xod/common-hardware/button has a 20msec latency. Open the note-button (double click it in the library list) to see how it was made.
  • The library is “x” for experimental. And, I don’t know how to “publish” yet.
  • I think it works, I can see it generating some data on the serial port. Please test carefully, I may have the values completely wrong.
  • Toggling the (xod) Debugger on may cause a conflict with MIDI. On several arduinos (e.g. UNO), MIDI will default to “Serial”, which is the same that the Debugger uses. The Leonardo, Due use Serial1 for MIDI. I haven’t looked at the shield yet to see how to use it.
  • The project in the xodball has several examples of use, and some comments.

INSTALL

  • install the awg libraries (from above)
  • import the xodball (from above), if you want to look at the examples. Not required.

Installing FortySevenEffects/arduino_midi_library for XOD is not pretty at the moment. You have to be able to create a link (shortcut) in the XOD install location.

First, we’ll get the midi library

  • Run the Arduino-IDE
  • In the Sketch menu, choose “Manage Libraries”
  • Search for “MIDI Library by Forty Seven Effects” and install it

Now we’ll do a link/shortcut:

  • In linux: sudo ln -s ~/Arduino/libraries/MIDI_Library /opt/XOD IDE/resources/arduino-libraries
  • In windows
    • Find the MIDI library folder, I think it’s in Documents/Arduino/libraries. There should be a MIDI_Library in there now.
    • Find the XOD install location. I have no idea where that is. Use the file-explorer to find XOD IDE/resources/arduino-libraries (note the space). There should be a README.md file, Servo directory, and a few others.
    • Create a shortcut from Arduino/libraries/MIDI_Library and put it in XOD IDE/resources/arduino-libraries
  • If XOD is already running, do “reload”.

That should do it. If you get it wrong, “deploy” will generate an error about not being able to find MIDI.h.

I’ll go over your other comments/notes/messages (eventually!).

Hello awgrover! I can not find awg/x-midi an get this error message:

We couldn’t find any code matching ‘x-midi’ in xodio/xod
You could try an advanced search.

That would be because I forgot to “push” the changes up to github. So, now I’ve updated my library.

What does the Trigger Button do? Is button #1 (true/false values) just a selector, and then “do it” on button 2? “Drawing” this in XOD is helpful: comment all the parts, use my new control-change node (or a dumy one) so I can see how things hook up.

Make a project in XOD showing this, so I can see where each input goes. Use my new Control Change node (or make your own as a dumy patch)

Depending on the XOD program, you may have to make an extra effort to send the initial values (to correspond to any fader, pot, button). I haven’t written any of the pot-as-controller for the nodes yet… (you suggested CC with pot, for example).

Updates to awgrover/x-midi (now version 1.2.0!)

  • Published as a Library: awgrover/x-midi. Also, still using github, but the node-names have changed (“awg” to “awgrover”). Use “Add Library”. (manual ugly install of FortySevenEffects/arduino_midi_library still required).
  • new Program-Change
  • new Control-Change
  • new Bank-Program-Change (bank-select + program-change)
  • new example patches in the library. You can deploy them(!), examine, copy.
  • I suspect the code isn’t quite right: “soft-thru” is probably broken.

Do these nodes work at all?

1 Like

Thanks for the new nodes! I have installed the FortySevenEffects library and will make a some tests in the next days. First I have to prepare some hardware for this, so please be patient… :mantelpiece_clock:

If I have some problems I will contact you. At this time it seem if the library is working well. I did a test upload and there was no error message.