So far, I’ve gotten more questions about getting Cocoa Views to work in Audio Units than other requests, so here we go.
Since I’ve been on a lengthy vacation, I didn’t think too much about it until I tried using the built-in template for Audio Unit Effects in Xcode 4.x. It doesn’t make it at all clear how to get it all working. Fortunately, it’s not terribly difficult. It just takes a bunch of changes to the files and projects that are generated by the template.
Also, there have been some changes in Mac OS X Lion that require attention to make this (and any new Audio Units) work.
Create the Project
First off, go ahead and create a new project. In the project sheet, select Audio Unit Effect as your project type and click Next.
In the next sheet you will be naming your effect. Make note of your Company Identifier, as you’ll be needing that later. Ensure that with Cocoa View is checked and click Next.
Go ahead and save your project as you normally would.
In my case, I’m using the simple project name of CV. So, wherever you see CV (in italics) in the following code, just insert your project name.
Tweak the Project
Once the project is created, we’ll start to adjust various project settings along with adding and removing some files to make things work on Lion.
First off, find the following files in your Xcode project’s AUPublic folder and delete them:
Next, and this is part of the Lion changes, Control-Click on your AUPublic folder and select “Add Files to CV…”
In the sheet that appears, navigate to
/Developer/Extras/CoreAudio/AudioUnits/AUPublic/AUBase and select the following files for addition.
We now have one more file to add. Right click on CV (or your project folder in Xcode) and select New File…
Create an empty file and name it CV-Prefix.pch.
Now, we could just turn the prefix setting in the build settings to not look for this file, but for consistency with the FilterDemo sample code, I just figured we’d put it in there in the event we want to use it later on for precompiled headers.
Last, we need to decide what architecture(s) we want to build this for. For simplicity’s sake, I build a universal component for 64-bit and 32-bit platforms. You’ll need to decide for yourself and make the changes accordingly. Here’s how.
Select your project in the left-most pane of Xcode. It will probably be right at the top of the pane and list how many Targets you have.
Once you’ve selected your target, you can make modifications to your build settings. Of particular interest are Architectures and Build Active Architecture Only. If you want to test both the 32 and 64-bit versions, you’ll need to set the following:
- Architectures – Standard (32/64-bit Intel)
- Build Active Architecture Only – No (for both Debug and Release – see below)
This is a point of confusion for many people. Basically, this is where you’re telling the compiler which versions to build. By default, the Debug setting is Yes. Which means that on any machines sold today, it will build only 64-bit versions since all the machines now are 64-bit. The problem with that is that AULab runs, by default, in 32-bit mode, so you won’t ever see your Audio Unit in the list.
Now, let’s modify some files…
Changing the Files
I’m just going to list the files to change along with the changes to make.
Locate the following lines and remove them.
#if AU_DEBUG_DISPATCHER #include "AUDebugDispatcher.h" #endif
Locate the following lines and remove them.
#if AU_DEBUG_DISPATCHER mDebugDispatcher = new AUDebugDispatcher (this); #endif
Locate the following line:
and change it to:
This is one piece of a fairly significant change the Apple is making with respect to Audio Units and the move away from Component Manager.
Locate this line in your GetProperty method:
CFBundleRef bundle = CFBundleGetBundleWithIdentifier( CFSTR("com.audiounit.CV") );
This needs to reflect the bundle identifier (typically your Company Identifier + ‘.audiounit.’ + projectname) of your target. For me it is
com.squishycat.audiounit.CV . This is typically set when you create the project and specify the name. So, change that line to something like…
CFBundleRef bundle = CFBundleGetBundleWithIdentifier( CFSTR("com.yourcompany.audiounit.CV") );
Add the line:
Be sure to put a carriage return at the end of the line to avoid syntax warnings.
You need to add a set of properties that used to belong in CV.r. Basically, you just add these just before the last
</dict> tag. Obviously, put your own company and text in where you see SquishyCat, etc. Take a look at TechNote TN2276 for more information on this change.
<key>AudioComponents</key> <array> <dict> <key>description</key> <string>SquishyCat Cocoa View</string> <key>factoryFunction</key> <string>CVFactory</string> <key>manufacturer</key> <string>SquishyCat</string> <key>name</key> <string>SquishyCat: Cocoa View Test</string> <key>subtype</key> <string>Pass</string> <key>type</key> <string>aufx</string> <key>version</key> <string>65536</string> </dict> </array>
Modify the CV_COMP_MANF to your 4-digit company code (Get that from Apple)
Modify the CV_COMP_SUBTYPE to something more appropriate for you AU (See Apple Documentation on Component Subtypes)
Finally, Build That Sucker!!!
HOLD ON!!! HOLD ON!!! Before slamming those fingers down on Command-B, make sure that your Scheme is set to compile your Component, not just the View bundle. For some reason, every time I set one of these up, Xcode defaults to wanting to build the ViewFactory rather than the Actual component. Since the component is set to have a dependency on the View, it’ll force the view to be built automagically.
Once you do that, see if you can’t successfully build the project. Once it’s built, move the component (just the component, you don’t need to manually move the View bundle) to either
~/Library/Audio/Plug-ins/Components, then start up AULab and see if your new component with Cocoa View shows up.