Аудиофайл swift 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)
}
1 ответ
В основном, вместо того, чтобы делать
frameCount = UInt32(audioFile.length)
Вы хотите использовать намного меньший для frameCount (например, 4096, примерно для 1/10 секунды звука), а затем перебрать аудиофайл, читая и обрабатывая каждый меньший фрагмент данных длины frameCount (делая более короткий оконный БПФ) отдельно, вместо обработки всего файла в одном огромном БПФ.
Обратите внимание, что при циклическом воспроизведении данных примера аудиофайла и выполнении серии FFT одинаковой длины вам нужно выполнить fftSetup только один раз.
Если вы хотите, вы можете векторизовать наборы итоговых векторов величин за более длительный период времени, чтобы уменьшить временное разрешение и продолжительность вашей распечатки. Это форма метода оценки спектральной плотности Уэлча.