problems with midi programming in python
bvdp at xplornet.com
bvdp at xplornet.com
Wed Jul 5 19:36:15 EDT 2006
sreekant wrote:
> Hi folks
>
> I hope someone here might be able to help. I scavenged some info and
> even code from the net and am trying to write a module that reads a text
> file and spits out a midi file.
>
> So far I managed to make it work to the level of reading a text file
> with appropriate notes, octaves, transposing, volume, aftertouch,
> polyphony, channeltouch etc.
>
> However I am stuck at writing notes longer than 127 decimal number.
>
> The code I am using is below. I didn't post the whole code to keep it
> brief. If it is ok I will post the whole.
>
> ###########################################
> def note_on(self, time, channel, note, velocity):
> return varLen(time) + [0x90 + channel, note, velocity]
>
> def varLen(value):
> # Big endian variable byte word
> # as defined by the midi standard
> result = []
> while value:
> result.append((value & 0x7F) | 0x80)
> value = value >> 7
> if len(result) == 0:
> return [0]
> else:
> result[len(result)-1] -= 128
> result.reverse()
> return result
> #############################################
>
> note_on should accept time,channel,note and velocity as decimals.
>
> Note and velocity are not a problem as their numbers are small.
>
> If I want to put a note that lasts say longer than 127, fluidsynth moans
> saying unexpected eof or unexpected byte 0xfe.
>
> What I would like to do is, to be able to
> note_on(1500,1,60,120)
> 1500 being the problem.
>
> Midi file standard says that time is written as a variable length
> entity. so if 1500 does not fit in a byte it should then use as many
> bytes as needed, but all bytes except last one have their msb set to 1
> to show there is more to come.
>
> Below is the output of mftext for a working and nonworking midi files
> respectively.
> ############## playing a single 'a' note ############ working fine ###
> Header format=1 ntrks=2 division=24
> Track start
> Time=0 Tempo, microseconds-per-MIDI-quarter-note=500000
> Time=0 Time signature=4/4 MIDI-clocks/click=24
> 32nd-notes/24-MIDI-clocks=8
> Time=0 Meta event, end of track
> Track end
> Track start
> Time=0 Program, chan=1 program=1
> Time=0 Note on, chan=1 pitch=57 vol=127
> Time=127 Note off, chan=1 pitch=57 vol=0
> Time=127 Meta event, end of track
> Track end
> ######################################################
>
> ######### playing a single a note, with double the 127 duration##
> ########not working############################################
> Header format=1 ntrks=2 division=24
> Track start
> Time=0 Tempo, microseconds-per-MIDI-quarter-note=500000
> Time=0 Time signature=4/4 MIDI-clocks/click=24
> 32nd-notes/24-MIDI-clocks=8
> Time=0 Meta event, end of track
> Track end
> Track start
> Time=0 Program, chan=1 program=1
> Time=0 Note on, chan=1 pitch=57 vol=127
> Error: unexpected byte: 0xfe
> #########################################################
>
> What am I doing wrong!!!!!!
>
> Help appreciated.
> ta
> sree
Here's a snippit which does work:
def intToVarNumber(x):
""" Convert INT to a variable length MIDI value. """
lst = chr(x & 0x7f)
while 1:
x = x >> 7
if x:
lst = chr((x & 0x7f) | 0x80) + lst
else:
return lst
See my program MMA for lots of ugly tricks.
http://users.xplornet.com/~bvdp/mma
Best,
More information about the Python-list
mailing list