diff --git a/build/macosx/platform_specific_code/juce_mac_NativeCode.mm b/build/macosx/platform_specific_code/juce_mac_NativeCode.mm index b8e80199a6..f4fffb2cfd 100644 --- a/build/macosx/platform_specific_code/juce_mac_NativeCode.mm +++ b/build/macosx/platform_specific_code/juce_mac_NativeCode.mm @@ -78,10 +78,12 @@ BEGIN_JUCE_NAMESPACE #undef Point //============================================================================== -#define ObjCExtraSuffix 1 +#ifndef JUCE_ObjCExtraSuffix + #define JUCE_ObjCExtraSuffix 2 +#endif #define appendMacro1(a, b, c, d) a ## _ ## b ## _ ## c ## _ ## d #define appendMacro2(a, b, c, d) appendMacro1(a, b, c, d) -#define MakeObjCClassName(rootName) appendMacro2 (rootName, JUCE_MAJOR_VERSION, JUCE_MINOR_VERSION, ObjCExtraSuffix) +#define MakeObjCClassName(rootName) appendMacro2 (rootName, JUCE_MAJOR_VERSION, JUCE_MINOR_VERSION, JUCE_ObjCExtraSuffix) //============================================================================== #define JUCE_INCLUDED_FILE 1 diff --git a/build/win32/platform_specific_code/juce_win32_PlatformUtils.cpp b/build/win32/platform_specific_code/juce_win32_PlatformUtils.cpp index 35d0812a29..b4066e31ed 100644 --- a/build/win32/platform_specific_code/juce_win32_PlatformUtils.cpp +++ b/build/win32/platform_specific_code/juce_win32_PlatformUtils.cpp @@ -159,9 +159,9 @@ void PlatformUtilities::deleteRegistryKey (const String& regKeyPath) } } -void PlatformUtilities::registerFileAssociation (const String& fileExtension, - const String& symbolicDescription, - const String& fullDescription, +void PlatformUtilities::registerFileAssociation (const String& fileExtension, + const String& symbolicDescription, + const String& fullDescription, const File& targetExecutable, int iconResourceNumber) { @@ -175,7 +175,7 @@ void PlatformUtilities::registerFileAssociation (const String& fileExtension, setRegistryValue (key + "\\", fullDescription); - setRegistryValue (key + "\\shell\\open\\command\\", + setRegistryValue (key + "\\shell\\open\\command\\", targetExecutable.getFullPathName() + " %1"); } diff --git a/extras/audio plugins/demo/src/JucePluginCharacteristics.h b/extras/audio plugins/demo/src/JucePluginCharacteristics.h index 08db649a94..4281ed171b 100644 --- a/extras/audio plugins/demo/src/JucePluginCharacteristics.h +++ b/extras/audio plugins/demo/src/JucePluginCharacteristics.h @@ -1,285 +1,285 @@ -/* - ============================================================================== - - 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. -*/ - - -//============================================================================== -/* Plugin Formats to build */ - -#define JucePlugin_Build_VST 1 -#define JucePlugin_Build_RTAS 0 -#define JucePlugin_Build_AU 1 - - -//============================================================================== -/* 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 - -/** You need to set this path to point to the location of the Digidesign WinBag - directory on your machine. (Only needed for Windows builds). Make sure you - don't put a slash on the end. -*/ -#define JucePlugin_WinBag_path "C:\\essentials\\PT_73_SDK\\WinBag" - - -//============================================================================== - -#endif +/* + ============================================================================== + + 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. +*/ + + +//============================================================================== +/* Plugin Formats to build */ + +#define JucePlugin_Build_VST 1 +#define JucePlugin_Build_RTAS 0 +#define JucePlugin_Build_AU 1 + + +//============================================================================== +/* 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 + +/** You need to set this path to point to the location of the Digidesign WinBag + directory on your machine. (Only needed for Windows builds). Make sure you + don't put a slash on the end. +*/ +#define JucePlugin_WinBag_path "C:\\essentials\\PT_73_SDK\\WinBag" + + +//============================================================================== + +#endif diff --git a/extras/audio plugins/wrapper/RTAS/juce_RTAS_MacUtilities.mm b/extras/audio plugins/wrapper/RTAS/juce_RTAS_MacUtilities.mm index e6f76ab9e5..5d54f709af 100644 --- a/extras/audio plugins/wrapper/RTAS/juce_RTAS_MacUtilities.mm +++ b/extras/audio plugins/wrapper/RTAS/juce_RTAS_MacUtilities.mm @@ -1,101 +1,101 @@ -/* - ============================================================================== - - 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 you get an error here, you might need to make sure that -// your build config files don't specify "C++" as one of the -// flags in OTHER_CFLAGS, because that stops the compiler building -// obj-c files correctly. -@class dummyclassname; - -#include -#include "../juce_PluginHeaders.h" - -#if JucePlugin_Build_RTAS - - -//============================================================================== -void initialiseMacRTAS() -{ - NSApplicationLoad(); -} - -void* attachSubWindow (void* hostWindowRef, Component* comp) -{ - const ScopedAutoReleasePool pool; - - NSWindow* hostWindow = [[NSWindow alloc] initWithWindowRef: hostWindowRef]; - [hostWindow retain]; - [hostWindow setCanHide: YES]; - [hostWindow setReleasedWhenClosed: YES]; - - NSView* content = [hostWindow contentView]; - NSRect f = [content frame]; - f.size.width = comp->getWidth(); - f.size.height = comp->getHeight(); - [content setFrame: f]; - - NSPoint windowPos = [hostWindow convertBaseToScreen: f.origin]; - windowPos.y = [[NSScreen mainScreen] frame].size.height - (windowPos.y + f.size.height); - - comp->setTopLeftPosition ((int) windowPos.x, (int) windowPos.y); - -#if ! JucePlugin_EditorRequiresKeyboardFocus - comp->addToDesktop (ComponentPeer::windowIsTemporary | ComponentPeer::windowIgnoresKeyPresses); -#else - comp->addToDesktop (ComponentPeer::windowIsTemporary); -#endif - - comp->setVisible (true); - - NSView* pluginView = (NSView*) comp->getWindowHandle(); - NSWindow* pluginWindow = [pluginView window]; - - [hostWindow addChildWindow: pluginWindow - ordered: NSWindowAbove]; - [hostWindow orderFront: nil]; - [pluginWindow orderFront: nil]; - return hostWindow; -} - -void removeSubWindow (void* nsWindow, Component* comp) -{ - const ScopedAutoReleasePool pool; - - NSView* pluginView = (NSView*) comp->getWindowHandle(); - NSWindow* hostWindow = (NSWindow*) nsWindow; - NSWindow* pluginWindow = [pluginView window]; - - [hostWindow removeChildWindow: pluginWindow]; - comp->removeFromDesktop(); - [hostWindow release]; -} - -#endif +/* + ============================================================================== + + 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 you get an error here, you might need to make sure that +// your build config files don't specify "C++" as one of the +// flags in OTHER_CFLAGS, because that stops the compiler building +// obj-c files correctly. +@class dummyclassname; + +#include +#include "../juce_PluginHeaders.h" + +#if JucePlugin_Build_RTAS + + +//============================================================================== +void initialiseMacRTAS() +{ + NSApplicationLoad(); +} + +void* attachSubWindow (void* hostWindowRef, Component* comp) +{ + const ScopedAutoReleasePool pool; + + NSWindow* hostWindow = [[NSWindow alloc] initWithWindowRef: hostWindowRef]; + [hostWindow retain]; + [hostWindow setCanHide: YES]; + [hostWindow setReleasedWhenClosed: YES]; + + NSView* content = [hostWindow contentView]; + NSRect f = [content frame]; + f.size.width = comp->getWidth(); + f.size.height = comp->getHeight(); + [content setFrame: f]; + + NSPoint windowPos = [hostWindow convertBaseToScreen: f.origin]; + windowPos.y = [[NSScreen mainScreen] frame].size.height - (windowPos.y + f.size.height); + + comp->setTopLeftPosition ((int) windowPos.x, (int) windowPos.y); + +#if ! JucePlugin_EditorRequiresKeyboardFocus + comp->addToDesktop (ComponentPeer::windowIsTemporary | ComponentPeer::windowIgnoresKeyPresses); +#else + comp->addToDesktop (ComponentPeer::windowIsTemporary); +#endif + + comp->setVisible (true); + + NSView* pluginView = (NSView*) comp->getWindowHandle(); + NSWindow* pluginWindow = [pluginView window]; + + [hostWindow addChildWindow: pluginWindow + ordered: NSWindowAbove]; + [hostWindow orderFront: nil]; + [pluginWindow orderFront: nil]; + return hostWindow; +} + +void removeSubWindow (void* nsWindow, Component* comp) +{ + const ScopedAutoReleasePool pool; + + NSView* pluginView = (NSView*) comp->getWindowHandle(); + NSWindow* hostWindow = (NSWindow*) nsWindow; + NSWindow* pluginWindow = [pluginView window]; + + [hostWindow removeChildWindow: pluginWindow]; + comp->removeFromDesktop(); + [hostWindow release]; +} + +#endif diff --git a/extras/audio plugins/wrapper/RTAS/juce_RTAS_Wrapper.cpp b/extras/audio plugins/wrapper/RTAS/juce_RTAS_Wrapper.cpp index 700027f079..46fb99fcb2 100644 --- a/extras/audio plugins/wrapper/RTAS/juce_RTAS_Wrapper.cpp +++ b/extras/audio plugins/wrapper/RTAS/juce_RTAS_Wrapper.cpp @@ -1,991 +1,991 @@ -/* - ============================================================================== - - 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_RTAS_DigiCode_Header.h" - -#if JucePlugin_Build_RTAS - -#ifdef _MSC_VER - #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 - - NB. If you hit a huge pile of bugs around here, make sure that you've not got the - Apple QuickTime headers before the PT headers in your path, because there are - some filename clashes between them. - -*/ -#include "CEffectGroupMIDI.h" -#include "CEffectProcessMIDI.h" -#include "CEffectProcessRTAS.h" -#include "CCustomView.h" -#include "CEffectTypeRTAS.h" -#include "CPluginControl.h" -#include "CPluginControl_OnOff.h" -#include "FicProcessTokens.h" - -//============================================================================== -#ifdef _MSC_VER - #pragma pack (push, 8) -#endif - -#include "../juce_PluginHeaders.h" - -#ifdef _MSC_VER - #pragma pack (pop) - - #if JUCE_DEBUG - #define PT_LIB_PATH JucePlugin_WinBag_path "\\Debug\\lib\\" - #else - #define PT_LIB_PATH JucePlugin_WinBag_path "\\Release\\lib\\" - #endif - - #pragma comment(lib, PT_LIB_PATH "DAE.lib") - #pragma comment(lib, PT_LIB_PATH "DigiExt.lib") - #pragma comment(lib, PT_LIB_PATH "DSI.lib") - #pragma comment(lib, PT_LIB_PATH "PluginLib.lib") - -#endif - -#undef Component -#undef MemoryBlock - -//============================================================================== -#if JUCE_WIN32 - extern void JUCE_CALLTYPE attachSubWindow (void* hostWindow, int& titleW, int& titleH, JUCE_NAMESPACE::Component* comp); - extern void JUCE_CALLTYPE resizeHostWindow (void* hostWindow, int& titleW, int& titleH, JUCE_NAMESPACE::Component* comp); - #if ! JucePlugin_EditorRequiresKeyboardFocus - extern void JUCE_CALLTYPE passFocusToHostWindow (void* hostWindow); - #endif -#else - extern void* attachSubWindow (void* hostWindowRef, JUCE_NAMESPACE::Component* comp); - extern void removeSubWindow (void* nsWindow, JUCE_NAMESPACE::Component* comp); -#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() - : midiBufferNode (0), - midiTransport (0), - channels (0), - prepared (false), - 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 Timer - { - public: - //============================================================================== - JuceCustomUIView (AudioProcessor* const filter_, - JucePlugInProcess* const process_) - : filter (filter_), - process (process_), - wrapper (0), - editorComp (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 oldRect; - GetRect (&oldRect); - - Rect r; - r.left = 0; - r.top = 0; - r.right = editorComp->getWidth(); - r.bottom = editorComp->getHeight(); - SetRect (&r); - - if ((oldRect.right != r.right) || (oldRect.bottom != r.bottom)) - startTimer (50); - } - - void timerCallback() - { - if (! JUCE_NAMESPACE::Component::isMouseButtonDownAnywhere()) - { - stopTimer(); - - // Send a token to the host to tell it about the resize - SSetProcessWindowResizeToken token (process->fRootNameId, process->fRootNameId); - FicSDSDispatchToken (&token); - } - } - - 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 JUCE_WIN32 - if (wrapper != 0) - { - ComponentPeer* const peer = wrapper->getPeer(); - - if (peer != 0) - { - // (seems to be required in PT6.4, but not in 7.x) - peer->repaint (0, 0, wrapper->getWidth(), wrapper->getHeight()); - } - } -#endif - } - - void DrawBackground (Rect*) {} - - //============================================================================== - private: - AudioProcessor* const filter; - JucePlugInProcess* const process; - JUCE_NAMESPACE::Component* wrapper; - AudioProcessorEditor* editorComp; - - void deleteEditorComp() - { - if (editorComp != 0 || wrapper != 0) - { -#if JUCE_MAC - const ScopedAutoReleasePool pool; -#endif - PopupMenu::dismissAllActiveMenus(); - - JUCE_NAMESPACE::Component* const modalComponent = JUCE_NAMESPACE::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_NAMESPACE::Component -#if ! JUCE_MAC - , public FocusChangeListener -#endif - { - public: - EditorCompWrapper (void* const hostWindow_, - Component* const editorComp, - JuceCustomUIView* const owner_) - : hostWindow (hostWindow_), - owner (owner_), - titleW (0), - titleH (0) - { -#if JucePlugin_EditorRequiresKeyboardFocus - setWantsKeyboardFocus (true); -#else - setWantsKeyboardFocus (false); -#endif - setOpaque (true); - setBroughtToFrontOnMouseClick (true); - setBounds (editorComp->getBounds()); - editorComp->setTopLeftPosition (0, 0); - addAndMakeVisible (editorComp); - -#if JUCE_WIN32 - attachSubWindow (hostWindow, titleW, titleH, this); -#else - nsWindow = attachSubWindow (hostWindow, this); -#endif - setVisible (true); - -#if JUCE_WIN32 && ! JucePlugin_EditorRequiresKeyboardFocus - Desktop::getInstance().addFocusChangeListener (this); -#endif - } - - ~EditorCompWrapper() - { -#if JUCE_WIN32 && ! JucePlugin_EditorRequiresKeyboardFocus - Desktop::getInstance().removeFocusChangeListener (this); -#endif - -#if JUCE_MAC - removeSubWindow (nsWindow, this); -#endif - } - - void paint (Graphics&) - { - } - - void resized() - { - JUCE_NAMESPACE::Component* const c = getChildComponent (0); - - if (c != 0) - c->setBounds (0, 0, getWidth(), getHeight()); - - repaint(); - } - -#if JUCE_WIN32 - void globalFocusChanged (JUCE_NAMESPACE::Component*) - { - #if ! JucePlugin_EditorRequiresKeyboardFocus - if (hasKeyboardFocus (true)) - passFocusToHostWindow (hostWindow); - #endif - } -#endif - - void childBoundsChanged (JUCE_NAMESPACE::Component* child) - { - setSize (child->getWidth(), child->getHeight()); - child->setTopLeftPosition (0, 0); - -#if JUCE_WIN32 - resizeHostWindow (hostWindow, titleW, titleH, this); -#endif - owner->updateSize(); - } - - void userTriedToCloseWindow() - { - } - - //============================================================================== - juce_UseDebuggingNewOperator - - private: - void* const hostWindow; - void* nsWindow; - JuceCustomUIView* const owner; - int titleW, titleH; - }; - }; - - 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, this); - } - - 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(); - (void) numMidiEventsComingIn; -#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 juce::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 0: - return ePlugIn_StemFormat_Generic; - - 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; - } -}; - -void initialiseMacRTAS(); - -CProcessGroupInterface* CProcessGroup::CreateProcessGroup() -{ - initialiseMacRTAS(); - initialiseJuce_NonGUI(); - return new JucePlugInGroup(); -} - -#endif +/* + ============================================================================== + + 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_RTAS_DigiCode_Header.h" + +#if JucePlugin_Build_RTAS + +#ifdef _MSC_VER + #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 + + NB. If you hit a huge pile of bugs around here, make sure that you've not got the + Apple QuickTime headers before the PT headers in your path, because there are + some filename clashes between them. + +*/ +#include "CEffectGroupMIDI.h" +#include "CEffectProcessMIDI.h" +#include "CEffectProcessRTAS.h" +#include "CCustomView.h" +#include "CEffectTypeRTAS.h" +#include "CPluginControl.h" +#include "CPluginControl_OnOff.h" +#include "FicProcessTokens.h" + +//============================================================================== +#ifdef _MSC_VER + #pragma pack (push, 8) +#endif + +#include "../juce_PluginHeaders.h" + +#ifdef _MSC_VER + #pragma pack (pop) + + #if JUCE_DEBUG + #define PT_LIB_PATH JucePlugin_WinBag_path "\\Debug\\lib\\" + #else + #define PT_LIB_PATH JucePlugin_WinBag_path "\\Release\\lib\\" + #endif + + #pragma comment(lib, PT_LIB_PATH "DAE.lib") + #pragma comment(lib, PT_LIB_PATH "DigiExt.lib") + #pragma comment(lib, PT_LIB_PATH "DSI.lib") + #pragma comment(lib, PT_LIB_PATH "PluginLib.lib") + +#endif + +#undef Component +#undef MemoryBlock + +//============================================================================== +#if JUCE_WIN32 + extern void JUCE_CALLTYPE attachSubWindow (void* hostWindow, int& titleW, int& titleH, JUCE_NAMESPACE::Component* comp); + extern void JUCE_CALLTYPE resizeHostWindow (void* hostWindow, int& titleW, int& titleH, JUCE_NAMESPACE::Component* comp); + #if ! JucePlugin_EditorRequiresKeyboardFocus + extern void JUCE_CALLTYPE passFocusToHostWindow (void* hostWindow); + #endif +#else + extern void* attachSubWindow (void* hostWindowRef, JUCE_NAMESPACE::Component* comp); + extern void removeSubWindow (void* nsWindow, JUCE_NAMESPACE::Component* comp); +#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() + : midiBufferNode (0), + midiTransport (0), + channels (0), + prepared (false), + 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 Timer + { + public: + //============================================================================== + JuceCustomUIView (AudioProcessor* const filter_, + JucePlugInProcess* const process_) + : filter (filter_), + process (process_), + wrapper (0), + editorComp (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 oldRect; + GetRect (&oldRect); + + Rect r; + r.left = 0; + r.top = 0; + r.right = editorComp->getWidth(); + r.bottom = editorComp->getHeight(); + SetRect (&r); + + if ((oldRect.right != r.right) || (oldRect.bottom != r.bottom)) + startTimer (50); + } + + void timerCallback() + { + if (! JUCE_NAMESPACE::Component::isMouseButtonDownAnywhere()) + { + stopTimer(); + + // Send a token to the host to tell it about the resize + SSetProcessWindowResizeToken token (process->fRootNameId, process->fRootNameId); + FicSDSDispatchToken (&token); + } + } + + 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 JUCE_WIN32 + if (wrapper != 0) + { + ComponentPeer* const peer = wrapper->getPeer(); + + if (peer != 0) + { + // (seems to be required in PT6.4, but not in 7.x) + peer->repaint (0, 0, wrapper->getWidth(), wrapper->getHeight()); + } + } +#endif + } + + void DrawBackground (Rect*) {} + + //============================================================================== + private: + AudioProcessor* const filter; + JucePlugInProcess* const process; + JUCE_NAMESPACE::Component* wrapper; + AudioProcessorEditor* editorComp; + + void deleteEditorComp() + { + if (editorComp != 0 || wrapper != 0) + { +#if JUCE_MAC + const ScopedAutoReleasePool pool; +#endif + PopupMenu::dismissAllActiveMenus(); + + JUCE_NAMESPACE::Component* const modalComponent = JUCE_NAMESPACE::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_NAMESPACE::Component +#if ! JUCE_MAC + , public FocusChangeListener +#endif + { + public: + EditorCompWrapper (void* const hostWindow_, + Component* const editorComp, + JuceCustomUIView* const owner_) + : hostWindow (hostWindow_), + owner (owner_), + titleW (0), + titleH (0) + { +#if JucePlugin_EditorRequiresKeyboardFocus + setWantsKeyboardFocus (true); +#else + setWantsKeyboardFocus (false); +#endif + setOpaque (true); + setBroughtToFrontOnMouseClick (true); + setBounds (editorComp->getBounds()); + editorComp->setTopLeftPosition (0, 0); + addAndMakeVisible (editorComp); + +#if JUCE_WIN32 + attachSubWindow (hostWindow, titleW, titleH, this); +#else + nsWindow = attachSubWindow (hostWindow, this); +#endif + setVisible (true); + +#if JUCE_WIN32 && ! JucePlugin_EditorRequiresKeyboardFocus + Desktop::getInstance().addFocusChangeListener (this); +#endif + } + + ~EditorCompWrapper() + { +#if JUCE_WIN32 && ! JucePlugin_EditorRequiresKeyboardFocus + Desktop::getInstance().removeFocusChangeListener (this); +#endif + +#if JUCE_MAC + removeSubWindow (nsWindow, this); +#endif + } + + void paint (Graphics&) + { + } + + void resized() + { + JUCE_NAMESPACE::Component* const c = getChildComponent (0); + + if (c != 0) + c->setBounds (0, 0, getWidth(), getHeight()); + + repaint(); + } + +#if JUCE_WIN32 + void globalFocusChanged (JUCE_NAMESPACE::Component*) + { + #if ! JucePlugin_EditorRequiresKeyboardFocus + if (hasKeyboardFocus (true)) + passFocusToHostWindow (hostWindow); + #endif + } +#endif + + void childBoundsChanged (JUCE_NAMESPACE::Component* child) + { + setSize (child->getWidth(), child->getHeight()); + child->setTopLeftPosition (0, 0); + +#if JUCE_WIN32 + resizeHostWindow (hostWindow, titleW, titleH, this); +#endif + owner->updateSize(); + } + + void userTriedToCloseWindow() + { + } + + //============================================================================== + juce_UseDebuggingNewOperator + + private: + void* const hostWindow; + void* nsWindow; + JuceCustomUIView* const owner; + int titleW, titleH; + }; + }; + + 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, this); + } + + 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(); + (void) numMidiEventsComingIn; +#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 juce::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 0: + return ePlugIn_StemFormat_Generic; + + 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; + } +}; + +void initialiseMacRTAS(); + +CProcessGroupInterface* CProcessGroup::CreateProcessGroup() +{ + initialiseMacRTAS(); + initialiseJuce_NonGUI(); + return new JucePlugInGroup(); +} + +#endif diff --git a/extras/audio plugins/wrapper/Standalone/juce_AudioFilterStreamer.cpp b/extras/audio plugins/wrapper/Standalone/juce_AudioFilterStreamer.cpp index 89662f7fd4..2db7a15942 100644 --- a/extras/audio plugins/wrapper/Standalone/juce_AudioFilterStreamer.cpp +++ b/extras/audio plugins/wrapper/Standalone/juce_AudioFilterStreamer.cpp @@ -30,7 +30,7 @@ */ #include "juce_AudioFilterStreamer.h" -#include "../../juce_IncludeCharacteristics.h" +#include "../juce_IncludeCharacteristics.h" //============================================================================== diff --git a/extras/audio plugins/wrapper/VST/juce_VST_Wrapper.mm b/extras/audio plugins/wrapper/VST/juce_VST_Wrapper.mm index 33eb372bca..338186f776 100644 --- a/extras/audio plugins/wrapper/VST/juce_VST_Wrapper.mm +++ b/extras/audio plugins/wrapper/VST/juce_VST_Wrapper.mm @@ -1,171 +1,171 @@ -/* - ============================================================================== - - 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_IncludeCharacteristics.h" - -#if JucePlugin_Build_VST - -#include - -#define ADD_CARBON_BODGE 1 // see note below.. - -#if ADD_CARBON_BODGE - #include -#endif - -#include "../juce_PluginHeaders.h" - -//============================================================================== -BEGIN_JUCE_NAMESPACE - -#if ADD_CARBON_BODGE -/* When you wrap a WindowRef as an NSWindow, it seems to bugger up the HideWindow - function, so when the host tries (and fails) to hide the window, this catches - the event and does the job properly. -*/ - -static pascal OSStatus windowVisibilityBodge (EventHandlerCallRef, EventRef e, void* user) -{ - NSWindow* hostWindow = (NSWindow*) user; - - switch (GetEventKind (e)) - { - case kEventWindowShown: - [hostWindow orderFront: nil]; - break; - case kEventWindowHidden: - [hostWindow orderOut: nil]; - break; - } - - return eventNotHandledErr; -} -#endif - -//============================================================================== -void initialiseMac() -{ - NSApplicationLoad(); -} - -void* attachComponentToWindowRef (Component* comp, void* windowRef) -{ - const ScopedAutoReleasePool pool; - - NSWindow* hostWindow = [[NSWindow alloc] initWithWindowRef: windowRef]; - [hostWindow retain]; - [hostWindow setCanHide: YES]; - [hostWindow setReleasedWhenClosed: YES]; - - NSView* content = [hostWindow contentView]; - NSRect f = [content frame]; - NSPoint windowPos = [hostWindow convertBaseToScreen: f.origin]; - windowPos.y = [[NSScreen mainScreen] frame].size.height - (windowPos.y + f.size.height); - comp->setTopLeftPosition ((int) windowPos.x, (int) windowPos.y); - -#if ! JucePlugin_EditorRequiresKeyboardFocus - comp->addToDesktop (ComponentPeer::windowIsTemporary | ComponentPeer::windowIgnoresKeyPresses); -#else - comp->addToDesktop (ComponentPeer::windowIsTemporary); -#endif - - comp->setVisible (true); - comp->toFront (false); - - NSView* pluginView = (NSView*) comp->getWindowHandle(); - NSWindow* pluginWindow = [pluginView window]; - [pluginWindow setExcludedFromWindowsMenu: YES]; - [pluginWindow setCanHide: YES]; - - [hostWindow addChildWindow: pluginWindow - ordered: NSWindowAbove]; - [hostWindow orderFront: nil]; - [pluginWindow orderFront: nil]; - -#if ADD_CARBON_BODGE - // Adds a callback bodge to work around some problems with wrapped - // carbon windows.. - const EventTypeSpec eventsToCatch[] = { - { kEventClassWindow, kEventWindowShown }, - { kEventClassWindow, kEventWindowHidden } - }; - - InstallWindowEventHandler ((WindowRef) windowRef, - NewEventHandlerUPP (windowVisibilityBodge), - GetEventTypeCount (eventsToCatch), eventsToCatch, - (void*) hostWindow, 0); -#endif - - return hostWindow; -} - -void detachComponentFromWindowRef (Component* comp, void* nsWindow) -{ - const ScopedAutoReleasePool pool; - - NSWindow* hostWindow = (NSWindow*) nsWindow; - NSView* pluginView = (NSView*) comp->getWindowHandle(); - NSWindow* pluginWindow = [pluginView window]; - - [hostWindow removeChildWindow: pluginWindow]; - comp->removeFromDesktop(); - - [hostWindow release]; -} - -void setNativeHostWindowSize (void* nsWindow, Component* component, int newWidth, int newHeight) -{ - NSWindow* hostWindow = (NSWindow*) nsWindow; - if (hostWindow != 0) - { - ScopedAutoReleasePool pool; - - // Can't use the cocoa NSWindow resizing code, or it messes up in Live. - Rect r; - GetWindowBounds ((WindowRef) [hostWindow windowRef], kWindowContentRgn, &r); - r.right += newWidth - component->getWidth(); - r.bottom += newHeight - component->getHeight(); - SetWindowBounds ((WindowRef) [hostWindow windowRef], kWindowContentRgn, &r); - - [[hostWindow contentView] setNeedsDisplay: YES]; - } -} - -void checkWindowVisibility (void* nsWindow, Component* comp) -{ - NSWindow* hostWindow = (NSWindow*) nsWindow; - comp->setVisible ([hostWindow isVisible]); -} - -END_JUCE_NAMESPACE - -#endif +/* + ============================================================================== + + 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_IncludeCharacteristics.h" + +#if JucePlugin_Build_VST + +#include + +#define ADD_CARBON_BODGE 1 // see note below.. + +#if ADD_CARBON_BODGE + #include +#endif + +#include "../juce_PluginHeaders.h" + +//============================================================================== +BEGIN_JUCE_NAMESPACE + +#if ADD_CARBON_BODGE +/* When you wrap a WindowRef as an NSWindow, it seems to bugger up the HideWindow + function, so when the host tries (and fails) to hide the window, this catches + the event and does the job properly. +*/ + +static pascal OSStatus windowVisibilityBodge (EventHandlerCallRef, EventRef e, void* user) +{ + NSWindow* hostWindow = (NSWindow*) user; + + switch (GetEventKind (e)) + { + case kEventWindowShown: + [hostWindow orderFront: nil]; + break; + case kEventWindowHidden: + [hostWindow orderOut: nil]; + break; + } + + return eventNotHandledErr; +} +#endif + +//============================================================================== +void initialiseMac() +{ + NSApplicationLoad(); +} + +void* attachComponentToWindowRef (Component* comp, void* windowRef) +{ + const ScopedAutoReleasePool pool; + + NSWindow* hostWindow = [[NSWindow alloc] initWithWindowRef: windowRef]; + [hostWindow retain]; + [hostWindow setCanHide: YES]; + [hostWindow setReleasedWhenClosed: YES]; + + NSView* content = [hostWindow contentView]; + NSRect f = [content frame]; + NSPoint windowPos = [hostWindow convertBaseToScreen: f.origin]; + windowPos.y = [[NSScreen mainScreen] frame].size.height - (windowPos.y + f.size.height); + comp->setTopLeftPosition ((int) windowPos.x, (int) windowPos.y); + +#if ! JucePlugin_EditorRequiresKeyboardFocus + comp->addToDesktop (ComponentPeer::windowIsTemporary | ComponentPeer::windowIgnoresKeyPresses); +#else + comp->addToDesktop (ComponentPeer::windowIsTemporary); +#endif + + comp->setVisible (true); + comp->toFront (false); + + NSView* pluginView = (NSView*) comp->getWindowHandle(); + NSWindow* pluginWindow = [pluginView window]; + [pluginWindow setExcludedFromWindowsMenu: YES]; + [pluginWindow setCanHide: YES]; + + [hostWindow addChildWindow: pluginWindow + ordered: NSWindowAbove]; + [hostWindow orderFront: nil]; + [pluginWindow orderFront: nil]; + +#if ADD_CARBON_BODGE + // Adds a callback bodge to work around some problems with wrapped + // carbon windows.. + const EventTypeSpec eventsToCatch[] = { + { kEventClassWindow, kEventWindowShown }, + { kEventClassWindow, kEventWindowHidden } + }; + + InstallWindowEventHandler ((WindowRef) windowRef, + NewEventHandlerUPP (windowVisibilityBodge), + GetEventTypeCount (eventsToCatch), eventsToCatch, + (void*) hostWindow, 0); +#endif + + return hostWindow; +} + +void detachComponentFromWindowRef (Component* comp, void* nsWindow) +{ + const ScopedAutoReleasePool pool; + + NSWindow* hostWindow = (NSWindow*) nsWindow; + NSView* pluginView = (NSView*) comp->getWindowHandle(); + NSWindow* pluginWindow = [pluginView window]; + + [hostWindow removeChildWindow: pluginWindow]; + comp->removeFromDesktop(); + + [hostWindow release]; +} + +void setNativeHostWindowSize (void* nsWindow, Component* component, int newWidth, int newHeight) +{ + NSWindow* hostWindow = (NSWindow*) nsWindow; + if (hostWindow != 0) + { + ScopedAutoReleasePool pool; + + // Can't use the cocoa NSWindow resizing code, or it messes up in Live. + Rect r; + GetWindowBounds ((WindowRef) [hostWindow windowRef], kWindowContentRgn, &r); + r.right += newWidth - component->getWidth(); + r.bottom += newHeight - component->getHeight(); + SetWindowBounds ((WindowRef) [hostWindow windowRef], kWindowContentRgn, &r); + + [[hostWindow contentView] setNeedsDisplay: YES]; + } +} + +void checkWindowVisibility (void* nsWindow, Component* comp) +{ + NSWindow* hostWindow = (NSWindow*) nsWindow; + comp->setVisible ([hostWindow isVisible]); +} + +END_JUCE_NAMESPACE + +#endif diff --git a/extras/juce demo/src/BinaryData.cpp b/extras/juce demo/src/BinaryData.cpp index 73bc33a63e..ea2472e13b 100644 --- a/extras/juce demo/src/BinaryData.cpp +++ b/extras/juce demo/src/BinaryData.cpp @@ -7974,4 +7974,3 @@ static const unsigned char temp17[] = {47,42,13,10,32,32,61,61,61,61,61,61,61,61 111,109,109,97,110,100,77,97,110,97,103,101,114,41,13,10,123,13,10,32,32,32,32,114,101,116,117,114,110,32,110,101,119,32,87,105,100,103,101,116, 115,68,101,109,111,32,40,99,111,109,109,97,110,100,77,97,110,97,103,101,114,41,59,13,10,125,13,10,0,0}; const char* BinaryData::widgetsdemo_cpp = (const char*) temp17; - diff --git a/extras/the jucer/src/BinaryData.cpp b/extras/the jucer/src/BinaryData.cpp index c08fddd03e..1279f531a8 100644 --- a/extras/the jucer/src/BinaryData.cpp +++ b/extras/the jucer/src/BinaryData.cpp @@ -911,4 +911,3 @@ static const unsigned char temp4[] = {137,80,78,71,13,10,26,10,0,0,0,13,73,72,68 0,98,28,9,155,95,0,2,104,68,236,11,1,8,160,17,225,73,128,0,3,0,120,52,172,151,198,78,252,63,0,0,0,0,73,69,78,68,174,66, 96,130,0,0}; const char* BinaryData::prefs_misc_png = (const char*) temp4; - diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index 6fbd529528..cfc3d4b1fa 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -262487,10 +262487,12 @@ BEGIN_JUCE_NAMESPACE #undef Point -#define ObjCExtraSuffix 1 +#ifndef JUCE_ObjCExtraSuffix + #define JUCE_ObjCExtraSuffix 2 +#endif #define appendMacro1(a, b, c, d) a ## _ ## b ## _ ## c ## _ ## d #define appendMacro2(a, b, c, d) appendMacro1(a, b, c, d) -#define MakeObjCClassName(rootName) appendMacro2 (rootName, JUCE_MAJOR_VERSION, JUCE_MINOR_VERSION, ObjCExtraSuffix) +#define MakeObjCClassName(rootName) appendMacro2 (rootName, JUCE_MAJOR_VERSION, JUCE_MINOR_VERSION, JUCE_ObjCExtraSuffix) #define JUCE_INCLUDED_FILE 1 diff --git a/src/juce_core/misc/juce_PlatformUtilities.h b/src/juce_core/misc/juce_PlatformUtilities.h index e979842acf..eed17849f8 100644 --- a/src/juce_core/misc/juce_PlatformUtilities.h +++ b/src/juce_core/misc/juce_PlatformUtilities.h @@ -112,7 +112,7 @@ public: /** WIN32 ONLY - Creates a file association in the registry. This lets you set the exe that should be launched by a given file extension. - @param fileExtension the file extension to associate, including the + @param fileExtension the file extension to associate, including the initial dot, e.g. ".txt" @param symbolicDescription a space-free short token to identify the file type @param fullDescription a human-readable description of the file type @@ -121,9 +121,9 @@ public: found by looking up this resource number in the executable. Pass 0 here to not use an icon */ - static void registerFileAssociation (const String& fileExtension, - const String& symbolicDescription, - const String& fullDescription, + static void registerFileAssociation (const String& fileExtension, + const String& symbolicDescription, + const String& fullDescription, const File& targetExecutable, int iconResourceNumber); diff --git a/src/juce_core/misc/juce_Uuid.cpp b/src/juce_core/misc/juce_Uuid.cpp index bc357a70c2..1bbba10d80 100644 --- a/src/juce_core/misc/juce_Uuid.cpp +++ b/src/juce_core/misc/juce_Uuid.cpp @@ -42,7 +42,7 @@ BEGIN_JUCE_NAMESPACE //============================================================================== Uuid::Uuid() { - // Mix up any available MAC addresses with some time-based pseudo-random numbers + // Mix up any available MAC addresses with some time-based pseudo-random numbers // to make it very very unlikely that two UUIDs will ever be the same.. static int64 macAddresses[2]; @@ -60,7 +60,7 @@ Uuid::Uuid() // We'll use both a local RNG that is re-seeded, plus the shared RNG, // whose seed will carry over between calls to this method. - Random r (macAddresses[0] ^ macAddresses[1] + Random r (macAddresses[0] ^ macAddresses[1] ^ Random::getSystemRandom().nextInt64()); for (int i = 4; --i >= 0;)