pyramidi is a very experimental package to generate / manipulate midi
data from R. Be aware that a lot of the code I’ve written some years ago
hurts my eyes when I look at it now :) Midi data is read into
dataframes, using the python package
miditapyr under the hood (which
itself uses the excellent mido). The
notes’ midi information (one line per note_on/note_off midi event)
is translated into a wide format (one line per note). This format
facilitates some manipulations of the notes’ data and also plotting them
in piano roll plots. Finally, the modified dataframes can be written
back to midi files (again using miditapyr).
Thus, you can manipulate all the intermediate dataframes and create midi
files from R. However, you need to make sure yourself that the midi
files you write can be understood by your softsynth. The data is not yet
validated by pyramidi, but mido (also used to write midi files) already
catches some of the possible inconsistencies.
played live in the R console OR generate a sound file and a html audio
player when knitting rmarkdown documents thanks to the excellent R
packages fluidsynth (see the
documentation of the
play()
method in the MidiFramer class and its helper function player()
which use
fluidsynth::midi_convert() to synthesize midi to wav files (needs
fluidsynth installed, but if I
understand correctly R will do that for you)
The python package miditapyr also
needs to be installed in your python environment used by
reticulate.
pip install miditapyr
But if everything works as I believe it should, miditapyr is
automatically installed if you install pyramidi, as soon as you access
the module for the first time.
Otherwise, you can also install it in your reticulate python environment
with the included helper function:
pyramidi::install_miditapyr()
I’m not sure if that works on windows too. Perhaps there you have to
manually configure your reticulate environment.
Usage
Generate a MidiFramer object
We can create a MidiFramer object by passing the file path to the
constructor method
(new()).
The object contains the midi data in various dataframe formats and an
interface to the miditapyr
miditapyr.MidiFrames
object mfr$mf. You can write the midi file resulting of the
MidiFramer object to disk:
mfr$mf$write_file("/path/to/your/midifile.mid")
Modifying midi data
In the MidiFramer object, we can modify mfr$df_notes_wide, the notes
in note-wise wide format (note_on & note_off events in the same
line). Thus we don’t need to worry which midi events belong together
Let’s look at a small example. We’ll define a function to replace every
note with a random midi note between 60 & 71::
When we call the update_notes_wide() method, the midi data in mfr is
updated:
mfr$update_notes_wide(mod)
Writing modified midi files
Thus, we can now save the modifications to a midi file:
mfr$mf$write_file("mod_test_midi_file.mid")
Synthesizing and playing audio
See the vignette("pyramidi", package = "pyramidi") to see how you can
synthesize the midi data to wav, convert to mp3 if you want, and then
embed a player in your rmarkdown html document with
The R packages av (on cran) and fluidsynth (not yet on cran but soon) allow for synthesizing and converting audio without requiring the user to install any extra shell utilities. Perhaps supporting that back-end can lower the barrier to use pyramidi.
I was an acoustic musician in a previous life, now a math nerd data scientist. This is the first time I've worked with midi data. Using music theory, I'm making sense of the note and b columns, however I think as I progress with this project, I suspect I'll end up reinventing the wheel without understanding all the columns output in the dataframes provided.
Could you please point me to documentation that will help me understand what the columns are in the various objects output by the midi transformations provided? Apologies if this is super obvious in the documentation and I failed to see it.
Thanks a lot for the development of this package! been having a lot of fun exploring it and so far everything works great. I was just curious to know if midi cc has been implemented? tried to import a midi file with midi cc values that I exported from Ableton to see if I could reverse engineered , but got an error.