From d0f36b0ba5d2c42a25f056f66feda954094fdead Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Sun, 14 Oct 2001 13:52:01 +0200 Subject: [PATCH] patch::: 1.5.16.jcn1 1.5.16.jcn1 =========== * Some more random hacking at midi2ly.py. 1.5.16 ====== --- CHANGES | 8 +++ VERSION | 2 +- input/bugs/knee.ly | 40 +++++++++++++ input/template/piano-dynamics.ly | 96 ++++++++++++++++++++++++++++++++ scripts/midi2ly.py | 87 ++++++++++++++++++----------- 5 files changed, 198 insertions(+), 35 deletions(-) create mode 100644 input/bugs/knee.ly create mode 100644 input/template/piano-dynamics.ly diff --git a/CHANGES b/CHANGES index 7eac9d8357..58ed8ae144 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,11 @@ +1.5.16.jcn1 +=========== + +* Some more random hacking at midi2ly.py. + +1.5.16 +====== + 1.5.15.jcn1 =========== diff --git a/VERSION b/VERSION index 39881eb45d..8b65089dcf 100644 --- a/VERSION +++ b/VERSION @@ -2,7 +2,7 @@ PACKAGE_NAME=LilyPond MAJOR_VERSION=1 MINOR_VERSION=5 PATCH_LEVEL=16 -MY_PATCH_LEVEL= +MY_PATCH_LEVEL=jcn1 # use the above to send patches: MY_PATCH_LEVEL is always empty for a # released version. diff --git a/input/bugs/knee.ly b/input/bugs/knee.ly new file mode 100644 index 0000000000..4f90edf59b --- /dev/null +++ b/input/bugs/knee.ly @@ -0,0 +1,40 @@ +\header { + +texidoc=" +gives + +@example + | | + | | + +-- | --+ + +----+----+ + | + | + +instead of the desired + + | | + | | + | --+ + +----+----+ + +-- + | + | + +@end example +" + +} + +\score { + \notes\relative c' { + c16 c''8 c16 + + % it's very helpful to have this one too, + % because a fix is likely to break + + c,, c'' c,, cc + } + \paper { linewidth = -1 } +} + \ No newline at end of file diff --git a/input/template/piano-dynamics.ly b/input/template/piano-dynamics.ly new file mode 100644 index 0000000000..59a0a08218 --- /dev/null +++ b/input/template/piano-dynamics.ly @@ -0,0 +1,96 @@ +\version "1.5.1" + +\header { + dedication = "dedication" + title = "Title" + subtitle = "Subtitle" + subsubtitle = "Subsubtitle" + composer = "Composer (xxxx-yyyy)" + opus = "Opus 0" + piece = "Piece I" + instrument = "Instrument" + arranger = "Arranger" + poet = "Poet" + texttranslator = "Translator" + copyright = "public domain" + enteredby = "jcn" + source = "urtext" +} + +upper = \notes\relative c'' { + a b c d +} + +lower = \notes\relative c { + a2 c +} + +dynamics = \notes { + \outputproperty #(make-type-checker 'dynamic-interface) + #'extra-offset = #'(0 . 2.5) + s2\fff\> s4 + \outputproperty #(make-type-checker 'dynamic-interface) + #'extra-offset = #'(0 . 2.5) + \!s\pp +} + +pedal = \notes { + s2\sustainDown s2\sustainUp +} + +\score { + \context PianoStaff < + \context Staff=upper \upper + \context Dynamics=dynamics \dynamics + \context Staff=lower < + \clef bass + \lower + > + \context Dynamics=pedal \pedal + > + \paper { + \translator { + \type "Engraver_group_engraver" + \name Dynamics + \consists "Output_property_engraver" + Generic_property_list = #generic-voice-properties + \consists "Property_engraver" + MinimumVerticalExtent = #'(-1 . 1) + + pedalSustainStrings = #'("Ped." "*Ped." "*") + pedalUnaCordaStrings = #'("una corda" "" "tre corde") + + \consists "Piano_pedal_engraver" + \consists "Script_engraver" + \consists "Dynamic_engraver" + \consists "Text_engraver" + + TextScript \override #'font-relative-size = #1 + TextScript \override #'font-shape = #'italic + + \consists "Skip_req_swallow_translator" + + \consistsend "Axis_group_engraver" + } + \translator { + \PianoStaffContext + \accepts Dynamics + VerticalAlignment \override #'forced-distance = #7 + } + } + \midi { + \translator { + \type "Performer_group_performer" + \name Dynamics + Generic_property_list = #generic-voice-properties + + \consists "Piano_pedal_performer" + \consists "Span_dynamic_performer" + \consists "Dynamic_performer" + } + \translator { + \PianoStaffContext + \accepts Dynamics + } + } +} diff --git a/scripts/midi2ly.py b/scripts/midi2ly.py index 0c3b42ae05..23ca1264f8 100644 --- a/scripts/midi2ly.py +++ b/scripts/midi2ly.py @@ -7,6 +7,9 @@ import string LINE_BELL = 60 scale_steps = [0,2,4,5,7,9,11] +whole_clocks = 1536 +quart_clocks = 0 + def split_track (track): chs = {} for i in range(16): @@ -35,15 +38,15 @@ def split_track (track): class Note: - def __init__ (self, duration, pitch, velocity): + def __init__ (self, clocks, pitch, velocity): self.velocity = velocity self.pitch = pitch - self.duration = duration + self.clocks = clocks - def duration_compare (a, b): - if a.duration < b.duration: + def clocks_compare (a, b): + if a.clocks < b.clocks: return -1 - elif a.duration > b.duration: + elif a.clocks > b.clocks: return 1 else: return 0 @@ -53,40 +56,54 @@ class Note: class Time: def __init__ (self, t, num, den): - self.duration = t + self.skip = t self.num = num self.den = den + self.clocks = 0 def dump (self): - return dump_skip (self.duration) + '\\time %d/%d ' % (self.num, self.den) + s = '' + if self.skip: + s = dump_skip (self.skip) + s = s + '\n ' + return s + '\\time %d/%d ' % (self.num, self.den) + '\n ' class Key: key_sharps = ('c', 'g', 'd', 'a', 'e', 'b', 'fis') key_flats = ('BUG', 'f', 'bes', 'es', 'as', 'des', 'ges') def __init__ (self, t, sharps, flats, minor): - self.duration = t + self.skip = t self.flats = flats self.sharps = sharps self.minor = minor + self.clocks = 0 def dump (self): + s = '' + if self.skip: + s = dump_skip (self.skip) + s = s + '\n ' if self.sharps and self.flats: s = '\\keysignature %s ' % 'TODO' elif self.sharps: - s = '\\notes\\key %s \major' % key_sharps[self.sharps] + s = '\\notes\\key %s \major' % self.key_sharps[self.sharps] elif self.flats: - s = '\\notes\\key %s \major' % key_flats[self.flats] - return dump_skip (self.duration) + s + s = '\\notes\\key %s \major' % self.key_flats[self.flats] + return s + '\n ' class Text: - def __init__ (self, text): + def __init__ (self, t, text): + self.skip = t self.text = text - self.duration = 0 - + self.clocks = 0 + def dump (self): - return dump_text (self) + s = '' + if self.skip: + s = dump_skip (self.skip) + return s + dump_text (self) def notes_on_channel (channel): pitches = {} @@ -103,7 +120,7 @@ def notes_on_channel (channel): (lt, vel) = pitches[e[1][1]] del pitches[e[1][1]] - nch.append ((t, Note (t-lt, e[1][1], vel))) + nch.append ((lt, Note (t-lt, e[1][1], vel))) except KeyError: pass @@ -121,7 +138,7 @@ def notes_on_channel (channel): 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]))) + nch.append ((t, Text (t, e[1][2]))) else: sys.stderr.write ("SKIP: %s\n" % `e`) pass @@ -140,11 +157,11 @@ def unthread_notes (channel): todo = [] for e in channel: t = e[0] - if e[1].__class__ == Note and ((t == start_busy_t and e[1].duration + t == end_busy_t) \ + if e[1].__class__ == Note and ((t == start_busy_t and e[1].clocks + t == end_busy_t) \ or t >= end_busy_t): thread.append (e) start_busy_t = t - end_busy_t = t + e[1].duration + end_busy_t = t + e[1].clocks elif e[1].__class__ == Time or e[1].__class__ == Key or e[1].__class__ == Text: thread.append (e) else: @@ -164,20 +181,18 @@ def gcd (a,b): b = c return a -def dump_skip (dt): - return 's' + dump_duration (dt) - -def dump_duration (dur): - g = gcd (dur, 384) - s = '4' - (p,q) = (dur / g, 384 / g) - if (p == 1 and q == 1) : - pass +def dump_skip (clocks): + return 's' + dump_duration (clocks) + ' ' + +def dump_duration (clocks): + g = gcd (clocks, whole_clocks) + (d, n) = (whole_clocks/ g, clocks / g) + if n == 1: + s = '%d' % d + elif n == 3 and d != 1: + s = '%d.' % (d / 2) else: - if p <> 1: - s = s + '*%d'% p - if q <> 1: - s = s + '*%d'% q + s = '%d*%d' % (d, n) return s def dump_note (note): @@ -196,7 +211,7 @@ def dump_note (note): if scale_steps[i] <> step: str = str + 'is' - return ' %s' % str + dump_duration (note.duration) + return str + dump_duration (note.clocks) + ' ' def dump (self): return self.dump () @@ -245,7 +260,7 @@ def dump_channel (thread): lines[-1] = lines[-1] + dump_chord (ch[1]) - last_t = t + ch[1][0].duration + last_t = t + ch[1][0].clocks return string.join (lines, '\n ') + '\n' @@ -286,9 +301,13 @@ def dump_track (channels, n): def convert_midi (f): + global whole_clocks, quart_clocks + str = open (f).read () midi_dump = midi.parse (str) + whole_clocks = midi_dump[0][1] + quart_clocks = whole_clocks / 4 tracks = [] for t in midi_dump[1]: -- 2.39.5