Browse Source

Add love.audio.getOutputDevice(s).

Miku AuahDark 3 years ago
parent
commit
65b898903c

+ 10 - 0
src/modules/audio/Audio.h

@@ -297,6 +297,16 @@ public:
 	virtual void pauseContext() = 0;
 	virtual void pauseContext() = 0;
 	virtual void resumeContext() = 0;
 	virtual void resumeContext() = 0;
 
 
+	/**
+	 * Get current output device name.
+	 */
+	virtual std::string getOutputDevice() = 0;
+
+	/**
+	 * Retrieve list of available output devices.
+	 */
+	virtual void getOutputDevices(std::vector<std::string> &list) = 0;
+
 private:
 private:
 
 
 	static StringMap<DistanceModel, DISTANCE_MAX_ENUM>::Entry distanceModelEntries[];
 	static StringMap<DistanceModel, DISTANCE_MAX_ENUM>::Entry distanceModelEntries[];

+ 9 - 0
src/modules/audio/null/Audio.cpp

@@ -211,6 +211,15 @@ void Audio::resumeContext()
 {
 {
 }
 }
 
 
+std::string Audio::getOutputDevice()
+{
+	return "";
+}
+
+void Audio::getOutputDevices(std::vector<std::string> &/*list*/)
+{
+}
+
 
 
 } // null
 } // null
 } // audio
 } // audio

+ 3 - 0
src/modules/audio/null/Audio.h

@@ -89,6 +89,9 @@ public:
 	void pauseContext();
 	void pauseContext();
 	void resumeContext();
 	void resumeContext();
 
 
+	std::string getOutputDevice();
+	void getOutputDevices(std::vector<std::string> &list);
+
 private:
 private:
 	float volume;
 	float volume;
 	DistanceModel distanceModel;
 	DistanceModel distanceModel;

+ 36 - 0
src/modules/audio/openal/Audio.cpp

@@ -93,6 +93,18 @@ ALenum Audio::getFormat(int bitDepth, int channels)
 	return AL_NONE;
 	return AL_NONE;
 }
 }
 
 
+static const char *getDeviceSpecifier(ALCdevice *device)
+{
+#ifndef ALC_ALL_DEVICES_SPECIFIER
+	constexpr ALCenum ALC_ALL_DEVICES_SPECIFIER = 0x1013;
+#endif
+	static ALCenum deviceEnum = alcIsExtensionPresent(nullptr, "ALC_ENUMERATE_ALL_EXT")
+		? ALC_ALL_DEVICES_SPECIFIER
+		: ALC_DEVICE_SPECIFIER;
+
+	return alcGetString(device, deviceEnum);
+}
+
 Audio::Audio()
 Audio::Audio()
 	: device(nullptr)
 	: device(nullptr)
 	, context(nullptr)
 	, context(nullptr)
@@ -314,6 +326,30 @@ void Audio::resumeContext()
 		alcMakeContextCurrent(context);
 		alcMakeContextCurrent(context);
 }
 }
 
 
+std::string Audio::getOutputDevice()
+{
+	const char *dev = getDeviceSpecifier(device);
+
+	if (dev == nullptr)
+		throw Exception("Failed to get current device: %s", alcGetString(device, alcGetError(device)));
+
+	return dev;
+}
+
+void Audio::getOutputDevices(std::vector<std::string> &list)
+{
+	const char *devices = getDeviceSpecifier(nullptr);
+
+	if (devices == nullptr)
+		throw Exception("Failed to enumerate devices: %s", alcGetString(nullptr, alcGetError(nullptr)));
+
+	for (const char *device = devices; *device; device++)
+	{
+		list.emplace_back(device);
+		device += list.back().length();
+	}
+}
+
 void Audio::setVolume(float volume)
 void Audio::setVolume(float volume)
 {
 {
 	alListenerf(AL_GAIN, volume);
 	alListenerf(AL_GAIN, volume);

+ 3 - 0
src/modules/audio/openal/Audio.h

@@ -127,6 +127,9 @@ public:
 
 
 	bool getEffectID(const char *name, ALuint &id);
 	bool getEffectID(const char *name, ALuint &id);
 
 
+	std::string getOutputDevice();
+	void getOutputDevices(std::vector<std::string> &list);
+
 private:
 private:
 	void initializeEFX();
 	void initializeEFX();
 	// The OpenAL device.
 	// The OpenAL device.

+ 27 - 0
src/modules/audio/wrap_Audio.cpp

@@ -543,6 +543,31 @@ int w_setMixWithSystem(lua_State *L)
 	return 1;
 	return 1;
 }
 }
 
 
+int w_getOutputDevice(lua_State* L)
+{
+	std::string device;
+
+	luax_catchexcept(L, [&]() { device = instance()->getOutputDevice(); });
+	luax_pushstring(L, device);
+	return 1;
+}
+
+int w_getOutputDevices(lua_State* L)
+{
+	std::vector<std::string> list;
+
+	luax_catchexcept(L, [&]() { instance()->getOutputDevices(list); });
+	lua_createtable(L, 0, (int) list.size());
+	for (int i = 0; i < (int) list.size(); i++)
+	{
+		lua_pushnumber(L, i + 1);
+		lua_pushstring(L, list[i].c_str());
+		lua_rawset(L, -3);
+	}
+
+	return 1;
+}
+
 // List of functions to wrap.
 // List of functions to wrap.
 static const luaL_Reg functions[] =
 static const luaL_Reg functions[] =
 {
 {
@@ -574,6 +599,8 @@ static const luaL_Reg functions[] =
 	{ "getMaxSourceEffects", w_getMaxSourceEffects },
 	{ "getMaxSourceEffects", w_getMaxSourceEffects },
 	{ "isEffectsSupported", w_isEffectsSupported },
 	{ "isEffectsSupported", w_isEffectsSupported },
 	{ "setMixWithSystem", w_setMixWithSystem },
 	{ "setMixWithSystem", w_setMixWithSystem },
+	{ "getOutputDevice", w_getOutputDevice },
+	{ "getOutputDevices", w_getOutputDevices },
 
 
 	{ 0, 0 }
 	{ 0, 0 }
 };
 };