0

我需要你的帮助。想在我的音频文件上使用 FFT。我想将我的音频文件切割成更小的缓冲区数组,并将我的 FFT 与所有子缓冲区一起使用。

为什么 ??因为我需要知道并查看(使用绘图数据)我的频率如何具有特殊性。我想知道,我的音频文件中的噪音是如何开始的。

那是我的 FFT 代码。我不知道我做错了什么。

谢谢你的帮助

编辑代码

func FFT (buffer: AVAudioPCMBuffer){

    let frameCount = buffer.frameCapacity
    let log2n = UInt(round(log2(Double(frameCount))))

    print (" log2n \(log2n)");

    let bufferSizePOT = Int(1 << log2n)

    print (" bufferSizePot \(bufferSizePOT)");
    let inputCount = bufferSizePOT / 2
    let fftSetup = vDSP_create_fftsetup(log2n, Int32(kFFTRadix2))

    var realp = [Float](repeating: 0, count: inputCount)
    var imagp = [Float](repeating: 0, count: inputCount)
    var output = DSPSplitComplex(realp: &realp, imagp: &imagp)


    let windowSize = bufferSizePOT
    var transferBuffer = [Float](repeating: 0, count: windowSize)
    var window = [Float](repeating: 0, count: windowSize)

    vDSP_hann_window(&window, vDSP_Length(windowSize), Int32(vDSP_HANN_NORM))
    vDSP_vmul((buffer.floatChannelData?.pointee)!, 1, window,
              1, &transferBuffer, 1, vDSP_Length(windowSize))

    let temp = UnsafePointer<Float>(transferBuffer)

    temp.withMemoryRebound(to: DSPComplex.self, capacity: transferBuffer.count) { (typeConvertedTransferBuffer) -> Void in
        vDSP_ctoz(typeConvertedTransferBuffer, 2, &output, 1, vDSP_Length(inputCount))

    }

    // Do the fast Fourier forward transform, packed input to packed output
    vDSP_fft_zrip(fftSetup!, &output, 1, log2n, FFTDirection(FFT_FORWARD))


    //---------------------------------------------------


    var magnitudes = [Float](repeating: 0.0, count: inputCount)
    vDSP_zvmags(&output, 1, &magnitudes, 1, vDSP_Length(inputCount))

    var normalizedMagnitudes = [Float](repeating: 0.0, count: inputCount)
    vDSP_vsmul(sqrt(x: magnitudes), 1, [2.0 / Float(inputCount)],
               &normalizedMagnitudes, 1, vDSP_Length(inputCount))


    for f in 0..<normalizedMagnitudes.count
    {
        print("\(f), \(normalizedMagnitudes[f])")
    }


    vDSP_destroy_fftsetup(fftSetup)

}
4

1 回答 1

0

基本上,而不是制作

frameCount = UInt32(audioFile.length)

您希望使用更小的 frameCount (例如 4096,大约 1/10 秒的音频),然后循环播放音频文件,读取和处理 frameCount 长度的每个较小的数据块(做更短的窗口化FFT) 分开处理,而不是在一个巨大的 FFT 中处理整个文件。

请注意,在循环音频文件样本数据并执行一系列相同长度的 FFT 时,您只需执行一次 fftSetup。

如果需要,您可以在更长的时间段内对结果幅度矢量的集合进行矢量求和,以减少打印输出的时间分辨率和长度。这是韦尔奇谱密度估计方法的一种形式。

于 2017-01-26T22:55:49.200 回答