|
@@ -98,7 +98,7 @@ static const char *getDeviceSpecifier(ALCdevice *device)
|
|
#ifndef ALC_ALL_DEVICES_SPECIFIER
|
|
#ifndef ALC_ALL_DEVICES_SPECIFIER
|
|
constexpr ALCenum ALC_ALL_DEVICES_SPECIFIER = 0x1013;
|
|
constexpr ALCenum ALC_ALL_DEVICES_SPECIFIER = 0x1013;
|
|
#endif
|
|
#endif
|
|
- static ALCenum deviceEnum = alcIsExtensionPresent(nullptr, "ALC_ENUMERATE_ALL_EXT")
|
|
|
|
|
|
+ static ALCenum deviceEnum = alcIsExtensionPresent(nullptr, "ALC_ENUMERATE_ALL_EXT") == ALC_TRUE
|
|
? ALC_ALL_DEVICES_SPECIFIER
|
|
? ALC_ALL_DEVICES_SPECIFIER
|
|
: ALC_DEVICE_SPECIFIER;
|
|
: ALC_DEVICE_SPECIFIER;
|
|
|
|
|
|
@@ -112,6 +112,9 @@ Audio::Audio()
|
|
, poolThread(nullptr)
|
|
, poolThread(nullptr)
|
|
, distanceModel(DISTANCE_INVERSE_CLAMPED)
|
|
, distanceModel(DISTANCE_INVERSE_CLAMPED)
|
|
{
|
|
{
|
|
|
|
+ attribs.push_back(0);
|
|
|
|
+ attribs.push_back(0);
|
|
|
|
+
|
|
// Before opening new device, check if recording
|
|
// Before opening new device, check if recording
|
|
// is requested.
|
|
// is requested.
|
|
if (getRequestRecordingPermission())
|
|
if (getRequestRecordingPermission())
|
|
@@ -134,12 +137,11 @@ Audio::Audio()
|
|
throw love::Exception("Could not open device.");
|
|
throw love::Exception("Could not open device.");
|
|
|
|
|
|
#ifdef ALC_EXT_EFX
|
|
#ifdef ALC_EXT_EFX
|
|
- ALint attribs[4] = { ALC_MAX_AUXILIARY_SENDS, MAX_SOURCE_EFFECTS, 0, 0 };
|
|
|
|
-#else
|
|
|
|
- ALint *attribs = nullptr;
|
|
|
|
|
|
+ attribs.insert(attribs.begin(), ALC_MAX_AUXILIARY_SENDS);
|
|
|
|
+ attribs.insert(attribs.begin() + 1, MAX_SOURCE_EFFECTS);
|
|
#endif
|
|
#endif
|
|
|
|
|
|
- context = alcCreateContext(device, attribs);
|
|
|
|
|
|
+ context = alcCreateContext(device, attribs.data());
|
|
|
|
|
|
if (context == nullptr)
|
|
if (context == nullptr)
|
|
throw love::Exception("Could not create context.");
|
|
throw love::Exception("Could not create context.");
|
|
@@ -350,6 +352,29 @@ 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);
|
|
|
|
+#endif
|
|
|
|
+ static LPALCREOPENDEVICESOFT alcReopenDeviceSOFT = alcIsExtensionPresent(device, "ALC_SOFT_reopen_device") == ALC_TRUE
|
|
|
|
+ ? (LPALCREOPENDEVICESOFT) alcGetProcAddress(device, "alcReopenDeviceSOFT")
|
|
|
|
+ : nullptr;
|
|
|
|
+
|
|
|
|
+ if (alcReopenDeviceSOFT == nullptr)
|
|
|
|
+ {
|
|
|
|
+ // Default implementation throws exception. To make
|
|
|
|
+ // error message consistent, call the base class.
|
|
|
|
+ love::audio::Audio::setOutputDevice(name);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (alcReopenDeviceSOFT(device, (const ALCchar *) name, attribs.data()) == ALC_FALSE)
|
|
|
|
+ throw love::Exception("Cannot set output device: %s", alcGetString(device, alcGetError(device)));
|
|
|
|
+}
|
|
|
|
+
|
|
void Audio::setVolume(float volume)
|
|
void Audio::setVolume(float volume)
|
|
{
|
|
{
|
|
alListenerf(AL_GAIN, volume);
|
|
alListenerf(AL_GAIN, volume);
|