Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace uses of std::rand() with lmms:fastRand() #7741

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
2 changes: 1 addition & 1 deletion include/Oscillator.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ class LMMS_EXPORT Oscillator

static inline sample_t noiseSample( const float )
{
return 1.0f - rand() * 2.0f / static_cast<float>(RAND_MAX);
return fastRand(-1.f, +1.f);
}

static sample_t userWaveSample(const SampleBuffer* buffer, const float sample)
Expand Down
4 changes: 4 additions & 0 deletions include/lmms_constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ namespace lmms
// using this directly
inline constexpr float F_EPSILON = 1.0e-10f; // 10^-10

// This should not be used directly, prefer calling one of the many
// overloads of fastRand() instead
inline constexpr auto FAST_RAND_MAX = 32767;

// Microtuner
inline constexpr unsigned MaxScaleCount = 10; //!< number of scales per project
inline constexpr unsigned MaxKeymapCount = 10; //!< number of keyboard mappings per project
Expand Down
54 changes: 38 additions & 16 deletions include/lmms_math.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@

namespace lmms
{
using namespace std::numbers;
using std::integral, std::floating_point;

// TODO C++23: Make constexpr since std::abs() will be constexpr
inline bool approximatelyEqual(float x, float y) noexcept
Expand All @@ -56,7 +58,7 @@ inline bool approximatelyEqual(float x, float y) noexcept
* Note that if the return value is used as a phase of an oscillator, that the oscillator must support
* negative phases.
*/
inline auto fraction(std::floating_point auto x) noexcept
inline auto fraction(floating_point auto x) noexcept
{
return x - std::trunc(x);
}
Expand All @@ -73,31 +75,51 @@ inline auto fraction(std::floating_point auto x) noexcept
* If the result is interpreted as a phase of an oscillator, it makes that negative phases are
* converted to positive phases.
*/
inline auto absFraction(std::floating_point auto x) noexcept
inline auto absFraction(floating_point auto x) noexcept
{
return x - std::floor(x);
}

inline auto fastRand() noexcept
//! @brief Returns a psuedorandom integer between 0 and FAST_RAND_MAX, inclusive.
inline integral auto fastRand() noexcept
{
static unsigned long next = 1;
next = next * 1103515245 + 12345;
return next / 65536 % 32768;
thread_local unsigned long s_next = 1;
s_next = s_next * 1103515245 + 12345;
return s_next / 65536 % 32768;
}

template<std::floating_point T>

//! @brief Returns a psuedorandom number between 0 and @p range, inclusive.
template<floating_point T>
inline auto fastRand(T range) noexcept
{
constexpr T FAST_RAND_RATIO = static_cast<T>(1.0 / 32767);
constexpr T FAST_RAND_RATIO = static_cast<T>(1.0 / FAST_RAND_MAX);
return fastRand() * range * FAST_RAND_RATIO;
}


//! @brief Returns a psuedorandom number between 0 and @p range, inclusive.
inline auto fastRand(integral auto range) noexcept
{
constexpr auto FAST_RAND_RATIO = static_cast<float>(1.0 / FAST_RAND_MAX);
return fastRand() * range * FAST_RAND_RATIO;
}

template<std::floating_point T>
inline auto fastRand(T from, T to) noexcept

//! @brief Returns a psuedorandom number between @p from and @p to, inclusive.
inline auto fastRand(auto from, auto to) noexcept
{
return from + fastRand(to - from);
}


//! @brief Returns true one in @p chance times at random.
inline bool oneIn(unsigned chance) noexcept
{
return 0 == (fastRand() % chance);
}


//! Round `value` to `where` depending on step size
template<class T>
static void roundAt(T& value, const T& where, const T& stepSize)
Expand Down Expand Up @@ -164,7 +186,7 @@ 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);
constexpr auto inv_e = static_cast<float>(1.0 / e);
const float valueLimited = std::clamp(value, min, max);
const float val = (valueLimited - min) / (max - min);
if (min < 0)
Expand All @@ -178,22 +200,22 @@ inline float linearToLogScale(float min, float max, float value)
}

// TODO C++26: Make constexpr since std::exp() will be constexpr
template<std::floating_point T>
template<floating_point T>
inline auto fastPow10f(T x)
{
return std::exp(std::numbers::ln10_v<T> * x);
return std::exp(ln10_v<T> * x);
}

// TODO C++26: Make constexpr since std::exp() will be constexpr
inline auto fastPow10f(std::integral auto x)
inline auto fastPow10f(integral auto x)
{
return std::exp(std::numbers::ln10_v<float> * x);
return std::exp(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);
constexpr auto inv_ln10 = static_cast<float>(1.0 / ln10);
return std::log(x) * inv_ln10;
}

Expand Down
114 changes: 43 additions & 71 deletions plugins/Organic/Organic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
#include "NotePlayHandle.h"
#include "Oscillator.h"
#include "PixmapButton.h"

#include "lmms_math.h"
#include "embed.h"
#include "plugin_export.h"

Expand Down Expand Up @@ -231,71 +231,63 @@ void OrganicInstrument::playNote( NotePlayHandle * _n,
auto oscs_l = std::array<Oscillator*, NUM_OSCILLATORS>{};
auto oscs_r = std::array<Oscillator*, NUM_OSCILLATORS>{};

_n->m_pluginData = new oscPtr;
auto newOsc = new oscPtr;
_n->m_pluginData = newOsc;

for( int i = m_numOscillators - 1; i >= 0; --i )
for (int i = m_numOscillators - 1; i >= 0; --i)
{
static_cast<oscPtr *>( _n->m_pluginData )->phaseOffsetLeft[i]
= rand() / (static_cast<float>(RAND_MAX) + 1.0f);
static_cast<oscPtr *>( _n->m_pluginData )->phaseOffsetRight[i]
= rand() / (static_cast<float>(RAND_MAX) + 1.0f);
newOsc->phaseOffsetLeft[i] = fastRand(1.f);
newOsc->phaseOffsetRight[i] = fastRand(1.f);

// initialise ocillators

if( i == m_numOscillators - 1 )
if (i == m_numOscillators - 1)
{
// create left oscillator
oscs_l[i] = new Oscillator(
&m_osc[i]->m_waveShape,
&m_modulationAlgo,
_n->frequency(),
m_osc[i]->m_detuningLeft,
static_cast<oscPtr *>( _n->m_pluginData )->phaseOffsetLeft[i],
m_osc[i]->m_volumeLeft );
&m_osc[i]->m_waveShape,
&m_modulationAlgo,
_n->frequency(),
m_osc[i]->m_detuningLeft,
newOsc->phaseOffsetLeft[i],
m_osc[i]->m_volumeLeft);
// create right oscillator
oscs_r[i] = new Oscillator(
&m_osc[i]->m_waveShape,
&m_modulationAlgo,
_n->frequency(),
m_osc[i]->m_detuningRight,
static_cast<oscPtr *>( _n->m_pluginData )->phaseOffsetRight[i],
m_osc[i]->m_volumeRight );
&m_osc[i]->m_waveShape,
&m_modulationAlgo,
_n->frequency(),
m_osc[i]->m_detuningRight,
newOsc->phaseOffsetRight[i],
m_osc[i]->m_volumeRight);
}
else
{
// create left oscillator
oscs_l[i] = new Oscillator(
&m_osc[i]->m_waveShape,
&m_modulationAlgo,
_n->frequency(),
m_osc[i]->m_detuningLeft,
static_cast<oscPtr *>( _n->m_pluginData )->phaseOffsetLeft[i],
m_osc[i]->m_volumeLeft,
oscs_l[i + 1] );
&m_osc[i]->m_waveShape,
&m_modulationAlgo,
_n->frequency(),
m_osc[i]->m_detuningLeft,
newOsc->phaseOffsetLeft[i],
m_osc[i]->m_volumeLeft,
oscs_l[i + 1]);
// create right oscillator
oscs_r[i] = new Oscillator(
&m_osc[i]->m_waveShape,
&m_modulationAlgo,
_n->frequency(),
m_osc[i]->m_detuningRight,
static_cast<oscPtr *>( _n->m_pluginData )->phaseOffsetRight[i],
m_osc[i]->m_volumeRight,
oscs_r[i + 1] );
&m_osc[i]->m_waveShape,
&m_modulationAlgo,
_n->frequency(),
m_osc[i]->m_detuningRight,
newOsc->phaseOffsetRight[i],
m_osc[i]->m_volumeRight,
oscs_r[i + 1]);
}


}

static_cast<oscPtr *>( _n->m_pluginData )->oscLeft = oscs_l[0];
static_cast<oscPtr *>( _n->m_pluginData )->oscRight = oscs_r[0];
newOsc->oscLeft = oscs_l[0];
newOsc->oscRight = oscs_r[0];
}

Oscillator * osc_l = static_cast<oscPtr *>( _n->m_pluginData )->oscLeft;
Oscillator * osc_r = static_cast<oscPtr *>( _n->m_pluginData)->oscRight;

osc_l->update( _working_buffer + offset, frames, 0 );
osc_r->update( _working_buffer + offset, frames, 1 );

auto osc = static_cast<oscPtr*>(_n->m_pluginData);
osc->oscLeft->update(_working_buffer + offset, frames, 0);
osc->oscRight->update(_working_buffer + offset, frames, 1);

// -- fx section --

Expand Down Expand Up @@ -346,27 +338,18 @@ float inline OrganicInstrument::waveshape(float in, float amount)
}




void OrganicInstrument::randomiseSettings()
{

for( int i = 0; i < m_numOscillators; i++ )
for (auto i = 0; i < m_numOscillators; ++i)
{
m_osc[i]->m_volModel.setValue( intRand( 0, 100 ) );

m_osc[i]->m_detuneModel.setValue( intRand( -5, 5 ) );

m_osc[i]->m_panModel.setValue( 0 );

m_osc[i]->m_oscModel.setValue( intRand( 0, 5 ) );
m_osc[i]->m_volModel.setValue(fastRand(100));
m_osc[i]->m_detuneModel.setValue(fastRand(-5, +5));
m_osc[i]->m_panModel.setValue(0);
m_osc[i]->m_oscModel.setValue(fastRand(5));
}

}




void OrganicInstrument::updateAllDetuning()
{
for( int i = 0; i < m_numOscillators; ++i )
Expand All @@ -376,17 +359,6 @@ void OrganicInstrument::updateAllDetuning()
}




int OrganicInstrument::intRand( int min, int max )
{
// int randn = min+int((max-min)*rand()/(RAND_MAX + 1.0));
// cout << randn << endl;
int randn = ( rand() % (max - min) ) + min;
return( randn );
}


gui::PluginView * OrganicInstrument::instantiateView( QWidget * _parent )
{
return( new gui::OrganicInstrumentView( this, _parent ) );
Expand Down
2 changes: 0 additions & 2 deletions plugins/Organic/Organic.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,6 @@ class OrganicInstrument : public Instrument

QString nodeName() const override;

int intRand( int min, int max );

static float * s_harmonics;

public slots:
Expand Down
2 changes: 1 addition & 1 deletion plugins/PeakControllerEffect/PeakControllerEffect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ PeakControllerEffect::PeakControllerEffect(
Model * _parent,
const Descriptor::SubPluginFeatures::Key * _key ) :
Effect( &peakcontrollereffect_plugin_descriptor, _parent, _key ),
m_effectId( rand() ),
m_effectId(fastRand()),
m_peakControls( this ),
m_lastSample( 0 ),
m_autoController( nullptr )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "PeakControllerEffectControls.h"
#include "PeakControllerEffect.h"
#include "Song.h"
#include "lmms_math.h"

namespace lmms
{
Expand Down Expand Up @@ -81,7 +82,7 @@ void PeakControllerEffectControls::loadSettings( const QDomElement & _this )
else
{
// TODO: Fix possible collision
m_effect->m_effectId = rand();
m_effect->m_effectId = fastRand();
}
}

Expand Down
Loading
Loading