From 098b891a45dbcb438045275dda13fe269efee46f Mon Sep 17 00:00:00 2001 From: falkTX Date: Mon, 26 Feb 2024 00:08:23 +0100 Subject: [PATCH] Implement programs for AU Signed-off-by: falkTX --- distrho/src/DistrhoPluginAU.cpp | 140 ++++++++++++++++++++++++---- distrho/src/DistrhoPluginExport.cpp | 11 ++- distrho/src/DistrhoUIAU.mm | 5 + 3 files changed, 136 insertions(+), 20 deletions(-) diff --git a/distrho/src/DistrhoPluginAU.cpp b/distrho/src/DistrhoPluginAU.cpp index ecd6cb08..c060d512 100644 --- a/distrho/src/DistrhoPluginAU.cpp +++ b/distrho/src/DistrhoPluginAU.cpp @@ -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]; @@ -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; ipresetNumber = 0; + fFactoryPresetsData->presetName = CFSTR("Default"); + } + #endif + + fUserPresetData.presetNumber = -1; + fUserPresetData.presetName = CFSTR(""); + #if DISTRHO_PLUGIN_WANT_STATE for (uint32_t i=0; i(outData) = presetsRef; + return noErr; + } + return kAudio_ParamError; + #endif + #if DISTRHO_PLUGIN_WANT_TIMEPOS case kAudioUnitProperty_HostCallbacks: std::memcpy(outData, &fHostCallbackInfo, sizeof(HostCallbackInfo)); @@ -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 @@ -865,7 +930,7 @@ class PluginAU #if DISTRHO_PLUGIN_WANT_PROGRAMS case 'DPFo': - *static_cast(outData) = fCurrentProgram; + *static_cast(outData) = fLastFactoryProgram; return noErr; #endif @@ -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(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; @@ -1573,7 +1660,6 @@ class PluginAU const AudioUnit fComponent; // AUv2 related fields - AUPreset fCurrentPreset; OSStatus fLastRenderError; PropertyListeners fPropertyListeners; Float64 fSampleRateForInput; @@ -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; @@ -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, @@ -1949,12 +2048,19 @@ class PluginAU if (CFDictionaryGetValueIfPresent(data, CFSTR("program"), reinterpret_cast(&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 diff --git a/distrho/src/DistrhoPluginExport.cpp b/distrho/src/DistrhoPluginExport.cpp index fe64f7d9..f4cd5507 100644 --- a/distrho/src/DistrhoPluginExport.cpp +++ b/distrho/src/DistrhoPluginExport.cpp @@ -67,8 +67,11 @@ void generate_au_plist(const PluginExporter& plugin, outputFile << " " << majorVersion << "." << minorVersion << "." << microVersion << "\n"; outputFile << " CFBundleVersion\n"; outputFile << " " << majorVersion << "." << minorVersion << "." << microVersion << "\n"; - outputFile << " NSHumanReadableCopyright\n"; - outputFile << " " << license << "\n"; + if (license != nullptr && license[0] != '\0') + { + outputFile << " NSHumanReadableCopyright\n"; + outputFile << " " << license << "\n"; + } outputFile << " NSHighResolutionCapable\n"; outputFile << " \n"; outputFile << " AudioComponents\n"; @@ -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('"')) diff --git a/distrho/src/DistrhoUIAU.mm b/distrho/src/DistrhoUIAU.mm index 90af5b1f..36adaa9b 100644 --- a/distrho/src/DistrhoUIAU.mm +++ b/distrho/src/DistrhoUIAU.mm @@ -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);