def chordToMidiFile(inputM21): 
    # this can be consolidated with noteToMidiFile
    c = inputM21

    mt = midiModule.MidiTrack(1)
    mt.events += midiModule.getStartEvents(mt)
    mt.events += chordToMidiEvents(c)
    mt.events += midiModule.getEndEvents(mt)

    # set all events to have this track
    mt.updateEvents()

    mf = midiModule.MidiFile()
    mf.tracks = [mt]
    mf.ticksPerQuarterNote = defaults.ticksPerQuarter
    return mf
def noteToMidiFile(inputM21): 
    '''
    >>> from music21 import note
    >>> n1 = note.Note()
    >>> n1.quarterLength = 6
    >>> mf = noteToMidiFile(n1)
    >>> mf.tracks[0].events
    [<MidiEvent DeltaTime, t=0, track=1, channel=None>, <MidiEvent SEQUENCE_TRACK_NAME, t=0, track=1, channel=None, data=''>, <MidiEvent DeltaTime, t=0, track=1, channel=None>, <MidiEvent NOTE_ON, t=None, track=1, channel=1, pitch=60, velocity=90>, <MidiEvent DeltaTime, t=6144, track=1, channel=None>, <MidiEvent NOTE_OFF, t=None, track=1, channel=1, pitch=60, velocity=0>, <MidiEvent DeltaTime, t=0, track=1, channel=None>, <MidiEvent END_OF_TRACK, t=None, track=1, channel=1, data=''>]
    '''
    n = inputM21
    mt = midiModule.MidiTrack(1)
    mt.events += midiModule.getStartEvents(mt)
    mt.events += noteToMidiEvents(n)
    mt.events += midiModule.getEndEvents(mt)

    # set all events to have this track
    mt.updateEvents()

    mf = midiModule.MidiFile()
    mf.tracks = [mt]
    mf.ticksPerQuarterNote = defaults.ticksPerQuarter
    return mf
def streamToMidiTrack(inputM21, instObj=None, translateTimeSignature=True):

    '''Returns a :class:`music21.midi.base.MidiTrack` object based on the content of this Stream.

    This assumes that this Stream has only one Part. For Streams that contain sub-streams, use streamToMidiTracks.

    >>> from music21 import *
    >>> s = stream.Stream()
    >>> n = note.Note('g#')
    >>> n.quarterLength = .5
    >>> s.repeatAppend(n, 4)
    >>> mt = streamToMidiTrack(s)
    >>> len(mt.events)
    20
    '''

    # NOTE: this procedure requires that there are no overlaps between
    # adjacent events. 

    if instObj is None:
        # see if an instrument is defined in this or a parent stream
        instObj = inputM21.getInstrument()

    # each part will become midi track
    # each needs an id; can be adjusted later
    mt = midiModule.MidiTrack(1)
    mt.events += midiModule.getStartEvents(mt, instObj.partName)

    # initial time is start of this Stream
    #t = self.offset * defaults.ticksPerQuarter
    # should shift at tracks level
    t = 0 * defaults.ticksPerQuarter

    # have to be sorted, have to strip ties
    # retain containers to get all elements: time signatures, dynamics, etc
    s = inputM21.stripTies(inPlace=False, matchByPitch=False, 
        retainContainers=True)
    s = s.flat
    # probably already flat and sorted
    for obj in s.sorted:
        tDurEvent = 0 # the found delta ticks in each event


        #environLocal.printDebug([str(obj).ljust(26), 't', str(t).ljust(10), 'tdif', tDif])

        #if obj.isClass(note.GeneralNote):
        classes = obj.classes

        # test: match to 'GeneralNote'
        if 'Note' in classes or 'Rest' in classes or 'Chord' in classes:
        #if obj.isNote or obj.isRest or obj.isChord:

            # find difference since last event to this event
            # cannot use getOffsetBySite(self), as need flat offset
            # all values are in tpq; t stores abs time in tpq
            tDif = (obj.offset * defaults.ticksPerQuarter) - t

            # includ 'Unpitched'
            if 'Rest' in classes:
                # for a rest, do not do anything: difference in offset will 
                # account for the gap
                continue

            # get a list of midi events
            # suing this property here is easier than using the above conversion
            # methods, as we do not need to know what the object is
            sub = obj.midiEvents

            # a note has 4 events: delta/note-on/delta/note-off
            if 'Note' in classes:
                sub[0].time = int(round(tDif)) # set first delta 
                # get the duration in ticks; this is the delta to 
                # to the note off message; already set when midi events are 
                # obtained
                tDurEvent = int(round(sub[2].time))

            # a chord has delta/note-on/delta/note-off for each memeber
            # of the chord. on the first delta is the offset, and only
            # the first delta preceding the first note-off is the duration
            if 'Chord' in classes:
                # divide events between note-on and note-off
                sub[0].time = int(round(tDif)) # set first delta 
                # only the delta before the first note-off has the event dur
                # could also sum all durations before setting first
                # this is the second half of events
                tDurEvent = int(round(len(sub) / 2))

            # to get new current time, need both the duration of the event
            # as well as any difference found between the last event
            t += tDif + tDurEvent
            # add events to the list
            mt.events += sub

        elif 'Dynamic' in classes:
            pass # configure dynamics

        elif 'TimeSignature' in classes:
            # find difference since last event to this event
            # cannot use getOffsetBySite(self), as need flat offset
            # all values are in tpq; t stores abs time in tpq
            tDif = (obj.offset * defaults.ticksPerQuarter) - t
            # return a pair of events
            sub = timeSignatureToMidiEvents(obj)
            # for a ts, this will usually be zero, but not always
            sub[0].time = int(round(tDif)) # set first delta 
            t += tDif
            mt.events += sub

        elif 'KeySignature' in classes:
            tDif = (obj.offset * defaults.ticksPerQuarter) - t

            environLocal.printDebug([str(obj).ljust(26), 't', str(t).ljust(10), 'tdif', tDif])

            sub = keySignatureToMidiEvents(obj)
            # for a ts, this will usually be zero, but not always
            sub[0].time = int(round(tDif)) # set first delta 
            t += tDif
            mt.events += sub

        else: # other objects may have already been added
            pass

    # must update all events with a ref to this MidiTrack
    mt.updateEvents()
    mt.events += midiModule.getEndEvents(mt)
    return mt