Skip to content

Commit

Permalink
Implement programs for AU
Browse files Browse the repository at this point in the history
Signed-off-by: falkTX <falktx@falktx.com>
  • Loading branch information
falkTX committed Feb 25, 2024
1 parent 2a38514 commit 098b891
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 20 deletions.
140 changes: 123 additions & 17 deletions distrho/src/DistrhoPluginAU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,16 +247,15 @@ class PluginAU
, fMidiEventCount(0)
#endif
#if DISTRHO_PLUGIN_WANT_PROGRAMS
, fCurrentProgram(0)
, fCurrentProgram(-1)
, fLastFactoryProgram(0)
, fProgramCount(fPlugin.getProgramCount())
, fFactoryPresetsData(nullptr)
#endif
#if DISTRHO_PLUGIN_WANT_STATE
, fStateCount(fPlugin.getStateCount())
#endif

{
fCurrentPreset.presetName = CFSTR("Default");
fCurrentPreset.presetNumber = 0;

if (fParameterCount != 0)
{
fLastParameterValues = new float[fParameterCount];
Expand All @@ -280,6 +279,33 @@ class PluginAU
std::memset(&fMidiOutputPackets, 0, sizeof(fMidiOutputPackets));
#endif

#if DISTRHO_PLUGIN_WANT_PROGRAMS
if (fProgramCount != 0)
{
fFactoryPresetsData = new AUPreset[fProgramCount];
std::memset(fFactoryPresetsData, 0, sizeof(AUPreset) * fProgramCount);

for (uint32_t i=0; i<fProgramCount; ++i)
{
fFactoryPresetsData[i].presetNumber = i;
fFactoryPresetsData[i].presetName = CFStringCreateWithCString(nullptr,
fPlugin.getProgramName(i),
kCFStringEncodingUTF8);
}
}
else
{
fFactoryPresetsData = new AUPreset;
std::memset(fFactoryPresetsData, 0, sizeof(AUPreset));

fFactoryPresetsData->presetNumber = 0;
fFactoryPresetsData->presetName = CFSTR("Default");
}
#endif

fUserPresetData.presetNumber = -1;
fUserPresetData.presetName = CFSTR("");

#if DISTRHO_PLUGIN_WANT_STATE
for (uint32_t i=0; i<fStateCount; ++i)
{
Expand All @@ -298,8 +324,14 @@ class PluginAU

~PluginAU()
{
CFRelease(fCurrentPreset.presetName);
delete[] fLastParameterValues;
CFRelease(fUserPresetData.presetName);

#if DISTRHO_PLUGIN_WANT_PROGRAMS
for (uint32_t i=0; i<fProgramCount; ++i)
CFRelease(fFactoryPresetsData[i].presetName);
delete[] fFactoryPresetsData;
#endif
}

OSStatus auInitialize()
Expand Down Expand Up @@ -451,6 +483,17 @@ class PluginAU
outWritable = true;
return noErr;

case kAudioUnitProperty_FactoryPresets:
DISTRHO_SAFE_ASSERT_UINT_RETURN(inScope == kAudioUnitScope_Global, inScope, kAudioUnitErr_InvalidScope);
DISTRHO_SAFE_ASSERT_UINT_RETURN(inElement == 0, inElement, kAudioUnitErr_InvalidElement);
#if DISTRHO_PLUGIN_WANT_PROGRAMS
outDataSize = sizeof(CFArrayRef);
outWritable = false;
return noErr;
#else
return kAudioUnitErr_InvalidProperty;
#endif

case kAudioUnitProperty_HostCallbacks:
DISTRHO_SAFE_ASSERT_UINT_RETURN(inScope == kAudioUnitScope_Global, inScope, kAudioUnitErr_InvalidScope);
DISTRHO_SAFE_ASSERT_UINT_RETURN(inElement == 0, inElement, kAudioUnitErr_InvalidElement);
Expand Down Expand Up @@ -795,6 +838,19 @@ class PluginAU
// TODO
break;

#if DISTRHO_PLUGIN_WANT_PROGRAMS
case kAudioUnitProperty_FactoryPresets:
if (const CFMutableArrayRef presetsRef = CFArrayCreateMutable(nullptr, fProgramCount, nullptr))
{
for (uint32_t i=0; i<fProgramCount; ++i)
CFArrayAppendValue(presetsRef, &fFactoryPresetsData[i]);

*static_cast<CFArrayRef*>(outData) = presetsRef;
return noErr;
}
return kAudio_ParamError;
#endif

#if DISTRHO_PLUGIN_WANT_TIMEPOS
case kAudioUnitProperty_HostCallbacks:
std::memcpy(outData, &fHostCallbackInfo, sizeof(HostCallbackInfo));
Expand All @@ -806,7 +862,16 @@ class PluginAU
return noErr;

case kAudioUnitProperty_PresentPreset:
std::memcpy(outData, &fCurrentPreset, sizeof(AUPreset));
#if DISTRHO_PLUGIN_WANT_PROGRAMS
if (fCurrentProgram >= 0)
{
std::memcpy(outData, &fFactoryPresetsData[fCurrentProgram], sizeof(AUPreset));
}
else
#endif
{
std::memcpy(outData, &fUserPresetData, sizeof(AUPreset));
}
return noErr;

#if DISTRHO_PLUGIN_HAS_UI
Expand Down Expand Up @@ -865,7 +930,7 @@ class PluginAU

#if DISTRHO_PLUGIN_WANT_PROGRAMS
case 'DPFo':
*static_cast<uint32_t*>(outData) = fCurrentProgram;
*static_cast<uint32_t*>(outData) = fLastFactoryProgram;
return noErr;
#endif

Expand Down Expand Up @@ -1136,8 +1201,30 @@ class PluginAU
DISTRHO_SAFE_ASSERT_UINT_RETURN(inElement == 0, inElement, kAudioUnitErr_InvalidElement);
DISTRHO_SAFE_ASSERT_UINT_RETURN(inDataSize == sizeof(AUPreset), inDataSize, kAudioUnitErr_InvalidPropertyValue);
{
CFRelease(fCurrentPreset.presetName);
std::memcpy(&fCurrentPreset, inData, sizeof(AUPreset));
const int32_t presetNumber = static_cast<const AUPreset*>(inData)->presetNumber;

#if DISTRHO_PLUGIN_WANT_PROGRAMS
if (presetNumber >= 0)
{
if (fCurrentProgram != presetNumber)
{
fCurrentProgram = presetNumber;
fLastFactoryProgram = presetNumber;
fPlugin.loadProgram(fLastFactoryProgram);
notifyListeners('DPFo', kAudioUnitScope_Global, 0);
}
}
else
{
fCurrentProgram = presetNumber;
CFRelease(fUserPresetData.presetName);
std::memcpy(&fUserPresetData, inData, sizeof(AUPreset));
}
#else
DISTRHO_SAFE_ASSERT_INT_RETURN(presetNumber < 0, presetNumber, kAudioUnitErr_InvalidPropertyValue);
CFRelease(fUserPresetData.presetName);
std::memcpy(&fUserPresetData, inData, sizeof(AUPreset));
#endif
}
return noErr;

Expand Down Expand Up @@ -1573,7 +1660,6 @@ class PluginAU
const AudioUnit fComponent;

// AUv2 related fields
AUPreset fCurrentPreset;
OSStatus fLastRenderError;
PropertyListeners fPropertyListeners;
Float64 fSampleRateForInput;
Expand Down Expand Up @@ -1601,8 +1687,12 @@ class PluginAU
#endif

#if DISTRHO_PLUGIN_WANT_PROGRAMS
uint32_t fCurrentProgram;
int32_t fCurrentProgram;
uint32_t fLastFactoryProgram;
uint32_t fProgramCount;
AUPreset* fFactoryPresetsData;
#endif
AUPreset fUserPresetData;

#if DISTRHO_PLUGIN_WANT_STATE
const uint32_t fStateCount;
Expand Down Expand Up @@ -1818,7 +1908,16 @@ class PluginAU
CFRelease(num);
}

CFDictionarySetValue(clsInfo, CFSTR(kAUPresetNameKey), fCurrentPreset.presetName);
#if DISTRHO_PLUGIN_WANT_PROGRAMS
if (fCurrentProgram >= 0)
{
CFDictionarySetValue(clsInfo, CFSTR(kAUPresetNameKey), fFactoryPresetsData[fCurrentProgram].presetName);
}
else
#endif
{
CFDictionarySetValue(clsInfo, CFSTR(kAUPresetNameKey), fUserPresetData.presetName);
}

if (const CFMutableDictionaryRef data = CFDictionaryCreateMutable(nullptr,
0,
Expand Down Expand Up @@ -1949,12 +2048,19 @@ class PluginAU
if (CFDictionaryGetValueIfPresent(data, CFSTR("program"), reinterpret_cast<const void**>(&programRef))
&& CFGetTypeID(programRef) == CFNumberGetTypeID())
{
SInt32 program = 0;
if (CFNumberGetValue(programRef, kCFNumberSInt32Type, &program) && program >= 0)
SInt32 program = -1;
if (CFNumberGetValue(programRef, kCFNumberSInt32Type, &program))
{
fCurrentProgram = program;
fPlugin.loadProgram(fCurrentProgram);
notifyListeners('DPFo', kAudioUnitScope_Global, 0);

if (program >= 0)
{
fLastFactoryProgram = program;
fPlugin.loadProgram(fLastFactoryProgram);
notifyListeners('DPFo', kAudioUnitScope_Global, 0);
}

notifyListeners(kAudioUnitProperty_PresentPreset, kAudioUnitScope_Global, 0);
}
}
#endif
Expand Down
11 changes: 8 additions & 3 deletions distrho/src/DistrhoPluginExport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,11 @@ void generate_au_plist(const PluginExporter& plugin,
outputFile << " <string>" << majorVersion << "." << minorVersion << "." << microVersion << "</string>\n";
outputFile << " <key>CFBundleVersion</key>\n";
outputFile << " <string>" << majorVersion << "." << minorVersion << "." << microVersion << "</string>\n";
outputFile << " <key>NSHumanReadableCopyright</key>\n";
outputFile << " <string>" << license << "</string>\n";
if (license != nullptr && license[0] != '\0')
{
outputFile << " <key>NSHumanReadableCopyright</key>\n";
outputFile << " <string>" << license << "</string>\n";
}
outputFile << " <key>NSHighResolutionCapable</key>\n";
outputFile << " <true/>\n";
outputFile << " <key>AudioComponents</key>\n";
Expand Down Expand Up @@ -122,8 +125,10 @@ int main(int argc, char* argv[])

String license(plugin.getLicense());

if (license.isEmpty())
{}
// License as URL, use as-is
if (license.contains("://"))
else if (license.contains("://"))
{}
// License contains quotes, use as-is
else if (license.contains('"'))
Expand Down
5 changes: 5 additions & 0 deletions distrho/src/DistrhoUIAU.mm
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,11 @@ - (NSView*) uiViewForAudioUnit:(AudioUnit)component withSize:(NSSize)inPreferred
dataSize = sizeof(Float64);
AudioUnitGetProperty(component, kAudioUnitProperty_SampleRate, kAudioUnitScope_Output, 0, &sampleRate, &dataSize);

#if defined(DISTRHO_UI_DEFAULT_WIDTH) && defined(DISTRHO_UI_DEFAULT_HEIGHT)
const double scaleFactor = [NSScreen mainScreen].backingScaleFactor;
inPreferredSize = NSMakeSize(DISTRHO_UI_DEFAULT_WIDTH * scaleFactor, DISTRHO_UI_DEFAULT_HEIGHT * scaleFactor);
#endif

// create view
view = [[[COCOA_VIEW_CLASS_NAME alloc] initWithPreferredSize:inPreferredSize] autorelease];
view->ui = new DPF_UI_AU(component, view, sampleRate, instancePointer);
Expand Down

0 comments on commit 098b891

Please sign in to comment.