Python Midi Package: writing events non-chronologically

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • tim

    #1

    Python Midi Package: writing events non-chronologically

    Someone using Python Midi Package from
    http://www.mxm.dk/products/public/ lately?

    I want to do the following :
    write some note events in a midi file
    then after doing that, put some controllers at the beginning of the
    midifile
    (because I want to be able to make those dependant on what notes were
    just written)

    def midctrls():
    global roffset, melchan, roffset, gmt, timedisplay, out_file, midi,
    usednotes, n
    midi.reset_time () #seems to do nothing
    for cha in range(16):
    if cha==1:
    midi.abs_time=0 #seems to do nothing
    midi._relative_ time = 0 #seems to do nothing, but I can
    imagine why
    midi._absolute_ time = 0 #seems to do nothing
    midi.update_tim e(new_time=0, relative=0) #although I give
    the variable relative=0 it seems to be relative ?
    midi.continuous _controller(cha , 0, 122)
    (snip)

    With this code I want a controller number 0 with value 122 to be written
    at the beginning of my midifile.
    It is written at the end, how I move the writing position to the beginning?

    thanks for any help!


  • Max M

    #2
    Re: Python Midi Package: writing events non-chronologically

    tim wrote:[color=blue]
    > Someone using Python Midi Package from
    > http://www.mxm.dk/products/public/ lately?
    >
    > I want to do the following :
    > write some note events in a midi file
    > then after doing that, put some controllers at the beginning of the
    > midifile
    > (because I want to be able to make those dependant on what notes were
    > just written)
    >
    > def midctrls():
    > global roffset, melchan, roffset, gmt, timedisplay, out_file, midi,
    > usednotes, n
    > midi.reset_time () #seems to do nothing
    > for cha in range(16):
    > if cha==1:
    > midi.abs_time=0 #seems to do nothing
    > midi._relative_ time = 0 #seems to do nothing, but I can
    > imagine why
    > midi._absolute_ time = 0 #seems to do nothing
    > midi.update_tim e(new_time=0, relative=0) #although I give
    > the variable relative=0 it seems to be relative ?
    > midi.continuous _controller(cha , 0, 122)
    > (snip)
    >
    > With this code I want a controller number 0 with value 122 to be written
    > at the beginning of my midifile.
    > It is written at the end, how I move the writing position to the beginning?
    >[/color]


    You should make a wrapper around the library that handles the midi
    events in a data structure.

    When your musical structure is then is complete, you use the midi
    library to write it to disk.

    I have attached a simple example here.

    --

    hilsen/regards Max M, Denmark

    A small collection of CLAP synths and effects inspired by classic hardware.

    IT's Mad Science

    # event classes. Only used internally by notes2midi
    class NoteOn:

    def __init__(self, time=0, pitch=64, velocity=64):
    self.time = time
    self.pitch = pitch
    self.velocity = velocity

    def __str__(self):
    r = []
    a = r.append
    a('NoteOn')
    a('time %s' % self.time)
    a('pitch %s' % self.pitch)
    a('velocity %s' % self.velocity)
    return '\n'.join(r)

    def render(self, channel, mididevice):
    "Writes the event to a midi stream"
    mididevice.note _on(channel=cha nnel, note=self.pitch , velocity=self.v elocity)



    class NoteOff:

    def __init__(self, time=0, pitch=64, velocity=64):
    self.time = time
    self.pitch = pitch
    self.velocity = velocity

    def __str__(self):
    r = []
    a = r.append
    a('NoteOff')
    a('time %s' % self.time)
    a('pitch %s' % self.pitch)
    a('velocity %s' % self.velocity)
    return '\n'.join(r)

    def render(self, channel, mididevice):
    "Writes the event to a midi stream"
    mididevice.note _off(channel=ch annel, note=self.pitch , velocity=self.v elocity)




    def notes2midi(note s, midi):
    "Turns a list of notes into a midi stream"
    # notes have absolute time values!!!

    # first turn notes into events (split into note-on / note-off)
    events = []
    for note in notes:
    on_event = NoteOn(note.tim e, note.pitch, note.velocity)
    events.append(o n_event)
    off_event = NoteOff(note.ti me+note.duratio n, note.pitch, note.velocity)
    events.append(o ff_event)
    # sort them in order of time
    events.sort(lam bda x,y: cmp(x.time, y.time))

    # midi device writing
    # non optional midi framework
    midi.header()
    midi.start_of_t rack()
    midi.reset_time ()
    absolute_time = 0
    for event in events:
    delta_time = event.time - absolute_time
    absolute_time = event.time
    # write the data
    midi.update_tim e(delta_time)
    event.render(0, midi)
    midi.end_of_tra ck()
    # non optional midi framework
    midi.update_tim e(0)
    midi.end_of_tra ck()

    midi.eof()


    if __name__ == '__main__':

    from Pattern import Note

    # a short example using notes, with no limits to number of simultaneous voices
    # creates a list of ascending notes
    track = [
    Note(time=24*i, pitch=64+i, velocity=127, duration=24)
    for i in range(16)
    ]


    ############### ###
    # write the notes to the file

    from midi.MidiOutFil e import MidiOutFile

    out_file = 'note-test.mid'
    midi = MidiOutFile(out _file)
    notes2midi(trac k, midi)

    Comment

    Working...