Channel routing without inserts.

This commit is contained in:
Robin E.R. Davies
2026-04-04 14:51:41 -04:00
parent 1f60e02ce0
commit b21c9d636a
25 changed files with 418 additions and 1284 deletions
+101 -148
View File
@@ -338,24 +338,12 @@ namespace pipedal
float *discardOutputBuffer = nullptr;
std::vector<float *> mainCaptureBuffers;
std::vector<float *> mainPlaybackBuffers;
std::vector<float *> mainInsertPlaybackBuffers;
std::vector<float *> mainVuPlaybackBuffers;
std::vector<float *> auxCaptureBuffers;
std::vector<float *> auxPlaybackBuffers;
std::vector<float *> auxVuPlaybackBuffers;
std::vector<float *> sendCaptureBuffers;
std::vector<float *> sendPlaybackBuffers;
struct OutputBufferMix
{
size_t outputChannel = 0;
std::vector<float *> inputBuffers;
float *outputBuffer = nullptr;
};
std::vector<OutputBufferMix> outputBufferMixes;
std::vector<uint8_t> rawCaptureBuffer;
std::vector<uint8_t> rawPlaybackBuffer;
@@ -1290,9 +1278,8 @@ namespace pipedal
<< ", " << this->bufferSize << "x" << this->numberOfBuffers
<< ", " << "device: " << this->DeviceInputBufferCount() << "/" << this->DeviceOutputBufferCount()
<< ", main: " << this->MainInputBufferCount() << "/" << this->MainOutputBufferCount()
<< ", main ins: " << this->MainOutputBufferCount() << "/" << this->MainOutputBufferCount()
<< ", aux: " << this->AuxInputBufferCount() << "/" << this->AuxOutputBufferCount()
<< ", send: " << this->SendOutputBufferCount() << "/" << this->SendInputBufferCount());
);
return result;
}
void PreparePlaybackFunctions(snd_pcm_format_t playbackFormat)
@@ -1833,25 +1820,12 @@ namespace pipedal
cpuUse.AddSample(ProfileCategory::Execute);
// Perform any neccessary mixing of outputs.
for (auto &bufferMix : outputBufferMixes)
for (auto&mixOp: this->mixOps)
{
float * PIPEDAL_RESTRICT outputBuffer = bufferMix.outputBuffer;
float * PIPEDAL_RESTRICT inputBuffer = bufferMix.inputBuffers[0];
for (size_t i = 0; i < framesRead; ++i)
{
outputBuffer[i] = inputBuffer[i];
}
for (size_t nInput = 1; nInput < bufferMix.inputBuffers.size(); ++nInput)
{
float * PIPEDAL_RESTRICT inputBuffer = bufferMix.inputBuffers[nInput];
for (size_t i = 0; i < framesRead; ++i)
{
outputBuffer[i] += inputBuffer[i];
}
}
mixOp(framesRead);
}
// final downmix.
// final format conversion.
(this->*copyOutputFn)(framesRead);
if (this->driverHost)
@@ -1939,23 +1913,6 @@ namespace pipedal
}
}
}
PIPEDAL_NON_INLINE float *AddMixBuffer(int64_t outputChannel, float *mixBuffer)
{
for (auto &bufferMix : outputBufferMixes)
{
if (bufferMix.outputChannel == outputChannel)
{
bufferMix.inputBuffers.push_back(mixBuffer);
return bufferMix.outputBuffer;
}
}
OutputBufferMix newMix;
newMix.outputChannel = outputChannel;
newMix.outputBuffer = devicePlaybackBuffers[outputChannel];
newMix.inputBuffers.push_back(mixBuffer);
outputBufferMixes.push_back(std::move(newMix));
return devicePlaybackBuffers[outputChannel];
}
PIPEDAL_NON_INLINE void AllocateOutputChannels(
const std::vector<int64_t> &channelSelection,
std::vector<float *> &channelBuffers)
@@ -1983,73 +1940,118 @@ namespace pipedal
}
}
}
PIPEDAL_NON_INLINE void AllocateOutputChannels(
const std::vector<int64_t> &channelSelection,
std::vector<float *> &channelBuffers,
std::vector<float *> &vuBuffers,
const std::set<int64_t> &summedChannels)
{
size_t nChannels = channelSelection.size();
if (nChannels == 0)
PIPEDAL_NON_INLINE void AllocateAuxChannels()
{
for (auto ix : channelSelection.auxInputChannels())
{
channelBuffers.resize(0);
vuBuffers.resize(0);
return;
auxCaptureBuffers.push_back(this->deviceCaptureBuffers[ix]);
}
channelBuffers.resize(nChannels);
vuBuffers.resize(nChannels);
for (size_t i = 0; i < nChannels; ++i)
for (auto ix : channelSelection.auxOutputChannels())
{
int64_t deviceChannel = channelSelection[i];
if (deviceChannel == -1 || deviceChannel >= playbackChannels)
{
channelBuffers[i] = GetDiscardOutputBuffer();
}
else
{
if (!summedChannels.contains(deviceChannel))
{
vuBuffers[i] = channelBuffers[i] = this->devicePlaybackBuffers[deviceChannel];
}
else
{
// Used once already. We need to mix down.
float *mixBuffer = AllocateAudioBuffer();
channelBuffers[i] = mixBuffer;
vuBuffers[i] = AddMixBuffer(deviceChannel, mixBuffer);
}
}
auxPlaybackBuffers.push_back(this->devicePlaybackBuffers[ix]);
}
}
std::set<int64_t> ComputeSummedChannels()
using MixOp = std::function<void(size_t nFrames)>;
std::vector<MixOp> mixOps;
PIPEDAL_NON_INLINE
void AddMixCopyOp(float*inputBuffer, float*outputBuffer)
{
std::set<int64_t> usedOutputChannels;
std::set<int64_t> result;
for (auto ch : channelSelection.mainOutputChannels())
{
if (usedOutputChannels.contains(ch))
mixOps.push_back([inputBuffer,outputBuffer](size_t nFrames) {
float*PIPEDAL_RESTRICT pIn = inputBuffer;
float*PIPEDAL_RESTRICT pOut = outputBuffer;
for (size_t i = 0; i < nFrames; ++i)
{
result.insert(ch);
pOut[i] = pIn[i];
}
else
});
}
PIPEDAL_NON_INLINE
void AddMixAddOp(float*inputBuffer, float*outputBuffer)
{
mixOps.push_back([inputBuffer,outputBuffer](size_t nFrames) {
float*PIPEDAL_RESTRICT pIn = inputBuffer;
float*PIPEDAL_RESTRICT pOut = outputBuffer;
for (size_t i = 0; i < nFrames; ++i)
{
usedOutputChannels.insert(ch);
pOut[i] += pIn[i];
}
});
}
PIPEDAL_NON_INLINE
void AddMixCopyOp(float scale, float*inputBuffer, float*outputBuffer)
{
mixOps.push_back([scale,inputBuffer,outputBuffer](size_t nFrames) {
float*PIPEDAL_RESTRICT pIn = inputBuffer;
float*PIPEDAL_RESTRICT pOut = outputBuffer;
for (size_t i = 0; i < nFrames; ++i)
{
pOut[i] = scale*pIn[i];
}
});
}
PIPEDAL_NON_INLINE
void AddMixAddOp(float scale, float*inputBuffer, float*outputBuffer)
{
mixOps.push_back([scale,inputBuffer,outputBuffer](size_t nFrames) {
float*PIPEDAL_RESTRICT pIn = inputBuffer;
float*PIPEDAL_RESTRICT pOut = outputBuffer;
for (size_t i = 0; i < nFrames; ++i)
{
pOut[i] += scale*pIn[i];
}
});
}
PIPEDAL_NON_INLINE void AddMixOps()
{
std::set<size_t> usedOutputChannels;
for (size_t i = 0; i < this->channelSelection.mainOutputChannels().size(); ++i) {
size_t outputChannel = this->channelSelection.mainOutputChannels()[i];
AddMixCopyOp(this->mainPlaybackBuffers[i],this->devicePlaybackBuffers[outputChannel]);
usedOutputChannels.insert(outputChannel);
}
for (auto ch : channelSelection.auxOutputChannels())
if (channelSelection.auxInputChannels().size() <= channelSelection.auxOutputChannels().size())
{
if (usedOutputChannels.contains(ch))
for (size_t i = 0; i < this->channelSelection.auxOutputChannels().size(); ++i)
{
result.insert(ch);
size_t outputChannel = this->channelSelection.auxOutputChannels()[i];
size_t inputChannel;
if (this->channelSelection.auxInputChannels().size() == 0) break;
if (i >= this->channelSelection.auxInputChannels().size()) {
inputChannel = 0;
} else {
inputChannel = this->channelSelection.auxInputChannels()[i];
}
if (outputChannel >= this->devicePlaybackBuffers.size())
{
continue;
}
if (usedOutputChannels.contains(outputChannel))
{
AddMixAddOp(this->deviceCaptureBuffers[inputChannel],this->devicePlaybackBuffers[outputChannel]);
} else {
AddMixCopyOp(this->deviceCaptureBuffers[inputChannel],this->devicePlaybackBuffers[outputChannel]);
}
usedOutputChannels.insert(outputChannel);
}
else
} else if (channelSelection.auxInputChannels().size() >= 2 && channelSelection.auxOutputChannels().size() == 1) {
float scale = 1.0/channelSelection.auxInputChannels().size();
for (size_t i = 0; i < this->channelSelection.auxOutputChannels().size(); ++i)
{
usedOutputChannels.insert(ch);
size_t outputChannel = this->channelSelection.auxOutputChannels()[i];
if (usedOutputChannels.contains(outputChannel))
{
AddMixAddOp(scale,this->auxCaptureBuffers[0],this->devicePlaybackBuffers[outputChannel]);
} else {
AddMixCopyOp(scale,this->auxCaptureBuffers[0],this->devicePlaybackBuffers[outputChannel]);
}
usedOutputChannels.insert(outputChannel);
}
}
return result;
}
}
bool activated = false;
@@ -2078,7 +2080,6 @@ namespace pipedal
devicePlaybackBuffers[i] = AllocateAudioBuffer();
}
std::set<int64_t> summedOutputChannels = ComputeSummedChannels();
AllocateInputChannels(
channelSelection.mainInputChannels(),
@@ -2086,25 +2087,9 @@ namespace pipedal
AllocateOutputChannels(
channelSelection.mainOutputChannels(),
this->mainPlaybackBuffers);
AllocateOutputChannels(
channelSelection.mainOutputChannels(),
this->mainInsertPlaybackBuffers,
this->mainVuPlaybackBuffers,
summedOutputChannels);
AllocateInputChannels(
channelSelection.auxInputChannels(),
this->auxCaptureBuffers);
AllocateOutputChannels(
channelSelection.auxOutputChannels(),
this->auxPlaybackBuffers,
this->auxVuPlaybackBuffers,
summedOutputChannels);
AllocateInputChannels(
channelSelection.sendInputChannels(),
this->sendCaptureBuffers);
AllocateOutputChannels(
channelSelection.sendOutputChannels(),
this->sendPlaybackBuffers);
AllocateAuxChannels();
AddMixOps();
audioThread = std::make_unique<std::jthread>([this]()
{ AudioThread(); });
@@ -2189,15 +2174,9 @@ namespace pipedal
virtual std::vector<float *> &MainInputBuffers() override { return this->mainCaptureBuffers; }
virtual std::vector<float *> &MainOutputBuffers() override { return this->mainPlaybackBuffers; }
virtual std::vector<float *> &MainInsertOutputBuffers() override { return this->mainInsertPlaybackBuffers; }
virtual std::vector<float *> &MainVuOutputBuffers() override { return this->mainVuPlaybackBuffers; }
virtual std::vector<float *> &AuxInputBuffers() override { return this->auxCaptureBuffers; }
virtual std::vector<float *> &AuxOutputBuffers() override { return this->auxPlaybackBuffers; }
virtual std::vector<float *> &AuxVuOutputBuffers() override { return this->auxVuPlaybackBuffers; }
virtual const std::vector<float *> &SendInputBuffers() const override { return this->sendCaptureBuffers; }
virtual const std::vector<float *> &SendOutputBuffers() const override { return this->sendPlaybackBuffers; }
virtual size_t MainInputBufferCount() const { return mainCaptureBuffers.size(); }
virtual float *GetMainInputBuffer(size_t channel) override
@@ -2221,16 +2200,6 @@ namespace pipedal
{
return auxPlaybackBuffers[channel];
}
virtual size_t SendInputBufferCount() const { return sendCaptureBuffers.size(); }
virtual float *GetSendInputBuffer(size_t channel) override
{
return sendCaptureBuffers[channel];
}
virtual size_t SendOutputBufferCount() const { return sendPlaybackBuffers.size(); }
virtual float *GetSendOutputBuffer(size_t channel) override
{
return sendPlaybackBuffers[channel];
}
virtual size_t GetMidiInputEventCount() override
{
@@ -2246,20 +2215,6 @@ namespace pipedal
{
return mainPlaybackBuffers[channel];
}
virtual size_t MainInsertOutputBufferCount() const override
{
return mainInsertPlaybackBuffers.size();
}
virtual float *GetMainInsertOutputBuffer(size_t channel) const
{
if (channel >= (int64_t)mainCaptureBuffers.size())
{
throw std::runtime_error("GetMainInsertOutputBuffer: Argument out of range.");
}
return mainInsertPlaybackBuffers[channel];
}
float *AllocateAudioBuffer()
{
std::vector<float> buffer;
@@ -2274,8 +2229,6 @@ namespace pipedal
mainPlaybackBuffers.clear();
auxCaptureBuffers.clear();
auxPlaybackBuffers.clear();
sendCaptureBuffers.clear();
sendPlaybackBuffers.clear();
zeroInputBuffer = nullptr;
discardOutputBuffer = nullptr;
allocatedBuffers.clear();
+10 -22
View File
@@ -64,42 +64,30 @@ namespace pipedal {
virtual std::vector<float*> &DeviceInputBuffers() = 0;
virtual std::vector<float*> &DeviceOutputBuffers() = 0;
virtual std::vector<float*> &MainInputBuffers() = 0;
virtual std::vector<float*> &MainOutputBuffers() = 0;
virtual std::vector<float*>&MainInsertOutputBuffers() = 0;
virtual std::vector<float*>&MainVuOutputBuffers() = 0;
virtual std::vector<float*>&AuxInputBuffers() = 0;
virtual std::vector<float*>&AuxOutputBuffers() = 0;
virtual std::vector<float*>&AuxVuOutputBuffers() = 0;
virtual size_t DeviceInputBufferCount() const = 0;
virtual size_t DeviceOutputBufferCount() const = 0;
virtual float* GetDeviceInputBuffer(size_t channel) const = 0;
virtual std::vector<float*> &DeviceOutputBuffers() = 0;
virtual size_t DeviceOutputBufferCount() const = 0;
virtual float* GetDeviceOutputBuffer(size_t channel) const = 0;
virtual std::vector<float*> &MainInputBuffers() = 0;
virtual size_t MainInputBufferCount() const = 0;
virtual float*GetMainInputBuffer(size_t channel) = 0;
virtual std::vector<float*> &MainOutputBuffers() = 0;
virtual size_t MainOutputBufferCount() const = 0;
virtual float*GetMainOutputBuffer(size_t channel) = 0;
virtual size_t MainInsertOutputBufferCount() const = 0;
virtual float*GetMainInsertOutputBuffer(size_t channe) const = 0;
virtual std::vector<float*>&AuxInputBuffers() = 0;
virtual std::vector<float*>&AuxOutputBuffers() = 0;
virtual size_t AuxInputBufferCount() const = 0;
virtual float*GetAuxInputBuffer(size_t channel) = 0;
virtual size_t AuxOutputBufferCount() const = 0;
virtual float*GetAuxOutputBuffer(size_t channel) = 0;
virtual size_t SendInputBufferCount() const = 0;
virtual float*GetSendInputBuffer(size_t channel) = 0;
virtual const std::vector<float*>&SendInputBuffers() const = 0;
virtual size_t SendOutputBufferCount() const = 0;
virtual float*GetSendOutputBuffer(size_t channel) = 0;
virtual const std::vector<float*>&SendOutputBuffers() const = 0;
virtual float*GetZeroInputBuffer() = 0;
virtual float*GetDiscardOutputBuffer() = 0;
+125 -404
View File
@@ -532,7 +532,6 @@ private:
std::vector<std::shared_ptr<Lv2Pedalboard>> activePedalboards; // pedalboards that have been sent to the audio queue.
Lv2Pedalboard *realtimeActivePedalboard = nullptr;
Lv2RoutingInserts realtimeRoutingInserts;
uint32_t sampleRate = 0;
uint64_t currentSample = 0;
@@ -682,7 +681,6 @@ private:
}
void processMonitorPortSubscriptions(
PedalboardType pedalboardType,
Lv2Pedalboard *pedalboard,
uint32_t nframes)
{
@@ -690,11 +688,6 @@ private:
{
auto &portSubscription = realtimeMonitorPortSubscriptions->subscriptions[i];
if (pedalboardType != portSubscription.pedalboardType)
{
continue;
}
portSubscription.samplesToNextCallback -= portSubscription.sampleRate;
if (portSubscription.samplesToNextCallback < 0)
{
@@ -906,47 +899,6 @@ private:
return false; // signal to caller that the effect has been replaced, and processing needs to start again.
}
case RingBufferCommand::ReplaceRoutingInserts:
{
Lv2RoutingInserts body;
realtimeReader.readComplete(&body);
auto oldValue = this->realtimeRoutingInserts;
this->realtimeRoutingInserts = body;
realtimeWriter.RoutingInsertsReplaced(oldValue);
// invalidate the possibly no-good subscriptions. Model will update them shortly.
freeRealtimeVuConfiguration();
freeRealtimeMonitorPortSubscriptions();
cancelParameterRequests();
Lv2Pedalboard *mainInserts = body.mainInserts;
if (mainInserts)
{
mainInserts->ResetAtomBuffers();
// issue patch gets for all writable path properties.
for (auto pEffect : mainInserts->GetEffects())
{
pEffect->RequestAllPathPatchProperties();
}
mainInserts->UpdateAudioPorts();
}
Lv2Pedalboard *auxInserts = body.auxInserts;
if (auxInserts)
{
auxInserts->ResetAtomBuffers();
// issue patch gets for all writable path properties.
for (auto pEffect : auxInserts->GetEffects())
{
pEffect->RequestAllPathPatchProperties();
}
auxInserts->UpdateAudioPorts();
}
reEntered = false;
return false; // signal to caller that the effect has been replaced, and processing needs to start again.
}
default:
throw PiPedalStateException("Unknown Ringbuffer command.");
}
@@ -1162,66 +1114,32 @@ private:
}
}
}
bool GetAudioDriverBuffers(PedalboardType pedalboardType,
float **inputBuffers,
float **outputBuffers)
bool GetMainDriverBuffers(
float **inputBuffers,
float **outputBuffers)
{
bool buffersValid = true;
if (!audioDriver)
for (int i = 0; i < audioDriver->MainInputBufferCount(); ++i)
{
inputBuffers[0] = nullptr;
outputBuffers[0] = nullptr;
return false;
float *input = (float *)audioDriver->GetMainInputBuffer(i);
if (input == nullptr)
{
buffersValid = false;
}
inputBuffers[i] = input;
}
switch (pedalboardType)
inputBuffers[audioDriver->MainInputBufferCount()] = nullptr;
for (int i = 0; i < audioDriver->MainOutputBufferCount(); ++i)
{
case PedalboardType::MainPedalboard:
for (int i = 0; i < audioDriver->MainInputBufferCount(); ++i)
float *output = audioDriver->GetMainOutputBuffer(i);
if (output == nullptr)
{
float *input = (float *)audioDriver->GetMainInputBuffer(i);
if (input == nullptr)
{
buffersValid = false;
}
inputBuffers[i] = input;
buffersValid = false;
}
inputBuffers[audioDriver->MainInputBufferCount()] = nullptr;
for (int i = 0; i < audioDriver->MainOutputBufferCount(); ++i)
{
float *output = audioDriver->GetMainOutputBuffer(i);
if (output == nullptr)
{
buffersValid = false;
}
outputBuffers[i] = output;
}
outputBuffers[audioDriver->MainOutputBufferCount()] = nullptr;
break;
case PedalboardType::MainInserts:
for (int i = 0; i < audioDriver->MainInputBufferCount(); ++i)
{
float *input = (float *)audioDriver->GetMainInputBuffer(i);
if (input == nullptr)
{
buffersValid = false;
}
inputBuffers[i] = input;
}
inputBuffers[audioDriver->MainInputBufferCount()] = nullptr;
for (int i = 0; i < audioDriver->MainOutputBufferCount(); ++i)
{
float *output = audioDriver->GetMainOutputBuffer(i);
if (output == nullptr)
{
buffersValid = false;
}
outputBuffers[i] = output;
}
outputBuffers[audioDriver->MainOutputBufferCount()] = nullptr;
break;
outputBuffers[i] = output;
}
outputBuffers[audioDriver->MainOutputBufferCount()] = nullptr;
return buffersValid;
}
void ProcessGlobalMidiInput()
@@ -1263,39 +1181,18 @@ private:
Lv2Log::info("Audio thread terminated.");
}
PIPEDAL_NON_INLINE void ProcessLv2Pedalboard(PedalboardType pedalboardType, size_t nframes)
PIPEDAL_NON_INLINE void ProcessLv2Pedalboard(size_t nframes)
{
Lv2Pedalboard *pedalboard = nullptr;
std::vector<float *> *pInputBuffers;
std::vector<float *> *pOutputBuffers;
switch (pedalboardType)
{
case PedalboardType::MainPedalboard:
pedalboard = this->realtimeActivePedalboard;
pInputBuffers = &(audioDriver->MainInputBuffers());
if (this->realtimeRoutingInserts.mainInserts != nullptr)
{
pOutputBuffers = &(audioDriver->MainOutputBuffers());
}
else
{
pOutputBuffers = &(audioDriver->MainInsertOutputBuffers());
}
break;
case PedalboardType::MainInserts:
pedalboard = this->realtimeActivePedalboard;
pInputBuffers = &(audioDriver->MainInputBuffers());
pOutputBuffers = &(audioDriver->MainOutputBuffers());
pedalboard = this->realtimeRoutingInserts.mainInserts;
pInputBuffers = &(audioDriver->MainOutputBuffers());
pOutputBuffers = &(audioDriver->MainInsertOutputBuffers());
break;
case PedalboardType::AuxInserts:
pedalboard = this->realtimeRoutingInserts.auxInserts;
pInputBuffers = &(audioDriver->AuxInputBuffers());
pOutputBuffers = &(audioDriver->AuxOutputBuffers());
break;
}
if (pInputBuffers->size() == 0 || pOutputBuffers->size() == 0)
if (pedalboard == nullptr || pInputBuffers->size() == 0 || pOutputBuffers->size() == 0)
{
return;
}
@@ -1320,62 +1217,26 @@ private:
if (this->realtimeMonitorPortSubscriptions != nullptr)
{
processMonitorPortSubscriptions(pedalboardType, pedalboard, nframes);
processMonitorPortSubscriptions(pedalboard, nframes);
}
}
else
{
switch (pedalboardType)
// zero output buffers.
size_t ix = 0;
while (outputBuffers[ix])
{
case PedalboardType::MainPedalboard:
{
// zero output buffers.
size_t ix = 0;
while (outputBuffers[ix])
float *outputBuffer = outputBuffers[ix];
for (size_t i = 0; i < nframes; ++i)
{
float *outputBuffer = outputBuffers[ix];
for (size_t i = 0; i < nframes; ++i)
{
outputBuffer[i] = 0;
}
++ix;
outputBuffer[i] = 0;
}
}
break;
case PedalboardType::MainInserts:
// do nothing. Main pedalboard wrote to Main insert outputs directly in this case.
break;
case PedalboardType::AuxInserts:
// Copy inputs to outputs.
{
if (outputBuffers[0] != nullptr && inputBuffers[0] != nullptr)
{
float *PIPEDAL_RESTRICT outputBuffer = outputBuffers[0];
float *PIPEDAL_RESTRICT inputBuffer = inputBuffers[0];
for (size_t i = 0; i < nframes; ++i)
{
outputBuffer[i] = inputBuffer[i];
}
}
if (outputBuffers[1] != nullptr && inputBuffers[0] != nullptr)
{
float *PIPEDAL_RESTRICT outputBuffer = outputBuffers[1];
float *PIPEDAL_RESTRICT inputBuffer = inputBuffers[1] != nullptr ? inputBuffers[1] : inputBuffers[0];
for (size_t i = 0; i < nframes; ++i)
{
outputBuffer[i] = inputBuffer[i];
}
}
}
break;
case PedalboardType::Invalid:
throw std::runtime_error("Invalid argument.");
break;
++ix;
}
}
}
void GetMasterChannels(PedalboardType pedalboardType, float **masterInputBuffers, float **masterOutputBuffers)
void GetMasterChannels(float **masterInputBuffers, float **masterOutputBuffers)
{
size_t inputIx = 0;
size_t outputIx = 0;
@@ -1385,90 +1246,72 @@ private:
masterOutputBuffers[0] = nullptr;
masterOutputBuffers[1] = nullptr;
const ChannelSelection &channelSelection = audioDriver->GetChannelSelection();
switch (pedalboardType)
for (auto nChannel : channelSelection.mainInputChannels())
{
case PedalboardType::MainPedalboard:
for (auto nChannel : channelSelection.mainInputChannels())
masterInputBuffers[inputIx++] = audioDriver->GetDeviceInputBuffer(nChannel);
}
for (auto nChannel : channelSelection.mainOutputChannels())
{
masterOutputBuffers[outputIx++] = audioDriver->GetDeviceOutputBuffer(nChannel);
}
}
inline void AccumulateVu(float*result, size_t nFrames, float*buffer)
{
float maxVal = *result;
for (size_t i = 0; i < nFrames; ++i)
{
float v = std::fabs(buffer[i]);
if (v > maxVal)
{
masterInputBuffers[inputIx++] = audioDriver->GetDeviceInputBuffer(nChannel);
maxVal = v;
}
for (auto nChannel : channelSelection.mainOutputChannels())
{
masterOutputBuffers[outputIx++] = audioDriver->GetDeviceOutputBuffer(nChannel);
}
break;
case PedalboardType::MainInserts:
if (this->realtimeActivePedalboard)
{
for (float *buffer : this->realtimeActivePedalboard->GetoutputBuffers())
{
masterInputBuffers[inputIx++] = buffer;
}
for (auto nChannel : channelSelection.mainOutputChannels())
{
masterOutputBuffers[outputIx++] = audioDriver->GetDeviceOutputBuffer(nChannel);
}
}
break;
case PedalboardType::AuxInserts:
for (auto nChannel : channelSelection.auxInputChannels())
{
switch (nChannel)
{
case ChannelRouterSettings::MAIN_OUT_LEFT_CHANNEL:
{
float *pBuffer = nullptr;
if (this->realtimeActivePedalboard)
{
auto &mainOutputBuffers = realtimeActivePedalboard->GetoutputBuffers();
if (mainOutputBuffers.size() >= 1)
{
pBuffer = mainOutputBuffers[0];
}
}
if (pBuffer == nullptr)
{
pBuffer = audioDriver->GetZeroInputBuffer();
}
masterInputBuffers[inputIx++] = pBuffer;
}
break;
case ChannelRouterSettings::MAIN_OUT_RIGHT_CHANNEL:
{
float *pBuffer = nullptr;
if (this->realtimeActivePedalboard)
{
auto &mainOutputBuffers = realtimeActivePedalboard->GetoutputBuffers();
if (mainOutputBuffers.size() == 1)
{
pBuffer = mainOutputBuffers[0];
}
else if (mainOutputBuffers.size() == 2)
{
pBuffer = mainOutputBuffers[0];
}
}
if (pBuffer == nullptr)
{
pBuffer = audioDriver->GetZeroInputBuffer();
}
masterInputBuffers[inputIx++] = pBuffer;
}
break;
default:
masterInputBuffers[outputIx++] = audioDriver->GetDeviceInputBuffer(nChannel);
};
}
for (auto nChannel : channelSelection.auxOutputChannels())
{
masterOutputBuffers[outputIx++] = audioDriver->GetDeviceOutputBuffer(nChannel);
}
break;
}
*result = maxVal;
}
void AccumulateVuInputs(size_t nFrames,VuUpdateX&vuUpdate, const std::vector<int64_t>&channels)
{
if (channels.size() == 0) return;
default:
throw std::runtime_error("GetMasterChannels: Argument out of range.");
AccumulateVu(&vuUpdate.inputMaxValueL_,nFrames,this->audioDriver->DeviceInputBuffers()[channels[0]]);
if (channels.size() == 2) {
AccumulateVu(&vuUpdate.inputMaxValueR_,nFrames,this->audioDriver->DeviceInputBuffers()[channels[1]]);
}
}
void AccumulateVuOutputs(size_t nFrames,VuUpdateX&vuUpdate, const std::vector<int64_t>&channels)
{
if (channels.size() == 0) return;
AccumulateVu(&vuUpdate.outputMaxValueL_,nFrames,this->audioDriver->DeviceOutputBuffers()[channels[0]]);
if (channels.size() >= 2) {
AccumulateVu(&vuUpdate.outputMaxValueR_,nFrames,this->audioDriver->DeviceOutputBuffers()[channels[1]]);
}
}
void ComputeMasterVus(size_t nFrames) {
if (this->realtimeVuBuffers)
{
float** audioBuffers;
for (auto& vuUpdate: this->realtimeVuBuffers->vuUpdateWorkingData)
{
if (vuUpdate.instanceId_ < 0)
{
switch (vuUpdate.instanceId_)
{
case Pedalboard::START_CONTROL_ID:
AccumulateVuInputs(nFrames, vuUpdate, pHost->GetChannelSelection().mainInputChannels());
break;
case Pedalboard::END_CONTROL_ID:
AccumulateVuOutputs(nFrames, vuUpdate, pHost->GetChannelSelection().mainOutputChannels());
break;
case Pedalboard::AUX_START_CONTROL_ID:
AccumulateVuInputs(nFrames, vuUpdate, pHost->GetChannelSelection().auxInputChannels());
break;
case Pedalboard::AUX_END_CONTROL_ID:
AccumulateVuOutputs(nFrames, vuUpdate, pHost->GetChannelSelection().auxOutputChannels());
break;
}
}
}
}
}
bool OnRealtimeUpdateDeviceVus(size_t nFrames) override
@@ -1481,20 +1324,9 @@ private:
if (this->realtimeActivePedalboard != nullptr)
{
GetMasterChannels(PedalboardType::MainPedalboard, masterInputBuffers, masterOutputBuffers);
realtimeActivePedalboard->ComputeVus(this->realtimeVuBuffers, nFrames, masterInputBuffers, masterOutputBuffers);
realtimeActivePedalboard->ComputeVus(this->realtimeVuBuffers, nFrames);
}
if (this->realtimeRoutingInserts.mainInserts)
{
GetMasterChannels(PedalboardType::MainInserts, masterInputBuffers, masterOutputBuffers);
this->realtimeRoutingInserts.mainInserts->ComputeVus(this->realtimeVuBuffers, nFrames, masterInputBuffers, masterOutputBuffers);
}
if (this->realtimeRoutingInserts.auxInserts)
{
GetMasterChannels(PedalboardType::AuxInserts, masterInputBuffers, masterOutputBuffers);
this->realtimeRoutingInserts.auxInserts->ComputeVus(this->realtimeVuBuffers, nFrames, masterInputBuffers, masterOutputBuffers);
}
ComputeMasterVus(nFrames);
// periodically send updates.
realtimeVuSamplesRemaining -= nFrames;
if (realtimeVuSamplesRemaining <= 0)
@@ -1517,14 +1349,6 @@ private:
{
pedalboard->ResetAtomBuffers();
}
if (this->realtimeRoutingInserts.auxInserts)
{
this->realtimeRoutingInserts.auxInserts->ResetAtomBuffers();
}
if (this->realtimeRoutingInserts.mainInserts)
{
this->realtimeRoutingInserts.mainInserts->ResetAtomBuffers();
}
while (true)
{
@@ -1542,12 +1366,7 @@ private:
{
ProcessGlobalMidiInput();
}
ProcessLv2Pedalboard(PedalboardType::MainPedalboard, nframes);
if (this->realtimeRoutingInserts.mainInserts != nullptr) // prevent zero-ing of main outputs if there's no mainInserts
{
ProcessLv2Pedalboard(PedalboardType::MainInserts, nframes);
}
ProcessLv2Pedalboard(PedalboardType::AuxInserts, nframes);
ProcessLv2Pedalboard(nframes);
if (pParameterRequests != nullptr)
{
@@ -1861,19 +1680,6 @@ public:
hostReader.read(&body);
OnActivePedalboardReleased(body.oldEffect);
}
else if (command == RingBufferCommand::RoutingInsertsReplaced)
{
Lv2RoutingInserts body;
hostReader.read(&body);
if (body.mainInserts)
{
OnActivePedalboardReleased(body.mainInserts);
}
if (body.auxInserts)
{
OnActivePedalboardReleased(body.auxInserts);
}
}
else if (command == RingBufferCommand::FreeSnapshot)
{
IndexedSnapshot *snapshot;
@@ -2099,23 +1905,6 @@ public:
}
}
virtual void SetChannelRoutingInserts(
const std::shared_ptr<Lv2Pedalboard> &mainInserts,
const std::shared_ptr<Lv2Pedalboard> &auxInserts) override
{
if (active && mainInserts)
{
mainInserts->Activate();
this->activePedalboards.push_back(mainInserts);
}
if (active && auxInserts)
{
auxInserts->Activate();
this->activePedalboards.push_back(auxInserts);
}
Lv2RoutingInserts routingInserts{mainInserts : mainInserts.get(), auxInserts : auxInserts.get()};
hostWriter.ReplaceRoutingInserts(routingInserts);
}
virtual void SetBypass(uint64_t instanceId, bool enabled)
{
@@ -2233,63 +2022,31 @@ public:
PIPEDAL_NON_INLINE RealtimePedalboardItemIndex GetRealtimeItemIndex(int64_t instanceId)
{
PedalboardType instanceType = Pedalboard::GetPedalboardTypeFromInstanceId(instanceId);
int64_t index = -1;
switch (instanceType)
if (this->currentPedalboard)
{
case PedalboardType::MainPedalboard:
if (this->currentPedalboard)
if (instanceId == Pedalboard::START_CONTROL_ID)
{
if (instanceId == Pedalboard::START_CONTROL_ID)
{
index = Pedalboard::START_CONTROL_ID;
}
else if (instanceId == Pedalboard::END_CONTROL_ID)
{
index = Pedalboard::END_CONTROL_ID;
}
else
{
index = this->currentPedalboard->GetIndexOfInstanceId(instanceId);
}
index = Pedalboard::START_CONTROL_ID;
}
break;
case PedalboardType::MainInserts:
if (this->currentMainInsertPedalboard)
else if (instanceId == Pedalboard::END_CONTROL_ID)
{
if (instanceId == Pedalboard::MAIN_INSERT_START_CONTROL_ID)
{
index = Pedalboard::MAIN_INSERT_START_CONTROL_ID;
}
else if (instanceId == Pedalboard::MAIN_INSERT_END_CONTROL_ID)
{
index = Pedalboard::END_CONTROL_ID;
}
else
{
index = this->currentMainInsertPedalboard->GetIndexOfInstanceId(instanceId);
}
index = Pedalboard::END_CONTROL_ID;
}
break;
case PedalboardType::AuxInserts:
if (this->currentAuxInsertPedalboard)
else if (instanceId == Pedalboard::AUX_START_CONTROL_ID)
{
if (instanceId == Pedalboard::AUX_INSERT_START_CONTROL_ID)
{
index = Pedalboard::START_CONTROL_ID;
}
else if (instanceId == Pedalboard::AUX_INSERT_END_CONTROL_ID)
{
index = Pedalboard::END_CONTROL_ID;
}
else
{
index = this->currentAuxInsertPedalboard->GetIndexOfInstanceId(instanceId);
}
index = Pedalboard::AUX_START_CONTROL_ID;
}
else if (instanceId == Pedalboard::AUX_END_CONTROL_ID)
{
index = Pedalboard::AUX_END_CONTROL_ID;
}
else
{
index = this->currentPedalboard->GetIndexOfInstanceId(instanceId);
}
break;
}
RealtimePedalboardItemIndex result{instanceType, index};
RealtimePedalboardItemIndex result{index};
return result;
}
virtual void SetVuSubscriptions(const std::vector<int64_t> &instanceIds)
@@ -2310,39 +2067,21 @@ public:
for (size_t i = 0; i < instanceIds.size(); ++i)
{
int64_t instanceId = instanceIds[i];
PedalboardType pedalboardType = Pedalboard::GetPedalboardTypeFromInstanceId(instanceId);
std::shared_ptr<Lv2Pedalboard> pedalboard;
switch (pedalboardType)
{
case PedalboardType::MainPedalboard:
pedalboard = this->currentPedalboard;
break;
case PedalboardType::MainInserts:
pedalboard = this->currentMainInsertPedalboard;
break;
case PedalboardType::AuxInserts:
pedalboard = this->currentAuxInsertPedalboard;
break;
default:
throw std::runtime_error("SetVuSubscriptions: Value out of range.");
break;
}
std::shared_ptr<Lv2Pedalboard>& pedalboard = this->currentPedalboard;
int64_t effectIndex = -1;
if (pedalboard != nullptr)
{
effectIndex = pedalboard->GetIndexOfInstanceId(instanceId);
}
if (effectIndex != -1)
{
IEffect *effect = pedalboard->GetEffect(instanceId);
RealtimePedalboardItemIndex index = RealtimePedalboardItemIndex(pedalboardType, effectIndex);
RealtimePedalboardItemIndex index = RealtimePedalboardItemIndex(effectIndex);
vuConfig->enabledIndexes.push_back(index);
VuUpdateX v;
v.pedalboardType(pedalboardType);
v.instanceId_ = instanceId;
// Display mono VUs if a stereo device is being fed identical L/R inputs.
v.isStereoInput_ = effect->GetNumberOfInputAudioBuffers() >= 2 && effect->GetAudioInputBuffer(0) != effect->GetAudioInputBuffer(1);
v.isStereoInput_ = effect->GetNumberOfInputAudioBuffers() >= 2;
v.isStereoOutput_ = effect->GetNumberOfOutputAudioBuffers() >= 2;
vuConfig->vuUpdateWorkingData.push_back(v);
@@ -2351,10 +2090,9 @@ public:
else if (
instanceId == Pedalboard::START_CONTROL_ID ||
instanceId == Pedalboard::END_CONTROL_ID ||
instanceId == Pedalboard::MAIN_INSERT_START_CONTROL_ID ||
instanceId == Pedalboard::MAIN_INSERT_END_CONTROL_ID ||
instanceId == Pedalboard::AUX_INSERT_START_CONTROL_ID ||
instanceId == Pedalboard::AUX_INSERT_END_CONTROL_ID)
instanceId == Pedalboard::AUX_START_CONTROL_ID ||
instanceId == Pedalboard::AUX_END_CONTROL_ID
)
{
auto index = GetRealtimeItemIndex(instanceId);
VuUpdateX v;
@@ -2371,16 +2109,10 @@ public:
case Pedalboard::END_CONTROL_ID:
nChannels = this->pHost->GetChannelSelection().mainOutputChannels().size();
break;
case Pedalboard::MAIN_INSERT_START_CONTROL_ID:
nChannels = this->pHost->GetChannelSelection().mainOutputChannels().size();
break;
case Pedalboard::MAIN_INSERT_END_CONTROL_ID:
nChannels = this->pHost->GetChannelSelection().mainOutputChannels().size();
break;
case Pedalboard::AUX_INSERT_START_CONTROL_ID:
case Pedalboard::AUX_START_CONTROL_ID:
nChannels = this->pHost->GetChannelSelection().auxInputChannels().size();
break;
case Pedalboard::AUX_INSERT_END_CONTROL_ID:
case Pedalboard::AUX_END_CONTROL_ID:
nChannels = this->pHost->GetChannelSelection().auxOutputChannels().size();
break;
}
@@ -2395,25 +2127,14 @@ public:
}
}
Lv2Pedalboard *GetPedalboard(PedalboardType pedalboardType)
Lv2Pedalboard *GetPedalboard()
{
switch (pedalboardType)
{
case PedalboardType::MainPedalboard:
return this->currentPedalboard.get();
case PedalboardType::MainInserts:
return this->realtimeRoutingInserts.mainInserts;
case PedalboardType::AuxInserts:
return this->realtimeRoutingInserts.auxInserts;
default:
throw std::runtime_error("AudioHostImpl::GetPedalboard: invalid argument.");
}
return this->currentPedalboard.get();
}
RealtimeMonitorPortSubscription MakeRealtimeSubscription(const MonitorPortSubscription &subscription)
{
RealtimeMonitorPortSubscription result;
result.subscriptionHandle = subscription.subscriptionHandle;
result.pedalboardType = Pedalboard::GetPedalboardTypeFromInstanceId(subscription.subscriptionHandle);
result.instanceIndex = this->currentPedalboard->GetIndexOfInstanceId(subscription.instanceid);
IEffect *pEffect = this->currentPedalboard->GetEffect(subscription.instanceid);
-5
View File
@@ -148,7 +148,6 @@ namespace pipedal
{
public:
int64_t subscriptionHandle;
PedalboardType pedalboardType;
int64_t instanceid;
std::string key;
float updateInterval;
@@ -239,10 +238,6 @@ namespace pipedal
virtual void SetPedalboard(const std::shared_ptr<Lv2Pedalboard> &pedalboard) = 0;
virtual void SetChannelRoutingInserts(
const std::shared_ptr<Lv2Pedalboard> &mainInserts,
const std::shared_ptr<Lv2Pedalboard> &auxInserts
) = 0;
virtual void SetControlValue(uint64_t instanceId, const std::string &symbol, float value) = 0;
+1 -1
View File
@@ -240,7 +240,7 @@ namespace pipedal
{
// zero length? We can never have a zero-length bank.
// Add a default preset and make it the selected preset.
Pedalboard pedalboard = Pedalboard::MakeDefault(PedalboardType::MainPedalboard);
Pedalboard pedalboard = Pedalboard::MakeDefault();
this->addPreset(pedalboard);
newSelection = presets_[0]->instanceId();
}
+4 -15
View File
@@ -76,8 +76,6 @@ ChannelSelection::ChannelSelection(ChannelRouterSettings&settings)
, mainOutputChannels_(settings.mainOutputChannels())
, auxInputChannels_(settings.auxInputChannels())
, auxOutputChannels_(settings.auxOutputChannels())
, sendInputChannels_(settings.sendInputChannels())
, sendOutputChannels_(settings.sendOutputChannels())
{
normalizeChannelSelection();
}
@@ -104,8 +102,6 @@ void ChannelSelection::normalizeChannelSelection() {
normalizeOutputChannels(mainOutputChannels_);
normalizeInputChannels(auxInputChannels_);
normalizeOutputChannels(auxOutputChannels_);
normalizeInputChannels(sendInputChannels_);
normalizeOutputChannels(sendOutputChannels_);
// If either aux inputs or outputs are zero, don't do ANY aux processing.
if (auxInputChannels_.size() == 0)
@@ -129,8 +125,6 @@ void ChannelSelection::normalizeChannelSelection() {
ChannelRouterSettings::ChannelRouterSettings()
: mainInserts_(PedalboardType::MainInserts)
, auxInserts_(PedalboardType::AuxInserts)
{
}
@@ -152,30 +146,25 @@ JSON_MAP_REFERENCE(ChannelRouterSettings, changed)
JSON_MAP_REFERENCE(ChannelRouterSettings, channelRouterPresetId)
JSON_MAP_REFERENCE(ChannelRouterSettings, mainInputChannels)
JSON_MAP_REFERENCE(ChannelRouterSettings, mainOutputChannels)
JSON_MAP_REFERENCE(ChannelRouterSettings, mainInserts)
JSON_MAP_REFERENCE(ChannelRouterSettings, auxInputChannels)
JSON_MAP_REFERENCE(ChannelRouterSettings, auxOutputChannels)
JSON_MAP_REFERENCE(ChannelRouterSettings, auxInserts)
JSON_MAP_REFERENCE(ChannelRouterSettings, sendInputChannels)
JSON_MAP_REFERENCE(ChannelRouterSettings, sendOutputChannels)
JSON_MAP_REFERENCE(ChannelRouterSettings, controlValues)
JSON_MAP_END()
JSON_MAP_END();
JSON_MAP_BEGIN(ChannelRouterPresetIndexEntry)
JSON_MAP_REFERENCE(ChannelRouterPresetIndexEntry, id)
JSON_MAP_REFERENCE(ChannelRouterPresetIndexEntry, name)
JSON_MAP_END()
JSON_MAP_END();
JSON_MAP_BEGIN(ChannelRouterPresetBankEntry)
JSON_MAP_REFERENCE(ChannelRouterPresetBankEntry, id)
JSON_MAP_REFERENCE(ChannelRouterPresetBankEntry, name)
JSON_MAP_REFERENCE(ChannelRouterPresetBankEntry, channelRouterSettings)
JSON_MAP_END()
JSON_MAP_END();
JSON_MAP_BEGIN(ChannelRouterPresetBank)
JSON_MAP_REFERENCE(ChannelRouterPresetBank, nextId)
JSON_MAP_REFERENCE(ChannelRouterPresetBank, version)
JSON_MAP_REFERENCE(ChannelRouterPresetBank, entries)
JSON_MAP_END()
JSON_MAP_END();
-24
View File
@@ -30,9 +30,6 @@ namespace pipedal
class ChannelRouterSettings
{
protected:
static constexpr int64_t CHANNEL_ROUTER_MAIN_INSERT_ID = -4; // Reserved Instance ID for Router Main Inserts.
static constexpr int64_t CHANNEL_ROUTER_AUX_INSERT_ID = -5; // Reserved Instance ID for Router Aux inserts.
bool configured_ = false;
int64_t channelRouterPresetId_ = -1;
@@ -40,22 +37,12 @@ namespace pipedal
std::vector<int64_t> mainInputChannels_ = {1, 1};
std::vector<int64_t> mainOutputChannels_ = {0, 1};
Pedalboard mainInserts_;
std::vector<int64_t> auxInputChannels_ = {-1, -1};
std::vector<int64_t> auxOutputChannels_ = {-1, -1};
Pedalboard auxInserts_;
std::vector<int64_t> sendInputChannels_ = {-1, -1};
std::vector<int64_t> sendOutputChannels_ = {-1, -1};
std::vector<ControlValue> controlValues_;
public:
static constexpr int64_t MAIN_OUT_LEFT_CHANNEL = -2;
static constexpr int64_t MAIN_OUT_RIGHT_CHANNEL = -3;
using self = ChannelRouterSettings;
using ptr = std::shared_ptr<self>;
@@ -69,13 +56,8 @@ namespace pipedal
JSON_GETTER_SETTER(changed)
JSON_GETTER_SETTER_REF(mainInputChannels)
JSON_GETTER_SETTER_REF(mainOutputChannels)
JSON_GETTER_SETTER_REF(mainInserts)
JSON_GETTER_SETTER_REF(auxInputChannels)
JSON_GETTER_SETTER_REF(auxOutputChannels)
JSON_GETTER_SETTER_REF(auxInserts)
JSON_GETTER_SETTER_REF(sendInputChannels)
JSON_GETTER_SETTER_REF(sendOutputChannels)
JSON_GETTER_SETTER_REF(controlValues)
DECLARE_JSON_MAP(ChannelRouterSettings);
};
@@ -96,15 +78,11 @@ namespace pipedal
const std::vector<int64_t> &mainOutputChannels() const { return mainOutputChannels_; }
const std::vector<int64_t> &auxInputChannels() const { return auxInputChannels_; }
const std::vector<int64_t> &auxOutputChannels() const { return auxOutputChannels_; }
const std::vector<int64_t> &sendInputChannels() const { return sendInputChannels_; }
const std::vector<int64_t> &sendOutputChannels() const { return sendOutputChannels_; }
std::vector<int64_t> &mainInputChannels() { return mainInputChannels_; }
std::vector<int64_t> &mainOutputChannels() { return mainOutputChannels_; }
std::vector<int64_t> &auxInputChannels() { return auxInputChannels_; }
std::vector<int64_t> &auxOutputChannels() { return auxOutputChannels_; }
std::vector<int64_t> &sendInputChannels() { return sendInputChannels_; }
std::vector<int64_t> &sendOutputChannels() { return sendOutputChannels_; }
private:
void normalizeChannelSelection();
@@ -113,8 +91,6 @@ namespace pipedal
std::vector<int64_t> mainOutputChannels_;
std::vector<int64_t> auxInputChannels_;
std::vector<int64_t> auxOutputChannels_;
std::vector<int64_t> sendInputChannels_;
std::vector<int64_t> sendOutputChannels_;
};
class ChannelRouterPresetIndexEntry {
+10 -31
View File
@@ -321,7 +321,6 @@ std::vector<float *> Lv2Pedalboard::PrepareItems(
void Lv2Pedalboard::Prepare(IHost *pHost, Pedalboard &pedalboard, Lv2PedalboardErrorList &errorList, ExistingEffectMap *existingEffects)
{
this->pHost = pHost;
this->pedalboardType = pedalboard.GetInstanceType();
inputVolume.SetSampleRate((float)(this->pHost->GetSampleRate()));
outputVolume.SetSampleRate((float)(this->pHost->GetSampleRate()));
@@ -573,7 +572,7 @@ void Lv2Pedalboard::SetBypass(int effectIndex, bool enabled)
}
void Lv2Pedalboard::ComputeVus(RealtimeVuBuffers *realtimeVuBuffers, uint32_t samples, float**masterInputBuffers, float**masterOutputBuffers)
void Lv2Pedalboard::ComputeVus(RealtimeVuBuffers *realtimeVuBuffers, uint32_t samples)
{
if (realtimeVuBuffers == nullptr)
{
@@ -582,23 +581,25 @@ void Lv2Pedalboard::ComputeVus(RealtimeVuBuffers *realtimeVuBuffers, uint32_t sa
for (size_t i = 0; i < realtimeVuBuffers->enabledIndexes.size(); ++i)
{
auto& rtIndex = realtimeVuBuffers->enabledIndexes[i];
if (rtIndex.instanceType != this->pedalboardType)
int index = rtIndex.index;
if (index == -1) continue;
if (index == Pedalboard::AUX_START_CONTROL_ID || index == Pedalboard::AUX_END_CONTROL_ID)
{
// handled by master VU updates.
continue;
}
int index = rtIndex.index;
VuUpdateX *pUpdate = &realtimeVuBuffers->vuUpdateWorkingData[i];
if (index == Pedalboard::START_CONTROL_ID)
{
if (this->pedalboardInputBuffers.size() == 2)
{
pUpdate->AccumulateInputs(masterInputBuffers[0], masterInputBuffers[1], samples);
// input is handled by master VU updates.
pUpdate->AccumulateOutputs(&(this->pedalboardInputBuffers[0][0]), &(this->pedalboardInputBuffers[1][0]), samples); // after outputVolume applied.
}
else if (this->pedalboardInputBuffers.size() == 1)
{
pUpdate->AccumulateInputs(masterInputBuffers[0], samples);
pUpdate->AccumulateOutputs(&(this->pedalboardInputBuffers[0][0]), samples); // after input volume applied.
pUpdate->AccumulateOutputs(&(this->pedalboardInputBuffers[0][0]), samples); // before input volume applied.
// output is handled by master VU updates.
}
}
else if (index == Pedalboard::END_CONTROL_ID)
@@ -606,12 +607,10 @@ void Lv2Pedalboard::ComputeVus(RealtimeVuBuffers *realtimeVuBuffers, uint32_t sa
if (this->pedalboardOutputBuffers.size() == 2)
{
pUpdate->AccumulateInputs(&(this->pedalboardOutputBuffers[0][0]), &(this->pedalboardOutputBuffers[1][0]), samples);
pUpdate->AccumulateOutputs(masterOutputBuffers[0], masterOutputBuffers[1], samples);
}
else if (this->pedalboardOutputBuffers.size() == 1)
{
pUpdate->AccumulateInputs(&(this->pedalboardOutputBuffers[0][0]), samples);
pUpdate->AccumulateOutputs(masterOutputBuffers[0], samples);
}
}
else
@@ -1032,29 +1031,9 @@ void Lv2Pedalboard::handleTapTempo(uint8_t value, const MidiTimestamp& timestamp
size_t Lv2Pedalboard::GetNumberOfAudioInputChannels() const {
switch (pedalboardType)
{
case PedalboardType::MainPedalboard:
return pHost->GetChannelSelection().mainInputChannels().size();
case PedalboardType::MainInserts:
return pHost->GetChannelSelection().mainOutputChannels().size();
case PedalboardType::AuxInserts:
return pHost->GetChannelSelection().auxInputChannels().size();
default:
throw std::runtime_error("Invalid argument");
}
return pHost->GetChannelSelection().mainInputChannels().size();
}
size_t Lv2Pedalboard::GetNumberOfAudioOutputChannels() const {
switch (pedalboardType)
{
case PedalboardType::MainPedalboard:
return pHost->GetChannelSelection().mainOutputChannels().size();
case PedalboardType::MainInserts:
return pHost->GetChannelSelection().mainOutputChannels().size();
case PedalboardType::AuxInserts:
return pHost->GetChannelSelection().auxOutputChannels().size();
default:
throw std::runtime_error("Invalid argument");
}
return pHost->GetChannelSelection().mainOutputChannels().size();
}
+1 -2
View File
@@ -52,7 +52,6 @@ namespace pipedal
class Lv2Pedalboard
{
private:
PedalboardType pedalboardType;
IHost *pHost = nullptr;
size_t currentFrameOffset = 0;
DbDezipper inputVolume;
@@ -174,7 +173,7 @@ namespace pipedal
void SetOutputVolume(float value) { this->outputVolume.SetTarget(value); }
void SetBypass(int effectIndex, bool enabled);
void ComputeVus(RealtimeVuBuffers *vuConfiguration, uint32_t samples, float**masterInputBuffers, float **masterOutputBuffers);
void ComputeVus(RealtimeVuBuffers *vuConfiguration, uint32_t samples);
float GetControlOutputValue(int effectIndex, int portIndex);
+3 -14
View File
@@ -210,7 +210,7 @@ PedalboardItem Pedalboard::MakeSplit()
Pedalboard Pedalboard::MakeDefault(PedalboardType instanceType)
Pedalboard Pedalboard::MakeDefault()
{
// copy insanity. but it happens so rarely.
Pedalboard result;
@@ -510,20 +510,9 @@ Snapshot Pedalboard::MakeSnapshotFromCurrentSettings(const Pedalboard &previousP
}
Pedalboard::Pedalboard(PedalboardType instanceType)
Pedalboard::Pedalboard()
{
switch (instanceType)
{
case PedalboardType::MainPedalboard:
nextInstanceId_ = 0;
break;
case PedalboardType::MainInserts:
nextInstanceId_ = MAIN_INSERT_INSTANCE_BASE;;
break;
case PedalboardType::AuxInserts:
nextInstanceId_ = AUX_INSERT_INSTANCE_BASE;;
break;
}
nextInstanceId_ = 0;
}
+4 -43
View File
@@ -216,13 +216,6 @@ namespace pipedal
DECLARE_JSON_MAP(Snapshot);
};
enum class PedalboardType
{
Invalid = 0,
MainPedalboard = 1,
MainInserts = 2,
AuxInserts = 3
};
class Pedalboard
{
@@ -239,49 +232,17 @@ namespace pipedal
int64_t selectedPlugin_ = -1;
static constexpr int64_t TWO_POWER_52 = 4503599627370496; // Maximum Javascript integer value.
static constexpr int64_t TWO_POWER_48 = 281474976710656; // Number of possible instance IDs for Main Pedalboards.
static constexpr int64_t MAX_INSTANCE_ID = TWO_POWER_48;
public:
static constexpr int64_t MAIN_INSERT_INSTANCE_BASE = TWO_POWER_52 - 2 * MAX_INSTANCE_ID;
static constexpr int64_t AUX_INSERT_INSTANCE_BASE = TWO_POWER_52 - 1 * MAX_INSTANCE_ID;
static constexpr int64_t CHANNEL_ROUTER_CONTROLS_INSTANCE_ID = -4; // Reserved Instance ID for Router Controls.
static constexpr int64_t START_CONTROL_ID = -2; // synthetic PedalboardItem for input volume.
static constexpr int64_t END_CONTROL_ID = -3; // synthetic PedalboardItem for output volume.
static constexpr int64_t MAIN_INSERT_START_CONTROL_ID = MAIN_INSERT_INSTANCE_BASE + MAX_INSTANCE_ID - 2;
static constexpr int64_t MAIN_INSERT_END_CONTROL_ID = MAIN_INSERT_INSTANCE_BASE + MAX_INSTANCE_ID - 3;
static constexpr int64_t AUX_INSERT_START_CONTROL_ID = AUX_INSERT_INSTANCE_BASE + MAX_INSTANCE_ID - 2;
static constexpr int64_t AUX_INSERT_END_CONTROL_ID = AUX_INSERT_INSTANCE_BASE + MAX_INSTANCE_ID - 3;
static PedalboardType GetPedalboardTypeFromInstanceId(int64_t instanceId)
{
if (instanceId == START_CONTROL_ID)
return PedalboardType::MainPedalboard;
if (instanceId == END_CONTROL_ID)
return PedalboardType::MainPedalboard;
static constexpr int64_t AUX_START_CONTROL_ID = -4; // synthetic PedalboardItem for aux input volume.
static constexpr int64_t AUX_END_CONTROL_ID = -5; // synthetic PedalboardItem for aux output volume.
if (instanceId >= MAIN_INSERT_INSTANCE_BASE)
{
return PedalboardType::MainInserts;
}
else if (instanceId >= AUX_INSERT_INSTANCE_BASE)
{
return PedalboardType::AuxInserts;
}
else
{
return PedalboardType::MainPedalboard;
}
}
PedalboardType GetInstanceType() const
{
return GetPedalboardTypeFromInstanceId(this->nextInstanceId_); // instanceId is irrelevant here.
}
Pedalboard(PedalboardType instanceType = PedalboardType::MainPedalboard);
Pedalboard();
// deep copy, breaking shared pointers.
Pedalboard DeepCopy();
@@ -315,7 +276,7 @@ namespace pipedal
PedalboardItem MakeEmptyItem();
PedalboardItem MakeSplit();
static Pedalboard MakeDefault(PedalboardType instanceType = PedalboardType::MainPedalboard);
static Pedalboard MakeDefault();
};
#undef GETTER_SETTER_REF
+4 -8
View File
@@ -82,7 +82,7 @@ PiPedalModel::PiPedalModel()
this->updater = Updater::Create();
this->updater->Start();
this->currentUpdateStatus = updater->GetCurrentStatus();
this->pedalboard = Pedalboard::MakeDefault(PedalboardType::MainPedalboard);
this->pedalboard = Pedalboard::MakeDefault();
this->jackServerSettings = this->storage.GetJackServerSettings();
@@ -394,7 +394,7 @@ void PiPedalModel::Load()
if (CrashGuard::HasCrashed())
{
// ignore the current preset, and load a blank pedalboard in order to avoid a potential plugin crash.
this->pedalboard = Pedalboard::MakeDefault(PedalboardType::MainPedalboard);
this->pedalboard = Pedalboard::MakeDefault();
}
else
{
@@ -1752,10 +1752,8 @@ static bool isStartOrEndControl(int64_t controlId)
{
case Pedalboard::START_CONTROL_ID:
case Pedalboard::END_CONTROL_ID:
case Pedalboard::MAIN_INSERT_START_CONTROL_ID:
case Pedalboard::MAIN_INSERT_END_CONTROL_ID:
case Pedalboard::AUX_INSERT_START_CONTROL_ID:
case Pedalboard::AUX_INSERT_END_CONTROL_ID:
case Pedalboard::AUX_START_CONTROL_ID:
case Pedalboard::AUX_END_CONTROL_ID:
return true;
default:
return false;
@@ -1794,11 +1792,9 @@ int64_t PiPedalModel::MonitorPort(int64_t instanceId, const std::string &key, fl
{
std::lock_guard<std::recursive_mutex> lock(mutex);
int64_t subscriptionId = ++nextSubscriptionId;
PedalboardType pedalboardType = Pedalboard::GetPedalboardTypeFromInstanceId(instanceId);
activeMonitorPortSubscriptions.push_back(
MonitorPortSubscription{
subscriptionId,
pedalboardType,
instanceId,
key,
updateInterval,
+2 -21
View File
@@ -45,19 +45,12 @@ namespace pipedal
uint8_t cc2_;
};
struct Lv2RoutingInserts {
Lv2Pedalboard*mainInserts = nullptr;
Lv2Pedalboard*auxInserts = nullptr;;
};
enum class RingBufferCommand : int64_t
{
Invalid = 0,
ReplaceEffect,
EffectReplaced,
ReplaceRoutingInserts,
RoutingInsertsReplaced,
SetValue,
SetBypass,
// AudioStopped,
@@ -106,19 +99,17 @@ namespace pipedal
struct RealtimePedalboardItemIndex {
RealtimePedalboardItemIndex()
: instanceType(PedalboardType::MainPedalboard), index(-1)
: index(-1)
{
}
RealtimePedalboardItemIndex(
PedalboardType instanceType,
int64_t index)
: instanceType(instanceType), index(index)
: index(index)
{
}
RealtimePedalboardItemIndex(const RealtimePedalboardItemIndex& other) = default;
RealtimePedalboardItemIndex& operator=(const RealtimePedalboardItemIndex& other) = default;
PedalboardType instanceType = PedalboardType::MainPedalboard;
int64_t index = -1;
};
@@ -150,7 +141,6 @@ namespace pipedal
{
public:
RealtimeMonitorPortSubscription() { delete callbackPtr; }
PedalboardType pedalboardType = PedalboardType::MainPedalboard;
int64_t subscriptionHandle;
int instanceIndex = 0;
int portIndex = 0;
@@ -553,15 +543,6 @@ namespace pipedal
write(RingBufferCommand::EffectReplaced, pedalboard);
}
void ReplaceRoutingInserts(Lv2RoutingInserts routingInserts)
{
write(RingBufferCommand::ReplaceRoutingInserts, routingInserts);
}
void RoutingInsertsReplaced(Lv2RoutingInserts routingInserts)
{
write(RingBufferCommand::ReplaceRoutingInserts, routingInserts);
}
void AudioTerminatedAbnormally()
+1 -1
View File
@@ -472,7 +472,7 @@ void Storage::LoadBankIndex()
if (bankIndex.entries().size() == 0)
{
currentBank.clear();
Pedalboard defaultPedalboard = Pedalboard::MakeDefault(PedalboardType::MainPedalboard);
Pedalboard defaultPedalboard = Pedalboard::MakeDefault();
int64_t instanceId = currentBank.addPreset(defaultPedalboard);
currentBank.selectedPreset(instanceId);
-1
View File
@@ -24,7 +24,6 @@ using namespace pipedal;
JSON_MAP_BEGIN(VuUpdateX)
JSON_MAP_REFERENCE(VuUpdateX,pedalboardType)
JSON_MAP_REFERENCE(VuUpdateX,instanceId)
JSON_MAP_REFERENCE(VuUpdateX,sampleTime)
JSON_MAP_REFERENCE(VuUpdateX,isStereoInput)
-4
View File
@@ -27,7 +27,6 @@ namespace pipedal
class VuUpdateX
{
public:
int pedalboardType_ = (int)PedalboardType::Invalid;
int64_t instanceId_ = 0;
long sampleTime_ = 0;
bool isStereoInput_ = false;
@@ -38,9 +37,6 @@ namespace pipedal
float outputMaxValueR_ = 0;
public:
PedalboardType pedalboardType() const { return (PedalboardType)pedalboardType_; }
void pedalboardType(PedalboardType value) { pedalboardType_ = (int)value; }
void reset() {
inputMaxValueL_ = 0;
inputMaxValueR_ = 0;