//	Delay.cpp - Simple (stereo) audio delay class.
//  ----------------------------------------------------------------------------
//	This file is part of 'NiallsAVLib', base code for any kind of audiovisual
//	apps.
//	Copyright (C) 2012  Niall Moody
//	
//	This program is free software: you can redistribute it and/or modify
//	it under the terms of the GNU General Public License as published by
//	the Free Software Foundation, either version 3 of the License, or
//	(at your option) any later version.
//
//	This program is distributed in the hope that it will be useful,
//	but WITHOUT ANY WARRANTY; without even the implied warranty of
//	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//	GNU General Public License for more details.
//
//	You should have received a copy of the GNU General Public License
//	along with this program.  If not, see <http://www.gnu.org/licenses/>.
//	----------------------------------------------------------------------------

#include "Delay.h"

//------------------------------------------------------------------------------
Delay::Delay():
readIndex((float)(BufferSize-2)),
writeIndex(0),
delay(0.0f),
feedback(0.0f),
mix(0.5f),
samplerate(44100.0f)
{
	int i;

	for(i=0;i<BufferSize;++i)
	{
		delayLine[0][i] = 0.0f;
		delayLine[1][i] = 0.0f;
	}
}

//------------------------------------------------------------------------------
Delay::~Delay()
{

}

//------------------------------------------------------------------------------
void Delay::getAudio(float *buffer, int numSamples)
{
	int i;
	int index;
	const float bufSize = delay * samplerate;

	for(i=0;i<numSamples;++i)
	{
		//Write to the delayline.
		index = (int)writeIndex;
		delayLine[0][index] *= feedback;
		delayLine[0][index] += buffer[(i*2)];
		delayLine[1][index] *= feedback;
		delayLine[1][index] += buffer[(i*2)+1];
		writeIndex += 1.0f;
		if(writeIndex > bufSize)
			writeIndex -= bufSize;

		//Read from the delayline.
		++index;
		buffer[(i*2)] *= 1.0f-mix;
		buffer[(i*2)] += delayLine[0][index] * mix;
		buffer[(i*2)+1] *= 1.0f-mix;
		buffer[(i*2)+1] += delayLine[1][index] * mix;
		readIndex += 1.0f;
		if(readIndex >= bufSize)
			readIndex -= bufSize;
	}

	/*for(i=0;i<numSamples;++i)
	{
		//Write to the delayline.
		delayLine[0][writeIndex] *= feedback;
		delayLine[0][writeIndex] += buffer[(i*2)];
		delayLine[1][writeIndex] *= feedback;
		delayLine[1][writeIndex] += buffer[(i*2)+1];
		++writeIndex;
		writeIndex %= BufferSize;

		//Read from the delayline.
		index = (int)readIndex;
		buffer[(i*2)] *= 1.0f-mix;
		buffer[(i*2)] += delayLine[0][index] * mix;
		buffer[(i*2)+1] *= 1.0f-mix;
		buffer[(i*2)+1] += delayLine[1][index] * mix;
		readIndex += 1.0f;
		if(readIndex >= (float)BufferSize)
			readIndex -= (float)BufferSize;
	}*/
}

//------------------------------------------------------------------------------
void Delay::setDelay(float val)
{
	float tempf;

	delay = val;

	tempf = (float)writeIndex - (delay * samplerate);
	while(tempf < 0.0f)
		tempf += (float)BufferSize;
	readIndex = tempf;
}

//------------------------------------------------------------------------------
void Delay::setFeedback(float val)
{
	feedback = val;
}

//------------------------------------------------------------------------------
void Delay::setMix(float val)
{
	mix = val;
}

//------------------------------------------------------------------------------
void Delay::setSamplerate(float val)
{
	samplerate = val;
	setDelay(delay);
}
