The module itself is fairly easy to use, but I suspect your main difficulty will be capturing and decoding the audio stream. If it's an au file, easy, but some broadcast bitstream is more difficult. That would involve capturing the sample from whatever buffer it is collected in. Without knowing the form your data takes, I'll assume something simple ;-)
The sox utility would be helpful for translating the various audio formats to the one you write for. Since you are interested in dominant frequencies, you can probably get away with a low fidelity monaural format with signed amplitudes, as opposed to PCM or some logarithmic encoding. Given a string containing 16-bit signed amplitude data read from a file or piped from sox, unpack will decode to an array. The Math::FFT object can be constructed with a reference to that array:
...and so on. Warning, untested code, and it will certainly need rewriting to fit your needs. The window parameter is used to filter out spurious high and low frequency components, I suggest looking at the power spectrum instead of the transformed amplitudes because the dominant peaks are more distinct.use Math::FFT my @samples; { local $/=\2048; # about 1/5 or 1/10 of a second at 11025 or 22050 sps # pick longer samples to be able to see lower frequencies binmode; @samples = <>; } # lets look at about 10 or 20 seconds in # should check if the sample exists in production code my $auft = Math::FFT->new([unpack 's*', $samples[100]]); my $power_spectrum = $auft->spctrm( [window => 'hamm'] ); my $dominant = (sort {$power_spectrum->[$a] <=> $power_spectrum->[$b]} + 0..$#power_spectrum)[-1];
PDL::FFT, PDL::FFTW, Math::Pari are among other possibilities.
After Compline,
Zaxo
In reply to Re: Using Math::FFT
by Zaxo
in thread Using Math::FFT
by katzuma
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |