我试图弄清楚一个人在麦克风讲话时的平均频率或范围。它不一定是实时的。到目前为止,我的方法是使用AVAudioEngine和AVAudioPCMBuffer,获取缓冲区数据并将其转换为FFT。
inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { (buffer: AVAudioPCMBuffer, when: AVAudioTime) in
self.recognitionRequest?.append(buffer)
let data = buffer.floatChannelData?[0]
let arrayOfData = Array(UnsafeBufferPointer(start: data, count: Int(buffer.frameLength)))
let fftData = self.performFFT(arrayOfData)
}
func performFFT(_ input: [Float]) -> [Float] {
var real = [Float](input)
var imag = [Float](repeating: 0.0, count: input.count)
var splitComplex = DSPSplitComplex(realp: &real, imagp: &imag)
let length = vDSP_Length(floor(log2(Float(input.count))))
let radix = FFTRadix(kFFTRadix2)
let weights = vDSP_create_fftsetup(length, radix)
vDSP_fft_zip(weights!, &splitComplex, 1, length, FFTDirection(FFT_FORWARD))
var magnitudes = [Float](repeating: 0.0, count: input.count)
vDSP_zvmags(&splitComplex, 1, &magnitudes, 1, vDSP_Length(input.count))
var normalizedMagnitudes = [Float](repeating: 0.0, count: input.count)
vDSP_vsmul(sqrt(magnitudes), 1, [2.0 / Float(input.count)], &normalizedMagnitudes, 1, vDSP_Length(input.count))
vDSP_destroy_fftsetup(weights)
return normalizedMagnitudes
}
public func sqrt(_ x: [Float]) -> [Float] {
var results = [Float](repeating: 0.0, count: x.count)
vvsqrtf(&results, x, [Int32(x.count)])
return results
}
我想我正在返回正确的FFT数据,打印看起来像这样:
然而,这不是正确的Hz。这是我说话,平均男性声音的范围是85到180赫兹。我只是不确定从哪里开始。
目标是找到用户通过麦克风讲话的频率平均值或范围。非常感谢任何帮助!!!
答案 0 :(得分:1)
FFT幅度是频谱估计器(对于许多语音音调不起作用),而不是音调检测/估计算法。尝试使用音调估计算法,即使声音谐波/泛音系列具有更多的光谱功率,也可以更好地检测基本音调。