Exemple #1
0
void UGenArray::Internal::add(const int numItems, const UGen* items) throw()
{	
	ugen_assert(numItems > 0);
	ugen_assert(items != 0);
	
	const int newSize = size_ +  numItems;
	
	if(allocatedSize >= newSize)
	{
		for(int i = size_; i < newSize; i++)
		{
			array[i] = *items++;
		}		
	}
	else 
	{
		UGen *newArray = new UGen[size_ +  numItems];
		
		for(int i = 0; i < size_; i++)
		{
			newArray[i] = array[i];
		}
		
		for(int i = size_; i < newSize; i++)
		{
			newArray[i] = *items++;
		}
		
		delete [] array;
		size_ = newSize;
		array = newArray;	
		allocatedSize = size_;
	}
}
Exemple #2
0
FFTSenderUGenInternal::FFTSenderUGenInternal(UGen const& input, 
											 FFTEngine::FFTModes mode,
											 FFTEngine const& fft, 
											 const int overlap,
											 const int firstBin,
											 const int numBins) throw()
:	UGenInternal(NumInputs),	
	mode_(mode),
	fftEngine(fft),
	fftSize(fftEngine.size()),
	fftSizeHalved(fftSize / 2),
	overlap_(overlap < 1 ? 1 : overlap),
	firstBin_(firstBin < fftSizeHalved ? firstBin : fftSizeHalved),
	maxNumBins(fftSizeHalved - firstBin_ + 1),
	numBins_(numBins ? (numBins < maxNumBins ? numBins : maxNumBins) : maxNumBins),
	inputBuffer(Buffer::newClear(fftSize, input.getNumChannels(), true)),
	outputBuffer(Buffer::newClear(fftSize, input.getNumChannels(), true)),
	bufferIndex(0)
{
	ugen_assert(overlap == overlap_);	// should be > 0
	ugen_assert(firstBin == firstBin_);	// should be in range
//	ugen_assert(numBins == numBins_);	// should be in range	
	
	inputs[Input] = input;	
}
Exemple #3
0
BEGIN_UGEN_NAMESPACE

#include "ugen_DiskIn.h"


DiskInUGenInternal::DiskInUGenInternal(File const& file, 
									   const int numChannels, 
									   bool loopFlag, 
									   const double startTime, 
									   const int numFrames,
									   const UGen::DoneAction doneAction) throw()
:	ProxyOwnerUGenInternal(0, numChannels - 1),
	file_(file),
	loopFlag_(loopFlag),
	startTime_(startTime < 0.0 ? 0.0 : startTime),
	doneAction_(doneAction),
	shouldDeleteValue(doneAction_ == UGen::DeleteWhenDone)
{	
	ugen_assert(numChannels > 0);
	ugen_assert(startTime == startTime_);
	ugen_assert(numFrames > 0);
	
	bufferData = new float*[numChannels];
	
	filePlayer.addChangeListener(this);
	filePlayer.setFile(file, numFrames);
	filePlayer.prepareToPlay(UGen::getEstimatedBlockSize(), UGen::getSampleRate());
	
	filePlayer.setPosition(startTime);
	filePlayer.start();
}
BEGIN_UGEN_NAMESPACE

#include "ugen_FFTMagnitudeSelection.h"
#include "ugen_FFTEngine.h"
#include "../core/ugen_Bits.h"

FFTMagnitudeSelectionUGenInternal::FFTMagnitudeSelectionUGenInternal(UGen const& input, 
																	 FFTEngine const& fft, 
																	 const int overlap, 
																	 IntArray const& _bins) throw()
:	ProxyOwnerUGenInternal(NumInputs, _bins.length()-1),
	fftEngine(fft),
	fftSize(fftEngine.size()),
	fftSizeHalved(fftSize / 2),	
	overlap_(overlap < 1 ? 1 : overlap),
	hopSize(fftSize / overlap),
	overlapSize(fftSize - hopSize),
	maxNumBins(fftSizeHalved + 1),
	bins(_bins),
	inputBuffer(BufferSpec(fftSize, 1, true)),
	outputBuffer(BufferSpec(fftSize, 1, true)),
	bufferIndex(fftSize - hopSize),
	magnitudes(BufferSpec(bins.length(), 1, true)),
	outputSampleData(new float*[bins.length()])
{
	ugen_assert(overlap == overlap_);	// should be > 0
	ugen_assert(bins.length() > 0);
	
	inputs[Input] = input;
}
inline static void splat(float *buffer, float value, int n)
{
	ugen_assert(buffer != 0);
	ugen_assert(n > 0);

	while(n--)
		*buffer++ = value;
}
bool RawInputUGenInternal::setInput(const float* block, const int channel) throw() 
{ 
	ugen_assert(channel >= 0);
	ugen_assert(channel < getNumChannels());
	ugen_assert(block != 0);
	
	bufferData[channel] = block; 
	return true;
}
Exemple #7
0
ASR::ASR(const float attackTime, const float sustainLevel, const float releaseTime, const UGen::DoneAction doneAction) throw()
{
	ugen_assert(attackTime >= 0.f);
	ugen_assert(sustainLevel > 0.f);
	ugen_assert(releaseTime >= 0.f);
	
	initInternal(1);
	internalUGens[0] = new ASRUGenInternal(attackTime, sustainLevel, releaseTime, doneAction);
}
Exemple #8
0
BankBaseUGenInternal::BankBaseUGenInternal(UGen const& input, const int size, const int numChannels) throw()
:	ProxyOwnerUGenInternal(1, numChannels-1),
	size_(size),
	bufferData(new float*[numChannels]),
	bank(UGenArray(size_)),
	mixer(Mix(bank))
{
	ugen_assert(size > 0);
	ugen_assert(numChannels > 0);
	inputs[Input] = input;
}
Exemple #9
0
void LagUDUGenInternal::processBlock(bool& shouldDelete, const unsigned int blockID, const int channel) throw()
{
	int numSamplesToProcess = uGenOutput.getBlockSize();
	float* outputSamples = uGenOutput.getSampleData();
	float* inputSamples = inputs[Input].processBlock(shouldDelete, blockID, channel);
	float* lagUpSamples = inputs[LagTimeUp].processBlock(shouldDelete, blockID, channel);
	float* lagDownSamples = inputs[LagTimeDown].processBlock(shouldDelete, blockID, channel);
	float newLagTimeUp = *lagUpSamples;
	float newLagTimeDown = *lagDownSamples;
	
	ugen_assert(newLagTimeUp >= 0.f);
	ugen_assert(newLagTimeDown >= 0.f);
	
	if((newLagTimeUp != currentLagTimeUp) || (newLagTimeDown != currentLagTimeDown))
	{
		float next_b1u = newLagTimeUp == 0.f ? 0.f : (float)exp(log001 / (newLagTimeUp * UGen::getSampleRate()));
		float next_b1d = newLagTimeDown == 0.f ? 0.f : (float)exp(log001 / (newLagTimeDown * UGen::getSampleRate()));
		float slope = 1.f / (float)numSamplesToProcess;
		float b1u_slope = (next_b1u - b1u) * slope;
		float b1d_slope = (next_b1d - b1d) * slope;
		currentLagTimeUp = newLagTimeUp;
		currentLagTimeDown = newLagTimeDown;
		
		while(numSamplesToProcess--)
		{
			b1u += b1u_slope;
			b1d += b1d_slope;
			float y0 = *inputSamples++; 
			
			if (y0 > y1)
				*outputSamples++ = y1 = (y0 + b1u * (y1 - y0));
			else
				*outputSamples++ = y1 = (y0 + b1d * (y1 - y0));
		}
		
		b1u = next_b1u;
		b1d = next_b1d;
	}
	else
	{
		while(numSamplesToProcess--)
		{
			float y0 = *inputSamples++; 
			if (y0 > y1)
				*outputSamples++ = y1 = (y0 + b1u * (y1 - y0));
			else
				*outputSamples++ = y1 = (y0 + b1d * (y1 - y0));
		}
	}
	
	y1 = zap(y1); // denormal!
}
int VoicerBaseUGenInternal::createUserData(const int midiChannel, const int midiNote) throw()
{
	ugen_assert(midiChannel == char(midiChannel));
	ugen_assert(midiNote == char(midiNote));

	VoicerUserDataUnion data;
	
	data.i = 0;
	data.s.midiChannel = midiChannel;
	data.s.midiNote = midiNote;
	
	return data.i;
}
Exemple #11
0
BufferValues::BufferValues(Buffer const& buffer) throw()
{
	ugen_assert(buffer.size() > 0);
	ugen_assert(buffer.getNumChannels() > 0);
	
	initInternal(buffer.size());
	generateFromProxyOwner(new BufferValuesUGenInternal(buffer));
	
	for(int i = 0; i < buffer.size(); i++)
	{
		internalUGens[i]->initValue(buffer.getSampleUnchecked(i));
	}
}
Exemple #12
0
BEGIN_UGEN_NAMESPACE

#include "ugen_Chain.h"

ChainBaseUGenInternal::ChainBaseUGenInternal(UGen const& input, const int size, const int numChannels) throw()
:	ProxyOwnerUGenInternal(1, numChannels-1),
	size_(size),
	bufferData(new float*[numChannels]),
	chain(UGenArray(size_))
{
	ugen_assert(size > 0);
	ugen_assert(numChannels > 0);
	inputs[Input] = input;
}
bool VoicerBaseUGenInternal::sendMidiNote(const int midiChannel, 
										  const int midiNote,
										  const int velocity) throw()
{
	const int userData = createUserData(midiChannel, midiNote);
	
	ugen_assert(userData != UGen::defaultUserData);
	ugen_assert(velocity >= 0);

	if(velocity > 0)
	{
		if(numVoices_ > 0)
		{
			const int voicesUsed = countNonstealingVoices();
			if(voicesUsed >= numVoices_)
			{
				UGen stealee = chooseStealee();
					
				if(stealee.isNotNull())
				{
					stealee.userData = stealingUserData;
					stealee.steal(forcedSteal_);
				}
			}
		}
		
		// stop double notes, AU lab was sending two ons but only one off 
		// stealNote(midiChannel, midiNote, false, true);  // let's only do this in the Juce version..
		
		UGen newEvent = spawnEvent(*this, currentEventIndex++, midiChannel, midiNote, velocity);
        
        if(newEvent.isNotNull())
        {
            newEvent.userData = userData;
            events.add(newEvent);
        }        
	}
	else
	{
		UGen releasee = chooseReleasee(midiChannel, midiNote);
		
		if(releasee.isNotNull())
		{
			//releasee.userData = UGen::defaultUserData; // need to rethink why I really wanted to do this
			releasee.release();
		}
	}
	
	return true;
}
Exemple #14
0
RecordBuf::RecordBuf(UGen const& input,
					 Buffer const& buffer, 
					 UGen const& recLevel,
					 UGen const& preLevel,
					 UGen const& loop, 
					 const UGen::DoneAction doneAction) throw()
{
	ugen_assert(buffer.size() > 0);
	ugen_assert(buffer.getNumChannels() > 0);

	const int numChannels = ugen::max(buffer.getNumChannels(), input.getNumChannels());
	initInternal(numChannels);
	generateFromProxyOwner(new RecordBufUGenInternal(input, buffer, recLevel, preLevel, loop.mix(), doneAction));
}
void EnvelopeComponent::setEnv(Env const& env)
{
    clear();
    
    double time = 0.0;
	
	const Buffer& levels = env.getLevels();
	const Buffer& times = env.getTimes();
	const EnvCurveList& curves = env.getCurves();
	
	ugen_assert(levels.size() == (times.size()+1));
	
	EnvelopeHandleComponent* handle = addHandle(time, (double)levels[0], EnvCurve::Linear);
	quantiseHandle(handle);

	for(int i = 0; i < times.size(); i++)
	{
		time += times[i];
		handle = addHandle(time, (double)levels[i+1], curves[i]);
		quantiseHandle(handle);
	}
	
	releaseNode = env.getReleaseNode();
	loopNode = env.getLoopNode();
}
AudioIn::AudioIn(const int numChannels) throw()
{
	ugen_assert(numChannels > 0);
	
	initInternal(numChannels);
	generateFromProxyOwner(new RawInputUGenInternal(numChannels));
}
Exemple #17
0
UGenArray UGenArray::range(const int startIndex, const int endIndex) const throw()
{
	ugen_assert(internal != 0);
	
	if(internal->size() == 0) return UGenArray();
	
	const int startIndexChecked = clip(startIndex, 0, internal->size());
	const int endIndexChecked = clip(endIndex, 0, internal->size());
	
	const int size = endIndexChecked - startIndexChecked;
	
	if(size <= 0)
	{
		return UGenArray();
	}
	else
	{
		UGenArray newArray(size);
		
		for(int i = 0; i < size; i++)
		{
			newArray.put(i, at(i + startIndexChecked));
		}
		
		return newArray;
	}
}
BEGIN_UGEN_NAMESPACE

#include "ugen_VoicerBase.h"
#include "../basics/ugen_MixUGen.h"
#include "../core/ugen_UGenArray.h"


VoicerBaseUGenInternal::VoicerBaseUGenInternal(const int numChannels, const int numVoices, const bool forcedSteal) throw()
:	SpawnBaseUGenInternal(0, numChannels, 0),
	numVoices_(numVoices),
	stealMode_(StealOldest),
	forcedSteal_(forcedSteal),
	ageCounter(0)
{
	ugen_assert(numChannels > 0);
	ugen_assert(numVoices >= 0);
}
Exemple #19
0
BEGIN_UGEN_NAMESPACE

#include "ugen_DiskOut.h"
#include "../ugen_JuceUtility.h"


DiskOutUGenInternal::DiskOutUGenInternal(File const& file, UGen const& input, bool overwriteExisitingFile, int bitDepth) throw()
:	ProxyOwnerUGenInternal(NumInputs, input.getNumChannels()-1),
	audioFormatWriter(0),
	bufferData(0),
	numInputChannels(input.getNumChannels())
{
	ugen_assert(bitDepth >= 16);
	
	inputs[Input] = input;
	
	bufferData = new float*[numInputChannels];
	memset(bufferData, 0, numInputChannels * sizeof(float*));
	
	File outputFile(file);
	
	if(outputFile.getFileExtension().isEmpty())
		outputFile = outputFile.withFileExtension("wav");
	
	if(overwriteExisitingFile == true && outputFile.exists())
		outputFile.deleteFile();
	else if(outputFile.exists())
	{
		ugen_assertfalse;
		return;
	}
	
	if(outputFile.hasFileExtension(".wav"))
	{
		WavAudioFormat wavAudioFormat;
		FileOutputStream* fileOutputStream = outputFile.createOutputStream();
		
		if(fileOutputStream)
			audioFormatWriter = wavAudioFormat.createWriterFor(fileOutputStream, 
															   UGen::getSampleRate(), 
															   numInputChannels, 
															   bitDepth, 0, 0);
	}
	else if(outputFile.hasFileExtension(".aif") 
			|| outputFile.hasFileExtension(".aiff"))
	{
		AiffAudioFormat aiffAudioFormat;
		FileOutputStream* fileOutputStream = outputFile.createOutputStream();
		
		if(fileOutputStream)
			audioFormatWriter = aiffAudioFormat.createWriterFor(fileOutputStream, 
																UGen::getSampleRate(), 
																numInputChannels, 
																bitDepth, 0, 0);
	}
		
}
Exemple #20
0
UGenArray& UGenArray::operator/= (UGenArray const& other) throw()
{
	ugen_assert(internal != 0);
	
	if(internal == 0)
		operator= (other);
	else
		operator= (*this / other);
	
	return *this;
}
BEGIN_UGEN_NAMESPACE

#include "ugen_RawInputUGens.h"


RawInputUGenInternal::RawInputUGenInternal(const int numChannels) throw()
:	ProxyOwnerUGenInternal(0, numChannels - 1)
{
	ugen_assert(numChannels > 0);
	
	bufferData = new const float*[numChannels];
	memset(bufferData, 0, numChannels * sizeof(float*));
}
const UGen& VoicerBaseUGenInternal::chooseReleasee(const int midiChannel, const int midiNote) throw()
{
	ugen_assert(midiChannel == char(midiChannel));
	ugen_assert(midiNote == char(midiNote));

	const int numEvents = events.size();
	
	for(int i = numEvents-1; i >= 0; i--) // release in reverse ?
	{
		UGen& releasee = events[i];
		VoicerUserDataStruct data = getUserData(releasee.userData);
		if((data.midiChannel == midiChannel)
		   && (data.midiNote == midiNote) 
		   // && (releasee.isReleasing() == false // something like this would be useful but tricky to implement
		   )
		{
			return releasee;
		}
	}
	
	return UGen::getNull();
}
Exemple #23
0
MulAdd::MulAdd(UGen const& input, UGen const& mul, UGen const& add) throw()
{	
	UGen inputs[] = { input, mul, add };
	const int numInputChannels = findMaxInputChannels(numElementsInArray(inputs), inputs);
	
	ugen_assert(numInputChannels > 0);
	
	initInternal(numInputChannels);
	for(unsigned int i = 0; i < numInternalUGens; i++)
	{
		internalUGens[i] = new MulAddUGenInternal(input, mul, add);
		internalUGens[i]->initValue(input.getValue(i) * mul.getValue(i) + add.getValue(i));
	}
}
void EnvelopeComponent::quantiseHandle(EnvelopeHandleComponent* thisHandle)
{
	ugen_assert(thisHandle != 0);
	
	if((gridQuantiseMode & GridDomain) && (domainGrid > 0.0))
	{
		double domain = round(thisHandle->getTime(), domainGrid);
		thisHandle->setTime(domain);
		
	}
	
	if((gridQuantiseMode & GridValue) && (valueGrid > 0.0))
	{
		double value = round(thisHandle->getValue(), valueGrid);
		thisHandle->setValue(value);
	}
}
FFTMagnitudeSelection::FFTMagnitudeSelection(UGen const& input, 
											 FFTEngine const& fft, 
											 const int overlap, 
											 IntArray const& bins) throw()
{
	int overlapChecked = Bits::isPowerOf2(overlap) ? overlap : Bits::nextPowerOf2(overlap);
	
	ugen_assert(overlap != overlapChecked); // should be power of 2

	FFTMagnitudeSelectionUGenInternal *fftMag = new FFTMagnitudeSelectionUGenInternal(input.mix(), 
																					  fft, 
																					  overlapChecked, 
																					  bins);
		
	initInternal(fftMag->getNumBins());
	generateFromProxyOwner(fftMag);
}
Exemple #26
0
int TextArray::indexOfIgnoreCase(Text const& item, const int startIndex) const throw()
{
	ugen_assert(startIndex >= 0);
	
	const Text *array = this->getArray();
	
	if(array != 0)
	{
		const int length = this->length();
		for(int i = startIndex < 0 ? 0 : startIndex; i < length; i++)
		{
			if(array[i].equalsIgnoreCase(item))
				return i;
		}
	}
	
	return -1;
}
Exemple #27
0
LLine::LLine(Buffer const& start,	
			 Buffer const& end,
			 Buffer const& duration,
			 const UGen::DoneAction doneAction) throw()
{
	Buffer inputs[] = { start, end, duration };
	const int numInputChannels = findMaxInputSizes(numElementsInArray(inputs), inputs);
	initInternal(numInputChannels);
	
	for(unsigned int i = 0; i < numInternalUGens; i++)
	{
		ugen_assert(duration.wrapAt(i) > 0.f);
		
		internalUGens[i] = new LLineUGenInternal(start.wrapAt(i), 
												 end.wrapAt(i), 
												 duration.wrapAt(i), 
												 doneAction);
	}
}
Exemple #28
0
BEGIN_UGEN_NAMESPACE

#include "ugen_TableOsc.h"
#include "../../core/ugen_Constants.h"


TableOscUGenInternal::TableOscUGenInternal(UGen const& freq, 
										   const float initialPhase, 
										   Buffer const& table) throw()
:	UGenInternal(NumInputs),
	table_(table),
	wavetableSize(table_.size()),
	wavetable(table_.getData(0)),
	currentPhase((initialPhase < 0.f) || (initialPhase >= 1.f) ? 0.f : initialPhase * wavetableSize)
{
	ugen_assert(initialPhase >= 0.f && initialPhase <= 1.f);
	
	inputs[Freq] = freq;
	initValue(lookupIndex(currentPhase));
}
Exemple #29
0
void LagUGenInternal::processBlock(bool& shouldDelete, const unsigned int blockID, const int channel) throw()
{
	int numSamplesToProcess = uGenOutput.getBlockSize();
	float* outputSamples = uGenOutput.getSampleData();
	float* inputSamples = inputs[Input].processBlock(shouldDelete, blockID, channel);
	float* lagSamples = inputs[LagTime].processBlock(shouldDelete, blockID, channel);
	float newLagTime = *lagSamples;
	
	ugen_assert(newLagTime >= 0.f);
	
	if(newLagTime != currentLagTime)
	{
		float next_b1 = newLagTime == 0.f ? 0.f : (float)exp(log001 / (newLagTime * UGen::getSampleRate()));
		float b1_slope = (next_b1 - b1) / (float)numSamplesToProcess;
		
		while(numSamplesToProcess--)
		{
			b1 += b1_slope;
			float y0 = *inputSamples++; 
			*outputSamples++ = y1 = (y0 + b1 * (y1 - y0));
		}
		
		b1 = next_b1;
		currentLagTime = newLagTime;
	}
	else
	{
		while(numSamplesToProcess--)
		{
			float y0 = *inputSamples++; 
			*outputSamples++ = y1 = (y0 + b1 * (y1 - y0));
		}
	}
	
	y1 = zap(y1); // denormal!
}
Exemple #30
0
void LagUDUGenInternalK::processBlock(bool& shouldDelete, const unsigned int blockID, const int channel) throw()
{
	const int krBlockSize = UGen::getControlRateBlockSize();
	unsigned int blockPosition = blockID % krBlockSize;
	int numSamplesToProcess = uGenOutput.getBlockSize();
	float* outputSamples = uGenOutput.getSampleData();
	float* inputSamples = inputs[Input].processBlock(shouldDelete, blockID, channel);
	float* lagUpSamples = inputs[LagTimeUp].processBlock(shouldDelete, blockID, channel);
	float* lagDownSamples = inputs[LagTimeDown].processBlock(shouldDelete, blockID, channel);
	float newLagTimeUp = *lagUpSamples;
	float newLagTimeDown = *lagDownSamples;
	
	ugen_assert(newLagTimeUp >= 0.f);
	ugen_assert(newLagTimeDown >= 0.f);
	
	int numKrSamples = blockPosition % krBlockSize;
	
	if((newLagTimeUp != currentLagTimeUp) || (newLagTimeDown != currentLagTimeDown))
	{
		float next_b1u = newLagTimeUp == 0.f ? 0.f : (float)exp(log001 * krBlockSize / (newLagTimeUp * UGen::getSampleRate()));
		float next_b1d = newLagTimeDown == 0.f ? 0.f : (float)exp(log001 * krBlockSize / (newLagTimeDown * UGen::getSampleRate()));
		float slope = (float)krBlockSize / (float)numSamplesToProcess;
		float b1u_slope = (next_b1u - b1u) * slope;
		float b1d_slope = (next_b1d - b1d) * slope;
		currentLagTimeUp = newLagTimeUp;
		currentLagTimeDown = newLagTimeDown;
		
		while(numSamplesToProcess > 0)
		{
			float nextValue = value;
			if(numKrSamples == 0)			
			{
				b1u += b1u_slope;
				b1d += b1d_slope;
				float y0 = *inputSamples; 
				
				if (y0 > y1)
					nextValue = y1 = (y0 + b1u * (y1 - y0));
				else
					nextValue = y1 = (y0 + b1d * (y1 - y0));
				
			}
			
			numKrSamples = krBlockSize - numKrSamples;
			
			blockPosition		+= numKrSamples;
			inputSamples		+= numKrSamples;
			
			if(nextValue == value)
			{
				while(numSamplesToProcess && numKrSamples)
				{
					*outputSamples++ = nextValue;
					--numSamplesToProcess;
					--numKrSamples;
				}
			} 
			else
			{
				float valueSlope = (nextValue - value) / (float)UGen::getControlRateBlockSize();
				
				while(numSamplesToProcess && numKrSamples)
				{
					*outputSamples++ = value;
					value += valueSlope;
					--numSamplesToProcess;
					--numKrSamples;
				}
				
				value = nextValue;
			}
		}
		
		b1u = next_b1u;
		b1d = next_b1d;
	}
	else
	{
		while(numSamplesToProcess > 0)
		{
			float nextValue = value;
			if(numKrSamples == 0)			
			{
				float y0 = *inputSamples; 
				
				if (y0 > y1)
					nextValue = y1 = (y0 + b1u * (y1 - y0));
				else
					nextValue = y1 = (y0 + b1d * (y1 - y0));
			}
			
			numKrSamples = krBlockSize - numKrSamples;
			
			blockPosition		+= numKrSamples;
			inputSamples		+= numKrSamples;
			
			if(nextValue == value)
			{
				while(numSamplesToProcess && numKrSamples)
				{
					*outputSamples++ = nextValue;
					--numSamplesToProcess;
					--numKrSamples;
				}
			} 
			else
			{
				float valueSlope = (nextValue - value) / (float)UGen::getControlRateBlockSize();
				
				while(numSamplesToProcess && numKrSamples)
				{
					*outputSamples++ = value;
					value += valueSlope;
					--numSamplesToProcess;
					--numKrSamples;
				}
				
				value = nextValue;
			}
		}
	}
	
	y1 = zap(y1);
}