(* ;;-*-LISP-*- KEEP EMACS HAPPY ******************************** * * AUDIO * *(1) OUT0 & OUTN tell the microcode how long the AUDIO.BUFFER is. *(2) MCPAGE & MCWORD tell where the microcode is. ****************************************************************) (DEFPROP .AUDIO. DOPVAL (1 AUDIO)) (DEFVAR AUDIO.BUFFER) (DEFVAR AUDIO.BUFFER.SIZE 8) (BLOCKRECORD AUDIOBLK ((OUT0 WORD) (OUTN WORD) (MCPAGE BYTE) (MCWORD BYTE) (INDELTA WORD))) (DEFEXPR (AUDIO.INIT) (PROG () (SETQ AUDIO.BUFFER (\VAG2 63 0)) (FOR I FROM 0 TO AUDIO.BUFFER.SIZE DO (\NEWPAGE (AUDIO.PAGE AUDIO.BUFFER I))) (\LOCKPAGES AUDIO.BUFFER AUDIO.BUFFER.SIZE) (AUDIO.RESET) )) (DEFEXPR (AUDIO.RESET) (PROG () (FOR I FROM 0 TO (1- AUDIO.BUFFER.SIZE) DO (AUDIO.ZEROPAGE AUDIO.BUFFER I)) (SETF (AUDIOBLK.OUT0 AUDIO.BUFFER) 256) (SETF (AUDIOBLK.OUTN AUDIO.BUFFER) 2303) (SETF (AUDIOBLK.MCPAGE AUDIO.BUFFER) 0) (SETF (AUDIOBLK.MCWORD AUDIO.BUFFER) 0) (SETF (AUDIOBLK.INDELTA AUDIO.BUFFER) 0) )) (DEFEXPR (AUDIO.PLAY FILE) (* Play FILE. For good results, FILE should be on {CORE}. *) (PROG (STREAM PAGESIZE N LPAGE LEND) (SETQ STREAM (OPENSTREAM FILE 'INPUT)) (AUDIO.RESET) (SETQ PAGESIZE (/ (+ (GETEOFPTR STREAM) 511) 512)) (SETQ N (IMAX AUDIO.BUFFER.SIZE PAGESIZE)) (FOR I FROM 0 TO (1- N) DO (\READPAGES STREAM I (AUDIO.PAGE AUDIO.BUFFER I))) (SETQ LPAGE 0) (SETQ LEND (IMOD PAGESIZE AUDIO.BUFFER.SIZE)) (RESETFORM (\AUDIO AUDIO.BUFFER) (FOR I FROM (1+ N) TO PAGESIZE DO (WHILE (EQ (AUDIOBLK.MCPAGE AUDIO.BUFFER) LPAGE) DO (* Wait for Microcode to finish LPAGE *)) (\READPAGES STREAM (1- I) (AUDIO.PAGE AUDIO.BUFFER LPAGE)) (SETQ LPAGE (IMOD (1+ LPAGE) AUDIO.BUFFER.SIZE))) (UNTIL (EQ (AUDIOBLK.MCPAGE AUDIO.BUFFER) LEND) DO (* Wait for Microcode to finish remaining pages *))) (CLOSEF STREAM) )) (DEFEXPR (AUDIO.PAGE BASE N) (* Return Nth page of BASE *) (\ADDBASE BASE (LLSH N 8))) (DEFEXPR (AUDIO.ZEROPAGE BASE N) (* Zero out Nth page of BASE *) (PROG () (SETQ BASE (AUDIO.PAGE BASE N)) (\ZEROWORDS BASE (\ADDBASE BASE 256)) )) (DEFEXPR (AUDIO.RECORD FILE (OPTIONAL NSEC 5)) (PROG (STREAM COP) (SETQ STREAM (OPENSTREAM FILE 'OUTPUT)) (AUDIO.RESET) (SETQ COP 1) (OR (EQ NSEC T) (\TRUNCATEFILE STREAM (x 16 NSEC) 0)) (* Preallocate space) (AUDIO.RECORDFN T) (* Wait for user to tell you to start) (RESETFORM (\AUDIO AUDIO.BUFFER) (FOR F FROM 0 WHILE (AUDIO.RECORDFN NIL) DO (WHILE (= COP (AUDIOBLK.MCPAGE AUDIO.BUFFER))) (\WRITEPAGES STREAM F (AUDIO.PAGE AUDIO.BUFFER COP)) (AUDIO.ZEROPAGE AUDIO.BUFFER COP) (COND ((= COP AUDIO.BUFFER.SIZE) (SETQ COP 1)) (T (SETQ COP (1+ COP)))) FINALLY (SETQ COP (LLSH F 9)))) (\SETEOFPTR STREAM COP) (CLOSEF FILE))) (DEFVAR AUDIO.CLOCK) (DEFEXPR (AUDIO.RECORDFN STARTP) (DECLARE (GLOBALVARS AUDIO.CLOCK)) (PROG () (COND (STARTP (PROMPTPRINT "Press and hold CTRL key to record.") (UNTIL (KEYDOWNP 'CTRL)) (PROMPTPRINT "Recording in progress...") (SETQ AUDIO.CLOCK (CLOCK))) ((KEYDOWNP 'CTRL) (* Continue to record. *) (RETURN T)) (T (PROMPTPRINT "Recording complete. Duration: ") (PRINTOUT PROMPTWINDOW (/$ (CLOCKDIFFERENCE AUDIO.CLOCK) 1000.0)) " seconds." T)) )) (DEFEXPR (\AUDIO BUF) (* Any odd pointer turns off the audio ucode) (OR (.AUDIO. (OR BUF (\ADDBASE AUDIO.BUFFER 1))) (SHOULDNT "No audio microcode")) (\ADDBASE AUDIO.BUFFER 1)) (COND ((NOT (CCODEP (GETD '\AUDIO))) (COMPILE '\AUDIO))) (COND ((NULL AUDIO.BUFFER) (AUDIO.INIT))) STOP