Ambient Sound performance on iOS 4.x

Nibbie
Posts: 2
Joined: 2011.01
Post: #1
I'm working towards a new update of my app. As a new feature there will be in-game background music. The oldest HW and SW I'm testing against is a 2nd gen iPod Touch running iOS 3.1.2. On this device it seems to be mandatory to make the audio session use kAudioSessionCategory_SoloAmbientSound. Using kAudioSessionCategory_AmbientSound (even while iPod is not playing) causes a huge performace hit.

Anyway, on iOS 3.x devices, the obvious solution is simply to check during app startup whether the iPod is playing or not, and set the category accordingly.

But what concerns me, is the behaviour on the devices running iOS 4.x on multi-tasking envoronment, where user may suspend the app, start playing iPod music and the resume the app. The main question is that, is it generally ok to use simply kAudioSessionCategory_AmbientSound ALL the way through the life-cycle of the application without getting performance hits similar to 3.x? If that is the case, it would be enough to just to check the iPod playing status each time the app is actived ( at applicationDidBecomeActive() ) and then stop/resume the in-game music accordingly (I'm using AVAudioPlayer). For the devices I have been able to test with, this seems to be the sufficient.

But I am still worried should I take care of resetting the category (kAudioSessionCategory_SoloAmbientSound / kAudioSessionCategory_AmbientSound) accordingly.

Anyone doing category setup everytime the app enters background / resumes?
Quote this message in a reply
Member
Posts: 440
Joined: 2002.09
Post: #2
Typically if you're playing background music you want to use SoloAmbientSound no matter what the hardware or OS. That's the only way to ensure you're getting (fast) hardware decoded audio.

Playing nice with other application's audio on a device that supports multitasking is actually trickier than it should be. Mostly because many apps simply hog the audio hardware and are a bit lazy when they go into the background.

Here's basically what I do in my apps:

Start up (applicationDidFinishLaunching):
Check for background audio. If it's playing, I disable my background music and use an AmbientSound session, if not I use SoloAmbientSound and play my music as appropriate.

applicationWillResignActive:
Here I pause my music if it's active/playing and set the session to AmbientSound to be nice to other apps (in case this is a multitask switch).

applicationDidBecomeActive:
This is the tricky bit. First thing I do here is check if other audio is playing. If it's not playing, I immediately set my session to SoloAmbientSound and start playing my background music as appropriate. If that other audio check finds that another app is playing audio, I start timer that waits a couple seconds then checks for other audio again. If other audio is still playing after that second check I set my session AmbientSound and disable my background music, otherwise I set it to SoloAmbientSound and restore my music as above.

I found that second delayed check is necessary since many apps don't stop playing audio when they go into the background, and the system takes a second or so to fade out their music and relinquish the audio session. So if someone switches from an ill-behaved app to yours, you'll get false positives on the first other-audio check.

You'll notice I don't do anything special audio wise in applicationDidEnterBackground or applicationWillEnterForeground. I found the old Will/DidResignActive events are the best place for this stuff and everything should "just work" on iOS 3, 4, and multitasking vs non-multitasking devices.
Quote this message in a reply
Nibbie
Posts: 2
Joined: 2011.01
Post: #3
(Feb 17, 2011 02:42 PM)Frank C. Wrote:  Here's basically what I do in my apps:
...
applicationWillResignActive:
Here I pause my music if it's active/playing and set the session to AmbientSound to be nice to other apps (in case this is a multitask switch).

applicationDidBecomeActive:
...

Thanks Frank! Awesome summary Smile

As for going into even more details, I would be interested to know if you use something like this while entering background/resuming:

applicationWillResignActive:
AudioSessionSetActive(false);

applicationDidBecomeActive:
AudioSessionSetActive(true);

Or is it acceptable practice to let my AudioSession to be still "active" when it is on background?
Quote this message in a reply
Member
Posts: 440
Joined: 2002.09
Post: #4
The only place I deactivate/reactivate the session is in my AudioSessionInterruptionListener callback. I can't recall if that actually gets called during multitask switches or not, but I haven't had any problems with this setup.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Ambient Music in my app kills performance AdrianM 10 6,865 Dec 8, 2009 10:10 AM
Last Post: wonza