-- MusicDefs.mesa -- Author: John Maxwell -- Last Edited by: Maxwell, November 22, 1983 12:46 pm -- This module gives the types used internally by the editor. -- MusicFileDefs gives the types used externally in the file format. DIRECTORY Graphics USING [Context, FontRef, PaintMode, SetPaintMode, SetStipple], KeyboardFace USING [keyboard], MouseFace USING [buttons], MusicFileDefs; MusicDefs: DEFINITIONS IMPORTS Graphics, KeyboardFace, MouseFace = BEGIN Error: SIGNAL[s: STRING]; Notify: SIGNAL[s: STRING]; -- **************************************************************************** -- the basic music types -- **************************************************************************** ScorePTR: TYPE = LONG POINTER TO ScoreRec; ScoreRec: TYPE = RECORD [ name: LONG STRING ← NIL, -- name of the score beamHeap: BeamHeapPTR ← NIL, -- collection of beams chordHeap: ChordHeapPTR ← NIL, -- collection of chords cache: CachePTR ← NIL, -- current key, time signature, etc. sheet: SheetPTR ← NIL, -- cached information about the sheet (derived from the piece) style: StylePTR ← NIL, -- maxVoice: CARDINAL ← 0, -- index of the highest numbered voice command: BOOLEAN ← FALSE, -- we have a new command flash: BOOLEAN ← FALSE, -- flash the screen for an error length: CARDINAL ← 0, -- length of score event: SEQUENCE max: CARDINAL OF EventPTR]; -- collection of events -- endOfScore: CARDINAL = LAST[CARDINAL]; ScorePortionPTR: TYPE = LONG POINTER TO ScorePortionRec; ScorePortionRec: TYPE = RECORD[ -- a portion of a score. score: ScorePTR ← NIL, toc: Time ← 0, -- length of portion in seconds of playing time. duration: Time ← 0, -- length in portion in pixels on the screen. -- duration = 0 means score is from synthesizer (ignore ss1 and ss2). ss1, ss2: ScoreState ← []]; -- state of score at beginning and end ScoreStatePTR: TYPE = LONG POINTER TO ScoreState; ScoreState: TYPE = RECORD[ key: INTEGER ← 0, style: CARDINAL ← 1, staff: ARRAY [0..4) OF Staff ← ALL[[]]]; EventPTR: TYPE = LONG POINTER TO EventRec; EventRec: TYPE = RECORD[ time: Time ← 0, -- measured in pixels from beginning of piece variant: SELECT type: EventType FROM sync => [length: CARDINAL ← 0, -- actual length of the sequence note: SEQUENCE max: CARDINAL OF NotePTR], -- collection of notes measure => [measure: MeasureType ← measure, eol: BOOLEAN ← FALSE], -- eol = force to end of line timeSignature => [ts: TimeSignature ← [4,4]], keySignature => [key: INTEGER ← 0], metrenome => [metrenome: INTEGER ← 128], staves => [ -- marks a change in staffing staves: StavesType ← style, height: INTEGER ← 0, offset: INTEGER ← 0, value: CARDINAL ← 0, -- index of the staff OR style number length: [0..4] ← 4, -- number of staffs in following array staff: ARRAY [0..4) OF Staff ← ALL[[]]], ENDCASE]; Time: TYPE = LONG INTEGER; SyncPTR: TYPE = LONG POINTER TO sync EventRec; -- 'sync' comes from 'synchronize' StavesPTR: TYPE = LONG POINTER TO staves EventRec; StavesType: TYPE = {style, clef, octava1, octava2}; EventType: TYPE = MACHINE DEPENDENT {sync (0), measure (1), timeSignature (7), keySignature (8), metrenome (9), staves (10), spare14 (31)}; MeasureType: TYPE = {measure, repeat1, repeat2, endMeasure, doubleMeasure, m5}; TimeSignature: TYPE = RECORD [top, bottom: [0..32)]; NotePTR: TYPE = LONG POINTER TO NoteRec; NoteRec: TYPE = MACHINE DEPENDENT RECORD[ sync: SyncPTR ← NIL, -- pointer back to sync beam: BeamPTR ← NIL, -- pointer back to beam chord: ChordPTR ← NIL, -- pointer back to chord pitch: INTEGER ← 44, -- pitch of the note voice: CARDINAL ← 0, -- the voice that this note belongs to value: NoteValue ← unknown, -- what is the logical value of this note? spelled: Accidental ← inKey, -- does this note have an explicit spelling on it? rest: BOOLEAN ← FALSE, -- is this a rest note? dotted: BOOLEAN ← FALSE, -- is this note dotted? doubleDotted: BOOLEAN ← FALSE, -- is this note double dotted? grace: BOOLEAN ← FALSE, -- is this a grace note? stemUp: BOOLEAN ← TRUE, -- is the stem up or down? spare1: BOOLEAN ← FALSE, embellish: Embellishment ← none, -- does this note have an embellishment on it? tied: BOOLEAN ← FALSE, -- is this the second note of a tied note? tie: NotePTR ← NIL, -- pointer to the second note of a tie tieHeight: INTEGER ← 0, -- the height of said tie show: BOOLEAN ← FALSE, shown: Accidental ← inKey, -- the accidental displayed on the screen (cached) spare: [0..256) ← 0, staff: [0..16) ← 1, -- the index of the staff that this note is on delta: [-128..128) ← 0, -- how far to move the note relative to the sync accDelta: [-128..128) ← 0, -- how far to move the accidental relative to the sync toc: LONG CARDINAL ← 0, -- physical-note time of occurance (in clock pulses) duration: CARDINAL ← 0]; -- physical-note duration (in clock pulses) NoteValue: TYPE = MusicFileDefs.NoteValueFormat; Accidental: TYPE = MusicFileDefs.AccidentalFormat; Embellishment: TYPE = MusicFileDefs.EmbellishmentFormat; PhysicalNote: TYPE = RECORD[ pitch: INTEGER ← 0, duration: CARDINAL ← 0, loudness: CARDINAL ← 0, toc: LONG CARDINAL ← 0]; --toc is the physical time of occurrance ChordPTR: TYPE = LONG POINTER TO ChordRec; ChordRec: TYPE = RECORD[ stemUp: BOOLEAN ← TRUE, delta: INTEGER ← 0, -- offset from center line of sync (cached) length: CARDINAL ← 0, -- length of note sequence note: SEQUENCE max: CARDINAL OF NotePTR]; BeamPTR: TYPE = LONG POINTER TO BeamRec; BeamRec: TYPE = RECORD[ tilt: REAL, -- tilt of beam beamed: BOOLEAN ← TRUE, -- does the beam show, or do you use brackets instead? ntuple, against: [0..128) ← 1, -- for ntupled beams; the ratio is what is important sync1, sync2: SyncPTR ← NIL, -- first and last sync in beam (cached) beam: BeamPTR ← NIL, -- beam that this beam belongs to height: INTEGER ← 0, -- height of beam from top of left-most note invisible: BOOLEAN ← FALSE, length: [0..1024) ← 0, -- length of chord sequence staff: [0..32) ← 0, -- graphical information chord: SEQUENCE max: CARDINAL OF VariousPTR]; VariousPTR: TYPE = RECORD[SELECT type: {note,chord,beam} FROM note => [n: NotePTR], chord=> [c: ChordPTR], beam=>[b: BeamPTR], ENDCASE]; endOfBeam: VariousPTR; -- saves a call to CodeBlockEqualLong -- ****************************************************************************** -- other types -- ****************************************************************************** BeamHeapPTR: TYPE = LONG POINTER TO BeamHeapRec; BeamHeapRec: TYPE = RECORD[ length: CARDINAL ← 0, beam: SEQUENCE max: CARDINAL OF BeamPTR]; ChordHeapPTR: TYPE = LONG POINTER TO ChordHeapRec; ChordHeapRec: TYPE = RECORD[ length: CARDINAL ← 0, chord: SEQUENCE max: CARDINAL OF ChordPTR]; CachePTR: TYPE = LONG POINTER TO CacheRec; CacheRec: TYPE = RECORD[ -- all of the structural (non-sync) events beamQueueLength: CARDINAL ← 0, beamQueue: ARRAY [0..3) OF BeamPTR ← ALL[NIL], -- drawn beams key1, key2: LONG POINTER TO EventRec.keySignature ← NIL, -- bracketing keys ts1, ts2: LONG POINTER TO EventRec.timeSignature ← NIL, -- bracketing time signatures met1, met2: LONG POINTER TO EventRec.metrenome ← NIL];-- bracketing metrenomes SheetPTR: TYPE = LONG POINTER TO SheetRec; SheetRec: TYPE = RECORD[ context: Graphics.Context ← NIL, voice: CARDINAL ← noVoice, -- currently selected voice top: INTEGER ← 0, -- the y position of the top of the score (for scrolling) begin, endTime: Time ← 0, -- start and end of the part of the score that is currently visible dirty1, dirty2: Time ← 0, -- the portion of the score that needs to be repainted scale: INTEGER ← 1, -- normal, hardcopy and overview density: INTEGER ← 256, -- scale factor in physical mode. justification: INTEGER ← 1, -- density of justification. used in graphical mode. accidental: BOOLEAN ← TRUE, notehead: BOOLEAN ← TRUE, sync: BOOLEAN ← FALSE, display: DisplayMode ← graphical, noCarry: BOOLEAN ← FALSE, hardcopy: BOOLEAN ← FALSE, -- display in hardcopy mode printing: BOOLEAN ← FALSE, -- we are printing instead of displaying width: INTEGER ← 550, -- width of staff current: CARDINAL ← 0, -- current section index length: CARDINAL ← 0, -- length of sheet sequence section: SEQUENCE max: CARDINAL OF Section]; -- sequence of sections Section: TYPE = RECORD[ time: Time ← 0, -- actual time of beginning of section. (may be different from staves.time) x, y: INTEGER ← 0, -- position of the lower left corner of the section page: INTEGER ← 0, -- the page that this section is on key: INTEGER ← 0, -- the key for this section staves: StavesPTR ← NIL]; noVoice: CARDINAL = 1000; StylePTR: TYPE = LONG POINTER TO StyleRec; StyleRec: TYPE = RECORD[ length: CARDINAL ← 0, style: SEQUENCE max: CARDINAL OF StavesPTR]; Staff: TYPE = MusicFileDefs.Staff; SelectionPTR: TYPE = LONG POINTER TO SelectionRec; SelectionRec: TYPE = RECORD[ lineSelect: BOOLEAN ← FALSE, -- line selection or note selection? score: ScorePTR ← NIL, -- score of primary selection or note selection select1, select2: Time ← 0, -- line selected score2: ScorePTR ← NIL, -- score of secondary selection greySelect1, greySelect2: Time ← 0, -- secondary line selection length: CARDINAL ← 0, -- length of note selection note: SEQUENCE max: CARDINAL OF NotePTR]; -- notes selected DisplayMode: TYPE = MusicFileDefs.DisplayModeFormat; ObjectType: TYPE = {measure, note, leftBeam, rightBeam, tie}; LookCommand: TYPE = {accidental, graphical, hardcopy, justified, logical, noCarry, notehead, overview, physical, style, sync, voice}; -- chordLength: CARDINAL = 10; -- syncLength: CARDINAL = 13; -- beamLength: CARDINAL = 16; sheetLength: CARDINAL= 350; maxScoreLength: CARDINAL = MAX[maxPieceLength,3000]; --6000 maxPieceLength: CARDINAL = 1000; maxBeamHeapLength: CARDINAL = 1000; --2000 maxChordHeapLength: CARDINAL = 1000; --2000 maxSelectionLength: CARDINAL = 100; --****************************************************************************** --global variables --****************************************************************************** -- style: ARRAY [0..20] OF Staves; --view on score -- TF: CARDINAL; ++ "Time Factor" = horizontal scale of score on sheet. -- scale,staffLength,top: INTEGER; --return info for commands -- min,max: Time; ++ extent of change -- command,flash: BOOLEAN; ++ flash = "error" --graphics -- context: Graphics.Context; text,music: Graphics.FontRef; -- print: BOOLEAN; --communicating with the synthesizer dataStructureInFlux: BOOLEAN; playing,listening: READONLY BOOLEAN; --data storage zone: UNCOUNTED ZONE; -- **************************************************************************** -- INLINE Procedures -- **************************************************************************** white: CARDINAL = 000000B; light: CARDINAL; grey: CARDINAL = 122645B; black: CARDINAL = 177777B; Measure: PROC[event: EventPTR] RETURNS[BOOLEAN] = INLINE {IF event.type = measure THEN RETURN[TRUE]; IF event.type = staves THEN WITH ev: event SELECT FROM staves => RETURN[ev.staves = style]; ENDCASE; RETURN[FALSE]}; EndOfScore: PROCEDURE[score: ScorePTR] RETURNS[Time] =INLINE {IF score.length#0 THEN RETURN[score.event[score.length-1].time+40] ELSE RETURN[10]}; LMod: PROCEDURE[m,n: Time] RETURNS[k: Time] = INLINE {k ← m - n*(m/n); IF k>n THEN k ← k+n}; Mod: PROCEDURE[m,n: INTEGER] RETURNS[k: INTEGER] = INLINE {k ← m MOD n; IF k<0 THEN k ← k+n}; SetBrush: PROCEDURE[score: ScorePTR, tex: CARDINAL, pnt: Graphics.PaintMode] = INLINE {Graphics.SetStipple[score.sheet.context,tex]; [] ← Graphics.SetPaintMode[score.sheet.context,pnt]}; SetDirty: PROCEDURE[score: ScorePTR, begin,end: Time] = INLINE {score.sheet.dirty1 ← MIN[score.sheet.dirty1, begin]; score.sheet.dirty2 ← MAX[score.sheet.dirty2, end]}; -- ************************************************************************* -- mouse and keyboard -- ************************************************************************* AnyBug: PROCEDURE RETURNS[BOOLEAN] = INLINE {RETURN[RedBug[] OR BlueBug[] OR YellowBug[]]}; RedBug: PROCEDURE RETURNS[BOOLEAN] = INLINE {RETURN[MouseFace.buttons[Mouse1] = down]}; YellowBug: PROCEDURE RETURNS[BOOLEAN] = INLINE {RETURN[MouseFace.buttons[Mouse2] = down]}; BlueBug: PROCEDURE RETURNS[BOOLEAN] = INLINE {RETURN[MouseFace.buttons[Mouse3] = down]}; Shift: PROCEDURE RETURNS[BOOLEAN] = INLINE {RETURN[ KeyboardFace.keyboard[57] = down OR -- A5 KeyboardFace.keyboard[76] = down]}; -- A6 Control: PROCEDURE RETURNS[BOOLEAN] = INLINE {RETURN[KeyboardFace.keyboard[52] = down]}; -- L11 END.