7 scale_steps = [0,2,4,5,7,9,11]
9 def split_track (track):
17 e = (e[0], tuple ([data[0] & 0xf0] + data[1:]))
25 for v in chs.values ():
26 ns = notes_on_channel (v)
27 dinges = unthread_notes (ns)
29 whatarewes.append (dinges)
34 def __init__ (self, duration, pitch, velocity):
35 self.velocity = velocity
37 self.duration = duration
39 def duration_compare (a,b):
40 if a.duration < b.duration :
42 elif a.duration > b.duration:
47 def notes_on_channel (channel):
54 if e[1][0] == midi.NOTE_ON:
55 if not pitches.has_key (e[1][1]):
56 pitches[e[1][1]] = (t, e[1][2])
57 elif e[1][0] == midi.NOTE_OFF:
59 (lt, vel) = pitches[e[1][1]]
62 nch.append ((t, Note (t-lt, e[1][1], vel)))
71 def unthread_notes (channel):
80 if (t == start_busy_t and e[1].duration + t == end_busy_t) \
84 end_busy_t = t + e[1].duration
87 threads.append (thread)
103 return 's' + dump_duration (dt)
105 def dump_duration (dur):
108 (p,q) = (dur / g, 384 / g)
109 if (p == 1 and q == 1) :
119 def dump_note (note):
125 while i < len (scale_steps):
126 if scale_steps[i] > step:
131 str = chr ((i + 2) % 7 + ord ('a'))
132 if scale_steps[i] <> step:
135 return ' %s' % str + dump_duration (note.duration)
140 s = dump_note (ch[0])
142 s = '<' + string.join (map (dump_note, ch)) + '>'
146 def dump_channel (thread):
152 if last_e and last_e[0] == e[0]:
156 chs.append ((last_e[0], ch))
163 chs.append ((last_e[0], ch))
171 s = s + dump_skip (t-last_t)
173 s = s + dump_chord (ch[1])
174 last_t = t + ch[1][0].duration
178 def dump_notes (channel):
183 s = s + dump_chord (on_hold)
190 def dump_track (channels, n):
192 track = 'track%c' % (n + ord ('A'))
193 for i in range (len (channels)):
194 channel = 'channel%c' % (i + ord ('A'))
195 s = s + '%s = \\context Thread=%s \\notes {\n' % (track + channel, track + channel)
196 s = s + ' ' + dump_channel (channels[i][0])
199 s = s + '%s = \\context Staff=%s <\n' % (track, track)
201 for i in range (len (channels)):
202 channel = 'channel%c' % (i + ord ('A'))
203 s = s + ' \\context Voice = %s \\%s\n' % (channel, track + channel)
208 def convert_midi (f):
209 str = open (f).read ()
210 midi_dump = midi.parse (str)
213 for t in midi_dump[1]:
214 tracks.append (split_track (t))
217 for i in range (len (tracks)):
218 s = s + dump_track (tracks[i], i)
220 s = s + '\n\\score {\n <\n'
221 for i in range (len (tracks)):
222 track = 'track%c' % (i + ord ('A'))
223 s = s + ' \\context Staff=%s \\%s\n' % (track, track)
229 for f in sys.argv[1:]: