diff --git a/pae2xml.pl b/pae2xml.pl index 3c555bc6997d9864e945839046cb6466bcc0c4a2..e38fe27152884bd5a59f995fefaa723fa0be3479 100755 --- a/pae2xml.pl +++ b/pae2xml.pl @@ -63,6 +63,8 @@ $old_duration = $divisions; $old_type = ""; $old_octave = 4; $BEAM = 0; +@rhythmic_model = (); +$rhythmic_model_index = 0; # Store all alterations already used in the current measure, so that e.g. # xCC also detects the second note as a Cis! Needs to be reset at the @@ -269,6 +271,10 @@ sub parse_notes { } elsif ($notes =~ /^r(.*)$/) { # End grace $notes = $1; $qq = 0; + } elsif ($notes =~ /^([0-9]\.?(?:\s?[0-9]+\.?)+)\s*(.*)$/) { # Rhythmic model + ($model, $notes) = ($1, $2); + @rhythmic_model = parse_rhythmic_model ($1); + $rhythmic_model_index = -1; } elsif ($notes =~ /^\=(\d*)(\/.*)$/) { # multi-measure rests $measrest = $1; $notes = $2; @@ -504,8 +510,24 @@ sub parse_note { </pitch> '; } + # We are using a rhythmic model, extract the correct duration + $this_duration = ""; + $this_head = ""; + if (($dur.$dot eq "") && scalar(@rhythmic_model)) { + if ($chord ne "^") { + $rhythmic_model_index = ($rhythmic_model_index +1 ) % scalar(@rhythmic_model); + } + $this_duration = $rhythmic_model[$rhythmic_model_index][0]; + $this_head = $rhythmic_model[$rhythmic_model_index][1]; + } elsif ($dur.$dot ne "" && scalar(@rhythmic_model)) { + # The rhythmic model ends when a new new rhythmic value appears! + @rhythmic_model = (); + } if ($gracecue ne "g") { - print OUT ' <duration>'.(duration($dur, $dot)*$normalnotes/$actualnotes).'</duration> + if (!$this_duration) { + $this_duration = duration ($dur, $dot); + } + print OUT ' <duration>'.($this_duration*$normalnotes/$actualnotes).'</duration> '; } @@ -533,7 +555,10 @@ sub parse_note { if ($gracecue eq "g") { print OUT " <type>eighth</type>\n"; } else { - print OUT notehead ($dur, $dot); + if (!$this_head) { + $this_head = notehead ($dur, $dot); + } + print OUT $this_head; } # If we have an explicit accidental on the note, print the <accidental> tag print OUT accidental_explicit ($acc); @@ -632,20 +657,56 @@ sub accidental_explicit { } } +sub raw_notehead { + my ($duration, $dots) = @_; + my %du=("0", "long", "9", "breve", "1", "whole", "2", "half", "4", "quarter", + "8", "eighth", "6", "16th", "3", "32nd", "5", "64th", "7", "128th"); + if ($duration && $du{$duration}) { + my $res = " <type>$du{$duration}</type>\n"; + $res .= repeat (" <dot/>\n", length ($dots)); + return $res; + } +} sub notehead { my ($duration, $dots) = @_; if ($duration.$dots ne "") { - my %du=("0", "long", "9", "breve", "1", "whole", "2", "half", "4", "quarter", - "8", "eighth", "6", "16th", "3", "32nd", "5", "64th", "7", "128th"); - my $res = " <type>$du{$duration}</type>\n"; - $res .= repeat (" <dot/>\n", length ($dots)); - $old_type = $res; + my $head = raw_notehead ($duration, $dots); + $old_type = $head if $head; } return $old_type; } +sub parse_rhythmic_model { + (my $model) = @_; + my @m = (); + while ($model =~ s/^([0-9])\s*(\.?)\s*([0-9\.\s]*)$/$3/) { + my ($this_dur, $this_dots) = ($1, $2); + my $dur = raw_duration ($this_dur, $this_dots); + my $notehead = raw_notehead ($this_dur, $this_dots); + push @m, [$dur, $notehead]; + } + return @m; +} +sub raw_duration { + my ($duration, $dots) = @_; + my %du=("1",4*$divisions,"2",2*$divisions,"4",$divisions, + "8",$divisions/2,"6",$divisions/4,"3",$divisions/8, + "5",$divisions/16,"7",$divisions/32, + "9",$divisions*8,"0",$divisions*16); # breve/long + my $res = $du{$duration}; + if ($res) { + my $add = $res; + while ($dots ne "") { + $add /= 2; + $res += $add; + $dots =~ /^.(.*)$/gs; + $dots = $1; + } + } + return $res; +} sub duration { my ($duration, $dots) = @_; if ($duration.$dots eq "7.") { @@ -653,21 +714,10 @@ sub duration { } if ($duration.$dots ne "") { - my %du=("1",4*$divisions,"2",2*$divisions,"4",$divisions, - "8",$divisions/2,"6",$divisions/4,"3",$divisions/8, - "5",$divisions/16,"7",$divisions/32, - "9",$divisions*8,"0",$divisions*16); # breve/long - $old_duration = $du{$duration}; + $old_duration = raw_duration ($duration, $dots); if ($old_duration eq "") { print_error("strange duration '$duration'\n"); } - my $add = $old_duration; - while ($dots ne "") { - $add /= 2; - $old_duration += $add; - $dots =~ /^.(.*)$/gs; - $dots = $1; - } } return $old_duration; } diff --git a/sample_files/Rhythmic-model.pae b/sample_files/Rhythmic-model.pae new file mode 100644 index 0000000000000000000000000000000000000000..813fb20e927b65fbbaf3f8aa3ff580bd51366def --- /dev/null +++ b/sample_files/Rhythmic-model.pae @@ -0,0 +1,7 @@ +Test Composer +Test case for a rhythmic model +1.1.1: S rhythmic model +plain&easy: %G-2@6/8� '2.C/'8.68{AB''C}{DEF}/{GAB}{'''CDE}/8'CDEFGA// + +Test Library +00000000 \ No newline at end of file