first commit
This commit is contained in:
50
scripts/atis/README
Normal file
50
scripts/atis/README
Normal 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/.
|
||||
|
||||
80
scripts/atis/atis-lex.pl
Executable file
80
scripts/atis/atis-lex.pl
Executable file
@@ -0,0 +1,80 @@
|
||||
#! /usr/bin/perl -w
|
||||
|
||||
sub usage {
|
||||
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:
|
||||
FG_ROOT=/home/whatever/fgdata FG_SRC=/home/whatever/flightgear ./atis-lex.pl > phraseology.vlist
|
||||
EoF
|
||||
}
|
||||
|
||||
use strict;
|
||||
use Symbol;
|
||||
|
||||
my $fgroot = $ENV{'FG_ROOT'} || '.';
|
||||
|
||||
main: {
|
||||
if (@ARGV) {
|
||||
usage;
|
||||
exit;
|
||||
}
|
||||
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[(]//) {
|
||||
$line =~ s/[)][ \t]*$//;
|
||||
print "$line\n";
|
||||
}
|
||||
}
|
||||
print <<EoF;
|
||||
zero
|
||||
one
|
||||
two
|
||||
three
|
||||
four
|
||||
five
|
||||
six
|
||||
seven
|
||||
eight
|
||||
nine
|
||||
niner
|
||||
alpha
|
||||
bravo
|
||||
charlie
|
||||
delta
|
||||
echo
|
||||
foxtrot
|
||||
golf
|
||||
hotel
|
||||
india
|
||||
juliet
|
||||
kilo
|
||||
lima
|
||||
mike
|
||||
november
|
||||
oscar
|
||||
papa
|
||||
quebec
|
||||
romeo
|
||||
sierra
|
||||
tango
|
||||
uniform
|
||||
victor
|
||||
whiskey
|
||||
xray
|
||||
yankee
|
||||
zulu
|
||||
decimal
|
||||
EoF
|
||||
}
|
||||
21
scripts/atis/find_nonUTF8.pl
Executable file
21
scripts/atis/find_nonUTF8.pl
Executable file
@@ -0,0 +1,21 @@
|
||||
#! /usr/bin/perl
|
||||
|
||||
my($content, $length);
|
||||
|
||||
open(FILE, "< airports.vlist") || die "Unable to open file small. <$!>\n";
|
||||
|
||||
while( chomp($content = <FILE>) ) {
|
||||
$length = length($content);
|
||||
|
||||
for( $i = 0; $i < $length; $i++ ) {
|
||||
|
||||
if( ord(substr($content, $i, 1)) > 127 )
|
||||
{
|
||||
print "$content\n";
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
close(FILE);
|
||||
|
||||
exit 0
|
||||
155
scripts/atis/list-airports.pl
Executable file
155
scripts/atis/list-airports.pl
Executable file
@@ -0,0 +1,155 @@
|
||||
#! /usr/bin/perl -w
|
||||
|
||||
sub usage {
|
||||
print <<EoF;
|
||||
Read the apt.dat (or apt.dat.gz) file.
|
||||
Remap airport names to remove ugly abbreviations.
|
||||
Print airport names, one per line.
|
||||
|
||||
Remapping is done by reference to the atis_remap.hxx file.
|
||||
|
||||
Typical usage:
|
||||
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 $verbose = 0;
|
||||
my $apt_name = '';
|
||||
my $lat;
|
||||
my $lon;
|
||||
my $atis;
|
||||
my $country = '';
|
||||
my $elev;
|
||||
my $tower;
|
||||
my $bldgs;
|
||||
my $apt_id;
|
||||
my $shapefile;
|
||||
my $namer = 'NAME';
|
||||
my $skipping = 0;
|
||||
my $tot_apts = 0;
|
||||
|
||||
my %states = ();
|
||||
my %short_country = ();
|
||||
|
||||
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
my $str .= $apt_name;
|
||||
|
||||
$str =~ s' *$''; ## remove trailing spaces
|
||||
if ($noparen) {
|
||||
$str =~ s/[(][^)]*[)]?//g;
|
||||
}
|
||||
print "$str\n";
|
||||
$tot_apts++;
|
||||
}
|
||||
|
||||
my %remap = ();
|
||||
|
||||
sub get_remap {
|
||||
|
||||
# Note: in this context, GKI probably stands for Gereja Kristen Indonesia
|
||||
# I guess the church builds lots of airports.
|
||||
|
||||
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);
|
||||
}
|
||||
while (my $line = <$mapch>) {
|
||||
chomp $line;
|
||||
if ($line =~ s/[ \t]*REMAP[(]//) {
|
||||
$line =~ s/[)][ \t]*$//;
|
||||
my @stuff = split(',', $line, 2);
|
||||
my $from = $stuff[0];
|
||||
my $to = $stuff[1];
|
||||
$to =~ s/^[ \t]*//;
|
||||
if ($to eq 'NIL') {
|
||||
$to = '';
|
||||
}
|
||||
$remap{$from} = $to;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
main: {
|
||||
if (@ARGV) {
|
||||
usage;
|
||||
exit;
|
||||
}
|
||||
|
||||
get_remap;
|
||||
|
||||
my $delim = '-';
|
||||
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";
|
||||
|
||||
|
||||
my $junk = <$inch>;
|
||||
$junk = <$inch>;
|
||||
liner: while (my $line = <$inch>) {
|
||||
chomp $line;
|
||||
my @stuff = split(' ', $line);
|
||||
my $type = shift @stuff || 0;
|
||||
### print "..$type ... $line ...\n";
|
||||
|
||||
if ($type == 1) {
|
||||
## Here if new airport.
|
||||
##
|
||||
## First, print results of previous work, i.e. airport
|
||||
## stanzas already seen ... since the apt.dat file
|
||||
## doesn't have a clear way of signaling the end of a stanza.
|
||||
if ($apt_name) {
|
||||
process_apt();
|
||||
}
|
||||
$apt_name = '';
|
||||
$atis = '';
|
||||
$lat = 0;
|
||||
$lon = 0;
|
||||
$country = '';
|
||||
|
||||
$elev = shift @stuff;
|
||||
$tower = shift @stuff;
|
||||
$bldgs = shift @stuff;
|
||||
$apt_id = shift @stuff;
|
||||
my $name = join $delim, @stuff;
|
||||
|
||||
for my $from (keys %remap) {
|
||||
my $to = $remap{$from};
|
||||
$name =~ s/\b$from\b/$to/gi;
|
||||
}
|
||||
|
||||
## option for plain words, not hyphenated phrases
|
||||
if (1) {
|
||||
$name =~ s/$delim/ /g;
|
||||
}
|
||||
|
||||
$apt_name = "$name";
|
||||
}
|
||||
|
||||
if ($type == 10) {
|
||||
$lat = $stuff[0];
|
||||
$lon = $stuff[1];
|
||||
}
|
||||
|
||||
if ($type == 50) {
|
||||
$atis = join(' ', @stuff);
|
||||
}
|
||||
}
|
||||
process_apt(); ## flush out the very last one
|
||||
print STDERR "Total airports: $tot_apts\n";
|
||||
}
|
||||
BIN
scripts/atis/quiet0.500.wav
Normal file
BIN
scripts/atis/quiet0.500.wav
Normal file
Binary file not shown.
349
scripts/atis/synth.pl
Executable file
349
scripts/atis/synth.pl
Executable file
@@ -0,0 +1,349 @@
|
||||
#! /usr/bin/perl -w
|
||||
|
||||
use strict;
|
||||
use Symbol;
|
||||
use Audio::Wav;
|
||||
|
||||
sub usage {
|
||||
print <<EoF;
|
||||
Run a bunch of words through the speech synthesizer
|
||||
and collect the results.
|
||||
Typical usage:
|
||||
./synth.pl [options] sport.vlist sport.vce sport.wav
|
||||
|
||||
Options include:
|
||||
-skip # skip a line from the .vlist file;
|
||||
-one # take only the first word from each line
|
||||
|
||||
Note: -skip -one is useful if the .vlist file is actually in .vce format.
|
||||
|
||||
Other usages:
|
||||
./synth.pl -dump foo.wav # dump headers 'foo.wav'
|
||||
./synth.pl -help # print this message
|
||||
|
||||
where sport.vlist is a file containing a list of words, we use the
|
||||
first word on each line and ignore anything else on that line
|
||||
(which means a .vce file is acceptable as input, using -skip -one).
|
||||
|
||||
Note that "atis-lex.pl" and "list-airports.pl" are useful for
|
||||
creating the .vlist file.
|
||||
|
||||
Note that you may also need to:
|
||||
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
|
||||
|
||||
You may also need to scrounge a non-buggy version of
|
||||
/usr/local/share/perl/5.10.1/Audio/Wav/Read.pm
|
||||
EoF
|
||||
}
|
||||
|
||||
my $proto = <<EoF;
|
||||
(voice_en1_mbrola) ;; best voice I know of
|
||||
(setq voice_rab_diphone voice_en1_mbrola)
|
||||
(setq voice_en1 voice_en1_mbrola)
|
||||
(setq voice_el_diphone voice_en1_mbrola)
|
||||
(setq voice_ked_diphone voice_en1_mbrola)
|
||||
(utt.save.wave (utt.synth (Utterance Text "XXX")) "YYY" 'riff)
|
||||
EoF
|
||||
|
||||
my %list;
|
||||
my %count;
|
||||
|
||||
sub doit {
|
||||
my ($word) = @_;
|
||||
if (exists $list{lc $word}
|
||||
&& $list{lc $word} =~ m'^[A-Z][a-z]') {
|
||||
; # tasteful capitalization; leave as is
|
||||
} else {
|
||||
$list{lc $word} = $word;
|
||||
}
|
||||
$count{lc $word}++;
|
||||
}
|
||||
|
||||
## This is an ugly way to fix festival's bad guess as to
|
||||
## pronunciation in special cases.
|
||||
## In the case of wind (windh versus wynd),
|
||||
## nominally there are ways of tagging parts-of-speech,
|
||||
## i.e. noun versus verb,
|
||||
## but they don't seem to be reliable.
|
||||
my %fixup = (
|
||||
'wind' => 'windh',
|
||||
'romeo' => 'Rome E O',
|
||||
'xray' => 'X ray',
|
||||
);
|
||||
|
||||
main: {
|
||||
|
||||
my $skip = 0;
|
||||
my $fmtcheck = 1;
|
||||
my $oneword = 0;
|
||||
my $gripe = 0;
|
||||
my $out_bits_sample = 8; ## this is what FGFS expects
|
||||
my @plain_args = ();
|
||||
argx: while (@ARGV) {
|
||||
my $arg = shift @ARGV;
|
||||
$arg =~ s/^--/-/;
|
||||
if ($arg eq '-help' || $arg eq '-h') {
|
||||
usage;
|
||||
exit(0);
|
||||
}
|
||||
if ($arg eq '-dump') {
|
||||
my $ifn = shift @ARGV || 'foo.wav';
|
||||
my $wav = new Audio::Wav;
|
||||
print "About to open '$ifn' ...\n";
|
||||
my $waver = $wav -> read( $ifn );
|
||||
print "xxxxxxxxxxxxxxxx\n";
|
||||
for my $detail (keys %{$waver->details()}) {
|
||||
printf("%-20s %s\n", $detail, ${$waver->details()}{$detail});
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
if ($arg eq '-skip') {
|
||||
$skip++;
|
||||
next argx;
|
||||
}
|
||||
if ($arg eq '-gripe') {
|
||||
$gripe++;
|
||||
next argx;
|
||||
}
|
||||
if ($arg eq '-one' || $arg eq '-1') {
|
||||
$oneword++;
|
||||
next argx;
|
||||
}
|
||||
if ($arg eq '-nocheck') {
|
||||
$fmtcheck=0;
|
||||
next argx;
|
||||
}
|
||||
if ($arg =~ '^-') {
|
||||
die "Unrecognized option '$arg'\n";
|
||||
}
|
||||
push @plain_args, $arg;
|
||||
}
|
||||
|
||||
my $nargs = @plain_args;
|
||||
if ($nargs != 3) {
|
||||
die "Wrong number of arguments ($nargs); for help try:\n $0 -help\n";
|
||||
}
|
||||
my @todo = ();
|
||||
my ($ifn, $indexfn, $out_wav) = @plain_args;
|
||||
|
||||
my $inch = Symbol::gensym;
|
||||
open ($inch, '<', $ifn)
|
||||
|| die "Couldn't open input file '$ifn'\n";
|
||||
|
||||
# Skip some lines from the input list, as requested:
|
||||
for (my $ii = 0; $ii < $skip; $ii++) {
|
||||
my $ignore = <$inch>;
|
||||
}
|
||||
|
||||
# Read the rest of the input file:
|
||||
while (my $line = <$inch>) {
|
||||
chomp($line);
|
||||
if ($oneword) {
|
||||
my @stuff = split(' ', $line, 2);
|
||||
doit($stuff[0]);
|
||||
} else {
|
||||
for my $word (split(' ', $line)) {
|
||||
doit($word);
|
||||
}
|
||||
}
|
||||
}
|
||||
close $inch;
|
||||
|
||||
# Optionally print a list of things that the input file
|
||||
# requested more than once.
|
||||
if ($gripe) {
|
||||
foreach my $thing (sort keys %count) {
|
||||
if ($count{$thing} > 1) {
|
||||
printf("%4d %s\n", $count{$thing}, $list{$thing});
|
||||
}
|
||||
}
|
||||
}
|
||||
my $nsnip = (keys %list);
|
||||
|
||||
if (0 && $nsnip > 10) {
|
||||
$nsnip = 10;
|
||||
}
|
||||
print STDERR "nsnip: $nsnip\n";
|
||||
|
||||
my $index = Symbol::gensym;
|
||||
open ($index, '>', $indexfn)
|
||||
|| die "Couldn't write index file '$indexfn'\n";
|
||||
|
||||
print $index "$nsnip\n";
|
||||
if (! -d 'snip') {
|
||||
mkdir('snip')
|
||||
|| die "Could not create directory 'snip' : $!\n";
|
||||
}
|
||||
|
||||
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;
|
||||
if ($thing eq '/' || $thing eq '/_') {
|
||||
system("/bin/cp quiet0.500.wav $xfn.wav");
|
||||
} else {
|
||||
my $script = $proto;
|
||||
$script =~ s/XXX/$fraise/;
|
||||
$script =~ s|YYY|$xfn.wav|;
|
||||
#xxxx print "$fraise ... $script\n";
|
||||
|
||||
my $cmd = '/usr/bin/festival';
|
||||
my $pipe = Symbol::gensym;
|
||||
open ($pipe, '|-', $cmd)
|
||||
|| die "Couldn't open pipe to '$cmd'\n";
|
||||
print $pipe $script;
|
||||
close $pipe;
|
||||
if ($? != 0){
|
||||
print STDERR "Error in festival script: '$script'\n";
|
||||
next snipper;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$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";
|
||||
my $stat = Symbol::gensym;
|
||||
open ($stat, '-|', $statcmd)
|
||||
|| die "Couldn't open pipe from '$statcmd'\n";
|
||||
my $vol = 0;
|
||||
my $size = 0;
|
||||
|
||||
my $lastline;
|
||||
while (my $line = <$stat>) {
|
||||
chomp $line;
|
||||
$lastline = $line;
|
||||
my @stuff = split ':', $line;
|
||||
my $nw = @stuff;
|
||||
#### print STDERR "$nw +++ $line\n";
|
||||
if ($nw == 2) {
|
||||
if ($stuff[0] eq 'Volume adjustment') {
|
||||
$vol = 0+$stuff[1];
|
||||
}
|
||||
elsif ($stuff[0] eq 'Samples read') {
|
||||
$size = 0+$stuff[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
my $status = close $stat;
|
||||
if ($?) {
|
||||
print STDERR "Stat command failed: $statcmd\n" . ": $lastline \n";
|
||||
next snipper;
|
||||
}
|
||||
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";
|
||||
if (1) {
|
||||
my $vol_handle = Symbol::gensym;
|
||||
open ($vol_handle, '|-', $volume_cmd)
|
||||
|| die "Couldn't open pipe to command '$volume_cmd'\n";
|
||||
|
||||
close $vol_handle;
|
||||
if ($?) {
|
||||
die "Volume command failed: $statcmd\n" . ": $lastline";
|
||||
}
|
||||
}
|
||||
push @todo, "$xfn.raw";
|
||||
}
|
||||
close $index;
|
||||
|
||||
my $cat_cmd = "cat " . join(' ', @todo) . " > ./snip/everything.raw";
|
||||
my $cat_handle = Symbol::gensym;
|
||||
open ($cat_handle, '|-', $cat_cmd)
|
||||
|| die "Couldn't open pipe to command '$cat_cmd'\n";
|
||||
close $cat_handle;
|
||||
if ($?) {
|
||||
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";
|
||||
|
||||
my $wav_handle = Symbol::gensym;
|
||||
open ($wav_handle, '|-', $wav_cmd)
|
||||
|| die "Couldn't open pipe to command '$wav_cmd'\n";
|
||||
close $wav_handle;
|
||||
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");
|
||||
}
|
||||
102
scripts/atis/voice.pl
Executable file
102
scripts/atis/voice.pl
Executable file
@@ -0,0 +1,102 @@
|
||||
#! /usr/bin/perl -w
|
||||
|
||||
use strict;
|
||||
use Symbol;
|
||||
|
||||
sub usage {
|
||||
print <<EoF;
|
||||
|
||||
EoF
|
||||
}
|
||||
|
||||
my $fgroot = $ENV{'FG_ROOT'} || '.';
|
||||
|
||||
my $dir="$fgroot/ATC";
|
||||
my %start=();
|
||||
my %len=();
|
||||
|
||||
my $str = 'Tucson International airport_information
|
||||
Ryan automated_weather_observation
|
||||
zero four one five zulu weather
|
||||
/ Wind one one zero at one five
|
||||
/ Visibility one zero
|
||||
/ sky_condition two thousand four hundred scattered
|
||||
/ Temperature one zero celsius dewpoint five celsius
|
||||
/ Altimeter two niner niner two
|
||||
/ Landing_and_departing_runway one one right
|
||||
/ on_initial_contact_advise_you_have_information zulu ';
|
||||
|
||||
main: {
|
||||
setup();
|
||||
unlink 'tmp.raw';
|
||||
$str =~ s/\n/ /g;
|
||||
##print "$start{'decimal'} ... $len{'decimal'}\n";
|
||||
my $didsome = 0;
|
||||
for my $arg (@ARGV) {
|
||||
if ($arg ne '-') {
|
||||
say1($arg);
|
||||
$didsome++;
|
||||
} else {
|
||||
for my $word (split(' ', $str)){
|
||||
say1($word);
|
||||
$didsome++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($didsome) {
|
||||
my $cmd = 'sox -q -r 8000 -t raw -e signed-integer -b 16 tmp.raw'
|
||||
. ' tmp.wav';
|
||||
# . ' -t alsa';
|
||||
print "$cmd\n";
|
||||
system $cmd;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
sub say1{
|
||||
my ($arg) = @_;
|
||||
$arg = lc($arg);
|
||||
if (exists $start{$arg}) {
|
||||
my $cmd = "sox -q $dir/voice.wav "
|
||||
. " -t raw -r 8000 -e signed-integer -b 16 - "
|
||||
. " trim $start{$arg}s $len{$arg}s"
|
||||
. " >> tmp.raw ";
|
||||
print "$cmd\n";
|
||||
system $cmd;
|
||||
my $end = $start{$arg} + $len{$arg};
|
||||
print "$start{$arg} + $len{$arg} = $end\n";
|
||||
} else {
|
||||
print "Can't find '$arg'\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub setup{
|
||||
my $inch = Symbol::gensym();
|
||||
my $file = "$dir/voice.vce";
|
||||
open($inch, "<$file") || die "Cannot open input file '$file'\n";
|
||||
my $header = <$inch>;
|
||||
chomp $header;
|
||||
my $ii=1;
|
||||
liner: while (my $line = <$inch>){
|
||||
chomp $line;
|
||||
my @word = split(" ", $line);
|
||||
my $nn = @word;
|
||||
if ($nn != 3) {
|
||||
next liner;
|
||||
}
|
||||
my $id = lc($word[0]);
|
||||
my $st = $word[1];
|
||||
my $ln = $word[2];
|
||||
if ($ln =~ s/^x//) {
|
||||
$ln = $ln - $st;
|
||||
print "$id $st $ln\n";
|
||||
}
|
||||
$start{$id} = $st;
|
||||
$len{$id} = $ln;
|
||||
##print "$ii $nn '$line'\n";
|
||||
$ii++;
|
||||
}
|
||||
print "(($header)) --> $ii\n";
|
||||
}
|
||||
43
scripts/atis/words_per_line.sh
Executable file
43
scripts/atis/words_per_line.sh
Executable file
@@ -0,0 +1,43 @@
|
||||
#! /bin/bash
|
||||
|
||||
##
|
||||
##
|
||||
|
||||
if test "x$1" = "x-h" ; then
|
||||
1>&2 echo "Usage: "
|
||||
1>&2 echo " $0 [filename]"
|
||||
1>&2 echo "Read words from input, treating all whitespace like,"
|
||||
1>&2 echo "and write exactly N words per line on output."
|
||||
1>&2 echo "Options: "
|
||||
1>&2 echo " -n [N] specify N (default: 1)"
|
||||
1>&2 echo " filename = '-' or '' ==> read from standard input"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
: ${wordmax:=1}
|
||||
files=""
|
||||
|
||||
|
||||
while test -n "$*" ; do
|
||||
this=$1 ; shift
|
||||
case $this in
|
||||
-n) wordmax=$1 ; shift
|
||||
;;
|
||||
*) files="$files $this"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
|
||||
awk '{
|
||||
for (ii = 1; ii <=NF; ii++) {
|
||||
printf ("%s", $ii);
|
||||
words++;
|
||||
if (words >= wordmax) {
|
||||
print "";
|
||||
words = 0;
|
||||
} else {
|
||||
printf (" ");
|
||||
}
|
||||
}
|
||||
}' wordmax=$wordmax $files
|
||||
Reference in New Issue
Block a user