{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Digital Musicology Tutorium Week 4: MIDI Data Explorations" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [], "source": [ "# import packages\n", "using DigitalMusicology\n", "using DataFrames\n", "using Plots" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 1) Convert Frequencies to Pitches and vice verca" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "pitch_to_frequency (generic function with 1 method)" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# A4 is set to 440Hz\n", "frequency_to_pitch(f) = 69 + 12 * log2(f / 440)\n", "\n", "pitch_to_frequency(p) = 2^((p - 69) / 12) * 440" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "261.6255653005986" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# the frequency of C4\n", "pitch_to_frequency(60)" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(8.175798915643707, 12543.853951415975)" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# the lowest midi note has a frequency of about 8Hz,\n", "# the highest about 13kHz\n", "# humans typically hear between 20Hz and 20kHz\n", "pitch_to_frequency(0), pitch_to_frequency(127)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2) Example of this Weeks Tutorial: Iron Maiden *Run to the hills*\n", "[song on youtube](https://www.youtube.com/watch?v=3ZlDZPYzfm4)\n", "\n", "[find midi file here](http://www.maidenmidi.com/number.html)\n", "\n", "The midi file can also be read by Garageband and MuseScore!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 3) Read MIDI File as a DataFrame\n", "- A MIDI file is essentially a list of **MIDI events / MIDI commands**\n", "- There are of are **note-on**, **note-off**, and **meta events** grouped by **channels** (repesenting voices) that are grouped by **tracks** (representing instruments)\n", "- For note events, **pitch** and **velocity** are specified\n", "- Meta events e.g. specify the key of a piece or indicate tempo changes\n", "- To work with a MIDI file, we convert it into a list of notes" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
onset_ticksoffset_ticksonset_wholesoffset_wholesonset_secsoffset_secspitchvelocitytrackchannelkey_sharpskey_major
10460//123//3840.00.1056984166666666742110790true
201600//15//240.00.367646666666666736110790true
348941//1647//3840.1102940.215992416666666742110790true
4961421//871//3840.2205880.326286416666666742110790true
51441903//1695//3840.3308820.436580416666666742110790true
61922381//4119//3840.4411760.546874416666666742110790true
" ], "text/plain": [ "6×12 DataFrames.DataFrame\n", "│ Row │ onset_ticks │ offset_ticks │ onset_wholes │ offset_wholes │ onset_secs │\n", "├─────┼─────────────┼──────────────┼──────────────┼───────────────┼────────────┤\n", "│ 1 │ 0 │ 46 │ 0//1 │ 23//384 │ 0.0 │\n", "│ 2 │ 0 │ 160 │ 0//1 │ 5//24 │ 0.0 │\n", "│ 3 │ 48 │ 94 │ 1//16 │ 47//384 │ 0.110294 │\n", "│ 4 │ 96 │ 142 │ 1//8 │ 71//384 │ 0.220588 │\n", "│ 5 │ 144 │ 190 │ 3//16 │ 95//384 │ 0.330882 │\n", "│ 6 │ 192 │ 238 │ 1//4 │ 119//384 │ 0.441176 │\n", "\n", "│ Row │ offset_secs │ pitch │ velocity │ track │ channel │ key_sharps │\n", "├─────┼─────────────┼───────┼──────────┼───────┼─────────┼────────────┤\n", "│ 1 │ 0.105698 │ 42 │ 110 │ 7 │ 9 │ 0 │\n", "│ 2 │ 0.367647 │ 36 │ 110 │ 7 │ 9 │ 0 │\n", "│ 3 │ 0.215992 │ 42 │ 110 │ 7 │ 9 │ 0 │\n", "│ 4 │ 0.326286 │ 42 │ 110 │ 7 │ 9 │ 0 │\n", "│ 5 │ 0.43658 │ 42 │ 110 │ 7 │ 9 │ 0 │\n", "│ 6 │ 0.546874 │ 42 │ 110 │ 7 │ 9 │ 0 │\n", "\n", "│ Row │ key_major │\n", "├─────┼───────────┤\n", "│ 1 │ true │\n", "│ 2 │ true │\n", "│ 3 │ true │\n", "│ 4 │ true │\n", "│ 5 │ true │\n", "│ 6 │ true │" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "notes = midifilenotes(\"Run_To_The_Hills.mid\")\n", "head(notes)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- `key_sharps` and `key_major` have default values\n", "- Be careful if you see the default setting `(0,true)` like here!" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1-element DataArrays.DataArray{Int64,1}:\n", " 0" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "notes[:key_sharps] |> unique" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "search: \u001b[1mm\u001b[22m\u001b[1mi\u001b[22m\u001b[1md\u001b[22m\u001b[1mi\u001b[22m\u001b[1mf\u001b[22m\u001b[1mi\u001b[22m\u001b[1ml\u001b[22m\u001b[1me\u001b[22m\u001b[1mn\u001b[22m\u001b[1mo\u001b[22m\u001b[1mt\u001b[22m\u001b[1me\u001b[22m\u001b[1ms\u001b[22m\n", "\n" ] }, { "data": { "text/markdown": [ "```\n", "midifilenotes(file; warnings=false, overlaps=:queue, orphans=:skip)\n", "```\n", "\n", "Reads a midi file and returns a `DataFrame` with one row per note. On- and offset times are given in ticks, whole notes, and seconds. The data frame has the following columns:\n", "\n", " * onset_ticks (Int)\n", " * offset_ticks (Int)\n", " * onset_wholes (Rational{Int})\n", " * offset_wholes (Rational{Int})\n", " * onset_secs (Rational{Int})\n", " * offset_secs (Rational{Int})\n", " * pitch (MidiPitch)\n", " * velocity (Int)\n", " * channel (Int)\n", " * track (Int)\n", " * key_sharps (Int)\n", " * key_major (Bool)\n", "\n", "If `warnings` is `true`, warnings about encoding errors will be displayed. If two notes overlap on the same channel and track (e.g. two ons, then two offs for the same pitch) `overlaps` provides the strategy for interpreting the sequence of on and off events:\n", "\n", " * `:queue` matches ons and offs in a FIFO manner (first on to first off).\n", " * `:stack` matches ons and offs in a LIFO manner (first on to last off).\n", "\n", "`orphans` determines what happens to on and off events without counterpart. Currently, its value is ignored and orphan events are always skipped.\n" ], "text/plain": [ "```\n", "midifilenotes(file; warnings=false, overlaps=:queue, orphans=:skip)\n", "```\n", "\n", "Reads a midi file and returns a `DataFrame` with one row per note. On- and offset times are given in ticks, whole notes, and seconds. The data frame has the following columns:\n", "\n", " * onset_ticks (Int)\n", " * offset_ticks (Int)\n", " * onset_wholes (Rational{Int})\n", " * offset_wholes (Rational{Int})\n", " * onset_secs (Rational{Int})\n", " * offset_secs (Rational{Int})\n", " * pitch (MidiPitch)\n", " * velocity (Int)\n", " * channel (Int)\n", " * track (Int)\n", " * key_sharps (Int)\n", " * key_major (Bool)\n", "\n", "If `warnings` is `true`, warnings about encoding errors will be displayed. If two notes overlap on the same channel and track (e.g. two ons, then two offs for the same pitch) `overlaps` provides the strategy for interpreting the sequence of on and off events:\n", "\n", " * `:queue` matches ons and offs in a FIFO manner (first on to first off).\n", " * `:stack` matches ons and offs in a LIFO manner (first on to last off).\n", "\n", "`orphans` determines what happens to on and off events without counterpart. Currently, its value is ignored and orphan events are always skipped.\n" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "?midifilenotes" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "6-element DataArrays.DataArray{Int64,1}:\n", " 2\n", " 3\n", " 4\n", " 5\n", " 6\n", " 7" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# this is a small pipeline\n", "notes[:track] |> unique |> sort" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "6-element DataArrays.DataArray{Int64,1}:\n", " 2\n", " 3\n", " 4\n", " 5\n", " 6\n", " 7" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# it is equivalent to\n", "sort(unique(notes[:track]))" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "7-element Array{String,1}:\n", " \"meta\" \n", " \"vocals\" \n", " \"vocal harmony\"\n", " \"guitar 1\" \n", " \"guitar 2\" \n", " \"bass\" \n", " \"drums\" " ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "track_names = [\"meta\", \"vocals\", \"vocal harmony\", \"guitar 1\", \"guitar 2\", \"bass\", \"drums\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Track 1 is reserved for meta events!\n", "- The other tracks are for vocals, vocal harmony, guitar 1, guitar 2, bass, drums\n", "- one row in the data frame represents one note\n", "- the columns are the features that we know about the notes\n", "\n", "## 4) A look at the first bar" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
onset_wholesonset_ticks
10//10
20//10
31//1648
41//896
53//16144
61//4192
71//4192
85//16240
93//8288
107//16336
111//2384
121//2384
139//16432
145//8480
1511//16528
163//4576
173//4576
187//8672
191//1768
201//1768
" ], "text/plain": [ "20×2 DataFrames.DataFrame\n", "│ Row │ onset_wholes │ onset_ticks │\n", "├─────┼──────────────┼─────────────┤\n", "│ 1 │ 0//1 │ 0 │\n", "│ 2 │ 0//1 │ 0 │\n", "│ 3 │ 1//16 │ 48 │\n", "│ 4 │ 1//8 │ 96 │\n", "│ 5 │ 3//16 │ 144 │\n", "│ 6 │ 1//4 │ 192 │\n", "│ 7 │ 1//4 │ 192 │\n", "│ 8 │ 5//16 │ 240 │\n", "│ 9 │ 3//8 │ 288 │\n", "│ 10 │ 7//16 │ 336 │\n", "│ 11 │ 1//2 │ 384 │\n", "│ 12 │ 1//2 │ 384 │\n", "│ 13 │ 9//16 │ 432 │\n", "│ 14 │ 5//8 │ 480 │\n", "│ 15 │ 11//16 │ 528 │\n", "│ 16 │ 3//4 │ 576 │\n", "│ 17 │ 3//4 │ 576 │\n", "│ 18 │ 7//8 │ 672 │\n", "│ 19 │ 1//1 │ 768 │\n", "│ 20 │ 1//1 │ 768 │" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# drums in first bar\n", "# there are 192 ticks per quarter note\n", "notes[1:20, [:onset_wholes, :onset_ticks]]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 5) Exploratory Analysis\n", "1. Pitch histogram\n", "1. Pitch class histogram\n", "1. Pitch class histogram per instrument\n", "1. Note duration histogram per instrument\n", "1. Beat histogram (onsets per beat) per instrument" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 5.1) Plot a pitch histogram" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
onset_ticksoffset_ticksonset_wholesoffset_wholesonset_secsoffset_secspitchvelocitytrackchannelkey_sharpskey_major
12976321431//81607//3846.8382287.38510241666666786110420true
22976307031//81535//3846.8382287.05422041666666662110530true
32976307031//81535//3846.8382287.05422041666666669110530true
42976307031//81535//3846.8382287.05422041666666674110530true
52976307031//81535//3846.8382287.05422041666666638110640true
6307232144//11607//3847.0588167.38510241666666764110530true
" ], "text/plain": [ "6×12 DataFrames.DataFrame\n", "│ Row │ onset_ticks │ offset_ticks │ onset_wholes │ offset_wholes │ onset_secs │\n", "├─────┼─────────────┼──────────────┼──────────────┼───────────────┼────────────┤\n", "│ 1 │ 2976 │ 3214 │ 31//8 │ 1607//384 │ 6.83823 │\n", "│ 2 │ 2976 │ 3070 │ 31//8 │ 1535//384 │ 6.83823 │\n", "│ 3 │ 2976 │ 3070 │ 31//8 │ 1535//384 │ 6.83823 │\n", "│ 4 │ 2976 │ 3070 │ 31//8 │ 1535//384 │ 6.83823 │\n", "│ 5 │ 2976 │ 3070 │ 31//8 │ 1535//384 │ 6.83823 │\n", "│ 6 │ 3072 │ 3214 │ 4//1 │ 1607//384 │ 7.05882 │\n", "\n", "│ Row │ offset_secs │ pitch │ velocity │ track │ channel │ key_sharps │\n", "├─────┼─────────────┼───────┼──────────┼───────┼─────────┼────────────┤\n", "│ 1 │ 7.3851 │ 86 │ 110 │ 4 │ 2 │ 0 │\n", "│ 2 │ 7.05422 │ 62 │ 110 │ 5 │ 3 │ 0 │\n", "│ 3 │ 7.05422 │ 69 │ 110 │ 5 │ 3 │ 0 │\n", "│ 4 │ 7.05422 │ 74 │ 110 │ 5 │ 3 │ 0 │\n", "│ 5 │ 7.05422 │ 38 │ 110 │ 6 │ 4 │ 0 │\n", "│ 6 │ 7.3851 │ 64 │ 110 │ 5 │ 3 │ 0 │\n", "\n", "│ Row │ key_major │\n", "├─────┼───────────┤\n", "│ 1 │ true │\n", "│ 2 │ true │\n", "│ 3 │ true │\n", "│ 4 │ true │\n", "│ 5 │ true │\n", "│ 6 │ true │" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# select the the instruments other than the drums\n", "not_percussive_notes = notes[notes[:track] .!= 7, :]\n", "head(not_percussive_notes)" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "10-element Array{Int64,1}:\n", " 86\n", " 62\n", " 69\n", " 74\n", " 38\n", " 64\n", " 71\n", " 76\n", " 40\n", " 86" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# convert midi notes to pitch numbers\n", "pitches = [note.pitch for note in not_percussive_notes[:pitch]]\n", "pitches[1:10]" ] }, { "cell_type": "code", "execution_count": 36, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "0\n", "\n", "\n", "20\n", "\n", "\n", "40\n", "\n", "\n", "60\n", "\n", "\n", "80\n", "\n", "\n", "100\n", "\n", "\n", "120\n", "\n", "\n", "0\n", "\n", "\n", "100\n", "\n", "\n", "200\n", "\n", "\n", "300\n", "\n", "\n", "400\n", "\n", "\n", "500\n", "\n", "\n", "600\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "y1\n", "\n", "\n" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# plot pitch histogram\n", "histogram(pitches, bins=collect(0:127))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 5.2) Plot a pitch class histogram" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "0\n", "\n", "\n", "1\n", "\n", "\n", "2\n", "\n", "\n", "3\n", "\n", "\n", "4\n", "\n", "\n", "5\n", "\n", "\n", "6\n", "\n", "\n", "7\n", "\n", "\n", "8\n", "\n", "\n", "9\n", "\n", "\n", "10\n", "\n", "\n", "11\n", "\n", "\n", "0\n", "\n", "\n", "250\n", "\n", "\n", "500\n", "\n", "\n", "750\n", "\n", "\n", "1000\n", "\n", "\n", "1250\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "y1\n", "\n", "\n" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# plot pitch class histogram\n", "pitch_classes = [mod(p, 12) for p in pitches]\n", "xticks = (collect(0:11) .+ 0.5, collect(0:11))\n", "histogram(pitch_classes, bins=12, xticks=xticks)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Looks like a C major scale!" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "7\n", "\n", "\n", "8\n", "\n", "\n", "9\n", "\n", "\n", "10\n", "\n", "\n", "11\n", "\n", "\n", "0\n", "\n", "\n", "1\n", "\n", "\n", "2\n", "\n", "\n", "3\n", "\n", "\n", "4\n", "\n", "\n", "5\n", "\n", "\n", "6\n", "\n", "\n", "0\n", "\n", "\n", "250\n", "\n", "\n", "500\n", "\n", "\n", "750\n", "\n", "\n", "1000\n", "\n", "\n", "1250\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "y1\n", "\n", "\n" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# shift the histogram so that the most prominent note is in front\n", "shifted_xticks = (collect(0:11) .+ 0.5, [mod(pc+7, 12) for pc in 0:11])\n", "histogram(\n", " [mod(pc-7, 12) for pc in pitch_classes], \n", " bins=12, \n", " xticks=shifted_xticks\n", ")" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "0\n", "\n", "\n", "1\n", "\n", "\n", "2\n", "\n", "\n", "3\n", "\n", "\n", "4\n", "\n", "\n", "5\n", "\n", "\n", "6\n", "\n", "\n", "7\n", "\n", "\n", "8\n", "\n", "\n", "9\n", "\n", "\n", "10\n", "\n", "\n", "11\n", "\n", "\n", "0\n", "\n", "\n", "250\n", "\n", "\n", "500\n", "\n", "\n", "750\n", "\n", "\n", "1000\n", "\n", "\n", "1250\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "y1\n", "\n", "\n" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "transform(p) = mod((p+4)*7, 12)\n", "histogram(\n", " transform.(pitch_classes), \n", " bins = 12, \n", " xticks = (transform.(collect(0:11)) .+ 0.5, (collect(0:11))), \n", " xlim = (0,12)\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 5.3) Plot a Pitch Class Histogram per Instrument" ] }, { "cell_type": "code", "execution_count": 40, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "0\n", "\n", "\n", "1\n", "\n", "\n", "2\n", "\n", "\n", "3\n", "\n", "\n", "4\n", "\n", "\n", "5\n", "\n", "\n", "6\n", "\n", "\n", "7\n", "\n", "\n", "8\n", "\n", "\n", "9\n", "\n", "\n", "10\n", "\n", "\n", "11\n", "\n", "\n", "0\n", "\n", "\n", "10\n", "\n", "\n", "20\n", "\n", "\n", "30\n", "\n", "\n", "40\n", "\n", "\n", "50\n", "\n", "\n", "vocals\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "y1\n", "\n", "\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "0\n", "\n", "\n", "1\n", "\n", "\n", "2\n", "\n", "\n", "3\n", "\n", "\n", "4\n", "\n", "\n", "5\n", "\n", "\n", "6\n", "\n", "\n", "7\n", "\n", "\n", "8\n", "\n", "\n", "9\n", "\n", "\n", "10\n", "\n", "\n", "11\n", "\n", "\n", "0\n", "\n", "\n", "5\n", "\n", "\n", "10\n", "\n", "\n", "15\n", "\n", "\n", "20\n", "\n", "\n", "25\n", "\n", "\n", "30\n", "\n", "\n", "35\n", "\n", "\n", "vocal harmony\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "y1\n", "\n", "\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "0\n", "\n", "\n", "1\n", "\n", "\n", "2\n", "\n", "\n", "3\n", "\n", "\n", "4\n", "\n", "\n", "5\n", "\n", "\n", "6\n", "\n", "\n", "7\n", "\n", "\n", "8\n", "\n", "\n", "9\n", "\n", "\n", "10\n", "\n", "\n", "11\n", "\n", "\n", "0\n", "\n", "\n", "100\n", "\n", "\n", "200\n", "\n", "\n", "300\n", "\n", "\n", "400\n", "\n", "\n", "guitar 1\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "y1\n", "\n", "\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "0\n", "\n", "\n", "1\n", "\n", "\n", "2\n", "\n", "\n", "3\n", "\n", "\n", "4\n", "\n", "\n", "5\n", "\n", "\n", "6\n", "\n", "\n", "7\n", "\n", "\n", "8\n", "\n", "\n", "9\n", "\n", "\n", "10\n", "\n", "\n", "11\n", "\n", "\n", "0\n", "\n", "\n", "100\n", "\n", "\n", "200\n", "\n", "\n", "300\n", "\n", "\n", "400\n", "\n", "\n", "500\n", "\n", "\n", "guitar 2\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "y1\n", "\n", "\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "0\n", "\n", "\n", "1\n", "\n", "\n", "2\n", "\n", "\n", "3\n", "\n", "\n", "4\n", "\n", "\n", "5\n", "\n", "\n", "6\n", "\n", "\n", "7\n", "\n", "\n", "8\n", "\n", "\n", "9\n", "\n", "\n", "10\n", "\n", "\n", "11\n", "\n", "\n", "0\n", "\n", "\n", "100\n", "\n", "\n", "200\n", "\n", "\n", "300\n", "\n", "\n", "400\n", "\n", "\n", "bass\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "y1\n", "\n", "\n" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "for track in 2:6\n", " display(\n", " histogram(\n", " [mod(note.pitch, 12) for note in notes[notes[:track] .== track, :pitch]], \n", " bins = collect(0:12),\n", " xticks = xticks,\n", " title = track_names[track],\n", " xlim = (0,12)\n", " )\n", " )\n", "end" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 5.4) Plot a Note Duration Histogram per Instrument" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1691-element DataArrays.DataArray{Rational{Int64},1}:\n", " 119//384\n", " 71//384\n", " 9//16 \n", " 71//384\n", " 71//384\n", " 9//16 \n", " 71//384\n", " 71//384\n", " 9//16 \n", " 71//384\n", " 71//384\n", " 9//16 \n", " 71//384\n", " ⋮ \n", " 5//128\n", " 5//128\n", " 5//128\n", " 5//128\n", " 5//128\n", " 5//128\n", " 263//384\n", " 263//384\n", " 263//384\n", " 5//24 \n", " 5//24 \n", " 5//24 " ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "onsets = notes[notes[:track] .== 4, :onset_wholes]\n", "offsets = notes[notes[:track] .== 4, :offset_wholes]\n", "durations = offsets - onsets" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1691-element Array{Rational{Int64},1}:\n", " 5//16\n", " 3//16\n", " 5//8 \n", " 3//16\n", " 3//16\n", " 5//8 \n", " 3//16\n", " 3//16\n", " 5//8 \n", " 3//16\n", " 3//16\n", " 5//8 \n", " 3//16\n", " ⋮ \n", " 3//64\n", " 3//64\n", " 3//64\n", " 3//64\n", " 3//64\n", " 3//64\n", " 11//16\n", " 11//16\n", " 11//16\n", " 1//4 \n", " 1//4 \n", " 1//4 " ] }, "execution_count": 42, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[(d.num + 1) // d.den for d in durations]" ] }, { "cell_type": "code", "execution_count": 43, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "0\n", "\n", "\n", "1\n", "\n", "\n", "2\n", "\n", "\n", "3\n", "\n", "\n", "0\n", "\n", "\n", "20\n", "\n", "\n", "40\n", "\n", "\n", "60\n", "\n", "\n", "80\n", "\n", "\n", "100\n", "\n", "\n", "120\n", "\n", "\n", "vocals\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "y1\n", "\n", "\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "0.2\n", "\n", "\n", "0.4\n", "\n", "\n", "0.6\n", "\n", "\n", "0.8\n", "\n", "\n", "1.0\n", "\n", "\n", "0\n", "\n", "\n", "5\n", "\n", "\n", "10\n", "\n", "\n", "15\n", "\n", "\n", "20\n", "\n", "\n", "25\n", "\n", "\n", "30\n", "\n", "\n", "35\n", "\n", "\n", "vocal harmony\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "y1\n", "\n", "\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "0.0\n", "\n", "\n", "0.5\n", "\n", "\n", "1.0\n", "\n", "\n", "1.5\n", "\n", "\n", "2.0\n", "\n", "\n", "0\n", "\n", "\n", "200\n", "\n", "\n", "400\n", "\n", "\n", "600\n", "\n", "\n", "guitar 1\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "y1\n", "\n", "\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "0.0\n", "\n", "\n", "0.5\n", "\n", "\n", "1.0\n", "\n", "\n", "1.5\n", "\n", "\n", "2.0\n", "\n", "\n", "0\n", "\n", "\n", "200\n", "\n", "\n", "400\n", "\n", "\n", "600\n", "\n", "\n", "800\n", "\n", "\n", "guitar 2\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "y1\n", "\n", "\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "0.0\n", "\n", "\n", "0.5\n", "\n", "\n", "1.0\n", "\n", "\n", "1.5\n", "\n", "\n", "0\n", "\n", "\n", "200\n", "\n", "\n", "400\n", "\n", "\n", "600\n", "\n", "\n", "bass\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "y1\n", "\n", "\n" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "for track in 2:6\n", " onsets = notes[notes[:track] .== track, :onset_wholes]\n", " offsets = notes[notes[:track] .== track, :offset_wholes]\n", " durations = offsets - onsets\n", " display(histogram([(d.num + 1) // d.den for d in durations], title=track_names[track]))\n", "end" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 5.5) Plot beat histogram (onsets per beat) per instrument" ] }, { "cell_type": "code", "execution_count": 44, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "0.00\n", "\n", "\n", "0.25\n", "\n", "\n", "0.50\n", "\n", "\n", "0.75\n", "\n", "\n", "1.00\n", "\n", "\n", "0\n", "\n", "\n", "10\n", "\n", "\n", "20\n", "\n", "\n", "30\n", "\n", "\n", "40\n", "\n", "\n", "50\n", "\n", "\n", "60\n", "\n", "\n", "vocals\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "y1\n", "\n", "\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "0.00\n", "\n", "\n", "0.25\n", "\n", "\n", "0.50\n", "\n", "\n", "0.75\n", "\n", "\n", "1.00\n", "\n", "\n", "0\n", "\n", "\n", "10\n", "\n", "\n", "20\n", "\n", "\n", "30\n", "\n", "\n", "vocal harmony\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "y1\n", "\n", "\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "0.00\n", "\n", "\n", "0.25\n", "\n", "\n", "0.50\n", "\n", "\n", "0.75\n", "\n", "\n", "1.00\n", "\n", "\n", "0\n", "\n", "\n", "50\n", "\n", "\n", "100\n", "\n", "\n", "150\n", "\n", "\n", "200\n", "\n", "\n", "guitar 1\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "y1\n", "\n", "\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "0.00\n", "\n", "\n", "0.25\n", "\n", "\n", "0.50\n", "\n", "\n", "0.75\n", "\n", "\n", "1.00\n", "\n", "\n", "0\n", "\n", "\n", "50\n", "\n", "\n", "100\n", "\n", "\n", "150\n", "\n", "\n", "200\n", "\n", "\n", "250\n", "\n", "\n", "guitar 2\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "y1\n", "\n", "\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", " \n", " \n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "0.00\n", "\n", "\n", "0.25\n", "\n", "\n", "0.50\n", "\n", "\n", "0.75\n", "\n", "\n", "1.00\n", "\n", "\n", "0\n", "\n", "\n", "50\n", "\n", "\n", "100\n", "\n", "\n", "150\n", "\n", "\n", "bass\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "y1\n", "\n", "\n" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "for track in 2:6\n", " onsets = notes[notes[:track] .== track, :onset_wholes]\n", " display(\n", " histogram(\n", " [o - floor(o) for o in onsets], \n", " bins = [x*1/16 for x in 0:16], \n", " title = track_names[track]\n", " )\n", " )\n", "end" ] } ], "metadata": { "kernelspec": { "display_name": "Julia 0.6.1", "language": "julia", "name": "julia-0.6" }, "language_info": { "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", "version": "0.6.1" } }, "nbformat": 4, "nbformat_minor": 2 }