首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AVAudioConverter会损坏数据

AVAudioConverter会损坏数据
EN

Stack Overflow用户
提问于 2020-10-27 19:44:15
回答 1查看 196关注 0票数 0

我正在尝试将AVAudioPCMBuffer从Float32 44.1 8kHz转换为Int16 8 8kHz。我使用AVAudioConverter。但是在转换之后,我得到了损坏的数据。当我每隔100ms从麦克风中读取数据时,我会得到每800个样本(读取数据中的第一个样本)的损坏。损坏的示例如下所示:broken sample

这只是800个样本中的一个,但这听起来真的很讨厌每100毫秒点击一次。下面是我的一段代码:

代码语言:javascript
复制
...
    let outputFormat = AVAudioFormat(commonFormat: .pcmFormatInt16,
                                     sampleRate: 8000,
                                     channels: 1,
                                     interleaved: false)!
    let input = self.engine.inputNode
    let bus = 0
    let inputFormat = input.outputFormat(forBus: bus)
        
    let bufferSize = inputFormat.sampleRate * 0.1 // Read every 100ms
        
    input.installTap(onBus: bus, bufferSize: UInt32(bufferSize), format: inputFormat) { (buffer, time) -> Void in
                
        let convertedBuffer = self.convertBuffer(buffer: buffer, from: inputFormat, to: outputFormat)
        if self.isRecording {
            self.inFile?.seekToEndOfFile()
            let data = Data(buffer: UnsafeBufferPointer(start: convertedBuffer.int16ChannelData![0], count: Int(convertedBuffer.frameLength)))
            self.inFile?.write(data)
        }
...

func convertBuffer(buffer: AVAudioPCMBuffer,
                   from inputFormat: AVAudioFormat,
                   to outputFormat: AVAudioFormat) -> AVAudioPCMBuffer {
        
    let converter = AVAudioConverter(from: inputFormat, to: outputFormat)!
        
    let inputCallback: AVAudioConverterInputBlock = { inNumPackets, outStatus in
        outStatus.pointee = .haveData
        return buffer
    }
        
    let convertedBuffer = AVAudioPCMBuffer(
        pcmFormat: outputFormat,
        frameCapacity: AVAudioFrameCount(outputFormat.sampleRate) * buffer.frameLength / AVAudioFrameCount(buffer.format.sampleRate))!
        
    var error: NSError?
    let status = converter.convert(to: convertedBuffer, error: &error, withInputFrom: inputCallback)
    assert(status != .error)
        
    return convertedBuffer
}

当我在没有任何转换的情况下编写buffer时,我可以得到清晰的声音而不会损坏。如果我每隔200ms读取一次数据,那么每1600个样本就会被损坏。所以它只是我得到的每个缓冲区中的第一个样本是损坏的。

我真的不知道我的代码出了什么问题,为什么它会这样工作。有什么错误吗?

附言:我真的不关心转换,所有我需要的是从麦克风获得16位PCM 8 8kHz原始音频数据。如果有人知道如何以另一种方式做到这一点,我将非常感谢您的帮助。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-10-28 19:50:25

音频转换器具有内部状态。创建一个转换器,而不是在每次调用convertBuffer时创建一个转换器,应该可以解决这个问题。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64553738

复制
相关文章

相似问题

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