mirror of
https://github.com/spiffcode/hostile-takeover.git
synced 2026-04-03 03:18:17 -06:00
Restore game audio after OS events (dictation or siri) use audio
- Dictation reliable raises the handleAudioInterrupt notification, so that is used for disabling / enabling audio - Siri sometimes doesn't raise the handleAudioInterrupt notification, so rely on applicationDidBecomeActive / applicationWillResignActive. - Trial and error showed it is best to destroy and re-create the OS audio objects when audio is disabled / enabled.
This commit is contained in:
parent
2a3ef9776d
commit
f2d7002bc3
@ -2165,6 +2165,14 @@ bool Game::FilterEvent(Event *pevt)
|
||||
case mpShowObjectivesEvent:
|
||||
ShowObjectivesAction::OnMPShowObjectivesEvent(pevt->dw);
|
||||
break;
|
||||
|
||||
case disableSoundEvent:
|
||||
gsndm.SaveStateAndClear();
|
||||
break;
|
||||
|
||||
case enableSoundEvent:
|
||||
gsndm.RestoreState();
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -2201,7 +2209,9 @@ void Game::Suspend()
|
||||
// Call host. This is a modal loop. When it returns, the game isn't
|
||||
// paused anymore
|
||||
|
||||
gsndm.SaveStateAndClear();
|
||||
HostSuspendModalLoop(pbmBack);
|
||||
gsndm.RestoreState();
|
||||
|
||||
// Ok, invalidate everything so it all redraws
|
||||
|
||||
|
||||
@ -1789,6 +1789,8 @@ struct Event { // evt
|
||||
#define checkGameOverEvent 0x6011
|
||||
#define connectionCloseEvent 0x6012
|
||||
#define showMessageEvent 0x6013
|
||||
#define enableSoundEvent 0x6014
|
||||
#define disableSoundEvent 0x6015
|
||||
|
||||
// gameOverEvent constants (placed in Event::dw)
|
||||
|
||||
|
||||
@ -156,6 +156,16 @@ bool ProcessMessage(base::Message *pmsg, Event *pevt)
|
||||
pevt->ff = 0;
|
||||
break;
|
||||
|
||||
case kidmDisableSound:
|
||||
pevt->eType = disableSoundEvent;
|
||||
pevt->ff = 0;
|
||||
break;
|
||||
|
||||
case kidmEnableSound:
|
||||
pevt->eType = enableSoundEvent;
|
||||
pevt->ff = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -23,6 +23,8 @@ const int kidmAppSetFocus = 17;
|
||||
const int kidmAppKillFocus = 18;
|
||||
const int kidmAskStringEvent = 19;
|
||||
const int kidmKeyDown = 20;
|
||||
const int kidmEnableSound = 21;
|
||||
const int kidmDisableSound = 22;
|
||||
|
||||
extern base::MessageQueue gmq;
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#import <CoreFoundation/CoreFoundation.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <UIKit/UIWindow.h>
|
||||
#import <UIKit/UIApplication.h>
|
||||
@ -46,6 +47,27 @@ IPhoneAppDelegate *g_appDelegate;
|
||||
{
|
||||
}
|
||||
|
||||
- (void)handleAudioInterruption:(NSNotification *)notification
|
||||
{
|
||||
UInt8 type = [[notification.userInfo valueForKey:AVAudioSessionInterruptionTypeKey] intValue];
|
||||
if (type == AVAudioSessionInterruptionTypeBegan) {
|
||||
if (m_game_thread != NULL) {
|
||||
m_game_thread->Post(kidmDisableSound, NULL);
|
||||
}
|
||||
}
|
||||
if (type == AVAudioSessionInterruptionTypeEnded) {
|
||||
NSError *error = nil;
|
||||
BOOL success = [[AVAudioSession sharedInstance] setActive:YES error:&error];
|
||||
if (success) {
|
||||
if (m_game_thread != NULL) {
|
||||
m_game_thread->Post(kidmEnableSound, NULL);
|
||||
}
|
||||
} else {
|
||||
NSLog(@"AVAudioSession setActive error %@", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)allocPath:(char **)ppsz baseDir:(const char *)baseDir
|
||||
subDir:(const char *)subDir
|
||||
{
|
||||
@ -171,6 +193,12 @@ IPhoneAppDelegate *g_appDelegate;
|
||||
strcpy(m_pszUUID, pszUUID);
|
||||
CFRelease(strUUID);
|
||||
|
||||
// Set up a notification to restore sound when interrupted
|
||||
[[NSNotificationCenter defaultCenter] addObserver: self
|
||||
selector: @selector(handleAudioInterruption:)
|
||||
name: AVAudioSessionInterruptionNotification
|
||||
object: nil];
|
||||
|
||||
// Spin off a thread to run the game
|
||||
m_game_thread = new base::Thread();
|
||||
m_game_thread->Start(wi::IPhone::GameThreadStart, NULL);
|
||||
|
||||
@ -7,25 +7,6 @@
|
||||
#include "criticalsection.h"
|
||||
#include "iphone.h"
|
||||
|
||||
@interface AudioInterruptionHandler : NSObject
|
||||
{
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation AudioInterruptionHandler
|
||||
- (void)handleInterruption:(NSNotification *)notification
|
||||
{
|
||||
UInt8 type = [[notification.userInfo valueForKey:AVAudioSessionInterruptionTypeKey] intValue];
|
||||
if (type == AVAudioSessionInterruptionTypeEnded) {
|
||||
NSError *error = nil;
|
||||
BOOL success = [[AVAudioSession sharedInstance] setActive:YES error:&error];
|
||||
if (!success) {
|
||||
NSLog(@"AVAudioSession setActive error %@", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
@end
|
||||
|
||||
namespace wi {
|
||||
|
||||
#define kcBuffers 4
|
||||
@ -91,9 +72,11 @@ IPhoneSoundDevice::IPhoneSoundDevice()
|
||||
|
||||
IPhoneSoundDevice::~IPhoneSoundDevice()
|
||||
{
|
||||
// This api deletes buffers too
|
||||
if (m_haq != NULL) {
|
||||
AudioQueueDispose(m_haq, true);
|
||||
}
|
||||
SetSoundServiceDevice(NULL);
|
||||
}
|
||||
|
||||
bool IPhoneSoundDevice::Init()
|
||||
@ -118,14 +101,6 @@ bool IPhoneSoundDevice::Init()
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set up callback for turning on audio when an interruption ends
|
||||
AudioInterruptionHandler *handler = [AudioInterruptionHandler alloc];
|
||||
[[NSNotificationCenter defaultCenter] addObserver: handler
|
||||
selector: @selector(handleInterruption:)
|
||||
name: AVAudioSessionInterruptionNotification
|
||||
object: session];
|
||||
[handler release];
|
||||
|
||||
success = [session setActive:YES error:nil];
|
||||
if (!success) {
|
||||
return false;
|
||||
|
||||
@ -122,9 +122,6 @@ bool SoundMgr::IsEnabled()
|
||||
return false;
|
||||
}
|
||||
|
||||
// Our game conflicts with OS audio on some devices like Clie. We try to detect these cases and turn audio
|
||||
// completely off
|
||||
|
||||
void SoundMgr::RestoreState()
|
||||
{
|
||||
if (m_fStateSaved) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user