Browse Source

Fix AU setState to allow arbitrary keys

Squashed commit of the following:

commit 5afe95e223
Author: falkTX <falktx@falktx.com>
Date:   Thu Apr 3 11:07:20 2025 +0200

    Cleanup to follow current DPF style

    Signed-off-by: falkTX <falktx@falktx.com>

commit 44278abbb1
Author: TheOnlyJoey <joeyferweda@gmail.com>
Date:   Wed Apr 2 05:18:11 2025 +0200

    Forgot to remove include from testing

commit 870ac0b4f2
Author: TheOnlyJoey <joeyferweda@gmail.com>
Date:   Wed Apr 2 05:15:26 2025 +0200

    Updated setState on AU components to allow arbitrary key-value pairs to have parity with other plugin formats on macOS.

Signed-off-by: falkTX <falktx@falktx.com>
popup-tests
falkTX 1 month ago
parent
commit
3f1e740f76
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
2 changed files with 51 additions and 28 deletions
  1. +35
    -20
      distrho/src/DistrhoPluginAU.cpp
  2. +16
    -8
      distrho/src/DistrhoUIAU.mm

+ 35
- 20
distrho/src/DistrhoPluginAU.cpp View File

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2024 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2025 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -1153,6 +1153,8 @@ public:
const CFStringRef keyRef = CFStringCreateWithCString(nullptr,
fPlugin.getStateKey(i),
kCFStringEncodingASCII);
DISTRHO_SAFE_ASSERT_CONTINUE(keyRef != nullptr);

CFArrayAppendValue(keysRef, keyRef);
CFRelease(keyRef);
}
@@ -1647,29 +1649,42 @@ public:

case 'DPFs':
DISTRHO_SAFE_ASSERT_UINT_RETURN(inScope == kAudioUnitScope_Global, inScope, kAudioUnitErr_InvalidScope);
DISTRHO_SAFE_ASSERT_UINT_RETURN(inDataSize == sizeof(CFStringRef), inDataSize, kAudioUnitErr_InvalidPropertyValue);
DISTRHO_SAFE_ASSERT_UINT_RETURN(inDataSize == sizeof(CFDictionaryRef), inDataSize, kAudioUnitErr_InvalidPropertyValue);
#if DISTRHO_PLUGIN_WANT_STATE
DISTRHO_SAFE_ASSERT_UINT_RETURN(inElement < fStateCount, inElement, kAudioUnitErr_InvalidElement);
DISTRHO_SAFE_ASSERT_UINT_RETURN(inElement == 0, inElement, kAudioUnitErr_InvalidElement);
{
const CFStringRef valueRef = *static_cast<const CFStringRef*>(inData);
const CFDictionaryRef dictRef = *static_cast<const CFDictionaryRef*>(inData);
DISTRHO_SAFE_ASSERT_RETURN(CFGetTypeID(dictRef) == CFDictionaryGetTypeID(),
kAudioUnitErr_InvalidPropertyValue);
DISTRHO_SAFE_ASSERT_RETURN(CFDictionaryGetCount(dictRef) == 1, kAudioUnitErr_InvalidPropertyValue);

CFStringRef keyRef = nullptr;
CFStringRef valueRef = nullptr;
CFDictionaryGetKeysAndValues(dictRef,
reinterpret_cast<const void**>(&keyRef),
reinterpret_cast<const void**>(&valueRef));
DISTRHO_SAFE_ASSERT_RETURN(keyRef != nullptr && CFGetTypeID(keyRef) == CFStringGetTypeID(),
kAudioUnitErr_InvalidPropertyValue);
DISTRHO_SAFE_ASSERT_RETURN(valueRef != nullptr && CFGetTypeID(valueRef) == CFStringGetTypeID(),
kAudioUnitErr_InvalidPropertyValue);

const CFIndex valueLen = CFStringGetLength(valueRef);
char* const value = static_cast<char*>(std::malloc(valueLen + 1));
DISTRHO_SAFE_ASSERT_RETURN(value != nullptr, kAudio_ParamError);
DISTRHO_SAFE_ASSERT_RETURN(CFStringGetCString(valueRef, value, valueLen + 1, kCFStringEncodingUTF8),
const CFIndex keyRefLen = CFStringGetLength(keyRef);
char* key = static_cast<char*>(std::malloc(keyRefLen + 1));
DISTRHO_SAFE_ASSERT_RETURN(CFStringGetCString(keyRef, key, keyRefLen + 1, kCFStringEncodingASCII),
kAudioUnitErr_InvalidPropertyValue);

const String& key(fPlugin.getStateKey(inElement));
const CFIndex valueRefLen = CFStringGetLength(valueRef);
char* value = static_cast<char*>(std::malloc(valueRefLen + 1));
DISTRHO_SAFE_ASSERT_RETURN(CFStringGetCString(valueRef, value, valueRefLen + 1, kCFStringEncodingUTF8),
kAudioUnitErr_InvalidPropertyValue);

// save this key as needed
if (fPlugin.wantStateKey(key))
fStateMap[key] = value;
const String dkey(key);

fPlugin.setState(key, value);
// save this key as needed
if (fPlugin.wantStateKey(dkey))
fStateMap[dkey] = value;

std::free(value);
fPlugin.setState(dkey, value);
}
return noErr;
#else
@@ -2561,12 +2576,12 @@ private:
CFStringRef keyRef = CFStringCreateWithCString(nullptr, key, kCFStringEncodingASCII);
CFStringRef valueRef = CFStringCreateWithCString(nullptr, value, kCFStringEncodingUTF8);

if (CFDictionaryRef dictRef = CFDictionaryCreate(nullptr,
reinterpret_cast<const void**>(&keyRef),
reinterpret_cast<const void**>(&valueRef),
1,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks))
if (const CFDictionaryRef dictRef = CFDictionaryCreate(nullptr,
reinterpret_cast<const void**>(&keyRef),
reinterpret_cast<const void**>(&valueRef),
1,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks))
{
CFArrayAppendValue(statesRef, dictRef);
CFRelease(dictRef);


+ 16
- 8
distrho/src/DistrhoUIAU.mm View File

@@ -1,6 +1,6 @@
/*
* DISTRHO Plugin Framework (DPF)
* Copyright (C) 2012-2024 Filipe Coelho <falktx@falktx.com>
* Copyright (C) 2012-2025 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
@@ -125,6 +125,7 @@ public:

CFRunLoopAddTimer(CFRunLoopGetCurrent(), fTimerRef, kCFRunLoopCommonModes);

// setup property listeners
AudioUnitAddPropertyListener(fComponent, kAudioUnitProperty_SampleRate, auPropertyChangedCallback, this);
AudioUnitAddPropertyListener(fComponent, 'DPFp', auPropertyChangedCallback, this);
#if DISTRHO_PLUGIN_WANT_PROGRAMS
@@ -322,15 +323,22 @@ private:
#if DISTRHO_PLUGIN_WANT_STATE
void setState(const char* const key, const char* const value)
{
const std::vector<String>::iterator it = std::find(fStateKeys.begin(), fStateKeys.end(), key);
DISTRHO_SAFE_ASSERT_RETURN(it != fStateKeys.end(),);

if (const CFStringRef valueRef = CFStringCreateWithCString(nullptr, value, kCFStringEncodingUTF8))
CFStringRef keyRef = CFStringCreateWithCString(nullptr, key, kCFStringEncodingASCII);
CFStringRef valueRef = CFStringCreateWithCString(nullptr, value, kCFStringEncodingUTF8);

if (const CFDictionaryRef dictRef = CFDictionaryCreate(nullptr,
reinterpret_cast<const void**>(&keyRef),
reinterpret_cast<const void**>(&valueRef),
1,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks))
{
const uint32_t index = it - fStateKeys.begin();
AudioUnitSetProperty(fComponent, 'DPFs', kAudioUnitScope_Global, index, &valueRef, sizeof(CFStringRef));
CFRelease(valueRef);
AudioUnitSetProperty(fComponent, 'DPFs', kAudioUnitScope_Global, 0, &dictRef, sizeof(dictRef));
CFRelease(dictRef);
}

CFRelease(keyRef);
CFRelease(valueRef);
}

static void setStateCallback(void* const ptr, const char* const key, const char* const value)


Loading…
Cancel
Save