Below is my modifications to juce_Sampler so that it’s access to samples is continuous, a hacked-in ring buffer to effect.
So as you can see the original code … DoInterpolate() works perfectly.
My “ringbuffer” equivalent GetSampleInterpolatedLinear() sounds distorted.
I’ll let you know how i’m doing, but if anyone see’s my problem in the mean time or can help me out great.
[code]float wrap(float f)
{
if(f < 0.f){return f + 1.0f;}
if(f > 1.f){return f - 1.0f;}
return f;
}
UINT32 index_wrap(const int in, const int max)
{
int i = in;
while(i < 0){i += max;}
while(i >= max){i -= max;}
return i;
}
float LinearInterpolate(float a, float b, float i)
{
return (b - a) * i + a;
}
//NEW INTERPOLATION (SOUNDS DISTORTED)
void GetSampleInterpolatedLinear(juce::AudioSampleBuffer& buff, int m_len, float m_reciplen, double& m_phase, float pitch, float* l, float* r)
{
const float index = m_phase * float(m_len);
m_phase += pitch * m_reciplen;
wrap(m_phase);
*l = LinearInterpolate(*buff.getSampleData(0, index_wrap(int(index), m_len)), *buff.getSampleData(0, index_wrap(int(index)+1, m_len)), index - int(index));
*r = LinearInterpolate(*buff.getSampleData(1, index_wrap(int(index), m_len)), *buff.getSampleData(0, index_wrap(int(index)+1, m_len)), index - int(index));
}
//OLD INTERPOLATION (WORKS PERFECTLY)
void DoInterpolate(float* l, float r, const float inL, const float* inR, int m_len, double& sourceSamplePosition, float pitch)
{
const int pos = (int) sourceSamplePosition;
const float alpha = (float) (sourceSamplePosition - pos);
const float invAlpha = 1.0f - alpha;
// just using a very simple linear interpolation here..
*l = (inL [pos] * invAlpha + inL [pos + 1] * alpha);
*r = (inR != nullptr) ? (inR [pos] * invAlpha + inR [pos + 1] * alpha)
: *l;
sourceSamplePosition += pitch;
if (sourceSamplePosition > m_len)
sourceSamplePosition = 0;
}
//==============================================================================
void SamplerVoice::renderNextBlock (AudioSampleBuffer& outputBuffer, int startSample, int numSamples)
{
const SamplerSound* const playingSound = static_cast <SamplerSound*> (getCurrentlyPlayingSound().getObject());
if (playingSound != nullptr)
{
const float reciplen = 1.0f/playingSound->length;
const float* const inL = playingSound->data->getSampleData (0, 0);
const float* const inR = playingSound->data->getNumChannels() > 1
? playingSound->data->getSampleData (1, 0) : nullptr;
float* outL = outputBuffer.getSampleData (0, startSample);
float* outR = outputBuffer.getNumChannels() > 1 ? outputBuffer.getSampleData (1, startSample) : nullptr;
while (--numSamples >= 0)
{
float l = 0.f;
float r = 0.f;
//DoInterpolate(&l, &r, inL, inR, playingSound->length, sourceSamplePosition, pitchRatio);
GetSampleInterpolatedLinear(*playingSound->data, playingSound->length, reciplen, sourceSamplePosition, pitchRatio, &l, &r);
l *= lgain;
r *= rgain;
if (isInAttack)
{
l *= attackReleaseLevel;
r *= attackReleaseLevel;
attackReleaseLevel += attackDelta;
if (attackReleaseLevel >= 1.0f)
{
attackReleaseLevel = 1.0f;
isInAttack = false;
}
}
else if (isInRelease)
{
l *= attackReleaseLevel;
r *= attackReleaseLevel;
attackReleaseLevel += releaseDelta;
if (attackReleaseLevel <= 0.0f)
{
stopNote (false);
break;
}
}
if (outR != nullptr)
{
*outL++ += l;
*outR++ += r;
}
else
{
*outL++ += (l + r) * 0.5f;
}
}
}
}[/code]