1
0
Fork 0

Update ATIS voice generation scripts

Split voice samples into two separate files (airport and phraseology).
Compress voice samples.
This commit is contained in:
ThorstenB 2012-10-13 01:27:52 +02:00
parent 2d424062b7
commit 3bf09215b0
7 changed files with 119 additions and 25 deletions

4
scripts/atis/.gitignore vendored Normal file
View file

@ -0,0 +1,4 @@
*.vlist
*.vce
*.wav.gz
snip/*

50
scripts/atis/README Normal file
View file

@ -0,0 +1,50 @@
The ATIS Voice Generation HowTo
-------------------------------
Required packages / installation hints by J. Denker
---------------------------------------------------
cpan Audio::Wav
apt-get install festival mbrola sox festlex-oald
cd \$tars
wget http://tcts.fpms.ac.be/synthesis/mbrola/dba/en1/en1-980910.zip
wget http://www.cstr.ed.ac.uk/downloads/festival/1.95/festvox_en1.tar.gz
cd /usr/share/festival/voices/english
mkdir en1_mbrola
cd en1_mbrola
unzip \$tars/en1-980910.zip
cd /usr/share/festival
mkdir lib
cd lib
ln -s ../voices ./
cd /usr/share
tar -xpzvf \$tars/festvox_en1.tar.gz
Generating Voice Files
----------------------
1. Configure paths to fgdata and flightgear sources
export FG_ROOT=/home/whatever/fgdata
export FG_SRC=/home/whatever/flightgear
2. Create phraseology word list
./atis-lex.pl > phraseology.vlist
3. Create airport word list
export ATIS_ONLY=yes
./list-airports.pl | ./words_per_line.sh > airports.vlist
4. Check for and fix non-UTF8 encoded airport names
./find_nonUTF8.pl
5. Generate phraseology voice file
./synth.pl phraseology.vlist phraseology.vce phraseology.wav
6. Generate airport voice file
./synth.pl airports.vlist airports.vce airports.wav
7. Install *.vce and *.wav.gz files in fgdata:
cp phraseology.vce $(FG_ROOT)/ATC/voices/default/.
cp phraseology.wav.gz $(FG_ROOT)/ATC/voices/default/.
cp airports.vce $(FG_ROOT)/ATC/voices/default/.
cp airports.wav.gz $(FG_ROOT)/ATC/voices/default/.

View file

@ -1,16 +1,14 @@
#! /usr/bin/perl -w
sub usage {
print <<\EoF;
print <<EoF;
Read the atis_lexicon.hxx file and print
the vocabulary words ... plus phonetic digits and letters.
See also list-airports.pl
Typical usage:
(echo "/"
FG_ROOT=/games/$whatever/fgd ATIS_ONLY=yes ./list-airports.pl
FG_ROOT=/games/$whatever/fgd ./atis-lex.pl) > $whatever.vlist
FG_ROOT=/home/whatever/fgdata FG_SRC=/home/whatever/flightgear ./atis-lex.pl > phraseology.vlist
EoF
}
@ -24,13 +22,14 @@ main: {
usage;
exit;
}
my $mapfn = "$fgroot/../fgs/src/ATCDCL/atis_lexicon.hxx";
my $mapfn = "$ENV{'FG_SRC'}/src/ATCDCL/atis_lexicon.hxx";
my $mapch = Symbol::gensym;
if (!open($mapch, '<', $mapfn)) {
print STDERR "Could not open abbreviation file '$mapfn'\n";
print STDERR "Maybe you need to set FG_ROOT\n";
exit(1);
}
print "/\n";
while (my $line = <$mapch>) {
chomp $line;
if ($line =~ s/^[ \t]*Q[(]//) {
@ -76,5 +75,6 @@ whiskey
xray
yankee
zulu
decimal
EoF
}

View file

@ -2,7 +2,7 @@
my($content, $length);
open(FILE, "< atis.list") || die "Unable to open file small. <$!>\n";
open(FILE, "< airports.vlist") || die "Unable to open file small. <$!>\n";
while( chomp($content = <FILE>) ) {
$length = length($content);

View file

@ -9,14 +9,14 @@ Print airport names, one per line.
Remapping is done by reference to the atis_remap.hxx file.
Typical usage:
FG_ROOT=whatever ATIS_ONLY=yes ./list-airports.pl | words_per_line.sh > atis.list
FG_ROOT=whatever FG_SRC=whatever ATIS_ONLY=yes ./list-airports.pl | ./words_per_line.sh > airports.vlist
EoF
}
use strict;
use Symbol;
my $noparen = 1;
my $noparen = 1;
my $verbose = 0;
my $apt_name = '';
my $lat;
@ -38,6 +38,7 @@ my $noparen = 1;
my $fgroot = $ENV{'FG_ROOT'} || '.';
my $atis_only = $ENV{'ATIS_ONLY'} || 0;
my $mapfn = "$ENV{'FG_SRC'}/src/ATCDCL/atis_remap.hxx";
sub process_apt {
if ($atis_only && ! $atis) {
@ -60,7 +61,6 @@ sub get_remap {
# Note: in this context, GKI probably stands for Gereja Kristen Indonesia
# I guess the church builds lots of airports.
my $mapfn = "$fgroot/../fgs/src/ATCDCL/atis_remap.hxx";
my $mapch = Symbol::gensym;
if (!open($mapch, '<', $mapfn)) {
print STDERR "Could not open abbreviation file '$mapfn'\n";
@ -84,11 +84,16 @@ sub get_remap {
}
main: {
if (@ARGV) {
usage;
exit;
}
get_remap;
my $delim = '-';
my $incmd = 'zcat /games/sport/fgd/Airports/apt.dat.gz';
my $fgroot = $ENV{'FG_ROOT'} || 0;
my $incmd = "zcat $fgroot/Airports/apt.dat.gz";
my $inch = Symbol::gensym;
open ($inch, '-|', $incmd)
|| die "Couldn't open pipe from '$incmd'\n";

BIN
scripts/atis/quiet0.500.wav Normal file

Binary file not shown.

View file

@ -88,6 +88,7 @@ my %fixup = (
main: {
my $skip = 0;
my $fmtcheck = 1;
my $oneword = 0;
my $gripe = 0;
my $out_bits_sample = 8; ## this is what FGFS expects
@ -122,6 +123,10 @@ main: {
$oneword++;
next argx;
}
if ($arg eq '-nocheck') {
$fmtcheck=0;
next argx;
}
if ($arg =~ '^-') {
die "Unrecognized option '$arg'\n";
}
@ -184,23 +189,31 @@ main: {
|| die "Could not create directory 'snip' : $!\n";
}
############## system "/bin/cp nothing.wav t1.wav";
my $where = 0;
my $wav = new Audio::Wav;
my $waver = $wav -> read("quiet0.500.wav");
my $sample_rate = -1;
my $channels = -1;
my $bits_sample = -1;
$sample_rate = ${$waver->details()}{'sample_rate'};
$channels = ${$waver->details()}{'channels'};
$bits_sample = ${$waver->details()}{'bits_sample'};
############## system "/bin/cp nothing.wav t1.wav";
my $where = 0;
my $ii = 0;
snipper: for my $thing (sort keys %list) {
$ii++;
my $iix = sprintf('%05d', $ii);
my $xfn = "./snip/x$iix";
print( "$xfn\n");
my $fraise = lc($thing);
if (exists $fixup{$fraise}) {
#xxxx print "fixing $fraise\n";
$fraise = $fixup{$fraise};
}
## This turns dashes and other funny stuff into spaces
## in the phrase to be processed:
$fraise =~ s%[^a-z']+% %gi;
@ -223,18 +236,27 @@ main: {
next snipper;
}
}
}
my $wav = new Audio::Wav;
my $waver = $wav -> read("$xfn.wav");
if ($sample_rate < 0) {
$sample_rate = ${$waver->details()}{'sample_rate'};
$channels = ${$waver->details()}{'channels'};
$bits_sample = ${$waver->details()}{'bits_sample'};
} else {
$sample_rate == ${$waver->details()}{'sample_rate'}
&& $channels == ${$waver->details()}{'channels'}
&& $bits_sample == ${$waver->details()}{'bits_sample'}
|| die "audio format not the same: $xfn.wav";
$ii = 0;
snipper: for my $thing (sort keys %list) {
$ii++;
my $iix = sprintf('%05d', $ii);
my $xfn = "./snip/x$iix";
if ($fmtcheck == 1) {
my $wav = new Audio::Wav;
my $waver = $wav -> read("$xfn.wav");
if ($sample_rate < 0) {
$sample_rate = ${$waver->details()}{'sample_rate'};
$channels = ${$waver->details()}{'channels'};
$bits_sample = ${$waver->details()}{'bits_sample'};
} else {
$sample_rate == ${$waver->details()}{'sample_rate'}
&& $channels == ${$waver->details()}{'channels'}
&& $bits_sample == ${$waver->details()}{'bits_sample'}
|| die "audio format not the same: $xfn.wav";
}
}
my $statcmd = "2>&1 sox $xfn.wav -n stat";
@ -268,12 +290,16 @@ main: {
if ($size == 0) {
print STDERR "?Warning! Zero-size audio file for $iix '$thing'\n";
}
if ($vol > 20) {
## unreasonable volume, happens with 'silent' files
$vol = 0;
}
printf("%s %6.3f %6d '%s'\n", $iix, $vol, $size, $thing);
my $subsize = int($size/2);
printf $index ("%-45s %10d %10d\n", $thing, $where, $subsize);
$where += $subsize;
my $volume_cmd = sprintf("sox -v %6.3f %s.wav %s.raw",
$vol*0.9, $xfn, $xfn);
########## print "+ $volume_cmd\n";
@ -300,6 +326,7 @@ main: {
die "Cat command failed: $cat_cmd";
}
## Convert RAW to WAVE format
my $wav_cmd = "sox --rate $sample_rate --bits $bits_sample"
. " --encoding signed-integer"
. " ./snip/everything.raw --rate 8000 --bits $out_bits_sample $out_wav";
@ -311,4 +338,12 @@ main: {
if ($?) {
die ".wav command failed: $wav_cmd";
}
## Compress WAVE file
my $gz_cmd = "gzip -f $out_wav";
my $gz_handle = Symbol::gensym;
open ($gz_handle, '|-', $gz_cmd)
|| die "Couldn't open pipe to command '$gz_cmd'\n";
close $gz_handle;
system("rm snip/*; rmdir snip");
}