]> git.mxchange.org Git - flightgear.git/commitdiff
Update ATIS voice generation scripts
authorThorstenB <brehmt@gmail.com>
Fri, 12 Oct 2012 23:27:52 +0000 (01:27 +0200)
committerThorstenB <brehmt@gmail.com>
Sat, 13 Oct 2012 13:45:15 +0000 (15:45 +0200)
Split voice samples into two separate files (airport and phraseology).
Compress voice samples.

scripts/atis/.gitignore [new file with mode: 0644]
scripts/atis/README [new file with mode: 0644]
scripts/atis/atis-lex.pl
scripts/atis/find_nonUTF8.pl
scripts/atis/list-airports.pl
scripts/atis/quiet0.500.wav [new file with mode: 0644]
scripts/atis/synth.pl

diff --git a/scripts/atis/.gitignore b/scripts/atis/.gitignore
new file mode 100644 (file)
index 0000000..4a675de
--- /dev/null
@@ -0,0 +1,4 @@
+*.vlist
+*.vce
+*.wav.gz
+snip/*
diff --git a/scripts/atis/README b/scripts/atis/README
new file mode 100644 (file)
index 0000000..e5d484b
--- /dev/null
@@ -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/.
+
index 583080e1328c598f90530f30b173776957da4cbc..701f1c673bda2d469f4ed34d5ca7f0cd53c33f19 100755 (executable)
@@ -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
 }
index a5cf22ebc6fabaedea94d6d27ab651c8428a5a92..dcd45cf73f19b4d140d741100d8932270f684eee 100755 (executable)
@@ -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);
index a431fca682a0408b61cfd9838ee2b2149c1f6870..347b92842955b5758515aefc60ab5e1fd3a2e22d 100755 (executable)
@@ -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";
diff --git a/scripts/atis/quiet0.500.wav b/scripts/atis/quiet0.500.wav
new file mode 100644 (file)
index 0000000..bceb4e6
Binary files /dev/null and b/scripts/atis/quiet0.500.wav differ
index 1cc0d222316044a5d627ef2f502e4d56c575d179..86cbf67649ed971ec40143b6c58e7cfa19cc52df 100755 (executable)
@@ -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");
 }