Skip to content

Commit

Permalink
AudioMonitor: refactor and remove channel limit
Browse files Browse the repository at this point in the history
  • Loading branch information
anjaldoshi committed Sep 25, 2024
1 parent dfdc40d commit 9c47a1b
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 123 deletions.
199 changes: 105 additions & 94 deletions Source/Processors/AudioMonitor/AudioMonitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,88 @@
#include "AudioMonitorEditor.h"
#include <stdio.h>

AudioMonitor::AudioMonitor()
: GenericProcessor ("Audio Monitor"),
AudioMonitorSettings::AudioMonitorSettings()
: numChannels (0),
sampleRate (0),
destBufferSampleRate (44100.0f),
estimatedSamples (1024)
{
tempBuffer = std::make_unique<AudioSampleBuffer>();
}

void AudioMonitorSettings::createFilters (int nChans, float sampleRate_)
{
numChannels = nChans;
sampleRate = sampleRate_;

bandpassfilters.clear();
antialiasingfilters.clear();

for (int i = 0; i < MAX_CHANNELS; i++)
Dsp::Params bandpassParams;
bandpassParams[0] = sampleRate; // sample rate
bandpassParams[1] = 2; // order
bandpassParams[2] = (7000 + 100) / 2; // center frequency
bandpassParams[3] = 7000 - 100; // bandwidth

for (int n = 0; n < numChannels; ++n)
{
bandpassfilters.add (new Dsp::SmoothedFilterDesign<Dsp::Butterworth::Design::BandPass // design type
<2>, // order
1, // number of channels (must be const)
Dsp::DirectFormII> (1)); // realization

bandpassfilters.getLast()->setParams (bandpassParams);

antialiasingfilters.add (new Dsp::SmoothedFilterDesign<Dsp::RBJ::Design::LowPass, 1> (1024));
}

updateAntiAliasingFilterParameters();
}

void AudioMonitorSettings::updateAntiAliasingFilterParameters()
{
Dsp::Params antialiasingParams;
antialiasingParams[0] = destBufferSampleRate; // sample rate
antialiasingParams[1] = destBufferSampleRate / 2; // cutoff frequency
antialiasingParams[2] = 1.25; //Q //

for (int i = 0; i < numChannels; ++i)
{
antialiasingfilters[i]->setParams (antialiasingParams);
}
}

void AudioMonitorSettings::setOutputSampleRate (double outputSampleRate, double estimatedSamplesPerBlock)
{
destBufferSampleRate = outputSampleRate;
estimatedSamples = estimatedSamplesPerBlock;

numSamplesExpected = (sampleRate / destBufferSampleRate) * estimatedSamples;
ratio = sampleRate / destBufferSampleRate;

samplesInBackupBuffer.clear();
samplesInOverflowBuffer.clear();

bufferA.clear();
bufferB.clear();
bufferSwap.clear();

for (int i = 0; i < numChannels; i++)
{
samplesInBackupBuffer.emplace (i, 0.0f);
samplesInOverflowBuffer.emplace (i, 0.0f);

bufferA.emplace (i, std::make_unique<AudioBuffer<float>> (1, (int) destBufferSampleRate));
bufferB.emplace (i, std::make_unique<AudioBuffer<float>> (1, (int) destBufferSampleRate));
bufferSwap.emplace (i, false);
}

updateAntiAliasingFilterParameters();
}

AudioMonitor::AudioMonitor()
: GenericProcessor ("Audio Monitor")
{
tempBuffer = std::make_unique<AudioSampleBuffer> (1, 4096);
}

void AudioMonitor::registerParameters()
Expand All @@ -64,8 +130,7 @@ void AudioMonitor::registerParameters()
Parameter::STREAM_SCOPE,
"channels",
"Channels",
"Channels to monitor",
4);
"Channels to monitor");

addCategoricalParameter (
Parameter::STREAM_SCOPE,
Expand All @@ -87,8 +152,15 @@ void AudioMonitor::updateSettings()
{
updatePlaybackBuffer();

settings.update (getDataStreams());

for (auto stream : dataStreams)
{
// create filters for each channel
settings[stream->getStreamId()]->createFilters (stream->getChannelCount(),
stream->getSampleRate());

// update the spike channel parameter with the available spike channels
Array<String> spikeChannelNames;
spikeChannelNames.add ("No spike channel");
for (auto spikeChan : stream->getSpikeChannels())
Expand All @@ -115,48 +187,10 @@ void AudioMonitor::updatePlaybackBuffer()

void AudioMonitor::prepareToPlay (double sampleRate_, int estimatedSamplesPerBlock)
{
destBufferSampleRate = sampleRate_;
estimatedSamples = estimatedSamplesPerBlock;
recreateBuffers();
}

void AudioMonitor::recreateBuffers()
{
numSamplesExpected.clear();
sourceBufferSampleRate.clear();

ratio.clear();

for (int i = 0; i < getNumInputs(); i++)
{
numSamplesExpected.emplace (i,
continuousChannels[i]->getSampleRate()
/ destBufferSampleRate
* estimatedSamples);

sourceBufferSampleRate.emplace (i, continuousChannels[i]->getSampleRate());

ratio.emplace (i, sourceBufferSampleRate[i] / destBufferSampleRate);
}

samplesInBackupBuffer.clear();
samplesInOverflowBuffer.clear();

bufferA.clear();
bufferB.clear();
bufferSwap.clear();

for (int i = 0; i < MAX_CHANNELS; i++)
for (auto stream : dataStreams)
{
samplesInBackupBuffer.emplace (i, 0.0f);
samplesInOverflowBuffer.emplace (i, 0.0f);

bufferA.emplace (i, std::make_unique<AudioBuffer<float>> (1, 44100));
bufferB.emplace (i, std::make_unique<AudioBuffer<float>> (1, 44100));
bufferSwap.emplace (i, false);
settings[stream->getStreamId()]->setOutputSampleRate (sampleRate_, estimatedSamplesPerBlock);
}

tempBuffer->setSize (1, 4096);
}

void AudioMonitor::parameterValueChanged (Parameter* param)
Expand Down Expand Up @@ -191,28 +225,6 @@ void AudioMonitor::parameterValueChanged (Parameter* param)
}
}

void AudioMonitor::updateFilter (int i, uint16 streamId)
{
Dsp::Params params1;
params1[0] = getDataStream (streamId)->getSampleRate(); // sample rate
params1[1] = 2; // order
params1[2] = (7000 + 100) / 2; // center frequency
params1[3] = 7000 - 100; // bandwidth

bandpassfilters[i]->setParams (params1);

double cutoffFreq = destBufferSampleRate / 2; // upsample

double sampleFreq = destBufferSampleRate; // upsample

Dsp::Params params2;
params2[0] = sampleFreq; // sample rate
params2[1] = cutoffFreq; // cutoff frequency
params2[2] = 1.25; //Q //

antialiasingfilters[i]->setParams (params2);
}

void AudioMonitor::handleBroadcastMessage (const String& msg, const int64 messageTimeMilliseconds)
{
LOGC ("Audio Monitor received message: ", msg);
Expand All @@ -227,7 +239,7 @@ void AudioMonitor::handleBroadcastMessage (const String& msg, const int64 messag

if (command.equalsIgnoreCase ("SELECT"))
{
if(parts.size() == 3)
if (parts.size() == 3)
{
String command = parts[2];

Expand All @@ -237,7 +249,6 @@ void AudioMonitor::handleBroadcastMessage (const String& msg, const int64 messag

for (auto stream : getDataStreams())
stream->getParameter ("channels")->setNextValue (ch);

}
}
else if (parts.size() >= 4)
Expand Down Expand Up @@ -277,11 +288,6 @@ void AudioMonitor::handleBroadcastMessage (const String& msg, const int64 messag
void AudioMonitor::setSelectedStream (uint16 streamId)
{
selectedStream = streamId;

for (int i = 0; i < MAX_CHANNELS; i++)
{
updateFilter (i, selectedStream);
}
}

void AudioMonitor::process (AudioBuffer<float>& buffer)
Expand All @@ -301,6 +307,7 @@ void AudioMonitor::process (AudioBuffer<float>& buffer)
if (stream->getStreamId() == selectedStream
&& (*stream)["enable_stream"])
{
auto streamSettings = settings[selectedStream];
AudioSampleBuffer* overflowBuffer;
AudioSampleBuffer* backupBuffer;

Expand All @@ -314,32 +321,34 @@ void AudioMonitor::process (AudioBuffer<float>& buffer)

tempBuffer->clear();

if (! bufferSwap[i])
if (! streamSettings->bufferSwap[localIndex])
{
overflowBuffer = bufferA[i].get();
backupBuffer = bufferB[i].get();
overflowBuffer = streamSettings->bufferA[localIndex].get();
backupBuffer = streamSettings->bufferB[localIndex].get();

bufferSwap[i] = true;
streamSettings->bufferSwap[localIndex] = true;
}
else
{
overflowBuffer = bufferB[i].get();
backupBuffer = bufferA[i].get();
overflowBuffer = streamSettings->bufferB[localIndex].get();
backupBuffer = streamSettings->bufferA[localIndex].get();

bufferSwap[i] = false;
streamSettings->bufferSwap[localIndex] = false;
}

backupBuffer->clear();

samplesInOverflowBuffer[i] = samplesInBackupBuffer[i]; // size of buffer after last round
samplesInBackupBuffer[i] = 0;
streamSettings->samplesInOverflowBuffer[localIndex] = streamSettings->samplesInBackupBuffer[localIndex]; // size of buffer after last round
streamSettings->samplesInBackupBuffer[localIndex] = 0;

double orphanedSamples = 0;

// 1. copy overflow buffer

double samplesToCopyFromOverflowBuffer =
((samplesInOverflowBuffer[i] <= numSamplesExpected[globalIndex]) ? samplesInOverflowBuffer[i] : numSamplesExpected[globalIndex]);
((streamSettings->samplesInOverflowBuffer[localIndex] <= streamSettings->numSamplesExpected)
? streamSettings->samplesInOverflowBuffer[localIndex]
: streamSettings->numSamplesExpected);

// LOGD("Number of samples to copy: ", samplesToCopyFromOverflowBuffer);

Expand All @@ -356,7 +365,7 @@ void AudioMonitor::process (AudioBuffer<float>& buffer)
1.0f // gain to apply
);

double leftoverSamples = samplesInOverflowBuffer[i] - samplesToCopyFromOverflowBuffer;
double leftoverSamples = streamSettings->samplesInOverflowBuffer[localIndex] - samplesToCopyFromOverflowBuffer;

//std::cout << "Copying to backup buffer: " << leftoverSamples << std::endl;

Expand All @@ -372,17 +381,18 @@ void AudioMonitor::process (AudioBuffer<float>& buffer)
);
}

samplesInBackupBuffer[i] = leftoverSamples;
streamSettings->samplesInBackupBuffer[localIndex] = leftoverSamples;
}

double remainingSamples = double (numSamplesExpected[globalIndex]) - samplesToCopyFromOverflowBuffer;
double remainingSamples = double (streamSettings->numSamplesExpected) - samplesToCopyFromOverflowBuffer;

double samplesAvailable = double (getNumSamplesInBlock (selectedStream));

//std::cout << "Remaining samples: " << remainingSamples << std::endl;
//std::cout << "Samples available: " << samplesAvailable << std::endl;

double samplesToCopyFromIncomingBuffer = ((remainingSamples <= samplesAvailable) ? remainingSamples : samplesAvailable);
double samplesToCopyFromIncomingBuffer =
((remainingSamples <= samplesAvailable) ? remainingSamples : samplesAvailable);

//std::cout << "Copying from incoming buffer: " << samplesToCopyFromIncomingBuffer << std::endl;

Expand All @@ -402,18 +412,19 @@ void AudioMonitor::process (AudioBuffer<float>& buffer)

//std::cout << "Orphaned samples: " << orphanedSamples << std::endl;

if (orphanedSamples > 0 && (samplesInBackupBuffer[i] + orphanedSamples < backupBuffer->getNumSamples()))
if (orphanedSamples > 0
&& (streamSettings->samplesInBackupBuffer[localIndex] + orphanedSamples < backupBuffer->getNumSamples()))
{
backupBuffer->addFrom (0, // destination channel
samplesInBackupBuffer[i], // destination start sample
streamSettings->samplesInBackupBuffer[localIndex], // destination start sample
buffer, // source
globalIndex, // source channel
(int) remainingSamples, // source start sample
(int) orphanedSamples, // number of samples
1.0f // gain to apply
);

samplesInBackupBuffer[i] = samplesInBackupBuffer[i] + orphanedSamples;
streamSettings->samplesInBackupBuffer[localIndex] += orphanedSamples;
}

//std::cout << "Total copied: " << samplesToCopyFromOverflowBuffer + samplesToCopyFromIncomingBuffer << std::endl;
Expand All @@ -427,7 +438,7 @@ void AudioMonitor::process (AudioBuffer<float>& buffer)
if (totalCopied == 0)
continue;

bandpassfilters[i]->process (totalCopied, &ptr);
streamSettings->bandpassfilters[localIndex]->process (totalCopied, &ptr);

/*if (i == 0)
{
Expand Down Expand Up @@ -480,7 +491,7 @@ void AudioMonitor::process (AudioBuffer<float>& buffer)
1, // number of samples
alpha); // gain to apply to source

subSampleOffset += ratio[globalIndex];
subSampleOffset += streamSettings->ratio;

while (subSampleOffset >= 1.0)
{
Expand Down
Loading

0 comments on commit 9c47a1b

Please sign in to comment.