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

Reintroduce fast math functions #7495

Merged
merged 7 commits into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
22 changes: 11 additions & 11 deletions include/interpolation.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,27 +69,27 @@ inline float hermiteInterpolate( float x0, float x1, float x2, float x3,

inline float cubicInterpolate( float v0, float v1, float v2, float v3, float x )
{
float frsq = x*x;
float frcu = frsq*v0;
float t1 = std::fma(v1, 3, v3);
float frsq = x * x;
float frcu = frsq * v0;
float t1 = v1 * 3.f + v3;

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));
return v1 + (0.5f * frcu + x) * (v2 - frcu * (1.0f / 6.0f) -
(t1 * (1.0f / 6.0f) - v0) * (1.0f / 3.0f)) + frsq * x * (t1 *
(1.0f / 6.0f) - 0.5f * v2) + frsq * (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 std::fma(f, v1 - v0, v0);
return f * (v1 - v0) + v0;
}


inline float linearInterpolate( float v0, float v1, float x )
{
return std::fma(x, v1 - v0, v0);
return 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 std::fma(std::fma(std::fma(c3, z, c2), z, c1), z, c0);
return ((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 std::fma(std::fma(std::fma(c3, z, c2), z, c1), z, c0);
return ((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 std::fma(std::fma(std::fma(c3, x, c2), x, c1), x, c0);
return ((c3 * x + c2) * x + c1) * x + c0;
}


Expand Down
17 changes: 16 additions & 1 deletion include/lmms_math.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,13 @@

#include <QtGlobal>
#include <algorithm>
#include <cassert>
Rossmaxx marked this conversation as resolved.
Show resolved Hide resolved
#include <cmath>
#include <cstdint>
#include <cstring>

#include "lmms_constants.h"
#include "lmmsconfig.h"
#include <cassert>

namespace lmms
{
Expand Down Expand Up @@ -96,6 +97,20 @@ static void roundAt(T& value, const T& where, const T& stepSize)
}
}

//! Source: http://martin.ankerl.com/2007/10/04/optimized-pow-approximation-for-java-and-c-c/
inline double fastPow(double a, double b)
{
double d;
std::int32_t x[2];

std::memcpy(x, &a, sizeof(x));
x[1] = static_cast<std::int32_t>(b * (x[1] - 1072632447) + 1072632447);
x[0] = 0;

std::memcpy(&d, x, sizeof(d));
return d;
}


//! returns 1.0f if val >= 0.0f, -1.0 else
inline float sign(float val)
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 - std::pow((m_counter < m_length) ? m_counter / m_length : 1, m_env);
const double gain = 1 - fastPow((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 - std::pow(m_counter / m_length, m_slope))) : 0;
const double change = (m_counter < m_length) ? ((m_startFreq - m_endFreq) * (1 - fastPow(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 std::pow(s, m_parent->m_slope[slope]);
return fastPow(s, m_parent->m_slope[slope]);
}


Expand Down
Loading