]> CRI, Mines Paris - PSL - minwii.git/blobdiff - src/mxmMidi/MidiFileParser.py
ménage (par le vide)
[minwii.git] / src / mxmMidi / MidiFileParser.py
diff --git a/src/mxmMidi/MidiFileParser.py b/src/mxmMidi/MidiFileParser.py
deleted file mode 100644 (file)
index 2b447bc..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-# -*- coding: ISO-8859-1 -*-\r
-\r
-# std library\r
-from struct import unpack\r
-\r
-# uhh I don't really like this, but there are so many constants to \r
-# import otherwise\r
-from constants import *\r
-\r
-from EventDispatcher import EventDispatcher\r
-\r
-class MidiFileParser:\r
-\r
-    """\r
-    \r
-    The MidiFileParser is the lowest level parser that see the data as \r
-    midi data. It generates events that gets triggered on the outstream.\r
-    \r
-    """\r
-\r
-    def __init__(self, raw_in, outstream):\r
-\r
-        """\r
-        raw_data is the raw content of a midi file as a string.\r
-        """\r
-\r
-        # internal values, don't mess with 'em directly\r
-        self.raw_in = raw_in\r
-        self.dispatch = EventDispatcher(outstream)\r
-\r
-        # Used to keep track of stuff\r
-        self._running_status = None\r
-\r
-\r
-\r
-\r
-    def parseMThdChunk(self):\r
-        \r
-        "Parses the header chunk"\r
-        \r
-        raw_in = self.raw_in\r
-\r
-        header_chunk_type = raw_in.nextSlice(4)\r
-        header_chunk_zise = raw_in.readBew(4)\r
-\r
-        # check if it is a proper midi file\r
-        if header_chunk_type != 'MThd':\r
-            raise TypeError, "It is not a valid midi file!"\r
-\r
-        # Header values are at fixed locations, so no reason to be clever\r
-        self.format = raw_in.readBew(2)\r
-        self.nTracks = raw_in.readBew(2)\r
-        self.division = raw_in.readBew(2)\r
-        \r
-        # Theoretically a header larger than 6 bytes can exist\r
-        # but no one has seen one in the wild\r
-        # But correctly ignore unknown data if it is though\r
-        if header_chunk_zise > 6:\r
-            raw_in.moveCursor(header_chunk_zise-6)\r
-\r
-        # call the header event handler on the stream\r
-        self.dispatch.header(self.format, self.nTracks, self.division)\r
-\r
-\r
-\r
-    def parseMTrkChunk(self):\r
-        \r
-        "Parses a track chunk. This is the most important part of the parser."\r
-        \r
-        # set time to 0 at start of a track\r
-        self.dispatch.reset_time()\r
-        \r
-        dispatch = self.dispatch\r
-        raw_in = self.raw_in\r
-        \r
-        # Trigger event at the start of a track\r
-        dispatch.start_of_track(self._current_track)\r
-        # position cursor after track header\r
-        raw_in.moveCursor(4)\r
-        # unsigned long is 4 bytes\r
-        tracklength = raw_in.readBew(4)\r
-        track_endposition = raw_in.getCursor() + tracklength # absolute position!\r
-\r
-        while raw_in.getCursor() < track_endposition:\r
-        \r
-            # find relative time of the event\r
-            time = raw_in.readVarLen()\r
-            dispatch.update_time(time)\r
-            \r
-            # be aware of running status!!!!\r
-            peak_ahead = raw_in.readBew(move_cursor=0)\r
-            if (peak_ahead & 0x80): \r
-                # the status byte has the high bit set, so it\r
-                # was not running data but proper status byte\r
-                status = self._running_status = raw_in.readBew()\r
-            else:\r
-                # use that darn running status\r
-                status = self._running_status\r
-                # could it be illegal data ?? Do we need to test for that?\r
-                # I need more example midi files to be shure.\r
-                \r
-                # Also, while I am almost certain that no realtime \r
-                # messages will pop up in a midi file, I might need to \r
-                # change my mind later.\r
-\r
-            # we need to look at nibbles here\r
-            hi_nible, lo_nible = status & 0xF0, status & 0x0F\r
-            \r
-            # match up with events\r
-\r
-            # Is it a meta_event ??\r
-            # these only exists in midi files, not in transmitted midi data\r
-            # In transmitted data META_EVENT (0xFF) is a system reset\r
-            if status == META_EVENT:\r
-                meta_type = raw_in.readBew()\r
-                meta_length = raw_in.readVarLen()\r
-                meta_data = raw_in.nextSlice(meta_length)\r
-                dispatch.meta_event(meta_type, meta_data)\r
-\r
-\r
-            # Is it a sysex_event ??\r
-            elif status == SYSTEM_EXCLUSIVE:\r
-                # ignore sysex events\r
-                sysex_length = raw_in.readVarLen()\r
-                # don't read sysex terminator\r
-                sysex_data = raw_in.nextSlice(sysex_length-1)\r
-                # only read last data byte if it is a sysex terminator\r
-                # It should allways be there, but better safe than sorry\r
-                if raw_in.readBew(move_cursor=0) == END_OFF_EXCLUSIVE:\r
-                    eo_sysex = raw_in.readBew()\r
-                dispatch.sysex_event(sysex_data)\r
-                # the sysex code has not been properly tested, and might be fishy!\r
-\r
-\r
-            # is it a system common event?\r
-            elif hi_nible == 0xF0: # Hi bits are set then\r
-                data_sizes = {\r
-                    MTC:1,\r
-                    SONG_POSITION_POINTER:2,\r
-                    SONG_SELECT:1,\r
-                }\r
-                data_size = data_sizes.get(hi_nible, 0)\r
-                common_data = raw_in.nextSlice(data_size)\r
-                common_type = lo_nible\r
-                dispatch.system_common(common_type, common_data)\r
-            \r
-\r
-            # Oh! Then it must be a midi event (channel voice message)\r
-            else:\r
-                data_sizes = {\r
-                    PATCH_CHANGE:1,\r
-                    CHANNEL_PRESSURE:1,\r
-                    NOTE_OFF:2,\r
-                    NOTE_ON:2,\r
-                    AFTERTOUCH:2,\r
-                    CONTINUOUS_CONTROLLER:2,\r
-                    PITCH_BEND:2,\r
-                }\r
-                data_size = data_sizes.get(hi_nible, 0)\r
-                channel_data = raw_in.nextSlice(data_size)\r
-                event_type, channel = hi_nible, lo_nible\r
-                dispatch.channel_messages(event_type, channel, channel_data)\r
-\r
-\r
-    def parseMTrkChunks(self):\r
-        "Parses all track chunks."\r
-        for t in range(self.nTracks):\r
-            self._current_track = t\r
-            self.parseMTrkChunk() # this is where it's at!\r
-        self.dispatch.eof()\r
-\r
-\r
-\r
-if __name__ == '__main__':\r
-\r
-    # get data\r
-    test_file = 'test/midifiles/minimal.mid'\r
-    test_file = 'test/midifiles/cubase-minimal.mid'\r
-    test_file = 'test/midifiles/Lola.mid'\r
-#    f = open(test_file, 'rb')\r
-#    raw_data = f.read()\r
-#    f.close()\r
-#    \r
-#    \r
-#    # do parsing\r
-    from MidiToText import MidiToText\r
-    from RawInstreamFile import RawInstreamFile\r
-\r
-    midi_in = MidiFileParser(RawInstreamFile(test_file), MidiToText())\r
-    midi_in.parseMThdChunk()\r
-    midi_in.parseMTrkChunks()\r
-    
\ No newline at end of file