#!/usr/bin/perl -w

# turtle-demo: Demonstration of the "turtle" language domain
# included with Sphinx-II.

# Copyright (c) 2000 Cepstral LLC.
#
# This program is free software; you can redistribute it and/or modify
# it under the same terms as Perl itself.
#
# Written by David Huggins-Daines <dhuggins@cs.cmu.edu>

use strict;
use Speech::Recognizer::SPX qw(:fbs :uttproc);
use Audio::SPX qw(DEFAULT_SAMPLES_PER_SEC);
use Time::HiRes qw(usleep);

use constant SAMPLE_RATE => 16000;

use vars qw($Done);

fbs_init([qw(-live TRUE
	     -ctloffset 0
	     -ctlcount 100000000
	     -cepdir /usr/local/share/sphinx2/model/lm/turtle/ctl
	     -datadir /usr/local/share/sphinx2/model/lm/turtle/ctl
	     -agcmax FALSE
	     -langwt 6.5
	     -fwdflatlw 8.5
	     -rescorelw 9.5
	     -ugwt 0.5
	     -fillpen 1e-10
	     -silpen 0.005
	     -inspen 0.65
	     -top 1
	     -topsenfrm 3
	     -topsenthresh -70000
	     -beam 2e-06
	     -npbeam 2e-06
	     -lpbeam 2e-05
	     -lponlybeam 0.0005
	     -nwbeam 0.0005
	     -fwdflat FALSE
	     -fwdflatbeam 1e-08
	     -fwdflatnwbeam 0.0003
	     -bestpath TRUE
	     -kbdumpdir /usr/local/share/sphinx2
	     -lmfn /usr/local/share/sphinx2/model/lm/turtle/turtle.lm
	     -dictfn /usr/local/share/sphinx2/model/lm/turtle/turtle.dic
	     -phnfn /usr/local/share/sphinx2/model/hmm/6k/phone
	     -mapfn /usr/local/share/sphinx2/model/hmm/6k/map
	     -hmmdir /usr/local/share/sphinx2/model/hmm/6k
	     -hmmdirlist /usr/local/share/sphinx2/model/hmm/6k
	     -8bsen TRUE
	     -sendumpfn /usr/local/share/sphinx2/model/hmm/6k/sendump
	     -cbdir /usr/local/share/sphinx2/model/hmm/6k)]);

# Handles ad_open, cont_ad_init
my $ad = Audio::SPX->open_sps(SAMPLE_RATE)
    or die "ad_open_sps failed: $!";
my $cad = Audio::SPX::Continuous->init($ad)
    or die "cont_ad_init failed: $!";

$ad->start_rec
    or die "start recording failed: $!";
$cad->calib
    or die "calibration failed: $!";

$|=1;
my $adbuf;
until ($Done) {
    print "READY...\n";
    my $s;
    while (($s = $cad->read($adbuf, 4096)) == 0) {
	usleep(200_000);
    }
    die "continuous audio read failed" unless defined $s;

    uttproc_begin_utt();
    uttproc_rawdata($adbuf, 0);

    my $ts = $cad->read_ts;
    print "Listening... ts=$ts\n";

    while (1) {
	unless (defined($s = $cad->read($adbuf, 4096))) {
	    die "continuous audio read failed";
	}
	if ($s == 0) {
	    last if $cad->read_ts - $ts > DEFAULT_SAMPLES_PER_SEC;
	} else {
	    $ts = $cad->read_ts;
	}
	my $rem = uttproc_rawdata($adbuf, 0);

	unless ($rem or $s) {
	    usleep(20_000);
	}
    }

    $ad->stop_rec
	or die "couldn't stop dancing^Wrecording";
    1 while defined $ad->read($adbuf, 4096);
    $cad->reset;

    print "Stopped listening, please wait...\n";
    uttproc_end_utt();
    die "uttproc_result failed" unless (my ($fr, $hyp) = uttproc_result(1));

    last if $hyp =~ /quit/i;

    $ad->start_rec
	or die "couldn't start recording";
}

fbs_end();
