home *** CD-ROM | disk | FTP | other *** search
- UNIT SongUtils;
-
- INTERFACE
-
- USES SongUnit, SongElements;
-
-
-
-
- {----------------------------------------------------------------------------}
- { Definitions for accelerating the use of note periods. }
- {____________________________________________________________________________}
-
- CONST
- NumberOctaves = 7;
- NumberNotes = 12;
- NumberPeriods = NumberOctaves * NumberNotes;
-
- TYPE
- TPeriodSet = ARRAY[0..NumberOctaves-1] OF { Octave }
- ARRAY[0..NumberNotes -1] OF WORD; { Note }
-
- TPeriodArray = ARRAY[0..NumberPeriods - 1] OF WORD;
-
- CONST
- { The different note values. }
-
- PeriodSet : TPeriodSet = (
- { C C# D D# E F F# G G# A A# B }
- ($06B0,$0650,$05F5,$05A0,$054F,$0503,$04BB,$0477,$0436,$03FA,$03C1,$038B),
- ($0358,$0328,$02FB,$02D0,$02A7,$0281,$025D,$023B,$021B,$01FD,$01E0,$01C5),
- ($01AC,$0194,$017D,$0168,$0154,$0141,$012F,$011E,$010E,$00FE,$00F0,$00E3),
- ($00D6,$00CA,$00BF,$00B4,$00AA,$00A0,$0097,$008F,$0087,$007F,$0078,$0071),
- ($006B,$0065,$005F,$005A,$0055,$0050,$004C,$0047,$0043,$0040,$003C,$0039),
- ($0035,$0032,$0030,$002D,$002A,$0028,$0026,$0024,$0022,$0020,$001E,$001C),
- ($001B,$0019,$0018,$0016,$0015,$0014,$0013,$0012,$0011,$0010,$000F,$000E)
- );
-
- { The different inter-note values. }
-
- PeriodDiff : TPeriodSet = (
- ($0680,$0622,$05CA,$0577,$0529,$04DF,$0499,$0456,$0418,$03DD,$03A6,$0371),
- ($0340,$0311,$02E5,$02BB,$0294,$026F,$024C,$022B,$020C,$01EE,$01D2,$01B8),
- ($01A0,$0188,$0172,$015E,$014A,$0138,$0126,$0116,$0106,$00F7,$00E9,$00DC),
- ($00D0,$00C4,$00B9,$00AF,$00A5,$009B,$0093,$008B,$0083,$007B,$0074,$006E),
- ($0068,$0062,$005C,$0057,$0052,$004E,$0049,$0045,$0041,$003E,$003A,$0037),
- ($0033,$0031,$002E,$002B,$0029,$0027,$0025,$0023,$0021,$001F,$001D,$001B),
- ($001A,$0018,$0017,$0015,$0014,$0013,$0012,$0011,$0010,$000F,$000E,$000E)
- );
-
- VAR
- PeriodArray : TPeriodArray ABSOLUTE PeriodSet;
-
- TYPE
- TNoteString = STRING[3];
-
- TNoteSet = ARRAY[0..2047] OF WORD;
- TNoteStringSet = ARRAY[0..NumberPeriods] OF TNoteString;
-
- VAR
- NoteIdx : TNoteSet; { For each period, specifies its closest note, in two ways: }
- { Hi byte: octave in the hi nibble and note in the low nibble. }
- { Low byte: sequential note for indexing. }
-
- NoteStr : TNoteStringSet; { The strings for each note (e.g. 'A#2'). }
-
-
-
-
- FUNCTION SwapLong (l: LONGINT) : LONGINT;
- PROCEDURE NoteFreq (f: WORD; VAR s: TNoteString);
-
- PROCEDURE InitModVideoTables;
- PROCEDURE InitModUnit;
-
- FUNCTION FullNotesEqual (VAR fn1, fn2: TFullNote) : BOOLEAN;
-
-
-
- IMPLEMENTATION
-
-
-
-
-
- FUNCTION SwapLong(l: LONGINT) : LONGINT;
- VAR
- w : ARRAY[0..1] OF WORD ABSOLUTE l;
- r : WORD;
- BEGIN
- r := SWAP(w[0]);
- w[0] := SWAP(w[1]);
- w[1] := r;
- SwapLong := l;
- END;
-
-
-
-
- PROCEDURE NoteFreq(f: WORD; VAR s: TNoteString);
- BEGIN
- IF f > 2047 THEN
- f := 2047;
-
- s := NoteStr[NoteIdx[f] AND $FF];
- { STR(f, s);}
- END;
-
-
-
-
- {----------------------------------------------------------------------------}
- { Initialization routines. }
- {____________________________________________________________________________}
-
- PROCEDURE InitModUnit;
- VAR
- l : LONGINT;
- f,
- o, i : WORD;
- LABEL
- Octava, NextFreq;
- BEGIN
- FOR f := 0 TO 2047 DO BEGIN
-
- FOR o := 0 TO 6 DO
- IF f > PeriodDiff[o][11] THEN GOTO Octava;
- i := 0; o := 0;
- GOTO NextFreq;
-
- Octava:
- FOR i := 0 TO 11 DO
- IF f > PeriodDiff[o][i] THEN GOTO NextFreq;
- i := 0; o := 0;
-
- NextFreq:
- NoteIdx[f] := (o*16+i)*256 + (o*12+i)
-
- END;
- END;
-
-
-
-
- PROCEDURE InitModVideoTables;
- CONST
- NoteLet : STRING[12] = 'CCDDEFFGGAAB';
- NoteSus : STRING[12] = ' # # # # # ';
- VAR
- o, i : WORD;
- s : STRING[3];
- BEGIN
- FOR i := 0 TO 12*7-1 DO BEGIN
- s[0] := CHR(3);
- o := i DIV 12;
- s[3] := CHR(o + ORD('0'));
- o := i MOD 12 + 1;
- s[1] := NoteLet[o];
- s[2] := NoteSus[o];
-
- NoteStr[i] := s;
- END;
-
- NoteStr[12*7] := '---';
- END;
-
-
-
-
- FUNCTION FullNotesEqual (VAR fn1, fn2: TFullNote) : BOOLEAN;
- TYPE
- TFNArray = ARRAY[1..SizeOf(TFullNote)] OF BYTE;
- VAR
- fna1 : TFNArray ABSOLUTE fn1;
- fna2 : TFNArray ABSOLUTE fn2;
- i : WORD;
- BEGIN
- FullNotesEqual := FALSE;
- FOR i := 1 TO SizeOf(TFullNote) DO
- IF fna1[i] <> fna2[i] THEN EXIT;
- FullNotesEqual := TRUE;
- END;
-
-
-
-
- END.