-- Author: John Maxwell
-- Last Edited by: Maxwell, November 18, 1983 1:33 pm
DIRECTORY
MusicDefs: FROM "MusicDefs",
Real USING [FixI],
Sheet USING [Height];
Beam: DEFINITIONS IMPORTS MusicDefs, Real, Sheet =
BEGIN
OPEN MusicDefs;
Draw: PROCEDURE[score: ScorePTR, b: BeamPTR] RETURNS[INTEGER, INTEGER];
Drawn: PROCEDURE[score: ScorePTR, b: BeamPTR] RETURNS[BOOLEAN];
AddItem: PROCEDURE[score: ScorePTR, beam: BeamPTR, item: VariousPTR]
RETURNS[new: BeamPTR]; -- may need to create a new beam
RemoveItem: PROCEDURE[score: ScorePTR, beam: BeamPTR, item: VariousPTR,
free: BOOLEAN ← TRUE];
-- removes item from beam.
-- If beam.length < 2 and free = TRUE, then beam is freed.
New: PROC[score: ScorePTR, length: CARDINAL, old: BeamPTR ← NIL]
RETURNS[beam: BeamPTR]; -- copies from old and then frees it
Free: PROC[score: ScorePTR, b: BeamPTR];
-- removes beam from anything that points to it, then frees it.
Grace: PROCEDURE[b: BeamPTR] RETURNS[BOOLEAN];
InVoice: PROCEDURE[b: BeamPTR, voice: CARDINAL] RETURNS[BOOLEAN];
SetStems: PROCEDURE[sheet: SheetPTR, b: BeamPTR];
SetSyncs: PROCEDURE[b: BeamPTR];
GetSyncs: PROCEDURE[b: BeamPTR] RETURNS[sync1, sync2: SyncPTR];
-- returns the first and last sync in the beam (may recurse down nested beams)
Sort: PROCEDURE[b: BeamPTR];
-- inline procedures
GetHeapIndex: PUBLIC PROC[heap: BeamHeapPTR, p: BeamPTR] RETURNS[CARDINAL] = INLINE
{FOR i: CARDINAL IN [0..heap.length) DO
IF heap.beam[i] = p THEN RETURN[i];
ENDLOOP;
RETURN[heap.length]};
Height: PROCEDURE[sheet: SheetPTR, b: BeamPTR, time: Time] RETURNS[h: INTEGER] = INLINE
{sync1: SyncPTR ← GetSyncs[b].sync1;
h ← b.height+Sheet.Height[sheet, sync1.time, , b.staff];
IF time # sync1.time THEN h ← h + Real.FixI[(time-sync1.time)*b.tilt]};
Length: PROC[b: BeamPTR] RETURNS[CARDINAL] = INLINE {RETURN[b.length]};
time: PUBLIC PROCEDURE[chord: VariousPTR] RETURNS[Time] = INLINE
{WITH ev: chord SELECT FROM
note => RETURN[ev.n.sync.time];
chord => RETURN[ev.c.note[0].sync.time];
beam => {sync1: SyncPTR ← GetSyncs[ev.b].sync1;
RETURN[IF sync1 # NIL THEN sync1.time ELSE 0]};
ENDCASE => ERROR};
END..