fix measure timing and remaining utf8 - issues
authorDirk Koopman <djk@tobit.co.uk>
Sat, 24 Sep 2016 15:34:22 +0000 (16:34 +0100)
committerDirk Koopman <djk@tobit.co.uk>
Sat, 24 Sep 2016 15:34:22 +0000 (16:34 +0100)
The program now handles utf8 - characters that Finale uses. There may
be others yet lurking. Also fix the remaining timing issues.

A truly raw musicxml->mscx converted file now halves times and the resultant file
loads into mscore without error. Mind you that's only one file so far, but it's a
big one and it is has a number of quirky features that just seem to work.

mscore-halve

index 4d92702e1058eccea5761c8d7ef17bfc93deb4e3..ee5990a115dc3e9fd26e7e141f3ba931cdfb111e 100755 (executable)
@@ -15,22 +15,24 @@ use strict;
 use XML::LibXML;
 use File::Basename;
 use IO::File;
-
 use v5.10;
+use utf8;
 
 our %half = (                                  # decode from one note length to its half
-                                           # there may be mispellings, as I can't be bothered
-                                           # to look at the code, as I use this for early music
-                        
                         qw(
+                                  maxima long
                                   long breve
                                   breve whole
                                   whole half
                                   half quarter
                                   quarter eighth
-                                  eighth sixteenth
-                                  sixteenth thirtysecond
-                                  thirtysecond sixtyfourth
+                                  eighth 16th
+                                  16th 32nd
+                                  32nd 64th
+                                  64th 128th
+                                  128th 256th
+                                  256th 512th
+                                  512th 1024th
                          )
                        );
 our %yesno = ( qw(yes 1 no 0) ); # used for turning translating yes/no text values
@@ -41,6 +43,8 @@ our $removebeam = 1;                  # if set remove any BeamMode clauses
 
 usage() unless @ARGV;
 
+binmode STDOUT, "utf8";
+
 foreach my $fn (@ARGV) {
        my ($name, $path, $suffix) = fileparse($fn, qr/\.[^.]*/);
        my ($ifn, $ofn);
@@ -69,7 +73,16 @@ sub process
                my $syllabic = 0;               # track syllabic mode (whether we are in the middle of a word in lyrics).
                display($staff) if $dbg;
                foreach my $measure ($staff->findnodes('./Measure')) {
-
+                       my $lens;
+                       
+                       # obtain the measure no and any len attr. Change the len attribute
+                       my ($l) = $measure->findnodes('./@len');
+                       if ($l) {
+                               my ($t,$b) = split m{/}, $l->to_literal;
+                               $b *= 2;
+                               $lens = "$t/$b";
+                               $l->setValue($lens);
+                       }
                        # process nodes
                        foreach my $node ($measure->findnodes('./*')) {
                                if ($node->nodeType == XML_ELEMENT_NODE) {
@@ -82,7 +95,7 @@ sub process
                                                                my ($nz) = $node->findnodes('./duration/@z');
                                                                my ($nn) = $node->findnodes('./duration/@n');
                                                                my $was = $nn->to_literal;
-                                                               my $now = $sigD || $was * 2;
+                                                               my $now = $was * 2;
                                                                my $z = $nz->to_literal;
                                                                display($staff, $measure, $node, "$type $z/$was -> $z/$now") if $dbg;
                                                                $nn->setValue($now);
@@ -117,14 +130,14 @@ sub process
                                                        }
 
                                                        # determine where we are in a word and if there is a <syllabic>
-                                                       # clause, and it is necessary, add an appropriate one
+                                                       # clause, note its value (which is "in word" or "not in word")
                                                        #
                                                        # This is for dealing with musicxml imports where there is no
-                                                       # explicit detection of trailing '-' signs, if there are and
-                                                       # there is no <syllabic> add one of the correct sort and remove
+                                                       # explicit detection of trailing '-' signs, if there are such signs and
+                                                       # there is no <syllabic> clause, add one of the correct sort and remove
                                                        # any trailing '-' from the text.
                                                        #
-                                                       # Sadly, it's too much hard work to deal with trailing '_' 'cos
+                                                       # Sadly, it's too much hard work to deal with any trailing '_' 'cos
                                                        # mscore calulates the distance in advance because they appear
                                                        # to be too lazy to have another <syllabic> state to deal with
                                                        # it. Manual edit will therefore be required. Hopefully, not
@@ -146,11 +159,11 @@ sub process
                                                                        my $newv;
                                                                        my $newstate;
                                                                        my $newtext = $v;
-                                                                       if ($v =~ /-$/) {
+                                                                       if ($v =~ /[-–]$/) {
                                                                                $newv = 'begin' unless $syllabic;
                                                                                $newv = 'middle' if $syllabic;
                                                                                $newstate = 1;
-                                                                               $newtext =~ s/\-+$//; 
+                                                                               $newtext =~ s/[-–]+$//; 
                                                                        } else {
                                                                                $newv = 'end' if $syllabic;
                                                                                $newstate = 0;