1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2;;;                                                                     ;;;
3;;;                     Carnegie Mellon University                      ;;;
4;;;                  and Alan W Black and Kevin Lenzo                   ;;;
5;;;                      Copyright (c) 1998-2000                        ;;;
6;;;                        All Rights Reserved.                         ;;;
7;;;                                                                     ;;;
8;;; Permission is hereby granted, free of charge, to use and distribute ;;;
9;;; this software and its documentation without restriction, including  ;;;
10;;; without limitation the rights to use, copy, modify, merge, publish, ;;;
11;;; distribute, sublicense, and/or sell copies of this work, and to     ;;;
12;;; permit persons to whom this work is furnished to do so, subject to  ;;;
13;;; the following conditions:                                           ;;;
14;;;  1. The code must retain the above copyright notice, this list of   ;;;
15;;;     conditions and the following disclaimer.                        ;;;
16;;;  2. Any modifications must be clearly marked as such.               ;;;
17;;;  3. Original authors' names are not deleted.                        ;;;
18;;;  4. The authors' names are not used to endorse or promote products  ;;;
19;;;     derived from this software without specific prior written       ;;;
20;;;     permission.                                                     ;;;
21;;;                                                                     ;;;
22;;; CARNEGIE MELLON UNIVERSITY AND THE CONTRIBUTORS TO THIS WORK        ;;;
23;;; DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING     ;;;
24;;; ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT  ;;;
25;;; SHALL CARNEGIE MELLON UNIVERSITY NOR THE CONTRIBUTORS BE LIABLE     ;;;
26;;; FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES   ;;;
27;;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN  ;;;
28;;; AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,         ;;;
29;;; ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF      ;;;
30;;; THIS SOFTWARE.                                                      ;;;
31;;;                                                                     ;;;
32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
33;;;                                                                      ;;
34;;;  A generic voice definition file for a clunits synthesizer           ;;
35;;;  Customized for: cmu_us_slt_arctic                                       ;;
36;;;                                                                      ;;
37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
38
39;;; Ensure this version of festival has been compiled with clunits module
40(require_module 'clunits)
41(require 'clunits) ;; runtime scheme support
42
43;;; Try to find the directory where the voice is, this may be from
44;;; .../festival/lib/voices/ or from the current directory
45(if (assoc 'cmu_us_slt_arctic_clunits voice-locations)
46    (defvar cmu_us_slt_arctic::clunits_dir
47      (cdr (assoc 'cmu_us_slt_arctic_clunits voice-locations)))
48    (defvar cmu_us_slt_arctic::clunits_dir (string-append (pwd) "/")))
49
50;;; Did we succeed in finding it
51(if (not (probe_file (path-append cmu_us_slt_arctic::clunits_dir "festvox/")))
52    (begin
53     (format stderr "cmu_us_slt_arctic::clunits: Can't find voice scm files they are not in\n")
54     (format stderr "   %s\n" (path-append  cmu_us_slt_arctic::clunits_dir "festvox/"))
55     (format stderr "   Either the voice isn't linked in Festival library\n")
56     (format stderr "   or you are starting festival in the wrong directory\n")
57     (error)))
58
59;;;  Add the directory contains general voice stuff to load-path
60(set! load-path (cons (path-append cmu_us_slt_arctic::clunits_dir "festvox/")
61		      load-path))
62
63;;; Voice specific parameter are defined in each of the following
64;;; files
65(require 'cmu_us_slt_arctic_phoneset)
66(require 'cmu_us_slt_arctic_tokenizer)
67(require 'cmu_us_slt_arctic_tagger)
68(require 'cmu_us_slt_arctic_lexicon)
69(require 'cmu_us_slt_arctic_phrasing)
70(require 'cmu_us_slt_arctic_intonation)
71(require 'cmu_us_slt_arctic_duration)
72(require 'cmu_us_slt_arctic_f0model)
73(require 'cmu_us_slt_arctic_other)
74;; ... and others as required
75
76;;;
77;;;  Code specific to the clunits waveform synthesis method
78;;;
79
80;;; Flag to save multiple loading of db
81(defvar cmu_us_slt_arctic::clunits_loaded nil)
82;;; When set to non-nil clunits voices *always* use their closest voice
83;;; this is used when generating the prompts
84(defvar cmu_us_slt_arctic::clunits_prompting_stage nil)
85;;; Flag to allow new lexical items to be added only once
86(defvar cmu_us_slt_arctic::clunits_added_extra_lex_items nil)
87
88;;; You may wish to change this (only used in building the voice)
89(set! cmu_us_slt_arctic::closest_voice 'voice_kal_diphone)
90
91;;;  These are the parameters which are needed at run time
92;;;  build time parameters are added to his list in cmu_us_slt_arctic_build.scm
93(set! cmu_us_slt_arctic::dt_params
94      (list
95       (list 'db_dir cmu_us_slt_arctic::clunits_dir)
96       '(name cmu_us_slt_arctic)
97       '(index_name cmu_us_slt_arctic)
98       '(f0_join_weight 0.0)
99       '(join_weights
100         (0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 ))
101       '(trees_dir "festival/trees/")
102       '(catalogue_dir "festival/clunits/")
103       '(coeffs_dir "mcep/")
104       '(coeffs_ext ".mcep")
105       '(clunit_name_feat lisp_cmu_us_slt_arctic::clunit_name)
106       ;;  Run time parameters
107       '(join_method windowed)
108       ;; if pitch mark extraction is bad this is better than the above
109;       '(join_method smoothedjoin)
110;       '(join_method modified_lpc)
111       '(continuity_weight 5)
112;       '(log_scores 1)  ;; good for high variance joins (not so good for ldom)
113       '(optimal_coupling 1)
114       '(extend_selections 2)
115       '(pm_coeffs_dir "mcep/")
116       '(pm_coeffs_ext ".mcep")
117       '(sig_dir "wav/")
118       '(sig_ext ".wav")
119;       '(pm_coeffs_dir "lpc/")
120;       '(pm_coeffs_ext ".lpc")
121;       '(sig_dir "lpc/")
122;       '(sig_ext ".res")
123;       '(clunits_debug 1)
124))
125
126(define (cmu_us_slt_arctic::clunit_name i)
127  "(cmu_us_slt_arctic::clunit_name i)
128Defines the unit name for unit selection for us.  The can be modified
129changes the basic classification of unit for the clustering.  By default
130this we just use the phone name, but you may want to make this, phone
131plus previous phone (or something else)."
132  (let ((name (item.name i)))
133    (cond
134     ((and (not cmu_us_slt_arctic::clunits_loaded)
135	   (or (string-equal "h#" name)
136	       (string-equal "1" (item.feat i "ignore"))
137	       (and (string-equal "pau" name)
138		    (or (string-equal "pau" (item.feat i "p.name"))
139			(string-equal "h#" (item.feat i "p.name")))
140		    (string-equal "pau" (item.feat i "n.name")))))
141      "ignore")
142     ((string-matches name "[aeiou].*")
143      (string-append
144       name
145       (item.feat i "R:SylStructure.parent.stress")))
146     ((string-equal name "pau")
147      name)
148     (t
149      (string-append
150       name
151       (item.feat i "seg_onsetcoda"))))))
152
153(define (cmu_us_slt_arctic::clunits_load)
154  "(cmu_us_slt_arctic::clunits_load)
155Function that actual loads in the databases and selection trees.
156SHould only be called once per session."
157  (set! dt_params cmu_us_slt_arctic::dt_params)
158  (set! clunits_params cmu_us_slt_arctic::dt_params)
159  (clunits:load_db clunits_params)
160  (load (string-append
161	 (string-append
162	  cmu_us_slt_arctic::clunits_dir "/"
163	  (get_param 'trees_dir dt_params "trees/")
164	  (get_param 'index_name dt_params "all")
165	  ".tree")))
166  (set! cmu_us_slt_arctic::clunits_clunit_selection_trees clunits_selection_trees)
167  (set! cmu_us_slt_arctic::clunits_loaded t))
168
169(define (cmu_us_slt_arctic::voice_reset)
170  "(cmu_us_slt_arctic::voice_reset)
171Reset global variables back to previous voice."
172  (cmu_us_slt_arctic::reset_phoneset)
173  (cmu_us_slt_arctic::reset_tokenizer)
174  (cmu_us_slt_arctic::reset_tagger)
175  (cmu_us_slt_arctic::reset_lexicon)
176  (cmu_us_slt_arctic::reset_phrasing)
177  (cmu_us_slt_arctic::reset_intonation)
178  (cmu_us_slt_arctic::reset_duration)
179  (cmu_us_slt_arctic::reset_f0model)
180  (cmu_us_slt_arctic::reset_other)
181
182  t
183)
184
185;; This function is called to setup a voice.  It will typically
186;; simply call functions that are defined in other files in this directory
187;; Sometime these simply set up standard Festival modules othertimes
188;; these will be specific to this voice.
189;; Feel free to add to this list if your language requires it
190
191(define (voice_cmu_us_slt_arctic_clunits)
192  "(voice_cmu_us_slt_arctic_clunits)
193Define voice for us."
194  ;; *always* required
195  (voice_reset)
196
197  ;; Select appropriate phone set
198  (cmu_us_slt_arctic::select_phoneset)
199
200  ;; Select appropriate tokenization
201  (cmu_us_slt_arctic::select_tokenizer)
202
203  ;; For part of speech tagging
204  (cmu_us_slt_arctic::select_tagger)
205
206  (cmu_us_slt_arctic::select_lexicon)
207  ;; For clunits selection you probably don't want vowel reduction
208  ;; the unit selection will do that
209  (if (string-equal "americanenglish" (Param.get 'Language))
210      (set! postlex_vowel_reduce_cart_tree nil))
211
212  (cmu_us_slt_arctic::select_phrasing)
213
214  (cmu_us_slt_arctic::select_intonation)
215
216  (cmu_us_slt_arctic::select_duration)
217
218  (cmu_us_slt_arctic::select_f0model)
219
220  ;; Waveform synthesis model: clunits
221
222  ;; Load in the clunits databases (or select it if its already loaded)
223  (if (not cmu_us_slt_arctic::clunits_prompting_stage)
224      (begin
225	(if (not cmu_us_slt_arctic::clunits_loaded)
226	    (cmu_us_slt_arctic::clunits_load)
227	    (clunits:select 'cmu_us_slt_arctic))
228	(set! clunits_selection_trees
229	      cmu_us_slt_arctic::clunits_clunit_selection_trees)
230	(Parameter.set 'Synth_Method 'Cluster)))
231
232  ;; This is where you can modify power (and sampling rate) if desired
233  (set! after_synth_hooks nil)
234;  (set! after_synth_hooks
235;      (list
236;        (lambda (utt)
237;          (utt.wave.rescale utt 2.1))))
238
239  (set! current_voice_reset cmu_us_slt_arctic::voice_reset)
240
241  (set! current-voice 'cmu_us_slt_arctic_clunits)
242)
243
244(define (is_pau i)
245  (if (phone_is_silence (item.name i))
246      "1"
247      "0"))
248
249(provide 'cmu_us_slt_arctic_clunits)
250
251