DIRECTORY Menus USING [Menu], Rope USING [ROPE], Jukebox USING [bytesPerChirp], ViewerClasses USING [Viewer], ViewerEvents USING [EventRegistration], VoiceRope USING [VoiceRopeInterval], TiogaOpsDefs USING [Ref, Location]; VoiceViewers: CEDAR DEFINITIONS = BEGIN VoiceViewerInfo: TYPE = REF VoiceViewerInfoRec; VoiceViewerInfoRec: TYPE = RECORD [ -- the data structure underpinning all voice viewers viewer: ViewerClasses.Viewer, viewerNumber: INT, ropeInterval: VoiceRopeInterval, -- the rope interval represented by the viewer soundList: SoundList, -- a list of the sound/silence intervals in that rope interval remnant: INT, -- the display shows the rope interval using characters representing a fixed amount of time: this is samplesInRope MOD lengthOfACharacterInSamples charMarkList: LIST OF INT _ NIL, -- an ordered list of the characters which have character marks on them textMarkList: LIST OF TextMarkEntry _ NIL, -- see below: list is again ordered ageList: LIST OF IntPair _ NIL, -- see below: each age lasts until the next element in the list, otherwise until the end of the viewer color: BOOLEAN _ FALSE, -- is the viewer currently on the color display? edited: BOOLEAN _ FALSE, -- the true indication whether the voice has been edited: at times may not agree with the viewer's 'edited' flags editInProgress: BOOLEAN _ TRUE, -- set if an initiated edit has yet to complete: this includes all cut/paste operations; input to the viewer; alteration of markers and redrawing operations, since none of these is allowed to occur simultaneously in this implementation. It is created TRUE and only set FALSE once the viewer's contents are valid destroyEvent: ViewerEvents.EventRegistration, changeColumnEvent: ViewerEvents.EventRegistration, parentViewer: ViewerClasses.Viewer _ NIL, -- trace of where the SourceMarker for the viewer is, NIL if no parent positionInParent: TiogaOpsDefs.Location, -- ditto: invalid if parentViewer = NIL nextInfoRec: VoiceViewerInfo _ NIL ]; TextMarkEntry: TYPE = REF TextMarkRec; TextMarkRec: TYPE = RECORD [ position: INT, -- the number of the character to which the text is attached text: Rope.ROPE, -- the text itself displayChars: INT, -- how much of the text can be displayed [without running into the next TextMarkEntry], in characters width: INT -- how much space this display will take, measured in voice character widths ]; IntPair: TYPE = RECORD [ position: INT, age: INT ]; soundRopeCharsPerSecond: NAT = 4; soundRopeCharLength: NAT = Jukebox.bytesPerChirp/soundRopeCharsPerSecond; soundRopeCharDivisions: NAT = 4; -- number of stripes per character; soundRopeResolution: NAT = soundRopeCharLength/soundRopeCharDivisions; voiceViewerMenu: Menus.Menu; voiceViewerInfoList: VoiceViewers.VoiceViewerInfo; VoiceRopeInterval: TYPE = VoiceRope.VoiceRopeInterval; -- RECORD [ropeID: Rope.ROPE, start: INT, length: INT] Selection: TYPE = REF SelectionRec; SelectionRec: TYPE = RECORD -- specification of where to insert voice into a slab: if ropeInterval.length # nil then selection is to be deleted first [ viewer: ViewerClasses.Viewer, voiceViewerInfo: VoiceViewers.VoiceViewerInfo, ropeInterval: VoiceRopeInterval, displayNode: TiogaOpsDefs.Ref ]; SoundInterval: TYPE = REF SoundIntervalRec; SoundIntervalRec: TYPE = RECORD [ ropeInterval: VoiceRopeInterval, soundList: SoundList _ NIL, charMarkList: LIST OF INT _ NIL, textMarkList: LIST OF TextMarkEntry _ NIL ]; SoundList: TYPE = LIST OF Sound; Sound: TYPE = RECORD [ silence: INT, -- a Sound element simply consists of a length of silence sound: INT -- followed by a length of sound - either may legally be zero ]; BuildVoiceViewer: PROC [voiceID: Rope.ROPE, textInVoice: Rope.ROPE, youngVoice: BOOLEAN] RETURNS [viewer: ViewerClasses.Viewer, viewerInfo: VoiceViewerInfo, viewerNumber: INT]; SetViewerContents: PROC [viewer: ViewerClasses.Viewer, viewerInfo: VoiceViewers.VoiceViewerInfo, voiceID: Rope.ROPE, textInVoice: Rope.ROPE, youngVoice: BOOLEAN]; SetParentViewer: PROC [viewerInfo: VoiceViewerInfo, parentViewer: ViewerClasses.Viewer, positionInParent: TiogaOpsDefs.Location]; RemoveParentViewer: PROC [viewerNumber: INT]; SetVoiceViewerEditStatus: PROC [viewer: ViewerClasses.Viewer]; GetVoiceLock: PROC [VoiceViewerInfo] RETURNS [BOOLEAN]; END. ’VoiceViewers.mesa interface to routines to create and delete voice viewers, data structures used in editing them and a monitor routine for locking a viewer against simultaneous attempts to manipulate it Ades, April 29, 1986 5:10:08 pm PDT textual markers are held as a list of the following elements as part of the VoiceViewerInfo; see VoiceMarkersImpl and TextInVoiceImpl for more details aging markers in VoiceViewerInfo are held as a list the following records these constants define how a voice rope maps onto a graphical representation [in fact a rope of characters in special font, each character consisting of a series of black or white vertical stripes] Jukebox.BytesPerChirp is the measure of voice samples per second the menu for all voice viewers the list of all currently existing voice edit windows ------------------------------------ data structures used in editing voice the purpose of the next data object is to keep track of voice which is to be moved to some part of some slab - both a VoiceRopeInterval and a cache of the SoundList, charMarkList and textMarkList which correspond to it ------------------------------------ routines to create and delete voice viewers build a new voice viewer: if voiceID = NIL then leave it with voiceVewerInfo.editInProgress TRUE [used when opening a dictation machine viewer], otherwise then call SetViewerContents, passing on all three parameters set the contents of the viewer to the given voiceRope [voiceID] with the given textual annotations on it [textInVoice] and then make it editable. If youngVoice then set it to youngest edit and age all other voice [see VoiceAging], otherwise create it at maximum age and do not do any aging of other voice called when the referent to the voice viewer is about to be deleted brings the viewer into agreement with the viewerinfo about whether the viewer has been edited this routine is a monitor to prevent more than one manipulation on a voice viewer at a time: this does NOT include playback which is separately monitored: since I haven't made the VoiceViewerInfo an opaque type, dropping a lock is the right of anybody who already holds it and thus is not monitored [belch] ΚJ˜™™ΈJ™#J™——šΟk ˜ Jšœœ˜Jšœœœ˜Jšœœ˜Jšœœ ˜Jšœ œ˜'Jšœ œ˜$Jšœ œ˜#J˜—JšΟn œœ œ˜'J˜Jšœœœ˜/šœœœΟc4˜XIcode˜Kšœœ˜Kšœ!Ÿ.˜OKšœŸ>˜TKšœ œŸ’˜ Kš œœœœœŸG˜hKšœœœœŸ#˜NKšœ œœ œŸf˜†KšœœœŸ0˜HKšœœœŸq˜ŠKšœœœŸΈ˜ΨK˜-K˜2Kšœ%œŸF˜pKšœ)Ÿ'˜PKšœ˜"—Kšœ˜K˜K™–Jšœœœ ˜'šœ œœ˜Jšœ œŸ<˜KJšœ œŸ˜#JšœœŸe˜xJšœœŸL˜W—J˜J˜JšœI™Išœ œœ˜Jšœ œ˜Jšœ˜—J˜J˜K˜K™ΕKšœœ˜!Jšœœ1˜IJšœ@™@JšœœŸ%˜FJšœœ.˜FK˜Kšœ˜K™K˜Kšœ2˜2K™5K™K™$K™%K™Kšœœ Ÿ6˜mJ˜Jšœ œœ˜#JšœœœŸ{˜—˜ J˜.Jšœ ˜ Jšœ˜—J˜J˜JšœΪ™ΪJšœœœ˜+Jšœœœ˜"šœ#˜#Jšœœ˜Jš œœœœœ˜ Kšœœœ˜)—J˜J˜Jšœ œœœ˜ šœœœ˜šœ œŸ:˜KKšœœŸ>˜I—K˜—K™K™$™+K™—KšžœœœœœœKœ˜°Kšœ₯žœ"™ΨK™Kš žœœXœœœ˜’Kšœ°™°K˜Kšžœœl˜K˜Kšžœœœ˜-K™CK™Kšžœœ ˜>K™]K™Kšž œœœœ˜7Kšœ²™²J˜Jšœ˜—…—Ύš