mirror of
https://github.com/love2d/love.git
synced 2026-08-17 19:23:38 +02:00
Properly pause all audio processing in Android when minimized.
This uses ALC_SOFT_pause_device extension which is available since OpenAL-soft 1.16. We guarantee almost 100% availability of this extension since we've been using OpenAL-soft in Android since beginning. Fixes #1828
This commit is contained in:
@@ -195,7 +195,16 @@ Audio::Audio()
|
|||||||
#ifdef LOVE_IOS
|
#ifdef LOVE_IOS
|
||||||
love::ios::initAudioSessionInterruptionHandler();
|
love::ios::initAudioSessionInterruptionHandler();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef LOVE_ANDROID
|
||||||
|
bool hasPauseDeviceExt = alcIsExtensionPresent(device, "ALC_SOFT_pause_device") == ALC_TRUE;
|
||||||
|
alcDevicePauseSOFT = hasPauseDeviceExt
|
||||||
|
? (LPALCDEVICEPAUSESOFT) alcGetProcAddress(device, "alcDevicePauseSOFT")
|
||||||
|
: nullptr;
|
||||||
|
alcDeviceResumeSOFT = hasPauseDeviceExt
|
||||||
|
? (LPALCDEVICERESUMESOFT) alcGetProcAddress(device, "alcDeviceResumeSOFT")
|
||||||
|
: nullptr;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Audio::~Audio()
|
Audio::~Audio()
|
||||||
@@ -305,13 +314,42 @@ std::vector<love::audio::Source*> Audio::pause()
|
|||||||
|
|
||||||
void Audio::pauseContext()
|
void Audio::pauseContext()
|
||||||
{
|
{
|
||||||
|
#ifdef LOVE_ANDROID
|
||||||
|
if (alcDevicePauseSOFT)
|
||||||
|
alcDevicePauseSOFT(device);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// This is extremely rare case since we're using OpenAL-soft
|
||||||
|
// in Android and the ALC_SOFT_pause_device has been supported
|
||||||
|
// since 1.16
|
||||||
|
for (auto &src: pausedSources)
|
||||||
|
src->release();
|
||||||
|
pausedSources = pause();
|
||||||
|
for (auto &src: pausedSources)
|
||||||
|
src->retain();
|
||||||
|
}
|
||||||
|
#else
|
||||||
alcMakeContextCurrent(nullptr);
|
alcMakeContextCurrent(nullptr);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio::resumeContext()
|
void Audio::resumeContext()
|
||||||
{
|
{
|
||||||
|
#ifdef LOVE_ANDROID
|
||||||
|
if (alcDeviceResumeSOFT)
|
||||||
|
alcDeviceResumeSOFT(device);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Again, this is rare case
|
||||||
|
play(pausedSources);
|
||||||
|
for (auto &src: pausedSources)
|
||||||
|
src->release();
|
||||||
|
pausedSources.resize(0);
|
||||||
|
}
|
||||||
|
#else
|
||||||
if (context && alcGetCurrentContext() != context)
|
if (context && alcGetCurrentContext() != context)
|
||||||
alcMakeContextCurrent(context);
|
alcMakeContextCurrent(context);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio::setVolume(float volume)
|
void Audio::setVolume(float volume)
|
||||||
|
|||||||
@@ -176,6 +176,17 @@ private:
|
|||||||
|
|
||||||
DistanceModel distanceModel;
|
DistanceModel distanceModel;
|
||||||
//float metersPerUnit = 1.0;
|
//float metersPerUnit = 1.0;
|
||||||
|
|
||||||
|
#ifdef LOVE_ANDROID
|
||||||
|
# undef ALC_SOFT_pause_device
|
||||||
|
# ifndef ALC_SOFT_pause_device
|
||||||
|
typedef void (ALC_APIENTRY*LPALCDEVICEPAUSESOFT)(ALCdevice *device);
|
||||||
|
typedef void (ALC_APIENTRY*LPALCDEVICERESUMESOFT)(ALCdevice *device);
|
||||||
|
# endif
|
||||||
|
LPALCDEVICEPAUSESOFT alcDevicePauseSOFT;
|
||||||
|
LPALCDEVICERESUMESOFT alcDeviceResumeSOFT;
|
||||||
|
std::vector<love::audio::Source*> pausedSources;
|
||||||
|
#endif
|
||||||
}; // Audio
|
}; // Audio
|
||||||
|
|
||||||
#ifdef ALC_EXT_EFX
|
#ifdef ALC_EXT_EFX
|
||||||
|
|||||||
@@ -627,20 +627,9 @@ Message *Event::convertWindowEvent(const SDL_Event &e)
|
|||||||
if (auto audio = Module::getInstance<audio::Audio>(Module::M_AUDIO))
|
if (auto audio = Module::getInstance<audio::Audio>(Module::M_AUDIO))
|
||||||
{
|
{
|
||||||
if (e.window.event == SDL_WINDOWEVENT_MINIMIZED)
|
if (e.window.event == SDL_WINDOWEVENT_MINIMIZED)
|
||||||
{
|
audio->pauseContext();
|
||||||
for (auto &src : pausedSources)
|
|
||||||
src->release();
|
|
||||||
pausedSources = audio->pause();
|
|
||||||
for (auto &src : pausedSources)
|
|
||||||
src->retain();
|
|
||||||
}
|
|
||||||
else if (e.window.event == SDL_WINDOWEVENT_RESTORED)
|
else if (e.window.event == SDL_WINDOWEVENT_RESTORED)
|
||||||
{
|
audio->resumeContext();
|
||||||
audio->play(pausedSources);
|
|
||||||
for (auto &src : pausedSources)
|
|
||||||
src->release();
|
|
||||||
pausedSources.resize(0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -78,10 +78,6 @@ private:
|
|||||||
static std::map<SDL_Keycode, love::keyboard::Keyboard::Key> createKeyMap();
|
static std::map<SDL_Keycode, love::keyboard::Keyboard::Key> createKeyMap();
|
||||||
static std::map<SDL_Keycode, love::keyboard::Keyboard::Key> keys;
|
static std::map<SDL_Keycode, love::keyboard::Keyboard::Key> keys;
|
||||||
|
|
||||||
#ifdef LOVE_ANDROID
|
|
||||||
std::vector<love::audio::Source*> pausedSources;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}; // Event
|
}; // Event
|
||||||
|
|
||||||
} // sdl
|
} // sdl
|
||||||
|
|||||||
Reference in New Issue
Block a user