In [1]:
midifile = 'data/chopin-fantaisie.mid'

In [2]:
import time
import copy
import subprocess
from abc import abstractmethod

import numpy as np
import midi # Midi file parser

from midipattern import MidiPattern
from distorter import *
from align import align_frame_to_frame, read_align, write_align


device 0 ('ALSA', 'Midi Through Port-0', 0, 1, 0)
device 1 ('ALSA', 'Midi Through Port-0', 1, 0, 0)
device 2 ('ALSA', 'TiMidity port 0', 0, 1, 0)
device 3 ('ALSA', 'TiMidity port 1', 0, 1, 0)
device 4 ('ALSA', 'TiMidity port 2', 0, 1, 0)
device 5 ('ALSA', 'TiMidity port 3', 0, 1, 0)

In [3]:
MidiPattern.MIDI_DEVICE = 2

Init Pygame and Audio

Midi Pattern


In [4]:
pattern = MidiPattern(midi.read_midifile(midifile))
simple = pattern.simplified(bpm=160)
simple.stamp_time('t0')
midi.write_midifile("generated/simple.mid", simple)

In [5]:
print simple.attributes[0][-40:]


[{'t0': 203.24999999999994}, {'t0': 203.25468749999993}, {'t0': 203.34843749999993}, {'t0': 203.34843749999993}, {'t0': 203.43749999999994}, {'t0': 203.44218749999993}, {'t0': 203.53124999999994}, {'t0': 203.53124999999994}, {'t0': 203.62499999999994}, {'t0': 203.62499999999994}, {'t0': 203.71874999999994}, {'t0': 203.71874999999994}, {'t0': 203.81249999999994}, {'t0': 203.81249999999994}, {'t0': 203.90624999999994}, {'t0': 203.90624999999994}, {'t0': 203.99999999999994}, {'t0': 203.99999999999994}, {'t0': 203.99999999999994}, {'t0': 203.99999999999994}, {'t0': 204.04687499999994}, {'t0': 204.09374999999994}, {'t0': 204.14062499999994}, {'t0': 204.18749999999994}, {'t0': 204.28124999999994}, {'t0': 205.49999999999994}, {'t0': 205.49999999999994}, {'t0': 205.49999999999994}, {'t0': 205.49999999999994}, {'t0': 205.49999999999994}, {'t0': 205.49999999999994}, {'t0': 205.54687499999994}, {'t0': 205.59374999999994}, {'t0': 205.64062499999994}, {'t0': 206.99999999999994}, {'t0': 206.99999999999994}, {'t0': 206.99999999999994}, {'t0': 206.99999999999994}, {'t0': 206.99999999999994}, {'t0': 209.52109374999995}]

In [6]:
pattern[0]
pattern.play(180)


Was playing note 40 time 4.44444444444

In [7]:
simple.play()


Was playing note 5 time 3.0

Distorter


In [8]:
distorter = VelocityNoiseDistorter(sigma=20.)
distorter.randomize()
print distorter
dist_pattern = distorter.distort(simple)
midi.write_midifile('generated/velocity-noise.mid', dist_pattern)
dist_pattern.play(bpm=180)


VelocityNoiseDistorter(sigma=7.63)
Was playing note 5 time 2.66666666667

In [9]:
print dist_pattern.attributes[0][-4:]


[{'t': 206.99999999999994, 't0': 206.99999999999994}, {'t': 206.99999999999994, 't0': 206.99999999999994}, {'t': 206.99999999999994, 't0': 206.99999999999994}, {'t': 209.52109374999995, 't0': 209.52109374999995}]

In [10]:
distorter = VelocityWalkDistorter(sigma=0.1)
distorter.randomize()
print distorter
dist_pattern = distorter.distort(simple)
midi.write_midifile('generated/velocity-walk.mid', dist_pattern)
dist_pattern.play(bpm=180)


VelocityWalkDistorter(sigma=19.24, min=1.18, max=1.23)
Was playing note 5 time 2.66666666667

In [11]:
distorter = ProgramDistorter()
distorter.randomize()
# for some reason GM 1- 3 makes no sound in pygame?
print distorter
dist_pattern = distorter.distort(simple)
midi.write_midifile('generated/program.mid', dist_pattern)
dist_pattern.play(bpm=180)


ProgramDistorter(ticks=0.00)
Was playing note 19 time 2.66666666667

In [12]:
distorter = TempoDistorter(sigma=0, min=0.5, max=2.)
distorter.randomize()
print distorter
dist_pattern = distorter.distort(simple)
print 'time warp', dist_pattern.attributes[0][-4:]
midi.write_midifile('generated/tempo.mid', dist_pattern)
dist_pattern.play(bpm=180)


TempoDistorter(sigma=0.83, min=0.99, max=1.21)
time warp [{'t': 200.28854166666386, 't0': 206.99999999999994}, {'t': 200.28932291666385, 't0': 206.99999999999994}, {'t': 200.29010416666384, 't0': 206.99999999999994}, {'t': 200.38932291666384, 't0': 209.52109374999995}]
Was playing note 14 time 0.360416666667

In [13]:
distorter = TimeNoiseDistorter()
distorter.randomize()
print distorter
dist_pattern = distorter.distort(simple)
print 'time warp', dist_pattern.attributes[0][-4:]
midi.write_midifile('generated/time.mid', dist_pattern)
dist_pattern.play(bpm=180)


TimeNoiseDistorter(sigma=0.08)
time warp [{'t': 206.99999999999977, 't0': 206.99999999999994}, {'t': 206.99999999999977, 't0': 206.99999999999994}, {'t': 206.99999999999977, 't0': 206.99999999999994}, {'t': 209.52109374999978, 't0': 209.52109374999995}]
Was playing note 5 time 2.62916666667

Individual Note Times to Global Alignment


In [14]:
stride = 1.
align = align_frame_to_frame(dist_pattern, stride)
align


Out[14]:
[0,
 1,
 3,
 3,
 4,
 5,
 6,
 7,
 8,
 9,
 10,
 11,
 12,
 13,
 14,
 15,
 16,
 17,
 18,
 19,
 20,
 21,
 22,
 23,
 24,
 25,
 26,
 27,
 28,
 29,
 30,
 31,
 32,
 33,
 34,
 35,
 36,
 37,
 38,
 39,
 40,
 41,
 42,
 43,
 44,
 45,
 46,
 47,
 48,
 49,
 50,
 51,
 52,
 53,
 54,
 55,
 56,
 57,
 58,
 59,
 60,
 61,
 62,
 63,
 64,
 65,
 66,
 67,
 68,
 69,
 70,
 71,
 72,
 73,
 74,
 75,
 76,
 77,
 78,
 79,
 80,
 81,
 82,
 83,
 84,
 85,
 86,
 87,
 88,
 89,
 90,
 91,
 92,
 93,
 94,
 95,
 96,
 97,
 98,
 99,
 100,
 101,
 102,
 103,
 104,
 105,
 106,
 107,
 108,
 109,
 110,
 111,
 112,
 113,
 114,
 115,
 116,
 117,
 118,
 119,
 120,
 121,
 122,
 123,
 124,
 125,
 126,
 127,
 128,
 129,
 130,
 131,
 132,
 133,
 134,
 135,
 136,
 137,
 138,
 139,
 140,
 141,
 142,
 143,
 144,
 145,
 146,
 147,
 148,
 149,
 150,
 151,
 152,
 153,
 154,
 155,
 156,
 157,
 158,
 159,
 160,
 161,
 162,
 163,
 164,
 165,
 166,
 167,
 168,
 169,
 170,
 171,
 172,
 173,
 174,
 175,
 176,
 177,
 178,
 179,
 180,
 181,
 182,
 183,
 184,
 185,
 186,
 187,
 188,
 189,
 190,
 191,
 192,
 193,
 194,
 195,
 196,
 197,
 198,
 199,
 200,
 201,
 202,
 203,
 204,
 205,
 206,
 207,
 208,
 209]

In [15]:
write_align('generated/align.txt', align, stride)
align2, stride2 = read_align('generated/align.txt')
print align2 == align
print int(stride2) == int(stride), stride2, stride


True
True 1.0 1.0

Actual Generation


In [20]:
dist_pattern = random_distort(simple)
align = align_frame_to_frame(dist_pattern, stride=1.)
print align
dist_pattern.play()


[2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 57, 58, 59, 61, 62, 63, 64, 65, 67, 68, 69, 70, 71, 73, 74, 75, 76, 77, 79, 80, 81, 82, 83, 84, 86, 87, 88, 89, 90, 91, 92, 94, 95, 96, 97, 98, 100, 101, 102, 103, 104, 106, 107, 108, 109, 110, 111, 112, 114, 115, 116, 117, 118, 119, 120, 122, 123, 124, 125, 126, 127, 128, 129, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 207]
Was playing note 77 time 3.18072916667

In [21]:
num_samples = 10
stride = 0.1
for i in xrange(num_samples):
    base_name = 'generated/sample-{}'.format(i)
    align_name = '{}.txt'.format(base_name)
    midi_name = '{}.mid'.format(base_name)
    wav_name = '{}.wav'.format(base_name)
    distorted = random_distort(simple)
    align = align_frame_to_frame(distorted, stride)
    write_align(align_name, align, stride)
    midi.write_midifile(midi_name, distorted)
    # Convert to wav using timidity
    print wav_name
    subprocess.check_call(['timidity', '-Ow', midi_name, '-o', wav_name])
    print 'Done generating {}'.format(base_name)


generated/sample-0.wav
Done generating generated/sample-0
generated/sample-1.wav
Done generating generated/sample-1
generated/sample-2.wav
Done generating generated/sample-2
generated/sample-3.wav
Done generating generated/sample-3
generated/sample-4.wav
Done generating generated/sample-4
generated/sample-5.wav
Done generating generated/sample-5
generated/sample-6.wav
Done generating generated/sample-6
generated/sample-7.wav
Done generating generated/sample-7
generated/sample-8.wav
Done generating generated/sample-8
generated/sample-9.wav
Done generating generated/sample-9