-- Author: John Maxwell
-- Last Edited by: Maxwell, November 22, 1983 12:06 pm
DIRECTORY
MusicDefs: FROM "MusicDefs";
Event: DEFINITIONS IMPORTS MusicDefs =
BEGIN
OPEN MusicDefs;
Draw: PROCEDURE[score: ScorePTR, event: EventPTR];
Invisible: PROCEDURE[score: ScorePTR, index: CARDINAL, leftEdge: Time]
RETURNS[BOOLEAN]; -- Hidden
GetScoreIndex: PROCEDURE[score: ScorePTR, event: EventPTR] RETURNS[index: CARDINAL];
-- returns score.length if not found (score[score.length] is always NIL)
-- ************************************************
-- Type coersion
-- ************************************************
Sync: PROC[e: EventPTR] RETURNS[SyncPTR] = INLINE
{RETURN[IF e # NIL AND e.type = sync THEN LOOPHOLE[e] ELSE NIL]};
TimeSignature: PROC[e: EventPTR] RETURNS[LONG POINTER TO EventRec.timeSignature] =
INLINE {RETURN[IF e # NIL AND e.type = timeSignature THEN LOOPHOLE[e] ELSE NIL]};
KeySignature: PROC[e: EventPTR] RETURNS[LONG POINTER TO EventRec.keySignature] =
INLINE{RETURN[IF e # NIL AND e.type = keySignature THEN LOOPHOLE[e] ELSE NIL]};
Measure: PROC[e: EventPTR] RETURNS[LONG POINTER TO EventRec.measure] = INLINE
{RETURN[IF e # NIL AND e.type = measure THEN LOOPHOLE[e] ELSE NIL]};
Metrenome: PROC[e: EventPTR] RETURNS[LONG POINTER TO EventRec.metrenome] = INLINE
{RETURN[IF e # NIL AND e.type = metrenome THEN LOOPHOLE[e] ELSE NIL]};
Staves: PROC[e: EventPTR] RETURNS[StavesPTR] = INLINE
{RETURN[IF e # NIL AND e.type = staves THEN LOOPHOLE[e] ELSE NIL]};
-- ************************************************
-- Procedures that only apply to staves
-- ************************************************
Octava: PROC[event: EventPTR] RETURNS[BOOLEAN] = INLINE
{WITH ev: event SELECT FROM
staves => RETURN[ev.staves IN [octava1..octava2]];
ENDCASE => RETURN[FALSE]};
Clef: PROC[event: EventPTR] RETURNS[BOOLEAN] = INLINE
{WITH ev: event SELECT FROM
staves => RETURN[ev.staves = clef];
ENDCASE => RETURN[FALSE]};
GetOctava: PROCEDURE[score: ScorePTR, octava: StavesPTR] RETURNS[other: StavesPTR];
SetStave: PROCEDURE[score: ScorePTR, oldS, newS: StavesPTR]; -- copy info from old to new
GetStaff: PROCEDURE[staves: StavesPTR, staff: CARDINAL] RETURNS[LONG POINTER TO Staff] = INLINE {RETURN[@staves.staff[staff]]};
-- ************************************************
-- Procedures that only apply to syncs
-- ************************************************
AddNote: PROCEDURE[score: ScorePTR, sync: SyncPTR, note: NotePTR]
RETURNS[new: SyncPTR]; -- may create a new sync
RemoveNote: PROCEDURE[score: ScorePTR, sync: SyncPTR, note: NotePTR, free: BOOLEAN ← FALSE];
-- removes note from sync. If sync.length = 0 and free = TRUE, then sync is freed.
Adjust: PROCEDURE[score: ScorePTR, s: SyncPTR]; -- space the notes so they don't overlap
NewSync: PROC[score: ScorePTR, length: CARDINAL ← 12, old: SyncPTR ← NIL]
RETURNS[sync: SyncPTR]; -- frees old after copying data
Free: PROC[score: ScorePTR, event: EventPTR];
-- removes sync from anything that points to it, then frees it.
-- INLINE Procedures
AddTimes: PROCEDURE[event: EventPTR, time, toc: Time] = INLINE { -- add times to notes
sync: SyncPTR;
event.time ← event.time + time;
IF event.type = sync THEN sync ← Sync[event] ELSE RETURN;
FOR i: CARDINAL IN [0..sync.length) DO
sync.note[i].toc ← sync.note[i].toc + toc;
ENDLOOP};
Grace: PROCEDURE[sync: SyncPTR] RETURNS[BOOLEAN] = INLINE
{FOR j: CARDINAL IN [0..sync.length) DO
IF ~sync.note[j].grace THEN RETURN[FALSE];
ENDLOOP;
RETURN[TRUE]};
InVoice: PROCEDURE[sync: SyncPTR, voice: CARDINAL] RETURNS[BOOLEAN] = INLINE
{FOR j: CARDINAL IN [0..sync.length) DO
IF sync.note[j].voice = voice THEN RETURN[TRUE];
ENDLOOP;
RETURN[FALSE]};
-- Length: PROC[sync: SyncPTR] RETURNS[CARDINAL] = INLINE {RETURN[s.length]};
END..