diff options
Diffstat (limited to 'Build/source/utils/mtx/mtx-0.60d/globals.pas')
-rw-r--r-- | Build/source/utils/mtx/mtx-0.60d/globals.pas | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/Build/source/utils/mtx/mtx-0.60d/globals.pas b/Build/source/utils/mtx/mtx-0.60d/globals.pas new file mode 100644 index 00000000000..ad53376438f --- /dev/null +++ b/Build/source/utils/mtx/mtx-0.60d/globals.pas @@ -0,0 +1,247 @@ +unit globals; + +{ 1. All global variables. + 2. Miscellaneous other procedures required by several Units. +} + +interface + +const PMXlinelength = 128; +{ !!! One or more of the following constants should be reduced if this + program is to be compiled by a 16-bit compiler (e.g. Turbo Pascal), + otherwise you get a "Data segment too large" error } + lines_in_paragraph = 100; + max_words = 128; + max_notes = 128; +{ Christian Mondrup's suggestion to reduce data segment size: + lines_in_paragraph = 50; + max_words = 64; + max_notes = 64; +} + max_bars = 16; + maxstaves = 15; + maxvoices = 15; + maxgroups = 3; + standardPMXvoices = 12; + max_lyrics_line_length = PMXlinelength-4; + inf = 32000; + unspec = 1000; + default_size = 20; + + start_beam = '['; + stop_beam = ']'; + rest = 'r'; + pause = 'rp'; + dotcode = 'd'; + grace_group = 'G'; + multi_group = 'x'; + barsym = '|'; + comment = '%'; + double_comment: string[2] = '%%'; + blank = ' '; + dot = '.'; + comma = ','; + colon = ':'; + tilde = '~'; + atsign = '@'; + dummy = #0; + + ndurs = 8; + durations: string[ndurs] = '90248136'; + unspecified = '5'; { Not a valid duration } + whole = 2; { position of '0' in durations } + terminators: string = '.x'; + digits = '123456789'; + digitsdot = '0123456789.'; + has_duration: string[8] = 'abcdefgr'; + solfa_names: string[7] = 'drmfslt'; + + choice: char = ' '; + outfile_open: boolean = false; + texdir: string = ''; + old_meter_word: string = ''; + outlen: integer = 0; + putspace = true; + nospace = false; + ignore_input: boolean = false; + print = true; + +type + paragraph_index = 1..lines_in_paragraph; + voice_index = 1..maxvoices; + stave_index = 1..maxstaves; + bar_index0 = 0..max_bars; + word_index0 = 0..max_words; + paragraph_index0 = 0..lines_in_paragraph; + voice_index0 = 0..maxvoices; + stave_index0 = 0..maxstaves; + paragraph = array[paragraph_index] of string; + line_nos = array[paragraph_index] of integer; + +var voice_label: array[voice_index] of string; + clef: array[stave_index] of char; + instr, stave, first_on_stave, number_on_stave: + array[stave_index] of voice_index0; + nspace, stave_size: array[stave_index] of integer; + nvoices, nstaves, ninstr, bottom, top: voice_index0; + one_beat, full_bar, line_no, short_note, musicsize, + meternum, meterdenom, pmnum, pmdenom, paragraph_no, + bar_no, pickup, nbars, nleft: integer; + para_len: paragraph_index0; + xmtrnum0: real; + P: paragraph; + orig_line_no: line_nos; + infile, outfile, stylefile: text; + default_duration: char; + fracindent, this_version, this_version_date: string; + pmx_preamble_done, first_paragraph, final_paragraph, must_respace, + must_restyle, multi_bar_rest, some_vocal: boolean; + +procedure error(message: string; printLine: boolean); +procedure fatalerror(message: string); +procedure warning(message: string; printLine: boolean); +function PMXinstr (stave: integer): integer; +procedure setDefaultDuration(meterdenom: integer); +procedure getMeter(line: string; + var meternum, meterdenom, pmnum, pmdenom: integer); +procedure setSpace(line: string); +function meterChange(n1, n2: integer; blind: boolean): string; +function meterWord (num, denom, pnum, pdenom: integer): string; +procedure cancel(var num,denom: integer; lowest: integer); +function isNoteOrRest(w: string): boolean; +function isPause(note: string): boolean; + +implementation uses strings, control, utility; + +function isNoteOrRest(w: string): boolean; +begin isNoteOrRest := pos1(w[1],has_duration)>0; end; + +function isPause(note: string): boolean; +begin isPause:=startsWith(note,pause); end; + +procedure cancel(var num,denom: integer; lowest: integer); +begin while (num mod 2 = 0) and (denom>lowest) do + begin num:=num div 2; denom:=denom div 2; end; +end; + +function meterWord (num,denom,pnum,pdenom: integer): string; +begin meterWord := 'm' + toString(num) + '/' + toString(denom) + + '/' + toString(pnum) + '/' + toString(pdenom); +end; + +function meterChange(n1, n2: integer; blind: boolean): string; + var f, l: integer; +begin + if blind then + begin f:=64; l:=n1 * (64 div n2); + cancel(l,f,meterdenom); meterChange := meterWord (l,f,0,0); + if meternum>0 then + writeln('Blind meter change to ', l, '/', f, ' on line ', line_no); + end + else meterChange := meterWord(n1,n2,0,0); +end; + +procedure setSpace(line: string); + var i: integer; + word: string; + begin i:=0; + while i<ninstr do + begin word:=GetNextWord(line,blank,dummy); + if word='' then exit; + inc(i); getNum(word,nspace[i]); + end; + end; + +procedure onumber (s: string; var j, n1: integer); + begin if s[j]='o' then n1:=1 else if s[j]='1' then + begin n1:=10+digit(s[j+1]); inc(j); end + else n1:=digit(s[j]); + inc(j); + end; + +procedure extractNumber(var s: string; var k: integer); + var w: string; +begin w:=getNextWord(s,'/',dummy); getNum(w,k); +end; + +procedure readMeter (meter: string; + var meternum, meterdenom, pmnum, pmdenom: integer); + var j: integer; +begin if meter[1]='m' then + if pos1('/',meter)=0 then + begin j:=2; onumber(meter,j,meternum); onumber(meter,j,meterdenom); + onumber(meter,j,pmnum); onumber(meter,j,pmdenom); + end + else begin predelete(meter,1); + extractNumber(meter,meternum); extractNumber(meter,meterdenom); + extractNumber(meter,pmnum); extractNumber(meter,pmdenom); + end + else begin getTwoNums(meter, meternum, meterdenom); + pmnum:=meternum; pmdenom:=meterdenom; + end; +end; + +procedure getMeter(line: string; + var meternum, meterdenom, pmnum, pmdenom: integer); + var meter: string; +begin meter:=GetNextWord(line,blank,dummy); + if (meter='C/') or (meter='mC/') then + begin meternum:=2; meterdenom:=2; pmdenom:=5; pmnum:=0; end + else if (meter='C') or (meter='mC') then + begin meternum:=4; meterdenom:=4; pmdenom:=6; pmnum:=0; end + else readMeter(meter,meternum,meterdenom,pmnum,pmdenom); + if meterdenom=0 then Error + (meter+': Meter denominator must be nonzero',print); +end; + +function whereInParagraph(l: integer): integer; + var j: integer; +begin whereInParagraph:=0; + for j:=1 to para_len do if orig_line_no[j]=l then + begin whereInParagraph:=j; exit end; +end; + +procedure fatalerror(message: string); +begin setFeature('ignoreErrors',false); error(message,not print) end; + +procedure error(message: string; printline: boolean); + var j: integer; +begin + writeln (message, ': ERROR on line ', line_no); + j:=whereInParagraph(line_no); if (j>0) and printline then writeln(P[j]); + if not ignoreErrors then + begin if outfile_open then + begin close(outfile); rewrite(outfile); close(outfile); end; + if line_no=0 then line_no:=10000; + halt(line_no); + end; +end; + +procedure warning(message: string; printline: boolean); + var j: integer; +begin + if line_no>0 then + begin writeln (message, ': WARNING on line ', line_no); + if not printline then exit; + j:=whereInParagraph(line_no); if j>0 then writeln(P[j]) + end + else writeln (message, ': WARNING in preamble'); +end; + +function PMXinstr (stave: integer): integer; +begin PMXinstr := ninstr + 1 - instr[stave]; end; + +procedure setDefaultDuration(meterdenom: integer); +begin + case meterdenom of + 1: default_duration:='0'; + 2: default_duration:='2'; + 4: default_duration:='4'; + 8: default_duration:='8'; + 16: default_duration:='1'; + 32: default_duration:='3'; + 64: default_duration:='6'; + end; +end; + +end. |