JUCE 5.4

macOS Mojave, iOS 12, Windows hiDPI, and Unity native plug-in support, plus more!

JUCE 5.4

Release Notes

Introducing JUCE 5.4

System requirement changes:



macOS Mojave and iOS 12 support

JUCE has been updated to fully support the new macOS 10.14 Mojave and iOS 12 updates, allowing deployment to the new iPhone XS and XR.


Windows hiDPI support

JUCE now supports building per-monitor DPI-aware applications on Windows 8.1+, meaning that JUCE applications will scale dynamically with the DPI of the monitor that they are on ensuring crisp UIs on high resolution displays. The VST client and hosting code has also been updated to support the Windows scaling APIs making it possible to build and host DPI-aware VST2 and VST3 plug-ins on Windows, and the AudioPluginHost example has been updated to showcase these changes.


Unity native plug-in support

JUCE now supports building Unity native audio plug-ins, which can used within the Unity Editor, allowing you to leverage JUCE’s DSP and audio processing code within your Unity projects. More details on how to set this up can be found here.

Screenshot 2018-11-06 at 16.37.53

Microsoft BLE MIDI support

JUCE now supports the WinRT MIDI API on the latest version of Windows 10, providing access to improved throughput performance and BLE MIDI devices.

Plug-in parameter groups

Plug-in parameters can be organised into groups, allowing plug-in hosts to show a hierarchical view of your plug-in’s controls.

Support for production-ready Android OBOE

Google’s new audio API, OBOE, is supported where available on a device.

Video playback support on Android and iOS

On mobile platforms JUCE can use native APIs for video playback.

AudioProcessorValueTreeState improvements

The AudioProcessorValueTreeState now supports plug-in parameter groups and JUCE’s built-in plug-in parameter types.

Support for Android Studio 3.2

JUCE creates projects compatible with the latest version of the Android IDE.

Detailed list of new features


  • Support for adding Xcode subprojects
  • Made UI application templates fullscreen on mobile devices
  • Added an option to set the /MP (multi-processor compilation) option in the Visual Studio exporter
  • Fixed a bug in the VS exporter causing the PlatformToolset property to be duplicated

Audio/MIDI and plug-ins

  • Added MIDI output capability to the standalone plug-in
  • Made the dsp::Oversampling class more customisable
  • Added detection for some AVX512 features
  • Added support for Bela MIDI input
  • Added support for more sample rates to audio devices
  • Added AudioProcessLoadMeasurer utility class
  • Added a handleVstHostCallbackAvailable method to the VSTCallbackHandler interface
  • Added support for MIDI controller messages when hosting VST3 plug-ins
  • Added support for EQ curve graphs via a new AudioProcessor callback AudioProcessor::getAAXCurve()
  • macOS: Fixed a potential out-of-bounds array access in the CoreAudio internals
  • macOS: Fixed a VST3 resizing bug in FL Studio
  • macOS: Fixed a crash hiding an NSView in Vienna Ensemble Pro
  • Set the note-on time of MPESynthesiserVoice correctly
  • Fixed a potential AudioPluginInstance leak in AudioPluginFormatManager::createPluginInstanceAsync()
  • Ensure that setting a plug-in to be non-resizable using AudioProcessorEditor::setResizable() does not overwrite custom bounds constrainers
  • Make sure that the velocity value set in MidiKeyboardComponent::setVelocity() is used when sending notes
  • Linux: Fix problem with ALSA midi name in console applications


  • Android: Added broadcast address support


  • Linux: Added an option to lazily load libcurl symbols only when they are needed
  • macOS: Fixed some Objective-C id -> auto* conversion warnings
  • Linux: Fixed an issue with the X11 web browser not rendering content
  • Windows: Set the MB_TOPMOST flag for native alert windows if there are any alwaysOnTop JUCE windows so they don’t get stuck behind

GUI, Graphics & OpenGL

  • Linux: Fixed some potential deadlocks using OpenGL


  • Replaced ArrayAllocationBase with a safer storage container
  • Made many JUCE classes trivially copyable
  • Added converting constructors to OwnedArray, ArrayBase and HeapBlock
  • Added some macros for asserting when functions are called in an unsafe manner outside the message thread
  • Added a HeavyweightLeakedObjectDetector class and corresponding JUCE_HEAVYWEIGHT_LEAK_DETECTOR macro
  • Added a std::make_unique implementation to systems lacking c++14 support
  • Added classes ArgumentList and ConsoleApplcation which are helpers for writing console applications that parse and resolve command-line arguments
  • Various IPAddress and MACAddress class improvements
  • New NetworkServiceDiscovery::Advertiser and NetworkServiceDiscovery::AvailableServiceList classes to implement a simple protocol for discovering and connecting devices on the LAN
  • LittleFoot: Added support for global arrays
  • LittleFoot: Added the ability to #include other scripts
  • Fixed a bug adding ReferenceCountedArrays
  • Fixed a bug adding derived ReferenceCountedObjects to base class ReferenceCountedArrays
  • Fixed some dangling listeners in the BLOCKS demos
  • Fixed a some asan and ubsan warnings
  • Fixed an issue adding two RectangleLists
  • Fix for JSON stringification of INF and NaN double values
  • Fixed an issue when connecting to a non-existent NamedPipe


  • Change: The use of WinRT MIDI functions has been disabled by default for any version of Windows 10 before 1809 (October 2018 Update).

    • Possible Issues: If you were previously using WinRT MIDI functions on older versions of Windows then the new behaviour is to revert to the old Win32 MIDI API.

    • Workaround: Set the preprocessor macro JUCE_FORCE_WINRT_MIDI=1 (in addition to the previously selected JUCE_USE_WINRT_MIDI=1) to allow the use of the WinRT API on older versions of Windows.

    • Rationale: Until now JUCE's support for the Windows 10 WinRT MIDI API was experimental,due to longstanding issues within the API itself. These issues have been addressed in the Windows 10 1809 (October 2018 Update) release.
  • Change: The VST2 SDK embedded within JUCE has been removed.

    • Possible Issues: 1. Building or hosting VST2 plug-ins requires header files from the VST2 SDK,which is no longer part of JUCE. 2. Building a VST2-compatible VST3 plug-in (the previous default behaviour in JUCE) requires header files from the VST2 SDK, which is no longer part ofJUCE. When a new JUCE plug-in project is created the option JUCE_VST3_CAN_REPLACE_VST2 will be set to zero.

    • Workaround: 1. The VST2 SDK can be obtained from the vstsdk3610_11_06_2018_build_37 (or older) VST3 SDK or JUCE version 5.3.2. You should put the VST2 SDK in your header search paths or use the "VST (Legacy) SDK Folder" fields in the Projucer. 2. For new plug-in projects where you will be releasing both a VST2 and VST3 version, and you want the VST3 plug-in to replace the VST2 plug-in in hosts that support it, then you should enable the JUCE_VST3_CAN_REPLACE_VST2 option.

    • Rationale: Distributing VST2 plug-ins requires a VST2 license from Steinberg. Following Steinberg's removal of the VST2 SDK from their public SDKs we are also removing the VST2 SDK from the JUCE codebase.
  • Change: The AudioProcessorValueTreeState::createAndAddParameter function has been deprecated.

    • Possible Issues: Deprecation warnings will be seen when compiling code which uses this function and eventually builds will fail when it is later removed from the API.

    • Workaround: Previous calls to createAndAddParameter (paramID, paramName, ...) can be directly replaced with
using Parameter = AudioProcessorValueTreeState::Parameter;
createAndAddParameter (std::make_unique<Parameter> (paramID, paramName, ...));  

but an even better approach is to use the new AudioProcessorValueTreeState constructor where you can pass both RangedAudioParameters and AudioProcessorParameterGroups of RangedAudioParameters to the AudioProcessorValueTreeState and initialise the ValueTree simultaneously.

  • Rationale: The new createAndAddParameter method is much more flexible and enables any parameter types derived from RangedAudioParameter to be managed by the AudioProcessorValueTreeState.

  • Change: The Projucer's per-exporter Android SDK/NDK path options have been removed.

    • Possible Issues: Projects that previously used these fields may no longer build.

    • Workaround: Use the Projucer's global paths settings to point to these directories, either by opening the "Projucer/File->Global Paths..." menu item or using the "--set-global-search-path" command-line option.

    • Rationale: Having multiple places where the paths could be set was confusing and could cause unexpected mismatches.
  • Change: SystemStats::getDeviceDescription() will now return the device code on iOS e.g. "iPhone7, 2" for an iPhone 6 instead of just "iPhone".

    • Possible Issues: Code that previously relied on this method returning either explicitly "iPhone" or "iPad" may no longer work.

    • Workaround: Modify this code to handle the new device code string e.g. by changing: SystemStats::getDeviceDescription() == "iPhone"; to SystemStats::getDeviceDescription().contains ("iPhone");.

    • Rationale: The exact device model can now be deduced from this information instead of just the device family.
  • Change: DragAndDropContainer::performExternalDragDropOfFiles() and ::performExternalDragDropOfText() are now asynchronous on Windows.

    • Possible Issues: Code that previously relied on these operations being synchronous and blocking until completion will no longer work as the methods will return immediately and run asynchronously.

    • Workaround: Use the callback argument that has been added to these methods to register a lambda that will be called when the operation has been completed.

    • Rationale: The behaviour of these methods is now consistent across all platforms and the method no longer blocks the message thread on Windows.
  • Change: AudioProcessor::getTailLengthSeconds can now return infinity for VST/VST3/AU/AUv3.

    • Possible Issues: If you are using the result of getTailLengthSeconds to allocate a buffer in your host, then your host will now likely crash when loading a plug-in with an infinite tail time.

    • Workaround: Re-write your code to not use the result of getTailLengthSeconds directly to allocate a buffer.

    • Rationale: Before this change there was no way for a JUCE plug-in to report an infinite tail time.

Further Information

© Raw Material Software Limited