Audio unit custom view

DSP, Plugin and Host development discussion.
Post Reply New Topic
RELATED
PRODUCTS

Post

I'm currently developing a software synthesizer as an OSX AudioUnit. It's working just fine, except that when I use the plugin in more than one track in Logic Pro X, only the first track I selected my plugin for will display the plugin's custom view. Any subsequent instances of the plugin shows only the standard generic view. Even if I open a saved Logic project with two tracks using my plugin, the track I created second will always just open the generic view, while the one I created first will open the custom view, even if I open settings for the second track first.

I based my project on Apple's Audio Effect example (which has a custom view), and this example does not have the same problem. I tried comparing my project with this example, but can't seem to find any differences that could cause this.

Post

Not sure without seeing the code, but you could try to localize things like some of the older AU examples. You might want to see if you can find the older StarterAUEffectWithCocoaUI (which used to be a template) example and try that method.

Before that, you could try @private visibility modifier for your uiFreshlyLoadedView declaration in your YOUR_EFFECT_CocoaViewFactory.h file. That might help keep it encapsulated and prevent class cross-coupling.

But if you want to try a completely different approach like the old template, in your AU *.cpp file 'getProperty' section for your custom view, try:

Code: Select all

				AudioUnitCocoaViewInfo cocoaInfo;
				cocoaInfo.mCocoaAUViewBundleLocation = bundleURL;
				cocoaInfo.mCocoaAUViewClass[0] = CFStringCreateWithCString(NULL, "YOUR_EFFECT_CocoaViewFactory", kCFStringEncodingUTF8);


And then in YOUR_EFFECT_CocoaViewFactory.m file view class:

Code: Select all

- (NSView *)uiViewForAudioUnit:(AudioUnit)inAU withSize:(NSSize)inPreferredSize
{
	if (![NSBundle loadNibNamed: @"YOUR_EFFECT_CocoaView" owner:self]) {
        NSLog (@"Unable to load nib for view.");
		return nil;
	}
I am no cocoa-master, but that is generally the basics of how I tie in the UI. If that doesn't work, you might have to look into how it is being interacted with in your UIView. Maybe someone else can be more specific. Good luck.

Post

Thank you very much for your suggestions. I've tried them out, with no luck. Either the result was the same, or that the View never showed up.

I have found one difference between the Apple demo filter and my project. In Build settings for the View target, there was originally "Apple LLVM 5.1 - Language: Compile Sources As = According to file type."
In my project this is "Objective-C++". If I change this to "According to file type", I get this error in AUInstrumentBase.h: " 'vector' file not found " on this line: #include <vector>.

Do you think this could be the culprit?

I remember struggling with this when I was merging code from the Apple Effect demo with the Apple SinSynth demo, in order to end up with a synth with a custom View. I thought I had done it, but found out later that the View would only show up on one track.

I think the whole AU-thing looks a bit unfinished and messy. Maybe I should try VST instead? Do you think that would be easier or harder to work with than AU?

Post

Just a few things that I'll throw out there since there are a few issues going on.

Well if that didn't fix it, then it is another namespace collision issue, which can be a bear to debug. That was a big issue for me getting back into AUs after the carbon/cocoa changeover. To avoid it now I prefix everything... names, classes, maps, events, etc. That's all in Apple's 'Programming with Objective-C' documents, but it is buried in thousands of lines of text.

ObjC classes can only exist once, so a second instance would fail to load if there is a collision. It could be a simple as renaming all your classes with a prefix that includes a unique plugin and manufacturer name, such as MycompanyCoolplugin_ViewFactory, MycompanyCoolplugin_UIView, MycompanyCoolplugin_CocoaView and the CFBundleRef URL string (and maybe even the main *.nib/*.xib file just to be sure), and then making sure that those names all agree across the c++, ObjC and *.plist files (and make sure to clean the build between changes). That should prevent issues between previously-loaded plugins or plugins built from the same template that might inadvertently use a common namespace. Also uniquely-name all product targets and make sure the subtype code is unique to each.

(Also if you redefined alloc/dealloc in your header, you might get that same issue. I use ARC on my cocoa UIs so that I don't mess with that at all (but that kills support pre-10.6 if that is an issue for you)).

As for the mixed c/objC question, (if you have not tried this already) if you are using 'according to file type' and including a c++ *.h in your objC code and mixing them, you'll need to rename your *.m files to *.mm to tip the compiler off to expect c++ since ObjC and C++ bind at different times at compile, but I thought that but 'Objective-C++' should take care of that (maybe not, I don't use that option so I am not sure), so I am not sure why the error, but try *.mm if you have #include a C file for some reason.

As for VST, my personal feelings (take this with a grain of salt) I have been avoiding VST until they either get the standards nailed down and working, clean-up/simplify/debug VST3, or give up and revert to VST2 and put out a 2.5 version of the SDK (not likely). VST locks you out of Apple's pro-apps though, so that is a big minus with the off-setting plus being that you can easily port the VST code across platforms. I also hate vstgui4 but that is another conversation. the VST3 SDK does have an AU wrapper though if you want to take that option, although it is outdated and has to be hacked to get a working build. Another alternative is to use a 3rd party library/IDE that has already sorted out the kinks. JUCE and WDL come to mind.

VSTs are subjectively simpler in terms of the DSP/UI relationship, BUT that complexity is somewhat by design in AUs since one of the tenets is that the DSP and UI don't have to be run in the same hosts or even on the same machines and the ability to do things like intercept the parameters across multiple plugins and roll dynamically them into a common UI (like adding an AU to a virtual instrument in garageband where it will map the parameters to the instrument's UI), or splitting the DSP load while retaining the common UI like Logic's distributed node processing, but as a result the cocoa namespace handling makes things really messy sometimes, but once you have a handle on that it is not a big deal except having to provide unique classes with prefixed names per-plugin. Rumor also has it that the AU examples and literature are in for an overhaul in the near future, so we'll see what changes that brings... hopefully cleaner UI handling, but the bottom line is that both formats have their issues that you'll have to work around.

Sorry for the long post, hopefully something in there is helpful.

Post Reply

Return to “DSP and Plugin Development”