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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With