mirror of https://github.com/axmolengine/axmol.git
fixed #17395: OpenAL A003 error if doing AL invocation before alcMakeContextCurrent(s_ALContext); (#17492)
Pause director if Audio Session is still in interrupted state, resume director in interrupted ended.
This commit is contained in:
parent
769f7830f0
commit
b842202541
|
@ -81,6 +81,7 @@ void AudioEngineInterruptionListenerCallback(void* user_data, UInt32 interruptio
|
|||
if ([[[UIDevice currentDevice] systemVersion] intValue] > 5) {
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleInterruption:) name:AVAudioSessionInterruptionNotification object:[AVAudioSession sharedInstance]];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleInterruption:) name:UIApplicationDidBecomeActiveNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleInterruption:) name:UIApplicationWillResignActiveNotification object:nil];
|
||||
}
|
||||
// only enable it on iOS. Disable it on tvOS
|
||||
// AudioSessionInitialize removed from tvOS
|
||||
|
@ -95,31 +96,71 @@ void AudioEngineInterruptionListenerCallback(void* user_data, UInt32 interruptio
|
|||
|
||||
-(void)handleInterruption:(NSNotification*)notification
|
||||
{
|
||||
static bool isAudioSessionInterrupted = false;
|
||||
static bool resumeOnBecomingActive = false;
|
||||
static bool pauseOnResignActive = false;
|
||||
|
||||
if ([notification.name isEqualToString:AVAudioSessionInterruptionNotification]) {
|
||||
if ([notification.name isEqualToString:AVAudioSessionInterruptionNotification])
|
||||
{
|
||||
NSInteger reason = [[[notification userInfo] objectForKey:AVAudioSessionInterruptionTypeKey] integerValue];
|
||||
if (reason == AVAudioSessionInterruptionTypeBegan) {
|
||||
alcMakeContextCurrent(NULL);
|
||||
if (reason == AVAudioSessionInterruptionTypeBegan)
|
||||
{
|
||||
isAudioSessionInterrupted = true;
|
||||
|
||||
if ([UIApplication sharedApplication].applicationState != UIApplicationStateActive)
|
||||
{
|
||||
ALOGD("AVAudioSessionInterruptionTypeBegan, application != UIApplicationStateActive, alcMakeContextCurrent(nullptr)");
|
||||
alcMakeContextCurrent(nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
ALOGD("AVAudioSessionInterruptionTypeBegan, application == UIApplicationStateActive, pauseOnResignActive = true");
|
||||
pauseOnResignActive = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (reason == AVAudioSessionInterruptionTypeEnded) {
|
||||
if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive) {
|
||||
if (reason == AVAudioSessionInterruptionTypeEnded)
|
||||
{
|
||||
isAudioSessionInterrupted = false;
|
||||
|
||||
if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive)
|
||||
{
|
||||
ALOGD("AVAudioSessionInterruptionTypeEnded, application == UIApplicationStateActive, alcMakeContextCurrent(s_ALContext)");
|
||||
NSError *error = nil;
|
||||
[[AVAudioSession sharedInstance] setActive:YES error:&error];
|
||||
alcMakeContextCurrent(s_ALContext);
|
||||
} else {
|
||||
if (Director::getInstance()->isPaused())
|
||||
{
|
||||
ALOGD("AVAudioSessionInterruptionTypeEnded, director was paused, try to resume it.");
|
||||
Director::getInstance()->resume();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ALOGD("AVAudioSessionInterruptionTypeEnded, application != UIApplicationStateActive, resumeOnBecomingActive = true");
|
||||
resumeOnBecomingActive = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ([notification.name isEqualToString:UIApplicationDidBecomeActiveNotification] && resumeOnBecomingActive) {
|
||||
else if ([notification.name isEqualToString:UIApplicationWillResignActiveNotification])
|
||||
{
|
||||
ALOGD("UIApplicationWillResignActiveNotification");
|
||||
if (pauseOnResignActive)
|
||||
{
|
||||
pauseOnResignActive = false;
|
||||
ALOGD("UIApplicationWillResignActiveNotification, alcMakeContextCurrent(nullptr)");
|
||||
alcMakeContextCurrent(nullptr);
|
||||
}
|
||||
}
|
||||
else if ([notification.name isEqualToString:UIApplicationDidBecomeActiveNotification])
|
||||
{
|
||||
ALOGD("UIApplicationDidBecomeActiveNotification");
|
||||
if (resumeOnBecomingActive)
|
||||
{
|
||||
resumeOnBecomingActive = false;
|
||||
ALOGD("UIApplicationDidBecomeActiveNotification, alcMakeContextCurrent(s_ALContext)");
|
||||
NSError *error = nil;
|
||||
BOOL success = [[AVAudioSession sharedInstance]
|
||||
setCategory: AVAudioSessionCategoryAmbient
|
||||
error: &error];
|
||||
BOOL success = [[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryAmbient error: &error];
|
||||
if (!success) {
|
||||
ALOGE("Fail to set audio session.");
|
||||
return;
|
||||
|
@ -127,12 +168,19 @@ void AudioEngineInterruptionListenerCallback(void* user_data, UInt32 interruptio
|
|||
[[AVAudioSession sharedInstance] setActive:YES error:&error];
|
||||
alcMakeContextCurrent(s_ALContext);
|
||||
}
|
||||
else if (isAudioSessionInterrupted)
|
||||
{
|
||||
ALOGD("Audio session is still interrupted, pause director!");
|
||||
Director::getInstance()->pause();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-(void) dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:AVAudioSessionInterruptionNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillResignActiveNotification object:nil];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue