- clean working copy for leaving SVN
This commit is contained in:
@@ -0,0 +1,339 @@
|
||||
|
||||
The Juce Polymorphic Plugin Project!
|
||||
====================================
|
||||
|
||||
(c) 2012 by Raw Material Software, visit www.rawmaterialsoftware.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.rawmaterialsoftware.com/juce 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).
|
||||
Reference in New Issue
Block a user