Quantcast
Channel: VBForums - CodeBank - Visual Basic 6 and earlier
Viewing all articles
Browse latest Browse all 1532

Simple FFT module

$
0
0
I wrote this FFT that you can put in a module file and use anywhere in your program.
Code:

Public Const Pi As Double = 3.14159265358979

Public Type Complex
    Re As Double
    Im As Double
End Type


Dim FFTSize As Long
Dim FFTSize_Log2 As Long
Dim BOR_LUT() As Long
Dim Pow2_LUT() As Long


Public Sub SetupFFT(ByVal Size As Long)
    Dim n As Long
    Dim n1 As Long
    Dim n2 As Long
    Dim i As Long
   
    FFTSize = Size
    FFTSize_Log2 = Log(FFTSize) / Log(2)
   
    ReDim BOR_LUT(FFTSize - 1)
   
    For n = 0 To FFTSize - 1
        n1 = n
        n2 = 0
        For i = 0 To FFTSize_Log2 - 1
            n2 = (n2 * 2) Or (n1 And 1)
            n1 = n1 \ 2
        Next i
        BOR_LUT(n) = n2
    Next n
   
    ReDim Pow2_LUT(FFTSize_Log2 - 1)
    For n = 0 To FFTSize_Log2 - 1
        Pow2_LUT(n) = 2 ^ n
    Next n
End Sub


Public Sub FFT(ByRef Data1() As Complex, ByRef Data2() As Complex, ByVal Sign As Long)
    Dim Layer As Long
    Dim BlockCount As Long
    Dim BlockSize As Long
    Dim HalfBlockSize As Long
    Dim BlockNumber As Long
    Dim ButterflyNumber As Long
    Dim n0 As Long
    Dim n1 As Long
    Dim n2 As Long
    Dim DataTemp() As Complex
    Dim Twiddles() As Complex
    Dim n As Long
   
    ReDim Twiddles(FFTSize - 1)
    For n = 0 To FFTSize - 1
        Twiddles(n) = GetTwiddle(n, Sign)
    Next n
   
   
    DataTemp() = Data1()
   
    For Layer = 0 To FFTSize_Log2 - 1
        BlockCount = Pow2_LUT(Layer)
        BlockSize = FFTSize \ BlockCount
        HalfBlockSize = BlockSize \ 2
        For BlockNumber = 0 To BlockCount - 1
            n0 = BlockNumber * BlockSize
            For ButterflyNumber = 0 To HalfBlockSize - 1
                n1 = n0 + ButterflyNumber
                n2 = n1 + HalfBlockSize
               
                'do butterfly calculation
                Data2(n1) = ComplexAdd(DataTemp(n1), DataTemp(n2))
                Data2(n2) = ComplexMult(ComplexSub(DataTemp(n1), DataTemp(n2)), Twiddles(ButterflyNumber * BlockCount))
               
            Next ButterflyNumber
        Next BlockNumber
        DataTemp() = Data2()
    Next Layer
   
    For n = 0 To FFTSize - 1
        Data2(n) = DataTemp(BOR_LUT(n))
    Next n
End Sub


Private Function ComplexAdd(ByRef Value1 As Complex, ByRef Value2 As Complex) As Complex
    ComplexAdd.Re = Value1.Re + Value2.Re
    ComplexAdd.Im = Value1.Im + Value2.Im
End Function

Private Function ComplexSub(ByRef Value1 As Complex, ByRef Value2 As Complex) As Complex
    ComplexSub.Re = Value1.Re - Value2.Re
    ComplexSub.Im = Value1.Im - Value2.Im
End Function

Private Function ComplexMult(ByRef Value1 As Complex, ByRef Value2 As Complex) As Complex
    ComplexMult.Re = Value1.Re * Value2.Re - Value1.Im * Value2.Im
    ComplexMult.Im = Value1.Re * Value2.Im + Value1.Im * Value2.Re
End Function


Private Function GetTwiddle(ByVal k As Long, ByVal Sign As Long) As Complex
    With GetTwiddle
        .Re = Cos(2 * Pi * k / FFTSize)
        .Im = Sin(2 * Pi * k / FFTSize) * Sign
    End With
End Function


You just call SetupFFT before using it, to set the size of the FFT (must be a power-of-2), and then you perform an FFT or IFFT on your data by calling the FFT sub. You also need to call SetupFFT again, any time you want to change the size of your FFT. I moved as much stuff out of the FFT sub to the SetupFFT sub, so that this setup stuff doesn't get run with every single you run the FFT sub (which would slow it down). To do an FFT, call it with the Sign parameter set to -1. To do an IFFT, call the FFT sub with the Sign parameter set to 1. The FFT parameters Data1 and Data2 are arrays of type Complex (a user-defined type). Data1 is the input, and Data2 is the output. Data1 is time domain, and Data2 is frequency domain, when performing an FFT. Data1 is frequency domain, and Data2 is time domain, when performing an IFFT.

Viewing all articles
Browse latest Browse all 1532

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>