> and plot it. Are the signal components still in the wrong
> place? If so, could you generate a small example like this:
>
> N = 64 The number of samples
> f1 = 4/64 Frequency of first component
> f2 = 17/64 Frequency of second component
>
> x(n) = sin(f1*2*pi) + cos(f2*2*pi)
This should of course be
x(n) = sin(f1*2*pi*n) + cos(f2*2*pi*n)
Rune
Reply by Rune Allnor●May 3, 20052005-05-03
rvhoven wrote:
> >
> >rvhoven wrote:
> >> I'm new to FFTW and I'm trying to get it to recongize a tone.
> >> When I run the fft on a single tone it will recongize
> >> the tone but a the wrong frequency. When I run it with
> >> 2 tones it will recongize 2 tones but again at the
> >> wrong frequency and the spacing between the tones are
> >> incorrect. What could I be doing wrong? I have
> >> posted some of the code that I use to compute the
> >> fftw. Thanks in advance.
> >
> >I see you use a function called fft_real. I'd expect at least
> >parts of your problem to be related to I/O formats in the routine.
> >An FFT that works on real-valued inputs produces a complex-valued
> >result. However, the complex-valued output is symmetric, so one
> >really needs only half the complex-valued data. You need only
> >half the data points but each point comrise a real and imaginary
> >value, so the total number of numbers (eh...) is the same.
> >
> >Your declarations show that both the real-valued input and the
> >complex-valued output consist of N double numbers. I am pretty
> >sure the output consists of only half the spectrum, but that
> >both the real and imaginary parts are available in that one
> >array of doubles.
> >
> >So go back to the documentation of your FFT routine and see
> >how the output is formatted.
> >
> >Rune
> >
> >
>
> Rune,
> I got my layout for the FFTW tutorial in Chapter 2.3 pg 7. The array
is
> out array is DC,r1,r2,...,r(n/2),i((n+1)/2-1),....,i2,i1
>
> Therefore the first half of my array is real and the second half is
> imaginary and I only have N/2+1 data points.
Ah, I was right, then.
In order to find out what is going on, rearrange the real and
imaginary parts to an array of ~N/2 complex numbers. Note that
the DC component is always real-valued with real-valued data,
so the routine does probably not return an imaginary part for it.
Next, compute the spectrum magnitude response from the complex
numbers as
mag[n] = sqrt(r[n]^2+i[n]^2); /* n = 0,...,~N/2 */
and plot it. Are the signal components still in the wrong
place? If so, could you generate a small example like this:
N = 64 The number of samples
f1 = 4/64 Frequency of first component
f2 = 17/64 Frequency of second component
x(n) = sin(f1*2*pi) + cos(f2*2*pi)
When you run your FFT on these data, you should have the following
(assuming C-style indexing, starting at n=0):
out[17] = 1 The cos term
out[60] = 1 The sin term
mag[4] = 1
mag[17] = 1
although I suspect the numbers will be 8 rather than 1.
This is a normalization question that each implementation of
the FFT does in its own way. All other entries in the arrays
'out' and 'mag' should vanish.
Rune
Reply by rvhoven●May 2, 20052005-05-02
>
>rvhoven wrote:
>> I'm new to FFTW and I'm trying to get it to recongize a tone.
>> When I run the fft on a single tone it will recongize
>> the tone but a the wrong frequency. When I run it with
>> 2 tones it will recongize 2 tones but again at the
>> wrong frequency and the spacing between the tones are
>> incorrect. What could I be doing wrong? I have
>> posted some of the code that I use to compute the
>> fftw. Thanks in advance.
>
>I see you use a function called fft_real. I'd expect at least
>parts of your problem to be related to I/O formats in the routine.
>An FFT that works on real-valued inputs produces a complex-valued
>result. However, the complex-valued output is symmetric, so one
>really needs only half the complex-valued data. You need only
>half the data points but each point comrise a real and imaginary
>value, so the total number of numbers (eh...) is the same.
>
>Your declarations show that both the real-valued input and the
>complex-valued output consist of N double numbers. I am pretty
>sure the output consists of only half the spectrum, but that
>both the real and imaginary parts are available in that one
>array of doubles.
>
>So go back to the documentation of your FFT routine and see
>how the output is formatted.
>
>Rune
>
>
Rune,
I got my layout for the FFTW tutorial in Chapter 2.3 pg 7. The array is
out array is DC,r1,r2,...,r(n/2),i((n+1)/2-1),....,i2,i1
Therefore the first half of my array is real and the second half is
imaginary and I only have N/2+1 data points.
rvhoven
This message was sent using the Comp.DSP web interface on
www.DSPRelated.com
Reply by Rune Allnor●April 26, 20052005-04-26
rvhoven wrote:
> I'm new to FFTW and I'm trying to get it to recongize a tone.
> When I run the fft on a single tone it will recongize
> the tone but a the wrong frequency. When I run it with
> 2 tones it will recongize 2 tones but again at the
> wrong frequency and the spacing between the tones are
> incorrect. What could I be doing wrong? I have
> posted some of the code that I use to compute the
> fftw. Thanks in advance.
I see you use a function called fft_real. I'd expect at least
parts of your problem to be related to I/O formats in the routine.
An FFT that works on real-valued inputs produces a complex-valued
result. However, the complex-valued output is symmetric, so one
really needs only half the complex-valued data. You need only
half the data points but each point comrise a real and imaginary
value, so the total number of numbers (eh...) is the same.
Your declarations show that both the real-valued input and the
complex-valued output consist of N double numbers. I am pretty
sure the output consists of only half the spectrum, but that
both the real and imaginary parts are available in that one
array of doubles.
So go back to the documentation of your FFT routine and see
how the output is formatted.
Rune
Reply by Fred Marshall●April 26, 20052005-04-26
"rvhoven" <rvhoven@rogers.com> wrote in message
news:W8SdnekhO5Gc4PDfRVn-sg@giganews.com...
> I'm new to FFTW and I'm trying to get it to recongize a tone.
> When I run the fft on a single tone it will recongize
> the tone but a the wrong frequency. When I run it with
> 2 tones it will recongize 2 tones but again at the
> wrong frequency and the spacing between the tones are
> incorrect. What could I be doing wrong? I have
> posted some of the code that I use to compute the
> fftw. Thanks in advance.
Instead of doing all the log stuff, etc. I would test fftw with very simple
code.
Let fs=1.0
Let N=1024 so that frequency interval is 1/1024.
There are 1024 samples in time and in frequency.
The frequency samples run from frequency 0 to 1-1/1024.
If the first tone is at 200/1024 then there should be components around
frequency samples 201 and 1024-200 if I have the indexing just right.
Anyway, somewhere around those indices.
If the second tone is at 100/1024 then there should be components around
frequency samples 101 and 1024-100.
If that's not what you get, then something quite fundamental is wrong.
Fred
Fred
Reply by rvhoven●April 25, 20052005-04-25
I'm new to FFTW and I'm trying to get it to recongize a tone.
When I run the fft on a single tone it will recongize
the tone but a the wrong frequency. When I run it with
2 tones it will recongize 2 tones but again at the
wrong frequency and the spacing between the tones are
incorrect. What could I be doing wrong? I have
posted some of the code that I use to compute the
fftw. Thanks in advance.
fftw_plan p;
unsigned char ulaw;
static int N=1024;
int deltaF= 8000/N; //frequency spacing(sample rate/fft size)
int space =0; //used for freq spacing between samples
int i=0;
int k=0;
double logPS; //log of power spectrum
double linear[N];
fftw_real in[N];//same as double
fftw_real out[N], power_spectrum[N/2+1],ps[N/2+1];
rfftw_plan p;
//get a byte from the file and convert ulaw to 16-bit linear
//the conversion works
while((ulaw =getbyte(fpin))&& i<N){
linear[i]=ulaw2linear(ulaw);
in[i]=linear[i];
fprintf(fpout,"%f\n",linear[i]);
i++;
}
p = rfftw_create_plan(N, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE);
rfftw_one(p,in,out);
power_spectrum[0] = out[0]*out[0]; /* DC component */
logPS = 10*(log10(power_spectrum[0]));
space = k*deltaF;
for (k=1; k< (N+1)/2; ++k) /*(k < N/2 rounded up) */
{ power_spectrum[k] = (out[k]*out[k] + out[N-k]*out[N-k]);
logPS = 10*(log10(power_spectrum[k]/N));
space = k*deltaF;
}
if (N%2 ==0) /*N is even */
{ power_spectrum[N/2] = out[N/2]*out[N/2]; /*Nyquist frew. */
}
rfftw_destroy_plan(p);
fclose (fpin);
This message was sent using the Comp.DSP web interface on
www.DSPRelated.com