katzuma has asked for the wisdom of the Perl Monks concerning the following question:

hi wise magisters: I'm trying to calculate frequencies of a raw audio bit stream with FFT.... the problem is i don't even know how to begin. The topic is so complicated.... can someone give me some advices?

Replies are listed 'Best First'.
Re: Using Math::FFT
by Zaxo (Archbishop) on May 16, 2002 at 04:25 UTC

    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:

    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];
    ...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.

    PDL::FFT, PDL::FFTW, Math::Pari are among other possibilities.

    After Compline,
    Zaxo