14

I'm attempting to output audio to the bluetooth headset (not A2DP) using AVAudioPlayer, AVAudioSession and AudioSessionSetProperty.

There seems to be functions to select the bluetooth headset as input (kAudioSessionProperty_OverrideCategoryEnableBluetoothInput), but no equivalent for setting the output. This is done in the Voicemail app, where you can select the headset, handset speaker or speaker phone. I've tried various combinations of SessionCategories and the AudioSession properties, but I just can't seem to hit on an approach that works.

I'm sure someone has figured this out, care to share an example?

Ethan
  • 486
  • 1
  • 6
  • 15
  • Seems like no one has solved this one (well no one that is talking so far at least!) I've opened an Apple support ticket on this subject and will post a response when I have one. – Ethan Mar 10 '10 at 21:51
  • Yes I did. To paraphrase, "no, you can't do that." I don't think the engineer really understood what I was asking for, because I was able to accomplish it. I'll see if I can post the pertinent parts as an answer. – Ethan Mar 31 '11 at 05:56

2 Answers2

18

This little test worked for me... it involves setting up the bluetooth headset as the input also (not sure if that's what you want). Sorry about the crappy formatting on the code...

// create and set up the audio session
AVAudioSession* audioSession = [AVAudioSession sharedInstance];
[audioSession setDelegate:self];
[audioSession setCategory: AVAudioSessionCategoryPlayAndRecord error: nil];
[audioSession setActive: YES error: nil];

// set up for bluetooth microphone input
UInt32 allowBluetoothInput = 1;
OSStatus stat = AudioSessionSetProperty (
                         kAudioSessionProperty_OverrideCategoryEnableBluetoothInput,
                         sizeof (allowBluetoothInput),
                         &allowBluetoothInput
                        );
NSLog(@"status = %x", stat);    // problem if this is not zero

// check the audio route
UInt32 size = sizeof(CFStringRef);
CFStringRef route;
OSStatus result = AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &size, &route);
NSLog(@"route = %@", route);    
// if bluetooth headset connected, should be "HeadsetBT"
// if not connected, will be "ReceiverAndMicrophone"

// now, play a quick sound we put in the bundle (bomb.wav)
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef        soundFileURLRef;
SystemSoundID   soundFileObject;
soundFileURLRef  = CFBundleCopyResourceURL (mainBundle,CFSTR ("bomb"),CFSTR ("wav"),NULL);
AudioServicesCreateSystemSoundID (soundFileURLRef,&soundFileObject);
AudioServicesPlaySystemSound (soundFileObject);     // should play into headset

Hope that helps!

Matthias
  • 196
  • 2
  • 4
  • This looks like the code I ended up as well, sorry i didn't come here and mark it sooner ;) – Ethan Mar 31 '11 at 06:07
  • "that documentation is wrong. It affects both input and output." from the apple coreaudio mailing list ( http://lists.apple.com/archives/coreaudio-api/2009/Oct/msg00030.html ) – mtoy Sep 15 '11 at 18:28
  • 2
    AudioSessionSetProperty is deprecated since iOS7. How would this look like without using AudioSessionSetProperty ? – Sjoerd Perfors Oct 02 '13 at 10:35
  • Not able to play because of AudioSessionSetProperty. What is the solutions for it ? – Nirmalsinh Rathod Nov 17 '14 at 07:17
  • This code works but when I disconnect bluetooth, the audio comes out through the phone's earpiece and not through the speaker. How can I configure to obtain the output through the Speaker? – KrmX Jul 25 '22 at 09:19
6

I was able to get this working, but it took some doing. I've pieced together the pertinent piece of code here:

[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:&err];

UInt32 allowBluetoothInput = 1;
AudioSessionSetProperty(
    kAudioSessionProperty_OverrideCategoryEnableBluetoothInput,
    sizeof (allowBluetoothInput),
    &allowBluetoothInput);

It is also possible to which sources are available and switch between bluetooth, a headset, handset or the speakerphone but things become very involved at that point. The audio source manager I ultimately wrote was over 700 lines.

Ethan
  • 486
  • 1
  • 6
  • 15
  • 6
    I am very interested in seeing how to switch between the available sources that are available, do you think you could make that code public or add some information to your profile where I can contact you? – Aran Mulholland Nov 28 '11 at 23:04
  • http://stackoverflow.com/questions/20393249/use-audio-unit-i-o-to-create-audio-on-the-fly – madLokesh Dec 11 '13 at 05:57