I am trying to transfer audio from a microphone to another iPhone through the Multipleer Connectivity core. To capture and play audio, I use AVAudioEngine (thanks to Rhythmic Fistman for the answer here ).
I get data from the microphone by setting a red button on the input, from this I get AVAudioPCMBuffer, which I then convert to an UInt8 array, which I then transfer to another phone.
But when I convert the array back to AVAudioPCMBuffer, I get an EXC_BAD_ACCESS exception, and the compiler points to a method in which I again convert the byte array to AVAudioPCMBuffer.
Here is the code where I take, convert and stream:
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 data conversion (taken from Martin.R 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 side:
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)
do {
try engine.start()
audioPlayer.scheduleBuffer(audioBuffer, completionHandler: nil)
audioPlayer.play()
}catch let error {
print(error.localizedDescription)
}
}
}
The fact is that I can convert an array of bytes back and forth and play sound from it before transmitting it (in the same phone), but not create an AVAudioPCMBuffer on the receiving side. Does anyone know why the conversion does not work on the receiving side? Is this the right way?
Any help, thoughts / materials about this would be much appreciated.