Commit 796f6552 authored by Reinhold Kainhofer's avatar Reinhold Kainhofer
Browse files

Implement rhythmic models

-) Store the current rhythmic model in a global variable, loop index variable
-) Factor out raw duration and notehead functions to parse values also for
   rhythmic models
-) Reset rhythmic model as soon as a new explicit duration is encountered
parent c6aeb153
......@@ -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;
}
......
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
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment