October 31, 2025, 11:37:52 AM

News:

IWBasic runs in Windows 11!


Fast Fourier Transform Library...

Started by crodzilla, September 22, 2008, 08:02:19 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

crodzilla

Ok,
I have been studying spectrum analysis and extraction of frequencies from data.  I ran into this DLL that was written and published by a couple students at MIT.  It is supposed to the the fastest FFT algorithm on the planet.

It performs a Fourier transform on an array, and outputs the individual extracted waveforms of the strongest (amplitude) to the weakest, or outputs a reverse transform on the extracted waves to recombine into the (near) original waveform, minus the static.

I've read the website and don't understand how to use the original libfftw3-3.dll.  I found a wrapper DLL which seems to make life easier.  But now I don't quite understand how to use the pointers to point to my input and output arrays.

Here is the important "workhorse" definition of the sampledll.dll (wrapper for libfftw3-3.dll):
int    FFTfiltr(double& arr[], double& arr[], int, int, double, int);

-Pointer to the input array
-Pointer to the output array
-How many data points to use, frequencies found will max at (data points/2)
-How many tones to return in output array (1=single tone, >1 = combined # of tones)
-Cut-off (f) Cut-offs all tones which are weaker than f times of weakest of tones. Setting it to value > 1.0 will decrease number of output components; decreasing it will increase; default to 1.0
-Min tone.  Minimum # of ranked tones to return in output array.

So, if you set how many tones to 1 and min tone to 1, the output array will hold the waveform of the highest amplitude tone.  Set min tone to 2, you will get the second highest, etc.

If you set how many tones to 6 and the min tone to 1, the output array will hold the reverse fourier of the top 6 tones combined.
If you set how many tones to 6 and the min tone to 3, the output array will hold the reverse fourier of the 3rd, 4th and 5th tones combined.

I don't know anything more than that.

So, my question is, how can we define the arrays that can be used by this dll?  It looks like the arrays need pointers.  But I am unsure as to how to ensure the "define" is correct and the setup of the array pointers for use by the dll.

Here is the address to the FFT website: http://www.fftw.org/

Thanks to anyone who can explain how to use this neat DLL.
Carl

crodzilla

The sampledll.dll (attached above) is a wrapper for a single dimension array of data only.  FFTW has other powerful routines, which I will have to learn later, such as multi-dimensional Fourier transformations, arbitrary size transforms, parallel transforms, etc.

Carl

sapero

October 04, 2008, 04:20:07 PM #2 Last Edit: October 04, 2008, 07:05:31 PM by sapero
Carl, I'm done with headers conversion, now scanning the .gz archive for small examples.

OK, found three examples, for Aurora too. Files attached.

sapero

October 05, 2008, 09:14:52 AM #3 Last Edit: October 22, 2008, 01:25:22 PM by sapero
Here is example for your ExpertSample.dll.
It creates a sum of three sine waves, draws the sum directly on desktop window, calls the FFTfiltr to filter out only one sine, and draws the result in red on desktop.
$include "windowssdk.inc"

'ExpertSample.inc
$use "fftw3\\ExpertSample.lib"
declare import, GetIntValue(int i),int
declare import, GetDoubleValue(double i),double
declare import, GetStringValue(string i),string
declare import, GetArrayItemValue(pointer arr,int i,int i),double
declare import, SetArrayItemValue(pointer arr,int i,int i,double i),bool
declare import, GetRatesItemValue(pointer rates,int i,int i,int i),double
declare import, SortStringArray(pointer arr,int i),int
declare import, ProcessStringArray(pointer arr,int i),int
declare import, FFTfiltr(pointer arr, pointer arr, int i, int i, double i, int i),int
declare import, FFT(pointer arr, pointer i),bool

main()

sub main()

int screenX
pointer in, out
WINRECT rc
HDC dc

screenX = GetSystemMetrics(SM_CXSCREEN)
in  = new(double, screenX * 2)
out = new(double, screenX)

settype in, double
settype out, double

dc = GetDC(0)
SetRect(&rc, 0,0,screenX,100)
FillRect(dc, &rc, GetStockObject(WHITE_BRUSH))

for x=0 to screenX-1
' first sine
*in[x] = sind(x)
' second sine freq boost: 2
*in[x] += sind(x*2)
' third sine freq boost: 4
*in[x] += sind(x*4)
' normalize it
*in[x] /= 3
' display it
SetPixel(dc, x, 50-(*in[x] * 49.0), 0xa0b0c0)
next x

' show the result in RED
FFTfiltr(in, out, screenX, 1, 1.0, 1)

for x=0 to screenX-1
SetPixel(dc, x, 50-(*out[x] * 49.0), 0x00FF)
next x

' draw x-axis
MoveToEx(dc, 0, 50, NULL)
_LineTo(dc, screenX,50)

ReleaseDC(0, dc)

delete in
delete out
return
endsub

Techno

Hello

He created the import library but I doesn't see anyone in the LIB directory of C:\EBDev\

Can anyone help me where the lib files ?

Kind regards
Stephane


sapero

Try with $use "ExpertSample.lib", I have all the fft libs in separate folder.

Techno

Hi Sapero

It doesn't work !



' http://www.nashruddin.com/fft-with-fftw-example.html
' sapero october 5 2008
' commpile as console app

$include "stdio.inc"
$include "fftw3.inc"
$USE "libfftw3-3.lib"
$define SIZE 4

type fftw_complex
double d[2]
endtype


main()

sub main()

    double     _input[SIZE] : _input = 1.0, 1.0, 1.0, 1.0
    pointer    _data, fft_result, ifft_result
    fftw_plan  plan_forward, plan_backward
    int        i

settype _data, fftw_complex
settype fft_result, fftw_complex
settype ifft_result, fftw_complex

    _data       = fftw_malloc( len( fftw_complex ) * SIZE )
    fft_result  = fftw_malloc( len( fftw_complex ) * SIZE )
    ifft_result = fftw_malloc( len( fftw_complex ) * SIZE )
   
    plan_forward  = fftw_plan_dft_1d( SIZE, _data, fft_result, FFTW_FORWARD, FFTW_ESTIMATE )
    plan_backward = fftw_plan_dft_1d( SIZE, fft_result, ifft_result, FFTW_BACKWARD, FFTW_ESTIMATE )
   
    /* populate _input _data */
    for i = 0 to SIZE-1
        *_data[i].d[0] = _input[i]
        *_data[i].d[1] = 0.0
    next i

    /* print initial _data */
    for i = 0 to SIZE-1
        printf( "_data[%d] = { %2.2f, %2.2f }\n",_
                    i, *_data[i].d[0], *_data[i].d[1] )
    next i
   
    fftw_execute( plan_forward )
   
    /* print fft result */
    for i = 0 to SIZE-1
        printf( "fft_result[%d] = { %2.2f, %2.2f }\n",_
                    i, *fft_result[i].d[0], *fft_result[i].d[1] )
    next i

    fftw_execute( plan_backward )

    /* print ifft result */
    for i = 0 to SIZE-1
        printf( "ifft_result[%d] = { %2.2f, %2.2f }\n",_
                    i, *ifft_result[i].d[0] / SIZE, *ifft_result[i].d[1] / SIZE )
    next i

    /* free memory */
    fftw_destroy_plan( plan_forward )
    fftw_destroy_plan( plan_backward )

    fftw_free( _data )
    fftw_free( fft_result )
    fftw_free( ifft_result )
   
    return 0
endsub

Error report:
=======

Compiling...
fft-with-fftw-example.eba
No Errors

Linking...
Emergence Linker v1.11 Copyright ÂÃ,© 2006 Ionic Wind Software
Error: Unable to open file C:\Program Files\EBDev\libs\libfftw3f-3.lib
Error: Unable to open file C:\Program Files\EBDev\libs\libfftw3l-3.lib
Error(s) in linking C:\Program Files\EBDev\projects\fft\emergence\fft-with-fftw-example.exe



sapero

I waited for the error messages.
You need to download windows binaries from http://www.fftw.org/install/windows.html (3 dll files), and create import libs.
The include file fftw3.inc has definitions for these three dll's, so it links to three libs.

You may also $define __FFTW3_NOLIB__ before including fftw3.inc, and manually $use the lib you need.
See in fftw3.inc:$ifndef __FFTW3_NOLIB__
$use "libfftw3-3.lib"
$use "libfftw3f-3.lib"
$use "libfftw3l-3.lib"
$endif

crodzilla

Thanks Sapero,

I really appreciate your expertise to make this cool dll work.  This is really neat.
I'll dive in and continue my studies of Fourier.

Carl