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:
@@ -64,6 +64,7 @@ QDataStream& operator>> ( QDataStream &in, WaveMipMap &waveMipMap )
|
||||
|
||||
void BandLimitedWave::generateWaves()
|
||||
{
|
||||
using namespace std::numbers;
|
||||
// don't generate if they already exist
|
||||
if( s_wavesGenerated ) return;
|
||||
|
||||
@@ -103,8 +104,8 @@ void BandLimitedWave::generateWaves()
|
||||
{
|
||||
hlen = static_cast<double>( len ) / static_cast<double>( harm );
|
||||
const double amp = -1.0 / static_cast<double>( harm );
|
||||
//const double a2 = std::cos(om * harm * numbers::tau_v<float>);
|
||||
s += amp * /*a2 **/ std::sin(static_cast<double>(ph * harm) / static_cast<double>(len) * numbers::tau_v<float>);
|
||||
//const double a2 = std::cos(om * harm * 2 * pi_v<float>);
|
||||
s += amp * /*a2 **/ std::sin(static_cast<double>(ph * harm) / static_cast<double>(len) * 2 * pi_v<float>);
|
||||
harm++;
|
||||
} while( hlen > 2.0 );
|
||||
s_waveforms[static_cast<std::size_t>(BandLimitedWave::Waveform::BLSaw)].setSampleAt( i, ph, s );
|
||||
@@ -145,8 +146,8 @@ void BandLimitedWave::generateWaves()
|
||||
{
|
||||
hlen = static_cast<double>( len ) / static_cast<double>( harm );
|
||||
const double amp = 1.0 / static_cast<double>( harm );
|
||||
//const double a2 = std::cos(om * harm * numbers::tau_v<float>);
|
||||
s += amp * /*a2 **/ std::sin(static_cast<double>(ph * harm) / static_cast<double>(len) * numbers::tau_v<float>);
|
||||
//const double a2 = std::cos(om * harm * 2 * pi_v<float>);
|
||||
s += amp * /*a2 **/ std::sin(static_cast<double>(ph * harm) / static_cast<double>(len) * 2 * pi_v<float>);
|
||||
harm += 2;
|
||||
} while( hlen > 2.0 );
|
||||
s_waveforms[static_cast<std::size_t>(BandLimitedWave::Waveform::BLSquare)].setSampleAt( i, ph, s );
|
||||
@@ -186,9 +187,9 @@ void BandLimitedWave::generateWaves()
|
||||
{
|
||||
hlen = static_cast<double>( len ) / static_cast<double>( harm );
|
||||
const double amp = 1.0 / static_cast<double>( harm * harm );
|
||||
//const double a2 = std::cos(om * harm * numbers::tau_v<float>);
|
||||
//const double a2 = std::cos(om * harm * 2 * pi_v<float>);
|
||||
s += amp * /*a2 **/ std::sin((static_cast<double>(ph * harm) / static_cast<double>(len) +
|
||||
((harm + 1) % 4 == 0 ? 0.5 : 0.0)) * numbers::tau_v<float>);
|
||||
((harm + 1) % 4 == 0 ? 0.5 : 0.0)) * 2 * pi_v<float>);
|
||||
harm += 2;
|
||||
} while( hlen > 2.0 );
|
||||
s_waveforms[static_cast<std::size_t>(BandLimitedWave::Waveform::BLTriangle)].setSampleAt( i, ph, s );
|
||||
|
||||
@@ -176,8 +176,7 @@ float DrumSynth::waveform(float ph, int form)
|
||||
// sine^2
|
||||
if (form == 1) { return std::abs(2.f * std::sin(0.5f * ph)) - 1.f; }
|
||||
// sawtooth with range [0, 1], used to generate triangle, sawtooth, and square
|
||||
auto ph_tau = ph / numbers::tau_v<float>;
|
||||
auto saw01 = ph_tau - std::floor(ph_tau);
|
||||
auto saw01 = absFraction(ph / (2 * std::numbers::pi_v<float>));
|
||||
// triangle
|
||||
if (form == 2) { return 1.f - 4.f * std::abs(saw01 - 0.5f); }
|
||||
// sawtooth
|
||||
@@ -304,6 +303,7 @@ float DrumSynth::GetPrivateProfileFloat(const char* sec, const char* key, float
|
||||
|
||||
int DrumSynth::GetDSFileSamples(QString dsfile, int16_t*& wave, int channels, sample_rate_t Fs)
|
||||
{
|
||||
using namespace std::numbers;
|
||||
// input file
|
||||
char sec[32];
|
||||
char ver[32];
|
||||
@@ -429,12 +429,12 @@ int DrumSynth::GetDSFileSamples(QString dsfile, int16_t*& wave, int channels, sa
|
||||
sliLev[0] = GetPrivateProfileInt(sec, "Level", 128, dsfile);
|
||||
TL = static_cast<float>(sliLev[0] * sliLev[0]) * mem_t;
|
||||
GetEnv(1, sec, "Envelope", dsfile);
|
||||
F1 = MasterTune * numbers::tau_v<float> * GetPrivateProfileFloat(sec, "F1", 200.0, dsfile) / Fs;
|
||||
F1 = MasterTune * 2 * pi_v<float> * GetPrivateProfileFloat(sec, "F1", 200.0, dsfile) / Fs;
|
||||
if (std::abs(F1) < 0.001f)
|
||||
{
|
||||
F1 = 0.001f; // to prevent overtone ratio div0
|
||||
}
|
||||
F2 = MasterTune * numbers::tau_v<float> * GetPrivateProfileFloat(sec, "F2", 120.0, dsfile) / Fs;
|
||||
F2 = MasterTune * 2 * pi_v<float> * GetPrivateProfileFloat(sec, "F2", 120.0, dsfile) / Fs;
|
||||
TDroopRate = GetPrivateProfileFloat(sec, "Droop", 0.f, dsfile);
|
||||
if (TDroopRate > 0.f)
|
||||
{
|
||||
@@ -460,8 +460,8 @@ int DrumSynth::GetDSFileSamples(QString dsfile, int16_t*& wave, int channels, sa
|
||||
GetEnv(3, sec, "Envelope1", dsfile);
|
||||
GetEnv(4, sec, "Envelope2", dsfile);
|
||||
OMode = GetPrivateProfileInt(sec, "Method", 2, dsfile);
|
||||
OF1 = MasterTune * numbers::tau_v<float> * GetPrivateProfileFloat(sec, "F1", 200.0, dsfile) / Fs;
|
||||
OF2 = MasterTune * numbers::tau_v<float> * GetPrivateProfileFloat(sec, "F2", 120.0, dsfile) / Fs;
|
||||
OF1 = MasterTune * 2 * pi_v<float> * GetPrivateProfileFloat(sec, "F1", 200.0, dsfile) / Fs;
|
||||
OF2 = MasterTune * 2 * pi_v<float> * GetPrivateProfileFloat(sec, "F2", 120.0, dsfile) / Fs;
|
||||
OW1 = GetPrivateProfileInt(sec, "Wave1", 0, dsfile);
|
||||
OW2 = GetPrivateProfileInt(sec, "Wave2", 0, dsfile);
|
||||
OBal2 = static_cast<float>(GetPrivateProfileInt(sec, "Param", 50, dsfile));
|
||||
@@ -489,8 +489,8 @@ int DrumSynth::GetDSFileSamples(QString dsfile, int16_t*& wave, int channels, sa
|
||||
OcQ = OcA * OcA;
|
||||
OcF = (1.8f - 0.7f * OcQ) * 0.92f; // multiply by env 2
|
||||
OcA *= 1.0f + 4.0f * OBal1; // level is a compromise!
|
||||
Ocf1 = numbers::tau_v<float> / OF1;
|
||||
Ocf2 = numbers::tau_v<float> / OF2;
|
||||
Ocf1 = 2 * pi_v<float> / OF1;
|
||||
Ocf2 = 2 * pi_v<float> / OF2;
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
Oc[i][0] = Oc[i][1] = Ocf1 + (Ocf2 - Ocf1) * 0.2f * static_cast<float>(i);
|
||||
@@ -502,8 +502,8 @@ int DrumSynth::GetDSFileSamples(QString dsfile, int16_t*& wave, int channels, sa
|
||||
BON = chkOn[3];
|
||||
sliLev[3] = GetPrivateProfileInt(sec, "Level", 128, dsfile);
|
||||
BL = static_cast<float>(sliLev[3] * sliLev[3]) * mem_b;
|
||||
BF = MasterTune * numbers::tau_v<float> * GetPrivateProfileFloat(sec, "F", 1000.0, dsfile) / Fs;
|
||||
BPhi = numbers::tau_v<float> / 8.f;
|
||||
BF = MasterTune * 2 * pi_v<float> * GetPrivateProfileFloat(sec, "F", 1000.0, dsfile) / Fs;
|
||||
BPhi = pi_v<float> / 4.f;
|
||||
GetEnv(5, sec, "Envelope", dsfile);
|
||||
BFStep = GetPrivateProfileInt(sec, "dF", 50, dsfile);
|
||||
BQ = static_cast<float>(BFStep);
|
||||
@@ -515,8 +515,8 @@ int DrumSynth::GetDSFileSamples(QString dsfile, int16_t*& wave, int channels, sa
|
||||
BON2 = chkOn[4];
|
||||
sliLev[4] = GetPrivateProfileInt(sec, "Level", 128, dsfile);
|
||||
BL2 = static_cast<float>(sliLev[4] * sliLev[4]) * mem_b;
|
||||
BF2 = MasterTune * numbers::tau_v<float> * GetPrivateProfileFloat(sec, "F", 1000.0, dsfile) / Fs;
|
||||
BPhi2 = numbers::tau_v<float> / 8.f;
|
||||
BF2 = MasterTune * 2 * pi_v<float> * GetPrivateProfileFloat(sec, "F", 1000.0, dsfile) / Fs;
|
||||
BPhi2 = pi_v<float> / 4.f;
|
||||
GetEnv(6, sec, "Envelope", dsfile);
|
||||
BFStep2 = GetPrivateProfileInt(sec, "dF", 50, dsfile);
|
||||
BQ2 = static_cast<float>(BFStep2);
|
||||
@@ -662,7 +662,7 @@ int DrumSynth::GetDSFileSamples(QString dsfile, int16_t*& wave, int channels, sa
|
||||
UpdateEnv(1, t);
|
||||
}
|
||||
Tphi = Tphi + phi[totmp];
|
||||
DF[totmp] += TL * envData[1][ENV] * std::sin(std::fmod(Tphi, numbers::tau_v<float>)); // overflow?
|
||||
DF[totmp] += TL * envData[1][ENV] * std::sin(Tphi); // overflow?
|
||||
}
|
||||
if (t >= envData[1][MAX])
|
||||
{
|
||||
@@ -695,7 +695,7 @@ int DrumSynth::GetDSFileSamples(QString dsfile, int16_t*& wave, int channels, sa
|
||||
}
|
||||
BPhi = BPhi + BF + BQ * BdF;
|
||||
botmp = t - tpos;
|
||||
DF[botmp] = DF[botmp] + std::cos(std::fmod(BPhi, numbers::tau_v<float>)) * envData[5][ENV] * BL;
|
||||
DF[botmp] = DF[botmp] + std::cos(BPhi) * envData[5][ENV] * BL;
|
||||
}
|
||||
if (t >= envData[5][MAX])
|
||||
{
|
||||
@@ -721,7 +721,7 @@ int DrumSynth::GetDSFileSamples(QString dsfile, int16_t*& wave, int channels, sa
|
||||
}
|
||||
BPhi2 = BPhi2 + BF2 + BQ2 * BdF2;
|
||||
botmp = t - tpos;
|
||||
DF[botmp] = DF[botmp] + std::cos(std::fmod(BPhi2, numbers::tau_v<float>)) * envData[6][ENV] * BL2;
|
||||
DF[botmp] = DF[botmp] + std::cos(BPhi2) * envData[6][ENV] * BL2;
|
||||
}
|
||||
if (t >= envData[6][MAX])
|
||||
{
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
#include "ConfigManager.h"
|
||||
#include "SampleFrame.h"
|
||||
#include "lmms_constants.h"
|
||||
#include "lmms_math.h"
|
||||
|
||||
namespace lmms
|
||||
{
|
||||
@@ -190,7 +190,7 @@ void Effect::checkGate(double outSum)
|
||||
|
||||
// Check whether we need to continue processing input. Restart the
|
||||
// counter if the threshold has been exceeded.
|
||||
if (outSum - gate() <= F_EPSILON)
|
||||
if (approximatelyEqual(outSum, gate()))
|
||||
{
|
||||
incrementBufferCount();
|
||||
if( bufferCount() > timeout() )
|
||||
|
||||
@@ -25,12 +25,11 @@
|
||||
#include "Instrument.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <numbers>
|
||||
|
||||
#include "DummyInstrument.h"
|
||||
#include "InstrumentTrack.h"
|
||||
#include "lmms_basics.h"
|
||||
#include "lmms_constants.h"
|
||||
|
||||
|
||||
namespace lmms
|
||||
{
|
||||
@@ -152,7 +151,7 @@ void Instrument::applyFadeIn(SampleFrame* buf, NotePlayHandle * n)
|
||||
{
|
||||
for (ch_cnt_t ch = 0; ch < DEFAULT_CHANNELS; ++ch)
|
||||
{
|
||||
buf[offset + f][ch] *= 0.5 - 0.5 * std::cos(numbers::pi_v<float> * (float) f / (float) n->m_fadeInLength);
|
||||
buf[offset + f][ch] *= 0.5 - 0.5 * std::cos(std::numbers::pi_v<float> * static_cast<float>(f) / static_cast<float>(n->m_fadeInLength));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -168,7 +167,7 @@ void Instrument::applyFadeIn(SampleFrame* buf, NotePlayHandle * n)
|
||||
for (ch_cnt_t ch = 0; ch < DEFAULT_CHANNELS; ++ch)
|
||||
{
|
||||
float currentLength = n->m_fadeInLength * (1.0f - (float) f / frames) + new_length * ((float) f / frames);
|
||||
buf[f][ch] *= 0.5 - 0.5 * std::cos(numbers::pi_v<float> * (float) (total + f) / currentLength);
|
||||
buf[f][ch] *= 0.5 - 0.5 * std::cos(std::numbers::pi_v<float> * static_cast<float>(total + f) / currentLength);
|
||||
if (total + f >= currentLength)
|
||||
{
|
||||
n->m_fadeInLength = currentLength;
|
||||
|
||||
@@ -26,12 +26,12 @@
|
||||
#include "NotePlayHandle.h"
|
||||
|
||||
#include "AudioEngine.h"
|
||||
#include "BasicFilters.h"
|
||||
#include "DetuningHelper.h"
|
||||
#include "InstrumentSoundShaping.h"
|
||||
#include "InstrumentTrack.h"
|
||||
#include "Instrument.h"
|
||||
#include "Song.h"
|
||||
#include "lmms_math.h"
|
||||
|
||||
namespace lmms
|
||||
{
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#if !defined(__MINGW32__) && !defined(__MINGW64__)
|
||||
#include <thread>
|
||||
#endif
|
||||
#include <numbers>
|
||||
|
||||
#include "BufferManager.h"
|
||||
#include "Engine.h"
|
||||
@@ -118,6 +119,7 @@ void Oscillator::update(SampleFrame* ab, const fpp_t frames, const ch_cnt_t chnl
|
||||
|
||||
void Oscillator::generateSawWaveTable(int bands, sample_t* table, int firstBand)
|
||||
{
|
||||
using namespace std::numbers;
|
||||
// sawtooth wave contain both even and odd harmonics
|
||||
// hence sinewaves are added for all bands
|
||||
// https://en.wikipedia.org/wiki/Sawtooth_wave
|
||||
@@ -127,7 +129,7 @@ void Oscillator::generateSawWaveTable(int bands, sample_t* table, int firstBand)
|
||||
const float imod = (i - OscillatorConstants::WAVETABLE_LENGTH / 2.f) / OscillatorConstants::WAVETABLE_LENGTH;
|
||||
for (int n = firstBand; n <= bands; n++)
|
||||
{
|
||||
table[i] += (n % 2 ? 1.0f : -1.0f) / n * std::sin(numbers::tau_v<float> * n * imod) / numbers::pi_half_v<float>;
|
||||
table[i] += (n % 2 ? 1.0f : -1.0f) / n * std::sin(2 * pi_v<float> * n * imod) / (pi_v<float> * 0.5f);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -135,6 +137,8 @@ void Oscillator::generateSawWaveTable(int bands, sample_t* table, int firstBand)
|
||||
|
||||
void Oscillator::generateTriangleWaveTable(int bands, sample_t* table, int firstBand)
|
||||
{
|
||||
using namespace std::numbers;
|
||||
constexpr float pi_sqr = pi_v<float> * pi_v<float>;
|
||||
// triangle waves contain only odd harmonics
|
||||
// hence sinewaves are added for alternate bands
|
||||
// https://en.wikipedia.org/wiki/Triangle_wave
|
||||
@@ -142,8 +146,8 @@ void Oscillator::generateTriangleWaveTable(int bands, sample_t* table, int first
|
||||
{
|
||||
for (int n = firstBand | 1; n <= bands; n += 2)
|
||||
{
|
||||
table[i] += (n & 2 ? -1.0f : 1.0f) / (n * n) *
|
||||
std::sin(numbers::tau_v<float> * n * i / (float)OscillatorConstants::WAVETABLE_LENGTH) / (numbers::pi_sqr_v<float> / 8.0f);
|
||||
table[i] += (n & 2 ? -1.0f : 1.0f) / (n * n)
|
||||
* std::sin(2 * pi_v<float> * n * i / (float)OscillatorConstants::WAVETABLE_LENGTH) / (pi_sqr / 8.f);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -151,6 +155,7 @@ void Oscillator::generateTriangleWaveTable(int bands, sample_t* table, int first
|
||||
|
||||
void Oscillator::generateSquareWaveTable(int bands, sample_t* table, int firstBand)
|
||||
{
|
||||
using namespace std::numbers;
|
||||
// square waves only contain odd harmonics,
|
||||
// at diffrent levels when compared to triangle waves
|
||||
// https://en.wikipedia.org/wiki/Square_wave
|
||||
@@ -159,8 +164,8 @@ void Oscillator::generateSquareWaveTable(int bands, sample_t* table, int firstBa
|
||||
for (int n = firstBand | 1; n <= bands; n += 2)
|
||||
{
|
||||
table[i] += (1.0f / n)
|
||||
* std::sin(numbers::tau_v<float> * i * n / OscillatorConstants::WAVETABLE_LENGTH)
|
||||
/ (numbers::pi_v<float> / 4);
|
||||
* std::sin(2 * pi_v<float> * i * n / OscillatorConstants::WAVETABLE_LENGTH)
|
||||
/ (pi_v<float> / 4.f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "ValueBuffer.h"
|
||||
|
||||
#include "interpolation.h"
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
namespace lmms
|
||||
{
|
||||
@@ -38,9 +39,7 @@ int ValueBuffer::length() const
|
||||
void ValueBuffer::interpolate(float start, float end_)
|
||||
{
|
||||
float i = 0;
|
||||
std::generate(begin(), end(), [&]() {
|
||||
return linearInterpolate( start, end_, i++ / length());
|
||||
});
|
||||
std::generate(begin(), end(), [&]() { return std::lerp(start, end_, i++ / length()); });
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#include "fft_helpers.h"
|
||||
|
||||
#include <cmath>
|
||||
#include "lmms_constants.h"
|
||||
#include <numbers>
|
||||
|
||||
namespace lmms
|
||||
{
|
||||
@@ -104,6 +104,7 @@ int notEmpty(const std::vector<float> &spectrum)
|
||||
*/
|
||||
int precomputeWindow(float *window, unsigned int length, FFTWindow type, bool normalized)
|
||||
{
|
||||
using namespace std::numbers;
|
||||
if (window == nullptr) {return -1;}
|
||||
|
||||
float gain = 0;
|
||||
@@ -144,9 +145,9 @@ int precomputeWindow(float *window, unsigned int length, FFTWindow type, bool no
|
||||
// common computation for cosine-sum based windows
|
||||
for (unsigned int i = 0; i < length; i++)
|
||||
{
|
||||
window[i] = (a0 - a1 * std::cos(2 * numbers::pi_v<float> * i / ((float)length - 1.0))
|
||||
+ a2 * std::cos(4 * numbers::pi_v<float> * i / ((float)length - 1.0))
|
||||
- a3 * std::cos(6 * numbers::pi_v<float> * i / ((float)length - 1.0)));
|
||||
window[i] = (a0 - a1 * std::cos(2 * pi_v<float> * i / (static_cast<float>(length) - 1.0))
|
||||
+ a2 * std::cos(4 * pi_v<float> * i / (static_cast<float>(length) - 1.0))
|
||||
- a3 * std::cos(6 * pi_v<float> * i / (static_cast<float>(length) - 1.0)));
|
||||
gain += window[i];
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "Knob.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <numbers>
|
||||
|
||||
#include "lmms_math.h"
|
||||
#include "DeprecationHelper.h"
|
||||
@@ -312,7 +313,7 @@ void Knob::setTextColor( const QColor & c )
|
||||
|
||||
QLineF Knob::calculateLine( const QPointF & _mid, float _radius, float _innerRadius ) const
|
||||
{
|
||||
const float rarc = m_angle * numbers::pi_v<float> / 180.0;
|
||||
const float rarc = m_angle * std::numbers::pi_v<float> / 180.0;
|
||||
const float ca = std::cos(rarc);
|
||||
const float sa = -std::sin(rarc);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user