X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=scripts%2Fmusicxml2ly.py;h=2b630029b6223bbb061580201fa54f3874d66c31;hb=d959f8d548dc073c162c4599cfef2a596f9b66db;hp=7e8dbbae023eb40083e442800ccf8fc37b168798;hpb=d7c0f4263534307616c82d9b2ce6fdef9472456f;p=lilypond.git diff --git a/scripts/musicxml2ly.py b/scripts/musicxml2ly.py index 7e8dbbae02..2b630029b6 100644 --- a/scripts/musicxml2ly.py +++ b/scripts/musicxml2ly.py @@ -7,6 +7,7 @@ import os import string import codecs import zipfile +import tempfile import StringIO """ @@ -67,109 +68,8 @@ additional_definitions = { (let* ((ev (event-cause grob)) (den (if denominator denominator (ly:event-property ev 'denominator))) (num (if numerator numerator (ly:event-property ev 'numerator)))) - (format "~a:~a" den num))) + (format #f "~a:~a" den num))) """, - - "compound-time-signature": """%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% Formatting of (possibly complex) compound time signatures -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -#(define-public (insert-markups l m) - (let* ((ll (reverse l))) - (let join-markups ((markups (list (car ll))) - (remaining (cdr ll))) - (if (pair? remaining) - (join-markups (cons (car remaining) (cons m markups)) (cdr remaining)) - markups)))) - -% Use a centered-column inside a left-column, because the centered column -% moves its reference point to the center, which the left-column undoes. -% The center-column also aligns its contented centered, which is not undone... -#(define-public (format-time-fraction time-sig-fraction) - (let* ((revargs (reverse (map number->string time-sig-fraction))) - (den (car revargs)) - (nums (reverse (cdr revargs)))) - (make-override-markup '(baseline-skip . 0) - (make-number-markup - (make-left-column-markup (list - (make-center-column-markup (list - (make-line-markup (insert-markups nums "+")) - den)))))))) - -#(define-public (format-complex-compound-time time-sig) - (let* ((sigs (map format-time-fraction time-sig))) - (make-override-markup '(baseline-skip . 0) - (make-number-markup - (make-line-markup - (insert-markups sigs (make-vcenter-markup "+"))))))) - -#(define-public (format-compound-time time-sig) - (cond - ((not (pair? time-sig)) (null-markup)) - ((pair? (car time-sig)) (format-complex-compound-time time-sig)) - (else (format-time-fraction time-sig)))) - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% Measure length calculation of (possibly complex) compound time signatures -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -#(define-public (calculate-time-fraction time-sig-fraction) - (let* ((revargs (reverse time-sig-fraction)) - (den (car revargs)) - (nums (cdr revargs))) - (ly:make-moment (apply + nums) den))) - -#(define-public (calculate-complex-compound-time time-sig) - (let* ((sigs (map calculate-time-fraction time-sig))) - (let add-moment ((moment ZERO-MOMENT) - (remaining sigs)) - (if (pair? remaining) - (add-moment (ly:moment-add moment (car remaining)) (cdr remaining)) - moment)))) - -#(define-public (calculate-compound-measure-length time-sig) - (cond - ((not (pair? time-sig)) (ly:make-moment 4 4)) - ((pair? (car time-sig)) (calculate-complex-compound-time time-sig)) - (else (calculate-time-fraction time-sig)))) - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% Base beat lenth -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -#(define-public (calculate-compound-base-beat-full time-sig) - (let* ((den (map last time-sig))) - (apply max den))) - -#(define-public (calculate-compound-base-beat time-sig) - (ly:make-moment 1 (cond - ((not (pair? time-sig)) 4) - ((pair? (car time-sig)) (calculate-compound-base-beat-full time-sig)) - (else (calculate-compound-base-beat-full (list time-sig)))))) - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% The music function to set the complex time signature -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -compoundMeter = -#(define-music-function (parser location args) (pair?) - (let ((mlen (calculate-compound-measure-length args)) - (beat (calculate-compound-base-beat args))) - #{ -\once \override Staff.TimeSignature #'stencil = #ly:text-interface::print -\once \override Staff.TimeSignature #'text = #(format-compound-time $args) -% \set Staff.beatGrouping = #(reverse (cdr (reverse $args))) -\set Timing.measureLength = $mlen -\set Timing.timeSignatureFraction = #(cons (ly:moment-main-numerator $mlen) - (ly:moment-main-denominator $mlen)) -\set Timing.baseMoment = $beat - -% TODO: Implement beatGrouping and auto-beam-settings!!! -#} )) -""" } def round_to_two_digits (val): @@ -342,6 +242,13 @@ class PartGroupInfo: error_message (_ ("Unprocessed PartGroupInfo %s encountered") % self) return '' +def musicxml_step_to_lily (step): + if step: + return (ord (step) - ord ('A') + 7 - 2) % 7 + else: + return None + + def staff_attributes_to_string_tunings (mxl_attr): details = mxl_attr.get_maybe_exist_named_child ('staff-details') if not details: @@ -351,7 +258,7 @@ def staff_attributes_to_string_tunings (mxl_attr): if staff_lines: lines = string.atoi (staff_lines.get_text ()) - tunings = [0]*lines + tunings = [musicexp.Pitch()]*lines staff_tunings = details.get_named_children ('staff-tuning') for i in staff_tunings: p = musicexp.Pitch() @@ -832,8 +739,6 @@ def musicxml_time_to_lily (attributes): return None change = musicexp.TimeSignatureChange() change.fractions = sig - if (len(sig) != 2) or isinstance (sig[0], list): - needed_additional_definitions.append ("compound-time-signature") time_elm = attributes.get_maybe_exist_named_child ('time') if time_elm and hasattr (time_elm, 'symbol'): @@ -896,7 +801,12 @@ def musicxml_key_to_lily (attributes): else: # Non-standard key signature of the form [[step,alter<,octave>],...] - change.non_standard_alterations = key_sig + # MusicXML contains C,D,E,F,G,A,B as steps, lily uses 0-7, so convert + alterations = [] + for k in key_sig: + k[0] = musicxml_step_to_lily (k[0]) + alterations.append (k) + change.non_standard_alterations = alterations return change def musicxml_transpose_to_lily (attributes): @@ -1409,7 +1319,7 @@ def musicxml_accordion_to_markup (mxl_event): if high: commandname += "H" command += """\\combine - \\raise #2.5 \\musicglyph #\"accordion.accDot\" + \\raise #2.5 \\musicglyph #\"accordion.dot\" """ middle = mxl_event.get_maybe_exist_named_child ('accordion-middle') if middle: @@ -1423,32 +1333,32 @@ def musicxml_accordion_to_markup (mxl_event): if txt == 3: commandname += "MMM" command += """\\combine - \\raise #1.5 \\musicglyph #\"accordion.accDot\" + \\raise #1.5 \\musicglyph #\"accordion.dot\" \\combine - \\raise #1.5 \\translate #(cons 1 0) \\musicglyph #\"accordion.accDot\" + \\raise #1.5 \\translate #(cons 1 0) \\musicglyph #\"accordion.dot\" \\combine - \\raise #1.5 \\translate #(cons -1 0) \\musicglyph #\"accordion.accDot\" + \\raise #1.5 \\translate #(cons -1 0) \\musicglyph #\"accordion.dot\" """ elif txt == 2: commandname += "MM" command += """\\combine - \\raise #1.5 \\translate #(cons 0.5 0) \\musicglyph #\"accordion.accDot\" + \\raise #1.5 \\translate #(cons 0.5 0) \\musicglyph #\"accordion.dot\" \\combine - \\raise #1.5 \\translate #(cons -0.5 0) \\musicglyph #\"accordion.accDot\" + \\raise #1.5 \\translate #(cons -0.5 0) \\musicglyph #\"accordion.dot\" """ elif not txt <= 0: commandname += "M" command += """\\combine - \\raise #1.5 \\musicglyph #\"accordion.accDot\" + \\raise #1.5 \\musicglyph #\"accordion.dot\" """ low = mxl_event.get_maybe_exist_named_child ('accordion-low') if low: commandname += "L" command += """\\combine - \\raise #0.5 \musicglyph #\"accordion.accDot\" + \\raise #0.5 \musicglyph #\"accordion.dot\" """ - command += "\musicglyph #\"accordion.accDiscant\"" + command += "\musicglyph #\"accordion.discant\"" command = "\\markup { \\normalsize %s }" % command # Define the newly built command \accReg[H][MMM][L] additional_definitions[commandname] = "%s = %s" % (commandname, command) @@ -1873,11 +1783,11 @@ def musicxml_note_to_lily_main_event (n): # TODO: Handle the level-display setting for displaying brackets/parentheses elif n.get_maybe_exist_typed_child (musicxml.Unpitched): - # Unpitched elements have display-step and can also have - # display-octave. - unpitched = n.get_maybe_exist_typed_child (musicxml.Unpitched) - event = musicexp.NoteEvent () - event.pitch = musicxml_unpitched_to_lily (unpitched) + # Unpitched elements have display-step and can also have + # display-octave. + unpitched = n.get_maybe_exist_typed_child (musicxml.Unpitched) + event = musicexp.NoteEvent () + event.pitch = musicxml_unpitched_to_lily (unpitched) elif n.get_maybe_exist_typed_child (musicxml.Rest): # rests can have display-octave and display-step, which are @@ -2116,12 +2026,6 @@ class VoiceData: self.lyrics_dict = {} self.lyrics_order = [] -def musicxml_step_to_lily (step): - if step: - return (ord (step) - ord ('A') + 7 - 2) % 7 - else: - return None - def measure_length_from_attributes (attr, current_measure_length): len = attr.get_measure_length () if not len: @@ -2586,11 +2490,11 @@ def musicxml_unpitched_to_lily (mxl_unpitched): p = None step = mxl_unpitched.get_step () if step: - p = musicexp.Pitch () - p.step = musicxml_step_to_lily (step) + p = musicexp.Pitch () + p.step = musicxml_step_to_lily (step) octave = mxl_unpitched.get_octave () if octave and p: - p.octave = octave - 4 + p.octave = octave - 4 return p def musicxml_restdisplay_to_lily (mxl_rest): @@ -2660,7 +2564,7 @@ If the given filename is -, musicxml2ly reads from the command line. p.version = ('''%prog (LilyPond) @TOPLEVEL_VERSION@\n\n''' + -_ ("""Copyright (c) 2005--2010 by +_ ("""Copyright (c) 2005--2011 by Han-Wen Nienhuys , Jan Nieuwenhuizen and Reinhold Kainhofer @@ -2707,7 +2611,7 @@ information.""") % 'lilypond') p.add_option ('-l', '--language', metavar = _ ("LANG"), action = "store", - help = _ ("use a different language file 'LANG.ly' and corresponding pitch names, e.g. 'deutsch' for deutsch.ly")) + help = _ ("use LANG for pitch names, e.g. 'deutsch' for note names in German")) p.add_option ('--nd', '--no-articulation-directions', action = "store_false", @@ -2885,7 +2789,17 @@ def read_musicxml (filename, compressed, use_lxml): if compressed: if filename == "-": progress (_ ("Input is compressed, extracting raw MusicXML data from stdin") ) - z = zipfile.ZipFile (sys.stdin) + # unfortunately, zipfile.ZipFile can't read directly from + # stdin, so copy everything from stdin to a temp file and read + # that. TemporaryFile() will remove the file when it is closed. + tmp = tempfile.TemporaryFile() + sys.stdin = os.fdopen(sys.stdin.fileno(), 'rb', 0) # Make sys.stdin binary + bytes_read = sys.stdin.read (8192) + while bytes_read: + for b in bytes_read: + tmp.write(b) + bytes_read = sys.stdin.read (8192) + z = zipfile.ZipFile (tmp, "r") else: progress (_ ("Input file %s is compressed, extracting raw MusicXML data") % filename) z = zipfile.ZipFile (filename, "r") @@ -3000,7 +2914,7 @@ def main (): if options.language: musicexp.set_pitch_language (options.language) needed_additional_definitions.append (options.language) - additional_definitions[options.language] = "\\include \"%s.ly\"\n" % options.language + additional_definitions[options.language] = "\\language \"%s\"\n" % options.language conversion_settings.ignore_beaming = not options.convert_beaming conversion_settings.convert_page_layout = options.convert_page_layout