首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >-用AVAudioConverter转换PCM缓冲区时出错50次

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

Stack Overflow用户
提问于 2020-02-18 04:14:10
回答 1查看 190关注 0票数 1

我试图将一个样本率为44100的AVAudioPCMBuffer转换为一个采样率为48000的,但在转换时总是会出现异常(-50错误)。下面是代码:

代码语言:javascript
复制
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)")
}

有什么想法吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-02-18 22:45:42

一位苹果工程师在他们的开发论坛上回答了这个问题。我错过了convert(to:from:)变体AVAudioConverter不能转换采样率,所以您必须使用withInputFrom变量。上面的文档不太清楚,但我想出了:

代码语言:javascript
复制
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()
    }

    let conversionRatio = sampleRate / Float(tempBuffer.format.sampleRate)
    let newLength = Float(audioFile.length) * conversionRatio
    guard let newBuffer = AVAudioPCMBuffer(pcmFormat: newFormat,
                                           frameCapacity: AVAudioFrameCount(newLength)) 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
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60273653

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档