I am trying to stream audio from the microphone to another iPhone via Apples Multipeer Connectivity framework. To do the audio capturing and playback I am using AVAudioEngine (much thanks to Rhythmic Fistman's answer here).
I receive data from the microphone by installing a tap on the input, from this I am getting a AVAudioPCMBuffer which I then convert to an array of UInt8 which I then stream to the other phone.
But when I am converting the array back to an AVAudioPCMBuffer I get an EXC_BAD_ACCESS exception with the compiler pointing to the method where I am converting the byte array to AVAudioPCMBuffer again.
Here is the code for where I'm taking, converting and streaming the input:
input.installTap(onBus: 0, bufferSize: 2048, format: input.inputFormat(forBus: 0), block: {
(buffer: AVAudioPCMBuffer!, time: AVAudioTime!) -> Void in
let audioBuffer = self.typetobinary(buffer)
stream.write(audioBuffer, maxLength: audioBuffer.count)
})
My both functions for converting the data (taken from Martin.R's answer here):
func binarytotype <T> (_ value: [UInt8], _: T.Type) -> T {
return value.withUnsafeBufferPointer {
UnsafeRawPointer($0.baseAddress!).load(as: T.self)
}
}
func typetobinary<T>(_ value: T) -> [UInt8] {
var data = [UInt8](repeating: 0, count: MemoryLayout<T>.size)
data.withUnsafeMutableBufferPointer {
UnsafeMutableRawPointer($0.baseAddress!).storeBytes(of: value, as: T.self)
}
return data
}
And on the receiving end:
func session(_ session: MCSession, didReceive stream: InputStream, withName streamName: String, fromPeer peerID: MCPeerID) {
if streamName == "voice" {
stream.schedule(in: RunLoop.current, forMode: .defaultRunLoopMode)
stream.open()
var bytes = [UInt8](repeating: 0, count: 8)
stream.read(&bytes, maxLength: bytes.count)
let audioBuffer = self.binarytotype(bytes, AVAudioPCMBuffer.self) //Here is where the app crashes
do {
try engine.start()
audioPlayer.scheduleBuffer(audioBuffer, completionHandler: nil)
audioPlayer.play()
}catch let error {
print(error.localizedDescription)
}
}
}
The thing is that I can convert the byte array back and forth and play sound from it before I stream it (in the same phone) but not create the AVAudioPCMBuffer on the receiving end. Does anyone know why the conversion doesn't work on the receiving end? Is this the right way to go?
Any help, thoughts/input about this would be much appreciated.
See Question&Answers more detail:
os