DIRECTORY Beam USING [Remove], Chord USING [RemoveNote], Graphics USING [MoveTo, DrawRectangle, SetTexture], InlineDefs USING [LowHalf], MusicDefs, Note USING [default, DrawHead, DrawTie, Duration, GetBackTie, FindChord, Width], Piece USING [NearestSync], Real USING [Fix], Score USING [GetAccidental, ShowPitch], Sheet USING [FindLine, Height, Map, MapNote], Sync USING [RemoveNote], Utility USING [DrawChar, DrawCubic, DrawLine, FreeNote, FreeSync]; NoteImpl: CEDAR PROGRAM IMPORTS Beam, Chord, Graphics, InlineDefs, MusicDefs, Note, Piece, Real, Score, Sheet, Sync, Utility EXPORTS Note = BEGIN OPEN Graphics, MusicDefs, Note, Utility; Error: SIGNAL; Delta: PUBLIC PROC[n: NotePTR] RETURNS[INTEGER] = { IF show.display#graphical THEN RETURN[0] ELSE RETURN[n.delta + (IF FindChord[n]=NIL THEN 0 ELSE FindChord[n].delta)] }; GetSyncIndex: PUBLIC PROC[a: SyncPTR, p: NotePTR] RETURNS[NAT] = { FOR i: NAT IN [0..syncLength) DO IF a.event[i]=p THEN RETURN[i]; ENDLOOP; ERROR; }; Delete: PUBLIC PROC[n: NotePTR, free: BOOL] = { s: SyncPTR = n.sync; c: ChordPTR = Note.FindChord[n]; Sync.RemoveNote[s, n]; IF c#NIL THEN Chord.RemoveNote[c, n]; IF c=NIL AND n.beam#NIL THEN Beam.Remove[n.beam, n, NIL, NIL]; IF NOT free THEN RETURN; IF s.event[0]=NIL THEN Utility.FreeSync[@n.sync]; Utility.FreeNote[@n]; }; SetAccidental: PUBLIC PROC[n: NotePTR, a: Accidental] = { IF voice AND n.voice#selectedVoice THEN RETURN; flash _ TRUE; SELECT n.pitch MOD 12 FROM 0 => IF a=doubleFlat OR a=sharp THEN RETURN; 1 => IF a=flat OR a=doubleSharp THEN RETURN; 2 => IF a=doubleFlat OR a=natural THEN RETURN; 3 => IF a=flat OR a=sharp THEN RETURN; 4 => IF a=doubleFlat OR a=natural OR a=doubleSharp THEN RETURN; 5 => IF a=flat OR a=sharp THEN RETURN; 6 => IF a=natural OR a=doubleSharp THEN RETURN; 7 => IF a=doubleFlat OR a=sharp THEN RETURN; 8 => IF a=flat OR a=doubleSharp THEN RETURN; 9 => IF a=doubleFlat OR a=natural THEN RETURN; 10=> IF a=flat OR a=sharp THEN RETURN; 11=> IF a=natural OR a=doubleSharp THEN RETURN; ENDCASE; flash _ FALSE; n.spelled _ a; SetDirty[n.sync.time, n.sync.time]; }; SetEmbellishment: PUBLIC PROC[n: NotePTR, e: Embellishment] = { IF voice AND n.voice#selectedVoice THEN RETURN; IF n.rest THEN RETURN; n.embellish _ e; SetDirty[n.sync.time, n.sync.time]; }; Duration: PUBLIC PROC[n: NotePTR, metrenome: INTEGER] RETURNS[d: Time] = { m, t, rem: Time; l: REAL _ 1; b: BeamPTR; IF metrenome#128 THEN m _ Real.Fix[128*(l*256/metrenome)] ELSE m _ 256; d _ SELECT n.value FROM whole=>64, half=>32, quarter=>16, eighth=>8, sixteenth=>4, thirtysecond=>2, ENDCASE=>1; IF n.dotted THEN d _ (d*3)/2; d _ d*m; FOR b _ n.beam, b.beam WHILE b#NIL DO IF b.ntuple=0 THEN LOOP; t _ (d*b.against)/b.ntuple; rem _ d*(b.against)-t*b.ntuple; IF b.sync2.time=n.sync.time THEN d _ t+rem ELSE d _ t; ENDLOOP; }; GetBackTie: PUBLIC PROC[n: NotePTR] RETURNS[t: NotePTR] = { i, j: CARDINAL; start: CARDINAL; IF n=NIL THEN RETURN[NIL]; IF n.sync=NIL THEN RETURN[NIL]; IF ~n.tied THEN RETURN[NIL]; start _ Piece.NearestSync[p: score, t: n.sync.time, notesOnly: TRUE]; FOR i IN [start..scoreLength) DO FOR j IN [0..syncLength) DO IF score[i].event[j]=NIL THEN EXIT; IF score[i].event[j].tie=n THEN RETURN[score[i].event[j]]; ENDLOOP; ENDLOOP; Error; }; Draw: PUBLIC PROC[n: NotePTR, stem: INTEGER] = { two: REAL = 2; flag: NoteValue; x, y, mid, width: INTEGER _ 0; width _ Note.Width[n]; [x, y] _ Sheet.MapNote[n]; Note.DrawHead[n, x, y, x+width+2]; --includes x delta IF n.rest OR NOT show.notehead THEN RETURN; mid _ Sheet.Map[n.sync.time,, n.staff].y+16; FOR i: INTEGER IN [3..9] WHILE y-mid >= i*d DO IF ~n.grace THEN DrawRectangle[context,[x-3, mid+1+i*d],[x+width+3, mid-1+i*d]] ELSE DrawRectangle[context,[x-3, mid+1/two+i*d],[x+width+3, mid-1/two+i*d]] ENDLOOP; FOR i: INTEGER IN [3..9] WHILE mid-y >= i*d DO IF ~n.grace THEN DrawRectangle[context,[x-3, mid+1-i*d],[x+width+3, mid-1-i*d]] ELSE DrawRectangle[context,[x-3, mid+1/two-i*d],[x+width+3, mid-1/two-i*d]] ENDLOOP; IF n.value=whole OR n.value=unknown THEN RETURN; flag _ n.value; IF stem#default -- drawing part of or beam THEN {stem _ (IF n.stemUp THEN stem+1 ELSE stem-1); flag _ quarter} ELSE SELECT TRUE FROM n.grace AND n.stemUp => stem _ y+2*d; n.grace AND ~n.stemUp => stem _ y-2*d; n.stemUp => stem _ MAX[y+(7*d)/2, mid]; ~n.stemUp => stem _ MIN[y-(7*d)/2, mid]; ENDCASE; IF n.stemUp THEN DrawLine[x+width, y, x+width, stem] ELSE DrawLine[x, y, x, stem]; IF n.grace THEN MoveTo[context,[x, IF n.stemUp THEN stem-17 ELSE stem+17]] ELSE MoveTo[context,[x, IF n.stemUp THEN stem-24 ELSE stem+24]]; SELECT TRUE FROM flag=quarter => NULL; n.grace => IF n.stemUp THEN DrawChar[context, 133C] ELSE DrawChar[context, 134C]; flag=eighth => IF n.stemUp THEN DrawChar[context, 153C] ELSE DrawChar[context, 163C]; flag=sixteenth => IF n.stemUp THEN DrawChar[context, 152C] ELSE DrawChar[context, 162C]; flag=thirtysecond => IF n.stemUp THEN DrawChar[context, 151C] ELSE DrawChar[context, 161C]; flag=sixtyfourth => IF n.stemUp THEN DrawChar[context, 151C] ELSE DrawChar[context, 161C]; ENDCASE; }; DrawHead: PUBLIC PROC[n: NotePTR, x, y, dotX: INTEGER] = { inVoice: BOOL; width, dotY: INTEGER; inVoice_ ~(voice AND n.voice#selectedVoice); Graphics.SetTexture[context, IF inVoice THEN black ELSE light]; IF NOT show.notehead THEN {DrawPhysical[n, x, y]; RETURN}; IF n.tie#NIL THEN Note.DrawTie[n]; MoveTo[context,[x, y]]; IF n.grace THEN IF n.rest THEN SELECT n.value FROM ENDCASE => DrawChar[context, 172C] ELSE SELECT n.value FROM ENDCASE => DrawChar[context, 132C] ELSE IF n.rest THEN SELECT n.value FROM whole => {MoveTo[context,[x, y+(IF print THEN -5 ELSE 3)]] ; DrawChar[context, 145C]}; half => {IF print THEN MoveTo[context,[x, y-9]]; DrawChar[context, 145C]}; quarter => DrawChar[context, 144C]; eighth => DrawChar[context, 143C]; sixteenth => DrawChar[context, 142C]; thirtysecond => DrawChar[context, 141C]; ENDCASE => DrawChar[context, 114C] ELSE SELECT n.value FROM whole => DrawChar[context, 156C]; half => DrawChar[context, 155C]; ENDCASE => DrawChar[context, 154C]; width _ Note.Width[n]; IF DottedOnLine[n] THEN dotY _ y+4 ELSE dotY _ y; IF n.dotted THEN { MoveTo[context,[dotX, dotY]]; DrawChar[context, 056C]; dotX _ dotX+3; }; IF n.doubleDotted THEN { MoveTo[context,[dotX, dotY]]; DrawChar[context, 056C]; dotX _ dotX+3; MoveTo[context,[dotX, dotY]]; DrawChar[context, 056C]; }; IF n.embellish#none THEN { sy: INTEGER; sy _ MAX[y, Sheet.Map[n.sync.time,, n.staff].y+28]; IF n.embellish=trill THEN MoveTo[context,[x, sy+10]] ELSE MoveTo[context,[x-2, sy+10]]; SELECT n.embellish FROM trill => DrawChar[context,'U]; mordent1 => DrawChar[context,'V]; mordent2 => DrawChar[context,'W]; ENDCASE; }; IF n.rest OR NOT show.accidental THEN RETURN; x _ x-9+(IF show.display=graphical THEN n.accDelta ELSE 0); MoveTo[context,[x, y]]; SELECT Score.GetAccidental[n] FROM doubleFlat => {MoveTo[context,[x-4, y]]; DrawChar[context, 110C]}; flat => DrawChar[context, 111C]; natural => DrawChar[context, 112C]; sharp => DrawChar[context, 113C]; doubleSharp => DrawChar[context, 114C]; ENDCASE; }; DottedOnLine: PROC[n: NotePTR] RETURNS[BOOL]=INLINE { IF NOT n.dotted THEN RETURN[FALSE]; RETURN[Mod[Sheet.Height[n.sync.time, Score.ShowPitch[n.pitch, n.spelled, 0], n.staff]- Sheet.Height[n.sync.time , , n.staff ], 8]=0]; }; Mod: PROC[k, m: INTEGER] RETURNS[n: INTEGER] = { n _ k MOD m; IF n<0 THEN n _ n+m; }; DrawPhysical: PROC[n: NotePTR, x, y: INTEGER] = { duration: INTEGER; IF n.rest THEN RETURN; IF show.display#physical THEN duration _ InlineDefs.LowHalf[7*(Note.Duration[n, 128]/8)/TF]; IF show.display=physical OR n.value=unknown THEN duration _ n.duration/TF; DrawRectangle[context,[x, y-2],[MIN[x+duration, staffLength+12], y+1]]; }; DrawTie: PUBLIC PROC[n: NotePTR] = { temp: NotePTR; oneTie: BOOL; x1, x2, y1, y2, xe, ye: INTEGER; IF n.sync.time0 THEN y1 _ y1+2 ELSE y1 _ y1-2; IF n.tieHeight>0 THEN y2 _ y2+2 ELSE y2 _ y2-2; IF ABS[n.sync.time-n.tie.sync.time]<28 THEN { x1 _ x1-5; x2 _ x2+5; IF n.tieHeight>0 THEN y1 _ y1+4 ELSE y1 _ y1-4; IF n.tieHeight>0 THEN y2 _ y2+4 ELSE y2 _ y2-4}; IF x1>x2 THEN { oneTie _ FALSE; xe _ staffLength; ye _ y1; } ELSE { oneTie _ TRUE; xe _ x2-2; ye _ y2; }; x1 _ x1 + 10; IF n.tie.sync.time>=begin THEN DrawCubic[x1, y1, xe, ye, n.tieHeight]; IF oneTie THEN RETURN; IF n.sync.time<=endTime THEN { xe _ sheet[Sheet.FindLine[n.sync.time]].x-6; ye _ y2; DrawCubic[xe, ye, x2, y2, n.tieHeight]; }; }; d: CARDINAL = 8; END. DrawStem: PUBLIC PROC[x, y1, y2, stem, staff: INTEGER, stemUp, grace: BOOL, flag: NoteValue] = { n: INTEGER; line: REAL _ 1; IF stem#default -- drawing part of or beam THEN stem _ (IF stemUp THEN stem+1 ELSE stem-1) ELSE {[, middle] _ Sheet.Map[n.sync.time, 1000, n.staff]+16; IF stemUp THEN stem _ MAX[y+(7*d)/2, middle] ELSE stem _ MIN[y-(7*d)/2, middle]}; FOR n IN [3..9] WHILE MAX[head, head2]-middle >= n*d DO DrawRectangle[context,[x-3, middle+line+n*d],[x+w, middle-line+n*d]]; ENDLOOP; FOR n IN [3..9] WHILE middle-MIN[head, head2] >= n*d DO DrawRectangle[context,[x-3, middle+line-n*d],[x+w, middle-line-n*d]]; ENDLOOP; IF flag=whole OR flag=unknown THEN RETURN; MoveTo[context,[x, IF stemUp THEN tail-24 ELSE tail+24]]; SELECT flag FROM eighth => IF stemUp THEN DrawChar[context, 153C] ELSE DrawChar[context, 163C]; sixteenth => IF stemUp THEN DrawChar[context, 152C] ELSE DrawChar[context, 162C]; thirtysecond => IF stemUp THEN DrawChar[context, 151C] ELSE DrawChar[context, 161C]; ENDCASE; IF stemUp THEN x _ x+8; DrawLine[x, head, x, tail]; }; Vector: TYPE = RECORD[x, y: INTEGER]; DisplayAcc: PROC[x, y: INTEGER, n: NotePTR] = { c: Accidental; MoveTo[context,[x, y]]; c _ GetAccidental[n]; SELECT c FROM doubleFlat => { MoveTo[context,[x-4, y]]; DrawChar[context, 110C]; }; flat => DrawChar[context, 111C]; natural => DrawChar[context, 112C]; sharp => DrawChar[context, 113C]; doubleSharp => DrawChar[context, 114C]; ENDCASE; }; |NoteImpl.mesa Copyright (C) 1981, 1984 Xerox Corporation. All rights reserved. Author: John Maxwell last modified: December 18, 1981 8: 51 AM Edited by Doug Wyatt, June 14, 1984 1:07:46 pm PDT **************************************************************************** note procedures **************************************************************************** **************************************************************************** drawing notes **************************************************************************** draw the ledger lines note above mid note below mid draw the stem draw the flag draw notehead (physical, rest, or normal), dot, and accidental x is the left edge of the note, y1 & y2 are the y coordinates of the top and bottom notes of a chord stem is the y coordinate (stem=default is a request for the default stem) note above middle note below middle Ê‹˜šœ ™ Jšœ@™@Jšœ™Jšœ*™*J™2J˜—šÏk ˜ Jšœœ ˜Jšœœ˜Jšœ œ%˜3Jšœ œ ˜J˜ JšœœF˜PJšœœ˜Jšœœ˜Jšœœ˜'Jšœœ"˜-Jšœœ˜Jšœœ5˜BJ˜—Jšœ œ˜Jšœ]˜dJšœ˜ Jšœœœ$˜0J˜Jšœœ˜J˜š Ïnœœœ œœ˜3Jšœœœ˜(Jš œœ œœœœ˜Kšœ˜J˜——š ž œœœœœ˜BJšœœœœœœœœ˜IJšœ˜Jšœ˜J˜—JšœL™LJšœ™JšœL™LJ˜šžœœœœ˜/J˜J˜ J˜Jšœœœ˜%Jšœœœœœœœ˜>Jšœœœœ˜Jšœ œœ˜1J˜Jšœ˜—J˜šž œœœ˜9Jšœœœœ˜/Jšœœ˜ šœ œ˜Jš œœœ œœ˜-Jš œœœœœ˜-Jš œœœ œœ˜/Jš œœœ œœ˜'Jš œœœ œœœ ˜HJš œœœ œœ˜'Jš œœ œœœ˜0Jš œœœ œœ˜-Jš œœœœœ˜-Jš œœœ œœ˜/Jš œœœ œœ˜'Jš œœ œœœ˜/Jšœ˜—Jšœœ˜J˜J˜#Jšœ˜—J˜šžœœœ"˜?Jšœœœœ˜/Jšœœœ˜J˜J˜#Jšœ˜—J˜š žœœœœœ˜KJ˜Jšœœ˜ J˜ Jšœœ%œ ˜Gšœœ ˜J˜,Jšœœ˜*—Jšœ œ ˜J˜šœœœ˜%Jšœ œœ˜J˜J˜Jšœœ œ˜6Jšœ˜—Jšœ˜—J˜šž œœœ œ˜;Jšœœ˜Jšœœ˜Jš œœœœœ˜Jš œœœœœ˜Jšœ œœœ˜Jšœ?œ˜Ešœœ˜ šœœ˜Jšœœœœ˜#Jšœœœ˜:Jšœ˜—Jšœ˜—J˜Jšœ˜—J˜JšœL™LJšœ ™ JšœL™LJ˜šžœœœœ˜0Jšœœ˜J˜Jšœœ˜J˜J˜Jšœ#Ïc˜5Jš œœœœœ˜+Jšœ™J˜,š œœœœœœ ˜™>Jš œœ7œ œœ˜mJšœœœœ˜:Jšœœœ˜"J˜šœ˜ šœœ˜šœœ ˜Jšœ˜"—šœœ ˜Jšœ˜"——šœœ˜šœœ ˜šœ œœœ˜=J˜—šœ œœ˜1J˜—J˜*J˜+J˜+J˜+Jšœ ˜'—šœœ ˜J˜#J˜#Jšœ˜$———J˜Jšœœ œ ˜1šœ œ˜J˜J˜J˜Jšœ˜—šœœ˜J˜EJ˜6Jšœ˜—šœœ˜Jšœœ˜ Jšœœ+˜3Jšœœœ˜Wšœ ˜J˜!J˜!J˜!Jšœ˜—Jšœ˜—Jš œœœœœ˜-Jšœ œœ œ˜;J˜šœ˜"J˜BJ˜#J˜#J˜#J˜)Jšœ˜—Jšœ˜—J˜š ž œœ œœœ˜6Jš œœ œœœ˜#Jšœ˜…Jšœ˜—J˜Jš žœœœœœ˜.Jšœœœœ ˜&J˜šž œœœ˜1Jšœ œ˜Jšœœœ˜šœœ ˜)Jšœ/œ˜3—Jšœœœœ˜JJšœ œ$˜GJšœ˜—J˜šžœœœ˜$J˜Jšœœ˜ Jšœœ˜ šœœŸ˜6J˜Jšœœ ˜.Jšœœ˜"J˜J˜ Jšœ˜—J˜