{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\"FMP\"\n", "\"AudioLabs\"\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\"C1\"\n", "

Symbolic Format: MIDI

\n", "
\n", "\n", "
\n", "\n", "

\n", "Following Section 1.2.2 of [Müller, FMP, Springer 2015], we have in this a notebook a look at the MIDI standard, which is often used to encode symbolic music. \n", "

" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## MIDI Standard\n", "\n", "**MIDI** (Musical Instrument Digital Interface) was originally developed as an industry standard to get digital electronic musical instruments from different manufacturers to work and play together. It was the advent of MIDI in 1981–1983 that caused a rapid growth of the electronic musical instrument market. MIDI allows a musician to remotely and automatically control an electronic instrument or a digital synthesizer in real time. As an example, let us consider a digital piano, where a musician pushes down a key of the piano keyboard to start a sound. The intensity of the sound is controlled by the velocity of the keystroke. Releasing the key stops the sound. Instead of physically pushing and releasing the piano key, the musician may also trigger the instrument to produce the same sound by transmitting suitable MIDI messages, which encode the note-on, the velocity, the note-off, and other information. These MIDI messages may be automatically generated by some other electronic instrument or may be provided by a computer. It is an important fact that MIDI does not represent musical sound directly, but only represents performance information encoding the instructions about how an instrument has been played or how music is to be produced." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## MIDI Representation\n", "\n", "The original MIDI standard was later augmented to include the **Standard MIDI File (SMF)** specification, which describes how MIDI data should be stored on a computer. In the following, we denote SMF files simply as **MIDI files**\n", "or **MIDI representations**. The SMF file format allows users to exchange MIDI data regardless of the computer operating system and has provided a basis for an efficient internet-wide distribution of music data, including numerous websites devoted to the sale and exchange of music. A MIDI file contains a list of MIDI messages together with timestamps, which are required to determine the timing of the messages. Further information (called meta messages) is relevant to software that processes MIDI files.\n", "\n", "The most important MIDI messages are the note-on and the note-off commands, which correspond to the start and the end of a note, respectively. Each note-on and note-off message is, among others, equipped with a MIDI note number, a value for the key velocity, a channel specification, as well as a timestamp. The **MIDI note number** is an integer between $0$ and $127$ and encodes a note's pitch, where MIDI pitches are based on the equal-tempered scale. Similarly to an acoustic piano, where the $88$ keys of the keyboard correspond to the musical pitches A0 to C8, the MIDI note numbers encode, in increasing order, the musical pitches C0 to G$^\\sharp$9. For example, the concert pitch A4 has the MIDI note number $69$.\n", "\n", "\"FMP_C1_MIDI-NoteNumbers\"\n", "\n", "The **key velocity** is again an integer between $0$ and $127$, which controls the intensity of the sound—in the case of a note-on event it determines the volume, whereas in the case of a note-off event it controls the decay during the release phase of the tone. The exact interpretation of the key velocity, however, depends on the respective instrument or synthesizer.\n", "The **MIDI channel** is an integer between $0$ and $15$. Intuitively speaking, this number prompts the synthesizer to use the instrument that has been previously assigned to the respective channel number. Finally, the **time stamp** is an integer value that represents how many clock pulses or **ticks** to wait before the respective note-on or note-off command is executed. \n", "\n", "The following figure shows various symbolic music representations of the first twelve notes of Beethoven's Fifth including a sheet music representation, a MIDI representation (in a simplified, tabular form), and a piano-roll representation.\n", "\n", "\"FMP_C1_MIDI-NoteNumbers\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Timing Information in MIDI \n", "\n", "An important feature of the MIDI format is that it can handle musical as well as physical onset times and note durations. Similarly to sheet music representations, MIDI can express timing information in terms of musical entities rather than using absolute time units such as microseconds. To this end, MIDI subdivides a quarter note into basic time units referred to as **clock pulses** or **ticks**. The number of pulses per quarter note (PPQN) is to be specified at the beginning, in the so-called **header** of a MIDI file, and refers to all subsequent MIDI messages. A common value is 120 PPQN, which determines the resolution of the time stamps associated to note events. \n", "\n", "Like the sheet music representation, MIDI also allows for encoding and storing absolute timing information, however, at a much finer resolution level and in a more flexible way. To this end, one can include additional tempo messages that specify the number of microseconds per quarter note. From the tempo message, one can compute the absolute duration of a tick. For example, having 600000 $\\mu$s per quarter note and 120, each tick corresponds to 5000 $\\mu$s. Furthermore, one can derive from the tempo message the number of quarter notes played in a minute, which yields the tempo measured in **beats per minute** (BPM). For example, the 600000 $\\mu$s per quarter note correspond to 100 BPM. While the number of pulses per quarter note is fixed throughout a MIDI file, the absolute tempo information may be changed by inserting a tempo message between any two note-on or other MIDI messages. This makes it possible to account not only for global tempo information but also for local tempo changes such as accelerandi, ritardandi, or fermate." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Processing MIDI Files Using `PrettyMIDI`\n", "\n", "The [file format specifications for MIDI](https://www.midi.org/specifications-old/category/smf-specifications) are complex and go beyond the scope of the FMP notebooks. The good news is that there are various software tools for parsing, manipulating, synthesizing, and storing MIDI files. In the following, we introduce the Python package [`PrettyMIDI`](https://github.com/craffel/pretty-midi) for reading MIDI files. Furthermore, this package transforms the (often cryptic) MIDI messages into a list of easy-to-understand note events. The following code cell parses a MIDI file, converts the data into a standard Python list, and displays the first MIDI events in a table. We continue with our Beethoven example from above." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "execution": { "iopub.execute_input": "2024-02-15T08:45:33.937341Z", "iopub.status.busy": "2024-02-15T08:45:33.937045Z", "iopub.status.idle": "2024-02-15T08:45:36.771999Z", "shell.execute_reply": "2024-02-15T08:45:36.771370Z" } }, "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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
StartEndPitchVelocityInstrument
0.250.5043113Piano
0.250.505576Piano
0.250.506776Piano
0.500.7543113Piano
0.500.755576Piano
0.500.756776Piano
0.751.0043113Piano
0.751.005576Piano
0.751.006776Piano
1.002.0039126Piano
1.002.0051126Piano
1.002.006370Piano
" ], "text/plain": [ "" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import os\n", "import sys\n", "\n", "from matplotlib import pyplot as plt\n", "from matplotlib import patches\n", "from matplotlib import colors\n", "import pretty_midi\n", "import pandas as pd\n", "import IPython.display as ipd\n", "\n", "sys.path.append('..')\n", "import libfmp.c1\n", "\n", "fn = os.path.join('..', 'data', 'C1', 'FMP_C1_F13a_Beethoven_FateMotive_Sibelius-Tracks.mid')\n", "midi_data = pretty_midi.PrettyMIDI(fn)\n", "midi_list = []\n", "\n", "for instrument in midi_data.instruments:\n", " for note in instrument.notes:\n", " start = note.start\n", " end = note.end\n", " pitch = note.pitch\n", " velocity = note.velocity\n", " midi_list.append([start, end, pitch, velocity, instrument.name])\n", " \n", "midi_list = sorted(midi_list, key=lambda x: (x[0], x[2]))\n", "\n", "df = pd.DataFrame(midi_list, columns=['Start', 'End', 'Pitch', 'Velocity', 'Instrument'])\n", "html = df.to_html(index=False)\n", "ipd.HTML(html)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`PrettyMIDI` also offers functionality to synthesize the MIDI data with sinusoidal sounds, without paying attention to the actual instruments playing the notes." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "execution": { "iopub.execute_input": "2024-02-15T08:45:36.813742Z", "iopub.status.busy": "2024-02-15T08:45:36.813315Z", "iopub.status.idle": "2024-02-15T08:45:36.851903Z", "shell.execute_reply": "2024-02-15T08:45:36.851054Z" } }, "outputs": [ { "data": { "text/html": [ "\n", " \n", " " ], "text/plain": [ "" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Fs = 22050\n", "audio_data = midi_data.synthesize(fs=Fs)\n", "ipd.Audio(audio_data, rate=Fs)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Finally, we plot the MIDI data in a piano roll representation, where the color (given as RGBA value) of each rectangle is determined by a note's instrument (RBG value) and velocity (alpha parameter, opacity). We now use a visualization function from `libfmp` that has been introduced in the notebook on our [CSV format for symbolic music](../C1/C1S2_CSV.html)." ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "execution": { "iopub.execute_input": "2024-02-15T08:45:36.857591Z", "iopub.status.busy": "2024-02-15T08:45:36.857028Z", "iopub.status.idle": "2024-02-15T08:45:37.067068Z", "shell.execute_reply": "2024-02-15T08:45:37.066236Z" } }, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjgAAADQCAYAAAAK/RswAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAAAYaklEQVR4nO3de5gddZ3n8fc3nQsJtwRtYkPQzILboigIUZZh0I64DIKPwCo7LASD8kxgdkTwMojMuhNl1tsw4nUEVIQxDi4rgzKZgREdG2Yfr2mIAQwRgwFDQkgCBtugEPLdP06FbZsmfeFUV6X6/Xqefs45deryPf2l0h9+VacqMhNJkqQmmVR1AZIkSe1mwJEkSY1jwJEkSY1jwJEkSY1jwJEkSY0zueoCRmLmzJl50EEHVV2GBvnNb37D7rvvXnUZGoK9qS97U0/2pb76+vo2ZWbnaJfbJQLO7NmzWbZsWdVlaJDe3l56enqqLkNDsDf1ZW/qyb7UV0TcP5blPEQlSZIax4AjSZIax4AjSZIaZ5c4B0eSpIngiSeeYPXq1WzdurXqUsbdjBkzOPDAA5k6dWpb1mfAGWcXv+tcNq9bU3UZbbHi7pW84mUHV11G2/x8zQMcNPeFVZfRFr9jqidMSrug1atXM3PmTLq7u5k0aeIcZNm+fTsbNmxg9erVHHxwe/6uGHDG2eZ1a7hiwYuqLqMtjrzg+435LAB/9BfLuGLBMVWX0RanfvqOqkuQNAZbt26dcOEGYNKkScyePZt169a1b51tW5MkSXrOJlq42aHdn3ti/hYlSVKjGXAkSaqpuXNeQES07WfunBcMu82Ojg4OO+wwDjnkEE499VS2bt3KsmXLeOc73zkOn7h9PAdnnD1vv7mcs2RN1WW0xaTpMzlnyZguMFlL0/betzGfZ/d9hv9HTFL93f/gBnJx+9YXizcMO8/06dNZvnw5AGeccQaXX3457373u5k3b177ChkHBpxx9uHLLq+6hLbx0ub11dvbW3UJkhrgmGOOYcWKFfT29nLppZeydOlSfvSjH3HBBRfw+OOPM336dL785S/T3d3N1VdfzY033sjWrVtZvXo1p5xyCh//+McBuPbaa/nwhz9MZnLiiSfysY99rPTaDTiSJOkZtm3bxk033cTxxx//e9Nf8pKXcNtttzF58mS+/e1vc/HFF3P99dcDsHz5cu644w6mTZtGd3c35513Hh0dHbzvfe+jr6+PWbNmcdxxx/GNb3yDk08+udT6DTiSJOlpjz/+OIcddhjQGsE5++yz+d73vvf0+1u2bGHhwoXce++9RARPPvnk0+8de+yx7L333gC89KUv5f7772fz5s309PTQ2dm6IfgZZ5zBbbfdZsCRJEnjZ+A5OEP5wAc+wPz587nhhhtYs2bN752qMG3atKefd3R0sG3bNjKzxGqfXanfooqImRHx9Yi4JyJWRsRREbE4Ih6MiOXFzwll1iBJktpny5Yt7L///gBcffXVw85/5JFHcuutt7Jp0yaeeuoprr32Wl772teWXGX5IzifAm7OzLdExFRgBvDHwGWZeWnJ25YkaZf2ov1nj+ibT6NZ33N14YUXsnDhQj7xiU/wute9btj5u7q6+MhHPsL8+fPJTE444QROOumk51zHcEoLOBGxF/Aa4CyAzHwCeCIiytqkJEmNsmbtQ+O+zf7+/mdM6+npefpQ1FFHHcXPfvazp9+75JJLADjrrLM466yznp6+dOnSp5+ffvrpnH766eUU/CzKHMH5D8BG4MsRcSjQB5xfvPeOiHgrsAx4T2Y+OnjhiFgELALo7Oz0a6811N/fb19qyt7Ul72pp7r0Zc8996y6hMq1qw9R1sk/ETEP+AFwdGb+MCI+BTwGfBbYBCRwCdCVmW/f2bq6u7tz1apVpdSpsfM6OPVlb+rL3tRTXfrS19fHEUccUXUZlRnq80dEX2aO+iqDZZ5kvBZYm5k/LF5/HTg8Mzdk5lOZuR34AvDqEmuQJGmXsn379qpLqES7P3dpASczHwJ+GRHdxaRjgZ9GRNeA2U4B7iqrBkmSdiUzZsxgw4YNEy7kbN++nQ0bNjBjxoy2rbPsb1GdB3y1+AbVfcDbgE9HxGG0DlGtAc4puQZJknYJBx54IKtXr2bdunVVlzLuZsyYwYEHHti29ZUacDJzOTD4uNmZZW5TkqRd1dSpUzn44IOrLqMRSr3QnyRJUhUMOJIkqXG8F5XUQNde9Tn+6SufqboMDWHjxo3801c6qy5Dg/Q/OakWXxNX+xhwpAZ6/FcbuOLPX1V1GRrCL9d2cMCcA6ouQ4O89XM/rroEtZmHqCRJUuMYcCRJUuMYcCRJUuN4Do7UQNNnzuY9162pugwNYePGjXR2PlV1GRpk+szZVZegNjPgSA30397+534jpKbqclNH/b463Elc7eUhKkmS1DgGHEmS1DgGHEmS1DgGHEmS1DgGHEmS1DgGHEmS1DgGHEmS1DgGHEmS1DilBpyImBkRX4+IeyJiZUQcFRH7RMQtEXFv8TirzBokSdLEU/YIzqeAmzPzJcChwErgIuA7mfli4DvFa0mSpLYpLeBExF7Aa4AvAWTmE5n5K+Ak4JpitmuAk8uqQZIkTUyRmeWsOOIw4Ergp7RGb/qA84EHM3PmgPkezcxnHKaKiEXAIoDOzs4jrrvuulLq1Nj19/ezxx57VF2GhmBv6sve1JN9qa/58+f3Zea80S5XZsCZB/wAODozfxgRnwIeA84bScAZqLu7O1etWlVKnRo7bxpYX/amvuxNPdmX+oqIMQWcMs/BWQuszcwfFq+/DhwObIiILoDi8eESa5AkSRNQaQEnMx8CfhkR3cWkY2kdrroRWFhMWwh8s6waJEnSxDS55PWfB3w1IqYC9wFvoxWqrouIs4EHgFNLrkGSJE0wpQaczFwODHXc7NgytytJkiY2r2QsSZIax4AjSZIax4AjSZIax4AjSZIax4AjSZIax4AjSZIax4AjSZIax4AjSZIax4AjSZIax4AjSZIax4AjSZIax4AjSZIax4AjSZIax4AjSZIax4AjSZIax4AjSZIax4AjSZIap9SAExFrIuLOiFgeEcuKaYsj4sFi2vKIOKHMGiRJ0sQzeRy2MT8zNw2adllmXjoO266di991LpvXram6jLZYcfdKXvGyg6suo21+vuYBDpr7wqrLaIvfMZWenp6qy5CkyoxHwNEAm9et4YoFL6q6jLY48oLvN+azAPzRXyzjigXHVF1GW5z66TuqLkGSKlX2OTgJfCsi+iJi0YDp74iIFRFxVUTMKrkGSZI0wZQ9gnN0Zq6LiH2BWyLiHuDzwCW0ws8lwN8Cbx+8YBGIFgF0dnbS29tbcqnj45FHHmHd+ilVl9EW2zNZt35d1WW0zZNPPtmYz7Ptqacas880TX9/v72pIfvSPCMKOBExDXgzMHfgMpn5oZ0tl5nriseHI+IG4NWZeduA9X4BWPosy14JXAnQ3d2dTTmf4NrP78N+XftVXUZbTIpozGcBmDJlSmM+z+SODZ6DU1O9vb32pobsS/OMdATnm8AWoA/43UgWiIjdgUmZ+evi+XHAhyKiKzPXF7OdAtw1ypp3ac/bby7nLFlTdRltMWn6TM5Zcn/VZbTNtL33bczn2X2fF1RdgiRVaqQBZ05mHj/Kdc8GboiIHdv5h8y8OSK+EhGH0TpEtQY4Z5Tr3aV9+LLLqy6hbfw/nvpyqF3SRDfSgPO9iHh5Zt450hVn5n3AoUNMP3Ok65AkSRqLnQaciLiT1kjLZOBtEXEfrUNUAWRmvqL8EiVJkkZnuBGcN45LFZIkSW200+vgZOb9mXk/0AU8MuD1I4BnMUqSpFoa6YX+Pg/0D3j9m2KaJElS7Yw04ERm5o4Xmbkdb/MgSZJqaqQB576IeGdETCl+zgfuK7MwSZKksRppwDkX+EPgQWAtcCTwp2UVJUmS9FyM9DDTizPztIETIuJoYGP7S5IkSXpuRjqC85kRTpMkSarccBf6O4rWoanOiHj3gLf2AjrKLEySJGmshjtENRXYo5hvzwHTHwPeUlZRkiRJz8VOA05m3grcGhFXFxf4kyRJqr3hDlF9MjMvAD4bETn4/cx8U1mFSZIkjdVwh6i+UjxeWnYhktpnwWlvZv3GR6suQ0NJWrcrVq10dc5i7UObqy5DbTRcwLk7Ii4ADgLuBL6UmdtKr0rSc7L+4Ud5arF/ResoE8LW1E7HYv+HoGmG+5r4NcA8WuHmDcDfll6RJEnSczTcCM5LM/PlABHxJeBH5ZckSZL03Aw3gvPkjicempIkSbuK4UZwDo2Ix4rnAUwvXgeQmbnXzhaOiDXAr4GngG2ZOS8i9gH+NzAXWAP818z04KfURl37zqLjg+5WteRJxrXUte+sqktQmw13HZx2XK14fmZuGvD6IuA7mfnRiLioeP2+NmxHUmHJ166np6en6jI0hN7eXntTQ729vVWXoDYb6b2o2ukkWicvUzyeXEENkiSpwSLzGdfva9/KI34BPEprUPaKzLwyIn6VmTMHzPNoZj5jbDAiFgGLADo7O4+47rrrSqtTY9Pf388ee+xRdRkagr2pL3tTT/alvubPn9+XmfNGu9xw5+A8V0dn5rqI2Be4JSLuGemCmXklcCVAd3d3OqRbPw6115e9qS97U0/2pXlKPUSVmeuKx4eBG4BXAxsiogugeHy4zBokSdLEU1rAiYjdI2LPHc+B44C7gBuBhcVsC4FvllWDJEmamMo8RDUbuCFa1ySfDPxDZt4cET8GrouIs4EHgFNLrEGSJE1ApQWczLwPOHSI6ZuBY8variRJUhVfE5ckSSqVAUeSJDWOAUeSJDWOAUeSJDWOAUeSJDWOAUeSJDWOAUeSJDWOAUeSJDWOAUeSJDWOAUeSJDWOAUeSJDWOAUeSJDWOAUeSJDWOAUeSJDWOAUeSJDWOAUeSJDWOAUeSJDVO6QEnIjoi4o6IWFq8XhwRD0bE8uLnhLJrkCRJE8vkcdjG+cBKYK8B0y7LzEvHYduSJGkCKnUEJyLmACcCXyxzO5IkSQOVPYLzSeBCYM9B098REW8FlgHvycxHBy8YEYuARQCdnZ309vaWW6lGrb+/377UlL2pL3tTT/aleSIzy1lxxBuBEzLzv0dED/DezHxjRMwGNgEJXAJ0Zebbd7au7u7uXLVqVSl1aux6e3vp6empugwNwd7Ul72pJ/tSXxHRl5nzRrtcmSM4RwNvKk4i3g3YKyKWZOaCHTNExBeApSXWIEmSJqDSzsHJzPdn5pzMnAucBvxbZi6IiK4Bs50C3FVWDZIkaWIaj29RDfbxiDiM1iGqNcA5FdQgSZIabFwCTmb2Ar3F8zPHY5uSJGni8krGkiSpcQw4kiSpcao4B2dCO+qIQ1i7dm3VZbTFb7duZbcZM6ouo22e+O1vmbrbblWX0RazZs1ixT2/qLoMSaqMAWecrV27ll9eNPi6h7umvd+/hY0N+SzQ+jwbFndWXUZbdP31xqpLkKRKeYhKkiQ1jgFHkiQ1jgFHkiQ1jufgjLM5c+ZwwEebcZLx1ClTOOCjv666jLbZbdq0xnyezs5mnEskSWNlwBln3+9rzp0pvDldfXlXZEkTnYeoJElS4xhwJElS4xhwJElS4xhwJElS4xhwJElS4xhwJElS4xhwJElS4xhwJElS45QecCKiIyLuiIilxet9IuKWiLi3eJxVdg2SJGliGY8RnPOBlQNeXwR8JzNfDHyneC1JktQ2pQaciJgDnAh8ccDkk4BriufXACeXWYMkSZp4yh7B+SRwIbB9wLTZmbkeoHjct+QaJEnSBFPazTYj4o3Aw5nZFxE9Y1h+EbAIWndG9uaB9dPf329fasre1Je9qSf70jyRmeWsOOIjwJnANmA3YC/gH4FXAT2ZuT4iuoDezOze2bq6u7tz1apVpdSpsfNu4vVlb+rL3tSTfamviOjLzHmjXa60EZzMfD/wfoBiBOe9mbkgIv4GWAh8tHj8Zlk1SBPVgtPezPqNj1ZdhoaSQFRdhAbr6pzF2oc2V12G2qi0gLMTHwWui4izgQeAUyuoQWq09Q8/ylOL/StaR5kQtqZ2Ohb7PwRNMy4BJzN7gd7i+Wbg2PHYriRJmpi8krEkSWocA44kSWocA44kSWqcKk4yllSyrn1n0fFBT5qsJb9FVUtd+3pbxKYx4EgNtORr13tNj5ryeiv15EX+msdDVJIkqXEMOJIkqXEMOJIkqXFKuxdVO0XErwFvRlU/zwc2VV2EhmRv6sve1JN9qa/uzNxztAvtKicZrxrLjbZUrohYZl/qyd7Ul72pJ/tSXxGxbCzLeYhKkiQ1jgFHkiQ1zq4ScK6sugANyb7Ul72pL3tTT/alvsbUm13iJGNJkqTR2FVGcCRJkkbMgCNJkhqnVgEnIo6PiFUR8fOIuGiI9yMiPl28vyIiDq+izolmBH3piYgtEbG8+PmfVdQ50UTEVRHxcETc9Szvu79UZAS9cZ+pQEQcEBHfjYiVEXF3RJw/xDzuN+NshH0Z9T5Tm+vgREQH8DngPwNrgR9HxI2Z+dMBs70BeHHxcyTw+eJRJRlhXwD+PTPfOO4FTmxXA58F/v5Z3nd/qc7V7Lw34D5ThW3AezLz9ojYE+iLiFv8O1O5kfQFRrnP1GkE59XAzzPzvsx8AvgacNKgeU4C/j5bfgDMjIiu8S50ghlJX1SBzLwNeGQns7i/VGQEvVEFMnN9Zt5ePP81sBLYf9Bs7jfjbIR9GbU6BZz9gV8OeL2WZ37Akcyj9hrp7/yoiPhJRNwUES8bn9I0DPeXenOfqVBEzAVeCfxw0FvuNxXaSV9glPtMbQ5RATHEtMHfYR/JPGqvkfzObwdelJn9EXEC8A1aw7uqlvtLfbnPVCgi9gCuBy7IzMcGvz3EIu4342CYvox6n6nTCM5a4IABr+cA68Ywj9pr2N95Zj6Wmf3F838BpkTE88evRD0L95eacp+pTkRMofVH9KuZ+Y9DzOJ+U4Hh+jKWfaZOAefHwIsj4g8iYipwGnDjoHluBN5anOX+n4Atmbl+vAudYIbtS0S8ICKieP5qWv9dbR73SjWY+0tNuc9Uo/idfwlYmZmfeJbZ3G/G2Uj6MpZ9pjaHqDJzW0S8A/hXoAO4KjPvjohzi/cvB/4FOAH4ObAVeFtV9U4UI+zLW4A/i4htwOPAaeklsksXEdcCPcDzI2It8FfAFHB/qdoIeuM+U42jgTOBOyNieTHtYuCF4H5ToZH0ZdT7jLdqkCRJjVOnQ1SSJEltYcCRJEmNY8CRJEmNY8CRJEmNY8CRJEmNY8CRBEBEPG/AnXofiogHi+f9EfF3JW3zgoh4axnrHouIWLOzi4dFxNciwisOS7sAvyYu6RkiYjHQn5mXlriNybQuv354Zm4razujERFrgHmZuelZ3n8tsCAz/3RcC5M0ao7gSNqpiOiJiKXF88URcU1EfKsY7fgvEfHxiLgzIm4uLrdORBwREbdGRF9E/Ouz3I35dcDtO8JNRLwzIn4aESsi4mvFtN0j4qqI+HFE3BERJxXTOyLi0mK7KyLivGL6scV8dxbLTSumr4mID0bE7cV7LymmP6/4LHdExBUU9yEqtvvP0bqx310R8SdFzf8OvL4IZ5JqzIAjabQOBE4ETgKWAN/NzJfTurroiUXI+Qzwlsw8ArgK+F9DrOdooG/A64uAV2bmK4Bzi2l/CfxbZr4KmA/8TUTsDiwC/mDA/F+NiN2Aq4E/KeqZDPzZgPVvyszDgc8D7y2m/RXwfzPzlbQu0f/CYvrxwLrMPDQzDwFuBsjM7bSucHvoaH5hksafAUfSaN2UmU8Cd9K6fcfNxfQ7gblAN3AIcEtx2fX/QeuGhYN1ARsHvF5BK6gsAHYcsjoOuKhYTy+wG60Q8nrg8h2jP5n5SLHdX2Tmz4plrwFeM2D9O27g11fUSfH+kmId/ww8OuCzvD4iPhYRx2TmlgHreRjYb8jfjKTacJhV0mj9DlqjGRHx5ID7wWyn9W9KAHdn5lHDrOdxWoFlhxNpBY43AR+IiJcV63pzZq4auGBx073BJxDGSOoGnuL3/+17xomImfmziDiC1j2JPhIR38rMDxVv71bULqnGHMGR1G6rgM6IOAogIqYUYWWwlcBBxTyTgAMy87vAhcBMYA9aN3k9b8BdhF9ZLPst4Nwd58JExD7APcDciDiomOdM4NZhar0NOKNYxxuAWcXz/YCtmbkEuBQ4fMAy/xG4e/hfg6QqGXAktVVmPkHrzr8fi4ifAMuBPxxi1pv4/4eQOoAlEXEncAdwWWb+CriE1l24V0TEXcVrgC8CDxTTfwKcnpm/pXXn5/9TrGc7cPkw5X4QeE1E3E7rcNgDxfSXAz8qDo39JfDXABExG3g8M9eP7LchqSp+TVxSZSLiBuDCzLy36lpGIiLeBTyWmV+quhZJO+cIjqQqXUTrZONdxa9onbwsqeYcwZEkSY3jCI4kSWocA44kSWocA44kSWocA44kSWocA44kSWqc/wdGWt7Hl9S8ywAAAABJRU5ErkJggg==\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "def midi_to_list(midi):\n", " \"\"\"Convert a midi file to a list of note events\n", "\n", " Notebook: C1/C1S2_MIDI.ipynb\n", "\n", " Args:\n", " midi (str or pretty_midi.pretty_midi.PrettyMIDI): Either a path to a midi file or PrettyMIDI object\n", "\n", " Returns:\n", " score (list): A list of note events where each note is specified as\n", " ``[start, duration, pitch, velocity, label]``\n", " \"\"\"\n", "\n", " if isinstance(midi, str):\n", " midi_data = pretty_midi.pretty_midi.PrettyMIDI(midi)\n", " elif isinstance(midi, pretty_midi.pretty_midi.PrettyMIDI):\n", " midi_data = midi\n", " else:\n", " raise RuntimeError('midi must be a path to a midi file or pretty_midi.PrettyMIDI')\n", "\n", " score = []\n", "\n", " for instrument in midi_data.instruments:\n", " for note in instrument.notes:\n", " start = note.start\n", " duration = note.end - start\n", " pitch = note.pitch\n", " velocity = note.velocity / 127. # since midi velocity is in [0, 127]\n", " score.append([start, duration, pitch, velocity, instrument.name])\n", " return score\n", "\n", "score = midi_to_list(midi_data)\n", "libfmp.c1.visualize_piano_roll(score, figsize=(8, 3), velocity_alpha=True);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The next example reads and visualizes a MIDI file for the beginning of the four-voice Fugue BWV 846 in C major by Johann Sebastian Bach. In the MIDI file, the four voices (soprano, alto, tenor, basso) are encoded by four different MIDI channels.\n", "\n", "\"C1\"\n", "
\n", "-->\n", "\n", "\n" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "execution": { "iopub.execute_input": "2024-02-15T08:45:37.070930Z", "iopub.status.busy": "2024-02-15T08:45:37.070632Z", "iopub.status.idle": "2024-02-15T08:45:37.462322Z", "shell.execute_reply": "2024-02-15T08:45:37.461714Z" } }, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjgAAADQCAYAAAAK/RswAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAAA0DElEQVR4nO3de3hU1b3/8feXmxbwkkkCJCgzba3YWixWj7daD9RKrbWltVWrlKsVQUS8VZAeFbVaaq0eKh4qikItBawW7a/1WOslWlufUqMcpVVUcMIl4ZILaLxxW78/ZhIzmT3Jnsx98nk9D0+SNWvvvfZemcli7+/6LnPOISIiIlJMeuS6ASIiIiLppgGOiIiIFB0NcERERKToaIAjIiIiRUcDHBERESk6GuCIiIhI0cnoAMfMLjezf5nZGjNbZmb7m1nAzP5iZm9Gv5Zksg0iIiLS/Vim8uCY2WDgeeBzzrkPzOxB4DHgc0Cjc26umc0CSpxzMzva18EHH+wOO+ywjLRTUvPee+/Rr1+/XDdD2lG/5C/1Tf5S3+Snjvqlurq63jlX7vVar4y2KrL/T5jZbqAvUAtcA4yIvr4EqAI6HOAMHDiQF198MXOtlC6rqqpixIgRuW6GtKN+yV/qm/ylvslPHfWLmdUk2i5jd3CiB54B3Ax8ADzhnBtjZjuccwe3qdPknIt7TGVmk4HJAOXl5cc8+OCDGWundF1zczP9+/fPdTOkHfVL/lLf5C/1TX7qqF9GjhxZ7Zw71uu1jN3BicbWjAY+CewAfmdmP/C7vXNuIbAQYOjQoU6j6vyk//HkJ/VL/lLf5C/1TX7qar9kMsj4q8DbzrntzrndwO+Bk4CtZlYBEP26LYNtEBERkW4okzE4G4ATzKwvkUdUpwIvAu8B44G50a+PZrANIiIF6/xLzie8PdxpvVB5iN/O/23mGyRps2vXLtatW8f777+f66bkvQMOOIDXXnuNT3/60/Tp08f3dhkb4Djn/mFmDwEvAXuAl4k8cuoPPGhmFxAZBJ2dqTaIiBSy8PYwh644tPN654Yz3xhJq3Xr1nHwwQczdOhQevRQSrqO7Nu3j61bt7Ju3To++9nP+t4uo7OonHPXA9e3K/6IyN0cERGRbun999/X4ManHj16MHDgQGpra5PbLkPtERERkQ5ocONfV66Vrq6IiIgUnUwn+hMRkU58/+LvewYT122og3M73z5UHkp7myS7QocMombz1rTtLzh4IOFNWzqtt3LlSs466yxee+01jjjiCMLhMGeeeSZr1qxh9erV1NbWcsYZZ6StXdmkAY6ISI6Ft4c59HcewcRnw99X/D37DZKsq9m8FTcnffuzOf4GS8uWLePkk09m+fLlzJkT24DVq1fz4osvFuwAR4+oREREuqHm5mb+9re/sWjRIpYvXx7z2q5du7juuutYsWIFw4cPZ8WKFTQ2NvLtb3+bo446ihNOOIFXXnklRy33R3dwREREuqFHHnmE008/ncMPP5xAIMBLL71EIBAAoE+fPtx44428+OKLzJ8/H4Dp06dz9NFH88gjj/D0008zbtw4Vq9encMz6JgGOCIiORYqDxE+O+xZLpIpy5Yt47LLLgPg+9//PsuWLWPatGkJ6z///PM8/PDDAHzlK1+hoaGBnTt3ctBBB2WjuUnTAEdEJMeW/8/yziuJpFFDQwNPP/00a9aswczYu3cvZsbFF1+ccBuvxbnNLJPNTIlicERERLqZhx56iHHjxlFTU0M4HGbjxo188pOfZNOmTa11DjjgAN59993Wn0855RSWLl0KRBbALCsr48ADD8x62/3SHRwREZEcCw4e6Hvmk9/9dWTZsmXMmjUrpuy73/0ut9xyS+vPI0eOZO7cuQwfPpxrrrmGOXPmMHHiRI466ij69u3LkiVL0tbeTNAAR0REJMf85KxJp6qqqriySy+9lEsvvbT150AgwD//+c+YOo8+WjjrY2uAI1Ikxs4YS7g+DMDOHTs56B7vwL9QWYgH5j2QlTZNumoSNQ01MWXB0iD33XZfVo6fLYkS9YXKQ3HxNbcsuIVr77k2tl4W+0Sku9AAR6RIhOvDDFk6BICtW7cycKD3LerwmHDW2lTTUMOQ+4fElk2sSVC7cCVK1Oc1M2pL8xaG/WlYbL0s9olId6EgYxERESk6GuCIiIhI0cnYIyozGwqsaFP0KeA64GDgQmB7tHy2c+6xTLVDREREup+MDXCcc2uB4QBm1hPYDKwEJgJ3OOduy9SxRbqjUFmoNZZj546dfHTwRwnrZUuwNBgXcxMsDWbt+NmSTCbiQf0HsWHMhth6WewTke4iW0HGpwLrnHM1+Zz1UKSQtZ2FU1VVxYgRI3LXmKhimy2VSDKZiGdPnZ0XfSP5ZfCQELUb0xeAX3lokM0bwh3W6dmzJ8OGDcM5R8+ePZk/fz4nnXRS2tqQa+aVejntBzG7D3jJOTffzOYAE4B3gBeBK51zTR7bTAYmA5SXlx/z4IMPZrydkrzm5mb69++f62ZIO+qX/KW+yV/Z7JsDDjiAY445pvVnM+N7z7yXtv0/NLKf59IKbfXv35/m5mYA/vznP3PLLbfw7LPPpq0N6VZdXR2TWRlg5MiR1c65Y73qZ/wOjpn1Ab4FXBMtWgDcBLjo118Ak9pv55xbCCwEGDp0qNP/ePJTvtwpkFjql/ylvslf2eyb6urqrBzHr3feeYeSkhIgMtAbPXo0TU1N7N69m5/85CeMHj2a9957j3POOYdNmzaxd+9err32Ws4991xmzZrFH/7wB3r16sWoUaO47bbbqKmpYdKkSWzfvp3y8nLuv/9+hgwZ0kkrOpdM/2TjEdXXidy92QrQ8hXAzO4B/piFNoiIiEgbH3zwAcOHD+fDDz+krq6Op59+GoD999+flStXcuCBB1JfX88JJ5zAt771LR5//HEqKyv505/+BMDOnTtpbGxk5cqVvP7665gZO3bsAOCSSy5h3LhxjB8/nvvuu49LL72URx55JKvnl40BznnAspYfzKzCOVcX/fE7wJostEEk7/3w6h8SbggTKg1x76335ro5gHcm4mR4ZS2eMnsK4YZwXN1QaYhf3fKrLh8rW8ZMH0NNfbvA6bIgS+9cGlfX6/r12dWn6O7gdJeM1cXmE5/4BKtXrwbghRdeYNy4caxZswbnHLNnz+a5556jR48ebN68ma1btzJs2DCuuuoqZs6cyZlnnsmXv/xl9uzZw/77788Pf/hDvvGNb3DmmWe27u/3v/89AGPHjuXqq6/O+vlldIBjZn2B04CL2hTfambDiTyiCrd7TaTbCjeECS4KEr4gnOumtPLKRJzU9h5Zi8MNYYJ3x8+kCl8U7vJxsqmmvoZDl8VmLa45z3sQ6HX9/u/b/5extuVKd8lYXcxOPPFE6uvr2b59O4899hjbt2+nurqa3r17EwqF+PDDDzn88MOprq7mscce45prrmHUqFFcd911rFq1iqeeeorly5czf/781jtBbeViglFGBzjOufeB0nZlYzN5TBEREUnO66+/zt69eyktLWXnzp0MGDCA3r1788wzz1BTExms1tbWEggE+MEPfkD//v1ZvHgxzc3NvP/++5xxxhmccMIJHHbYYQCcdNJJLF++nLFjx7J06VJOPvnkrJ+T1qISERHJscpDgzw0sl9a99eZlhgcAOccS5YsoWfPnowZM4ZvfvObHHvssQwfPpwjjjgCgFdffZUf/ehH9OjRg969e7NgwQLeffddRo8ezYcffohzjjvuuAOAX/7yl0yaNImf//znrUHG2aYBjkieCJWGCF8QicHJF16J+pLdvr1QacjzcVQ+nXdHgmXBuEdSwTLvPyZe129gP+9FUAtZd0nomEmd5azJhL1793qWl5WV8cILL8SVh0Ihvva1r8WVr1q1yrOu16OqbNIARyRP5EtgcVuZCBIthEDijngFEyfidf2qqqrS2Jr8oGBiyUdabFNERESKjgY4IiIiUnQ0wBEREZGioxgckTRpSdTXVS0J/tomwiuU5HfpcMn1l1DT2C5QNRBk/g3z03qciVdOJFwfjikLlYW4/xfxszyUwK7rCj2hoxQ+DXBE0qQlUV+Xt48m+GubCK9Qkt+lQ01jDaE7QzFl4enhtB8nXB9myJLYpHTh8d7HUQK7riv0hI5S+PSISkREJMcGhQZhZmn7Nyg0qNNj3nzzzRx55JEcddRRDB8+nH/84x9ZONPs0R0cERGRHNtaszWygFG69mdbO3z9hRde4I9//CMvvfQS++23H/X19ezatSulY+7Zs4devfJnWKE7OCIiIt1MXV0dZWVl7LfffkAkuV9lZSVPPfUURx99NMOGDWPSpEl89NFHQCRx38yZMznuuOM47rjjeOuttwCYMGECV1xxBSNHjmTmzJmsWrWKk046iaOPPpqTTjqJtWvXArB48WLOOussTj/9dD7zmc/ELL65bNkyhg0bxuc//3lmzpyZtnPMn6GWSB5KJnB447qNcEHXj9WSybdtpt+N6zdy5rQzfW0fDAS566a7ut6AHAsGgnExNzVv1TB6xuiYslAgxLzr5/na5+RZk+P6rzZcC+Nj622u2cyoC0fFbb/p7U0wsV078zBD79Vzr6amyV9sULAkyK2zbs1wixJnrN6wbgNnTD0jtk2BIAtuXpDxNsnHRo0axY033sjhhx/OV7/6Vc4991yOP/54JkyYwFNPPcXhhx/OuHHjWLBgAZdddhkABx54IKtWreLXv/41l112GX/84x8BeOONN3jyySfp2bMn77zzDs899xy9evXiySefZPbs2Tz88MMArF69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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "fn = os.path.join('..', 'data', 'C1', 'FMP_C1_F12_Bach_BWV846_Sibelius-Tracks.mid')\n", "midi_data = pretty_midi.PrettyMIDI(fn)\n", "score = midi_to_list(midi_data)\n", "libfmp.c1.visualize_piano_roll(score, figsize=(8, 3), velocity_alpha=True);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Conversion from MIDI to CSV\n", "\n", "We can convert a list of note events into a CSV file with the [`to_csv`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_csv.html) method of a `pd.DataFrame`. In the following code cell, we convert a MIDI file into a CSV file as used in the [FMP notebook on the CSV format](../C1/C1S2_CSV.html)." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "execution": { "iopub.execute_input": "2024-02-15T08:45:37.465018Z", "iopub.status.busy": "2024-02-15T08:45:37.464820Z", "iopub.status.idle": "2024-02-15T08:45:37.482346Z", "shell.execute_reply": "2024-02-15T08:45:37.481693Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Score as list:\n", "[[6.724133, 0.5172410000000003, 67, 0.5984251968503937, 'Soprano'], [7.241374, 0.5172410000000003, 69, 0.6062992125984252, 'Soprano'], [7.758615000000001, 0.5172410000000003, 71, 0.6141732283464567, 'Soprano']]\n", "\n", "\n", "Score as pandas DataFrame\n", " Start Duration Pitch Velocity Instrument\n", "0 6.724133 0.517241 67 0.598425 Soprano\n", "1 7.241374 0.517241 69 0.606299 Soprano\n", "2 7.758615 0.517241 71 0.614173 Soprano\n", "\n", "\n", "Score as CSV\n", "../output/C1/FMP_C1_F12_Bach_BWV846_Sibelius-Tracks.csv\n", "['\"Start\";\"Duration\";\"Pitch\";\"Velocity\";\"Instrument\"\\n', '\"6.724\";\"0.517\";67;\"0.598\";\"Soprano\"\\n', '\"7.241\";\"0.517\";69;\"0.606\";\"Soprano\"\\n', '\"7.759\";\"0.517\";71;\"0.614\";\"Soprano\"\\n']\n" ] } ], "source": [ "fn_in = os.path.join('..', 'data', 'C1', 'FMP_C1_F12_Bach_BWV846_Sibelius-Tracks.mid')\n", "fn_out = os.path.join('..', 'output', 'C1', 'FMP_C1_F12_Bach_BWV846_Sibelius-Tracks.csv')\n", "midi_data = pretty_midi.PrettyMIDI(fn_in)\n", "score = midi_to_list(midi_data)\n", "df = pd.DataFrame(score, columns=['Start', 'Duration', 'Pitch', 'Velocity', 'Instrument'])\n", "df.to_csv(fn_out, sep=';', quoting=2, float_format='%.3f', index=False)\n", "\n", "print('Score as list:')\n", "print(score[0:3])\n", "print('\\n')\n", "\n", "print('Score as pandas DataFrame')\n", "print(df.loc[0:2,:])\n", "print('\\n')\n", "\n", "print('Score as CSV')\n", "print(fn_out)\n", "with open(fn_out, 'r', encoding='utf-8') as file:\n", " csv_str = file.readlines()\n", "print(csv_str[0:4])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Python Package `music21`\n", "\n", "The package [`music21`](https://web.mit.edu/music21/), which will be introduced in more detail in the [FMP notebook on MusicXML](../C1/C1S2_MusicXML.html), offers similar plotting functionalities." ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "execution": { "iopub.execute_input": "2024-02-15T08:45:37.485053Z", "iopub.status.busy": "2024-02-15T08:45:37.484858Z", "iopub.status.idle": "2024-02-15T08:45:37.909716Z", "shell.execute_reply": "2024-02-15T08:45:37.908954Z" } }, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAABJEAAAG0CAYAAACCF7aQAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAABYlAAAWJQFJUiTwAABf00lEQVR4nO3de1xU1f7/8TcCgkKIaUpqMuSUlpUVamWlWB49Vl7Kyg5mgpV6stOpzLQ7nW6n0pNWp2+WF6ws7WZqkmYp2o3MyU5UY2oNliaWFpIoOsD+/eFvRpCBgZlhrq/n4+FD2Je1P3utvdfAh7XXjjIMwxAAAAAAAABQj2aBDgAAAAAAAADBjyQSAAAAAAAA3CKJBAAAAAAAALdIIgEAAAAAAMAtkkgAAAAAAABwiyQSAAAAAAAA3CKJBAAAAAAAALdIIgEAAAAAAMAtkkgAAAAAAABwiyQSAAAAAAAA3CKJBAAAAAAAALdIIgEAAAAAAMAtkkgAAAAAAABwiyQSACBkmUwmRUVFOf8dd9xx+uWXX+rcPj8/v8b2jn8mk8l/QfvRu+++q9GjR6tLly5KTExUYmKiunTpolGjRuntt9+WYRiBDjFi1HXtRUVFKSsrK9DhBdQNN9zQZPUxfPjwGmXn5OT4rGxP5ebm1nktOP4lJCSoe/fuuuOOO1z2aYZhaPjw4erYsaO+++47v8XelG0FAAgNJJEAACHr/fffV2Fhof7+979Lknbv3q1rr71WVVVVLrfv1auXCgsLVVhYqA4dOmjYsGEqLCzU+++/77OYHImt/Px8n5XZWEVFRTrnnHM0dOhQHTx4UI888ohWr16t999/X/fff792796tESNGqGfPntq8eXPA4vSFoqIi5y+0waz6tefw8MMPq7CwUI888kgAI2t6WVlZ9SZw/vWvf9W4j33p6aefVmFhoYYNG+bzsj01fPhwFRYWauXKlc5lc+fOdV4f69ev1//93/8pKipK06dP1+mnn65PP/20Rhl79uzRkiVL9Msvv+i9996rdYymui+asq0AAKEhJtABAADgqZNPPlmS1K5dO+eyNWvW6JFHHtF9991Xa/uEhASddtppkqTY2FglJyc7vw8Xmzdv1vnnn6+ysjK99957GjRoUI31ffr00ZgxYzRv3jzdcMMNOu+88/TBBx/orLPOClDEkaH6tefQsWPHsLv+PNGhQwd16NChxn3sK507d5YkJScn+7xsTyUnJys5OVmJiYnOZWlpaTWuhV69emnkyJE666yzZLVadcUVV2jLli065phjJElt27bV5MmTtWHDBl1zzTV+i70p2woAEBoYiQQACBtDhw6VJD344IP6+OOPAxyN/+3bt09DhgzR7t27NXPmzFoJpOqys7M1ZcoU/f777xoxYoT27t3rx0gBuBMXF6cpU6ZIknbt2qU33nijxvonnnhCq1evVseOHQMRHgAgQpFEAgCEjdzcXHXu3FmVlZXKzMzU77//HuiQ/GrmzJnavHmzTjzxRF1//fVut7/77ruVkJAgm82m//znP36IEEBjdO/e3fn1V199FbhAAAD4/0giAQDCRuvWrbVo0SLFxsbq559/1tixYz0uq7y8XE899ZTOOecctWrVSi1atFC3bt10++23a+fOnbW2d8yFtG3bNklS//79a0xA62qOpA8//FDDhg1Tu3bt1Lx5c7Vv316XXnqp3nnnnUbHW1VVpZkzZ0qSRowYoWbN3H/EJyYm6pJLLpEkPfvss6qsrJQkzZgxo97Jcx1z3Dj+5ebm1iq7pKRE8+fP1/Dhw3XyySerRYsWatWqlc4991zNnDlTdru91j4PP/xwjXIzMjJkt9v173//W927d1eLFi2c6xxzvqSlpTn3P3py4qNVVlZq9uzZuvDCC5WcnKz4+HiZTCaNGTPG5S/oZrO51nn+8MMPGj16tDp06KDo6GhnnP60detW3XjjjTKZTIqLi1Pr1q11/vnna+bMmSovL6+x7SuvvFJrEnnDMDRz5kx1795d8fHxat++vbKzs/Xbb7/VeUy73a7p06frtNNOU3x8vI499lhddNFFWrp0aa1Jwx2Pjjmuk/nz50s6PEKwoZNcl5aW6tZbb9UJJ5yguLg4denSRTk5Oc5r1Bs7d+7UjTfe6Cz7hBNO0M0331zr/F1NeF29ravPO9RUE3c3b97c+XVFRYWk2vdf9fvTk/uiqqpKubm56t+/v4499ljFxsYqJSVFAwYM0JNPPumyv6uuKdsKABB8SCIBAMLKueeeq0cffVSStGTJEj3zzDONLmPXrl0677zzdPvtt+u0007TkiVLtHbtWl133XWaNWuWunfvXutxOcck3x06dJBUc6LcwsJC9erVq8b2U6dO1YABA7Rt2zY9/fTT+uijjzR9+nTZbDZdfvnluuGGGxoV85dffun8JfjoY9UnPT1dkvT7779r48aNkqTRo0fXO3nuI488osLCQvXs2bPOch9++GFlZWVp+/bteuihh/TRRx/plVdeUadOnXTrrbdq0KBBOnToUI19xo8fr8LCQj388MOSDv9yO2zYMP300096/vnntWLFCp133nmSDic1jp6cuHp9V5/AWjr8qN+gQYN04403KiUlRa+88oo+/PBD3XrrrVq2bJl69eqlefPm1djnvffeq3GemzZt0uDBg3XBBRdo6dKlmjdvnhISEtzWsS+98847Ov300/XOO+/ojjvuUH5+vubNm6c2bdro1ltv1YUXXqg//vjDuf2QIUNUWFiouXPnOpeNHz9eW7Zs0YsvvqglS5aod+/eys3N1V//+leXv/gfOnRIQ4YM0R133KEWLVrotdde06pVqzRmzBjdcssteu655yQdni+nsLBQn332maQj14ljUuu///3vNdrnpptucnmOBw4c0ODBg9W5c2ctXrxYr776qpo3b64HH3xQt99+u1f1V1xcrL59+8pkMumtt97SihUrdOGFF+q///2v0tPTVVRU5Ny2sLBQ9957r6TDcxB9/fXXNa6Rjh07qrCwUJMnT9YxxxyjL7/8ss5z8tSWLVucX3fr1k3SkXp1dX86YmrofVFWVqa//vWvys7OVmJiohYsWKBPPvlE06ZN02+//aY777zTOa+UK03ZVgCAIGUAABDiHnjgAaP6R1pVVZVx2WWXGZKMuLg446uvvqq1T2pqqjFmzJhay6uqqowLL7zQkGTccssttda//fbbhiSjTZs2xo4dO1yWK8lYs2ZNnfHOmTPHkGR069bNKC8vr7GurKzMOOGEEwxJxgsvvFDPWdc0d+5cQ5IhydiwYUOD93vjjTec+82ZM6fGOke9uqonwzCMfv36GZKMefPm1Vo3adIko1OnTkZpaWmtdVlZWYYkY9q0aS7LnTdvniHJiI6ONiZNmlRj3SeffGJIMmw2m2EYhmGz2Zzx12f06NGGJCMrK6vWuq+++spo1qyZERsba3zzzTd1nmdcXJyxcePGGutuvPFGo1+/fvUe+2iOeF3VW32++eYbIz4+3mjevLnx/fff11p/xRVXGJKMzMzMWuvWrFnjrNMJEybUWFdRUWF07tzZkGS89957tfZ1XAddunQx/vzzzxrrioqKjMTEREOS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nF9v27bN5Ta//vqrT47lD/XF6rivq5+zw3HHHadhw4ZJOjzB9tdff63169f7dEJtf2tIX1dRUaF9+/bVe98AACILSSQAQETo06ePHn74YUnSzJkz65ywesSIEZIOz6Oza9cul9t88MEHNbatzpGIqZ7E+eKLL5yTcPfp08c56awjgXM0u92uzMxMPfvss416/OiOO+5Qp06d9MMPP9SYu6Uu//73v1VWVqYuXbq4TKw55rpxNTluSUmJtm7d6rLcqqoq59euklk//fST29gaqnriq/qx8vLy9NFHH0mSc46pAwcO1Dlx9saNGzVmzBitWbPGZ7F5q3oSKS4uTpdddpmkuq8b6fAb/2666SZnwslbF1xwgXO0XV119+mnn9Zbhqt7oqioSG+++ab27Nnjkzgb6pNPPnG5vLCw0BnLpZde6nIbR8JoyZIleuihh3T22WerZ8+eTROolxpzX5SUlNT5FrUHHnhAxxxzjL7++usmjBYAEEpIIgEAIsadd96pwYMHS6r7EZzLLrtMffv2VVVVlcvXwS9evFhff/212rRpoylTptRa70i8/P77785ld999t2699VZJh0f3PPLII5Kk//73vy4TKo8++qh2797tsvz6tGnTRm+99ZZatWqlW265xZnscuWll17So48+qrZt2+rdd991OS/KeeedJ+nw42lHP9737LPP1jnayfEGrH379undd9+ttf75559v8Dm507ZtW2eizVHnFRUVuvLKK/Xiiy9KOjxf1JgxYyRJ9913X62RVVVVVZo8ebJatGihW265xWex+dqDDz6oFi1a6JNPPnE5Ymr16tVavny5xo4d67PHJFu2bOm8dp9++ulak6H//PPPbueZcnVPLFiwQFdddZXzzW/+8t133+mdd96ptdxxT1544YXq27evy30vvvhidenSRRUVFXrzzTeDehRSY++LBx98sNb9vGvXLs2dO1e9evXy+u1zAIDwwZxIAICQtXnzZh06dMj5iIrjbUNpaWlKSEiotX1UVJReeuklnXXWWXU+7hMVFaXXX39df/3rX/Xcc8/pwIEDGjNmjFq2bKkPPvhADz/8sJKTk/XOO+/o+OOPr7X/pZdeqk8//VTPP/+8OnbsqG+//VZr1qxxPmomSVlZWfrhhx/08MMPq0+fPrrvvvuUnp6u3bt3a+HChXrppZc0YcIEXXPNNY2uk969e6ugoECjRo3SwIEDddVVV2nEiBFKS0tTZWWlNm/erNdee00rVqzQhRdeqJdfftn5VqqjnXrqqbr00ku1fPlyXXrppZo8ebKOO+44LVu2TF9++aXOP/98rVu3Tjt27NA333yjDh066Nhjj9V5552nzMxMvfrqqxo1apTuvvtuXXjhhfrzzz81d+5crVixwnkMR5uddtppKikp0fbt27Vjxw5Jhx+3c9em8fHxuuiii7Rq1So99thjuvrqq/Xaa6/pwIEDGjp0qHO75557TsXFxVq5cqX69eunO+64QyaTSTabTTNmzFBBQYHmz59fYyJzm82msrIylZWVSZLzPJs3b66TTz65Ue3yxx9/yGKx1Fj23Xff1Zvo27lzZ43vTz31VC1atEjXXHONRo4cqcmTJ2vw4MGy2+1as2aNnnzySaWnp+vJJ5907lNWViabzSabzSbpcPL0m2++UUJCgtLS0px17riHSkpK9M0336h169bq2LGjpMNJ0IKCAq1cuVL9+/fXPffco86dO+ubb77Rww8/rIkTJzrfgujKJZdcokcffVRLlizRsGHDVFFRoVmzZumMM86QyWTSr7/+6vxXPYZ27dqpXbt22rFjh/74449a7dCQx0l/+uknlZaWOt+iOGTIEI0bN05Wq1UDBgxQWVmZXnzxRS1atEgnnHCCXnrppTrLckywfddddykxMdHjCbUddV59NKTNZnMm/tzNd+Woj/rarLH3xdKlSzV8+HDddNNNOvbYY/XNN9/o0UcfVVVVlRYtWuTcvinbCgAQIgwAAEJUamqqIanWvzVr1tS730cffWTExMQYY8aMqXObAwcOGP/5z3+MXr16Gcccc4wRFxdnnHTSScatt95q/PLLL3Xud/DgQeO2224zOnToYMTGxhonnHCC8Y9//MMoLS2tte3atWuNESNGGO3btzdiYmKM1q1bGwMGDDDefPPNhlZBnaqqqowlS5YYY8aMMU466SQjKSnJkGTExMQY2dnZxvvvv9+gcv7880/jlltuMTp27GjExsYaaWlpxv33328cPHjQ6NevX416f+aZZ5z7VVZWGk8//bRx5plnGvHx8UZcXJxx8sknG7fddpvx+eef12ozwzCMefPmuWxPd236888/G5dffrmRnJxsxMfHG926dTOefvrpWttVVlYaubm5RkZGhpGcnGzExMQYHTp0MK655hrDYrHU2v7o83P8S01NbVDdVbdmzZo6z62+f66O9cMPPxgTJkwwTjzxRCMuLs5ISEgw0tPTjWnTphnl5eUNOm6/fv0Mw6i7zo++Nw4dOmRMmzbNOPXUU424uDjj2GOPNS655BLjk08+MT788ENDknHSSSfVef4vvPCC0a1bNyM2NtY47rjjjGHDhhlbtmwxDMMwHnjgAZcxPPDAA4ZhGMaYMWNcrp83b57beh82bFitMr/99lvjqquuMtq3b2/ExsYaHTt2NG666Sbj119/dVtecXGxER0dbdxwww1ut61Lfdd5Q340r6s+jm4zb+6Lzp07G+PGjTN++umnGts2ZVsBAEJDlGE0YOZNAAAQ8mbNmqUJEyZo8ODBuu2225Senq7k5GRe0w2vvP322xoxYoT69OlT55xD4eK7775T9+7dtX79evXq1SvQ4QAA4Hf81AgAQIQYP368pk6dqvfee08DBw5UmzZtdOyxxwY6LAS577//Xv/+97/rXO+YlNkxh1Y4mz17ts4880wSSACAiEUSCQCACPLYY49pxYoVGjhwYI03OAF12bJli+666y6Xo4x+//13zZ07V7GxsRo/fnwAoms627dv19ChQ52vty8rK1Nubq5uuummAEcGAEDg8NMjAAARZtCgQRo0aJAqKyudE+QC7lx++eW666671Lt3b8XHx+t///ufHn/8cf3222964YUXdNJJJwU6RJ/at2+fli1bpocffliXXHKJpk2bptatWzvfaAYAQCRiTiQAAADUaf/+/VqyZIkWL16sr7/+WsXFxdq/f7/at2+vfv36OefXCje//PKLhgwZos2bN8swDPXq1Uv/93//p27dugU6NAAAAoYkEgAAAAAAANxiTiQAAAAAAAC4RRIJAAAAAAAAbpFEAgAAAAAAgFskkQAAAAAAAOAWSSQAAAAAAAC4RRKpgUaNGqVRo0YFOgwAAAAAAICAiAl0AKFi06ZNgQ4haG3fvl2S1KlTpwBHAgDwJ/p/AIhM9P9A5GIkEgAAAAAAANwiiQQAAAAAAAC3SCIBAAAAAADALZJIAAAAAAAAcIskEgAAAAAAANwiiQQAAAAAAAC3SCIBAAAAAADALZJIAAAAAAAAcIskEgAAAAAAANwiiQQAAAAAAAC3SCIBAAAAAADALZJIAAAAAAAAcIskEgAAAAAAANwiiQQAAAAA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DMNwJp5sNptzvSRt375d55xzjnbt2qVVq1bpjz/+0BtvvCGbzabLLrusxnGLi4t1zjnn6OWXX9bzzz+v0tJSffDBB9q6dat69+6twsJC57ZFRUVas2aNJOmBBx5wHrOoqMi7igIAABGDJBIAAIALmzdvliR16tTJ7baObex2uzN55Km3335bpaWluu2229S1a1fFxcXpjDPOqDHfksPEiRO1detWPf744xo0aJDi4uJ02mmnacGCBdq7d68mTJjgVSwAAADVkUQCAABwYe/evZKkFi1auN22ZcuWzq9LS0u9Oq7jsba33367xhvfunTpUuMRteLiYi1evFhxcXG69tpra5RhNpvVs2dPffrpp85kGAAAgLdIIgEAALjQqlUrSdKBAwfcbrt//37n18nJyV4dd+TIkTr++OM1b948denSRVOnTtUXX3wh6XByyGHDhg0yDEOnnnqqmjdvXqucE044QZJksVi8igcAAMCBJBIAAIALJ598sqTDcxS549gmLi7O64mq27Vrp6+++kq333679u/fr8cff1y9e/fW6aefrry8POd2jpFSGzdudE6SXf3f22+/LUnatWuXV/EAAAA4kEQCAABwYfDgwZKk9evXu932888/lyRlZGTUeLTNU+3atdP06dNVXFysFStW6Oqrr9a3336ryy67TOvWrZN0ZMTT+eef75wk29W/W2+91et4AAAAJJJIAAAALo0cOVKpqalat26dtm3bVu+2L730kiRpypQpXh9306ZN+u677yRJMTExGjRokBYtWqR//etfMgzDOcKoV69eatasWZ1vVysrK9OKFSu0Z88e5zLHfEsAAACeIIkEAADgQvPmzfXKK68oOjpaEyZMUEVFhcvtcnNztWbNGt18883q37+/18dduHChHnzwwVrLu3fvLunIRN/t2rXTiBEjtGPHDn3wwQe1tn/++ec1cuRIxcXFOZe1bt1aklReXu78/7TTTtOHH37oddwAACD8kUQCAACowwUXXKClS5fq888/V0ZGhlauXKm9e/fq4MGD+uabb3T77bfrxhtv1D/+8Q899dRTPjvum2++qZkzZ+rXX39VeXm5NmzYoH/961865phjNHbsWOd2zz77rE4++WSNHj1ab7/9tv744w/99ttvevbZZ3XPPfdoxowZSkxMdG5vNpuVnJysTz/9VPv27dOrr76qTZs2eT2PEwAAiAxRhmEYgQ4CAAAgmO3Zs0dPP/203n33XW3dulUHDx7U8ccfr379+ummm25S7969a2xvMplcPgJnGIZyc3OVnZ1da90DDzygnJwc7dy5Uy+99JKWLl2qH3/8UX/88Yc6dOigfv366a677nJO+O1QUlKixx57TG+99ZZ+/vlnHXvsserRo4fuuOMODRgwoNZxli5dqqlTp8pms+n444/X3XffrRtuuMHLGgIAAJGAJBIAAAAAAADc4nE2AAAAAAAAuEUSCQAAAAAAAG6RRAIAAAAAAIBbJJEAAAAAAADgFkkkAAAAAAAAuEUSCQAAAAAAAG6RRAIAAAAAAIBbJJEAAAAAAADgFkkkAAAAAAAAuEUSCQAAAAAAAG6RRAIAAAAAAIBbJJEAAAAAAADgFkkkAAAAAAAAuEUSCQAAAAAAAG6RRAIAAAAAAIBbJJEAAAAAAADgFkkkAAAAAAAAuPX/ALCLXHq+NQ1ZAAAAAElFTkSuQmCC\n", "text/plain": [ "
" ] }, "metadata": { "image/png": { "height": 218, "width": 584 } }, "output_type": "display_data" } ], "source": [ "import music21 as m21\n", "\n", "fn = os.path.join('..', 'data', 'C1', 'FMP_C1_F12_Bach_BWV846_Sibelius-Tracks.mid')\n", "s = m21.converter.parse(fn)\n", "s.plot('pianoroll', figureSize=(10, 3))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Python Package `pypianoroll`\n", "\n", "Another package for piano roll visualizations is [`pypianoroll`](https://github.com/salu133445/pypianoroll). The functions to convert a midi file to a list of note events as well as the pianoroll visualization function have been included into `libfmp`. In the following code cell, we call those `libfmp` functions:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "execution": { "iopub.execute_input": "2024-02-15T08:45:37.913138Z", "iopub.status.busy": "2024-02-15T08:45:37.912947Z", "iopub.status.idle": "2024-02-15T08:45:38.099760Z", "shell.execute_reply": "2024-02-15T08:45:38.099151Z" } }, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "image/png": { "height": 207, "width": 568 }, "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "import sys\n", "sys.path.append('..')\n", "import libfmp.c1\n", "\n", "fn = os.path.join('..', 'data', 'C1', 'FMP_C1_F13a_Beethoven_FateMotive_Sibelius.mid')\n", "fn_out = os.path.join('..', 'output', 'C1', 'FMP_C1_F13a_Beethoven_FateMotive_Sibelius.csv')\n", "\n", "score = libfmp.c1.midi_to_list(fn)\n", "libfmp.c1.visualize_piano_roll(score, figsize=(8, 3))\n", "libfmp.c1.list_to_csv(score, fn_out)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "Acknowledgment: This notebook was created by Frank Zalkow and Meinard Müller.\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n", "
\"C0\"\"C1\"\"C2\"\"C3\"\"C4\"\"C5\"\"C6\"\"C7\"\"C8\"
" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.16" } }, "nbformat": 4, "nbformat_minor": 1 }