From 238d2db591e228e7a3efdeb3e2361d2bbc86e108 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 25 Sep 2016 13:53:30 +0200 Subject: [PATCH] Audio: implemented ALC_ENUMERATION_EXT. --- doc/openal-support.dox | 2 +- src/Magnum/Audio/Context.cpp | 32 +++++++++++++++++---- src/Magnum/Audio/Context.h | 43 +++++++++++++++++++++++++---- src/Magnum/Audio/magnum-al-info.cpp | 4 +++ 4 files changed, 70 insertions(+), 11 deletions(-) diff --git a/doc/openal-support.dox b/doc/openal-support.dox index ede9afe56..6f9d1b58d 100644 --- a/doc/openal-support.dox +++ b/doc/openal-support.dox @@ -38,7 +38,7 @@ functions and enum values are exposed through the API. Extension | Status ------------------------------------------- | ------ -@alc_extension{ENUMERATION,EXT} | | +@alc_extension{ENUMERATION,EXT} | done @al_extension{EXT,double} | done @al_extension{EXT,float32} | done @al_extension{EXT,ALAW} | done diff --git a/src/Magnum/Audio/Context.cpp b/src/Magnum/Audio/Context.cpp index df7d58779..a1aa20d2d 100644 --- a/src/Magnum/Audio/Context.cpp +++ b/src/Magnum/Audio/Context.cpp @@ -30,6 +30,7 @@ #include #include +#include #include #include @@ -75,6 +76,15 @@ Debug& operator<<(Debug& debug, const Context::HrtfStatus value) { Context* Context::_current = nullptr; +std::vector Context::deviceSpecifierStrings() { + std::vector list; + const char* const devices = alcGetString(nullptr, ALC_DEVICE_SPECIFIER); + for(const char* device = devices; *device; device += std::strlen(device) + 1) + list.push_back(device); + + return list; +} + bool Context::hasCurrent() { return _current; } Context& Context::current() { @@ -87,11 +97,10 @@ Context::Context(): Context{Configuration{}} {} Context::Context(const Configuration& config) { CORRADE_ASSERT(!_current, "Audio::Context: context already created", ); - /* Open default device */ - const ALCchar* const defaultDevice = alcGetString(nullptr, ALC_DEFAULT_DEVICE_SPECIFIER); - _device = alcOpenDevice(defaultDevice); - if(!_device) { - Error() << "Audio::Context: cannot open sound device" << defaultDevice; + /* Open the device */ + const ALCchar* const deviceSpecifier = config.deviceSpecifier().empty() ? alcGetString(nullptr, ALC_DEFAULT_DEVICE_SPECIFIER) : config.deviceSpecifier().data(); + if(!(_device = alcOpenDevice(deviceSpecifier))) { + Error() << "Audio::Context: cannot open sound device" << deviceSpecifier; std::exit(1); } @@ -189,4 +198,17 @@ bool Context::tryCreateContext(const Configuration& config) { return !!_context; } +Context::Configuration::Configuration() = default; +Context::Configuration::~Configuration() = default; + +Context::Configuration& Context::Configuration::setDeviceSpecifier(const std::string& specifier) { + _deviceSpecifier = specifier; + return *this; +} + +Context::Configuration& Context::Configuration::setDeviceSpecifier(std::string&& specifier) { + _deviceSpecifier = std::move(specifier); + return *this; +} + }} diff --git a/src/Magnum/Audio/Context.h b/src/Magnum/Audio/Context.h index 6b45cc4a7..dc68741ed 100644 --- a/src/Magnum/Audio/Context.h +++ b/src/Magnum/Audio/Context.h @@ -83,7 +83,6 @@ class MAGNUM_AUDIO_EXPORT Extension { */ class MAGNUM_AUDIO_EXPORT Context { public: - /** * @brief HRTF status * @@ -127,6 +126,14 @@ class MAGNUM_AUDIO_EXPORT Context { UnsupportedFormat = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT }; + /** + * @brief All device specifier strings + * + * @see @ref deviceSpecifierString(), @ref Configuration::setDeviceSpecifier() + * @fn_al{GetString} with @def_alc{DEVICE_SPECIFIER} + */ + static std::vector deviceSpecifierStrings(); + /** * @brief Whether there is any current context * @@ -202,17 +209,27 @@ class MAGNUM_AUDIO_EXPORT Context { return alcGetString(_device, ALC_HRTF_SPECIFIER_SOFT); } + /** + * @brief Device specifier string + * + * @see @ref deviceSpecifierStrings(), @ref vendorString(), @ref rendererString(), + * @fn_al{GetString} with @def_alc{DEVICE_SPECIFIER} + */ + std::string deviceSpecifierString() const { return alcGetString(_device, ALC_DEVICE_SPECIFIER); } + /** * @brief Vendor string * - * @see @ref rendererString(), @fn_al{GetString} with @def_al{VENDOR} + * @see @ref deviceSpecifierString(), @ref rendererString(), + * @fn_al{GetString} with @def_al{VENDOR} */ std::string vendorString() const { return alGetString(AL_VENDOR); } /** * @brief Renderer string * - * @see @ref vendorString(), @fn_al{GetString} with @def_al{RENDERER} + * @see @ref deviceSpecifierString(), @ref vendorString(), + * @fn_al{GetString} with @def_al{RENDERER} */ std::string rendererString() const { return alGetString(AL_RENDERER); } @@ -314,8 +331,22 @@ class MAGNUM_AUDIO_EXPORT Context::Configuration { Disabled = 2 /**< Disabled */ }; - /** @brief Constructor */ - explicit Configuration() {} + explicit Configuration(); + ~Configuration(); + + /** @brief Device specifier */ + const std::string& deviceSpecifier() const { return _deviceSpecifier; } + + /** + * @brief Set device specifier + * @return Reference to self (for method chaining) + * + * If set to empty string (the default), default device specifier is + * used. + * @see @ref Context::deviceSpecifierStrings() + */ + Configuration& setDeviceSpecifier(const std::string& specifier); + Configuration& setDeviceSpecifier(std::string&& specifier); /**< @overload */ /** @brief Sampling rate in Hz */ Int frequency() const { return _frequency; } @@ -392,6 +423,8 @@ class MAGNUM_AUDIO_EXPORT Context::Configuration { } private: + std::string _deviceSpecifier; + Int _frequency{-1}; Hrtf _hrtf{}; diff --git a/src/Magnum/Audio/magnum-al-info.cpp b/src/Magnum/Audio/magnum-al-info.cpp index 50a3b8f6e..e3c3c41b2 100644 --- a/src/Magnum/Audio/magnum-al-info.cpp +++ b/src/Magnum/Audio/magnum-al-info.cpp @@ -88,6 +88,10 @@ int main(const int argc, const char** const argv) { Debug() << ""; Audio::Context c; + Debug() << "Available devices:"; + for(const auto& device: Audio::Context::deviceSpecifierStrings()) + Debug() << " " << device; + Debug() << "Current device:" << c.deviceSpecifierString(); if(args.isSet("extension-strings")) { Debug() << "Extension strings:" << Debug::newline