Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it OK to mix AudioServicesPlaySystemSound and AVAudioPlayer?

We have a game that is very close to being released, but we have one extremely annoying problem. One on of our Beta testers phones, he can't hear any of the in game sound effects. He can, however, hear the background music and the title screen music just fine.

The background and title music are both being played via AVAudioPlayer (they are longer, we need looping and volume control, etc). The sound effects are simply being played with AudioServicesPlaySystemSound (they are very short, we don't need precise control or to know when they end, etc). This works on most iPhones, but not on this one. All of this is being played with an audio session of AVAudioSessionCategorySoloAmbient.

So I have two questions: - First, is this an acceptable implementation? i.e. is there something I missed that says you can't mix these two frameworks, or a reason why its a bad idea to mix them? - Second, has anyone seen something like this before? If so, did you find a way around it?

Additional background note: I can pretty conclusively say that on his phone, it is the mixing of the two frameworks. He was able to hear sounds until roughly the same build where we added the title screen music. Also, if I change one of the sounds to work through an AVAudioPlayer, he's able to hear it. Unfortunately, I can't simply move the sounds into AVAudioPlayers because it just doesn't perform well at all, and I need better synchronization.

like image 902
Bdebeez Avatar asked Nov 02 '09 02:11

Bdebeez


2 Answers

EDIT 2:
I've determined the cause of the error. The two different audio frameworks play on two different volume settings. There is the main volume (that's what shows up once you are in the app, and has no title on it) and the ringer volume (that's what shows up when you're on the home screen without any app loaded). The AVAudioPlayer calls play with the main volume setting. As I have set the category to AVAudioSessionCategorySoloAmbient (see code below), this is the volume control that will be adjusted if you use the volume rocker inside the app. The SystemSounds, however, are played at the Ringer Volume. This will NOT come up inside the app, and as such does not allow the user to adjust their settings during the game.

It's easy to see the possible confusion for the user: Let's say they have their ringer set to low, or even off. They start playing the game. They hear the title screen music (AVAudioPlayer) and are able to turn the volume up or down and it responds normally. Then they start the game and the sound effects play (SystemSounds), and they hear nothing because the ringer volume is low/off. In an effort to hear the sound effects, they bump up the volume and the background music responds accordingly. So from this point of view, it definitely looks like the sound effects just aren't playing.

If you have this similar situation, have your user make sure that their ringer volume is up before playing the game and their mute switch is on (i.e. not muted). You can also verify all of this by doing the test yourself - drop your ringer volume and bump your in-app volume up. Your SystemSounds should drop out of the mix.

Original answer: In re-digging through all of the docs, I found the answer. I wasn't properly activating the audio session. Previously I only had this code to set the category:

NSError *setCategoryError = nil; 
BOOL    categoryWasSet    = [[AVAudioSession sharedInstance] 
                              setCategory: AVAudioSessionCategorySoloAmbient 
                              error: &setCategoryError]; 

But I needed to also add the following code to explicitly activate the audio session:

NSError *activationError  = nil;
BOOL    activationSuccess = [[AVAudioSession sharedInstance]
                              setActive: YES 
                              error: &activationError];

I've re-tested with this user, and it has completely fixed the issue. Hope that helps anyone who might have a similar problem.

EDIT: This doesn't seem to have resolved the issue after all. I got a false positive from my tester, and when examined more in detail it seems that he didn't actually hear the SystemSound generated sounds.

like image 150
Bdebeez Avatar answered Sep 19 '22 19:09

Bdebeez


I have two apps on the app store that mix those two frameworks. AVAudioPlayer for sounds that require start and stop and volume control and AudioServices toolbox for short little beeps and clicks. The only think I can think of, off the top of my head, is that the volume of AVAudioPlayer seems to be controlled separately from the AudioServices sounds. So check to make sure that the tester doesn't have sounds turned off (with the vibrate mode switch) or the volume turned way down.

If this doesn't help, tell me more about your sounds/code and I can add some code to my app to see if I can get the same behavior. Of course, sounds like most your testers don't have this problem, and I probably won't see it either.

like image 26
mahboudz Avatar answered Sep 23 '22 19:09

mahboudz