-50用AVAudioConverter转换PCM缓冲区时出错

问题描述 投票:0回答:1

我正在尝试将具有44100采样率的AVAudioPCMBuffer转换为具有48000采样率的AVAudioPCMBuffer,但是在转换时我总是会遇到异常(-50错误)。这是代码:

guard let deviceFormat = AVAudioFormat(standardFormatWithSampleRate: 48000.0, channels: 1) else {
    preconditionFailure()
}

// This file is saved as mono 44100
guard let lowToneURL = Bundle.main.url(forResource: "Tone220", withExtension: "wav") else {
    preconditionFailure()
}
guard let audioFile = try? AVAudioFile(forReading: lowToneURL) else {
    preconditionFailure()
}

let tempBuffer = AVAudioPCMBuffer(pcmFormat: audioFile.processingFormat,
                                       frameCapacity: AVAudioFrameCount(audioFile.length))!
tempBuffer.frameLength = tempBuffer.frameCapacity
    do { try audioFile.read(into: tempBuffer) } catch {
        assertionFailure("*** Caught: \(error)")
    }

guard let converter = AVAudioConverter(from: audioFile.processingFormat, to: deviceFormat) else {
    preconditionFailure()
}
guard let convertedBuffer = AVAudioPCMBuffer(pcmFormat: deviceFormat,
                                                     frameCapacity: AVAudioFrameCount(audioFile.length)) else {
    preconditionFailure()
}
convertedBuffer.frameLength = tempBuffer.frameCapacity
do { try converter.convert(to: convertedBuffer, from: tempBuffer) } catch {
     assertionFailure("*** Caught: \(error)")
}

有什么想法吗?

ios avfoundation core-audio
1个回答
0
投票

Apple工程师在他们的开发论坛上回答了这个问题。我错过了convert(to:from:)AVAudioConverter变体无法转换采样率的功能,因此您必须使用withInputFrom变体。上的文档不太清楚,但是我想出了:

private func pcmBufferForFile(filename: String, sampleRate: Float) -> AVAudioPCMBuffer {

    guard let newFormat = AVAudioFormat(standardFormatWithSampleRate: Double(sampleRate), channels: 1) else {
        preconditionFailure()
    }
    guard let url = Bundle.main.url(forResource: filename, withExtension: "wav") else {
        preconditionFailure()
    }
    guard let audioFile = try? AVAudioFile(forReading: url) else {
        preconditionFailure()
    }
    guard let tempBuffer = AVAudioPCMBuffer(pcmFormat: audioFile.processingFormat,
                                            frameCapacity: AVAudioFrameCount(audioFile.length)) else {
        preconditionFailure()
    }
    guard let newBuffer = AVAudioPCMBuffer(pcmFormat: newFormat,
                                           frameCapacity: AVAudioFrameCount(audioFile.length)) else {
        preconditionFailure()
    }

    do { try audioFile.read(into: tempBuffer) } catch {
        preconditionFailure()
    }
    guard let converter = AVAudioConverter(from: audioFile.processingFormat, to: newFormat) else {
        preconditionFailure()
    }
    var error: NSError?
    converter.convert(to: newBuffer, error: &error, withInputFrom: { (packetCount, statusPtr) -> AVAudioBuffer? in
        statusPtr.pointee = .haveData
        return tempBuffer
    })
    if error != nil {
        print("*** Conversion error: \(error!)")
    }
    return newBuffer
}
© www.soinside.com 2019 - 2024. All rights reserved.