FMODi paigaldamine projekti sisse, fmod project created, assets are imported into FMOD; AudioManager and FMODEvents scripts, VR is set up
This commit is contained in:
128
Assets/Plugins/FMOD/platform_ios.mm
Normal file
128
Assets/Plugins/FMOD/platform_ios.mm
Normal file
@@ -0,0 +1,128 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
|
||||
static void (*gSuspendCallback)(bool suspend) = nullptr;
|
||||
static bool gIsSuspended = false;
|
||||
static bool gNeedsReset = false;
|
||||
|
||||
extern "C" void RegisterSuspendCallback(void (*callback)(bool))
|
||||
{
|
||||
if (gSuspendCallback || !callback)
|
||||
{
|
||||
return;
|
||||
}
|
||||
gSuspendCallback = callback;
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserverForName:AVAudioSessionInterruptionNotification object:nil queue:nil usingBlock:^(NSNotification *notification)
|
||||
{
|
||||
AVAudioSessionInterruptionType type = (AVAudioSessionInterruptionType)[[notification.userInfo valueForKey:AVAudioSessionInterruptionTypeKey] unsignedIntegerValue];
|
||||
if (type == AVAudioSessionInterruptionTypeBegan)
|
||||
{
|
||||
NSLog(@"Interruption Began");
|
||||
// Ignore deprecated warnings regarding AVAudioSessionInterruptionReasonAppWasSuspended and
|
||||
// AVAudioSessionInterruptionWasSuspendedKey, we protect usage for the versions where they are available
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
|
||||
// If the audio session was deactivated while the app was in the background, the app receives the
|
||||
// notification when relaunched. Identify this reason for interruption and ignore it.
|
||||
if (@available(iOS 16.0, tvOS 14.5, *))
|
||||
{
|
||||
// Delayed suspend-in-background notifications no longer exist, this must be a real interruption
|
||||
}
|
||||
#if !TARGET_OS_TV // tvOS never supported "AVAudioSessionInterruptionReasonAppWasSuspended"
|
||||
else if (@available(iOS 14.5, *))
|
||||
{
|
||||
if ([[notification.userInfo valueForKey:AVAudioSessionInterruptionReasonKey] intValue] == AVAudioSessionInterruptionReasonAppWasSuspended)
|
||||
{
|
||||
return; // Ignore delayed suspend-in-background notification
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
if ([[notification.userInfo valueForKey:AVAudioSessionInterruptionWasSuspendedKey] boolValue])
|
||||
{
|
||||
return; // Ignore delayed suspend-in-background notification
|
||||
}
|
||||
}
|
||||
|
||||
gSuspendCallback(true);
|
||||
gIsSuspended = true;
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
else if (type == AVAudioSessionInterruptionTypeEnded)
|
||||
{
|
||||
NSLog(@"Interruption Ended");
|
||||
NSError *errorMessage = nullptr;
|
||||
if (![[AVAudioSession sharedInstance] setActive:TRUE error:&errorMessage])
|
||||
{
|
||||
// Interruption like Siri can prevent session activation, wait for did-become-active notification
|
||||
NSLog(@"AVAudioSessionInterruptionNotification: AVAudioSession.setActive() failed: %@", errorMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
gSuspendCallback(false);
|
||||
gIsSuspended = false;
|
||||
}
|
||||
}];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidBecomeActiveNotification object:nil queue:nil usingBlock:^(NSNotification *notification)
|
||||
{
|
||||
// Unity video playback prior to 2022.3 on tvOS breaks FMOD audio, so force a reset
|
||||
#if TARGET_OS_TV && !UNITY_2022_3_OR_NEWER
|
||||
gNeedsReset = true;
|
||||
#endif
|
||||
|
||||
if (gNeedsReset)
|
||||
{
|
||||
gSuspendCallback(true);
|
||||
gIsSuspended = true;
|
||||
}
|
||||
|
||||
NSError *errorMessage = nullptr;
|
||||
if (![[AVAudioSession sharedInstance] setActive:TRUE error:&errorMessage])
|
||||
{
|
||||
if ([errorMessage code] == AVAudioSessionErrorCodeCannotStartPlaying)
|
||||
{
|
||||
// Interruption like Screen Time can prevent session activation, but will not trigger an interruption-ended notification.
|
||||
// There is no other callback or trigger to hook into after this point, we are not in the background and there is no other audio playing.
|
||||
// Our only option is to have a sleep loop until the Audio Session can be activated again.
|
||||
while (![[AVAudioSession sharedInstance] setActive:TRUE error:nil])
|
||||
{
|
||||
usleep(20000);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Interruption like Siri can prevent session activation, wait for interruption-ended notification.
|
||||
NSLog(@"UIApplicationDidBecomeActiveNotification: AVAudioSession.setActive() failed: %@", errorMessage);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// It's possible the system missed sending us an interruption end, so recover here
|
||||
if (gIsSuspended)
|
||||
{
|
||||
gSuspendCallback(false);
|
||||
gNeedsReset = false;
|
||||
gIsSuspended = false;
|
||||
}
|
||||
}];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserverForName:AVAudioSessionMediaServicesWereResetNotification object:nil queue:nil usingBlock:^(NSNotification *notification)
|
||||
{
|
||||
if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground || gIsSuspended)
|
||||
{
|
||||
// Received the reset notification while in the background, need to reset the AudioUnit when we come back to foreground.
|
||||
gNeedsReset = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// In the foregound but something chopped the media services, need to do a reset.
|
||||
gSuspendCallback(true);
|
||||
gSuspendCallback(false);
|
||||
}
|
||||
}];
|
||||
}
|
||||
Reference in New Issue
Block a user