{
 "metadata": {
  "name": "",
  "signature": "sha256:c6f4357d56b3f588009579621acd75301f063ab2786515cdd06653d4054d3588"
 },
 "nbformat": 3,
 "nbformat_minor": 0,
 "worksheets": [
  {
   "cells": [
    {
     "cell_type": "heading",
     "level": 1,
     "metadata": {},
     "source": [
      "K-Nearest Neighbor"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "My first audio classifier: introducing K-NN!\n",
      "\n",
      "We can now appreciate why we need additional intelligence in our systems -- heuristics don't go very far in the world of complex audio signals.  We'll be using scikit-learn's implementation of the k-NN for our work here.  It proves be a straight-forward and easy to use implementation.  The steps and skills of working with one classifier will scale nicely to working with other, more complex classifiers."
     ]
    },
    {
     "cell_type": "heading",
     "level": 2,
     "metadata": {},
     "source": [
      "Training Data"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "from sklearn import preprocessing\n",
      "from sklearn.ensemble import AdaBoostClassifier\n",
      "from sklearn.linear_model import LogisticRegression\n",
      "from sklearn.naive_bayes import GaussianNB\n",
      "from sklearn.neighbors import KNeighborsClassifier\n",
      "from sklearn.svm import SVC\n",
      "import essentia\n",
      "import essentia.standard as ess\n",
      "import urllib\n",
      "import urllib2"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 93
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Read in a list of filenames of ten kick drums and ten snare drums:"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "kicks_URL = \"https://ccrma.stanford.edu/workshops/mir2014/KickCorpus.txt\"\n",
      "kick_file_list = [audio_file_URL.rstrip() for audio_file_URL in urllib2.urlopen(kicks_URL)]\n",
      "kick_file_list"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 94,
       "text": [
        "['https://ccrma.stanford.edu/workshops/mir2014/audio/drum%20samples/kicks/Bass_Drum_01_V01.WAV',\n",
        " 'https://ccrma.stanford.edu/workshops/mir2014/audio/drum%20samples/kicks/Bass_Drum_02_V01.WAV',\n",
        " 'https://ccrma.stanford.edu/workshops/mir2014/audio/drum%20samples/kicks/Bass_Drum_03_V01.WAV',\n",
        " 'https://ccrma.stanford.edu/workshops/mir2014/audio/drum%20samples/kicks/Bass_Drum_04_V01.WAV',\n",
        " 'https://ccrma.stanford.edu/workshops/mir2014/audio/drum%20samples/kicks/Bass_Drum_05_V01.WAV',\n",
        " 'https://ccrma.stanford.edu/workshops/mir2014/audio/drum%20samples/kicks/Bass_Drum_06_V01.WAV',\n",
        " 'https://ccrma.stanford.edu/workshops/mir2014/audio/drum%20samples/kicks/Bass_Drum_07_V01.WAV',\n",
        " 'https://ccrma.stanford.edu/workshops/mir2014/audio/drum%20samples/kicks/Bass_Drum_08_V01.WAV',\n",
        " 'https://ccrma.stanford.edu/workshops/mir2014/audio/drum%20samples/kicks/Bass_Drum_09_V01.WAV',\n",
        " 'https://ccrma.stanford.edu/workshops/mir2014/audio/drum%20samples/kicks/Bass_Drum_10_V01.WAV']"
       ]
      }
     ],
     "prompt_number": 94
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "snares_URL = \"https://ccrma.stanford.edu/workshops/mir2014/SnareCorpus.txt\"\n",
      "snare_file_list = [audio_file_URL.rstrip() for audio_file_URL in urllib2.urlopen(snares_URL)]\n",
      "snare_file_list"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 95,
       "text": [
        "['https://ccrma.stanford.edu/workshops/mir2014/audio/drum%20samples/snares/SNARE_01_01.WAV',\n",
        " 'https://ccrma.stanford.edu/workshops/mir2014/audio/drum%20samples/snares/SNARE_02_01.WAV',\n",
        " 'https://ccrma.stanford.edu/workshops/mir2014/audio/drum%20samples/snares/SNARE_04_01.WAV',\n",
        " 'https://ccrma.stanford.edu/workshops/mir2014/audio/drum%20samples/snares/SNARE_05_01.WAV',\n",
        " 'https://ccrma.stanford.edu/workshops/mir2014/audio/drum%20samples/snares/SNARE_06_01.WAV',\n",
        " 'https://ccrma.stanford.edu/workshops/mir2014/audio/drum%20samples/snares/SNARE_07_01.WAV',\n",
        " 'https://ccrma.stanford.edu/workshops/mir2014/audio/drum%20samples/snares/SNARE_08_01.WAV',\n",
        " 'https://ccrma.stanford.edu/workshops/mir2014/audio/drum%20samples/snares/SNARE_09_01.WAV',\n",
        " 'https://ccrma.stanford.edu/workshops/mir2014/audio/drum%20samples/snares/SNARE_10_01.WAV',\n",
        " 'https://ccrma.stanford.edu/workshops/mir2014/audio/drum%20samples/snares/snare_mono.wav']"
       ]
      }
     ],
     "prompt_number": 95
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "To access the filenames contained in the array, use the square brackets [ ] to get to the element that you want to access:"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "snare_file_list[0]"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 96,
       "text": [
        "'https://ccrma.stanford.edu/workshops/mir2014/audio/drum%20samples/snares/SNARE_01_01.WAV'"
       ]
      }
     ],
     "prompt_number": 96
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "When we feature extract a sample collection, we need to sequentially access audio files, segment them (or not), and feature extract them.  Loading a lot of audio files into memory is not always a feasible or desirable operation, so you will create a loop which loads an audio file, feature extracts it, and closes  the audio file.  Note that the only information that we retain in memory are the features that are extracted.\n",
      "\n",
      "Create a function that reads an audio file from a remote URL and outputs a feature vector."
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "zcr = ess.ZeroCrossingRate()\n",
      "centroid = ess.Centroid()\n",
      "spectrum = ess.Spectrum()\n",
      "centralmoments = ess.CentralMoments()\n",
      "distributionshape = ess.DistributionShape()\n",
      "hamming_window = ess.Windowing(type='hamming')\n",
      "\n",
      "def extract_features_from_audio(frame):\n",
      "    spectral_magnitude = spectrum(hamming_window(frame))\n",
      "    spectral_moments = distributionshape(centralmoments(spectral_magnitude))\n",
      "    feature_vector = [zcr(frame), centroid(spectral_magnitude)]\n",
      "    feature_vector.extend( spectral_moments )\n",
      "    return feature_vector\n",
      "\n",
      "def extract_features(url, fs=44100, frame_sz=0.200):\n",
      "    urllib.urlretrieve(url, filename='temp.wav')\n",
      "    try:\n",
      "        audio = ess.MonoLoader(filename='temp.wav', sampleRate=fs)() \n",
      "        frame = audio[:int(frame_sz*fs)]\n",
      "        return extract_features_from_audio(frame)\n",
      "    except RuntimeError:\n",
      "        print 'error:', url\n",
      "        return None"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 97
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Use this function to compute one feature vector for each of the training audio files:"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "feature_table = array([extract_features(url) for url in kick_file_list + snare_file_list])\n",
      "print feature_table.min(axis=0)\n",
      "print feature_table.max(axis=0)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "[ 0.00408163  0.01719355  0.00287186  0.55032426 -0.47705555]\n",
        "[  1.62471652e-01   2.71532953e-01   4.44976576e-02   7.22230673e+00\n",
        "   7.60733871e+01]\n"
       ]
      }
     ],
     "prompt_number": 98
    },
    {
     "cell_type": "heading",
     "level": 2,
     "metadata": {},
     "source": [
      "Feature Scaling"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Since the features are different scales, we will want to normalize each feature vector to a common range - storing the scaling coefficients for later use.  Many techniques exist for scaling your features.  We'll use linear scaling, which forces the features into the range -1 to 1.\n",
      "\n",
      "For this, we'll use a scikit.learn class called [MinMaxScaler](http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.MinMaxScaler.html).  MinMaxScaler fits and transforms, returning an array of scaled values, and retains coefficients which were used to scale each column into -1 to 1."
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "scaler = preprocessing.MinMaxScaler(feature_range=(-1, 1))\n",
      "training_features = scaler.fit_transform(feature_table)\n",
      "print training_features.min(axis=0)\n",
      "print training_features.max(axis=0)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "[-1. -1. -1. -1. -1.]\n",
        "[ 1.  1.  1.  1.  1.]\n"
       ]
      }
     ],
     "prompt_number": 99
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Finally, create the associated labels for the training files, where 0 denotes a kick drum, and 1 denotes a snare drum:"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "training_labels = concatenate([zeros(10), ones(10)])"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 100
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Plot the training features:"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "scatter(training_features[:10,0], training_features[:10,1], c='b')\n",
      "scatter(training_features[10:,0], training_features[10:,1], c='r')\n",
      "xlabel('Zero Crossing Rate')\n",
      "ylabel('Spectral Centroid')"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 101,
       "text": [
        "<matplotlib.text.Text at 0x10e6b41d0>"
       ]
      },
      {
       "metadata": {},
       "output_type": "display_data",
       "png": "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\n",
       "text": [
        "<matplotlib.figure.Figure at 0x1067c9450>"
       ]
      }
     ],
     "prompt_number": 101
    },
    {
     "cell_type": "heading",
     "level": 2,
     "metadata": {},
     "source": [
      "Building the K-NN Model"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Build a k-NN model for the snare drums using scikit.learn's [KNeighborsClassifier](http://scikit-learn.org/stable/modules/generated/sklearn.neighbors.KNeighborsClassifier.html) class."
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "#model = KNeighborsClassifier(n_neighbors=1)\n",
      "#model = SVC()\n",
      "#model = LogisticRegression()\n",
      "#model = GaussianNB()\n",
      "model = AdaBoostClassifier()\n",
      "model.fit(training_features, training_labels)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 102,
       "text": [
        "AdaBoostClassifier(algorithm='SAMME.R',\n",
        "          base_estimator=DecisionTreeClassifier(compute_importances=None, criterion='gini',\n",
        "            max_depth=1, max_features=None, min_density=None,\n",
        "            min_samples_leaf=1, min_samples_split=2, random_state=None,\n",
        "            splitter='best'),\n",
        "          learning_rate=1.0, n_estimators=50, random_state=None)"
       ]
      }
     ],
     "prompt_number": 102
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Try it out:"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "model.predict(training_features[0])"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 103,
       "text": [
        "array([ 0.])"
       ]
      }
     ],
     "prompt_number": 103
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Evaluate the model on the training data:"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "model.score(training_features, training_labels)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 104,
       "text": [
        "1.0"
       ]
      }
     ],
     "prompt_number": 104
    },
    {
     "cell_type": "heading",
     "level": 2,
     "metadata": {},
     "source": [
      "Testing"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Now, test the classifier with these test examples:\n",
      "\n",
      "-   https://ccrma.stanford.edu/workshops/mir2014/TestKicksCorpus.txt\n",
      "-   https://ccrma.stanford.edu/workshops/mir2014/TestSnaresCorpus.txt"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "test_URL = \"https://ccrma.stanford.edu/workshops/mir2014/TestKicksCorpus.txt\"\n",
      "test_URL = \"https://ccrma.stanford.edu/workshops/mir2014/TestSnaresCorpus.txt\"\n",
      "test_file_list = [audio_file_URL.replace('#', '%23').rstrip() for audio_file_URL in urllib2.urlopen(test_URL)]"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 105
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "test_features = [extract_features(url) for url in test_file_list if extract_features(url) is not None]"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "error: https://ccrma.stanford.edu/workshops/mir2014/audio/drum%20samples/test%20snares/15%20Mid%20Rim.wav\n",
        "error:"
       ]
      },
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        " https://ccrma.stanford.edu/workshops/mir2014/audio/drum%20samples/test%20snares/16%20Tone%20syn.wav\n",
        "error:"
       ]
      },
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        " https://ccrma.stanford.edu/workshops/mir2014/audio/drum%20samples/test%20snares/17%20Tiny.wav\n",
        "error:"
       ]
      },
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        " https://ccrma.stanford.edu/workshops/mir2014/audio/drum%20samples/test%20snares/18%20Shortest.wav\n"
       ]
      }
     ],
     "prompt_number": 106
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "test_features = scaler.transform(test_features)\n",
      "print test_features.min(axis=0)\n",
      "print test_features.max(axis=0)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "[-0.4158912  -0.10375141 -0.46853682 -1.04463977 -0.99018434]\n",
        "[ 1.1159628   1.48739906  1.60301345 -0.50959573 -0.77698699]\n"
       ]
      }
     ],
     "prompt_number": 107
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Evaluate:"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "test_labels = ones(len(test_features))\n",
      "model.score(test_features, test_labels)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 108,
       "text": [
        "0.92592592592592593"
       ]
      }
     ],
     "prompt_number": 108
    },
    {
     "cell_type": "heading",
     "level": 1,
     "metadata": {},
     "source": [
      "Exercise: Instrument Classification using K-NN"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "This exercise is loosely based upon \"Lab 1\" from previous MIR workshops ([2010](https://ccrma.stanford.edu/workshops/mir2010/Lab1_2010.pdf))."
     ]
    },
    {
     "cell_type": "heading",
     "level": 2,
     "metadata": {},
     "source": [
      "Goals"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "1. Extract spectral features from an audio signal.\n",
      "2. Train a K-Nearest Neighbor classifier.\n",
      "3. Use the classifier to classify beats in a drum loop."
     ]
    },
    {
     "cell_type": "heading",
     "level": 2,
     "metadata": {},
     "source": [
      "Step 1: Retrieve Audio, Detect Onsets, and Segment"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "[Follow the same steps here.](feature_sonification.ipynb#Step-1:-Retrieve-Audio)\n",
      "\n",
      "1. Download the file `simpleLoop.wav` onto your local machine.\n",
      "1. Save the audio signal into an array.\n",
      "1. Find the times, in seconds, when onsets occur in the audio signal.\n",
      "1. Save into an array, `segments`, 100-ms segments beginning at each onset."
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "import urllib\n",
      "url = 'https://ccrma.stanford.edu/workshops/mir2014/audio/simpleLoop.wav'\n",
      "url = 'https://ccrma.stanford.edu/workshops/mir2014/audio/125BOUNC-mono.WAV'\n",
      "urllib.urlretrieve(url, filename='test.wav')"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 109,
       "text": [
        "('test.wav', <httplib.HTTPMessage instance at 0x10cd30fc8>)"
       ]
      }
     ],
     "prompt_number": 109
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "fs = 44100\n",
      "loader = ess.MonoLoader(filename='../test/beatbox.wav')\n",
      "audio = loader()"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 110
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "from IPython.display import Audio\n",
      "Audio(data=audio, rate=fs)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "html": [
        "\n",
        "                <audio controls=\"controls\" >\n",
        "                    <source src=\"data:audio/wav;base64,[encoded data, 772840 characters]\" type=\"audio/wav\" />\n",
        "                    Your browser does not support the audio element.\n",
        "                </audio>\n",
        "              "
       ],
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 111,
       "text": [
        "<IPython.lib.display.Audio at 0x10e6d38d0>"
       ]
      }
     ],
     "prompt_number": 111
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "get_onsets = ess.OnsetRate()\n",
      "onset_times, onset_rate = get_onsets(audio)\n",
      "print onset_times"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "[ 0.98684806  1.8575964   2.65868473  3.44816327  3.64553285  4.22603178\n",
        "  4.99229002]\n"
       ]
      }
     ],
     "prompt_number": 112
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "onset_samples = [int(fs*i) for i in onset_times]\n",
      "print onset_samples"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "[43519, 81920, 117247, 152064, 160767, 186368, 220159]\n"
       ]
      }
     ],
     "prompt_number": 113
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "onsets_marker = ess.AudioOnsetsMarker(onsets=onset_times, type='beep')\n",
      "with_beeps = onsets_marker(audio)\n",
      "Audio(data=with_beeps, rate=fs)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "html": [
        "\n",
        "                <audio controls=\"controls\" >\n",
        "                    <source src=\"data:audio/wav;base64,[encoded data, 772840 characters]\" type=\"audio/wav\" />\n",
        "                    Your browser does not support the audio element.\n",
        "                </audio>\n",
        "              "
       ],
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 114,
       "text": [
        "<IPython.lib.display.Audio at 0x10cd3bc90>"
       ]
      }
     ],
     "prompt_number": 114
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "frame_sz = int(0.200*fs)\n",
      "segments = array([audio[i:i+frame_sz] for i in onset_samples])"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 115
    },
    {
     "cell_type": "heading",
     "level": 2,
     "metadata": {},
     "source": [
      "Step 2: Extract Features"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "For each segment, compute the same features as above: zero crossing rate and spectral moments."
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "feature_table = [extract_features_from_audio(segment) for segment in segments]\n",
      "test_features = scaler.transform(feature_table)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 116
    },
    {
     "cell_type": "heading",
     "level": 2,
     "metadata": {},
     "source": [
      "Step 3: Train K-NN Classifier"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "For training, see [Training Data](#Training-Data) below.\n",
      "\n",
      "For more on K-NN, see the [notebook on K-NN](../notebooks/knn.ipynb)."
     ]
    },
    {
     "cell_type": "heading",
     "level": 2,
     "metadata": {},
     "source": [
      "Step 4: Run the Classifier"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "test_labels = model.predict(test_features)\n",
      "test_labels"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 117,
       "text": [
        "array([ 1.,  1.,  1.,  1.,  1.,  1.,  1.])"
       ]
      }
     ],
     "prompt_number": 117
    },
    {
     "cell_type": "heading",
     "level": 2,
     "metadata": {},
     "source": [
      "Step 5: Sonify the Classifier Output"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Play a \"beep\" for each detected kick drum."
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "onsets_marker = ess.AudioOnsetsMarker(onsets=onset_times[test_labels==0], type='beep')\n",
      "with_beeps = onsets_marker(audio)\n",
      "Audio(data=with_beeps, rate=fs)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "html": [
        "\n",
        "                <audio controls=\"controls\" >\n",
        "                    <source src=\"data:audio/wav;base64,[encoded data, 772840 characters]\" type=\"audio/wav\" />\n",
        "                    Your browser does not support the audio element.\n",
        "                </audio>\n",
        "              "
       ],
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 118,
       "text": [
        "<IPython.lib.display.Audio at 0x10cd3b2d0>"
       ]
      }
     ],
     "prompt_number": 118
    },
    {
     "cell_type": "heading",
     "level": 2,
     "metadata": {},
     "source": [
      "Bonus"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "In addition to the MFCCs, extract the following features:\n",
      "\n",
      "- spectral centroid\n",
      "- spectral spread\n",
      "- spectral skewness\n",
      "- spectral kurtosis. "
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "from essentia.standard import CentralMoments, DistributionShape\n",
      "DistributionShape?"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 119
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Re-train the classifier, and re-run the classifier over the test audio signal. Do the results change?"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Repeat the steps above for the following audio files:"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "url = 'https://ccrma.stanford.edu/workshops/mir2014/audio/CongaGroove-mono.wav'\n",
      "url = 'https://ccrma.stanford.edu/workshops/mir2014/audio/125BOUNC-mono.WAV'"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 120
    }
   ],
   "metadata": {}
  }
 ]
}