;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; ;;; Language Technologies Institute ;;; ;;; Carnegie Mellon University ;;; ;;; Copyright (c) 2007-2009 ;;; ;;; All Rights Reserved. ;;; ;;; ;;; ;;; Permission is hereby granted, free of charge, to use and distribute ;;; ;;; this software and its documentation without restriction, including ;;; ;;; without limitation the rights to use, copy, modify, merge, publish, ;;; ;;; distribute, sublicense, and/or sell copies of this work, and to ;;; ;;; permit persons to whom this work is furnished to do so, subject to ;;; ;;; the following conditions: ;;; ;;; 1. The code must retain the above copyright notice, this list of ;;; ;;; conditions and the following disclaimer. ;;; ;;; 2. Any modifications must be clearly marked as such. ;;; ;;; 3. Original authors' names are not deleted. ;;; ;;; 4. The authors' names are not used to endorse or promote products ;;; ;;; derived from this software without specific prior written ;;; ;;; permission. ;;; ;;; ;;; ;;; CARNEGIE MELLON UNIVERSITY AND THE CONTRIBUTORS TO THIS WORK ;;; ;;; DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ;;; ;;; ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT ;;; ;;; SHALL CARNEGIE MELLON UNIVERSITY NOR THE CONTRIBUTORS BE LIABLE ;;; ;;; FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ;;; ;;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN ;;; ;;; AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ;;; ;;; ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF ;;; ;;; THIS SOFTWARE. ;;; ;;; ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Author: Alan W Black (awb@cs.cmu.edu) ;;; ;;; Date: November 2007 ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; ;;; Convert a clustergen voice to flite ;;; ;;; ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Used for getting smaller models, if non-zero this will reduce the ;; order of the dumped models from whatever it is (probably 24) to this ;; It does the right thing with statics and dynamics and stddev (defvar cg_reduced_order 0) (if (> cg_reduced_order 0) ;; just to remind me (format t "\n***** CG: note reducing order to %d *****\n\n" cg_reduced_order)) (defvar F0MEAN 0.0) (defvar F0STD 1.0) (define (cg_convert name festvoxdir odir) "(cg_convert name clcatfn clcatfnordered cltreesfn festvoxdir odir) Convert a festvox clunits (processed) voice into a C file." (load (format nil "%s/festvox/%s_cg.scm" festvoxdir name)) (eval (list (intern (format nil "voice_%s_cg" name)))) (set! ofd (fopen (path-append odir (string-append name "_cg.c")) "w")) (format ofd "/*****************************************************/\n") (format ofd "/** Autogenerated clustergen voice for %s */\n" name) (format ofd "/*****************************************************/\n") (format ofd "\n") (format ofd "#include \"cst_string.h\"\n") (format ofd "#include \"cst_cg.h\"\n") (format ofd "#include \"cst_cart.h\"\n") (format t "cg_convert: converting F0 trees\n") ;; F0 trees (set! val_table nil) ;; different val number over the two sets of carts (cg_convert_carts (load (format nil "festival/trees/%s_f0.tree" name) t) "f0" name odir) (format ofd "\n") (format ofd "extern const cst_cart * const %s_f0_carts[];\n" name ) ;; spectral trees (set! val_table nil) ;; different val number over the two sets of carts (if cg:multimodel (begin ;; MULTIMODAL (format t "cg_convert: converting static spectral trees\n") (set! mfd (fopen (path-append odir "paramfiles.mak") "w")) (format mfd "PARAMMODEL=multimodel\n") (fclose mfd) (set! old_carttoC_extract_answer carttoC_extract_answer) (set! carttoC_extract_answer carttoC_extract_spectral_frame) (cg_convert_carts (load (format nil "festival/trees/%s_mcep_static.tree" name) t) "static_mcep" name odir) (set! carttoC_extract_answer old_carttoC_extract_answer) (format ofd "\n") (format ofd "extern const cst_cart * const %s_static_mcep_carts[];\n" name ) ;; spectral params (format t "cg_convert: converting static spectral params\n") (cg_convert_params (format nil "festival/trees/%s_mcep_static.params" name) (format nil "festival/trees/%s_min_range.scm" name) name "static" odir ofd) (format ofd "extern const unsigned short * const %s_static_model_vectors[];\n" name ) (set! val_table nil) (format t "cg_convert: converting delta spectral trees\n") (set! old_carttoC_extract_answer carttoC_extract_answer) (set! carttoC_extract_answer carttoC_extract_spectral_frame) (cg_convert_carts (load (format nil "festival/trees/%s_mcep_delta.tree" name) t) "delta_mcep" name odir) (set! carttoC_extract_answer old_carttoC_extract_answer) (format ofd "\n") (format ofd "extern const cst_cart * const %s_delta_mcep_carts[];\n" name ) ;; spectral params (format t "cg_convert: converting delta spectral params\n") (cg_convert_params (format nil "festival/trees/%s_mcep_delta.params" name) (format nil "festival/trees/%s_min_range.scm" name) name "delta" odir ofd) (format ofd "extern const unsigned short * const %s_delta_model_vectors[];\n" name ) ) (begin ;; SINGLE MODEL (format t "cg_convert: converting single spectral trees\n") (set! mfd (fopen (path-append odir "paramfiles.mak") "w")) (format mfd "PARAMMODEL=single\n") (fclose mfd) (set! old_carttoC_extract_answer carttoC_extract_answer) (set! carttoC_extract_answer carttoC_extract_spectral_frame) (cg_convert_carts (load (format nil "festival/trees/%s_mcep.tree" name) t) "single_mcep" name odir) (set! carttoC_extract_answer old_carttoC_extract_answer) (format ofd "\n") (format ofd "extern const cst_cart * const %s_single_mcep_carts[];\n" name ) ;; spectral params (format t "cg_convert: converting single spectral params\n") (cg_convert_params (format nil "festival/trees/%s_mcep.params" name) (format nil "festival/trees/%s_min_range.scm" name) name "single" odir ofd) (format ofd "extern const unsigned short * const %s_single_model_vectors[];\n" name ) )) ;; duration model (car conversion) (format t "cg_convert: converting duration model\n") (cg_convert_durmodel (format nil "festvox/%s_durdata_cg.scm" name) name odir) (format ofd "extern const dur_stat * const %s_dur_stats[];\n" name) (format ofd "extern const cst_cart %s_dur_cart;\n" name) ;; phone to states (format t "cg_convert: converting phone to state map\n") (cg_phone_to_states (format nil "festvox/%s_statenames.scm" name) name odir) (format ofd "extern const char * const *%s_phone_states[];\n" name) (format ofd "\n") (format ofd "const char * const %s_types[] = {\n" name) (mapcar (lambda (cart) (format ofd " \"%s\",\n" (car cart))) (load (format nil "festival/trees/%s_f0.tree" name) t)) (format ofd " NULL};\n") (format ofd "#define %s_num_types %d\n\n" name (length (load (format nil "festival/trees/%s_f0.tree" name) t))) (format ofd "const float %s_model_min[] = { \n" name) (mapcar (lambda (p) (format ofd " %f,\n" (car p))) (reverse new_min_range)) (format ofd "};\n") (format ofd "const float %s_model_range[] = { \n" name) (mapcar (lambda (p) (format ofd " %f,\n" (cadr p))) (reverse new_min_range)) (format ofd "};\n") (format ofd "const float %s_dynwin[] = { -0.5, 0.0, 0.5 };\n" name) (format ofd "#define %s_dynwinsize 3\n" name) (if cg:mixed_excitation (begin (set! memf me_mix_filters) (set! n 0) (while (< n 5) (format ofd "const double %s_me_filter_%d[] = {\n" name n) (set! o 0) (while (< o 47) (format ofd "%f, " (car memf)) (set! memf (cdr memf)) (set! o (+ o 1))) (format ofd "%f\n};\n" (car memf)) (set! memf (cdr memf)) (set! n (+ n 1)) ) (if memf (format t "Error still %d values left in me_filter\n" (length memf))) (format ofd "const double * const %s_me_h[] = {\n" name) (format ofd " %s_me_filter_0,\n" name) (format ofd " %s_me_filter_1,\n" name) (format ofd " %s_me_filter_2,\n" name) (format ofd " %s_me_filter_3,\n" name) (format ofd " %s_me_filter_4\n" name) (format ofd "};\n\n") )) (format ofd "const cst_cg_db %s_cg_db = {\n" name) (format ofd " \"%s\",\n" name) (format ofd " %s_types,\n" name) (format ofd " %s_num_types,\n" name) (format ofd " 16000,\n") ;; sample rate (format ofd " %f,%f,\n" F0MEAN F0STD) (format ofd " %s_f0_carts,\n" name) (if cg:multimodel (begin (format ofd " %s_static_mcep_carts,\n" name) (format ofd " %s_delta_mcep_carts,\n" name) (format ofd " NULL,\n") (format ofd " %s_static_num_channels,\n" name) (format ofd " %s_static_num_frames,\n" name) (format ofd " %s_static_model_vectors,\n" name) (format ofd " %s_delta_num_channels,\n" name) (format ofd " %s_delta_num_frames,\n" name) (format ofd " %s_delta_model_vectors,\n" name) (format ofd " 0,0,NULL,\n") ) (begin (format ofd " %s_single_mcep_carts,\n" name) (format ofd " NULL,NULL,\n") (format ofd " %s_single_num_channels,\n" name) (format ofd " %s_single_num_frames,\n" name) (format ofd " %s_single_model_vectors,\n" name) (format ofd " 0,0,NULL,\n") (format ofd " 0,0,NULL,\n"))) (format ofd " %s_model_min,\n" name) (format ofd " %s_model_range,\n" name) (format ofd " %f, /* frame_advance */\n" cg:frame_shift) (format ofd " %s_dur_stats,\n" name) (format ofd " &%s_dur_cart,\n" name) (format ofd " %s_phone_states,\n" name) (format ofd " 1, /* 1 if mlpg required */\n") (format ofd " %s_dynwin,\n" name) (format ofd " %s_dynwinsize,\n" name) (format ofd " %f, /* mlsa_alpha */\n" mlsa_alpha_param) (format ofd " %f, /* mlsa_beta */\n" mlsa_beta_param) (if cg:multimodel (format ofd " 1, /* cg:multimodel */\n") (format ofd " 0, /* cg:multimodel */\n")) (if cg:mixed_excitation (begin (format ofd " 1, /* cg:mixed_excitation */\n") (format ofd " 5,48, /* filter sizes */\n") (format ofd " %s_me_h \n" name)) (begin (format ofd " 0, /* cg:mixed_excitation */\n") (format ofd " 0,0, /* cg:mixed_excitation */\n") (format ofd " NULL \n"))) (format ofd "};\n") (fclose ofd) ) (define (unit_type u) (apply string-append (reverse (symbolexplode (string-after (apply string-append (reverse (symbolexplode u))) "_"))))) (define (unit_occur u) (apply string-append (reverse (symbolexplode (string-before (apply string-append (reverse (symbolexplode u))) "_"))))) (define (cg_convert_durmodel durmodelfn name odir) (set! durmodel (load durmodelfn t)) (set! phonedurs (cadr (car (cddr (car durmodel))))) (set! zdurtree (cadr (car (cddr (cadr durmodel))))) (set! dfd (fopen (path-append odir (string-append name "_cg_durmodel.c")) "w")) (set! dfdh (fopen (path-append odir (string-append name "_cg_durmodel.h")) "w")) (format dfd "/*****************************************************/\n") (format dfd "/** Autogenerated durmodel_cg for %s */\n" name) (format dfd "/*****************************************************/\n") (format dfd "#include \"cst_synth.h\"\n") (format dfd "#include \"cst_string.h\"\n") (format dfd "#include \"cst_cart.h\"\n") (format dfd "#include \"%s_cg_durmodel.h\"\n\n" name) (mapcar (lambda (s) (format dfd "static const dur_stat dur_state_%s = { \"%s\", %f, %f };\n" (cg_normal_phone_name (car s)) (car s) (car (cdr s)) (car (cddr s))) ) phonedurs) (format dfd "\n") (format dfd "const dur_stat * const %s_dur_stats[] = {\n" name) (mapcar (lambda (s) (format dfd " &dur_state_%s,\n" (cg_normal_phone_name (car s)))) phonedurs) (format dfd " NULL\n};\n") (set! val_table nil) (set! current_node -1) (set! feat_nums nil) (do_carttoC dfd dfdh (format nil "%s_%s" name "dur") zdurtree) (fclose dfd) (fclose dfdh) ) (define (cg_phone_to_states phonestatefn name odir) (set! dfd (fopen (path-append odir (string-append name "_cg_phonestate.c")) "w")) (format dfd "/*****************************************************/\n") (format dfd "/** Autogenerated phonestate_cg for %s */\n" name) (format dfd "/*****************************************************/\n") (set! phonestates (load phonestatefn t)) (mapcar (lambda (x) (format dfd "const char * const %s_%s_ps[] = { " name (cg_normal_phone_name (car x))) (mapcar (lambda (y) (format dfd "\"%s\", " y)) x) (format dfd " 0};\n")) (cadr (caddr (car phonestates)))) (format dfd "const char * const * const %s_phone_states[] = {\n" name) (mapcar (lambda (x) (format dfd " %s_%s_ps,\n" name (cg_normal_phone_name (car x)))) (cadr (caddr (car phonestates)))) (format dfd " 0};\n") (fclose dfd) ) (define (cg_convert_params mcepfn mcepminrangefn name type odir cofd) (let ((param.track (track.load mcepfn)) (i 0) (mfd)) (set! mfd (fopen (path-append odir (string-append name "_cg_" type "_params.c")) "w")) (format mfd "/*****************************************************/\n") (format mfd "/** Autogenerated model_vectors for %s */\n" name) (format mfd "/*****************************************************/\n") (set! num_channels (track.num_channels param.track)) (set! num_frames (track.num_frames param.track)) ;; Output each frame (set! mcep_min_range (load mcepminrangefn t)) (while (< i num_frames) (output_param_frame name type param.track i mfd) (set! i (+ 1 i))) (format mfd "\n\n") ;; Output each frame (format mfd "const unsigned short * const %s_%s_model_vectors[] = {\n" name type) (set! i 0) (while (< i num_frames) (format mfd " %s_%s_param_frame_%d,\n" name type i) (set! i (+ 1 i))) (format mfd "};\n\n") (if (> cg_reduced_order 0) (format cofd "#define %s_%s_num_channels %d\n" name type (+ 4 (* 4 cg_reduced_order))) (format cofd "#define %s_%s_num_channels %d\n" name type num_channels)) (format cofd "#define %s_%s_num_frames %d\n" name type num_frames) (fclose mfd) )) (define (mcepcoeff_norm c min range) (* (/ (- c min) range) 65535)) (define (output_param_frame name type track f ofd) "(output_param_frame name track frame ofd) Ouput this frame." (let ((i 0) (nc (track.num_channels track))) (format ofd "static const unsigned short %s_%s_param_frame_%d[] = { \n" name type f) (set! min_range mcep_min_range) (set! real_order (/ (- nc 4) 4)) (set! new_min_range nil) (while (< i nc) (if (or (eq cg_reduced_order 0) (< i (* 2 (+ 1 cg_reduced_order))) ;; static and static_stddev (and (> i (- (/ nc 2) 1)) ;; deltas and delta_stddev (< i (+ (/ nc 2) (* 2 cg_reduced_order)))) (> i (- nc 3))) (begin ; (format t "i is %d %d\n" i (+ (/ nc 2) (* 2 cg_reduced_order))) (format ofd " %d," (mcepcoeff_norm (track.get track f i) (caar min_range) (cadr (car min_range)))) (set! new_min_range (cons (car min_range) new_min_range)) )) (set! min_range (cdr min_range)) (set! i (+ 1 i))) (format ofd " };\n") ) ) (define (carttoC_extract_spectral_frame ofdh tree) "(carttoC_extract_spectral_frame tree) Get list of answers from leaf node." (carttoC_val_table ofdh (car (car tree)) 'none)) (define (cg_convert_carts carts prefix name odir) "(define cg_convert_carts cartfn name) Output cg selection carts into odir/name_carts.c" (let (ofd ofdh) ;; Set up to dump full list of things at leafs ;; default processing of leaf (int or float) is fine (set! ofd (fopen (format nil "%s/%s_cg_%s_trees.c" odir name prefix) "w")) (set! ofdh (fopen (format nil "%s/%s_cg_%s_trees.h" odir name prefix) "w")) (format ofd "/*****************************************************/\n") (format ofd "/** Autogenerated %s %s carts */\n" name prefix) (format ofd "/*****************************************************/\n") (format ofd "\n") (format ofd "#include \"cst_string.h\"\n") (format ofd "#include \"cst_cart.h\"\n") (format ofd "#include \"%s_cg_%s_trees.h\"\n" name prefix) (mapcar (lambda (cart) (if (string-equal "string" (typeof (car cart))) (begin (set! current_node -1) (set! feat_nums nil) (do_carttoC ofd ofdh (format nil "%s_%s_%s" name prefix (cg_normal_phone_name (car cart))) (cadr cart))))) carts) (format ofd "\n\n") (format ofd "const cst_cart * const %s_%s_carts[] = {\n" name prefix) (mapcar (lambda (cart) (if (string-equal "string" (typeof (car cart))) (format ofd " &%s_%s_%s_cart,\n" name prefix (cg_normal_phone_name (car cart)))) ) carts) (format ofd " 0 };\n") (fclose ofd) (fclose ofdh) ) ) (define (cg_normal_phone_name x) ;; Some phonenames aren't valid C labels (cond ((string-matches x ".*@.*" x) (intern (string-append (string-before x "@") "atsign" (string-after x "@")))) ((string-matches x ".*:.*") (intern (string-append (string-before x ":") "sc" (string-after x ":")))) (t x))) (provide 'make_cg)