My Loop Stretching Code

I was playing around with some loop stretching code and got this ultra simple one working. Sounds actually pretty good. And is time-perfect, meaning that it outputs the correct size. I was testing SoundTouch but it kept removing 1ms of my sample data from the start of the audio. :-\ I even tested the command-line version from the site and the result was 100% the same. Not sure what’s going on. Anyway, the code is simple, but maybe I will improve it over time and make it into a module if anyone wants. :slight_smile:

void WLoopChanger::process(AudioSampleBuffer& audio, const int beats, const float sampleRate, const int sectionsPerBeat, const float originalBPM, const float targetBPM)
{
	AudioSampleBuffer copyAudio(audio);
	//
	double nSamplesPerSection = ((60.0 / double(targetBPM)) / double(sectionsPerBeat)) * double(sampleRate);
	double nSamplesPerSectionOriginal = ((60.0 / double(originalBPM)) / double(sectionsPerBeat)) * double(sampleRate);
	int finalSize = int(nSamplesPerSection * double(beats) * double(sectionsPerBeat));
	int nSamplesPerSubSectionFade = int(jmax(4.0, nSamplesPerSectionOriginal / 8.0));
	//
	audio.setSize(2, finalSize, false, false, true);
	audio.clear();
	//
	for (int xp = 0; xp < (beats * sectionsPerBeat); xp++)
	{
		int xStart = int(nSamplesPerSection * double(xp));
		int xStartOriginal = int(nSamplesPerSectionOriginal * double(xp));
		//
		if (xp > 0)
		{
			xStart -= nSamplesPerSubSectionFade;
			xStartOriginal -= nSamplesPerSubSectionFade;
		}
		//
		for (int xsamp = 0; xsamp < (nSamplesPerSection + nSamplesPerSubSectionFade); xsamp++)
		{
			float multiplier = 1.0f;
			//
			if (xp > 0 && xsamp < nSamplesPerSubSectionFade)
			{
				multiplier = (1.0f / nSamplesPerSubSectionFade) * float(xsamp);
			}
			//
			if (xsamp > nSamplesPerSection)
			{
				multiplier = 1.0f - ((1.0f / nSamplesPerSubSectionFade) * float(xsamp - nSamplesPerSection));
			}
			//
			if (((xsamp + xStart) < (audio.getNumSamples() - 1)) && 
				((xsamp + xStartOriginal) < (copyAudio.getNumSamples() - 1)))
			{
				audio.addSample(0, xsamp + xStart, copyAudio.getSample(0, xsamp + xStartOriginal) * multiplier);
					audio.addSample(1, xsamp + xStart, copyAudio.getSample(1, xsamp + xStartOriginal) * multiplier);
			}
		}
	}
} 

Cheers, WilliamK
www.Wusik.com