// ChatAudio.bcpl -- Generate audio output through Diablo printer interface // Copyright Xerox Corporation 1979 // Last modified April 24, 1979 1:37 PM get "ChatAudio.d" get "AltoDefs.d" external [ // outgoing procedures EnqueueAudioOut; AudioFinish // incoming procedures DisableInterrupts; CauseInterrupt // outgoing statics audioSavedSCP; audioSavedUFP // incoming statics @acb; lvSwatContextProc; lvUserFinishProc ] static [ audioSavedSCP; audioSavedUFP ] // --------------------------------------------------------------------------- let EnqueueAudioOut(pitch, duration) = valof // --------------------------------------------------------------------------- // Pitch is one-half the period of the signal to be generated, in units of // 38.08 microseconds, and in the range 1 to 1023. That is, // pitch = 1 / (2 * 38.08 * 10↑-6 * f) // where f is the desired frequency. This accomodates frequencies from // approximately 12.8 Hz to 13.1 KHz, though the highest frequencies are // unattainable due to latency limitations. // Duration is the length of time to generate the signal, in units of // the "pitch" interval. // Returns true iff the queue didn't overflow. // Special actions: if pitch=0, generates duration*39 ms of silence. // If duration=0, stops everything and resets the queue. [ if (pitch & -1024) ne 0 resultis false let write = acb>>ACB.write if duration eq 0 & acb>>ACB.duration ne 0 then [ // stop current output and reset the queue DisableInterrupts() acb>>ACB.read = write acb>>ACB.duration = 1 CauseInterrupt(@itInterruptMask) // Re-enables interrupts resultis true ] write!0 = pitch lshift acb>>ACB.sitShiftCount write!1 = duration write = write+2 if write eq acb>>ACB.end then write = acb>>ACB.base test write eq acb>>ACB.read ifso resultis false ifnot [ acb>>ACB.write = write if acb>>ACB.duration eq 0 then [ acb>>ACB.duration = 1; CauseInterrupt(@itInterruptMask) ] resultis true ] ] // --------------------------------------------------------------------------- and AudioFinish() be // --------------------------------------------------------------------------- [ @itInterruptMask = 0 @lvSwatContextProc = audioSavedSCP @lvUserFinishProc = audioSavedUFP ]