(* ;;-*-LISP-*- KEEP EMACS HAPPY ********************************
*
*    SPEECH -- TRANSLATION OF HANDSY 
*
*(1) SR = 10000
*(2) PLCONSTANT = .995 when SR = 10000
****************************************************************)

(DEFCONST PI 3.14159265)
(DEFVAR SR 10000)
(DEFVAR PERIODT .0001)
(DEFVAR PIT .0003141593)
(DEFVAR TWOPIT .0006283186)
(DEFVAR PLCONSTANT .995)

(DEFEXPR (SPEECH.SR (OPTIONAL SAMPLERATE 10000))
  (PROG ()
    (SETQ SR SAMPLERATE)
    (SETQ PERIODT (/$ 1.0 SR))
    (SETQ PIT (x$ PI PERIODT))
    (SETQ TWOPIT (x$ 2.0 PIT))
    (SETQ PLCONSTANT (ANTILOG (x$ -50.13705 PERIODT)))
))

(DEFVAR SPEECH.MEMORY)
(DEFVAR SPEECH.SLICE)
(DEFVAR SPEECH.COEFF)
(DEFVAR SPEECH.WAVE)

(DEFEXPR (SPEECH.INIT)
  (PROG ()
    (PARCOE.INIT)
    (SETQ SPEECH.MEMORY (COEWAVE.CREATE.MEMORY))
    (SETQ SPEECH.SLICE OW.SLICE)
    (SETF (PVECTOR.COMMENT SPEECH.SLICE) '(* SPEECH.SLICE *))
    (SETQ SPEECH.COEFF (COEWAVE.CREATE.COEFF))
    (SETQ SPEECH.WAVE (ARRAY SPEECH.WAVESIZE 'POINTER 0.0))
    (SPEECH.SR 10000)
    (COEWAVE.INIT.COEFF SPEECH.COEFF)
    (COEWAVE.INIT.MEMORY SPEECH.MEMORY)
    (COEWAVE.TRACE 'OUTPUT)
))

(DEFEXPR (SPEECH.SYNTHTRAJ (OPTIONAL TRAJ SPEECH.TRAJ))
  (* SPEECH.WAVE created according to contents of TRAJ *)
  (PROG ()
    (COEWAVE.INIT.COEFF SPEECH.COEFF)
    (COEWAVE.INIT.MEMORY SPEECH.MEMORY)
    (* Synthesize, updating SPEECH.COEFF every 50 samples *)
    (FOR N ← 1 BY (+ N 50)
     WHILE (< N (ARRAYSIZE SPEECH.WAVE))
     DO (PARCOE.INTERPOLATE N TRAJ SPEECH.SLICE)
     (PARCOE.PTC SPEECH.SLICE SPEECH.COEFF)
     (COEWAVE.CTW SPEECH.COEFF SPEECH.MEMORY SPEECH.WAVE
		  N (IMIN (+ N 49) (ARRAYSIZE SPEECH.WAVE))))
    (RETURN SPEECH.WAVE)
))

(DEFEXPR (SPEECH.SYNTHSLICE (OPTIONAL SLICE SPEECH.SLICE))
  (* SPEECH.WAVE created according to contents of SLICE
     We do 4 periods, then fake the rest. *)
  (PROG (PERIOD0)
    (COEWAVE.INIT.COEFF SPEECH.COEFF)
    (COEWAVE.INIT.MEMORY SPEECH.MEMORY)
    (* PERIOD0 = glottal period. *)
    (SETQ PERIOD0 (/ SR (PVECTOR.F0 SLICE)))
    (COND ((ZEROP PERIOD0)(SETQ PERIOD0 100)))
    (FOR N ← 1 BY (+ N PERIOD0)
     WHILE (< N (ARRAYSIZE SPEECH.WAVE))
     AS I FROM 1 TO 4
     DO (PARCOE.PTC SLICE SPEECH.COEFF)
     (COEWAVE.CTW 
      SPEECH.COEFF SPEECH.MEMORY SPEECH.WAVE 
      N (IMIN (+ N PERIOD0 -1) (ARRAYSIZE SPEECH.WAVE))))
    (FOR N FROM (1+ (x 4 PERIOD0)) TO (ARRAYSIZE SPEECH.WAVE)
     DO (SETF (ELT SPEECH.WAVE N)
	      (ELT SPEECH.WAVE (+ (x 3 PERIOD0) (\ N PERIOD0))))
     (COND (COEWAVE.TRACE 
	    (WDISPLAY.DRAWXY N (ELT SPEECH.WAVE N) COEWAVE.WINDOW))))
    (RETURN SPEECH.WAVE)
))


(* ****************************************************************
*
*     INPUT/OUTPUT
*
****************************************************************)

(DEFEXPR (SPEECH.BIN STREAM)
  (PROG (CODE)
    (SETQ CODE (\BIN STREAM))
    (COND ((>= CODE 128) (SETQ CODE (- 127 CODE))))
    (RETURN CODE)
))

(DEFEXPR (SPEECH.BOUT STREAM CODE)
  (PROG ()
    (COND ((< CODE 0) (SETQ CODE (- 127 CODE))))
    (\BOUT STREAM CODE)
))

(* ****************************************************************
*STOP
****************************************************************)

STOP