Skip to content

Commit

Permalink
Server: Try many more layouts before falling back to the plugin default
Browse files Browse the repository at this point in the history
  • Loading branch information
apohl79 committed May 16, 2022
1 parent 2a67409 commit d095a2c
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 58 deletions.
3 changes: 1 addition & 2 deletions Server/Source/AudioWorker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@ void AudioWorker::init(std::unique_ptr<StreamingSocket> s, HandshakeRequest cfg)
m_channelMapper.createServerMapping(m_activeChannels);
m_channelMapper.print();
m_chain = std::make_shared<ProcessorChain>(
ProcessorChain::createBussesProperties(m_channelsIn, m_channelsOut, m_channelsSC), cfg);
m_chain->setLogTagSource(getLogTagSource());
getLogTagSource(), ProcessorChain::createBussesProperties(m_channelsIn, m_channelsOut, m_channelsSC), cfg);
if (m_doublePrecission && m_chain->supportsDoublePrecisionProcessing()) {
m_chain->setProcessingPrecision(AudioProcessor::doublePrecision);
}
Expand Down
145 changes: 95 additions & 50 deletions Server/Source/ProcessorChain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ bool ProcessorChain::setProcessorBusesLayout(Processor* proc) {
layout.inputBuses.add(AudioChannelSet::mono());
supported = proc->checkBusesLayoutSupported(layout) && proc->setBusesLayout(layout);
}

if (!supported) {
logln("trying without sidechain bus");
layout.inputBuses.remove(1);
Expand All @@ -125,31 +126,81 @@ bool ProcessorChain::setProcessorBusesLayout(Processor* proc) {
}
}
}

if (!supported && layout.getMainOutputChannels() > 2 && layout.getMainInputChannels() == 0) {
logln("trying multi-mono-bus layout for instrument");
AudioProcessor::BusesLayout layout2;
for (int ch = 0; ch < layout.getMainOutputChannels(); ch++) {
layout2.outputBuses.add(AudioChannelSet::mono());
}
supported = proc->checkBusesLayoutSupported(layout2) && proc->setBusesLayout(layout2);
if (!supported) {
logln("trying multi-stereo-bus layout for instrument");
layout2.outputBuses.clear();
for (int ch = 0; ch + 1 < layout.getMainOutputChannels(); ch += 2) {
layout2.outputBuses.add(AudioChannelSet::stereo());
auto addInputs = [](AudioProcessor::BusesLayout& l, int channels) {
l.inputBuses.clear();

if (channels == 1) {
l.inputBuses.add(AudioChannelSet::mono());
} else if (channels == 2) {
l.inputBuses.add(AudioChannelSet::stereo());
} else {
l.inputBuses.add(AudioChannelSet::discreteChannels(channels));
}
supported = proc->checkBusesLayoutSupported(layout2) && proc->setBusesLayout(layout2);
}
if (!supported) {
logln("trying multi-mono-bus layout with stereo main for instrument");
layout2.outputBuses.clear();
layout2.outputBuses.add(AudioChannelSet::stereo());
for (int ch = 2; ch < layout.getMainOutputChannels(); ch++) {
layout2.outputBuses.add(AudioChannelSet::mono());
};

auto addOutputsAndLayout = [](Array<AudioProcessor::BusesLayout>& layouts, AudioProcessor::BusesLayout& l,
int channels) {

// try layouts with different combinations of stereo and mono buses
int numStereo = channels / 2;

while (numStereo >= 0) {
l.outputBuses.clear();

int numMono = channels - numStereo * 2;

for (int ch = 0; ch < numStereo; ch++) {
l.outputBuses.add(AudioChannelSet::stereo());
}

for (int ch = 0; ch < numMono; ch++) {
l.outputBuses.add(AudioChannelSet::mono());
}

layouts.add(l);

numStereo--;
}
supported = proc->checkBusesLayoutSupported(layout2) && proc->setBusesLayout(layout2);
}

// try layouts with one bus with the exact number of channels
for (auto channelSet : AudioChannelSet::channelSetsWithNumberOfChannels(channels)) {
l.outputBuses.clear();
l.outputBuses.add(channelSet);
layouts.add(l);
}
};

auto check = [&](int channels) {
Array<AudioProcessor::BusesLayout> layouts;
AudioProcessor::BusesLayout layout2;

addOutputsAndLayout(layouts, layout2, channels);

addInputs(layout2, 2);
addOutputsAndLayout(layouts, layout2, channels);

addInputs(layout2, 1);
addOutputsAndLayout(layouts, layout2, channels);

for (auto& l : layouts) {
if (proc->checkBusesLayoutSupported(l) && proc->setBusesLayout(l)) {
return true;
}
}

return false;
};

int channelsToTry = Defaults::PLUGIN_CHANNELS_MAX;

do {
logln("trying instrument-multi-bus layouts with " << channelsToTry << " channels");
supported = check(channelsToTry--);
} while (!supported && channelsToTry > 0);
}

if (!supported) {
if (hasSidechain) {
logln("disabling sidechain input to use the plugins I/O layout");
Expand All @@ -161,42 +212,36 @@ bool ProcessorChain::setProcessorBusesLayout(Processor* proc) {

logln("falling back to the plugins default layout");

// keep the processor's layout and calculate the neede extra channels
auto procLayout = proc->getBusesLayout();
supported = true;
}
}

// main bus IN
int extraInChannels = procLayout.getMainInputChannels() - layout.getMainInputChannels();
// check extra busses IN
for (int busIdx = 1; busIdx < procLayout.inputBuses.size(); busIdx++) {
extraInChannels += procLayout.inputBuses[busIdx].size();
}
// main bus OUT
int extraOutChannels = procLayout.getMainOutputChannels() - layout.getMainOutputChannels();
// check extra busses OUT
for (int busIdx = 1; busIdx < procLayout.outputBuses.size(); busIdx++) {
extraOutChannels += procLayout.outputBuses[busIdx].size();
}
auto procLayout = proc->getBusesLayout();

proc->setExtraChannels(extraInChannels, extraOutChannels);
// main bus IN
int extraInChannels = procLayout.getMainInputChannels() - layout.getMainInputChannels();
// check extra busses IN
for (int busIdx = 1; busIdx < procLayout.inputBuses.size(); busIdx++) {
extraInChannels += procLayout.inputBuses[busIdx].size();
}
// main bus OUT
int extraOutChannels = procLayout.getMainOutputChannels() - layout.getMainOutputChannels();
// check extra busses OUT
for (int busIdx = 1; busIdx < procLayout.outputBuses.size(); busIdx++) {
extraOutChannels += procLayout.outputBuses[busIdx].size();
}

m_extraChannels = jmax(m_extraChannels, extraInChannels, extraOutChannels);
proc->setExtraChannels(extraInChannels, extraOutChannels);

logln(extraInChannels << " extra input(s), " << extraOutChannels << " extra output(s) -> "
<< m_extraChannels << " extra channel(s) in total");
m_extraChannels = jmax(m_extraChannels, extraInChannels, extraOutChannels);

layout = procLayout;
supported = true;
}
}
logln(extraInChannels << " extra input(s), " << extraOutChannels << " extra output(s) -> " << m_extraChannels
<< " extra channel(s) in total");

if (supported) {
logln("using I/O layout:");
printBusesLayout(layout);
} else {
logln("no working I/O layout found");
}
logln("setting processor to I/O layout:");
printBusesLayout(procLayout);

return supported;
return true;
}

int ProcessorChain::getExtraChannels() {
Expand Down
14 changes: 9 additions & 5 deletions Tests/Source/Server/ProcessorChainTest.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,25 +31,27 @@ class ProcessorChainTest : UnitTest {

int chIn = 2, chOut = 2, chSc = 0;

auto pc = std::make_unique<ProcessorChain>(ProcessorChain::createBussesProperties(chIn, chOut, chSc),
LogTag testTag("test");

auto pc = std::make_unique<ProcessorChain>(&testTag, ProcessorChain::createBussesProperties(chIn, chOut, chSc),
HandshakeRequest());
expect(pc->updateChannels(chIn, chOut, chSc));
pc.reset();

chIn = chOut = 64;
pc = std::make_unique<ProcessorChain>(ProcessorChain::createBussesProperties(chIn, chOut, chSc),
pc = std::make_unique<ProcessorChain>(&testTag, ProcessorChain::createBussesProperties(chIn, chOut, chSc),
HandshakeRequest());
expect(pc->updateChannels(chIn, chOut, chSc));
pc.reset();

chSc = 2;
pc = std::make_unique<ProcessorChain>(ProcessorChain::createBussesProperties(chIn, chOut, chSc),
pc = std::make_unique<ProcessorChain>(&testTag, ProcessorChain::createBussesProperties(chIn, chOut, chSc),
HandshakeRequest());
expect(pc->updateChannels(chIn, chOut, chSc));
pc.reset();

chIn = chOut = chSc = 2;
pc = std::make_unique<ProcessorChain>(ProcessorChain::createBussesProperties(chIn, chOut, chSc),
pc = std::make_unique<ProcessorChain>(&testTag, ProcessorChain::createBussesProperties(chIn, chOut, chSc),
HandshakeRequest());
expect(pc->updateChannels(chIn, chOut, chSc));
}
Expand All @@ -60,7 +62,9 @@ class ProcessorChainTest : UnitTest {
double sampleRate = 48000.0;
int blockSize = 512, chIn = 2, chOut = 2, chSc = 2;

auto pc = std::make_unique<ProcessorChain>(ProcessorChain::createBussesProperties(chIn, chOut, chSc),
LogTag testTag("test");

auto pc = std::make_unique<ProcessorChain>(&testTag, ProcessorChain::createBussesProperties(chIn, chOut, chSc),
HandshakeRequest());
pc->updateChannels(chIn, chOut, chSc);
pc->prepareToPlay(sampleRate, blockSize);
Expand Down
5 changes: 4 additions & 1 deletion Tests/Source/Server/SandboxPluginTest.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@ class SandboxPluginTest : UnitTest {
HandshakeRequest cfg = {AG_PROTOCOL_VERSION, chIn, chOut, chSc, sampleRate, blockSize, false, 0, 0, 0,
activeChannels.toInt(), 0};

auto pc = std::make_unique<ProcessorChain>(ProcessorChain::createBussesProperties(chIn, chOut, chSc), cfg);
LogTag testTag("test");

auto pc =
std::make_unique<ProcessorChain>(&testTag, ProcessorChain::createBussesProperties(chIn, chOut, chSc), cfg);
pc->setProcessingPrecision(AudioProcessor::singlePrecision);
pc->updateChannels(chIn, chOut, chSc);
pc->prepareToPlay(sampleRate, blockSize);
Expand Down

0 comments on commit d095a2c

Please sign in to comment.