Package: miditk-smf
miditk-smfA Python toolkit for working with Standard MIDI filesQuickstartInstall:pip install miditk-smfUsage:frommiditk.smfimportMidiFileWriter# Open file for writing in binary mode.withopen('minimal.mid','wb')assmf:# Create standard MIDI file writer.midi=MidiFileWriter(smf)# Write file and track header for Type 0 file, one track, 96 pulses per# quarter note (ppqn). These are also the default parameter values.midi.header(format=0,num_tracks=1,tick_division=96)midi.start_of_track()# Set tempo to 120 bpm in µsec per quarter note.# When no tempo is set in the MIDI file, sequencers will generally assume# it to be 120 bpm.midi.tempo(int(60_000_000/120))# Add MIDI events.midi.note_on(channel=0,note=0x40)# Advance 192 ticks (i.e. a half note).midi.update_ticks(192)midi.note_off(channel=0,note=0x40)# End track and midi file.midi.end_of_track()midi.eof()For more examples, see theUsage examplessection below.Overviewmiditk-smfis a general-purpose library for the parsing and generation of
Standard MIDI Files (SMF). The package is part of several planned packages
under the common top-level package namespacemiditk. This package mainly
provides themiditk.smfsub-package for handling standard MIDI files.
Additional sub-packages with more specialised MIDI libraries and tools may be
developed and distributed as separate package distributions in the future.Compatibilitymiditk-smfworks with (C)Python >= 3.8 and PyPy 3.Installationmiditk-smfis installable viapipfrom thePython Package Index:pip install miditk-smfIt is provided as a source distribution and a universal Python wheel for all
supported Python versions and operating systems. It only depends on the Python
standard library.Package contentsmiditk.common:A collection of constants from the MIDI specification used by sub-packages and
general data types for working with MIDI events.miditk.smf:An event-based standard MIDI file (SMF) parsing and generation framework.miditk.smf.api:Base event handler classes, which can be subclassed for specialised event
handling.miditk.smf.converters:A collection of functions that converts the special data types used in midi
files to and from byte strings.miditk.smf.parser:The main binary MIDI file data parser.miditk.smf.reader:Combines the parser with an event handler class.miditk.smf.sequence:An event handler, which stores all MIDI events from a MIDI file in aMidiSequencecontainer class.miditk.smf.writer:An event handler to write out MIDI events to a standard MIDI File.Usage examplesThe following section contains a few code examples, which demonstrate several
usage scenarios for the different modules in the package. For more examples see
also the scripts in theexamplesdirectory of the source distribution.Parsing a standard MIDI fileThemiditk.smfmodule provides theMidiSequencecontainer class, which uses
its own MIDI event handler class to collect all information and events from
parsing a midi file. Use theMidiSequence.fromfile()class method to parse a
standard MIDI file.You can then use several convenience methods of the returnedMidiSequenceinstance to access information about the midi file properties or events.frommiditk.smfimportMidiSequence# Do parsingsequence=MidiSequence.fromfile(sys.argv[1])# Print some info from the MIDI file header,# e.g. number of tracks, events sequence name.print(sequence)# Print a list of events with event type, data and timestamp.sequence.dump_events()# Iterate over all sysex events in track 0.# If track is not specified, sysex_events() yields all sysex events# in all tracks.forevinsequence.sysex_events(track=0):print("Sysex event ({}bytes) @{:.2f}".format(len(ev.data),ev.timestamp))# Iterate over all events sorted by timestamp and then track.fortime,groupinsequence.events_by_time():forevingroup:handle_event(ev)Changing MIDI events in-streamThe event-based parsing allows to handle MIDI events as they are read (or
received via MIDI in). You need to define a sub-class ofmiditk.smf.BaseMidiEventHandlerormiditk.smf.NullMidiEventHandlerand
overwrite only the event handling methods for the events you are interested in.The following example transposes all note on/off events by an octave (i.e. 12
semitones):importsysfrommiditk.smfimportMidiFileReader,MidiFileWriter# MidiFileWriter is a sub-class of NullMidiEventHandler.classTransposer(MidiFileWriter):"""Transpose note values of all note on/off events by 1 octave."""defnote_on(self,channel,note,velocity):super().note_on(self,channel,min(127,note+12),velocity)defnote_off(self,channel,note,velocity):super().note_off(self,channel,min(127,note+12),velocity)infile=sys.argv.pop(1)outfile=sys.argv.pop(1)# Create the parser and event handlerwithopen(outfile,'wb')assmf:midiout=Transposer(smf)midiin=MidiFileReader(infile,midiout)# Now do the processing.midiin.read()DevelopmentClone the Git repository:git clone https://github.com/SpotlightKid/miditk-smf.gitcd miditk-smfInstall tox:pip install toxOr via your Linux distribution package manager, e.g. on debian/Ubuntu:sudo apt-get install python-toxOr on Arch Linux:sudo pacman -S python-toxRun the tests via tox for all Python versions configured intox.ini:toxIf all is well, create a new git branch and start hacking and then contribute
your changes by opening apull
requeston GitHub.Code QAThe included Makefile is set up to run several Python static code checking and
reporting tools. To print a list of available Makefile targets and the tools
they run, simple run:makeThen run the Makefile target of your choice, e.g.:make flake8Unless noted otherwise, these targets run all tools directly, i.e. without tox,
which means they need to be installed in your Python environment. You can use
[hatch] to create a virtual environments for general development tasks or for
specific tasks as, for example, building the documentation. Dependencies and
tools needed for these tasks will be installed automatically into these
environments on creation:To show which special environments are defined:hatch env showTo create and enter e.g. the "dev" environment:hatch --env dev shellDocumentationPackage documentation is generated by Sphinx. The documentation can be build
with:make docsAfter a successful build the documentation index is opened in your web
browser.Authors and LicenseThemiditkpackage is written by Christopher Arndt and licensed under the MIT
License.The the structure of themiditk.smfsub-package owes inspiration to thePython Midi[^1] package, written bymaxm@maxm.dk.[^1]: Original web site, now defunct:http://www.mxm.dk/products/public/pythonmidi/