Trying to stream audio from microphone to another phone via multipeer connectivity
Your AVAudioPCMBuffer
serialisation/deserialisation is wrong.
Swift3's casting has changed a lot & seems to require more copying than Swift2.
Here's how you can convert between [UInt8]
and AVAudioPCMBuffer
s:
N.B: this code assumes mono float data at 44.1kHz.
You might want to change that.
func copyAudioBufferBytes(_ audioBuffer: AVAudioPCMBuffer) -> [UInt8] {
let srcLeft = audioBuffer.floatChannelData![0]
let bytesPerFrame = audioBuffer.format.streamDescription.pointee.mBytesPerFrame
let numBytes = Int(bytesPerFrame * audioBuffer.frameLength)
// initialize bytes to 0 (how to avoid?)
var audioByteArray = [UInt8](repeating: 0, count: numBytes)
// copy data from buffer
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 {
// format assumption! make this part of your protocol?
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]
// for stereo
// let dstRight = audioBuffer.floatChannelData![1]
buf.withUnsafeBufferPointer {
let src = UnsafeRawPointer($0.baseAddress!).bindMemory(to: Float.self, capacity: Int(frameLength))
dstLeft.initialize(from: src, count: Int(frameLength))
}
return audioBuffer
}
iOS8 AVAudioEngine how to send microphone data over Multipeer Connectivity?
I haven't tried this solution:
- (NSOutputStream *)startStreamWithName:(NSString *)streamName
toPeer:(MCPeerID *)peerID
error:(NSError **)error
You can receive a float array by using the property buffer.floatChannelData
. Now you can pack this float array into NSOutputStream
and send it.
On client side you can try to receive a stream:
- (void)session:(MCSession *)session
didReceiveStream:(NSInputStream *)stream
withName:(NSString *)streamName
fromPeer:(MCPeerID *)peerID
{
stream.delegate = self;
[stream scheduleInRunLoop:[NSRunLoop mainRunLoop]
forMode:NSDefaultRunLoopMode];
[stream open];
}
But before you try this, you could try to send random values (therefore white noise) instead of the float array, so you can make sure, that the time slot for sending these buffers (we are talking about real-time) is wide enough.
Update 15.10.2014
I found exactly what you need:
http://robots.thoughtbot.com/streaming-audio-to-multiple-listeners-via-ios-multipeer-connectivity
Related Topics
How to Remove Optional from String Value Swift
Convert a Custom Object to Data to Be Saved in Nsuserdefauts
Uicollectionviewlayout Not Working with Uiimage in Swift 5 and Xcode 11
Why Can't the Swift Compiler Infer This Closure's Type
How to Return a First Word from a String in Swift
How to Rewrite Swift ++ Operator in : Ternary Operator
Swift 4.0 Mapview Running Slow
Swift Error: 'Missing Return in Function'
Single-Element Parethesized Expressions/Tuples VS Common Use of Parentheses
How to Add Kerning to a Textfield in Swiftui
Call Completion Block When Two Other Completion Blocks Have Been Called
Firebase Storage Downloadurl()' Is Deprecated: Use 'Storagereference.Downloadurlwithcompletion()
How to Open Settings App Programmatically
Initializer for Conditional Binding Must Have Optional Type, Not 'String'
Swift: Second Occurrence with Indexof
Checking If an Array of Custom Objects Contain a Specific Custom Object