Skip to contents
library(mydough)
install_mido()
#> python:         C:/Users/znmeb/AppData/Local/r-miniconda/envs/mydough/python.exe
#> libpython:      C:/Users/znmeb/AppData/Local/r-miniconda/envs/mydough/python311.dll
#> pythonhome:     C:/Users/znmeb/AppData/Local/r-miniconda/envs/mydough
#> version:        3.11.3 | packaged by conda-forge | (main, Apr  6 2023, 08:50:54) [MSC v.1934 64 bit (AMD64)]
#> Architecture:   64bit
#> numpy:          C:/Users/znmeb/AppData/Local/r-miniconda/envs/mydough/Lib/site-packages/numpy
#> numpy_version:  1.24.2
#> 
#> NOTE: Python version was forced by use_python function
library(reticulate)
use_condaenv("mydough")

Why a score table?

The ultimate output document from a composer, whether a fully-automated process or a human using automated processes, is a score of some kind. If the composition is intended for human performers, the score would usually be some mix of conventional music notation and specialized composition-dependent notations. But for compositions intended to be rendeded by a computer or a collection of electronic instruments, the most “standard” way of defining a composition is a MIDI file. (Back 1999)

The score table (symbolically, a score-table) provides a format convenient for both humans and automated processes, which mydough can then automatically compile into a MIDI file.

Format of a score_table

First of all, a score_table is a data.table::data.table (Dowle and Srinivasan 2023). data.tables provide rapid in-place data manipulation that the compilation process requires.

Second, a composer usually thinks of events and time in musical terms - beats, bars, repeated sequences / arpeggios / loops, chords and so on. A MIDI file has a very precise way of dealing with time that is not particularly musician-friendly. See (Mido Project 2023), sections 3.10.7 and 3.10.8 for the details.

Columns of a score_table

  • track_number: integer. A MIDI file can have a number of tracks.

  • event_type: character. What kind of event is this? (It’s usually a “note”.)

  • event_start_time: real, unit is beats

  • event_duration: real, unit is beats. mydough will compute the end time

  • midi_channel: integer. On the synthesizer end, this is the channel that the synth pays attention to. Channel numbers range from 1 to 16.

    Some synthesiers can be set to “omni” mode, where they listen to all channels, or MIDI Polyphonic Expression (MPE) mode, where they use multiple channels internally to perform different notes. This will be important when we come to pitch bends.

  • tempo: real, beats per minute. This can be changed on a “tempo” event only. The value is ignored on “note” events.

  • note_number: integer. For a note event, this is the MIDI note number, a value between 0 and 127. To orient yourself, middle C is note number 60 and A 440 Hz is note number 69.

  • pitch_bend: real, unit is cents. This is how much up or down the note should be bent from its standard value. Details:

    1. This value is only used for note events.

    2. For note events, speicfy a value of NA whenever there is no pitch bend.

    3. Synthesizers often have a setting for the range of a pitch bend. mydough assumes it is between -200 and +200 cents.

    4. Pitch bends apply to all the notes on the channel! So if you have more than one note sounding at a time, for example, in a chord, they either have to be sent to different synthesizers listening on different channels, or to one synthesizer listening in “omni” mode.

  • velocity: integer. How hard to play the note (0 - 127).

References

Back, David. 1999. Standard MIDI File Format, Updated — Music.mcgill.ca.” https://www.music.mcgill.ca/~ich/classes/mumt306/StandardMIDIfileformat.html.
Dowle, Matt, and Arun Srinivasan. 2023. Data.table: Extension of ‘Data.frame‘. https://CRAN.R-project.org/package=data.table.
Mido Project. 2023. Mido - MIDI Objects for Python; Mido 1.2.10 Documentation — Mido.readthedocs.io.” https://mido.readthedocs.io/en/latest/index.html.