Use C++20 std::numbers, std::lerp() (#7696)

* use c++20 concepts and numbers for lmms_constants.h

* replace lmms::numbers::sqrt2 with std::numbers::sqrt2

* replace lmms::numbers::e with std::numbers::e
Also replace the only use of lmms::numbers::inv_e with a local constexpr instead

* remove lmms::numbers::pi_half and lmms::numbers::pi_sqr
They were only used in one or two places each

* replace lmms::numbers::pi with std::numbers::pi

* add #include <numbers> to every file touched so far
This is probably not needed for some of these files. I'll remove those later

* Remove lmms::numbers

Rest in peace lmms::numbers::tau, my beloved

* Add missing #include <numbers>

* replace stray use of F_EPSILON with approximatelyEqual()

* make many constants inline constexpr
A lot of the remaining constants in lmms_constants.h are specific to
SaProcessor. If they are only used there, shouldn't they be in SaProcessor.h?

* ok then, it's allowed to be signed

* remove #include "lmms_constants.h" for files that don't need it
- And also move F_EPSILON into lmms_math.h
- And also add an overload for fast_rand() to specify a higher and lower bound
- And a bunch of other nonsense

* ok then, it's allowed to be inferred

* ok then, it can accept an integral

* fix typo

* appease msvc

* appease msvc again

* Replace linearInterpolate with std::lerp()

As well as time travel to undo several foolish decisions and squash tiny
commits together

* Fix msvc constexpr warnings

* Fix msvc float to double truncation warning

* Apply two suggestions from code review

Co-authored-by: Dalton Messmer <messmer.dalton@gmail.com>

* Apply suggestions from code review

Co-authored-by: Dalton Messmer <messmer.dalton@gmail.com>

* fix silly mistake

* Remove SlicerT's dependence on lmms_math.h

* Allow more type inference on fastRand() and fastPow10f()

* Apply suggestions from code review

Co-authored-by: Dalton Messmer <messmer.dalton@gmail.com>

* Clean up fastRand() a little bit more

---------

Co-authored-by: Dalton Messmer <messmer.dalton@gmail.com>
This commit is contained in:
Fawn
2025-02-13 11:15:08 -07:00
committed by GitHub
parent e615046d78
commit e328a136fc
47 changed files with 327 additions and 321 deletions

View File

@@ -22,7 +22,7 @@
*
*/
#include <cmath>
#include <QDomElement>
#include "BitInvader.h"
@@ -36,10 +36,9 @@
#include "NotePlayHandle.h"
#include "PixmapButton.h"
#include "Song.h"
#include "interpolation.h"
#include "lmms_math.h"
#include "embed.h"
#include "plugin_export.h"
namespace lmms
@@ -121,7 +120,7 @@ sample_t BSynth::nextStringSample( float sample_length )
}
const auto nextIndex = currentIndex < sample_length - 1 ? currentIndex + 1 : 0;
return linearInterpolate(sample_shape[currentIndex], sample_shape[nextIndex], fraction(currentRealIndex));
return std::lerp(sample_shape[currentIndex], sample_shape[nextIndex], fraction(currentRealIndex));
}
/***********************************************************************

View File

@@ -24,6 +24,7 @@
*/
#include "Bitcrush.h"
#include "lmms_math.h"
#include "embed.h"
#include "plugin_export.h"
@@ -97,7 +98,7 @@ inline float BitcrushEffect::depthCrush( float in )
inline float BitcrushEffect::noise( float amt )
{
return fastRandf( amt * 2.0f ) - amt;
return fastRand(-amt, +amt);
}
Effect::ProcessStatus BitcrushEffect::processImpl(SampleFrame* buf, const fpp_t frames)
@@ -248,4 +249,4 @@ PLUGIN_EXPORT Plugin * lmms_plugin_main( Model* parent, void* data )
}
} // namespace lmms
} // namespace lmms

View File

@@ -24,8 +24,10 @@
#include "Compressor.h"
#include <cmath>
#include <numbers>
#include "embed.h"
#include "interpolation.h"
#include "lmms_math.h"
#include "plugin_export.h"
@@ -209,18 +211,19 @@ void CompressorEffect::redrawKnee()
void CompressorEffect::calcTiltCoeffs()
{
using namespace std::numbers;
m_tiltVal = m_compressorControls.m_tiltModel.value();
const float amp = 6.f / std::log(2.f);
constexpr float amp = 6.f / ln2_v<float>;
const float gfactor = 5;
constexpr float gfactor = 5;
const float g1 = m_tiltVal > 0 ? -gfactor * m_tiltVal : -m_tiltVal;
const float g2 = m_tiltVal > 0 ? m_tiltVal : gfactor * m_tiltVal;
m_lgain = std::exp(g1 / amp) - 1;
m_hgain = std::exp(g2 / amp) - 1;
const float omega = numbers::tau_v<float> * m_compressorControls.m_tiltFreqModel.value();
const float omega = 2 * pi_v<float> * m_compressorControls.m_tiltFreqModel.value();
const float n = 1 / (m_sampleRate * 3 + omega);
m_a0 = 2 * omega * n;
m_b1 = (m_sampleRate * 3 - omega) * n;
@@ -402,21 +405,21 @@ Effect::ProcessStatus CompressorEffect::processImpl(SampleFrame* buf, const fpp_
if (blend <= 1)// Blend to minimum volume
{
const float temp1 = qMin(m_gainResult[0], m_gainResult[1]);
m_gainResult[0] = linearInterpolate(m_gainResult[0], temp1, blend);
m_gainResult[1] = linearInterpolate(m_gainResult[1], temp1, blend);
m_gainResult[0] = std::lerp(m_gainResult[0], temp1, blend);
m_gainResult[1] = std::lerp(m_gainResult[1], temp1, blend);
}
else if (blend <= 2)// Blend to average volume
{
const float temp1 = qMin(m_gainResult[0], m_gainResult[1]);
const float temp2 = (m_gainResult[0] + m_gainResult[1]) * 0.5f;
m_gainResult[0] = linearInterpolate(temp1, temp2, blend - 1);
m_gainResult[0] = std::lerp(temp1, temp2, blend - 1);
m_gainResult[1] = m_gainResult[0];
}
else// Blend to maximum volume
{
const float temp1 = (m_gainResult[0] + m_gainResult[1]) * 0.5f;
const float temp2 = qMax(m_gainResult[0], m_gainResult[1]);
m_gainResult[0] = linearInterpolate(temp1, temp2, blend - 2);
m_gainResult[0] = std::lerp(temp1, temp2, blend - 2);
m_gainResult[1] = m_gainResult[0];
}
}

View File

@@ -26,6 +26,7 @@
#include "CompressorControlDialog.h"
#include "CompressorControls.h"
#include <cmath>
#include <QLabel>
#include <QPainter>
#include <QWheelEvent>
@@ -34,7 +35,6 @@
#include "embed.h"
#include "../Eq/EqFader.h"
#include "GuiApplication.h"
#include "interpolation.h"
#include "Knob.h"
#include "MainWindow.h"
#include "PixmapButton.h"
@@ -437,7 +437,11 @@ void CompressorControlDialog::drawVisPixmap()
m_p.setPen(QPen(m_inVolAreaColor, 1));
for (int i = 0; i < m_compPixelMovement; ++i)
{
const int temp = linearInterpolate(m_lastPoint, m_yPoint, float(i) / float(m_compPixelMovement));
const int temp = std::lerp(
m_lastPoint,
m_yPoint,
static_cast<float>(i) / static_cast<float>(m_compPixelMovement)
);
m_p.drawLine(m_windowSizeX-m_compPixelMovement+i, temp, m_windowSizeX-m_compPixelMovement+i, m_windowSizeY);
}
@@ -449,7 +453,11 @@ void CompressorControlDialog::drawVisPixmap()
m_p.setPen(QPen(m_outVolAreaColor, 1));
for (int i = 0; i < m_compPixelMovement; ++i)
{
const int temp = linearInterpolate(m_lastPoint+m_lastGainPoint, m_yPoint+m_yGainPoint, float(i) / float(m_compPixelMovement));
const int temp = std::lerp(
m_lastPoint + m_lastGainPoint,
m_yPoint + m_yGainPoint,
static_cast<float>(i) / static_cast<float>(m_compPixelMovement)
);
m_p.drawLine(m_windowSizeX-m_compPixelMovement+i, temp, m_windowSizeX-m_compPixelMovement+i, m_windowSizeY);
}
@@ -512,7 +520,7 @@ void CompressorControlDialog::redrawKnee()
// Draw knee curve using many straight lines.
for (int i = 0; i < COMP_KNEE_LINES; ++i)
{
newPoint[0] = linearInterpolate(kneePoint1, kneePoint2X, (i + 1) / (float)COMP_KNEE_LINES);
newPoint[0] = std::lerp(kneePoint1, kneePoint2X, (i + 1) / static_cast<float>(COMP_KNEE_LINES));
const float temp = newPoint[0] - thresholdVal + kneeVal;
newPoint[1] = (newPoint[0] + (actualRatio - 1) * temp * temp / (4 * kneeVal));

View File

@@ -25,6 +25,7 @@
#include "Lfo.h"
#include <cmath>
#include <numbers>
namespace lmms
{
@@ -33,7 +34,7 @@ namespace lmms
Lfo::Lfo( int samplerate )
{
m_samplerate = samplerate;
m_twoPiOverSr = numbers::tau_v<float> / samplerate;
m_twoPiOverSr = 2 * std::numbers::pi_v<float> / samplerate;
}

View File

@@ -25,8 +25,8 @@
#ifndef LFO_H
#define LFO_H
#include "lmms_constants.h"
#include <cmath>
#include <numbers>
namespace lmms
{
@@ -50,7 +50,7 @@ public:
m_frequency = frequency;
m_increment = m_frequency * m_twoPiOverSr;
if (m_phase >= numbers::tau_v<float>) { m_phase -= numbers::tau_v<float>; }
m_phase = std::fmod(m_phase, 2 * std::numbers::pi_v<float>);
}
@@ -59,7 +59,7 @@ public:
inline void setSampleRate ( int samplerate )
{
m_samplerate = samplerate;
m_twoPiOverSr = numbers::tau_v<float> / samplerate;
m_twoPiOverSr = 2 * std::numbers::pi_v<float> / samplerate;
m_increment = m_frequency * m_twoPiOverSr;
}

View File

@@ -70,7 +70,7 @@ Effect::ProcessStatus DispersionEffect::processImpl(SampleFrame* buf, const fpp_
const bool dc = m_dispersionControls.m_dcModel.value();
// All-pass coefficient calculation
const float w0 = (numbers::tau_v<float> / m_sampleRate) * freq;
const float w0 = (2 * std::numbers::pi_v<float> / m_sampleRate) * freq;
const float a0 = 1 + (std::sin(w0) / (reso * 2.f));
float apCoeff1 = (1 - (a0 - 1)) / a0;
float apCoeff2 = (-2 * std::cos(w0)) / a0;

View File

@@ -25,8 +25,10 @@
#include "DynamicsProcessor.h"
#include <cmath>
#include "lmms_math.h"
#include "interpolation.h"
#include "RmsHelper.h"
#include "embed.h"
@@ -189,7 +191,7 @@ Effect::ProcessStatus DynProcEffect::processImpl(SampleFrame* buf, const fpp_t f
{
float gain;
if (lookup < 1) { gain = frac * samples[0]; }
else if (lookup < 200) { gain = linearInterpolate(samples[lookup - 1], samples[lookup], frac); }
else if (lookup < 200) { gain = std::lerp(samples[lookup - 1], samples[lookup], frac); }
else { gain = samples[199]; }
s[i] *= gain;

View File

@@ -31,7 +31,6 @@
#include "embed.h"
#include "Engine.h"
#include "FontHelper.h"
#include "lmms_constants.h"
#include "lmms_math.h"
@@ -200,13 +199,14 @@ bool EqHandle::mousePressed() const
float EqHandle::getPeakCurve( float x )
{
using namespace std::numbers;
double freqZ = xPixelToFreq( EqHandle::x(), m_width );
double w0 = numbers::tau * freqZ / Engine::audioEngine()->outputSampleRate();
double w0 = 2 * pi * freqZ / Engine::audioEngine()->outputSampleRate();
double c = std::cos(w0);
double s = std::sin(w0);
double Q = getResonance();
double A = fastPow10f(yPixelToGain(EqHandle::y(), m_heigth, m_pixelsPerUnitHeight) / 40);
double alpha = s * std::sinh(std::log(2.0) / 2 * Q * w0 / std::sin(w0));
double alpha = s * std::sinh(ln2 / 2 * Q * w0 / std::sin(w0));
//calc coefficents
double b0 = 1 + alpha * A;
@@ -237,7 +237,7 @@ float EqHandle::getPeakCurve( float x )
float EqHandle::getHighShelfCurve( float x )
{
double freqZ = xPixelToFreq( EqHandle::x(), m_width );
double w0 = numbers::tau * freqZ / Engine::audioEngine()->outputSampleRate();
double w0 = 2 * std::numbers::pi * freqZ / Engine::audioEngine()->outputSampleRate();
double c = std::cos(w0);
double s = std::sin(w0);
double A = fastPow10f(yPixelToGain(EqHandle::y(), m_heigth, m_pixelsPerUnitHeight) * 0.025);
@@ -272,7 +272,7 @@ float EqHandle::getHighShelfCurve( float x )
float EqHandle::getLowShelfCurve( float x )
{
double freqZ = xPixelToFreq( EqHandle::x(), m_width );
double w0 = numbers::tau * freqZ / Engine::audioEngine()->outputSampleRate();
double w0 = 2 * std::numbers::pi * freqZ / Engine::audioEngine()->outputSampleRate();
double c = std::cos(w0);
double s = std::sin(w0);
double A = fastPow10f(yPixelToGain(EqHandle::y(), m_heigth, m_pixelsPerUnitHeight) / 40);
@@ -307,7 +307,7 @@ float EqHandle::getLowShelfCurve( float x )
float EqHandle::getLowCutCurve( float x )
{
double freqZ = xPixelToFreq( EqHandle::x(), m_width );
double w0 = numbers::tau * freqZ / Engine::audioEngine()->outputSampleRate();
double w0 = 2 * std::numbers::pi * freqZ / Engine::audioEngine()->outputSampleRate();
double c = std::cos(w0);
double s = std::sin(w0);
double resonance = getResonance();
@@ -349,7 +349,7 @@ float EqHandle::getLowCutCurve( float x )
float EqHandle::getHighCutCurve( float x )
{
double freqZ = xPixelToFreq( EqHandle::x(), m_width );
double w0 = numbers::tau * freqZ / Engine::audioEngine()->outputSampleRate();
double w0 = 2 * std::numbers::pi * freqZ / Engine::audioEngine()->outputSampleRate();
double c = std::cos(w0);
double s = std::sin(w0);
double resonance = getResonance();
@@ -522,7 +522,7 @@ void EqHandle::setlp48()
double EqHandle::calculateGain(const double freq, const double a1, const double a2, const double b0, const double b1, const double b2 )
{
const double w = std::sin(numbers::pi * freq / Engine::audioEngine()->outputSampleRate());
const double w = std::sin(std::numbers::pi * freq / Engine::audioEngine()->outputSampleRate());
const double PHI = w * w * 4;
auto bb = b0 + b1 + b2;

View File

@@ -25,13 +25,14 @@
#ifndef EQFILTER_H
#define EQFILTER_H
#include <numbers>
#include "BasicFilters.h"
#include "lmms_math.h"
namespace lmms
{
///
/// \brief The EqFilter class.
/// A wrapper for the StereoBiQuad class, giving it freq, res, and gain controls.
@@ -185,7 +186,7 @@ public :
{
// calc intermediate
float w0 = numbers::tau_v<float> * m_freq / m_sampleRate;
float w0 = 2 * std::numbers::pi_v<float> * m_freq / m_sampleRate;
float c = std::cos(w0);
float s = std::sin(w0);
float alpha = s / ( 2 * m_res );
@@ -228,7 +229,7 @@ public :
{
// calc intermediate
float w0 = numbers::tau_v<float> * m_freq / m_sampleRate;
float w0 = 2 * std::numbers::pi_v<float> * m_freq / m_sampleRate;
float c = std::cos(w0);
float s = std::sin(w0);
float alpha = s / ( 2 * m_res );
@@ -268,12 +269,13 @@ public:
void calcCoefficents() override
{
using namespace std::numbers;
// calc intermediate
float w0 = numbers::tau_v<float> * m_freq / m_sampleRate;
float w0 = 2 * pi_v<float> * m_freq / m_sampleRate;
float c = std::cos(w0);
float s = std::sin(w0);
float A = fastPow10f(m_gain * 0.025);
float alpha = s * std::sinh(std::log(2.f) / 2 * m_bw * w0 / std::sin(w0));
float alpha = s * std::sinh(ln2 / 2 * m_bw * w0 / std::sin(w0));
//calc coefficents
float b0 = 1 + alpha * A;
@@ -332,7 +334,7 @@ public :
{
// calc intermediate
float w0 = numbers::tau_v<float> * m_freq / m_sampleRate;
float w0 = 2 * std::numbers::pi_v<float> * m_freq / m_sampleRate;
float c = std::cos(w0);
float s = std::sin(w0);
float A = fastPow10f(m_gain * 0.025);
@@ -369,7 +371,7 @@ public :
{
// calc intermediate
float w0 = numbers::tau_v<float> * m_freq / m_sampleRate;
float w0 = 2 * std::numbers::pi_v<float> * m_freq / m_sampleRate;
float c = std::cos(w0);
float s = std::sin(w0);
float A = fastPow10f(m_gain * 0.025);

View File

@@ -35,7 +35,6 @@
#include "AutomatableModel.h"
#include "EqCurve.h"
#include "EqParameterWidget.h"
#include "lmms_constants.h"
namespace lmms::gui
@@ -239,4 +238,4 @@ EqBand::EqBand() :
}
} // namespace lmms::gui
} // namespace lmms::gui

View File

@@ -23,6 +23,7 @@
#include "EqSpectrumView.h"
#include <cmath>
#include <numbers>
#include <QPainter>
#include <QPen>
@@ -31,7 +32,6 @@
#include "EqCurve.h"
#include "GuiApplication.h"
#include "MainWindow.h"
#include "lmms_constants.h"
namespace lmms
{
@@ -43,6 +43,7 @@ EqAnalyser::EqAnalyser() :
m_sampleRate ( 1 ),
m_active ( true )
{
using namespace std::numbers;
m_inProgress=false;
m_specBuf = ( fftwf_complex * ) fftwf_malloc( ( FFT_BUFFER_SIZE + 1 ) * sizeof( fftwf_complex ) );
m_fftPlan = fftwf_plan_dft_r2c_1d( FFT_BUFFER_SIZE*2, m_buffer, m_specBuf, FFTW_MEASURE );
@@ -56,9 +57,9 @@ EqAnalyser::EqAnalyser() :
for (auto i = std::size_t{0}; i < FFT_BUFFER_SIZE; i++)
{
m_fftWindow[i] = (a0 - a1 * std::cos(2 * numbers::pi_v<float> * i / ((float)FFT_BUFFER_SIZE - 1.0))
+ a2 * std::cos(4 * numbers::pi_v<float> * i / ((float)FFT_BUFFER_SIZE - 1.0))
- a3 * std::cos(6 * numbers::pi_v<float> * i / ((float)FFT_BUFFER_SIZE - 1.0)));
m_fftWindow[i] = a0 - a1 * std::cos(2 * pi_v<float> * i / static_cast<float>(FFT_BUFFER_SIZE - 1.0))
+ a2 * std::cos(4 * pi_v<float> * i / static_cast<float>(FFT_BUFFER_SIZE - 1.0))
- a3 * std::cos(6 * pi_v<float> * i / static_cast<float>(FFT_BUFFER_SIZE - 1.0));
}
clear();
}

View File

@@ -23,6 +23,9 @@
*/
#include "FlangerEffect.h"
#include <numbers>
#include "Engine.h"
#include "MonoDelay.h"
#include "QuadratureLfo.h"
@@ -94,7 +97,7 @@ Effect::ProcessStatus FlangerEffect::processImpl(SampleFrame* buf, const fpp_t f
float amplitude = m_flangerControls.m_lfoAmountModel.value() * Engine::audioEngine()->outputSampleRate();
bool invertFeedback = m_flangerControls.m_invertFeedbackModel.value();
m_lfo->setFrequency( 1.0/m_flangerControls.m_lfoFrequencyModel.value() );
m_lfo->setOffset(m_flangerControls.m_lfoPhaseModel.value() / 180 * numbers::pi);
m_lfo->setOffset(m_flangerControls.m_lfoPhaseModel.value() / 180 * std::numbers::pi);
m_lDelay->setFeedback( m_flangerControls.m_feedbackModel.value() );
m_rDelay->setFeedback( m_flangerControls.m_feedbackModel.value() );
auto dryS = std::array<sample_t, 2>{};
@@ -103,8 +106,8 @@ Effect::ProcessStatus FlangerEffect::processImpl(SampleFrame* buf, const fpp_t f
float leftLfo;
float rightLfo;
buf[f][0] += (fastRandf(2.0f) - 1.0f) * noise;
buf[f][1] += (fastRandf(2.0f) - 1.0f) * noise;
buf[f][0] += fastRand(-1.f, +1.f) * noise;
buf[f][1] += fastRand(-1.f, +1.f) * noise;
dryS[0] = buf[f][0];
dryS[1] = buf[f][1];
m_lfo->tick(&leftLfo, &rightLfo);

View File

@@ -26,6 +26,7 @@
#include <cmath>
#include "embed.h"
#include "lmms_math.h"
#include "plugin_export.h"
@@ -155,18 +156,15 @@ Effect::ProcessStatus GranularPitchShifterEffect::processImpl(SampleFrame* buf,
if (++m_timeSinceLastGrain >= m_nextWaitRandomization * waitMult)
{
m_timeSinceLastGrain = 0;
double randThing = fast_rand() * static_cast<double>(FAST_RAND_RATIO) * 2. - 1.;
auto randThing = fastRand<double>(-1.0, +1.0);
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() * FAST_RAND_RATIO * spray * m_sampleRate;
sprayResult[1] = linearInterpolate(
sprayResult[0],
fast_rand() * FAST_RAND_RATIO * spray * m_sampleRate,
spraySpread);
sprayResult[0] = fastRand(spray * m_sampleRate);
sprayResult[1] = std::lerp(sprayResult[0], fastRand(spray * m_sampleRate), spraySpread);
}
std::array<int, 2> readPoint;
@@ -271,7 +269,7 @@ void GranularPitchShifterEffect::changeSampleRate()
m_grainCount = 0;
m_grains.reserve(8);// arbitrary
m_dcCoeff = std::exp(-numbers::tau_v<float> * DcRemovalHz / m_sampleRate);
m_dcCoeff = std::exp(-2 * std::numbers::pi_v<float> * DcRemovalHz / m_sampleRate);
const double pitch = m_granularpitchshifterControls.m_pitchModel.value() * (1. / 12.);
const double pitchSpread = m_granularpitchshifterControls.m_pitchSpreadModel.value() * (1. / 24.);

View File

@@ -25,6 +25,8 @@
#ifndef LMMS_GRANULAR_PITCH_SHIFTER_EFFECT_H
#define LMMS_GRANULAR_PITCH_SHIFTER_EFFECT_H
#include <numbers>
#include "Effect.h"
#include "GranularPitchShifterControls.h"
@@ -118,12 +120,13 @@ private:
void setCoefs(float sampleRate, float cutoff)
{
const float g = std::tan(numbers::pi_v<float> * cutoff / sampleRate);
const float ginv = g / (1.f + g * (g + numbers::sqrt2_v<float>));
m_g1 = ginv;
m_g2 = 2.f * (g + numbers::sqrt2_v<float>) * ginv;
m_g3 = g * ginv;
m_g4 = 2.f * ginv;
using namespace std::numbers;
const float g = std::tan(pi_v<float> * cutoff / sampleRate);
const float ginv = g / (1.f + g * (g + sqrt2_v<float>));
m_g1 = ginv;
m_g2 = 2 * (g + sqrt2_v<float>) * ginv;
m_g3 = g * ginv;
m_g4 = 2 * ginv;
}
float process(float input)

View File

@@ -26,11 +26,12 @@
#ifndef KICKER_OSC_H
#define KICKER_OSC_H
#include <cmath>
#include "DspEffectLibrary.h"
#include "Oscillator.h"
#include "lmms_math.h"
#include "interpolation.h"
namespace lmms
{
@@ -72,7 +73,7 @@ public:
// update distortion envelope if necessary
if( m_hasDistEnv && m_counter < m_length )
{
float thres = linearInterpolate( m_distStart, m_distEnd, m_counter / m_length );
float thres = std::lerp(m_distStart, m_distEnd, m_counter / m_length);
m_FX.leftFX().setThreshold( thres );
m_FX.rightFX().setThreshold( thres );
}

View File

@@ -24,6 +24,7 @@
#include "LOMM.h"
#include "lmms_math.h"
#include "embed.h"
#include "plugin_export.h"
@@ -312,11 +313,11 @@ Effect::ProcessStatus LOMMEffect::processImpl(SampleFrame* buf, const fpp_t fram
{
if (downward * depth <= 1)
{
aboveGain = linearInterpolate(yDbfs, aboveGain, downward * depth);
aboveGain = std::lerp(yDbfs, aboveGain, downward * depth);
}
else
{
aboveGain = linearInterpolate(aboveGain, aThresh[j], downward * depth - 1);
aboveGain = std::lerp(aboveGain, aThresh[j], downward * depth - 1);
}
}
@@ -338,11 +339,11 @@ Effect::ProcessStatus LOMMEffect::processImpl(SampleFrame* buf, const fpp_t fram
{
if (upward * depth <= 1)
{
belowGain = linearInterpolate(yDbfs, belowGain, upward * depth);
belowGain = std::lerp(yDbfs, belowGain, upward * depth);
}
else
{
belowGain = linearInterpolate(belowGain, bThresh[j], upward * depth - 1);
belowGain = std::lerp(belowGain, bThresh[j], upward * depth - 1);
}
}
@@ -396,12 +397,12 @@ Effect::ProcessStatus LOMMEffect::processImpl(SampleFrame* buf, const fpp_t fram
bands[j][i] *= outBandVol[j];
bands[j][i] = linearInterpolate(bandsDry[j][i], bands[j][i], mix);
bands[j][i] = std::lerp(bandsDry[j][i], bands[j][i], mix);
}
s[i] = bands[0][i] + bands[1][i] + bands[2][i];
s[i] *= linearInterpolate(1.f, outVol, mix * (depthScaling ? depth : 1));
s[i] *= std::lerp(1.f, outVol, mix * (depthScaling ? depth : 1));
}
// Convert mid/side back to left/right.

View File

@@ -30,7 +30,6 @@
#include "Effect.h"
#include "BasicFilters.h"
#include "lmms_math.h"
namespace lmms
{

View File

@@ -22,11 +22,10 @@
*
*/
#include "Monstro.h"
#include <QDomElement>
#include "Monstro.h"
#include "ComboBox.h"
#include "Engine.h"
#include "InstrumentTrack.h"
@@ -34,7 +33,6 @@
#include "interpolation.h"
#include "embed.h"
#include "plugin_export.h"
namespace lmms
@@ -625,8 +623,8 @@ void MonstroSynth::renderOutput( fpp_t _frames, SampleFrame* _buf )
sub = qBound( 0.0f, sub, 1.0f );
}
sample_t O3L = linearInterpolate( O3AL, O3BL, sub );
sample_t O3R = linearInterpolate( O3AR, O3BR, sub );
sample_t O3L = std::lerp(O3AL, O3BL, sub);
sample_t O3R = std::lerp(O3AR, O3BR, sub);
// modulate volume
O3L *= o3lv;
@@ -665,8 +663,8 @@ void MonstroSynth::renderOutput( fpp_t _frames, SampleFrame* _buf )
sample_t L = O1L + O3L + ( omod == MOD_MIX ? O2L : 0.0f );
sample_t R = O1R + O3R + ( omod == MOD_MIX ? O2R : 0.0f );
_buf[f][0] = linearInterpolate( L, m_l_last, m_parent->m_integrator );
_buf[f][1] = linearInterpolate( R, m_r_last, m_parent->m_integrator );
_buf[f][0] = std::lerp(L, m_l_last, m_parent->m_integrator);
_buf[f][1] = std::lerp(R, m_r_last, m_parent->m_integrator);
m_l_last = L;
m_r_last = R;

View File

@@ -26,6 +26,7 @@
#include "MultitapEcho.h"
#include "embed.h"
#include "lmms_basics.h"
#include "lmms_math.h"
#include "plugin_export.h"
namespace lmms

View File

@@ -54,7 +54,7 @@ private:
inline void setFilterFreq( float fc, StereoOnePole & f )
{
const float b1 = std::exp(-numbers::tau_v<float> * fc);
const float b1 = std::exp(-2 * std::numbers::pi_v<float> * fc);
f.setCoeffs( 1.0f - b1, b1 );
}

View File

@@ -29,7 +29,6 @@
#include "AudioEngine.h"
#include "Engine.h"
#include "InstrumentTrack.h"
#include "interpolation.h"
#include "Knob.h"
#include "Oscillator.h"
@@ -398,7 +397,7 @@ void NesObject::renderOutput( SampleFrame* buf, fpp_t frames )
pin1 = pin1 * 2.0f - 1.0f;
// simple first order iir filter, to simulate the frequency response falloff in nes analog audio output
pin1 = linearInterpolate( pin1, m_12Last, m_nsf );
pin1 = std::lerp(pin1, m_12Last, m_nsf);
m_12Last = pin1;
// compensate DC offset
@@ -416,7 +415,7 @@ void NesObject::renderOutput( SampleFrame* buf, fpp_t frames )
pin2 = pin2 * 2.0f - 1.0f;
// simple first order iir filter, to simulate the frequency response falloff in nes analog audio output
pin2 = linearInterpolate( pin2, m_34Last, m_nsf );
pin2 = std::lerp(pin2, m_34Last, m_nsf);
m_34Last = pin2;
// compensate DC offset

View File

@@ -34,7 +34,7 @@
#include "SampleLoader.h"
#include "Song.h"
#include "embed.h"
#include "lmms_constants.h"
#include "interpolation.h"
#include "plugin_export.h"
namespace lmms {
@@ -183,7 +183,7 @@ void SlicerT::findSlices()
for (auto i = std::size_t{0}; i < singleChannel.size(); i++)
{
singleChannel[i] /= maxMag;
if (sign(lastValue) != sign(singleChannel[i]))
if ((lastValue >= 0) != (singleChannel[i] >= 0))
{
zeroCrossings.push_back(i);
lastValue = singleChannel[i];

View File

@@ -41,6 +41,7 @@
#include "InstrumentTrack.h"
#include "embed.h"
#include "lmms_math.h"
#include "plugin_export.h"
namespace lmms
@@ -305,26 +306,26 @@ void MalletsInstrument::playNote( NotePlayHandle * _n,
if (p < 9)
{
hardness += random * (static_cast<float>(fast_rand() % 128) - 64.0);
hardness += random * fastRand(-64.f, +64.f);
hardness = std::clamp(hardness, 0.0f, 128.0f);
position += random * (static_cast<float>(fast_rand() % 64) - 32.0);
position += random * fastRand(-32.f, +32.f);
position = std::clamp(position, 0.0f, 64.0f);
}
else if (p == 9)
{
modulator += random * (static_cast<float>(fast_rand() % 128) - 64.0);
modulator += random * fastRand(-64.f, +64.f);
modulator = std::clamp(modulator, 0.0f, 128.0f);
crossfade += random * (static_cast<float>(fast_rand() % 128) - 64.0);
crossfade += random * fastRand(-64.f, +64.f);
crossfade = std::clamp(crossfade, 0.0f, 128.0f);
}
else
{
pressure += random * (static_cast<float>(fast_rand() % 128) - 64.0);
pressure += random * fastRand(-64.f, +64.f);
pressure = std::clamp(pressure, 0.0f, 128.0f);
speed += random * (static_cast<float>(fast_rand() % 128) - 64.0);
speed += random * fastRand(-64.f, +64.f);
speed = std::clamp(speed, 0.0f, 128.0f);
}

View File

@@ -32,7 +32,6 @@
#include "PixmapButton.h"
#include "Song.h"
#include "lmms_math.h"
#include "interpolation.h"
#include "embed.h"
#include "plugin_export.h"
@@ -122,12 +121,16 @@ void WatsynObject::renderOutput( fpp_t _frames )
///////////// A-series /////////////////
// A2
sample_t A2_L = linearInterpolate( m_A2wave[ static_cast<int>( m_lphase[A2_OSC] ) ],
m_A2wave[ static_cast<int>( m_lphase[A2_OSC] + 1 ) % WAVELEN ],
fraction( m_lphase[A2_OSC] ) ) * m_parent->m_lvol[A2_OSC];
sample_t A2_R = linearInterpolate( m_A2wave[ static_cast<int>( m_rphase[A2_OSC] ) ],
m_A2wave[ static_cast<int>( m_rphase[A2_OSC] + 1 ) % WAVELEN ],
fraction( m_rphase[A2_OSC] ) ) * m_parent->m_rvol[A2_OSC];
sample_t A2_L = m_parent->m_lvol[A2_OSC] * std::lerp(
m_A2wave[static_cast<int>(m_lphase[A2_OSC])],
m_A2wave[static_cast<int>(m_lphase[A2_OSC] + 1) % WAVELEN],
fraction(m_lphase[A2_OSC])
);
sample_t A2_R = m_parent->m_rvol[A2_OSC] * std::lerp(
m_A2wave[static_cast<int>(m_rphase[A2_OSC])],
m_A2wave[static_cast<int>(m_rphase[A2_OSC] + 1) % WAVELEN],
fraction(m_rphase[A2_OSC])
);
// if phase mod, add to phases
if( m_amod == MOD_PM )
@@ -138,22 +141,30 @@ void WatsynObject::renderOutput( fpp_t _frames )
if( A1_rphase < 0 ) A1_rphase += WAVELEN;
}
// A1
sample_t A1_L = linearInterpolate( m_A1wave[ static_cast<int>( A1_lphase ) ],
m_A1wave[ static_cast<int>( A1_lphase + 1 ) % WAVELEN ],
fraction( A1_lphase ) ) * m_parent->m_lvol[A1_OSC];
sample_t A1_R = linearInterpolate( m_A1wave[ static_cast<int>( A1_rphase ) ],
m_A1wave[ static_cast<int>( A1_rphase + 1 ) % WAVELEN ],
fraction( A1_rphase ) ) * m_parent->m_rvol[A1_OSC];
sample_t A1_L = m_parent->m_lvol[A1_OSC] * std::lerp(
m_A1wave[static_cast<int>(A1_lphase)],
m_A1wave[static_cast<int>(A1_lphase + 1) % WAVELEN],
fraction(A1_lphase)
);
sample_t A1_R = m_parent->m_rvol[A1_OSC] * std::lerp(
m_A1wave[static_cast<int>(A1_rphase)],
m_A1wave[static_cast<int>(A1_rphase + 1) % WAVELEN],
fraction(A1_rphase)
);
///////////// B-series /////////////////
// B2
sample_t B2_L = linearInterpolate( m_B2wave[ static_cast<int>( m_lphase[B2_OSC] ) ],
m_B2wave[ static_cast<int>( m_lphase[B2_OSC] + 1 ) % WAVELEN ],
fraction( m_lphase[B2_OSC] ) ) * m_parent->m_lvol[B2_OSC];
sample_t B2_R = linearInterpolate( m_B2wave[ static_cast<int>( m_rphase[B2_OSC] ) ],
m_B2wave[ static_cast<int>( m_rphase[B2_OSC] + 1 ) % WAVELEN ],
fraction( m_rphase[B2_OSC] ) ) * m_parent->m_rvol[B2_OSC];
sample_t B2_L = m_parent->m_lvol[B2_OSC] * std::lerp(
m_B2wave[static_cast<int>(m_lphase[B2_OSC])],
m_B2wave[static_cast<int>(m_lphase[B2_OSC] + 1) % WAVELEN],
fraction(m_lphase[B2_OSC])
);
sample_t B2_R = m_parent->m_rvol[B2_OSC] * std::lerp(
m_B2wave[static_cast<int>(m_rphase[B2_OSC])],
m_B2wave[static_cast<int>(m_rphase[B2_OSC] + 1) % WAVELEN],
fraction(m_rphase[B2_OSC])
);
// if crosstalk active, add a1
const float xt = m_parent->m_xtalk.value();
@@ -172,12 +183,16 @@ void WatsynObject::renderOutput( fpp_t _frames )
if( B1_rphase < 0 ) B1_rphase += WAVELEN;
}
// B1
sample_t B1_L = linearInterpolate( m_B1wave[ static_cast<int>( B1_lphase ) % WAVELEN ],
m_B1wave[ static_cast<int>( B1_lphase + 1 ) % WAVELEN ],
fraction( B1_lphase ) ) * m_parent->m_lvol[B1_OSC];
sample_t B1_R = linearInterpolate( m_B1wave[ static_cast<int>( B1_rphase ) % WAVELEN ],
m_B1wave[ static_cast<int>( B1_rphase + 1 ) % WAVELEN ],
fraction( B1_rphase ) ) * m_parent->m_rvol[B1_OSC];
sample_t B1_L = m_parent->m_lvol[B1_OSC] * std::lerp(
m_B1wave[static_cast<int>(B1_lphase) % WAVELEN],
m_B1wave[static_cast<int>(B1_lphase + 1) % WAVELEN],
fraction(B1_lphase)
);
sample_t B1_R = m_parent->m_rvol[B1_OSC] * std::lerp(
m_B1wave[static_cast<int>(B1_rphase) % WAVELEN],
m_B1wave[static_cast<int>(B1_rphase + 1) % WAVELEN],
fraction(B1_rphase)
);
// A-series modulation)

View File

@@ -27,7 +27,6 @@
#include "WaveShaper.h"
#include "lmms_math.h"
#include "embed.h"
#include "interpolation.h"
#include "plugin_export.h"
@@ -116,9 +115,7 @@ Effect::ProcessStatus WaveShaperEffect::processImpl(SampleFrame* buf, const fpp_
}
else if( lookup < 200 )
{
s[i] = linearInterpolate( samples[ lookup - 1 ],
samples[ lookup ], frac )
* posneg;
s[i] = std::lerp(samples[lookup - 1], samples[lookup], frac) * posneg;
}
else
{

View File

@@ -29,9 +29,8 @@
#include <vector>
#include <cmath>
#include <random>
#include <numbers>
#include "interpolation.h"
#include "lmms_math.h"
#include "NotePlayHandle.h"
#include "SampleFrame.h"
@@ -220,7 +219,7 @@ struct WaveValueFunctionInterpolate : public exprtk::ifunction<T>
const T x = positiveFraction(index) * m_size;
const int ix = (int)x;
const float xfrc = fraction(x);
return linearInterpolate(m_vec[ix], m_vec[(ix + 1) % m_size], xfrc);
return std::lerp(m_vec[ix], m_vec[(ix + 1) % m_size], xfrc);
}
const T *m_vec;
const std::size_t m_size;
@@ -413,7 +412,7 @@ struct sin_wave
static inline float process(float x)
{
x = positiveFraction(x);
return std::sin(x * numbers::tau_v<float>);
return std::sin(x * 2 * std::numbers::pi_v<float>);
}
};
static freefunc1<float,sin_wave,true> sin_wave_func;
@@ -535,7 +534,7 @@ ExprFront::ExprFront(const char * expr, int last_func_samples)
m_data->m_expression_string = expr;
m_data->m_symbol_table.add_pi();
m_data->m_symbol_table.add_constant("e", numbers::e_v<float>);
m_data->m_symbol_table.add_constant("e", std::numbers::e_v<float>);
m_data->m_symbol_table.add_constant("seed", SimpleRandom::generator() & max_float_integer_mask);

View File

@@ -40,8 +40,6 @@
#include "Song.h"
#include "base64.h"
#include "lmms_constants.h"
#include "embed.h"
#include "ExprSynth.h"
@@ -252,7 +250,8 @@ void Xpressive::smooth(float smoothness,const graphModel * in,graphModel * out)
const int guass_size = (int)(smoothness * 5) | 1;
const int guass_center = guass_size/2;
const float delta = smoothness;
const float a = 1.0f / (std::sqrt(numbers::tau_v<float>) * delta);
constexpr float inv_sqrt2pi = std::numbers::inv_sqrtpi_v<float> / std::numbers::sqrt2_v<float>;
const float a = inv_sqrt2pi / delta;
auto const guassian = new float[guass_size];
float sum = 0.0f;
float temp = 0.0f;