{"id":17383795,"url":"https://github.com/numblr/python-midi-io","last_synced_at":"2025-03-27T21:15:02.290Z","repository":{"id":79291413,"uuid":"148617053","full_name":"numblr/python-midi-io","owner":"numblr","description":"Midi file IO for python 3","archived":false,"fork":false,"pushed_at":"2018-09-13T09:47:21.000Z","size":207,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-01T23:36:09.944Z","etag":null,"topics":["midi","midi-files","midi-parser"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/numblr.png","metadata":{"files":{"readme":"README.mediawiki","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-09-13T09:46:26.000Z","updated_at":"2020-09-30T04:12:03.000Z","dependencies_parsed_at":"2023-05-25T05:00:38.610Z","dependency_job_id":null,"html_url":"https://github.com/numblr/python-midi-io","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/numblr%2Fpython-midi-io","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/numblr%2Fpython-midi-io/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/numblr%2Fpython-midi-io/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/numblr%2Fpython-midi-io/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/numblr","download_url":"https://codeload.github.com/numblr/python-midi-io/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245924515,"owners_count":20694730,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["midi","midi-files","midi-parser"],"created_at":"2024-10-16T07:43:48.157Z","updated_at":"2025-03-27T21:15:02.264Z","avatar_url":"https://github.com/numblr.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"=Python MIDI IO=\n\nThe Python MIDI IO module provides a domain model for midi events and supports\nreading and write from standard midi files.\n\n==Features==\n\n* High level class types that represent individual MIDI events.\n* A multi-track aware container, that allows you to manage your MIDI events.\n* A reader and writer, so you can read and write your MIDI tracks to disk.\n\n==Installation==\nFirst, make sure you have swig installed (www.swig.org)\n\nFollow the [http://docs.python.org/2/install/index.html normal procedure for Python module installation]:\n\n\u003cpre\u003e\npython setup.py install\n\u003c/pre\u003e\n\n===Examine a MIDI File===\n\nTo examine the contents of a MIDI file run\n\n\u003cpre\u003e\n$ mididump.py mary.mid\n\u003c/pre\u003e\n\nThis will print out a representation of \"Mary had a Little Lamb\" as executable python code.\n\n==Example Usage==\n\n===Building a MIDI File from scratch===\n\nIt is easy to build a MIDI track from scratch.\n\n\u003cpre\u003e\nimport midi\n# Instantiate a MIDI note on event, append it to the track\non = midiio.NoteOnEvent(tick=0, velocity=20, pitch=midiio.G_3)\ntrack.append(on)\n# Instantiate a MIDI note off event, append it to the track\noff = midiio.NoteOffEvent(tick=100, pitch=midiio.G_3)\ntrack.append(off)\n# Add the end of track event, append it to the track\neot = midiio.EndOfTrackEvent(tick=1)\n# Instantiate a MIDI Track (contains a list of MIDI events)\ntrack = midiio.Track((on, off, eot))\n# Instantiate a MIDI Pattern (contains a list of tracks)\npattern = midiio.Pattern((track,))\n# Print out the pattern\nprint pattern\n# Save the pattern to disk\nmidiio.write_midifile(\"example.mid\", pattern)\n\u003c/pre\u003e\n\nA MIDI file is represented as a hierarchical set of objects.  At the top is a\nPattern, which contains a list of Tracks, and a Track is is a list of MIDI\nEvents.\n\nThe MIDI Pattern supports append(), extend(), slicing, and iteration. Patterns\nalso contain global MIDI metadata: the resolution and MIDI Format.\n\nThe MIDI Track class does not have any special metadata like Pattern, but it\ndoes provide a few helper functions to manipulate all events within a track.\n\nThere are 27 different MIDI Events supported.  In this example, three different\nMIDI events are created and added to the MIDI Track:\n\nThe NoteOnEvent captures the start of note, like a piano player pushing down on\na piano key.  The tick is when this event occurred, the pitch is the note value\nof the key pressed, and the velocity represents how hard the key was pressed.\n\nThe NoteOffEvent captures the end of note, just like a piano player removing her\nfinger from a depressed piano key. Once again, the tick is when this event\noccurred, the pitch is the note that is released, and the velocity has no real\nworld analogy and is usually ignored. NoteOnEvents with a velocity of zero are\nequivalent to NoteOffEvents.\n\nThe EndOfTrackEvent is a special event, and is used to indicate to MIDI\nsequencing software when the song ends.  With creating Patterns with multiple\nTracks, you only need one EndOfTrack event for the entire song.  Most MIDI\nsoftware will refuse to load a MIDI file if it does not contain an EndOfTrack\nevent.\n\nYou might notice that the EndOfTrackEvent has a tick value of 1.  This is\nbecause MIDI represents ticks in relative time.  The actual tick offset of the\nMidiTrackEvent is the sum of its tick and all the ticks from previous events.\nIn this example, the EndOfTrackEvent would occur at tick 101 (0 + 100 + 1).\n\n====Side Note: What is a MIDI Tick?====\n\nThe problem with ticks is that they don't give you any information about when\nthey occur without knowing two other pieces of information, the resolution, and\nthe tempo.  The code handles these issues for you so all you have to do is\nthink about things in terms of milliseconds, or ticks, if you care about the beat.\n\nA tick represents the lowest level resolution of a MIDI track.  Tempo is always\nanalogous with Beats per Minute (BPM) which is the same thing as Quarter notes\nper Minute (QPM).  The Resolution is also known as the Pulses per Quarter note\n(PPQ).  It analogous to Ticks per Beat (TPB).\n\nTempo is set by two things.  First, a saved MIDI file encodes an initial\nResolution and Tempo.  You use these values to initialize the sequencer timer.\nThe Resolution should be considered static to a track, as well as the\nsequencer.  During MIDI playback, the MIDI file may have encoded sequenced\n(that is, timed) Tempo change events.  These events will modulate the Tempo at\nthe time they specify.  The Resolution, however, can not change from its\ninitial value during playback.\n\nUnder the hood, MIDI represents Tempo in microseconds.  In other words, you\nconvert Tempo to Microseconds per Beat.  If the Tempo was 120 BPM, the python\ncode to convert to microseconds looks like this:\n\n\u003cpre\u003e\n\u003e\u003e\u003e 60 * 1000000 / 120\n500000\n\u003c/pre\u003e\n\nThis says the Tempo is 500,000 microseconds per beat. This, in combination\nwith the Resolution, will allow you to convert ticks to time. If there are\n500,000 microseconds per beat, and if the Resolution is 1,000 than one tick is\nhow much time?\n\n\u003cpre\u003e\n\u003e\u003e\u003e 500000 / 1000\n500\n\u003e\u003e\u003e 500 / 1000000.0\n0.00050000000000000001\n\u003c/pre\u003e\n\nIn other words, one tick represents .0005 seconds of time or half a millisecond.\nIncrease the Resolution and this number gets smaller, the inverse as the\nresolution gets smaller. Same for Tempo.\n\nAlthough MIDI encodes Time Signatures, it has no impact on the Tempo. However,\nhere is a quick refresher on Time Signatures:\n\nhttp://en.wikipedia.org/wiki/Time_signature\n\n===Reading our Track back from Disk===\n\nIt's just as easy to load your MIDI file from disk.\n\n\u003cpre\u003e\nimport midiio\npattern = midiio.read_midifile(\"example.mid\")\nprint pattern\n\u003c/pre\u003e\n\n==History==\n\nThis module is based on a fork of the\n[python-midi library](https://github.com/vishnubob/python-midi) and was started\nbecause the lacking Python 3 support. From the original module support for\nsequencing midi events was removed and it was slightly restructured.\n\n\n\n==Website, support, bug tracking, development etc.==\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnumblr%2Fpython-midi-io","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnumblr%2Fpython-midi-io","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnumblr%2Fpython-midi-io/lists"}