,

Turning Time Series Data into Music

Blake Bradford Avatar

·

MIDITime: Turning Time Series Data into Music

Do you have time series data that you want to transform into musical compositions? Look no further than MIDITime! This powerful Python library allows you to convert any kind of time series data into pitch, velocity, and duration values based on your musical preferences, and outputs a .mid file.

MIDI files are not technically audio files – they are instructions on how software instruments should be played. You can play .mid files directly in some music applications or import them into popular music editors like ProTools, Ableton, or MaxMSP to add various effects and produce professional-grade music.

Installation

To get started with MIDITime, simply use pip to install the library:

#python
pip install miditime

Basic Usage

Let’s begin with a very basic example. First, instantiate the MIDITime class with a tempo (default is 120bpm) and the desired output file destination. Then, create a list of notes, where each note is represented as [time, pitch, velocity, duration]. Finally, add the track with those notes and save the .mid file.

#python
from miditime.miditime import MIDITime

mymidi = MIDITime(120, 'myfile.mid')

midinotes = [
    [0, 60, 127, 3],  # Start: 0 beats, Middle C (pitch 60), velocity 127, duration 3 beats
    [10, 61, 127, 4]  # Start: 10 beats (12 seconds from start), C#5 (pitch 61), velocity 127, duration 4 beats
]

mymidi.add_track(midinotes)
mymidi.save_midi()

Advanced Control

For more advanced control over your musical composition, you can instantiate the MIDITime class with additional parameters. These include the number of seconds you want to represent a year in the final song, the base octave, and the number of octaves you want your output to range over.

#python
from miditime.miditime import MIDITime

mymidi = MIDITime(120, 'myfile.mid', 5, 5, 1)

To incorporate your own time series data, follow these steps. Assuming your data is already in date order, convert the date/time data into an integer representing the number of days since the epoch (January 1, 1970). Then, scale the data down to a reasonable range for a song. Finally, build your note list based on the scaled data.

#python
my_data = [
    {'event_date': , 'magnitude': 3.4},
    {'event_date': , 'magnitude': 3.2},
    {'event_date': , 'magnitude': 3.6},
    {'event_date': , 'magnitude': 3.0},
    {'event_date': , 'magnitude': 5.6},
    {'event_date': , 'magnitude': 4.0}
]

my_data_epoched = [{'days_since_epoch': mymidi.days_since_epoch(d['event_date']), 'magnitude': d['magnitude']} for d in my_data]

my_data_timed = [{'beat': mymidi.beat(d['days_since_epoch']), 'magnitude': d['magnitude']} for d in my_data_epoched]

start_time = my_data_timed[0]['beat']

note_list = []

for d in my_data_timed:
    note_list.append([
        d['beat'] - start_time,
        mag_to_pitch_tuned(d['magnitude']),
        100,  # velocity
        1  # duration, in beats
    ])

mymidi.add_track(note_list)
mymidi.save_midi()

Play Your Music

To play your music, you can use various MIDI software. One simple command-line tool is timidity. Install it with apt and use the following command:

#
timidity mymidifilename.mid

License and Credits

MIDITime is released under the MIT license. If you use this library to create something awesome, it would be appreciated if you credited Reveal and Michael Corey. Special thanks to Julia Smith for her assistance in understanding musical keys and modes better.

MIDITime is a wrapper around the MIDI-making library called midiutil by Mark Conway Wirt. The midiutil package has been included in MIDITime per Mark Conway Wirt’s recommendation.


Thank you for reading! I hope this article has inspired you to explore the creative possibilities of turning time series data into music using MIDITime. If you have any questions or ideas, feel free to leave a comment or reach out to me directly.

Happy coding and composing!

References:
MIDITime Repository
MIDITime README

Leave a Reply

Your email address will not be published. Required fields are marked *