Let’s Make an AUv3 (Audio Unit) MIDI Extension – Part 2: C++

auv3-midi1

This is the 3rd installment of the (AUv3) Audio Units MIDI Extension tutorial.

Introduction

AUv3 C++
If you have looked at any iOS or macOS Audio Unit code on the net you have probably seen .mm and .hpp files. What’s up with that?

Apple is still saying that Swift is the language of the future and that it outperforms those languages used by geezers. The sad truth is that Swift will be the language of the future – in the future – now. It simply will not work well for audio rendering. Nor with ABI instability work well as plugins. (What if the host uses a different version from the plugin?).

Actually, Objective-C is not good for audio rendering either. Due to the way message sending works, there is overhead that could lead to blocking. You don’t want blocking in an audio thread – especially if you’re wearing headphones and the volume is cranked up. Ok, maybe some maniacs do. I’ll ignore them.

So, what’s left? Well, there is C. C works. A better option is C++, because, well, it’s ++. You may be put off by it – in my case, I had been using it for 9 years and was actually teaching C++ at AT&T when Sun came in to demo Java in 1995. I left C++ for Java at that time, so I know what the irritations are. But C++ has come a long way and it really is a robust language. And in our case, it’s the right tool to use right now. Maybe not in the future, but we are living right now and not in the future.

Using C++

When you want to create C++ via XCode, maybe you want to create a .cpp file and a .h file like the books say. You can certainly do that. If you look at the v2 audio unit examples from Apple, that’s what you will see. Here’s is an example from AudioKit’s core classes.

But the context we’re in right now is creating an AUv3 audio unit. The XCode template code for your audio unit is in Objective-C. You’re going to want to call your C++ code from this Objective-C code. So how do you do that?

First, rename your audio unit .m file to use a .mm extension. If you look at the inspector panel, it says the type is now Objective-C++. That’s not a new language, it just means you will be able to call C++ code from it. You’ve probably seen .mm files in audio code on the net. For example, here is AudioKit’s FM Oscillator Bank.

Now for the C++ code. Where does that go? The convention here is to create a .hpp file. So, go ahead and create one. The only thing that the XCode template will generate are a few directives. You’ll have to create the actual class.

An hpp file is a bit like Java or Swift where the interface and implementation are together. If you prefer the old school style of putting the interface in the .h/.hpp file and the implementation in the .cpp/.mm file, you can.

Here is a simple example: IntervalPlugin.hpp

Then in your Objective-C file, you include this header file along with the other headers that you need.
In the implementation, define an instance variable of your C++ class type. You don’t want it to be an Objective-C property which would be copied on access.

Then later, you can create an instance of your C++ using the C++ keyword new.

Then, capture this instance variable in your render block accessor.

The audio unit’s AUHostMusicalContextBlock is one of the blocks handed to the audio unit by the host. We capture that too so we can use it in the render block to see what the current tempo is among other timing data. In this example, I pass the tempo to the C++ plugin. In the next blog post on audio units, I’ll talk more about timing.

Now that we can call C++ from our render block, we can put that MIDI processing stuff from the previous example into the C++ plugin. Something like this.

Then, over in C++ land,

Of course, the outputEventBlock was handed to the C++ object by the audio unit Objective-C class. The alloc render resources method is a good place to do that.

Neat. Swift, Objective-C, and C++ in one project.

Summary

Using C++ in an audio project for iOS or macOS is encouraged. It’s not especially difficult to set up, but there are a few tricks that we have just seen.

Resources

There is a separate target in the Github project named AUParamsPlugin which has the C++ version. The AUParams target is from the last blog post and has no C++

GITHUB REPO

Previous posts in this series:

Related Posts

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.