Skip to content

Instantly share code, notes, and snippets.

@mattalhonte
Created May 7, 2015 02:11
Show Gist options
  • Save mattalhonte/b9d6fa0e40e4f203a547 to your computer and use it in GitHub Desktop.
Save mattalhonte/b9d6fa0e40e4f203a547 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"metadata": {
"name": ""
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We'll start with generating blobs of numbers and then interpreting them in interesting (?) ways.\n",
"\n",
"Sometimes we'll just export the raw data, for later import into other applications, like Max or Supercollider, Processing, a spreadsheet, etc. When you store data in a text file, maybe as a CSV (Comma Seperated Values) file, it makes it really easy to then use that data in other applications. Almost any programming or production environment can use a text file for input data.\n",
"\n",
"We'll also generate a bunch of MIDI files. This is not because we particularly want to work with MIDI files, but rather because it's a really quick way to hear what you've done. MIDI files are generic enough that you can play them back almost anywhere. You probaby won't make a finished piece by spitting out a MIDI file, but you can certainly start to assemble your materials that way. And of course any music application will be happy to open your MIDI file, allowing you to turn it into something not so dumb. \n",
"\n",
"Here's a list of MIDI General Instruments. PrettyMidi starts counting at zero, so subtract one from each instrument number...\n",
"http://www.midi.org/techspecs/gm1sound.php\n",
"\n",
"We'll also generate some graphs, and even some scores! Whee!\n",
"\n",
"We won't get to working with synthesis or samples yet. That's in the next notebook.\n"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# basic imports\n",
"\n",
"# this one lets us call external command line programs\n",
"from subprocess import Popen\n",
"\n",
"# we'll need some random number generators\n",
"import random\n",
"\n",
"# numpy is numerical python, lots of useful routines\n",
"# the \"as np\" means we can refer to this as np rather than numpy\n",
"# why? it's just a convention you'll see in lots of demo code, so we'll follow it as well\n",
"# plus we save typing three letters!\n",
"import numpy as np\n",
"\n",
"# we wanna make plots like in Matlab!\n",
"# same idea, we can just type \"plt\" instead of the whole name\n",
"import matplotlib.pyplot as plt\n",
"\n",
"#here's a simple midi library written by Collin in Dan Ellis's lab\n",
"#https://github.com/craffel/pretty-midi\n",
"import pretty_midi\n",
"import midi\n",
"\n",
"# abjad is a lilypad scoring interface built by Victor Adan and friends\n",
"# http://abjad.mbrsi.org/\n",
"import abjad\n",
"\n",
"# this tells the notebook to show us graphics inline\n",
"# this is only meaningful in iPython Notebook\n",
"# iPython commands that start with % are called \"magics\"\n",
"# this won't do anything in regular python\n",
"%matplotlib inline\n"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stderr",
"text": [
"/Library/Python/2.7/site-packages/pretty_midi/pretty_midi.py:14: UserWarning: Module readline was already imported from /Library/Python/2.7/site-packages/readline.pyc, but /Library/Python/2.7/site-packages/readline-6.2.4.1-py2.7-macosx-10.7-intel.egg is being added to sys.path\n",
" import pkg_resources\n"
]
}
],
"prompt_number": 1
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This is how we're going to play back MIDI files. \n",
"\n",
"We'll create a method called, uh, play_midi_file() and we'll send it the name of a MIDI file we've just saved. It'll use a Python trick to send that filename to VLC via the command line. Here's how it would look if you typed it in the Terminal:\n",
"\n",
"<code>douglas$ /Applications/VLC.app/Contents/MacOS/VLC -I dummy myfile.midi vlc://quit</code>\n",
"\n",
"VLC is a nice application that can play almost anything. You have to have VLC installed and select a synth bank to play MIDI files. \n",
"\n",
"We'll also define a method called kill_midi(). Call that anytime you want VLC to stop playing the MIDI file you just sent it. Like if you generated 100,000 notes by mistake... It works by, again, using a Python trick to call a command line program. In this case it calles \"killall\", which kills whatever program you ask it to. We send it the name \"VLC\", and so it kills any copies of VLC it finds running. On the command line it would look like this:\n",
"\n",
"<code>douglas$ killall VLC</code>\n",
"\n",
"Finally we'll make an open_file(filename) method. This will be just like double-clicking on a file in a folder. We'll use it to look at text files. The OS will automatically open the text file in your default text file application.\n",
"\n",
"<code>douglas$ open bleep.txt</code>\n"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"\n",
"def play_midi_file(midi_filename):\n",
" p = Popen([\"/Applications/VLC.app/Contents/MacOS/VLC\", \"-I\", \"dummy\", midi_filename, \"vlc://quit\"])\n",
"\n",
"def kill_midi():\n",
" # MAKE IT STOP!!!\n",
" p = Popen([\"killall\", \"VLC\"])\n",
" \n",
"def open_file(filename):\n",
" p = Popen([\"open\", filename])"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 2
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Since we're dealing with notes, maybe we want to call them by letter names. I generally find it easier to work with numbers at this stage, but there might be a reason you want to see note names. So for convenience, let's make a list of pitch class names."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"#make a list of pitch class names\n",
"p_class_names = ['c', 'c#', 'd', 'd#', 'e', 'f', 'f#', 'g', 'g#', 'a', 'a#', 'b']\n",
"\n",
"print p_class_names[0]\n",
"print p_class_names[0], p_class_names[4], p_class_names[7]\n",
"print p_class_names[-1]\n",
"print p_class_names[0:4]\n",
"\n",
"for name in p_class_names:\n",
" print name,\n"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"c\n",
"c e g\n",
"b\n",
"['c', 'c#', 'd', 'd#']\n",
"c c# d d# e f f# g g# a a# b\n"
]
}
],
"prompt_number": 3
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The dumbest, simplest thing to do now is generate some random note values. NO ONE WANTS TO LISTEN TO RANDOM NOTES!!! But here we are."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"for note in range(10):\n",
" # pick a number from 0 to 11\n",
" note_num = random.randint(0,11)\n",
" print p_class_names[note_num],\n"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"f# c# a# b g f# e g e b\n"
]
}
],
"prompt_number": 4
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's add a randomly generated octave indication to our notes. And instead of just printing them, let's also save them in a text file."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# this time we need a list to store our notes in since we'll use them later\n",
"notes = []\n",
"\n",
"for note in range(10):\n",
" # pick a number from 0 to 11\n",
" note_num = random.randint(0,11)\n",
" oct_num = random.randint(0, 8)\n",
"\n",
" # combine note name and octave\n",
" # there are other ways to build a string. I like this one.\n",
" note_string = p_class_names[note_num] + str(oct_num)\n",
" notes.append(note_string)\n",
"\n",
"print notes\n",
"\n",
"# store our filename in a variable so that we can refer to it later\n",
"file_name = \"random_notes.txt\"\n",
"\n",
"# this will open our file for writing. we can refer to it as f.\n",
"with open(file_name, 'w') as f:\n",
" \n",
" f.write(\"zzz, here are some random notes:\\n\")\n",
" \n",
" for note in notes:\n",
" f.write(note)\n",
" f.write(\", \")\n",
" \n",
" # make our text file prettier by ending with a new line\n",
" f.write(\"\\n\")\n",
" \n",
" f.close()\n",
" \n",
"\n",
"open_file(file_name)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"['e3', 'e6', 'a7', 'a5', 'd7', 'g5', 'g#1', 'f#0', 'c0', 'c3']\n"
]
}
],
"prompt_number": 5
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Okay, if that was exciting then you're done. Otherwise, let's do something more interesting!\n",
"\n",
"Maybe we want a LOT of notes in one octave. We want them in a normal distribution, which means they make a bell shape when we plot them. We want to pick which note should be the left-most in our distribution. "
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"normal_values = np.random.randn(10)\n",
"print normal_values\n",
"print min(normal_values)\n",
"print max(normal_values)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"[ 0.69415412 0.39434932 0.56603263 1.34491834 0.6491153 1.5807638\n",
" 1.57948205 0.46322283 -0.38611648 0.19682072]\n",
"-0.386116475836\n",
"1.58076380331\n"
]
}
],
"prompt_number": 6
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# we'll define a method that we can call later\n",
"\n",
"def gen_norm_pitch_dist(start_pitch_num = 0, num_pitches = 1000):\n",
" \n",
" #generate values with a normal (bell-shaped) distribution)\n",
" normal_values = np.random.randn(num_pitches)\n",
"\n",
"\n",
" normal_values = np.interp(normal_values,[normal_values.min(), normal_values.max()],[0,12])\n",
"\n",
" # we round them so that we have integers rather than floats\n",
" normal_values = np.round(normal_values)\n",
" \n",
" #print normal_values\n",
" \n",
" # we shift them so that the starting pitch is at the left side of the bell curve\n",
" normal_values += start_pitch_num\n",
"\n",
" # we do mod 12 so that our numbers are still from 0-11\n",
" normal_values %= 12\n",
" \n",
" # technically they're still floats at this point. return them as ints.\n",
" return normal_values.astype(int)\n",
"\n"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 7
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# get a big list of pitches\n",
"\n",
"# which note do we want to start on? C = 0\n",
"# start on F (5), meaning we have very few F's\n",
"start_pitch = 0\n",
"\n",
"# let's use the method we defined above to get 1000 pitches\n",
"pitches = gen_norm_pitch_dist(start_pitch, num_pitches = 1000)\n",
"\n",
"# generate a histogram of the normal values. This will put them into 12 bins and generate a nice graphic of the distribution\n",
"counts, null, null = plt.hist(pitches,12)\n"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"png": "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\nRU5ErkJggg==\n",
"text": [
"<matplotlib.figure.Figure at 0x10902cc90>"
]
}
],
"prompt_number": 8
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"\n",
"#make a little chart of the pitch class names and how many of each we got\n",
"# zip takes two lists and lines them up, giving you pairs of elements, one from each list\n",
"for num, count in zip(range(12), counts):\n",
" print p_class_names[num], \"\\t\", count\n",
"\n",
"#print the pitch class selections as numbers \n",
"print pitches[:10]\n",
"\n",
"#now print them with their pitch class names\n",
"for n in pitches[:10]:\n",
" print p_class_names[n], "
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"c \t5.0\n",
"c# \t12.0\n",
"d \t29.0\n",
"d# \t67.0\n",
"e \t123.0\n",
"f \t184.0\n",
"f# \t193.0\n",
"g \t187.0\n",
"g# \t111.0\n",
"a \t58.0\n",
"a# \t21.0\n",
"b \t10.0\n",
"[9 4 6 3 3 4 7 5 6 7]\n",
"a e f# d# d# e g f f# g\n"
]
}
],
"prompt_number": 9
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"#make a bar graph showing us how many of each pitch class we got\n",
"plt.xticks(np.arange(0,12), p_class_names)\n",
"plt.bar(np.arange(0,12), counts, align='center')\n"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 10,
"text": [
"<Container object of 12 artists>"
]
},
{
"metadata": {},
"output_type": "display_data",
"png": "iVBORw0KGgoAAAANSUhEUgAAAXIAAAEACAYAAACuzv3DAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAE/FJREFUeJzt3X9s1Hfhx/HXB9tJAlTaGK7a63LOtrQ32rtuWEXpKBll\nuo3aOXOzm6wMjFvVqHFGx4zakmV00WE2FTMJmVWTIZpJMXEEZblaGKa4DZzeJnWWrS1t2ShIRx0I\nvL9/zF4K9Aff6+dz1/f1+UguKXefvl+fu3764t33fe7OMcYYAQCsNSvVOwAAmBqKHAAsR5EDgOUo\ncgCwHEUOAJajyAHAchMWeXd3t5YvX65rr71WixYt0uOPPy5JGhwcVHV1tYqKirRy5UqdPHky/j0b\nN25UYWGhiouLtXv3bm/3HgAgZ6LzyPv7+9Xf369wOKy33npL119/vXbs2KEnn3xS733ve/WNb3xD\njzzyiE6cOKHm5mbFYjHdeeedOnDggHp7e7VixQodPnxYs2Yx8QcAr0zYsLm5uQqHw5KkuXPnqqSk\nRL29vdq5c6fq6+slSfX19dqxY4ckqbW1VXV1dcrMzFQgEFBBQYE6Ojo8vgsAMLNd8VT5yJEjevHF\nF/XhD39YAwMD8vl8kiSfz6eBgQFJ0tGjR+X3++Pf4/f71dvb6/IuAwBGu6Iif+utt3T77bfrscce\n07x58y66zXEcOY4z7vdOdBsAYOoyJtvgv//9r26//XatXr1atbW1kt6Zhff39ys3N1d9fX1asGCB\nJCkvL0/d3d3x7+3p6VFeXt5lY4bDYR06dMit+wAAM0IoFNLBgwcvu37CGbkxRuvWrVMwGNRXv/rV\n+PU1NTVqaWmRJLW0tMQLvqamRtu2bdPZs2fV1dWlzs5OVVRUXDbuoUOHZIy5ost3v/vdK97WrUuy\nM9M9bybcRx7T9Mic7nnjTYAnnJHv27dPv/zlL1VWVqby8nJJ75xe+MADDygSiWjr1q0KBALavn27\nJCkYDCoSiSgYDCojI0ObN29maQUAPDZhkS9dulQXLlwY87Y//vGPY17/4IMP6sEHH5z6ngEArsi0\nP8G7qqoq7TPTPS8Vmemel4pM7uP0zZvwBUFecRxHKYgFAKuN153TfkYOAJgYRQ6MIysrJ/46Cbcv\nWVk5qb57SCMsrQDjeOeMK6+OU34H8P/H0goApCmKHAAsR5EDgOUocgCwHEUOAJajyIFpgtMdkShO\nPwTGkezTDzndEZPh9EMASFMUOazh1dIDyw6wHUsrsIZ3Sw9jH48srWC6YWkFANIURQ4AlqPIAcBy\nFDkAWI4iBwDLUeQAYDmKHAAsR5EDgOUocgCwHEUOAJajyAHAchQ5AFiOIgcAy1HkAGA5ihwALEeR\nA4DlKHIAsBxFDgCWo8gBwHIUOQBYjiIHAMtR5ABgOYocACxHkQOA5ShyALAcRQ4AlqPIAcByFDkA\nWI4iBwDLUeQAYDmKHAAsR5EDgOUmLfK1a9fK5/OptLQ0fl1jY6P8fr/Ky8tVXl6uZ555Jn7bxo0b\nVVhYqOLiYu3evdubvQYAxDnGGDPRBu3t7Zo7d67uvvtuvfTSS5KkpqYmzZs3T1/72tcu2jYWi+nO\nO+/UgQMH1NvbqxUrVujw4cOaNevi/y8cx9EkscBlHMeR5MVxM/bx6F3e2JnJzoN9xuvOSWfklZWV\nys7Ovuz6sQZrbW1VXV2dMjMzFQgEVFBQoI6OjgR3GQBwJRJeI//hD3+oUCikdevW6eTJk5Kko0eP\nyu/3x7fx+/3q7e2d+l4CAMaVkcg3NTQ06Dvf+Y4k6dvf/rbuv/9+bd26dcxt3/lz8XKNjY3xr6uq\nqlRVVZXIrgBA2opGo4pGo5Nul1CRL1iwIP715z73Oa1atUqSlJeXp+7u7vhtPT09ysvLG3OM0UUO\nALjcpZPcpqamMbdLaGmlr68v/vVvf/vb+BktNTU12rZtm86ePauuri51dnaqoqIikQgAwBWadEZe\nV1entrY2vfnmm8rPz1dTU5Oi0agOHjwox3H0gQ98QE888YQkKRgMKhKJKBgMKiMjQ5s3bx53aQUA\n4I5JTz/0JJTTD5EATj90Nw/2Sfj0QwDA9EaRA4DlKHIAsBxFDgCWo8gBwHIUOQBYjiIHAMtR5ABg\nOYocACxHkQOA5ShyALAcRQ4AlqPIAcByFDkAWI4iBwDLUeQAYDmKHAAsR5EDgOUocgCwHEUOAJaj\nyAHAchQ5AFiOIgcAy1HkAGA5ihwALEeRA4DlKHIkJCsrR47jeHLJyspJ9d0DrOIYY0zSQx1HKYiF\nixzHkeTVz3Ds48O7zGTnjZ2ZiscUdhmvO5mRA4DlKHIAsBxFDgCWo8gBwHIUOQBYjiIHAMtR5ABg\nOYocACxHkQOA5ShyALAcRQ4AlqPIgRmMNz9LD7xpFhLCm2a5n5lej+n4mUgcb5oFAGmKIgcAy1Hk\nAGA5ihwALEeRA4DlKHIAsNykRb527Vr5fD6VlpbGrxscHFR1dbWKioq0cuVKnTx5Mn7bxo0bVVhY\nqOLiYu3evdubvQYAxE1a5Pfcc4927dp10XXNzc2qrq7W4cOHdeONN6q5uVmSFIvF9Ktf/UqxWEy7\ndu3SF77wBV24cMGbPQcASLqCIq+srFR2dvZF1+3cuVP19fWSpPr6eu3YsUOS1Nraqrq6OmVmZioQ\nCKigoEAdHR0e7DYAYERCa+QDAwPy+XySJJ/Pp4GBAUnS0aNH5ff749v5/X719va6sJsAgPFkTHWA\nkfdVmOj2sTQ2Nsa/rqqqUlVV1VR3BQDSSjQaVTQanXS7hIrc5/Opv79fubm56uvr04IFCyRJeXl5\n6u7ujm/X09OjvLy8MccYXeQAgMtdOsltamoac7uEllZqamrU0tIiSWppaVFtbW38+m3btuns2bPq\n6upSZ2enKioqEokAAFyhSWfkdXV1amtr05tvvqn8/Hxt2LBBDzzwgCKRiLZu3apAIKDt27dLkoLB\noCKRiILBoDIyMrR58+YJl10AAFPH29giIen1lqvT4y1e0+sxHT8TieNtbAEgTVHkAGA5ihwALEeR\nA4DlKHIAsBxFDgCWo8gBwHIUOQBYjiIHAMtR5ABgOYocACxHkQOA5ShyALAcRQ4AlqPIAcByFDkA\nWI4iBwDLUeQAYDmKHAAsR5EDgOUocgCwHEUOAJajyAHAchQ5AFiOIgcAy1HkAGA5ihwALEeRA4Dl\nKHIAsBxFDgCWo8gBwHIUOQBYjiJPE1lZOXIcx5NLVlZOqu8egAk4xhiT9FDHUQpi05rjOJK8ekwv\n/3klO8/bzGTnjZ2ZXo/p+JlI3HjdyYwcACxHkQOA5ShyALAcRQ4AlqPIAcByFDkAWI4iBwDLUeQA\nYDmKHEDS8Apkb2SkegcAzBxDQyfk1StJh4YcT8a1ATNyALAcRQ4AlqPIAcByU1ojDwQCysrK0rve\n9S5lZmaqo6NDg4ODuuOOO/Taa68pEAho+/btmj9/vlv7CwC4xJRm5I7jKBqN6sUXX1RHR4ckqbm5\nWdXV1Tp8+LBuvPFGNTc3u7KjAICxTXlp5dL3xt25c6fq6+slSfX19dqxY8dUIwAAE5jyjHzFihVa\nvHixtmzZIkkaGBiQz+eTJPl8Pg0MDEx9LwEA45rSGvm+ffv0vve9T2+88Yaqq6tVXFx80e0jJ+qP\npbGxMf51VVWVqqqqprIrAJB2otGootHopNu59lFvTU1Nmjt3rrZs2aJoNKrc3Fz19fVp+fLleuWV\nVy4O5aPeXMfHktmUN3Zmej2mY2fy0XJT4/pHvQ0PD2toaEiSdPr0ae3evVulpaWqqalRS0uLJKml\npUW1tbWJRgAArkDCM/Kuri7ddtttkqRz587prrvu0vr16zU4OKhIJKLXX3993NMPmZG7bybMrJiR\nu5uXikxm5FMzXne6trTixs4gcTPhF5IidzcvFZkU+dS4vrQCAJgeKHIAsBxFDgCWo8gBwHIUOQBY\njiIHAMtR5ABgOYocACxHkQOA5ShyALAcRQ4AlqPIAcByFDkAWI4iBwDLUeQAYDmKHAAsR5EDgOUo\ncgCwHEXukaysHDmO4/olKysn1XcNwDSTkeodSFdDQyfkxWcTDg05ro8JwG7MyAHAchQ5AFiOIgcA\ny1HkAGA5ihwALEeRA4DlKHIAsBxFDiCtzYQX5/GCIABpbSa8OI8ZOQBYjiIHAMtR5ABgOYocACxH\nkQOA5ShyALAcRQ4AlqPIAcByM6LIvXpl13R7dReAmWlGvLLTq1d2vTP29Hl1F4CZaUbMyAEgnc2I\nGTkAJEtWVs7/VgGShyIHABd5uZQrjb2Uy9IKAFiOIgcAy1HkAGC5lK2RO443p+3Nm5etU6cGPRkb\nAKYjT2bku3btUnFxsQoLC/XII4+Ms5Xx5JLsZ4sBINVcL/Lz58/rS1/6knbt2qVYLKannnpKL7/8\n8hRGjLq1a9M4M93zUpGZ7nmpyEx2Xioy7cxzvcg7OjpUUFCgQCCgzMxMfeYzn1Fra+sURoy6tWvT\nODPd81KRme55qchMdl4qMu3Mc73Ie3t7lZ+fH/+33+9Xb2+v2zEAgP9xvci9ehITADAO47L9+/eb\nm266Kf7vhx9+2DQ3N1+0TSgU8uaZTi5cuHBJ40soFBqzdx1jjJGLzp07p4ULF2rPnj16//vfr4qK\nCj311FMqKSlxMwYA8D+un0eekZGhH/3oR7rpppt0/vx5rVu3jhIHAA+5PiMHACQXL9Efw+nTp1Vd\nXS1Jqqys1IULFzzPbGxs1KOPPprUjH/84x9as2aNjDH66Ec/6ml2Mj3++OMKBoNavXp1UjNGHsPb\nbrtNAwMDnmWnUroeM6M98cQT+tnPfqZDhw7pvvvu8yTjyJEjKi0tdW083sZ2DPv379eSJUt04sQJ\nzZkzR7Nmef//XTLO9rk0o729XTfccIP++te/atGiRZ7nJ8tPfvKT+HM0ycr45z//qYKCAhlj1NfX\nJ5/P51l2KqXrMTPa3r171dTUpN/97ne64YYbUr07V8bts1bc1NLSYsrKykwoFDKrV6/2dPy7777b\nvPrqqyYUCpnc3FzzwQ9+0FxzzTUmNzfXlJeXm2PHjrme/9BDD5mioiKzdOlSU1dXZ77//e8nJaO9\nvd2Ew2GTk5NjSkpKjN/vN1dffbX50Ic+5Hr+L37xC1NRUWHC4bC59957zfnz513PGO3ee+81V111\nlSktLTU/+MEPPM/YuHGjCYfD5uqrrzb5+fmmuLjY5OTkmHA4bA4ePOhJ/oYNG8zChQs9O27GGj+Z\nx4wxxtTW1prrr7/eXHvtteanP/1pUsbftGmTCYfDZs6cOSYcDpv58+ebYDBoGhoaXM/v6uoyxcXF\n5q677jIlJSXm05/+tBkeHk54vGlb5H/7299MUVGROX78uDHGmMHBwaSNf8stt5jBwUHT1NRkfv/7\n37uaO+Ivf/mLKS0tNf/5z3/MqVOnTEFBgXn00UeTmrFkyRJjjDH33HOPicVirmYbY0wsFjOrVq0y\n586dM8YY09DQYH7+85+7nnOpQCAQ/7kmK+OLX/yieeGFF0xLS4vZvHmzZ7kdHR0mHA6bM2fOmKGh\nIVNYWOjqcTPZ+F4fMyNGfh+Hh4fNokWLXP95jjf+G2+8YWpqaowxxlRUVLiaOVpXV5dxHMc899xz\nxhhj1q5dO6X/kKftGvmzzz6rSCSinJx3PqU+Ozs7aeMfO3ZM2dnZOnTokMrKylzNHdHe3q5PfepT\nmj17tubNm6eamhoZl593nihjeHhY7373uyVJnZ2dKioqcjVbkvbs2aPnn39eixcvVnl5uZ599ll1\ndXW5njMdvPTSSwoGg54eM5K0b98+1dbW6qqrrtLcuXO1atUqV4+bicZPxjEz4rHHHlM4HNaSJUvU\n09Ojzs5Oz8bv7u6Oj//888+rrKxMp06d0vz5813NvFR+fr6WLFkiSfrsZz+rvXv3JjzWtF0jdxzH\n9WKbbPyGhgbt3btXPT09Ki8vV2dnp2699VatWbNGX/nKVzzN9+K+jvcYfvKTn9Qrr7yikydPKhQK\n6ciRI1q8eLHWr1+vSCTi6j7U19fr4YcfdnXM6cIYow0bNujpp5/Wq6++qo985CP617/+pT/84Q/6\nxCc+McE7fybO6+NmOhwz0WhUe/bs0Z///GfNnj1by5cv15kzZzwd//XXX9d9992nY8eOafbs2dq2\nbZuGhoZ03XXX6Te/+Y2uueYa1/JHjH7OyhgztefJEv/jwFt///vfL1r6cPtPq0vHH/lT69e//rXZ\ntGmTOXLkiIlEIq5mjvbCCy+YsrKy+LKH238iT5bxve99zzz99NMmGo2ab37zm67mjojFYqawsDD+\n/MLx48fNa6+95knWaMleWjlw4ID58pe/bM6cOWMqKys9zT1w4IC57rrrzNtvv22GhoZMUVGRq8fN\nROMn45gxxpjW1lazatUqY4wxL7/8spk9e7Zpa2tLyvi33nqrOX78uGlsbDTPPPOMa5mXGlla2b9/\nvzHGmHXr1plNmzYlPN60XVoJBoP61re+pWXLlikcDuvrX/+6p+Pff//9kqS2tjYtXbpU7e3tqqqq\ncjVztPLyct1xxx0KhUK6+eabVVFRkdSMP/3pT/rYxz6m9vZ2LVu2zPVsSSopKdFDDz2klStXKhQK\naeXKlerv7/cka7RknwHU1tamyspKdXR0xP9U9srixYtVU1OjsrIy3XzzzSotLdV73vOepIyfjGNG\nkj7+8Y/r3LlzCgaDWr9+veuP6Xjjnz9/XoODg8rJydFzzz2npUuXupo7muM4WrhwoX784x8rGAzq\n3//+txoaGhIfzxheEATY5PTp05ozZ46Gh4e1bNkybdmyReFw2Jrx4b5pu0YOYGyf//znFYvF9Pbb\nb2vNmjWul6zX48N9zMgBwHLTdo0cAHBlKHIAsBxFDgCWo8gBwHIUOQBYjiIHAMv9HzNvMNf5oNLd\nAAAAAElFTkSuQmCC\n",
"text": [
"<matplotlib.figure.Figure at 0x1090dba90>"
]
}
],
"prompt_number": 10
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"#write them to a text file as MIDI note values around middle C (midi note 60)\n",
"\n",
"filename = \"normal_notes.txt\"\n",
"\n",
"with open(filename, 'w') as f:\n",
" midi_note_offset = 60\n",
" \n",
" for note in pitches:\n",
" trans_note_num = note + midi_note_offset\n",
" #print \"t_n_n: \", trans_note_num\n",
" f.write(str(trans_note_num))\n",
" f.write(\", \")\n",
" \n",
" \n",
" f.write(\"\\n\")\n",
" f.close()\n",
"\n",
"\n",
"open_file(filename)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 11
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"#that's cool, but what about making an actual MIDI file from the data?\n",
"\n",
"#make a pretty midi object\n",
"pm = pretty_midi.PrettyMIDI()\n",
"\n",
"#add a trumpet instrument\n",
"pm.instruments.append(pretty_midi.Instrument(56))\n",
"\n",
"curr_time = 0.0\n",
"beat_duration = .1\n",
"note_duration = beat_duration * 0.9\n",
"# clustered around middle C\n",
"midi_note_offset = 60\n",
"\n",
"times = []\n",
"\n",
"for note in pitches:\n",
" trans_note_num = note + midi_note_offset\n",
" pm.instruments[0].notes.append(pretty_midi.Note(90, \n",
" trans_note_num, curr_time, curr_time + note_duration))\n",
" curr_time += beat_duration\n",
"\n",
"#we'll use this filename to play back in a sec, so let's store it in a variable\n",
"midi_filename = \"normal_dist.mid\"\n",
"#write out the midi file. This file is for real and will work with any midi app!\n",
"pm.write(midi_filename)\n",
"\n",
"#play it!\n",
"play_midi_file(midi_filename)\n",
"\n"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 12
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"#MAKE IT STOP!!!\n",
"kill_midi()"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 13
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# a little improv with cymbal...\n",
"\n",
"#make a pretty midi object\n",
"pm = pretty_midi.PrettyMIDI()\n",
"\n",
"#add a couple instruments\n",
"pm.instruments.append(pretty_midi.Instrument(20))\n",
"pm.instruments.append(pretty_midi.Instrument(0, is_drum=True))\n",
"\n",
"beats_per_second = 8\n",
"improv_duration = 10.0\n",
"num_beats = improv_duration * beats_per_second\n",
"beat_length = improv_duration / num_beats\n",
"# why use a multiplier here instead of just, say, subtracting 0.1 seconds?\n",
"note_length = beat_length * 0.75\n",
"\n",
"# use np.arange to create a list of beat start times\n",
"for time in np.arange(0, improv_duration, beat_length):\n",
" #just to prove to yourself that this works!\n",
" #print \"current time: \", time\n",
" \n",
" #pick a random midi note from 60-72 (middle C + an octave)\n",
" note = random.randint(60, 72);\n",
" \n",
" #append the note to our instrument's note list\n",
" #Note arguments are volume, note number, start time, end time\n",
" \n",
" # maybe we don't always want a note. Use np.random.choice to decide...\n",
" \n",
" if np.random.choice([True, False]):\n",
" pm.instruments[0].notes.append(pretty_midi.Note(90, note, time, time + note_length))\n",
" \n",
" #add a cymbal tick on each beat. Why not!?!\n",
" # let's vary the volume a bit to give it some life\n",
" volume = random.randint(70,110)\n",
" pm.instruments[1].notes.append(pretty_midi.Note(volume, 42, time, time + note_length))\n",
"\n",
"#we'll use this filename to play back in a sec, so let's store it in a variable\n",
"midi_filename = \"improv.mid\"\n",
"#write out the midi file. This file is for real and will work with any midi app!\n",
"pm.write(midi_filename)\n",
"\n",
"#play it!\n",
"play_midi_file(midi_filename)\n",
"\n"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 14
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"kill_midi()"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 15
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# What about that Tom Johnson Chord Catalog piece? Let's do something like that!\n",
"# Let's play all 3-voice chords in an octave\n",
"\n",
"\n",
"# this is our starting note, middle C\n",
"base_note = 60\n",
"#this will keep track of where each of our three voices is\n",
"chord = [0,0,0]\n",
"\n",
"# let's store all the chords to use later...\n",
"tj_chords = []\n",
"\n",
"#how long is each beat\n",
"beat_duration = .1\n",
"\n",
"#how long do we hold each chord? let's say it's half the beat duration\n",
"note_duration = beat_duration * 0.5\n",
"\n",
"#make a pretty midi object\n",
"pm = pretty_midi.PrettyMIDI()\n",
"\n",
"#add honky tonk piano\n",
"pm.instruments.append(pretty_midi.Instrument(3))\n",
"pm.instruments.append(pretty_midi.Instrument(0, is_drum=True))\n",
"\n",
"curr_time = 0.0\n",
"\n",
"#uh, let's just do 2 or it'll play forever...\n",
"#for offset_0 in range(12):\n",
"for offset_0 in range(2):\n",
" \n",
" chord[0] = base_note + offset_0\n",
" \n",
" for offset_1 in range(12):\n",
" chord[1] = base_note + offset_1\n",
" \n",
" for offset_2 in range(12):\n",
" chord[2] = base_note + offset_2\n",
" \n",
" for n in range(3):\n",
" #wiggle our volume, from 20-90\n",
" volume = random.randint(20,90)\n",
"\n",
" #create our chord from our three chord[n] values\n",
" #use curr_time as starting time and curr_time + our note duration for the stop time\n",
" pm.instruments[0].notes.append(pretty_midi.Note(volume, chord[n], curr_time, curr_time + note_duration))\n",
" volume = random.randint(70,110)\n",
" pm.instruments[1].notes.append(pretty_midi.Note(volume, 42, curr_time, curr_time + note_length))\n",
" #increment curr_time with beat_duration, not note_duration. This lets us play with articulation a bit\n",
" curr_time += beat_duration\n",
" \n",
" # save for later\n",
" # note that we make a copy of the chord each time\n",
" # otherwise we're just saving a reference to the same chord structure and it'll replace the values every time!\n",
" tj_chords.append(list(chord))\n",
"\n",
"midi_filename = \"all_chords.mid\"\n",
"pm.write(midi_filename)\n",
"\n",
"#play it!\n",
"play_midi_file(midi_filename)\n"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 16
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"kill_midi()"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 17
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"#let's mess up a perfectly good midi file\n",
"\n",
"input_filename = \"moonlight.mid\"\n",
"\n",
"# Construct PrettyMIDI object\n",
"pm = pretty_midi.PrettyMIDI(\"moonlight.mid\")\n",
"\n",
"c_counter = 0\n",
"c_mod_counter = 0\n",
"\n",
"# Iterate over the instrument tracks in the MIDI file\n",
"for instrument in pm.instruments:\n",
" # Check whether the instrument is a drum track\n",
" if not instrument.is_drum:\n",
" # Iterate over note events for this instrument\n",
" # Enumerate gives us an index as well as the object\n",
" for i,note in enumerate(instrument.notes):\n",
" \n",
" if note.pitch % 12 == 0:\n",
" c_counter += 1\n",
" #we'll just mess up every 5th note\n",
" if i % 5 == 0:\n",
" # Shift up by a half-step\n",
" note.pitch += 1\n",
" \n",
" if note.pitch % 12== 0:\n",
" c_mod_counter += 1\n",
" \n",
"# Write out wonky version\n",
"name_parts = input_filename.split(\".\")\n",
"print \"name_parts: \", name_parts\n",
"output_filename = name_parts[0] + \"_wonky.mid\"\n",
"print \"output_filename: \", output_filename\n",
"pm.write(output_filename)\n",
"\n",
"#play it!\n",
"play_midi_file(output_filename)\n",
"\n",
"print (\"here's how many c's:\", c_counter)\n",
"print (\"here's how many c mods:\", c_mod_counter)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"name_parts: ['moonlight', 'mid']\n",
"output_filename: moonlight_wonky.mid\n",
"(\"here's how many c's:\", 64)"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"(\"here's how many c mods:\", 74)\n"
]
}
],
"prompt_number": 18
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"kill_midi()"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 19
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# How about something with text? Let's assign a note to each letter in the alphabet, then play texts through it!\n",
"\n",
"def values_from_text(text):\n",
"\n",
" values = []\n",
"\n",
" for letter in text:\n",
" # ord gets the ascii value of each letter\n",
" # %127 makes sure we only get note numbers 0-127\n",
" letter_value = ord(letter) % 127\n",
" \n",
" #add it to our list!\n",
" values.append(letter_value)\n",
" \n",
" #we'll just return a list of values to be processed later...\n",
" return values\n",
"\n",
"\n",
"\n",
"#let's use it!\n",
"\n",
"#our text can come from anywhere. \n",
"\n",
"#here we'll open a file and read in the text\n",
"\n",
"f = open(\"seuss_green.txt\", \"r\")\n",
"text_lines = f.readlines()\n",
"text = \"\"\n",
"for line in text_lines:\n",
" text += line\n",
"\n",
"\n",
"#here we'll just type in some text directly\n",
"#text = \"i like tacos. I like tacos. You like tacos. U like tacos.\"\n",
"\n",
"# get letter values from the text\n",
"# we'll interpret them as MIDI note values, but they could be anything\n",
"notes = values_from_text(text)\n",
"\n",
"#make a pretty midi object\n",
"pm = pretty_midi.PrettyMIDI()\n",
"\n",
"#add banjo\n",
"pm.instruments.append(pretty_midi.Instrument(105))\n",
"\n",
"#how long is each bleep?\n",
"beat_duration = 0.05\n",
"note_duration = beat_duration * 0.75\n",
"\n",
"curr_time = 0.0\n",
" \n",
"for note in notes:\n",
" pm.instruments[0].notes.append(pretty_midi.Note(75, note, curr_time, curr_time + note_duration))\n",
" curr_time += note_duration\n",
" \n",
"\n",
"midi_filename = \"text_to_notes.mid\"\n",
"pm.write(midi_filename)\n",
"\n",
"#let's play it!\n",
"play_midi_file(midi_filename)\n",
"\n",
"# let's plot the notes and print the text!\n",
"plt.xlabel(\"letters\")\n",
"plt.ylabel(\"midi notes\")\n",
"plt.plot(range(len(notes)), notes)\n",
"print text\n"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"I am Sam. I am Sam. Sam-I-Am.\n",
"\n",
"That Sam-I-Am! That Sam-I-Am! I do not like that Sam-I-Am!\n",
"\n",
"Do you like green eggs and ham?\n",
"\n",
"I do not like them, Sam-I-Am.\n",
"I do not like green eggs and ham.\n",
"\n",
"Would you like them here or there?\n",
"\n",
"I would not like them here or there.\n",
"I would not like them anywhere.\n",
"I do not like green eggs and ham.\n",
"I do not like them, Sam-I-Am.\n",
"\n",
"\n"
]
},
{
"metadata": {},
"output_type": "display_data",
"png": "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\n",
"text": [
"<matplotlib.figure.Figure at 0x1095b7750>"
]
}
],
"prompt_number": 20
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"kill_midi()"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 21
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# that was all playing with note values. what about time?\n",
"\n",
"# let's play one note lots of times, constantly speeding up\n",
"\n",
"#make a pretty midi object\n",
"pm = pretty_midi.PrettyMIDI()\n",
"\n",
"#add drum\n",
"pm.instruments.append(pretty_midi.Instrument(0, is_drum=True))\n",
"\n",
"# each note for a 10th of a second\n",
"note_num = 37 #side stick\n",
"note_dur = 0.1\n",
"\n",
"# we'll make 100 notes\n",
"num_hits = 100\n",
"# starting 1 second apart\n",
"delay = 1.0\n",
"# reduce delay by some percentage each hit\n",
"time_dialation_coefficient = 0.1\n",
"\n",
"# first event at time zero\n",
"time = 0.0\n",
"\n",
"events = []\n",
"\n",
"# let's get faster and then slower\n",
"for n in range(num_hits):\n",
" pm.instruments[0].notes.append(pretty_midi.Note(75, note_num, time, time + note_dur))\n",
" \n",
" notes.append(time)\n",
" time += delay\n",
" \n",
" # we'll switch directions 1/2 way through...\n",
" if n < num_hits/2:\n",
" delay -= delay * time_dialation_coefficient\n",
" else:\n",
" delay += delay * time_dialation_coefficient\n",
"\n",
"midi_filename = \"slow_fast_slow.mid\"\n",
"pm.write(midi_filename)\n",
"\n",
"#let's play it!\n",
"play_midi_file(midi_filename)\n",
"\n",
"#events is now a list of start times for something or other\n",
"print(events)\n",
"plt.plot(events)\n",
"\n"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"[]\n"
]
},
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 22,
"text": [
"[<matplotlib.lines.Line2D at 0x109690f90>]"
]
},
{
"metadata": {},
"output_type": "display_data",
"png": "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\n6NAhBYPBjA0GAHBmwgEBALi/zYg7qe/3m+4yMZ8kHTp0SLNmzdLAwMBkt3xPnM63c+dO+f1+BQIB\nrV+/Xjdv3pyq1u/obsdCknbs2CGfz6dAIKD29vZ72na6TXS+WCymxx57TIsXL9aSJUv04osvTmXb\n4+bk+Emf3cO1fPlyrV27diravSdOZhscHFRlZaX8fr+Ki4vV2to69os5voqRATt37jQNDQ3GGGPq\n6+vNrl270mpGRkZMQUGBuXr1qhkaGjKBQMB0dHQYY4y5cOGC+da3vmWGhoaMMcb84x//mLrmx8Hp\nfMYYc+3aNVNWVmby8/PNjRs3pqz38XA63+9//3uTTCaNMcbs2rXLuv1UutuxMMaYM2fOmDVr1hhj\njGltbTWlpaXj3na6OZnv+vXrpr293RhjzL///W9TWFh4X833f4cOHTIbN240a9eunbK+x8PpbJs3\nbza/+c1vjDHGDA8Pm8HBwTFfb0acQdzvN905nU+SnnnmGb3wwgtT1vO9cDpfKBTSrFmf/VMsLS1V\nPB6fuuYt7nYspNEzl5aWanBwUH19fePadrpNdL7+/n7l5ORo2bJlkqS5c+fK7/ert7d3ymcYi5P5\nJCkejyscDuupp56SmWG/gXcy282bN3Xx4kVt2bJFkpSVlaUHHnhgzNebEQFxv99053S+5uZmeTwe\nLV26dGoavkdO57vVyy+/rPLy8slrdhzG0+udanp7e8c153Sa6Hy3B3dPT4/a29tVWlo6uQ3fIyfH\nT5KefvppHTx4MPWhZSZxcuyuXr2q+fPn68knn9SKFSu0detWffzxx2O+3oS/5nqv7veb7iZrvk8+\n+UT79+/XuXPnUs9Nx6eayTx+t+5r9uzZ2rhx48QbzYDx9CpNz3HIhInOd+t2H330kSorK3X48GHN\nnTs3o/05NdH5jDF6/fXXtWDBAi1fvnxG/ikOJ8duZGREly5dUmNjo1auXKm6ujrV19frZz/72R33\nM2UBcesb3O3cbrf6+vqUk5Oj69eva8GCBWk1ubm5isViqeVYLCaPxyPps4Rcv369JGnlypWaNWuW\nbty4Yb2vYrJM1nxXrlxRT0+PAoGApM9Ofx955BG1tbVZ9zNZJvP4SdIrr7yicDis8+fPZ7bxCbhb\nr7aaeDwuj8ej4eHhu2473SY6X25urqTPvqL+xBNPaNOmTdb7n6abk/lee+01tbS0KBwO69NPP9WH\nH36ozZs36+TJk1PW/1iczGaMkcfj0cqVKyVJlZWV1j+yOkqGrp04snPnztQd1gcOHLBepBweHjZf\n/epXzdWrV81//vOfURdnjhw5Yn76058aY4x5//33TV5e3tQ1Pw5O57vVTL1I7WS+s2fPmuLiYvPP\nf/5zSvu+k/Eci1svBL755pupC4HjPY7Tycl8//3vf80PfvADU1dXN+V9j5eT+W4VjUbNd77znSnp\nebyczvaNb3zDvP/++8YYY55//nnz7LPPjvl6MyIgbty4YVatWmV8Pp8JhULmgw8+MMYYk0gkTHl5\neaouHA6bwsJCU1BQYPbv3596fmhoyGzatMksWbLErFixwrzxxhtTPcKYnM53q4cffnjGBYTT+bxe\nr/nyl79sli1bZpYtW2a2b98+5TPcztbrkSNHzJEjR1I1P/rRj0xBQYFZunSpefvtt8fcdqaZ6HwX\nL140LpfLBAKB1PE6e/bstMwwFifH7/+i0eiM+xaTMc5me+edd0xJSYlZunSp+e53v3vXbzFxoxwA\nwGrmXaYHAMwIBAQAwIqAAABYERAAACsCAgBgRUAAAKwICACAFQEBALD6H0kMTjXEL6ZMAAAAAElF\nTkSuQmCC\n",
"text": [
"<matplotlib.figure.Figure at 0x10970a110>"
]
}
],
"prompt_number": 22
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"kill_midi()"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 23
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# okay, but that was kinda clunky. Let's generate start times directly\n",
"\n",
"#make a pretty midi object\n",
"pm = pretty_midi.PrettyMIDI()\n",
"\n",
"#add drum\n",
"pm.instruments.append(pretty_midi.Instrument(0, is_drum=True))\n",
"\n",
"# each note is a middle C played for a 10th of a second\n",
"note_num = 38 #snare\n",
"note_dur = 0.1\n",
"\n",
"# generate log-spaced numbers\n",
"# np.linspace() generates a linear spacing\n",
"# so np.logspace() generate a log spacing, which is often more musically interesting\n",
"# from 2^4 to 2^0 (16 to 1)\n",
"slow_fast = 16 - np.logspace(4,0,base=2)\n",
"fast_slow = 14 + np.logspace(0,4,base=2)\n",
"\n",
"start_times = np.concatenate((slow_fast, fast_slow))\n",
"\n",
"\n",
"for start in start_times:\n",
" pm.instruments[0].notes.append(pretty_midi.Note(75, note_num, start, start + note_dur))\n",
" \n",
"\n",
"midi_filename = \"slow_fast_slow2.mid\"\n",
"pm.write(midi_filename)\n",
"\n",
"#let's play it!\n",
"play_midi_file(midi_filename)\n",
"\n",
"# plot them as is\n",
"plt.plot(start_times)\n",
"print start_times\n",
"\n"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"[ 0. 0.88019795 1.71197412 2.49799231 3.24076977\n",
" 3.94268529 4.60598677 5.23279846 5.82512775 6.38487161\n",
" 6.91382262 7.41367479 7.8860289 8.3323977 8.75421069\n",
" 9.15281874 9.52949842 9.88545606 10.22183162 10.53970237\n",
" 10.84008629 11.12394538 11.39218871 11.64567534 11.88521707\n",
" 12.11158103 12.32549218 12.52763557 12.71865858 12.89917295\n",
" 13.0697568 13.23095643 13.38328808 13.52723961 13.66327202\n",
" 13.79182097 13.91329814 14.02809256 14.13657186 14.23908346\n",
" 14.33595566 14.42749868 14.51400571 14.59575378 14.6730047\n",
" 14.74600585 14.81499105 14.8801812 14.94178509 15. 15.\n",
" 15.05821491 15.1198188 15.18500895 15.25399415 15.3269953\n",
" 15.40424622 15.48599429 15.57250132 15.66404434 15.76091654\n",
" 15.86342814 15.97190744 16.08670186 16.20817903 16.33672798\n",
" 16.47276039 16.61671192 16.76904357 16.9302432 17.10082705\n",
" 17.28134142 17.47236443 17.67450782 17.88841897 18.11478293\n",
" 18.35432466 18.60781129 18.87605462 19.15991371 19.46029763\n",
" 19.77816838 20.11454394 20.47050158 20.84718126 21.24578931\n",
" 21.6676023 22.1139711 22.58632521 23.08617738 23.61512839\n",
" 24.17487225 24.76720154 25.39401323 26.05731471 26.75923023\n",
" 27.50200769 28.28802588 29.11980205 30. ]\n"
]
},
{
"metadata": {},
"output_type": "display_data",
"png": "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\n7lwtf3SgIwAAAABJRU5ErkJggg==\n",
"text": [
"<matplotlib.figure.Figure at 0x1094d8690>"
]
}
],
"prompt_number": 24
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"kill_midi()"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 25
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# same thing, but with a linear time drum along side for comparison\n",
"\n",
"#make a pretty midi object\n",
"pm = pretty_midi.PrettyMIDI()\n",
"\n",
"#add drum\n",
"pm.instruments.append(pretty_midi.Instrument(0, is_drum=True))\n",
"\n",
"# each note is a middle C played for a 10th of a second\n",
"log_note_num = 67 #high agogo\n",
"lin_note_num = 68 #low agogo\n",
"note_dur = 0.1\n",
"\n",
"# generate log-spaced numbers\n",
"# from 2^4 to 2^0 (16 to 1)\n",
"slow_fast = 16 - np.logspace(4,0,base=2)\n",
"fast_slow = 14 + np.logspace(0,4,base=2)\n",
"log_start_times = np.concatenate((slow_fast, fast_slow))\n",
"lin_start_times = np.linspace(0,30,100)\n",
"\n",
"\n",
"for log_start,lin_start in zip(log_start_times, lin_start_times):\n",
" pm.instruments[0].notes.append(pretty_midi.Note(75, log_note_num, log_start, log_start + note_dur))\n",
" pm.instruments[0].notes.append(pretty_midi.Note(75, lin_note_num, lin_start, lin_start + note_dur))\n",
"\n",
"midi_filename = \"speedup2.mid\"\n",
"pm.write(midi_filename)\n",
"\n",
"#let's play it!\n",
"play_midi_file(midi_filename)\n",
"\n",
"# plot them as is\n",
"plt.plot(log_start_times)\n",
"plt.plot(lin_start_times)\n"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 23,
"text": [
"[<matplotlib.lines.Line2D at 0x10270bc90>]"
]
},
{
"metadata": {},
"output_type": "display_data",
"png": "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\n",
"text": [
"<matplotlib.figure.Figure at 0x109579050>"
]
}
],
"prompt_number": 23
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"kill_midi()"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 24
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# let's do a normal distribution of drum hit onsets\n",
"\n",
"def get_norm_times(num = 100, duration = 10.0):\n",
" \n",
" # get num normally distributed values\n",
" norm_hits = np.random.randn(num)\n",
" #print norm_hits\n",
" \n",
" # sort them low to high\n",
" norm_hits.sort()\n",
" #print norm_hits\n",
" \n",
" # shift them so that we start at zero\n",
" norm_hits -= norm_hits.min()\n",
" #print norm_hits\n",
" \n",
" # we want to multiply our times by some value\n",
" # so that they cover the total duration\n",
" # last time value * x = duration\n",
" # x = duration / last time value\n",
" time_multi = duration / norm_hits.max()\n",
" norm_hits *= time_multi\n",
" \n",
" return norm_hits\n",
"\n",
"start_times = get_norm_times(1000, 15.0)\n",
"\n",
"#make a pretty midi object\n",
"pm = pretty_midi.PrettyMIDI()\n",
"\n",
"#add drum\n",
"pm.instruments.append(pretty_midi.Instrument(0, is_drum=True))\n",
"\n",
"# each note is a 10th of a second\n",
"note_num = 76 #wood block\n",
"note_dur = 0.1\n",
"\n",
"for time in start_times:\n",
" pm.instruments[0].notes.append(pretty_midi.Note(75, note_num, time, time + note_dur))\n",
"\n",
"midi_filename = \"normal_rhythm.mid\"\n",
"pm.write(midi_filename)\n",
"\n",
"#let's play it!\n",
"play_midi_file(midi_filename)\n",
"\n",
"plt.plot(start_times)\n",
"#print start_times"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 25,
"text": [
"[<matplotlib.lines.Line2D at 0x109b91dd0>]"
]
},
{
"metadata": {},
"output_type": "display_data",
"png": "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\n0ikmeCIinfp/xt7un1IQj78AAAAASUVORK5CYII=\n",
"text": [
"<matplotlib.figure.Figure at 0x109698050>"
]
}
],
"prompt_number": 25
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"kill_midi()"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 30
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# let's do two drums with different normal distributions\n",
"\n",
"start_times_a = get_norm_times(1000, 25.0)\n",
"start_times_b = get_norm_times(1000, 25.0)\n",
"\n",
"#make a pretty midi object\n",
"pm = pretty_midi.PrettyMIDI()\n",
"\n",
"#add drum\n",
"pm.instruments.append(pretty_midi.Instrument(0, is_drum=True))\n",
"pm.instruments.append(pretty_midi.Instrument(0, is_drum=True))\n",
"\n",
"# each note is a middle C played for a 10th of a second\n",
"note_num_a = 61 # tom\n",
"note_num_b = 60 # tom\n",
"note_dur = 0.25\n",
"\n",
"for time_a,time_b in zip(start_times_a,start_times_b):\n",
" pm.instruments[0].notes.append(pretty_midi.Note(75, note_num_a, time_a, time_a + note_dur))\n",
" pm.instruments[1].notes.append(pretty_midi.Note(75, note_num_b, time_b, time_b + note_dur))\n",
"\n",
"midi_filename = \"normal_rhythm_double.mid\"\n",
"pm.write(midi_filename)\n",
"\n",
"#let's play it!\n",
"play_midi_file(midi_filename)\n",
"\n",
"plt.plot(start_times_a)\n",
"plt.plot(start_times_b)\n",
"#print start_times"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 31,
"text": [
"[<matplotlib.lines.Line2D at 0x10dd5ddd0>]"
]
},
{
"metadata": {},
"output_type": "display_data",
"png": "iVBORw0KGgoAAAANSUhEUgAAAXgAAAEACAYAAAC57G0KAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3Xlc1VXi//HXVcx9VxZBQZEdFFxwyQV3zT3TscycdKZp\n/Vb2/VrNfButmXGZrMy26fetjLGymjKl3C0v7ito4oJLoICAIqIgiiyf3x+fwswN9V4uXN7Px+M+\n4l7u53PO5zzy7fF8zucci2EYBiIi4nSqOboCIiJiHwp4EREnpYAXEXFSCngRESelgBcRcVIKeBER\nJ3XDgL948SJdunQhPDyc4OBgXnzxRQCys7MZMGAA/v7+DBw4kJycnHKprIiIlJ3lZvPg8/PzqVOn\nDkVFRfTo0YO5c+cSExNDs2bNmDZtGnPmzOHMmTPMnj27vOosIiJlcNMhmjp16gBw6dIliouLady4\nMTExMUyaNAmASZMmsWTJEvvWUkREbtlNA76kpITw8HDc3Nzo06cPISEhZGZm4ubmBoCbmxuZmZl2\nr6iIiNwal5t9oVq1auzevZuzZ88yaNAg1q1bd8XvLRYLFovFbhUUEZHbc9OA/0XDhg0ZOnQou3bt\nws3NjYyMDNzd3UlPT8fV1fWq77dt25ajR4/atLIiIs7O19eXI0eO2ORcNxyiycrKKp0hc+HCBdas\nWUNERAQjRowgOjoagOjoaEaNGnXVsUePHsUwDL0Mg+nTpzu8DhXlpbZQW6gtbvyyZcf4hj349PR0\nJk2aRElJCSUlJUycOJF+/foRERHBuHHj+PDDD/Hx8eHLL7+0WYVERMQ2bhjwYWFhxMXFXfV5kyZN\nWLt2rd0qJSIid05PspaDqKgoR1ehwlBbXKa2uExtYR83fdDptk9ssWCnU4uIOC1bZqd68CIiTkoB\nLyLipBTwIiJOSgEvIuKkFPAiIk5KAS8i4qQU8CIiTkoBLyLipBTwIiJOSgEvIuKkFPAiIk5KAS8i\n4qQU8CIiTkoBLyLipBTwIiJOSgEvIuKkFPAiIk5KAS8i4qQU8CIiTkoBLyLipBTwIiJOSgEvIuKk\nFPAiIk5KAS8i4qQU8CIiTkoBLyLipG4Y8CkpKfTp04eQkBBCQ0OZP38+ADNmzMDLy4uIiAgiIiJY\nuXJluVRWRETKzmIYhnG9X2ZkZJCRkUF4eDh5eXl07NiRJUuW8OWXX1K/fn2mTp16/RNbLNzg1CIi\ncg22zE6XG/3S3d0dd3d3AOrVq0dQUBBpaWkACm8RkQquzGPwycnJxMfH07VrVwDeeust2rdvz5Qp\nU8jJybFbBUVE5PaUKeDz8vK47777ePPNN6lXrx6PPfYYSUlJ7N69Gw8PD5577jl711NExOlNeON9\nm57vhkM0AIWFhYwZM4YHH3yQUaNGAeDq6lr6+z/84Q8MHz78msfOmDGj9OeoqCiioqLurLYiIk7G\narVitVoBWL7mK5ue+4Y3WQ3DYNKkSTRt2pQ33nij9PP09HQ8PDwAeOONN9ixYwefffbZlSfWTVYR\nkVvi+nxPTv1zY/ncZN20aROffPIJ7dq1IyIiAoCZM2eyaNEidu/ejcVioXXr1rz/vm3/WSEiUhWd\nr55q0/PdsAd/RydWD15EpMxKjBJcZtTGeOWSzbJTT7KKiFQAp86fonpRA5ueUwEvIlIBpJ5LxSXf\n06bnVMCLiFQAiacTqZbjZ9NzKuBFRCqA2EO7KE5rb9NzKuBFRBzsSPYRPtu3kKGtx9j0vAp4EREH\nSsxK5O6P7ib05D8Y2iXIpudWwIuIOEhuQS7jvx7Pc92eo/b+P9KqlW3Pr4AXEXGQP3//Z3wa+fBs\n12dJSYGWLW17fgW8iIgDGIbBzvSdTO06FZdqNUhNVcCLiDiFF79/kRO5J2jn1o5Tp6BOHfNlSwp4\nEZFylncpj+g90Sz53RIa1mpol+EZUMCLiJS7xQcW49vYl/bu5rz3deugXTvbl6OAFxEpR5eKL/H0\nyqcZHzqeapZqZGTA3/4GkyfbviwFvIhIOVp8YDHBzYN5vPPjAMyYAQ8/DPbYD+mmOzqJiIhtnL14\nlpdjX+Zvff5GNUs10tPhiy8gKck+5akHLyJSTlYeWUlRSREjA0YCMHcuTJgAjRrZpzz14EVEysmR\n7COMCRpDjeo1SEuDBQsgIcF+5akHLyJSTtYlr6OdmzldZt48c+y9RQv7laeAFxEpB4dPHybhZAJj\ng8cC5tTIe++1b5kKeBGRcvDZ3s/4XcjvqFG9BgsWmDdWO3a0b5kKeBEROysuKeaTvZ/wQNgDGAZM\nnQqLF0OtWvYtVwEvImJnH8R9gGtdVyI9I0lPhxo1oHdv+5erWTQiInZ05sIZpq2dxoaHN2CxWEhM\nhICA8ilbPXgRETtafGAx/dv0L509c+iQAl5EpNJLzErkf9f9L493erz0s82bwd+/fMpXwIuI2MG5\ngnP0X9ifl3q9RL82/Th+HP76V1i7FiZOLJ86KOBFROzgsWWPMdh3MMPdH+feeyEsDFJSYOVK8PAo\nnzroJquIiI2lnktlxeEVHH4imZGDzfnuSUnQpEn51sNiGIZhlxNbLNjp1CIiFVZ6bjoDPxnIuKDx\nbJr9F1xcICYGqpVxvMSW2XnDIlNSUujTpw8hISGEhoYyf/58ALKzsxkwYAD+/v4MHDiQnJwcm1RG\nRKSy++emf3J3y7s58+2fMQz45puyh7ut3bAHn5GRQUZGBuHh4eTl5dGxY0eWLFnCggULaNasGdOm\nTWPOnDmcOXOG2bNnX3li9eBFpAopMUr4MO5Dpq2dxpJBe7i3Xyv27r31xcRsmZ03HIN3d3fH3d0d\ngHr16hEUFERaWhoxMTHExsYCMGnSJKKioq4KeBGRqqKwuJCHljxEXHoc/+q9lP95pBUvvWTflSLL\nosz/cEhOTiY+Pp4uXbqQmZmJm5sbAG5ubmRmZtqtgiIiFVWJUcLf1/+d0PdCOXD4Iq1X7uEPA3rR\nrh088YSja1fGWTR5eXmMGTOGN998k/r161/xO4vFgsViueZxM2bMKP05KiqKKHtsOigi4iAL9yzk\n33GLqLbi/1EtqxdTXrDw4fvg6Vn2c1itVqxWq13qd9NZNIWFhQwbNowhQ4bwzDPPABAYGIjVasXd\n3Z309HT69OnDwYMHrzyxxuBFxIntzdxL749747Iwlr/8MYwnn4Tq1e/8vOU2i8YwDKZMmUJwcHBp\nuAOMGDGC6OhoAKKjoxk1apRNKiMiUhkcOHWA3h/3pl/1GbSsGcbTT9sm3G3thj34jRs30qtXL9q1\na1c6DDNr1iwiIyMZN24cx48fx8fHhy+//JJGv9k1Vj14EXE2xSXFzLC+zPwt7xKaNYOfPn+Sr7+G\n7t1tV4Yts1MPOomIlEFGXgbT103n291bcVmyiN8PDebJJ8HV1bbllNs0SRGRqqqgqID3d73PwayD\nJOcks/nYNtzODqPomxhWL/YmNNTRNbw5BbyIyM+yL2Sz+MBilh1exq4Tuwh1DWVI23tI+eEe6nz3\nARMmtOBPG+DnWeIVnoZoRKTKMwyD17e8zivrX6F/m/4M8xtGF68uBDUL4oUXLKxaBevXQ4MG9q+L\nhmhERGwk5WwKX+z7grmb57Lx4Y2EuYUB8P33MHGauQrkgQPlE+62poAXkSop9Vwqz699nlVHVtGp\nRSdWT1xdGu5/+xu8/TZ8+CH07AkNGzq4srdJAS8iVcriA4t5e/vb7ErfxcR2E0l5NoXaNWpTVARb\ntsD06XDkCGzaBG3bOrq2d0Zj8CJSJeRczCF6dzRzt8zlrSFv0b9Nf346WI+YGDPMExKgZk2YOtXc\nUu83q7KUG43Bi4iU0bqkdczcOJNtqdvo7tWDf929mpNbgoh6ENLT4d574fHHwc8PAgLgOktrVUrq\nwYuIU9qTsYc5m+ZgTbbyQsd/cuDrMfz7o9q0aGHujzphAowcCS4VrJurHryIyG8YhsGh04dYcnAJ\na5PWsidjD3/u+WeeDHiVcYM9GTYMjh2DZs0cXdPyox68iFRKJUYJ87bOIz4jnvTcdBJPJ2IYBiMD\nRuJ5qT9ZWwexa2sd9u41b5w+/bSja1w2WotGRKq0k+dPMm/rPL45+A0v3P0CHvU9qJ7bmtOH2vLt\ntxaWLYNnn4UOHaB/f/PmaWWhgBeRKskwDNYlr+PhpQ/Ty7sX/xX5X9yV1Zm//918MKlzZxgzxvxv\nRISja3t7FPAiUiXkF+az88ROtqZuLX3VrlGbqV2n8kTkE3z9NTz6KPzlLzBpEjRu7Oga3zkFvIg4\ntSPZR5i/bT6LEhbh29iXrl5dS1/eDb3JyrLwwguwZAl8+61t12N3NM2iERGnc/zscT6I+4BVR1dx\n+PRhHg5/mPW/X09Q8yAADAMWLYL7Xod9+8xNrffuhRYtHFzxCkw9eBFxmNP5p4nPiGdb6jb+vuHv\n/CHiD4wKHEX3lt2pXaM2hYXwww+weTN8/LG54Nfs2ZXvxumt0BCNiFRaSWeSiD0WS2JWIu/seIcI\njwgCmgbwZOSTtHNrB0BRkblcwOrV4O9vBnq3bnDPPQ6ufDnQEI2IVColRgnrktaxYPcClh1expC2\nQ/Co58HGyRsJbtqO9eth7afw2h44dQq2bTNXcUxIAA8PR9e+8lIPXkTsIr8wnyUHl7D+2Hq+PvA1\nnvU9mRwxmeDiB/hxazNOnDAX+Tp6FHx8IDISwsPNQA8NBW9vR1+BY2iIRkQqpMSsRJYcXMKPJ39k\n+eHlhDQP4R6/odzdYDxbVrRm1SrzBukDD5ibVd99txnuVTXMr0UBLyIVQt6lPD5P+JzUc6mknUvj\n20PfMsh7NI3yO2IkDiM5wZ3du6GwEIYPh1GjzFCvrBtolAcFvIg4VIlRwo60HUxdPZUalpr41+pB\nQVYLflzVgeRNkXToYM5N79DB3DQjNNS5luG1JwW8iDhEcUkxf1ryNIsT/4NLSV1cj/w3R754hLZt\nXGjXDvr1g3HjHLdZhjPQLBoRKRf5+bA29jzfHvuMLSfWc8D4BktqNwKPbCHUsw3dusGf3oNatRxd\nU7kW9eBFBMOA06fNPUkTEgy+P7iD+IKvyK63kWoee3DPH0h4g/6MazeKsYM8qVPH0TV2XhqiEZHb\nZhiQlgYrVkBcvMGOYz+SkL0LXPdRx2cvhQ0TqV2zOiO8H+J3XXvRvVUX6t5V19HVrjIU8CJSZidO\nQGIiLF9urt2yfz/k1ovDp/d6Ulu8Ay4X6NemL+GewYS5huHf1J82jdtQvVp1R1e9SirXgJ88eTLL\nli3D1dWVvXv3AjBjxgw++OADmjdvDsCsWbMYPHiw3SopIrdm715zCd3YWKhWo5CWXXbg2nEzd7kf\nZW/+Kqq7lNCvdT8mR0yme8vuWDTFpcIo14DfsGED9erV46GHHioN+Jdffpn69eszderUcqmkiNxc\nfj4sXAjfb8hl1f6tRI7eRonXRnZkbKZN4zb08u6Fb2Nf+rTuQ6hrKNUs1RxdZbmGcp1F07NnT5KT\nk6/6XOEt4jiGAcnJsHbjOWJ2x7LhxFrO1d9GncZnKfJPIezuCMJ9u9Kt5SP09v6UpnWaOrrK4gC3\nPU3yrbfe4t///jedOnXitddeo1GjRrasl4j8SkkJfP45bN5+AWvKGo5c3ILhHUtxsx9p3agrEzr3\nY1zXV2lWpwm+TXyp5aJ5i1LGm6zJyckMHz68dIjm5MmTpePvL730Eunp6Xz44YdXnthiYfr06aXv\no6KiiIqKsmHVRZzfyfMnee/rfXyzaS/HCndy0TuGtg3aMcS/H4OCepSumy6Vl9VqxWq1lr5/+eWX\ny3cWzW8Dviy/0xi8yK3LzoaYuK18sO914k9v4mJxPjXPhtDBM4yhXYO4P2IEPo18HF1NsSOHP8ma\nnp6Ox8+LNH/zzTeEhYXZpDIiVUGJUcK5gnNk5GaycschNiUeIiFzHxn5KZytlYCLpSa+Gc/xZOA/\nGTvAm9BQi54Uldty0x78/fffT2xsLFlZWbi5ufHyyy9jtVrZvXs3FouF1q1b8/777+Pm5nblidWD\nFymVnpvO7HVvseNYAnHZ6zBKqmG50BxOB9C6YVvC3ELo2NabgR39aNfKW3PQqzA96CRSCaxaZbDs\nx62sPxvNQSOGkoSx+Na4m8jmfekU3IyQEOjSBerqIVH5FQW8SAVz9iwcOgR79kB8PGxPyOJA039S\nLewLwl3Gc0+r8Uy5J4Kf5yaIXJfDx+BFqrKLF82t5lavho0b4dBPF8kzTtKs8zrqtt1FocceTrb4\nkcG+g5l3zya8Gng5uspSRakHL3IdJSXw009mjzwuztxqbt8+OJ57FM8O+/DtfJispks5mLuNJnWa\n0KNVD7p6diXcPZwOHh1oXLuxoy9BKiEN0YjYWFER7NwJR47AwYOwfTts2waNGkFYp3Ncavc+eQ22\nc/CilbtqVCfcPZygZkGEuYUxqf0k3RQVm1HAi9yhwkJz/fP4eHPs/O23oVo1aN8ePEOOcZd3HA1a\nHmdNyjfsSt/FyICRDGk7hB6tetCqYSstziV2o4AXKYPERHOcfM8eyMw0b4QeOwYnT5oB36iRGej+\ngcU0Do+F1t+zLyuBjcc30s2rG60atiLKJ4oBbQZouEXKjQJe5DrOnIH33oPvvoPDh2HMGAgJAW9v\naNgQWrYEd3corp7Hf/Z/yY60HSxNXIpbPTdG+I/Au5E3IwJG0KxOM0dfilRRCniRn+XmQkoKnDpl\njp+//jqEhcGUKdC9++U55kezj/LG1jdIykkiPTedxNOJ9GzVk0G+gxjiN4TAZoGOvRCRnyngpUoy\nDHN3op07zVktq1dDQgJ4eUHTpmbvfOxYGD0aLBYoLC4k4WQCH8V/xKKERTwZ+SSdWnTCvZ47fk38\naFiroaMvSeQqCnipEkpKzO3lPv/cvBm6axcUF0PHjubY+cCBZi+9dm1zf4L9p/azOWUzR7KPkHw2\nmY3HN1K3Rl3GhYzjic5P4FHfw9GXJHJTCnhxOgUFkJ4O339v7h26c6f5vnFjePBBuPtuM9hbtTJ7\n579Iz01nzJdjSDiZQO0atRnqN5S2Tdri08iHMNcwwty0EJ5ULgp4qdQMA44fh6+/hpgYc5bL+fPg\n6gqdO0OfPjB8OLRoATVr/vo4g13pu/h6/9ek5qZyIvcEu07s4ukuT/NM12doVKuRpi9KpaeAl0qj\npMQcNz906PLDQ9u2mUMtQ4fCgAHmUEvjxuY89F8UlxRz+sJpErMSiUuPI+FkAmt+WkM1SzUmhE2g\nbZO2uNVzo6tXVxrV0m5i4jwU8FJhpabC1q0QG2vuGbplC9x1F/j6mr3zLl0gMhJ8fK4cagFzpsuK\nIyvYeHwj3x76ltoutWnTuA2dWnQiuHkwUT5RBDcP1mbR4tQU8FIhGAZkZJiP9q9aBUuXQlYWdO1q\n3vwMCDDD3Mvrt8cZnMo/RXJOMssPL2ffqX2sP7aegqIChvkPo3+b/vRt3ZdWDVs55sJEHEgBL+Wq\npMSclrh1q/nw0IED5iJcqanmDJawMDPUBw82x89/3TM3DIPjZ4+zPW07celxbDi+gV3pu6hboy4t\nG7akm1c3unl1o7dPb1o2aKkxdKnyFPBiNyUlZpCvXm0OsWRlwebN5jzz/v3Bzw8CA80hl5YtoU6d\ny8eeKzjHj5k/Ep8eT3yG+Tp0+hD176pPF68udPLoRGfPzvRs1ZO6d2mXC5FrUcCLzf34I7z1Fixc\naK7RMnGiGeRNmpjj5i1aXPn9EqOEuPQ41hxdQ3xGPLHHYsktyCXUNZQI9wgiPCKIcI8gqHkQDWo2\ncMxFiVRCCnixifx8WLsWFi82pytOnQqTJ18d5gdOHWDtT2tJzknm2NljHDt7jH0n99G0TlPGBo+l\nvVt7+rTuoyEWERtQwMtty8kxHyb6+GNzpkvHjjBsGEyYYC7C9Yus/Cx2ndjF9rTtzN0yl/tD76dN\n4zZ4N/SmVcNWhLmFUe+ueg67DhFnpYCXW3LiBPznP+brxx8hKAieesqch97451VwDcMg4WQCm1M2\nsyhhEfEZ8XTw6EAnj04M8B3AQN+Bjr0IkSpCAS9XKS421z9PTjZfKSnmDdK1a80ldHv1gsceM2e5\n1KplLsS19+Re9mTsYU/mHjYc30B6bjr92vRjsO9gxoWMo0b1Go6+LJEqRwEvFBWZvfH9+80nQ7/6\nylwa19fXfIioVSvzBmm3btCunfmUaH5hPl/t/4pFCYvYeHwj3g29CXcPJ7BZIF08u9CtZTcNu4g4\nmAK+ikpLM4N87VpzMa46dcwx9PBwuO8+8Pe/8vvnCs6xJWUL64+tZ1PKJuIz4on0jOSRDo/Qr00/\nmtRu4pgLEZHrUsBXMdu3w7/+ZS7ONXw4jBplhrqv79WP+6ecTWFr6lbmbZvHnow9dGzRkZ6tetKj\nVQ8iPSMV6iIVnC2z08UmZxGbOXXKfEo0I8NcNnflSvPzSZPMp0hdXa8+xjAM9p3ax5qja3hl/St0\natGJ57o9x1C/odR0qXn1ASJSJSjgHay4GFasgGXLzLH0n34ynxZt3hx69zYDPiDgypUWAQ5mHWTT\n8U1sT9tOzKEYarvUpn+b/nx7/7f0aNXDMRcjIhWKhmjKWW6uOZaemgpr1sAHH5g3RCdNMhfm6tTJ\nXH3x1y4VX2Jr6lbi0uNYl7yOxKxEci7mMKjtIAKaBjA+dDxtGrdxzAWJiE2V6xDN5MmTWbZsGa6u\nruzduxeA7Oxsfve733Hs2DF8fHz48ssvadRIa3L/VkEBbNhg9s4PHDCXzi0sNFdX9PIyZ7ds3Wr2\n2H+rsLiQL/Z9QUxiDNZkK14NvOjcojMPhD5AcPNgApsFahqjiNzQTXvwGzZsoF69ejz00EOlAT9t\n2jSaNWvGtGnTmDNnDmfOnGH27NlXnrgK9uDz882NLXbvhrlzzZ9DQmDMGAgOhp49oVmzq2+M/sIw\nDI5kH2HfqX3MsM7ApZoL/9Xlv+jl3QufRj7lei0i4hjlPosmOTmZ4cOHlwZ8YGAgsbGxuLm5kZGR\nQVRUFAcPHrRbJSuDzExziKVuXTPMH37YXD63evUbH1dQVEBcehybUzYTeyyW7Wnb6dSiE129uvLn\nnn/W5hYiVYzDZ9FkZmbi5uYGgJubG5mZmTapTGVTUGA+bBQTA9HR5vZzH3xw/R76L9LOpbH88HI2\npWziq/1f0bZJW7q37E6/1v34bMxnethIRGzijmfRWCyW664gOGPGjNKfo6KiiIqKutPiHM4w4Lvv\n4JVXYN8+aNMGhgwx13mJjLxxuJ8rOMc3B77hudXPMcRvCB3cO/C3Pn+jZcOW5XcBIlKhWK1WrFar\nXc5920M0VqsVd3d30tPT6dOnj9MP0ZSUwIcfwkcfmcMxb7xh9th/veHF9RSVFPFD0g88vPRhQl1D\neanXS5rKKCLX5PAhmhEjRhAdHc3zzz9PdHQ0o0aNskllKprsbPj2W7BazdkujRrBX/9qLtxV9yYb\nEi07tIyYxBh2nNjB4ezD+Df1Z/7g+YwJHlMudRcRuWkP/v777yc2NpasrCzc3Nx45ZVXGDlyJOPG\njeP48ePXnSZZWXvweXnmDJiDB80nSfv3h4EDISICOne++oGjX+QX5pOck4w12cqC3Qs4c+EMUyKm\n0K9NP/ya+NG4duPyvRARqZS0Fo0drFtnjqMvW3Z58a5evcDb+9rfT8xKJHpPNIdOH+LomaMczT6K\nR30POnh0YEzQGEYHjqZ6tZtMoRER+Q0FvA0tWgQvvGCOsT/9tDm1MSTk+jdL953cx7OrnmXD8Q08\n3ulxIj0j8W3ii18TPxrWali+lRcRp+PwMfjKrKQEVq+G9evNKY7x8eYSvF26XH/4BeDMhTNsTtnM\nhMUTeCryKWLuj6GWS63yq7iIyC2qUj345GT4y19gzx7z6dKAABgxAurdYNp59oVsVhxewV+tf8Wr\ngRd9ffoyPWp6udVZRKoW9eBvw9atMHYsjB4NmzdDgwY3/n5scizTrdOJS4+jt09v5g6Yy+ig0eVT\nWRERG3D6HvzevbBgAXz6Kbz/vrlZxs38dd1f+eTHT5jeezr3+N1D87rN7V9RERHUg7+pggLzgaRN\nm2DVKhg2zFwAzMPjJscVFfDOjneYv20+B544gEf9mxwgIlKBOdVKVnl5MH++Oba+bBn06wc7dpg9\n+JuF++IDi/Ge582KIyv4YdIPCncRqfScogeflgaPPgqxsdC9O3z5pbkuTFnsztjNq5tfZePxjSwd\nv5QuXl3sW1kRkXJSqXvwFy6Y68MMGwYtW0JKirnFXVnCPbcgl0e/e5R7Pr2Hto3bsu/xfQp3EXEq\nlbIHX1AA//gHvPmmOX/9pZdg5Mibr73+i5jEGJ5c/iSRnpHs+OMOPBt42rfCIiIOUOkC/uBBc6qj\nv785n93Hp+zHJpxM4N0d7/LV/q/4atxX9GzV87pLHYuIVHaVaojm/HkYOhSefRaWLCl7uOcX5vOP\n9f+gb3RfSowS4v4URy/vXgp3EXFqlWIefFYW/PSTOSRjGPDZZ2U/NvtCNiMWjaCopIgFIxcQ1DzI\nJnUSEbEHW2Znhe3BJybCu+/ChAnQujU88gi4usLbb5ft+NyCXMb+Zyxt3mxDuHs4Gx7eoHAXkSql\nQo7Bb9gAw4eb68X07QszZ15/2d7fKigqYP+p/Tyz6hn8mviR/EwyjWo1uvmBIiJOpsIN0RiGubnG\no4+ar1tRXFLMoE8GkXIuhVEBo5jVfxbVLBX2HykiIldx6qUKXn/dXNL3j38s2/eLS4r5Yt8XvLvj\nXXZn7KZ7y+7sf3y/NtsQkSqvQvXgN282h2Z27jTH3W+ksLiQj3d/zKd7PyW/MJ//7fW/RPlE0aDm\nTZaJFBGpwJyyB79jh/lE6kcf3TzcDcPgnR3v8PHuj3kq8ikmtp/IXdXvKp+KiohUEhUm4K1WmDTp\n5sv5nsg9wfBFw8nKz2LByAX0bd23XOonIlLZVIg7kBcvwnvvQdBNZjHOsM4g5N0Q+vr0JenpJIW7\niMgNVIgx+EcegfR0+OILqFPn2t9ZfXQ1ExZPYP/j+7UBh4g4Lacag//0U4iJMdeYuVa4G4ZBTGIM\njy57lPdgmk3UAAALHklEQVSGvqdwFxEpI4cG/IIFMHUqLF8Oja7xLNLSg0t58fsXqelSk3mD5nFf\n8H3lX0kRkUrKYUM0CQnQo4cZ7t27X/37xKxEun/UnY9GfMRQ/6G4VHP4PzZEROyu0g/R5OfD2LHw\n6qtXhnthcSEzN8xk+ZHl7M3cy7zB8xgZONIRVRQRqfQc0oN/9FFz6d+FCy9/dvzscUZ9PoqmdZry\nYo8X6ebVjdo1atujaiIiFVal7sF/8w2sWQPx8Zc/W310Nb9f8nv+u/t/82zXZ7VOu4iIDdxRD97H\nx4cGDRpQvXp1atSowfbt2y+f+Bp/CxUVQXAwvP8+9Oljfnbmwhma/LMJKyasYHDbwbdbFRERp1Bh\nevAWiwWr1UqTJk3K9P3Fi8013aOiLn+2PW07vb17K9xFRGzsjp9kvZW/aY4dg65d4dcjMNvSttHF\ns8udVkNERH7jjgLeYrHQv39/OnXqxP/93//d9PtpadCixeX3J3JP8O89/6Zfm353Ug0REbmGOxqi\n2bRpEx4eHpw6dYoBAwYQGBhIz549r/v9lBSzB/+Ld3e8S49WPRjoO/BOqiEiItdwRwHv4eEBQPPm\nzRk9ejTbt2+/IuBnzJhR+nOvXlFs2BDFa6+Z73MLcnlnxztsnbL1TqogIlKpWa1WrFarXc5927No\n8vPzKS4upn79+pw/f56BAwcyffp0Bg40e+O/vRO8c6e5gXZiovn+ZevLbE7dzKoHV935VYiIOIkK\nMYsmMzOT0aNHA1BUVMSECRNKw/23SkrgD3+4vMdqYXEhr299nfg/xV/z+yIicufK5UnW48fNsfe0\nNHMGzeHThxn0ySB+evonexQtIlJp2bIHXy4bfvz0E/j6Xp4eeTDrIH5N/cqjaBGRKqtcAn7nTggN\nvfx+xZEV9PHpUx5Fi4hUWXYP+PPn4d134f77zfclRgmLDyxmbPBYexctIlKl2T3gly4Ff3/o1ct8\nn3QmiZouNfFt4mvvokVEqjS7B/ypU+D3q+H2nSd2Eu4ebu9iRUSqPLsHfE7OldvxxRyKYbCvFhYT\nEbG3cgn4xo3NnwuKClh+eDmjg0bbu1gRkSqvXHvwa35aQ5hrGO713O1drIhIlWfXgC8uhi1boHlz\n8/3XB75mTNAYexYpIiI/s2vA79xpLlMwZIi5PEFMYgz3Bt1rzyJFRORndg34xx6DJ54AFxdYdngZ\nbZu0pWXDlvYsUkREfmbXtWiaNzfIzDSXKBjy6RAeDHuQCe0m2KM4ERGnUGnWovH0vLz+TNKZJCI8\nIuxZnIiI/IpdA/6X7fmOZB8h8XQi3g297VmciIj8il0DvlkzuFR8iQ7vd2DugLnUvauuPYsTEZFf\nsWvA160LmXmZ1K9Zn+e6P2fPokRE5DfsGvC1a0Pm+Uzc6rrZsxgREbkG+wd8XqaeXBURcQC7B/zu\njN20bdLWnsWIiMg12DngDRYlLGJcyDh7FiMiItdg14BPd9lMQXEB3Vt2t2cxIiJyDXYN+DR2MNh3\nMNUs5bL1q4iI/IpdkzfPkoZnA097FiEiItdh14A/a6ThWV8BLyLiCHYN+JziE+rBi4g4iF0DPrsw\njRb1W9izCBERuQ67BnzWJQ3RiIg4il0DvrrFhfo169uzCBERuY7bDviVK1cSGBiIn58fc+bMueZ3\n3Ouq9y4i4ii3FfDFxcU8+eSTrFy5kv3797No0SIOHDhw1fdaaHgGAKvV6ugqVBhqi8vUFpepLezj\ntgJ++/bttG3bFh8fH2rUqMH48eNZunTpVd8LbBpwxxV0Bvqf9zK1xWVqi8vUFvZxWwGflpZGy5aX\nN8/28vIiLS3tqu9Niph4+zUTEZE7clsBb/llo9WbCPcIu53Ti4iILRi3YcuWLcagQYNK38+cOdOY\nPXv2Fd/x9fU1AL300ksvvW7h5evrezuxfE0WwzAMblFRUREBAQF8//33tGjRgsjISBYtWkRQUNCt\nnkpEROzE5bYOcnHh7bffZtCgQRQXFzNlyhSFu4hIBXNbPXgREan47PIka1kegnImKSkp9OnTh5CQ\nEEJDQ5k/fz4A2dnZDBgwAH9/fwYOHEhOTk7pMbNmzcLPz4/AwEBWr17tqKrbRXFxMREREQwfPhyo\nuu0AkJOTw3333UdQUBDBwcFs27atSrbHrFmzCAkJISwsjAceeICCgoIq0w6TJ0/Gzc2NsLDLk05u\n59p37dpFWFgYfn5+PP3002Ur3Gaj+T8rKioyfH19jaSkJOPSpUtG+/btjf3799u6mAolPT3diI+P\nNwzDMHJzcw1/f39j//79xv/8z/8Yc+bMMQzDMGbPnm08//zzhmEYxr59+4z27dsbly5dMpKSkgxf\nX1+juLjYYfW3tddee8144IEHjOHDhxuGYVTZdjAMw3jooYeMDz/80DAMwygsLDRycnKqXHskJSUZ\nrVu3Ni5evGgYhmGMGzfO+Pjjj6tMO6xfv96Ii4szQkNDSz+7lWsvKSkxDMMwOnfubGzbts0wDMMY\nMmSIsWLFipuWbfOA37x58xUzbGbNmmXMmjXL1sVUaCNHjjTWrFljBAQEGBkZGYZhmH8JBAQEGIZx\n9ayjQYMGGVu2bHFIXW0tJSXF6Nevn/HDDz8Yw4YNMwzDqJLtYBiGkZOTY7Ru3fqqz6tae5w+fdrw\n9/c3srOzjcLCQmPYsGHG6tWrq1Q7JCUlXRHwt3rtJ06cMAIDA0s/X7RokfGnP/3ppuXafIimrA9B\nOavk5GTi4+Pp0qULmZmZuLm5AeDm5kZmZiYAJ06cwMvLq/QYZ2qjZ599lldffZVq1S7/r1UV2wEg\nKSmJ5s2b8/DDD9OhQwf++Mc/cv78+SrXHk2aNOG5556jVatWtGjRgkaNGjFgwIAq1w6/dqvX/tvP\nPT09y9QmNg/4sj4E5Yzy8vIYM2YMb775JvXrX7mKpsViuWHbOEO7fffdd7i6uhIREYFxnXv3VaEd\nflFUVERcXByPP/44cXFx1K1bl9mzZ1/xnarQHkePHmXevHkkJydz4sQJ8vLy+OSTT674TlVoh+u5\n2bXfCZsHvKenJykpKaXvU1JSrvibx1kVFhYyZswYJk6cyKhRowDzb+aMjAwA0tPTcXV1Ba5uo9TU\nVDw9K//CbJs3byYmJobWrVtz//3388MPPzBx4sQq1w6/8PLywsvLi86dOwNw3333ERcXh7u7e5Vq\nj507d9K9e3eaNm2Ki4sL9957L1u2bKly7fBrt/JnwsvLC09PT1JTU6/4vCxtYvOA79SpE4cPHyY5\nOZlLly7xxRdfMGLECFsXU6EYhsGUKVMIDg7mmWeeKf18xIgRREdHAxAdHV0a/CNGjODzzz/n0qVL\nJCUlcfjwYSIjIx1Sd1uaOXMmKSkpJCUl8fnnn9O3b18WLlxY5drhF+7u7rRs2ZJDhw4BsHbtWkJC\nQhg+fHiVao/AwEC2bt3KhQsXMAyDtWvXEhwcXOXa4ddu9c+Eu7s7DRo0YNu2bRiGwcKFC0uPuSFb\n3ED4reXLlxv+/v6Gr6+vMXPmTHsUUaFs2LDBsFgsRvv27Y3w8HAjPDzcWLFihXH69GmjX79+hp+f\nnzFgwADjzJkzpcf84x//MHx9fY2AgABj5cqVDqy9fVit1tJZNFW5HXbv3m106tTJaNeunTF69Ggj\nJyenSrbHnDlzjODgYCM0NNR46KGHjEuXLlWZdhg/frzh4eFh1KhRw/Dy8jI++uij27r2nTt3GqGh\noYavr6/x1FNPlalsPegkIuKk7Lpln4iIOI4CXkTESSngRUSclAJeRMRJKeBFRJyUAl5ExEkp4EVE\nnJQCXkTESf1/MAvf75EYnM8AAAAASUVORK5CYII=\n",
"text": [
"<matplotlib.figure.Figure at 0x10dcd8550>"
]
}
],
"prompt_number": 31
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"kill_midi()"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 32
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"okay, normal is nice, what about something else?\n",
"pareto is a one-sided exponential distribution\n",
"so we'll get lots of events at the beginning and then a long tail"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def get_pareto_times(num = 100, duration = 10.0, shape = 5):\n",
" \n",
" # get num pareto distributed values\n",
" pareto_hits = np.random.pareto(shape, num)\n",
" #print pareto_hits\n",
" \n",
" # sort them low to high\n",
" pareto_hits.sort()\n",
" #print norm_hits\n",
" \n",
" # shift them so that we start at zero\n",
" pareto_hits -= pareto_hits.min()\n",
" #print norm_hits\n",
" \n",
" # we want to multiply our times by some value\n",
" # so that they cover the total duration\n",
" time_multi = duration / pareto_hits.max()\n",
"\n",
" pareto_hits *= time_multi\n",
" \n",
" return pareto_hits\n",
"\n",
"# the shape parameter tells you how sharp the turn is...\n",
"start_times = get_pareto_times(1000, 25.0)\n",
"\n",
"#make a pretty midi object\n",
"pm = pretty_midi.PrettyMIDI()\n",
"\n",
"#add drum\n",
"pm.instruments.append(pretty_midi.Instrument(0, is_drum=True))\n",
"\n",
"# each note is a middle C played for a 10th of a second\n",
"note_num = 61 # tom\n",
"note_dur = 0.25\n",
"\n",
"for time in start_times:\n",
" pm.instruments[0].notes.append(pretty_midi.Note(75, note_num, time, time + note_dur))\n",
"\n",
"midi_filename = \"pareto_rhythm.mid\"\n",
"pm.write(midi_filename)\n",
"\n",
"#let's play it!\n",
"play_midi_file(midi_filename)\n",
"\n",
"plt.plot(start_times)\n",
"#print start_times\n"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 26,
"text": [
"[<matplotlib.lines.Line2D at 0x109ca6950>]"
]
},
{
"metadata": {},
"output_type": "display_data",
"png": "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\nAAAAAElFTkSuQmCC\n",
"text": [
"<matplotlib.figure.Figure at 0x109579090>"
]
}
],
"prompt_number": 26
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"kill_midi()"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 34
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"zipf is a power law type distribution -- small events are most likely, large events least likely. we'll use it to make a crackling sound, with occassional loud bursts. like a log burning!"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"\n",
"def get_zipf_volumes(num = 100, shape = 2.0):\n",
" \n",
" # get num zipf distributed values\n",
" volumes = np.random.zipf(shape, num)\n",
" \n",
" # find multiplier to shift values from 10-127 for MIDI volume\n",
" normalizer = 117.0/volumes.max()\n",
" volumes *= normalizer\n",
" # now all values are from 0-117, so shift up 10 for 10-127\n",
" volumes += 10\n",
" \n",
" return volumes\n",
"\n",
"# get a bunch of volume values\n",
"volumes = get_zipf_volumes(500)\n",
"\n",
"#make a pretty midi object\n",
"pm = pretty_midi.PrettyMIDI()\n",
"\n",
"#add drum\n",
"pm.instruments.append(pretty_midi.Instrument(0, is_drum=True))\n",
"\n",
"# our drum sound\n",
"note_num = 62 # tom\n",
"note_dur = 0.5\n",
"\n",
"# we're generating our time values with linspace. they're independent of our note_dur value. so we can overlap notes if we want...\n",
"for time, volume in zip(np.linspace(0.0, 20, len(volumes)), volumes):\n",
" pm.instruments[0].notes.append(pretty_midi.Note(volume, note_num, time, time + note_dur))\n",
"\n",
"midi_filename = \"zipf_volumes.mid\"\n",
"pm.write(midi_filename)\n",
"\n",
"#let's play it!\n",
"play_midi_file(midi_filename)\n",
"\n",
"plt.plot(volumes)\n"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 30,
"text": [
"[<matplotlib.lines.Line2D at 0x10a2d1250>]"
]
},
{
"metadata": {},
"output_type": "display_data",
"png": "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\n",
"text": [
"<matplotlib.figure.Figure at 0x109627c50>"
]
}
],
"prompt_number": 30
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"kill_midi()"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 29
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Remember the Tom Johnson example, above? We stored the chords in a list called tj_chords. Let's use them to generate a score using Abjad and lilypond, an open source music notation package.\n",
"\n",
"We stored the chords as MIDI values, starting with middle C (MIDI note 60). But abjad uses middle C = 0. So we need to subtract 60 from each element in each chord. Ugh! \n",
"\n",
"In a normal Python list you can't operate on all members of the list at once. You'd have to iterate through each item in each chord, subtract 60 from it, then store it back in the chord. Luckily numpy knows that this is a pretty common need, so there's a super easy way to do it using a numpy array rather than a Python list. You can generally think of numpy arrays and Python lists as being the same thing. But numpy arrays have a lot of extra functions built in that let you manipulate them in all sorts of useful ways."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# we'll use a numpy array here so that we can do the -= 60 trick\n",
"# this line simply copies the Python list tj_chords into a numpy array called np_chords\n",
"np_chords = np.array(tj_chords)\n",
"\n",
"# the chords are using MIDI note numbers. but abjad wants middle C = 0\n",
"# so we'll just shift everything down by 60\n",
"np_chords -= 60\n",
"\n",
"# an abjad Container can take a bunch of chords and display them on a staff\n",
"score = abjad.Container()\n",
"\n",
"# we'll create an abjad Chord object for each chord and store it in our score\n",
"for chord in np_chords:\n",
" chord = abjad.Chord(chord, abjad.Duration(1, 4))\n",
" score.append(chord)\n",
" \n",
"# abjad will use lilypad behind the scenes to create a pdf file and ask our OS to open it for us\n",
"abjad.show(score)\n",
"\n"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 31
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Remember above when we generated a bunch of pitches in a normal distribution. We stored them in a list called pitches. Let's make a score!\n",
"\n",
"We stored pitches as numbers from 0-11, so we don't have to shift them down for abjad."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"normal_score = abjad.Container()\n",
"\n",
"for pitch in pitches:\n",
" normal_score.append(abjad.Note(pitch, abjad.Duration(1,32)))\n",
"\n",
"abjad.show(normal_score)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 32
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Remember the Larry Polansky piece 51 Melodies? It used the idea of 'morphing' one melody into another. Let's see how we might do that.\n",
"\n",
"We'll start with melody A and morph it into melody B. We'll just do the pitches this time, but you could apply this technique to any parameters you want.\n",
"\n",
"To make the process really clear we'll simply morph an ascending C Major scale into a descending C Major scale. We'll iterate through the scale over and over again, each time picking a note to morph. Morphing a note will simply mean moving it one half step closer to the target note."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# nudge one note in current closer to target\n",
"def morph_scale_step(target, current):\n",
" \n",
" note_num = random.randint(0,len(target) - 1)\n",
" #print \"trying note: \", note_num\n",
"\n",
" t_note = target[note_num]\n",
"\n",
" if current[note_num] < t_note:\n",
" current[note_num] += 1\n",
" return True\n",
" elif current[note_num] > t_note:\n",
" current[note_num] -= 1\n",
" return True\n",
" else:\n",
" return False"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 33
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"source_scale = [0, 2, 4, 5, 7, 9, 11, 12]\n",
"\n",
"# WHAT?!?\n",
"# this means take the whole list and count through it backwards (-1)\n",
"# that gives us the list backwards!\n",
"target_scale = source_scale[::-1]\n",
"\n",
"# we want to make a copy of our scale so that we don't modify the original\n",
"# this has the same effect as doing:\n",
"# curr_scale = source_scale[:]\n",
"curr_scale = list(source_scale)\n",
"\n",
"print source_scale\n",
"print target_scale\n",
"print curr_scale\n",
"\n",
"# we want to store all of our intermediate scales\n",
"scales = [source_scale]\n",
"\n",
"while not curr_scale == target_scale:\n",
" got_one = morph_scale_step(target_scale, curr_scale)\n",
" if got_one:\n",
" scales.append(list(curr_scale))\n",
" \n",
"#make a pretty midi object\n",
"pm = pretty_midi.PrettyMIDI()\n",
"\n",
"#add guitar\n",
"pm.instruments.append(pretty_midi.Instrument(24, is_drum=False))\n",
"\n",
"time = 0.0\n",
"note_num = 0 \n",
"beat_dur = 0.1\n",
"note_dur = beat_dur * 0.9\n",
"\n",
"# create an abjad score container\n",
"morph_score = abjad.Container()\n",
"\n",
"for scale in scales:\n",
" for note in scale:\n",
" morph_score.append(abjad.Note(note, abjad.Duration(1, 16)))\n",
" pm.instruments[0].notes.append(pretty_midi.Note(90, note + 60, time, time + note_dur))\n",
" time += beat_dur\n",
"\n",
"\n",
"abjad.show(morph_score)\n",
"\n",
"\n",
"midi_filename = \"morph_melody.mid\"\n",
"pm.write(midi_filename)\n",
"\n",
"#let's play it!\n",
"play_midi_file(midi_filename)\n"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"[0, 2, 4, 5, 7, 9, 11, 12]\n",
"[12, 11, 9, 7, 5, 4, 2, 0]\n",
"[0, 2, 4, 5, 7, 9, 11, 12]\n"
]
}
],
"prompt_number": 34
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"kill_midi()"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 32
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# come on, we gotta do two at once!\n",
"# let's use one-note source/target melodies!\n",
"\n",
"source_scale_a = [0,0,0,0,0,0,0,0]\n",
"source_scale_b = [12,12,12,12,12,12,12,12]\n",
"\n",
"target_scale_a = list(source_scale_b)\n",
"target_scale_b = list(source_scale_a)\n",
"\n",
"# we want to make a copy of our scale so that we don't modify the original\n",
"curr_scale_a = list(source_scale_a)\n",
"curr_scale_b = list(source_scale_b)\n",
"\n",
"print source_scale_a\n",
"print target_scale_a\n",
"print source_scale_b\n",
"print target_scale_b\n",
"\n",
"#print curr_scale_a\n",
"#print curr_scale_b\n",
"\n",
"# we want to store all of our intermediate scales\n",
"scales_a = [source_scale_a]\n",
"scales_b = [source_scale_b]\n",
"\n",
"while not curr_scale_a == target_scale_a:\n",
" got_one = morph_scale_step(target_scale_a, curr_scale_a)\n",
" if got_one:\n",
" scales_a.append(list(curr_scale_a))\n",
"\n",
"while not curr_scale_b == target_scale_b:\n",
" got_one = morph_scale_step(target_scale_b, curr_scale_b)\n",
" if got_one:\n",
" scales_b.append(list(curr_scale_b))\n",
"\n",
"#print curr_scale\n",
"\n",
"#print scales\n",
"\n",
" \n",
"#make a pretty midi object\n",
"pm = pretty_midi.PrettyMIDI()\n",
"\n",
"#add guitars\n",
"pm.instruments.append(pretty_midi.Instrument(24, is_drum=False))\n",
"pm.instruments.append(pretty_midi.Instrument(25, is_drum=False))\n",
"\n",
"# our drum sound\n",
"time = 0.0\n",
"note_num = 0 \n",
"beat_dur = 0.15\n",
"note_dur = beat_dur * 0.9\n",
"\n",
"morph_score = abjad.Container()\n",
"\n",
"for s_a, s_b in zip(scales_a, scales_b):\n",
" for note_a, note_b in zip(s_a, s_b):\n",
" chord = abjad.Chord([note_a], abjad.Duration(1,8))\n",
" chord.note_heads.append(note_b)\n",
" morph_score.append(chord)\n",
" pm.instruments[0].notes.append(pretty_midi.Note(90, note_a + 60, time, time + note_dur))\n",
" pm.instruments[1].notes.append(pretty_midi.Note(90, note_b + 60, time, time + note_dur))\n",
" time += beat_dur\n",
"\n",
"abjad.show(morph_score)\n",
"\n",
"\n",
"midi_filename = \"morph_melodies.mid\"\n",
"pm.write(midi_filename)\n",
"\n",
"#let's play it!\n",
"play_midi_file(midi_filename)\n",
"\n"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"[0, 0, 0, 0, 0, 0, 0, 0]\n",
"[12, 12, 12, 12, 12, 12, 12, 12]\n",
"[12, 12, 12, 12, 12, 12, 12, 12]\n",
"[0, 0, 0, 0, 0, 0, 0, 0]\n"
]
}
],
"prompt_number": 35
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"kill_midi()"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 43
},
{
"cell_type": "code",
"collapsed": false,
"input": [],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 112
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"\n"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 113
},
{
"cell_type": "code",
"collapsed": false,
"input": [],
"language": "python",
"metadata": {},
"outputs": []
}
],
"metadata": {}
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment