commit 17eecabd4011e087a49a2144164bee1ec3645ade
parent 1aa5892a13d7797935964443ae7dda6e08c470cd
Author: falkTX <falktx@falktx.com>
Date: Fri, 22 Jul 2022 06:45:41 +0100
Deal a bit more with VST3 buses and arrangements
Signed-off-by: falkTX <falktx@falktx.com>
Diffstat:
3 files changed, 299 insertions(+), 113 deletions(-)
diff --git a/distrho/DistrhoPlugin.hpp b/distrho/DistrhoPlugin.hpp
@@ -636,6 +636,9 @@ struct Parameter {
A group can be applied to both inputs and outputs (at the same time).
The same group cannot be used in audio ports and parameters.
+ When both audio and parameter groups are used, audio groups MUST be defined first.
+ That is, group indexes start with audio ports, then parameters.
+
An audio port group logically combines ports which should be considered part of the same stream.@n
For example, two audio ports in a group may form a stereo stream.
diff --git a/distrho/src/DistrhoPluginInternal.hpp b/distrho/src/DistrhoPluginInternal.hpp
@@ -674,6 +674,32 @@ public:
return fData->portGroupCount;
}
+ uint32_t getPortCountWithGroupId(const bool input, const uint32_t groupId) const noexcept
+ {
+ DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, 0);
+
+ uint32_t numPorts = 0;
+
+ if (input)
+ {
+ for (uint32_t i=0; i<(input ? DISTRHO_PLUGIN_NUM_INPUTS : DISTRHO_PLUGIN_NUM_OUTPUTS); ++i)
+ {
+ if (fData->audioPorts[i].groupId == groupId)
+ ++numPorts;
+ }
+ }
+ else
+ {
+ for (uint32_t i=0; i<(input ? DISTRHO_PLUGIN_NUM_INPUTS : DISTRHO_PLUGIN_NUM_OUTPUTS); ++i)
+ {
+ if (fData->audioPorts[i + DISTRHO_PLUGIN_NUM_INPUTS].groupId == groupId)
+ ++numPorts;
+ }
+ }
+
+ return numPorts;
+ }
+
const PortGroupWithId& getPortGroupById(const uint32_t groupId) const noexcept
{
DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr && fData->portGroupCount != 0, sFallbackPortGroup);
diff --git a/distrho/src/DistrhoPluginVST3.cpp b/distrho/src/DistrhoPluginVST3.cpp
@@ -276,13 +276,15 @@ class PluginVst3
uint32_t numMainAudio;
uint32_t numSidechain;
uint32_t numCV;
+ uint32_t numGroups;
BusInfo()
: audio(0),
sidechain(0),
numMainAudio(0),
numSidechain(0),
- numCV(0) {}
+ numCV(0),
+ numGroups(0) {}
} inputBuses, outputBuses;
#if DISTRHO_PLUGIN_WANT_MIDI_INPUT
@@ -601,16 +603,28 @@ public:
#endif
{
#if DISTRHO_PLUGIN_NUM_INPUTS > 0
+ std::vector<uint32_t> visitedInputPortGroups;
for (uint32_t i=0; i<DISTRHO_PLUGIN_NUM_INPUTS; ++i)
{
- const uint32_t hints = fPlugin.getAudioPortHints(true, i);
+ AudioPortWithBusId& port(fPlugin.getAudioPort(true, i));
+
+ if (port.groupId != kPortGroupNone)
+ {
+ const std::vector<uint32_t>::iterator end = visitedInputPortGroups.end();
+ if (std::find(visitedInputPortGroups.begin(), end, port.groupId) == end)
+ {
+ visitedInputPortGroups.push_back(port.groupId);
+ ++inputBuses.numGroups;
+ }
+ continue;
+ }
- if (hints & kAudioPortIsCV)
+ if (port.hints & kAudioPortIsCV)
++inputBuses.numCV;
else
++inputBuses.numMainAudio;
- if (hints & kAudioPortIsSidechain)
+ if (port.hints & kAudioPortIsSidechain)
++inputBuses.numSidechain;
}
@@ -624,25 +638,46 @@ public:
{
AudioPortWithBusId& port(fPlugin.getAudioPort(true, i));
- if (port.hints & kAudioPortIsCV)
- port.busId = inputBuses.audio + inputBuses.sidechain + cvInputBusId++;
- else if (port.hints & kAudioPortIsSidechain)
- port.busId = inputBuses.audio;
+ if (port.groupId != kPortGroupNone)
+ {
+ port.busId = port.groupId;
+ }
else
- port.busId = 0;
+ {
+ if (port.hints & kAudioPortIsCV)
+ port.busId = inputBuses.audio + inputBuses.sidechain + cvInputBusId++;
+ else if (port.hints & kAudioPortIsSidechain)
+ port.busId = inputBuses.audio;
+ else
+ port.busId = 0;
+
+ port.busId += inputBuses.numGroups;
+ }
}
#endif
#if DISTRHO_PLUGIN_NUM_OUTPUTS > 0
+ std::vector<uint32_t> visitedOutputPortGroups;
for (uint32_t i=0; i<DISTRHO_PLUGIN_NUM_OUTPUTS; ++i)
{
- const uint32_t hints = fPlugin.getAudioPortHints(false, i);
+ AudioPortWithBusId& port(fPlugin.getAudioPort(false, i));
+
+ if (port.groupId != kPortGroupNone)
+ {
+ const std::vector<uint32_t>::iterator end = visitedOutputPortGroups.end();
+ if (std::find(visitedOutputPortGroups.begin(), end, port.groupId) == end)
+ {
+ visitedOutputPortGroups.push_back(port.groupId);
+ ++outputBuses.numGroups;
+ }
+ continue;
+ }
- if (hints & kAudioPortIsCV)
+ if (port.hints & kAudioPortIsCV)
++outputBuses.numCV;
else
++outputBuses.numMainAudio;
- if (hints & kAudioPortIsSidechain)
+ if (port.hints & kAudioPortIsSidechain)
++outputBuses.numSidechain;
}
@@ -656,12 +691,21 @@ public:
{
AudioPortWithBusId& port(fPlugin.getAudioPort(false, i));
- if (port.hints & kAudioPortIsCV)
- port.busId = outputBuses.audio + outputBuses.sidechain + cvOutputBusId++;
- else if (port.hints & kAudioPortIsSidechain)
- port.busId = outputBuses.audio;
+ if (port.groupId != kPortGroupNone)
+ {
+ port.busId = port.groupId;
+ }
else
- port.busId = 0;
+ {
+ if (port.hints & kAudioPortIsCV)
+ port.busId = outputBuses.audio + outputBuses.sidechain + cvOutputBusId++;
+ else if (port.hints & kAudioPortIsSidechain)
+ port.busId = outputBuses.audio;
+ else
+ port.busId = 0;
+
+ port.busId += outputBuses.numGroups;
+ }
}
#endif
@@ -783,9 +827,9 @@ public:
{
case V3_AUDIO:
if (busDirection == V3_INPUT)
- return inputBuses.audio + inputBuses.sidechain + inputBuses.numCV;
+ return inputBuses.audio + inputBuses.sidechain + inputBuses.numCV + inputBuses.numGroups;
if (busDirection == V3_OUTPUT)
- return outputBuses.audio + outputBuses.sidechain + outputBuses.numCV;
+ return outputBuses.audio + outputBuses.sidechain + outputBuses.numCV + outputBuses.numGroups;
break;
case V3_EVENT:
#if DISTRHO_PLUGIN_WANT_MIDI_INPUT
@@ -812,7 +856,7 @@ public:
DISTRHO_SAFE_ASSERT_INT_RETURN(busIndex >= 0, busIndex, V3_INVALID_ARG);
#if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0 || DISTRHO_PLUGIN_WANT_MIDI_INPUT || DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
- const uint32_t busId = static_cast<uint32_t>(busIndex);
+ uint32_t busId = static_cast<uint32_t>(busIndex);
#endif
if (mediaType == V3_AUDIO)
@@ -826,49 +870,96 @@ public:
if (busDirection == V3_INPUT)
{
#if DISTRHO_PLUGIN_NUM_INPUTS > 0
- switch (busId)
+ if (busId < inputBuses.numGroups)
{
- case 0:
- if (inputBuses.audio)
- {
- numChannels = inputBuses.numMainAudio;
- busType = V3_MAIN;
- flags = V3_DEFAULT_ACTIVE;
- break;
- }
- // fall-through
- case 1:
- if (inputBuses.sidechain)
- {
- numChannels = inputBuses.numSidechain;
- busType = V3_AUX;
- flags = 0;
- break;
- }
- // fall-through
- default:
- numChannels = 1;
+ numChannels = fPlugin.getPortCountWithGroupId(true, busId);
busType = V3_AUX;
- flags = V3_IS_CONTROL_VOLTAGE;
- break;
- }
+ flags = 0;
- if (busType == V3_MAIN)
- {
- strncpy_utf16(busName, "Audio Input", 128);
- }
- else
- {
for (uint32_t i=0; i<DISTRHO_PLUGIN_NUM_INPUTS; ++i)
{
const AudioPortWithBusId& port(fPlugin.getAudioPort(true, i));
- // TODO find port group name for sidechain buses
if (port.busId == busId)
{
- strncpy_utf16(busName, port.name, 128);
+ const PortGroupWithId& group(fPlugin.getPortGroupById(port.groupId));
+
+ switch (port.groupId)
+ {
+ case kPortGroupMono:
+ case kPortGroupStereo:
+ strncpy_utf16(busName, "Audio Input", 128);
+ break;
+ default:
+ if (group.name.isNotEmpty())
+ strncpy_utf16(busName, group.name, 128);
+ else
+ strncpy_utf16(busName, port.name, 128);
+ break;
+ }
+
+ if (inputBuses.audio == 0 && (port.hints & kAudioPortIsSidechain) == 0x0)
+ {
+ busType = V3_MAIN;
+ flags = V3_DEFAULT_ACTIVE;
+ }
+ break;
+ }
+ }
+ }
+ else
+ {
+ busId -= inputBuses.numGroups;
+
+ switch (busId)
+ {
+ case 0:
+ if (inputBuses.audio)
+ {
+ numChannels = inputBuses.numMainAudio;
+ busType = V3_MAIN;
+ flags = V3_DEFAULT_ACTIVE;
+ break;
+ }
+ // fall-through
+ case 1:
+ if (inputBuses.sidechain)
+ {
+ numChannels = inputBuses.numSidechain;
+ busType = V3_AUX;
+ flags = 0;
break;
}
+ // fall-through
+ default:
+ numChannels = 1;
+ busType = V3_AUX;
+ flags = V3_IS_CONTROL_VOLTAGE;
+ break;
+ }
+
+ if (busType == V3_MAIN)
+ {
+ strncpy_utf16(busName, "Audio Input", 128);
+ }
+ else
+ {
+ for (uint32_t i=0; i<DISTRHO_PLUGIN_NUM_INPUTS; ++i)
+ {
+ const AudioPortWithBusId& port(fPlugin.getAudioPort(true, i));
+
+ if (port.busId == busId)
+ {
+ const PortGroupWithId& group(fPlugin.getPortGroupById(port.groupId));
+
+ if (group.name.isNotEmpty())
+ strncpy_utf16(busName, group.name, 128);
+ else
+ strncpy_utf16(busName, port.name, 128);
+
+ break;
+ }
+ }
}
}
#else
@@ -879,50 +970,98 @@ public:
else
{
#if DISTRHO_PLUGIN_NUM_OUTPUTS > 0
- switch (busId)
+ if (busId < outputBuses.numGroups)
{
- case 0:
- if (outputBuses.audio)
- {
- numChannels = outputBuses.numMainAudio;
- busType = V3_MAIN;
- flags = V3_DEFAULT_ACTIVE;
- break;
- }
- // fall-through
- case 1:
- if (outputBuses.sidechain)
- {
- numChannels = outputBuses.numSidechain;
- busType = V3_AUX;
- flags = 0;
- break;
- }
- // fall-through
- default:
- numChannels = 1;
+ numChannels = fPlugin.getPortCountWithGroupId(false, busId);
busType = V3_AUX;
- flags = V3_IS_CONTROL_VOLTAGE;
- break;
- }
+ flags = 0;
- if (busType == V3_MAIN)
- {
- strncpy_utf16(busName, "Audio Output", 128);
- }
- else
- {
for (uint32_t i=0; i<DISTRHO_PLUGIN_NUM_OUTPUTS; ++i)
{
const AudioPortWithBusId& port(fPlugin.getAudioPort(false, i));
- // TODO find port group name for sidechain buses
if (port.busId == busId)
{
- strncpy_utf16(busName, port.name, 128);
+ const PortGroupWithId& group(fPlugin.getPortGroupById(port.groupId));
+
+ switch (port.groupId)
+ {
+ case kPortGroupMono:
+ case kPortGroupStereo:
+ strncpy_utf16(busName, "Audio Output", 128);
+ break;
+ default:
+ if (group.name.isNotEmpty())
+ strncpy_utf16(busName, group.name, 128);
+ else
+ strncpy_utf16(busName, port.name, 128);
+ break;
+ }
+
+ if (outputBuses.audio == 0 && (port.hints & kAudioPortIsSidechain) == 0x0)
+ {
+ busType = V3_MAIN;
+ flags = V3_DEFAULT_ACTIVE;
+ }
+ break;
+ }
+ }
+ }
+ else
+ {
+ busId -= outputBuses.numGroups;
+
+ switch (busId)
+ {
+ case 0:
+ if (outputBuses.audio)
+ {
+ numChannels = outputBuses.numMainAudio;
+ busType = V3_MAIN;
+ flags = V3_DEFAULT_ACTIVE;
+ break;
+ }
+ // fall-through
+ case 1:
+ if (outputBuses.sidechain)
+ {
+ numChannels = outputBuses.numSidechain;
+ busType = V3_AUX;
+ flags = 0;
break;
}
+ // fall-through
+ default:
+ numChannels = 1;
+ busType = V3_AUX;
+ flags = V3_IS_CONTROL_VOLTAGE;
+ break;
+ }
+
+ if (busType == V3_MAIN)
+ {
+ strncpy_utf16(busName, "Audio Output", 128);
}
+ else
+ {
+ for (uint32_t i=0; i<DISTRHO_PLUGIN_NUM_OUTPUTS; ++i)
+ {
+ const AudioPortWithBusId& port(fPlugin.getAudioPort(false, i));
+
+ if (port.busId == busId)
+ {
+ const PortGroupWithId& group(fPlugin.getPortGroupById(port.groupId));
+
+ if (group.name.isNotEmpty())
+ strncpy_utf16(busName, group.name, 128);
+ else
+ strncpy_utf16(busName, port.name, 128);
+
+ break;
+ }
+ }
+ }
+
}
#else
d_stdout("invalid bus %d", busId);
@@ -1327,14 +1466,14 @@ public:
return V3_NOT_IMPLEMENTED;
}
- v3_result getBusArrangement(const int32_t busDirection, const int32_t busId, v3_speaker_arrangement* const speaker) const noexcept
+ v3_result getBusArrangement(const int32_t busDirection, const int32_t busIndex, v3_speaker_arrangement* const speaker) const noexcept
{
DISTRHO_SAFE_ASSERT_INT_RETURN(busDirection == V3_INPUT || busDirection == V3_OUTPUT, busDirection, V3_INVALID_ARG);
- DISTRHO_SAFE_ASSERT_INT_RETURN(busId >= 0, busId, V3_INVALID_ARG);
+ DISTRHO_SAFE_ASSERT_INT_RETURN(busIndex >= 0, busIndex, V3_INVALID_ARG);
DISTRHO_SAFE_ASSERT_RETURN(speaker != nullptr, V3_INVALID_ARG);
#if DISTRHO_PLUGIN_NUM_INPUTS > 0 || DISTRHO_PLUGIN_NUM_OUTPUTS > 0
- const uint32_t ubusId = static_cast<uint32_t>(busId);
+ uint32_t busId = static_cast<uint32_t>(busIndex);
#endif
if (busDirection == V3_INPUT)
@@ -1344,7 +1483,7 @@ public:
{
AudioPortWithBusId& port(fPlugin.getAudioPort(true, i));
- if (port.busId != ubusId)
+ if (port.busId != busId)
continue;
v3_speaker_arrangement arr;
@@ -1358,25 +1497,34 @@ public:
arr = V3_SPEAKER_L | V3_SPEAKER_R;
break;
default:
- return V3_INVALID_ARG;
- /*
- if (inputBuses.audio != 0 && ubusId == 0)
+ if (busId < inputBuses.numGroups)
{
+ const uint32_t numPortsInBus = fPlugin.getPortCountWithGroupId(true, busId);
arr = 0x0;
- for (uint32_t j=0; j<inputBuses.numMainAudio; ++j)
+ for (uint32_t j=0; j<numPortsInBus; ++j)
arr |= 1ull << (j + 33ull);
}
- else if (inputBuses.sidechain != 0 && ubusId == inputBuses.audio)
- {
- arr = 0x0;
- for (uint32_t j=0; j<inputBuses.numSidechain; ++j)
- arr |= 1ull << (inputBuses.numMainAudio + j + 33ull);
- }
else
{
- arr = 1ull << (inputBuses.numMainAudio + inputBuses.numSidechain + ubusId + 33ull);
+ busId -= inputBuses.numGroups;
+
+ if (inputBuses.audio != 0 && busId == 0)
+ {
+ arr = 0x0;
+ for (uint32_t j=0; j<inputBuses.numMainAudio; ++j)
+ arr |= 1ull << (j + 33ull);
+ }
+ else if (inputBuses.sidechain != 0 && busId == inputBuses.audio)
+ {
+ arr = 0x0;
+ for (uint32_t j=0; j<inputBuses.numSidechain; ++j)
+ arr |= 1ull << (inputBuses.numMainAudio + j + 33ull);
+ }
+ else
+ {
+ arr = 1ull << (inputBuses.numMainAudio + inputBuses.numSidechain + busId + 33ull);
+ }
}
- */
break;
}
@@ -1394,7 +1542,7 @@ public:
{
AudioPortWithBusId& port(fPlugin.getAudioPort(false, i));
- if (port.busId != ubusId)
+ if (port.busId != busId)
continue;
v3_speaker_arrangement arr;
@@ -1408,25 +1556,34 @@ public:
arr = V3_SPEAKER_L | V3_SPEAKER_R;
break;
default:
- return V3_INVALID_ARG;
- /*
- if (outputBuses.audio != 0 && ubusId == 0)
+ if (busId < outputBuses.numGroups)
{
+ const uint32_t numPortsInBus = fPlugin.getPortCountWithGroupId(false, busId);
arr = 0x0;
- for (uint32_t j=0; j<outputBuses.numMainAudio; ++j)
+ for (uint32_t j=0; j<numPortsInBus; ++j)
arr |= 1ull << (j + 33ull);
}
- else if (outputBuses.sidechain != 0 && ubusId == outputBuses.audio)
- {
- arr = 0x0;
- for (uint32_t j=0; j<outputBuses.numSidechain; ++j)
- arr |= 1ull << (outputBuses.numMainAudio + j + 33ull);
- }
else
{
- arr = 1ull << (outputBuses.numMainAudio + outputBuses.numSidechain + ubusId + 33ull);
+ busId -= outputBuses.numGroups;
+
+ if (outputBuses.audio != 0 && busId == 0)
+ {
+ arr = 0x0;
+ for (uint32_t j=0; j<outputBuses.numMainAudio; ++j)
+ arr |= 1ull << (j + 33ull);
+ }
+ else if (outputBuses.sidechain != 0 && busId == outputBuses.audio)
+ {
+ arr = 0x0;
+ for (uint32_t j=0; j<outputBuses.numSidechain; ++j)
+ arr |= 1ull << (outputBuses.numMainAudio + j + 33ull);
+ }
+ else
+ {
+ arr = 1ull << (outputBuses.numMainAudio + outputBuses.numSidechain + busId + 33ull);
+ }
}
- */
break;
}