Guidance指路人g.yi.org software / rapidq / Examples / Algorithm & Maths / Fourier Transforms / fft_test.htm
 最新 LeonAutoBackup
fft_test.bas
```
'******************** Sample FFT test code ***********************
'this program will add sine waves, perform an FFT (or DFT), then
'   plot the amplitude of the spectrum, then reconstruct the
'   original input waveform
'     Uses fftlib.dll  -- a dll made by Freebasic STDCALL convention
'*****************************************************************

\$TYPECHECK ON
\$INCLUDE <RapidQ2.inc>
\$INCLUDE <QChart.inc>
\$INCLUDE <fftlib.inc>

'----- Form Event SUB Declarations
Declare Sub frmMainResize (SENDER As QFORM)
declare Sub DrawOrig

CONST pi =  3.141592653589793#

'set some maximum limits
DEFINT maxc = 10           'max columns
DEFINT maxr = 20           'max rows
DEFINT maxv = 16000        'should be at least double sample points

'set the number of data points
DIM n AS INTEGER
n = 512 'try 256, or 512, 1024, 4096 8192, etc.

DIM pi2 as single
pi2 =  pi * 2
DIM th AS SINGLE

DIM xdata(0 TO maxv) AS SINGLE
DIM ydata(0 TO maxv) AS SINGLE
DIM tdata(0 TO maxv) AS SINGLE
DIM i                AS INTEGER
DIM myStep            AS SINGLE
myStep = pi2 /n
DIM myTime            AS SINGLE

'**** build our waveform of sine waves ******
i = 0
FOR th = 0.0 TO pi2 STEP myStep   '(pi2 /(n/1.0001))      '1 sec period of n samples
xdata(i) =             16 * COS(th * 2) 'amp & Hz
xdata(i) = xdata(i) + 6 * COS(th * 8) 'amp & Hz
xdata(i) = xdata(i) + 4 * SIN(th * 14) 'amp & Hz
xdata(i) = xdata(i) + 2 * COS(th * 20) 'amp & Hz
xdata(i) = xdata(i) + 2 * SIN(th * 26) 'amp & Hz
xdata(i) = xdata(i) + 4 * COS(th * 32) 'amp & Hz
xdata(i) = xdata(i) + 8 * SIN(th * 38) 'amp & Hz
xdata(i) = xdata(i) + 12 * SIN(th * 65) 'amp & Hz
xdata(i) = xdata(i) + 12 * SIN(th * 85) 'amp & Hz
xdata(i) = xdata(i) + 12 * SIN(th * 103) 'amp & Hz
xdata(i) = xdata(i) + 12 * SIN(th * 120) 'amp & Hz
ydata(i) = 0                            'nothing in imaginary domain
tdata(i) = i
i = i + 1
NEXT th

'----- Define the main form
Create frmMain As QFORM
Width = 640
ClientHeight = 480
OnResize = frmMainResize
Onshow = DrawOrig
Create Graph1 As QCHART                 'Create a copy of the new object
Top = 0 : Left = 0
Width = frmMain.ClientWidth
Height = frmMain.ClientHeight
OnPaint = Graph1.PaintChart           'This line REQUIRED to process Repaints
End Create'Graph1
End Create'frmMain

Create FFTMain As QFORM
Width = 640
left =300
top = 200
ClientHeight = 480
OnResize = frmMainResize
Create Graph2 As QCHART                 'Create a copy of the new object
Top = 0 : Left = 0
Width = FFTMain.ClientWidth
Height = FFTMain.ClientHeight
OnPaint = Graph2.PaintChart             'This line REQUIRED to process Repaints
End Create'Graph2
End Create

Create iFFTMain As QFORM
Width = 640
left =400
ClientHeight = 480
OnResize = frmMainResize
Create Graph3 As QCHART                    'Create a copy of the new object
Top = 0 : Left = 0
Width = iFFTMain.ClientWidth
Height = iFFTMain.ClientHeight
OnPaint = Graph3.PaintChart              'This line REQUIRED to process Repaints
End Create'Graph2
End Create

Graph3.ClearAll
Graph2.ClearAll
Graph1.ClearAll
frmMain.Showmodal

'draw the original input waveform
Sub DrawOrig
Dim j  As Integer
Dim i  As Integer
'draw original data set
With Graph1
.Initialize                             'Set defaults
.ChartType = ctXY                       'XY Scatter Chart
.ChartStyle = csLines                   'just Lines, use csBoth for lines and Points
.MainTitle.Text = "Original Data"
.XTitle.Text = "X Axis"
.YTitle.Text = "Y Axis"
.Cols = 1                               'Number of series
.Rows = n-1                            'Number of data points per series
REDIM Graph1.XYData(.Cols,.Rows,2)      'Redim XYData.  Note 3rd dim always 2
.DoLegend = false
.Series(1).LineWidth = 2
For j = 0 To .Rows
.XYData(1,j,1) = tdata(j)           'X Values (3rd dim 1)
.XYData(1,j,2) = xdata(j)           'Y Values (3rd dim 2)
Next j
.DrawChart (FALSE)                      'Draw it!
End With

'calc the fft spectrum

DIM xCopy(n)  AS SINGLE
DIM yCopy(n)  AS SINGLE
DIM Hz(0 TO n) AS SINGLE
DIM ph(0 TO n) AS SINGLE
DIM Amp(0 TO n) AS SINGLE

myTime = TIMER
fft(@xdata(0), @ydata(0), n, 0)
FFTMagnitude(@xdata(0) , @ydata(0) , n, @Amp(0))
FFTPhase(@xdata(0), @ydata(0), n, @ph(0))
FFTFrequency(@Hz(0),(n/1.0!), n)

' ' or
' --------DFT any size sample ---------------
'   DFT(@xdata(0), @ydata(0), n, 0)
'   DFTMagnitude(@xdata(0) , @ydata(0) , n, @Amp(0))
'   DFTPhase(@xdata(0), @ydata(0), n, @ph(0))
'   FFTFrequency (@Hz(0), (n), n)
SHowmessage "fft calculation time = " + str\$(TIMER - myTime)

' '------------------------------------------

'draw fourier domain data set
With Graph2
.Initialize                                     'Set defaults
.ChartType = ctXY                               'XY Scatter Chart
.ChartStyle = csLines                           'just Lines, use csBoth for lines and Points
.Cols = 1                                       'Number of series
.DoLegend = false
.Series(1).LineWidth = 2
.Rows = n\2 -1                                 'spectral data is 1/2 sample (nyquist limit)
REDIM Graph2.XYData(.Cols,.Rows,2)               'Redim XYData.  Note 3rd dim always 2
For j = 0 To .Rows
.XYData(1,j,1) = Hz(j)                  'X Values (3rd dim 1)
.XYData(1,j,2) = amp(j) 'ph(j)                   'Y Values (3rd dim 2)
Next j
.MainTitle.Text = "Spectrum"
.XTitle.Text = "Frequency":         .YTitle.Text = "Magnitude"
.DrawChart (FALSE)
End With
FFTMain.Show

'check inverse
fft(@xdata(0), @ydata(0), n, 1)			'time domain left in xData
'  or
'   DFT(@xdata(0), @ydata(0), n, 1)

With Graph3
.Initialize                                     'Set defaults
.ChartType = ctXY                               'XY Scatter Chart
.ChartStyle = csLines                           'just Lines, use csBoth for lines and Points
.Cols = 1                                       'Number of series
.DoLegend = false
.Series(1).LineWidth = 2
.Rows = n-1
REDIM Graph3.XYData(.Cols,.Rows,2)               'Redim XYData.  Note 3rd dim always 2
For j = 0 To .Rows
.XYData(1,j,1) = tdata(j)                   'X Values (3rd dim 1)
.XYData(1,j,2) = xdata(j)                   'Y Values (3rd dim 2)
Next j
.MainTitle.Text = "reconstructed"
.XTitle.Text = "Time":         .YTitle.Text = "signal"
.DrawChart (FALSE)
End With
iFFTMain.Show
END SUB

SUB frmMainResize (SENDER AS QForm)
WITH Graph1
.Width = frmMain.ClientWidth               'Calculate new sizes
.Height = frmMain.ClientHeight
.RedrawChart                                        'Redraw the QChart Object
END WITH
'Plus anything else that needs doing in your form resize
END SUB

```