From b1e19da5f512ec9a2c6c7c15bd1967327c218097 Mon Sep 17 00:00:00 2001 From: Sudara Date: Wed, 16 Jul 2025 17:01:08 +0200 Subject: [PATCH 01/50] Docs: Improve CMake API docs * Add LV2 to FORMATS (thx @FigBug). * Add more property defaults. * Update examples to use lowest supported iOS CMAKE_OSX_DEPLOYMENT_TARGET. * Formatting consistency and general cleanup. --- docs/CMake API.md | 214 +++++++++++++++++++++++++--------------------- 1 file changed, 117 insertions(+), 97 deletions(-) diff --git a/docs/CMake API.md b/docs/CMake API.md index 6959794bc9..63ec4224b5 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` @@ -431,13 +435,16 @@ attributes directly to these creation functions, rather than adding them later. if you get linker or include errors that reference StoreKit, just set this argument to `TRUE`. `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 @@ -445,11 +452,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 @@ -473,8 +481,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` @@ -482,8 +490,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` @@ -495,71 +503,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`, @@ -570,42 +587,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 @@ -641,8 +661,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. @@ -665,22 +685,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. @@ -752,10 +772,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` @@ -822,7 +842,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 From 79ded8c1f3917b012afb197f2299ace6c357c35d Mon Sep 17 00:00:00 2001 From: attila Date: Wed, 23 Jul 2025 14:17:34 +0200 Subject: [PATCH 02/50] PopupMenu: Fix accessibility issue where ticked items couldn't be pressed The issue became manifest in c51b331318aff1485df862694bd562c3bae1a62f. In our implementation the toggle action takes precedence over the press action, making the latter unreachable when the Item is in a checkable state. Calling isTicked (true) turns the Item into a checkable object. The onToggle implementation however didn't interact with the isTicked state, and it didn't fire the press action either. This made the item non-interactable with screen readers once it got into a ticked state. --- modules/juce_gui_basics/menus/juce_PopupMenu.cpp | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) 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)) { From 8f30ba70ccf010ef7a034465317bd796bc33bdd5 Mon Sep 17 00:00:00 2001 From: attila Date: Fri, 25 Jul 2025 17:32:34 +0200 Subject: [PATCH 03/50] Tidying --- modules/juce_gui_basics/widgets/juce_ComboBox.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 */ From b674a4c130cea75989c205c052e0da6c07764ad1 Mon Sep 17 00:00:00 2001 From: attila Date: Mon, 14 Jul 2025 16:26:35 +0200 Subject: [PATCH 04/50] Tidying: Change misleading variable name --- modules/juce_gui_basics/windows/juce_VBlankAttachment.cpp | 4 ++-- modules/juce_gui_basics/windows/juce_VBlankAttachment.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) 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; From 5bc44c301f61e95608aa24e1048e4d4ac68d2b48 Mon Sep 17 00:00:00 2001 From: attila Date: Wed, 16 Jul 2025 17:40:41 +0200 Subject: [PATCH 05/50] Make Direct2DGraphicsContextTests acceptance criteria stricter --- .../native/juce_Direct2DGraphicsContext_windows.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp b/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp index e05a643717..534c1ab239 100644 --- a/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp +++ b/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp @@ -1340,6 +1340,7 @@ public: 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{}; @@ -1352,14 +1353,18 @@ public: 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); } }; From 3f898f6fee85e179e8940e3ccb16dc6b8d5a4301 Mon Sep 17 00:00:00 2001 From: attila Date: Tue, 15 Jul 2025 17:53:25 +0200 Subject: [PATCH 06/50] Direct2D: Fix jitter when drawing bitmaps with non-unity scaling Reverts ca3abbb96d637085a6c367b0efc4dc6c0091c1de. Prior to this fix gradually changing the Component scale would lead to the jittery movement of drawn bitmaps, as their position would be snapped to an arbitrary integral representation. --- .../native/juce_Direct2DGraphicsContext_windows.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp b/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp index 534c1ab239..05d6b346ec 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)); From 19906c9d2f97a9bba515258bdee4531439c6b2d8 Mon Sep 17 00:00:00 2001 From: attila Date: Wed, 16 Jul 2025 19:13:10 +0200 Subject: [PATCH 07/50] Direct2DGraphicsContextTests: Ignore the image edges to allow for differences in anti-aliasing --- .../juce_Direct2DGraphicsContext_windows.cpp | 32 ++++++++++++++++--- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp b/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp index 05d6b346ec..2e36356242 100644 --- a/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp +++ b/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp @@ -1327,13 +1327,34 @@ 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); } } } } - 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()); @@ -1344,10 +1365,13 @@ public: 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); From f97355b9f650d018062f26f8f955e86e669b822a Mon Sep 17 00:00:00 2001 From: attila Date: Wed, 16 Jul 2025 19:13:44 +0200 Subject: [PATCH 08/50] Direct2D: Fix seams between tiles for large bitmaps --- .../juce_Direct2DGraphicsContext_windows.cpp | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp b/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp index 2e36356242..9cd61bee03 100644 --- a/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp +++ b/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp @@ -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); } } }; @@ -1337,6 +1344,42 @@ public: } } } + + 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); + } } static Image createEdgeMask (int sourceWidth, From 242405323e3ae2de8f7dfbb45fa99dd4833a6120 Mon Sep 17 00:00:00 2001 From: attila Date: Fri, 25 Jul 2025 17:29:36 +0200 Subject: [PATCH 09/50] ComboBox: Fix accessibility navigation when the PopupMenu has a parent component With the PopupMenu creating its own window the focus would return to the ComboBox after activating a menu item. Prior to this commit however the focus was seemingly lost after menu item activation. With this change the focus returns to the ComboBox in both cases. --- modules/juce_gui_basics/widgets/juce_ComboBox.cpp | 3 +++ 1 file changed, 3 insertions(+) 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(); } } From 11752d061f29cd72e04e18ec5b9697fa6807ddc5 Mon Sep 17 00:00:00 2001 From: reuk Date: Mon, 28 Jul 2025 12:50:21 +0100 Subject: [PATCH 10/50] Android: Refactor to use inline statics --- .../native/juce_Windowing_android.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/modules/juce_gui_basics/native/juce_Windowing_android.cpp b/modules/juce_gui_basics/native/juce_Windowing_android.cpp index 22f446f709..961eebb4c6 100644 --- a/modules/juce_gui_basics/native/juce_Windowing_android.cpp +++ b/modules/juce_gui_basics/native/juce_Windowing_android.cpp @@ -2089,8 +2089,8 @@ public: } //============================================================================== - static Point lastMousePos; - static int64 touchesDown; + inline static Point lastMousePos{}; + inline static int64 touchesDown = 0; //============================================================================== struct StartupActivityCallbackListener final : public ActivityLifecycleCallbacks @@ -2529,8 +2529,8 @@ private: //============================================================================== friend class Displays; - static AndroidComponentPeer* frontWindow; - static GlobalRef activityCallbackListener; + inline static AndroidComponentPeer* frontWindow = nullptr; + inline static GlobalRef activityCallbackListener; static constexpr jint GRAVITY_LEFT = 0x3, GRAVITY_TOP = 0x30; static constexpr jint TYPE_APPLICATION = 0x2; @@ -2550,11 +2550,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) { From 1c2eb2d0568da3719fd5894f9a329001e37ee41f Mon Sep 17 00:00:00 2001 From: reuk Date: Mon, 28 Jul 2025 12:52:16 +0100 Subject: [PATCH 11/50] Android: Refactor lifecycle callbacks to reduce repetition in lifecycle listener registration --- .../native/juce_JNIHelpers_android.cpp | 19 ++++- .../native/juce_JNIHelpers_android.h | 20 +++++- .../juce_core/native/juce_Threads_android.cpp | 26 +------ .../native/juce_Messaging_android.cpp | 24 +------ .../native/juce_Windowing_android.cpp | 69 ++++--------------- .../native/juce_CameraDevice_android.h | 13 ++-- .../juce_video/native/juce_Video_android.h | 22 ++---- 7 files changed, 56 insertions(+), 137 deletions(-) diff --git a/modules/juce_core/native/juce_JNIHelpers_android.cpp b/modules/juce_core/native/juce_JNIHelpers_android.cpp index dd8d55147f..32bd98b18b 100644 --- a/modules/juce_core/native/juce_JNIHelpers_android.cpp +++ b/modules/juce_core/native/juce_JNIHelpers_android.cpp @@ -429,7 +429,22 @@ 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 (CreateJavaInterface (this, "android/app/Application$ActivityLifecycleCallbacks")), + 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(); @@ -475,7 +490,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 543a11aed0..e4ab1591d3 100644 --- a/modules/juce_core/native/juce_JNIHelpers_android.h +++ b/modules/juce_core/native/juce_JNIHelpers_android.h @@ -1016,9 +1016,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*/) {} @@ -1044,15 +1046,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 d17318e09a..d1e16bad22 100644 --- a/modules/juce_core/native/juce_Threads_android.cpp +++ b/modules/juce_core/native/juce_Threads_android.cpp @@ -111,33 +111,9 @@ class JuceActivityWatcher final : public ActivityLifecycleCallbacks public: JuceActivityWatcher() { - 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()); - } - checkActivityIsMain (androidApkContext); } - ~JuceActivityWatcher() override - { - LocalRef 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(); @@ -273,10 +249,10 @@ private: return mainActivityClassPath; } - GlobalRef myself; CriticalSection currentActivityLock; jweak currentActivity = nullptr; jweak mainActivity = nullptr; + ActivityLifecycleCallbackForwarder forwarder { GlobalRef { getAppContext() }, this }; }; //============================================================================== diff --git a/modules/juce_events/native/juce_Messaging_android.cpp b/modules/juce_events/native/juce_Messaging_android.cpp index eb559d06ca..061bd52c1a 100644 --- a/modules/juce_events/native/juce_Messaging_android.cpp +++ b/modules/juce_events/native/juce_Messaging_android.cpp @@ -183,29 +183,6 @@ public: JuceAppLifecycle (juce::JUCEApplicationBase* (*initSymbolAddr)()) : createApplicationSymbol (initSymbolAddr) { - 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()); - } - } - - ~JuceAppLifecycle() override - { - LocalRef 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 @@ -292,6 +269,7 @@ private: GlobalRef myself; juce::JUCEApplicationBase* (*createApplicationSymbol)(); bool hasBeenInitialised = false; + ActivityLifecycleCallbackForwarder forwarder { GlobalRef { getAppContext() }, this }; }; //============================================================================== diff --git a/modules/juce_gui_basics/native/juce_Windowing_android.cpp b/modules/juce_gui_basics/native/juce_Windowing_android.cpp index 961eebb4c6..da2befc2f9 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) @@ -2097,20 +2098,12 @@ public: { 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 @@ -2530,7 +2523,7 @@ private: //============================================================================== friend class Displays; inline static AndroidComponentPeer* frontWindow = nullptr; - inline static GlobalRef activityCallbackListener; + inline static std::optional startupActivityCallbackListener; static constexpr jint GRAVITY_LEFT = 0x3, GRAVITY_TOP = 0x30; static constexpr jint TYPE_APPLICATION = 0x2; @@ -2562,37 +2555,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; } @@ -2625,8 +2591,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) @@ -2972,20 +2938,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_video/native/juce_CameraDevice_android.h b/modules/juce_video/native/juce_CameraDevice_android.h index 125a2c1ec7..dcbaec988a 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 4c3e386b99..de869f092c 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 From c34208b3b0bc05d769090a8eb5d00c1218338bcb Mon Sep 17 00:00:00 2001 From: reuk Date: Mon, 28 Jul 2025 13:48:59 +0100 Subject: [PATCH 12/50] Android: Fix formatting in JuceInvocationHandler.java --- .../com/rmsl/juce/JuceInvocationHandler.java | 50 +++++----- .../native/juce_JNIHelpers_android.cpp | 96 ++++++++++++++----- 2 files changed, 98 insertions(+), 48 deletions(-) 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 32bd98b18b..4c922cfbc8 100644 --- a/modules/juce_core/native/juce_JNIHelpers_android.cpp +++ b/modules/juce_core/native/juce_JNIHelpers_android.cpp @@ -36,29 +36,79 @@ 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 +}; //============================================================================== #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ From be8a5f72cc53face722090a7479d257761c88f86 Mon Sep 17 00:00:00 2001 From: reuk Date: Mon, 28 Jul 2025 13:49:56 +0100 Subject: [PATCH 13/50] Android: Add new ActivityLifecycleCallbacks base class --- .../rmsl/juce/JuceActivityCallbacksBase.java | 63 +++++++++++++++ .../native/juce_JNIHelpers_android.cpp | 78 ++++++++++++++++++- 2 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 modules/juce_core/native/java/app/com/rmsl/juce/JuceActivityCallbacksBase.java 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/juce_JNIHelpers_android.cpp b/modules/juce_core/native/juce_JNIHelpers_android.cpp index 4c922cfbc8..be5f790b93 100644 --- a/modules/juce_core/native/juce_JNIHelpers_android.cpp +++ b/modules/juce_core/native/juce_JNIHelpers_android.cpp @@ -110,6 +110,69 @@ constexpr uint8 invocationHandleByteCode[] 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) \ STATICMETHOD (newProxyInstance, "newProxyInstance", "(Ljava/lang/ClassLoader;[Ljava/lang/Class;Ljava/lang/reflect/InvocationHandler;)Ljava/lang/Object;") \ @@ -146,6 +209,12 @@ constexpr 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 { @@ -481,7 +550,14 @@ void juce_dispatchDelete (JNIEnv*, jobject /*object*/, jlong host) //============================================================================== ActivityLifecycleCallbackForwarder::ActivityLifecycleCallbackForwarder (GlobalRef ctx, ActivityLifecycleCallbacks* cb) : appContext (ctx), - myself (CreateJavaInterface (this, "android/app/Application$ActivityLifecycleCallbacks")), + 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) From 0c2d55c7dd16906fe78549f40642f4be4843cf98 Mon Sep 17 00:00:00 2001 From: attila Date: Mon, 28 Jul 2025 19:05:46 +0200 Subject: [PATCH 14/50] Linux: Fix XEmbedComponent::setVisible This also affects the WebBrowserComponent. Prior to this fix calling setVisible (false) had no effect. --- .../native/juce_XEmbedComponent_linux.cpp | 90 ++++++++++++++----- 1 file changed, 68 insertions(+), 22 deletions(-) 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(); } From 2cbcbc888218f876bfacb840b450d7cba6c52ae3 Mon Sep 17 00:00:00 2001 From: reuk Date: Tue, 29 Jul 2025 13:24:14 +0100 Subject: [PATCH 15/50] iOS: Update Info.plist generation to include UIApplicationSceneManifest This suppresses the "Info.plist contained no UIScene configuration dictionary" warning, raised at runtime in the Xcode console. --- examples/DemoRunner/Builds/iOS/Info-App.plist | 7 +++++++ extras/AudioPerformanceTest/Builds/iOS/Info-App.plist | 7 +++++++ extras/AudioPluginHost/Builds/iOS/Info-App.plist | 7 +++++++ .../Build/juce_build_tools/utils/juce_PlistOptions.cpp | 9 +++++++++ extras/NetworkGraphicsDemo/Builds/iOS/Info-App.plist | 7 +++++++ 5 files changed, 37 insertions(+) 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/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/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/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/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 From b272f968aa5dbff7afab26162e9b978fa2b4f5c3 Mon Sep 17 00:00:00 2001 From: reuk Date: Tue, 29 Jul 2025 15:26:21 +0100 Subject: [PATCH 16/50] NativeMessageBox (iOS): Delay lookup of focused peer Before 2c5b1fbb6f91ba9ffb03a82449edf678b8f2654f, we only queried currentlyFocusedPeer during runAsync(), instead of reading it immediately. The behaviour after that commit prevented message boxes from showing if showMessageBoxAsync() was called before any peer had been created. --- .../native/juce_NativeMessageBox_ios.mm | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) 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) }; From b95ede49ff0ab2bd1698ee534b55ede179468eb1 Mon Sep 17 00:00:00 2001 From: attila Date: Tue, 12 Aug 2025 16:21:33 +0200 Subject: [PATCH 17/50] Fix calling FileListComponent::setSelectedFile after DirectoryContentsList::setDirectory Prior to this fix calling setDirectory and then setSelectedFile from the same call stack could cause setSelectedFile to have no effect. This was because the directory change is asynchronously propagated from the DirectoryContentsList. This was picked up by the FileListComponent as a directory change after setSelectedFile, even though the directory change happened before. --- modules/juce_gui_basics/filebrowser/juce_FileListComponent.cpp | 2 ++ 1 file changed, 2 insertions(+) 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;) From 5b4fca7bd0a5e7aafc3c9fd1c13529a56d4ae78c Mon Sep 17 00:00:00 2001 From: Anthony Nicholls Date: Sat, 9 Aug 2025 12:18:03 +0100 Subject: [PATCH 18/50] String: Fix a bug in calculating the number of significant digits for exact powers of 10 --- modules/juce_core/text/juce_String.cpp | 14 ++++++++++++++ modules/juce_core/text/juce_String.h | 9 ++++----- 2 files changed, 18 insertions(+), 5 deletions(-) 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; From 7a30354ce9cf2e12dba5bcb9da47dd944ee6c730 Mon Sep 17 00:00:00 2001 From: Oliver James Date: Wed, 25 Jun 2025 15:02:48 +0100 Subject: [PATCH 19/50] TextLayout: Enforce character wrapping attribute --- modules/juce_graphics/fonts/juce_TextLayout.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/juce_graphics/fonts/juce_TextLayout.cpp b/modules/juce_graphics/fonts/juce_TextLayout.cpp index 573430e0fc..df605ca567 100644 --- a/modules/juce_graphics/fonts/juce_TextLayout.cpp +++ b/modules/juce_graphics/fonts/juce_TextLayout.cpp @@ -421,6 +421,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; From 8dc4dcd56b03de995506d1a23e91b1d66d469772 Mon Sep 17 00:00:00 2001 From: Oli Date: Thu, 7 Aug 2025 15:17:01 +0100 Subject: [PATCH 20/50] TextLayout: Implement better line balancing algorithm The previous implementation was unstable when 'by character' line breaking was used on long lines of text. Co-authored-by: Tom Poole --- .../juce_graphics/fonts/juce_TextLayout.cpp | 65 ++++++++++++++----- 1 file changed, 49 insertions(+), 16 deletions(-) diff --git a/modules/juce_graphics/fonts/juce_TextLayout.cpp b/modules/juce_graphics/fonts/juce_TextLayout.cpp index df605ca567..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); } //============================================================================== From 8741f900e72522fa8481d20487d85df1d8496a0d Mon Sep 17 00:00:00 2001 From: Oli Date: Fri, 1 Aug 2025 15:48:25 +0100 Subject: [PATCH 21/50] TooltipWindow: Enable by-char breaking for the tooltip text --- modules/juce_gui_basics/detail/juce_LookAndFeelHelpers.h | 1 + 1 file changed, 1 insertion(+) 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); From df99869d235099d5191169892721a1f9c79b18bf Mon Sep 17 00:00:00 2001 From: Oli Date: Fri, 18 Jul 2025 14:11:52 +0100 Subject: [PATCH 22/50] ModifierKeys: Add support for back and forward mouse buttons --- .../keyboard/juce_ModifierKeys.cpp | 2 ++ .../juce_gui_basics/keyboard/juce_ModifierKeys.h | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) 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 From d390db8eef10b40bff07478b11edaf62852623aa Mon Sep 17 00:00:00 2001 From: Oli Date: Fri, 18 Jul 2025 14:12:35 +0100 Subject: [PATCH 23/50] Windows: Implement support for extra mouse buttons --- modules/juce_gui_basics/native/juce_Windowing_windows.cpp | 4 ++++ 1 file changed, 4 insertions(+) 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; From c01bf65d3fe5ec5f01c0921fd73b0b8fe5265e43 Mon Sep 17 00:00:00 2001 From: Oliver James Date: Fri, 27 Jun 2025 13:09:39 +0100 Subject: [PATCH 24/50] MacOS: Implement support for extra mouse buttons --- .../native/juce_NSViewComponentPeer_mac.mm | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) 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 From fa6fa9a61ab23cbd8d81d0dd27acccde62d93e10 Mon Sep 17 00:00:00 2001 From: Oliver James Date: Fri, 27 Jun 2025 14:06:51 +0100 Subject: [PATCH 25/50] Linux: Implement support for extra mouse buttons --- .../native/juce_XWindowSystem_linux.cpp | 51 +++++++++++-------- .../native/juce_XWindowSystem_linux.h | 2 +- 2 files changed, 30 insertions(+), 23 deletions(-) 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; From fa0ed2801dd8b081d83a851411286f41f6fd4417 Mon Sep 17 00:00:00 2001 From: attila Date: Wed, 13 Aug 2025 17:05:32 +0200 Subject: [PATCH 26/50] Fix J8 vertical text placement regression in the software renderer --- modules/juce_graphics/native/juce_RenderingHelpers.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/juce_graphics/native/juce_RenderingHelpers.h b/modules/juce_graphics/native/juce_RenderingHelpers.h index c6436a4a9d..7db4ac7539 100644 --- a/modules/juce_graphics/native/juce_RenderingHelpers.h +++ b/modules/juce_graphics/native/juce_RenderingHelpers.h @@ -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)) { From aebba3c875db47b09292c90cd71096cbed9226d4 Mon Sep 17 00:00:00 2001 From: reuk Date: Wed, 30 Jul 2025 13:37:59 +0100 Subject: [PATCH 27/50] AAX Client: Manually declare compatibility with all channel layouts for MIDI FX Previously, MIDI FX plugins would only load on mono tracks. Now, we add a separate plugin description for each potential track layout. This is the same approach used by the example MIDI FX from the AAX SDK. --- .../juce_audio_plugin_client_AAX.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) 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 From b5ea607dcc128a40a7f9f5812c5e22b545285041 Mon Sep 17 00:00:00 2001 From: reuk Date: Wed, 30 Jul 2025 15:57:01 +0100 Subject: [PATCH 28/50] AU Host: Avoid potential UB reads of MIDI data --- .../format_types/juce_AudioUnitPluginFormat.mm | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) 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(); From 0fb62bd24048d618ee9b5ab2f08e43d4dd425d9f Mon Sep 17 00:00:00 2001 From: reuk Date: Tue, 5 Aug 2025 11:54:37 +0100 Subject: [PATCH 29/50] AU: Refactor getAUChannelInfo to reduce duplication --- .../format_types/juce_AU_Shared.h | 38 +++++++++---------- 1 file changed, 18 insertions(+), 20 deletions(-) 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 11ed907270..3cf11e3afe 100644 --- a/modules/juce_audio_processors/format_types/juce_AU_Shared.h +++ b/modules/juce_audio_processors/format_types/juce_AU_Shared.h @@ -440,31 +440,29 @@ struct AudioUnitHelpers } } - auto hasUnsupportedInput = ! hasMainInputBus, hasUnsupportedOutput = ! hasMainOutputBus; - - for (auto inChanNum = hasMainInputBus ? 1 : 0; inChanNum <= (hasMainInputBus ? maxNumChanToCheckFor : 0); ++inChanNum) + const auto computeHasUnsupportedLayout = [&] (bool isInput) { - Channels channelConfiguration { static_cast (inChanNum), - static_cast (hasInOutMismatch ? defaultOutputs : inChanNum) }; + const auto hasMainBus = isInput ? hasMainInputBus : hasMainOutputBus; + const auto begin = hasMainBus ? 1 : 0; + const auto end = hasMainBus ? maxNumChanToCheckFor : 0; - if (! supportedChannels.contains (channelConfiguration)) + for (auto chan = begin; chan <= end; ++chan) { - hasUnsupportedInput = true; - break; - } - } + const Channels channelConfig + { + static_cast (! isInput && hasInOutMismatch ? defaultInputs : chan), + static_cast ( isInput && hasInOutMismatch ? defaultOutputs : chan) + }; - 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)) - { - hasUnsupportedOutput = true; - break; + if (! supportedChannels.contains (channelConfig)) + return true; } - } + + return ! hasMainBus; + }; + + const auto hasUnsupportedInput = computeHasUnsupportedLayout (true); + const auto hasUnsupportedOutput = computeHasUnsupportedLayout (false); for (const auto& supported : supportedChannels) { From 7e3aae3cb9cb5e61ecf6a297b8fd8544a76f36c4 Mon Sep 17 00:00:00 2001 From: reuk Date: Tue, 5 Aug 2025 12:36:03 +0100 Subject: [PATCH 30/50] AU: Refactor getAUChannelInfo to make mismatch checking more concise --- .../format_types/juce_AU_Shared.h | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) 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 3cf11e3afe..669796f633 100644 --- a/modules/juce_audio_processors/format_types/juce_AU_Shared.h +++ b/modules/juce_audio_processors/format_types/juce_AU_Shared.h @@ -429,16 +429,9 @@ struct AudioUnitHelpers } } - auto hasInOutMismatch = false; - - for (const auto& supported : supportedChannels) - { - if (supported.ins != supported.outs) - { - hasInOutMismatch = true; - break; - } - } + const auto hasInOutMismatch = std::any_of (supportedChannels.begin(), + supportedChannels.end(), + [] (const Channels& x) { return x.ins != x.outs; }); const auto computeHasUnsupportedLayout = [&] (bool isInput) { From 35d3fab960a274820c48b14ffdbfe533a7983fa8 Mon Sep 17 00:00:00 2001 From: reuk Date: Tue, 5 Aug 2025 18:08:37 +0100 Subject: [PATCH 31/50] AU Client: Improve AUChannelInfo reporting and add tests The previous implementation could emit 'wildcard' channel layouts in too many scenarios. A wildcard channel count is -1 or -2, and indicates that any number of channels is supported on the bus. If the input and output layouts must match, then a layout of [-1, -1] should be returned. If any layout is valid in both directions, then a layout of [-1, -2] should be returned. In the case where we have a bus A and opposite bus B, we will now only emit a wildcard count for bus A if every bus standard bus layout up to a channel count of 16 can be applied successfully without changing the bus count of B. --- .../Builds/Android/app/CMakeLists.txt | 6 +- .../DemoRunner/Builds/LinuxMakefile/Makefile | 4 +- .../DemoRunner.xcodeproj/project.pbxproj | 6 + .../VisualStudio2019/DemoRunner_App.vcxproj | 11 +- .../DemoRunner_App.vcxproj.filters | 3 + .../VisualStudio2022/DemoRunner_App.vcxproj | 11 +- .../DemoRunner_App.vcxproj.filters | 3 + .../DemoRunner/Builds/iOS/App.entitlements | 2 + .../iOS/DemoRunner.xcodeproj/project.pbxproj | 4 +- examples/DemoRunner/CMakeLists.txt | 1 + examples/DemoRunner/DemoRunner.jucer | 3 +- .../Builds/Android/app/CMakeLists.txt | 2 + .../AudioPerformanceTest_App.vcxproj | 3 + .../AudioPerformanceTest_App.vcxproj.filters | 3 + .../Builds/Android/app/CMakeLists.txt | 2 + .../AudioPluginHost_App.vcxproj | 3 + .../AudioPluginHost_App.vcxproj.filters | 3 + .../AudioPluginHost_App.vcxproj | 3 + .../AudioPluginHost_App.vcxproj.filters | 3 + .../Builds/Android/app/CMakeLists.txt | 2 + .../NetworkGraphicsDemo_App.vcxproj | 3 + .../NetworkGraphicsDemo_App.vcxproj.filters | 3 + .../UnitTestRunner_ConsoleApp.vcxproj | 3 + .../UnitTestRunner_ConsoleApp.vcxproj.filters | 3 + .../UnitTestRunner_ConsoleApp.vcxproj | 3 + .../UnitTestRunner_ConsoleApp.vcxproj.filters | 3 + extras/UnitTestRunner/CMakeLists.txt | 1 + .../WindowsDLL_DynamicLibrary.vcxproj | 3 + .../WindowsDLL_DynamicLibrary.vcxproj.filters | 3 + .../juce_audio_plugin_client_AU_1.mm | 7 +- .../juce_audio_plugin_client_AUv3.mm | 8 +- .../format_types/juce_AU_Shared.h | 232 +++++++------ .../juce_AudioUnitPluginFormat_test.cpp | 308 ++++++++++++++++++ .../juce_audio_processors.cpp | 4 + 34 files changed, 547 insertions(+), 115 deletions(-) create mode 100644 modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat_test.cpp diff --git a/examples/DemoRunner/Builds/Android/app/CMakeLists.txt b/examples/DemoRunner/Builds/Android/app/CMakeLists.txt index 7d1df29077..53405c352d 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() @@ -782,6 +782,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" @@ -3443,6 +3444,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" 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 f1a1501633..ca973b4fb1 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 @@ -990,6 +990,9 @@ true + + true + true diff --git a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters index b176171d2c..a36e352160 100644 --- a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters +++ b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters @@ -1693,6 +1693,9 @@ JUCE Modules\juce_audio_processors\format_types + + JUCE Modules\juce_audio_processors\format_types + JUCE Modules\juce_audio_processors\format_types diff --git a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj index 41e58dcb04..0537755935 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 @@ -990,6 +990,9 @@ true + + true + true diff --git a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters index b15569500b..47e2dbfa05 100644 --- a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters +++ b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters @@ -1693,6 +1693,9 @@ JUCE Modules\juce_audio_processors\format_types + + JUCE Modules\juce_audio_processors\format_types + JUCE Modules\juce_audio_processors\format_types 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/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 631b2176d1..6770e135ae 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 297b3433a1..e7a3dabda5 100644 --- a/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt +++ b/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt @@ -737,6 +737,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" @@ -3012,6 +3013,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" diff --git a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj index 5e4733c6d1..16c03c9fb1 100644 --- a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj +++ b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj @@ -948,6 +948,9 @@ true + + true + true diff --git a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters index 6f97b74514..9c5168a180 100644 --- a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters +++ b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters @@ -1474,6 +1474,9 @@ JUCE Modules\juce_audio_processors\format_types + + JUCE Modules\juce_audio_processors\format_types + JUCE Modules\juce_audio_processors\format_types diff --git a/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt b/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt index 39b8c5d8ae..c166794e68 100644 --- a/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt +++ b/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt @@ -770,6 +770,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" @@ -3198,6 +3199,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" diff --git a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj index b3de1fcfcf..a7be3d1522 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj +++ b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj @@ -956,6 +956,9 @@ true + + true + true diff --git a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters index 5fb7e3e165..12a2459b27 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters +++ b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters @@ -1549,6 +1549,9 @@ JUCE Modules\juce_audio_processors\format_types + + JUCE Modules\juce_audio_processors\format_types + JUCE Modules\juce_audio_processors\format_types diff --git a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj index 5bb5d8c7d1..37a8c9fe26 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj +++ b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj @@ -956,6 +956,9 @@ true + + true + true diff --git a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters index 7f3b289347..2683798e1b 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters +++ b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters @@ -1549,6 +1549,9 @@ JUCE Modules\juce_audio_processors\format_types + + JUCE Modules\juce_audio_processors\format_types + JUCE Modules\juce_audio_processors\format_types diff --git a/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt b/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt index 9a2b403b26..9ae92f19d5 100644 --- a/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt +++ b/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt @@ -741,6 +741,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" @@ -3096,6 +3097,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" diff --git a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj index 6561e0794a..fc0e97f1c0 100644 --- a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj +++ b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj @@ -948,6 +948,9 @@ true + + true + true diff --git a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters index 0be08cef39..f0e9149811 100644 --- a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters +++ b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_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 diff --git a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj index 8daf07f44b..a12918abd7 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj +++ b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj @@ -964,6 +964,9 @@ true + + true + true diff --git a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters index ff8bbd5869..f0fc8fb7f6 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters +++ b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters @@ -1597,6 +1597,9 @@ JUCE Modules\juce_audio_processors\format_types + + JUCE Modules\juce_audio_processors\format_types + JUCE Modules\juce_audio_processors\format_types diff --git a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj index b675003219..3124bc734f 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj +++ b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj @@ -964,6 +964,9 @@ true + + true + true diff --git a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters index 1b43276b07..bbca4ac57b 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters +++ b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters @@ -1597,6 +1597,9 @@ JUCE Modules\juce_audio_processors\format_types + + JUCE Modules\juce_audio_processors\format_types + JUCE Modules\juce_audio_processors\format_types 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 9f549bc5ac..16a1068990 100644 --- a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj +++ b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj @@ -947,6 +947,9 @@ true + + true + true diff --git a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj.filters b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj.filters index bb7be0a05a..89db1c617d 100644 --- a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj.filters +++ b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj.filters @@ -1501,6 +1501,9 @@ JUCE Modules\juce_audio_processors\format_types + + JUCE Modules\juce_audio_processors\format_types + JUCE Modules\juce_audio_processors\format_types 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 5d70af4c07..e1a22253c1 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 a801de44bd..3951a15ed8 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 669796f633..92a4d48139 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 @@ -363,7 +365,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") @@ -372,131 +407,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; - - if (auto* outBus = processor.getBus (false, 0)) - if (! isNumberOfChannelsSupported (outBus, outChanNum, outLayout)) - continue; - - supportedChannels.add ({ static_cast (hasMainInputBus ? outLayout.getMainInputChannels() : 0), - static_cast (hasMainOutputBus ? outLayout.getMainOutputChannels() : 0) }); + const auto setsWithSizeI = AudioChannelSet::channelSetsWithNumberOfChannels (i); + std::copy (setsWithSizeI.begin(), setsWithSizeI.end(), std::back_inserter (sets)); } - } - const auto hasInOutMismatch = std::any_of (supportedChannels.begin(), - supportedChannels.end(), - [] (const Channels& x) { return x.ins != x.outs; }); + return sets; + }); - const auto computeHasUnsupportedLayout = [&] (bool isInput) + std::vector inputHasOutputRestrictions (layoutsToTry.size()), outputHasInputRestrictions (layoutsToTry.size()); + + for (const auto [inputIndex, inputLayout] : enumerate (layoutsToTry)) { - const auto hasMainBus = isInput ? hasMainInputBus : hasMainOutputBus; - const auto begin = hasMainBus ? 1 : 0; - const auto end = hasMainBus ? maxNumChanToCheckFor : 0; - - for (auto chan = begin; chan <= end; ++chan) + for (const auto [outputIndex, outputLayout] : enumerate (layoutsToTry)) { - const Channels channelConfig + 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)) { - static_cast (! isInput && hasInOutMismatch ? defaultInputs : chan), - static_cast ( isInput && hasInOutMismatch ? defaultOutputs : chan) - }; - - if (! supportedChannels.contains (channelConfig)) - return true; + supportedChannels.insert ({ (SInt16) inputLayout.size(), (SInt16) outputLayout.size() }); + } + else + { + inputHasOutputRestrictions[(size_t) inputIndex] = true; + outputHasInputRestrictions[(size_t) outputIndex] = true; + } } - - return ! hasMainBus; - }; - - const auto hasUnsupportedInput = computeHasUnsupportedLayout (true); - const auto hasUnsupportedOutput = computeHasUnsupportedLayout (false); - - for (const auto& supported : supportedChannels) - { - AUChannelInfo info; - - // 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 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); - static bool isNumberOfChannelsSupported (const AudioProcessor::Bus* b, int numChannels, AudioProcessor::BusesLayout& inOutCurrentLayout) - { - auto potentialSets = AudioChannelSet::channelSetsWithNumberOfChannels (static_cast (numChannels)); - - for (auto set : potentialSets) + if (noRestrictions) { - auto copy = inOutCurrentLayout; - - if (b->isLayoutSupported (set, ©)) + if (hasMainInputBus) { - inOutCurrentLayout = copy; - return true; + if (hasMainOutputBus) + return { Channels { -1, -2 } }; + + return { Channels { -1, 0 } }; } + + return { Channels { 0, -1 } }; } - return false; + const auto allMatchedLayoutsExclusivelySupported = std::invoke ([&] + { + for (SInt16 i = 1; i <= Channels::maxNumChanToCheckFor; ++i) + if (supportedChannels.find ({ i, i }) == supportedChannels.end()) + return false; + + 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) + { + return std::distance (layoutsToTry.begin(), + std::lower_bound (layoutsToTry.begin(), + layoutsToTry.end(), + channelCount, + [] (auto a, auto b) { return a.size() < b; })); + }; + + const auto findChannelCount = [&] (auto& restrictions, + auto thisChannelCount, + auto otherChannelCount, + auto hasMainBus) + { + 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); + } + + removeNonWildcardLayouts (filteredChannels); + + return filteredChannels; } //============================================================================== 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/juce_audio_processors.cpp b/modules/juce_audio_processors/juce_audio_processors.cpp index 20fdc86cfb..0a9eaedfef 100644 --- a/modules/juce_audio_processors/juce_audio_processors.cpp +++ b/modules/juce_audio_processors/juce_audio_processors.cpp @@ -221,6 +221,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 From 2712f636288f386ba41ca038c504f47b369d80b8 Mon Sep 17 00:00:00 2001 From: reuk Date: Wed, 6 Aug 2025 15:21:29 +0100 Subject: [PATCH 32/50] Graphics: Use unique_ptr instead of raw pointers in RenderingHelpers --- modules/juce_graphics/native/juce_RenderingHelpers.h | 8 ++++---- modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/juce_graphics/native/juce_RenderingHelpers.h b/modules/juce_graphics/native/juce_RenderingHelpers.h index 7db4ac7539..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); } diff --git a/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp b/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp index 8fcb1babc7..30a33c191c 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) { From 5eba9a64342397001bad13466fc2d7b8eef27043 Mon Sep 17 00:00:00 2001 From: reuk Date: Wed, 6 Aug 2025 15:29:03 +0100 Subject: [PATCH 33/50] OpenGL: Clear bound texture after rendering transparency layer A change introduced in 00836d1e94dcd45949da5be7f9266258c5d0dfe5 meant that GL renderers could sometimes assert in StateHelpers::ActiveTextures::bindTexture() when ending a transparency layer. Specifically, the issue was provoked by adding the ScopedTextureBinding in the constructor of OpenGLFrameBuffer. This reset the bound texture after creating a new transparency layer. I think the previous implementation worked by accident, not by design. It so happens that when rendering multiple transparency layers within the same frame (i.e. calling begin/end several times in that order, *not* nesting the calls), the same texture ID will generally get reused. From the graphics context's (GC's) perspective, we create a texture with ID "2", then call bindTexture() to bind it, and the GC remembers that this ID is bound. We draw the frame, and the texture gets destroyed. The call to glDeleteTextures() will cause the default texture, "0", to be bound if the texture being destroyed is bound at the point of destruction. So, after the texture is destroyed, the GC's stored binding no longer reflects reality, since texture "0" is now bound. The next time we create a texture, that texture also gets created with ID "2". Previously, we would leave this texture bound after construction, but now we re-bind the previously-bound texture, "0". This causes the assertion in bindTexture() to fire when we next attempt to bind texture "2", since the actual bound texture is "0". The solution added in this patch will bind texture "0" when the transparency layer image is destroyed, in order to keep the GC's view of the GL context consistent with the real state. --- modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp b/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp index 30a33c191c..9289f8acdc 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp @@ -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); } } From 90b948dffd0d5a21399bc5234bbc188fca84f735 Mon Sep 17 00:00:00 2001 From: reuk Date: Thu, 7 Aug 2025 16:18:25 +0100 Subject: [PATCH 34/50] AudioProcessor: Remove deprecated functions --- .../processors/juce_AudioProcessor.cpp | 91 ------------------- .../processors/juce_AudioProcessor.h | 6 -- 2 files changed, 97 deletions(-) diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp b/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp index a28e46aa5e..37eb89016a 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp +++ b/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp @@ -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]) diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessor.h b/modules/juce_audio_processors/processors/juce_AudioProcessor.h index 00df5b2f7b..c9a86be43c 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. From 1623b63889817fb1197cfdc14928f5f13cb6d51c Mon Sep 17 00:00:00 2001 From: reuk Date: Thu, 7 Aug 2025 16:21:54 +0100 Subject: [PATCH 35/50] AudioProcessorParameter: Move impl to dedicated file --- .../Builds/Android/app/CMakeLists.txt | 2 + .../VisualStudio2019/DemoRunner_App.vcxproj | 3 + .../DemoRunner_App.vcxproj.filters | 3 + .../VisualStudio2022/DemoRunner_App.vcxproj | 3 + .../DemoRunner_App.vcxproj.filters | 3 + .../Builds/Android/app/CMakeLists.txt | 2 + .../AudioPerformanceTest_App.vcxproj | 3 + .../AudioPerformanceTest_App.vcxproj.filters | 3 + .../Builds/Android/app/CMakeLists.txt | 2 + .../AudioPluginHost_App.vcxproj | 3 + .../AudioPluginHost_App.vcxproj.filters | 3 + .../AudioPluginHost_App.vcxproj | 3 + .../AudioPluginHost_App.vcxproj.filters | 3 + .../Builds/Android/app/CMakeLists.txt | 2 + .../NetworkGraphicsDemo_App.vcxproj | 3 + .../NetworkGraphicsDemo_App.vcxproj.filters | 3 + .../UnitTestRunner_ConsoleApp.vcxproj | 3 + .../UnitTestRunner_ConsoleApp.vcxproj.filters | 3 + .../UnitTestRunner_ConsoleApp.vcxproj | 3 + .../UnitTestRunner_ConsoleApp.vcxproj.filters | 3 + .../WindowsDLL_DynamicLibrary.vcxproj | 3 + .../WindowsDLL_DynamicLibrary.vcxproj.filters | 3 + .../juce_audio_processors.cpp | 1 + .../processors/juce_AudioProcessor.cpp | 135 -------------- .../juce_AudioProcessorParameter.cpp | 172 ++++++++++++++++++ 25 files changed, 235 insertions(+), 135 deletions(-) create mode 100644 modules/juce_audio_processors/processors/juce_AudioProcessorParameter.cpp diff --git a/examples/DemoRunner/Builds/Android/app/CMakeLists.txt b/examples/DemoRunner/Builds/Android/app/CMakeLists.txt index 53405c352d..3ed4365d7d 100644 --- a/examples/DemoRunner/Builds/Android/app/CMakeLists.txt +++ b/examples/DemoRunner/Builds/Android/app/CMakeLists.txt @@ -812,6 +812,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h" "../../../../../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" @@ -3474,6 +3475,7 @@ set_source_files_properties( "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h" "../../../../../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/VisualStudio2019/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj index ca973b4fb1..952fefe56a 100644 --- a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj +++ b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj @@ -1029,6 +1029,9 @@ true + + true + true diff --git a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters index a36e352160..b31b55b228 100644 --- a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters +++ b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters @@ -1732,6 +1732,9 @@ 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 0537755935..41c71aee0f 100644 --- a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj +++ b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj @@ -1029,6 +1029,9 @@ true + + true + true diff --git a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters index 47e2dbfa05..199a536b52 100644 --- a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters +++ b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters @@ -1732,6 +1732,9 @@ JUCE Modules\juce_audio_processors\processors + + JUCE Modules\juce_audio_processors\processors + JUCE Modules\juce_audio_processors\processors diff --git a/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt b/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt index e7a3dabda5..9f25515615 100644 --- a/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt +++ b/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt @@ -767,6 +767,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h" "../../../../../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" @@ -3043,6 +3044,7 @@ set_source_files_properties( "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h" "../../../../../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 16c03c9fb1..02e9187d3e 100644 --- a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj +++ b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj @@ -987,6 +987,9 @@ true + + true + true diff --git a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters index 9c5168a180..20f2802f08 100644 --- a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters +++ b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters @@ -1513,6 +1513,9 @@ JUCE Modules\juce_audio_processors\processors + + JUCE Modules\juce_audio_processors\processors + JUCE Modules\juce_audio_processors\processors diff --git a/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt b/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt index c166794e68..ee5c610d23 100644 --- a/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt +++ b/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt @@ -800,6 +800,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h" "../../../../../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" @@ -3229,6 +3230,7 @@ set_source_files_properties( "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h" "../../../../../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 a7be3d1522..a16b9084e1 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj +++ b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj @@ -995,6 +995,9 @@ true + + true + true diff --git a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters index 12a2459b27..ad264c4143 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters +++ b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters @@ -1588,6 +1588,9 @@ 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 37a8c9fe26..f118e5e5ae 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj +++ b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj @@ -995,6 +995,9 @@ true + + true + true diff --git a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters index 2683798e1b..d47bbe62ef 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters +++ b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters @@ -1588,6 +1588,9 @@ JUCE Modules\juce_audio_processors\processors + + JUCE Modules\juce_audio_processors\processors + JUCE Modules\juce_audio_processors\processors diff --git a/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt b/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt index 9ae92f19d5..97e3496b4a 100644 --- a/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt +++ b/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt @@ -771,6 +771,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h" "../../../../../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" @@ -3127,6 +3128,7 @@ set_source_files_properties( "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp" "../../../../../modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h" "../../../../../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 fc0e97f1c0..7c7d21ec99 100644 --- a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj +++ b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj @@ -987,6 +987,9 @@ true + + true + true diff --git a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters index f0e9149811..6c0fbc226e 100644 --- a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters +++ b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters @@ -1543,6 +1543,9 @@ JUCE Modules\juce_audio_processors\processors + + JUCE Modules\juce_audio_processors\processors + JUCE Modules\juce_audio_processors\processors diff --git a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj index a12918abd7..4258f0bac0 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj +++ b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj @@ -1003,6 +1003,9 @@ true + + true + true diff --git a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters index f0fc8fb7f6..168542acff 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters +++ b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters @@ -1636,6 +1636,9 @@ 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 3124bc734f..8baa176922 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj +++ b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj @@ -1003,6 +1003,9 @@ true + + true + true diff --git a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters index bbca4ac57b..4c8fc70387 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters +++ b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters @@ -1636,6 +1636,9 @@ JUCE Modules\juce_audio_processors\processors + + JUCE Modules\juce_audio_processors\processors + JUCE Modules\juce_audio_processors\processors diff --git a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj index 16a1068990..5ec98a412f 100644 --- a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj +++ b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj @@ -986,6 +986,9 @@ true + + true + true diff --git a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj.filters b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj.filters index 89db1c617d..7029ea85c7 100644 --- a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj.filters +++ b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj.filters @@ -1540,6 +1540,9 @@ JUCE Modules\juce_audio_processors\processors + + JUCE Modules\juce_audio_processors\processors + JUCE Modules\juce_audio_processors\processors diff --git a/modules/juce_audio_processors/juce_audio_processors.cpp b/modules/juce_audio_processors/juce_audio_processors.cpp index 0a9eaedfef..a8ff26282b 100644 --- a/modules/juce_audio_processors/juce_audio_processors.cpp +++ b/modules/juce_audio_processors/juce_audio_processors.cpp @@ -184,6 +184,7 @@ 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_AudioPluginInstance.cpp" #include "processors/juce_AudioProcessorEditor.cpp" diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp b/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp index 37eb89016a..48b8d5904d 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp +++ b/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp @@ -1429,139 +1429,4 @@ 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_AudioProcessorParameter.cpp b/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.cpp new file mode 100644 index 0000000000..259e9d014e --- /dev/null +++ b/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.cpp @@ -0,0 +1,172 @@ +/* + ============================================================================== + + 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::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 From edd274f18e13e18619e9d6523accdd88c623491a Mon Sep 17 00:00:00 2001 From: reuk Date: Thu, 7 Aug 2025 17:17:15 +0100 Subject: [PATCH 36/50] AudioProcessorListener: Move impl to dedicated file --- .../Builds/Android/app/CMakeLists.txt | 2 + .../VisualStudio2019/DemoRunner_App.vcxproj | 3 ++ .../DemoRunner_App.vcxproj.filters | 3 ++ .../VisualStudio2022/DemoRunner_App.vcxproj | 3 ++ .../DemoRunner_App.vcxproj.filters | 3 ++ .../Builds/Android/app/CMakeLists.txt | 2 + .../AudioPerformanceTest_App.vcxproj | 3 ++ .../AudioPerformanceTest_App.vcxproj.filters | 3 ++ .../Builds/Android/app/CMakeLists.txt | 2 + .../AudioPluginHost_App.vcxproj | 3 ++ .../AudioPluginHost_App.vcxproj.filters | 3 ++ .../AudioPluginHost_App.vcxproj | 3 ++ .../AudioPluginHost_App.vcxproj.filters | 3 ++ .../Builds/Android/app/CMakeLists.txt | 2 + .../NetworkGraphicsDemo_App.vcxproj | 3 ++ .../NetworkGraphicsDemo_App.vcxproj.filters | 3 ++ .../UnitTestRunner_ConsoleApp.vcxproj | 3 ++ .../UnitTestRunner_ConsoleApp.vcxproj.filters | 3 ++ .../UnitTestRunner_ConsoleApp.vcxproj | 3 ++ .../UnitTestRunner_ConsoleApp.vcxproj.filters | 3 ++ .../WindowsDLL_DynamicLibrary.vcxproj | 3 ++ .../WindowsDLL_DynamicLibrary.vcxproj.filters | 3 ++ .../juce_audio_processors.cpp | 1 + .../processors/juce_AudioProcessor.cpp | 4 -- .../juce_AudioProcessorListener.cpp | 41 +++++++++++++++++++ 25 files changed, 104 insertions(+), 4 deletions(-) create mode 100644 modules/juce_audio_processors/processors/juce_AudioProcessorListener.cpp diff --git a/examples/DemoRunner/Builds/Android/app/CMakeLists.txt b/examples/DemoRunner/Builds/Android/app/CMakeLists.txt index 3ed4365d7d..be816b44e7 100644 --- a/examples/DemoRunner/Builds/Android/app/CMakeLists.txt +++ b/examples/DemoRunner/Builds/Android/app/CMakeLists.txt @@ -811,6 +811,7 @@ 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" @@ -3474,6 +3475,7 @@ 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" diff --git a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj index 952fefe56a..7d5b98eea5 100644 --- a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj +++ b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj @@ -1029,6 +1029,9 @@ true + + true + true diff --git a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters index b31b55b228..f32366ff80 100644 --- a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters +++ b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters @@ -1732,6 +1732,9 @@ 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 41c71aee0f..6ded2020e0 100644 --- a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj +++ b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj @@ -1029,6 +1029,9 @@ true + + true + true diff --git a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters index 199a536b52..87dd169013 100644 --- a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters +++ b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters @@ -1732,6 +1732,9 @@ JUCE Modules\juce_audio_processors\processors + + JUCE Modules\juce_audio_processors\processors + JUCE Modules\juce_audio_processors\processors diff --git a/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt b/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt index 9f25515615..0fc7efd773 100644 --- a/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt +++ b/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt @@ -766,6 +766,7 @@ 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" @@ -3043,6 +3044,7 @@ 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" diff --git a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj index 02e9187d3e..2049220ba3 100644 --- a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj +++ b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj @@ -987,6 +987,9 @@ true + + true + true diff --git a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters index 20f2802f08..1070784acd 100644 --- a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters +++ b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters @@ -1513,6 +1513,9 @@ JUCE Modules\juce_audio_processors\processors + + JUCE Modules\juce_audio_processors\processors + JUCE Modules\juce_audio_processors\processors diff --git a/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt b/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt index ee5c610d23..ace3c62eea 100644 --- a/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt +++ b/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt @@ -799,6 +799,7 @@ 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" @@ -3229,6 +3230,7 @@ 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" diff --git a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj index a16b9084e1..275bb95f2a 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj +++ b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj @@ -995,6 +995,9 @@ true + + true + true diff --git a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters index ad264c4143..8cce520998 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters +++ b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters @@ -1588,6 +1588,9 @@ 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 f118e5e5ae..97300a8603 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj +++ b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj @@ -995,6 +995,9 @@ true + + true + true diff --git a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters index d47bbe62ef..949e748965 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters +++ b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters @@ -1588,6 +1588,9 @@ JUCE Modules\juce_audio_processors\processors + + JUCE Modules\juce_audio_processors\processors + JUCE Modules\juce_audio_processors\processors diff --git a/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt b/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt index 97e3496b4a..a9b7c0b0d4 100644 --- a/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt +++ b/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt @@ -770,6 +770,7 @@ 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" @@ -3127,6 +3128,7 @@ 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" diff --git a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj index 7c7d21ec99..4081ef0e9a 100644 --- a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj +++ b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj @@ -987,6 +987,9 @@ true + + true + true diff --git a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters index 6c0fbc226e..117b396858 100644 --- a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters +++ b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters @@ -1543,6 +1543,9 @@ JUCE Modules\juce_audio_processors\processors + + JUCE Modules\juce_audio_processors\processors + JUCE Modules\juce_audio_processors\processors diff --git a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj index 4258f0bac0..bf02663c21 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj +++ b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj @@ -1003,6 +1003,9 @@ true + + true + true diff --git a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters index 168542acff..1d47d6d504 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters +++ b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters @@ -1636,6 +1636,9 @@ 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 8baa176922..e1e9ea96e5 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj +++ b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj @@ -1003,6 +1003,9 @@ true + + true + true diff --git a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters index 4c8fc70387..5234ed2371 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters +++ b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters @@ -1636,6 +1636,9 @@ JUCE Modules\juce_audio_processors\processors + + JUCE Modules\juce_audio_processors\processors + JUCE Modules\juce_audio_processors\processors diff --git a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj index 5ec98a412f..d866e19fd8 100644 --- a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj +++ b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj @@ -986,6 +986,9 @@ true + + true + true diff --git a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj.filters b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj.filters index 7029ea85c7..47c5735c77 100644 --- a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj.filters +++ b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_DynamicLibrary.vcxproj.filters @@ -1540,6 +1540,9 @@ JUCE Modules\juce_audio_processors\processors + + JUCE Modules\juce_audio_processors\processors + JUCE Modules\juce_audio_processors\processors diff --git a/modules/juce_audio_processors/juce_audio_processors.cpp b/modules/juce_audio_processors/juce_audio_processors.cpp index a8ff26282b..8819516eb1 100644 --- a/modules/juce_audio_processors/juce_audio_processors.cpp +++ b/modules/juce_audio_processors/juce_audio_processors.cpp @@ -186,6 +186,7 @@ private: #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" diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp b/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp index 48b8d5904d..d0d61136fe 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp +++ b/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp @@ -1425,8 +1425,4 @@ bool AudioProcessor::canRemoveBus ([[maybe_unused]] bool isInput) const JUCE_END_IGNORE_DEPRECATION_WARNINGS -//============================================================================== -void AudioProcessorListener::audioProcessorParameterChangeGestureBegin (AudioProcessor*, int) {} -void AudioProcessorListener::audioProcessorParameterChangeGestureEnd (AudioProcessor*, int) {} - } // namespace juce 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 From 476f09f2c95409ce5a8224083b1bd64efa064ae9 Mon Sep 17 00:00:00 2001 From: reuk Date: Thu, 7 Aug 2025 16:30:18 +0100 Subject: [PATCH 37/50] AudioProcessorParameter: Remove friendship with unrelated types --- .../juce_LegacyAudioParameter.cpp | 54 +++++++++---------- .../processors/juce_AudioProcessor.cpp | 6 +-- .../juce_AudioProcessorParameter.cpp | 6 +++ .../processors/juce_AudioProcessorParameter.h | 12 +++-- 4 files changed, 43 insertions(+), 35 deletions(-) diff --git a/modules/juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp b/modules/juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp index 977206dc07..33a8751968 100644 --- a/modules/juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp +++ b/modules/juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp @@ -44,25 +44,25 @@ public: { processor = &audioProcessorToUse; - parameterIndex = audioParameterIndex; - jassert (parameterIndex < processor->getNumParameters()); + 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 +85,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 +105,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)) { diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp b/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp index d0d61136fe..0d14c6ab23 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp +++ b/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp @@ -522,7 +522,7 @@ void AudioProcessor::addParameter (AudioProcessorParameter* param) parameterTree.addChild (std::unique_ptr (param)); param->processor = this; - param->parameterIndex = flatParameterList.size(); + param->setParameterIndex (flatParameterList.size()); flatParameterList.add (param); validateParameter (param); @@ -540,7 +540,7 @@ void AudioProcessor::addParameterGroup (std::unique_ptrprocessor = this; - p->parameterIndex = i; + p->setParameterIndex (i); validateParameter (p); } @@ -567,7 +567,7 @@ void AudioProcessor::setParameterTree (AudioProcessorParameterGroup&& newTree) { auto p = flatParameterList.getUnchecked (i); p->processor = this; - p->parameterIndex = i; + p->setParameterIndex (i); validateParameter (p); } diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.cpp b/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.cpp index 259e9d014e..a5ed0090d3 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.cpp +++ b/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.cpp @@ -44,6 +44,12 @@ AudioProcessorParameter::~AudioProcessorParameter() #endif } +void AudioProcessorParameter::setParameterIndex (int index) noexcept +{ + jassert (parameterIndex < 0 && 0 <= index); + parameterIndex = index; +} + void AudioProcessorParameter::setValueNotifyingHost (float newValue) { setValue (newValue); diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h b/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h index 7978246366..426b9f2284 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h +++ b/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h @@ -262,6 +262,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 parameter indices *will* break things! + */ + void setParameterIndex (int index) noexcept; + //============================================================================== /** Returns the current value of the parameter as a String. @@ -349,11 +355,11 @@ public: /** @internal */ void sendValueChangedMessageToListeners (float newValue); + /** @internal */ + AudioProcessor* processor = nullptr; + private: //============================================================================== - friend class AudioProcessor; - friend class LegacyAudioParameter; - AudioProcessor* processor = nullptr; int parameterIndex = -1; int version = 0; CriticalSection listenerLock; From 96ff7a0dcbd224671328019e5ed49b6f5d6c4827 Mon Sep 17 00:00:00 2001 From: reuk Date: Thu, 7 Aug 2025 17:30:59 +0100 Subject: [PATCH 38/50] AudioProcessor: Move getDefaultNumParameterSteps() to AudioProcessorParameter --- .../processors/juce_AudioProcessor.cpp | 4 ++-- .../processors/juce_AudioProcessorParameter.cpp | 7 ++++++- .../processors/juce_AudioProcessorParameter.h | 11 ++++++++++- .../utilities/juce_RangedAudioParameter.cpp | 2 +- 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp b/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp index 0d14c6ab23..989abed023 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp +++ b/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp @@ -577,7 +577,7 @@ void AudioProcessor::refreshParameterList() {} int AudioProcessor::getDefaultNumParameterSteps() noexcept { - return 0x7fffffff; + return AudioProcessorParameter::getDefaultNumParameterSteps(); } void AudioProcessor::suspendProcessing (const bool shouldBeSuspended) @@ -1358,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 diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.cpp b/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.cpp index a5ed0090d3..7aec22456f 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.cpp +++ b/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.cpp @@ -136,7 +136,7 @@ bool AudioProcessorParameter::isOrientationInverted() const 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(); } +int AudioProcessorParameter::getNumSteps() const { return getDefaultNumParameterSteps(); } bool AudioProcessorParameter::isDiscrete() const { return false; } bool AudioProcessorParameter::isBoolean() const { return false; } @@ -175,4 +175,9 @@ void AudioProcessorParameter::removeListener (AudioProcessorParameter::Listener* 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 426b9f2284..0c0ddaaeec 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h +++ b/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h @@ -173,7 +173,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. @@ -358,6 +358,15 @@ public: /** @internal */ AudioProcessor* processor = nullptr; + /** 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: //============================================================================== int parameterIndex = -1; 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 From da8150bb58f28b33c025b98d07d2d994efd75b60 Mon Sep 17 00:00:00 2001 From: reuk Date: Thu, 7 Aug 2025 17:07:57 +0100 Subject: [PATCH 39/50] AudioProcessorParameter: Break dependency cycle with AudioProcessor --- .../juce_LegacyAudioParameter.cpp | 16 ++++++-- .../processors/juce_AudioProcessor.cpp | 31 ++++++++++++-- .../processors/juce_AudioProcessor.h | 27 +++++++++++++ .../processors/juce_AudioProcessorEditor.h | 1 + .../juce_AudioProcessorParameter.cpp | 40 +++++++------------ .../processors/juce_AudioProcessorParameter.h | 16 ++++---- 6 files changed, 91 insertions(+), 40 deletions(-) diff --git a/modules/juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp b/modules/juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp index 33a8751968..2225dfeea0 100644 --- a/modules/juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp +++ b/modules/juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp @@ -40,10 +40,12 @@ 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; - + setOwner (&listener); setParameterIndex (audioParameterIndex); jassert (getParameterIndex() < processor->getNumParameters()); } @@ -118,6 +120,9 @@ public: return {}; } + +private: + AudioProcessor* processor = nullptr; }; //============================================================================== @@ -135,6 +140,7 @@ public: { clear(); + forwarder = AudioProcessor::ParameterChangeForwarder { &audioProcessor }; legacyParamIDs = forceLegacyParamIDs; auto numParameters = audioProcessor.getNumParameters(); @@ -147,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)); @@ -163,6 +169,7 @@ public: void clear() { + forwarder = AudioProcessor::ParameterChangeForwarder { nullptr }; ownedGroup = AudioProcessorParameterGroup(); params.clear(); } @@ -211,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/processors/juce_AudioProcessor.cpp b/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp index 989abed023..26fdf35837 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp +++ b/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp @@ -521,7 +521,7 @@ void AudioProcessor::addParameter (AudioProcessorParameter* param) jassert (param != nullptr); parameterTree.addChild (std::unique_ptr (param)); - param->processor = this; + param->setOwner (¶meterListener); param->setParameterIndex (flatParameterList.size()); flatParameterList.add (param); @@ -539,7 +539,7 @@ void AudioProcessor::addParameterGroup (std::unique_ptrprocessor = this; + p->setOwner (¶meterListener); p->setParameterIndex (i); validateParameter (p); @@ -566,7 +566,7 @@ void AudioProcessor::setParameterTree (AudioProcessorParameterGroup&& newTree) for (int i = 0; i < flatParameterList.size(); ++i) { auto p = flatParameterList.getUnchecked (i); - p->processor = this; + p->setOwner (¶meterListener); p->setParameterIndex (i); validateParameter (p); @@ -1423,6 +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 } // namespace juce diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessor.h b/modules/juce_audio_processors/processors/juce_AudioProcessor.h index c9a86be43c..cd57916c37 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessor.h +++ b/modules/juce_audio_processors/processors/juce_AudioProcessor.h @@ -1516,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 @@ -1588,6 +1613,8 @@ private: AudioProcessorParameterGroup parameterTree; Array flatParameterList; + ParameterChangeForwarder parameterListener { this }; + AudioProcessorParameter* getParamChecked (int) const; #if JUCE_DEBUG 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_AudioProcessorParameter.cpp b/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.cpp index 7aec22456f..1221281a0a 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.cpp +++ b/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.cpp @@ -50,6 +50,12 @@ void AudioProcessorParameter::setParameterIndex (int index) noexcept parameterIndex = index; } +void AudioProcessorParameter::setOwner (Listener* listenerIn) noexcept +{ + jassert (finalListener == nullptr); + finalListener = listenerIn; +} + void AudioProcessorParameter::setValueNotifyingHost (float newValue) { setValue (newValue); @@ -59,7 +65,7 @@ void AudioProcessorParameter::setValueNotifyingHost (float newValue) void AudioProcessorParameter::beginChangeGesture() { // This method can't be used until the parameter has been attached to a processor! - jassert (processor != nullptr && parameterIndex >= 0); + jassert (parameterIndex >= 0); #if JUCE_DEBUG && ! JUCE_DISABLE_AUDIOPROCESSOR_BEGIN_END_GESTURE_CHECKING // This means you've called beginChangeGesture twice in succession without @@ -75,20 +81,14 @@ void AudioProcessorParameter::beginChangeGesture() 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()); - } + 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 (processor != nullptr && parameterIndex >= 0); + jassert (parameterIndex >= 0); #if JUCE_DEBUG && ! JUCE_DISABLE_AUDIOPROCESSOR_BEGIN_END_GESTURE_CHECKING // This means you've called endChangeGesture without having previously @@ -104,14 +104,8 @@ void AudioProcessorParameter::endChangeGesture() 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()); - } + if (finalListener != nullptr) + finalListener->parameterGestureChanged (getParameterIndex(), false); } void AudioProcessorParameter::sendValueChangedMessageToListeners (float newValue) @@ -122,14 +116,8 @@ void AudioProcessorParameter::sendValueChangedMessageToListeners (float newValue 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); - } + if (finalListener != nullptr) + finalListener->parameterValueChanged (getParameterIndex(), newValue); } bool AudioProcessorParameter::isOrientationInverted() const { return false; } diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h b/modules/juce_audio_processors/processors/juce_AudioProcessorParameter.h index 0c0ddaaeec..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. @@ -264,9 +262,9 @@ public: /** @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 parameter indices *will* break things! + a processor. Do not call this function; changing the parameter index *will* break things! */ - void setParameterIndex (int index) noexcept; + void setParameterIndex (int) noexcept; //============================================================================== /** Returns the current value of the parameter as a String. @@ -338,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. @@ -355,9 +359,6 @@ public: /** @internal */ void sendValueChangedMessageToListeners (float newValue); - /** @internal */ - AudioProcessor* processor = nullptr; - /** Returns the default number of steps for a parameter. NOTE! This method is deprecated! It's recommended that you use @@ -373,6 +374,7 @@ private: int version = 0; CriticalSection listenerLock; Array listeners; + Listener* finalListener = nullptr; mutable StringArray valueStrings; #if JUCE_DEBUG From ccdc9d67797219526d9f6db35a60417d2abfcdfd Mon Sep 17 00:00:00 2001 From: reuk Date: Thu, 7 Aug 2025 20:15:35 +0100 Subject: [PATCH 40/50] AudioProcessor: Remove friendship with AudioProcessorParameter --- modules/juce_audio_processors/processors/juce_AudioProcessor.h | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessor.h b/modules/juce_audio_processors/processors/juce_AudioProcessor.h index cd57916c37..b7d8b633e0 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessor.h +++ b/modules/juce_audio_processors/processors/juce_AudioProcessor.h @@ -1642,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.")]] From b9a0dd4b5662d32b22a84234109bae1450c71b86 Mon Sep 17 00:00:00 2001 From: reuk Date: Thu, 7 Aug 2025 20:47:00 +0100 Subject: [PATCH 41/50] CMake: Fix juce_vst3_helper target check --- extras/Build/CMake/JUCEUtils.cmake | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/extras/Build/CMake/JUCEUtils.cmake b/extras/Build/CMake/JUCEUtils.cmake index 58ac358e41..82589be7dd 100644 --- a/extras/Build/CMake/JUCEUtils.cmake +++ b/extras/Build/CMake/JUCEUtils.cmake @@ -1030,7 +1030,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")) @@ -1048,7 +1050,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}) From cb698566e8fc0aa83bea0f5c9238a8a6fd23023e Mon Sep 17 00:00:00 2001 From: Oli Date: Wed, 9 Apr 2025 15:17:42 +0100 Subject: [PATCH 42/50] Projucer: (MSVC) Add missing Unity binary location property --- .../Projucer/Source/ProjectSaving/jucer_ProjectExport_MSVC.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_MSVC.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_MSVC.h index bf07daf77b..18ce0b809c 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_MSVC.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_MSVC.h @@ -803,7 +803,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(), From 270063ac3114e4b8ce5bcaaa719a2f875a307854 Mon Sep 17 00:00:00 2001 From: Oli Date: Wed, 26 Mar 2025 16:09:39 +0000 Subject: [PATCH 43/50] Projucer: (MSVC) Emit message on plugin install location and config error --- .../ProjectSaving/jucer_ProjectExport_MSVC.h | 164 +++++++++++++++--- 1 file changed, 140 insertions(+), 24 deletions(-) diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_MSVC.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_MSVC.h index 18ce0b809c..a1385168f4 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; } @@ -1723,6 +1728,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; @@ -1742,7 +1758,7 @@ public: + " " + (directory + "\\" + segments[0] + "\\").quoted(); - return config.isPluginBinaryCopyStepEnabled() ? copyStep : ""; + return shouldPerformCopyStepForPlugin (type, config, arch) ? copyStep : ""; }; if (type == AAXPlugIn) @@ -1778,7 +1794,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); @@ -1813,7 +1829,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)); @@ -1923,7 +1941,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) @@ -1938,6 +1956,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) @@ -1959,24 +2085,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) { @@ -2010,8 +2120,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)); From bb5a9cbac96b90ee819be45f5b2f8d3cec36edff Mon Sep 17 00:00:00 2001 From: attila Date: Fri, 15 Aug 2025 17:21:39 +0200 Subject: [PATCH 44/50] Direct2D: Fix wrong brush transform calculation This change is practically a no-op, because if the affected branch is taken, then the world transform was not applied, so transform is a unity matrix. But if transform was non-unity, then the wrong ordering would cause an observable error. Logically the brush transformation is nested inside the world transformation so the right order is applying the brush transform first followed by the world transform. --- .../native/juce_Direct2DGraphicsContextImpl_windows.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/juce_graphics/native/juce_Direct2DGraphicsContextImpl_windows.cpp b/modules/juce_graphics/native/juce_Direct2DGraphicsContextImpl_windows.cpp index d86bb9064a..d1a6e20651 100644 --- a/modules/juce_graphics/native/juce_Direct2DGraphicsContextImpl_windows.cpp +++ b/modules/juce_graphics/native/juce_Direct2DGraphicsContextImpl_windows.cpp @@ -480,7 +480,7 @@ public: if (fillType.transform.isOnlyTranslation()) translation += Point (fillType.transform.getTranslationX(), fillType.transform.getTranslationY()); else - transform = transform.followedBy (fillType.transform); + transform = fillType.transform.followedBy (transform); } if ((flags & BrushTransformFlags::applyInverseWorldTransform) != 0) @@ -513,7 +513,7 @@ public: transform = currentTransform.getTransform(); if ((flags & BrushTransformFlags::applyFillTypeTransform) != 0) - transform = transform.followedBy (fillType.transform); + transform = fillType.transform.followedBy (transform); if ((flags & BrushTransformFlags::applyInverseWorldTransform) != 0) transform = transform.followedBy (currentTransform.getTransform().inverted()); From 35fe3ac714ce50926174b6640ab04bd20678d784 Mon Sep 17 00:00:00 2001 From: attila Date: Mon, 18 Aug 2025 13:59:57 +0200 Subject: [PATCH 45/50] Direct2D: Fix gradient fill when the brush is transformed with not just translation The code contains a performance optimisation for cases where the world transform is translation only. In this case instead of applying the brush transformation first and then the world translation, the order is reversed. The translation is applied first and then the brush transformation. Flipping the transformations however is only correct in the special case when both transformations are translation only. --- ...ce_Direct2DGraphicsContextImpl_windows.cpp | 2 +- .../juce_Direct2DGraphicsContext_windows.cpp | 79 +++++++++++++++++++ 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/modules/juce_graphics/native/juce_Direct2DGraphicsContextImpl_windows.cpp b/modules/juce_graphics/native/juce_Direct2DGraphicsContextImpl_windows.cpp index d1a6e20651..f209171fca 100644 --- a/modules/juce_graphics/native/juce_Direct2DGraphicsContextImpl_windows.cpp +++ b/modules/juce_graphics/native/juce_Direct2DGraphicsContextImpl_windows.cpp @@ -469,7 +469,7 @@ public: { if ((flags & BrushTransformFlags::applyWorldTransform) != 0) { - if (currentTransform.isOnlyTranslated) + if (currentTransform.isOnlyTranslated && fillType.transform.isOnlyTranslation()) translation = currentTransform.offset.toFloat(); else transform = currentTransform.getTransform(); diff --git a/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp b/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp index 9cd61bee03..efd547698b 100644 --- a/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp +++ b/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp @@ -1380,6 +1380,12 @@ public: compareImages (targetNative, targetSoftware, 1, pixelsToIgnore); } + + beginTest ("Gradient fill transform should compose with world transform correctly"); + { + testGradientFillTransform (1.0f); + testGradientFillTransform (1.5f); + } } static Image createEdgeMask (int sourceWidth, @@ -1433,6 +1439,79 @@ public: const auto averageError = (double) accumulatedError / (double) numSamples; 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); + } + } }; static Direct2DGraphicsContextTests direct2DGraphicsContextTests; From ad28684b10c4568c85f8186fb9d409c65ca8de75 Mon Sep 17 00:00:00 2001 From: attila Date: Fri, 15 Aug 2025 18:14:41 +0200 Subject: [PATCH 46/50] Tidying: Remove unused code --- ...ce_Direct2DGraphicsContextImpl_windows.cpp | 51 +++++++------------ 1 file changed, 17 insertions(+), 34 deletions(-) diff --git a/modules/juce_graphics/native/juce_Direct2DGraphicsContextImpl_windows.cpp b/modules/juce_graphics/native/juce_Direct2DGraphicsContextImpl_windows.cpp index f209171fca..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 && fillType.transform.isOnlyTranslation()) - 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 = fillType.transform.followedBy (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 = fillType.transform.followedBy (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; From 4263efb96a6555cc3a0f203342a0a1d2b0c34ad2 Mon Sep 17 00:00:00 2001 From: Oli Date: Wed, 20 Aug 2025 09:51:28 +0100 Subject: [PATCH 47/50] Jpeg: Disable "extern C" in jpeglib.h --- modules/juce_graphics/image_formats/juce_JPEGLoader.cpp | 1 + 1 file changed, 1 insertion(+) 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" From ac8900794960cbbc3197da9760c0c90242b04b7e Mon Sep 17 00:00:00 2001 From: reuk Date: Thu, 21 Aug 2025 15:52:40 +0100 Subject: [PATCH 48/50] ARA Host: Fix build The build got broken in f3d7c74ea1ce9df539754dd3a5d09c4f8b40c1a1 - the ARAVST3.h include is needed for both hosts and clients. --- .../format_types/juce_VST3Headers.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) 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 From ceaa70804234dd07a5a6d22fa09babd47ded6978 Mon Sep 17 00:00:00 2001 From: Oli Date: Mon, 18 Aug 2025 14:45:02 +0100 Subject: [PATCH 49/50] Core: Use correct "debug break" intrinsic for Windows-ARM64-ClangCL --- modules/juce_core/system/juce_PlatformDefs.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 From 1843554ad8726e0516e37b7b7299039997aba1f0 Mon Sep 17 00:00:00 2001 From: Oli Date: Mon, 18 Aug 2025 14:45:28 +0100 Subject: [PATCH 50/50] DSP: Don't include neon headers for Windows-ARM64-ClangCL --- modules/juce_dsp/juce_dsp.h | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) 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