.. _moduleMidi.base:

music21.midi.base
=================

.. WARNING: DO NOT EDIT THIS FILE: AUTOMATICALLY GENERATED. Edit the .py file directly

.. module:: music21.midi.base


Objects and tools for processing MIDI data.

This module uses routines from Will Ware's public domain midi.py from 2001
see http://groups.google.com/group/alt.sources/msg/0c5fc523e050c35e




.. function:: charToBinary(char)


    Convert a char into its binary representation. Useful for debugging.



    >>> from music21 import *
    >>> midi.charToBinary('a')
    '01100001'



.. function:: getNumber(str, length)

    Return the value of a string byte from an 8-bit string. Then, return the remaining string.

    The `length` is the number of chars to read.

    This will sum a length greater than 1 if desired.

    Note that MIDI uses big-endian for everything
    in python this is the inverse of chr()



    >>> from music21 import *
    >>> midi.getNumber('test', 0)
    (0, 'test')
    >>> midi.getNumber('test', 2)
    (29797, 'st')
    >>> midi.getNumber('test', 4)
    (1952805748, '')



.. function:: getNumbersAsList(str)


    Translate each char into a number, return in a list.
    Used for reading data messages where each byte encodes
    a different discrete value.



    >>> from music21 import *
    >>> midi.getNumbersAsList('\x00\x00\x00\x03')
    [0, 0, 0, 3]



.. function:: getVariableLengthNumber(str)


    Given a string of data, strip off a number that might be of variable
    size; after finding the appropriate termination,
    return the remaining string.

    This necessary as DeltaTime times are given with variable size,
    and thus may be if different numbers of characters.



    >>> from music21 import *
    >>> midi.getVariableLengthNumber('A-u')
    (65, '-u')
    >>> midi.getVariableLengthNumber('-u')
    (45, 'u')
    >>> midi.getVariableLengthNumber('u')
    (117, '')
    ⁠ 
    >>> midi.getVariableLengthNumber('test')
    (116, 'est')
    >>> midi.getVariableLengthNumber('E@-E')
    (69, '@-E')
    >>> midi.getVariableLengthNumber('@-E')
    (64, '-E')
    >>> midi.getVariableLengthNumber('-E')
    (45, 'E')
    >>> midi.getVariableLengthNumber('E')
    (69, '')



    >>> midi.getVariableLengthNumber('\xff\x7f')
    (16383, '')



.. function:: intsToHexString(intList)


    Convert a list of integers into a hex string, suitable for testing MIDI encoding.



    >>> from music21 import *
    >>> # note on, middle c, 120 velocity
    >>> midi.intsToHexString([144, 60, 120])
    '\x90<x'



.. function:: putNumber(num, length)


    Put a single number as a hex number at the end of a string `length` bytes long.



    >>> from music21 import *
    >>> midi.putNumber(3, 4)
    '\x00\x00\x00\x03'
    >>> midi.putNumber(0, 1)
    '\x00'



.. function:: putNumbersAsList(numList)


    Translate a list of numbers (0-255) into a character byte strings.
    Used for encoding data messages where each byte encodes a different discrete value.



    >>> from music21 import *
    >>> midi.putNumbersAsList([0, 0, 0, 3])
    '\x00\x00\x00\x03'

    If a number is < 0 but >= -256 then it wraps around from the top.



    >>> midi.putNumbersAsList([0, 0, 0, -3])
    '\x00\x00\x00\xfd'
    >>> midi.putNumbersAsList([0, 0, 0, -1])
    '\x00\x00\x00\xff'



.. function:: putVariableLengthNumber(x)




    >>> from music21 import *
    >>> midi.putVariableLengthNumber(4)
    '\x04'
    >>> midi.putVariableLengthNumber(127)
    '\x7f'
    >>> midi.putVariableLengthNumber(0)
    '\x00'
    >>> midi.putVariableLengthNumber(1024)
    '\x88\x00'
    >>> midi.putVariableLengthNumber(8192)
    '\xc0\x00'
    >>> midi.putVariableLengthNumber(16383)
    '\xff\x7f'
    ⁠ 
    >>> midi.putVariableLengthNumber(-1)
    Traceback (most recent call last):
    MidiException: cannot putVariableLengthNumber() when number is negative: -1



DeltaTime
---------

Inherits from: :class:`~music21.midi.base.MidiEvent`

.. class:: DeltaTime(track, time=None, channel=None)


    A :class:`~music21.midi.base.MidiEvent` subclass that stores the
    time change (in ticks) since the start or since the last MidiEvent.

    Pairs of DeltaTime and MidiEvent objects are the basic presentation of temporal data.

    The `track` argument must be a :class:`~music21.midi.base.MidiTrack` object.

    Time values are in integers, representing ticks.

    The `channel` attribute, inherited from MidiEvent is not used and set to None
    unless overridden (don't!).



    >>> from music21 import *
    >>> mt = midi.MidiTrack(1)
    >>> dt = midi.DeltaTime(mt)
    >>> dt.time = 380
    >>> dt
    <MidiEvent DeltaTime, t=380, track=1, channel=None>




    **DeltaTime** **properties**

        Properties inherited from :class:`~music21.midi.base.MidiEvent`: :attr:`~music21.midi.base.MidiEvent.data`, :attr:`~music21.midi.base.MidiEvent.pitch`, :attr:`~music21.midi.base.MidiEvent.velocity`

    **DeltaTime** **methods**

        .. method:: read(oldstr)

            No documentation.


        .. method:: write()

            No documentation.


        Methods inherited from :class:`~music21.midi.base.MidiEvent`: :meth:`~music21.midi.base.MidiEvent.isDeltaTime`, :meth:`~music21.midi.base.MidiEvent.isNoteOff`, :meth:`~music21.midi.base.MidiEvent.isNoteOn`, :meth:`~music21.midi.base.MidiEvent.matchedNoteOff`, :meth:`~music21.midi.base.MidiEvent.setPitchBend`, :meth:`~music21.midi.base.MidiEvent.updateSortOrder`


Enumeration
-----------



.. class:: Enumeration(enumList)


    Utility object for defining binary MIDI message constants.



    **Enumeration** **methods**

        .. method:: hasValue(attr)

            No documentation.


        .. method:: hasattr(attr)

            No documentation.


        .. method:: whatis(value)

            No documentation.



MidiEvent
---------



.. class:: MidiEvent(track, type=None, time=None, channel=None)


    A model of a MIDI event, including note-on, note-off, program change, controller change, any many others.

    MidiEvent objects are paired (preceded) by :class:`~music21.midi.base.DeltaTime`
    objects in the list of events in a MidiTrack object.

    The `track` argument must be a :class:`~music21.midi.base.MidiTrack` object.

    The `type` attribute is a string representation of a Midi event from the channelVoiceMessages
    or metaEvents definitions.

    The `channel` attribute is an integer channel id, from 1 to 16.

    The `time` attribute is an integer duration of the event in ticks. This value
    can be zero. This value is not essential, as ultimate time positioning is
    determined by :class:`~music21.midi.base.DeltaTime` objects.

    The `pitch` attribute is only defined for note-on and note-off messages.
    The attribute stores an integer representation (0-127, with 60 = middle C).

    The `velocity` attribute is only defined for note-on and note-off messages.
    The attribute stores an integer representation (0-127).  A note-on message with
    velocity 0 is generally assumed to be the same as a note-off message.

    The `data` attribute is used for storing other messages,
    such as SEQUENCE_TRACK_NAME string values.



    >>> from music21 import *
    >>> mt = midi.MidiTrack(1)
    >>> me1 = midi.MidiEvent(mt)
    >>> me1.type = "NOTE_ON"
    >>> me1.channel = 3
    >>> me1.time = 200
    >>> me1.pitch = 60
    >>> me1.velocity = 120
    >>> me1
    <MidiEvent NOTE_ON, t=200, track=1, channel=3, pitch=60, velocity=120>
    ⁠ 
    >>> me2 = midi.MidiEvent(mt)
    >>> me2.type = "SEQUENCE_TRACK_NAME"
    >>> me2.time = 0
    >>> me2.data = 'guitar'
    >>> me2
    <MidiEvent SEQUENCE_TRACK_NAME, t=0, track=1, channel=None, data='guitar'>



    **MidiEvent** **properties**

        .. attribute:: data

            No documentation.


        .. attribute:: pitch

            No documentation.


        .. attribute:: velocity

            No documentation.


    **MidiEvent** **methods**

        .. method:: isDeltaTime()


            Return a boolean if this is a DeltaTime subclass.



            >>> from music21 import *
            >>> mt = midi.MidiTrack(1)
            >>> dt = midi.DeltaTime(mt)
            >>> dt.isDeltaTime()
            True



        .. method:: isNoteOff()


            Return a boolean if this is should be interpreted as a note-off message,
            either as a real note-off or as a note-on with zero velocity.



            >>> from music21 import *
            >>> mt = midi.MidiTrack(1)
            >>> me1 = midi.MidiEvent(mt)
            >>> me1.type = "NOTE_OFF"
            >>> me1.isNoteOn()
            False
            >>> me1.isNoteOff()
            True
            ⁠ 
            >>> me2 = midi.MidiEvent(mt)
            >>> me2.type = "NOTE_ON"
            >>> me2.velocity = 0
            >>> me2.isNoteOn()
            False
            >>> me2.isNoteOff()
            True



        .. method:: isNoteOn()


            Return a boolean if this is a note-on message and velocity is not zero.



            >>> from music21 import *
            >>> mt = midi.MidiTrack(1)
            >>> me1 = midi.MidiEvent(mt)
            >>> me1.type = "NOTE_ON"
            >>> me1.velocity = 120
            >>> me1.isNoteOn()
            True
            >>> me1.isNoteOff()
            False



        .. method:: matchedNoteOff(other)


            Returns True if `other` is a MIDI event that specifies
            a note-off message for this message.  That is, this event
            is a NOTE_ON message, and the other is a NOTE_OFF message
            for this pitch on this channel.  Otherwise returns False



            >>> from music21 import *
            >>> mt = midi.MidiTrack(1)
            >>> me1 = midi.MidiEvent(mt)
            >>> me1.type = "NOTE_ON"
            >>> me1.velocity = 120
            >>> me1.pitch = 60
            ⁠ 
            >>> me2 = midi.MidiEvent(mt)
            >>> me2.type = "NOTE_ON"
            >>> me2.velocity = 0
            >>> me2.pitch = 60



            >>> me1.matchedNoteOff(me2)
            True
            ⁠ 
            >>> me2.pitch = 61
            >>> me1.matchedNoteOff(me2)
            False



            >>> me2.type = "NOTE_OFF"
            >>> me1.matchedNoteOff(me2)
            False
            ⁠ 
            >>> me2.pitch = 60
            >>> me1.matchedNoteOff(me2)
            True



            >>> me2.channel = 12
            >>> me1.matchedNoteOff(me2)
            False




        .. method:: read(time, str)


            Parse the string that is given and take the beginning
            section and convert it into data for this event and return the
            now truncated string.



            The `time` value is the number of ticks into the Track
            at which this event happens. This is derived from reading
            data the level of the track.

            TODO: These instructions are inadequate.



            >>> # all note-on messages (144-159) can be found
            >>> 145 & 0xF0 # testing message type extraction
            144
            >>> 146 & 0xF0 # testing message type extraction
            144
            >>> (144 & 0x0F) + 1 # getting the channel
            1
            >>> (159 & 0x0F) + 1 # getting the channel
            16



        .. method:: setPitchBend(cents, bendRange=2)

            Treat this event as a pitch bend value, and set the ._parameter1 and ._parameter2 fields appropriately given a specified bend value in cents.

            The `bendRange` parameter gives the number of half steps in the bend range.



            >>> from music21 import *
            >>> mt = midi.MidiTrack(1)
            >>> me1 = midi.MidiEvent(mt)
            >>> me1.setPitchBend(50)
            >>> me1._parameter1, me1._parameter2
            (0, 80)
            >>> me1.setPitchBend(100)
            >>> me1._parameter1, me1._parameter2
            (0, 96)
            >>> me1.setPitchBend(200)
            >>> me1._parameter1, me1._parameter2
            (127, 127)
            >>> me1.setPitchBend(-50)
            >>> me1._parameter1, me1._parameter2
            (0, 48)
            >>> me1.setPitchBend(-100)
            >>> me1._parameter1, me1._parameter2
            (0, 32)



        .. method:: updateSortOrder()

            No documentation.


        .. method:: write()


            Write out a midi track.




MidiFile
--------



.. class:: MidiFile()


    Low-level MIDI file writing, emulating methods from normal Python files.

    The `ticksPerQuarterNote` attribute must be set before writing. 1024 is a common value.

    This object is returned by some properties for directly writing files of midi representations.



    **MidiFile** **attributes**

        Attributes without Documentation: `ticksPerSecond`, `tracks`, `ticksPerQuarterNote`, `file`, `format`

    **MidiFile** **methods**

        .. method:: close()


            Close the file.



        .. method:: open(filename, attrib='rb')


            Open a MIDI file path for reading or writing.

            For writing to a MIDI file, `attrib` should be "wb".



        .. method:: openFileLike(fileLike)

            Assign a file-like object, such as those provided by StringIO, as an open file object.



            >>> import StringIO  # in python3.0 use "from io import StringIO"
            >>> from music21 import *
            >>> fileLikeOpen = StringIO.StringIO()
            >>> mf = midi.MidiFile()
            >>> mf.openFileLike(fileLikeOpen)
            >>> mf.close()



        .. method:: read()


            Read and parse MIDI data stored in a file.



        .. method:: readstr(str)


            Read and parse MIDI data as a string.



        .. method:: write()


            Write MIDI data as a file.



        .. method:: writestr()


            Return MIDI data as a string.




MidiTrack
---------



.. class:: MidiTrack(index)


    A MIDI Track. Each track contains a list of
    :class:`~music21.midi.base.MidiChannel` objects, one for each channel.

    All events are stored in the `events` list, in order.

    An `index` is an integer identifier for this object.


    TODO: Better Docs



    >>> from music21 import *
    >>> mt = midi.MidiTrack(0)




    **MidiTrack** **methods**

        .. method:: getChannels()

            Get all channels used in this Track.



        .. method:: getProgramChanges()

            Get all unique program changes used in this Track, sorted.



        .. method:: hasNotes()

            Return True/False if this track has any note-on/note-off pairs defined.



        .. method:: read(str)


            Read as much of the string (representing midi data) as necessary;
            return the remaining string for reassignment and further processing.

            The string should begin with `MTrk`, specifying a Midi Track

            Creates and stores :class:`~music21.midi.base.DeltaTime`
            and :class:`~music21.midi.base.MidiEvent` objects.



        .. method:: setChannel(value)

            Set the channel of all events in this Track.



        .. method:: updateEvents()


            We may attach events to this track before setting their `track` parameter.
            This method will move through all events and set their track to this track.



        .. method:: write()


            returns a string of midi-data from the `.events` in the object.




