I’m having trouble using the beat synced LFOs with the oversampler. It produces a stepped result instead of a smooth line, where the first part of the oversampled block is repeated by the oversampling rate. I’m calling SetSampleRate in the LFO and the free frequency LFO works as expected and retains the correct frequency at all sample rates. It’s almost as if the PPQ position is resetting within
Here’s my code:
void IPlugEffect::ProcessBlock(sample** inputs, sample** outputs, int nFrames)
{
// Update oversampler if value changed
if (mFactorChanged || GetSampleRate() != prevSampleRate)
UpdateOversampling();
prevSampleRate = GetSampleRate();
// Calculate number of channels to send to the oversampler
numInChans = NInChansConnected() / 2;
numOutChans = NOutChansConnected();
if (GetParam(kEnvFromSidechain)->Value() == kEnvfromSidechain)
numSCChans = numInChans;
else
numSCChans = 0;
// Oversampled Processing routine
mOverSampler.ProcessBlock(inputs, outputs, nFrames, numInChans + numSCChans, numOutChans, [&](sample** inputs, sample** outputs, int nFrames)
{
mLFOAL.ProcessBlock(mModulations.GetList()[kModLFO1], nFrames, mTimeInfo.mPPQPos, mTimeInfo.mTransportIsRunning, mTimeInfo.mTempo);
LFODataGeneratedA[0] = mModulations.GetList()[kModLFO1];
for (auto s = 0; s < nFrames; s++) {
skipcount++;
if (skipcount >= limit)
{
mEnvVisSenderTEMP.PushData({ kCtrlTagEnvSlow, {float(LFODataGeneratedA[0][s])} });
skipcount -= limit;
}
}
for (auto s = 0; s < nFrames; s++)
outputs[0][s] = LFODataGeneratedA[0][s];
});
// END OF OVERSAMPLING
// *******************
}
void IPlugEffect::UpdateOversampling()
{
mOverSampler.SetOverSampling((EFactor)GetParam(kOverSampling)->Int()); // Warning, this could allocate.
mFactorChanged = false;
// Update Sampling Rate
switch (GetParam(kOverSampling)->Int())
{
case 0:
oversamplingscalar = 1; break;
case 1:
oversamplingscalar = 2; break;
case 2:
oversamplingscalar = 4; break;
case 3:
oversamplingscalar = 8; break;
case 4:
oversamplingscalar = 16; break;
case 5:
oversamplingscalar = 32; break;
}
oversampledsamplerate = GetSampleRate() * oversamplingscalar;
oversampledsamplerate1div = 1.0 / oversampledsamplerate;
mOverSampler.Reset(GetBlockSize());
Reset(GetSampleRate(), GetBlockSize());
// Update Modulation
mLFOAL.SetSampleRate(oversampledsamplerate);
mLFORateA = (GetParam(kLFOARateFreq)->Value()) * (44140.0 / GetSampleRate());
mLFOAL.SetQNScalarFromDivision(static_cast<int>(GetParam(kLFOARateSynced)->Value()));
}
void IPlugEffect::Reset(double sampleRate, int blockSize)
{
mModulationsData.Resize(blockSize * kNumModulations);
mModulations.Empty();
for (int i = 0; i < kNumModulations; i++)
{
mModulations.Add(mModulationsData.Get() + (blockSize * i));
}
}