From 12c795b95e06362f82250c49419e980358b2345c Mon Sep 17 00:00:00 2001 From: Squareys Date: Tue, 3 Nov 2015 21:04:55 +0100 Subject: [PATCH] Audio: Improve support for ALC_HRTF_SOFT(X). Add `HrtfStatus` and queries in `Audio::Renderer`, `ALC::SOFT::HRTF` and `@requires_alc_extension` notes for relevant methods in `Configuration`. Signed-off-by: Squareys --- doc/openal-support.dox | 1 + src/Magnum/Audio/Context.cpp | 3 +- src/Magnum/Audio/Context.h | 9 ++++- src/Magnum/Audio/Extensions.h | 3 ++ src/Magnum/Audio/Renderer.cpp | 15 ++++++++ src/Magnum/Audio/Renderer.h | 72 +++++++++++++++++++++++++++++++++++ 6 files changed, 101 insertions(+), 2 deletions(-) diff --git a/doc/openal-support.dox b/doc/openal-support.dox index 01593b21c..57667e26d 100644 --- a/doc/openal-support.dox +++ b/doc/openal-support.dox @@ -47,6 +47,7 @@ Extension | Status Extension | Status ------------------------------------------- | ------ @alc_extension{SOFTX,HRTF} | done +@alc_extension{SOFT,HRTF} | done */ diff --git a/src/Magnum/Audio/Context.cpp b/src/Magnum/Audio/Context.cpp index 4d1965df8..369325560 100644 --- a/src/Magnum/Audio/Context.cpp +++ b/src/Magnum/Audio/Context.cpp @@ -45,7 +45,8 @@ const std::vector& Extension::extensions() { _extension(AL,EXT,FLOAT32), _extension(AL,EXT,DOUBLE), _extension(ALC,EXT,ENUMERATION), - _extension(ALC,SOFTX,HRTF) + _extension(ALC,SOFTX,HRTF), + _extension(ALC,SOFT,HRTF) }; #undef _entension diff --git a/src/Magnum/Audio/Context.h b/src/Magnum/Audio/Context.h index b7f647207..3e4bf9b93 100644 --- a/src/Magnum/Audio/Context.h +++ b/src/Magnum/Audio/Context.h @@ -240,13 +240,20 @@ class MAGNUM_AUDIO_EXPORT Context::Configuration { return *this; } - /** @brief Whether to use hrtfs */ + /** + * @brief Whether to use hrtfs + * @requires_alc_extension for HRTFs, extension @alc_extension{SOFTX,HRTF} + * or @alc_extension{SOFT,HRTF} + */ EnabledState isHrtfEnabled() const { return _enableHrtf; } /** * @brief Set whether to use hrtfs * * Defaults to local OpenAL configuration or false. + * @requires_alc_extension for HRTFs otherwise setting will be ignored, + * extension @alc_extension{SOFTX,HRTF} or + * @alc_extension{SOFT,HRTF} */ Configuration& setHrtfEnabled(EnabledState hrtf) { _enableHrtf = hrtf; diff --git a/src/Magnum/Audio/Extensions.h b/src/Magnum/Audio/Extensions.h index 16f3ed790..e1039dc92 100644 --- a/src/Magnum/Audio/Extensions.h +++ b/src/Magnum/Audio/Extensions.h @@ -87,6 +87,9 @@ namespace AL { namespace SOFTX { _extension(ALC,SOFTX,HRTF) // #??? } + namespace SOFT { + _extension(ALC,SOFT,HRTF) // #??? + } } #undef _extension #undef _extension_rev diff --git a/src/Magnum/Audio/Renderer.cpp b/src/Magnum/Audio/Renderer.cpp index 85214cf5d..25dd54d0a 100644 --- a/src/Magnum/Audio/Renderer.cpp +++ b/src/Magnum/Audio/Renderer.cpp @@ -60,4 +60,19 @@ Debug& operator<<(Debug& debug, const Renderer::DistanceModel value) { return debug << "Audio::Renderer::DistanceModel::(invalid)"; } +Debug& operator<<(Debug& debug, const Renderer::HrtfStatus value) { + switch(value) { + #define _c(value) case Renderer::HrtfStatus::value: return debug << "Audio::Renderer::HrtfStatus::" #value; + _c(Disabled) + _c(Enabled) + _c(Denied) + _c(Required) + _c(Detected) + _c(UnsupportedFormat) + #undef _c + } + + return debug << "Audio::Renderer::HrtfStatus::(invalid)"; +} + }} diff --git a/src/Magnum/Audio/Renderer.h b/src/Magnum/Audio/Renderer.h index bf158c717..df66e43c0 100644 --- a/src/Magnum/Audio/Renderer.h +++ b/src/Magnum/Audio/Renderer.h @@ -32,8 +32,11 @@ #include #include +#include #include "Magnum/Magnum.h" +#include "Magnum/Audio/Context.h" +#include "Magnum/Audio/Extensions.h" #include "Magnum/Audio/visibility.h" #include "Magnum/Math/Vector3.h" @@ -58,6 +61,38 @@ class Renderer { OutOfMemory = AL_OUT_OF_MEMORY /**< Unable to allocate memory */ }; + enum class HrtfStatus: Short { + Disabled = ALC_HRTF_DISABLED_SOFT, /**< HRTF is disabled */ + Enabled = ALC_HRTF_ENABLED_SOFT, /**< HRTF is enabled */ + + /** + * HRTF is disabled because it is not allowed on the device. This + * may be caused by invalid resource permissions, or an other user + * configuration that disallows HRTF. + */ + Denied = ALC_HRTF_DENIED_SOFT, + + /** + * HRTF is enabled because it must be used on the device. This may + * be caused by a device that can only use HRTF, or other user + * configuration that forces HRTF to be used. + */ + Required = ALC_HRTF_REQUIRED_SOFT, + + /** + * HRTF is enabled automatically because the device reported + * headphones. + */ + Detected = ALC_HRTF_HEADPHONES_DETECTED_SOFT, + + /** + * The device does not support HRTF with the current format. + * Typically this is caused by non-stereo output or an incompatible + * output frequency. + */ + UnsupportedFormat = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT + }; + /** @brief Error status */ static Error error() { return Error(alGetError()); } @@ -256,6 +291,40 @@ class Renderer { alDistanceModel(ALenum(model)); } + /** + * @brief Whether HRTFs (Head Related Transfer Functions) are enabled + * + * HRFTs may not be enabled/disabled in a running context. Instead + * create a new context with HRFTs enabled or disabled. + * @see @fn_al{GetIntegerv} with @def_alc{HRTF_SOFT}, + * Audio::Configuration::isHrtfEnabled(), + * Audio::Configuration::setHrtfEnabled() + */ + static bool isHrtfEnabled() { + Int enabled = ALC_FALSE; + alGetIntegerv(ALC_HRTF_SOFT, &enabled); + return enabled == ALC_TRUE; + } + + /** + * @brief HRTF status + * + * @requires_alc_extension for only @ref HrtfStatus::Enabled and + * @ref HrtfStatus::Disabled, extension @alc_extension{SOFTX,HRTF} + * @requires_alc_extension for any @ref HrtfStatus, @alc_extension{SOFT,HRTF} + * @see @fn_al{GetIntegerv} with @def_alc{HRTF_STATUS_SOFT}, + * @ref isHrtfEnabled() + */ + static HrtfStatus hrtfStatus() { + if(!Context::current()->isExtensionSupported()) { + return (isHrtfEnabled()) ? HrtfStatus::Enabled : HrtfStatus::Disabled; + } + + Int status = ALC_HRTF_DISABLED_SOFT; + alGetIntegerv(ALC_HRTF_STATUS_SOFT, &status); + return HrtfStatus(status); + } + /*@}*/ }; @@ -265,6 +334,9 @@ MAGNUM_AUDIO_EXPORT Debug& operator<<(Debug& debug, Renderer::Error value); /** @debugoperatorclassenum{Magnum::Audio::Renderer,Magnum::Audio::Renderer::DistanceModel} */ MAGNUM_AUDIO_EXPORT Debug& operator<<(Debug& debug, Renderer::DistanceModel value); +/** @debugoperatorclassenum{Magnum::Audio::Renderer,Magnum::Audio::Renderer::HrtfStatus} */ +MAGNUM_AUDIO_EXPORT Debug& operator<<(Debug& debug, Renderer::HrtfStatus value); + }} #endif