A new MIDI library

Well, actually, there are 3 libraries.
The main one is e/midi, which defines all the necessary types, abstractions (and also some helpers for common use cases).
And there are also e/serial-midi and e/usb-midi, which implement actual MIDI I/O communications over Serial and USB.

Here is how to use them.

Creating MIDI messages

e/midi defines a message type to represent MIDI messages so we won’t have to throw around status and data bytes as separate values.

You can create a message by specifying a type, channel and data bytes using a e/midi/message node. There are also helper nodes for common message types like note-on, note-off, control-change, program-change, mod-wheel and pitch-bend. And, of course, you can create other ones yourself!

Screen Shot 2019-12-10 at 16.57.20

Sending and receiving messages

e/midi only defines generic send and receive nodes:
Screen Shot 2019-12-10 at 18.16.00

There are a few other alternative transport methods besides the good old 5-pin DIN, and I want to make message processing logic be as decoupled from them as possible.

For now, two are supported: e/serial-midi for communication on the serial ports and e/usb-midi for communication over USB. The next one should probably be a wrapper around something like Arduino-AppleMIDI-Library (and I would love if someone would help with that :wink:).

Let’s say you want to make a simple controller that will act a a mod wheel:
Screen Shot 2019-12-10 at 18.37.30
If you have a board with native USB support (like Arduino Leonardo) and want to make a USB controller, place a e/usb-midi/usb-midi node and connect it to send's MIDI input. And it you want to switch it for an old-school 5-pin DIN connection over serial, just replace usb-midi with one of serial-midi nodes from e/serial-midi. Generic nodes are awesome!

Unpacking and processing messages

To extract status and data bytes from message, use e/midi/unpack-message:
Screen Shot 2019-12-10 at 17.41.16

e/midi has a filter-by-channel node that only lets through messages with a specified channel (and is an example on how to deal with messages in C++)

e/midi also includes some helper nodes that extract data from specific messages and ignore the rest (on-control-change, on-pitch-bend etc).

Here is how to control a servo with ModWheel CC messages sent over the 1st channel:

.

As with message-creating nodes, the included message-processing helpers are absolutely not meant to cover all the possible use cases. But as long you use e/midi/message type, all additional helper libraries will be compatible with each other (and with future additional/alternative transport implementations)!

3 Likes

I would especially love some input on this from authors of other MIDI-libraries (@awgrover, @dox, @copsmusic and others).

1 Like

please be patient. i will have a look at this library soon. unfortunately i am very busy at the moment…

1 Like

@ evgenykochetkov

I made a test sketch and got these error message on a completely new installed WIN 10 PC:

grafik

Begin compiling code for the board Arduino/Genuino Uno :package:

Downloading and installing missing tool: builtin:ctags@5.8-arduino11

Downloading builtin:ctags@5.8-arduino11…

0 / 116455 0.00%

builtin:ctags@5.8-arduino11 0 B / 113.73 KiB 0.00%

builtin:ctags@5.8-arduino11 46.82 KiB / 113.73 KiB 41.17%

builtin:ctags@5.8-arduino11 downloaded
Installing builtin:ctags@5.8-arduino11…

builtin:ctags@5.8-arduino11 installed

Using board ‘uno’ from platform in folder: C:\Users\DELL PC\xod_packages_\packages\arduino\hardware\avr\1.8.1
Using core ‘arduino’ from platform in folder: C:\Users\DELL PC\xod_packages_\packages\arduino\hardware\avr\1.8.1

Detecting libraries used…

“C:\Users\DELL PC\xod\packages\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino5/bin/avr-g++” -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10607 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR “-IC:\Users\DELL PC\xod\packages\packages\arduino\hardware\avr\1.8.1\cores\arduino” “-IC:\Users\DELL PC\xod\packages\packages\arduino\hardware\avr\1.8.1\variants\standard” “C:\Users\DELLPC~1\AppData\Local\Temp\arduino-sketch-6D0982BD0921F828CC2D099648796DAC\sketch\xod_1583958146328_sketch.ino.cpp” -o nul

Alternatives for MIDIUSB.h: [MIDIUSB@1.0.4]

ResolveLibrary(MIDIUSB.h)

-> candidates: [MIDIUSB@1.0.4]

“C:\Users\DELL PC\xod\packages\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino5/bin/avr-g++” -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10607 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR “-IC:\Users\DELL PC\xod\packages\packages\arduino\hardware\avr\1.8.1\cores\arduino” “-IC:\Users\DELL PC\xod\packages\packages\arduino\hardware\avr\1.8.1\variants\standard” “-IC:\Users\DELLPC~1\AppData\Local\Temp\xod_temp_sketchbookChnjt8\libraries\MIDIUSB\src” “C:\Users\DELLPC~1\AppData\Local\Temp\arduino-sketch-6D0982BD0921F828CC2D099648796DAC\sketch\xod_1583958146328_sketch.ino.cpp” -o nul

Error while detecting libraries included by C:\Users\DELLPC~1\AppData\Local\Temp\arduino-sketch-6D0982BD0921F828CC2D099648796DAC\sketch\xod_1583958146328_sketch.ino.cpp

“C:\Users\DELL PC\xod\packages\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino5/bin/avr-g++” -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10607 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR “-IC:\Users\DELL PC\xod\packages\packages\arduino\hardware\avr\1.8.1\cores\arduino” “-IC:\Users\DELL PC\xod\packages\packages\arduino\hardware\avr\1.8.1\variants\standard” “-IC:\Users\DELLPC~1\AppData\Local\Temp\xod_temp_sketchbookChnjt8\libraries\MIDIUSB\src” “C:\Users\DELLPC~1\AppData\Local\Temp\xod_temp_sketchbookChnjt8\libraries\MIDIUSB\src\MIDIUSB.cpp” -o nul

Error while detecting libraries included by C:\Users\DELLPC~1\AppData\Local\Temp\xod_temp_sketchbookChnjt8\libraries\MIDIUSB\src\MIDIUSB.cpp

Generating function prototypes…

“C:\Users\DELL PC\xod\packages\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino5/bin/avr-g++” -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10607 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR “-IC:\Users\DELL PC\xod\packages\packages\arduino\hardware\avr\1.8.1\cores\arduino” “-IC:\Users\DELL PC\xod\packages\packages\arduino\hardware\avr\1.8.1\variants\standard” “-IC:\Users\DELLPC~1\AppData\Local\Temp\xod_temp_sketchbookChnjt8\libraries\MIDIUSB\src” “C:\Users\DELLPC~1\AppData\Local\Temp\arduino-sketch-6D0982BD0921F828CC2D099648796DAC\sketch\xod_1583958146328_sketch.ino.cpp” -o “C:\Users\DELLPC~1\AppData\Local\Temp\arduino-sketch-6D0982BD0921F828CC2D099648796DAC\preproc\ctags_target_for_gcc_minus_e.cpp”

In file included from C:\Users\DELLPC~1\AppData\Local\Temp\xod_temp_sketchbookChnjt8\xod_1583958146328_sketch\xod_1583958146328_sketch.ino:979:0:
C:\Users\DELLPC~1\AppData\Local\Temp\xod_temp_sketchbookChnjt8\libraries\MIDIUSB\src/MIDIUSB.h:18:2: error: #error MIDIUSB can only be used with an USB MCU.
#error MIDIUSB can only be used with an USB MCU.
^~~~~

Multiple libraries were found for “MIDIUSB.h”

Used: C:\Users\DELLPC~1\AppData\Local\Temp\xod_temp_sketchbookChnjt8\libraries\MIDIUSB

Using library MIDIUSB at version 1.0.4 in folder: C:\Users\DELLPC~1\AppData\Local\Temp\xod_temp_sketchbookChnjt8\libraries\MIDIUSB

Error: exit status 1
Compilation failed.
Compilation failed
Command Process exited with code 1
The generated C++ code contains errors. It can be due to a bad node implementation or if your board is not compatible with XOD runtime code. The original compiler error message is above. Fix C++ errors to continue. If you believe it is a bug, report the problem to XOD developers.

hi, user DELL PC … do you have a space? that gives error. Should be DELLPC or DELL_PC

User DELL PC becomes DELLPC~1 , so it cannot find the necessary files.

Judging from error, that probably isn’t the issue.

error MIDIUSB can only be used with an USB MCU.

Would seen to indicate the USB midi node is not compatible with this Arduino model.

yeah … I thought about it but I didn’t realize that that was there :+1:

Yes, you are right.
I have to use [send(uart)] whe I want to receive the program change messages over USB with my UNO.
That’s confusing…

When do I use [send(usb-midi)]?

usb-midi is for controllers with native USB capabilities (atmega32u4 based boards or ARM boards). It will not work with UNO.

Hi
Some months ago i build a MIDI processor using an Arduino Uno, an joystick shield with 4 buttons and 2 extra switches, and an 20 * 4 i2c lcd module. The objective was to expand the MIDI capabilities of a Yamaha SY77 Synthesizer which are very limited.
I did it first with the copsmusic MIDI library, and managed to add new functions like octave and semitone transpose, remap and rechannelize controller functions and transmit some basic SY77 Sys-ex messages (developing additional patches).
I managed to translate the same project using your e/midi library (except for the Sys-ex part), and noticed a slight but noticeable improvement in the closed loop (from SY77 out to processor in and from processor out back to SY77 in, local off) response.
Would it be difficult to add some Sys-ex patches to the library? I am relatively new on using Generic nodes and abstract patch nodes, thanks!

1 Like