;;;  This file is additional code NOT INCLUDED with the Festival TTS 
;;;   system as distributed by CSTR/University of Edinburgh.  
;;;
;;;  Festival is being redistributed with permission of CSTR as part of 
;;;   the CSLU Toolkit.   
;;;
;;;  The CSLU Toolkit and this code are 
;;;    Copyright (C)1997 Center for Spoken Language Understanding,
;;;                      Oregon Graduate Institute of Science & Technology
;;;
;;; In addition to conditions disclaimers below, please see the file "license.ogi" 
;;; for information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES.
;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;  Set up jph_diphones using the OGI resLPC diphone synthesizer
;;;
;;;  JPH diphones: male American English collected March 1997 by OGI
;;;  OGI residual LPC synthesizer by M. Macon early 1997.

;;; Lexicons
(require 'ogi_lexicons)

;;; Postlexical rules
(require 'ogi_postlex)

;;; Phrase breaks
(require 'ogi_phrase)

;;; You can override the following in siteinit.scm
(defvar jph_diphone_dir (cdr (assoc 'jph_diphone voice-locations))
  "jph_diphone_dir
  The default directory for the jph diphone database.")
(set! load-path (cons (path-append jph_diphone_dir "festvox") load-path))

;;;  Set up the MOBY+CMU lexicon
(setup_moby_lex)

(defvar jph_OGI_di_db 'jph_lpc
  "jph_OGI_di_db
The name of the jph diphone database for use with OGI residual excited LPC.")

;;; Use the grouped file by default
(defvar jph_grouped_or_ungrouped 'grouped)

;;; For building the group file
(set! jph_diphone_src_dir '/u/macon/TTS/tts_data/jph/)

;;;  The following a diphone database dependent but are sharable between
;;;  the different encodings of the jph diphone db
(set! jph_alternates_before
   '(alternates_before
     ((m= m) (n= n) (l= l) (h pau) (j i:))))
(set! jph_alternates_after
   '(alternates_after
    ((m= m) (n= n) (l= l) (h pau) (j i:))))
(set! jph_default_diphone '(default_diphone "pau-h"))

;;; Load the phoneset
(require 'ogi_worldbet_phones)

(define (voice_jph_diphone)
"(voice_jph_diphone)
 Set up the current voice to be an American male JPH using
 the JPH diphone set and OGI's resLPC backend."

  ;; reset global parameters
  (voice_reset)

  ;; Phone set
  (Parameter.set 'Language 'americanenglish)
  (require 'ogi_lts_worldbet)
  (Parameter.set 'PhoneSet 'worldbet)
  (PhoneSet.select 'worldbet)

  ;; Token to word rules
  (set! token_to_words english_token_to_words)

  ;; POS tagger
  (require 'pos)
  (set! pos_lex_name "english_poslex")
  (set! pos_ngram_name 'english_pos_ngram)
  (set! pos_supported t)
  (set! guess_pos english_guess_pos)   ;; need this for accents

  ;; Lexicon selection
  (lex.select "moby")

  ;; Postlexical rules (some defined in "ogi_postlex.scm")
  (set! postlex_vowel_reduce_cart_tree  OGI_postlex_vowel_reduce_cart_tree_hand) ;; must set this!
  (set! postlex_rules_hooks (list PostLex_Reduce The_Before_Vowel t_to_ch_hack postlex_apos_s_check))

  ;; Phrase prediction
  (require 'phrase)
  (require 'ogi_phrase)
  (set! festival-phrasify Phrasify)
  (set! Phrasify OGI_PuncPhrasify)

  (Parameter.set 'Phrase_Method 'prob_models)  ;; use this for paragraphs
  (set! phr_break_params OGI_english_phr_break_params)

  ;; Accent and tone prediction
  (require 'tobi)
  (set! int_tone_cart_tree f2b_int_tone_cart_tree)
  (set! int_accent_cart_tree f2b_int_accent_cart_tree)

  ;; F0 prediction
  (require 'f2bf0lr)
  (set! f0_lr_start f2b_f0_lr_start)
  (set! f0_lr_mid f2b_f0_lr_mid)
  (set! f0_lr_end f2b_f0_lr_end)
  (Parameter.set 'Int_Method Intonation_Tree)
  (set! int_lr_params
	'((target_f0_mean 115) (target_f0_std 15)
	  (model_f0_mean 170) (model_f0_std 34)))
  (Parameter.set 'Int_Target_Method Int_Targets_LR)

  ;; Duration prediction
  (require 'ogi_kddurtreeZ_wb)
  (set! duration_cart_tree kd_duration_cart_tree_wb)
  (set! duration_ph_info kd_durs_wb)
  (Parameter.set 'Duration_Method Duration_Tree_ZScores)
  (Parameter.set 'Duration_Stretch 1.00)

  (Parameter.set 'Synth_Method OGIresLPC_Synthesize)
  (Dbase.select jph_OGI_di_db)      
  (Synth_Init jph_OGI_syn_params)  
  (set! current_voice_reset jph_voice_reset)
  (set! current-voice 'jph_diphone)  
)


(define (jph_voice_reset)
  (set! Phrasify festival-phrasify)
  )
 


;;
;;  Residual LPC synthesizer parameters - used by Synth_Init
;;
(set! jph_smooth_lpc   ;;; max number of frames to use in smoothing LPC at joins
      '(smooth_lpc
	((silence 0)
	 (vowel 10)
	 (liquid 4)
	 (nasal 5)
	 (stop 0)
	 (vfric 5)
	 (uvfric 0)
	 )))

(set! jph_smooth_power   ;;; max number of frames to use in smoothing power at joins
      '(smooth_power
	((silence 0)
	 (vowel 10)
	 (liquid 4)
	 (nasal 5)
	 (stop 0)
	 (vfric 5)
	 (uvfric 5)
	 )))

(set! jph_OGI_syn_params  ; 16k
      (list
       '(Fo_default 100.0);; default Fo used if can't find any Fo targets
       '(Fo_UV_thr 60.0)  ;; used to make V/UV decision 
       '(Fo_UV_pm 120.0)  ;; used to place UV pmarks
       '(sil_ramp 10.0)   ;; ramp silences to 0 with this ramp duration (msec)
       '(post_gain 1.0)   ;; this may need to be large if preemph close to 1
       '(beta_smooth 0)   ;; preserves aperiodicity - smooth window is 2*beta_smooth+1
       '(xcorr_Nsearch 0);; num of cross-correlations to try when joining units 
       '(xcorr_Nskip 1)   ;; num samples to incr between xcorrs
       '(xcorr_win_prcnt 0.35)  ;; xcorr window size (%To)
       '(debug_level 0)   ;; see resLPC_debug.h for definitions (0 is 'off')
       jph_smooth_lpc
       jph_smooth_power
       ))

(define (setup_jph_OGI_lpc_di_16k)
"(setup_jph_OGI_lpc_di_16k)
  Initialise the JPH diphone database.  This sets up the 16K version
  for residual excited LPC."
(if (equal? jph_grouped_or_ungrouped 'ungrouped)
(Dbase_Init  ;; ungrouped
 (list
  '(name jph_lpc)
  (list 'index_file (path-append jph_diphone_src_dir "dic" "diphdic.msec"))
  (list 'lpc_dir (path-append jph_diphone_src_dir "lpc16" ""))
  '(lpc_ext ".lpc")
  '(lpc_type "ascii")
  '(lpc_res_ext ".res")
  '(lpc_res_type "raw")
  '(type lpc)
  (list 'pitch_dir (path-append jph_diphone_src_dir "pm" ""))
  '(pitch_ext ".pmv")
  '(samp_freq 16000)
  '(num_diphones 2200)
  '(sig_band 160)
  '(lpc_order 16)  
  '(preemph 0.96)  ;; preemphasis filter coeff
  '(phoneset worldbet)  
  '(access_type "ondemand")
  '(group_encoding "compressed")
   jph_alternates_before
   jph_alternates_after
   jph_default_diphone
   ))
(Dbase_Init   ;;  grouped -- parameters set here override those in groupfile
  (list
   '(name jph_lpc)
   (list 'group_file (path-append jph_diphone_dir "group" "jphlpcOGI16k.group"))
   '(access_type "ondemand")
  '(preemph 0.96)  ;; preemphasis filter coeff
   jph_alternates_before
   jph_alternates_after
   jph_default_diphone
   )))
t)

(setup_jph_OGI_lpc_di_16k) 


(proclaim_voice
 'jph_diphone
 '((language english)
   (gender male)
   (dialect american)
   (description
    "This voice provides an American English male voice using a
     residual excited LPC diphone synthesis module, both created at
     OGI.  It uses a lexicon compiled from MOBY and CMU lexicons, and
     other trained modules used by CSTR voices.  The OGIresLPC
     synthesizer module is a plug-in to Festival and is available at
     http://www.cse.ogi.edu/CSLU/tts.")))

(provide 'jph_diphone)





