15

I am trying to take incoming microphone audio and stream it to another iPhone. Basically a phone call but via bluetooth. I have the audio coming in via AVAudioRecorder:

func startRecording() {
    audioRecorder = nil
    let audioSession:AVAudioSession = AVAudioSession.sharedInstance()
    audioSession.setCategory(AVAudioSessionCategoryRecord, error: nil)

    var recordSettings:NSMutableDictionary = NSMutableDictionary(capacity: 10)
    recordSettings.setObject(NSNumber(integerLiteral: kAudioFormatLinearPCM), forKey: AVFormatIDKey)
    recordSettings.setObject(NSNumber(float: 44100.0), forKey: AVSampleRateKey)
    recordSettings.setObject(NSNumber(int: 2), forKey: AVNumberOfChannelsKey)
    recordSettings.setObject(NSNumber(int: 16), forKey: AVLinearPCMBitDepthKey)
    recordSettings.setObject(NSNumber(bool: false), forKey: AVLinearPCMIsBigEndianKey)
    recordSettings.setObject(NSNumber(bool: false), forKey: AVLinearPCMIsFloatKey)

    soundPath = documentsDirectory.stringByAppendingPathComponent("record.caf")
    refURL = NSURL(fileURLWithPath: soundPath as String)
    var error:NSError?

    audioRecorder = AVAudioRecorder(URL: refURL, settings: recordSettings as [NSObject : AnyObject], error: &error)

    if audioRecorder.prepareToRecord() == true {
        audioRecorder.meteringEnabled = true
        audioRecorder.record()
    } else {
        println(error?.localizedDescription)
    }
}

Then I tried using StreamReader from HERE - StreamReader from @martin-r

Using:

if let aStreamReader = StreamReader(path: documentsDirectory.stringByAppendingPathComponent("record.caf")) {
                while let line = aStreamReader.nextLine() {
                    let dataz = line.dataUsingEncoding(NSUTF8StringEncoding)
                    println (line)

Then send the data to another device using:

self.appDelegate.mpcDelegate.session.sendData(data: NSData!, toPeers: [AnyObject]!, withMode: MCSessionSendDataMode, error: NSErrorPointer )

I convert line to NSData, then using a dispatch_after 0.5 seconds running constantly, I send it to another device via bluetooth.

It does not seem to work and I don't think this is a practical way of doing it. I have done numerous searches and haven't seen much on streaming data via bluetooth. The key word streaming (understandably) sends me to pages about server streaming.

My question is, how can I take audio from a microphone and send it to another iPhone via bluetooth? I have the bluetooth part all set up and it works great. My question is very similar to THIS except with iPhones and Swift - I want to have a phone call via bluetooth.

Thank you in advance.

Community
  • 1
  • 1
iSkore
  • 7,394
  • 3
  • 34
  • 59
  • Which part isn't working? The audio capture or the data transmission? Break your problem into capture, transmission, and then conversion back to audio. I did some searching and found there are (complicated) ways of capturing streaming audio into NSData. Buffer the data and then stream it to your peers with MCSession startStreamWithName. Assuming that you want minimal latency so don't bother writing to a file and reading it back out. – Dan Loughney Jun 16 '15 at 17:17
  • 1
    Ok, so MCSession, I will give that a shot now. Yes, my issue is with the transmission. Got the recording going, got the transmission part, but the transmission doesn't send till after the full phrase is recorded. So you hold the button, talk, it records, then on button release, transmits. – iSkore Jun 18 '15 at 14:00
  • Still not working. Can you give an example of a buffer in this situation? – iSkore Jun 21 '15 at 12:49
  • Did you ever get this working? I would love to speak with you about it, as I'm working on something very similar. – Logan Jul 11 '16 at 16:10
  • @iSkore have u did the app . is it working? – Ramkumar chintala Jul 27 '16 at 07:00
  • Hi, do you have a working sample code of this feature? – Ulysses Feb 23 '17 at 11:17
  • @iSkore could you please provide the git URL of sample code? – Saurabh Jain Sep 21 '17 at 10:36

1 Answers1

9

To simultaneously record and redirect output you need to use the category AVAudioSessionCategoryMultiRoute.

Here's the link to the categories list: https://developer.apple.com/library/ios/documentation/AVFoundation/Reference/AVAudioSession_ClassReference/#//apple_ref/doc/constant_group/Audio_Session_Categories

If all else fails you can use a pre-made solution: http://audiob.us

It has an API that lets you integrate audio streaming from one app to another: https://developer.audiob.us/

It supports multiple output endpoints.

Hope this helps.

Capstone
  • 2,254
  • 2
  • 20
  • 39