diff --git a/extras/audio plugins/How to use this framework.txt b/extras/audio plugins/How to use this framework.txt new file mode 100644 index 0000000000..9cde1475a6 --- /dev/null +++ b/extras/audio plugins/How to use this framework.txt @@ -0,0 +1,272 @@ + + The Juce Audio Plugin project! + ============================== + +(c) 2005-6 by Raw Material Software, visit www.rawmaterialsoftware.com for more info. + +The idea behind this is to create a framework which lets you write a platform-independent +audio plugin using Juce, which can be easily rebuilt to target multiple different plugin +formats and platforms. + + +How does it work? +================= + +There's a generic audio plugin base class defined in juce_AudioFilterBase.h, and to write +your plugin, you just need to create a sub-class of this. + +You can then compile your class against one or more of the platform-specific projects, +so that it gets wrapped as a VST, AudioUnit, RTAS, etc. - hopefully without changing any +of your code at all, or having to go anywhere near any platform-specific stuff. + + +How do I use it? +================ + +Under the 'wrapper/formats' directory are a bunch of different sets of files containing the +wrapper code for each different plugin type. + +There is also a 'demo' folder - this shows an example plugin which can be built in all +the different formats. The demo folder contains: + +- a 'src' directory containing the common, platform-independent code that defines this + plugin's behaviour +- a 'build' directory which contains projects for building the demo for each different + platform and format. + +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. + +I'd recommend NOT putting your own plugin code inside the JuceAudioPlugin directory - it's +much neater to keep it somewhere separate and to alter the projects to point to your +files instead of the demo ones. That way when new versions of this library come out, it'll +make it easier to update to the latest code. + +For details about how to create your own projects for the various formats, see below. + + +Sending feedback: +================= + +- if you spot a bug or some kind of host incompatibility, tell me, of course! + +- the plan is that no-one should need to change any of the platform-specific code, or the base-class + code.. So if you find that your plugin can't do something you want it to, then rather than just + jumping in and hacking things to get the functionality you need, why not contact me and we'll + figure out a nice generic way of doing it. That way it'll benefit all the users, and you won't + have to hack it all over again when the next version comes out. + +- if you're really determined to rewrite large chunks of my code and send it to me to look at, + *please* don't reformat anything in your own preferred style, or change the format of the + comments, etc.. It's bad enough looking at people's code and trying to figure out why they've + done something, but if everything's moved around I can't even diff it.. + + +What are the 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. + + +----------------------------------------------------------------------------------------------------- + + How to create your own VST project + ================================== + +- Visit http://www.steinberg.net and jump through whatever hoops are necessary to download + and install the VST SDK. +- Make sure your include path contains an entry for the "vstsdk2.4" folder containing + the SDK. +- First try loading the VST demo project in JuceAudioPlugin/demo/build. Hopefully this + should build correctly. +- To create your own project for a VST, the simplest way is to take a copy of + the demo project and go through it carefully, changing any relevent settings to reflect + your own project. + +N.B. On the Mac, there's an important point to 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). + + +----------------------------------------------------------------------------------------------------- + + How to create your own AudioUnit project + ======================================== + +- If you've got XCode installed, the demo project in JuceAudioPlugin/demo/build/AudioUnit + should just build. You may need to tweak a few paths to make sure it can find the + juce.h include file and juce library. +- When copying this project to make your own, a good plan is to open up a view of the settings + for the project and target, viewing the "customised settings" to see those values that + have to be deliberately set for the plugin to work. + +N.B. For the Mac there can be an issue with exported symbols - see the note about this for + VSTs, as the same solution can be used for AudioUnits. + + +----------------------------------------------------------------------------------------------------- + + How to create your own RTAS project + =================================== + + +RTAS is a bit more of a pain to build than VSTs or AUs. To begin with: + +- 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. + +Compiling the juce demo RTAS on the PC: +======================================= + +- Using the Digidesign demo projects in the SDK, make sure you've built debug and release + versions of these static libraries: DAE.lib, DigiExt.lib, DSI.lib, PlugInLib.lib. + +- In Visual Studio, add all of this lot to your include path: + + c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\EffectClasses + c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ProcessClasses + c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ProcessClasses\Interfaces + c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Utilities + c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\RTASP_Adapt + c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\CoreClasses + c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Controls + c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Meters + c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ViewClasses + c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\DSPClasses + c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Interfaces + c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\common + c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\common\Platform + c:\yourdirectory\PT_73_SDK\AlturaPorts\TDMPlugins\SignalProcessing\Public + c:\yourdirectory\PT_73_SDK\AlturaPorts\SADriver\Interfaces + c:\yourdirectory\PT_73_SDK\AlturaPorts\DigiPublic\Interfaces + c:\yourdirectory\PT_73_SDK\AlturaPorts\Fic\Interfaces\DAEClient + c:\yourdirectory\PT_73_SDK\AlturaPorts\NewFileLibs\Cmn + c:\yourdirectory\PT_73_SDK\AlturaPorts\NewFileLibs\DOA + c:\yourdirectory\PT_73_SDK\AlturaPorts\AlturaSource\PPC_H + c:\yourdirectory\PT_73_SDK\AlturaPorts\AlturaSource\AppSupport + c:\yourdirectory\PT_73_SDK\AvidCode\AVX2sdk\AVX\avx2\avx2sdk\inc + +- The Visual Studio juce_RTAS project contains a folder called "libs", with "debug" and + "release" subdirectories - these should contain links to the Digidesign lib files + DAE.lib, DigiExt.lib, DSI.lib, PlugInLib.lib - you'll need to update these links to + point to the correct locations according to where you've installed the SDK. + +- Fingers crossed, this should now compile.. + +- IMPORTANT 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 project for your own RTAS on the PC: +================================================= + +- start a new empty project in Developer Studio, as a "Windows DLL" +- in the source tree, create the same folders and add to them the same list of + cpp files that are in the demo project's "wrapper code" folder. +- select all the CPP files in the "wrapper code/RTAS specific" folder, and also + the juce_RTASWrapper.cpp file, (but NOT the juce_RTASUtilities.cpp file or any + other files!), and in their properties dialog, under C++/Advanced, change their + "Calling convention" setting to "__stdcall". + Remember to do this for both your debug and release builds! +- in your project's C++/General settings, add an additional include path so that + it will be able find your JucePluginCharacteristics.h file. +- Under "linker settings", change the output file name to have the suffix ".dpm" + instead of ".dll" +- Under "linker settings/input/ignore specific library", you'll probably need to + add "libcmtd.lib" for debug, and "libcmt.lib" for release. +- Under "linkey settings", set the Module definition file to be + JuceAudioPlugin/wrapper/formats/RTAS/juce_RTAS_dlldefs.def +- 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 +- Add a custom build step to copy the dummy resource file "JuceAudioPlugin\wrapper\formats\RTAS\DefaultResourceFile" + to your target directory, renaming to to be the same as your .dpm file, but with + ".rsr" on the end of the name. The demo project does this with the command + "copy /Y ..\..\..\wrapper\formats\RTAS\DefaultResourceFile "$(TargetPath)".rsr" +- Under the "general" properties, make sure that the character set is not unicode, as + this seems to stop some of the Digi code building. Hopefully this will be fixed + in future SDK releases +- add a "libs" folder to your project, and copy the set of libraries from the + equivalent folder in the demo project. Make sure you enable the debug/release + versions of these libraries appropriately. + +There are quite a few things that you need to get right for an RTAS to compile correctly - +the Digi SDK documentation has a full list of tips on setting up a project, but the +main ones to note are: + +- the SDK uses __stdcall as its calling convention, but JUCE uses __cdecl. I've got + around this by leaving the project's default setting as __cdecl, but changing it + specifically for those files that include or build files from the SDK - i.e. for + most of the files in the "wrapper code/RTAS specific" folder of the demo project. +- the default struct alignment for the SDK is 2 bytes, wheras the default as used in + juce is 8 bytes. Again, I've left this at the default setting, and have explicitly + changed it with pragmas when including/building SDK files. +- even though it's not used, each xx.dpm file needs to have a corresponding + xx.dpm.rsr file next to it, or PT will refuse to load it. The demo project currently + does this by using a custom build step to copy and rename a small dummy rsr file called + JuceAudioPlugin/wrapper/formats/RTAS/DefaultResourceFile + + +Compiling the juce demo RTAS on the Mac: +======================================== + +- 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. +- Load the juce_RTASDemo.xcodeproject and look through the project in XCode to find + all the broken links to Digidesign files. You'll need to repair these to make them + point to the location of the SDK files on your machine. +- Open the project's settings, and look for the "MacBag" setting - this defines the location + of the MacBag folder in the Digidesign SDK. You'll need to update this to point to + its location on your machine. +- It should all compile now, fingers crossed.. + +- Building a universal binary on the Mac: for this, you'll need to recompile the Digidesign + PluginLibrary project as a universal binary. The easiest way to do this is to add the + following lines to the top of the CommonDebugSettings.xcconfig and CommonReleaseSettings.xcconfig + files (these are found deep in the PT SDK tree somewhere, and are used for config by both the + Digi projects and the juce plugin projects): + ARCHS = ppc i386 + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk + MACOSX_DEPLOYMENT_TARGET_ppc = 10.3 + + +Creating a new project for your own RTAS plugin on the Mac: +=========================================================== + +It's probably easiest to take a copy of the juce demo project and go through it changing +its settings to those of your plugin. + +If you decide to start from scratch, use the juce demo project as a reference to see +what needs to go in there. Looking at its project info for "customised settings" is a good +way to see what values have been set deliberately. + diff --git a/extras/audio plugins/demo/build/AudioUnit/Info-JuceAU.plist b/extras/audio plugins/demo/build/AudioUnit/Info-JuceAU.plist new file mode 100644 index 0000000000..e26db49912 --- /dev/null +++ b/extras/audio plugins/demo/build/AudioUnit/Info-JuceAU.plist @@ -0,0 +1,28 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + + CFBundleGetInfoString + + CFBundleIconFile + + CFBundleIdentifier + com.rawmaterialsoftware.JuceAUDemo + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + Juce Audio Unit Demo + CFBundlePackageType + BNDL + CFBundleShortVersionString + + CFBundleSignature + ???? + CFBundleVersion + 1.0.0 + + diff --git a/extras/audio plugins/demo/build/AudioUnit/JuceAU.exp b/extras/audio plugins/demo/build/AudioUnit/JuceAU.exp new file mode 100644 index 0000000000..60e62a5185 --- /dev/null +++ b/extras/audio plugins/demo/build/AudioUnit/JuceAU.exp @@ -0,0 +1,9 @@ +# +# This file must contain entries for the two AU entry points. +# +# Your JucePluginCharacteristics.h file must define the prefix used for these function names - for +# more info, see the comments in JucePluginCharacteristics.h +# + +_JuceDemoAUEntry +_JuceDemoAUViewEntry diff --git a/extras/audio plugins/demo/build/AudioUnit/JuceDemoAU.xcodeproj/project.pbxproj b/extras/audio plugins/demo/build/AudioUnit/JuceDemoAU.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..4e8417291e --- /dev/null +++ b/extras/audio plugins/demo/build/AudioUnit/JuceDemoAU.xcodeproj/project.pbxproj @@ -0,0 +1,609 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 42; + objects = { + +/* Begin PBXBuildFile section */ + 3E8BF105079CA60300021B09 /* AUBase.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D199ED03175E1E01CA2136 /* AUBase.h */; }; + 3E8BF106079CA60300021B09 /* AUDispatch.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D199EF03175E1E01CA2136 /* AUDispatch.h */; }; + 3E8BF107079CA60300021B09 /* AUInputElement.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D199F103175E1E01CA2136 /* AUInputElement.h */; }; + 3E8BF108079CA60300021B09 /* AUOutputElement.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D199F303175E1E01CA2136 /* AUOutputElement.h */; }; + 3E8BF109079CA60300021B09 /* AUScopeElement.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D199F603175E1E01CA2136 /* AUScopeElement.h */; }; + 3E8BF10A079CA60300021B09 /* ComponentBase.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D199FA03175E1E01CA2136 /* ComponentBase.h */; }; + 3E8BF10B079CA60300021B09 /* AUEffectBase.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D199FF03175E1E01CA2136 /* AUEffectBase.h */; }; + 3E8BF10C079CA60300021B09 /* AUBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D19A0F03175E1E01CA2136 /* AUBuffer.h */; }; + 3E8BF10D079CA60300021B09 /* CAStreamBasicDescription.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D19A6903175E8C01CA2136 /* CAStreamBasicDescription.h */; }; + 3E8BF10E079CA60300021B09 /* CAAudioChannelLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 7967EF8C04D70E7C00C625F7 /* CAAudioChannelLayout.h */; }; + 3E8BF113079CA60300021B09 /* AUBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5D199EC03175E1E01CA2136 /* AUBase.cpp */; }; + 3E8BF114079CA60300021B09 /* AUDispatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5D199EE03175E1E01CA2136 /* AUDispatch.cpp */; }; + 3E8BF115079CA60300021B09 /* AUInputElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5D199F003175E1E01CA2136 /* AUInputElement.cpp */; }; + 3E8BF116079CA60300021B09 /* AUOutputElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5D199F203175E1E01CA2136 /* AUOutputElement.cpp */; }; + 3E8BF117079CA60300021B09 /* AUScopeElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5D199F503175E1E01CA2136 /* AUScopeElement.cpp */; }; + 3E8BF118079CA60300021B09 /* ComponentBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5D199F903175E1E01CA2136 /* ComponentBase.cpp */; }; + 3E8BF119079CA60300021B09 /* AUEffectBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5D199FE03175E1E01CA2136 /* AUEffectBase.cpp */; }; + 3E8BF11A079CA60300021B09 /* AUBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5D19A0E03175E1E01CA2136 /* AUBuffer.cpp */; }; + 3E8BF11B079CA60300021B09 /* CAAudioChannelLayout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7967EF8B04D70E7C00C625F7 /* CAAudioChannelLayout.cpp */; }; + 3E8BF11C079CA60300021B09 /* CAStreamBasicDescription.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7967EF8D04D70E7C00C625F7 /* CAStreamBasicDescription.cpp */; }; + 3E8BF11F079CA60300021B09 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F5AA9A2F0281AAB901C34293 /* CoreFoundation.framework */; }; + 3E8BF120079CA60300021B09 /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F5AA9A300281AAB901C34293 /* CoreServices.framework */; }; + 3E8BF121079CA60300021B09 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F5DA37E702821D04014500A0 /* Carbon.framework */; }; + 3E8BF122079CA60300021B09 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F5D19ABE0317606901CA2136 /* AudioUnit.framework */; }; + 844C50290C71B6E300D0082E /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 844C50280C71B6E300D0082E /* IOKit.framework */; }; + 845FAE5F0A5C0A6A008C94D8 /* juce.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 845FAE5E0A5C0A6A008C94D8 /* juce.xcconfig */; }; + 845FAEE10A5C2696008C94D8 /* QuickTime.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 845FAEE00A5C2696008C94D8 /* QuickTime.framework */; }; + 84B4CDD10C7DD23B0083122F /* MusicDeviceBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84B4CDCF0C7DD23B0083122F /* MusicDeviceBase.cpp */; }; + 84B4CDD20C7DD23B0083122F /* MusicDeviceBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 84B4CDD00C7DD23B0083122F /* MusicDeviceBase.h */; }; + 84BC4E5E0C8DDD3D00FA249B /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84BC4E5D0C8DDD3C00FA249B /* OpenGL.framework */; }; + 84CFAEFB090964560053C22C /* AUCarbonViewDispatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5D19AAB03175F3201CA2136 /* AUCarbonViewDispatch.cpp */; }; + 84CFAEFC090964560053C22C /* AUCarbonViewControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5D19AA903175F3201CA2136 /* AUCarbonViewControl.cpp */; }; + 84CFAEFD090964560053C22C /* AUCarbonViewBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5D19AA703175F3201CA2136 /* AUCarbonViewBase.cpp */; }; + 84CFAF0E090965080053C22C /* CarbonEventHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5D19AB003175F3201CA2136 /* CarbonEventHandler.cpp */; }; + 84CFAF10090965080053C22C /* CAAUParameter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EF64FA42057BC39200D99563 /* CAAUParameter.cpp */; }; + 84CFAFEB0909666C0053C22C /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3E8BF154079CA7A800021B09 /* AudioToolbox.framework */; }; + 84CFB029090968590053C22C /* DemoJuceAudioUnit.component in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3E8BF126079CA60300021B09 /* DemoJuceAudioUnit.component */; }; + 84EB400B090A4A2C008FAC1B /* juce_AudioUnitWrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84EB4009090A4A2C008FAC1B /* juce_AudioUnitWrapper.cpp */; }; + 84EB400C090A4A2C008FAC1B /* juce_AudioUnitWrapper.r in Rez */ = {isa = PBXBuildFile; fileRef = 84EB400A090A4A2C008FAC1B /* juce_AudioUnitWrapper.r */; }; + 84EB4042090A4F5A008FAC1B /* CAVectorUnit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F4E5DC280898301D00589A5A /* CAVectorUnit.cpp */; }; + 84EB404E090A5116008FAC1B /* JucePluginCharacteristics.h in Headers */ = {isa = PBXBuildFile; fileRef = 84EB404D090A5116008FAC1B /* JucePluginCharacteristics.h */; }; + 84F0521E090674BB00AEC8DB /* Info-JuceAU.plist in Resources */ = {isa = PBXBuildFile; fileRef = 84F05215090674BB00AEC8DB /* Info-JuceAU.plist */; }; + 84F0548F090687F600AEC8DB /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84F0548E090687F600AEC8DB /* CoreAudio.framework */; }; + 84F054E80906C8DD00AEC8DB /* AUMIDIBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F054E40906C8DD00AEC8DB /* AUMIDIBase.cpp */; }; + 84F054E90906C8DD00AEC8DB /* AUMIDIBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F054E50906C8DD00AEC8DB /* AUMIDIBase.h */; }; + 84F054EA0906C8DD00AEC8DB /* AUMIDIEffectBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F054E60906C8DD00AEC8DB /* AUMIDIEffectBase.cpp */; }; + 84F054EB0906C8DD00AEC8DB /* AUMIDIEffectBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F054E70906C8DD00AEC8DB /* AUMIDIEffectBase.h */; }; + 84F055010906E9EA00AEC8DB /* DemoEditorComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F054FD0906E9EA00AEC8DB /* DemoEditorComponent.cpp */; }; + 84F055020906E9EA00AEC8DB /* DemoEditorComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F054FE0906E9EA00AEC8DB /* DemoEditorComponent.h */; }; + 84F055030906E9EA00AEC8DB /* DemoJuceFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F054FF0906E9EA00AEC8DB /* DemoJuceFilter.cpp */; }; + 84F055040906E9EA00AEC8DB /* DemoJuceFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F055000906E9EA00AEC8DB /* DemoJuceFilter.h */; }; + 84F055260906FBCF00AEC8DB /* AUSilentTimeout.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F055250906FBCF00AEC8DB /* AUSilentTimeout.h */; }; + 84F87963093B1EDC00225D65 /* AGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84F87962093B1EDC00225D65 /* AGL.framework */; }; + 84FDAFE90C15B9E200CD0087 /* libjucedebug.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 84FDAFBD0C15B8F100CD0087 /* libjucedebug.a */; }; + A9E885EA0874B5BF00B2DFE8 /* CAThreadSafeList.h in Headers */ = {isa = PBXBuildFile; fileRef = A9E885E90874B5BF00B2DFE8 /* CAThreadSafeList.h */; }; + F4E5DC2C0898301D00589A5A /* CAVectorUnit.h in Headers */ = {isa = PBXBuildFile; fileRef = F4E5DC290898301D00589A5A /* CAVectorUnit.h */; }; + F4E5DC2D0898301D00589A5A /* CAVectorUnitTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = F4E5DC2A0898301D00589A5A /* CAVectorUnitTypes.h */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 84FDAFBC0C15B8F100CD0087 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 84F0545A0906865D00AEC8DB /* Juce.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = D2AAC046055464E500DB518D; + remoteInfo = Juce; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 84CFB0240909684B0053C22C /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 12; + dstPath = "$HOME/Library/Audio/Plug-Ins/Components"; + dstSubfolderSpec = 0; + files = ( + 84CFB029090968590053C22C /* DemoJuceAudioUnit.component in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 3E3AAA740670E29D00C484A8 /* AUResources.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; path = AUResources.r; sourceTree = ""; }; + 3E8BF126079CA60300021B09 /* DemoJuceAudioUnit.component */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DemoJuceAudioUnit.component; sourceTree = BUILT_PRODUCTS_DIR; }; + 3E8BF154079CA7A800021B09 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = /System/Library/Frameworks/AudioToolbox.framework; sourceTree = ""; }; + 7967EF8B04D70E7C00C625F7 /* CAAudioChannelLayout.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CAAudioChannelLayout.cpp; sourceTree = ""; }; + 7967EF8C04D70E7C00C625F7 /* CAAudioChannelLayout.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CAAudioChannelLayout.h; sourceTree = ""; }; + 7967EF8D04D70E7C00C625F7 /* CAStreamBasicDescription.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CAStreamBasicDescription.cpp; sourceTree = ""; }; + 844C50280C71B6E300D0082E /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = IOKit.framework; sourceTree = ""; }; + 845FAE5E0A5C0A6A008C94D8 /* juce.xcconfig */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xcconfig; name = juce.xcconfig; path = ../../../../../build/macosx/juce.xcconfig; sourceTree = SOURCE_ROOT; }; + 845FAEE00A5C2696008C94D8 /* QuickTime.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = QuickTime.framework; sourceTree = ""; }; + 84B4CDCF0C7DD23B0083122F /* MusicDeviceBase.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = MusicDeviceBase.cpp; path = /Developer/Examples/CoreAudio/AudioUnits/AUPublic/OtherBases/MusicDeviceBase.cpp; sourceTree = ""; }; + 84B4CDD00C7DD23B0083122F /* MusicDeviceBase.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = MusicDeviceBase.h; path = /Developer/Examples/CoreAudio/AudioUnits/AUPublic/OtherBases/MusicDeviceBase.h; sourceTree = ""; }; + 84BC4E5D0C8DDD3C00FA249B /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = /System/Library/Frameworks/OpenGL.framework; sourceTree = ""; }; + 84EB4009090A4A2C008FAC1B /* juce_AudioUnitWrapper.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_AudioUnitWrapper.cpp; path = ../../../wrapper/formats/AudioUnit/juce_AudioUnitWrapper.cpp; sourceTree = SOURCE_ROOT; }; + 84EB400A090A4A2C008FAC1B /* juce_AudioUnitWrapper.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = juce_AudioUnitWrapper.r; path = ../../../wrapper/formats/AudioUnit/juce_AudioUnitWrapper.r; sourceTree = SOURCE_ROOT; }; + 84EB404D090A5116008FAC1B /* JucePluginCharacteristics.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JucePluginCharacteristics.h; path = ../../src/JucePluginCharacteristics.h; sourceTree = SOURCE_ROOT; }; + 84F05215090674BB00AEC8DB /* Info-JuceAU.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; path = "Info-JuceAU.plist"; sourceTree = ""; }; + 84F05217090674BB00AEC8DB /* JuceAU.exp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.exports; path = JuceAU.exp; sourceTree = ""; }; + 84F0545A0906865D00AEC8DB /* Juce.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Juce.xcodeproj; path = ../../../../../build/macosx/Juce.xcodeproj; sourceTree = SOURCE_ROOT; }; + 84F0548E090687F600AEC8DB /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = /System/Library/Frameworks/CoreAudio.framework; sourceTree = ""; }; + 84F054E40906C8DD00AEC8DB /* AUMIDIBase.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AUMIDIBase.cpp; path = /Developer/Examples/CoreAudio/AudioUnits/AUPublic/OtherBases/AUMIDIBase.cpp; sourceTree = ""; }; + 84F054E50906C8DD00AEC8DB /* AUMIDIBase.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AUMIDIBase.h; path = /Developer/Examples/CoreAudio/AudioUnits/AUPublic/OtherBases/AUMIDIBase.h; sourceTree = ""; }; + 84F054E60906C8DD00AEC8DB /* AUMIDIEffectBase.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AUMIDIEffectBase.cpp; path = /Developer/Examples/CoreAudio/AudioUnits/AUPublic/OtherBases/AUMIDIEffectBase.cpp; sourceTree = ""; }; + 84F054E70906C8DD00AEC8DB /* AUMIDIEffectBase.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AUMIDIEffectBase.h; path = /Developer/Examples/CoreAudio/AudioUnits/AUPublic/OtherBases/AUMIDIEffectBase.h; sourceTree = ""; }; + 84F054FD0906E9EA00AEC8DB /* DemoEditorComponent.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DemoEditorComponent.cpp; path = ../../src/DemoEditorComponent.cpp; sourceTree = SOURCE_ROOT; }; + 84F054FE0906E9EA00AEC8DB /* DemoEditorComponent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = DemoEditorComponent.h; path = ../../src/DemoEditorComponent.h; sourceTree = SOURCE_ROOT; }; + 84F054FF0906E9EA00AEC8DB /* DemoJuceFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DemoJuceFilter.cpp; path = ../../src/DemoJuceFilter.cpp; sourceTree = SOURCE_ROOT; }; + 84F055000906E9EA00AEC8DB /* DemoJuceFilter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = DemoJuceFilter.h; path = ../../src/DemoJuceFilter.h; sourceTree = SOURCE_ROOT; }; + 84F055250906FBCF00AEC8DB /* AUSilentTimeout.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AUSilentTimeout.h; path = /Developer/Examples/CoreAudio/AudioUnits/AUPublic/Utility/AUSilentTimeout.h; sourceTree = ""; }; + 84F87962093B1EDC00225D65 /* AGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AGL.framework; path = /System/Library/Frameworks/AGL.framework; sourceTree = ""; }; + A3C2CC6105B4A4BE000F141E /* AUViewLocalizedStringKeys.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AUViewLocalizedStringKeys.h; sourceTree = ""; }; + A9E885E90874B5BF00B2DFE8 /* CAThreadSafeList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CAThreadSafeList.h; sourceTree = ""; }; + EF64FA42057BC39200D99563 /* CAAUParameter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CAAUParameter.cpp; sourceTree = ""; }; + EF64FA43057BC39200D99563 /* CAAUParameter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CAAUParameter.h; sourceTree = ""; }; + F4E5DC280898301D00589A5A /* CAVectorUnit.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CAVectorUnit.cpp; sourceTree = ""; }; + F4E5DC290898301D00589A5A /* CAVectorUnit.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CAVectorUnit.h; sourceTree = ""; }; + F4E5DC2A0898301D00589A5A /* CAVectorUnitTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CAVectorUnitTypes.h; sourceTree = ""; }; + F5AA9A2F0281AAB901C34293 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = CoreFoundation.framework; sourceTree = ""; }; + F5AA9A300281AAB901C34293 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = CoreServices.framework; sourceTree = ""; }; + F5D199EC03175E1E01CA2136 /* AUBase.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AUBase.cpp; sourceTree = ""; }; + F5D199ED03175E1E01CA2136 /* AUBase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AUBase.h; sourceTree = ""; }; + F5D199EE03175E1E01CA2136 /* AUDispatch.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AUDispatch.cpp; sourceTree = ""; }; + F5D199EF03175E1E01CA2136 /* AUDispatch.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AUDispatch.h; sourceTree = ""; }; + F5D199F003175E1E01CA2136 /* AUInputElement.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AUInputElement.cpp; sourceTree = ""; }; + F5D199F103175E1E01CA2136 /* AUInputElement.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AUInputElement.h; sourceTree = ""; }; + F5D199F203175E1E01CA2136 /* AUOutputElement.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AUOutputElement.cpp; sourceTree = ""; }; + F5D199F303175E1E01CA2136 /* AUOutputElement.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AUOutputElement.h; sourceTree = ""; }; + F5D199F503175E1E01CA2136 /* AUScopeElement.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AUScopeElement.cpp; sourceTree = ""; }; + F5D199F603175E1E01CA2136 /* AUScopeElement.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AUScopeElement.h; sourceTree = ""; }; + F5D199F903175E1E01CA2136 /* ComponentBase.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ComponentBase.cpp; sourceTree = ""; }; + F5D199FA03175E1E01CA2136 /* ComponentBase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ComponentBase.h; sourceTree = ""; }; + F5D199FE03175E1E01CA2136 /* AUEffectBase.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AUEffectBase.cpp; sourceTree = ""; }; + F5D199FF03175E1E01CA2136 /* AUEffectBase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AUEffectBase.h; sourceTree = ""; }; + F5D19A0E03175E1E01CA2136 /* AUBuffer.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AUBuffer.cpp; sourceTree = ""; }; + F5D19A0F03175E1E01CA2136 /* AUBuffer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AUBuffer.h; sourceTree = ""; }; + F5D19A6903175E8C01CA2136 /* CAStreamBasicDescription.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CAStreamBasicDescription.h; sourceTree = ""; }; + F5D19AA703175F3201CA2136 /* AUCarbonViewBase.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AUCarbonViewBase.cpp; sourceTree = ""; }; + F5D19AA803175F3201CA2136 /* AUCarbonViewBase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AUCarbonViewBase.h; sourceTree = ""; }; + F5D19AA903175F3201CA2136 /* AUCarbonViewControl.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AUCarbonViewControl.cpp; sourceTree = ""; }; + F5D19AAA03175F3201CA2136 /* AUCarbonViewControl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AUCarbonViewControl.h; sourceTree = ""; }; + F5D19AAB03175F3201CA2136 /* AUCarbonViewDispatch.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AUCarbonViewDispatch.cpp; sourceTree = ""; }; + F5D19AB003175F3201CA2136 /* CarbonEventHandler.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CarbonEventHandler.cpp; sourceTree = ""; }; + F5D19AB103175F3201CA2136 /* CarbonEventHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CarbonEventHandler.h; sourceTree = ""; }; + F5D19ABE0317606901CA2136 /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = AudioUnit.framework; sourceTree = ""; }; + F5DA37E702821D04014500A0 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Carbon.framework; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 3E8BF11E079CA60300021B09 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 84FDAFE90C15B9E200CD0087 /* libjucedebug.a in Frameworks */, + 84CFAFEB0909666C0053C22C /* AudioToolbox.framework in Frameworks */, + 3E8BF11F079CA60300021B09 /* CoreFoundation.framework in Frameworks */, + 3E8BF120079CA60300021B09 /* CoreServices.framework in Frameworks */, + 3E8BF121079CA60300021B09 /* Carbon.framework in Frameworks */, + 3E8BF122079CA60300021B09 /* AudioUnit.framework in Frameworks */, + 84F0548F090687F600AEC8DB /* CoreAudio.framework in Frameworks */, + 84F87963093B1EDC00225D65 /* AGL.framework in Frameworks */, + 845FAEE10A5C2696008C94D8 /* QuickTime.framework in Frameworks */, + 844C50290C71B6E300D0082E /* IOKit.framework in Frameworks */, + 84BC4E5E0C8DDD3D00FA249B /* OpenGL.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 84EB403B090A4ED3008FAC1B /* Juce AU Code */ = { + isa = PBXGroup; + children = ( + 84EB4009090A4A2C008FAC1B /* juce_AudioUnitWrapper.cpp */, + 84EB400A090A4A2C008FAC1B /* juce_AudioUnitWrapper.r */, + ); + name = "Juce AU Code"; + sourceTree = ""; + }; + 84F0516D09066DB800AEC8DB /* Plugin Code */ = { + isa = PBXGroup; + children = ( + 84F054FD0906E9EA00AEC8DB /* DemoEditorComponent.cpp */, + 84F054FE0906E9EA00AEC8DB /* DemoEditorComponent.h */, + 84F054FF0906E9EA00AEC8DB /* DemoJuceFilter.cpp */, + 84F055000906E9EA00AEC8DB /* DemoJuceFilter.h */, + 84EB404D090A5116008FAC1B /* JucePluginCharacteristics.h */, + 84F05215090674BB00AEC8DB /* Info-JuceAU.plist */, + 84F05217090674BB00AEC8DB /* JuceAU.exp */, + ); + name = "Plugin Code"; + sourceTree = ""; + }; + 84F0516E09066DC900AEC8DB /* Wrapper Code */ = { + isa = PBXGroup; + children = ( + 84EB403B090A4ED3008FAC1B /* Juce AU Code */, + F5AA99C50281A64501C34293 /* Apple AU Code */, + ); + name = "Wrapper Code"; + sourceTree = ""; + }; + 84FDAFB90C15B8F100CD0087 /* Products */ = { + isa = PBXGroup; + children = ( + 84FDAFBD0C15B8F100CD0087 /* libjucedebug.a */, + ); + name = Products; + sourceTree = ""; + }; + A3C2CC6005B4A4BE000F141E /* AUViewBase */ = { + isa = PBXGroup; + children = ( + A3C2CC6105B4A4BE000F141E /* AUViewLocalizedStringKeys.h */, + ); + path = AUViewBase; + sourceTree = ""; + }; + F5AA99B60281A61201C34293 = { + isa = PBXGroup; + children = ( + F5D199EA03175DB401CA2136 /* Source */, + 845FAE5E0A5C0A6A008C94D8 /* juce.xcconfig */, + F5AA99C40281A62C01C34293 /* Products */, + F5AA9E890281AAC901C34293 /* Frameworks */, + ); + sourceTree = ""; + }; + F5AA99C40281A62C01C34293 /* Products */ = { + isa = PBXGroup; + children = ( + 3E8BF126079CA60300021B09 /* DemoJuceAudioUnit.component */, + ); + name = Products; + sourceTree = ""; + }; + F5AA99C50281A64501C34293 /* Apple AU Code */ = { + isa = PBXGroup; + children = ( + F5D199EB03175E1E01CA2136 /* AUBase */, + A3C2CC6005B4A4BE000F141E /* AUViewBase */, + F5D19AA603175F3201CA2136 /* AUCarbonViewBase */, + F5D199FD03175E1E01CA2136 /* OtherBases */, + F5D19A0C03175E1E01CA2136 /* Utility */, + F5D19A3603175E8C01CA2136 /* PublicUtility */, + ); + name = "Apple AU Code"; + path = /Developer/Examples/CoreAudio/AudioUnits/AUPublic; + sourceTree = ""; + }; + F5AA9E890281AAC901C34293 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 84F0545A0906865D00AEC8DB /* Juce.xcodeproj */, + F5D19ABE0317606901CA2136 /* AudioUnit.framework */, + 3E8BF154079CA7A800021B09 /* AudioToolbox.framework */, + 84F0548E090687F600AEC8DB /* CoreAudio.framework */, + F5DA37E702821D04014500A0 /* Carbon.framework */, + F5AA9A2F0281AAB901C34293 /* CoreFoundation.framework */, + F5AA9A300281AAB901C34293 /* CoreServices.framework */, + 84F87962093B1EDC00225D65 /* AGL.framework */, + 84BC4E5D0C8DDD3C00FA249B /* OpenGL.framework */, + 844C50280C71B6E300D0082E /* IOKit.framework */, + 845FAEE00A5C2696008C94D8 /* QuickTime.framework */, + ); + name = Frameworks; + path = /System/Library/Frameworks; + sourceTree = ""; + }; + F5D199EA03175DB401CA2136 /* Source */ = { + isa = PBXGroup; + children = ( + 84F0516D09066DB800AEC8DB /* Plugin Code */, + 84F0516E09066DC900AEC8DB /* Wrapper Code */, + ); + name = Source; + sourceTree = ""; + }; + F5D199EB03175E1E01CA2136 /* AUBase */ = { + isa = PBXGroup; + children = ( + 3E3AAA740670E29D00C484A8 /* AUResources.r */, + F5D199EC03175E1E01CA2136 /* AUBase.cpp */, + F5D199ED03175E1E01CA2136 /* AUBase.h */, + F5D199EE03175E1E01CA2136 /* AUDispatch.cpp */, + F5D199EF03175E1E01CA2136 /* AUDispatch.h */, + F5D199F003175E1E01CA2136 /* AUInputElement.cpp */, + F5D199F103175E1E01CA2136 /* AUInputElement.h */, + F5D199F203175E1E01CA2136 /* AUOutputElement.cpp */, + F5D199F303175E1E01CA2136 /* AUOutputElement.h */, + F5D199F503175E1E01CA2136 /* AUScopeElement.cpp */, + F5D199F603175E1E01CA2136 /* AUScopeElement.h */, + F5D199F903175E1E01CA2136 /* ComponentBase.cpp */, + F5D199FA03175E1E01CA2136 /* ComponentBase.h */, + ); + path = AUBase; + sourceTree = ""; + }; + F5D199FD03175E1E01CA2136 /* OtherBases */ = { + isa = PBXGroup; + children = ( + 84F054E40906C8DD00AEC8DB /* AUMIDIBase.cpp */, + 84F054E50906C8DD00AEC8DB /* AUMIDIBase.h */, + 84F054E60906C8DD00AEC8DB /* AUMIDIEffectBase.cpp */, + 84F054E70906C8DD00AEC8DB /* AUMIDIEffectBase.h */, + F5D199FE03175E1E01CA2136 /* AUEffectBase.cpp */, + F5D199FF03175E1E01CA2136 /* AUEffectBase.h */, + 84B4CDCF0C7DD23B0083122F /* MusicDeviceBase.cpp */, + 84B4CDD00C7DD23B0083122F /* MusicDeviceBase.h */, + ); + path = OtherBases; + sourceTree = ""; + }; + F5D19A0C03175E1E01CA2136 /* Utility */ = { + isa = PBXGroup; + children = ( + F5D19A0E03175E1E01CA2136 /* AUBuffer.cpp */, + F5D19A0F03175E1E01CA2136 /* AUBuffer.h */, + 84F055250906FBCF00AEC8DB /* AUSilentTimeout.h */, + ); + path = Utility; + sourceTree = ""; + }; + F5D19A3603175E8C01CA2136 /* PublicUtility */ = { + isa = PBXGroup; + children = ( + F4E5DC280898301D00589A5A /* CAVectorUnit.cpp */, + F4E5DC290898301D00589A5A /* CAVectorUnit.h */, + F4E5DC2A0898301D00589A5A /* CAVectorUnitTypes.h */, + A9E885E90874B5BF00B2DFE8 /* CAThreadSafeList.h */, + 7967EF8C04D70E7C00C625F7 /* CAAudioChannelLayout.h */, + 7967EF8B04D70E7C00C625F7 /* CAAudioChannelLayout.cpp */, + F5D19A6903175E8C01CA2136 /* CAStreamBasicDescription.h */, + 7967EF8D04D70E7C00C625F7 /* CAStreamBasicDescription.cpp */, + EF64FA42057BC39200D99563 /* CAAUParameter.cpp */, + EF64FA43057BC39200D99563 /* CAAUParameter.h */, + ); + name = PublicUtility; + path = /Developer/Examples/CoreAudio/PublicUtility; + sourceTree = ""; + }; + F5D19AA603175F3201CA2136 /* AUCarbonViewBase */ = { + isa = PBXGroup; + children = ( + F5D19AA703175F3201CA2136 /* AUCarbonViewBase.cpp */, + F5D19AA803175F3201CA2136 /* AUCarbonViewBase.h */, + F5D19AA903175F3201CA2136 /* AUCarbonViewControl.cpp */, + F5D19AAA03175F3201CA2136 /* AUCarbonViewControl.h */, + F5D19AAB03175F3201CA2136 /* AUCarbonViewDispatch.cpp */, + F5D19AB003175F3201CA2136 /* CarbonEventHandler.cpp */, + F5D19AB103175F3201CA2136 /* CarbonEventHandler.h */, + ); + path = AUCarbonViewBase; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 3E8BF103079CA60300021B09 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 3E8BF105079CA60300021B09 /* AUBase.h in Headers */, + 3E8BF106079CA60300021B09 /* AUDispatch.h in Headers */, + 3E8BF107079CA60300021B09 /* AUInputElement.h in Headers */, + 3E8BF108079CA60300021B09 /* AUOutputElement.h in Headers */, + 3E8BF109079CA60300021B09 /* AUScopeElement.h in Headers */, + 3E8BF10A079CA60300021B09 /* ComponentBase.h in Headers */, + 3E8BF10B079CA60300021B09 /* AUEffectBase.h in Headers */, + 3E8BF10C079CA60300021B09 /* AUBuffer.h in Headers */, + 3E8BF10D079CA60300021B09 /* CAStreamBasicDescription.h in Headers */, + 3E8BF10E079CA60300021B09 /* CAAudioChannelLayout.h in Headers */, + A9E885EA0874B5BF00B2DFE8 /* CAThreadSafeList.h in Headers */, + F4E5DC2C0898301D00589A5A /* CAVectorUnit.h in Headers */, + F4E5DC2D0898301D00589A5A /* CAVectorUnitTypes.h in Headers */, + 84F054E90906C8DD00AEC8DB /* AUMIDIBase.h in Headers */, + 84F054EB0906C8DD00AEC8DB /* AUMIDIEffectBase.h in Headers */, + 84F055020906E9EA00AEC8DB /* DemoEditorComponent.h in Headers */, + 84F055040906E9EA00AEC8DB /* DemoJuceFilter.h in Headers */, + 84F055260906FBCF00AEC8DB /* AUSilentTimeout.h in Headers */, + 84EB404E090A5116008FAC1B /* JucePluginCharacteristics.h in Headers */, + 84B4CDD20C7DD23B0083122F /* MusicDeviceBase.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 3E8BF102079CA60300021B09 /* JuceAU */ = { + isa = PBXNativeTarget; + buildConfigurationList = A9E884AD0874ABE600B2DFE8 /* Build configuration list for PBXNativeTarget "JuceAU" */; + buildPhases = ( + 3E8BF103079CA60300021B09 /* Headers */, + 3E8BF110079CA60300021B09 /* Resources */, + 3E8BF111079CA60300021B09 /* Sources */, + 3E8BF11E079CA60300021B09 /* Frameworks */, + 3E8BF123079CA60300021B09 /* Rez */, + 84CFB0240909684B0053C22C /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = JuceAU; + productInstallPath = "$(USER_LIBRARY_DIR)/Bundles"; + productName = MultitapAU; + productReference = 3E8BF126079CA60300021B09 /* DemoJuceAudioUnit.component */; + productType = "com.apple.product-type.bundle"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + F5AA99BA0281A61201C34293 /* Project object */ = { + isa = PBXProject; + buildConfigurationList = A9E884B90874ABE600B2DFE8 /* Build configuration list for PBXProject "JuceDemoAU" */; + hasScannedForEncodings = 1; + mainGroup = F5AA99B60281A61201C34293; + productRefGroup = F5AA99C40281A62C01C34293 /* Products */; + projectDirPath = ""; + projectReferences = ( + { + ProductGroup = 84FDAFB90C15B8F100CD0087 /* Products */; + ProjectRef = 84F0545A0906865D00AEC8DB /* Juce.xcodeproj */; + }, + ); + targets = ( + 3E8BF102079CA60300021B09 /* JuceAU */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXReferenceProxy section */ + 84FDAFBD0C15B8F100CD0087 /* libjucedebug.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libjucedebug.a; + remoteRef = 84FDAFBC0C15B8F100CD0087 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + +/* Begin PBXResourcesBuildPhase section */ + 3E8BF110079CA60300021B09 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 84F0521E090674BB00AEC8DB /* Info-JuceAU.plist in Resources */, + 845FAE5F0A5C0A6A008C94D8 /* juce.xcconfig in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXRezBuildPhase section */ + 3E8BF123079CA60300021B09 /* Rez */ = { + isa = PBXRezBuildPhase; + buildActionMask = 2147483647; + files = ( + 84EB400C090A4A2C008FAC1B /* juce_AudioUnitWrapper.r in Rez */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXRezBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 3E8BF111079CA60300021B09 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3E8BF115079CA60300021B09 /* AUInputElement.cpp in Sources */, + 3E8BF116079CA60300021B09 /* AUOutputElement.cpp in Sources */, + 3E8BF117079CA60300021B09 /* AUScopeElement.cpp in Sources */, + 3E8BF113079CA60300021B09 /* AUBase.cpp in Sources */, + 3E8BF119079CA60300021B09 /* AUEffectBase.cpp in Sources */, + 3E8BF114079CA60300021B09 /* AUDispatch.cpp in Sources */, + 3E8BF11C079CA60300021B09 /* CAStreamBasicDescription.cpp in Sources */, + 3E8BF11B079CA60300021B09 /* CAAudioChannelLayout.cpp in Sources */, + 84CFAF0E090965080053C22C /* CarbonEventHandler.cpp in Sources */, + 84CFAEFB090964560053C22C /* AUCarbonViewDispatch.cpp in Sources */, + 84CFAEFC090964560053C22C /* AUCarbonViewControl.cpp in Sources */, + 84CFAEFD090964560053C22C /* AUCarbonViewBase.cpp in Sources */, + 3E8BF118079CA60300021B09 /* ComponentBase.cpp in Sources */, + 84CFAF10090965080053C22C /* CAAUParameter.cpp in Sources */, + 3E8BF11A079CA60300021B09 /* AUBuffer.cpp in Sources */, + 84F054E80906C8DD00AEC8DB /* AUMIDIBase.cpp in Sources */, + 84F054EA0906C8DD00AEC8DB /* AUMIDIEffectBase.cpp in Sources */, + 84F055010906E9EA00AEC8DB /* DemoEditorComponent.cpp in Sources */, + 84F055030906E9EA00AEC8DB /* DemoJuceFilter.cpp in Sources */, + 84EB400B090A4A2C008FAC1B /* juce_AudioUnitWrapper.cpp in Sources */, + 84EB4042090A4F5A008FAC1B /* CAVectorUnit.cpp in Sources */, + 84B4CDD10C7DD23B0083122F /* MusicDeviceBase.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + A9E884AE0874ABE600B2DFE8 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + EXPORTED_SYMBOLS_FILE = JuceAU.exp; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + GCC_USE_GCC3_PFE_SUPPORT = YES; + INFOPLIST_FILE = "Info-JuceAU.plist"; + INSTALL_PATH = "/Library/Audio/Plug-Ins/Components/"; + OTHER_REZFLAGS = "-d ppc_$ppc -d i386_$i386 -I / -I /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CarbonCore.framework/Versions/A/Headers"; + PRODUCT_NAME = "$(AU_NAME)"; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + "-Wno-non-virtual-dtor", + ); + WRAPPER_EXTENSION = component; + ZERO_LINK = NO; + }; + name = Debug; + }; + A9E884AF0874ABE600B2DFE8 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + EXPORTED_SYMBOLS_FILE = JuceAU.exp; + FRAMEWORK_SEARCH_PATHS = ""; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_OPTIMIZATION_LEVEL = 3; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + GCC_USE_GCC3_PFE_SUPPORT = YES; + INFOPLIST_FILE = "Info-JuceAU.plist"; + INSTALL_PATH = "/Library/Audio/Plug-Ins/Components/"; + OTHER_REZFLAGS = "-d ppc_$ppc -d i386_$i386 -I / -I /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CarbonCore.framework/Versions/A/Headers"; + PRODUCT_NAME = "$(AU_NAME)"; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + "-Wno-non-virtual-dtor", + ); + WRAPPER_EXTENSION = component; + ZERO_LINK = NO; + }; + name = Release; + }; + A9E884BA0874ABE600B2DFE8 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 845FAE5E0A5C0A6A008C94D8 /* juce.xcconfig */; + buildSettings = { + AU_NAME = DemoJuceAudioUnit; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + HEADER_SEARCH_PATHS = ../../../../../; + LIBRARY_SEARCH_PATHS = ../../../../../bin; + }; + name = Debug; + }; + A9E884BB0874ABE600B2DFE8 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 845FAE5E0A5C0A6A008C94D8 /* juce.xcconfig */; + buildSettings = { + AU_NAME = DemoJuceAudioUnit; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + HEADER_SEARCH_PATHS = ../../../../../; + LIBRARY_SEARCH_PATHS = ../../../../../bin; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + A9E884AD0874ABE600B2DFE8 /* Build configuration list for PBXNativeTarget "JuceAU" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A9E884AE0874ABE600B2DFE8 /* Debug */, + A9E884AF0874ABE600B2DFE8 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; + A9E884B90874ABE600B2DFE8 /* Build configuration list for PBXProject "JuceDemoAU" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A9E884BA0874ABE600B2DFE8 /* Debug */, + A9E884BB0874ABE600B2DFE8 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; +/* End XCConfigurationList section */ + }; + rootObject = F5AA99BA0281A61201C34293 /* Project object */; +} diff --git a/extras/audio plugins/demo/build/RTAS_Mac/Info.plist b/extras/audio plugins/demo/build/RTAS_Mac/Info.plist new file mode 100644 index 0000000000..fc2ac8d798 --- /dev/null +++ b/extras/audio plugins/demo/build/RTAS_Mac/Info.plist @@ -0,0 +1,32 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + EXECUTABLE_NAME + CFBundleGetInfoString + VERSION_STR + CFBundleIdentifier + com.rawmaterialsoftware.JuceDemo + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + PRODUCT_NAME + CFBundlePackageType + TDMw + CFBundleShortVersionString + VERSION_STR + CFBundleSignature + PTul + CFBundleVersion + VERSION_NUM + LSMultipleInstancesProhibited + true + LSPrefersCarbon + + NSAppleScriptEnabled + No + + diff --git a/extras/audio plugins/demo/build/RTAS_Mac/juce_RTASDemo.xcodeproj/project.pbxproj b/extras/audio plugins/demo/build/RTAS_Mac/juce_RTASDemo.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..4c1e0ddb1b --- /dev/null +++ b/extras/audio plugins/demo/build/RTAS_Mac/juce_RTASDemo.xcodeproj/project.pbxproj @@ -0,0 +1,394 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 42; + objects = { + +/* Begin PBXBuildFile section */ + 5B521CB1088F264F009C75FE /* System.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B521CB0088F264F009C75FE /* System.framework */; }; + 841E07300AF9F015005E6FCC /* DemoEditorComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 841E072B0AF9F015005E6FCC /* DemoEditorComponent.cpp */; }; + 841E07310AF9F015005E6FCC /* DemoJuceFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 841E072D0AF9F015005E6FCC /* DemoJuceFilter.cpp */; }; + 841E073D0AF9F099005E6FCC /* juce_RTASUtilities.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 841E073B0AF9F099005E6FCC /* juce_RTASUtilities.cpp */; }; + 841E073E0AF9F099005E6FCC /* juce_RTASWrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 841E073C0AF9F099005E6FCC /* juce_RTASWrapper.cpp */; }; + 846444EF0AFA005B00E7B2BE /* juce_Wrapper_CEffectGroup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 846444E20AFA005B00E7B2BE /* juce_Wrapper_CEffectGroup.cpp */; }; + 846444F00AFA005B00E7B2BE /* juce_Wrapper_CEffectGroupMIDI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 846444E30AFA005B00E7B2BE /* juce_Wrapper_CEffectGroupMIDI.cpp */; }; + 846444F10AFA005B00E7B2BE /* juce_Wrapper_CEffectMIDIUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 846444E40AFA005B00E7B2BE /* juce_Wrapper_CEffectMIDIUtils.cpp */; }; + 846444F20AFA005B00E7B2BE /* juce_Wrapper_CEffectProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 846444E50AFA005B00E7B2BE /* juce_Wrapper_CEffectProcess.cpp */; }; + 846444F30AFA005B00E7B2BE /* juce_Wrapper_CEffectProcessAS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 846444E60AFA005B00E7B2BE /* juce_Wrapper_CEffectProcessAS.cpp */; }; + 846444F40AFA005B00E7B2BE /* juce_Wrapper_CEffectProcessMIDI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 846444E70AFA005B00E7B2BE /* juce_Wrapper_CEffectProcessMIDI.cpp */; }; + 846444F50AFA005B00E7B2BE /* juce_Wrapper_CEffectType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 846444E80AFA005B00E7B2BE /* juce_Wrapper_CEffectType.cpp */; }; + 846444F60AFA005B00E7B2BE /* juce_Wrapper_CEffectTypeRTAS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 846444E90AFA005B00E7B2BE /* juce_Wrapper_CEffectTypeRTAS.cpp */; }; + 846444F70AFA005B00E7B2BE /* juce_Wrapper_ChunkDataParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 846444EA0AFA005B00E7B2BE /* juce_Wrapper_ChunkDataParser.cpp */; }; + 846444FA0AFA005B00E7B2BE /* juce_Wrapper_PlugInUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 846444EE0AFA005B00E7B2BE /* juce_Wrapper_PlugInUtils.cpp */; }; + 846445060AFA010800E7B2BE /* AGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 846445040AFA010800E7B2BE /* AGL.framework */; }; + 846445070AFA010800E7B2BE /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 846445050AFA010800E7B2BE /* CoreAudio.framework */; }; + 8464450A0AFA012100E7B2BE /* QuickTime.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 846445090AFA012100E7B2BE /* QuickTime.framework */; }; + 84BC4E9C0C8DDF6400FA249B /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84BC4E9B0C8DDF6400FA249B /* OpenGL.framework */; }; + 84C9D7FB0AFA3C9C00F1348E /* juce_Wrapper_Dispatcher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84C9D7F90AFA3C9C00F1348E /* juce_Wrapper_Dispatcher.cpp */; }; + 84C9D7FC0AFA3C9C00F1348E /* juce_Wrapper_PluginInitialize.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84C9D7FA0AFA3C9C00F1348E /* juce_Wrapper_PluginInitialize.cpp */; }; + 84EEB4180AFB6679009655FF /* DummyResourceFile.r in Rez */ = {isa = PBXBuildFile; fileRef = 84EEB4170AFB6679009655FF /* DummyResourceFile.r */; }; + 84FAD76D0C7C894B00AF3028 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84FAD76C0C7C894B00AF3028 /* IOKit.framework */; }; + 84FAD77B0C7C89E100AF3028 /* libPluginLibrary.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 84FAD7770C7C897000AF3028 /* libPluginLibrary.a */; }; + 84FDB0120C15BBCE00CD0087 /* libjucedebug.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 84FDB0100C15BBA500CD0087 /* libjucedebug.a */; }; + 8D01CCCE0486CAD60068D4B7 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 08EA7FFBFE8413EDC02AAC07 /* Carbon.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 84FAD7760C7C897000AF3028 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5B521CEB08916D36009C75FE /* PluginLibrary.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = B65B09B30860FB0800FE2E6A; + remoteInfo = "Plugin Library"; + }; + 84FDB00F0C15BBA500CD0087 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 846444D70AF9FFDB00E7B2BE /* Juce.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = D2AAC046055464E500DB518D; + remoteInfo = Juce; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 08EA7FFBFE8413EDC02AAC07 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = ""; }; + 5B521CB0088F264F009C75FE /* System.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = System.framework; path = /System/Library/Frameworks/System.framework; sourceTree = ""; }; + 5B521CEB08916D36009C75FE /* PluginLibrary.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = PluginLibrary.xcodeproj; path = /Users/jules/stuff/PT_73_SDK/AlturaPorts/TDMPlugIns/PlugInLibrary/MacBuild/PluginLibrary.xcodeproj; sourceTree = ""; }; + 841E072B0AF9F015005E6FCC /* DemoEditorComponent.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DemoEditorComponent.cpp; path = ../../src/DemoEditorComponent.cpp; sourceTree = SOURCE_ROOT; }; + 841E072C0AF9F015005E6FCC /* DemoEditorComponent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = DemoEditorComponent.h; path = ../../src/DemoEditorComponent.h; sourceTree = SOURCE_ROOT; }; + 841E072D0AF9F015005E6FCC /* DemoJuceFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DemoJuceFilter.cpp; path = ../../src/DemoJuceFilter.cpp; sourceTree = SOURCE_ROOT; }; + 841E072E0AF9F015005E6FCC /* DemoJuceFilter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = DemoJuceFilter.h; path = ../../src/DemoJuceFilter.h; sourceTree = SOURCE_ROOT; }; + 841E072F0AF9F015005E6FCC /* JucePluginCharacteristics.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JucePluginCharacteristics.h; path = ../../src/JucePluginCharacteristics.h; sourceTree = SOURCE_ROOT; }; + 841E073B0AF9F099005E6FCC /* juce_RTASUtilities.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_RTASUtilities.cpp; path = ../../../wrapper/formats/RTAS/juce_RTASUtilities.cpp; sourceTree = SOURCE_ROOT; }; + 841E073C0AF9F099005E6FCC /* juce_RTASWrapper.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_RTASWrapper.cpp; path = ../../../wrapper/formats/RTAS/juce_RTASWrapper.cpp; sourceTree = SOURCE_ROOT; }; + 841E07420AF9F126005E6FCC /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; path = Info.plist; sourceTree = ""; }; + 846444D70AF9FFDB00E7B2BE /* Juce.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Juce.xcodeproj; path = ../../../../../build/macosx/Juce.xcodeproj; sourceTree = SOURCE_ROOT; }; + 846444E20AFA005B00E7B2BE /* juce_Wrapper_CEffectGroup.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Wrapper_CEffectGroup.cpp; path = ../../../wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectGroup.cpp; sourceTree = SOURCE_ROOT; }; + 846444E30AFA005B00E7B2BE /* juce_Wrapper_CEffectGroupMIDI.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Wrapper_CEffectGroupMIDI.cpp; path = ../../../wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectGroupMIDI.cpp; sourceTree = SOURCE_ROOT; }; + 846444E40AFA005B00E7B2BE /* juce_Wrapper_CEffectMIDIUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Wrapper_CEffectMIDIUtils.cpp; path = ../../../wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectMIDIUtils.cpp; sourceTree = SOURCE_ROOT; }; + 846444E50AFA005B00E7B2BE /* juce_Wrapper_CEffectProcess.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Wrapper_CEffectProcess.cpp; path = ../../../wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectProcess.cpp; sourceTree = SOURCE_ROOT; }; + 846444E60AFA005B00E7B2BE /* juce_Wrapper_CEffectProcessAS.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Wrapper_CEffectProcessAS.cpp; path = ../../../wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectProcessAS.cpp; sourceTree = SOURCE_ROOT; }; + 846444E70AFA005B00E7B2BE /* juce_Wrapper_CEffectProcessMIDI.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Wrapper_CEffectProcessMIDI.cpp; path = ../../../wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectProcessMIDI.cpp; sourceTree = SOURCE_ROOT; }; + 846444E80AFA005B00E7B2BE /* juce_Wrapper_CEffectType.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Wrapper_CEffectType.cpp; path = ../../../wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectType.cpp; sourceTree = SOURCE_ROOT; }; + 846444E90AFA005B00E7B2BE /* juce_Wrapper_CEffectTypeRTAS.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Wrapper_CEffectTypeRTAS.cpp; path = ../../../wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectTypeRTAS.cpp; sourceTree = SOURCE_ROOT; }; + 846444EA0AFA005B00E7B2BE /* juce_Wrapper_ChunkDataParser.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Wrapper_ChunkDataParser.cpp; path = ../../../wrapper/formats/RTAS/wrappers/juce_Wrapper_ChunkDataParser.cpp; sourceTree = SOURCE_ROOT; }; + 846444ED0AFA005B00E7B2BE /* juce_Wrapper_Header.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = juce_Wrapper_Header.h; path = ../../../wrapper/formats/RTAS/wrappers/juce_Wrapper_Header.h; sourceTree = SOURCE_ROOT; }; + 846444EE0AFA005B00E7B2BE /* juce_Wrapper_PlugInUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Wrapper_PlugInUtils.cpp; path = ../../../wrapper/formats/RTAS/wrappers/juce_Wrapper_PlugInUtils.cpp; sourceTree = SOURCE_ROOT; }; + 846445040AFA010800E7B2BE /* AGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AGL.framework; path = /System/Library/Frameworks/AGL.framework; sourceTree = ""; }; + 846445050AFA010800E7B2BE /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = /System/Library/Frameworks/CoreAudio.framework; sourceTree = ""; }; + 846445090AFA012100E7B2BE /* QuickTime.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuickTime.framework; path = /System/Library/Frameworks/QuickTime.framework; sourceTree = ""; }; + 84BC4E9B0C8DDF6400FA249B /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = /System/Library/Frameworks/OpenGL.framework; sourceTree = ""; }; + 84C442690B306D39003FCBFF /* CommonReleaseSettings.xcconfig */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xcconfig; name = CommonReleaseSettings.xcconfig; path = /Users/jules/stuff/PT_73_SDK/AlturaPorts/TDMPlugIns/common/Mac/CommonReleaseSettings.xcconfig; sourceTree = ""; }; + 84C4426A0B306D39003FCBFF /* CommonDebugSettings.xcconfig */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xcconfig; name = CommonDebugSettings.xcconfig; path = /Users/jules/stuff/PT_73_SDK/AlturaPorts/TDMPlugIns/common/Mac/CommonDebugSettings.xcconfig; sourceTree = ""; }; + 84C9D7F90AFA3C9C00F1348E /* juce_Wrapper_Dispatcher.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Wrapper_Dispatcher.cpp; path = ../../../wrapper/formats/RTAS/wrappers/juce_Wrapper_Dispatcher.cpp; sourceTree = SOURCE_ROOT; }; + 84C9D7FA0AFA3C9C00F1348E /* juce_Wrapper_PluginInitialize.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Wrapper_PluginInitialize.cpp; path = ../../../wrapper/formats/RTAS/wrappers/juce_Wrapper_PluginInitialize.cpp; sourceTree = SOURCE_ROOT; }; + 84EEB4170AFB6679009655FF /* DummyResourceFile.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = DummyResourceFile.r; path = ../../../wrapper/formats/RTAS/DummyResourceFile.r; sourceTree = SOURCE_ROOT; }; + 84F5CF5F0B1B705E00A2E279 /* juce_RTASCompileFlags.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = juce_RTASCompileFlags.h; path = ../../../wrapper/formats/RTAS/juce_RTASCompileFlags.h; sourceTree = SOURCE_ROOT; }; + 84FAD76C0C7C894B00AF3028 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = ""; }; + 8D01CCD20486CAD60068D4B7 /* JuceRTASDemo.dpm */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = JuceRTASDemo.dpm; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 8D01CCCD0486CAD60068D4B7 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 84FAD77B0C7C89E100AF3028 /* libPluginLibrary.a in Frameworks */, + 84FDB0120C15BBCE00CD0087 /* libjucedebug.a in Frameworks */, + 8D01CCCE0486CAD60068D4B7 /* Carbon.framework in Frameworks */, + 5B521CB1088F264F009C75FE /* System.framework in Frameworks */, + 846445060AFA010800E7B2BE /* AGL.framework in Frameworks */, + 846445070AFA010800E7B2BE /* CoreAudio.framework in Frameworks */, + 8464450A0AFA012100E7B2BE /* QuickTime.framework in Frameworks */, + 84FAD76D0C7C894B00AF3028 /* IOKit.framework in Frameworks */, + 84BC4E9C0C8DDF6400FA249B /* OpenGL.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 089C166AFE841209C02AAC07 /* ProjectTemplate */ = { + isa = PBXGroup; + children = ( + 84C442690B306D39003FCBFF /* CommonReleaseSettings.xcconfig */, + 84C4426A0B306D39003FCBFF /* CommonDebugSettings.xcconfig */, + 08FB77ADFE841716C02AAC07 /* Source */, + 089C167CFE841241C02AAC07 /* Resources */, + 089C1671FE841209C02AAC07 /* External Frameworks and Libraries */, + 19C28FB4FE9D528D11CA2CBB /* Products */, + ); + name = ProjectTemplate; + sourceTree = ""; + }; + 089C1671FE841209C02AAC07 /* External Frameworks and Libraries */ = { + isa = PBXGroup; + children = ( + 84BC4E9B0C8DDF6400FA249B /* OpenGL.framework */, + 84FAD76C0C7C894B00AF3028 /* IOKit.framework */, + 846445040AFA010800E7B2BE /* AGL.framework */, + 846445050AFA010800E7B2BE /* CoreAudio.framework */, + 846445090AFA012100E7B2BE /* QuickTime.framework */, + 846444D70AF9FFDB00E7B2BE /* Juce.xcodeproj */, + 5B521CEB08916D36009C75FE /* PluginLibrary.xcodeproj */, + 5B521CB0088F264F009C75FE /* System.framework */, + 08EA7FFBFE8413EDC02AAC07 /* Carbon.framework */, + ); + name = "External Frameworks and Libraries"; + sourceTree = ""; + }; + 089C167CFE841241C02AAC07 /* Resources */ = { + isa = PBXGroup; + children = ( + 84EEB4170AFB6679009655FF /* DummyResourceFile.r */, + 841E07420AF9F126005E6FCC /* Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 08FB77ADFE841716C02AAC07 /* Source */ = { + isa = PBXGroup; + children = ( + 841E07270AF9EFE2005E6FCC /* filter */, + 841E072A0AF9EFEF005E6FCC /* wrapper */, + ); + name = Source; + sourceTree = ""; + }; + 19C28FB4FE9D528D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 8D01CCD20486CAD60068D4B7 /* JuceRTASDemo.dpm */, + ); + name = Products; + sourceTree = ""; + }; + 841E07270AF9EFE2005E6FCC /* filter */ = { + isa = PBXGroup; + children = ( + 841E072B0AF9F015005E6FCC /* DemoEditorComponent.cpp */, + 841E072C0AF9F015005E6FCC /* DemoEditorComponent.h */, + 841E072D0AF9F015005E6FCC /* DemoJuceFilter.cpp */, + 841E072E0AF9F015005E6FCC /* DemoJuceFilter.h */, + 841E072F0AF9F015005E6FCC /* JucePluginCharacteristics.h */, + ); + name = filter; + sourceTree = ""; + }; + 841E072A0AF9EFEF005E6FCC /* wrapper */ = { + isa = PBXGroup; + children = ( + 841E07340AF9F02D005E6FCC /* rtas specific */, + ); + name = wrapper; + sourceTree = ""; + }; + 841E07340AF9F02D005E6FCC /* rtas specific */ = { + isa = PBXGroup; + children = ( + 846444E10AFA003B00E7B2BE /* Digi code wrappers */, + 841E073B0AF9F099005E6FCC /* juce_RTASUtilities.cpp */, + 841E073C0AF9F099005E6FCC /* juce_RTASWrapper.cpp */, + 84F5CF5F0B1B705E00A2E279 /* juce_RTASCompileFlags.h */, + ); + name = "rtas specific"; + sourceTree = ""; + }; + 846444E10AFA003B00E7B2BE /* Digi code wrappers */ = { + isa = PBXGroup; + children = ( + 84C9D7F90AFA3C9C00F1348E /* juce_Wrapper_Dispatcher.cpp */, + 84C9D7FA0AFA3C9C00F1348E /* juce_Wrapper_PluginInitialize.cpp */, + 846444E20AFA005B00E7B2BE /* juce_Wrapper_CEffectGroup.cpp */, + 846444E30AFA005B00E7B2BE /* juce_Wrapper_CEffectGroupMIDI.cpp */, + 846444E40AFA005B00E7B2BE /* juce_Wrapper_CEffectMIDIUtils.cpp */, + 846444E50AFA005B00E7B2BE /* juce_Wrapper_CEffectProcess.cpp */, + 846444E60AFA005B00E7B2BE /* juce_Wrapper_CEffectProcessAS.cpp */, + 846444E70AFA005B00E7B2BE /* juce_Wrapper_CEffectProcessMIDI.cpp */, + 846444E80AFA005B00E7B2BE /* juce_Wrapper_CEffectType.cpp */, + 846444E90AFA005B00E7B2BE /* juce_Wrapper_CEffectTypeRTAS.cpp */, + 846444EA0AFA005B00E7B2BE /* juce_Wrapper_ChunkDataParser.cpp */, + 846444ED0AFA005B00E7B2BE /* juce_Wrapper_Header.h */, + 846444EE0AFA005B00E7B2BE /* juce_Wrapper_PlugInUtils.cpp */, + ); + name = "Digi code wrappers"; + sourceTree = ""; + }; + 84FAD7730C7C897000AF3028 /* Products */ = { + isa = PBXGroup; + children = ( + 84FAD7770C7C897000AF3028 /* libPluginLibrary.a */, + ); + name = Products; + sourceTree = ""; + }; + 84FDB00C0C15BBA500CD0087 /* Products */ = { + isa = PBXGroup; + children = ( + 84FDB0100C15BBA500CD0087 /* libjucedebug.a */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 8D01CCC60486CAD60068D4B7 /* JuceRTASDemo */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5B521C99088F2389009C75FE /* Build configuration list for PBXNativeTarget "JuceRTASDemo" */; + buildPhases = ( + 8D01CCCB0486CAD60068D4B7 /* Sources */, + 8D01CCCD0486CAD60068D4B7 /* Frameworks */, + 5B521D370891748B009C75FE /* Rez */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = JuceRTASDemo; + productInstallPath = "$(HOME)/Library/Bundles"; + productName = ProjectTemplate; + productReference = 8D01CCD20486CAD60068D4B7 /* JuceRTASDemo.dpm */; + productType = "com.apple.product-type.bundle"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 089C1669FE841209C02AAC07 /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 5B521C9D088F2389009C75FE /* Build configuration list for PBXProject "juce_RTASDemo" */; + hasScannedForEncodings = 1; + mainGroup = 089C166AFE841209C02AAC07 /* ProjectTemplate */; + projectDirPath = ""; + projectReferences = ( + { + ProductGroup = 84FDB00C0C15BBA500CD0087 /* Products */; + ProjectRef = 846444D70AF9FFDB00E7B2BE /* Juce.xcodeproj */; + }, + { + ProductGroup = 84FAD7730C7C897000AF3028 /* Products */; + ProjectRef = 5B521CEB08916D36009C75FE /* PluginLibrary.xcodeproj */; + }, + ); + targets = ( + 8D01CCC60486CAD60068D4B7 /* JuceRTASDemo */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXReferenceProxy section */ + 84FAD7770C7C897000AF3028 /* libPluginLibrary.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libPluginLibrary.a; + remoteRef = 84FAD7760C7C897000AF3028 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 84FDB0100C15BBA500CD0087 /* libjucedebug.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libjucedebug.a; + remoteRef = 84FDB00F0C15BBA500CD0087 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + +/* Begin PBXRezBuildPhase section */ + 5B521D370891748B009C75FE /* Rez */ = { + isa = PBXRezBuildPhase; + buildActionMask = 2147483647; + files = ( + 84EEB4180AFB6679009655FF /* DummyResourceFile.r in Rez */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXRezBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 8D01CCCB0486CAD60068D4B7 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 841E07300AF9F015005E6FCC /* DemoEditorComponent.cpp in Sources */, + 841E07310AF9F015005E6FCC /* DemoJuceFilter.cpp in Sources */, + 841E073D0AF9F099005E6FCC /* juce_RTASUtilities.cpp in Sources */, + 841E073E0AF9F099005E6FCC /* juce_RTASWrapper.cpp in Sources */, + 846444EF0AFA005B00E7B2BE /* juce_Wrapper_CEffectGroup.cpp in Sources */, + 846444F00AFA005B00E7B2BE /* juce_Wrapper_CEffectGroupMIDI.cpp in Sources */, + 846444F10AFA005B00E7B2BE /* juce_Wrapper_CEffectMIDIUtils.cpp in Sources */, + 846444F20AFA005B00E7B2BE /* juce_Wrapper_CEffectProcess.cpp in Sources */, + 846444F30AFA005B00E7B2BE /* juce_Wrapper_CEffectProcessAS.cpp in Sources */, + 846444F40AFA005B00E7B2BE /* juce_Wrapper_CEffectProcessMIDI.cpp in Sources */, + 846444F50AFA005B00E7B2BE /* juce_Wrapper_CEffectType.cpp in Sources */, + 846444F60AFA005B00E7B2BE /* juce_Wrapper_CEffectTypeRTAS.cpp in Sources */, + 846444F70AFA005B00E7B2BE /* juce_Wrapper_ChunkDataParser.cpp in Sources */, + 846444FA0AFA005B00E7B2BE /* juce_Wrapper_PlugInUtils.cpp in Sources */, + 84C9D7FB0AFA3C9C00F1348E /* juce_Wrapper_Dispatcher.cpp in Sources */, + 84C9D7FC0AFA3C9C00F1348E /* juce_Wrapper_PluginInitialize.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 5B521C9A088F2389009C75FE /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + }; + name = Debug; + }; + 5B521C9E088F2389009C75FE /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 84C4426A0B306D39003FCBFF /* CommonDebugSettings.xcconfig */; + buildSettings = { + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + MacBag = /Users/jules/stuff/PT_73_SDK/MacBag; + PRODUCT_NAME = JuceRTASDemo; + USER_HEADER_SEARCH_PATHS = "/Users/jules/code/juce $(inherited)"; + }; + name = Debug; + }; + 5BEA73AA09E4370600964A97 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + }; + name = Release; + }; + 5BEA73AB09E4370600964A97 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 84C442690B306D39003FCBFF /* CommonReleaseSettings.xcconfig */; + buildSettings = { + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + MacBag = /Users/jules/stuff/PT_73_SDK/MacBag; + PRODUCT_NAME = JuceRTASDemo; + USER_HEADER_SEARCH_PATHS = "/Users/jules/code/juce $(inherited)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 5B521C99088F2389009C75FE /* Build configuration list for PBXNativeTarget "JuceRTASDemo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5B521C9A088F2389009C75FE /* Debug */, + 5BEA73AA09E4370600964A97 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; + 5B521C9D088F2389009C75FE /* Build configuration list for PBXProject "juce_RTASDemo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5B521C9E088F2389009C75FE /* Debug */, + 5BEA73AB09E4370600964A97 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; +/* End XCConfigurationList section */ + }; + rootObject = 089C1669FE841209C02AAC07 /* Project object */; +} diff --git a/extras/audio plugins/demo/build/RTAS_Win32/juce_RTAS.sln b/extras/audio plugins/demo/build/RTAS_Win32/juce_RTAS.sln new file mode 100644 index 0000000000..3c50d69e64 --- /dev/null +++ b/extras/audio plugins/demo/build/RTAS_Win32/juce_RTAS.sln @@ -0,0 +1,49 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "juce_RTAS", "juce_RTAS.vcproj", "{2EB09DDD-CF48-45ED-9698-6C5ADF123C98}" + ProjectSection(ProjectDependencies) = postProject + {AE232C11-D91C-4CA1-B24E-8B11A52EFF26} = {AE232C11-D91C-4CA1-B24E-8B11A52EFF26} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JUCE", "..\..\..\..\..\build\win32\vc8\JUCE.vcproj", "{AE232C11-D91C-4CA1-B24E-8B11A52EFF26}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug DLL|Win32 = Debug DLL|Win32 + Debug|Win32 = Debug|Win32 + DLL Debug|Win32 = DLL Debug|Win32 + DLL Release|Win32 = DLL Release|Win32 + Release DLL|Win32 = Release DLL|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2EB09DDD-CF48-45ED-9698-6C5ADF123C98}.Debug DLL|Win32.ActiveCfg = Debug|Win32 + {2EB09DDD-CF48-45ED-9698-6C5ADF123C98}.Debug DLL|Win32.Build.0 = Debug|Win32 + {2EB09DDD-CF48-45ED-9698-6C5ADF123C98}.Debug|Win32.ActiveCfg = Debug|Win32 + {2EB09DDD-CF48-45ED-9698-6C5ADF123C98}.Debug|Win32.Build.0 = Debug|Win32 + {2EB09DDD-CF48-45ED-9698-6C5ADF123C98}.DLL Debug|Win32.ActiveCfg = Debug|Win32 + {2EB09DDD-CF48-45ED-9698-6C5ADF123C98}.DLL Debug|Win32.Build.0 = Debug|Win32 + {2EB09DDD-CF48-45ED-9698-6C5ADF123C98}.DLL Release|Win32.ActiveCfg = Release|Win32 + {2EB09DDD-CF48-45ED-9698-6C5ADF123C98}.DLL Release|Win32.Build.0 = Release|Win32 + {2EB09DDD-CF48-45ED-9698-6C5ADF123C98}.Release DLL|Win32.ActiveCfg = Release|Win32 + {2EB09DDD-CF48-45ED-9698-6C5ADF123C98}.Release DLL|Win32.Build.0 = Release|Win32 + {2EB09DDD-CF48-45ED-9698-6C5ADF123C98}.Release|Win32.ActiveCfg = Release|Win32 + {2EB09DDD-CF48-45ED-9698-6C5ADF123C98}.Release|Win32.Build.0 = Release|Win32 + {AE232C11-D91C-4CA1-B24E-8B11A52EFF26}.Debug DLL|Win32.ActiveCfg = Debug|Win32 + {AE232C11-D91C-4CA1-B24E-8B11A52EFF26}.Debug DLL|Win32.Build.0 = Debug|Win32 + {AE232C11-D91C-4CA1-B24E-8B11A52EFF26}.Debug|Win32.ActiveCfg = Debug|Win32 + {AE232C11-D91C-4CA1-B24E-8B11A52EFF26}.Debug|Win32.Build.0 = Debug|Win32 + {AE232C11-D91C-4CA1-B24E-8B11A52EFF26}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32 + {AE232C11-D91C-4CA1-B24E-8B11A52EFF26}.DLL Debug|Win32.Build.0 = DLL Debug|Win32 + {AE232C11-D91C-4CA1-B24E-8B11A52EFF26}.DLL Release|Win32.ActiveCfg = DLL Release|Win32 + {AE232C11-D91C-4CA1-B24E-8B11A52EFF26}.DLL Release|Win32.Build.0 = DLL Release|Win32 + {AE232C11-D91C-4CA1-B24E-8B11A52EFF26}.Release DLL|Win32.ActiveCfg = Release|Win32 + {AE232C11-D91C-4CA1-B24E-8B11A52EFF26}.Release DLL|Win32.Build.0 = Release|Win32 + {AE232C11-D91C-4CA1-B24E-8B11A52EFF26}.Release|Win32.ActiveCfg = Release|Win32 + {AE232C11-D91C-4CA1-B24E-8B11A52EFF26}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/extras/audio plugins/demo/build/RTAS_Win32/juce_RTAS.vcproj b/extras/audio plugins/demo/build/RTAS_Win32/juce_RTAS.vcproj new file mode 100644 index 0000000000..92ca5bb3ed --- /dev/null +++ b/extras/audio plugins/demo/build/RTAS_Win32/juce_RTAS.vcproj @@ -0,0 +1,629 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/extras/audio plugins/demo/build/RTAS_Win32/juce_RTASDemo.rc b/extras/audio plugins/demo/build/RTAS_Win32/juce_RTASDemo.rc new file mode 100644 index 0000000000..086a710a53 --- /dev/null +++ b/extras/audio plugins/demo/build/RTAS_Win32/juce_RTASDemo.rc @@ -0,0 +1,112 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// English (U.K.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,1 + PRODUCTVERSION 1,0,0,1 + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "080904b0" + BEGIN + VALUE "FileDescription", "Juce Audio Plugin RTAS Demo" + VALUE "FileVersion", "1, 0, 0, 1" + VALUE "InternalName", "Juce RTAS Demo" + VALUE "LegalCopyright", "Copyright (C) 2006" + VALUE "ProductName", "Juce RTAS Demo" + VALUE "ProductVersion", "1, 0, 0, 1" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x809, 1200 + END +END + +#endif // English (U.K.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/extras/audio plugins/demo/build/RTAS_Win32/resource.h b/extras/audio plugins/demo/build/RTAS_Win32/resource.h new file mode 100644 index 0000000000..184fcb49e8 --- /dev/null +++ b/extras/audio plugins/demo/build/RTAS_Win32/resource.h @@ -0,0 +1,14 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by juce_RTASDemo.rc + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/extras/audio plugins/demo/build/VST_Linux/premake.lua b/extras/audio plugins/demo/build/VST_Linux/premake.lua new file mode 100644 index 0000000000..14406e8b8d --- /dev/null +++ b/extras/audio plugins/demo/build/VST_Linux/premake.lua @@ -0,0 +1,55 @@ + +project.name = "JucePluginDemo" +project.bindir = "build" +project.libdir = "build" + +project.configs = { "Debug", "Release" } + +package = newpackage() +package.name = "JucePluginDemo" +package.kind = "dll" +package.language = "c++" + +package.objdir = "build/intermediate" +package.config["Debug"].objdir = "build/intermediate/Debug" +package.config["Release"].objdir = "build/intermediate/Release" + +package.config["Debug"].defines = { "LINUX=1", "DEBUG=1", "_DEBUG=1" } +package.config["Debug"].buildoptions = { "-O0 -ggdb -g3 -Wall" } + +package.config["Release"].defines = { "LINUX=1", "NDEBUG=1" } +package.config["Release"].buildoptions = { "-O2 -s" } + +package.includepaths = { + "/usr/include", + "../../../../../", + "/usr/include/vst/source/common", + "/usr/include/vst", + "../../src" +} + +package.libpaths = { + "../../../../../bin", + "/usr/X11R6/lib/", + "/usr/lib" +} + +package.config["Debug"].links = { + "freetype", "pthread", "rt", "X11", "GL", "GLU", "Xinerama", "asound", "juce_debug" +} + +package.config["Release"].links = { + "freetype", "pthread", "rt", "X11", "GL", "GLU", "Xinerama", "asound", "juce" +} + +package.files = { + matchfiles ( + "../../../wrapper/*.h", + "../../../wrapper/*.cpp", + "../../../wrapper/formats/VST/*.cpp" + ), + matchrecursive ( + "../../src/*.h", + "../../src/*.cpp" + ) +} diff --git a/extras/audio plugins/demo/build/VST_Mac/Info.plist b/extras/audio plugins/demo/build/VST_Mac/Info.plist new file mode 100644 index 0000000000..c5b8c15fef --- /dev/null +++ b/extras/audio plugins/demo/build/VST_Mac/Info.plist @@ -0,0 +1,28 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + JuceVST + CFBundleGetInfoString + Juce VST Demo plugin + CFBundleIconFile + + CFBundleIdentifier + com.rawmaterialsoftware.JuceVSTDemo + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + JuceVST + CFBundlePackageType + BNDL + CFBundleShortVersionString + + CFBundleSignature + JUCE + CFBundleVersion + 0.0.1 + + diff --git a/extras/audio plugins/demo/build/VST_Mac/JuceVST-Info.plist b/extras/audio plugins/demo/build/VST_Mac/JuceVST-Info.plist new file mode 100644 index 0000000000..688e659fa4 --- /dev/null +++ b/extras/audio plugins/demo/build/VST_Mac/JuceVST-Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + JuceVST + CFBundleIdentifier + com.rawmaterialsoftware.JuceVST + CFBundleInfoDictionaryVersion + 1.0 + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + CSResourcesFileMapped + yes + + diff --git a/extras/audio plugins/demo/build/VST_Mac/JuceVST.xcodeproj/project.pbxproj b/extras/audio plugins/demo/build/VST_Mac/JuceVST.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..489c2d2713 --- /dev/null +++ b/extras/audio plugins/demo/build/VST_Mac/JuceVST.xcodeproj/project.pbxproj @@ -0,0 +1,289 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 42; + objects = { + +/* Begin PBXBuildFile section */ + 8456E9D008A29AE60087C412 /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8456E9CF08A29AE60087C412 /* CoreServices.framework */; }; + 845FAE4C0A5C09FA008C94D8 /* juce.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 845FAE4B0A5C09FA008C94D8 /* juce.xcconfig */; }; + 84BACBD20987847C0073300C /* juce_VstWrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84BACBD10987847C0073300C /* juce_VstWrapper.cpp */; }; + 84BC4EBC0C8DE02200FA249B /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84BC4EBA0C8DE02200FA249B /* IOKit.framework */; }; + 84BC4EBD0C8DE02200FA249B /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84BC4EBB0C8DE02200FA249B /* OpenGL.framework */; }; + 84E1AE51089EBAAA00E85E4F /* DemoEditorComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84E1AE4D089EBAAA00E85E4F /* DemoEditorComponent.cpp */; }; + 84E1AE52089EBAAA00E85E4F /* DemoJuceFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84E1AE4F089EBAAA00E85E4F /* DemoJuceFilter.cpp */; }; + 84E1AF2B089EBE4C00E85E4F /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84E1AF2A089EBE4C00E85E4F /* Carbon.framework */; }; + 84E1AF30089EBE5A00E85E4F /* QuickTime.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84E1AF2F089EBE5A00E85E4F /* QuickTime.framework */; }; + 84E1AF34089EBE6C00E85E4F /* AGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84E1AF33089EBE6C00E85E4F /* AGL.framework */; }; + 84E1AF38089EBF1300E85E4F /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84E1AF37089EBF1300E85E4F /* CoreAudio.framework */; }; + 84E1AF42089EBFD900E85E4F /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 84E1AF41089EBFD900E85E4F /* Info.plist */; }; + 84F5CF040B1B66B100A2E279 /* How to use this framework.txt in Resources */ = {isa = PBXBuildFile; fileRef = 84F5CF030B1B66B100A2E279 /* How to use this framework.txt */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 84551AA009BDB8F3009C9F3E /* JucePluginCharacteristics.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JucePluginCharacteristics.h; path = ../../src/JucePluginCharacteristics.h; sourceTree = SOURCE_ROOT; }; + 8456E9CF08A29AE60087C412 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = /System/Library/Frameworks/CoreServices.framework; sourceTree = ""; }; + 845FAE4B0A5C09FA008C94D8 /* juce.xcconfig */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xcconfig; name = juce.xcconfig; path = ../../../../../build/macosx/juce.xcconfig; sourceTree = SOURCE_ROOT; }; + 84BACBD10987847C0073300C /* juce_VstWrapper.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_VstWrapper.cpp; path = ../../../wrapper/formats/VST/juce_VstWrapper.cpp; sourceTree = SOURCE_ROOT; }; + 84BC4EBA0C8DE02200FA249B /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = ""; }; + 84BC4EBB0C8DE02200FA249B /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = /System/Library/Frameworks/OpenGL.framework; sourceTree = ""; }; + 84E1AE47089EBA6A00E85E4F /* JuceVST.vst */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = JuceVST.vst; sourceTree = BUILT_PRODUCTS_DIR; }; + 84E1AE4D089EBAAA00E85E4F /* DemoEditorComponent.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DemoEditorComponent.cpp; path = ../../src/DemoEditorComponent.cpp; sourceTree = SOURCE_ROOT; }; + 84E1AE4E089EBAAA00E85E4F /* DemoEditorComponent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = DemoEditorComponent.h; path = ../../src/DemoEditorComponent.h; sourceTree = SOURCE_ROOT; }; + 84E1AE4F089EBAAA00E85E4F /* DemoJuceFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DemoJuceFilter.cpp; path = ../../src/DemoJuceFilter.cpp; sourceTree = SOURCE_ROOT; }; + 84E1AE50089EBAAA00E85E4F /* DemoJuceFilter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = DemoJuceFilter.h; path = ../../src/DemoJuceFilter.h; sourceTree = SOURCE_ROOT; }; + 84E1AF2A089EBE4C00E85E4F /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = ""; }; + 84E1AF2F089EBE5A00E85E4F /* QuickTime.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuickTime.framework; path = /System/Library/Frameworks/QuickTime.framework; sourceTree = ""; }; + 84E1AF33089EBE6C00E85E4F /* AGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AGL.framework; path = /System/Library/Frameworks/AGL.framework; sourceTree = ""; }; + 84E1AF37089EBF1300E85E4F /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = /System/Library/Frameworks/CoreAudio.framework; sourceTree = ""; }; + 84E1AF41089EBFD900E85E4F /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; path = Info.plist; sourceTree = SOURCE_ROOT; }; + 84F5CF030B1B66B100A2E279 /* How to use this framework.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = "How to use this framework.txt"; path = "../../../How to use this framework.txt"; sourceTree = SOURCE_ROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 84E1AE45089EBA6A00E85E4F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 84E1AF2B089EBE4C00E85E4F /* Carbon.framework in Frameworks */, + 84E1AF30089EBE5A00E85E4F /* QuickTime.framework in Frameworks */, + 84E1AF34089EBE6C00E85E4F /* AGL.framework in Frameworks */, + 84E1AF38089EBF1300E85E4F /* CoreAudio.framework in Frameworks */, + 8456E9D008A29AE60087C412 /* CoreServices.framework in Frameworks */, + 84BC4EBC0C8DE02200FA249B /* IOKit.framework in Frameworks */, + 84BC4EBD0C8DE02200FA249B /* OpenGL.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 089C166AFE841209C02AAC07 /* JuceVST */ = { + isa = PBXGroup; + children = ( + 08FB77ADFE841716C02AAC07 /* Source */, + 84F5CF030B1B66B100A2E279 /* How to use this framework.txt */, + 089C167CFE841241C02AAC07 /* Resources */, + 089C1671FE841209C02AAC07 /* External Frameworks and Libraries */, + 19C28FB4FE9D528D11CA2CBB /* Products */, + ); + name = JuceVST; + sourceTree = ""; + }; + 089C1671FE841209C02AAC07 /* External Frameworks and Libraries */ = { + isa = PBXGroup; + children = ( + 84BC4EBA0C8DE02200FA249B /* IOKit.framework */, + 84BC4EBB0C8DE02200FA249B /* OpenGL.framework */, + 84E1AF2A089EBE4C00E85E4F /* Carbon.framework */, + 8456E9CF08A29AE60087C412 /* CoreServices.framework */, + 84E1AF37089EBF1300E85E4F /* CoreAudio.framework */, + 84E1AF33089EBE6C00E85E4F /* AGL.framework */, + 84E1AF2F089EBE5A00E85E4F /* QuickTime.framework */, + ); + name = "External Frameworks and Libraries"; + sourceTree = ""; + }; + 089C167CFE841241C02AAC07 /* Resources */ = { + isa = PBXGroup; + children = ( + 84E1AF41089EBFD900E85E4F /* Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 08FB77ADFE841716C02AAC07 /* Source */ = { + isa = PBXGroup; + children = ( + 84E1AE4C089EBA9300E85E4F /* filter */, + 84E1AE53089EBACA00E85E4F /* wrapper code */, + 845FAE4B0A5C09FA008C94D8 /* juce.xcconfig */, + ); + name = Source; + sourceTree = ""; + }; + 19C28FB4FE9D528D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 84E1AE47089EBA6A00E85E4F /* JuceVST.vst */, + ); + name = Products; + sourceTree = ""; + }; + 84E1AE4C089EBA9300E85E4F /* filter */ = { + isa = PBXGroup; + children = ( + 84E1AE4D089EBAAA00E85E4F /* DemoEditorComponent.cpp */, + 84E1AE4E089EBAAA00E85E4F /* DemoEditorComponent.h */, + 84E1AE4F089EBAAA00E85E4F /* DemoJuceFilter.cpp */, + 84E1AE50089EBAAA00E85E4F /* DemoJuceFilter.h */, + 84551AA009BDB8F3009C9F3E /* JucePluginCharacteristics.h */, + ); + name = filter; + sourceTree = ""; + }; + 84E1AE53089EBACA00E85E4F /* wrapper code */ = { + isa = PBXGroup; + children = ( + 84BACBD10987847C0073300C /* juce_VstWrapper.cpp */, + ); + name = "wrapper code"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 84E1AE46089EBA6A00E85E4F /* JuceVST */ = { + isa = PBXNativeTarget; + buildConfigurationList = 84E1AE48089EBA8900E85E4F /* Build configuration list for PBXNativeTarget "JuceVST" */; + buildPhases = ( + 84E1AE43089EBA6A00E85E4F /* Resources */, + 84E1AE44089EBA6A00E85E4F /* Sources */, + 84E1AE45089EBA6A00E85E4F /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = JuceVST; + productName = JuceVST; + productReference = 84E1AE47089EBA6A00E85E4F /* JuceVST.vst */; + productType = "com.apple.product-type.bundle"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 089C1669FE841209C02AAC07 /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 84E1ADD2089EB1BA00E85E4F /* Build configuration list for PBXProject "JuceVST" */; + hasScannedForEncodings = 1; + mainGroup = 089C166AFE841209C02AAC07 /* JuceVST */; + projectDirPath = ""; + targets = ( + 84E1AE46089EBA6A00E85E4F /* JuceVST */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 84E1AE43089EBA6A00E85E4F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 84E1AF42089EBFD900E85E4F /* Info.plist in Resources */, + 845FAE4C0A5C09FA008C94D8 /* juce.xcconfig in Resources */, + 84F5CF040B1B66B100A2E279 /* How to use this framework.txt in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 84E1AE44089EBA6A00E85E4F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 84E1AE51089EBAAA00E85E4F /* DemoEditorComponent.cpp in Sources */, + 84E1AE52089EBAAA00E85E4F /* DemoJuceFilter.cpp in Sources */, + 84BACBD20987847C0073300C /* juce_VstWrapper.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 84E1ADD3089EB1BA00E85E4F /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 845FAE4B0A5C09FA008C94D8 /* juce.xcconfig */; + buildSettings = { + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = DEBUG; + HEADER_SEARCH_PATHS = ( + ../../../../.., + "~/stuff/vstsdk2.4/", + ); + LIBRARY_SEARCH_PATHS = ../../../../../bin; + OTHER_LDFLAGS = "-ljucedebug"; + }; + name = Debug; + }; + 84E1ADD4089EB1BA00E85E4F /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 845FAE4B0A5C09FA008C94D8 /* juce.xcconfig */; + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS = NDEBUG; + HEADER_SEARCH_PATHS = ( + ../../../../.., + "~/stuff/vstsdk2.4/", + ); + LIBRARY_SEARCH_PATHS = ../../../../../bin; + OTHER_LDFLAGS = "-ljuce"; + }; + name = Release; + }; + 84E1AE49089EBA8900E85E4F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + GENERATE_PKGINFO_FILE = YES; + INFOPLIST_FILE = info.plist; + PRODUCT_NAME = JuceVST; + SYMROOT = "$(HOME)/Library/Audio/Plug-Ins/VST"; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + WRAPPER_EXTENSION = vst; + }; + name = Debug; + }; + 84E1AE4A089EBA8900E85E4F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_INLINES_ARE_PRIVATE_EXTERN = YES; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + GENERATE_PKGINFO_FILE = YES; + INFOPLIST_FILE = info.plist; + PRODUCT_NAME = JuceVST; + SYMROOT = "$(HOME)/Library/Audio/Plug-Ins/VST"; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + WRAPPER_EXTENSION = vst; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 84E1ADD2089EB1BA00E85E4F /* Build configuration list for PBXProject "JuceVST" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 84E1ADD3089EB1BA00E85E4F /* Debug */, + 84E1ADD4089EB1BA00E85E4F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; + 84E1AE48089EBA8900E85E4F /* Build configuration list for PBXNativeTarget "JuceVST" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 84E1AE49089EBA8900E85E4F /* Debug */, + 84E1AE4A089EBA8900E85E4F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; +/* End XCConfigurationList section */ + }; + rootObject = 089C1669FE841209C02AAC07 /* Project object */; +} diff --git a/extras/audio plugins/demo/build/VST_Mac/version.plist b/extras/audio plugins/demo/build/VST_Mac/version.plist new file mode 100644 index 0000000000..169b5fae84 --- /dev/null +++ b/extras/audio plugins/demo/build/VST_Mac/version.plist @@ -0,0 +1,16 @@ + + + + + BuildVersion + 38 + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1.0 + ProjectName + CarbonProjectTemplates + SourceVersion + 140000 + + diff --git a/extras/audio plugins/demo/build/VST_Win32/juce_vst.sln b/extras/audio plugins/demo/build/VST_Win32/juce_vst.sln new file mode 100644 index 0000000000..d87b0d4a00 --- /dev/null +++ b/extras/audio plugins/demo/build/VST_Win32/juce_vst.sln @@ -0,0 +1,39 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JuceAudioPlugin Demo", "juce_vst.vcproj", "{6F0F1E35-EAF8-431A-83D9-F0340921E560}" + ProjectSection(ProjectDependencies) = postProject + {AE232C11-D91C-4CA1-B24E-8B11A52EFF26} = {AE232C11-D91C-4CA1-B24E-8B11A52EFF26} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JUCE", "..\..\..\..\..\build\win32\vc8\JUCE.vcproj", "{AE232C11-D91C-4CA1-B24E-8B11A52EFF26}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + DLL Debug|Win32 = DLL Debug|Win32 + DLL Release|Win32 = DLL Release|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6F0F1E35-EAF8-431A-83D9-F0340921E560}.Debug|Win32.ActiveCfg = Debug|Win32 + {6F0F1E35-EAF8-431A-83D9-F0340921E560}.Debug|Win32.Build.0 = Debug|Win32 + {6F0F1E35-EAF8-431A-83D9-F0340921E560}.DLL Debug|Win32.ActiveCfg = Debug|Win32 + {6F0F1E35-EAF8-431A-83D9-F0340921E560}.DLL Debug|Win32.Build.0 = Debug|Win32 + {6F0F1E35-EAF8-431A-83D9-F0340921E560}.DLL Release|Win32.ActiveCfg = Release|Win32 + {6F0F1E35-EAF8-431A-83D9-F0340921E560}.DLL Release|Win32.Build.0 = Release|Win32 + {6F0F1E35-EAF8-431A-83D9-F0340921E560}.Release|Win32.ActiveCfg = Release|Win32 + {6F0F1E35-EAF8-431A-83D9-F0340921E560}.Release|Win32.Build.0 = Release|Win32 + {AE232C11-D91C-4CA1-B24E-8B11A52EFF26}.Debug|Win32.ActiveCfg = Debug|Win32 + {AE232C11-D91C-4CA1-B24E-8B11A52EFF26}.Debug|Win32.Build.0 = Debug|Win32 + {AE232C11-D91C-4CA1-B24E-8B11A52EFF26}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32 + {AE232C11-D91C-4CA1-B24E-8B11A52EFF26}.DLL Debug|Win32.Build.0 = DLL Debug|Win32 + {AE232C11-D91C-4CA1-B24E-8B11A52EFF26}.DLL Release|Win32.ActiveCfg = DLL Release|Win32 + {AE232C11-D91C-4CA1-B24E-8B11A52EFF26}.DLL Release|Win32.Build.0 = DLL Release|Win32 + {AE232C11-D91C-4CA1-B24E-8B11A52EFF26}.Release|Win32.ActiveCfg = Release|Win32 + {AE232C11-D91C-4CA1-B24E-8B11A52EFF26}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/extras/audio plugins/demo/build/VST_Win32/juce_vst.vcproj b/extras/audio plugins/demo/build/VST_Win32/juce_vst.vcproj new file mode 100644 index 0000000000..965468e416 --- /dev/null +++ b/extras/audio plugins/demo/build/VST_Win32/juce_vst.vcproj @@ -0,0 +1,268 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/extras/audio plugins/demo/src/DemoEditorComponent.cpp b/extras/audio plugins/demo/src/DemoEditorComponent.cpp new file mode 100644 index 0000000000..ddd46c4242 --- /dev/null +++ b/extras/audio plugins/demo/src/DemoEditorComponent.cpp @@ -0,0 +1,195 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +#include "../../../../juce.h" +#include "DemoEditorComponent.h" + +//============================================================================== +// quick-and-dirty function to format a timecode string +static const String timeToTimecodeString (const double seconds) +{ + const double absSecs = fabs (seconds); + const tchar* const sign = (seconds < 0) ? T("-") : T(""); + + const int hours = (int) (absSecs / (60.0 * 60.0)); + const int mins = ((int) (absSecs / 60.0)) % 60; + const int secs = ((int) absSecs) % 60; + + return String::formatted (T("%s%02d:%02d:%02d:%03d"), + sign, hours, mins, secs, + roundDoubleToInt (absSecs * 1000) % 1000); +} + +// quick-and-dirty function to format a bars/beats string +static const String ppqToBarsBeatsString (const double ppq, + const double lastBarPPQ, + const int numerator, + const int denominator) +{ + if (numerator == 0 || denominator == 0) + return T("1|1|0"); + + const int ppqPerBar = (numerator * 4 / denominator); + const double beats = (fmod (ppq, ppqPerBar) / ppqPerBar) * numerator; + + const int bar = ((int) ppq) / ppqPerBar + 1; + const int beat = ((int) beats) + 1; + const int ticks = ((int) (fmod (beats, 1.0) * 960.0)); + + String s; + s << bar << T('|') << beat << T('|') << ticks; + return s; +} + + +//============================================================================== +DemoEditorComponent::DemoEditorComponent (DemoJuceFilter* const ownerFilter) + : AudioProcessorEditor (ownerFilter) +{ + // create our gain slider.. + addAndMakeVisible (gainSlider = new Slider (T("gain"))); + gainSlider->addListener (this); + gainSlider->setRange (0.0, 1.0, 0.01); + gainSlider->setTooltip (T("changes the volume of the audio that runs through the plugin..")); + + // get the gain parameter from the filter and use it to set up our slider + gainSlider->setValue (ownerFilter->getParameter (0), false); + + // create and add the midi keyboard component.. + addAndMakeVisible (midiKeyboard + = new MidiKeyboardComponent (ownerFilter->keyboardState, + MidiKeyboardComponent::horizontalKeyboard)); + + // add a label that will display the current timecode and status.. + addAndMakeVisible (infoLabel = new Label (String::empty, String::empty)); + + // add the triangular resizer component for the bottom-right of the UI + addAndMakeVisible (resizer = new ResizableCornerComponent (this, &resizeLimits)); + resizeLimits.setSizeLimits (150, 150, 800, 300); + + // set our component's initial size to be the last one that was stored in the filter's settings + setSize (ownerFilter->lastUIWidth, + ownerFilter->lastUIHeight); + + // register ourselves with the filter - it will use its ChangeBroadcaster base + // class to tell us when something has changed, and this will call our changeListenerCallback() + // method. + ownerFilter->addChangeListener (this); +} + +DemoEditorComponent::~DemoEditorComponent() +{ + getFilter()->removeChangeListener (this); + + deleteAllChildren(); +} + +//============================================================================== +void DemoEditorComponent::paint (Graphics& g) +{ + // just clear the window + g.fillAll (Colour::greyLevel (0.9f)); +} + +void DemoEditorComponent::resized() +{ + gainSlider->setBounds (10, 10, 200, 22); + infoLabel->setBounds (10, 35, 450, 20); + + const int keyboardHeight = 70; + midiKeyboard->setBounds (4, getHeight() - keyboardHeight - 4, + getWidth() - 8, keyboardHeight); + + resizer->setBounds (getWidth() - 16, getHeight() - 16, 16, 16); + + // if we've been resized, tell the filter so that it can store the new size + // in its settings + getFilter()->lastUIWidth = getWidth(); + getFilter()->lastUIHeight = getHeight(); +} + +//============================================================================== +void DemoEditorComponent::changeListenerCallback (void* source) +{ + // this is the filter telling us that it's changed, so we'll update our + // display of the time, midi message, etc. + updateParametersFromFilter(); +} + +void DemoEditorComponent::sliderValueChanged (Slider*) +{ + getFilter()->setParameterNotifyingHost (0, (float) gainSlider->getValue()); +} + +//============================================================================== +void DemoEditorComponent::updateParametersFromFilter() +{ + DemoJuceFilter* const filter = getFilter(); + + // we use this lock to make sure the processBlock() method isn't writing to the + // lastMidiMessage variable while we're trying to read it, but be extra-careful to + // only hold the lock for a minimum amount of time.. + filter->getCallbackLock().enter(); + + // take a local copy of the info we need while we've got the lock.. + const AudioPlayHead::CurrentPositionInfo positionInfo (filter->lastPosInfo); + const float newGain = filter->getParameter (0); + + // ..release the lock ASAP + filter->getCallbackLock().exit(); + + + // ..and after releasing the lock, we're free to do the time-consuming UI stuff.. + String infoText; + infoText << String (positionInfo.bpm, 2) << T(" bpm, ") + << positionInfo.timeSigNumerator << T("/") << positionInfo.timeSigDenominator + << T(" - ") << timeToTimecodeString (positionInfo.timeInSeconds) + << T(" - ") << ppqToBarsBeatsString (positionInfo.ppqPosition, + positionInfo.ppqPositionOfLastBarStart, + positionInfo.timeSigNumerator, + positionInfo.timeSigDenominator); + + if (positionInfo.isPlaying) + infoText << T(" (playing)"); + + infoLabel->setText (infoText, false); + + /* Update our slider. + + (note that it's important here to tell the slider not to send a change + message, because that would cause it to call the filter with a parameter + change message again, and the values would drift out. + */ + gainSlider->setValue (newGain, false); + + setSize (filter->lastUIWidth, + filter->lastUIHeight); +} diff --git a/extras/audio plugins/demo/src/DemoEditorComponent.h b/extras/audio plugins/demo/src/DemoEditorComponent.h new file mode 100644 index 0000000000..a0530fc21b --- /dev/null +++ b/extras/audio plugins/demo/src/DemoEditorComponent.h @@ -0,0 +1,99 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +#ifndef DEMOJUCEPLUGINEDITOR_H +#define DEMOJUCEPLUGINEDITOR_H + +#include "DemoJuceFilter.h" + + +//============================================================================== +/** + This is the Component that our filter will use as its UI. + + One or more of these is created by the DemoJuceFilter::createEditor() method, + and they will be deleted at some later time by the wrapper code. + + To demonstrate the correct way of connecting a filter to its UI, this + class is a ChangeListener, and our demo filter is a ChangeBroadcaster. The + editor component registers with the filter when it's created and deregisters + when it's destroyed. When the filter's parameters are changed, it broadcasts + a message and this editor responds by updating its display. +*/ +class DemoEditorComponent : public AudioProcessorEditor, + public ChangeListener, + public SliderListener +{ +public: + /** Constructor. + + When created, this will register itself with the filter for changes. It's + safe to assume that the filter won't be deleted before this object is. + */ + DemoEditorComponent (DemoJuceFilter* const ownerFilter); + + /** Destructor. */ + ~DemoEditorComponent(); + + //============================================================================== + /** Our demo filter is a ChangeBroadcaster, and will call us back when one of + its parameters changes. + */ + void changeListenerCallback (void* source); + + void sliderValueChanged (Slider*); + + //============================================================================== + /** Standard Juce paint callback. */ + void paint (Graphics& g); + + /** Standard Juce resize callback. */ + void resized(); + + +private: + //============================================================================== + Slider* gainSlider; + MidiKeyboardComponent* midiKeyboard; + Label* infoLabel; + ResizableCornerComponent* resizer; + ComponentBoundsConstrainer resizeLimits; + TooltipWindow tooltipWindow; + + void updateParametersFromFilter(); + + // handy wrapper method to avoid having to cast the filter to a DemoJuceFilter + // every time we need it.. + DemoJuceFilter* getFilter() const throw() { return (DemoJuceFilter*) getAudioProcessor(); } +}; + + +#endif diff --git a/extras/audio plugins/demo/src/DemoJuceFilter.cpp b/extras/audio plugins/demo/src/DemoJuceFilter.cpp new file mode 100644 index 0000000000..c7bc07de0a --- /dev/null +++ b/extras/audio plugins/demo/src/DemoJuceFilter.cpp @@ -0,0 +1,236 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +#include "../../../../juce.h" +#include "DemoJuceFilter.h" +#include "DemoEditorComponent.h" + + +//============================================================================== +/** + This function must be implemented to create a new instance of your + plugin object. +*/ +AudioProcessor* JUCE_CALLTYPE createPluginFilter() +{ + return new DemoJuceFilter(); +} + +//============================================================================== +DemoJuceFilter::DemoJuceFilter() +{ + gain = 1.0f; + lastUIWidth = 400; + lastUIHeight = 140; + + zeromem (&lastPosInfo, sizeof (lastPosInfo)); + lastPosInfo.timeSigNumerator = 4; + lastPosInfo.timeSigDenominator = 4; + lastPosInfo.bpm = 120; +} + +DemoJuceFilter::~DemoJuceFilter() +{ +} + +//============================================================================== +int DemoJuceFilter::getNumParameters() +{ + return 1; +} + +float DemoJuceFilter::getParameter (int index) +{ + return (index == 0) ? gain + : 0.0f; +} + +void DemoJuceFilter::setParameter (int index, float newValue) +{ + if (index == 0) + { + if (gain != newValue) + { + gain = newValue; + + // if this is changing the gain, broadcast a change message which + // our editor will pick up. + sendChangeMessage (this); + } + } +} + +const String DemoJuceFilter::getParameterName (int index) +{ + if (index == 0) + return T("gain"); + + return String::empty; +} + +const String DemoJuceFilter::getParameterText (int index) +{ + if (index == 0) + return String (gain, 2); + + return String::empty; +} + +const String DemoJuceFilter::getInputChannelName (const int channelIndex) const +{ + return String (channelIndex + 1); +} + +const String DemoJuceFilter::getOutputChannelName (const int channelIndex) const +{ + return String (channelIndex + 1); +} + +bool DemoJuceFilter::isInputChannelStereoPair (int index) const +{ + return false; +} + +bool DemoJuceFilter::isOutputChannelStereoPair (int index) const +{ + return false; +} + +//============================================================================== +void DemoJuceFilter::prepareToPlay (double sampleRate, int samplesPerBlock) +{ + // do your pre-playback setup stuff here.. + keyboardState.reset(); +} + +void DemoJuceFilter::releaseResources() +{ + // when playback stops, you can use this as an opportunity to free up any + // spare memory, etc. +} + +void DemoJuceFilter::processBlock (AudioSampleBuffer& buffer, + MidiBuffer& midiMessages) +{ + // for each of our input channels, we'll attenuate its level by the + // amount that our volume parameter is set to. + for (int channel = 0; channel < getNumInputChannels(); ++channel) + { + buffer.applyGain (channel, 0, buffer.getNumSamples(), gain); + } + + // 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()); + } + + // if any midi messages come in, use them to update the keyboard state object. This + // object sends notification to the UI component about key up/down changes + keyboardState.processNextMidiBuffer (midiMessages, + 0, buffer.getNumSamples(), + true); + + // have a go at getting the current time from the host, and if it's changed, tell + // our UI to update itself. + AudioPlayHead::CurrentPositionInfo pos; + + if (getPlayHead() != 0 && getPlayHead()->getCurrentPosition (pos)) + { + if (memcmp (&pos, &lastPosInfo, sizeof (pos)) != 0) + { + lastPosInfo = pos; + sendChangeMessage (this); + } + } + else + { + zeromem (&lastPosInfo, sizeof (lastPosInfo)); + lastPosInfo.timeSigNumerator = 4; + lastPosInfo.timeSigDenominator = 4; + lastPosInfo.bpm = 120; + } +} + +//============================================================================== +AudioProcessorEditor* DemoJuceFilter::createEditor() +{ + return new DemoEditorComponent (this); +} + +//============================================================================== +void DemoJuceFilter::getStateInformation (MemoryBlock& destData) +{ + // you can store your parameters as binary data if you want to or if you've got + // a load of binary to put in there, but if you're not doing anything too heavy, + // XML is a much cleaner way of doing it - here's an example of how to store your + // params as XML.. + + // create an outer XML element.. + XmlElement xmlState (T("MYPLUGINSETTINGS")); + + // add some attributes to it.. + xmlState.setAttribute (T("pluginVersion"), 1); + xmlState.setAttribute (T("gainLevel"), gain); + xmlState.setAttribute (T("uiWidth"), lastUIWidth); + xmlState.setAttribute (T("uiHeight"), lastUIHeight); + + // you could also add as many child elements as you need to here.. + + + // then use this helper function to stuff it into the binary blob and return it.. + copyXmlToBinary (xmlState, destData); +} + +void DemoJuceFilter::setStateInformation (const void* data, int sizeInBytes) +{ + // use this helper function to get the XML from this binary blob.. + XmlElement* const xmlState = getXmlFromBinary (data, sizeInBytes); + + if (xmlState != 0) + { + // check that it's the right type of xml.. + if (xmlState->hasTagName (T("MYPLUGINSETTINGS"))) + { + // ok, now pull out our parameters.. + gain = (float) xmlState->getDoubleAttribute (T("gainLevel"), gain); + + lastUIWidth = xmlState->getIntAttribute (T("uiWidth"), lastUIWidth); + lastUIHeight = xmlState->getIntAttribute (T("uiHeight"), lastUIHeight); + + sendChangeMessage (this); + } + + delete xmlState; + } +} diff --git a/extras/audio plugins/demo/src/DemoJuceFilter.h b/extras/audio plugins/demo/src/DemoJuceFilter.h new file mode 100644 index 0000000000..ae8a0384c5 --- /dev/null +++ b/extras/audio plugins/demo/src/DemoJuceFilter.h @@ -0,0 +1,112 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +#ifndef DEMOJUCEPLUGINFILTER_H +#define DEMOJUCEPLUGINFILTER_H + + +//============================================================================== +/** + A simple plugin filter that just applies a gain change to the audio + passing through it. + +*/ +class DemoJuceFilter : public AudioProcessor, + public ChangeBroadcaster +{ +public: + //============================================================================== + DemoJuceFilter(); + ~DemoJuceFilter(); + + //============================================================================== + void prepareToPlay (double sampleRate, int samplesPerBlock); + void releaseResources(); + + void processBlock (AudioSampleBuffer& buffer, + MidiBuffer& midiMessages); + + //============================================================================== + AudioProcessorEditor* createEditor(); + + //============================================================================== + int getNumParameters(); + + float getParameter (int index); + void setParameter (int index, float newValue); + + const String getParameterName (int index); + const String getParameterText (int index); + + const String getInputChannelName (const int channelIndex) const; + const String getOutputChannelName (const int channelIndex) const; + bool isInputChannelStereoPair (int index) const; + bool isOutputChannelStereoPair (int index) const; + + //============================================================================== + int getNumPrograms() { return 0; } + int getCurrentProgram() { return 0; } + void setCurrentProgram (int index) { } + const String getProgramName (int index) { return String::empty; } + void changeProgramName (int index, const String& newName) { } + + //============================================================================== + void getStateInformation (MemoryBlock& destData); + void setStateInformation (const void* data, int sizeInBytes); + + //============================================================================== + // These properties are public so that our editor component can access them + // - a bit of a hacky way to do it, but it's only a demo! + + // this is kept up to date with the midi messages that arrive, and the UI component + // registers with it so it can represent the incoming messages + MidiKeyboardState keyboardState; + + // this keeps a copy of the last set of time info that was acquired during an audio + // callback - the UI component will read this and display it. + AudioPlayHead::CurrentPositionInfo lastPosInfo; + + // these are used to persist the UI's size - the values are stored along with the + // filter's other parameters, and the UI component will update them when it gets + // resized. + int lastUIWidth, lastUIHeight; + + //============================================================================== + juce_UseDebuggingNewOperator + +private: + // this is our gain - the UI and the host can access this by getting/setting + // parameter 0. + float gain; +}; + + +#endif diff --git a/extras/audio plugins/demo/src/JucePluginCharacteristics.h b/extras/audio plugins/demo/src/JucePluginCharacteristics.h new file mode 100644 index 0000000000..e8dc81601e --- /dev/null +++ b/extras/audio plugins/demo/src/JucePluginCharacteristics.h @@ -0,0 +1,270 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +#ifndef __JUCE_PLUGIN_CHARACTERISTICS_H__ +#define __JUCE_PLUGIN_CHARACTERISTICS_H__ + + +//============================================================================== +/* All of the following settings need to be defined for your plugin. + + Go through each of these definitions and check that it's correctly + set-up before trying to do a build. +*/ + +//============================================================================== +/* Generic settings */ + +/** The name of your plugin. (Try to keep this as short as possible) +*/ +#define JucePlugin_Name "Juce Demo Plugin" + +/** A longer decription of your plugin. +*/ +#define JucePlugin_Desc "A Demo Plugin demonstrating Juce" + +/** The name of your company. (Try to keep this as short as possible) +*/ +#define JucePlugin_Manufacturer "Raw Material Software" + +/** A four-character code for your company. + Use single quotes - this isn't a string! +*/ +#define JucePlugin_ManufacturerCode 'RawM' + +/** A unique four-character code for your plugin. + Use single quotes - this isn't a string! + + Note that for AU compatibility, this must contain at least one + upper-case letter. +*/ +#define JucePlugin_PluginCode 'JcDm' + +//============================================================================== +/** The maximum number of channels of audio input that the plugin can handle. + + The actual number of channels supplied may be less than this, depending on the host. + For VSTs, you specify a maximum number of channels, for AUs and RTAS a set + of channel configurations is specified in JucePlugin_PreferredChannelConfigurations + and the host will choose one of these, but you should still set the max number of + channels correctly. + + As soon as a plugin's prepareToPlay() method is called, you can find out the actual + number of channels that will be used with the AudioProcessor::getNumInputChannels() + method. +*/ +#define JucePlugin_MaxNumInputChannels 2 + +/** The maximum number of channels of audio output that the plugin can handle. + + The actual number of channels supplied may be less than this, depending on the host. + For VSTs, you specify a maximum number of channels, for AUs and RTAS a set + of channel configurations is specified in JucePlugin_PreferredChannelConfigurations + and the host will choose one of these, but you should still set the max number of + channels correctly. + + As soon as a plugin's prepareToPlay() method is called, you can find out the actual + number of channels that will be used with the AudioProcessor::getNumOutputChannels() + method. +*/ +#define JucePlugin_MaxNumOutputChannels 2 + +/** This allows the plugin to specify the configurations of input/output channels that + they can support. + + AU and RTAS hosts will use this information, although VSTs only have a concept of + a maximum number of channels. + + The list is a set of pairs of values in the form { numInputs, numOutputs }, and each + pair indicates a valid configuration that the plugin can handle. + + So for example, {1, 1}, {2, 2} means that the plugin can be used in just two + configurations: either with 1 input and 1 output, or with 2 inputs and 2 outputs. If + you used this in Pro-Tools, the plugin could be placed on a mono or stereo track. + If the list was just {1, 1}, then Pro-Tools would only allow it to be used as a mono + plugin. + + As soon as a plugin's prepareToPlay() method is called, you can find out the actual + number of channels that the host has connected to the plugin by using the + AudioProcessor::getNumOutputChannels() and AudioFilterBase::getNumInputChannels() + methods. +*/ +#define JucePlugin_PreferredChannelConfigurations { 1, 1 }, { 2, 2 } + +//============================================================================== +/** Set this value to 1 if your plugin is a synth, or 0 if it isn't. +*/ +#define JucePlugin_IsSynth 0 + +/** Set this to 1 if your plugin needs to receive midi messages, or 0 if + it doesn't. +*/ +#define JucePlugin_WantsMidiInput 1 + +/** Set this to 1 if your plugin wants to output midi messages, or 0 if + it doesn't. +*/ +#define JucePlugin_ProducesMidiOutput 1 + +/** If this is 1, it means that when the plugins input buffers are + silent, it's output will be too. + + Some hosts may use this to avoid calling the plugin when no audio + would be produced. +*/ +#define JucePlugin_SilenceInProducesSilenceOut 0 + +/** If set to 1, this hints that the host should ignore any keys that are pressed + when the plugin has keyboard focus. If 0, then the host should still execute + any shortcut keys that are pressed, even if the plugin does have focus. + + Various hosts/platforms may deal with this differently, or ignore it. +*/ +#define JucePlugin_EditorRequiresKeyboardFocus 1 + + +//============================================================================== +/** A version number +*/ +#define JucePlugin_VersionCode 0x00010100 + +#define JucePlugin_VersionString "1.1" + + +//============================================================================== +/* VST settings */ + +/** For VSTs, if you're compiling against the V2.3 SDK, set this to zero. If + you're using V2.4 or later, make sure it's set to 1. +*/ +#define JUCE_USE_VSTSDK_2_4 1 + +/** Defines a UID for your VST plugin. + The default setting here is probably fine, unless you specifically need + a custom value. It's passed to the setUniqueID() method of the plugin class. +*/ +#define JucePlugin_VSTUniqueID JucePlugin_PluginCode + +/** Defines the type of plugin. For most pursposes, you don't need to change this + setting. +*/ +#if JucePlugin_IsSynth + #define JucePlugin_VSTCategory kPlugCategSynth +#else + #define JucePlugin_VSTCategory kPlugCategEffect +#endif + +//============================================================================== +/* AudioUnit settings */ + +/** Defines the major type of plugin - see AUComponent.h for the available options. + If it's an effect, you should use kAudioUnitType_Effect. For a synth, you'll + need to use kAudioUnitType_MusicEffect or kAudioUnitType_MusicDevice. +*/ +#if JucePlugin_IsSynth + #define JucePlugin_AUMainType kAudioUnitType_MusicDevice +#else + #define JucePlugin_AUMainType kAudioUnitType_Effect +#endif + +/** A 4-character plugin ID code that should be unique. + + You can leave this using the generic value JucePlugin_PluginCode, or + override it if necessary. + + Note that for AU, this must contain at least one upper-case letter. +*/ +#define JucePlugin_AUSubType JucePlugin_PluginCode + +/** A prefix for the names of exported entry-point functions that the component exposes. + + It's very important that your plugin's .exp file contains two entries that correspond to + this name. So for example if you set the prefix to "abc" then your exports + file must contain: + + _abcEntry + _abcViewEntry +*/ +#define JucePlugin_AUExportPrefix JuceDemoAU + +/** This is the same as JucePlugin_AUExportPrefix, but in quotes + (needed for the resource compiler...) +*/ +#define JucePlugin_AUExportPrefixQuoted "JuceDemoAU" + +/** A 4-character manufacturer code - this is your company name. + You can leave this using the generic value JucePlugin_ManufacturerCode, or + override it if necessary. +*/ +#define JucePlugin_AUManufacturerCode JucePlugin_ManufacturerCode + +/** If you define this value to be the same as the CFBundleIdentifier in your + plugin's plist, it allows the plugin to work out its own path, which is + needed if you want to use File::getSpecialLocation (currentExecutableFile) +*/ +#define JucePlugin_CFBundleIdentifier "com.rawmaterialsoftware.JuceDemo" + +//============================================================================== +/* RTAS settings */ + +/** How to categorise this plugin. + + For a synth you probably want to set this to ePlugInCategory_SWGenerators. + For an effect, you could choose one of: + ePlugInCategory_None, ePlugInCategory_EQ, ePlugInCategory_Dynamics, + ePlugInCategory_PitchShift, ePlugInCategory_Reverb, ePlugInCategory_Delay, + ePlugInCategory_Modulation, ePlugInCategory_Harmonic, ePlugInCategory_NoiseReduction, + ePlugInCategory_Dither, ePlugInCategory_SoundField + + (All values are listed in FicPluginEnums.h) +*/ +#if JucePlugin_IsSynth + #define JucePlugin_RTASCategory ePlugInCategory_SWGenerators +#else + #define JucePlugin_RTASCategory ePlugInCategory_None +#endif + +/** A 4-character manufacturer code - this is your company name. + You can leave this using the generic value JucePlugin_ManufacturerCode, or + override it if necessary. +*/ +#define JucePlugin_RTASManufacturerCode JucePlugin_ManufacturerCode + +/** A 4-character plugin ID code that should be unique. + You can leave this using the generic value JucePlugin_PluginCode, or + override it if necessary. +*/ +#define JucePlugin_RTASProductId JucePlugin_PluginCode + + +//============================================================================== + +#endif diff --git a/extras/audio plugins/wrapper/formats/AudioUnit/juce_AudioUnitWrapper.cpp b/extras/audio plugins/wrapper/formats/AudioUnit/juce_AudioUnitWrapper.cpp new file mode 100644 index 0000000000..102313ec35 --- /dev/null +++ b/extras/audio plugins/wrapper/formats/AudioUnit/juce_AudioUnitWrapper.cpp @@ -0,0 +1,948 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +#include +#include "AUMIDIEffectBase.h" +#include "MusicDeviceBase.h" +#include "AUCarbonViewBase.h" +#include "../../juce_IncludeCharacteristics.h" +#include "../../../../../juce.h" + +//============================================================================== +#define juceFilterObjectPropertyID 0x1a45ffe9 +static VoidArray activePlugins; + +static const short channelConfigs[][2] = { JucePlugin_PreferredChannelConfigurations }; +static const int numChannelConfigs = numElementsInArray (channelConfigs); + +BEGIN_JUCE_NAMESPACE +extern void juce_setCurrentExecutableFileNameFromBundleId (const String& bundleId) throw(); +END_JUCE_NAMESPACE + +#if JucePlugin_IsSynth + #define JuceAUBaseClass MusicDeviceBase +#else + #define JuceAUBaseClass AUMIDIEffectBase +#endif + +//============================================================================== +/** Somewhere in the codebase of your plugin, you need to implement this function + and make it create an instance of the filter subclass that you're building. +*/ +extern AudioProcessor* JUCE_CALLTYPE createPluginFilter(); + + +//============================================================================== +class JuceAU : public JuceAUBaseClass, + public AudioProcessorListener, + public AudioPlayHead +{ +public: + //============================================================================== + JuceAU (AudioUnit component) +#if JucePlugin_IsSynth + : MusicDeviceBase (component, 0, 1), +#else + : AUMIDIEffectBase (component), +#endif + juceFilter (0), + bufferSpace (2, 16), + channels (0), + prepared (false) + { + CreateElements(); + + if (activePlugins.size() == 0) + { + initialiseJuce_GUI(); + +#ifdef JucePlugin_CFBundleIdentifier + juce_setCurrentExecutableFileNameFromBundleId (JucePlugin_CFBundleIdentifier); +#endif + + MessageManager::getInstance()->setTimeBeforeShowingWaitCursor (0); + } + + juceFilter = createPluginFilter(); + juceFilter->setPlayHead (this); + juceFilter->addListener (this); + + jassert (juceFilter != 0); + Globals()->UseIndexedParameters (juceFilter->getNumParameters()); + + activePlugins.add (this); + + zerostruct (auEvent); + auEvent.mArgument.mParameter.mAudioUnit = GetComponentInstance(); + auEvent.mArgument.mParameter.mScope = kAudioUnitScope_Global; + auEvent.mArgument.mParameter.mElement = 0; + } + + ~JuceAU() + { + delete juceFilter; + juceFilter = 0; + + juce_free (channels); + channels = 0; + + jassert (activePlugins.contains (this)); + activePlugins.removeValue (this); + + if (activePlugins.size() == 0) + shutdownJuce_GUI(); + } + + //============================================================================== + ComponentResult GetPropertyInfo (AudioUnitPropertyID inID, + AudioUnitScope inScope, + AudioUnitElement inElement, + UInt32& outDataSize, + Boolean& outWritable) + { + if (inScope == kAudioUnitScope_Global) + { + if (inID == juceFilterObjectPropertyID) + { + outWritable = false; + outDataSize = sizeof (void*); + return noErr; + } + } + + return JuceAUBaseClass::GetPropertyInfo (inID, inScope, inElement, outDataSize, outWritable); + } + + ComponentResult GetProperty (AudioUnitPropertyID inID, + AudioUnitScope inScope, + AudioUnitElement inElement, + void* outData) + { + if (inScope == kAudioUnitScope_Global) + { + if (inID == juceFilterObjectPropertyID) + { + *((void**) outData) = (void*) juceFilter; + return noErr; + } + } + + return JuceAUBaseClass::GetProperty (inID, inScope, inElement, outData); + } + + ComponentResult SaveState (CFPropertyListRef* outData) + { + ComponentResult err = JuceAUBaseClass::SaveState (outData); + + if (err != noErr) + return err; + + jassert (CFGetTypeID (*outData) == CFDictionaryGetTypeID()); + + CFMutableDictionaryRef dict = (CFMutableDictionaryRef) *outData; + + if (juceFilter != 0) + { + MemoryBlock state; + juceFilter->getCurrentProgramStateInformation (state); + + if (state.getSize() > 0) + { + CFDataRef ourState = CFDataCreate (kCFAllocatorDefault, (const uint8*) state, state.getSize()); + CFDictionarySetValue (dict, CFSTR("jucePluginState"), ourState); + CFRelease (ourState); + } + } + + return noErr; + } + + ComponentResult RestoreState (CFPropertyListRef inData) + { + ComponentResult err = JuceAUBaseClass::RestoreState (inData); + + if (err != noErr) + return err; + + if (juceFilter != 0) + { + CFDictionaryRef dict = (CFDictionaryRef) inData; + CFDataRef data = 0; + + if (CFDictionaryGetValueIfPresent (dict, CFSTR("jucePluginState"), + (const void**) &data)) + { + if (data != 0) + { + const int numBytes = (int) CFDataGetLength (data); + const uint8* const rawBytes = CFDataGetBytePtr (data); + + if (numBytes > 0) + juceFilter->setCurrentProgramStateInformation (rawBytes, numBytes); + } + } + } + + return noErr; + } + + UInt32 SupportedNumChannels (const AUChannelInfo** outInfo) + { + // You need to actually add some configurations to the JucePlugin_PreferredChannelConfigurations + // value in your JucePluginCharacteristics.h file.. + jassert (numChannelConfigs > 0); + + if (outInfo != 0) + { + for (int i = 0; i < numChannelConfigs; ++i) + { +#if JucePlugin_IsSynth + channelInfo[i].inChannels = 0; +#else + channelInfo[i].inChannels = channelConfigs[i][0]; +#endif + channelInfo[i].outChannels = channelConfigs[i][1]; + + outInfo[i] = channelInfo + i; + } + } + + return numChannelConfigs; + } + + //============================================================================== + ComponentResult GetParameterInfo (AudioUnitScope inScope, + AudioUnitParameterID inParameterID, + AudioUnitParameterInfo& outParameterInfo) + { + const int index = (int) inParameterID; + + if (inScope == kAudioUnitScope_Global + && juceFilter != 0 + && index < juceFilter->getNumParameters()) + { + outParameterInfo.flags = kAudioUnitParameterFlag_IsWritable + | kAudioUnitParameterFlag_IsReadable + | kAudioUnitParameterFlag_HasCFNameString; + + const String name (juceFilter->getParameterName (index)); + + // set whether the param is automatable (unnamed parameters aren't allowed to be automated) + if (name.isEmpty() || ! juceFilter->isParameterAutomatable (index)) + outParameterInfo.flags |= kAudioUnitParameterFlag_NonRealTime; + + AUBase::FillInParameterName (outParameterInfo, + PlatformUtilities::juceStringToCFString (name), + false); + + outParameterInfo.minValue = 0.0f; + outParameterInfo.maxValue = 1.0f; + outParameterInfo.defaultValue = 0.0f; + outParameterInfo.unit = kAudioUnitParameterUnit_Generic; + + return noErr; + } + else + { + return kAudioUnitErr_InvalidParameter; + } + } + + ComponentResult GetParameter (AudioUnitParameterID inID, + AudioUnitScope inScope, + AudioUnitElement inElement, + Float32& outValue) + { + if (inScope == kAudioUnitScope_Global && juceFilter != 0) + { + outValue = juceFilter->getParameter ((int) inID); + return noErr; + } + + return AUBase::GetParameter (inID, inScope, inElement, outValue); + } + + ComponentResult SetParameter (AudioUnitParameterID inID, + AudioUnitScope inScope, + AudioUnitElement inElement, + Float32 inValue, + UInt32 inBufferOffsetInFrames) + { + if (inScope == kAudioUnitScope_Global && juceFilter != 0) + { + juceFilter->setParameter ((int) inID, inValue); + return noErr; + } + + return AUBase::SetParameter (inID, inScope, inElement, inValue, inBufferOffsetInFrames); + } + + //============================================================================== + ComponentResult Version() { return JucePlugin_VersionCode; } + + bool SupportsTail() { return true; } + Float64 GetTailTime() { return 0; } + + Float64 GetSampleRate() + { + return GetOutput(0)->GetStreamFormat().mSampleRate; + } + + Float64 GetLatency() + { + jassert (GetSampleRate() > 0); + + if (GetSampleRate() <= 0) + return 0.0; + + return juceFilter->getLatencySamples() / GetSampleRate(); + } + + //============================================================================== + int GetNumCustomUIComponents() { return 1; } + + void GetUIComponentDescs (ComponentDescription* inDescArray) + { + inDescArray[0].componentType = kAudioUnitCarbonViewComponentType; + inDescArray[0].componentSubType = JucePlugin_AUSubType; + inDescArray[0].componentManufacturer = JucePlugin_AUManufacturerCode; + inDescArray[0].componentFlags = 0; + inDescArray[0].componentFlagsMask = 0; + } + + //============================================================================== + bool getCurrentPosition (AudioPlayHead::CurrentPositionInfo& info) + { + info.timeSigNumerator = 0; + info.timeSigDenominator = 0; + info.timeInSeconds = 0; + info.editOriginTime = 0; + info.ppqPositionOfLastBarStart = 0; + info.isPlaying = false; + info.isRecording = false; + + switch (lastSMPTETime.mType) + { + case kSMPTETimeType24: + info.frameRate = AudioPlayHead::fps24; + break; + + case kSMPTETimeType25: + info.frameRate = AudioPlayHead::fps25; + break; + + case kSMPTETimeType30Drop: + info.frameRate = AudioPlayHead::fps30drop; + break; + + case kSMPTETimeType30: + info.frameRate = AudioPlayHead::fps30; + break; + + case kSMPTETimeType2997: + info.frameRate = AudioPlayHead::fps2997; + break; + + case kSMPTETimeType2997Drop: + info.frameRate = AudioPlayHead::fps2997drop; + break; + + //case kSMPTETimeType60: + //case kSMPTETimeType5994: + default: + info.frameRate = AudioPlayHead::fpsUnknown; + break; + } + + if (CallHostBeatAndTempo (&info.ppqPosition, &info.bpm) != noErr) + { + info.ppqPosition = 0; + info.bpm = 0; + } + + UInt32 outDeltaSampleOffsetToNextBeat; + double outCurrentMeasureDownBeat; + float num; + UInt32 den; + + if (CallHostMusicalTimeLocation (&outDeltaSampleOffsetToNextBeat, &num, &den, + &outCurrentMeasureDownBeat) == noErr) + { + info.timeSigNumerator = (int) num; + info.timeSigDenominator = den; + info.ppqPositionOfLastBarStart = outCurrentMeasureDownBeat; + } + + double outCurrentSampleInTimeLine, outCycleStartBeat, outCycleEndBeat; + Boolean playing, playchanged, looping; + + if (CallHostTransportState (&playing, + &playchanged, + &outCurrentSampleInTimeLine, + &looping, + &outCycleStartBeat, + &outCycleEndBeat) == noErr) + { + info.isPlaying = playing; + info.timeInSeconds = outCurrentSampleInTimeLine / GetSampleRate(); + } + + return true; + } + + void sendAUEvent (const AudioUnitEventType type, const int index) throw() + { + if (AUEventListenerNotify != 0) + { + auEvent.mEventType = type; + auEvent.mArgument.mParameter.mParameterID = (AudioUnitParameterID) index; + AUEventListenerNotify (0, 0, &auEvent); + } + } + + void audioProcessorParameterChanged (AudioProcessor*, int index, float newValue) + { + sendAUEvent (kAudioUnitEvent_ParameterValueChange, index); + } + + void audioProcessorParameterChangeGestureBegin (AudioProcessor*, int index) + { + sendAUEvent (kAudioUnitEvent_BeginParameterChangeGesture, index); + } + + void audioProcessorParameterChangeGestureEnd (AudioProcessor*, int index) + { + sendAUEvent (kAudioUnitEvent_EndParameterChangeGesture, index); + } + + void audioProcessorChanged (AudioProcessor*) + { + // xxx is there an AU equivalent? + } + + bool StreamFormatWritable (AudioUnitScope inScope, AudioUnitElement element) + { + return ! IsInitialized(); + } + + ComponentResult StartNote (MusicDeviceInstrumentID, MusicDeviceGroupID, NoteInstanceID&, UInt32, const MusicDeviceNoteParams&) + { + return noErr; + } + + ComponentResult StopNote (MusicDeviceGroupID, NoteInstanceID, UInt32) + { + return noErr; + } + + //============================================================================== + ComponentResult Initialize() + { +#if ! JucePlugin_IsSynth + const int numIns = GetInput(0) != 0 ? GetInput(0)->GetStreamFormat().mChannelsPerFrame : 0; +#endif + const int numOuts = GetOutput(0) != 0 ? GetOutput(0)->GetStreamFormat().mChannelsPerFrame : 0; + + bool isValidChannelConfig = false; + + for (int i = 0; i < numChannelConfigs; ++i) +#if JucePlugin_IsSynth + if (numOuts == channelConfigs[i][1]) +#else + if (numIns == channelConfigs[i][0] && numOuts == channelConfigs[i][1]) +#endif + isValidChannelConfig = true; + + if (! isValidChannelConfig) + return kAudioUnitErr_FormatNotSupported; + + JuceAUBaseClass::Initialize(); + prepareToPlay(); + return noErr; + } + + void Cleanup() + { + JuceAUBaseClass::Cleanup(); + + if (juceFilter != 0) + juceFilter->releaseResources(); + + bufferSpace.setSize (2, 16); + midiEvents.clear(); + prepared = false; + } + + ComponentResult Reset (AudioUnitScope inScope, AudioUnitElement inElement) + { + if (! prepared) + prepareToPlay(); + + return JuceAUBaseClass::Reset (inScope, inElement); + } + + void prepareToPlay() + { + if (juceFilter != 0) + { +#if ! JucePlugin_IsSynth + juceFilter->setPlayConfigDetails (GetInput(0)->GetStreamFormat().mChannelsPerFrame, +#else + juceFilter->setPlayConfigDetails (0, +#endif + GetOutput(0)->GetStreamFormat().mChannelsPerFrame, + GetSampleRate(), + GetMaxFramesPerSlice()); + + bufferSpace.setSize (juceFilter->getNumInputChannels() + juceFilter->getNumOutputChannels(), + GetMaxFramesPerSlice() + 32); + + juceFilter->prepareToPlay (GetSampleRate(), + GetMaxFramesPerSlice()); + + midiEvents.clear(); + + juce_free (channels); + channels = (float**) juce_calloc (sizeof (float*) * jmax (juceFilter->getNumInputChannels(), + juceFilter->getNumOutputChannels()) + 4); + + prepared = true; + } + } + + ComponentResult Render (AudioUnitRenderActionFlags &ioActionFlags, + const AudioTimeStamp& inTimeStamp, + UInt32 nFrames) + { + lastSMPTETime = inTimeStamp.mSMPTETime; + +#if ! JucePlugin_IsSynth + return JuceAUBaseClass::Render (ioActionFlags, inTimeStamp, nFrames); +#else + // synths can't have any inputs.. + AudioBufferList inBuffer; + inBuffer.mNumberBuffers = 0; + + return ProcessBufferLists (ioActionFlags, inBuffer, GetOutput(0)->GetBufferList(), nFrames); +#endif + } + + + OSStatus ProcessBufferLists (AudioUnitRenderActionFlags& ioActionFlags, + const AudioBufferList& inBuffer, + AudioBufferList& outBuffer, + UInt32 numSamples) + { + if (juceFilter != 0) + { + jassert (prepared); + + int numOutChans = 0; + int nextSpareBufferChan = 0; + bool needToReinterleave = false; + const int numIn = juceFilter->getNumInputChannels(); + const int numOut = juceFilter->getNumOutputChannels(); + + unsigned int i; + for (i = 0; i < outBuffer.mNumberBuffers; ++i) + { + AudioBuffer& buf = outBuffer.mBuffers[i]; + + if (buf.mNumberChannels == 1) + { + channels [numOutChans++] = (float*) buf.mData; + } + else + { + needToReinterleave = true; + + for (unsigned int subChan = 0; subChan < buf.mNumberChannels && numOutChans < numOut; ++subChan) + channels [numOutChans++] = bufferSpace.getSampleData (nextSpareBufferChan++); + } + + if (numOutChans >= numOut) + break; + } + + int numInChans = 0; + + for (i = 0; i < inBuffer.mNumberBuffers; ++i) + { + const AudioBuffer& buf = inBuffer.mBuffers[i]; + + if (buf.mNumberChannels == 1) + { + if (numInChans < numOutChans) + memcpy (channels [numInChans], (const float*) buf.mData, sizeof (float) * numSamples); + else + channels [numInChans] = (float*) buf.mData; + + ++numInChans; + } + else + { + // need to de-interleave.. + for (unsigned int subChan = 0; subChan < buf.mNumberChannels && numInChans < numIn; ++subChan) + { + float* dest; + + if (numInChans < numOutChans) + { + dest = channels [numInChans++]; + } + else + { + dest = bufferSpace.getSampleData (nextSpareBufferChan++); + channels [numInChans++] = dest; + } + + const float* src = ((const float*) buf.mData) + subChan; + + for (int j = numSamples; --j >= 0;) + { + *dest++ = *src; + src += buf.mNumberChannels; + } + } + } + + if (numInChans >= numIn) + break; + } + + { + AudioSampleBuffer buffer (channels, jmax (numIn, numOut), numSamples); + + const ScopedLock sl (juceFilter->getCallbackLock()); + + if (juceFilter->isSuspended()) + { + for (int i = 0; i < numOut; ++i) + zeromem (channels [i], sizeof (float) * numSamples); + } + else + { + juceFilter->processBlock (buffer, midiEvents); + } + } + + if (! midiEvents.isEmpty()) + { +#if JucePlugin_ProducesMidiOutput + const uint8* midiEventData; + int midiEventSize, midiEventPosition; + MidiBuffer::Iterator i (midiEvents); + + while (i.getNextEvent (midiEventData, midiEventSize, midiEventPosition)) + { + jassert (((unsigned int) midiEventPosition) < (unsigned int) numSamples); + + + + //xxx + } +#else + // if your plugin creates midi messages, you'll need to set + // the JucePlugin_ProducesMidiOutput macro to 1 in your + // JucePluginCharacteristics.h file + //jassert (midiEvents.getNumEvents() <= numMidiEventsComingIn); +#endif + midiEvents.clear(); + } + + if (needToReinterleave) + { + nextSpareBufferChan = 0; + + for (i = 0; i < outBuffer.mNumberBuffers; ++i) + { + AudioBuffer& buf = outBuffer.mBuffers[i]; + + if (buf.mNumberChannels > 1) + { + for (unsigned int subChan = 0; subChan < buf.mNumberChannels; ++subChan) + { + const float* src = bufferSpace.getSampleData (nextSpareBufferChan++); + float* dest = ((float*) buf.mData) + subChan; + + for (int j = numSamples; --j >= 0;) + { + *dest = *src++; + dest += buf.mNumberChannels; + } + } + } + } + } + +#if ! JucePlugin_SilenceInProducesSilenceOut + ioActionFlags &= ~kAudioUnitRenderAction_OutputIsSilence; +#endif + } + + return noErr; + } + +protected: + OSStatus HandleMidiEvent (UInt8 nStatus, + UInt8 inChannel, + UInt8 inData1, + UInt8 inData2, + long inStartFrame) + { +#if JucePlugin_WantsMidiInput + uint8 data [4]; + data[0] = nStatus | inChannel; + data[1] = inData1; + data[2] = inData2; + + midiEvents.addEvent (data, 3, inStartFrame); +#endif + + return noErr; + } + + //============================================================================== +private: + AudioProcessor* juceFilter; + AudioSampleBuffer bufferSpace; + float** channels; + MidiBuffer midiEvents; + bool prepared; + SMPTETime lastSMPTETime; + AUChannelInfo channelInfo [numChannelConfigs]; + AudioUnitEvent auEvent; +}; + + +//============================================================================== +class JuceAUComponentHolder : public Component +{ +public: + JuceAUComponentHolder (Component* const editorComp) + { + addAndMakeVisible (editorComp); + setOpaque (true); + setVisible (true); + setBroughtToFrontOnMouseClick (true); + +#if ! JucePlugin_EditorRequiresKeyboardFocus + setWantsKeyboardFocus (false); +#endif + } + + ~JuceAUComponentHolder() + { + } + + void resized() + { + if (getNumChildComponents() > 0) + getChildComponent (0)->setBounds (0, 0, getWidth(), getHeight()); + } + + void paint (Graphics& g) + { + } +}; + +//============================================================================== +class JuceAUView : public AUCarbonViewBase, + public ComponentListener, + public MouseListener, + public Timer +{ + AudioProcessor* juceFilter; + AudioProcessorEditor* editorComp; + Component* windowComp; + bool recursive; + int mx, my; + +public: + JuceAUView (AudioUnitCarbonView auview) + : AUCarbonViewBase (auview), + juceFilter (0), + editorComp (0), + windowComp (0), + recursive (false), + mx (0), + my (0) + { + } + + ~JuceAUView() + { + deleteUI(); + } + + ComponentResult CreateUI (Float32 inXOffset, Float32 inYOffset) + { + if (juceFilter == 0) + { + UInt32 propertySize = sizeof (&juceFilter); + + AudioUnitGetProperty (GetEditAudioUnit(), + juceFilterObjectPropertyID, + kAudioUnitScope_Global, + 0, + &juceFilter, + &propertySize); + } + + if (juceFilter != 0) + { + deleteUI(); + + editorComp = juceFilter->createEditorIfNeeded(); + + const int w = editorComp->getWidth(); + const int h = editorComp->getHeight(); + + editorComp->setOpaque (true); + editorComp->setVisible (true); + + windowComp = new JuceAUComponentHolder (editorComp); + windowComp->setBounds ((int) inXOffset, (int) inYOffset, w, h); + + windowComp->addToDesktop (0, (void*) mCarbonPane); + SizeControl (mCarbonPane, w, h); + + editorComp->addComponentListener (this); + windowComp->addMouseListener (this, true); + + startTimer (20); + } + else + { + jassertfalse // can't get a pointer to our effect + } + + return noErr; + } + + void componentMovedOrResized (Component& component, + bool wasMoved, + bool wasResized) + { + if (! recursive) + { + recursive = true; + + if (editorComp != 0 && wasResized) + { + const int w = jmax (32, editorComp->getWidth()); + const int h = jmax (32, editorComp->getHeight()); + + SizeControl (mCarbonPane, w, h); + + if (windowComp->getWidth() != w + || windowComp->getHeight() != h) + { + windowComp->setSize (w, h); + } + + editorComp->repaint(); + } + + recursive = false; + } + } + + void timerCallback() + { + // for some stupid Apple-related reason, mouse move events just don't seem to get sent + // to the windows in an AU, so we have to bodge it here and simulate them with a + // timer.. + if (editorComp != 0) + { + int x, y; + Desktop::getInstance().getMousePosition (x, y); + + if (x != mx || y != my) + { + mx = x; + my = y; + + if (! ModifierKeys::getCurrentModifiers().isAnyMouseButtonDown()) + { + for (int i = ComponentPeer::getNumPeers(); --i >= 0;) + { + ComponentPeer* const peer = ComponentPeer::getPeer (i); + + int rx = x, ry = y; + peer->getComponent()->globalPositionToRelative (rx, ry); + + if (peer->contains (rx, ry, false) && peer->getComponent()->isShowing()) + { + peer->handleMouseMove (rx, ry, Time::currentTimeMillis()); + break; + } + } + } + } + } + } + + void mouseMove (const MouseEvent& e) + { + Desktop::getInstance().getMousePosition (mx, my); + startTimer (20); + } + +private: + void deleteUI() + { + PopupMenu::dismissAllActiveMenus(); + + // there's some kind of component currently modal, but the host + // is trying to delete our plugin.. + jassert (Component::getCurrentlyModalComponent() == 0); + + if (editorComp != 0) + juceFilter->editorBeingDeleted (editorComp); + + deleteAndZero (editorComp); + deleteAndZero (windowComp); + } +}; + +//============================================================================== +#define JUCE_COMPONENT_ENTRYX(Class, Name, Suffix) \ +extern "C" __attribute__((visibility("default"))) ComponentResult Name ## Suffix (ComponentParameters* params, Class* obj); \ +extern "C" __attribute__((visibility("default"))) ComponentResult Name ## Suffix (ComponentParameters* params, Class* obj) \ +{ \ + return ComponentEntryPoint::Dispatch(params, obj); \ +} + +#define JUCE_COMPONENT_ENTRY(Class, Name, Suffix) JUCE_COMPONENT_ENTRYX(Class, Name, Suffix) + +JUCE_COMPONENT_ENTRY (JuceAU, JucePlugin_AUExportPrefix, Entry) +JUCE_COMPONENT_ENTRY (JuceAUView, JucePlugin_AUExportPrefix, ViewEntry) diff --git a/extras/audio plugins/wrapper/formats/AudioUnit/juce_AudioUnitWrapper.r b/extras/audio plugins/wrapper/formats/AudioUnit/juce_AudioUnitWrapper.r new file mode 100644 index 0000000000..5d32214260 --- /dev/null +++ b/extras/audio plugins/wrapper/formats/AudioUnit/juce_AudioUnitWrapper.r @@ -0,0 +1,70 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +#include +#include + +//============================================================================== +/* The JucePluginCharacteristics.h file is supposed to live in your plugin-specific + project directory, and has to contain info describing its name, type, etc. For + more info, see the JucePluginCharacteristics.h that is included in the demo plugin. + + You may need to adjust the include path of your project to make sure it can be + found by this include statement. (Don't hack this file to change the include path) +*/ +#include "JucePluginCharacteristics.h" + + +//============================================================================== +// component resources for Audio Unit +#define RES_ID 1000 +#define COMP_TYPE JucePlugin_AUMainType +#define COMP_SUBTYPE JucePlugin_AUSubType +#define COMP_MANUF JucePlugin_AUManufacturerCode +#define VERSION JucePlugin_VersionCode +#define NAME JucePlugin_Manufacturer ": " JucePlugin_Name +#define DESCRIPTION JucePlugin_Desc +#define ENTRY_POINT JucePlugin_AUExportPrefixQuoted "Entry" + +#include "/Developer/Examples/CoreAudio/AudioUnits/AUPublic/AUBase/AUResources.r" + +//============================================================================== +// component resources for Audio Unit Carbon View +#define RES_ID 2000 +#define COMP_TYPE kAudioUnitCarbonViewComponentType +#define COMP_SUBTYPE JucePlugin_AUSubType +#define COMP_MANUF JucePlugin_AUManufacturerCode +#define VERSION JucePlugin_VersionCode +#define NAME JucePlugin_Manufacturer ": " JucePlugin_Name " View" +#define DESCRIPTION NAME +#define ENTRY_POINT JucePlugin_AUExportPrefixQuoted "ViewEntry" + +#include "/Developer/Examples/CoreAudio/AudioUnits/AUPublic/AUBase/AUResources.r" diff --git a/extras/audio plugins/wrapper/formats/RTAS/DefaultResourceFile b/extras/audio plugins/wrapper/formats/RTAS/DefaultResourceFile new file mode 100644 index 0000000000..d8bfb4a1c8 Binary files /dev/null and b/extras/audio plugins/wrapper/formats/RTAS/DefaultResourceFile differ diff --git a/extras/audio plugins/wrapper/formats/RTAS/DummyResourceFile.r b/extras/audio plugins/wrapper/formats/RTAS/DummyResourceFile.r new file mode 100644 index 0000000000..b607d8d1be --- /dev/null +++ b/extras/audio plugins/wrapper/formats/RTAS/DummyResourceFile.r @@ -0,0 +1,4 @@ + +// This dummy file is added to the resources section of the project to +// force XCode to create some resources for the dpm. If there aren't any +// resources, PT would refuse to load the plugin.. \ No newline at end of file diff --git a/extras/audio plugins/wrapper/formats/RTAS/juce_RTASCompileFlags.h b/extras/audio plugins/wrapper/formats/RTAS/juce_RTASCompileFlags.h new file mode 100644 index 0000000000..2427003106 --- /dev/null +++ b/extras/audio plugins/wrapper/formats/RTAS/juce_RTASCompileFlags.h @@ -0,0 +1,63 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +#ifndef __JUCE_RTASCOMPILEFLAGS_JUCEHEADER__ +#define __JUCE_RTASCOMPILEFLAGS_JUCEHEADER__ + +#ifdef _MSC_VER + + #define kCompileAsCodeResource 0 + #define kBuildStandAlone 0 + #define kNoDSP 0 + #define kNoDAE 0 + #define kNoSDS 0 + #define kNoViews 0 + #define kUseDSPCodeDecode 0 + + #define WINDOWS_VERSION 1 + #define PLUGIN_SDK_BUILD 1 + #define PLUGIN_SDK_DIRECTMIDI 1 + +#else + + #define kCompileAsCodeResource 0 + #define kNoDSP 1 + #define kNoDAE 0 + #define kNoSDS 0 + #define kNoViews 0 + #define kUseDSPCodeDecode 0 + + #define PLUGIN_SDK_BUILD 1 + #define PLUGIN_SDK_DIRECTMIDI 1 + +#endif + +#endif // __JUCE_RTASCOMPILEFLAGS_JUCEHEADER__ diff --git a/extras/audio plugins/wrapper/formats/RTAS/juce_RTASUtilities.cpp b/extras/audio plugins/wrapper/formats/RTAS/juce_RTASUtilities.cpp new file mode 100644 index 0000000000..acaf0e8924 --- /dev/null +++ b/extras/audio plugins/wrapper/formats/RTAS/juce_RTASUtilities.cpp @@ -0,0 +1,139 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +#if _MSC_VER + +// (these functions are in a separate file because of problems including windows.h +// at the same time as the Digi headers) + +#include + +#ifdef _MSC_VER + #pragma pack (push, 8) +#endif + +#include "../../../../../juce.h" + +#ifdef _MSC_VER + #pragma pack (pop) +#endif + + +//============================================================================== +void JUCE_CALLTYPE attachSubWindow (void* hostWindow, + int& titleW, int& titleH, + Component* comp) +{ + RECT clientRect; + GetClientRect ((HWND) hostWindow, &clientRect); + + titleW = clientRect.right - clientRect.left; + titleH = jmax (0, (clientRect.bottom - clientRect.top) - comp->getHeight()); + comp->setTopLeftPosition (0, titleH); + + comp->addToDesktop (0); + + HWND plugWnd = (HWND) comp->getWindowHandle(); + SetParent (plugWnd, (HWND) hostWindow); + + DWORD val = GetWindowLong (plugWnd, GWL_STYLE); + val = (val & ~WS_POPUP) | WS_CHILD; + SetWindowLong (plugWnd, GWL_STYLE, val); +} + +void JUCE_CALLTYPE resizeHostWindow (void* hostWindow, + int& titleW, int& titleH, + Component* comp) +{ + RECT clientRect, windowRect; + GetClientRect ((HWND) hostWindow, &clientRect); + GetWindowRect ((HWND) hostWindow, &windowRect); + const int borderW = (windowRect.right - windowRect.left) - (clientRect.right - clientRect.left); + const int borderH = (windowRect.bottom - windowRect.top) - (clientRect.bottom - clientRect.top); + + SetWindowPos ((HWND) hostWindow, 0, 0, 0, + borderW + jmax (titleW, comp->getWidth()), + borderH + comp->getHeight() + titleH, + SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOOWNERZORDER); +} + +#if ! JucePlugin_EditorRequiresKeyboardFocus + +static HWND findMDIParentOf (HWND w) +{ + const int frameThickness = GetSystemMetrics (SM_CYFIXEDFRAME); + + while (w != 0) + { + HWND parent = GetParent (w); + + if (parent == 0) + break; + + TCHAR windowType [32]; + zeromem (windowType, sizeof (windowType)); + GetClassName (parent, windowType, 31); + + if (String (windowType).equalsIgnoreCase (T("MDIClient"))) + { + w = parent; + break; + } + + RECT windowPos; + GetWindowRect (w, &windowPos); + + RECT parentPos; + GetWindowRect (parent, &parentPos); + + int dw = (parentPos.right - parentPos.left) - (windowPos.right - windowPos.left); + int dh = (parentPos.bottom - parentPos.top) - (windowPos.bottom - windowPos.top); + + if (dw > 100 || dh > 100) + break; + + w = parent; + + if (dw == 2 * frameThickness) + break; + } + + return w; +} + +void JUCE_CALLTYPE passFocusToHostWindow (void* hostWindow) +{ + SetFocus (findMDIParentOf ((HWND) hostWindow)); +} + +#endif + +#endif diff --git a/extras/audio plugins/wrapper/formats/RTAS/juce_RTASWrapper.cpp b/extras/audio plugins/wrapper/formats/RTAS/juce_RTASWrapper.cpp new file mode 100644 index 0000000000..812d8c8217 --- /dev/null +++ b/extras/audio plugins/wrapper/formats/RTAS/juce_RTASWrapper.cpp @@ -0,0 +1,1092 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +#include "juce_RTASCompileFlags.h" + +#ifdef _MSC_VER + // the Digidesign projects all use a struct alignment of 2.. + #pragma pack (2) + #pragma warning (disable: 4267) + + #include "ForcedInclude.h" + #include "Mac2Win.H" +#endif + +/* Note about include paths + ------------------------ + + To be able to include all the Digidesign headers correctly, you'll need to add this + lot to your include path: + + c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\EffectClasses + c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ProcessClasses + c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ProcessClasses\Interfaces + c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Utilities + c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\RTASP_Adapt + c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\CoreClasses + c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Controls + c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Meters + c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ViewClasses + c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\DSPClasses + c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Interfaces + c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\common + c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\common\Platform + c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\SignalProcessing\Public + c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugIns\DSPManager\Interfaces + c:\yourdirectory\PT_711_SDK\AlturaPorts\SADriver\Interfaces + c:\yourdirectory\PT_711_SDK\AlturaPorts\DigiPublic\Interfaces + c:\yourdirectory\PT_711_SDK\AlturaPorts\Fic\Interfaces\DAEClient + c:\yourdirectory\PT_711_SDK\AlturaPorts\NewFileLibs\Cmn + c:\yourdirectory\PT_711_SDK\AlturaPorts\NewFileLibs\DOA + c:\yourdirectory\PT_711_SDK\AlturaPorts\AlturaSource\PPC_H + c:\yourdirectory\PT_711_SDK\AlturaPorts\AlturaSource\AppSupport +*/ + +#include "CEffectGroupMIDI.h" +#include "CEffectProcessMIDI.h" +#include "CEffectProcessRTAS.h" +#include "CCustomView.h" +#include "CEffectTypeRTAS.h" +#include "CPluginControl.h" +#include "CPluginControl_OnOff.h" + +//============================================================================== +#ifdef _MSC_VER + #pragma pack (push, 8) +#endif + +#include "../../../../../juce.h" +#include "../../juce_IncludeCharacteristics.h" + +#ifdef _MSC_VER + #pragma pack (pop) +#endif + +#undef Component +#undef MemoryBlock + +//============================================================================== +#if JUCE_WIN32 + extern void JUCE_CALLTYPE attachSubWindow (void* hostWindow, int& titleW, int& titleH, juce::Component* comp); + extern void JUCE_CALLTYPE resizeHostWindow (void* hostWindow, int& titleW, int& titleH, juce::Component* comp); + #if ! JucePlugin_EditorRequiresKeyboardFocus + extern void JUCE_CALLTYPE passFocusToHostWindow (void* hostWindow); + #endif +#endif + +const int midiBufferSize = 1024; +const OSType juceChunkType = 'juce'; +static const int bypassControlIndex = 1; + +//============================================================================== +/** Somewhere in the codebase of your plugin, you need to implement this function + and make it return a new instance of the filter subclass that you're building. +*/ +extern AudioProcessor* JUCE_CALLTYPE createPluginFilter(); + + +//============================================================================== +static float longToFloat (const long n) throw() +{ + return (float) ((((double) n) + (double) 0x80000000) / (double) 0xffffffff); +} + +static long floatToLong (const float n) throw() +{ + return roundDoubleToInt (jlimit (-(double) 0x80000000, + (double) 0x7fffffff, + n * (double) 0xffffffff - (double) 0x80000000)); +} + +static int numInstances = 0; + +//============================================================================== +class JucePlugInProcess : public CEffectProcessMIDI, + public CEffectProcessRTAS, + public AudioProcessorListener, + public AudioPlayHead, + public AsyncUpdater +{ +public: + //============================================================================== + JucePlugInProcess() + : channels (0), + prepared (false), + midiBufferNode (0), + midiTransport (0), + sampleRate (44100.0) + { + juceFilter = createPluginFilter(); + jassert (juceFilter != 0); + + AddChunk (juceChunkType, "Juce Audio Plugin Data"); + + ++numInstances; + } + + ~JucePlugInProcess() + { + if (mLoggedIn) + MIDILogOut(); + + deleteAndZero (midiBufferNode); + deleteAndZero (midiTransport); + + if (prepared) + juceFilter->releaseResources(); + + delete juceFilter; + juce_free (channels); + + if (--numInstances == 0) + shutdownJuce_GUI(); + } + + //============================================================================== + class JuceCustomUIView : public CCustomView + { + public: + //============================================================================== + JuceCustomUIView (AudioProcessor* const filter_) + : filter (filter_), + editorComp (0), + wrapper (0) + { + // setting the size in here crashes PT for some reason, so keep it simple.. + } + + ~JuceCustomUIView() + { + deleteEditorComp(); + } + + //============================================================================== + void updateSize() + { + if (editorComp == 0) + { + editorComp = filter->createEditorIfNeeded(); + jassert (editorComp != 0); + } + + Rect r; + r.left = 0; + r.top = 0; + r.right = editorComp->getWidth(); + r.bottom = editorComp->getHeight(); + + SetRect (&r); + } + + void attachToWindow (GrafPtr port) + { + if (port != 0) + { + updateSize(); + +#if JUCE_WIN32 + void* const hostWindow = (void*) ASI_GethWnd ((WindowPtr) port); +#else + void* const hostWindow = (void*) GetWindowFromPort (port); +#endif + deleteAndZero (wrapper); + + wrapper = new EditorCompWrapper (hostWindow, editorComp, this); + } + else + { + deleteEditorComp(); + } + } + + void DrawContents (Rect*) + { + if (wrapper != 0) + { + ComponentPeer* const peer = wrapper->getPeer(); + + if (peer != 0) + { +#if JUCE_WIN32 + // (seems to be required in PT6.4, but not in 7.x) + peer->repaint (0, 0, wrapper->getWidth(), wrapper->getHeight()); + +#elif JUCE_PPC + // This crap is needed because if you resize a window, PT doesn't + // update its clip region, so only part of your new window gets drawn. + // This overrides the clipping region that's being passed into the Draw + // method. + Rect visible; + GetVisibleRect (&visible); + + RestoreFocus(); + Focus (&visible); +#endif + peer->performAnyPendingRepaintsNow(); + } + } + } + + void DrawBackground (Rect* r) + { + } + + //============================================================================== + private: + AudioProcessor* const filter; + juce::Component* wrapper; + AudioProcessorEditor* editorComp; + + void deleteEditorComp() + { + if (editorComp != 0) + { + PopupMenu::dismissAllActiveMenus(); + + juce::Component* const modalComponent = juce::Component::getCurrentlyModalComponent(); + if (modalComponent != 0) + modalComponent->exitModalState (0); + + filter->editorBeingDeleted (editorComp); + deleteAndZero (editorComp); + deleteAndZero (wrapper); + } + } + + //============================================================================== + // A component to hold the AudioProcessorEditor, and cope with some housekeeping + // chores when it changes or repaints. + class EditorCompWrapper : public juce::Component, +#if JUCE_MAC + public Timer +#else + public FocusChangeListener +#endif + { + public: + EditorCompWrapper (void* const hostWindow_, + AudioProcessorEditor* const editorComp, + JuceCustomUIView* const owner_) + : hostWindow (hostWindow_), + owner (owner_), + titleW (0), + titleH (0) +#if JUCE_MAC + , forcedRepaintTimer (0) +#endif + { +#if ! JucePlugin_EditorRequiresKeyboardFocus + setWantsKeyboardFocus (false); +#endif + setOpaque (true); + setBroughtToFrontOnMouseClick (true); + setBounds (editorComp->getBounds()); + editorComp->setTopLeftPosition (0, 0); + addAndMakeVisible (editorComp); + +#if JUCE_WIN32 + attachSubWindow (hostWindow, titleW, titleH, this); + setVisible (true); +#else + SetAutomaticControlDragTrackingEnabledForWindow ((WindowRef) hostWindow_, true); + + WindowAttributes attributes; + GetWindowAttributes ((WindowRef) hostWindow_, &attributes); + + parentView = 0; + + if ((attributes & kWindowCompositingAttribute) != 0) + { + HIViewRef root = HIViewGetRoot ((WindowRef) hostWindow_); + HIViewFindByID (root, kHIViewWindowContentID, &parentView); + + if (parentView == 0) + parentView = root; + } + else + { + GetRootControl ((WindowRef) hostWindow_, (ControlRef*) &parentView); + + if (parentView == 0) + CreateRootControl ((WindowRef) hostWindow_, (ControlRef*) &parentView); + } + + jassert (parentView != 0); + Rect clientRect; + GetWindowBounds ((WindowRef) hostWindow, kWindowContentRgn, &clientRect); + + titleW = clientRect.right - clientRect.left; + titleH = jmax (0, (clientRect.bottom - clientRect.top) - getHeight()); + setTopLeftPosition (0, 0); + + HIViewSetNeedsDisplay (parentView, true); + + setVisible (true); + addToDesktop (ComponentPeer::windowRepaintedExplictly, (void*) parentView); + + HIViewRef pluginView = HIViewGetFirstSubview (parentView); + + #if ! JucePlugin_EditorRequiresKeyboardFocus + HIViewSetActivated (pluginView, false); + #endif + /* This is a convoluted and desperate workaround for a Digi (or maybe Apple) + layout bug. Until the parent control gets some kind of mouse-move + event, then our plugin's HIView remains stuck at (0, 0) in the + window (despite drawing correctly), which blocks mouse events from + getting to the widgets above it. + + After days of frustration the only hack I can find that works + is to use this arcane function to redirect mouse events to + the parent, while running a timer to spot the moment when our + view mysteriously snaps back to its correct location. + + If anyone at Digi or Apple is reading this and they realise that it's + their fault, could they please give me back the week of my life that + they made me waste on this rubbish. Thankyou. + */ + SetControlSupervisor (pluginView, parentView); + startTimer (150); +#endif + +#if JUCE_WIN32 && ! JucePlugin_EditorRequiresKeyboardFocus + Desktop::getInstance().addFocusChangeListener (this); +#endif + } + + ~EditorCompWrapper() + { +#if JUCE_WIN32 && ! JucePlugin_EditorRequiresKeyboardFocus + Desktop::getInstance().removeFocusChangeListener (this); +#endif + +#if JUCE_MAC + delete forcedRepaintTimer; +#endif + } + + void paint (Graphics&) + { +#if JUCE_MAC + if (forcedRepaintTimer != 0) + forcedRepaintTimer->stopTimer(); +#endif + } + + void resized() + { + juce::Component* const c = getChildComponent (0); + + if (c != 0) + c->setBounds (0, 0, getWidth(), getHeight()); + + repaint(); + } + +#if JUCE_MAC + void timerCallback() + { + // Wait for the moment when PT deigns to allow our view to + // take up its actual location (see rant above) + HIViewRef content = 0; + HIViewFindByID (HIViewGetRoot ((WindowRef) hostWindow), kHIViewWindowContentID, &content); + HIPoint p = { 0.0f, 0.0f }; + + HIViewRef v = HIViewGetFirstSubview (parentView); + HIViewConvertPoint (&p, v, content); + + if (p.y > 12) + { + HIViewRef v = HIViewGetFirstSubview (parentView); + SetControlSupervisor (v, 0); + stopTimer(); + + forcedRepaintTimer = new RepaintCheckTimer (*this); + } + } +#endif + +#if JUCE_WIN32 + void globalFocusChanged (juce::Component*) + { + #if ! JucePlugin_EditorRequiresKeyboardFocus + if (hasKeyboardFocus (true)) + passFocusToHostWindow (hostWindow); + #endif + } +#endif + + void childBoundsChanged (juce::Component* child) + { + setSize (child->getWidth(), child->getHeight()); + child->setTopLeftPosition (0, 0); + +#if JUCE_WIN32 + resizeHostWindow (hostWindow, titleW, titleH, this); +#else + Rect r; + GetWindowBounds ((WindowRef) hostWindow, kWindowContentRgn, &r); + + HIRect p; + zerostruct (p); + HIViewConvertRect (&p, parentView, 0); // find the X position of our view in case there's space to the left of it + + r.right = r.left + jmax (titleW, ((int) p.origin.x) + getWidth()); + r.bottom = r.top + getHeight() + titleH; + + SetWindowBounds ((WindowRef) hostWindow, kWindowContentRgn, &r); + + owner->updateSize(); + owner->Invalidate(); +#endif + } + + //============================================================================== + juce_UseDebuggingNewOperator + +#if JUCE_MAC + protected: + void internalRepaint (int x, int y, int w, int h) + { + Component::internalRepaint (x, y, w, h); + owner->Invalidate(); + + if (forcedRepaintTimer != 0 && ! forcedRepaintTimer->isTimerRunning()) + forcedRepaintTimer->startTimer (1000 / 25); + } + + HIViewRef parentView; +#endif + + private: + void* const hostWindow; + JuceCustomUIView* const owner; + int titleW, titleH; + +#if JUCE_MAC + // if PT makes us wait too long for a redraw after we've + // asked for one, this should kick in and force one to happen + class RepaintCheckTimer : public Timer + { + public: + RepaintCheckTimer (EditorCompWrapper& owner_) + : owner (owner_) + { + } + + void timerCallback() + { + stopTimer(); + ComponentPeer* const peer = owner.getPeer(); + + if (peer != 0) + peer->performAnyPendingRepaintsNow(); + } + + EditorCompWrapper& owner; + }; + + RepaintCheckTimer* forcedRepaintTimer; +#endif + }; + }; + + JuceCustomUIView* getView() const + { + return dynamic_cast (fOurPlugInView); + } + + void GetViewRect (Rect* size) + { + if (getView() != 0) + getView()->updateSize(); + + CEffectProcessRTAS::GetViewRect (size); + } + + CPlugInView* CreateCPlugInView() + { + return new JuceCustomUIView (juceFilter); + } + + void SetViewPort (GrafPtr port) + { + CEffectProcessRTAS::SetViewPort (port); + + if (getView() != 0) + getView()->attachToWindow (port); + } + + //============================================================================== +protected: + ComponentResult GetDelaySamplesLong (long* aNumSamples) + { + if (aNumSamples != 0) + *aNumSamples = juceFilter != 0 ? juceFilter->getLatencySamples() : 0; + + return noErr; + } + + //============================================================================== + void EffectInit() + { + SFicPlugInStemFormats stems; + GetProcessType()->GetStemFormats (&stems); + + juceFilter->setPlayConfigDetails (fNumInputs, fNumOutputs, + juceFilter->getSampleRate(), juceFilter->getBlockSize()); + + AddControl (new CPluginControl_OnOff ('bypa', "Master Bypass\nMastrByp\nMByp\nByp", false, true)); + DefineMasterBypassControlIndex (bypassControlIndex); + + for (int i = 0; i < juceFilter->getNumParameters(); ++i) + AddControl (new JucePluginControl (juceFilter, i)); + + // we need to do this midi log-in to get timecode, regardless of whether + // the plugin actually uses midi... + if (MIDILogIn() == noErr) + { +#if JucePlugin_WantsMidiInput + CEffectType* const type = dynamic_cast (this->GetProcessType()); + + if (type != 0) + { + char nodeName [64]; + type->GetProcessTypeName (63, nodeName); + p2cstrcpy (nodeName, reinterpret_cast (nodeName)); + + midiBufferNode = new CEffectMIDIOtherBufferedNode (&mMIDIWorld, + 8192, + eLocalNode, + nodeName, + midiBuffer); + + midiBufferNode->Initialize (1, true); + } +#endif + } + + midiTransport = new CEffectMIDITransport (&mMIDIWorld); + + juceFilter->setPlayHead (this); + juceFilter->addListener (this); + } + + void handleAsyncUpdate() + { + if (! prepared) + { + sampleRate = gProcessGroup->GetSampleRate(); + jassert (sampleRate > 0); + + juce_free (channels); + channels = (float**) juce_calloc (sizeof (float*) * jmax (juceFilter->getNumInputChannels(), + juceFilter->getNumOutputChannels())); + + juceFilter->setPlayConfigDetails (fNumInputs, fNumOutputs, + sampleRate, mRTGlobals->mHWBufferSizeInSamples); + + juceFilter->prepareToPlay (sampleRate, + mRTGlobals->mHWBufferSizeInSamples); + + prepared = true; + } + } + + void RenderAudio (float** inputs, float** outputs, long numSamples) + { + if (! prepared) + { + triggerAsyncUpdate(); + bypassBuffers (inputs, outputs, numSamples); + return; + } + + if (mBypassed) + { + bypassBuffers (inputs, outputs, numSamples); + return; + } + +#if JucePlugin_WantsMidiInput + midiEvents.clear(); + + const Cmn_UInt32 bufferSize = mRTGlobals->mHWBufferSizeInSamples; + + if (midiBufferNode->GetAdvanceScheduleTime() != bufferSize) + midiBufferNode->SetAdvanceScheduleTime (bufferSize); + + if (midiBufferNode->FillMIDIBuffer (mRTGlobals->mRunningTime, numSamples) == noErr) + { + jassert (midiBufferNode->GetBufferPtr() != 0); + const int numMidiEvents = midiBufferNode->GetBufferSize(); + + for (int i = 0; i < numMidiEvents; ++i) + { + const DirectMidiPacket& m = midiBuffer[i]; + + jassert ((int) m.mTimestamp < numSamples); + + midiEvents.addEvent (m.mData, m.mLength, + jlimit (0, (int) numSamples - 1, (int) m.mTimestamp)); + } + } +#endif + +#if defined (JUCE_DEBUG) || JUCE_LOG_ASSERTIONS + const int numMidiEventsComingIn = midiEvents.getNumEvents(); +#endif + + { + const ScopedLock sl (juceFilter->getCallbackLock()); + + const int numIn = juceFilter->getNumInputChannels(); + const int numOut = juceFilter->getNumOutputChannels(); + const int totalChans = jmax (numIn, numOut); + + if (juceFilter->isSuspended()) + { + for (int i = 0; i < numOut; ++i) + zeromem (outputs [i], sizeof (float) * numSamples); + } + else + { + { + int i; + for (i = 0; i < numOut; ++i) + { + channels[i] = outputs [i]; + + if (i < numIn && inputs != outputs) + memcpy (outputs [i], inputs[i], sizeof (float) * numSamples); + } + + for (; i < numIn; ++i) + channels [i] = inputs [i]; + } + + AudioSampleBuffer chans (channels, totalChans, numSamples); + + juceFilter->processBlock (chans, midiEvents); + } + } + + if (! midiEvents.isEmpty()) + { +#if JucePlugin_ProducesMidiOutput + const uint8* midiEventData; + int midiEventSize, midiEventPosition; + MidiBuffer::Iterator i (midiEvents); + + while (i.getNextEvent (midiEventData, midiEventSize, midiEventPosition)) + { +// jassert (midiEventPosition >= 0 && midiEventPosition < (int) numSamples); + + //xxx + } +#else + // if your plugin creates midi messages, you'll need to set + // the JucePlugin_ProducesMidiOutput macro to 1 in your + // JucePluginCharacteristics.h file + jassert (midiEvents.getNumEvents() <= numMidiEventsComingIn); +#endif + + midiEvents.clear(); + } + } + + //============================================================================== + ComponentResult GetChunkSize (OSType chunkID, long* size) + { + if (chunkID == juceChunkType) + { + tempFilterData.setSize (0); + juceFilter->getStateInformation (tempFilterData); + + *size = sizeof (SFicPlugInChunkHeader) + tempFilterData.getSize(); + return noErr; + } + + return CEffectProcessMIDI::GetChunkSize (chunkID, size); + } + + ComponentResult GetChunk (OSType chunkID, SFicPlugInChunk* chunk) + { + if (chunkID == juceChunkType) + { + if (tempFilterData.getSize() == 0) + juceFilter->getStateInformation (tempFilterData); + + chunk->fSize = sizeof (SFicPlugInChunkHeader) + tempFilterData.getSize(); + tempFilterData.copyTo ((void*) chunk->fData, 0, tempFilterData.getSize()); + + tempFilterData.setSize (0); + + return noErr; + } + + return CEffectProcessMIDI::GetChunk (chunkID, chunk); + } + + ComponentResult SetChunk (OSType chunkID, SFicPlugInChunk* chunk) + { + if (chunkID == juceChunkType) + { + tempFilterData.setSize (0); + + if (chunk->fSize - sizeof (SFicPlugInChunkHeader) > 0) + { + juceFilter->setStateInformation ((void*) chunk->fData, + chunk->fSize - sizeof (SFicPlugInChunkHeader)); + } + + return noErr; + } + + return CEffectProcessMIDI::SetChunk (chunkID, chunk); + } + + //============================================================================== + ComponentResult UpdateControlValue (long controlIndex, long value) + { + if (controlIndex != bypassControlIndex) + juceFilter->setParameter (controlIndex - 2, longToFloat (value)); + else + mBypassed = (value > 0); + + return CProcess::UpdateControlValue (controlIndex, value); + } + + //============================================================================== + bool getCurrentPosition (AudioPlayHead::CurrentPositionInfo& info) + { + // this method can only be called while the plugin is running + jassert (prepared); + + Cmn_Float64 bpm = 120.0; + Cmn_Int32 num = 4, denom = 4; + Cmn_Int64 ticks = 0; + Cmn_Bool isPlaying = false; + + if (midiTransport != 0) + { + midiTransport->GetCurrentTempo (&bpm); + midiTransport->IsTransportPlaying (&isPlaying); + midiTransport->GetCurrentMeter (&num, &denom); + midiTransport->GetCurrentTickPosition (&ticks); + } + + info.bpm = bpm; + info.timeSigNumerator = num; + info.timeSigDenominator = denom; + info.isPlaying = isPlaying; + info.isRecording = false; + info.ppqPosition = ticks / 960000.0; + info.ppqPositionOfLastBarStart = 0; //xxx no idea how to get this correctly.. + + // xxx incorrect if there are tempo changes, but there's no + // other way of getting this info.. + info.timeInSeconds = ticks * (60.0 / 960000.0) / bpm; + + double framesPerSec = 24.0; + + switch (fTimeCodeInfo.mFrameRate) + { + case ficFrameRate_24Frame: + info.frameRate = AudioPlayHead::fps24; + break; + + case ficFrameRate_25Frame: + info.frameRate = AudioPlayHead::fps25; + framesPerSec = 25.0; + break; + + case ficFrameRate_2997NonDrop: + info.frameRate = AudioPlayHead::fps2997; + framesPerSec = 29.97002997; + break; + + case ficFrameRate_2997DropFrame: + info.frameRate = AudioPlayHead::fps2997drop; + framesPerSec = 29.97002997; + break; + + case ficFrameRate_30NonDrop: + info.frameRate = AudioPlayHead::fps30; + framesPerSec = 30.0; + break; + + case ficFrameRate_30DropFrame: + info.frameRate = AudioPlayHead::fps30drop; + framesPerSec = 30.0; + break; + + case ficFrameRate_23976: + // xxx not strictly true.. + info.frameRate = AudioPlayHead::fps24; + framesPerSec = 23.976; + break; + + default: + info.frameRate = AudioPlayHead::fpsUnknown; + break; + } + + info.editOriginTime = fTimeCodeInfo.mFrameOffset / framesPerSec; + + return true; + } + + void audioProcessorParameterChanged (AudioProcessor*, int index, float newValue) + { + SetControlValue (index + 2, floatToLong (newValue)); + } + + void audioProcessorParameterChangeGestureBegin (AudioProcessor*, int index) + { + TouchControl (index + 2); + } + + void audioProcessorParameterChangeGestureEnd (AudioProcessor*, int index) + { + ReleaseControl (index + 2); + } + + void audioProcessorChanged (AudioProcessor*) + { + // xxx is there an RTAS equivalent? + } + + //============================================================================== +private: + AudioProcessor* juceFilter; + MidiBuffer midiEvents; + CEffectMIDIOtherBufferedNode* midiBufferNode; + CEffectMIDITransport* midiTransport; + DirectMidiPacket midiBuffer [midiBufferSize]; + + JUCE_NAMESPACE::MemoryBlock tempFilterData; + float** channels; + bool prepared; + double sampleRate; + + void bypassBuffers (float** const inputs, float** const outputs, const long numSamples) const + { + for (int i = fNumOutputs; --i >= 0;) + { + if (i < fNumInputs) + memcpy (outputs[i], inputs[i], numSamples * sizeof (float)); + else + zeromem (outputs[i], numSamples * sizeof (float)); + } + } + + //============================================================================== + class JucePluginControl : public CPluginControl + { + public: + //============================================================================== + JucePluginControl (AudioProcessor* const juceFilter_, const int index_) + : juceFilter (juceFilter_), + index (index_) + { + } + + ~JucePluginControl() + { + } + + //============================================================================== + OSType GetID() const { return index + 1; } + long GetDefaultValue() const { return floatToLong (0); } + void SetDefaultValue (long) {} + long GetNumSteps() const { return 0xffffffff; } + + long ConvertStringToValue (const char* valueString) const + { + return floatToLong (String (valueString).getFloatValue()); + } + + Cmn_Bool IsKeyValid (long key) const { return true; } + + void GetNameOfLength (char* name, int maxLength, OSType inControllerType) const + { + juceFilter->getParameterName (index).copyToBuffer (name, maxLength); + } + + long GetPriority() const { return kFicCooperativeTaskPriority; } + + long GetOrientation() const + { + return kDAE_LeftMinRightMax | kDAE_BottomMinTopMax + | kDAE_RotarySingleDotMode | kDAE_RotaryLeftMinRightMax; + } + + long GetControlType() const { return kDAE_ContinuousValues; } + + void GetValueString (char* valueString, int maxLength, long value) const + { + juceFilter->getParameterText (index).copyToBuffer (valueString, maxLength); + } + + Cmn_Bool IsAutomatable() const + { + return juceFilter->isParameterAutomatable (index); + } + + private: + //============================================================================== + AudioProcessor* const juceFilter; + const int index; + + JucePluginControl (const JucePluginControl&); + const JucePluginControl& operator= (const JucePluginControl&); + }; +}; + + +//============================================================================== +class JucePlugInGroup : public CEffectGroupMIDI +{ +public: + //============================================================================== + JucePlugInGroup() + { + DefineManufacturerNamesAndID (JucePlugin_Manufacturer, JucePlugin_RTASManufacturerCode); + DefinePlugInNamesAndVersion (createRTASName(), JucePlugin_VersionCode); + +#ifndef JUCE_DEBUG + AddGestalt (pluginGestalt_IsCacheable); +#endif + } + + ~JucePlugInGroup() + { + shutdownJuce_GUI(); + shutdownJuce_NonGUI(); + } + + //============================================================================== + void CreateEffectTypes() + { + const short channelConfigs[][2] = { JucePlugin_PreferredChannelConfigurations }; + const int numConfigs = numElementsInArray (channelConfigs); + + // You need to actually add some configurations to the JucePlugin_PreferredChannelConfigurations + // value in your JucePluginCharacteristics.h file.. + jassert (numConfigs > 0); + + for (int i = 0; i < numConfigs; ++i) + { + CEffectType* const type + = new CEffectTypeRTAS ('jcaa' + i, + JucePlugin_RTASProductId, + JucePlugin_RTASCategory); + + type->DefineTypeNames (createRTASName()); + type->DefineSampleRateSupport (eSupports48kAnd96kAnd192k); + + type->DefineStemFormats (getFormatForChans (channelConfigs [i][0]), + getFormatForChans (channelConfigs [i][1])); + + type->AddGestalt (pluginGestalt_CanBypass); + type->AddGestalt (pluginGestalt_SupportsVariableQuanta); + type->AttachEffectProcessCreator (createNewProcess); + + AddEffectType (type); + } + } + + void Initialize() + { + CEffectGroupMIDI::Initialize(); + } + + //============================================================================== +private: + static CEffectProcess* createNewProcess() + { + // Juce setup +#if JUCE_WIN32 + PlatformUtilities::setCurrentModuleInstanceHandle (gThisModule); +#endif + initialiseJuce_GUI(); + + return new JucePlugInProcess(); + } + + static const String createRTASName() + { + return String (JucePlugin_Name) + T("\n") + + String (JucePlugin_Name).substring (0, 4); + } + + static EPlugIn_StemFormat getFormatForChans (const int numChans) throw() + { + switch (numChans) + { + case 1: + return ePlugIn_StemFormat_Mono; + + case 2: + return ePlugIn_StemFormat_Stereo; + + case 3: + return ePlugIn_StemFormat_LCR; + + case 4: + return ePlugIn_StemFormat_Quad; + + case 5: + return ePlugIn_StemFormat_5dot0; + + case 6: + return ePlugIn_StemFormat_5dot1; + + case 7: + return ePlugIn_StemFormat_6dot1; + + case 8: + return ePlugIn_StemFormat_7dot1; + + default: + jassertfalse // hmm - not a valid number of chans for RTAS.. + break; + } + + return ePlugIn_StemFormat_Generic; + } +}; + +CProcessGroupInterface* CProcessGroup::CreateProcessGroup() +{ + initialiseJuce_NonGUI(); + return new JucePlugInGroup(); +} diff --git a/extras/audio plugins/wrapper/formats/RTAS/juce_RTAS_dlldefs.def b/extras/audio plugins/wrapper/formats/RTAS/juce_RTAS_dlldefs.def new file mode 100644 index 0000000000..31b09258e4 --- /dev/null +++ b/extras/audio plugins/wrapper/formats/RTAS/juce_RTAS_dlldefs.def @@ -0,0 +1,3 @@ +EXPORTS + NewPlugIn @1 + _PI_GetRoutineDescriptor @2 diff --git a/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectGroup.cpp b/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectGroup.cpp new file mode 100644 index 0000000000..2a938ae853 --- /dev/null +++ b/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectGroup.cpp @@ -0,0 +1,44 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +#include "juce_Wrapper_Header.h" + +/* + This file is used to include and build a digidesign CPP file without your project needing to + reference the file directly. Because the file will be located via the include path, this means + that the project doesn't have to change to cope with people's SDKs being in different locations. + + Note about include paths + + If you get an error including this file, check your paths - there's a full list of + Digidesign paths in juce_RTASWrapper.cpp +*/ +#include "CEffectGroup.cpp" diff --git a/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectGroupMIDI.cpp b/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectGroupMIDI.cpp new file mode 100644 index 0000000000..07aa7ee05c --- /dev/null +++ b/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectGroupMIDI.cpp @@ -0,0 +1,44 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +#include "juce_Wrapper_Header.h" + +/* + This file is used to include and build a digidesign CPP file without your project needing to + reference the file directly. Because the file will be located via the include path, this means + that the project doesn't have to change to cope with people's SDKs being in different locations. + + Note about include paths + + If you get an error including this file, check your paths - there's a full list of + Digidesign paths in juce_RTASWrapper.cpp +*/ +#include "CEffectGroupMIDI.cpp" diff --git a/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectMIDIUtils.cpp b/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectMIDIUtils.cpp new file mode 100644 index 0000000000..a9a948b281 --- /dev/null +++ b/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectMIDIUtils.cpp @@ -0,0 +1,44 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +#include "juce_Wrapper_Header.h" + +/* + This file is used to include and build a digidesign CPP file without your project needing to + reference the file directly. Because the file will be located via the include path, this means + that the project doesn't have to change to cope with people's SDKs being in different locations. + + Note about include paths + + If you get an error including this file, check your paths - there's a full list of + Digidesign paths in juce_RTASWrapper.cpp +*/ +#include "CEffectMIDIUtils.cpp" diff --git a/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectProcess.cpp b/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectProcess.cpp new file mode 100644 index 0000000000..2dfa8561b9 --- /dev/null +++ b/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectProcess.cpp @@ -0,0 +1,44 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +#include "juce_Wrapper_Header.h" + +/* + This file is used to include and build a digidesign CPP file without your project needing to + reference the file directly. Because the file will be located via the include path, this means + that the project doesn't have to change to cope with people's SDKs being in different locations. + + Note about include paths + + If you get an error including this file, check your paths - there's a full list of + Digidesign paths in juce_RTASWrapper.cpp +*/ +#include "CEffectProcess.cpp" diff --git a/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectProcessAS.cpp b/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectProcessAS.cpp new file mode 100644 index 0000000000..70083d8da6 --- /dev/null +++ b/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectProcessAS.cpp @@ -0,0 +1,44 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +#include "juce_Wrapper_Header.h" + +/* + This file is used to include and build a digidesign CPP file without your project needing to + reference the file directly. Because the file will be located via the include path, this means + that the project doesn't have to change to cope with people's SDKs being in different locations. + + Note about include paths + + If you get an error including this file, check your paths - there's a full list of + Digidesign paths in juce_RTASWrapper.cpp +*/ +#include "CEffectProcessAS.cpp" diff --git a/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectProcessMIDI.cpp b/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectProcessMIDI.cpp new file mode 100644 index 0000000000..24313d8492 --- /dev/null +++ b/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectProcessMIDI.cpp @@ -0,0 +1,44 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +#include "juce_Wrapper_Header.h" + +/* + This file is used to include and build a digidesign CPP file without your project needing to + reference the file directly. Because the file will be located via the include path, this means + that the project doesn't have to change to cope with people's SDKs being in different locations. + + Note about include paths + + If you get an error including this file, check your paths - there's a full list of + Digidesign paths in juce_RTASWrapper.cpp +*/ +#include "CEffectProcessMIDI.cpp" diff --git a/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectType.cpp b/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectType.cpp new file mode 100644 index 0000000000..5c33164ea9 --- /dev/null +++ b/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectType.cpp @@ -0,0 +1,44 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +#include "juce_Wrapper_Header.h" + +/* + This file is used to include and build a digidesign CPP file without your project needing to + reference the file directly. Because the file will be located via the include path, this means + that the project doesn't have to change to cope with people's SDKs being in different locations. + + Note about include paths + + If you get an error including this file, check your paths - there's a full list of + Digidesign paths in juce_RTASWrapper.cpp +*/ +#include "CEffectType.cpp" diff --git a/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectTypeRTAS.cpp b/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectTypeRTAS.cpp new file mode 100644 index 0000000000..1464ee04d7 --- /dev/null +++ b/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectTypeRTAS.cpp @@ -0,0 +1,44 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +#include "juce_Wrapper_Header.h" + +/* + This file is used to include and build a digidesign CPP file without your project needing to + reference the file directly. Because the file will be located via the include path, this means + that the project doesn't have to change to cope with people's SDKs being in different locations. + + Note about include paths + + If you get an error including this file, check your paths - there's a full list of + Digidesign paths in juce_RTASWrapper.cpp +*/ +#include "CEffectTypeRTAS.cpp" diff --git a/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_ChunkDataParser.cpp b/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_ChunkDataParser.cpp new file mode 100644 index 0000000000..5f29659bd7 --- /dev/null +++ b/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_ChunkDataParser.cpp @@ -0,0 +1,44 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +#include "juce_Wrapper_Header.h" + +/* + This file is used to include and build a digidesign CPP file without your project needing to + reference the file directly. Because the file will be located via the include path, this means + that the project doesn't have to change to cope with people's SDKs being in different locations. + + Note about include paths + + If you get an error including this file, check your paths - there's a full list of + Digidesign paths in juce_RTASWrapper.cpp +*/ +#include "ChunkDataParser.cpp" diff --git a/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_DLLMain.cpp b/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_DLLMain.cpp new file mode 100644 index 0000000000..fa1259df2d --- /dev/null +++ b/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_DLLMain.cpp @@ -0,0 +1,46 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +#include "juce_Wrapper_Header.h" + +/* + This file is used to include and build a digidesign CPP file without your project needing to + reference the file directly. Because the file will be located via the include path, this means + that the project doesn't have to change to cope with people's SDKs being in different locations. + + Note about include paths + + If you get an error including this file, check your paths - there's a full list of + Digidesign paths in juce_RTASWrapper.cpp +*/ +#if WINDOWS_VERSION + #include "DLLMain.cpp" +#endif diff --git a/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_DefaultSwap.cpp b/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_DefaultSwap.cpp new file mode 100644 index 0000000000..3cc54a6782 --- /dev/null +++ b/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_DefaultSwap.cpp @@ -0,0 +1,46 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +#include "juce_Wrapper_Header.h" + +/* + This file is used to include and build a digidesign CPP file without your project needing to + reference the file directly. Because the file will be located via the include path, this means + that the project doesn't have to change to cope with people's SDKs being in different locations. + + Note about include paths + + If you get an error including this file, check your paths - there's a full list of + Digidesign paths in juce_RTASWrapper.cpp +*/ +#if WINDOWS_VERSION + #include "DefaultSwap.cpp" +#endif diff --git a/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_Dispatcher.cpp b/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_Dispatcher.cpp new file mode 100644 index 0000000000..d8b321ea65 --- /dev/null +++ b/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_Dispatcher.cpp @@ -0,0 +1,40 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +/* This file is used to include and build a digidesign CPP file without your project needing to + reference the file directly. Because the file will be located via the include path, this means + that the project doesn't have to change to cope with people's SDKs being in different locations. +*/ + +#include "juce_Wrapper_Header.h" +#if ! WINDOWS_VERSION + #include "Dispatcher.cpp" +#endif diff --git a/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_Header.h b/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_Header.h new file mode 100644 index 0000000000..f746288711 --- /dev/null +++ b/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_Header.h @@ -0,0 +1,45 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +#ifndef __JUCE_WRAPPER_HEADER_JUCEHEADER__ +#define __JUCE_WRAPPER_HEADER_JUCEHEADER__ + +#include "../juce_RTASCompileFlags.h" + +#ifdef _MSC_VER + // the Digidesign projects all use a struct alignment of 2.. + #pragma pack (2) + #pragma warning (disable: 4267 4996 4311 4312 4103) + + #include "ForcedInclude.h" +#endif + +#endif // __JUCE_WRAPPER_HEADER_JUCEHEADER__ diff --git a/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_PlugInUtils.cpp b/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_PlugInUtils.cpp new file mode 100644 index 0000000000..19c8440f53 --- /dev/null +++ b/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_PlugInUtils.cpp @@ -0,0 +1,44 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +#include "juce_Wrapper_Header.h" + +/* + This file is used to include and build a digidesign CPP file without your project needing to + reference the file directly. Because the file will be located via the include path, this means + that the project doesn't have to change to cope with people's SDKs being in different locations. + + Note about include paths + + If you get an error including this file, check your paths - there's a full list of + Digidesign paths in juce_RTASWrapper.cpp +*/ +#include "PlugInUtils.cpp" diff --git a/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_PluginInitialize.cpp b/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_PluginInitialize.cpp new file mode 100644 index 0000000000..80698eeff2 --- /dev/null +++ b/extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_PluginInitialize.cpp @@ -0,0 +1,40 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +/* This file is used to include and build a digidesign CPP file without your project needing to + reference the file directly. Because the file will be located via the include path, this means + that the project doesn't have to change to cope with people's SDKs being in different locations. +*/ + +#include "juce_Wrapper_Header.h" +#if ! WINDOWS_VERSION + #include "PlugInInitialize.cpp" +#endif diff --git a/extras/audio plugins/wrapper/formats/Standalone/juce_AudioFilterStreamer.cpp b/extras/audio plugins/wrapper/formats/Standalone/juce_AudioFilterStreamer.cpp new file mode 100644 index 0000000000..25e456f453 --- /dev/null +++ b/extras/audio plugins/wrapper/formats/Standalone/juce_AudioFilterStreamer.cpp @@ -0,0 +1,173 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +#include "juce_AudioFilterStreamer.h" +#include "../../juce_IncludeCharacteristics.h" + + +//============================================================================== +AudioFilterStreamer::AudioFilterStreamer (AudioProcessor& filterToUse) + : filter (filterToUse), + isPlaying (false), + sampleRate (0), + emptyBuffer (1, 32) +{ + filter.setPlayConfigDetails (JucePlugin_MaxNumInputChannels, JucePlugin_MaxNumOutputChannels, 0, 0); + + filter.setPlayHead (this); +} + +AudioFilterStreamer::~AudioFilterStreamer() +{ + audioDeviceStopped(); +} + +void AudioFilterStreamer::audioDeviceIOCallback (const float** inputChannelData, + int totalNumInputChannels, + float** outputChannelData, + int totalNumOutputChannels, + int numSamples) +{ + MidiBuffer midiBuffer; + midiCollector.removeNextBlockOfMessages (midiBuffer, numSamples); + + int i, numActiveInChans = 0, numActiveOutChans = 0; + int numOutsWanted = filter.getNumOutputChannels(); + const int numInsWanted = filter.getNumInputChannels(); + + for (i = 0; i < totalNumInputChannels; ++i) + if (inputChannelData[i] != 0) + inChans [numActiveInChans++] = (float*) inputChannelData[i]; + + while (numActiveInChans < numInsWanted) + inChans [numActiveInChans++] = emptyBuffer.getSampleData (0, 0); + + for (i = 0; i < totalNumOutputChannels; ++i) + if (outputChannelData[i] != 0) + outChans [numActiveOutChans++] = outputChannelData[i]; + + i = 0; + while (numActiveOutChans < numOutsWanted) + outChans [numActiveOutChans++] = emptyBuffer.getSampleData (++i, 0); + + AudioSampleBuffer input (inChans, jmin (numInsWanted, numActiveInChans), numSamples); + AudioSampleBuffer output (outChans, jmin (numOutsWanted, numActiveOutChans), numSamples); + + { + const ScopedLock sl (filter.getCallbackLock()); + + if (filter.isSuspended()) + { + output.clear(); + } + else + { + for (int i = jmin (output.getNumChannels(), input.getNumChannels()); --i >= 0;) + output.copyFrom (i, 0, input, i, 0, numSamples); + + filter.processBlock (output, midiBuffer); + } + } + + while (numOutsWanted < numActiveOutChans) + zeromem (outChans[numOutsWanted++], sizeof (float) * numSamples); +} + +void AudioFilterStreamer::audioDeviceAboutToStart (double sampleRate_, + int numSamplesPerBlock) +{ + sampleRate = sampleRate_; + + isPlaying = true; + + emptyBuffer.setSize (1 + filter.getNumOutputChannels(), + jmax (2048, numSamplesPerBlock * 2)); + emptyBuffer.clear(); + + midiCollector.reset (sampleRate); + + filter.prepareToPlay (sampleRate, numSamplesPerBlock); +} + +void AudioFilterStreamer::audioDeviceStopped() +{ + isPlaying = false; + filter.releaseResources(); + midiCollector.reset (sampleRate); + emptyBuffer.setSize (1, 32); +} + +void AudioFilterStreamer::handleIncomingMidiMessage (MidiInput* source, const MidiMessage& message) +{ +#if JucePlugin_WantsMidiInput + midiCollector.addMessageToQueue (message); +#endif +} + +bool AudioFilterStreamer::getCurrentPosition (AudioPlayHead::CurrentPositionInfo& info) +{ + return false; +} + + +//============================================================================== +AudioFilterStreamingDeviceManager::AudioFilterStreamingDeviceManager() + : streamer (0) +{ +} + +AudioFilterStreamingDeviceManager::~AudioFilterStreamingDeviceManager() +{ + setFilter (0); + clearSingletonInstance(); +} + +void AudioFilterStreamingDeviceManager::setFilter (AudioProcessor* filterToStream) +{ + if (streamer != 0) + { + removeMidiInputCallback (streamer); + setAudioCallback (0); + + delete streamer; + streamer = 0; + } + + if (filterToStream != 0) + { + streamer = new AudioFilterStreamer (*filterToStream); + + setAudioCallback (streamer); + addMidiInputCallback (String::empty, streamer); + } +} + +juce_ImplementSingleton (AudioFilterStreamingDeviceManager); diff --git a/extras/audio plugins/wrapper/formats/Standalone/juce_AudioFilterStreamer.h b/extras/audio plugins/wrapper/formats/Standalone/juce_AudioFilterStreamer.h new file mode 100644 index 0000000000..8fbfc95be8 --- /dev/null +++ b/extras/audio plugins/wrapper/formats/Standalone/juce_AudioFilterStreamer.h @@ -0,0 +1,128 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +#ifndef __JUCE_AUDIOFILTERSTREAMER_JUCEHEADER__ +#define __JUCE_AUDIOFILTERSTREAMER_JUCEHEADER__ + +#include "../../../../../juce.h" + + +//============================================================================== +/** + A class that wraps an AudioProcessor as an AudioIODeviceCallback, so its + output can be streamed directly to/from some audio and midi inputs and outputs. + + To use it, just create an instance of this for your filter, and register it + as the callback with an AudioIODevice or AudioDeviceManager object. + + To receive midi input in your filter, you should also register it as a + MidiInputCallback with a suitable MidiInput or an AudioDeviceManager. + + And for an even easier way of doing a standalone plugin, see the + AudioFilterStreamingDeviceManager class... +*/ +class AudioFilterStreamer : public AudioIODeviceCallback, + public MidiInputCallback, + public AudioPlayHead +{ +public: + //============================================================================== + AudioFilterStreamer (AudioProcessor& filterToUse); + ~AudioFilterStreamer(); + + + //============================================================================== + void audioDeviceIOCallback (const float** inputChannelData, + int totalNumInputChannels, + float** outputChannelData, + int totalNumOutputChannels, + int numSamples); + + void audioDeviceAboutToStart (double sampleRate, int numSamplesPerBlock); + void audioDeviceStopped(); + + void handleIncomingMidiMessage (MidiInput* source, const MidiMessage& message); + + bool getCurrentPosition (AudioPlayHead::CurrentPositionInfo& info); + + juce_UseDebuggingNewOperator + +private: + //============================================================================== + AudioProcessor& filter; + bool isPlaying; + double sampleRate; + MidiMessageCollector midiCollector; + + float* outChans [128]; + float* inChans [128]; + AudioSampleBuffer emptyBuffer; +}; + +//============================================================================== +/** + Wraps an AudioFilterStreamer in an AudioDeviceManager to make it easy to + create a standalone filter. + + This simply acts as a singleton AudioDeviceManager, which continuously + streams audio from the filter you give it with the setFilter() method. + + To use it, simply create an instance of it (or use getInstance() if you're + using it as a singleton), initialise it like you would a normal + AudioDeviceManager, and call setFilter() to start it running your plugin. + +*/ +class AudioFilterStreamingDeviceManager : public AudioDeviceManager +{ +public: + //============================================================================== + AudioFilterStreamingDeviceManager(); + ~AudioFilterStreamingDeviceManager(); + + juce_DeclareSingleton (AudioFilterStreamingDeviceManager, true); + + //============================================================================== + /** Tells the device which filter to stream audio through. + + Pass in 0 to deselect the current filter. + */ + void setFilter (AudioProcessor* filterToStream); + + + //============================================================================== + juce_UseDebuggingNewOperator + +private: + AudioFilterStreamer* streamer; +}; + + +#endif // __JUCE_AUDIOFILTERSTREAMER_JUCEHEADER__ diff --git a/extras/audio plugins/wrapper/formats/Standalone/juce_StandaloneFilterWindow.cpp b/extras/audio plugins/wrapper/formats/Standalone/juce_StandaloneFilterWindow.cpp new file mode 100644 index 0000000000..71ab118440 --- /dev/null +++ b/extras/audio plugins/wrapper/formats/Standalone/juce_StandaloneFilterWindow.cpp @@ -0,0 +1,301 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +#include "juce_StandaloneFilterWindow.h" +#include "../../juce_IncludeCharacteristics.h" + +//============================================================================== +/** Somewhere in the codebase of your plugin, you need to implement this function + and make it create an instance of the filter subclass that you're building. +*/ +extern AudioProcessor* JUCE_CALLTYPE createPluginFilter(); + + +//============================================================================== +StandaloneFilterWindow::StandaloneFilterWindow (const String& title, + const Colour& backgroundColour) + : DocumentWindow (title, backgroundColour, + DocumentWindow::minimiseButton + | DocumentWindow::closeButton), + filter (0), + deviceManager (0), + optionsButton (0) +{ + setTitleBarButtonsRequired (DocumentWindow::minimiseButton | DocumentWindow::closeButton, false); + + PropertySet* const globalSettings = getGlobalSettings(); + + optionsButton = new TextButton (T("options")); + Component::addAndMakeVisible (optionsButton); + optionsButton->addButtonListener (this); + optionsButton->setTriggeredOnMouseDown (true); + + JUCE_TRY + { + filter = createPluginFilter(); + + if (filter != 0) + { + deviceManager = new AudioFilterStreamingDeviceManager(); + deviceManager->setFilter (filter); + + XmlElement* savedState = 0; + + if (globalSettings != 0) + savedState = globalSettings->getXmlValue (T("audioSetup")); + + deviceManager->initialise (filter->getNumInputChannels(), + filter->getNumOutputChannels(), + savedState, + true); + + delete savedState; + + if (globalSettings != 0) + { + juce::MemoryBlock data; + + if (data.fromBase64Encoding (globalSettings->getValue (T("filterState"))) + && data.getSize() > 0) + { + filter->setStateInformation (data.getData(), data.getSize()); + } + } + + setContentComponent (filter->createEditorIfNeeded(), true, true); + + const int x = globalSettings->getIntValue (T("windowX"), -100); + const int y = globalSettings->getIntValue (T("windowY"), -100); + + if (x != -100 && y != -100) + setBoundsConstrained (x, y, getWidth(), getHeight()); + else + centreWithSize (getWidth(), getHeight()); + } + } + JUCE_CATCH_ALL + + if (deviceManager == 0) + { + jassertfalse // Your filter didn't create correctly! In a standalone app that's not too great. + JUCEApplication::quit(); + } +} + +StandaloneFilterWindow::~StandaloneFilterWindow() +{ + PropertySet* const globalSettings = getGlobalSettings(); + + globalSettings->setValue (T("windowX"), getX()); + globalSettings->setValue (T("windowY"), getY()); + + deleteAndZero (optionsButton); + + if (globalSettings != 0 && deviceManager != 0) + { + XmlElement* const xml = deviceManager->createStateXml(); + globalSettings->setValue (T("audioSetup"), xml); + delete xml; + } + + deleteAndZero (deviceManager); + + if (globalSettings != 0 && filter != 0) + { + juce::MemoryBlock data; + filter->getStateInformation (data); + + globalSettings->setValue (T("filterState"), data.toBase64Encoding()); + } + + deleteFilter(); +} + +//============================================================================== +void StandaloneFilterWindow::deleteFilter() +{ + if (deviceManager != 0) + deviceManager->setFilter (0); + + if (filter != 0 && getContentComponent() != 0) + { + filter->editorBeingDeleted (dynamic_cast (getContentComponent())); + setContentComponent (0, true); + } + + deleteAndZero (filter); +} + +void StandaloneFilterWindow::resetFilter() +{ + deleteFilter(); + + filter = createPluginFilter(); + + if (filter != 0) + { + if (deviceManager != 0) + deviceManager->setFilter (filter); + + setContentComponent (filter->createEditorIfNeeded(), true, true); + } + + PropertySet* const globalSettings = getGlobalSettings(); + + if (globalSettings != 0) + globalSettings->removeValue (T("filterState")); +} + +//============================================================================== +void StandaloneFilterWindow::saveState() +{ + PropertySet* const globalSettings = getGlobalSettings(); + + FileChooser fc (TRANS("Save current state"), + globalSettings != 0 ? File (globalSettings->getValue (T("lastStateFile"))) + : File::nonexistent); + + if (fc.browseForFileToSave (true)) + { + juce::MemoryBlock data; + filter->getStateInformation (data); + + if (! fc.getResult().replaceWithData (data.getData(), data.getSize())) + { + AlertWindow::showMessageBox (AlertWindow::WarningIcon, + TRANS("Error whilst saving"), + TRANS("Couldn't write to the specified file!")); + } + } +} + +void StandaloneFilterWindow::loadState() +{ + PropertySet* const globalSettings = getGlobalSettings(); + + FileChooser fc (TRANS("Load a saved state"), + globalSettings != 0 ? File (globalSettings->getValue (T("lastStateFile"))) + : File::nonexistent); + + if (fc.browseForFileToOpen()) + { + juce::MemoryBlock data; + + if (fc.getResult().loadFileAsData (data)) + { + filter->setStateInformation (data.getData(), data.getSize()); + } + else + { + AlertWindow::showMessageBox (AlertWindow::WarningIcon, + TRANS("Error whilst loading"), + TRANS("Couldn't read from the specified file!")); + } + } +} + +//============================================================================== +PropertySet* StandaloneFilterWindow::getGlobalSettings() +{ + /* If you want this class to store the plugin's settings, you can set up an + ApplicationProperties object and use this method as it is, or override this + method to return your own custom PropertySet. + + If using this method without changing it, you'll probably need to call + ApplicationProperties::setStorageParameters() in your plugin's constructor to + tell it where to save the file. + */ + return ApplicationProperties::getInstance()->getUserSettings(); +} + +void StandaloneFilterWindow::showAudioSettingsDialog() +{ + AudioDeviceSelectorComponent selectorComp (*deviceManager, + filter->getNumInputChannels(), + filter->getNumInputChannels(), + filter->getNumOutputChannels(), + filter->getNumOutputChannels(), + true, false); + + selectorComp.setSize (500, 350); + + DialogWindow::showModalDialog (TRANS("Audio Settings"), &selectorComp, this, Colours::lightgrey, true, false, false); +} + +//============================================================================== +void StandaloneFilterWindow::closeButtonPressed() +{ + JUCEApplication::quit(); +} + +void StandaloneFilterWindow::resized() +{ + DocumentWindow::resized(); + + if (optionsButton != 0) + optionsButton->setBounds (8, 6, 60, getTitleBarHeight() - 8); +} + +void StandaloneFilterWindow::buttonClicked (Button*) +{ + if (filter == 0) + return; + + PopupMenu m; + m.addItem (1, TRANS("Audio Settings...")); + m.addSeparator(); + m.addItem (2, TRANS("Save current state...")); + m.addItem (3, TRANS("Load a saved state...")); + m.addSeparator(); + m.addItem (4, TRANS("Reset to default state")); + + switch (m.showAt (optionsButton)) + { + case 1: + showAudioSettingsDialog(); + break; + + case 2: + saveState(); + break; + + case 3: + loadState(); + break; + + case 4: + resetFilter(); + break; + + default: + break; + } +} diff --git a/extras/audio plugins/wrapper/formats/Standalone/juce_StandaloneFilterWindow.h b/extras/audio plugins/wrapper/formats/Standalone/juce_StandaloneFilterWindow.h new file mode 100644 index 0000000000..d6016c7501 --- /dev/null +++ b/extras/audio plugins/wrapper/formats/Standalone/juce_StandaloneFilterWindow.h @@ -0,0 +1,96 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +#ifndef __JUCE_STANDALONEFILTERWINDOW_JUCEHEADER__ +#define __JUCE_STANDALONEFILTERWINDOW_JUCEHEADER__ + +#include "juce_AudioFilterStreamer.h" + + +//============================================================================== +/** + A class that can be used to run a simple standalone application containing your filter. + + Just create one of these objects in your JUCEApplication::initialise() method, and + let it do its work. It will create your filter object using the same createFilter() function + that the other plugin wrappers use. +*/ +class StandaloneFilterWindow : public DocumentWindow, + public ButtonListener +{ +public: + //============================================================================== + StandaloneFilterWindow (const String& title, + const Colour& backgroundColour); + + ~StandaloneFilterWindow(); + + //============================================================================== + /** Deletes and re-creates the filter and its UI. */ + void resetFilter(); + + /** Pops up a dialog letting the user save the filter's state to a file. */ + void saveState(); + + /** Pops up a dialog letting the user re-load the filter's state from a file. */ + void loadState(); + + /** Shows the audio properties dialog box modally. */ + virtual void showAudioSettingsDialog(); + + /** Returns the property set to use for storing the app's last state. + + This will be used to store the audio set-up and the filter's last state. + */ + virtual PropertySet* getGlobalSettings(); + + //============================================================================== + /** @internal */ + void closeButtonPressed(); + /** @internal */ + void buttonClicked (Button*); + /** @internal */ + void resized(); + + juce_UseDebuggingNewOperator + +private: + AudioProcessor* filter; + AudioFilterStreamingDeviceManager* deviceManager; + Button* optionsButton; + + void deleteFilter(); + + StandaloneFilterWindow (const StandaloneFilterWindow&); + const StandaloneFilterWindow& operator= (const StandaloneFilterWindow&); +}; + +#endif // __JUCE_STANDALONEFILTERWINDOW_JUCEHEADER__ diff --git a/extras/audio plugins/wrapper/formats/VST/juce_VstWrapper.cpp b/extras/audio plugins/wrapper/formats/VST/juce_VstWrapper.cpp new file mode 100644 index 0000000000..5ffcef8093 --- /dev/null +++ b/extras/audio plugins/wrapper/formats/VST/juce_VstWrapper.cpp @@ -0,0 +1,1536 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +/* + *** DON't EDIT THIS FILE!! *** + + The idea is that everyone's plugins should share this same wrapper + code, so if you start hacking around in here you're missing the point! + + If there's a bug or a function you need that can't be done without changing + some of the code in here, give me a shout so we can add it to the library, + rather than branching off and going it alone! +*/ + + +//============================================================================== +#ifdef _MSC_VER + #pragma warning (disable : 4996) +#endif + +#ifdef _WIN32 + #include +#elif defined (LINUX) + #include + #include + #include + #undef KeyPress +#else + #include +#endif + +#ifdef PRAGMA_ALIGN_SUPPORTED + #undef PRAGMA_ALIGN_SUPPORTED + #define PRAGMA_ALIGN_SUPPORTED 1 +#endif + +#include "../../juce_IncludeCharacteristics.h" + +//============================================================================== +/* These files come with the Steinberg VST SDK - to get them, you'll need to + visit the Steinberg website and jump through some hoops to sign up as a + VST developer. + + Then, you'll need to make sure your include path contains your "vstsdk2.3" or + "vstsdk2.4" directory. + + Note that the JUCE_USE_VSTSDK_2_4 macro should be defined in JucePluginCharacteristics.h +*/ +#if JUCE_USE_VSTSDK_2_4 + // VSTSDK V2.4 includes.. + #include "public.sdk/source/vst2.x/audioeffectx.h" + #include "public.sdk/source/vst2.x/aeffeditor.h" + #include "public.sdk/source/vst2.x/audioeffectx.cpp" + #include "public.sdk/source/vst2.x/audioeffect.cpp" +#else + // VSTSDK V2.3 includes.. + #include "source/common/audioeffectx.h" + #include "source/common/AEffEditor.hpp" + #include "source/common/audioeffectx.cpp" + #include "source/common/AudioEffect.cpp" + typedef long VstInt32; + typedef long VstIntPtr; + enum Vst2StringConstants + { + kVstMaxNameLen = 64, + kVstMaxLabelLen = 64, + kVstMaxShortLabelLen = 8, + kVstMaxCategLabelLen = 24, + kVstMaxFileNameLen = 100 + }; + + enum VstSmpteFrameRate + { + kVstSmpte24fps = 0, ///< 24 fps + kVstSmpte25fps = 1, ///< 25 fps + kVstSmpte2997fps = 2, ///< 29.97 fps + kVstSmpte30fps = 3, ///< 30 fps + kVstSmpte2997dfps = 4, ///< 29.97 drop + kVstSmpte30dfps = 5, ///< 30 drop + kVstSmpteFilm16mm = 6, ///< Film 16mm + kVstSmpteFilm35mm = 7, ///< Film 35mm + kVstSmpte239fps = 10, ///< HDTV: 23.976 fps + kVstSmpte249fps = 11, ///< HDTV: 24.976 fps + kVstSmpte599fps = 12, ///< HDTV: 59.94 fps + kVstSmpte60fps = 13 ///< HDTV: 60 fps + }; +#endif + +//============================================================================== +#ifdef _MSC_VER + #pragma pack (push, 8) +#endif + +#include "../../../../../juce.h" + +#ifdef _MSC_VER + #pragma pack (pop) +#endif + +#undef MemoryBlock + +class JuceVSTWrapper; +static bool recursionCheck = false; +static uint32 lastMasterIdleCall = 0; + +BEGIN_JUCE_NAMESPACE + extern void juce_callAnyTimersSynchronously(); + + #if JUCE_LINUX + extern Display* display; + extern bool juce_postMessageToSystemQueue (void* message); + #endif +END_JUCE_NAMESPACE + + +//============================================================================== +#if JUCE_WIN32 + +static HWND findMDIParentOf (HWND w) +{ + const int frameThickness = GetSystemMetrics (SM_CYFIXEDFRAME); + + while (w != 0) + { + HWND parent = GetParent (w); + + if (parent == 0) + break; + + TCHAR windowType [32]; + zeromem (windowType, sizeof (windowType)); + GetClassName (parent, windowType, 31); + + if (String (windowType).equalsIgnoreCase (T("MDIClient"))) + { + w = parent; + break; + } + + RECT windowPos; + GetWindowRect (w, &windowPos); + + RECT parentPos; + GetWindowRect (parent, &parentPos); + + const int dw = (parentPos.right - parentPos.left) - (windowPos.right - windowPos.left); + const int dh = (parentPos.bottom - parentPos.top) - (windowPos.bottom - windowPos.top); + + if (dw > 100 || dh > 100) + break; + + w = parent; + + if (dw == 2 * frameThickness) + break; + } + + return w; +} + +//============================================================================== +#elif JUCE_LINUX + +class SharedMessageThread : public Thread +{ +public: + SharedMessageThread() + : Thread (T("VstMessageThread")) + { + startThread (7); + } + + ~SharedMessageThread() + { + signalThreadShouldExit(); + + const int quitMessageId = 0xfffff321; + Message* const m = new Message (quitMessageId, 1, 0, 0); + + if (! juce_postMessageToSystemQueue (m)) + delete m; + + clearSingletonInstance(); + } + + void run() + { + MessageManager* const messageManager = MessageManager::getInstance(); + + const int originalThreadId = messageManager->getCurrentMessageThread(); + messageManager->setCurrentMessageThread (getThreadId()); + + while (! threadShouldExit() + && messageManager->dispatchNextMessage()) + { + } + + messageManager->setCurrentMessageThread (originalThreadId); + } + + juce_DeclareSingleton (SharedMessageThread, false) +}; + +juce_ImplementSingleton (SharedMessageThread); + +#endif + +//============================================================================== +// A component to hold the AudioProcessorEditor, and cope with some housekeeping +// chores when it changes or repaints. +class EditorCompWrapper : public Component, + public AsyncUpdater +{ + JuceVSTWrapper* wrapper; + +public: + EditorCompWrapper (JuceVSTWrapper* const wrapper_, + AudioProcessorEditor* const editor) + : wrapper (wrapper_) + { + setOpaque (true); + editor->setOpaque (true); + + setBounds (editor->getBounds()); + editor->setTopLeftPosition (0, 0); + addAndMakeVisible (editor); + +#if JUCE_WIN32 + addMouseListener (this, true); +#endif + } + + ~EditorCompWrapper() + { + deleteAllChildren(); + } + + void paint (Graphics& g) + { + } + + void paintOverChildren (Graphics& g) + { + // this causes an async call to masterIdle() to help + // creaky old DAWs like Nuendo repaint themselves while we're + // repainting. Otherwise they just seem to give up and sit there + // waiting. + triggerAsyncUpdate(); + } + + AudioProcessorEditor* getEditorComp() const + { + return dynamic_cast (getChildComponent (0)); + } + + void resized() + { + Component* const c = getChildComponent (0); + + if (c != 0) + { +#if JUCE_LINUX + const MessageManagerLock mml; +#endif + c->setBounds (0, 0, getWidth(), getHeight()); + } + } + + void childBoundsChanged (Component* child); + void handleAsyncUpdate(); + +#if JUCE_WIN32 + void mouseDown (const MouseEvent&) + { + broughtToFront(); + } + + void broughtToFront() + { + // for hosts like nuendo, need to also pop the MDI container to the + // front when our comp is clicked on. + HWND parent = findMDIParentOf ((HWND) getWindowHandle()); + + if (parent != 0) + { + SetWindowPos (parent, + HWND_TOP, + 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOSIZE); + } + } +#endif + + //============================================================================== + juce_UseDebuggingNewOperator +}; + +static VoidArray activePlugins; + + +//============================================================================== +/** + This wraps an AudioProcessor as an AudioEffectX... +*/ +class JuceVSTWrapper : public AudioEffectX, + private Timer, + public AudioProcessorListener, + public AudioPlayHead +{ +public: + //============================================================================== + JuceVSTWrapper (audioMasterCallback audioMaster, + AudioProcessor* const filter_) + : AudioEffectX (audioMaster, + filter_->getNumPrograms(), + filter_->getNumParameters()), + filter (filter_) + { + editorComp = 0; + outgoingEvents = 0; + outgoingEventSize = 0; + chunkMemoryTime = 0; + isProcessing = false; + firstResize = true; + hasShutdown = false; + channels = 0; + +#if JUCE_MAC || JUCE_LINUX + hostWindow = 0; +#endif + + filter->setPlayConfigDetails (JucePlugin_MaxNumInputChannels, + JucePlugin_MaxNumOutputChannels, + 0, 0); + + filter_->setPlayHead (this); + filter_->addListener (this); + + cEffect.flags |= effFlagsHasEditor; + cEffect.version = (long) (JucePlugin_VersionCode); + + setUniqueID ((int) (JucePlugin_VSTUniqueID)); + +#if JucePlugin_WantsMidiInput && ! JUCE_USE_VSTSDK_2_4 + wantEvents(); +#endif + + setNumInputs (filter->getNumInputChannels()); + setNumOutputs (filter->getNumOutputChannels()); + + canProcessReplacing (true); + +#if ! JUCE_USE_VSTSDK_2_4 + hasVu (false); + hasClip (false); +#endif + + isSynth ((JucePlugin_IsSynth) != 0); + noTail ((JucePlugin_SilenceInProducesSilenceOut) != 0); + setInitialDelay (filter->getLatencySamples()); + programsAreChunks (true); + + activePlugins.add (this); + } + + ~JuceVSTWrapper() + { + stopTimer(); + deleteEditor(); + + hasShutdown = true; + + delete filter; + filter = 0; + + if (outgoingEvents != 0) + { + for (int i = outgoingEventSize; --i >= 0;) + juce_free (outgoingEvents->events[i]); + + juce_free (outgoingEvents); + outgoingEvents = 0; + } + + jassert (editorComp == 0); + + juce_free (channels); + channels = 0; + deleteTempChannels(); + + jassert (activePlugins.contains (this)); + activePlugins.removeValue (this); + + if (activePlugins.size() == 0) + { +#if JUCE_LINUX + SharedMessageThread::deleteInstance(); +#endif + shutdownJuce_GUI(); + } + } + + void open() + { + startTimer (1000 / 4); + } + + void close() + { + jassert (! recursionCheck); + + stopTimer(); + deleteEditor(); + } + + //============================================================================== + bool getEffectName (char* name) + { + String (JucePlugin_Name).copyToBuffer (name, 64); + return true; + } + + bool getVendorString (char* text) + { + String (JucePlugin_Manufacturer).copyToBuffer (text, 64); + return true; + } + + bool getProductString (char* text) + { + return getEffectName (text); + } + + VstInt32 getVendorVersion() + { + return JucePlugin_VersionCode; + } + + VstPlugCategory getPlugCategory() + { + return JucePlugin_VSTCategory; + } + + VstInt32 canDo (char* text) + { + VstInt32 result = 0; + + if (strcmp (text, "receiveVstEvents") == 0 + || strcmp (text, "receiveVstMidiEvent") == 0 + || strcmp (text, "receiveVstMidiEvents") == 0) + { +#if JucePlugin_WantsMidiInput + result = 1; +#else + result = -1; +#endif + } + else if (strcmp (text, "sendVstEvents") == 0 + || strcmp (text, "sendVstMidiEvent") == 0 + || strcmp (text, "sendVstMidiEvents") == 0) + { +#if JucePlugin_ProducesMidiOutput + result = 1; +#else + result = -1; +#endif + } + else if (strcmp (text, "receiveVstTimeInfo") == 0 + || strcmp (text, "conformsToWindowRules") == 0) + { + result = 1; + } + + return result; + } + + bool keysRequired() + { + return (JucePlugin_EditorRequiresKeyboardFocus) != 0; + } + + bool getInputProperties (VstInt32 index, VstPinProperties* properties) + { + if (filter == 0 || index >= filter->getNumInputChannels()) + return false; + + const String name (filter->getInputChannelName ((int) index)); + + name.copyToBuffer (properties->label, kVstMaxLabelLen - 1); + name.copyToBuffer (properties->shortLabel, kVstMaxShortLabelLen - 1); + + properties->flags = kVstPinIsActive; + + if (filter->isInputChannelStereoPair ((int) index)) + properties->flags |= kVstPinIsStereo; + + properties->arrangementType = 0; + + return true; + } + + bool getOutputProperties (VstInt32 index, VstPinProperties* properties) + { + if (filter == 0 || index >= filter->getNumOutputChannels()) + return false; + + const String name (filter->getOutputChannelName ((int) index)); + + name.copyToBuffer (properties->label, kVstMaxLabelLen - 1); + name.copyToBuffer (properties->shortLabel, kVstMaxShortLabelLen - 1); + + properties->flags = kVstPinIsActive; + + if (filter->isOutputChannelStereoPair ((int) index)) + properties->flags |= kVstPinIsStereo; + + properties->arrangementType = 0; + + return true; + } + + //============================================================================== + VstInt32 processEvents (VstEvents* events) + { +#if JucePlugin_WantsMidiInput + for (int i = 0; i < events->numEvents; ++i) + { + const VstEvent* const e = events->events[i]; + + if (e != 0 && e->type == kVstMidiType) + { + const VstMidiEvent* const vme = (const VstMidiEvent*) e; + + midiEvents.addEvent ((const uint8*) vme->midiData, + 4, + vme->deltaFrames); + } + } + + return 1; +#else + return 0; +#endif + } + + void process (float** inputs, float** outputs, VstInt32 numSamples) + { + const int numIn = filter->getNumInputChannels(); + const int numOut = filter->getNumOutputChannels(); + + AudioSampleBuffer temp (numIn, numSamples); + int i; + for (i = numIn; --i >= 0;) + memcpy (temp.getSampleData (i), outputs[i], sizeof (float) * numSamples); + + processReplacing (inputs, outputs, numSamples); + + AudioSampleBuffer dest (outputs, numOut, numSamples); + + for (i = jmin (numIn, numOut); --i >= 0;) + dest.addFrom (i, 0, temp, i, 0, numSamples); + } + + void processReplacing (float** inputs, float** outputs, VstInt32 numSamples) + { + // if this fails, the host hasn't called resume() before processing + jassert (isProcessing); + + // (tragically, some hosts actually need this, although it's stupid to have + // to do it here..) + if (! isProcessing) + resume(); + +#if JUCE_DEBUG && ! JucePlugin_ProducesMidiOutput + const int numMidiEventsComingIn = midiEvents.getNumEvents(); +#endif + + jassert (activePlugins.contains (this)); + + { + const ScopedLock sl (filter->getCallbackLock()); + + const int numIn = filter->getNumInputChannels(); + const int numOut = filter->getNumOutputChannels(); + + if (filter->isSuspended()) + { + for (int i = 0; i < numOut; ++i) + zeromem (outputs[i], sizeof (float) * numSamples); + } + else + { + if (! hasCreatedTempChannels) + { + // do this just once when we start processing.. + hasCreatedTempChannels = true; + + // if some output channels are disabled, some hosts supply the same buffer + // for multiple channels - this buggers up our method of copying the + // inputs over the outputs, so we need to create unique temp buffers in this case.. + for (int i = 0; i < numOut; ++i) + { + for (int j = i; --j >= 0;) + { + if (outputs[j] == outputs[i] && outputs[i] != 0) + { + tempChannels.set (i, juce_malloc (sizeof (float) * blockSize * 2)); + break; + } + } + } + } + + { + int i; + for (i = 0; i < numOut; ++i) + { + // if some output channels are disabled, the host may pass the same dummy buffer + // pointer for all of these outputs - and that means that we'd be copying all our + // input channels into the same place... so in this case, we use an internal dummy + // buffer which has enough channels for each input. + float* chan = (float*) tempChannels.getUnchecked(i); + if (chan == 0) + chan = outputs[i]; + + if (i < numIn && chan != inputs[i]) + memcpy (chan, inputs[i], sizeof (float) * numSamples); + + channels[i] = chan; + } + + for (; i < numIn; ++i) + channels[i] = inputs[i]; + } + + AudioSampleBuffer chans (channels, jmax (numIn, numOut), numSamples); + + filter->processBlock (chans, midiEvents); + } + } + + if (! midiEvents.isEmpty()) + { +#if JucePlugin_ProducesMidiOutput + const int numEvents = midiEvents.getNumEvents(); + + ensureOutgoingEventSize (numEvents); + outgoingEvents->numEvents = 0; + + const uint8* midiEventData; + int midiEventSize, midiEventPosition; + MidiBuffer::Iterator i (midiEvents); + + while (i.getNextEvent (midiEventData, midiEventSize, midiEventPosition)) + { + if (midiEventSize <= 4) + { + VstMidiEvent* const vme = (VstMidiEvent*) outgoingEvents->events [outgoingEvents->numEvents++]; + + memcpy (vme->midiData, midiEventData, midiEventSize); + vme->deltaFrames = midiEventPosition; + + jassert (vme->deltaFrames >= 0 && vme->deltaFrames < numSamples); + } + } + + sendVstEventsToHost (outgoingEvents); +#else + /* This assertion is caused when you've added some events to the + midiMessages array in your processBlock() method, which usually means + that you're trying to send them somewhere. But in this case they're + getting thrown away. + + If your plugin does want to send midi messages, you'll need to set + the JucePlugin_ProducesMidiOutput macro to 1 in your + JucePluginCharacteristics.h file. + + If you don't want to produce any midi output, then you should clear the + midiMessages array at the end of your processBlock() method, to + indicate that you don't want any of the events to be passed through + to the output. + */ + jassert (midiEvents.getNumEvents() <= numMidiEventsComingIn); +#endif + + midiEvents.clear(); + } + } + + //============================================================================== + void resume() + { + if (filter == 0) + return; + + isProcessing = true; + juce_free (channels); + channels = (float**) juce_calloc (sizeof (float*) * (filter->getNumInputChannels() + filter->getNumOutputChannels())); + + double rate = getSampleRate(); + jassert (rate > 0); + if (rate <= 0.0) + rate = 44100.0; + + const int blockSize = getBlockSize(); + jassert (blockSize > 0); + + filter->setPlayConfigDetails (JucePlugin_MaxNumInputChannels, + JucePlugin_MaxNumOutputChannels, + rate, blockSize); + + deleteTempChannels(); + + filter->prepareToPlay (rate, blockSize); + midiEvents.clear(); + + setInitialDelay (filter->getLatencySamples()); + + AudioEffectX::resume(); + +#if JucePlugin_ProducesMidiOutput + ensureOutgoingEventSize (64); +#endif + +#if JucePlugin_WantsMidiInput && ! JUCE_USE_VSTSDK_2_4 + wantEvents(); +#endif + } + + void suspend() + { + if (filter == 0) + return; + + AudioEffectX::suspend(); + + filter->releaseResources(); + midiEvents.clear(); + + isProcessing = false; + juce_free (channels); + channels = 0; + + deleteTempChannels(); + } + + bool getCurrentPosition (AudioPlayHead::CurrentPositionInfo& info) + { + const VstTimeInfo* const ti = getTimeInfo (kVstPpqPosValid + | kVstTempoValid + | kVstBarsValid + //| kVstCyclePosValid + | kVstTimeSigValid + | kVstSmpteValid + | kVstClockValid); + + if (ti == 0 || ti->sampleRate <= 0) + return false; + + if ((ti->flags & kVstTempoValid) != 0) + info.bpm = ti->tempo; + else + info.bpm = 0.0; + + if ((ti->flags & kVstTimeSigValid) != 0) + { + info.timeSigNumerator = ti->timeSigNumerator; + info.timeSigDenominator = ti->timeSigDenominator; + } + else + { + info.timeSigNumerator = 4; + info.timeSigDenominator = 4; + } + + info.timeInSeconds = ti->samplePos / ti->sampleRate; + + if ((ti->flags & kVstPpqPosValid) != 0) + info.ppqPosition = ti->ppqPos; + else + info.ppqPosition = 0.0; + + if ((ti->flags & kVstBarsValid) != 0) + info.ppqPositionOfLastBarStart = ti->barStartPos; + else + info.ppqPositionOfLastBarStart = 0.0; + + if ((ti->flags & kVstSmpteValid) != 0) + { + AudioPlayHead::FrameRateType rate = AudioPlayHead::fpsUnknown; + double fps = 1.0; + + switch (ti->smpteFrameRate) + { + case kVstSmpte24fps: + rate = AudioPlayHead::fps24; + fps = 24.0; + break; + + case kVstSmpte25fps: + rate = AudioPlayHead::fps25; + fps = 25.0; + break; + + case kVstSmpte2997fps: + rate = AudioPlayHead::fps2997; + fps = 29.97; + break; + + case kVstSmpte30fps: + rate = AudioPlayHead::fps30; + fps = 30.0; + break; + + case kVstSmpte2997dfps: + rate = AudioPlayHead::fps2997drop; + fps = 29.97; + break; + + case kVstSmpte30dfps: + rate = AudioPlayHead::fps30drop; + fps = 30.0; + break; + + case kVstSmpteFilm16mm: + case kVstSmpteFilm35mm: + fps = 24.0; + break; + + case kVstSmpte239fps: fps = 23.976; break; + case kVstSmpte249fps: fps = 24.976; break; + case kVstSmpte599fps: fps = 59.94; break; + case kVstSmpte60fps: fps = 60; break; + + default: + jassertfalse // unknown frame-rate.. + } + + info.frameRate = rate; + info.editOriginTime = ti->smpteOffset / (80.0 * fps); + } + else + { + info.frameRate = AudioPlayHead::fpsUnknown; + info.editOriginTime = 0; + } + + info.isRecording = (ti->flags & kVstTransportRecording) != 0; + info.isPlaying = (ti->flags & kVstTransportPlaying) != 0 || info.isRecording; + + return true; + } + + //============================================================================== + VstInt32 getProgram() + { + return filter != 0 ? filter->getCurrentProgram() : 0; + } + + void setProgram (VstInt32 program) + { + if (filter != 0) + filter->setCurrentProgram (program); + } + + void setProgramName (char* name) + { + if (filter != 0) + filter->changeProgramName (filter->getCurrentProgram(), name); + } + + void getProgramName (char* name) + { + if (filter != 0) + filter->getProgramName (filter->getCurrentProgram()).copyToBuffer (name, 24); + } + + bool getProgramNameIndexed (VstInt32 category, VstInt32 index, char* text) + { + if (filter != 0 && ((unsigned int) index) < (unsigned int) filter->getNumPrograms()) + { + filter->getProgramName (index).copyToBuffer (text, 24); + return true; + } + + return false; + } + + //============================================================================== + float getParameter (VstInt32 index) + { + if (filter == 0) + return 0.0f; + + jassert (((unsigned int) index) < (unsigned int) filter->getNumParameters()); + return filter->getParameter (index); + } + + void setParameter (VstInt32 index, float value) + { + if (filter != 0) + { + jassert (((unsigned int) index) < (unsigned int) filter->getNumParameters()); + filter->setParameter (index, value); + } + } + + void getParameterDisplay (VstInt32 index, char* text) + { + if (filter != 0) + { + jassert (((unsigned int) index) < (unsigned int) filter->getNumParameters()); + filter->getParameterText (index).copyToBuffer (text, 24); // length should technically be kVstMaxParamStrLen, which is 8, but hosts will normally allow a bit more. + } + } + + void getParameterName (VstInt32 index, char* text) + { + if (filter != 0) + { + jassert (((unsigned int) index) < (unsigned int) filter->getNumParameters()); + filter->getParameterName (index).copyToBuffer (text, 16); // length should technically be kVstMaxParamStrLen, which is 8, but hosts will normally allow a bit more. + } + } + + void audioProcessorParameterChanged (AudioProcessor*, int index, float newValue) + { + setParameterAutomated (index, newValue); + } + + void audioProcessorParameterChangeGestureBegin (AudioProcessor*, int index) + { + beginEdit (index); + } + + void audioProcessorParameterChangeGestureEnd (AudioProcessor*, int index) + { + endEdit (index); + } + + void audioProcessorChanged (AudioProcessor*) + { + updateDisplay(); + } + + bool canParameterBeAutomated (VstInt32 index) + { + return filter != 0 && filter->isParameterAutomatable ((int) index); + } + + bool setSpeakerArrangement (VstSpeakerArrangement* /*pluginInput*/, + VstSpeakerArrangement* /*pluginOutput*/) + { + // if this method isn't implemented, nuendo4 + cubase4 crash when you've got multiple channels.. + return true; + } + + //============================================================================== + VstInt32 getChunk (void** data, bool onlyStoreCurrentProgramData) + { + if (filter == 0) + return 0; + + chunkMemory.setSize (0); + if (onlyStoreCurrentProgramData) + filter->getCurrentProgramStateInformation (chunkMemory); + else + filter->getStateInformation (chunkMemory); + + *data = (void*) chunkMemory; + + // because the chunk is only needed temporarily by the host (or at least you'd + // hope so) we'll give it a while and then free it in the timer callback. + chunkMemoryTime = JUCE_NAMESPACE::Time::getApproximateMillisecondCounter(); + + return chunkMemory.getSize(); + } + + VstInt32 setChunk (void* data, VstInt32 byteSize, bool onlyRestoreCurrentProgramData) + { + if (filter == 0) + return 0; + + chunkMemory.setSize (0); + chunkMemoryTime = 0; + + if (byteSize > 0 && data != 0) + { + if (onlyRestoreCurrentProgramData) + filter->setCurrentProgramStateInformation (data, byteSize); + else + filter->setStateInformation (data, byteSize); + } + + return 0; + } + + void timerCallback() + { + if (chunkMemoryTime > 0 + && chunkMemoryTime < JUCE_NAMESPACE::Time::getApproximateMillisecondCounter() - 2000 + && ! recursionCheck) + { + chunkMemoryTime = 0; + chunkMemory.setSize (0); + } + + tryMasterIdle(); + } + + void tryMasterIdle() + { + if (Component::isMouseButtonDownAnywhere() + && ! recursionCheck) + { + const uint32 now = JUCE_NAMESPACE::Time::getMillisecondCounter(); + + if (now > lastMasterIdleCall + 20 && editorComp != 0) + { + lastMasterIdleCall = now; + + recursionCheck = true; + masterIdle(); + recursionCheck = false; + } + } + } + + void doIdleCallback() + { + // (wavelab calls this on a separate thread and causes a deadlock).. + if (MessageManager::getInstance()->isThisTheMessageThread() + && ! recursionCheck) + { + const MessageManagerLock mml; + + recursionCheck = true; + + juce_callAnyTimersSynchronously(); + + for (int i = ComponentPeer::getNumPeers(); --i >= 0;) + ComponentPeer::getPeer (i)->performAnyPendingRepaintsNow(); + + recursionCheck = false; + } + } + + void createEditorComp() + { + if (hasShutdown || filter == 0) + return; + + if (editorComp == 0) + { +#if JUCE_LINUX + const MessageManagerLock mml; +#endif + + AudioProcessorEditor* const ed = filter->createEditorIfNeeded(); + + if (ed != 0) + { + ed->setOpaque (true); + ed->setVisible (true); + + editorComp = new EditorCompWrapper (this, ed); + } + } + } + + void deleteEditor() + { + PopupMenu::dismissAllActiveMenus(); + + jassert (! recursionCheck); + recursionCheck = true; + +#if JUCE_LINUX + const MessageManagerLock mml; +#endif + + if (editorComp != 0) + { + Component* const modalComponent = Component::getCurrentlyModalComponent(); + if (modalComponent != 0) + modalComponent->exitModalState (0); + + filter->editorBeingDeleted (editorComp->getEditorComp()); + + deleteAndZero (editorComp); + + // there's some kind of component currently modal, but the host + // is trying to delete our plugin. You should try to avoid this happening.. + jassert (Component::getCurrentlyModalComponent() == 0); + } + +#if JUCE_MAC || JUCE_LINUX + hostWindow = 0; +#endif + + recursionCheck = false; + } + + VstIntPtr dispatcher (VstInt32 opCode, VstInt32 index, VstIntPtr value, void* ptr, float opt) + { + if (hasShutdown) + return 0; + + if (opCode == effEditIdle) + { + doIdleCallback(); + return 0; + } + else if (opCode == effEditOpen) + { + jassert (! recursionCheck); + + deleteEditor(); + createEditorComp(); + + if (editorComp != 0) + { +#if JUCE_LINUX + const MessageManagerLock mml; +#endif + + editorComp->setOpaque (true); + editorComp->setVisible (false); + +#if JUCE_WIN32 + editorComp->addToDesktop (0); + + hostWindow = (HWND) ptr; + HWND editorWnd = (HWND) editorComp->getWindowHandle(); + + SetParent (editorWnd, hostWindow); + + DWORD val = GetWindowLong (editorWnd, GWL_STYLE); + val = (val & ~WS_POPUP) | WS_CHILD; + SetWindowLong (editorWnd, GWL_STYLE, val); + + editorComp->setVisible (true); +#elif JUCE_LINUX + editorComp->addToDesktop (0); + + hostWindow = (Window) ptr; + + Window editorWnd = (Window) editorComp->getWindowHandle(); + + XReparentWindow (display, editorWnd, hostWindow, 0, 0); + + editorComp->setVisible (true); +#else + hostWindow = (WindowRef) ptr; + firstResize = true; + + SetAutomaticControlDragTrackingEnabledForWindow (hostWindow, true); + + WindowAttributes attributes; + GetWindowAttributes (hostWindow, &attributes); + + HIViewRef parentView = 0; + + if ((attributes & kWindowCompositingAttribute) != 0) + { + HIViewRef root = HIViewGetRoot (hostWindow); + HIViewFindByID (root, kHIViewWindowContentID, &parentView); + + if (parentView == 0) + parentView = root; + } + else + { + GetRootControl (hostWindow, (ControlRef*) &parentView); + + if (parentView == 0) + CreateRootControl (hostWindow, (ControlRef*) &parentView); + } + + jassert (parentView != 0); // agh - the host has to provide a compositing window.. + + editorComp->setVisible (true); + editorComp->addToDesktop (0, (void*) parentView); +#endif + + return 1; + } + } + else if (opCode == effEditClose) + { + deleteEditor(); + return 0; + } + else if (opCode == effEditGetRect) + { + createEditorComp(); + + if (editorComp != 0) + { + editorSize.left = 0; + editorSize.top = 0; + editorSize.right = editorComp->getWidth(); + editorSize.bottom = editorComp->getHeight(); + + *((ERect**) ptr) = &editorSize; + + return (VstIntPtr) &editorSize; + } + else + { + return 0; + } + } + + return AudioEffectX::dispatcher (opCode, index, value, ptr, opt); + } + + void resizeHostWindow (int newWidth, int newHeight) + { + if (editorComp != 0) + { +#if ! JUCE_LINUX // linux hosts shouldn't be trusted! + if (! (canHostDo ("sizeWindow") && sizeWindow (newWidth, newHeight))) +#endif + { + // some hosts don't support the sizeWindow call, so do it manually.. +#if JUCE_MAC + Rect r; + GetWindowBounds (hostWindow, kWindowContentRgn, &r); + + if (firstResize) + { + diffW = (r.right - r.left) - editorComp->getWidth(); + diffH = (r.bottom - r.top) - editorComp->getHeight(); + firstResize = false; + } + + r.right = r.left + newWidth + diffW; + r.bottom = r.top + newHeight + diffH; + + SetWindowBounds (hostWindow, kWindowContentRgn, &r); + + r.bottom -= r.top; + r.right -= r.left; + r.left = r.top = 0; + InvalWindowRect (hostWindow, &r); +#elif JUCE_LINUX + Window root; + int x, y; + unsigned int width, height, border, depth; + + XGetGeometry (display, hostWindow, &root, + &x, &y, &width, &height, &border, &depth); + + newWidth += (width + border) - editorComp->getWidth(); + newHeight += (height + border) - editorComp->getHeight(); + + XResizeWindow (display, hostWindow, newWidth, newHeight); +#else + int dw = 0; + int dh = 0; + const int frameThickness = GetSystemMetrics (SM_CYFIXEDFRAME); + + HWND w = (HWND) editorComp->getWindowHandle(); + + while (w != 0) + { + HWND parent = GetParent (w); + + if (parent == 0) + break; + + TCHAR windowType [32]; + zeromem (windowType, sizeof (windowType)); + GetClassName (parent, windowType, 31); + + if (String (windowType).equalsIgnoreCase (T("MDIClient"))) + break; + + RECT windowPos; + GetWindowRect (w, &windowPos); + + RECT parentPos; + GetWindowRect (parent, &parentPos); + + SetWindowPos (w, 0, 0, 0, + newWidth + dw, + newHeight + dh, + SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOOWNERZORDER); + + dw = (parentPos.right - parentPos.left) - (windowPos.right - windowPos.left); + dh = (parentPos.bottom - parentPos.top) - (windowPos.bottom - windowPos.top); + + w = parent; + + if (dw == 2 * frameThickness) + break; + + if (dw > 100 || dh > 100) + w = 0; + } + + if (w != 0) + SetWindowPos (w, 0, 0, 0, + newWidth + dw, + newHeight + dh, + SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOOWNERZORDER); +#endif + } + + if (editorComp->getPeer() != 0) + editorComp->getPeer()->handleMovedOrResized(); + } + } + + + //============================================================================== + juce_UseDebuggingNewOperator + +private: + AudioProcessor* filter; + juce::MemoryBlock chunkMemory; + uint32 chunkMemoryTime; + EditorCompWrapper* editorComp; + ERect editorSize; + MidiBuffer midiEvents; + VstEvents* outgoingEvents; + int outgoingEventSize; + bool isProcessing; + bool firstResize; + bool hasShutdown; + int diffW, diffH; + float** channels; + VoidArray tempChannels; // see note in processReplacing() + bool hasCreatedTempChannels; + + void deleteTempChannels() + { + int i; + for (i = tempChannels.size(); --i >= 0;) + juce_free (tempChannels.getUnchecked(i)); + + tempChannels.clear(); + + if (filter != 0) + tempChannels.insertMultiple (0, 0, filter->getNumInputChannels() + filter->getNumOutputChannels()); + + hasCreatedTempChannels = false; + } + + void ensureOutgoingEventSize (int numEvents) + { + if (outgoingEventSize < numEvents) + { + numEvents += 32; + const int size = 16 + sizeof (VstEvent*) * numEvents; + + if (outgoingEvents == 0) + outgoingEvents = (VstEvents*) juce_calloc (size); + else + outgoingEvents = (VstEvents*) juce_realloc (outgoingEvents, size); + + for (int i = outgoingEventSize; i < numEvents; ++i) + { + VstMidiEvent* const e = (VstMidiEvent*) juce_calloc (sizeof (VstMidiEvent)); + e->type = kVstMidiType; + e->byteSize = 24; + + outgoingEvents->events[i] = (VstEvent*) e; + } + + outgoingEventSize = numEvents; + } + } + + const String getHostName() + { + char host[256]; + zeromem (host, sizeof (host)); + getHostProductString (host); + return host; + } + +#if JUCE_MAC + WindowRef hostWindow; +#elif JUCE_LINUX + Window hostWindow; +#else + HWND hostWindow; +#endif +}; + +//============================================================================== +void EditorCompWrapper::childBoundsChanged (Component* child) +{ + child->setTopLeftPosition (0, 0); + + const int cw = child->getWidth(); + const int ch = child->getHeight(); + + wrapper->resizeHostWindow (cw, ch); + setSize (cw, ch); + +#if JUCE_MAC + wrapper->resizeHostWindow (cw, ch); // (doing this a second time seems to be necessary in tracktion) +#endif +} + +void EditorCompWrapper::handleAsyncUpdate() +{ + wrapper->tryMasterIdle(); +} + +//============================================================================== +/** Somewhere in the codebase of your plugin, you need to implement this function + and make it create an instance of the filter subclass that you're building. +*/ +extern AudioProcessor* JUCE_CALLTYPE createPluginFilter(); + + +//============================================================================== +static AEffect* pluginEntryPoint (audioMasterCallback audioMaster) +{ + initialiseJuce_GUI(); + + MessageManager::getInstance()->setTimeBeforeShowingWaitCursor (0); + + try + { + if (audioMaster (0, audioMasterVersion, 0, 0, 0, 0) != 0) + { + AudioProcessor* const filter = createPluginFilter(); + + if (filter != 0) + { + JuceVSTWrapper* const wrapper = new JuceVSTWrapper (audioMaster, filter); + return wrapper->getAeffect(); + } + } + } + catch (...) + {} + + return 0; +} + + +//============================================================================== +// Mac startup code.. +#if JUCE_MAC + +extern "C" __attribute__ ((visibility("default"))) AEffect* VSTPluginMain (audioMasterCallback audioMaster) +{ + return pluginEntryPoint (audioMaster); +} + +extern "C" __attribute__ ((visibility("default"))) AEffect* main_macho (audioMasterCallback audioMaster) +{ + return pluginEntryPoint (audioMaster); +} + +//============================================================================== +// Linux startup code.. +#elif JUCE_LINUX + +extern "C" AEffect* main_plugin (audioMasterCallback audioMaster) asm ("main"); + +extern "C" AEffect* main_plugin (audioMasterCallback audioMaster) +{ + initialiseJuce_GUI(); + SharedMessageThread::getInstance(); + + return pluginEntryPoint (audioMaster); +} + +__attribute__((constructor)) void myPluginInit() +{ + // don't put initialiseJuce_GUI here... it will crash ! +} + +__attribute__((destructor)) void myPluginFini() +{ + // don't put shutdownJuce_GUI here... it will crash ! +} + +//============================================================================== +// Win32 startup code.. +#else + +extern "C" __declspec (dllexport) AEffect* VSTPluginMain (audioMasterCallback audioMaster) +{ + return pluginEntryPoint (audioMaster); +} + +extern "C" __declspec (dllexport) void* main (audioMasterCallback audioMaster) +{ + return (void*) pluginEntryPoint (audioMaster); +} + +BOOL WINAPI DllMain (HINSTANCE instance, DWORD dwReason, LPVOID) +{ + if (dwReason == DLL_PROCESS_ATTACH) + PlatformUtilities::setCurrentModuleInstanceHandle (instance); + + return TRUE; +} + +#endif diff --git a/extras/audio plugins/wrapper/juce_IncludeCharacteristics.h b/extras/audio plugins/wrapper/juce_IncludeCharacteristics.h new file mode 100644 index 0000000000..1030d5fefb --- /dev/null +++ b/extras/audio plugins/wrapper/juce_IncludeCharacteristics.h @@ -0,0 +1,98 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +#ifndef __JUCE_INCLUDECHARACTERISTICS_JUCEHEADER__ +#define __JUCE_INCLUDECHARACTERISTICS_JUCEHEADER__ + +//============================================================================== +/* The JucePluginCharacteristics.h file is supposed to live in your plugin-specific + project directory, and has to contain info describing its name, type, etc. For + more info, see the JucePluginCharacteristics.h that is included in the demo plugin. + + You may need to adjust the include path of your project to make sure it can be + found by this include statement. (Don't hack this file to change the include path) +*/ +#include "JucePluginCharacteristics.h" + + +//============================================================================== +// The following stuff is just to cause a compile error if you've forgotten to +// define all your plugin settings properly. + +#ifndef JucePlugin_IsSynth + #error "You need to define the JucePlugin_IsSynth value in your JucePluginCharacteristics.h file!" +#endif + +#ifndef JucePlugin_ManufacturerCode + #error "You need to define the JucePlugin_ManufacturerCode value in your JucePluginCharacteristics.h file!" +#endif + +#ifndef JucePlugin_PluginCode + #error "You need to define the JucePlugin_PluginCode value in your JucePluginCharacteristics.h file!" +#endif + +#ifndef JucePlugin_ProducesMidiOutput + #error "You need to define the JucePlugin_ProducesMidiOutput value in your JucePluginCharacteristics.h file!" +#endif + +#ifndef JucePlugin_WantsMidiInput + #error "You need to define the JucePlugin_WantsMidiInput value in your JucePluginCharacteristics.h file!" +#endif + +#ifndef JucePlugin_MaxNumInputChannels + #error "You need to define the JucePlugin_MaxNumInputChannels value in your JucePluginCharacteristics.h file!" +#endif + +#ifndef JucePlugin_MaxNumOutputChannels + #error "You need to define the JucePlugin_MaxNumOutputChannels value in your JucePluginCharacteristics.h file!" +#endif + +#ifndef JucePlugin_PreferredChannelConfigurations + #error "You need to define the JucePlugin_PreferredChannelConfigurations value in your JucePluginCharacteristics.h file!" +#endif + +#ifdef JucePlugin_Latency + #error "JucePlugin_Latency is now deprecated - instead, call the AudioProcessor::setLatencySamples() method if your plugin has a non-zero delay" +#endif + +#ifndef JucePlugin_SilenceInProducesSilenceOut + #error "You need to define the JucePlugin_SilenceInProducesSilenceOut value in your JucePluginCharacteristics.h file!" +#endif + +#ifndef JucePlugin_EditorRequiresKeyboardFocus + #error "You need to define the JucePlugin_EditorRequiresKeyboardFocus value in your JucePluginCharacteristics.h file!" +#endif + +#if JUCE_USE_VSTSDK_2_4 != 0 && JUCE_USE_VSTSDK_2_4 != 1 + #error "You need to define the JUCE_USE_VSTSDK_2_4 value in your JucePluginCharacteristics.h file!" +#endif + +#endif // __JUCE_INCLUDECHARACTERISTICS_JUCEHEADER__