首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带Swift的流音频

带Swift的流音频
EN

Stack Overflow用户
提问于 2020-12-11 22:30:22
回答 1查看 414关注 0票数 2

我正在开发一个应用程序,该应用程序应该记录用户的语音并通过MQTT协议将其传输到自定义设备。自定义设备的音频规范:小终端,无签名,16位LPCM,8khz采样率.每个数据包应该是1000个字节。

我不熟悉AudioEngine,我发现了这个代码示例,我认为它适合我的情况:

代码语言:javascript
复制
func startRecord() {
    audioEngine = AVAudioEngine()
    let bus = 0
    let inputNode = audioEngine.inputNode
    let inputFormat = inputNode.outputFormat(forBus: bus)
    
    var streamDescription = AudioStreamBasicDescription()
    streamDescription.mFormatID = kAudioFormatLinearPCM.littleEndian
    streamDescription.mSampleRate = 8000.0
    streamDescription.mChannelsPerFrame = 1
    streamDescription.mBitsPerChannel = 16
    streamDescription.mBytesPerPacket = 1000
    
    
    let outputFormat = AVAudioFormat(streamDescription: &streamDescription)!
    
    guard let converter: AVAudioConverter = AVAudioConverter(from: inputFormat, to: outputFormat) else {
        print("Can't convert in to this format")
        return
    }
    
    inputNode.installTap(onBus: 0, bufferSize: 1024, format: inputFormat) { (buffer, time) in
        print("Buffer format: \(buffer.format)")
        
        var newBufferAvailable = true
        
        let inputCallback: AVAudioConverterInputBlock = { inNumPackets, outStatus in
            if newBufferAvailable {
                outStatus.pointee = .haveData
                newBufferAvailable = false
                return buffer
            } else {
                outStatus.pointee = .noDataNow
                return nil
            }
        }
        
        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)
        
        print("Converted buffer format:", convertedBuffer.format)
    }
    
    audioEngine.prepare()
    
    do {
        try audioEngine.start()
    } catch {
        print("Can't start the engine: \(error)")
    }
    
}

但是目前,转换器无法将输入格式转换为我的输出格式,我不明白为什么。如果我将输出格式更改为类似的内容:

代码语言:javascript
复制
let outputFormat = AVAudioFormat(commonFormat: .pcmFormatInt16, sampleRate: 8000.0, channels: 1, interleaved: false)!

那就成功了。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-12-11 23:45:04

您的streamDescription是错误的,您没有填写所有字段,而mBytesPerPacket则是错误的--这与您的协议要求的数据包不同。对于未压缩音频(如LPCM),AudioStreamBasicDescription要求此字段为1。如果您的协议要求样本在1000个组中,那么您必须这样做。

尝尝这个

代码语言:javascript
复制
var streamDescription = AudioStreamBasicDescription()
streamDescription.mSampleRate = 8000.0
streamDescription.mFormatID = kAudioFormatLinearPCM
streamDescription.mFormatFlags = kAudioFormatFlagIsSignedInteger // no endian flag means little endian
streamDescription.mBytesPerPacket = 2
streamDescription.mFramesPerPacket = 1
streamDescription.mBytesPerFrame = 2
streamDescription.mChannelsPerFrame = 1
streamDescription.mBitsPerChannel = 16
streamDescription.mReserved = 0
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65259492

复制
相关文章

相似问题

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