Skip to main content

Math Sequence to MIDI

Project description

rmidipy

This python library is intended to open midi files as python objects. Midi file is binary files, list in form of tracks. Every track contains a sequence of events. Each event is associated delta time, which refers to time from perivous event, current event should occur.

In same structure rmidi has MIDI as base class, MIDI.Track for track representation and MIDI.Track.Event to represent each event.

Getting Started

rmidi is available on python pip. You can install library through below command.

    $ pip install rmidi

rmidi has two classes for handling the midi files MIDI and AbsoluteMidi, further documentation reveals out their differences. You can open **.mid** files with MIDI class only, which can transform to AbsoluteMidi class object

Opening and Creating the midi file

>>> from rmidi.midi import MIDI
>>> mid = MIDI.parse_midi(<midi-file-path>)
>>> # do any manupulation it
>>> mid.create_file(<midi-file-name>, <dir-path> = current-dir) # if dir is not specified file is store in current directory 

Create empty Midi File

>>> from rmidi.midi import MIDI
>>> mid = MIDI(empty = True) # creates file with, format_type = 0, track_count = 0, time_div = 0x1e0
>>> mid.create_file("empyty.mid")

MIDI

>>> from rmidi import MIDI
>>> y = MIDI.parse_midi(<midi_file_path>)

OUTPUT

| Absolute Time   |  Duration       |  Delta Time |  ETYPE     |   Event ID | META  | LENGTH     | DATA
|______________________________________________________________________________________________________________________________ . . .
| 0.000000        | 0.000000        | 0x0         | META       | 0xff       | 0x58  | 0x4        |  0x04  0x02 0x18  0x0
| 0.000000        | 0.000000        | 0x0         | META       | 0xff       | 0x59  | 0x2        |  0x00  0x0
| 0.000000        | 0.000000        | 0x0         | META       | 0xff       | 0x51  | 0x3        |  0x07  0xa1 0x2
| 0.000000        | 0.000000        | 0x0         | CHANNEL    | 0xb0       | 0     | 0x2        |  0x79  0x0
| 0.000000        | 0.000000        | 0x0         | CHANNEL    | 0xc0       | 0     | 0x1        |  0x0
| 0.000000        | 0.000000        | 0x0         | CHANNEL    | 0xb0       | 0     | 0x2        |  0x07  0x6
| 0.000000        | 0.000000        | 0x0         | CHANNEL    | 0xb0       | 0     | 0x2        |  0x0a  0x4
| 0.000000        | 0.000000        | 0x0         | CHANNEL    | 0xb0       | 0     | 0x2        |  0x5b  0x0
| 0.000000        | 0.000000        | 0x0         | CHANNEL    | 0xb0       | 0     | 0x2        |  0x5d  0x0
| 0.000000        | 0.000000        | 0x0         | META       | 0xff       | 0x21  | 0x1        |  0x0
| 0.000000        | 0.000000        | 0x0         | CHANNEL    | 0x90       | 0     | 0x2        |  0x48  0x5
| 0.000000        | 0.000000        | 0x71f       | CHANNEL    | 0x90       | 0     | 0x2        |  0x48  0x0
| 0.000000        | 0.000000        | 0x61        | CHANNEL    | 0x90       | 0     | 0x2        |  0x4a  0x5
| 0.000000        | 0.000000        | 0x71f       | CHANNEL    | 0x90       | 0     | 0x2        |  0x4a  0x0
| 0.000000        | 0.000000        | 0x61        | CHANNEL    | 0x90       | 0     | 0x2        |  0x4c  0x5
| 0.000000        | 0.000000        | 0x71f       | CHANNEL    | 0x90       | 0     | 0x2        |  0x4c  0x0
| 0.000000        | 0.000000        | 0x61        | CHANNEL    | 0x90       | 0     | 0x2        |  0x4d  0x5
| 0.000000        | 0.000000        | 0x71f       | CHANNEL    | 0x90       | 0     | 0x2        |  0x4d  0x0
| 0.000000        | 0.000000        | 0x61        | CHANNEL    | 0x90       | 0     | 0x2        |  0x4f  0x5
| 0.000000        | 0.000000        | 0x71f       | CHANNEL    | 0x90       | 0     | 0x2        |  0x4f  0x0
| 0.000000        | 0.000000        | 0x61        | CHANNEL    | 0x90       | 0     | 0x2        |  0x51  0x5
| 0.000000        | 0.000000        | 0x71f       | CHANNEL    | 0x90       | 0     | 0x2        |  0x51  0x0
| 0.000000        | 0.000000        | 0x61        | CHANNEL    | 0x90       | 0     | 0x2        |  0x53  0x5
| 0.000000        | 0.000000        | 0x71f       | CHANNEL    | 0x90       | 0     | 0x2        |  0x53  0x0
| 0.000000        | 0.000000        | 0x61        | CHANNEL    | 0x90       | 0     | 0x2        |  0x54  0x5
| 0.000000        | 0.000000        | 0x71f       | CHANNEL    | 0x90       | 0     | 0x2        |  0x54  0x0
| 0.000000        | 0.000000        | 0x1         | META       | 0xff       | 0x2f  | 0x0        |

Absolute midi

Absolute Midi is defined as its time from start, in seconds.

>>> from rmidi import MIDI, AbosluteMidi
>>> y = MIDI.parse_midi(<midi-file-path>)
>>> yabs = AbsoluteMidi.to_abs_midi(y)
>>> print(yabs)

OUTPUT

| Absolute Time   |  Duration       |  Note  Time         |  Delta Time |  ETYPE     |   Event ID | META  | LENGTH     | DATA
|______________________________________________________________________________________________________________________________ . . .
| 0.000000        | 0.000000        | 0                    | 0x0         | META       | 0xff       | 0x58  | 0x4        |  0x04  0x02 0x18  0x08
| 0.000000        | 0.000000        | 0                    | 0x0         | META       | 0xff       | 0x59  | 0x2        |  0x00  0x00
| 0.000000        | 0.000000        | 0                    | 0x0         | META       | 0xff       | 0x51  | 0x3        |  0x07  0xa1 0x20
| 0.000000        | 0.000000        | 0                    | 0x0         | CHANNEL    | 0xb0       | 0     | 0x2        |  0x79  0x00
| 0.000000        | 0.000000        | 0                    | 0x0         | CHANNEL    | 0xc0       | 0     | 0x1        |  0x00
| 0.000000        | 0.000000        | 0                    | 0x0         | CHANNEL    | 0xb0       | 0     | 0x2        |  0x07  0x64
| 0.000000        | 0.000000        | 0                    | 0x0         | CHANNEL    | 0xb0       | 0     | 0x2        |  0x0a  0x40
| 0.000000        | 0.000000        | 0                    | 0x0         | CHANNEL    | 0xb0       | 0     | 0x2        |  0x5b  0x00
| 0.000000        | 0.000000        | 0                    | 0x0         | CHANNEL    | 0xb0       | 0     | 0x2        |  0x5d  0x00
| 0.000000        | 0.000000        | 0                    | 0x0         | META       | 0xff       | 0x21  | 0x1        |  0x00
| 0.000000        | 31.649306       | 1.0666666666666667   | 0x0         | CHANNEL    | 0x90       | 0     | 0x2        |  0x48  0x50
| 33.333333       | 31.649306       | 1.0666666666666667   | 0x61        | CHANNEL    | 0x90       | 0     | 0x2        |  0x4a  0x50
| 66.666667       | 31.649306       | 1.0666666666666667   | 0x61        | CHANNEL    | 0x90       | 0     | 0x2        |  0x4c  0x50
| 100.000000      | 31.649306       | 1.0666666666666667   | 0x61        | CHANNEL    | 0x90       | 0     | 0x2        |  0x4d  0x50
| 133.333333      | 31.649306       | 1.0666666666666667   | 0x61        | CHANNEL    | 0x90       | 0     | 0x2        |  0x4f  0x50
| 166.666667      | 31.649306       | 1.0666666666666667   | 0x61        | CHANNEL    | 0x90       | 0     | 0x2        |  0x51  0x50
| 200.000000      | 31.649306       | 1.0666666666666667   | 0x61        | CHANNEL    | 0x90       | 0     | 0x2        |  0x53  0x50
| 233.333333      | 31.649306       | 1.0666666666666667   | 0x61        | CHANNEL    | 0x90       | 0     | 0x2        |  0x54  0x50
| 0.000000        | 0.000000        | 0                    | 0x1         | META       | 0xff       | 0x2f  | 0x0        |
*******************************************************************************************************************

NoteSequence

rmidi.dataset.NoteSequence is similar object to that of Magenta.NoteSequence, It holds everthing in dict, whole midi file is express as python nested dictionary

>>> from rmidi.dataset import notesequence
>>> ns = NoteSequence(<midi-file-path>)
>>> print(ns)
Output
[
    {
        "track-0": [
            [
                "type : meta",
                "deltatime : 0",
                "time : 0",
                "duration : 0",
                "subtype : time_sig",
                "length : 4",
                "data : 0x04  0x02 0x18 0x08 \n"
            ],
            [
                "type : meta",
                "deltatime : 0",
                "time : 0",
                "duration : 0",
                "subtype : key_sig",
                "length : 2",
                "data : 0x00  0x00 \n"
            ],
            [
                "type : meta",
                "deltatime : 0",
                "time : 0",
                "duration : 0",
                "subtype : set_tempo",
                "length : 3",
                "data : 0x07  0xa1 0x20 \n"
            ],
            [
                "type : cntroller",
                "deltatime : 0",
                "event_id : 176",
                "time : 0",
                "duaration : 0",
                "pitch : None",
                "velocity : None",
                "is_drum : False",
                "subtype : mode_messages_0"
            ],
            [
                "type : program_change",
                "deltatime : 0",
                "event_id : 192",
                "time : 0",
                "duaration : 0",
                "pitch : None",
                "velocity : None",
                "is_drum : False"
            ],
            [
                "type : cntroller",
                "deltatime : 0",
                "event_id : 176",
                "time : 0",
                "duaration : 0",
                "pitch : None",
                "velocity : None",
                "is_drum : False",
                "subtype : main_volume"
            ],
            [
                "type : cntroller",
                "deltatime : 0",
                "event_id : 176",
                "time : 0",
                "duaration : 0",
                "pitch : None",
                "velocity : None",
                "is_drum : False",
                "subtype : pan"
            ],
            [
                "type : cntroller",
                "deltatime : 0",
                "event_id : 176",
                "time : 0",
                "duaration : 0",
                "pitch : None",
                "velocity : None",
                "is_drum : False",
                "subtype : effects_depth_0"
            ],
            [
                "type : cntroller",
                "deltatime : 0",
                "event_id : 176",
                "time : 0",
                "duaration : 0",
                "pitch : None",
                "velocity : None",
                "is_drum : False",
                "subtype : effects_depth_2"
            ],
            [
                "type : meta",
                "deltatime : 0",
                "time : 0",
                "duration : 0",
                "subtype : midi_port",
                "length : 1",
                "data : 0x00  \n"
            ],
            [
                "type : note_on",
                "deltatime : 0",
                "event_id : 144",
                "time : 0.0",
                "duaration : 31.649305555555554",
                "pitch : 72",
                "velocity : 80",
                "is_drum : False"
            ],
            [
                "type : note_on",
                "deltatime : 97",
                "event_id : 144",
                "time : 33.33333333333333",
                "duaration : 31.649305555555557",
                "pitch : 74",
                "velocity : 80",
                "is_drum : False"
            ],
            [
                "type : note_on",
                "deltatime : 97",
                "event_id : 144",
                "time : 66.66666666666666",
                "duaration : 31.649305555555557",
                "pitch : 76",
                "velocity : 80",
                "is_drum : False"
            ],
            [
                "type : note_on",
                "deltatime : 97",
                "event_id : 144",
                "time : 99.99999999999999",
                "duaration : 31.649305555555557",
                "pitch : 77",
                "velocity : 80",
                "is_drum : False"
            ],
            [
                "type : note_on",
                "deltatime : 97",
                "event_id : 144",
                "time : 133.33333333333331",
                "duaration : 31.649305555555543",
                "pitch : 79",
                "velocity : 80",
                "is_drum : False"
            ],
            [
                "type : note_on",
                "deltatime : 97",
                "event_id : 144",
                "time : 166.66666666666663",
                "duaration : 31.649305555555543",
                "pitch : 81",
                "velocity : 80",
                "is_drum : False"
            ],
            [
                "type : note_on",
                "deltatime : 97",
                "event_id : 144",
                "time : 199.99999999999994",
                "duaration : 31.649305555555543",
                "pitch : 83",
                "velocity : 80",
                "is_drum : False"
            ],
            [
                "type : note_on",
                "deltatime : 97",
                "event_id : 144",
                "time : 233.33333333333326",
                "duaration : 31.649305555555543",
                "pitch : 84",
                "velocity : 80",
                "is_drum : False"
            ],
            [
                "type : meta",
                "deltatime : 1",
                "time : 0",
                "duration : 0",
                "subtype : end_of_track",
                "length : 0",
                "data : \n"
            ]
        ]
    }
]

NoteSequence object is subscriptable, you can access, any note from praticular track easily.

>>> event = ns[0][11] # this will give you the 11th event occured from 0th track
>>> event = ns[0, 11] # this to is valid in numpy style

NoteSequence@tostring

Converts the dict to pretty string

from rmidi.dataset import NoteSequence
dict_ = {0: OrderedDict([(17, {'type': 'note_on', 'deltatime': 97, 'event_id': 144, 'time': 233.33333333333326, 'duaration': 31.649305555555543, 'pitch': 84, 'velocity': 80, 'is_drum': False}), (16, {'type': 'note_on', 'deltatime': 97, 'event_id': 144, 'time': 199.99999999999994, 'duaration': 31.649305555555543, 'pitch': 83, 'velocity': 80, 'is_drum': False}), (15, {'type': 'note_on', 'deltatime': 97, 'event_id': 144, 'time': 166.66666666666663, 'duaration': 31.649305555555543, 'pitch': 81, 'velocity': 80, 'is_drum': False}), (14, {'type': 'note_on', 'deltatime': 97, 'event_id': 144, 'time': 133.33333333333331, 'duaration': 31.649305555555543, 'pitch': 79, 'velocity': 80, 'is_drum': False}), (13, {'type': 'note_on', 'deltatime': 97, 'event_id': 144, 'time': 99.99999999999999, 'duaration': 31.649305555555557, 'pitch': 77, 'velocity': 80, 'is_drum': False}), (12, {'type': 'note_on', 'deltatime': 97, 'event_id': 144, 'time': 66.66666666666666, 'duaration': 31.649305555555557, 'pitch': 76, 'velocity': 80, 'is_drum': False}), (11, {'type': 'note_on', 'deltatime': 97, 'event_id': 144, 'time': 33.33333333333333, 'duaration': 31.649305555555557, 'pitch': 74, 'velocity': 80, 'is_drum': False}), (10, {'type': 'note_on', 'deltatime': 0, 'event_id': 144, 'time': 0.0, 'duaration': 31.649305555555554, 'pitch': 72, 'velocity': 80, 'is_drum': False})])}
print(NoteSequence.tostring(dict_))
Output
[
    {
        "track-0": [
            [
                "type : note_on",
                "deltatime : 97",
                "event_id : 144",
                "time : 233.33333333333326",
                "duaration : 31.649305555555543",
                "pitch : 84",
                "velocity : 80",
                "is_drum : False"
            ],
            [
                "type : note_on",
                "deltatime : 97",
                "event_id : 144",
                "time : 199.99999999999994",
                "duaration : 31.649305555555543",
                "pitch : 83",
                "velocity : 80",
                "is_drum : False"
            ],
            [
                "type : note_on",
                "deltatime : 97",
                "event_id : 144",
                "time : 166.66666666666663",
                "duaration : 31.649305555555543",
                "pitch : 81",
                "velocity : 80",
                "is_drum : False"
            ],
            [
                "type : note_on",
                "deltatime : 97",
                "event_id : 144",
                "time : 133.33333333333331",
                "duaration : 31.649305555555543",
                "pitch : 79",
                "velocity : 80",
                "is_drum : False"
            ],
            [
                "type : note_on",
                "deltatime : 97",
                "event_id : 144",
                "time : 99.99999999999999",
                "duaration : 31.649305555555557",
                "pitch : 77",
                "velocity : 80",
                "is_drum : False"
            ],
            [
                "type : note_on",
                "deltatime : 97",
                "event_id : 144",
                "time : 66.66666666666666",
                "duaration : 31.649305555555557",
                "pitch : 76",
                "velocity : 80",
                "is_drum : False"
            ],
            [
                "type : note_on",
                "deltatime : 97",
                "event_id : 144",
                "time : 33.33333333333333",
                "duaration : 31.649305555555557",
                "pitch : 74",
                "velocity : 80",
                "is_drum : False"
            ],
            [
                "type : note_on",
                "deltatime : 0",
                "event_id : 144",
                "time : 0.0",
                "duaration : 31.649305555555554",
                "pitch : 72",
                "velocity : 80",
                "is_drum : False"
            ]
        ]
    }
]

NoteSequence@notes

To get just notes, i.e. just note_on and note_off event, you can call NoteSequence object as ns.notes

>>> from rmidi.dataset import NoteSequence
>>> ns = NoteSequence(<midi-file-path>)
>>> notes = ns.notes
>>> print(notes)
>>> print(ns.tostring(notes)) # to pretty print
Output
 [
    {
        "track-0": [
            [
                "type : note_on",
                "deltatime : 0",
                "event_id : 144",
                "time : 0.0",
                "duaration : 31.649305555555554",
                "pitch : 72",
                "velocity : 80",
                "is_drum : False"
            ],
            [
                "type : note_on",
                "deltatime : 97",
                "event_id : 144",
                "time : 33.33333333333333",
                "duaration : 31.649305555555557",
                "pitch : 74",
                "velocity : 80",
                "is_drum : False"
            ],
            [
                "type : note_on",
                "deltatime : 97",
                "event_id : 144",
                "time : 66.66666666666666",
                "duaration : 31.649305555555557",
                "pitch : 76",
                "velocity : 80",
                "is_drum : False"
            ],
            [
                "type : note_on",
                "deltatime : 97",
                "event_id : 144",
                "time : 99.99999999999999",
                "duaration : 31.649305555555557",
                "pitch : 77",
                "velocity : 80",
                "is_drum : False"
            ],
            [
                "type : note_on",
                "deltatime : 97",
                "event_id : 144",
                "time : 133.33333333333331",
                "duaration : 31.649305555555543",
                "pitch : 79",
                "velocity : 80",
                "is_drum : False"
            ],
            [
                "type : note_on",
                "deltatime : 97",
                "event_id : 144",
                "time : 166.66666666666663",
                "duaration : 31.649305555555543",
                "pitch : 81",
                "velocity : 80",
                "is_drum : False"
            ],
            [
                "type : note_on",
                "deltatime : 97",
                "event_id : 144",
                "time : 199.99999999999994",
                "duaration : 31.649305555555543",
                "pitch : 83",
                "velocity : 80",
                "is_drum : False"
            ],
            [
                "type : note_on",
                "deltatime : 97",
                "event_id : 144",
                "time : 233.33333333333326",
                "duaration : 31.649305555555543",
                "pitch : 84",
                "velocity : 80",
                "is_drum : False"
            ]
        ]
    }
]

Notesequence@order_by

It orders the events within track base on event attribute, order by is intended to work for attributes 'time', 'duration', 'pitch', deltatime

>>> from rmidi.dataset import NoteSequence
>>> ns = NoteSequence(filepath)
>>> ordered = ns.order_by(<attribute_name>, reverse=True)
>>> print(ordered) # Output for pitch sorted in reverse
Output
[
    {
        "track-0": [
            [
                "type : note_on",
                "deltatime : 97",
                "event_id : 144",
                "time : 233.33333333333326",
                "duaration : 31.649305555555543",
                "pitch : 84",
                "velocity : 80",
                "is_drum : False"
            ],
            [
                "type : note_on",
                "deltatime : 97",
                "event_id : 144",
                "time : 199.99999999999994",
                "duaration : 31.649305555555543",
                "pitch : 83",
                "velocity : 80",
                "is_drum : False"
            ],
            [
                "type : note_on",
                "deltatime : 97",
                "event_id : 144",
                "time : 166.66666666666663",
                "duaration : 31.649305555555543",
                "pitch : 81",
                "velocity : 80",
                "is_drum : False"
            ],
            [
                "type : note_on",
                "deltatime : 97",
                "event_id : 144",
                "time : 133.33333333333331",
                "duaration : 31.649305555555543",
                "pitch : 79",
                "velocity : 80",
                "is_drum : False"
            ],
            [
                "type : note_on",
                "deltatime : 97",
                "event_id : 144",
                "time : 99.99999999999999",
                "duaration : 31.649305555555557",
                "pitch : 77",
                "velocity : 80",
                "is_drum : False"
            ],
            [
                "type : note_on",
                "deltatime : 97",
                "event_id : 144",
                "time : 66.66666666666666",
                "duaration : 31.649305555555557",
                "pitch : 76",
                "velocity : 80",
                "is_drum : False"
            ],
            [
                "type : note_on",
                "deltatime : 97",
                "event_id : 144",
                "time : 33.33333333333333",
                "duaration : 31.649305555555557",
                "pitch : 74",
                "velocity : 80",
                "is_drum : False"
            ],
            [
                "type : note_on",
                "deltatime : 0",
                "event_id : 144",
                "time : 0.0",
                "duaration : 31.649305555555554",
                "pitch : 72",
                "velocity : 80",
                "is_drum : False"
            ]
        ]
    }
]

Notesequence@to_abs_midi

Convert NoteSequece to AbsoluteMidi object.

>>> from rmidi.dataset import NoteSequence
>>> ns = NoteSequence(filepath)
>>> absmidi = ns.to_abs_midi()
>>> print(type(absmidi))

Output

<class 'rmidi.absolutemidi.AbsoluteMidi'>

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rmidi-0.0.37.tar.gz (34.9 kB view details)

Uploaded Source

File details

Details for the file rmidi-0.0.37.tar.gz.

File metadata

  • Download URL: rmidi-0.0.37.tar.gz
  • Upload date:
  • Size: 34.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/46.1.3 requests-toolbelt/0.9.1 tqdm/4.45.0 CPython/3.7.7

File hashes

Hashes for rmidi-0.0.37.tar.gz
Algorithm Hash digest
SHA256 d8cbe057fad1add652ec10ee867422c233964c14ee4078c8e1477f151c7738e3
MD5 496871ad9feea8cdc4ad12dca7c5acf7
BLAKE2b-256 97ea1aeda99b35cdc156bf29ab5fa7ad28a00a54b4e301d43850a160740a5043

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page