diff --git a/include/lmms_math.h b/include/lmms_math.h index 369a89b6ea6..499205342bf 100644 --- a/include/lmms_math.h +++ b/include/lmms_math.h @@ -30,32 +30,27 @@ #include #include +#include "lmms_basics.h" #include "lmms_constants.h" #include "lmmsconfig.h" #include namespace lmms { - -static inline bool approximatelyEqual(float x, float y) -{ - return x == y ? true : std::abs(x - y) < F_EPSILON; -} - -#ifdef __INTEL_COMPILER - -static inline float absFraction( const float _x ) -{ - return( _x - floorf( _x ) ); -} - -static inline float fraction( const float _x ) +/*! + * @brief Returns the fractional part of a float, a value between -1.0f and 1.0f. + * + * fraction( 2.3) => 0.3 + * fraction(-2.3) => -0.3 + * + * Note that if the return value is used as a phase of an oscillator, that the oscillator must support + * negative phases. + */ +static inline float fraction(const float x) { - return( _x - floorf( _x ) - ( _x >= 0.0f ? 0.0 : 1.0 ) ); + return x - std::trunc(x); } -#else - /*! * @brief Returns the wrapped fractional part of a float, a value between 0.0f and 1.0f. * @@ -71,61 +66,6 @@ static inline float absFraction(const float x) return x - std::floor(x); } -/*! - * @brief Returns the fractional part of a float, a value between -1.0f and 1.0f. - * - * fraction( 2.3) => 0.3 - * fraction(-2.3) => -0.3 - * - * Note that if the return value is used as a phase of an oscillator, that the oscillator must support - * negative phases. - */ -static inline float fraction( const float _x ) -{ - return( _x - static_cast( _x ) ); -} - - -#if 0 -// SSE3-version -static inline float absFraction( float _x ) -{ - unsigned int tmp; - asm( - "fld %%st\n\t" - "fisttp %1\n\t" - "fild %1\n\t" - "ftst\n\t" - "sahf\n\t" - "jae 1f\n\t" - "fld1\n\t" - "fsubrp %%st, %%st(1)\n\t" - "1:\n\t" - "fsubrp %%st, %%st(1)" - : "+t"( _x ), "=m"( tmp ) - : - : "st(1)", "cc" ); - return( _x ); -} - -static inline float absFraction( float _x ) -{ - unsigned int tmp; - asm( - "fld %%st\n\t" - "fisttp %1\n\t" - "fild %1\n\t" - "fsubrp %%st, %%st(1)" - : "+t"( _x ), "=m"( tmp ) - : - : "st(1)" ); - return( _x ); -} -#endif - -#endif // __INTEL_COMPILER - - constexpr int FAST_RAND_MAX = 32767; static inline int fast_rand() @@ -185,17 +125,14 @@ static inline double fastFma( double a, double b, double c ) #endif } -// source: http://martin.ankerl.com/2007/10/04/optimized-pow-approximation-for-java-and-c-c/ -static inline double fastPow( double a, double b ) +//! Round `value` to `where` depending on step size +template +static void roundAt(T& value, const T& where, const T& stepSize) { - union + if (std::abs(value - where) < typeInfo::minEps() * std::abs(stepSize)) { - double d; - int32_t x[2]; - } u = { a }; - u.x[1] = static_cast( b * ( u.x[1] - 1072632447 ) + 1072632447 ); - u.x[0] = 0; - return u.d; + value = where; + } } // sinc function @@ -304,33 +241,6 @@ static inline float sqrt_neg( float val ) } -// fast approximation of square root -static inline float fastSqrt( float n ) -{ - union - { - int32_t i; - float f; - } u; - u.f = n; - u.i = ( u.i + ( 127 << 23 ) ) >> 1; - return u.f; -} - -//! returns value furthest from zero -template -static inline T absMax( T a, T b ) -{ - return std::abs(a) > std::abs(b) ? a : b; -} - -//! returns value nearest to zero -template -static inline T absMin( T a, T b ) -{ - return std::abs(a) < std::abs(b) ? a : b; -} - //! Returns the linear interpolation of the two values template constexpr T lerp(T a, T b, F t) @@ -342,23 +252,18 @@ constexpr T lerp(T a, T b, F t) // @note Once we upgrade to C++20, we could probably use std::formatted_size static inline int numDigitsAsInt(float f) { - // use rounding: - // LcdSpinBox sometimes uses roundf(), sometimes cast rounding - // we use rounding to be on the "safe side" - const float rounded = roundf(f); - int asInt = static_cast(rounded); + int asInt = static_cast(std::round(f)); int digits = 1; // always at least 1 - if(asInt < 0) + if (asInt < 0) { ++digits; asInt = -asInt; } - // "asInt" is positive from now - int32_t power = 1; - for(int32_t i = 1; i<10; ++i) + int power = 1; + for (int i = 1; i < 10; ++i) { power *= 10; - if(static_cast(asInt) >= power) { ++digits; } // 2 digits for >=10, 3 for >=100 + if (asInt >= power) { ++digits; } // 2 digits for >=10, 3 for >=100 else { break; } } return digits; diff --git a/plugins/Kicker/KickerOsc.h b/plugins/Kicker/KickerOsc.h index 420373512af..a11b0fc5521 100644 --- a/plugins/Kicker/KickerOsc.h +++ b/plugins/Kicker/KickerOsc.h @@ -64,7 +64,7 @@ class KickerOsc { for( fpp_t frame = 0; frame < frames; ++frame ) { - const double gain = ( 1 - fastPow( ( m_counter < m_length ) ? m_counter / m_length : 1, m_env ) ); + const double gain = 1 - std::pow((m_counter < m_length) ? m_counter / m_length : 1, m_env); const sample_t s = ( Oscillator::sinSample( m_phase ) * ( 1 - m_noise ) ) + ( Oscillator::noiseSample( 0 ) * gain * gain * m_noise ); buf[frame][0] = s * gain; buf[frame][1] = s * gain; @@ -80,7 +80,7 @@ class KickerOsc m_FX.nextSample( buf[frame][0], buf[frame][1] ); m_phase += m_freq / sampleRate; - const double change = ( m_counter < m_length ) ? ( ( m_startFreq - m_endFreq ) * ( 1 - fastPow( m_counter / m_length, m_slope ) ) ) : 0; + const double change = (m_counter < m_length) ? ((m_startFreq - m_endFreq) * (1 - std::pow(m_counter / m_length, m_slope))) : 0; m_freq = m_endFreq + change; ++m_counter; } diff --git a/plugins/Monstro/Monstro.cpp b/plugins/Monstro/Monstro.cpp index 874b5d8d13a..d53fcc9137d 100644 --- a/plugins/Monstro/Monstro.cpp +++ b/plugins/Monstro/Monstro.cpp @@ -858,7 +858,7 @@ inline sample_t MonstroSynth::calcSlope( int slope, sample_t s ) { if( m_parent->m_slope[slope] == 1.0f ) return s; if( s == 0.0f ) return s; - return fastPow( s, m_parent->m_slope[slope] ); + return std::pow(s, m_parent->m_slope[slope]); } diff --git a/src/core/AutomatableModel.cpp b/src/core/AutomatableModel.cpp index 5ce259dc2b0..e006be651a4 100644 --- a/src/core/AutomatableModel.cpp +++ b/src/core/AutomatableModel.cpp @@ -350,18 +350,6 @@ float AutomatableModel::inverseScaledValue( float value ) const -//! @todo: this should be moved into a maths header -template -void roundAt( T& value, const T& where, const T& step_size ) -{ - if (std::abs(value - where) < F_EPSILON * std::abs(step_size)) - { - value = where; - } -} - - - template void AutomatableModel::roundAt( T& value, const T& where ) const