Can't control the Speaker on iPad - ios

I have followed method that takes care about my speaker state:
AudioSession.h
enum {
kAudioSessionOverrideAudioRoute_None = 0,
kAudioSessionOverrideAudioRoute_Speaker = 'spkr'
};
MyClass
#synthesize speakerEnabled;
...
- (void)setSpeakerEnabled:(BOOL)enable {
speakerEnabled = enable;
if(enable) {
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute
, sizeof (audioRouteOverride)
, &audioRouteOverride);
} else {
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_None;
AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute
, sizeof (audioRouteOverride)
, &audioRouteOverride);
}
}
However it works on iPhone only, for iPad - nothing happens.
When I press on button: Speaker On, I enter to if(enable) and AudioSessionSetProperty receives kAudioSessionOverrideAudioRoute_Speaker;
When I press on button: Speaker Off, I enter to else and AudioSessionSetProperty receives kAudioSessionOverrideAudioRoute_None;
I started to debug and din't find difference between to devices.
I have iPad2 iOS 6.1.
Did I miss something?
please, help me
Edit
As LombaX says I added on launch application AVAudioSession category:
NSError *err = nil;
BOOL success = [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&err];
if(!success){
[MyLogger logc:MyLoggerLog format:"%#",[err localizedDescription]];
}
success = YES
Still doesn't work.

I think you misunderstand the use of this property. You are hoping to enable/disable your speaker. That is not quite the intent of kAudioSessionProperty_OverrideAudioRoute. Rather, it affects the output sound routing, in a fairly limited manner.
These are the various possible output routes avaiable to the iPhone
extern const CFStringRef kAudioSessionOutputRoute_LineOut
extern const CFStringRef kAudioSessionOutputRoute_Headphones
extern const CFStringRef kAudioSessionOutputRoute_BluetoothHFP
extern const CFStringRef kAudioSessionOutputRoute_BluetoothA2DP
extern const CFStringRef kAudioSessionOutputRoute_BuiltInReceiver
extern const CFStringRef kAudioSessionOutputRoute_BuiltInSpeaker
extern const CFStringRef kAudioSessionOutputRoute_USBAudio
extern const CFStringRef kAudioSessionOutputRoute_HDMI
extern const CFStringRef kAudioSessionOutputRoute_AirPlay
These are only possible routes - what is actually available is context-dependent. Apple severely restricts your ability to determine these routes in-app as it is something that the user needs to control in a device-consistent manner. Most of them are determined implicitly by the user plugging/unplugging hardware (headphone, USB, HDMI, line out), and Apple doesn't want your app to mess with user expectations here.
Airplay can be selected using MPVolumeView's routeButton if the media context is correct (and airplay is available). Bluetooth can be guided by OverrideCategoryEnableBluetoothInput (which controls both input and output)
IN particular, note that kAudioSessionOutputRoute_BuiltInReceiver is the low-level speaker on the iPhone you hold to your ear when making a phone call. This is the default audio output route for the iPhone if an external device (eg headphones) is not plugged in. kAudioSessionOutputRoute_BuiltInSpeaker is the 'handsfree' louder speaker at the bottom of the phone.
You can reroute from whatever the current default is to this BuiltInSpeaker by setting one of these override properties:
key: kAudioSessionProperty_OverrideAudioRoute
values: kAudioSessionOverrideAudioRoute_Speaker
: kAudioSessionOverrideAudioRoute_None
Specifies whether or not to override the audio session category’s normal audio route.
key: kAudioSessionProperty_OverrideCategoryDefaultToSpeaker
values: TRUE
: FALSE
Specifies whether or not to route audio to the speaker (instead of to the receiver) when no other audio route, such as a headset, is connected.
Both of these are only designed to be used with the kAudioSessionCategory_PlayAndRecord Audio Session category.
Notice that in both cases you are not choosing amongst any output route, you are only overriding the "default route" in favour of the built-in (loud)speaker.
The iPad, lacking a phone, does not have a BuiltInReceiver type of speaker. It's default route, in the absence of connected gadgets or airplay, is that very same BuiltInSpeaker. Therefore, overriding doesn't have any effect.
Assuming you are really trying to mute the audio in your app, how you achieve that depends on many other aspects of your app design. If you want to mute the device, Apple would rather the user controls this via the ring/silent switch. It seems they wouldn't have it any other way:
I've had a response from Apple on this.
They've said they don't and never have provided a method for detecting hardware mute switch and don't intend to do so. https://stackoverflow.com/a/8009073/1375695
"The speaker setting is an overide for the device, not for a given sound"
http://lists.apple.com/archives/coreaudio-api/2009/Mar/msg00300.html

Have you tried to set the audio category before playing?
I remember I had the same problem a while ago, and found this solution (adjust the category)
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
I didn't found anything on the documentation, I think that on iPad you must set the category because iPhone and iPad differs about a detail: on iPhone, the left hardware switch can mute the speaker. On iPad, the same switch is used to lock the rotation.
Try and let me know
EDIT:
useful link:
http://developer.apple.com/library/ios/#documentation/Audio/Conceptual/AudioSessionProgrammingGuide/Cookbook/Cookbook.html

Related

AVAudioSessionManager availableInputs "Unknown selected data source for port iPhone Microphone"

I've noticed this error in my console log for a while. Though it does not affect the execution of my application, I find it really annoying. Thus, I started to trace where this error came from. It turns out when I call availableInputs
NSArray *inputs = [[AVAudioSession sharedInstance] availableInputs];
It will give me the log message:
ERROR: [0x3d61318c] AVAudioSessionPortImpl.mm:50: ValidateRequiredFields: Unknown selected data source for Port iPhone Microphone (type: MicrophoneBuiltIn)
I tried to print out the inputs..
Printing description of inputs:
<__NSArrayI 0x188c4610>(
<AVAudioSessionPortDescription: 0x188c4580, type = MicrophoneBuiltIn; name = iPhone Microphone; UID = Built-In Microphone; selectedDataSource = (null)>,
<AVAudioSessionPortDescription: 0x18835d90, type = BluetoothHFP; name = Valore-BTi22; UID = 00:23:01:10:38:77-tsco; selectedDataSource = (null)>
So selectedDataSource is (null). I don't know what should I do to make it not null? iPhone Microphone is a built-in input... I suppose it's set by Apple already?
This problem seems not just happen to me... I will just share my understanding here..
My situation is.. I'm using pjsip library, which has a lower level control of audio resources. I've noticed that, the sound device has been closed before I call [[AVAudioSession sharedInstance] availableInputs];
Thus, (I guess) AVAudioSession, as a higher level control, couldn't find corresponding audio data source for its input - as the error indicated...
To further investigate the problem, you'd better check somewhere in your code that modify the audio source.. and make sure the audio source is activated before you call AVAudioSession
I can only go this far for now... Deeper understanding and better explanation of audio control is always appreciated!!
Regarding the error in your console, I can also confirm that I sometimes receive this message when using my iPhone 5S, but I've never seen it on my 4S. It could just be some core audio dump, but it doesn't seem to affect actual performance (at least for me).
Regarding the available inputs, what your actually printing out is the available input ports and their descriptions. This bit is more confusing and I don't understand why the selectedDataSource field is null for each one.
I will say that the iPhone is definitely defaulting to one of those sources (probably the Built-in Mic) regardless of what the selectedDataSource is saying.
Now if you wanted to explicitly select one of the port descriptions you could do something like this:
NSArray *availableInputs = [[AVAudioSession sharedInstance] availableInputs];
AVAudioSessionPortDescription *port = [availableInputs objectAtIndex:0]; //built in mic for your case
NSError *portErr = nil;
[[AVAudioSession sharedInstance] setPreferredInput:port error:&portErr];
and I would check portErr afterwards to make sure there's no error in setting the preferredInput.
Its worth noting that you can also cycle through the available dataSources for a particular Port Description as well and select one using
[port setPreferredDataSource:source error:&sourceErr];
then follow that with:
[[AVAudioSession sharedInstance] setPreferredInput:port error:&portErr];
These are some handy iOS7 only features that take advantage of hardware with multiple built-in mice.

Play audio through upper (phone call) speaker

I'm trying to get audio in my app to play through the upper speaker on the iPhone, the one you press to your ear during a phone call. I know it's possible, because I've played a game from the App Store ("The Heist" by "tap tap tap") that simulates phone calls and does exactly that.
I've done a lot of research online, but I'm having a surprisingly hard time finding ANYONE who has even discussed the possibility. The overwhelming majority of posts seem to be about the handsfree speaker vs plugged-in earphones, (like this and this and this), rather than the upper "phone call" speaker vs the handsfree speaker. (Part of that problem might be not having a good name for it: "phone speaker" often means the handsfree speaker at the bottom of the device, etc, so it's hard to do a really well-targeted search). I've looked into Apple's Audio Session Category Route Overrides, but those again seem to (correct me if I'm wrong) deal only with the handsfree speaker at the bottom, not the speaker at the top of the phone.
I have found ONE post that seems to be about this: link. It even provides a bunch of code, so I thought I was home free, but now I can't seem to get the code to work. For simplicity I just copied the DisableSpeakerPhone method (which if I understand it correctly should be the one to re-route audio to the upper speaker) into my viewDidLoad to see if it would work, but the first "assert" line fails, and the audio continues to play out the bottom. (I also imported the AudioToolbox Framework, as suggested in the comment, so that isn't the problem.)
Here is the main block of code I'm working with (this is what I copied into my viewDidLoad to test), although there are a few more methods in the article I linked to:
void DisableSpeakerPhone () {
UInt32 dataSize = sizeof(CFStringRef);
CFStringRef currentRoute = NULL;
OSStatus result = noErr;
AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &dataSize, &currentRoute);
// Set the category to use the speakers and microphone.
UInt32 sessionCategory = kAudioSessionCategory_PlayAndRecord;
result = AudioSessionSetProperty (
kAudioSessionProperty_AudioCategory,
sizeof (sessionCategory),
&sessionCategory
);
assert(result == kAudioSessionNoError);
Float64 sampleRate = 44100.0;
dataSize = sizeof(sampleRate);
result = AudioSessionSetProperty (
kAudioSessionProperty_PreferredHardwareSampleRate,
dataSize,
&sampleRate
);
assert(result == kAudioSessionNoError);
// Default to speakerphone if a headset isn't plugged in.
// Overriding the output audio route
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_None;
dataSize = sizeof(audioRouteOverride);
AudioSessionSetProperty(
kAudioSessionProperty_OverrideAudioRoute,
dataSize,
&audioRouteOverride);
assert(result == kAudioSessionNoError);
AudioSessionSetActive(YES);
}
So my question is this: can anyone either A) help me figure out why that code doesn't work, or B) offer a better suggestion for being able to press a button and route the audio up to the upper speaker?
PS I am getting more and more familiar with iOS programming, but this is my first foray into the world of AudioSessions and such, so details and code samples are much appreciated! Thank you for your help!
UPDATE:
From the suggestion of "He Was" (below) I've removed the code quoted above and replaced it with:
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayAndRecord error:nil];
[[AVAudioSession sharedInstance] setActive: YES error:nil];
at the beginning of viewDidLoad. It still isn't working, though, (by which I mean the audio is still coming out of the speaker at the bottom of the phone instead of the receiver at the top). Apparently the default behavior should be for AVAudioSessionCategoryPlayAndRecord to send audio out of the receiver on its own, so something is still wrong.
More specifically what I'm doing with this code is playing audio through the iPod Music Player (initialized right after the AVAudioSession lines above in viewDidLoad, for what it's worth):
_musicPlayer = [MPMusicPlayerController iPodMusicPlayer];
and the media for that iPod Music Player is chosen through an MPMediaPickerController:
- (void) mediaPicker: (MPMediaPickerController *) mediaPicker didPickMediaItems: (MPMediaItemCollection *) mediaItemCollection {
if (mediaItemCollection) {
[_musicPlayer setQueueWithItemCollection: mediaItemCollection];
[_musicPlayer play];
}
[self dismissViewControllerAnimated:YES completion:nil];
}
This all seems fairly straightforward to me, I've got no errors or warnings, and I know that the Media Picker and Music Player are working correctly because the correct songs start playing, it's just out of the wrong speaker. Could there be a "play media using this AudioSession" method or something? Or is there a way to check what audio session category is currently active, to confirm that nothing could have switched it back or something? Is there a way to emphatically tell the code to USE the receiver, rather than relying on the default to do so? I feel like I'm on the one-yard line, I just need to cross that final bit...
EDIT: I just thought of a theory, wherein it's something about the iPod Music Player that doesn't want to play out of the receiver. My reasoning: it is possible to set a song to start playing through the official iPod app and then seamlessly adjust it (pause, skip, etc) through the app I'm developing. The continuous playback from one app to the next made me think that maybe the iPod Music Player has its own audio route settings, or maybe it doesn't stop to check the settings in the new app? Does anyone who knows what they're talking about think it could it be something like that?
Was struggling with this for a while too. Maybe this would help someone later.You can also use the newer methods of overriding ports. Many of the methods in your sample code are actually deprecated.
So if you have your AudioSession sharedInstance by getting,
NSError *error = nil;
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayAndRecord error:&error];
[session setActive: YES error:nil];
The session category has to be AVAudioSessionCategoryPlayAndRecord
You can get the current output by checking this value.
AVAudioSessionPortDescription *routePort = session.currentRoute.outputs.firstObject;
NSString *portType = routePort.portType;
And now depending on the port you want to send it to, simply toggle the output using
if ([portType isEqualToString:#"Receiver"]) {
[session overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:&error];
} else {
[session overrideOutputAudioPort:AVAudioSessionPortOverrideNone error:&error];
}
This should be a quick way to toggle the outputs to the speaker phone and receiver.
You have to initialise your audio session first.
Using the C API
AudioSessionInitialize (NULL, NULL, NULL, NULL);
In iOS6 you can use AVAudioSession methods instead (you will need to import the AVFoundation framework to use AVAudioSession):
Initialization using AVAudioSession
self.audioSession = [AVAudioSession sharedInstance];
Setting the audioSession category using AVAudioSession
[self.audioSession setCategory:AVAudioSessionCategoryPlayAndRecord
error:nil];
For further research, if you want better search terms, here are the full names of the constants for the speakers:
const CFStringRef kAudioSessionOutputRoute_BuiltInReceiver;
const CFStringRef kAudioSessionOutputRoute_BuiltInSpeaker;
see apple's docs here
But the real mystery is why you are having any trouble routing to the receiver. It's the default behaviour for the playAndRecord category. Apple's documentation of kAudioSessionOverrideAudioRoute_None:
"Specifies, for the kAudioSessionCategory_PlayAndRecord category, that output audio should go to the receiver. This is the default output audio route for this category."
update
In your updated question you reveal that you are using the MPMusicPlayerController class. This class invokes the global music player (the same player used in the Music app). This music player is separate from your app, and so doesn't share the same audio session as your app's audioSession. Any properties you set on your app's audioSession will be ignored by the MPMusicPlayerController.
If you want control over your app's audio behaviour, you need to use an audio framework internal to your app. This would be AVAudioRecorder / AVAudioPlayer or Core Audio (Audio Queues, Audio Units or OpenAL). Whichever method you use, the audio session can be controlled either via AVAudioSession properties or via the Core Audio API. Core Audio gives you more fine-grained control, but with each new release of iOS more of it is ported over to AVFoundation, so start with that.
Also remember that the audio session provides a way for you to describe the intended behaviour of your app's audio in relation to the total iOS environment, but it will not hand you total control. Apple takes care to ensure that the user's expectations of their device's audio behaviour remain consistent between apps, and when one app needs to interrupt another's audio stream.
update 2
In your edit you allude to the possibility of audio sessions checking other app's audio session settings. That does not happen1. The idea is that each app sets it's preferences for it's own audio behaviour using it's self-contained audio session. The operating system arbitrates between conflicting audio requirements when more than one app competes for an unshareable resource, such as the internal microphone or one of the speakers, and will usually decide in favour of that behaviour which is most likely to meet the user's expectations of the device as a whole.
The MPMusicPlayerController class is slightly unusual in that it gives you the ability for one app to have some degree of control over another. In this case, your app is not playing the audio, it is sending a request to the Music Player to play audio on your behalf. Your control is limited by the extent of the MPMusicPlayerController API. For more control, your app will have to provide it's own implementation of audio playback.
In your comment you wonder:
Could there be a way to pull an MPMediaItem from the MPMusicPlayerController and then play them through the app-specific audio session, or anything like that?
That's a (big) subject for a new question. Here is a good starting read (from Chris Adamson's blog) From iPod Library to PCM Samples in Far Fewer Steps Than Were Previously Necessary - it's the sequel to From iphone media library to pcm samples in dozens of confounding and potentially lossy steps - that should give you a sense to the complexity you will face. This may have got easier since iOS6 but I wouldn't be so sure!
1 there is an otherAudioPlaying read-only BOOL property in ios6, but that's about it
Swift 3.0 Code
func provider(_ provider: CXProvider, didActivate audioSession: AVAudioSession) {
let routePort: AVAudioSessionPortDescription? = obsession. current Route. outputs. first
let portType: String? = routePort?.portType
if (portType == "Receiver") {
try? audioSession.overrideOutputAudioPort(.speaker)
}
else {
try? audioSession.overrideOutputAudioPort(.none)
}
swift 5.0
func activateProximitySensor(isOn: Bool) {
let device = UIDevice.current
device.isProximityMonitoringEnabled = isOn
if isOn {
NotificationCenter.default.addObserver(self, selector: #selector(proximityStateDidChange), name: UIDevice.proximityStateDidChangeNotification, object: device)
let session = AVAudioSession.sharedInstance()
do{
try session.setCategory(.playAndRecord)
try session.setActive(true)
try session.overrideOutputAudioPort(AVAudioSession.PortOverride.speaker)
} catch {
print ("\(#file) - \(#function) error: \(error.localizedDescription)")
}
} else {
NotificationCenter.default.removeObserver(self, name: UIDevice.proximityStateDidChangeNotification, object: device)
}
}
#objc func proximityStateDidChange(notification: NSNotification) {
if let device = notification.object as? UIDevice {
print(device)
let session = AVAudioSession.sharedInstance()
do{
let routePort: AVAudioSessionPortDescription? = session.currentRoute.outputs.first
let portType = routePort?.portType
if let type = portType, type.rawValue == "Receiver" {
try session.overrideOutputAudioPort(AVAudioSession.PortOverride.speaker)
} else {
try session.overrideOutputAudioPort(AVAudioSession.PortOverride.none)
}
} catch {
print ("\(#file) - \(#function) error: \(error.localizedDescription)")
}
}
}

iOS: How do I detect if music is playing in any background music app?

I currently have my game correctly handling disabling its own BGM when music is playing in the built-in iPod app, but it does not detect when an app such as Pandora is playing music.
Currently, in my applicationDidBecomeActive method, I check [[MPMusicPlayerController iPodMusicPlayer] playbackState] to determine whether music is playing. What is the equivalent of this to check if an app like Pandora is playing audio in the background?
AudioSessionGetProperty (as mentioned in jake_hetfield's answer) is deprecated as of iOS 7.
Instead, try this one-liner that uses isOtherAudioPlaying:
BOOL isOtherAudioPlaying = [[AVAudioSession sharedInstance] isOtherAudioPlaying];
Works on iOS 6+.
Check out this question
Seems you can see if another audio is playing by checking the property kAudioSessionProperty_OtherAudioIsPlaying like this:
UInt32 propertySize, audioIsAlreadyPlaying=0;
propertySize = sizeof(UInt32);
AudioSessionGetProperty(kAudioSessionProperty_OtherAudioIsPlaying, &propertySize, &audioIsAlreadyPlaying);
A complement to this could be to ask the user if he/she wants to have the game music or the already playing sound/music.
As of iOS 8, the secondaryAudioShouldBeSilencedHint property should be used:
/* Will be true when another application with a non-mixable audio session is playing audio. Applications may use
this property as a hint to silence audio that is secondary to the functionality of the application. For example, a game app
using AVAudioSessionCategoryAmbient may use this property to decide to mute its soundtrack while leaving its sound effects unmuted.
Note: This property is closely related to AVAudioSessionSilenceSecondaryAudioHintNotification.
*/
#property(readonly) BOOL secondaryAudioShouldBeSilencedHint NS_AVAILABLE_IOS(8_0);
You may want to do something like this.....
Create A class to handle your audio settings say... "AudioManager"
Poll the Boolean "isOtherAudioPlaying"... maybe assign it to your own Boolean value.
import Foundation
import AVFoundation
class AudioManager {
static let successBingSoundID: SystemSoundID = <Your System Sound ID in Int>
static func playSystemSoundIfBackgroundSoundIsOff() {
guard !AVAudioSession.sharedInstance().isOtherAudioPlaying else {return}
AudioServicesPlaySystemSoundWithCompletion(successBingSoundID, nil)
}
}
usage:
AudioManager.playSystemSoundIfBackgroundSoundIsOff()

Is it possible to force an AVAudioSession to output to the headphone jack even if an HDMI accessory is connected?

Is it possible to force audio through the headphone jack even if an HDMI adatper is connected?
I see that iOS 5.0 now has constants for multiple Audio Routes:
const CFStringRef kAudioSessionOutputRoute_LineOut;
const CFStringRef kAudioSessionOutputRoute_Headphones;
const CFStringRef kAudioSessionOutputRoute_BluetoothHFP;
const CFStringRef kAudioSessionOutputRoute_BluetoothA2DP;
const CFStringRef kAudioSessionOutputRoute_BuiltInReceiver;
const CFStringRef kAudioSessionOutputRoute_BuiltInSpeaker;
const CFStringRef kAudioSessionOutputRoute_USBAudio;
const CFStringRef kAudioSessionOutputRoute_HDMI;
const CFStringRef kAudioSessionOutputRoute_AirPlay;
I also see that iOS 5.0 supports a new property called kAudioSessionProperty_OutputDestination that is read/write:
kAudioSessionProperty_OutputDestination
A read/write CFNumberRef object that indicates the audio output destination, from a USB audio accessory attached through the iPad camera connection kit, that you want to use.
The value must be one of the identifiers provided as a kAudioSession_OutputDestinationKey_ID key as part of the kAudioSessionProperty_OutputDestinations array.
Available in iOS 5.0 and later.
Questions:
Is the property designed to let me force the output route?
The docs mention a USB audio accessory. Will this work when no accessory is connected, or when a HDMI cable is connected?
Is there any sample code showing how to set this property correctly?
Thanks!

Detect attached audio devices iOS

I'm trying to figure out how to detect which if any audio devices are connected on iphone/ipad/ipod. I know all about the audio route calls and route change callbacks but these don't tell me anything about what's attached. They only report where the audio is currently routing. I need to know, for instance, if headphones and/or bluetooth are still attached while audio is routed through the speakers. Or, for instance, if a user plugs in the headset while using bluetooth then decides to disconnect bluetooth, I need to know that the bluetooth is disconnected even as audio is still routing through headphones.
Unfortunately, as of iOS11, it seems there's no API to reliably get the list of the output devices that are currently attached - as soon as the current route changes, you only see 1 device (currently routed) via AVAudioSession's currentRoute.outputs, even though multiple devices may still be attached.
However, for the input, and that includes Bluetooth devices with HFP profile, if the proper Audio Session mode is used (AVAudioSessionModeVoiceChat or AVAudioSessionModeVideoChat for example), one can get the list of the available input via AVAudioSession's availableInputs, and those inputs are listed there even when that device is not an active route - this is very useful when a user is doing a manual override via MPVolumeView from Bluetooth to the speaker, for example, and since HFP is a 2-way IO (has both input and output), you can judge whether output HFP Bluetooth is still available by looking at the inputs.
BOOL isBtInputAvailable = NO;
NSArray *inputs = [[AVAudioSession sharedInstance] availableInputs];
for (AVAudioSessionPortDescription* port in inputs) {
if ([port.portType isEqualToString:AVAudioSessionPortBluetoothHFP]) {
isBtInputAvailable = YES;
break;
}
}
In case of iOS 5 you should use:
CFStringRef newRoute;
size = sizeof(CFStringRef);
XThrowIfError(AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &size, &newRoute), "couldn't get new audio route");
if (newRoute)
{
CFShow(newRoute);
if (CFStringCompare(newRoute, CFSTR("HeadsetInOut"), NULL) == kCFCompareEqualTo) // headset plugged in
{
colorLevels[0] = .3;
colorLevels[5] = .5;
}
else if (CFStringCompare(newRoute, CFSTR("SpeakerAndMicrophone"), NULL) == kCFCompareEqualTo)
}
You can get from AudioSession properties a list of InputSources and OutputDestinations.
Check out these Session Properties:
kAudioSessionProperty_InputSources
kAudioSessionProperty_OutputDestinations
And to query the details of each, you can use:
kAudioSessionProperty_InputSource
kAudioSessionProperty_OutputDestination

Resources