* fixes #6354: Sample and Hold for LFO Controller LFO controller's "white noise" wave shape didn't respect the frequency knob at all, so Sample-and-Hold was added to extend the functionality of the LFO Controller with this random waveshape. The original functionallity can still be accessed by setting the FREQ knob to minimum (0.01) --------- Co-authored-by: Kevin Zander <veratil@gmail.com> Co-authored-by: saker <sakertooth@gmail.com>
This commit is contained in:
@@ -126,6 +126,7 @@ private:
|
||||
void upgrade_defaultTripleOscillatorHQ();
|
||||
void upgrade_mixerRename();
|
||||
void upgrade_bbTcoRename();
|
||||
void upgrade_sampleAndHold();
|
||||
|
||||
// List of all upgrade methods
|
||||
static const std::vector<UpgradeMethod> UPGRADE_METHODS;
|
||||
|
||||
@@ -86,6 +86,7 @@ protected:
|
||||
sample_t (*m_sampleFunction)( const float );
|
||||
|
||||
private:
|
||||
float m_heldSample;
|
||||
SampleBuffer * m_userDefSampleBuffer;
|
||||
|
||||
protected slots:
|
||||
|
||||
@@ -79,6 +79,7 @@ const std::vector<DataFile::UpgradeMethod> DataFile::UPGRADE_METHODS = {
|
||||
&DataFile::upgrade_automationNodes , &DataFile::upgrade_extendedNoteRange,
|
||||
&DataFile::upgrade_defaultTripleOscillatorHQ,
|
||||
&DataFile::upgrade_mixerRename , &DataFile::upgrade_bbTcoRename,
|
||||
&DataFile::upgrade_sampleAndHold ,
|
||||
};
|
||||
|
||||
// Vector of all versions that have upgrade routines.
|
||||
@@ -1762,6 +1763,23 @@ void DataFile::upgrade_bbTcoRename()
|
||||
}
|
||||
|
||||
|
||||
// Set LFO speed to 0.01 on projects made before sample-and-hold PR
|
||||
void DataFile::upgrade_sampleAndHold()
|
||||
{
|
||||
QDomNodeList elements = elementsByTagName("lfocontroller");
|
||||
for (int i = 0; i < elements.length(); ++i)
|
||||
{
|
||||
if (elements.item(i).isNull()) { continue; }
|
||||
auto e = elements.item(i).toElement();
|
||||
// Correct old random wave LFO speeds
|
||||
if (e.attribute("wave").toInt() == 6)
|
||||
{
|
||||
e.setAttribute("speed",0.01f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DataFile::upgrade()
|
||||
{
|
||||
// Runs all necessary upgrade methods
|
||||
|
||||
@@ -88,6 +88,7 @@ void LfoController::updateValueBuffer()
|
||||
{
|
||||
m_phaseOffset = m_phaseModel.value() / 360.0;
|
||||
float phase = m_currentPhase + m_phaseOffset;
|
||||
float phasePrev = 0.0f;
|
||||
|
||||
// roll phase up until we're in sync with period counter
|
||||
m_bufferLastUpdated++;
|
||||
@@ -102,20 +103,45 @@ void LfoController::updateValueBuffer()
|
||||
ValueBuffer *amountBuffer = m_amountModel.valueBuffer();
|
||||
int amountInc = amountBuffer ? 1 : 0;
|
||||
float *amountPtr = amountBuffer ? &(amountBuffer->values()[ 0 ] ) : &amount;
|
||||
Oscillator::WaveShape waveshape = static_cast<Oscillator::WaveShape>(m_waveModel.value());
|
||||
|
||||
for( float& f : m_valueBuffer )
|
||||
{
|
||||
const float currentSample = m_sampleFunction != nullptr
|
||||
? m_sampleFunction( phase )
|
||||
: m_userDefSampleBuffer->userWaveSample( phase );
|
||||
float currentSample = 0;
|
||||
switch (waveshape)
|
||||
{
|
||||
case Oscillator::WaveShape::WhiteNoise:
|
||||
{
|
||||
if (absFraction(phase) < absFraction(phasePrev))
|
||||
{
|
||||
// Resample when phase period has completed
|
||||
m_heldSample = m_sampleFunction(phase);
|
||||
}
|
||||
currentSample = m_heldSample;
|
||||
break;
|
||||
}
|
||||
case Oscillator::WaveShape::UserDefined:
|
||||
{
|
||||
currentSample = m_userDefSampleBuffer->userWaveSample(phase);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
if (m_sampleFunction != nullptr)
|
||||
{
|
||||
currentSample = m_sampleFunction(phase);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
f = std::clamp(m_baseModel.value() + (*amountPtr * currentSample / 2.0f), 0.0f, 1.0f);
|
||||
|
||||
phasePrev = phase;
|
||||
phase += 1.0 / m_duration;
|
||||
amountPtr += amountInc;
|
||||
}
|
||||
|
||||
m_currentPhase = absFraction( phase - m_phaseOffset );
|
||||
m_currentPhase = absFraction(phase - m_phaseOffset);
|
||||
m_bufferLastUpdated = s_periods;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user