diff options
Diffstat (limited to 'Build/source/utils/xml2pmx/xml2pmx-src/obsrc/Testbed.m')
-rw-r--r-- | Build/source/utils/xml2pmx/xml2pmx-src/obsrc/Testbed.m | 2996 |
1 files changed, 0 insertions, 2996 deletions
diff --git a/Build/source/utils/xml2pmx/xml2pmx-src/obsrc/Testbed.m b/Build/source/utils/xml2pmx/xml2pmx-src/obsrc/Testbed.m deleted file mode 100644 index ac181a1dfd4..00000000000 --- a/Build/source/utils/xml2pmx/xml2pmx-src/obsrc/Testbed.m +++ /dev/null @@ -1,2996 +0,0 @@ -MODULE Testbed; - -(***************************************************************************) -(**************** Copyright 2015--2021 Dieter Gloetzel ********************) -(************************ Version016 multi platform ***********************) -(***************************************************************************) -(* This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. *) - - (* corrections starting 09.07.2020 beam2pmx add "l" or "u" to "[j" *) - (* IMPORT Texts, Strings, Files, Oberon, b, Complete, Out; (* Import fuer Oberon Version *) *) - (* IMPORT Args32, Strings, Files, Out := WCout, b, Complete, Fifo ; *) (* Import fuer Windows-Exe Version *) - IMPORT Args, Files := MyFiles, Strings := Strings1, Out, b, Complete; (* Import for Linux-Version *) - - -CONST - NL = 0AX; BLANK = 20X; (* TAB = 09X; *) CR = 0DX; measurelimit = 600; -TYPE - LONGINT = INTEGER; - ControlDesc = RECORD (* data structure of input data *) - xml, dtd: ARRAY 256 OF CHAR; - title: ARRAY 128 OF CHAR; - composer, lyricist, info, software: ARRAY 128 OF CHAR; - rights: ARRAY 128 OF CHAR; - parts: ARRAY 30 OF ARRAY 16 OF CHAR; - instruments: ARRAY 30 OF ARRAY 32 OF CHAR; - worknumber: ARRAY 32 OF CHAR; - equalkeys : BOOLEAN; - - END; - AttributesDesc = RECORD (* initial signature, meter , #staves,clef *) - - measure, note, pickup: LONGINT; - divisions, duration: INTEGER; - fifth: INTEGER; - beats: INTEGER; - beattype, mtrdenp: INTEGER; - staves: INTEGER; - clefsign: ARRAY 4 OF CHAR; (* index is for staff *) - clefline: ARRAY 4 OF LONGINT; - diatonic, chromatic: LONGINT; - octave: LONGINT; (* parameters in <transpose> *) - END; - DirectionDesc = RECORD (* data structure for directions *) - part, staff, measure, note, lastnote, voice: LONGINT; (* voice ? implizit ueber lastnote definiert *) - before: BOOLEAN; - placement: CHAR; (* "h" or "l" for above and below *) - dirtype: CHAR; (* words, metronome, dynamics, wedge= hairpin, pedal, segno, coda, other *) - wedgetype: ARRAY 32 OF CHAR; (* crescendo, diminuendo, stop crescendo and stop diminuendo *) - dyntype: ARRAY 16 OF CHAR; - pedaltype: ARRAY 16 OF CHAR; (* start, stop, *) - text: ARRAY 128 OF CHAR; - pmxdirection: ARRAY 128 OF CHAR; - defaultx: INTEGER; - used: BOOLEAN; (* avoid duplication of dynamic marks in case of two voices in a staff - enable two directions at one note *) - END; - NoteDesc = RECORD (* properties of a note *) - accidental: ARRAY 10 OF CHAR; - actual: INTEGER; - (* arpeggio: BOOLEAN; *) - (* base : INTEGER; Base note of a chord *) - beam, closebeam: ARRAY 16 OF CHAR; - chord: CHAR; cue : BOOLEAN; - clef: CHAR; - clefchanged: CHAR; - defaultx: INTEGER; - dot: CHAR; - fermata: ARRAY 16 OF CHAR; - from, to, duration: INTEGER; - grace: INTEGER; - lefttext, righttext: ARRAY 256 OF CHAR; - maxbeam : LONGINT; (* number of beams for binary tremolo*) - normal: INTEGER; - pitchoctave: INTEGER; - pitchstep: CHAR; - pmxgrace: ARRAY 32 OF CHAR; (* Aenderung 16.11.2020 *) - pmxnote: ARRAY 64 OF CHAR; - probj: BOOLEAN; (* evaluates print-object = "no" TRUE means "print", FALSE don't print *) - rbleft, rbright: ARRAY 32 OF CHAR; (* blind rests to fill incomplete measures *) - repeat: ARRAY 16 OF CHAR; - rest, blind: CHAR; - slur: ARRAY 2 OF ARRAY 8 OF CHAR; - staccato, accent, trill, strongaccent: ARRAY 8 OF CHAR; - staff: INTEGER; - stem: CHAR; - tied: ARRAY 2 OF ARRAY 8 OF CHAR; - trembeam: LONGINT; - tremolotype : ARRAY 32 OF CHAR; - tuplet: ARRAY 16 OF CHAR; - type, normaltype: ARRAY 8 OF CHAR; (* begend begin and end of a series of Grace notes *) - voicetime: INTEGER; - END; - MeasureDesc = RECORD (* properties of measure *) - beattype, beats, fifth: INTEGER; - repeat: ARRAY 16 OF CHAR; - ending: ARRAY 16 OF CHAR; - barstyle, meterchange: ARRAY 16 OF CHAR; - voicetime: ARRAY 27 OF ARRAY 4 OF INTEGER; - duration, keys: ARRAY 27 OF INTEGER; - (* divisions : ARRAY 27 OF INTEGER; *) - dur : INTEGER; (* measure actual length of a measure *) - clefchange : ARRAY 27 OF CHAR; (* Maerz 2018 *) - END; - -VAR - - uptomeasure : LONGINT; (* global variable for reducing the number of measures *) - - notes: POINTER TO ARRAY 24 OF ARRAY 3 OF ARRAY 600 OF ARRAY 83 OF POINTER TO NoteDesc; (*20-10-2020 Lilypond2 *) - - (* notes: POINTER TO ARRAY 24 OF ARRAY 3 OF ARRAY 400 OF ARRAY 64 OF NoteDesc; *) - - keytotal : ARRAY 132 OF CHAR; - unix: BOOLEAN; outputcont : ARRAY 32 OF CHAR; outputset : SET; - voicemeasure: POINTER TO ARRAY 30 OF ARRAY 600 OF SET; - voiceps: ARRAY 30 OF SET; - voicelimmps: ARRAY 30 OF LONGINT; - vmapps: ARRAY 30 OF ARRAY 5 OF LONGINT; - minvoice, maxvoice: POINTER TO ARRAY 27 OF ARRAY 600 OF LONGINT; - vmap: ARRAY 30 OF ARRAY 600 OF ARRAY 5 OF LONGINT; - (* notetypei : ARRAY 10 OF INTEGER; inverse of notetype index 0 => 64 *) - - clefspec, lastclef: ARRAY 27 OF CHAR; (* special clef and valid clef in the actual measure *) - - voicelimm: ARRAY 30 OF ARRAY 600 OF LONGINT; - sout : ARRAY 128 OF CHAR; (* target file path and directory *) - - (* controls# voices within a staff and measure*) - voicecount: ARRAY 30 OF LONGINT; (* counts different voices within a staff *) countnote, countattr, countdir : LONGINT; - - ingrace2pmx: LONGINT; - in, out: ARRAY 128 OF CHAR; - lastto, lastfrom: INTEGER; (* global variable for time progress in measure *) - pmxdur: ARRAY 16 OF CHAR; (* global variable: duration of notes in PMX *) - lastnote : LONGINT; (* global variable for position of last note *) - fi, fo: Files.File; ri: Files.Rider; - (* VAR notes : notestype; *) - voicetime: ARRAY 27 OF ARRAY 4 OF INTEGER; (* progress of notes duration in part,staff,voice, actual measure *) - lasttype: ARRAY 32 OF CHAR; (* beam type of preceding note *) - laststaff : LONGINT; - closebeam: ARRAY 8 OF CHAR; (* staff of preceding note for beam calculation *) - (* q: FIFO; *) (* global variable for sorted notes queue *) - maxdir, i, j, part, staff, voice, measure, note, count, maxpart, maxmeasure, itags, maxgrace, controlpart, - nostaves, nties, lfdnr, ps, dirnum, lastdirnum, attnum, lastattnum, lastgrace: LONGINT; - lastdyn: ARRAY 32 OF CHAR; - (* Global variables *) - stavesfound: BOOLEAN; - partlabel: ARRAY 27 OF ARRAY 5 OF CHAR; - directions: POINTER TO ARRAY 2000 OF ARRAY 5 OF DirectionDesc; - maxdirtype: ARRAY 2000 OF LONGINT; (* vorlaeufig, nur zum Daten sammeln. *) - attributes: ARRAY 30 OF AttributesDesc; - partstaff: ARRAY 30 OF ARRAY 2 OF LONGINT; - (* notes: ARRAY 30 OF ARRAY 2 OF ARRAY 500 OF ARRAY 64 OF NoteDesc; Aenderung wegen voice numerierung *) - maxnote, maxnote0, maxnote1, minnote0, minnote1, minnote: ARRAY 30 OF ARRAY 3 OF ARRAY 600 OF LONGINT; - (* number of last note in part/staff/measure *) - measures: POINTER TO ARRAY 600 OF MeasureDesc; - pmxcontrol: ControlDesc; - accidentaltag, parttag, measuretag, notetag, pitchtag, steptag, octavetag, durationtag, voicetag, dottag, stemtag, cleftag, clefoctavetag, staccatotag: ARRAY 32 OF CHAR; - attributestag, divisionstag, keytag, fifthstag, timetag, beatstag, beattypetag, stavestag, signtag, linetag, typetag, fermatatag, tuplettag: ARRAY 32 OF CHAR; - notationtag, lyrictag, syllabictag, texttag, resttag, chordtag, backuptag, repeattag, slurtag, stafftag, printtag, directiontag, tiedtag, - cleflinetag, actualtag, normaltag, beamtag, wordstag, eonotetag, eomeasuretag, barlinetag, endingtag, barstyletag, dynamicstag, - worktag, identificationtag, defaultstag, eoattributestag, forwardtag, eodirectiontag, credittag, gracetag, gracetag2, cuetag : ARRAY 32 OF CHAR; - staves: ARRAY 30 OF LONGINT; (* maximum staff of "part" *) - - beamopen : ARRAY 30 OF ARRAY 3 OF BOOLEAN; -(* cl: Args32.LPSTR; (* Command line for Windows.Exe *) *) - - - - - PROCEDURE pmxtype( xmltype: INTEGER ): INTEGER; - VAR i: INTEGER; - BEGIN - CASE xmltype OF - 1: i := 0; - | 2: i := 2; - | 4: i := 4; - | 8: i := 8; - | 16: - i := 1; - | 32: - i := 3; - | 64: - i := 6; - ELSE - Out.Ln(); i := -1; Out.String( "xml note type : " ); Out.Int( xmltype, 5 ); - Out.String( " not implemented." ); Out.Ln(); - END; - RETURN i; - - END pmxtype; - - - PROCEDURE FillRests( notefrom, noteto, measure, ps, voice: LONGINT ); - (* Fills incomplete measures with blind rests, as needed *) - VAR note, part, staff, lastnote: LONGINT; delta, lastto: INTEGER; (* global "lastnote" removed 29.11.2016 *) - BEGIN - part := partstaff[ps, 0]; staff := partstaff[ps, 1]; - lastto := 0; lastnote := 0; - - IF (measures[measure].voicetime[ps, voice] < measures[measure].duration[part]) THEN - (* Out.Ln(); Out.String( "Fillrests: notefrom. noteto " ); Out.Int( notefrom, 5 ); Out.Int( noteto, 5 ); *) note := notefrom; - WHILE note <= noteto DO - (* Out.Ln(); Out.Int( measure, 5 ); Out.Int( ps, 5 ); Out.Int( voice, 5 ); Out.Int( note, 5 ); *) - (* NoteOut(notes[ps,voice,measure,note]); *) - INC( note ); - END; - - - (* left of first note *) - note := notefrom; - IF (notes[ps, voice, measure, note] # NIL) & - (notes[ps, voice, measure, note].from > 0) THEN - - delta := notes[ps, voice, measure, note].from - 1; (* Out.Ln(); Out.String( " note delta : " ); - Out.Int( note, 5 ); Out.Int( delta, 5 ); *) - IF delta > 0 THEN Complete.Int2br( attributes[part].divisions, delta, notes[ps, voice, measure, note].rbleft ); END; - - lastnote := note; lastto := notes[ps, voice, measure, note].to; - - ELSE - END; - (* left of 2nd to last note *) - INC( note ); - - WHILE (note <= noteto) DO - IF ( notes[ps, voice, measure, note] # NIL ) & - (notes[ps, voice, measure, note].from > 0) THEN - delta := notes[ps, voice, measure, note].from - lastto - 1; - (* Out.Ln(); Out.String( " note delta : " ); Out.Int( note, 5 ); Out.Int( delta, 5 ); *) - - IF delta > 0 THEN - Complete.Int2br( attributes[part].divisions, delta, notes[ps, voice, measure, note].rbleft ); - - - END; - lastnote := note; - IF notes[ps, voice, measure, note] # NIL - THEN - lastto := notes[ps, voice, measure, note].to; - END - - END; - - INC( note ); - END; - (* right of last note *) - delta := measures[measure].duration[part] - lastto; - (* Out.Ln(); Out.Int(ps,5); Out.Int(measure,5);Out.String( " note delta : " ); - Out.Ln(); Out.Int( lastnote, 5 ); Out.Int( delta, 5 ); *) - IF delta > 0 THEN - Complete.Int2br( attributes[part].divisions, delta, notes[ps, voice, measure, lastnote].rbright ); - - END; - - END; - - END FillRests; - - PROCEDURE PMXdyn( XMLdyn: ARRAY OF CHAR; VAR out: ARRAY OF CHAR ); - (* converts e.g. <f /> to " Df "*) - BEGIN - (* doubke on purpose *) - IF XMLdyn = "<f />" THEN COPY( " Df ", out ); END; - IF XMLdyn = "<ff />" THEN COPY( " Dff ", out ); END; - IF XMLdyn = "<fff />" THEN COPY( " Dfff ", out ); END; - IF XMLdyn = "<ffff/>" THEN COPY( " Dffff ", out ); END; - IF XMLdyn = "<mf />" THEN COPY( " Dmf ", out ); END; - IF XMLdyn = "<p />" THEN COPY( " Dp ", out ); END; - IF XMLdyn = "<pp />" THEN COPY( " Dpp ", out ); END; - IF XMLdyn = "<ppp />" THEN COPY( " Dppp ", out ); END; - IF XMLdyn = "<pppp />" THEN COPY( " Dpppp ", out ); END; - IF XMLdyn = "<mp />" THEN COPY( " Dmp ", out ); END; - IF XMLdyn = "<sf />" THEN COPY( " Dsfz ", out ); END; - IF XMLdyn = "<fp />" THEN COPY( " Dfp ", out ); END; - IF XMLdyn = "<f/>" THEN COPY( " Df ", out ); END; - IF XMLdyn = "<ff/>" THEN COPY( " Dff ", out ); END; - IF XMLdyn = "<fff/>" THEN COPY( " Dfff ", out ); END; - IF XMLdyn = "<ffff/>" THEN COPY( " Dffff ", out ); END; - IF XMLdyn = "<mf/>" THEN COPY( " Dmf ", out ); END; - IF XMLdyn = "<p/>" THEN COPY( " Dp ", out ); END; - IF XMLdyn = "<pp/>" THEN COPY( " Dpp ", out ); END; - IF XMLdyn = "<ppp/>" THEN COPY( " Dppp ", out ); END; - IF XMLdyn = "<pppp/>" THEN COPY( " Dpppp ", out ); END; - IF XMLdyn = "<mp/>" THEN COPY( " Dmp ", out ); END; - IF XMLdyn = "<sf/>" THEN COPY( " Dsfz ", out ); END; - IF XMLdyn = "<fp/>" THEN COPY( " Dfp ", out ); END; - - - - IF ( XMLdyn = "crescendo") & (lastdyn # " D<" ) THEN COPY( " D<", out ); COPY( out, lastdyn ); END; (* 18.02.2017 *) - - IF ( XMLdyn = "diminuendo" ) & (lastdyn # " D>" ) THEN COPY( " D>", out ); COPY( out, lastdyn ); - END; - IF XMLdyn = "stop" THEN COPY( lastdyn, out );IF lastdyn # "" THEN Strings.Append( out, "+0+3" ); END; - b.loesch( lastdyn ); END; - (* Out.String( XMLdyn ); Out.Char( "|" ); Out.String( out ); *) - END PMXdyn; - - PROCEDURE WriteLInt( VAR W: Files.Rider; i: LONGINT ); - VAR si: ARRAY 10 OF CHAR; - BEGIN - Strings.IntToStr( i, si ); Files.Write( W, BLANK ); WriteString( W, si ); - END WriteLInt; - - PROCEDURE WriteString( VAR W: Files.Rider; s: ARRAY OF CHAR ); - BEGIN - Files.WriteBytes( W, s, Strings.Length( s ) ); - END WriteString; - - - PROCEDURE SetOutput*; - VAR c : CHAR; i : LONGINT; - BEGIN - i := 0; WHILE i < Strings.Length(outputcont) DO - c := outputcont[i]; - CASE c OF - - | "R" : INCL(outputset,10); (* remove notes with print-obj="no" in print phase; e.g. for xml-files with programmed Trill 20-11-2019 *) - | "P" : INCL(outputset,9); (* parser output 0 durch 9 ersetzt 20.05.2019 *) - | "D" : INCL(outputset,1); (* list directions *) - | "V" : INCL(outputset,2); (* list voices per measure and instrument *) - | "A" : INCL(outputset,3); (* Statistics of MusicXML tags *) - | "L" : INCL(outputset,4); (* store lyrics *) - | "S" : INCL(outputset,5); (* remove all slurs *) - | "T" : INCL(outputset,6); (* remove all ties *) - | "G" : INCL(outputset,7); (* eliminate slurs around grace notes, replace by PMX internal Grace notes. *) - | "X" : INCL(outputset,8); (* x-option for voice crossing slurs, only with PMX282 *) - | "N" : (* no option chosen *) - - ELSE Out.String(" option not implemented.") - END; - INC(i); END; - END SetOutput; - -(* PROCEDURE commandO*; (* Command for Oberon-Version *) - VAR R: Texts.Reader; i: LONGINT; c: CHAR; - BEGIN - (* 0. Read Filenames from Oberon.Par.text *) - Texts.OpenReader( R, Oberon.Par.text, Oberon.Par.pos ); Texts.Read( R, c ); i := 0; - WHILE (c # "~") & (~R.eot) & (i < LEN( comline )) DO comline[i] := c; Texts.Read( R, c ); INC( i ) END; - comline[i - 1] := 0X; Out.Ln(); Out.String("comline : ");Out.String (comline); - Filenames(FALSE, comline, in, out, outputcont ); - Stripfilename(out,sout); InOut( in, out ); - - END commandO; *) - - (* PROCEDURE commandX; (* WIndows EXE *) - VAR i: LONGINT; c: CHAR; - BEGIN - Args32.Str( "Program XML2PMX.EXE Copyright 2016 Dieter Gloetzel" ); Args32.Ln(); - - cl := Args32.GetCommandLine(); Args32.CopyString( cl, comline ); Args32.Str( comline ); Args32.Ln(); - Filenames(TRUE,comline,in,out,outputcont); - Stripfilename(out,sout); InOut( in, out ); - END commandX; *) - PROCEDURE CommandU; - VAR output : ARRAY 16 OF CHAR; kno : LONGINT; - BEGIN - kno := Args.argc; - IF ( kno >= 3 ) THEN - Args.GetArg(1, in); - Args.GetArg(2, out); - COPY(out,sout); - Strings.ChangeSuffix(sout,"txt"); - IF ( kno >= 4 ) THEN Args.GetArg(3,output); END; - Strings.Upper(output,outputcont); - SetOutput; b.voutput := (2 IN outputset); - IF ( kno = 5 ) THEN Args.GetArg(4,output); Strings.StrToInt(output,uptomeasure); END; - Out.String( "Linux Binary XML2PMX Copyright 2015/2021 Dieter Gloetzel" ); Out.Ln(); - InOut(in, out); - ELSE - Args.GetArg(0, in); - Out.String(in); Out.String(" error: argument number < 2 "); Out.Ln; - END; - END CommandU; - - PROCEDURE Voicing( q: b.FIFO); - (* calculates an array of Sets vontaining the voices for part, staff and measure. *) - VAR n: b.Tag; - BEGIN - n := q.first; - WHILE (n.next # NIL ) DO - IF n.tagname = notetag THEN - ps := linstaff( nostaves, n.part, n.staff ); INCL( voicemeasure[ps, n.measure], n.voice ); - INCL( voiceps[ps], n.voice ); maxvoice[ps, n.measure] := b.Max( maxvoice[ps, n.measure], n.voice ); - minvoice[ps, n.measure] := b.Min( minvoice[ps, n.measure], n.voice ); - END; - n := n.next; - END; - END Voicing; - - PROCEDURE DeleteTag(deltag : b.Tag); - VAR n : b.Tag; - BEGIN - n := b.q.first; - REPEAT n := n.next UNTIL (n.next = NIL) OR (n.next = deltag); - IF n.next = deltag THEN n.next := deltag.next END; - (* Out.Ln(); Out.Int(deltag.nr, 5); Out.String("deleted"); *) - END DeleteTag; - -PROCEDURE DeleteTS (tag : ARRAY OF CHAR); (* deletes all ties or slurs according to "tag" *) - VAR n : b.Tag; count : LONGINT; - BEGIN - n:= b.q.first; count := 0; - WHILE n.next # NIL DO - - IF (n.tagname = tag) (* tags of type "tag" will be removed. *) - THEN - (* b.OutTag(n, TRUE); Out.String("deleted"); *) - DeleteTag(n); INC(count); - END; - n:= n.next END; - Out.Ln(); Out.String("********************************"); - Out.Int (count,5); Out.String(tag); Out.String ("deleted"); -END DeleteTS; - - - - -PROCEDURE InOut( infilename, outfilename: ARRAY OF CHAR ); - VAR n: b.Tag; (* data structure for sorting notes *) - outfilenameprep: ARRAY 64 OF CHAR; - fprep: Files.File; rprep: Files.Rider; res : INTEGER; - BEGIN - Out.String( "This is XML2PMX Version 16. dyn. alloc." ); fi := Files.Old( infilename ); - IF (fi # NIL ) THEN (* 1*) - Files.Set( ri, fi, 0 ); - (***************************************) - (* 1. Analyze XML data *) AnalyzeXML2( ri ); - - (* n:= b.q.first; WHILE n.next # NIL DO b.OutTag(n, TRUE); n:= n.next END; *) - - (* DeleteTies or Slurs; *) - IF (5 IN outputset) THEN DeleteTS("<slur>"); END; - IF (6 IN outputset) THEN DeleteTS("<tied>"); END; - - (* 2. create temporary result storage for PMX-data *) - COPY( outfilename, outfilenameprep ); Strings.Append( outfilenameprep, "prep" ); - fprep := Files.New( outfilenameprep ); Files.Set( rprep, fprep, 0 ); - Out.Ln(); Out.String("Intermediate output file "); Out.String(outfilenameprep); Out.String(" created. "); - - (* 3. map part/staff to a linear index. *) AllStaves( staves ); - Out.Ln(); Out.String("3: Allstaves done!"); - (* 4. Extract control data *) ControlProp; - Out.Ln(); Out.String("4: ControlProp done!"); - (* 5. Enrich Data *) Enrich( b.q ); - Out.Ln(); Out.String("5: Enrich done!"); - (* n := b.q.first; - WHILE n.next # NIL DO b.OutTag( n, TRUE ); n := n.next END; *) - (****************************************************************************) - (*6. Calculate data for mapping of voices between PMX and XML *) - - Voicing( b.q ); (* Store voices wrt part,stave and measure. *) - Out.Ln(); Out.String("6 : Voicing done!"); - - IF (2 IN outputset) THEN Out.Ln(); - Out.String( "*************** voices per instrument (part/staff) " ); ps := 0; - Out.Ln(); Out.String( "nostaves" ); Out.Int( nostaves, 5 ); - WHILE ps < nostaves DO - Out.Ln(); Out.Int( ps, 5 ); b.Outset( voiceps[ps], voicelimmps[ps], vmapps[ps] ); INC( ps ); - END; - END; - ps := 0; - IF 2 IN outputset THEN - Out.Ln(); - Out.String( "*************** voices per measure and instrument (part/staff) " ); Out.Ln(); - END; - WHILE ps < nostaves DO; - measure := 1; - WHILE measure <= maxmeasure DO - IF (2 IN outputset) THEN - Out.Ln(); Out.Int( ps, 5 ); Out.Int( measure, 5 ); - END; - b.Outset( voicemeasure[ps, measure], voicelimm[ps, measure], vmap[ps, measure] ); - (* Out.Int(minvoice[ps,measure],5); Out.Int(maxvoice[ps,measure],5); *) - INC( measure ); - END; - INC( ps ); - END; - (****************************************************************************) - - - - (* i := 1; - WHILE i <= maxpart DO - Out.Ln(); Out.String( "part, label : " ); Out.Int( i, 5 ); Out.String( partlabel[i] ); INC( i ); - END; *) - (* 7. identify potential pickup *) Pickup( b.q, attributes[1].pickup ); - Out.Ln(); Out.String("7: Pickup done!"); - - - - (* 8. Generate Control data for PMX (i.e everything before the notes and store in"outfilename"*) - - ControlData( rprep ); - Out.Ln(); Out.String("8: ControlData done!"); - - - - - (* *) - - (*9. Investigate time series of notes (e.g. incomplete measures) *) - progress( b.q ); - Out.Ln(); Out.String("9: progress done!"); - (* listmeter;*) - - - (* IF 1 = 0 THEN *) - (* 10. Store everything in arrays measurewise *) - EnumerateTags; Out.Ln(); Out.String( "10: EnumerateTags done!" ); - - IF 9 IN outputset THEN (* Option "p" *) - n := b.q.first; WHILE (n.next # NIL) & (n.measure < uptomeasure) DO b.OutTag(n,TRUE); - n:= n.next; END; - END; - - (* listmeter;*) - (* 11.. Generate PMX and store in outfilename *) - (* 14.11.2020: Do not link directions to grace notes *) - (* IF (voice = 0) & (notes[ps,voice,measure,note].grace = 0 ) THEN *) DistributeDirections; (* END; *) - WritePMX( rprep ); Out.Ln(); Out.String( "11: nach WritePMX" ); - (* 12. Remove multiple Blanks from result file and break lines after 100 Chars *) - Files.Register( fprep ); fo := Files.New( outfilename ); Copywo( fprep, fo, unix ); Files.Close( fi ); - Files.Close(fprep); Files.Delete( outfilenameprep, res ); - IF ( res = 0 ) THEN Out.Ln(); Out.String("Intermediate data deleted"); END; - Files.Register( fo ); Files.Close( fo ); Out.Ln(); Out.String(out); Out.String( " registered" ); - - (* END; *) - - IF (4 IN outputset) THEN b.writetext; END; (* Lyrics is decoded in MODULE "b" and appears in "songtext.txt" in this directory. *) - - IF (3 IN outputset) THEN b.SortTags END; (* lists all occurences of XML-Tags. *) - ELSE - Out.Ln(); Out.String("input file: "); Out.String(infilename); Out.String(" not found "); - END; - - (* Out.Ln(); Out.String("countclefchanges : "); - - Out.Int(countclefchanges,5); *) - Out.Ln() - END InOut; - - - PROCEDURE Copywo( VAR fin, fout: Files.File; unix: BOOLEAN ); - (* Copies a File and eliminates multiple BLANKs. *) - VAR ch: CHAR; rin, rout: Files.Rider; column: LONGINT; - BEGIN - Files.Set( rin, fin, 0 ); Files.Set( rout, fout, 0 ); column := 0; Files.Read( rin, ch ); - WHILE ~rin.eof DO - IF (~unix) THEN Files.Write( rout, Strings.OberonToISO[ORD( ch )] ); INC( column ); - ELSIF unix & (ch # CR) THEN Files.Write( rout, Strings.OberonToISO[ORD( ch )] ); INC( column ); - END; - IF (ch = NL) THEN column := 0; END; - IF (column > 100) & (ch = BLANK) THEN - column := 0; - IF (~unix) THEN Files.Write( rout, CR ); END; - Files.Write( rout, NL ); - END; - - (* IF ch =Strings.CR THEN Files.Write(R,NL); END; *) - IF (ch = BLANK) THEN - WHILE (ch = BLANK) DO Files.Read( rin, ch ); END; - ELSE Files.Read( rin, ch ); - - END; - - END; - END Copywo; - - PROCEDURE DistributeDirections; - VAR idir, j, lastnote, lastidir, lastj, lastmeasure, lastlastnote, lastps, noteto, firstnote, count: LONGINT; - lastdirtype: CHAR; - posnote: ARRAY 64 OF INTEGER; - BEGIN - lastnote := 0; - idir := 1; - WHILE idir <= maxdir DO - j := 1; - WHILE j <= maxdirtype[idir] DO - - - part := directions[idir, 0].part; - staff := directions[idir, 0].staff; lastmeasure := measure; - measure := directions[idir, 0].measure; - lastlastnote := lastnote; lastnote := directions[idir, 0].lastnote; - - - IF (1 IN outputset) THEN (* Print all directions *) OutDir( idir, j ); END; - - (* IF lastnote = 0 THEN lastnote := 1 END; *) - lastps := ps; ps := linstaff( nostaves, part, staff ); firstnote := minnote0[part, staff, measure]; - IF (notes[ps,0,measure,firstnote].grace > 0) THEN (* first note is grace note and cannot carry dynamic marks *) - - (* Out.Ln(); Out.String("DistrDir : ");Out.Int(ps,5); Out.Int(measure,5); Out.Int(firstnote,5); Out.Char("|"); - Out.Int(notes[ps,0,measure,firstnote].grace,5 ); Out.Int(lastnote,5); *) - - REPEAT INC(firstnote) UNTIL notes[ps,0,measure,firstnote].grace = 0; - Out.Ln(); Out.String(" first real note at ps, measure, note :"); Out.Int(ps,5); Out.Int(measure,5); Out.Int(firstnote,5); - Out.Char("|"); Out.Int(notes[ps,0,measure,firstnote].grace,5 ); - - END; - CASE directions[idir, j].dirtype OF - - "w": (* words, i.e. text *) - IF lastnote < firstnote THEN lastnote := firstnote END; - - IF (notes[ps, 0, measure, lastnote].lefttext = "") THEN - Strings.Append( notes[ps, 0, measure, lastnote].lefttext, directions[idir, j].pmxdirection ); (* pmxdirection pruefen *) - (* Out.Ln(); Out.String("idir,j,pmxdirection "); Out.Int(idir,5); Out.Char("|");Out.Int(j,5); Out.Char("|"); - Out.String(directions[idir,j].pmxdirection); *) - - ELSE - b.APPzca( notes[ps, 0, measure, lastnote].lefttext, directions[idir, j].pmxdirection ); - b.loesch( directions[idir, j].pmxdirection ); - END; - - | "h": (* hair pins *) - IF lastnote < firstnote THEN lastnote := firstnote END; - IF ( lastnote > maxnote0[part,staff,measure] ) THEN lastnote := maxnote0[part,staff,measure] END; (* Modification 23.12.2016 *) - Strings.Append( notes[ps, 0, measure, lastnote].righttext, directions[idir, j].pmxdirection ); - lastdirtype := "h"; - | "d": (* dynamic marks *) - IF (directions[idir, j].lastnote = 0) & (directions[idir, j].defaultx = 0) THEN - directions[idir, j].lastnote := firstnote; lastnote := directions[idir, j].lastnote - ELSIF (directions[idir, j].lastnote > 0) & (directions[idir, j].lastnote < maxnote0[part, staff, measure]) THEN - INC( directions[idir, j].lastnote ); lastnote := directions[idir, j].lastnote - ELSIF (directions[idir, j].lastnote = 0) & (directions[idir, j].defaultx > 0) THEN - (* Out.Ln(); Out.String( "Direction default-x: " ); Out.Int( directions[idir, j].defaultx, 5 ); *) - note := minnote0[part, staff, measure]; noteto := maxnote0[part, staff, measure]; - (* Out.String( "note : " ); Out.Int( note, 5 ); Out.String( "noteto : " ); Out.Int( noteto, 5 ); *) - count := noteto - note + 1; (* Out.String( "count : " ); Out.Int( count, 5 ); *) - - WHILE note <= noteto DO - posnote[note - minnote0[part, staff, measure]] := notes[ps, 0, measure, note].defaultx; - INC( note ); - END; - lastnote := b.MinDist( directions[idir, j].defaultx, posnote, SHORT( count ) ) + 1; - (* Out.String( "lastnote : " ); Out.Int( lastnote, 5 ); *) - - END; - (* IF (notes[ps, 0, measure, lastnote].rest = "r") THEN (* avoid dynamics on rests. *) - REPEAT INC( lastnote ) UNTIL notes[ps, 0, measure, lastnote].rest # "r"; - END; *) - IF notes[ps, 0, measure, lastnote] # NIL THEN - Strings.Append( notes[ps, 0, measure, lastnote].righttext, directions[idir, j].pmxdirection ); - (* Out.Ln(); Out.String("DistrDirections , lastnote, righttext :"); - Out.Int(measure,5);Out.Int(lastnote,5); Out.String(notes[ps, 0, measure, lastnote].righttext); *) - END; - - lastdirtype := "d"; - | "p": - INC( lastnote ); - IF lastnote < firstnote THEN lastnote := firstnote END; - Strings.Append( notes[ps, 0, measure, lastnote].lefttext, directions[idir, j].pmxdirection ); - lastdirtype := "p"; - | "s": - IF lastnote < firstnote THEN lastnote := firstnote END; - Strings.Append( notes[ps, 0, measure, lastnote].righttext, directions[idir, j].pmxdirection ); - lastdirtype := "s"; - - - | "c": - IF lastnote < firstnote THEN lastnote := firstnote END; - Strings.Append( notes[ps, 0, measure, lastnote].righttext, directions[idir, j].pmxdirection ); - lastdirtype := "c"; - - - ELSE Out.Ln(); Out.String( "DistributeDirections : dirtype unknown." ); - END; - (* Out.Ln(); Out.String(" ps,measure,lastnote ");Out.Int(ps,5); Out.Int(measure,5); Out.Int(lastnote,5); Out.Char("|");Out.String(directions[idir,j].pmxdirection); - - *) - lastj := j; INC( j ); - END; - - lastidir := idir; INC( idir ); - END; - - END DistributeDirections; - - - PROCEDURE PMXDuration( tuplettype,tremolotype : ARRAY OF CHAR; div, xmldur: INTEGER; actual, normal: INTEGER; - VAR pmxdur: ARRAY OF CHAR; istuplet: BOOLEAN; type: ARRAY OF CHAR ); - (* Calculates the pmx-duration of a note (0,2,4,8,1,3,6) or rest from the XML-duration. Takes into account one dot and two dots *) - VAR double: CHAR; tupletdur,noteduration, i : INTEGER; - - - BEGIN - -IF ( istuplet & (tremolotype = "") ) THEN (* 1 *) - double := 0X; - noteduration := xmldur; - - tupletdur := Complete.tupletduration(div,type,normal); (* total duration of tuplet in terms of xml-duration *) - IF tuplettype = "start" THEN (* tuplets *) (* 2 *) - Complete.Dur2PMX(div,tupletdur,pmxdur ); - - ELSE - i := 0; WHILE i < 16 DO pmxdur[i] := 0X; INC(i) END; - END; (* 2 *) - IF ABS(actual * noteduration - tupletdur) > 5 THEN (* 3 *) - - IF ABS(noteduration*actual - 2 * tupletdur) < 5 THEN double := "D" END; (* Das ist Swing *) - - IF ABS (noteduration*actual * 2 - 3 * tupletdur) < 5 THEN double := "d" END; (* Das ist Punktierung *) - - Strings.AppendCh( pmxdur, double ); - - END; (* 3 *) -ELSIF istuplet & ( tremolotype ="start" ) THEN (* binary tremolo *) (* 1a *) - - tupletdur := Complete.tupletduration(div,type,normal); - Complete.Dur2PMX(div,tupletdur,pmxdur ); - - ELSIF ( tremolotype = "stop" ) THEN (* 1b *) - i := 0; WHILE i < 16 DO pmxdur[i] := 0X; INC(i) END; - -ELSE (* normal notes *) - Complete.Dur2PMX(div,xmldur,pmxdur ); - - -END; - -END PMXDuration; - - - PROCEDURE DelTag*; - VAR nlast, n, m: b.Tag; - BEGIN - nlast := NIL; - n := b.q.first; - WHILE n.next # NIL DO - IF (n.next.tagname = notetag) & (n.next.probj = "n") THEN - (* OutTag(n); OutTag(n.next); *) - (* nlast := n; *) (* n.next ist Note *) - m := n.next; - REPEAT m := m.next - UNTIL m.tagname = eonotetag; - (* OutTag( m ); *) - nlast.next := m.next; - - IF nlast.next.tagname ="<backup>" THEN nlast.next := nlast.next.next.next END; - (* eliminate backup *) - - (* Out.Ln(); Out.String(" nlast.nr und m.next.nr : "); - Out.Int(nlast.nr,5); Out.Char("|");Out.Int(m.next.nr,5); *) - n := m; - ELSE - n := n.next; nlast := n; - - (* Out.Ln(); Out.String("ELSE n, n.next, nlast : ");Out.Int(n.nr,5); Out.Int(n.next.nr,5); Out.Int(nlast.nr,5); *) - END; - - END; - (* n := q.first; REPEAT n:= n.next UNTIL n.nr = 20530 ; WHILE i < 30 DO OutTag (n); n:= n.next; INC(i) END;*) - END DelTag; - - - - - PROCEDURE WriteNote2PMX( VAR W: Files.Rider; VAR Note: NoteDesc; - ps, voice, voicefrom, measure, note: LONGINT; VAR Dtext, Rtext: ARRAY OF CHAR; - VAR istuplet: BOOLEAN ); - (* Writes the data for one note or rest to Files.Rider "W"; called by PROC. W ritePMX; *) - VAR pmxdur: ARRAY 16 OF CHAR; sactual : ARRAY 4 OF CHAR; - pmxnote: ARRAY 64 OF CHAR; blindrest : ARRAY 32 OF CHAR; - tremolo: ARRAY 32 OF CHAR; - octave: CHAR; stemchar: CHAR; maxnotelastmeasure : LONGINT; - - BEGIN - - - IF ( Note.grace # -1 ) THEN (* avoid chords as grace notes *) - -(* IF (Wpos := Files.Pos(W); *) - (* remove duplicate grace notes *) -(* Out.Ln(); Out.Int(ps,5); Out.Int(voice,5); Out.Int(measure,5); Out.Int(note,5); Out.Int(Note.grace,5); *) - (*IF Note.grace > 1 THEN - Out.Ln(); Out.String("remove duplicates");Out.Int(Note.grace,5); - - IF (Note.pmxnote # 0X) THEN Out.String(Note.pmxnote); END; - b.loesch ( Note.pmxnote) ; - Out.Ln(); IF (Note.pmxgrace # 0X) THEN Out.String(Note.pmxgrace);END; - b.loesch ( Note.pmxgrace) ; - END; *) - - - part := partstaff[ps, 0]; staff := partstaff[ps, 1]; pmxnote[0] := BLANK; pmxnote[1] := 0X; - COPY( Note.lefttext, Dtext ); (* 07.04.2017 *) - - IF (Note.clefchanged # 0X) THEN Files.Write(W,BLANK); Files.Write(W,"C"); Files.Write(W,Note.clefchanged); Files.Write(W,BLANK); END; - IF (Dtext[0] # 0X) THEN WriteString( W, Dtext ); END; - IF (Note.rbleft[0] # 0X) THEN WriteString( W, Note.rbleft ); END; - - IF (Note.pitchstep # 0X) THEN - (* Branch for normal notes, tuplet notes and grace notes , as opposed to rests*) - (* 1 *) - INC( count ); - - istuplet := Note.actual # 0; - - IF Note.grace = 0 THEN (* d.h. es ist keine Gracenote! *) - - PMXDuration( Note.tuplet, Note.tremolotype, attributes[part].divisions, - Note.duration, Note.actual, Note.normal, pmxdur, istuplet, Note.type ); - END; - (* delete slur before gracenote *) - IF (7 IN outputset) & (Note.grace = 0) OR ~(7 IN outputset) (* option control via outputset 24.04.2017*) - THEN (* Aenderung 18.04.2017*) - IF (Note.slur[0,1] = "(") THEN (* 3*) - Strings.Append( pmxnote, Note.slur [0]); - END; - - - IF (Note.slur[1,1] ="(") THEN - Strings.Append(pmxnote,Note.slur[1]); END; - - END; (* 3*) - - IF (Note.grace = 1) THEN (* ist erste einer Folge von grace notes *) - - Strings.Append( pmxnote, Note.pmxgrace ); - (* Out.Ln(); Out.String( " $$$$pmxgrace " ); Out.String( pmxnote ); *) - - END; (* 4*) - - IF (Note.tied[0, 1] = "{") THEN (* 5*) - - Strings.Append( pmxnote, Note.tied[0] ) - ELSIF (Note.tied[1, 1] = "{") THEN Strings.Append( pmxnote, Note.tied[1] ) - - END; (* 5*) - - (* IF ~istuplet & (Note.beam[1] = "[") & (Note.grace = 0) THEN *) (* 6 alter code 14.01.2017 *) - IF ( ~istuplet OR ( istuplet & ( Note.tuplet = "start") ) ) - - & (Note.beam[1] = "[") & (Note.grace = 0) & (Note.tremolotype # "start") - (* & ( ~beamopen[ps,voice] ) (*10. 05. 2017 *) - & ????????????? *) - THEN - - Strings.Append( pmxnote, Note.beam ); - beamopen[ps,voice] := TRUE; (* 10.5.2017 *) - - END; (* 6*) - IF Note.trembeam > 0 THEN - - b.pmxTremolo( Note.pitchstep, Note.pitchoctave, Note.stem, Note.clef, Note.trembeam, pmxdur[0], - tremolo ); - - Strings.Append( pmxnote, tremolo ); - - Out.Ln(); Out.String( "tremolo&&&&" ); Out.Int( ps, 5 ); - Out.Int( measure, 5 ); Out.String( tremolo ); - - END; - - Strings.AppendCh( pmxnote, Note.chord ); - IF Note.grace = 0 THEN (* attention: suppress duplicate Grace notes *) (* 7*) - (* also normale Note "0" 18.11.2020*) - - - - Strings.AppendCh( pmxnote, Note.pitchstep ); - END; (* 7*) - - IF (Note.chord # "z") THEN Strings.Append( pmxnote, pmxdur ); END; (* 8*) - - octave := CHR( Note.pitchoctave + 48 ); - IF Note.grace = 0 THEN Strings.AppendCh( pmxnote, octave ); (* also normale Note "0" 18.11.2020*) - -(* IF Note.grace # 1 THEN Strings.AppendCh( pmxnote, octave ); (* also normale Note *) *) - Strings.Append( pmxnote, Note.accidental ); - (* Out.Ln(); Out.String("accid in WriteNote2PMX"); Out.Int(measure,5);Out.String(Note.accidental); *) - END; (* Dont forget accidentals for gracenotes *) (* 9*) - (* test for basenote , find series of chord notes - IF Note.base # 0 THEN noteno := Note.base; - Out.Ln(); Out.String("test for abse of chord ");WHILE notes[ps,voice,measure,noteno].base = Note.base DO - Out.Ln(); Out.Int(ps,5); Out.Int(voice,2); Out.Int(measure,5); Out.Int(noteno,5); - Out.Int(notes[ps,voice,measure,noteno].base,5);INC(noteno); END; END; *) - - IF (Note.tuplet = "start") & (Note.actual # 0) - THEN (* 10*) - - Strings.AppendCh( pmxnote, "x" ); Strings.IntToStr(Note.actual,sactual); - Strings.Append( pmxnote, sactual ); - END; (* 10*) - (* binary tremolo *) - IF (Note.tremolotype = "start") & (Note.actual # 0) (* first note of binary tremolo *) - THEN (* 18*) - - Strings.AppendCh( pmxnote, "x" ); - Strings.AppendCh(pmxnote,"T"); - Strings.IntToStr(Note.maxbeam,sactual); - Strings.Append( pmxnote, sactual ); Strings.AppendCh(pmxnote, "0"); - END; (* 18*) - - - IF (Note.chord # "z") & (Note.tuplet # "start") & (Note.grace = 0) & ( Note.tremolotype # "start" ) (* 11*) - THEN - (* no stem direction specified eventuell switch einbauen ! *) - stemchar := Note.stem; - IF stemchar = "d" THEN stemchar := "l" END; - Strings.AppendCh( pmxnote, stemchar ); - END; (* 11*) - (* IF (Note.pmxdyn[0] # 0X) THEN - WriteString( W, Note.pmxdyn ); - END; *) - (* Suppress fermata in tuplet *) - IF ( Note.actual = 0 ) THEN Strings.AppendCh( pmxnote, BLANK ); Strings.Append( pmxnote, Note.fermata ); END; - Strings.AppendCh( pmxnote, BLANK ); Strings.Append( pmxnote, Note.staccato ); - Strings.AppendCh( pmxnote, BLANK ); Strings.Append( pmxnote, Note.accent ); - Strings.AppendCh( pmxnote, BLANK ); Strings.Append( pmxnote, Note.strongaccent ); - Strings.AppendCh( pmxnote, BLANK ); Strings.Append( pmxnote, Note.trill ); - - - (* IF Note.arpeggio THEN Strings.Append( pmxnote, " ? " ); maxarp := Note.maxarp END; (* ???????? 22. Nov. 2019 *) - IF (maxarp > 0) & (Note.maxarp = maxarp) THEN Strings.Append( pmxnote, " ? " ); maxarp := 0; END; *) - - (* No closing slur at gracenote or one after gracenote *) - maxnotelastmeasure := maxnote0[part,staff,measure-1]; - IF voice = 1 THEN maxnotelastmeasure := maxnote1[part,staff,measure-1]; END; -IF (7 IN outputset) & ( ( note = 1 ) & (Note.grace = 0) & ( notes[ps,voice,measure,maxnotelastmeasure].grace= 0 ) - OR ( note >1 ) &( Note.grace = 0) & (notes[ps,voice,measure,note - 1].grace = 0 ) ) (* Aenderung wg. Don 17022017 *) - OR ~(7 IN outputset) - THEN (* end of slur directly after gracenote not allowed *) (* Blinder Versuch 7 statt 5 *) - - IF (Note.slur[0,1] = ")") THEN (* 13*) - IF Note.grace = 0 THEN - Strings.Append( pmxnote, Note.slur[0] ); END; END; - IF (Note.slur[1, 1] = ")") THEN - IF Note.grace = 0 THEN - - Strings.Append( pmxnote, Note.slur[1] ); END; END; - - END; (* 13*) - - IF (Note.tied[0, 1] = "}") (* 14*) - THEN - Strings.Append( pmxnote, Note.tied[0] ); - ELSIF (Note.tied[1, 1] = "}") THEN Strings.Append( pmxnote, Note.tied[1] ); - END; (* 14*) - - - (* IF ~istuplet & (Note.beam[1] = "]") & (Note.grace = 0) THEN (* 15*) backchanged 16. 4. 2017 changed 14.01.2017 *) - IF ( ~istuplet OR ( istuplet & ( Note.tuplet = "stop" ) ) ) - & (Note.beam[1] = "]") & (Note.grace = 0 ) & (Note.tremolotype # "stop") - THEN (* VErsion 12 *) - IF beamopen[ps,voice] THEN - Strings.Append( pmxnote, Note.beam ); - beamopen[ps,voice] := FALSE; - END; - END; (* 15*) - - IF ~istuplet & (Note.closebeam[1] = "]") & (Note.grace = 0) THEN (* 15a closing for single note beam *) - IF beamopen[ps,voice] THEN - Strings.Append( pmxnote, Note.closebeam ); - beamopen[ps,voice] := FALSE; - END; - - - - - END; (* 15a*) - - - - (************************ clef changed *******************) - - (* IF (Note.clefchanged # 0X) THEN (* 16*) - (* There is a clef change after this note. *) - Out.String("Note clefchanged"); Out.Char(Note.clefchanged); - - (* INC(countclefchanges); *) - (* IF note < maxnote[part,staff,measure] THEN *) - maxinote := maxnote0[part,staff,measure]; - IF voice > voicefrom THEN maxinote := maxnote1[part, staff, measure] END; - IF note < maxinote THEN - - Strings.Append( pmxnote, " C" ); Strings.AppendCh( pmxnote, Note.clefchanged ); - Strings.AppendCh( pmxnote, BLANK ); - - Out.Ln(); Out.Int(ps,5); Out.Int(voice,5); Out.Int(measure,5); Out.Int(note,5); - Out.String( "cleffx" ); Out.Char( Note.clefchanged ); Out.Char("|"); Out.Char( Note.clef ); - ELSE - Out.String( "clef change after last note "); Out.Int(maxinote,5); - (* activated 14. Maerz 2018 , verschiebt clefchange vom Ende des Taktes vor die erste Note dwes folgenden Taktes*) - - measures[measure + 1].clefchange[ps] := Note.clefchanged; - - - END; - (* NoteOut(Note); *) - END; (* 16*) *) - -(* Out.Ln(); Out.String("pmxnote vorher");Out.String(Note.pmxnote); *) - - COPY( pmxnote, Note.pmxnote ); WriteString( W, Note.pmxnote ); - -(* IF Note.grace >1 THEN b.loesch(Note.pmxnote); - b.loesch(Note.pmxgrace) END; Out.Ln(); Out.String(" Note.pmxnote" ); Out.Int(measure,5); Out.String( Note.pmxnote ); - Out.String( Note.pmxgrace ); Out.Char("|"); Out.Int (Note.grace,5); *) - - - (* Out.Int( Note.staff, 5 ); Out.Char( "|" ); - Out.Int( Note.voice, 5 ); *) - - ELSIF (Note.rest = "r") THEN (* Branch for Rests *) (* 1*) - - INC( count ); (* this note is a rest! *) - - istuplet := Note.actual # 0; - - - PMXDuration( Note.tuplet, Note.tremolotype, attributes[part].divisions, Note.duration, Note.actual, Note.normal, - pmxdur, istuplet, Note.type ); - pmxnote[0] := 20X; - IF ( Note.blind = "b" ) THEN - - Complete.CalcForward(Note.duration,attributes[part].divisions,blindrest); - - Strings.Append(pmxnote,blindrest); - ELSE - - IF (Note.duration = attributes[part].duration) THEN (* rest of type "rp" *) (* 17*) - Strings.Append( pmxnote, "rp" ); - ELSE (* 17*) - Strings.AppendCh( pmxnote, Note.rest ); Strings.Append( pmxnote, pmxdur ); - IF (Note.tuplet = "start") & (Note.actual # 0) (* leading note of tuplet *) - THEN (* 18*) - - Strings.AppendCh( pmxnote, "x" ); Strings.IntToStr(Note.actual,sactual); - Strings.Append( pmxnote, sactual ); - END; (* 18*) - - - END; (* 17 *) - (************************************************ first try for slur ending on rest ****************) - IF (Note.slur[0,1] = ")") - THEN (* 13*) - Strings.Append( pmxnote, Note.slur[0] ); - END; - IF (Note.slur[1, 1] = ")") - THEN - Strings.Append( pmxnote, Note.slur[1] ); - END; - - (* END; 13*) - - -END; - - - Strings.AppendCh( pmxnote, BLANK ); - (* IF (Note.clefchanged # 0X) THEN (* 16*) (* clef change on the fly, activated 14. Maerz 2018 *) - (* IF note < maxnote[part,staff,measure] THEN *) - Strings.Append( pmxnote, " C" ); Strings.AppendCh( pmxnote, Note.clefchanged ); - Strings.AppendCh( pmxnote, BLANK ); - Out.Ln(); Out.Int(ps,5); Out.Int(voice,5); Out.Int(measure,5); Out.Int(note,5); - Out.String( "cleffy" ); Out.Char( Note.clefchanged ); Out.Char( Note.clef ); - (* NoteOut(Note); *) - END; (* 16*) *) - - COPY( pmxnote, Note.pmxnote ); WriteString( W, pmxnote ); - - END; (*1*) - (* IF (Note.direction > 0) THEN (* 19*) - - (* OutDir( Note.direction ); *) - Files.Write( W, Note.direction ); Files.Write( W, CR ); Files.Write( W, NL ); - END; (* 19*) *) - (* directions within measures are written *) - COPY( notes[ps, voice, measure, note].righttext, Rtext ); - (* Out.Ln(); Out.String("WriteNote2PMX : "); Out.Int(ps,5); Out.Int(voice,5); Out.Int(measure,5); Out.Int(note,5); Out.String (Rtext); - - Out.Int(notes[ps, voice, measure, note].grace,5); *) - - IF (Rtext[0] # 0X) (* & ( ~written ) *) THEN WriteString( W, Rtext ); - END; - IF (Note.rbright[0] # 0X) THEN WriteString( W, Note.rbright ); END; - (* Out.Ln();Out.String("measure,ps,voice,note"); - Out.Int(measure,5); Out.Int(ps,5); Out.Int(voice,5); Out.Int(note,5); Out.Int(Note.voice,5);Out.String(pmxnote); *) - (* "maxnote" is the last note in part/staff/measure, minnote is the first note in part/staff/measure *) - (* IF ( note = maxnote[part, staff, measure] )*) (* Aenderung 22.12.2015: introduce voice dependence *) - (* "maxnote" is the last note in part/staff/measure, minnote is the first note in part/staff/measure *) - IF (note = maxnote[part, staff, measure]) OR ((note = maxnote0[part, staff, measure]) & (voice = 0)) OR - ((note = maxnote1[part, staff, measure]) & (voice = 1)) - - THEN - (* WriteString( W, " | " ); not needed in PMX *) - IF (ps = nostaves - 1) & (voice = voicefrom) THEN - IF (measures[measure].barstyle # 0X) THEN WriteString( W, measures[measure].barstyle ) END; - IF (measures[measure].repeat = " Rr ") THEN - Files.Write( W, CR ); Files.Write( W, NL ); WriteString( W, measures[measure].repeat ); - END; - END; - - Files.Write(W,BLANK); Files.Write( W, "/" ); (* Print "/" for end of single voice . *) - - END; - IF Note.tuplet = "stop" THEN istuplet := FALSE END; - ELSE - Out.Ln(); Out.String("grace = -1"); Out.Int(ps,5); Out.Int(measure,5); Out.Int(note,5);END; - END WriteNote2PMX; - - - - - - PROCEDURE WritePMX ( VAR W: Files.Rider ); - (* Creates and stores the notes part of the PMX file (starting with "% Bar 1"). after the Control Data *) - VAR voice, staff, voicefrom, voiceto, nnotes, notefrom, noteto : LONGINT; concertkey : ARRAY 10 OF CHAR; - Dtext, Rtext: ARRAY 128 OF CHAR; - keychange, dummy: ARRAY 32 OF CHAR; keychanged : BOOLEAN; - blindmeterchange: ARRAY 16 OF CHAR; - istuplet: BOOLEAN; minmeasure: LONGINT; ipickup: INTEGER; - (* decides whether direction is written before or after the note. *) - restbefore, restafter: ARRAY 16 OF CHAR; - - BEGIN - ipickup := 0; keychanged := FALSE; - IF attributes[1].pickup > 0 THEN ipickup := 1; END; - (* Write transposition string s *) - (* part := 1; - WHILE part <= maxpart DO - IF attributes[part].diatonic # 0 THEN WriteString( W, attributes[part].kstring ); - END; - Files.Write( W, CR ); Files.Write( W, NL ); INC( part ); Out.Ln(); Out.String("diatonic"); - END; *) - Files.Write( W, CR ); Files.Write( W, NL ); - - measure := 1; note := 1; - - IF (attributes[1].pickup > 0) THEN minmeasure := 1 - ELSE minmeasure := 0 - END; (* do not extend 1st measure in case of pickup. *) - IF ( uptomeasure > 0 ) & ( uptomeasure <= maxmeasure ) THEN maxmeasure := uptomeasure; END; - WHILE measure <= maxmeasure DO - (* Out.Ln(); Out.String("measure ="); Out.Int(measure,5); *) - - - - Complete.erasetime( nostaves, voicetime ); ps := nostaves - 1; - IF maxpart > 1 THEN - - - IF ( measure = 1 ) OR ( ( measure > 1 ) & ( measures[measure].fifth # measures[measure-1].fifth )) - THEN - - keychanged := TRUE; - ELSIF measure > 1 THEN i := 1 ; - REPEAT - keychanged := (measures[measure].keys[i] # measures[measure].keys[maxpart] ) & (* Aenderung2.2.2017 *) - (measures[measure].keys[i] # measures[measure - 1].keys[i]); - INC(i) ; - UNTIL ( i = maxpart ) OR keychanged ; - END; - (* END; *) - IF (keychanged & ~ pmxcontrol.equalkeys) THEN - i := 1; WHILE i <=maxpart DO b.mkeys[i] := measures[measure].keys[i]; INC(i) END; - b.testmakekey(maxpart,measure,keytotal); - COPY("K+0",concertkey); - - IF measures[measure].keys[maxpart] >= 0 THEN Strings.AppendCh(concertkey,"+"); END; - Strings.IntToStr(measures[measure].keys[maxpart],dummy); Strings.Append(concertkey,dummy); - IF measure >= 1 THEN - WriteString( W, concertkey ); Files.Write( W, CR ); - Files.Write( W, NL ); END; - - - WriteString( W, keytotal ); Files.Write( W, CR ); - Files.Write( W, NL ); END; - - (* Out.Ln(); Out.String("concertkey : "); Out.String(concertkey); - Out.Ln(); Out.String("keytotal : "); Out.String(keytotal); *) - END; - - WHILE (ps >= 0) DO - part := partstaff[ps, 0]; staff := partstaff[ps, 1]; - - - - - (* neuer Code: shift to voice := 0,1 *) - voiceto := voicelimm[ps, measure] - 1; voicefrom := 0; voice := voicefrom; - (* IF voiceto < 0 THEN voiceto := 0; END; *) - - (* Out.Ln(); Out.String("measure, part, staff, voicefrom, voiceto:"); - - Out.Int(measure,5); Out.Int(part,5); Out.Int(staff,5); - - Out.Int(voicefrom,5); Out.Int(voiceto,5); *) - - - (* IF voiceto > 1 THEN voiceto := 1 END; (* this line only for testing BWV0826; to be removed. *) *) - WHILE voice <= voiceto DO - nnotes := 0; WriteString( W, "% " ); Files.Write( W, "(" ); WriteLInt( W, part ); - Files.Write( W, "|" ); WriteLInt( W, staff ); Files.Write( W, "|" ); WriteLInt( W, vmap[ps, measure, voice] ); - Files.Write( W, ")" ); WriteLInt( W, measure - ipickup ); Files.Write( W, CR ); - Files.Write( W, NL ); - - - - - b.loesch( Dtext ); b.loesch( Rtext ); - (********************** Meter Change *******************) - IF (measure > 1) THEN - IF (measures[measure].beats # measures[measure - 1].beats) OR - (measures[measure].beattype # measures[measure - 1].beattype) THEN - IF measures[measure].beattype >0 THEN - b.NewBeat( measures[measure].beats, measures[measure].beattype, - measures[measure].meterchange, FALSE ); - (* 20-10-2020 Lilypond *) - attributes[part].duration := - measures[measure].beats*4* attributes[part].divisions DIV measures[measure].beattype; - ELSE - Out.Ln(); - Out.String("PROC. WritePMX: measure = "); - Out.Int(measure,5); - END; - - (* measures[measure].divisions[part] *) - measures[measure].duration[part] := attributes[part].duration ; - IF (ps = nostaves - 1) & (voice = voicefrom) THEN - Files.Write( W, CR ); Files.Write( W, NL ); WriteString( W, measures[measure].meterchange ); - Files.Write( W, CR ); Files.Write( W, NL ); - END - END; - END; - (* blind meter change in case of Pickup. *) - IF (attributes[1].pickup > 0) & (measure = 2) & (ps = nostaves - 1) & (voice = voicefrom) THEN (* Change 09.05.2020 *) - b.NewBeat( attributes[1].beats, attributes[1].beattype, blindmeterchange, TRUE ); - - WriteString( W, blindmeterchange ); Files.Write( W, CR ); Files.Write( W, NL ); - END; - - - (********************** key change ***********************) - IF pmxcontrol.equalkeys &(ps = nostaves - 1) & (measure > 1) & (voice = voicefrom) & (* change 03052018 *) - (measures[measure].fifth # measures[measure - 1].fifth) THEN - COPY( "K+0", keychange ); - IF ( measures[measure].fifth >= 0 ) THEN Strings.Append(keychange,"+"); END; - Strings.IntToStr( measures[measure].fifth, dummy ); - Strings.Append( keychange, dummy ); WriteString( W, keychange ); Files.Write( W, CR ); - Files.Write( W, NL ); - END; - - IF (measures[measure].ending # 0X) & (ps = nostaves - 1) THEN - WriteString( W, measures[measure].ending ); - END; - - IF (measures[measure].repeat = " Rl ") & (ps = nostaves - 1) & (voice = voicefrom) THEN - WriteString( W, measures[measure].repeat ); - END; - notefrom := minnote0[part, staff, measure]; noteto := maxnote0[part, staff, measure]; - (* IF measure = 25 THEN Out.Ln(); Out.String("voice = 0"); - Out.Ln(); Out.String("notefrom(to : "); Out.Int(notefrom,5); Out.Int(noteto,5); END; *) - - IF (voice = 1) THEN - notefrom := minnote1[part, staff, measure]; - noteto := maxnote1[part, staff, measure]; (* changed from note := 1; 22.12.2015 *) - (* IF measure = 25 THEN Out.Ln(); Out.String("voice = 1"); - Out.Ln(); Out.String("notefrom(to : "); Out.Int(notefrom,5); Out.Int(noteto,5); END; *) - END; - note := notefrom; - - IF (measure > minmeasure) THEN FillRests( notefrom, noteto, measure, ps, voice ); - END; - - (* do not extend 1st measure in case of pickup. *) - - WHILE note <= noteto DO (* 1 *) - IF (notes[ps, voice, measure, note] # NIL) & - (Strings.IsAlpha( notes[ps, voice, measure, note].pitchstep ) OR (notes[ps, voice, measure, note].rest = "r")) - (* note OR rest *) - - - (* remove print-object="no". 26.07.2019*) - THEN (* CHANGE 11.Juli 2019: remove print-object = "no" notes *) - IF ~ (10 IN outputset) OR ( notes[ps, voice, measure, note].probj = TRUE ) THEN - (* Option "r" : remove notes with print_obj = "no" 04.05.2020 *) - - - WriteNote2PMX( W, notes[ps, voice, measure, note]^, ps, voice, voicefrom, measure, note, Dtext, - Rtext, istuplet ); - b.loesch( restbefore ); b.loesch( restafter ); - - INC( nnotes ); - - (* b.loesch(Rtext); b.loesch(Dtext); *) - END; - - END; - INC( note ); (* IF voice = 1 THEN Out.Ln(); Out.String("Count notes of 2nd voice. ");Out.Int(note,5); END; *) - END; (* 1 *) (* Loop over notes *) - - (* Measure Properties go here *) ; - (* WriteString(W," | /"); *) - IF ( voicelimm[ps,measure] = 2 ) & (voice = 0) & (nnotes > 0) - - & ( ((notes[ps,0,measure,minnote1[part,staff,measure]] # NIL) - & (notes[ps, 0, measure, minnote1[part,staff,measure]].probj = TRUE)) - OR ~ ( 10 IN outputset ) ) - (* second slash removed because second voice eliminated. Change 04.05.2020 *) - THEN - - Files.Write( W, "/" ); END; (* Print second "/" for first voice of two voices *) - Files.Write( W, CR ); Files.Write( W, NL ); - - INC( voice ); - - END; (* Loop over voices *) - - DEC( ps ); - END; - INC( measure ); - END; (* Out.Ln(); Out.String(" Divisions : "); - i := 1; WHILE i <= maxpart DO Out.Ln(); Out.Int(i,5); Out.Int(attributes[i].divisions,5); INC(i);END; *) - END WritePMX; - -(* PROCEDURE ListMeasures*; - VAR i,j : LONGINT; - BEGIN - Out.Ln(); Out.String("ListMeasures"); - i := 1; - WHILE i <= maxmeasure DO - - Out.Ln(); Out.Int(i, 5); Out.Int( measures[i].beats, 5); Out.Int(measures[i].beattype,5); Out.Int ( measures[i].fifth , 5); - j := 1; - - WHILE j<=maxpart DO Out.Int(measures[i].keys[j],5); INC(j); END; INC(i); END; - - - (* j := 1; WHILE j<maxpart DO Out.Int(measures[i].duration[j],5); INC(j); END; INC(i); END; *) - - - - END ListMeasures; *) - - - - - - - PROCEDURE repeat2PMX( n: b.Tag; VAR pmxrepeat: ARRAY OF CHAR ); - (* translates a left or right repeat from XML to PMX *) - VAR c: CHAR; - direction: ARRAY 32 OF CHAR; - BEGIN - b.loesch( pmxrepeat ); COPY( BLANK, pmxrepeat ); b.FindAtt( n, "direction", direction ); - IF (direction = "backward") THEN Strings.Append( pmxrepeat, "Rr" ); - ELSIF (direction = "forward") THEN Strings.Append( pmxrepeat, "Rl" ); - END; - - Strings.AppendCh( pmxrepeat, BLANK ); c := 0X; Strings.AppendCh( pmxrepeat, c ); - - END repeat2PMX; - - PROCEDURE ending2PMX( n: b.Tag; VAR pmxending: ARRAY OF CHAR; VAR type: ARRAY OF CHAR ); - (* translates a Volta from XML to PMX, possibly not general enough *) - VAR c: CHAR; - number: ARRAY 32 OF CHAR; - BEGIN - COPY( BLANK, pmxending ); b.FindAtt( n, "number", number ); b.FindAtt( n, "type", type ); - IF (type = "start") THEN - Strings.AppendCh( pmxending, "V" ); Strings.Append( pmxending, number ); - IF (number = "2") THEN Strings.AppendCh( pmxending, "b" ); END; - END; - IF (type = "discontinue") THEN COPY ("Vx",pmxending); END; - - Strings.AppendCh( pmxending, BLANK ); c := 0X; Strings.AppendCh( pmxending, c ); - - END ending2PMX; - - PROCEDURE beam2PMX( n: b.Tag; VAR pmxbeam: ARRAY OF CHAR; stem: CHAR; staff: LONGINT ); - (* Translates a beginning or ending or continued beam from XML to PMX. staff is the staff of the beam element *) - VAR c, j, stemj: CHAR; m: b.Tag; - type, number: ARRAY 32 OF CHAR; - BEGIN - b.loesch( pmxbeam ); COPY( n.between, type ); b.FindAtt( n, "number", number ); b.loesch( closebeam ); j := 0X; - IF (number = "1") THEN (* 1*) - COPY( BLANK, pmxbeam ); - IF (type = "begin") THEN c := "["; - ELSIF (type = "end") THEN - IF (lasttype = "continue") & (laststaff # staff) THEN - c := "["; j := "j"; COPY( " ] ", closebeam ); - ELSE c := "]"; END; - ELSIF (type = "continue") THEN - IF (lasttype = "continue") & (laststaff # staff) THEN - c := "["; j := "j"; - ELSE - - b.findnextnote( n, m ); (* Out.Char("|"); Out.Int(n.nr,5); Out.Int(staff,5); Out.Char("|");Out.Int(m.nr,5);Out.Int(m.staff,5); *) - (* Out.Ln(); Out.String(" beam : continue "); *) - IF (m.staff # staff) THEN j := "j"; c := "]" ELSE c := "?" END; - END; - ELSE c := "?" - END; - Strings.AppendCh( pmxbeam, c ); - IF (j = "j") (* neuer Code fuer joined beams *) - THEN - Strings.AppendCh( pmxbeam, j ); - IF c = "[" THEN Strings.AppendCh( pmxbeam, "f" ); (* flip l/u *) - - stemj := "u"; IF stem = "u" THEN stemj := "l"; END; - Strings.AppendCh( pmxbeam, stemj ); Strings.AppendCh( pmxbeam, BLANK ); END; - (* Out.String("pmxbeam"); Out.String(pmxbeam); Out.Char("|"); *) - ELSE - IF (c = "[") THEN - IF (stem = "d") THEN Strings.AppendCh( pmxbeam, "l" ); - ELSIF (stem = "u") THEN Strings.AppendCh( pmxbeam, "u" ); - END; - (* IF (stem = "u") THEN Strings.Append(pmxbeam,"+2"); - ELSIF (stem = "d") THEN Strings.Append(pmxbeam,"-2"); END; *) - Strings.AppendCh( pmxbeam, BLANK ); - END; - END; - END; - IF (type = "continue") & (j # "j") OR (number > "1") THEN b.loesch( pmxbeam ); END; - COPY( type, lasttype ); laststaff := staff; - END beam2PMX; - -(* PROCEDURE tied2PMX( n: b.Tag; type: ARRAY OF CHAR; VAR pmxtied: ARRAY OF CHAR; voice: LONGINT); - (* Translates a beginning or ending tie from XML to PMX. - orientation = "d" => note with stem down yields tie with orientation "u". - orientation = "u" => note with stem up yields tie with orientation "l". *) - VAR c: CHAR; - number: ARRAY 32 OF CHAR; orient : ARRAY 10 OF CHAR; orientation : CHAR; - nt: Fifo.Node; - - BEGIN - b.loesch( pmxtied ); b.FindAtt( n, "number", number ); - b.FindAtt( n, "orientation", orient ); - IF orient = "over" THEN orientation := "u"; (* IF orient = "" THEN follow stem direction *) - ELSIF orient = "under" THEN orientation := "l"; - ELSE orientation := " "; - END; - - (* Out.Char("|"); Out.String("tied : "); Out.Char("|");Out.String(type);Out.Char("|"); - Out.String(number);Out.Char("|");Out.Char(orientation); *) - COPY( BLANK, pmxtied ); - IF (type = "start") THEN - c := "{"; - Strings.AppendCh( pmxtied, c ); - NEW( nt ); nt.key := Fifo.smallfree( b.tieunusdnum[ps, voice] ); - EXCL( b.tieunusdnum[ps, voice], nt.key ); - Fifo.Enqueue( b.tieq[ps, voice], nt ); - Strings.IntToStr( nt.key, number ); - Strings.Append( pmxtied, number ); - Strings.AppendCh( pmxtied, orientation ); - ELSIF (type = "stop") THEN c := "}"; Strings.AppendCh( pmxtied, c ); - - nt := Fifo.DequeuedNode( b.tieq[ps, voice] ); - IF nt # NIL THEN INCL( b.tieunusdnum[ps, voice], nt.key ); (* avoid nt undefined *) - Strings.IntToStr( nt.key, number ); Strings.Append( pmxtied, number ); END; - ELSE Out.String( "wrong type of tie " ); - END; - Strings.AppendCh( pmxtied, BLANK ); - END tied2PMX; *) - -(* PROCEDURE slur2PMX( n: b.Tag; VAR pmxslur: ARRAY OF CHAR ); - (* Translates a beginning or ending slur from XML to PMX. *) - - VAR c, cs : CHAR; - type, number, placement: ARRAY 32 OF CHAR; inumber : LONGINT; res : ARRAY 4 OF CHAR; - BEGIN - b.loesch( pmxslur ); b.FindAtt( n, "type", type ); b.FindAtt( n, "number", number ); - IF ( number # "" ) THEN - Strings.StrToInt(number, inumber); - cs := CHR(inumber + 65) - ELSE cs := "A"; - END; - b.FindAtt( n, "placement", placement ); - IF (type # "continue") THEN (* gibt es das ueberhapt? *) - - COPY( BLANK, pmxslur ); - IF (type = "start") THEN c := "("; - ELSIF (type = "stop") THEN c := ")" - END; - Strings.AppendCh( pmxslur, c ); - Strings.AppendCh( pmxslur, cs ); - (* Achtung x-option for staff crossing slur *) - IF 8 IN outputset THEN Strings.Append(pmxslur,"x"); END; - - IF (type = "start") THEN (* gibt es slurs ohne placement Angabe? *) - IF (placement = "below") THEN Strings.AppendCh( pmxslur, "l" ) - ELSIF (placement = "above") THEN Strings.AppendCh( pmxslur, "u" ); - END; - END; - Strings.AppendCh( pmxslur, BLANK ); c := 0X; Strings.AppendCh( pmxslur, c ); - - END; - (* Out.Ln(); Out.String( "slur2pmx : " ); Out.String( pmxslur ); *) - - (* Slur control according to grace property *) - - END slur2PMX; *) - - PROCEDURE grace( n: b.Tag; ps, voice, measure, note, maxgrace: LONGINT; VAR res: ARRAY OF CHAR ); - (* counts the calls in "ingrace2pmx", prerequisite n.tagname = notetag *) - - VAR nograce: LONGINT; isgrace: BOOLEAN; - slash, type, stem: ARRAY 32 OF CHAR; - snograce,str,accpmx: ARRAY 4 OF CHAR; ns : CHAR; no : LONGINT; - BEGIN - isgrace := FALSE; - b.loesch( res ); - WHILE (n.next # NIL ) & (n.tagname # eonotetag) DO (* loop over all tags of the note 1 *) - (* Out.Ln(); Out.String( n.tagname ); *) - - IF (n.tagname = gracetag) OR (n.tagname = gracetag2) THEN (* 2 *) - b.FindAtt( n, "slash", slash ); nograce := 0; isgrace := TRUE; - - (* Out.Ln(); Out.String( " ***********************grace : " ); Out.String( slash ); *) - END; - - IF (n.tagname) = steptag THEN (* 3 *) - notes[ps, voice, measure, note].pitchstep := Strings.LowerCh( n.between[0] ); (* Out.String( n.between ); *) - END; - - IF (n.tagname) = octavetag THEN (* 4 *) - notes[ps, voice, measure, note].pitchoctave := b.ExtractInt( n.between ); (* Out.String( n.between ); *) - END; - Accidentals(n,ps,voice,measure,note); - (* Out.Ln(); Out.String("note1 accidental"); Out.String(notes[ps, voice, measure, note].accidental); *) - IF (n.tagname = "<type>") THEN - COPY( n.between, type ); (* Out.String( n.between ); *) (* 6 *) - END; - - IF (n.tagname = "stem") THEN (* 7 *) - COPY( n.between, stem ); (* Out.Ln(); Out.String( n.between ); *) - END; - - - n := n.next; - END; (* 1 *) (* Daten der ersten Grace-Note *) - - - nograce := maxgrace; (* Out.Ln(); Out.String( "grace : n#gracenotes" ); Out.Int( nograce, 5 ); *) res[0] := BLANK; - - Strings.IntToStr( nograce, snograce); res[0] := "G"; res[1] := 0X; Strings.Append( res, snograce ); - Strings.AppendCh( res, "m" ); - IF (type = "eighth") THEN Strings.AppendCh( res, "1" ) - ELSIF (type = "16th") THEN Strings.AppendCh( res, "2" ) - ELSIF (type = "32nd") THEN Strings.AppendCh( res, "3" ) - END; - IF ( 7 IN outputset) THEN Strings.AppendCh( res, "s" ); END; (* slur internal to grace note, goes from first grace note to first non-grace note *) - IF (slash = "yes") THEN Strings.Append( res, "x" ); END; - IF (stem = "up") THEN Strings.AppendCh( res, "u" ) - ELSIF (stem = "down") THEN Strings.AppendCh( res, "l" ) - END; - - Strings.AppendCh( res, notes[ps, voice, measure, note].pitchstep ); - Strings.IntToStr( notes[ps, voice, measure, note].pitchoctave, str ); Strings.Append( res, str ); - Strings.Append(res,notes[ps,voice,measure,note].accidental); Strings.AppendCh( res, BLANK ); Strings.AppendCh( res, 0X ); - (* 1st gracenote and config *) - n := n.next; - (* b.OutTag(n,TRUE); *) - - WHILE (nograce >1) & isgrace DO - (* Out.Ln(); Out.Int(nograce,5); *) - Findnextgrace (n,isgrace,ns,no,accpmx); - Strings.AppendCh(res,BLANK); Strings.AppendCh(res,ns); - Strings.IntToStr( no,str); Strings.Append(res,str); IF(accpmx[0] # 0X) THEN Strings.Append(res,accpmx) END; - n := n.next; DEC(nograce); (* Out.Ln(); Out.String(res); %%%%% *) - END; - - - END grace; - PROCEDURE Findnextgrace* (VAR n : b.Tag; VAR isgrace : BOOLEAN; VAR notestep : CHAR; - VAR noteoctave : LONGINT; VAR accpmx : ARRAY OF CHAR ); - (* Neu 14.11.2020: Anbindung der weiteren grace-Noten an Hauptnote - prerequisite n ist zweite Note der Verzierung *) - - BEGIN - notestep := 0X; noteoctave := -1; accpmx[0] := 0X; isgrace := FALSE; - WHILE ( n.next # NIL ) & (n.tagname # eonotetag) DO - IF n.tagname = gracetag THEN isgrace := TRUE; END; - IF n.tagname = steptag THEN notestep := Strings.LowerCh(n.between[0]); END; - IF n.tagname = octavetag THEN noteoctave := b.ExtractInt(n.between); END; - IF n.tagname = "<accidental>" THEN - IF( n.between = "sharp") THEN COPY( "s", accpmx ); END; - IF ( n.between = "flat") THEN COPY( "f", accpmx ); END; - IF (n.between = "double-sharp") OR (n.between = "sharp-sharp") THEN COPY( "ss", accpmx ); END; - IF (n.between = "flat-flat") OR (n.between = "double-flat") THEN COPY( "ff", accpmx ); END; - IF (n.between = "natural") THEN COPY( "n", accpmx ); END; - END; - - - - n:= n.next; - END; (* WHILE *) - (* Out.Ln(); Out.String("Findnextgrace"); Out.Int(measure,5); - Out.Char(notestep); Out.Int(noteoctave,5);Out.String(accpmx); *) -END Findnextgrace; - - - - PROCEDURE OutDir( i, j: LONGINT ); - BEGIN - Out.Ln(); Out.String( " OutDir : " ); Out.Int( i, 5 ); Out.Int( j, 5 ); Out.Int( directions[i, 0].part, 5 ); - Out.Int( directions[i, 0].staff, 5 ); Out.Int( directions[i, 0].measure, 5 ); Out.Char( "|" ); - Out.Int( directions[i, 0].lastnote, 5 ); Out.Char( "|" ); Out.Int( directions[i, 0].voice, 5 ); Out.Char( "|" ); - Out.Int( directions[i, 0].note, 5 ); Out.Char( "|" ); - Out.Char( directions[i, j].dirtype ); Out.Char( "|" ); Out.Char( directions[i, j].placement ); Out.Char( "|" ); - Out.String( directions[i, j].wedgetype ); Out.Char( "|" ); Out.String( directions[i, j].dyntype ); Out.Char( "|" ); - Out.String( directions[i, j].pedaltype ); Out.Char( "|" ); Out.String( directions[i, j].text ); Out.Char( "|" ); - Out.String( directions[i, j].pmxdirection ); Out.Char( "|" ); Out.Int( directions[i, j].defaultx, 5 ); - (* IF directions[i,j].used THEN Out.String(" direction used "); ELSE Out.String(" direction not used ") END; *) - END OutDir; - - PROCEDURE NotesProp( part, staff, voice, measure: LONGINT; VAR note: LONGINT; VAR n: b.Tag ); - (* stores notes information in an array with indices [ps,voice,measure,note] for later use in the generation measure - by measure; "part" and "staff" are combined in one index "ps". *) - VAR pmxslur, pmxtied, pmxbeam, type, pmxrepeat, pmxgrace : ARRAY 32 OF CHAR; - number, ntype, mtype: ARRAY 32 OF CHAR; placement : ARRAY 32 OF CHAR; - m: b.Tag; - defaultxs: ARRAY 32 OF CHAR; (* openslur : ARRAY 1000 OF OpenSlurDesc; *) - ps, defaultx, long : LONGINT; - - BEGIN - nties := 0; ps := linstaff( nostaves, part, staff ); - NEW( notes[ps, voice, measure, note] ); - notes[ps, voice, measure, note].voicetime := n.voicetime; - notes[ps, voice, measure, note].cue := n.cue; - notes[ps, voice, measure, note].from := n.from; notes[ps, voice, measure, note].to := n.to; - (* Out.Ln(); Out.String("NotesProp voice + voice : "); - Out.Int(part,5);Out.Int(staff,5);Out.Int(measure,5);Out.Int(voice,5); Out.Int(n.voice,5); - Out.Int(note,5);Out.Int(n.from,5);Out.Int(n.to,5); Out.Int(n.voicetime,5); *) - IF voice = 0 THEN - maxnote0[part, staff, measure] := b.Max( note, maxnote0[part, staff, measure] ); - minnote0[part, staff, measure] := b.Min( note, minnote0[part, staff, measure] ); - END; - IF voice = 1 THEN - maxnote1[part, staff, measure] := b.Max( note, maxnote1[part, staff, measure] ); - minnote1[part, staff, measure] := b.Min( note, minnote1[part, staff, measure] ); - END; - IF (n.probj = "n") THEN notes[ps, voice, measure, note].probj := FALSE - ELSE notes[ps, voice, measure, note].probj :=TRUE; END; - notes[ps, voice, measure, note].clef := lastclef[ps]; - IF ( n.newclef # 0X ) THEN - notes[ps,voice, measure, note].clefchanged := n.newclef; (* 17.10.2020 new Implemtation od clef *) - (* Out.Ln(); Out.String("in NotesProp : "); Out.Char(n.newclef); *) - END; - b.FindAtt( n, "default-x", defaultxs ); Strings.StrToInt( defaultxs, defaultx ); - notes[ps, voice, measure, note].defaultx := SHORT( defaultx ); notes[ps, voice, measure, note].from := n.from; - notes[ps, voice, measure, note].to := n.to; - - (* clef change on bar change - lastnotethismeasure := maxnote0[part,staff,measure]; - IF voice = 1 THEN lastnotethismeasure := maxnote1[part,staff,measure] END; - firstnotenextmeasure := minnote0[part,staff,measure+1]; - IF voice = 1 THEN firstnotenextmeasure := minnote1[part,staff,measure+1] END; - IF ( notes[ps,voice,measure,lastnotethismeasure].clefchanged # 0X ) - & ( measure < maxmeasure )THEN - - notes[ps,voice,measure+1,firstnotenextmeasure].clefchanged := - notes[ps,voice,measure,lastnotethismeasure].clefchanged; END; - - Ende: clcef change on bar change *) - - - - - - - WHILE (n.next # NIL ) & (n.tagname # eonotetag) DO - - (* OutTag( n ); &&&&&&&&&&&&&&&&&&& Alarm arpeggio *) - (* IF (n.arpeggio > 0) THEN notes[ps, voice, measure, note].arpeggio := n.arpeggio; END; - IF (n.arpeggio = 1) THEN - b.arplen( n, maxarp ); notes[ps, voice, measure, note].maxarp := SHORT( maxarp ); Out.Ln(); - Out.String( "maxarp" ); Out.Int( maxarp, 5 ); - END; *) - IF (n.grace > 0) THEN notes[ps, voice, measure, note].grace := n.grace; - (* Out.Ln(); Out.String(" notesprop : "); Out.Int(ps,5); Out.Int(voice,5); Out.Int(measure,5); Out.Int(note,5); Out.Int(n.grace,5); *) - END; - IF (n.grace > 0 ) & ( n.chord ="c" ) THEN notes[ps, voice, measure, note].grace :=-1 END; - (* eliminate chord notes in grace *) - IF (n.grace = 1) THEN b.gracelen( n, maxgrace ); (* Out.Ln(); Out.String( "maxgrace" ); Out.Int( maxgrace, 5 ); *) - - grace( n, ps, voice, measure, note, maxgrace, pmxgrace ); - - (* Out.Ln(); Out.String( "NotesProp nach PROC grace : " ); Out.Int( ps, 5) ; Out.Int( part, 5 ); - Out.Int( staff, 5 ); Out.Int( voice, 5 ); Out.Int( measure, 5 ); Out.Int( note, 5 ); - Out.Int(notes[ps, voice, measure, note].grace,5); Out.Char("|"); *) - - - COPY( pmxgrace, notes[ps, voice, measure, note].pmxgrace ); - - (* Out.String( notes[ps, voice, measure, note].pmxgrace ); *) - - - - - (* ELSIF n.grace > 1 THEN - - Out.Ln();Out.String("n.grace > 1");Out.Int(ps,5); Out.Int(voice,5); Out.Int(measure,5); Out.Int(note,5); *) - ELSE (* not a grace note *) - - IF (n.tagname = "<forward>") THEN - notes[ps, voice, measure, note].blind := "b"; (* Out.Ln(); Out.String( "NotesProp : <forward>" ); - Out.Int( part, 5 ); Out.Int( staff, 5 ); Out.Int( voice, 5 ); Out.Int( measure, 5 ); Out.Int( note, 5 ); *) - END; - IF (n.tagname = steptag) THEN notes[ps, voice, measure, note].pitchstep := Strings.LowerCh( n.between[0] ) END; - - IF (n.tagname = octavetag) THEN notes[ps, voice, measure, note].pitchoctave := b.ExtractInt( n.between ) - END; - IF (n.tagname = "<unpitched>") THEN - n := n.next; - IF (n.tagname = "<display-step>") THEN - notes[ps, voice, measure, note].pitchstep := Strings.LowerCh( n.between[0] ) - END; - n := n.next; - IF (n.tagname = "<display-octave>") THEN - notes[ps, voice, measure, note].pitchoctave := b.ExtractInt( n.between ) - END; - END; - IF (n.tagname = durationtag) THEN notes[ps, voice, measure, note].duration := b.ExtractInt( n.between ); END; - (* IF (n.tagname = stafftag) THEN notes[ps, voice, measure, note].staff := b.ExtractInt( n.between ) ; - laststaff := notes[ps, voice, measure, note].staff END; *) - (* IF (n.tagname = voicetag) THEN notes[ps, voice, measure, note].voice := b.ExtractInt( n.between ) END; *) - IF (n.tagname = dottag) OR (n.tagname = "<dot />") OR (n.tagname = "<dot>") THEN - IF notes[ps, voice, measure, note].dot = "d" THEN notes[ps, voice, measure, note].dot := "D"; - ELSE notes[ps, voice, measure, note].dot := "d" - END; - END; - IF (n.tagname) = actualtag THEN - Strings.StrToInt(n.between, long); - - notes[ps, voice, measure, note].actual := SHORT(long); - (* (Out.Ln(); Out.String("NotesProp .: ps, voice,measure, note, actual "); Out.Int(ps,5); Out.Int(voice,5); - Out.Int(measure,5); Out.Int(note,5); Out.Int(notes[ps, voice, measure, note].actual,5); *) - END; - IF (n.tagname = stemtag ) THEN notes[ps, voice, measure, note].stem := n.between[0] END; - IF (n.tagname = normaltag ) THEN Strings.StrToInt(n.between, long); - notes[ps, voice, measure, note].normal := SHORT(long); END; - IF (n.tagname = "<type>") THEN COPY( n.between, notes[ps, voice, measure, note].type ); END; - - IF (n.tagname = "<normal-type>") THEN - COPY( n.between, notes[ps, voice, measure, note].normaltype ); (* normal-type = type warum? 08.04.2017*) - (* IF notes[ps, voice, measure, note].normaltype[0] #0X THEN *) - COPY( n.between, notes[ps, voice, measure, note].type ); (* END; *) - END; - (* IF (n.tagname = "<actual-type>") THEN - COPY( n.between, notes[ps, voice, measure, note].actualtype ); (* Baustelle Korrektur 24062019*) - (* IF notes[ps, voice, measure, note].normaltype[0] #0X THEN *) - COPY( n.between, notes[ps, voice, measure, note].type ); (* END; *) - END; *) - - - Accidentals (n,ps,voice,measure,note); - - IF (n.tagname = resttag) OR (n.tagname = "<rest>") OR (n.tagname = "</rest>") THEN - notes[ps, voice, measure, note].rest := "r"; - END; - (* IF (n.tagname # chordtag) & ( n.tagname # "<chord>" ) THEN lastbase := SHORT( note ) END; store main note of a chord *) - IF (n.tagname = chordtag) OR (n.tagname = "<chord>") THEN notes[ps, voice, measure, note].chord := "z"; - (* notes[ps, voice, measure, note].base := lastbase; *) END; - IF (n.tagname = fermatatag) THEN (* keine Fermata im Tuplett. *) - b.FindAtt( n, "type", type ); COPY( " of", notes[ps, voice, measure, note].fermata ); - - IF ( type = "inverted") THEN Strings.Append( notes[ps, voice, measure, note].fermata, "d " ); END; - END; - (* prepare for binary tremolo ! *) - IF (n.tagname = beamtag) THEN (* counts the beams in one note *) - b.FindAtt(n, "number",number); - Strings.StrToInt(number,notes[ps,voice,measure,note].maxbeam) - END; - IF ( n.tagname = "<tremolo>" ) (* & (measure = 166) *) THEN - b.FindAtt(n, "type",notes[ps,voice,measure,note].tremolotype); - Out.Ln(); Out.String("tremolotype : "); Out.String(notes[ps,voice,measure,note].tremolotype); - Out.Ln(); Out.String("BEams in tremolo : "); Out.String(n.between); (*&&&&&&&*) - Strings.StrToInt(n.between, notes[ps,voice,measure,note].maxbeam); - - END; - - IF (n.tagname = slurtag) THEN - b.slur2PMX( n, pmxslur , outputset); COPY(pmxslur, notes[ps, voice, measure, note].slur[0] ) ; - (* Out.Ln(); Out.Int(ps,5); Out.Int(voice,5); Out.Int(measure,5); Out.Int(note,5); Out.String(pmxslur); - openslur.ps := ps; openslur.voice := voice; openslur.measure := measure; openslur.note := note; - openslur.grace := notes[ps,voice,measure,note].grace; - Out.Int(notes[ps,voice,measure,note].grace,5); *) - n := n.next; - IF (n.tagname = slurtag) THEN - b.slur2PMX(n,pmxslur, outputset); COPY(pmxslur, notes[ps, voice, measure, note].slur[1] ) ; - (* Out.Ln(); Out.Int(ps,5); Out.Int(voice,5); Out.Int(measure,5); Out.Int(note,5); Out.String(pmxslur); - Out.Int(notes[ps,voice,measure,note].grace,5); *) - - n := n.next; - END; - - - END; - - - - - - -(* END; *) - - IF (n.tagname = tiedtag) THEN (* 1*) - b.FindAtt( n, "type", ntype ); - - IF ntype = "start" THEN (* 2 *) - b.tied2PMX( n, ntype, pmxtied, ps,voice); - COPY( pmxtied, notes[ps, voice, measure, note].tied[0] ); - ELSIF ntype = "stop" THEN - m := n.next; - IF m.tagname = tiedtag THEN (* 3 *) - (* Out.Ln(); Out.String( "================== found 2nd tie" ); *) - - b.FindAtt( m, "type", mtype ); - IF mtype = "start" THEN (* 4 *) - b.tied2PMX( m, mtype, pmxtied, ps, voice); - COPY( pmxtied, notes[ps, voice, measure, note].tied[0] ); - b.tied2PMX( n, ntype, pmxtied, ps,voice); - COPY( pmxtied, notes[ps, voice, measure, note].tied[1] ); - ELSE - Out.Ln(); Out.String( "===========Notesprop: tie inconsistent" ); Out.Int( ps, 5 ); - Out.Int( voice, 5 ); Out.Int( measure, 5 ); - END; (* 4 *) - - - ELSE (* next Tag is not a tiedtag! *) - (* ntype = "stop" *) - b.tied2PMX( n, ntype, pmxtied, ps,voice); - COPY( pmxtied, notes[ps, voice, measure, note].tied[1] ); - END; (* 3 *) - IF m.tagname = tiedtag THEN n := n.next END; - END; (* 2 *) - END; (* 1 *) - IF (n.tagname = beamtag) THEN - b.FindAtt( n, "number", number ); - - IF (number = "1") THEN (* PMX needs only one beam *) - beam2PMX( n, pmxbeam, notes[ps, voice, measure, note].stem, staff ); - - IF notes[ps, voice, measure, note].chord # "z" THEN - COPY( pmxbeam, notes[ps, voice, measure, note].beam ); - COPY( closebeam, notes[ps, voice, measure, note].closebeam ); - - END; - END; - END; - IF ( n.tagname = "<trill-mark>" ) OR ( n.tagname = "<trill-mark/>" ) THEN COPY (" oT0 ", notes[ps, voice, measure, note].trill); END; - IF n.tagname = staccatotag THEN COPY( " o. ", notes[ps, voice, measure, note].staccato ); END; - IF (n.tagname = "<accent>" ) OR (n.tagname = "<accent />" ) OR (n.tagname = "<accent/>" ) - THEN - b.FindAtt( n, "placement", placement ); - COPY( " o>", notes[ps, voice, measure, note].accent ); - IF ( placement = "below") THEN - Strings.Append(notes[ps, voice, measure, note].accent,"-12 ") END; - Strings.AppendCh(notes[ps, voice, measure, note].accent," "); - END; - IF ( n.tagname = "<strong-accent>") OR ( n.tagname = "<strong-accent/>") OR ( n.tagname = "<strong-accent />") - THEN COPY( " o^ ", notes[ps, voice, measure, note].strongaccent ); END; - - (* IF n.tagname = "<arpeggiate>" THEN notes[ps,voice,measure,note].arpeggio := TRUE; END; (* 22. November 2019 $$$$$$$ *) *) - IF n.tagname = tuplettag THEN - b.FindAtt( n, "type", type ); COPY( type, notes[ps, voice, measure, note].tuplet ) - END; - IF (n.tagname = stafftag) THEN notes[ps, voice, measure, note].staff := ORD( n.between[0] ) - 48; END; - IF (n.tagname = repeattag) THEN - repeat2PMX( n, pmxrepeat ); COPY( pmxrepeat, notes[ps, voice, measure, note].repeat ); - END; - END; - - IF (n.tagname = "<tremolo>") & ( notes[ps, voice, measure, note].tremolotype ="single" ) - THEN Strings.StrToInt( n.between, notes[ps, voice, measure, note].trembeam ); - - (* Out.Ln(); Out.String( " NotesProp-tremolo-beams : " ); Out.Int( ps, 5 ); Out.Int( measure, 5 ); - Out.Int( notes[ps, voice, measure, note].trembeam, 5 ); *) - END; (* not a grace note *) - - IF (4 IN outputset ) & ( n.tagname = lyrictag ) THEN b.lyric( ps, n ); END; (* stores lyric of a song *) - IF (n.tagname # eonotetag) THEN n := n.next; END; - END; - (* Enumerate(part,staff,voice,measure,note); *) - END NotesProp; - - - PROCEDURE MeasureProp( measure: LONGINT; n: b.Tag ); - (* stores measure information in an array with index [measure] for later use in the PMX generation. *) - VAR pmxrepeat, pmxending: ARRAY 16 OF CHAR; - type: ARRAY 32 OF CHAR; - BEGIN -(* Out.Ln(); Out.String("in measure prop"); *) - IF (n.tagname = barstyletag) THEN - IF (n.between = "light-light") THEN COPY( " Rd ", measures[measure].barstyle ) - (* ELSIF (n.between = "light-heavy") THEN COPY( " RD ", measures[measure].barstyle ) RD not needed in PMX *) - END; - END; - IF (n.tagname = repeattag) THEN repeat2PMX( n, pmxrepeat ); COPY( pmxrepeat, measures[measure].repeat ); END; - IF (n.tagname = endingtag) THEN - ending2PMX( n, pmxending, type ); - IF type = "start" THEN COPY( pmxending, measures[measure].ending ); END; - IF type = "discontinue" THEN COPY (pmxending,measures[measure+1].ending); END; - END; - - END MeasureProp; - - PROCEDURE ReadClef( VAR n: b.Tag; VAR sign: CHAR; VAR line, staff: LONGINT ); - VAR endtag, number: ARRAY 32 OF CHAR; - - BEGIN - IF (n.tagname = cleftag) THEN - b.loesch( number ); b.FindAtt( n, "number", number ); (* Out.Ln(); Out.String( " ReadClef : " ); - Out.Int( n.nr, 5 ); Out.Char( "|" ); Out.String( number ); *) - IF number[0] # 0X THEN Strings.StrToInt( number, staff ); ELSE staff := 1 END; - COPY( n.endtag, endtag ); - WHILE (n.next # NIL ) & (n.tagname # endtag) DO - (* OutTag( n ); *) - IF (n.tagname = signtag) THEN sign := n.between[0]; END; (* "p" by percussion *) - IF (n.tagname = cleflinetag) THEN Strings.StrToInt( n.between, line ); END; - n := n.next; - END; - ELSE Out.String( "Readclef n.tagname = " ); Out.String( n.tagname ) - END; - END ReadClef; - - PROCEDURE AttributesProp( VAR n: b.Tag ); - (* stores initial structure ( divisions, fifths,beats,beattype,staves,clef and transposition) - in an array with index [part] for later use in the PMX generation. *) - VAR staff: LONGINT; - endtag, symbol: ARRAY 32 OF CHAR; - sign: CHAR; line: LONGINT; - BEGIN - - IF (n.tagname = attributestag) THEN - COPY( n.endtag, endtag ); n.used := TRUE; stavesfound := FALSE; - WHILE (n.next # NIL ) & (n.tagname # endtag) DO - part := n.part; attributes[part].measure := n.measure; measure := n.measure; (* OutTag( n ); *) - - attributes[part].note := n.note; (* Out.Ln(); Out.String( "AttributesProp : part " ); Out.Int( part, 5 ); *) - IF (n.tagname = divisionstag) THEN attributes[part].divisions := b.ExtractInt( n.between ) ; END; - - IF (n.tagname = fifthstag) THEN - attributes[part].fifth := b.ExtractInt( n.between ); measures[measure].keys[part] := attributes[part].fifth; - b.akeys[part] := attributes[part].fifth; - END; - IF (n.tagname = "<time>") THEN - b.FindAtt( n, "symbol", symbol ); (* Out.Ln(); Out.String( "att. symbol :****************" ); *) - Out.String( symbol ); - IF symbol = "common" THEN attributes[part].mtrdenp := 6; - ELSIF symbol = "cut" THEN attributes[part].mtrdenp := 5; - ELSE attributes[part].mtrdenp := 0; - END; - END; - - IF (n.tagname = beatstag) THEN - attributes[part].beats := b.ExtractInt( n.between ); (* measures[measure].beats := attributes[part].beats; versuch: 19.5.2017*) - END; - IF (n.tagname = beattypetag) THEN - attributes[part].beattype := b.ExtractInt( n.between ); - - END; - - IF (n.tagname = stavestag) THEN - attributes[part].staves := b.ExtractInt( n.between ); stavesfound := TRUE; - staves[n.part] := attributes[part].staves; - END; - IF (n.tagname = "<diatonic>") THEN - Out.Ln(); Out.String( " diatonic" ); Out.Ln(); Strings.StrToInt( n.between, attributes[part].diatonic ) - END; - IF (n.tagname = "<chromatic>") THEN Strings.StrToInt( n.between, attributes[part].chromatic ) END; - IF (n.tagname = "<octave-change>") THEN Strings.StrToInt( n.between, attributes[part].octave ) END; - - IF (n.tagname = cleftag) THEN - ReadClef( n, sign, line, staff ); attributes[part].clefsign[staff] := sign; - attributes[part].clefline[staff] := line; END; - - n := n.next; - - END; - IF (stavesfound = FALSE ) THEN attributes[part].staves := 1; staves[n.part] := attributes[part].staves; END; - - IF (attributes[part].diatonic # 0) & (attributes[part].chromatic # 0) THEN - Out.Ln(); Out.String( " Transposition : part, fifths, dia, chrom, oct " ); Out.Int( part, 5 ); - Out.Int( attributes[part].fifth, 5 ); Out.Int( attributes[part].diatonic, 5 ); - - Out.Int( attributes[part].chromatic, 5 ); Out.Int( attributes[part].octave, 5 ); - END; - - END; - END AttributesProp; - - - - PROCEDURE Enrich2( q: b.FIFO ); - (* determines last note with voice "0" for distributing directions. *) - (* n.voice12 has the value "1" for the upper voice and "2" for the lower voice in one staff. *) - VAR n: b.Tag; lastnote: LONGINT; - BEGIN - n := q.first; lastnote := 0; - WHILE n.next # NIL DO - IF (n.tagname = measuretag) THEN lastnote := 0; END; - IF (n.tagname = notetag) THEN - part := n.part; staff := n.staff; ps := linstaff( nostaves, part, staff ); - n.voice12 := VOICE01( ps, n.voice, n.measure ) + 1; - (* IF (n.chord # "z") THEN n.lastnote := lastnote; END; Change: 26.07.2019 *) - IF (n.chord # "c") THEN n.lastnote := lastnote; END; - (* OutTag(n,TRUE); *) - END; - IF n.voice12 = 1 THEN lastnote := n.note END; - n := n.next; - END; - - END Enrich2; - PROCEDURE Enrich( q: b.FIFO ); - (* 1. Read voice and staff; store as notes attribute; - 2. Calculates maxnote, minvoice,maxvoice,minVoice,maxVoice; *) - VAR n, m: b.Tag; notevoice, notestaff : LONGINT; duration, backup, B: LONGINT; - - BEGIN - - b.loeschint( voicecount ); - n := q.first; (* Out.Ln(); Out.String( "part, staff, measure, voice, note, minvoice " ); Out.Ln(); *) - WHILE n.next # NIL DO - - IF (n.tagname = notetag) THEN - - - IF (n.next.tagname = gracetag) OR (n.next.tagname = gracetag2) THEN - INC( lastgrace ); n.grace := SHORT( lastgrace ); (*b.OutTag(n,TRUE); Out.String("ist grace"); *) - ELSE lastgrace := 0 - END; - - b.FindProperty( n, notetag, "<arpeggiate>", B ); - IF B > 0 THEN n.arpeggio := TRUE ELSE n.arpeggio := FALSE END; - - b.FindIProperty( n, notetag, voicetag, voice ); n.voice := voice; notevoice := voice; - - b.FindIProperty( n, notetag, stafftag, staff ); n.staff := staff; notestaff := staff; note := n.note; - - b.FindIProperty( n, notetag, durationtag, duration ); n.duration := SHORT( duration ); - - b.FindProperty( n, notetag, chordtag, B ); - IF B > 0 THEN n.chord := "c" END; - - measure := n.measure; part := n.part; - - maxnote[part, staff, measure] := b.Max( note, maxnote[part, staff, measure] ); - minnote[part, staff, measure] := b.Min( note, minnote[part, staff, measure] ); - - (* NEW( st ); b.psv2String( part, staff, voice, st.key ); InsertRanked( first, st ); NEW( psmv ); - b.psmv2String( part, staff, voice, measure, psmv.key ); InsertRanked( firstpsmv, psmv ); *) - - END; - IF (n.tagname = directiontag) THEN b.FindIProperty( n, directiontag, stafftag, staff ); n.staff := staff; - b.findnextnote (n,m); IF m # NIL THEN n.nextnote := m.note; - b.FindIProperty( m, notetag, voicetag, voice ); n.nextvoice := voice; END; (* voice of next note "m"&&&&& *) - END; - IF (n.tagname = backuptag) THEN - (* Out.Ln();Out.String("******************* Backup"); *) - b.FindIProperty( n, backuptag, durationtag, backup ); n.backup := SHORT( backup ); m := n; - WHILE (m.next # NIL ) & (m.tagname # notetag) DO - (* Out.Ln(); Out.String("backup-m"); b.OutTag(m,FALSE); *) - m := m.next ; - END; (* hier werden Daten weggelesen, bis zur naechsten Note *) - (* und dann der backup der Note zugeordnet *) - (* IF m.grace > 0 THEN - WHILE - m.grace > 0 DO b.OutTag(m,TRUE); m := m.next; - END; - END; (* Aenderung wg ala tiurca grace notes Takt 28 ff *) *) - (* Store backup at next note *) ; m.backup := SHORT( backup ); (* b.OutTag(m,TRUE); *) - END; - - (* OutTag(n); *) - n := n.next; - END; - Enrich2(b.q); - - - - END Enrich; - - PROCEDURE VOICE01( ps, voice, measure: LONGINT ): LONGINT; - BEGIN - IF vmap[ps, measure, 0] = voice THEN RETURN 0 - ELSIF vmap[ps, measure, 1] = voice THEN RETURN 1 - ELSE RETURN 2 - END; - - END VOICE01; - - - PROCEDURE Accidentals(n : b.Tag; ps, voice, measure, note : LONGINT); - VAR - cautionary, editorial, parentheses : ARRAY 32 OF CHAR; - BEGIN - IF (n.tagname) = accidentaltag THEN (* 5 *) - b.FindAtt( n, "editorial", editorial ); - b.FindAtt( n, "cautionary", cautionary ); - b.FindAtt( n, "parentheses", parentheses ); - IF n.between = "sharp" THEN - COPY( "s", notes[ps, voice, measure, note].accidental ); - IF editorial = "yes" THEN Strings.Append( notes[ps, voice, measure, note].accidental, " oes " ) END; - ELSIF n.between = "flat" THEN - COPY( "f", notes[ps, voice, measure, note].accidental ); - IF editorial = "yes" THEN Strings.Append( notes[ps, voice, measure, note].accidental, " oef " ) END; - ELSIF (n.between = "double-sharp") OR (n.between = "sharp-sharp") THEN - COPY( "ss", notes[ps, voice, measure, note].accidental ) - ELSIF (n.between = "flat-flat") OR (n.between = "double-flat") THEN - COPY( "ff", notes[ps, voice, measure, note].accidental ) - ELSIF n.between = "natural" THEN COPY( "n", notes[ps, voice, measure, note].accidental ); - IF editorial = "yes" THEN Strings.Append( notes[ps, voice, measure, note].accidental, " oen " ) END; - ELSE - END; - IF ( cautionary = "yes" ) OR ( parentheses = "yes") - THEN Strings.AppendCh( notes[ps, voice, measure, note].accidental, "c" ); - - END; - - END; - - END Accidentals; - - - - PROCEDURE EnumerateTags*; - (* runs through the list of tags and calls NotesProp and MeasuresProp and lists the tag-data in System.Log *) - VAR n: b.Tag; voice01: LONGINT; - BEGIN - n := b.q.first; voice01 := 0; - WHILE n.next # NIL DO (* 1 *) - part := n.part; measure := n.measure; note := n.note; (* voice := n.voice; staff := n.staff; *) - - - IF (n.tagname = notetag) THEN (* 3 *) - - voice := n.voice; staff := n.staff; - (* store cue-property 11.07.2019 *) - IF ( n.next.tagname = "<cue/>" ) THEN n.cue := TRUE; END; - - ps := linstaff( nostaves, part, staff ); voice01 := VOICE01( ps, voice, measure ); - - (* directions are coded after notes in upper voice *) - NotesProp( part, staff, voice01, measure, note, n ); INC(countnote); - (* (* IF (countnote <10) THEN *) Out.Ln(); Out.String("cnote");Out.Int(countnote,5) (* END; *) ; *) - - - END; (* 3 *) - - IF (n.tagname = attributestag) THEN AttributesPropM( voice01, measure, n ); - INC (countattr); END; - (* geaendert 8.1.2016: lastnote -> note *) - (* IF 1 =0 THEN *) - IF (n.tagname = directiontag) THEN DirectionProp( n,voice01 ); INC(countdir) ;END; - MeasureProp( measure, n ); (* OutTag( n ); *) - n := n.next - END; (* 1 *) - (* FillMeasures; - Out.Ln(); Out.String(" nach attributesprom : "); ; ListMeasures; *) - - (* ListDir; $$$$$$$$$$$$$$$$ *) -(* Out.Ln(); Out.String( "part, transposition: fifth diatonic chromatic octave "); -INC - part := 1; - WHILE part <= maxpart DO - Out.Ln(); Out.Int( part, 5 ); Out.Int( attributes[part].fifth, 5 ); Out.Int( attributes[part].diatonic, 5 ); - Out.Ln(); Out.String("divisions in enumerate : "); Out.Int(attributes[part].divisions,5); - (* Out.Int( attributes[part].chromatic, 5 ); Out.Int( attributes[part].octave, 5 ); *) - (* pitch.pmxtranspose(part,attributes[part].fifth, remove automatic transposition based on XML-transpose - attributes[part].diatonic,attributes[part].chromatic,attributes[part].octave,kstring); - Out.Char("|"); Out.String(kstring); COPY(kstring,attributes[part].kstring); *) - INC( part ); - END; *) - ps := 0; - WHILE ps < nostaves DO part := partstaff[ps, 0]; - (* Calculate durations for all instruments and measures *) - measure := 1; - WHILE measure <= maxmeasure DO - - IF measures[measure].beattype > 0 THEN (* 20.10.2020 Lilypond *) - - measures[measure].duration[part] := - measures[measure].beats*4*attributes[part].divisions - DIV measures[measure].beattype; (* Division durch 0 *) - - - END; - INC( measure ); - END; - INC( ps ); - END; -(* END; (* Fake End *) *) -(* ListMeasures; $$$$ *) - (* prvoicetime; *) - (* CopyClefVoice; *) - END EnumerateTags; - - - - PROCEDURE DirectionProp( VAR n: b.Tag; voice01 : LONGINT ); - VAR endtag, placement, type, res: ARRAY 128 OF CHAR; - dirnum, dirtypenr : LONGINT; defaultx: LONGINT; sbeatunit : ARRAY 32 OF CHAR; - defaultxs: ARRAY 32 OF CHAR; rehtext : ARRAY 32 OF CHAR; (* fuer rehearsal marks *) - BEGIN - (* Out.Ln(); Out.String("in direction prop"); *) - - IF (n.tagname = directiontag) THEN (* 1 *) - - (* b.OutTag( n, TRUE ); *) - COPY( n.endtag, endtag ); part := n.part; measure := n.measure; dirnum := n.dirnum; staff := n.staff; - directions[dirnum, 0].part := n.part; directions[dirnum, 0].measure := n.measure; voice := n.voice; - directions[dirnum, 0].staff := staff; directions[dirnum, 0].used := FALSE; (* allow usage of direction only once. *) - maxdirtype[dirnum] := 0; ps := linstaff( nostaves, part, staff ); (* voice01 := VOICE01( ps, voice, measure ); changed 22.12.2016 *) - (* Voice01( ps, voice ); *) - - directions[dirnum, 0].note := n.note; directions[dirnum, 0].lastnote := n.lastnote; (* -1 ; Versuch 21. Mai => Absturz *) - directions[dirnum,0].voice := voice01; (* changed 22.12.2016 *) - - IF measure = 96 THEN Out.Ln(); Out.String("DirectionProp : dirnum, note | lastnote "); - Out.Int(dirnum,5); Out.Int(n.note,5); Out.Char("|");Out.Int(n.lastnote,5); - END; - - (* CheckVoice(ps,measure,n.lastnote); *) - (* the direction is stored at this note *) - - (* Out.Ln(); Out.String( "DirectionProp : lastnote " ); Out.Int( dirnum, 5 ); - Out.Int( directions[dirnum, 0].lastnote, 5 ); *) - directions[dirnum, 0].before := FALSE; (*$$$$$$$$$$$$$$$$$$$$$$*) - - - b.FindAtt( n, "placement", placement ); dirtypenr := 0; - (* placement is valid for all direction-types under the direction *) - WHILE (n.next # NIL ) & (n.tagname # endtag) DO (* 2 *) - IF (n.tagname = "<direction-type>") THEN (* 3 *) - INC( dirtypenr ); n := n.next; (* OutTag( n ); *) - directions[dirnum, dirtypenr].lastnote := directions[dirnum, 0].lastnote; - IF (n.tagname = "<dynamics>") THEN (* 3 .1*) - - b.FindAtt( n, "default-x", defaultxs ); Strings.StrToInt( defaultxs, defaultx ); - directions[dirnum, dirtypenr].defaultx := SHORT( defaultx ); - - n := n.next; (* OutTag( n ); *) directions[dirnum, dirtypenr].dirtype := "d"; - COPY( n.tagname, directions[dirnum, dirtypenr].dyntype ); - directions[dirnum, dirtypenr].before := FALSE; - IF directions[dirnum, dirtypenr].note = 0 THEN - directions[dirnum, dirtypenr].note := 1; directions[dirnum, dirtypenr].placement := "l"; - END; - - ELSIF (n.tagname = "<words>") THEN (* 3 .2*) - IF (placement = "above") OR (placement = "") THEN - directions[dirnum, dirtypenr].placement := "h"; (* Aenderung 19. Mai *) - - ELSIF (placement = "below") THEN directions[dirnum, dirtypenr].placement := "l"; - END; - - directions[dirnum, dirtypenr].dirtype := "w"; COPY( n.between, directions[dirnum, dirtypenr].text ); - - directions[dirnum, dirtypenr].before := TRUE; - - ELSIF (n.tagname = "<pedal>") THEN (* 3 .3*) - directions[dirnum, dirtypenr].dirtype := "p"; b.FindAtt( n, "type", type ); - directions[dirnum, dirtypenr].before := TRUE; - - COPY( type, directions[dirnum, dirtypenr].pedaltype ); - - ELSIF (n.tagname = "<wedge>") THEN (* 3 .4*) - directions[dirnum, dirtypenr].dirtype := "h"; b.FindAtt( n, "type", type ); - COPY( type, directions[dirnum, dirtypenr].wedgetype ); directions[dirnum, dirtypenr].before := FALSE; - IF directions[dirnum, dirtypenr].note = 0 THEN directions[dirnum, dirtypenr].note := 1; END; - directions[dirnum, dirtypenr].placement := "l"; - ELSIF (n.tagname = "<metronome>") THEN (* 3 .5*) - directions[dirnum, dirtypenr].placement := "h"; directions[dirnum, dirtypenr].dirtype := "w"; (* Metronom ist "w" *) - WHILE (n.next # NIL ) & (n.tagname # "</metronome>") DO - IF n.tagname = "<beat-unit>" THEN COPY (n.between,sbeatunit) END; - - IF n.tagname = "<per-minute>" THEN b.metron2PMX (sbeatunit,n.between,directions[dirnum,dirtypenr].text); - (* Out.String( "metronome : " ); *) - (* Out.String( directions[dirnum, dirtypenr].text ); *) - directions[dirnum, dirtypenr].before := TRUE; - END; - - n := n.next; - END; - ELSIF (n.tagname = "<segno>" ) THEN directions[dirnum, dirtypenr].dirtype := "s"; - directions[dirnum, dirtypenr].before := FALSE; - ELSIF (n.tagname = "<coda>" ) THEN directions[dirnum, dirtypenr].dirtype := "c"; - directions[dirnum, dirtypenr].before := FALSE; - ELSIF (n.tagname = "<rehearsal>" ) THEN - directions[dirnum, dirtypenr].placement := "h"; - directions[dirnum, dirtypenr].dirtype := "w"; (* 14.10.2020 "rehearsal" *) - directions[dirnum, dirtypenr].before := TRUE; - COPY (" \boxit{",rehtext); - Strings.Append (rehtext,n.between); - b.loesch(directions[dirnum,dirtypenr].text) ; - Strings.Append(rehtext," } ") ; - - COPY(rehtext,directions[dirnum,dirtypenr].text); - - - Out.Ln(); Out.String( "rehearsal : "); Out.String(rehtext); - Out.Ln();Out.String("text :"); Out.String ( directions[dirnum,dirtypenr].text ) ; - - - ELSE - Out.Ln(); Out.String( "<direction-type> " ); Out.String( n.tagname ); - Out.String( " not implemented. " ); - END; - maxdirtype[dirnum] := b.Max( dirtypenr, maxdirtype[dirnum] ); - (* Out.Ln(); Out.String("dirtypenr : "); Out.Int(dirtypenr,5);*) - pmxDirections( dirnum, dirtypenr, res ); COPY( res, directions[dirnum, dirtypenr].pmxdirection ); - (* OutDir(dirnum,dirtypenr); *) - - (* Out.Int(dirnum,5); Out.String("| in directionprop "); Out.String(res); Out.String(directions[dirnum, dirtypenr].pmxdirection); *) - - END; (* 3 *) - (* IF (n.tagname = stafftag) THEN Strings.StrToInt( n.between, directions[dirnum].staff ) END; ??????? *) - n := n.next; (* OutTag( n ); *) - END; (* 2 *) - END; (* 1 *) - - END DirectionProp; - - PROCEDURE AttributesPropM ( voice, measure: LONGINT; VAR n: b.Tag ); - (***************** voice = voice01 ********************) - VAR sign: CHAR; line, number, part : LONGINT; clef: CHAR; m : b.Tag; staff : LONGINT; - (* takes care of changes: - - clefchange [part,staff] in the flow of notes - - meter change: beats and beattype [measure] - - fifth change - - change of divisions - links the changes to a note *) - BEGIN (* Out.Ln(); Out.String(" in AttirbutesPropM ");*) - IF (n.tagname = attributestag) & ~n.used THEN (* 1 *) - part := n.part; staff := n.staff; (* REparaturversuch 31.10.2020 *) - (* ps := linstaff( nostaves, part, staff ); *) -WHILE n.tagname # "</attributes>" DO (* 2*) - (* Out.Ln(); Out.String(n.tagname); *) - IF (n.tagname = cleftag) THEN - (* Out.Ln(); Out.String(cleftag); - Out.Ln(); Out.String("part,staff,ps, measure :");Out.Int(part,5); Out.Int(staff,5); Out.Int(ps,5); Out.Int(measure,5); *) - - (* neu Oktober 2020) find next note of same staff. *) - ReadClef( n, sign, line, number ); - b.clefPMX( sign, SHORT( line ), clef, clefspec[ps] ); - b.findnextnotestaff ( n, m ,number); m.newclef := clef; - (* lastclef[ps] := clef; *) - (* notes[ps, voice, measure, n.lastnote].clefchanged := clef; *) - - - (* b.OutTag(m,TRUE); *) (* INC (countclefchanges); Out.Ln();Out.Int(countclefchanges,5); *) - - END; - - (* Out.Ln(); Out.String("AttPropM"); Out.Char("|"); Out.Char( clef ); - Out.Char("|"); (* Out.Char( clefspec[ps] ); *) - - Out.Ln();Out.String("n. lastnote"); Out.Int(n.lastnote,5); - - IF ( n.lastnote # 0 ) THEN - lastclef[ps] := clef; notes[ps, voice, measure, n.lastnote].clefchanged := clef; - - Out.Ln(); Out.String("AttributesProp: n.lastnote # 0 "); Out.Int(measure,5); Out.Char("|"); Out.Char(clef); - ELSE - (* n.lastnote = 0 *) - measures[measure ].clefchange[linstaff(nostaves,part,number)] := clef; (* Maerz 2018 *) - - - Out.Ln(); Out.String("AttributesProp: n.lastnote = 0 "); Out.Int(measure,5); Out.Char("|"); Out.Char(clef); - END; *) - (* Out.Ln(); - Out.String( "clefs *******" ); Out.Int( ps, 5 ); Out.Int( voice, 5 ); Out.Int( measure, 5 ); - Out.Int( n.lastnote, 5 ); Out.Char( clef ); *) - - (* IF part = 1 THEN Korrektur 12. Januar 2016: Taktwechsel bei Takt 209 Vivaldi fehlt in der zweiten und driitten - Stimme. - *) - IF (n.tagname = beatstag) THEN (* change 19.5.2017 *) - - measures[measure].beats := b.ExtractInt( n.between ); (* Out.String( " PropM : measure = " ); - Out.Int( measure, 5 ); Out.Int( measures[measure].beats, 5 ); *) - END; - IF (n.tagname = beattypetag) THEN - measures[measure].beattype := b.ExtractInt( n.between ); - (* Out.Int( measures[easure].beattype, 5 ); *) - END; - IF (n.tagname = fifthstag) THEN - attributes[part].fifth := b.ExtractInt( n.between ); - measures[measure].keys[part] := attributes[part].fifth; - IF (part = maxpart) THEN measures[measure].fifth := attributes[part].fifth END; - i := measure+1; - WHILE i <= maxmeasure DO measures[i].keys[part] := attributes[part].fifth; - IF ( part = maxpart ) THEN - measures[i].fifth := attributes[maxpart].fifth; (* store concertkey *) - END; - - INC(i); - END; - - b.mkeys[part] := attributes[part].fifth; - - END; - - - IF (n.tagname = divisionstag) THEN attributes[part].divisions := b.ExtractInt( n.between ) ; END; - (* END; *) - n := n.next; - END (* 2 *) - - ELSE (* 1 *) - - (* Out.Ln(); Out.String( " AttributesPropM : attributstag not found or already used ! " ); - Out.String( n.tagname ); *) - - END; (* 1 *) - - END AttributesPropM; - - PROCEDURE Pickup( q: b.FIFO; VAR duration: LONGINT ); - (* finds out whether first measure is smaller, i.e. we have a pickup. *) - VAR n: b.Tag; isnote: BOOLEAN; - endtag: ARRAY 32 OF CHAR; - chord: CHAR; noteduration: LONGINT; - durationsv: ARRAY 25 OF ARRAY 10 OF LONGINT; - BEGIN - n := q.first; isnote := FALSE; chord := 0X; - WHILE (n.next # NIL ) & (n.tagname # measuretag) DO n := n.next; END; (* first measure of first part found *) - (* b.OutTag( n, TRUE ); *) COPY( n.endtag, endtag ); duration := 0; - WHILE (n.next # NIL ) & (n.tagname # endtag) DO (* Loop over all elements of 1st measure / 1st instrument /1st staff *) - IF (n.tagname = notetag) THEN - isnote := TRUE; part := n.part; staff := n.staff; voice := n.voice; chord := n.chord; (* b.OutTag( n, TRUE ); *) - END; - IF (n.tagname = eonotetag) THEN isnote := FALSE; END; - IF (n.tagname = durationtag) & isnote & (chord # "c") THEN - Strings.StrToInt( n.between, noteduration ); - (* Out.Ln(); Out.String("staff :"); Out.Int(staff,5); Out.String("voice :"); Out.Int(voice,5); - Out.String("duration : "); Out.Int(noteduration,5); *) - - INC( durationsv[staff, voice], noteduration ); - (* b.OutTag( n, TRUE ); *) - (* IF isnote THEN Out.String( "ist Note" ); END; *) - END; - n := n.next; - END; - - IF (duration = attributes[1].duration) THEN duration := 0; - END; - (* Out.Ln(); Out.String( "beats, beattype and divisions : " ); Out.Int( attributes[1].beats, 5 ); Out.Int( attributes[1].beattype, 5 ); - Out.Int( attributes[1].divisions, 5 ); - - Out.Ln(); Out.String( "Pickup : " ); Out.Int( duration, 5 ); Out.Int( attributes[1].duration, 5 ); *) - END Pickup; - - - - - PROCEDURE ControlProp*; - (* Extracts metadata from XML file for later use in PMX *) - VAR type, id, digits: ARRAY 32 OF CHAR; - dummy: ARRAY 128 OF CHAR; - n: b.Tag; part: LONGINT; - BEGIN - n := b.q.first; - WHILE (n.next # NIL ) & (n.tagname # "</part-list>") DO - IF n.tagname = "<work-number>" THEN COPY( n.between, pmxcontrol.worknumber ) END; - IF n.tagname = "<work-title>" THEN b.FilterTeX( n.between, dummy ); COPY( dummy, pmxcontrol.title ); END; - b.loesch( type ); - IF n.tagname = "<movement-title>" THEN COPY( n.between, pmxcontrol.title ); END; - IF n.tagname = "<creator>" THEN - b.FindAtt( n, "type", type ); - IF type = "composer" THEN COPY( n.between, pmxcontrol.composer ); - ELSIF (type = "lyricist") THEN COPY( n.between, pmxcontrol.lyricist ) - END; - END; - IF (n.tagname = "<rights>") THEN COPY( n.between, pmxcontrol.rights ); END; - IF n.tagname = "<encoding-date>" THEN - COPY( "encoding date : ", pmxcontrol.info ); Strings.Append( pmxcontrol.info, n.between ); - Strings.AppendCh( pmxcontrol.info, BLANK ); - END; - IF n.tagname = "<software>" THEN - IF pmxcontrol.software[0] = 0X THEN - COPY( "Software : ", pmxcontrol.software ); Strings.Append( pmxcontrol.software, n.between ); - ELSE - Strings.AppendCh( pmxcontrol.software, BLANK ); Strings.Append( pmxcontrol.software, n.between ); - END; - Strings.AppendCh( pmxcontrol.info, BLANK ); - END; - (* parts and instruments *) - IF n.tagname = "<score-part>" THEN - b.FindAtt( n, "id", id ); b.ExtractDigits( id, digits ); Strings.StrToInt( digits, controlpart ); - - - (* controlpart := ORD( id[1] ) - 48; old version single digit only *) - - COPY( id, pmxcontrol.parts[controlpart] ); - END; - IF n.tagname = "<instrument-name>" THEN b.FilterTeX( n.between, pmxcontrol.instruments[controlpart] ); END; - n := n.next; - END; - - part := 1; pmxcontrol.equalkeys := TRUE; - WHILE (part <= maxpart) DO - WHILE (n.next # NIL ) & (n.tagname # parttag) DO n := n.next END; (* FInd next <part> ***************) - WHILE (n.next # NIL ) & (n.tagname # attributestag) DO n := n.next END; - (* FInd next <attributes> *********) - IF (n.tagname = attributestag) THEN AttributesProp( n ); - (* determine length of measure in divisions. *******************************) - attributes[part].duration := - attributes[part].divisions*attributes[part].beats*4 DIV attributes[part].beattype; - (* Out.Ln(); Out.String( "AttributesProp : Part | XML-duration of measure : " ); Out.Int( part, 5 ); Out.Char("|"); - Out.Int( attributes[part].duration, 5 ); *) - (* measures[1].duration[part] := attributes[part].duration; *) - END; - (* check for transposing instruments! *) - IF ( part > 1 ) THEN pmxcontrol.equalkeys := pmxcontrol.equalkeys & ( attributes[part].fifth = attributes[part-1].fifth ) END; - - INC( part ); END; - IF ~ pmxcontrol.equalkeys THEN b.testmakekey(maxpart,1,keytotal); END; (* different keys in different parts *) - END ControlProp; - - PROCEDURE StaffInd( nostaves, part, staff: LONGINT ): LONGINT; - (* finds the linear index for [part,staff] *) - VAR i, dist: LONGINT; - BEGIN - i := -1; - REPEAT INC( i ); dist := ABS( partstaff[i, 0] - part ) + ABS( partstaff[i, 1] - staff ); - UNTIL (i = nostaves - 1) OR (dist = 0); - RETURN i; - END StaffInd; - - PROCEDURE AllStaves( VAR staves: ARRAY OF LONGINT ); - (* maps part/staff to a linear index. *) - VAR part, staff, i, nostaves: LONGINT; - BEGIN - i := 0; part := 1; - WHILE part <= maxpart DO - staff := 1; - WHILE staff <= staves[part] DO partstaff[i, 0] := part; partstaff[i, 1] := staff; INC( staff ); INC( i ); END; - - INC( part ); - END; - nostaves := i; i := 0; b.nostaves := nostaves; (* inform MODULE "b" about # of staves *) - END AllStaves; - - PROCEDURE progress( q: b.FIFO ); - (* Calculates the horizontal position of each note in a measure and stores it in the tag. *) - VAR n: b.Tag; ps: LONGINT; - BEGIN - ps := 0; - n := q.first; - - WHILE (n.next # NIL ) DO (* 1 *) - IF (n.tagname = measuretag) THEN Complete.erasetime( nostaves,voicetime ); lastto := 0; lastfrom := 0; END; (* 2 *) - IF (n.tagname = notetag) THEN (* 3 *) - part := n.part; staff := n.staff; measure := n.measure; ps := StaffInd( nostaves, part, staff ); - voice := VOICE01( ps, n.voice, n.measure ); - - IF (n.chord # "c") & ( n.grace = 0 ) THEN (* 4 *) (* war frueher "&" statt "OR" *) - (* INC(measures[measure].dur,n.duration); Out.Int(n.duration,5); *) - INC( voicetime[ps, voice], n.duration ); n.voicetime := voicetime[ps, voice]; - measures[measure].voicetime[ps, voice] := n.voicetime; n.from := lastto + 1 - n.backup; - n.to := n.from + n.duration - 1; lastto := n.to; lastfrom := n.from; - ELSIF (n.chord = "c" ) THEN n.voicetime := lastto; n.to := lastto; n.from := lastfrom; - ELSIF ( n.grace = 1 ) THEN n.from := lastto - n.backup; n.to := n.from ; lastto := n.to; - ELSIF ( n.grace > 1 ) THEN n.from := lastto; n.to := n.from; lastto := n.to; - ELSE - END; (* 4 *) - - END; (* 3 *) - IF ( n.tagname = eomeasuretag ) & (ps = nostaves - 1) THEN (* 5 *) - measures[measure].dur := lastto; - (* Out.Char("|");Out.Int(measure,5);Out.Int(ps,5);Out.Int(measures[measure].dur,5); Out.Ln(); *) END; (* 5 *) - - n := n.next; - END; (* 1 *) - (* Out.Ln(); Out.String("measure duration"); *) - measure := 1; WHILE measure <= maxmeasure DO (* Out.Ln(); Out.Int(measure,5); - Out.Int (measures[measure].dur ,5); *) - Complete.dur2beat(measures[measure].dur,attributes[part].divisions, - measures[measure].beats, measures[measure].beattype); - (* Out.Int(measures[measure].beats,5); Out.Int(measures[measure].beattype,5); *) - INC(measure) END; - - END progress; - - - PROCEDURE linstaff( nostaves, part, staff: LONGINT ): LONGINT; - (* calculates the linear index of the combination "part and staff" *) - VAR i: LONGINT; - BEGIN - i := 0; - WHILE (i < nostaves) & (partstaff[i, 0] # part) DO INC( i ) END; - WHILE (i < nostaves) & (partstaff[i, 0] = part) & (partstaff[i, 1] # staff) DO INC( i ) END; - - IF (i < nostaves) THEN RETURN i; - ELSE RETURN -1; - END; - END linstaff; - - - PROCEDURE ControlData( VAR W: Files.Rider ); - (* Writes PMX header information to intermediate Files.File "fprep" with Files.Rider "rprep" *) - VAR i: LONGINT; xmtrnum0: LONGREAL; clef: CHAR; - perclef, perline: ARRAY 32 OF CHAR; - zeit, tag, xmtrnum0s: ARRAY 16 OF CHAR; - BEGIN - - - (* TeX Input type 4 *) - WriteString( W, "---" ); Files.Write( W, CR ); Files.Write( W, NL ); - WriteString( W, "%\input musixlyr" ); Files.Write( W, CR ); Files.Write( W, NL ); - WriteString( W, "%\special{papersize=297mm,420mm}%" ); Files.Write( W, CR ); Files.Write( W, NL ); - WriteString( W, "---" ); Files.Write( W, CR ); Files.Write( W, NL ); - - Files.Write( W, "%" ); - (* DateTime(zeit,tag); *) - WriteString( W, tag ); Files.Write( W, "|" ); WriteString( W, zeit ); Files.Write( W, CR ); Files.Write( W, NL ); - - Files.Write( W, "%" ); - - WriteString( W, pmxcontrol.xml ); Files.Write( W, CR ); Files.Write( W, NL ); Files.Write( W, "%" ); - - WriteString( W, pmxcontrol.dtd ); Files.Write( W, CR ); Files.Write( W, NL ); Files.Write( W, "%" ); - - WriteString( W, pmxcontrol.title ); Files.Write( W, CR ); Files.Write( W, NL ); Files.Write( W, "%" ); - - IF (pmxcontrol.worknumber[0] # 0X) THEN - WriteString( W, "% work number : " ); WriteString( W, pmxcontrol.worknumber ); Files.Write( W, CR ); - Files.Write( W, NL ); Files.Write( W, "%" ); - END; - - WriteString( W, pmxcontrol.composer ); Files.Write( W, CR ); Files.Write( W, NL ); Files.Write( W, "%" ); - - IF (pmxcontrol.lyricist[0] # 0X) THEN - WriteString( W, pmxcontrol.lyricist ); Files.Write( W, CR ); Files.Write( W, NL ); - - Files.Write( W, "%" ); - END; - - WriteString( W, pmxcontrol.info ); Files.Write( W, CR ); - Files.Write( W, NL ); Files.Write( W, "%" ); - - IF (pmxcontrol.rights[0] # 0X) THEN - WriteString( W, " Rights : " ); WriteString( W, pmxcontrol.rights ); Files.Write( W, CR ); Files.Write( W, NL ); - Files.Write( W, "%" ); - END; - WriteString( W, pmxcontrol.software ); Files.Write( W, CR ); Files.Write( W, NL ); Files.Write( W, "%" ); - - part := 1; nostaves := 0; - WHILE part <= maxpart DO - - WriteString( W, "Part " ); WriteString( W, pmxcontrol.parts[part] ); WriteString( W, " : " ); - WriteString( W, pmxcontrol.instruments[part] ); Files.Write( W, CR ); Files.Write( W, NL ); - Files.Write( W, "%" ); nostaves := nostaves + attributes[part].staves; INC( part ); - END; - - AllStaves( staves ); Files.Write( W, CR ); Files.Write( W, NL ); Files.Write( W, "%" ); Files.Write( W, CR ); - Files.Write( W, NL ); - - WriteString( W, "% nv, -noinst, nostaves per instrument" ); Files.Write( W, CR ); Files.Write( W, NL ); - - WriteLInt( W, nostaves ); (* nv *) - WriteLInt( W, -maxpart ); (* noinst *) - i := maxpart; - WHILE i > 0 DO WriteLInt( W, staves[i] ); DEC( i ) END; - Files.Write( W, CR ); Files.Write( W, NL ); - - WriteString( W, "% mtrnuml,mtrdenl,mtrnmp,mtrdnp,xmtrnum0,isig" ); Files.Write( W, CR ); - Files.Write( W, NL ); - - WriteLInt( W, attributes[1].beats ); (* mtrnuml *) - WriteLInt( W, pmxtype( attributes[1].beattype ) ); (* mtrdenl *) - IF attributes[1].mtrdenp # 0 THEN WriteLInt( W, 0 ) ELSE WriteLInt( W, attributes[1].beats ); END; (* mtrnump *) - IF attributes[1].mtrdenp # 0 THEN WriteLInt( W, attributes[1].mtrdenp ) - ELSE WriteLInt( W, attributes[1].beattype ); - END; (* mtrdenp *) - IF (attributes[1].pickup > 0) THEN - xmtrnum0 := attributes[1].pickup/attributes[1].divisions; - IF attributes[1].beattype = 2 THEN xmtrnum0 := xmtrnum0/2; - ELSIF attributes[1].beattype = 8 THEN xmtrnum0 := xmtrnum0*2; - ELSIF attributes[1].beattype = 16 THEN xmtrnum0 := xmtrnum0*4; - ELSE - END; - - ELSE xmtrnum0 := 0.; - END; - Strings.RealToStr( xmtrnum0, xmtrnum0s ); Files.Write( W, BLANK ); - WriteString( W, xmtrnum0s ); (*xmtrnum0 *) - WriteLInt( W, attributes[maxpart].fifth ); (* isig *) (* this is the concert key *) - Files.Write( W, CR ); Files.Write( W, NL ); Files.Write( W, "%" ); Files.Write( W, CR ); Files.Write( W, NL ); - - WriteString( W, "% npages,nsyst,musicsize,fracindent " ); Files.Write( W, CR ); Files.Write( W, NL ); - - WriteLInt( W, 0 ); WriteLInt( W, 5 ); WriteLInt( W, 16 ); Files.Write( W, BLANK ); WriteString( W, "0.07" ); - part := maxpart; - WHILE (part >= 1) DO - Files.Write( W, CR ); Files.Write( W, NL ); - IF pmxcontrol.instruments[part] = "Acoustic Grand Piano" THEN - COPY( "Piano", pmxcontrol.instruments[part] ); - END; - WriteString( W, pmxcontrol.instruments[part] ); DEC( part ); - END; - Files.Write( W, CR ); Files.Write( W, NL ); - - i := nostaves - 1; - WHILE i >= 0 DO part := partstaff[i, 0]; staff := partstaff[i, 1]; (* Out.Ln(); - - Out.String( "control data : i, part, staff, sign, line, clef special clef " ); Out.Int( i, 5 ); Out.Int( part, 5 ); - Out.Int( staff, 5 ); *) - - b.clefPMX( attributes[part].clefsign[staff], SHORT( attributes[part].clefline[staff] ), clef, clefspec[i] ); - lastclef[i] := clef; Files.Write( W, clef ); - DEC( i ); - END; - - Files.Write( W, CR ); Files.Write( W, NL ); WriteString( W, "./" ); Files.Write( W, CR ); Files.Write( W, NL ); - - WriteString( W, "Tt" ); Files.Write( W, CR ); Files.Write( W, NL ); - - WriteString( W, pmxcontrol.title ); Files.Write( W, CR ); Files.Write( W, NL ); - - WriteString( W, "Tc" ); Files.Write( W, CR ); Files.Write( W, NL ); - - WriteString( W, pmxcontrol.composer ); Files.Write( W, CR ); Files.Write( W, NL ); WriteString( W, "Abepl" ); - Files.Write( W, CR ); Files.Write( W, NL ); i := 0; - WriteString(W,"\\input musixper\"); Files.Write( W, CR ); Files.Write( W, NL ); - WHILE i < nostaves DO - IF clefspec[i] = "p" THEN Out.Ln(); Out.String("percussion");Out.Int(i,5); Out.Char(clefspec[i]); Out.Int(maxpart-i,5); - b.percussionclef( maxpart - i , perclef, perline ); WriteString( W, perclef ); Files.Write( W, CR ); - Files.Write( W, NL ); WriteString( W, perline ); Files.Write( W, CR ); - Files.Write( W, NL ); - - END; - INC( i ); - END; - (* IF pmxcontrol.a3paper THEN *) - WriteString( W, "%%w277m" ); Files.Write( W, CR ); Files.Write( W, NL ); WriteString( W, "%%h390m" ); - Files.Write( W, CR ); Files.Write( W, NL ); - (* END; *) - - - (* Outclef; *) - (* Files.Close( f ); Files.Register( f ); *) - END ControlData; - - - PROCEDURE pmxDirections( idir, dirtypenr: LONGINT; VAR res: ARRAY OF CHAR ); - (* determines the Direction-string to be appended to a note in the PMX file. *) - VAR dirtype: CHAR; - height: ARRAY 3 OF CHAR; - BEGIN - b.loesch( res ); dirtype := directions[idir, dirtypenr].dirtype; - - CASE dirtype OF - "w": - IF (Strings.Length( directions[idir, dirtypenr].text ) > 0) THEN - IF (directions[idir, dirtypenr].note = 0) THEN directions[idir, dirtypenr].note := 1 END; (* &&&&& *) - IF directions[idir, dirtypenr].placement = "h" THEN COPY( "12", height ); - ELSIF directions[idir, dirtypenr].placement = "l" THEN COPY( "-6", height ); - END; - COPY( " \zcharnote{", res ); Strings.Append( res, height ); Strings.AppendCh( res, "}" ); - Strings.AppendCh( res, "{" ); Strings.Append( res, directions[idir, dirtypenr].text ); - Strings.Append( res, "}\" ); - END; - | "d": - - PMXdyn( directions[idir, dirtypenr].dyntype, res ); - | "h": - PMXdyn( directions[idir, dirtypenr].wedgetype, res ); - | "p": - b.loesch( res ); - IF directions[idir, dirtypenr].pedaltype = "start" THEN COPY( " \PED\ ", res ); - ELSIF directions[idir, dirtypenr].pedaltype = "stop" THEN COPY( " \DEP\ ", res ); - END; - | "s": b.loesch(res); COPY (" oG ",res); - - - | "c": b.loesch(res); COPY (" oC ",res); - ELSE Out.Ln(); Out.String( "Direction type " ); Out.Char( dirtype ); Out.String( " not implemented." ) - - END; - END pmxDirections; - - PROCEDURE AnalyzeXML2( VAR R: Files.Rider ); - (* Decodes MusicXML and stores data in a linked list. *) - VAR dummy: ARRAY 256 OF CHAR; (* geaendert von 128. 28.07.2019 *) - rec, rec1: ARRAY 256 OF CHAR; - - tag, endtag, between: ARRAY 256 OF CHAR; - note, voice, staff, savenote, novalues, length: LONGINT; - - names, values: ARRAY 10 OF ARRAY 32 OF CHAR; (* Change 9.11.2016 32->64 *) - - - BEGIN - - attnum := 0; dirnum := 0; part := 0; measure := 0; note := 0; voice := 0; - - (******************** Read XML-Information ****************************) - b.ReadUntilTx( R, ">", pmxcontrol.xml ); Out.Ln(); Out.String( pmxcontrol.xml ); - b.ReadUntilTx( R, NL, dummy ); - - b.ReadUntilTx( R, ">", pmxcontrol.dtd ); Out.Ln(); Out.String( pmxcontrol.dtd ); - b.ReadUntilTx( R, NL, dummy ); - - WHILE ~R.eof (* & ( itags < 10) *) DO (* Loop over tags *) - b.ReadRecn( R, rec, length ); (* Files.Read(R,c); Versuch zur Loesung eines Problems *) - - (* Out.Ln(); Out.String("nach ReadRecn : "); Out.Int(itags,5); Out.Char("|"); Out.String(rec); Out.Char("|"); *) - IF length = 0 THEN Out.Ln(); Out.String("empty record "); - ELSIF length > 0 THEN - - IF ~R.eof & (length > 0) & (rec[Strings.Length( rec ) - 1] # ">") THEN - b.ReadRecn( R, rec1, length ); Strings.AppendCh( rec, BLANK ); Strings.Append( rec, rec1 ); - length := Strings.Length( rec ); - END; - (* Out.Ln(); Out.Int(itags,5); Out.String(" rec : "); Out.String(rec); *) - IF (* (rec[1] # "/") & *) (rec[1] # "!") THEN INC( itags ); - (* problem with lilypond test data *) - IF tag = "<identification>" THEN b.SkipUntilPattern( R, endtag ); END; - (*****************************************************************) - b.AnalyzeTag2( rec, tag, endtag, between, names, values, novalues ); - - (* Out.Ln();Out.Int(zaehler,6); Out.String(rec); Out.String(tag); INC(zaehler); *) - (*+******************************************************************) - (* Out.Ln();Out.Int(itags,5); Out.Char("|");Out.String(tag); *) - - (* IF (tag = printtag) THEN SkipUntilPattern( R, endtag ) END; *) - (* print information not useful for PMX *) - (* Verursacht ABbruch bei bestimmten Scans *) - IF (tag = credittag) THEN b.SkipUntilPattern( R, endtag ) END; (* credit information not useful for PMX *) - IF (tag = defaultstag) THEN b.SkipUntilPattern( R, endtag ) END; - (* defaults information not useful for PMX *) - IF (tag = "<appearance>") THEN b.SkipUntilPattern( R, endtag ) END; - (* appearance information not useful for PMX *) - - - IF (tag = parttag) THEN - INC( part ); COPY( values[0], partlabel[part] ); - (* part := - ORD( values[0, 1] ) - 48; old code, only one digit for part *) - (* ExtractDigits( values[0], digits ); Strings.StrToInt( digits, part ); *) - (* Out.Ln(); Out.String (" global id of part : "); Out.Int(part,5); *) - note := 0; maxpart := b.Max( part, maxpart ); voice := 0; staff := 0; measure := 0; savenote := 0; - staves[part] := 1; - END; - IF (tag = measuretag) THEN - (* Strings.StrToInt( values[0], measure ); *) - IF measure < measurelimit THEN - INC( measure ); lastnote := 0; note := 0; maxnote[part, 1, measure] := 0; - maxnote0[part, 1, measure] := 0; maxnote[part, 2, measure] := 0; voice := 0; - minnote[part, 1, measure] := 100; maxnote0[part, 2, measure] := 0; - minnote[part, 2, measure] := 100; - (* maxnote total count of notes/rests/forwards in part,staff,measure. - maxnote0 total count of notes/rests/forwards in part,staff,measure for voice=0. *) - - - (* Out.Ln(); Out.String (" global id of measure : "); Out.Int(measure,5); *) - maxmeasure := b.Max( measure, maxmeasure ); voice := 0; staff := 0; - (* attnum := 0; dirnum := 0; *) - ELSE Out.Ln(); Out.String( "maximum measure reached; HALT! " ); HALT( 20 ); - END; - END; - IF (tag = stavestag) THEN staves[part] := 1; Strings.StrToInt( between, staves[part] ); END; - IF (tag = directiontag) THEN dirnum := lastdirnum; INC( dirnum ); maxdir := b.Max( maxdir, dirnum ); END; - IF (tag = eodirectiontag) THEN lastdirnum := dirnum; dirnum := 0; END; - (*********************************************************************************) - IF (tag = attributestag) THEN attnum := lastattnum; INC( attnum ); END; - IF (tag = eoattributestag) THEN lastattnum := attnum; attnum := 0; END; - (**********************************************************************************) - IF (tag = notetag) OR (tag = forwardtag) THEN note := lastnote; INC( note ); END; (* Aenderung27. April *) - IF (tag = eonotetag) THEN lastnote := note; note := 0 END; - (**********************************************************************************) - IF (tag = "<forward>") THEN (* <forward ist ein blind rest> *) - note := lastnote; INC( note ); INC( lastnote ); (* Out.Ln(); Out.String( "note after forward " ); - Out.Int( part, 5 ); Out.Int( staff, 5 ); Out.Int( voice, 5 ); Out.Int( measure, 5 ); Out.Int( note, 5 ); *) - b.StoreTag( itags, notetag, eonotetag, part, voice, measure, note, attnum, dirnum, lastnote, novalues, names, values, between ); - (********************************************************************************) - (*************************Store Information in Tag "new"******************************) - INC( itags ); - b.StoreTag( itags, "<rest/>", eonotetag, part, voice, measure, note, attnum, dirnum, lastnote, novalues, names, values, between ); - - INC( itags ); - END; - b.StoreTag( itags, tag, endtag, part, voice, measure, note, attnum, dirnum, lastnote, novalues, names, values, between ); - IF (tag = "</forward>") THEN - INC( itags ); - b.StoreTag( itags, eonotetag, eonotetag, part, voice, measure, note, attnum, dirnum, lastnote, novalues, names, values, between ); - END; - END; - END; - END; - part := 1; - WHILE part <= maxpart DO - nostaves := nostaves + staves[part]; (* Aenderung 5.11.2015 *) - INC( part ); - END; - - END AnalyzeXML2; -(* PROCEDURE ListMeasure*; - VAR i, measure : INTEGER; - BEGIN - Out.Ln(); Out.String("ListMeasure"); Out.Ln(); - - i := 1; WHILE i < maxmeasure DO Out.Ln(); Out.Int(i,5); INC(i); measure := i; - Out.Char( measures[measure].clefchange[1]); - Out.Char( measures[measure].clefchange[2]); - Out.Char( measures[measure].clefchange[3]); - Out.Char( measures[measure].clefchange[4]);END; - END ListMeasure; *) - - - - -BEGIN - COPY( "<part>", parttag ); COPY( "<measure>", measuretag ); COPY( "<attributes>", attributestag ); - COPY( "</attributes>", eoattributestag ); COPY( "<divisions>", divisionstag ); COPY( "<key>", keytag ); - COPY( "<fifths>", fifthstag ); COPY( "<time>", timetag ); COPY( "<beats>", beatstag ); - COPY( "<beat-type>", beattypetag ); COPY( "<staves>", stavestag ); COPY( "<clef>", cleftag ); - COPY( "<sign>", signtag ); COPY( "<line>", linetag ); COPY( "<clef-octave-change>", clefoctavetag ); - COPY( "<note>", notetag ); COPY( "<pitch>", pitchtag ); COPY( "<step>", steptag ); - COPY( "<octave>", octavetag ); COPY( "<duration>", durationtag ); COPY( "<voice>", voicetag ); - COPY( "<type>", typetag ); COPY( "<dot/>", dottag ); COPY( "<stem>", stemtag ); - COPY( "<notations>", notationtag ); COPY( "<lyric>", lyrictag ); COPY( "<syllabic>", syllabictag ); - COPY( "<text>", texttag ); COPY( "<accidental>", accidentaltag ); COPY( "<rest/>", resttag ); - COPY( "<chord/>", chordtag ); COPY( "<backup>", backuptag ); COPY( "<slur>", slurtag ); - COPY( "<staff>", stafftag ); COPY( "<fermata>", fermatatag ); - COPY( "<print>", printtag ); COPY( "<direction>", directiontag ); COPY( "<tied>", tiedtag ); - COPY( "<beam>", beamtag ); COPY( "<tuplet>", tuplettag ); COPY( "<staccato/>", staccatotag ); - COPY( "<words>", wordstag ); COPY( "<repeat>", repeattag ); COPY( "</note>", eonotetag ); - COPY( "</measure>", eomeasuretag ); COPY( "<barline>", barlinetag ); COPY( "<ending>", endingtag ); - COPY( "<line>", cleflinetag ); COPY( "<actual-notes>", actualtag ); COPY( "<normal-notes>", normaltag ); - COPY( "<bar-style>", barstyletag ); COPY( "<dynamics>", dynamicstag ); COPY( "<work>", worktag ); - COPY( "<identification>", identificationtag ); COPY( "<defaults>", defaultstag ); COPY( "<credit>", credittag ); - COPY( "<grace/>", gracetag ); COPY( "</direction>", eodirectiontag ); COPY( "<grace>", gracetag2 ); - COPY("<cue/>",cuetag); - (* initialize notes type conversion XML -> PMX *) - pmxdur[0] := "0"; pmxdur[1] := "2"; pmxdur[2] := "4"; pmxdur[3] := "8"; pmxdur[4] := "1"; pmxdur[5] := "3"; - pmxdur[6] := "6"; pmxdur[7] := "7"; (*128th note ? *) - - (* Initialization of voices count *) - i := 0; j := 0; ingrace2pmx := 0; NEW( directions ); NEW( measures ); NEW( voicemeasure ); - NEW( minvoice ); NEW( maxvoice ); NEW( notes ) ; - - itags := 0; lfdnr := 1; (* outarray(minvoice); *) - (* Initialize tie numbering *) - i := 0; - WHILE i < 24 DO - j := 0; - WHILE j < 10 DO INCL( b.tieunusdnum[i, 0], j ); INCL( b.tieunusdnum[i, 1], j ); INC( j ); END; - INC( i ); - END; - (* Initialization of notes counter *) - - part := 0; - WHILE part < 24 DO - measure := 1; - WHILE measure < measurelimit DO - maxnote[part, 1, measure] := 0; - maxnote[part, 2, measure] := 0; - minnote0[part, 1, measure] := 100; - minnote0[part, 2, measure] := 100; - minnote1[part, 1, measure] := 100; - minnote1[part, 2, measure] := 100; - minnote[part, 1, measure] := 100; - minnote[part, 2, measure] := 100; - - maxnote0[part, 2, measure] := 0; - maxnote0[part, 1, measure] := 0; - maxnote1[part, 2, measure] := 0; - maxnote1[part, 1, measure] := 0; - minvoice[part, measure] := 10; - maxvoice[part, measure] := 0; - INC( measure ); - END; - INC( part ); - END; - unix := TRUE; (* CRLF end of line; for LF end of line set unix := TRUE. *) - b.unix := unix; (* inform MODULE "b" about end of line character. *) - (********************* Read CommandLine ***************) - (* commandO; never activate call externally for Oberon-Version ***********) - (*****************************************************) - (* commandX; *) (* activate for Windows-Exe Version *******) - (**************** ******************************) - CommandU; (* activate for Linux-Binary Version *************) - -END Testbed. |