summaryrefslogtreecommitdiff
path: root/distrho/src
diff options
context:
space:
mode:
Diffstat (limited to 'distrho/src')
-rw-r--r--distrho/src/CocoaUI/Info.plist14
-rw-r--r--distrho/src/CocoaUI/PluginAU_CocoaUI.m156
-rwxr-xr-xdistrho/src/CoreAudio106/Info.plist2
-rw-r--r--distrho/src/DistrhoPluginAU.cpp35
-rw-r--r--distrho/src/DistrhoUIAU.cpp211
5 files changed, 413 insertions, 5 deletions
diff --git a/distrho/src/CocoaUI/Info.plist b/distrho/src/CocoaUI/Info.plist
new file mode 100644
index 00000000..472ef07d
--- /dev/null
+++ b/distrho/src/CocoaUI/Info.plist
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleExecutable</key>
+ <string>X-DPF-EXECUTABLE-DPF-X-CocoaUI</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.example.audiounit.X-DPF-EXECUTABLE-DPF-X</string>
+ <key>CFBundlePackageType</key>
+ <string>BNDL</string>
+ <key>NSPrincipalClass</key>
+ <string>PluginAU_CocoaUIFactory</string>
+</dict>
+</plist>
diff --git a/distrho/src/CocoaUI/PluginAU_CocoaUI.m b/distrho/src/CocoaUI/PluginAU_CocoaUI.m
new file mode 100644
index 00000000..ee8da585
--- /dev/null
+++ b/distrho/src/CocoaUI/PluginAU_CocoaUI.m
@@ -0,0 +1,156 @@
+#include <Cocoa/Cocoa.h>
+#include <AudioUnit/AudioUnit.h>
+#include <AudioToolbox/AudioToolbox.h>
+#include <AudioUnit/AUCocoaUIView.h>
+
+#define MAX_PARAMS 100
+
+@interface PluginAU_CocoaUI : NSView
+{
+ AudioUnit mAU;
+ AudioUnitParameter mParameter[MAX_PARAMS];
+ AUParameterListenerRef mParameterListener;
+ UInt32 paramCount;
+}
+
+#pragma mark ____ PUBLIC FUNCTIONS ____
+- (void)setAU:(AudioUnit)inAU;
+
+#pragma mark ____ PRIVATE FUNCTIONS
+- (void)_synchronizeUIWithParameterValues;
+- (void)_addListeners;
+- (void)_removeListeners;
+
+#pragma mark ____ LISTENER CALLBACK DISPATCHEE ____
+- (void)_parameterListener:(void *)inObject
+ parameter:(const AudioUnitParameter *)inParameter
+ value:(Float32)inValue;
+
+@end
+
+
+@implementation PluginAU_CocoaUI
+
+#pragma mark ____ (INIT /) DEALLOC ____
+- (void)dealloc {
+ [self _removeListeners];
+ [super dealloc];
+}
+
+#pragma mark ____ PUBLIC FUNCTIONS ____
+- (void)setAU:(AudioUnit)inAU {
+ // remove previous listeners
+ if (mAU) [self _removeListeners];
+ mAU = inAU;
+
+ paramCount = 1; //globalUI->dspPtr.getParameterCount();
+
+ UInt32 i;
+ for (i = 0; i < paramCount; ++i) {
+ mParameter[i].mAudioUnit = inAU;
+ mParameter[i].mParameterID = i;
+ mParameter[i].mScope = kAudioUnitScope_Global;
+ mParameter[i].mElement = 0;
+ }
+
+ //auUI* dspUI = [self dspUI];
+
+ // add new listeners
+ [self _addListeners];
+
+ // initial setup
+ [self _synchronizeUIWithParameterValues];
+
+}
+
+#pragma mark ____ LISTENER CALLBACK DISPATCHER ____
+void ParameterListenerDispatcher (void *inRefCon, void *inObject,
+ const AudioUnitParameter *inParameter,
+ Float32 inValue)
+{
+ PluginAU_CocoaUI *SELF = (PluginAU_CocoaUI *)inRefCon;
+
+ [SELF _parameterListener:inObject parameter:inParameter value:inValue];
+}
+
+#pragma mark ____ PRIVATE FUNCTIONS ____
+- (void)_addListeners {
+ NSAssert (AUListenerCreate(ParameterListenerDispatcher, self,
+ CFRunLoopGetCurrent(), kCFRunLoopDefaultMode, 0.100, // 100 ms
+ &mParameterListener ) == noErr,
+ @"[_addListeners] AUListenerCreate()");
+
+ UInt32 i;
+ for (i = 0; i < paramCount; ++i) {
+ NSAssert(AUListenerAddParameter(mParameterListener,
+ NULL, &mParameter[i]) == noErr,
+ @"[_addListeners] AUListenerAddParameter()");
+ }
+}
+
+- (void)_removeListeners {
+ UInt32 i;
+ for (i = 0; i < paramCount; ++i) {
+ NSAssert (AUListenerRemoveParameter(mParameterListener,
+ NULL, &mParameter[i]) == noErr,
+ @"[_removeListeners] AUListenerRemoveParameter()");
+ }
+
+ NSAssert (AUListenerDispose(mParameterListener) == noErr,
+ @"[_removeListeners] AUListenerDispose()");
+}
+
+- (void)_synchronizeUIWithParameterValues {
+ Float32 value;
+ UInt32 i;
+
+ for (i = 0; i < paramCount; ++i) {
+ // only has global parameters
+ NSAssert (AudioUnitGetParameter(mAU, mParameter[i].mParameterID,
+ kAudioUnitScope_Global, 0, &value) == noErr,
+ @"[synchronizeUIWithParameterValues] (x.1)");
+ NSAssert (AUParameterSet(mParameterListener, self, &mParameter[i],
+ value, 0) == noErr,
+ @"[synchronizeUIWithParameterValues] (x.2)");
+ NSAssert (AUParameterListenerNotify (mParameterListener, self,
+ &mParameter[i]) == noErr,
+ @"[synchronizeUIWithParameterValues] (x.3)");
+ }
+}
+
+#pragma mark ____ LISTENER CALLBACK DISPATCHEE ____
+- (void)_parameterListener:(void *)inObject
+ parameter: (const AudioUnitParameter *)inParameter
+ value: (Float32)inValue
+{
+ //DPF: setUIParameter(inParameter->mParameterID, inValue);
+}
+
+@end
+
+@interface PluginAU_CocoaUIFactory : NSObject <AUCocoaUIBase>
+{
+ IBOutlet PluginAU_CocoaUI *uiFreshlyLoadedView;
+}
+
+- (NSString *) description;
+
+@end
+
+@implementation PluginAU_CocoaUIFactory
+
+- (unsigned) interfaceVersion {
+ return 0;
+}
+
+- (NSString *) description {
+ return @"DPF: AU UI";
+}
+
+- (NSView *)uiViewForAudioUnit:(AudioUnit)inAU withSize:(NSSize)inPreferredSize {
+ PluginAU_CocoaUI *view = [[PluginAU_CocoaUI alloc] init];
+ [view setAU:inAU];
+ return [view autorelease];
+}
+
+@end
diff --git a/distrho/src/CoreAudio106/Info.plist b/distrho/src/CoreAudio106/Info.plist
index e0e7c89f..f9d3ee2f 100755
--- a/distrho/src/CoreAudio106/Info.plist
+++ b/distrho/src/CoreAudio106/Info.plist
@@ -9,7 +9,7 @@
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
- <string>com.yourcompany.dpfplugin</string>
+ <string>com.example.audiounit.X-DPF-EXECUTABLE-DPF-X</string>
<key>CFBundleName</key>
<string>X-DPF-EXECUTABLE-DPF-X</string>
<key>CFBundleInfoDictionaryVersion</key>
diff --git a/distrho/src/DistrhoPluginAU.cpp b/distrho/src/DistrhoPluginAU.cpp
index 3b2fbc85..9c5a21bd 100644
--- a/distrho/src/DistrhoPluginAU.cpp
+++ b/distrho/src/DistrhoPluginAU.cpp
@@ -184,10 +184,37 @@ protected:
if (inID == kAudioUnitProperty_CocoaUI && inScope == kAudioUnitScope_Global && outData != nullptr)
{
d_stdout("GetProperty asked for CocoaUI");
- AudioUnitCocoaViewInfo* const info = (AudioUnitCocoaViewInfo*)outData;
- info->mCocoaAUViewBundleLocation = nullptr; // NSURL, CFURLRef
- info->mCocoaAUViewClass[0] = nullptr; // NSString, CFStringRef
- // return noErr;
+
+ // Need to do a special dance just to get the path to the UI binary
+
+ // Get the main DSP bundle
+ CFBundleRef bundle = CFBundleGetBundleWithIdentifier(
+ CFSTR("com.example.audiounit." DISTRHO_PLUGIN_NAME));
+ if (bundle == NULL) {
+ d_stdout("XXX bundle=NULL");
+ return fnfErr;
+ }
+
+ CFURLRef auuiURL = CFBundleCopyResourceURL(bundle,
+ CFSTR(DISTRHO_PLUGIN_NAME "-CocoaUI"),
+ CFSTR("bundle"),
+ NULL);
+
+ if (auuiURL == NULL) {
+ d_stdout("XXX auuiURL=NULL");
+ return fnfErr;
+ }
+
+ // Use hardcoded UI entrypoint
+ CFStringRef className = CFSTR("PluginAU_CocoaUIFactory");
+
+ AudioUnitCocoaViewInfo info;
+ info.mCocoaAUViewBundleLocation = auuiURL;
+ info.mCocoaAUViewClass[0] = className;
+
+ *((AudioUnitCocoaViewInfo *)outData) = info;
+
+ return noErr;
}
#endif
diff --git a/distrho/src/DistrhoUIAU.cpp b/distrho/src/DistrhoUIAU.cpp
new file mode 100644
index 00000000..dc5a61c7
--- /dev/null
+++ b/distrho/src/DistrhoUIAU.cpp
@@ -0,0 +1,211 @@
+/*
+ * DISTRHO Plugin Framework (DPF)
+ * Copyright (C) 2012-2019 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
+ * permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "DistrhoUIInternal.hpp"
+
+#include "../extra/Sleep.hpp"
+
+START_NAMESPACE_DISTRHO
+
+//#if ! DISTRHO_PLUGIN_WANT_MIDI_INPUT
+static const sendNoteFunc sendNoteCallback = nullptr;
+//#endif
+
+// -----------------------------------------------------------------------
+
+class UIAu
+{
+public:
+ UIAu(const char* const uiTitle)
+ : fUI(this, 0, nullptr, setParameterCallback, setStateCallback, sendNoteCallback, setSizeCallback),
+ fHostClosed(false)
+ {
+ fUI.setWindowTitle(uiTitle);
+ }
+
+ ~UIAu()
+ {
+ }
+
+ void exec()
+ {
+ for (;;)
+ {
+ if (fHostClosed || ! fUI.idle())
+ break;
+
+ d_msleep(30);
+ }
+ }
+
+ // -------------------------------------------------------------------
+
+#if 0
+#if DISTRHO_PLUGIN_WANT_STATE
+ void auui_configure(const char* key, const char* value)
+ {
+ fUI.stateChanged(key, value);
+ }
+#endif
+#endif
+
+ void auui_control(ulong index, float value)
+ {
+ fUI.parameterChanged(index, value);
+ }
+
+#if 0
+#if DISTRHO_PLUGIN_WANT_PROGRAMS
+ void auui_program(ulong bank, ulong program)
+ {
+ fUI.programLoaded(bank * 128 + program);
+ }
+#endif
+#endif
+
+ void auui_samplerate(const double sampleRate)
+ {
+ fUI.setSampleRate(sampleRate, true);
+ }
+
+ void auui_show()
+ {
+ fUI.setWindowVisible(true);
+ }
+
+ void auui_hide()
+ {
+ fUI.setWindowVisible(false);
+ }
+
+ void auui_quit()
+ {
+ fHostClosed = true;
+ fUI.quit();
+ }
+
+ // -------------------------------------------------------------------
+
+protected:
+ void setParameterValue(const uint32_t rindex, const float value)
+ {
+ //FIXME fUI.setParameterValue(rindex, value);
+ }
+
+ void setState(const char* const key, const char* const value)
+ {
+ }
+
+#if 0
+#if DISTRHO_PLUGIN_WANT_MIDI_INPUT
+ void sendNote(const uint8_t channel, const uint8_t note, const uint8_t velocity)
+ {
+ if (fOscData.server == nullptr)
+ return;
+ if (channel > 0xF)
+ return;
+
+ uint8_t mdata[4] = {
+ 0,
+ static_cast<uint8_t>(channel + (velocity != 0 ? 0x90 : 0x80)),
+ note,
+ velocity
+ };
+ fOscData.send_midi(mdata);
+ }
+#endif
+#endif
+
+ void setSize(const uint width, const uint height)
+ {
+ fUI.setWindowSize(width, height);
+ }
+
+private:
+ UIExporter fUI;
+ bool fHostClosed;
+
+ // -------------------------------------------------------------------
+ // Callbacks
+
+ #define uiPtr ((UIAu*)ptr)
+
+ static void setParameterCallback(void* ptr, uint32_t rindex, float value)
+ {
+ uiPtr->setParameterValue(rindex, value);
+ }
+
+ static void setStateCallback(void* ptr, const char* key, const char* value)
+ {
+ uiPtr->setState(key, value);
+ }
+
+#if 0
+#if DISTRHO_PLUGIN_WANT_MIDI_INPUT
+ static void sendNoteCallback(void* ptr, uint8_t channel, uint8_t note, uint8_t velocity)
+ {
+ uiPtr->sendNote(channel, note, velocity);
+ }
+#endif
+#endif
+
+ static void setSizeCallback(void* ptr, uint width, uint height)
+ {
+ uiPtr->setSize(width, height);
+ }
+
+ #undef uiPtr
+};
+
+// -----------------------------------------------------------------------
+
+static const char* gUiTitle = nullptr;
+static UIAu* globalUI = nullptr;
+
+static void initUiIfNeeded()
+{
+ if (globalUI != nullptr)
+ return;
+
+ if (d_lastUiSampleRate == 0.0)
+ d_lastUiSampleRate = 44100.0;
+
+ globalUI = new UIAu(gUiTitle);
+}
+
+END_NAMESPACE_DISTRHO
+
+// -----------------------------------------------------------------------
+
+int main(int argc, char* argv[])
+{
+ USE_NAMESPACE_DISTRHO
+
+ // dummy test mode
+ if (argc == 1)
+ {
+ gUiTitle = "AU UI Test";
+
+ initUiIfNeeded();
+ globalUI->auui_show();
+ globalUI->exec();
+
+ delete globalUI;
+ globalUI = nullptr;
+
+ return 0;
+ }
+}