| @@ -36,6 +36,7 @@ | |||||
| #endif | #endif | ||||
| #include <map> | #include <map> | ||||
| #include <vector> | |||||
| #include "clap/entry.h" | #include "clap/entry.h" | ||||
| #include "clap/plugin-factory.h" | #include "clap/plugin-factory.h" | ||||
| @@ -739,19 +740,24 @@ public: | |||||
| updateStateValueCallback), | updateStateValueCallback), | ||||
| fHost(host), | fHost(host), | ||||
| fOutputEvents(nullptr), | fOutputEvents(nullptr), | ||||
| #if DISTRHO_PLUGIN_WANT_LATENCY | |||||
| #if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS != 0 | |||||
| fUsingCV(false), | |||||
| #endif | |||||
| #if DISTRHO_PLUGIN_WANT_LATENCY | |||||
| fLatencyChanged(false), | fLatencyChanged(false), | ||||
| fLastKnownLatency(0), | fLastKnownLatency(0), | ||||
| #endif | |||||
| #if DISTRHO_PLUGIN_WANT_MIDI_INPUT | |||||
| #endif | |||||
| #if DISTRHO_PLUGIN_WANT_MIDI_INPUT | |||||
| fMidiEventCount(0), | fMidiEventCount(0), | ||||
| #endif | |||||
| #endif | |||||
| fHostExtensions(host) | fHostExtensions(host) | ||||
| { | { | ||||
| fCachedParameters.setup(fPlugin.getParameterCount()); | fCachedParameters.setup(fPlugin.getParameterCount()); | ||||
| #if DISTRHO_PLUGIN_HAS_UI && DISTRHO_PLUGIN_WANT_MIDI_INPUT | #if DISTRHO_PLUGIN_HAS_UI && DISTRHO_PLUGIN_WANT_MIDI_INPUT | ||||
| fNotesRingBuffer.setRingBuffer(&fNotesBuffer, true); | fNotesRingBuffer.setRingBuffer(&fNotesBuffer, true); | ||||
| #endif | #endif | ||||
| #if DISTRHO_PLUGIN_WANT_STATE | #if DISTRHO_PLUGIN_WANT_STATE | ||||
| for (uint32_t i=0, count=fPlugin.getStateCount(); i<count; ++i) | for (uint32_t i=0, count=fPlugin.getStateCount(); i<count; ++i) | ||||
| { | { | ||||
| @@ -759,6 +765,16 @@ public: | |||||
| fStateMap[dkey] = fPlugin.getStateDefaultValue(i); | fStateMap[dkey] = fPlugin.getStateDefaultValue(i); | ||||
| } | } | ||||
| #endif | #endif | ||||
| #if DISTRHO_PLUGIN_NUM_INPUTS != 0 | |||||
| fillInBusInfoDetails<true>(); | |||||
| #endif | |||||
| #if DISTRHO_PLUGIN_NUM_OUTPUTS != 0 | |||||
| fillInBusInfoDetails<false>(); | |||||
| #endif | |||||
| #if DISTRHO_PLUGIN_NUM_INPUTS != 0 && DISTRHO_PLUGIN_NUM_OUTPUTS != 0 | |||||
| fillInBusInfoPairs(); | |||||
| #endif | |||||
| } | } | ||||
| // ---------------------------------------------------------------------------------------------------------------- | // ---------------------------------------------------------------------------------------------------------------- | ||||
| @@ -992,25 +1008,66 @@ public: | |||||
| if (const uint32_t frames = process->frames_count) | if (const uint32_t frames = process->frames_count) | ||||
| { | { | ||||
| // TODO multi-port bus stuff | |||||
| DISTRHO_SAFE_ASSERT_UINT_RETURN(process->audio_inputs_count == 0 || process->audio_inputs_count == 1, | |||||
| process->audio_inputs_count, false); | |||||
| DISTRHO_SAFE_ASSERT_UINT_RETURN(process->audio_outputs_count == 0 || process->audio_outputs_count == 1, | |||||
| process->audio_outputs_count, false); | |||||
| const float** inputs = process->audio_inputs != nullptr | |||||
| ? const_cast<const float**>(process->audio_inputs[0].data32) | |||||
| : nullptr; | |||||
| /**/ float** outputs = process->audio_outputs != nullptr | |||||
| ? process->audio_outputs[0].data32 | |||||
| : nullptr; | |||||
| #if DISTRHO_PLUGIN_NUM_INPUTS != 0 | |||||
| const float** const audioInputs = fAudioInputs; | |||||
| uint32_t in=0; | |||||
| for (uint32_t i=0; i<process->audio_inputs_count; ++i) | |||||
| { | |||||
| const clap_audio_buffer_t& inputs(process->audio_inputs[i]); | |||||
| DISTRHO_SAFE_ASSERT_CONTINUE(inputs.channel_count != 0); | |||||
| for (uint32_t j=0; j<inputs.channel_count; ++j, ++in) | |||||
| audioInputs[in] = const_cast<const float*>(inputs.data32[j]); | |||||
| } | |||||
| if (fUsingCV) | |||||
| { | |||||
| for (; in<DISTRHO_PLUGIN_NUM_INPUTS; ++in) | |||||
| audioInputs[in] = nullptr; | |||||
| } | |||||
| else | |||||
| { | |||||
| DISTRHO_SAFE_ASSERT_UINT2_RETURN(in == DISTRHO_PLUGIN_NUM_INPUTS, | |||||
| in, process->audio_inputs_count, false); | |||||
| } | |||||
| #else | |||||
| constexpr const float* const audioInputs = nullptr; | |||||
| #endif | |||||
| #if DISTRHO_PLUGIN_NUM_OUTPUTS != 0 | |||||
| float** const audioOutputs = fAudioOutputs; | |||||
| uint32_t out=0; | |||||
| for (uint32_t i=0; i<process->audio_outputs_count; ++i) | |||||
| { | |||||
| const clap_audio_buffer_t& outputs(process->audio_outputs[i]); | |||||
| DISTRHO_SAFE_ASSERT_CONTINUE(outputs.channel_count != 0); | |||||
| for (uint32_t j=0; j<outputs.channel_count; ++j, ++out) | |||||
| audioOutputs[out] = outputs.data32[j]; | |||||
| } | |||||
| if (fUsingCV) | |||||
| { | |||||
| for (; out<DISTRHO_PLUGIN_NUM_OUTPUTS; ++out) | |||||
| audioOutputs[out] = nullptr; | |||||
| } | |||||
| else | |||||
| { | |||||
| DISTRHO_SAFE_ASSERT_UINT2_RETURN(out == DISTRHO_PLUGIN_NUM_OUTPUTS, | |||||
| out, DISTRHO_PLUGIN_NUM_OUTPUTS, false); | |||||
| } | |||||
| #else | |||||
| constexpr float* audioOutputs = nullptr; | |||||
| #endif | |||||
| fOutputEvents = process->out_events; | fOutputEvents = process->out_events; | ||||
| #if DISTRHO_PLUGIN_WANT_MIDI_INPUT | #if DISTRHO_PLUGIN_WANT_MIDI_INPUT | ||||
| fPlugin.run(inputs, outputs, frames, fMidiEvents, fMidiEventCount); | |||||
| fPlugin.run(audioInputs, audioOutputs, frames, fMidiEvents, fMidiEventCount); | |||||
| #else | #else | ||||
| fPlugin.run(inputs, outputs, frames); | |||||
| fPlugin.run(audioInputs, audioOutputs, frames); | |||||
| #endif | #endif | ||||
| // TODO set last frame | // TODO set last frame | ||||
| @@ -1243,6 +1300,48 @@ public: | |||||
| fPlugin.setParameterValue(event->param_id, event->value); | fPlugin.setParameterValue(event->param_id, event->value); | ||||
| } | } | ||||
| // ---------------------------------------------------------------------------------------------------------------- | |||||
| // audio ports | |||||
| #if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS != 0 | |||||
| template<bool isInput> | |||||
| uint32_t getAudioPortCount() const noexcept | |||||
| { | |||||
| return (isInput ? fAudioInputBuses : fAudioOutputBuses).size(); | |||||
| } | |||||
| template<bool isInput> | |||||
| bool getAudioPortInfo(const uint32_t index, clap_audio_port_info_t* const info) const noexcept | |||||
| { | |||||
| const std::vector<BusInfo>& busInfos(isInput ? fAudioInputBuses : fAudioOutputBuses); | |||||
| DISTRHO_SAFE_ASSERT_RETURN(index < busInfos.size(), false); | |||||
| const BusInfo& busInfo(busInfos[index]); | |||||
| info->id = busInfo.groupId; | |||||
| DISTRHO_NAMESPACE::strncpy(info->name, busInfo.name, CLAP_NAME_SIZE); | |||||
| info->flags = busInfo.isMain ? CLAP_AUDIO_PORT_IS_MAIN : 0x0; | |||||
| info->channel_count = busInfo.numChannels; | |||||
| switch (busInfo.groupId) | |||||
| { | |||||
| case kPortGroupMono: | |||||
| info->port_type = CLAP_PORT_MONO; | |||||
| break; | |||||
| case kPortGroupStereo: | |||||
| info->port_type = CLAP_PORT_STEREO; | |||||
| break; | |||||
| default: | |||||
| info->port_type = nullptr; | |||||
| break; | |||||
| } | |||||
| info->in_place_pair = busInfo.hasPair ? busInfo.groupId : CLAP_INVALID_ID; | |||||
| return true; | |||||
| } | |||||
| #endif | |||||
| // ---------------------------------------------------------------------------------------------------------------- | // ---------------------------------------------------------------------------------------------------------------- | ||||
| // latency | // latency | ||||
| @@ -1673,6 +1772,15 @@ private: | |||||
| const clap_host_t* const fHost; | const clap_host_t* const fHost; | ||||
| const clap_output_events_t* fOutputEvents; | const clap_output_events_t* fOutputEvents; | ||||
| #if DISTRHO_PLUGIN_NUM_INPUTS != 0 | |||||
| const float* fAudioInputs[DISTRHO_PLUGIN_NUM_INPUTS]; | |||||
| #endif | |||||
| #if DISTRHO_PLUGIN_NUM_OUTPUTS != 0 | |||||
| float* fAudioOutputs[DISTRHO_PLUGIN_NUM_OUTPUTS]; | |||||
| #endif | |||||
| #if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS != 0 | |||||
| bool fUsingCV; | |||||
| #endif | |||||
| #if DISTRHO_PLUGIN_WANT_LATENCY | #if DISTRHO_PLUGIN_WANT_LATENCY | ||||
| bool fLatencyChanged; | bool fLatencyChanged; | ||||
| uint32_t fLastKnownLatency; | uint32_t fLastKnownLatency; | ||||
| @@ -1718,6 +1826,170 @@ private: | |||||
| } | } | ||||
| } fHostExtensions; | } fHostExtensions; | ||||
| // ---------------------------------------------------------------------------------------------------------------- | |||||
| // helper functions for dealing with buses | |||||
| #if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS != 0 | |||||
| struct BusInfo { | |||||
| char name[CLAP_NAME_SIZE]; | |||||
| uint32_t numChannels; | |||||
| bool hasPair; | |||||
| bool isCV; | |||||
| bool isMain; | |||||
| uint32_t groupId; | |||||
| }; | |||||
| std::vector<BusInfo> fAudioInputBuses, fAudioOutputBuses; | |||||
| template<bool isInput> | |||||
| void fillInBusInfoDetails() | |||||
| { | |||||
| constexpr const uint32_t numPorts = isInput ? DISTRHO_PLUGIN_NUM_INPUTS : DISTRHO_PLUGIN_NUM_OUTPUTS; | |||||
| std::vector<BusInfo>& busInfos(isInput ? fAudioInputBuses : fAudioOutputBuses); | |||||
| enum { | |||||
| kPortTypeNull, | |||||
| kPortTypeAudio, | |||||
| kPortTypeSidechain, | |||||
| kPortTypeCV, | |||||
| kPortTypeGroup | |||||
| } lastSeenPortType = kPortTypeNull; | |||||
| uint32_t lastSeenGroupId = kPortGroupNone; | |||||
| uint32_t nonGroupAudioId = 0; | |||||
| uint32_t nonGroupSidechainId = 0x20000000; | |||||
| for (uint32_t i=0; i<numPorts; ++i) | |||||
| { | |||||
| const AudioPortWithBusId& port(fPlugin.getAudioPort(isInput, i)); | |||||
| if (port.groupId != kPortGroupNone) | |||||
| { | |||||
| if (lastSeenPortType != kPortTypeGroup || lastSeenGroupId != port.groupId) | |||||
| { | |||||
| lastSeenPortType = kPortTypeGroup; | |||||
| lastSeenGroupId = port.groupId; | |||||
| BusInfo busInfo = { | |||||
| {}, 1, false, false, | |||||
| // if this is the first port, set it as main | |||||
| busInfos.empty(), | |||||
| // user given group id with extra safety offset | |||||
| port.groupId + 0x80000000 | |||||
| }; | |||||
| const PortGroupWithId& group(fPlugin.getPortGroupById(port.groupId)); | |||||
| switch (port.groupId) | |||||
| { | |||||
| case kPortGroupStereo: | |||||
| case kPortGroupMono: | |||||
| if (busInfo.isMain) | |||||
| { | |||||
| DISTRHO_NAMESPACE::strncpy(busInfo.name, | |||||
| isInput ? "Audio Input" : "Audio Output", CLAP_NAME_SIZE); | |||||
| break; | |||||
| } | |||||
| // fall-through | |||||
| default: | |||||
| if (group.name.isNotEmpty()) | |||||
| DISTRHO_NAMESPACE::strncpy(busInfo.name, group.name, CLAP_NAME_SIZE); | |||||
| else | |||||
| DISTRHO_NAMESPACE::strncpy(busInfo.name, port.name, CLAP_NAME_SIZE); | |||||
| break; | |||||
| } | |||||
| busInfos.push_back(busInfo); | |||||
| } | |||||
| else | |||||
| { | |||||
| ++busInfos.back().numChannels; | |||||
| } | |||||
| } | |||||
| else if (port.hints & kAudioPortIsCV) | |||||
| { | |||||
| // TODO | |||||
| lastSeenPortType = kPortTypeCV; | |||||
| lastSeenGroupId = kPortGroupNone; | |||||
| fUsingCV = true; | |||||
| } | |||||
| else if (port.hints & kAudioPortIsSidechain) | |||||
| { | |||||
| if (lastSeenPortType != kPortTypeSidechain) | |||||
| { | |||||
| lastSeenPortType = kPortTypeSidechain; | |||||
| lastSeenGroupId = kPortGroupNone; | |||||
| BusInfo busInfo = { | |||||
| {}, 1, false, false, | |||||
| // not main | |||||
| false, | |||||
| // give unique id | |||||
| nonGroupSidechainId++ | |||||
| }; | |||||
| DISTRHO_NAMESPACE::strncpy(busInfo.name, port.name, CLAP_NAME_SIZE); | |||||
| busInfos.push_back(busInfo); | |||||
| } | |||||
| else | |||||
| { | |||||
| ++busInfos.back().numChannels; | |||||
| } | |||||
| } | |||||
| else | |||||
| { | |||||
| if (lastSeenPortType != kPortTypeAudio) | |||||
| { | |||||
| lastSeenPortType = kPortTypeAudio; | |||||
| lastSeenGroupId = kPortGroupNone; | |||||
| BusInfo busInfo = { | |||||
| {}, 1, false, false, | |||||
| // if this is the first port, set it as main | |||||
| busInfos.empty(), | |||||
| // give unique id | |||||
| nonGroupAudioId++ | |||||
| }; | |||||
| if (busInfo.isMain) | |||||
| { | |||||
| DISTRHO_NAMESPACE::strncpy(busInfo.name, | |||||
| isInput ? "Audio Input" : "Audio Output", CLAP_NAME_SIZE); | |||||
| } | |||||
| else | |||||
| { | |||||
| DISTRHO_NAMESPACE::strncpy(busInfo.name, port.name, CLAP_NAME_SIZE); | |||||
| } | |||||
| busInfos.push_back(busInfo); | |||||
| } | |||||
| else | |||||
| { | |||||
| ++busInfos.back().numChannels; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| #endif | |||||
| #if DISTRHO_PLUGIN_NUM_INPUTS != 0 && DISTRHO_PLUGIN_NUM_OUTPUTS != 0 | |||||
| void fillInBusInfoPairs() | |||||
| { | |||||
| const size_t numChannels = std::min(fAudioInputBuses.size(), fAudioOutputBuses.size()); | |||||
| for (size_t i=0; i<numChannels; ++i) | |||||
| { | |||||
| if (fAudioInputBuses[i].groupId != fAudioOutputBuses[i].groupId) | |||||
| break; | |||||
| if (fAudioInputBuses[i].numChannels != fAudioOutputBuses[i].numChannels) | |||||
| break; | |||||
| if (fAudioInputBuses[i].isMain != fAudioOutputBuses[i].isMain) | |||||
| break; | |||||
| fAudioInputBuses[i].hasPair = fAudioOutputBuses[i].hasPair = true; | |||||
| } | |||||
| } | |||||
| #endif | |||||
| // ---------------------------------------------------------------------------------------------------------------- | // ---------------------------------------------------------------------------------------------------------------- | ||||
| // DPF callbacks | // DPF callbacks | ||||
| @@ -1962,61 +2234,41 @@ static const clap_plugin_timer_support_t clap_timer = { | |||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| // plugin audio ports | // plugin audio ports | ||||
| static uint32_t clap_plugin_audio_ports_count(const clap_plugin_t*, const bool is_input) | |||||
| #if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS != 0 | |||||
| static uint32_t clap_plugin_audio_ports_count(const clap_plugin_t* const plugin, const bool is_input) | |||||
| { | { | ||||
| return (is_input ? DISTRHO_PLUGIN_NUM_INPUTS : DISTRHO_PLUGIN_NUM_OUTPUTS) != 0 ? 1 : 0; | |||||
| PluginCLAP* const instance = static_cast<PluginCLAP*>(plugin->plugin_data); | |||||
| return is_input ? instance->getAudioPortCount<true>() | |||||
| : instance->getAudioPortCount<false>(); | |||||
| } | } | ||||
| static bool clap_plugin_audio_ports_get(const clap_plugin_t* /* const plugin */, | |||||
| static bool clap_plugin_audio_ports_get(const clap_plugin_t* const plugin, | |||||
| const uint32_t index, | const uint32_t index, | ||||
| const bool is_input, | const bool is_input, | ||||
| clap_audio_port_info_t* const info) | clap_audio_port_info_t* const info) | ||||
| { | { | ||||
| const uint32_t maxPortCount = is_input ? DISTRHO_PLUGIN_NUM_INPUTS : DISTRHO_PLUGIN_NUM_OUTPUTS; | |||||
| DISTRHO_SAFE_ASSERT_UINT2_RETURN(index < maxPortCount, index, maxPortCount, false); | |||||
| #if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0 | |||||
| // PluginCLAP* const instance = static_cast<PluginCLAP*>(plugin->plugin_data); | |||||
| // TODO use groups | |||||
| AudioPortWithBusId& audioPort(sPlugin->getAudioPort(is_input, index)); | |||||
| info->id = index; | |||||
| DISTRHO_NAMESPACE::strncpy(info->name, audioPort.name, CLAP_NAME_SIZE); | |||||
| // TODO bus stuff | |||||
| info->flags = CLAP_AUDIO_PORT_IS_MAIN; | |||||
| info->channel_count = maxPortCount; | |||||
| // TODO CV | |||||
| // info->port_type = audioPort.hints & kAudioPortIsCV ? CLAP_PORT_CV : nullptr; | |||||
| // TODO port groups | |||||
| info->port_type = maxPortCount == 2 ? CLAP_PORT_STEREO : maxPortCount == 1 ? CLAP_PORT_MONO : nullptr; | |||||
| info->in_place_pair = DISTRHO_PLUGIN_NUM_INPUTS == DISTRHO_PLUGIN_NUM_OUTPUTS ? index : CLAP_INVALID_ID; | |||||
| return true; | |||||
| #else | |||||
| return false; | |||||
| // unused | |||||
| (void)info; | |||||
| #endif | |||||
| PluginCLAP* const instance = static_cast<PluginCLAP*>(plugin->plugin_data); | |||||
| return is_input ? instance->getAudioPortInfo<true>(index, info) | |||||
| : instance->getAudioPortInfo<false>(index, info); | |||||
| } | } | ||||
| static const clap_plugin_audio_ports_t clap_plugin_audio_ports = { | static const clap_plugin_audio_ports_t clap_plugin_audio_ports = { | ||||
| clap_plugin_audio_ports_count, | clap_plugin_audio_ports_count, | ||||
| clap_plugin_audio_ports_get | clap_plugin_audio_ports_get | ||||
| }; | }; | ||||
| #endif | |||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| // plugin audio ports | |||||
| // plugin note ports | |||||
| #if DISTRHO_PLUGIN_WANT_MIDI_INPUT+DISTRHO_PLUGIN_WANT_MIDI_OUTPUT != 0 | |||||
| static uint32_t clap_plugin_note_ports_count(const clap_plugin_t*, const bool is_input) | static uint32_t clap_plugin_note_ports_count(const clap_plugin_t*, const bool is_input) | ||||
| { | { | ||||
| return (is_input ? DISTRHO_PLUGIN_WANT_MIDI_INPUT : DISTRHO_PLUGIN_WANT_MIDI_OUTPUT) != 0 ? 1 : 0; | return (is_input ? DISTRHO_PLUGIN_WANT_MIDI_INPUT : DISTRHO_PLUGIN_WANT_MIDI_OUTPUT) != 0 ? 1 : 0; | ||||
| } | } | ||||
| static bool clap_plugin_note_ports_get(const clap_plugin_t*, uint32_t, const bool is_input, clap_note_port_info_t* const info) | |||||
| static bool clap_plugin_note_ports_get(const clap_plugin_t*, uint32_t, | |||||
| const bool is_input, clap_note_port_info_t* const info) | |||||
| { | { | ||||
| if (is_input) | if (is_input) | ||||
| { | { | ||||
| @@ -2026,8 +2278,6 @@ static bool clap_plugin_note_ports_get(const clap_plugin_t*, uint32_t, const boo | |||||
| info->preferred_dialect = CLAP_NOTE_DIALECT_MIDI; | info->preferred_dialect = CLAP_NOTE_DIALECT_MIDI; | ||||
| std::strcpy(info->name, "Event/MIDI Input"); | std::strcpy(info->name, "Event/MIDI Input"); | ||||
| return true; | return true; | ||||
| #else | |||||
| return false; | |||||
| #endif | #endif | ||||
| } | } | ||||
| else | else | ||||
| @@ -2038,21 +2288,17 @@ static bool clap_plugin_note_ports_get(const clap_plugin_t*, uint32_t, const boo | |||||
| info->preferred_dialect = CLAP_NOTE_DIALECT_MIDI; | info->preferred_dialect = CLAP_NOTE_DIALECT_MIDI; | ||||
| std::strcpy(info->name, "Event/MIDI Output"); | std::strcpy(info->name, "Event/MIDI Output"); | ||||
| return true; | return true; | ||||
| #else | |||||
| return false; | |||||
| #endif | #endif | ||||
| } | } | ||||
| #if DISTRHO_PLUGIN_WANT_MIDI_INPUT+DISTRHO_PLUGIN_WANT_MIDI_OUTPUT == 0 | |||||
| // unused | |||||
| (void)info; | |||||
| #endif | |||||
| return false; | |||||
| } | } | ||||
| static const clap_plugin_note_ports_t clap_plugin_note_ports = { | static const clap_plugin_note_ports_t clap_plugin_note_ports = { | ||||
| clap_plugin_note_ports_count, | clap_plugin_note_ports_count, | ||||
| clap_plugin_note_ports_get | clap_plugin_note_ports_get | ||||
| }; | }; | ||||
| #endif | |||||
| // -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
| // plugin parameters | // plugin parameters | ||||
| @@ -2197,12 +2443,16 @@ static CLAP_ABI clap_process_status clap_plugin_process(const clap_plugin_t* con | |||||
| static CLAP_ABI const void* clap_plugin_get_extension(const clap_plugin_t*, const char* const id) | static CLAP_ABI const void* clap_plugin_get_extension(const clap_plugin_t*, const char* const id) | ||||
| { | { | ||||
| if (std::strcmp(id, CLAP_EXT_PARAMS) == 0) | |||||
| return &clap_plugin_params; | |||||
| #if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS != 0 | |||||
| if (std::strcmp(id, CLAP_EXT_AUDIO_PORTS) == 0) | if (std::strcmp(id, CLAP_EXT_AUDIO_PORTS) == 0) | ||||
| return &clap_plugin_audio_ports; | return &clap_plugin_audio_ports; | ||||
| #endif | |||||
| #if DISTRHO_PLUGIN_WANT_MIDI_INPUT+DISTRHO_PLUGIN_WANT_MIDI_OUTPUT != 0 | |||||
| if (std::strcmp(id, CLAP_EXT_NOTE_PORTS) == 0) | if (std::strcmp(id, CLAP_EXT_NOTE_PORTS) == 0) | ||||
| return &clap_plugin_note_ports; | return &clap_plugin_note_ports; | ||||
| if (std::strcmp(id, CLAP_EXT_PARAMS) == 0) | |||||
| return &clap_plugin_params; | |||||
| #endif | |||||
| #if DISTRHO_PLUGIN_WANT_LATENCY | #if DISTRHO_PLUGIN_WANT_LATENCY | ||||
| if (std::strcmp(id, CLAP_EXT_LATENCY) == 0) | if (std::strcmp(id, CLAP_EXT_LATENCY) == 0) | ||||
| return &clap_plugin_latency; | return &clap_plugin_latency; | ||||