From: <sv...@op...> - 2024-12-18 15:47:18
|
Author: manx Date: Wed Dec 18 16:47:05 2024 New Revision: 22568 URL: https://source.openmpt.org/browse/openmpt/?op=revision&rev=22568 Log: [Ref] mpt/base/saturate_round.hpp: Add full set of _trunc, _round, _ceil, _floor variants. [Ref] mpt/base/saturate_round.hpp: Template on floating point type. Modified: trunk/OpenMPT/soundlib/SampleFormats.cpp trunk/OpenMPT/src/mpt/base/saturate_round.hpp trunk/OpenMPT/src/mpt/base/tests/tests_base_saturate_round.hpp Modified: trunk/OpenMPT/soundlib/SampleFormats.cpp ============================================================================== --- trunk/OpenMPT/soundlib/SampleFormats.cpp Wed Dec 18 16:45:24 2024 (r22567) +++ trunk/OpenMPT/soundlib/SampleFormats.cpp Wed Dec 18 16:47:05 2024 (r22568) @@ -1618,11 +1618,11 @@ return false; } - if(!mpt::in_range<uint32>(mpt::saturate_round<int64>(audioFormat.mSampleRate))) + if(!mpt::in_range<uint32>(mpt::saturate_round<int64>(audioFormat.mSampleRate.get()))) { return false; } - uint32 sampleRate = static_cast<uint32>(mpt::saturate_round<int64>(audioFormat.mSampleRate)); + uint32 sampleRate = static_cast<uint32>(mpt::saturate_round<int64>(audioFormat.mSampleRate.get())); if(sampleRate <= 0) { return false; Modified: trunk/OpenMPT/src/mpt/base/saturate_round.hpp ============================================================================== --- trunk/OpenMPT/src/mpt/base/saturate_round.hpp Wed Dec 18 16:45:24 2024 (r22567) +++ trunk/OpenMPT/src/mpt/base/saturate_round.hpp Wed Dec 18 16:47:05 2024 (r22568) @@ -10,6 +10,9 @@ #include "mpt/base/math.hpp" #include <limits> +#include <type_traits> + +#include <cmath> @@ -18,23 +21,13 @@ -template <typename Tdst> -constexpr Tdst saturate_trunc(double src) { - if (src >= static_cast<double>(std::numeric_limits<Tdst>::max())) { - return std::numeric_limits<Tdst>::max(); - } - if (src <= static_cast<double>(std::numeric_limits<Tdst>::min())) { - return std::numeric_limits<Tdst>::min(); - } - return static_cast<Tdst>(src); -} - -template <typename Tdst> -constexpr Tdst saturate_trunc(float src) { - if (src >= static_cast<float>(std::numeric_limits<Tdst>::max())) { +template <typename Tdst, typename Tsrc> +constexpr Tdst saturate_trunc(Tsrc src) { + static_assert(std::is_floating_point<Tsrc>::value); + if (src >= static_cast<Tsrc>(std::numeric_limits<Tdst>::max())) { return std::numeric_limits<Tdst>::max(); } - if (src <= static_cast<float>(std::numeric_limits<Tdst>::min())) { + if (src <= static_cast<Tsrc>(std::numeric_limits<Tdst>::min())) { return std::numeric_limits<Tdst>::min(); } return static_cast<Tdst>(src); @@ -44,22 +37,27 @@ // Rounds given double value to nearest integer value of type T. // Out-of-range values are saturated to the specified integer type's limits. -template <typename T> -inline T saturate_round(float val) { - static_assert(std::numeric_limits<T>::is_integer); - return mpt::saturate_trunc<T>(mpt::round(val)); +template <typename Tdst, typename Tsrc> +inline Tdst saturate_round(Tsrc val) { + static_assert(std::is_floating_point<Tsrc>::value); + static_assert(std::numeric_limits<Tdst>::is_integer); + return mpt::saturate_trunc<Tdst>(mpt::round(val)); } -template <typename T> -inline T saturate_round(double val) { - static_assert(std::numeric_limits<T>::is_integer); - return mpt::saturate_trunc<T>(mpt::round(val)); + +template <typename Tdst, typename Tsrc> +inline Tdst saturate_ceil(Tsrc val) { + static_assert(std::is_floating_point<Tsrc>::value); + static_assert(std::numeric_limits<Tdst>::is_integer); + return mpt::saturate_trunc<Tdst>(std::ceil(val)); } -template <typename T> -inline T saturate_round(long double val) { - static_assert(std::numeric_limits<T>::is_integer); - return mpt::saturate_trunc<T>(mpt::round(val)); + +template <typename Tdst, typename Tsrc> +inline Tdst saturate_floor(Tsrc val) { + static_assert(std::is_floating_point<Tsrc>::value); + static_assert(std::numeric_limits<Tdst>::is_integer); + return mpt::saturate_trunc<Tdst>(std::floor(val)); } Modified: trunk/OpenMPT/src/mpt/base/tests/tests_base_saturate_round.hpp ============================================================================== --- trunk/OpenMPT/src/mpt/base/tests/tests_base_saturate_round.hpp Wed Dec 18 16:45:24 2024 (r22567) +++ trunk/OpenMPT/src/mpt/base/tests/tests_base_saturate_round.hpp Wed Dec 18 16:47:05 2024 (r22568) @@ -44,6 +44,34 @@ MPT_TEST_EXPECT_EQUAL(mpt::saturate_round<int8>(110.1), 110); MPT_TEST_EXPECT_EQUAL(mpt::saturate_round<int8>(-110.1), -110); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_trunc<int8>(-0.6), 0); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_trunc<int8>(-0.5), 0); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_trunc<int8>(-0.4), 0); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_trunc<int8>(0.4), 0); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_trunc<int8>(0.5), 0); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_trunc<int8>(0.6), 0); + + MPT_TEST_EXPECT_EQUAL(mpt::saturate_round<int8>(-0.6), -1); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_round<int8>(-0.5), -1); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_round<int8>(-0.4), 0); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_round<int8>(0.4), 0); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_round<int8>(0.5), 1); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_round<int8>(0.6), 1); + + MPT_TEST_EXPECT_EQUAL(mpt::saturate_ceil<int8>(-0.6), 0); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_ceil<int8>(-0.5), 0); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_ceil<int8>(-0.4), 0); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_ceil<int8>(0.4), 1); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_ceil<int8>(0.5), 1); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_ceil<int8>(0.6), 1); + + MPT_TEST_EXPECT_EQUAL(mpt::saturate_floor<int8>(-0.6), -1); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_floor<int8>(-0.5), -1); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_floor<int8>(-0.4), -1); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_floor<int8>(0.4), 0); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_floor<int8>(0.5), 0); + MPT_TEST_EXPECT_EQUAL(mpt::saturate_floor<int8>(0.6), 0); + // These should fail to compile //mpt::saturate_round<std::string>(1.0); //mpt::saturate_round<int64>(1.0); |