{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "1jC9CYFpLUFK",
    "outputId": "f38c5041-f815-472c-a9ad-a74ec2c056ee"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Requirement already satisfied: symusic in /usr/local/lib/python3.10/dist-packages (0.0.6)\n",
      "Requirement already satisfied: mido in /usr/local/lib/python3.10/dist-packages (1.3.0)\n",
      "Requirement already satisfied: pretty_midi in /usr/local/lib/python3.10/dist-packages (0.2.10)\n",
      "Requirement already satisfied: miditoolkit in /usr/local/lib/python3.10/dist-packages (1.0.1)\n",
      "Requirement already satisfied: music21 in /usr/local/lib/python3.10/dist-packages (9.1.0)\n",
      "Requirement already satisfied: numpy>=1.20 in /usr/local/lib/python3.10/dist-packages (from symusic) (1.23.5)\n",
      "Requirement already satisfied: packaging~=23.1 in /usr/local/lib/python3.10/dist-packages (from mido) (23.2)\n",
      "Requirement already satisfied: six in /usr/local/lib/python3.10/dist-packages (from pretty_midi) (1.16.0)\n",
      "Requirement already satisfied: matplotlib in /usr/local/lib/python3.10/dist-packages (from miditoolkit) (3.7.1)\n",
      "Requirement already satisfied: chardet in /usr/local/lib/python3.10/dist-packages (from music21) (5.2.0)\n",
      "Requirement already satisfied: joblib in /usr/local/lib/python3.10/dist-packages (from music21) (1.3.2)\n",
      "Requirement already satisfied: jsonpickle in /usr/local/lib/python3.10/dist-packages (from music21) (3.0.2)\n",
      "Requirement already satisfied: more-itertools in /usr/local/lib/python3.10/dist-packages (from music21) (10.1.0)\n",
      "Requirement already satisfied: requests in /usr/local/lib/python3.10/dist-packages (from music21) (2.31.0)\n",
      "Requirement already satisfied: webcolors>=1.5 in /usr/local/lib/python3.10/dist-packages (from music21) (1.13)\n",
      "Requirement already satisfied: contourpy>=1.0.1 in /usr/local/lib/python3.10/dist-packages (from matplotlib->miditoolkit) (1.2.0)\n",
      "Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.10/dist-packages (from matplotlib->miditoolkit) (0.12.1)\n",
      "Requirement already satisfied: fonttools>=4.22.0 in /usr/local/lib/python3.10/dist-packages (from matplotlib->miditoolkit) (4.44.3)\n",
      "Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.10/dist-packages (from matplotlib->miditoolkit) (1.4.5)\n",
      "Requirement already satisfied: pillow>=6.2.0 in /usr/local/lib/python3.10/dist-packages (from matplotlib->miditoolkit) (9.4.0)\n",
      "Requirement already satisfied: pyparsing>=2.3.1 in /usr/local/lib/python3.10/dist-packages (from matplotlib->miditoolkit) (3.1.1)\n",
      "Requirement already satisfied: python-dateutil>=2.7 in /usr/local/lib/python3.10/dist-packages (from matplotlib->miditoolkit) (2.8.2)\n",
      "Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests->music21) (3.3.2)\n",
      "Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests->music21) (3.4)\n",
      "Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests->music21) (2.0.7)\n",
      "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.10/dist-packages (from requests->music21) (2023.7.22)\n"
     ]
    }
   ],
   "source": [
    "!pip install symusic mido pretty_midi miditoolkit music21 matplotlib"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "oygHeqhtLUFM",
    "outputId": "09aad19a-783f-4288-8dd3-b568c9b983c7"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "--2023-11-26 16:29:28--  https://github.com/lzqlzzq/minimidi/raw/main/example/mahler.mid\n",
      "Resolving github.com (github.com)... 20.29.134.23\n",
      "Connecting to github.com (github.com)|20.29.134.23|:443... connected.\n",
      "HTTP request sent, awaiting response... 302 Found\n",
      "Location: https://raw.githubusercontent.com/lzqlzzq/minimidi/main/example/mahler.mid [following]\n",
      "--2023-11-26 16:29:28--  https://raw.githubusercontent.com/lzqlzzq/minimidi/main/example/mahler.mid\n",
      "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...\n",
      "Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.\n",
      "HTTP request sent, awaiting response... 200 OK\n",
      "Length: 478769 (468K) [audio/midi]\n",
      "Saving to: ‘mahler.mid.4’\n",
      "\n",
      "mahler.mid.4        100%[===================>] 467.55K  --.-KB/s    in 0.03s   \n",
      "\n",
      "2023-11-26 16:29:28 (15.4 MB/s) - ‘mahler.mid.4’ saved [478769/478769]\n",
      "\n"
     ]
    }
   ],
   "source": [
    "!wget https://github.com/lzqlzzq/minimidi/raw/main/example/mahler.mid"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "gPtW8uG4LUFN"
   },
   "source": [
    "# Load MIDI File\n",
    "\n",
    "* print each objects in symusic could get the corresponding summaries\n",
    "* Time unit is a quarter.\n",
    "* A *pyi* file have been generated, you can browse the members and functions of each class in it."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "lO5sIUDOLUFO",
    "outputId": "8c48c5c7-84c6-4106-97e6-e6f3fcfb36bf"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "note_num:  60411\n",
      "start_time:  780\n",
      "end_time:  1431755\n"
     ]
    }
   ],
   "source": [
    "from symusic import Score\n",
    "score = Score(\"mahler.mid\")\n",
    "print(\"note_num: \", score.note_num())\n",
    "print(\"start_time: \", score.start())\n",
    "print(\"end_time: \", score.end())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "v6b6VcS3bQLT",
    "outputId": "ff8f0c88-3bb3-475a-e008-2e1d95eda2de"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "TempoTickList[Tempo(time=0, qpm=20.00, ttype=Tick), Tempo(time=720, qpm=100.00, ttype=Tick), Tempo(time=7200, qpm=120.00, ttype=Tick), Tempo(time=12960, qpm=64.00, ttype=Tick), Tempo(time=15840, qpm=60.00, ttype=Tick), Tempo(time=18000, qpm=55.00, ttype=Tick), Tempo(time=18660, qpm=20.00, ttype=Tick), Tempo(time=18720, qpm=50.00, ttype=Tick), Tempo(time=51360, qpm=40.00, ttype=Tick), Tempo(time=53280, qpm=34.00, ttype=Tick), Tempo(time=54240, qpm=20.00, ttype=Tick), Tempo(time=54720, qpm=40.00, ttype=Tick), Tempo(time=55200, qpm=34.00, ttype=Tick), Tempo(time=56160, qpm=20.00, ttype=Tick), Tempo(time=56640, qpm=40.00, ttype=Tick), Tempo(time=57120, qpm=34.00, ttype=Tick), Tempo(time=60480, qpm=50.00, ttype=Tick), Tempo(time=155040, qpm=100.00, ttype=Tick), Tempo(time=203040, qpm=109.00, ttype=Tick), Tempo(time=220320, qpm=120.00, ttype=Tick), Tempo(time=224160, qpm=140.00, ttype=Tick), Tempo(time=228000, qpm=120.00, ttype=Tick), Tempo(time=229920, qpm=109.00, ttype=Tick), Tempo(time=231840, qpm=100.00, ttype=Tick), Tempo(time=235680, qpm=69.00, ttype=Tick), Tempo(time=241440, qpm=40.00, ttype=Tick), Tempo(time=243360, qpm=50.00, ttype=Tick), Tempo(time=250920, qpm=20.00, ttype=Tick), Tempo(time=251040, qpm=50.00, ttype=Tick), Tempo(time=266400, qpm=60.00, ttype=Tick), Tempo(time=277920, qpm=50.00, ttype=Tick), Tempo(time=335520, qpm=40.00, ttype=Tick), Tempo(time=337440, qpm=34.00, ttype=Tick), Tempo(time=339360, qpm=30.00, ttype=Tick), Tempo(time=341280, qpm=40.00, ttype=Tick), Tempo(time=343200, qpm=34.00, ttype=Tick), Tempo(time=344160, qpm=40.00, ttype=Tick), Tempo(time=345000, qpm=120.00, ttype=Tick), Tempo(time=432480, qpm=109.00, ttype=Tick), Tempo(time=444000, qpm=120.00, ttype=Tick), Tempo(time=522720, qpm=100.00, ttype=Tick), Tempo(time=561120, qpm=80.00, ttype=Tick), Tempo(time=562080, qpm=60.00, ttype=Tick), Tempo(time=562560, qpm=40.00, ttype=Tick), Tempo(time=562920, qpm=20.00, ttype=Tick), Tempo(time=563040, qpm=120.00, ttype=Tick), Tempo(time=589920, qpm=80.00, ttype=Tick), Tempo(time=591840, qpm=109.00, ttype=Tick), Tempo(time=622080, qpm=120.00, ttype=Tick), Tempo(time=684960, qpm=123.00, ttype=Tick), Tempo(time=686880, qpm=128.00, ttype=Tick), Tempo(time=688800, qpm=132.00, ttype=Tick), Tempo(time=690720, qpm=136.00, ttype=Tick), Tempo(time=692640, qpm=140.00, ttype=Tick), Tempo(time=694560, qpm=142.00, ttype=Tick), Tempo(time=696480, qpm=143.00, ttype=Tick), Tempo(time=698400, qpm=145.00, ttype=Tick), Tempo(time=700320, qpm=148.00, ttype=Tick), Tempo(time=702240, qpm=150.00, ttype=Tick), Tempo(time=704160, qpm=151.00, ttype=Tick), Tempo(time=706080, qpm=154.00, ttype=Tick), Tempo(time=708000, qpm=156.00, ttype=Tick), Tempo(time=709920, qpm=157.00, ttype=Tick), Tempo(time=711840, qpm=160.00, ttype=Tick), Tempo(time=713760, qpm=162.00, ttype=Tick), Tempo(time=719520, qpm=163.00, ttype=Tick), Tempo(time=721440, qpm=165.00, ttype=Tick), Tempo(time=723360, qpm=167.00, ttype=Tick), Tempo(time=725280, qpm=170.00, ttype=Tick), Tempo(time=727200, qpm=172.00, ttype=Tick), Tempo(time=729120, qpm=173.00, ttype=Tick), Tempo(time=731040, qpm=176.00, ttype=Tick), Tempo(time=732960, qpm=177.00, ttype=Tick), Tempo(time=734880, qpm=180.00, ttype=Tick), Tempo(time=736800, qpm=185.00, ttype=Tick), Tempo(time=738720, qpm=190.00, ttype=Tick), Tempo(time=740640, qpm=195.00, ttype=Tick), Tempo(time=742560, qpm=200.00, ttype=Tick), Tempo(time=750240, qpm=190.00, ttype=Tick), Tempo(time=752160, qpm=180.00, ttype=Tick), Tempo(time=754080, qpm=170.00, ttype=Tick), Tempo(time=756000, qpm=160.00, ttype=Tick), Tempo(time=757920, qpm=150.00, ttype=Tick), Tempo(time=759840, qpm=140.00, ttype=Tick), Tempo(time=761760, qpm=130.00, ttype=Tick), Tempo(time=763680, qpm=120.00, ttype=Tick), Tempo(time=765360, qpm=20.00, ttype=Tick), Tempo(time=765600, qpm=80.00, ttype=Tick), Tempo(time=823200, qpm=34.00, ttype=Tick), Tempo(time=834720, qpm=60.00, ttype=Tick), Tempo(time=836160, qpm=100.00, ttype=Tick), Tempo(time=844320, qpm=34.00, ttype=Tick), Tempo(time=849120, qpm=100.00, ttype=Tick), Tempo(time=850080, qpm=80.00, ttype=Tick), Tempo(time=850800, qpm=34.00, ttype=Tick), Tempo(time=854640, qpm=100.00, ttype=Tick), Tempo(time=856065, qpm=34.00, ttype=Tick), Tempo(time=860400, qpm=100.00, ttype=Tick), Tempo(time=866190, qpm=34.00, ttype=Tick), Tempo(time=866640, qpm=89.00, ttype=Tick), Tempo(time=868080, qpm=60.00, ttype=Tick), Tempo(time=868560, qpm=34.00, ttype=Tick), Tempo(time=871920, qpm=20.00, ttype=Tick), Tempo(time=872430, qpm=34.00, ttype=Tick), Tempo(time=872640, qpm=20.00, ttype=Tick), Tempo(time=873120, qpm=50.00, ttype=Tick), Tempo(time=873830, qpm=34.00, ttype=Tick), Tempo(time=874635, qpm=20.00, ttype=Tick), Tempo(time=874800, qpm=34.00, ttype=Tick), Tempo(time=876240, qpm=20.00, ttype=Tick), Tempo(time=878160, qpm=45.00, ttype=Tick), Tempo(time=880080, qpm=25.00, ttype=Tick), Tempo(time=882000, qpm=45.00, ttype=Tick), Tempo(time=883920, qpm=25.00, ttype=Tick), Tempo(time=885840, qpm=45.00, ttype=Tick), Tempo(time=894960, qpm=25.00, ttype=Tick), Tempo(time=895440, qpm=45.00, ttype=Tick), Tempo(time=897840, qpm=25.00, ttype=Tick), Tempo(time=900240, qpm=45.00, ttype=Tick), Tempo(time=903600, qpm=25.00, ttype=Tick), Tempo(time=905040, qpm=45.00, ttype=Tick), Tempo(time=917040, qpm=50.00, ttype=Tick), Tempo(time=947760, qpm=46.00, ttype=Tick), Tempo(time=949680, qpm=45.00, ttype=Tick), Tempo(time=951600, qpm=42.00, ttype=Tick), Tempo(time=953520, qpm=45.00, ttype=Tick), Tempo(time=959280, qpm=25.00, ttype=Tick), Tempo(time=960720, qpm=45.00, ttype=Tick), Tempo(time=969360, qpm=25.00, ttype=Tick), Tempo(time=970320, qpm=45.00, ttype=Tick), Tempo(time=972720, qpm=25.00, ttype=Tick), Tempo(time=975120, qpm=45.00, ttype=Tick), Tempo(time=987600, qpm=25.00, ttype=Tick), Tempo(time=988560, qpm=45.00, ttype=Tick), Tempo(time=994320, qpm=55.00, ttype=Tick), Tempo(time=1015440, qpm=50.00, ttype=Tick), Tempo(time=1021200, qpm=55.00, ttype=Tick), Tempo(time=1040400, qpm=109.00, ttype=Tick), Tempo(time=1071120, qpm=100.00, ttype=Tick), Tempo(time=1109520, qpm=102.00, ttype=Tick), Tempo(time=1111440, qpm=104.00, ttype=Tick), Tempo(time=1113360, qpm=105.00, ttype=Tick), Tempo(time=1115280, qpm=107.00, ttype=Tick), Tempo(time=1121040, qpm=109.00, ttype=Tick), Tempo(time=1145520, qpm=89.00, ttype=Tick), Tempo(time=1147440, qpm=69.00, ttype=Tick), Tempo(time=1149360, qpm=50.00, ttype=Tick), Tempo(time=1150320, qpm=30.00, ttype=Tick), Tempo(time=1151280, qpm=45.00, ttype=Tick), Tempo(time=1169490, qpm=34.00, ttype=Tick), Tempo(time=1170480, qpm=25.00, ttype=Tick), Tempo(time=1172400, qpm=45.00, ttype=Tick), Tempo(time=1174320, qpm=25.00, ttype=Tick), Tempo(time=1176240, qpm=45.00, ttype=Tick), Tempo(time=1180080, qpm=25.00, ttype=Tick), Tempo(time=1181520, qpm=60.00, ttype=Tick), Tempo(time=1184880, qpm=25.00, ttype=Tick), Tempo(time=1185330, qpm=40.00, ttype=Tick), Tempo(time=1193520, qpm=100.00, ttype=Tick), Tempo(time=1239600, qpm=94.00, ttype=Tick), Tempo(time=1247280, qpm=100.00, ttype=Tick), Tempo(time=1254960, qpm=80.00, ttype=Tick), Tempo(time=1297200, qpm=69.00, ttype=Tick), Tempo(time=1300920, qpm=20.00, ttype=Tick), Tempo(time=1301040, qpm=120.00, ttype=Tick), Tempo(time=1331760, qpm=60.00, ttype=Tick), Tempo(time=1347120, qpm=80.00, ttype=Tick), Tempo(time=1358640, qpm=69.00, ttype=Tick), Tempo(time=1360560, qpm=60.00, ttype=Tick), Tempo(time=1366320, qpm=50.00, ttype=Tick), Tempo(time=1370160, qpm=80.00, ttype=Tick), Tempo(time=1385520, qpm=120.00, ttype=Tick), Tempo(time=1408320, qpm=20.00, ttype=Tick), Tempo(time=1408560, qpm=80.00, ttype=Tick), Tempo(time=1423920, qpm=89.00, ttype=Tick), Tempo(time=1433525, qpm=89.00, ttype=Tick), Tempo(time=1435615, qpm=80.00, ttype=Tick)]\n",
      "KeySignatureTickList[KeySignature(time=0, key=0, tonality=0, ttype=Tick), KeySignature(time=7200, key=0, tonality=0, ttype=Tick), KeySignature(time=18720, key=0, tonality=0, ttype=Tick), KeySignature(time=51360, key=0, tonality=0, ttype=Tick), KeySignature(time=82080, key=0, tonality=0, ttype=Tick), KeySignature(time=103200, key=0, tonality=0, ttype=Tick), KeySignature(time=118560, key=0, tonality=0, ttype=Tick), KeySignature(time=155040, key=0, tonality=0, ttype=Tick), KeySignature(time=189600, key=0, tonality=0, ttype=Tick), KeySignature(time=220320, key=0, tonality=0, ttype=Tick), KeySignature(time=241440, key=0, tonality=0, ttype=Tick), KeySignature(time=279840, key=0, tonality=0, ttype=Tick), KeySignature(time=300960, key=0, tonality=0, ttype=Tick), KeySignature(time=320160, key=0, tonality=0, ttype=Tick), KeySignature(time=341280, key=0, tonality=0, ttype=Tick), KeySignature(time=350880, key=0, tonality=0, ttype=Tick), KeySignature(time=351840, key=0, tonality=0, ttype=Tick), KeySignature(time=371040, key=0, tonality=0, ttype=Tick), KeySignature(time=424800, key=0, tonality=0, ttype=Tick), KeySignature(time=472800, key=0, tonality=0, ttype=Tick), KeySignature(time=495840, key=0, tonality=0, ttype=Tick), KeySignature(time=538080, key=0, tonality=0, ttype=Tick), KeySignature(time=563040, key=0, tonality=0, ttype=Tick), KeySignature(time=591840, key=0, tonality=0, ttype=Tick), KeySignature(time=624480, key=0, tonality=0, ttype=Tick), KeySignature(time=625920, key=0, tonality=0, ttype=Tick), KeySignature(time=628800, key=0, tonality=0, ttype=Tick), KeySignature(time=630240, key=0, tonality=0, ttype=Tick), KeySignature(time=636000, key=0, tonality=0, ttype=Tick), KeySignature(time=637440, key=0, tonality=0, ttype=Tick), KeySignature(time=640320, key=0, tonality=0, ttype=Tick), KeySignature(time=642240, key=0, tonality=0, ttype=Tick), KeySignature(time=643680, key=0, tonality=0, ttype=Tick), KeySignature(time=647520, key=0, tonality=0, ttype=Tick), KeySignature(time=648960, key=0, tonality=0, ttype=Tick), KeySignature(time=650880, key=0, tonality=0, ttype=Tick), KeySignature(time=652320, key=0, tonality=0, ttype=Tick), KeySignature(time=658080, key=0, tonality=0, ttype=Tick), KeySignature(time=659520, key=0, tonality=0, ttype=Tick), KeySignature(time=661440, key=0, tonality=0, ttype=Tick), KeySignature(time=662880, key=0, tonality=0, ttype=Tick), KeySignature(time=664800, key=0, tonality=0, ttype=Tick), KeySignature(time=666240, key=0, tonality=0, ttype=Tick), KeySignature(time=673920, key=0, tonality=0, ttype=Tick), KeySignature(time=678240, key=0, tonality=0, ttype=Tick), KeySignature(time=682080, key=0, tonality=0, ttype=Tick), KeySignature(time=684960, key=0, tonality=0, ttype=Tick), KeySignature(time=692640, key=0, tonality=0, ttype=Tick), KeySignature(time=721440, key=0, tonality=0, ttype=Tick), KeySignature(time=765600, key=0, tonality=0, ttype=Tick), KeySignature(time=796320, key=0, tonality=0, ttype=Tick), KeySignature(time=823200, key=0, tonality=0, ttype=Tick), KeySignature(time=836640, key=0, tonality=0, ttype=Tick), KeySignature(time=850080, key=0, tonality=0, ttype=Tick), KeySignature(time=850800, key=0, tonality=0, ttype=Tick), KeySignature(time=860400, key=0, tonality=0, ttype=Tick), KeySignature(time=863280, key=0, tonality=0, ttype=Tick), KeySignature(time=866640, key=0, tonality=0, ttype=Tick), KeySignature(time=868560, key=0, tonality=0, ttype=Tick), KeySignature(time=874320, key=0, tonality=0, ttype=Tick), KeySignature(time=878160, key=0, tonality=0, ttype=Tick), KeySignature(time=891600, key=0, tonality=0, ttype=Tick), KeySignature(time=895920, key=0, tonality=0, ttype=Tick), KeySignature(time=899760, key=0, tonality=0, ttype=Tick), KeySignature(time=917040, key=0, tonality=0, ttype=Tick), KeySignature(time=934320, key=0, tonality=0, ttype=Tick), KeySignature(time=953520, key=0, tonality=0, ttype=Tick), KeySignature(time=954480, key=0, tonality=0, ttype=Tick), KeySignature(time=957360, key=0, tonality=0, ttype=Tick), KeySignature(time=959280, key=0, tonality=0, ttype=Tick), KeySignature(time=960720, key=0, tonality=0, ttype=Tick), KeySignature(time=961680, key=0, tonality=0, ttype=Tick), KeySignature(time=964560, key=0, tonality=0, ttype=Tick), KeySignature(time=965520, key=0, tonality=0, ttype=Tick), KeySignature(time=969360, key=0, tonality=0, ttype=Tick), KeySignature(time=970800, key=0, tonality=0, ttype=Tick), KeySignature(time=974640, key=0, tonality=0, ttype=Tick), KeySignature(time=980400, key=0, tonality=0, ttype=Tick), KeySignature(time=981840, key=0, tonality=0, ttype=Tick), KeySignature(time=991440, key=0, tonality=0, ttype=Tick), KeySignature(time=994320, key=0, tonality=0, ttype=Tick), KeySignature(time=1021200, key=0, tonality=0, ttype=Tick), KeySignature(time=1040400, key=0, tonality=0, ttype=Tick), KeySignature(time=1082640, key=0, tonality=0, ttype=Tick), KeySignature(time=1121040, key=0, tonality=0, ttype=Tick), KeySignature(time=1144080, key=0, tonality=0, ttype=Tick), KeySignature(time=1145520, key=0, tonality=0, ttype=Tick), KeySignature(time=1151280, key=0, tonality=0, ttype=Tick), KeySignature(time=1172400, key=0, tonality=0, ttype=Tick), KeySignature(time=1193520, key=0, tonality=0, ttype=Tick), KeySignature(time=1224240, key=0, tonality=0, ttype=Tick), KeySignature(time=1254960, key=0, tonality=0, ttype=Tick), KeySignature(time=1301040, key=0, tonality=0, ttype=Tick), KeySignature(time=1331760, key=0, tonality=0, ttype=Tick), KeySignature(time=1358640, key=0, tonality=0, ttype=Tick), KeySignature(time=1385520, key=0, tonality=0, ttype=Tick), KeySignature(time=1408560, key=0, tonality=0, ttype=Tick)]\n",
      "TimeSignatureTickList[TimeSignature(time=0, numerator=3, denominator=8, ttype=Tick), TimeSignature(time=7200, numerator=3, denominator=8, ttype=Tick), TimeSignature(time=18720, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=51360, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=82080, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=103200, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=118560, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=155040, numerator=2, denominator=2, ttype=Tick), TimeSignature(time=189600, numerator=2, denominator=2, ttype=Tick), TimeSignature(time=220320, numerator=2, denominator=2, ttype=Tick), TimeSignature(time=241440, numerator=2, denominator=2, ttype=Tick), TimeSignature(time=279840, numerator=2, denominator=2, ttype=Tick), TimeSignature(time=300960, numerator=2, denominator=2, ttype=Tick), TimeSignature(time=320160, numerator=2, denominator=2, ttype=Tick), TimeSignature(time=341280, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=350880, numerator=2, denominator=4, ttype=Tick), TimeSignature(time=351840, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=371040, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=424800, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=472800, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=495840, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=538080, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=563040, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=591840, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=624480, numerator=3, denominator=4, ttype=Tick), TimeSignature(time=625920, numerator=6, denominator=4, ttype=Tick), TimeSignature(time=628800, numerator=3, denominator=4, ttype=Tick), TimeSignature(time=630240, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=636000, numerator=3, denominator=4, ttype=Tick), TimeSignature(time=637440, numerator=6, denominator=4, ttype=Tick), TimeSignature(time=640320, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=642240, numerator=3, denominator=4, ttype=Tick), TimeSignature(time=643680, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=647520, numerator=3, denominator=4, ttype=Tick), TimeSignature(time=648960, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=650880, numerator=3, denominator=4, ttype=Tick), TimeSignature(time=652320, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=658080, numerator=3, denominator=4, ttype=Tick), TimeSignature(time=659520, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=661440, numerator=3, denominator=4, ttype=Tick), TimeSignature(time=662880, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=664800, numerator=3, denominator=4, ttype=Tick), TimeSignature(time=666240, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=673920, numerator=3, denominator=4, ttype=Tick), TimeSignature(time=678240, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=682080, numerator=3, denominator=4, ttype=Tick), TimeSignature(time=684960, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=692640, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=721440, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=765600, numerator=2, denominator=2, ttype=Tick), TimeSignature(time=796320, numerator=2, denominator=2, ttype=Tick), TimeSignature(time=823200, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=836640, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=850080, numerator=3, denominator=8, ttype=Tick), TimeSignature(time=850800, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=860400, numerator=6, denominator=4, ttype=Tick), TimeSignature(time=863280, numerator=7, denominator=4, ttype=Tick), TimeSignature(time=866640, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=868560, numerator=6, denominator=4, ttype=Tick), TimeSignature(time=874320, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=878160, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=891600, numerator=3, denominator=4, ttype=Tick), TimeSignature(time=895920, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=899760, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=917040, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=934320, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=953520, numerator=2, denominator=4, ttype=Tick), TimeSignature(time=954480, numerator=3, denominator=4, ttype=Tick), TimeSignature(time=957360, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=959280, numerator=3, denominator=4, ttype=Tick), TimeSignature(time=960720, numerator=2, denominator=4, ttype=Tick), TimeSignature(time=961680, numerator=3, denominator=4, ttype=Tick), TimeSignature(time=964560, numerator=2, denominator=4, ttype=Tick), TimeSignature(time=965520, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=969360, numerator=3, denominator=4, ttype=Tick), TimeSignature(time=970800, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=974640, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=980400, numerator=3, denominator=4, ttype=Tick), TimeSignature(time=981840, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=991440, numerator=6, denominator=4, ttype=Tick), TimeSignature(time=994320, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=1021200, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=1040400, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=1082640, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=1121040, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=1144080, numerator=3, denominator=4, ttype=Tick), TimeSignature(time=1145520, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=1151280, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=1172400, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=1193520, numerator=2, denominator=2, ttype=Tick), TimeSignature(time=1224240, numerator=2, denominator=2, ttype=Tick), TimeSignature(time=1254960, numerator=2, denominator=2, ttype=Tick), TimeSignature(time=1301040, numerator=2, denominator=2, ttype=Tick), TimeSignature(time=1331760, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=1358640, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=1385520, numerator=4, denominator=4, ttype=Tick), TimeSignature(time=1408560, numerator=2, denominator=2, ttype=Tick)]\n"
     ]
    }
   ],
   "source": [
    "print(score.tempos)\n",
    "print(score.key_signatures)\n",
    "print(score.time_signatures)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "FYkaBzW-LUFP",
    "outputId": "632e695a-c9c6-415e-d704-d71d019f4c24"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Tempo(time=0, qpm=20.00, ttype=Tick)\n",
      "KeySignature(time=0, key=0, tonality=0, ttype=Tick)\n",
      "TimeSignature(time=0, numerator=3, denominator=8, ttype=Tick)\n"
     ]
    }
   ],
   "source": [
    "print(score.tempos[0])\n",
    "print(score.key_signatures[0])\n",
    "print(score.time_signatures[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "XdzfTIMULUFP",
    "outputId": "4eef7993-dfee-4550-84d6-ec1cd49cf5d0"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "track name:  PICCOLO\n",
      "is_drum:  False\n",
      "note_num:  1053\n",
      "start:  2160\n",
      "end:  1431755\n",
      "notes[0]:  Note(time=2160, duration=4895, pitch=106, velocity=111, ttype=Tick)\n",
      "notes[-1]:  Note(time=1423920, duration=7835, pitch=99, velocity=111, ttype=Tick)\n"
     ]
    }
   ],
   "source": [
    "print(\"track name: \", score.tracks[0].name)\n",
    "print(\"is_drum: \", score.tracks[0].is_drum)\n",
    "print(\"note_num: \", score.tracks[0].note_num())\n",
    "print(\"start: \", score.tracks[0].start())\n",
    "print(\"end: \", score.tracks[0].end())\n",
    "print(\"notes[0]: \", score.tracks[0].notes[0])\n",
    "print(\"notes[-1]: \", score.tracks[0].notes[-1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "yrl6VKzwLUFQ",
    "outputId": "cbdb5d73-d13a-40fa-95c9-29d780adbedc"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "start:\t\t 2160\n",
      "duration:\t 4895\n",
      "pitch:\t\t 106\n",
      "velocity:\t 111\n"
     ]
    }
   ],
   "source": [
    "note = score.tracks[0].notes[0]\n",
    "print(\"start:\\t\\t\", note.start)\n",
    "print(\"duration:\\t\", note.duration)\n",
    "print(\"pitch:\\t\\t\", note.pitch)\n",
    "print(\"velocity:\\t\", note.velocity)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "iaOZNxk6Yp88"
   },
   "source": [
    "# Batch Processing\n",
    "\n",
    "* sort\n",
    "* shift_time\n",
    "* shift_pitch\n",
    "* shift_velocity\n",
    "* clip(start: float, end: float, clip_end: bool)\n",
    "* filter_notes(func: Callable)\n",
    "* note_array"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "PYn1Fc9MYpGx",
    "outputId": "7763477f-c5ee-4799-acbe-a81fce3567a0"
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "IOPub data rate exceeded.\n",
      "The notebook server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--NotebookApp.iopub_data_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "NotebookApp.iopub_data_rate_limit=1000000.0 (bytes/sec)\n",
      "NotebookApp.rate_limit_window=3.0 (secs)\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# inplace operation\n",
    "print(score.sort())\n",
    "print(score.tracks[0].sort())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "0u3hr6AGZFnR",
    "outputId": "db303e7b-8ea7-49d8-e6ae-f53400c4094c"
   },
   "outputs": [],
   "source": [
    "# method chaining\n",
    "score.shift_time(10) \\\n",
    "     .shift_pitch(-6) \\\n",
    "     .shift_velocity(-7) \\\n",
    "     .sort()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "GGcz6q0yZoh6",
    "outputId": "4e22d9d7-467f-41cb-df90-08118fe1897e"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Track(name=\"PICCOLO\", program=73, is_drum=False, ttype=Tick, notes=[Note(time=12960, duration=575, pitch=94, velocity=111, ttype=Tick), Note(time=13680, duration=575, pitch=92, velocity=111, ttype=Tick), Note(time=14400, duration=575, pitch=91, velocity=111, ttype=Tick), Note(time=15120, duration=575, pitch=89, velocity=111, ttype=Tick), Note(time=15840, duration=575, pitch=91, velocity=111, ttype=Tick), Note(time=16560, duration=575, pitch=89, velocity=111, ttype=Tick), Note(time=17280, duration=575, pitch=87, velocity=111, ttype=Tick), Note(time=18000, duration=575, pitch=85, velocity=111, ttype=Tick), Note(time=18720, duration=1150, pitch=84, velocity=31, ttype=Tick), Note(time=23520, duration=575, pitch=79, velocity=31, ttype=Tick), Note(time=23520, duration=575, pitch=67, velocity=31, ttype=Tick), Note(time=24240, duration=430, pitch=60, velocity=31, ttype=Tick), Note(time=24240, duration=430, pitch=72, velocity=31, ttype=Tick), Note(time=24720, duration=190, pitch=62, velocity=31, ttype=Tick), Note(time=24720, duration=190, pitch=74, velocity=31, ttype=Tick), Note(time=24960, duration=190, pitch=76, velocity=31, ttype=Tick), Note(time=24960, duration=190, pitch=64, velocity=31, ttype=Tick), Note(time=25200, duration=190, pitch=77, velocity=31, ttype=Tick), Note(time=25200, duration=190, pitch=65, velocity=31, ttype=Tick), Note(time=25440, duration=1150, pitch=67, velocity=31, ttype=Tick), Note(time=25440, duration=1150, pitch=79, velocity=31, ttype=Tick), Note(time=28320, duration=960, pitch=79, velocity=31, ttype=Tick), Note(time=28320, duration=960, pitch=67, velocity=31, ttype=Tick), Note(time=29280, duration=770, pitch=81, velocity=31, ttype=Tick), Note(time=29280, duration=770, pitch=69, velocity=31, ttype=Tick), Note(time=30240, duration=960, pitch=67, velocity=31, ttype=Tick), Note(time=30240, duration=960, pitch=79, velocity=31, ttype=Tick), Note(time=31200, duration=770, pitch=81, velocity=31, ttype=Tick), Note(time=31200, duration=770, pitch=69, velocity=31, ttype=Tick), Note(time=32160, duration=960, pitch=72, velocity=31, ttype=Tick), Note(time=32160, duration=1535, pitch=79, velocity=31, ttype=Tick), Note(time=33120, duration=770, pitch=74, velocity=31, ttype=Tick), Note(time=34080, duration=770, pitch=79, velocity=31, ttype=Tick), Note(time=34080, duration=770, pitch=72, velocity=31, ttype=Tick), Note(time=36000, duration=770, pitch=79, velocity=31, ttype=Tick), Note(time=36000, duration=770, pitch=72, velocity=31, ttype=Tick)], controls=[], pitch_bends=[], pedals=[])"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "score.tracks[1].clip(1000, 100000, True) # start: float, end: float, clip_end: bool"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "eiU2D9XDc30t",
    "outputId": "e284d341-c07d-49dd-e64f-6aba03ae9566"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "frame_pianoroll float32 (1, 128, 5966)\n",
      "onset_pianoroll float32 (1, 128, 5966)\n",
      "both_pianoroll float32 (2, 128, 5966)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.image.AxesImage at 0x7f6e78bb0190>"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 37016 characters]",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from matplotlib import pyplot as plt\n",
    "\n",
    "frame_pianoroll = score.tracks[10].pianoroll(960 / 4, 'frame')\n",
    "print(\"frame_pianoroll\", frame_pianoroll.dtype, frame_pianoroll.shape)\n",
    "onset_pianoroll = score.tracks[10].pianoroll(960 / 4, 'onset')\n",
    "print(\"onset_pianoroll\", onset_pianoroll.dtype, onset_pianoroll.shape)\n",
    "pianoroll = score.tracks[10].pianoroll(960 / 4, 'both')\n",
    "print(\"both_pianoroll\", pianoroll.dtype, pianoroll.shape)\n",
    "plt.imshow(frame_pianoroll[0], aspect='auto')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "TunMY7rGLUFQ"
   },
   "source": [
    "# Benchmark\n",
    "\n",
    "## MIDI Parsing\n",
    "\n",
    "* mido is writen in pure python, and only parsing midi file to event level\n",
    "* pretty_midi and miditoolkit is based on mido"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "ihVpllc6LUFQ",
    "outputId": "30e3d4c7-0975-422b-d984-5f8378445a3b"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Requirement already satisfied: jill in /usr/local/lib/python3.10/dist-packages (0.11.5)\n",
      "Requirement already satisfied: fire<0.6.0,>=0.5.0 in /usr/local/lib/python3.10/dist-packages (from jill) (0.5.0)\n",
      "Requirement already satisfied: jsonschema<5.0.0,>=4.17.3 in /usr/local/lib/python3.10/dist-packages (from jill) (4.19.2)\n",
      "Requirement already satisfied: python-gnupg<0.6.0,>=0.5.0 in /usr/local/lib/python3.10/dist-packages (from jill) (0.5.1)\n",
      "Requirement already satisfied: requests<3.0.0,>=2.28.2 in /usr/local/lib/python3.10/dist-packages (from jill) (2.31.0)\n",
      "Requirement already satisfied: requests-futures<2.0.0,>=1.0.0 in /usr/local/lib/python3.10/dist-packages (from jill) (1.0.1)\n",
      "Requirement already satisfied: semantic-version<3.0.0,>=2.10.0 in /usr/local/lib/python3.10/dist-packages (from jill) (2.10.0)\n",
      "Requirement already satisfied: wget<4.0,>=3.2 in /usr/local/lib/python3.10/dist-packages (from jill) (3.2)\n",
      "Requirement already satisfied: six in /usr/local/lib/python3.10/dist-packages (from fire<0.6.0,>=0.5.0->jill) (1.16.0)\n",
      "Requirement already satisfied: termcolor in /usr/local/lib/python3.10/dist-packages (from fire<0.6.0,>=0.5.0->jill) (2.3.0)\n",
      "Requirement already satisfied: attrs>=22.2.0 in /usr/local/lib/python3.10/dist-packages (from jsonschema<5.0.0,>=4.17.3->jill) (23.1.0)\n",
      "Requirement already satisfied: jsonschema-specifications>=2023.03.6 in /usr/local/lib/python3.10/dist-packages (from jsonschema<5.0.0,>=4.17.3->jill) (2023.11.1)\n",
      "Requirement already satisfied: referencing>=0.28.4 in /usr/local/lib/python3.10/dist-packages (from jsonschema<5.0.0,>=4.17.3->jill) (0.31.0)\n",
      "Requirement already satisfied: rpds-py>=0.7.1 in /usr/local/lib/python3.10/dist-packages (from jsonschema<5.0.0,>=4.17.3->jill) (0.13.0)\n",
      "Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests<3.0.0,>=2.28.2->jill) (3.3.2)\n",
      "Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests<3.0.0,>=2.28.2->jill) (3.4)\n",
      "Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests<3.0.0,>=2.28.2->jill) (2.0.7)\n",
      "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.10/dist-packages (from requests<3.0.0,>=2.28.2->jill) (2023.7.22)\n",
      "\u001b[1mJILL - Julia Installer 4 Linux (MacOS, Windows and FreeBSD) -- Light\u001b[0m\n",
      "\n",
      "\u001b[92mquerying release information from https://julialang-s3.julialang.org/bin/versions.json\u001b[0m\n",
      "julia 1.9.4 already installed.\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "# install julia for testing MIDI.jl\n",
    "!pip install jill\n",
    "!jill install -c True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "id": "KKKW8JljLUFR"
   },
   "outputs": [],
   "source": [
    "import mido, music21\n",
    "import pretty_midi as pm\n",
    "import miditoolkit as mtk\n",
    "p = \"mahler.mid\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "id": "AwG9h0wPMsSh"
   },
   "outputs": [],
   "source": [
    "# %%timeit\n",
    "# midi_jl.load(p)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "BZ7zTxdGLUFR",
    "outputId": "e451a265-42fd-47fc-b48d-5c83a94dc14d"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "23.3 ms ± 12.3 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)\n"
     ]
    }
   ],
   "source": [
    "%%timeit\n",
    "Score(p)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "PFPvSmJBLUFS",
    "outputId": "534187bb-c8c3-4a61-bf57-56fb34be2c86"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "7.15 s ± 2.11 s per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
     ]
    }
   ],
   "source": [
    "%%timeit\n",
    "# mido is writen in pure python, and only parsing midi file to event level\n",
    "mido.MidiFile(p)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "wGJ0OnE6LUFS",
    "outputId": "0479eff7-3dc4-479d-f02b-f09734e7f928"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "7.1 s ± 1.64 s per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
     ]
    }
   ],
   "source": [
    "%%timeit\n",
    "pm.PrettyMIDI(p)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "kTF9cTUBLUFT",
    "outputId": "6fbf0963-1329-47d7-ccc9-227b8914b9f1"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "6.73 s ± 1.54 s per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
     ]
    }
   ],
   "source": [
    "%%timeit\n",
    "mtk.MidiFile(p)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "4aRmyoYPLUFT",
    "outputId": "effd7541-df89-4c87-8618-325d2073664c"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10.2 s ± 558 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
     ]
    }
   ],
   "source": [
    "%%timeit\n",
    "music21.converter.parse(p)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "id": "f2-NDVlELUFT"
   },
   "outputs": [],
   "source": [
    "jl_script = f\"\"\"\n",
    "import Pkg\n",
    "Pkg.add(\"MIDI\")\n",
    "Pkg.add(\"BenchmarkTools\")\n",
    "using BenchmarkTools\n",
    "using MIDI\n",
    "b = @benchmark load(\"{p}\")\n",
    "println(\"first run: \", b)\n",
    "b = @benchmark load(\"{p}\")\n",
    "println(\"scecond run: \", b)\n",
    "\"\"\"\n",
    "with open(\"bench.jl\", \"w\") as f:\n",
    "  f.write(jl_script)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "NJPsOcRDSxdg",
    "outputId": "34ba1bfc-320c-4b33-eb58-6a67a69fd31b"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[32m\u001b[1m   Resolving\u001b[22m\u001b[39m package versions...\n",
      "\u001b[32m\u001b[1m  No Changes\u001b[22m\u001b[39m to `~/.julia/environments/v1.9/Project.toml`\n",
      "\u001b[32m\u001b[1m  No Changes\u001b[22m\u001b[39m to `~/.julia/environments/v1.9/Manifest.toml`\n",
      "\u001b[?25l\u001b[?25h\u001b[2K\u001b[?25h\u001b[32m\u001b[1m   Resolving\u001b[22m\u001b[39m package versions...\n",
      "\u001b[32m\u001b[1m  No Changes\u001b[22m\u001b[39m to `~/.julia/environments/v1.9/Project.toml`\n",
      "\u001b[32m\u001b[1m  No Changes\u001b[22m\u001b[39m to `~/.julia/environments/v1.9/Manifest.toml`\n",
      "\u001b[?25l\u001b[?25h\u001b[2K\u001b[?25hfirst run: Trial(132.627 ms)\n",
      "scecond run: Trial(132.829 ms)\n"
     ]
    }
   ],
   "source": [
    "!julia bench.jl"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "P4WwHyBwd2JC"
   },
   "source": [
    "## Bench Processing\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "id": "nl7QrFqqeA0K"
   },
   "outputs": [],
   "source": [
    "score = Score(p)\n",
    "score2 = score.copy()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "9kkPPSLYekkt",
    "outputId": "fdba9ddb-a5f2-454a-e5fc-7423c797599e"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "276 µs ± 16.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n"
     ]
    }
   ],
   "source": [
    "%%timeit\n",
    "score.copy()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "SX7QdfpQd1eW",
    "outputId": "012d0540-fe24-4ceb-972c-8f1ac9707817"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "364 µs ± 6.46 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n"
     ]
    }
   ],
   "source": [
    "%%timeit\n",
    "score.shift_pitch(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "w3mQlDdkeNbK",
    "outputId": "36028a05-3bcd-4473-e3a4-58e785f369bc"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10.3 ms ± 389 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n"
     ]
    }
   ],
   "source": [
    "%%timeit\n",
    "[(t.onset_pianoroll(960 / 4), t.frame_pianoroll(960 / 4)) for t in score.tracks]"
   ]
  }
 ],
 "metadata": {
  "colab": {
   "provenance": []
  },
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.11.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
