miditk-smf


Namemiditk-smf JSON
Version 0.3.1 PyPI version JSON
download
home_page
SummaryA Python toolkit for working with Standard MIDI files
upload_time2023-08-21 12:01:30
maintainer
docs_urlNone
author
requires_python>=3.8
license
keywords midi smf multimedia music parsing
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # miditk-smf

A Python toolkit for working with Standard MIDI files

## Quickstart

Install:

```console
pip install miditk-smf
```

Usage:

```py
from miditk.smf import MidiFileWriter

# Open file for writing in binary mode.
with open('minimal.mid', 'wb') as smf:
    # 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 the [Usage examples](#usage-examples) section below.


## Overview

`miditk-smf` is 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 namespace `miditk`. This package mainly
provides the `miditk.smf` sub-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.


### Compatibility

`miditk-smf` works with (C)Python >= 3.8 and PyPy 3.


## Installation

`miditk-smf` is installable via [pip](https://pypi.org/project/pip/)
from the [Python Package Index](https://pypi.org/project/miditk-smf/):

```console
pip install miditk-smf
```

It 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 contents

`miditk.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 a
`MidiSequence` container class.

`miditk.smf.writer`:

An event handler to write out MIDI events to a standard MIDI File.


## Usage examples

The 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 the [examples] directory of the source distribution.


### Parsing a standard MIDI file

The `miditk.smf` module provides the `MidiSequence` container class, which uses
its own MIDI event handler class to collect all information and events from
parsing a midi file. Use the `MidiSequence.fromfile()` class method to parse a
standard MIDI file.

You can then use several convenience methods of the returned `MidiSequence`
instance to access information about the midi file properties or events.

```py
from miditk.smf import MidiSequence

# Do parsing
sequence = 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.
for ev in sequence.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.
for time, group in sequence.events_by_time():
    for ev in group:
        handle_event(ev)
```


### Changing MIDI events in-stream

The event-based parsing allows to handle MIDI events as they are read (or
received via MIDI in). You need to define a sub-class of
`miditk.smf.BaseMidiEventHandler` or `miditk.smf.NullMidiEventHandler` and
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):

```py
import sys
from miditk.smf import MidiFileReader, MidiFileWriter

# MidiFileWriter is a sub-class of NullMidiEventHandler.
class Transposer(MidiFileWriter):
    """Transpose note values of all note on/off events by 1 octave."""

    def note_on(self, channel, note, velocity):
        super().note_on(self, channel, min(127, note + 12), velocity)

    def note_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 handler
with open(outfile, 'wb') as smf:
    midiout = Transposer(smf)
    midiin = MidiFileReader(infile, midiout)

    # Now do the processing.
    midiin.read()
```


## Development

Clone the Git repository:

```console
git clone https://github.com/SpotlightKid/miditk-smf.git
cd miditk-smf
```

Install tox:

```console
pip install tox
```

Or via your Linux distribution package manager, e.g. on debian/Ubuntu:

```console
sudo apt-get install python-tox
```

Or on Arch Linux:

```console
sudo pacman -S python-tox
```

Run the tests via tox for all Python versions configured in `tox.ini`:

```console
tox
```

If all is well, create a new git branch and start hacking and then contribute
your changes by opening a [pull
request](https://github.com/SpotlightKid/miditk-smf/pulls) on GitHub.


## Code QA

The 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:

```console
make
```

Then run the Makefile target of your choice, e.g.:

```console
make flake8
```

Unless 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:

```console
hatch env show
```

To create and enter e.g. the "dev" environment:

```console
hatch --env dev shell
```


## Documentation

Package documentation is generated by Sphinx. The documentation can be build
with:

```console
make docs
```

After a successful build the documentation index is opened in your web
browser.


## Authors and License

The `miditk` package is written by Christopher Arndt and licensed under the MIT
License.

The the structure of the `miditk.smf` sub-package owes inspiration to the
[Python Midi] [^1] package, written by <maxm@maxm.dk>.


[examples]: https://github.com/SpotlightKid/miditk-smf/tree/master/examples
[python midi]: http://web.archive.org/web/20100919095628/http://www.mxm.dk/products/public/pythonmidi/
[^1]: Original web site, now defunct: http://www.mxm.dk/products/public/pythonmidi/

            

Raw data

            {
    "_id": null,
    "home_page": "",
    "name": "miditk-smf",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": "",
    "keywords": "MIDI,SMF,multimedia,music,parsing",
    "author": "",
    "author_email": "Christopher Arndt <info@chrisarndt.de>",
    "download_url": "https://files.pythonhosted.org/packages/1f/d9/2106cb522fb4e42a4d9db82cd1eeedbb271529d42746bea8773ac4a15cf8/miditk_smf-0.3.1.tar.gz",
    "platform": null,
    "description": "# miditk-smf\n\nA Python toolkit for working with Standard MIDI files\n\n## Quickstart\n\nInstall:\n\n```console\npip install miditk-smf\n```\n\nUsage:\n\n```py\nfrom miditk.smf import MidiFileWriter\n\n# Open file for writing in binary mode.\nwith open('minimal.mid', 'wb') as smf:\n    # Create standard MIDI file writer.\n    midi = MidiFileWriter(smf)\n\n    # Write file and track header for Type 0 file, one track, 96 pulses per\n    # quarter note (ppqn). These are also the default parameter values.\n    midi.header(format=0, num_tracks=1, tick_division=96)\n    midi.start_of_track()\n\n    # Set tempo to 120 bpm in \u00b5sec per quarter note.\n    # When no tempo is set in the MIDI file, sequencers will generally assume\n    # it to be 120 bpm.\n    midi.tempo(int(60_000_000 / 120))\n\n    # Add MIDI events.\n    midi.note_on(channel=0, note=0x40)\n    # Advance 192 ticks (i.e. a half note).\n    midi.update_ticks(192)\n    midi.note_off(channel=0, note=0x40)\n\n    # End track and midi file.\n    midi.end_of_track()\n    midi.eof()\n```\n\nFor more examples, see the [Usage examples](#usage-examples) section below.\n\n\n## Overview\n\n`miditk-smf` is a general-purpose library for the parsing and generation of\nStandard MIDI Files (SMF). The package is part of several planned packages\nunder the common top-level package namespace `miditk`. This package mainly\nprovides the `miditk.smf` sub-package for handling standard MIDI files.\nAdditional sub-packages with more specialised MIDI libraries and tools may be\ndeveloped and distributed as separate package distributions in the future.\n\n\n### Compatibility\n\n`miditk-smf` works with (C)Python >= 3.8 and PyPy 3.\n\n\n## Installation\n\n`miditk-smf` is installable via [pip](https://pypi.org/project/pip/)\nfrom the [Python Package Index](https://pypi.org/project/miditk-smf/):\n\n```console\npip install miditk-smf\n```\n\nIt is provided as a source distribution and a universal Python wheel for all\nsupported Python versions and operating systems. It only depends on the Python\nstandard library.\n\n\n## Package contents\n\n`miditk.common`:\n\nA collection of constants from the MIDI specification used by sub-packages and\ngeneral data types for working with MIDI events.\n\n`miditk.smf`:\n\nAn event-based standard MIDI file (SMF) parsing and generation framework.\n\n`miditk.smf.api`:\n\nBase event handler classes, which can be subclassed for specialised event\nhandling.\n\n`miditk.smf.converters`:\n\nA collection of functions that converts the special data types used in midi\nfiles to and from byte strings.\n\n`miditk.smf.parser`:\n\nThe main binary MIDI file data parser.\n\n`miditk.smf.reader`:\n\nCombines the parser with an event handler class.\n\n`miditk.smf.sequence`:\n\nAn event handler, which stores all MIDI events from a MIDI file in a\n`MidiSequence` container class.\n\n`miditk.smf.writer`:\n\nAn event handler to write out MIDI events to a standard MIDI File.\n\n\n## Usage examples\n\nThe following section contains a few code examples, which demonstrate several\nusage scenarios for the different modules in the package. For more examples see\nalso the scripts in the [examples] directory of the source distribution.\n\n\n### Parsing a standard MIDI file\n\nThe `miditk.smf` module provides the `MidiSequence` container class, which uses\nits own MIDI event handler class to collect all information and events from\nparsing a midi file. Use the `MidiSequence.fromfile()` class method to parse a\nstandard MIDI file.\n\nYou can then use several convenience methods of the returned `MidiSequence`\ninstance to access information about the midi file properties or events.\n\n```py\nfrom miditk.smf import MidiSequence\n\n# Do parsing\nsequence = MidiSequence.fromfile(sys.argv[1])\n\n# Print some info from the MIDI file header,\n# e.g. number of tracks, events sequence name.\nprint(sequence)\n# Print a list of events with event type, data and timestamp.\nsequence.dump_events()\n\n# Iterate over all sysex events in track 0.\n# If track is not specified, sysex_events() yields all sysex events\n# in all tracks.\nfor ev in sequence.sysex_events(track=0):\n    print(\"Sysex event ({} bytes) @ {:.2f}\".format(len(ev.data), ev.timestamp))\n\n# Iterate over all events sorted by timestamp and then track.\nfor time, group in sequence.events_by_time():\n    for ev in group:\n        handle_event(ev)\n```\n\n\n### Changing MIDI events in-stream\n\nThe event-based parsing allows to handle MIDI events as they are read (or\nreceived via MIDI in). You need to define a sub-class of\n`miditk.smf.BaseMidiEventHandler` or `miditk.smf.NullMidiEventHandler` and\noverwrite only the event handling methods for the events you are interested in.\n\nThe following example transposes all note on/off events by an octave (i.e. 12\nsemitones):\n\n```py\nimport sys\nfrom miditk.smf import MidiFileReader, MidiFileWriter\n\n# MidiFileWriter is a sub-class of NullMidiEventHandler.\nclass Transposer(MidiFileWriter):\n    \"\"\"Transpose note values of all note on/off events by 1 octave.\"\"\"\n\n    def note_on(self, channel, note, velocity):\n        super().note_on(self, channel, min(127, note + 12), velocity)\n\n    def note_off(self, channel, note, velocity):\n        super().note_off(self, channel, min(127, note + 12), velocity)\n\ninfile = sys.argv.pop(1)\noutfile = sys.argv.pop(1)\n\n# Create the parser and event handler\nwith open(outfile, 'wb') as smf:\n    midiout = Transposer(smf)\n    midiin = MidiFileReader(infile, midiout)\n\n    # Now do the processing.\n    midiin.read()\n```\n\n\n## Development\n\nClone the Git repository:\n\n```console\ngit clone https://github.com/SpotlightKid/miditk-smf.git\ncd miditk-smf\n```\n\nInstall tox:\n\n```console\npip install tox\n```\n\nOr via your Linux distribution package manager, e.g. on debian/Ubuntu:\n\n```console\nsudo apt-get install python-tox\n```\n\nOr on Arch Linux:\n\n```console\nsudo pacman -S python-tox\n```\n\nRun the tests via tox for all Python versions configured in `tox.ini`:\n\n```console\ntox\n```\n\nIf all is well, create a new git branch and start hacking and then contribute\nyour changes by opening a [pull\nrequest](https://github.com/SpotlightKid/miditk-smf/pulls) on GitHub.\n\n\n## Code QA\n\nThe included Makefile is set up to run several Python static code checking and\nreporting tools. To print a list of available Makefile targets and the tools\nthey run, simple run:\n\n```console\nmake\n```\n\nThen run the Makefile target of your choice, e.g.:\n\n```console\nmake flake8\n```\n\nUnless noted otherwise, these targets run all tools directly, i.e. without tox,\nwhich means they need to be installed in your Python environment. You can use\n[hatch] to create a virtual environments for general development tasks or for\nspecific tasks as, for example, building the documentation. Dependencies and\ntools needed for these tasks will be installed automatically into these\nenvironments on creation:\n\nTo show which special environments are defined:\n\n```console\nhatch env show\n```\n\nTo create and enter e.g. the \"dev\" environment:\n\n```console\nhatch --env dev shell\n```\n\n\n## Documentation\n\nPackage documentation is generated by Sphinx. The documentation can be build\nwith:\n\n```console\nmake docs\n```\n\nAfter a successful build the documentation index is opened in your web\nbrowser.\n\n\n## Authors and License\n\nThe `miditk` package is written by Christopher Arndt and licensed under the MIT\nLicense.\n\nThe the structure of the `miditk.smf` sub-package owes inspiration to the\n[Python Midi] [^1] package, written by <maxm@maxm.dk>.\n\n\n[examples]: https://github.com/SpotlightKid/miditk-smf/tree/master/examples\n[python midi]: http://web.archive.org/web/20100919095628/http://www.mxm.dk/products/public/pythonmidi/\n[^1]: Original web site, now defunct: http://www.mxm.dk/products/public/pythonmidi/\n",
    "bugtrack_url": null,
    "license": "",
    "summary": "A Python toolkit for working with Standard MIDI files",
    "version": "0.3.1",
    "project_urls": {
        "Bug Tracker": "https://github.com/SpotlightKid/miditk-smf/issues",
        "Homepage": "https://github.com/SpotlightKid/miditk-smf"
    },
    "split_keywords": [
        "midi",
        "smf",
        "multimedia",
        "music",
        "parsing"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "bc4c78f7f7654b734b5fc0384bf0b8971bcc202507a31c1f038fbae4e0d5787c",
                "md5": "7e21d389c84d754d9f5a88cd5ca989a1",
                "sha256": "fe4260cf3fa874e083adc525d884e59098309c8c66fa04313c146b04e1c979dc"
            },
            "downloads": -1,
            "filename": "miditk_smf-0.3.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "7e21d389c84d754d9f5a88cd5ca989a1",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 29267,
            "upload_time": "2023-08-21T12:01:28",
            "upload_time_iso_8601": "2023-08-21T12:01:28.985563Z",
            "url": "https://files.pythonhosted.org/packages/bc/4c/78f7f7654b734b5fc0384bf0b8971bcc202507a31c1f038fbae4e0d5787c/miditk_smf-0.3.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "1fd92106cb522fb4e42a4d9db82cd1eeedbb271529d42746bea8773ac4a15cf8",
                "md5": "5d94bfd8d11aa30c856c76f2456b9a69",
                "sha256": "5667536d8a0ae5f5d078c78b367d5d7020d79b8c5385dcfb7a2cce04f8b452e1"
            },
            "downloads": -1,
            "filename": "miditk_smf-0.3.1.tar.gz",
            "has_sig": false,
            "md5_digest": "5d94bfd8d11aa30c856c76f2456b9a69",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 40827,
            "upload_time": "2023-08-21T12:01:30",
            "upload_time_iso_8601": "2023-08-21T12:01:30.621927Z",
            "url": "https://files.pythonhosted.org/packages/1f/d9/2106cb522fb4e42a4d9db82cd1eeedbb271529d42746bea8773ac4a15cf8/miditk_smf-0.3.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-08-21 12:01:30",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "SpotlightKid",
    "github_project": "miditk-smf",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "tox": true,
    "lcname": "miditk-smf"
}
        
Elapsed time: 0.68208s