mirror of
https://github.com/love2d/love.git
synced 2026-08-17 11:00:31 +02:00
Merge branch 'master' into 12.0-development
This commit is contained in:
@@ -78,6 +78,12 @@ bool setAudioMixWithOthers(bool mixEnabled);
|
||||
**/
|
||||
bool hasBackgroundMusic();
|
||||
|
||||
/**
|
||||
* Registers notifications to handle and restore audio interruptions
|
||||
**/
|
||||
void initAudioSessionInterruptionHandler();
|
||||
void destroyAudioSessionInterruptionHandler();
|
||||
|
||||
/**
|
||||
* Gets the area in the window that is safe for UI to render to (not covered by
|
||||
* the status bar, notch, etc.)
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
#import <AudioToolbox/AudioServices.h>
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
|
||||
#include "modules/audio/Audio.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <SDL_events.h>
|
||||
@@ -200,6 +202,56 @@ static int dropFileEventFilter(void *userdata, SDL_Event *event)
|
||||
}
|
||||
}
|
||||
|
||||
@interface LoveAudioInterruptionListener : NSObject
|
||||
@end
|
||||
|
||||
@implementation LoveAudioInterruptionListener
|
||||
|
||||
+ (id) shared
|
||||
{
|
||||
// thread-safe singleton
|
||||
static dispatch_once_t pred = 0;
|
||||
__strong static id _shared = nil;
|
||||
dispatch_once(&pred, ^{
|
||||
_shared = [[self alloc] init];
|
||||
});
|
||||
return _shared;
|
||||
}
|
||||
|
||||
- (void)audioSessionInterruption:(NSNotification *)note
|
||||
{
|
||||
@synchronized (self)
|
||||
{
|
||||
auto audio = love::Module::getInstance<love::audio::Audio>(love::Module::M_AUDIO);
|
||||
if (!audio)
|
||||
{
|
||||
NSLog(@"LoveAudioInterruptionListener could not get love audio module");
|
||||
return;
|
||||
}
|
||||
NSNumber *type = note.userInfo[AVAudioSessionInterruptionTypeKey];
|
||||
if (type.unsignedIntegerValue == AVAudioSessionInterruptionTypeBegan)
|
||||
audio->pauseContext();
|
||||
else
|
||||
audio->resumeContext();
|
||||
}
|
||||
}
|
||||
|
||||
- (void)applicationBecameActive:(NSNotification *)note
|
||||
{
|
||||
@synchronized (self)
|
||||
{
|
||||
auto audio = love::Module::getInstance<love::audio::Audio>(love::Module::M_AUDIO);
|
||||
if (!audio)
|
||||
{
|
||||
NSLog(@"ERROR:could not get love audio module");
|
||||
return;
|
||||
}
|
||||
audio->resumeContext();
|
||||
}
|
||||
}
|
||||
|
||||
@end // LoveAudioInterruptionListener
|
||||
|
||||
namespace love
|
||||
{
|
||||
namespace ios
|
||||
@@ -380,6 +432,38 @@ bool hasBackgroundMusic()
|
||||
}
|
||||
}
|
||||
|
||||
void initAudioSessionInterruptionHandler()
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
AVAudioSession *session = [AVAudioSession sharedInstance];
|
||||
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
|
||||
|
||||
[center addObserver:[LoveAudioInterruptionListener shared]
|
||||
selector:@selector(audioSessionInterruption:)
|
||||
name:AVAudioSessionInterruptionNotification
|
||||
object:session];
|
||||
|
||||
// An interruption end notification is not guaranteed to be sent if
|
||||
// we were previously interrupted... resuming if needed when the app
|
||||
// becomes active seems to be the way to go.
|
||||
[center addObserver:[LoveAudioInterruptionListener shared]
|
||||
selector:@selector(applicationBecameActive:)
|
||||
name:UIApplicationDidBecomeActiveNotification
|
||||
object:nil];
|
||||
|
||||
[center addObserver:[LoveAudioInterruptionListener shared]
|
||||
selector:@selector(applicationBecameActive:)
|
||||
name:UIApplicationWillEnterForegroundNotification
|
||||
object:nil];
|
||||
}
|
||||
}
|
||||
|
||||
void destroyAudioSessionInterruptionHandler()
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:[LoveAudioInterruptionListener shared]];
|
||||
}
|
||||
|
||||
Rect getSafeArea(SDL_Window *window)
|
||||
{
|
||||
@autoreleasepool
|
||||
|
||||
@@ -291,6 +291,12 @@ public:
|
||||
**/
|
||||
static bool setMixWithSystem(bool mix);
|
||||
|
||||
/**
|
||||
* Pause/resume audio context
|
||||
*/
|
||||
virtual void pauseContext() = 0;
|
||||
virtual void resumeContext() = 0;
|
||||
|
||||
private:
|
||||
|
||||
static StringMap<DistanceModel, DISTANCE_MAX_ENUM>::Entry distanceModelEntries[];
|
||||
|
||||
@@ -203,6 +203,15 @@ bool Audio::isEFXsupported() const
|
||||
return false;
|
||||
}
|
||||
|
||||
void Audio::pauseContext()
|
||||
{
|
||||
}
|
||||
|
||||
void Audio::resumeContext()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
} // null
|
||||
} // audio
|
||||
} // love
|
||||
|
||||
@@ -86,6 +86,9 @@ public:
|
||||
int getMaxSourceEffects() const;
|
||||
bool isEFXsupported() const;
|
||||
|
||||
void pauseContext();
|
||||
void resumeContext();
|
||||
|
||||
private:
|
||||
float volume;
|
||||
DistanceModel distanceModel;
|
||||
|
||||
@@ -26,6 +26,10 @@
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
|
||||
#ifdef LOVE_IOS
|
||||
#include "common/ios.h"
|
||||
#endif
|
||||
|
||||
namespace love
|
||||
{
|
||||
namespace audio
|
||||
@@ -189,10 +193,18 @@ Audio::Audio()
|
||||
|
||||
poolThread = new PoolThread(pool);
|
||||
poolThread->start();
|
||||
|
||||
#ifdef LOVE_IOS
|
||||
love::ios::initAudioSessionInterruptionHandler();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
Audio::~Audio()
|
||||
{
|
||||
#ifdef LOVE_IOS
|
||||
love::ios::destroyAudioSessionInterruptionHandler();
|
||||
#endif
|
||||
poolThread->setFinish();
|
||||
poolThread->wait();
|
||||
|
||||
@@ -293,6 +305,17 @@ std::vector<love::audio::Source*> Audio::pause()
|
||||
return Source::pause(pool);
|
||||
}
|
||||
|
||||
void Audio::pauseContext()
|
||||
{
|
||||
alcMakeContextCurrent(nullptr);
|
||||
}
|
||||
|
||||
void Audio::resumeContext()
|
||||
{
|
||||
if (context && alcGetCurrentContext() != context)
|
||||
alcMakeContextCurrent(context);
|
||||
}
|
||||
|
||||
void Audio::setVolume(float volume)
|
||||
{
|
||||
alListenerf(AL_GAIN, volume);
|
||||
|
||||
@@ -95,6 +95,8 @@ public:
|
||||
void pause(love::audio::Source *source);
|
||||
void pause(const std::vector<love::audio::Source*> &sources);
|
||||
std::vector<love::audio::Source*> pause();
|
||||
void pauseContext();
|
||||
void resumeContext();
|
||||
void setVolume(float volume);
|
||||
float getVolume() const;
|
||||
|
||||
|
||||
@@ -499,7 +499,7 @@ love::graphics::StreamBuffer *CreateStreamBuffer(BufferType mode, size_t size)
|
||||
{
|
||||
// AMD's pinned memory seems to be faster than persistent mapping,
|
||||
// on AMD GPUs.
|
||||
if (GLAD_AMD_pinned_memory)
|
||||
if (GLAD_AMD_pinned_memory && gl.getVendor() == OpenGL::VENDOR_AMD)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user