Browse Source

Add love.audiodisconnected callback.

The callback is fired when the audio has been disconnected.
Miku AuahDark 3 years ago
parent
commit
2cc93af436

+ 1 - 2
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<std::string> &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);

+ 31 - 2
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<event::Event>(Module::M_EVENT);
+		if (eventModule)
+		{
+			ALCint connected;
+			alcGetIntegerv(device, ALC_CONNECTED, 1, &connected);
+
+			if (connected)
+				disconnectNotified = false;
+			else if (!disconnectNotified)
+			{
+				StrongRef<event::Message> msg(new event::Message("audiodisconnected"), Acquire::NORETAIN);
+				eventModule->push(msg);
+				disconnectNotified = true;
+			}
+		}
+	}
+
 	std::vector<Source *> torelease;
 
 	for (const auto &i : playing)

+ 7 - 1
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;
 

+ 5 - 0
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)