Skip to content

Commit 19e32d1

Browse files
committed
More fixes
1 parent b8f2189 commit 19e32d1

3 files changed

Lines changed: 78 additions & 30 deletions

File tree

modules/yup_audio_plugin_client/clap/yup_audio_plugin_client_CLAP.cpp

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -468,14 +468,11 @@ AudioPluginProcessorCLAP::AudioPluginProcessorCLAP (const clap_host_t* host)
468468
if (event->type == CLAP_EVENT_PARAM_VALUE)
469469
{
470470
const auto* paramEvent = reinterpret_cast<const clap_event_param_value_t*> (event);
471-
const auto paramIndex = audioProcessor.getParameterIndexByHostID (paramEvent->param_id);
472-
473-
if (isPositiveAndBelow (paramIndex, static_cast<int> (audioProcessor.getParameters().size())))
474-
{
475-
wrapper->paramChangeBuffer.addChange (paramIndex,
476-
static_cast<float> (paramEvent->value),
477-
static_cast<int> (event->time));
478-
}
471+
addParameterChangeByHostParameterID (audioProcessor,
472+
wrapper->paramChangeBuffer,
473+
paramEvent->param_id,
474+
static_cast<float> (paramEvent->value),
475+
static_cast<int> (event->time));
479476
}
480477
else if (auto convertedEvent = clapEventToMidiMessage (event))
481478
{
@@ -484,8 +481,7 @@ AudioPluginProcessorCLAP::AudioPluginProcessorCLAP (const clap_host_t* host)
484481
}
485482

486483
// CLAP events arrive sorted — no sort needed; apply final values for backward compat
487-
for (const auto& change : wrapper->paramChangeBuffer)
488-
audioProcessor.getParameters()[change.parameterIndex]->setNormalizedValue (change.normalizedValue);
484+
applyParameterChangesToProcessor (audioProcessor, wrapper->paramChangeBuffer);
489485

490486
// Copy input audio into output buffers for effect processors
491487
for (uint32_t busIdx = 0; busIdx < std::min (process->audio_inputs_count, process->audio_outputs_count); ++busIdx)

modules/yup_audio_plugin_client/common/yup_AudioPluginUtilities.h

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,69 @@
2525
namespace yup
2626
{
2727

28+
/** Returns the first host-facing parameter ID not used by the processor.
29+
30+
This is useful for wrapper-owned synthetic parameters, such as bypass, that
31+
must not collide with plugin-authored stable automation IDs.
32+
*/
33+
inline uint32 findFirstUnusedHostParameterID (const AudioProcessor& processor, uint32 preferredParameterID)
34+
{
35+
auto parameterID = preferredParameterID;
36+
37+
while (processor.getParameterByHostID (parameterID) != nullptr
38+
&& parameterID < AudioParameter::maximumHostParameterID)
39+
{
40+
++parameterID;
41+
}
42+
43+
jassert (parameterID <= AudioParameter::maximumHostParameterID);
44+
jassert (processor.getParameterByHostID (parameterID) == nullptr);
45+
46+
return parameterID;
47+
}
48+
49+
/** Returns a host-facing parameter ID suitable for a wrapper-owned bypass parameter. */
50+
inline uint32 getBypassHostParameterID (const AudioProcessor& processor)
51+
{
52+
return findFirstUnusedHostParameterID (processor, static_cast<uint32> (processor.getParameters().size()));
53+
}
54+
55+
/** Adds a normalized automation change for a host-facing parameter ID.
56+
57+
@returns true if the host parameter ID mapped to a processor parameter and
58+
the change was added to the buffer.
59+
*/
60+
inline bool addParameterChangeByHostParameterID (AudioProcessor& processor,
61+
ParameterChangeBuffer& changes,
62+
uint32 hostParameterID,
63+
float normalizedValue,
64+
int sampleOffset)
65+
{
66+
const auto parameters = processor.getParameters();
67+
const auto parameterIndex = processor.getParameterIndexByHostID (hostParameterID);
68+
69+
if (! isPositiveAndBelow (parameterIndex, static_cast<int> (parameters.size())))
70+
return false;
71+
72+
return changes.addChange (parameterIndex, normalizedValue, sampleOffset);
73+
}
74+
75+
/** Applies the last known normalized values in a parameter change buffer.
76+
77+
Wrappers use this after collecting sample-accurate changes so processors that
78+
still read AudioParameter atomics directly see the latest host value.
79+
*/
80+
inline void applyParameterChangesToProcessor (AudioProcessor& processor, const ParameterChangeBuffer& changes)
81+
{
82+
const auto parameters = processor.getParameters();
83+
84+
for (const auto& change : changes)
85+
{
86+
if (isPositiveAndBelow (change.parameterIndex, static_cast<int> (parameters.size())))
87+
parameters[change.parameterIndex]->setNormalizedValue (change.normalizedValue);
88+
}
89+
}
90+
2891
/** Ends any active parameter gestures before a plugin wrapper tears down its processor. */
2992
inline void endActiveParameterGestures (AudioProcessor* processor)
3093
{

modules/yup_audio_plugin_client/vst3/yup_audio_plugin_client_VST3.cpp

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -104,17 +104,7 @@ Vst::ParamID getVST3ParameterID (const AudioParameter::Ptr& parameter)
104104

105105
Vst::ParamID getVST3BypassParameterID (const AudioProcessor& processor)
106106
{
107-
auto parameterID = static_cast<uint32> (processor.getParameters().size());
108-
109-
while (processor.getParameterByHostID (parameterID) != nullptr
110-
&& parameterID < AudioParameter::maximumHostParameterID)
111-
{
112-
++parameterID;
113-
}
114-
115-
jassert (parameterID <= AudioParameter::maximumHostParameterID);
116-
jassert (processor.getParameterByHostID (parameterID) == nullptr);
117-
return static_cast<Vst::ParamID> (parameterID);
107+
return static_cast<Vst::ParamID> (getBypassHostParameterID (processor));
118108
}
119109

120110
class AudioPluginPlayHeadVST3 final : public AudioPlayHead
@@ -1166,7 +1156,6 @@ class AudioPluginProcessorVST3 : public Vst::AudioEffect
11661156

11671157
if (data.inputParameterChanges)
11681158
{
1169-
const auto parameters = processor->getParameters();
11701159
const auto bypassTag = getVST3BypassParameterID (*processor);
11711160

11721161
const int32 numParams = data.inputParameterChanges->getParameterCount();
@@ -1194,26 +1183,26 @@ class AudioPluginProcessorVST3 : public Vst::AudioEffect
11941183
}
11951184
else
11961185
{
1197-
const auto parameterIndex = processor->getParameterIndexByHostID (static_cast<uint32> (tag));
1198-
if (! isPositiveAndBelow (parameterIndex, static_cast<int> (parameters.size())))
1199-
continue;
1200-
1201-
if (parameters[parameterIndex]->isPerformingChangeGesture())
1186+
const auto parameter = processor->getParameterByHostID (static_cast<uint32> (tag));
1187+
if (parameter == nullptr || parameter->isPerformingChangeGesture())
12021188
continue;
12031189

12041190
for (int32 p = 0; p < numPoints; ++p)
12051191
{
12061192
int32 sampleOffset;
12071193
Vst::ParamValue value;
12081194
if (queue->getPoint (p, sampleOffset, value) == kResultOk)
1209-
paramChangeBuffer.addChange (parameterIndex, static_cast<float> (value), sampleOffset);
1195+
addParameterChangeByHostParameterID (*processor,
1196+
paramChangeBuffer,
1197+
static_cast<uint32> (tag),
1198+
static_cast<float> (value),
1199+
sampleOffset);
12101200
}
12111201
}
12121202
}
12131203

12141204
paramChangeBuffer.sort();
1215-
for (const auto& change : paramChangeBuffer)
1216-
parameters[change.parameterIndex]->setNormalizedValue (change.normalizedValue);
1205+
applyParameterChangesToProcessor (*processor, paramChangeBuffer);
12171206
}
12181207

12191208
// --- Process Events ---

0 commit comments

Comments
 (0)