从麦克风播放的音频不稳定,听起来像吹进麦克风的空气

时间:2017-03-09 17:02:51

标签: ios swift audio type-conversion avaudioplayer

我使用以下方法录制音频:

    localInput?.installTap(onBus: 0, bufferSize: 4096, format: localInputFormat) {
        (buffer, time) -> Void in

        let audioBuffer = self.audioBufferToBytes(audioBuffer: buffer)
        let output = self.outputStream!.write(audioBuffer, maxLength: Int(buffer.frameLength))

        if output > 0 {
            print("\(#file) > \(#function) > \(output) bytes written from queue \(self.currentQueueName())")
        }
        else if output == -1 {
            let error = self.outputStream!.streamError
            print("\(#file) > \(#function) > Error writing to stream: \(error?.localizedDescription)")
        }
    }

我的localInputFormat如下:

self.localInput = self.localAudioEngine.inputNode
self.localAudioEngine.attach(self.localAudioPlayer)
self.localInputFormat = self.localInput?.inputFormat(forBus: 0)
self.localAudioEngine.connect(self.localAudioPlayer, to: self.localAudioEngine.mainMixerNode, format: self.localInputFormat)

函数audioBufferToBytes如下:

func audioBufferToBytes(audioBuffer: AVAudioPCMBuffer) -> [UInt8] {
    let srcLeft = audioBuffer.floatChannelData![0]
    let bytesPerFrame = audioBuffer.format.streamDescription.pointee.mBytesPerFrame
    let numBytes = Int(bytesPerFrame * audioBuffer.frameLength)

    // initialize bytes by 0 
    var audioByteArray = [UInt8](repeating: 0, count: numBytes)

    srcLeft.withMemoryRebound(to: UInt8.self, capacity: numBytes) { srcByteData in
        audioByteArray.withUnsafeMutableBufferPointer {
            $0.baseAddress!.initialize(from: srcByteData, count: numBytes)
        }
    }

    return audioByteArray
}

在另一台设备上,当我收到数据时,我必须将其转换回来。因此,它收到了以下内容:

func bytesToAudioBuffer(_ buf: [UInt8]) -> AVAudioPCMBuffer {

    let fmt = AVAudioFormat(commonFormat: .pcmFormatFloat32, sampleRate: 44100, channels: 1, interleaved: true)
    let frameLength = UInt32(buf.count) / fmt.streamDescription.pointee.mBytesPerFrame

    let audioBuffer = AVAudioPCMBuffer(pcmFormat: fmt, frameCapacity: frameLength)
    audioBuffer.frameLength = frameLength

    let dstLeft = audioBuffer.floatChannelData![0]

    buf.withUnsafeBufferPointer {
        let src = UnsafeRawPointer($0.baseAddress!).bindMemory(to: Float.self, capacity: Int(frameLength))
        dstLeft.initialize(from: src, count: Int(frameLength))
    }

    return audioBuffer
}

最后,我们播放这个音频数据:

                self.audioPlayerQueue.async {
                    self.peerAudioPlayer.scheduleBuffer(audioBuffer)

                    if (!self.peerAudioPlayer.isPlaying && self.localAudioEngine.isRunning) {
                        self.peerAudioPlayer.play()
                    }
                }

然而,在任何一个扬声器上我都会听到听起来像是每隔半秒(ish)敲击麦克风的声音。不是他们真正说话或任何事情。我想这是因为我从音频缓冲区转换为字节并返回,但我不确定。有没有人看到上述任何问题?

感谢。

1 个答案:

答案 0 :(得分:0)

如果有人对该解决方案感兴趣,基本上问题是录音设备上的音频是17640字节,但要流式传输,它会将其分解成更小的部分,而在接收设备上我必须读取第一个17640字节然后播放音频。不播放收到的每一小块数据。