Skip to content

Commit 576b507

Browse files
committed
Add kParameterDesignationReset, implement for AU, CLAP and LV2
Signed-off-by: falkTX <falktx@falktx.com>
1 parent 800583a commit 576b507

File tree

6 files changed

+135
-47
lines changed

6 files changed

+135
-47
lines changed

distrho/DistrhoDetails.hpp

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ static constexpr const uint32_t kStateIsOnlyForUI = 0x20;
202202

203203
/**
204204
Parameter designation.@n
205-
Allows a parameter to be specially designated for a task, like bypass.
205+
Allows a parameter to be specially designated for a task, like bypass and reset.
206206
207207
Each designation is unique, there must be only one parameter that uses it.@n
208208
The use of designated parameters is completely optional.
@@ -214,13 +214,20 @@ enum ParameterDesignation {
214214
/**
215215
Null or unset designation.
216216
*/
217-
kParameterDesignationNull = 0,
217+
kParameterDesignationNull,
218218

219219
/**
220220
Bypass designation.@n
221221
When on (> 0.5f), it means the plugin must run in a bypassed state.
222222
*/
223-
kParameterDesignationBypass = 1
223+
kParameterDesignationBypass,
224+
225+
/**
226+
Reset designation.@n
227+
When on (> 0.5f), it means the plugin should reset its internal processing state
228+
(like filters, oscillators, envelopes, lfos, etc) and kill all voices.
229+
*/
230+
kParameterDesignationReset,
224231
};
225232

226233
/**
@@ -234,7 +241,12 @@ namespace ParameterDesignationSymbols {
234241
static constexpr const char bypass[] = "dpf_bypass";
235242

236243
/**
237-
Bypass designation symbol, inverted for LV2 so it becomes "enabled".
244+
Reset designation symbol.
245+
*/
246+
static constexpr const char reset[] = "dpf_reset";
247+
248+
/**
249+
LV2 bypass designation symbol, inverted for LV2 so it becomes "enabled".
238250
*/
239251
static constexpr const char bypass_lv2[] = "lv2_enabled";
240252
};
@@ -728,6 +740,18 @@ struct Parameter {
728740
ranges.min = 0.0f;
729741
ranges.max = 1.0f;
730742
break;
743+
case kParameterDesignationReset:
744+
hints = kParameterIsAutomatable|kParameterIsBoolean|kParameterIsInteger|kParameterIsTrigger;
745+
name = "Reset";
746+
shortName = "Reset";
747+
symbol = ParameterDesignationSymbols::reset;
748+
unit = "";
749+
midiCC = 0;
750+
groupId = kPortGroupNone;
751+
ranges.def = 0.0f;
752+
ranges.min = 0.0f;
753+
ranges.max = 1.0f;
754+
break;
731755
}
732756
}
733757

distrho/src/DistrhoPluginAU.cpp

Lines changed: 52 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ bool isNumChannelsComboValid(const uint16_t numInputs, const uint16_t numOutputs
264264
// --------------------------------------------------------------------------------------------------------------------
265265

266266
struct PropertyListener {
267-
AudioUnitPropertyID prop;
267+
AudioUnitPropertyID prop;
268268
AudioUnitPropertyListenerProc proc;
269269
void* userData;
270270
};
@@ -348,7 +348,8 @@ class PluginAU
348348
fUsingRenderListeners(false),
349349
fParameterCount(fPlugin.getParameterCount()),
350350
fLastParameterValues(nullptr),
351-
fBypassParameterIndex(UINT32_MAX)
351+
fBypassParameterIndex(UINT32_MAX),
352+
fResetParameterIndex(UINT32_MAX)
352353
#if DISTRHO_PLUGIN_WANT_MIDI_INPUT
353354
, fMidiEventCount(0)
354355
#endif
@@ -365,7 +366,7 @@ class PluginAU
365366
, fStateCount(fPlugin.getStateCount())
366367
#endif
367368
{
368-
if (fParameterCount != 0)
369+
if (fParameterCount != 0)
369370
{
370371
fLastParameterValues = new float[fParameterCount];
371372
std::memset(fLastParameterValues, 0, sizeof(float) * fParameterCount);
@@ -374,8 +375,17 @@ class PluginAU
374375
{
375376
fLastParameterValues[i] = fPlugin.getParameterValue(i);
376377

377-
if (fPlugin.getParameterDesignation(i) == kParameterDesignationBypass)
378+
switch (fPlugin.getParameterDesignation(i))
379+
{
380+
case kParameterDesignationNull:
381+
break;
382+
case kParameterDesignationBypass:
378383
fBypassParameterIndex = i;
384+
break;
385+
case kParameterDesignationReset:
386+
fResetParameterIndex = i;
387+
break;
388+
}
379389
}
380390
}
381391

@@ -923,13 +933,13 @@ class PluginAU
923933
case kAudioUnitProperty_FastDispatch:
924934
switch (inElement)
925935
{
926-
case kAudioUnitGetParameterSelect:
936+
case kAudioUnitGetParameterSelect:
927937
*static_cast<AudioUnitGetParameterProc*>(outData) = FastDispatchGetParameter;
928938
return noErr;
929-
case kAudioUnitSetParameterSelect:
939+
case kAudioUnitSetParameterSelect:
930940
*static_cast<AudioUnitSetParameterProc*>(outData) = FastDispatchSetParameter;
931941
return noErr;
932-
case kAudioUnitRenderSelect:
942+
case kAudioUnitRenderSelect:
933943
*static_cast<AudioUnitRenderProc*>(outData) = FastDispatchRender;
934944
return noErr;
935945
}
@@ -1458,7 +1468,7 @@ class PluginAU
14581468
const float value = bypass ? 1.f : 0.f;
14591469
fLastParameterValues[fBypassParameterIndex] = value;
14601470
fPlugin.setParameterValue(fBypassParameterIndex, value);
1461-
notifyPropertyListeners(inProp, inScope, inElement);
1471+
notifyPropertyListeners(inProp, inScope, inElement);
14621472
}
14631473
}
14641474
return noErr;
@@ -1480,12 +1490,12 @@ class PluginAU
14801490
#if DISTRHO_PLUGIN_WANT_TIMEPOS
14811491
{
14821492
const UInt32 usableDataSize = std::min(inDataSize, static_cast<UInt32>(sizeof(HostCallbackInfo)));
1483-
const bool changed = std::memcmp(&fHostCallbackInfo, inData, usableDataSize) != 0;
1493+
const bool changed = std::memcmp(&fHostCallbackInfo, inData, usableDataSize) != 0;
14841494

1485-
std::memcpy(&fHostCallbackInfo, inData, usableDataSize);
1495+
std::memcpy(&fHostCallbackInfo, inData, usableDataSize);
14861496

14871497
if (sizeof(HostCallbackInfo) > usableDataSize)
1488-
std::memset(&fHostCallbackInfo + usableDataSize, 0, sizeof(HostCallbackInfo) - usableDataSize);
1498+
std::memset(&fHostCallbackInfo + usableDataSize, 0, sizeof(HostCallbackInfo) - usableDataSize);
14891499

14901500
if (changed)
14911501
notifyPropertyListeners(inProp, inScope, inElement);
@@ -1612,7 +1622,7 @@ class PluginAU
16121622
AUEventListenerNotify(NULL, NULL, &event);
16131623

16141624
if (fBypassParameterIndex == inElement)
1615-
notifyPropertyListeners(kAudioUnitProperty_BypassEffect, kAudioUnitScope_Global, 0);
1625+
notifyPropertyListeners(kAudioUnitProperty_BypassEffect, kAudioUnitScope_Global, 0);
16161626
}
16171627
return noErr;
16181628

@@ -1821,7 +1831,12 @@ class PluginAU
18211831
DISTRHO_SAFE_ASSERT_UINT_RETURN(scope == kAudioUnitScope_Global || scope == kAudioUnitScope_Input || scope == kAudioUnitScope_Output, scope, kAudioUnitErr_InvalidScope);
18221832
DISTRHO_SAFE_ASSERT_UINT_RETURN(elem == 0, elem, kAudioUnitErr_InvalidElement);
18231833

1824-
if (fPlugin.isActive())
1834+
if (fResetParameterIndex != UINT32_MAX)
1835+
{
1836+
fPlugin.setParameterValue(fResetParameterIndex, 1.f);
1837+
fPlugin.setParameterValue(fResetParameterIndex, 0.f);
1838+
}
1839+
else if (fPlugin.isActive())
18251840
{
18261841
fPlugin.deactivate();
18271842
fPlugin.activate();
@@ -2180,6 +2195,7 @@ class PluginAU
21802195
const uint32_t fParameterCount;
21812196
float* fLastParameterValues;
21822197
uint32_t fBypassParameterIndex;
2198+
uint32_t fResetParameterIndex;
21832199

21842200
#if DISTRHO_PLUGIN_WANT_MIDI_INPUT
21852201
uint32_t fMidiEventCount;
@@ -2220,7 +2236,7 @@ class PluginAU
22202236
const PropertyListener& pl(*it);
22212237

22222238
if (pl.prop == prop)
2223-
pl.proc(pl.userData, fComponent, prop, scope, elem);
2239+
pl.proc(pl.userData, fComponent, prop, scope, elem);
22242240
}
22252241
}
22262242

@@ -2845,7 +2861,7 @@ class PluginAU
28452861
// --------------------------------------------------------------------------------------------------------------------
28462862

28472863
struct AudioComponentPlugInInstance {
2848-
AudioComponentPlugInInterface acpi;
2864+
AudioComponentPlugInInterface acpi;
28492865
PluginAU* plugin;
28502866

28512867
AudioComponentPlugInInstance() noexcept
@@ -2854,25 +2870,25 @@ struct AudioComponentPlugInInstance {
28542870
{
28552871
std::memset(&acpi, 0, sizeof(acpi));
28562872
acpi.Open = Open;
2857-
acpi.Close = Close;
2858-
acpi.Lookup = Lookup;
2859-
acpi.reserved = nullptr;
2873+
acpi.Close = Close;
2874+
acpi.Lookup = Lookup;
2875+
acpi.reserved = nullptr;
28602876
}
28612877

28622878
~AudioComponentPlugInInstance()
28632879
{
28642880
delete plugin;
28652881
}
28662882

2867-
static OSStatus Open(void* const self, const AudioUnit component)
2883+
static OSStatus Open(void* const self, const AudioUnit component)
28682884
{
28692885
d_debug("AudioComponentPlugInInstance::Open(%p)", self);
28702886

28712887
static_cast<AudioComponentPlugInInstance*>(self)->plugin = new PluginAU(component);
28722888
return noErr;
28732889
}
28742890

2875-
static OSStatus Close(void* const self)
2891+
static OSStatus Close(void* const self)
28762892
{
28772893
d_debug("AudioComponentPlugInInstance::Close(%p)", self);
28782894

@@ -2964,15 +2980,15 @@ struct AudioComponentPlugInInstance {
29642980
d_debug("AudioComponentPlugInInstance::GetPropertyInfo(%p, %d:%x:%s, %d:%s, %d, ...)",
29652981
self, inProp, inProp, AudioUnitPropertyID2Str(inProp), inScope, AudioUnitScope2Str(inScope), inElement);
29662982

2967-
UInt32 dataSize = 0;
2968-
Boolean writable = false;
2983+
UInt32 dataSize = 0;
2984+
Boolean writable = false;
29692985
const OSStatus res = self->plugin->auGetPropertyInfo(inProp, inScope, inElement, dataSize, writable);
29702986

2971-
if (outDataSize != nullptr)
2972-
*outDataSize = dataSize;
2987+
if (outDataSize != nullptr)
2988+
*outDataSize = dataSize;
29732989

2974-
if (outWritable != nullptr)
2975-
*outWritable = writable;
2990+
if (outWritable != nullptr)
2991+
*outWritable = writable;
29762992

29772993
return res;
29782994
}
@@ -3016,24 +3032,24 @@ struct AudioComponentPlugInInstance {
30163032
if (res != noErr)
30173033
return res;
30183034

3019-
void* outBuffer;
3035+
void* outBuffer;
30203036
uint8_t* tmpBuffer;
30213037
if (inDataSize < outDataSize)
3022-
{
3023-
tmpBuffer = new uint8_t[outDataSize];
3024-
outBuffer = tmpBuffer;
3025-
}
3038+
{
3039+
tmpBuffer = new uint8_t[outDataSize];
3040+
outBuffer = tmpBuffer;
3041+
}
30263042
else
30273043
{
3028-
tmpBuffer = nullptr;
3029-
outBuffer = outData;
3030-
}
3044+
tmpBuffer = nullptr;
3045+
outBuffer = outData;
3046+
}
30313047

30323048
res = self->plugin->auGetProperty(inProp, inScope, inElement, outBuffer);
30333049

3034-
if (res != noErr)
3050+
if (res != noErr)
30353051
{
3036-
*ioDataSize = 0;
3052+
*ioDataSize = 0;
30373053
return res;
30383054
}
30393055

distrho/src/DistrhoPluginCLAP.cpp

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,7 @@ class PluginCLAP : ClapEventQueue
751751
updateStateValueCallback),
752752
fHost(host),
753753
fOutputEvents(nullptr),
754+
fResetParameterIndex(UINT32_MAX),
754755
#if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS != 0
755756
fUsingCV(false),
756757
#endif
@@ -763,7 +764,19 @@ class PluginCLAP : ClapEventQueue
763764
#endif
764765
fHostExtensions(host)
765766
{
766-
fCachedParameters.setup(fPlugin.getParameterCount());
767+
if (const uint32_t paramCount = fPlugin.getParameterCount())
768+
{
769+
fCachedParameters.setup(paramCount);
770+
771+
for (uint32_t i=0; i<paramCount; ++i)
772+
{
773+
if (fPlugin.getParameterDesignation(i) == kParameterDesignationReset)
774+
{
775+
fResetParameterIndex = i;
776+
break;
777+
}
778+
}
779+
}
767780

768781
#if DISTRHO_PLUGIN_HAS_UI && DISTRHO_PLUGIN_WANT_MIDI_INPUT
769782
fNotesRingBuffer.setRingBuffer(&fNotesBuffer, true);
@@ -823,7 +836,18 @@ class PluginCLAP : ClapEventQueue
823836

824837
void reset()
825838
{
826-
fHost->request_restart(fHost);
839+
if (fResetParameterIndex != UINT32_MAX)
840+
{
841+
#if DISTRHO_PLUGIN_WANT_MIDI_INPUT
842+
fMidiEventCount = 0;
843+
#endif
844+
fPlugin.setParameterValue(fResetParameterIndex, 1.f);
845+
fPlugin.setParameterValue(fResetParameterIndex, 0.f);
846+
}
847+
else
848+
{
849+
fHost->request_restart(fHost);
850+
}
827851
}
828852

829853
bool process(const clap_process_t* const process)
@@ -1119,14 +1143,19 @@ class PluginCLAP : ClapEventQueue
11191143
{
11201144
const ParameterRanges& ranges(fPlugin.getParameterRanges(index));
11211145

1122-
if (fPlugin.getParameterDesignation(index) == kParameterDesignationBypass)
1146+
switch (fPlugin.getParameterDesignation(index))
11231147
{
1148+
case kParameterDesignationBypass:
11241149
info->flags = CLAP_PARAM_IS_STEPPED|CLAP_PARAM_IS_BYPASS|CLAP_PARAM_IS_AUTOMATABLE;
11251150
std::strcpy(info->name, "Bypass");
11261151
std::strcpy(info->module, "dpf_bypass");
1127-
}
1128-
else
1129-
{
1152+
break;
1153+
case kParameterDesignationReset:
1154+
info->flags = CLAP_PARAM_IS_STEPPED|CLAP_PARAM_IS_READONLY;
1155+
std::strcpy(info->name, "Reset");
1156+
std::strcpy(info->module, "dpf_reset");
1157+
break;
1158+
default:
11301159
const uint32_t hints = fPlugin.getParameterHints(index);
11311160
const uint32_t groupId = fPlugin.getParameterGroupId(index);
11321161

@@ -1156,6 +1185,7 @@ class PluginCLAP : ClapEventQueue
11561185
}
11571186

11581187
d_strncpy(info->module + wrtn, fPlugin.getParameterSymbol(index), CLAP_PATH_SIZE - wrtn);
1188+
break;
11591189
}
11601190

11611191
info->id = index;
@@ -1791,6 +1821,7 @@ class PluginCLAP : ClapEventQueue
17911821
const clap_host_t* const fHost;
17921822
const clap_output_events_t* fOutputEvents;
17931823

1824+
uint32_t fResetParameterIndex;
17941825
#if DISTRHO_PLUGIN_NUM_INPUTS != 0
17951826
const float* fAudioInputs[DISTRHO_PLUGIN_NUM_INPUTS];
17961827
#endif

distrho/src/DistrhoPluginLV2export.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,16 @@ void lv2_generate_ttl(const char* const basename)
758758
pluginString += " lv2:portProperty lv2:toggled , lv2:integer ;\n";
759759
pluginString += " lv2:designation lv2:enabled ;\n";
760760
break;
761+
case kParameterDesignationReset:
762+
designated = true;
763+
pluginString += " lv2:name \"Reset\" ;\n";
764+
pluginString += " lv2:symbol \"" + String(ParameterDesignationSymbols::reset) + "\" ;\n";
765+
pluginString += " lv2:default 0 ;\n";
766+
pluginString += " lv2:minimum 0 ;\n";
767+
pluginString += " lv2:maximum 1 ;\n";
768+
pluginString += " lv2:portProperty lv2:toggled , lv2:integer , <" LV2_PORT_PROPS__trigger "> ;\n";
769+
pluginString += " lv2:designation <" LV2_KXSTUDIO_PROPERTIES__Reset "> ;\n";
770+
break;
761771
}
762772
}
763773

0 commit comments

Comments
 (0)