PlaySystemSound with mute switch on
Asked Answered
P

5

10

I know, I have to set the AudioSession to the 'playback' category, which allows audio even when the mute switch is on. This is what I do, but sound still gets muted when switch is on.

 UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
 AudioSessionSetProperty(kAudioSessionProperty_AudioCategory,sizeof(sessionCategory), &sessionCategory);

 SystemSoundID soundID;
 NSString *path = [[NSBundle mainBundle] pathForResource:soundString ofType:@"wav"];    

 AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath:path],&soundID);
 AudioServicesPlaySystemSound (soundID);


EDIT: by the way, the app is a soundpad. Playing sound is the sole purpose of the app. Here's what Apple Doc says about this:

Use this category for an application whose audio playback is of primary importance. Your audio plays even with the screen locked and with the Ring/Silent switch set to silent.


EDIT 2: with the mute switch on, sound wont even play through the headphones. I know the user is king. I know the mute switch has its purpose. That is not the question. I'm trying to get an answer on the fact that setting the AudioSession category to kAudioSessionCategory_MediaPlayback doesn't have the expected result.


EDIT 3: following Jonathan Watmough's suggestion, I set the AudioServices kAudioServicesPropertyIsUISound property, but still no luck. Am I missing something?

// set the session property
UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
AudioSessionSetProperty(kAudioSessionProperty_AudioCategory,sizeof(sessionCategory), &sessionCategory);

// creates soundID
SystemSoundID soundID;
NSString *path = [[NSBundle mainBundle] pathForResource:soundString ofType:@"wav"];    
AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath:path],&soundID);

// Jonathan Watmough suggestion
UInt32 flag = 0;
AudioServicesSetProperty(kAudioServicesPropertyIsUISound, sizeof(UInt32), &soundID, sizeof(UInt32), &flag);

AudioServicesPlaySystemSound (soundID);
Pretrice answered 17/6, 2010 at 2:18 Comment(5)
Seems downright malicious to play sound when the user has muted their phone. If the system level stuff doesn't do it why should your app. Unless your app is "nuclear reactor meltdown warning" I see NO reason why your app should be allowed to interrupt a meeting, wedding or funeral with noise.Occidental
From the Apple Doc: "Use this category for an application whose audio playback is of primary importance. Your audio plays even with the screen locked and with the Ring/Silent switch set to silent."Pretrice
So what classifies as primary importance to you? I guess at the end of the day they have opened your app as I forgot that your app can't execute actions without them opening it but even still it if they have their phone muted and get no noise that seems desired behaviour.Occidental
I would respect the user's wishes. Sit back a little and think this through, The keypad making noises when I have muted the phone is NOT proper behavior.Cuckoo
There are definitely times when playing sound with the mute switch is perfectly fine, and Sam's case seems to be one of those. If the purpose of action the user is performing is to play a sound or music, it seems perfectly fine to do it whether the silent switch is on or off. This is the behavior of the iPod application.Roscoeroscommon
P
4

Well to add on Jonathan Watmough's answer, indeed it doesn't seem possible to let AudioServicesSystemSound overwrite the mute switch. What I ended up doing is using OpenAL to play the sounds, which will play just fine following the Audio Session category you specify. Here's how I setup the Audio session:

AudioSessionInitialize(NULL, NULL, NULL, NULL);
UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
AudioSessionSetProperty(kAudioSessionProperty_AudioCategory,sizeof(sessionCategory), &sessionCategory);
AudioSessionSetActive(YES);

To play the sounds, I used Finch, a simple OpenAL-based sound effect player for iPhone.

Pretrice answered 26/6, 2010 at 17:23 Comment(1)
Thanks a for your answer. I made a test and you're right, using Finch to use OpenAL enables you to play a sound even if the mute is set using kAudioSessionCategory_MediaPlayback (as stated in the documentation of this constant).Incapacitate
S
1

I haven't tried it yet, but you may want to change the property on your loaded sound:

kAudioServicesPropertyIsUISound A UInt32 value, where 1 means that, for the audio file specified by a system sound passed in the inSpecifier parameter, the System Sound server respects the user setting in the Sound Effects preference and is silent when the user turns off sound effects. This property is set to 1 by default. Set it to 0 for the system sound to always play when passed to AudioServicesPlaySystemSound, regardless of the user's setting in sound preferences. Available in iPhone OS 2.0 and later. Declared in AudioServices.h.

I'd expect that having done everything else right, setting the property to 0 will tell the system that your sound is an app sound, and not a 'UI' sound and hence subject to muting.

EDIT: It looks like it can't be done with system sounds. If you go through OpenAL, you will obviously be able to play with the mute button set.

I built the SysSound sample, and added the following code to set the flag as you did above, and it doesn't play on mute at all.

 // Set the sound to always play
    int setTo0 = 0;
    AudioServicesSetProperty( kAudioServicesPropertyIsUISound,0,nil,
                             4,&setTo0 );
Shamus answered 17/6, 2010 at 15:36 Comment(3)
Thought that was it but nope :( See edit 3 in my original postPretrice
Yea that's what I was thinking. Please emphasize the answer on the fact that it can't be done with SystemSound (suggesting OpenAL) so I can accept your answer. Thanks a lot for helping out!Pretrice
This code is wrong. You need to pass a SystemSoundID as the second and third parameters.Suilmann
A
0

You are calling setActive:error: for the AVAudioSession somewhere right? Here is the code that I use to initialize. But I'm not using system sounds, I'm using AVAudioPlayer to play sounds.

avSession = [AVAudioSession sharedInstance];    // init session, important

// allow other audio to mix, such as iPod
const UInt32 categoryProp = kAudioSessionCategory_MediaPlayback;
AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(categoryProp), &categoryProp);

UInt32 category = kAudioSessionCategory_MediaPlayback;
AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(category), &category);

// Allow our audio to mix with any iPod audio that is playing
AudioSessionSetProperty (kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof(setProperty_YES), &setProperty_YES);

[avSession setActive:YES error:nil];
Ascription answered 18/6, 2010 at 16:58 Comment(0)
B
0

I cannot find it explicitly mentioned in the docs, but I would expect the AudioServicesPlaySystemSound() ignores your audio session configuration.

If you want to control the session mixing and other properties you need to use AVAudioPlayer instead e.g.:

NSError *err;
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayback error:&err];
[session setActive:YES error:&err];

NSString *path = [[NSBundle mainBundle] pathForResource:@"Basso" ofType:@"aiff"];    
AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:&err];
[player prepareToPlay];
[player play];
Brazier answered 24/6, 2010 at 5:17 Comment(2)
I'm playing super short sounds that shouldn't be played with AVAudioPlayer. AudioServicesPlaySystemSound or OpenAL are the 2 appropriate sound engines for playing short sounds.Pretrice
Well you cannot use AudioServicesPlaySystemSound as the "system" will be controlling the session mixing options, including muting. I cannot see a way to circumvent that, although it would be pretty handy at times to be able to do so.Brazier
D
0

i am using the below code to solve my issue

AudioSessionInitialize(NULL, NULL, NULL, NULL); UInt32   
sessionCategory = kAudioSessionCategory_MediaPlayback;    
AudioSessionSetProperty(kAudioSessionProperty_AudioCategory,sizeof(sessionCategory),
&sessionCategory); AudioSessionSetActive(YES);
Danie answered 19/8, 2013 at 13:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.