-- 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..