{"id":17083,"date":"2022-08-25T21:36:30","date_gmt":"2022-08-26T01:36:30","guid":{"rendered":"https:\/\/scruss.com\/blog\/?p=17083"},"modified":"2022-08-25T21:36:30","modified_gmt":"2022-08-26T01:36:30","slug":"micropython-midi-mayhem-kinda","status":"publish","type":"post","link":"https:\/\/scruss.com\/blog\/2022\/08\/25\/micropython-midi-mayhem-kinda\/","title":{"rendered":"MicroPython MIDI mayhem (kinda)"},"content":{"rendered":"\n<p>It pleased me to learn about <a href=\"https:\/\/github.com\/bixb922\/umidiparser\">umidiparser &#8211; MIDI file parser for Micropython<\/a>. Could I use my <a href=\"https:\/\/scruss.com\/blog\/2021\/02\/24\/nyan-cat-except-it-gets-faster-rtttl-on-the-raspberry-pi-pico\/\">previous adventures in beepy nonsense<\/a> to turn a simple MIDI file into a terrible squeaky rendition of same? You betcha!<\/p>\n\n\n\n<p>MIDI seems to be absurdly complex. In all the files I looked at, there didn&#8217;t seem to be much of a standard in encoding whether the note duration was in the NOTE_ON event or the NOTE_OFF event. Eventually, I managed to fudge a tiny single channel file that had acceptable note durations in the NOTE_OFF events. Here is the file:<\/p>\n\n\n\n<div class=\"wp-block-file\"><a id=\"wp-block-file--media-fbc4c775-cb98-40f0-8f37-e28cb3992c4e\" href=\"https:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2022\/08\/lg2.mid\">lg2.mid<\/a><a href=\"https:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2022\/08\/lg2.mid\" class=\"wp-block-file__button\" download aria-describedby=\"wp-block-file--media-fbc4c775-cb98-40f0-8f37-e28cb3992c4e\">Download<\/a><\/div>\n\n\n\n<p>I used the same setup as before:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"680\" height=\"383\" src=\"https:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2021\/02\/spkr.jpg\" alt=\"Raspberry Pi Pico with small piezo speaker connected to pins 23 and 26\" class=\"wp-image-16636\" srcset=\"https:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2021\/02\/spkr.jpg 680w, https:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2021\/02\/spkr-320x180.jpg 320w, https:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2021\/02\/spkr-160x90.jpg 160w\" sizes=\"auto, (max-width: 680px) 100vw, 680px\" \/><figcaption>piezo between pins 26 and 23<\/figcaption><\/figure>\n\n\n\n<p>With this code:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n# extremely crude MicroPython MIDI demo\n# MicroPython \/ Raspberry Pi Pico - scruss, 2022-08\n# see https:\/\/github.com\/bixb922\/umidiparser\n\nimport umidiparser\nfrom time import sleep_us\nfrom machine import Pin, PWM\n\n# pin 26 - GP20; just the right distance from GND at pin 23\n#  to use one of those PC beepers with the 4-pin headers\npwm = PWM(Pin(20))\nled = Pin(&#039;LED&#039;, Pin.OUT)\n\n\ndef play_tone(freq, usec):\n    # play RTTL\/midi notes, also flash onboard LED\n    # original idea thanks to\n    #   https:\/\/github.com\/dhylands\/upy-rtttl\n    print(&#039;freq = {:6.1f} usec = {:6.1f}&#039;.format(freq, usec))\n    if freq &gt; 0:\n        pwm.freq(int(freq))       # Set frequency\n        pwm.duty_u16(32767)       # 50% duty cycle\n    led.on()\n    sleep_us(int(0.9 * usec))     # Play for a number of usec\n    pwm.duty_u16(0)               # Stop playing for gap between notes\n    led.off()\n    sleep_us(int(0.1 * usec))     # Pause for a number of usec\n\n\n# map MIDI notes (0-127) to frequencies. Note 69 is 440 Hz (&#039;A4&#039;)\nfreqs = &#x5B;440 * 2**((float(x) - 69) \/ 12) for x in range(128)]\n\nfor event in umidiparser.MidiFile(&quot;lg2.mid&quot;, reuse_event_object=True):\n    if event.status == umidiparser.NOTE_OFF and event.channel == 0:\n        play_tone(freqs&#x5B;event.note], event.delta_us)\n\n<\/pre><\/div>\n\n\n<p>This isn&#8217;t be any means a general MIDI parser, but is rather specialized to play monophonic tunes on channel 0. The result is gloriously awful:<\/p>\n\n\n\n<figure class=\"wp-block-audio\"><audio controls src=\"https:\/\/scruss.com\/wordpress\/wp-content\/uploads\/2022\/08\/lg2-midi.mp3\"><\/audio><figcaption>apologies to LG<\/figcaption><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>It pleased me to learn about umidiparser &#8211; MIDI file parser for Micropython. Could I use my previous adventures in beepy nonsense to turn a simple MIDI file into a terrible squeaky rendition of same? You betcha! MIDI seems to be absurdly complex. In all the files I looked at, there didn&#8217;t seem to be [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[2],"tags":[3094,3221],"class_list":["post-17083","post","type-post","status-publish","format-standard","hentry","category-goatee-stroking-musing-or-something","tag-micropython","tag-midi"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/pQNZZ-4rx","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/posts\/17083","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/comments?post=17083"}],"version-history":[{"count":1,"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/posts\/17083\/revisions"}],"predecessor-version":[{"id":17086,"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/posts\/17083\/revisions\/17086"}],"wp:attachment":[{"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/media?parent=17083"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/categories?post=17083"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/scruss.com\/blog\/wp-json\/wp\/v2\/tags?post=17083"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}