Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cleanup lmms_math.h #7382

Merged
merged 36 commits into from
Aug 28, 2024
Merged
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
5c5ec5d
simplified fraction and absfraction functions
Rossmaxx Jul 16, 2024
1dded27
removed unused fastSqrt() function
Rossmaxx Jul 16, 2024
e30614c
unused absMin() and absMax()
Rossmaxx Jul 16, 2024
d845331
simplified numDigitsAsInt() function
Rossmaxx Jul 16, 2024
b1bc173
removed fastPow()
Rossmaxx Jul 16, 2024
0853f5a
move roundAt to math header
Rossmaxx Jul 16, 2024
41b1e86
use lmms namespace for roundAt
Rossmaxx Jul 16, 2024
6e7be74
fixed compilation
Rossmaxx Jul 16, 2024
2ab7411
patch up calculation flaw
Rossmaxx Jul 16, 2024
e4614c3
patch up calculation flaw
Rossmaxx Jul 16, 2024
311941c
Stupid semicolon miss
Rossmaxx Jul 16, 2024
aa1408f
Fixed tests failing.
Rossmaxx Jul 16, 2024
bb82c0d
Negate diff
Rossmaxx Jul 16, 2024
9287e4e
Another semicolon
Rossmaxx Jul 16, 2024
cb069f9
Code review from saker
Rossmaxx Jul 17, 2024
cb3be41
it's const
Rossmaxx Jul 19, 2024
7ebb8c2
use std::trunc()
Rossmaxx Jul 19, 2024
30c61cb
Merge branch 'master' into cleanup-lmms-math
Rossmaxx Aug 9, 2024
49d452a
fixup after fixing merge conflicts
Rossmaxx Aug 9, 2024
ca613d0
remove unused fastFma and fastFmal functions.
Rossmaxx Aug 9, 2024
05af0eb
don't fix style in unmodified line
Rossmaxx Aug 9, 2024
dea9ae8
remove lmms_basics include, not needed
Rossmaxx Aug 9, 2024
164f788
some negation of diff
Rossmaxx Aug 9, 2024
f24f713
use signedPowf from lmms_math in NES
Rossmaxx Aug 9, 2024
21477bc
removed fastRand function, unused
Rossmaxx Aug 9, 2024
8d996d1
remove fastFmal
Rossmaxx Aug 9, 2024
3782334
remove unused sinc function
Rossmaxx Aug 9, 2024
7131d1c
cleanup signedPowf
Rossmaxx Aug 9, 2024
c6b60df
fix build
Rossmaxx Aug 9, 2024
3175e81
add copyright
Rossmaxx Aug 9, 2024
189ae65
more style
Rossmaxx Aug 9, 2024
9857493
code review
Rossmaxx Aug 11, 2024
cf2d996
further simplify random number math
Rossmaxx Aug 27, 2024
de57764
nuke unnecessary brackets
Rossmaxx Aug 27, 2024
f0e4d43
static cast
Rossmaxx Aug 27, 2024
af7deeb
removed static from lmms_math file
Rossmaxx Aug 27, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions include/interpolation.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,25 +71,25 @@ inline float cubicInterpolate( float v0, float v1, float v2, float v3, float x )
{
float frsq = x*x;
float frcu = frsq*v0;
float t1 = v3 + 3*v1;
float t1 = std::fma(v1, 3, v3);

return( v1 + fastFmaf( 0.5f, frcu, x ) * ( v2 - frcu * ( 1.0f/6.0f ) -
fastFmaf( t1, ( 1.0f/6.0f ), -v0 ) * ( 1.0f/3.0f ) ) + frsq * x * ( t1 *
( 1.0f/6.0f ) - 0.5f * v2 ) + frsq * fastFmaf( 0.5f, v2, -v1 ) );
return (v1 + std::fma(0.5f, frcu, x) * (v2 - frcu * (1.0f / 6.0f) -
std::fma(t1, (1.0f / 6.0f), -v0) * (1.0f / 3.0f)) + frsq * x * (t1 *
(1.0f / 6.0f) - 0.5f * v2) + frsq * std::fma(0.5f, v2, -v1));
}



inline float cosinusInterpolate( float v0, float v1, float x )
{
const float f = ( 1.0f - cosf( x * F_PI ) ) * 0.5f;
return fastFmaf( f, v1-v0, v0 );
return std::fma(f, v1 - v0, v0);
}


inline float linearInterpolate( float v0, float v1, float x )
{
return fastFmaf( x, v1-v0, v0 );
return std::fma(x, v1 - v0, v0);
}


Expand All @@ -104,7 +104,7 @@ inline float optimalInterpolate( float v0, float v1, float x )
const float c2 = even * -0.004541102062639801;
const float c3 = odd * -1.57015627178718420;

return fastFmaf( fastFmaf( fastFmaf( c3, z, c2 ), z, c1 ), z, c0 );
return std::fma(std::fma(std::fma(c3, z, c2), z, c1), z, c0);
}


Expand All @@ -121,7 +121,7 @@ inline float optimal4pInterpolate( float v0, float v1, float v2, float v3, float
const float c2 = even1 * -0.246185007019907091 + even2 * 0.24614027139700284;
const float c3 = odd1 * -0.36030925263849456 + odd2 * 0.10174985775982505;

return fastFmaf( fastFmaf( fastFmaf( c3, z, c2 ), z, c1 ), z, c0 );
return std::fma(std::fma(std::fma(c3, z, c2), z, c1), z, c0);
}


Expand All @@ -132,7 +132,7 @@ inline float lagrangeInterpolate( float v0, float v1, float v2, float v3, float
const float c1 = v2 - v0 * ( 1.0f / 3.0f ) - v1 * 0.5f - v3 * ( 1.0f / 6.0f );
const float c2 = 0.5f * (v0 + v2) - v1;
const float c3 = ( 1.0f/6.0f ) * ( v3 - v0 ) + 0.5f * ( v1 - v2 );
return fastFmaf( fastFmaf( fastFmaf( c3, x, c2 ), x, c1 ), x, c0 );
return std::fma(std::fma(std::fma(c3, x, c2), x, c1), x, c0);
}


Expand Down
210 changes: 35 additions & 175 deletions include/lmms_math.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,20 +42,20 @@ 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)
Rossmaxx marked this conversation as resolved.
Show resolved Hide resolved
messmerd marked this conversation as resolved.
Show resolved Hide resolved
{
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.
*
Expand All @@ -71,146 +71,49 @@ static inline float absFraction(const float x)
return x - std::floor(x);
Rossmaxx marked this conversation as resolved.
Show resolved Hide resolved
}

/*!
* @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<int>( _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;
constexpr float FAST_RAND_RATIO = 1.0f / 32767;
static inline int fast_rand()
{
static unsigned long next = 1;
next = next * 1103515245 + 12345;
return( (unsigned)( next / 65536 ) % 32768 );
}

static inline double fastRand( double range )
{
static const double fast_rand_ratio = 1.0 / FAST_RAND_MAX;
return fast_rand() * range * fast_rand_ratio;
}

static inline float fastRandf( float range )
{
static const float fast_rand_ratio = 1.0f / FAST_RAND_MAX;
return fast_rand() * range * fast_rand_ratio;
return fast_rand() * range * FAST_RAND_RATIO;
}

//! @brief Takes advantage of fmal() function if present in hardware
static inline long double fastFmal( long double a, long double b, long double c )
{
#ifdef FP_FAST_FMAL
#ifdef __clang__
return fma( a, b, c );
#else
return fmal( a, b, c );
#endif
#else
return a * b + c;
#endif // FP_FAST_FMAL
}

//! @brief Takes advantage of fmaf() function if present in hardware
static inline float fastFmaf( float a, float b, float c )
//! Round `value` to `where` depending on step size
template<class T>
static void roundAt(T& value, const T& where, const T& stepSize)
{
#ifdef FP_FAST_FMAF
#ifdef __clang__
return fma( a, b, c );
#else
return fmaf( a, b, c );
#endif
#else
return a * b + c;
#endif // FP_FAST_FMAF
if (std::abs(value - where) < F_EPSILON * std::abs(stepSize))
{
value = where;
}
}

//! @brief Takes advantage of fma() function if present in hardware
static inline double fastFma( double a, double b, double c )
{
#ifdef FP_FAST_FMA
return fma( a, b, c );
#else
return a * b + 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 )
{
union
{
double d;
int32_t x[2];
} u = { a };
u.x[1] = static_cast<int32_t>( b * ( u.x[1] - 1072632447 ) + 1072632447 );
u.x[0] = 0;
return u.d;
//! returns 1.0f if val >= 0.0f, -1.0 else
static inline float sign(float val)
{
return val >= 0.0f ? 1.0f : -1.0f;
}

// sinc function
static inline double sinc( double _x )

//! if val >= 0.0f, returns sqrtf(val), else: -sqrtf(-val)
static inline float sqrt_neg(float val)
{
return _x == 0.0 ? 1.0 : sin( F_PI * _x ) / ( F_PI * _x );
return std::sqrt(std::abs(val)) * sign(val);
}


//! @brief Exponential function that deals with negative bases
static inline float signedPowf( float v, float e )
static inline float signedPowf(float v, float e)
{
return v < 0
? powf( -v, e ) * -1.0f
: powf( v, e );
return std::pow(std::abs(v), e) * sign(v);
Rossmaxx marked this conversation as resolved.
Show resolved Hide resolved
}


Expand Down Expand Up @@ -289,48 +192,6 @@ static inline float dbfsToAmp(float dbfs)
}



//! returns 1.0f if val >= 0.0f, -1.0 else
static inline float sign( float val )
{
return val >= 0.0f ? 1.0f : -1.0f;
}


//! if val >= 0.0f, returns sqrtf(val), else: -sqrtf(-val)
static inline float sqrt_neg( float val )
{
return sqrtf( fabs( val ) ) * sign( 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<class T>
static inline T absMax( T a, T b )
{
return std::abs(a) > std::abs(b) ? a : b;
}

//! returns value nearest to zero
template<class T>
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<class T, class F>
constexpr T lerp(T a, T b, F t)
Expand All @@ -343,22 +204,21 @@ constexpr T lerp(T a, T b, F t)
static inline int numDigitsAsInt(float f)
{
// use rounding:
// LcdSpinBox sometimes uses roundf(), sometimes cast rounding
// LcdSpinBox sometimes uses std::round(), sometimes cast rounding
// we use rounding to be on the "safe side"
const float rounded = roundf(f);
int asInt = static_cast<int>(rounded);
int asInt = static_cast<int>(std::round(f));
int digits = 1; // always at least 1
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<int32_t>(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;
Expand Down
4 changes: 2 additions & 2 deletions plugins/Flanger/Noise.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,15 @@ namespace lmms

Noise::Noise()
{
inv_randmax = 1.0/FAST_RAND_MAX; /* for range of 0 - 1.0 */
inv_randmax = FAST_RAND_RATIO; /* for range of 0 - 1.0 */
Rossmaxx marked this conversation as resolved.
Show resolved Hide resolved
}




float Noise::tick()
{
return (float) ((2.0 * fast_rand() * inv_randmax) - 1.0);
return fastRandf(2.0f) - 1.0f;
}


Expand Down
6 changes: 3 additions & 3 deletions plugins/GranularPitchShifter/GranularPitchShifterEffect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,17 +157,17 @@ bool GranularPitchShifterEffect::processAudioBuffer(SampleFrame* buf, const fpp_
if (++m_timeSinceLastGrain >= m_nextWaitRandomization * waitMult)
{
m_timeSinceLastGrain = 0;
double randThing = (fast_rand()/static_cast<double>(FAST_RAND_MAX) * 2. - 1.);
double randThing = (fast_rand() * FAST_RAND_RATIO * 2. - 1.);
Rossmaxx marked this conversation as resolved.
Show resolved Hide resolved
m_nextWaitRandomization = std::exp2(randThing * twitch);
double grainSpeed = 1. / std::exp2(randThing * jitter);

std::array<float, 2> sprayResult = {0, 0};
if (spray > 0)
{
sprayResult[0] = (fast_rand() / static_cast<float>(FAST_RAND_MAX)) * spray * m_sampleRate;
sprayResult[0] = fast_rand() * FAST_RAND_RATIO * spray * m_sampleRate;
sprayResult[1] = linearInterpolate(
sprayResult[0],
(fast_rand() / static_cast<float>(FAST_RAND_MAX)) * spray * m_sampleRate,
fast_rand() * FAST_RAND_RATIO * spray * m_sampleRate,
spraySpread);
}

Expand Down
4 changes: 2 additions & 2 deletions plugins/Kicker/KickerOsc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}
Expand Down
2 changes: 1 addition & 1 deletion plugins/Monstro/Monstro.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
}


Expand Down
Loading
Loading