我已经被这个问题困扰好几天了,并且浏览了几乎所有相关的 StackOverflow 页面。通过这次活动,我现在对 FFT 是什么及其工作原理有了更深入的了解。尽管如此,我在将其实现到我的应用程序中时遇到了极大的困难。
简而言之,我想做的是为我的应用程序制作一个频谱可视化工具(类似于this http://a3.mzstatic.com/us/r30/Purple/v4/19/5e/83/195e83f1-1e87-0b22-a726-881dd719672c/screen568x568.jpeg)。根据我收集的信息,我非常确定我需要使用声音的大小作为条形的高度。因此,考虑到所有这些,目前我能够一次分析整个 .caf 文件。为此,我使用以下代码:
let audioFile = try! AVAudioFile(forReading: soundURL!)
let frameCount = UInt32(audioFile.length)
let buffer = AVAudioPCMBuffer(PCMFormat: audioFile.processingFormat, frameCapacity: frameCount)
do {
try audioFile.readIntoBuffer(buffer, frameCount:frameCount)
} catch {
}
let log2n = UInt(round(log2(Double(frameCount))))
let bufferSize = Int(1 << log2n)
let fftSetup = vDSP_create_fftsetup(log2n, Int32(kFFTRadix2))
var realp = [Float](count: bufferSize/2, repeatedValue: 0)
var imagp = [Float](count: bufferSize/2, repeatedValue: 0)
var output = DSPSplitComplex(realp: &realp, imagp: &imagp)
vDSP_ctoz(UnsafePointer<DSPComplex>(buffer.floatChannelData.memory), 2, &output, 1, UInt(bufferSize / 2))
vDSP_fft_zrip(fftSetup, &output, 1, log2n, Int32(FFT_FORWARD))
var fft = [Float](count:Int(bufferSize / 2), repeatedValue:0.0)
let bufferOver2: vDSP_Length = vDSP_Length(bufferSize / 2)
vDSP_zvmags(&output, 1, &fft, 1, bufferOver2)
这工作正常并输出一长串数据。然而,此代码的问题是它会立即分析整个音频文件。我需要的是分析音频文件as它正在播放,与此视频非常相似:频谱可视化仪 https://www.youtube.com/watch?v=fMH9f6QM8Hs.
所以我想我的问题是:如何进行 FFT 分析while音频正在播放?
此外,除此之外,如何将 FFT 分析的输出转换为条形的实际高度?我使用上面的 FFT 分析代码收到的音频文件的输出之一是这样的:http://pastebin.com/RBLTuGx7 http://pastebin.com/RBLTuGx7。 Pastebin 的唯一原因是它的长度。我假设我将所有这些数字平均在一起并使用这些值? (仅供参考,我通过打印上面代码中的“fft”变量来获取该数组)
我尝试阅读 EZAudio 代码,但是我无法找到他们如何实时读取音频样本。任何帮助是极大的赞赏。