kstenerud / ObjectAL-for-iPhone

Mac and iOS Audio development, minus the headache. ObjectAL is the easy Objective-C interface to OpenAL, AVAudioPlayer, and audio session management.
http://kstenerud.github.com/ObjectAL-for-iPhone
885 stars 171 forks source link

allowIpod doesn't work #6

Closed futuretap closed 13 years ago

futuretap commented 13 years ago

I've set allowIpod=YES and useHardwareIfAvailable=NO. I'm using only -[OALSimpleAudio playEffect]. However, I can't start iPod playback (by using the task switcher, not activating the iPad app) while the app is running.

When I start or resume the app while iPod is already playing, it mixes my sound effects as expected. However, when I stop iPod playing, then suspend and resume the app, iPod playing is disabled again.

kstenerud commented 13 years ago

Hmm I'm not able to replicate this.

I've set up a basic app with the following in the app delegate:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{    
    [OALSimpleAudio sharedInstance].allowIpod = YES;
    [OALSimpleAudio sharedInstance].useHardwareIfAvailable = NO;
    [[OALSimpleAudio sharedInstance] playEffect:@"ColdFunk.wav" loop:YES];

    [window addSubview:viewController.view];
    [window makeKeyAndVisible];

    return YES;
}

I tried switching out to springboard and then loading ipod, as well as just task switching between ipod and the app, starting and stopping ipod playback, locking and unlocking the phone, and all seems normal (on a 3GS).

Can you tell me the exact steps to reproduce it?

futuretap commented 13 years ago

Launch the test app, then double click the home button, then scroll to the left and try to tap the play button. It is disabled in my case. The exact same procedure works in other apps or in Springboard.

I tried it with the exact same test app you're describing and I can replicate it.

kstenerud commented 13 years ago

Does it work in any apps that produce sound? Every app in my phone that produces sound has those fast task switcher ipod controls disabled. The only way to enable them, it seems, is if you either use MPMoviePlayerController (at which point those controls will control the movie), or by setting up your app as a background music player (at which point those controls will control YOUR app, not iPod.

http://stackoverflow.com/questions/3196330/iphone-how-to-enable-ipod-controls-in-the-background-to-control-non-ipod-music

futuretap commented 13 years ago

It does work in other apps. Actually, I used to use Apple's AudioFX sample code which uses AudioToolbox. With that solution, it does work without any problem.

kstenerud commented 13 years ago

AudioFX uses system sounds to play sound effects. It's extremely limited but doesn't require an audio session. A newer version of AudioFX is SoundEffect, used in Apple's GLPaint and BubbleLevel apps, both of which work with the mini ipod controls.

However, Apple's Metronome app doesn't work with mini ipod controls because it uses AVAudioPlayer, which sets up an audio session.

futuretap commented 13 years ago

Interestingly, when using AVAudioSessionCategoryPlayback and setting kAudioSessionProperty_OverrideCategoryMixWithOthers, the iPod controls work as expected. Unfortunately, it's not suitable because it doesn't obey the mute and lock switch. I've filed a bug with Apple: http://openradar.appspot.com/radar?id=905401 Please dupe it if you consider this a bug, too.

kstenerud commented 13 years ago

AVAudioSessionCategoryPlayback is a bit strange all in all. First, it doesn't stop playing when the screen locks. It also doesn't pay attention to the silent-switch-which-isn't-really-a-silent-switch. Further, when you choose that mode, starting iPod playback causes the app's sound to stop until you turn off iPod playback, even if you're only using OpenAL.

You can enable that behavior in ObjectAL like so:

[OALSimpleAudio sharedInstance].allowIpod = YES;
[OALSimpleAudio sharedInstance].useHardwareIfAvailable = NO;
[OALSimpleAudio sharedInstance].honorSilentSwitch = NO;

I really don't like Apple's opaque audio session category system. You end up having to choose between sets of functionality, all of which don't quite do what you want. The very presence of kAudioSessionProperty_OverrideCategoryMixWithOthers betrays the inflexibility of such a system.

Edit: It turns out that setting kAudioSessionProperty_OtherMixableAudioShouldDuck resets kAudioSessionProperty_OverrideCategoryMixWithOthers to FALSE. I'll post a fix that reverses the order in which they are called later.

Edit 2: Bleh. Turns out that kAudioSessionProperty_OtherMixableAudioShouldDuck and kAudioSessionProperty_OverrideCategoryMixWithOthers are mutually exclusive, even though the Apple docs make no mention of it. This fix will have to wait till later tonight.

kstenerud commented 13 years ago

I've made some changes to the audio session handling code to be more consistent.

I've added a new demo "AudioSessionDemo" which allows you to play with the session settings in realtime.

That's about the best I can do since any other category setting completely blocks out the mini ipod player.