打印

一段VB编的FFT,有疑问。急!!!

[复制链接]
2347|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
rockzone|  楼主 | 2007-8-13 20:39 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
程序如下:


Option Explicit
Const Pi = 3.14159265358979

Function NumberOfBitsNeeded(PowerOfTwo As Long) As Byte
    Dim I As Byte
    For I = 0 To 16
        If (PowerOfTwo And (2 ^ I)) <> 0 Then
            NumberOfBitsNeeded = I
            Exit Function
        End If
    Next
End Function


Function IsPowerOfTwo(X As Long) As Boolean
    If (X < 2) Then IsPowerOfTwo = False: Exit Function
    If (X And (X - 1)) = False Then IsPowerOfTwo = True
End Function


Function ReverseBits(ByVal Index As Long, NumBits As Byte) As Long
    Dim I As Byte, Rev As Long
    
    For I = 0 To NumBits - 1
        Rev = (Rev * 2) Or (Index And 1)
        Index = Index \ 2
    Next
    
    ReverseBits = Rev
End Function


Sub FourierTransform(NumSamples As Long, RealIn() As Double, ImageIn() As Double, RealOut() As Double, ImagOut() As Double, Optional InverseTransform As Boolean = False)
    Dim AngleNumerator As Double
    Dim NumBits As Byte, I As Long, j As Long, K As Long, n As Long, BlockSize As Long, BlockEnd As Long
    Dim DeltaAngle As Double, DeltaAr As Double
    Dim Alpha As Double, Beta As Double
    Dim TR As Double, TI As Double, AR As Double, AI As Double
    
    If InverseTransform Then
        AngleNumerator = -2# * Pi
    Else
        AngleNumerator = 2# * Pi
    End If

    If (IsPowerOfTwo(NumSamples) = False) Or (NumSamples < 2) Then
        Call MsgBox("Error in procedure Fourier:" + vbCrLf + " NumSamples is " + CStr(NumSamples) + ", which is not a positive integer power of two.", , "Error!")
        Exit Sub
    End If
   
    NumBits = NumberOfBitsNeeded(NumSamples)
    For I = 0 To (NumSamples - 1)
        j = ReverseBits(I, NumBits)
        RealOut(j) = RealIn(I)
        ImagOut(j) = ImageIn(I)
    Next
    
    BlockEnd = 1
    BlockSize = 2
    
    Do While BlockSize <= NumSamples
        DeltaAngle = AngleNumerator / BlockSize
        Alpha = Sin(0.5 * DeltaAngle)
        Alpha = 2# * Alpha * Alpha
        Beta = Sin(DeltaAngle)
        
        I = 0
        Do While I < NumSamples
            AR = 1#
            AI = 0#
            
            j = I
            For n = 0 To BlockEnd - 1
                K = j + BlockEnd
                TR = AR * RealOut(K) - AI * ImagOut(K)
                TI = AI * RealOut(K) + AR * ImagOut(K)
                RealOut(K) = RealOut(j) - TR
                ImagOut(K) = ImagOut(j) - TI
                RealOut(j) = RealOut(j) + TR
                ImagOut(j) = ImagOut(j) + TI
                DeltaAr = Alpha * AR + Beta * AI
                AI = AI - (Alpha * AI - Beta * AR)
                AR = AR - DeltaAr
                j = j + 1
            Next
            
            I = I + BlockSize
        Loop
        
        BlockEnd = BlockSize
        BlockSize = BlockSize * 2
    Loop

    If InverseTransform Then
        'Normalize the resulting time samples...
        For I = 0 To NumSamples - 1
            RealOut(I) = RealOut(I) / NumSamples
            ImagOut(I) = ImagOut(I) / NumSamples
        Next
    End If
End Sub


Function FrequencyOfIndex(NumberOfSamples As Long, ByVal Index As Long) As Double
    'Based on IndexToFrequency().  This name makes more sense to me.
    
    If Index >= NumberOfSamples Then
        FrequencyOfIndex = 0#
        Exit Function
    ElseIf Index <= NumberOfSamples / 2 Then
        FrequencyOfIndex = CDbl(Index) / CDbl(NumberOfSamples)
        Exit Function
    Else
        FrequencyOfIndex = -CDbl(NumberOfSamples - Index) / CDbl(NumberOfSamples)
        Exit Function
    End If
End Function


Sub CalcFrequency(NumberOfSamples As Long, FrequencyIndex As Long, RealIn() As Double, ImagIn() As Double, RealOut As Double, ImagOut As Double)
    
    Dim K As Long
    Dim Cos1 As Double, Cos2 As Double, Cos3 As Double, Theta As Double, Beta As Double
    Dim Sin1 As Double, Sin2 As Double, Sin3 As Double
    
    Theta = 2 * Pi * FrequencyIndex / CDbl(NumberOfSamples)
    Sin1 = Sin(-2 * Theta)
    Sin2 = Sin(-Theta)
    Cos1 = Cos(-2 * Theta)
    Cos2 = Cos(-Theta)
    Beta = 2 * Cos2
    
    For K = 0 To NumberOfSamples - 2
        'Update trig values
        Sin3 = Beta * Sin2 - Sin1
        Sin1 = Sin2
        Sin2 = Sin3
        
        Cos3 = Beta * Cos2 - Cos1
        Cos1 = Cos2
        Cos2 = Cos3
        
        RealOut = RealOut + RealIn(K) * Cos3 - ImagIn(K) * Sin3
        ImagOut = ImagOut + ImagIn(K) * Cos3 + RealIn(K) * Sin3
    Next
End Sub



以上程序各函数功能是什么,请高手讲解一下。

相关帖子

沙发
computer00| | 2007-8-13 21:16 | 只看该作者

晕...看名字都看出来了...

NumberOfBitsNeeded  计算需要多少个bit,因为要做倒序排列,所以要知道有多少个bit,才能高低位掉转。

IsPowerOfTwo  判断它是不是2的整数次方。

ReverseBits  位反转用的,前面那个NumberOfBitsNeeded计算出需要多少位,然后再用这个函数将位反转。


FourierTransform  这个不用说了吧?就是FFT了。


FrequencyOfIndex  从名字上来看,是计算FFT结果中某点的频率值。


最后一个子过程, CalcFrequency,计算频率,不知道干啥用的...

使用特权

评论回复
板凳
rockzone|  楼主 | 2007-8-13 21:32 | 只看该作者

RealIn(),Imagin()是输入信号的实部和虚部数组

RealIn(),Imagin()是输入信号的实部和虚部数组
我做了一个数组正弦信号1024个数,但都是浮点的十进制数,怎么变成
输入信号的实部和须部呢?

使用特权

评论回复
地板
rockzone|  楼主 | 2007-8-13 21:38 | 只看该作者

这段程序如何使用呢??

请高手举一个例子,多谢了!!!!!

使用特权

评论回复
5
将军令| | 2007-8-14 09:25 | 只看该作者

basic语言跑快速傅立叶变换,那就不是快速了

而应该是慢速傅立叶变换】】

为什么不用C

在21ic,用basic作型号处理,是稀有物种哦!!!!!!!

使用特权

评论回复
6
将军令| | 2007-8-14 09:25 | 只看该作者

在21ic,用basic作信号处理,是稀有物种哦!!!!!!!

使用特权

评论回复
7
rockzone|  楼主 | 2007-8-14 14:26 | 只看该作者

C语言如何嵌套到VB中呢?

C语言如何嵌套到VB中呢?

使用特权

评论回复
8
computer00| | 2007-8-14 14:59 | 只看该作者

用VC做成DLL,给VB调用。

使用特权

评论回复
9
rockzone|  楼主 | 2007-8-14 15:17 | 只看该作者

不会VC,只会VB

使用特权

评论回复
10
computer00| | 2007-8-14 16:16 | 只看该作者

其实PC处理速度还是很快的,用VB处理也可以试试

使用特权

评论回复
11
rockzone|  楼主 | 2007-8-14 16:32 | 只看该作者

!!

楼上的BOSS,能不能帮我说说这段程序我应该怎么用啊,

比如说我有1024个十进制的数,是个正弦波,

我想画出频域谱线,应该怎么引用这段程序呢?

使用特权

评论回复
12
computer00| | 2007-8-14 20:21 | 只看该作者

直接调用FourierTransform这个函数就可以了

关于变换后的结果是什么意思,你可以去DSP版块搜索我以前发过的帖子。

使用特权

评论回复
13
rockzone|  楼主 | 2007-8-14 20:45 | 只看该作者

~~

结果计算的结果是实部+虚部,

这样的数怎么画成谱线呢,

BOSS,你在DSP的帖子好多,我该看哪个呢,请明示!

使用特权

评论回复
14
computer00| | 2007-8-14 21:10 | 只看该作者

搜索就有了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

69

主题

807

帖子

4

粉丝