从麦克风播放的音频断断续续,听起来像空气吹进麦克风
Audio being played from microphone is choppy and sounds like air blowing into the microphone
我正在使用以下方法录制音频:
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 {
[=12=].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([=13=].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()
}
}
但是,在任何一个扬声器上,我都只能听到有人每隔半秒(左右)轻敲一次麦克风的声音。不是他们真的在说话什么的。我想这是由于我从音频缓冲区到字节再转换回来的结果,但我不确定。有没有人看到上述任何问题?
谢谢。
如果有人对解决方案感兴趣,基本上问题是录音设备上的音频是 17640 字节,但要流式传输它,它会将其分解成更小的部分,并且在接收设备上我必须阅读前 17640 字节,然后播放音频。不播放接收到的每一小部分数据。
我正在使用以下方法录制音频:
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 {
[=12=].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([=13=].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()
}
}
但是,在任何一个扬声器上,我都只能听到有人每隔半秒(左右)轻敲一次麦克风的声音。不是他们真的在说话什么的。我想这是由于我从音频缓冲区到字节再转换回来的结果,但我不确定。有没有人看到上述任何问题?
谢谢。
如果有人对解决方案感兴趣,基本上问题是录音设备上的音频是 17640 字节,但要流式传输它,它会将其分解成更小的部分,并且在接收设备上我必须阅读前 17640 字节,然后播放音频。不播放接收到的每一小部分数据。