Building acoustic model in speech recognition [duplicate] - sphinx

I'm having problems in the decoding part of speech recognition. I followed the steps here. When I type: perl scripts_pl/decode/slave.pl, I get these errors:
MODULE: DECODE Decoding using models previously trained
Decoding 130 segments starting at 0 (part 1 of 1) Could not find executable for /home/go/Documents/tutorial/an4/bin/sphinx3_decode
at
/home/go/Documents/tutorial/an4/scripts_pl/decode/../lib/SphinxTrain/Util.pm
line 299.
Aligning results to find error rate Can't open /home/go/Documents/tutorial/an4/result/an4-1-1.match word_align.pl
failed with error code 65280 at scripts_pl/decode/slave.pl line 173.
Here is word_align.pl line 179
#sub initialize {
my ($ref_words, $hyp_words, $align_matrix, $backtrace_matrix) = #_;
# All initial costs along the j axis are insertions
for (my $j = 0; $j <= #$hyp_words; ++$j) {
$$align_matrix[0][$j] = $j;
}
for (my $j = 0; $j <= #$hyp_words; ++$j) {
$$backtrace_matrix[0][$j] = INS;
}
# All initial costs along the i axis are deletions
for (my $i = 0; $i <= #$ref_words; ++$i) {
$$align_matrix[$i][0] = $i;
}
for (my $i = 0; $i <= #$ref_words; ++$i) {
$$backtrace_matrix[$i][0] = DEL;
}
#}
and Util.pm line 299
die "Could not find executable for $cmd" unless -e $cmd;
Why am I missing the an4-1-1.match file?

I followed the steps here http://www.speech.cs.cmu.edu/sphinx/tutorial.html
This tutorial is outdated. A recent one is http://cmusphinx.sourceforge.net/wiki/tutorialam
Could not find executable for
/home/go/Documents/tutorial/an4/bin/sphinx3_decode
This is a reason of the problem. You need to copy the executable to the specified location. Then run decoding again.

Related

Open (IN...) command failing possibly due to problems with naming

New to Perl and quite new to coding in general so I apologise if this is formatted terribly and an easy question! Trying simply to input somebody's elses code as a step in a larger project involving PRAAT. The code is designed to distinguish beats in speech rhythm, I've followed their nomenclature in file naming (on line 2) but the code won't move past line 13. Could anyone tell me why? Is it trying to open a directory called "intensities"? Additionally, is there anywhere else I may have to change the code, it is quite possibly reasonably old! Thank you very much!
#!/usr/local/bin/perl -w
scalar(#ARGV) == 1 or scalar(#ARGV) == 2 or die "Usage: getBeatsOneShot.pl someSoundFile <threshold>";
$stem = shift;
# Parameters to fiddle with
if (scalar(#ARGV) == 0) {
$threshold = 0.2;
} else {
$threshold = shift;
print "Threshold is $threshold\n";
}
open(IN, "intensities/$stem.intensity") or die "badly";
open(OUT, ">beats/$stem.beats") or die "eek";
# File type = "ooTextFile short"
$_ = <IN>; print OUT $_;
# replace "Intensity" with "TextGrid"
$_ = <IN>; print OUT "\"TextGrid\"\n\n";
# skip a line
$_ = <IN>;
chomp($xmin = <IN>);
chomp($xmax = <IN>);
chomp($nx = <IN>); $nx = 0; #(just suprress a arning here)
chomp($dx = <IN>);
chomp($x1 = <IN>);
# Read in intensity contour into #e (envelope)
#e = ();
while($_ = <IN>) { chomp; last unless $_ eq "1";}
push #e, $_;
while($_ = <IN>) {
chomp($_);
push #e, $_;
}
# (1) Find max and min
$max = 0; $min = 1000000;
foreach $ival (#e) {
if($ival > $max) {
$max = $ival;
}
if($ival < $min) {
$min = $ival;
}
}
# (2) look for beats
#beats = ();
print "Thresh: $threshold\n";
open doesn't create the path to the file. Directories intensities/ and beats/ therefore must exist in the current working directory before the script is run.
When open fails, it sets $! to the reason of the failure. Instead of eek or badly, use die $! so Perl can tell you what went wrong.
Moreover, you should turn strict and warnings on. They prevent many common mistakes. As a newbie, you might like to enable diagnostics, too, to get detailed explanations of all the errors and warnings.

Perl subroutine not working in loop

I tried writing a simple code to find whether a number can be expressed as the sum of primes or not, in Perl. The sample code is as shown:
sub funcIsPrime {
my $num = $_[0];
my $isPrime = 1;
for($i= 2; $i <= $num/2; $i++){
if($num%$i == 0){
$isPrime = 0;
last;
}
}
return $isPrime;
}
#my $num = <>;
my $num = 20;
for($i = 2; $i <= $num/2; $i++){
print "$i\t";
my $j = $num-$i;
print "$j\n";
if(funcIsPrime($i) and funcIsPrime($j)){ # Line x
print "$num = $i + $j\n";
}
}
The function call statements in Line x do not execute. The same line when put outside the loop works fine. What can be the possible solution? Please help. Thank you.
The main issue is missing my in variable declarations. Perl won't let you run the program if you include use warnings; and use strict;:
Global symbol "$i" requires explicit package name (did you forget to declare "my $i"?) at test.pl line 22.
Execution of test.pl aborted due to compilation errors.
Here's simplified working code (you can search for factors up to the square root of n, by the way, although this isn't a perfect or efficient prime test by any means):
use strict;
use warnings;
sub isPrime {
my $num = $_[0];
for (my $i = int sqrt $num; $i > 1; $i--) {
if ($num % $i == 0) {
return 0;
}
}
return 1;
}
my $num = 20;
for (my $i = 2; $i <= $num / 2; $i++) {
my $j = $num - $i;
if (isPrime($i) && isPrime($j)) {
print "$num = $i + $j\n";
}
}
Output
20 = 3 + 17
20 = 7 + 13

Perl - reading cyclic logfile backwards

I'm currently using Perl to read a logfile backwards using the aptly named File::ReadBackwards module. However, the first line it returns only contains
CLOG� ��
Am I doing something wrong by trying to read the last line of a cyclic logfile?
This is the relevant code:
use File::ReadBackwards;
my $filePath = '/var/log/';
my #fileNames = ('gateways.log', 'system.log');
for(my $i = 0; $i <= #fileNames; $i++){
scanFile($filePath,$fileNames[$i]);
sleep(60);
}
sub scanFile(){
my $handle = File::ReadBackwards->new($_[0] . $_[1]);
my $line = $handle->readline;
return $line
}
EDIT: I just read this - https://doc.pfsense.org/index.php/Why_can't_I_view_view_log_files_with_cat/grep/etc%3F_(clog)
I can't seem to find a module or the likes that already reads these, can anyone point me the right way to extract lines from this CLog?

Weird subroutine interaction in perl while drawing pyramids out of stars

I wasn't completely sure what to title this, but here is the issue. My goal is to create a subroutine called drawPyramids that will draw a pyramid out of *, with the number of rows depending on the command line parameter. With each row, the number of * increments by 2, so it goes 1-3-5-7 and so on. Here's what I have so far:
sub drawRow {
my $space = $_[0];
my $star = $_[1];
for ($i=0;$i<$space;$i++) {
print " ";
}
for ($i=0;$i<$star;$i++) {
print "*";
}
}
sub drawPyramid {
my $rows = $_[0];
my $x = 1;
for ($i=1;$i<=$rows;$i++) {
drawRow($rows-$i,$x);
print "\n";
$x+=2;
}
}
if(#ARGV == 0) { #check if user entered parameter by checking size of array
die "ERROR: Please supply command-line parameter\n";
}
foreach $a(#ARGV) { #check if number is negative
if ($a < 0) {
print "ERROR: Number must be non-negative\n";
}
}
$sp = #ARGV[0];
$st = #ARGV[1];
drawPyramid($sp);
Lets say I run it as perl pyramid.pl 5 in my CMD. The expected result is:
*
***
*****
*******
*********
with 4 spaces before the first star on the first row, 3 spaces...and so on. However, this is what I get:
*
***
*****
The third row with 5 stars should have 2 spaces before the stars start, and the program doesn't even print the last two lines (which would have 7 and 9 stars).
What is wrong with the program? Any help is appreciated.
The problem is that both subroutines are reading and modifying the same global variable $i (also known as $::i or $main::i), so they're interfering with each other.
To fix this, you should instead use local variables, declared with my; that is, change this:
for ($i = 1; $i <= ...; $i++) {
to this:
for (my $i = 1; $i <= ...; $i++) {
throughout.

How do I average column values from a tab-separated data file, ignoring a header row and the left column?

My task is to compute averages from the following data file, titled Lab1_table.txt:
retrovirus genome gag pol env
HIV-1 9181 1503 3006 2571
FIV 9474 1353 2993 2571
KoRV 8431 1566 3384 1980
GaLV 8088 1563 3498 2058
PERV 8072 1560 3621 1532
I have to write a script that will open and read this file, read each line by splitting the contents into an array and computer the average of the numerical values (genome, gag, pol, env), and write to a new file the average from each of the aforementioned columns.
I've been trying my best to figure out how to not take into account the first row, or the first column, but every time I try to execute on the command line I keep coming up with 'explicit package name' errors.
Global symbol #average requires explicit package name at line 23.
Global symbol #average requires explicit package name at line 29.
Execution aborted due to compilation errors.
I understand that this involves # and $, but even knowing that I've not been able to change the errors.
This is my code, but I emphasise that I'm a beginner having started this just last week:
#!/usr/bin/perl -w
use strict;
my $infile = "Lab1_table.txt"; # This is the file path
open INFILE, $infile or die "Can't open $infile: $!";
my $count = 0;
my $average = ();
while (<INFILE>) {
chomp;
my #columns = split /\t/;
$count++;
if ( $count == 1 ) {
$average = #columns;
}
else {
for( my $i = 1; $i < scalar $average; $i++ ) {
$average[$i] += $columns[$i];
}
}
}
for( my $i = 1; $i < scalar $average; $i++ ) {
print $average[$i]/$count, "\n";
}
I'd appreciate any insight, and I would also great appreciate letting me know by list numbering what you're doing at each step - if appropriate. I'd like to learn and it would make more sense to me if I was able to read through what someone's process was.
Here are the points you need to change
Use another variable for the headers
my $count = 0;
my #header = ();
my #average = ();
then change the logic inside if statement
if ( $count == 1 ) {
#header = #columns;
}
Now don't use the #average for the limit, use $i < scalar #columns for else statement.
Initially #average is zero, you will never get inside the for loop ever.
else {
for( my $i = 1; $i < scalar #columns; $i++ ) {
$average[$i] += $columns[$i];
}
}
Finally add -1 to your counter. Remember you increment your counter when you parse your header
for( my $i = 1; $i < scalar #average; $i++ ) {
print $average[$i]/($count-1), "\n";
}
Here is the final code
You can take advantage of #header to display the result neatly
#!/usr/bin/perl -w
use strict;
my $infile = "Lab1_table.txt"; # This is the file path
open INFILE, $infile or die "Can't open $infile: $!";
my $count = 0;
my #header = ();
my #average = ();
while (<INFILE>) {
chomp;
my #columns = split /\t/;
$count++;
if ( $count == 1 ) {
#header = #columns;
}
else {
for( my $i = 1; $i < scalar #columns; $i++ ) {
$average[$i] += $columns[$i];
}
}
}
for( my $i = 1; $i < scalar #average; $i++ ) {
print $average[$i]/($count-1), "\n";
}
There are other ways to write this code but I thought it would be better to just correct your code so that you can easily understand what is wrong with your code. Hope it helps