diff --git a/distrho/DistrhoPlugin.hpp b/distrho/DistrhoPlugin.hpp index 964acdc7..aed60510 100644 --- 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 index 37cdb7c9..932019fe 100644 --- 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 index c22706e6..2ad54c22 100644 --- 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 visitedInputPortGroups; for (uint32_t i=0; i::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 visitedOutputPortGroups; for (uint32_t i=0; i::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(busIndex); + uint32_t busId = static_cast(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 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= 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(busId); + uint32_t busId = static_cast(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