<> <> <> <> <> <> <> <> DIRECTORY BluejayTool, Containers USING [Container], Graphics USING [black, Color, white], IO USING [int, PutFR], Jukebox USING [bytesPerChirp], Process USING [Detach, MsecToTicks, Pause], PupDefs USING [PupSocket], Rules USING [Create, Set], VFonts USING [FontHeight, StringWidth], ViewerTools USING [MakeNewTextViewer, SetContents], VoiceStream; VoiceStreamMonitor: MONITOR LOCKS Lock IMPORTS IO, Process, Rules, VFonts, ViewerTools, VoiceStream EXPORTS BluejayTool, VoiceStream SHARES VoiceStream = BEGIN OPEN VoiceStream; masterSwitch: BOOL _ FALSE; EnableViewerUpdates: PUBLIC PROC [enable: BOOL _ TRUE] = { IF masterSwitch = enable THEN RETURN; masterSwitch _ enable; IF masterSwitch THEN Process.Detach[FORK monitor[]]; }; StartMonitor: PUBLIC PROCEDURE[container: Containers.Container, y: INT] RETURNS [newY: INT] = <> <> BEGIN lineHeight: INT _ VFonts.FontHeight[] + 3; playbackWidth: INT _ VFonts.StringWidth["Recording:"] + 20; pieceWidth: INT _ VFonts.StringWidth["XXXX[00000000:00000000]"]; [] _ Rules.Create[info: [parent: container, wx: 0, wy: y, ww: 1024, wh: 1, border: FALSE]]; y _ y+2; FOR i:INTEGER IN [0..nMonEntries) DO MonEntries[i].handle _ NIL; MonEntries[i].new _ TRUE; MonEntries[i].playbackViewer _ ViewerTools.MakeNewTextViewer[ info: [parent: container, wx: 0, wy: y, wh: lineHeight, ww: playbackWidth, data: " ", border: FALSE, scrollable: FALSE]]; MonEntries[i].pieceViewer _ ViewerTools.MakeNewTextViewer[ info: [parent: container, wx: playbackWidth+10, wy: y, wh: lineHeight, ww: pieceWidth, data: " ", border: FALSE, scrollable: FALSE]]; MonEntries[i].actionRule _ Rules.Create[ info: [parent: container, wx: playbackWidth+ pieceWidth+15, wy: y, wh: lineHeight, ww: lineHeight, border: FALSE], color: Graphics.white]; [] _ Rules.Create[info: [parent: container, wx: 0, wy: y+lineHeight+1, ww: 1024, wh: 1, border: FALSE]]; y _ y + lineHeight + 3; ENDLOOP; EnableViewerUpdates[TRUE]; RETURN [y]; END; monGet: ENTRY PROCEDURE[i: INTEGER] RETURNS[handle: Handle, socket: PupDefs.PupSocket, tuneId: INT, firstByte: INT, nBytes: INT, playback: BOOLEAN, action: BOOLEAN] = <> <> BEGIN piece: REF Piece; buffer: REF Buffer; adjust: INT; handle _ MonEntries[i].handle; IF handle = NIL THEN RETURN; IF handle.connection # NIL THEN socket _ handle.connection.socket; action _ handle.action; handle.action _ FALSE; piece _ handle.piece; IF piece = NIL THEN BEGIN tuneId _ -1; firstByte _ -1; nBytes _ -1; playback _ FALSE; END ELSE BEGIN tuneId _ piece.tuneId; <> <> <> firstByte _ piece.firstByte; nBytes _ piece.nBytes; buffer _ handle.firstClientBuffer; adjust _ 0; WHILE buffer # NIL DO adjust _ adjust + buffer.block.stopIndexPlusOne - buffer.block.startIndex; buffer _ buffer.next; ENDLOOP; firstByte _ firstByte - adjust; nBytes _ nBytes + adjust; playback _ piece.playback; END; RETURN; END; monitor: PROCEDURE = <> <> BEGIN handle: Handle; socket: PupDefs.PupSocket; tuneId, firstByte, nBytes: INT; playback, action, new: BOOLEAN; white: REF Graphics.Color _ NEW[Graphics.Color _ Graphics.white]; black: REF Graphics.Color _ NEW[Graphics.Color _ Graphics.black]; WHILE TRUE DO Process.Pause[Process.MsecToTicks[250]]; IF NOT masterSwitch THEN EXIT; FOR i:INTEGER IN [0..nMonEntries) DO <> <> [handle, socket, tuneId, firstByte, nBytes, playback, action] _ monGet[i]; new _ MonEntries[i].new; IF (handle = NIL) THEN BEGIN <> IF new THEN LOOP ELSE <> BEGIN MonEntries[i].new _ TRUE; ViewerTools.SetContents[MonEntries[i].playbackViewer, " "]; ViewerTools.SetContents[MonEntries[i].pieceViewer, " "]; Rules.Set[MonEntries[i].actionRule, white]; LOOP; END; END; <> <> IF (tuneId # MonEntries[i].tuneId) OR (firstByte # MonEntries[i].firstByte) OR (nBytes # MonEntries[i].nBytes) OR new THEN BEGIN IF tuneId >= 0 THEN BEGIN ViewerTools.SetContents[MonEntries[i].pieceViewer, IO.PutFR["%d[%d:%d]", IO.int[tuneId], IO.int[firstByte/Jukebox.bytesPerChirp], IO.int[(firstByte+nBytes-1)/Jukebox.bytesPerChirp]]]; END ELSE BEGIN ViewerTools.SetContents[MonEntries[i].pieceViewer, " "]; ViewerTools.SetContents[MonEntries[i].playbackViewer, " "]; END; MonEntries[i].tuneId _ tuneId; MonEntries[i].firstByte _ firstByte; MonEntries[i].nBytes _ nBytes; END; IF (playback # MonEntries[i].playback) OR new THEN BEGIN IF tuneId >= 0 THEN BEGIN IF playback THEN ViewerTools.SetContents[MonEntries[i].playbackViewer, "Playback:"] ELSE ViewerTools.SetContents[MonEntries[i].playbackViewer, "Recording:"]; END; MonEntries[i].playback _ playback; END; IF MonEntries[i].black THEN BEGIN Rules.Set[MonEntries[i].actionRule, white]; MonEntries[i].black _ FALSE; END ELSE IF action THEN BEGIN Rules.Set[MonEntries[i].actionRule, black]; MonEntries[i].black _ TRUE; END; MonEntries[i].new _ FALSE; ENDLOOP; ENDLOOP; END; END. <> <>