为什么Swift中的FFT与Python中的FFT不同?

2024-03-28 14:20:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试使用Accelerate框架将一些python numpy代码移植到Swift。在

我用python写

import numpy as np
frames = np.array([1.0, 2.0, 3.0, 4.0])
fftArray = np.fft.fft(frames, len(frames))
print(fftArray)

输出是:

^{pr2}$

所以在Swift中,我试着像这样计算FFT:

import Foundation
import Accelerate

    func fftAnalyzer(frameOfSamples: [Float]) {
        // As above, frameOfSamples = [1.0, 2.0, 3.0, 4.0]            

        let analysisBuffer = frameOfSamples
        let frameCount = frameOfSamples.count

        var reals = [Float]()
        var imags = [Float]()
        for (idx, element) in analysisBuffer.enumerated() {
            if idx % 2 == 0 {
                reals.append(element)
            } else {
                imags.append(element)
            }
        }
        var complexBuffer = DSPSplitComplex(realp: UnsafeMutablePointer(mutating: reals), imagp: UnsafeMutablePointer(mutating: imags))

        let log2Size = Int(log2f(Float(frameCount)))

        guard let fftSetup = vDSP_create_fftsetup(vDSP_Length(log2Size), Int32(kFFTRadix2)) else {
            return []
        }

        // Perform a forward FFT
        vDSP_fft_zrip(fftSetup, &(complexBuffer), 1, UInt(log2Size), Int32(FFT_FORWARD))

        let realFloats = Array(UnsafeBufferPointer(start: complexBuffer.realp, count: Int(frameCount)))
        let imaginaryFloats = Array(UnsafeBufferPointer(start: complexBuffer.imagp, count: Int(frameCount)))

        print(realFloats)
        print(imaginaryFloats)

        // Release the setup
        vDSP_destroy_fftsetup(fftSetup)

        return realFloats
    }

realFloats和imaginaryFloats的打印方式如下:

[20.0, -4.0, 0.0, 0.0]
[-4.0, 4.0, 0.0, 0.0]

有什么想法我应该做的不同?在


Tags: importfftframesvarcountnpfloatprint
1条回答
网友
1楼 · 发布于 2024-03-28 14:20:14

我不擅长numpy,但是根据the docfft需要复杂的输入。那么它的等价物将是vDSP_fft_zip,而不是{}。在

您的代码会导致缓冲区溢出或可能会导致指针悬空,在解决了所有这些问题之后,我得到了如下结论:

func fftAnalyzer(frameOfSamples: [Float]) -> [Float] {
    // As above, frameOfSamples = [1.0, 2.0, 3.0, 4.0]

    let frameCount = frameOfSamples.count

    let reals = UnsafeMutableBufferPointer<Float>.allocate(capacity: frameCount)
    defer {reals.deallocate()}
    let imags =  UnsafeMutableBufferPointer<Float>.allocate(capacity: frameCount)
    defer {imags.deallocate()}
    _ = reals.initialize(from: frameOfSamples)
    imags.initialize(repeating: 0.0)
    var complexBuffer = DSPSplitComplex(realp: reals.baseAddress!, imagp: imags.baseAddress!)

    let log2Size = Int(log2(Float(frameCount)))
    print(log2Size)

    guard let fftSetup = vDSP_create_fftsetup(vDSP_Length(log2Size), FFTRadix(kFFTRadix2)) else {
        return []
    }
    defer {vDSP_destroy_fftsetup(fftSetup)}

    // Perform a forward FFT
    vDSP_fft_zip(fftSetup, &complexBuffer, 1, vDSP_Length(log2Size), FFTDirection(FFT_FORWARD))

    let realFloats = Array(reals)
    let imaginaryFloats = Array(imags)

    print(realFloats)
    print(imaginaryFloats)

    return realFloats
}

印刷品

[10.0, -2.0, -2.0, -2.0]
[0.0, 2.0, 0.0, -2.0]

相关问题 更多 >