|
-
- The Juce Polymorphic Plugin Project!
- ====================================
-
- (c) 2015 by ROLI, visit www.juce.com for more info.
-
- -----------------------------------------------------------------------------------------------------
-
- The purpose of this framework is to make is simple to write an audio plugin in a generic
- way, which can then be compiled as a VST, AudioUnit, RTAS, or any combination of these.
-
- It's "polymorphic" because the output is a single binary module that acts as all of the
- different plugin formats at the same time. This means that you only need to maintain one
- project, and only need to perform one build to create a multi-format plugin.
-
- Also included are some helper classes that make it easy to create a stand-alone app to
- run your plugin without a host. This might be useful in its own right, but can also be very
- handy when developing your plugin, because you can build, test and debug it without needing
- to keep restarting a 3rd-party host.
-
- How does it work?
- =================
-
- To create your plugin, you just create a subclass of the AudioPluginInstance class to
- perform the processing. And your plugin UI is written like any normal Juce UI component.
-
- All the platform-specific code is hidden away in wrapper classes that you just add to
- your project - you should (hopefully) never need to even see the inner workings of these.
-
-
- Licensing issues
- ================
-
- Juce is released under the GPL (Gnu Public License) - this means that you're free to use
- and redistribute it as long as your products are also released under the GPL. Basically
- this means that if you use it, you also have to give away your source code.
- If you want to release a closed-source application, you can buy a commercial license
- that lets you avoid this restriction - see http://www.juce.com for more info,
- or see the comments at the top of all the Juce source files.
-
- If you're building the VST projects or releasing a VST, you'll need have a look at Steinberg's
- developer site to see what licensing rules apply these days. Their website's at
- http://www.steinberg.net
-
- If you're building an RTAS then you'll need to sign Digidesign's developer license to get
- their SDK. Visit http://www.digidesign.com for more info.
-
-
-
- Getting Started
- ===============
-
- The best advice for creating a plugin is to USE THE INTROJUCER! This will auto-generate a
- cross-platform project for you with all the correct settings, and some framework classes to
- get you started.
-
- If you choose to go it alone and not use the introjucer, then you'll have a lot of painful
- project set-up to do, and will need to scour this document and the juce forum for the details.
-
- There's a demo plugin in the juce/extras folder - this contains an example plugin which can
- be built in all the different formats.
-
- Have a look at the demo classes to see how it works, and then to create a real plugin,
- you'll need to replace the demo files with your own code.
-
- I've tried to add helpful comments where you might run across common compile errors, to
- help describe what you might be doing wrong, as getting a build set-up for some of these
- formats can be a bit of a pain. Please let me know if you find there's anything missing
- from these instructions or anything I could change to help smooth the build process along
- a bit.
-
-
- -----------------------------------------------------------------------------------------------------
-
- Prerequisites for building a VST
- ================================
-
- - Visit http://www.steinberg.net and jump through whatever hoops are necessary to download
- and install the VST SDK.
-
- -----------------------------------------------------------------------------------------------------
-
- Prerequisites for building an RTAS
- ==================================
-
- - Contact Digidesign, ask to become a Digidesign Development Partner, sign the relevent
- agreements and NDAs.
- - From the Digidesign website, download their latest Plug-In SDK
- - Install the SDK and build some of the demo plugins to make sure it all works.
- - In Visual Studio: Using the Digidesign demo projects in the SDK, make sure you've compiled
- debug and release versions of the following static libraries:
- DAE.lib, DigiExt.lib, DSI.lib, PlugInLib.lib.
- - In XCode: After installing the Digidesign SDK, make sure you've run the config_SDK_for_Mac
- command in the SDK's root directory. This sets up some of the tools that it needs.
-
-
- -----------------------------------------------------------------------------------------------------
-
- Choosing the formats to build
- =============================
-
- Each plugin project needs to contain an AppConfig.h file, which holds all the plugin-specific build details.
- (The introjucer will auto-generate this file for you when you create a project). In here, there are three macros
- that you can set to enable each of the available formats:
-
- #define JucePlugin_Build_VST 1
- #define JucePlugin_Build_RTAS 1
- #define JucePlugin_Build_AU 1
-
- The introjucer contains options in its config panel that let you set these values automatically without
- needing to manually change any files.
-
-
- -----------------------------------------------------------------------------------------------------
-
- Manually Creating a PC VST/RTAS plugin in Visual Studio
- =======================================================
-
-
- NOTE! That the following tips are provided only for the case where you're not using the introjucer..
- If you're sensible, you'll let the introjucer do all the heavy lifting, and won't need to read this.
-
-
- - First try loading the VST demo project in JuceAudioPlugin/demo/build. Hopefully this
- should build correctly.
- - Create a new, empty, win32 project using Visual Studio. Choose "DLL" as the type of
- product to build
- - If building an RTAS, add to your project all the juce_RTAS_*.cpp files from the wrapper/RTAS folder.
- - If building a VST, add to your project all the juce_VST_*.cpp files from the wrapper/VST folder.
-
- - Create yourself a JucePluginCharacteristics.h file, starting with a copy of the one in the
- demo project. Go through each item inside it carefully, and set them to the appropriate value
- for your plugin.
-
- - Under "Additional Include Directories", add the folder in which you're going to put
- your JucePluginCharacteristics.h file.
-
- - If you're doing an RTAS, change these project settings (these can all be ignored if you're only doing a VST):
- - Make sure all of these are on your include path:
- c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\EffectClasses
- c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ProcessClasses
- c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ProcessClasses\Interfaces
- c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Utilities
- c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\RTASP_Adapt
- c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\CoreClasses
- c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Controls
- c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Meters
- c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ViewClasses
- c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\DSPClasses
- c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Interfaces
- c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\common
- c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\common\Platform
- c:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugins\SignalProcessing\Public
- C:\yourdirectory\PT_80_SDK\AlturaPorts\TDMPlugIns\DSPManager\Interfaces
- c:\yourdirectory\PT_80_SDK\AlturaPorts\SADriver\Interfaces
- c:\yourdirectory\PT_80_SDK\AlturaPorts\DigiPublic\Interfaces
- c:\yourdirectory\PT_80_SDK\AlturaPorts\Fic\Interfaces\DAEClient
- c:\yourdirectory\PT_80_SDK\AlturaPorts\NewFileLibs\Cmn
- c:\yourdirectory\PT_80_SDK\AlturaPorts\NewFileLibs\DOA
- c:\yourdirectory\PT_80_SDK\AlturaPorts\AlturaSource\PPC_H
- c:\yourdirectory\PT_80_SDK\AlturaPorts\AlturaSource\AppSupport
- c:\yourdirectory\PT_80_SDK\AvidCode\AVX2sdk\AVX\avx2\avx2sdk\inc
- C:\yourdirectory\PT_80_SDK\xplat\AVX\avx2\avx2sdk\inc
- - Set "C++/Code Generation/Runtime Library" to be "Multi-threaded DLL" or "Multi-threaded Debug DLL"
- - Set the "Linker/Input/Module Definition file" to point to "wrapper/RTAS/juce_RTAS_WinExports.def"
- - Under "Linker/Input/Delay loaded DLLs", add the following:
- "DAE.dll; DigiExt.dll; DSI.dll; PluginLib.dll; DSPManager.dll"
- - You may (or may not) need to add "libcmtd.lib; libcmt.lib" to the "Linker/Input/Ignore Specific Library" setting.
- - For ONLY the following files:
- juce_RTAS_Wrapper.cpp, juce_RTAS_DigiCode1.cpp, juce_RTAS_DigiCode2.cpp, juce_RTAS_DigiCode3.cpp,
- change their "C++/Advanced/Calling Convention" property to "__stdcall". All other files should
- be left with the default calling convention of "__cdecl"
- - Set the "Linker/General/Output File" property to "$(OutDir)\$(ProjectName).dpm" (If you're building
- a polymorphic VST/RTAS, then you can simply copy or rename the finished .dpm file to a .dll, and
- it'll function as a VST)
- - Under "Custom build step", add the following command:
- copy /Y "\yourdirectory\juce\extras\audio plugins\wrapper\RTAS\juce_RTAS_WinResources.rsr" "$(TargetPath)".rsr
- The corresponding "Outputs" setting for this must be set to "$(TargetPath)".rsr
- (This will copy and rename the juce_RTAS_WinResources.rsr file to sit next to the finished .dpm file. It's
- a dummy resource file, but PT will refuse to load the plugin unless it has a corresponding .rsr file)
- - Because the RTAS code duplicates some win32 constants, you might need to force it to link correctly
- by adding "/FORCE:multiple" to the linker's additional command line options.
- - You might want to change the output directory to "\Program Files\Common Files\Digidesign\DAE\Plug-Ins\"
- if you want the built plugin to go directly into the PT plugins folder
- - When setting properties, remember to change them for both your debug and release builds!
-
- - Create your actual plugin classes and add them to the project. Obviously this is the hard bit!
-
- - Add the amalgamated juce source file to the project - have a look at the demo app for neat ways of doing this.
-
- - NOTE: on Windows, because RTAS uses the altura mac-style code, there are annoying clashes caused if
- you also include the Apple QuickTime headers, so you might need to turn off quicktime by setting the
- juce config macro: #define JUCE_QUICKTIME 0
-
- - NOTE: If you're using MSVC2005 to build your plugin, the users will need to
- have the Microsoft VC8 Runtime installed on their machines, otherwise the DLL will
- silently fail to load. You should probably add the runtime to your plugin's installer,
- and you can get a copy of it here:
- http://www.microsoft.com/downloads/details.aspx?FamilyID=32bc1bee-a3f9-4c13-9c99-220b62a191ee&DisplayLang=en
-
-
-
- -----------------------------------------------------------------------------------------------------
-
- Creating a Mac AU/VST/RTAS plugin in XCode
- ==========================================
-
- NOTE! That the following tips are provided only for the case where you're not using the introjucer..
- If you're sensible, you'll let the introjucer do all the heavy lifting, and won't need to read this.
-
- - Some of the RTAS SDK files in the demo project might be highlighted red to indicate that they're
- missing - if you're not bulding an RTAS, then you can just delete them from the project. If you are
- building an RTAS and have the SDK, you might need to update their paths to match your SDK location.
- - For an AU, there are a bunch of Apple cpp files that need to be included directly in your project - these
- used to be found in /Developer/Examples/CoreAudio/ but in the 10.6 SDK, Apple have moved them to a slightly
- more sensible location at /Developer/Extras/CoreAudio. The Juce demo is hardwired to refer to their new
- 10.6 location, so if you haven't yet installed the 10.6 SDK, the easiest way to make it all happy is just
- to duplicate your /Developer/Examples/CoreAudio folder as /Developer/Extras/CoreAudio. That way old and new
- juce plugin projects will all compile without changing any project paths.
- - For an AU, make sure that the JucePlugin_Build_AU is enabled in your JucePluginCharacteristics.h
- - In XCode, create a new project based on the "Audio Unit Effect" template
- - XCode will create a bunch of template source files for you - you can remove all of these from the project
- and delete them
- - In the target settings, clear the "Exported Symbols File" setting. The exports are specified by directives
- within the wrapper code, so don't need to be listed explicitly.
- - All all the Apple frameworks that Juce normally requires to the "External Frameworks" list
- - Add all the juce_AU_* files from the /wrapper/AU directory to your project
- - The template project creates an AUPublic group that contains lots of AudioUnit source files. But
- it leaves out files that it thinks you might not need, e.g. if you chose an "Audio Unit Effect" project,
- then it won't add the classes for handling MIDI. So you'll probably need to go into this folder
- and check that it contains AUMIDIBase.cpp, AUMidiEffectBase.cpp, MusicDeviceBase.cpp, etc
- - As for the PC, you'll need to make sure your project contains a correctly set-up JucePluginCharacteristics.h
- file - start with a copy of the one in the demo plugin project, and go through it making sure that
- all the values make sense for your plugin.
- - The JucePluginCharacteristics.h file is included not only by the code, but also by the resources files - so it
- needs to be locatable on both your normal header search path, and also on your resource include path, which is
- the project setting called 'Rez Search Paths'
- - Because of the flat naming structure used by Objective-C, if a host loads several different plugins which
- all contain slightly different versions of the juce library, you can get nasty situations where all their obj-C
- classes are cross-linked to the similarly-named class in other modules, and everything turns into a big mess...
- To avoid this, you're advised to set a unique JUCE_ObjCExtraSuffix value (you'll find this in juce_mac_NativeCode.mm,
- or if you're using the amalgamated version, you can just set it before including juce_amalgamated.cpp). Choose a
- suffix that's unique to both the name and version of your plugin.
- - Create your actual plugin classes and add them to the project. Obviously this is the hard bit!
-
- You should now be able to build a functional AU! If you want VST support as well, then read on...
-
- - Make sure that the JucePlugin_Build_VST is enabled in your JucePluginCharacteristics.h
- - For VST support, add all the juce_VST_* files from /wrapper/VST
- - In your target info settings, add the vstsdk2_4 folder to your "Header Search Paths" list
- - Make sure that in your Info.plist, the "Bundle Name" value is correctly set to the name of your plugin.
-
- Now, if you compile, the resulting bundle should work as both a VST and AU - you can simply copy or rename it,
- changing the suffix to ".vst", and put it in your VST folder.
-
- NOTE! In order to copy and rename the plugin to the various different plugin folders, the demo plugin project
- contains a VERY useful script, which you'll almost certainly want to copy into your own projects - have
- a look in the demo target for the build phase called "Copy into the different plugin folders", and use the
- inspector to have a look at the script. It uses advanced cunningness to copy only to the correct target
- folders for the types of plugin you're targeting, and should be able to be used in your own project
- without needing to edit it.
-
- NOTE! If you use the Finder to rename your xyz.component file to xyz.vst, it might look like it's done
- exactly this... but in fact, the Finder may have secretly renamed it as "xyz.vst.component", even though
- it shows "xyz.vst" as the name on the screen. I have wasted quite a lot of time angrily wondering why my VSTs
- don't seem to work, before realising that this is what has happened. You should use the command-line to rename
- it correctly.
-
- If you also want to build an RTAS, then carry on reading...
-
-
- - Make sure that the JucePlugin_Build_RTAS is enabled in your JucePluginCharacteristics.h
- - After installing the Digidesign SDK, make sure you've run the config_SDK_for_Mac command in
- its root directory. This sets up some of the tools that it needs.
- - Add the files from /wrapper/RTAS to your project. Obviously a couple of these are for Windows, so
- you shouldn't add those
- - In the Digi SDK, in /AlturaPorts/TDMPlugins/common/mac, there are two config files:
- CommonDebugSettings.xconfig and CommonReleaseSettings.xconfig
- These contain lots of Digi hackery to get their stuff to compile, so you should add them to your project
- and change your project's settings to use these files as their base config. Even so, it's all a bit of a mess,
- and you may need to tweak them a bit to get it to work on your system.
- - In your target settings, add a custom build setting called "MacBag", and set this to the path where the
- "MacBag" folder of the Digi SDK lives.
- - Add the following to your "Header Search Paths" setting (it's easiest to copy-and-paste this setting from
- the demo project):
- "$(MacBag)/../AlturaPorts/TDMPlugIns/PlugInLibrary/**"
- "$(MacBag)/../AlturaPorts/TDMPlugIns/DSPManager/**"
- "$(MacBag)/../AlturaPorts/TDMPlugIns/SupplementalPlugInLib/Encryption"
- "$(MacBag)/../AlturaPorts/TDMPlugIns/SupplementalPlugInLib/GraphicsExtensions"
- "$(MacBag)/../AlturaPorts/TDMPlugIns/common"
- "$(MacBag)/../AlturaPorts/TDMPlugIns/common/PI_LibInterface"
- "$(MacBag)/../AlturaPorts/TDMPlugIns/PACEProtection/**"
- "$(MacBag)/../AlturaPorts/OMS/Headers"
- "$(MacBag)/../AlturaPorts/Fic/Interfaces/**"
- "$(MacBag)/../AlturaPorts/Fic/Source/SignalNets"
- "$(MacBag)/../AlturaPorts/DSIPublicInterface/PublicHeaders"
- "$(MacBag)/../DAEWin/Include"
- "$(MacBag)/../AlturaPorts/DigiPublic/Interfaces"
- "$(MacBag)/../AlturaPorts/DigiPublic"
- "$(MacBag)/../AlturaPorts/NewFileLibs/DOA"
- "$(MacBag)/../AlturaPorts/NewFileLibs/Cmn"
- "$(MacBag)/../AlturaPorts/TDMPlugIns/SignalProcessing/**"
- "$(MacBag)/../AvidCode/AVX2sdk/AVX/avx2/avx2sdk/inc"
- "$(MacBag)/../AvidCode/AVX2sdk/AVX/avx2/avx2sdk/utils"
- - If you're using the Digi files CommonDebugSettings.xcconfig and CommonReleaseSettings.xcconfig,
- then you'll probably have to remove the "-x c++" option from their OTHER_CFLAGS setting, because
- that prevents it compiling obj-C. Also, you might need to comment-out the GCC_PREFIX_HEADER setting,
- unless you can persuade precompiled headers to work (I've never managed to get them working myself..)
- You'll also probably want to add a "MacBag" setting to these files, rather than putting it into
- your project - e.g. "MacBag = /Users/jules/SDKs/PT_80_SDK/MacBag"
- - If you get include errors compiling some of the DigiDesign code, you may need to
- add "/Developer/Headers/FlatCarbon" to your header search path.
- - In the SDK, find the PluginLibrary.xcodeproj file, and add this to your "External frameworks and Libraries".
- If you've already compiled this library, you can open its item in your XCode project treeview, to find
- the "libPluginLibrary.a" item inside it. Drag this subitem down to your Target/"Link Binary With Libraries"
- build stage and drop it there to add it to the link process.
- - In your Info.plist, change the "Bundle OS Type Code" to "TDMw", and the "Bundle Creator OS Type Code" to
- "PTul".
- - You may need to remove the "OTHER_CFLAGS = -x c++" from the RTAS settings file to stop it complaining about
- obj-C code
-
- You should now be able to build an RTAS! Again, just renaming the finished bundle to ".dpm" and
- putting it in your RTAS folder should be do the trick.
-
- If you get any weird build problems, a good tip is to try comparing the demo plugin's build settings with your
- own - this should usually show up what's missing.
-
-
- Note about exported symbols:
- When XCode builds the plugin, I've had unpredictable results when trying to stop it from exporting
- all of the internal functions as public symbols. There are some flags that are supposed to turn this
- off, but sometimes they don't seem to have any effect, and using an explicit exports file also
- seems a bit hit-and-miss. (If anyone knows better and can get this working, please let me know!)
- Anyway, as well as being wasteful and showing everyone what's inside your plugin, leaving all
- the symbols in there will cause fatal crashes when used with Tracktion, or alongside any other
- Juce-based plugins. A way of making sure your plugin is stripped is to use the command
- "strip -x -S YourPlugin.vst/Contents/MacOS/YourPlugin" after bulding it, which removes the
- unnecessary symbols (although in my experience this also doesn't seem to work all the time,
- so it's a good idea to check it using the unix "nm" command).
|