From 39753eb44dccec0d338867adefa6c4c3814e317b Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Fri, 5 Oct 2001 17:32:57 +0200 Subject: [PATCH] patch::: 1.5.14.jcn6 1.5.14.jcn6 --- CHANGES | 4 +- VERSION | 2 +- modules/midi.c | 1 + scripts/midi2ly.py | 140 +++++++++++++++++++++++++++++++++++---------- 4 files changed, 114 insertions(+), 33 deletions(-) diff --git a/CHANGES b/CHANGES index 08e3491f71..b671b77e42 100644 --- a/CHANGES +++ b/CHANGES @@ -1,7 +1,7 @@ -1.5.14.jcn5 +1.5.14.jcn6 =========== -* Some random typing at midi2ly.py. +* Some more random hacking at midi2ly.py. * Slightly better doco for r, s and \skip, with examples. diff --git a/VERSION b/VERSION index 9c836f5b21..d70f1c7952 100644 --- a/VERSION +++ b/VERSION @@ -2,7 +2,7 @@ PACKAGE_NAME=LilyPond MAJOR_VERSION=1 MINOR_VERSION=5 PATCH_LEVEL=14 -MY_PATCH_LEVEL=jcn5 +MY_PATCH_LEVEL=jcn6 # use the above to send patches: MY_PATCH_LEVEL is always empty for a # released version. diff --git a/modules/midi.c b/modules/midi.c index 768e6308e9..826215b139 100644 --- a/modules/midi.c +++ b/modules/midi.c @@ -108,6 +108,7 @@ message_t metaEvents[] = { 0x58, "TIME_SIGNATURE", 0x59, "KEY_SIGNATURE", 0x7F, "SEQUENCER_SPECIFIC_META_EVENT", + 0xFF, "META_EVENT", 0,0 }; diff --git a/scripts/midi2ly.py b/scripts/midi2ly.py index 67a584d939..bf169683f1 100644 --- a/scripts/midi2ly.py +++ b/scripts/midi2ly.py @@ -4,6 +4,7 @@ import midi import sys import string +LINE_BELL = 60 scale_steps = [0,2,4,5,7,9,11] def split_track (track): @@ -12,10 +13,13 @@ 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] == []: @@ -36,14 +40,54 @@ class Note: 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 = {} @@ -63,7 +107,26 @@ def notes_on_channel (channel): 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 @@ -77,13 +140,15 @@ def unthread_notes (channel): 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 @@ -110,12 +175,11 @@ def dump_duration (dur): 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 @@ -134,12 +198,18 @@ def dump_note (note): 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? @@ -164,16 +234,20 @@ def dump_channel (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 = [] @@ -187,21 +261,27 @@ def dump_notes (channel): 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 @@ -219,9 +299,9 @@ def convert_midi (f): 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) -- 2.39.5