Audio
view release on metacpan or search on metacpan
my $lpc;
if (1)
{
# my ($auto,$ref);
my $levinson = $window->lpc($LPC_POLES,$auto,$ref);
roots(levinson => $levinson);
inverse($raw,$levinson);
# impulse($levinson);
$levinson *= -1;
$levinson->[0] = 1.0;
$levinson->length($FFT_SIZE);
# Take fft - gives transfer func of inverse filter (1-Sigma(An*z**-n))
# so to approx filter take reciprocal of each point
my $lpc = 1.0/$levinson->fft($FFT_SIZE);
$lpc->length($FFT_SIZE/2);
$xfrm->traceconfigure($t_lpc,-data => $lpc, -state => 'normal');
}
if (0)
{
my $auto = $window->autocorrelation($LPC_POLES);
# $auto *= ($window->samples-$LPC_POLES);
my $durbin = $auto->durbin;
my $gain = $durbin->[0];
warn "gain = $gain\n";
roots(durbin => $durbin);
$durbin *= -1;
$durbin->[0] = 1.0;
$durbin->length($FFT_SIZE);
# Take fft - gives transfer func of inverse filter (1-Sigma(An*z**-n))
# so to approx filter take reciprocal of each point
my $lpc = 1.0/$durbin->fft($FFT_SIZE);
$lpc->length($FFT_SIZE/2);
$xfrm->traceconfigure($t_aux,-data => $lpc, -state => 'normal');
}
}
else
{
$xfrm->traceconfigure($t_lpc,-state => 'hidden');
}
my $d = $au->rate/2;
$xfrm->configure(-xmax => $d, -end => $d, -start => 0);
}
sub inverse
{
my ($au,$lpc) = @_;
my @a = map { -$_ } $lpc->data;
my $rate = $lpc->rate;
my $n = @a-1;
$au->length($FFT_SIZE);
my $filter = Audio::Filter::FIR->new(rate => $rate);
$filter->data(@a);
$filter->[0] = 1;
$filter->length(2*$n+1);
my $response = Audio::Data->new(rate => $rate);
$response .= $filter->process($au);
my $dur = $response->duration/2;
$voice->configure(-start => 0, -end => $dur, -xmax => $dur, -yscale => undef);
$voice->traceconfigure($t_inv,-data => $response->timerange($dur,2*$dur));
# my $fresp = $response->fft($FFT_SIZE);
# $fresp->length($FFT_SIZE/2);
# $xfrm->traceconfigure($t_aux,-data => $fresp, -state => 'normal');
}
sub impulse
{
my $lpc = shift;
my $rate = $lpc->rate;
my @a = $lpc->data;
my $n = @a-1;
my $filter = Audio::Filter::AllPole->new(rate => $rate);
$filter->data(@a);
# 0'th entry is gain or error or other "junk".
$filter->[0] = 1;
$filter->length(2*$n+1);
my $response = Audio::Data->new(rate => $rate);
# No feed it an impulse i.e. ...
$response .= $filter->process(1); # ... 1 at time 0 and ...
for my $i (1..$FFT_SIZE-1)
{
$response .= $filter->process(0); # ... 0 otherwise
}
my $dur = $response->duration;
$voice->configure(-start => 0, -end => $dur, -xmax => $dur, -yscale => undef);
$voice->traceconfigure($t_imp,-data => $response);
my $fresp = $response->fft($FFT_SIZE);
$fresp->length($FFT_SIZE/2);
$xfrm->traceconfigure($t_aux,-data => $fresp, -state => 'normal');
}
my @formant;
my @pole;
sub pole_pair
{
my @colours = qw(red darkgreen blue magenta brown black);
my ($rate,$k,$f,$b,$r,$i) = @_;
my $d = $r*$r+$i*$i;
my $fresp;
# chr(0xb1) is +/- sign
$txt->insert('end',sprintf("f=%5.0fHz bw=%4.0fHz %.3g %+.3g%c%.3gi\n",
$f,$b,1/sqrt($d),$r,0xb1,$i),["f$k"]);
my $zr = 64*$r/$d;
my $zi = 64*$i/$d;
unless ($pole[$k])
{
my $col = $colours[$k % @colours];
$txt->tagConfigure("f$k",-foreground => $col);
my $p = $poles->create(oval =>[0,0,0,0],-fill => $col, -outline => $col);
my $m = $poles->create(oval =>[0,0,0,0],-fill => $col, -outline => $col);
$pole[$k] =[$p,$m];
}
$poles->coords($pole[$k][0],[65+$zr-1,65+$zi-1,65+$zr+1,65+$zi+1]);
$poles->coords($pole[$k][1],[65+$zr-1,65-$zi-1,65+$zr+1,65-$zi+1]);
$poles->itemconfigure($pole[$k][0],-state => 'normal');
( run in 1.576 second using v1.01-cache-2.11-cpan-39bf76dae61 )