let user play ipod music in background with soundengine

Apprentice
Posts: 6
Joined: 2008.11
Post: #1
Hey Guys,

Just wondering how I can let the user listen to their currently playing ipod music in the background, using the soundengine API (from crash landing)? At the moment when my app starts up the currently playing track stops, even if I dont set a background track in soundengine. I still would like to have the sound effects play in either case though.

Do I need to detect if the ipod is playing, or do I have to set something up (or not set something up) when I init the soundengine?

Cheers!
Quote this message in a reply
Moderator
Posts: 3,570
Joined: 2003.06
Post: #2
This is a major pain in the butt IMHO, but here's how I do it (if I recall correctly). When my app launches I check to see if other audio is playing. Must make sure that OpenAL is not active yet though. Either don't init OpenAL yet, or call alcMakeContextCurrent(nil) Then, I do this:

Code:
BOOL            gOtherAudioIsPlaying = YES;

void CheckIfOtherAudioIsPlaying(void)
{
    UInt32        propertySize, audioIsAlreadyPlaying;
    
    // do not open the track if the audio hardware is already in use (could be the iPod app playing music)
    propertySize = sizeof(UInt32);
    AudioSessionGetProperty(kAudioSessionProperty_OtherAudioIsPlaying, &propertySize, &audioIsAlreadyPlaying);
    if (audioIsAlreadyPlaying != 0)
    {
        gOtherAudioIsPlaying = YES;
        //NSLog(@"other audio is playing");
        
        UInt32    sessionCategory = kAudioSessionCategory_AmbientSound;
        AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(sessionCategory), &sessionCategory);
        AudioSessionSetActive(YES);
    }
    else
    {
        //NSLog(@"no other audio is playing ...");
        
        gOtherAudioIsPlaying = NO;
        
        // since no other audio is *supposedly* playing, then we will make darn sure by changing the audio session category temporarily
        // to kick any system remnants out of hardware (iTunes (or the iPod App, or whatever you wanna call it) sticks around)
        UInt32    sessionCategory = kAudioSessionCategory_MediaPlayback;
        AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(sessionCategory), &sessionCategory);
        AudioSessionSetActive(YES);
        
        // now change back to ambient session category so our app honors the "silent switch"
        sessionCategory = kAudioSessionCategory_SoloAmbientSound;
        AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(sessionCategory), &sessionCategory);
    }
}

If gOtherAudioIsPlaying is set when I would normally start playing a background music track with Audio Queues, I cancel that and let the system music continue. But either way, after the check you can either continue to init OpenAL for the sound effects or activate it again with alcMakeContextCurrent(context)

I *think* this is all I do at app launch.

But there is another sinister issue which Apple really needs to address, but you can work around: If the user double-clicks on the home button and starts playing music while you are playing background music, the iPhone tries to pipe your music and the iPod music through the same hardware. This can freeze the device! At the very least it will make things run very poorly. So this is essentially what I do:

Code:
[[NSNotificationCenter defaultCenter] addObserver:self
        selector:@selector(applicationWillResignActive:)
        name:@"UIApplicationWillResignActiveNotification"
        object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
        selector:@selector(applicationDidBecomeActive:)
        name:@"UIApplicationDidBecomeActiveNotification"
        object:nil];
                                              
- (void)applicationWillResignActive:(NSNotification *)notification
{
    [backgroundMusic stop];
    alcMakeContextCurrent(nil)
    AudioSessionSetActive(NO);
}

- (void)applicationDidBecomeActive:(NSNotification *)notification
{
    // the user might have double-clicked home and started playing music, so do the same as at app launch
    CheckIfOtherAudioIsPlaying();
    
    if (!gOtherAudioIsPlaying)
        [backgroundMusic play];
    
     alcMakeContextCurrent(context)
}
Quote this message in a reply
Apprentice
Posts: 6
Joined: 2008.11
Post: #3
Hey, thanks alot.

What do you mean by honoring the "silent switch" though?

Thanks
Quote this message in a reply
Moderator
Posts: 3,570
Joined: 2003.06
Post: #4
The silent switch is a button on the side of an iPhone to make it so it doesn't ring, or supposedly make any noise when the user wants it to be off. I didn't know about it either because I develop on an iPod Touch, but it's there on the phones and users apparently get ticked if your app doesn't work with it. OpenAL and Audio Queues in third party apps don't automatically obey that switch, and a user could launch your game in a meeting and get in trouble. Almost all of us believe this is a flaw on Apple's part, but until they fix it, we have been trying to work around it by setting our audio session category to ambient.
Quote this message in a reply
Moderator
Posts: 3,570
Joined: 2003.06
Post: #5
Oh yeah, and setting the session category to ambient has the side-effect of letting your OpenAL sound effects play along with the iPod's music. Forgot to mention that little detail. Wink
Quote this message in a reply
Apprentice
Posts: 17
Joined: 2008.10
Post: #6
I'm having a hard time getting the posted code to work. I'm also using the SoundEngine API that is in the CrashLanding example.

In the function CheckOtherAudioPlaying, the value of audioIsAlreadyPlaying is always != 0 regardless of music playing or not.

When I do have audio playing, the audio invariably is turned off when this runs
Code:
            alcMakeContextCurrent(mContext);
                AssertNoOALError("Error setting current OpenAL context", end)

Any help?
Quote this message in a reply
Moderator
Posts: 3,570
Joined: 2003.06
Post: #7
Are you certain that your OpenAL context is not active before you do the check for other audio playing? At app launch, I check before I init OpenAL at all.

By the way, this is a hackish workaround, so I can't guarantee that it actually works.

Strange that your audio stops after you call alcMakeContextCurrent(mContext); Are you sure mContext is valid?
Quote this message in a reply
Moderator
Posts: 3,570
Joined: 2003.06
Post: #8
sumiguchi Wrote:In the function CheckOtherAudioPlaying, the value of audioIsAlreadyPlaying is always != 0 regardless of music playing or not.

Sorry to bump this thread at such a later date but it has recently come to my attention that it is important to mention that the audio session must already have been initialized and that it isn't active when this function is called. I assumed that others would already know this, but I should have mentioned it previously, because that could be causing an incorrect reading from AudioSessionGetProperty.
Quote this message in a reply
Apprentice
Posts: 9
Joined: 2009.02
Post: #9
I was having this same issue. Turns out it was because I was not initializing the audio session until after I was checking for other audio playing. So I simply added this line:

AudioSessionInitialize(NULL,NULL,NULL,NULL);

before:

AudioSessionGetProperty(kAudioSessionProperty_OtherAudioIsPlaying, &propertySize, &audioIsAlreadyPlaying);

and removed the AudioSessionInitialize where I was doing it later in my code.

Hope that helps!

-Keith
Quote this message in a reply
Member
Posts: 36
Joined: 2009.02
Post: #10
Just wanted to thank AnotherJake for his code. I've put it in my code and it works great!
Quote this message in a reply
Moderator
Posts: 3,570
Joined: 2003.06
Post: #11
Glad to help Smile
Quote this message in a reply
Apprentice
Posts: 17
Joined: 2008.10
Post: #12
Yes - thank you AnotherJake! I left this after I posted and when I came back I saw your post about initializing Blush everything worked fine!
Quote this message in a reply
Moderator
Posts: 3,570
Joined: 2003.06
Post: #13
I'm glad to hear that you finally got it working because I was really stumped on that one! Smile

On a side-note, I've stumbled across other code snippets on the internet using my code for this. It's kind of funny, but I'm glad to see it has helped others too! (I know it was this code because they left some of the comments in Wink )
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  iTunes Connect Test User acting like real user jonhud 1 4,135 Apr 3, 2012 12:58 AM
Last Post: sefiroths
  What format to use for streaming background music on the iphone? AdrianM 4 4,134 Aug 7, 2009 11:29 AM
Last Post: bware218
  SoundEngine.cpp SetEffectPosition() mlady 1 1,841 May 4, 2009 09:06 AM
Last Post: Ingemar