summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuslan Mustakov <r.mustakov@gmail.com>2018-05-07 15:44:07 +0700
committerRuslan Mustakov <r.mustakov@gmail.com>2018-05-07 15:48:46 +0700
commit96301e934d7600975922c5f373a488a532d77aad (patch)
tree7a521d7a508e2e872944ef691df45771f1735318
parente15305721da0e4478b62efcda3e79f1c04e7a901 (diff)
Resume audio on iOS after phone call or alarm
When a phone call or an alarm triggers on iOS, the application receives an "audio interruption" and it's up to the application to resume playback when the interruption ends. I added handling for audio interruptions same as if the game is focused out and then back in.
-rw-r--r--drivers/coreaudio/audio_driver_coreaudio.cpp13
-rw-r--r--drivers/coreaudio/audio_driver_coreaudio.h1
-rw-r--r--platform/iphone/app_delegate.h1
-rw-r--r--platform/iphone/app_delegate.mm79
4 files changed, 72 insertions, 22 deletions
diff --git a/drivers/coreaudio/audio_driver_coreaudio.cpp b/drivers/coreaudio/audio_driver_coreaudio.cpp
index c84469f26f..6e451eabcd 100644
--- a/drivers/coreaudio/audio_driver_coreaudio.cpp
+++ b/drivers/coreaudio/audio_driver_coreaudio.cpp
@@ -217,13 +217,24 @@ void AudioDriverCoreAudio::start() {
if (!active) {
OSStatus result = AudioOutputUnitStart(audio_unit);
if (result != noErr) {
- ERR_PRINT("AudioOutputUnitStart failed");
+ ERR_PRINT(("AudioOutputUnitStart failed, code: " + itos(result)).utf8().get_data());
} else {
active = true;
}
}
};
+void AudioDriverCoreAudio::stop() {
+ if (active) {
+ OSStatus result = AudioOutputUnitStop(audio_unit);
+ if (result != noErr) {
+ ERR_PRINT(("AudioOutputUnitStop failed, code: " + itos(result)).utf8().get_data());
+ } else {
+ active = false;
+ }
+ }
+}
+
int AudioDriverCoreAudio::get_mix_rate() const {
return mix_rate;
};
diff --git a/drivers/coreaudio/audio_driver_coreaudio.h b/drivers/coreaudio/audio_driver_coreaudio.h
index 9891920263..c44e225521 100644
--- a/drivers/coreaudio/audio_driver_coreaudio.h
+++ b/drivers/coreaudio/audio_driver_coreaudio.h
@@ -90,6 +90,7 @@ public:
virtual void finish();
bool try_lock();
+ void stop();
AudioDriverCoreAudio();
~AudioDriverCoreAudio();
diff --git a/platform/iphone/app_delegate.h b/platform/iphone/app_delegate.h
index f14864b5b7..c34b5053d6 100644
--- a/platform/iphone/app_delegate.h
+++ b/platform/iphone/app_delegate.h
@@ -37,6 +37,7 @@
@interface AppDelegate : NSObject <UIApplicationDelegate, GLViewDelegate> {
//@property (strong, nonatomic) UIWindow *window;
ViewController *view_controller;
+ bool is_focus_out;
};
@property(strong, nonatomic) UIWindow *window;
diff --git a/platform/iphone/app_delegate.mm b/platform/iphone/app_delegate.mm
index 9e6bbff1d7..7ed1328b20 100644
--- a/platform/iphone/app_delegate.mm
+++ b/platform/iphone/app_delegate.mm
@@ -140,6 +140,42 @@ void _ios_add_joystick(GCController *controller, AppDelegate *delegate) {
};
}
+static void on_focus_out(ViewController *view_controller, bool *is_focus_out) {
+ if (!*is_focus_out) {
+ *is_focus_out = true;
+ if (OS::get_singleton()->get_main_loop())
+ OS::get_singleton()->get_main_loop()->notification(
+ MainLoop::NOTIFICATION_WM_FOCUS_OUT);
+
+ [view_controller.view stopAnimation];
+ if (OS::get_singleton()->native_video_is_playing()) {
+ OSIPhone::get_singleton()->native_video_focus_out();
+ }
+
+ AudioDriverCoreAudio *audio = dynamic_cast<AudioDriverCoreAudio *>(AudioDriverCoreAudio::get_singleton());
+ if (audio)
+ audio->stop();
+ }
+}
+
+static void on_focus_in(ViewController *view_controller, bool *is_focus_out) {
+ if (*is_focus_out) {
+ *is_focus_out = false;
+ if (OS::get_singleton()->get_main_loop())
+ OS::get_singleton()->get_main_loop()->notification(
+ MainLoop::NOTIFICATION_WM_FOCUS_IN);
+
+ [view_controller.view startAnimation];
+ if (OSIPhone::get_singleton()->native_video_is_playing()) {
+ OSIPhone::get_singleton()->native_video_unpause();
+ }
+
+ AudioDriverCoreAudio *audio = dynamic_cast<AudioDriverCoreAudio *>(AudioDriverCoreAudio::get_singleton());
+ if (audio)
+ audio->start();
+ }
+}
+
- (void)controllerWasConnected:(NSNotification *)notification {
// create our dictionary if we don't have one yet
if (ios_joysticks == nil) {
@@ -569,6 +605,8 @@ static int frame_count = 0;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
CGRect rect = [[UIScreen mainScreen] bounds];
+ is_focus_out = false;
+
[application setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
// disable idle timer
// application.idleTimerDisabled = YES;
@@ -628,6 +666,12 @@ static int frame_count = 0;
[self initGameControllers];
+ [[NSNotificationCenter defaultCenter]
+ addObserver:self
+ selector:@selector(onAudioInterruption:)
+ name:AVAudioSessionInterruptionNotification
+ object:[AVAudioSession sharedInstance]];
+
// OSIPhone::screen_width = rect.size.width - rect.origin.x;
// OSIPhone::screen_height = rect.size.height - rect.origin.y;
@@ -639,6 +683,18 @@ static int frame_count = 0;
return TRUE;
};
+- (void)onAudioInterruption:(NSNotification *)notification {
+ if ([notification.name isEqualToString:AVAudioSessionInterruptionNotification]) {
+ if ([[notification.userInfo valueForKey:AVAudioSessionInterruptionTypeKey] isEqualToNumber:[NSNumber numberWithInt:AVAudioSessionInterruptionTypeBegan]]) {
+ NSLog(@"Audio interruption began");
+ on_focus_out(view_controller, &is_focus_out);
+ } else if ([[notification.userInfo valueForKey:AVAudioSessionInterruptionTypeKey] isEqualToNumber:[NSNumber numberWithInt:AVAudioSessionInterruptionTypeEnded]]) {
+ NSLog(@"Audio interruption ended");
+ on_focus_in(view_controller, &is_focus_out);
+ }
+ }
+};
+
- (void)applicationWillTerminate:(UIApplication *)application {
[self deinitGameControllers];
@@ -656,14 +712,7 @@ static int frame_count = 0;
- (void)applicationDidEnterBackground:(UIApplication *)application {
///@TODO maybe add pause motionManager? and where would we unpause it?
- if (OS::get_singleton()->get_main_loop())
- OS::get_singleton()->get_main_loop()->notification(
- MainLoop::NOTIFICATION_WM_FOCUS_OUT);
-
- [view_controller.view stopAnimation];
- if (OS::get_singleton()->native_video_is_playing()) {
- OSIPhone::get_singleton()->native_video_focus_out();
- };
+ on_focus_out(view_controller, &is_focus_out);
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
@@ -678,19 +727,7 @@ static int frame_count = 0;
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
- if (OS::get_singleton()->get_main_loop())
- OS::get_singleton()->get_main_loop()->notification(
- MainLoop::NOTIFICATION_WM_FOCUS_IN);
-
- [view_controller.view
- startAnimation]; // FIXME: resume seems to be recommended elsewhere
- if (OSIPhone::get_singleton()->native_video_is_playing()) {
- OSIPhone::get_singleton()->native_video_unpause();
- };
-
- // Fixed audio can not resume if it is interrupted cause by an incoming phone call
- if (AudioDriverCoreAudio::get_singleton() != NULL)
- AudioDriverCoreAudio::get_singleton()->start();
+ on_focus_in(view_controller, &is_focus_out);
}
- (void)dealloc {