Index: tools/configure =================================================================== --- tools/configure (revision 14429) +++ tools/configure (working copy) @@ -329,7 +329,7 @@ if [ -f "`which flite`" ]; then FLITE="F(l)ite " - FLITE_OPTS="FLITE_OPTS=\"\"" + FLITE_OPTS="" DEFAULT_TTS="flite" DEFAULT_TTS_OPTS=$FLITE_OPTS DEFAULT_NOISEFLOOR="500" @@ -337,7 +337,7 @@ fi if [ -f "`which espeak`" ]; then ESPEAK="(e)Speak " - ESPEAK_OPTS="ESPEAK_OPTS=\"\"" + ESPEAK_OPTS="" DEFAULT_TTS="espeak" DEFAULT_TTS_OPTS=$ESPEAK_OPTS DEFAULT_NOISEFLOOR="500" @@ -345,7 +345,7 @@ fi if [ -f "`which festival`" ]; then FESTIVAL="(F)estival " - FESTIVAL_OPTS="FESTIVAL_OPTS=\"\"" + FESTIVAL_OPTS="" DEFAULT_TTS="festival" DEFAULT_TTS_OPTS=$FESTIVAL_OPTS DEFAULT_NOISEFLOOR="500" @@ -354,7 +354,7 @@ # Allow SAPI if Windows is in use if [ -f "`which winver`" ]; then SAPI5="(S)API5 " - SAPI5_OPTS="SAPI5_OPTS=\"\"" + SAPI5_OPTS="" DEFAULT_TTS="sapi5" DEFAULT_TTS_OPTS=$SAPI5_OPTS DEFAULT_NOISEFLOOR="500" @@ -397,10 +397,10 @@ echo "Using $TTS_ENGINE for TTS" # Allow the user to input manual commandline options - printf "Enter $TTS_ENGINE options (enter for defaults `echo $TTS_OPTS |sed 's/.*=//'`): " + printf "Enter $TTS_ENGINE options (enter for defaults \"$TTS_OPTS\"): " USER_TTS_OPTS=`input` if [ -n "$USER_TTS_OPTS" ]; then - TTS_OPTS="`echo $TTS_OPTS | sed 's/=.*//'`=\"$USER_TTS_OPTS\"" + TTS_OPTS="$USER_TTS_OPTS" fi echo "" @@ -408,7 +408,7 @@ if [ -f "`which oggenc`" ]; then OGGENC="(O)ggenc " DEFAULT_ENC="oggenc" - VORBIS_OPTS="VORBIS_OPTS=\"-q0 --downmix\"" + VORBIS_OPTS="-q0 --downmix" DEFAULT_ENC_OPTS=$VORBIS_OPTS DEFAULT_CHOICE="O" fi @@ -422,7 +422,7 @@ if [ -f "`which lame`" ]; then LAME="(L)ame " DEFAULT_ENC="lame" - LAME_OPTS="LAME_OPTS=\"--resample 12 -t -m m -h -V 9 -S\"" + LAME_OPTS="--resample 12 -t -m m -h -V 9 -S" DEFAULT_ENC_OPTS=$LAME_OPTS DEFAULT_CHOICE="L" fi @@ -456,25 +456,16 @@ echo "Using $ENCODER for encoding voice clips" # Allow the user to input manual commandline options - printf "Enter $ENCODER options (enter for defaults `echo $ENC_OPTS |sed 's/.*=//'`): " + printf "Enter $ENCODER options (enter for defaults \"$ENC_OPTS\"): " USER_ENC_OPTS=`input` if [ -n "$USER_ENC_OPTS" ]; then - ENC_OPTS="`echo $ENC_OPTS | sed 's/=.*//'`=\"$USER_ENC_OPTS\"" + ENC_OPTS=$USER_ENC_OPTS fi TEMPDIR="${pwd}" if [ -f "`which cygpath`" ]; then TEMPDIR=`cygpath . -a -w` fi - - cat > voicesettings-$thislang.sh < ) \___| < | \_\ ( <_> > < < +# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ +# \/ \/ \/ \/ \/ +# $Id: +# +# Copyright (C) 2007 Jonas Häggqvist +# +# All files in this archive are subject to the GNU General Public License. +# See the file COPYING in the source tree root for full license agreement. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. + +use strict; +use warnings; +use File::Basename; +use File::Copy; +use Switch; +use vars qw($V $C $t $l $e $E $s $S $i $v); +use IPC::Open3; +use Digest::MD5 qw(md5_hex); + +sub printusage { + print < + Specify which target you want to build voicefile for. Must include + any features that target supports. + + -i= + Numeric target id. Needed for voice building. + + -l= + Specify which language you want to build. Without .lang extension. + + -e= + Which encoder to use for voice strings + + -E= + Which encoder options to use when compressing voice strings. Enclose + in double quotes if the options include spaces. + + -s= + Which TTS engine to use. + + -S= + Options to pass to the TTS engine. Enclose in double quotes if the + options include spaces. + + -v + Be verbose +USAGE +; +} + +# Initialize TTS engine. May return an object or value which will be passed +# to voicestring and shutdown_tts +sub init_tts { + my ($tts_engine, $tts_engine_opts) = @_; + my $ret = undef; + switch($tts_engine) { + case "festival" { + my $pid = open(FESTIVAL_SERVER, "| festival --server > /dev/null 2>&1"); + $ret = *FESTIVAL_SERVER; + $ret = $pid; + } + } + return $ret; +} + +# Shutdown TTS engine if necessary. +sub shutdown_tts { + my ($tts_engine, $tts_object) = @_; + switch($tts_engine) { + case "festival" { + # Send SIGTERM to festival server + kill TERM => $tts_object; + } + } +} + +# Produce a wav file of the text given +sub voicestring { + our $verbose; + my ($string, $output, $tts_engine, $tts_engine_opts, $tts_object) = @_; + my $cmd; + printf("Generate \"%s\" with %s in file %s\n", $string, $tts_engine, $output) if $verbose; + switch($tts_engine) { + case "festival" { + # festival_client lies to us, so we have to do awful soul-eating + # work with IPC::open3() + $cmd = "festival_client --server localhost --otype riff --ttw --output \"$output\""; + print("> $cmd\n") if $verbose; + # Open command, and filehandles for STDIN, STDOUT, STDERR + my $pid = open3(*CMD_IN, *CMD_OUT, *CMD_ERR, $cmd); + # Put the string to speak into STDIN and close it + print(CMD_IN $string); + close(CMD_IN); + while () { + } + close(CMD_OUT); + close(CMD_ERR); + } + case "flite" { + $cmd = "flite $tts_engine_opts -t \"$string\" \"$output\""; + print("> $cmd\n") if $verbose; + `$cmd`; + } + case "espeak" { + # xxx: $tts_engine_opts isn't used + $cmd = "espeak $tts_engine_opts -w $output"; + print("> $cmd\n") if $verbose; + open(ESPEAK, "| $cmd"); + print ESPEAK $string . "\n"; + close(ESPEAK); + } + case "sapi5" { + # xxx: re-implement SAPI5 building + } + } +} + +# Encode a wav file into the given destination file +sub encodewav { + our $verbose; + my ($input, $output, $encoder, $encoder_opts) = @_; + printf("Encode \"%s\" with %s in file %s\n", $input, $encoder, $output) if $verbose; + switch ($encoder) { + case 'lame' { + my $cmd = "lame $encoder_opts \"$input\" \"$output\""; + print("> $cmd\n") if $verbose; + `lame $encoder_opts "$input" "$output"`; + `$cmd`; + } + case 'vorbis' { + `oggenc $encoder_opts "$input" -o "$output"`; + } + case 'speexenc' { + `speexenc $encoder_opts "$input" "$output"`; + } + } +} + +# Run genlang and create voice clips for each string +sub generateclips { + our $verbose; + my ($language, $target, $encoder, $encoder_opts, $tts_engine, $tts_engine_opts) = @_; + my $genlang = dirname($0) . '/genlang'; + my $english = dirname($0) . '/../apps/lang/english.lang'; + my $langfile = dirname($0) . '/../apps/lang/' . $language . '.lang'; + my $id = ''; + my $voice = ''; + my $cmd = "$genlang -o -t=$target -e=$english $langfile 2>/dev/null"; + my $pool_file; + open(VOICEFONTIDS, "> voicefontids"); + + my $tts_object = init_tts($tts_engine, $tts_engine_opts); + for (`$cmd`) { + my $line = $_; + print(VOICEFONTIDS $line); + if ($line =~ /^id: (.*)$/) { + $id = $1; + } + elsif ($line =~ /^voice: "(.*)"$/) { + $voice = $1; + if ($id !~ /^NOT_USED_.*$/) { + # If we have a pool of snippes, see if the string exists there first + if (defined($ENV{'POOL'})) { + $pool_file = sprintf("%s/%s-%s-%s.mp3", $ENV{'POOL'}, md5_hex($voice), $language, $tts_engine); + if (-f $pool_file) { + printf("Re-using %s from pool\n", $id) if $verbose; + copy($pool_file, $id . '.mp3'); + } + } + if (! -f $id . '.mp3') { + voicestring($voice, $id . '.wav', $tts_engine, $tts_engine_opts, $tts_object); + if (defined($ENV{'POOL'})) { + encodewav($id . '.wav', $pool_file, $encoder, $encoder_opts); + copy($pool_file, $id . '.mp3'); + } + else { + encodewav($id . '.wav', $id . '.mp3', $encoder, $encoder_opts); + } + } + } + } + } + close(VOICEFONTIDS); + shutdown_tts($tts_engine, $tts_object); +} + +# Assemble the voicefile +sub createvoice { + my ($language, $target_id) = @_; + my $voicefont = dirname($0) . '/voicefont'; + my $cmd = "$voicefont 'voicefontids' $target_id ./ ${language}.voice"; + `$cmd`; +} + +# Check parameters +my $printusage = 0; +unless (defined($V) or defined($C)) { print("Missing either -V or -C\n"); $printusage = 1; } +if (defined($V)) { + unless (defined($t)) { print("Missing -t argument\n"); $printusage = 1; } + unless (defined($l)) { print("Missing -l argument\n"); $printusage = 1; } + unless (defined($i)) { print("Missing -i argument\n"); $printusage = 1; } +} +elsif (defined($C)) { + unless (defined($ARGV[0])) { print "Missing path argument\n"; $printusage = 1; } +} +unless (defined($e)) { print("Missing -e argument\n"); $printusage = 1; } +unless (defined($E)) { print("Missing -E argument\n"); $printusage = 1; } +unless (defined($s)) { print("Missing -s argument\n"); $printusage = 1; } +unless (defined($S)) { print("Missing -S argument\n"); $printusage = 1; } +if ($printusage == 1) { printusage(); exit 1; } + +if (defined($v)) { + our $verbose = 1; +} + +# Do what we're told +if ($V == 1) { + generateclips($l, $t, $e, $E, $s, $S); + createvoice($l, $t, $i); +} +elsif ($C) { + # xxx: Implement .talk clip generation +} Property changes on: tools/voice.pl ___________________________________________________________________ Name: svn:executable + *