Tuesday, April 22, 2014

Create an NSArray from Properties of the Items in NSArray

It is possible to create a new NSArray from properties of an NSArray of objects by the following command.

NSArray *licensePlates = [myCars valueForKeyPath:@"licensePlate"]
This is useful when we are only interested in a particular property of a class.
(Source: stackoverflow)

Monday, April 7, 2014

Setting Up an AudioUnit Audio Effects Project with JUCE for Ableton Live 9 (32-bit)

JUCE is a multi-platform C++ framework that amongst many things can be used to develop audio plugins, including VST, AudioUnits, RTAS (Digidesign) and AAX. My goto DAW being Ableton Live, I will focus on how to get started with JUCE for AU plugins to use with Ableton Live. In this post I will go over how to setup a project with JUCE and get it compiled with Xcode. For this post, I am using Xcode 5.1 on OSX 10.9.2.

Unlike VSTs or other audio plugin formats, as a Mac user, it is possible obtain code for AudioUnits without jumping through hoops, which is why I will focus on developing AudioUnits with JUCE. Developing for VSTs should not be much different except for the need to download the VST SDK from Steinberg.

Step 0. Download Xcode with OSX SDK

Download Xcode from the Apple App Store. This may take quite a while.

Step 1. Download JUCE from Github

Download JUCE here.

Step 2. Download CoreAudio Utility Classes

JUCE uses a few utility classes that do not come with the CoreAudio framework in the OSX SDK. These classes can be found here. Click on the "Download Sample Code" button.
Once downloaded and unzipped, copy the CoreAudio folder to /Applications/Xcode.app/Contents/Developer/Extras. You will need to create the Extra folder.   This is the default directory that JUCE searches for the CoreAudio Utility classes.
I have yet to figure out how to make JUCE search for a more reasonable folder. Note: yes we are adding files to the Xcode app bundle, which is not a good idea since anytime you upgrade Xcode you will have to copy the files again. Hopefully this will be addressed in future JUCE releases.

Step 3. Compile and Run Introjucer

The quick and easy way to setup a JUCE project is by Introjucer. You can find the source code for Introjucer under extras in the JUCE source code. Compile Introjucer by choosing the platform of interest under Builds. Since we are focusing on OSX, lets open Builds/MacOSX/The Introjucer.xcodeproj. This will open Xcode. Compile and run the project. It might be a good idea to archive the project as an app bundle, if you are going to develop many audio plugins with JUCE.

Step 4. Setup an Xcode Project with Introjucer


Run Introjucer

Figure 1. Introjucer with no Jucer project.
You should see Introjucer with no project like Figure 1.
From the menu choose "File > New Project" or press cmd+N.

Create Project

Figure 2. Creating a Jucer project.

Name your project. I'm calling mine STTR. For project type, choose "Audio Plug-In". And choose the folder you want the files to be in. Add the folder name below the folder tree to create a new folder. (If not it will create the files in the current folder.) When you press "Create...",  Introjucer will ask you for the "JUCE modules" folder. You can find the folder aptly named modules in the folder downloaded from Step 1.

Setup Project


Figure 3. Setting up a Jucer project.

Introjucer has now created an introjucer project. (In the project folder you will find a .jucer file along with source code folders.) We now need to setup the project. For our case, we need to set the following,
  • the company name
  • the output plugin formats
For Ableton Live users, the company name matters because Live organizes AudioUnits by the company name. Let's uncheck "Build VST" for now. (It is selected by default.) That will be enough for this post. However, I recommend scrolling down the list and skimming over the other options especially those starting with "Plugin". We are now ready to open Xcode. Click on "Save Project and Open in Xcode...".

Step 5. Modify the Xcode Project for Live

Though Introjucer does most of the setup needed, there are a few steps we have to go through to make the project compile.

Choose Architecture, Base SDK

Figure 4. Xcode project settings.

As of the time of writing Ableton recommends installing the 32-bit version of Live and the 32-bit version will not load 64-bit AudioUnits. Xcode 5 on the other hand defaults to 64-bit architectures, so we need to fix this. Open the build settings by clicking on the blueprint icons (See Figure 4).  For "Architectures" choose, "32-bit Intel (i386)". For "Base SDK", choose "Latest OS X".

Fix line 263 in AUCarbonViewBase

AUCarbonViewBase can be found in "Juce Library Code > Juce AU Wrapper". Use the Project Navigator on the left (the sidebar) to find it.
You need to add the static_cast like below. Xcode will offer to fix it.

HISize originalSize = { static_cast(mBottomRight.h), static_cast(mBottomRight.v) };

This code is actually one of the files from Step 2, so you will only need to fix this every time you upgrade Xcode.

Fix line 1415 in juce_OpenGLGraphicsContext.cpp

If you try to build now (cmd+B), you will get an error in juce_OpenGLGraphicsContext.cpp. The file is in "Juce Modules > juce_opengl > opengl" .Removing fontHeight should fix the problem.

const ScopedPointer et (font.getTypeface()->getEdgeTableForGlyph (glyphNumber, t, fontHeight));

(Caveat: I am not aware of the consequences of this workaround. I have not experienced any problems.)

Step 6. Write Code

For a quick example, let's create a ring modulator (which simply means multiplying the input signal with a sine wave). Before we start coding, let's look at the files we will be working in. JUCE automatically creates four C++ files when creating the project: PluginProcessor.h/.cpp and PluginEditor.h/.cpp. The former contains the signal processing code, while the latter is user interface code. The actual classes are named after your project name. For my project STTR the class in PluginProcessor is SttrAudioProcessor, a subclass of AudiProcessor.
The function to access the audio buffer is void SttrAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages). It uses one audio buffer for input and output, which means you read the buffer data from buffer for the input signal, then write the output sample to the same object.
The function is populated with some useful starter code. Replace it with the code below.

void SttrAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages)
{
    static double phase = 0;

    // This is the place where you'd normally do the guts of your plugin's
    // audio processing...
    for (int channel = 0; channel < getNumInputChannels(); ++channel)
    {
        float* channelData = buffer.getSampleData (channel);

        // ..do something to the data...
        for (int n = 0; n < buffer.getNumSamples(); n++) {
            
            if (channel == 0) { // increment phase once per sample
                
                phase += M_PI*2*880/getSampleRate(); // modulate by 880 Hz
                
                if (phase > 2*M_PI)
                    phase -= 2*M_PI;
            }
            
            channelData[n] *= sin(phase);
        }
    }

    // In case we have more outputs than inputs, we'll clear any output
    // channels that didn't contain input data, (because these aren't
    // guaranteed to be empty - they may contain garbage).
    for (int i = getNumInputChannels(); i < getNumOutputChannels(); ++i)
    {
        buffer.clear (i, 0, buffer.getNumSamples());
    }
}

Step 7. Compile the project

Compile the project by pressing cmd + B. You should find the compiled .component file in [YourProject Folder]/Builds/MacOSX/build/Debug.

Step 8. Install the .component plugin

Now we have an AudioUnit plugin. While some DAWs allow the user to put the plugin in your own custom folder, Ableton Live expects the AudioUnit plugin to be in a predefined location. In OSX Mavericks (10.9.2), that location is /Library/Audio/Plug-Ins/Components. Copy the .component file into /Library/Audio/Plug-Ins/Components. Since it's a system folder you will need administrator level access (i.e. be able to run sudo).
Now you should be able to see your plugin in Ableton Live under "Plug-ins".

What next?

For a complete synthesizer example, you can find one in "extras/audio plugin demo" in the JUCE repository. It is worth looking at the JUCE API Documentation. There are a lot of classes that implement commonly used functions, so I suggest taking a look before implementing your own.

While preparing my own project and writing this post, I found this post helpful. http://feature-space.com/en/post161.html