From ffb4006c9b46e61eb2f80f86135a9b92aae6513c Mon Sep 17 00:00:00 2001 From: falkTX Date: Fri, 23 Feb 2024 02:15:31 +0100 Subject: [PATCH] AU: handle UI->DSP state changes Signed-off-by: falkTX --- distrho/src/DistrhoPluginAU.cpp | 55 ++++++++++++++++++++--------- distrho/src/DistrhoUIAU.mm | 15 ++++++-- examples/Meters/DistrhoPluginInfo.h | 3 ++ examples/Meters/ExampleUIMeters.cpp | 28 ++++++++++++--- examples/Meters/Makefile | 1 + 5 files changed, 80 insertions(+), 22 deletions(-) diff --git a/distrho/src/DistrhoPluginAU.cpp b/distrho/src/DistrhoPluginAU.cpp index 610f26725..8f1d1f128 100644 --- a/distrho/src/DistrhoPluginAU.cpp +++ b/distrho/src/DistrhoPluginAU.cpp @@ -402,6 +402,13 @@ class PluginAU return noErr; #endif + case 'DPFe': + DISTRHO_SAFE_ASSERT_UINT_RETURN(inScope == kAudioUnitScope_Global, inScope, kAudioUnitErr_InvalidScope); + DISTRHO_SAFE_ASSERT_UINT_RETURN(inElement < fParameterCount, inElement, kAudioUnitErr_InvalidElement); + outDataSize = sizeof(bool); + outWritable = true; + return noErr; + case 'DPFp': DISTRHO_SAFE_ASSERT_UINT_RETURN(inScope == kAudioUnitScope_Global, inScope, kAudioUnitErr_InvalidScope); DISTRHO_SAFE_ASSERT_UINT_RETURN(inElement < fParameterCount, inElement, kAudioUnitErr_InvalidElement); @@ -409,12 +416,14 @@ class PluginAU outWritable = true; return noErr; - case 'DPFt': + #if DISTRHO_PLUGIN_WANT_STATE + case 'DPFs': DISTRHO_SAFE_ASSERT_UINT_RETURN(inScope == kAudioUnitScope_Global, inScope, kAudioUnitErr_InvalidScope); - DISTRHO_SAFE_ASSERT_UINT_RETURN(inElement < fParameterCount, inElement, kAudioUnitErr_InvalidElement); - outDataSize = sizeof(bool); + DISTRHO_SAFE_ASSERT_RETURN(inElement != 0, kAudioUnitErr_InvalidElement); + outDataSize = inElement; outWritable = true; return noErr; + #endif // unwanted properties case kAudioUnitProperty_CPULoad: @@ -917,21 +926,18 @@ class PluginAU // TODO return noErr; - case 'DPFp': + case 'DPFe': DISTRHO_SAFE_ASSERT_UINT_RETURN(inScope == kAudioUnitScope_Global, inScope, kAudioUnitErr_InvalidScope); DISTRHO_SAFE_ASSERT_UINT_RETURN(inElement < fParameterCount, inElement, kAudioUnitErr_InvalidElement); - DISTRHO_SAFE_ASSERT_UINT_RETURN(inDataSize == sizeof(float), inDataSize, kAudioUnitErr_InvalidPropertyValue); + DISTRHO_SAFE_ASSERT_UINT_RETURN(inDataSize == sizeof(bool), inDataSize, kAudioUnitErr_InvalidPropertyValue); { - const float value = *static_cast(inData); - DISTRHO_SAFE_ASSERT_RETURN(std::isfinite(value), kAudioUnitErr_InvalidParameterValue); - - fLastParameterValues[inElement] = value; - fPlugin.setParameterValue(inElement, value); + const bool started = *static_cast(inData); AudioUnitEvent event; std::memset(&event, 0, sizeof(event)); - event.mEventType = kAudioUnitEvent_ParameterValueChange; + event.mEventType = started ? kAudioUnitEvent_BeginParameterChangeGesture + : kAudioUnitEvent_EndParameterChangeGesture; event.mArgument.mParameter.mAudioUnit = fComponent; event.mArgument.mParameter.mParameterID = inElement; event.mArgument.mParameter.mScope = kAudioUnitScope_Global; @@ -939,24 +945,41 @@ class PluginAU } return noErr; - case 'DPFt': + case 'DPFp': DISTRHO_SAFE_ASSERT_UINT_RETURN(inScope == kAudioUnitScope_Global, inScope, kAudioUnitErr_InvalidScope); DISTRHO_SAFE_ASSERT_UINT_RETURN(inElement < fParameterCount, inElement, kAudioUnitErr_InvalidElement); - DISTRHO_SAFE_ASSERT_UINT_RETURN(inDataSize == sizeof(bool), inDataSize, kAudioUnitErr_InvalidPropertyValue); + DISTRHO_SAFE_ASSERT_UINT_RETURN(inDataSize == sizeof(float), inDataSize, kAudioUnitErr_InvalidPropertyValue); { - const bool started = *static_cast(inData); + const float value = *static_cast(inData); + DISTRHO_SAFE_ASSERT_RETURN(std::isfinite(value), kAudioUnitErr_InvalidParameterValue); + + fLastParameterValues[inElement] = value; + fPlugin.setParameterValue(inElement, value); AudioUnitEvent event; std::memset(&event, 0, sizeof(event)); - event.mEventType = started ? kAudioUnitEvent_BeginParameterChangeGesture - : kAudioUnitEvent_EndParameterChangeGesture; + event.mEventType = kAudioUnitEvent_ParameterValueChange; event.mArgument.mParameter.mAudioUnit = fComponent; event.mArgument.mParameter.mParameterID = inElement; event.mArgument.mParameter.mScope = kAudioUnitScope_Global; AUEventListenerNotify(NULL, NULL, &event); } return noErr; + + #if DISTRHO_PLUGIN_WANT_STATE + case 'DPFs': + DISTRHO_SAFE_ASSERT_UINT_RETURN(inScope == kAudioUnitScope_Global, inScope, kAudioUnitErr_InvalidScope); + DISTRHO_SAFE_ASSERT_RETURN(inElement != 0, kAudioUnitErr_InvalidElement); + DISTRHO_SAFE_ASSERT_UINT2_RETURN(inDataSize == inElement, inDataSize, inElement, kAudioUnitErr_InvalidPropertyValue); + { + const char* const key = static_cast(inData); + const char* const value = key + std::strlen(key) + 1; + + fPlugin.setState(key, value); + } + return noErr; + #endif } d_stdout("TODO SetProperty(%d:%s, %d:%s, %d, %p, %u)", inProp, AudioUnitPropertyID2Str(inProp), inScope, AudioUnitScope2Str(inScope), inElement, inData, inDataSize); diff --git a/distrho/src/DistrhoUIAU.mm b/distrho/src/DistrhoUIAU.mm index 74a3d8124..68c418462 100644 --- a/distrho/src/DistrhoUIAU.mm +++ b/distrho/src/DistrhoUIAU.mm @@ -156,7 +156,7 @@ static void auPropertyChangedCallback(void* const userData, void editParameter(const uint32_t rindex, const bool started) const { - AudioUnitSetProperty(fComponent, 'DPFt', kAudioUnitScope_Global, rindex, &started, sizeof(bool)); + AudioUnitSetProperty(fComponent, 'DPFe', kAudioUnitScope_Global, rindex, &started, sizeof(bool)); } static void editParameterCallback(void* const ptr, const uint32_t rindex, const bool started) @@ -175,8 +175,19 @@ static void setParameterCallback(void* const ptr, const uint32_t rindex, const f } #if DISTRHO_PLUGIN_WANT_STATE - void setState(const char*, const char*) + void setState(const char* const key, const char* const value) { + const size_t len_key = std::strlen(key); + const size_t len_value = std::strlen(value); + const size_t len_combined = len_key + len_value + 2; + char* const data = new char[len_combined]; + std::memcpy(data, key, len_key); + std::memcpy(data + len_key + 1, value, len_value); + data[len_key] = data[len_key + len_value + 1] = '\0'; + + AudioUnitSetProperty(fComponent, 'DPFs', kAudioUnitScope_Global, len_combined, data, len_combined); + + delete[] data; } static void setStateCallback(void* const ptr, const char* const key, const char* const value) diff --git a/examples/Meters/DistrhoPluginInfo.h b/examples/Meters/DistrhoPluginInfo.h index 46c9b42f3..4bc936bae 100644 --- a/examples/Meters/DistrhoPluginInfo.h +++ b/examples/Meters/DistrhoPluginInfo.h @@ -22,6 +22,9 @@ #define DISTRHO_PLUGIN_URI "http://distrho.sf.net/examples/Meters" #define DISTRHO_PLUGIN_CLAP_ID "studio.kx.distrho.examples.meters" +#define DISTRHO_PLUGIN_AU_SUBTYPE mtrs +#define DISTRHO_PLUGIN_AU_MANUFACTURER Dstr + #define DISTRHO_PLUGIN_HAS_UI 1 #define DISTRHO_PLUGIN_IS_RT_SAFE 1 #define DISTRHO_PLUGIN_NUM_INPUTS 2 diff --git a/examples/Meters/ExampleUIMeters.cpp b/examples/Meters/ExampleUIMeters.cpp index 0f33eff28..4318b7e55 100644 --- a/examples/Meters/ExampleUIMeters.cpp +++ b/examples/Meters/ExampleUIMeters.cpp @@ -41,7 +41,9 @@ class ExampleUIMeters : public UI fColorValue(0), // init meter values to 0 fOutLeft(0.0f), - fOutRight(0.0f) + fOutRight(0.0f), + // FIXME + fNeedsRepaint(false) { setGeometryConstraints(32, 128, false); } @@ -71,7 +73,9 @@ class ExampleUIMeters : public UI if (fOutLeft != value) { fOutLeft = value; - repaint(); + // FIXME + // repaint(); + fNeedsRepaint = true; } break; @@ -84,7 +88,9 @@ class ExampleUIMeters : public UI if (fOutRight != value) { fOutRight = value; - repaint(); + // FIXME + // repaint(); + fNeedsRepaint = true; } break; } @@ -198,6 +204,15 @@ class ExampleUIMeters : public UI return true; } + void uiIdle() override + { + if (fNeedsRepaint) + { + fNeedsRepaint = false; + repaint(); + } + } + // ------------------------------------------------------------------------------------------------------- private: @@ -213,6 +228,9 @@ class ExampleUIMeters : public UI */ float fOutLeft, fOutRight; + // FIXME this shouldnt be needed! + bool fNeedsRepaint; + /** Update color if needed. */ @@ -233,7 +251,9 @@ class ExampleUIMeters : public UI break; } - repaint(); + // FIXME + // repaint(); + fNeedsRepaint = true; } /** diff --git a/examples/Meters/Makefile b/examples/Meters/Makefile index 413f8304f..b6f91d050 100644 --- a/examples/Meters/Makefile +++ b/examples/Meters/Makefile @@ -40,6 +40,7 @@ TARGETS += lv2_sep TARGETS += vst2 TARGETS += vst3 TARGETS += clap +TARGETS += au endif # HAVE_OPENGL