Live Recording of a Midi Controller via Mido Inport
motivation
I got the idea to import live data of a midi controller through this blog post:
Here it is!
— Colin Fay 🤘 (@_ColinFay) September 17, 2020
Listen to MIDI events from #RStats https://t.co/L7pyxZ8iTE pic.twitter.com/f5xQTuAj5E
mido controller input via mido
To run this on your machine, you need to install the R package reticulate and the python package mido.
import mido
mido <- reticulate::import("mido")
connect to inport
You need to connect your midi controller to the computer. In case you don’t have one and want to try this out you can also run a virtual midi controller, for example VMPK. In this example I connected a Nektar Impact LX 61.
# In order to obtain all the inports available, just type
# mido$get_input_names()
# in your console
inport <- mido$open_input("Impact LX61+:Impact LX61+ MIDI 1 20:0")
live record midi controller
Now we are all set up to record the midi messages coming in via the input port.
We just create empty vectors and append the midi messages and the times when they arrive in an endless loop until we send a keyboard interrupt:
msgs <- c()
times <- c()
while (TRUE) {
t <- Sys.time()
msg <- inport$poll()
# only record the midi message when it's not empty:
if (!is.null(msg)) {
msgs <<- append(msgs, as.character(msg))
times <<- append(times, t)
}
}
Instead of the poll()
method mido also provides
a receive()
method which should be more appropriate for this action. However, I wasn’t able to get this working without making my PC stuck and having to restart RStudio.
print out the recorded data
After interrupting the loop above the data is in an R vector msgs. Here I show a small example of the resulting data when a C note is played twice and the pitch wheel is turned a bit:
# Set time precision value for printing to milliseconds:
op <- options(digits.secs = 3)
# Print out the recorded data:
data.frame(times, msgs)
#> times msgs
#> 1 2020-10-24 14:04:31.611 note_on channel=15 note=60 velocity=81 time=0
#> 2 2020-10-24 14:04:31.742 note_off channel=15 note=60 velocity=0 time=0
#> 3 2020-10-24 14:04:31.981 note_on channel=15 note=60 velocity=78 time=0
#> 4 2020-10-24 14:04:32.117 note_off channel=15 note=60 velocity=0 time=0
#> 5 2020-10-24 14:04:33.927 pitchwheel channel=15 pitch=128 time=0
#> 6 2020-10-24 14:04:33.938 pitchwheel channel=15 pitch=384 time=0
#> 7 2020-10-24 14:04:33.960 pitchwheel channel=15 pitch=512 time=0
#> 8 2020-10-24 14:04:33.992 pitchwheel channel=15 pitch=128 time=0
#> 9 2020-10-24 14:04:34.003 pitchwheel channel=15 pitch=0 time=0