{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"name": "4.4 Learning Billie Jean.ipynb",
"provenance": [],
"collapsed_sections": [],
"toc_visible": true,
"include_colab_link": true
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "view-in-github",
"colab_type": "text"
},
"source": [
""
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "43_89uOEoRGh",
"colab_type": "text"
},
"source": [
"#4.4 Learning Billie Jean\n",
"Let's work with an actual song. In this notebook we'll learn how to use Markov chains to learn patterns from actual songs and generate new material. We will read in music from the song Billi Jean, train a Markov model, and resynthesize Billie Jean using the trained Markov model. Things get weird quickly..."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "z8qlvAmBownS",
"colab_type": "text"
},
"source": [
"## Step 1: Setup\n",
"Install external libraries and import them into your notebok session"
]
},
{
"cell_type": "code",
"metadata": {
"id": "FQR9wI2woycP",
"colab_type": "code",
"colab": {}
},
"source": [
"# install external libraries for sound playback\n",
"from IPython.display import clear_output\n",
"!pip install -q git+https://github.com/davidkant/mai#egg=mai;\n",
"!apt-get -qq update\n",
"!apt-get -qq install -y libfluidsynth1\n",
"!apt-get install lame\n",
"!git clone https://github.com/davidkant/mai.git\n",
"clear_output()"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "pnALZR3Sp0yx",
"colab_type": "code",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 34
},
"outputId": "ca1115f3-1047-4f4e-c214-1c3f825cba99"
},
"source": [
"# imports\n",
"import mai\n",
"import random\n",
"import pretty_midi\n",
"import matplotlib.pyplot as plt\n",
"import copy\n",
"import IPython.display"
],
"execution_count": 2,
"outputs": [
{
"output_type": "stream",
"text": [
"Using TensorFlow backend.\n"
],
"name": "stderr"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "pRkghRsEEqE1",
"colab_type": "text"
},
"source": [
"We'll also define a function here for plotting. Don't worry about understanding this cell."
]
},
{
"cell_type": "code",
"metadata": {
"id": "NBpnxXijEwaD",
"colab_type": "code",
"colab": {}
},
"source": [
"def plot_melodies(original_pitches, new_pitcjes, num_notes=45):\n",
" \"\"\"Plot original melody and new melody.\"\"\"\n",
" plt.figure(figsize=(9,3))\n",
" plt.plot(original_pitches[0:num_notes])\n",
" plt.scatter(range(num_notes), original_pitches[0:num_notes])\n",
" plt.plot(new_pitches[0:num_notes])\n",
" plt.scatter(range(num_notes), new_pitches[0:num_notes])\n",
" plt.ylim([min(original_pitches)-1, max(original_pitches)+1])\n",
" plt.xlabel('time (in numbe of notes)')\n",
" plt.ylabel('pitch')\n",
" plt.title(\"original melody (blue) and new melody (orange)\");"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "BgZQ_gcFqFoO",
"colab_type": "text"
},
"source": [
"## Step 2: Load a MIDI file\n",
"First load in a MIDI file of the song Billie Jean. We are using a Python package called `pretty_midi` to read and manipulate MIDI data. I have provided the MIDI file `Billie_Jean.mid` in the `aim80L` Python package."
]
},
{
"cell_type": "code",
"metadata": {
"id": "hTgyHI6rZU9d",
"colab_type": "code",
"colab": {}
},
"source": [
"# load midi file\n",
"midi_data = pretty_midi.PrettyMIDI('mai/resources/midi/Billie_Jean.mid')\n",
"\n",
"# and make a copy for our resynthesized version\n",
"altered_midi_data = copy.deepcopy(midi_data)"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "lKVU6l_EoViL",
"colab_type": "text"
},
"source": [
"## Step 3: Select an instrument\n",
"MIDI files are often organized with multiple voices or instruments, which are stored in an `instruments` list. Run the cell below to see the instruments list. Hopefully the file you are using names its instruments! Otherwise it'll be difficult to know which voice corresponds to which instrument..."
]
},
{
"cell_type": "code",
"metadata": {
"id": "azeeKlSB5SKX",
"colab_type": "code",
"outputId": "3ef2cca2-1f81-43a3-a454-9a024e29fd2f",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 243
}
},
"source": [
"# display all instruments\n",
"midi_data.instruments"
],
"execution_count": 5,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"[Instrument(program=53, is_drum=False, name=\"\"),\n",
" Instrument(program=5, is_drum=False, name=\"\"),\n",
" Instrument(program=27, is_drum=False, name=\"\"),\n",
" Instrument(program=28, is_drum=False, name=\"\"),\n",
" Instrument(program=49, is_drum=False, name=\"\"),\n",
" Instrument(program=7, is_drum=False, name=\"\"),\n",
" Instrument(program=63, is_drum=False, name=\"\"),\n",
" Instrument(program=88, is_drum=False, name=\"\"),\n",
" Instrument(program=62, is_drum=False, name=\"\"),\n",
" Instrument(program=28, is_drum=False, name=\"\"),\n",
" Instrument(program=50, is_drum=False, name=\"\"),\n",
" Instrument(program=35, is_drum=False, name=\"\"),\n",
" Instrument(program=0, is_drum=True, name=\"\")]"
]
},
"metadata": {
"tags": []
},
"execution_count": 5
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "0prpSkCz5i52",
"colab_type": "text"
},
"source": [
"Now indicate the instrument you'd like to work with according to its index in the list. "
]
},
{
"cell_type": "code",
"metadata": {
"id": "EHxQzqM0oRBo",
"colab_type": "code",
"colab": {}
},
"source": [
"# instrument to work with\n",
"instrument_index = 0"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "I1rp7kWtZU9i",
"colab_type": "text"
},
"source": [
"__note:__ Since instruments arn't named in this file, here are a few:\n",
"\n",
"* vocal = `midi_data.instrument[0]`\n",
"* drums = `midi_data.instrument[-1]`\n",
"* bass = `midi_data.instrument[-2]`\n",
"* keys = `midi_data.instrument[-3]`"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "G-JVU8hc3qIq",
"colab_type": "text"
},
"source": [
"## Step 4: Extract note pitches\n",
"We are going to extract the pitch and rhythm information from the vocal melody, turning it into two lists of numbers, one representing pitch and the other duration. Don't worry about understanding the programming in this cell."
]
},
{
"cell_type": "code",
"metadata": {
"id": "CZTO4dMlBf87",
"colab_type": "code",
"colab": {}
},
"source": [
"# select instrument from list\n",
"instrument = midi_data.instruments[instrument_index]\n",
"\n",
"# extract pitch to list\n",
"original_pitches = [note.pitch for note in instrument.notes] \n",
"\n",
"# extract durations to list\n",
"original_durs = [(n2.start - n1.start) for n1,n2 in zip(instrument.notes[:-1], instrument.notes[1:])]"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "IudNAzpBB7DL",
"colab_type": "text"
},
"source": [
"Print the pitches and durations lists."
]
},
{
"cell_type": "code",
"metadata": {
"id": "Bg1N7n0qBv68",
"colab_type": "code",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 54
},
"outputId": "67d5047c-84c1-4bda-a393-4cf88864a457"
},
"source": [
"print(original_pitches)"
],
"execution_count": 8,
"outputs": [
{
"output_type": "stream",
"text": [
"[61, 61, 61, 59, 57, 59, 57, 61, 57, 57, 59, 57, 61, 61, 61, 61, 61, 59, 57, 59, 57, 61, 59, 57, 56, 54, 54, 56, 54, 54, 56, 54, 54, 56, 54, 54, 57, 59, 57, 56, 54, 57, 56, 54, 57, 56, 54, 57, 56, 54, 61, 61, 61, 59, 57, 59, 57, 61, 57, 57, 59, 57, 61, 61, 61, 61, 61, 59, 57, 59, 57, 61, 59, 57, 56, 54, 54, 56, 54, 54, 56, 54, 54, 56, 54, 66, 64, 66, 64, 66, 69, 66, 69, 66, 66, 64, 66, 61, 66, 64, 66, 66, 66, 64, 66, 68, 66, 64, 66, 64, 66, 64, 66, 66, 66, 66, 69, 66, 66, 64, 66, 61, 66, 62, 62, 62, 62, 64, 66, 66, 65, 65, 65, 65, 66, 68, 66, 68, 66, 66, 64, 61, 61, 66, 66, 64, 61, 66, 66, 66, 64, 61, 61, 66, 69, 71, 69, 68, 66, 66, 66, 73, 71, 71, 66, 62, 61, 66, 69, 71, 69, 68, 66, 66, 66, 73, 71, 71, 66, 62, 61, 61, 61, 61, 59, 57, 59, 57, 61, 57, 57, 59, 57, 61, 61, 61, 61, 61, 59, 57, 59, 57, 61, 59, 57, 56, 54, 54, 56, 54, 54, 56, 54, 54, 56, 54, 54, 57, 59, 57, 56, 54, 57, 56, 54, 57, 56, 54, 57, 56, 54, 61, 61, 61, 59, 57, 59, 57, 61, 57, 57, 59, 57, 61, 61, 61, 61, 61, 59, 57, 59, 57, 61, 59, 57, 56, 54, 54, 56, 54, 54, 56, 54, 54, 56, 54, 66, 64, 66, 64, 66, 69, 66, 69, 66, 66, 64, 66, 61, 66, 64, 66, 66, 66, 64, 66, 68, 66, 64, 66, 64, 66, 64, 66, 66, 66, 66, 69, 66, 66, 64, 66, 61, 66, 62, 62, 62, 62, 64, 66, 66, 65, 65, 65, 65, 66, 68, 66, 68, 66, 66, 64, 61, 61, 66, 66, 64, 61, 66, 66, 66, 64, 61, 61, 66, 69, 71, 69, 68, 66, 66, 66, 73, 71, 71, 66, 62, 61, 66, 66, 64, 61, 61, 66, 66, 64, 61, 66, 66, 66, 64, 61, 61, 66, 69, 71, 69, 68, 66, 66, 66, 73, 71, 71, 66, 62, 61, 66, 69, 71, 69, 68, 66, 66, 66, 73, 71, 71, 66, 62, 61, 66, 69, 71, 69, 68, 66, 66, 66, 73, 71, 71, 66, 62, 61, 66, 66, 64, 61, 61, 66, 66, 64, 61, 66, 66, 66, 64, 61, 61, 66, 69, 71, 69, 68, 66, 66, 66, 73, 71, 71, 66, 62, 61, 66, 69, 71, 69, 68, 66, 66, 66, 73, 71, 71, 66, 62, 61, 66, 66, 64, 61, 61, 66, 66, 64, 61, 66, 66, 64, 61, 61, 66, 66, 64, 61, 66, 66, 64, 61, 61, 66, 66, 64, 61, 66, 66, 64, 61, 61, 66, 66, 64, 61, 66, 66, 64, 61, 61, 66, 66, 64, 61, 66, 66, 64, 61, 61, 66, 66, 64, 61, 66, 66, 64, 61, 61, 66, 66, 64, 61]\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "XtwY4GitBxs3",
"colab_type": "code",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 54
},
"outputId": "b1d49923-cf39-4d9a-a9b0-6708a24e2752"
},
"source": [
"print(original_durs)"
],
"execution_count": 9,
"outputs": [
{
"output_type": "stream",
"text": [
"[0.22395833333333215, 0.28125, 0.234375, 0.265625, 0.265625, 0.5, 0.2421875, 0.2552083333333357, 0.125, 0.1328125, 0.23177083333333215, 0.23958333333333215, 0.7552083333333357, 0.2473958333333286, 0.2395833333333357, 0.2786458333333357, 0.2421875, 0.2421875, 0.2578125, 0.2526041666666643, 0.234375, 0.5234375, 0.4947916666666643, 0.2630208333333357, 0.2630208333333357, 1.6979166666666643, 0.1354166666666643, 0.1197916666666714, 0.7421875, 0.1510416666666643, 0.1171875, 0.7395833333333357, 0.1380208333333286, 0.109375, 2.5, 0.2421875, 0.2604166666666714, 0.4947916666666643, 0.2421875, 0.2708333333333357, 1.7395833333333286, 0.1302083333333357, 0.140625, 0.7213541666666643, 0.1354166666666714, 0.1354166666666643, 0.7291666666666643, 0.1302083333333357, 0.1276041666666643, 4.7578125, 0.2239583333333357, 0.28125, 0.234375, 0.265625, 0.265625, 0.5, 0.2421875, 0.2552083333333357, 0.125, 0.1328125, 0.2317708333333286, 0.2395833333333357, 0.7552083333333357, 0.2473958333333286, 0.2395833333333357, 0.2786458333333357, 0.2421875, 0.2421875, 0.2578125, 0.2526041666666643, 0.234375, 0.5234375, 0.4947916666666643, 0.2630208333333357, 0.2630208333333357, 1.6979166666666643, 0.1354166666666643, 0.1197916666666714, 0.7552083333333286, 0.1380208333333357, 0.1197916666666643, 0.734375, 0.140625, 0.1171875, 4.236979166666671, 0.2447916666666572, 0.1197916666666714, 0.2604166666666714, 0.1380208333333286, 0.46875, 0.5234375, 0.2447916666666714, 0.2395833333333286, 0.1276041666666714, 0.2473958333333286, 0.1197916666666714, 1.0286458333333286, 0.1197916666666714, 0.1302083333333286, 0.1276041666666714, 0.11979166666665719, 0.5130208333333428, 0.1354166666666572, 0.1328125, 0.2734375, 0.46875, 1.9739583333333428, 0.2604166666666572, 0.2421875, 0.1328125, 0.2604166666666714, 0.1276041666666714, 0.2942708333333286, 0.6588541666666714, 0.11979166666665719, 0.1354166666666714, 0.2630208333333286, 0.1380208333333428, 0.2786458333333286, 0.1302083333333286, 0.9557291666666714, 0.1302083333333286, 0.1197916666666714, 0.2552083333333286, 0.1119791666666714, 0.1354166666666714, 0.125, 0.3984375, 0.7109375, 0.2604166666666572, 0.2604166666666714, 0.1223958333333286, 0.1328125, 0.1302083333333428, 0.3854166666666572, 0.4895833333333428, 0.2421875, 0.75, 0.2135416666666572, 0.2734375, 0.265625, 0.5026041666666714, 0.2604166666666714, 0.2421875, 0.46875, 0.5078125, 0.9947916666666572, 0.2604166666666714, 0.2552083333333286, 0.2708333333333428, 0.2369791666666572, 0.2421875, 0.4895833333333428, 0.2942708333333286, 0.4635416666666714, 0.5104166666666572, 0.2473958333333428, 0.2395833333333286, 1.4869791666666714, 0.5, 0.2604166666666572, 0.2526041666666714, 0.2838541666666714, 0.4791666666666572, 0.2682291666666714, 0.5026041666666714, 2.46875, 0.234375, 0.2708333333333286, 0.4817708333333286, 0.2552083333333428, 0.2682291666666572, 1.4895833333333428, 0.4921875, 0.2578125, 0.2473958333333286, 0.2630208333333286, 0.4921875, 0.2630208333333428, 0.5026041666666572, 4.736979166666671, 0.2239583333333286, 0.28125, 0.234375, 0.265625, 0.265625, 0.5, 0.2421875, 0.2552083333333428, 0.125, 0.1328125, 0.2317708333333286, 0.2395833333333286, 0.7552083333333428, 0.2473958333333286, 0.2395833333333286, 0.2786458333333428, 0.2421875, 0.2421875, 0.2578125, 0.2526041666666572, 0.234375, 0.5234375, 0.4947916666666714, 0.2630208333333286, 0.2630208333333428, 1.6979166666666572, 0.1354166666666714, 0.1197916666666714, 0.7421875, 0.1510416666666572, 0.1171875, 0.7395833333333428, 0.1380208333333286, 0.109375, 2.5, 0.2421875, 0.2604166666666714, 0.4947916666666572, 0.2421875, 0.2708333333333428, 1.7395833333333286, 0.1302083333333286, 0.140625, 0.7213541666666714, 0.1354166666666714, 0.1354166666666572, 0.7291666666666714, 0.1302083333333286, 0.1276041666666714, 4.757812499999986, 0.2239583333333428, 0.28125, 0.234375, 0.265625, 0.265625, 0.5, 0.2421875, 0.2552083333333428, 0.125, 0.1328125, 0.23177083333331439, 0.2395833333333428, 0.7552083333333428, 0.24739583333331439, 0.2395833333333428, 0.2786458333333428, 0.2421875, 0.2421875, 0.2578125, 0.2526041666666572, 0.234375, 0.5234375, 0.4947916666666572, 0.2630208333333428, 0.2630208333333428, 1.6979166666666572, 0.1354166666666572, 0.11979166666668561, 0.7552083333333144, 0.1380208333333428, 0.11979166666665719, 0.734375, 0.140625, 0.1171875, 4.236979166666686, 0.2447916666666572, 0.11979166666665719, 0.2604166666666856, 0.13802083333331439, 0.46875, 0.5234375, 0.24479166666668561, 0.23958333333331439, 0.12760416666668561, 0.24739583333331439, 0.11979166666668561, 1.0286458333333144, 0.11979166666668561, 0.13020833333331439, 0.12760416666668561, 0.11979166666665719, 0.5130208333333428, 0.1354166666666572, 0.1328125, 0.2734375, 0.46875, 1.9739583333333428, 0.2604166666666572, 0.2421875, 0.1328125, 0.2604166666666572, 0.12760416666668561, 0.2942708333333144, 0.6588541666666856, 0.11979166666665719, 0.1354166666666572, 0.2630208333333428, 0.1380208333333428, 0.2786458333333144, 0.1302083333333428, 0.9557291666666572, 0.1302083333333428, 0.11979166666665719, 0.2552083333333428, 0.11197916666665719, 0.13541666666668561, 0.125, 0.3984375, 0.7109375, 0.2604166666666572, 0.2604166666666572, 0.12239583333334281, 0.1328125, 0.1302083333333428, 0.3854166666666572, 0.4895833333333428, 0.2421875, 0.75, 0.2135416666666572, 0.2734375, 0.265625, 0.5026041666666572, 0.2604166666666856, 0.2421875, 0.46875, 0.5078125, 0.9947916666666572, 0.2604166666666572, 0.2552083333333428, 0.2708333333333428, 0.2369791666666572, 0.2421875, 0.4895833333333428, 0.2942708333333144, 0.4635416666666856, 0.5104166666666572, 0.2473958333333428, 0.23958333333331439, 1.4869791666666856, 0.5, 0.2604166666666572, 0.2526041666666572, 0.2838541666666856, 0.4791666666666572, 0.2682291666666572, 0.5026041666666856, 4.7265625, 0.2135416666666572, 0.2734375, 0.265625, 0.5026041666666572, 0.2604166666666856, 0.2421875, 0.46875, 0.5078125, 0.9947916666666572, 0.2604166666666572, 0.2552083333333428, 0.2708333333333428, 0.2369791666666572, 0.2421875, 0.4895833333333428, 0.2942708333333144, 0.4635416666666856, 0.5104166666666572, 0.2473958333333428, 0.23958333333331439, 1.4869791666666856, 0.5, 0.2604166666666572, 0.2526041666666572, 0.2838541666666856, 0.4791666666666572, 0.2682291666666572, 0.5026041666666856, 2.46875, 0.234375, 0.2708333333333144, 0.4817708333333428, 0.2552083333333428, 0.2682291666666572, 1.4895833333333428, 0.4921875, 0.2578125, 0.24739583333331439, 0.2630208333333428, 0.4921875, 0.2630208333333428, 0.5026041666666572, 18.481770833333343, 0.234375, 0.2708333333333144, 0.4817708333333428, 0.2552083333333428, 0.2682291666666572, 1.4895833333333428, 0.4921875, 0.2578125, 0.24739583333331439, 0.2630208333333428, 0.4921875, 0.2630208333333428, 0.5026041666666572, 4.739583333333343, 0.2135416666666572, 0.2734375, 0.265625, 0.5026041666666572, 0.2604166666666856, 0.2421875, 0.46875, 0.5078125, 0.9947916666666572, 0.2604166666666572, 0.2552083333333428, 0.2708333333333428, 0.2369791666666572, 0.2421875, 0.4895833333333428, 0.2942708333333144, 0.4635416666666856, 0.5104166666666572, 0.2473958333333428, 0.23958333333331439, 1.4869791666666856, 0.5, 0.2604166666666572, 0.2526041666666572, 0.2838541666666856, 0.4791666666666572, 0.2682291666666572, 0.5026041666666856, 2.46875, 0.234375, 0.2708333333333144, 0.4817708333333428, 0.2552083333333428, 0.2682291666666572, 1.4895833333333428, 0.4921875, 0.2578125, 0.24739583333331439, 0.2630208333333428, 0.4921875, 0.2630208333333428, 0.5026041666666572, 4.739583333333343, 0.2135416666666572, 0.2734375, 0.265625, 0.5026041666666572, 0.2604166666666856, 0.2421875, 0.46875, 0.5078125, 1.265625, 0.21354166666662877, 0.2734375, 0.265625, 0.5026041666666856, 0.2604166666666856, 0.2421875, 0.46875, 0.5078125, 1.265625, 0.21354166666662877, 0.2734375, 0.265625, 0.5026041666666856, 0.2604166666666856, 0.2421875, 0.46875, 0.5078125, 1.265625, 0.21354166666662877, 0.2734375, 0.265625, 0.5026041666666856, 0.2604166666666856, 0.2421875, 0.46875, 0.5078125, 1.265625, 0.21354166666662877, 0.2734375, 0.265625, 0.5026041666666856, 0.2604166666666856, 0.2421875, 0.46875, 0.5078125, 1.265625, 0.21354166666662877, 0.2734375, 0.265625, 0.5026041666666856, 0.2604166666666856, 0.2421875, 0.46875, 0.5078125, 1.265625, 0.21354166666662877, 0.2734375, 0.265625, 0.5026041666666856, 0.2604166666666856, 0.2421875, 0.46875, 0.5078125]\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "kSJ6bXQ0CA0Z",
"colab_type": "text"
},
"source": [
"And... play it. Just the first 30 notes or so, it's a long song."
]
},
{
"cell_type": "code",
"metadata": {
"id": "fqw43AFyCD1H",
"colab_type": "code",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 256
},
"outputId": "1a26f902-964b-4616-9174-233f6d640134"
},
"source": [
"# num notes\n",
"n = 35\n",
"\n",
"# plot\n",
"mai.make_music_plot(pitches=original_pitches[:n], durs=original_durs[:n])\n",
"\n",
"# play\n",
"mai.make_music(pitches=original_pitches[:n], durs=original_durs[:n], pgm=35)"
],
"execution_count": 10,
"outputs": [
{
"output_type": "display_data",
"data": {
"image/png": "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\n",
"text/plain": [
"