summaryrefslogtreecommitdiff
path: root/Build/source/utils/xml2pmx/xml2pmx-src/obsrc/Complete.m
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/utils/xml2pmx/xml2pmx-src/obsrc/Complete.m')
-rw-r--r--Build/source/utils/xml2pmx/xml2pmx-src/obsrc/Complete.m254
1 files changed, 254 insertions, 0 deletions
diff --git a/Build/source/utils/xml2pmx/xml2pmx-src/obsrc/Complete.m b/Build/source/utils/xml2pmx/xml2pmx-src/obsrc/Complete.m
new file mode 100644
index 00000000000..bce3cac5db3
--- /dev/null
+++ b/Build/source/utils/xml2pmx/xml2pmx-src/obsrc/Complete.m
@@ -0,0 +1,254 @@
+MODULE Complete;
+IMPORT Strings := Strings1, Out;
+TYPE LONGINT = INTEGER;
+VAR pmxdur : ARRAY 10 OF ARRAY 4 OF CHAR; durvec : ARRAY 10 OF INTEGER; ixmax : LONGINT;
+notetypexml: ARRAY 10 OF ARRAY 8 OF CHAR; notetypepmx: ARRAY 10 OF CHAR;
+notetypei : ARRAY 10 OF INTEGER; (* inverse of notetype index 0 => 64 *)
+ PROCEDURE erasetime*(nostaves : LONGINT; VAR time: ARRAY OF ARRAY OF INTEGER );
+ VAR ps, i, j: LONGINT;
+ BEGIN
+ ps := nostaves - 1;
+ WHILE (ps >= 0) DO
+
+ i := 0; j := LEN( time, 1 );
+ WHILE i < j DO time[ps, i] := 0; INC( i ) END;
+ DEC( ps );
+ END;
+ END erasetime;
+ PROCEDURE divdur* (measuredur,div : INTEGER; VAR beats, beattype : INTEGER);
+ BEGIN
+ IF ( measuredur MOD div = 0 ) THEN
+ beattype := 4; beats := measuredur DIV div;
+ ELSIF ( 2* measuredur MOD div = 0 ) THEN
+ beattype := 8; beats := 2* measuredur DIV div;
+ ELSIF ( 4 * measuredur MOD div = 0 ) THEN
+ beattype := 16; beats := 4 * measuredur DIV div;
+ ELSE
+ Out.Ln(); Out.String(" error in divdur ");
+ END;
+ Out.Ln(); Out.Int(measuredur,5); Out.Int(div,5); Out.Int(beats,5); Out.Int(beattype,5);
+ END divdur;
+ PROCEDURE testdivdur*;
+ VAR beats, beattype : INTEGER;
+ BEGIN
+ divdur (4096, 1024, beats, beattype);
+ divdur (192, 48, beats, beattype);
+ divdur (144, 48, beats, beattype);
+ divdur (216, 48, beats, beattype);
+ divdur (72, 48, beats, beattype);
+ divdur (96, 48, beats, beattype);
+ divdur (240, 48, beats, beattype);
+
+ divdur (4096, 1024, beats, beattype);
+
+ END testdivdur;
+
+
+ PROCEDURE CalcForward* (note,div : INTEGER; VAR res : ARRAY OF CHAR);
+ VAR i : INTEGER;
+ BEGIN
+ i := 0; WHILE i < 8 DO durvec[i]:= 0 ; INC(i) END; (* erase durvec *)
+
+
+ Durit (note,div);
+
+ blindrest(durvec,res);
+
+(* Out.String("CalcForward res : ");Out.Ln();Out.String(res); *)
+
+
+
+ END CalcForward;
+ PROCEDURE notetype;
+ (* Defines the MusicXML types of notes *)
+ BEGIN
+
+ COPY( "64th", notetypexml[0] ); COPY( "32nd", notetypexml[1] ); COPY( "16th", notetypexml[2] );
+ COPY( "eighth", notetypexml[3] ); COPY( "quarter", notetypexml[4] ); COPY( "half", notetypexml[5] );
+ COPY( "whole", notetypexml[6] ); COPY( "breve", notetypexml[7] );
+ notetypepmx[0] := "6"; notetypepmx[1] := "3"; notetypepmx[2] := "1";
+ notetypepmx[3] := "8"; notetypepmx[4] := "4";
+ notetypepmx[5] := "2"; notetypepmx[6] := "0"; notetypepmx[7] := "9";
+ notetypei[0] := 64; notetypei[1] := 32;notetypei[2] := 16;notetypei[3] := 8;
+ notetypei[4] := 4;notetypei[5] :=2;notetypei[6] := 1;
+ END notetype;
+
+ PROCEDURE tupletduration* ( div: INTEGER; normaltype: ARRAY OF CHAR; normal: INTEGER ): INTEGER;
+ (* calculates the duration of a tuplet, starting from divisions, normaltype, and normal count *)
+ VAR i, fac: INTEGER;
+ BEGIN
+ fac := 1; i := 0;
+ WHILE (i < 8) & (notetypexml[i] # normaltype) DO
+ fac := fac*2; INC( i ); END;
+ IF i < 8 THEN RETURN div*normal*fac DIV 16
+ ELSE Out.Ln(); Out.String("tupletduration normaltype "); Out.String(normaltype);Out.String("not found"); RETURN 0; END;
+ END tupletduration;
+
+
+ PROCEDURE dur2beat* (duration,divisions : INTEGER; VAR beat, beattype : INTEGER);
+ (* calculates beat and beattype from duration of a measure *)
+ VAR i : INTEGER;
+ BEGIN
+ i := 0; WHILE i < 8 DO durvec[i]:= 0 ; INC(i) END; (* erase durvec *)
+
+ (* Out.Ln(); Out.String("dur2beat duration, divisions : ");Out.Int(duration, 5); Out.Int(divisions,5); *)
+
+ IF ( duration MOD divisions = 0 ) THEN
+ beattype := 4; beat := duration DIV divisions
+ ELSIF (duration MOD (divisions DIV 2) ) = 0 THEN
+ beattype :=8; beat := duration * 2 DIV divisions
+ ELSIF (duration MOD (divisions DIV 4)) = 0 THEN
+ beattype := 16; beat := duration * 4 DIV divisions
+ END;
+ (* Out.Ln(); Out.String("dur2beat beat / beattype : "); Out.Int(beat,5); Out.Int(beattype,5); *)
+
+ END dur2beat;
+ PROCEDURE testdur2beat*;
+ VAR beat, beattype : INTEGER;
+ BEGIN
+ dur2beat(240,48, beat, beattype);
+ dur2beat(216,48, beat, beattype);
+ dur2beat(144,48, beat, beattype);
+ dur2beat(36,48, beat, beattype);
+ END testdur2beat;
+
+ PROCEDURE Durit(note,div : INTEGER);
+ VAR index, rest, i : INTEGER;
+ BEGIN
+ i := 0;
+ REPEAT
+(* Out.Ln(); Out.String("Durit : note, div "); Out.Int(note, 5); Out.Int(div, 5); *)
+ FindDurit(note, div,index, rest);
+ note := rest; INC(i);
+ UNTIL (i > 4) OR (rest = 0);
+ END Durit;
+ PROCEDURE FindDurit(note,div: INTEGER; VAR index,rest : INTEGER );
+ (* distributes a given note duration into available note values and stores tthe distribution in xmldur. *)
+ VAR
+ i : INTEGER;
+ xmldur : ARRAY 9 OF INTEGER; (* change 25.April 2020 *)
+
+ BEGIN
+ xmldur[0] := 4 * div;
+ xmldur[1] := 2 * div;
+ xmldur[2] := div; ixmax := 2;
+ IF ( ( div MOD 2 ) = 0 ) THEN xmldur[3] := div DIV 2 ; ixmax := 3; END;
+ IF ( ( div MOD 4 ) = 0 ) THEN xmldur[4] := div DIV 4; ixmax := 4; END;
+ IF ( ( div MOD 8 ) = 0 ) THEN xmldur[5] := div DIV 8; ixmax := 5; END;
+ IF ( ( div MOD 16 ) = 0 ) THEN xmldur[6] := div DIV 16;ixmax := 6; END;
+ IF ( ( div MOD 32 ) = 0 ) THEN xmldur[7] := div DIV 32;ixmax := 7; END;
+ IF ( ( div MOD 64 ) = 0 ) THEN xmldur[8] := div DIV 64;ixmax := 8; END; (* change 25.April 2020 *)
+
+
+
+ i := 0; WHILE ( i < LEN(xmldur) - 1) & ( xmldur[i] > note ) DO INC(i); END; (* change 25.04.2020 *)
+ IF xmldur[i] <= note THEN
+
+ index := i; rest := note - xmldur[i];
+(* Out.Ln(); Out.String("FindDurit : "); Out.Int(note,5); Out.Int(div,5); Out.Int(index,5); Out.Int(rest,5); *)
+ INC(durvec[i], 1); END;
+
+ END FindDurit;
+
+ PROCEDURE blindrest (durvec : ARRAY OF INTEGER; VAR res : ARRAY OF CHAR);
+ VAR i,j : INTEGER;
+ BEGIN
+ i := 0; WHILE i < 32 DO res[i] := 0X; INC(i) END;
+ i := 0; WHILE ( i < 7 ) DO
+ j := 0; WHILE ( j < durvec[i] ) DO
+ Strings.AppendCh(res, " ");
+ Strings.Append(res,pmxdur[i]);
+ INC(j); END;
+ INC(i) END; Strings.AppendCh(res," ");
+ END blindrest;
+
+
+PROCEDURE Int2br* ( divisions, intdur : INTEGER; VAR res : ARRAY OF CHAR);
+(* converts an Integer Interval into a series of blind rests *)
+VAR i : INTEGER;
+BEGIN
+i := 0; WHILE i < 7 DO durvec[i] := 0; INC(i); END;
+i := 0; WHILE i < LEN(res) DO res[i] := 0X; INC(i); END;
+Durit(intdur, divisions);
+blindrest (durvec, res);
+(* Out.Ln();Out.String("divisions : "); Out.Int(divisions,5); Out.String("duration : ");
+ Out.Int(intdur,5); Out.String("pmx-decomposition : "); Out.String(res); *)
+END Int2br;
+
+PROCEDURE Dur2PMX* ( divisions, intdur : INTEGER; VAR res : ARRAY OF CHAR);
+(* converts an Integer Interval into a series of blind rests *)
+VAR i : INTEGER;
+BEGIN
+i := 0; WHILE i < 7 DO durvec[i] := 0; INC(i); END;
+i := 0; WHILE i < LEN(res) DO res[i] := 0X; INC(i); END;
+Durit(intdur, divisions);
+i := 0; WHILE (durvec[i] = 0) DO INC(i) END;
+IF durvec[i] = 1 THEN res[0] := pmxdur[i,1];
+ IF durvec[i+1] = 1 THEN Strings.AppendCh(res,"d");
+ IF durvec[i+2] = 1 THEN Strings.AppendCh(res,"d"); END;
+ END;
+END;
+(* Out.Ln();Out.String("divisions : "); Out.Int(divisions,5); Out.String("duration : ");
+ Out.Int(intdur,5); Out.String("pmx-decomposition : "); Out.String(res); *)
+
+END Dur2PMX;
+
+PROCEDURE testDur2PMX*;
+VAR res : ARRAY 32 OF CHAR;
+BEGIN
+
+Dur2PMX (256, 64,res);
+
+
+Dur2PMX (256,32,res);
+
+Dur2PMX (256,16,res);
+
+Dur2PMX (256,8,res);
+Dur2PMX (1024,768,res);
+
+Dur2PMX (1024,1536,res);
+
+END testDur2PMX;
+PROCEDURE Complete* (from, to, divisions, measureduration : INTEGER; VAR before, after : ARRAY OF CHAR);
+ (* solves the problem of dangling notes created with the backup or forward statement of MusicXML *)
+ VAR beforedur, afterdur, i : INTEGER;
+ BEGIN
+ beforedur := from - 1;
+ afterdur := measureduration - to;
+ (* Out.Ln(); Out.String(" from, to, divisions, measureduration : ");
+ Out.Int(from,5); Out.Int(to,5); Out.Int(divisions,5); Out.Int(measureduration,5);
+ Out.String(" Complete : beforedur, afterdur"); Out.Int(beforedur,5); Out.Int(afterdur,5); *)
+ i := 0; WHILE i < 7 DO durvec[i] := 0; INC(i); END;before[0] := 0X; after[0] := 0X;
+ IF ( beforedur > 0 ) THEN Durit(beforedur,divisions);
+ blindrest (durvec,before);
+ END;
+ (* loesch durvec ! *) i := 0; WHILE i < 7 DO durvec[i] := 0; INC(i); END;
+
+ IF ( afterdur > 0 ) THEN Durit (afterdur,divisions);
+ blindrest (durvec, after); END;
+ (* Out.String(" before|after : "); Out.String(before); Out.Char("|");Out.String(after); *)
+END Complete;
+BEGIN
+ notetype; (* initialize notes type conversion XML -> PMX *)
+ pmxdur[0] := "r0b";
+ pmxdur[1] := "r2b";
+ pmxdur[2] := "r4b";
+ pmxdur[3] := "r8b" ;
+ pmxdur[4] := "r1b" ;
+ pmxdur[5] := "r3b" ;
+ pmxdur[6] := "r6b";
+ pmxdur[7] := "r7b";
+
+END Complete.testdur2beat
+
+Complete.testdivdur
+
+Complete.TestFindDur
+
+
+Complete.testDur2PMX
+
+TestFindDur
+
+ System.Free Complete