| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543 |
- #!/bin/sh
- ###########################################################################
- ## ##
- ## Language Technologies Institute ##
- ## Carnegie Mellon University ##
- ## Copyright (c) 2002-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. ##
- ## ##
- ###########################################################################
- ## ##
- ## Build a flite voice from a festvox voice ##
- ## ##
- ## C files are built into flite/ ##
- ## ##
- ###########################################################################
- FIND_STS=$FLITEDIR/bin/find_sts
- FESTIVAL=$ESTDIR/../festival/bin/festival
- if [ "$PROMPTFILE" = "" ]
- then
- if [ $# -ge 2 ]
- then
- export PROMPTFILE=$2
- else
- export PROMPTFILE=etc/txt.done.data
- fi
- fi
- if [ "$SIODHEAPSIZE" = "" ]
- then
- SIODHEAPSIZE=20000000
- export SIODHEAPSIZE
- fi
- HEAPSIZE=$SIODHEAPSIZE
- . ./etc/voice.defs
- if [ $# = 0 ]
- then
- if [ "$FV_TYPE" = "clunits" ]
- then
- $0 lpc
- $0 sts
- $0 mcep
- $0 clunits
- elif [ "$FV_TYPE" = "ldom" ]
- then
- $0 lpc
- $0 sts
- $0 mcep
- $0 clunits
- elif [ "$FV_TYPE" = "diphone" ]
- then
- $0 lpc
- $0 sts etc/txt.done.data g721
- $0 diphone
- elif [ "$FV_TYPE" = "cg" ]
- then
- $0 cg
- else
- echo $0 unsupported voicetype $FV_TYPE
- fi
- exit 0
- fi
- # Build lpc coefficients
- if [ "$1" = "lpc" ]
- then
- echo "Finding LPC coefficients"
- ./bin/make_lpc $PROMPTFILE
- echo "Finding LPC min, max and range"
- # make lpc.params file
- cat $PROMPTFILE |
- awk '{print $2}' |
- while read i
- do
- $ESTDIR/bin/ch_track -otype est_ascii lpc/$i.lpc |
- sed '1,/EST_Header_End/d'
- done |
- awk 'BEGIN {min=0; max=0;}
- {for (i=4; i<=NF; i++)
- {
- if ($i < min) min = $i;
- if ($i > max) max = $i;
- }
- }
- END {printf("LPC_MIN=%f\n",min);
- printf("LPC_MAX=%f\n",max);
- printf("LPC_RANGE=%f\n",max-min);
- }' >lpc/lpc.params
- exit 0
- fi
- # build sts files
- if [ "$1" = "sts" ]
- then
- echo "Finding STS files"
- if [ ! -d sts ]
- then
- mkdir sts
- fi
- . ./lpc/lpc.params
- CODEC=ulaw
- if [ "$#" = "3" ]
- then
- CODEC=$3
- fi
- cat $PROMPTFILE |
- awk '{print $2}' |
- while read i
- do
- fname=$i
- echo $fname STS
- if [ $CODEC = "g721vuv" -o $CODEC = "vuv" ]
- then
- $ESTDIR/bin/ch_track -itype ascii -otype est_binary -s 0.005 -o v.v v/$fname.v
- $FIND_STS -lpcmin $LPC_MIN -lpcrange $LPC_RANGE -lpc lpc/$fname.lpc -wave wav/$fname.wav -o sts/$fname.sts -codec $CODEC -vuv v.v
- else
- $FIND_STS -lpcmin $LPC_MIN -lpcrange $LPC_RANGE -lpc lpc/$fname.lpc -wave wav/$fname.wav -o sts/$fname.sts -codec $CODEC
- fi
- done
- echo $CODEC >flite/codec
- exit 0
- fi
- if [ "$1" = "voxdata" ]
- then # for clunits external data
- echo converting ${FV_VOICENAME}_ressize
- grep "^ " flite/${FV_VOICENAME}_ressize.c |
- tr -d "," |
- awk '{for (i=1; i<=NF; i++)
- {
- if ($i > 255)
- print 255;
- else
- print $i;}}' |
- $FLITEDIR/tools/a2byte.pl >flite/${FV_VOICENAME}_ressize.raw
- echo converting ${FV_VOICENAME}_lpc
- grep "^ " flite/${FV_VOICENAME}_lpcall.c |
- tr -d "," | sed 's/^ //;s/ */\n/g' |
- $FLITEDIR/tools/a2short.pl >flite/${FV_VOICENAME}_lpc.raw
- echo converting ${FV_VOICENAME}_mcep
- grep "^ " flite/${FV_VOICENAME}_mcepall.c |
- tr -d "," | sed 's/^ //;s/ */\n/g' |
- $FLITEDIR/tools/a2short.pl >flite/${FV_VOICENAME}_mcep.raw
- echo converting ${FV_VOICENAME}_residual
- grep "^ " flite/${FV_VOICENAME}_resall.c |
- tr -d "," | sed 's/^ //;s/ */\n/g' |
- $FLITEDIR/tools/a2byte.pl >flite/${FV_VOICENAME}_res.raw
- echo converting ${FV_VOICENAME}_residx
- grep "^ " flite/${FV_VOICENAME}_residx.c |
- tr -d "," | sed 's/^ *//;s/ */\n/g' |
- $FLITEDIR/tools/a2int.pl >flite/${FV_VOICENAME}_residx.raw
- wc flite/${FV_VOICENAME}_residx.raw \
- flite/${FV_VOICENAME}_lpc.raw \
- flite/${FV_VOICENAME}_mcep.raw \
- flite/${FV_VOICENAME}_res.raw \
- flite/${FV_VOICENAME}_ressize.raw
- printf "CMUFLITE\0" >flite/${FV_VOICENAME}.voxdata
- printf "%54s\0" ${FV_VOICENAME} >>flite/${FV_VOICENAME}.voxdata
- wc flite/${FV_VOICENAME}_residx.raw \
- flite/${FV_VOICENAME}_lpc.raw \
- flite/${FV_VOICENAME}_mcep.raw \
- flite/${FV_VOICENAME}_res.raw \
- flite/${FV_VOICENAME}_ressize.raw |
- awk '{if ($4 != "total") print $3}' |
- $FLITEDIR/tools/a2int.pl >>flite/${FV_VOICENAME}.voxdata
- # Order goes from 4 bytes, 2 bytes, 1 byte info to ensure alignment
- cat flite/${FV_VOICENAME}_residx.raw >>flite/${FV_VOICENAME}.voxdata
- cat flite/${FV_VOICENAME}_lpc.raw >>flite/${FV_VOICENAME}.voxdata
- cat flite/${FV_VOICENAME}_mcep.raw >>flite/${FV_VOICENAME}.voxdata
- cat flite/${FV_VOICENAME}_res.raw >>flite/${FV_VOICENAME}.voxdata
- cat flite/${FV_VOICENAME}_ressize.raw >>flite/${FV_VOICENAME}.voxdata
- exit 0
- fi
- # build mcep (params)
- if [ "$1" = "mcep" ]
- then
- echo "Finding MCEP min max and range"
- cat $PROMPTFILE |
- awk '{print $2}' |
- while read i
- do
- $ESTDIR/bin/ch_track -otype est_ascii mcep/$i.mcep |
- sed '1,/EST_Header_End/d'
- done |
- awk 'BEGIN {min=0; max=0;}
- {for (i=4; i<=NF; i++)
- {
- if ($i < min) min = $i;
- if ($i > max) max = $i;
- }
- }
- END {printf("(set! mcep_min %f)\n",min);
- printf("(set! mcep_max %f)\n",max);
- printf("(set! mcep_range %f)\n",max-min);
- }' >mcep/mcep.params.scm
- exit 0
- fi
- if [ "$1" = "cg_spam" ]
- then
- #Dump phrase tree
- $FESTIVAL --heap $HEAPSIZE -b \
- $FLITEDIR/tools/make_cg.scm \
- $FLITEDIR/tools/make_cart.scm \
- $FLITEDIR/tools/make_vallist.scm \
- festvox/${FV_VOICENAME}_cg.scm \
- '(begin
- (voice_'$FV_VOICENAME'_cg)
- (if cg:spamf0
- (begin
- (format t "cg_convert: Dumping spamf0 models\n")
- (set! current_node -1)
- (set! feat_nums nil)
- (set! val_table nil)
- (set! ptree (car (load "festival/trees/phrase.tree" t)))
- (set! ofd (fopen (format nil "flite/%s_spamf0_phrase.c" "'$FV_VOICENAME'") "w"))
- (set! ofdh (fopen (format nil "flite/%s_spamf0_phrase.h" "'$FV_VOICENAME'") "w"))
- (format ofd "/*****************************************************/\n")
- (format ofd "/** Autogenerated %s phrase carts */\n" "'$FV_VOICENAME'")
- (format ofd "/*****************************************************/\n")
- (format ofd "\n")
- (format ofd "#include \"cst_string.h\"\n")
- (format ofd "#include \"cst_cart.h\"\n")
- (format ofd "#include \"%s_spamf0_phrase.h\"\n" "'$FV_VOICENAME'")
- (do_carttoC ofd ofdh (format nil "%s_spamf0_phrase" "'$FV_VOICENAME'") ptree)
- (fclose ofd)
- (fclose ofdh)
- )))'
-
- #Dump accent tree
- $FESTIVAL --heap $HEAPSIZE -b \
- $FLITEDIR/tools/make_cg.scm \
- $FLITEDIR/tools/make_cart.scm \
- $FLITEDIR/tools/make_vallist.scm \
- festvox/${FV_VOICENAME}_cg.scm \
- '(begin
- (voice_'$FV_VOICENAME'_cg)
- (if cg:spamf0
- (begin
- (set! current_node -1)
- (set! feat_nums nil)
- (set! val_table nil)
- (set! acctree (car (load "festival/trees/acc.tree" t)))
- (set! ofd (fopen (format nil "flite/%s_spamf0_accent.c" "'$FV_VOICENAME'") "w"))
- (set! ofdh (fopen (format nil "flite/%s_spamf0_accent.h" "'$FV_VOICENAME'") "w"))
- (format ofd "/*****************************************************/\n")
- (format ofd "/** Autogenerated %s spam accent params */\n" "'$FV_VOICENAME'")
- (format ofd "/*****************************************************/\n")
- (format ofd "\n")
- (format ofd "#include \"cst_string.h\"\n")
- (format ofd "#include \"cst_cart.h\"\n")
- (format ofd "#include \"%s_spamf0_accent.h\"\n" "'$FV_VOICENAME'")
- (set! old_carttoC_extract_answer carttoC_extract_answer)
- (set! carttoC_extract_answer carttoC_extract_spectral_frame)
- (do_carttoC ofd ofdh (format nil "%s_spamf0_accent" "'$FV_VOICENAME'") acctree)
- (set! carttoC_extract_answer old_carttoC_extract_answer)
- (fclose ofd)
- (fclose ofdh)
- )))'
- #Dump accent params
- $FESTIVAL --heap $HEAPSIZE -b \
- $FLITEDIR/tools/make_cg.scm \
- $FLITEDIR/tools/make_cart.scm \
- $FLITEDIR/tools/make_vallist.scm \
- festvox/${FV_VOICENAME}_cg.scm \
- '(begin
- (voice_'$FV_VOICENAME'_cg)
- (if cg:spamf0
- (begin
- (set! current_node -1)
- (set! feat_nums nil)
- (set! val_table nil)
- (set! mfd (fopen (format nil "flite/%s_spamf0_accent_params.c" "'$FV_VOICENAME'") "w"))
- (set! acctrack (track.load "festival/trees/cb.params"))
- (format mfd "/*****************************************************/\n")
- (format mfd "/** Autogenerated Spam accent vectors for %s */\n" "'$FV_VOICENAME'")
- (format mfd "/*****************************************************/\n")
- (set! num_channels (track.num_channels acctrack))
- (set! num_frames (track.num_frames acctrack))
- (set! i 0)
- (while (< i num_frames)
- (output_accent_frame "'$FV_VOICENAME'" acctrack i mfd)
- (set! i (+ 1 i)))
- (format mfd "\n\n")
- (format mfd "const float * const %s_spamf0_accent_vectors[] = {\n" "'$FV_VOICENAME'" )
- (set! i 0)
- (while (< i num_frames)
- (format mfd " %s_spamf0_accent_frame_%d,\n" "'$FV_VOICENAME'" i)
- (set! i (+ 1 i)))
- (format mfd "};\n\n")
- (fclose mfd)
- )))'
- $0 cg
- exit 0
- fi
- if [ "$1" = "cg" ] # clustergen
- then
- # For smaller (and quicker) voices you can build with a reduced order
- # this seems to be ok for values down to 13
- RORDER=0
- if [ $# = 2 ]
- then
- RORDER=$2
- fi
- echo cg_convert: finding parameter ranges
- $ESTDIR/bin/ch_track -otype est_ascii festival/trees/${FV_VOICENAME}_mcep*.params |
- sed '1,/EST_Header_End/d' |
- awk 'BEGIN {nc=0;}
- {if (nc == 0) nc = NF;
- if (NF == nc )
- {
- for (i=3; i<=NF; i++)
- {
- if ((NR == 1) || ($i < min[i])) min[i] = $i;
- if ((NR == 1) || ($i > max[i])) max[i] = $i;
- }
- nc = NF;
- }
- }
- END {for (i=3; i<=nc; i++)
- {
- printf("( %f %f )\n",min[i],max[i]-min[i]);
- }
- }' >festival/trees/${FV_VOICENAME}_min_range.scm
- cat etc/f0.params |
- sed 's/=/ /' |
- head -2 |
- awk '{printf("(set! %s %s)\n",$1,$2)}' >flite/f0_params.scm
- $FESTIVAL --heap $HEAPSIZE -b \
- '(set! cg_reduced_order '$RORDER')' \
- flite/f0_params.scm \
- $FLITEDIR/tools/make_cg.scm \
- $FLITEDIR/tools/make_cart.scm \
- $FLITEDIR/tools/make_vallist.scm \
- '(cg_convert
- "'$FV_VOICENAME'"
- "."
- "flite/")'
- echo "flite_build cg complete. You can compile the generated voice by"
- echo " cd flite; make"
- exit 0
- fi
- if [ "$1" = "clunits" ] # clunits or ldom
- then
- echo "Building clunits/ldom index"
- sed '1,/EST_Header_End/d' festival/clunits/$FV_VOICENAME.catalogue |
- awk 'BEGIN {p="CLUNIT_NONE";}
- {if ((NR > 1) && (t != "0_0"))
- {
- n = split(t,bits,"_");
- unit_type = substr(t,1,length(t)-(length(bits[n])+1));
- unit_occur = bits[n];
- if ((t == "0_0") || (f != $2) || ($1 == "0_0"))
- printf("%s-%05d -- ( %s %s %s )\n",unit_type,unit_occur,line,p,"CLUNIT_NONE");
- else
- printf("%s-%05d -- ( %s %s unit_%s )\n",unit_type,unit_occur, line,p,$1);
- }
- line = $0;
- if ((t == "0_0") || (f != $2))
- p = "CLUNIT_NONE";
- else
- p=sprintf("unit_%s",t);
- t=$1;
- f=$2;
- }
- END { if (t != "0_0")
- {
- n = split(t,bits,"_");
- unit_type = substr(t,1,length(t)-(length(bits[n])+1));
- unit_occur = bits[n];
- printf("%s-%05d -- ( %s %s %s )\n", unit_type,unit_occur,line,p,"CLUNIT_NONE");
- } }' |
- cat >festival/clunits/$FV_VOICENAME.scm
- cat festival/clunits/$FV_VOICENAME.scm |
- $FLITEDIR/bin/flite_sort |
- sed 's/^.* -- //' >festival/clunits/$FV_VOICENAME.unitordered.scm
- cat festival/clunits/$FV_VOICENAME.scm |
- sed 's/^.* -- //' >festival/clunits/$FV_VOICENAME.fileordered.scm
- rm -f flite/$FV_VOICENAME"_lpc"*
- rm -f flite/$FV_VOICENAME"_mcep"*
- rm -f flite/$FV_VOICENAME"_res"*
- $FESTIVAL --heap $HEAPSIZE -b $FLITEDIR/tools/make_clunits.scm \
- $FLITEDIR/tools/make_cart.scm \
- $FLITEDIR/tools/make_vallist.scm \
- mcep/mcep.params.scm \
- '(clunits_convert "'$FV_VOICENAME'"
- "festival/clunits/'$FV_VOICENAME'.fileordered.scm"
- "festival/clunits/'$FV_VOICENAME'.unitordered.scm"
- "festival/trees/'$FV_VOICENAME'.tree"
- "."
- "flite/")'
- echo "flite_build complete. You can compile the generated voice by"
- echo " cd flite; make"
- exit 0
- fi
- if [ "$1" = "diphone" ]
- then
- echo "Building diphone index"
- # Not a good way to do this, to take the most recent
- idxfile=`ls -t dic/*.est | head -1`
- echo "Using "$idxfile
- sed '1,/EST_Header_End/d' $idxfile |
- awk '{printf("%s ( %s )\n",$1,$0)}' |
- $FLITEDIR/bin/flite_sort |
- sed 's/^.* (/(/' >dic/diphidx.scm
- $FESTIVAL --heap $HEAPSIZE -b $FLITEDIR/tools/make_didb2.scm \
- '(diphtoC "dic/diphidx.scm" "'$FV_VOICENAME'" "sts" "flite")'
- echo "flite_build complete. You can compile the generated voice by"
- echo " cd flite; make"
- exit 0
- fi
- # build index file
- if [ "$1" = "idx" ]
- then
- HEAPSIZE=100000000
- if [ "$FV_TYPE" != "diphone" ] # clunits or ldom
- then
- echo "Building clunits/ldom index"
- sed '1,/EST_Header_End/d' festival/clunits/$FV_VOICENAME.catalogue |
- awk 'BEGIN {p="CLUNIT_NONE";}
- {if ((NR > 1) && (t != "0_0"))
- {
- n = split(t,bits,"_");
- unit_type = substr(t,1,length(t)-(length(bits[n])+1));
- unit_occur = bits[n];
- if ((t == "0_0") || (f != $2) || ($1 == "0_0"))
- printf("%s_%05d -- ( %s %s %s )\n",unit_type,unit_occur,line,p,"CLUNIT_NONE");
- else
- printf("%s_%05d -- ( %s %s unit_%s )\n",unit_type,unit_occur, line,p,$1);
- }
- line = $0;
- if ((t == "0_0") || (f != $2))
- p = "CLUNIT_NONE";
- else
- p=sprintf("unit_%s",t);
- t=$1;
- f=$2;
- }
- END { if (t != "0_0")
- {
- n = split(t,bits,"_");
- unit_type = substr(t,1,length(t)-(length(bits[n])+1));
- unit_occur = bits[n];
- printf("%s_%05d -- ( %s %s %s )\n", unit_type,unit_occur,line,p,"CLUNIT_NONE");
- } }' |
- cat >festival/clunits/$FV_VOICENAME.scm
- cat festival/clunits/$FV_VOICENAME.scm |
- $FLITEDIR/bin/flite_sort |
- sed 's/^.* -- //' >festival/clunits/$FV_VOICENAME.unitordered.scm
- cat festival/clunits/$FV_VOICENAME.scm |
- sed 's/^.* -- //' >festival/clunits/$FV_VOICENAME.fileordered.scm
- rm -f flite/$FV_VOICENAME"_lpc"*
- rm -f flite/$FV_VOICENAME"_mcep"*
- rm -f flite/$FV_VOICENAME"_res"*
- $FESTIVAL --heap $HEAPSIZE -b $FLITEDIR/tools/make_clunits.scm \
- $FLITEDIR/tools/make_cart.scm \
- $FLITEDIR/tools/make_vallist.scm \
- mcep/mcep.params.scm \
- '(clunits_convert "'$FV_VOICENAME'"
- "festival/clunits/'$FV_VOICENAME'.fileordered.scm"
- "festival/clunits/'$FV_VOICENAME'.unitordered.scm"
- "festival/trees/'$FV_VOICENAME'.tree"
- "."
- "flite/")'
- fi
- if [ "$FV_TYPE" = "diphone" ]
- then
- echo "Building diphone index"
- # Not a good way to do this, to take the most recent
- idxfile=`ls -t dic/*.est | head -1`
- echo "Using "$idxfile
- sed '1,/EST_Header_End/d' $idxfile |
- awk '{printf("%s ( %s )\n",$1,$0)}' |
- $FLITEDIR/bin/flite_sort |
- sed 's/^.* (/(/' >dic/diphidx.scm
- $FESTIVAL --heap $HEAPSIZE -b $FLITEDIR/tools/make_didb.scm \
- '(diphtoC "dic/diphidx.scm" "'$FV_VOICENAME'" "sts" "flite")'
- fi
- echo "flite_build complete. You can compile the generated voice by"
- echo " cd flite; make"
- exit 0
- fi
- echo build_flite unknown arguments $*
- exit 1
|