Skip to content

Commit

Permalink
Merge pull request #188 from infrasonicaudio/osc-fmod-optimization
Browse files Browse the repository at this point in the history
Improve Oscillator performance by avoiding fmodf
  • Loading branch information
beserge committed Dec 11, 2023
2 parents c17dc18 + 0cc02b3 commit 37f4f8b
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 11 deletions.
4 changes: 2 additions & 2 deletions Source/Synthesis/oscillator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ float Oscillator::Process()
t = phase_;
out = phase_ < 0.5f ? 1.0f : -1.0f;
out += Polyblep(phase_inc_, t);
out -= Polyblep(phase_inc_, fmodf(t + 0.5f, 1.0f));
out -= Polyblep(phase_inc_, fastmod1f(t + 0.5f));
// Leaky Integrator:
// y[n] = A + x[n] + (1 - A) * y[n-1]
out = phase_inc_ * out + (1.0f - phase_inc_) * last_out_;
Expand All @@ -38,7 +38,7 @@ float Oscillator::Process()
t = phase_;
out = phase_ < pw_ ? 1.0f : -1.0f;
out += Polyblep(phase_inc_, t);
out -= Polyblep(phase_inc_, fmodf(t + (1.0f - pw_), 1.0f));
out -= Polyblep(phase_inc_, fastmod1f(t + (1.0f - pw_)));
out *= 0.707f; // ?
break;
default: out = 0.0f; break;
Expand Down
26 changes: 17 additions & 9 deletions Source/Utility/dsp.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,14 @@ inline float fastroot(float f, int n)
return f;
}

/** Significantly more efficient than fmodf(x, 1.0f) for calculating
* the decimal part of a floating point value.
*/
inline float fastmod1f(float x)
{
return x - static_cast<int>(x);
}

/** From http://openaudio.blogspot.com/2017/02/faster-log10-and-pow.html
No approximation, pow10f(x) gives a 90% speed increase over powf(10.f, x)
*/
Expand Down Expand Up @@ -145,16 +153,16 @@ enum class Mapping
LOG,
};

/** Maps a float between a specified range, using a specified curve.
*
/** Maps a float between a specified range, using a specified curve.
*
* \param in a value between 0 to 1 that will be mapped to the new range.
* \param min the new minimum value
* \param max the new maxmimum value
* \param curve a Mapping Value to adjust the response curve of the transformation
* defaults to Linear. @see Mapping
*
*
* When using the log curve min and max, must be greater than zero.
*
*
* \retval returns the transformed float within the new range.
*/
inline float
Expand Down Expand Up @@ -233,11 +241,11 @@ inline float SoftClip(float x)
return SoftLimit(x);
}

/** Quick check for Invalid float values (NaN, Inf, out of range)
** \param x value passed by reference, replaced by y if invalid.
** \param y value to replace x if invalidity is found.
**
** When DEBUG is true in the build, this will halt
/** Quick check for Invalid float values (NaN, Inf, out of range)
** \param x value passed by reference, replaced by y if invalid.
** \param y value to replace x if invalidity is found.
**
** When DEBUG is true in the build, this will halt
** execution for tracing the reason for the invalidity. */
inline void TestFloat(float &x, float y = 0.f)
{
Expand Down

0 comments on commit 37f4f8b

Please sign in to comment.