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