DSPRelated.com
Forums

FFT output interpretation (FFTW v. Ooura)

Started by rela...@hotmail.co.uk September 30, 2008
> Did you try passing all 1's for *w?

Yes, it didn't make any difference.

> Given your Scilab and FFTW results -- well-documented routines -- I
still question
> your .wav reader. If I just take the first 1024 points of
event_zoom.wav,
> Hypersignal is showing a value of -0.113 for the real dc bin without
the 1024 scaling
> and about -116 with it. Are you sure the reader is handling the
.wav file header
> correctly? Hypersignal is showing a 44 byte header in this case.

Yes, it's reading everything correctly. For example (warning: Lisp
code ahead!) -

;; Open the wav file and store it in a variable.
;; Returns an instance of the class WAV-FILE, whose
;; slots hold the data (values of the various header
;; fields and the actual samples).
(setf wav (open-wav-file "/theevent-zoom.wav"))
=> #

;; Check the subchunk2 size.
(subchunk2-size wav)
=> 179758

;; Check the size (in bytes) of the original file.
(with-open-file (str "/theevent-zoom.wav")
(file-length str))
=> 179802

(- 179802 179758)
=> 44

Scilab gives me the following for the first sample -

-->wavread('/theevent-zoom.wav', 1)
ans = 0.0051880

My Lisp code gives me -

(aref (samples wav) 0) ; Accessing the first index to the vector.
=> 0.0051880

I've also visualized the data in my own Lisp-based graphical app and
everything seems to check out OK...

I called the FFTW routines with exactly the same data as the Ooura,
and got 0 for the DC imag part. I've just checked it with the C
version of the telafft library (http://www.jjj.de/fft/fftpage.html) -
calling that from Lisp again gives a 0 DC imag part (well actually it
simply omits it and just gives the real part, like Scilab). So there's
obviously some problem with the way I'm calling the Ooura routine, or
setting up the data for it, or perhaps there's an issue with the .dll
I'm using. I'll have another look at, but for now I think I'm going to
stick with the telafft library.

Many thanks for your help and advice.

Best wishes,
Chris
Chris-

> > Did you try passing all 1's for *w?
>
> Yes, it didn't make any difference.
>
> > Given your Scilab and FFTW results -- well-documented routines -- I
> still question
> > your .wav reader. If I just take the first 1024 points of
> event_zoom.wav,
> > Hypersignal is showing a value of -0.113 for the real dc bin without
> the 1024 scaling
> > and about -116 with it. Are you sure the reader is handling the
> .wav file header
> > correctly? Hypersignal is showing a 44 byte header in this case.
>
> Yes, it's reading everything correctly. For example (warning: Lisp
> code ahead!) -
>
> ;; Open the wav file and store it in a variable.
> ;; Returns an instance of the class WAV-FILE, whose
> ;; slots hold the data (values of the various header
> ;; fields and the actual samples).
> (setf wav (open-wav-file "/theevent-zoom.wav"))
> => # ;; Check the subchunk2 size.
> (subchunk2-size wav)
> => 179758
>
> ;; Check the size (in bytes) of the original file.
> (with-open-file (str "/theevent-zoom.wav")
> (file-length str))
> => 179802
>
> (- 179802 179758)
> => 44
>
> Scilab gives me the following for the first sample -
>
> -->wavread('/theevent-zoom.wav', 1)
> ans = 0.0051880
>
> My Lisp code gives me -
>
> (aref (samples wav) 0) ; Accessing the first index to the vector.
> => 0.0051880

Hypersignal gives the same. So the consensus says your .wav reader is fine.

> I've also visualized the data in my own Lisp-based graphical app and
> everything seems to check out OK...
>
> I called the FFTW routines with exactly the same data as the Ooura,
> and got 0 for the DC imag part. I've just checked it with the C
> version of the telafft library (http://www.jjj.de/fft/fftpage.html) -
> calling that from Lisp again gives a 0 DC imag part (well actually it
> simply omits it and just gives the real part, like Scilab). So there's
> obviously some problem with the way I'm calling the Ooura routine, or
> setting up the data for it, or perhaps there's an issue with the .dll
> I'm using. I'll have another look at, but for now I think I'm going to
> stick with the telafft library.

Are all the other Ooura values Ok? It could just be that Ooura "uses" the dc bin
imag value for some other purpose, for example an overall algorithm statistic (max
value, avg, etc). My favorite would be max value -- useful for plotting. In FFT
terms, it's a meaningless "spot" anyway.

-Jeff
> Are all the other Ooura values Ok? It could just be that Ooura
"uses" the dc bin
> imag value for some other purpose, for example an overall algorithm
statistic (max
> value, avg, etc). My favorite would be max value -- useful for
plotting. In FFT
> terms, it's a meaningless "spot" anyway.
>
> -Jeff
>

Thanks again Jeff. I think I've solved it - it's the magnitude of
Nyquist. In fact checking the sources again I found this reference to
the output of the Ooura real-to-complex, which I must admit at first
somewhat mystified me -

output data
a[2*k] = R[k], 0<=k a[2*k+1] = I[k], 0 a[1] = R[n/2]

And indeed checking the value at the n/2-th index of the full output
it's the same as the DC 'imaginary' part (I was of course discarding
the second half of my output so it wasn't showing up previously). The
FFTW tutorial mentions that some FFT implementations 'store the
Nyquist element where the DC imaginary part would go, in order to make
the input and output arrays the same size'. So it seems that that is
what Ooura is doing.

Many thanks again, and apologies if I wasted any of your time!
Chris
> And indeed checking the value at the n/2-th index of the full output
> it's the same as the DC 'imaginary' part (I was of course discarding
> the second half of my output so it wasn't showing up previously).

Or rather checking that index in Scilab gives me the same value as the
Ooura DC 'imag' part. Ooura discards the second (reflected) half of
the output, Scilab apparently doesn't.

Chris
Chris-

>> Are all the other Ooura values Ok? It could just be that Ooura
> "uses" the dc bin
>> imag value for some other purpose, for example an overall algorithm
> statistic (max
>> value, avg, etc). My favorite would be max value -- useful for
> plotting. In FFT
>> terms, it's a meaningless "spot" anyway.
>>
>> -Jeff
>> Thanks again Jeff. I think I've solved it - it's the magnitude of
> Nyquist. In fact checking the sources again I found this reference to
> the output of the Ooura real-to-complex, which I must admit at first
> somewhat mystified me -
>
> output data
> a[2*k] = R[k], 0<=k > a[2*k+1] = I[k], 0 > a[1] = R[n/2]
>
> And indeed checking the value at the n/2-th index of the full output
> it's the same as the DC 'imaginary' part (I was of course discarding
> the second half of my output so it wasn't showing up previously). The
> FFTW tutorial mentions that some FFT implementations 'store the
> Nyquist element where the DC imaginary part would go, in order to make
> the input and output arrays the same size'. So it seems that that is
> what Ooura is doing.
>
> Many thanks again, and apologies if I wasted any of your time!

No waste of time at all, it's a small mystery solved. What's happening makes sense and is good to keep in mind.

The Ooura doc must be really terse. I would have thought it would mention something like this and/or offer config
options for different output behavior that matches other algorithms.

-Jeff