-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #10481 from KentuckyCompass/ios-audio-fix
iOS: handle audio session interruptions and improve micro-stutter
- Loading branch information
Showing
6 changed files
with
267 additions
and
153 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -1,21 +1,108 @@ | |||
#import "AppDelegate.h" | #import "AppDelegate.h" | ||
#import "ViewController.h" | #import "ViewController.h" | ||
#import "base/NativeApp.h" | #import "base/NativeApp.h" | ||
#import "Core/System.h" | |||
#import "Core/Config.h" | |||
#import "Common/Log.h" | |||
|
|||
#import <AVFoundation/AVFoundation.h> | |||
|
|
||
@implementation AppDelegate | @implementation AppDelegate | ||
|
|||
// This will be called when the user receives and dismisses a phone call | |||
// or other interruption to the audio session | |||
// Registered in application:didFinishLaunchingWithOptions: | |||
// for AVAudioSessionInterruptionNotification | |||
-(void) handleAudioSessionInterruption:(NSNotification *)notification { | |||
NSNumber *interruptionType = notification.userInfo[AVAudioSessionInterruptionTypeKey]; | |||
|
|||
// Sanity check in case it's somehow not an NSNumber | |||
if (![interruptionType respondsToSelector:@selector(unsignedIntegerValue)]) { | |||
return; // Lets not crash | |||
} | |||
|
|||
switch ([interruptionType unsignedIntegerValue]) { | |||
case AVAudioSessionInterruptionTypeBegan: | |||
INFO_LOG(SYSTEM, "ios audio session interruption beginning"); | |||
if (g_Config.bEnableSound) { | |||
Audio_Shutdown(); | |||
} | |||
break; | |||
|
|||
case AVAudioSessionInterruptionTypeEnded: | |||
INFO_LOG(SYSTEM, "ios audio session interruption ending"); | |||
if (g_Config.bEnableSound) { | |||
/* | |||
* Only try to reinit audio if in the foreground, otherwise | |||
* it may fail. Instead, trust that applicationDidBecomeActive | |||
* will do it later. | |||
*/ | |||
if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive) { | |||
Audio_Init(); | |||
} | |||
} | |||
break; | |||
|
|||
default: | |||
break; | |||
}; | |||
} | |||
|
|||
// This will be called when the iOS's shared media process was reset | |||
// Registered in application:didFinishLaunchingWithOptions: | |||
// for AVAudioSessionMediaServicesWereResetNotification | |||
-(void) handleMediaServicesWereReset:(NSNotification *)notification { | |||
INFO_LOG(SYSTEM, "ios media services were reset - reinitializing audio"); | |||
|
|||
/* | |||
When media services were reset, Apple recommends: | |||
1) Dispose of orphaned audio objects (such as players, recorders, | |||
converters, or audio queues) and create new ones | |||
2) Reset any internal audio states being tracked, including all | |||
properties of AVAudioSession | |||
3) When appropriate, reactivate the AVAudioSession instance using the | |||
setActive:error: method | |||
We accomplish this by shutting down and reinitializing audio | |||
*/ | |||
|
|||
if (g_Config.bEnableSound) { | |||
Audio_Shutdown(); | |||
Audio_Init(); | |||
} | |||
} | |||
|
|||
-(BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { | -(BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { | ||
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; | ||
self.viewController = [[ViewController alloc] init]; | self.viewController = [[ViewController alloc] init]; | ||
|
|||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleAudioSessionInterruption:) name:AVAudioSessionInterruptionNotification object:[AVAudioSession sharedInstance]]; | |||
|
|||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleMediaServicesWereReset:) name:AVAudioSessionMediaServicesWereResetNotification object:nil]; | |||
|
|||
self.window.rootViewController = self.viewController; | self.window.rootViewController = self.viewController; | ||
[self.window makeKeyAndVisible]; | [self.window makeKeyAndVisible]; | ||
|
|||
return YES; | return YES; | ||
} | } | ||
|
|
||
-(void) dealloc { | |||
[[NSNotificationCenter defaultCenter] removeObserver:self]; | |||
} | |||
|
|||
-(void) applicationWillResignActive:(UIApplication *)application { | -(void) applicationWillResignActive:(UIApplication *)application { | ||
if (g_Config.bEnableSound) { | |||
Audio_Shutdown(); | |||
} | |||
|
|||
NativeMessageReceived("lost_focus", ""); | NativeMessageReceived("lost_focus", ""); | ||
} | } | ||
|
|
||
-(void) applicationDidBecomeActive:(UIApplication *)application { | -(void) applicationDidBecomeActive:(UIApplication *)application { | ||
if (g_Config.bEnableSound) { | |||
Audio_Init(); | |||
} | |||
|
|||
NativeMessageReceived("got_focus", ""); | NativeMessageReceived("got_focus", ""); | ||
} | } | ||
@end |
|
||
@end |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.