X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=scripts%2Fmusicxml2ly.py;h=c6e7dd53c226d427d32aa9f160714aa67cfd4404;hb=edf17353d89f4f6bd831466262402bb9151a26ca;hp=c7b1000349d7882eaf1e0cf38bdf67136755a194;hpb=50be93de6195cc1240ea0608f01a4c933867d764;p=lilypond.git diff --git a/scripts/musicxml2ly.py b/scripts/musicxml2ly.py index c7b1000349..c6e7dd53c2 100644 --- a/scripts/musicxml2ly.py +++ b/scripts/musicxml2ly.py @@ -55,24 +55,23 @@ additional_definitions = { '(-0.1 . 0.1) '(0.1 . 1))) 0.7 X))))""", "eyeglasses": """eyeglassesps = #"0.15 setlinewidth -% 255 0 0 setrgbcolor --0.9 0 translate -1.1 1.1 scale -1.2 0.7 moveto -0.7 0.7 0.5 0 361 arc -stroke -2.20 0.70 0.50 0 361 arc -stroke -1.45 0.85 0.30 0 180 arc -stroke -0.20 0.70 moveto -0.80 2.00 lineto -0.92 2.26 1.30 2.40 1.15 1.70 curveto -stroke -2.70 0.70 moveto -3.30 2.00 lineto -3.42 2.26 3.80 2.40 3.65 1.70 curveto -stroke" + -0.9 0 translate + 1.1 1.1 scale + 1.2 0.7 moveto + 0.7 0.7 0.5 0 361 arc + stroke + 2.20 0.70 0.50 0 361 arc + stroke + 1.45 0.85 0.30 0 180 arc + stroke + 0.20 0.70 moveto + 0.80 2.00 lineto + 0.92 2.26 1.30 2.40 1.15 1.70 curveto + stroke + 2.70 0.70 moveto + 3.30 2.00 lineto + 3.42 2.26 3.80 2.40 3.65 1.70 curveto + stroke" eyeglasses = \markup { \with-dimensions #'(0 . 4.4) #'(0 . 2.5) \postscript #eyeglassesps }""" } @@ -1311,25 +1310,25 @@ def musicxml_harmony_to_lily (n): return res -def musicxml_chordroot_to_lily (mxl_root): - r = musicexp.ChordRoot () - r.alteration = mxl_root.get_alteration () - r.step = musicxml_step_to_lily (mxl_root.get_step ()) +def musicxml_chordpitch_to_lily (mxl_cpitch): + r = musicexp.ChordPitch () + r.alteration = mxl_cpitch.get_alteration () + r.step = musicxml_step_to_lily (mxl_cpitch.get_step ()) return r chordkind_dict = { - 'major': '', - 'minor': 'm', - 'augmented': 'aug', - 'diminished': 'dim', + 'major': '5', + 'minor': 'm5', + 'augmented': 'aug5', + 'diminished': 'dim5', # Sevenths: 'dominant': '7', - 'major-seventh': 'maj', + 'major-seventh': 'maj7', 'minor-seventh': 'm7', 'diminished-seventh': 'dim7', 'augmented-seventh': 'aug7', - #'half-diminished': '???', (diminished triad, minor seventh) - #'major-minor': '???', (minor triad, major seventh) + 'half-diminished': 'dim5m7', + 'major-minor': 'maj7m5', # Sixths: 'major-sixth': '6', 'minor-sixth': 'm6', @@ -1342,28 +1341,30 @@ chordkind_dict = { 'major-11th': 'maj11', 'minor-11th': 'm11', # 13ths (usually as the basis for alteration): - 'dominant-13th': '13', - 'major-13th': 'maj13', + 'dominant-13th': '13.11', + 'major-13th': 'maj13.11', 'minor-13th': 'm13', # Suspended: 'suspended-second': 'sus2', 'suspended-fourth': 'sus4', # Functional sixths: + # TODO #'Neapolitan': '???', #'Italian': '???', #'French': '???', #'German': '???', # Other: #'pedal': '???',(pedal-point bass) - #'power': '???',(perfect fifth) + 'power': '5^3', #'Tristan': '???', - #'other': '', - 'none': '', + 'other': '1', + 'none': None, } def musicxml_chordkind_to_lily (kind): res = chordkind_dict.get (kind, None) - if not res: + # Check for None, since a major chord is converted to '' + if res == None: error_message (_ ("Unable to convert chord type %s to lilypond.") % kind) return res @@ -1372,20 +1373,44 @@ def musicxml_harmony_to_lily_chordname (n): root = n.get_maybe_exist_named_child ('root') if root: ev = musicexp.ChordNameEvent () - ev.root = musicxml_chordroot_to_lily (root) + ev.root = musicxml_chordpitch_to_lily (root) kind = n.get_maybe_exist_named_child ('kind') if kind: ev.kind = musicxml_chordkind_to_lily (kind.get_text ()) + if not ev.kind: + return res + bass = n.get_maybe_exist_named_child ('bass') + if bass: + ev.bass = musicxml_chordpitch_to_lily (bass) + inversion = n.get_maybe_exist_named_child ('inversion') + if inversion: + # TODO: Lilypond does not support inversions, does it? + + # Mail from Carl Sorensen on lilypond-devel, June 11, 2008: + # 4. LilyPond supports the first inversion in the form of added + # bass notes. So the first inversion of C major would be c:/g. + # To get the second inversion of C major, you would need to do + # e:6-3-^5 or e:m6-^5. However, both of these techniques + # require you to know the chord and calculate either the fifth + # pitch (for the first inversion) or the third pitch (for the + # second inversion) so they may not be helpful for musicxml2ly. + inversion_count = string.atoi (inversion.get_text ()) + if inversion_count == 1: + # TODO: Calculate the bass note for the inversion... + pass + pass + for deg in n.get_named_children ('degree'): + d = musicexp.ChordModification () + d.type = deg.get_type () + d.step = deg.get_value () + d.alteration = deg.get_alter () + ev.add_modification (d) #TODO: convert the user-symbols attribute: #major: a triangle, like Unicode 25B3 #minor: -, like Unicode 002D #augmented: +, like Unicode 002B #diminished: (degree), like Unicode 00B0 #half-diminished: (o with slash), like Unicode 00F8 - # TODO: Convert the inversion and bass children - for deg in n.get_named_children ('degree'): - # TODO: Convert the added/removed degrees to lilypond - pass if ev and ev.root: res.append (ev) @@ -1512,6 +1537,7 @@ class LilyPondVoiceBuilder: self.begin_moment = Rational (0) self.pending_multibar = Rational (0) self.ignore_skips = False + self.has_relevant_elements = False def _insert_multibar (self): r = musicexp.MultiMeasureRest () @@ -1536,6 +1562,7 @@ class LilyPondVoiceBuilder: if self.pending_multibar > Rational (0): self._insert_multibar () + self.has_relevant_elements = True self.elements.append (music) self.begin_moment = self.end_moment self.set_duration (duration) @@ -1551,6 +1578,7 @@ class LilyPondVoiceBuilder: assert isinstance (command, musicexp.Music) if self.pending_multibar > Rational (0): self._insert_multibar () + self.has_relevant_elements = True self.elements.append (command) def add_barline (self, barline): # TODO: Implement merging of default barline and custom bar line @@ -1564,9 +1592,13 @@ class LilyPondVoiceBuilder: self.pending_dynamics.append (dynamic) def add_bar_check (self, number): + # re/store has_relevant_elements, so that a barline alone does not + # trigger output for figured bass, chord names + has_relevant = self.has_relevant_elements b = musicexp.BarLine () b.bar_number = number self.add_barline (b) + self.has_relevant_elements = has_relevant def jumpto (self, moment): current_end = self.end_moment + self.pending_multibar @@ -1769,6 +1801,8 @@ def musicxml_voice_to_lily_voice (voice): num = 0 if num > 0: voice_builder.add_bar_check (num) + figured_bass_builder.add_bar_check (num) + chordnames_builder.add_bar_check (num) main_event = musicxml_note_to_lily_main_event (n) if main_event and not first_pitch: @@ -1821,6 +1855,8 @@ def musicxml_voice_to_lily_voice (voice): dur = fb.real_duration if not dur: dur = ev_chord.get_length () + if not fb.duration: + fb.duration = ev_chord.get_duration () figured_bass_builder.add_music (fb, dur) pending_figured_bass = [] @@ -2012,7 +2048,7 @@ def musicxml_voice_to_lily_voice (voice): return_value.ly_voice = v # create \figuremode { figured bass elements } - if figured_bass_builder.elements: + if figured_bass_builder.has_relevant_elements: fbass_music = musicexp.SequentialMusic () fbass_music.elements = figured_bass_builder.elements v = musicexp.ModeChangingMusicWrapper() @@ -2021,7 +2057,7 @@ def musicxml_voice_to_lily_voice (voice): return_value.figured_bass = v # create \chordmode { chords } - if chordnames_builder.elements: + if chordnames_builder.has_relevant_elements: cname_music = musicexp.SequentialMusic () cname_music.elements = chordnames_builder.elements v = musicexp.ModeChangingMusicWrapper()