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:
@@ -156,11 +156,11 @@ public:
|
||||
t += 1;
|
||||
const sample_t s3 = s_waveforms[ static_cast<std::size_t>(_wave) ].sampleAt( t, lookup );
|
||||
const sample_t s4 = s_waveforms[ static_cast<std::size_t>(_wave) ].sampleAt( t, ( lookup + 1 ) % tlen );
|
||||
const sample_t s34 = linearInterpolate( s3, s4, ip );
|
||||
const sample_t s34 = std::lerp(s3, s4, ip);
|
||||
|
||||
const float ip2 = ( ( tlen - _wavelen ) / tlen - 0.5 ) * 2.0;
|
||||
|
||||
return linearInterpolate( s12, s34, ip2 );
|
||||
return std::lerp(s12, s34, ip2);
|
||||
*/
|
||||
};
|
||||
|
||||
|
||||
@@ -31,12 +31,12 @@
|
||||
#ifndef LMMS_BASIC_FILTERS_H
|
||||
#define LMMS_BASIC_FILTERS_H
|
||||
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
#include <numbers>
|
||||
|
||||
#include "lmms_basics.h"
|
||||
#include "lmms_constants.h"
|
||||
#include "interpolation.h"
|
||||
|
||||
namespace lmms
|
||||
{
|
||||
@@ -69,21 +69,22 @@ public:
|
||||
|
||||
inline void setCoeffs( float freq )
|
||||
{
|
||||
using namespace std::numbers;
|
||||
// wc
|
||||
const double wc = numbers::tau * freq;
|
||||
const double wc = 2 * pi * freq;
|
||||
const double wc2 = wc * wc;
|
||||
const double wc3 = wc2 * wc;
|
||||
m_wc4 = wc2 * wc2;
|
||||
|
||||
// k
|
||||
const double k = wc / std::tan(numbers::pi * freq / m_sampleRate);
|
||||
const double k = wc / std::tan(pi * freq / m_sampleRate);
|
||||
const double k2 = k * k;
|
||||
const double k3 = k2 * k;
|
||||
m_k4 = k2 * k2;
|
||||
|
||||
// a
|
||||
const double sq_tmp1 = numbers::sqrt2 * wc3 * k;
|
||||
const double sq_tmp2 = numbers::sqrt2 * wc * k3;
|
||||
const double sq_tmp1 = sqrt2 * wc3 * k;
|
||||
const double sq_tmp2 = sqrt2 * wc * k3;
|
||||
|
||||
m_a = 1.0 / ( 4.0 * wc2 * k2 + 2.0 * sq_tmp1 + m_k4 + 2.0 * sq_tmp2 + m_wc4 );
|
||||
|
||||
@@ -206,7 +207,7 @@ public:
|
||||
|
||||
inline float update( float s, ch_cnt_t ch )
|
||||
{
|
||||
if (std::abs(s) < 1.0e-10f && std::abs(m_z1[ch]) < 1.0e-10f) return 0.0f;
|
||||
if (std::abs(s) < 1.0e-10f && std::abs(m_z1[ch]) < 1.0e-10f) { return 0.0f; }
|
||||
return m_z1[ch] = s * m_a0 + m_z1[ch] * m_b1;
|
||||
}
|
||||
|
||||
@@ -375,7 +376,7 @@ public:
|
||||
for( int i = 0; i < 4; ++i )
|
||||
{
|
||||
ip += 0.25f;
|
||||
sample_t x = linearInterpolate( m_last[_chnl], _in0, ip ) - m_r * m_y3[_chnl];
|
||||
sample_t x = std::lerp(m_last[_chnl], _in0, ip) - m_r * m_y3[_chnl];
|
||||
|
||||
m_y1[_chnl] = std::clamp((x + m_oldx[_chnl]) * m_p
|
||||
- m_k * m_y1[_chnl], -10.0f,
|
||||
@@ -701,6 +702,7 @@ public:
|
||||
|
||||
inline void calcFilterCoeffs( float _freq, float _q )
|
||||
{
|
||||
using namespace std::numbers;
|
||||
// temp coef vars
|
||||
_q = std::max(_q, minQ());
|
||||
|
||||
@@ -713,7 +715,7 @@ public:
|
||||
{
|
||||
_freq = std::clamp(_freq, 50.0f, 20000.0f);
|
||||
const float sr = m_sampleRatio * 0.25f;
|
||||
const float f = 1.0f / (_freq * numbers::tau_v<float>);
|
||||
const float f = 1.0f / (_freq * 2 * pi_v<float>);
|
||||
|
||||
m_rca = 1.0f - sr / ( f + sr );
|
||||
m_rcb = 1.0f - m_rca;
|
||||
@@ -746,8 +748,8 @@ public:
|
||||
const float fract = vowelf - vowel;
|
||||
|
||||
// interpolate between formant frequencies
|
||||
const float f0 = 1.0f / (linearInterpolate(_f[vowel+0][0], _f[vowel+1][0], fract) * numbers::tau_v<float>);
|
||||
const float f1 = 1.0f / (linearInterpolate(_f[vowel+0][1], _f[vowel+1][1], fract) * numbers::tau_v<float>);
|
||||
const float f0 = 1.f / (std::lerp(_f[vowel+0][0], _f[vowel+1][0], fract) * 2 * pi_v<float>);
|
||||
const float f1 = 1.f / (std::lerp(_f[vowel+0][1], _f[vowel+1][1], fract) * 2 * pi_v<float>);
|
||||
|
||||
// samplerate coeff: depends on oversampling
|
||||
const float sr = m_type == FilterType::FastFormant ? m_sampleRatio : m_sampleRatio * 0.25f;
|
||||
@@ -796,7 +798,7 @@ public:
|
||||
m_type == FilterType::Highpass_SV ||
|
||||
m_type == FilterType::Notch_SV )
|
||||
{
|
||||
const float f = std::sin(std::max(minFreq(), _freq) * m_sampleRatio * numbers::pi_v<float>);
|
||||
const float f = std::sin(std::max(minFreq(), _freq) * m_sampleRatio * pi_v<float>);
|
||||
m_svf1 = std::min(f, 0.825f);
|
||||
m_svf2 = std::min(f * 2.0f, 0.825f);
|
||||
m_svq = std::max(0.0001f, 2.0f - (_q * 0.1995f));
|
||||
@@ -805,7 +807,7 @@ public:
|
||||
|
||||
// other filters
|
||||
_freq = std::clamp(_freq, minFreq(), 20000.0f);
|
||||
const float omega = numbers::tau_v<float> * _freq * m_sampleRatio;
|
||||
const float omega = 2 * pi_v<float> * _freq * m_sampleRatio;
|
||||
const float tsin = std::sin(omega) * 0.5f;
|
||||
const float tcos = std::cos(omega);
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#ifndef LMMS_GUI_COLOR_HELPER_H
|
||||
#define LMMS_GUI_COLOR_HELPER_H
|
||||
|
||||
#include <cmath>
|
||||
#include <QColor>
|
||||
|
||||
namespace lmms::gui
|
||||
@@ -40,10 +41,11 @@ public:
|
||||
qreal br, bg, bb, ba;
|
||||
b.getRgbF(&br, &bg, &bb, &ba);
|
||||
|
||||
const float interH = lerp(ar, br, t);
|
||||
const float interS = lerp(ag, bg, t);
|
||||
const float interV = lerp(ab, bb, t);
|
||||
const float interA = lerp(aa, ba, t);
|
||||
const auto t2 = static_cast<qreal>(t);
|
||||
const float interH = std::lerp(ar, br, t2);
|
||||
const float interS = std::lerp(ag, bg, t2);
|
||||
const float interV = std::lerp(ab, bb, t2);
|
||||
const float interA = std::lerp(aa, ba, t2);
|
||||
|
||||
return QColor::fromRgbF(interH, interS, interV, interA);
|
||||
}
|
||||
|
||||
@@ -26,9 +26,9 @@
|
||||
#ifndef LMMS_DELAY_H
|
||||
#define LMMS_DELAY_H
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "lmms_basics.h"
|
||||
#include "lmms_math.h"
|
||||
#include "interpolation.h"
|
||||
|
||||
namespace lmms
|
||||
{
|
||||
@@ -114,7 +114,7 @@ public:
|
||||
int readPos = m_position - m_delay;
|
||||
if( readPos < 0 ) { readPos += m_size; }
|
||||
|
||||
const double y = linearInterpolate( m_buffer[readPos][ch], m_buffer[( readPos + 1 ) % m_size][ch], m_fraction );
|
||||
const double y = std::lerp(m_buffer[readPos][ch], m_buffer[(readPos + 1) % m_size][ch], m_fraction);
|
||||
|
||||
++m_position %= m_size;
|
||||
|
||||
@@ -185,7 +185,7 @@ class CombFeedfwd
|
||||
int readPos = m_position - m_delay;
|
||||
if( readPos < 0 ) { readPos += m_size; }
|
||||
|
||||
const double y = linearInterpolate( m_buffer[readPos][ch], m_buffer[( readPos + 1 ) % m_size][ch], m_fraction ) + in * m_gain;
|
||||
const double y = std::lerp(m_buffer[readPos][ch], m_buffer[(readPos + 1) % m_size][ch], m_fraction) + in * m_gain;
|
||||
|
||||
++m_position %= m_size;
|
||||
|
||||
@@ -262,8 +262,8 @@ class CombFeedbackDualtap
|
||||
int readPos2 = m_position - m_delay2;
|
||||
if( readPos2 < 0 ) { readPos2 += m_size; }
|
||||
|
||||
const double y = linearInterpolate( m_buffer[readPos1][ch], m_buffer[( readPos1 + 1 ) % m_size][ch], m_fraction1 ) +
|
||||
linearInterpolate( m_buffer[readPos2][ch], m_buffer[( readPos2 + 1 ) % m_size][ch], m_fraction2 );
|
||||
const double y = std::lerp(m_buffer[readPos1][ch], m_buffer[(readPos1 + 1) % m_size][ch], m_fraction1)
|
||||
+ std::lerp(m_buffer[readPos2][ch], m_buffer[(readPos2 + 1) % m_size][ch], m_fraction2);
|
||||
|
||||
++m_position %= m_size;
|
||||
|
||||
@@ -337,7 +337,7 @@ public:
|
||||
int readPos = m_position - m_delay;
|
||||
if( readPos < 0 ) { readPos += m_size; }
|
||||
|
||||
const double y = linearInterpolate( m_buffer[readPos][ch], m_buffer[( readPos + 1 ) % m_size][ch], m_fraction ) + in * -m_gain;
|
||||
const double y = std::lerp(m_buffer[readPos][ch], m_buffer[(readPos + 1) % m_size][ch], m_fraction) + in * -m_gain;
|
||||
const double x = in + m_gain * y;
|
||||
|
||||
++m_position %= m_size;
|
||||
|
||||
@@ -25,8 +25,9 @@
|
||||
#ifndef LMMS_DSPEFFECTLIBRARY_H
|
||||
#define LMMS_DSPEFFECTLIBRARY_H
|
||||
|
||||
#include <numbers>
|
||||
|
||||
#include "lmms_math.h"
|
||||
#include "lmms_constants.h"
|
||||
#include "lmms_basics.h"
|
||||
#include "SampleFrame.h"
|
||||
|
||||
@@ -328,7 +329,7 @@ namespace lmms::DspEffectLibrary
|
||||
|
||||
void nextSample( sample_t& inLeft, sample_t& inRight )
|
||||
{
|
||||
const float toRad = numbers::pi_v<float> / 180;
|
||||
constexpr float toRad = std::numbers::pi_v<float> / 180.f;
|
||||
const sample_t tmp = inLeft;
|
||||
inLeft += inRight * std::sin(m_wideCoeff * toRad * .5f);
|
||||
inRight -= tmp * std::sin(m_wideCoeff * toRad * .5f);
|
||||
|
||||
@@ -30,10 +30,10 @@
|
||||
#include <fftw3.h>
|
||||
#include <memory>
|
||||
#include <cstdlib>
|
||||
#include "interpolation.h"
|
||||
#include <cmath>
|
||||
|
||||
#include "Engine.h"
|
||||
#include "lmms_constants.h"
|
||||
#include "lmms_math.h"
|
||||
#include "lmmsconfig.h"
|
||||
#include "AudioEngine.h"
|
||||
#include "OscillatorConstants.h"
|
||||
@@ -114,7 +114,7 @@ public:
|
||||
// now follow the wave-shape-routines...
|
||||
static inline sample_t sinSample( const float _sample )
|
||||
{
|
||||
return std::sin(_sample * numbers::tau_v<float>);
|
||||
return std::sin(_sample * 2 * std::numbers::pi_v<float>);
|
||||
}
|
||||
|
||||
static inline sample_t triangleSample( const float _sample )
|
||||
@@ -173,7 +173,7 @@ public:
|
||||
const auto frame = absFraction(sample) * frames;
|
||||
const auto f1 = static_cast<f_cnt_t>(frame);
|
||||
|
||||
return linearInterpolate(buffer->data()[f1][0], buffer->data()[(f1 + 1) % frames][0], fraction(frame));
|
||||
return std::lerp(buffer->data()[f1][0], buffer->data()[(f1 + 1) % frames][0], fraction(frame));
|
||||
}
|
||||
|
||||
struct wtSampleControl {
|
||||
@@ -202,24 +202,25 @@ public:
|
||||
{
|
||||
assert(table != nullptr);
|
||||
wtSampleControl control = getWtSampleControl(sample);
|
||||
return linearInterpolate(table[control.band][control.f1],
|
||||
table[control.band][control.f2], fraction(control.frame));
|
||||
return std::lerp(table[control.band][control.f1], table[control.band][control.f2], fraction(control.frame));
|
||||
}
|
||||
|
||||
sample_t wtSample(const OscillatorConstants::waveform_t* table, const float sample) const
|
||||
{
|
||||
assert(table != nullptr);
|
||||
wtSampleControl control = getWtSampleControl(sample);
|
||||
return linearInterpolate((*table)[control.band][control.f1],
|
||||
(*table)[control.band][control.f2], fraction(control.frame));
|
||||
return std::lerp(
|
||||
(*table)[control.band][control.f1],
|
||||
(*table)[control.band][control.f2],
|
||||
fraction(control.frame)
|
||||
);
|
||||
}
|
||||
|
||||
inline sample_t wtSample(sample_t **table, const float sample) const
|
||||
{
|
||||
assert(table != nullptr);
|
||||
wtSampleControl control = getWtSampleControl(sample);
|
||||
return linearInterpolate(table[control.band][control.f1],
|
||||
table[control.band][control.f2], fraction(control.frame));
|
||||
return std::lerp(table[control.band][control.f1], table[control.band][control.f2], fraction(control.frame));
|
||||
}
|
||||
|
||||
static inline int waveTableBandFromFreq(float freq)
|
||||
|
||||
@@ -25,7 +25,8 @@
|
||||
#ifndef LMMS_QUADRATURE_LFO_H
|
||||
#define LMMS_QUADRATURE_LFO_H
|
||||
|
||||
#include "lmms_math.h"
|
||||
#include <numbers>
|
||||
#include <cmath>
|
||||
|
||||
namespace lmms
|
||||
{
|
||||
@@ -37,7 +38,7 @@ public:
|
||||
QuadratureLfo( int sampleRate ) :
|
||||
m_frequency(0),
|
||||
m_phase(0),
|
||||
m_offset(numbers::pi_half)
|
||||
m_offset(std::numbers::pi * 0.5)
|
||||
{
|
||||
setSampleRate(sampleRate);
|
||||
}
|
||||
@@ -64,7 +65,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;
|
||||
}
|
||||
|
||||
@@ -80,7 +81,7 @@ public:
|
||||
*l = std::sin(m_phase);
|
||||
*r = std::sin(m_phase + m_offset);
|
||||
m_phase += m_increment;
|
||||
while (m_phase >= numbers::tau) { m_phase -= numbers::tau; }
|
||||
m_phase = std::fmod(m_phase, 2 * std::numbers::pi);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -26,8 +26,7 @@
|
||||
#define LMMS_INTERPOLATION_H
|
||||
|
||||
#include <cmath>
|
||||
#include "lmms_constants.h"
|
||||
#include "lmms_math.h"
|
||||
#include <numbers>
|
||||
|
||||
namespace lmms
|
||||
{
|
||||
@@ -78,17 +77,11 @@ inline float cubicInterpolate( float v0, float v1, float v2, float v3, float x )
|
||||
|
||||
inline float cosinusInterpolate( float v0, float v1, float x )
|
||||
{
|
||||
const float f = (1.0f - std::cos(x * numbers::pi_v<float>)) * 0.5f;
|
||||
const float f = (1.0f - std::cos(x * std::numbers::pi_v<float>)) * 0.5f;
|
||||
return f * (v1 - v0) + v0;
|
||||
}
|
||||
|
||||
|
||||
inline float linearInterpolate( float v0, float v1, float x )
|
||||
{
|
||||
return x * (v1 - v0) + v0;
|
||||
}
|
||||
|
||||
|
||||
inline float optimalInterpolate( float v0, float v1, float x )
|
||||
{
|
||||
const float z = x - 0.5f;
|
||||
|
||||
@@ -25,65 +25,20 @@
|
||||
#ifndef LMMS_CONSTANTS_H
|
||||
#define LMMS_CONSTANTS_H
|
||||
|
||||
// #include <numbers>
|
||||
// #include <concepts>
|
||||
|
||||
namespace lmms::numbers
|
||||
{
|
||||
|
||||
//TODO C++20: Use std::floating_point instead of typename
|
||||
//TODO C++20: Use std::numbers::pi_v<T> instead of literal value
|
||||
template<typename T>
|
||||
inline constexpr T pi_v = T(3.14159265358979323846264338327950288419716939937510);
|
||||
inline constexpr double pi = pi_v<double>;
|
||||
|
||||
//TODO C++20: Use std::floating_point instead of typename
|
||||
template<typename T>
|
||||
inline constexpr T tau_v = T(pi_v<T> * 2.0);
|
||||
inline constexpr double tau = tau_v<double>;
|
||||
|
||||
//TODO C++20: Use std::floating_point instead of typename
|
||||
template<typename T>
|
||||
inline constexpr T pi_half_v = T(pi_v<T> / 2.0);
|
||||
inline constexpr double pi_half = pi_half_v<double>;
|
||||
|
||||
//TODO C++20: Use std::floating_point instead of typename
|
||||
template<typename T>
|
||||
inline constexpr T pi_sqr_v = T(pi_v<T> * pi_v<T>);
|
||||
inline constexpr double pi_sqr = pi_sqr_v<double>;
|
||||
|
||||
//TODO C++20: Use std::floating_point instead of typename
|
||||
//TODO C++20: Use std::numbers::e_v<T> instead of literal value
|
||||
template<typename T>
|
||||
inline constexpr T e_v = T(2.71828182845904523536028747135266249775724709369995);
|
||||
inline constexpr double e = e_v<double>;
|
||||
|
||||
//TODO C++20: Use std::floating_point instead of typename
|
||||
template<typename T>
|
||||
inline constexpr T inv_e_v = T(1.0 / e_v<T>);
|
||||
inline constexpr double inv_e = e_v<double>;
|
||||
|
||||
//TODO C++20: Use std::floating_point instead of typename
|
||||
//TODO C++20: Use std::numbers::sqrt2_v<T> instead of literal value
|
||||
//TODO C++26: Remove since std::sqrt(2.0) is constexpr
|
||||
template<typename T>
|
||||
inline constexpr T sqrt2_v = T(1.41421356237309504880168872420969807856967187537695);
|
||||
inline constexpr double sqrt2 = sqrt2_v<double>;
|
||||
|
||||
}
|
||||
|
||||
namespace lmms
|
||||
{
|
||||
|
||||
constexpr float F_EPSILON = 1.0e-10f; // 10^-10
|
||||
// Prefer using `approximatelyEqual()` from lmms_math.h rather than
|
||||
// using this directly
|
||||
inline constexpr float F_EPSILON = 1.0e-10f; // 10^-10
|
||||
|
||||
// Microtuner
|
||||
constexpr unsigned int MaxScaleCount = 10; //!< number of scales per project
|
||||
constexpr unsigned int MaxKeymapCount = 10; //!< number of keyboard mappings per project
|
||||
inline constexpr unsigned MaxScaleCount = 10; //!< number of scales per project
|
||||
inline constexpr unsigned MaxKeymapCount = 10; //!< number of keyboard mappings per project
|
||||
|
||||
// Frequency ranges (in Hz).
|
||||
// Arbitrary low limit for logarithmic frequency scale; >1 Hz.
|
||||
constexpr int LOWEST_LOG_FREQ = 5;
|
||||
inline constexpr auto LOWEST_LOG_FREQ = 5;
|
||||
|
||||
// Full range is defined by LOWEST_LOG_FREQ and current sample rate.
|
||||
enum class FrequencyRange
|
||||
@@ -95,14 +50,14 @@ enum class FrequencyRange
|
||||
High
|
||||
};
|
||||
|
||||
constexpr int FRANGE_AUDIBLE_START = 20;
|
||||
constexpr int FRANGE_AUDIBLE_END = 20000;
|
||||
constexpr int FRANGE_BASS_START = 20;
|
||||
constexpr int FRANGE_BASS_END = 300;
|
||||
constexpr int FRANGE_MIDS_START = 200;
|
||||
constexpr int FRANGE_MIDS_END = 5000;
|
||||
constexpr int FRANGE_HIGH_START = 4000;
|
||||
constexpr int FRANGE_HIGH_END = 20000;
|
||||
inline constexpr auto FRANGE_AUDIBLE_START = 20;
|
||||
inline constexpr auto FRANGE_AUDIBLE_END = 20000;
|
||||
inline constexpr auto FRANGE_BASS_START = 20;
|
||||
inline constexpr auto FRANGE_BASS_END = 300;
|
||||
inline constexpr auto FRANGE_MIDS_START = 200;
|
||||
inline constexpr auto FRANGE_MIDS_END = 5000;
|
||||
inline constexpr auto FRANGE_HIGH_START = 4000;
|
||||
inline constexpr auto FRANGE_HIGH_END = 20000;
|
||||
|
||||
// Amplitude ranges (in dBFS).
|
||||
// Reference: full scale sine wave (-1.0 to 1.0) is 0 dB.
|
||||
@@ -115,15 +70,14 @@ enum class AmplitudeRange
|
||||
Silent
|
||||
};
|
||||
|
||||
constexpr int ARANGE_EXTENDED_START = -80;
|
||||
constexpr int ARANGE_EXTENDED_END = 20;
|
||||
constexpr int ARANGE_AUDIBLE_START = -50;
|
||||
constexpr int ARANGE_AUDIBLE_END = 0;
|
||||
constexpr int ARANGE_LOUD_START = -30;
|
||||
constexpr int ARANGE_LOUD_END = 0;
|
||||
constexpr int ARANGE_SILENT_START = -60;
|
||||
constexpr int ARANGE_SILENT_END = -10;
|
||||
|
||||
inline constexpr auto ARANGE_EXTENDED_START = -80;
|
||||
inline constexpr auto ARANGE_EXTENDED_END = 20;
|
||||
inline constexpr auto ARANGE_AUDIBLE_START = -50;
|
||||
inline constexpr auto ARANGE_AUDIBLE_END = 0;
|
||||
inline constexpr auto ARANGE_LOUD_START = -30;
|
||||
inline constexpr auto ARANGE_LOUD_END = 0;
|
||||
inline constexpr auto ARANGE_SILENT_START = -60;
|
||||
inline constexpr auto ARANGE_SILENT_END = -10;
|
||||
|
||||
} // namespace lmms
|
||||
|
||||
|
||||
@@ -31,18 +31,22 @@
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <numbers>
|
||||
#include <concepts>
|
||||
|
||||
#include "lmms_constants.h"
|
||||
#include "lmmsconfig.h"
|
||||
#include "lmms_constants.h"
|
||||
|
||||
namespace lmms
|
||||
{
|
||||
|
||||
inline bool approximatelyEqual(float x, float y)
|
||||
// TODO C++23: Make constexpr since std::abs() will be constexpr
|
||||
inline bool approximatelyEqual(float x, float y) noexcept
|
||||
{
|
||||
return x == y ? true : std::abs(x - y) < F_EPSILON;
|
||||
return x == y || std::abs(x - y) < F_EPSILON;
|
||||
}
|
||||
|
||||
// TODO C++23: Make constexpr since std::trunc() will be constexpr
|
||||
/*!
|
||||
* @brief Returns the fractional part of a float, a value between -1.0f and 1.0f.
|
||||
*
|
||||
@@ -52,11 +56,13 @@ inline bool approximatelyEqual(float x, float y)
|
||||
* Note that if the return value is used as a phase of an oscillator, that the oscillator must support
|
||||
* negative phases.
|
||||
*/
|
||||
inline float fraction(const float x)
|
||||
inline auto fraction(std::floating_point auto x) noexcept
|
||||
{
|
||||
return x - std::trunc(x);
|
||||
}
|
||||
|
||||
|
||||
// TODO C++23: Make constexpr since std::floor() will be constexpr
|
||||
/*!
|
||||
* @brief Returns the wrapped fractional part of a float, a value between 0.0f and 1.0f.
|
||||
*
|
||||
@@ -67,25 +73,30 @@ inline float fraction(const float x)
|
||||
* If the result is interpreted as a phase of an oscillator, it makes that negative phases are
|
||||
* converted to positive phases.
|
||||
*/
|
||||
inline float absFraction(const float x)
|
||||
inline auto absFraction(std::floating_point auto x) noexcept
|
||||
{
|
||||
return x - std::floor(x);
|
||||
}
|
||||
|
||||
|
||||
constexpr float FAST_RAND_RATIO = 1.0f / 32767;
|
||||
inline int fast_rand()
|
||||
inline auto fastRand() noexcept
|
||||
{
|
||||
static unsigned long next = 1;
|
||||
next = next * 1103515245 + 12345;
|
||||
return( (unsigned)( next / 65536 ) % 32768 );
|
||||
return next / 65536 % 32768;
|
||||
}
|
||||
|
||||
inline float fastRandf(float range)
|
||||
template<std::floating_point T>
|
||||
inline auto fastRand(T range) noexcept
|
||||
{
|
||||
return fast_rand() * range * FAST_RAND_RATIO;
|
||||
constexpr T FAST_RAND_RATIO = static_cast<T>(1.0 / 32767);
|
||||
return fastRand() * range * FAST_RAND_RATIO;
|
||||
}
|
||||
|
||||
template<std::floating_point T>
|
||||
inline auto fastRand(T from, T to) noexcept
|
||||
{
|
||||
return from + fastRand(to - from);
|
||||
}
|
||||
|
||||
//! Round `value` to `where` depending on step size
|
||||
template<class T>
|
||||
@@ -112,10 +123,11 @@ inline double fastPow(double a, double b)
|
||||
}
|
||||
|
||||
|
||||
//! returns 1.0f if val >= 0.0f, -1.0 else
|
||||
inline float sign(float val)
|
||||
//! returns +1 if val >= 0, else -1
|
||||
template<typename T>
|
||||
constexpr T sign(T val) noexcept
|
||||
{
|
||||
return val >= 0.0f ? 1.0f : -1.0f;
|
||||
return val >= 0 ? 1 : -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -136,14 +148,15 @@ inline float signedPowf(float v, float e)
|
||||
//! Value should be within [0,1]
|
||||
inline float logToLinearScale(float min, float max, float value)
|
||||
{
|
||||
using namespace std::numbers;
|
||||
if (min < 0)
|
||||
{
|
||||
const float mmax = std::max(std::abs(min), std::abs(max));
|
||||
const float val = value * (max - min) + min;
|
||||
float result = signedPowf(val / mmax, numbers::e_v<float>) * mmax;
|
||||
float result = signedPowf(val / mmax, e_v<float>) * mmax;
|
||||
return std::isnan(result) ? 0 : result;
|
||||
}
|
||||
float result = std::pow(value, numbers::e_v<float>) * (max - min) + min;
|
||||
float result = std::pow(value, e_v<float>) * (max - min) + min;
|
||||
return std::isnan(result) ? 0 : result;
|
||||
}
|
||||
|
||||
@@ -151,26 +164,37 @@ inline float logToLinearScale(float min, float max, float value)
|
||||
//! @brief Scales value from logarithmic to linear. Value should be in min-max range.
|
||||
inline float linearToLogScale(float min, float max, float value)
|
||||
{
|
||||
constexpr auto inv_e = static_cast<float>(1.0 / std::numbers::e);
|
||||
const float valueLimited = std::clamp(value, min, max);
|
||||
const float val = (valueLimited - min) / (max - min);
|
||||
if (min < 0)
|
||||
{
|
||||
const float mmax = std::max(std::abs(min), std::abs(max));
|
||||
float result = signedPowf(valueLimited / mmax, numbers::inv_e_v<float>) * mmax;
|
||||
float result = signedPowf(valueLimited / mmax, inv_e) * mmax;
|
||||
return std::isnan(result) ? 0 : result;
|
||||
}
|
||||
float result = std::pow(val, numbers::inv_e_v<float>) * (max - min) + min;
|
||||
float result = std::pow(val, inv_e) * (max - min) + min;
|
||||
return std::isnan(result) ? 0 : result;
|
||||
}
|
||||
|
||||
inline float fastPow10f(float x)
|
||||
// TODO C++26: Make constexpr since std::exp() will be constexpr
|
||||
template<std::floating_point T>
|
||||
inline auto fastPow10f(T x)
|
||||
{
|
||||
return std::exp(2.302585092994046f * x);
|
||||
return std::exp(std::numbers::ln10_v<T> * x);
|
||||
}
|
||||
|
||||
inline float fastLog10f(float x)
|
||||
// TODO C++26: Make constexpr since std::exp() will be constexpr
|
||||
inline auto fastPow10f(std::integral auto x)
|
||||
{
|
||||
return std::log(x) * 0.4342944819032518f;
|
||||
return std::exp(std::numbers::ln10_v<float> * x);
|
||||
}
|
||||
|
||||
// TODO C++26: Make constexpr since std::log() will be constexpr
|
||||
inline auto fastLog10f(float x)
|
||||
{
|
||||
constexpr auto inv_ln10 = static_cast<float>(1.0 / std::numbers::ln10);
|
||||
return std::log(x) * inv_ln10;
|
||||
}
|
||||
|
||||
//! @brief Converts linear amplitude (>0-1.0) to dBFS scale.
|
||||
@@ -209,16 +233,8 @@ inline float safeDbfsToAmp(float dbfs)
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Returns the linear interpolation of the two values
|
||||
template<class T, class F>
|
||||
constexpr T lerp(T a, T b, F t)
|
||||
{
|
||||
return (1. - t) * a + t * b;
|
||||
}
|
||||
|
||||
// TODO C++20: use std::formatted_size
|
||||
// @brief Calculate number of digits which LcdSpinBox would show for a given number
|
||||
// @note Once we upgrade to C++20, we could probably use std::formatted_size
|
||||
inline int numDigitsAsInt(float f)
|
||||
{
|
||||
// use rounding:
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
#include "Effect.h"
|
||||
|
||||
#include "BasicFilters.h"
|
||||
#include "lmms_math.h"
|
||||
|
||||
namespace lmms
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "MultitapEcho.h"
|
||||
#include "embed.h"
|
||||
#include "lmms_basics.h"
|
||||
#include "lmms_math.h"
|
||||
#include "plugin_export.h"
|
||||
|
||||
namespace lmms
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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