--
Ian Collins.
Look at "Discrete Fourier Transform" and the implementations of a "Fast
Fourier Transform".
Here is some code I toyed with - I lifted it from somewhere, I don't
know exactly where and then I templateized it a little.
The FFT is done in the complex number space.... You could also look up
the DCT (discrete cosine transform) which I think operates in the real
number space but it's not as accurate - I really don't know much about
DCT's.
#define PI 3.1415926535897932384626
inline long revbin_update(long r,long n)
{
do {
n=n>>1;
r=r^n;
} while ((r&n)==0);
return r;
}
template <typename TranType>
inline void revbin_permute(TranType *a,long n)
{
if (n<=2) return;
long r=0;
for (long x=1; x<n; x++)
{
r=revbin_update(r,n);
if (r>x) swap(a[x],a[r]);
}
}
template <typename TranType>
TranType omega(double theta)
{ return TranType(cos(theta),sin(theta)); }
template <int is, typename TranType>
void fft(TranType *a, long ldn)
// O(N log N)
//
// a[] is the TranType input data set, lsb in 0 and msb in N
// ldn is the power of 2 which contains the entire data set, try to
// align the data to a power of 2 by padding with zeroes.
// is is the direction of the transform, +1 = forward, -1 = backward
//
// result is a[]
{
long n=1 << ldn;
revbin_permute(a,n);
for (long ldm=1; ldm<=ldn; ldm++)
{
long m=1 << ldm;
long mh=m/2;
for (long j=0; j<mh; j++)
{
TranType e=omega<TranType>(is*2*PI*j/m);
for (long r=0; r<=n-m; r+=m)
{
TranType u=a[r+j];
TranType v=a[r+j+mh]*e;
a[r+j]=(u+v);
a[r+j+mh]=(u-v);
}
}
}
}
template <typename TranType>
void fft_convolution(TranType *x,TranType *y, long n)
// x[], y[] are the two input TranType data sets.
// n is the power of 2 which contains the entire data set.
//
// result is y[]
{
long pw=1 << n;
fft<1>(x,n); // forward transform of x[]
fft<1>(y,n); // forward transfomr of y[]
for (int i=0; i<pw; i++)
y[i]=y[i]*x[i]; // element wise multiplication
fft<-1>(y,n); // backward transform of y[]
for (int i=0; i<pw; i++)
y[i]=y[i]/TranType(pw,0); // normalize
}
#include <complex>
/// example of use
int main()
{
static std::complex<double> a[1<<21];
// revbin_permute( a, 1<<21 );
fft<1>( a, 21 );
}
as someone else has pointed out, performing a fourier transform on the
raw data is what you need. Instead of trying to build your own
fourier transform there are ones available in the Intel Performance
Primitives Library that will do everything that you need. I've used
them for a while now and find them very fast and accurate.
Flamingo
> How to get the frequency of an audio file and how to
> separate the low and high frequency of an audio file
NTG, but maybe it would help you:
1. Think about what is frequency. It's an occurence of
something over some particular time. The more often
it occurs, the higher is that frequency.
2. Sound consists from waves. Every sound can be decomposed
to its component waves, which are sines.
3. A lowpass filter is lowering the amplitude for higher
frequency components, and doesn't change the amplitude
for lower frequency components.
4. Audio file stores values of the amplitude in particular
moments of time [samples].
5. A wave is the change in ampliture over time.
So, use advices of the other posters and use FFT to decompose
sound to its frequency components [spectral analysis], deamplify
the frequencies you don't want and compose your sound back again
using only the frequency components you want [they're sines,
you know].
--
SasQ
No no ... if you want to create a filter (filter out a certain set of
frequencies) then create a low-pass/high-pass/band-pass filter. There
is no need to do it in the frequency domain. FFT's are relatively
expensive computationally.
>> So, use advices of the other posters and use FFT to decompose
>> sound to its frequency components [spectral analysis], deamplify
>> the frequencies you don't want and compose your sound back again
>> using only the frequency components you want [they're sines,
>> you know].
>
> No no ... if you want to create a filter (filter out a certain
> set of frequencies) then create a low-pass/high-pass/band-pass
> filter. There is no need to do it in the frequency domain.
> FFT's are relatively expensive computationally.
Oh, I didn't know that can be done better. Can you tell me
something more about it? [maybe on priv, if it's NTG here].
--
SasQ
I don't remember all the details. You can probably find enough
information if you google for "discrete low pass filter" or somthing
like that.