Does JUCE have some sort of basic support for this?
I’ve tried to make modifications to the juce_Synthesizer class with no avail:
[code]void DoInterpolate(float* l, float r, const float inL, const float* inR, double sourceSamplePosition)
{
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;
}
//==============================================================================
void SamplerVoice::renderNextBlock (AudioSampleBuffer& outputBuffer, int startSample, int numSamples)
{
const SamplerSound* const playingSound = static_cast <SamplerSound*> (getCurrentlyPlayingSound().getObject());
if (playingSound != nullptr)
{
const int mid = playingSound->length / 2;
const int tenth = playingSound->length / 10;
const float invtenth = 1.f/tenth;
double FadePosition = 0.f;
bool togglefade = false;
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, sourceSamplePosition);
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(sourceSamplePosition >= playingSound->length-tenth)
{
if(togglefade == false)
{
togglefade = true;
FadePosition = mid;
}
l *= 1.0f - float((sourceSamplePosition - (playingSound->length-tenth)) * invtenth);
r *= 1.0f - float((sourceSamplePosition - (playingSound->length-tenth)) * invtenth);
float l2 = 0.f;
float r2 = 0.f;
DoInterpolate(&l2, &r2, inL, inR, FadePosition);
l2 *= lgain;
r2 *= rgain;
l2 *= float((sourceSamplePosition - (playingSound->length-tenth)) * invtenth);
r2 *= float((sourceSamplePosition - (playingSound->length-tenth)) * invtenth);
l += l2;
r += r2;
FadePosition += pitchRatio;
}
if (outR != nullptr)
{
*outL++ += l;
*outR++ += r;
}
else
{
*outL++ += (l + r) * 0.5f;
}
sourceSamplePosition += pitchRatio;
if (sourceSamplePosition > playingSound->length)
{
//stopNote (false);
togglefade = false;
sourceSamplePosition = FadePosition;
break;
}
}
}
}[/code]