diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000000..93504dc1cd --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,23 @@ +Checks: > + -clang-analyzer-cplusplus.NewDeleteLeaks, + -clang-analyzer-optin.performance.Padding, + -clang-analyzer-security.FloatLoopCounter, + -clang-analyzer-security.insecureAPI.strcpy, + modernize-concat-nested-namespaces, + +WarningsAsErrors: '*' + +# No negative lookahead available here, which makes things difficult. +# +# We want checks to run on JUCE files included from the JUCE modules. We can +# restrict these to files named `juce_.*`. +# +# We also want checks to run on any files inlcuded from the examples or extras +# directories. However, some include paths generated by the Android Studio build +# system look like: +# +# ~/JUCE/examples/DemoRunner/Builds/Android/app/../../../../../modules/juce_box2d/box2d/Collision/b2CollideEdge.cpp +# +# Since we can only opt-in to paths, we restrict the maximum depth of the path +# past examples/extras. +HeaderFilterRegex: '(.*\/modules\/juce_.*juce_[^\/]*$)|(\/(examples|extras)(\/[^\/]*){1,7}$)' diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 686c5b1ee2..13bf7b7330 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -48,10 +48,11 @@ body: multiple: true options: - x86_64 - - ARM - - Other - - 64-bit - - 32-bit + - Arm64/aarch64 + - Arm64EC (Windows) + - x86 (Windows, Android) + - 32 bit Arm (Linux, Android) + - Unsupported validations: required: true - type: textarea diff --git a/.gitignore b/.gitignore index 8f482be812..629e360a22 100644 --- a/.gitignore +++ b/.gitignore @@ -65,3 +65,5 @@ extras/Projucer/JUCECompileEngine.dylib /build CMakeUserPresets.json +.editorconfig + diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e91a6b175c..4962bc719e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,4 +1,9 @@ -include: - - project: 'juce-repos/JUCE-utils' - file: '/CI/gitlab-ci.yml' +variables: + REF: &REF master +include: + - project: juce-repos/JUCE-utils + file: /CI/gitlab-ci.yml + ref: *REF + inputs: + ref: *REF diff --git a/BREAKING-CHANGES.txt b/BREAKING_CHANGES.md similarity index 57% rename from BREAKING-CHANGES.txt rename to BREAKING_CHANGES.md index 973f3e0746..2c1cee87ee 100644 --- a/BREAKING-CHANGES.txt +++ b/BREAKING_CHANGES.md @@ -1,65 +1,1558 @@ -JUCE breaking changes -===================== +# JUCE breaking changes -Version 7.0.3 -============= +# Version 8.0.4 + +## Change + +The Javascript implementation has been moved into a independent juce module. + +**Possible Issues** + +Any existing use of JavascriptEngine, JSCursor, or JSObject will fail to compile. + +**Workaround** + +Add the new juce_javascript module to the project. + +**Rationale** + +The Javascript implementation increases compilation times while being required +by only a select number of projects. + + +## Change + +The VBlankAttachment class' inheritance from the ComponentPeer::VBlankListener +and ComponentListener classes has been made private. + +**Possible Issues** + +External code that calls VBlankAttachment::onVBlank or +VBlankAttachment::componentParentHierarchyChanged will fail to compile. + +**Workaround** + +There is no workaround. + +**Rationale** + +Making the inheritance public originally was an oversight. The overriden +functions are meant to be called only by the ComponentPeer and Component objects +that the VBlankAttachment instance registers itself with. External code calling +these functions undermines the correct behaviour of the VBlankAttachment class. + + +## Change + +The signature of VBlankListener::onVBlank() was changed to +VBlankListener::onVBlank (double), with the addition of a timestamp parameter +that corresponds to the time at which the next frame will be displayed. + +**Possible Issues** + +Code that overrides VBlankListener::onVBlank() will fail to compile. + +**Workaround** + +Add a double parameter to the function overriding VBlankListener::onVBlank(). +The behaviour will be unchanged if this new parameter is then ignored. + +**Rationale** + +A timestamp parameter has been missing from the VBlank callback since its +addition. The new parameter allows all VBlankListeners to synchronise the +content of their draw calls to the same frame timestamp. + + +# Version 8.0.2 + +## Change + +Font::getStringWidth and Font::getStringWidthFloat have been deprecated. +Font::getGlyphPositions has been removed. + +**Possible Issues** + +Code that uses these functions will raise warnings at compile time, or fail +to build. + +**Workaround** + +Use GlyphArrangement::getStringWidth or TextLayout::getStringWidth to find the +width of a string taking font-fallback and shaping into account. + +To find individual glyph positions, lay out the string using GlyphArrangement +or TextLayout, then use the positions provided by +GlyphArrangement::PositionedGlyph and/or TextLayout::Glyph. + +**Rationale** + +The results of the old Font member functions computed their results assuming +that ligatures and other font features would not be used when rendering the +string. The functions would also substitute missing characters with the Font's +notdef/tofu glyph instead of using a fallback font. + +Using GlyphArrangement or TextLayout will use a sophisticated text shaping +algorithm to lay out the string, with support for font fallback. + + +## Change + +The constructors of the WebSliderRelay, WebToggleButtonRelay and +WebComboBoxRelay classes were changed and they no longer accept a reference +parameter to a WebBrowserComponent object. + +**Possible Issues** + +Code that uses these classes will fail to compile. + +**Workaround** + +Omit the WebBrowserComponent parameter when constructing the relay objects. + +**Rationale** + +The relay classes use a new underlying mechanism to obtain a pointer to the +WebBrowserComponent object. When calling the +WebBrowserComponent::Options::withOptionsFrom() function with the relay as a +parameter, the corresponding WebBrowserComponent object will notify the relay +about its creation and destruction. + +This avoids the anti-pattern where the relay class required a reference to a +yet uninitialised WebBrowserComponent object. + + +## Change + +The coefficients of LadderFilter::Mode::BPF12 have been changed, causing a +slight change in the filter's transfer function. + +**Possible Issues** + +Code that uses the LadderFilter in BPF12 mode may produce different output +samples. + +**Workaround** + +There is no workaround. If you need this functionality, please let us know +about your use case. In the meantime, you may be able to copy the old class +into your own project/module and use it that way. + +**Rationale** + +The LadderFilter implementation follows the paper Valimaki (2006): Oscillator +and Filter Algorithms for Virtual Analog Synthesis. The BPF12 mode coefficients +however contained a typo compared to the paper, making the BPF12 mode incorrect. + + +# Version 8.0.1 + +## Change + +All member functions of DynamicObject other than clone() and writeAsJSON() have +been made non-virtual. + +**Possible Issues** + +Classes that override these functions will fail to compile. + +**Workaround** + +Instead of overriding hasMethod() and invokeMethod(), call setMethod() to +add new member functions. + +Instead of overriding getProperty() to return a custom property, add that +property using setProperty(). + +**Rationale** + +Allowing the implementations of these functions to be changed may cause derived +types to accidentally break the invariants of the DynamicObject type. +Specifically, the results of hasMethod() and hasProperty() must be consistent +with the result of getProperties(). Additiionally, calling getProperty() should +return the same var as fetching the property through getProperties(), and +calling invokeMethod() should behave the same way as retrieving and invoking a +NativeFunction via getProperties(). + +More concretely, the new QuickJS-based Javascript engine requires that all +methods/properties are declared explicitly, which cannot be mapped to the more +open-ended invokeMethod() API taking an arbitrary method name. Making +invokeMethod() non-virtual forces users to add methods with setMethod() instead +of overriding invokeMethod(), which is more compatible with QuickJS. + + +## Change + +The default JSON encoding has changed from ASCII escape sequences to UTF-8. + +**Possible Issues** + +JSON text exchanged with a non-standard compliant parser expecting ASCII +encoding, may fail to parse UTF-8 encoded JSON files. Reliance on the raw JSON +encoded string literal, for example for file comparison, Base64 encoding, or any +encryption, may result in false negatives for JSON data containing the same data +between versions of JUCE. + +Note: JSON files that only ever encoded ASCII text will NOT be effected. + +**Workaround** + +Use the `JSON::writeToStream()` or `JSON::toString()` functions that take a +`FormatOptions` parameter and call `withEncoding (JSON::Encoding::ascii)` on the +`FormatOptions` object. + +**Rationale** + +RFC 8259 states + +> JSON text exchanged between systems that are not part of a closed ecosystem +MUST be encoded using UTF-8 [RFC3629]. +> +> Previous specifications of JSON have not required the use of UTF-8 when +transmitting JSON text. However, the vast majority of JSON-based software +implementations have chosen to use the UTF-8 encoding, to the extent that it is +the only encoding that achieves interoperability. + +For this reason UTF-8 encoding has better interoperability than ASCII escape +sequences. + + +## Change + +The ASCII and Unicode BEL character (U+0007) escape sequence has changed in the +JSON encoder from "\a" to "\u0007". + +**Possible Issues** + +Reliance on the raw JSON encoded string literal, for example for file comparison, +base-64 encoding, or any encryption, may result in false negatives for JSON data +containing a BEL character between versions of JUCE. + +**Workaround** + +Use string replace, for example call `replace ("\\u007", "\\a")` on the +resulting JSON string to match older versions of JUCE. + +**Rationale** + +The JSON specification does not state that the BEL character can be escaped +using "\a". Therefore other JSON parsers incorrectly read this character when +they encounter it. + + +## Change + +The LowLevelGraphicsPostscriptRenderer has been removed. + +**Possible Issues** + +Code that uses this class will no longer compile. + +**Workaround** + +There is no workaround. If you need this functionality, please let us know +about your use case. In the meantime, you may be able to copy the old classes +into your own project/module and use them that way. + +**Rationale** + +We are not aware of any projects using this functionality. This renderer was +not as fully-featured as any of the other renderers, so it's likely that users +would have filed issue reports if they were using this feature. + + +## Change + +Support for the MinGW toolchain has been removed. + +**Possible Issues** + +MinGW can no longer be used to build JUCE. + +**Workaround** + +On Windows, use an alternative compiler such as Clang or MSVC. + +Cross-compiling for Windows from Linux is not supported, and there is no +workaround for this use case. + +**Rationale** + +The MinGW provides a poor user experience, with very long build times and +missing features. The high maintenance cost, both in terms of developer time, +and continuous integration bandwidth (both of which could provide more value +elsewhere), means that continued support for MinGW is difficult to justify. + + +## Change + +The GUI Editor has been removed from the Projucer. + +**Possible Issues** + +The Projucer can no longer be used to visually edit JUCE Components. + +**Workaround** + +There is no workaround. + +**Rationale** + +This feature has been deprecated, without receiving bugfixes or maintenance, +for a long time. + + +## Change + +The Visual Studio 2017 exporter has been removed from the Projucer. + +**Possible Issues** + +It will no longer be possible to generate Visual Studio 2017 projects using the +Projucer. + +**Workaround** + +Use a different exporter, such as the exporter for Visual Studio 2019 or 2022. + +**Rationale** + +Since JUCE 8, the minimum build requirement has been Visual Studio 2019. This +minimum requirement allows JUCE to use modern C++ features, along with modern +Windows platform features. + + +## Change + +The Code::Blocks exporter has been removed from the Projucer. + +**Possible Issues** + +It will no longer be possible to generate Code::Blocks projects using the +Projucer. + +**Workaround** + +Use a different exporter, such as the Makefile exporter on Linux, or one of the +Visual Studio exporters on Windows. + +**Rationale** + +The Code::Blocks IDE does not seem to be actively maintained. Other projects +are dropping support, with the Code::Blocks generator deprecated in CMake 3.27. +Additionally, the Code::Blocks exporter did not provide a good user experience, +especially for new users on Windows, as it defaulted to using the MinGW +toolchain. This toolchain tends to be slow to build and link, and is not fully +supported by JUCE, missing support for some audio and video backends, and +plugin formats. + + +## Change + +The tab width when rendering text with the GlyphArrangement and TextLayout +classes now equals the width of a space. Previously it equaled the width of a +tofu character used for missing glyphs. + +**Possible Issues** + +User interfaces using the GlyphArrangement and TextLayout classes directly to +render text containing tabs will look differently. The TextEditor and +CodeEditorComponent classes have special logic for replacing the tabs prior to +rendering, and consequently, these are not affected. + +**Workaround** + +Replace the tab characters prior to rendering and substitute them with the +required number of non-breaking spaces. + +**Rationale** + +Since the Unicode related revamping of JUCE's text rendering classes, tab +characters would raise assertions and would be rendered with the tofu glyph. +This change visually treats tab characters as non-breaking spaces. Since the +JUCE 7 behaviour of using the tofu glyph's width was not a conscious decision, +but rather a side effect of ignoring unresolved glyphs, using a default width +of one space is more reasonable. + + +# Version 8.0.0 + +## Change + +The virtual functions ResizableWindow::getBorderThickness() and +ResizableWindow::getContentComponentBorder() are now const. + +**Possible Issues** + +Classes overriding these functions will fail to compile. + +**Workaround** + +Add 'const' to overriding functions. + +**Rationale** + +Omitting 'const' from these functions implies that they may change the state of +the ResizableWindow, which would be unexpected behaviour for getter functions. +It also means that the functions cannot be called from const member functions, +which limits their usefulness. + + +## Change + +As part of the Unicode upgrades TextLayout codepaths have been unified across +all platforms. As a consequence the behaviour of TextLayout on Apple platforms +will now be different in two regards: +- With certain fonts, line spacing will now be different. +- The AttributedString option WordWrap::byChar will no longer have an effect, + just like it didn't have an effect on non-Apple platforms previously. Wrapping + will now always happen on word boundaries. + +Furthermore, the JUCE_USE_DIRECTWRITE compiler flag will no longer have any +effect. + +**Possible Issues** + +User interfaces using TextLayout and the WordWrap::byChar option will have their +appearance altered on Apple platforms. The line spacing will be different for +certain fonts. + +**Workaround** + +There is no workaround. + +**Rationale** + +The new, unified codepath has better support for Unicode text in general. The +font fallback mechanism, which previously was only available using the removed +codepaths is now an integral part of the new approach. By removing the +alternative codepaths, text layout and line spacing has become more consistent +across the platforms. + + +## Change + +As part of the Unicode upgrades the vertical alignment logic of TextLayout has +been altered. Lines containing text written in multiple different fonts will +now have their baselines aligned. Additionally, using the +Justification::verticallyCentred or Justification::bottom flags may now result +in the text being positioned slightly differently. + +**Possible Issues** + +User interfaces using TextLayout with texts drawn using multiple fonts will now +have their look changed. + +**Workaround** + +There is no workaround. + +**Rationale** + +The old implementation had incosistent vertical alignment behaviour. Depending +on what exact fonts the first line of text happened to use, the bottom alignment +would sometimes produce unnecessary padding on the bottom. With certain text and +Font combinations the text would be drawn beyond the bottom boundary even though +there was free space above the text. + +The same amount of incorrect vertical offset, that was calculated for bottom +alignment, was also present when using centred, it just wasn't as apparent. + +Not having the baselines aligned between different fonts resulted in generally +displeasing visuals. + + +## Change + +The virtual functions LowLevelGraphicsContext::drawGlyph() and drawTextLayout() +have been removed. + +**Possible Issues** + +Classes overriding these functions will fail to compile. + +**Workaround** + +Replace drawGlyph() with drawGlyphs(), which draws several glyphs at once. +Remove implementations of drawTextLayout(). + +**Rationale** + +On Windows and macOS, drawing several glyphs at once is faster than drawing +glyphs one-at-a-time. The new API is more general, and allows for more +performant text rendering. + + +## Change + +JUCE widgets now query the LookAndFeel to determine the TypefaceMetricsKind to +use. By default, the LookAndFeel will specify the "portable" metrics kind, +which may change the size of text in JUCE widgets, depending on the font and +platform. + +**Possible Issues** + +Using "portable" metrics may cause text to render at a different scale when +compared to the old "legacy" metrics. + +**Workaround** + +If you want to restore the old metrics, e.g. to maintain the same text scaling +in an existing app, you can override LookAndFeel::getDefaultMetricsKind() on +each LookAndFeel in your application, to return the "legacy" metrics kind. + +**Rationale** + +Using portable font metrics streamlines the development experience when working +on applications that must run on multiple platforms. Using portable metrics by +default means that new projects will benefit from this improved cross-platform +behaviour from the outset. + + +## Change + +Signatures of several Typeface member functions have been updated to accept a +new TypefaceMetricsKind argument. The getAscent(), getDescent(), and +getHeightToPointsFactor() members have been replaced by getMetrics(), which +returns the same metrics information all at once. + +Font instances now store a metrics kind internally. Calls to Font::getAscent() +and other functions that query font metrics will always use the Font's stored +metrics kind. Calls to Font::operator== will take the metrics kinds into +account, so two fonts that differ only in their stored metrics kind will +be considered non-equal. + +**Possible Issues** + +Code that calls any of the affected Typeface functions will fail to compile. +Code that compares Font instances may behave differently if the compared font +instances use mismatched metrics kinds. + +**Workaround** + +Specify the kind of metrics you require when calling Typeface member functions. +Call getMetrics() instead of the old individual getters for metrics. Review +calls to Font::operator==, especially where comparing against a +default-constructed Font. + +**Rationale** + +Until now, the same font data could produce different results from +Typeface::getAscent() et al. depending on the platform. The updated interfaces +allow the user to choose between the old-style non-portable metrics (to avoid +layout changes in existing projects), and portable metrics (more suitable for +new or cross-platform projects). +Most users will fetch metrics from Font objects rather than from the Typeface. +Font will continue to return non-portable metrics when constructed using the +old (deprecated) constructors. Portable metrics can be enabled by switching to +the new Font constructor that takes a FontOptions argument. See the +documentation for TypefaceMetricsKind for more details. + + +## Change + +Typeface::getOutlineForGlyph now returns void instead of bool. + +**Possible Issues** + +Code that checks the result of this function will fail to compile. + +**Workaround** + +Omit any checks against the result of this function. + +**Rationale** + +This function can no longer fail. It may still output an empty path if the +requested glyph isn't present in the typeface. + + +## Change + +CustomTypeface has been removed. + +**Possible Issues** + +Code that interacts with CustomTypeface will fail to compile. + +**Workaround** + +There is currently no workaround. If you were using CustomTypeface to +implement typeface fallback, there is a new API, +Font::findSuitableFontForText, that you can use to locate fonts capable +of rendering given strings. + +**Rationale** + +The CustomTypeface class is difficult/impossible to support with the new +HarfBuzz Typeface implementation. New support for automatic font fallback +will be introduced in JUCE 8, and this will obviate much of the need for +CustomTypeface. + + +## Change + +The Android implementations of Typeface::getStringWidth(), getGlyphPositions(), +and getEdgeTableForGlyph() have been updated to return correctly-normalised +results. The effect of this change is to change (in practice, slightly reduce) +the size at which many fonts will render on Android. + +**Possible Issues** + +The scale of some text on Android may change. + +**Workaround** + +For font sizes specified in 'JUCE units' by passing a value to the Font +constructor or to Font::setHeight, instead pass the same size to +Font::withPointHeight and use the returned Font object. + +**Rationale** + +The behaviour of the Typeface member functions did not match the documented +behaviour, or the behaviour on other platforms. This could make it difficult to +create interfaces that rendered as expected on multiple platforms. + +The upcoming unicode support work will unify much of the font-handling and +text-shaping machinery in JUCE. Ensuring that all platforms have consistent +behaviour before and after the unicode upgrade will make it easier to implement +and verify those changes. + + +## Change + +The JavascriptEngine::callFunctionObject() function has been removed. + +**Possible Issues** + +Projects that used the removed function will fail to compile. + +**Workaround** + +Use the JSObjectCursor::invokeMethod() function to call functions beyond the +root scope. + +**Rationale** + +The JavascriptEngine's underlying implementation has been changed, and the +DynamicObject type is no longer used for the internal implementation of the +engine. The JSObjectCursor class provides a way to navigate the Javascript +object graph without depending on the type of the engine's internal +implementation. + + +## Change + +The JavascriptEngine::getRootObjectProperties() function returns its result by +value instead of const reference. + +**Possible Issues** + +Projects that captured the returned value by reference and depended on it being +valid for more than the current function's scope may stop working correctly. + +**Workaround** + +If the return value is used beyond the calling function's scope it must be +stored in a value. + +**Rationale** + +The JavascriptEngine's underlying implementation has been changed, and the +NamedValueSet type is no longer used in its internal representation. Hence a new +NamedValueSet object is created during the getRootObjectProperties() function +call. + + +## Change + +JavascriptEngine::evaluate() will now return a void variant if the passed in +code successfully evaluates to void, and only return an undefined variant if +an error occurred during evaluation. The previous implementation would return +var::undefined() in both cases. + +**Possible Issues** + +Projects that depended on the returned value of JavascriptEngine::evaluate() to +be undefined even during successful evaluation may fail to work correctly. + +**Workaround** + +Code paths that depend on an undefined variant to be returned should be checked +if they aren't used exclusively to determine evaluation failure. In failed +cases the JavascriptEngine::evaluate() function will continue to return +var::undefined(). + +**Rationale** + +When a Javascript expression successfully evaluates to void, and when it fails +evaluation due to timeout or syntax errors are distinctly different situations +and this should be reflected on the value returned. + + +## Change + +The old JavascriptEngine internals have been entirely replaced by a new +implementation wrapping the QuickJS engine. + +**Possible Issues** + +Code that previously successfully evaluated using JavascriptEngine::evaluate() +or JavascriptEngine::execute(), could now fail due to the rules applied by the +new, much more standards compliant engine. One example is object literals +e.g. { a: 'foo', b: 42, c: {} }. When evaluated this way the new engine will +assume that this is a code block and fail. + +**Workaround** + +When calling JavascriptEngine::evaluate() or JavascriptEngine::execute() the +code may have to be updated to ensure that it's correct according to the +Javascript language specification and in the context of that evaluation. Object +literals standing on their own for example should be wrapped in parentheses +e.g. ({ a: 'foo', b: 42, c: {} }). + +**Rationale** + +The new implementation uses a fully featured, performant, standards compliant +Javascript engine, which is a significant upgrade. + + +## Change + +The `WebBrowserComponent::pageAboutToLoad()` function on Android now only +receives callbacks for entire page navigation events, as opposed to every +resource fetch operation. Returning `false` from the function now prevents +this operation from taking any effect, as opposed to producing potentially +visible error messages. + +**Possible Issues** + +Code that previously depended on the ability to allow or fail resource +requests on Android may fail to work correctly. + +**Workaround** + +Navigating to webpages can still be prevented by returning `false` from this +function, similarly to other platforms. + +Resource requests sent to the domain returned by +`WebBrowserComponent::getResourceProviderRoot()` can be served or rejected by +using the `WebBrowserComponent::ResourceProvider` feature. + +Resource requests sent to other domains can not be controlled on Android +anymore. + +**Rationale** + +Prior to this change there was no way to reject a page load operation without +any visible effect, like there was on the other platforms. The fine grained per +resource control was not possible on other platforms. This change makes the +Android implementation more consistent with the other platforms. + + +## Change + +The minimum supported compilers and deployment targets have been updated, with +the new minimums listed in the top level [README](README.md). + +MinGW is no longer supported. + +**Possible Issues** + +You may no longer be able to build JUCE projects or continue targeting older +platforms. + +**Workaround** + +If you cannot build your project, update your build machine to a more modern +operating system and compiler. + +There is no workaround to target platforms that predate the new minimum +deployment targets. + +**Rationale** + +New features of JUCE require both more modern compilers and deployment targets. + +The amount of investment MinGW support requires is unsustainable. + + +## Change + +The [JUCE End User Licence Agreement](https://juce.com/legal/juce-8-licence/) +has been updated and all JUCE modules are now dual-licensed under the AGPLv3 and +the JUCE licence. Previously the juce_audio_basics, juce_audio_devices, +juce_core and juce_events modules were licensed under the ISC licence. + +Please read the End User Licence Agreement for full details. + +**Possible Issues** + +There may be new restrictions on how you can use JUCE. + +**Workaround** + +N/A + +**Rationale** + +The new JUCE End User Licence Agreement is much easier to understand, and has a +much more generous personal tier. The move from ISC to AGPLv3/JUCE simplifies +the licensing situation and encourages the creation of more open source software +without impacting personal use of the JUCE framework. + + +# Version 7.0.12 + +## Change + +The function AudioChannelSet::create9point0point4, along with variants for +9.1.4, 9.0.6, and 9.1.6, used to correspond to VST3 layouts k90_4, k91_4, +k90_6, and k91_6 respectively. These functions now correspond to k90_4_W, +k91_4_W, k90_6_W, and k91_6_W respectively. + +**Possible Issues** + +VST3 plugins that used these AudioChannelSet layouts to specify initial bus +layouts, or to validate layouts in isBusesLayoutSupported, will now behave +differently. + +For example, if the host wants to check whether the k90_4 layout is supported, +previously isBusesLayoutSupported() would have received the layout created by +create9point0point4(), but will now receive the layout created by +create9point0point4ITU(). + +**Workaround** + +If you already have special-case handling for specific surround layouts, +e.g. to enable or disable them in isBusesLayoutSupported(), you may need to +add cases to handle the new AudioChannelSet::create*ITU() layout variants. + +**Rationale** + +Previously, the VST3 SDK only contained ITU higher-order surround layouts, but +the higher-order layouts specified in JUCE used Atmos speaker positions rather +than ITU speaker positions. This meant that JUCE had to remap speaker layouts +between Atmos/ITU formats when communicating with VST3 plugins. This was +confusing, as it required that the meaning of some channels was changed during +the conversion. + +In newer versions of the VST3 SDK, new "wide" left and right speaker +definitions are available, allowing both ITU and Atmos surround layouts to be +represented. The change in JUCE surfaces this distinction to the user, allowing +them to determine e.g. whether the host has requested an ITU or an Atmos +layout, and to handle these cases separately if necessary. + + +# Version 7.0.10 + +## Change + +The signatures of some member functions of ci::Device have been changed: +- sendPropertyGetInquiry +- sendPropertySetInquiry + +The signature of ci::PropertyHost::sendSubscriptionUpdate has also changed. + +The following member functions of ci::Device have been replaced with new +alternatives: +- sendPropertySubscriptionStart +- sendPropertySubscriptionEnd +- getOngoingSubscriptionsForMuid +- countOngoingPropertyTransactions + +The enum field PropertyExchangeResult::Error::invalidPayload has been removed. + +**Possible Issues** + +Code that uses any of these symbols will fail to compile until it is updated. + +**Workaround** + +Device::sendPropertyGetInquiry, Device::sendPropertySetInquiry, and +PropertyHost::sendSubscriptionUpdate all now return an optional RequestKey +instead of an ErasedScopeGuard. Requests started via any of these functions may +be cancelled by the request's RequestKey to the new function +Device::abortPropertyRequest. The returned RequestKey may be null, indicating a +failure to send the request. + +countOngoingPropertyTransactions has been replaced by getOngoingRequests, +which returns the RequestKeys of all ongoing requests. To find the number of +transactions, use the size of the returned container. + +sendPropertySubscriptionStart has been replaced by beginSubscription. +sendPropertySubscriptionEnd has been replaced by endSubscription. +The new functions no longer take callbacks. Instead, to receive notifications +when a subscription starts or ends, override +DeviceListener::propertySubscriptionChanged. + +getOngoingSubscriptionsForMuid is replaced by multiple functions. +getOngoingSubscriptions returns SubscriptionKeys for all of the subscriptions +currently in progress, which may be filtered based on SubscriptionKey::getMuid. +The subscribeId assigned to a particular SubscriptionKey can be found using +getSubscribeIdForKey, and the subscribed resource can be found using +getResourceForKey. + +It's possible that the initial call to beginSubscription may not be able to +start the subscription, e.g. if the remote device is busy and request a retry. +In this case, the request is cached. If you use subscriptions, then you +should call sendPendingMessages periodically to flush any messages that may +need to be retried. + +There is no need to check for the invalidPayload error when processing +property exchange results. + +**Rationale** + +Keeping track of subscriptions is quite involved, as the initial request to +begin a subscription might not be accepted straight away. The device may not +initially have enough vacant slots to send the request, or responder might +request a retry if it is too busy to process the request. The ci::Device now +caches requests when necessary, allowing them to be retried in the future. +This functionality couldn't be implemented without modifying the old interface. + +Replacing ErasedScopeGuards with Keys makes lifetime handling a bit easier. +It's no longer necessary to store or manually release scope guards for requests +that don't need to be cancelled. The new Key types are also a bit more +typesafe, and allow for simple queries of the transaction that created the key. + + +## Change + +The ListenerList::Iterator class has been removed. + +**Possible Issues** + +Any code directly referencing the ListenerList::Iterator will fail to compile. + +**Workaround** + +In most cases there should be a public member function that does the required +job, for example, call, add, remove, or clear. In other cases you can access the +raw array of listeners to iterate through them by calling getListeners(). + +**Rationale** + +Iterating through the listeners using the ListenerList::Iterator could in a +number of cases lead to surprising results and undefined behavior. + + +## Change + +The background colour of the Toolbar::CustomisationDialog has been changed from +white to a new, customisable value, that matches Toolbar::backgroundColourId by +default. + +**Possible Issues** + +User interfaces that use Toolbar::CustomisationDialog will render differently. + +**Workaround** + +You can customise the new colour using LookAndFeel::setColour() using +Toolbar::customisationDialogBackgroundColourId. + +**Rationale** + +Previously there was no way to customise the dialog's background colour and the +fixed white colour was inappropriate for most user interfaces. + + +## Change + +ProfileHost::enableProfile and ProfileHost::disableProfile have been combined +into a single function, ProfileHost::setProfileEnablement. + +**Possible Issues** + +Code that calls this function will fail to compile until it is updated. + +**Workaround** + +To enable a profile, call setProfileEnablement with a positive number of +channels. To disable a profile, call setProfileEnablement with zero channels. + +**Rationale** + +The new API is simpler, more compact, and more consistent, as it now mirrors +the signature of Device::sendProfileEnablement. + + +## Change + +OpenGLContext::getRenderingScale() has been changed to include the effects of +AffineTransforms on all platforms. + +**Possible Issues** + +Applications that use OpenGLContext::getRenderingScale() and also have scaling +transformations that affect the context component's size may render incorrectly. + +**Workaround** + +Adjust rendering code by dividing the reported scale with the user specified +transformation scale, if necessary. + +**Rationale** + +The previous implementation resulted in inconsistent behaviour between Windows +and the other platforms. The main intended use-case for getRenderingScale() is +to help determine the number of physical pixels covered by the context +component. Since plugin windows will often use AffineTransforms to set up the +correct rendering scale, it makes sense to include these in the result of +getRenderingScale(). + + +## Change + +Components that have setMouseClickGrabsKeyboardFocus() set to false will not +accept or propagate keyboard focus to parent components due to a mouse click +event. This is now true even if the mouse click event happens in a child +component with setMouseClickGrabsKeyboardFocus (true) and +setWantsKeyboardFocus (false). + +**Possible Issues** + +Components that rely on child components propagating keyboard focus from a +mouse click, when those child components have setMouseClickGrabsKeyboardFocus() +set to false, will no longer grab keyboard focus. + +**Workaround** + +Add a MouseListener to the component receiving the click and override the +mouseDown() method in the listener. In the mouseDown() method call +Component::grabKeyboardFocus() for the component that should be focused. + +**Rationale** + +The intent of setMouseClickGrabsKeyboardFocus (false) is to reject focus changes +coming from mouse clicks even if the component is otherwise capable of receiving +keyboard focus. + +The previous behaviour could result in surprising focus changes when a child +component was clicked. This manifested in the focus seemingly disappearing when +a PopupMenu item added to a component was clicked. + + +## Change + +The NodeID argument to AudioProcessorGraph::addNode() has been changed to take +a std::optional. + +**Possible Issues** + +The behavior of any code calling AudioProcessorGraph::addNode(), that explicitly +passes a default constructed NodeID or a NodeID constructed with a value of 0, +will change. Previously these values would have been treated as a null value +resulting in the actual NodeID being automatically determined. These will now +be treated as requests for an explicit value. + +**Workaround** + +Either remove the explicit NodeID argument and rely on the default argument or +pass a std::nullopt instead. + +**Rationale** + +The previous version prevented users from specifying a NodeID of 0 and resulted +in unexpected behavior. + + +## Change + +The signature of DynamicObject::writeAsJSON() has been changed to accept a +more extensible JSON::FormatOptions argument. + +**Possible Issues** + +Code that overrides or calls this function will fail to compile. + +**Workaround** + +Update the signatures of overriding functions. Use FormatOptions::getIndentLevel() +and FormatOptions::getMaxDecimalPlaces() as necessary. To find whether the output +should be multi-line, compare the result of FormatOptions::getSpacing() with +JSON::Spacing::multiLine. + +Callers of the function can construct the new argument type using the old +arguments accordingly + +``` +JSON::FormatOptions{}.withIndentLevel (indentLevel) + .withSpacing (allOnOneLine ? JSON::Spacing::singleLine + : JSON::Spacing::multiLine) + .withMaxDecimalPlaces (maximumDecimalPlaces); +``` + +**Rationale** + +The previous signature made it impossible to add new formatting options. Now, +if we need to add further options in the future, these can be added to the +FormatOptions type, which will not be a breaking change. + + +# Version 7.0.9 + +## Change + +CachedValue::operator==() will now emit floating point comparison warnings if +they are enabled for the project. + +**Possible Issues** + +Code using this function to compare floating point values may fail to compile +due to the warnings. + +**Workaround** + +Rather than using CachedValue::operator==() for floating point types, use the +exactlyEqual() or approximatelyEqual() functions in combination with +CachedValue::get(). + +**Rationale** + +The JUCE Framework now offers the free-standing exactlyEqual() and +approximatelyEqual() functions to clearly express the desired semantics when +comparing floating point values. These functions are intended to eliminate +the ambiguity in code-bases regarding these types. However, when such a value +is wrapped in a CachedValue the corresponding warning was suppressed until now, +making such efforts incomplete. + + +# Version 7.0.8 + +## Change + +DynamicObject::clone now returns unique_ptr instead of +ReferenceCountedObjectPtr. + +**Possible Issues** + +Overrides of this function using the old signature will fail to compile. +The result of this function may need to be manually converted to a +ReferenceCountedObjectPtr. + +**Workaround** + +Update overrides to use the new signature. +If necessary, manually construct a ReferenceCountedObjectPtr at call sites. + +**Rationale** + +It's easy to safely upgrade a unique_ptr to a shared/refcounted pointer. +However, it's not so easy to convert safely in the opposite direction. +Generally, returning unique_ptrs rather than refcounted pointers leads to more +flexible APIs. + + +# Version 7.0.7 + +## Change + +The minimum supported CMake version is now 3.22. + +**Possible Issues** + +It will no longer be possible to configure JUCE projects with CMake versions +between 3.15 and 3.21 inclusive. + +**Workaround** + +No workaround is available. Newer versions of CMake can be obtained from the +official download page, or through system package managers. + +**Rationale** + +Moving to CMake 3.22 improves consistency with the Projucer's Android exporter, +which already requires CMake 3.22. It also allows us to make use of the +XCODE_EMBED_APP_EXTENSIONS property (introduced in CMake 3.21), fixing an +issue when archiving AUv3 plugins. + + +# Version 7.0.6 + +## Change + +Thread::wait and WaitableEvent::wait now take a double rather than an int to +indicate the number of milliseconds to wait. + +**Possible Issues** + +Calls to either wait function may trigger warnings. + +**Workaround** + +Explicitly cast the value to double. + +**Rationale** + +Changing to double allows sub-millisecond waits which was important for +supporting changes to the HighResolutionTimer. + + +## Change + +RealtimeOptions member workDurationMs was replaced by three optional member +variables in RealtimeOptions, and all RealtimeOptions member variables were +marked private. + +**Possible Issues** + +Trying to construct a RealtimeOptions object with one or two values, or access +any of its member variables, will no longer compile. + +**Workaround** + +Use the withMember functions to construct the object, and the getter functions +to access the member variable values. + +**Rationale** + +The new approach improves the flexibility for users to specify realtime thread +options on macOS/iOS and improves the flexibility for the API to evolve without +introducing further breaking changes. + + +## Change + +JUCE module compilation files with a platform suffix are now checked case +insensitively for CMake builds. + +**Possible Issues** + +If a JUCE module compilation file ends in a specific platform suffix but does +not match the case for the string previously checked by the CMake +implementation, it may have compiled for all platforms. Now, it will only +compile for the platform specified by the suffix. + +**Workaround** + +In most cases this was probably a bug, in other cases rename the file to remove +the platform suffix. + +**Rationale** + +This change improves consistency between the Projucer and CMake integrations. + + +## Change + +An undocumented feature that allowed JUCE module compilation files to compile +for a specific platform or subset of platforms by declaring the platform name +followed by an underscore, was removed. + +**Possible Issues** + +If a JUCE module compilation file contains a matching platform suffix followed +by an underscore and is loaded by the Projucer it will no longer compile for +just that platform. + +**Workaround** + +Use the suffix of the name only. If the undocumented feature was used to select +multiple platforms, make multiple separate files for each of the required +platforms. + +**Rationale** + +This change improves consistency between the Projucer and CMake integrations. +Given the functionality was undocumented, the ease of a workaround, and the +added complexity required for CMake support, the functionality was removed. + + +## Change + +Unique device IDs on iOS now use the OS provided 'identifierForVendor'. +OnlineUnlockStatus has been updated to handle the iOS edge-case where a device +ID query might return an empty String. + +**Possible Issues** + +The License checks using InAppPurchases, getLocalMachineIDs(), and +getUniqueDeviceID() may return an empty String if iOS 'is not ready'. This can +occur for example if the device has restarted but has not yet been unlocked. + +**Workaround** + +InAppPurchase has been updated to handle this and propagate the error +accordingly. The relevant methods have been updated to return a Result object +that can be queried for additional information on failure. + +**Rationale** + +Apple have introduced restrictions on device identification rendering our +previous methods unsuitable. + + +## Change + +AudioProcessor::getAAXPluginIDForMainBusConfig() has been deprecated. + +**Possible Issues** + +Any AudioProcessor overriding this method will fail to compile. + +**Workaround** + +- Create an object which inherits from AAXClientExtensions. +- In the object override and implement getPluginIDForMainBusConfig(). +- In the AudioProcessor override getAAXClientExtensions() and return a pointer + to the object. + +**Rationale** + +Additional AAX specific functionality was required in the audio processor. +Rather than continuing to grow and expand the AudioProcessor class with format +specific functionality, separating this concern into a new class allows for +greater expansion for those that need it without burdening those that don't. +Moving this function into this class improves consistency both with the new +functionality and with similar functionality for the VST2 and VST3 formats. + + +## Change + +Unique device IDs on Windows have been updated to use a more reliable SMBIOS +parser. The SystemStats::getUniqueDeviceID function now returns new IDs using +this improved parser. Additionally, a new function, +SystemStats::getMachineIdentifiers, has been introduced to aggregate all ID +sources. It is recommended to use this new function to verify any IDs. + +**Possible Issues** + +The SystemStats::getUniqueDeviceID function will return a different ID for the +same machine due to the updated parser. + +**Workaround** + +For code that previously relied on SystemStats::getUniqueDeviceID, it is advised +to switch to using SystemStats::getMachineIdentifiers() instead. + +**Rationale** + +This update ensures the generation of more stable and reliable unique device +IDs, while also maintaining backward compatibility with the previous ID +generation methods. + + +## Change + +The Grid layout algorithm has been slightly altered to provide more consistent +behaviour. The new approach guarantees that dimensions specified using the +absolute Px quantity will always be correctly rounded when applied to the +integer dimensions of Components. + +**Possible Issues** + +Components laid out using Grid can observe a size or position change of +/- 1px +along each dimension compared with the result of the previous algorithm. + +**Workaround** + +If the Grid based graphical layout is sensitive to changes of +/- 1px, then the +UI layout code may have to be adjusted to the new algorithm. + +**Rationale** + +The old Grid layout algorithm could exhibit surprising and difficult to control +single pixel artifacts, where an item with a specified absolute size of +e.g. 100px could end up with a layout size of 101px. The new approach +guarantees that such items will have a layout size exactly as specified, and +this new behaviour is also in line with CSS behaviour in browsers. The new +approach makes necessary corrections easier as adding 1px to the size of an +item with absolute dimensions is guaranteed to translate into an observable 1px +increase in the layout size. + + +## Change + +The k91_4 and k90_4 VST3 layouts are now mapped to the canonical JUCE 9.1.4 and +9.0.4 AudioChannelSets. This has a different ChannelType layout than the +AudioChannelSet previously used with such VST3 SpeakerArrangements. + +**Possible Issues** + +VST3 plugins that were prepared to work with the k91_4 and k90_4 +SpeakerArrangements may now have incorrect channel mapping. The channels +previously accessible through ChannelType::left and right are now accessible +through ChannelType::wideLeft and wideRight, and channels previously accessible +through ChannelType::leftCentre and rightCentre are now accessible through +ChannelType::left and right. + +**Workaround** + +Code that accesses the channels that correspond to the VST3 Speakers kSpeakerL, +kSpeakerR, kSpeakerLc and kSpeakerRc needs to be updated. These channels are now +accessible respectively through ChannelTypes wideLeft, wideRight, left and +right. Previously they were accessible respectively through left, right, +leftCentre and rightCentre. + +**Rationale** + +This change allows developers to handle the 9.1.4 and 9.0.4 surround layouts +with one codepath across all plugin formats. Previously the +AudioChannelSet::create9point1point4() and create9point0point4() layouts would +only be used in CoreAudio and AAX, but a different AudioChannelSet would be used +in VST3 even though they were functionally equivalent. + + +## Change + +The signatures of the ContentSharer member functions have been updated. The +ContentSharer class itself is no longer a singleton. + +**Possible Issues** + +Projects that use the old signatures will not build until they are updated. + +**Workaround** + +Instead of calling content sharer functions through a singleton instance, e.g. + ContentSharer::getInstance()->shareText (...); +call the static member functions directly: + ScopedMessageBox messageBox = ContentSharer::shareTextScoped (...); +The new functions return a ScopedMessageBox instance. On iOS, the content +sharer will only remain open for as long as the ScopedMessageBox remains alive. +On Android, this functionality will be added as/when the native APIs allow. + +**Rationale** + +The new signatures are safer and easier to use. The ScopedMessageBox also +allows content sharers to be dismissed programmatically, which wasn't +previously possible. + + +## Change + +The minimum supported AAX library version has been bumped to 2.4.0 and the +library is now built automatically while building an AAX plugin. The +JucePlugin_AAXLibs_path preprocessor definition is no longer defined in AAX +plugin builds. + +**Possible Issues** + +Projects that use the JucePlugin_AAXLibs_path definition may no longer build +correctly. Projects that reference an AAX library version earlier than 2.4.0 +will fail to build. + +**Workaround** + +You must download an AAX library distribution with a version of at least 2.4.0. +Use the definition JucePlugin_Build_AAX to check whether the AAX format is +enabled at build time. + +**Rationale** + +The JUCE framework now requires features only present in version 2.4.0 of the +AAX library. The build change removes steps from the build process, and ensures +that the same compiler flags are used across the entire project. + + +## Change + +The implementation of ColourGradient::createLookupTable has been updated to use +non-premultiplied colours. + +**Possible Issues** + +Programs that draw transparent gradients using the OpenGL or software +renderers, or that use lookup tables generated from transparent gradients for +other purposes, may now produce different results. + +**Workaround** + +For gradients to render the same as they did previously, transparent colour +stops should be un-premultiplied. For colours with an alpha component of 0, it +may be necessary to specify appropriate RGB components. + +**Rationale** + +Previously, transparent gradients rendered using CoreGraphics looked different +to the same gradients drawn using OpenGL or the software renderer. This change +updates the OpenGL and software renderers, so that they produce the same +results as CoreGraphics. + + +## Change + +Projucer-generated MSVC projects now build VST3s as bundles, rather than as +single DLL files. + +**Possible Issues** + +Build workflows that expect the VST3 to be a single DLL may break. + +**Workaround** + +Any post-build scripts that expect to copy or move the built VST3 should be +updated so that the entire bundle directory is copied/moved. The DLL itself +can still be located and extracted from within the generated bundle if +necessary. + +**Rationale** + +Distributing VST3s as single files was deprecated in VST3 v3.6.10. JUCE's CMake +scripts already produce VST3s as bundles, so this change increases consistency +between the two build systems. + + +# Version 7.0.3 + +## Change -Change ------- The default macOS and iOS deployment targets set by the Projucer have been increased to macOS 10.13 and iOS 11 respectively. -Possible Issues ---------------- +**Possible Issues** + Projects using the Projucer's default minimum deployment target will have their minimum deployment target increased. -Workaround ----------- +**Workaround** + If you need a lower minimum deployment target then you must set this in the Projucer's Xcode build configuration settings. -Rationale ---------- +**Rationale** + Xcode 14 no longer supports deployment targets lower than macOS 10.13 and iOS 11. -Change ------- +## Change + The ARA SDK expected by JUCE has been updated to version 2.2.0. -Possible Issues ---------------- +**Possible Issues** + Builds using earlier versions of the ARA SDK will fail to compile. -Workaround ----------- +**Workaround** + The ARA SDK configured in JUCE must be updated to version 2.2.0. -Rationale ---------- -Version 2.2.0 is the latest official release of the ARA SDK. +**Rationale** + +# Version 2.2.0 is the latest official release of the ARA SDK. -Change ------- +## Change + The Thread::startThread (int) and Thread::setPriority (int) methods have been removed. A new Thread priority API has been introduced. -Possible Issues ---------------- +**Possible Issues** + Code will fail to compile. -Workaround ----------- +**Workaround** + Rather than using an integer thread priority you must instead use a value from the Thread::Priority enum. Thread::setPriority and Thread::getPriority should only be called from the target thread. To start a Thread with a realtime performance profile you must call startRealtimeThread. -Rationale ---------- +**Rationale** + Operating systems are moving away from a specific thread priority and towards more granular control over which types of cores can be used and things like power throttling options. In particular, it is no longer possible to map a 0-10 @@ -71,22 +1564,22 @@ interfaces, and that changing a priority using the new interface can only be done on the currently running thread. -Change ------- +## Change + The constructor of WebBrowserComponent now requires passing in an instance of a new Options class instead of a single option boolean. The WindowsWebView2WebBrowserComponent class was removed. -Possible Issues ---------------- +**Possible Issues** + Code using the WebBrowserComponent's boolean parameter to indicate if a webpage should be unloaded when the component is hidden, will now fail to compile. Additionally, any code using the WindowsWebView2WebBrowserComponent class will fail to compile. Code relying on the default value of the WebBrowserComponent's constructor are not affected. -Workaround ----------- +**Workaround** + Instead of passing in a single boolean to the WebBrowserComponent's constructor you should now set this option via tha WebBrowserComponent::Options::withKeepPageLoadedWhenBrowserIsHidden method. @@ -97,8 +1590,8 @@ this by setting the WebBrowserComponent::Options::withBackend method. The WebView2Preferences can now be modified with the methods in WebBrowserComponent::Options::WinWebView2. -Rationale ---------- +**Rationale** + The old API made adding further options to the WebBrowserComponent cumbersome especially as the WindowsWebView2WebBrowserComponent already had a parameter very similar to the above Options class, whereas the base class did not use @@ -108,48 +1601,48 @@ special class, especially if additional browser backends are added in the future. -Change ------- +## Change + The function AudioIODeviceCallback::audioDeviceIOCallback() was removed. -Possible Issues ---------------- +**Possible Issues** + Code overriding audioDeviceIOCallback() will fail to compile. -Workaround ----------- +**Workaround** + Affected classes should override the audioDeviceIOCallbackWithContext() function instead. -Rationale ---------- +**Rationale** + The audioDeviceIOCallbackWithContext() function fulfills the same role as audioDeviceIOCallback(), it just has an extra parameter. Hence the audioDeviceIOCallback() function was superfluous. -Change ------- +## Change + The type representing multi-channel audio data has been changed from T** to T* const*. Affected classes are AudioIODeviceCallback, AudioBuffer and AudioFormatReader. -Possible Issues ---------------- +**Possible Issues** + Code overriding the affected AudioIODeviceCallback and AudioFormatReader functions will fail to compile. Code that interacts with the return value of AudioBuffer::getArrayOfReadPointers() and AudioBuffer::getArrayOfWritePointers() may fail to compile. -Workaround ----------- +**Workaround** + Functions overriding the affected AudioIODeviceCallback and AudioFormatReader members will need to be changed to confirm to the new signature. Type declarations related to getArrayOfReadPointers() and getArrayOfWritePointers() of AudioBuffer may have to be adjusted. -Rationale ---------- +**Rationale** + While the previous signature permitted it, changing the channel pointers by the previously used types was already being considered illegal. The earlier type however prevented passing T** values to parameters with type const T**. In some @@ -157,39 +1650,39 @@ places this necessitated the usage of const_cast. The new signature can bind to T** values and the awkward casting can be avoided. -Change ------- +## Change + The minimum supported C++ standard is now C++17 and the oldest supported compilers on Linux are now GCC 7.0 and Clang 6.0. -Possible Issues ---------------- +**Possible Issues** + Older compilers will no longer be able to compile JUCE. -Workaround ----------- +**Workaround** + No workaround is available. -Rationale ---------- +**Rationale** + This compiler upgrade will allow the use of C++17 within the framework. -Change ------- +## Change + Resource forks are no longer generated for Audio Unit plug-ins. -Possible Issues ---------------- +**Possible Issues** + New builds of JUCE Audio Units may no longer load in old hosts that use the Component Manager to discover plug-ins. -Workaround ----------- +**Workaround** + No workaround is available. -Rationale ---------- +**Rationale** + The Component Manager is deprecated in macOS 10.8 and later, so the majority of hosts have now implemented support for the new plist-based discovery mechanism. The new AudioUnitSDK (https://github.com/apple/AudioUnitSDK) provided by Apple @@ -197,27 +1690,27 @@ to replace the old Core Audio Utility Classes no longer includes the files required to generate resource forks. -Change ------- +## Change + Previously, the AudioProcessorGraph would call processBlockBypassed on any processor for which setBypassed had previously been called. Now, the AudioProcessorGraph will now only call processBlockBypassed if those processors do not have dedicated bypass parameters. -Possible Issues ---------------- +**Possible Issues** + Processors with non-functional bypass parameters may not bypass in the same way as before. -Workaround ----------- +**Workaround** + For each AudioProcessor owned by a Graph, ensure that either: the processor has a working bypass parameter that correctly affects the output of processBlock(); or, the processor has no bypass parameter, in which case processBlockBypassed() will be called as before. -Rationale ---------- +**Rationale** + The documentation for AudioProcessor::getBypassParameter() states that if this function returns non-null, then processBlockBypassed() should never be called, but the AudioProcessorGraph was breaking this rule. Calling @@ -227,30 +1720,29 @@ The new behaviour obeys the contract set out in the AudioProcessor documentation. -Version 7.0.2 -============= +# Version 7.0.2 + +## Change -Change ------- The Matrix3D (Vector3D vector) constructor has been replaced with an explicit static Matrix3D fromTranslation (Vector3D vector) function, and a bug in the behaviour of the multipication operator that reversed the order of operations has been addressed. -Possible Issues ---------------- +**Possible Issues** + Code using the old constructor will not compile. Code that relied upon the order of multiplication operations will return different results. -Workaround ----------- +**Workaround** + Code that was using the old constructor must use the new static function. Code that relied on the order of multiplication operations will need to have the order of the arguments reversed. With the old code A * B was returning BA rather than AB. -Rationale ---------- +**Rationale** + Previously a matrix multipled by a vector would return a matrix, rather than a vector, as the multiplied-by vector would be automatically converted into a matrix during the operation. Removing the converting constructor makes @@ -259,50 +1751,49 @@ The current multiplication routine also included a bug where A * B resulted in BA rather than AB, which needed to be addressed. -Version 7.0.0 -============= +# Version 7.0.0 + +## Change -Change ------- AudioProcessor::getHostTimeNs() and AudioProcessor::setHostTimeNanos() have been removed. -Possible Issues ---------------- +**Possible Issues** + Code that used these functions will no longer compile. -Workaround ----------- +**Workaround** + Set and get the system time corresponding to the current audio callback using the new functions AudioPlayHead::PositionInfo::getHostTimeNs() and AudioPlayHead::PositionInfo::setHostTimeNs(). -Rationale ---------- +**Rationale** + This change consolidates callback-related timing information into the PositionInfo type, improving the consistency of the AudioProcessor and AudioPlayHead APIs. -Change ------- +## Change + AudioPlayHead::getCurrentPosition() has been deprecated and replaced with AudioPlayHead::getPosition(). -Possible Issues ---------------- +**Possible Issues** + Hosts that implemented custom playhead types may no longer compile. Plugins that used host-provided timing information may trigger deprecation warnings when building. -Workaround ----------- +**Workaround** + Classes that derive from AudioPlayHead must now override getPosition() instead of getCurrentPosition(). Code that used to use the playhead's CurrentPositionInfo must switch to using the new PositionInfo type. -Rationale ---------- +**Rationale** + Not all hosts and plugin formats are capable of providing the full complement of timing information contained in the old CurrentPositionInfo class. Previously, in the case that some information could not be provided, fallback @@ -314,24 +1805,24 @@ The new PositionInfo type also includes a new "barCount" member, which is currently only used by the LV2 host and client. -Change ------- +## Change + The optional JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS preprocessor flag will now use a new Metal layer renderer when running on macOS 10.14 or later. The minimum requirements for building macOS and iOS software are now macOS 10.13.6 and Xcode 10.1. -Possible Issues ---------------- +**Possible Issues** + Previously enabling JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS had no negative effect on performance. Now it may slow rendering down. -Workaround ----------- +**Workaround** + Disable JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS. -Rationale ---------- +**Rationale** + JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS has been ineffective when running on macOS 10.13 or later. Enabling this flag, and hence using the new Metal layer renderer when running on macOS 10.14, restores the previous @@ -343,101 +1834,100 @@ JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS improves or degrades performance is specific to an application. -Change ------- +## Change + The optional JUCE_COREGRAPHICS_DRAW_ASYNC preprocessor flag has been removed and asynchronous Core Graphics rendering is now the default. The helper function setComponentAsyncLayerBackedViewDisabled has also been removed. -Possible Issues ---------------- +**Possible Issues** + Components that were previously using setComponentAsyncLayerBackedViewDisabled to conditionally opt out of asynchronous Core Graphics rendering will no longer be able to do so. -Workaround ----------- +**Workaround** + To opt out of asynchronous Core Graphics rendering the windowRequiresSynchronousCoreGraphicsRendering ComponentPeer style flag can be used when adding a component to the desktop. -Rationale ---------- +**Rationale** + Asynchronous Core Graphics rendering provides a substantial performance benefit. Asynchronous rendering is a property of a Peer, rather than a Component, so a Peer style flag to conditionally opt out of asynchronous rendering is more appropriate. -Change ------- +## Change + Constructors of AudioParameterBool, AudioParameterChoice, AudioParameterFloat, AudioParameterInt, and AudioProcessorParameterWithID have been deprecated and replaced with new constructors taking an 'Attributes' argument. -Possible Issues ---------------- +**Possible Issues** + The compiler may issue a deprecation warning upon encountering usages of the old constructors. -Workaround ----------- +**Workaround** + Update code to pass an 'Attributes' instance instead. Example usages of the new constructors are given in the constructor documentation, and in the plugin example projects. -Rationale ---------- +**Rationale** + Parameter types have many different properties. Setting a non-default property using the old constructors required explicitly setting other normally-defaulted properties, which was redundant. The new Attributes types allow non-default properties to be set in isolation. -Version 6.1.6 -============= +# Version 6.1.6 + +## Change -Change ------- Unhandled mouse wheel and magnify events will now be passed to the closest enclosing enabled ancestor component. -Possible Issues ---------------- +**Possible Issues** + Components that previously blocked mouse wheel events when in a disabled state may no longer block the events as expected. -Workaround ----------- +**Workaround** + If a component should explicitly prevent events from propagating when disabled, it should override mouseWheelMove() and mouseMagnify() to do nothing when the component is disabled. -Rationale ---------- +**Rationale** + Previously, unhandled wheel events would be passed to the parent component, but only if the parent was enabled. This meant that scrolling on a component nested inside a disabled component would have no effect by default. This behaviour was not intuitive. -Change ------- +## Change + The invalidPressure, invalidOrientation, invalidRotation, invalidTiltX and invalidTiltY members of MouseInputSource have been deprecated. -Possible Issues ---------------- +**Possible Issues** + Deprecation warnings will be seen when compiling code which uses these members and eventually builds will fail when they are later removed from the API. -Workaround ----------- +**Workaround** + Use the equivalent defaultPressure, defaultOrientation, defaultRotation, defaultTiltX and defaultTiltY members of MouseInputSource. -Rationale ---------- +**Rationale** + The deprecated members represent valid values and the isPressureValid() etc. functions return true when using them. This could be a source of confusion and may be inviting programming errors. The new names are in line with the ongoing @@ -445,18 +1935,18 @@ practice of using these values to provide a neutral default in the absence of actual OS provided values. -Change ------- +## Change + Plugin wrappers will no longer call processBlockBypassed() if the wrapped AudioProcessor returns a parameter from getBypassParameter(). -Possible Issues ---------------- +**Possible Issues** + Plugins that used to depend on processBlockBypassed() being called may no longer correctly enter a bypassed state. -Workaround ----------- +**Workaround** + AudioProcessors that implement getBypassParameter() must check the current value of the bypass parameter on each call to processBlock(), and bypass processing as appropriate. When switching between bypassed and non-bypassed @@ -465,8 +1955,8 @@ discontinuities in the output. If the plugin introduces latency when not bypassed, the plugin must delay its output when in bypassed mode so that the overall latency does not change when enabling/disabling bypass. -Rationale ---------- +**Rationale** + The documentation for AudioProcessor::getBypassParameter() says > if this method returns a non-null value, you should never call processBlockBypassed but use the returned parameter to control the bypass @@ -475,23 +1965,23 @@ Some plugin wrappers were not following this rule. After this change, the behaviour of all plugin wrappers is consistent with the documented behaviour. -Change ------- +## Change + The ComponentPeer::getFrameSize() function has been deprecated on Linux. -Possible Issues ---------------- +**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 ----------- +**Workaround** + Use the ComponentPeer::getFrameSizeIfPresent() function. The new function returns an OptionalBorderSize object. Use operator bool() to determine if the border size is valid, then access the value using operator*() only if it is. -Rationale ---------- +**Rationale** + The XWindow system cannot return a valid border size immediately after window creation. ComponentPeer::getFrameSize() returns a default constructed BorderSize instance in such cases that corresponds to a frame size of @@ -499,158 +1989,156 @@ zero. That however can be a valid value, and needs to be treated differently from the situation when the frame size is not yet available. -Change ------- +## Change + The return type of XWindowSystem::getBorderSize() was changed to ComponentPeer::OptionalBorderSize. -Possible Issues ---------------- +**Possible Issues** + User code that uses XWindowSystem::getBorderSize() will fail to build. -Workaround ----------- +**Workaround** + Use operator bool() to determine the validity of the new return value and access the contained value using operator*(). -Rationale ---------- +**Rationale** + The XWindow system cannot immediately report the correct border size after window creation. The underlying X11 calls will signal whether querying the border size was successful, but there was no way to forward this information through XWindowSystem::getBorderSize() until this change. -Version 6.1.5 -============= +# Version 6.1.5 + +## Change -Change ------- XWindowSystemUtilities::XSettings now has a private constructor. -Possible Issues ---------------- +**Possible Issues** + User code that uses XSettings::XSettings() will fail to build. -Workaround ----------- +**Workaround** + Use the XSettings::createXSettings() factory function. -Rationale ---------- +**Rationale** + The XSETTINGS facility is not available on all Linux distributions and the old constructor would fail on such systems, potentially crashing the application. The factory function will return nullptr in such situations instead. -Version 6.1.3 -============= +# Version 6.1.3 + +## Change -Change ------- The format specific structs of ExtensionsVisitor now return pointers to forward declared types instead of `void*`. For this purpose the `struct AEffect;` forward declaration was placed inside the global namespace. -Possible Issues ---------------- +**Possible Issues** + User code that includes the VST headers inside a namespace may fail to build, because the forward declared type can collide with the contents of `aeffect.h`. -Workaround ----------- +**Workaround** + The collision can be avoided by placing a `struct AEffect;` forward declaration in the same namespace where the VST headers are included. The forward declaration must come before the inclusion. -Rationale ---------- +**Rationale** + Using the forward declared types eliminates the need for error prone casting at the site where the ExtensionsVisitor facility is used. -Change ------- +## Change + ListBox::createSnapshotOfRows now returns ScaledImage instead of Image. -Possible Issues ---------------- +**Possible Issues** + User code that overrides this function will fail to build. -Workaround ----------- +**Workaround** + To emulate the old behaviour, simply wrap the Image that was previous returned into a ScaledImage and return that instead. -Rationale ---------- +**Rationale** + Returning a ScaledImage allows the overriding function to specify the scale at which the image should be drawn. Returning an oversampled image will provide smoother-looking results on high resolution displays. -Change ------- +## Change + AudioFrameRate::frameRate is now a class type instead of an enum. -Possible Issues ---------------- +**Possible Issues** + Code that read the old enum value will not compile. -Workaround ----------- +**Workaround** + Call frameRate.getType() to fetch the old enum type. Alternatively, use the new getBaseRate(), isDrop(), isPullDown(), and getEffectiveRate() functions. The new functions provide a more accurate description of the host's frame rate. -Rationale ---------- +**Rationale** + The old enum-based interface was not flexible enough to describe all the frame rates that might be reported by a plugin host. -Change ------- +## Change + FlexItem::alignSelf now defaults to "autoAlign" rather than "stretch". -Possible Issues ---------------- +**Possible Issues** + FlexBox layouts will be different in cases where FlexBox::alignItems is set to a value other than "stretch". This is because each FlexItem will now default to using the FlexBox's alignItems value. Layouts that explicitly set FlexItem::alignSelf on each item will not be affected. -Workaround ----------- +**Workaround** + To restore the previous layout behaviour, set FlexItem::alignSelf to "stretch" on all FlexItems that would otherwise use the default value for alignSelf. -Rationale ---------- +**Rationale** + The new behaviour more closely matches the behaviour of CSS FlexBox implementations. In CSS, "align-self" has an initial value of "auto", which computes to the parent's "align-items" value. -Change ------- +## Change + Functions on AudioPluginInstance that can add parameters have been made private. -Possible Issues ---------------- +**Possible Issues** + Code implementing custom plugin formats may stop building if it calls these functions. -Workaround ----------- +**Workaround** + When implementing custom plugin formats, ensure that the plugin parameters derive from AudioPluginInstance::HostedParameter and then use addHostedParameter, addHostedParameterGroup or setHostedParameterTree to add the parameters to the plugin instance. -Rationale ---------- +**Rationale** + In a plugin host, it is very important to be able to uniquely identify parameters across different versions of the same plugin. To make this possible, we needed to introduce a way of retrieving a unique ID for each parameter, @@ -659,24 +2147,23 @@ to enforce that all AudioPluginInstances can only have parameters which are of the type HostedParameter, which required hiding the old functions. -Version 6.1.0 -============= +# Version 6.1.0 + +## Change -Change ------- juce::gl::loadFunctions() no longer loads extension functions. -Possible Issues ---------------- +**Possible Issues** + Code that depended on extension functions being loaded automatically may cease to function correctly. -Workaround ----------- +**Workaround** + Extension functions can now be loaded using juce::gl::loadExtensions(). -Rationale ---------- +**Rationale** + There are a great number of extension functions, and on some systems these can be slow to load (i.e. a second or so). Projects that do not require these extension functions should not have to pay for this unnecessary overhead. Now, @@ -684,24 +2171,24 @@ only core functions will be loaded by default, and extensions can be loaded explicitly in projects that require such functionality. -Change ------- +## Change + Thread::setPriority() will no longer set a realtime scheduling policy for all threads with non-zero priorities on POSIX systems. -Possible Issues ---------------- +**Possible Issues** + Threads that implicitly relied on using a realtime policy will no longer request a realtime policy if their priority is 7 or lower. -Workaround ----------- +**Workaround** + For threads that require a realtime policy on POSIX systems, request a priority of 8 or higher by calling Thread::setPriority() or Thread::setCurrentThreadPriority(). -Rationale ---------- +**Rationale** + By default, new Thread instances have a priority of 5. Previously, non-zero priorities corresponded to realtime scheduling policies, meaning that new Threads would use the realtime scheduling policy unless they explicitly @@ -711,41 +2198,41 @@ degrade performance, as multiple realtime threads will end up fighting for limited resources. -Change ------- +## Change + The JUCE_GLSL_VERSION preprocessor definition has been removed. -Possible Issues ---------------- +**Possible Issues** + Code which used this definition will no longer compile. -Workaround ----------- +**Workaround** + Use OpenGLHelpers::getGLSLVersionString to retrieve a version string which is consistent with the capabilities of the current OpenGL context. -Rationale ---------- +**Rationale** + A compile-time version string is not very useful, as OpenGL versions and capabilities can change at runtime. Replacing this macro with a function allows querying the capabilities of the current context at runtime. -Change ------- -The minimum support CMake version is now 3.15. +## Change + +The minimum supported CMake version is now 3.15. + +**Possible Issues** -Possible Issues ---------------- It will no longer be possible to configure JUCE projects with CMake versions between 3.12 and 3.14 inclusive. -Workaround ----------- +**Workaround** + No workaround is available. -Rationale ---------- +**Rationale** + Moving to 3.15 allows us to use target_link_directories and target_link_options, which were introduced in 3.13, which in turn allows us to provide support for bundled precompiled libraries in modules. Plugins already @@ -753,24 +2240,24 @@ required CMake 3.15, so this change just brings other target types in line with the requirements for plugins. -Change ------- +## Change + The default value of JUCE_MODAL_LOOPS_PERMITTED has been changed from 1 to 0. -Possible Issues ---------------- +**Possible Issues** + With JUCE_MODAL_LOOPS_PERMITTED set to 0 code that previously relied upon modal loops will need to be rewritten to use asynchronous versions of the modal functions. There is no non-modal alternative to AlterWindow::showNativeDialogBox and the previously modal behaviour of the MultiDocumentPanel destructor has changed. -Workaround ----------- +**Workaround** + Set JUCE_MODAL_LOOPS_PERMITTED back to 1. -Rationale ---------- +**Rationale** + Modal operations are a frequent source of problems, particularly when used in plug-ins. On Android modal loops are not possible, so people wanting to target Android often have an unwelcome surprise when then have to rewrite what they @@ -778,36 +2265,36 @@ assumed to be platform independent code. Changing the default addresses these problems. -Change ------- +## Change + The minimum supported C++ standard is now C++14 and the oldest supported compilers on macOS and Linux are now Xcode 9.2, GCC 5.0 and Clang 3.4. -Possible Issues ---------------- +**Possible Issues** + Older compilers will no longer be able to compile JUCE. People using Xcode 8.5 on OS X 10.11 will need to update the operating system to OS X 10.12 to be able to use Xcode 9.2. -Workaround ----------- +**Workaround** + No workaround is available. -Rationale ---------- +**Rationale** + This compiler upgrade will allow the use of C++14 within the framework. -Change ------- +## Change + Platform GL headers are no longer included in juce_opengl.h -Possible Issues ---------------- +**Possible Issues** + Projects depending on symbols declared in these headers may fail to build. -Workaround ----------- +**Workaround** + The old platform-supplied headers have been replaced with a new juce_gl.h header which is generated using the XML registry files supplied by Khronos. This custom header declares GL symbols in the juce::gl namespace. If your code @@ -816,8 +2303,8 @@ only needs to be JUCE-compatible, you can explicitly qualify each name with libraries (GLEW, GL3W etc.) you can make all GL symbols visible without additional qualification with `using namespace juce::gl`. -Rationale ---------- +**Rationale** + Using our own GL headers allows us to generate platform-independent headers which include symbols for all specified OpenGL versions and extensions. Note that although the function signatures exist, they may not resolve to a function @@ -831,88 +2318,88 @@ generally written in C, and export a significant portion of their symbols as preprocessor definitions. -Change ------- +## Change + The functions `getComponentAsyncLayerBackedViewDisabled` and `setComponentAsyncLayerBackedViewDisabled` were moved into the juce namespace. -Possible Issues ---------------- +**Possible Issues** + Code that declares these functions may fail to link. -Workaround ----------- +**Workaround** + Move declarations of these functions into the juce namespace. -Rationale ---------- +**Rationale** + Although the names of these functions are unlikely to collide with functions from other libraries, we can make such collisions much more unlikely by keeping JUCE code in the juce namespace. -Change ------- +## Change + The `juce_blocks_basics` module was removed. -Possible Issues ---------------- +**Possible Issues** + Projects depending on `juce_blocks_basics` will not build. -Workaround ----------- +**Workaround** + The BLOCKS API is now located in a separate repository: https://github.com/WeAreROLI/roli_blocks_basics Projects which used to depend on `juce_blocks_basics` can use `roli_blocks_basics` instead. -Rationale ---------- +**Rationale** + ROLI is no longer involved with the development of JUCE. Therefore, development on the BLOCKS API has been moved out of the JUCE repository, and to a new repository managed by ROLI. -Change ------- +## Change + The live build functionality of the Projucer has been removed. -Possible Issues ---------------- +**Possible Issues** + You will no longer be able to use live build in the Projucer. -Workaround ----------- +**Workaround** + None. -Rationale ---------- +**Rationale** + Keeping the live build compatible with the latest compilers on all our supported platforms is a very substantial maintenance burden, but very few people are using this feature of the Projucer. Removing the live build will simplify the code and our release process. -Change ------- +## Change + `Component::createFocusTraverser()` has been renamed to `Component::createKeyboardFocusTraverser()` and now returns a `std::unique_ptr` instead of a raw pointer. `Component::createFocusTraverser()` is a new method for controlling basic focus traversal and not keyboard focus traversal. -Possible Issues ---------------- +**Possible Issues** + Derived Components that override the old method will no longer compile. -Workaround ----------- +**Workaround** + Override the new method. Be careful to override `createKeyboardFocusTraverser()` and not `createFocusTraverser()` to ensure that the behaviour is the same. -Rationale ---------- +**Rationale** + The ownership of this method is now clearer as the previous code relied on the caller deleting the object. The name has changed to accommodate the new `Component::createFocusTraverser()` method that returns an object for @@ -920,22 +2407,22 @@ determining basic focus traversal, of which keyboard focus is generally a subset. -Change ------- +## Change + PluginDescription::uid has been deprecated and replaced with a new 'uniqueId' data member. -Possible Issues ---------------- +**Possible Issues** + Code using the old data member will need to be updated in order to compile. -Workaround ----------- +**Workaround** + Code that used to use 'uid' to identify plugins should switch to using 'uniqueId', with some caveats - see "Rationale" for details. -Rationale ---------- +**Rationale** + The 'uniqueId' member has the benefit of being consistent for a given VST3 across Windows, macOS, and Linux. However, the value of the uniqueId may differ from the value of the old uid on some platforms. The value @@ -945,39 +2432,38 @@ the new uniqueId, and falling back to the deprecatedUid. This should allow hosts to gracefully upgrade from the old uid values to the new values. -Version 6.0.8 -============= +# Version 6.0.8 + +## Change -Change ------- Calling AudioProcessorEditor::setResizeLimits() will no longer implicitly add a ResizableCornerComponent to the editor if it has not already been set as resizable. -Possible Issues ---------------- +**Possible Issues** + Code which previously relied on calling this method to set up the corner resizer will no longer work. -Workaround ----------- +**Workaround** + Explicitly call AudioProcessorEditor::setResizable() with the second argument set to true to enable the corner resizer. -Rationale ---------- +**Rationale** + The previous behaviour was undocumented and potentially confusing. There is now a single method to control the behaviour of the editor's corner resizer to avoid any ambiguity. -Change ------- +## Change + The implementations of `getValue` and `setValue` in `AUInstanceParameter` now properly take the ranges of discrete parameters into account. -Possible Issues ---------------- +**Possible Issues** + This issue affects JUCE Audio Unit hosts. Automation data previously saved for a discrete parameter with a non-zero minimum value may not set the parameter to the same values as previous JUCE versions. Note that previously, `getValue` on @@ -986,12 +2472,12 @@ a hosted discrete parameter may have returned out-of-range values, and result, automation recorded for affected parameters was likely already behaving unexpectedly. -Workaround ----------- +**Workaround** + There is no workaround. -Rationale ---------- +**Rationale** + The old behaviour was incorrect, and was causing issues in plugin validators and other hosts. Hosts expect `getValue` to return a normalised parameter value. If this function returns an out-of-range value (including Inf and NaN) @@ -999,23 +2485,23 @@ this is likely to break assumptions made by the host, leading to crashes, corrupted project data, or other defects. -Change ------- +## Change + AudioProcessorListener::audioProcessorChanged gained a new parameter describing the nature of any change. -Possible Issues ---------------- +**Possible Issues** + Code using the old function signature will not build until updated to use the new signature. -Workaround ----------- +**Workaround** + Listeners should add the new parameter to any overrides of audioProcessorChanged. -Rationale ---------- +**Rationale** + The new function signature means that wrappers can be smarter about the requests that they make to hosts whenever some aspect of the processor changes. In particular, plugin wrappers can now distinguish between changes to latency, @@ -1023,114 +2509,112 @@ parameter attributes, and the current program. This means that hosts will no longer assume parameters have changed when `setLatencySamples` is called. -Change ------- +## Change + CharacterFunctions::readDoubleValue now returns values consistent with other C++ number parsing libraries. Parsing values smaller than the minimum number representable in a double will return (+/-)0.0 and parsing values larger than the maximum number representable in a double will return (+/-)inf. -Possible Issues ---------------- +**Possible Issues** + Code reading very large or very small numbers may receive values of 0.0 and inf rather than nan. -Workaround ----------- +**Workaround** + Where you may be using std::isnan to check the validity of the result you can instead use std::isfinite. -Rationale ---------- +**Rationale** + The new behaviour is consistent with other string parsing libraries. -Version 6.0.6 -============= +# Version 6.0.6 + +## Change -Change ------- The name of `OperatingSystemType::MacOSX_11_0` was changed to `OperatingSystemType::MacOS_11`. -Possible Issues ---------------- +**Possible Issues** + Code using the old name will not build until it is updated to use the new name. -Workaround ----------- +**Workaround** + Update code using the old name to use the new name instead. -Rationale ---------- +**Rationale** + Newer versions of macOS have dropped the "X" naming. Minor version updates are also less significant now than they were for the X-series. -Change ------- +## Change + Xcode projects generated using the Projucer will now use the "New Build System" instead of the "Legacy Build System" by default. -Possible Issues ---------------- +**Possible Issues** + Xcode 10.0 - 10.2 has some known issues when using the new build system such as JUCE modules not rebuilding correctly when modified, issue and file navigation not working, and breakpoints not being reliably set or hit. -Workaround ----------- +**Workaround** + If you are using an affected version of Xcode then you can enable the "Use Legacy Build System" setting in the Projucer Xcode exporter to go back to the previous behaviour. -Rationale ---------- +**Rationale** + The legacy build system has issues building arm64 binaries for Apple silicon and will eventually be removed altogether. -Version 6.0.5 -============= +# Version 6.0.5 + +## Change -Change ------- New pure virtual methods accepting `PopupMenu::Options` arguments have been added to `PopupMenu::LookAndFeelMethods`. -Possible Issues ---------------- +**Possible Issues** + Classes derived from `PopupMenu::LookAndFeelMethods`, such as custom LookAndFeel classes, will not compile unless these pure virtual methods are implemented. -Workaround ----------- +**Workaround** + The old LookAndFeel methods still exist, so if the new Options parameter is not useful in your application, your implementation of `PopupMenu::LookAndFeelMethods` can simply forward to the old methods. For example, your implementation of `drawPopupMenuBackgroundWithOptions` can internally call your existing `drawPopupMenuBackground` implementation. -Rationale ---------- +**Rationale** + Allowing the LookAndFeelMethods to access the popup menu's options allows for more flexible styling. For example, a theme may wish to query the menu's target component or parent for colours to use. -Change ------- +## Change + A typo in the JUCEUtils CMake script that caused the wrong manufacturer code to be set in the compile definitions for a plugin was fixed. -Possible Issues ---------------- +**Possible Issues** + The manufacturer code for plugins built under CMake with this version of JUCE will differ from the manufacturer code that was generated previously. -Workaround ----------- +**Workaround** + If you have released plugins that used the old, incorrect manufacturer code and wish to continue using this code for backwards compatibility, add the following to your `juce_add_plugin` call: @@ -1140,18 +2624,17 @@ to your `juce_add_plugin` call: In most cases, this should not be necessary, and we recommend using the fixed behaviour. -Rationale ---------- +**Rationale** + This change ensures that the manufacturer codes used by CMake projects match the codes that would be generated by the Projucer, improving compatibility when transitioning from the Projucer to CMake. -Version 6.0.2 -============= +# Version 6.0.2 + +## Change -Change ------- The JUCE_WASAPI_EXCLUSIVE flag has been removed from juce_audio_devices and all available WASAPI audio device modes (shared, shared low latency and exclusive) are available by default when JUCE_WASAPI is enabled. The @@ -1159,80 +2642,80 @@ AudioIODeviceType::createAudioIODeviceType_WASAPI() method which takes a single boolean argument has also been deprecated in favour of a new method which takes a WASAPIDeviceMode enum. -Possible Issues ---------------- +**Possible Issues** + Code that relied on the JUCE_WASAPI_EXCLUSIVE flag to disable WASAPI exclusive mode will no longer work. -Workaround ----------- +**Workaround** + Override the AudioDeviceManager::createAudioDeviceTypes() method to omit the WASAPI exclusive mode device if you do not want it to be available. -Rationale ---------- +**Rationale** + JUCE now supports shared low latency WASAPI audio devices via the AudioClient3 interface and instead of adding an additional compile time config flag to enable this functionality, which adds complexity to the build process when not using the Projucer, JUCE makes all WASAPI device modes available by default. -Change ------- +## Change + The fields representing Mac OS X 10.4 to 10.6 inclusive have been removed from the `OperatingSystemType` enum. -Possible Issues ---------------- +**Possible Issues** + Code that uses these fields will fail to build. -Workaround ----------- +**Workaround** + Remove references to these fields from user code. -Rationale ---------- +**Rationale** + JUCE is not supported on Mac OS X versions lower than 10.7, so it is a given that `getOperatingSystemType` will always return an OS version greater than or equal to 10.7. Code that changes behaviours depending on the OS version can assume that this version is at least 10.7. -Change ------- +## Change + The JUCE_DISABLE_COREGRAPHICS_FONT_SMOOTHING flag in juce_graphics is no longer used on iOS. -Possible Issues ---------------- +**Possible Issues** + Projects with this flag enabled may render differently on iOS. -Workaround ----------- +**Workaround** + There is no workaround. -Rationale ---------- +**Rationale** + When using a cached image to render Components with `setBufferedToImage (true)` the result now matches the default behaviour on iOS where fonts are not smoothed. -Change ------- +## Change + Space, return and escape key events on the native macOS menu bar are no longer passed to the currently focused JUCE Component. -Possible Issues ---------------- +**Possible Issues** + Code relying on receiving these keyboard events will no longer work. -Workaround ----------- +**Workaround** + There is no workaround. -Rationale ---------- +**Rationale** + It should be possible for users with a keyboard or assistive device to navigate the menu, invoking the currently highlighted menu item with the space or return key and dismissing the menu with the escape key. These key events should not be @@ -1241,11 +2724,10 @@ JUCE apps. Only passing these events to the native macOS menu means that JUCE apps behave as expected for users. -Version 6.0.0 -============= +# Version 6.0.0 + +## Change -Change ------- The Convolution class interface was changed: - `loadImpulseResponse` member functions now take `enum class` parameters instead of `bool`. @@ -1253,21 +2735,21 @@ The Convolution class interface was changed: `copyAndLoadImpulseResponseFromBuffer` were replaced by a new `loadImpulseResponse` overload. -Possible Issues ---------------- +**Possible Issues** + Code using the old interface will no longer compile, and will need to be updated. -Workaround ----------- +**Workaround** + Code that was previously loading impulse responses from binary data or from files can substitute old `bool` parameters with the newer `enum class` equivalents. Code that was previously passing buffers or blocks will need reworking so that the Convolution instance can take ownership of the buffer containing the impulse response. -Rationale ---------- +**Rationale** + The newer `enum class` parameters make user code much more readable, e.g. `loadImpulseResponse (file, Stereo::yes, Trim::yes, 0, Normalise::yes)` rather than `loadImpulseResponse (file, true, true, 0, true);`. By taking ownership of @@ -1278,188 +2760,186 @@ copies/allocations on the audio thread, and gives more flexibility to the implementation to run initialisation tasks on a background thread. -Change ------- +## Change + All references to ROLI Ltd. (ROLI) have been changed to Raw Material Software Limited. -Possible Issues ---------------- +**Possible Issues** + Existing projects, particularly Android, may need to be resaved by the Projucer and have the old build artefacts deleted before they will build. -Workaround ----------- +**Workaround** + In Android projects any explicit mention of paths with the from "com.roli.*" should be changed to the form "com.rmsl.*". -Rationale ---------- +**Rationale** + This change reflects the change in ownership from ROLI to RMSL. -Change ------- +## Change + The Windows DPI handling in the VST wrapper and hosting code has been refactored to be more stable. -Possible Issues ---------------- +**Possible Issues** + The new code uses a top-level AffineTransform to scale the JUCE editor window instead of native methods. Therefore any AudioProcessorEditors which have their own AffineTransform applied will no longer work correctly. -Workaround ----------- +**Workaround** + If you are using an AffineTransform to scale the entire plug-in window then consider putting the component you want to transform in a child of the editor and transform that instead. Alternatively, if you don't need a separate scale factor for each plug-in instance you can use Desktop::setGlobalScaleFactor(). -Rationale ---------- +**Rationale** + The old code had some bugs when using OpenGL and when moving between monitors with different scale factors. The new code should fix these and DPI-aware plug-ins will scale correctly. -Change ------- +## Change + Relative Xcode subproject paths specified in the Projucer are now relative to the build directory rather than the project directory. -Possible Issues ---------------- +**Possible Issues** + After being re-saved in the Projucer existing Xcode projects will fail to find any subprojects specified using a relative path. -Workaround ----------- +**Workaround** + Update the subproject path in the Projucer. -Rationale ---------- +**Rationale** + Most other Xcode specific paths are specified relative to the build directory. This change brings the Xcode subproject path in line with the rest of the configuration. -Version 5.4.6 -============= +# Version 5.4.6 + +## Change -Change ------- AudioProcessorValueTreeState::getRawParameterValue now returns a std::atomic* instead of a float*. -Possible Issues ---------------- +**Possible Issues** + Existing code which explicitly mentions the type of the returned value, or interacts with the dereferenced float in ways unsupported by the std::atomic wrapper, will fail to compile. Certain evaluation-reordering compiler optimisations may no longer be possible. -Workaround ----------- +**Workaround** + Update your code to deal with a std::atomic* instead of a float*. -Rationale ---------- +**Rationale** + Returning a std::atomic* allows the JUCE framework to have much stronger guarantees about thread safety. -Change ------- +## Change + Removed a workaround from the ASIOAudioIODevice::getOutputLatencyInSamples() and ASIOAudioIODevice::getInputLatencyInSamples() methods which was adding an arbitrary amount to the reported latencies to compensate for dodgy, old drivers. -Possible Issues ---------------- +**Possible Issues** + Code which relied on these altered values may now behave differently. -Workaround ----------- +**Workaround** + Update your code to deal with the new, correct values reported from the drivers directly. -Rationale ---------- +**Rationale** + JUCE will now return the latency values as reported by the drivers without adding anything to them. The workaround was for old drivers and the current drivers should report the correct values without the need for the workaround. -Change ------- +## Change + The default behaviour of the AU and AUv3 plug-in wrappers is now to call get/setStateInformation instead of get/setProgramStateInformation. -Possible Issues ---------------- +**Possible Issues** + AudioProcessor subclasses which have overridden the default implementations of get/setProgramStateInformation (which simply call through to get/setStateInformation) may be unable to load previously saved state; state previously saved via a call to getProgramStateInformation will be presented to setStateInformation. -Workaround ----------- +**Workaround** + Enable the JUCE_AU_WRAPPERS_SAVE_PROGRAM_STATES configuration option in the juce_audio_plugin_client module to preserve backwards compatibility if required. -Rationale ---------- +**Rationale** + When using overridden get/setProgramStateInformation methods the previous behaviour of the AU and AUv3 wrappers does not correctly save and restore state. -Version 5.4.5 -============= +# Version 5.4.5 + +## Change -Change ------- The alignment of text rendered on macOS using CoreGraphics may have shifted slightly, depending on the font you have used. The default macOS font has shifted downwards. -Possible Issues ---------------- +**Possible Issues** + Meticulously aligned text components of a GUI may now be misaligned. -Workaround ----------- +**Workaround** + Use a custom LookAndFeel to change the location where text is drawn, or use a different font that matches the previous alignment of your original font. -Rationale ---------- +**Rationale** + This was an unintentional change resulting from moving away from a deprecated macOS text API. The new alignment is consistent with other rendering engines (web browsers and text editors) and the software renderer. -Change ------- +## Change + The JUCEApplicationBase::backButtonPressed() method now returns a bool to indicate whether the back event was handled or not. -Possible Issues ---------------- +**Possible Issues** + Applications which override this method will fail to compile. -Workaround ----------- +**Workaround** + You will need to update your code to return a bool indicating whether the back event was handled or not. -Rationale ---------- +**Rationale** + The back button behaviour on Android was previously broken as it would not do anything. The new code will correctly call finish() on the Activity when the back button is pressed but this method now allows the user to override this to @@ -1467,25 +2947,25 @@ implement their own custom navigation behaviour by returning true to indicate that it has been handled. -Change ------- +## Change + The AudioBlock class has been refactored and some of the method names have changed. Additionally the `const` behaviour now mirrors that of `std::span`, with the `const`-ness of the contained data decoupled from the `const`-ness of the container. -Possible Issues ---------------- +**Possible Issues** + Code using the old method names or violating `const`-correctness will fail to compile. -Workaround ----------- +**Workaround** + You will need to update your code to use the new method names and select an appropriate `const`-ness for the AudioBlock and the data it references. -Rationale ---------- +**Rationale** + The names of some of the methods in the AudioBlock class were ambiguous, particularly when chaining methods involving references to other blocks. The interaction between the `const`-ness of the AudioBlock and the `const`-ness of @@ -1493,26 +2973,25 @@ the referenced data was also ambiguous and has now been standardised to the same behaviour as other non-owning data views like `std::span`. -Version 5.4.4 -============= +# Version 5.4.4 + +## Change -Change ------- The Visual Studio 2013 exporter has been removed from the Projucer and we will no longer maintain backwards compatibility with Visual Studio 2013 in JUCE. -Possible Issues ---------------- +**Possible Issues** + It is no longer possible to create Visual Studio 2013 projects from the Projucer or compile JUCE-based software using Visual Studio 2013. -Workaround ----------- +**Workaround** + If you are using Visual Studio 2013 to build your projects you will need to update to a more modern version of Visual Studio. -Rationale ---------- +**Rationale** + Of all the platforms JUCE supports Visual Studio 2013 was holding us back the most in terms of C++ features we would like to use more broadly across the codebase. It is still possible to target older versions of Windows with more @@ -1521,47 +3000,47 @@ a Visual Studio 2013 project, but this is now provided as a Visual Studio 2017 project. -Change ------- +## Change + JUCE is moving towards using C++11 pointer container types instead of passing raw pointers as arguments and return values. -Possible Issues ---------------- +**Possible Issues** + You will need to change your code to pass std::unique_ptr into and out of various functions across JUCE's API. -Workaround ----------- +**Workaround** + None -Rationale ---------- +**Rationale** + Indicating ownership through the transfer of smart pointer types has been part of mainstream C++ for a long time and this change enforces memory safety by default in most situations. -Change ------- +## Change + SystemTrayIconComponent::setIconImage now takes two arguments, rather than one. The new argument is a template image for use on macOS where all non-transparent regions will render in a monochrome colour determined dynamically by the operating system. -Possible Issues ---------------- +**Possible Issues** + You will now need to provide two images to display a SystemTrayIconComponent and the SystemTrayIconComponent will have a different appearance on macOS. -Workaround ----------- +**Workaround** + If you are not targeting macOS then you can provide an empty image, `{}`, for the second argument. If you are targeting macOS then you will likely need to design a new monochrome icon. -Rationale ---------- +**Rationale** + The introduction of "Dark Mode" in macOS 10.14 means that menu bar icons must support several different colours and highlight modes to retain the same appearance as the native Apple icons. Doing this correctly without delegating @@ -1569,30 +3048,30 @@ the behaviour to the operating system is extremely cumbersome, and the APIs we were previously using to interact with menu bar items have been deprecated. -Change ------- +## Change + The AudioBlock class now differentiates between const and non-const data. -Possible Issues ---------------- +**Possible Issues** + The return type of the getInputBlock() method of the ProcessContextReplacing and ProcessContextNonReplacing classes has changed from AudioBlock to AudioBlock. -Workaround ----------- +**Workaround** + For ProcessContextReplacing you should use getOutputBlock() instead of getInputBlock(). For ProcessContextNonReplacing attempting to modify the input block is very likely an error. -Rationale ---------- +**Rationale** + This change makes the intent of the code much clearer and means that we can remove some const_cast operations. -Change ------- +## Change + The formatting of floating point numbers written to XML and JSON files has changed. @@ -1600,168 +3079,165 @@ Note that there is no change in precision - the XML and JSON files containing the new format numbers will parse in exactly the same way, it is only the string representation that has changed. -Possible Issues ---------------- +**Possible Issues** + If you rely upon exactly reproducing XML or JSON files then the new files may be different. -Workaround ----------- +**Workaround** + Update any reference XML or JSON files to use the new format. -Rationale ---------- +**Rationale** + The new format retains full precision, provides a human friendly representation of values near 1, and uses scientific notation for small and large numbers. This prevents needless file size bloat from numbers like 0.00000000000000001. -Version 5.4.3 -============= +# Version 5.4.3 + +## Change -Change ------- The global user module path setting in the Projucer can now only contain a single path. -Possible Issues ---------------- +**Possible Issues** + Projects that previously relied on using multiple global user module paths separated by a semicolon will fail to find these modules after re-saving. -Workaround ----------- +**Workaround** + Replace the multiple paths with a single global user module path. -Rationale ---------- +**Rationale** + Using multiple global user module paths did not work when saving a project which exported to different OSes. Only allowing a single path will prevent this from silently causing issues. -Version 5.4.2 -============= +# Version 5.4.2 + +## Change -Change ------- The return type of Block::getBlockAreaWithinLayout() has been changed from Rectangle to a simpler BlockArea struct. -Possible Issues ---------------- +**Possible Issues** + Classes that derive from Block and implement this pure virtual method will no longer compile due to a change in the function signature. -Workaround ----------- +**Workaround** + Update the method to return a BlockArea struct and update code that calls getBlockAreaWithinLayout to handle a BlockArea instead of a Rectangle. -Rationale ---------- +**Rationale** + The juce_blocks_basics is ISC licensed and therefore cannot depend on the GPL/Commercial licensed juce_graphics module that contains Rectangle. -Change ------- +## Change + Renaming and deletion of open file handles on Windows is now possible using the FILE_SHARE_DELETE flag. -Possible Issues ---------------- +**Possible Issues** + Previous code that relied on open files not being able to be renamed or deleted on Windows may fail. -Workaround ----------- +**Workaround** + No workaround. -Rationale ---------- +**Rationale** + This unifies the behaviour across OSes as POSIX systems already allow this. -Change ------- +## Change + Multiple changes to low-level, non-public JNI and Android APIs. -Possible Issues ---------------- +**Possible Issues** + If you were using any non-public, low-level JNI macros, calling java code or receiving JNI callbacks, then your code will probably no longer work. See the forum for further details. -Workaround ----------- +**Workaround** + See the forum for further details. -Rationale ---------- +**Rationale** + See the forum for further details. -Change ------- +## Change + The minimum Android version for a JUCE app is now Android 4.1 -Possible Issues ---------------- +**Possible Issues** + Your app may not run on very old versions of Android (less than 0.5% of the devices). -Workaround ----------- +**Workaround** + There is no workaround. -Rationale ---------- +**Rationale** + Less than 0.5% of all devices in the world run versions of Android older than Android 4.1. In the interest of keeping JUCE code clean and lean, we must deprecate support for very old Android versions from time to time. -Version 5.4.0 -============= +# Version 5.4.0 + +## Change -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 ---------------- +**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 ----------- +**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 ---------- +**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 ------- +## Change + The VST2 SDK embedded within JUCE has been removed. -Possible Issues ---------------- +**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 of JUCE. -Workaround ----------- +**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 @@ -1773,25 +3249,25 @@ Workaround 3. When a new JUCE plug-in project is created the value of JUCE_VST3_CAN_REPLACE_VST2 will be set to zero. -Rationale ---------- +**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 ------- +## Change + The AudioProcessorValueTreeState::createAndAddParameter function has been deprecated. -Possible Issues ---------------- +**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 ----------- +**Workaround** + Previous calls to createAndAddParameter (paramID, paramName, ...); @@ -1806,157 +3282,155 @@ constructor where you can pass both RangedAudioParameters and AudioProcessorParameterGroups of RangedAudioParameters to the AudioProcessorValueTreeState and initialise the ValueTree simultaneously. -Rationale ---------- +**Rationale** + The new createAndAddParameter method is much more flexible and enables any parameter types derived from RangedAudioParameter to be managed by the AudioProcessorValueTreeState. -Change ------- +## Change + The Projucer's per-exporter Android SDK/NDK path options have been removed. -Possible Issues ---------------- +**Possible Issues** + Projects that previously used these fields may no longer build. -Workaround ----------- +**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 ---------- +**Rationale** + Having multiple places where the paths could be set was confusing and could cause unexpected mismatches. -Change ------- +## 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 ---------------- +**Possible Issues** + Code that previously relied on this method returning either explicitly "iPhone" or "iPad" may no longer work. -Workaround ----------- +**Workaround** + Modify this code to handle the new device code string e.g. by changing: SystemStats::getDeviceDescription() == "iPhone"; to SystemStats::getDeviceDescription().contains ("iPhone");. -Rationale ---------- +**Rationale** + The exact device model can now be deduced from this information instead of just the device family. -Change ------- +## Change + DragAndDropContainer::performExternalDragDropOfFiles() and ::performExternalDragDropOfText() are now asynchronous on Windows. -Possible Issues ---------------- +**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 ----------- +**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 ---------- +**Rationale** + The behaviour of these methods is now consistent across all platforms and the method no longer blocks the message thread on Windows. -Change ------- +## Change + AudioProcessor::getTailLengthSeconds can now return infinity for VST/VST3/AU/AUv3. -Possible Issues ---------------- +**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 ----------- +**Workaround** + Rewrite your code to not use the result of getTailLengthSeconds directly to allocate a buffer. -Rationale ---------- +**Rationale** + Before this change there was no way for a JUCE plug-in to report an infinite tail time. -Version 5.3.2 -============= +# Version 5.3.2 + +## Change -Change ------- The behaviour of an UndoManager used by an AudioProcessorValueTreeState has been improved. -Possible Issues ---------------- +**Possible Issues** + If your plug-in contains an UndoManager used by an AudioProcessorValueTreeState and relies upon the old behaviour of the UndoManager then it is possible that the new behaviour is no longer appropriate for your use case. -Workaround ----------- +**Workaround** + Use an external UndoManager to reproduce the old behaviour manually. -Rationale ---------- +**Rationale** + This change fixes a few bugs in the behaviour of an UndoManager used by an AudioProcessorValueTreeState. -Change ------- +## Change + JUCE no longer supports OS X deployment targets earlier than 10.7. -Possible Issues ---------------- +**Possible Issues** + If you were previously targeting OS X 10.5 or 10.6 you will no longer be able to build JUCE-based products compatible with those platforms. -Workaround ----------- +**Workaround** + None. With the appropriate JUCE licence you may be able to backport new JUCE features, but there will be no official support for this. -Rationale ---------- +**Rationale** + Increasing the minimum supported OS X version allows the JUCE codebase to make use of the more modern C++ features found in the 10.7 standard library, which in turn will increase thread and memory safety. -Version 5.3.0 -============= +# Version 5.3.0 + +## Change -Change ------- 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 ---------------- +**Possible Issues** + 1. Due to the large number of changes that have occurred in the JUCE Git repository, pulling this version may result in a messy folder structure with empty directories that have been removed. @@ -1964,8 +3438,8 @@ Possible Issues 3. The Audio Plugin Host project has moved from the examples directory to the extras directory. -Workaround ----------- +**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 @@ -1973,34 +3447,34 @@ Workaround 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 ---------- +**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. -Change ------- +## Change + When hosting plug-ins all AudioProcessor methods of managing parameters that take a parameter index as an argument have been deprecated. -Possible Issues ---------------- +**Possible Issues** + A single assertion will be fired in debug builds on the first use of a deprecated function. -Workaround ----------- +**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 ---------- +**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 @@ -2008,19 +3482,19 @@ used. The move away from the AudioProcessor methods both improves the interface to that class and makes ongoing development work much easier. -Change ------- +## Change + This 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 ---------------- +**Possible Issues** + Any code using InAppPurchases needs to be updated to retrieve a singleton pointer to InAppPurchases. -Workaround ----------- +**Workaround** + Instead of holding a InAppPurchase member yourself, you should get an instance via InAppPurchases::getInstance(), e.g. @@ -2033,19 +3507,19 @@ call: InAppPurchases::getInstance()->purchaseProduct (...); -Rationale ---------- +**Rationale** + This change was required to fix an issue on Android where on failed transaction a listener would not get called. -Change ------- +## Change + JUCE's MPE classes have been updated to reflect the official specification recently approved by the MIDI Manufacturers Association (MMA). -Possible Issues ---------------- +**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 @@ -2059,60 +3533,59 @@ 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 ----------- +**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 ---------- +**Rationale** + The MPE classes in JUCE are out of date and should be updated to reflect the new, official MPE standard. -Version 5.2.1 -============= +# Version 5.2.1 + +## Change -Change ------- 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 ---------------- +**Possible Issues** + Any code calling JUCEApplicationBase::quit() to place the app in background will close the app instead. -Workaround ----------- +**Workaround** + Use Process::hide(). -Rationale ---------- +**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. -Change ------- +## Change + On Windows, release builds will now link to the dynamic C++ runtime by default -Possible Issues ---------------- +**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 ----------- +**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 @@ -2130,8 +3603,8 @@ 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 ---------- +**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 @@ -2141,53 +3614,52 @@ vendors to use the dynamic runtime. To help with this, JUCE has decided to make dynamic runtime linkage the default in JUCE. -Change ------- +## Change + 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 ---------------- +**Possible Issues** + The changes won't cause any silent errors in user code, but will require some manual refactoring -Workaround ----------- +**Workaround** + Just find equivalent new methods to replace existing code. -Rationale ---------- +**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. -Version 5.2.0 -============= +# Version 5.2.0 + +## Change -Change ------- Viewport now enables "scroll on drag" mode by default on Android and iOS. -Possible Issues ---------------- +**Possible Issues** + Any code relying on "scroll on drag" mode being turned off by default, should disable it manually. -Workaround ----------- +**Workaround** + None. -Rationale ---------- +**Rationale** + It is expected on mobile devices to be able to scroll a list by just a drag, rather than using a dedicated scrollbar. The scrollbar is still available though if needed. -Change ------- +## Change + The previous setting of Android exporter "Custom manifest xml elements" creating child nodes of element has been replaced by "Custom manifest XML content" setting that allows to specify the content of the entire @@ -2198,15 +3670,15 @@ Any custom elements or custom attributes will override the ones set by Projucer. Projucer will also automatically add any missing and required elements and attributes. -Possible Issues ---------------- +**Possible Issues** + If a Projucer project used "Custom manifest xml elements" field, the value will no longer be compatible with the project generated in the latest Projucer version. The solution is very simple and quick though, as mentioned in the Workaround section. -Workaround ----------- +**Workaround** + For any elements previously used, simply embed them explicitly in elements, for example instead of: @@ -2222,8 +3694,8 @@ simply write: -Rationale ---------- +**Rationale** + To maintain the high level of flexibility of generated Android projects and to avoid creating fields in Projucer for every possible future parameter, it is simpler to allow to set up the required parameters manually. This way it is not @@ -2238,17 +3710,16 @@ satisfactory because you want a support for x-large screens only, simply set -Version 5.1.2 -============= +# Version 5.1.2 + +## Change -Change ------- The method used to classify AudioUnit, VST3 and AAX plug-in parameters as either continuous or discrete has changed, and AudioUnit and AudioUnit v3 parameters are marked as high precision by default. -Possible Issues ---------------- +**Possible Issues** + Plug-ins: DAW projects with automation data written by an AudioUnit, AudioUnit v3 VST3 or AAX plug-in built with JUCE version 5.1.1 or earlier may load incorrectly when opened by an AudioUnit, AudioUnit v3, VST3 or AAX plug-in @@ -2257,16 +3728,16 @@ built with JUCE version 5.1.2 and later. Hosts: The AudioPluginInstance::getParameterNumSteps method now returns correct values for AU and VST3 plug-ins. -Workaround ----------- +**Workaround** + Plug-ins: Enable JUCE_FORCE_LEGACY_PARAMETER_AUTOMATION_TYPE in the juce_audio_plugin_client module config page in the Projucer. Hosts: Use AudioPluginInstance::getDefaultNumParameterSteps as the number of steps for all parameters. -Rationale ---------- +**Rationale** + The old system for presenting plug-in parameters to a host as either continuous or discrete is inconsistent between plug-in types and lacks sufficient flexibility. This change harmonises the behaviour and allows individual @@ -2276,42 +3747,42 @@ offer a limited number of parameter values, which again produces different behaviour for different plug-in types. -Change ------- +## Change + A new FrameRateType fps23976 has been added to AudioPlayHead, -Possible Issues ---------------- +**Possible Issues** + Previously JUCE would report the FrameRateType fps24 for both 24 and 23.976 fps. If your code uses switch statements (or similar) to handle all possible frame rate types, then this change may cause it to fall through. -Workaround ----------- +**Workaround** + Add fps23976 to your switch statement and handle it appropriately. -Rationale ---------- +**Rationale** + JUCE should be able to handle all popular frame rate codes but was missing support for 23.976. -Change ------- +## Change + The String (bool) constructor and operator<< (String&, bool) have been explicitly deleted. -Possible Issues ---------------- +**Possible Issues** + Previous code which relied on an implicit bool to int type conversion to produce a String will not compile. -Workaround ----------- +**Workaround** + Cast your bool to an integer to generate a string representation of it. -Rationale ---------- +**Rationale** + Letting things implicitly convert to bool to produce a String opens the door to all kinds of nasty type conversion edge cases. Furthermore, before this change, MacOS would automatically convert bools to ints but this wouldn't occur on @@ -2319,89 +3790,88 @@ different platform. Now the behaviour is consistent across all operating systems supported by JUCE. -Change ------- +## Change + The writeAsJSON virtual method of the DynamicObject class requires an additional parameter, maximumDecimalPlaces, to specify the maximum precision of floating point numbers. -Possible Issues ---------------- +**Possible Issues** + Classes which inherit from DynamicObject and override this method will need to update their method signature. -Workaround ----------- +**Workaround** + Your custom DynamicObject class can choose to ignore the additional parameter if you don't wish to support this behaviour. -Rationale ---------- +**Rationale** + When serialising the results of calculations to JSON the rounding of floating point numbers can result in numbers with 17 significant figures where only a few are required. This change to DynamicObject is required to support truncating those numbers. -Version 5.1.0 -============= +# Version 5.1.0 + +## Change -Change ------- The JUCE_COMPILER_SUPPORTS_LAMBDAS preprocessor macro has been removed. -Possible Issues ---------------- +**Possible Issues** + If your project is using JUCE_COMPILER_SUPPORTS_LAMBDAS in your source code then it will likely evaluate to "false" and you could end up unnecessarily using code paths which avoid lambda functions. -Workaround ----------- +**Workaround** + Remove the usage of JUCE_COMPILER_SUPPORTS_LAMBDAS from your code. -Rationale ---------- +**Rationale** + Lambda functions are now available on all platforms that JUCE supports. -Change ------- +## Change + The option to set the C++ language standard is now located in the project settings instead of the build configuration settings. -Possible Issues ---------------- +**Possible Issues** + Projects that had a specific version of the C++ language standard set for exporter build configurations will instead use the default (C++11) when re-saving with the new Projucer. -Workaround ----------- +**Workaround** + Change the "C++ Language Standard" setting in the main project settings to the required version - the Projucer will add this value to the exported project as a compiler flag when saving exporters. -Rationale ---------- +**Rationale** + Having a different C++ language standard option for each build configuration was unnecessary and was not fully implemented for all exporters. Changing it to a per-project settings means that the preference will propagate to all exporters and only needs to be set in one place. -Change ------- +## Change + PopupMenus now scale according to the AffineTransform and scaling factor of their target components. -Possible Issues ---------------- +**Possible Issues** + Developers who have manually scaled their PopupMenus to fit the scaling factor of the parent UI will now have the scaling applied two times in a row. -Workaround ----------- +**Workaround** + 1. Do not apply your own manual scaling to make your popups match the UI scaling @@ -2412,54 +3882,54 @@ or return false. See https://github.com/juce-framework/JUCE/blob/c288c94c2914af20f36c03ca9c5401fcb555e4e9/modules/juce_gui_basics/menus/juce_PopupMenu.h#725 -Rationale ---------- +**Rationale** + Previously, PopupMenus would not scale if the GUI of the target component (or any of its parents) were scaled. The only way to scale PopupMenus was via the global scaling factor. This had several drawbacks as the global scaling factor would scale everything. This was especially problematic in plug-in editors. -Change ------- +## Change + Removed the setSecurityFlags() method from the Windows implementation of WebInputStream as it disabled HTTPS security features. -Possible Issues ---------------- +**Possible Issues** + Any code previously relying on connections to insecure webpages succeeding will no longer work. -Workaround ----------- +**Workaround** + Check network connectivity on Windows and re-write any code that relied on insecure connections. -Rationale ---------- +**Rationale** + The previous behaviour resulted in network connections on Windows having all the HTTPS security features disabled, exposing users to network attacks. HTTPS connections on Windows are now secure and will fail when connecting to an insecure web address. -Change ------- +## Change + Pointer arithmetic on a pointer will have the same result regardless if it is wrapped in JUCE's Atomic class or not. -Possible Issues ---------------- +**Possible Issues** + Any code using pointer arithmetic on Atomic will now have a different result leading to undefined behaviour or crashes. -Workaround ----------- +**Workaround** + Re-write your code in a way that it does not depend on your pointer being wrapped in JUCE's Atomic or not. See rationale. -Rationale ---------- +**Rationale** + Before this change, pointer arithmetic with JUCE's Atomic type would yield confusing results. For example, the following code would assert before this change: @@ -2475,28 +3945,27 @@ confusing and unintuitive. Furthermore, this aligns JUCE's Atomic type with std::atomic. -Version 4.3.1 -============= +# Version 4.3.1 + +## Change -Change ------- JUCE has changed the way native VST3/AudioUnit parameter ids are calculated. -Possible Issues ---------------- +**Possible Issues** + DAW projects with automation data written by an AudioUnit or VST3 plug-in built with pre JUCE 4.3.1 versions will load incorrectly when opened by an AudioUnit or VST3 built with JUCE versions 4.3.1 and later. Plug-ins using JUCE_FORCE_USE_LEGACY_PARAM_IDS are not affected. -Workaround ----------- +**Workaround** + Disable JUCE_USE_STUDIO_ONE_COMPATIBLE_PARAMETERS in the juce_audio_plugin_client module config page in the Projucer. For new plug-ins, be sure to use the default value for this property. -Rationale --------- +**Rationale** + JUCE needs to convert between its own JUCE parameter id format (strings) to the native parameter id formats of the various plug-in backends. For VST3 and AudioUnits, JUCE uses a hash function to generate a numeric id. However, some @@ -2505,27 +3974,26 @@ parameters that have a negative parameter id. Therefore, the hash function for VST3/AudioUnits needed to be changed to only return positive-valued hashes. -Version 4.3.0 -============= +# Version 4.3.0 + +## Change -Change ------- A revised multi-bus API was released which supersedes the previously flawed multi-bus API - JUCE versions 4.0.0 - 4.2.4 (inclusive). -Possible Issues ---------------- +**Possible Issues** + If you have developed a plug-in with JUCE versions 4.0.0 - 4.2.4 (inclusive), then you will need to update your plug-in to the new multi-bus API. Pre JUCE 4.0.0 plug-ins are not affected apart from other breaking changes listed in this document. -Workaround ---------- +**Workaround** + None. -Rationale --------- +**Rationale** + A flawed multi-bus API was introduced with JUCE versions 4.0.0 up until version 4.2.4 (inclusive) which was not API compatible with pre JUCE 4 plug-ins. JUCE 4.3.0 releases a revised multi-bus API which restores pre JUCE 4 API @@ -2533,27 +4001,27 @@ compatibility. However, the new multi-bus API is not compatible with the flawed multi-bus API (JUCE version 4.0.0 - 4.2.4). -Change ------- +## Change + JUCE now generates the AAX plug-in bus layout configuration id independent from the position as it appears in the Projucer’s legacy "Channel layout configuration" field. -Possible Issues ---------------- +**Possible Issues** + ProTools projects generated with a < 4.3.0 JUCE versions of your plug-in, may load the incorrect bus configuration when upgrading your plug-in to >= 4.3.0 versions of JUCE. -Workaround ----------- +**Workaround** + Implement AudioProcessor’s getAAXPluginIDForMainBusConfig callback to manually override which AAX plug-in id is associated to a specific bus layout of your plug-in. This workaround is only necessary if you have released your plug-in built with a version previous to JUCE 4.3.0. -Rationale --------- +**Rationale** + The new multi-bus API offers more features, flexibility and accuracy in specifying bus layouts which cannot be expressed by the Projucer’s legacy "Channel layout configuration" field. The native plug-in format backends use @@ -2569,27 +4037,26 @@ in which the channel configurations appear in the legacy "Channel layout configuration" field. -Version 4.2.1 -============= +# Version 4.2.1 + +## Change -Change ------- JUCE now uses the paramID property used in AudioProcessorParameterWithID to uniquely identify parameters to the host. -Possible Issues ---------------- +**Possible Issues** + DAW projects with automation data written by an audio plug-in built with pre JUCE 4.2.1 will load incorrectly when opened by an audio plug-in built with JUCE 4.2.1 and later. -Workaround ----------- +**Workaround** + Enable JUCE_FORCE_USE_LEGACY_PARAM_IDS in the juce_audio_plugin_client module config page in the Projucer. For new plug-ins, be sure to disable this property. -Rationale --------- +**Rationale** + Each parameter of the AudioProcessor has an id associated so that the plug-in’s host can uniquely identify parameters. The id has a different data-type for different plug-in types (for example VST uses integers, AAX uses string diff --git a/ChangeList.txt b/CHANGE_LIST.md similarity index 83% rename from ChangeList.txt rename to CHANGE_LIST.md index ca5cc3c9ed..978bb20d94 100644 --- a/ChangeList.txt +++ b/CHANGE_LIST.md @@ -1,16 +1,132 @@ -== Major JUCE features and updates == +# Major JUCE features and updates -This file just lists the more notable headline features. For more detailed info -about changes and bugfixes please see the git log and BREAKING-CHANGES.txt. +This file lists the more notable headline features. For more detailed info +about changes and bugfixes please see the git log and BREAKING_CHANGES.md. + +## Version 8.0.4 + + - Simplified singleton creation + - Fixed some Javascript and C++ interoperability issues + - Added exact passthrough of MIDI CC timestamps + - Switched to obtaining MIDI plug-in properties at runtime + - Improved Windows Arm CMake support + - Improved ShapedText + - Fixed some issues with Windows DLL builds + - Add system-provided timestamps to VBlankAttachment and animations + - Fixed some iOS deprecation warnings + - Updated embedded CHOC version + - Updated embedded Oboe version + - Moved the JavaScript implementation into a separate module + +## Version 8.0.3 + + - Updated the AAX SDK to 2.8.0 + - Fixed multiple Direct2D drawing issues + - Fixed buffer size and sample rate selection on iOS 18 + +## Version 8.0.2 + + - Fixed some issues handling large images in Direct2D + - Enabled rounded window corners in Windows 11 + - Fixed some compiler warnings in Xcode 16 + - Improved macOS and Android GU rendering performance + - Added support for C++20 and C++23 + - Fixed a Windows mouse response issue + - Updated the VST3 SDK to 3.7.12 + +## Version 8.0.1 + + - Fixed some issues with text layout + - Removed source code for unsupported platforms + - Fixed some Direct2D issues + - Update the embedded version of harfbuzz + - Added more surround formats + +## Version 8.0.0 + + - Added a new Direct2D renderer + - Added support for WebView based UIs + - Added consistent unicode support across platforms + - Added a new animation module + - Bundled the AAX SDK + +## Version 7.0.12 + + - Fixed an issue with timers in Pro Tools + - Fixed an issue with Projucer Xcode code signing + +## Version 7.0.11 + + - Fixed an issue with paths containing a tilde in Xcode + - Multiple fixes for plug-in deployment and code signing in Xcode + - Fixed an issue painting an empty RectangleList + - Improved the performance of TreeView rendering + +## Version 7.0.10 + + - Fixed multiple issues selecting devices in AudioDeviceSelector + - Updated the bundled Oboe version + - Fixed multiple issues with Timer + - Updated the bundled version of FLAC + - Added configuration options for sockets + - Added new JSON::Formatter + - Added support for Xcode 15.1 + - Update OpenGL compatibility headers + - Added ChildProcessManager + - Fixed multiple MIDI-CI issues + +## Version 7.0.9 + + - Added MIDI-CI support + - Added enumerate utility function + - Fixed a macOS/iOS CMake signing issue + +## Version 7.0.8 + + - Added macOS/iOS AudioWorkgroup support + - Added Xcode 15, macOS Sonoma and LLVM 17 compatibility + - Added serialisation tools + - Fixed some VST3 manifest generation issues + - Fixed a MessageManager locking bug + - Fixed GCC 7 VST3 support + - Fixed some SVG scaling issues + +## Version 7.0.7 + + - Fixed some macOS 14.0 deprecations + - Fixed some issues with VST3 manifest generation + - Fixed a Metal layer rendering issue + - Fixed an issue setting realtime thread priorities + - Fixed a crash in VirtualDesktopWatcher + - Fixed an AUv3 bundling problem + +## Version 7.0.6 + + - Added support for VST3 bundles and moduleinfo.json + - Improved message box dismissal + - Improved WebView support + - Updated to the latest VST3 and AAX SDKs + - Fixed some Metal layer rendering issues + - Improved ambisonic support + - Improved machine ID support + - Improved the HighResolutionTimer implementation + +## Version 7.0.5 + + - Fixed Windows 7 compatibility + - Fixed dark mode notifications on macOS + - Improved the performance of AudioProcessorGraph + +## Version 7.0.4 -Version 7.0.4 - Improved Metal device handling - Adopted more C++17 features - Improved input handling on macOS and iOS - Fixed a GUI display issue on Linux - Fixed some compiler warnings -Version 7.0.3 +## Version 7.0.3 + - Added a unique machine ID - Added new threading classes - Improved the performance of multiple OpenGL contexts @@ -19,18 +135,21 @@ Version 7.0.3 - Fixed Studio One drawing performance - Updated the FLAC library -Version 7.0.2 +## Version 7.0.2 + - Fixed accessibility table navigation - Fixed Android file access on older APIs - Improved Linux VST3 threading - Improved ARA integration -Version 7.0.1 +## Version 7.0.1 + - Fixed some Xcode and MSVC compiler warnings - Improved VST3 bus configuration and channel handling - Fixed some Metal layer rendering bugs -Version 7.0.0 +## Version 7.0.0 + - Added Audio Random Access (ARA) SDK support - Added support for authoring and hosting LV2 plug-ins - Added a default renderer for macOS and iOS @@ -40,14 +159,16 @@ Version 7.0.0 - Revamped AudioPlayHead functionality - Improved accessibility support -Version 6.1.6 +## Version 6.1.6 + - Improved the handling of AU multichannel layouts - Added JUCE_NODISCARD to builder-patten functions - Added recursion options to DirectoryIterator - Unified the loading of OpenGL 3.2 core profiles - Improved macOS full-screen behaviour with non-native titlebars -Version 6.1.5 +## Version 6.1.5 + - Improved the accessibility framework - Added handling of non-Latin virtual key codes on macOS - Improved X11 compatibility @@ -56,12 +177,14 @@ Version 6.1.5 - Improved MinGW-w64 compatibility - Added an MPEKeyboardComponent class -Version 6.1.4 +## Version 6.1.4 + - Restored Projucer project saving behavior - Fixed a CGImage memory access violation on Monterey - Improved macOS thread priority management -Version 6.1.3 +## Version 6.1.3 + - Added support for Visual Studio 2022 to the Projucer - Added support for creating OpenGL 3.2 contexts on Windows - Added support for plugin hosts to easily retrieve stable parameter IDs @@ -72,12 +195,14 @@ Version 6.1.3 - Improved macOS 12 compatibility, including OpenGL and FileChooser fixes - Improved accessibility support -Version 6.1.2 +## Version 6.1.2 + - Fixed an OpenGL display refresh rate issue on macOS - Improved the scaling behaviour of hosted VST3 plug-ins - Improved accessibility support -Version 6.1.1 +## Version 6.1.1 + - Fixed a CMake installation issue - Improved parameter value loading after plug-in restarts - Fixed some problems with multi-line text layouts @@ -85,7 +210,8 @@ Version 6.1.1 - Fixed an issue setting OpenGL repaint events - Improved accessibility support -Version 6.1.0 +## Version 6.1.0 + - Added accessibility support - Enabled use of VST3 plug-in extensions - Improved OpenGL function loading @@ -102,7 +228,8 @@ Version 6.1.0 - Improved modal dismissing - Improved assertion handling on macOS ARM -Version 6.0.8 +## Version 6.0.8 + - Fixed a macOS graphics invalidation region issue - Improved the handling of modal dialog dismissal - Fixed audio glitching in CoreAudio before microphone permission is granted @@ -116,11 +243,13 @@ Version 6.0.8 - Fixed some DSP convolution issues - Added host detection on macOS ARM -Version 6.0.7 +## Version 6.0.7 + - Fixed a macOS drawing issue - Updated the DemoRunner bundle ID -Version 6.0.6 +## Version 6.0.6 + - Moved to the new CoreMIDI API on supported platforms - Added support for the "New Build System" in Xcode - Made the audio format readers more robust @@ -128,7 +257,8 @@ Version 6.0.6 - Fixed a VST3 program parameter issue - Updated to Oboe 1.5 on Android -Version 6.0.5 +## Version 6.0.5 + - Added more support for styling PopupMenus - Fixed some race conditions in the IPC and name named pipe classes - Implemented multiple FileChooser improvements @@ -136,16 +266,19 @@ Version 6.0.5 - Prevented CoreAudio glitches before accepting audio access permissions - Made reading MIDI and audio files more robust -Version 6.0.4 +## Version 6.0.4 + - Improved the Projucer update mechanism - Fixed an AUv3 parameter normalisation issue - Fixed WASAPI exclusive mode sample rate selection bug - Fixed a Linux build issue when omitting ALSA -Version 6.0.3 +## Version 6.0.3 + - Fixed version numbers in project files -Version 6.0.2 +## Version 6.0.2 + - Added support for macOS 11 and arm64 - Added Windows IAudioClient3 support for low latency audio drivers - Added Windows and macOS precompiled header support in the Projucer @@ -155,7 +288,8 @@ Version 6.0.2 - Improved resave diffs in Projucer project files - Fixed some Linux JACK issues -Version 6.0.1 +## Version 6.0.1 + - Fixed a bug in the Projucer GUI editor causing existing code to be overwritten - Updated Android Oboe to 1.4.2 - Bumped default Android Studio gradle and plugin versions to the latest @@ -169,7 +303,8 @@ Version 6.0.1 - Fixed Projucer CLion exporter generated CMakeLists.txt - Fixed drag and drop for non-DPI aware plug-ins on Windows -Version 6.0.0 +## Version 6.0.0 + - Added support for building JUCE projects with CMake - Revamped the DSP module - Added VST3 support on Linux @@ -195,7 +330,8 @@ Version 6.0.0 - Windows and Linux hiDPI scaling improvements - Various bug-fixes, improvements and documentation updates -Version 5.4.7 +## Version 5.4.7 + - Fixed a macOS focus bug causing Components to not receive mouse events - Fixed a potential NullPointerException in the Android IAP code - Fixed an entitlements file generation bug in the Projucer @@ -203,7 +339,8 @@ Version 5.4.7 - Fixed some build errors and warnings when using Clang on Windows - Changed the default architecture specified in Linux Makefiles generated by the Projucer -Version 5.4.6 +## Version 5.4.6 + - Fixed compatibility with macOS versions below 10.11 - Multiple thread safety improvements - Added dynamic parameter and parameter group names @@ -212,7 +349,8 @@ Version 5.4.6 - Replaced WaitableEvent internals with std::condition_variable - Fixed some macOS text alignment issues -Version 5.4.5 +## Version 5.4.5 + - Improved message queue performance on Linux - Added missing lifecycle callbacks on Android Q - Refactored the AudioBlock class @@ -224,7 +362,8 @@ Version 5.4.5 - Replaced select() calls with poll() - Various bug-fixes, improvements and documentation updates -Version 5.4.4 +## Version 5.4.4 + - Improvements to floating point number printing - Faster plug-in parameter indexing - Added support for persisting attachements to MIDI devices @@ -234,7 +373,8 @@ Version 5.4.4 - Added support for Visual Studio 2019 - Removed support for Visual Studio 2013 -Version 5.4.3 +## Version 5.4.3 + - Added a Visual Studio 2019 exporter to the Projucer - Added options to configure macOS Hardened Runtime in the Projucer - Fixed a potential memory corruption when drawing on macOS/iOS @@ -242,7 +382,8 @@ Version 5.4.3 - Multiple DSP module enhancements - Various bug-fixes, improvements and documentation updates -Version 5.4.2 +## Version 5.4.2 + - Restructured the low-level Android native code - Added an ADSR envelope class - AudioProcessorValueTreeState performance improvements @@ -250,7 +391,8 @@ Version 5.4.2 - Improved VST3 hosting - Windows hiDPI scaling enhancements -Version 5.4.1 +## Version 5.4.1 + - Fixed a VST2 compilation error in VS2013 - Fixed some live-build compilation errors in the Projucer - Fixed a bug in the Oversampling class @@ -258,7 +400,8 @@ Version 5.4.1 - Fixed some bugs in the Unity plug-in wrapper - Fixed some VS2015 compiler errors -Version 5.4.0 +## Version 5.4.0 + - macOS Mojave and iOS 12 support - Windows hiDPI support - Unity native plug-in support @@ -270,7 +413,8 @@ Version 5.4.0 - Support for Android Studio 3.2 - Various bug-fixes, improvements and documentation updates -Version 5.3.2 +## Version 5.3.2 + - Removed the OSX 10.5 and 10.6 deployment target options from the Projucer and enabled more C++11 features across all platforms - Replaced all usage of ScopedPointer with std::unique_ptr - Added camera support for iOS and Android @@ -285,7 +429,8 @@ Version 5.3.2 - Fixed a bug causing an unintentional menu item highlight disco party when using a popup menu in a plug-in's UI - Marked as deprecated: String::empty, var::null, File::nonexistent, ValueTree::invalid and other problematic statically-initialised null values -Version 5.3.1 +## Version 5.3.1 + - Add Android and iOS support to AudioPluginHost - Added support for Bela in the form of an AudioIODeviceType - Add bypass support to both hosting and plug-in client code @@ -304,7 +449,8 @@ Version 5.3.1 - Added a command-line option to use LF as linefeeds rather than CRLF in the Projucer cleanup tools - Multiple documentation updates -Version 5.3.0 +## Version 5.3.0 + - Added support for Android OBOE (developer preview) - Updated JUCE's MPE classes to comply with the new MMA-adopted specification - Multiple documentation updates @@ -317,7 +463,8 @@ Version 5.3.0 - Added thread safe methods for getting and setting the AudioProcessorValueTreeState state - Added customisable MacOS icons -Version 5.2.1 +## Version 5.2.1 + - Added native content sharing support for iOS and Android - Added iOS and Android native file chooser support - Implemented WebBrowserComponent on Android @@ -343,7 +490,8 @@ Version 5.2.1 - Multiple Projucer UI and UX improvements - Various documentation tweaks and fixes -Version 5.2.0 +## Version 5.2.0 + - Added a CMake exporter to the Projucer - JUCE analytics module - Added support for push notifications on iOS and Android @@ -362,7 +510,8 @@ Version 5.2.0 - Improved the performance of 3D rendering when multiple OpenGL contexts are used at the same time - Tweaked the rate at which EdgeTable grows its internal storage, to improve performance rendering large and complex paths -Version 5.1.2 +## Version 5.1.2 + - Fixed multiple plugin-resizing bugs - Added support for AUv3 MIDI and screen size negotiation - Added support for Xcode 9 and iOS 11 @@ -376,7 +525,8 @@ Version 5.1.2 - Plug-in parameters can be explicitly marked as continuous or discrete - Multiple documentation updates -Version 5.1.1 +## Version 5.1.1 + - Fixed Windows live build engine on Visual Studio 2017 - Fixed a compiler error in juce_MathFunctions.h in Visual Studio 2013 - Fixed a potential crash when using the ProcessorDuplicator @@ -390,7 +540,8 @@ Version 5.1.1 - Fixed an issue where a JUCE VST2 would not correctly report that it supports resizing of it’s plugin editor - Various documentation tweaks and fixes -Version 5.1.0 +## Version 5.1.0 + - Release of the JUCE DSP module - Multichannel audio readers and writers - Plugin editor Hi-DPI scaling support @@ -402,7 +553,8 @@ Version 5.1.0 - Various documentation fixes - Various minor improvements and bug fixes -Version 5.0.2 +## Version 5.0.2 + - Improved project save speed in the Projucer - Added option to save individual exporters in the Projucer - Added the ability to create custom colour schemes for the Projucer’s code editor @@ -425,7 +577,8 @@ Version 5.0.2 - Various documentation fixes - Various minor improvements and bug fixes -Version 5.0.1 +## Version 5.0.1 + - Fixed Windows live build engine on Visual Studio 2017 - Fixed memory-leak in Projucer live build engine - Fixed an issue where you could not paste your redeem serial number with Cmd+V on macOS @@ -433,7 +586,8 @@ Version 5.0.1 - Minor Projucer UI improvements - Various minor improvements and bug fixes -Version 5.0.0 +## Version 5.0.0 + - New licensing model - Projucer UI/UX overhaul - New look and feel (version 4) @@ -452,7 +606,8 @@ Version 5.0.0 - Various minor improvements and bug fixes - Various documentation improvements -Version 4.3.1 +## Version 4.3.1 + - Added support for iOS download tasks - Added support for AAX plug-in meters - Added support for dynamically disabling/enabling sidechains in ProTools @@ -467,7 +622,8 @@ Version 4.3.1 - Various minor improvements and bug fixes - Various documentation improvements -Version 4.3.0 +## Version 4.3.0 + - Added API and examples for ROLI Blocks - Multiple Projucer live-build UI and diagnostics improvements - JUCE now supports hosting multi-bus plug-ins @@ -480,7 +636,8 @@ Version 4.3.0 - Various minor improvements and bug fixes - Various documentation improvements -Version 4.2.4 +## Version 4.2.4 + - Pre-release of live build engine on Windows - Added FlexBox layout engine - Removed dependency on external Steinberg SDK when building and/or hosting VST2 plug-ins @@ -504,18 +661,21 @@ Version 4.2.4 - Various minor improvements and bug fixes - Various documentation improvements -Version 4.2.3 +## Version 4.2.3 + - Various VST3 improvements: resizing VST3 windows, plug-in compatibility issues - Use NSURLSession on newer OS X versions - Add compatibility for VST 3 SDK update 3.6.6 - Miscellaneous fixes and improvements -Version 4.2.1 +## Version 4.2.1 + - New class CachedValue, for providing easy and efficient access to ValueTree properties - Reduced audio plug-in binary sizes on OS X and added symbol-stripping option - Miscellaneous fixes and improvements -Version 4.2 +## Version 4.2 + - Added support for AudioUnit v3 on OS X and iOS - Simplified the JUCE module format. Removed the json module definition files, and made it easier to manually add modules to projects. The format is fully described in the @@ -528,21 +688,25 @@ Version 4.2 open-source project. This will allow everyone to compile the Projucer's IDE themselves, and having just one app instead of two will make things a lot less confusing! -Version 4.1 +## Version 4.1 + - Added multi-bus support for audio plug-in clients - Added support for MIDI effect plug-ins (AU and AAX). - Added new example: Network Graphics Demo -Version 4.0.3 +## Version 4.0.3 + - Added MPE (Multidimensional Polyphonic Expression) classes - Added full support for generating and parsing Midi RPN/NRPN messages - Made the LinearSmoothedValue class public - Miscellaneous fixes and minor improvements -Version 4.0.2 +## Version 4.0.2 + - Miscellaneous fixes and house-keeping -Version 4.0.1 +## Version 4.0.1 + - Initial release of the Projucer! - Full OSC support! - Android Studio exporting from the Introjucer @@ -556,12 +720,14 @@ Version 4.0.1 - Many updates to Introjucer - Many new tutorials and examples -Version 3.3.0 +## Version 3.3.0 + - New functions for Base64 conversion - New command-line options in the introjucer for trimming whitespace and replacing tabs in source files -Version 3.2.0 +## Version 3.2.0 + - Major OpenGL performance/stability improvements - Performance improvements to FloatVectorOperations math functions - New FloatVectorOperations: abs, min, max, addWithMultiply, clip diff --git a/CMakeLists.txt b/CMakeLists.txt index cb7252c299..019aa86c51 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,170 +1,194 @@ -# ============================================================================== -# -# This file is part of the JUCE library. -# Copyright (c) 2022 - Raw Material Software Limited -# -# JUCE is an open source library subject to commercial or open-source -# licensing. -# -# By using JUCE, you agree to the terms of both the JUCE 7 End-User License -# Agreement and JUCE Privacy Policy. -# -# End User License Agreement: www.juce.com/juce-7-licence -# Privacy Policy: www.juce.com/juce-privacy-policy -# -# Or: You may also use this code under the terms of the GPL v3 (see -# www.gnu.org/licenses). -# -# JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER -# EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE -# DISCLAIMED. -# -# ============================================================================== - -cmake_minimum_required(VERSION 3.15) - -project(JUCE VERSION 7.0.4 LANGUAGES C CXX) - -include(CMakeDependentOption) - -set_property(GLOBAL PROPERTY USE_FOLDERS YES) - -set(JUCE_MODULES_DIR "${JUCE_SOURCE_DIR}/modules" CACHE INTERNAL - "The path to JUCE modules") - -# This option will disable most of the JUCE helper functions and tools. This option exists to -# facilitate existing CMake builds which handle things like bundle creation, icons, plists, and -# binary data independently of JUCE. This option is not recommended - use at your own risk! - -option(JUCE_MODULES_ONLY "Only configure the JUCE modules" OFF) - -include(extras/Build/CMake/JUCEModuleSupport.cmake) - -# This option controls whether dummy targets are added to the build, where these targets contain all -# of the source files for each JUCE module. If you're planning to use an IDE and want to be able to -# browse all of JUCE's source files, this may be useful. However, it will increase the size of -# generated IDE projects and might slow down configuration a bit. If you enable this, you should -# probably also add `set_property(GLOBAL PROPERTY USE_FOLDERS YES)` to your top level CMakeLists, -# otherwise the module sources will be added directly to the top level of the project, instead of in -# a nice 'Modules' subfolder. - -cmake_dependent_option(JUCE_ENABLE_MODULE_SOURCE_GROUPS - "Show all module sources in IDE projects" OFF - "NOT JUCE_MODULES_ONLY" OFF) - -add_subdirectory(modules) - -if(JUCE_MODULES_ONLY) - return() -endif() - -include(extras/Build/CMake/JUCEUtils.cmake) - -set_directory_properties(PROPERTIES - JUCE_COMPANY_NAME "JUCE" - JUCE_COMPANY_WEBSITE "https://juce.com" - JUCE_COMPANY_EMAIL "info@juce.com" - JUCE_COMPANY_COPYRIGHT "Copyright (c) 2020 - Raw Material Software Limited") - -option(JUCE_COPY_PLUGIN_AFTER_BUILD - "Whether or not plugins should be installed to the system after building" OFF) -set_property(GLOBAL PROPERTY JUCE_COPY_PLUGIN_AFTER_BUILD ${JUCE_COPY_PLUGIN_AFTER_BUILD}) - -set(CMAKE_CXX_EXTENSIONS FALSE) - -juce_disable_default_flags() - -add_subdirectory(extras/Build) - -# If you want to build the JUCE examples with VST2/AAX/ARA support, you'll need to make the -# VST2/AAX/ARA headers visible to the juce_audio_processors module. You can either set the paths on -# the command line, (e.g. -DJUCE_GLOBAL_AAX_SDK_PATH=/path/to/sdk) if you're just building the JUCE -# examples, or you can call the `juce_set_*_sdk_path` functions in your own CMakeLists after -# importing JUCE. - -if(JUCE_GLOBAL_AAX_SDK_PATH) - juce_set_aax_sdk_path("${JUCE_GLOBAL_AAX_SDK_PATH}") -endif() - -if(JUCE_GLOBAL_VST2_SDK_PATH) - juce_set_vst2_sdk_path("${JUCE_GLOBAL_VST2_SDK_PATH}") -endif() - -# The ARA_SDK path should point to the "Umbrella installer" ARA_SDK directory. -# The directory can be obtained by recursively cloning https://github.com/Celemony/ARA_SDK and -# checking out the tag releases/2.1.0. -if(JUCE_GLOBAL_ARA_SDK_PATH) - juce_set_ara_sdk_path("${JUCE_GLOBAL_ARA_SDK_PATH}") -endif() - -# We don't build anything other than the juceaide by default, because we want to keep configuration -# speedy and the number of targets low. If you want to add targets for the extra projects and -# example PIPs (there's a lot of them!), specify -DJUCE_BUILD_EXAMPLES=ON and/or -# -DJUCE_BUILD_EXTRAS=ON when initially generating your build tree. - -option(JUCE_BUILD_EXTRAS "Add build targets for the Projucer and other tools" OFF) - -if(JUCE_BUILD_EXTRAS) - add_subdirectory(extras) -endif() - -option(JUCE_BUILD_EXAMPLES "Add build targets for the DemoRunner and PIPs" OFF) - -if(JUCE_BUILD_EXAMPLES) - add_subdirectory(examples) -endif() - -# ================================================================================================== -# Install configuration - -include(CMakePackageConfigHelpers) -write_basic_package_version_file("${JUCE_BINARY_DIR}/JUCEConfigVersion.cmake" - VERSION ${JUCE_VERSION} - COMPATIBILITY ExactVersion - ${extra_version_arg}) - -set(JUCE_INSTALL_DESTINATION "lib/cmake/JUCE-${JUCE_VERSION}" CACHE STRING - "The location, relative to the install prefix, where the JUCE config file will be installed") - -set(JUCE_MODULE_PATH "include/JUCE-${JUCE_VERSION}/modules") -set(UTILS_INSTALL_DIR "${JUCE_INSTALL_DESTINATION}") -set(JUCEAIDE_PATH "${JUCE_TOOL_INSTALL_DIR}/${JUCE_JUCEAIDE_NAME}") -configure_package_config_file("${JUCE_CMAKE_UTILS_DIR}/JUCEConfig.cmake.in" - "${JUCE_BINARY_DIR}/JUCEConfig.cmake" - PATH_VARS UTILS_INSTALL_DIR JUCEAIDE_PATH JUCE_MODULE_PATH - INSTALL_DESTINATION "${JUCE_INSTALL_DESTINATION}") - -set(JUCE_MODULE_PATH "${JUCE_MODULES_DIR}") -set(UTILS_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/extras/Build/CMake") -get_target_property(JUCEAIDE_PATH juceaide IMPORTED_LOCATION) -configure_package_config_file("${JUCE_CMAKE_UTILS_DIR}/JUCEConfig.cmake.in" - "${JUCE_BINARY_DIR}/JUCEExportConfig.cmake" - PATH_VARS UTILS_INSTALL_DIR JUCEAIDE_PATH JUCE_MODULE_PATH - INSTALL_PREFIX "${CMAKE_CURRENT_BINARY_DIR}" - INSTALL_DESTINATION "${CMAKE_CURRENT_BINARY_DIR}") - -install(FILES "${JUCE_BINARY_DIR}/JUCEConfigVersion.cmake" - "${JUCE_BINARY_DIR}/JUCEConfig.cmake" - "${JUCE_CMAKE_UTILS_DIR}/JUCECheckAtomic.cmake" - "${JUCE_CMAKE_UTILS_DIR}/JUCEHelperTargets.cmake" - "${JUCE_CMAKE_UTILS_DIR}/JUCEModuleSupport.cmake" - "${JUCE_CMAKE_UTILS_DIR}/JUCEUtils.cmake" - "${JUCE_CMAKE_UTILS_DIR}/JuceLV2Defines.h.in" - "${JUCE_CMAKE_UTILS_DIR}/LaunchScreen.storyboard" - "${JUCE_CMAKE_UTILS_DIR}/PIPAudioProcessor.cpp.in" - "${JUCE_CMAKE_UTILS_DIR}/PIPAudioProcessorWithARA.cpp.in" - "${JUCE_CMAKE_UTILS_DIR}/PIPComponent.cpp.in" - "${JUCE_CMAKE_UTILS_DIR}/PIPConsole.cpp.in" - "${JUCE_CMAKE_UTILS_DIR}/RecentFilesMenuTemplate.nib" - "${JUCE_CMAKE_UTILS_DIR}/UnityPluginGUIScript.cs.in" - "${JUCE_CMAKE_UTILS_DIR}/checkBundleSigning.cmake" - "${JUCE_CMAKE_UTILS_DIR}/copyDir.cmake" - "${JUCE_CMAKE_UTILS_DIR}/juce_runtime_arch_detection.cpp" - DESTINATION "${JUCE_INSTALL_DESTINATION}") - -if("${CMAKE_SOURCE_DIR}" STREQUAL "${JUCE_SOURCE_DIR}") - _juce_add_lv2_manifest_helper_target() - install(TARGETS juce_lv2_helper EXPORT LV2_HELPER DESTINATION "bin/JUCE-${JUCE_VERSION}") - install(EXPORT LV2_HELPER NAMESPACE juce:: DESTINATION "${JUCE_INSTALL_DESTINATION}") -endif() - +# ============================================================================== +# +# 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. +# +# ============================================================================== + +cmake_minimum_required(VERSION 3.22) + +project(JUCE VERSION 8.0.4 LANGUAGES C CXX) + +include(CMakeDependentOption) + +set_property(GLOBAL PROPERTY USE_FOLDERS YES) + +set(JUCE_MODULES_DIR "${JUCE_SOURCE_DIR}/modules" CACHE INTERNAL + "The path to JUCE modules") + +# This option will disable most of the JUCE helper functions and tools. This option exists to +# facilitate existing CMake builds which handle things like bundle creation, icons, plists, and +# binary data independently of JUCE. This option is not recommended - use at your own risk! + +option(JUCE_MODULES_ONLY "Only configure the JUCE modules" OFF) + +include(extras/Build/CMake/JUCEModuleSupport.cmake) + +# This option controls whether dummy targets are added to the build, where these targets contain all +# of the source files for each JUCE module. If you're planning to use an IDE and want to be able to +# browse all of JUCE's source files, this may be useful. However, it will increase the size of +# generated IDE projects and might slow down configuration a bit. If you enable this, you should +# probably also add `set_property(GLOBAL PROPERTY USE_FOLDERS YES)` to your top level CMakeLists, +# otherwise the module sources will be added directly to the top level of the project, instead of in +# a nice 'Modules' subfolder. + +cmake_dependent_option(JUCE_ENABLE_MODULE_SOURCE_GROUPS + "Show all module sources in IDE projects" OFF + "NOT JUCE_MODULES_ONLY" OFF) + +add_subdirectory(modules) + +if(JUCE_MODULES_ONLY) + return() +endif() + +include(extras/Build/CMake/JUCEUtils.cmake) + +set_directory_properties(PROPERTIES + JUCE_COMPANY_NAME "JUCE" + JUCE_COMPANY_WEBSITE "https://juce.com" + JUCE_COMPANY_EMAIL "info@juce.com" + JUCE_COMPANY_COPYRIGHT "Copyright (c) - Raw Material Software Limited") + +option(JUCE_COPY_PLUGIN_AFTER_BUILD + "Whether or not plugins should be installed to the system after building" OFF) +set_property(GLOBAL PROPERTY JUCE_COPY_PLUGIN_AFTER_BUILD ${JUCE_COPY_PLUGIN_AFTER_BUILD}) + +set(CMAKE_CXX_EXTENSIONS FALSE) + +juce_disable_default_flags() + +add_subdirectory(extras/Build) + +# If you want to build the JUCE examples with VST2/AAX/ARA support, you'll need to make the +# VST2/AAX/ARA headers visible to the juce_audio_processors module. You can either set the paths on +# the command line, (e.g. -DJUCE_GLOBAL_AAX_SDK_PATH=/path/to/sdk) if you're just building the JUCE +# examples, or you can call the `juce_set_*_sdk_path` functions in your own CMakeLists after +# importing JUCE. + +if(JUCE_GLOBAL_AAX_SDK_PATH) + juce_set_aax_sdk_path("${JUCE_GLOBAL_AAX_SDK_PATH}") +endif() + +if(JUCE_GLOBAL_VST2_SDK_PATH) + juce_set_vst2_sdk_path("${JUCE_GLOBAL_VST2_SDK_PATH}") +endif() + +# The ARA_SDK path should point to the "Umbrella installer" ARA_SDK directory. +# The directory can be obtained by recursively cloning https://github.com/Celemony/ARA_SDK and +# checking out the tag releases/2.1.0. +if(JUCE_GLOBAL_ARA_SDK_PATH) + juce_set_ara_sdk_path("${JUCE_GLOBAL_ARA_SDK_PATH}") +endif() + +# We don't build anything other than the juceaide by default, because we want to keep configuration +# speedy and the number of targets low. If you want to add targets for the extra projects and +# example PIPs (there's a lot of them!), specify -DJUCE_BUILD_EXAMPLES=ON and/or +# -DJUCE_BUILD_EXTRAS=ON when initially generating your build tree. + +option(JUCE_BUILD_EXTRAS "Add build targets for the Projucer and other tools" OFF) + +if(JUCE_BUILD_EXTRAS) + add_subdirectory(extras) +endif() + +option(JUCE_BUILD_EXAMPLES "Add build targets for the DemoRunner and PIPs" OFF) + +if(JUCE_BUILD_EXAMPLES) + add_subdirectory(examples) +endif() + +string(CONCAT webview2_option_message "Location that overrides the default directory where our " + "FindWebView2 script is looking for the " + "*Microsoft.Web.WebView2* directory") + +option(JUCE_WEBVIEW2_PACKAGE_LOCATION ${webview2_option_message} "") + +# ================================================================================================== +# Install configuration + +include(CMakePackageConfigHelpers) +write_basic_package_version_file("${JUCE_BINARY_DIR}/JUCEConfigVersion.cmake" + VERSION ${JUCE_VERSION} + COMPATIBILITY ExactVersion) + +set(JUCE_INSTALL_DESTINATION "lib/cmake/JUCE-${JUCE_VERSION}" CACHE STRING + "The location, relative to the install prefix, where the JUCE config file will be installed") + +set(JUCE_MODULE_PATH "include/JUCE-${JUCE_VERSION}/modules") +set(UTILS_INSTALL_DIR "${JUCE_INSTALL_DESTINATION}") +set(JUCEAIDE_PATH "${JUCE_TOOL_INSTALL_DIR}/${JUCE_JUCEAIDE_NAME}") +configure_package_config_file("${JUCE_CMAKE_UTILS_DIR}/JUCEConfig.cmake.in" + "${JUCE_BINARY_DIR}/JUCEConfig.cmake" + PATH_VARS UTILS_INSTALL_DIR JUCEAIDE_PATH JUCE_MODULE_PATH + INSTALL_DESTINATION "${JUCE_INSTALL_DESTINATION}") + +set(JUCE_MODULE_PATH "${JUCE_MODULES_DIR}") +set(UTILS_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/extras/Build/CMake") +get_target_property(JUCEAIDE_PATH juceaide IMPORTED_LOCATION) +configure_package_config_file("${JUCE_CMAKE_UTILS_DIR}/JUCEConfig.cmake.in" + "${JUCE_BINARY_DIR}/JUCEExportConfig.cmake" + PATH_VARS UTILS_INSTALL_DIR JUCEAIDE_PATH JUCE_MODULE_PATH + INSTALL_PREFIX "${CMAKE_CURRENT_BINARY_DIR}" + INSTALL_DESTINATION "${CMAKE_CURRENT_BINARY_DIR}") + +install(FILES "${JUCE_BINARY_DIR}/JUCEConfigVersion.cmake" + "${JUCE_BINARY_DIR}/JUCEConfig.cmake" + "${JUCE_CMAKE_UTILS_DIR}/JUCECheckAtomic.cmake" + "${JUCE_CMAKE_UTILS_DIR}/JUCEHelperTargets.cmake" + "${JUCE_CMAKE_UTILS_DIR}/JUCEModuleSupport.cmake" + "${JUCE_CMAKE_UTILS_DIR}/JUCEUtils.cmake" + "${JUCE_CMAKE_UTILS_DIR}/JuceLV2Defines.h.in" + "${JUCE_CMAKE_UTILS_DIR}/LaunchScreen.storyboard" + "${JUCE_CMAKE_UTILS_DIR}/PIPAudioProcessor.cpp.in" + "${JUCE_CMAKE_UTILS_DIR}/PIPAudioProcessorWithARA.cpp.in" + "${JUCE_CMAKE_UTILS_DIR}/PIPComponent.cpp.in" + "${JUCE_CMAKE_UTILS_DIR}/PIPConsole.cpp.in" + "${JUCE_CMAKE_UTILS_DIR}/RecentFilesMenuTemplate.nib" + "${JUCE_CMAKE_UTILS_DIR}/UnityPluginGUIScript.cs.in" + "${JUCE_CMAKE_UTILS_DIR}/checkBundleSigning.cmake" + "${JUCE_CMAKE_UTILS_DIR}/copyDir.cmake" + "${JUCE_CMAKE_UTILS_DIR}/juce_runtime_arch_detection.cpp" + "${JUCE_CMAKE_UTILS_DIR}/juce_LinuxSubprocessHelper.cpp" + DESTINATION "${JUCE_INSTALL_DESTINATION}") + +if(("${CMAKE_SOURCE_DIR}" STREQUAL "${JUCE_SOURCE_DIR}") AND (NOT JUCE_BUILD_HELPER_TOOLS)) + _juce_add_lv2_manifest_helper_target() + + if(TARGET juce_lv2_helper) + install(TARGETS juce_lv2_helper EXPORT LV2_HELPER DESTINATION "bin/JUCE-${JUCE_VERSION}") + install(EXPORT LV2_HELPER NAMESPACE juce:: DESTINATION "${JUCE_INSTALL_DESTINATION}") + endif() + + _juce_add_vst3_manifest_helper_target() + + if(TARGET juce_vst3_helper) + install(TARGETS juce_vst3_helper EXPORT VST3_HELPER DESTINATION "bin/JUCE-${JUCE_VERSION}") + install(EXPORT VST3_HELPER NAMESPACE juce:: DESTINATION "${JUCE_INSTALL_DESTINATION}") + endif() +endif() diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000000..3cb6776e36 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,132 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, caste, color, religion, or sexual +identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the overall + community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or advances of + any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email address, + without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +[info@juce.com](mailto:info@juce.com). +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series of +actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or permanent +ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the +community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.1, available at +[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. + +For answers to common questions about this code of conduct, see the FAQ at +[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at +[https://www.contributor-covenant.org/translations][translations]. + +[homepage]: https://www.contributor-covenant.org +[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html +[Mozilla CoC]: https://github.com/mozilla/diversity +[FAQ]: https://www.contributor-covenant.org/faq +[translations]: https://www.contributor-covenant.org/translations diff --git a/LICENSE.md b/LICENSE.md index 9cf154811f..fa98770365 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,37 +1,66 @@ -# The JUCE Library +# The JUCE Framework -**BY DOWNLOADING, INSTALLING OR USING ANY PART OF THE JUCE LIBRARY, YOU AGREE -TO THE [JUCE 7 END-USER LICENSE AGREEMENT](https://www.juce.com/juce-7-licence) -AND THE [JUCE PRIVACY POLICY](https://www.juce.com/juce-privacy-policy), WHICH -ARE BINDING AGREEMENTS BETWEEN YOU AND RAW MATERIAL SOFTWARE LIMITED. IF YOU DO -NOT AGREE TO THE TERMS, DO NOT USE THE JUCE LIBRARY.** +The JUCE Framework is an open source framework licensed under a combination of +open source and commercial licences. -JUCE has tier-leveled license terms, with different terms for each available -license: JUCE Personal (for developers or startup businesses with revenue under -the 50K USD Revenue Limit; free), JUCE Indie (for small businesses with under -500K USD Revenue Limit; $40/month), JUCE Pro (no Revenue Limit; $130/month), -and JUCE Educational (no Revenue Limit; free for bona fide educational -institutions). All licenses allow you to commercially release applications as -long as you do not exceed the Revenue Limit and pay the applicable Fees. Once -your business hits the Revenue Limit for your JUCE license tier, to continue -distributing your Applications you will either have to upgrade your JUCE -license, or instead release your Applications under the -[GNU General Public License v.3](https://www.gnu.org/licenses/gpl-3.0.en.html), -which means, amongst other things, that you must make the source code of your -Applications available. +The JUCE Framework modules are dual-licensed under the +[AGPLv3](https://www.gnu.org/licenses/agpl-3.0.en.html) and the commercial [JUCE +licence](https://juce.com/legal/juce-8-licence/). -JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER -EXPRESSED OR IMPLIED, INCLUDING WARRANTY OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE, ARE DISCLAIMED. +## The JUCE Licence -The juce_audio_basics, juce_audio_devices, juce_core and juce_events modules -are permissively licensed under the terms of the [ISC -license](http://www.isc.org/downloads/software-support-policy/isc-license). +If you are not licensing the JUCE Framework modules under the +[AGPLv3](https://www.gnu.org/licenses/agpl-3.0.en.html) then 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 the [JUCE 8 End User Licence +Agreement](https://juce.com/legal/juce-8-licence/), and all incorporated terms +including the [JUCE Privacy Policy](https://juce.com/legal/juce-privacy-policy/) +and the [JUCE Website Terms of +Service](https://juce.com/legal/juce-website-terms-of-service/), as applicable, +which will bind you. If you do not agree to the terms of this Agreement, 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. -For more information, visit the website: -[www.juce.com](https://www.juce.com) +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. -FULL JUCE TERMS: -- [JUCE 7 END-USER LICENSE AGREEMENT](https://www.juce.com/juce-7-licence) -- [JUCE PRIVACY POLICY](https://www.juce.com/juce-privacy-policy) +For more information, visit the [JUCE website](https://juce.com). +Full licence terms: +- [JUCE 8 End User Licence Agreement](https://juce.com/legal/juce-8-licence/) +- [JUCE Privacy Policy](https://juce.com/legal/juce-privacy-policy/) +- [JUCE Website Terms of Service](https://juce.com/legal/juce-website-terms-of-service/) + +## The JUCE Framework Dependencies + +The JUCE modules contain the following dependencies: +- [AudioUnitSDK](modules/juce_audio_plugin_client/AU/AudioUnitSDK/) ([Apache 2.0](modules/juce_audio_plugin_client/AU/AudioUnitSDK/LICENSE.txt)) +- [Oboe](modules/juce_audio_devices/native/oboe/) ([Apache 2.0](modules/juce_audio_devices/native/oboe/LICENSE)) +- [FLAC](modules/juce_audio_formats/codecs/flac/) ([BSD](modules/juce_audio_formats/codecs/flac/Flac%20Licence.txt)) +- [GLEW](modules/juce_opengl/opengl/juce_gl.h) ([BSD](modules/juce_opengl/opengl/juce_gl.h)), including [Mesa](modules/juce_opengl/opengl/juce_gl.h) ([MIT](modules/juce_opengl/opengl/juce_gl.h)) and [Khronos](modules/juce_opengl/opengl/juce_gl.h) ([MIT](modules/juce_opengl/opengl/juce_gl.h)) +- [Ogg Vorbis](modules/juce_audio_formats/codecs/oggvorbis/) ([BSD](modules/juce_audio_formats/codecs/oggvorbis/Ogg%20Vorbis%20Licence.txt)) +- [jpeglib](modules/juce_graphics/image_formats/jpglib/) ([Independent JPEG Group License](modules/juce_graphics/image_formats/jpglib/README)) +- [CHOC](modules/juce_core/javascript/choc/) ([ISC](modules/juce_core/javascript/choc/LICENSE.md)), including [QuickJS](modules/juce_core/javascript/choc/javascript/choc_javascript_QuickJS.h) ([MIT](modules/juce_core/javascript/choc/javascript/choc_javascript_QuickJS.h)) +- [LV2](modules/juce_audio_processors/format_types/LV2_SDK/) ([ISC](modules/juce_audio_processors/format_types/LV2_SDK/lv2/COPYING)) +- [pslextensions](modules/juce_audio_processors/format_types/pslextensions/ipslcontextinfo.h) ([Public domain](modules/juce_audio_processors/format_types/pslextensions/ipslcontextinfo.h)) +- [AAX](modules/juce_audio_plugin_client/AAX/SDK/) ([Proprietary Avid AAX License/GPLv3](modules/juce_audio_plugin_client/AAX/SDK/LICENSE.txt)) +- [VST3](modules/juce_audio_processors/format_types/VST3_SDK/) ([Proprietary Steinberg VST3 License/GPLv3](modules/juce_audio_processors/format_types/VST3_SDK/LICENSE.txt)) +- [Box2D](modules/juce_box2d/box2d/) ([zlib](modules/juce_box2d/box2d/Box2D.h)) +- [pnglib](modules/juce_graphics/image_formats/pnglib/) ([zlib](modules/juce_graphics/image_formats/pnglib/LICENSE)) +- [zlib](modules/juce_core/zip/zlib/) ([zlib](modules/juce_core/zip/zlib/README)) +- [HarfBuzz](modules/juce_graphics/fonts/harfbuzz/) ([Old MIT](modules/juce_graphics/fonts/harfbuzz/COPYING)) +- [SheenBidi](modules/juce_graphics/unicode/sheenbidi/) ([Apache](modules/juce_graphics/unicode/sheenbidi/LICENSE)) + +The JUCE examples are licensed under the terms of the +[ISC license](http://www.isc.org/downloads/software-support-policy/isc-license/). + +Dependencies in the examples: +- [reaper-sdk](examples/Plugins/extern/) ([zlib](examples/Plugins/extern/LICENSE.md)) + +Dependencies in the bundled applications: +- [Projucer icons](extras/Projucer/Source/Utility/UI/jucer_Icons.cpp) ([MIT](extras/Projucer/Source/Utility/UI/jucer_Icons.cpp)) + +Dependencies in the build system: +- [Android Gradle](examples/DemoRunner/Builds/Android/gradle/wrapper/LICENSE-for-gradlewrapper.txt) ([Apache 2.0](examples/DemoRunner/Builds/Android/gradle/wrapper/LICENSE-for-gradlewrapper.txt)) diff --git a/README.md b/README.md index 2f675c4411..c6402df854 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,38 @@ ![alt text](https://assets.juce.com/juce/JUCE_banner_github.png "JUCE") -JUCE is an open-source cross-platform C++ application framework for creating high quality -desktop and mobile applications, including VST, VST3, AU, AUv3, AAX and LV2 audio plug-ins -and plug-in hosts. JUCE can be easily integrated with existing projects via CMake, or can -be used as a project generation tool via the [Projucer](https://juce.com/discover/projucer), -which supports exporting projects for Xcode (macOS and iOS), Visual Studio, Android Studio, -Code::Blocks and Linux Makefiles as well as containing a source code editor. +JUCE is an open-source cross-platform C++ application framework for creating +desktop and mobile applications, including VST, VST3, AU, AUv3, AAX and LV2 +audio plug-ins and plug-in hosts. JUCE can be easily integrated with existing +projects via CMake, or can be used as a project generation tool via the +[Projucer](#the-projucer), which supports exporting projects for Xcode (macOS +and iOS), Visual Studio, Android Studio, and Linux Makefiles as well as +containing a source code editor. ## Getting Started -The JUCE repository contains a [master](https://github.com/juce-framework/JUCE/tree/master) -and [develop](https://github.com/juce-framework/JUCE/tree/develop) branch. The develop branch -contains the latest bugfixes and features and is periodically merged into the master -branch in stable [tagged releases](https://github.com/juce-framework/JUCE/releases) -(the latest release containing pre-built binaries can be also downloaded from the -[JUCE website](https://juce.com/get-juce)). +The JUCE repository contains a +[master](https://github.com/juce-framework/JUCE/tree/master) and +[develop](https://github.com/juce-framework/JUCE/tree/develop) branch. The +develop branch contains the latest bug fixes and features and is periodically +merged into the master branch in stable [tagged +releases](https://github.com/juce-framework/JUCE/releases) (the latest release +containing pre-built binaries can be also downloaded from the [JUCE +website](https://juce.com/get-juce)). -JUCE projects can be managed with either the Projucer (JUCE's own project-configuration -tool) or with CMake. +JUCE projects can be managed with either the Projucer (JUCE's own +project-configuration tool) or with CMake. ### The Projucer The repository doesn't contain a pre-built Projucer so you will need to build it -for your platform - Xcode, Visual Studio and Linux Makefile projects are located in -[extras/Projucer/Builds](/extras/Projucer/Builds) -(the minimum system requirements are listed in the __System Requirements__ section below). -The Projucer can then be used to create new JUCE projects, view tutorials and run examples. -It is also possible to include the JUCE modules source code in an existing project directly, -or build them into a static or dynamic library which can be linked into a project. +for your platform - Xcode, Visual Studio and Linux Makefile projects are located +in [extras/Projucer/Builds](/extras/Projucer/Builds) (the minimum system +requirements are listed in the [minimum system +requirements](#minimum-system-requirements) section below). The Projucer can +then be used to create new JUCE projects, view tutorials and run examples. It is +also possible to include the JUCE modules source code in an existing project +directly, or build them into a static or dynamic library which can be linked +into a project. For further help getting started, please refer to the JUCE [documentation](https://juce.com/learn/documentation) and @@ -35,7 +40,7 @@ For further help getting started, please refer to the JUCE ### CMake -Version 3.15 or higher is required. To use CMake, you will need to install it, +Version 3.22 or higher is required. To use CMake, you will need to install it, either from your system package manager or from the [official download page](https://cmake.org/download/). For comprehensive documentation on JUCE's CMake API, see the [JUCE CMake documentation](/docs/CMake%20API.md). For @@ -56,19 +61,20 @@ of the target you wish to build. #### Building JUCE Projects -- __macOS/iOS__: Xcode 10.1 (macOS 10.13.6) -- __Windows__: Windows 8.1 and Visual Studio 2017 +- __C++ Standard__: 17 +- __macOS/iOS__: Xcode 12.4 (Intel macOS 10.15.4, Apple Silicon macOS 11.0) +- __Windows__: Visual Studio 2019 (Windows 10) - __Linux__: g++ 7.0 or Clang 6.0 (for a full list of dependencies, see [here](/docs/Linux%20Dependencies.md)). -- __Android__: Android Studio on Windows, macOS or Linux +- __Android__: Android Studio (NDK 26) on Windows, macOS or Linux #### Deployment Targets -- __macOS__: macOS 10.9 -- __Windows__: Windows Vista -- __Linux__: Mainstream Linux distributions -- __iOS__: iOS 9.0 -- __Android__: Jelly Bean (API 16) +- __macOS__: macOS 10.11 (x86_64, Arm64) +- __Windows__: Windows 10 (x86_64, x86, Arm64, Arm64EC) +- __Linux__: Mainstream Linux distributions (x86_64, Arm64/aarch64, (32 bit Arm systems like armv7 should work but are not regularly tested)) +- __iOS__: iOS 12 (Arm64, Arm64e, x86_64 (Simulator)) +- __Android__: Android 5 - Lollipop (API Level 21) (arm64-v8a, armeabi-v7a, x86_64, x86) ## Contributing @@ -76,43 +82,37 @@ Please see our [contribution guidelines](.github/contributing.md). ## Licensing -The core JUCE modules (juce_audio_basics, juce_audio_devices, juce_core and juce_events) -are permissively licensed under the terms of the -[ISC license](http://www.isc.org/downloads/software-support-policy/isc-license/). -Other modules are covered by a -[GPL](https://www.gnu.org/licenses/gpl-3.0.en.html)/Commercial license. +See [LICENSE.md](LICENSE.md) for licensing and dependency information. -There are multiple commercial licensing tiers for JUCE, with different terms for each: -- JUCE Personal (developers or startup businesses with revenue under 50K USD) - free -- JUCE Indie (small businesses with revenue under 500K USD) - $40/month or $800 perpetual -- JUCE Pro (no revenue limit) - $130/month or $2600 perpetual -- JUCE Educational (no revenue limit) - free for bona fide educational institutes +## AAX Plug-Ins -For full terms see [LICENSE.md](LICENSE.md). +AAX plug-ins need to be digitally signed using PACE Anti-Piracy's signing tools +before they will run in commercially available versions of Pro Tools. These +tools are provided free of charge by Avid. Before obtaining the signing tools, +you will need to use a special build of Pro Tools, called Pro Tools Developer, +to test your unsigned plug-ins. The steps to obtain Pro Tools Developer are: -The JUCE framework contains the following dependencies: -- [Oboe](modules/juce_audio_devices/native/oboe/) ([Apache 2.0](modules/juce_audio_devices/native/oboe/LICENSE)) -- [FLAC](modules/juce_audio_formats/codecs/flac/) ([BSD](modules/juce_audio_formats/codecs/flac/Flac%20Licence.txt)) -- [Ogg Vorbis](modules/juce_audio_formats/codecs/oggvorbis/) ([BSD](modules/juce_audio_formats/codecs/oggvorbis/Ogg%20Vorbis%20Licence.txt)) -- [AudioUnitSDK](modules/juce_audio_plugin_client/AU/AudioUnitSDK/) ([Apache 2.0](modules/juce_audio_plugin_client/AU/AudioUnitSDK/LICENSE.txt)) -- [AUResources.r](modules/juce_audio_plugin_client/AUResources.r) ([Apple](modules/juce_audio_plugin_client/AUResources.r)) -- [LV2](modules/juce_audio_processors/format_types/LV2_SDK/) ([ISC](modules/juce_audio_processors/format_types/LV2_SDK/lv2/COPYING)) -- [pslextensions](modules/juce_audio_processors/format_types/pslextensions/ipslcontextinfo.h) ([Public domain](modules/juce_audio_processors/format_types/pslextensions/ipslcontextinfo.h)) -- [VST3](modules/juce_audio_processors/format_types/VST3_SDK/) ([Proprietary Steinberg VST3/GPLv3](modules/juce_audio_processors/format_types/VST3_SDK/LICENSE.txt)) -- [zlib](modules/juce_core/zip/zlib/) ([zlib](modules/juce_core/zip/zlib/README)) -- [Box2D](modules/juce_box2d/box2d/) ([zlib](modules/juce_box2d/box2d/Box2D.h)) -- [jpeglib](modules/juce_graphics/image_formats/jpglib/) ([Independent JPEG Group License](modules/juce_graphics/image_formats/jpglib/README)) -- [pnglib](modules/juce_graphics/image_formats/pnglib/) ([zlib](modules/juce_graphics/image_formats/pnglib/LICENSE)) -- [GLEW](modules/juce_opengl/opengl/juce_gl.h) ([BSD](modules/juce_opengl/opengl/juce_gl.h)), including [Mesa](modules/juce_opengl/opengl/juce_gl.h) ([MIT](modules/juce_opengl/opengl/juce_gl.h)) and [Khronos](modules/juce_opengl/opengl/juce_gl.h) ([MIT](modules/juce_opengl/opengl/juce_gl.h)) +1. Sign up as an AAX Developer [here](https://developer.avid.com/aax/). +2. Request a Pro Tools Developer Bundle activation code by sending an email to + [devauth@avid.com](mailto:devauth@avid.com). +3. Download the latest Pro Tools Developer build from your Avid Developer + account. -The JUCE examples are licensed under the terms of the -[ISC license](http://www.isc.org/downloads/software-support-policy/isc-license/). +When your plug-ins have been tested and debugged in Pro Tools Developer, and you +are ready to digitally sign them, please send an email to +[audiosdk@avid.com](mailto:audiosdk@avid.com) with the subject "PACE Eden +Signing Tools Request". You need to include an overview of each plug-in along +with a screen recording showing the plug-in running in Pro Tools Developer, with +audio if possible. -Dependencies in the examples: -- [reaper-sdk](examples/Plugins/extern/) ([zlib](examples/Plugins/extern/LICENSE.md)) +Please also include the following information: -Dependencies in the bundled applications: -- [Projucer icons](extras/Projucer/Source/Utility/UI/jucer_Icons.cpp) ([MIT](extras/Projucer/Source/Utility/UI/jucer_Icons.cpp)) +- Company name +- Admin full name +- Telephone number -Dependencies in the build system: -- [Android Gradle](examples/DemoRunner/Builds/Android/gradle/wrapper/LICENSE-for-gradlewrapper.txt) ([Apache 2.0](examples/DemoRunner/Builds/Android/gradle/wrapper/LICENSE-for-gradlewrapper.txt)) +Once the request is submitted, PACE Anti-Piracy will contact you directly with +information about signing your plug-ins. When the plug-ins have been signed, you +are free to sell and distribute them. If you are interested in selling your +plug-ins on the Avid Marketplace, please send an email to +[audiosdk@avid.com](mailto:audiosdk@avid.com). diff --git a/docs/CMake API.md b/docs/CMake API.md index 059c73ab7d..689357acf6 100644 --- a/docs/CMake API.md +++ b/docs/CMake API.md @@ -2,9 +2,8 @@ ## System Requirements -- All project types require CMake 3.15 or higher. +- All project types require CMake 3.22 or higher. - Android targets are not currently supported. -- WebView2 on Windows via JUCE_USE_WIN_WEBVIEW2 flag in juce_gui_extra is not currently supported. Most system package managers have packages for CMake, but we recommend using the most recent release from https://cmake.org/download. You should always use a CMake that's newer than your build @@ -144,11 +143,10 @@ you can configure a Clang-cl build by passing "-T ClangCL" on your configuration 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. CMake 3.12 is not supported, CMake 3.15 has -support, CMake 3.20 or higher is recommended. 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.15/prop_tgt/MSVC_RUNTIME_LIBRARY.html) of this +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 property for usage recommendations. ### A note about compile definitions @@ -169,10 +167,10 @@ appropriate: target_compile_definitions(my_target PUBLIC NAME_OF_KEY=) -The `JucePlugin_PreferredChannelConfig` preprocessor definition for plugins is difficult to specify -in a portable way due to its use of curly braces, which may be misinterpreted in Linux/Mac builds -using the Ninja/Makefile generators. It is recommended to avoid this option altogether, and to use -the newer buses API to specify the desired plugin inputs and outputs. +The `JucePlugin_PreferredChannelConfigurations` preprocessor definition for plugins is difficult to +specify in a portable way due to its use of curly braces, which may be misinterpreted in Linux/Mac +builds using the Ninja/Makefile generators. It is recommended to avoid this option altogether, and +to use the newer buses API to specify the desired plugin inputs and outputs. ## API Reference @@ -224,6 +222,24 @@ plugin folders may be protected, so the build may require elevated permissions i installation to work correctly, or you may need to adjust the permissions of the destination folders. +#### `JUCE_MODULES_ONLY` + +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 +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 +`%userprofile%\AppData\Local\PackageManagement\NuGet\Packages`. This location can be overriden by +specifying this option. The provided location should contain the `*Microsoft.Web.WebView2*` +directory. + ### Functions #### `juce_add_` @@ -266,7 +282,7 @@ attributes directly to these creation functions, rather than adding them later. `BUNDLE_ID` - 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 `PRODUCT_NAME`. + the target's `COMPANY_NAME` and the name of the CMake target. `MICROPHONE_PERMISSION_ENABLED` - May be either TRUE or FALSE. Adds the appropriate entries to an app's Info.plist. @@ -398,6 +414,11 @@ attributes directly to these creation functions, rather than adding them later. are set on a JUCE target. By default, we don't link Webkit because you might not need it, but if you get linker or include errors that reference Webkit, just set this argument to `TRUE`. +`NEEDS_WEBVIEW2` +- On Windows, JUCE may or may not need to link to WebView2 depending on the compile definitions that + are set on a JUCE target. By default, we don't link WebView2 because you might not need it, but + if you get linker or include errors that reference WebView2, just set this argument to `TRUE`. + `NEEDS_STORE_KIT` - On macOS, JUCE may or may not need to link to StoreKit depending on the compile definitions that are set on a JUCE target. By default, we don't link StoreKit because you might not need it, but @@ -445,6 +466,11 @@ attributes directly to these creation functions, rather than adding them later. - A set of space-separated paths that will be added to this target's entitlements plist for 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`. + For more information see Apple's IOKit User Client Class Temporary Exception documentation. + `PLIST_TO_MERGE` - A string to insert into an app/plugin's Info.plist. @@ -499,6 +525,17 @@ attributes directly to these creation functions, rather than adding them later. `AAX_IDENTIFIER` - The bundle ID for the AAX plugin target. Matches the `BUNDLE_ID` by default. +`LV2URI` +- 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 + 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. + `VST_NUM_MIDI_INS` - For VST2 and VST3 plugins that accept midi, this allows you to configure the number of inputs. @@ -507,7 +544,7 @@ attributes directly to these creation functions, rather than adding them later. `VST2_CATEGORY` - Should be one of: `kPlugCategUnknown`, `kPlugCategEffect`, `kPlugCategSynth`, - `kPlugCategAnalysis`, `kPlugCategMatering`, `kPlugCategSpacializer`, `kPlugCategRoomFx`, + `kPlugCategAnalysis`, `kPlugCategMastering`, `kPlugCategSpacializer`, `kPlugCategRoomFx`, `kPlugSurroundFx`, `kPlugCategRestoration`, `kPlugCategOfflineProcess`, `kPlugCategShell`, `kPlugCategGenerator`. @@ -540,13 +577,9 @@ attributes directly to these creation functions, rather than adding them later. in GarageBand. `AAX_CATEGORY` -- Should be one or more of: `AAX_ePlugInCategory_None`, `AAX_ePlugInCategory_EQ`, - `AAX_ePlugInCategory_Dynamics`, `AAX_ePlugInCategory_PitchShift`, `AAX_ePlugInCategory_Reverb`, - `AAX_ePlugInCategory_Delay`, `AAX_ePlugInCategory_Modulation`, `AAX_ePlugInCategory_Harmonic`, - `AAX_ePlugInCategory_NoiseReduction`, `AAX_ePlugInCategory_Dither`, - `AAX_ePlugInCategory_SoundField`, `AAX_ePlugInCategory_HWGenerators`, - `AAX_ePlugInCategory_SWGenerators`, `AAX_ePlugInCategory_WrappedPlugin`, - `AAX_EPlugInCategory_Effect` +- 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_`. `PLUGINHOST_AU` - May be either TRUE or FALSE (defaults to FALSE). If TRUE, will add the preprocessor definition @@ -635,6 +668,17 @@ attributes directly to these creation functions, rather than adding them later. `kARAPlaybackTransformationContentBasedFadeAtTail`, `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 + `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. + #### `juce_add_binary_data` juce_add_binary_data( @@ -695,6 +739,19 @@ If your custom build steps need to use the location of the plugin artefact, you by querying the property `JUCE_PLUGIN_ARTEFACT_FILE` on a plugin target (*not* the shared code target!). +#### `juce_enable_vst3_manifest_step` + + juce_enable_vst3_manifest_step() + +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. +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 +steps, and then finally call `juce_enable_vst3_manifest_step`. + #### `juce_set__sdk_path` juce_set_aax_sdk_path() @@ -738,8 +795,8 @@ CMakeLists in the `modules` directory. This function parses the PIP metadata block in the provided header, and adds appropriate build targets for a console app, GUI app, or audio plugin. For audio plugin targets, it builds as many -plugin formats as possible. To build AAX or VST2 targets, call `juce_set_aax_sdk_path` and/or -`juce_set_vst2_sdk_path` *before* calling `juce_add_pip`. +plugin formats as possible. To build VST2 targets, call `juce_set_vst2_sdk_path` *before* calling +`juce_add_pip`. This is mainly provided to build the built-in example projects in the JUCE repo, and for building quick proof-of-concept demo apps with minimal set-up. For any use-case more complex than a @@ -755,6 +812,21 @@ This function sets the `CMAKE__FLAGS_` to empty in the current direc allowing alternative optimisation/debug flags to be supplied without conflicting with the CMake-supplied defaults. +#### `juce_link_with_embedded_linux_subprocess` + + juce_link_with_embedded_linux_subprocess() + +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 +non-standalone format, and will be used to host a WebKit view. This technique is used by audio +plugins on Linux. + +This function is automatically called if necessary for all targets created by one of the JUCE target +creation functions i.e. `juce_add_gui_app`, `juce_add_console_app` and `juce_add_gui_app`. You don't +need to call this function manually in these cases. + ### Targets #### `juce::juce_recommended_warning_flags` diff --git a/docs/JUCE Module Format.md b/docs/JUCE Module Format.md index c114b302aa..447a3df774 100644 --- a/docs/JUCE Module Format.md +++ b/docs/JUCE Module Format.md @@ -65,28 +65,28 @@ adding these files to their projects. The names of these source files must begin with the name of the module, but they can have a number or other suffix if there is more than one. -In order to specify that a source file should only be compiled on a specific platform, -then the filename can be suffixed with one of the following strings: +In order to specify that a source file should only be compiled for a specific platform, +then the filename can be suffixed with one of the following (case insensitive) strings: - _OSX - _Windows - _Linux - _Android - _iOS + _mac or _osx <- compiled for macOS and OSX platforms only + _windows <- compiled for Windows platforms only + _linux <- compiled for Linux and FreeBSD platforms only + _andoid <- compiled for Android platforms only + _ios <- compiled for iOS platforms only e.g. - juce_mymodule/juce_mymodule_1.cpp <- compiled on all platforms - juce_mymodule/juce_mymodule_2.cpp <- compiled on all platforms - juce_mymodule/juce_mymodule_OSX.cpp <- compiled only on OSX - juce_mymodule/juce_mymodule_Windows.cpp <- compiled only on Windows + juce_mymodule/juce_mymodule_1.cpp <- compiled for all platforms + juce_mymodule/juce_mymodule_2.cpp <- compiled for all platforms + juce_mymodule/juce_mymodule_mac.cpp <- compiled for macOS and OSX platforms only + juce_mymodule/juce_mymodule_windows.cpp <- compiled for Windows platforms only Often this isn't necessary, as in most cases you can easily add checks inside the files to do different things depending on the platform, but this may be handy just to avoid clutter in user projects where files aren't needed. To simplify the use of obj-C++ there's also a special-case rule: If the folder contains -both a .mm and a .cpp file whose names are otherwise identical, then on OSX/iOS the .mm +both a .mm and a .cpp file whose names are otherwise identical, then on macOS/iOS the .mm will be used and the cpp ignored. (And vice-versa for other platforms, of course). @@ -95,8 +95,7 @@ will be used and the cpp ignored. (And vice-versa for other platforms, of course Precompiled libraries can be included in a module by placing them in a libs/ subdirectory. The following directories are automatically added to the library search paths, and libraries placed in these directories can be linked with projects via the OSXLibs, iOSLibs, -windowsLibs, linuxLibs and mingwLibs keywords in the module declaration (see the following -section). +windowsLibs, and linuxLibs keywords in the module declaration (see the following section). - OS X - libs/MacOSX - to support multiple architectures, you may place libraries built as universal @@ -115,9 +114,6 @@ section). - libs/Linux/{arch}, where {arch} is the architecture you are targeting with the compiler. Some common examples of {arch} are "x86_64", "i386" and "armv6". -- MinGW - - libs/MinGW/{arch}, where {arch} can take the same values as Linux. - - iOS - libs/iOS - to support multiple architectures, you may place libraries built as universal binaries at this location. For backwards compatibility, the Projucer will also include the @@ -206,10 +202,6 @@ Possible values: - (Optional) A list (space or comma-separated) of static or dynamic libs that should be linked in a linux build (these are passed to the linker via the -l flag) -- mingwLibs - - (Optional) A list (space or comma-separated) of static libs that should be linked in a - win32 mingw build (these are passed to the linker via the -l flag) - - OSXLibs - (Optional) A list (space or comma-separated) of static or dynamic libs that should be linked in an OS X build (these are passed to the linker via the -l flag) @@ -232,13 +224,12 @@ Here's an example block: name: JUCE audio and MIDI I/O device classes description: Classes to play and record from audio and MIDI I/O devices website: http://www.juce.com/juce - license: GPL/Commercial + license: AGPLv3/Commercial dependencies: juce_audio_basics, juce_audio_formats, juce_events OSXFrameworks: CoreAudio CoreMIDI DiscRecording iOSFrameworks: CoreAudio CoreMIDI AudioToolbox AVFoundation linuxLibs: asound - mingwLibs: winmm END_JUCE_MODULE_DECLARATION diff --git a/docs/Linux Dependencies.md b/docs/Linux Dependencies.md index 3dc1502c95..2ef02f869a 100644 --- a/docs/Linux Dependencies.md +++ b/docs/Linux Dependencies.md @@ -32,7 +32,11 @@ or - libcurl4-openssl-dev (unless `JUCE_USE_CURL=0`) #### juce_graphics -- libfreetype6-dev (unless `JUCE_USE_FREETYPE=0`) +- libfontconfig1-dev (unless `JUCE_USE_FONTCONFIG=0`) +- libfreetype-dev (unless `JUCE_USE_FREETYPE=0`) + +These packages are available on Ubuntu 22 and 24. If libfreetype-dev is not +available you could try installing the libfreetype6-dev package. #### juce_gui_basics - libx11-dev @@ -44,7 +48,14 @@ or - libxrender-dev (unless `JUCE_USE_XRENDER=0`) #### juce_gui_extra -- libwebkit2gtk-4.0-dev (unless `JUCE_WEB_BROWSER=0`) +- libwebkit2gtk-4.1-dev (unless `JUCE_WEB_BROWSER=0`) + +On older systems, where 4.1 is not available, you can also use + +- libwebkit2gtk-4.0-dev + +Compiled JUCE applications will dynamically load whichever library version is +available during runtime. #### juce_opengl - libglu1-mesa-dev @@ -56,7 +67,7 @@ The full command is as follows: sudo apt install libasound2-dev libjack-jackd2-dev \ ladspa-sdk \ libcurl4-openssl-dev \ - libfreetype6-dev \ - libx11-dev libxcomposite-dev libxcursor-dev libxcursor-dev libxext-dev libxinerama-dev libxrandr-dev libxrender-dev \ - libwebkit2gtk-4.0-dev \ + libfreetype-dev libfontconfig1-dev \ + libx11-dev libxcomposite-dev libxcursor-dev libxext-dev libxinerama-dev libxrandr-dev libxrender-dev \ + libwebkit2gtk-4.1-dev \ libglu1-mesa-dev mesa-common-dev diff --git a/docs/doxygen/Doxyfile b/docs/doxygen/Doxyfile index bd662d2577..13de46435d 100644 --- a/docs/doxygen/Doxyfile +++ b/docs/doxygen/Doxyfile @@ -1,4 +1,4 @@ -# Doxyfile 1.8.12 +# Doxyfile 1.9.8 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. @@ -12,16 +12,26 @@ # For lists, items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (\" \"). +# +# Note: +# +# Use doxygen to compare the used configuration file with the template +# configuration file: +# doxygen -x [configFile] +# Use doxygen to compare the used configuration file with the template +# configuration file without replacing the environment variables or CMake type +# replacement variables: +# doxygen -x_noenv [configFile] #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all text -# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv -# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv -# for the list of possible encodings. +# This tag specifies the encoding used for all characters in the configuration +# file that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# https://www.gnu.org/software/libiconv/ for the list of possible encodings. # The default value is: UTF-8. DOXYFILE_ENCODING = UTF-8 @@ -60,16 +70,28 @@ PROJECT_LOGO = OUTPUT_DIRECTORY = -# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- -# directories (in 2 levels) under the output directory of each output format and -# will distribute the generated files over these directories. Enabling this +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create up to 4096 +# sub-directories (in 2 levels) under the output directory of each output format +# and will distribute the generated files over these directories. Enabling this # option can be useful when feeding doxygen a huge amount of source files, where # putting all generated files in the same directory would otherwise causes -# performance problems for the file system. +# performance problems for the file system. Adapt CREATE_SUBDIRS_LEVEL to +# control the number of sub-directories. # The default value is: NO. CREATE_SUBDIRS = NO +# Controls the number of sub-directories that will be created when +# CREATE_SUBDIRS tag is set to YES. Level 0 represents 16 directories, and every +# level increment doubles the number of directories, resulting in 4096 +# directories at level 8 which is the default and also the maximum value. The +# sub-directories are organized in 2 levels, the first level always has a fixed +# number of 16 directories. +# Minimum value: 0, maximum value: 8, default value: 8. +# This tag requires that the tag CREATE_SUBDIRS is set to YES. + +CREATE_SUBDIRS_LEVEL = 8 + # If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII # characters to appear in the names of generated files. If set to NO, non-ASCII # characters will be escaped, for example _xE3_x81_x84 will be used for Unicode @@ -81,14 +103,14 @@ ALLOW_UNICODE_NAMES = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. -# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, -# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), -# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, -# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), -# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, -# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, -# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, -# Ukrainian and Vietnamese. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Bulgarian, +# Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, English +# (United States), Esperanto, Farsi (Persian), Finnish, French, German, Greek, +# Hindi, Hungarian, Indonesian, Italian, Japanese, Japanese-en (Japanese with +# English messages), Korean, Korean-en (Korean with English messages), Latvian, +# Lithuanian, Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, +# Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, +# Swedish, Turkish, Ukrainian and Vietnamese. # The default value is: English. OUTPUT_LANGUAGE = English @@ -179,6 +201,16 @@ SHORT_NAMES = NO JAVADOC_AUTOBRIEF = YES +# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line +# such as +# /*************** +# as being the beginning of a Javadoc-style comment "banner". If set to NO, the +# Javadoc-style will behave just like regular comments and it will not be +# interpreted by doxygen. +# The default value is: NO. + +JAVADOC_BANNER = NO + # If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first # line (until the first dot) of a Qt-style comment as the brief description. If # set to NO, the Qt-style will behave just like regular Qt-style comments (thus @@ -199,6 +231,14 @@ QT_AUTOBRIEF = NO MULTILINE_CPP_IS_BRIEF = NO +# By default Python docstrings are displayed as preformatted text and doxygen's +# special commands cannot be used. By setting PYTHON_DOCSTRING to NO the +# doxygen's special commands can be used and the contents of the docstring +# documentation blocks is shown as doxygen documentation. +# The default value is: YES. + +PYTHON_DOCSTRING = YES + # If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the # documentation from any documented member that it re-implements. # The default value is: YES. @@ -222,11 +262,16 @@ TAB_SIZE = 4 # the documentation. An alias has the form: # name=value # For example adding -# "sideeffect=@par Side Effects:\n" +# "sideeffect=@par Side Effects:^^" # will allow you to put the command \sideeffect (or @sideeffect) in the # documentation, which will result in a user-defined paragraph with heading -# "Side Effects:". You can put \n's in the value part of an alias to insert -# newlines. +# "Side Effects:". Note that you cannot put \n's in the value part of an alias +# to insert newlines (in the resulting output). You can put ^^ in the value part +# of an alias to insert a newline as if a physical newline was in the original +# file. When you need a literal { or } or , in the value part of an alias you +# have to escape them by means of a backslash (\), this can lead to conflicts +# with the commands \{ and \} for these it is advised to use the version @{ and +# @} or use a double escape (\\{ and \\}) ALIASES = "tags{1}=" \ "topictag{1}=\1" \ @@ -251,12 +296,6 @@ ALIASES = "tags{1}=" \ "c_new=@s_code{new}" \ "c_typedef=@s_code{typedef}" -# This tag can be used to specify a number of word-keyword mappings (TCL only). -# A mapping has the form "name=value". For example adding "class=itcl::class" -# will allow you to use the command class in the itcl::class meaning. - -TCL_SUBST = - # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources # only. Doxygen will then generate output that is more tailored for C. For # instance, some of the names that are used will be different. The list of all @@ -285,28 +324,40 @@ OPTIMIZE_FOR_FORTRAN = NO OPTIMIZE_OUTPUT_VHDL = NO +# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice +# sources only. Doxygen will then generate output that is more tailored for that +# language. For instance, namespaces will be presented as modules, types will be +# separated into more groups, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_SLICE = NO + # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, and -# language is one of the parsers supported by doxygen: IDL, Java, Javascript, -# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: -# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: -# Fortran. In the later case the parser tries to guess whether the code is fixed -# or free formatted code, this is the default for Fortran type files), VHDL. For -# instance to make doxygen treat .inc files as Fortran files (default is PHP), -# and .f files as C (default is Fortran), use: inc=Fortran f=C. +# language is one of the parsers supported by doxygen: IDL, Java, JavaScript, +# Csharp (C#), C, C++, Lex, D, PHP, md (Markdown), Objective-C, Python, Slice, +# VHDL, Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: +# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser +# tries to guess whether the code is fixed or free formatted code, this is the +# default for Fortran type files). For instance to make doxygen treat .inc files +# as Fortran files (default is PHP), and .f files as C (default is Fortran), +# use: inc=Fortran f=C. # # Note: For files without extension you can use no_extension as a placeholder. # # Note that for custom extensions you also need to set FILE_PATTERNS otherwise -# the files are not read by doxygen. +# the files are not read by doxygen. When specifying no_extension you should add +# * to the FILE_PATTERNS. +# +# Note see also the list of default file extension mappings. EXTENSION_MAPPING = txt=md # If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments # according to the Markdown format, which allows for more readable -# documentation. See http://daringfireball.net/projects/markdown/ for details. +# documentation. See https://daringfireball.net/projects/markdown/ for details. # The output of markdown processing is further processed by doxygen, so you can # mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in # case of backward compatibilities issues. @@ -318,11 +369,22 @@ MARKDOWN_SUPPORT = YES # to that level are automatically included in the table of contents, even if # they do not have an id attribute. # Note: This feature currently applies only to Markdown headings. -# Minimum value: 0, maximum value: 99, default value: 0. +# Minimum value: 0, maximum value: 99, default value: 5. # This tag requires that the tag MARKDOWN_SUPPORT is set to YES. TOC_INCLUDE_HEADINGS = 0 +# The MARKDOWN_ID_STYLE tag can be used to specify the algorithm used to +# generate identifiers for the Markdown headings. Note: Every identifier is +# unique. +# Possible values are: DOXYGEN use a fixed 'autotoc_md' string followed by a +# sequence number starting at 0 and GITHUB use the lower case version of title +# with any whitespace replaced by '-' and punctuation characters removed. +# The default value is: DOXYGEN. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +MARKDOWN_ID_STYLE = DOXYGEN + # When enabled doxygen tries to link words that correspond to documented # classes, or namespaces to their corresponding documentation. Such a link can # be prevented in individual cases by putting a % sign in front of the word or @@ -348,7 +410,7 @@ BUILTIN_STL_SUPPORT = YES CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip (see: -# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen +# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen # will parse them like normal C++ but will assume all classes use public instead # of private inheritance when no explicit protection keyword is present. # The default value is: NO. @@ -434,6 +496,27 @@ TYPEDEF_HIDES_STRUCT = NO LOOKUP_CACHE_SIZE = 0 +# The NUM_PROC_THREADS specifies the number of threads doxygen is allowed to use +# during processing. When set to 0 doxygen will based this on the number of +# cores available in the system. You can set it explicitly to a value larger +# than 0 to get more control over the balance between CPU load and processing +# speed. At this moment only the input processing can be done using multiple +# threads. Since this is still an experimental feature the default is set to 1, +# which effectively disables parallel processing. Please report any issues you +# encounter. Generating dot graphs in parallel is controlled by the +# DOT_NUM_THREADS setting. +# Minimum value: 0, maximum value: 32, default value: 1. + +NUM_PROC_THREADS = 1 + +# If the TIMESTAMP tag is set different from NO then each generated page will +# contain the date or date and time when the page was generated. Setting this to +# NO can help when comparing the output of multiple runs. +# Possible values are: YES, NO, DATETIME and DATE. +# The default value is: NO. + +TIMESTAMP = NO + #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- @@ -454,6 +537,12 @@ EXTRACT_ALL = YES EXTRACT_PRIVATE = NO +# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual +# methods of a class will be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIV_VIRTUAL = NO + # If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal # scope will be included in the documentation. # The default value is: NO. @@ -491,6 +580,13 @@ EXTRACT_LOCAL_METHODS = NO EXTRACT_ANON_NSPACES = NO +# If this flag is set to YES, the name of an unnamed parameter in a declaration +# will be determined by the corresponding definition. By default unnamed +# parameters remain unnamed in the output. +# The default value is: YES. + +RESOLVE_UNNAMED_PARAMS = YES + # If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all # undocumented members inside documented classes or files. If set to NO these # members will be included in the various overviews, but no documentation @@ -502,14 +598,15 @@ HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. If set # to NO, these classes will be included in the various overviews. This option -# has no effect if EXTRACT_ALL is enabled. +# will also hide undocumented C++ concepts if enabled. This option has no effect +# if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_CLASSES = YES # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend -# (class|struct|union) declarations. If set to NO, these declarations will be -# included in the documentation. +# declarations. If set to NO, these declarations will be included in the +# documentation. # The default value is: NO. HIDE_FRIEND_COMPOUNDS = YES @@ -526,14 +623,22 @@ HIDE_IN_BODY_DOCS = YES # will be excluded. Set it to YES to include the internal documentation. # The default value is: NO. -INTERNAL_DOCS = YES +INTERNAL_DOCS = NO -# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file -# names in lower-case letters. If set to YES, upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. -# The default value is: system dependent. +# With the correct setting of option CASE_SENSE_NAMES doxygen will better be +# able to match the capabilities of the underlying filesystem. In case the +# filesystem is case sensitive (i.e. it supports files in the same directory +# whose names only differ in casing), the option must be set to YES to properly +# deal with such files in case they appear in the input. For filesystems that +# are not case sensitive the option should be set to NO to properly deal with +# output files written for symbols that only differ in casing, such as for two +# classes, one named CLASS and the other named Class, and to also support +# references to files without having to specify the exact matching casing. On +# Windows (including Cygwin) and MacOS, users should typically set this option +# to NO, whereas on Linux or other Unix flavors it should typically be set to +# YES. +# Possible values are: SYSTEM, NO and YES. +# The default value is: SYSTEM. CASE_SENSE_NAMES = YES @@ -551,6 +656,12 @@ HIDE_SCOPE_NAMES = NO HIDE_COMPOUND_REFERENCE= NO +# If the SHOW_HEADERFILE tag is set to YES then the documentation for a class +# will show which file needs to be included to use the class. +# The default value is: YES. + +SHOW_HEADERFILE = YES + # If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of # the files that are included by a file in the documentation of that file. # The default value is: YES. @@ -708,7 +819,8 @@ FILE_VERSION_FILTER = # output files in an output format independent way. To create the layout file # that represents doxygen's defaults, run doxygen with the -l option. You can # optionally specify a file name after the option, if omitted DoxygenLayout.xml -# will be used as the name of the layout file. +# will be used as the name of the layout file. See also section "Changing the +# layout of pages" for information. # # Note that if you run doxygen from a directory containing a file called # DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE @@ -719,7 +831,7 @@ LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files containing # the reference definitions. This must be a list of .bib files. The .bib # extension is automatically appended if omitted. This requires the bibtex tool -# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. +# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. # For LaTeX the style of the bibliography can be controlled using # LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the # search path. See also \cite for info how to create references. @@ -754,23 +866,50 @@ WARNINGS = YES WARN_IF_UNDOCUMENTED = YES # If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some parameters -# in a documented function, or documenting parameters that don't exist or using -# markup commands wrongly. +# potential errors in the documentation, such as documenting some parameters in +# a documented function twice, or documenting parameters that don't exist or +# using markup commands wrongly. # The default value is: YES. WARN_IF_DOC_ERROR = YES +# If WARN_IF_INCOMPLETE_DOC is set to YES, doxygen will warn about incomplete +# function parameter documentation. If set to NO, doxygen will accept that some +# parameters have no documentation without warning. +# The default value is: YES. + +WARN_IF_INCOMPLETE_DOC = YES + # This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that # are documented, but have no documentation for their parameters or return -# value. If set to NO, doxygen will only warn about wrong or incomplete -# parameter documentation, but not about the absence of documentation. +# value. If set to NO, doxygen will only warn about wrong parameter +# documentation, but not about the absence of documentation. If EXTRACT_ALL is +# set to YES then this flag will automatically be disabled. See also +# WARN_IF_INCOMPLETE_DOC # The default value is: NO. WARN_NO_PARAMDOC = NO +# If WARN_IF_UNDOC_ENUM_VAL option is set to YES, doxygen will warn about +# undocumented enumeration values. If set to NO, doxygen will accept +# undocumented enumeration values. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: NO. + +WARN_IF_UNDOC_ENUM_VAL = NO + # If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when -# a warning is encountered. +# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS +# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but +# at the end of the doxygen process doxygen will return with a non-zero status. +# If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS_PRINT then doxygen behaves +# like FAIL_ON_WARNINGS but in case no WARN_LOGFILE is defined doxygen will not +# write the warning messages in between other messages but write them at the end +# of a run, in case a WARN_LOGFILE is defined the warning messages will be +# besides being in the defined file also be shown at the end of a run, unless +# the WARN_LOGFILE is defined as - i.e. standard output (stdout) in that case +# the behavior will remain as with the setting FAIL_ON_WARNINGS. +# Possible values are: NO, YES, FAIL_ON_WARNINGS and FAIL_ON_WARNINGS_PRINT. # The default value is: NO. WARN_AS_ERROR = NO @@ -781,13 +920,27 @@ WARN_AS_ERROR = NO # and the warning text. Optionally the format may contain $version, which will # be replaced by the version of the file (if it could be obtained via # FILE_VERSION_FILTER) +# See also: WARN_LINE_FORMAT # The default value is: $file:$line: $text. WARN_FORMAT = "$file:$line: $text" +# In the $text part of the WARN_FORMAT command it is possible that a reference +# to a more specific place is given. To make it easier to jump to this place +# (outside of doxygen) the user can define a custom "cut" / "paste" string. +# Example: +# WARN_LINE_FORMAT = "'vi $file +$line'" +# See also: WARN_FORMAT +# The default value is: at line $line of file $file. + +WARN_LINE_FORMAT = "at line $line of file $file" + # The WARN_LOGFILE tag can be used to specify a file to which warning and error # messages should be written. If left blank the output is written to standard -# error (stderr). +# error (stderr). In case the file specified cannot be opened for writing the +# warning and error messages are written to standard error. When as file - is +# specified the warning and error messages are written to standard output +# (stdout). WARN_LOGFILE = @@ -808,12 +961,23 @@ INPUT = build \ # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses # libiconv (or the iconv built into libc) for the transcoding. See the libiconv -# documentation (see: http://www.gnu.org/software/libiconv) for the list of -# possible encodings. +# documentation (see: +# https://www.gnu.org/software/libiconv/) for the list of possible encodings. +# See also: INPUT_FILE_ENCODING # The default value is: UTF-8. INPUT_ENCODING = UTF-8 +# This tag can be used to specify the character encoding of the source files +# that doxygen parses The INPUT_FILE_ENCODING tag can be used to specify +# character encoding on a per file pattern basis. Doxygen will compare the file +# name with each pattern and apply the encoding instead of the default +# INPUT_ENCODING) if there is a match. The character encodings are a list of the +# form: pattern=encoding (like *.php=ISO-8859-1). See cfg_input_encoding +# "INPUT_ENCODING" for further information on supported encodings. + +INPUT_FILE_ENCODING = + # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and # *.h) to filter out the source-files in the directories. @@ -822,11 +986,15 @@ INPUT_ENCODING = UTF-8 # need to set EXTENSION_MAPPING for the extension otherwise the files are not # read by doxygen. # +# Note the list of default checked file patterns might differ from the list of +# default file extension mappings. +# # If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, # *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, -# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, -# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, -# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf. +# *.hh, *.hxx, *.hpp, *.h++, *.l, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, +# *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C +# comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, +# *.vhdl, *.ucf, *.qsf and *.ice. FILE_PATTERNS = juce_*.h \ juce_*.dox @@ -883,12 +1051,9 @@ EXCLUDE_PATTERNS = juce_GIFLoader* \ # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories use the pattern */test/* +# ANamespace::AClass, ANamespace::*Test -EXCLUDE_SYMBOLS = +EXCLUDE_SYMBOLS = detail # The EXAMPLE_PATH tag can be used to specify one or more files or directories # that contain example code fragments that are included (see the \include @@ -931,6 +1096,11 @@ IMAGE_PATH = # code is scanned, but not when the output code is generated. If lines are added # or removed, the anchors will not be placed correctly. # +# Note that doxygen will use the data processed and written to standard output +# for further processing, therefore nothing else, like debug statements or used +# commands (so in case of a Windows batch file always use @echo OFF), should be +# written to standard output. +# # Note that for custom extensions or not directly supported extensions you also # need to set EXTENSION_MAPPING for the extension otherwise the files are not # properly processed by doxygen. @@ -972,6 +1142,15 @@ FILTER_SOURCE_PATTERNS = USE_MDFILE_AS_MAINPAGE = +# The Fortran standard specifies that for fixed formatted Fortran code all +# characters from position 72 are to be considered as comment. A common +# extension is to allow longer lines before the automatic comment starts. The +# setting FORTRAN_COMMENT_AFTER will also make it possible that longer lines can +# be processed before the automatic comment starts. +# Minimum value: 7, maximum value: 10000, default value: 72. + +FORTRAN_COMMENT_AFTER = 72 + #--------------------------------------------------------------------------- # Configuration options related to source browsing #--------------------------------------------------------------------------- @@ -999,7 +1178,7 @@ INLINE_SOURCES = NO STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES then for each documented -# function all documented functions referencing it will be listed. +# entity all documented functions referencing it will be listed. # The default value is: NO. REFERENCED_BY_RELATION = YES @@ -1031,12 +1210,12 @@ SOURCE_TOOLTIPS = YES # If the USE_HTAGS tag is set to YES then the references to source code will # point to the HTML generated by the htags(1) tool instead of doxygen built-in # source browser. The htags tool is part of GNU's global source tagging system -# (see http://www.gnu.org/software/global/global.html). You will need version +# (see https://www.gnu.org/software/global/global.html). You will need version # 4.8.6 or higher. # # To use it do the following: # - Install the latest version of global -# - Enable SOURCE_BROWSER and USE_HTAGS in the config file +# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file # - Make sure the INPUT points to the root of the source tree # - Run doxygen as normal # @@ -1069,17 +1248,11 @@ VERBATIM_HEADERS = NO ALPHABETICAL_INDEX = YES -# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in -# which the alphabetical index list will be split. -# Minimum value: 1, maximum value: 20, default value: 5. -# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. - -COLS_IN_ALPHA_INDEX = 3 - -# In case all classes in a project start with a common prefix, all classes will -# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag -# can be used to specify a prefix (or a list of prefixes) that should be ignored -# while generating the index headers. +# The IGNORE_PREFIX tag can be used to specify a prefix (or a list of prefixes) +# that should be ignored while generating the index headers. The IGNORE_PREFIX +# tag works for classes, function and member names. The entity will be placed in +# the alphabetical list under the first letter of the entity name that remains +# after removing the prefix. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. IGNORE_PREFIX = @@ -1158,7 +1331,12 @@ HTML_STYLESHEET = # Doxygen will copy the style sheet files to the output directory. # Note: The order of the extra style sheet files is of importance (e.g. the last # style sheet in the list overrules the setting of the previous ones in the -# list). For an example see the documentation. +# list). +# Note: Since the styling of scrollbars can currently not be overruled in +# Webkit/Chromium, the styling will be left out of the default doxygen.css if +# one or more extra stylesheets have been specified. So if scrollbar +# customization is desired it has to be added explicitly. For an example see the +# documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_STYLESHEET = @@ -1173,10 +1351,23 @@ HTML_EXTRA_STYLESHEET = HTML_EXTRA_FILES = +# The HTML_COLORSTYLE tag can be used to specify if the generated HTML output +# should be rendered with a dark or light theme. +# Possible values are: LIGHT always generate light mode output, DARK always +# generate dark mode output, AUTO_LIGHT automatically set the mode according to +# the user preference, use light mode if no preference is set (the default), +# AUTO_DARK automatically set the mode according to the user preference, use +# dark mode if no preference is set and TOGGLE allow to user to switch between +# light and dark mode via a button. +# The default value is: AUTO_LIGHT. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE = AUTO_LIGHT + # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen # will adjust the colors in the style sheet and background images according to -# this color. Hue is specified as an angle on a colorwheel, see -# http://en.wikipedia.org/wiki/Hue for more information. For instance the value +# this color. Hue is specified as an angle on a color-wheel, see +# https://en.wikipedia.org/wiki/Hue for more information. For instance the value # 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 # purple, and 360 is red again. # Minimum value: 0, maximum value: 359, default value: 220. @@ -1185,7 +1376,7 @@ HTML_EXTRA_FILES = HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors -# in the HTML output. For a value of 0 the output will use grayscales only. A +# in the HTML output. For a value of 0 the output will use gray-scales only. A # value of 255 will produce the most vivid colors. # Minimum value: 0, maximum value: 255, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. @@ -1203,14 +1394,16 @@ HTML_COLORSTYLE_SAT = 100 HTML_COLORSTYLE_GAMMA = 80 -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting this -# to YES can help to show when doxygen was last run and thus if the -# documentation is up to date. -# The default value is: NO. +# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML +# documentation will contain a main index with vertical navigation menus that +# are dynamically created via JavaScript. If disabled, the navigation index will +# consists of multiple levels of tabs that are statically embedded in every HTML +# page. Disable this option to support browsers that do not have JavaScript, +# like the Qt help browser. +# The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_TIMESTAMP = YES +HTML_DYNAMIC_MENUS = NO # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the @@ -1220,6 +1413,14 @@ HTML_TIMESTAMP = YES HTML_DYNAMIC_SECTIONS = NO +# If the HTML_CODE_FOLDING and SOURCE_BROWSER tags are set to YES then classes +# and functions can be dynamically folded and expanded in the generated HTML +# source code. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_CODE_FOLDING = YES + # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries # shown in the various tree structured indices initially; the user can expand # and collapse entries dynamically later on. Doxygen will expand the tree to @@ -1235,13 +1436,14 @@ HTML_INDEX_NUM_ENTRIES = 32 # If the GENERATE_DOCSET tag is set to YES, additional index files will be # generated that can be used as input for Apple's Xcode 3 integrated development -# environment (see: http://developer.apple.com/tools/xcode/), introduced with -# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a -# Makefile in the HTML output directory. Running make will produce the docset in -# that directory and running make install will install the docset in +# environment (see: +# https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To +# create a documentation set, doxygen will generate a Makefile in the HTML +# output directory. Running make will produce the docset in that directory and +# running make install will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at -# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html -# for more information. +# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy +# genXcode/_index.html for more information. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. @@ -1255,6 +1457,13 @@ GENERATE_DOCSET = NO DOCSET_FEEDNAME = "Doxygen generated docs" +# This tag determines the URL of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDURL = + # This tag specifies a string that should uniquely identify the documentation # set bundle. This should be a reverse domain-name style string, e.g. # com.mycompany.MyDocSet. Doxygen will append .docset to the name. @@ -1280,8 +1489,12 @@ DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three # additional HTML index files: index.hhp, index.hhc, and index.hhk. The # index.hhp is a project file that can be read by Microsoft's HTML Help Workshop -# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on -# Windows. +# on Windows. In the beginning of 2021 Microsoft took the original page, with +# a.o. the download links, offline the HTML help workshop was already many years +# in maintenance mode). You can download the HTML help workshop from the web +# archives at Installation executable (see: +# http://web.archive.org/web/20160201063255/http://download.microsoft.com/downlo +# ad/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe). # # The HTML Help Workshop contains a compiler that can convert all HTML output # generated by doxygen into a single compiled HTML file (.chm). Compiled HTML @@ -1311,7 +1524,7 @@ CHM_FILE = HHC_LOCATION = # The GENERATE_CHI flag controls if a separate .chi index file is generated -# (YES) or that it should be included in the master .chm file (NO). +# (YES) or that it should be included in the main .chm file (NO). # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. @@ -1338,6 +1551,16 @@ BINARY_TOC = NO TOC_EXPAND = NO +# The SITEMAP_URL tag is used to specify the full URL of the place where the +# generated documentation will be placed on the server by the user during the +# deployment of the documentation. The generated sitemap is called sitemap.xml +# and placed on the directory specified by HTML_OUTPUT. In case no SITEMAP_URL +# is specified no sitemap is generated. For information about the sitemap +# protocol see https://www.sitemaps.org +# This tag requires that the tag GENERATE_HTML is set to YES. + +SITEMAP_URL = + # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that # can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help @@ -1356,7 +1579,8 @@ QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help # Project output. For more information please see Qt Help Project / Namespace -# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). +# (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_QHP is set to YES. @@ -1364,8 +1588,8 @@ QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt # Help Project output. For more information please see Qt Help Project / Virtual -# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- -# folders). +# Folders (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders). # The default value is: doc. # This tag requires that the tag GENERATE_QHP is set to YES. @@ -1373,30 +1597,30 @@ QHP_VIRTUAL_FOLDER = doc # If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom # filter to add. For more information please see Qt Help Project / Custom -# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- -# filters). +# Filters (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_NAME = # The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see Qt Help Project / Custom -# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- -# filters). +# Filters (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's filter section matches. Qt Help Project / Filter Attributes (see: -# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_SECT_FILTER_ATTRS = -# The QHG_LOCATION tag can be used to specify the location of Qt's -# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the -# generated .qhp file. +# The QHG_LOCATION tag can be used to specify the location (absolute path +# including file name) of Qt's qhelpgenerator. If non-empty doxygen will try to +# run qhelpgenerator on the generated .qhp file. # This tag requires that the tag GENERATE_QHP is set to YES. QHG_LOCATION = @@ -1439,16 +1663,28 @@ DISABLE_INDEX = NO # to work a browser that supports JavaScript, DHTML, CSS and frames is required # (i.e. any modern browser). Windows users are probably better off using the # HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can -# further fine-tune the look of the index. As an example, the default style -# sheet generated by doxygen has an example that shows how to put an image at -# the root of the tree instead of the PROJECT_NAME. Since the tree basically has -# the same information as the tab index, you could consider setting -# DISABLE_INDEX to YES when enabling this option. +# further fine tune the look of the index (see "Fine-tuning the output"). As an +# example, the default style sheet generated by doxygen has an example that +# shows how to put an image at the root of the tree instead of the PROJECT_NAME. +# Since the tree basically has the same information as the tab index, you could +# consider setting DISABLE_INDEX to YES when enabling this option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_TREEVIEW = NO +# When both GENERATE_TREEVIEW and DISABLE_INDEX are set to YES, then the +# FULL_SIDEBAR option determines if the side bar is limited to only the treeview +# area (value NO) or if it should extend to the full height of the window (value +# YES). Setting this to YES gives a layout similar to +# https://docs.readthedocs.io with more room for contents, but less room for the +# project logo, title, and description. If either GENERATE_TREEVIEW or +# DISABLE_INDEX is set to NO, this option has no effect. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FULL_SIDEBAR = NO + # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that # doxygen will group on one line in the generated HTML documentation. # @@ -1473,6 +1709,24 @@ TREEVIEW_WIDTH = 320 EXT_LINKS_IN_WINDOW = NO +# If the OBFUSCATE_EMAILS tag is set to YES, doxygen will obfuscate email +# addresses. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +OBFUSCATE_EMAILS = YES + +# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg +# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see +# https://inkscape.org) to generate formulas as SVG images instead of PNGs for +# the HTML output. These images will generally look nicer at scaled resolutions. +# Possible values are: png (the default) and svg (looks nicer but requires the +# pdf2svg or inkscape tool). +# The default value is: png. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FORMULA_FORMAT = png + # Use this tag to change the font size of LaTeX formulas included as images in # the HTML documentation. When you change the font size after a successful # doxygen run you need to manually remove any form_*.png images from the HTML @@ -1482,19 +1736,14 @@ EXT_LINKS_IN_WINDOW = NO FORMULA_FONTSIZE = 10 -# Use the FORMULA_TRANPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are not -# supported properly for IE 6.0, but are supported on all modern browsers. -# -# Note that when changing this option you need to delete any form_*.png files in -# the HTML output directory before the changes have effect. -# The default value is: YES. -# This tag requires that the tag GENERATE_HTML is set to YES. +# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands +# to create new LaTeX commands to be used in formulas as building blocks. See +# the section "Including formulas" for details. -FORMULA_TRANSPARENT = YES +FORMULA_MACROFILE = # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see -# http://www.mathjax.org) which uses client side Javascript for the rendering +# https://www.mathjax.org) which uses client side JavaScript for the rendering # instead of using pre-rendered bitmaps. Use this if you do not have LaTeX # installed or if you want to formulas look prettier in the HTML output. When # enabled you may also need to install MathJax separately and configure the path @@ -1504,11 +1753,29 @@ FORMULA_TRANSPARENT = YES USE_MATHJAX = NO +# With MATHJAX_VERSION it is possible to specify the MathJax version to be used. +# Note that the different versions of MathJax have different requirements with +# regards to the different settings, so it is possible that also other MathJax +# settings have to be changed when switching between the different MathJax +# versions. +# Possible values are: MathJax_2 and MathJax_3. +# The default value is: MathJax_2. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_VERSION = MathJax_2 + # When MathJax is enabled you can set the default output format to be used for -# the MathJax output. See the MathJax site (see: -# http://docs.mathjax.org/en/latest/output.html) for more details. +# the MathJax output. For more details about the output format see MathJax +# version 2 (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) and MathJax version 3 +# (see: +# http://docs.mathjax.org/en/latest/web/components/output.html). # Possible values are: HTML-CSS (which is slower, but has the best -# compatibility), NativeMML (i.e. MathML) and SVG. +# compatibility. This is the name for Mathjax version 2, for MathJax version 3 +# this will be translated into chtml), NativeMML (i.e. MathML. Only supported +# for NathJax 2. For MathJax version 3 chtml will be used instead.), chtml (This +# is the name for Mathjax version 3, for MathJax version 2 this will be +# translated into HTML-CSS) and SVG. # The default value is: HTML-CSS. # This tag requires that the tag USE_MATHJAX is set to YES. @@ -1521,22 +1788,29 @@ MATHJAX_FORMAT = HTML-CSS # MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax # Content Delivery Network so you can quickly see the result without installing # MathJax. However, it is strongly recommended to install a local copy of -# MathJax from http://www.mathjax.org before deployment. -# The default value is: http://cdn.mathjax.org/mathjax/latest. +# MathJax from https://www.mathjax.org before deployment. The default value is: +# - in case of MathJax version 2: https://cdn.jsdelivr.net/npm/mathjax@2 +# - in case of MathJax version 3: https://cdn.jsdelivr.net/npm/mathjax@3 # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_RELPATH = http://www.mathjax.org/mathjax # The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax # extension names that should be enabled during MathJax rendering. For example +# for MathJax version 2 (see +# https://docs.mathjax.org/en/v2.7-latest/tex.html#tex-and-latex-extensions): # MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# For example for MathJax version 3 (see +# http://docs.mathjax.org/en/latest/input/tex/extensions/index.html): +# MATHJAX_EXTENSIONS = ams # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_EXTENSIONS = # The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces # of code that will be used on startup of the MathJax code. See the MathJax site -# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an # example see the documentation. # This tag requires that the tag USE_MATHJAX is set to YES. @@ -1564,7 +1838,7 @@ MATHJAX_CODEFILE = SEARCHENGINE = YES # When the SERVER_BASED_SEARCH tag is enabled the search engine will be -# implemented using a web server instead of a web client using Javascript. There +# implemented using a web server instead of a web client using JavaScript. There # are two flavors of web server based searching depending on the EXTERNAL_SEARCH # setting. When disabled, doxygen will generate a PHP script for searching and # an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing @@ -1583,7 +1857,8 @@ SERVER_BASED_SEARCH = NO # # Doxygen ships with an example indexer (doxyindexer) and search engine # (doxysearch.cgi) which are based on the open source search engine library -# Xapian (see: http://xapian.org/). +# Xapian (see: +# https://xapian.org/). # # See the section "External Indexing and Searching" for details. # The default value is: NO. @@ -1596,8 +1871,9 @@ EXTERNAL_SEARCH = NO # # Doxygen ships with an example indexer (doxyindexer) and search engine # (doxysearch.cgi) which are based on the open source search engine library -# Xapian (see: http://xapian.org/). See the section "External Indexing and -# Searching" for details. +# Xapian (see: +# https://xapian.org/). See the section "External Indexing and Searching" for +# details. # This tag requires that the tag SEARCHENGINE is set to YES. SEARCHENGINE_URL = @@ -1648,21 +1924,35 @@ LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. # -# Note that when enabling USE_PDFLATEX this option is only used for generating -# bitmaps for formulas in the HTML output, but not in the Makefile that is -# written to the output directory. -# The default file is: latex. +# Note that when not enabling USE_PDFLATEX the default is latex when enabling +# USE_PDFLATEX the default is pdflatex and when in the later case latex is +# chosen this is overwritten by pdflatex. For specific output languages the +# default can have been set differently, this depends on the implementation of +# the output language. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate # index for LaTeX. +# Note: This tag is used in the Makefile / make.bat. +# See also: LATEX_MAKEINDEX_CMD for the part in the generated output file +# (.tex). # The default file is: makeindex. # This tag requires that the tag GENERATE_LATEX is set to YES. MAKEINDEX_CMD_NAME = makeindex +# The LATEX_MAKEINDEX_CMD tag can be used to specify the command name to +# generate index for LaTeX. In case there is no backslash (\) as first character +# it will be automatically added in the LaTeX code. +# Note: This tag is used in the generated output file (.tex). +# See also: MAKEINDEX_CMD_NAME for the part in the Makefile / make.bat. +# The default value is: makeindex. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_MAKEINDEX_CMD = makeindex + # If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX # documents. This may be useful for small projects and may help to save some # trees in general. @@ -1678,7 +1968,7 @@ COMPACT_LATEX = NO # The default value is: a4. # This tag requires that the tag GENERATE_LATEX is set to YES. -PAPER_TYPE = a4wide +PAPER_TYPE = a4 # The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names # that should be included in the LaTeX output. The package can be specified just @@ -1692,29 +1982,31 @@ PAPER_TYPE = a4wide EXTRA_PACKAGES = -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the -# generated LaTeX document. The header should contain everything until the first -# chapter. If it is left blank doxygen will generate a standard header. See -# section "Doxygen usage" for information on how to let doxygen write the -# default header to a separate file. +# The LATEX_HEADER tag can be used to specify a user-defined LaTeX header for +# the generated LaTeX document. The header should contain everything until the +# first chapter. If it is left blank doxygen will generate a standard header. It +# is highly recommended to start with a default header using +# doxygen -w latex new_header.tex new_footer.tex new_stylesheet.sty +# and then modify the file new_header.tex. See also section "Doxygen usage" for +# information on how to generate the default header that doxygen normally uses. # -# Note: Only use a user-defined header if you know what you are doing! The -# following commands have a special meaning inside the header: $title, -# $datetime, $date, $doxygenversion, $projectname, $projectnumber, -# $projectbrief, $projectlogo. Doxygen will replace $title with the empty -# string, for the replacement values of the other commands the user is referred -# to HTML_HEADER. +# Note: Only use a user-defined header if you know what you are doing! +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. The following +# commands have a special meaning inside the header (and footer): For a +# description of the possible markers and block names see the documentation. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_HEADER = -# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the -# generated LaTeX document. The footer should contain everything after the last -# chapter. If it is left blank doxygen will generate a standard footer. See +# The LATEX_FOOTER tag can be used to specify a user-defined LaTeX footer for +# the generated LaTeX document. The footer should contain everything after the +# last chapter. If it is left blank doxygen will generate a standard footer. See # LATEX_HEADER for more information on how to generate a default footer and what -# special commands can be used inside the footer. -# -# Note: Only use a user-defined footer if you know what you are doing! +# special commands can be used inside the footer. See also section "Doxygen +# usage" for information on how to generate the default footer that doxygen +# normally uses. Note: Only use a user-defined footer if you know what you are +# doing! # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_FOOTER = @@ -1747,18 +2039,26 @@ LATEX_EXTRA_FILES = PDF_HYPERLINKS = NO -# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate -# the PDF file directly from the LaTeX files. Set this option to YES, to get a -# higher quality PDF documentation. +# If the USE_PDFLATEX tag is set to YES, doxygen will use the engine as +# specified with LATEX_CMD_NAME to generate the PDF file directly from the LaTeX +# files. Set this option to YES, to get a higher quality PDF documentation. +# +# See also section LATEX_CMD_NAME for selecting the engine. # The default value is: YES. # This tag requires that the tag GENERATE_LATEX is set to YES. USE_PDFLATEX = NO -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode -# command to the generated LaTeX files. This will instruct LaTeX to keep running -# if errors occur, instead of asking the user for help. This option is also used -# when generating formulas in HTML. +# The LATEX_BATCHMODE tag ignals the behavior of LaTeX in case of an error. +# Possible values are: NO same as ERROR_STOP, YES same as BATCH, BATCH In batch +# mode nothing is printed on the terminal, errors are scrolled as if is +# hit at every error; missing files that TeX tries to input or request from +# keyboard input (\read on a not open input stream) cause the job to abort, +# NON_STOP In nonstop mode the diagnostic message will appear on the terminal, +# but there is no possibility of user interaction just like in batch mode, +# SCROLL In scroll mode, TeX will stop only for missing files to input or if +# keyboard input is necessary and ERROR_STOP In errorstop mode, TeX will stop at +# each error, asking for user intervention. # The default value is: NO. # This tag requires that the tag GENERATE_LATEX is set to YES. @@ -1771,31 +2071,21 @@ LATEX_BATCHMODE = NO LATEX_HIDE_INDICES = NO -# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source -# code with syntax highlighting in the LaTeX output. -# -# Note that which sources are shown also depends on other settings such as -# SOURCE_BROWSER. -# The default value is: NO. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_SOURCE_CODE = NO - # The LATEX_BIB_STYLE tag can be used to specify the style to use for the # bibliography, e.g. plainnat, or ieeetr. See -# http://en.wikipedia.org/wiki/BibTeX and \cite for more info. +# https://en.wikipedia.org/wiki/BibTeX and \cite for more info. # The default value is: plain. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_BIB_STYLE = plain -# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated -# page will contain the date and time when the page was generated. Setting this -# to NO can help when comparing the output of multiple runs. -# The default value is: NO. +# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute) +# path from which the emoji images will be read. If a relative path is entered, +# it will be relative to the LATEX_OUTPUT directory. If left blank the +# LATEX_OUTPUT directory will be used. # This tag requires that the tag GENERATE_LATEX is set to YES. -LATEX_TIMESTAMP = NO +LATEX_EMOJI_DIRECTORY = #--------------------------------------------------------------------------- # Configuration options related to the RTF output @@ -1836,9 +2126,9 @@ COMPACT_RTF = NO RTF_HYPERLINKS = NO -# Load stylesheet definitions from file. Syntax is similar to doxygen's config -# file, i.e. a series of assignments. You only have to provide replacements, -# missing definitions are set to their default value. +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# configuration file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. # # See also section "Doxygen usage" for information on how to generate the # default style sheet that doxygen normally uses. @@ -1847,22 +2137,12 @@ RTF_HYPERLINKS = NO RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an RTF document. Syntax is -# similar to doxygen's config file. A template extensions file can be generated -# using doxygen -e rtf extensionFile. +# similar to doxygen's configuration file. A template extensions file can be +# generated using doxygen -e rtf extensionFile. # This tag requires that the tag GENERATE_RTF is set to YES. RTF_EXTENSIONS_FILE = -# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code -# with syntax highlighting in the RTF output. -# -# Note that which sources are shown also depends on other settings such as -# SOURCE_BROWSER. -# The default value is: NO. -# This tag requires that the tag GENERATE_RTF is set to YES. - -RTF_SOURCE_CODE = NO - #--------------------------------------------------------------------------- # Configuration options related to the man page output #--------------------------------------------------------------------------- @@ -1934,6 +2214,13 @@ XML_OUTPUT = xml XML_PROGRAMLISTING = YES +# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include +# namespace members in file scope as well, matching the HTML output. +# The default value is: NO. +# This tag requires that the tag GENERATE_XML is set to YES. + +XML_NS_MEMB_FILE_SCOPE = NO + #--------------------------------------------------------------------------- # Configuration options related to the DOCBOOK output #--------------------------------------------------------------------------- @@ -1952,23 +2239,14 @@ GENERATE_DOCBOOK = NO DOCBOOK_OUTPUT = docbook -# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the -# program listings (including syntax highlighting and cross-referencing -# information) to the DOCBOOK output. Note that enabling this will significantly -# increase the size of the DOCBOOK output. -# The default value is: NO. -# This tag requires that the tag GENERATE_DOCBOOK is set to YES. - -DOCBOOK_PROGRAMLISTING = NO - #--------------------------------------------------------------------------- # Configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an -# AutoGen Definitions (see http://autogen.sf.net) file that captures the -# structure of the code including all documentation. Note that this feature is -# still experimental and incomplete at the moment. +# AutoGen Definitions (see https://autogen.sourceforge.net/) file that captures +# the structure of the code including all documentation. Note that this feature +# is still experimental and incomplete at the moment. # The default value is: NO. GENERATE_AUTOGEN_DEF = NO @@ -2028,7 +2306,7 @@ ENABLE_PREPROCESSING = YES # The default value is: NO. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -MACRO_EXPANSION = NO +MACRO_EXPANSION = YES # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then # the macro expansion is limited to the macros specified with the PREDEFINED and @@ -2047,7 +2325,8 @@ SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by the -# preprocessor. +# preprocessor. Note that the INCLUDE_PATH is not recursive, so the setting of +# RECURSIVE has no effect here. # This tag requires that the tag SEARCH_INCLUDES is set to YES. INCLUDE_PATH = @@ -2082,7 +2361,16 @@ PREDEFINED = WIN32=1 \ JUCE_COMPILER_SUPPORTS_VARIADIC_TEMPLATES=1 \ JUCE_COMPILER_SUPPORTS_OVERRIDE_AND_FINAL=1 \ JUCE_COMPILER_SUPPORTS_LAMBDAS=1 \ - JUCE_MODAL_LOOPS_PERMITTED=1 + JUCE_MODAL_LOOPS_PERMITTED=1 \ + JUCE_HAS_CONSTEXPR=1 \ + JUCE_CONSTEXPR=constexpr \ + JUCE_IGNORE_MSVC(warnings)= \ + JUCE_BEGIN_IGNORE_WARNINGS_LEVEL_MSVC(level, warnings)= \ + JUCE_BEGIN_IGNORE_WARNINGS_MSVC(warnings)= \ + JUCE_END_IGNORE_WARNINGS_MSVC= \ + JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE(...)= \ + JUCE_END_IGNORE_WARNINGS_GCC_LIKE= \ + JUCE_ENABLE_ALLOCATION_HOOKS=0 # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # tag can be used to specify a list of macro names that should be expanded. The @@ -2150,25 +2438,9 @@ EXTERNAL_GROUPS = YES EXTERNAL_PAGES = YES #--------------------------------------------------------------------------- -# Configuration options related to the dot tool +# Configuration options related to diagram generator tools #--------------------------------------------------------------------------- -# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram -# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to -# NO turns the diagrams off. Note that this option also works with HAVE_DOT -# disabled, but it is recommended to install and use dot, since it yields more -# powerful graphs. -# The default value is: YES. - -CLASS_DIAGRAMS = YES - -# You can include diagrams made with dia in doxygen documentation. Doxygen will -# then run dia to produce the diagram and insert it in the documentation. The -# DIA_PATH tag allows you to specify the directory where the dia binary resides. -# If left empty dia is assumed to be found in the default search path. - -DIA_PATH = - # If set to YES the inheritance and collaboration graphs will hide inheritance # and usage relations if the target is undocumented or is not a class. # The default value is: YES. @@ -2177,7 +2449,7 @@ HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz (see: -# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent +# https://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent # Bell Labs. The other options in this section have no effect if this option is # set to NO # The default value is: NO. @@ -2194,35 +2466,52 @@ HAVE_DOT = YES DOT_NUM_THREADS = 0 -# When you want a differently looking font in the dot files that doxygen -# generates you can specify the font name using DOT_FONTNAME. You need to make -# sure dot is able to find the font, which can be done by putting it in a -# standard location or by setting the DOTFONTPATH environment variable or by -# setting DOT_FONTPATH to the directory containing the font. -# The default value is: Helvetica. +# DOT_COMMON_ATTR is common attributes for nodes, edges and labels of +# subgraphs. When you want a differently looking font in the dot files that +# doxygen generates you can specify fontname, fontcolor and fontsize attributes. +# For details please see Node, +# Edge and Graph Attributes specification You need to make sure dot is able +# to find the font, which can be done by putting it in a standard location or by +# setting the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the +# directory containing the font. Default graphviz fontsize is 14. +# The default value is: fontname=Helvetica,fontsize=10. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_FONTNAME = +DOT_COMMON_ATTR = "fontname=Helvetica,fontsize=10" -# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of -# dot graphs. -# Minimum value: 4, maximum value: 24, default value: 10. +# DOT_EDGE_ATTR is concatenated with DOT_COMMON_ATTR. For elegant style you can +# add 'arrowhead=open, arrowtail=open, arrowsize=0.5'. Complete documentation about +# arrows shapes. +# The default value is: labelfontname=Helvetica,labelfontsize=10. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_FONTSIZE = 10 +DOT_EDGE_ATTR = "labelfontname=Helvetica,labelfontsize=10" -# By default doxygen will tell dot to use the default font as specified with -# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set -# the path where dot can find it using this tag. +# DOT_NODE_ATTR is concatenated with DOT_COMMON_ATTR. For view without boxes +# around nodes set 'shape=plain' or 'shape=plaintext' Shapes specification +# The default value is: shape=box,height=0.2,width=0.4. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_NODE_ATTR = "shape=box,height=0.2,width=0.4" + +# You can set the path where dot can find font specified with fontname in +# DOT_COMMON_ATTR and others dot attributes. # This tag requires that the tag HAVE_DOT is set to YES. DOT_FONTPATH = -# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for -# each documented class showing the direct and indirect inheritance relations. -# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO. +# If the CLASS_GRAPH tag is set to YES or GRAPH or BUILTIN then doxygen will +# generate a graph for each documented class showing the direct and indirect +# inheritance relations. In case the CLASS_GRAPH tag is set to YES or GRAPH and +# HAVE_DOT is enabled as well, then dot will be used to draw the graph. In case +# the CLASS_GRAPH tag is set to YES and HAVE_DOT is disabled or if the +# CLASS_GRAPH tag is set to BUILTIN, then the built-in generator will be used. +# If the CLASS_GRAPH tag is set to TEXT the direct and indirect inheritance +# relations will be shown as texts / links. +# Possible values are: NO, YES, TEXT, GRAPH and BUILTIN. # The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. CLASS_GRAPH = YES @@ -2236,7 +2525,8 @@ CLASS_GRAPH = YES COLLABORATION_GRAPH = NO # If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for -# groups, showing the direct groups dependencies. +# groups, showing the direct groups dependencies. See also the chapter Grouping +# in the manual. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2259,10 +2549,32 @@ UML_LOOK = NO # but if the number exceeds 15, the total amount of fields shown is limited to # 10. # Minimum value: 0, maximum value: 100, default value: 10. -# This tag requires that the tag HAVE_DOT is set to YES. +# This tag requires that the tag UML_LOOK is set to YES. UML_LIMIT_NUM_FIELDS = 10 +# If the DOT_UML_DETAILS tag is set to NO, doxygen will show attributes and +# methods without types and arguments in the UML graphs. If the DOT_UML_DETAILS +# tag is set to YES, doxygen will add type and arguments for attributes and +# methods in the UML graphs. If the DOT_UML_DETAILS tag is set to NONE, doxygen +# will not generate fields with class member information in the UML graphs. The +# class diagrams will look similar to the default class diagrams but using UML +# notation for the relationships. +# Possible values are: NO, YES and NONE. +# The default value is: NO. +# This tag requires that the tag UML_LOOK is set to YES. + +DOT_UML_DETAILS = NO + +# The DOT_WRAP_THRESHOLD tag can be used to set the maximum number of characters +# to display on a single line. If the actual line length exceeds this threshold +# significantly it will wrapped across multiple lines. Some heuristics are apply +# to avoid ugly line breaks. +# Minimum value: 0, maximum value: 1000, default value: 17. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_WRAP_THRESHOLD = 17 + # If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and # collaboration graphs will show the relations between templates and their # instances. @@ -2329,10 +2641,17 @@ GRAPHICAL_HIERARCHY = NO DIRECTORY_GRAPH = NO +# The DIR_GRAPH_MAX_DEPTH tag can be used to limit the maximum number of levels +# of child directories generated in directory dependency graphs by dot. +# Minimum value: 1, maximum value: 25, default value: 1. +# This tag requires that the tag DIRECTORY_GRAPH is set to YES. + +DIR_GRAPH_MAX_DEPTH = 1 + # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. For an explanation of the image formats see the section # output formats in the documentation of the dot tool (Graphviz (see: -# http://www.graphviz.org/)). +# https://www.graphviz.org/)). # Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order # to make the SVG files visible in IE 9+ (other browsers do not have this # requirement). @@ -2369,11 +2688,12 @@ DOT_PATH = DOTFILE_DIRS = -# The MSCFILE_DIRS tag can be used to specify one or more directories that -# contain msc files that are included in the documentation (see the \mscfile -# command). +# You can include diagrams made with dia in doxygen documentation. Doxygen will +# then run dia to produce the diagram and insert it in the documentation. The +# DIA_PATH tag allows you to specify the directory where the dia binary resides. +# If left empty dia is assumed to be found in the default search path. -MSCFILE_DIRS = +DIA_PATH = # The DIAFILE_DIRS tag can be used to specify one or more directories that # contain dia files that are included in the documentation (see the \diafile @@ -2382,13 +2702,18 @@ MSCFILE_DIRS = DIAFILE_DIRS = # When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the -# path where java can find the plantuml.jar file. If left blank, it is assumed -# PlantUML is not used or called during a preprocessing step. Doxygen will -# generate a warning when it encounters a \startuml command in this case and -# will not generate output for the diagram. +# path where java can find the plantuml.jar file or to the filename of jar file +# to be used. If left blank, it is assumed PlantUML is not used or called during +# a preprocessing step. Doxygen will generate a warning when it encounters a +# \startuml command in this case and will not generate output for the diagram. PLANTUML_JAR_PATH = +# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a +# configuration file for plantuml. + +PLANTUML_CFG_FILE = + # When using plantuml, the specified paths are searched for files specified by # the !include statement in a plantuml block. @@ -2418,18 +2743,6 @@ DOT_GRAPH_MAX_NODES = 50 MAX_DOT_GRAPH_DEPTH = 0 -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, because dot on Windows does not seem -# to support this out of the box. -# -# Warning: Depending on the platform used, enabling this option may lead to -# badly anti-aliased labels on the edges of a graph (i.e. they become hard to -# read). -# The default value is: NO. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_TRANSPARENT = YES - # Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) support @@ -2442,14 +2755,34 @@ DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page # explaining the meaning of the various boxes and arrows in the dot generated # graphs. +# Note: This tag requires that UML_LOOK isn't set, i.e. the doxygen internal +# graphical representation for inheritance and collaboration diagrams is used. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. GENERATE_LEGEND = NO -# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot +# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate # files that are used to generate the various graphs. +# +# Note: This setting is not only used for dot files but also for msc temporary +# files. # The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. DOT_CLEANUP = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. If the MSCGEN_TOOL tag is left empty (the default), then doxygen will +# use a built-in version of mscgen tool to produce the charts. Alternatively, +# the MSCGEN_TOOL tag can also specify the name an external tool. For instance, +# specifying prog as the value, doxygen will call the tool as prog -T +# -o . The external tool should support +# output file formats "png", "eps", "svg", and "ismap". + +MSCGEN_TOOL = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the \mscfile +# command). + +MSCFILE_DIRS = diff --git a/examples/Assets/ADSRComponent.h b/examples/Assets/ADSRComponent.h new file mode 100644 index 0000000000..d83422c84f --- /dev/null +++ b/examples/Assets/ADSRComponent.h @@ -0,0 +1,190 @@ +/* + ============================================================================== + + This file is part of the JUCE framework examples. + Copyright (c) Raw Material Software Limited + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + to use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + + ============================================================================== +*/ + +#pragma once + +class ADSRComponent final : public Component +{ +public: + ADSRComponent() + : envelope { *this } + { + for (Slider* slider : { &adsrAttack, &adsrDecay, &adsrSustain, &adsrRelease }) + { + if (slider == &adsrSustain) + { + slider->textFromValueFunction = [slider] (double value) + { + String text; + + text << slider->getName(); + + const auto val = (int) jmap (value, 0.0, 1.0, 0.0, 100.0); + text << String::formatted (": %d%%", val); + + return text; + }; + } + else + { + slider->textFromValueFunction = [slider] (double value) + { + String text; + + text << slider->getName(); + + text << ": " << ((value < 0.4f) ? String::formatted ("%dms", (int) std::round (value * 1000)) + : String::formatted ("%0.2lf Sec", value)); + + return text; + }; + + slider->setSkewFactor (0.3); + } + + slider->setRange (0, 1); + slider->setTextBoxStyle (Slider::TextBoxBelow, true, 300, 25); + slider->onValueChange = [this] + { + NullCheckedInvocation::invoke (onChange); + repaint(); + }; + + addAndMakeVisible (slider); + } + + adsrAttack.setName ("Attack"); + adsrDecay.setName ("Decay"); + adsrSustain.setName ("Sustain"); + adsrRelease.setName ("Release"); + + adsrAttack.setValue (0.1, dontSendNotification); + adsrDecay.setValue (0.3, dontSendNotification); + adsrSustain.setValue (0.3, dontSendNotification); + adsrRelease.setValue (0.2, dontSendNotification); + + addAndMakeVisible (envelope); + } + + std::function onChange; + + ADSR::Parameters getParameters() const + { + return + { + (float) adsrAttack.getValue(), + (float) adsrDecay.getValue(), + (float) adsrSustain.getValue(), + (float) adsrRelease.getValue(), + }; + } + + void resized() final + { + auto bounds = getLocalBounds(); + + const auto knobWidth = bounds.getWidth() / 4; + auto knobBounds = bounds.removeFromBottom (bounds.getHeight() / 2); + { + adsrAttack.setBounds (knobBounds.removeFromLeft (knobWidth)); + adsrDecay.setBounds (knobBounds.removeFromLeft (knobWidth)); + adsrSustain.setBounds (knobBounds.removeFromLeft (knobWidth)); + adsrRelease.setBounds (knobBounds.removeFromLeft (knobWidth)); + } + + envelope.setBounds (bounds); + } + + Slider adsrAttack { Slider::RotaryVerticalDrag, Slider::TextBoxBelow }; + Slider adsrDecay { Slider::RotaryVerticalDrag, Slider::TextBoxBelow }; + Slider adsrSustain { Slider::RotaryVerticalDrag, Slider::TextBoxBelow }; + Slider adsrRelease { Slider::RotaryVerticalDrag, Slider::TextBoxBelow }; + +private: + class Envelope final : public Component + { + public: + Envelope (ADSRComponent& adsr) : parent { adsr } {} + + void paint (Graphics& g) final + { + const auto env = parent.getParameters(); + + // sustain isn't a length but we use a fixed value here to give + // sustain some visual width in the envelope + constexpr auto sustainLength = 0.1; + + const auto adsrLength = env.attack + + env.decay + + sustainLength + + env.release; + + auto bounds = getLocalBounds().toFloat(); + + const auto attackWidth = bounds.proportionOfWidth (env.attack / adsrLength); + const auto decayWidth = bounds.proportionOfWidth (env.decay / adsrLength); + const auto sustainWidth = bounds.proportionOfWidth (sustainLength / adsrLength); + const auto releaseWidth = bounds.proportionOfWidth (env.release / adsrLength); + const auto sustainHeight = bounds.proportionOfHeight (1 - env.sustain); + + const auto attackBounds = bounds.removeFromLeft (attackWidth); + const auto decayBounds = bounds.removeFromLeft (decayWidth); + const auto sustainBounds = bounds.removeFromLeft (sustainWidth); + const auto releaseBounds = bounds.removeFromLeft (releaseWidth); + + g.setColour (Colours::black.withAlpha (0.1f)); + g.fillRect (bounds); + + const auto alpha = 0.4f; + + g.setColour (Colour (246, 98, 92).withAlpha (alpha)); + g.fillRect (attackBounds); + + g.setColour (Colour (242, 187, 60).withAlpha (alpha)); + g.fillRect (decayBounds); + + g.setColour (Colour (109, 234, 166).withAlpha (alpha)); + g.fillRect (sustainBounds); + + g.setColour (Colour (131, 61, 183).withAlpha (alpha)); + g.fillRect (releaseBounds); + + Path envelopePath; + envelopePath.startNewSubPath (attackBounds.getBottomLeft()); + envelopePath.lineTo (decayBounds.getTopLeft()); + envelopePath.lineTo (sustainBounds.getX(), sustainHeight); + envelopePath.lineTo (releaseBounds.getX(), sustainHeight); + envelopePath.lineTo (releaseBounds.getBottomRight()); + + const auto lineThickness = 4.0f; + + g.setColour (Colours::white); + g.strokePath (envelopePath, PathStrokeType { lineThickness }); + } + + private: + ADSRComponent& parent; + }; + + Envelope envelope; +}; diff --git a/examples/Assets/AudioLiveScrollingDisplay.h b/examples/Assets/AudioLiveScrollingDisplay.h index d706170dc2..a102f99119 100644 --- a/examples/Assets/AudioLiveScrollingDisplay.h +++ b/examples/Assets/AudioLiveScrollingDisplay.h @@ -1,18 +1,22 @@ /* ============================================================================== - This file is part of the JUCE examples. - Copyright (c) 2022 - Raw Material Software Limited + This file is part of the JUCE framework examples. + Copyright (c) Raw Material Software Limited The code included in this file is provided under the terms of the ISC license http://www.isc.org/downloads/software-support-policy/isc-license. Permission - To use, copy, modify, and/or distribute this software for any purpose with or + to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted provided that the above copyright notice and this permission notice appear in all copies. - THE SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, - WHETHER EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR - PURPOSE, ARE DISCLAIMED. + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. ============================================================================== */ @@ -24,8 +28,8 @@ /* This component scrolls a continuous waveform showing the audio that's coming into whatever audio inputs this object is connected to. */ -class LiveScrollingAudioDisplay : public AudioVisualiserComponent, - public AudioIODeviceCallback +class LiveScrollingAudioDisplay final : public AudioVisualiserComponent, + public AudioIODeviceCallback { public: LiveScrollingAudioDisplay() : AudioVisualiserComponent (1) diff --git a/examples/Assets/DSPDemos_Common.h b/examples/Assets/DSPDemos_Common.h index 9fa1d5c3a0..ea4ecd86e7 100644 --- a/examples/Assets/DSPDemos_Common.h +++ b/examples/Assets/DSPDemos_Common.h @@ -1,18 +1,22 @@ /* ============================================================================== - This file is part of the JUCE examples. - Copyright (c) 2022 - Raw Material Software Limited + This file is part of the JUCE framework examples. + Copyright (c) Raw Material Software Limited The code included in this file is provided under the terms of the ISC license http://www.isc.org/downloads/software-support-policy/isc-license. Permission - To use, copy, modify, and/or distribute this software for any purpose with or + to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted provided that the above copyright notice and this permission notice appear in all copies. - THE SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, - WHETHER EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR - PURPOSE, ARE DISCLAIMED. + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. ============================================================================== */ @@ -38,7 +42,7 @@ struct DSPDemoParameterBase : public ChangeBroadcaster }; //============================================================================== -struct SliderParameter : public DSPDemoParameterBase +struct SliderParameter final : public DSPDemoParameterBase { SliderParameter (Range range, double skew, double initialValue, const String& labelName, const String& suffix = {}) @@ -66,7 +70,7 @@ private: }; //============================================================================== -struct ChoiceParameter : public DSPDemoParameterBase +struct ChoiceParameter final : public DSPDemoParameterBase { ChoiceParameter (const StringArray& options, int initialId, const String& labelName) : DSPDemoParameterBase (labelName) @@ -89,11 +93,11 @@ private: }; //============================================================================== -class AudioThumbnailComponent : public Component, - public FileDragAndDropTarget, - public ChangeBroadcaster, - private ChangeListener, - private Timer +class AudioThumbnailComponent final : public Component, + public FileDragAndDropTarget, + public ChangeBroadcaster, + private ChangeListener, + private Timer { public: AudioThumbnailComponent (AudioDeviceManager& adm, AudioFormatManager& afm) @@ -148,7 +152,7 @@ public: { transportSource = newSource; - struct ResetCallback : public CallbackMessage + struct ResetCallback final : public CallbackMessage { ResetCallback (AudioThumbnailComponent& o) : owner (o) {} void messageCallback() override { owner.reset(); } @@ -217,7 +221,7 @@ private: }; //============================================================================== -class DemoParametersComponent : public Component +class DemoParametersComponent final : public Component { public: DemoParametersComponent (const std::vector& demoParams) @@ -270,9 +274,9 @@ private: //============================================================================== template -struct DSPDemo : public AudioSource, - public ProcessorWrapper, - private ChangeListener +struct DSPDemo final : public AudioSource, + public ProcessorWrapper, + private ChangeListener { DSPDemo (AudioSource& input) : inputSource (&input) @@ -327,10 +331,10 @@ struct DSPDemo : public AudioSource, //============================================================================== template -class AudioFileReaderComponent : public Component, - private TimeSliceThread, - private Value::Listener, - private ChangeListener +class AudioFileReaderComponent final : public Component, + private TimeSliceThread, + private Value::Listener, + private ChangeListener { public: //============================================================================== @@ -379,7 +383,7 @@ public: r.removeFromTop (20); - if (parametersComponent.get() != nullptr) + if (parametersComponent != nullptr) parametersComponent->setBounds (r.removeFromTop (parametersComponent->getHeightNeeded()).reduced (20, 0)); } @@ -412,6 +416,7 @@ public: readerSource->setLooping (loopState.getValue()); init(); + resized(); return true; } @@ -442,7 +447,7 @@ public: transportSource.reset (new AudioTransportSource()); transportSource->addChangeListener (this); - if (readerSource.get() != nullptr) + if (readerSource != nullptr) { if (auto* device = audioDeviceManager.getCurrentAudioDevice()) { @@ -461,12 +466,20 @@ public: audioSourcePlayer.setSource (currentDemo.get()); - initParameters(); + auto& parameters = currentDemo->getParameters(); + + parametersComponent.reset(); + + if (! parameters.empty()) + { + parametersComponent = std::make_unique (parameters); + addAndMakeVisible (parametersComponent.get()); + } } void play() { - if (readerSource.get() == nullptr) + if (readerSource == nullptr) return; if (transportSource->getCurrentPosition() >= transportSource->getLengthInSeconds() @@ -479,32 +492,17 @@ public: void setLooping (bool shouldLoop) { - if (readerSource.get() != nullptr) + if (readerSource != nullptr) readerSource->setLooping (shouldLoop); } AudioThumbnailComponent& getThumbnailComponent() { return header.thumbnailComp; } - void initParameters() - { - auto& parameters = currentDemo->getParameters(); - - parametersComponent.reset(); - - if (parameters.size() > 0) - { - parametersComponent.reset (new DemoParametersComponent (parameters)); - addAndMakeVisible (parametersComponent.get()); - } - - resized(); - } - private: //============================================================================== - class AudioPlayerHeader : public Component, - private ChangeListener, - private Value::Listener + class AudioPlayerHeader final : public Component, + private ChangeListener, + private Value::Listener { public: AudioPlayerHeader (AudioDeviceManager& adm, @@ -596,13 +594,17 @@ private: const auto u = fc.getURLResult(); if (! audioFileReader.loadURL (u)) - NativeMessageBox::showAsync (MessageBoxOptions() - .withIconType (MessageBoxIconType::WarningIcon) - .withTitle ("Error loading file") - .withMessage ("Unable to load audio file"), - nullptr); + { + auto options = MessageBoxOptions().withIconType (MessageBoxIconType::WarningIcon) + .withTitle ("Error loading file") + .withMessage ("Unable to load audio file") + .withButton ("OK"); + messageBox = NativeMessageBox::showScopedAsync (options, nullptr); + } else + { thumbnailComp.setCurrentURL (u); + } } fileChooser = nullptr; @@ -629,12 +631,13 @@ private: AudioFileReaderComponent& audioFileReader; std::unique_ptr fileChooser; + ScopedMessageBox messageBox; }; //============================================================================== void valueChanged (Value& v) override { - if (readerSource.get() != nullptr) + if (readerSource != nullptr) readerSource->setLooping (v.getValue()); } diff --git a/examples/Assets/DemoUtilities.h b/examples/Assets/DemoUtilities.h index ffdfc3631c..1c5534bff7 100644 --- a/examples/Assets/DemoUtilities.h +++ b/examples/Assets/DemoUtilities.h @@ -1,18 +1,22 @@ /* ============================================================================== - This file is part of the JUCE examples. - Copyright (c) 2022 - Raw Material Software Limited + This file is part of the JUCE framework examples. + Copyright (c) Raw Material Software Limited The code included in this file is provided under the terms of the ISC license http://www.isc.org/downloads/software-support-policy/isc-license. Permission - To use, copy, modify, and/or distribute this software for any purpose with or + to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted provided that the above copyright notice and this permission notice appear in all copies. - THE SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, - WHETHER EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR - PURPOSE, ARE DISCLAIMED. + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. ============================================================================== */ @@ -82,11 +86,26 @@ inline File getExamplesDirectory() noexcept #endif } -inline std::unique_ptr createAssetInputStream (const char* resourcePath) +enum class AssertAssetExists +{ + no, + yes +}; + +inline std::unique_ptr createAssetInputStream (const char* resourcePath, + [[maybe_unused]] AssertAssetExists assertExists = AssertAssetExists::yes) { #if JUCE_ANDROID ZipFile apkZip (File::getSpecialLocation (File::invokedExecutableFile)); - return std::unique_ptr (apkZip.createStreamForEntry (apkZip.getIndexOfFileName ("assets/" + String (resourcePath)))); + const auto fileIndex = apkZip.getIndexOfFileName ("assets/" + String (resourcePath)); + + if (fileIndex == -1) + { + jassert (assertExists == AssertAssetExists::no); + return {}; + } + + return std::unique_ptr (apkZip.createStreamForEntry (fileIndex)); #else #if JUCE_IOS auto assetsDir = File::getSpecialLocation (File::currentExecutableFile) @@ -102,7 +121,12 @@ inline std::unique_ptr createAssetInputStream (const char* resource #endif auto resourceFile = assetsDir.getChildFile (resourcePath); - jassert (resourceFile.existsAsFile()); + + if (! resourceFile.existsAsFile()) + { + jassert (assertExists == AssertAssetExists::no); + return {}; + } return resourceFile.createInputStream(); #endif @@ -218,11 +242,7 @@ inline Path getJUCELogoPath() // 0.0 and 1.0 at a random speed struct BouncingNumber { - BouncingNumber() - : speed (0.0004 + 0.0007 * Random::getSystemRandom().nextDouble()), - phase (Random::getSystemRandom().nextDouble()) - { - } + virtual ~BouncingNumber() = default; float getValue() const { @@ -231,10 +251,11 @@ struct BouncingNumber } protected: - double speed, phase; + double speed = 0.0004 + 0.0007 * Random::getSystemRandom().nextDouble(), + phase = Random::getSystemRandom().nextDouble(); }; -struct SlowerBouncingNumber : public BouncingNumber +struct SlowerBouncingNumber final : public BouncingNumber { SlowerBouncingNumber() { @@ -244,10 +265,8 @@ struct SlowerBouncingNumber : public BouncingNumber inline std::unique_ptr makeInputSource (const URL& url) { - #if JUCE_ANDROID - if (auto doc = AndroidDocument::fromDocument (url)) + if (const auto doc = AndroidDocument::fromDocument (url)) return std::make_unique (doc); - #endif #if ! JUCE_IOS if (url.isLocalFile()) @@ -257,4 +276,17 @@ inline std::unique_ptr makeInputSource (const URL& url) return std::make_unique (url); } +inline std::unique_ptr makeOutputStream (const URL& url) +{ + if (const auto doc = AndroidDocument::fromDocument (url)) + return doc.createOutputStream(); + + #if ! JUCE_IOS + if (url.isLocalFile()) + return url.getLocalFile().createOutputStream(); + #endif + + return url.createOutputStream(); +} + #endif // PIP_DEMO_UTILITIES_INCLUDED diff --git a/examples/Assets/WavefrontObjParser.h b/examples/Assets/WavefrontObjParser.h index 01f5177051..eb8b25b6a6 100644 --- a/examples/Assets/WavefrontObjParser.h +++ b/examples/Assets/WavefrontObjParser.h @@ -1,18 +1,22 @@ /* ============================================================================== - This file is part of the JUCE examples. - Copyright (c) 2022 - Raw Material Software Limited + This file is part of the JUCE framework examples. + Copyright (c) Raw Material Software Limited The code included in this file is provided under the terms of the ISC license http://www.isc.org/downloads/software-support-policy/isc-license. Permission - To use, copy, modify, and/or distribute this software for any purpose with or + to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted provided that the above copyright notice and this permission notice appear in all copies. - THE SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, - WHETHER EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR - PURPOSE, ARE DISCLAIMED. + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. ============================================================================== */ diff --git a/examples/Assets/juce_module_info b/examples/Assets/juce_module_info index 1059fa2abc..9cf8a262d6 100644 --- a/examples/Assets/juce_module_info +++ b/examples/Assets/juce_module_info @@ -33,6 +33,5 @@ "OSXFrameworks": "Cocoa IOKit", "iOSFrameworks": "Foundation", - "LinuxLibs": "rt dl pthread", - "mingwLibs": "uuid wsock32 wininet version ole32 ws2_32 oleaut32 imm32 comdlg32 shlwapi rpcrt4 winmm" + "LinuxLibs": "rt dl pthread" } diff --git a/examples/Assets/webviewplugin-gui-fallback.html b/examples/Assets/webviewplugin-gui-fallback.html new file mode 100644 index 0000000000..58b4f71be2 --- /dev/null +++ b/examples/Assets/webviewplugin-gui-fallback.html @@ -0,0 +1,39 @@ + + + + + WebViewPluginDemo + + + +

WebViewPluginDemo

+

+ This document is a placeholder for the GUI component of the + WebViewPluginDemo. +

+

+ To build the fully fledged user interface you need to install + node.js +

+

+ Then navigate into the + examples/Plugins/WebViewPluginDemoGUI directory inside your JUCE + directory, and issue the following commands. +

+
+        npm install
+        npm run build
+        npm run zip
+      
+

+ This will build the full GUI package and place it in the + Assets directory. +

+

After this, rebuild and restart this demo.

+ + diff --git a/examples/Audio/AudioAppDemo.h b/examples/Audio/AudioAppDemo.h index 933edb53c7..67e9ee2d35 100644 --- a/examples/Audio/AudioAppDemo.h +++ b/examples/Audio/AudioAppDemo.h @@ -1,18 +1,22 @@ /* ============================================================================== - This file is part of the JUCE examples. - Copyright (c) 2022 - Raw Material Software Limited + This file is part of the JUCE framework examples. + Copyright (c) Raw Material Software Limited The code included in this file is provided under the terms of the ISC license http://www.isc.org/downloads/software-support-policy/isc-license. Permission - To use, copy, modify, and/or distribute this software for any purpose with or + to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted provided that the above copyright notice and this permission notice appear in all copies. - THE SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, - WHETHER EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR - PURPOSE, ARE DISCLAIMED. + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. ============================================================================== */ @@ -50,7 +54,7 @@ //============================================================================== -class AudioAppDemo : public AudioAppComponent +class AudioAppDemo final : public AudioAppComponent { public: //============================================================================== diff --git a/examples/Audio/AudioLatencyDemo.h b/examples/Audio/AudioLatencyDemo.h index cd47e94a35..6334a851cb 100644 --- a/examples/Audio/AudioLatencyDemo.h +++ b/examples/Audio/AudioLatencyDemo.h @@ -1,18 +1,22 @@ /* ============================================================================== - This file is part of the JUCE examples. - Copyright (c) 2022 - Raw Material Software Limited + This file is part of the JUCE framework examples. + Copyright (c) Raw Material Software Limited The code included in this file is provided under the terms of the ISC license http://www.isc.org/downloads/software-support-policy/isc-license. Permission - To use, copy, modify, and/or distribute this software for any purpose with or + to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted provided that the above copyright notice and this permission notice appear in all copies. - THE SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, - WHETHER EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR - PURPOSE, ARE DISCLAIMED. + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. ============================================================================== */ @@ -52,8 +56,8 @@ #include "../Assets/AudioLiveScrollingDisplay.h" //============================================================================== -class LatencyTester : public AudioIODeviceCallback, - private Timer +class LatencyTester final : public AudioIODeviceCallback, + private Timer { public: LatencyTester (TextEditor& editorBox) @@ -304,7 +308,7 @@ private: }; //============================================================================== -class AudioLatencyDemo : public Component +class AudioLatencyDemo final : public Component { public: AudioLatencyDemo() diff --git a/examples/Audio/AudioPlaybackDemo.h b/examples/Audio/AudioPlaybackDemo.h index 6d317f4466..c31e311efa 100644 --- a/examples/Audio/AudioPlaybackDemo.h +++ b/examples/Audio/AudioPlaybackDemo.h @@ -1,18 +1,22 @@ /* ============================================================================== - This file is part of the JUCE examples. - Copyright (c) 2022 - Raw Material Software Limited + This file is part of the JUCE framework examples. + Copyright (c) Raw Material Software Limited The code included in this file is provided under the terms of the ISC license http://www.isc.org/downloads/software-support-policy/isc-license. Permission - To use, copy, modify, and/or distribute this software for any purpose with or + to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted provided that the above copyright notice and this permission notice appear in all copies. - THE SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, - WHETHER EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR - PURPOSE, ARE DISCLAIMED. + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. ============================================================================== */ @@ -48,12 +52,12 @@ #include "../Assets/DemoUtilities.h" -class DemoThumbnailComp : public Component, - public ChangeListener, - public FileDragAndDropTarget, - public ChangeBroadcaster, - private ScrollBar::Listener, - private Timer +class DemoThumbnailComp final : public Component, + public ChangeListener, + public FileDragAndDropTarget, + public ChangeBroadcaster, + private ScrollBar::Listener, + private Timer { public: DemoThumbnailComp (AudioFormatManager& formatManager, @@ -188,7 +192,7 @@ public: if (canMoveTransport()) setRange ({ newStart, newStart + visibleRange.getLength() }); - if (wheel.deltaY != 0.0f) + if (! approximatelyEqual (wheel.deltaY, 0.0f)) zoomSlider.setValue (zoomSlider.getValue() - wheel.deltaY); repaint(); @@ -251,19 +255,19 @@ private: }; //============================================================================== -class AudioPlaybackDemo : public Component, - #if (JUCE_ANDROID || JUCE_IOS) - private Button::Listener, - #else - private FileBrowserListener, - #endif - private ChangeListener +class AudioPlaybackDemo final : public Component, + #if (JUCE_ANDROID || JUCE_IOS) + private Button::Listener, + #else + private FileBrowserListener, + #endif + private ChangeListener { public: AudioPlaybackDemo() { addAndMakeVisible (zoomLabel); - zoomLabel.setFont (Font (15.00f, Font::plain)); + zoomLabel.setFont (FontOptions (15.00f, Font::plain)); zoomLabel.setJustificationType (Justification::centredRight); zoomLabel.setEditable (false, false, false); zoomLabel.setColour (TextEditor::textColourId, Colours::black); @@ -285,7 +289,7 @@ public: fileTreeComp.addListener (this); addAndMakeVisible (explanation); - explanation.setFont (Font (14.00f, Font::plain)); + explanation.setFont (FontOptions (14.00f, Font::plain)); explanation.setJustificationType (Justification::bottomRight); explanation.setEditable (false, false, false); explanation.setColour (TextEditor::textColourId, Colours::black); @@ -312,12 +316,7 @@ public: thread.startThread (Thread::Priority::normal); #ifndef JUCE_DEMO_RUNNER - RuntimePermissions::request (RuntimePermissions::recordAudio, - [this] (bool granted) - { - int numInputChannels = granted ? 2 : 0; - audioDeviceManager.initialise (numInputChannels, 2, nullptr, true, {}, nullptr); - }); + audioDeviceManager.initialise (0, 2, nullptr, true, {}, nullptr); #endif audioDeviceManager.addAudioCallback (&audioSourcePlayer); @@ -415,9 +414,14 @@ private: //============================================================================== void showAudioResource (URL resource) { - if (loadURLIntoTransport (resource)) - currentAudioFile = std::move (resource); + if (! loadURLIntoTransport (resource)) + { + // Failed to load the audio file! + jassertfalse; + return; + } + currentAudioFile = std::move (resource); zoomSlider.setValue (0, dontSendNotification); thumbnail->setURL (currentAudioFile); } @@ -492,7 +496,7 @@ private: if (FileChooser::isPlatformDialogAvailable()) { - fileChooser = std::make_unique ("Select an audio file...", File(), "*.wav;*.mp3;*.aif"); + fileChooser = std::make_unique ("Select an audio file...", File(), "*.wav;*.flac;*.aif"); fileChooser->launchAsync (FileBrowserComponent::openMode | FileBrowserComponent::canSelectFiles, [this] (const FileChooser& fc) mutable diff --git a/examples/Audio/AudioRecordingDemo.h b/examples/Audio/AudioRecordingDemo.h index 38bf15b7d7..6782616e04 100644 --- a/examples/Audio/AudioRecordingDemo.h +++ b/examples/Audio/AudioRecordingDemo.h @@ -1,18 +1,22 @@ /* ============================================================================== - This file is part of the JUCE examples. - Copyright (c) 2022 - Raw Material Software Limited + This file is part of the JUCE framework examples. + Copyright (c) Raw Material Software Limited The code included in this file is provided under the terms of the ISC license http://www.isc.org/downloads/software-support-policy/isc-license. Permission - To use, copy, modify, and/or distribute this software for any purpose with or + to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted provided that the above copyright notice and this permission notice appear in all copies. - THE SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, - WHETHER EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR - PURPOSE, ARE DISCLAIMED. + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. ============================================================================== */ @@ -55,7 +59,7 @@ /** A simple class that acts as an AudioIODeviceCallback and writes the incoming audio data to a WAV file. */ -class AudioRecorder : public AudioIODeviceCallback +class AudioRecorder final : public AudioIODeviceCallback { public: AudioRecorder (AudioThumbnail& thumbnailToUpdate) @@ -170,8 +174,8 @@ private: }; //============================================================================== -class RecordingThumbnail : public Component, - private ChangeListener +class RecordingThumbnail final : public Component, + private ChangeListener { public: RecordingThumbnail() @@ -230,7 +234,7 @@ private: }; //============================================================================== -class AudioRecordingDemo : public Component +class AudioRecordingDemo final : public Component { public: AudioRecordingDemo() @@ -239,7 +243,7 @@ public: addAndMakeVisible (liveAudioScroller); addAndMakeVisible (explanationLabel); - explanationLabel.setFont (Font (15.0f, Font::plain)); + explanationLabel.setFont (FontOptions (15.0f, Font::plain)); explanationLabel.setJustificationType (Justification::topLeft); explanationLabel.setEditable (false, false, false); explanationLabel.setColour (TextEditor::textColourId, Colours::black); @@ -305,17 +309,14 @@ private: LiveScrollingAudioDisplay liveAudioScroller; RecordingThumbnail recordingThumbnail; - AudioRecorder recorder { recordingThumbnail.getAudioThumbnail() }; + AudioRecorder recorder { recordingThumbnail.getAudioThumbnail() }; - Label explanationLabel { {}, "This page demonstrates how to record a wave file from the live audio input..\n\n" - #if (JUCE_ANDROID || JUCE_IOS) - "After you are done with your recording you can share with other apps." - #else - "Pressing record will start recording a file in your \"Documents\" folder." - #endif - }; + Label explanationLabel { {}, + "This page demonstrates how to record a wave file from the live audio input.\n\n" + "After you are done with your recording you can choose where to save it." }; TextButton recordButton { "Record" }; File lastRecording; + FileChooser chooser { "Output file...", File::getCurrentWorkingDirectory().getChildFile ("recording.wav"), "*.wav" }; void startRecording() { @@ -350,28 +351,18 @@ private: { recorder.stop(); - #if JUCE_CONTENT_SHARING - SafePointer safeThis (this); - File fileToShare = lastRecording; + chooser.launchAsync ( FileBrowserComponent::saveMode + | FileBrowserComponent::canSelectFiles + | FileBrowserComponent::warnAboutOverwriting, + [this] (const FileChooser& c) + { + if (FileInputStream inputStream (lastRecording); inputStream.openedOk()) + if (const auto outputStream = makeOutputStream (c.getURLResult())) + outputStream->writeFromInputStream (inputStream, -1); - ContentSharer::getInstance()->shareFiles (Array ({URL (fileToShare)}), - [safeThis, fileToShare] (bool success, const String& error) - { - if (fileToShare.existsAsFile()) - fileToShare.deleteFile(); - - if (! success && error.isNotEmpty()) - NativeMessageBox::showAsync (MessageBoxOptions() - .withIconType (MessageBoxIconType::WarningIcon) - .withTitle ("Sharing Error") - .withMessage (error), - nullptr); - }); - #endif - - lastRecording = File(); - recordButton.setButtonText ("Record"); - recordingThumbnail.setDisplayFullThumbnail (true); + recordButton.setButtonText ("Record"); + recordingThumbnail.setDisplayFullThumbnail (true); + }); } JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioRecordingDemo) diff --git a/examples/Audio/AudioSettingsDemo.h b/examples/Audio/AudioSettingsDemo.h index 6865a086ae..d1231c2bb1 100644 --- a/examples/Audio/AudioSettingsDemo.h +++ b/examples/Audio/AudioSettingsDemo.h @@ -1,18 +1,22 @@ /* ============================================================================== - This file is part of the JUCE examples. - Copyright (c) 2022 - Raw Material Software Limited + This file is part of the JUCE framework examples. + Copyright (c) Raw Material Software Limited The code included in this file is provided under the terms of the ISC license http://www.isc.org/downloads/software-support-policy/isc-license. Permission - To use, copy, modify, and/or distribute this software for any purpose with or + to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted provided that the above copyright notice and this permission notice appear in all copies. - THE SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, - WHETHER EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR - PURPOSE, ARE DISCLAIMED. + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. ============================================================================== */ @@ -51,8 +55,8 @@ #include "../Assets/DemoUtilities.h" //============================================================================== -class AudioSettingsDemo : public Component, - public ChangeListener +class AudioSettingsDemo final : public Component, + public ChangeListener { public: AudioSettingsDemo() diff --git a/examples/Audio/AudioSynthesiserDemo.h b/examples/Audio/AudioSynthesiserDemo.h index 11891911b6..469196630a 100644 --- a/examples/Audio/AudioSynthesiserDemo.h +++ b/examples/Audio/AudioSynthesiserDemo.h @@ -1,18 +1,22 @@ /* ============================================================================== - This file is part of the JUCE examples. - Copyright (c) 2022 - Raw Material Software Limited + This file is part of the JUCE framework examples. + Copyright (c) Raw Material Software Limited The code included in this file is provided under the terms of the ISC license http://www.isc.org/downloads/software-support-policy/isc-license. Permission - To use, copy, modify, and/or distribute this software for any purpose with or + to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted provided that the above copyright notice and this permission notice appear in all copies. - THE SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, - WHETHER EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR - PURPOSE, ARE DISCLAIMED. + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. ============================================================================== */ @@ -53,20 +57,16 @@ //============================================================================== /** Our demo synth sound is just a basic sine wave.. */ -struct SineWaveSound : public SynthesiserSound +struct SineWaveSound final : public SynthesiserSound { - SineWaveSound() {} - bool appliesToNote (int /*midiNoteNumber*/) override { return true; } bool appliesToChannel (int /*midiChannel*/) override { return true; } }; //============================================================================== /** Our demo synth voice just plays a sine wave.. */ -struct SineWaveVoice : public SynthesiserVoice +struct SineWaveVoice final : public SynthesiserVoice { - SineWaveVoice() {} - bool canPlaySound (SynthesiserSound* sound) override { return dynamic_cast (sound) != nullptr; @@ -92,8 +92,8 @@ struct SineWaveVoice : public SynthesiserVoice // start a tail-off by setting this flag. The render callback will pick up on // this and do a fade out, calling clearCurrentNote() when it's finished. - if (tailOff == 0.0) // we only need to begin a tail-off if it's not already doing so - the - tailOff = 1.0; // stopNote method could be called more than once. + if (approximatelyEqual (tailOff, 0.0)) // we only need to begin a tail-off if it's not already doing so - the + tailOff = 1.0; // stopNote method could be called more than once. } else { @@ -108,7 +108,7 @@ struct SineWaveVoice : public SynthesiserVoice void renderNextBlock (AudioBuffer& outputBuffer, int startSample, int numSamples) override { - if (angleDelta != 0.0) + if (! approximatelyEqual (angleDelta, 0.0)) { if (tailOff > 0.0) { @@ -157,7 +157,7 @@ private: //============================================================================== // This is an audio source that streams the output of our demo synth. -struct SynthAudioSource : public AudioSource +struct SynthAudioSource final : public AudioSource { SynthAudioSource (MidiKeyboardState& keyState) : keyboardState (keyState) { @@ -242,7 +242,52 @@ struct SynthAudioSource : public AudioSource }; //============================================================================== -class AudioSynthesiserDemo : public Component +class Callback final : public AudioIODeviceCallback +{ +public: + Callback (AudioSourcePlayer& playerIn, LiveScrollingAudioDisplay& displayIn) + : player (playerIn), display (displayIn) {} + + void audioDeviceIOCallbackWithContext (const float* const* inputChannelData, + int numInputChannels, + float* const* outputChannelData, + int numOutputChannels, + int numSamples, + const AudioIODeviceCallbackContext& context) override + { + player.audioDeviceIOCallbackWithContext (inputChannelData, + numInputChannels, + outputChannelData, + numOutputChannels, + numSamples, + context); + display.audioDeviceIOCallbackWithContext (outputChannelData, + numOutputChannels, + nullptr, + 0, + numSamples, + context); + } + + void audioDeviceAboutToStart (AudioIODevice* device) override + { + player.audioDeviceAboutToStart (device); + display.audioDeviceAboutToStart (device); + } + + void audioDeviceStopped() override + { + player.audioDeviceStopped(); + display.audioDeviceStopped(); + } + +private: + AudioSourcePlayer& player; + LiveScrollingAudioDisplay& display; +}; + +//============================================================================== +class AudioSynthesiserDemo final : public Component { public: AudioSynthesiserDemo() @@ -259,19 +304,13 @@ public: sampledButton.onClick = [this] { synthAudioSource.setUsingSampledSound(); }; addAndMakeVisible (liveAudioDisplayComp); - audioDeviceManager.addAudioCallback (&liveAudioDisplayComp); audioSourcePlayer.setSource (&synthAudioSource); #ifndef JUCE_DEMO_RUNNER - RuntimePermissions::request (RuntimePermissions::recordAudio, - [this] (bool granted) - { - int numInputChannels = granted ? 2 : 0; - audioDeviceManager.initialise (numInputChannels, 2, nullptr, true, {}, nullptr); - }); + audioDeviceManager.initialise (0, 2, nullptr, true, {}, nullptr); #endif - audioDeviceManager.addAudioCallback (&audioSourcePlayer); + audioDeviceManager.addAudioCallback (&callback); audioDeviceManager.addMidiInputDeviceCallback ({}, &(synthAudioSource.midiCollector)); setOpaque (true); @@ -282,8 +321,7 @@ public: { audioSourcePlayer.setSource (nullptr); audioDeviceManager.removeMidiInputDeviceCallback ({}, &(synthAudioSource.midiCollector)); - audioDeviceManager.removeAudioCallback (&audioSourcePlayer); - audioDeviceManager.removeAudioCallback (&liveAudioDisplayComp); + audioDeviceManager.removeAudioCallback (&callback); } //============================================================================== @@ -318,5 +356,7 @@ private: LiveScrollingAudioDisplay liveAudioDisplayComp; + Callback callback { audioSourcePlayer, liveAudioDisplayComp }; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioSynthesiserDemo) }; diff --git a/examples/Audio/AudioWorkgroupDemo.h b/examples/Audio/AudioWorkgroupDemo.h new file mode 100644 index 0000000000..a180f24646 --- /dev/null +++ b/examples/Audio/AudioWorkgroupDemo.h @@ -0,0 +1,663 @@ +/* + ============================================================================== + + This file is part of the JUCE framework examples. + Copyright (c) Raw Material Software Limited + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + to use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + + ============================================================================== +*/ + +/******************************************************************************* + The block below describes the properties of this PIP. A PIP is a short snippet + of code that can be read by the Projucer and used to generate a JUCE project. + + BEGIN_JUCE_PIP_METADATA + + name: AudioWorkgroupDemo + version: 1.0.0 + vendor: JUCE + website: http://juce.com + description: Simple audio workgroup demo application. + + dependencies: juce_audio_basics, juce_audio_devices, juce_audio_formats, + juce_audio_processors, juce_audio_utils, juce_core, + juce_data_structures, juce_events, juce_graphics, + juce_gui_basics, juce_gui_extra + exporters: xcode_mac, xcode_iphone + + moduleFlags: JUCE_STRICT_REFCOUNTEDPOINTER=1 + + type: Component + mainClass: AudioWorkgroupDemo + + useLocalCopy: 1 + + END_JUCE_PIP_METADATA + +*******************************************************************************/ + +#pragma once + +#include "../Assets/DemoUtilities.h" +#include "../Assets/AudioLiveScrollingDisplay.h" +#include "../Assets/ADSRComponent.h" + +constexpr auto NumWorkerThreads = 4; + +//============================================================================== +class ThreadBarrier : public ReferenceCountedObject +{ +public: + using Ptr = ReferenceCountedObjectPtr; + + static Ptr make (int numThreadsToSynchronise) + { + return { new ThreadBarrier { numThreadsToSynchronise } }; + } + + void arriveAndWait() + { + std::unique_lock lk { mutex }; + + [[maybe_unused]] const auto c = ++blockCount; + + // You've tried to synchronise too many threads!! + jassert (c <= threadCount); + + if (blockCount == threadCount) + { + blockCount = 0; + cv.notify_all(); + return; + } + + cv.wait (lk, [this] { return blockCount == 0; }); + } + +private: + std::mutex mutex; + std::condition_variable cv; + int blockCount{}; + const int threadCount{}; + + explicit ThreadBarrier (int numThreadsToSynchronise) + : threadCount (numThreadsToSynchronise) {} + + JUCE_DECLARE_NON_COPYABLE (ThreadBarrier) + JUCE_DECLARE_NON_MOVEABLE (ThreadBarrier) +}; + +struct Voice +{ + struct Oscillator + { + float getNextSample() + { + const auto s = (2.f * phase - 1.f); + phase += delta; + + if (phase >= 1.f) + phase -= 1.f; + + return s; + } + + float delta = 0; + float phase = 0; + }; + + Voice (int numSamples, double newSampleRate) + : sampleRate (newSampleRate), + workBuffer (2, numSamples) + { + } + + bool isActive() const { return adsr.isActive(); } + + void startNote (int midiNoteNumber, float detuneAmount, ADSR::Parameters env) + { + constexpr float superSawDetuneValues[] = { -1.f, -0.8f, -0.6f, 0.f, 0.5f, 0.7f, 1.f }; + const auto freq = 440.f * std::pow (2.f, ((float) midiNoteNumber - 69.f) / 12.f); + + for (size_t i = 0; i < 7; i++) + { + auto& osc = oscillators[i]; + + const auto detune = superSawDetuneValues[i] * detuneAmount; + + osc.delta = (freq + detune) / (float) sampleRate; + osc.phase = wobbleGenerator.nextFloat(); + } + + currentNote = midiNoteNumber; + + adsr.setParameters (env); + adsr.setSampleRate (sampleRate); + adsr.noteOn(); + } + + void stopNote() + { + adsr.noteOff(); + } + + void run() + { + workBuffer.clear(); + + constexpr auto oscillatorCount = 7; + constexpr float superSawPanValues[] = { -1.f, -0.7f, -0.3f, 0.f, 0.3f, 0.7f, 1.f }; + + constexpr auto spread = 0.8f; + constexpr auto mix = 1 / 7.f; + + auto* l = workBuffer.getWritePointer (0); + auto* r = workBuffer.getWritePointer (1); + + for (int i = 0; i < workBuffer.getNumSamples(); i++) + { + const auto a = adsr.getNextSample(); + + float left = 0; + float right = 0; + + for (size_t o = 0; o < oscillatorCount; o++) + { + auto& osc = oscillators[o]; + const auto s = a * osc.getNextSample(); + + left += s * (1.f - (superSawPanValues[o] * spread)); + right += s * (1.f + (superSawPanValues[o] * spread)); + } + + l[i] += left * mix; + r[i] += right * mix; + } + + workBuffer.applyGain (0.25f); + } + + const AudioSampleBuffer& getWorkBuffer() const { return workBuffer; } + + ADSR adsr; + double sampleRate; + std::array oscillators; + int currentNote = 0; + Random wobbleGenerator; + +private: + AudioSampleBuffer workBuffer; + + JUCE_DECLARE_NON_COPYABLE (Voice) + JUCE_DECLARE_NON_MOVEABLE (Voice) +}; + +struct AudioWorkerThreadOptions +{ + int numChannels; + int numSamples; + double sampleRate; + AudioWorkgroup workgroup; + ThreadBarrier::Ptr completionBarrier; +}; + +class AudioWorkerThread final : private Thread +{ +public: + using Ptr = std::unique_ptr; + using Options = AudioWorkerThreadOptions; + + explicit AudioWorkerThread (const Options& workerOptions) + : Thread ("AudioWorkerThread"), + options (workerOptions) + { + jassert (options.completionBarrier != nullptr); + + #if defined (JUCE_MAC) + jassert (options.workgroup); + #endif + + startRealtimeThread (RealtimeOptions{}.withApproximateAudioProcessingTime (options.numSamples, options.sampleRate)); + } + + ~AudioWorkerThread() override { stop(); } + + using Thread::notify; + using Thread::signalThreadShouldExit; + using Thread::isThreadRunning; + + int getJobCount() const { return lastJobCount; } + + int queueAudioJobs (Span jobs) + { + size_t spanIndex = 0; + + const auto write = jobQueueFifo.write ((int) jobs.size()); + write.forEach ([&, jobs] (int dstIndex) + { + jobQueue[(size_t) dstIndex] = jobs[spanIndex++]; + }); + return write.blockSize1 + write.blockSize2; + } + +private: + void stop() + { + signalThreadShouldExit(); + stopThread (-1); + } + + void run() override + { + WorkgroupToken token; + + options.workgroup.join (token); + + while (wait (-1) && ! threadShouldExit()) + { + const auto numReady = jobQueueFifo.getNumReady(); + lastJobCount = numReady; + + if (numReady > 0) + { + jobQueueFifo.read (jobQueueFifo.getNumReady()) + .forEach ([this] (int srcIndex) + { + jobQueue[(size_t) srcIndex]->run(); + }); + } + + // Wait for all our threads to get to this point. + options.completionBarrier->arriveAndWait(); + } + } + + static constexpr auto numJobs = 128; + + Options options; + std::array jobQueue; + AbstractFifo jobQueueFifo { numJobs }; + std::atomic lastJobCount = 0; + +private: + JUCE_DECLARE_NON_COPYABLE (AudioWorkerThread) + JUCE_DECLARE_NON_MOVEABLE (AudioWorkerThread) +}; + +template +struct SharedThreadValue +{ + SharedThreadValue (LockType& lockRef, ValueType initialValue = {}) + : lock (lockRef), + preSyncValue (initialValue), + postSyncValue (initialValue) + { + } + + void set (const ValueType& newValue) + { + const typename LockType::ScopedLockType sl { lock }; + preSyncValue = newValue; + } + + ValueType get() const + { + { + const typename LockType::ScopedTryLockType sl { lock, true }; + + if (sl.isLocked()) + postSyncValue = preSyncValue; + } + + return postSyncValue; + } + +private: + LockType& lock; + ValueType preSyncValue{}; + mutable ValueType postSyncValue{}; + + JUCE_DECLARE_NON_COPYABLE (SharedThreadValue) + JUCE_DECLARE_NON_MOVEABLE (SharedThreadValue) +}; + +//============================================================================== +class SuperSynth +{ +public: + SuperSynth() = default; + + void setEnvelope (ADSR::Parameters params) + { + envelope.set (params); + } + + void setThickness (float newThickness) + { + thickness.set (newThickness); + } + + void prepareToPlay (int numSamples, double sampleRate) + { + activeVoices.reserve (128); + + for (auto& voice : voices) + voice.reset (new Voice { numSamples, sampleRate }); + } + + void process (ThreadBarrier::Ptr barrier, Span workers, + AudioSampleBuffer& buffer, MidiBuffer& midiBuffer) + { + const auto blockThickness = thickness.get(); + const auto blockEnvelope = envelope.get(); + + // We're not trying to be sample accurate.. handle the on/off events in a single block. + for (auto event : midiBuffer) + { + const auto message = event.getMessage(); + + if (message.isNoteOn()) + { + for (auto& voice : voices) + { + if (! voice->isActive()) + { + voice->startNote (message.getNoteNumber(), blockThickness, blockEnvelope); + break; + } + } + + continue; + } + + if (message.isNoteOff()) + { + for (auto& voice : voices) + { + if (voice->currentNote == message.getNoteNumber()) + voice->stopNote(); + } + + continue; + } + } + + // Queue up all active voices + for (auto& voice : voices) + if (voice->isActive()) + activeVoices.push_back (voice.get()); + + constexpr auto jobsPerThread = 1; + + // Try and split the voices evenly just for demonstration purposes. + // You could also do some of the work on this thread instead of waiting. + for (int i = 0; i < (int) activeVoices.size();) + { + for (auto worker : workers) + { + if (i >= (int) activeVoices.size()) + break; + + const auto jobCount = jmin (jobsPerThread, (int) activeVoices.size() - i); + i += worker->queueAudioJobs ({ activeVoices.data() + i, (size_t) jobCount }); + } + } + + // kick off the work. + for (auto& worker : workers) + worker->notify(); + + // Wait for our jobs to complete. + barrier->arriveAndWait(); + + // mix the jobs into the main audio thread buffer. + for (auto* voice : activeVoices) + { + buffer.addFrom (0, 0, voice->getWorkBuffer(), 0, 0, buffer.getNumSamples()); + buffer.addFrom (1, 0, voice->getWorkBuffer(), 1, 0, buffer.getNumSamples()); + } + + // Abuse std::vector not reallocating on clear. + activeVoices.clear(); + } + +private: + std::array, 128> voices; + std::vector activeVoices; + + template + using ThreadValue = SharedThreadValue; + + SpinLock paramLock; + ThreadValue envelope { paramLock, { 0.f, 0.3f, 1.f, 0.3f } }; + ThreadValue thickness { paramLock, 1.f }; + + JUCE_DECLARE_NON_COPYABLE (SuperSynth) + JUCE_DECLARE_NON_MOVEABLE (SuperSynth) +}; + +//============================================================================== +class AudioWorkgroupDemo : public Component, + private Timer, + private AudioSource, + private MidiInputCallback +{ +public: + AudioWorkgroupDemo() + { + addAndMakeVisible (keyboardComponent); + addAndMakeVisible (liveAudioDisplayComp); + addAndMakeVisible (envelopeComponent); + addAndMakeVisible (keyboardComponent); + addAndMakeVisible (thicknessSlider); + addAndMakeVisible (voiceCountLabel); + + std::generate (threadLabels.begin(), threadLabels.end(), &std::make_unique