diff --git a/docs/CMake API.md b/docs/CMake API.md index 5dc3f78f9b..d3ae2ee542 100644 --- a/docs/CMake API.md +++ b/docs/CMake API.md @@ -75,17 +75,17 @@ or Visual Studio project, then you could open the generated project in your IDE. ### Building for iOS -To build for iOS, you'll need CMake 3.14 or higher. Using the Xcode generator is highly recommended, -as other generators may not automatically find the correct SDK for the iPhone simulator, and may -fail to run certain parts of the build, such as compiling icons and processing the app's plist. By -default, CMake will build for the same system that originally configured the project, so to enable -cross-compilation for iOS, a few extra flags must be passed to the initial CMake invocation: +Using the Xcode generator is highly recommended, as other generators may not automatically find +the correct SDK for the iPhone simulator, and may fail to run certain parts of the build, such as +compiling icons and processing the app's plist. By default, CMake will build for the same system +that originally configured the project, so to enable cross-compilation for iOS, a few extra flags +must be passed to the initial CMake invocation: - cmake -Bbuild-ios -GXcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_DEPLOYMENT_TARGET=9.3 + cmake -Bbuild-ios -GXcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 Here we create a build tree in the directory named 'build-ios', using the Xcode generator. The `-DCMAKE_SYSTEM_NAME=iOS` option tells CMake to enable cross-compiling for iOS. The -`-DCMAKE_OSX_DEPLOYMENT_TARGET=9.3` option sets the minimum deployment target (it applies to iOS +`-DCMAKE_OSX_DEPLOYMENT_TARGET=12.0` option sets the minimum deployment target (it applies to iOS despite the 'OSX' in the variable name!). Once the project has generated, we can open it as normal in Xcode (look for the project file in the @@ -102,7 +102,7 @@ require special code signing. If we wanted to build for a real device, we would need to pass some extra signing details to the initial CMake configuration command: - cmake -Bbuild-ios -GXcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_DEPLOYMENT_TARGET=9.3 \ + cmake -Bbuild-ios -GXcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 \ -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY="iPhone Developer" -DCMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM=<10 character id> @@ -136,14 +136,14 @@ configuring the CMake project with `"-DCMAKE_OSX_ARCHITECTURES=arm64;x86_64"`. ### Building with Clang on Windows -Clang-cl (Clang with MSVC-like command-line) should work by default. If you are generating a Visual +Clang-cl (Clang with MSVC-like command line) should work by default. If you are generating a Visual Studio project, and have installed the LLVM package which is distributed with Visual Studio, then -you can configure a Clang-cl build by passing "-T ClangCL" on your configuration commandline. +you can configure a Clang-cl build by passing `-T ClangCL` on your configuration command line. If you wish to use Clang with GNU-like command-line instead, you can pass -`-DCMAKE_CXX_COMPILER=clang++` and `-DCMAKE_C_COMPILER=clang` on your configuration commandline. -clang++ and clang must be on your `PATH` for this to work. Only more recent versions of CMake -support Clang's GNU-like command-line on Windows. Note that CMake doesn't seem to automatically +`-DCMAKE_CXX_COMPILER=clang++` and `-DCMAKE_C_COMPILER=clang` on your configuration command line. +`clang++` and `clang` must be on your `PATH` for this to work. Only more recent versions of CMake +support Clang's GNU-like command-line on Windows. Note that CMake doesn't seem to automatically link a runtime library when building in this configuration, but this can be remedied by setting the `MSVC_RUNTIME_LIBRARY` property. See the [official documentation](https://cmake.org/cmake/help/v3.22/prop_tgt/MSVC_RUNTIME_LIBRARY.html) of this @@ -226,18 +226,18 @@ folders. Only brings in targets for the built-in JUCE modules, and the `juce_add_module*` CMake functions. This is meant for highly custom use-cases where the `juce_add_gui_app` and `juce_add_plugin` -functions are not required. Most importantly, the 'juceaide' helper tool is not built when this +functions are not required. Most importantly, the `juceaide` helper tool is not built when this option is enabled, which may improve build times for established products that use other methods to handle plugin bundle structures, icons, plists, and so on. If this option is enabled, then `JUCE_ENABLE_MODULE_SOURCE_GROUPS` will have no effect. #### `JUCE_WEBVIEW2_PACKAGE_LOCATION` -You can ask JUCE to link the WebView2 library statically to your target on Windows, by specifying -the `NEEDS_WEBVIEW2` option when creating your target. In this case JUCE will search for the -WebView2 package on your system. The default search location is +You can ask JUCE to link the WebView2 library statically to your target on Windows, by specifying +the `NEEDS_WEBVIEW2` option when creating your target. In this case JUCE will search for the +WebView2 package on your system. The default search location is `%userprofile%\AppData\Local\PackageManagement\NuGet\Packages`. This location can be overriden by -specifying this option. The provided location should contain the `*Microsoft.Web.WebView2*` +specifying this option. The provided location should contain the `*Microsoft.Web.WebView2*` directory. ### Functions @@ -274,82 +274,86 @@ attributes directly to these creation functions, rather than adding them later. the target's plist. `BUILD_VERSION` -- A version number string in the format "major.minor.bugfix". If not specified, this will match +- A version number string in the format `major.minor.bugfix`. If not specified, this will match the `VERSION` of the target. On Apple platforms, this is the private version string used to distinguish between App Store builds. This option corresponds to the `CFBundleVersion` field in the target's plist. `BUNDLE_ID` -- An identifier string in the form "com.yourcompany.productname" which should uniquely identify +- An identifier string in the form `com.yourcompany.productname` which should uniquely identify this target. Mainly used for macOS builds. If not specified, a default will be generated using the target's `COMPANY_NAME` and the name of the CMake target. `MICROPHONE_PERMISSION_ENABLED` -- May be either TRUE or FALSE. Adds NSMicrophoneUsageDescription to an app's Info.plist. +- May be either `TRUE` or `FALSE`. Adds `NSMicrophoneUsageDescription` to an app's Info.plist. `MICROPHONE_PERMISSION_TEXT` - The text your app will display when it requests microphone permissions. `CAMERA_PERMISSION_ENABLED` -- May be either TRUE or FALSE. Adds NSCameraUsageDescription to an app's Info.plist. +- May be either `TRUE` or `FALSE`. Adds `NSCameraUsageDescription` to an app's Info.plist. `CAMERA_PERMISSION_TEXT` - The text your app will display when it requests camera permissions. `BLUETOOTH_PERMISSION_ENABLED` -- May be either TRUE or FALSE. Adds NSBluetoothAlwaysUsageDescription to an app's Info.plist. +- May be either `TRUE` or `FALSE`. Adds `NSBluetoothAlwaysUsageDescription` to an app's Info.plist. `BLUETOOTH_PERMISSION_TEXT` - The text your app will display when it requests bluetooth permissions. `LOCAL_NETWORK_PERMISSION_ENABLED` -- May be either TRUE or FALSE. Adds NSLocalNetworkUsageDescription to an app's Info.plist. +- May be either `TRUE` or `FALSE`. Adds `NSLocalNetworkUsageDescription` to an app's Info.plist. `LOCAL_NETWORK_PERMISSION_TEXT` - The text your app will display when it requests local network access permissions. `SEND_APPLE_EVENTS_PERMISSION_ENABLED` -- May be either TRUE or FALSE. Enable this to allow your app to send Apple events. +- May be either `TRUE` or `FALSE`. Enable this to allow your app to send Apple events. `SEND_APPLE_EVENTS_PERMISSION_TEXT` - The text your app will display when it requests permission to send Apple events. `FILE_SHARING_ENABLED` -- May be either TRUE or FALSE. Adds the appropriate entries to an iOS app's Info.plist. +- May be either `TRUE` or `FALSE`. Adds the appropriate entries to an iOS app's Info.plist. `DOCUMENT_BROWSER_ENABLED` -- May be either TRUE or FALSE. Adds the appropriate entries to an iOS app's Info.plist. +- May be either `TRUE` or `FALSE`. Adds the appropriate entries to an iOS app's Info.plist. `STATUS_BAR_HIDDEN` -- May be either TRUE or FALSE. Adds the appropriate entries to an iOS app's Info.plist. +- May be either `TRUE` or `FALSE`. Adds the appropriate entries to an iOS app's Info.plist. - `REQUIRES_FULL_SCREEN` - - May be either TRUE or FALSE. Adds the appropriate entries to an iOS app's Info.plist. +`REQUIRES_FULL_SCREEN` +- May be either `TRUE` or `FALSE`. Adds the appropriate entries to an iOS app's Info.plist. `BACKGROUND_AUDIO_ENABLED` -- May be either TRUE or FALSE. Adds the appropriate entries to an iOS app's Info.plist. +- May be either `TRUE` or `FALSE`. Adds the appropriate entries to an iOS app's Info.plist. `BACKGROUND_BLE_ENABLED` -- May be either TRUE or FALSE. Adds the appropriate entries to an iOS app's Info.plist. +- May be either `TRUE` or `FALSE`. Adds the appropriate entries to an iOS app's Info.plist. `APP_GROUPS_ENABLED` -- May be either TRUE or FALSE. Adds the appropriate entries to an iOS app's entitlements. +- May be either `TRUE` or `FALSE`. Adds the appropriate entries to an iOS app's entitlements. `APP_GROUP_IDS` - The app groups to which your iOS app belongs. These will be added to your app's entitlements. `ICLOUD_PERMISSIONS_ENABLED` -- May be either TRUE or FALSE. Adds the appropriate entries to an iOS app's entitlements. +- May be either `TRUE` or `FALSE`. Adds the appropriate entries to an iOS app's entitlements. `IPHONE_SCREEN_ORIENTATIONS` - May be one or more of `UIInterfaceOrientationUnknown`, `UIInterfaceOrientationPortrait`, `UIInterfaceOrientationPortraitUpsideDown`, `UIInterfaceOrientationLandscapeLeft`, or `UIInterfaceOrientationLandscapeRight`. Adds appropriate entries to an iOS app's plist. + Defaults to `UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight` `IPAD_SCREEN_ORIENTATIONS` - May be one or more of `UIInterfaceOrientationUnknown`, `UIInterfaceOrientationPortrait`, `UIInterfaceOrientationPortraitUpsideDown`, `UIInterfaceOrientationLandscapeLeft`, or `UIInterfaceOrientationLandscapeRight`. Adds appropriate entries to an iOS app's plist. + Defaults to `UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight` `LAUNCH_STORYBOARD_FILE` - A custom launch storyboard file to use on iOS. If not supplied, a default storyboard will be @@ -358,14 +362,14 @@ attributes directly to these creation functions, rather than adding them later. `CUSTOM_XCASSETS_FOLDER` - A path to an xcassets directory, containing icons and/or launch images for this target. If this - is specified, the ICON_BIG and ICON_SMALL arguments will not have an effect on iOS. LaunchImages - have been deprecated from iOS 13 onward, but if your xcassets folder contains a LaunchImage and - a custom storyboard hasn't been specified, then it will be used. + is specified, the `ICON_BIG` and `ICON_SMALL` arguments will not have an effect on iOS. + LaunchImages have been deprecated from iOS 13 onward, but if your xcassets folder contains a + LaunchImage and a custom storyboard hasn't been specified, then it will be used. `TARGETED_DEVICE_FAMILY` - Specifies the device families on which the product must be capable of running. Allowed values - are "1", "2", and "1,2"; these correspond to "iPhone/iPod touch", "iPad", and "iPhone/iPod and - iPad" respectively. This will default to "1,2", meaning that the target will target iPhone, + are `1`, `2`, and `1,2`; these correspond to "iPhone/iPod touch", "iPad", and "iPhone/iPod and + iPad" respectively. This will default to `1,2`, meaning that the target will target iPhone, iPod, and iPad. `ICON_BIG`, `ICON_SMALL` @@ -440,13 +444,16 @@ attributes directly to these creation functions, rather than adding them later. new target. `PUSH_NOTIFICATIONS_ENABLED` -- Sets app entitlements to allow push notifications. False by default. +- Sets app entitlements to allow push notifications. May be either `TRUE` + or `FALSE`. Defaults to `FALSE`. `NETWORK_MULTICAST_ENABLED` -- Sets app entitlements to allow IP multicast or broadcast on macOS/iOS. False by default. +- Sets app entitlements to allow IP multicast or broadcast on macOS/iOS. May be either `TRUE` + or `FALSE`. Defaults to `FALSE`. `HARDENED_RUNTIME_ENABLED` -- Enables macOS' hardened runtime for this target. Required for notarisation. False by default. +- Enables macOS' hardened runtime for this target. Required for notarisation. May be either + `TRUE` or `FALSE`. Defaults to `FALSE`. `HARDENED_RUNTIME_OPTIONS` - A set of space-separated entitlement keys that will be added to this target's entitlements @@ -454,11 +461,12 @@ attributes directly to these creation functions, rather than adding them later. `com.apple.security.*` where `*` is a specific entitlement. `APP_SANDBOX_ENABLED` -- Enables macOS' app sandbox for this target. False by default. +- Enables macOS' app sandbox for this target. May be either `TRUE` or `FALSE`. Defaults to `FALSE`. `APP_SANDBOX_INHERIT` - Allows child processes to inherit the static entitlements of their parent process. If this - is set to `TRUE`, no other app sandbox entitlements will be set on this target. + is set to `TRUE`, no other app sandbox entitlements will be set on this target. Defaults to + `FALSE`. `APP_SANDBOX_OPTIONS` - A set of space-separated entitlement keys that will be added to this target's entitlements @@ -482,8 +490,8 @@ attributes directly to these creation functions, rather than adding them later. accessing read/write absolute paths if `APP_SANDBOX_ENABLED` is `TRUE`. `APP_SANDBOX_EXCEPTION_IOKIT` -- A set of space-separated strings specifying IOUserClient subclasses to open or to set properties - on. These will be added to this target's entitlements plist if `APP_SANDBOX_ENABLED` is `TRUE`. +- A set of space-separated strings specifying IOUserClient subclasses to open or to set properties + on. These will be added to this target's entitlements plist if `APP_SANDBOX_ENABLED` is `TRUE`. For more information see Apple's IOKit User Client Class Temporary Exception documentation. `PLIST_TO_MERGE` @@ -491,8 +499,8 @@ attributes directly to these creation functions, rather than adding them later. `FORMATS` - For plugin targets, specifies the plugin targets to build. Should be provided as a - space-separated list. Valid values are `Standalone Unity VST3 AU AUv3 AAX VST`. `AU` and `AUv3` - plugins will only be enabled when building on macOS. It is an error to pass `AAX` or `VST` + space-separated list. Valid values are `Standalone Unity VST3 AU AUv3 AAX VST LV2`. `AU` and + `AUv3` plugins will only be enabled when building on macOS. It is an error to pass `AAX` or `VST` without first calling `juce_set_aax_sdk_path` or `juce_set_vst2_sdk_path` respectively. `PLUGIN_NAME` @@ -504,71 +512,80 @@ attributes directly to these creation functions, rather than adding them later. `PLUGIN_MANUFACTURER_CODE` - A four-character unique ID for your company. For AU compatibility, this must contain at least one upper-case letter. GarageBand 10.3 requires the first letter to be upper-case, and the - remaining letters to be lower-case. + remaining letters to be lower-case. Defaults to `Manu`. `PLUGIN_CODE` - A four-character unique ID for your plugin. For AU compatibility, this must contain exactly one upper-case letter. GarageBand 10.3 requires the first letter to be upper-case, and the remaining - letters to be lower-case. + letters to be lower-case. Defaults to a random code that changes each time the build is + configured. `DESCRIPTION` - A short description of your plugin. `IS_SYNTH` - Whether the plugin is a synth. Will be used to set sensible plugin category values if they - are not provided explicitly. + are not provided explicitly. May be either `TRUE` or `FALSE`. Defaults to `FALSE`. `NEEDS_MIDI_INPUT` -- Whether the plugin should provide a midi input. +- Whether the plugin should provide a midi input. May be either `TRUE` or `FALSE`. Defaults to + `FALSE`. `NEEDS_MIDI_OUTPUT` -- Whether the plugin should provide a midi output. +- Whether the plugin should provide a midi output. May be either `TRUE` or `FALSE`. Defaults to + `FALSE`. `IS_MIDI_EFFECT` - Whether the plugin is a MIDI effect (some hosts provide a special channel-strip location for - MIDI effect plugins). + MIDI effect plugins). May be either `TRUE` or `FALSE`. Defaults to `FALSE`. `EDITOR_WANTS_KEYBOARD_FOCUS` - Whether the plugin requires keyboard focus, or should defer all keyboard handling to the host. + May be either `TRUE` or `FALSE`. Defaults to `FALSE`. `DISABLE_AAX_BYPASS` -- Whether the AAX bypass function should be disabled. +- Whether the AAX bypass function should be disabled. May be either `TRUE` or `FALSE`. Defaults to + `FALSE`. `DISABLE_AAX_MULTI_MONO` -- Whether the AAX multi mono bus layout should be disabled. +- Whether the AAX multi mono bus layout should be disabled. May be either `TRUE` or `FALSE`. + Defaults to `FALSE`. `AAX_IDENTIFIER` -- The bundle ID for the AAX plugin target. Matches the `BUNDLE_ID` by default. +- The bundle ID for the AAX plugin target. Defaults to the `BUNDLE_ID`. `LV2URI` -- This is a string that acts as a unique identifier for an LV2 plugin. If you make any incompatible +- This is a string that acts as a unique identifier for an LV2 plugin. If you make any incompatible changes to your plugin (remove parameters, reorder parameters, change preset format etc.) you MUST change this value. LV2 hosts will assume that any plugins with the same URI are interchangeable. - By default, the value of this property will be generated based on the COMPANY_WEBSITE and - PLUGIN_NAME. However, in some circumstances, such as the following, you'll need to override the + By default, the value of this property will be generated based on the `COMPANY_WEBSITE` and + `PLUGIN_NAME`. However, in some circumstances, such as the following, you'll need to override the default: - The plugin name contains characters such as spaces that are invalid in a URI; or - - The COMPANY_WEBSITE omits the leading scheme identifier (http://); or - - There's no website associated with the plugin, so you want to use a 'urn:' identifier instead. + - The `COMPANY_WEBSITE` omits the leading scheme identifier (`http://`); or + - There's no website associated with the plugin, so you want to use a `urn:` identifier instead. `VST_NUM_MIDI_INS` - For VST2 and VST3 plugins that accept midi, this allows you to configure the number of inputs. + Defaults to `16`. `VST_NUM_MIDI_OUTS` - For VST2 and VST3 plugins that produce midi, this allows you to configure the number of outputs. + Defaults to `16`. `VST2_CATEGORY` - Should be one of: `kPlugCategUnknown`, `kPlugCategEffect`, `kPlugCategSynth`, `kPlugCategAnalysis`, `kPlugCategMastering`, `kPlugCategSpacializer`, `kPlugCategRoomFx`, `kPlugSurroundFx`, `kPlugCategRestoration`, `kPlugCategOfflineProcess`, `kPlugCategShell`, - `kPlugCategGenerator`. + `kPlugCategGenerator`. Defaults to `kPlugCategSynth` if `IS_SYNTH` is `TRUE`. Otherwise defaults + to `kPlugCategEffect`. `VST3_CATEGORIES` - Should be one or more, separated by spaces, of the following: `Fx`, `Instrument`, `Analyzer`, `Delay`, `Distortion`, `Drum`, `Dynamics`, `EQ`, `External`, `Filter`, `Generator`, `Mastering`, `Modulation`, `Mono`, `Network`, `NoOfflineProcess`, `OnlyOfflineProcess`, `OnlyRT`, `Pitch Shift`, `Restoration`, `Reverb`, `Sampler`, `Spatial`, `Stereo`, `Surround`, `Synth`, - `Tools`, `Up-Downmix` + `Tools`, `Up-Downmix`. Defaults to `Synth` if `IS_SYNTH` is `TRUE`. Otherwise defaults to `Fx`. `AU_MAIN_TYPE` - Should be one of: `kAudioUnitType_Effect`, `kAudioUnitType_FormatConverter`, @@ -579,42 +596,45 @@ attributes directly to these creation functions, rather than adding them later. `AU_EXPORT_PREFIX` - A prefix for the names of entry-point functions that your component exposes. Typically this will be a version of your plugin's name that can be used as part of a C++ token. Defaults - to your plugin's name with the suffix 'AU'. + to your plugin's name with the suffix `AU`. `AU_SANDBOX_SAFE` -- May be either TRUE or FALSE. Adds the appropriate entries to an AU plugin's Info.plist. +- Adds the appropriate entries to an AU plugin's Info.plist. May be either `TRUE` or `FALSE`. + Defaults to `FALSE`. `SUPPRESS_AU_PLIST_RESOURCE_USAGE` -- May be either TRUE or FALSE. Defaults to FALSE. Set this to TRUE to disable the `resourceUsage` - key in the target's plist. This is useful for AU plugins that must access resources which cannot - be declared in the resourceUsage block, such as UNIX domain sockets. In particular, - PACE-protected AU plugins may require this option to be enabled in order for the plugin to load - in GarageBand. +- May be either `TRUE` or `FALSE`. Defaults to `FALSE`. Set this to `TRUE` to disable the + `resourceUsage` key in the target's plist. This is useful for AU plugins that must access + resources which cannot be declared in the resourceUsage block, such as UNIX domain sockets. In + particular, PACE-protected AU plugins may require this option to be enabled in order for the + plugin to load in GarageBand. `AAX_CATEGORY` - Should be one or more of: `None`, `EQ`, `Dynamics`, `PitchShift`, `Reverb`, `Delay`, `Modulation`, `Harmonic`, `NoiseReduction`, `Dither`, `SoundField`, `HWGenerators`, `SWGenerators`, `WrappedPlugin`, `Effect`, and `MIDIEffect`. You may also add the prefix `AAX_ePlugInCategory_`. + Defaults to `MIDIEffect` when `IS_MIDI_EFFECT` is `TRUE`, `SWGenerators` when `IS_SYNTH` is + `TRUE`, otherwise `None`. `PLUGINHOST_AU` -- May be either TRUE or FALSE (defaults to FALSE). If TRUE, will add the preprocessor definition - `JUCE_PLUGINHOST_AU=1` to the new target, and will link the macOS frameworks necessary for - hosting plugins. Using this parameter should be preferred over using +- May be either `TRUE` or `FALSE`. Defaults to `FALSE`. If `TRUE`, will add the preprocessor + definition `JUCE_PLUGINHOST_AU=1` to the new target, and will link the macOS frameworks necessary + for hosting plugins. Using this parameter should be preferred over using `target_compile_definitions` to manually set the `JUCE_PLUGINHOST_AU` preprocessor definition. `USE_LEGACY_COMPATIBILITY_PLUGIN_CODE` -- May be either TRUE or FALSE (defaults to FALSE). If TRUE, will override the value of the - preprocessor definition "JucePlugin_ManufacturerCode" with the hex equivalent of "proj". This - option exists to maintain compatibility with a previous, buggy version of JUCE's CMake support - which mishandled the manufacturer code property. Most projects should leave this option set to - its default value. +- May be either `TRUE` or `FALSE`. Defaults to `FALSE`. If `TRUE`, the preprocessor definition + `JucePlugin_ManufacturerCode` will be set to the hex equivalent of `proj`. This option exists to + maintain compatibility with a previous, buggy version of JUCE's CMake support which mishandled the + manufacturer code property. Most projects should leave this option set to its default value. `COPY_PLUGIN_AFTER_BUILD` -- Whether or not to install the plugin to the current system after building. False by default. - If you want all of the plugins in a subdirectory to be installed automatically after building, - you can set the property `JUCE_COPY_PLUGIN_AFTER_BUILD` on the directory before adding the - plugins, rather than setting this argument on each individual target. Note that on Windows, - the default install locations may not be writable by normal user accounts. +- Whether or not to install the plugin to the current system after building. May be either + `TRUE` or `FALSE`. Defaults to `FALSE`. If you want all of the plugins in a subdirectory to be + installed automatically after building, you can set the property `JUCE_COPY_PLUGIN_AFTER_BUILD` + on the directory before adding the plugins, rather than setting this argument on each individual + target. Note that on Windows, the default install locations may not be writable by normal user + accounts. `VST_COPY_DIR` - The location to which VST2 (legacy) plugins will be copied after building if @@ -650,8 +670,8 @@ attributes directly to these creation functions, rather than adding them later. to set it if you have enabled `COPY_PLUGIN_AFTER_BUILD` and the `Unity` format. `IS_ARA_EFFECT` -- May be either TRUE or FALSE (defaults to FALSE). If TRUE it enables additional codepaths in the - VST3 and AU plugin wrappers allowing compatible hosts to load the plugin with additional ARA +- May be either `TRUE` or `FALSE`. Defaults to `FALSE`. If `TRUE` it enables additional codepaths in + the VST3 and AU plugin wrappers allowing compatible hosts to load the plugin with additional ARA functionality. It will also add the preprocessor definition `JucePlugin_Enable_ARA=1`, which can be used in preprocessor conditions inside the plugin code. You should not add this definition using `target_compile_definitions` manually. @@ -674,22 +694,22 @@ attributes directly to these creation functions, rather than adding them later. - Defaults to having no analyzable types. Should be one or more of the following values if the document controller has the corresponding analysis capability: `kARAContentTypeNotes`, `kARAContentTypeTempoEntries`, `kARAContentTypeBarSignatures`, `kARAContentTypeStaticTuning `, - `kARAContentTypeKeySignatures`, `kARAContentTypeSheetChords` + `kARAContentTypeKeySignatures`, `kARAContentTypeSheetChords`. `ARA_TRANSFORMATION_FLAGS` - Defaults to `kARAPlaybackTransformationNoChanges`. If the document controller has the ability to provide the corresponding change it should be one or more of: `kARAPlaybackTransformationTimestretch`, `kARAPlaybackTransformationTimestretchReflectingTempo`, `kARAPlaybackTransformationContentBasedFadeAtTail`, - `kARAPlaybackTransformationContentBasedFadeAtHead` + `kARAPlaybackTransformationContentBasedFadeAtHead`. `VST3_AUTO_MANIFEST` -- May be either TRUE or FALSE (defaults to TRUE). When TRUE, a POST_BUILD step will be added to the - VST3 target which will generate a moduleinfo.json file into the Resources subdirectory of the - plugin bundle. This is normally desirable, but does require that the plugin can be successfully - loaded immediately after building the VST3 target. If the plugin needs further processing before - it can be loaded (e.g. custom signing), then set this option to FALSE to disable the automatic - manifest generation. To generate the manifest at a later point in the build, use the +- May be either `TRUE` or `FALSE`. Defaults to `TRUE`. When `TRUE`, a `POST_BUILD` step will be + added to the VST3 target which will generate a `moduleinfo.json` file into the Resources + subdirectory of the plugin bundle. This is normally desirable, but does require that the plugin + can be successfully loaded immediately after building the VST3 target. If the plugin needs further + processing before it can be loaded (e.g. custom signing), then set this option to FALSE to disable + the automatic manifest generation. To generate the manifest at a later point in the build, use the `juce_enable_vst3_manifest_step` function. It is strongly recommended to generate a manifest for your plugin, as this allows compatible hosts to scan the plugin much more quickly, leading to an improved experience for users. @@ -761,10 +781,10 @@ target!). You may call this function to manually enable VST3 manifest generation on a plugin. The argument to this function should be a target previously created with `juce_add_plugin`. -VST3_AUTO_MANIFEST TRUE will cause the VST3 manifest to be generated immediately after building. +`VST3_AUTO_MANIFEST TRUE` will cause the VST3 manifest to be generated immediately after building. This is not always appropriate, if extra build steps (such as signing or modifying the plugin bundle) must be executed before the plugin can be loaded. In such cases, you should set -VST3_AUTO_MANIFEST FALSE, use `add_custom_command(TARGET POST_BUILD)` to add your own post-build +`VST3_AUTO_MANIFEST FALSE`, use `add_custom_command(TARGET POST_BUILD)` to add your own post-build steps, and then finally call `juce_enable_vst3_manifest_step`. #### `juce_set__sdk_path` @@ -831,7 +851,7 @@ CMake-supplied defaults. juce_link_with_embedded_linux_subprocess() -This function links the provided target with an interface library that generates a barebones +This function links the provided target with an interface library that generates a barebones standalone executable file and embeds it as a binary resource. This binary resource is only used by the `juce_gui_extra` module and only when its `JUCE_WEB_BROWSER` capability is enabled. This executable will then be deployed into a temporary file only when the code is running in a diff --git a/examples/DemoRunner/Builds/Android/app/CMakeLists.txt b/examples/DemoRunner/Builds/Android/app/CMakeLists.txt index cad2e36543..0c1b9e66ac 100644 --- a/examples/DemoRunner/Builds/Android/app/CMakeLists.txt +++ b/examples/DemoRunner/Builds/Android/app/CMakeLists.txt @@ -34,9 +34,9 @@ include_directories( AFTER enable_language(ASM) if(JUCE_BUILD_CONFIGURATION MATCHES "DEBUG") - add_definitions([[-DJUCE_PROJUCER_VERSION=0x80008]] [[-DJUCE_MODULE_AVAILABLE_juce_analytics=1]] [[-DJUCE_MODULE_AVAILABLE_juce_animation=1]] [[-DJUCE_MODULE_AVAILABLE_juce_audio_basics=1]] [[-DJUCE_MODULE_AVAILABLE_juce_audio_devices=1]] [[-DJUCE_MODULE_AVAILABLE_juce_audio_formats=1]] [[-DJUCE_MODULE_AVAILABLE_juce_audio_processors=1]] [[-DJUCE_MODULE_AVAILABLE_juce_audio_utils=1]] [[-DJUCE_MODULE_AVAILABLE_juce_box2d=1]] [[-DJUCE_MODULE_AVAILABLE_juce_core=1]] [[-DJUCE_MODULE_AVAILABLE_juce_cryptography=1]] [[-DJUCE_MODULE_AVAILABLE_juce_data_structures=1]] [[-DJUCE_MODULE_AVAILABLE_juce_dsp=1]] [[-DJUCE_MODULE_AVAILABLE_juce_events=1]] [[-DJUCE_MODULE_AVAILABLE_juce_graphics=1]] [[-DJUCE_MODULE_AVAILABLE_juce_gui_basics=1]] [[-DJUCE_MODULE_AVAILABLE_juce_gui_extra=1]] [[-DJUCE_MODULE_AVAILABLE_juce_javascript=1]] [[-DJUCE_MODULE_AVAILABLE_juce_midi_ci=1]] [[-DJUCE_MODULE_AVAILABLE_juce_opengl=1]] [[-DJUCE_MODULE_AVAILABLE_juce_osc=1]] [[-DJUCE_MODULE_AVAILABLE_juce_product_unlocking=1]] [[-DJUCE_MODULE_AVAILABLE_juce_video=1]] [[-DJUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1]] [[-DJUCE_USE_MP3AUDIOFORMAT=1]] [[-DJUCE_PLUGINHOST_VST3=1]] [[-DJUCE_PLUGINHOST_LV2=1]] [[-DJUCE_ALLOW_STATIC_NULL_VARIABLES=0]] [[-DJUCE_STRICT_REFCOUNTEDPOINTER=1]] [[-DJUCE_USE_CAMERA=1]] [[-DJUCE_STANDALONE_APPLICATION=1]] [[-DJUCE_DEMO_RUNNER=1]] [[-DJUCE_UNIT_TESTS=1]] [[-DJUCE_PUSH_NOTIFICATIONS=1]] [[-DJUCER_ANDROIDSTUDIO_7F0E4A25=1]] [[-DJUCE_APP_VERSION=8.0.8]] [[-DJUCE_APP_VERSION_HEX=0x80008]] [[-DDEBUG=1]] [[-D_DEBUG=1]]) + add_definitions([[-DJUCE_PROJUCER_VERSION=0x80008]] [[-DJUCE_MODULE_AVAILABLE_juce_analytics=1]] [[-DJUCE_MODULE_AVAILABLE_juce_animation=1]] [[-DJUCE_MODULE_AVAILABLE_juce_audio_basics=1]] [[-DJUCE_MODULE_AVAILABLE_juce_audio_devices=1]] [[-DJUCE_MODULE_AVAILABLE_juce_audio_formats=1]] [[-DJUCE_MODULE_AVAILABLE_juce_audio_processors=1]] [[-DJUCE_MODULE_AVAILABLE_juce_audio_utils=1]] [[-DJUCE_MODULE_AVAILABLE_juce_box2d=1]] [[-DJUCE_MODULE_AVAILABLE_juce_core=1]] [[-DJUCE_MODULE_AVAILABLE_juce_cryptography=1]] [[-DJUCE_MODULE_AVAILABLE_juce_data_structures=1]] [[-DJUCE_MODULE_AVAILABLE_juce_dsp=1]] [[-DJUCE_MODULE_AVAILABLE_juce_events=1]] [[-DJUCE_MODULE_AVAILABLE_juce_graphics=1]] [[-DJUCE_MODULE_AVAILABLE_juce_gui_basics=1]] [[-DJUCE_MODULE_AVAILABLE_juce_gui_extra=1]] [[-DJUCE_MODULE_AVAILABLE_juce_javascript=1]] [[-DJUCE_MODULE_AVAILABLE_juce_midi_ci=1]] [[-DJUCE_MODULE_AVAILABLE_juce_opengl=1]] [[-DJUCE_MODULE_AVAILABLE_juce_osc=1]] [[-DJUCE_MODULE_AVAILABLE_juce_product_unlocking=1]] [[-DJUCE_MODULE_AVAILABLE_juce_video=1]] [[-DJUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1]] [[-DJUCE_USE_MP3AUDIOFORMAT=1]] [[-DJUCE_PLUGINHOST_VST3=1]] [[-DJUCE_PLUGINHOST_AU=1]] [[-DJUCE_PLUGINHOST_LV2=1]] [[-DJUCE_ALLOW_STATIC_NULL_VARIABLES=0]] [[-DJUCE_STRICT_REFCOUNTEDPOINTER=1]] [[-DJUCE_USE_CAMERA=1]] [[-DJUCE_STANDALONE_APPLICATION=1]] [[-DJUCE_DEMO_RUNNER=1]] [[-DJUCE_UNIT_TESTS=1]] [[-DJUCE_PUSH_NOTIFICATIONS=1]] [[-DJUCER_ANDROIDSTUDIO_7F0E4A25=1]] [[-DJUCE_APP_VERSION=8.0.8]] [[-DJUCE_APP_VERSION_HEX=0x80008]] [[-DDEBUG=1]] [[-D_DEBUG=1]]) elseif(JUCE_BUILD_CONFIGURATION MATCHES "RELEASE") - add_definitions([[-DJUCE_PROJUCER_VERSION=0x80008]] [[-DJUCE_MODULE_AVAILABLE_juce_analytics=1]] [[-DJUCE_MODULE_AVAILABLE_juce_animation=1]] [[-DJUCE_MODULE_AVAILABLE_juce_audio_basics=1]] [[-DJUCE_MODULE_AVAILABLE_juce_audio_devices=1]] [[-DJUCE_MODULE_AVAILABLE_juce_audio_formats=1]] [[-DJUCE_MODULE_AVAILABLE_juce_audio_processors=1]] [[-DJUCE_MODULE_AVAILABLE_juce_audio_utils=1]] [[-DJUCE_MODULE_AVAILABLE_juce_box2d=1]] [[-DJUCE_MODULE_AVAILABLE_juce_core=1]] [[-DJUCE_MODULE_AVAILABLE_juce_cryptography=1]] [[-DJUCE_MODULE_AVAILABLE_juce_data_structures=1]] [[-DJUCE_MODULE_AVAILABLE_juce_dsp=1]] [[-DJUCE_MODULE_AVAILABLE_juce_events=1]] [[-DJUCE_MODULE_AVAILABLE_juce_graphics=1]] [[-DJUCE_MODULE_AVAILABLE_juce_gui_basics=1]] [[-DJUCE_MODULE_AVAILABLE_juce_gui_extra=1]] [[-DJUCE_MODULE_AVAILABLE_juce_javascript=1]] [[-DJUCE_MODULE_AVAILABLE_juce_midi_ci=1]] [[-DJUCE_MODULE_AVAILABLE_juce_opengl=1]] [[-DJUCE_MODULE_AVAILABLE_juce_osc=1]] [[-DJUCE_MODULE_AVAILABLE_juce_product_unlocking=1]] [[-DJUCE_MODULE_AVAILABLE_juce_video=1]] [[-DJUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1]] [[-DJUCE_USE_MP3AUDIOFORMAT=1]] [[-DJUCE_PLUGINHOST_VST3=1]] [[-DJUCE_PLUGINHOST_LV2=1]] [[-DJUCE_ALLOW_STATIC_NULL_VARIABLES=0]] [[-DJUCE_STRICT_REFCOUNTEDPOINTER=1]] [[-DJUCE_USE_CAMERA=1]] [[-DJUCE_STANDALONE_APPLICATION=1]] [[-DJUCE_DEMO_RUNNER=1]] [[-DJUCE_UNIT_TESTS=1]] [[-DJUCE_PUSH_NOTIFICATIONS=1]] [[-DJUCER_ANDROIDSTUDIO_7F0E4A25=1]] [[-DJUCE_APP_VERSION=8.0.8]] [[-DJUCE_APP_VERSION_HEX=0x80008]] [[-DNDEBUG=1]]) + add_definitions([[-DJUCE_PROJUCER_VERSION=0x80008]] [[-DJUCE_MODULE_AVAILABLE_juce_analytics=1]] [[-DJUCE_MODULE_AVAILABLE_juce_animation=1]] [[-DJUCE_MODULE_AVAILABLE_juce_audio_basics=1]] [[-DJUCE_MODULE_AVAILABLE_juce_audio_devices=1]] [[-DJUCE_MODULE_AVAILABLE_juce_audio_formats=1]] [[-DJUCE_MODULE_AVAILABLE_juce_audio_processors=1]] [[-DJUCE_MODULE_AVAILABLE_juce_audio_utils=1]] [[-DJUCE_MODULE_AVAILABLE_juce_box2d=1]] [[-DJUCE_MODULE_AVAILABLE_juce_core=1]] [[-DJUCE_MODULE_AVAILABLE_juce_cryptography=1]] [[-DJUCE_MODULE_AVAILABLE_juce_data_structures=1]] [[-DJUCE_MODULE_AVAILABLE_juce_dsp=1]] [[-DJUCE_MODULE_AVAILABLE_juce_events=1]] [[-DJUCE_MODULE_AVAILABLE_juce_graphics=1]] [[-DJUCE_MODULE_AVAILABLE_juce_gui_basics=1]] [[-DJUCE_MODULE_AVAILABLE_juce_gui_extra=1]] [[-DJUCE_MODULE_AVAILABLE_juce_javascript=1]] [[-DJUCE_MODULE_AVAILABLE_juce_midi_ci=1]] [[-DJUCE_MODULE_AVAILABLE_juce_opengl=1]] [[-DJUCE_MODULE_AVAILABLE_juce_osc=1]] [[-DJUCE_MODULE_AVAILABLE_juce_product_unlocking=1]] [[-DJUCE_MODULE_AVAILABLE_juce_video=1]] [[-DJUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1]] [[-DJUCE_USE_MP3AUDIOFORMAT=1]] [[-DJUCE_PLUGINHOST_VST3=1]] [[-DJUCE_PLUGINHOST_AU=1]] [[-DJUCE_PLUGINHOST_LV2=1]] [[-DJUCE_ALLOW_STATIC_NULL_VARIABLES=0]] [[-DJUCE_STRICT_REFCOUNTEDPOINTER=1]] [[-DJUCE_USE_CAMERA=1]] [[-DJUCE_STANDALONE_APPLICATION=1]] [[-DJUCE_DEMO_RUNNER=1]] [[-DJUCE_UNIT_TESTS=1]] [[-DJUCE_PUSH_NOTIFICATIONS=1]] [[-DJUCER_ANDROIDSTUDIO_7F0E4A25=1]] [[-DJUCE_APP_VERSION=8.0.8]] [[-DJUCE_APP_VERSION_HEX=0x80008]] [[-DNDEBUG=1]]) else() message( FATAL_ERROR "No matching build-configuration found." ) endif() @@ -805,6 +805,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_processors/format_types/juce_AU_Shared.h" "../../../../../modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.h" "../../../../../modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm" + "../../../../../modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat_test.cpp" "../../../../../modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp" "../../../../../modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.h" "../../../../../modules/juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp" @@ -833,7 +834,9 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorEditorHostContext.h" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h" + "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorListener.cpp" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorListener.h" + "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorParameter.cpp" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorParameterGroup.cpp" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorParameterGroup.h" @@ -3489,6 +3492,7 @@ set_source_files_properties( "../../../../../modules/juce_audio_processors/format_types/juce_AU_Shared.h" "../../../../../modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.h" "../../../../../modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm" + "../../../../../modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat_test.cpp" "../../../../../modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp" "../../../../../modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.h" "../../../../../modules/juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp" @@ -3517,7 +3521,9 @@ set_source_files_properties( "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorEditorHostContext.h" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h" + "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorListener.cpp" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorListener.h" + "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorParameter.cpp" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorParameterGroup.cpp" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorParameterGroup.h" diff --git a/examples/DemoRunner/Builds/LinuxMakefile/Makefile b/examples/DemoRunner/Builds/LinuxMakefile/Makefile index a0892ff741..1313924227 100644 --- a/examples/DemoRunner/Builds/LinuxMakefile/Makefile +++ b/examples/DemoRunner/Builds/LinuxMakefile/Makefile @@ -39,7 +39,7 @@ ifeq ($(CONFIG),Debug) TARGET_ARCH := endif - JUCE_CPPFLAGS := $(DEPFLAGS) "-DLINUX=1" "-DDEBUG=1" "-D_DEBUG=1" "-DJUCE_PROJUCER_VERSION=0x80008" "-DJUCE_MODULE_AVAILABLE_juce_analytics=1" "-DJUCE_MODULE_AVAILABLE_juce_animation=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_devices=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_formats=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_processors=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_utils=1" "-DJUCE_MODULE_AVAILABLE_juce_box2d=1" "-DJUCE_MODULE_AVAILABLE_juce_core=1" "-DJUCE_MODULE_AVAILABLE_juce_cryptography=1" "-DJUCE_MODULE_AVAILABLE_juce_data_structures=1" "-DJUCE_MODULE_AVAILABLE_juce_dsp=1" "-DJUCE_MODULE_AVAILABLE_juce_events=1" "-DJUCE_MODULE_AVAILABLE_juce_graphics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_extra=1" "-DJUCE_MODULE_AVAILABLE_juce_javascript=1" "-DJUCE_MODULE_AVAILABLE_juce_midi_ci=1" "-DJUCE_MODULE_AVAILABLE_juce_opengl=1" "-DJUCE_MODULE_AVAILABLE_juce_osc=1" "-DJUCE_MODULE_AVAILABLE_juce_product_unlocking=1" "-DJUCE_MODULE_AVAILABLE_juce_video=1" "-DJUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1" "-DJUCE_USE_MP3AUDIOFORMAT=1" "-DJUCE_PLUGINHOST_VST3=1" "-DJUCE_PLUGINHOST_LV2=1" "-DJUCE_ALLOW_STATIC_NULL_VARIABLES=0" "-DJUCE_STRICT_REFCOUNTEDPOINTER=1" "-DJUCE_USE_CAMERA=1" "-DJUCE_STANDALONE_APPLICATION=1" "-DJUCE_DEMO_RUNNER=1" "-DJUCE_UNIT_TESTS=1" "-DJUCE_PUSH_NOTIFICATIONS=1" "-DJUCER_LINUX_MAKE_6D53C8B4=1" "-DJUCE_APP_VERSION=8.0.8" "-DJUCE_APP_VERSION_HEX=0x80008" $(shell $(PKG_CONFIG) --cflags $(shell ($(PKG_CONFIG) --exists webkit2gtk-4.1 && echo webkit2gtk-4.1) || echo webkit2gtk-4.0) alsa freetype2 fontconfig gl libcurl gtk+-x11-3.0) -pthread -I../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv/src -I../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv -I../../../../modules/juce_audio_processors/format_types/LV2_SDK/sratom -I../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord/src -I../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord -I../../../../modules/juce_audio_processors/format_types/LV2_SDK/serd -I../../../../modules/juce_audio_processors/format_types/LV2_SDK/lv2 -I../../../../modules/juce_audio_processors/format_types/LV2_SDK -I../../../../modules/juce_audio_processors/format_types/VST3_SDK -I../../JuceLibraryCode -I../../../../modules $(CPPFLAGS) + JUCE_CPPFLAGS := $(DEPFLAGS) "-DLINUX=1" "-DDEBUG=1" "-D_DEBUG=1" "-DJUCE_PROJUCER_VERSION=0x80008" "-DJUCE_MODULE_AVAILABLE_juce_analytics=1" "-DJUCE_MODULE_AVAILABLE_juce_animation=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_devices=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_formats=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_processors=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_utils=1" "-DJUCE_MODULE_AVAILABLE_juce_box2d=1" "-DJUCE_MODULE_AVAILABLE_juce_core=1" "-DJUCE_MODULE_AVAILABLE_juce_cryptography=1" "-DJUCE_MODULE_AVAILABLE_juce_data_structures=1" "-DJUCE_MODULE_AVAILABLE_juce_dsp=1" "-DJUCE_MODULE_AVAILABLE_juce_events=1" "-DJUCE_MODULE_AVAILABLE_juce_graphics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_extra=1" "-DJUCE_MODULE_AVAILABLE_juce_javascript=1" "-DJUCE_MODULE_AVAILABLE_juce_midi_ci=1" "-DJUCE_MODULE_AVAILABLE_juce_opengl=1" "-DJUCE_MODULE_AVAILABLE_juce_osc=1" "-DJUCE_MODULE_AVAILABLE_juce_product_unlocking=1" "-DJUCE_MODULE_AVAILABLE_juce_video=1" "-DJUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1" "-DJUCE_USE_MP3AUDIOFORMAT=1" "-DJUCE_PLUGINHOST_VST3=1" "-DJUCE_PLUGINHOST_AU=1" "-DJUCE_PLUGINHOST_LV2=1" "-DJUCE_ALLOW_STATIC_NULL_VARIABLES=0" "-DJUCE_STRICT_REFCOUNTEDPOINTER=1" "-DJUCE_USE_CAMERA=1" "-DJUCE_STANDALONE_APPLICATION=1" "-DJUCE_DEMO_RUNNER=1" "-DJUCE_UNIT_TESTS=1" "-DJUCE_PUSH_NOTIFICATIONS=1" "-DJUCER_LINUX_MAKE_6D53C8B4=1" "-DJUCE_APP_VERSION=8.0.8" "-DJUCE_APP_VERSION_HEX=0x80008" $(shell $(PKG_CONFIG) --cflags $(shell ($(PKG_CONFIG) --exists webkit2gtk-4.1 && echo webkit2gtk-4.1) || echo webkit2gtk-4.0) alsa freetype2 fontconfig gl libcurl gtk+-x11-3.0) -pthread -I../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv/src -I../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv -I../../../../modules/juce_audio_processors/format_types/LV2_SDK/sratom -I../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord/src -I../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord -I../../../../modules/juce_audio_processors/format_types/LV2_SDK/serd -I../../../../modules/juce_audio_processors/format_types/LV2_SDK/lv2 -I../../../../modules/juce_audio_processors/format_types/LV2_SDK -I../../../../modules/juce_audio_processors/format_types/VST3_SDK -I../../JuceLibraryCode -I../../../../modules $(CPPFLAGS) JUCE_CPPFLAGS_APP := "-DJucePlugin_Build_VST=0" "-DJucePlugin_Build_VST3=0" "-DJucePlugin_Build_AU=0" "-DJucePlugin_Build_AUv3=0" "-DJucePlugin_Build_AAX=0" "-DJucePlugin_Build_Standalone=0" "-DJucePlugin_Build_Unity=0" "-DJucePlugin_Build_LV2=0" JUCE_TARGET_APP := DemoRunner @@ -60,7 +60,7 @@ ifeq ($(CONFIG),Release) TARGET_ARCH := endif - JUCE_CPPFLAGS := $(DEPFLAGS) "-DLINUX=1" "-DNDEBUG=1" "-DJUCE_PROJUCER_VERSION=0x80008" "-DJUCE_MODULE_AVAILABLE_juce_analytics=1" "-DJUCE_MODULE_AVAILABLE_juce_animation=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_devices=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_formats=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_processors=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_utils=1" "-DJUCE_MODULE_AVAILABLE_juce_box2d=1" "-DJUCE_MODULE_AVAILABLE_juce_core=1" "-DJUCE_MODULE_AVAILABLE_juce_cryptography=1" "-DJUCE_MODULE_AVAILABLE_juce_data_structures=1" "-DJUCE_MODULE_AVAILABLE_juce_dsp=1" "-DJUCE_MODULE_AVAILABLE_juce_events=1" "-DJUCE_MODULE_AVAILABLE_juce_graphics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_extra=1" "-DJUCE_MODULE_AVAILABLE_juce_javascript=1" "-DJUCE_MODULE_AVAILABLE_juce_midi_ci=1" "-DJUCE_MODULE_AVAILABLE_juce_opengl=1" "-DJUCE_MODULE_AVAILABLE_juce_osc=1" "-DJUCE_MODULE_AVAILABLE_juce_product_unlocking=1" "-DJUCE_MODULE_AVAILABLE_juce_video=1" "-DJUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1" "-DJUCE_USE_MP3AUDIOFORMAT=1" "-DJUCE_PLUGINHOST_VST3=1" "-DJUCE_PLUGINHOST_LV2=1" "-DJUCE_ALLOW_STATIC_NULL_VARIABLES=0" "-DJUCE_STRICT_REFCOUNTEDPOINTER=1" "-DJUCE_USE_CAMERA=1" "-DJUCE_STANDALONE_APPLICATION=1" "-DJUCE_DEMO_RUNNER=1" "-DJUCE_UNIT_TESTS=1" "-DJUCE_PUSH_NOTIFICATIONS=1" "-DJUCER_LINUX_MAKE_6D53C8B4=1" "-DJUCE_APP_VERSION=8.0.8" "-DJUCE_APP_VERSION_HEX=0x80008" $(shell $(PKG_CONFIG) --cflags $(shell ($(PKG_CONFIG) --exists webkit2gtk-4.1 && echo webkit2gtk-4.1) || echo webkit2gtk-4.0) alsa freetype2 fontconfig gl libcurl gtk+-x11-3.0) -pthread -I../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv/src -I../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv -I../../../../modules/juce_audio_processors/format_types/LV2_SDK/sratom -I../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord/src -I../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord -I../../../../modules/juce_audio_processors/format_types/LV2_SDK/serd -I../../../../modules/juce_audio_processors/format_types/LV2_SDK/lv2 -I../../../../modules/juce_audio_processors/format_types/LV2_SDK -I../../../../modules/juce_audio_processors/format_types/VST3_SDK -I../../JuceLibraryCode -I../../../../modules $(CPPFLAGS) + JUCE_CPPFLAGS := $(DEPFLAGS) "-DLINUX=1" "-DNDEBUG=1" "-DJUCE_PROJUCER_VERSION=0x80008" "-DJUCE_MODULE_AVAILABLE_juce_analytics=1" "-DJUCE_MODULE_AVAILABLE_juce_animation=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_devices=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_formats=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_processors=1" "-DJUCE_MODULE_AVAILABLE_juce_audio_utils=1" "-DJUCE_MODULE_AVAILABLE_juce_box2d=1" "-DJUCE_MODULE_AVAILABLE_juce_core=1" "-DJUCE_MODULE_AVAILABLE_juce_cryptography=1" "-DJUCE_MODULE_AVAILABLE_juce_data_structures=1" "-DJUCE_MODULE_AVAILABLE_juce_dsp=1" "-DJUCE_MODULE_AVAILABLE_juce_events=1" "-DJUCE_MODULE_AVAILABLE_juce_graphics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_basics=1" "-DJUCE_MODULE_AVAILABLE_juce_gui_extra=1" "-DJUCE_MODULE_AVAILABLE_juce_javascript=1" "-DJUCE_MODULE_AVAILABLE_juce_midi_ci=1" "-DJUCE_MODULE_AVAILABLE_juce_opengl=1" "-DJUCE_MODULE_AVAILABLE_juce_osc=1" "-DJUCE_MODULE_AVAILABLE_juce_product_unlocking=1" "-DJUCE_MODULE_AVAILABLE_juce_video=1" "-DJUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1" "-DJUCE_USE_MP3AUDIOFORMAT=1" "-DJUCE_PLUGINHOST_VST3=1" "-DJUCE_PLUGINHOST_AU=1" "-DJUCE_PLUGINHOST_LV2=1" "-DJUCE_ALLOW_STATIC_NULL_VARIABLES=0" "-DJUCE_STRICT_REFCOUNTEDPOINTER=1" "-DJUCE_USE_CAMERA=1" "-DJUCE_STANDALONE_APPLICATION=1" "-DJUCE_DEMO_RUNNER=1" "-DJUCE_UNIT_TESTS=1" "-DJUCE_PUSH_NOTIFICATIONS=1" "-DJUCER_LINUX_MAKE_6D53C8B4=1" "-DJUCE_APP_VERSION=8.0.8" "-DJUCE_APP_VERSION_HEX=0x80008" $(shell $(PKG_CONFIG) --cflags $(shell ($(PKG_CONFIG) --exists webkit2gtk-4.1 && echo webkit2gtk-4.1) || echo webkit2gtk-4.0) alsa freetype2 fontconfig gl libcurl gtk+-x11-3.0) -pthread -I../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv/src -I../../../../modules/juce_audio_processors/format_types/LV2_SDK/lilv -I../../../../modules/juce_audio_processors/format_types/LV2_SDK/sratom -I../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord/src -I../../../../modules/juce_audio_processors/format_types/LV2_SDK/sord -I../../../../modules/juce_audio_processors/format_types/LV2_SDK/serd -I../../../../modules/juce_audio_processors/format_types/LV2_SDK/lv2 -I../../../../modules/juce_audio_processors/format_types/LV2_SDK -I../../../../modules/juce_audio_processors/format_types/VST3_SDK -I../../JuceLibraryCode -I../../../../modules $(CPPFLAGS) JUCE_CPPFLAGS_APP := "-DJucePlugin_Build_VST=0" "-DJucePlugin_Build_VST3=0" "-DJucePlugin_Build_AU=0" "-DJucePlugin_Build_AUv3=0" "-DJucePlugin_Build_AAX=0" "-DJucePlugin_Build_Standalone=0" "-DJucePlugin_Build_Unity=0" "-DJucePlugin_Build_LV2=0" JUCE_TARGET_APP := DemoRunner diff --git a/examples/DemoRunner/Builds/MacOSX/DemoRunner.xcodeproj/project.pbxproj b/examples/DemoRunner/Builds/MacOSX/DemoRunner.xcodeproj/project.pbxproj index 6738318cb5..bdfeb3827b 100644 --- a/examples/DemoRunner/Builds/MacOSX/DemoRunner.xcodeproj/project.pbxproj +++ b/examples/DemoRunner/Builds/MacOSX/DemoRunner.xcodeproj/project.pbxproj @@ -29,6 +29,7 @@ 4FBBB55F4E347757F74F1F41 /* MainComponent.cpp */ = {isa = PBXBuildFile; fileRef = 25E5ED33876A2C752378C859; }; 527DA2E6827BAFDDD3E8E80F /* CoreAudioKit.framework */ = {isa = PBXBuildFile; fileRef = B4389672DA4CC8E0A531062D; }; 55F120E70543228568573D4A /* include_juce_animation.cpp */ = {isa = PBXBuildFile; fileRef = CB4C64BACC1CA4AAD6D69565; }; + 5C1957CE874953FB83DCDACB /* AudioUnit.framework */ = {isa = PBXBuildFile; fileRef = 4A8625BBDD6C3BA8052CCA53; }; 5CB78489F16E82144914972D /* include_juce_gui_extra.mm */ = {isa = PBXBuildFile; fileRef = 979F23EA9E5E76131299E886; }; 5E4310B3F6BB639875D3E9B8 /* Foundation.framework */ = {isa = PBXBuildFile; fileRef = 49ECA8B998B339A083674A22; }; 5EB6872A39122A5AB67E544E /* include_juce_audio_processors_ara.cpp */ = {isa = PBXBuildFile; fileRef = 8D44097417573B38729A0179; }; @@ -97,6 +98,7 @@ 483C3A8B4FB98B54BB42CB50 /* include_juce_graphics_Harfbuzz.cpp */ /* include_juce_graphics_Harfbuzz.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = include_juce_graphics_Harfbuzz.cpp; path = ../../JuceLibraryCode/include_juce_graphics_Harfbuzz.cpp; sourceTree = SOURCE_ROOT; }; 491641F7632BCC81BBA0ED85 /* juce_audio_formats */ /* juce_audio_formats */ = {isa = PBXFileReference; lastKnownFileType = folder; name = juce_audio_formats; path = ../../../../modules/juce_audio_formats; sourceTree = SOURCE_ROOT; }; 49ECA8B998B339A083674A22 /* Foundation.framework */ /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 4A8625BBDD6C3BA8052CCA53 /* AudioUnit.framework */ /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = System/Library/Frameworks/AudioUnit.framework; sourceTree = SDKROOT; }; 4DF215D350FFE5E119CBA7E5 /* include_juce_box2d.cpp */ /* include_juce_box2d.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = include_juce_box2d.cpp; path = ../../JuceLibraryCode/include_juce_box2d.cpp; sourceTree = SOURCE_ROOT; }; 4E9AD0EAF3CA57B548622D9A /* JuceHeader.h */ /* JuceHeader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = JuceHeader.h; path = ../../JuceLibraryCode/JuceHeader.h; sourceTree = SOURCE_ROOT; }; 4EC2782DE1779A130835B64D /* Info-App.plist */ /* Info-App.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "Info-App.plist"; path = "Info-App.plist"; sourceTree = SOURCE_ROOT; }; @@ -165,6 +167,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 5C1957CE874953FB83DCDACB, 48CF0B02E1D06E5DA51E6270, 163B0CF2DD0990A63DF1D5A6, 7B4163348896EB1B86B15160, @@ -192,6 +195,7 @@ 4452EAA652B65A9AE648288C /* Frameworks */ = { isa = PBXGroup; children = ( + 4A8625BBDD6C3BA8052CCA53, A04E4408525F24F7DCBA000E, 470C3E4553B513FFEF752779, DC192EFA899E6CBE6B5CD394, @@ -577,6 +581,7 @@ "JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1", "JUCE_USE_MP3AUDIOFORMAT=1", "JUCE_PLUGINHOST_VST3=1", + "JUCE_PLUGINHOST_AU=1", "JUCE_PLUGINHOST_LV2=1", "JUCE_ALLOW_STATIC_NULL_VARIABLES=0", "JUCE_STRICT_REFCOUNTEDPOINTER=1", @@ -671,6 +676,7 @@ "JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1", "JUCE_USE_MP3AUDIOFORMAT=1", "JUCE_PLUGINHOST_VST3=1", + "JUCE_PLUGINHOST_AU=1", "JUCE_PLUGINHOST_LV2=1", "JUCE_ALLOW_STATIC_NULL_VARIABLES=0", "JUCE_STRICT_REFCOUNTEDPOINTER=1", diff --git a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj index 5301d64dbe..ef40d3824a 100644 --- a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj +++ b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj @@ -68,7 +68,7 @@ Disabled ProgramDatabase ..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\lilv\src;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\lilv;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\sratom;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\sord\src;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\sord;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\serd;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\lv2;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK;..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK;..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCE_PROJUCER_VERSION=0x80008;JUCE_MODULE_AVAILABLE_juce_analytics=1;JUCE_MODULE_AVAILABLE_juce_animation=1;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_audio_formats=1;JUCE_MODULE_AVAILABLE_juce_audio_processors=1;JUCE_MODULE_AVAILABLE_juce_audio_utils=1;JUCE_MODULE_AVAILABLE_juce_box2d=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_dsp=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_MODULE_AVAILABLE_juce_javascript=1;JUCE_MODULE_AVAILABLE_juce_midi_ci=1;JUCE_MODULE_AVAILABLE_juce_opengl=1;JUCE_MODULE_AVAILABLE_juce_osc=1;JUCE_MODULE_AVAILABLE_juce_product_unlocking=1;JUCE_MODULE_AVAILABLE_juce_video=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_USE_MP3AUDIOFORMAT=1;JUCE_PLUGINHOST_VST3=1;JUCE_PLUGINHOST_LV2=1;JUCE_ALLOW_STATIC_NULL_VARIABLES=0;JUCE_STRICT_REFCOUNTEDPOINTER=1;JUCE_USE_CAMERA=1;JUCE_STANDALONE_APPLICATION=1;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCE_PUSH_NOTIFICATIONS=1;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=8.0.8;JUCE_APP_VERSION_HEX=0x80008;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;JucePlugin_Build_LV2=0;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCE_PROJUCER_VERSION=0x80008;JUCE_MODULE_AVAILABLE_juce_analytics=1;JUCE_MODULE_AVAILABLE_juce_animation=1;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_audio_formats=1;JUCE_MODULE_AVAILABLE_juce_audio_processors=1;JUCE_MODULE_AVAILABLE_juce_audio_utils=1;JUCE_MODULE_AVAILABLE_juce_box2d=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_dsp=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_MODULE_AVAILABLE_juce_javascript=1;JUCE_MODULE_AVAILABLE_juce_midi_ci=1;JUCE_MODULE_AVAILABLE_juce_opengl=1;JUCE_MODULE_AVAILABLE_juce_osc=1;JUCE_MODULE_AVAILABLE_juce_product_unlocking=1;JUCE_MODULE_AVAILABLE_juce_video=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_USE_MP3AUDIOFORMAT=1;JUCE_PLUGINHOST_VST3=1;JUCE_PLUGINHOST_AU=1;JUCE_PLUGINHOST_LV2=1;JUCE_ALLOW_STATIC_NULL_VARIABLES=0;JUCE_STRICT_REFCOUNTEDPOINTER=1;JUCE_USE_CAMERA=1;JUCE_STANDALONE_APPLICATION=1;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCE_PUSH_NOTIFICATIONS=1;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=8.0.8;JUCE_APP_VERSION_HEX=0x80008;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;JucePlugin_Build_LV2=0;%(PreprocessorDefinitions) MultiThreadedDebugDLL true NotUsing @@ -83,7 +83,7 @@ ..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\lilv\src;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\lilv;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\sratom;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\sord\src;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\sord;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\serd;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\lv2;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK;..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK;..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCE_PROJUCER_VERSION=0x80008;JUCE_MODULE_AVAILABLE_juce_analytics=1;JUCE_MODULE_AVAILABLE_juce_animation=1;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_audio_formats=1;JUCE_MODULE_AVAILABLE_juce_audio_processors=1;JUCE_MODULE_AVAILABLE_juce_audio_utils=1;JUCE_MODULE_AVAILABLE_juce_box2d=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_dsp=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_MODULE_AVAILABLE_juce_javascript=1;JUCE_MODULE_AVAILABLE_juce_midi_ci=1;JUCE_MODULE_AVAILABLE_juce_opengl=1;JUCE_MODULE_AVAILABLE_juce_osc=1;JUCE_MODULE_AVAILABLE_juce_product_unlocking=1;JUCE_MODULE_AVAILABLE_juce_video=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_USE_MP3AUDIOFORMAT=1;JUCE_PLUGINHOST_VST3=1;JUCE_PLUGINHOST_LV2=1;JUCE_ALLOW_STATIC_NULL_VARIABLES=0;JUCE_STRICT_REFCOUNTEDPOINTER=1;JUCE_USE_CAMERA=1;JUCE_STANDALONE_APPLICATION=1;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCE_PUSH_NOTIFICATIONS=1;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=8.0.8;JUCE_APP_VERSION_HEX=0x80008;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;JucePlugin_Build_LV2=0;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCE_PROJUCER_VERSION=0x80008;JUCE_MODULE_AVAILABLE_juce_analytics=1;JUCE_MODULE_AVAILABLE_juce_animation=1;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_audio_formats=1;JUCE_MODULE_AVAILABLE_juce_audio_processors=1;JUCE_MODULE_AVAILABLE_juce_audio_utils=1;JUCE_MODULE_AVAILABLE_juce_box2d=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_dsp=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_MODULE_AVAILABLE_juce_javascript=1;JUCE_MODULE_AVAILABLE_juce_midi_ci=1;JUCE_MODULE_AVAILABLE_juce_opengl=1;JUCE_MODULE_AVAILABLE_juce_osc=1;JUCE_MODULE_AVAILABLE_juce_product_unlocking=1;JUCE_MODULE_AVAILABLE_juce_video=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_USE_MP3AUDIOFORMAT=1;JUCE_PLUGINHOST_VST3=1;JUCE_PLUGINHOST_AU=1;JUCE_PLUGINHOST_LV2=1;JUCE_ALLOW_STATIC_NULL_VARIABLES=0;JUCE_STRICT_REFCOUNTEDPOINTER=1;JUCE_USE_CAMERA=1;JUCE_STANDALONE_APPLICATION=1;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCE_PUSH_NOTIFICATIONS=1;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=8.0.8;JUCE_APP_VERSION_HEX=0x80008;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;JucePlugin_Build_LV2=0;%(PreprocessorDefinitions) $(OutDir)\DemoRunner.exe @@ -112,7 +112,7 @@ Full ProgramDatabase ..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\lilv\src;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\lilv;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\sratom;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\sord\src;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\sord;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\serd;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\lv2;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK;..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK;..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCE_PROJUCER_VERSION=0x80008;JUCE_MODULE_AVAILABLE_juce_analytics=1;JUCE_MODULE_AVAILABLE_juce_animation=1;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_audio_formats=1;JUCE_MODULE_AVAILABLE_juce_audio_processors=1;JUCE_MODULE_AVAILABLE_juce_audio_utils=1;JUCE_MODULE_AVAILABLE_juce_box2d=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_dsp=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_MODULE_AVAILABLE_juce_javascript=1;JUCE_MODULE_AVAILABLE_juce_midi_ci=1;JUCE_MODULE_AVAILABLE_juce_opengl=1;JUCE_MODULE_AVAILABLE_juce_osc=1;JUCE_MODULE_AVAILABLE_juce_product_unlocking=1;JUCE_MODULE_AVAILABLE_juce_video=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_USE_MP3AUDIOFORMAT=1;JUCE_PLUGINHOST_VST3=1;JUCE_PLUGINHOST_LV2=1;JUCE_ALLOW_STATIC_NULL_VARIABLES=0;JUCE_STRICT_REFCOUNTEDPOINTER=1;JUCE_USE_CAMERA=1;JUCE_STANDALONE_APPLICATION=1;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCE_PUSH_NOTIFICATIONS=1;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=8.0.8;JUCE_APP_VERSION_HEX=0x80008;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;JucePlugin_Build_LV2=0;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCE_PROJUCER_VERSION=0x80008;JUCE_MODULE_AVAILABLE_juce_analytics=1;JUCE_MODULE_AVAILABLE_juce_animation=1;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_audio_formats=1;JUCE_MODULE_AVAILABLE_juce_audio_processors=1;JUCE_MODULE_AVAILABLE_juce_audio_utils=1;JUCE_MODULE_AVAILABLE_juce_box2d=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_dsp=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_MODULE_AVAILABLE_juce_javascript=1;JUCE_MODULE_AVAILABLE_juce_midi_ci=1;JUCE_MODULE_AVAILABLE_juce_opengl=1;JUCE_MODULE_AVAILABLE_juce_osc=1;JUCE_MODULE_AVAILABLE_juce_product_unlocking=1;JUCE_MODULE_AVAILABLE_juce_video=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_USE_MP3AUDIOFORMAT=1;JUCE_PLUGINHOST_VST3=1;JUCE_PLUGINHOST_AU=1;JUCE_PLUGINHOST_LV2=1;JUCE_ALLOW_STATIC_NULL_VARIABLES=0;JUCE_STRICT_REFCOUNTEDPOINTER=1;JUCE_USE_CAMERA=1;JUCE_STANDALONE_APPLICATION=1;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCE_PUSH_NOTIFICATIONS=1;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=8.0.8;JUCE_APP_VERSION_HEX=0x80008;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;JucePlugin_Build_LV2=0;%(PreprocessorDefinitions) MultiThreaded true NotUsing @@ -127,7 +127,7 @@ ..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\lilv\src;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\lilv;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\sratom;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\sord\src;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\sord;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\serd;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\lv2;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK;..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK;..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCE_PROJUCER_VERSION=0x80008;JUCE_MODULE_AVAILABLE_juce_analytics=1;JUCE_MODULE_AVAILABLE_juce_animation=1;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_audio_formats=1;JUCE_MODULE_AVAILABLE_juce_audio_processors=1;JUCE_MODULE_AVAILABLE_juce_audio_utils=1;JUCE_MODULE_AVAILABLE_juce_box2d=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_dsp=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_MODULE_AVAILABLE_juce_javascript=1;JUCE_MODULE_AVAILABLE_juce_midi_ci=1;JUCE_MODULE_AVAILABLE_juce_opengl=1;JUCE_MODULE_AVAILABLE_juce_osc=1;JUCE_MODULE_AVAILABLE_juce_product_unlocking=1;JUCE_MODULE_AVAILABLE_juce_video=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_USE_MP3AUDIOFORMAT=1;JUCE_PLUGINHOST_VST3=1;JUCE_PLUGINHOST_LV2=1;JUCE_ALLOW_STATIC_NULL_VARIABLES=0;JUCE_STRICT_REFCOUNTEDPOINTER=1;JUCE_USE_CAMERA=1;JUCE_STANDALONE_APPLICATION=1;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCE_PUSH_NOTIFICATIONS=1;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=8.0.8;JUCE_APP_VERSION_HEX=0x80008;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;JucePlugin_Build_LV2=0;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCE_PROJUCER_VERSION=0x80008;JUCE_MODULE_AVAILABLE_juce_analytics=1;JUCE_MODULE_AVAILABLE_juce_animation=1;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_audio_formats=1;JUCE_MODULE_AVAILABLE_juce_audio_processors=1;JUCE_MODULE_AVAILABLE_juce_audio_utils=1;JUCE_MODULE_AVAILABLE_juce_box2d=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_dsp=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_MODULE_AVAILABLE_juce_javascript=1;JUCE_MODULE_AVAILABLE_juce_midi_ci=1;JUCE_MODULE_AVAILABLE_juce_opengl=1;JUCE_MODULE_AVAILABLE_juce_osc=1;JUCE_MODULE_AVAILABLE_juce_product_unlocking=1;JUCE_MODULE_AVAILABLE_juce_video=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_USE_MP3AUDIOFORMAT=1;JUCE_PLUGINHOST_VST3=1;JUCE_PLUGINHOST_AU=1;JUCE_PLUGINHOST_LV2=1;JUCE_ALLOW_STATIC_NULL_VARIABLES=0;JUCE_STRICT_REFCOUNTEDPOINTER=1;JUCE_USE_CAMERA=1;JUCE_STANDALONE_APPLICATION=1;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCE_PUSH_NOTIFICATIONS=1;JUCER_VS2019_78A5026=1;JUCE_APP_VERSION=8.0.8;JUCE_APP_VERSION_HEX=0x80008;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;JucePlugin_Build_LV2=0;%(PreprocessorDefinitions) $(OutDir)\DemoRunner.exe @@ -1020,6 +1020,9 @@ true + + true + true @@ -1056,6 +1059,12 @@ true + + true + + + true + true diff --git a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters index 3443195c73..b65cb16ffc 100644 --- a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters +++ b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters @@ -1723,6 +1723,9 @@ JUCE Modules\juce_audio_processors\format_types + + JUCE Modules\juce_audio_processors\format_types + JUCE Modules\juce_audio_processors\format_types @@ -1759,6 +1762,12 @@ JUCE Modules\juce_audio_processors\processors + + JUCE Modules\juce_audio_processors\processors + + + JUCE Modules\juce_audio_processors\processors + JUCE Modules\juce_audio_processors\processors diff --git a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj index 347119b4fe..87f9585e69 100644 --- a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj +++ b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj @@ -68,7 +68,7 @@ Disabled ProgramDatabase ..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\lilv\src;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\lilv;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\sratom;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\sord\src;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\sord;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\serd;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\lv2;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK;..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK;..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCE_PROJUCER_VERSION=0x80008;JUCE_MODULE_AVAILABLE_juce_analytics=1;JUCE_MODULE_AVAILABLE_juce_animation=1;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_audio_formats=1;JUCE_MODULE_AVAILABLE_juce_audio_processors=1;JUCE_MODULE_AVAILABLE_juce_audio_utils=1;JUCE_MODULE_AVAILABLE_juce_box2d=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_dsp=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_MODULE_AVAILABLE_juce_javascript=1;JUCE_MODULE_AVAILABLE_juce_midi_ci=1;JUCE_MODULE_AVAILABLE_juce_opengl=1;JUCE_MODULE_AVAILABLE_juce_osc=1;JUCE_MODULE_AVAILABLE_juce_product_unlocking=1;JUCE_MODULE_AVAILABLE_juce_video=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_USE_MP3AUDIOFORMAT=1;JUCE_PLUGINHOST_VST3=1;JUCE_PLUGINHOST_LV2=1;JUCE_ALLOW_STATIC_NULL_VARIABLES=0;JUCE_STRICT_REFCOUNTEDPOINTER=1;JUCE_USE_CAMERA=1;JUCE_STANDALONE_APPLICATION=1;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCE_PUSH_NOTIFICATIONS=1;JUCER_VS2022_78A503E=1;JUCE_APP_VERSION=8.0.8;JUCE_APP_VERSION_HEX=0x80008;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;JucePlugin_Build_LV2=0;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCE_PROJUCER_VERSION=0x80008;JUCE_MODULE_AVAILABLE_juce_analytics=1;JUCE_MODULE_AVAILABLE_juce_animation=1;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_audio_formats=1;JUCE_MODULE_AVAILABLE_juce_audio_processors=1;JUCE_MODULE_AVAILABLE_juce_audio_utils=1;JUCE_MODULE_AVAILABLE_juce_box2d=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_dsp=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_MODULE_AVAILABLE_juce_javascript=1;JUCE_MODULE_AVAILABLE_juce_midi_ci=1;JUCE_MODULE_AVAILABLE_juce_opengl=1;JUCE_MODULE_AVAILABLE_juce_osc=1;JUCE_MODULE_AVAILABLE_juce_product_unlocking=1;JUCE_MODULE_AVAILABLE_juce_video=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_USE_MP3AUDIOFORMAT=1;JUCE_PLUGINHOST_VST3=1;JUCE_PLUGINHOST_AU=1;JUCE_PLUGINHOST_LV2=1;JUCE_ALLOW_STATIC_NULL_VARIABLES=0;JUCE_STRICT_REFCOUNTEDPOINTER=1;JUCE_USE_CAMERA=1;JUCE_STANDALONE_APPLICATION=1;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCE_PUSH_NOTIFICATIONS=1;JUCER_VS2022_78A503E=1;JUCE_APP_VERSION=8.0.8;JUCE_APP_VERSION_HEX=0x80008;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;JucePlugin_Build_LV2=0;%(PreprocessorDefinitions) MultiThreadedDebugDLL true NotUsing @@ -83,7 +83,7 @@ ..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\lilv\src;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\lilv;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\sratom;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\sord\src;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\sord;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\serd;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\lv2;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK;..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK;..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCE_PROJUCER_VERSION=0x80008;JUCE_MODULE_AVAILABLE_juce_analytics=1;JUCE_MODULE_AVAILABLE_juce_animation=1;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_audio_formats=1;JUCE_MODULE_AVAILABLE_juce_audio_processors=1;JUCE_MODULE_AVAILABLE_juce_audio_utils=1;JUCE_MODULE_AVAILABLE_juce_box2d=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_dsp=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_MODULE_AVAILABLE_juce_javascript=1;JUCE_MODULE_AVAILABLE_juce_midi_ci=1;JUCE_MODULE_AVAILABLE_juce_opengl=1;JUCE_MODULE_AVAILABLE_juce_osc=1;JUCE_MODULE_AVAILABLE_juce_product_unlocking=1;JUCE_MODULE_AVAILABLE_juce_video=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_USE_MP3AUDIOFORMAT=1;JUCE_PLUGINHOST_VST3=1;JUCE_PLUGINHOST_LV2=1;JUCE_ALLOW_STATIC_NULL_VARIABLES=0;JUCE_STRICT_REFCOUNTEDPOINTER=1;JUCE_USE_CAMERA=1;JUCE_STANDALONE_APPLICATION=1;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCE_PUSH_NOTIFICATIONS=1;JUCER_VS2022_78A503E=1;JUCE_APP_VERSION=8.0.8;JUCE_APP_VERSION_HEX=0x80008;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;JucePlugin_Build_LV2=0;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;DEBUG;_DEBUG;JUCE_PROJUCER_VERSION=0x80008;JUCE_MODULE_AVAILABLE_juce_analytics=1;JUCE_MODULE_AVAILABLE_juce_animation=1;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_audio_formats=1;JUCE_MODULE_AVAILABLE_juce_audio_processors=1;JUCE_MODULE_AVAILABLE_juce_audio_utils=1;JUCE_MODULE_AVAILABLE_juce_box2d=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_dsp=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_MODULE_AVAILABLE_juce_javascript=1;JUCE_MODULE_AVAILABLE_juce_midi_ci=1;JUCE_MODULE_AVAILABLE_juce_opengl=1;JUCE_MODULE_AVAILABLE_juce_osc=1;JUCE_MODULE_AVAILABLE_juce_product_unlocking=1;JUCE_MODULE_AVAILABLE_juce_video=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_USE_MP3AUDIOFORMAT=1;JUCE_PLUGINHOST_VST3=1;JUCE_PLUGINHOST_AU=1;JUCE_PLUGINHOST_LV2=1;JUCE_ALLOW_STATIC_NULL_VARIABLES=0;JUCE_STRICT_REFCOUNTEDPOINTER=1;JUCE_USE_CAMERA=1;JUCE_STANDALONE_APPLICATION=1;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCE_PUSH_NOTIFICATIONS=1;JUCER_VS2022_78A503E=1;JUCE_APP_VERSION=8.0.8;JUCE_APP_VERSION_HEX=0x80008;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;JucePlugin_Build_LV2=0;%(PreprocessorDefinitions) $(OutDir)\DemoRunner.exe @@ -112,7 +112,7 @@ Full ProgramDatabase ..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\lilv\src;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\lilv;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\sratom;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\sord\src;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\sord;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\serd;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\lv2;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK;..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK;..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCE_PROJUCER_VERSION=0x80008;JUCE_MODULE_AVAILABLE_juce_analytics=1;JUCE_MODULE_AVAILABLE_juce_animation=1;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_audio_formats=1;JUCE_MODULE_AVAILABLE_juce_audio_processors=1;JUCE_MODULE_AVAILABLE_juce_audio_utils=1;JUCE_MODULE_AVAILABLE_juce_box2d=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_dsp=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_MODULE_AVAILABLE_juce_javascript=1;JUCE_MODULE_AVAILABLE_juce_midi_ci=1;JUCE_MODULE_AVAILABLE_juce_opengl=1;JUCE_MODULE_AVAILABLE_juce_osc=1;JUCE_MODULE_AVAILABLE_juce_product_unlocking=1;JUCE_MODULE_AVAILABLE_juce_video=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_USE_MP3AUDIOFORMAT=1;JUCE_PLUGINHOST_VST3=1;JUCE_PLUGINHOST_LV2=1;JUCE_ALLOW_STATIC_NULL_VARIABLES=0;JUCE_STRICT_REFCOUNTEDPOINTER=1;JUCE_USE_CAMERA=1;JUCE_STANDALONE_APPLICATION=1;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCE_PUSH_NOTIFICATIONS=1;JUCER_VS2022_78A503E=1;JUCE_APP_VERSION=8.0.8;JUCE_APP_VERSION_HEX=0x80008;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;JucePlugin_Build_LV2=0;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCE_PROJUCER_VERSION=0x80008;JUCE_MODULE_AVAILABLE_juce_analytics=1;JUCE_MODULE_AVAILABLE_juce_animation=1;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_audio_formats=1;JUCE_MODULE_AVAILABLE_juce_audio_processors=1;JUCE_MODULE_AVAILABLE_juce_audio_utils=1;JUCE_MODULE_AVAILABLE_juce_box2d=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_dsp=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_MODULE_AVAILABLE_juce_javascript=1;JUCE_MODULE_AVAILABLE_juce_midi_ci=1;JUCE_MODULE_AVAILABLE_juce_opengl=1;JUCE_MODULE_AVAILABLE_juce_osc=1;JUCE_MODULE_AVAILABLE_juce_product_unlocking=1;JUCE_MODULE_AVAILABLE_juce_video=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_USE_MP3AUDIOFORMAT=1;JUCE_PLUGINHOST_VST3=1;JUCE_PLUGINHOST_AU=1;JUCE_PLUGINHOST_LV2=1;JUCE_ALLOW_STATIC_NULL_VARIABLES=0;JUCE_STRICT_REFCOUNTEDPOINTER=1;JUCE_USE_CAMERA=1;JUCE_STANDALONE_APPLICATION=1;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCE_PUSH_NOTIFICATIONS=1;JUCER_VS2022_78A503E=1;JUCE_APP_VERSION=8.0.8;JUCE_APP_VERSION_HEX=0x80008;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;JucePlugin_Build_LV2=0;%(PreprocessorDefinitions) MultiThreaded true NotUsing @@ -127,7 +127,7 @@ ..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\lilv\src;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\lilv;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\sratom;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\sord\src;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\sord;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\serd;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK\lv2;..\..\..\..\modules\juce_audio_processors\format_types\LV2_SDK;..\..\..\..\modules\juce_audio_processors\format_types\VST3_SDK;..\..\JuceLibraryCode;..\..\..\..\modules;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCE_PROJUCER_VERSION=0x80008;JUCE_MODULE_AVAILABLE_juce_analytics=1;JUCE_MODULE_AVAILABLE_juce_animation=1;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_audio_formats=1;JUCE_MODULE_AVAILABLE_juce_audio_processors=1;JUCE_MODULE_AVAILABLE_juce_audio_utils=1;JUCE_MODULE_AVAILABLE_juce_box2d=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_dsp=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_MODULE_AVAILABLE_juce_javascript=1;JUCE_MODULE_AVAILABLE_juce_midi_ci=1;JUCE_MODULE_AVAILABLE_juce_opengl=1;JUCE_MODULE_AVAILABLE_juce_osc=1;JUCE_MODULE_AVAILABLE_juce_product_unlocking=1;JUCE_MODULE_AVAILABLE_juce_video=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_USE_MP3AUDIOFORMAT=1;JUCE_PLUGINHOST_VST3=1;JUCE_PLUGINHOST_LV2=1;JUCE_ALLOW_STATIC_NULL_VARIABLES=0;JUCE_STRICT_REFCOUNTEDPOINTER=1;JUCE_USE_CAMERA=1;JUCE_STANDALONE_APPLICATION=1;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCE_PUSH_NOTIFICATIONS=1;JUCER_VS2022_78A503E=1;JUCE_APP_VERSION=8.0.8;JUCE_APP_VERSION_HEX=0x80008;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;JucePlugin_Build_LV2=0;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;WIN32;_WINDOWS;NDEBUG;JUCE_PROJUCER_VERSION=0x80008;JUCE_MODULE_AVAILABLE_juce_analytics=1;JUCE_MODULE_AVAILABLE_juce_animation=1;JUCE_MODULE_AVAILABLE_juce_audio_basics=1;JUCE_MODULE_AVAILABLE_juce_audio_devices=1;JUCE_MODULE_AVAILABLE_juce_audio_formats=1;JUCE_MODULE_AVAILABLE_juce_audio_processors=1;JUCE_MODULE_AVAILABLE_juce_audio_utils=1;JUCE_MODULE_AVAILABLE_juce_box2d=1;JUCE_MODULE_AVAILABLE_juce_core=1;JUCE_MODULE_AVAILABLE_juce_cryptography=1;JUCE_MODULE_AVAILABLE_juce_data_structures=1;JUCE_MODULE_AVAILABLE_juce_dsp=1;JUCE_MODULE_AVAILABLE_juce_events=1;JUCE_MODULE_AVAILABLE_juce_graphics=1;JUCE_MODULE_AVAILABLE_juce_gui_basics=1;JUCE_MODULE_AVAILABLE_juce_gui_extra=1;JUCE_MODULE_AVAILABLE_juce_javascript=1;JUCE_MODULE_AVAILABLE_juce_midi_ci=1;JUCE_MODULE_AVAILABLE_juce_opengl=1;JUCE_MODULE_AVAILABLE_juce_osc=1;JUCE_MODULE_AVAILABLE_juce_product_unlocking=1;JUCE_MODULE_AVAILABLE_juce_video=1;JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1;JUCE_USE_MP3AUDIOFORMAT=1;JUCE_PLUGINHOST_VST3=1;JUCE_PLUGINHOST_AU=1;JUCE_PLUGINHOST_LV2=1;JUCE_ALLOW_STATIC_NULL_VARIABLES=0;JUCE_STRICT_REFCOUNTEDPOINTER=1;JUCE_USE_CAMERA=1;JUCE_STANDALONE_APPLICATION=1;JUCE_DEMO_RUNNER=1;JUCE_UNIT_TESTS=1;JUCE_PUSH_NOTIFICATIONS=1;JUCER_VS2022_78A503E=1;JUCE_APP_VERSION=8.0.8;JUCE_APP_VERSION_HEX=0x80008;JucePlugin_Build_VST=0;JucePlugin_Build_VST3=0;JucePlugin_Build_AU=0;JucePlugin_Build_AUv3=0;JucePlugin_Build_AAX=0;JucePlugin_Build_Standalone=0;JucePlugin_Build_Unity=0;JucePlugin_Build_LV2=0;%(PreprocessorDefinitions) $(OutDir)\DemoRunner.exe @@ -1020,6 +1020,9 @@ true + + true + true @@ -1056,6 +1059,12 @@ true + + true + + + true + true diff --git a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters index 42c70e400f..d4c3e7fc6a 100644 --- a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters +++ b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters @@ -1723,6 +1723,9 @@ JUCE Modules\juce_audio_processors\format_types + + JUCE Modules\juce_audio_processors\format_types + JUCE Modules\juce_audio_processors\format_types @@ -1759,6 +1762,12 @@ JUCE Modules\juce_audio_processors\processors + + JUCE Modules\juce_audio_processors\processors + + + JUCE Modules\juce_audio_processors\processors + JUCE Modules\juce_audio_processors\processors diff --git a/examples/DemoRunner/Builds/iOS/App.entitlements b/examples/DemoRunner/Builds/iOS/App.entitlements index 42bc7ba9ba..1f88fc4f83 100644 --- a/examples/DemoRunner/Builds/iOS/App.entitlements +++ b/examples/DemoRunner/Builds/iOS/App.entitlements @@ -2,6 +2,8 @@ + inter-app-audio + com.apple.developer.icloud-container-identifiers iCloud.$(CFBundleIdentifier) diff --git a/examples/DemoRunner/Builds/iOS/DemoRunner.xcodeproj/project.pbxproj b/examples/DemoRunner/Builds/iOS/DemoRunner.xcodeproj/project.pbxproj index 2d96b5e41c..cce1ef3db7 100644 --- a/examples/DemoRunner/Builds/iOS/DemoRunner.xcodeproj/project.pbxproj +++ b/examples/DemoRunner/Builds/iOS/DemoRunner.xcodeproj/project.pbxproj @@ -410,7 +410,7 @@ enabled = 0; }; com.apple.InterAppAudio = { - enabled = 0; + enabled = 1; }; com.apple.Push = { enabled = 0; @@ -588,6 +588,7 @@ "JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1", "JUCE_USE_MP3AUDIOFORMAT=1", "JUCE_PLUGINHOST_VST3=1", + "JUCE_PLUGINHOST_AU=1", "JUCE_PLUGINHOST_LV2=1", "JUCE_ALLOW_STATIC_NULL_VARIABLES=0", "JUCE_STRICT_REFCOUNTEDPOINTER=1", @@ -682,6 +683,7 @@ "JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1", "JUCE_USE_MP3AUDIOFORMAT=1", "JUCE_PLUGINHOST_VST3=1", + "JUCE_PLUGINHOST_AU=1", "JUCE_PLUGINHOST_LV2=1", "JUCE_ALLOW_STATIC_NULL_VARIABLES=0", "JUCE_STRICT_REFCOUNTEDPOINTER=1", diff --git a/examples/DemoRunner/Builds/iOS/Info-App.plist b/examples/DemoRunner/Builds/iOS/Info-App.plist index d8b1054a27..9adbb45a6f 100644 --- a/examples/DemoRunner/Builds/iOS/Info-App.plist +++ b/examples/DemoRunner/Builds/iOS/Info-App.plist @@ -17,6 +17,13 @@ UILaunchStoryboardName LaunchScreen + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier diff --git a/examples/DemoRunner/CMakeLists.txt b/examples/DemoRunner/CMakeLists.txt index 4a8d650a31..7f5d77b85a 100644 --- a/examples/DemoRunner/CMakeLists.txt +++ b/examples/DemoRunner/CMakeLists.txt @@ -54,6 +54,7 @@ target_compile_definitions(DemoRunner PRIVATE JUCE_ALLOW_STATIC_NULL_VARIABLES=0 JUCE_CONTENT_SHARING=1 JUCE_DEMO_RUNNER=1 + JUCE_PLUGINHOST_AU=1 JUCE_PLUGINHOST_LV2=1 JUCE_PLUGINHOST_VST3=1 JUCE_PUSH_NOTIFICATIONS=1 diff --git a/examples/DemoRunner/DemoRunner.jucer b/examples/DemoRunner/DemoRunner.jucer index e2694a71f8..2b27d30ec8 100644 --- a/examples/DemoRunner/DemoRunner.jucer +++ b/examples/DemoRunner/DemoRunner.jucer @@ -257,7 +257,8 @@ + JUCE_STRICT_REFCOUNTEDPOINTER="1" JUCE_PLUGINHOST_LV2="1" JUCE_PLUGINHOST_VST3="1" + JUCE_PLUGINHOST_AU="1"/> diff --git a/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt b/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt index 03cd95e25b..ca9bdfbaaf 100644 --- a/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt +++ b/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt @@ -760,6 +760,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_processors/format_types/juce_AU_Shared.h" "../../../../../modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.h" "../../../../../modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm" + "../../../../../modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat_test.cpp" "../../../../../modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp" "../../../../../modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.h" "../../../../../modules/juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp" @@ -788,7 +789,9 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorEditorHostContext.h" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h" + "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorListener.cpp" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorListener.h" + "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorParameter.cpp" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorParameterGroup.cpp" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorParameterGroup.h" @@ -3058,6 +3061,7 @@ set_source_files_properties( "../../../../../modules/juce_audio_processors/format_types/juce_AU_Shared.h" "../../../../../modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.h" "../../../../../modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm" + "../../../../../modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat_test.cpp" "../../../../../modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp" "../../../../../modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.h" "../../../../../modules/juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp" @@ -3086,7 +3090,9 @@ set_source_files_properties( "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorEditorHostContext.h" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h" + "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorListener.cpp" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorListener.h" + "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorParameter.cpp" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorParameterGroup.cpp" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorParameterGroup.h" diff --git a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj index acdc6d0047..bbc3392cc7 100644 --- a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj +++ b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj @@ -978,6 +978,9 @@ true + + true + true @@ -1014,6 +1017,12 @@ true + + true + + + true + true diff --git a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters index 4b4340cd8b..aeefc06c58 100644 --- a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters +++ b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters @@ -1504,6 +1504,9 @@ JUCE Modules\juce_audio_processors\format_types + + JUCE Modules\juce_audio_processors\format_types + JUCE Modules\juce_audio_processors\format_types @@ -1540,6 +1543,12 @@ JUCE Modules\juce_audio_processors\processors + + JUCE Modules\juce_audio_processors\processors + + + JUCE Modules\juce_audio_processors\processors + JUCE Modules\juce_audio_processors\processors diff --git a/extras/AudioPerformanceTest/Builds/iOS/Info-App.plist b/extras/AudioPerformanceTest/Builds/iOS/Info-App.plist index 7223a0460a..49fb828a02 100644 --- a/extras/AudioPerformanceTest/Builds/iOS/Info-App.plist +++ b/extras/AudioPerformanceTest/Builds/iOS/Info-App.plist @@ -9,6 +9,13 @@ UILaunchStoryboardName LaunchScreen + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier diff --git a/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt b/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt index 8e5af291fd..32c29712b7 100644 --- a/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt +++ b/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt @@ -793,6 +793,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_processors/format_types/juce_AU_Shared.h" "../../../../../modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.h" "../../../../../modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm" + "../../../../../modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat_test.cpp" "../../../../../modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp" "../../../../../modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.h" "../../../../../modules/juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp" @@ -821,7 +822,9 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorEditorHostContext.h" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h" + "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorListener.cpp" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorListener.h" + "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorParameter.cpp" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorParameterGroup.cpp" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorParameterGroup.h" @@ -3244,6 +3247,7 @@ set_source_files_properties( "../../../../../modules/juce_audio_processors/format_types/juce_AU_Shared.h" "../../../../../modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.h" "../../../../../modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm" + "../../../../../modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat_test.cpp" "../../../../../modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp" "../../../../../modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.h" "../../../../../modules/juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp" @@ -3272,7 +3276,9 @@ set_source_files_properties( "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorEditorHostContext.h" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h" + "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorListener.cpp" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorListener.h" + "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorParameter.cpp" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorParameterGroup.cpp" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorParameterGroup.h" diff --git a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj index b4ddec8884..e80ac75e90 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj +++ b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj @@ -986,6 +986,9 @@ true + + true + true @@ -1022,6 +1025,12 @@ true + + true + + + true + true diff --git a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters index 2ebca4c84e..ceef990767 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters +++ b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters @@ -1579,6 +1579,9 @@ JUCE Modules\juce_audio_processors\format_types + + JUCE Modules\juce_audio_processors\format_types + JUCE Modules\juce_audio_processors\format_types @@ -1615,6 +1618,12 @@ JUCE Modules\juce_audio_processors\processors + + JUCE Modules\juce_audio_processors\processors + + + JUCE Modules\juce_audio_processors\processors + JUCE Modules\juce_audio_processors\processors diff --git a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj index 1110f35e1a..d0a64a8214 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj +++ b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj @@ -986,6 +986,9 @@ true + + true + true @@ -1022,6 +1025,12 @@ true + + true + + + true + true diff --git a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters index 2db578d129..0fe0fb861b 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters +++ b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters @@ -1579,6 +1579,9 @@ JUCE Modules\juce_audio_processors\format_types + + JUCE Modules\juce_audio_processors\format_types + JUCE Modules\juce_audio_processors\format_types @@ -1615,6 +1618,12 @@ JUCE Modules\juce_audio_processors\processors + + JUCE Modules\juce_audio_processors\processors + + + JUCE Modules\juce_audio_processors\processors + JUCE Modules\juce_audio_processors\processors diff --git a/extras/AudioPluginHost/Builds/iOS/Info-App.plist b/extras/AudioPluginHost/Builds/iOS/Info-App.plist index 9be3f85435..902b6b63ad 100644 --- a/extras/AudioPluginHost/Builds/iOS/Info-App.plist +++ b/extras/AudioPluginHost/Builds/iOS/Info-App.plist @@ -11,6 +11,13 @@ UILaunchStoryboardName LaunchScreen + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier diff --git a/extras/Build/CMake/JUCEUtils.cmake b/extras/Build/CMake/JUCEUtils.cmake index e218a16c4a..8cf7b41719 100644 --- a/extras/Build/CMake/JUCEUtils.cmake +++ b/extras/Build/CMake/JUCEUtils.cmake @@ -1044,7 +1044,9 @@ endfunction() # ================================================================================================== function(_juce_add_vst3_manifest_helper_target shared_code_target) - if(TARGET juce_vst3_helper + set(vst3_helper_target ${shared_code_target}_vst3_helper) + + if(TARGET ${vst3_helper_target} OR (CMAKE_SYSTEM_NAME STREQUAL "iOS") OR (CMAKE_SYSTEM_NAME STREQUAL "Android") OR (CMAKE_SYSTEM_NAME MATCHES ".*BSD")) @@ -1062,7 +1064,6 @@ function(_juce_add_vst3_manifest_helper_target shared_code_target) set(source "${module_path}/juce_audio_plugin_client/VST3/juce_VST3ManifestHelper.${extension}") - set(vst3_helper_target ${shared_code_target}_vst3_helper) add_executable(${vst3_helper_target} "${source}") add_executable(juce::${vst3_helper_target} ALIAS ${vst3_helper_target}) diff --git a/extras/Build/juce_build_tools/utils/juce_PlistOptions.cpp b/extras/Build/juce_build_tools/utils/juce_PlistOptions.cpp index eba17c96c3..af02ab5687 100644 --- a/extras/Build/juce_build_tools/utils/juce_PlistOptions.cpp +++ b/extras/Build/juce_build_tools/utils/juce_PlistOptions.cpp @@ -165,6 +165,15 @@ namespace juce::build_tools if (shouldAddStoryboardToProject) addPlistDictionaryKey (*dict, "UILaunchStoryboardName", storyboardName); + + XmlElement sceneManifestKey ("key"); + sceneManifestKey.addTextElement ("UIApplicationSceneManifest"); + dict->addChildElement (new XmlElement (sceneManifestKey)); + + auto* sceneManifestDict = dict->createNewChildElement ("dict"); + addPlistDictionaryKey (*sceneManifestDict, "UIApplicationSupportsMultipleScenes", false); + addKeyIfNotFound (*sceneManifestDict, "UISceneConfigurations"); + sceneManifestDict->createNewChildElement ("dict"); } else { diff --git a/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt b/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt index 32be901834..cf20609d1f 100644 --- a/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt +++ b/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt @@ -764,6 +764,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_processors/format_types/juce_AU_Shared.h" "../../../../../modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.h" "../../../../../modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm" + "../../../../../modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat_test.cpp" "../../../../../modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp" "../../../../../modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.h" "../../../../../modules/juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp" @@ -792,7 +793,9 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorEditorHostContext.h" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h" + "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorListener.cpp" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorListener.h" + "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorParameter.cpp" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorParameterGroup.cpp" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorParameterGroup.h" @@ -3142,6 +3145,7 @@ set_source_files_properties( "../../../../../modules/juce_audio_processors/format_types/juce_AU_Shared.h" "../../../../../modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.h" "../../../../../modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm" + "../../../../../modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat_test.cpp" "../../../../../modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.cpp" "../../../../../modules/juce_audio_processors/format_types/juce_LADSPAPluginFormat.h" "../../../../../modules/juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp" @@ -3170,7 +3174,9 @@ set_source_files_properties( "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorEditorHostContext.h" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h" + "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorListener.cpp" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorListener.h" + "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorParameter.cpp" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorParameterGroup.cpp" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorParameterGroup.h" diff --git a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj index ea7d72e077..ea745ba8e6 100644 --- a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj +++ b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj @@ -978,6 +978,9 @@ true + + true + true @@ -1014,6 +1017,12 @@ true + + true + + + true + true diff --git a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters index 7b491b9084..818c1800eb 100644 --- a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters +++ b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters @@ -1534,6 +1534,9 @@ JUCE Modules\juce_audio_processors\format_types + + JUCE Modules\juce_audio_processors\format_types + JUCE Modules\juce_audio_processors\format_types @@ -1570,6 +1573,12 @@ JUCE Modules\juce_audio_processors\processors + + JUCE Modules\juce_audio_processors\processors + + + JUCE Modules\juce_audio_processors\processors + JUCE Modules\juce_audio_processors\processors diff --git a/extras/NetworkGraphicsDemo/Builds/iOS/Info-App.plist b/extras/NetworkGraphicsDemo/Builds/iOS/Info-App.plist index db1a8b3bbc..01a4708006 100644 --- a/extras/NetworkGraphicsDemo/Builds/iOS/Info-App.plist +++ b/extras/NetworkGraphicsDemo/Builds/iOS/Info-App.plist @@ -9,6 +9,13 @@ UILaunchStoryboardName LaunchScreen + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_MSVC.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_MSVC.h index cc9b5e44c5..e4d5e48023 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_MSVC.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_MSVC.h @@ -77,6 +77,8 @@ public: MSVCScriptBuilder& deleteFile (const StringOrBuilder& path) { + jassert (path.value.isQuotedString()); + script << "del /s /q " << path.value; script << newLine; return *this; @@ -84,6 +86,8 @@ public: MSVCScriptBuilder& mkdir (const StringOrBuilder& path) { + jassert (path.value.isQuotedString()); + script << "mkdir " << path.value; script << newLine; return *this; @@ -175,7 +179,8 @@ public: MSVCScriptBuilder& append (const StringOrBuilder& string) { - script << string.value << newLine; + if (string.isNotEmpty()) + script << string.value << newLine; return *this; } @@ -803,7 +808,8 @@ public: std::pair { Ids::vstBinaryLocation, &t.vstBinaryLocation }, std::pair { Ids::vst3BinaryLocation, &t.vst3BinaryLocation }, std::pair { Ids::aaxBinaryLocation, &t.aaxBinaryLocation }, - std::pair { Ids::lv2BinaryLocation, &t.lv2BinaryLocation } + std::pair { Ids::lv2BinaryLocation, &t.lv2BinaryLocation }, + std::pair { Ids::unityPluginBinaryLocation, &t.unityPluginBinaryLocation } }; const auto iter = std::find_if (properties.begin(), @@ -1745,6 +1751,17 @@ public: return aaxSdk.getChildFile ("Utilities").getChildFile ("PlugIn.ico"); } + static bool shouldPerformCopyStepForPlugin (Target::Type pluginType, + const MSVCBuildConfiguration& config, + Architecture arch) + { + if (! config.isPluginBinaryCopyStepEnabled()) + return false; + + const auto binaryLocationId = getPluginTypeInfo (pluginType).second; + return binaryLocationId.isValid() && config.getBinaryPath (binaryLocationId, arch).isNotEmpty(); + } + String getExtraPostBuildSteps (const MSVCBuildConfiguration& config, Architecture arch) const { using Builder = MSVCScriptBuilder; @@ -1764,7 +1781,7 @@ public: + " " + (directory + "\\" + segments[0] + "\\").quoted(); - return config.isPluginBinaryCopyStepEnabled() ? copyStep : ""; + return shouldPerformCopyStepForPlugin (type, config, arch) ? copyStep : ""; }; if (type == AAXPlugIn) @@ -1800,7 +1817,7 @@ public: auto pkgScript = String ("copy /Y ") + scriptPath.toWindowsStyle().quoted() + " \"$(OutDir)\""; - if (config.isPluginBinaryCopyStepEnabled()) + if (shouldPerformCopyStepForPlugin (type, config, arch)) { auto copyLocation = config.getBinaryPath (Ids::unityPluginBinaryLocation, arch); @@ -1835,7 +1852,9 @@ public: + ".lv2\"\r\n"; builder.runAndCheck (writer, - config.isPluginBinaryCopyStepEnabled() ? copyStep : Builder{}.info ("Sucessfully generated LV2 manifest").build(), + shouldPerformCopyStepForPlugin (type, config, arch) + ? copyStep + : Builder{}.info ("Successfully generated LV2 manifest").build(), Builder{}.error ("Failed to generate LV2 manifest.") .exit (-1)); @@ -1945,7 +1964,7 @@ public: .build(); } - if (type == VSTPlugIn && config.isPluginBinaryCopyStepEnabled()) + if (type == VSTPlugIn && shouldPerformCopyStepForPlugin (type, config, arch)) { const String copyCommand = "copy /Y \"$(OutDir)$(TargetFileName)\" \"" + config.getBinaryPath (Ids::vstBinaryLocation, arch) @@ -1960,6 +1979,114 @@ public: return {}; } + static std::pair getPluginTypeInfo (Target::Type targetType) + { + if (targetType == AAXPlugIn) return { "AAX", Ids::aaxBinaryLocation }; + if (targetType == VSTPlugIn) return { "VST (Legacy)", Ids::vstBinaryLocation }; + if (targetType == VST3PlugIn) return { "VST3", Ids::vst3BinaryLocation }; + if (targetType == UnityPlugIn) return { "Unity", Ids::unityPluginBinaryLocation }; + if (targetType == LV2PlugIn) return { "LV2", Ids::lv2BinaryLocation }; + + return {}; + } + + static String generatePluginCopyStepPathValidatorScript (Target::Type targetType, + const MSVCBuildConfiguration& config, + Architecture arch) + { + MSVCScriptBuilder builder; + + if (config.isPluginBinaryCopyStepEnabled()) + { + const auto [projectTypeString, binaryLocationId] = getPluginTypeInfo (targetType); + + if (projectTypeString.isNotEmpty()) + { + const auto binaryPath = config.getBinaryPath (binaryLocationId, arch); + + if (binaryPath.isEmpty()) + { + String warningMessage = + "Plugin Configuration Warning: Plugin copy step is enabled but no target " + "path is specified in the Projucer."; + + warningMessage << " This can be configured via the \"" + << getArchitectureValueString (arch) << " " + << projectTypeString << " " + << "Binary Location\" option in the relevant Exporter configuration panel."; + + builder.warning (warningMessage.quoted()); + } + else + { + constexpr auto errorMessage = + "Plugin Copy Step Failure: Either the install path does not exist or you " + "do not have permission to write to the target directory. Ensure you " + "have the necessary permissions to write to the directory, or choose " + "a different install location (e.g., a folder in your user directory)."; + + MemoryOutputStream script; + + const auto validProjectName = build_tools::makeValidIdentifier (config.project.getProjectNameString(), + false, + true, + false, + false); + const auto validPluginName = build_tools::makeValidIdentifier (projectTypeString, + false, + true, + false, + false); + script << "set TOUCH_NAME=\".touch_\"" + << validProjectName << "_" + << validPluginName << "_" + << "\"%RANDOM%\"" << newLine; + + String tempPath = binaryPath; + tempPath << "\\%TOUCH_NAME%"; + + script << "(" << newLine; + script << "echo \".\" > " << tempPath.quoted() << newLine; + script << ") > nul 2>&1" << newLine; + + builder.append (script.toString()); + builder.ifelse ("exist " + tempPath.quoted(), + MSVCScriptBuilder{}.deleteFile (tempPath.quoted()), + MSVCScriptBuilder{}.error (String { errorMessage }.quoted()) + .exit (1)); + } + } + } + + return builder.build(); + } + + static String generateToolchainValidatorScript (Architecture arch) + { + MSVCScriptBuilder builder; + + if (arch == Architecture::win64) + { + const auto x86ToolchainErrorMessage = + "echo : Warning: Toolchain configuration issue!" + " You are using a 32-bit toolchain to compile a 64-bit target on a 64-bit system." + " This may cause problems with the build system." + " To resolve this, use the x64 version of MSBuild. You can invoke it directly at:" + " \"/MSBuild/Current/Bin/amd64/MSBuild.exe\"" + " Or, use the \"x64 Native Tools Command Prompt\" script."; + + builder.ifAllConditionsTrue ( + { + "\"$(PROCESSOR_ARCHITECTURE)\" == " + getVisualStudioArchitectureId (Architecture::win32).quoted(), + + // This only exists if the process is x86 but the host is x64. + "defined PROCESSOR_ARCHITEW6432" + }, MSVCScriptBuilder{}.append (x86ToolchainErrorMessage)); + } + + return builder.build(); + } + String getExtraPreBuildSteps (const MSVCBuildConfiguration& config, Architecture arch) const { const auto createBundleStructure = [&] (const StringArray& segments) @@ -1981,24 +2108,8 @@ public: MSVCScriptBuilder builder; - if (arch == Architecture::win64) - { - const auto x86ToolchainErrorMessage = - "echo : Warning: Toolchain configuration issue!" - " You are using a 32-bit toolchain to compile a 64-bit target on a 64-bit system." - " This may cause problems with the build system." - " To resolve this, use the x64 version of MSBuild. You can invoke it directly at:" - " \"/MSBuild/Current/Bin/amd64/MSBuild.exe\"" - " Or, use the \"x64 Native Tools Command Prompt\" script."; - - builder.ifAllConditionsTrue ( - { - "\"$(PROCESSOR_ARCHITECTURE)\" == " + getVisualStudioArchitectureId (Architecture::win32).quoted(), - - // This only exists if the process is x86 but the host is x64. - "defined PROCESSOR_ARCHITEW6432" - }, MSVCScriptBuilder{}.append (x86ToolchainErrorMessage)); - } + builder.append (generatePluginCopyStepPathValidatorScript (type, config, arch)); + builder.append (generateToolchainValidatorScript (arch)); if (type == LV2PlugIn) { @@ -2032,8 +2143,14 @@ public: return builder.build(); } + if (type == UnityPlugIn) + return builder.build(); + if (type == AAXPlugIn) - return createBundleStructure (getAaxBundleStructure (config, arch)); + return builder.build() + "\r\n" + createBundleStructure (getAaxBundleStructure (config, arch)); + + if (type == VSTPlugIn) + return builder.build(); if (type == VST3PlugIn) return builder.build() + "\r\n" + createBundleStructure (getVst3BundleStructure (config, arch)); diff --git a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj index 89e24bfe48..bc032216cc 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj +++ b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj @@ -994,6 +994,9 @@ true + + true + true @@ -1030,6 +1033,12 @@ true + + true + + + true + true diff --git a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters index d8f1ca5ba6..fd2d7021b8 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters +++ b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters @@ -1627,6 +1627,9 @@ JUCE Modules\juce_audio_processors\format_types + + JUCE Modules\juce_audio_processors\format_types + JUCE Modules\juce_audio_processors\format_types @@ -1663,6 +1666,12 @@ JUCE Modules\juce_audio_processors\processors + + JUCE Modules\juce_audio_processors\processors + + + JUCE Modules\juce_audio_processors\processors + JUCE Modules\juce_audio_processors\processors diff --git a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj index e2e9a20efa..7ce389fce8 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj +++ b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj @@ -994,6 +994,9 @@ true + + true + true @@ -1030,6 +1033,12 @@ true + + true + + + true + true diff --git a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters index 71723e8ef6..53a52ae934 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters +++ b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters @@ -1627,6 +1627,9 @@ JUCE Modules\juce_audio_processors\format_types + + JUCE Modules\juce_audio_processors\format_types + JUCE Modules\juce_audio_processors\format_types @@ -1663,6 +1666,12 @@ JUCE Modules\juce_audio_processors\processors + + JUCE Modules\juce_audio_processors\processors + + + JUCE Modules\juce_audio_processors\processors + JUCE Modules\juce_audio_processors\processors diff --git a/extras/UnitTestRunner/CMakeLists.txt b/extras/UnitTestRunner/CMakeLists.txt index 552cd7ac3b..fab649524d 100644 --- a/extras/UnitTestRunner/CMakeLists.txt +++ b/extras/UnitTestRunner/CMakeLists.txt @@ -37,6 +37,7 @@ juce_generate_juce_header(UnitTestRunner) target_sources(UnitTestRunner PRIVATE Source/Main.cpp) target_compile_definitions(UnitTestRunner PRIVATE + JUCE_PLUGINHOST_AU=1 JUCE_PLUGINHOST_LV2=1 JUCE_PLUGINHOST_VST3=1 JUCE_UNIT_TESTS=1 diff --git a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj index 0609dcef72..a13dd56b89 100644 --- a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj +++ b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj @@ -977,6 +977,9 @@ true + + true + true @@ -1013,6 +1016,12 @@ true + + true + + + true + true diff --git a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj.filters b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj.filters index c9b151cc71..01510cde16 100644 --- a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj.filters +++ b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj.filters @@ -1531,6 +1531,9 @@ JUCE Modules\juce_audio_processors\format_types + + JUCE Modules\juce_audio_processors\format_types + JUCE Modules\juce_audio_processors\format_types @@ -1567,6 +1570,12 @@ JUCE Modules\juce_audio_processors\processors + + JUCE Modules\juce_audio_processors\processors + + + JUCE Modules\juce_audio_processors\processors + JUCE Modules\juce_audio_processors\processors diff --git a/modules/juce_audio_plugin_client/juce_audio_plugin_client_AAX.cpp b/modules/juce_audio_plugin_client/juce_audio_plugin_client_AAX.cpp index 122fce805f..400b2a0813 100644 --- a/modules/juce_audio_plugin_client/juce_audio_plugin_client_AAX.cpp +++ b/modules/juce_audio_plugin_client/juce_audio_plugin_client_AAX.cpp @@ -2414,9 +2414,6 @@ namespace AAXClasses aaxInputFormat = aaxOutputFormat; #endif - if (processor.isMidiEffect()) - aaxInputFormat = aaxOutputFormat = AAX_eStemFormat_Mono; - check (desc.AddAudioIn (JUCEAlgorithmIDs::inputChannels)); check (desc.AddAudioOut (JUCEAlgorithmIDs::outputChannels)); @@ -2586,10 +2583,16 @@ namespace AAXClasses // MIDI effect plug-ins do not support any audio channels jassert (numInputBuses == 0 && numOutputBuses == 0); - if (auto* desc = descriptor.NewComponentDescriptor()) + for (const auto format : aaxFormats) { - createDescriptor (*desc, plugin->getBusesLayout(), *plugin, pluginIds, numMeters); - check (descriptor.AddComponent (desc)); + const auto channelSet = channelSetFromStemFormat (format, false); + const AudioProcessor::BusesLayout layout { { channelSet }, { channelSet } }; + + if (auto* desc = descriptor.NewComponentDescriptor()) + { + createDescriptor (*desc, layout, *plugin, pluginIds, numMeters); + check (descriptor.AddComponent (desc)); + } } } else diff --git a/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU_1.mm b/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU_1.mm index f577a20d45..755a1c9a58 100644 --- a/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU_1.mm +++ b/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU_1.mm @@ -172,7 +172,12 @@ public: channelInfo.add (info); } #else - channelInfo = AudioUnitHelpers::getAUChannelInfo (*juceFilter); + auto channelInfoSet = AudioUnitHelpers::getAUChannelInfo (*juceFilter); + channelInfo.resize ((int) channelInfoSet.size()); + std::transform (channelInfoSet.begin(), + channelInfoSet.end(), + channelInfo.begin(), + [] (auto x) { return x.makeChannelInfo(); }); #endif AddPropertyListener (kAudioUnitProperty_ContextName, auPropertyListenerDispatcher, this); diff --git a/modules/juce_audio_plugin_client/juce_audio_plugin_client_AUv3.mm b/modules/juce_audio_plugin_client/juce_audio_plugin_client_AUv3.mm index 2125f69d90..a03d1f1868 100644 --- a/modules/juce_audio_plugin_client/juce_audio_plugin_client_AUv3.mm +++ b/modules/juce_audio_plugin_client/juce_audio_plugin_client_AUv3.mm @@ -194,7 +194,13 @@ public: channelInfos.add (channelInfo); } #else - Array channelInfos = AudioUnitHelpers::getAUChannelInfo (processor); + auto channelInfoSet = AudioUnitHelpers::getAUChannelInfo (processor); + Array channelInfos; + channelInfos.resize ((int) channelInfoSet.size()); + std::transform (channelInfoSet.begin(), + channelInfoSet.end(), + channelInfos.begin(), + [] (auto x) { return x.makeChannelInfo(); }); #endif processor.setPlayHead (this); diff --git a/modules/juce_audio_processors/format_types/juce_AU_Shared.h b/modules/juce_audio_processors/format_types/juce_AU_Shared.h index b41e0b12cf..28b3cee3dd 100644 --- a/modules/juce_audio_processors/format_types/juce_AU_Shared.h +++ b/modules/juce_audio_processors/format_types/juce_AU_Shared.h @@ -32,6 +32,8 @@ ============================================================================== */ +#pragma once + /** @cond */ // This macro can be set if you need to override this internal name for some reason.. #ifndef JUCE_STATE_DICTIONARY_KEY @@ -357,7 +359,40 @@ struct AudioUnitHelpers return false; } - static Array getAUChannelInfo (const AudioProcessor& processor) + struct Channels + { + SInt16 ins, outs; + + std::pair makePair() const noexcept { return std::make_pair (ins, outs); } + AUChannelInfo makeChannelInfo() const noexcept { return { ins, outs }; } + + bool operator< (const Channels& other) const noexcept { return makePair() < other.makePair(); } + bool operator== (const Channels& other) const noexcept { return makePair() == other.makePair(); } + + // The 'standard' layout with the most channels defined is AudioChannelSet::create9point1point6(). + // This value should be updated if larger standard channel layouts are added in the future. + static constexpr auto maxNumChanToCheckFor = 16; + }; + + /* Removes non-wildcard layouts that are already included by other wildcard layouts. + */ + static void removeNonWildcardLayouts (std::set& layouts) + { + for (auto it = layouts.begin(); it != layouts.end();) + { + if ((it->ins != -1 && layouts.find ({ -1, it->outs }) != layouts.end()) + || (it->outs != -1 && layouts.find ({ it->ins, -1 }) != layouts.end())) + { + it = layouts.erase (it); + } + else + { + ++it; + } + } + } + + static std::set getAUChannelInfo (const AudioProcessor& processor) { #ifdef JucePlugin_AUMainType JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wfour-char-constants") @@ -366,140 +401,130 @@ struct AudioUnitHelpers // A MIDI effect requires an output bus in order to determine the sample rate. // No audio will be written to the output bus, so it can have any number of channels. // No input bus is required. - return { AUChannelInfo { 0, -1 } }; + return { Channels { 0, -1 } }; } JUCE_END_IGNORE_WARNINGS_GCC_LIKE #endif - Array channelInfo; + const auto defaultInputs = processor.getChannelCountOfBus (true, 0); + const auto defaultOutputs = processor.getChannelCountOfBus (false, 0); + const auto hasMainInputBus = (AudioUnitHelpers::getBusCountForWrapper (processor, true) > 0); + const auto hasMainOutputBus = (AudioUnitHelpers::getBusCountForWrapper (processor, false) > 0); - auto hasMainInputBus = (AudioUnitHelpers::getBusCountForWrapper (processor, true) > 0); - auto hasMainOutputBus = (AudioUnitHelpers::getBusCountForWrapper (processor, false) > 0); - - auto layout = processor.getBusesLayout(); - - // The 'standard' layout with the most channels defined is AudioChannelSet::create9point1point6(). - // This value should be updated if larger standard channel layouts are added in the future. - constexpr auto maxNumChanToCheckFor = 16; - - auto defaultInputs = processor.getChannelCountOfBus (true, 0); - auto defaultOutputs = processor.getChannelCountOfBus (false, 0); - - struct Channels - { - SInt16 ins, outs; - - std::pair makePair() const noexcept { return std::make_pair (ins, outs); } - - bool operator< (const Channels& other) const noexcept { return makePair() < other.makePair(); } - bool operator== (const Channels& other) const noexcept { return makePair() == other.makePair(); } - }; - - SortedSet supportedChannels; + std::set supportedChannels; // add the current configuration if (defaultInputs != 0 || defaultOutputs != 0) - supportedChannels.add ({ static_cast (defaultInputs), - static_cast (defaultOutputs) }); + supportedChannels.insert ({ static_cast (defaultInputs), + static_cast (defaultOutputs) }); - for (auto inChanNum = hasMainInputBus ? 1 : 0; inChanNum <= (hasMainInputBus ? maxNumChanToCheckFor : 0); ++inChanNum) + static const auto layoutsToTry = std::invoke ([&] { - auto inLayout = layout; + std::vector sets; - if (auto* inBus = processor.getBus (true, 0)) - if (! isNumberOfChannelsSupported (inBus, inChanNum, inLayout)) - continue; - - for (auto outChanNum = hasMainOutputBus ? 1 : 0; outChanNum <= (hasMainOutputBus ? maxNumChanToCheckFor : 0); ++outChanNum) + for (auto i = 1; i <= Channels::maxNumChanToCheckFor; ++i) { - auto outLayout = inLayout; + const auto setsWithSizeI = AudioChannelSet::channelSetsWithNumberOfChannels (i); + std::copy (setsWithSizeI.begin(), setsWithSizeI.end(), std::back_inserter (sets)); + } - if (auto* outBus = processor.getBus (false, 0)) - if (! isNumberOfChannelsSupported (outBus, outChanNum, outLayout)) - continue; + return sets; + }); - supportedChannels.add ({ static_cast (hasMainInputBus ? outLayout.getMainInputChannels() : 0), - static_cast (hasMainOutputBus ? outLayout.getMainOutputChannels() : 0) }); + std::vector inputHasOutputRestrictions (layoutsToTry.size()), outputHasInputRestrictions (layoutsToTry.size()); + + for (const auto [inputIndex, inputLayout] : enumerate (layoutsToTry)) + { + for (const auto [outputIndex, outputLayout] : enumerate (layoutsToTry)) + { + auto copy = processor.getBusesLayout(); + + if (! copy.inputBuses.isEmpty()) + copy.inputBuses.getReference (0) = inputLayout; + + if (! copy.outputBuses.isEmpty()) + copy.outputBuses.getReference (0) = outputLayout; + + if (processor.checkBusesLayoutSupported (copy)) + { + supportedChannels.insert ({ (SInt16) inputLayout.size(), (SInt16) outputLayout.size() }); + } + else + { + inputHasOutputRestrictions[(size_t) inputIndex] = true; + outputHasInputRestrictions[(size_t) outputIndex] = true; + } } } - auto hasInOutMismatch = false; + static constexpr auto identity = [] (auto x) { return x; }; + const auto noRestrictions = std::none_of (inputHasOutputRestrictions.begin(), inputHasOutputRestrictions.end(), identity) + && std::none_of (outputHasInputRestrictions.begin(), outputHasInputRestrictions.end(), identity); - for (const auto& supported : supportedChannels) + if (noRestrictions) { - if (supported.ins != supported.outs) + if (hasMainInputBus) { - hasInOutMismatch = true; - break; + if (hasMainOutputBus) + return { Channels { -1, -2 } }; + + return { Channels { -1, 0 } }; } + + return { Channels { 0, -1 } }; } - auto hasUnsupportedInput = ! hasMainInputBus, hasUnsupportedOutput = ! hasMainOutputBus; - - for (auto inChanNum = hasMainInputBus ? 1 : 0; inChanNum <= (hasMainInputBus ? maxNumChanToCheckFor : 0); ++inChanNum) + const auto allMatchedLayoutsExclusivelySupported = std::invoke ([&] { - Channels channelConfiguration { static_cast (inChanNum), - static_cast (hasInOutMismatch ? defaultOutputs : inChanNum) }; + for (SInt16 i = 1; i <= Channels::maxNumChanToCheckFor; ++i) + if (supportedChannels.find ({ i, i }) == supportedChannels.end()) + return false; - if (! supportedChannels.contains (channelConfiguration)) + return std::all_of (supportedChannels.begin(), supportedChannels.end(), [] (auto x) { return x.ins == x.outs; }); + }); + + if (allMatchedLayoutsExclusivelySupported) + return { Channels { -1, -1 } }; + + std::set filteredChannels; + + for (auto& c : supportedChannels) + { + const auto findDistance = [&] (auto channelCount) { - hasUnsupportedInput = true; - break; - } - } + return std::distance (layoutsToTry.begin(), + std::lower_bound (layoutsToTry.begin(), + layoutsToTry.end(), + channelCount, + [] (auto a, auto b) { return a.size() < b; })); + }; - for (auto outChanNum = hasMainOutputBus ? 1 : 0; outChanNum <= (hasMainOutputBus ? maxNumChanToCheckFor : 0); ++outChanNum) - { - Channels channelConfiguration { static_cast (hasInOutMismatch ? defaultInputs : outChanNum), - static_cast (outChanNum) }; - - if (! supportedChannels.contains (channelConfiguration)) + const auto findChannelCount = [&] (auto& restrictions, + auto thisChannelCount, + auto otherChannelCount, + auto hasMainBus) { - hasUnsupportedOutput = true; - break; - } + const auto lower = findDistance (otherChannelCount); + const auto upper = findDistance (otherChannelCount + 1); + + const auto wildcard = std::all_of (restrictions.begin() + lower, + restrictions.begin() + upper, + identity) + ? thisChannelCount + : (SInt16) -1; + return hasMainBus ? wildcard : (SInt16) 0; + }; + + const auto ins = findChannelCount (outputHasInputRestrictions, c.ins, c.outs, hasMainInputBus); + const auto outs = findChannelCount (inputHasOutputRestrictions, c.outs, c.ins, hasMainOutputBus); + + const Channels layout { ins, outs }; + filteredChannels.insert (layout == Channels { -1, -1 } ? c : layout); } - for (const auto& supported : supportedChannels) - { - AUChannelInfo info; + removeNonWildcardLayouts (filteredChannels); - // see here: https://developer.apple.com/library/mac/documentation/MusicAudio/Conceptual/AudioUnitProgrammingGuide/TheAudioUnit/TheAudioUnit.html - info.inChannels = static_cast (hasMainInputBus ? (hasUnsupportedInput ? supported.ins : (hasInOutMismatch && (! hasUnsupportedOutput) ? -2 : -1)) : 0); - info.outChannels = static_cast (hasMainOutputBus ? (hasUnsupportedOutput ? supported.outs : (hasInOutMismatch && (! hasUnsupportedInput) ? -2 : -1)) : 0); - - if (info.inChannels == -2 && info.outChannels == -2) - info.inChannels = -1; - - int j; - for (j = 0; j < channelInfo.size(); ++j) - if (info.inChannels == channelInfo.getReference (j).inChannels - && info.outChannels == channelInfo.getReference (j).outChannels) - break; - - if (j >= channelInfo.size()) - channelInfo.add (info); - } - - return channelInfo; - } - - static bool isNumberOfChannelsSupported (const AudioProcessor::Bus* b, int numChannels, AudioProcessor::BusesLayout& inOutCurrentLayout) - { - auto potentialSets = AudioChannelSet::channelSetsWithNumberOfChannels (static_cast (numChannels)); - - for (auto set : potentialSets) - { - auto copy = inOutCurrentLayout; - - if (b->isLayoutSupported (set, ©)) - { - inOutCurrentLayout = copy; - return true; - } - } - - return false; + return filteredChannels; } //============================================================================== diff --git a/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm b/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm index 546b61cee7..81820516c8 100644 --- a/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm +++ b/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm @@ -1417,11 +1417,22 @@ public: for (const auto metadata : midiMessages) { if (metadata.numBytes <= 3) + { + const auto getByteOrZero = [&metadata] (int index) + { + return index < metadata.numBytes ? metadata.data[index] : (uint8) 0; + }; + MusicDeviceMIDIEvent (audioUnit, - metadata.data[0], metadata.data[1], metadata.data[2], + getByteOrZero (0), + getByteOrZero (1), + getByteOrZero (2), (UInt32) metadata.samplePosition); + } else + { MusicDeviceSysEx (audioUnit, metadata.data, (UInt32) metadata.numBytes); + } } midiMessages.clear(); diff --git a/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat_test.cpp b/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat_test.cpp new file mode 100644 index 0000000000..b310be7278 --- /dev/null +++ b/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat_test.cpp @@ -0,0 +1,308 @@ +/* + ============================================================================== + + This file is part of the JUCE framework. + Copyright (c) Raw Material Software Limited + + JUCE is an open source framework subject to commercial or open source + licensing. + + By downloading, installing, or using the JUCE framework, or combining the + JUCE framework with any other source code, object code, content or any other + copyrightable work, you agree to the terms of the JUCE End User Licence + Agreement, and all incorporated terms including the JUCE Privacy Policy and + the JUCE Website Terms of Service, as applicable, which will bind you. If you + do not agree to the terms of these agreements, we will not license the JUCE + framework to you, and you must discontinue the installation or download + process and cease use of the JUCE framework. + + JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/ + JUCE Privacy Policy: https://juce.com/juce-privacy-policy + JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/ + + Or: + + You may also use this code under the terms of the AGPLv3: + https://www.gnu.org/licenses/agpl-3.0.en.html + + THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL + WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF + MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. + + ============================================================================== +*/ + +#include "juce_AU_Shared.h" + +namespace juce +{ + +class AudioUnitPluginFormatTests final : public UnitTest +{ +public: + AudioUnitPluginFormatTests() + : UnitTest ("AU Hosting", UnitTestCategories::audioProcessors) + { + } + + void runTest() override + { + beginTest ("Permissive audio processor produces layout [-1, -2]"); + { + struct ProcA : public MockAudioProcessor + { + ProcA() + : MockAudioProcessor (BusesProperties().withInput ("Input", AudioChannelSet::stereo()) + .withOutput ("Output", AudioChannelSet::stereo())) {} + + bool isBusesLayoutSupported (const BusesLayout&) const override + { + return true; + } + }; + + ProcA processor; + const auto layouts = AudioUnitHelpers::getAUChannelInfo (processor); + expect (layouts == std::set { AudioUnitHelpers::Channels { -1, -2 } }); + } + + beginTest ("Audio processor with matched I/O produces layout [-1, -1]"); + { + struct ProcB : public MockAudioProcessor + { + ProcB() + : MockAudioProcessor (BusesProperties().withInput ("Input", AudioChannelSet::stereo()) + .withOutput ("Output", AudioChannelSet::stereo())) {} + + bool isBusesLayoutSupported (const BusesLayout& l) const override + { + return l.getMainInputChannelSet() == l.getMainOutputChannelSet(); + } + }; + + ProcB processor; + const auto layouts = AudioUnitHelpers::getAUChannelInfo (processor); + expect (layouts == std::set { AudioUnitHelpers::Channels { -1, -1 } }); + } + + beginTest ("Audio processor that supports any input with a two-channel output produces layout [-1, 2]"); + { + struct ProcC : public MockAudioProcessor + { + ProcC() + : MockAudioProcessor (BusesProperties().withInput ("Input", AudioChannelSet::stereo()) + .withOutput ("Output", AudioChannelSet::stereo())) {} + + bool isBusesLayoutSupported (const BusesLayout& l) const override + { + return l.getMainOutputChannelSet() == AudioChannelSet::stereo(); + } + }; + + ProcC processor; + const auto layouts = AudioUnitHelpers::getAUChannelInfo (processor); + expect (layouts == std::set { AudioUnitHelpers::Channels { -1, 2 } }); + } + + beginTest ("Audio processor that supports any output with a 6-channel input produces layout [6, -1]"); + { + struct ProcD : public MockAudioProcessor + { + ProcD() + : MockAudioProcessor (BusesProperties().withInput ("Input", AudioChannelSet::create5point1()) + .withOutput ("Output", AudioChannelSet::create5point1())) {} + + bool isBusesLayoutSupported (const BusesLayout& l) const override + { + return l.getMainInputChannelSet() == AudioChannelSet::create5point1(); + } + }; + + ProcD processor; + const auto layouts = AudioUnitHelpers::getAUChannelInfo (processor); + expect (layouts == std::set { AudioUnitHelpers::Channels { 6, -1 } }); + } + + beginTest ("Audio processor that supports both above layouts produces [-1, 2] and [6, -1]"); + { + struct ProcE : public MockAudioProcessor + { + ProcE() + : MockAudioProcessor (BusesProperties().withInput ("Input", AudioChannelSet::create5point1()) + .withOutput ("Output", AudioChannelSet::stereo())) {} + + bool isBusesLayoutSupported (const BusesLayout& l) const override + { + return l.getMainOutputChannelSet() == AudioChannelSet::stereo() + || l.getMainInputChannelSet() == AudioChannelSet::create5point1(); + } + }; + + ProcE processor; + const auto layouts = AudioUnitHelpers::getAUChannelInfo (processor); + expect (layouts == std::set { AudioUnitHelpers::Channels { -1, 2 }, + AudioUnitHelpers::Channels { 6, -1 } }); + } + + beginTest ("Audio processor that supports only stereo and 5.1 produces [2, 2], [6, 6], [2, 6], and [6, 2]"); + { + struct ProcF : public MockAudioProcessor + { + ProcF() + : MockAudioProcessor (BusesProperties().withInput ("Input", AudioChannelSet::create5point1()) + .withOutput ("Output", AudioChannelSet::stereo())) {} + + bool isBusesLayoutSupported (const BusesLayout& l) const override + { + const std::array supported { AudioChannelSet::stereo(), AudioChannelSet::create5point1() }; + + return std::find (supported.begin(), supported.end(), l.getMainInputChannelSet()) != supported.end() + && std::find (supported.begin(), supported.end(), l.getMainOutputChannelSet()) != supported.end(); + } + }; + + ProcF processor; + const auto layouts = AudioUnitHelpers::getAUChannelInfo (processor); + expect (layouts == std::set { AudioUnitHelpers::Channels { 2, 2 }, + AudioUnitHelpers::Channels { 2, 6 }, + AudioUnitHelpers::Channels { 6, 2 }, + AudioUnitHelpers::Channels { 6, 6 } }); + } + + beginTest ("Complex layout is supported"); + { + struct ProcG : public MockAudioProcessor + { + ProcG() + : MockAudioProcessor (BusesProperties().withInput ("Input", AudioChannelSet::create9point1point6()) + .withOutput ("Output", AudioChannelSet::create9point1point6())) {} + + bool isBusesLayoutSupported (const BusesLayout& l) const override + { + using ACS = juce::AudioChannelSet; + + const auto input = l.getMainInputChannelSet(); + const auto output = l.getMainOutputChannelSet(); + + if (output == ACS::mono()) + return input == ACS::mono(); + + if (output == ACS::stereo()) + return input == ACS::mono() || input == ACS::stereo(); + + if (output == ACS::create9point1point6()) + { + return input == ACS::mono() + || input == ACS::stereo() + || input == ACS::createLCR() + || input == ACS::quadraphonic() + || input == ACS::create5point0() + || input == ACS::create5point1() + || input == ACS::create7point0() + || input == ACS::create7point1() + || input == ACS::create7point0point2() + || input == ACS::create5point1point4() + || input == ACS::create7point0point4() + || input == ACS::create7point1point4() + || input == ACS::create7point0point6() + || input == ACS::create7point1point6() + || input == ACS::create9point0point6() + || input == ACS::create9point1point6(); + } + + return false; + } + }; + + ProcG processor; + const auto layouts = AudioUnitHelpers::getAUChannelInfo (processor); + expect (layouts == std::set { AudioUnitHelpers::Channels { 1, 1 }, + AudioUnitHelpers::Channels { 1, 2 }, + AudioUnitHelpers::Channels { 2, 2 }, + AudioUnitHelpers::Channels { 1, 16 }, + AudioUnitHelpers::Channels { 2, 16 }, + AudioUnitHelpers::Channels { 3, 16 }, + AudioUnitHelpers::Channels { 4, 16 }, + AudioUnitHelpers::Channels { 5, 16 }, + AudioUnitHelpers::Channels { 6, 16 }, + AudioUnitHelpers::Channels { 7, 16 }, + AudioUnitHelpers::Channels { 8, 16 }, + AudioUnitHelpers::Channels { 9, 16 }, + AudioUnitHelpers::Channels { 10, 16 }, + AudioUnitHelpers::Channels { 11, 16 }, + AudioUnitHelpers::Channels { 12, 16 }, + AudioUnitHelpers::Channels { 13, 16 }, + AudioUnitHelpers::Channels { 14, 16 }, + AudioUnitHelpers::Channels { 15, 16 }, + AudioUnitHelpers::Channels { 16, 16 } }); + } + + beginTest ("Audio processor that supports only stereo out reports [0, 2]"); + { + struct ProcH : public MockAudioProcessor + { + ProcH() + : MockAudioProcessor (BusesProperties().withOutput ("Output", AudioChannelSet::stereo())) {} + + bool isBusesLayoutSupported (const BusesLayout& l) const override + { + return l.inputBuses.isEmpty() && l.getMainOutputChannelSet() == AudioChannelSet::stereo(); + } + }; + + ProcH processor; + const auto layouts = AudioUnitHelpers::getAUChannelInfo (processor); + expect (layouts == std::set { AudioUnitHelpers::Channels { 0, 2 } }); + } + + beginTest ("Audio processor that supports any out but no in reports [0, -1]"); + { + struct ProcI : public MockAudioProcessor + { + ProcI() + : MockAudioProcessor (BusesProperties().withOutput ("Output", AudioChannelSet::stereo())) {} + + bool isBusesLayoutSupported (const BusesLayout& l) const override + { + return l.inputBuses.isEmpty(); + } + }; + + ProcI processor; + const auto layouts = AudioUnitHelpers::getAUChannelInfo (processor); + expect (layouts == std::set { AudioUnitHelpers::Channels { 0, -1 } }); + } + } + +private: + struct MockAudioProcessor : public AudioProcessor + { + using AudioProcessor::AudioProcessor; + + const String getName() const override { return "Basic Processor"; } + double getTailLengthSeconds() const override { return {}; } + bool acceptsMidi() const override { return {}; } + bool producesMidi() const override { return {}; } + AudioProcessorEditor* createEditor() override { return {}; } + bool hasEditor() const override { return {}; } + int getNumPrograms() override { return 1; } + int getCurrentProgram() override { return {}; } + void setCurrentProgram (int) override {} + const String getProgramName (int) override { return {}; } + void changeProgramName (int, const String&) override {} + void getStateInformation (MemoryBlock&) override {} + void setStateInformation (const void*, int) override {} + void prepareToPlay (double, int) override {} + void releaseResources() override {} + bool supportsDoublePrecisionProcessing() const override { return {}; } + bool isMidiEffect() const override { return {}; } + void reset() override {} + void setNonRealtime (bool) noexcept override {} + void processBlock (AudioBuffer&, MidiBuffer&) override {} + using AudioProcessor::processBlock; + }; +}; + +static AudioUnitPluginFormatTests auPluginFormatTests; + +} // namespace juce diff --git a/modules/juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp b/modules/juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp index 977206dc07..2225dfeea0 100644 --- a/modules/juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp +++ b/modules/juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp @@ -40,29 +40,31 @@ JUCE_BEGIN_IGNORE_DEPRECATION_WARNINGS class LegacyAudioParameter final : public HostedAudioProcessorParameter { public: - LegacyAudioParameter (AudioProcessor& audioProcessorToUse, int audioParameterIndex) + LegacyAudioParameter (AudioProcessorParameter::Listener& listener, + AudioProcessor& audioProcessorToUse, + int audioParameterIndex) + : processor (&audioProcessorToUse) { - processor = &audioProcessorToUse; - - parameterIndex = audioParameterIndex; - jassert (parameterIndex < processor->getNumParameters()); + setOwner (&listener); + setParameterIndex (audioParameterIndex); + jassert (getParameterIndex() < processor->getNumParameters()); } //============================================================================== - float getValue() const override { return processor->getParameter (parameterIndex); } - void setValue (float newValue) override { processor->setParameter (parameterIndex, newValue); } - float getDefaultValue() const override { return processor->getParameterDefaultValue (parameterIndex); } - String getName (int maxLen) const override { return processor->getParameterName (parameterIndex, maxLen); } - String getLabel() const override { return processor->getParameterLabel (parameterIndex); } - int getNumSteps() const override { return processor->getParameterNumSteps (parameterIndex); } - bool isDiscrete() const override { return processor->isParameterDiscrete (parameterIndex); } + float getValue() const override { return processor->getParameter (getParameterIndex()); } + void setValue (float newValue) override { processor->setParameter (getParameterIndex(), newValue); } + float getDefaultValue() const override { return processor->getParameterDefaultValue (getParameterIndex()); } + String getName (int maxLen) const override { return processor->getParameterName (getParameterIndex(), maxLen); } + String getLabel() const override { return processor->getParameterLabel (getParameterIndex()); } + int getNumSteps() const override { return processor->getParameterNumSteps (getParameterIndex()); } + bool isDiscrete() const override { return processor->isParameterDiscrete (getParameterIndex()); } bool isBoolean() const override { return false; } - bool isOrientationInverted() const override { return processor->isParameterOrientationInverted (parameterIndex); } - bool isAutomatable() const override { return processor->isParameterAutomatable (parameterIndex); } - bool isMetaParameter() const override { return processor->isMetaParameter (parameterIndex); } - Category getCategory() const override { return processor->getParameterCategory (parameterIndex); } - String getCurrentValueAsText() const override { return processor->getParameterText (parameterIndex); } - String getParameterID() const override { return processor->getParameterID (parameterIndex); } + bool isOrientationInverted() const override { return processor->isParameterOrientationInverted (getParameterIndex()); } + bool isAutomatable() const override { return processor->isParameterAutomatable (getParameterIndex()); } + bool isMetaParameter() const override { return processor->isMetaParameter (getParameterIndex()); } + Category getCategory() const override { return processor->getParameterCategory (getParameterIndex()); } + String getCurrentValueAsText() const override { return processor->getParameterText (getParameterIndex()); } + String getParameterID() const override { return processor->getParameterID (getParameterIndex()); } //============================================================================== float getValueForText (const String&) const override @@ -85,22 +87,18 @@ public: return (dynamic_cast (param) != nullptr); } - static int getParamIndex (AudioProcessor& processor, AudioProcessorParameter* param) noexcept + static int getParamIndex (AudioProcessor& proc, AudioProcessorParameter* param) noexcept { if (auto* legacy = dynamic_cast (param)) - { - return legacy->parameterIndex; - } - else - { - auto n = processor.getNumParameters(); - jassert (n == processor.getParameters().size()); + return legacy->getParameterIndex(); - for (int i = 0; i < n; ++i) - { - if (processor.getParameters()[i] == param) - return i; - } + auto n = proc.getNumParameters(); + jassert (n == proc.getParameters().size()); + + for (int i = 0; i < n; ++i) + { + if (proc.getParameters()[i] == param) + return i; } return -1; @@ -109,7 +107,7 @@ public: static String getParamID (const AudioProcessorParameter* param, bool forceLegacyParamIDs) noexcept { if (auto* legacy = dynamic_cast (param)) - return forceLegacyParamIDs ? String (legacy->parameterIndex) : legacy->getParameterID(); + return forceLegacyParamIDs ? String (legacy->getParameterIndex()) : legacy->getParameterID(); if (auto* paramWithID = dynamic_cast (param)) { @@ -122,6 +120,9 @@ public: return {}; } + +private: + AudioProcessor* processor = nullptr; }; //============================================================================== @@ -139,6 +140,7 @@ public: { clear(); + forwarder = AudioProcessor::ParameterChangeForwarder { &audioProcessor }; legacyParamIDs = forceLegacyParamIDs; auto numParameters = audioProcessor.getNumParameters(); @@ -151,7 +153,7 @@ public: if (usingManagedParameters) return audioProcessor.getParameters()[i]; - auto newParam = std::make_unique (audioProcessor, i); + auto newParam = std::make_unique (forwarder, audioProcessor, i); auto* result = newParam.get(); ownedGroup.addChild (std::move (newParam)); @@ -167,6 +169,7 @@ public: void clear() { + forwarder = AudioProcessor::ParameterChangeForwarder { nullptr }; ownedGroup = AudioProcessorParameterGroup(); params.clear(); } @@ -215,6 +218,7 @@ private: const AudioProcessorParameterGroup* processorGroup = nullptr; AudioProcessorParameterGroup ownedGroup; Array params; + AudioProcessor::ParameterChangeForwarder forwarder { nullptr }; bool legacyParamIDs = false, usingManagedParameters = false; }; diff --git a/modules/juce_audio_processors/format_types/juce_VST3Headers.h b/modules/juce_audio_processors/format_types/juce_VST3Headers.h index 2ad8272a28..dc0f252432 100644 --- a/modules/juce_audio_processors/format_types/juce_VST3Headers.h +++ b/modules/juce_audio_processors/format_types/juce_VST3Headers.h @@ -246,7 +246,7 @@ JUCE_END_IGNORE_WARNINGS_MSVC JUCE_END_IGNORE_WARNINGS_GCC_LIKE //============================================================================== -#if JucePlugin_Enable_ARA +#if JucePlugin_Enable_ARA || JUCE_PLUGINHOST_ARA JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wpragma-pack") #include JUCE_END_IGNORE_WARNINGS_GCC_LIKE @@ -255,10 +255,12 @@ JUCE_END_IGNORE_WARNINGS_GCC_LIKE #error "Unsupported ARA version - only ARA version 2 and onward are supported by the current implementation" #endif - DEF_CLASS_IID (ARA::IPlugInEntryPoint) - DEF_CLASS_IID (ARA::IPlugInEntryPoint2) - DEF_CLASS_IID (ARA::IMainFactory) -#endif // JucePlugin_Enable_ARA + #if ! JUCE_VST3HEADERS_INCLUDE_HEADERS_ONLY + DEF_CLASS_IID (ARA::IPlugInEntryPoint) + DEF_CLASS_IID (ARA::IPlugInEntryPoint2) + DEF_CLASS_IID (ARA::IMainFactory) + #endif +#endif // JucePlugin_Enable_ARA || JUCE_PLUGINHOST_ARA //============================================================================== #if JUCE_WINDOWS diff --git a/modules/juce_audio_processors/juce_audio_processors.cpp b/modules/juce_audio_processors/juce_audio_processors.cpp index 20fdc86cfb..8819516eb1 100644 --- a/modules/juce_audio_processors/juce_audio_processors.cpp +++ b/modules/juce_audio_processors/juce_audio_processors.cpp @@ -184,7 +184,9 @@ private: #include "format/juce_AudioPluginFormat.cpp" #include "format/juce_AudioPluginFormatManager.cpp" #include "format_types/juce_LegacyAudioParameter.cpp" +#include "processors/juce_AudioProcessorParameter.cpp" #include "processors/juce_AudioProcessor.cpp" +#include "processors/juce_AudioProcessorListener.cpp" #include "processors/juce_AudioPluginInstance.cpp" #include "processors/juce_AudioProcessorEditor.cpp" #include "processors/juce_AudioProcessorGraph.cpp" @@ -221,6 +223,10 @@ private: #include "format_types/juce_VST3PluginFormat_test.cpp" #endif + #if JUCE_PLUGINHOST_AU && (JUCE_MAC || JUCE_IOS) + #include "format_types/juce_AudioUnitPluginFormat_test.cpp" + #endif + #if JUCE_PLUGINHOST_LV2 && (! (JUCE_ANDROID || JUCE_IOS)) #include "format_types/juce_LV2PluginFormat_test.cpp" #endif diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp b/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp index a28e46aa5e..26fdf35837 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp +++ b/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp @@ -521,8 +521,8 @@ void AudioProcessor::addParameter (AudioProcessorParameter* param) jassert (param != nullptr); parameterTree.addChild (std::unique_ptr (param)); - param->processor = this; - param->parameterIndex = flatParameterList.size(); + param->setOwner (¶meterListener); + param->setParameterIndex (flatParameterList.size()); flatParameterList.add (param); validateParameter (param); @@ -539,8 +539,8 @@ void AudioProcessor::addParameterGroup (std::unique_ptrprocessor = this; - p->parameterIndex = i; + p->setOwner (¶meterListener); + p->setParameterIndex (i); validateParameter (p); } @@ -566,8 +566,8 @@ void AudioProcessor::setParameterTree (AudioProcessorParameterGroup&& newTree) for (int i = 0; i < flatParameterList.size(); ++i) { auto p = flatParameterList.getUnchecked (i); - p->processor = this; - p->parameterIndex = i; + p->setOwner (¶meterListener); + p->setParameterIndex (i); validateParameter (p); } @@ -577,7 +577,7 @@ void AudioProcessor::refreshParameterList() {} int AudioProcessor::getDefaultNumParameterSteps() noexcept { - return 0x7fffffff; + return AudioProcessorParameter::getDefaultNumParameterSteps(); } void AudioProcessor::suspendProcessing (const bool shouldBeSuspended) @@ -1278,97 +1278,6 @@ VST3ClientExtensions* AudioProcessor::getVST3ClientExtensions() //============================================================================== JUCE_BEGIN_IGNORE_DEPRECATION_WARNINGS -void AudioProcessor::setParameterNotifyingHost (int parameterIndex, float newValue) -{ - if (auto* param = getParameters()[parameterIndex]) - { - param->setValueNotifyingHost (newValue); - } - else if (isPositiveAndBelow (parameterIndex, getNumParameters())) - { - setParameter (parameterIndex, newValue); - sendParamChangeMessageToListeners (parameterIndex, newValue); - } -} - -void AudioProcessor::sendParamChangeMessageToListeners (int parameterIndex, float newValue) -{ - if (auto* param = getParameters()[parameterIndex]) - { - param->sendValueChangedMessageToListeners (newValue); - } - else - { - if (isPositiveAndBelow (parameterIndex, getNumParameters())) - { - for (int i = listeners.size(); --i >= 0;) - if (auto* l = getListenerLocked (i)) - l->audioProcessorParameterChanged (this, parameterIndex, newValue); - } - else - { - jassertfalse; // called with an out-of-range parameter index! - } - } -} - -void AudioProcessor::beginParameterChangeGesture (int parameterIndex) -{ - if (auto* param = getParameters()[parameterIndex]) - { - param->beginChangeGesture(); - } - else - { - if (isPositiveAndBelow (parameterIndex, getNumParameters())) - { - #if JUCE_DEBUG && ! JUCE_DISABLE_AUDIOPROCESSOR_BEGIN_END_GESTURE_CHECKING - // This means you've called beginParameterChangeGesture twice in succession without a matching - // call to endParameterChangeGesture. That might be fine in most hosts, but better to avoid doing it. - jassert (! changingParams[parameterIndex]); - changingParams.setBit (parameterIndex); - #endif - - for (int i = listeners.size(); --i >= 0;) - if (auto* l = getListenerLocked (i)) - l->audioProcessorParameterChangeGestureBegin (this, parameterIndex); - } - else - { - jassertfalse; // called with an out-of-range parameter index! - } - } -} - -void AudioProcessor::endParameterChangeGesture (int parameterIndex) -{ - if (auto* param = getParameters()[parameterIndex]) - { - param->endChangeGesture(); - } - else - { - if (isPositiveAndBelow (parameterIndex, getNumParameters())) - { - #if JUCE_DEBUG && ! JUCE_DISABLE_AUDIOPROCESSOR_BEGIN_END_GESTURE_CHECKING - // This means you've called endParameterChangeGesture without having previously called - // beginParameterChangeGesture. That might be fine in most hosts, but better to keep the - // calls matched correctly. - jassert (changingParams[parameterIndex]); - changingParams.clearBit (parameterIndex); - #endif - - for (int i = listeners.size(); --i >= 0;) - if (auto* l = getListenerLocked (i)) - l->audioProcessorParameterChangeGestureEnd (this, parameterIndex); - } - else - { - jassertfalse; // called with an out-of-range parameter index! - } - } -} - String AudioProcessor::getParameterName (int index, int maximumStringLength) { if (auto* p = getParameters()[index]) @@ -1449,7 +1358,7 @@ int AudioProcessor::getParameterNumSteps (int index) if (auto* p = getParameters()[index]) return p->getNumSteps(); - return AudioProcessor::getDefaultNumParameterSteps(); + return getDefaultNumParameterSteps(); } bool AudioProcessor::isParameterDiscrete (int index) const @@ -1514,145 +1423,31 @@ AudioProcessorParameter* AudioProcessor::getParamChecked (int index) const bool AudioProcessor::canAddBus ([[maybe_unused]] bool isInput) const { return false; } bool AudioProcessor::canRemoveBus ([[maybe_unused]] bool isInput) const { return false; } +//============================================================================== +void AudioProcessor::ParameterChangeForwarder::parameterValueChanged (int index, float value) +{ + if (owner == nullptr) + return; + + for (int i = owner->listeners.size(); --i >= 0;) + if (auto* l = owner->listeners[i]) + l->audioProcessorParameterChanged (owner, index, value); +} + +void AudioProcessor::ParameterChangeForwarder::parameterGestureChanged (int index, bool begin) +{ + if (owner == nullptr) + return; + + const auto callback = begin + ? &AudioProcessorListener::audioProcessorParameterChangeGestureBegin + : &AudioProcessorListener::audioProcessorParameterChangeGestureEnd; + + for (int i = owner->listeners.size(); --i >= 0;) + if (auto* l = owner->listeners[i]) + (l->*callback) (owner, index); +} + JUCE_END_IGNORE_DEPRECATION_WARNINGS -//============================================================================== -void AudioProcessorListener::audioProcessorParameterChangeGestureBegin (AudioProcessor*, int) {} -void AudioProcessorListener::audioProcessorParameterChangeGestureEnd (AudioProcessor*, int) {} - -//============================================================================== -AudioProcessorParameter::~AudioProcessorParameter() -{ - #if JUCE_DEBUG && ! JUCE_DISABLE_AUDIOPROCESSOR_BEGIN_END_GESTURE_CHECKING - // This will fail if you've called beginChangeGesture() without having made - // a corresponding call to endChangeGesture... - jassert (! isPerformingGesture); - #endif -} - -void AudioProcessorParameter::setValueNotifyingHost (float newValue) -{ - setValue (newValue); - sendValueChangedMessageToListeners (newValue); -} - -void AudioProcessorParameter::beginChangeGesture() -{ - // This method can't be used until the parameter has been attached to a processor! - jassert (processor != nullptr && parameterIndex >= 0); - - #if JUCE_DEBUG && ! JUCE_DISABLE_AUDIOPROCESSOR_BEGIN_END_GESTURE_CHECKING - // This means you've called beginChangeGesture twice in succession without - // a matching call to endChangeGesture. That might be fine in most hosts, - // but it would be better to avoid doing it. - jassert (! isPerformingGesture); - isPerformingGesture = true; - #endif - - ScopedLock lock (listenerLock); - - for (int i = listeners.size(); --i >= 0;) - if (auto* l = listeners[i]) - l->parameterGestureChanged (getParameterIndex(), true); - - if (processor != nullptr && parameterIndex >= 0) - { - // audioProcessorParameterChangeGestureBegin callbacks will shortly be deprecated and - // this code will be removed. - for (int i = processor->listeners.size(); --i >= 0;) - if (auto* l = processor->listeners[i]) - l->audioProcessorParameterChangeGestureBegin (processor, getParameterIndex()); - } -} - -void AudioProcessorParameter::endChangeGesture() -{ - // This method can't be used until the parameter has been attached to a processor! - jassert (processor != nullptr && parameterIndex >= 0); - - #if JUCE_DEBUG && ! JUCE_DISABLE_AUDIOPROCESSOR_BEGIN_END_GESTURE_CHECKING - // This means you've called endChangeGesture without having previously - // called beginChangeGesture. That might be fine in most hosts, but it - // would be better to keep the calls matched correctly. - jassert (isPerformingGesture); - isPerformingGesture = false; - #endif - - ScopedLock lock (listenerLock); - - for (int i = listeners.size(); --i >= 0;) - if (auto* l = listeners[i]) - l->parameterGestureChanged (getParameterIndex(), false); - - if (processor != nullptr && parameterIndex >= 0) - { - // audioProcessorParameterChangeGestureEnd callbacks will shortly be deprecated and - // this code will be removed. - for (int i = processor->listeners.size(); --i >= 0;) - if (auto* l = processor->listeners[i]) - l->audioProcessorParameterChangeGestureEnd (processor, getParameterIndex()); - } -} - -void AudioProcessorParameter::sendValueChangedMessageToListeners (float newValue) -{ - ScopedLock lock (listenerLock); - - for (int i = listeners.size(); --i >= 0;) - if (auto* l = listeners [i]) - l->parameterValueChanged (getParameterIndex(), newValue); - - if (processor != nullptr && parameterIndex >= 0) - { - // audioProcessorParameterChanged callbacks will shortly be deprecated and - // this code will be removed. - for (int i = processor->listeners.size(); --i >= 0;) - if (auto* l = processor->listeners[i]) - l->audioProcessorParameterChanged (processor, getParameterIndex(), newValue); - } -} - -bool AudioProcessorParameter::isOrientationInverted() const { return false; } -bool AudioProcessorParameter::isAutomatable() const { return true; } -bool AudioProcessorParameter::isMetaParameter() const { return false; } -AudioProcessorParameter::Category AudioProcessorParameter::getCategory() const { return genericParameter; } -int AudioProcessorParameter::getNumSteps() const { return AudioProcessor::getDefaultNumParameterSteps(); } -bool AudioProcessorParameter::isDiscrete() const { return false; } -bool AudioProcessorParameter::isBoolean() const { return false; } - -String AudioProcessorParameter::getText (float value, int /*maximumStringLength*/) const -{ - return String (value, 2); -} - -String AudioProcessorParameter::getCurrentValueAsText() const -{ - return getText (getValue(), 1024); -} - -StringArray AudioProcessorParameter::getAllValueStrings() const -{ - if (isDiscrete() && valueStrings.isEmpty()) - { - auto maxIndex = getNumSteps() - 1; - - for (int i = 0; i < getNumSteps(); ++i) - valueStrings.add (getText ((float) i / (float) maxIndex, 1024)); - } - - return valueStrings; -} - -void AudioProcessorParameter::addListener (AudioProcessorParameter::Listener* newListener) -{ - const ScopedLock sl (listenerLock); - listeners.addIfNotAlreadyThere (newListener); -} - -void AudioProcessorParameter::removeListener (AudioProcessorParameter::Listener* listenerToRemove) -{ - const ScopedLock sl (listenerLock); - listeners.removeFirstMatchingValue (listenerToRemove); -} - } // namespace juce diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessor.h b/modules/juce_audio_processors/processors/juce_AudioProcessor.h index 00df5b2f7b..b7d8b633e0 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessor.h +++ b/modules/juce_audio_processors/processors/juce_AudioProcessor.h @@ -1483,9 +1483,6 @@ protected: /** @internal */ std::atomic playHead { nullptr }; - /** @internal */ - void sendParamChangeMessageToListeners (int parameterIndex, float newValue); - public: /** @cond */ // These methods are all deprecated in favour of using AudioProcessorParameter @@ -1506,9 +1503,6 @@ public: [[deprecated]] virtual bool isParameterAutomatable (int parameterIndex) const; [[deprecated]] virtual bool isMetaParameter (int parameterIndex) const; [[deprecated]] virtual AudioProcessorParameter::Category getParameterCategory (int parameterIndex) const; - [[deprecated]] void beginParameterChangeGesture (int parameterIndex); - [[deprecated]] void endParameterChangeGesture (int parameterIndex); - [[deprecated]] void setParameterNotifyingHost (int parameterIndex, float newValue); // These functions are deprecated: your audio processor can inform the host // on its bus and channel layouts and names using the AudioChannelSet and various bus classes. @@ -1522,6 +1516,31 @@ public: [[deprecated]] virtual bool isOutputChannelStereoPair (int index) const; /** @endcond */ + /** @internal + Used to convert new-style per-parameter callbacks into old-style processor-change + callbacks. + This type will be removed in the future! + */ + class ParameterChangeForwarder : public AudioProcessorParameter::Listener + { + public: + explicit ParameterChangeForwarder (AudioProcessor* o) : owner (o) {} + + ParameterChangeForwarder (const ParameterChangeForwarder& other) : owner (other.owner) {} + + ParameterChangeForwarder& operator= (const ParameterChangeForwarder& other) + { + owner = other.owner; + return *this; + } + + void parameterValueChanged (int, float) override; + void parameterGestureChanged (int, bool) override; + + private: + AudioProcessor* owner = nullptr; + }; + private: //============================================================================== struct InOutChannelPair @@ -1594,6 +1613,8 @@ private: AudioProcessorParameterGroup parameterTree; Array flatParameterList; + ParameterChangeForwarder parameterListener { this }; + AudioProcessorParameter* getParamChecked (int) const; #if JUCE_DEBUG @@ -1621,7 +1642,6 @@ private: template void processBypassed (AudioBuffer&, MidiBuffer&); - friend class AudioProcessorParameter; friend class LADSPAPluginInstance; [[deprecated ("This method is no longer used - you can delete it from your AudioProcessor classes.")]] diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.h b/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.h index 85f52cd264..e194b0ef6c 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.h +++ b/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.h @@ -36,6 +36,7 @@ namespace juce { class AudioProcessorEditorListener; +class AudioProcessor; //============================================================================== /** diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessorListener.cpp b/modules/juce_audio_processors/processors/juce_AudioProcessorListener.cpp new file mode 100644 index 0000000000..744f250c37 --- /dev/null +++ b/modules/juce_audio_processors/processors/juce_AudioProcessorListener.cpp @@ -0,0 +1,41 @@ +/* + ============================================================================== + + This file is part of the JUCE framework. + Copyright (c) Raw Material Software Limited + + JUCE is an open source framework subject to commercial or open source + licensing. + + By downloading, installing, or using the JUCE framework, or combining the + JUCE framework with any other source code, object code, content or any other + copyrightable work, you agree to the terms of the JUCE End User Licence + Agreement, and all incorporated terms including the JUCE Privacy Policy and + the JUCE Website Terms of Service, as applicable, which will bind you. If you + do not agree to the terms of these agreements, we will not license the JUCE + framework to you, and you must discontinue the installation or download + process and cease use of the JUCE framework. + + JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/ + JUCE Privacy Policy: https://juce.com/juce-privacy-policy + JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/ + + Or: + + You may also use this code under the terms of the AGPLv3: + https://www.gnu.org/licenses/agpl-3.0.en.html + + THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL + WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF + MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ + +void AudioProcessorListener::audioProcessorParameterChangeGestureBegin (AudioProcessor*, int) {} +void AudioProcessorListener::audioProcessorParameterChangeGestureEnd (AudioProcessor*, int) {} + +} // namespace juce diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.cpp b/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.cpp new file mode 100644 index 0000000000..1221281a0a --- /dev/null +++ b/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.cpp @@ -0,0 +1,171 @@ +/* + ============================================================================== + + This file is part of the JUCE framework. + Copyright (c) Raw Material Software Limited + + JUCE is an open source framework subject to commercial or open source + licensing. + + By downloading, installing, or using the JUCE framework, or combining the + JUCE framework with any other source code, object code, content or any other + copyrightable work, you agree to the terms of the JUCE End User Licence + Agreement, and all incorporated terms including the JUCE Privacy Policy and + the JUCE Website Terms of Service, as applicable, which will bind you. If you + do not agree to the terms of these agreements, we will not license the JUCE + framework to you, and you must discontinue the installation or download + process and cease use of the JUCE framework. + + JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/ + JUCE Privacy Policy: https://juce.com/juce-privacy-policy + JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/ + + Or: + + You may also use this code under the terms of the AGPLv3: + https://www.gnu.org/licenses/agpl-3.0.en.html + + THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL + WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF + MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. + + ============================================================================== +*/ + +namespace juce +{ + +AudioProcessorParameter::~AudioProcessorParameter() +{ + #if JUCE_DEBUG && ! JUCE_DISABLE_AUDIOPROCESSOR_BEGIN_END_GESTURE_CHECKING + // This will fail if you've called beginChangeGesture() without having made + // a corresponding call to endChangeGesture... + jassert (! isPerformingGesture); + #endif +} + +void AudioProcessorParameter::setParameterIndex (int index) noexcept +{ + jassert (parameterIndex < 0 && 0 <= index); + parameterIndex = index; +} + +void AudioProcessorParameter::setOwner (Listener* listenerIn) noexcept +{ + jassert (finalListener == nullptr); + finalListener = listenerIn; +} + +void AudioProcessorParameter::setValueNotifyingHost (float newValue) +{ + setValue (newValue); + sendValueChangedMessageToListeners (newValue); +} + +void AudioProcessorParameter::beginChangeGesture() +{ + // This method can't be used until the parameter has been attached to a processor! + jassert (parameterIndex >= 0); + + #if JUCE_DEBUG && ! JUCE_DISABLE_AUDIOPROCESSOR_BEGIN_END_GESTURE_CHECKING + // This means you've called beginChangeGesture twice in succession without + // a matching call to endChangeGesture. That might be fine in most hosts, + // but it would be better to avoid doing it. + jassert (! isPerformingGesture); + isPerformingGesture = true; + #endif + + ScopedLock lock (listenerLock); + + for (int i = listeners.size(); --i >= 0;) + if (auto* l = listeners[i]) + l->parameterGestureChanged (getParameterIndex(), true); + + if (finalListener != nullptr) + finalListener->parameterGestureChanged (getParameterIndex(), true); +} + +void AudioProcessorParameter::endChangeGesture() +{ + // This method can't be used until the parameter has been attached to a processor! + jassert (parameterIndex >= 0); + + #if JUCE_DEBUG && ! JUCE_DISABLE_AUDIOPROCESSOR_BEGIN_END_GESTURE_CHECKING + // This means you've called endChangeGesture without having previously + // called beginChangeGesture. That might be fine in most hosts, but it + // would be better to keep the calls matched correctly. + jassert (isPerformingGesture); + isPerformingGesture = false; + #endif + + ScopedLock lock (listenerLock); + + for (int i = listeners.size(); --i >= 0;) + if (auto* l = listeners[i]) + l->parameterGestureChanged (getParameterIndex(), false); + + if (finalListener != nullptr) + finalListener->parameterGestureChanged (getParameterIndex(), false); +} + +void AudioProcessorParameter::sendValueChangedMessageToListeners (float newValue) +{ + ScopedLock lock (listenerLock); + + for (int i = listeners.size(); --i >= 0;) + if (auto* l = listeners [i]) + l->parameterValueChanged (getParameterIndex(), newValue); + + if (finalListener != nullptr) + finalListener->parameterValueChanged (getParameterIndex(), newValue); +} + +bool AudioProcessorParameter::isOrientationInverted() const { return false; } +bool AudioProcessorParameter::isAutomatable() const { return true; } +bool AudioProcessorParameter::isMetaParameter() const { return false; } +AudioProcessorParameter::Category AudioProcessorParameter::getCategory() const { return genericParameter; } +int AudioProcessorParameter::getNumSteps() const { return getDefaultNumParameterSteps(); } +bool AudioProcessorParameter::isDiscrete() const { return false; } +bool AudioProcessorParameter::isBoolean() const { return false; } + +String AudioProcessorParameter::getText (float value, int /*maximumStringLength*/) const +{ + return String (value, 2); +} + +String AudioProcessorParameter::getCurrentValueAsText() const +{ + return getText (getValue(), 1024); +} + +StringArray AudioProcessorParameter::getAllValueStrings() const +{ + if (isDiscrete() && valueStrings.isEmpty()) + { + auto maxIndex = getNumSteps() - 1; + + for (int i = 0; i < getNumSteps(); ++i) + valueStrings.add (getText ((float) i / (float) maxIndex, 1024)); + } + + return valueStrings; +} + +void AudioProcessorParameter::addListener (AudioProcessorParameter::Listener* newListener) +{ + const ScopedLock sl (listenerLock); + listeners.addIfNotAlreadyThere (newListener); +} + +void AudioProcessorParameter::removeListener (AudioProcessorParameter::Listener* listenerToRemove) +{ + const ScopedLock sl (listenerLock); + listeners.removeFirstMatchingValue (listenerToRemove); +} + +int AudioProcessorParameter::getDefaultNumParameterSteps() noexcept +{ + return 0x7fffffff; +} + +} // namespace juce diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h b/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h index 7978246366..4790d0a271 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h +++ b/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h @@ -35,8 +35,6 @@ namespace juce { -class AudioProcessor; - //============================================================================== /** An abstract base class for parameter objects that can be added to an AudioProcessor. @@ -173,7 +171,7 @@ public: /** Returns the number of steps that this parameter's range should be quantised into. If you want a continuous range of values, don't override this method, and allow - the default implementation to return AudioProcessor::getDefaultNumParameterSteps(). + the default implementation to return getDefaultNumParameterSteps(). If your parameter is boolean, then you may want to make this return 2. @@ -262,6 +260,12 @@ public: /** Returns the index of this parameter in its parent processor's parameter list. */ int getParameterIndex() const noexcept { return parameterIndex; } + /** @internal + This should only be called by the owner of the parameter after it has been added to + a processor. Do not call this function; changing the parameter index *will* break things! + */ + void setParameterIndex (int) noexcept; + //============================================================================== /** Returns the current value of the parameter as a String. @@ -332,6 +336,12 @@ public: virtual void parameterGestureChanged (int parameterIndex, bool gestureIsStarting) = 0; }; + /** @internal + This should only be called by the owner of the parameter after it has been added to + a processor. Do not call this function; changing the owner *will* break things! + */ + void setOwner (Listener* listener) noexcept; + /** Registers a listener to receive events when the parameter's state changes. If the listener is already registered, this will not register it again. @@ -349,15 +359,22 @@ public: /** @internal */ void sendValueChangedMessageToListeners (float newValue); + /** Returns the default number of steps for a parameter. + + NOTE! This method is deprecated! It's recommended that you use + AudioProcessorParameter::getNumSteps() instead. + + @see getParameterNumSteps + */ + static int getDefaultNumParameterSteps() noexcept; + private: //============================================================================== - friend class AudioProcessor; - friend class LegacyAudioParameter; - AudioProcessor* processor = nullptr; int parameterIndex = -1; int version = 0; CriticalSection listenerLock; Array listeners; + Listener* finalListener = nullptr; mutable StringArray valueStrings; #if JUCE_DEBUG diff --git a/modules/juce_audio_processors/utilities/juce_RangedAudioParameter.cpp b/modules/juce_audio_processors/utilities/juce_RangedAudioParameter.cpp index 645961ce1e..57a9eeb4ca 100644 --- a/modules/juce_audio_processors/utilities/juce_RangedAudioParameter.cpp +++ b/modules/juce_audio_processors/utilities/juce_RangedAudioParameter.cpp @@ -42,7 +42,7 @@ int RangedAudioParameter::getNumSteps() const if (range.interval > 0) return (static_cast ((range.end - range.start) / range.interval) + 1); - return AudioProcessor::getDefaultNumParameterSteps(); + return getDefaultNumParameterSteps(); } float RangedAudioParameter::convertTo0to1 (float v) const noexcept diff --git a/modules/juce_core/native/java/app/com/rmsl/juce/JuceActivityCallbacksBase.java b/modules/juce_core/native/java/app/com/rmsl/juce/JuceActivityCallbacksBase.java new file mode 100644 index 0000000000..1792c41c81 --- /dev/null +++ b/modules/juce_core/native/java/app/com/rmsl/juce/JuceActivityCallbacksBase.java @@ -0,0 +1,63 @@ +/* + ============================================================================== + + This file is part of the JUCE framework. + Copyright (c) Raw Material Software Limited + + JUCE is an open source framework subject to commercial or open source + licensing. + + By downloading, installing, or using the JUCE framework, or combining the + JUCE framework with any other source code, object code, content or any other + copyrightable work, you agree to the terms of the JUCE End User Licence + Agreement, and all incorporated terms including the JUCE Privacy Policy and + the JUCE Website Terms of Service, as applicable, which will bind you. If you + do not agree to the terms of these agreements, we will not license the JUCE + framework to you, and you must discontinue the installation or download + process and cease use of the JUCE framework. + + JUCE End User Licence Agreement: https://juce.com/legal/juce-8-licence/ + JUCE Privacy Policy: https://juce.com/juce-privacy-policy + JUCE Website Terms of Service: https://juce.com/juce-website-terms-of-service/ + + Or: + + You may also use this code under the terms of the AGPLv3: + https://www.gnu.org/licenses/agpl-3.0.en.html + + THE JUCE FRAMEWORK IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL + WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF + MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. + + ============================================================================== +*/ + +package com.rmsl.juce; + +import android.app.Activity; +import android.app.Application; +import android.os.Bundle; + +public class JuceActivityCallbacksBase implements Application.ActivityLifecycleCallbacks +{ + @Override + public void onActivityCreated (Activity activity, Bundle savedInstanceState) {} + + @Override + public void onActivityStarted (Activity activity) {} + + @Override + public void onActivityResumed (Activity activity) {} + + @Override + public void onActivityPaused (Activity activity) {} + + @Override + public void onActivityStopped (Activity activity) {} + + @Override + public void onActivitySaveInstanceState (Activity activity, Bundle outState) {} + + @Override + public void onActivityDestroyed (Activity activity) {} +} diff --git a/modules/juce_core/native/java/app/com/rmsl/juce/JuceInvocationHandler.java b/modules/juce_core/native/java/app/com/rmsl/juce/JuceInvocationHandler.java index 919b5a32f8..503bbc0351 100644 --- a/modules/juce_core/native/java/app/com/rmsl/juce/JuceInvocationHandler.java +++ b/modules/juce_core/native/java/app/com/rmsl/juce/JuceInvocationHandler.java @@ -38,35 +38,35 @@ import java.lang.reflect.*; public class JuceInvocationHandler implements InvocationHandler { - public JuceInvocationHandler (long nativeContextRef) - { - nativeContext = nativeContextRef; - } + public JuceInvocationHandler (long nativeContextRef) + { + nativeContext = nativeContextRef; + } - public void clear() - { - nativeContext = 0; - } + public void clear() + { + nativeContext = 0; + } - @Override - public void finalize() - { - if (nativeContext != 0) - dispatchFinalize (nativeContext); - } + @Override + public void finalize() + { + if (nativeContext != 0) + dispatchFinalize (nativeContext); + } - @Override - public Object invoke (Object proxy, Method method, Object[] args) throws Throwable - { - if (nativeContext != 0) - return dispatchInvoke (nativeContext, proxy, method, args); + @Override + public Object invoke (Object proxy, Method method, Object[] args) throws Throwable + { + if (nativeContext != 0) + return dispatchInvoke (nativeContext, proxy, method, args); - return null; - } + return null; + } - //============================================================================== - private long nativeContext = 0; + //============================================================================== + private long nativeContext = 0; - private native void dispatchFinalize (long nativeContextRef); - private native Object dispatchInvoke (long nativeContextRef, Object proxy, Method method, Object[] args); + private native void dispatchFinalize (long nativeContextRef); + private native Object dispatchInvoke (long nativeContextRef, Object proxy, Method method, Object[] args); } diff --git a/modules/juce_core/native/juce_JNIHelpers_android.cpp b/modules/juce_core/native/juce_JNIHelpers_android.cpp index d8f0a13331..810b88ba44 100644 --- a/modules/juce_core/native/juce_JNIHelpers_android.cpp +++ b/modules/juce_core/native/juce_JNIHelpers_android.cpp @@ -36,29 +36,142 @@ namespace juce { //============================================================================== -static const uint8 invocationHandleByteCode[] = -{31,139,8,8,215,115,161,94,0,3,105,110,118,111,99,97,116,105,111,110,72,97,110,100,108,101,66,121,116,101,67,111,100,101,46, -100,101,120,0,109,148,65,107,19,65,20,199,223,236,78,146,90,211,116,77,141,214,88,33,151,130,7,117,91,172,80,73,17,161,32,53,93, -17,108,233,65,5,217,38,155,102,219,237,110,220,108,99,172,8,173,40,42,244,36,245,226,65,232,165,138,7,15,226,65,193,147,120,244, -166,130,95,192,155,23,189,21,68,252,207,206,180,137,218,133,223,204,155,247,222,206,123,111,119,230,85,156,86,247,208,201, -83,84,121,127,155,63,122,245,209,24,205,141,63,156,124,186,176,229,110,12,151,158,157,126,219,76,39,136,234,68,212,154,25,201, -146,122,38,56,81,158,164,126,15,248,10,160,162,95,128,129,99,24,82,152,71,152,92,123,24,86,116,162,53,204,203,26,209,29,112, -15,108,128,231,224,37,248,2,126,128,4,252,6,192,56,184,6,102,65,21,220,2,171,224,1,120,2,94,128,215,224,29,248,0,62,129,111,224, -59,248,169,203,184,72,157,146,36,115,233,82,185,118,131,189,160,7,232,138,171,154,204,95,200,53,77,218,83,170,214,180,146, -35,77,238,153,139,107,212,99,27,35,141,122,213,218,80,181,239,83,250,108,60,51,234,139,247,213,148,191,68,188,61,13,149,208,142, -97,24,228,180,99,63,194,69,206,122,44,111,233,50,223,186,33,52,7,32,93,30,2,35,68,25,229,1,95,46,235,140,173,5,97,17,107,153, -97,154,203,245,212,89,216,17,103,24,33,71,81,141,88,215,135,52,226,44,131,90,121,252,141,250,184,172,109,170,222,233,219,67,83, -33,234,191,158,186,155,122,156,218,108,38,69,212,52,106,204,210,209,223,180,243,48,53,139,60,214,88,251,219,203,178,116,236, -223,165,190,117,50,254,15,42,243,49,215,119,163,51,196,74,148,47,45,149,157,243,126,51,40,219,145,27,248,19,182,95,241,156,240, -196,188,221,180,41,97,149,44,203,34,110,137,113,208,42,7,139,102,184,216,240,204,121,188,98,238,250,94,145,242,86,197,246,154, -238,130,105,251,126,16,197,54,115,186,22,6,55,26,69,202,90,98,91,211,179,253,57,243,226,236,188,83,142,138,148,235,208,197,126, -246,172,231,20,17,173,173,14,157,170,7,95,115,215,104,255,187,93,112,162,90,80,41,18,155,33,109,166,68,125,87,118,137,202,237, -112,174,65,137,178,231,216,33,25,21,183,81,183,163,114,237,156,235,219,158,187,236,80,102,91,35,66,46,56,212,85,221,182,36,93, -169,73,46,198,81,168,199,71,66,77,103,60,240,35,167,21,145,241,215,242,146,83,165,68,61,12,90,55,137,71,53,23,1,155,182,183, -132,237,216,193,84,70,203,23,181,185,210,113,156,146,84,102,146,246,99,188,127,153,14,235,253,185,94,72,155,164,105,236,208,0, -235,231,196,116,113,134,87,87,248,186,174,225,246,50,1,123,163,235,236,179,206,216,138,248,207,198,63,103,65,204,219,61,66,235, -232,19,122,71,175,224,29,253,34,65,237,158,145,164,118,223,208,13,41,199,231,170,32,223,89,23,62,5,169,23,247,135,25,82,31,223, -169,130,140,43,250,140,174,252,197,61,226,133,246,253,34,37,15,170,196,133,44,122,218,31,165,24,139,249,12,5,0,0,0,0}; +constexpr uint8 invocationHandleByteCode[] +{ + 0x1f, 0x8b, 0x08, 0x08, 0xa2, 0x70, 0x87, 0x68, 0x00, 0x03, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x65, 0x73, 0x2e, 0x64, 0x65, 0x78, 0x00, 0x6d, 0x94, + 0xbd, 0x6f, 0xd3, 0x40, 0x14, 0xc0, 0xdf, 0x9d, 0x9d, 0xa4, 0x94, 0x12, + 0xd2, 0x0f, 0x10, 0x2a, 0x1d, 0x2a, 0x0b, 0x18, 0x50, 0xd2, 0x38, 0x25, + 0x90, 0xa4, 0x29, 0x15, 0x12, 0x88, 0x8f, 0xca, 0x80, 0x44, 0xab, 0x0e, + 0x05, 0x24, 0x2e, 0xf6, 0x85, 0xb8, 0x75, 0xec, 0x28, 0x4e, 0x43, 0xf8, + 0xaa, 0x0a, 0x42, 0x65, 0xab, 0x58, 0x3a, 0x30, 0x20, 0x18, 0x58, 0x91, + 0x18, 0xf8, 0x03, 0x90, 0x58, 0x40, 0x0c, 0xc0, 0xc6, 0x00, 0x13, 0x6c, + 0x74, 0x64, 0x64, 0xe0, 0x9d, 0xef, 0x4a, 0x22, 0x51, 0x4b, 0xbf, 0xbb, + 0xe7, 0xf7, 0xde, 0xbd, 0xf7, 0xee, 0xec, 0x7b, 0x0e, 0xef, 0xf4, 0x9b, + 0xc7, 0x0a, 0xf0, 0xf0, 0xfb, 0xa7, 0x8d, 0xb7, 0x9b, 0xe6, 0x6b, 0x72, + 0xee, 0xe9, 0x97, 0xe1, 0x1f, 0xfe, 0xe6, 0xc7, 0x5f, 0x3f, 0x7f, 0x7f, + 0x7b, 0xf1, 0x31, 0x98, 0x8f, 0x01, 0x34, 0x00, 0xa0, 0xb3, 0x90, 0x1f, + 0x02, 0xf5, 0x3c, 0xd1, 0x01, 0xf6, 0x83, 0xd4, 0xef, 0x42, 0xde, 0x23, + 0xa8, 0x82, 0x2d, 0x84, 0x20, 0x63, 0x38, 0x24, 0x70, 0x3e, 0x44, 0xe4, + 0xfb, 0x35, 0x1c, 0xbe, 0x6a, 0x00, 0xf7, 0x70, 0xbe, 0x42, 0x01, 0x16, + 0x91, 0xeb, 0xc8, 0x6d, 0x64, 0x0d, 0x59, 0x47, 0x5e, 0x21, 0x1f, 0x90, + 0xef, 0xc8, 0x6f, 0xe4, 0x20, 0xfa, 0x17, 0x90, 0x29, 0x64, 0x06, 0x99, + 0x43, 0x16, 0x11, 0x4f, 0xc4, 0x41, 0xd6, 0x91, 0x0d, 0xe4, 0x19, 0xf2, + 0x52, 0x93, 0x79, 0xb0, 0x54, 0x88, 0x83, 0xcc, 0xdd, 0xa7, 0x6a, 0xeb, + 0x47, 0x76, 0x23, 0x7b, 0x10, 0x4d, 0x91, 0xa7, 0xb2, 0x5e, 0x21, 0x9f, + 0xa2, 0xd2, 0x9e, 0x50, 0x7b, 0x1b, 0x50, 0xb2, 0x45, 0x65, 0xcc, 0xe1, + 0x68, 0x4f, 0x5a, 0x64, 0x23, 0x40, 0x21, 0xa9, 0xde, 0xf7, 0xaa, 0xbd, + 0xa6, 0x94, 0x7e, 0x30, 0x9a, 0x09, 0x0c, 0x45, 0x71, 0xa9, 0xf2, 0x97, + 0x88, 0xd5, 0x69, 0x54, 0x09, 0x6d, 0x07, 0x13, 0x5f, 0xd2, 0x65, 0xae, + 0x7e, 0xac, 0x42, 0xd4, 0x3b, 0x42, 0x65, 0x9e, 0x39, 0x86, 0xe7, 0x8a, + 0xce, 0x39, 0x20, 0x5a, 0x11, 0xab, 0x4a, 0xdc, 0x48, 0x84, 0x89, 0x47, + 0x89, 0xcd, 0x76, 0x5c, 0x44, 0x18, 0x48, 0x0c, 0x26, 0x86, 0x10, 0x11, + 0x4f, 0x93, 0xe7, 0x4c, 0xe5, 0x7e, 0x1b, 0x29, 0x31, 0x2e, 0xa2, 0x2a, + 0xa9, 0x2c, 0x00, 0x06, 0x95, 0xe7, 0x21, 0xbe, 0xd3, 0xe2, 0x38, 0x44, + 0x75, 0xc7, 0xd4, 0x4e, 0x8e, 0x50, 0xb9, 0xcf, 0xb9, 0x53, 0x68, 0x47, + 0x39, 0x47, 0x81, 0x16, 0x69, 0x0c, 0x1a, 0x26, 0x05, 0x9d, 0x24, 0xe1, + 0xa4, 0x70, 0x4a, 0xbe, 0x83, 0xa3, 0x04, 0x92, 0xd3, 0x60, 0x42, 0x1a, + 0x4e, 0x40, 0xf2, 0x71, 0xf7, 0x8c, 0x65, 0xf9, 0x1a, 0xe6, 0xee, 0x53, + 0x67, 0x1a, 0x8f, 0xce, 0x5b, 0x66, 0x8e, 0x4f, 0xbb, 0xbe, 0xdb, 0x9a, + 0x01, 0x32, 0x0b, 0xa3, 0xb3, 0x2b, 0x36, 0xbf, 0xe0, 0xb7, 0x03, 0x9b, + 0xb5, 0xdc, 0xc0, 0x3f, 0xcf, 0x7c, 0xc7, 0xe3, 0xcd, 0x89, 0x25, 0xd6, + 0x66, 0x10, 0xb3, 0x66, 0x2d, 0xcb, 0x02, 0xdd, 0x12, 0xe3, 0x61, 0xcb, + 0x0e, 0xea, 0xd9, 0x66, 0x3d, 0xf4, 0xb2, 0x4b, 0xb8, 0x24, 0xbb, 0xe3, + 0xba, 0x32, 0x8c, 0x5a, 0x0e, 0xf3, 0xda, 0xee, 0x72, 0x96, 0xf9, 0x7e, + 0xd0, 0x8a, 0x6c, 0xd9, 0xf9, 0x5a, 0x33, 0xb8, 0x15, 0x96, 0x61, 0xc8, + 0x12, 0x61, 0xb3, 0x1e, 0xf3, 0x6f, 0x66, 0x2f, 0x57, 0x96, 0xb8, 0xdd, + 0x2a, 0xc3, 0xbe, 0x1e, 0x5d, 0xe4, 0xc7, 0x2a, 0x1e, 0x2f, 0x63, 0xb6, + 0xae, 0xba, 0xc9, 0xab, 0x1e, 0xfa, 0x66, 0x77, 0xcc, 0xf6, 0xbf, 0xdb, + 0x45, 0xde, 0xaa, 0x05, 0x4e, 0x19, 0xc8, 0x02, 0xd0, 0x85, 0x59, 0x18, + 0xbe, 0xba, 0x43, 0xd6, 0x98, 0xed, 0x71, 0xd6, 0x84, 0x94, 0xe3, 0x86, + 0x0d, 0xd6, 0xb2, 0x6b, 0x67, 0x5d, 0x9f, 0x79, 0xee, 0x1d, 0x0e, 0xc9, + 0x6d, 0x8d, 0x48, 0xb6, 0xcc, 0xa1, 0xaf, 0xba, 0x6d, 0x89, 0xbb, 0x52, + 0xb3, 0xc7, 0xc7, 0x12, 0xda, 0xfc, 0x74, 0xe0, 0xb7, 0x78, 0xa7, 0x05, + 0xb1, 0x36, 0xf3, 0x56, 0x38, 0x3c, 0x27, 0xab, 0xab, 0x67, 0x8a, 0x77, + 0x8d, 0x0a, 0xb3, 0x97, 0xb9, 0xef, 0x18, 0x53, 0x86, 0xc3, 0x3b, 0x46, + 0xda, 0xc0, 0x33, 0x6b, 0xb8, 0x5e, 0x54, 0x74, 0xa6, 0x1e, 0x38, 0x1c, + 0x0d, 0x4d, 0x8e, 0xb9, 0x43, 0x8e, 0xc6, 0x1a, 0x0b, 0x33, 0x76, 0x8d, + 0xdb, 0xcb, 0xe1, 0x4a, 0x3d, 0x34, 0xa6, 0xaa, 0xcc, 0x0b, 0x79, 0xda, + 0xa8, 0xbb, 0x7e, 0x86, 0x35, 0x5c, 0x63, 0x6a, 0x32, 0x9f, 0x36, 0xc2, + 0x1a, 0xcb, 0xe4, 0x70, 0x11, 0x2b, 0x30, 0x27, 0x57, 0x64, 0x05, 0x33, + 0x7f, 0xc2, 0xac, 0x14, 0x4a, 0x25, 0xc7, 0xcc, 0x17, 0x27, 0x79, 0xbe, + 0x54, 0xb0, 0x73, 0x66, 0x89, 0x15, 0x8e, 0x57, 0xaa, 0x85, 0x6a, 0x29, + 0xe7, 0x88, 0xa8, 0x6d, 0xde, 0x0c, 0x31, 0x1d, 0x2e, 0x2a, 0x4e, 0xe4, + 0xcc, 0x89, 0x52, 0xc6, 0xe1, 0x6d, 0xe3, 0x3e, 0x50, 0x4a, 0x46, 0xc6, + 0xc8, 0x01, 0x1d, 0x7f, 0x5c, 0xf1, 0xf3, 0x3f, 0x58, 0xd3, 0xdf, 0x68, + 0xf4, 0x21, 0x05, 0x22, 0x20, 0x9f, 0x35, 0x8d, 0x6c, 0x69, 0x84, 0xfc, + 0x51, 0x77, 0xea, 0xac, 0x0e, 0xff, 0x1e, 0xa2, 0x66, 0xf1, 0x5f, 0x35, + 0x74, 0x79, 0x9f, 0x7a, 0xf5, 0x04, 0xba, 0xbd, 0x86, 0xf6, 0xf4, 0x1b, + 0xad, 0xa7, 0xe7, 0xe8, 0x3d, 0x7d, 0x27, 0x06, 0xdd, 0xde, 0x13, 0x87, + 0x6e, 0xff, 0x21, 0xe3, 0xd2, 0x4f, 0xf4, 0x20, 0x4d, 0xc9, 0xe2, 0xde, + 0x91, 0x94, 0x94, 0xa3, 0xfb, 0x39, 0x2e, 0x73, 0x89, 0x1e, 0xa5, 0x8f, + 0xf7, 0xd4, 0xaa, 0x64, 0x71, 0x6f, 0xb5, 0x94, 0x94, 0x45, 0xad, 0x71, + 0xa5, 0x17, 0x77, 0x1a, 0x94, 0x5e, 0xf4, 0xc6, 0xbf, 0x68, 0xe3, 0xb4, + 0x6f, 0x54, 0x05, 0x00, 0x00 +}; + +constexpr uint8 activityCallbacksByteCode[] +{ + 0x1f, 0x8b, 0x08, 0x08, 0x70, 0x70, 0x87, 0x68, 0x00, 0x03, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x65, 0x73, 0x2e, 0x64, 0x65, 0x78, 0x00, 0x9d, 0x94, + 0x41, 0x68, 0x13, 0x41, 0x14, 0x86, 0xdf, 0x6c, 0xd2, 0x56, 0x6b, 0xac, + 0xb1, 0x15, 0x0f, 0x2a, 0x52, 0x96, 0x5e, 0x02, 0x49, 0x36, 0xa9, 0xd1, + 0x4d, 0x9a, 0xa2, 0x58, 0x73, 0x51, 0x16, 0x2a, 0x16, 0x72, 0x2a, 0xc8, + 0x64, 0x77, 0x62, 0x36, 0xdd, 0xec, 0x2e, 0x3b, 0x9b, 0xd0, 0x22, 0x96, + 0x56, 0x3c, 0xa8, 0x07, 0x0f, 0x0a, 0x9e, 0x04, 0xa1, 0x17, 0xaf, 0x1e, + 0xbd, 0x0a, 0x1e, 0x3d, 0x88, 0x20, 0x88, 0x78, 0xf0, 0x24, 0x08, 0x7a, + 0x91, 0x82, 0x37, 0xf1, 0xcd, 0xee, 0x6c, 0x92, 0x1e, 0xbc, 0x74, 0xc2, + 0x97, 0x99, 0xf9, 0xe7, 0xbd, 0x37, 0x6f, 0x96, 0x99, 0x67, 0xb1, 0xcd, + 0xe9, 0xd2, 0x05, 0x1d, 0xde, 0x7f, 0xf9, 0xf4, 0x68, 0xf6, 0xf1, 0xce, + 0xf4, 0x46, 0xb7, 0xff, 0x67, 0xef, 0xf6, 0xae, 0xf1, 0xf6, 0xc9, 0xb3, + 0xc6, 0xf3, 0xd5, 0xdc, 0xde, 0xb7, 0x34, 0x80, 0x0f, 0x00, 0x9b, 0xcd, + 0xca, 0x2c, 0xc8, 0x66, 0xa0, 0x26, 0x26, 0x42, 0x9f, 0x44, 0xde, 0x20, + 0x29, 0xe4, 0x03, 0x8c, 0xda, 0x51, 0x64, 0x1f, 0x21, 0xc8, 0x32, 0xfe, + 0x3d, 0x40, 0x83, 0x75, 0xec, 0xcf, 0x29, 0x00, 0x0b, 0x48, 0x03, 0x59, + 0x47, 0x9e, 0x22, 0xaf, 0x90, 0x8f, 0xc8, 0x77, 0xe4, 0x07, 0xf2, 0x0b, + 0xf9, 0x8d, 0x4c, 0xa0, 0xcf, 0x19, 0x24, 0x8f, 0x5c, 0x11, 0xfe, 0x88, + 0x87, 0xdc, 0x47, 0x14, 0xb9, 0x27, 0xa6, 0x02, 0x13, 0x32, 0x8f, 0x29, + 0xc9, 0x84, 0xcc, 0xe1, 0x88, 0x1c, 0x67, 0x94, 0x38, 0x1f, 0x31, 0x3e, + 0xa5, 0xc4, 0x7e, 0x10, 0xf9, 0x2b, 0x30, 0x1d, 0xf5, 0x04, 0x8e, 0xc9, + 0x3e, 0x23, 0xfb, 0xe3, 0x72, 0x7d, 0x46, 0xce, 0x4f, 0xc8, 0x3e, 0x2b, + 0xf7, 0x04, 0xb9, 0x3f, 0x91, 0xf3, 0xb4, 0x12, 0x8f, 0x45, 0x5b, 0x90, + 0x06, 0x24, 0xfa, 0x01, 0xfc, 0x25, 0xb1, 0x8d, 0x9f, 0x15, 0x19, 0xcd, + 0xa0, 0x5f, 0x92, 0x41, 0xec, 0x23, 0xf6, 0x50, 0xa2, 0x13, 0x1d, 0x4e, + 0x3b, 0x7c, 0xbc, 0x5c, 0xa4, 0x93, 0x31, 0x00, 0x40, 0x5a, 0x29, 0x30, + 0xb9, 0x6c, 0xbb, 0x76, 0x78, 0x19, 0xce, 0xdf, 0xe8, 0x9b, 0xec, 0xaa, + 0x19, 0xda, 0x03, 0x3b, 0xdc, 0xba, 0x46, 0x1d, 0xa7, 0x45, 0xcd, 0x0d, + 0xbe, 0x42, 0x39, 0x2b, 0x76, 0xe9, 0x80, 0xc2, 0x69, 0x83, 0xba, 0x56, + 0xe0, 0xd9, 0x96, 0x46, 0x7d, 0x5f, 0x4b, 0x0c, 0xeb, 0x50, 0x39, 0xa8, + 0xfb, 0xbe, 0x63, 0x9b, 0x34, 0xb4, 0x3d, 0x77, 0x21, 0xb1, 0x31, 0xec, + 0x36, 0x33, 0xb7, 0x4c, 0x87, 0x0d, 0xa3, 0xd6, 0x61, 0x6e, 0xe8, 0xe5, + 0x71, 0x6d, 0xa5, 0xef, 0x5a, 0x0e, 0xab, 0x43, 0xce, 0x30, 0xbd, 0x9e, + 0x16, 0xf4, 0xb8, 0xa3, 0x75, 0x31, 0x19, 0xed, 0xbf, 0x19, 0xd5, 0x61, + 0xd6, 0x10, 0x49, 0x69, 0x0e, 0x75, 0xef, 0x68, 0xab, 0xad, 0x2e, 0x33, + 0xc3, 0x3a, 0x90, 0x26, 0x28, 0x4d, 0x03, 0x52, 0x4d, 0xc3, 0x80, 0x93, + 0x9e, 0x3b, 0xf4, 0x0c, 0x18, 0x0d, 0x99, 0x05, 0x73, 0x23, 0xa9, 0xc1, + 0x78, 0x18, 0x78, 0x5b, 0x28, 0x66, 0x47, 0xe2, 0x4d, 0xda, 0xe7, 0xa8, + 0x8c, 0x79, 0xde, 0x62, 0xbc, 0xdf, 0x43, 0xe9, 0xec, 0x48, 0x5a, 0xa3, + 0x03, 0x76, 0xdd, 0xe5, 0x21, 0x75, 0x4d, 0xb6, 0x16, 0x62, 0xdc, 0x71, + 0x7b, 0x14, 0x82, 0xf0, 0x60, 0x88, 0xb5, 0xd0, 0xf3, 0x7d, 0x94, 0x5e, + 0x92, 0xed, 0xed, 0x46, 0xf5, 0xae, 0x2a, 0x8e, 0xc0, 0x5c, 0x4b, 0x5d, + 0x52, 0x2d, 0xb6, 0xa9, 0xe6, 0x55, 0x3c, 0xb0, 0x6f, 0x3b, 0xd1, 0xf7, + 0x2a, 0xf4, 0x3c, 0x8b, 0xe1, 0x42, 0xc0, 0x1c, 0x86, 0x67, 0xc4, 0xc5, + 0x0e, 0xe5, 0x05, 0xb3, 0xc3, 0xf0, 0xd0, 0xfd, 0x1e, 0x57, 0x97, 0xda, + 0xd4, 0xe1, 0x2c, 0xaf, 0xf6, 0x6c, 0xb7, 0x40, 0x7d, 0x5b, 0x5d, 0x5a, + 0xac, 0xe4, 0x55, 0xde, 0xa1, 0x85, 0x32, 0x3a, 0x51, 0x9d, 0x5a, 0xe5, + 0x2a, 0xd5, 0x4b, 0x95, 0x4b, 0xa5, 0x96, 0x5e, 0xab, 0x59, 0xa5, 0x4a, + 0x75, 0x91, 0x55, 0x6a, 0xba, 0x59, 0x2e, 0xd5, 0xa8, 0x7e, 0xb1, 0xd5, + 0xd6, 0xdb, 0xb5, 0xb2, 0x25, 0xa2, 0x0e, 0x58, 0xc0, 0x71, 0x3b, 0x74, + 0xaa, 0x16, 0xcb, 0xa5, 0x62, 0xad, 0x60, 0xb1, 0x81, 0x7a, 0x4f, 0xdc, + 0x8c, 0x29, 0xd8, 0xdd, 0x49, 0x7f, 0x55, 0x08, 0xd9, 0x47, 0x1e, 0xa6, + 0x08, 0x79, 0x81, 0xbc, 0x46, 0xde, 0x21, 0x9f, 0x91, 0x9f, 0x78, 0x05, + 0x33, 0x63, 0x77, 0x2b, 0xe9, 0x93, 0x3a, 0x21, 0xee, 0xd4, 0x78, 0xad, + 0x48, 0xea, 0x85, 0x78, 0x93, 0x49, 0xad, 0x98, 0x84, 0x51, 0xbd, 0x20, + 0xf3, 0xf1, 0xfb, 0x15, 0x35, 0x23, 0x35, 0x0f, 0xc3, 0x77, 0x44, 0xb2, + 0xf2, 0xdd, 0x63, 0x40, 0x65, 0x3e, 0x8e, 0x2f, 0x6a, 0x0a, 0x48, 0x9b, + 0xe8, 0xed, 0x65, 0xe3, 0xb1, 0xa8, 0x53, 0xff, 0x00, 0xdd, 0xea, 0xf5, + 0x4e, 0xe0, 0x04, 0x00, 0x00 +}; //============================================================================== #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ @@ -96,6 +209,12 @@ static const uint8 invocationHandleByteCode[] = DECLARE_JNI_CLASS_WITH_MIN_SDK (AndroidInMemoryDexClassLoader, "dalvik/system/InMemoryDexClassLoader", 26) #undef JNI_CLASS_MEMBERS +#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ + METHOD (constructor, "", "()V") + + DECLARE_JNI_CLASS_WITH_BYTECODE (JuceActivityCallbacksBase, "com/rmsl/juce/JuceActivityCallbacksBase", 24, activityCallbacksByteCode) +#undef JNI_CLASS_MEMBERS + //============================================================================== struct SystemJavaClassComparator { @@ -428,7 +547,29 @@ void juce_dispatchDelete (JNIEnv*, jobject /*object*/, jlong host) } //============================================================================== -jobject ActivityLifecycleCallbacks::invoke (jobject proxy, jobject method, jobjectArray args) +ActivityLifecycleCallbackForwarder::ActivityLifecycleCallbackForwarder (GlobalRef ctx, ActivityLifecycleCallbacks* cb) + : appContext (ctx), + myself (std::invoke ([&] + { + const LocalRef subclass { getEnv()->NewObject (JuceActivityCallbacksBase, + JuceActivityCallbacksBase.constructor) }; + return CreateJavaInterface (this, + { "android/app/Application$ActivityLifecycleCallbacks" }, + subclass); + })), + callbacks (cb) +{ + if (appContext != nullptr && myself != nullptr) + getEnv()->CallVoidMethod (appContext, AndroidApplication.registerActivityLifecycleCallbacks, myself.get()); +} + +ActivityLifecycleCallbackForwarder::~ActivityLifecycleCallbackForwarder() +{ + if (appContext != nullptr && myself != nullptr) + getEnv()->CallVoidMethod (appContext, AndroidApplication.unregisterActivityLifecycleCallbacks, myself.get()); +} + +jobject ActivityLifecycleCallbackForwarder::invoke (jobject proxy, jobject method, jobjectArray args) { auto* env = getEnv(); @@ -474,7 +615,7 @@ jobject ActivityLifecycleCallbacks::invoke (jobject proxy, jobject method, jobje const auto activity = env->GetArrayLength (args) > 0 ? env->GetObjectArrayElement (args, 0) : (jobject) nullptr; const auto bundle = env->GetArrayLength (args) > 1 ? env->GetObjectArrayElement (args, 1) : (jobject) nullptr; - (iter->second) (*this, activity, bundle); + (iter->second) (*callbacks, activity, bundle); return nullptr; } diff --git a/modules/juce_core/native/juce_JNIHelpers_android.h b/modules/juce_core/native/juce_JNIHelpers_android.h index fb73ae67c4..e19d8b7280 100644 --- a/modules/juce_core/native/juce_JNIHelpers_android.h +++ b/modules/juce_core/native/juce_JNIHelpers_android.h @@ -1033,9 +1033,11 @@ LocalRef CreateJavaInterface (AndroidInterfaceImplementer* implementer, const String& interfaceName); //============================================================================== -class ActivityLifecycleCallbacks : public AndroidInterfaceImplementer +class ActivityLifecycleCallbacks { public: + virtual ~ActivityLifecycleCallbacks() = default; + virtual void onActivityPreCreated (jobject /*activity*/, jobject /*bundle*/) {} virtual void onActivityPreDestroyed (jobject /*activity*/) {} virtual void onActivityPrePaused (jobject /*activity*/) {} @@ -1061,15 +1063,27 @@ public: virtual void onActivityPostStopped (jobject /*activity*/) {} virtual void onActivityConfigurationChanged (jobject /*activity*/) {} +}; + +class ActivityLifecycleCallbackForwarder : private AndroidInterfaceImplementer +{ +public: + ActivityLifecycleCallbackForwarder (GlobalRef appContext, ActivityLifecycleCallbacks* callbacks); + + ~ActivityLifecycleCallbackForwarder() override; private: jobject invoke (jobject, jobject, jobjectArray) override; + + GlobalRef appContext; + GlobalRef myself; + ActivityLifecycleCallbacks* callbacks = nullptr; }; //============================================================================== -struct SurfaceHolderCallback : AndroidInterfaceImplementer +struct SurfaceHolderCallback : public AndroidInterfaceImplementer { - virtual ~SurfaceHolderCallback() override = default; + ~SurfaceHolderCallback() override = default; virtual void surfaceChanged (LocalRef holder, int format, int width, int height) = 0; virtual void surfaceCreated (LocalRef holder) = 0; diff --git a/modules/juce_core/native/juce_Threads_android.cpp b/modules/juce_core/native/juce_Threads_android.cpp index 47a96a02ed..370e5eb003 100644 --- a/modules/juce_core/native/juce_Threads_android.cpp +++ b/modules/juce_core/native/juce_Threads_android.cpp @@ -161,33 +161,9 @@ class JuceActivityWatcher final : public ActivityLifecycleCallbacks public: JuceActivityWatcher() { - auto appContext = getAppContext(); - - if (appContext != nullptr) - { - auto* env = getEnv(); - - myself = GlobalRef (CreateJavaInterface (this, "android/app/Application$ActivityLifecycleCallbacks")); - env->CallVoidMethod (appContext.get(), AndroidApplication.registerActivityLifecycleCallbacks, myself.get()); - } - checkActivityIsMain (androidApkContext); } - ~JuceActivityWatcher() override - { - auto appContext = getAppContext(); - - if (appContext != nullptr && myself != nullptr) - { - auto* env = getEnv(); - - env->CallVoidMethod (appContext.get(), AndroidApplication.unregisterActivityLifecycleCallbacks, myself.get()); - clear(); - myself.clear(); - } - } - void onActivityStarted (jobject activity) override { auto* env = getEnv(); @@ -314,9 +290,9 @@ private: return mainActivityClassPath; } - GlobalRef myself; CriticalSection currentActivityLock; WeakGlobalRef currentActivity, mainActivity; + ActivityLifecycleCallbackForwarder forwarder { GlobalRef { getAppContext() }, this }; }; //============================================================================== diff --git a/modules/juce_core/system/juce_PlatformDefs.h b/modules/juce_core/system/juce_PlatformDefs.h index 47cdf01046..feb78b6523 100644 --- a/modules/juce_core/system/juce_PlatformDefs.h +++ b/modules/juce_core/system/juce_PlatformDefs.h @@ -85,14 +85,14 @@ namespace juce #define JUCE_BREAK_IN_DEBUGGER { __debugbreak(); } #elif JUCE_INTEL && (JUCE_GCC || JUCE_CLANG || JUCE_MAC) #if JUCE_NO_INLINE_ASM - #define JUCE_BREAK_IN_DEBUGGER { } + #define JUCE_BREAK_IN_DEBUGGER { } #else - #define JUCE_BREAK_IN_DEBUGGER { asm ("int $3"); } + #define JUCE_BREAK_IN_DEBUGGER { asm ("int $3"); } #endif -#elif JUCE_ARM && JUCE_MAC - #define JUCE_BREAK_IN_DEBUGGER { __builtin_debugtrap(); } #elif JUCE_ANDROID #define JUCE_BREAK_IN_DEBUGGER { __builtin_trap(); } +#elif JUCE_ARM && JUCE_CLANG + #define JUCE_BREAK_IN_DEBUGGER { __builtin_debugtrap(); } #else #define JUCE_BREAK_IN_DEBUGGER { __asm int 3 } #endif diff --git a/modules/juce_core/text/juce_String.cpp b/modules/juce_core/text/juce_String.cpp index cebff47d96..8ac68ea1f1 100644 --- a/modules/juce_core/text/juce_String.cpp +++ b/modules/juce_core/text/juce_String.cpp @@ -2878,6 +2878,20 @@ public: expectEquals (String::toDecimalStringWithSignificantFigures (2.8647, 6), String ("2.86470")); expectEquals (String::toDecimalStringWithSignificantFigures (-0.0000000000019, 1), String ("-0.000000000002")); + + // Powers of 10 + + expectEquals (String::toDecimalStringWithSignificantFigures ( 0.001, 7), String ( "0.001000000")); + expectEquals (String::toDecimalStringWithSignificantFigures ( 0.01, 7), String ( "0.01000000")); + expectEquals (String::toDecimalStringWithSignificantFigures ( 0.1, 7), String ( "0.1000000")); + expectEquals (String::toDecimalStringWithSignificantFigures ( 1, 7), String ( "1.000000")); + expectEquals (String::toDecimalStringWithSignificantFigures ( 10, 7), String ( "10.00000")); + expectEquals (String::toDecimalStringWithSignificantFigures ( 100, 7), String ( "100.0000")); + expectEquals (String::toDecimalStringWithSignificantFigures ( 1000, 7), String ( "1000.000")); + expectEquals (String::toDecimalStringWithSignificantFigures ( 10000, 7), String ( "10000.00")); + expectEquals (String::toDecimalStringWithSignificantFigures ( 100000, 7), String ( "100000.0")); + expectEquals (String::toDecimalStringWithSignificantFigures ( 1000000, 7), String ( "1000000")); + expectEquals (String::toDecimalStringWithSignificantFigures (10000000, 7), String ("10000000")); } beginTest ("Float trimming"); diff --git a/modules/juce_core/text/juce_String.h b/modules/juce_core/text/juce_String.h index 25afe617fc..5daa1fda3e 100644 --- a/modules/juce_core/text/juce_String.h +++ b/modules/juce_core/text/juce_String.h @@ -1159,11 +1159,10 @@ public: return "0"; } - auto numDigitsBeforePoint = (int) std::ceil (std::log10 (number < 0 ? -number : number)); - - auto shift = numberOfSignificantFigures - numDigitsBeforePoint; - auto factor = std::pow (10.0, shift); - auto rounded = std::round (number * factor) / factor; + const auto numDigitsBeforePoint = (int) std::floor (std::log10 (std::abs (number)) + DecimalType (1)); + const auto shift = numberOfSignificantFigures - numDigitsBeforePoint; + const auto factor = std::pow (10.0, shift); + const auto rounded = std::round (number * factor) / factor; std::stringstream ss; ss << std::fixed << std::setprecision (std::max (shift, 0)) << rounded; diff --git a/modules/juce_dsp/juce_dsp.h b/modules/juce_dsp/juce_dsp.h index aefc25ae9d..0b8e2f9e27 100644 --- a/modules/juce_dsp/juce_dsp.h +++ b/modules/juce_dsp/juce_dsp.h @@ -92,10 +92,18 @@ #endif #endif - #if JUCE_64BIT && JUCE_WINDOWS - #include - #else - #include + #if JUCE_USE_SIMD + #if JUCE_WINDOWS + #if JUCE_64BIT + #if ! JUCE_CLANG + #include + #endif + #else + #include + #endif + #else + #include + #endif #endif #else diff --git a/modules/juce_events/native/juce_Messaging_android.cpp b/modules/juce_events/native/juce_Messaging_android.cpp index af84671f25..2034d06fa7 100644 --- a/modules/juce_events/native/juce_Messaging_android.cpp +++ b/modules/juce_events/native/juce_Messaging_android.cpp @@ -182,29 +182,6 @@ public: explicit JuceAppLifecycle (CreateApp initSymbolAddr) : createApplicationSymbol (initSymbolAddr) { - auto appContext = getAppContext(); - - if (appContext != nullptr) - { - auto* env = getEnv(); - - myself = GlobalRef (CreateJavaInterface (this, "android/app/Application$ActivityLifecycleCallbacks")); - env->CallVoidMethod (appContext.get(), AndroidApplication.registerActivityLifecycleCallbacks, myself.get()); - } - } - - ~JuceAppLifecycle() override - { - auto appContext = getAppContext(); - - if (appContext != nullptr && myself != nullptr) - { - auto* env = getEnv(); - - clear(); - env->CallVoidMethod (appContext.get(), AndroidApplication.unregisterActivityLifecycleCallbacks, myself.get()); - myself.clear(); - } } void onActivityCreated (jobject, jobject) override @@ -291,6 +268,7 @@ private: GlobalRef myself; CreateApp createApplicationSymbol{}; bool hasBeenInitialised = false; + ActivityLifecycleCallbackForwarder forwarder { GlobalRef { getAppContext() }, this }; }; //============================================================================== diff --git a/modules/juce_graphics/fonts/juce_TextLayout.cpp b/modules/juce_graphics/fonts/juce_TextLayout.cpp index 573430e0fc..aeb2d4b6a8 100644 --- a/modules/juce_graphics/fonts/juce_TextLayout.cpp +++ b/modules/juce_graphics/fonts/juce_TextLayout.cpp @@ -283,39 +283,72 @@ void TextLayout::createLayoutWithBalancedLineLengths (const AttributedString& te createLayoutWithBalancedLineLengths (text, maxWidth, 1.0e7f); } -void TextLayout::createLayoutWithBalancedLineLengths (const AttributedString& text, float maxWidth, float maxHeight) +void TextLayout::createLayoutWithBalancedLineLengths (const AttributedString& text, + float maxWidth, + float maxHeight) { auto minimumWidth = maxWidth / 2.0f; auto bestWidth = maxWidth; - float bestLineProportion = 0.0f; + auto bestScore = std::numeric_limits::max(); + + auto widthProbeText = text; + + if (widthProbeText.getWordWrap() == AttributedString::byChar) + widthProbeText.setWordWrap (AttributedString::byWord); + + std::optional advanceWidth; while (maxWidth > minimumWidth) { - createLayout (text, maxWidth, maxHeight); + createLayout (widthProbeText, maxWidth, maxHeight); - if (getNumLines() < 2) + const auto numLines = getNumLines(); + + if (numLines < 2) return; - auto line1 = lines.getUnchecked (lines.size() - 1)->getLineBoundsX().getLength(); - auto line2 = lines.getUnchecked (lines.size() - 2)->getLineBoundsX().getLength(); - auto shortest = jmin (line1, line2); - auto longest = jmax (line1, line2); - auto prop = shortest > 0 ? longest / shortest : 1.0f; + std::vector lineLengths; + lineLengths.reserve ((size_t) numLines); + std::transform (lines.begin(), + lines.end(), + std::back_inserter (lineLengths), + [] (const auto& line) { return line->getLineBoundsX().getLength(); }); - if (prop > 0.9f && prop < 1.1f) - return; + const auto longestLineLength = *std::max_element (lineLengths.begin(), lineLengths.end()); - if (prop > bestLineProportion) + auto accumulateScore = [longestLineLength] (auto scoreSum, auto lineLength) { - bestLineProportion = prop; + const auto unusedSpace = 1.0f - (lineLength / longestLineLength); + return scoreSum + (unusedSpace * unusedSpace); + }; + + const auto score = std::accumulate (lineLengths.begin(), + lineLengths.end(), + 0.0f, accumulateScore) / (float) numLines; + + if (score < bestScore) + { + bestScore = score; bestWidth = maxWidth; + + if (score < 0.4f) + break; } - maxWidth -= 10.0f; + if (! advanceWidth.has_value()) + { + advanceWidth = std::numeric_limits::max(); + + for (const auto& line : lines) + for (const auto& run : line->runs) + for (const auto& glyph : run->glyphs) + advanceWidth = jmin (*advanceWidth, glyph.width); + } + + maxWidth -= *advanceWidth; } - if (! approximatelyEqual (bestWidth, maxWidth)) - createLayout (text, bestWidth, maxHeight); + createLayout (text, bestWidth, maxHeight); } //============================================================================== @@ -421,6 +454,9 @@ void TextLayout::createStandardLayout (const AttributedString& text) if (text.getWordWrap() != AttributedString::none) shapedTextOptions = shapedTextOptions.withWordWrapWidth (width); + if (text.getWordWrap() == AttributedString::WordWrap::byChar) + shapedTextOptions = shapedTextOptions.withAllowBreakingInsideWord (true); + ShapedText st { text.getText(), shapedTextOptions }; std::optional lastLineNumber; diff --git a/modules/juce_graphics/image_formats/juce_JPEGLoader.cpp b/modules/juce_graphics/image_formats/juce_JPEGLoader.cpp index d2121fb88e..cf90a1c638 100644 --- a/modules/juce_graphics/image_formats/juce_JPEGLoader.cpp +++ b/modules/juce_graphics/image_formats/juce_JPEGLoader.cpp @@ -55,6 +55,7 @@ namespace jpeglibNamespace "-Wregister", "-Wredundant-decls") + #define DONT_USE_EXTERN_C #include "jpglib/jaricom.c" #include "jpglib/jcapimin.c" #include "jpglib/jcapistd.c" diff --git a/modules/juce_graphics/native/juce_Direct2DGraphicsContextImpl_windows.cpp b/modules/juce_graphics/native/juce_Direct2DGraphicsContextImpl_windows.cpp index d86bb9064a..6df36af92b 100644 --- a/modules/juce_graphics/native/juce_Direct2DGraphicsContextImpl_windows.cpp +++ b/modules/juce_graphics/native/juce_Direct2DGraphicsContextImpl_windows.cpp @@ -449,8 +449,7 @@ public: { noTransforms = 0, applyWorldTransform = 1, - applyInverseWorldTransform = 2, - applyFillTypeTransform = 4, + applyFillTypeTransform = 2, applyWorldAndFillTypeTransforms = applyFillTypeTransform | applyWorldTransform }; @@ -462,38 +461,30 @@ public: if (! fillType.isGradient() && ! fillType.isTiledImage()) return currentBrush; - Point translation{}; AffineTransform transform{}; + if ((flags & BrushTransformFlags::applyWorldTransform) != 0) + transform = currentTransform.getTransform(); + + if ((flags & BrushTransformFlags::applyFillTypeTransform) != 0) + transform = fillType.transform.followedBy (transform); + if (fillType.isGradient()) { - if ((flags & BrushTransformFlags::applyWorldTransform) != 0) - { - if (currentTransform.isOnlyTranslated) - translation = currentTransform.offset.toFloat(); - else - transform = currentTransform.getTransform(); - } + auto p1 = fillType.gradient->point1; + auto p2 = fillType.gradient->point2; - if ((flags & BrushTransformFlags::applyFillTypeTransform) != 0) + if (transform.isOnlyTranslation()) { - if (fillType.transform.isOnlyTranslation()) - translation += Point (fillType.transform.getTranslationX(), fillType.transform.getTranslationY()); - else - transform = transform.followedBy (fillType.transform); + Point translation { transform.getTranslationX(), transform.getTranslationY() }; + p1 += translation; + p2 += translation; } - - if ((flags & BrushTransformFlags::applyInverseWorldTransform) != 0) + else { - if (currentTransform.isOnlyTranslated) - translation -= currentTransform.offset.toFloat(); - else - transform = transform.followedBy (currentTransform.getTransform().inverted()); + currentBrush->SetTransform (D2DUtilities::transformToMatrix (transform)); } - const auto p1 = fillType.gradient->point1 + translation; - const auto p2 = fillType.gradient->point2 + translation; - if (fillType.gradient->isRadial) { const auto radius = p2.getDistanceFrom (p1); @@ -507,19 +498,11 @@ public: linearGradient->SetEndPoint ({ p2.x, p2.y }); } } - else if (fillType.isTiledImage()) + else { - if ((flags & BrushTransformFlags::applyWorldTransform) != 0) - transform = currentTransform.getTransform(); - - if ((flags & BrushTransformFlags::applyFillTypeTransform) != 0) - transform = transform.followedBy (fillType.transform); - - if ((flags & BrushTransformFlags::applyInverseWorldTransform) != 0) - transform = transform.followedBy (currentTransform.getTransform().inverted()); + currentBrush->SetTransform (D2DUtilities::transformToMatrix (transform)); } - currentBrush->SetTransform (D2DUtilities::transformToMatrix (transform)); currentBrush->SetOpacity (fillType.getOpacity()); return currentBrush; diff --git a/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp b/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp index e05a643717..efd547698b 100644 --- a/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp +++ b/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp @@ -924,7 +924,7 @@ void Direct2DGraphicsContext::drawImage (const Image& imageIn, const AffineTrans continue; const auto src = intersection - pageBounds.getPosition().toFloat(); - const auto dst = getRect (intersection - pagesAndArea.area.getPosition().toFloat()).toNearestInt().toFloat(); + const auto dst = getRect (intersection - pagesAndArea.area.getPosition().toFloat()); const auto [srcConverted, dstConverted] = std::tuple (D2DUtilities::toRECT_F (src), D2DUtilities::toRECT_F (dst)); @@ -945,12 +945,19 @@ void Direct2DGraphicsContext::drawImage (const Image& imageIn, const AffineTrans } else { + const auto lastMode = deviceContext->GetAntialiasMode(); + + if (pagesAndArea.pages.size() > 1) + deviceContext->SetAntialiasMode (D2D1_ANTIALIAS_MODE_ALIASED); + deviceContext->DrawBitmap (page.bitmap, dstConverted, currentState->fillType.getOpacity(), currentState->interpolationMode, srcConverted, {}); + + deviceContext->SetAntialiasMode (lastMode); } } }; @@ -1327,39 +1334,183 @@ public: g.drawImageTransformed (imageToDraw, transform); } - compareImages (targetNative, targetSoftware); + auto pixelsToIgnore = createEdgeMask (imageToDraw.getWidth(), + imageToDraw.getHeight(), + targetNative.getWidth(), + targetNative.getHeight(), + transform); + + compareImages (targetNative, targetSoftware, 16, pixelsToIgnore); } } } + + beginTest ("Check that there is no seam between D2D image tiles"); + { + const auto width = 229; + const auto height = 80 * width; + + Image filmStripSoftware { Image::RGB, width, height, true, SoftwareImageType{} }; + + { + Graphics g { filmStripSoftware }; + g.setGradientFill ({ Colours::red, 0, 0, Colours::cyan, (float) filmStripSoftware.getWidth(), 0, false }); + g.fillAll(); + } + + const auto filmStrip = NativeImageType{}.convert (filmStripSoftware); + Image targetNative { Image::RGB, targetDim, targetDim, true, NativeImageType{} }; + Image targetSoftware { Image::RGB, targetDim, targetDim, true, SoftwareImageType{} }; + const auto transform = AffineTransform::scale (1.1f); + + for (auto* target : { &targetNative, &targetSoftware }) + { + Graphics g { *target }; + g.setColour (Colours::orange); + g.fillAll(); + g.addTransform (transform); + g.drawImage (filmStrip, 0, 0, width, width, 0, (16384 / width) * width, width, width); + } + + auto pixelsToIgnore = createEdgeMask (width, + width, + targetNative.getWidth(), + targetNative.getHeight(), + transform); + + compareImages (targetNative, targetSoftware, 1, pixelsToIgnore); + } + + beginTest ("Gradient fill transform should compose with world transform correctly"); + { + testGradientFillTransform (1.0f); + testGradientFillTransform (1.5f); + } } - void compareImages (const Image& a, const Image& b) + static Image createEdgeMask (int sourceWidth, + int sourceHeight, + int maskWidth, + int maskHeight, + const AffineTransform& transform) + { + Image mask { Image::SingleChannel, maskWidth, maskHeight, true, SoftwareImageType{} }; + Graphics g { mask }; + g.addTransform (transform); + g.setColour (Colours::white); + g.drawRect (Rectangle { 0, 0, sourceWidth + 1, sourceHeight + 1 }.toFloat(), 2.0f); + + return mask; + } + + void compareImages (const Image& a, const Image& b, int stride, const Image& ignoreMask) { expect (a.getBounds() == b.getBounds()); const Image::BitmapData bitmapA { a, Image::BitmapData::readOnly }; const Image::BitmapData bitmapB { b, Image::BitmapData::readOnly }; + int64_t maxAbsError{}; int64_t accumulatedError{}; int64_t numSamples{}; - for (auto y = 0; y < a.getHeight(); y += 16) + for (auto y = 0; y < a.getHeight(); y += stride) { - for (auto x = 0; x < a.getWidth(); x += 16) + for (auto x = 0; x < a.getWidth(); x += stride) { + if (ignoreMask.getPixelAt (x, y) != Colour{}) + continue; + const auto expected = bitmapA.getPixelColour (x, y); const auto actual = bitmapB.getPixelColour (x, y); for (auto& fn : { &Colour::getRed, &Colour::getGreen, &Colour::getBlue, &Colour::getAlpha }) { - accumulatedError += ((int64_t) (actual.*fn)() - (int64_t) (expected.*fn)()); + const auto signedError = ((int64_t) (actual.*fn)() - (int64_t) (expected.*fn)()); + const auto absError = std::abs (signedError); + maxAbsError = std::max (maxAbsError, absError); + + accumulatedError += absError; ++numSamples; } } } const auto averageError = (double) accumulatedError / (double) numSamples; - expect (std::abs (averageError) < 1.0); + expect (std::abs (averageError) < 1.0 && maxAbsError < 10); + } + + void testGradientFillTransform (float scale) + { + constexpr int size = 500; + constexpr int circleSize = 100; + constexpr int brushTranslation = 20; + + Image image { Image::RGB, + roundToInt (size * scale), + roundToInt (size * scale), + true }; + + { + for (int i = 0; i < size / circleSize; ++i) + { + Graphics g { image }; + + g.addTransform (AffineTransform::scale (scale)); + g.addTransform (AffineTransform::translation ((float) i * circleSize, (float) i * circleSize)); + + const auto fillCol1 { Colours::red }; + const auto fillCol2 { Colours::green }; + const auto centreLoc = circleSize / 2.0f; + + FillType innerGlowGrad = ColourGradient { fillCol1, + { centreLoc, centreLoc }, + fillCol2, + { centreLoc, 0.0f }, + true }; + + innerGlowGrad.gradient->addColour (0.19, fillCol1); + + innerGlowGrad.transform = AffineTransform::scale (1.1f, 0.9f, centreLoc, centreLoc) + .followedBy (AffineTransform::translation (brushTranslation, + brushTranslation)); + + g.setFillType (innerGlowGrad); + g.fillEllipse (0, 0, (float) circleSize, (float) circleSize); + } + } + + for (int i = 0; i < size / circleSize; ++i) + { + const auto getScaled = [scale] (Point p) + { + return p.toFloat().transformedBy (AffineTransform::scale (scale)).roundToInt(); + }; + + const auto approximatelyEqual = [] (const Colour& a, const Colour& b) + { + return std::abs (a.getRed() - b.getRed()) < 2 + && std::abs (a.getGreen() - b.getGreen()) < 2 + && std::abs (a.getBlue() - b.getBlue()) < 2 + && std::abs (a.getAlpha() - b.getAlpha()) < 2; + }; + + const Point centre { circleSize / 2, circleSize / 2 }; + const Point brushOffset { brushTranslation, brushTranslation }; + + const auto redPosition = getScaled (centre + brushOffset); + expect (image.getPixelAt (redPosition.getX(), redPosition.getY()) == Colours::red); + + const auto mostlyRedPosition = getScaled (centre); + expect (approximatelyEqual (image.getPixelAt (mostlyRedPosition.getX(), mostlyRedPosition.getY()), + Colour { 138, 59, 0 })); + + const auto greenPosition = getScaled (centre.withY (2)); + expect (image.getPixelAt (greenPosition.getX(), greenPosition.getY()) == Colours::green); + + const auto blackPosition = getScaled ({ circleSize - 2, 2 }); + expect (image.getPixelAt (blackPosition.getX(), blackPosition.getY()) == Colours::black); + } } }; diff --git a/modules/juce_graphics/native/juce_RenderingHelpers.h b/modules/juce_graphics/native/juce_RenderingHelpers.h index c6436a4a9d..b35401a6e2 100644 --- a/modules/juce_graphics/native/juce_RenderingHelpers.h +++ b/modules/juce_graphics/native/juce_RenderingHelpers.h @@ -2420,9 +2420,9 @@ public: SoftwareRendererSavedState (const SoftwareRendererSavedState& other) = default; - SoftwareRendererSavedState* beginTransparencyLayer (float opacity) + std::unique_ptr beginTransparencyLayer (float opacity) { - auto* s = new SoftwareRendererSavedState (*this); + auto s = std::make_unique (*this); if (clip != nullptr) { @@ -2565,12 +2565,12 @@ public: void beginTransparencyLayer (float opacity) { save(); - currentState.reset (currentState->beginTransparencyLayer (opacity)); + currentState = currentState->beginTransparencyLayer (opacity); } void endTransparencyLayer() { - std::unique_ptr finishedTransparencyLayer (currentState.release()); + auto finishedTransparencyLayer = std::move (currentState); restore(); currentState->endTransparencyLayer (*finishedTransparencyLayer); } @@ -2680,7 +2680,7 @@ protected: if (auto fill = colourLayer->colour) stack->setFillType (*fill); - stack->fillEdgeTable (colourLayer->clip, drawPosition.x, (int) drawPosition.y); + stack->fillEdgeTable (colourLayer->clip, drawPosition.x, roundToInt (drawPosition.y)); } else if (auto* imageLayer = std::get_if (&layer.layer)) { diff --git a/modules/juce_gui_basics/detail/juce_LookAndFeelHelpers.h b/modules/juce_gui_basics/detail/juce_LookAndFeelHelpers.h index 959b411eb1..6aa9c19662 100644 --- a/modules/juce_gui_basics/detail/juce_LookAndFeelHelpers.h +++ b/modules/juce_gui_basics/detail/juce_LookAndFeelHelpers.h @@ -59,6 +59,7 @@ struct LookAndFeelHelpers const int maxToolTipWidth = 400; AttributedString s; + s.setWordWrap (AttributedString::WordWrap::byChar); s.setJustification (Justification::centred); s.append (text, FontOptions (tooltipFontSize, Font::bold).withMetricsKind (metrics), colour); diff --git a/modules/juce_gui_basics/filebrowser/juce_FileListComponent.cpp b/modules/juce_gui_basics/filebrowser/juce_FileListComponent.cpp index 4fb2f175b1..ba6f92998c 100644 --- a/modules/juce_gui_basics/filebrowser/juce_FileListComponent.cpp +++ b/modules/juce_gui_basics/filebrowser/juce_FileListComponent.cpp @@ -72,6 +72,8 @@ void FileListComponent::scrollToTop() void FileListComponent::setSelectedFile (const File& f) { + lastDirectory = directoryContentsList.getDirectory(); + if (! directoryContentsList.isStillLoading()) { for (int i = directoryContentsList.getNumFiles(); --i >= 0;) diff --git a/modules/juce_gui_basics/keyboard/juce_ModifierKeys.cpp b/modules/juce_gui_basics/keyboard/juce_ModifierKeys.cpp index 306d082058..c7fd5c60f2 100644 --- a/modules/juce_gui_basics/keyboard/juce_ModifierKeys.cpp +++ b/modules/juce_gui_basics/keyboard/juce_ModifierKeys.cpp @@ -46,6 +46,8 @@ int ModifierKeys::getNumMouseButtonsDown() const noexcept if (isLeftButtonDown()) ++num; if (isRightButtonDown()) ++num; if (isMiddleButtonDown()) ++num; + if (isBackButtonDown()) ++num; + if (isForwardButtonDown()) ++num; return num; } diff --git a/modules/juce_gui_basics/keyboard/juce_ModifierKeys.h b/modules/juce_gui_basics/keyboard/juce_ModifierKeys.h index 44f79ad277..384ef8cf82 100644 --- a/modules/juce_gui_basics/keyboard/juce_ModifierKeys.h +++ b/modules/juce_gui_basics/keyboard/juce_ModifierKeys.h @@ -98,6 +98,10 @@ public: inline bool isMiddleButtonDown() const noexcept { return testFlags (middleButtonModifier); } + inline bool isBackButtonDown() const noexcept { return testFlags (backButtonModifier); } + + inline bool isForwardButtonDown() const noexcept { return testFlags (forwardButtonModifier); } + /** Tests for any of the mouse-button flags. */ inline bool isAnyMouseButtonDown() const noexcept { return testFlags (allMouseButtonModifiers); } @@ -144,6 +148,12 @@ public: /** Middle mouse button flag. */ middleButtonModifier = 64, + /* Back mouse button flag. Otherwise known as button 4. */ + backButtonModifier = 128, + + /* Forward mouse button flag. Otherwise known as button 5. */ + forwardButtonModifier = 256, + #if JUCE_MAC || JUCE_IOS /** Command key flag - on windows this is the same as the CTRL key flag. */ commandModifier = 8, @@ -164,7 +174,11 @@ public: allKeyboardModifiers = shiftModifier | ctrlModifier | altModifier | commandModifier, /** Represents a combination of all the mouse buttons at once. */ - allMouseButtonModifiers = leftButtonModifier | rightButtonModifier | middleButtonModifier, + allMouseButtonModifiers = leftButtonModifier + | rightButtonModifier + | middleButtonModifier + | backButtonModifier + | forwardButtonModifier, /** Represents a combination of all the alt, ctrl and command key modifiers. */ ctrlAltCommandModifiers = ctrlModifier | altModifier | commandModifier diff --git a/modules/juce_gui_basics/menus/juce_PopupMenu.cpp b/modules/juce_gui_basics/menus/juce_PopupMenu.cpp index 1f6b591890..7055dc7646 100644 --- a/modules/juce_gui_basics/menus/juce_PopupMenu.cpp +++ b/modules/juce_gui_basics/menus/juce_PopupMenu.cpp @@ -250,7 +250,7 @@ private: } private: - static AccessibilityActions getAccessibilityActions (ItemAccessibilityHandler& handler, + static AccessibilityActions getAccessibilityActions (ItemAccessibilityHandler&, ItemComponent& item) { auto onFocus = [&item] @@ -260,16 +260,7 @@ private: item.parentWindow.setCurrentlyHighlightedChild (&item); }; - auto onToggle = [&handler, &item, onFocus] - { - if (handler.getCurrentState().isSelected()) - item.parentWindow.setCurrentlyHighlightedChild (nullptr); - else - onFocus(); - }; - - auto actions = AccessibilityActions().addAction (AccessibilityActionType::focus, std::move (onFocus)) - .addAction (AccessibilityActionType::toggle, std::move (onToggle)); + auto actions = AccessibilityActions().addAction (AccessibilityActionType::focus, std::move (onFocus)); if (canBeTriggered (item.item)) { diff --git a/modules/juce_gui_basics/native/juce_NSViewComponentPeer_mac.mm b/modules/juce_gui_basics/native/juce_NSViewComponentPeer_mac.mm index 6487cda34d..2197326e8b 100644 --- a/modules/juce_gui_basics/native/juce_NSViewComponentPeer_mac.mm +++ b/modules/juce_gui_basics/native/juce_NSViewComponentPeer_mac.mm @@ -1445,9 +1445,16 @@ public: static int getModifierForButtonNumber (const NSInteger num) { - return num == 0 ? ModifierKeys::leftButtonModifier - : (num == 1 ? ModifierKeys::rightButtonModifier - : (num == 2 ? ModifierKeys::middleButtonModifier : 0)); + switch (num) + { + case 0: return ModifierKeys::leftButtonModifier; + case 1: return ModifierKeys::rightButtonModifier; + case 2: return ModifierKeys::middleButtonModifier; + case 3: return ModifierKeys::backButtonModifier; + case 4: return ModifierKeys::forwardButtonModifier; + } + + return 0; } static unsigned int getNSWindowStyleMask (const int flags) noexcept diff --git a/modules/juce_gui_basics/native/juce_NativeMessageBox_ios.mm b/modules/juce_gui_basics/native/juce_NativeMessageBox_ios.mm index 7182599bd9..d97f643415 100644 --- a/modules/juce_gui_basics/native/juce_NativeMessageBox_ios.mm +++ b/modules/juce_gui_basics/native/juce_NativeMessageBox_ios.mm @@ -44,6 +44,15 @@ std::unique_ptr ScopedMessageBoxInterface::create (co void runAsync (std::function recipient) override { + auto* peerToUse = std::invoke ([&]() -> UIViewComponentPeer* + { + if (auto* comp = options.getAssociatedComponent()) + if (auto* peer = comp->getPeer()) + return static_cast (peer); + + return iOSGlobals::currentlyFocusedPeer; + }); + if (peerToUse == nullptr) { // Since iOS8, alert windows need to be associated with a window, so you need to @@ -109,15 +118,6 @@ std::unique_ptr ScopedMessageBoxInterface::create (co private: const MessageBoxOptions options; - UIViewComponentPeer* peerToUse = std::invoke ([&]() -> UIViewComponentPeer* - { - if (auto* comp = options.getAssociatedComponent()) - if (auto* peer = comp->getPeer()) - return static_cast (peer); - - return iOSGlobals::currentlyFocusedPeer; - }); - NSUniquePtr alert; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MessageBox) }; diff --git a/modules/juce_gui_basics/native/juce_Windowing_android.cpp b/modules/juce_gui_basics/native/juce_Windowing_android.cpp index 5f02e315c3..fa5cae7e46 100644 --- a/modules/juce_gui_basics/native/juce_Windowing_android.cpp +++ b/modules/juce_gui_basics/native/juce_Windowing_android.cpp @@ -1308,7 +1308,8 @@ static constexpr int translateAndroidKeyboardFlags (int javaFlags) noexcept } //============================================================================== -class AndroidComponentPeer final : public ComponentPeer +class AndroidComponentPeer final : public ComponentPeer, + private ActivityLifecycleCallbacks { public: AndroidComponentPeer (Component& comp, int windowStyleFlags, void* nativeViewHandle) @@ -2092,28 +2093,20 @@ public: } //============================================================================== - static Point lastMousePos; - static int64 touchesDown; + inline static Point lastMousePos{}; + inline static int64 touchesDown = 0; //============================================================================== struct StartupActivityCallbackListener final : public ActivityLifecycleCallbacks { void onActivityStarted (jobject /*activity*/) override { - auto* env = getEnv(); - LocalRef appContext (getAppContext()); + forceDisplayUpdate(); - if (appContext.get() != nullptr) - { - env->CallVoidMethod (appContext.get(), - AndroidApplication.unregisterActivityLifecycleCallbacks, - activityCallbackListener.get()); - clear(); - activityCallbackListener.clear(); - - forceDisplayUpdate(); - } + AndroidComponentPeer::startupActivityCallbackListener.reset(); } + + ActivityLifecycleCallbackForwarder forwarder { GlobalRef { getAppContext() }, this }; }; class MainActivityWindowLayoutListener : public AndroidInterfaceImplementer @@ -2532,8 +2525,8 @@ private: //============================================================================== friend class Displays; - static AndroidComponentPeer* frontWindow; - static GlobalRef activityCallbackListener; + inline static AndroidComponentPeer* frontWindow = nullptr; + inline static std::optional startupActivityCallbackListener; static constexpr jint GRAVITY_LEFT = 0x3, GRAVITY_TOP = 0x30; static constexpr jint TYPE_APPLICATION = 0x2; @@ -2553,11 +2546,6 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AndroidComponentPeer) }; -Point AndroidComponentPeer::lastMousePos; -int64 AndroidComponentPeer::touchesDown = 0; -AndroidComponentPeer* AndroidComponentPeer::frontWindow = nullptr; -GlobalRef AndroidComponentPeer::activityCallbackListener; - //============================================================================== ComponentPeer* Component::createNewPeer (int styleFlags, void* nativeWindow) { @@ -2570,37 +2558,10 @@ bool Desktop::canUseSemiTransparentWindows() noexcept return true; } -class Desktop::NativeDarkModeChangeDetectorImpl : public ActivityLifecycleCallbacks +class Desktop::NativeDarkModeChangeDetectorImpl : private ActivityLifecycleCallbacks { public: - NativeDarkModeChangeDetectorImpl() - { - LocalRef appContext (getAppContext()); - - if (appContext != nullptr) - { - auto* env = getEnv(); - - myself = GlobalRef (CreateJavaInterface (this, "android/app/Application$ActivityLifecycleCallbacks")); - env->CallVoidMethod (appContext.get(), AndroidApplication.registerActivityLifecycleCallbacks, myself.get()); - } - } - - ~NativeDarkModeChangeDetectorImpl() override - { - LocalRef appContext (getAppContext()); - - if (appContext != nullptr && myself != nullptr) - { - auto* env = getEnv(); - - env->CallVoidMethod (appContext.get(), - AndroidApplication.unregisterActivityLifecycleCallbacks, - myself.get()); - clear(); - myself.clear(); - } - } + NativeDarkModeChangeDetectorImpl() = default; bool isDarkModeEnabled() const noexcept { return darkModeEnabled; } @@ -2633,8 +2594,8 @@ private: UI_MODE_NIGHT_UNDEFINED = 0x00000000, UI_MODE_NIGHT_YES = 0x00000020; - GlobalRef myself; bool darkModeEnabled = getDarkModeSetting(); + ActivityLifecycleCallbackForwarder forwarder { GlobalRef { getAppContext() }, this }; //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NativeDarkModeChangeDetectorImpl) @@ -2979,20 +2940,9 @@ void Displays::findDisplays (float masterScale) } } } - else if (AndroidComponentPeer::activityCallbackListener == nullptr) + else if (! AndroidComponentPeer::startupActivityCallbackListener.has_value()) { - LocalRef appContext (getAppContext()); - - if (appContext.get() != nullptr) - { - AndroidComponentPeer::activityCallbackListener = GlobalRef (CreateJavaInterface ( - new AndroidComponentPeer::StartupActivityCallbackListener, - "android/app/Application$ActivityLifecycleCallbacks")); - - env->CallVoidMethod (appContext, - AndroidApplication.registerActivityLifecycleCallbacks, - AndroidComponentPeer::activityCallbackListener.get()); - } + AndroidComponentPeer::startupActivityCallbackListener.emplace(); } displays.add (d); diff --git a/modules/juce_gui_basics/native/juce_Windowing_windows.cpp b/modules/juce_gui_basics/native/juce_Windowing_windows.cpp index 047c32cfda..c89140b03f 100644 --- a/modules/juce_gui_basics/native/juce_Windowing_windows.cpp +++ b/modules/juce_gui_basics/native/juce_Windowing_windows.cpp @@ -1973,6 +1973,8 @@ public: if (wParam & MK_LBUTTON) mouseMods |= ModifierKeys::leftButtonModifier; if (wParam & MK_RBUTTON) mouseMods |= ModifierKeys::rightButtonModifier; if (wParam & MK_MBUTTON) mouseMods |= ModifierKeys::middleButtonModifier; + if (wParam & MK_XBUTTON1) mouseMods |= ModifierKeys::backButtonModifier; + if (wParam & MK_XBUTTON2) mouseMods |= ModifierKeys::forwardButtonModifier; ModifierKeys::currentModifiers = ModifierKeys::getCurrentModifiers().withoutMouseButtons().withFlags (mouseMods); updateKeyModifiers(); @@ -4056,12 +4058,14 @@ private: case WM_LBUTTONDOWN: case WM_MBUTTONDOWN: case WM_RBUTTONDOWN: + case WM_XBUTTONDOWN: doMouseDown (lParam, wParam); return 0; case WM_LBUTTONUP: case WM_MBUTTONUP: case WM_RBUTTONUP: + case WM_XBUTTONUP: doMouseUp (getPointFromLocalLParam (lParam), wParam); return 0; diff --git a/modules/juce_gui_basics/native/juce_XWindowSystem_linux.cpp b/modules/juce_gui_basics/native/juce_XWindowSystem_linux.cpp index 1ab1f6191f..4e4d0f715b 100644 --- a/modules/juce_gui_basics/native/juce_XWindowSystem_linux.cpp +++ b/modules/juce_gui_basics/native/juce_XWindowSystem_linux.cpp @@ -411,7 +411,9 @@ namespace Keys MiddleButton = 2, RightButton = 3, WheelUp = 4, - WheelDown = 5 + WheelDown = 5, + BackButton = 6, + ForwardButton = 7 }; static int AltMask = 0; @@ -2518,6 +2520,7 @@ ModifierKeys XWindowSystem::getNativeRealtimeModifiers() const XWindowSystemUtilities::ScopedXLock xLock; + // xQueryPointer doesn't emit masks for back/forward buttons. if (X11Symbols::getInstance()->xQueryPointer (display, X11Symbols::getInstance()->xRootWindow (display, X11Symbols::getInstance()->xDefaultScreen (display)), @@ -3077,26 +3080,24 @@ void XWindowSystem::setWindowType (::Window windowH, int styleFlags) const void XWindowSystem::initialisePointerMap() { - auto numButtons = X11Symbols::getInstance()->xGetPointerMapping (display, nullptr, 0); - pointerMap[2] = pointerMap[3] = pointerMap[4] = Keys::NoButton; + const auto numButtons = X11Symbols::getInstance()->xGetPointerMapping (display, nullptr, 0); + std::fill_n (pointerMap, std::size (pointerMap), Keys::NoButton); - if (numButtons == 2) - { - pointerMap[0] = Keys::LeftButton; - pointerMap[1] = Keys::RightButton; - } - else if (numButtons >= 3) - { - pointerMap[0] = Keys::LeftButton; - pointerMap[1] = Keys::MiddleButton; - pointerMap[2] = Keys::RightButton; + constexpr unsigned char twoButtons[] { Keys::LeftButton, Keys::RightButton }; + constexpr unsigned char moreButtons[] { Keys::LeftButton, + Keys::MiddleButton, + Keys::RightButton, + Keys::WheelUp, + Keys::WheelDown, + Keys::NoButton, + Keys::NoButton, + Keys::BackButton, + Keys::ForwardButton }; + static_assert (std::size (moreButtons) >= std::size (decltype (pointerMap){})); - if (numButtons >= 5) - { - pointerMap[3] = Keys::WheelUp; - pointerMap[4] = Keys::WheelDown; - } - } + auto* sourceArray = numButtons == 2 ? twoButtons : moreButtons; + const auto numToCopy = jmin (numButtons, (int) std::size (pointerMap)); + std::copy (sourceArray, sourceArray + numToCopy, pointerMap); } void XWindowSystem::deleteIconPixmaps (::Window windowH) const @@ -3620,6 +3621,9 @@ void XWindowSystem::handleButtonPressEvent (LinuxComponentPeer* peer, const XBut case Keys::LeftButton: handleButtonPressEvent (peer, buttonPressEvent, ModifierKeys::leftButtonModifier); break; case Keys::RightButton: handleButtonPressEvent (peer, buttonPressEvent, ModifierKeys::rightButtonModifier); break; case Keys::MiddleButton: handleButtonPressEvent (peer, buttonPressEvent, ModifierKeys::middleButtonModifier); break; + case Keys::BackButton: handleButtonPressEvent (peer, buttonPressEvent, ModifierKeys::backButtonModifier); break; + case Keys::ForwardButton: handleButtonPressEvent (peer, buttonPressEvent, ModifierKeys::forwardButtonModifier); break; + default: break; } } @@ -3638,9 +3642,12 @@ void XWindowSystem::handleButtonReleaseEvent (LinuxComponentPeer* peer, const XB { switch (pointerMap[mapIndex]) { - case Keys::LeftButton: ModifierKeys::currentModifiers = ModifierKeys::getCurrentModifiers().withoutFlags (ModifierKeys::leftButtonModifier); break; - case Keys::RightButton: ModifierKeys::currentModifiers = ModifierKeys::getCurrentModifiers().withoutFlags (ModifierKeys::rightButtonModifier); break; - case Keys::MiddleButton: ModifierKeys::currentModifiers = ModifierKeys::getCurrentModifiers().withoutFlags (ModifierKeys::middleButtonModifier); break; + case Keys::LeftButton: ModifierKeys::currentModifiers = ModifierKeys::getCurrentModifiers().withoutFlags (ModifierKeys::leftButtonModifier); break; + case Keys::RightButton: ModifierKeys::currentModifiers = ModifierKeys::getCurrentModifiers().withoutFlags (ModifierKeys::rightButtonModifier); break; + case Keys::MiddleButton: ModifierKeys::currentModifiers = ModifierKeys::getCurrentModifiers().withoutFlags (ModifierKeys::middleButtonModifier); break; + case Keys::BackButton: ModifierKeys::currentModifiers = ModifierKeys::getCurrentModifiers().withoutFlags (ModifierKeys::backButtonModifier); break; + case Keys::ForwardButton: ModifierKeys::currentModifiers = ModifierKeys::getCurrentModifiers().withoutFlags (ModifierKeys::forwardButtonModifier); break; + default: break; } } diff --git a/modules/juce_gui_basics/native/juce_XWindowSystem_linux.h b/modules/juce_gui_basics/native/juce_XWindowSystem_linux.h index e8733d1d21..7bc74527da 100644 --- a/modules/juce_gui_basics/native/juce_XWindowSystem_linux.h +++ b/modules/juce_gui_basics/native/juce_XWindowSystem_linux.h @@ -352,7 +352,7 @@ private: #endif int shmCompletionEvent = 0; - int pointerMap[5] = {}; + unsigned char pointerMap[9]{}; String localClipboardContent; Point parentScreenPosition; diff --git a/modules/juce_gui_basics/widgets/juce_ComboBox.cpp b/modules/juce_gui_basics/widgets/juce_ComboBox.cpp index c0cba0782e..cca35f1645 100644 --- a/modules/juce_gui_basics/widgets/juce_ComboBox.cpp +++ b/modules/juce_gui_basics/widgets/juce_ComboBox.cpp @@ -523,6 +523,9 @@ static void comboBoxPopupMenuFinishedCallback (int result, ComboBox* combo) if (result != 0) combo->setSelectedId (result); + + if (auto* handler = combo->getAccessibilityHandler()) + handler->grabFocus(); } } diff --git a/modules/juce_gui_basics/widgets/juce_ComboBox.h b/modules/juce_gui_basics/widgets/juce_ComboBox.h index ca0c89a9ae..fcae19d2f8 100644 --- a/modules/juce_gui_basics/widgets/juce_ComboBox.h +++ b/modules/juce_gui_basics/widgets/juce_ComboBox.h @@ -356,7 +356,7 @@ public: These constants can be used either via the Component::setColour(), or LookAndFeel::setColour() methods. - To change the colours of the menu that pops up, you can set the colour IDs in PopupMenu::ColourIDs. + To change the colours of the menu that pops up, you can set the colour IDs in PopupMenu::ColourIds. @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour */ diff --git a/modules/juce_gui_basics/windows/juce_VBlankAttachment.cpp b/modules/juce_gui_basics/windows/juce_VBlankAttachment.cpp index 27e71ec57b..ee0318d15a 100644 --- a/modules/juce_gui_basics/windows/juce_VBlankAttachment.cpp +++ b/modules/juce_gui_basics/windows/juce_VBlankAttachment.cpp @@ -80,9 +80,9 @@ VBlankAttachment::~VBlankAttachment() cleanup(); } -void VBlankAttachment::onVBlank (double timestampMs) +void VBlankAttachment::onVBlank (double timestampSec) { - NullCheckedInvocation::invoke (callback, timestampMs); + NullCheckedInvocation::invoke (callback, timestampSec); } void VBlankAttachment::componentParentHierarchyChanged (Component&) diff --git a/modules/juce_gui_basics/windows/juce_VBlankAttachment.h b/modules/juce_gui_basics/windows/juce_VBlankAttachment.h index 9b53aa1f6c..817bdc13ca 100644 --- a/modules/juce_gui_basics/windows/juce_VBlankAttachment.h +++ b/modules/juce_gui_basics/windows/juce_VBlankAttachment.h @@ -80,7 +80,7 @@ public: private: //============================================================================== - void onVBlank (double timestampMs) override; + void onVBlank (double timestampSec) override; //============================================================================== void componentParentHierarchyChanged (Component&) override; diff --git a/modules/juce_gui_extra/native/juce_XEmbedComponent_linux.cpp b/modules/juce_gui_extra/native/juce_XEmbedComponent_linux.cpp index 492e73d5bc..f2b48814a8 100644 --- a/modules/juce_gui_extra/native/juce_XEmbedComponent_linux.cpp +++ b/modules/juce_gui_extra/native/juce_XEmbedComponent_linux.cpp @@ -288,15 +288,76 @@ public: private: //============================================================================== + class ComponentIsShowingListener : private ComponentMovementWatcher + { + public: + ComponentIsShowingListener (Component& componentIn, std::function callbackIn) + : ComponentMovementWatcher (&componentIn), + callback (std::move (callbackIn)) + {} + + private: + void componentMovedOrResized (bool, bool) override {} + void componentPeerChanged() override {} + void componentVisibilityChanged() override { NullCheckedInvocation::invoke (callback); } + + using ComponentMovementWatcher::componentMovedOrResized; + using ComponentMovementWatcher::componentVisibilityChanged; + + std::function callback; + }; + + class WindowMapper + { + public: + WindowMapper (Pimpl& pimplIn, Window& windowIn) + : pimpl (pimplIn), + window (windowIn) + {} + + void update() + { + if (window == 0) + return; + + const auto shouldBeMapped = pimpl.getXEmbedMappedFlag() + && pimpl.owner.isShowing() + && pimpl.lastPeer != nullptr; + + if (std::exchange (mapped, shouldBeMapped) != shouldBeMapped) + { + if (shouldBeMapped) + X11Symbols::getInstance()->xMapWindow (pimpl.getDisplay(), window); + else + X11Symbols::getInstance()->xUnmapWindow (pimpl.getDisplay(), window); + } + } + + void unmap() + { + if (window == 0) + return; + + X11Symbols::getInstance()->xUnmapWindow (pimpl.getDisplay(), window); + mapped = false; + } + + private: + Pimpl& pimpl; + Window& window; + bool mapped = false; + }; + XEmbedComponent& owner; + ComponentIsShowingListener isShowingListener { owner, [this] { updateMapping(); } }; Window client = 0, host = 0; + WindowMapper clientMapper { *this, client }, hostMapper { *this, host }; Atom infoAtom, messageTypeAtom; bool clientInitiated; bool wantsFocus = false; bool allowResize = false; bool supportsXembed = false; - bool hasBeenMapped = false; int xembedVersion = maxXEmbedVersionToSupport; ComponentPeer* lastPeer = nullptr; @@ -369,11 +430,8 @@ private: int defaultScreen = X11Symbols::getInstance()->xDefaultScreen (dpy); Window root = X11Symbols::getInstance()->xRootWindow (dpy, defaultScreen); - if (hasBeenMapped) - { - X11Symbols::getInstance()->xUnmapWindow (dpy, client); - hasBeenMapped = false; - } + hostMapper.unmap(); + clientMapper.unmap(); X11Symbols::getInstance()->xReparentWindow (dpy, client, root, 0, 0); client = 0; @@ -384,20 +442,8 @@ private: void updateMapping() { - if (client != 0) - { - const bool shouldBeMapped = getXEmbedMappedFlag(); - - if (shouldBeMapped != hasBeenMapped) - { - hasBeenMapped = shouldBeMapped; - - if (shouldBeMapped) - X11Symbols::getInstance()->xMapWindow (getDisplay(), client); - else - X11Symbols::getInstance()->xUnmapWindow (getDisplay(), client); - } - } + hostMapper.update(); + clientMapper.update(); } Window getParentX11Window() @@ -496,7 +542,7 @@ private: Rectangle newBounds = getX11BoundsFromJuce(); if (newPeer == nullptr) - X11Symbols::getInstance()->xUnmapWindow (dpy, host); + hostMapper.unmap(); Window newParent = (newPeer != nullptr ? getParentX11Window() : rootWindow); X11Symbols::getInstance()->xReparentWindow (dpy, host, newParent, newBounds.getX(), newBounds.getY()); @@ -512,7 +558,7 @@ private: } componentMovedOrResized (owner, true, true); - X11Symbols::getInstance()->xMapWindow (dpy, host); + updateMapping(); broughtToFront(); } diff --git a/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp b/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp index 8fcb1babc7..9289f8acdc 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp @@ -1797,9 +1797,9 @@ struct SavedState final : public RenderingHelpers::SavedStateBase previousTarget (createCopyIfNotNull (other.previousTarget.get())) {} - SavedState* beginTransparencyLayer (float opacity) + std::unique_ptr beginTransparencyLayer (float opacity) { - auto* s = new SavedState (*this); + auto s = std::make_unique (*this); if (clip != nullptr) { @@ -1834,6 +1834,8 @@ struct SavedState final : public RenderingHelpers::SavedStateBase clip->renderImageUntransformed (*this, finishedLayerState.transparencyLayer, (int) (finishedLayerState.transparencyLayerAlpha * 255.0f), clipBounds.getX(), clipBounds.getY(), false); + + state->activeTextures.bindTexture (0); } } diff --git a/modules/juce_video/native/juce_CameraDevice_android.h b/modules/juce_video/native/juce_CameraDevice_android.h index 62de170823..55499e26a8 100644 --- a/modules/juce_video/native/juce_CameraDevice_android.h +++ b/modules/juce_video/native/juce_CameraDevice_android.h @@ -490,8 +490,7 @@ private: }; //============================================================================== -struct CameraDevice::Pimpl - : private ActivityLifecycleCallbacks +struct CameraDevice::Pimpl : private ActivityLifecycleCallbacks { using InternalOpenCameraResultCallback = std::function; @@ -504,7 +503,6 @@ struct CameraDevice::Pimpl maxWidth (maxWidthToUse), maxHeight (maxHeightToUse), cameraId (cameraIdToUse), - activityLifeListener (CreateJavaInterface (this, "android/app/Application$ActivityLifecycleCallbacks")), cameraManager (initialiseCameraManager()), cameraCharacteristics (initialiseCameraCharacteristics (cameraManager, cameraId)), streamConfigurationMap (cameraCharacteristics), @@ -516,10 +514,7 @@ struct CameraDevice::Pimpl ~Pimpl() override { - auto* env = getEnv(); - - env->CallVoidMethod (getAppContext().get(), AndroidApplication.unregisterActivityLifecycleCallbacks, activityLifeListener.get()); - activityLifeListener.clear(); + callbackForwarder.reset(); } JUCE_DECLARE_WEAK_REFERENCEABLE (Pimpl) @@ -551,7 +546,7 @@ struct CameraDevice::Pimpl { if (granted) { - getEnv()->CallVoidMethod (getAppContext().get(), AndroidApplication.registerActivityLifecycleCallbacks, activityLifeListener.get()); + callbackForwarder.emplace (GlobalRef { getAppContext() }, static_cast (this)); scopedCameraDevice.reset (new ScopedCameraDevice (*this, cameraId, cameraManager, handler, getAutoFocusModeToUse())); } else @@ -2809,7 +2804,7 @@ private: String cameraId; InternalOpenCameraResultCallback cameraOpenCallback; - GlobalRef activityLifeListener; + std::optional callbackForwarder; GlobalRef cameraManager; GlobalRef cameraCharacteristics; diff --git a/modules/juce_video/native/juce_Video_android.h b/modules/juce_video/native/juce_Video_android.h index 12cbf5c61b..aa1a50c1e6 100644 --- a/modules/juce_video/native/juce_Video_android.h +++ b/modules/juce_video/native/juce_Video_android.h @@ -344,8 +344,9 @@ private: }; //============================================================================== -struct VideoComponent::Pimpl - : public AndroidViewComponent, private ActivityLifecycleCallbacks, private SurfaceHolderCallback +struct VideoComponent::Pimpl : public AndroidViewComponent, + private ActivityLifecycleCallbacks, + private SurfaceHolderCallback { Pimpl (VideoComponent& ownerToUse, bool) : owner (ownerToUse), @@ -360,14 +361,6 @@ struct VideoComponent::Pimpl LocalRef appContext (getAppContext()); - if (appContext != nullptr) - { - ActivityLifecycleCallbacks* callbacks = dynamic_cast (this); - - activityLifeListener = GlobalRef (CreateJavaInterface (callbacks, "android/app/Application$ActivityLifecycleCallbacks")); - env->CallVoidMethod (appContext.get(), AndroidApplication.registerActivityLifecycleCallbacks, activityLifeListener.get()); - } - { LocalRef surfaceView (env->NewObject (AndroidSurfaceView, AndroidSurfaceView.constructor, getAppContext().get())); LocalRef holder (env->CallObjectMethod (surfaceView.get(), AndroidSurfaceView.getHolder)); @@ -397,13 +390,6 @@ struct VideoComponent::Pimpl surfaceHolderCallback.clear(); } } - - if (activityLifeListener != nullptr) - { - env->CallVoidMethod (getAppContext().get(), AndroidApplication.unregisterActivityLifecycleCallbacks, activityLifeListener.get()); - ActivityLifecycleCallbacks::clear(); - activityLifeListener.clear(); - } } void loadAsync (const URL& url, std::function callback) @@ -1696,7 +1682,7 @@ private: VideoComponent& owner; MediaSession mediaSession; - GlobalRef activityLifeListener; + ActivityLifecycleCallbackForwarder forwarder { GlobalRef { getAppContext() }, this }; #if JUCE_SYNC_VIDEO_VOLUME_WITH_OS_MEDIA_VOLUME SystemVolumeListener systemVolumeListener; #endif