gpt4 book ai didi

ios - FFT 计算错误 - Swift

转载 作者:搜寻专家 更新时间:2023-10-31 23:02:32 25 4
gpt4 key购买 nike

我正在尝试进行快速傅里叶变换。我的计算基于 Surge .我无法获得正确的结果。当我获取 1000 赫兹声音的 fft 时,我得到看起来像这样的东西。 FFT using surge .当我使用相同的语气并使用 python 时,我得到的东西看起来更正确 python code . python 代码如下所示:

import numpy as np
import scipy.io.wavfile
import numpy.fft
import matplotlib.pyplot as plt

FILENAME = 'beep.wav'

fs, data = scipy.io.wavfile.read(FILENAME)
data = data[:801]
spacing = 1 / float(fs)
freq = numpy.fft.rfft(data)
freq_power = np.abs(freq)
a = 1 / (2 * spacing)
b = (len(data) + 1) // 2
freq_axis = np.linspace(0, a, b)
plt.plot(freq_axis, freq_power)
plt.show()

swift代码看起来像

import Accelerate
public func sqrt(x: [Float]) -> [Float] {
var results = [Float](count: x.count, repeatedValue: 0.0)
vvsqrtf(&results, x, [Int32(x.count)])

return results
}

public func fft(input: [Float]) -> [Float] {
var real = [Float](input)
var imaginary = [Float](count: input.count, repeatedValue: 0.0)
var splitComplex = DSPSplitComplex(realp: &real, imagp: &imaginary)

let length = vDSP_Length(floor(log2(Float(input.count))))
let radix = FFTRadix(kFFTRadix2)
let weights = vDSP_create_fftsetup(length, radix)
println(weights)
vDSP_fft_zip(weights, &splitComplex, 1, 8, FFTDirection(FFT_FORWARD))

var magnitudes = [Float](count: input.count, repeatedValue: 0.0)
vDSP_zvmags(&splitComplex, 1, &magnitudes, 1, vDSP_Length(input.count))

var normalizedMagnitudes = [Float](count: input.count, repeatedValue: 0.0)
vDSP_vsmul(sqrt(magnitudes), 1, [2.0 / Float(input.count)], &normalizedMagnitudes, 1, vDSP_Length(input.count))
vDSP_destroy_fftsetup(weights)

return normalizedMagnitudes
}

重申一下。 swift 代码是给出意想不到的结果的代码。我做错了什么?

最佳答案

看起来您正在将 Swift Float 数组与 Accelerate 框架一起使用,但您可能需要使用 UnsafeMutablePointer<Float> 来分配向量。类型,因为 Accelerate 框架是一个 Objective C 框架。以下是如何执行此操作的示例。

public func sqrt(x: [Float]) -> [Float] {
// convert swift array to C vector
var temp = UnsafeMutablePointer<Float>.alloc(x.count)
for (var i=0;i<x.count;i++) {
temp[i] = x[i];
}
var count = UnsafeMutablePointer<Int32>.alloc(1)
count[0] = Int32(x.count)
vvsqrtf(temp, temp, count)
// convert C vector to swift array
var results = [Float](count: x.count, repeatedValue: 0.0)
for (var i=0;i<x.count;i++) {
results[i] = temp[i];
}
// Free memory
count.dealloc(1)
temp.dealloc(x.count)
return results
}

使用 UnsafeMutablePointer<Float> 会提高性能在整个代码中为数据向量类型,而不是像我在这个例子中所做的那样在函数调用中来回转换。此外,您还应该保存 FFT 设置并重新使用它以获得更好的性能。

由于您使用的是 vDSP FFT,您可能还喜欢 vDSP_zvabs从 FFT 结果计算幅度(以 dB 为单位)的 API。

最后一定要阅读这个关于 Accelerate 框架 FFT API 的数据打包和缩放的链接。 https://developer.apple.com/library/mac/documentation/Performance/Conceptual/vDSP_Programming_Guide/UsingFourierTransforms/UsingFourierTransforms.html

为了提高性能,vDSP API 不会输出最明显的缩放值(因为您无疑会在其他地方缩放数据)并且它们会将一些额外数据打包到一些 FFT 点中。

关于ios - FFT 计算错误 - Swift,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31999725/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com