musicxml2ly patch: Convert articulations (fermata, staccato, tremolo, etc.)
Attached is a git diff to translate articulations from MusicXML to lilypond. It's basically the patch from yesterday with a few style-fixes as requested by Han-Wen. Cheers, Reinhold PS: If anyone needs an ubuntu package for guile 1.8.2, I have built one to be able to build lilypond. -- -- Reinhold Kainhofer, Vienna University of Technology, Austria email: [EMAIL PROTECTED], http://reinhold.kainhofer.com/ * Financial and Actuarial Mathematics, TU Wien, http://www.fam.tuwien.ac.at/ * K Desktop Environment, http://www.kde.org, KOrganizer maintainer * Chorvereinigung Jung-Wien, http://www.jung-wien.at/ From 757c4f75afadfd94e0480435374ed526f9282a91 Mon Sep 17 00:00:00 2001 From: Reinhold Kainhofer [EMAIL PROTECTED] Date: Sat, 18 Aug 2007 12:02:39 +0200 Subject: [PATCH] Convert articulations like fermata, staccato, tenuto, tremolo (only single-note tremolo), accents, etc. These entries in the xml are inside the notation.../notation tags, listed in the ornaments, technical and articulations tags. --- python/musicexp.py | 30 +- python/musicxml.py | 36 +++ scripts/musicxml2ly.py | 151 +++- 3 files changed, 214 insertions(+), 3 deletions(-) diff --git a/python/musicexp.py b/python/musicexp.py index e7b3870..963b311 100644 --- a/python/musicexp.py +++ b/python/musicexp.py @@ -498,7 +498,35 @@ class TieEvent(Event): def ly_expression (self): return '~' - + +class ArticulationEvent (Event): +def __init__ (self): +self.type = None +self.force_direction = None + +def direction_mod (self): +dirstr = '' +try: +dirstr += { 1: '^', -1: '_', 0: '-' }[self.force_direction] +except KeyError: +pass +return dirstr + +def ly_expression (self): +return '%s\\%s' % (self.direction_mod (), self.type) + + +class TremoloEvent (Event): +def __init__ (self): +self.bars = 0; + +def ly_expression (self): +str='' +if self.bars 0: +str += ':%s' % 2**( 2 + string.atoi (self.bars) ) +return str + + class RhythmicEvent(Event): def __init__ (self): Event.__init__ (self) diff --git a/python/musicxml.py b/python/musicxml.py index 3466473..304b2c6 100644 --- a/python/musicxml.py +++ b/python/musicxml.py @@ -450,6 +450,32 @@ class Staff (Music_xml_node): class Instrument (Music_xml_node): pass +class Fermata (Music_xml_node): +pass +class Dynamics (Music_xml_node): +pass +class Articulations (Music_xml_node): +pass +class Accent (Music_xml_node): +pass +class Staccato (Music_xml_node): +pass +class Tenuto (Music_xml_node): +pass +class Tremolo (Music_xml_node): +pass +class Technical (Music_xml_node): +pass +class Ornaments (Music_xml_node): +pass + + +class Direction (Music_xml_node): +pass +class DirType (Music_xml_node): +pass + + ## need this, not all classes are instantiated ## for every input file. class_dict = { @@ -477,6 +503,16 @@ class_dict = { 'type': Type, 'part-list': Part_list, 'staff': Staff, +'fermata': Fermata, +'articulations': Articulations, +'accent': Accent, +'staccato': Staccato, +'tenuto': Tenuto, +'tremolo': Tremolo, +'technical': Technical, +'ornaments': Ornaments, +'direction': Direction, +'direction-type': DirType } def name2class_name (name): diff --git a/scripts/musicxml2ly.py b/scripts/musicxml2ly.py index e358268..77561f3 100644 --- a/scripts/musicxml2ly.py +++ b/scripts/musicxml2ly.py @@ -168,6 +168,101 @@ def musicxml_spanner_to_lily_event (mxl_event): return ev +def musicxml_direction_to_indicator (direction): +returnval = None +try: + val = { above: 1, upright: 1, below: -1, downright: -1 }[direction]; + returnval = val +except (KeyError): + pass +return returnval + +def musicxml_fermata_to_lily_event (mxl_event): +ev = musicexp.ArticulationEvent () +ev.type = fermata +try: + dir = musicxml_direction_to_indicator( mxl_event.type ) + if dir: +ev.force_direction = dir +except (AttributeError, KeyError): + pass +return ev + +def musicxml_tremolo_to_lily_event(mxl_event): +if mxl_event.get_name () != tremolo: +return +ev = musicexp.TremoloEvent () +ev.bars = mxl_event.get_text () +return ev + +# TODO: Some translations are missing! +articulations_dict = { +# ORNAMENTS +trill-mark: trill, +turn: turn, +#delayed-turn: ?, +inverted-turn: reverseturn, +#shake: ?, +#wavy-line: ?, +mordent: mordent, +#inverted-mordent: ?, +#schleifer: ? +# TECHNICALS +up-bow: upbow, +down-bow: downbow, +#harmonic: , +#open-string: , +#thumb-position: , +#fingering: , +
musicxml2ly patch: fix order of parts
This git patch forces lilypond to output the voice definitions in the order as they appear in the score. So far, they were ordered randomly. Cheers, Reinhold -- -- Reinhold Kainhofer, Vienna University of Technology, Austria email: [EMAIL PROTECTED], http://reinhold.kainhofer.com/ * Financial and Actuarial Mathematics, TU Wien, http://www.fam.tuwien.ac.at/ * K Desktop Environment, http://www.kde.org, KOrganizer maintainer * Chorvereinigung Jung-Wien, http://www.jung-wien.at/ From be8df8fcb2caadc92948b744bbc55b2a5054ca95 Mon Sep 17 00:00:00 2001 From: Reinhold Kainhofer [EMAIL PROTECTED] Date: Sat, 18 Aug 2007 12:04:11 +0200 Subject: [PATCH] Sorting of the parts in the .ly output. Currently, their order was not first staff, second staff, third, etc. but seemingly random Basically, I use the part_list to sort the individual music voices in the order as they appear in the score before printing them out. --- scripts/musicxml2ly.py | 12 +--- 1 files changed, 9 insertions(+), 3 deletions(-) diff --git a/scripts/musicxml2ly.py b/scripts/musicxml2ly.py index 77561f3..bc83031 100644 --- a/scripts/musicxml2ly.py +++ b/scripts/musicxml2ly.py @@ -659,9 +659,15 @@ def music_xml_voice_name_to_lily_name (part, name): str = Part%sVoice%s % (part.id, name) return musicxml_id_to_lily (str) -def print_voice_definitions (printer, voices): +def print_voice_definitions (printer, part_list, voices): +part_dict={} for (part, nv_dict) in voices.items(): - +part_dict[part.id] = (part, nv_dict) + +for part in part_list: +(part, nv_dict) = part_dict[part.id] +for (name, (voice, mxlvoice)) in nv_dict.items (): +print music_xml_voice_name_to_lily_name (part, name); for (name, (voice, mxlvoice)) in nv_dict.items (): k = music_xml_voice_name_to_lily_name (part, name) printer.dump ('%s = ' % k) @@ -774,7 +780,7 @@ def convert (filename, options): printer.set_file (open (defs_ly_name, 'w')) print_ly_preamble (printer, filename) -print_voice_definitions (printer, voices) +print_voice_definitions (printer, part_list, voices) printer.close () -- 1.5.2.3 ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
musicxml2ly patch: Convert dynamics
This git patch converts dynamic marks and hairpin (de)crescendos from musicxml to lilypond. Unfortunately, I don't have a musicxml editor, so my only test files are the output files of several OMR packages (Audiveris and SmartScore). They are way too large and to serve as test files... Cheers, Reinhold -- -- Reinhold Kainhofer, Vienna University of Technology, Austria email: [EMAIL PROTECTED], http://reinhold.kainhofer.com/ * Financial and Actuarial Mathematics, TU Wien, http://www.fam.tuwien.ac.at/ * K Desktop Environment, http://www.kde.org, KOrganizer maintainer * Chorvereinigung Jung-Wien, http://www.jung-wien.at/ From f5d10c51caa36baa232a61c8727f29acf6bb472e Mon Sep 17 00:00:00 2001 From: Reinhold Kainhofer [EMAIL PROTECTED] Date: Sat, 18 Aug 2007 12:53:25 +0200 Subject: [PATCH] Convert dynamic marks (given in a direction tag, assigned to the staff at a given position in xml, not to a note like in lilypond) In the LilyPondVoiceBuilder, I added a method to store any pending dynamics and print them out only after the next note or rest (everything with duration0) is encountered. Also convert (de-)crescendo (begin/end also given in a direction tag, not assigned to a particular note) --- python/musicexp.py | 45 python/musicxml.py | 10 +-- scripts/musicxml2ly.py | 60 ++- 3 files changed, 110 insertions(+), 5 deletions(-) diff --git a/python/musicexp.py b/python/musicexp.py index 963b311..4618ea7 100644 --- a/python/musicexp.py +++ b/python/musicexp.py @@ -499,6 +499,51 @@ class TieEvent(Event): return '~' +class HairpinEvent (Event): +def __init__ (self, type): +self.type = type +def hairpin_to_ly (self): +val = '' +try: +val += { 0: '\!', 1: '\', -1: '\' }[self.type] +except KeyError: +pass +return val + +def ly_expression (self): +return self.hairpin_to_ly () + +def print_ly (self, printer): +val = self.hairpin_to_ly () +if val: +printer.dump (val) + + + +class DynamicsEvent (Event): +def __init__ (self): +self.type = None +self.available_commands = [ p, , ppp, pp, p, +mp, mf, +f, ff, fff, , +fp, sf, sff, sp, spp, sfz, rfz ]; +def ly_expression (self): +if self.type == None: +return; +elif self.type in self.available_commands: +return '\%s' % self.type +else: +return '\markup{ \dynamic %s }' % self.type + +def print_ly (self, printer): +if self.type == None: +return +elif self.type in self.available_commands: +printer.dump (\\%s % self.type) +else: +printer.dump (\\markup{ \\dynamic %s } % self.type) + + class ArticulationEvent (Event): def __init__ (self): self.type = None diff --git a/python/musicxml.py b/python/musicxml.py index 304b2c6..90d9e45 100644 --- a/python/musicxml.py +++ b/python/musicxml.py @@ -354,14 +354,14 @@ class Part (Music_xml_node): for n in elements: voice_id = n.get_maybe_exist_typed_child (class_dict['voice']) - if not (voice_id or isinstance (n, Attributes)): + if not (voice_id or isinstance (n, Attributes) or isinstance (n, Direction) ): continue if isinstance (n, Attributes) and not start_attr: start_attr = n continue - if isinstance (n, Attributes): + if isinstance (n, Attributes) or isinstance (n, Direction): for v in voices.values (): v.add_element (n) continue @@ -474,6 +474,8 @@ class Direction (Music_xml_node): pass class DirType (Music_xml_node): pass +class Wedge (Music_xml_node): +pass ## need this, not all classes are instantiated @@ -512,7 +514,9 @@ class_dict = { 'technical': Technical, 'ornaments': Ornaments, 'direction': Direction, -'direction-type': DirType +'direction-type': DirType, +'dynamics': Dynamics, +'wedge': Wedge } def name2class_name (name): diff --git a/scripts/musicxml2ly.py b/scripts/musicxml2ly.py index bc83031..ed51d9c 100644 --- a/scripts/musicxml2ly.py +++ b/scripts/musicxml2ly.py @@ -263,13 +263,46 @@ def musicxml_articulation_to_lily_event(mxl_event): return ev +def musicxml_direction_to_lily( n ): +# TODO: Handle the staff element! +res = [] +dirtype = n.get_maybe_exist_typed_child (musicxml.DirType) +if not dirtype: + return res + +for entry in dirtype.get_all_children (): +if entry.get_name() == dynamics: +for dynentry in entry.get_all_children(): +dynamics_available = ( p, pp, ppp, , p, pp, +f, ff,
Re: musicxml2ly patch: Convert articulations (fermata, staccato, tremolo, etc.)
Reinhold Kainhofer escreveu: Attached is a git diff to translate articulations from MusicXML to lilypond. It's basically the patch from yesterday with a few style-fixes as requested by Han-Wen. Cheers, Reinhold PS: If anyone needs an ubuntu package for guile 1.8.2, I have built one to be able to build lilypond. +def direction_mod (self): +dirstr = '' +try: +dirstr += { 1: '^', -1: '_', 0: '-' }[self.force_direction] +except KeyError: +pass +return dirstr use {}.get (..) +def musicxml_direction_to_indicator (direction): +returnval = None +try: + val = { above: 1, upright: 1, below: -1, downright: -1 }[direction]; idem +str += ':%s' % 2**( 2 + string.atoi (self.bars) ) no space inside ( ) +try: +dir = musicxml_direction_to_indicator (mxl_event.placement) +#dir = mxl_event.type +if ( dir ): + ev.force_direction = dir +except (KeyError, ValueError, AttributeError): +pass +return ev don't use except() for control flow. exceptions are for exceptional situations only This programming style can easily hide programming errors. also, no spaces inside ( ) , and no () around the if condition. -- Han-Wen Nienhuys - [EMAIL PROTECTED] - http://www.xs4all.nl/~hanwen ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Punctuation after @ref
Le mardi 14 août 2007 à 10:24 +0200, Francisco Vila a écrit : Yesterday we told about superfluous commas in English originals. Now I've found a commit that says exactly = @ref{...} must *always* be followed by punctuation. 3bb76531e32eef98adf8349312f0e09800e53379 Author: Werner Lemberg [EMAIL PROTECTED] 2007-04-10 16:21:23 Committer: Werner Lemberg [EMAIL PROTECTED] 2007-04-10 16:21:23 Parent: 0fafa6ce40f750d57656502b2cac4e40ed4b2323 (Whitespace fixes.) Child: 8058fadae4f6d278677335df4507a74b66691369 (Some optical improvements.) Branches: mytranslation, master, lilypond/mytranslation Follows: release/2.11.22-1 Precedes: release/2.11.23-1 = See it in the web at: http://git.sv.gnu.org/gitweb/?p=lilypond.git;a=commit;h=3bb76531e32eef98adf8349312f0e09800e53379 My question is, why is it so important? and, can I keep following my language rules in spite of this? I think so -- we haven't add commas in French either, as these punctuation rule makes non sense for the French translators. I'm no expert in this topic at all, but I suspect that a comma may be necessary after @ref to explicitly tell where the end of the reference is. However, references are clearly hilighted (or surrounded with '*' and '::' in info standalone) in all output formats and viewers I tried, so there must be another reason, maybe an English grammar rule. Werner, can you tell what the real rule is? Cheers, John ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Patch against lilypond/translation
Le lundi 06 août 2007 à 14:56 +0200, Jean-Charles Malahieude a écrit : Hi all, Some corrections to the French part, an typo regarding text which should open a linked page (an 's' within text breaks the link). Thanks, applied. Cheers, John ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Punctuation after @ref
@ref{...} must *always* be followed by punctuation. Werner, can you tell what the real rule is? See below the snippet from the texinfo manual. I haven't yet checked how to handle languages other than English. Werner == 8.6 [EMAIL PROTECTED]' == [EMAIL PROTECTED]' is nearly the same as [EMAIL PROTECTED]' except that it does not generate a `See' in the printed output, just the reference itself. This makes it useful as the last part of a sentence. For example, For more information, see @ref{Hurricanes}. produces (in Info): For more information, see *Note Hurricanes::. and (in printed output): For more information, see Section 8.2 [Hurricanes], page 123. The [EMAIL PROTECTED]' command sometimes tempts writers to express themselves in a manner that is suitable for a printed manual but looks awkward in the Info format. Bear in mind that your audience will be using both the printed and the Info format. For example: Sea surges are described in @ref{Hurricanes}. looks ok in the printed output: Sea surges are described in Section 6.7 [Hurricanes], page 72. but is awkward to read in Info: Sea surges are described in *Note Hurricanes::. As a general rule, you should write a period or comma immediately after an [EMAIL PROTECTED]' command with two or more arguments. If there is no such following punctuation, `makeinfo' will generate a (grammatically incorrect) period in the Info output; otherwise, the cross-reference would fail completely, due to the current syntax of Info format. ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Punctuation after @ref
@ref{...} must *always* be followed by punctuation. I suggest that you discuss this issue on a texinfo mailing list. Werner ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel