Skip to content
Snippets Groups Projects
Commit 2303f228 authored by jsiegle's avatar jsiegle
Browse files

Implement double-buffering scheme

parent 1d2ceeae
Branches
Tags
No related merge requests found
......@@ -27,8 +27,8 @@
AudioNode::AudioNode()
: GenericProcessor("Audio Node"), audioEditor(0), volume(0.00001f),
overflowBuffer(2,10000),
overflowOverflowBuffer(2,10000)
bufferA(2,10000),
bufferB(2,10000)
{
settings.numInputs = 2048;
......@@ -37,17 +37,12 @@ AudioNode::AudioNode()
// 128 inputs, 2 outputs (left and right channel)
setPlayConfigDetails(getNumInputs(), getNumOutputs(), 44100.0, 128);
//leftChan.clear();
//rightChan.clear();
nextAvailableChannel = 2; // keep first two channels empty
//overflowBuffer.setSize(2, 10000); // 2 channels x 10000 samples
numSamplesExpected = 1024;
overflowBufferEndIndex = 0;
overflowBufferStartIndex = 0;
overflowSamples = 0;
samplesInOverflowBuffer = 0;
samplesInBackupBuffer = 0;
}
......@@ -63,10 +58,6 @@ AudioProcessorEditor* AudioNode::createEditor()
{
audioEditor = new AudioEditor(this);
//audioEditor->setUIComponent(getUIComponent());
//audioEditor->updateBufferSizeText();
// setEditor(editor);
return audioEditor;
......@@ -80,6 +71,9 @@ void AudioNode::resetConnections()
channelPointers.clear();
samplesInOverflowBuffer = 0;
samplesInBackupBuffer = 0;
}
void AudioNode::updateBufferSize()
......@@ -111,8 +105,6 @@ void AudioNode::setChannelStatus(Channel* chan, bool status)
void AudioNode::enableCurrentChannel(bool state)
{
//setCurrentChannel(nextAvailableChannel);
if (state)
{
setParameter(100, 0.0f);
......@@ -127,8 +119,6 @@ void AudioNode::enableCurrentChannel(bool state)
void AudioNode::addInputChannel(GenericProcessor* sourceNode, int chan)
{
//if (chan != getProcessorGraph()->midiChannelIndex)
//{
int channelIndex = getNextChannel(false);
......@@ -136,11 +126,6 @@ void AudioNode::addInputChannel(GenericProcessor* sourceNode, int chan)
channelPointers.add(sourceNode->channels[chan]);
//} else {
// Can't monitor events at the moment!
// }
}
void AudioNode::setParameter(int parameterIndex, float newValue)
......@@ -157,23 +142,11 @@ void AudioNode::setParameter(int parameterIndex, float newValue)
channelPointers[currentChannel]->isMonitored = true;
// add current channel
// if (!leftChan.contains(currentChannel))
// {
// leftChan.add(currentChannel);
// rightChan.add(currentChannel);
// }
}
else if (parameterIndex == -100)
{
channelPointers[currentChannel]->isMonitored = false;
// remove current channel
// if (leftChan.contains(currentChannel))
// {
// leftChan.remove(leftChan.indexOf(currentChannel));
// rightChan.remove(rightChan.indexOf(currentChannel));
// }
}
}
......@@ -186,12 +159,16 @@ void AudioNode::prepareToPlay(double sampleRate_, int estimatedSamplesPerBlock)
std::cout << "Audio card sample rate: " << sampleRate_ << std::endl;
std::cout << "Samples per block: " << estimatedSamplesPerBlock << std::endl;
numSamplesExpected = (int) (getSampleRate()/sampleRate_*float(estimatedSamplesPerBlock));
numSamplesExpected = (int) (getSampleRate()/sampleRate_*float(estimatedSamplesPerBlock)) + 1;
// processor sample rate divided by sound card sample rate
overflowBufferStartIndex = 0;
overflowBufferEndIndex = 0;
overflowSamples = 0;
samplesInBackupBuffer = 0;
samplesInOverflowBuffer = 0;
bufferA.clear();
bufferB.clear();
bufferSwap = false;
}
void AudioNode::process(AudioSampleBuffer& buffer,
......@@ -199,204 +176,182 @@ void AudioNode::process(AudioSampleBuffer& buffer,
int& nSamples)
{
float gain;
//std::cout << "Audio node sample count: " << nSamples << std::endl; ///buffer.getNumSamples() << std::endl;
// clear the left and right channels
buffer.clear(0,0,buffer.getNumSamples());
buffer.clear(1,0,buffer.getNumSamples());
if (0)
if (1)
{
if (overflowSamples > 1024)
{
std::cout << "Clearing overflow buffer!" << std::endl;
// just forget about it
overflowBuffer.clear();
overflowSamples = 0;
}
int totalAvailableSamples = nSamples + overflowSamples;
int leftoverSamples = 0;
int samplesFromOverflowBuffer = 0;
int remainingSamples = 0;
// jassert (sourceStartSample >= 0 && sourceStartSample + numSamples <= source.size);
AudioSampleBuffer* overflowBuffer;
AudioSampleBuffer* backupBuffer;
if (channelPointers.size() > 0)
{
if (!bufferSwap)
{
overflowBuffer = &bufferA;
backupBuffer = &bufferB;
bufferSwap = true;
} else {
overflowBuffer = &bufferB;
backupBuffer = &bufferA;
bufferSwap = false;
}
// 2. now copy from the incoming buffer
backupBuffer->clear();
samplesInOverflowBuffer = samplesInBackupBuffer; // size of buffer after last round
samplesInBackupBuffer = 0;
bool copiedBuffer = false;
int samplesToCopy = 0;
int orphanedSamples = 0;
for (int i = 2; i < buffer.getNumChannels(); i++)
if (channelPointers.size() > 0)
{
bool copiedBuffer = false;
if (channelPointers[i-2]->isMonitored)
for (int i = 2; i < buffer.getNumChannels(); i++)
{
if (!copiedBuffer)
if (channelPointers[i-2]->isMonitored)
{
// 1. copy overflow buffer
samplesFromOverflowBuffer = ((overflowSamples <= numSamplesExpected) ?
overflowSamples :
numSamplesExpected);
std::cout << " " << std::endl;
std::cout << "Copying " << samplesFromOverflowBuffer << " samples from overflow buffer." << std::endl;
if (samplesFromOverflowBuffer > 0)
if (!copiedBuffer)
{
// 1. copy overflow buffer
buffer.addFrom(0, // destination channel
0, // destination start sample
overflowBuffer, // source
0, // source channel
0, // source start sample
samplesFromOverflowBuffer, // number of samples
1.0f // gain to apply
);
buffer.addFrom(1, // destination channel
0, // destination start sample
overflowBuffer, // source
1, // source channel
0, // source start sample
samplesFromOverflowBuffer, // number of samples
1.0f // gain to apply
);
samplesToCopy = ((samplesInOverflowBuffer <= numSamplesExpected) ?
samplesInOverflowBuffer :
numSamplesExpected);
overflowBuffer.clear(0, samplesFromOverflowBuffer);
// std::cout << " " << std::endl;
// std::cout << "Copying " << samplesToCopy << " samples from overflow buffer of " << samplesInOverflowBuffer << " samples." << std::endl;
std::cout << "Samples remaining in overflow buffer: " << overflowSamples - samplesFromOverflowBuffer << std::endl;
if (samplesFromOverflowBuffer < overflowSamples)
if (samplesToCopy > 0)
{
// move remaining samples to the front of the buffer
// have to double-copy because copying from a buffer into itself is not allowed
overflowOverflowBuffer.addFrom(0, // destination channel
0, // destination start sample
overflowBuffer, // source
0, // source channel
samplesFromOverflowBuffer, // source start sample
overflowSamples - samplesFromOverflowBuffer, // number of samples
1.0f // gain to apply
buffer.addFrom(0, // destination channel
0, // destination start sample
*overflowBuffer, // source
0, // source channel
0, // source start sample
samplesToCopy, // number of samples
1.0f // gain to apply
);
overflowOverflowBuffer.addFrom(1, // destination channel
0, // destination start sample
overflowBuffer, // source
1, // source channel
samplesFromOverflowBuffer, // source start sample
overflowSamples - samplesFromOverflowBuffer, // number of samples
1.0f // gain to apply
buffer.addFrom(1, // destination channel
0, // destination start sample
*overflowBuffer, // source
1, // source channel
0, // source start sample
samplesToCopy, // number of samples
1.0f // gain to apply
);
overflowBuffer.addFrom(0, // destination channel
0, // destination start sample
overflowOverflowBuffer, // source
0, // source channel
0, // source start sample
overflowSamples - samplesFromOverflowBuffer, // number of samples
1.0f // gain to apply
);
overflowBuffer.addFrom(1, // destination channel
0, // destination start sample
overflowOverflowBuffer, // source
1, // source channel
0, // source start sample
overflowSamples - samplesFromOverflowBuffer, // number of samples
1.0f // gain to apply
);
int leftoverSamples = samplesInOverflowBuffer - samplesToCopy;
overflowOverflowBuffer.clear();
// std::cout << "Samples remaining in overflow buffer: " << leftoverSamples << std::endl;
}
if (leftoverSamples > 0)
{
overflowSamples = overflowSamples - samplesFromOverflowBuffer;
// move remaining samples to the backup buffer
}
backupBuffer->addFrom(0, // destination channel
0, // destination start sample
*overflowBuffer, // source
0, // source channel
samplesToCopy, // source start sample
leftoverSamples, // number of samples
1.0f // gain to apply
);
int remainingSamples = numSamplesExpected - samplesFromOverflowBuffer;
backupBuffer->addFrom(1, // destination channel
0, // destination start sample
*overflowBuffer, // source
1, // source channel
samplesToCopy, // source start sample
leftoverSamples, // number of samples
1.0f // gain to apply
);
std::cout << "Copying " << remainingSamples << " samples from incoming buffer of " << nSamples << " samples" << std::endl;
}
leftoverSamples = nSamples - remainingSamples;
samplesInBackupBuffer = leftoverSamples;
if (leftoverSamples < 0)
{
leftoverSamples = nSamples;
}
}
jassert (leftoverSamples >= 0);
copiedBuffer = true;
std::cout << "Samples remaining in incoming buffer: " << leftoverSamples << std::endl;
} // copying buffer
copiedBuffer = true;
}
gain = volume/(float(0x7fff) * channelPointers[i-2]->bitVolts);
gain = volume/(float(0x7fff) * channelPointers[i-2]->bitVolts);
int remainingSamples = numSamplesExpected - samplesToCopy;
if (remainingSamples > 0)
{
// std::cout << "Copying " << remainingSamples << " samples from incoming buffer of " << nSamples << " samples." << std::endl;
buffer.addFrom(0, // destination channel
samplesFromOverflowBuffer, // destination start sample
buffer, // source
i, // source channel
0, // source start sample
remainingSamples, // number of samples
gain // gain to apply
);
int samplesToCopy2 = ((remainingSamples <= nSamples) ?
remainingSamples :
nSamples);
buffer.addFrom(1, // destination channel
samplesFromOverflowBuffer, // destination start sample
buffer, // source
i, // source channel
0, // source start sample
remainingSamples, // number of samples
gain // gain to apply
);
}
if (samplesToCopy2 > 0)
{
if (leftoverSamples > 0)
{
overflowBuffer.addFrom(0, // destination channel
overflowSamples, // destination start sample
buffer, // source
i, // source channel
remainingSamples, // source start sample
leftoverSamples, // number of samples
gain // gain to apply
);
buffer.addFrom(0, // destination channel
samplesToCopy, // destination start sample
buffer, // source
i, // source channel
0, // source start sample
remainingSamples, // number of samples
gain // gain to apply
);
overflowBuffer.addFrom(0, // destination channel
overflowSamples, // destination start sample
buffer, // source
i, // source channel
remainingSamples, // source start sample
leftoverSamples, // number of samples
gain // gain to apply
);
buffer.addFrom(1, // destination channel
samplesToCopy, // destination start sample
buffer, // source
i, // source channel
0, // source start sample
remainingSamples, // number of samples
gain // gain to apply
);
}
}
orphanedSamples = nSamples - samplesToCopy2;
}
}
// std::cout << "Samples remaining in incoming buffer: " << orphanedSamples << std::endl;
if (orphanedSamples > 0)
{
backupBuffer->addFrom(0, // destination channel
samplesInBackupBuffer, // destination start sample
buffer, // source
i, // source channel
remainingSamples, // source start sample
orphanedSamples, // number of samples
gain // gain to apply
);
backupBuffer->addFrom(0, // destination channel
samplesInBackupBuffer, // destination start sample
buffer, // source
i, // source channel
remainingSamples, // source start sample
orphanedSamples, // number of samples
gain // gain to apply
);
overflowSamples += leftoverSamples;
}
}
}
}
nSamples = numSamplesExpected;
}
samplesInBackupBuffer += orphanedSamples;
nSamples = numSamplesExpected;
}
}
......@@ -107,13 +107,15 @@ private:
/** An array of pointers to the channels that feed into the AudioNode. */
Array<Channel*> channelPointers;
AudioSampleBuffer overflowBuffer;
AudioSampleBuffer overflowOverflowBuffer;
AudioSampleBuffer bufferA;
AudioSampleBuffer bufferB;
int numSamplesExpected;
int overflowBufferEndIndex;
int overflowSamples;
int overflowBufferStartIndex;
int samplesInBackupBuffer;
int samplesInOverflowBuffer;
bool bufferSwap;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(AudioNode);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment