Introducing JUCE 5.3
System requirement changes
Tutorials and Documentation
A comprehensive list of new tutorials have been added to help the onboarding of new and existing JUCE users. Along with a new website design, the learning experience is improved by encouraging non-linear explorations of tutorials through categories. Existing tutorials have been updated to the latest coding standards and new tutorials provide in-depth explanations for JUCE features such as the DSP module, Analytics, In-App Purchases and Push Notifications. In addition, the online documentation now provides two separate master and develop branches to browse through.
PIPs (Projucer Instant Projects)
In order to streamline the process of writing and sharing simple JUCE applications, we are introducing PIPs. A PIP is a single header file containing some JUCE code and a chunk of metadata that is read by the Projucer to generate a JUCE project, taking care of the common startup/shutdown code and project settings for you. This means that it is now possible to create an entire JUCE project from a single file containing a Component, AudioProcessor or console application simply by drag and dropping the PIP onto the Projucer. The JUCE examples have been cleaned up, categorised and converted into PIPs that can be opened directly in the Projucer and previewed using the live-build engine via the “Open Example..” File menu command, and a new DemoRunner application has been created to allow you to preview all JUCE examples in one place and see the code side-by-side.
Hosted plug-in parameters
JUCE now extracts much more information about the parameters of a hosted audio plug-in, including proper value string support, the number of steps, and if the parameter should be represented by a drop down menu. This information is obtained both from the plug-in itself and is also parsed from any .vstxml files accompanying VST2 plug-ins. JUCE’s GenericAudioProcessorEditor has been updated to use this new functionality and now presents a much richer interface to a plug-in’s parameters.
Android Oboe support (developer preview)
Oboe is a C++ library for building low latency high-performance audio apps on Android. It supports API 16 onwards (99% of devices). Under the hood, Oboe uses OpenSL ES on API 16-26 and AAudio from API 27 (Android 8.1) onwards. AAudio introduces further audio performance improvements such as exclusive audio mode. When using Oboe, developers don’t have to code separately for OpenSL ES and AAudio, since Oboe intelligently picks the correct audio implementation at runtime. Oboe is currently in developer preview and is expected to be released in the near future. This preview allows for early access and evaluation for developers targeting Android platform. To enable Oboe in JUCE, simply download the Oboe repository from https://github.com/google/oboe, then in the Projucer set JUCE_USE_ANDROID_OBOE to Enabled and set the path to the repository in the Android exporter:
Detailed list of new Features
- Multiple Projucer UI and UX improvements
- Projucer: Added an option to clear the recent files list
- Projucer: Added menu items for managing the currently open windows
- Projucer: Added Help menu for quick access to online documentation
- Projucer: Added some drag+drop and copy-to-clipboard functions to the SVG helper tool
- Projucer: Expand concertina components fully on single-click
- Projucer: Added a set-global-search-path command line option
- Projucer: Added a Windows target platform option to the Code::Blocks exporter
- Changed the default language standard for new projects from C++11 to C++14
- Set all JUCE projects to use C++14
Audio/MIDI and Plug-Ins
- Updated JUCE's MPE classes to comply with the new MMA-adopted specification
- Added support for a subset of the Cockos VST extensions
- Added support for VST3 SDK 3.6.8
- Added support for loading VST3 preset files
- Added boolean AudioProcessorParameters
- Added thread safe methods for getting and setting the AudioProcessorValueTreeState state
- Cleanup and refactoring work on the AudioProcessorGraph and the audio plugin host demo
- DSP: Various improvements to the convolution engine
- DSP: Added a Phase class
- DSP: Added Butterworth methods to the FilterDesign class
- DSP: Various fixes and features including new LadderFilter
- Added new Sampler example project
- Added higher-order ambisonics support
- Added native content sharing support for iOS and Android
- Added iOS and Android native file chooser support
- Implemented WebBrowserComponent on Android
- Ensured that JUCE will always use the high-performance audio path on Android if the device supports it
- Added memory warning callbacks on iOS
- Refactored iOSAudioDevice to support multi-channel audio devices and improve the handling of sample rate changes from other apps
- Multiple improvements to the Android Studio exporter
- Improvements to push notifications
- Added PushNotifications support on OSX
- Added customisable MacOS icons
- Changed Windows projects to use dynamic runtime linking by default
GUI, Graphics & OpenGL
- Added the ability to adjust the number of decimal places displayed by a Slider
- Added SidePanel and BurgerMenu component classes
- Added lambda callbacks to ListenerList, Slider, Button, Label, ComboBox and TextEditor
- Various graphics optimisations
The JUCE examples have been cleaned up, modernised and converted into PIPs (Projucer Instant Projects).
The JUCE Demo has been removed and replaced by the DemoRunner application and larger projects such as the Audio Plugin Host and the Network Graphics Demo have been moved into the extras directory.
Possible Issues: 1. Due to the large number of changes that have occured in the JUCE Git repository, pulling this version may result in a messy folder structure with empty directories that have been removed. 2. The JUCE Demo project is no longer in the JUCE repository. 3. The Audio Plugin Host project has moved from the examples directory to the extras.
Workaround: 1. Run a Git clean command (git clean -xdf) in your JUCE directory to remove all untracked files, directories and build products. 2. The new DemoRunner application, located in extras/DemoRunner, can be used to preview all the JUCE examples and see the code side-by-side. 3. Change any file paths that depended on the plugin host project being located in the examples directory to use the extras directory instead.
- Rationale: The JUCE examples had inconsistent naming, coding styles and the projects and build products took up a large amount of space in the repository. Replacing them with PIPs reduces the file size and allows us to categorise the examples better, as well as cleaning up the code.
When hosting plug-ins all AudioProcessor methods of managing parameters that take a parameter index as an argument have been deprecated.
Possible Issues: A single assertion will be fired in debug builds on the first use of a deprecated function.
Workaround: When hosting plug-ins you should use the AudioProcessor::getParameters() method and interact with parameters via the returned array of AudioProcessorParameters. For a short-term fix you can also continue past the assertion in your debugger, or temporarily modify the JUCE source code to remove it.
- Rationale: Given the structure of JUCE's API it is impossible to deprecate these functions using only compile-time messages. Therefore a single assertion, which can be safely ignored, serves to indicate that these functions should no longer be used. The move away from the AudioProcessor methods both improves the interface to that class and makes ongoing development work much easier.
The InAppPurchases class is now a JUCE Singleton.
This means that you need to get an instance via InAppPurchases::getInstance(), instead of storing a InAppPurchases object yourself.
Possible Issues: Any code using InAppPurchases needs to be updated to retrieve a singleton pointer to InAppPurchases.
- Workaround: Instead of holding a InAppPurchase member yourself, you should get an instance via InAppPurchases::getInstance(), e.g.
InAppPurchases iap; iap.purchaseProduct (...);
- Rationale: This change was required to fix an issue on Android where on failed transaction a listener would not get called.
JUCE's MPE classes have been updated to reflect the official specification recently approved by the MIDI Manufacturers Association (MMA).
Possible Issues: The most significant changes have occurred in the MPEZoneLayout classes and programs using the higher level MPE classes such as MPEInstrument, MPESynthesiser, MPESynthesiserBase and MPESynthesiserVoice should be unaffected.
Previously, any MIDI channel from 1 - 15 could be selected to be the master channel of an MPE zone, with a specified number of member channels ascending from the master channel + 1. However, in the new specification this has been simplified so that a device only has a lower and/or an upper zone, where the lower zone has master channel 1 and assigns new member channels ascending from channel 2 and the upper zone has master channel 16 and assigns new member channels descending from channel 15.
Workaround: Use the MPEZoneLayout::setLowerZone() and MPEZoneLayout::setUpperZone() methods to set zone layouts.
Any UI that allows users to select and set zones on an MPE instrument should also be updated to reflect the specification changes.
- Rationale: The MPE classes in JUCE are out of date and should be updated to reflect the new, official MPE standard.
Android: Calling JUCEApplicationBase::quit() on Android will now really quit the app, rather than just placing it in background.
Starting with API level 21 (Android 5.0), the app will not appear in recent apps list after calling quit(). Prior to API 21, the app will still appear in recent app lists but when a user chooses the app, a new instance of the app will be started.
Possible Issues: Any code calling JUCEApplicationBase::quit() to place the app in background will close the app instead.
Workaround: Use Process::hide().
- Rationale: The old behaviour JUCEApplicationBase::quit() was confusing JUCE code, as a new instance of JUCE app was attempted to be created, while the older instance was still running in background. This would result in assertions when starting a second instance.
Windows: Release builds will now link to the dynamic C++ runtime by default
Possible Issues: If you are creating a new .jucer project, then your plug-in will now link to the dynamic C++ runtime by default, which means that you MUST ensure that the C++ runtime libraries exist on your customer's computers.
Workaround: If you are only targeting Windows 10, then the C++ runtime is now part of the system core components and will always exist on the computers of your customers (just like kernel332.dll, for example). If you are targeting Windows versions between Vista and Windows 10, then you should build your plug-in with the latest updated version of VS2015 or later, which ensures that it's linked to the universal runtime. Universal runtime is part of the system's core libraries on Windows 10 and on Windows versions Vista to 8.1, it will be available on your customer's computers via Windows Update. Unfortunately, if your customer has just installed Windows 8.1 to Vista on a fresh computer, then there is a chance that the update mechanism for the universal runtime hasn't triggered yet and your plug-in may still fail. Your installer should prompt the user to install all the Windows updates in this case or you can deploy the universal runtime as a redistributable with your installer. If you are targeting earlier versions of Windows then you should always include the runtime as a redistributable with your plug-in's installer. Alternatively, you can change the runtime linking to static (however, see 'Rationale' section).
- Rationale: In a recent update to Windows 10, Microsoft has limited the number of fiber local storage (FLS) slots per process. Effectively, this limits how many plug-ins with static runtime linkage can be loaded into a DAW. In the worst case, this limits the total number of plug-ins to a maximum of 64 plug-ins. There is no workaround for DAW vendors and the only solution is to push plug-in vendors to use the dynamic runtime. To help with this, JUCE has decided to make dynamic runtime linkage the default in JUCE.
AudioProcessorGraph interface has changed in a number of ways.
Node objects are now reference counted, there are different accessor methods to iterate them, and misc other small improvements to the API.
Possible Issues: The changes won't cause any silent errors in user code, but will require some manual refactoring.
Workaround: Just find equivalent new methods to replace existing code.
- Rationale: The graph class was extremely old and creaky, and these changes is the start of an improvement process that should eventually result in it being broken down into fundamental graph building block classes for use in other contexts.
Various Other Improvements & Bug Fixes
- Fixed an issue with the back button on Android
- Fixed an issue selecting the initial file of directory in native FileChoosers
- Improved Windows pen behaviour
- Improved iOS microphone permissions message
- Improved the handling of sidechain AAX plugins
- Added SystemStats::getDeviceManufacturer()
- Made the ScopedPointer interface more compatible with std::unique_ptr
- Multiple threading and undefined behaviour fixes and improvements
- Android: Updated default gradle android plugin version to 3.0.1
- Make setPlayHead in AudioProcessorGraph thread safe
- Added options to PluginListComponent and PluginDirectoryScanner to allow scanning of a specific set of files
- Added an initialiser list based ValueTree constructor
- Projucer: Added some options to the SVG path converter to toggle stroke/fill and closing sub-paths
- Added methods AbstractFifo::read() and AbstractFifo::write() which return a scope-based object to make it easy to hold, release and iterate blocks of items.
- VST3: Pass meter values to hosted plug-ins
- VST3: Detect when parameters are automatable when hosting
- Android: Added utility macro to log JNI references table.
- OpenGL: Apply Component's transform when invalidating
- Enabled std::atomic for Android
- Windows: Fixed an issue getting file icons with an alpha channel
- Deprecated some old functions roundDoubleToInt and roundFloatToInt
- Added an option to Slider::setVelocityModeParameters() to set the modifier keys
- Implemented the menuActive flag in TextEditor
- Added a showMenuAsync() method to PopupMenu that takes a std::function
- Projucer: Update VS exporter optimisation level options to correspond to the options in VS
- Projucer: Apply typeface name to font when loading painted text from XML
- CoreAudio: Better handling of background device changes
- Added some BSD target support
- Projucer: Show the menu for adding a new module when clicking the "+" button in the modules panel even if a module is currently selected
- Fixed some issues with IO channel counts in the StandaloneFilterWindow
- Fixed an issue with setAudioPreprocessingEnabled on iOS
- Made the sorting of plug-ins in KnownPluginList case-insensitive
- Added CURLOPT_NOSIGNAL to the cURL configuration
- Added a parallelogram class
- Replaced some old embedded images in the LookAndFeel with SVG
- Added some get/set/addSample methods to AudioBlock
- Simplified the Path class by making it use an Array for storage.
- StandaloneFilterWindow: hide title bar on iOS and Android even when not in Kiosk mode.
- VST3: Fixed an issue with parallel streams of parameter updates during playback
- Android: ensure that navigation/status bar visibility is correctly restored when the app gets resumed.
- StandalonePluginWindow: allow to customise kiosk mode enablement.
- Added a method to DatagramSocket to set whether multicast loopback should be enabled
- Added some next/prev window commands to the projucer
- Optimised the checking process for duplicate parameter IDs
- Enabled JUCE_CONSTEXPR for older versions of clang
- Fixed a bug in Windows plugins where the display bounds were not being updated when the scale factor was changed
- Added some methods to OSCSender and OSCReceiver to allow them to use existing sockets
- Fixed some CoreAudio errors when detecting bit depths
- Projucer: Draw transparent iOS app icons onto a white background so that they are valid
- Added an assertion to catch people using more than one TooltipWindow
- Added some extra methods to the interpolator classes
- Fixed a bug where PopupMenus with a scale factor applied were not appearing in the correct position
- Changed the parameters to Graphics::fillCheckerBoard() to be floats rather than ints, and improved its performance
- Projucer: Added some extra flags to the Visual Studio AAX copy step to ensure that hidden files are copied and file attributes are maintained
- CLion: Fixed a missing suffix when creating static libraries
- Fixed some data races in the CoreAudio audio device and in the Atomic and AbstractFifo classes
- Fixed a data race in the Thread destructor
- Various additions to SIMDRegister
- Added a SampleType accessor definition to AudioBuffer
- Added some methods to MidiKeyboardComponent to set/get the width of black notes
- Improved the idling of socket InterprocessConnections
- Added Component::isPaintingUnclipped
- LookAndFeel_V4: Use getSliderThumbRadius() when drawing slider thumb
- AU: Ensured that parameter changes coming from the host do not call the host listeners with the same change
- Added some colourIds to FileBrowserComponent to control current path ComboBox and filename TextEditor colours
- VST3 Hosting: Added a more robust way to check if a VST3 plug-in has midi inputs/outputs
- Added functionality to tell ProTools when a parameter name changes.
- Added DirectoryContentsDisplayComponent::ColourIds::highlightedTextColourId
- Removed a line in LookAndFeel_V4::drawFileBrowserRow() that could result in multiple unnecessary repaints
- Added ComboBox::ColourIds::focusedOutlineColourId
- Added a componentEnablementChanged method to ComponentListener
- Increased the movement tolerance for double-clicks when using a touch input source
- Ensured that JUCE_HAS_CONSTEXPR is enabled on MSVC 1900
- Added some methods ColourGradient::vertical and ColourGradient::horizontal, and also some missing move operators for that class
- DSP: Added an alignment argument to AudioBlock
- DSP: Added SIMDRegister::copyToRawArray and SIMDRegister::fromRawArray to easily convert between raw arrays and SIMD registers
- Projucer: use “userLandscape” or “sensorLandscape” screen orientation for Android if available.
- Optimised the GL renderer to avoid splitting large rectangles into horizontal strips unnecessarily
- Android: Add bluetooth permissions to the JuceDemo
- Avoided some unnecessary reallocations in AudioBuffer::setSize()
- Added a parameter to ValueTree::getPropertyAsValue() to allow synchronous updates
- Projucer: Update VS2017 project to use latest Windows 10 SDK
- Made the PopupMenu use the L+F to set the border it uses for custom components, and improved the layout of menus with icons
- Projucer: Improved the layout of the user settings popup window