Rather than mere data-driven rhythms, this is data-driven music in python.
More precisely, ddpy serializes tables in python to midi files and
deserializes midi files to tables. It provides a to_midi
function
and a from_midi
function.
We plan on adding to_midi
and from_midi
as pandas.DataFrame
methods eventually.
In the present documentation, we use "table" in a rather generic way.
It refers to a collection of things (rows), with the same attributes
(columns) measured about each thing. ddpy
recognizes two data
structures for representating a table.
- A list of dicts
- Pandas DataFrame
Each column in the table gets represented as an instrument, and each row in the table gets represented as a beat.
The following data types can be stored in a column
- Strings (
unicode
orstr
) - Factors (
pandas.Factor
) - Booleans (
bool
) - Integers (
int
,numpy.int64
, &c.) - Floats (
float
,numpy.float64
, &c.)
The following sections explain how columns are structured by data type.
Strings (unicode
or str
) are represented as lyrics.
Factors (pandas.Factor
) are represented as drum tracks, with a mapping
between drum notes and factor levels.
Floats are represented as continuous notes merging into each other through pitch bends.
Integers are represented as discrete notes. The pitches are determined by the same means as for floats.
A MIDI track can contain 16 different channels, and each channel can represent
128 different notes, numbered 0 to 127. Thus, a single track can represent
Most of these tweaks to output are set by a keyword argument. These keyword arguments can take two structures, which we'll call the table form or the column form.
The table form is just a value, and it applies to the full song. For example,
to set the volume for the full song, you can run to_midi(table, volume = 0.7)
.
This is the table form.
The column form allows us to specify different values for each column. This form is a dictionary whose keys are column names and values are parameters for the different columns. You do not need to specify a key-value pair for each column; a default value will be used for any that you don't specify.
By default, all instruments play at full volume. There are two ways of specifying volume: by instrument and by note.
To specify volume by instrument, pass a dictionary where the keys are column names and the values are instrument volumes, represented as numbers between 0 and 1. Columns for which you don't specify a volume use full volume (1) by default.
table = [{'debt':9001,'cats':8},{'debt':3,'cats':23}]
to_midi(table, volume = {'debt': 0.8})
The example above shows how to specify volume by instrument when creating
the file with to_midi
.
To specify a volume for each note, you should structure your table such
that cells contain (data,volume)
tuples rather than simple data
values. For example, the following code would do the exact same thing as
the previous code.
table = [{'debt':(9001,0.8),'cats':8},{'debt':(3,0.8),'cats':23}]
to_midi(table)
If you use both methods to specify volume, the volume for a given note will be the product of the two volumes.
Tuple
By default, no volume tuples
When you reading a file with from_midi
, the
instrument-level volumes are not returned;
they're just read as tuples.
By default, a key of C Major is used
You can change this...
from_midi
won't give you the key back
Rounding your data to the key signature destroys information in order to make the music sound better. Rounding is turned off by default, but you can turn it on
Each MIDI track has 16 channels, each of which can take 128 values. We represent floats and integers in base 128.
Integers: We use odd tracks for positive numbers and even tracks for negative numbers. For positive numbers, he first track corresponds to the first place, the third track to the second place, and so on. For negative numbers, the second track corresponds to the first place, the fourth to the second, and so on.
Floats: We use the first X tracks for the mantissa, the next Y tracks for the exponent, and the final track for the sign. The sign is represented as 0 or 1, with 0 being negative. Each of these components of the float is an integer like above but with fewer than 16 tracks.
This scheme is chosen so that cells containing the exact values 0, 1, 2, ... 127 will be mapped to the identical number on the first channel in MIDI.
timidity -Ow output.mid
https://wiki.archlinux.org/index.php/timidity#TiMidity.2B.2B_does_not_play_MIDI_files
I'm not liking MIDIUtil; I don't see how to add MIDI events other than notes. I might switch to http://web.mit.edu/music21/
import pandas, ddpy
df = pandas.read_csv('/home/tlevine/Documents/comparing-wifi-usage/data/chicago.csv')
ddpy.to_midi(df[['NUMBER OF SESSIONS']] / 600, 'chicago.mid')