From 2cc93af436cb83a8962ecb5ff72cf8c1a4a6d3ba Mon Sep 17 00:00:00 2001 From: Miku AuahDark Date: Tue, 3 May 2022 20:39:32 +0800 Subject: [PATCH] Add love.audiodisconnected callback. The callback is fired when the audio has been disconnected. --- src/modules/audio/openal/Audio.cpp | 3 +-- src/modules/audio/openal/Pool.cpp | 33 ++++++++++++++++++++++++++++-- src/modules/audio/openal/Pool.h | 8 +++++++- src/modules/love/callbacks.lua | 5 +++++ 4 files changed, 44 insertions(+), 5 deletions(-) diff --git a/src/modules/audio/openal/Audio.cpp b/src/modules/audio/openal/Audio.cpp index 88c4a4aef..5aff7115d 100644 --- a/src/modules/audio/openal/Audio.cpp +++ b/src/modules/audio/openal/Audio.cpp @@ -179,7 +179,7 @@ Audio::Audio() try { - pool = new Pool(); + pool = new Pool(device); } catch (love::Exception &) { @@ -354,7 +354,6 @@ void Audio::getOutputDevices(std::vector &list) void Audio::setOutputDevice(const char* name) { -#undef ALC_SOFT_reopen_device #ifndef ALC_SOFT_reopen_device typedef ALCboolean (ALC_APIENTRY*LPALCREOPENDEVICESOFT)(ALCdevice *device, const ALCchar *deviceName, const ALCint *attribs); diff --git a/src/modules/audio/openal/Pool.cpp b/src/modules/audio/openal/Pool.cpp index 47020dd9f..1c1df9cc0 100644 --- a/src/modules/audio/openal/Pool.cpp +++ b/src/modules/audio/openal/Pool.cpp @@ -20,6 +20,7 @@ #include "Pool.h" +#include "event/Event.h" #include "Source.h" namespace love @@ -29,8 +30,10 @@ namespace audio namespace openal { -Pool::Pool() - : sources() +Pool::Pool(ALCdevice *device) + : device(device) + , sources() + , disconnectNotified(false) , totalSources(0) { // Clear errors. @@ -101,8 +104,34 @@ bool Pool::isPlaying(Source *s) void Pool::update() { +#ifndef ALC_CONNECTED + constexpr ALCenum ALC_CONNECTED = 0x313; +#endif + thread::Lock lock(mutex); + static bool disconnectExtSupported = alcIsExtensionPresent(device, "ALC_EXT_Disconnect") == ALC_TRUE; + + // Device disconnection event + if (disconnectExtSupported) + { + auto eventModule = Module::getInstance(Module::M_EVENT); + if (eventModule) + { + ALCint connected; + alcGetIntegerv(device, ALC_CONNECTED, 1, &connected); + + if (connected) + disconnectNotified = false; + else if (!disconnectNotified) + { + StrongRef msg(new event::Message("audiodisconnected"), Acquire::NORETAIN); + eventModule->push(msg); + disconnectNotified = true; + } + } + } + std::vector torelease; for (const auto &i : playing) diff --git a/src/modules/audio/openal/Pool.h b/src/modules/audio/openal/Pool.h index c31882c2d..278cfb4e4 100644 --- a/src/modules/audio/openal/Pool.h +++ b/src/modules/audio/openal/Pool.h @@ -64,7 +64,7 @@ class Pool { public: - Pool(); + Pool(ALCdevice *device); ~Pool(); /** @@ -101,9 +101,15 @@ private: // Maximum possible number of OpenAL sources the pool attempts to generate. static const int MAX_SOURCES = 64; + // Current OpenAL device + ALCdevice *device; + // OpenAL sources ALuint sources[MAX_SOURCES]; + // Is device disconnection has been notified? + bool disconnectNotified; + // Total number of created sources in the pool. int totalSources; diff --git a/src/modules/love/callbacks.lua b/src/modules/love/callbacks.lua index 79b1b3e97..a13cc33e8 100644 --- a/src/modules/love/callbacks.lua +++ b/src/modules/love/callbacks.lua @@ -129,6 +129,11 @@ function love.createhandlers() localechanged = function () if love.localechanged then return love.localechanged() end end, + audiodisconnected = function () + if not love.audiodisconnected or not love.audiodisconnected() then + love.audio.setOutputDevice() + end + end, }, { __index = function(self, name) error("Unknown event: " .. name)