From aad57ea1cc59144475cc80538523121d97b293d4 Mon Sep 17 00:00:00 2001 From: Solomon Peachy Date: Sat, 11 Jul 2020 10:05:40 -0400 Subject: voice: Further enhancements for multi-lingual voice generation * configure: allow use of full tts engine names when making selection * voice.pl: fixes for espeak-ng * build.pm: Add a list of "standard" voices for tooling use The latter will be used by the nightly builder infrastructure to determine what voices to generate. Change-Id: Iff55288f94a30fbe08d8345b730969b7264b5e0f --- tools/builds.pm | 125 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- tools/configure | 20 ++++----- tools/voice.pl | 5 +++ 3 files changed, 139 insertions(+), 11 deletions(-) diff --git a/tools/builds.pm b/tools/builds.pm index fe400b6777..a69300cd3f 100644 --- a/tools/builds.pm +++ b/tools/builds.pm @@ -2,12 +2,15 @@ $publicrelease="3.15"; $releasedate="15 Nov 2019"; $releasenotes="/wiki/ReleaseNotes315"; -# { 'modelname' => { +################################################################ + +# 'modelname' => { # name => 'Full Name', # status => 1, # 0=retired, 1=unusable, 2=unstable, 3=stable # ram => 2, # optional (used?) # manual => 'modelname2', # optional (uses modelname2's manual) # icon => 'modelname3', # optional (uses modelname3's icon) +# voice => 'modelname4' # optional (uses modelname4's voice) # release => '3.14', # optional (final release version, if different from above) # } @@ -493,4 +496,124 @@ sub allbuilds { return @list; } +################################################################ + +# 'voicename' => { +# lang => 'langname', # source rockbox .lang file +# name => 'Native Name ( English Name )', # descriptive text +# short => 'sss', # short iso-ish text +# defengine => 'enginename', # which engine to prefer +# engines => { # supported engines +# enginea = '-opt1=x -opt2=y', # options for enginea +# engineb = '-lang=xx', # options for engineb +# }, +# } + +# A single source language file can have many voice variants. +# For example, Mandarin and Cantonese use the same "Chinese" script. +# Also, different genders or regional accents for the same language + +%voices = ( + # UK English always comes first + 'english' => { + 'lang' => 'english', + 'name' => 'UK English', + 'short' => 'en-uk', + 'defengine' => 'espeak', + 'engines' => { + 'festival' => '--language english', + 'espeak' => '-ven-gb', + 'gtts' => '-l en-gb', + }, + }, + # Everything else in alphabetical order + 'english-us' => { + 'lang' => 'english-us', + 'name' => 'American English', + 'short' => 'en-us', + 'defengine' => 'espeak', + 'engines' => { + 'festival' => '--language english', + 'espeak' => '-ven-us', + 'gtts' => '-l en-us', + }, + }, + 'greek' => { + 'lang' => 'greek', + 'name' => 'Ελληνικά (Greek)', + 'short' => 'el', + 'defengine' => 'espeak', + 'engines' => { + 'espeak' => '-vel', + 'gtts' => '-l el', + }, + }, + 'polski' => { + 'lang' => 'polski', + 'name' => 'Polski (Polish)', + 'short' => 'pl', + 'defengine' => 'espeak', + 'engines' => { + 'espeak' => '-vpl', + 'gtts' => '-l pl', + }, + }, + 'russian' => { + 'lang' => 'russian', + 'name' => 'Русский (Russian)', + 'short' => 'ru', + 'defengine' => 'espeak', + 'engines' => { + 'espeak' => '-vru', + 'gtts' => '-l ru', + }, + }, + 'slovak' => { + 'lang' => 'slovak', + 'name' => 'Slovenský (Slovak)', + 'short' => 'sk', + 'defengine' => 'espeak', + 'engines' => { + 'espeak' => '-vsk', + 'gtts' => '-l sk', + }, + }, + 'srpski' => { + 'lang' => 'srpski', + 'name' => 'српски (Serbian)', + 'short' => 'sr', + 'defengine' => 'espeak', + 'engines' => { + 'espeak' => '-vsr', + 'gtts' => '-l sr', + }, + }, +); + +sub bylang { + return uc $voices{$a}{lang} cmp uc $voices{$b}{lang}; +} + +sub allvoices { + my @list; + + for my $b (sort bylang keys %voices) { + push @list, $b; + } + + return @list; +} + +sub voicesforlang($) { + my $l = shift @_; + my @list; + + for my $b (sort bylang keys %voices) { + push @list, $b if ($voices{$b}{lang} eq $b); + } + + return @list; +} + + 1; diff --git a/tools/configure b/tools/configure index aab3e59dfb..96d45a9173 100755 --- a/tools/configure +++ b/tools/configure @@ -1167,8 +1167,8 @@ voiceconfig () { DEFAULT_CHOICE="O" fi - if [ "$FESTIVAL" = "$FLITE" ] && [ "$FLITE" = "$ESPEAK" ] && [ "$ESPEAK" = "$SAPI" ] && [ "$SAPI" = "$MIMIC"] && [ "$MIMIC" = "$SWIFT" ] && [ "$SWIFT" = "$RBSPEAK" ] && [ "$RBSPEAK" = "$GTTS" ] ; then - echo "You need Festival, eSpeak, Mimic, Flite, or rbspeak in your path, or SAPI available to build voice files" + if [ "$FESTIVAL" = "$FLITE" ] && [ "$FLITE" = "$ESPEAK" ] && [ "$ESPEAK" = "$SAPI" ] && [ "$SAPI" = "$MIMIC"] && [ "$MIMIC" = "$SWIFT" ] && [ "$SWIFT" = "$GTTS" ] && [ "$GTTS" = "$RBSPEAK" ] ; then + echo "You need Festival, eSpeak, Mimic, Flite, gtts, or rbspeak in your path, or SAPI available to build voice files" exit 3 fi @@ -1181,42 +1181,42 @@ voiceconfig () { advopts="$advopts --tts=$option" fi case "$option" in - [Ll]) + [Ll]|flite) TTS_ENGINE="flite" NOISEFLOOR="500" # TODO: check this value TTS_OPTS=$FLITE_OPTS ;; - [Ee]) + [Ee]|espeak) TTS_ENGINE="espeak" NOISEFLOOR="500" TTS_OPTS=$ESPEAK_OPTS ;; - [Ff]) + [Ff]|festival) TTS_ENGINE="festival" NOISEFLOOR="500" TTS_OPTS=$FESTIVAL_OPTS ;; - [Mm]) + [Mm]|mimic) TTS_ENGINE="mimic" NOISEFLOOR="500" TTS_OPTS=$MIMIC_OPTS ;; - [Ss]) + [Ss]|sapi) TTS_ENGINE="sapi" NOISEFLOOR="500" TTS_OPTS=$SAPI_OPTS ;; - [Ww]) + [Ww]|swift) TTS_ENGINE="swift" NOISEFLOOR="500" TTS_OPTS=$SWIFT_OPTS ;; - [Gg) + [Gg]|gtts) TTS_ENGINE="gtts" NOISEFLOOR="500" TTS_OPTS=$GTTS_OPTS ;; - [Oo]) + [Oo]|rbspeak) TTS_ENGINE="rbspeak" NOISEFLOOR="500" TTS_OPTS=$RBSPEAK_OPTS diff --git a/tools/voice.pl b/tools/voice.pl index 05ced3a6d9..0b49ddff04 100755 --- a/tools/voice.pl +++ b/tools/voice.pl @@ -244,6 +244,11 @@ sub voicestring { print("> $cmd\n") if $verbose; system($cmd); } + elsif ($name eq 'espeak-ng') { + $cmd = "espeak-ng $tts_engine_opts -w \"$output\" \"$string\""; + print("> $cmd\n") if $verbose; + system($cmd); + } elsif ($name eq 'sapi') { print({$$tts_object{"stdin"}} "SPEAK\t$output\t$string\r\n"); } -- cgit v1.2.3