Skip to content

Commit

Permalink
Fix some vst3 param oddities, use double normalized when possible
Browse files Browse the repository at this point in the history
  • Loading branch information
falkTX committed Aug 31, 2022
1 parent eff1c6f commit bbdbeb1
Showing 1 changed file with 72 additions and 40 deletions.
112 changes: 72 additions & 40 deletions distrho/src/DistrhoPluginVST3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ class PluginVst3
return placeSorted(event.sample_offset);
}

bool appendCC(const int32_t sampleOffset, v3_param_id paramId, const double value) noexcept
bool appendCC(const int32_t sampleOffset, v3_param_id paramId, const double normalized) noexcept
{
InputEventStorage& eventStorage(eventListStorage[numUsed]);

Expand All @@ -465,18 +465,18 @@ class PluginVst3
{
case 128:
eventStorage.type = CC_ChannelPressure;
eventStorage.midi[1] = std::max(0, std::min(127, (int)(value * 127)));
eventStorage.midi[1] = std::max(0, std::min(127, (int)(normalized * 127)));
eventStorage.midi[2] = 0;
break;
case 129:
eventStorage.type = CC_Pitchbend;
eventStorage.midi[1] = std::max(0, std::min(16384, (int)(value * 16384))) & 0x7f;
eventStorage.midi[2] = std::max(0, std::min(16384, (int)(value * 16384))) >> 7;
eventStorage.midi[1] = std::max(0, std::min(16384, (int)(normalized * 16384))) & 0x7f;
eventStorage.midi[2] = std::max(0, std::min(16384, (int)(normalized * 16384))) >> 7;
break;
default:
eventStorage.type = CC_Normal;
eventStorage.midi[1] = cc;
eventStorage.midi[2] = std::max(0, std::min(127, (int)(value * 127)));
eventStorage.midi[2] = std::max(0, std::min(127, (int)(normalized * 127)));
break;
}

Expand Down Expand Up @@ -578,7 +578,7 @@ class PluginVst3
#endif // DISTRHO_PLUGIN_WANT_MIDI_INPUT

public:
PluginVst3(v3_host_application** const host)
PluginVst3(v3_host_application** const host, const bool isComponent)
: fPlugin(this, writeMidiCallback, requestParameterValueChangeCallback, nullptr),
fComponentHandler(nullptr),
#if DISTRHO_PLUGIN_HAS_UI
Expand All @@ -588,6 +588,7 @@ class PluginVst3
fConnectionFromCtrlToView(nullptr),
fHostApplication(host),
#endif
fIsComponent(isComponent),
fParameterCount(fPlugin.getParameterCount()),
fVst3ParameterCount(fParameterCount + kVst3InternalParameterCount),
fCachedParameterValues(nullptr),
Expand Down Expand Up @@ -690,7 +691,7 @@ class PluginVst3
// ----------------------------------------------------------------------------------------------------------------
// utilities and common code

void setNormalizedPluginParameterValue(const uint32_t index, const float normalized)
float unnormalizeParameterValue(const uint32_t index, const double normalized)
{
const ParameterRanges& ranges(fPlugin.getParameterRanges(index));
const uint32_t hints = fPlugin.getParameterHints(index);
Expand All @@ -699,18 +700,35 @@ class PluginVst3
if (hints & kParameterIsBoolean)
{
const float midRange = ranges.min + (ranges.max - ranges.min) / 2.0f;
value = value > midRange ? ranges.max : ranges.min;
}
else if (hints & kParameterIsInteger)
{
value = std::round(value);
return value > midRange ? ranges.max : ranges.min;
}

if (hints & kParameterIsInteger)
return std::round(value);

return value;
}

void setNormalizedPluginParameterValue(const uint32_t index, const double normalized)
{
const float value = unnormalizeParameterValue(index, normalized);

if (d_isEqual(fCachedParameterValues[kVst3InternalParameterBaseCount + index], value))
return;

fCachedParameterValues[kVst3InternalParameterBaseCount + index] = value;
#if DISTRHO_PLUGIN_HAS_UI
fParameterValueChangesForUI[kVst3InternalParameterBaseCount + index] = true;

#if DISTRHO_PLUGIN_HAS_UI
#if DPF_VST3_USES_SEPARATE_CONTROLLER
if (!fIsComponent)
#endif
fPlugin.setParameterValue(index, value);
{
fParameterValueChangesForUI[kVst3InternalParameterBaseCount + index] = true;
}
#endif

if (!fPlugin.isParameterOutputOrTrigger(index))
fPlugin.setParameterValue(index, value);
}

// ----------------------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -1488,7 +1506,7 @@ class PluginVst3
if (v3_param_changes** const inparamsptr = data->input_params)
{
int32_t offset;
double value;
double normalized;

for (int32_t i = 0, count = v3_cpp_obj(inparamsptr)->get_param_count(inparamsptr); i < count; ++i)
{
Expand All @@ -1507,10 +1525,10 @@ class PluginVst3
{
for (int32_t j = 0, pcount = v3_cpp_obj(queue)->get_point_count(queue); j < pcount; ++j)
{
if (v3_cpp_obj(queue)->get_point(queue, j, &offset, &value) != V3_OK)
if (v3_cpp_obj(queue)->get_point(queue, j, &offset, &normalized) != V3_OK)
break;

if (inputEventList.appendCC(offset, rindex, value))
if (inputEventList.appendCC(offset, rindex, normalized))
{
canAppendMoreEvents = false;
break;
Expand All @@ -1526,14 +1544,14 @@ class PluginVst3
continue;

// if there are any parameter changes at frame 0, handle them here
if (v3_cpp_obj(queue)->get_point(queue, 0, &offset, &value) != V3_OK)
if (v3_cpp_obj(queue)->get_point(queue, 0, &offset, &normalized) != V3_OK)
break;

if (offset != 0)
continue;

const uint32_t index = rindex - kVst3InternalParameterCount;
setNormalizedPluginParameterValue(index, value);
setNormalizedPluginParameterValue(index, normalized);
}
}

Expand All @@ -1552,7 +1570,7 @@ class PluginVst3
if (v3_param_changes** const inparamsptr = data->input_params)
{
int32_t offset;
double value;
double normalized;

for (int32_t i = 0, count = v3_cpp_obj(inparamsptr)->get_param_count(inparamsptr); i < count; ++i)
{
Expand All @@ -1572,14 +1590,14 @@ class PluginVst3
if (pcount <= 0)
continue;

if (v3_cpp_obj(queue)->get_point(queue, pcount - 1, &offset, &value) != V3_OK)
if (v3_cpp_obj(queue)->get_point(queue, pcount - 1, &offset, &normalized) != V3_OK)
break;

if (offset == 0)
continue;

const uint32_t index = rindex - kVst3InternalParameterCount;
setNormalizedPluginParameterValue(index, value);
setNormalizedPluginParameterValue(index, normalized);
}
}

Expand Down Expand Up @@ -1918,7 +1936,7 @@ class PluginVst3
DISTRHO_SAFE_ASSERT_UINT2_RETURN(index < fParameterCount, index, fParameterCount, 0.0);

const ParameterRanges& ranges(fPlugin.getParameterRanges(index));
return ranges.getNormalizedValue(plain);
return ranges.getFixedAndNormalizedValue(plain);
}

double getParameterNormalized(const v3_param_id rindex)
Expand Down Expand Up @@ -1954,7 +1972,7 @@ class PluginVst3
DISTRHO_SAFE_ASSERT_UINT2_RETURN(index < fParameterCount, index, fParameterCount, 0.0);

const ParameterRanges& ranges(fPlugin.getParameterRanges(index));
return ranges.getNormalizedValue(fCachedParameterValues[kVst3InternalParameterBaseCount + index]);
return ranges.getFixedAndNormalizedValue(static_cast<double>(fCachedParameterValues[kVst3InternalParameterBaseCount + index]));
}

v3_result setParameterNormalized(const v3_param_id rindex, const double normalized)
Expand Down Expand Up @@ -2025,6 +2043,10 @@ class PluginVst3
const uint32_t index = static_cast<uint32_t>(rindex - kVst3InternalParameterCount);
DISTRHO_SAFE_ASSERT_UINT2_RETURN(index < fParameterCount, index, fParameterCount, V3_INVALID_ARG);

if (fIsComponent) {
DISTRHO_SAFE_ASSERT_RETURN(!fPlugin.isParameterOutputOrTrigger(index), V3_INVALID_ARG);
}

setNormalizedPluginParameterValue(index, normalized);
#endif
return V3_OK;
Expand Down Expand Up @@ -2230,7 +2252,12 @@ class PluginVst3
DISTRHO_SAFE_ASSERT_INT_RETURN(res == V3_OK, res, res);

const uint32_t index = rindex - kVst3InternalParameterCount;
const double normalized = fPlugin.getParameterRanges(index).getNormalizedValue(value);
const double normalized = fPlugin.getParameterRanges(index).getFixedAndNormalizedValue(value);

fCachedParameterValues[kVst3InternalParameterBaseCount + index] = value;

if (! fPlugin.isParameterOutputOrTrigger(index))
fPlugin.setParameterValue(index, value);

return v3_cpp_obj(fComponentHandler)->perform_edit(fComponentHandler, rindex, normalized);
}
Expand Down Expand Up @@ -2374,6 +2401,7 @@ class PluginVst3
#endif

// Temporary data
const bool fIsComponent;
const uint32_t fParameterCount;
const uint32_t fVst3ParameterCount; // full offset + real
float* fCachedParameterValues; // basic offset + real
Expand Down Expand Up @@ -2800,18 +2828,18 @@ class PluginVst3
{
DISTRHO_SAFE_ASSERT_RETURN(outparamsptr != nullptr,);

v3_param_id paramId;
float curValue;
double normalized;

#if DPF_VST3_USES_SEPARATE_CONTROLLER
for (v3_param_id i=kVst3InternalParameterBufferSize; i<=kVst3InternalParameterSampleRate; ++i)
{
if (! fParameterValuesChangedDuringProcessing[i])
continue;

curValue = plainParameterToNormalized(i, fCachedParameterValues[i]);
normalized = plainParameterToNormalized(i, fCachedParameterValues[i]);
fParameterValuesChangedDuringProcessing[i] = false;
addParameterDataToHostOutputEvents(outparamsptr, i, curValue);
addParameterDataToHostOutputEvents(outparamsptr, i, normalized);
}
#endif

Expand Down Expand Up @@ -2850,10 +2878,9 @@ class PluginVst3
fParameterValueChangesForUI[kVst3InternalParameterBaseCount + i] = true;
#endif

paramId = kVst3InternalParameterCount + i;
curValue = fPlugin.getParameterRanges(i).getNormalizedValue(curValue);
normalized = fPlugin.getParameterRanges(i).getFixedAndNormalizedValue(static_cast<double>(curValue));

if (! addParameterDataToHostOutputEvents(outparamsptr, paramId, curValue, offset))
if (! addParameterDataToHostOutputEvents(outparamsptr, kVst3InternalParameterCount + i, normalized, offset))
break;
}

Expand All @@ -2864,28 +2891,33 @@ class PluginVst3
{
fLastKnownLatency = latency;

curValue = plainParameterToNormalized(kVst3InternalParameterLatency,
fCachedParameterValues[kVst3InternalParameterLatency]);
addParameterDataToHostOutputEvents(outparamsptr, kVst3InternalParameterLatency, curValue);
normalized = plainParameterToNormalized(kVst3InternalParameterLatency,
fCachedParameterValues[kVst3InternalParameterLatency]);
addParameterDataToHostOutputEvents(outparamsptr, kVst3InternalParameterLatency, normalized);
}
#endif
}

bool addParameterDataToHostOutputEvents(v3_param_changes** const outparamsptr,
v3_param_id paramId,
const float curValue,
const double normalized,
const int32_t offset = 0)
{
int32_t index = 0;
v3_param_value_queue** const queue = v3_cpp_obj(outparamsptr)->add_param_data(outparamsptr,
&paramId, &index);
DISTRHO_SAFE_ASSERT_RETURN(queue != nullptr, false);
DISTRHO_SAFE_ASSERT_RETURN(v3_cpp_obj(queue)->add_point(queue, 0, curValue, &index) == V3_OK, false);
DISTRHO_SAFE_ASSERT_RETURN(v3_cpp_obj(queue)->add_point(queue, 0, normalized, &index) == V3_OK, false);

/* FLStudio gets confused with this one, skip it for now
if (offset != 0)
v3_cpp_obj(queue)->add_point(queue, offset, curValue, &index);
v3_cpp_obj(queue)->add_point(queue, offset, normalized, &index);
*/

return true;

// unused at the moment, buggy VST3 hosts :/
(void)offset;
}

#if DISTRHO_PLUGIN_HAS_UI
Expand Down Expand Up @@ -3586,7 +3618,7 @@ struct dpf_edit_controller : v3_edit_controller_cpp {
d_nextCanRequestParameterValueChanges = true;

// create the actual plugin
controller->vst3 = new PluginVst3(hostApplication);
controller->vst3 = new PluginVst3(hostApplication, false);

// set connection point if needed
if (dpf_comp2ctrl_connection_point* const point = controller->connectionComp2Ctrl)
Expand Down Expand Up @@ -4313,7 +4345,7 @@ struct dpf_component : v3_component_cpp {
d_nextCanRequestParameterValueChanges = true;

// create the actual plugin
component->vst3 = new PluginVst3(hostApplication);
component->vst3 = new PluginVst3(hostApplication, true);

#if DPF_VST3_USES_SEPARATE_CONTROLLER
// set connection point if needed
Expand Down

0 comments on commit bbdbeb1

Please sign in to comment.