import sys
import string
+LINE_BELL = 60
scale_steps = [0,2,4,5,7,9,11]
def split_track (track):
chs[i] = []
for e in track:
- data = list (e[1])
- c = data[0] & 0x0f
- e = (e[0], tuple ([data[0] & 0xf0] + data[1:]))
- chs[c].append (e)
+ data = list (e[1])
+ if data[0] > 0x7f and data[0] < 0xf0:
+ c = data[0] & 0x0f
+ e = (e[0], tuple ([data[0] & 0xf0] + data[1:]))
+ chs[c].append (e)
+ else:
+ chs[0].append (e)
for i in range (16):
if chs[i] == []:
self.pitch = pitch
self.duration = duration
- def duration_compare (a,b):
- if a.duration < b.duration :
+ def duration_compare (a, b):
+ if a.duration < b.duration:
return -1
elif a.duration > b.duration:
return 1
else:
return 0
-
+
+ def dump (self):
+ return dump_note (self)
+
+class Time:
+ def __init__ (self, t, num, den):
+ self.duration = t
+ self.num = num
+ self.den = den
+
+ def dump (self):
+ return dump_skip (self.duration) + '\\time %d/%d ' % (self.num, self.den)
+
+key_sharps = ('c', 'g', 'd', 'a', 'e', 'b', 'fis')
+key_flats = ('BUG', 'f', 'bes', 'es', 'as', 'des', 'ges')
+
+class Key:
+ def __init__ (self, t, sharps, flats, minor):
+ self.duration = t
+ self.flats = flats
+ self.sharps = sharps
+ self.minor = minor
+
+ def dump (self):
+ if self.sharps and self.flats:
+ s = '\\keysignature %s ' % 'TODO'
+ elif self.sharps:
+ s = '\\notes\\key %s \major' % key_sharps[self.sharps]
+ elif self.flats:
+ s = '\\notes\\key %s \major' % key_flats[self.flats]
+ return dump_skip (self.duration) + s
+
+
+class Text:
+ def __init__ (self, text):
+ self.text = text
+ self.duration = 0
+
+ def dump (self):
+ return dump_text (self)
+
def notes_on_channel (channel):
pitches = {}
except KeyError:
pass
+ elif e[1][0] == midi.META_EVENT:
+ if e[1][1] == midi.TIME_SIGNATURE:
+ (num, den, clocks4, count32) = map (ord, e[1][2])
+ nch.append ((t, Time (t, num, den)))
+ elif e[1][1] == midi.KEY_SIGNATURE:
+ (accidentals, minor) = map (ord, e[1][2])
+ sharps = 0
+ flats = 0
+ if accidentals < 127:
+ sharps = accidentals
+ else:
+ flats = 256 - accidentals
+ nch.append ((t, Key (t, sharps, flats, minor)))
+ elif e[1][1] == midi.TEXT_EVENT:
+ nch.append ((t, Text (e[1][2])))
+ else:
+ sys.stderr.write ("SKIP: %s\n" % `e`)
+ pass
else:
+ sys.stderr.write ("SKIP: %s\n" % `e`)
pass
return nch
todo = []
for e in channel:
t = e[0]
- if (t == start_busy_t and e[1].duration + t == end_busy_t) \
- or t >= end_busy_t:
+ if e[1].__class__ == Note and ((t == start_busy_t and e[1].duration + t == end_busy_t) \
+ or t >= end_busy_t):
thread.append (e)
start_busy_t = t
end_busy_t = t + e[1].duration
+ elif e[1].__class__ == Time or e[1].__class__ == Key or e[1].__class__ == Text:
+ thread.append (e)
else:
- todo.append(e)
+ todo.append (e)
threads.append (thread)
channel = todo
pass
else:
if p <> 1:
- s = '*%d'% p
+ s = s + '*%d'% p
if q <> 1:
- s = '*%d'% q
+ s = s + '*%d'% q
return s
-
def dump_note (note):
p = note.pitch
oct = p / 12
return ' %s' % str + dump_duration (note.duration)
+def dump (self):
+ return self.dump ()
+
+def dump_text (text):
+ return '\n % ' + text.text + '\n '
+
def dump_chord (ch):
s = ''
if len(ch) == 1:
- s = dump_note (ch[0])
+ s = dump (ch[0])
else:
- s = '<' + string.join (map (dump_note, ch)) + '>'
+ s = '<' + string.join (map (dump, ch)) + '>'
return s
# thread?
t = 0
last_t = 0
- s = ''
+ lines = ['']
for ch in chs:
+ if len (lines[-1]) > LINE_BELL:
+ lines.append ('')
+
t = ch[0]
if t - last_t:
- s = s + dump_skip (t-last_t)
+ lines[-1] = lines[-1] + dump_skip (t-last_t)
- s = s + dump_chord (ch[1])
+ lines[-1] = lines[-1] + dump_chord (ch[1])
+
last_t = t + ch[1][0].duration
-
- return s
+
+ return string.join (lines, '\n ') + '\n'
def dump_notes (channel):
on_hold = []
on_hold.append (e)
return s
+def track_name (i):
+ return 'track%c' % (i + ord ('A'))
+
+def channel_name (i):
+ return 'channel%c' % (i + ord ('A'))
+
def dump_track (channels, n):
- s = ''
- track = 'track%c' % (n + ord ('A'))
+ s = '\n'
+ track = track_name (n)
for i in range (len (channels)):
- channel = 'channel%c' % (i + ord ('A'))
- s = s + '%s = \\context Thread=%s \\notes {\n' % (track + channel, track + channel)
+ channel = channel_name (i)
+ s = s + '%s = \\notes {\n' % (track + channel)
s = s + ' ' + dump_channel (channels[i][0])
- s = s + '\n}\n'
+ s = s + '}\n\n'
- s = s + '%s = \\context Staff=%s <\n' % (track, track)
+ s = s + '%s = <\n' % track
for i in range (len (channels)):
- channel = 'channel%c' % (i + ord ('A'))
+ channel = channel_name (i)
s = s + ' \\context Voice = %s \\%s\n' % (channel, track + channel)
- s = s + '\n>\n'
+ s = s + '>\n\n'
return s
s = s + '\n\\score {\n <\n'
for i in range (len (tracks)):
- track = 'track%c' % (i + ord ('A'))
+ track = track_name (i)
s = s + ' \\context Staff=%s \\%s\n' % (track, track)
- s = s + '\n >\n}\n'
+ s = s + ' >\n}\n'
sys.stdout.write (s)