DPF

DISTRHO Plugin Framework
Log | Files | Refs | Submodules | README | LICENSE

commit 7fb4d014e8db06e7171446824255f1cfeb7cb173
parent a27d7a9b67a15443ae5911dbf5c14a299d303017
Author: falkTX <falktx@falktx.com>
Date:   Sun,  7 Aug 2022 02:17:55 +0100

Unduplicate some VST3 common code

Diffstat:
Mdistrho/src/DistrhoPluginVST3.cpp | 777+++++++++++++++++++++++++++++++++----------------------------------------------
1 file changed, 328 insertions(+), 449 deletions(-)

diff --git a/distrho/src/DistrhoPluginVST3.cpp b/distrho/src/DistrhoPluginVST3.cpp @@ -54,7 +54,6 @@ * - bus arrangements * - optional audio buses * - routing info, do we care? - * - set sidechain bus name from port group * == CV * - cv scaling to -1/+1 * - test in at least 1 host @@ -257,13 +256,18 @@ v3_plugin_view** dpf_plugin_view_create(v3_host_application** host, void* instan * VST3 DSP class. * * All the dynamic things from VST3 get implemented here, free of complex low-level VST3 pointer things. - * The DSP is created during the "initialize" component event, and destroyed during "terminate". + * This class is created during the "initialize" component event, and destroyed during "terminate". * * The low-level VST3 stuff comes after. */ class PluginVst3 { - /* buses: we provide 1 for the main audio (if there is any) plus 1 for each sidechain or cv port. + /* Buses: count possible buses we can provide to the host, in case they are not yet defined by the developer. + * These values are only used if port groups aren't set. + * We count the number of used port groups in `numGroups`. + * + * When port groups are not in use, we fill in appropriately. + * 1 bus is provided for the main audio (if there is any) plus 1 for each sidechain or cv port. * Main audio comes first, if available. * Then sidechain, also if available. * And finally each CV port individually. @@ -288,10 +292,10 @@ class PluginVst3 } inputBuses, outputBuses; #if DISTRHO_PLUGIN_WANT_MIDI_INPUT - /* handy class for storing and sorting events and MIDI CC parameters - * only stores events for which a MIDI conversion is possible. + /* Handy class for storing and sorting VST3 events and MIDI CC parameters. + * It will only store events for which a MIDI conversion is possible. */ - struct InputEventsList { + struct InputEventList { enum Type { NoteOn, NoteOff, @@ -313,17 +317,17 @@ class PluginVst3 }; } eventListStorage[kMaxMidiEvents]; - struct InputEventTiming { + struct InputEvent { int32_t sampleOffset; const InputEventStorage* storage; - InputEventTiming* next; + InputEvent* next; } eventList[kMaxMidiEvents]; uint16_t numUsed; int32_t firstSampleOffset; int32_t lastSampleOffset; - InputEventTiming* firstEvent; - InputEventTiming* lastEvent; + InputEvent* firstEvent; + InputEvent* lastEvent; void init() { @@ -336,7 +340,7 @@ class PluginVst3 { uint32_t count = 0; - for (const InputEventTiming* event = firstEvent; event != nullptr; event = event->next) + for (const InputEvent* event = firstEvent; event != nullptr; event = event->next) { MidiEvent& midiEvent(midiEvents[count++]); midiEvent.frame = event->sampleOffset; @@ -491,7 +495,7 @@ class PluginVst3 eventStorage.type = UI_MIDI; std::memcpy(eventStorage.midi, midiData, sizeof(uint8_t)*3); - InputEventTiming* const event = &eventList[numUsed]; + InputEvent* const event = &eventList[numUsed]; event->sampleOffset = 0; event->storage = &eventStorage; @@ -514,7 +518,7 @@ class PluginVst3 private: bool placeSorted(const int32_t sampleOffset) noexcept { - InputEventTiming* const event = &eventList[numUsed]; + InputEvent* const event = &eventList[numUsed]; // initialize if (numUsed == 0) @@ -542,7 +546,7 @@ class PluginVst3 else { // keep reference out of the loop so we can check validity afterwards - InputEventTiming* event2 = firstEvent; + InputEvent* event2 = firstEvent; // iterate all events for (; event2 != nullptr; event2 = event2->next) @@ -575,39 +579,39 @@ public: PluginVst3(v3_host_application** const host) : fPlugin(this, writeMidiCallback, requestParameterValueChangeCallback, nullptr), fComponentHandler(nullptr), -#if DISTRHO_PLUGIN_HAS_UI -# if DPF_VST3_USES_SEPARATE_CONTROLLER + #if DISTRHO_PLUGIN_HAS_UI + #if DPF_VST3_USES_SEPARATE_CONTROLLER fConnectionFromCompToCtrl(nullptr), -# endif + #endif fConnectionFromCtrlToView(nullptr), fHostApplication(host), -#endif + #endif fParameterCount(fPlugin.getParameterCount()), fVst3ParameterCount(fParameterCount + kVst3InternalParameterCount), fCachedParameterValues(nullptr), fDummyAudioBuffer(nullptr), fParameterValuesChangedDuringProcessing(nullptr) -#if DISTRHO_PLUGIN_HAS_UI + #if DISTRHO_PLUGIN_HAS_UI , fParameterValueChangesForUI(nullptr) , fConnectedToUI(false) -#endif -#if DISTRHO_PLUGIN_WANT_LATENCY + #endif + #if DISTRHO_PLUGIN_WANT_LATENCY , fLastKnownLatency(fPlugin.getLatency()) -#endif -#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT + #endif + #if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT , fHostEventOutputHandle(nullptr) -#endif -#if DISTRHO_PLUGIN_WANT_PROGRAMS + #endif + #if DISTRHO_PLUGIN_WANT_PROGRAMS , fCurrentProgram(0) , fProgramCountMinusOne(fPlugin.getProgramCount()-1) -#endif + #endif { -#if DISTRHO_PLUGIN_NUM_INPUTS > 0 + #if DISTRHO_PLUGIN_NUM_INPUTS > 0 fillInBusInfoDetails<true>(); -#endif -#if DISTRHO_PLUGIN_NUM_OUTPUTS > 0 + #endif + #if DISTRHO_PLUGIN_NUM_OUTPUTS > 0 fillInBusInfoDetails<false>(); -#endif + #endif if (const uint32_t extraParameterCount = fParameterCount + kVst3InternalParameterBaseCount) { @@ -732,14 +736,14 @@ public: return outputBuses.audio + outputBuses.sidechain + outputBuses.numCV + outputBuses.numGroups; break; case V3_EVENT: -#if DISTRHO_PLUGIN_WANT_MIDI_INPUT + #if DISTRHO_PLUGIN_WANT_MIDI_INPUT if (busDirection == V3_INPUT) return 1; -#endif -#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT + #endif + #if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT if (busDirection == V3_OUTPUT) return 1; -#endif + #endif break; } @@ -755,228 +759,31 @@ public: DISTRHO_SAFE_ASSERT_INT_RETURN(busDirection == V3_INPUT || busDirection == V3_OUTPUT, busDirection, V3_INVALID_ARG); 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 - uint32_t busId = static_cast<uint32_t>(busIndex); -#endif + #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); + #endif if (mediaType == V3_AUDIO) { #if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0 - int32_t numChannels; - uint32_t flags; - v3_bus_types busType; - v3_str_128 busName = {}; - if (busDirection == V3_INPUT) { #if DISTRHO_PLUGIN_NUM_INPUTS > 0 - if (busId < inputBuses.numGroups) - { - numChannels = fPlugin.getAudioPortCountWithGroupId(true, busId); - busType = V3_AUX; - flags = 0; - - 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)); - - 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; - } - } - } - } + return getAudioBusInfo<true>(busId, info); #else - d_stdout("invalid bus %d", busId); + d_stdout("invalid input bus %d", busId); return V3_INVALID_ARG; #endif // DISTRHO_PLUGIN_NUM_INPUTS } else { #if DISTRHO_PLUGIN_NUM_OUTPUTS > 0 - if (busId < outputBuses.numGroups) - { - numChannels = fPlugin.getAudioPortCountWithGroupId(false, busId); - busType = V3_AUX; - flags = 0; - - 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)); - - 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; - } - } - } - - } + return getAudioBusInfo<false>(busId, info); #else - d_stdout("invalid bus %d", busId); + d_stdout("invalid output bus %d", busId); return V3_INVALID_ARG; #endif // DISTRHO_PLUGIN_NUM_OUTPUTS } - - std::memset(info, 0, sizeof(v3_bus_info)); - info->media_type = V3_AUDIO; - info->direction = busDirection; - info->channel_count = numChannels; - std::memcpy(info->bus_name, busName, sizeof(busName)); - info->bus_type = busType; - info->flags = flags; - return V3_OK; #else d_stdout("invalid bus, line %d", __LINE__); return V3_INVALID_ARG; @@ -1373,130 +1180,24 @@ public: DISTRHO_SAFE_ASSERT_RETURN(speaker != nullptr, V3_INVALID_ARG); #if DISTRHO_PLUGIN_NUM_INPUTS > 0 || DISTRHO_PLUGIN_NUM_OUTPUTS > 0 - uint32_t busId = static_cast<uint32_t>(busIndex); + const uint32_t busId = static_cast<uint32_t>(busIndex); #endif if (busDirection == V3_INPUT) { #if DISTRHO_PLUGIN_NUM_INPUTS > 0 - for (uint32_t i=0; i<DISTRHO_PLUGIN_NUM_INPUTS; ++i) - { - AudioPortWithBusId& port(fPlugin.getAudioPort(true, i)); - - if (port.busId != busId) - { - d_stdout("port.busId != busId: %d %d", port.busId, busId); - continue; - } - - v3_speaker_arrangement arr; - - switch (port.groupId) - { - case kPortGroupMono: - arr = V3_SPEAKER_M; - break; - case kPortGroupStereo: - arr = V3_SPEAKER_L | V3_SPEAKER_R; - break; - default: - if (busId < inputBuses.numGroups) - { - const uint32_t numPortsInBus = fPlugin.getAudioPortCountWithGroupId(true, busId); - arr = 0x0; - for (uint32_t j=0; j<numPortsInBus; ++j) - arr |= 1ull << (j + 33ull); - } - else - { - 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; - } - - *speaker = arr; + if (getAudioBusArrangement<true>(busId, speaker)) return V3_OK; - } - #endif // DISTRHO_PLUGIN_NUM_INPUTS + #endif d_stdout("invalid input bus arrangement %d", busIndex); return V3_INVALID_ARG; } else { #if DISTRHO_PLUGIN_NUM_OUTPUTS > 0 - for (uint32_t i=0; i<DISTRHO_PLUGIN_NUM_OUTPUTS; ++i) - { - AudioPortWithBusId& port(fPlugin.getAudioPort(false, i)); - - if (port.busId != busId) - { - d_stdout("port.busId != busId: %d %d", port.busId, busId); - continue; - } - - v3_speaker_arrangement arr; - - switch (port.groupId) - { - case kPortGroupMono: - arr = V3_SPEAKER_M; - break; - case kPortGroupStereo: - arr = V3_SPEAKER_L | V3_SPEAKER_R; - break; - default: - if (busId < outputBuses.numGroups) - { - const uint32_t numPortsInBus = fPlugin.getAudioPortCountWithGroupId(false, busId); - arr = 0x0; - for (uint32_t j=0; j<numPortsInBus; ++j) - arr |= 1ull << (j + 33ull); - } - else - { - 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; - } - - *speaker = arr; + if (getAudioBusArrangement<false>(busId, speaker)) return V3_OK; - } - #endif // DISTRHO_PLUGIN_NUM_OUTPUTS + #endif d_stdout("invalid output bus arrangement %d", busIndex); return V3_INVALID_ARG; } @@ -2589,13 +2290,13 @@ private: // VST3 stuff v3_component_handler** fComponentHandler; -#if DISTRHO_PLUGIN_HAS_UI + #if DISTRHO_PLUGIN_HAS_UI #if DPF_VST3_USES_SEPARATE_CONTROLLER v3_connection_point** fConnectionFromCompToCtrl; #endif v3_connection_point** fConnectionFromCtrlToView; v3_host_application** const fHostApplication; -#endif + #endif // Temporary data const uint32_t fParameterCount; @@ -2603,35 +2304,35 @@ private: float* fCachedParameterValues; // basic offset + real float* fDummyAudioBuffer; bool* fParameterValuesChangedDuringProcessing; // basic offset + real -#if DISTRHO_PLUGIN_HAS_UI + #if DISTRHO_PLUGIN_HAS_UI bool* fParameterValueChangesForUI; // basic offset + real bool fConnectedToUI; -#endif -#if DISTRHO_PLUGIN_WANT_LATENCY + #endif + #if DISTRHO_PLUGIN_WANT_LATENCY uint32_t fLastKnownLatency; -#endif -#if DISTRHO_PLUGIN_WANT_MIDI_INPUT + #endif + #if DISTRHO_PLUGIN_WANT_MIDI_INPUT MidiEvent fMidiEvents[kMaxMidiEvents]; -# if DISTRHO_PLUGIN_HAS_UI + #if DISTRHO_PLUGIN_HAS_UI SmallStackRingBuffer fNotesRingBuffer; -# endif -#endif -#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT + #endif + #endif + #if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT v3_event_list** fHostEventOutputHandle; -#endif -#if DISTRHO_PLUGIN_WANT_PROGRAMS + #endif + #if DISTRHO_PLUGIN_WANT_PROGRAMS uint32_t fCurrentProgram; const uint32_t fProgramCountMinusOne; -#endif -#if DISTRHO_PLUGIN_WANT_STATE + #endif + #if DISTRHO_PLUGIN_WANT_STATE StringMap fStateMap; -#endif -#if DISTRHO_PLUGIN_WANT_TIMEPOS + #endif + #if DISTRHO_PLUGIN_WANT_TIMEPOS TimePosition fTimePosition; -#endif + #endif // ---------------------------------------------------------------------------------------------------------------- - // bus related helper functions called on constructor + // helper functions for dealing with buses #if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0 template<bool isInput> @@ -2693,6 +2394,185 @@ private: } } } + + template<bool isInput> + v3_result getAudioBusInfo(uint32_t busId, v3_bus_info* const info) const + { + constexpr const uint32_t numPorts = isInput ? DISTRHO_PLUGIN_NUM_INPUTS : DISTRHO_PLUGIN_NUM_OUTPUTS; + const BusInfo& bufInfo(isInput ? inputBuses : outputBuses); + + int32_t numChannels; + uint32_t flags; + v3_bus_types busType; + v3_str_128 busName = {}; + + if (busId < bufInfo.numGroups) + { + numChannels = fPlugin.getAudioPortCountWithGroupId(isInput, busId); + busType = V3_AUX; + flags = 0; + + for (uint32_t i=0; i<numPorts; ++i) + { + const AudioPortWithBusId& port(fPlugin.getAudioPort(isInput, i)); + + if (port.busId == busId) + { + const PortGroupWithId& group(fPlugin.getPortGroupById(port.groupId)); + + switch (port.groupId) + { + case kPortGroupMono: + case kPortGroupStereo: + strncpy_utf16(busName, isInput ? "Audio Input" : "Audio Output", 128); + break; + default: + if (group.name.isNotEmpty()) + strncpy_utf16(busName, group.name, 128); + else + strncpy_utf16(busName, port.name, 128); + break; + } + + if (bufInfo.audio == 0 && (port.hints & kAudioPortIsSidechain) == 0x0) + { + busType = V3_MAIN; + flags = V3_DEFAULT_ACTIVE; + } + break; + } + } + } + else + { + busId -= bufInfo.numGroups; + + switch (busId) + { + case 0: + if (bufInfo.audio) + { + numChannels = bufInfo.numMainAudio; + busType = V3_MAIN; + flags = V3_DEFAULT_ACTIVE; + break; + } + // fall-through + case 1: + if (bufInfo.sidechain) + { + numChannels = bufInfo.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, isInput ? "Audio Input" : "Audio Output", 128); + } + else + { + for (uint32_t i=0; i<numPorts; ++i) + { + const AudioPortWithBusId& port(fPlugin.getAudioPort(isInput, 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; + } + } + } + } + + std::memset(info, 0, sizeof(v3_bus_info)); + info->media_type = V3_AUDIO; + info->direction = isInput ? V3_INPUT : V3_OUTPUT; + info->channel_count = numChannels; + std::memcpy(info->bus_name, busName, sizeof(busName)); + info->bus_type = busType; + info->flags = flags; + return V3_OK; + } + + template<bool isInput> + bool getAudioBusArrangement(uint32_t busId, v3_speaker_arrangement* const speaker) const + { + constexpr const uint32_t numPorts = isInput ? DISTRHO_PLUGIN_NUM_INPUTS : DISTRHO_PLUGIN_NUM_OUTPUTS; + const BusInfo& bufInfo(isInput ? inputBuses : outputBuses); + + for (uint32_t i=0; i<numPorts; ++i) + { + AudioPortWithBusId& port(fPlugin.getAudioPort(isInput, i)); + + if (port.busId != busId) + { + d_stdout("port.busId != busId: %d %d", port.busId, busId); + continue; + } + + v3_speaker_arrangement arr; + + switch (port.groupId) + { + case kPortGroupMono: + arr = V3_SPEAKER_M; + break; + case kPortGroupStereo: + arr = V3_SPEAKER_L | V3_SPEAKER_R; + break; + default: + if (busId < bufInfo.numGroups) + { + const uint32_t numPortsInBus = fPlugin.getAudioPortCountWithGroupId(isInput, busId); + arr = 0x0; + for (uint32_t j=0; j<numPortsInBus; ++j) + arr |= 1ull << (j + 33ull); + } + else + { + busId -= bufInfo.numGroups; + + if (bufInfo.audio != 0 && busId == 0) + { + arr = 0x0; + for (uint32_t j=0; j<bufInfo.numMainAudio; ++j) + arr |= 1ull << (j + 33ull); + } + else if (bufInfo.sidechain != 0 && busId == bufInfo.audio) + { + arr = 0x0; + for (uint32_t j=0; j<bufInfo.numSidechain; ++j) + arr |= 1ull << (bufInfo.numMainAudio + j + 33ull); + } + else + { + arr = 1ull << (bufInfo.numMainAudio + bufInfo.numSidechain + busId + 33ull); + } + } + break; + } + + *speaker = arr; + return true; + } + + return false; + } #endif // ---------------------------------------------------------------------------------------------------------------- @@ -2790,7 +2670,7 @@ private: return true; } -#if DISTRHO_PLUGIN_HAS_UI + #if DISTRHO_PLUGIN_HAS_UI // ---------------------------------------------------------------------------------------------------------------- // helper functions called during message passing, can block @@ -2856,25 +2736,25 @@ private: v3_cpp_obj_unref(message); } -#endif + #endif // ---------------------------------------------------------------------------------------------------------------- // DPF callbacks + #if DISTRHO_PLUGIN_WANT_PARAMETER_VALUE_CHANGE_REQUEST bool requestParameterValueChange(const uint32_t index, float) { fParameterValuesChangedDuringProcessing[kVst3InternalParameterBaseCount + index] = true; return true; } -#if DISTRHO_PLUGIN_WANT_PARAMETER_VALUE_CHANGE_REQUEST static bool requestParameterValueChangeCallback(void* const ptr, const uint32_t index, const float value) { return ((PluginVst3*)ptr)->requestParameterValueChange(index, value); } -#endif + #endif -#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT + #if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT bool writeMidi(const MidiEvent& midiEvent) { DISTRHO_CUSTOM_SAFE_ASSERT_ONCE_RETURN("MIDI output unsupported", fHostEventOutputHandle != nullptr, false); @@ -2947,8 +2827,7 @@ private: { return ((PluginVst3*)ptr)->writeMidi(midiEvent); } -#endif - + #endif }; // -------------------------------------------------------------------------------------------------------------------- @@ -3254,41 +3133,41 @@ struct dpf_midi_mapping : v3_midi_mapping_cpp { struct dpf_edit_controller : v3_edit_controller_cpp { std::atomic_int refcounter; -#if DISTRHO_PLUGIN_HAS_UI + #if DISTRHO_PLUGIN_HAS_UI ScopedPointer<dpf_ctrl2view_connection_point> connectionCtrl2View; -#endif -#if DPF_VST3_USES_SEPARATE_CONTROLLER + #endif + #if DPF_VST3_USES_SEPARATE_CONTROLLER ScopedPointer<dpf_comp2ctrl_connection_point> connectionComp2Ctrl; ScopedPointer<PluginVst3> vst3; -#else + #else ScopedPointer<PluginVst3>& vst3; bool initialized; -#endif + #endif // cached values v3_component_handler** handler; v3_host_application** const hostApplicationFromFactory; -#if !DPF_VST3_USES_SEPARATE_CONTROLLER + #if !DPF_VST3_USES_SEPARATE_CONTROLLER v3_host_application** const hostApplicationFromComponent; v3_host_application** hostApplicationFromComponentInitialize; -#endif + #endif v3_host_application** hostApplicationFromInitialize; -#if DPF_VST3_USES_SEPARATE_CONTROLLER + #if DPF_VST3_USES_SEPARATE_CONTROLLER dpf_edit_controller(v3_host_application** const hostApp) : refcounter(1), vst3(nullptr), -#else + #else dpf_edit_controller(ScopedPointer<PluginVst3>& v, v3_host_application** const hostApp, v3_host_application** const hostComp) : refcounter(1), vst3(v), initialized(false), -#endif + #endif handler(nullptr), hostApplicationFromFactory(hostApp), -#if !DPF_VST3_USES_SEPARATE_CONTROLLER + #if !DPF_VST3_USES_SEPARATE_CONTROLLER hostApplicationFromComponent(hostComp), hostApplicationFromComponentInitialize(nullptr), -#endif + #endif hostApplicationFromInitialize(nullptr) { d_stdout("dpf_edit_controller() with hostApplication %p", hostApplicationFromFactory); @@ -3296,10 +3175,10 @@ struct dpf_edit_controller : v3_edit_controller_cpp { // make sure host application is valid through out this controller lifetime if (hostApplicationFromFactory != nullptr) v3_cpp_obj_ref(hostApplicationFromFactory); -#if !DPF_VST3_USES_SEPARATE_CONTROLLER + #if !DPF_VST3_USES_SEPARATE_CONTROLLER if (hostApplicationFromComponent != nullptr) v3_cpp_obj_ref(hostApplicationFromComponent); -#endif + #endif // v3_funknown, everything custom query_interface = query_interface_edit_controller; @@ -3329,18 +3208,18 @@ struct dpf_edit_controller : v3_edit_controller_cpp { ~dpf_edit_controller() { d_stdout("~dpf_edit_controller()"); -#if DISTRHO_PLUGIN_HAS_UI + #if DISTRHO_PLUGIN_HAS_UI connectionCtrl2View = nullptr; -#endif -#if DPF_VST3_USES_SEPARATE_CONTROLLER + #endif + #if DPF_VST3_USES_SEPARATE_CONTROLLER connectionComp2Ctrl = nullptr; vst3 = nullptr; -#endif + #endif -#if !DPF_VST3_USES_SEPARATE_CONTROLLER + #if !DPF_VST3_USES_SEPARATE_CONTROLLER if (hostApplicationFromComponent != nullptr) v3_cpp_obj_unref(hostApplicationFromComponent); -#endif + #endif if (hostApplicationFromFactory != nullptr) v3_cpp_obj_unref(hostApplicationFromFactory); } @@ -3364,22 +3243,22 @@ struct dpf_edit_controller : v3_edit_controller_cpp { if (v3_tuid_match(iid, v3_midi_mapping_iid)) { -#if DISTRHO_PLUGIN_WANT_MIDI_INPUT + #if DISTRHO_PLUGIN_WANT_MIDI_INPUT d_stdout("query_interface_edit_controller => %p %s %p | OK convert static", self, tuid2str(iid), iface); static dpf_midi_mapping midi_mapping; static dpf_midi_mapping* midi_mapping_ptr = &midi_mapping; *iface = &midi_mapping_ptr; return V3_OK; -#else + #else d_stdout("query_interface_edit_controller => %p %s %p | reject unused", self, tuid2str(iid), iface); *iface = nullptr; return V3_NO_INTERFACE; -#endif + #endif } if (v3_tuid_match(iid, v3_connection_point_iid)) { -#if DPF_VST3_USES_SEPARATE_CONTROLLER + #if DPF_VST3_USES_SEPARATE_CONTROLLER d_stdout("query_interface_edit_controller => %p %s %p | OK convert %p", self, tuid2str(iid), iface, controller->connectionComp2Ctrl.get()); @@ -3389,11 +3268,11 @@ struct dpf_edit_controller : v3_edit_controller_cpp { ++controller->connectionComp2Ctrl->refcounter; *iface = &controller->connectionComp2Ctrl; return V3_OK; -#else + #else d_stdout("query_interface_edit_controller => %p %s %p | reject unwanted", self, tuid2str(iid), iface); *iface = nullptr; return V3_NO_INTERFACE; -#endif + #endif } d_stdout("query_interface_edit_controller => %p %s %p | WARNING UNSUPPORTED", self, tuid2str(iid), iface); @@ -3420,7 +3299,7 @@ struct dpf_edit_controller : v3_edit_controller_cpp { return refcount; } -#if DPF_VST3_USES_SEPARATE_CONTROLLER + #if DPF_VST3_USES_SEPARATE_CONTROLLER /** * Some hosts will have unclean instances of a few of the controller child classes at this point. * We check for those here, going through the whole possible chain to see if it is safe to delete. @@ -3445,9 +3324,9 @@ struct dpf_edit_controller : v3_edit_controller_cpp { delete controller; delete controllerptr; -#else + #else d_stdout("dpf_edit_controller::unref => %p | refcount is zero, deletion will be done by component later", self); -#endif + #endif return 0; } @@ -3459,11 +3338,11 @@ struct dpf_edit_controller : v3_edit_controller_cpp { dpf_edit_controller* const controller = *static_cast<dpf_edit_controller**>(self); // check if already initialized -#if DPF_VST3_USES_SEPARATE_CONTROLLER + #if DPF_VST3_USES_SEPARATE_CONTROLLER DISTRHO_SAFE_ASSERT_RETURN(controller->vst3 == nullptr, V3_INVALID_ARG); -#else + #else DISTRHO_SAFE_ASSERT_RETURN(! controller->initialized, V3_INVALID_ARG); -#endif + #endif // query for host application v3_host_application** hostApplication = nullptr; @@ -3475,7 +3354,7 @@ struct dpf_edit_controller : v3_edit_controller_cpp { // save it for later so we can unref it controller->hostApplicationFromInitialize = hostApplication; -#if DPF_VST3_USES_SEPARATE_CONTROLLER + #if DPF_VST3_USES_SEPARATE_CONTROLLER // provide the factory application to the plugin if this new one is missing if (hostApplication == nullptr) hostApplication = controller->hostApplicationFromFactory; @@ -3497,10 +3376,10 @@ struct dpf_edit_controller : v3_edit_controller_cpp { if (point->other != nullptr) controller->vst3->comp2ctrl_connect(point->other); } -#else + #else // mark as initialized controller->initialized = true; -#endif + #endif return V3_OK; } @@ -3510,19 +3389,19 @@ struct dpf_edit_controller : v3_edit_controller_cpp { d_stdout("dpf_edit_controller::terminate => %p", self); dpf_edit_controller* const controller = *static_cast<dpf_edit_controller**>(self); -#if DPF_VST3_USES_SEPARATE_CONTROLLER + #if DPF_VST3_USES_SEPARATE_CONTROLLER // check if already terminated DISTRHO_SAFE_ASSERT_RETURN(controller->vst3 != nullptr, V3_INVALID_ARG); // delete actual plugin controller->vst3 = nullptr; -#else + #else // check if already terminated DISTRHO_SAFE_ASSERT_RETURN(controller->initialized, V3_INVALID_ARG); // mark as uninitialzed controller->initialized = false; -#endif + #endif // unref host application received during initialize if (controller->hostApplicationFromInitialize != nullptr) @@ -3541,30 +3420,30 @@ struct dpf_edit_controller : v3_edit_controller_cpp { { d_stdout("dpf_edit_controller::set_component_state => %p %p", self, stream); -#if DPF_VST3_USES_SEPARATE_CONTROLLER + #if DPF_VST3_USES_SEPARATE_CONTROLLER dpf_edit_controller* const controller = *static_cast<dpf_edit_controller**>(self); PluginVst3* const vst3 = controller->vst3; DISTRHO_SAFE_ASSERT_RETURN(vst3 != nullptr, V3_NOT_INITIALIZED); return vst3->setState(stream); -#else + #else return V3_OK; // unused (void)self; (void)stream; -#endif + #endif } static v3_result V3_API set_state(void* const self, v3_bstream** const stream) { d_stdout("dpf_edit_controller::set_state => %p %p", self, stream); -#if DPF_VST3_USES_SEPARATE_CONTROLLER + #if DPF_VST3_USES_SEPARATE_CONTROLLER dpf_edit_controller* const controller = *static_cast<dpf_edit_controller**>(self); DISTRHO_SAFE_ASSERT_RETURN(controller->vst3 != nullptr, V3_NOT_INITIALIZED); -#endif + #endif return V3_NOT_IMPLEMENTED; @@ -3577,10 +3456,10 @@ struct dpf_edit_controller : v3_edit_controller_cpp { { d_stdout("dpf_edit_controller::get_state => %p %p", self, stream); -#if DPF_VST3_USES_SEPARATE_CONTROLLER + #if DPF_VST3_USES_SEPARATE_CONTROLLER dpf_edit_controller* const controller = *static_cast<dpf_edit_controller**>(self); DISTRHO_SAFE_ASSERT_RETURN(controller->vst3 != nullptr, V3_NOT_INITIALIZED); -#endif + #endif return V3_NOT_IMPLEMENTED; @@ -3698,7 +3577,7 @@ struct dpf_edit_controller : v3_edit_controller_cpp { d_stdout("create_view has contexts %p %p", controller->hostApplicationFromFactory, controller->hostApplicationFromInitialize); -#if DISTRHO_PLUGIN_HAS_UI + #if DISTRHO_PLUGIN_HAS_UI // plugin must be initialized PluginVst3* const vst3 = controller->vst3; DISTRHO_SAFE_ASSERT_RETURN(vst3 != nullptr, nullptr); @@ -3711,12 +3590,12 @@ struct dpf_edit_controller : v3_edit_controller_cpp { // we require a host application for message creation v3_host_application** const host = controller->hostApplicationFromInitialize != nullptr ? controller->hostApplicationFromInitialize -#if !DPF_VST3_USES_SEPARATE_CONTROLLER + #if !DPF_VST3_USES_SEPARATE_CONTROLLER : controller->hostApplicationFromComponent != nullptr ? controller->hostApplicationFromComponent : controller->hostApplicationFromComponentInitialize != nullptr ? controller->hostApplicationFromComponentInitialize -#endif + #endif : controller->hostApplicationFromFactory; DISTRHO_SAFE_ASSERT_RETURN(host != nullptr, nullptr); @@ -3742,9 +3621,9 @@ struct dpf_edit_controller : v3_edit_controller_cpp { } return view; -#else + #else return nullptr; -#endif + #endif } }; @@ -3787,16 +3666,16 @@ struct dpf_process_context_requirements : v3_process_context_requirements_cpp { static uint32_t V3_API get_process_context_requirements(void*) { -#if DISTRHO_PLUGIN_WANT_TIMEPOS + #if DISTRHO_PLUGIN_WANT_TIMEPOS return 0x0 | V3_PROCESS_CTX_NEED_CONTINUOUS_TIME // V3_PROCESS_CTX_CONT_TIME_VALID | V3_PROCESS_CTX_NEED_PROJECT_TIME // V3_PROCESS_CTX_PROJECT_TIME_VALID | V3_PROCESS_CTX_NEED_TEMPO // V3_PROCESS_CTX_TEMPO_VALID | V3_PROCESS_CTX_NEED_TIME_SIG // V3_PROCESS_CTX_TIME_SIG_VALID | V3_PROCESS_CTX_NEED_TRANSPORT_STATE; // V3_PROCESS_CTX_PLAYING -#else + #else return 0x0; -#endif + #endif } DISTRHO_PREVENT_HEAP_ALLOCATION @@ -3867,9 +3746,9 @@ struct dpf_audio_processor : v3_audio_processor_cpp { v3_speaker_arrangement* const inputs, const int32_t num_inputs, v3_speaker_arrangement* const outputs, const int32_t num_outputs) { - // NOTE this is called a bunch of times - // d_stdout("dpf_audio_processor::set_bus_arrangements => %p %p %i %p %i", - // self, inputs, num_inputs, outputs, num_outputs); + // NOTE this is called a bunch of times in JUCE hosts + d_stdout("dpf_audio_processor::set_bus_arrangements => %p %p %i %p %i", + self, inputs, num_inputs, outputs, num_outputs); dpf_audio_processor* const processor = *static_cast<dpf_audio_processor**>(self); PluginVst3* const vst3 = processor->vst3; @@ -3965,11 +3844,11 @@ struct dpf_audio_processor : v3_audio_processor_cpp { struct dpf_component : v3_component_cpp { std::atomic_int refcounter; ScopedPointer<dpf_audio_processor> processor; -#if DPF_VST3_USES_SEPARATE_CONTROLLER + #if DPF_VST3_USES_SEPARATE_CONTROLLER ScopedPointer<dpf_comp2ctrl_connection_point> connectionComp2Ctrl; -#else + #else ScopedPointer<dpf_edit_controller> controller; -#endif + #endif ScopedPointer<PluginVst3> vst3; v3_host_application** const hostApplicationFromFactory; v3_host_application** hostApplicationFromInitialize; @@ -4010,11 +3889,11 @@ struct dpf_component : v3_component_cpp { { d_stdout("~dpf_component()"); processor = nullptr; -#if DPF_VST3_USES_SEPARATE_CONTROLLER + #if DPF_VST3_USES_SEPARATE_CONTROLLER connectionComp2Ctrl = nullptr; -#else + #else controller = nullptr; -#endif + #endif vst3 = nullptr; if (hostApplicationFromFactory != nullptr) @@ -4040,17 +3919,17 @@ struct dpf_component : v3_component_cpp { if (v3_tuid_match(iid, v3_midi_mapping_iid)) { -#if DISTRHO_PLUGIN_WANT_MIDI_INPUT + #if DISTRHO_PLUGIN_WANT_MIDI_INPUT d_stdout("query_interface_component => %p %s %p | OK convert static", self, tuid2str(iid), iface); static dpf_midi_mapping midi_mapping; static dpf_midi_mapping* midi_mapping_ptr = &midi_mapping; *iface = &midi_mapping_ptr; return V3_OK; -#else + #else d_stdout("query_interface_component => %p %s %p | reject unused", self, tuid2str(iid), iface); *iface = nullptr; return V3_NO_INTERFACE; -#endif + #endif } if (v3_tuid_match(iid, v3_audio_processor_iid)) @@ -4068,7 +3947,7 @@ struct dpf_component : v3_component_cpp { if (v3_tuid_match(iid, v3_connection_point_iid)) { -#if DPF_VST3_USES_SEPARATE_CONTROLLER + #if DPF_VST3_USES_SEPARATE_CONTROLLER d_stdout("query_interface_component => %p %s %p | OK convert %p", self, tuid2str(iid), iface, component->connectionComp2Ctrl.get()); @@ -4078,16 +3957,16 @@ struct dpf_component : v3_component_cpp { ++component->connectionComp2Ctrl->refcounter; *iface = &component->connectionComp2Ctrl; return V3_OK; -#else + #else d_stdout("query_interface_component => %p %s %p | reject unwanted", self, tuid2str(iid), iface); *iface = nullptr; return V3_NO_INTERFACE; -#endif + #endif } if (v3_tuid_match(iid, v3_edit_controller_iid)) { -#if !DPF_VST3_USES_SEPARATE_CONTROLLER + #if !DPF_VST3_USES_SEPARATE_CONTROLLER d_stdout("query_interface_component => %p %s %p | OK convert %p", self, tuid2str(iid), iface, component->controller.get()); @@ -4099,11 +3978,11 @@ struct dpf_component : v3_component_cpp { ++component->controller->refcounter; *iface = &component->controller; return V3_OK; -#else + #else d_stdout("query_interface_component => %p %s %p | reject unwanted", self, tuid2str(iid), iface); *iface = nullptr; return V3_NO_INTERFACE; -#endif + #endif } d_stdout("query_interface_component => %p %s %p | WARNING UNSUPPORTED", self, tuid2str(iid), iface); @@ -4147,7 +4026,7 @@ struct dpf_component : v3_component_cpp { } } -#if DPF_VST3_USES_SEPARATE_CONTROLLER + #if DPF_VST3_USES_SEPARATE_CONTROLLER if (dpf_comp2ctrl_connection_point* const point = component->connectionComp2Ctrl) { if (const int refcount = point->refcounter) @@ -4156,7 +4035,7 @@ struct dpf_component : v3_component_cpp { d_stderr("DPF warning: asked to delete component while connection point still active (refcount %d)", refcount); } } -#else + #else if (dpf_edit_controller* const controller = component->controller) { if (const int refcount = controller->refcounter) @@ -4165,7 +4044,7 @@ struct dpf_component : v3_component_cpp { d_stderr("DPF warning: asked to delete component while edit controller still active (refcount %d)", refcount); } } -#endif + #endif if (unclean) return handleUncleanComponent(componentptr);