From 3d6f8effb402ed9eb10d4beee36e5a7afbab745d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Tue, 8 Aug 2023 13:16:56 +0200 Subject: [PATCH] Audio: ability to query various context properties. And test all this, ugh, the test coverage is ABYSMAL here. --- src/Magnum/Audio/Context.cpp | 24 ++++++++++ src/Magnum/Audio/Context.h | 45 ++++++++++++++++-- src/Magnum/Audio/Test/ContextALTest.cpp | 62 +++++++++++++++++++++++-- 3 files changed, 124 insertions(+), 7 deletions(-) diff --git a/src/Magnum/Audio/Context.cpp b/src/Magnum/Audio/Context.cpp index 91e75f120..577271b10 100644 --- a/src/Magnum/Audio/Context.cpp +++ b/src/Magnum/Audio/Context.cpp @@ -340,6 +340,12 @@ std::vector Context::extensionStrings() const { return extensions; } +Int Context::frequency() const { + Int count; + alcGetIntegerv(_device, ALC_FREQUENCY, 1, &count); + return count; +} + bool Context::isHrtfEnabled() const { Int enabled; alcGetIntegerv(_device, ALC_HRTF_SOFT, 1, &enabled); @@ -360,6 +366,24 @@ std::string Context::hrtfSpecifierString() const { return Utility::String::fromArray(alcGetString(_device, ALC_HRTF_SPECIFIER_SOFT)); } +Int Context::monoSourceCount() const { + Int count; + alcGetIntegerv(_device, ALC_MONO_SOURCES, 1, &count); + return count; +} + +Int Context::stereoSourceCount() const { + Int count; + alcGetIntegerv(_device, ALC_STEREO_SOURCES, 1, &count); + return count; +} + +Int Context::refreshRate() const { + Int count; + alcGetIntegerv(_device, ALC_REFRESH, 1, &count); + return count; +} + std::string Context::deviceSpecifierString() const { return alcGetString(_device, ALC_DEVICE_SPECIFIER); } diff --git a/src/Magnum/Audio/Context.h b/src/Magnum/Audio/Context.h index db8882a70..19ad97775 100644 --- a/src/Magnum/Audio/Context.h +++ b/src/Magnum/Audio/Context.h @@ -265,6 +265,14 @@ class MAGNUM_AUDIO_EXPORT Context { */ bool tryCreate(const Configuration& configuration); + /** + * @brief Sampling rate in Hz + * @m_since_latest + * + * @see @ref Configuration::setFrequency() + */ + Int frequency() const; + /** * @brief Whether HRTFs (Head Related Transfer Functions) are enabled * @@ -296,6 +304,30 @@ class MAGNUM_AUDIO_EXPORT Context { */ std::string hrtfSpecifierString() const; + /** + * @brief Count of supported mono sources + * @m_since_latest + * + * @see @ref Configuration::setMonoSourceCount() + */ + Int monoSourceCount() const; + + /** + * @brief Count of supported stereo sources + * @m_since_latest + * + * @see @ref Configuration::setStereoSourceCount() + */ + Int stereoSourceCount() const; + + /** + * @brief Refresh rate in Hz + * @m_since_latest + * + * @see @ref Configuration::setRefreshRate() + */ + Int refreshRate() const; + /** * @brief Device specifier string * @@ -459,7 +491,8 @@ class MAGNUM_AUDIO_EXPORT Context::Configuration { * @return Reference to self (for method chaining) * * If set to @cpp -1 @ce (the default), system OpenAL configuration is - * used. + * used. Use @see @ref Context::frequency() to query the actual used + * sampling rate on a created context. */ Configuration& setFrequency(Int hz) { _frequency = hz; @@ -474,7 +507,9 @@ class MAGNUM_AUDIO_EXPORT Context::Configuration { * @return Reference to self (for method chaining) * * If set to @ref Hrtf::Default (the default), system OpenAL - * configuration is used. + * configuration is used. Use @ref Context::isHrtfEnabled(), + * @ref Context::hrtfStatus() and @ref Context::hrtfSpecifierString() + * to query the actual used HRTF configuration on a created context. * @requires_al_extension Extension @alc_extension{SOFTX,HRTF} or * @alc_extension{SOFT,HRTF}, otherwise the setting will be simply * ignored @@ -492,7 +527,8 @@ class MAGNUM_AUDIO_EXPORT Context::Configuration { * @return Reference to self (for method chaining) * * If set to @cpp -1 @ce (the default), no hint will be given to - * OpenAL. + * OpenAL. Use @see @ref Context::monoSourceCount() to query the actual + * supported mono source count on a created context. */ Configuration& setMonoSourceCount(Int count) { _monoSources = count; @@ -507,7 +543,8 @@ class MAGNUM_AUDIO_EXPORT Context::Configuration { * @return Reference to self (for method chaining) * * If set to @cpp -1 @ce (the default), no hint will be given to - * OpenAL. + * OpenAL. Use @see @ref Context::stereoSourceCount() to query the + * actual supported stereo source count on a created context. */ Configuration& setStereoSourceCount(Int count) { _stereoSources = count; diff --git a/src/Magnum/Audio/Test/ContextALTest.cpp b/src/Magnum/Audio/Test/ContextALTest.cpp index 21771074b..13a752595 100644 --- a/src/Magnum/Audio/Test/ContextALTest.cpp +++ b/src/Magnum/Audio/Test/ContextALTest.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include "Magnum/Audio/Extensions.h" #include "Magnum/Audio/Context.h" @@ -36,7 +37,8 @@ namespace Magnum { namespace Audio { namespace Test { namespace { struct ContextALTest: TestSuite::Tester { explicit ContextALTest(); - void construct(); + void constructDefault(); + void constructConfiguration(); void constructMove(); void quietLog(); @@ -52,7 +54,8 @@ ContextALTest::ContextALTest(): TestSuite::Tester{TestSuite::Tester::TesterConfiguration{} .setSkippedArgumentPrefixes({"magnum"})} { - addTests({&ContextALTest::construct, + addTests({&ContextALTest::constructDefault, + &ContextALTest::constructConfiguration, &ContextALTest::constructMove}); addInstancedTests({&ContextALTest::quietLog}, 2); @@ -64,13 +67,64 @@ ContextALTest::ContextALTest(): &ContextALTest::isExtensionDisabled}); } -void ContextALTest::construct() { +void ContextALTest::constructDefault() { CORRADE_VERIFY(!Context::hasCurrent()); { Context context{arguments().first, arguments().second}; CORRADE_VERIFY(Context::hasCurrent()); CORRADE_COMPARE(&Context::current(), &context); + + /* Verify the queries make sense */ + CORRADE_COMPARE_AS(context.frequency(), 10000, + TestSuite::Compare::Greater); + CORRADE_COMPARE_AS(context.monoSourceCount(), 2, + TestSuite::Compare::GreaterOrEqual); + CORRADE_COMPARE_AS(context.stereoSourceCount(), 1, + TestSuite::Compare::GreaterOrEqual); + CORRADE_COMPARE_AS(context.refreshRate(), 10, + TestSuite::Compare::Greater); + } + + CORRADE_VERIFY(!Context::hasCurrent()); +} + +void ContextALTest::constructConfiguration() { + CORRADE_VERIFY(!Context::hasCurrent()); + + { + Context context{ + Context::Configuration{} + .setFrequency(22050) + .setHrtf(Context::Configuration::Hrtf::Enabled) + .setMonoSourceCount(5) + .setStereoSourceCount(4) + .setRefreshRate(25), + arguments().first, arguments().second + }; + CORRADE_VERIFY(Context::hasCurrent()); + CORRADE_COMPARE(&Context::current(), &context); + + /* Verify the queries make sense. All of these are just hints so the + actual value used could be higher. */ + CORRADE_COMPARE_AS(context.frequency(), 22050, + TestSuite::Compare::GreaterOrEqual); + CORRADE_COMPARE_AS(context.monoSourceCount(), 5, + TestSuite::Compare::GreaterOrEqual); + CORRADE_COMPARE(context.stereoSourceCount(), 4); + CORRADE_COMPARE_AS(context.refreshRate(), 25, + TestSuite::Compare::GreaterOrEqual); + + /* HRTF gets enabled only if the extension is supported */ + if(context.isExtensionSupported()) { + CORRADE_COMPARE(context.hrtfStatus(), Context::HrtfStatus::Enabled); + CORRADE_VERIFY(!context.hrtfSpecifierString().empty()); + } else if(context.isExtensionSupported()) { + CORRADE_COMPARE(context.hrtfStatus(), Context::HrtfStatus::Enabled); + CORRADE_VERIFY(context.hrtfSpecifierString().empty()); + } else { + CORRADE_COMPARE(context.hrtfStatus(), Context::HrtfStatus::Disabled); + } } CORRADE_VERIFY(!Context::hasCurrent()); @@ -79,10 +133,12 @@ void ContextALTest::construct() { void ContextALTest::constructMove() { Context context; CORRADE_COMPARE(&Context::current(), &context); + Int frequency = context.frequency(); { Context second{std::move(context)}; CORRADE_COMPARE(&Context::current(), &second); + CORRADE_COMPARE(second.frequency(), frequency); } CORRADE_VERIFY(!Context::hasCurrent());