diff --git a/BREAKING_CHANGES.md b/BREAKING_CHANGES.md index 662d54c4354a..7a3331f1573b 100644 --- a/BREAKING_CHANGES.md +++ b/BREAKING_CHANGES.md @@ -1,10 +1,258 @@ # JUCE breaking changes +# develop + +## 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 + +>>>>>>> c74b2b1058 (CIDevice: Improve robustness of subscription API) +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 +CachedValue::operator==() will now emit floating point comparison warnings if they are enabled for the project. **Possible Issues** @@ -20,7 +268,7 @@ CachedValue::get(). **Rationale** -The JUCE Framework now offers the free-standing exactlyEqual() and +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 diff --git a/README.md b/README.md index 7f4e4c23e751..d93ec80d55fb 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,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 diff --git a/docs/CMake API.md b/docs/CMake API.md index 0f6df67e9ca5..bbc1ea1b786a 100644 --- a/docs/CMake API.md +++ b/docs/CMake API.md @@ -2,7 +2,7 @@ ## 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. @@ -144,11 +144,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 +168,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 diff --git a/examples/Audio/CapabilityInquiryDemo.h b/examples/Audio/CapabilityInquiryDemo.h index 46ed2e3a3dd8..5a547ecf6262 100644 --- a/examples/Audio/CapabilityInquiryDemo.h +++ b/examples/Audio/CapabilityInquiryDemo.h @@ -740,14 +740,7 @@ struct Model DeviceInfo info; Profiles profiles; Properties properties; - std::map subscribeIdForResource; - - std::optional getSubscriptionId (const String& resource) const - { - const auto iter = subscribeIdForResource.find (resource); - return iter != subscribeIdForResource.end() ? std::optional (iter->second) - : std::nullopt; - } + std::map subscriptions; template static auto serialise (Archive& archive, This& t) @@ -761,7 +754,7 @@ struct Model auto tie() const { - return std::tie (muid, info, profiles, properties, subscribeIdForResource); + return std::tie (muid, info, profiles, properties, subscriptions); } JUCE_TUPLE_RELATIONAL_OPS (Device) }; @@ -2472,7 +2465,7 @@ class PropertyValuePanel : public Component explicit PropertyValuePanel (State s) : PropertyValuePanel (s, {}) {} - PropertyValuePanel (State s, State> subState) + PropertyValuePanel (State s, State> subState) : state (s), subscriptions (subState) { addAndMakeVisible (value); @@ -2590,13 +2583,13 @@ class PropertyValuePanel : public Component if (const auto* selectedProp = state->properties.getSelected()) { - const auto text = sub.count (selectedProp->name) != 0 ? "Unsubscribe" : "Subscribe"; + const auto text = std::any_of (sub.begin(), sub.end(), [&] (const auto& p) { return p.second.resource == selectedProp->name; }) ? "Unsubscribe" : "Subscribe"; subscribe.setButtonText (text); } } State state; - State> subscriptions; + State> subscriptions; MonospaceEditor value; TextField format; @@ -2970,9 +2963,9 @@ class PropertyEditPanel : public Component { const auto selected = (size_t) state->transient.devices.selection; return state[&Model::App::transient] - [&Model::Transient::devices] - [&Model::ListWithSelection::items] - [selected]; + [&Model::Transient::devices] + [&Model::ListWithSelection::items] + [selected]; } State state; @@ -2980,7 +2973,7 @@ class PropertyEditPanel : public Component PropertyValuePanel value { getDeviceState()[&Model::Device::properties], - getDeviceState()[&Model::Device::subscribeIdForResource] + getDeviceState()[&Model::Device::subscriptions] }; TabbedComponent tabs { TabbedButtonBar::Orientation::TabsAtTop }; }; @@ -3613,7 +3606,8 @@ class LoggingPanel : public Component }); }; -class CapabilityInquiryDemo : public Component +class CapabilityInquiryDemo : public Component, + private Timer { public: CapabilityInquiryDemo() @@ -3667,10 +3661,14 @@ class CapabilityInquiryDemo : public Component { setPropertyPartial (bytes); }; + + startTimer (2'000); } ~CapabilityInquiryDemo() override { + stopTimer(); + // In a production app, it'd be a bit risky to write to a file from a destructor as it's // bad karma to throw an exception inside a destructor! if (auto* userSettings = applicationProperties.getUserSettings()) @@ -3691,6 +3689,12 @@ class CapabilityInquiryDemo : public Component } private: + void timerCallback() override + { + if (device.has_value()) + device->sendPendingMessages(); + } + std::optional> getPropertyRequestInfo() const { auto* selectedDevice = appState->transient.devices.getSelected(); @@ -3860,58 +3864,40 @@ class CapabilityInquiryDemo : public Component const auto& [muid, propName] = *details; - const auto subId = [&, propNameCopy = propName] + // Find the subscription for this resource, if any + const auto existingToken = [&, propNameCopy = propName]() -> std::optional { - const auto ongoing = device->getOngoingSubscriptionsForMuid (selectedDevice->muid); - const auto iter = std::find_if (ongoing.begin(), ongoing.end(), [&] (const auto& sub) - { - return sub.resource == propNameCopy; - }); + const auto ongoing = device->getOngoingSubscriptions(); - return iter != ongoing.end() ? iter->subscribeId : String(); - }(); + for (const auto& o : ongoing) + if (propNameCopy == device->getResourceForKey (o)) + return o; - ci::PropertySubscriptionHeader header; - header.resource = propName; - header.command = subId.isEmpty() ? ci::PropertySubscriptionCommand::start : ci::PropertySubscriptionCommand::end; - header.subscribeId = subId; + return std::nullopt; + }(); - auto callback = [this, - target = muid, - propertyName = propName, - existingSubscription = subId.isNotEmpty()] (const ci::PropertyExchangeResult& response) + // If we're already subscribed, end that subscription. + // Otherwise, begin a new subscription to this resource. + const auto changedToken = [this, + propNameCopy = propName, + muidCopy = muid, + existingTokenCopy = existingToken]() -> std::optional { - if (response.getError().has_value()) - return; - - auto updated = *appState; - - auto& knownDevices = updated.transient.devices.items; - const auto deviceIter = std::find_if (knownDevices.begin(), - knownDevices.end(), - [target] (const auto& d) { return d.muid == target; }); - - if (deviceIter == knownDevices.end()) + // We're not subscribed, so begin a new subscription + if (! existingTokenCopy.has_value()) { - // The device has gone away? - jassertfalse; - return; + ci::PropertySubscriptionHeader header; + header.resource = propNameCopy; + header.command = ci::PropertySubscriptionCommand::start; + return device->beginSubscription (muidCopy, header); } - const auto parsedHeader = response.getHeaderAsSubscriptionHeader(); - - if (parsedHeader.subscribeId.isNotEmpty() && ! existingSubscription) - deviceIter->subscribeIdForResource.emplace (propertyName, parsedHeader.subscribeId); - else - deviceIter->subscribeIdForResource.erase (propertyName); - - appState = std::move (updated); - }; + device->endSubscription (*existingTokenCopy); + return existingTokenCopy; + }(); - if (subId.isEmpty()) - device->sendPropertySubscriptionStart (muid, header, callback); - else - device->sendPropertySubscriptionEnd (muid, subId, callback); + if (changedToken.has_value()) + deviceListener.propertySubscriptionChanged (*changedToken); } template @@ -3973,11 +3959,8 @@ class CapabilityInquiryDemo : public Component header.resource = propertyName; header.mutualEncoding = *encodingToUse; - const auto it = ongoingGetInquiries.insert (ongoingGetInquiries.end(), ErasedScopeGuard{}); - *it = device->sendPropertyGetInquiry (target, header, [this, it, target, propertyName] (const auto& response) + device->sendPropertyGetInquiry (target, header, [this, target, propertyName] (const auto& response) { - ongoingGetInquiries.erase (it); - if (response.getError().has_value()) return; @@ -4088,10 +4071,7 @@ class CapabilityInquiryDemo : public Component else h->addProfile (profileAtAddress, state.supported); - if (state.active == 0) - h->disableProfile (profileAtAddress); - else - h->enableProfile (profileAtAddress, state.active); + h->setProfileEnablement (profileAtAddress, state.active); } } @@ -4116,7 +4096,7 @@ class CapabilityInquiryDemo : public Component header.command = ci::PropertySubscriptionCommand::notify; header.subscribeId = subId; header.resource = propertyName; - host->sendSubscriptionUpdate (receiver, header, {}, {}).release(); + host->sendSubscriptionUpdate (receiver, header, {}, {}); } } } @@ -4351,9 +4331,13 @@ class CapabilityInquiryDemo : public Component { const auto resource = [&] { - for (const auto& [subId, res] : demo.device->getOngoingSubscriptionsForMuid (muid)) - if (subId == subscription.header.subscribeId) - return res; + const auto ongoing = demo.device->getOngoingSubscriptions(); + + for (const auto& o : ongoing) + { + if (subscription.header.subscribeId == demo.device->getSubscribeIdForKey (o)) + return demo.device->getResourceForKey (o).value_or (String{}); + } return String{}; }(); @@ -4366,8 +4350,8 @@ class CapabilityInquiryDemo : public Component } auto devicesState = demo.appState[&Model::App::transient] - [&Model::Transient::devices] - [&Model::ListWithSelection::items]; + [&Model::Transient::devices] + [&Model::ListWithSelection::items]; auto copiedDevices = *devicesState; const auto matchingDevice = [&] @@ -4428,10 +4412,7 @@ class CapabilityInquiryDemo : public Component } case ci::PropertySubscriptionCommand::end: - { - matchingDevice->subscribeIdForResource.erase (resource); break; - } case ci::PropertySubscriptionCommand::start: jassertfalse; @@ -4441,6 +4422,35 @@ class CapabilityInquiryDemo : public Component devicesState = std::move (copiedDevices); } + void propertySubscriptionChanged (ci::SubscriptionKey key, const std::optional&) override + { + propertySubscriptionChanged (key); + } + + void propertySubscriptionChanged (ci::SubscriptionKey key) + { + auto updated = *demo.appState; + + auto& knownDevices = updated.transient.devices.items; + const auto deviceIter = std::find_if (knownDevices.begin(), + knownDevices.end(), + [target = key.getMuid()] (const auto& d) { return d.muid == target; }); + + if (deviceIter == knownDevices.end()) + { + // The device has gone away? + jassertfalse; + return; + } + + if (const auto resource = demo.device->getResourceForKey (key)) + deviceIter->subscriptions.emplace (key, ci::Subscription { demo.device->getSubscribeIdForKey (key).value_or (String{}), *resource }); + else + deviceIter->subscriptions.erase (key); + + demo.appState = std::move (updated); + } + private: void updateProfilesForMuid (ci::MUID muid) { @@ -4589,12 +4599,9 @@ class CapabilityInquiryDemo : public Component if (auto* host = demo.getProfileHost()) { - if (enabled) - host->enableProfile (profileAtAddress, numChannels); - else - host->disableProfile (profileAtAddress); - - profiles.channels[profileAtAddress].active = (uint16_t) numChannels; + const auto count = enabled ? jmax (1, numChannels) : 0; + host->setProfileEnablement (profileAtAddress, count); + profiles.channels[profileAtAddress].active = (uint16_t) count; state = profiles; } @@ -4849,7 +4856,6 @@ class CapabilityInquiryDemo : public Component std::unique_ptr input; std::unique_ptr output; std::optional device; - std::list ongoingGetInquiries; FileChooser fileChooser { "Pick State JSON File", {}, "*.json", true, false, this }; @@ -4881,7 +4887,6 @@ class CapabilityInquiryDemo : public Component .withPropertyDelegate (&propertyDelegate) .withProfileDelegate (&profileDelegate); - ongoingGetInquiries.clear(); device.emplace (options); device->addListener (deviceListener); diff --git a/examples/CMake/AudioPlugin/CMakeLists.txt b/examples/CMake/AudioPlugin/CMakeLists.txt index c808704ed6ef..e20d2e15d848 100644 --- a/examples/CMake/AudioPlugin/CMakeLists.txt +++ b/examples/CMake/AudioPlugin/CMakeLists.txt @@ -8,7 +8,7 @@ # CMake's behaviour is compatible with the named version. This is a standard CMake command, so more # information can be found in the CMake docs. -cmake_minimum_required(VERSION 3.15) +cmake_minimum_required(VERSION 3.22) # The top-level CMakeLists.txt file for a project must contain a literal, direct call to the # `project()` command. `project()` sets up some helpful variables that describe source/binary diff --git a/examples/CMake/ConsoleApp/CMakeLists.txt b/examples/CMake/ConsoleApp/CMakeLists.txt index 690bf09eeecc..1edaa1db76cf 100644 --- a/examples/CMake/ConsoleApp/CMakeLists.txt +++ b/examples/CMake/ConsoleApp/CMakeLists.txt @@ -10,7 +10,7 @@ # CMake's behaviour is compatible with the named version. This is a standard CMake command, so more # information can be found in the CMake docs. -cmake_minimum_required(VERSION 3.15) +cmake_minimum_required(VERSION 3.22) # The top-level CMakeLists.txt file for a project must contain a literal, direct call to the # `project()` command. `project()` sets up some helpful variables that describe source/binary diff --git a/examples/CMake/GuiApp/CMakeLists.txt b/examples/CMake/GuiApp/CMakeLists.txt index fd90b08ada72..03be7abbf90e 100644 --- a/examples/CMake/GuiApp/CMakeLists.txt +++ b/examples/CMake/GuiApp/CMakeLists.txt @@ -9,7 +9,7 @@ # CMake's behaviour is compatible with the named version. This is a standard CMake command, so more # information can be found in the CMake docs. -cmake_minimum_required(VERSION 3.15) +cmake_minimum_required(VERSION 3.22) # The top-level CMakeLists.txt file for a project must contain a literal, direct call to the # `project()` command. `project()` sets up some helpful variables that describe source/binary diff --git a/examples/DemoRunner/Builds/Android/app/CMakeLists.txt b/examples/DemoRunner/Builds/Android/app/CMakeLists.txt index 3c3220e68f09..b76bc1b94bca 100644 --- a/examples/DemoRunner/Builds/Android/app/CMakeLists.txt +++ b/examples/DemoRunner/Builds/Android/app/CMakeLists.txt @@ -192,8 +192,12 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamBuilder.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamCallback.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Definitions.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/FifoBuffer.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/FifoControllerBase.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/FullDuplexStream.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/LatencyTuner.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Oboe.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/OboeExtensions.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/ResultWithValue.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/StabilizedCallback.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Utilities.h" @@ -203,6 +207,8 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AAudioLoader.h" "../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/AdpfWrapper.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/AdpfWrapper.h" "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioClock.h" "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioSourceCaller.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioSourceCaller.h" @@ -221,8 +227,10 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_devices/native/oboe/src/common/LatencyTuner.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/MonotonicCounter.h" "../../../../../modules/juce_audio_devices/native/oboe/src/common/OboeDebug.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/OboeExtensions.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/QuirksManager.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/QuirksManager.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/README.md" "../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceFloatCaller.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceFloatCaller.h" "../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceI16Caller.cpp" @@ -237,11 +245,9 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_devices/native/oboe/src/common/Utilities.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/Version.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.cpp" - "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.h" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoController.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoController.h" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.cpp" - "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.h" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/HyperbolicCosineWindow.h" @@ -258,6 +264,8 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/README.md" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/ResamplerDefinitions.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResamplerStereo.cpp" @@ -269,10 +277,16 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/FlowgraphUtilities.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/Limiter.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/Limiter.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoBlend.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoBlend.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToManyConverter.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToManyConverter.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToMonoConverter.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToMonoConverter.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/RampLinear.cpp" @@ -335,7 +349,9 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_devices/juce_audio_devices.cpp" "../../../../../modules/juce_audio_devices/juce_audio_devices.mm" "../../../../../modules/juce_audio_devices/juce_audio_devices.h" - "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/all.h" + "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/deduplication/bitreader_read_rice_signed_block.c" + "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/deduplication/lpc_compute_autocorrelation_intrin.c" + "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/deduplication/lpc_compute_autocorrelation_intrin_neon.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitmath.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitreader.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitwriter.h" @@ -347,11 +363,9 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/lpc.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/md5.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/memory.h" - "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/metadata.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/stream_encoder.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/stream_encoder_framing.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/window.h" - "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/all.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/stream_decoder.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/stream_encoder.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/bitmath.c" @@ -363,6 +377,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/float.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/format.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/lpc_flac.c" + "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/lpc_intrin_neon.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/md5.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/memory.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/stream_decoder.c" @@ -378,8 +393,10 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_formats/codecs/flac/export.h" "../../../../../modules/juce_audio_formats/codecs/flac/Flac Licence.txt" "../../../../../modules/juce_audio_formats/codecs/flac/format.h" + "../../../../../modules/juce_audio_formats/codecs/flac/JUCE_CHANGES.txt" "../../../../../modules/juce_audio_formats/codecs/flac/metadata.h" "../../../../../modules/juce_audio_formats/codecs/flac/ordinals.h" + "../../../../../modules/juce_audio_formats/codecs/flac/private.h" "../../../../../modules/juce_audio_formats/codecs/flac/stream_decoder.h" "../../../../../modules/juce_audio_formats/codecs/flac/stream_encoder.h" "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/books/coupled/res_books_51.h" @@ -806,8 +823,6 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h" "../../../../../modules/juce_audio_processors/utilities/juce_ExtensionsVisitor.h" "../../../../../modules/juce_audio_processors/utilities/juce_FlagCache.h" - "../../../../../modules/juce_audio_processors/utilities/juce_NativeScaleFactorNotifier.cpp" - "../../../../../modules/juce_audio_processors/utilities/juce_NativeScaleFactorNotifier.h" "../../../../../modules/juce_audio_processors/utilities/juce_ParameterAttachments.cpp" "../../../../../modules/juce_audio_processors/utilities/juce_ParameterAttachments.h" "../../../../../modules/juce_audio_processors/utilities/juce_PluginHostType.cpp" @@ -992,6 +1007,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_core/containers/juce_SparseSet.h" "../../../../../modules/juce_core/containers/juce_Variant.cpp" "../../../../../modules/juce_core/containers/juce_Variant.h" + "../../../../../modules/juce_core/detail/juce_CallbackListenerList.h" "../../../../../modules/juce_core/files/juce_AndroidDocument.h" "../../../../../modules/juce_core/files/juce_common_MimeTypes.cpp" "../../../../../modules/juce_core/files/juce_common_MimeTypes.h" @@ -1053,6 +1069,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_core/memory/juce_Reservoir.h" "../../../../../modules/juce_core/memory/juce_ScopedPointer.h" "../../../../../modules/juce_core/memory/juce_SharedResourcePointer.h" + "../../../../../modules/juce_core/memory/juce_SharedResourcePointer_test.cpp" "../../../../../modules/juce_core/memory/juce_Singleton.h" "../../../../../modules/juce_core/memory/juce_WeakReference.h" "../../../../../modules/juce_core/misc/juce_ConsoleApplication.cpp" @@ -1367,6 +1384,8 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_events/broadcasters/juce_ChangeListener.h" "../../../../../modules/juce_events/broadcasters/juce_LockingAsyncUpdater.cpp" "../../../../../modules/juce_events/broadcasters/juce_LockingAsyncUpdater.h" + "../../../../../modules/juce_events/interprocess/juce_ChildProcessManager.cpp" + "../../../../../modules/juce_events/interprocess/juce_ChildProcessManager.h" "../../../../../modules/juce_events/interprocess/juce_ConnectedChildProcess.cpp" "../../../../../modules/juce_events/interprocess/juce_ConnectedChildProcess.h" "../../../../../modules/juce_events/interprocess/juce_InterprocessConnection.cpp" @@ -1404,6 +1423,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_events/native/juce_WinRTWrapper_windows.h" "../../../../../modules/juce_events/timers/juce_MultiTimer.cpp" "../../../../../modules/juce_events/timers/juce_MultiTimer.h" + "../../../../../modules/juce_events/timers/juce_TimedCallback.h" "../../../../../modules/juce_events/timers/juce_Timer.cpp" "../../../../../modules/juce_events/timers/juce_Timer.h" "../../../../../modules/juce_events/juce_events.cpp" @@ -1935,6 +1955,8 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_gui_basics/windows/juce_MessageBoxOptions.h" "../../../../../modules/juce_gui_basics/windows/juce_NativeMessageBox.cpp" "../../../../../modules/juce_gui_basics/windows/juce_NativeMessageBox.h" + "../../../../../modules/juce_gui_basics/windows/juce_NativeScaleFactorNotifier.cpp" + "../../../../../modules/juce_gui_basics/windows/juce_NativeScaleFactorNotifier.h" "../../../../../modules/juce_gui_basics/windows/juce_ResizableWindow.cpp" "../../../../../modules/juce_gui_basics/windows/juce_ResizableWindow.h" "../../../../../modules/juce_gui_basics/windows/juce_ScopedMessageBox.cpp" @@ -2266,8 +2288,12 @@ set_source_files_properties( "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamBuilder.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamCallback.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Definitions.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/FifoBuffer.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/FifoControllerBase.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/FullDuplexStream.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/LatencyTuner.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Oboe.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/OboeExtensions.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/ResultWithValue.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/StabilizedCallback.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Utilities.h" @@ -2277,6 +2303,8 @@ set_source_files_properties( "../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AAudioLoader.h" "../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/AdpfWrapper.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/AdpfWrapper.h" "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioClock.h" "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioSourceCaller.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioSourceCaller.h" @@ -2295,8 +2323,10 @@ set_source_files_properties( "../../../../../modules/juce_audio_devices/native/oboe/src/common/LatencyTuner.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/MonotonicCounter.h" "../../../../../modules/juce_audio_devices/native/oboe/src/common/OboeDebug.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/OboeExtensions.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/QuirksManager.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/QuirksManager.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/README.md" "../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceFloatCaller.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceFloatCaller.h" "../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceI16Caller.cpp" @@ -2311,11 +2341,9 @@ set_source_files_properties( "../../../../../modules/juce_audio_devices/native/oboe/src/common/Utilities.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/Version.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.cpp" - "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.h" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoController.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoController.h" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.cpp" - "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.h" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/HyperbolicCosineWindow.h" @@ -2332,6 +2360,8 @@ set_source_files_properties( "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/README.md" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/ResamplerDefinitions.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResamplerStereo.cpp" @@ -2343,10 +2373,16 @@ set_source_files_properties( "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/FlowgraphUtilities.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/Limiter.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/Limiter.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoBlend.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoBlend.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToManyConverter.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToManyConverter.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToMonoConverter.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToMonoConverter.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/RampLinear.cpp" @@ -2409,7 +2445,9 @@ set_source_files_properties( "../../../../../modules/juce_audio_devices/juce_audio_devices.cpp" "../../../../../modules/juce_audio_devices/juce_audio_devices.mm" "../../../../../modules/juce_audio_devices/juce_audio_devices.h" - "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/all.h" + "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/deduplication/bitreader_read_rice_signed_block.c" + "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/deduplication/lpc_compute_autocorrelation_intrin.c" + "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/deduplication/lpc_compute_autocorrelation_intrin_neon.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitmath.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitreader.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitwriter.h" @@ -2421,11 +2459,9 @@ set_source_files_properties( "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/lpc.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/md5.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/memory.h" - "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/metadata.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/stream_encoder.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/stream_encoder_framing.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/window.h" - "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/all.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/stream_decoder.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/stream_encoder.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/bitmath.c" @@ -2437,6 +2473,7 @@ set_source_files_properties( "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/float.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/format.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/lpc_flac.c" + "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/lpc_intrin_neon.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/md5.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/memory.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/stream_decoder.c" @@ -2452,8 +2489,10 @@ set_source_files_properties( "../../../../../modules/juce_audio_formats/codecs/flac/export.h" "../../../../../modules/juce_audio_formats/codecs/flac/Flac Licence.txt" "../../../../../modules/juce_audio_formats/codecs/flac/format.h" + "../../../../../modules/juce_audio_formats/codecs/flac/JUCE_CHANGES.txt" "../../../../../modules/juce_audio_formats/codecs/flac/metadata.h" "../../../../../modules/juce_audio_formats/codecs/flac/ordinals.h" + "../../../../../modules/juce_audio_formats/codecs/flac/private.h" "../../../../../modules/juce_audio_formats/codecs/flac/stream_decoder.h" "../../../../../modules/juce_audio_formats/codecs/flac/stream_encoder.h" "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/books/coupled/res_books_51.h" @@ -2880,8 +2919,6 @@ set_source_files_properties( "../../../../../modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h" "../../../../../modules/juce_audio_processors/utilities/juce_ExtensionsVisitor.h" "../../../../../modules/juce_audio_processors/utilities/juce_FlagCache.h" - "../../../../../modules/juce_audio_processors/utilities/juce_NativeScaleFactorNotifier.cpp" - "../../../../../modules/juce_audio_processors/utilities/juce_NativeScaleFactorNotifier.h" "../../../../../modules/juce_audio_processors/utilities/juce_ParameterAttachments.cpp" "../../../../../modules/juce_audio_processors/utilities/juce_ParameterAttachments.h" "../../../../../modules/juce_audio_processors/utilities/juce_PluginHostType.cpp" @@ -3066,6 +3103,7 @@ set_source_files_properties( "../../../../../modules/juce_core/containers/juce_SparseSet.h" "../../../../../modules/juce_core/containers/juce_Variant.cpp" "../../../../../modules/juce_core/containers/juce_Variant.h" + "../../../../../modules/juce_core/detail/juce_CallbackListenerList.h" "../../../../../modules/juce_core/files/juce_AndroidDocument.h" "../../../../../modules/juce_core/files/juce_common_MimeTypes.cpp" "../../../../../modules/juce_core/files/juce_common_MimeTypes.h" @@ -3127,6 +3165,7 @@ set_source_files_properties( "../../../../../modules/juce_core/memory/juce_Reservoir.h" "../../../../../modules/juce_core/memory/juce_ScopedPointer.h" "../../../../../modules/juce_core/memory/juce_SharedResourcePointer.h" + "../../../../../modules/juce_core/memory/juce_SharedResourcePointer_test.cpp" "../../../../../modules/juce_core/memory/juce_Singleton.h" "../../../../../modules/juce_core/memory/juce_WeakReference.h" "../../../../../modules/juce_core/misc/juce_ConsoleApplication.cpp" @@ -3441,6 +3480,8 @@ set_source_files_properties( "../../../../../modules/juce_events/broadcasters/juce_ChangeListener.h" "../../../../../modules/juce_events/broadcasters/juce_LockingAsyncUpdater.cpp" "../../../../../modules/juce_events/broadcasters/juce_LockingAsyncUpdater.h" + "../../../../../modules/juce_events/interprocess/juce_ChildProcessManager.cpp" + "../../../../../modules/juce_events/interprocess/juce_ChildProcessManager.h" "../../../../../modules/juce_events/interprocess/juce_ConnectedChildProcess.cpp" "../../../../../modules/juce_events/interprocess/juce_ConnectedChildProcess.h" "../../../../../modules/juce_events/interprocess/juce_InterprocessConnection.cpp" @@ -3478,6 +3519,7 @@ set_source_files_properties( "../../../../../modules/juce_events/native/juce_WinRTWrapper_windows.h" "../../../../../modules/juce_events/timers/juce_MultiTimer.cpp" "../../../../../modules/juce_events/timers/juce_MultiTimer.h" + "../../../../../modules/juce_events/timers/juce_TimedCallback.h" "../../../../../modules/juce_events/timers/juce_Timer.cpp" "../../../../../modules/juce_events/timers/juce_Timer.h" "../../../../../modules/juce_events/juce_events.cpp" @@ -4009,6 +4051,8 @@ set_source_files_properties( "../../../../../modules/juce_gui_basics/windows/juce_MessageBoxOptions.h" "../../../../../modules/juce_gui_basics/windows/juce_NativeMessageBox.cpp" "../../../../../modules/juce_gui_basics/windows/juce_NativeMessageBox.h" + "../../../../../modules/juce_gui_basics/windows/juce_NativeScaleFactorNotifier.cpp" + "../../../../../modules/juce_gui_basics/windows/juce_NativeScaleFactorNotifier.h" "../../../../../modules/juce_gui_basics/windows/juce_ResizableWindow.cpp" "../../../../../modules/juce_gui_basics/windows/juce_ResizableWindow.h" "../../../../../modules/juce_gui_basics/windows/juce_ScopedMessageBox.cpp" diff --git a/examples/DemoRunner/Builds/LinuxMakefile/Makefile b/examples/DemoRunner/Builds/LinuxMakefile/Makefile index 64e619cc6e10..41c4398f17b3 100644 --- a/examples/DemoRunner/Builds/LinuxMakefile/Makefile +++ b/examples/DemoRunner/Builds/LinuxMakefile/Makefile @@ -47,7 +47,7 @@ ifeq ($(CONFIG),Debug) JUCE_CXXFLAGS += $(JUCE_CFLAGS) -std=c++17 $(CXXFLAGS) JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) $(shell $(PKG_CONFIG) --libs alsa freetype2 gl libcurl) -fvisibility=hidden -lrt -ldl -lpthread $(LDFLAGS) - CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(TARGET) $(JUCE_OBJDIR) + CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(JUCE_TARGET_APP) $(JUCE_OBJDIR) endif ifeq ($(CONFIG),Release) @@ -68,7 +68,7 @@ ifeq ($(CONFIG),Release) JUCE_CXXFLAGS += $(JUCE_CFLAGS) -std=c++17 $(CXXFLAGS) JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) $(shell $(PKG_CONFIG) --libs alsa freetype2 gl libcurl) -fvisibility=hidden -lrt -ldl -lpthread $(LDFLAGS) - CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(TARGET) $(JUCE_OBJDIR) + CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(JUCE_TARGET_APP) $(JUCE_OBJDIR) endif OBJECTS_APP := \ @@ -264,6 +264,6 @@ clean: strip: @echo Stripping DemoRunner - -$(V_AT)$(STRIP) --strip-unneeded $(JUCE_OUTDIR)/$(TARGET) + -$(V_AT)$(STRIP) --strip-unneeded $(JUCE_OUTDIR)/$(JUCE_TARGET_APP) -include $(OBJECTS_APP:%.o=%.d) diff --git a/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj index 8ee50784206e..c823578a8589 100644 --- a/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj +++ b/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj @@ -317,6 +317,9 @@ true + + true + true @@ -344,6 +347,9 @@ true + + true + true @@ -416,12 +422,21 @@ true + + true + true + + true + true + + true + true @@ -527,6 +542,15 @@ true + + true + + + true + + + true + true @@ -554,6 +578,9 @@ true + + true + true @@ -1016,9 +1043,6 @@ true - - true - true @@ -1343,6 +1367,9 @@ true + + true + true @@ -1754,6 +1781,9 @@ true + + true + true @@ -2555,6 +2585,9 @@ true + + true + true @@ -2876,8 +2909,12 @@ + + + + @@ -2885,6 +2922,7 @@ + @@ -2900,9 +2938,7 @@ - - @@ -2912,14 +2948,18 @@ + + + + @@ -2943,7 +2983,6 @@ - @@ -2955,11 +2994,9 @@ - - @@ -2972,6 +3009,7 @@ + @@ -3234,7 +3272,6 @@ - @@ -3326,6 +3363,7 @@ + @@ -3530,6 +3568,7 @@ + @@ -3551,6 +3590,7 @@ + @@ -3808,6 +3848,7 @@ + @@ -3899,9 +3940,12 @@ + + + diff --git a/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj.filters index a8c9a94b9374..b652c98be60c 100644 --- a/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj.filters +++ b/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj.filters @@ -101,6 +101,9 @@ {9A5DB854-CFFB-5F88-C566-0E10F994DDB3} + + {2D16C77A-4E5B-B439-2856-90E03028DA07} + {38A5DDC7-416E-548F-39DA-887875FE6B20} @@ -410,6 +413,9 @@ {42F7BE9D-3C8A-AE26-289B-8F355C068036} + + {4C5ED3D6-28D2-8BFF-F891-96201A9DE159} + {7868764A-6572-381A-906C-9C26792A4C29} @@ -901,6 +907,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\aaudio + + JUCE Modules\juce_audio_devices\native\oboe\src\common + JUCE Modules\juce_audio_devices\native\oboe\src\common @@ -928,6 +937,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\common + + JUCE Modules\juce_audio_devices\native\oboe\src\common + JUCE Modules\juce_audio_devices\native\oboe\src\common @@ -1000,12 +1012,21 @@ JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph @@ -1117,6 +1138,15 @@ JUCE Modules\juce_audio_devices + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\deduplication + + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\deduplication + + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\deduplication + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC @@ -1144,6 +1174,9 @@ JUCE Modules\juce_audio_formats\codecs\flac\libFLAC + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC @@ -1615,9 +1648,6 @@ JUCE Modules\juce_audio_processors\utilities - - JUCE Modules\juce_audio_processors\utilities - JUCE Modules\juce_audio_processors\utilities @@ -1960,6 +1990,9 @@ JUCE Modules\juce_core\memory + + JUCE Modules\juce_core\memory + JUCE Modules\juce_core\misc @@ -2404,6 +2437,9 @@ JUCE Modules\juce_events\broadcasters + + JUCE Modules\juce_events\interprocess + JUCE Modules\juce_events\interprocess @@ -3268,6 +3304,9 @@ JUCE Modules\juce_gui_basics\windows + + JUCE Modules\juce_gui_basics\windows + JUCE Modules\juce_gui_basics\windows @@ -3822,12 +3861,24 @@ JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + JUCE Modules\juce_audio_devices\native\oboe\include\oboe JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + JUCE Modules\juce_audio_devices\native\oboe\include\oboe @@ -3849,6 +3900,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\aaudio + + JUCE Modules\juce_audio_devices\native\oboe\src\common + JUCE Modules\juce_audio_devices\native\oboe\src\common @@ -3894,15 +3948,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\common - - JUCE Modules\juce_audio_devices\native\oboe\src\fifo - JUCE Modules\juce_audio_devices\native\oboe\src\fifo - - JUCE Modules\juce_audio_devices\native\oboe\src\fifo - JUCE Modules\juce_audio_devices\native\oboe\src\fifo @@ -3930,6 +3978,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler @@ -3948,12 +3999,21 @@ JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph @@ -4023,9 +4083,6 @@ JUCE Modules\juce_audio_devices - - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private @@ -4059,9 +4116,6 @@ JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private @@ -4071,9 +4125,6 @@ JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\protected - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\protected @@ -4110,6 +4161,9 @@ JUCE Modules\juce_audio_formats\codecs\flac + + JUCE Modules\juce_audio_formats\codecs\flac + JUCE Modules\juce_audio_formats\codecs\flac @@ -4896,9 +4950,6 @@ JUCE Modules\juce_audio_processors\utilities - - JUCE Modules\juce_audio_processors\utilities - JUCE Modules\juce_audio_processors\utilities @@ -5172,6 +5223,9 @@ JUCE Modules\juce_core\containers + + JUCE Modules\juce_core\detail + JUCE Modules\juce_core\files @@ -5784,6 +5838,9 @@ JUCE Modules\juce_events\broadcasters + + JUCE Modules\juce_events\interprocess + JUCE Modules\juce_events\interprocess @@ -5847,6 +5904,9 @@ JUCE Modules\juce_events\timers + + JUCE Modules\juce_events\timers + JUCE Modules\juce_events\timers @@ -6618,6 +6678,9 @@ JUCE Modules\juce_gui_basics\windows + + JUCE Modules\juce_gui_basics\windows + JUCE Modules\juce_gui_basics\windows @@ -6887,6 +6950,12 @@ DemoRunner\Source + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + JUCE Modules\juce_audio_devices\native\oboe @@ -6896,6 +6965,9 @@ JUCE Modules\juce_audio_formats\codecs\flac + + JUCE Modules\juce_audio_formats\codecs\flac + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7 diff --git a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj index c9aac1f6ecc1..edc139f6d3fe 100644 --- a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj +++ b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj @@ -317,6 +317,9 @@ true + + true + true @@ -344,6 +347,9 @@ true + + true + true @@ -416,12 +422,21 @@ true + + true + true + + true + true + + true + true @@ -527,6 +542,15 @@ true + + true + + + true + + + true + true @@ -554,6 +578,9 @@ true + + true + true @@ -1016,9 +1043,6 @@ true - - true - true @@ -1343,6 +1367,9 @@ true + + true + true @@ -1754,6 +1781,9 @@ true + + true + true @@ -2555,6 +2585,9 @@ true + + true + true @@ -2876,8 +2909,12 @@ + + + + @@ -2885,6 +2922,7 @@ + @@ -2900,9 +2938,7 @@ - - @@ -2912,14 +2948,18 @@ + + + + @@ -2943,7 +2983,6 @@ - @@ -2955,11 +2994,9 @@ - - @@ -2972,6 +3009,7 @@ + @@ -3234,7 +3272,6 @@ - @@ -3326,6 +3363,7 @@ + @@ -3530,6 +3568,7 @@ + @@ -3551,6 +3590,7 @@ + @@ -3808,6 +3848,7 @@ + @@ -3899,9 +3940,12 @@ + + + diff --git a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters index 01cbaff9285f..2ebfa97940f0 100644 --- a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters +++ b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters @@ -101,6 +101,9 @@ {9A5DB854-CFFB-5F88-C566-0E10F994DDB3} + + {2D16C77A-4E5B-B439-2856-90E03028DA07} + {38A5DDC7-416E-548F-39DA-887875FE6B20} @@ -410,6 +413,9 @@ {42F7BE9D-3C8A-AE26-289B-8F355C068036} + + {4C5ED3D6-28D2-8BFF-F891-96201A9DE159} + {7868764A-6572-381A-906C-9C26792A4C29} @@ -901,6 +907,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\aaudio + + JUCE Modules\juce_audio_devices\native\oboe\src\common + JUCE Modules\juce_audio_devices\native\oboe\src\common @@ -928,6 +937,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\common + + JUCE Modules\juce_audio_devices\native\oboe\src\common + JUCE Modules\juce_audio_devices\native\oboe\src\common @@ -1000,12 +1012,21 @@ JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph @@ -1117,6 +1138,15 @@ JUCE Modules\juce_audio_devices + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\deduplication + + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\deduplication + + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\deduplication + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC @@ -1144,6 +1174,9 @@ JUCE Modules\juce_audio_formats\codecs\flac\libFLAC + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC @@ -1615,9 +1648,6 @@ JUCE Modules\juce_audio_processors\utilities - - JUCE Modules\juce_audio_processors\utilities - JUCE Modules\juce_audio_processors\utilities @@ -1960,6 +1990,9 @@ JUCE Modules\juce_core\memory + + JUCE Modules\juce_core\memory + JUCE Modules\juce_core\misc @@ -2404,6 +2437,9 @@ JUCE Modules\juce_events\broadcasters + + JUCE Modules\juce_events\interprocess + JUCE Modules\juce_events\interprocess @@ -3268,6 +3304,9 @@ JUCE Modules\juce_gui_basics\windows + + JUCE Modules\juce_gui_basics\windows + JUCE Modules\juce_gui_basics\windows @@ -3822,12 +3861,24 @@ JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + JUCE Modules\juce_audio_devices\native\oboe\include\oboe JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + JUCE Modules\juce_audio_devices\native\oboe\include\oboe @@ -3849,6 +3900,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\aaudio + + JUCE Modules\juce_audio_devices\native\oboe\src\common + JUCE Modules\juce_audio_devices\native\oboe\src\common @@ -3894,15 +3948,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\common - - JUCE Modules\juce_audio_devices\native\oboe\src\fifo - JUCE Modules\juce_audio_devices\native\oboe\src\fifo - - JUCE Modules\juce_audio_devices\native\oboe\src\fifo - JUCE Modules\juce_audio_devices\native\oboe\src\fifo @@ -3930,6 +3978,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler @@ -3948,12 +3999,21 @@ JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph @@ -4023,9 +4083,6 @@ JUCE Modules\juce_audio_devices - - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private @@ -4059,9 +4116,6 @@ JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private @@ -4071,9 +4125,6 @@ JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\protected - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\protected @@ -4110,6 +4161,9 @@ JUCE Modules\juce_audio_formats\codecs\flac + + JUCE Modules\juce_audio_formats\codecs\flac + JUCE Modules\juce_audio_formats\codecs\flac @@ -4896,9 +4950,6 @@ JUCE Modules\juce_audio_processors\utilities - - JUCE Modules\juce_audio_processors\utilities - JUCE Modules\juce_audio_processors\utilities @@ -5172,6 +5223,9 @@ JUCE Modules\juce_core\containers + + JUCE Modules\juce_core\detail + JUCE Modules\juce_core\files @@ -5784,6 +5838,9 @@ JUCE Modules\juce_events\broadcasters + + JUCE Modules\juce_events\interprocess + JUCE Modules\juce_events\interprocess @@ -5847,6 +5904,9 @@ JUCE Modules\juce_events\timers + + JUCE Modules\juce_events\timers + JUCE Modules\juce_events\timers @@ -6618,6 +6678,9 @@ JUCE Modules\juce_gui_basics\windows + + JUCE Modules\juce_gui_basics\windows + JUCE Modules\juce_gui_basics\windows @@ -6887,6 +6950,12 @@ DemoRunner\Source + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + JUCE Modules\juce_audio_devices\native\oboe @@ -6896,6 +6965,9 @@ JUCE Modules\juce_audio_formats\codecs\flac + + JUCE Modules\juce_audio_formats\codecs\flac + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7 diff --git a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj index a8e079161309..df3f9fcf6a9b 100644 --- a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj +++ b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj @@ -317,6 +317,9 @@ true + + true + true @@ -344,6 +347,9 @@ true + + true + true @@ -416,12 +422,21 @@ true + + true + true + + true + true + + true + true @@ -527,6 +542,15 @@ true + + true + + + true + + + true + true @@ -554,6 +578,9 @@ true + + true + true @@ -1016,9 +1043,6 @@ true - - true - true @@ -1343,6 +1367,9 @@ true + + true + true @@ -1754,6 +1781,9 @@ true + + true + true @@ -2555,6 +2585,9 @@ true + + true + true @@ -2876,8 +2909,12 @@ + + + + @@ -2885,6 +2922,7 @@ + @@ -2900,9 +2938,7 @@ - - @@ -2912,14 +2948,18 @@ + + + + @@ -2943,7 +2983,6 @@ - @@ -2955,11 +2994,9 @@ - - @@ -2972,6 +3009,7 @@ + @@ -3234,7 +3272,6 @@ - @@ -3326,6 +3363,7 @@ + @@ -3530,6 +3568,7 @@ + @@ -3551,6 +3590,7 @@ + @@ -3808,6 +3848,7 @@ + @@ -3899,9 +3940,12 @@ + + + diff --git a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters index f0f14261ef4c..aed569e0e88e 100644 --- a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters +++ b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters @@ -101,6 +101,9 @@ {9A5DB854-CFFB-5F88-C566-0E10F994DDB3} + + {2D16C77A-4E5B-B439-2856-90E03028DA07} + {38A5DDC7-416E-548F-39DA-887875FE6B20} @@ -410,6 +413,9 @@ {42F7BE9D-3C8A-AE26-289B-8F355C068036} + + {4C5ED3D6-28D2-8BFF-F891-96201A9DE159} + {7868764A-6572-381A-906C-9C26792A4C29} @@ -901,6 +907,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\aaudio + + JUCE Modules\juce_audio_devices\native\oboe\src\common + JUCE Modules\juce_audio_devices\native\oboe\src\common @@ -928,6 +937,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\common + + JUCE Modules\juce_audio_devices\native\oboe\src\common + JUCE Modules\juce_audio_devices\native\oboe\src\common @@ -1000,12 +1012,21 @@ JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph @@ -1117,6 +1138,15 @@ JUCE Modules\juce_audio_devices + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\deduplication + + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\deduplication + + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\deduplication + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC @@ -1144,6 +1174,9 @@ JUCE Modules\juce_audio_formats\codecs\flac\libFLAC + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC @@ -1615,9 +1648,6 @@ JUCE Modules\juce_audio_processors\utilities - - JUCE Modules\juce_audio_processors\utilities - JUCE Modules\juce_audio_processors\utilities @@ -1960,6 +1990,9 @@ JUCE Modules\juce_core\memory + + JUCE Modules\juce_core\memory + JUCE Modules\juce_core\misc @@ -2404,6 +2437,9 @@ JUCE Modules\juce_events\broadcasters + + JUCE Modules\juce_events\interprocess + JUCE Modules\juce_events\interprocess @@ -3268,6 +3304,9 @@ JUCE Modules\juce_gui_basics\windows + + JUCE Modules\juce_gui_basics\windows + JUCE Modules\juce_gui_basics\windows @@ -3822,12 +3861,24 @@ JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + JUCE Modules\juce_audio_devices\native\oboe\include\oboe JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + JUCE Modules\juce_audio_devices\native\oboe\include\oboe @@ -3849,6 +3900,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\aaudio + + JUCE Modules\juce_audio_devices\native\oboe\src\common + JUCE Modules\juce_audio_devices\native\oboe\src\common @@ -3894,15 +3948,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\common - - JUCE Modules\juce_audio_devices\native\oboe\src\fifo - JUCE Modules\juce_audio_devices\native\oboe\src\fifo - - JUCE Modules\juce_audio_devices\native\oboe\src\fifo - JUCE Modules\juce_audio_devices\native\oboe\src\fifo @@ -3930,6 +3978,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler @@ -3948,12 +3999,21 @@ JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph @@ -4023,9 +4083,6 @@ JUCE Modules\juce_audio_devices - - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private @@ -4059,9 +4116,6 @@ JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private @@ -4071,9 +4125,6 @@ JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\protected - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\protected @@ -4110,6 +4161,9 @@ JUCE Modules\juce_audio_formats\codecs\flac + + JUCE Modules\juce_audio_formats\codecs\flac + JUCE Modules\juce_audio_formats\codecs\flac @@ -4896,9 +4950,6 @@ JUCE Modules\juce_audio_processors\utilities - - JUCE Modules\juce_audio_processors\utilities - JUCE Modules\juce_audio_processors\utilities @@ -5172,6 +5223,9 @@ JUCE Modules\juce_core\containers + + JUCE Modules\juce_core\detail + JUCE Modules\juce_core\files @@ -5784,6 +5838,9 @@ JUCE Modules\juce_events\broadcasters + + JUCE Modules\juce_events\interprocess + JUCE Modules\juce_events\interprocess @@ -5847,6 +5904,9 @@ JUCE Modules\juce_events\timers + + JUCE Modules\juce_events\timers + JUCE Modules\juce_events\timers @@ -6618,6 +6678,9 @@ JUCE Modules\juce_gui_basics\windows + + JUCE Modules\juce_gui_basics\windows + JUCE Modules\juce_gui_basics\windows @@ -6887,6 +6950,12 @@ DemoRunner\Source + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + JUCE Modules\juce_audio_devices\native\oboe @@ -6896,6 +6965,9 @@ JUCE Modules\juce_audio_formats\codecs\flac + + JUCE Modules\juce_audio_formats\codecs\flac + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7 diff --git a/examples/DemoRunner/Source/UI/MainComponent.cpp b/examples/DemoRunner/Source/UI/MainComponent.cpp index 3428b41b2a75..bc960bc16d50 100644 --- a/examples/DemoRunner/Source/UI/MainComponent.cpp +++ b/examples/DemoRunner/Source/UI/MainComponent.cpp @@ -363,8 +363,10 @@ void MainComponent::resized() { auto bounds = getLocalBounds(); + #if JUCE_IOS || JUCE_ANDROID if (auto* display = Desktop::getInstance().getDisplays().getDisplayForRect (getScreenBounds())) return display->safeAreaInsets.subtractedFrom (display->keyboardInsets.subtractedFrom (bounds)); + #endif return bounds; }(); diff --git a/examples/Plugins/ARAPluginDemo.h b/examples/Plugins/ARAPluginDemo.h index 22baa2de47a0..4589accf40df 100644 --- a/examples/Plugins/ARAPluginDemo.h +++ b/examples/Plugins/ARAPluginDemo.h @@ -515,7 +515,9 @@ class EditorRenderer final : public ARAEditorRenderer, void willRemoveRegionSequence (ARA::PlugIn::RegionSequence* rs) noexcept override { - regionSequences.erase (static_cast (rs)); + auto* rsToRemove = static_cast (rs); + rsToRemove->removeListener (this); + regionSequences.erase (rsToRemove); } void didAddPlaybackRegion (ARA::PlugIn::PlaybackRegion*) noexcept override diff --git a/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt b/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt index 5ab573a09b18..7a72fb9f6191 100644 --- a/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt +++ b/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt @@ -164,8 +164,12 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamBuilder.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamCallback.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Definitions.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/FifoBuffer.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/FifoControllerBase.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/FullDuplexStream.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/LatencyTuner.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Oboe.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/OboeExtensions.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/ResultWithValue.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/StabilizedCallback.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Utilities.h" @@ -175,6 +179,8 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AAudioLoader.h" "../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/AdpfWrapper.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/AdpfWrapper.h" "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioClock.h" "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioSourceCaller.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioSourceCaller.h" @@ -193,8 +199,10 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_devices/native/oboe/src/common/LatencyTuner.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/MonotonicCounter.h" "../../../../../modules/juce_audio_devices/native/oboe/src/common/OboeDebug.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/OboeExtensions.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/QuirksManager.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/QuirksManager.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/README.md" "../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceFloatCaller.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceFloatCaller.h" "../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceI16Caller.cpp" @@ -209,11 +217,9 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_devices/native/oboe/src/common/Utilities.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/Version.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.cpp" - "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.h" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoController.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoController.h" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.cpp" - "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.h" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/HyperbolicCosineWindow.h" @@ -230,6 +236,8 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/README.md" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/ResamplerDefinitions.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResamplerStereo.cpp" @@ -241,10 +249,16 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/FlowgraphUtilities.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/Limiter.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/Limiter.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoBlend.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoBlend.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToManyConverter.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToManyConverter.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToMonoConverter.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToMonoConverter.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/RampLinear.cpp" @@ -307,7 +321,9 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_devices/juce_audio_devices.cpp" "../../../../../modules/juce_audio_devices/juce_audio_devices.mm" "../../../../../modules/juce_audio_devices/juce_audio_devices.h" - "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/all.h" + "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/deduplication/bitreader_read_rice_signed_block.c" + "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/deduplication/lpc_compute_autocorrelation_intrin.c" + "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/deduplication/lpc_compute_autocorrelation_intrin_neon.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitmath.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitreader.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitwriter.h" @@ -319,11 +335,9 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/lpc.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/md5.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/memory.h" - "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/metadata.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/stream_encoder.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/stream_encoder_framing.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/window.h" - "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/all.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/stream_decoder.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/stream_encoder.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/bitmath.c" @@ -335,6 +349,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/float.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/format.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/lpc_flac.c" + "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/lpc_intrin_neon.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/md5.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/memory.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/stream_decoder.c" @@ -350,8 +365,10 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_formats/codecs/flac/export.h" "../../../../../modules/juce_audio_formats/codecs/flac/Flac Licence.txt" "../../../../../modules/juce_audio_formats/codecs/flac/format.h" + "../../../../../modules/juce_audio_formats/codecs/flac/JUCE_CHANGES.txt" "../../../../../modules/juce_audio_formats/codecs/flac/metadata.h" "../../../../../modules/juce_audio_formats/codecs/flac/ordinals.h" + "../../../../../modules/juce_audio_formats/codecs/flac/private.h" "../../../../../modules/juce_audio_formats/codecs/flac/stream_decoder.h" "../../../../../modules/juce_audio_formats/codecs/flac/stream_encoder.h" "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/books/coupled/res_books_51.h" @@ -778,8 +795,6 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h" "../../../../../modules/juce_audio_processors/utilities/juce_ExtensionsVisitor.h" "../../../../../modules/juce_audio_processors/utilities/juce_FlagCache.h" - "../../../../../modules/juce_audio_processors/utilities/juce_NativeScaleFactorNotifier.cpp" - "../../../../../modules/juce_audio_processors/utilities/juce_NativeScaleFactorNotifier.h" "../../../../../modules/juce_audio_processors/utilities/juce_ParameterAttachments.cpp" "../../../../../modules/juce_audio_processors/utilities/juce_ParameterAttachments.h" "../../../../../modules/juce_audio_processors/utilities/juce_PluginHostType.cpp" @@ -868,6 +883,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_core/containers/juce_SparseSet.h" "../../../../../modules/juce_core/containers/juce_Variant.cpp" "../../../../../modules/juce_core/containers/juce_Variant.h" + "../../../../../modules/juce_core/detail/juce_CallbackListenerList.h" "../../../../../modules/juce_core/files/juce_AndroidDocument.h" "../../../../../modules/juce_core/files/juce_common_MimeTypes.cpp" "../../../../../modules/juce_core/files/juce_common_MimeTypes.h" @@ -929,6 +945,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_core/memory/juce_Reservoir.h" "../../../../../modules/juce_core/memory/juce_ScopedPointer.h" "../../../../../modules/juce_core/memory/juce_SharedResourcePointer.h" + "../../../../../modules/juce_core/memory/juce_SharedResourcePointer_test.cpp" "../../../../../modules/juce_core/memory/juce_Singleton.h" "../../../../../modules/juce_core/memory/juce_WeakReference.h" "../../../../../modules/juce_core/misc/juce_ConsoleApplication.cpp" @@ -1146,6 +1163,8 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_events/broadcasters/juce_ChangeListener.h" "../../../../../modules/juce_events/broadcasters/juce_LockingAsyncUpdater.cpp" "../../../../../modules/juce_events/broadcasters/juce_LockingAsyncUpdater.h" + "../../../../../modules/juce_events/interprocess/juce_ChildProcessManager.cpp" + "../../../../../modules/juce_events/interprocess/juce_ChildProcessManager.h" "../../../../../modules/juce_events/interprocess/juce_ConnectedChildProcess.cpp" "../../../../../modules/juce_events/interprocess/juce_ConnectedChildProcess.h" "../../../../../modules/juce_events/interprocess/juce_InterprocessConnection.cpp" @@ -1183,6 +1202,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_events/native/juce_WinRTWrapper_windows.h" "../../../../../modules/juce_events/timers/juce_MultiTimer.cpp" "../../../../../modules/juce_events/timers/juce_MultiTimer.h" + "../../../../../modules/juce_events/timers/juce_TimedCallback.h" "../../../../../modules/juce_events/timers/juce_Timer.cpp" "../../../../../modules/juce_events/timers/juce_Timer.h" "../../../../../modules/juce_events/juce_events.cpp" @@ -1714,6 +1734,8 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_gui_basics/windows/juce_MessageBoxOptions.h" "../../../../../modules/juce_gui_basics/windows/juce_NativeMessageBox.cpp" "../../../../../modules/juce_gui_basics/windows/juce_NativeMessageBox.h" + "../../../../../modules/juce_gui_basics/windows/juce_NativeScaleFactorNotifier.cpp" + "../../../../../modules/juce_gui_basics/windows/juce_NativeScaleFactorNotifier.h" "../../../../../modules/juce_gui_basics/windows/juce_ResizableWindow.cpp" "../../../../../modules/juce_gui_basics/windows/juce_ResizableWindow.h" "../../../../../modules/juce_gui_basics/windows/juce_ScopedMessageBox.cpp" @@ -1938,8 +1960,12 @@ set_source_files_properties( "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamBuilder.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamCallback.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Definitions.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/FifoBuffer.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/FifoControllerBase.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/FullDuplexStream.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/LatencyTuner.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Oboe.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/OboeExtensions.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/ResultWithValue.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/StabilizedCallback.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Utilities.h" @@ -1949,6 +1975,8 @@ set_source_files_properties( "../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AAudioLoader.h" "../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/AdpfWrapper.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/AdpfWrapper.h" "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioClock.h" "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioSourceCaller.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioSourceCaller.h" @@ -1967,8 +1995,10 @@ set_source_files_properties( "../../../../../modules/juce_audio_devices/native/oboe/src/common/LatencyTuner.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/MonotonicCounter.h" "../../../../../modules/juce_audio_devices/native/oboe/src/common/OboeDebug.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/OboeExtensions.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/QuirksManager.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/QuirksManager.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/README.md" "../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceFloatCaller.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceFloatCaller.h" "../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceI16Caller.cpp" @@ -1983,11 +2013,9 @@ set_source_files_properties( "../../../../../modules/juce_audio_devices/native/oboe/src/common/Utilities.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/Version.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.cpp" - "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.h" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoController.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoController.h" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.cpp" - "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.h" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/HyperbolicCosineWindow.h" @@ -2004,6 +2032,8 @@ set_source_files_properties( "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/README.md" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/ResamplerDefinitions.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResamplerStereo.cpp" @@ -2015,10 +2045,16 @@ set_source_files_properties( "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/FlowgraphUtilities.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/Limiter.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/Limiter.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoBlend.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoBlend.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToManyConverter.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToManyConverter.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToMonoConverter.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToMonoConverter.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/RampLinear.cpp" @@ -2081,7 +2117,9 @@ set_source_files_properties( "../../../../../modules/juce_audio_devices/juce_audio_devices.cpp" "../../../../../modules/juce_audio_devices/juce_audio_devices.mm" "../../../../../modules/juce_audio_devices/juce_audio_devices.h" - "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/all.h" + "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/deduplication/bitreader_read_rice_signed_block.c" + "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/deduplication/lpc_compute_autocorrelation_intrin.c" + "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/deduplication/lpc_compute_autocorrelation_intrin_neon.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitmath.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitreader.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitwriter.h" @@ -2093,11 +2131,9 @@ set_source_files_properties( "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/lpc.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/md5.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/memory.h" - "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/metadata.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/stream_encoder.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/stream_encoder_framing.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/window.h" - "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/all.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/stream_decoder.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/stream_encoder.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/bitmath.c" @@ -2109,6 +2145,7 @@ set_source_files_properties( "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/float.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/format.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/lpc_flac.c" + "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/lpc_intrin_neon.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/md5.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/memory.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/stream_decoder.c" @@ -2124,8 +2161,10 @@ set_source_files_properties( "../../../../../modules/juce_audio_formats/codecs/flac/export.h" "../../../../../modules/juce_audio_formats/codecs/flac/Flac Licence.txt" "../../../../../modules/juce_audio_formats/codecs/flac/format.h" + "../../../../../modules/juce_audio_formats/codecs/flac/JUCE_CHANGES.txt" "../../../../../modules/juce_audio_formats/codecs/flac/metadata.h" "../../../../../modules/juce_audio_formats/codecs/flac/ordinals.h" + "../../../../../modules/juce_audio_formats/codecs/flac/private.h" "../../../../../modules/juce_audio_formats/codecs/flac/stream_decoder.h" "../../../../../modules/juce_audio_formats/codecs/flac/stream_encoder.h" "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/books/coupled/res_books_51.h" @@ -2552,8 +2591,6 @@ set_source_files_properties( "../../../../../modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h" "../../../../../modules/juce_audio_processors/utilities/juce_ExtensionsVisitor.h" "../../../../../modules/juce_audio_processors/utilities/juce_FlagCache.h" - "../../../../../modules/juce_audio_processors/utilities/juce_NativeScaleFactorNotifier.cpp" - "../../../../../modules/juce_audio_processors/utilities/juce_NativeScaleFactorNotifier.h" "../../../../../modules/juce_audio_processors/utilities/juce_ParameterAttachments.cpp" "../../../../../modules/juce_audio_processors/utilities/juce_ParameterAttachments.h" "../../../../../modules/juce_audio_processors/utilities/juce_PluginHostType.cpp" @@ -2642,6 +2679,7 @@ set_source_files_properties( "../../../../../modules/juce_core/containers/juce_SparseSet.h" "../../../../../modules/juce_core/containers/juce_Variant.cpp" "../../../../../modules/juce_core/containers/juce_Variant.h" + "../../../../../modules/juce_core/detail/juce_CallbackListenerList.h" "../../../../../modules/juce_core/files/juce_AndroidDocument.h" "../../../../../modules/juce_core/files/juce_common_MimeTypes.cpp" "../../../../../modules/juce_core/files/juce_common_MimeTypes.h" @@ -2703,6 +2741,7 @@ set_source_files_properties( "../../../../../modules/juce_core/memory/juce_Reservoir.h" "../../../../../modules/juce_core/memory/juce_ScopedPointer.h" "../../../../../modules/juce_core/memory/juce_SharedResourcePointer.h" + "../../../../../modules/juce_core/memory/juce_SharedResourcePointer_test.cpp" "../../../../../modules/juce_core/memory/juce_Singleton.h" "../../../../../modules/juce_core/memory/juce_WeakReference.h" "../../../../../modules/juce_core/misc/juce_ConsoleApplication.cpp" @@ -2920,6 +2959,8 @@ set_source_files_properties( "../../../../../modules/juce_events/broadcasters/juce_ChangeListener.h" "../../../../../modules/juce_events/broadcasters/juce_LockingAsyncUpdater.cpp" "../../../../../modules/juce_events/broadcasters/juce_LockingAsyncUpdater.h" + "../../../../../modules/juce_events/interprocess/juce_ChildProcessManager.cpp" + "../../../../../modules/juce_events/interprocess/juce_ChildProcessManager.h" "../../../../../modules/juce_events/interprocess/juce_ConnectedChildProcess.cpp" "../../../../../modules/juce_events/interprocess/juce_ConnectedChildProcess.h" "../../../../../modules/juce_events/interprocess/juce_InterprocessConnection.cpp" @@ -2957,6 +2998,7 @@ set_source_files_properties( "../../../../../modules/juce_events/native/juce_WinRTWrapper_windows.h" "../../../../../modules/juce_events/timers/juce_MultiTimer.cpp" "../../../../../modules/juce_events/timers/juce_MultiTimer.h" + "../../../../../modules/juce_events/timers/juce_TimedCallback.h" "../../../../../modules/juce_events/timers/juce_Timer.cpp" "../../../../../modules/juce_events/timers/juce_Timer.h" "../../../../../modules/juce_events/juce_events.cpp" @@ -3488,6 +3530,8 @@ set_source_files_properties( "../../../../../modules/juce_gui_basics/windows/juce_MessageBoxOptions.h" "../../../../../modules/juce_gui_basics/windows/juce_NativeMessageBox.cpp" "../../../../../modules/juce_gui_basics/windows/juce_NativeMessageBox.h" + "../../../../../modules/juce_gui_basics/windows/juce_NativeScaleFactorNotifier.cpp" + "../../../../../modules/juce_gui_basics/windows/juce_NativeScaleFactorNotifier.h" "../../../../../modules/juce_gui_basics/windows/juce_ResizableWindow.cpp" "../../../../../modules/juce_gui_basics/windows/juce_ResizableWindow.h" "../../../../../modules/juce_gui_basics/windows/juce_ScopedMessageBox.cpp" diff --git a/extras/AudioPerformanceTest/Builds/LinuxMakefile/Makefile b/extras/AudioPerformanceTest/Builds/LinuxMakefile/Makefile index 9e8a33270c39..6adb518be9da 100644 --- a/extras/AudioPerformanceTest/Builds/LinuxMakefile/Makefile +++ b/extras/AudioPerformanceTest/Builds/LinuxMakefile/Makefile @@ -47,7 +47,7 @@ ifeq ($(CONFIG),Debug) JUCE_CXXFLAGS += $(JUCE_CFLAGS) -std=c++17 $(CXXFLAGS) JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) $(shell $(PKG_CONFIG) --libs alsa freetype2 libcurl) -fvisibility=hidden -lrt -ldl -lpthread $(LDFLAGS) - CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(TARGET) $(JUCE_OBJDIR) + CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(JUCE_TARGET_APP) $(JUCE_OBJDIR) endif ifeq ($(CONFIG),Release) @@ -68,7 +68,7 @@ ifeq ($(CONFIG),Release) JUCE_CXXFLAGS += $(JUCE_CFLAGS) -std=c++17 $(CXXFLAGS) JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) $(shell $(PKG_CONFIG) --libs alsa freetype2 libcurl) -fvisibility=hidden -lrt -ldl -lpthread $(LDFLAGS) - CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(TARGET) $(JUCE_OBJDIR) + CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(JUCE_TARGET_APP) $(JUCE_OBJDIR) endif OBJECTS_APP := \ @@ -186,6 +186,6 @@ clean: strip: @echo Stripping AudioPerformanceTest - -$(V_AT)$(STRIP) --strip-unneeded $(JUCE_OUTDIR)/$(TARGET) + -$(V_AT)$(STRIP) --strip-unneeded $(JUCE_OUTDIR)/$(JUCE_TARGET_APP) -include $(OBJECTS_APP:%.o=%.d) diff --git a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj index 5e49818634eb..888360468b40 100644 --- a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj +++ b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj @@ -298,6 +298,9 @@ true + + true + true @@ -325,6 +328,9 @@ true + + true + true @@ -397,12 +403,21 @@ true + + true + true + + true + true + + true + true @@ -508,6 +523,15 @@ true + + true + + + true + + + true + true @@ -535,6 +559,9 @@ true + + true + true @@ -997,9 +1024,6 @@ true - - true - true @@ -1183,6 +1207,9 @@ true + + true + true @@ -1468,6 +1495,9 @@ true + + true + true @@ -2269,6 +2299,9 @@ true + + true + true @@ -2480,8 +2513,12 @@ + + + + @@ -2489,6 +2526,7 @@ + @@ -2504,9 +2542,7 @@ - - @@ -2516,14 +2552,18 @@ + + + + @@ -2547,7 +2587,6 @@ - @@ -2559,11 +2598,9 @@ - - @@ -2576,6 +2613,7 @@ + @@ -2838,7 +2876,6 @@ - @@ -2882,6 +2919,7 @@ + @@ -3033,6 +3071,7 @@ + @@ -3054,6 +3093,7 @@ + @@ -3311,6 +3351,7 @@ + @@ -3350,9 +3391,12 @@ + + + diff --git a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters index d197119a0bae..7189235092de 100644 --- a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters +++ b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters @@ -86,6 +86,9 @@ {9A5DB854-CFFB-5F88-C566-0E10F994DDB3} + + {2D16C77A-4E5B-B439-2856-90E03028DA07} + {38A5DDC7-416E-548F-39DA-887875FE6B20} @@ -365,6 +368,9 @@ {42F7BE9D-3C8A-AE26-289B-8F355C068036} + + {4C5ED3D6-28D2-8BFF-F891-96201A9DE159} + {7868764A-6572-381A-906C-9C26792A4C29} @@ -751,6 +757,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\aaudio + + JUCE Modules\juce_audio_devices\native\oboe\src\common + JUCE Modules\juce_audio_devices\native\oboe\src\common @@ -778,6 +787,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\common + + JUCE Modules\juce_audio_devices\native\oboe\src\common + JUCE Modules\juce_audio_devices\native\oboe\src\common @@ -850,12 +862,21 @@ JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph @@ -967,6 +988,15 @@ JUCE Modules\juce_audio_devices + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\deduplication + + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\deduplication + + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\deduplication + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC @@ -994,6 +1024,9 @@ JUCE Modules\juce_audio_formats\codecs\flac\libFLAC + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC @@ -1465,9 +1498,6 @@ JUCE Modules\juce_audio_processors\utilities - - JUCE Modules\juce_audio_processors\utilities - JUCE Modules\juce_audio_processors\utilities @@ -1669,6 +1699,9 @@ JUCE Modules\juce_core\memory + + JUCE Modules\juce_core\memory + JUCE Modules\juce_core\misc @@ -1981,6 +2014,9 @@ JUCE Modules\juce_events\broadcasters + + JUCE Modules\juce_events\interprocess + JUCE Modules\juce_events\interprocess @@ -2845,6 +2881,9 @@ JUCE Modules\juce_gui_basics\windows + + JUCE Modules\juce_gui_basics\windows + JUCE Modules\juce_gui_basics\windows @@ -3246,12 +3285,24 @@ JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + JUCE Modules\juce_audio_devices\native\oboe\include\oboe JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + JUCE Modules\juce_audio_devices\native\oboe\include\oboe @@ -3273,6 +3324,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\aaudio + + JUCE Modules\juce_audio_devices\native\oboe\src\common + JUCE Modules\juce_audio_devices\native\oboe\src\common @@ -3318,15 +3372,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\common - - JUCE Modules\juce_audio_devices\native\oboe\src\fifo - JUCE Modules\juce_audio_devices\native\oboe\src\fifo - - JUCE Modules\juce_audio_devices\native\oboe\src\fifo - JUCE Modules\juce_audio_devices\native\oboe\src\fifo @@ -3354,6 +3402,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler @@ -3372,12 +3423,21 @@ JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph @@ -3447,9 +3507,6 @@ JUCE Modules\juce_audio_devices - - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private @@ -3483,9 +3540,6 @@ JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private @@ -3495,9 +3549,6 @@ JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\protected - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\protected @@ -3534,6 +3585,9 @@ JUCE Modules\juce_audio_formats\codecs\flac + + JUCE Modules\juce_audio_formats\codecs\flac + JUCE Modules\juce_audio_formats\codecs\flac @@ -4320,9 +4374,6 @@ JUCE Modules\juce_audio_processors\utilities - - JUCE Modules\juce_audio_processors\utilities - JUCE Modules\juce_audio_processors\utilities @@ -4452,6 +4503,9 @@ JUCE Modules\juce_core\containers + + JUCE Modules\juce_core\detail + JUCE Modules\juce_core\files @@ -4905,6 +4959,9 @@ JUCE Modules\juce_events\broadcasters + + JUCE Modules\juce_events\interprocess + JUCE Modules\juce_events\interprocess @@ -4968,6 +5025,9 @@ JUCE Modules\juce_events\timers + + JUCE Modules\juce_events\timers + JUCE Modules\juce_events\timers @@ -5739,6 +5799,9 @@ JUCE Modules\juce_gui_basics\windows + + JUCE Modules\juce_gui_basics\windows + JUCE Modules\juce_gui_basics\windows @@ -5852,6 +5915,12 @@ + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + JUCE Modules\juce_audio_devices\native\oboe @@ -5861,6 +5930,9 @@ JUCE Modules\juce_audio_formats\codecs\flac + + JUCE Modules\juce_audio_formats\codecs\flac + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7 diff --git a/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt b/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt index 979bd601731b..91508a03ab3b 100644 --- a/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt +++ b/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt @@ -197,8 +197,12 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamBuilder.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamCallback.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Definitions.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/FifoBuffer.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/FifoControllerBase.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/FullDuplexStream.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/LatencyTuner.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Oboe.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/OboeExtensions.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/ResultWithValue.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/StabilizedCallback.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Utilities.h" @@ -208,6 +212,8 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AAudioLoader.h" "../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/AdpfWrapper.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/AdpfWrapper.h" "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioClock.h" "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioSourceCaller.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioSourceCaller.h" @@ -226,8 +232,10 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_devices/native/oboe/src/common/LatencyTuner.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/MonotonicCounter.h" "../../../../../modules/juce_audio_devices/native/oboe/src/common/OboeDebug.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/OboeExtensions.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/QuirksManager.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/QuirksManager.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/README.md" "../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceFloatCaller.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceFloatCaller.h" "../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceI16Caller.cpp" @@ -242,11 +250,9 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_devices/native/oboe/src/common/Utilities.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/Version.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.cpp" - "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.h" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoController.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoController.h" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.cpp" - "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.h" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/HyperbolicCosineWindow.h" @@ -263,6 +269,8 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/README.md" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/ResamplerDefinitions.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResamplerStereo.cpp" @@ -274,10 +282,16 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/FlowgraphUtilities.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/Limiter.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/Limiter.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoBlend.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoBlend.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToManyConverter.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToManyConverter.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToMonoConverter.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToMonoConverter.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/RampLinear.cpp" @@ -340,7 +354,9 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_devices/juce_audio_devices.cpp" "../../../../../modules/juce_audio_devices/juce_audio_devices.mm" "../../../../../modules/juce_audio_devices/juce_audio_devices.h" - "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/all.h" + "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/deduplication/bitreader_read_rice_signed_block.c" + "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/deduplication/lpc_compute_autocorrelation_intrin.c" + "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/deduplication/lpc_compute_autocorrelation_intrin_neon.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitmath.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitreader.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitwriter.h" @@ -352,11 +368,9 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/lpc.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/md5.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/memory.h" - "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/metadata.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/stream_encoder.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/stream_encoder_framing.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/window.h" - "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/all.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/stream_decoder.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/stream_encoder.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/bitmath.c" @@ -368,6 +382,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/float.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/format.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/lpc_flac.c" + "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/lpc_intrin_neon.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/md5.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/memory.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/stream_decoder.c" @@ -383,8 +398,10 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_formats/codecs/flac/export.h" "../../../../../modules/juce_audio_formats/codecs/flac/Flac Licence.txt" "../../../../../modules/juce_audio_formats/codecs/flac/format.h" + "../../../../../modules/juce_audio_formats/codecs/flac/JUCE_CHANGES.txt" "../../../../../modules/juce_audio_formats/codecs/flac/metadata.h" "../../../../../modules/juce_audio_formats/codecs/flac/ordinals.h" + "../../../../../modules/juce_audio_formats/codecs/flac/private.h" "../../../../../modules/juce_audio_formats/codecs/flac/stream_decoder.h" "../../../../../modules/juce_audio_formats/codecs/flac/stream_encoder.h" "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/books/coupled/res_books_51.h" @@ -811,8 +828,6 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h" "../../../../../modules/juce_audio_processors/utilities/juce_ExtensionsVisitor.h" "../../../../../modules/juce_audio_processors/utilities/juce_FlagCache.h" - "../../../../../modules/juce_audio_processors/utilities/juce_NativeScaleFactorNotifier.cpp" - "../../../../../modules/juce_audio_processors/utilities/juce_NativeScaleFactorNotifier.h" "../../../../../modules/juce_audio_processors/utilities/juce_ParameterAttachments.cpp" "../../../../../modules/juce_audio_processors/utilities/juce_ParameterAttachments.h" "../../../../../modules/juce_audio_processors/utilities/juce_PluginHostType.cpp" @@ -901,6 +916,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_core/containers/juce_SparseSet.h" "../../../../../modules/juce_core/containers/juce_Variant.cpp" "../../../../../modules/juce_core/containers/juce_Variant.h" + "../../../../../modules/juce_core/detail/juce_CallbackListenerList.h" "../../../../../modules/juce_core/files/juce_AndroidDocument.h" "../../../../../modules/juce_core/files/juce_common_MimeTypes.cpp" "../../../../../modules/juce_core/files/juce_common_MimeTypes.h" @@ -962,6 +978,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_core/memory/juce_Reservoir.h" "../../../../../modules/juce_core/memory/juce_ScopedPointer.h" "../../../../../modules/juce_core/memory/juce_SharedResourcePointer.h" + "../../../../../modules/juce_core/memory/juce_SharedResourcePointer_test.cpp" "../../../../../modules/juce_core/memory/juce_Singleton.h" "../../../../../modules/juce_core/memory/juce_WeakReference.h" "../../../../../modules/juce_core/misc/juce_ConsoleApplication.cpp" @@ -1276,6 +1293,8 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_events/broadcasters/juce_ChangeListener.h" "../../../../../modules/juce_events/broadcasters/juce_LockingAsyncUpdater.cpp" "../../../../../modules/juce_events/broadcasters/juce_LockingAsyncUpdater.h" + "../../../../../modules/juce_events/interprocess/juce_ChildProcessManager.cpp" + "../../../../../modules/juce_events/interprocess/juce_ChildProcessManager.h" "../../../../../modules/juce_events/interprocess/juce_ConnectedChildProcess.cpp" "../../../../../modules/juce_events/interprocess/juce_ConnectedChildProcess.h" "../../../../../modules/juce_events/interprocess/juce_InterprocessConnection.cpp" @@ -1313,6 +1332,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_events/native/juce_WinRTWrapper_windows.h" "../../../../../modules/juce_events/timers/juce_MultiTimer.cpp" "../../../../../modules/juce_events/timers/juce_MultiTimer.h" + "../../../../../modules/juce_events/timers/juce_TimedCallback.h" "../../../../../modules/juce_events/timers/juce_Timer.cpp" "../../../../../modules/juce_events/timers/juce_Timer.h" "../../../../../modules/juce_events/juce_events.cpp" @@ -1844,6 +1864,8 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_gui_basics/windows/juce_MessageBoxOptions.h" "../../../../../modules/juce_gui_basics/windows/juce_NativeMessageBox.cpp" "../../../../../modules/juce_gui_basics/windows/juce_NativeMessageBox.h" + "../../../../../modules/juce_gui_basics/windows/juce_NativeScaleFactorNotifier.cpp" + "../../../../../modules/juce_gui_basics/windows/juce_NativeScaleFactorNotifier.h" "../../../../../modules/juce_gui_basics/windows/juce_ResizableWindow.cpp" "../../../../../modules/juce_gui_basics/windows/juce_ResizableWindow.h" "../../../../../modules/juce_gui_basics/windows/juce_ScopedMessageBox.cpp" @@ -2124,8 +2146,12 @@ set_source_files_properties( "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamBuilder.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamCallback.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Definitions.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/FifoBuffer.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/FifoControllerBase.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/FullDuplexStream.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/LatencyTuner.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Oboe.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/OboeExtensions.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/ResultWithValue.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/StabilizedCallback.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Utilities.h" @@ -2135,6 +2161,8 @@ set_source_files_properties( "../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AAudioLoader.h" "../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/AdpfWrapper.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/AdpfWrapper.h" "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioClock.h" "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioSourceCaller.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioSourceCaller.h" @@ -2153,8 +2181,10 @@ set_source_files_properties( "../../../../../modules/juce_audio_devices/native/oboe/src/common/LatencyTuner.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/MonotonicCounter.h" "../../../../../modules/juce_audio_devices/native/oboe/src/common/OboeDebug.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/OboeExtensions.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/QuirksManager.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/QuirksManager.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/README.md" "../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceFloatCaller.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceFloatCaller.h" "../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceI16Caller.cpp" @@ -2169,11 +2199,9 @@ set_source_files_properties( "../../../../../modules/juce_audio_devices/native/oboe/src/common/Utilities.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/Version.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.cpp" - "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.h" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoController.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoController.h" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.cpp" - "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.h" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/HyperbolicCosineWindow.h" @@ -2190,6 +2218,8 @@ set_source_files_properties( "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/README.md" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/ResamplerDefinitions.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResamplerStereo.cpp" @@ -2201,10 +2231,16 @@ set_source_files_properties( "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/FlowgraphUtilities.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/Limiter.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/Limiter.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoBlend.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoBlend.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToManyConverter.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToManyConverter.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToMonoConverter.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToMonoConverter.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/RampLinear.cpp" @@ -2267,7 +2303,9 @@ set_source_files_properties( "../../../../../modules/juce_audio_devices/juce_audio_devices.cpp" "../../../../../modules/juce_audio_devices/juce_audio_devices.mm" "../../../../../modules/juce_audio_devices/juce_audio_devices.h" - "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/all.h" + "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/deduplication/bitreader_read_rice_signed_block.c" + "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/deduplication/lpc_compute_autocorrelation_intrin.c" + "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/deduplication/lpc_compute_autocorrelation_intrin_neon.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitmath.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitreader.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitwriter.h" @@ -2279,11 +2317,9 @@ set_source_files_properties( "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/lpc.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/md5.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/memory.h" - "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/metadata.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/stream_encoder.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/stream_encoder_framing.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/window.h" - "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/all.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/stream_decoder.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/stream_encoder.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/bitmath.c" @@ -2295,6 +2331,7 @@ set_source_files_properties( "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/float.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/format.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/lpc_flac.c" + "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/lpc_intrin_neon.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/md5.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/memory.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/stream_decoder.c" @@ -2310,8 +2347,10 @@ set_source_files_properties( "../../../../../modules/juce_audio_formats/codecs/flac/export.h" "../../../../../modules/juce_audio_formats/codecs/flac/Flac Licence.txt" "../../../../../modules/juce_audio_formats/codecs/flac/format.h" + "../../../../../modules/juce_audio_formats/codecs/flac/JUCE_CHANGES.txt" "../../../../../modules/juce_audio_formats/codecs/flac/metadata.h" "../../../../../modules/juce_audio_formats/codecs/flac/ordinals.h" + "../../../../../modules/juce_audio_formats/codecs/flac/private.h" "../../../../../modules/juce_audio_formats/codecs/flac/stream_decoder.h" "../../../../../modules/juce_audio_formats/codecs/flac/stream_encoder.h" "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/books/coupled/res_books_51.h" @@ -2738,8 +2777,6 @@ set_source_files_properties( "../../../../../modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h" "../../../../../modules/juce_audio_processors/utilities/juce_ExtensionsVisitor.h" "../../../../../modules/juce_audio_processors/utilities/juce_FlagCache.h" - "../../../../../modules/juce_audio_processors/utilities/juce_NativeScaleFactorNotifier.cpp" - "../../../../../modules/juce_audio_processors/utilities/juce_NativeScaleFactorNotifier.h" "../../../../../modules/juce_audio_processors/utilities/juce_ParameterAttachments.cpp" "../../../../../modules/juce_audio_processors/utilities/juce_ParameterAttachments.h" "../../../../../modules/juce_audio_processors/utilities/juce_PluginHostType.cpp" @@ -2828,6 +2865,7 @@ set_source_files_properties( "../../../../../modules/juce_core/containers/juce_SparseSet.h" "../../../../../modules/juce_core/containers/juce_Variant.cpp" "../../../../../modules/juce_core/containers/juce_Variant.h" + "../../../../../modules/juce_core/detail/juce_CallbackListenerList.h" "../../../../../modules/juce_core/files/juce_AndroidDocument.h" "../../../../../modules/juce_core/files/juce_common_MimeTypes.cpp" "../../../../../modules/juce_core/files/juce_common_MimeTypes.h" @@ -2889,6 +2927,7 @@ set_source_files_properties( "../../../../../modules/juce_core/memory/juce_Reservoir.h" "../../../../../modules/juce_core/memory/juce_ScopedPointer.h" "../../../../../modules/juce_core/memory/juce_SharedResourcePointer.h" + "../../../../../modules/juce_core/memory/juce_SharedResourcePointer_test.cpp" "../../../../../modules/juce_core/memory/juce_Singleton.h" "../../../../../modules/juce_core/memory/juce_WeakReference.h" "../../../../../modules/juce_core/misc/juce_ConsoleApplication.cpp" @@ -3203,6 +3242,8 @@ set_source_files_properties( "../../../../../modules/juce_events/broadcasters/juce_ChangeListener.h" "../../../../../modules/juce_events/broadcasters/juce_LockingAsyncUpdater.cpp" "../../../../../modules/juce_events/broadcasters/juce_LockingAsyncUpdater.h" + "../../../../../modules/juce_events/interprocess/juce_ChildProcessManager.cpp" + "../../../../../modules/juce_events/interprocess/juce_ChildProcessManager.h" "../../../../../modules/juce_events/interprocess/juce_ConnectedChildProcess.cpp" "../../../../../modules/juce_events/interprocess/juce_ConnectedChildProcess.h" "../../../../../modules/juce_events/interprocess/juce_InterprocessConnection.cpp" @@ -3240,6 +3281,7 @@ set_source_files_properties( "../../../../../modules/juce_events/native/juce_WinRTWrapper_windows.h" "../../../../../modules/juce_events/timers/juce_MultiTimer.cpp" "../../../../../modules/juce_events/timers/juce_MultiTimer.h" + "../../../../../modules/juce_events/timers/juce_TimedCallback.h" "../../../../../modules/juce_events/timers/juce_Timer.cpp" "../../../../../modules/juce_events/timers/juce_Timer.h" "../../../../../modules/juce_events/juce_events.cpp" @@ -3771,6 +3813,8 @@ set_source_files_properties( "../../../../../modules/juce_gui_basics/windows/juce_MessageBoxOptions.h" "../../../../../modules/juce_gui_basics/windows/juce_NativeMessageBox.cpp" "../../../../../modules/juce_gui_basics/windows/juce_NativeMessageBox.h" + "../../../../../modules/juce_gui_basics/windows/juce_NativeScaleFactorNotifier.cpp" + "../../../../../modules/juce_gui_basics/windows/juce_NativeScaleFactorNotifier.h" "../../../../../modules/juce_gui_basics/windows/juce_ResizableWindow.cpp" "../../../../../modules/juce_gui_basics/windows/juce_ResizableWindow.h" "../../../../../modules/juce_gui_basics/windows/juce_ScopedMessageBox.cpp" diff --git a/extras/AudioPluginHost/Builds/LinuxMakefile/Makefile b/extras/AudioPluginHost/Builds/LinuxMakefile/Makefile index 45b1ed2e8233..24406dc12ffc 100644 --- a/extras/AudioPluginHost/Builds/LinuxMakefile/Makefile +++ b/extras/AudioPluginHost/Builds/LinuxMakefile/Makefile @@ -47,7 +47,7 @@ ifeq ($(CONFIG),Debug) JUCE_CXXFLAGS += $(JUCE_CFLAGS) -std=c++17 $(CXXFLAGS) JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) $(shell $(PKG_CONFIG) --libs alsa freetype2 gl libcurl) -fvisibility=hidden -lrt -ldl -lpthread $(LDFLAGS) - CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(TARGET) $(JUCE_OBJDIR) + CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(JUCE_TARGET_APP) $(JUCE_OBJDIR) endif ifeq ($(CONFIG),Release) @@ -68,7 +68,7 @@ ifeq ($(CONFIG),Release) JUCE_CXXFLAGS += $(JUCE_CFLAGS) -std=c++17 $(CXXFLAGS) JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) $(shell $(PKG_CONFIG) --libs alsa freetype2 gl libcurl) -fvisibility=hidden -lrt -ldl -lpthread $(LDFLAGS) - CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(TARGET) $(JUCE_OBJDIR) + CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(JUCE_TARGET_APP) $(JUCE_OBJDIR) endif OBJECTS_APP := \ @@ -246,6 +246,6 @@ clean: strip: @echo Stripping AudioPluginHost - -$(V_AT)$(STRIP) --strip-unneeded $(JUCE_OUTDIR)/$(TARGET) + -$(V_AT)$(STRIP) --strip-unneeded $(JUCE_OUTDIR)/$(JUCE_TARGET_APP) -include $(OBJECTS_APP:%.o=%.d) diff --git a/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj index b5438d9056d7..69df81242fb1 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj +++ b/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj @@ -306,6 +306,9 @@ true + + true + true @@ -333,6 +336,9 @@ true + + true + true @@ -405,12 +411,21 @@ true + + true + true + + true + true + + true + true @@ -516,6 +531,15 @@ true + + true + + + true + + + true + true @@ -543,6 +567,9 @@ true + + true + true @@ -1005,9 +1032,6 @@ true - - true - true @@ -1191,6 +1215,9 @@ true + + true + true @@ -1602,6 +1629,9 @@ true + + true + true @@ -2403,6 +2433,9 @@ true + + true + true @@ -2660,8 +2693,12 @@ + + + + @@ -2669,6 +2706,7 @@ + @@ -2684,9 +2722,7 @@ - - @@ -2696,14 +2732,18 @@ + + + + @@ -2727,7 +2767,6 @@ - @@ -2739,11 +2778,9 @@ - - @@ -2756,6 +2793,7 @@ + @@ -3018,7 +3056,6 @@ - @@ -3062,6 +3099,7 @@ + @@ -3266,6 +3304,7 @@ + @@ -3287,6 +3326,7 @@ + @@ -3544,6 +3584,7 @@ + @@ -3616,9 +3657,12 @@ + + + diff --git a/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj.filters index 9cf923552d35..8ed1c7a7ad5c 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj.filters +++ b/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj.filters @@ -95,6 +95,9 @@ {9A5DB854-CFFB-5F88-C566-0E10F994DDB3} + + {2D16C77A-4E5B-B439-2856-90E03028DA07} + {38A5DDC7-416E-548F-39DA-887875FE6B20} @@ -374,6 +377,9 @@ {42F7BE9D-3C8A-AE26-289B-8F355C068036} + + {4C5ED3D6-28D2-8BFF-F891-96201A9DE159} + {7868764A-6572-381A-906C-9C26792A4C29} @@ -826,6 +832,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\aaudio + + JUCE Modules\juce_audio_devices\native\oboe\src\common + JUCE Modules\juce_audio_devices\native\oboe\src\common @@ -853,6 +862,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\common + + JUCE Modules\juce_audio_devices\native\oboe\src\common + JUCE Modules\juce_audio_devices\native\oboe\src\common @@ -925,12 +937,21 @@ JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph @@ -1042,6 +1063,15 @@ JUCE Modules\juce_audio_devices + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\deduplication + + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\deduplication + + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\deduplication + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC @@ -1069,6 +1099,9 @@ JUCE Modules\juce_audio_formats\codecs\flac\libFLAC + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC @@ -1540,9 +1573,6 @@ JUCE Modules\juce_audio_processors\utilities - - JUCE Modules\juce_audio_processors\utilities - JUCE Modules\juce_audio_processors\utilities @@ -1744,6 +1774,9 @@ JUCE Modules\juce_core\memory + + JUCE Modules\juce_core\memory + JUCE Modules\juce_core\misc @@ -2188,6 +2221,9 @@ JUCE Modules\juce_events\broadcasters + + JUCE Modules\juce_events\interprocess + JUCE Modules\juce_events\interprocess @@ -3052,6 +3088,9 @@ JUCE Modules\juce_gui_basics\windows + + JUCE Modules\juce_gui_basics\windows + JUCE Modules\juce_gui_basics\windows @@ -3522,12 +3561,24 @@ JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + JUCE Modules\juce_audio_devices\native\oboe\include\oboe JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + JUCE Modules\juce_audio_devices\native\oboe\include\oboe @@ -3549,6 +3600,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\aaudio + + JUCE Modules\juce_audio_devices\native\oboe\src\common + JUCE Modules\juce_audio_devices\native\oboe\src\common @@ -3594,15 +3648,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\common - - JUCE Modules\juce_audio_devices\native\oboe\src\fifo - JUCE Modules\juce_audio_devices\native\oboe\src\fifo - - JUCE Modules\juce_audio_devices\native\oboe\src\fifo - JUCE Modules\juce_audio_devices\native\oboe\src\fifo @@ -3630,6 +3678,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler @@ -3648,12 +3699,21 @@ JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph @@ -3723,9 +3783,6 @@ JUCE Modules\juce_audio_devices - - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private @@ -3759,9 +3816,6 @@ JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private @@ -3771,9 +3825,6 @@ JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\protected - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\protected @@ -3810,6 +3861,9 @@ JUCE Modules\juce_audio_formats\codecs\flac + + JUCE Modules\juce_audio_formats\codecs\flac + JUCE Modules\juce_audio_formats\codecs\flac @@ -4596,9 +4650,6 @@ JUCE Modules\juce_audio_processors\utilities - - JUCE Modules\juce_audio_processors\utilities - JUCE Modules\juce_audio_processors\utilities @@ -4728,6 +4779,9 @@ JUCE Modules\juce_core\containers + + JUCE Modules\juce_core\detail + JUCE Modules\juce_core\files @@ -5340,6 +5394,9 @@ JUCE Modules\juce_events\broadcasters + + JUCE Modules\juce_events\interprocess + JUCE Modules\juce_events\interprocess @@ -5403,6 +5460,9 @@ JUCE Modules\juce_events\timers + + JUCE Modules\juce_events\timers + JUCE Modules\juce_events\timers @@ -6174,6 +6234,9 @@ JUCE Modules\juce_gui_basics\windows + + JUCE Modules\juce_gui_basics\windows + JUCE Modules\juce_gui_basics\windows @@ -6386,6 +6449,12 @@ AudioPluginHost\BinaryData + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + JUCE Modules\juce_audio_devices\native\oboe @@ -6395,6 +6464,9 @@ JUCE Modules\juce_audio_formats\codecs\flac + + JUCE Modules\juce_audio_formats\codecs\flac + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7 diff --git a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj index 8bd2c78a83fc..9f06930a868d 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj +++ b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj @@ -306,6 +306,9 @@ true + + true + true @@ -333,6 +336,9 @@ true + + true + true @@ -405,12 +411,21 @@ true + + true + true + + true + true + + true + true @@ -516,6 +531,15 @@ true + + true + + + true + + + true + true @@ -543,6 +567,9 @@ true + + true + true @@ -1005,9 +1032,6 @@ true - - true - true @@ -1191,6 +1215,9 @@ true + + true + true @@ -1602,6 +1629,9 @@ true + + true + true @@ -2403,6 +2433,9 @@ true + + true + true @@ -2660,8 +2693,12 @@ + + + + @@ -2669,6 +2706,7 @@ + @@ -2684,9 +2722,7 @@ - - @@ -2696,14 +2732,18 @@ + + + + @@ -2727,7 +2767,6 @@ - @@ -2739,11 +2778,9 @@ - - @@ -2756,6 +2793,7 @@ + @@ -3018,7 +3056,6 @@ - @@ -3062,6 +3099,7 @@ + @@ -3266,6 +3304,7 @@ + @@ -3287,6 +3326,7 @@ + @@ -3544,6 +3584,7 @@ + @@ -3616,9 +3657,12 @@ + + + diff --git a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters index fd4b79c96b2b..85b5efc6471a 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters +++ b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters @@ -95,6 +95,9 @@ {9A5DB854-CFFB-5F88-C566-0E10F994DDB3} + + {2D16C77A-4E5B-B439-2856-90E03028DA07} + {38A5DDC7-416E-548F-39DA-887875FE6B20} @@ -374,6 +377,9 @@ {42F7BE9D-3C8A-AE26-289B-8F355C068036} + + {4C5ED3D6-28D2-8BFF-F891-96201A9DE159} + {7868764A-6572-381A-906C-9C26792A4C29} @@ -826,6 +832,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\aaudio + + JUCE Modules\juce_audio_devices\native\oboe\src\common + JUCE Modules\juce_audio_devices\native\oboe\src\common @@ -853,6 +862,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\common + + JUCE Modules\juce_audio_devices\native\oboe\src\common + JUCE Modules\juce_audio_devices\native\oboe\src\common @@ -925,12 +937,21 @@ JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph @@ -1042,6 +1063,15 @@ JUCE Modules\juce_audio_devices + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\deduplication + + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\deduplication + + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\deduplication + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC @@ -1069,6 +1099,9 @@ JUCE Modules\juce_audio_formats\codecs\flac\libFLAC + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC @@ -1540,9 +1573,6 @@ JUCE Modules\juce_audio_processors\utilities - - JUCE Modules\juce_audio_processors\utilities - JUCE Modules\juce_audio_processors\utilities @@ -1744,6 +1774,9 @@ JUCE Modules\juce_core\memory + + JUCE Modules\juce_core\memory + JUCE Modules\juce_core\misc @@ -2188,6 +2221,9 @@ JUCE Modules\juce_events\broadcasters + + JUCE Modules\juce_events\interprocess + JUCE Modules\juce_events\interprocess @@ -3052,6 +3088,9 @@ JUCE Modules\juce_gui_basics\windows + + JUCE Modules\juce_gui_basics\windows + JUCE Modules\juce_gui_basics\windows @@ -3522,12 +3561,24 @@ JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + JUCE Modules\juce_audio_devices\native\oboe\include\oboe JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + JUCE Modules\juce_audio_devices\native\oboe\include\oboe @@ -3549,6 +3600,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\aaudio + + JUCE Modules\juce_audio_devices\native\oboe\src\common + JUCE Modules\juce_audio_devices\native\oboe\src\common @@ -3594,15 +3648,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\common - - JUCE Modules\juce_audio_devices\native\oboe\src\fifo - JUCE Modules\juce_audio_devices\native\oboe\src\fifo - - JUCE Modules\juce_audio_devices\native\oboe\src\fifo - JUCE Modules\juce_audio_devices\native\oboe\src\fifo @@ -3630,6 +3678,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler @@ -3648,12 +3699,21 @@ JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph @@ -3723,9 +3783,6 @@ JUCE Modules\juce_audio_devices - - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private @@ -3759,9 +3816,6 @@ JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private @@ -3771,9 +3825,6 @@ JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\protected - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\protected @@ -3810,6 +3861,9 @@ JUCE Modules\juce_audio_formats\codecs\flac + + JUCE Modules\juce_audio_formats\codecs\flac + JUCE Modules\juce_audio_formats\codecs\flac @@ -4596,9 +4650,6 @@ JUCE Modules\juce_audio_processors\utilities - - JUCE Modules\juce_audio_processors\utilities - JUCE Modules\juce_audio_processors\utilities @@ -4728,6 +4779,9 @@ JUCE Modules\juce_core\containers + + JUCE Modules\juce_core\detail + JUCE Modules\juce_core\files @@ -5340,6 +5394,9 @@ JUCE Modules\juce_events\broadcasters + + JUCE Modules\juce_events\interprocess + JUCE Modules\juce_events\interprocess @@ -5403,6 +5460,9 @@ JUCE Modules\juce_events\timers + + JUCE Modules\juce_events\timers + JUCE Modules\juce_events\timers @@ -6174,6 +6234,9 @@ JUCE Modules\juce_gui_basics\windows + + JUCE Modules\juce_gui_basics\windows + JUCE Modules\juce_gui_basics\windows @@ -6386,6 +6449,12 @@ AudioPluginHost\BinaryData + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + JUCE Modules\juce_audio_devices\native\oboe @@ -6395,6 +6464,9 @@ JUCE Modules\juce_audio_formats\codecs\flac + + JUCE Modules\juce_audio_formats\codecs\flac + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7 diff --git a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj index f49b44f33a47..122f7efc9927 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj +++ b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj @@ -306,6 +306,9 @@ true + + true + true @@ -333,6 +336,9 @@ true + + true + true @@ -405,12 +411,21 @@ true + + true + true + + true + true + + true + true @@ -516,6 +531,15 @@ true + + true + + + true + + + true + true @@ -543,6 +567,9 @@ true + + true + true @@ -1005,9 +1032,6 @@ true - - true - true @@ -1191,6 +1215,9 @@ true + + true + true @@ -1602,6 +1629,9 @@ true + + true + true @@ -2403,6 +2433,9 @@ true + + true + true @@ -2660,8 +2693,12 @@ + + + + @@ -2669,6 +2706,7 @@ + @@ -2684,9 +2722,7 @@ - - @@ -2696,14 +2732,18 @@ + + + + @@ -2727,7 +2767,6 @@ - @@ -2739,11 +2778,9 @@ - - @@ -2756,6 +2793,7 @@ + @@ -3018,7 +3056,6 @@ - @@ -3062,6 +3099,7 @@ + @@ -3266,6 +3304,7 @@ + @@ -3287,6 +3326,7 @@ + @@ -3544,6 +3584,7 @@ + @@ -3616,9 +3657,12 @@ + + + diff --git a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters index d25cd68b1dfb..ef1344ea23f3 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters +++ b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters @@ -95,6 +95,9 @@ {9A5DB854-CFFB-5F88-C566-0E10F994DDB3} + + {2D16C77A-4E5B-B439-2856-90E03028DA07} + {38A5DDC7-416E-548F-39DA-887875FE6B20} @@ -374,6 +377,9 @@ {42F7BE9D-3C8A-AE26-289B-8F355C068036} + + {4C5ED3D6-28D2-8BFF-F891-96201A9DE159} + {7868764A-6572-381A-906C-9C26792A4C29} @@ -826,6 +832,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\aaudio + + JUCE Modules\juce_audio_devices\native\oboe\src\common + JUCE Modules\juce_audio_devices\native\oboe\src\common @@ -853,6 +862,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\common + + JUCE Modules\juce_audio_devices\native\oboe\src\common + JUCE Modules\juce_audio_devices\native\oboe\src\common @@ -925,12 +937,21 @@ JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph @@ -1042,6 +1063,15 @@ JUCE Modules\juce_audio_devices + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\deduplication + + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\deduplication + + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\deduplication + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC @@ -1069,6 +1099,9 @@ JUCE Modules\juce_audio_formats\codecs\flac\libFLAC + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC @@ -1540,9 +1573,6 @@ JUCE Modules\juce_audio_processors\utilities - - JUCE Modules\juce_audio_processors\utilities - JUCE Modules\juce_audio_processors\utilities @@ -1744,6 +1774,9 @@ JUCE Modules\juce_core\memory + + JUCE Modules\juce_core\memory + JUCE Modules\juce_core\misc @@ -2188,6 +2221,9 @@ JUCE Modules\juce_events\broadcasters + + JUCE Modules\juce_events\interprocess + JUCE Modules\juce_events\interprocess @@ -3052,6 +3088,9 @@ JUCE Modules\juce_gui_basics\windows + + JUCE Modules\juce_gui_basics\windows + JUCE Modules\juce_gui_basics\windows @@ -3522,12 +3561,24 @@ JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + JUCE Modules\juce_audio_devices\native\oboe\include\oboe JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + JUCE Modules\juce_audio_devices\native\oboe\include\oboe @@ -3549,6 +3600,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\aaudio + + JUCE Modules\juce_audio_devices\native\oboe\src\common + JUCE Modules\juce_audio_devices\native\oboe\src\common @@ -3594,15 +3648,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\common - - JUCE Modules\juce_audio_devices\native\oboe\src\fifo - JUCE Modules\juce_audio_devices\native\oboe\src\fifo - - JUCE Modules\juce_audio_devices\native\oboe\src\fifo - JUCE Modules\juce_audio_devices\native\oboe\src\fifo @@ -3630,6 +3678,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler @@ -3648,12 +3699,21 @@ JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph @@ -3723,9 +3783,6 @@ JUCE Modules\juce_audio_devices - - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private @@ -3759,9 +3816,6 @@ JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private @@ -3771,9 +3825,6 @@ JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\protected - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\protected @@ -3810,6 +3861,9 @@ JUCE Modules\juce_audio_formats\codecs\flac + + JUCE Modules\juce_audio_formats\codecs\flac + JUCE Modules\juce_audio_formats\codecs\flac @@ -4596,9 +4650,6 @@ JUCE Modules\juce_audio_processors\utilities - - JUCE Modules\juce_audio_processors\utilities - JUCE Modules\juce_audio_processors\utilities @@ -4728,6 +4779,9 @@ JUCE Modules\juce_core\containers + + JUCE Modules\juce_core\detail + JUCE Modules\juce_core\files @@ -5340,6 +5394,9 @@ JUCE Modules\juce_events\broadcasters + + JUCE Modules\juce_events\interprocess + JUCE Modules\juce_events\interprocess @@ -5403,6 +5460,9 @@ JUCE Modules\juce_events\timers + + JUCE Modules\juce_events\timers + JUCE Modules\juce_events\timers @@ -6174,6 +6234,9 @@ JUCE Modules\juce_gui_basics\windows + + JUCE Modules\juce_gui_basics\windows + JUCE Modules\juce_gui_basics\windows @@ -6386,6 +6449,12 @@ AudioPluginHost\BinaryData + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + JUCE Modules\juce_audio_devices\native\oboe @@ -6395,6 +6464,9 @@ JUCE Modules\juce_audio_formats\codecs\flac + + JUCE Modules\juce_audio_formats\codecs\flac + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7 diff --git a/extras/AudioPluginHost/Source/HostStartup.cpp b/extras/AudioPluginHost/Source/HostStartup.cpp index b3c5e4ba7838..4eae83647d65 100644 --- a/extras/AudioPluginHost/Source/HostStartup.cpp +++ b/extras/AudioPluginHost/Source/HostStartup.cpp @@ -48,13 +48,15 @@ class PluginScannerSubprocess final : private ChildProcessWorker, if (mb.isEmpty()) return; - if (! doScan (mb)) - { - { - const std::lock_guard lock (mutex); - pendingBlocks.emplace (mb); - } + const std::lock_guard lock (mutex); + if (const auto results = doScan (mb); ! results.isEmpty()) + { + sendResults (results); + } + else + { + pendingBlocks.emplace (mb); triggerAsyncUpdate(); } } @@ -68,26 +70,17 @@ class PluginScannerSubprocess final : private ChildProcessWorker, { for (;;) { - const auto block = [&]() -> MemoryBlock - { - const std::lock_guard lock (mutex); - - if (pendingBlocks.empty()) - return {}; + const std::lock_guard lock (mutex); - auto out = std::move (pendingBlocks.front()); - pendingBlocks.pop(); - return out; - }(); - - if (block.isEmpty()) + if (pendingBlocks.empty()) return; - doScan (block); + sendResults (doScan (pendingBlocks.front())); + pendingBlocks.pop(); } } - bool doScan (const MemoryBlock& block) + OwnedArray doScan (const MemoryBlock& block) { MemoryInputStream stream { block, false }; const auto formatName = stream.readString(); @@ -106,20 +99,19 @@ class PluginScannerSubprocess final : private ChildProcessWorker, return nullptr; }(); - if (matchingFormat == nullptr - || (! MessageManager::getInstance()->isThisTheMessageThread() - && ! matchingFormat->requiresUnblockedMessageThreadDuringCreation (pd))) + OwnedArray results; + + if (matchingFormat != nullptr + && (MessageManager::getInstance()->isThisTheMessageThread() + || matchingFormat->requiresUnblockedMessageThreadDuringCreation (pd))) { - return false; + matchingFormat->findAllTypesForFile (results, identifier); } - OwnedArray results; - matchingFormat->findAllTypesForFile (results, identifier); - sendPluginDescriptions (results); - return true; + return results; } - void sendPluginDescriptions (const OwnedArray& results) + void sendResults (const OwnedArray& results) { XmlElement xml ("LIST"); @@ -132,9 +124,6 @@ class PluginScannerSubprocess final : private ChildProcessWorker, std::mutex mutex; std::queue pendingBlocks; - - // After construction, this will only be accessed by doScan so there's no need - // to worry about synchronisation. AudioPluginFormatManager formatManager; }; diff --git a/extras/BinaryBuilder/Builds/LinuxMakefile/Makefile b/extras/BinaryBuilder/Builds/LinuxMakefile/Makefile index fe5674337a19..12f35abde498 100644 --- a/extras/BinaryBuilder/Builds/LinuxMakefile/Makefile +++ b/extras/BinaryBuilder/Builds/LinuxMakefile/Makefile @@ -47,7 +47,7 @@ ifeq ($(CONFIG),Debug) JUCE_CXXFLAGS += $(JUCE_CFLAGS) -std=c++17 $(CXXFLAGS) JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) $(shell $(PKG_CONFIG) --libs libcurl) -fvisibility=hidden -lrt -ldl -lpthread $(LDFLAGS) - CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(TARGET) $(JUCE_OBJDIR) + CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(JUCE_TARGET_CONSOLEAPP) $(JUCE_OBJDIR) endif ifeq ($(CONFIG),Release) @@ -68,7 +68,7 @@ ifeq ($(CONFIG),Release) JUCE_CXXFLAGS += $(JUCE_CFLAGS) -std=c++17 $(CXXFLAGS) JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) $(shell $(PKG_CONFIG) --libs libcurl) -fvisibility=hidden -lrt -ldl -lpthread $(LDFLAGS) - CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(TARGET) $(JUCE_OBJDIR) + CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(JUCE_TARGET_CONSOLEAPP) $(JUCE_OBJDIR) endif OBJECTS_CONSOLEAPP := \ @@ -114,6 +114,6 @@ clean: strip: @echo Stripping BinaryBuilder - -$(V_AT)$(STRIP) --strip-unneeded $(JUCE_OUTDIR)/$(TARGET) + -$(V_AT)$(STRIP) --strip-unneeded $(JUCE_OUTDIR)/$(JUCE_TARGET_CONSOLEAPP) -include $(OBJECTS_CONSOLEAPP:%.o=%.d) diff --git a/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj b/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj index 3a13f2669904..979fd5abe867 100644 --- a/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj +++ b/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj @@ -250,6 +250,9 @@ true + + true + true @@ -520,6 +523,7 @@ + diff --git a/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj.filters b/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj.filters index 66ba5850dd67..b3b761618051 100644 --- a/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj.filters +++ b/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj.filters @@ -11,6 +11,9 @@ {42F7BE9D-3C8A-AE26-289B-8F355C068036} + + {4C5ED3D6-28D2-8BFF-F891-96201A9DE159} + {7868764A-6572-381A-906C-9C26792A4C29} @@ -190,6 +193,9 @@ JUCE Modules\juce_core\memory + + JUCE Modules\juce_core\memory + JUCE Modules\juce_core\misc @@ -528,6 +534,9 @@ JUCE Modules\juce_core\containers + + JUCE Modules\juce_core\detail + JUCE Modules\juce_core\files diff --git a/extras/Build/CMake/JUCEUtils.cmake b/extras/Build/CMake/JUCEUtils.cmake index c1da98713316..0af5e1c3ab4b 100644 --- a/extras/Build/CMake/JUCEUtils.cmake +++ b/extras/Build/CMake/JUCEUtils.cmake @@ -405,6 +405,8 @@ function(juce_add_binary_data target) add_library(${target} STATIC) + set_target_properties(${target} PROPERTIES POSITION_INDEPENDENT_CODE TRUE) + set(juce_binary_data_folder "${CMAKE_CURRENT_BINARY_DIR}/juce_binarydata_${target}/JuceLibraryCode") set(binary_file_names) @@ -1057,7 +1059,6 @@ function(juce_enable_vst3_manifest_step shared_code_target) # Use the helper tool to write out the moduleinfo.json add_custom_command(TARGET ${target_name} POST_BUILD - COMMAND ${CMAKE_COMMAND} -E remove -f "${product}/Contents/moduleinfo.json" COMMAND ${CMAKE_COMMAND} -E make_directory "${product}/Contents/Resources" COMMAND juce_vst3_helper -create @@ -1116,6 +1117,12 @@ function(_juce_set_plugin_target_properties shared_code_target kind) get_target_property(vst3_auto_manifest ${shared_code_target} JUCE_VST3_AUTO_MANIFEST) + add_custom_command(TARGET ${target_name} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E echo "removing moduleinfo.json" + COMMAND ${CMAKE_COMMAND} -E remove -f + "${output_path}/Contents/moduleinfo.json" + "${output_path}/Contents/Resources/moduleinfo.json") + if(vst3_auto_manifest) juce_enable_vst3_manifest_step(${shared_code_target}) endif() @@ -1989,6 +1996,7 @@ function(juce_add_console_app target) endif() _juce_initialise_target(${target} ${ARGN}) + _juce_set_output_name(${target} $) if(NOT JUCE_ARG__NO_RESOURCERC) _juce_write_configure_time_info(${target}) diff --git a/extras/Build/juce_build_tools/utils/juce_RelativePath.h b/extras/Build/juce_build_tools/utils/juce_RelativePath.h index 0782845757f0..7a62768ae1f3 100644 --- a/extras/Build/juce_build_tools/utils/juce_RelativePath.h +++ b/extras/Build/juce_build_tools/utils/juce_RelativePath.h @@ -107,21 +107,12 @@ namespace juce::build_tools File getFakeFile() const { - #if JUCE_WINDOWS - if (isAbsolutePath (path)) - { - // This is a hack to convert unix-style absolute paths into valid absolute Windows paths to avoid hitting - // an assertion in File::parseAbsolutePath(). - if (path.startsWithChar (L'/') || path.startsWithChar (L'$') || path.startsWithChar (L'~')) - return File (String ("C:\\") + windowsStylePath (path.substring (1))); - - return File (path); - } - #endif + const auto unixStylePath = toUnixStyle(); + const auto name = unixStylePath.substring (unixStylePath.lastIndexOfChar ('/') + 1); // This method gets called very often, so we'll cache this directory. static const File currentWorkingDirectory (File::getCurrentWorkingDirectory()); - return currentWorkingDirectory.getChildFile (path); + return currentWorkingDirectory.getChildFile (name); } }; diff --git a/extras/Build/juceaide/Main.cpp b/extras/Build/juceaide/Main.cpp index 63f7140a3240..32ba1c7db181 100644 --- a/extras/Build/juceaide/Main.cpp +++ b/extras/Build/juceaide/Main.cpp @@ -570,5 +570,13 @@ int main (int argc, char** argv) { juce::ConsoleApplication::fail (error.message); } + catch (const std::exception& ex) + { + juce::ConsoleApplication::fail (ex.what()); + } + catch (...) + { + juce::ConsoleApplication::fail ("Unhandled exception"); + } }); } diff --git a/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt b/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt index 17f9ecf35aa8..d75c548634a4 100644 --- a/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt +++ b/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt @@ -168,8 +168,12 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamBuilder.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamCallback.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Definitions.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/FifoBuffer.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/FifoControllerBase.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/FullDuplexStream.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/LatencyTuner.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Oboe.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/OboeExtensions.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/ResultWithValue.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/StabilizedCallback.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Utilities.h" @@ -179,6 +183,8 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AAudioLoader.h" "../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/AdpfWrapper.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/AdpfWrapper.h" "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioClock.h" "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioSourceCaller.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioSourceCaller.h" @@ -197,8 +203,10 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_devices/native/oboe/src/common/LatencyTuner.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/MonotonicCounter.h" "../../../../../modules/juce_audio_devices/native/oboe/src/common/OboeDebug.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/OboeExtensions.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/QuirksManager.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/QuirksManager.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/README.md" "../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceFloatCaller.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceFloatCaller.h" "../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceI16Caller.cpp" @@ -213,11 +221,9 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_devices/native/oboe/src/common/Utilities.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/Version.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.cpp" - "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.h" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoController.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoController.h" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.cpp" - "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.h" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/HyperbolicCosineWindow.h" @@ -234,6 +240,8 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/README.md" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/ResamplerDefinitions.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResamplerStereo.cpp" @@ -245,10 +253,16 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/FlowgraphUtilities.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/Limiter.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/Limiter.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoBlend.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoBlend.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToManyConverter.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToManyConverter.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToMonoConverter.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToMonoConverter.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/RampLinear.cpp" @@ -311,7 +325,9 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_devices/juce_audio_devices.cpp" "../../../../../modules/juce_audio_devices/juce_audio_devices.mm" "../../../../../modules/juce_audio_devices/juce_audio_devices.h" - "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/all.h" + "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/deduplication/bitreader_read_rice_signed_block.c" + "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/deduplication/lpc_compute_autocorrelation_intrin.c" + "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/deduplication/lpc_compute_autocorrelation_intrin_neon.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitmath.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitreader.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitwriter.h" @@ -323,11 +339,9 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/lpc.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/md5.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/memory.h" - "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/metadata.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/stream_encoder.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/stream_encoder_framing.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/window.h" - "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/all.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/stream_decoder.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/stream_encoder.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/bitmath.c" @@ -339,6 +353,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/float.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/format.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/lpc_flac.c" + "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/lpc_intrin_neon.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/md5.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/memory.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/stream_decoder.c" @@ -354,8 +369,10 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_formats/codecs/flac/export.h" "../../../../../modules/juce_audio_formats/codecs/flac/Flac Licence.txt" "../../../../../modules/juce_audio_formats/codecs/flac/format.h" + "../../../../../modules/juce_audio_formats/codecs/flac/JUCE_CHANGES.txt" "../../../../../modules/juce_audio_formats/codecs/flac/metadata.h" "../../../../../modules/juce_audio_formats/codecs/flac/ordinals.h" + "../../../../../modules/juce_audio_formats/codecs/flac/private.h" "../../../../../modules/juce_audio_formats/codecs/flac/stream_decoder.h" "../../../../../modules/juce_audio_formats/codecs/flac/stream_encoder.h" "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/books/coupled/res_books_51.h" @@ -782,8 +799,6 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h" "../../../../../modules/juce_audio_processors/utilities/juce_ExtensionsVisitor.h" "../../../../../modules/juce_audio_processors/utilities/juce_FlagCache.h" - "../../../../../modules/juce_audio_processors/utilities/juce_NativeScaleFactorNotifier.cpp" - "../../../../../modules/juce_audio_processors/utilities/juce_NativeScaleFactorNotifier.h" "../../../../../modules/juce_audio_processors/utilities/juce_ParameterAttachments.cpp" "../../../../../modules/juce_audio_processors/utilities/juce_ParameterAttachments.h" "../../../../../modules/juce_audio_processors/utilities/juce_PluginHostType.cpp" @@ -872,6 +887,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_core/containers/juce_SparseSet.h" "../../../../../modules/juce_core/containers/juce_Variant.cpp" "../../../../../modules/juce_core/containers/juce_Variant.h" + "../../../../../modules/juce_core/detail/juce_CallbackListenerList.h" "../../../../../modules/juce_core/files/juce_AndroidDocument.h" "../../../../../modules/juce_core/files/juce_common_MimeTypes.cpp" "../../../../../modules/juce_core/files/juce_common_MimeTypes.h" @@ -933,6 +949,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_core/memory/juce_Reservoir.h" "../../../../../modules/juce_core/memory/juce_ScopedPointer.h" "../../../../../modules/juce_core/memory/juce_SharedResourcePointer.h" + "../../../../../modules/juce_core/memory/juce_SharedResourcePointer_test.cpp" "../../../../../modules/juce_core/memory/juce_Singleton.h" "../../../../../modules/juce_core/memory/juce_WeakReference.h" "../../../../../modules/juce_core/misc/juce_ConsoleApplication.cpp" @@ -1165,6 +1182,8 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_events/broadcasters/juce_ChangeListener.h" "../../../../../modules/juce_events/broadcasters/juce_LockingAsyncUpdater.cpp" "../../../../../modules/juce_events/broadcasters/juce_LockingAsyncUpdater.h" + "../../../../../modules/juce_events/interprocess/juce_ChildProcessManager.cpp" + "../../../../../modules/juce_events/interprocess/juce_ChildProcessManager.h" "../../../../../modules/juce_events/interprocess/juce_ConnectedChildProcess.cpp" "../../../../../modules/juce_events/interprocess/juce_ConnectedChildProcess.h" "../../../../../modules/juce_events/interprocess/juce_InterprocessConnection.cpp" @@ -1202,6 +1221,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_events/native/juce_WinRTWrapper_windows.h" "../../../../../modules/juce_events/timers/juce_MultiTimer.cpp" "../../../../../modules/juce_events/timers/juce_MultiTimer.h" + "../../../../../modules/juce_events/timers/juce_TimedCallback.h" "../../../../../modules/juce_events/timers/juce_Timer.cpp" "../../../../../modules/juce_events/timers/juce_Timer.h" "../../../../../modules/juce_events/juce_events.cpp" @@ -1733,6 +1753,8 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_gui_basics/windows/juce_MessageBoxOptions.h" "../../../../../modules/juce_gui_basics/windows/juce_NativeMessageBox.cpp" "../../../../../modules/juce_gui_basics/windows/juce_NativeMessageBox.h" + "../../../../../modules/juce_gui_basics/windows/juce_NativeScaleFactorNotifier.cpp" + "../../../../../modules/juce_gui_basics/windows/juce_NativeScaleFactorNotifier.h" "../../../../../modules/juce_gui_basics/windows/juce_ResizableWindow.cpp" "../../../../../modules/juce_gui_basics/windows/juce_ResizableWindow.h" "../../../../../modules/juce_gui_basics/windows/juce_ScopedMessageBox.cpp" @@ -2022,8 +2044,12 @@ set_source_files_properties( "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamBuilder.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamCallback.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Definitions.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/FifoBuffer.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/FifoControllerBase.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/FullDuplexStream.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/LatencyTuner.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Oboe.h" + "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/OboeExtensions.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/ResultWithValue.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/StabilizedCallback.h" "../../../../../modules/juce_audio_devices/native/oboe/include/oboe/Utilities.h" @@ -2033,6 +2059,8 @@ set_source_files_properties( "../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AAudioLoader.h" "../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/AdpfWrapper.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/AdpfWrapper.h" "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioClock.h" "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioSourceCaller.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/AudioSourceCaller.h" @@ -2051,8 +2079,10 @@ set_source_files_properties( "../../../../../modules/juce_audio_devices/native/oboe/src/common/LatencyTuner.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/MonotonicCounter.h" "../../../../../modules/juce_audio_devices/native/oboe/src/common/OboeDebug.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/OboeExtensions.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/QuirksManager.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/QuirksManager.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/common/README.md" "../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceFloatCaller.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceFloatCaller.h" "../../../../../modules/juce_audio_devices/native/oboe/src/common/SourceI16Caller.cpp" @@ -2067,11 +2097,9 @@ set_source_files_properties( "../../../../../modules/juce_audio_devices/native/oboe/src/common/Utilities.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/common/Version.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.cpp" - "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.h" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoController.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoController.h" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.cpp" - "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.h" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/HyperbolicCosineWindow.h" @@ -2088,6 +2116,8 @@ set_source_files_properties( "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/README.md" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/ResamplerDefinitions.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResamplerStereo.cpp" @@ -2099,10 +2129,16 @@ set_source_files_properties( "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/FlowgraphUtilities.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/Limiter.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/Limiter.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoBlend.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoBlend.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.h" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToManyConverter.cpp" + "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToManyConverter.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToMonoConverter.cpp" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToMonoConverter.h" "../../../../../modules/juce_audio_devices/native/oboe/src/flowgraph/RampLinear.cpp" @@ -2165,7 +2201,9 @@ set_source_files_properties( "../../../../../modules/juce_audio_devices/juce_audio_devices.cpp" "../../../../../modules/juce_audio_devices/juce_audio_devices.mm" "../../../../../modules/juce_audio_devices/juce_audio_devices.h" - "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/all.h" + "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/deduplication/bitreader_read_rice_signed_block.c" + "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/deduplication/lpc_compute_autocorrelation_intrin.c" + "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/deduplication/lpc_compute_autocorrelation_intrin_neon.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitmath.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitreader.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitwriter.h" @@ -2177,11 +2215,9 @@ set_source_files_properties( "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/lpc.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/md5.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/memory.h" - "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/metadata.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/stream_encoder.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/stream_encoder_framing.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/private/window.h" - "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/all.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/stream_decoder.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/stream_encoder.h" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/bitmath.c" @@ -2193,6 +2229,7 @@ set_source_files_properties( "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/float.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/format.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/lpc_flac.c" + "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/lpc_intrin_neon.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/md5.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/memory.c" "../../../../../modules/juce_audio_formats/codecs/flac/libFLAC/stream_decoder.c" @@ -2208,8 +2245,10 @@ set_source_files_properties( "../../../../../modules/juce_audio_formats/codecs/flac/export.h" "../../../../../modules/juce_audio_formats/codecs/flac/Flac Licence.txt" "../../../../../modules/juce_audio_formats/codecs/flac/format.h" + "../../../../../modules/juce_audio_formats/codecs/flac/JUCE_CHANGES.txt" "../../../../../modules/juce_audio_formats/codecs/flac/metadata.h" "../../../../../modules/juce_audio_formats/codecs/flac/ordinals.h" + "../../../../../modules/juce_audio_formats/codecs/flac/private.h" "../../../../../modules/juce_audio_formats/codecs/flac/stream_decoder.h" "../../../../../modules/juce_audio_formats/codecs/flac/stream_encoder.h" "../../../../../modules/juce_audio_formats/codecs/oggvorbis/libvorbis-1.3.7/lib/books/coupled/res_books_51.h" @@ -2636,8 +2675,6 @@ set_source_files_properties( "../../../../../modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.h" "../../../../../modules/juce_audio_processors/utilities/juce_ExtensionsVisitor.h" "../../../../../modules/juce_audio_processors/utilities/juce_FlagCache.h" - "../../../../../modules/juce_audio_processors/utilities/juce_NativeScaleFactorNotifier.cpp" - "../../../../../modules/juce_audio_processors/utilities/juce_NativeScaleFactorNotifier.h" "../../../../../modules/juce_audio_processors/utilities/juce_ParameterAttachments.cpp" "../../../../../modules/juce_audio_processors/utilities/juce_ParameterAttachments.h" "../../../../../modules/juce_audio_processors/utilities/juce_PluginHostType.cpp" @@ -2726,6 +2763,7 @@ set_source_files_properties( "../../../../../modules/juce_core/containers/juce_SparseSet.h" "../../../../../modules/juce_core/containers/juce_Variant.cpp" "../../../../../modules/juce_core/containers/juce_Variant.h" + "../../../../../modules/juce_core/detail/juce_CallbackListenerList.h" "../../../../../modules/juce_core/files/juce_AndroidDocument.h" "../../../../../modules/juce_core/files/juce_common_MimeTypes.cpp" "../../../../../modules/juce_core/files/juce_common_MimeTypes.h" @@ -2787,6 +2825,7 @@ set_source_files_properties( "../../../../../modules/juce_core/memory/juce_Reservoir.h" "../../../../../modules/juce_core/memory/juce_ScopedPointer.h" "../../../../../modules/juce_core/memory/juce_SharedResourcePointer.h" + "../../../../../modules/juce_core/memory/juce_SharedResourcePointer_test.cpp" "../../../../../modules/juce_core/memory/juce_Singleton.h" "../../../../../modules/juce_core/memory/juce_WeakReference.h" "../../../../../modules/juce_core/misc/juce_ConsoleApplication.cpp" @@ -3019,6 +3058,8 @@ set_source_files_properties( "../../../../../modules/juce_events/broadcasters/juce_ChangeListener.h" "../../../../../modules/juce_events/broadcasters/juce_LockingAsyncUpdater.cpp" "../../../../../modules/juce_events/broadcasters/juce_LockingAsyncUpdater.h" + "../../../../../modules/juce_events/interprocess/juce_ChildProcessManager.cpp" + "../../../../../modules/juce_events/interprocess/juce_ChildProcessManager.h" "../../../../../modules/juce_events/interprocess/juce_ConnectedChildProcess.cpp" "../../../../../modules/juce_events/interprocess/juce_ConnectedChildProcess.h" "../../../../../modules/juce_events/interprocess/juce_InterprocessConnection.cpp" @@ -3056,6 +3097,7 @@ set_source_files_properties( "../../../../../modules/juce_events/native/juce_WinRTWrapper_windows.h" "../../../../../modules/juce_events/timers/juce_MultiTimer.cpp" "../../../../../modules/juce_events/timers/juce_MultiTimer.h" + "../../../../../modules/juce_events/timers/juce_TimedCallback.h" "../../../../../modules/juce_events/timers/juce_Timer.cpp" "../../../../../modules/juce_events/timers/juce_Timer.h" "../../../../../modules/juce_events/juce_events.cpp" @@ -3587,6 +3629,8 @@ set_source_files_properties( "../../../../../modules/juce_gui_basics/windows/juce_MessageBoxOptions.h" "../../../../../modules/juce_gui_basics/windows/juce_NativeMessageBox.cpp" "../../../../../modules/juce_gui_basics/windows/juce_NativeMessageBox.h" + "../../../../../modules/juce_gui_basics/windows/juce_NativeScaleFactorNotifier.cpp" + "../../../../../modules/juce_gui_basics/windows/juce_NativeScaleFactorNotifier.h" "../../../../../modules/juce_gui_basics/windows/juce_ResizableWindow.cpp" "../../../../../modules/juce_gui_basics/windows/juce_ResizableWindow.h" "../../../../../modules/juce_gui_basics/windows/juce_ScopedMessageBox.cpp" diff --git a/extras/NetworkGraphicsDemo/Builds/LinuxMakefile/Makefile b/extras/NetworkGraphicsDemo/Builds/LinuxMakefile/Makefile index cae2e3042693..351ffb7623b3 100644 --- a/extras/NetworkGraphicsDemo/Builds/LinuxMakefile/Makefile +++ b/extras/NetworkGraphicsDemo/Builds/LinuxMakefile/Makefile @@ -47,7 +47,7 @@ ifeq ($(CONFIG),Debug) JUCE_CXXFLAGS += $(JUCE_CFLAGS) -std=c++17 $(CXXFLAGS) JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) $(shell $(PKG_CONFIG) --libs alsa freetype2 gl libcurl) -fvisibility=hidden -lrt -ldl -lpthread $(LDFLAGS) - CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(TARGET) $(JUCE_OBJDIR) + CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(JUCE_TARGET_APP) $(JUCE_OBJDIR) endif ifeq ($(CONFIG),Release) @@ -68,7 +68,7 @@ ifeq ($(CONFIG),Release) JUCE_CXXFLAGS += $(JUCE_CFLAGS) -std=c++17 $(CXXFLAGS) JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) $(shell $(PKG_CONFIG) --libs alsa freetype2 gl libcurl) -fvisibility=hidden -lrt -ldl -lpthread $(LDFLAGS) - CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(TARGET) $(JUCE_OBJDIR) + CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(JUCE_TARGET_APP) $(JUCE_OBJDIR) endif OBJECTS_APP := \ @@ -210,6 +210,6 @@ clean: strip: @echo Stripping NetworkGraphicsDemo - -$(V_AT)$(STRIP) --strip-unneeded $(JUCE_OUTDIR)/$(TARGET) + -$(V_AT)$(STRIP) --strip-unneeded $(JUCE_OUTDIR)/$(JUCE_TARGET_APP) -include $(OBJECTS_APP:%.o=%.d) diff --git a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj index 2c2f94735952..f62032925475 100644 --- a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj +++ b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj @@ -298,6 +298,9 @@ true + + true + true @@ -325,6 +328,9 @@ true + + true + true @@ -397,12 +403,21 @@ true + + true + true + + true + true + + true + true @@ -508,6 +523,15 @@ true + + true + + + true + + + true + true @@ -535,6 +559,9 @@ true + + true + true @@ -997,9 +1024,6 @@ true - - true - true @@ -1183,6 +1207,9 @@ true + + true + true @@ -1489,6 +1516,9 @@ true + + true + true @@ -2290,6 +2320,9 @@ true + + true + true @@ -2571,8 +2604,12 @@ + + + + @@ -2580,6 +2617,7 @@ + @@ -2595,9 +2633,7 @@ - - @@ -2607,14 +2643,18 @@ + + + + @@ -2638,7 +2678,6 @@ - @@ -2650,11 +2689,9 @@ - - @@ -2667,6 +2704,7 @@ + @@ -2929,7 +2967,6 @@ - @@ -2973,6 +3010,7 @@ + @@ -3131,6 +3169,7 @@ + @@ -3152,6 +3191,7 @@ + @@ -3409,6 +3449,7 @@ + @@ -3484,9 +3525,12 @@ + + + diff --git a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters index 32733727fabb..100c39898ab9 100644 --- a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters +++ b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters @@ -86,6 +86,9 @@ {9A5DB854-CFFB-5F88-C566-0E10F994DDB3} + + {2D16C77A-4E5B-B439-2856-90E03028DA07} + {38A5DDC7-416E-548F-39DA-887875FE6B20} @@ -365,6 +368,9 @@ {42F7BE9D-3C8A-AE26-289B-8F355C068036} + + {4C5ED3D6-28D2-8BFF-F891-96201A9DE159} + {7868764A-6572-381A-906C-9C26792A4C29} @@ -781,6 +787,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\aaudio + + JUCE Modules\juce_audio_devices\native\oboe\src\common + JUCE Modules\juce_audio_devices\native\oboe\src\common @@ -808,6 +817,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\common + + JUCE Modules\juce_audio_devices\native\oboe\src\common + JUCE Modules\juce_audio_devices\native\oboe\src\common @@ -880,12 +892,21 @@ JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph @@ -997,6 +1018,15 @@ JUCE Modules\juce_audio_devices + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\deduplication + + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\deduplication + + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\deduplication + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC @@ -1024,6 +1054,9 @@ JUCE Modules\juce_audio_formats\codecs\flac\libFLAC + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC @@ -1495,9 +1528,6 @@ JUCE Modules\juce_audio_processors\utilities - - JUCE Modules\juce_audio_processors\utilities - JUCE Modules\juce_audio_processors\utilities @@ -1699,6 +1729,9 @@ JUCE Modules\juce_core\memory + + JUCE Modules\juce_core\memory + JUCE Modules\juce_core\misc @@ -2035,6 +2068,9 @@ JUCE Modules\juce_events\broadcasters + + JUCE Modules\juce_events\interprocess + JUCE Modules\juce_events\interprocess @@ -2899,6 +2935,9 @@ JUCE Modules\juce_gui_basics\windows + + JUCE Modules\juce_gui_basics\windows + JUCE Modules\juce_gui_basics\windows @@ -3387,12 +3426,24 @@ JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + JUCE Modules\juce_audio_devices\native\oboe\include\oboe JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + JUCE Modules\juce_audio_devices\native\oboe\include\oboe @@ -3414,6 +3465,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\aaudio + + JUCE Modules\juce_audio_devices\native\oboe\src\common + JUCE Modules\juce_audio_devices\native\oboe\src\common @@ -3459,15 +3513,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\common - - JUCE Modules\juce_audio_devices\native\oboe\src\fifo - JUCE Modules\juce_audio_devices\native\oboe\src\fifo - - JUCE Modules\juce_audio_devices\native\oboe\src\fifo - JUCE Modules\juce_audio_devices\native\oboe\src\fifo @@ -3495,6 +3543,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler @@ -3513,12 +3564,21 @@ JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph @@ -3588,9 +3648,6 @@ JUCE Modules\juce_audio_devices - - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private @@ -3624,9 +3681,6 @@ JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private @@ -3636,9 +3690,6 @@ JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\protected - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\protected @@ -3675,6 +3726,9 @@ JUCE Modules\juce_audio_formats\codecs\flac + + JUCE Modules\juce_audio_formats\codecs\flac + JUCE Modules\juce_audio_formats\codecs\flac @@ -4461,9 +4515,6 @@ JUCE Modules\juce_audio_processors\utilities - - JUCE Modules\juce_audio_processors\utilities - JUCE Modules\juce_audio_processors\utilities @@ -4593,6 +4644,9 @@ JUCE Modules\juce_core\containers + + JUCE Modules\juce_core\detail + JUCE Modules\juce_core\files @@ -5067,6 +5121,9 @@ JUCE Modules\juce_events\broadcasters + + JUCE Modules\juce_events\interprocess + JUCE Modules\juce_events\interprocess @@ -5130,6 +5187,9 @@ JUCE Modules\juce_events\timers + + JUCE Modules\juce_events\timers + JUCE Modules\juce_events\timers @@ -5901,6 +5961,9 @@ JUCE Modules\juce_gui_basics\windows + + JUCE Modules\juce_gui_basics\windows + JUCE Modules\juce_gui_basics\windows @@ -6122,6 +6185,12 @@ NetworkGraphicsDemo + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + JUCE Modules\juce_audio_devices\native\oboe @@ -6131,6 +6200,9 @@ JUCE Modules\juce_audio_formats\codecs\flac + + JUCE Modules\juce_audio_formats\codecs\flac + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7 diff --git a/extras/Projucer/Builds/LinuxMakefile/Makefile b/extras/Projucer/Builds/LinuxMakefile/Makefile index 2dbf59541a4b..cc9dc97e7a51 100644 --- a/extras/Projucer/Builds/LinuxMakefile/Makefile +++ b/extras/Projucer/Builds/LinuxMakefile/Makefile @@ -47,7 +47,7 @@ ifeq ($(CONFIG),Debug) JUCE_CXXFLAGS += $(JUCE_CFLAGS) -std=c++17 $(CXXFLAGS) JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) $(shell $(PKG_CONFIG) --libs freetype2) -fvisibility=hidden -lrt -ldl -lpthread $(LDFLAGS) - CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(TARGET) $(JUCE_OBJDIR) + CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(JUCE_TARGET_APP) $(JUCE_OBJDIR) endif ifeq ($(CONFIG),Release) @@ -68,7 +68,7 @@ ifeq ($(CONFIG),Release) JUCE_CXXFLAGS += $(JUCE_CFLAGS) -std=c++17 $(CXXFLAGS) JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) $(shell $(PKG_CONFIG) --libs freetype2) -fvisibility=hidden -lrt -ldl -lpthread $(LDFLAGS) - CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(TARGET) $(JUCE_OBJDIR) + CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(JUCE_TARGET_APP) $(JUCE_OBJDIR) endif OBJECTS_APP := \ @@ -450,6 +450,6 @@ clean: strip: @echo Stripping Projucer - -$(V_AT)$(STRIP) --strip-unneeded $(JUCE_OUTDIR)/$(TARGET) + -$(V_AT)$(STRIP) --strip-unneeded $(JUCE_OUTDIR)/$(JUCE_TARGET_APP) -include $(OBJECTS_APP:%.o=%.d) diff --git a/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj b/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj index 43e5cacae911..c720c388fe7d 100644 --- a/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj +++ b/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj @@ -389,6 +389,9 @@ true + + true + true @@ -695,6 +698,9 @@ true + + true + true @@ -1496,6 +1502,9 @@ true + + true + true @@ -1818,6 +1827,7 @@ + @@ -1976,6 +1986,7 @@ + @@ -1997,6 +2008,7 @@ + @@ -2254,6 +2266,7 @@ + diff --git a/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj.filters b/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj.filters index 6eaee4140148..b2fad075897f 100644 --- a/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj.filters +++ b/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj.filters @@ -92,6 +92,9 @@ {42F7BE9D-3C8A-AE26-289B-8F355C068036} + + {4C5ED3D6-28D2-8BFF-F891-96201A9DE159} + {7868764A-6572-381A-906C-9C26792A4C29} @@ -670,6 +673,9 @@ JUCE Modules\juce_core\memory + + JUCE Modules\juce_core\memory + JUCE Modules\juce_core\misc @@ -1006,6 +1012,9 @@ JUCE Modules\juce_events\broadcasters + + JUCE Modules\juce_events\interprocess + JUCE Modules\juce_events\interprocess @@ -1870,6 +1879,9 @@ JUCE Modules\juce_gui_basics\windows + + JUCE Modules\juce_gui_basics\windows + JUCE Modules\juce_gui_basics\windows @@ -2610,6 +2622,9 @@ JUCE Modules\juce_core\containers + + JUCE Modules\juce_core\detail + JUCE Modules\juce_core\files @@ -3084,6 +3099,9 @@ JUCE Modules\juce_events\broadcasters + + JUCE Modules\juce_events\interprocess + JUCE Modules\juce_events\interprocess @@ -3147,6 +3165,9 @@ JUCE Modules\juce_events\timers + + JUCE Modules\juce_events\timers + JUCE Modules\juce_events\timers @@ -3918,6 +3939,9 @@ JUCE Modules\juce_gui_basics\windows + + JUCE Modules\juce_gui_basics\windows + JUCE Modules\juce_gui_basics\windows diff --git a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj index 9f5563944b0b..4fd4266322aa 100644 --- a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj +++ b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj @@ -389,6 +389,9 @@ true + + true + true @@ -695,6 +698,9 @@ true + + true + true @@ -1496,6 +1502,9 @@ true + + true + true @@ -1818,6 +1827,7 @@ + @@ -1976,6 +1986,7 @@ + @@ -1997,6 +2008,7 @@ + @@ -2254,6 +2266,7 @@ + diff --git a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters index 3c3c1ba7300d..77c915347c86 100644 --- a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters +++ b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters @@ -92,6 +92,9 @@ {42F7BE9D-3C8A-AE26-289B-8F355C068036} + + {4C5ED3D6-28D2-8BFF-F891-96201A9DE159} + {7868764A-6572-381A-906C-9C26792A4C29} @@ -670,6 +673,9 @@ JUCE Modules\juce_core\memory + + JUCE Modules\juce_core\memory + JUCE Modules\juce_core\misc @@ -1006,6 +1012,9 @@ JUCE Modules\juce_events\broadcasters + + JUCE Modules\juce_events\interprocess + JUCE Modules\juce_events\interprocess @@ -1870,6 +1879,9 @@ JUCE Modules\juce_gui_basics\windows + + JUCE Modules\juce_gui_basics\windows + JUCE Modules\juce_gui_basics\windows @@ -2610,6 +2622,9 @@ JUCE Modules\juce_core\containers + + JUCE Modules\juce_core\detail + JUCE Modules\juce_core\files @@ -3084,6 +3099,9 @@ JUCE Modules\juce_events\broadcasters + + JUCE Modules\juce_events\interprocess + JUCE Modules\juce_events\interprocess @@ -3147,6 +3165,9 @@ JUCE Modules\juce_events\timers + + JUCE Modules\juce_events\timers + JUCE Modules\juce_events\timers @@ -3918,6 +3939,9 @@ JUCE Modules\juce_gui_basics\windows + + JUCE Modules\juce_gui_basics\windows + JUCE Modules\juce_gui_basics\windows diff --git a/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj b/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj index 0d9a8a6f2a09..0b683eb37c3f 100644 --- a/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj +++ b/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj @@ -389,6 +389,9 @@ true + + true + true @@ -695,6 +698,9 @@ true + + true + true @@ -1496,6 +1502,9 @@ true + + true + true @@ -1818,6 +1827,7 @@ + @@ -1976,6 +1986,7 @@ + @@ -1997,6 +2008,7 @@ + @@ -2254,6 +2266,7 @@ + diff --git a/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters b/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters index 8491cc628c54..ec5e3760470d 100644 --- a/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters +++ b/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters @@ -92,6 +92,9 @@ {42F7BE9D-3C8A-AE26-289B-8F355C068036} + + {4C5ED3D6-28D2-8BFF-F891-96201A9DE159} + {7868764A-6572-381A-906C-9C26792A4C29} @@ -670,6 +673,9 @@ JUCE Modules\juce_core\memory + + JUCE Modules\juce_core\memory + JUCE Modules\juce_core\misc @@ -1006,6 +1012,9 @@ JUCE Modules\juce_events\broadcasters + + JUCE Modules\juce_events\interprocess + JUCE Modules\juce_events\interprocess @@ -1870,6 +1879,9 @@ JUCE Modules\juce_gui_basics\windows + + JUCE Modules\juce_gui_basics\windows + JUCE Modules\juce_gui_basics\windows @@ -2610,6 +2622,9 @@ JUCE Modules\juce_core\containers + + JUCE Modules\juce_core\detail + JUCE Modules\juce_core\files @@ -3084,6 +3099,9 @@ JUCE Modules\juce_events\broadcasters + + JUCE Modules\juce_events\interprocess + JUCE Modules\juce_events\interprocess @@ -3147,6 +3165,9 @@ JUCE Modules\juce_events\timers + + JUCE Modules\juce_events\timers + JUCE Modules\juce_events\timers @@ -3918,6 +3939,9 @@ JUCE Modules\juce_gui_basics\windows + + JUCE Modules\juce_gui_basics\windows + JUCE Modules\juce_gui_basics\windows diff --git a/extras/Projucer/Source/Project/jucer_Project.cpp b/extras/Projucer/Source/Project/jucer_Project.cpp index 26704bf63026..24bec335bf76 100644 --- a/extras/Projucer/Source/Project/jucer_Project.cpp +++ b/extras/Projucer/Source/Project/jucer_Project.cpp @@ -2326,7 +2326,8 @@ int Project::getARAContentTypes() const noexcept { int res = 0; - if (auto* arr = pluginARAAnalyzableContentValue.get().getArray()) + if (const auto analyzableContent = pluginARAAnalyzableContentValue.get(); + auto* arr = analyzableContent.getArray()) { for (auto c : *arr) res |= (int) c; @@ -2339,7 +2340,8 @@ int Project::getARATransformationFlags() const noexcept { int res = 0; - if (auto* arr = pluginARATransformFlagsValue.get().getArray()) + if (const auto transformFlags = pluginARATransformFlagsValue.get(); + auto* arr = transformFlags.getArray()) { for (auto c : *arr) res |= (int) c; diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Make.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Make.h index 215029bc2f88..fe6cc239db2f 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Make.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Make.h @@ -128,7 +128,7 @@ class MakefileProjectExporter final : public ProjectExporter class MakefileTarget final : public build_tools::ProjectType::Target { public: - MakefileTarget (build_tools::ProjectType::Target::Type targetType, const MakefileProjectExporter& exporter) + MakefileTarget (Type targetType, const MakefileProjectExporter& exporter) : Target (targetType), owner (exporter) {} @@ -163,7 +163,7 @@ class MakefileProjectExporter final : public ProjectExporter StringPairArray getDefines (const BuildConfiguration& config) const { StringPairArray result; - auto commonOptionKeys = owner.getAllPreprocessorDefs (config, build_tools::ProjectType::Target::unspecified).getAllKeys(); + auto commonOptionKeys = owner.getAllPreprocessorDefs (config, unspecified).getAllKeys(); auto targetSpecific = owner.getAllPreprocessorDefs (config, type); for (auto& key : targetSpecific.getAllKeys()) @@ -831,47 +831,51 @@ class MakefileProjectExporter final : public ProjectExporter out << " $(LDFLAGS)" << newLine; } - void writeTargetLines (OutputStream& out, const StringArray& packages) const + void writeLinesForAggregateTarget (OutputStream& out) const { - auto n = targets.size(); - - for (int i = 0; i < n; ++i) + const auto isPartOfAggregate = [&] (const MakefileTarget* x) { - if (auto* target = targets.getUnchecked (i)) - { - if (target->type == build_tools::ProjectType::Target::AggregateTarget) - { - StringArray dependencies; - MemoryOutputStream subTargetLines; + return x != nullptr + && x->type != build_tools::ProjectType::Target::AggregateTarget + && x->type != build_tools::ProjectType::Target::SharedCodeTarget; + }; - for (int j = 0; j < n; ++j) - { - if (i == j) continue; - - if (auto* dependency = targets.getUnchecked (j)) - { - if (dependency->type != build_tools::ProjectType::Target::SharedCodeTarget) - { - auto phonyName = dependency->getPhonyName(); - - subTargetLines << phonyName << " : " << dependency->getBuildProduct() << newLine; - dependencies.add (phonyName); - } - } - } + std::vector dependencies; + std::copy_if (targets.begin(), targets.end(), std::back_inserter (dependencies), isPartOfAggregate); - out << "all : " << dependencies.joinIntoString (" ") << newLine << newLine; - out << subTargetLines.toString() << newLine << newLine; - } - else - { - if (! getProject().isAudioPluginProject()) - out << "all : " << target->getBuildProduct() << newLine << newLine; + out << "all :"; - target->writeTargetLine (out, packages); - } - } + for (const auto& d : dependencies) + out << ' ' << d->getPhonyName(); + + out << newLine << newLine; + + for (const auto& d : dependencies) + out << d->getPhonyName() << " : " << d->getBuildProduct() << newLine; + + out << newLine << newLine; + } + + void writeLinesForTarget (OutputStream& out, const StringArray& packages, MakefileTarget& target) const + { + if (target.type == build_tools::ProjectType::Target::AggregateTarget) + { + writeLinesForAggregateTarget (out); } + else + { + if (! getProject().isAudioPluginProject()) + out << "all : " << target.getBuildProduct() << newLine << newLine; + + target.writeTargetLine (out, packages); + } + } + + void writeTargetLines (OutputStream& out, const StringArray& packages) const + { + for (const auto& target : targets) + if (target != nullptr) + writeLinesForTarget (out, packages, *target); } void writeConfig (OutputStream& out, const MakeBuildConfiguration& config) const @@ -945,7 +949,18 @@ class MakefileProjectExporter final : public ProjectExporter return ""; }(); - out << " CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(TARGET) $(JUCE_OBJDIR)" << preBuildDirectory << newLine + const auto targetsToClean = [&] + { + StringArray result; + + for (const auto& target : targets) + if (target->type != build_tools::ProjectType::Target::AggregateTarget) + result.add (target->getBuildProduct()); + + return result; + }(); + + out << " CLEANCMD = rm -rf " << targetsToClean.joinIntoString (" ") << " $(JUCE_OBJDIR)" << preBuildDirectory << newLine << "endif" << newLine << newLine; } @@ -1244,10 +1259,19 @@ class MakefileProjectExporter final : public ProjectExporter << "\t$(V_AT)$(CLEANCMD)" << newLine << newLine; - out << "strip:" << newLine - << "\t@echo Stripping " << projectName << newLine - << "\t-$(V_AT)$(STRIP) --strip-unneeded $(JUCE_OUTDIR)/$(TARGET)" << newLine - << newLine; + out << "strip:" << newLine + << "\t@echo Stripping " << projectName << newLine; + + for (const auto& target : targets) + { + if (target->type != build_tools::ProjectType::Target::AggregateTarget + && target->type != build_tools::ProjectType::Target::SharedCodeTarget) + { + out << "\t-$(V_AT)$(STRIP) --strip-unneeded " << target->getBuildProduct() << newLine; + } + } + + out << newLine; writeIncludeLines (out); } @@ -1269,6 +1293,7 @@ class MakefileProjectExporter final : public ProjectExporter String getPhonyTargetLine() const { MemoryOutputStream phonyTargetLine; + phonyTargetLine.setNewLineString (getNewLineString()); phonyTargetLine << ".PHONY: clean all strip"; @@ -1276,9 +1301,13 @@ class MakefileProjectExporter final : public ProjectExporter return phonyTargetLine.toString(); for (auto target : targets) + { if (target->type != build_tools::ProjectType::Target::SharedCodeTarget && target->type != build_tools::ProjectType::Target::AggregateTarget) + { phonyTargetLine << " " << target->getPhonyName(); + } + } return phonyTargetLine.toString(); } diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Xcode.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Xcode.h index f0cc34f05b1f..8ce01ff2f280 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Xcode.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Xcode.h @@ -46,7 +46,7 @@ if [ -e "$JUCE_INSTALL_PATH$JUCE_PRODUCT_NAME" ]; then : rm -rf "$JUCE_INSTALL_PATH$JUCE_PRODUCT_NAME" fi mkdir -p "$JUCE_INSTALL_PATH" -cp -r "$JUCE_SOURCE_BUNDLE" "$JUCE_INSTALL_PATH" +ln -sfhv "$JUCE_SOURCE_BUNDLE" "$JUCE_INSTALL_PATH" )"; static constexpr const char* adhocCodeSignTemplate = R"( @@ -2220,7 +2220,7 @@ class XcodeProjectExporter final : public ProjectExporter, && project.getEnabledModules().isModuleEnabled ("juce_audio_plugin_client")) { const auto path = rebaseFromProjectFolderToBuildTarget (getLV2HelperProgramSource()); - addFile (FileOptions().withRelativePath ({ expandPath (path.toUnixStyle()), path.getRoot() }) + addFile (FileOptions().withRelativePath ({ path.toUnixStyle(), path.getRoot() }) .withSkipPCHEnabled (true) .withCompilationEnabled (true) .withInhibitWarningsEnabled (true) @@ -2232,7 +2232,7 @@ class XcodeProjectExporter final : public ProjectExporter, && project.getEnabledModules().isModuleEnabled ("juce_audio_plugin_client")) { const auto path = rebaseFromProjectFolderToBuildTarget (getVST3HelperProgramSource()); - addFile (FileOptions().withRelativePath ({ expandPath (path.toUnixStyle()), path.getRoot() }) + addFile (FileOptions().withRelativePath ({ path.toUnixStyle(), path.getRoot() }) .withSkipPCHEnabled (true) .withCompilationEnabled (true) .withInhibitWarningsEnabled (true) diff --git a/extras/UnitTestRunner/Builds/LinuxMakefile/Makefile b/extras/UnitTestRunner/Builds/LinuxMakefile/Makefile index bdfd986cc76c..f851cf1a0a7e 100644 --- a/extras/UnitTestRunner/Builds/LinuxMakefile/Makefile +++ b/extras/UnitTestRunner/Builds/LinuxMakefile/Makefile @@ -47,7 +47,7 @@ ifeq ($(CONFIG),Debug) JUCE_CXXFLAGS += $(JUCE_CFLAGS) -std=c++17 $(CXXFLAGS) JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) $(shell $(PKG_CONFIG) --libs alsa freetype2 gl libcurl) -fvisibility=hidden -lrt -ldl -lpthread $(LDFLAGS) - CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(TARGET) $(JUCE_OBJDIR) + CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(JUCE_TARGET_CONSOLEAPP) $(JUCE_OBJDIR) endif ifeq ($(CONFIG),Release) @@ -68,7 +68,7 @@ ifeq ($(CONFIG),Release) JUCE_CXXFLAGS += $(JUCE_CFLAGS) -std=c++17 $(CXXFLAGS) JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) $(shell $(PKG_CONFIG) --libs alsa freetype2 gl libcurl) -fvisibility=hidden -lrt -ldl -lpthread $(LDFLAGS) - CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(TARGET) $(JUCE_OBJDIR) + CLEANCMD = rm -rf $(JUCE_OUTDIR)/$(JUCE_TARGET_CONSOLEAPP) $(JUCE_OBJDIR) endif OBJECTS_CONSOLEAPP := \ @@ -228,6 +228,6 @@ clean: strip: @echo Stripping UnitTestRunner - -$(V_AT)$(STRIP) --strip-unneeded $(JUCE_OUTDIR)/$(TARGET) + -$(V_AT)$(STRIP) --strip-unneeded $(JUCE_OUTDIR)/$(JUCE_TARGET_CONSOLEAPP) -include $(OBJECTS_CONSOLEAPP:%.o=%.d) diff --git a/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj index bbef1681eea5..fdf87b78346f 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj +++ b/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj @@ -314,6 +314,9 @@ true + + true + true @@ -341,6 +344,9 @@ true + + true + true @@ -413,12 +419,21 @@ true + + true + true + + true + true + + true + true @@ -524,6 +539,15 @@ true + + true + + + true + + + true + true @@ -551,6 +575,9 @@ true + + true + true @@ -1013,9 +1040,6 @@ true - - true - true @@ -1199,6 +1223,9 @@ true + + true + true @@ -1610,6 +1637,9 @@ true + + true + true @@ -2411,6 +2441,9 @@ true + + true + true @@ -2552,6 +2585,9 @@ true + + true + true @@ -2753,8 +2789,12 @@ + + + + @@ -2762,6 +2802,7 @@ + @@ -2777,9 +2818,7 @@ - - @@ -2789,14 +2828,18 @@ + + + + @@ -2820,7 +2863,6 @@ - @@ -2832,11 +2874,9 @@ - - @@ -2849,6 +2889,7 @@ + @@ -3111,7 +3152,6 @@ - @@ -3155,6 +3195,7 @@ + @@ -3359,6 +3400,7 @@ + @@ -3380,6 +3422,7 @@ + @@ -3637,6 +3680,7 @@ + @@ -3696,6 +3740,7 @@ + @@ -3747,9 +3792,12 @@ + + + diff --git a/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj.filters index b34259cec121..f8f71aef89f7 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj.filters +++ b/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj.filters @@ -95,6 +95,9 @@ {9A5DB854-CFFB-5F88-C566-0E10F994DDB3} + + {2D16C77A-4E5B-B439-2856-90E03028DA07} + {38A5DDC7-416E-548F-39DA-887875FE6B20} @@ -374,6 +377,9 @@ {42F7BE9D-3C8A-AE26-289B-8F355C068036} + + {4C5ED3D6-28D2-8BFF-F891-96201A9DE159} + {7868764A-6572-381A-906C-9C26792A4C29} @@ -847,6 +853,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\aaudio + + JUCE Modules\juce_audio_devices\native\oboe\src\common + JUCE Modules\juce_audio_devices\native\oboe\src\common @@ -874,6 +883,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\common + + JUCE Modules\juce_audio_devices\native\oboe\src\common + JUCE Modules\juce_audio_devices\native\oboe\src\common @@ -946,12 +958,21 @@ JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph @@ -1063,6 +1084,15 @@ JUCE Modules\juce_audio_devices + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\deduplication + + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\deduplication + + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\deduplication + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC @@ -1090,6 +1120,9 @@ JUCE Modules\juce_audio_formats\codecs\flac\libFLAC + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC @@ -1561,9 +1594,6 @@ JUCE Modules\juce_audio_processors\utilities - - JUCE Modules\juce_audio_processors\utilities - JUCE Modules\juce_audio_processors\utilities @@ -1765,6 +1795,9 @@ JUCE Modules\juce_core\memory + + JUCE Modules\juce_core\memory + JUCE Modules\juce_core\misc @@ -2209,6 +2242,9 @@ JUCE Modules\juce_events\broadcasters + + JUCE Modules\juce_events\interprocess + JUCE Modules\juce_events\interprocess @@ -3073,6 +3109,9 @@ JUCE Modules\juce_gui_basics\windows + + JUCE Modules\juce_gui_basics\windows + JUCE Modules\juce_gui_basics\windows @@ -3232,6 +3271,9 @@ JUCE Modules\juce_midi_ci\ci + + JUCE Modules\juce_midi_ci\ci + JUCE Modules\juce_midi_ci\detail @@ -3633,12 +3675,24 @@ JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + JUCE Modules\juce_audio_devices\native\oboe\include\oboe JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + JUCE Modules\juce_audio_devices\native\oboe\include\oboe @@ -3660,6 +3714,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\aaudio + + JUCE Modules\juce_audio_devices\native\oboe\src\common + JUCE Modules\juce_audio_devices\native\oboe\src\common @@ -3705,15 +3762,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\common - - JUCE Modules\juce_audio_devices\native\oboe\src\fifo - JUCE Modules\juce_audio_devices\native\oboe\src\fifo - - JUCE Modules\juce_audio_devices\native\oboe\src\fifo - JUCE Modules\juce_audio_devices\native\oboe\src\fifo @@ -3741,6 +3792,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler @@ -3759,12 +3813,21 @@ JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph @@ -3834,9 +3897,6 @@ JUCE Modules\juce_audio_devices - - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private @@ -3870,9 +3930,6 @@ JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private @@ -3882,9 +3939,6 @@ JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\protected - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\protected @@ -3921,6 +3975,9 @@ JUCE Modules\juce_audio_formats\codecs\flac + + JUCE Modules\juce_audio_formats\codecs\flac + JUCE Modules\juce_audio_formats\codecs\flac @@ -4707,9 +4764,6 @@ JUCE Modules\juce_audio_processors\utilities - - JUCE Modules\juce_audio_processors\utilities - JUCE Modules\juce_audio_processors\utilities @@ -4839,6 +4893,9 @@ JUCE Modules\juce_core\containers + + JUCE Modules\juce_core\detail + JUCE Modules\juce_core\files @@ -5451,6 +5508,9 @@ JUCE Modules\juce_events\broadcasters + + JUCE Modules\juce_events\interprocess + JUCE Modules\juce_events\interprocess @@ -5514,6 +5574,9 @@ JUCE Modules\juce_events\timers + + JUCE Modules\juce_events\timers + JUCE Modules\juce_events\timers @@ -6285,6 +6348,9 @@ JUCE Modules\juce_gui_basics\windows + + JUCE Modules\juce_gui_basics\windows + JUCE Modules\juce_gui_basics\windows @@ -6462,6 +6528,9 @@ JUCE Modules\juce_midi_ci\ci + + JUCE Modules\juce_midi_ci\ci + JUCE Modules\juce_midi_ci\ci @@ -6611,6 +6680,12 @@ + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + JUCE Modules\juce_audio_devices\native\oboe @@ -6620,6 +6695,9 @@ JUCE Modules\juce_audio_formats\codecs\flac + + JUCE Modules\juce_audio_formats\codecs\flac + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7 diff --git a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj index 058a07e9d5c6..8ef7014ba348 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj +++ b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj @@ -314,6 +314,9 @@ true + + true + true @@ -341,6 +344,9 @@ true + + true + true @@ -413,12 +419,21 @@ true + + true + true + + true + true + + true + true @@ -524,6 +539,15 @@ true + + true + + + true + + + true + true @@ -551,6 +575,9 @@ true + + true + true @@ -1013,9 +1040,6 @@ true - - true - true @@ -1199,6 +1223,9 @@ true + + true + true @@ -1610,6 +1637,9 @@ true + + true + true @@ -2411,6 +2441,9 @@ true + + true + true @@ -2552,6 +2585,9 @@ true + + true + true @@ -2753,8 +2789,12 @@ + + + + @@ -2762,6 +2802,7 @@ + @@ -2777,9 +2818,7 @@ - - @@ -2789,14 +2828,18 @@ + + + + @@ -2820,7 +2863,6 @@ - @@ -2832,11 +2874,9 @@ - - @@ -2849,6 +2889,7 @@ + @@ -3111,7 +3152,6 @@ - @@ -3155,6 +3195,7 @@ + @@ -3359,6 +3400,7 @@ + @@ -3380,6 +3422,7 @@ + @@ -3637,6 +3680,7 @@ + @@ -3696,6 +3740,7 @@ + @@ -3747,9 +3792,12 @@ + + + diff --git a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters index 4a6a45d5613b..f1766a3e5e13 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters +++ b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters @@ -95,6 +95,9 @@ {9A5DB854-CFFB-5F88-C566-0E10F994DDB3} + + {2D16C77A-4E5B-B439-2856-90E03028DA07} + {38A5DDC7-416E-548F-39DA-887875FE6B20} @@ -374,6 +377,9 @@ {42F7BE9D-3C8A-AE26-289B-8F355C068036} + + {4C5ED3D6-28D2-8BFF-F891-96201A9DE159} + {7868764A-6572-381A-906C-9C26792A4C29} @@ -847,6 +853,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\aaudio + + JUCE Modules\juce_audio_devices\native\oboe\src\common + JUCE Modules\juce_audio_devices\native\oboe\src\common @@ -874,6 +883,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\common + + JUCE Modules\juce_audio_devices\native\oboe\src\common + JUCE Modules\juce_audio_devices\native\oboe\src\common @@ -946,12 +958,21 @@ JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph @@ -1063,6 +1084,15 @@ JUCE Modules\juce_audio_devices + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\deduplication + + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\deduplication + + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\deduplication + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC @@ -1090,6 +1120,9 @@ JUCE Modules\juce_audio_formats\codecs\flac\libFLAC + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC @@ -1561,9 +1594,6 @@ JUCE Modules\juce_audio_processors\utilities - - JUCE Modules\juce_audio_processors\utilities - JUCE Modules\juce_audio_processors\utilities @@ -1765,6 +1795,9 @@ JUCE Modules\juce_core\memory + + JUCE Modules\juce_core\memory + JUCE Modules\juce_core\misc @@ -2209,6 +2242,9 @@ JUCE Modules\juce_events\broadcasters + + JUCE Modules\juce_events\interprocess + JUCE Modules\juce_events\interprocess @@ -3073,6 +3109,9 @@ JUCE Modules\juce_gui_basics\windows + + JUCE Modules\juce_gui_basics\windows + JUCE Modules\juce_gui_basics\windows @@ -3232,6 +3271,9 @@ JUCE Modules\juce_midi_ci\ci + + JUCE Modules\juce_midi_ci\ci + JUCE Modules\juce_midi_ci\detail @@ -3633,12 +3675,24 @@ JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + JUCE Modules\juce_audio_devices\native\oboe\include\oboe JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + JUCE Modules\juce_audio_devices\native\oboe\include\oboe @@ -3660,6 +3714,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\aaudio + + JUCE Modules\juce_audio_devices\native\oboe\src\common + JUCE Modules\juce_audio_devices\native\oboe\src\common @@ -3705,15 +3762,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\common - - JUCE Modules\juce_audio_devices\native\oboe\src\fifo - JUCE Modules\juce_audio_devices\native\oboe\src\fifo - - JUCE Modules\juce_audio_devices\native\oboe\src\fifo - JUCE Modules\juce_audio_devices\native\oboe\src\fifo @@ -3741,6 +3792,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler @@ -3759,12 +3813,21 @@ JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph @@ -3834,9 +3897,6 @@ JUCE Modules\juce_audio_devices - - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private @@ -3870,9 +3930,6 @@ JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private @@ -3882,9 +3939,6 @@ JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\protected - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\protected @@ -3921,6 +3975,9 @@ JUCE Modules\juce_audio_formats\codecs\flac + + JUCE Modules\juce_audio_formats\codecs\flac + JUCE Modules\juce_audio_formats\codecs\flac @@ -4707,9 +4764,6 @@ JUCE Modules\juce_audio_processors\utilities - - JUCE Modules\juce_audio_processors\utilities - JUCE Modules\juce_audio_processors\utilities @@ -4839,6 +4893,9 @@ JUCE Modules\juce_core\containers + + JUCE Modules\juce_core\detail + JUCE Modules\juce_core\files @@ -5451,6 +5508,9 @@ JUCE Modules\juce_events\broadcasters + + JUCE Modules\juce_events\interprocess + JUCE Modules\juce_events\interprocess @@ -5514,6 +5574,9 @@ JUCE Modules\juce_events\timers + + JUCE Modules\juce_events\timers + JUCE Modules\juce_events\timers @@ -6285,6 +6348,9 @@ JUCE Modules\juce_gui_basics\windows + + JUCE Modules\juce_gui_basics\windows + JUCE Modules\juce_gui_basics\windows @@ -6462,6 +6528,9 @@ JUCE Modules\juce_midi_ci\ci + + JUCE Modules\juce_midi_ci\ci + JUCE Modules\juce_midi_ci\ci @@ -6611,6 +6680,12 @@ + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + JUCE Modules\juce_audio_devices\native\oboe @@ -6620,6 +6695,9 @@ JUCE Modules\juce_audio_formats\codecs\flac + + JUCE Modules\juce_audio_formats\codecs\flac + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7 diff --git a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj index 76dc8be9a8a1..f1fa691a8398 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj +++ b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj @@ -314,6 +314,9 @@ true + + true + true @@ -341,6 +344,9 @@ true + + true + true @@ -413,12 +419,21 @@ true + + true + true + + true + true + + true + true @@ -524,6 +539,15 @@ true + + true + + + true + + + true + true @@ -551,6 +575,9 @@ true + + true + true @@ -1013,9 +1040,6 @@ true - - true - true @@ -1199,6 +1223,9 @@ true + + true + true @@ -1610,6 +1637,9 @@ true + + true + true @@ -2411,6 +2441,9 @@ true + + true + true @@ -2552,6 +2585,9 @@ true + + true + true @@ -2753,8 +2789,12 @@ + + + + @@ -2762,6 +2802,7 @@ + @@ -2777,9 +2818,7 @@ - - @@ -2789,14 +2828,18 @@ + + + + @@ -2820,7 +2863,6 @@ - @@ -2832,11 +2874,9 @@ - - @@ -2849,6 +2889,7 @@ + @@ -3111,7 +3152,6 @@ - @@ -3155,6 +3195,7 @@ + @@ -3359,6 +3400,7 @@ + @@ -3380,6 +3422,7 @@ + @@ -3637,6 +3680,7 @@ + @@ -3696,6 +3740,7 @@ + @@ -3747,9 +3792,12 @@ + + + diff --git a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters index 9261afe87807..759ab7224369 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters +++ b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters @@ -95,6 +95,9 @@ {9A5DB854-CFFB-5F88-C566-0E10F994DDB3} + + {2D16C77A-4E5B-B439-2856-90E03028DA07} + {38A5DDC7-416E-548F-39DA-887875FE6B20} @@ -374,6 +377,9 @@ {42F7BE9D-3C8A-AE26-289B-8F355C068036} + + {4C5ED3D6-28D2-8BFF-F891-96201A9DE159} + {7868764A-6572-381A-906C-9C26792A4C29} @@ -847,6 +853,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\aaudio + + JUCE Modules\juce_audio_devices\native\oboe\src\common + JUCE Modules\juce_audio_devices\native\oboe\src\common @@ -874,6 +883,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\common + + JUCE Modules\juce_audio_devices\native\oboe\src\common + JUCE Modules\juce_audio_devices\native\oboe\src\common @@ -946,12 +958,21 @@ JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph @@ -1063,6 +1084,15 @@ JUCE Modules\juce_audio_devices + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\deduplication + + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\deduplication + + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\deduplication + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC @@ -1090,6 +1120,9 @@ JUCE Modules\juce_audio_formats\codecs\flac\libFLAC + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC @@ -1561,9 +1594,6 @@ JUCE Modules\juce_audio_processors\utilities - - JUCE Modules\juce_audio_processors\utilities - JUCE Modules\juce_audio_processors\utilities @@ -1765,6 +1795,9 @@ JUCE Modules\juce_core\memory + + JUCE Modules\juce_core\memory + JUCE Modules\juce_core\misc @@ -2209,6 +2242,9 @@ JUCE Modules\juce_events\broadcasters + + JUCE Modules\juce_events\interprocess + JUCE Modules\juce_events\interprocess @@ -3073,6 +3109,9 @@ JUCE Modules\juce_gui_basics\windows + + JUCE Modules\juce_gui_basics\windows + JUCE Modules\juce_gui_basics\windows @@ -3232,6 +3271,9 @@ JUCE Modules\juce_midi_ci\ci + + JUCE Modules\juce_midi_ci\ci + JUCE Modules\juce_midi_ci\detail @@ -3633,12 +3675,24 @@ JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + JUCE Modules\juce_audio_devices\native\oboe\include\oboe JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + JUCE Modules\juce_audio_devices\native\oboe\include\oboe @@ -3660,6 +3714,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\aaudio + + JUCE Modules\juce_audio_devices\native\oboe\src\common + JUCE Modules\juce_audio_devices\native\oboe\src\common @@ -3705,15 +3762,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\common - - JUCE Modules\juce_audio_devices\native\oboe\src\fifo - JUCE Modules\juce_audio_devices\native\oboe\src\fifo - - JUCE Modules\juce_audio_devices\native\oboe\src\fifo - JUCE Modules\juce_audio_devices\native\oboe\src\fifo @@ -3741,6 +3792,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler @@ -3759,12 +3813,21 @@ JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph @@ -3834,9 +3897,6 @@ JUCE Modules\juce_audio_devices - - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private @@ -3870,9 +3930,6 @@ JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private @@ -3882,9 +3939,6 @@ JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\protected - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\protected @@ -3921,6 +3975,9 @@ JUCE Modules\juce_audio_formats\codecs\flac + + JUCE Modules\juce_audio_formats\codecs\flac + JUCE Modules\juce_audio_formats\codecs\flac @@ -4707,9 +4764,6 @@ JUCE Modules\juce_audio_processors\utilities - - JUCE Modules\juce_audio_processors\utilities - JUCE Modules\juce_audio_processors\utilities @@ -4839,6 +4893,9 @@ JUCE Modules\juce_core\containers + + JUCE Modules\juce_core\detail + JUCE Modules\juce_core\files @@ -5451,6 +5508,9 @@ JUCE Modules\juce_events\broadcasters + + JUCE Modules\juce_events\interprocess + JUCE Modules\juce_events\interprocess @@ -5514,6 +5574,9 @@ JUCE Modules\juce_events\timers + + JUCE Modules\juce_events\timers + JUCE Modules\juce_events\timers @@ -6285,6 +6348,9 @@ JUCE Modules\juce_gui_basics\windows + + JUCE Modules\juce_gui_basics\windows + JUCE Modules\juce_gui_basics\windows @@ -6462,6 +6528,9 @@ JUCE Modules\juce_midi_ci\ci + + JUCE Modules\juce_midi_ci\ci + JUCE Modules\juce_midi_ci\ci @@ -6611,6 +6680,12 @@ + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + JUCE Modules\juce_audio_devices\native\oboe @@ -6620,6 +6695,9 @@ JUCE Modules\juce_audio_formats\codecs\flac + + JUCE Modules\juce_audio_formats\codecs\flac + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7 diff --git a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj index 94f274feb15a..3f0dafa8c3d3 100644 --- a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj +++ b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj @@ -297,6 +297,9 @@ true + + true + true @@ -324,6 +327,9 @@ true + + true + true @@ -396,12 +402,21 @@ true + + true + true + + true + true + + true + true @@ -507,6 +522,15 @@ true + + true + + + true + + + true + true @@ -534,6 +558,9 @@ true + + true + true @@ -996,9 +1023,6 @@ true - - true - true @@ -1182,6 +1206,9 @@ true + + true + true @@ -1488,6 +1515,9 @@ true + + true + true @@ -2289,6 +2319,9 @@ true + + true + true @@ -2547,8 +2580,12 @@ + + + + @@ -2556,6 +2593,7 @@ + @@ -2571,9 +2609,7 @@ - - @@ -2583,14 +2619,18 @@ + + + + @@ -2614,7 +2654,6 @@ - @@ -2626,11 +2665,9 @@ - - @@ -2643,6 +2680,7 @@ + @@ -2905,7 +2943,6 @@ - @@ -2949,6 +2986,7 @@ + @@ -3107,6 +3145,7 @@ + @@ -3128,6 +3167,7 @@ + @@ -3385,6 +3425,7 @@ + @@ -3460,9 +3501,12 @@ + + + diff --git a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj.filters b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj.filters index 34b48d79640e..0a7fc35d2f08 100644 --- a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj.filters +++ b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj.filters @@ -80,6 +80,9 @@ {9A5DB854-CFFB-5F88-C566-0E10F994DDB3} + + {2D16C77A-4E5B-B439-2856-90E03028DA07} + {38A5DDC7-416E-548F-39DA-887875FE6B20} @@ -359,6 +362,9 @@ {42F7BE9D-3C8A-AE26-289B-8F355C068036} + + {4C5ED3D6-28D2-8BFF-F891-96201A9DE159} + {7868764A-6572-381A-906C-9C26792A4C29} @@ -778,6 +784,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\aaudio + + JUCE Modules\juce_audio_devices\native\oboe\src\common + JUCE Modules\juce_audio_devices\native\oboe\src\common @@ -805,6 +814,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\common + + JUCE Modules\juce_audio_devices\native\oboe\src\common + JUCE Modules\juce_audio_devices\native\oboe\src\common @@ -877,12 +889,21 @@ JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph @@ -994,6 +1015,15 @@ JUCE Modules\juce_audio_devices + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\deduplication + + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\deduplication + + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\deduplication + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC @@ -1021,6 +1051,9 @@ JUCE Modules\juce_audio_formats\codecs\flac\libFLAC + + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC + JUCE Modules\juce_audio_formats\codecs\flac\libFLAC @@ -1492,9 +1525,6 @@ JUCE Modules\juce_audio_processors\utilities - - JUCE Modules\juce_audio_processors\utilities - JUCE Modules\juce_audio_processors\utilities @@ -1696,6 +1726,9 @@ JUCE Modules\juce_core\memory + + JUCE Modules\juce_core\memory + JUCE Modules\juce_core\misc @@ -2032,6 +2065,9 @@ JUCE Modules\juce_events\broadcasters + + JUCE Modules\juce_events\interprocess + JUCE Modules\juce_events\interprocess @@ -2896,6 +2932,9 @@ JUCE Modules\juce_gui_basics\windows + + JUCE Modules\juce_gui_basics\windows + JUCE Modules\juce_gui_basics\windows @@ -3354,12 +3393,24 @@ JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + JUCE Modules\juce_audio_devices\native\oboe\include\oboe JUCE Modules\juce_audio_devices\native\oboe\include\oboe + + JUCE Modules\juce_audio_devices\native\oboe\include\oboe + JUCE Modules\juce_audio_devices\native\oboe\include\oboe @@ -3381,6 +3432,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\aaudio + + JUCE Modules\juce_audio_devices\native\oboe\src\common + JUCE Modules\juce_audio_devices\native\oboe\src\common @@ -3426,15 +3480,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\common - - JUCE Modules\juce_audio_devices\native\oboe\src\fifo - JUCE Modules\juce_audio_devices\native\oboe\src\fifo - - JUCE Modules\juce_audio_devices\native\oboe\src\fifo - JUCE Modules\juce_audio_devices\native\oboe\src\fifo @@ -3462,6 +3510,9 @@ JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler @@ -3480,12 +3531,21 @@ JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph @@ -3555,9 +3615,6 @@ JUCE Modules\juce_audio_devices - - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private @@ -3591,9 +3648,6 @@ JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private @@ -3603,9 +3657,6 @@ JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\private - - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\protected - JUCE Modules\juce_audio_formats\codecs\flac\libFLAC\include\protected @@ -3642,6 +3693,9 @@ JUCE Modules\juce_audio_formats\codecs\flac + + JUCE Modules\juce_audio_formats\codecs\flac + JUCE Modules\juce_audio_formats\codecs\flac @@ -4428,9 +4482,6 @@ JUCE Modules\juce_audio_processors\utilities - - JUCE Modules\juce_audio_processors\utilities - JUCE Modules\juce_audio_processors\utilities @@ -4560,6 +4611,9 @@ JUCE Modules\juce_core\containers + + JUCE Modules\juce_core\detail + JUCE Modules\juce_core\files @@ -5034,6 +5088,9 @@ JUCE Modules\juce_events\broadcasters + + JUCE Modules\juce_events\interprocess + JUCE Modules\juce_events\interprocess @@ -5097,6 +5154,9 @@ JUCE Modules\juce_events\timers + + JUCE Modules\juce_events\timers + JUCE Modules\juce_events\timers @@ -5868,6 +5928,9 @@ JUCE Modules\juce_gui_basics\windows + + JUCE Modules\juce_gui_basics\windows + JUCE Modules\juce_gui_basics\windows @@ -6089,6 +6152,12 @@ + + JUCE Modules\juce_audio_devices\native\oboe\src\common + + + JUCE Modules\juce_audio_devices\native\oboe\src\flowgraph\resampler + JUCE Modules\juce_audio_devices\native\oboe @@ -6098,6 +6167,9 @@ JUCE Modules\juce_audio_formats\codecs\flac + + JUCE Modules\juce_audio_formats\codecs\flac + JUCE Modules\juce_audio_formats\codecs\oggvorbis\libvorbis-1.3.7 diff --git a/modules/juce_audio_basics/midi/ump/juce_UMP_test.cpp b/modules/juce_audio_basics/midi/ump/juce_UMP_test.cpp index 732bf0e3800a..43d6ffcd82c0 100644 --- a/modules/juce_audio_basics/midi/ump/juce_UMP_test.cpp +++ b/modules/juce_audio_basics/midi/ump/juce_UMP_test.cpp @@ -989,22 +989,12 @@ class UniversalMidiPacketTests final : public UnitTest } } - #if JUCE_WINDOWS && ! JUCE_MINGW - #define JUCE_CHECKED_ITERATOR(msg, size) \ - stdext::checked_array_iterator> ((msg), (size_t) (size)) - #else - #define JUCE_CHECKED_ITERATOR(msg, size) (msg) - #endif - static bool equal (const MidiMessage& a, const MidiMessage& b) noexcept { return a.getRawDataSize() == b.getRawDataSize() - && std::equal (a.getRawData(), a.getRawData() + a.getRawDataSize(), - JUCE_CHECKED_ITERATOR (b.getRawData(), b.getRawDataSize())); + && std::equal (a.getRawData(), a.getRawData() + a.getRawDataSize(), b.getRawData()); } - #undef JUCE_CHECKED_ITERATOR - static bool equal (const MidiBuffer& a, const MidiBuffer& b) noexcept { return a.data == b.data; diff --git a/modules/juce_audio_basics/mpe/juce_MPEZoneLayout.cpp b/modules/juce_audio_basics/mpe/juce_MPEZoneLayout.cpp index 7ce29b601107..cff066cdede4 100644 --- a/modules/juce_audio_basics/mpe/juce_MPEZoneLayout.cpp +++ b/modules/juce_audio_basics/mpe/juce_MPEZoneLayout.cpp @@ -381,6 +381,17 @@ class MPEZoneLayoutTests final : public UnitTest expectEquals (layout.getLowerZone().numMemberChannels, 3); expectEquals (layout.getLowerZone().perNotePitchbendRange, 48); expectEquals (layout.getLowerZone().masterPitchbendRange, 2); + + const auto masterPitchBend = 0x0c; + layout.processNextMidiEvent ({ 0xb0, 0x64, 0x00 }); + layout.processNextMidiEvent ({ 0xb0, 0x06, masterPitchBend }); + + expectEquals (layout.getLowerZone().masterPitchbendRange, masterPitchBend); + + const auto newPitchBend = 0x0d; + layout.processNextMidiEvent ({ 0xb0, 0x06, newPitchBend }); + + expectEquals (layout.getLowerZone().masterPitchbendRange, newPitchBend); } } }; diff --git a/modules/juce_audio_devices/juce_audio_devices.cpp b/modules/juce_audio_devices/juce_audio_devices.cpp index 8a4ec9da6c24..76e219af4909 100644 --- a/modules/juce_audio_devices/juce_audio_devices.cpp +++ b/modules/juce_audio_devices/juce_audio_devices.cpp @@ -228,7 +228,9 @@ namespace juce "-Wzero-as-null-pointer-constant", "-Winconsistent-missing-destructor-override", "-Wshadow-field-in-constructor", - "-Wshadow-field") + "-Wshadow-field", + "-Wsign-conversion", + "-Wswitch-enum") #include JUCE_END_IGNORE_WARNINGS_GCC_LIKE diff --git a/modules/juce_audio_devices/native/juce_CoreAudio_mac.cpp b/modules/juce_audio_devices/native/juce_CoreAudio_mac.cpp index 87aec679e7e2..7124e408dcf6 100644 --- a/modules/juce_audio_devices/native/juce_CoreAudio_mac.cpp +++ b/modules/juce_audio_devices/native/juce_CoreAudio_mac.cpp @@ -1462,6 +1462,12 @@ class AudioIODeviceCombiner final : public AudioIODevice, auto getDeviceWrappers() { return std::array< DeviceWrapper*, 2> { { &inputWrapper, &outputWrapper } }; } auto getDeviceWrappers() const { return std::array { { &inputWrapper, &outputWrapper } }; } + int getIndexOfDevice (bool asInput) const + { + return asInput ? inputWrapper.getIndexOfDevice (true) + : outputWrapper.getIndexOfDevice (false); + } + StringArray getOutputChannelNames() override { return outputWrapper.getChannelNames(); } StringArray getInputChannelNames() override { return inputWrapper .getChannelNames(); } BigInteger getActiveOutputChannels() const override { return outputWrapper.getActiveChannels(); } @@ -1469,46 +1475,16 @@ class AudioIODeviceCombiner final : public AudioIODevice, Array getAvailableSampleRates() override { - Array commonRates; - bool first = true; - - for (auto& d : getDeviceWrappers()) - { - auto rates = d->getAvailableSampleRates(); - - if (first) - { - first = false; - commonRates = rates; - } - else - { - commonRates.removeValuesNotIn (rates); - } - } + auto commonRates = inputWrapper.getAvailableSampleRates(); + commonRates.removeValuesNotIn (outputWrapper.getAvailableSampleRates()); return commonRates; } Array getAvailableBufferSizes() override { - Array commonSizes; - bool first = true; - - for (auto& d : getDeviceWrappers()) - { - auto sizes = d->getAvailableBufferSizes(); - - if (first) - { - first = false; - commonSizes = sizes; - } - else - { - commonSizes.removeValuesNotIn (sizes); - } - } + auto commonSizes = inputWrapper.getAvailableBufferSizes(); + commonSizes.removeValuesNotIn (outputWrapper.getAvailableBufferSizes()); return commonSizes; } @@ -1520,22 +1496,12 @@ class AudioIODeviceCombiner final : public AudioIODevice, int getCurrentBitDepth() override { - int depth = 32; - - for (auto& d : getDeviceWrappers()) - depth = jmin (depth, d->getCurrentBitDepth()); - - return depth; + return jmin (32, inputWrapper.getCurrentBitDepth(), outputWrapper.getCurrentBitDepth()); } int getDefaultBufferSize() override { - int size = 0; - - for (auto& d : getDeviceWrappers()) - size = jmax (size, d->getDefaultBufferSize()); - - return size; + return jmax (0, inputWrapper.getDefaultBufferSize(), outputWrapper.getDefaultBufferSize()); } AudioWorkgroup getWorkgroup() const override @@ -2238,9 +2204,7 @@ class CoreAudioIODeviceType final : public AudioIODeviceType, return d->getIndexOfDevice (asInput); if (auto* d = dynamic_cast (device)) - for (auto* dev : d->getDeviceWrappers()) - if (const auto index = dev->getIndexOfDevice (asInput); index >= 0) - return index; + return d->getIndexOfDevice (asInput); return -1; } diff --git a/modules/juce_audio_devices/native/oboe/CMakeLists.txt b/modules/juce_audio_devices/native/oboe/CMakeLists.txt index 0f243b885d43..6f697da77cb6 100644 --- a/modules/juce_audio_devices/native/oboe/CMakeLists.txt +++ b/modules/juce_audio_devices/native/oboe/CMakeLists.txt @@ -9,6 +9,7 @@ project(oboe) set (oboe_sources src/aaudio/AAudioLoader.cpp src/aaudio/AudioStreamAAudio.cpp + src/common/AdpfWrapper.cpp src/common/AudioSourceCaller.cpp src/common/AudioStream.cpp src/common/AudioStreamBuilder.cpp @@ -18,6 +19,7 @@ set (oboe_sources src/common/FixedBlockReader.cpp src/common/FixedBlockWriter.cpp src/common/LatencyTuner.cpp + src/common/OboeExtensions.cpp src/common/SourceFloatCaller.cpp src/common/SourceI16Caller.cpp src/common/SourceI24Caller.cpp @@ -31,8 +33,11 @@ set (oboe_sources src/flowgraph/FlowGraphNode.cpp src/flowgraph/ChannelCountConverter.cpp src/flowgraph/ClipToRange.cpp + src/flowgraph/Limiter.cpp src/flowgraph/ManyToMultiConverter.cpp + src/flowgraph/MonoBlend.cpp src/flowgraph/MonoToMultiConverter.cpp + src/flowgraph/MultiToManyConverter.cpp src/flowgraph/MultiToMonoConverter.cpp src/flowgraph/RampLinear.cpp src/flowgraph/SampleRateConverter.cpp @@ -78,8 +83,11 @@ target_include_directories(oboe # We've also removed the explicit `-std=c++17` compile option, and replaced it with a more # cmake-friendly way of specifying the language standard. -target_compile_options(oboe PRIVATE -Ofast) -set_target_properties(oboe PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED TRUE CXX_EXTENSIONS FALSE) +target_compile_options(oboe + PRIVATE + "$<$:-Ofast>" + "$<$:-O3>") +target_compile_features(oboe PRIVATE cxx_std_17) # JUCE CHANGE ENDS HERE diff --git a/modules/juce_audio_devices/native/oboe/README.md b/modules/juce_audio_devices/native/oboe/README.md index cd4318a94d43..cff7332f7321 100644 --- a/modules/juce_audio_devices/native/oboe/README.md +++ b/modules/juce_audio_devices/native/oboe/README.md @@ -1,7 +1,7 @@ The files in this directory are reproduced from the official Oboe repository, which can be found at github.com/google/oboe. -These files are from tag 1.6.1 (855ea841). +These files are from tag 1.8.0 (987538b). We've included only those parts of the original repository which are required to build the Oboe library. Documentation, samples, tests, and other non-library items have been omitted. diff --git a/modules/juce_audio_devices/native/oboe/include/oboe/AudioStream.h b/modules/juce_audio_devices/native/oboe/include/oboe/AudioStream.h index 825ffc89bfef..261772a1aa04 100644 --- a/modules/juce_audio_devices/native/oboe/include/oboe/AudioStream.h +++ b/modules/juce_audio_devices/native/oboe/include/oboe/AudioStream.h @@ -68,6 +68,29 @@ class AudioStream : public AudioStreamBase { return Result::OK; // Called by subclasses. Might do more in the future. } + /** + * Free the audio resources associated with a stream created by AAudioStreamBuilder_openStream(). + * + * AAudioStream_close() should be called at some point after calling this function. + * + * After this call, the stream will be in AAUDIO_STREAM_STATE_CLOSING + * + * This function is useful if you want to release the audio resources immediately, but still allow + * queries to the stream to occur from other threads. This often happens if you are monitoring + * stream progress from a UI thread. + * + * NOTE: This function is only fully implemented for MMAP streams, which are low latency streams + * supported by some devices. On other "Legacy" streams some audio resources will still be in use + * and some callbacks may still be in process after this call. + * + * Available in AAudio since API level 30. Returns Result::ErrorUnimplemented otherwise. + * + * * @return either Result::OK or an error. + */ + virtual Result release() { + return Result::ErrorUnimplemented; + } + /** * Close the stream and deallocate any resources from the open() call. */ @@ -262,6 +285,10 @@ class AudioStream : public AudioStreamBase { * The latency of an OUTPUT stream is generally higher than the INPUT latency * because an app generally tries to keep the OUTPUT buffer full and the INPUT buffer empty. * + * Note that due to issues in Android before R, we recommend NOT calling + * this method from a data callback. See this tech note for more details. + * https://github.com/google/oboe/wiki/TechNote_ReleaseBuffer + * * @return a ResultWithValue which has a result of Result::OK and a value containing the latency * in milliseconds, or a result of Result::Error*. */ @@ -280,6 +307,10 @@ class AudioStream : public AudioStreamBase { * The time is based on the implementation's best effort, using whatever knowledge is available * to the system, but cannot account for any delay unknown to the implementation. * + * Note that due to issues in Android before R, we recommend NOT calling + * this method from a data callback. See this tech note for more details. + * https://github.com/google/oboe/wiki/TechNote_ReleaseBuffer + * * @deprecated since 1.0, use AudioStream::getTimestamp(clockid_t clockId) instead, which * returns ResultWithValue * @param clockId the type of clock to use e.g. CLOCK_MONOTONIC @@ -303,6 +334,11 @@ class AudioStream : public AudioStreamBase { * The time is based on the implementation's best effort, using whatever knowledge is available * to the system, but cannot account for any delay unknown to the implementation. * + * Note that due to issues in Android before R, we recommend NOT calling + * this method from a data callback. See this tech note for more details. + * https://github.com/google/oboe/wiki/TechNote_ReleaseBuffer + * + * See * @param clockId the type of clock to use e.g. CLOCK_MONOTONIC * @return a FrameTimestamp containing the position and time at which a particular audio frame * entered or left the audio processing pipeline, or an error if the operation failed. @@ -422,7 +458,12 @@ class AudioStream : public AudioStreamBase { * This can be used with an EXCLUSIVE MMAP input stream to avoid reading data too close to * the DSP write position, which may cause glitches. * - * @param numFrames minimum frames available + * Starting with Oboe 1.7.1, the numFrames will be clipped internally against the + * BufferCapacity minus BurstSize. This is to prevent trying to wait for more frames + * than could possibly be available. In this case, the return value may be less than numFrames. + * Note that there may still be glitching if numFrames is too high. + * + * @param numFrames requested minimum frames available * @param timeoutNanoseconds * @return number of frames available, ErrorTimeout */ @@ -436,6 +477,66 @@ class AudioStream : public AudioStreamBase { return mErrorCallbackResult; } + + int32_t getDelayBeforeCloseMillis() const { + return mDelayBeforeCloseMillis; + } + + /** + * Set the time to sleep before closing the internal stream. + * + * Sometimes a callback can occur shortly after a stream has been stopped and + * even after a close! If the stream has been closed then the callback + * might access memory that has been freed, which could cause a crash. + * This seems to be more likely in Android P or earlier. + * But it can also occur in later versions. By sleeping, we give time for + * the callback threads to finish. + * + * Note that this only has an effect when OboeGlobals::areWorkaroundsEnabled() is true. + * + * @param delayBeforeCloseMillis time to sleep before close. + */ + void setDelayBeforeCloseMillis(int32_t delayBeforeCloseMillis) { + mDelayBeforeCloseMillis = delayBeforeCloseMillis; + } + + /** + * Enable or disable a device specific CPU performance hint. + * Runtime benchmarks such as the callback duration may be used to + * speed up the CPU and improve real-time performance. + * + * Note that this feature is device specific and may not be implemented. + * Also the benefits may vary by device. + * + * The flag will be checked in the Oboe data callback. If it transitions from false to true + * then the PerformanceHint feature will be started. + * This only needs to be called once. + * + * You may want to enable this if you have a dynamically changing workload + * and you notice that you are getting underruns and glitches when your workload increases. + * This might happen, for example, if you suddenly go from playing one note to + * ten notes on a synthesizer. + * + * Try the CPU Load test in OboeTester if you would like to experiment with this interactively. + * + * On some devices, this may be implemented using the "ADPF" library. + * + * @param enabled true if you would like a performance boost + */ + void setPerformanceHintEnabled(bool enabled) { + mPerformanceHintEnabled = enabled; + } + + /** + * This only tells you if the feature has been requested. + * It does not tell you if the PerformanceHint feature is implemented or active on the device. + * + * @return true if set using setPerformanceHintEnabled(). + */ + bool isPerformanceHintEnabled() { + return mPerformanceHintEnabled; + } + protected: /** @@ -497,6 +598,37 @@ class AudioStream : public AudioStreamBase { mDataCallbackEnabled = enabled; } + /** + * This should only be called as a stream is being opened. + * Otherwise we might override setDelayBeforeCloseMillis(). + */ + void calculateDefaultDelayBeforeCloseMillis(); + + /** + * Try to avoid a race condition when closing. + */ + void sleepBeforeClose() { + if (mDelayBeforeCloseMillis > 0) { + usleep(mDelayBeforeCloseMillis * 1000); + } + } + + /** + * This may be called internally at the beginning of a callback. + */ + virtual void beginPerformanceHintInCallback() {} + + /** + * This may be called internally at the end of a callback. + * @param numFrames passed to the callback + */ + virtual void endPerformanceHintInCallback(int32_t numFrames) {} + + /** + * This will be called when the stream is closed just in case performance hints were enabled. + */ + virtual void closePerformanceHint() {} + /* * Set a weak_ptr to this stream from the shared_ptr so that we can * later use a shared_ptr in the error callback. @@ -540,6 +672,11 @@ class AudioStream : public AudioStreamBase { */ int32_t mFramesPerBurst = kUnspecified; + // Time to sleep in order to prevent a race condition with a callback after a close(). + // Two milliseconds may be enough but 10 msec is even safer. + static constexpr int kMinDelayBeforeCloseMillis = 10; + int32_t mDelayBeforeCloseMillis = kMinDelayBeforeCloseMillis; + private: // Log the scheduler if it changes. @@ -548,6 +685,8 @@ class AudioStream : public AudioStreamBase { std::atomic mDataCallbackEnabled{false}; std::atomic mErrorCallbackCalled{false}; + + std::atomic mPerformanceHintEnabled{false}; // set only by app }; /** diff --git a/modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamBase.h b/modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamBase.h index e6c3d37c5d06..6222e448072b 100644 --- a/modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamBase.h +++ b/modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamBase.h @@ -157,6 +157,41 @@ class AudioStreamBase { */ SessionId getSessionId() const { return mSessionId; } + /** + * @return whether the content of the stream is spatialized. + */ + bool isContentSpatialized() const { return mIsContentSpatialized; } + + /** + * @return the spatialization behavior for the stream. + */ + SpatializationBehavior getSpatializationBehavior() const { return mSpatializationBehavior; } + + /** + * Return the policy that determines whether the audio may or may not be captured + * by other apps or the system. + * + * See AudioStreamBuilder_setAllowedCapturePolicy(). + * + * Added in API level 29 to AAudio. + * + * @return the allowed capture policy, for example AllowedCapturePolicy::All + */ + AllowedCapturePolicy getAllowedCapturePolicy() const { return mAllowedCapturePolicy; } + + /** + * Return whether this input stream is marked as privacy sensitive. + * + * See AudioStreamBuilder_setPrivacySensitiveMode(). + * + * Added in API level 30 to AAudio. + * + * @return PrivacySensitiveMode::Enabled if privacy sensitive, + * PrivacySensitiveMode::Disabled if not privacy sensitive, and + * PrivacySensitiveMode::Unspecified if API is not supported. + */ + PrivacySensitiveMode getPrivacySensitiveMode() const { return mPrivacySensitiveMode; } + /** * @return true if Oboe can convert channel counts to achieve optimal results. */ @@ -178,12 +213,36 @@ class AudioStreamBase { return mSampleRateConversionQuality; } + /** + * @return the stream's channel mask. + */ + ChannelMask getChannelMask() const { + return mChannelMask; + } + + /** + * @return number of channels for the hardware, for example 2 for stereo, or kUnspecified. + */ + int32_t getHardwareChannelCount() const { return mHardwareChannelCount; } + + /** + * @return hardware sample rate for the stream or kUnspecified + */ + int32_t getHardwareSampleRate() const { return mHardwareSampleRate; } + + /** + * @return the audio sample format of the hardware (e.g. Float or I16) + */ + AudioFormat getHardwareFormat() const { return mHardwareFormat; } + protected: /** The callback which will be fired when new data is ready to be read/written. **/ AudioStreamDataCallback *mDataCallback = nullptr; + std::shared_ptr mSharedDataCallback; /** The callback which will be fired when an error or a disconnect occurs. **/ AudioStreamErrorCallback *mErrorCallback = nullptr; + std::shared_ptr mSharedErrorCallback; /** Number of audio frames which will be requested in each callback */ int32_t mFramesPerCallback = kUnspecified; @@ -197,6 +256,8 @@ class AudioStreamBase { int32_t mBufferCapacityInFrames = kUnspecified; /** Stream buffer size specified as a number of audio frames */ int32_t mBufferSizeInFrames = kUnspecified; + /** Stream channel mask. Only active on Android 32+ */ + ChannelMask mChannelMask = ChannelMask::Unspecified; /** Stream sharing mode */ SharingMode mSharingMode = SharingMode::Shared; @@ -218,11 +279,29 @@ class AudioStreamBase { /** Stream session ID allocation strategy. Only active on Android 28+ */ SessionId mSessionId = SessionId::None; + /** Allowed Capture Policy. Only active on Android 29+ */ + AllowedCapturePolicy mAllowedCapturePolicy = AllowedCapturePolicy::Unspecified; + + /** Privacy Sensitive Mode. Only active on Android 30+ */ + PrivacySensitiveMode mPrivacySensitiveMode = PrivacySensitiveMode::Unspecified; + /** Control the name of the package creating the stream. Only active on Android 31+ */ std::string mPackageName; /** Control the attribution tag of the context creating the stream. Only active on Android 31+ */ std::string mAttributionTag; + /** Whether the content is already spatialized. Only used on Android 32+ */ + bool mIsContentSpatialized = false; + /** Spatialization Behavior. Only active on Android 32+ */ + SpatializationBehavior mSpatializationBehavior = SpatializationBehavior::Unspecified; + + /** Hardware channel count. Only specified on Android 34+ AAudio streams */ + int32_t mHardwareChannelCount = kUnspecified; + /** Hardware sample rate. Only specified on Android 34+ AAudio streams */ + int32_t mHardwareSampleRate = kUnspecified; + /** Hardware format. Only specified on Android 34+ AAudio streams */ + AudioFormat mHardwareFormat = AudioFormat::Unspecified; + // Control whether Oboe can convert channel counts to achieve optimal results. bool mChannelConversionAllowed = false; // Control whether Oboe can convert data formats to achieve optimal results. @@ -238,10 +317,9 @@ class AudioStreamBase { case AudioFormat::Float: case AudioFormat::I24: case AudioFormat::I32: + case AudioFormat::IEC61937: break; - // JUCE CHANGE STARTS HERE - case AudioFormat::Invalid: - // JUCE CHANGE ENDS HERE + default: return Result::ErrorInvalidFormat; } diff --git a/modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamBuilder.h b/modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamBuilder.h index c7ea7af345a1..89e1447efff2 100644 --- a/modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamBuilder.h +++ b/modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamBuilder.h @@ -19,6 +19,7 @@ #include "oboe/Definitions.h" #include "oboe/AudioStreamBase.h" +#include "oboe/Utilities.h" #include "ResultWithValue.h" namespace oboe { @@ -42,12 +43,36 @@ class AudioStreamBuilder : public AudioStreamBase { * * Default is kUnspecified. If the value is unspecified then * the application should query for the actual value after the stream is opened. + * + * As the channel count here may be different from the corresponding channel count of + * provided channel mask used in setChannelMask(). The last called will be respected + * if this function and setChannelMask() are called. */ AudioStreamBuilder *setChannelCount(int channelCount) { mChannelCount = channelCount; + mChannelMask = ChannelMask::Unspecified; return this; } + /** + * Request a specific channel mask. + * + * Default is kUnspecified. If the value is unspecified then the application + * should query for the actual value after the stream is opened. + * + * As the corresponding channel count of provided channel mask here may be different + * from the channel count used in setChannelCount(). The last called will be respected + * if this function and setChannelCount() are called. + * + * As the setChannelMask API is available on Android 32+, this call will only take effects + * on Android 32+. + */ + AudioStreamBuilder *setChannelMask(ChannelMask channelMask) { + mChannelMask = channelMask; + mChannelCount = getChannelCountFromChannelMask(channelMask); + return this; + } + /** * Request the direction for a stream. The default is Direction::Output. * @@ -92,6 +117,14 @@ class AudioStreamBuilder : public AudioStreamBase { * the callbacks. But if your application is, for example, doing FFTs or other block * oriented operations, then call this function to get the sizes you need. * + * Calling setFramesPerDataCallback() does not guarantee anything about timing. + * This just collects the data into a the number of frames that your app requires. + * We encourage leaving this unspecified in most cases. + * + * If this number is larger than the burst size, some bursts will not receive a callback. + * If this number is smaller than the burst size, there may be multiple callbacks in a single + * burst. + * * @param framesPerCallback * @return pointer to the builder so calls can be chained */ @@ -295,11 +328,14 @@ class AudioStreamBuilder : public AudioStreamBase { * In most cases, the primary device will be the appropriate device to use, and the * deviceId can be left kUnspecified. * - * On Android, for example, the ID could be obtained from the Java AudioManager. - * AudioManager.getDevices() returns an array of AudioDeviceInfo[], which contains - * a getId() method (as well as other type information), that should be passed - * to this method. + * The ID could be obtained from the Java AudioManager. + * AudioManager.getDevices() returns an array of AudioDeviceInfo, + * which contains a getId() method. That ID can be passed to this function. * + * It is possible that you may not get the device that you requested. + * So if it is important to you, you should call + * stream->getDeviceId() after the stream is opened to + * verify the actual ID. * * Note that when using OpenSL ES, this will be ignored and the created * stream will have deviceId kUnspecified. @@ -312,17 +348,115 @@ class AudioStreamBuilder : public AudioStreamBase { return this; } + /** + * Specify whether this stream audio may or may not be captured by other apps or the system. + * + * The default is AllowedCapturePolicy::Unspecified which maps to AAUDIO_ALLOW_CAPTURE_BY_ALL. + * + * Note that an application can also set its global policy, in which case the most restrictive + * policy is always applied. See android.media.AudioAttributes.setAllowedCapturePolicy. + * + * Added in API level 29 to AAudio. + * + * @param inputPreset the desired level of opt-out from being captured. + * @return pointer to the builder so calls can be chained + */ + AudioStreamBuilder *setAllowedCapturePolicy(AllowedCapturePolicy allowedCapturePolicy) { + mAllowedCapturePolicy = allowedCapturePolicy; + return this; + } + + /** Indicates whether this input stream must be marked as privacy sensitive or not. + * + * When PrivacySensitiveMode::Enabled, this input stream is privacy sensitive and any + * concurrent capture is not permitted. + * + * This is off (PrivacySensitiveMode::Disabled) by default except when the input preset is + * InputPreset::VoiceRecognition or InputPreset::Camcorder + * + * Always takes precedence over default from input preset when set explicitly. + * + * Only relevant if the stream direction is Direction::Input and AAudio is used. + * + * Added in API level 30 to AAudio. + * + * @param privacySensitive PrivacySensitiveMode::Enabled if capture from this stream must be + * marked as privacy sensitive, PrivacySensitiveMode::Disabled if stream should be marked as + * not sensitive. + * @return pointer to the builder so calls can be chained + */ + AudioStreamBuilder *setPrivacySensitiveMode(PrivacySensitiveMode privacySensitiveMode) { + mPrivacySensitiveMode = privacySensitiveMode; + return this; + } + + /** + * Specifies whether the audio data of this output stream has already been processed for spatialization. + * + * If the stream has been processed for spatialization, setting this to true will prevent issues such as + * double-processing on platforms that will spatialize audio data. + * + * This is false by default. + * + * Available since API level 32. + * + * @param isContentSpatialized whether the content is already spatialized + * @return pointer to the builder so calls can be chained + */ + AudioStreamBuilder *setIsContentSpatialized(bool isContentSpatialized) { + mIsContentSpatialized = isContentSpatialized; + return this; + } + + /** + * Sets the behavior affecting whether spatialization will be used. + * + * The AAudio system will use this information to select whether the stream will go through a + * spatializer effect or not when the effect is supported and enabled. + * + * This is SpatializationBehavior::Never by default. + * + * Available since API level 32. + * + * @param spatializationBehavior the desired spatialization behavior + * @return pointer to the builder so calls can be chained + */ + AudioStreamBuilder *setSpatializationBehavior(SpatializationBehavior spatializationBehavior) { + mSpatializationBehavior = spatializationBehavior; + return this; + } + /** * Specifies an object to handle data related callbacks from the underlying API. * * Important: See AudioStreamCallback for restrictions on what may be called * from the callback methods. * - * @param dataCallback + * We pass a shared_ptr so that the sharedDataCallback object cannot be deleted + * before the stream is deleted. + * + * @param sharedDataCallback * @return pointer to the builder so calls can be chained */ - AudioStreamBuilder *setDataCallback(oboe::AudioStreamDataCallback *dataCallback) { + AudioStreamBuilder *setDataCallback(std::shared_ptr sharedDataCallback) { + // Use this raw pointer in the rest of the code to retain backwards compatibility. + mDataCallback = sharedDataCallback.get(); + // Hold a shared_ptr to protect the raw pointer for the lifetime of the stream. + mSharedDataCallback = sharedDataCallback; + return this; + } + + /** + * Pass a raw pointer to a data callback. This is not recommended because the dataCallback + * object might get deleted by the app while it is being used. + * + * @deprecated Call setDataCallback(std::shared_ptr) instead. + * @param dataCallback + * @return pointer to the builder so calls can be chained + */ + AudioStreamBuilder *setDataCallback(AudioStreamDataCallback *dataCallback) { mDataCallback = dataCallback; + mSharedDataCallback = nullptr; return this; } @@ -338,11 +472,32 @@ class AudioStreamBuilder : public AudioStreamBase { * When an error callback occurs, the associated stream must be stopped and closed * in a separate thread. * - * @param errorCallback + * We pass a shared_ptr so that the errorCallback object cannot be deleted before the stream is deleted. + * If the stream was created using a shared_ptr then the stream cannot be deleted before the + * error callback has finished running. + * + * @param sharedErrorCallback * @return pointer to the builder so calls can be chained */ - AudioStreamBuilder *setErrorCallback(oboe::AudioStreamErrorCallback *errorCallback) { + AudioStreamBuilder *setErrorCallback(std::shared_ptr sharedErrorCallback) { + // Use this raw pointer in the rest of the code to retain backwards compatibility. + mErrorCallback = sharedErrorCallback.get(); + // Hold a shared_ptr to protect the raw pointer for the lifetime of the stream. + mSharedErrorCallback = sharedErrorCallback; + return this; + } + + /** + * Pass a raw pointer to an error callback. This is not recommended because the errorCallback + * object might get deleted by the app while it is being used. + * + * @deprecated Call setErrorCallback(std::shared_ptr) instead. + * @param errorCallback + * @return pointer to the builder so calls can be chained + */ + AudioStreamBuilder *setErrorCallback(AudioStreamErrorCallback *errorCallback) { mErrorCallback = errorCallback; + mSharedErrorCallback = nullptr; return this; } @@ -354,18 +509,8 @@ class AudioStreamBuilder : public AudioStreamBase { * Important: See AudioStreamCallback for restrictions on what may be called * from the callback methods. * - * When an error callback occurs, the associated stream will be stopped and closed in a separate thread. - * - * A note on why the streamCallback parameter is a raw pointer rather than a smart pointer: - * - * The caller should retain ownership of the object streamCallback points to. At first glance weak_ptr may seem like - * a good candidate for streamCallback as this implies temporary ownership. However, a weak_ptr can only be created - * from a shared_ptr. A shared_ptr incurs some performance overhead. The callback object is likely to be accessed - * every few milliseconds when the stream requires new data so this overhead is something we want to avoid. - * - * This leaves a raw pointer as the logical type choice. The only caveat being that the caller must not destroy - * the callback before the stream has been closed. - * + * @deprecated Call setDataCallback(std::shared_ptr) and + * setErrorCallback(std::shared_ptr) instead. * @param streamCallback * @return pointer to the builder so calls can be chained */ @@ -383,7 +528,7 @@ class AudioStreamBuilder : public AudioStreamBase { * On some devices, mono streams might be broken, so a stereo stream might be opened * and converted to mono. * - * Default is true. + * Default is false. */ AudioStreamBuilder *setChannelConversionAllowed(bool allowed) { mChannelConversionAllowed = allowed; @@ -419,32 +564,37 @@ class AudioStreamBuilder : public AudioStreamBase { } /** - * Declare the name of the package creating the stream. - * - * This is usually Context#getPackageName() - * - * The default, if you do not call this function, is a random package in the calling uid. - * - * Added in API level 31. - * - * @param packageName packageName of the calling app. - */ + * Declare the name of the package creating the stream. + * + * This is usually {@code Context#getPackageName()}. + * + * The default, if you do not call this function, is a random package in the calling uid. + * The vast majority of apps have only one package per calling UID. + * If an invalid package name is set, input streams may not be given permission to + * record when started. + * + * The package name is usually the applicationId in your app's build.gradle file. + * + * Available since API level 31. + * + * @param packageName packageName of the calling app. + */ AudioStreamBuilder *setPackageName(std::string packageName) { mPackageName = packageName; return this; } /** - * Declare the attribution tag of the context creating the stream. - * - * This is usually Context#getAttributionTag() - * - * The default, if you do not call this function, is the default attribution tag. - * - * Added in API level 31. - * - * @param attributionTag attributionTag of the calling context. - */ + * Declare the attribution tag of the context creating the stream. + * + * This is usually {@code Context#getAttributionTag()}. + * + * The default, if you do not call this function, is null. + * + * Available since API level 31. + * + * @param attributionTag attributionTag of the calling context. + */ AudioStreamBuilder *setAttributionTag(std::string attributionTag) { mAttributionTag = attributionTag; return this; diff --git a/modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamCallback.h b/modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamCallback.h index 915c3d71b2be..17d28ba7081c 100644 --- a/modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamCallback.h +++ b/modules/juce_audio_devices/native/oboe/include/oboe/AudioStreamCallback.h @@ -92,6 +92,10 @@ class AudioStreamDataCallback { * being alerted when a stream has an error or is disconnected * using `onError*` methods. * + * Note: This callback is only fired when an AudioStreamCallback is set. + * If you use AudioStream::write() you have to evaluate the return codes of + * AudioStream::write() to notice errors in the stream. + * * It is used with AudioStreamBuilder::setErrorCallback(). */ class AudioStreamErrorCallback { diff --git a/modules/juce_audio_devices/native/oboe/include/oboe/Definitions.h b/modules/juce_audio_devices/native/oboe/include/oboe/Definitions.h index 566518f081c6..aaf4d6403ee3 100644 --- a/modules/juce_audio_devices/native/oboe/include/oboe/Definitions.h +++ b/modules/juce_audio_devices/native/oboe/include/oboe/Definitions.h @@ -98,6 +98,8 @@ namespace oboe { /** * Unspecified format. Format will be decided by Oboe. + * When calling getHardwareFormat(), this will be returned if + * the API is not supported. */ Unspecified = 0, // AAUDIO_FORMAT_UNSPECIFIED, @@ -137,6 +139,19 @@ namespace oboe { */ I32 = 4, // AAUDIO_FORMAT_PCM_I32 + /** + * This format is used for compressed audio wrapped in IEC61937 for HDMI + * or S/PDIF passthrough. + * + * Unlike PCM playback, the Android framework is not able to do format + * conversion for IEC61937. In that case, when IEC61937 is requested, sampling + * rate and channel count or channel mask must be specified. Otherwise, it may + * fail when opening the stream. Apps are able to get the correct configuration + * for the playback by calling AudioManager#getDevices(int). + * + * Available since API 34 (U). + */ + IEC61937 = 5, // AAUDIO_FORMAT_IEC61937 }; /** @@ -244,11 +259,14 @@ namespace oboe { /** * Use OpenSL ES. + * Note that OpenSL ES is deprecated in Android 13, API 30 and above. */ OpenSLES, /** * Try to use AAudio. Fail if unavailable. + * AAudio was first supported in Android 8, API 26 and above. + * It is only recommended for API 27 and above. */ AAudio }; @@ -268,8 +286,17 @@ namespace oboe { * This may be implemented using bilinear interpolation. */ Fastest, + /** + * Low quality conversion with 8 taps. + */ Low, + /** + * Medium quality conversion with 16 taps. + */ Medium, + /** + * High quality conversion with 32 taps. + */ High, /** * Highest quality conversion, which may be expensive in terms of CPU. @@ -482,6 +509,331 @@ namespace oboe { Stereo = 2, }; + /** + * The channel mask of the audio stream. The underlying type is `uint32_t`. + * Use of this enum is convenient. + * + * ChannelMask::Unspecified means this is not specified. + * The rest of the enums are channel position masks. + * Use the combinations of the channel position masks defined below instead of + * using those values directly. + * + * Channel masks are for input only, output only, or both input and output. + * These channel masks are different than those defined in AudioFormat.java. + * If an app gets a channel mask from Java API and wants to use it in Oboe, + * conversion should be done by the app. + */ + enum class ChannelMask : uint32_t { // aaudio_channel_mask_t + Unspecified = kUnspecified, + FrontLeft = 1 << 0, + FrontRight = 1 << 1, + FrontCenter = 1 << 2, + LowFrequency = 1 << 3, + BackLeft = 1 << 4, + BackRight = 1 << 5, + FrontLeftOfCenter = 1 << 6, + FrontRightOfCenter = 1 << 7, + BackCenter = 1 << 8, + SideLeft = 1 << 9, + SideRight = 1 << 10, + TopCenter = 1 << 11, + TopFrontLeft = 1 << 12, + TopFrontCenter = 1 << 13, + TopFrontRight = 1 << 14, + TopBackLeft = 1 << 15, + TopBackCenter = 1 << 16, + TopBackRight = 1 << 17, + TopSideLeft = 1 << 18, + TopSideRight = 1 << 19, + BottomFrontLeft = 1 << 20, + BottomFrontCenter = 1 << 21, + BottomFrontRight = 1 << 22, + LowFrequency2 = 1 << 23, + FrontWideLeft = 1 << 24, + FrontWideRight = 1 << 25, + + /** + * Supported for Input and Output + */ + Mono = FrontLeft, + + /** + * Supported for Input and Output + */ + Stereo = FrontLeft | + FrontRight, + + /** + * Supported for only Output + */ + CM2Point1 = FrontLeft | + FrontRight | + LowFrequency, + + /** + * Supported for only Output + */ + Tri = FrontLeft | + FrontRight | + FrontCenter, + + /** + * Supported for only Output + */ + TriBack = FrontLeft | + FrontRight | + BackCenter, + + /** + * Supported for only Output + */ + CM3Point1 = FrontLeft | + FrontRight | + FrontCenter | + LowFrequency, + + /** + * Supported for Input and Output + */ + CM2Point0Point2 = FrontLeft | + FrontRight | + TopSideLeft | + TopSideRight, + + /** + * Supported for Input and Output + */ + CM2Point1Point2 = CM2Point0Point2 | + LowFrequency, + + /** + * Supported for Input and Output + */ + CM3Point0Point2 = FrontLeft | + FrontRight | + FrontCenter | + TopSideLeft | + TopSideRight, + + /** + * Supported for Input and Output + */ + CM3Point1Point2 = CM3Point0Point2 | + LowFrequency, + + /** + * Supported for only Output + */ + Quad = FrontLeft | + FrontRight | + BackLeft | + BackRight, + + /** + * Supported for only Output + */ + QuadSide = FrontLeft | + FrontRight | + SideLeft | + SideRight, + + /** + * Supported for only Output + */ + Surround = FrontLeft | + FrontRight | + FrontCenter | + BackCenter, + + /** + * Supported for only Output + */ + Penta = Quad | + FrontCenter, + + /** + * Supported for Input and Output. aka 5Point1Back + */ + CM5Point1 = FrontLeft | + FrontRight | + FrontCenter | + LowFrequency | + BackLeft | + BackRight, + + /** + * Supported for only Output + */ + CM5Point1Side = FrontLeft | + FrontRight | + FrontCenter | + LowFrequency | + SideLeft | + SideRight, + + /** + * Supported for only Output + */ + CM6Point1 = FrontLeft | + FrontRight | + FrontCenter | + LowFrequency | + BackLeft | + BackRight | + BackCenter, + + /** + * Supported for only Output + */ + CM7Point1 = CM5Point1 | + SideLeft | + SideRight, + + /** + * Supported for only Output + */ + CM5Point1Point2 = CM5Point1 | + TopSideLeft | + TopSideRight, + + /** + * Supported for only Output + */ + CM5Point1Point4 = CM5Point1 | + TopFrontLeft | + TopFrontRight | + TopBackLeft | + TopBackRight, + + /** + * Supported for only Output + */ + CM7Point1Point2 = CM7Point1 | + TopSideLeft | + TopSideRight, + + /** + * Supported for only Output + */ + CM7Point1Point4 = CM7Point1 | + TopFrontLeft | + TopFrontRight | + TopBackLeft | + TopBackRight, + + /** + * Supported for only Output + */ + CM9Point1Point4 = CM7Point1Point4 | + FrontWideLeft | + FrontWideRight, + + /** + * Supported for only Output + */ + CM9Point1Point6 = CM9Point1Point4 | + TopSideLeft | + TopSideRight, + + /** + * Supported for only Input + */ + FrontBack = FrontCenter | + BackCenter, + }; + + /** + * The spatialization behavior of the audio stream. + */ + enum class SpatializationBehavior : int32_t { + + /** + * Constant indicating that the spatialization behavior is not specified. + */ + Unspecified = kUnspecified, + + /** + * Constant indicating the audio content associated with these attributes will follow the + * default platform behavior with regards to which content will be spatialized or not. + */ + Auto = 1, + + /** + * Constant indicating the audio content associated with these attributes should never + * be spatialized. + */ + Never = 2, + }; + + /** + * The PrivacySensitiveMode attribute determines whether an input stream can be shared + * with another privileged app, for example the Assistant. + * + * This allows to override the default behavior tied to the audio source (e.g + * InputPreset::VoiceCommunication is private by default but InputPreset::Unprocessed is not). + */ + enum class PrivacySensitiveMode : int32_t { + + /** + * When not explicitly requested, set privacy sensitive mode according to input preset: + * communication and camcorder captures are considered privacy sensitive by default. + */ + Unspecified = kUnspecified, + + /** + * Privacy sensitive mode disabled. + */ + Disabled = 1, + + /** + * Privacy sensitive mode enabled. + */ + Enabled = 2, + }; + + /** + * Specifies whether audio may or may not be captured by other apps or the system for an + * output stream. + * + * Note that these match the equivalent values in AudioAttributes in the Android Java API. + * + * Added in API level 29 for AAudio. + */ + enum class AllowedCapturePolicy : int32_t { + /** + * When not explicitly requested, set privacy sensitive mode according to the Usage. + * This should behave similarly to setting AllowedCapturePolicy::All. + */ + Unspecified = kUnspecified, + /** + * Indicates that the audio may be captured by any app. + * + * For privacy, the following Usages can not be recorded: VoiceCommunication*, + * Notification*, Assistance* and Assistant. + * + * On Android Q, only Usage::Game and Usage::Media may be captured. + * + * See ALLOW_CAPTURE_BY_ALL in the AudioAttributes Java API. + */ + All = 1, + /** + * Indicates that the audio may only be captured by system apps. + * + * System apps can capture for many purposes like accessibility, user guidance... + * but have strong restriction. See ALLOW_CAPTURE_BY_SYSTEM in the AudioAttributes Java API + * for what the system apps can do with the capture audio. + */ + System = 2, + /** + * Indicates that the audio may not be recorded by any app, even if it is a system app. + * + * It is encouraged to use AllowedCapturePolicy::System instead of this value as system apps + * provide significant and useful features for the user (eg. accessibility). + * See ALLOW_CAPTURE_BY_NONE in the AudioAttributes Java API + */ + None = 3, + }; + /** * On API 16 to 26 OpenSL ES will be used. When using OpenSL ES the optimal values for sampleRate and * framesPerBurst are not known by the native code. diff --git a/modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.h b/modules/juce_audio_devices/native/oboe/include/oboe/FifoBuffer.h similarity index 63% rename from modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.h rename to modules/juce_audio_devices/native/oboe/include/oboe/FifoBuffer.h index 6cced2d34ba1..68c1f055ab5e 100644 --- a/modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.h +++ b/modules/juce_audio_devices/native/oboe/include/oboe/FifoBuffer.h @@ -22,14 +22,30 @@ #include "oboe/Definitions.h" -#include "FifoControllerBase.h" +#include "oboe/FifoControllerBase.h" namespace oboe { class FifoBuffer { public: + /** + * Construct a `FifoBuffer`. + * + * @param bytesPerFrame amount of bytes for one frame + * @param capacityInFrames the capacity of frames in fifo + */ FifoBuffer(uint32_t bytesPerFrame, uint32_t capacityInFrames); + /** + * Construct a `FifoBuffer`. + * To be used if the storage allocation is done outside of FifoBuffer. + * + * @param bytesPerFrame amount of bytes for one frame + * @param capacityInFrames capacity of frames in fifo + * @param readCounterAddress address of read counter + * @param writeCounterAddress address of write counter + * @param dataStorageAddress address of storage + */ FifoBuffer(uint32_t bytesPerFrame, uint32_t capacityInFrames, std::atomic *readCounterAddress, @@ -38,18 +54,36 @@ class FifoBuffer { ~FifoBuffer(); + /** + * Convert a number of frames in bytes. + * + * @return number of bytes + */ int32_t convertFramesToBytes(int32_t frames); /** * Read framesToRead or, if not enough, then read as many as are available. + * * @param destination * @param framesToRead number of frames requested * @return number of frames actually read */ int32_t read(void *destination, int32_t framesToRead); + /** + * Write framesToWrite or, if too enough, then write as many as the fifo are not empty. + * + * @param destination + * @param framesToWrite number of frames requested + * @return number of frames actually write + */ int32_t write(const void *source, int32_t framesToWrite); + /** + * Get the buffer capacity in frames. + * + * @return number of frames + */ uint32_t getBufferCapacityInFrames() const; /** @@ -62,25 +96,56 @@ class FifoBuffer { */ int32_t readNow(void *destination, int32_t numFrames); + /** + * Get the number of frames in the fifo. + * + * @return number of frames actually in the buffer + */ uint32_t getFullFramesAvailable() { return mFifo->getFullFramesAvailable(); } + /** + * Get the amount of bytes per frame. + * + * @return number of bytes per frame + */ uint32_t getBytesPerFrame() const { return mBytesPerFrame; } + /** + * Get the position of read counter. + * + * @return position of read counter + */ uint64_t getReadCounter() const { return mFifo->getReadCounter(); } + /** + * Set the position of read counter. + * + * @param n position of read counter + */ void setReadCounter(uint64_t n) { mFifo->setReadCounter(n); } + /** + * Get the position of write counter. + * + * @return position of write counter + */ uint64_t getWriteCounter() { return mFifo->getWriteCounter(); } + + /** + * Set the position of write counter. + * + * @param n position of write counter + */ void setWriteCounter(uint64_t n) { mFifo->setWriteCounter(n); } diff --git a/modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.h b/modules/juce_audio_devices/native/oboe/include/oboe/FifoControllerBase.h similarity index 74% rename from modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.h rename to modules/juce_audio_devices/native/oboe/include/oboe/FifoControllerBase.h index a4c2b41a5e5e..6c12b75ea867 100644 --- a/modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.h +++ b/modules/juce_audio_devices/native/oboe/include/oboe/FifoControllerBase.h @@ -34,9 +34,11 @@ namespace oboe { class FifoControllerBase { public: - /** - * @param totalFrames capacity of the circular buffer in frames. - */ + /** + * Construct a `FifoControllerBase`. + * + * @param totalFrames capacity of the circular buffer in frames + */ FifoControllerBase(uint32_t totalFrames); virtual ~FifoControllerBase() = default; @@ -45,35 +47,53 @@ class FifoControllerBase { * The frames available to read will be calculated from the read and write counters. * The result will be clipped to the capacity of the buffer. * If the buffer has underflowed then this will return zero. + * * @return number of valid frames available to read. */ uint32_t getFullFramesAvailable() const; - /** + /** * The index in a circular buffer of the next frame to read. + * + * @return read index position */ uint32_t getReadIndex() const; - /** - * @param numFrames number of frames to advance the read index - */ + /** + * Advance read index from a number of frames. + * Equivalent of incrementReadCounter(numFrames). + * + * @param numFrames number of frames to advance the read index + */ void advanceReadIndex(uint32_t numFrames); - /** - * @return maximum number of frames that can be written without exceeding the threshold. - */ + /** + * Get the number of frame that are not written yet. + * + * @return maximum number of frames that can be written without exceeding the threshold + */ uint32_t getEmptyFramesAvailable() const; /** - * The index in a circular buffer of the next frame to write. - */ + * The index in a circular buffer of the next frame to write. + * + * @return index of the next frame to write + */ uint32_t getWriteIndex() const; - /** + /** + * Advance write index from a number of frames. + * Equivalent of incrementWriteCounter(numFrames). + * * @param numFrames number of frames to advance the write index */ void advanceWriteIndex(uint32_t numFrames); + /** + * Get the frame capacity of the fifo. + * + * @return frame capacity + */ uint32_t getFrameCapacity() const { return mTotalFrames; } virtual uint64_t getReadCounter() const = 0; diff --git a/modules/juce_audio_devices/native/oboe/include/oboe/FullDuplexStream.h b/modules/juce_audio_devices/native/oboe/include/oboe/FullDuplexStream.h new file mode 100644 index 000000000000..15d2489a53d4 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/include/oboe/FullDuplexStream.h @@ -0,0 +1,324 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBOE_FULL_DUPLEX_STREAM_ +#define OBOE_FULL_DUPLEX_STREAM_ + +#include +#include "oboe/Definitions.h" +#include "oboe/AudioStream.h" +#include "oboe/AudioStreamCallback.h" + +namespace oboe { + +/** + * FullDuplexStream can be used to synchronize an input and output stream. + * + * For the builder of the output stream, call setDataCallback() with this object. + * + * When both streams are ready, onAudioReady() of the output stream will call onBothStreamsReady(). + * Callers must override onBothStreamsReady(). + * + * To ensure best results, open an output stream before the input stream. + * Call inputBuilder.setBufferCapacityInFrames(mOutputStream->getBufferCapacityInFrames() * 2). + * Also, call inputBuilder.setSampleRate(mOutputStream->getSampleRate()). + * + * Callers must call setInputStream() and setOutputStream(). + * Call start() to start both streams and stop() to stop both streams. + * Caller is responsible for closing both streams. + * + * Callers should handle error callbacks with setErrorCallback() for the output stream. + * When an error callback occurs for the output stream, Oboe will stop and close the output stream. + * The caller is responsible for stopping and closing the input stream. + * The caller should also reopen and restart both streams when the error callback is ErrorDisconnected. + * See the LiveEffect sample as an example of this. + * + */ +class FullDuplexStream : public AudioStreamDataCallback { +public: + FullDuplexStream() {} + virtual ~FullDuplexStream() = default; + + /** + * Sets the input stream. Calling this is mandatory. + * + * @param stream the output stream + */ + void setInputStream(AudioStream *stream) { + mInputStream = stream; + } + + /** + * Gets the input stream + * + * @return the input stream + */ + AudioStream *getInputStream() { + return mInputStream; + } + + /** + * Sets the output stream. Calling this is mandatory. + * + * @param stream the output stream + */ + void setOutputStream(AudioStream *stream) { + mOutputStream = stream; + } + + /** + * Gets the output stream + * + * @return the output stream + */ + AudioStream *getOutputStream() { + return mOutputStream; + } + + /** + * Attempts to start both streams. Please call setInputStream() and setOutputStream() before + * calling this function. + * + * @return result of the operation + */ + virtual Result start() { + mCountCallbacksToDrain = kNumCallbacksToDrain; + mCountInputBurstsCushion = mNumInputBurstsCushion; + mCountCallbacksToDiscard = kNumCallbacksToDiscard; + + // Determine maximum size that could possibly be called. + int32_t bufferSize = getOutputStream()->getBufferCapacityInFrames() + * getOutputStream()->getChannelCount(); + if (bufferSize > mBufferSize) { + mInputBuffer = std::make_unique(bufferSize); + mBufferSize = bufferSize; + } + + oboe::Result result = getInputStream()->requestStart(); + if (result != oboe::Result::OK) { + return result; + } + return getOutputStream()->requestStart(); + } + + /** + * Stops both streams. Returns Result::OK if neither stream had an error during close. + * + * @return result of the operation + */ + virtual Result stop() { + Result outputResult = Result::OK; + Result inputResult = Result::OK; + if (getOutputStream()) { + outputResult = mOutputStream->requestStop(); + } + if (getInputStream()) { + inputResult = mInputStream->requestStop(); + } + if (outputResult != Result::OK) { + return outputResult; + } else { + return inputResult; + } + } + + /** + * Reads input from the input stream. Callers should not call this directly as this is called + * in onAudioReady(). + * + * @param numFrames + * @return result of the operation + */ + virtual ResultWithValue readInput(int32_t numFrames) { + return getInputStream()->read(mInputBuffer.get(), numFrames, 0 /* timeout */); + } + + /** + * Called when data is available on both streams. + * Caller should override this method. + * numInputFrames and numOutputFrames may be zero. + * + * @param inputData buffer containing input data + * @param numInputFrames number of input frames + * @param outputData a place to put output data + * @param numOutputFrames number of output frames + * @return DataCallbackResult::Continue or DataCallbackResult::Stop + */ + virtual DataCallbackResult onBothStreamsReady( + const void *inputData, + int numInputFrames, + void *outputData, + int numOutputFrames + ) = 0; + + /** + * Called when the output stream is ready to process audio. + * This in return calls onBothStreamsReady() when data is available on both streams. + * Callers should call this function when the output stream is ready. + * Callers must override onBothStreamsReady(). + * + * @param audioStream pointer to the associated stream + * @param audioData a place to put output data + * @param numFrames number of frames to be processed + * @return DataCallbackResult::Continue or DataCallbackResult::Stop + * + */ + DataCallbackResult onAudioReady( + AudioStream *audioStream, + void *audioData, + int numFrames) { + DataCallbackResult callbackResult = DataCallbackResult::Continue; + int32_t actualFramesRead = 0; + + // Silence the output. + int32_t numBytes = numFrames * getOutputStream()->getBytesPerFrame(); + memset(audioData, 0 /* value */, numBytes); + + if (mCountCallbacksToDrain > 0) { + // Drain the input. + int32_t totalFramesRead = 0; + do { + ResultWithValue result = readInput(numFrames); + if (!result) { + // Ignore errors because input stream may not be started yet. + break; + } + actualFramesRead = result.value(); + totalFramesRead += actualFramesRead; + } while (actualFramesRead > 0); + // Only counts if we actually got some data. + if (totalFramesRead > 0) { + mCountCallbacksToDrain--; + } + + } else if (mCountInputBurstsCushion > 0) { + // Let the input fill up a bit so we are not so close to the write pointer. + mCountInputBurstsCushion--; + + } else if (mCountCallbacksToDiscard > 0) { + mCountCallbacksToDiscard--; + // Ignore. Allow the input to reach to equilibrium with the output. + ResultWithValue resultAvailable = getInputStream()->getAvailableFrames(); + if (!resultAvailable) { + callbackResult = DataCallbackResult::Stop; + } else { + int32_t framesAvailable = resultAvailable.value(); + if (framesAvailable >= mMinimumFramesBeforeRead) { + ResultWithValue resultRead = readInput(numFrames); + if (!resultRead) { + callbackResult = DataCallbackResult::Stop; + } + } + } + } else { + int32_t framesRead = 0; + ResultWithValue resultAvailable = getInputStream()->getAvailableFrames(); + if (!resultAvailable) { + callbackResult = DataCallbackResult::Stop; + } else { + int32_t framesAvailable = resultAvailable.value(); + if (framesAvailable >= mMinimumFramesBeforeRead) { + // Read data into input buffer. + ResultWithValue resultRead = readInput(numFrames); + if (!resultRead) { + callbackResult = DataCallbackResult::Stop; + } else { + framesRead = resultRead.value(); + } + } + } + + if (callbackResult == DataCallbackResult::Continue) { + callbackResult = onBothStreamsReady(mInputBuffer.get(), framesRead, + audioData, numFrames); + } + } + + if (callbackResult == DataCallbackResult::Stop) { + getInputStream()->requestStop(); + } + + return callbackResult; + } + + /** + * + * This is a cushion between the DSP and the application processor cursors to prevent collisions. + * Typically 0 for latency measurements or 1 for glitch tests. + * + * @param numBursts number of bursts to leave in the input buffer as a cushion + */ + void setNumInputBurstsCushion(int32_t numBursts) { + mNumInputBurstsCushion = numBursts; + } + + /** + * Get the number of bursts left in the input buffer as a cushion. + * + * @return number of bursts in the input buffer as a cushion + */ + int32_t getNumInputBurstsCushion() const { + return mNumInputBurstsCushion; + } + + /** + * Minimum number of frames in the input stream buffer before calling readInput(). + * + * @param numFrames number of bursts in the input buffer as a cushion + */ + void setMinimumFramesBeforeRead(int32_t numFrames) { + mMinimumFramesBeforeRead = numFrames; + } + + /** + * Gets the minimum number of frames in the input stream buffer before calling readInput(). + * + * @return minimum number of frames before reading + */ + int32_t getMinimumFramesBeforeRead() const { + return mMinimumFramesBeforeRead; + } + +private: + + // TODO add getters and setters + static constexpr int32_t kNumCallbacksToDrain = 20; + static constexpr int32_t kNumCallbacksToDiscard = 30; + + // let input fill back up, usually 0 or 1 + int32_t mNumInputBurstsCushion = 0; + int32_t mMinimumFramesBeforeRead = 0; + + // We want to reach a state where the input buffer is empty and + // the output buffer is full. + // These are used in order. + // Drain several callback so that input is empty. + int32_t mCountCallbacksToDrain = kNumCallbacksToDrain; + // Let the input fill back up slightly so we don't run dry. + int32_t mCountInputBurstsCushion = mNumInputBurstsCushion; + // Discard some callbacks so the input and output reach equilibrium. + int32_t mCountCallbacksToDiscard = kNumCallbacksToDiscard; + + AudioStream *mInputStream = nullptr; + AudioStream *mOutputStream = nullptr; + + int32_t mBufferSize = 0; + std::unique_ptr mInputBuffer; +}; + +} // namespace oboe + +#endif //OBOE_FULL_DUPLEX_STREAM_ diff --git a/modules/juce_audio_devices/native/oboe/include/oboe/Oboe.h b/modules/juce_audio_devices/native/oboe/include/oboe/Oboe.h index c3a0bcabdff3..b9c948af86b5 100644 --- a/modules/juce_audio_devices/native/oboe/include/oboe/Oboe.h +++ b/modules/juce_audio_devices/native/oboe/include/oboe/Oboe.h @@ -33,5 +33,8 @@ #include "oboe/Utilities.h" #include "oboe/Version.h" #include "oboe/StabilizedCallback.h" +#include "oboe/FifoBuffer.h" +#include "oboe/OboeExtensions.h" +#include "oboe/FullDuplexStream.h" #endif //OBOE_OBOE_H diff --git a/modules/juce_audio_devices/native/oboe/include/oboe/OboeExtensions.h b/modules/juce_audio_devices/native/oboe/include/oboe/OboeExtensions.h new file mode 100644 index 000000000000..3722e77ed6cb --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/include/oboe/OboeExtensions.h @@ -0,0 +1,64 @@ +/* + * Copyright 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBOE_EXTENSIONS_ +#define OBOE_EXTENSIONS_ + +#include + +#include "oboe/Definitions.h" +#include "oboe/AudioStream.h" + +namespace oboe { + +/** + * The definitions below are only for testing. + * They are not recommended for use in an application. + * They may change or be removed at any time. + */ +class OboeExtensions { +public: + + /** + * @returns true if the device supports AAudio MMAP + */ + static bool isMMapSupported(); + + /** + * @returns true if the AAudio MMAP data path can be selected + */ + static bool isMMapEnabled(); + + /** + * Controls whether the AAudio MMAP data path can be selected when opening a stream. + * It has no effect after the stream has been opened. + * It only affects the application that calls it. Other apps are not affected. + * + * @param enabled + * @return 0 or a negative error code + */ + static int32_t setMMapEnabled(bool enabled); + + /** + * @param oboeStream + * @return true if the AAudio MMAP data path is used on the stream + */ + static bool isMMapUsed(oboe::AudioStream *oboeStream); +}; + +} // namespace oboe + +#endif // OBOE_LATENCY_TUNER_ diff --git a/modules/juce_audio_devices/native/oboe/include/oboe/StabilizedCallback.h b/modules/juce_audio_devices/native/oboe/include/oboe/StabilizedCallback.h index 3f1a689690dd..244fdb709e55 100644 --- a/modules/juce_audio_devices/native/oboe/include/oboe/StabilizedCallback.h +++ b/modules/juce_audio_devices/native/oboe/include/oboe/StabilizedCallback.h @@ -60,7 +60,7 @@ class StabilizedCallback : public AudioStreamCallback { #if defined(__i386__) || defined(__x86_64__) #define cpu_relax() asm volatile("rep; nop" ::: "memory"); -#elif defined(__arm__) || defined(__mips__) +#elif defined(__arm__) || defined(__mips__) || defined(__riscv) #define cpu_relax() asm volatile("":::"memory") #elif defined(__aarch64__) diff --git a/modules/juce_audio_devices/native/oboe/include/oboe/Utilities.h b/modules/juce_audio_devices/native/oboe/include/oboe/Utilities.h index 2c270881c531..f0f418658615 100644 --- a/modules/juce_audio_devices/native/oboe/include/oboe/Utilities.h +++ b/modules/juce_audio_devices/native/oboe/include/oboe/Utilities.h @@ -82,6 +82,18 @@ int getPropertyInteger(const char * name, int defaultValue); */ int getSdkVersion(); +/** + * Returns whether a device is on a pre-release SDK that is at least the specified codename + * version. + * + * @param codename the code name to verify. + * @return boolean of whether the device is on a pre-release SDK and is at least the specified + * codename + */ +bool isAtLeastPreReleaseCodename(const std::string& codename); + +int getChannelCountFromChannelMask(ChannelMask channelMask); + } // namespace oboe #endif //OBOE_UTILITIES_H diff --git a/modules/juce_audio_devices/native/oboe/include/oboe/Version.h b/modules/juce_audio_devices/native/oboe/include/oboe/Version.h index 5653030519e4..4c77a6754f4b 100644 --- a/modules/juce_audio_devices/native/oboe/include/oboe/Version.h +++ b/modules/juce_audio_devices/native/oboe/include/oboe/Version.h @@ -34,10 +34,10 @@ #define OBOE_VERSION_MAJOR 1 // Type: 8-bit unsigned int. Min value: 0 Max value: 255. See below for description. -#define OBOE_VERSION_MINOR 6 +#define OBOE_VERSION_MINOR 8 // Type: 16-bit unsigned int. Min value: 0 Max value: 65535. See below for description. -#define OBOE_VERSION_PATCH 1 +#define OBOE_VERSION_PATCH 0 #define OBOE_STRINGIFY(x) #x #define OBOE_TOSTRING(x) OBOE_STRINGIFY(x) diff --git a/modules/juce_audio_devices/native/oboe/src/aaudio/AAudioExtensions.h b/modules/juce_audio_devices/native/oboe/src/aaudio/AAudioExtensions.h index 51a37ae0e386..3a9d782d0173 100644 --- a/modules/juce_audio_devices/native/oboe/src/aaudio/AAudioExtensions.h +++ b/modules/juce_audio_devices/native/oboe/src/aaudio/AAudioExtensions.h @@ -41,7 +41,7 @@ typedef struct AAudioStreamStruct AAudioStream; * Call some AAudio test routines that are not part of the normal API. */ class AAudioExtensions { -public: +private: // Because it is a singleton. Call getInstance() instead. AAudioExtensions() { int32_t policy = getIntegerProperty("aaudio.mmap_policy", 0); mMMapSupported = isPolicyEnabled(policy); @@ -50,6 +50,7 @@ class AAudioExtensions { mMMapExclusiveSupported = isPolicyEnabled(policy); } +public: static bool isPolicyEnabled(int32_t policy) { return (policy == AAUDIO_POLICY_AUTO || policy == AAUDIO_POLICY_ALWAYS); } @@ -129,9 +130,16 @@ class AAudioExtensions { return 0; } + AAudioLoader *libLoader = AAudioLoader::getInstance(); + int openResult = libLoader->open(); + if (openResult != 0) { + LOGD("%s() could not open " LIB_AAUDIO_NAME, __func__); + return AAUDIO_ERROR_UNAVAILABLE; + } + void *libHandle = AAudioLoader::getInstance()->getLibHandle(); if (libHandle == nullptr) { - LOGI("%s() could not find " LIB_AAUDIO_NAME, __func__); + LOGE("%s() could not find " LIB_AAUDIO_NAME, __func__); return AAUDIO_ERROR_UNAVAILABLE; } diff --git a/modules/juce_audio_devices/native/oboe/src/aaudio/AAudioLoader.cpp b/modules/juce_audio_devices/native/oboe/src/aaudio/AAudioLoader.cpp index 8e43d724210d..213a6ef9f5a4 100644 --- a/modules/juce_audio_devices/native/oboe/src/aaudio/AAudioLoader.cpp +++ b/modules/juce_audio_devices/native/oboe/src/aaudio/AAudioLoader.cpp @@ -83,11 +83,25 @@ int AAudioLoader::open() { builder_setSessionId = load_V_PBI("AAudioStreamBuilder_setSessionId"); } + if (getSdkVersion() >= __ANDROID_API_Q__){ + builder_setAllowedCapturePolicy = load_V_PBI("AAudioStreamBuilder_setAllowedCapturePolicy"); + } + + if (getSdkVersion() >= __ANDROID_API_R__){ + builder_setPrivacySensitive = load_V_PBO("AAudioStreamBuilder_setPrivacySensitive"); + } + if (getSdkVersion() >= __ANDROID_API_S__){ builder_setPackageName = load_V_PBCPH("AAudioStreamBuilder_setPackageName"); builder_setAttributionTag = load_V_PBCPH("AAudioStreamBuilder_setAttributionTag"); } + if (getSdkVersion() >= __ANDROID_API_S_V2__) { + builder_setChannelMask = load_V_PBU("AAudioStreamBuilder_setChannelMask"); + builder_setIsContentSpatialized = load_V_PBO("AAudioStreamBuilder_setIsContentSpatialized"); + builder_setSpatializationBehavior = load_V_PBI("AAudioStreamBuilder_setSpatializationBehavior"); + } + builder_delete = load_I_PB("AAudioStreamBuilder_delete"); @@ -108,6 +122,10 @@ int AAudioLoader::open() { stream_getChannelCount = load_I_PS("AAudioStream_getSamplesPerFrame"); } + if (getSdkVersion() >= __ANDROID_API_R__) { + stream_release = load_I_PS("AAudioStream_release"); + } + stream_close = load_I_PS("AAudioStream_close"); stream_getBufferSize = load_I_PS("AAudioStream_getBufferSizeInFrames"); @@ -138,6 +156,27 @@ int AAudioLoader::open() { stream_getInputPreset = load_I_PS("AAudioStream_getInputPreset"); stream_getSessionId = load_I_PS("AAudioStream_getSessionId"); } + + if (getSdkVersion() >= __ANDROID_API_Q__){ + stream_getAllowedCapturePolicy = load_I_PS("AAudioStream_getAllowedCapturePolicy"); + } + + if (getSdkVersion() >= __ANDROID_API_R__){ + stream_isPrivacySensitive = load_O_PS("AAudioStream_isPrivacySensitive"); + } + + if (getSdkVersion() >= __ANDROID_API_S_V2__) { + stream_getChannelMask = load_U_PS("AAudioStream_getChannelMask"); + stream_isContentSpatialized = load_O_PS("AAudioStream_isContentSpatialized"); + stream_getSpatializationBehavior = load_I_PS("AAudioStream_getSpatializationBehavior"); + } + + if (getSdkVersion() >= __ANDROID_API_U__) { + stream_getHardwareChannelCount = load_I_PS("AAudioStream_getHardwareChannelCount"); + stream_getHardwareSampleRate = load_I_PS("AAudioStream_getHardwareSampleRate"); + stream_getHardwareFormat = load_F_PS("AAudioStream_getHardwareFormat"); + } + return 0; } @@ -207,10 +246,10 @@ AAudioLoader::signature_F_PS AAudioLoader::load_F_PS(const char *functionName) { return reinterpret_cast(proc); } -AAudioLoader::signature_B_PS AAudioLoader::load_B_PS(const char *functionName) { +AAudioLoader::signature_O_PS AAudioLoader::load_O_PS(const char *functionName) { void *proc = dlsym(mLibHandle, functionName); AAudioLoader_check(proc, functionName); - return reinterpret_cast(proc); + return reinterpret_cast(proc); } AAudioLoader::signature_I_PB AAudioLoader::load_I_PB(const char *functionName) { @@ -249,10 +288,32 @@ AAudioLoader::signature_I_PSKPLPL AAudioLoader::load_I_PSKPLPL(const char *funct return reinterpret_cast(proc); } +AAudioLoader::signature_V_PBU AAudioLoader::load_V_PBU(const char *functionName) { + void *proc = dlsym(mLibHandle, functionName); + AAudioLoader_check(proc, functionName); + return reinterpret_cast(proc); +} + +AAudioLoader::signature_U_PS AAudioLoader::load_U_PS(const char *functionName) { + void *proc = dlsym(mLibHandle, functionName); + AAudioLoader_check(proc, functionName); + return reinterpret_cast(proc); +} + +AAudioLoader::signature_V_PBO AAudioLoader::load_V_PBO(const char *functionName) { + void *proc = dlsym(mLibHandle, functionName); + AAudioLoader_check(proc, functionName); + return reinterpret_cast(proc); +} + // Ensure that all AAudio primitive data types are int32_t #define ASSERT_INT32(type) static_assert(std::is_same::value, \ #type" must be int32_t") +// Ensure that all AAudio primitive data types are uint32_t +#define ASSERT_UINT32(type) static_assert(std::is_same::value, \ +#type" must be uint32_t") + #define ERRMSG "Oboe constants must match AAudio constants." // These asserts help verify that the Oboe definitions match the equivalent AAudio definitions. @@ -361,6 +422,85 @@ AAudioLoader::signature_I_PSKPLPL AAudioLoader::load_I_PSKPLPL(const char *funct #endif // __NDK_MAJOR__ >= 17 +// aaudio_allowed_capture_policy_t was added in NDK 20, +// which is the first version to support Android Q (API 29). +#if __NDK_MAJOR__ >= 20 + + ASSERT_INT32(aaudio_allowed_capture_policy_t); + + static_assert((int32_t)AllowedCapturePolicy::Unspecified == AAUDIO_UNSPECIFIED, ERRMSG); + static_assert((int32_t)AllowedCapturePolicy::All == AAUDIO_ALLOW_CAPTURE_BY_ALL, ERRMSG); + static_assert((int32_t)AllowedCapturePolicy::System == AAUDIO_ALLOW_CAPTURE_BY_SYSTEM, ERRMSG); + static_assert((int32_t)AllowedCapturePolicy::None == AAUDIO_ALLOW_CAPTURE_BY_NONE, ERRMSG); + +#endif // __NDK_MAJOR__ >= 20 + +// The aaudio channel masks and spatialization behavior were added in NDK 24, +// which is the first version to support Android SC_V2 (API 32). +#if __NDK_MAJOR__ >= 24 + + ASSERT_UINT32(aaudio_channel_mask_t); + + static_assert((uint32_t)ChannelMask::FrontLeft == AAUDIO_CHANNEL_FRONT_LEFT, ERRMSG); + static_assert((uint32_t)ChannelMask::FrontRight == AAUDIO_CHANNEL_FRONT_RIGHT, ERRMSG); + static_assert((uint32_t)ChannelMask::FrontCenter == AAUDIO_CHANNEL_FRONT_CENTER, ERRMSG); + static_assert((uint32_t)ChannelMask::LowFrequency == AAUDIO_CHANNEL_LOW_FREQUENCY, ERRMSG); + static_assert((uint32_t)ChannelMask::BackLeft == AAUDIO_CHANNEL_BACK_LEFT, ERRMSG); + static_assert((uint32_t)ChannelMask::BackRight == AAUDIO_CHANNEL_BACK_RIGHT, ERRMSG); + static_assert((uint32_t)ChannelMask::FrontLeftOfCenter == AAUDIO_CHANNEL_FRONT_LEFT_OF_CENTER, ERRMSG); + static_assert((uint32_t)ChannelMask::FrontRightOfCenter == AAUDIO_CHANNEL_FRONT_RIGHT_OF_CENTER, ERRMSG); + static_assert((uint32_t)ChannelMask::BackCenter == AAUDIO_CHANNEL_BACK_CENTER, ERRMSG); + static_assert((uint32_t)ChannelMask::SideLeft == AAUDIO_CHANNEL_SIDE_LEFT, ERRMSG); + static_assert((uint32_t)ChannelMask::SideRight == AAUDIO_CHANNEL_SIDE_RIGHT, ERRMSG); + static_assert((uint32_t)ChannelMask::TopCenter == AAUDIO_CHANNEL_TOP_CENTER, ERRMSG); + static_assert((uint32_t)ChannelMask::TopFrontLeft == AAUDIO_CHANNEL_TOP_FRONT_LEFT, ERRMSG); + static_assert((uint32_t)ChannelMask::TopFrontCenter == AAUDIO_CHANNEL_TOP_FRONT_CENTER, ERRMSG); + static_assert((uint32_t)ChannelMask::TopFrontRight == AAUDIO_CHANNEL_TOP_FRONT_RIGHT, ERRMSG); + static_assert((uint32_t)ChannelMask::TopBackLeft == AAUDIO_CHANNEL_TOP_BACK_LEFT, ERRMSG); + static_assert((uint32_t)ChannelMask::TopBackCenter == AAUDIO_CHANNEL_TOP_BACK_CENTER, ERRMSG); + static_assert((uint32_t)ChannelMask::TopBackRight == AAUDIO_CHANNEL_TOP_BACK_RIGHT, ERRMSG); + static_assert((uint32_t)ChannelMask::TopSideLeft == AAUDIO_CHANNEL_TOP_SIDE_LEFT, ERRMSG); + static_assert((uint32_t)ChannelMask::TopSideRight == AAUDIO_CHANNEL_TOP_SIDE_RIGHT, ERRMSG); + static_assert((uint32_t)ChannelMask::BottomFrontLeft == AAUDIO_CHANNEL_BOTTOM_FRONT_LEFT, ERRMSG); + static_assert((uint32_t)ChannelMask::BottomFrontCenter == AAUDIO_CHANNEL_BOTTOM_FRONT_CENTER, ERRMSG); + static_assert((uint32_t)ChannelMask::BottomFrontRight == AAUDIO_CHANNEL_BOTTOM_FRONT_RIGHT, ERRMSG); + static_assert((uint32_t)ChannelMask::LowFrequency2 == AAUDIO_CHANNEL_LOW_FREQUENCY_2, ERRMSG); + static_assert((uint32_t)ChannelMask::FrontWideLeft == AAUDIO_CHANNEL_FRONT_WIDE_LEFT, ERRMSG); + static_assert((uint32_t)ChannelMask::FrontWideRight == AAUDIO_CHANNEL_FRONT_WIDE_RIGHT, ERRMSG); + static_assert((uint32_t)ChannelMask::Mono == AAUDIO_CHANNEL_MONO, ERRMSG); + static_assert((uint32_t)ChannelMask::Stereo == AAUDIO_CHANNEL_STEREO, ERRMSG); + static_assert((uint32_t)ChannelMask::CM2Point1 == AAUDIO_CHANNEL_2POINT1, ERRMSG); + static_assert((uint32_t)ChannelMask::Tri == AAUDIO_CHANNEL_TRI, ERRMSG); + static_assert((uint32_t)ChannelMask::TriBack == AAUDIO_CHANNEL_TRI_BACK, ERRMSG); + static_assert((uint32_t)ChannelMask::CM3Point1 == AAUDIO_CHANNEL_3POINT1, ERRMSG); + static_assert((uint32_t)ChannelMask::CM2Point0Point2 == AAUDIO_CHANNEL_2POINT0POINT2, ERRMSG); + static_assert((uint32_t)ChannelMask::CM2Point1Point2 == AAUDIO_CHANNEL_2POINT1POINT2, ERRMSG); + static_assert((uint32_t)ChannelMask::CM3Point0Point2 == AAUDIO_CHANNEL_3POINT0POINT2, ERRMSG); + static_assert((uint32_t)ChannelMask::CM3Point1Point2 == AAUDIO_CHANNEL_3POINT1POINT2, ERRMSG); + static_assert((uint32_t)ChannelMask::Quad == AAUDIO_CHANNEL_QUAD, ERRMSG); + static_assert((uint32_t)ChannelMask::QuadSide == AAUDIO_CHANNEL_QUAD_SIDE, ERRMSG); + static_assert((uint32_t)ChannelMask::Surround == AAUDIO_CHANNEL_SURROUND, ERRMSG); + static_assert((uint32_t)ChannelMask::Penta == AAUDIO_CHANNEL_PENTA, ERRMSG); + static_assert((uint32_t)ChannelMask::CM5Point1 == AAUDIO_CHANNEL_5POINT1, ERRMSG); + static_assert((uint32_t)ChannelMask::CM5Point1Side == AAUDIO_CHANNEL_5POINT1_SIDE, ERRMSG); + static_assert((uint32_t)ChannelMask::CM6Point1 == AAUDIO_CHANNEL_6POINT1, ERRMSG); + static_assert((uint32_t)ChannelMask::CM7Point1 == AAUDIO_CHANNEL_7POINT1, ERRMSG); + static_assert((uint32_t)ChannelMask::CM5Point1Point2 == AAUDIO_CHANNEL_5POINT1POINT2, ERRMSG); + static_assert((uint32_t)ChannelMask::CM5Point1Point4 == AAUDIO_CHANNEL_5POINT1POINT4, ERRMSG); + static_assert((uint32_t)ChannelMask::CM7Point1Point2 == AAUDIO_CHANNEL_7POINT1POINT2, ERRMSG); + static_assert((uint32_t)ChannelMask::CM7Point1Point4 == AAUDIO_CHANNEL_7POINT1POINT4, ERRMSG); + static_assert((uint32_t)ChannelMask::CM9Point1Point4 == AAUDIO_CHANNEL_9POINT1POINT4, ERRMSG); + static_assert((uint32_t)ChannelMask::CM9Point1Point6 == AAUDIO_CHANNEL_9POINT1POINT6, ERRMSG); + static_assert((uint32_t)ChannelMask::FrontBack == AAUDIO_CHANNEL_FRONT_BACK, ERRMSG); + + ASSERT_INT32(aaudio_spatialization_behavior_t); + + static_assert((int32_t)SpatializationBehavior::Unspecified == AAUDIO_UNSPECIFIED, ERRMSG); + static_assert((int32_t)SpatializationBehavior::Auto == AAUDIO_SPATIALIZATION_BEHAVIOR_AUTO, ERRMSG); + static_assert((int32_t)SpatializationBehavior::Never == AAUDIO_SPATIALIZATION_BEHAVIOR_NEVER, ERRMSG); + +#endif + #endif // AAUDIO_AAUDIO_H } // namespace oboe diff --git a/modules/juce_audio_devices/native/oboe/src/aaudio/AAudioLoader.h b/modules/juce_audio_devices/native/oboe/src/aaudio/AAudioLoader.h index 8efb6d277796..2378464e0064 100644 --- a/modules/juce_audio_devices/native/oboe/src/aaudio/AAudioLoader.h +++ b/modules/juce_audio_devices/native/oboe/src/aaudio/AAudioLoader.h @@ -66,10 +66,32 @@ typedef int32_t aaudio_session_id_t; #define __NDK_MAJOR__ 0 #endif +#if __NDK_MAJOR__ < 24 +// Defined in SC_V2 +typedef uint32_t aaudio_channel_mask_t; +typedef int32_t aaudio_spatialization_behavior_t; +#endif + +#ifndef __ANDROID_API_Q__ +#define __ANDROID_API_Q__ 29 +#endif + +#ifndef __ANDROID_API_R__ +#define __ANDROID_API_R__ 30 +#endif + #ifndef __ANDROID_API_S__ #define __ANDROID_API_S__ 31 #endif +#ifndef __ANDROID_API_S_V2__ +#define __ANDROID_API_S_V2__ 32 +#endif + +#ifndef __ANDROID_API_U__ +#define __ANDROID_API_U__ 34 +#endif + namespace oboe { /** @@ -90,6 +112,9 @@ class AAudioLoader { // P = Pointer to following data type // C = Const prefix // H = cHar + // U = uint32_t + // O = bOol + typedef int32_t (*signature_I_PPB)(AAudioStreamBuilder **builder); typedef const char * (*signature_CPH_I)(int32_t); @@ -101,8 +126,14 @@ class AAudioLoader { // AAudioStreamBuilder_setSampleRate() typedef void (*signature_V_PBI)(AAudioStreamBuilder *, int32_t); + // AAudioStreamBuilder_setChannelMask() + typedef void (*signature_V_PBU)(AAudioStreamBuilder *, uint32_t); + typedef void (*signature_V_PBCPH)(AAudioStreamBuilder *, const char *); + // AAudioStreamBuilder_setPrivacySensitive + typedef void (*signature_V_PBO)(AAudioStreamBuilder *, bool); + typedef int32_t (*signature_I_PS)(AAudioStream *); // AAudioStream_getSampleRate() typedef int64_t (*signature_L_PS)(AAudioStream *); // AAudioStream_getFramesRead() // AAudioStream_setBufferSizeInFrames() @@ -128,7 +159,9 @@ class AAudioLoader { typedef int32_t (*signature_I_PSKPLPL)(AAudioStream *, clockid_t, int64_t *, int64_t *); - typedef bool (*signature_B_PS)(AAudioStream *); + typedef bool (*signature_O_PS)(AAudioStream *); + + typedef uint32_t (*signature_U_PS)(AAudioStream *); static AAudioLoader* getInstance(); // singleton @@ -159,15 +192,22 @@ class AAudioLoader { signature_V_PBI builder_setPerformanceMode = nullptr; signature_V_PBI builder_setSampleRate = nullptr; signature_V_PBI builder_setSharingMode = nullptr; + signature_V_PBU builder_setChannelMask = nullptr; signature_V_PBI builder_setUsage = nullptr; signature_V_PBI builder_setContentType = nullptr; signature_V_PBI builder_setInputPreset = nullptr; signature_V_PBI builder_setSessionId = nullptr; + signature_V_PBO builder_setPrivacySensitive = nullptr; + signature_V_PBI builder_setAllowedCapturePolicy = nullptr; + signature_V_PBCPH builder_setPackageName = nullptr; signature_V_PBCPH builder_setAttributionTag = nullptr; + signature_V_PBO builder_setIsContentSpatialized = nullptr; + signature_V_PBI builder_setSpatializationBehavior = nullptr; + signature_V_PBPDPV builder_setDataCallback = nullptr; signature_V_PBPEPV builder_setErrorCallback = nullptr; @@ -182,6 +222,7 @@ class AAudioLoader { signature_I_PSKPLPL stream_getTimestamp = nullptr; + signature_I_PS stream_release = nullptr; signature_I_PS stream_close = nullptr; signature_I_PS stream_getChannelCount = nullptr; @@ -212,6 +253,18 @@ class AAudioLoader { signature_I_PS stream_getInputPreset = nullptr; signature_I_PS stream_getSessionId = nullptr; + signature_O_PS stream_isPrivacySensitive = nullptr; + signature_I_PS stream_getAllowedCapturePolicy = nullptr; + + signature_U_PS stream_getChannelMask = nullptr; + + signature_O_PS stream_isContentSpatialized = nullptr; + signature_I_PS stream_getSpatializationBehavior = nullptr; + + signature_I_PS stream_getHardwareChannelCount = nullptr; + signature_I_PS stream_getHardwareSampleRate = nullptr; + signature_F_PS stream_getHardwareFormat = nullptr; + private: AAudioLoader() {} ~AAudioLoader(); @@ -228,12 +281,15 @@ class AAudioLoader { signature_I_PS load_I_PS(const char *name); signature_L_PS load_L_PS(const char *name); signature_F_PS load_F_PS(const char *name); - signature_B_PS load_B_PS(const char *name); + signature_O_PS load_O_PS(const char *name); signature_I_PSI load_I_PSI(const char *name); signature_I_PSPVIL load_I_PSPVIL(const char *name); signature_I_PSCPVIL load_I_PSCPVIL(const char *name); signature_I_PSTPTL load_I_PSTPTL(const char *name); signature_I_PSKPLPL load_I_PSKPLPL(const char *name); + signature_V_PBU load_V_PBU(const char *name); + signature_U_PS load_U_PS(const char *name); + signature_V_PBO load_V_PBO(const char *name); void *mLibHandle = nullptr; }; diff --git a/modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.cpp b/modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.cpp index 5ce0dc4a8262..db7e658bcf36 100644 --- a/modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.cpp +++ b/modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.cpp @@ -146,6 +146,39 @@ void AudioStreamAAudio::internalErrorCallback( } } +void AudioStreamAAudio::beginPerformanceHintInCallback() { + if (isPerformanceHintEnabled()) { + if (!mAdpfOpenAttempted) { + int64_t targetDurationNanos = (mFramesPerBurst * 1e9) / getSampleRate(); + // This has to be called from the callback thread so we get the right TID. + int adpfResult = mAdpfWrapper.open(gettid(), targetDurationNanos); + if (adpfResult < 0) { + LOGW("WARNING ADPF not supported, %d\n", adpfResult); + } else { + LOGD("ADPF is now active\n"); + } + mAdpfOpenAttempted = true; + } + mAdpfWrapper.onBeginCallback(); + } else if (!isPerformanceHintEnabled() && mAdpfOpenAttempted) { + LOGD("ADPF closed\n"); + mAdpfWrapper.close(); + mAdpfOpenAttempted = false; + } +} + +void AudioStreamAAudio::endPerformanceHintInCallback(int32_t numFrames) { + if (mAdpfWrapper.isOpen()) { + // Scale the measured duration based on numFrames so it is normalized to a full burst. + double durationScaler = static_cast(mFramesPerBurst) / numFrames; + // Skip this callback if numFrames is very small. + // This can happen when buffers wrap around, particularly when doing sample rate conversion. + if (durationScaler < 2.0) { + mAdpfWrapper.onEndCallback(durationScaler); + } + } +} + void AudioStreamAAudio::logUnsupportedAttributes() { int sdkVersion = getSdkVersion(); @@ -205,7 +238,32 @@ Result AudioStreamAAudio::open() { } mLibLoader->builder_setBufferCapacityInFrames(aaudioBuilder, capacity); - mLibLoader->builder_setChannelCount(aaudioBuilder, mChannelCount); + if (mLibLoader->builder_setSessionId != nullptr) { + mLibLoader->builder_setSessionId(aaudioBuilder, + static_cast(mSessionId)); + // Output effects do not support PerformanceMode::LowLatency. + if (OboeGlobals::areWorkaroundsEnabled() + && mSessionId != SessionId::None + && mDirection == oboe::Direction::Output + && mPerformanceMode == PerformanceMode::LowLatency) { + mPerformanceMode = PerformanceMode::None; + LOGD("AudioStreamAAudio.open() performance mode changed to None when session " + "id is requested"); + } + } + + // Channel mask was added in SC_V2. Given the corresponding channel count of selected channel + // mask may be different from selected channel count, the last set value will be respected. + // If channel count is set after channel mask, the previously set channel mask will be cleared. + // If channel mask is set after channel count, the channel count will be automatically + // calculated from selected channel mask. In that case, only set channel mask when the API + // is available and the channel mask is specified. + if (mLibLoader->builder_setChannelMask != nullptr && mChannelMask != ChannelMask::Unspecified) { + mLibLoader->builder_setChannelMask(aaudioBuilder, + static_cast(mChannelMask)); + } else { + mLibLoader->builder_setChannelCount(aaudioBuilder, mChannelCount); + } mLibLoader->builder_setDeviceId(aaudioBuilder, mDeviceId); mLibLoader->builder_setDirection(aaudioBuilder, static_cast(mDirection)); mLibLoader->builder_setFormat(aaudioBuilder, static_cast(mFormat)); @@ -236,11 +294,6 @@ Result AudioStreamAAudio::open() { static_cast(inputPreset)); } - if (mLibLoader->builder_setSessionId != nullptr) { - mLibLoader->builder_setSessionId(aaudioBuilder, - static_cast(mSessionId)); - } - // These were added in S so we have to check for the function pointer. if (mLibLoader->builder_setPackageName != nullptr && !mPackageName.empty()) { mLibLoader->builder_setPackageName(aaudioBuilder, @@ -252,6 +305,33 @@ Result AudioStreamAAudio::open() { mAttributionTag.c_str()); } + // This was added in Q so we have to check for the function pointer. + if (mLibLoader->builder_setAllowedCapturePolicy != nullptr && mDirection == oboe::Direction::Output) { + mLibLoader->builder_setAllowedCapturePolicy(aaudioBuilder, + static_cast(mAllowedCapturePolicy)); + } + + if (mLibLoader->builder_setPrivacySensitive != nullptr && mDirection == oboe::Direction::Input + && mPrivacySensitiveMode != PrivacySensitiveMode::Unspecified) { + mLibLoader->builder_setPrivacySensitive(aaudioBuilder, + mPrivacySensitiveMode == PrivacySensitiveMode::Enabled); + } + + if (mLibLoader->builder_setIsContentSpatialized != nullptr) { + mLibLoader->builder_setIsContentSpatialized(aaudioBuilder, mIsContentSpatialized); + } + + if (mLibLoader->builder_setSpatializationBehavior != nullptr) { + // Override Unspecified as Never to reduce latency. + if (mSpatializationBehavior == SpatializationBehavior::Unspecified) { + mSpatializationBehavior = SpatializationBehavior::Never; + } + mLibLoader->builder_setSpatializationBehavior(aaudioBuilder, + static_cast(mSpatializationBehavior)); + } else { + mSpatializationBehavior = SpatializationBehavior::Never; + } + if (isDataCallbackSpecified()) { mLibLoader->builder_setDataCallback(aaudioBuilder, oboe_aaudio_data_callback_proc, this); mLibLoader->builder_setFramesPerDataCallback(aaudioBuilder, getFramesPerDataCallback()); @@ -309,17 +389,92 @@ Result AudioStreamAAudio::open() { mSessionId = SessionId::None; } + // This was added in Q so we have to check for the function pointer. + if (mLibLoader->stream_getAllowedCapturePolicy != nullptr && mDirection == oboe::Direction::Output) { + mAllowedCapturePolicy = static_cast(mLibLoader->stream_getAllowedCapturePolicy(mAAudioStream)); + } else { + mAllowedCapturePolicy = AllowedCapturePolicy::Unspecified; + } + + if (mLibLoader->stream_isPrivacySensitive != nullptr && mDirection == oboe::Direction::Input) { + bool isPrivacySensitive = mLibLoader->stream_isPrivacySensitive(mAAudioStream); + mPrivacySensitiveMode = isPrivacySensitive ? PrivacySensitiveMode::Enabled : + PrivacySensitiveMode::Disabled; + } else { + mPrivacySensitiveMode = PrivacySensitiveMode::Unspecified; + } + + if (mLibLoader->stream_getChannelMask != nullptr) { + mChannelMask = static_cast(mLibLoader->stream_getChannelMask(mAAudioStream)); + } + + if (mLibLoader->stream_isContentSpatialized != nullptr) { + mIsContentSpatialized = mLibLoader->stream_isContentSpatialized(mAAudioStream); + } + + if (mLibLoader->stream_getSpatializationBehavior != nullptr) { + mSpatializationBehavior = static_cast( + mLibLoader->stream_getSpatializationBehavior(mAAudioStream)); + } + + if (mLibLoader->stream_getHardwareChannelCount != nullptr) { + mHardwareChannelCount = mLibLoader->stream_getHardwareChannelCount(mAAudioStream); + } + if (mLibLoader->stream_getHardwareSampleRate != nullptr) { + mHardwareSampleRate = mLibLoader->stream_getHardwareSampleRate(mAAudioStream); + } + if (mLibLoader->stream_getHardwareFormat != nullptr) { + mHardwareFormat = static_cast(mLibLoader->stream_getHardwareFormat(mAAudioStream)); + } + LOGD("AudioStreamAAudio.open() format=%d, sampleRate=%d, capacity = %d", static_cast(mFormat), static_cast(mSampleRate), static_cast(mBufferCapacityInFrames)); + calculateDefaultDelayBeforeCloseMillis(); + error2: mLibLoader->builder_delete(aaudioBuilder); - LOGD("AudioStreamAAudio.open: AAudioStream_Open() returned %s", - mLibLoader->convertResultToText(static_cast(result))); + if (static_cast(result) > 0) { + // Possibly due to b/267531411 + LOGW("AudioStreamAAudio.open: AAudioStream_Open() returned positive error = %d", + static_cast(result)); + if (OboeGlobals::areWorkaroundsEnabled()) { + result = Result::ErrorInternal; // Coerce to negative error. + } + } else { + LOGD("AudioStreamAAudio.open: AAudioStream_Open() returned %s = %d", + mLibLoader->convertResultToText(static_cast(result)), + static_cast(result)); + } return result; } +Result AudioStreamAAudio::release() { + if (getSdkVersion() < __ANDROID_API_R__) { + return Result::ErrorUnimplemented; + } + + // AAudioStream_release() is buggy on Android R. + if (OboeGlobals::areWorkaroundsEnabled() && getSdkVersion() == __ANDROID_API_R__) { + LOGW("Skipping release() on Android R"); + return Result::ErrorUnimplemented; + } + + std::lock_guard lock(mLock); + AAudioStream *stream = mAAudioStream.load(); + if (stream != nullptr) { + if (OboeGlobals::areWorkaroundsEnabled()) { + // Make sure we are really stopped. Do it under mLock + // so another thread cannot call requestStart() right before the close. + requestStop_l(stream); + } + return static_cast(mLibLoader->stream_release(stream)); + } else { + return Result::ErrorClosed; + } +} + Result AudioStreamAAudio::close() { // Prevent two threads from closing the stream at the same time and crashing. // This could occur, for example, if an application called close() at the same @@ -340,12 +495,7 @@ Result AudioStreamAAudio::close() { // Make sure we are really stopped. Do it under mLock // so another thread cannot call requestStart() right before the close. requestStop_l(stream); - // Sometimes a callback can occur shortly after a stream has been stopped and - // even after a close! If the stream has been closed then the callback - // can access memory that has been freed. That causes a crash. - // This seems to be more likely in Android P or earlier. - // But it can also occur in later versions. - usleep(kDelayBeforeCloseMillis * 1000); + sleepBeforeClose(); } return static_cast(mLibLoader->stream_close(stream)); } else { @@ -407,6 +557,7 @@ Result AudioStreamAAudio::requestStart() { setDataCallbackEnabled(true); } mStopThreadAllowed = true; + closePerformanceHint(); return static_cast(mLibLoader->stream_requestStart(stream)); } else { return Result::ErrorClosed; @@ -472,6 +623,7 @@ Result AudioStreamAAudio::requestStop_l(AAudioStream *stream) { ResultWithValue AudioStreamAAudio::write(const void *buffer, int32_t numFrames, int64_t timeoutNanoseconds) { + std::shared_lock lock(mAAudioStreamLock); AAudioStream *stream = mAAudioStream.load(); if (stream != nullptr) { int32_t result = mLibLoader->stream_write(mAAudioStream, buffer, @@ -485,6 +637,7 @@ ResultWithValue AudioStreamAAudio::write(const void *buffer, ResultWithValue AudioStreamAAudio::read(void *buffer, int32_t numFrames, int64_t timeoutNanoseconds) { + std::shared_lock lock(mAAudioStreamLock); AAudioStream *stream = mAAudioStream.load(); if (stream != nullptr) { int32_t result = mLibLoader->stream_read(mAAudioStream, buffer, diff --git a/modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.h b/modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.h index e71efe85c870..2df4d85764e9 100644 --- a/modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.h +++ b/modules/juce_audio_devices/native/oboe/src/aaudio/AudioStreamAAudio.h @@ -22,6 +22,7 @@ #include #include +#include #include "oboe/AudioStreamBuilder.h" #include "oboe/AudioStream.h" #include "oboe/Definitions.h" @@ -51,6 +52,7 @@ class AudioStreamAAudio : public AudioStream { // These functions override methods in AudioStream. // See AudioStream for documentation. Result open() override; + Result release() override; Result close() override; Result requestStart() override; @@ -91,7 +93,12 @@ class AudioStreamAAudio : public AudioStream { void *audioData, int32_t numFrames); - bool isMMapUsed(); + bool isMMapUsed(); + + void closePerformanceHint() override { + mAdpfWrapper.close(); + mAdpfOpenAttempted = false; + } protected: static void internalErrorCallback( @@ -108,6 +115,14 @@ class AudioStreamAAudio : public AudioStream { void logUnsupportedAttributes(); + void beginPerformanceHintInCallback() override; + + void endPerformanceHintInCallback(int32_t numFrames) override; + + // set by callback (or app when idle) + std::atomic mAdpfOpenAttempted{false}; + AdpfWrapper mAdpfWrapper; + private: // Must call under mLock. And stream must NOT be nullptr. Result requestStop_l(AAudioStream *stream); @@ -117,9 +132,7 @@ class AudioStreamAAudio : public AudioStream { */ void launchStopThread(); - // Time to sleep in order to prevent a race condition with a callback after a close(). - // Two milliseconds may be enough but 10 msec is even safer. - static constexpr int kDelayBeforeCloseMillis = 10; +private: std::atomic mCallbackThreadEnabled; std::atomic mStopThreadAllowed{false}; diff --git a/modules/juce_audio_devices/native/oboe/src/common/AdpfWrapper.cpp b/modules/juce_audio_devices/native/oboe/src/common/AdpfWrapper.cpp new file mode 100644 index 000000000000..05accdea6f8f --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/common/AdpfWrapper.cpp @@ -0,0 +1,124 @@ +/* + * Copyright 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include "AdpfWrapper.h" +#include "AudioClock.h" +#include "OboeDebug.h" + +typedef APerformanceHintManager* (*APH_getManager)(); +typedef APerformanceHintSession* (*APH_createSession)(APerformanceHintManager*, const int32_t*, + size_t, int64_t); +typedef void (*APH_reportActualWorkDuration)(APerformanceHintSession*, int64_t); +typedef void (*APH_closeSession)(APerformanceHintSession* session); + +static bool gAPerformanceHintBindingInitialized = false; +static APH_getManager gAPH_getManagerFn = nullptr; +static APH_createSession gAPH_createSessionFn = nullptr; +static APH_reportActualWorkDuration gAPH_reportActualWorkDurationFn = nullptr; +static APH_closeSession gAPH_closeSessionFn = nullptr; + +static int loadAphFunctions() { + if (gAPerformanceHintBindingInitialized) return true; + + void* handle_ = dlopen("libandroid.so", RTLD_NOW | RTLD_NODELETE); + if (handle_ == nullptr) { + return -1000; + } + + gAPH_getManagerFn = (APH_getManager)dlsym(handle_, "APerformanceHint_getManager"); + if (gAPH_getManagerFn == nullptr) { + return -1001; + } + + gAPH_createSessionFn = (APH_createSession)dlsym(handle_, "APerformanceHint_createSession"); + if (gAPH_getManagerFn == nullptr) { + return -1002; + } + + gAPH_reportActualWorkDurationFn = (APH_reportActualWorkDuration)dlsym( + handle_, "APerformanceHint_reportActualWorkDuration"); + if (gAPH_getManagerFn == nullptr) { + return -1003; + } + + gAPH_closeSessionFn = (APH_closeSession)dlsym(handle_, "APerformanceHint_closeSession"); + if (gAPH_getManagerFn == nullptr) { + return -1004; + } + + gAPerformanceHintBindingInitialized = true; + return 0; +} + +bool AdpfWrapper::sUseAlternativeHack = false; // TODO remove hack + +int AdpfWrapper::open(pid_t threadId, + int64_t targetDurationNanos) { + std::lock_guard lock(mLock); + int result = loadAphFunctions(); + if (result < 0) return result; + + // This is a singleton. + APerformanceHintManager* manager = gAPH_getManagerFn(); + + int32_t thread32 = threadId; + if (sUseAlternativeHack) { + // TODO Remove this hack when we finish experimenting with alternative algorithms. + // The A5 is an arbitrary signal to a hacked version of ADPF to try an alternative + // algorithm that is not based on PID. + targetDurationNanos = (targetDurationNanos & ~0xFF) | 0xA5; + } + mHintSession = gAPH_createSessionFn(manager, &thread32, 1 /* size */, targetDurationNanos); + if (mHintSession == nullptr) { + return -1; + } + return 0; +} + +void AdpfWrapper::reportActualDuration(int64_t actualDurationNanos) { + //LOGD("ADPF Oboe %s(dur=%lld)", __func__, (long long)actualDurationNanos); + std::lock_guard lock(mLock); + if (mHintSession != nullptr) { + gAPH_reportActualWorkDurationFn(mHintSession, actualDurationNanos); + } +} + +void AdpfWrapper::close() { + std::lock_guard lock(mLock); + if (mHintSession != nullptr) { + gAPH_closeSessionFn(mHintSession); + mHintSession = nullptr; + } +} + +void AdpfWrapper::onBeginCallback() { + if (isOpen()) { + mBeginCallbackNanos = oboe::AudioClock::getNanoseconds(CLOCK_REALTIME); + } +} + +void AdpfWrapper::onEndCallback(double durationScaler) { + if (isOpen()) { + int64_t endCallbackNanos = oboe::AudioClock::getNanoseconds(CLOCK_REALTIME); + int64_t actualDurationNanos = endCallbackNanos - mBeginCallbackNanos; + int64_t scaledDurationNanos = static_cast(actualDurationNanos * durationScaler); + reportActualDuration(scaledDurationNanos); + } +} diff --git a/modules/juce_audio_devices/native/oboe/src/common/AdpfWrapper.h b/modules/juce_audio_devices/native/oboe/src/common/AdpfWrapper.h new file mode 100644 index 000000000000..330ee3c633a9 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/common/AdpfWrapper.h @@ -0,0 +1,85 @@ +/* + * Copyright 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SYNTHMARK_ADPF_WRAPPER_H +#define SYNTHMARK_ADPF_WRAPPER_H + +#include +#include +#include +#include +#include +#include + +struct APerformanceHintManager; +struct APerformanceHintSession; + +typedef struct APerformanceHintManager APerformanceHintManager; +typedef struct APerformanceHintSession APerformanceHintSession; + +class AdpfWrapper { +public: + /** + * Create an ADPF session that can be used to boost performance. + * @param threadId + * @param targetDurationNanos - nominal period of isochronous task + * @return zero or negative error + */ + int open(pid_t threadId, + int64_t targetDurationNanos); + + bool isOpen() const { + return (mHintSession != nullptr); + } + + void close(); + + /** + * Call this at the beginning of the callback that you are measuring. + */ + void onBeginCallback(); + + /** + * Call this at the end of the callback that you are measuring. + * It is OK to skip this if you have a short callback. + */ + void onEndCallback(double durationScaler); + + /** + * For internal use only! + * This is a hack for communicating with experimental versions of ADPF. + * @param enabled + */ + static void setUseAlternative(bool enabled) { + sUseAlternativeHack = enabled; + } + + /** + * Report the measured duration of a callback. + * This is normally called by onEndCallback(). + * You may want to call this directly in order to give an advance hint of a jump in workload. + * @param actualDurationNanos + */ + void reportActualDuration(int64_t actualDurationNanos); + +private: + std::mutex mLock; + APerformanceHintSession* mHintSession = nullptr; + int64_t mBeginCallbackNanos = 0; + static bool sUseAlternativeHack; +}; + +#endif //SYNTHMARK_ADPF_WRAPPER_H diff --git a/modules/juce_audio_devices/native/oboe/src/common/AudioStream.cpp b/modules/juce_audio_devices/native/oboe/src/common/AudioStream.cpp index 66d071172475..06c01118e401 100644 --- a/modules/juce_audio_devices/native/oboe/src/common/AudioStream.cpp +++ b/modules/juce_audio_devices/native/oboe/src/common/AudioStream.cpp @@ -33,6 +33,7 @@ AudioStream::AudioStream(const AudioStreamBuilder &builder) } Result AudioStream::close() { + closePerformanceHint(); // Update local counters so they can be read after the close. updateFramesWritten(); updateFramesRead(); @@ -58,6 +59,9 @@ DataCallbackResult AudioStream::fireDataCallback(void *audioData, int32_t numFra return DataCallbackResult::Stop; // Should not be getting called } + beginPerformanceHintInCallback(); + + // Call the app to do the work. DataCallbackResult result; if (mDataCallback) { result = mDataCallback->onAudioReady(this, audioData, numFrames); @@ -68,6 +72,8 @@ DataCallbackResult AudioStream::fireDataCallback(void *audioData, int32_t numFra // So block that here. setDataCallbackEnabled(result == DataCallbackResult::Continue); + endPerformanceHintInCallback(numFrames); + return result; } @@ -166,6 +172,14 @@ ResultWithValue AudioStream::waitForAvailableFrames(int32_t numFrames, if (numFrames == 0) return Result::OK; if (numFrames < 0) return Result::ErrorOutOfRange; + // Make sure we don't try to wait for more frames than the buffer can hold. + // Subtract framesPerBurst because this is often called from a callback + // and we don't want to be sleeping if the buffer is close to overflowing. + const int32_t maxAvailableFrames = getBufferCapacityInFrames() - getFramesPerBurst(); + numFrames = std::min(numFrames, maxAvailableFrames); + // The capacity should never be less than one burst. But clip to zero just in case. + numFrames = std::max(0, numFrames); + int64_t framesAvailable = 0; int64_t burstInNanos = getFramesPerBurst() * kNanosPerSecond / getSampleRate(); bool ready = false; @@ -196,4 +210,13 @@ ResultWithValue AudioStream::getTimestamp(clockid_t clockId) { } } +void AudioStream::calculateDefaultDelayBeforeCloseMillis() { + // Calculate delay time before close based on burst duration. + // Start with a burst duration then add 1 msec as a safety margin. + mDelayBeforeCloseMillis = std::max(kMinDelayBeforeCloseMillis, + 1 + ((mFramesPerBurst * 1000) / getSampleRate())); + LOGD("calculateDefaultDelayBeforeCloseMillis() default = %d", + static_cast(mDelayBeforeCloseMillis)); +} + } // namespace oboe diff --git a/modules/juce_audio_devices/native/oboe/src/common/DataConversionFlowGraph.cpp b/modules/juce_audio_devices/native/oboe/src/common/DataConversionFlowGraph.cpp index 2177685c582f..374fffd1984a 100644 --- a/modules/juce_audio_devices/native/oboe/src/common/DataConversionFlowGraph.cpp +++ b/modules/juce_audio_devices/native/oboe/src/common/DataConversionFlowGraph.cpp @@ -23,7 +23,6 @@ #include "SourceI24Caller.h" #include "SourceI32Caller.h" -#include #include #include #include diff --git a/modules/juce_audio_devices/native/oboe/src/common/FilterAudioStream.h b/modules/juce_audio_devices/native/oboe/src/common/FilterAudioStream.h index 2f50e3ec8fa6..189074997f44 100644 --- a/modules/juce_audio_devices/native/oboe/src/common/FilterAudioStream.h +++ b/modules/juce_audio_devices/native/oboe/src/common/FilterAudioStream.h @@ -55,9 +55,13 @@ class FilterAudioStream : public AudioStream, AudioStreamCallback { // Copy parameters that may not match builder. mBufferCapacityInFrames = mChildStream->getBufferCapacityInFrames(); mPerformanceMode = mChildStream->getPerformanceMode(); + mSharingMode = mChildStream->getSharingMode(); mInputPreset = mChildStream->getInputPreset(); mFramesPerBurst = mChildStream->getFramesPerBurst(); mDeviceId = mChildStream->getDeviceId(); + mHardwareSampleRate = mChildStream->getHardwareSampleRate(); + mHardwareChannelCount = mChildStream->getHardwareChannelCount(); + mHardwareFormat = mChildStream->getHardwareFormat(); } virtual ~FilterAudioStream() = default; diff --git a/modules/juce_audio_devices/native/oboe/src/common/OboeExtensions.cpp b/modules/juce_audio_devices/native/oboe/src/common/OboeExtensions.cpp new file mode 100644 index 000000000000..57731e89d7e9 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/common/OboeExtensions.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "oboe/OboeExtensions.h" +#include "aaudio/AAudioExtensions.h" + +using namespace oboe; + +bool OboeExtensions::isMMapSupported(){ + return AAudioExtensions::getInstance().isMMapSupported(); +} + +bool OboeExtensions::isMMapEnabled(){ + return AAudioExtensions::getInstance().isMMapEnabled(); +} + +int32_t OboeExtensions::setMMapEnabled(bool enabled){ + return AAudioExtensions::getInstance().setMMapEnabled(enabled); +} + +bool OboeExtensions::isMMapUsed(oboe::AudioStream *oboeStream){ + return AAudioExtensions::getInstance().isMMapUsed(oboeStream); +} diff --git a/modules/juce_audio_devices/native/oboe/src/common/QuirksManager.cpp b/modules/juce_audio_devices/native/oboe/src/common/QuirksManager.cpp index 594589c78b9f..f9890be5a31c 100644 --- a/modules/juce_audio_devices/native/oboe/src/common/QuirksManager.cpp +++ b/modules/juce_audio_devices/native/oboe/src/common/QuirksManager.cpp @@ -62,12 +62,23 @@ bool QuirksManager::DeviceQuirks::isAAudioMMapPossible(const AudioStreamBuilder && builder.getChannelCount() <= kChannelCountStereo; } -class SamsungDeviceQuirks : public QuirksManager::DeviceQuirks { -public: - SamsungDeviceQuirks() { - std::string arch = getPropertyString("ro.arch"); - isExynos = (arch.rfind("exynos", 0) == 0); // starts with? +bool QuirksManager::DeviceQuirks::shouldConvertFloatToI16ForOutputStreams() { + std::string productManufacturer = getPropertyString("ro.product.manufacturer"); + if (getSdkVersion() < __ANDROID_API_L__) { + return true; + } else if ((productManufacturer == "vivo") && (getSdkVersion() < __ANDROID_API_M__)) { + return true; + } + return false; +} +/** + * This is for Samsung Exynos quirks. Samsung Mobile uses Qualcomm chips so + * the QualcommDeviceQuirks would apply. + */ +class SamsungExynosDeviceQuirks : public QuirksManager::DeviceQuirks { +public: + SamsungExynosDeviceQuirks() { std::string chipname = getPropertyString("ro.hardware.chipname"); isExynos9810 = (chipname == "exynos9810"); isExynos990 = (chipname == "exynos990"); @@ -76,11 +87,10 @@ class SamsungDeviceQuirks : public QuirksManager::DeviceQuirks { mBuildChangelist = getPropertyInteger("ro.build.changelist", 0); } - virtual ~SamsungDeviceQuirks() = default; + virtual ~SamsungExynosDeviceQuirks() = default; int32_t getExclusiveBottomMarginInBursts() const override { - // TODO Make this conditional on build version when MMAP timing improves. - return isExynos ? kBottomMarginExynos : kBottomMarginOther; + return kBottomMargin; } int32_t getExclusiveTopMarginInBursts() const override { @@ -125,22 +135,61 @@ class SamsungDeviceQuirks : public QuirksManager::DeviceQuirks { private: // Stay farther away from DSP position on Exynos devices. - static constexpr int32_t kBottomMarginExynos = 2; - static constexpr int32_t kBottomMarginOther = 1; + static constexpr int32_t kBottomMargin = 2; static constexpr int32_t kTopMargin = 1; - bool isExynos = false; bool isExynos9810 = false; bool isExynos990 = false; bool isExynos850 = false; int mBuildChangelist = 0; }; +class QualcommDeviceQuirks : public QuirksManager::DeviceQuirks { +public: + QualcommDeviceQuirks() { + std::string modelName = getPropertyString("ro.soc.model"); + isSM8150 = (modelName == "SDM8150"); + } + + virtual ~QualcommDeviceQuirks() = default; + + int32_t getExclusiveBottomMarginInBursts() const override { + return kBottomMargin; + } + + bool isMMapSafe(const AudioStreamBuilder &builder) override { + // See https://github.com/google/oboe/issues/1121#issuecomment-897957749 + bool isMMapBroken = false; + if (isSM8150 && (getSdkVersion() <= __ANDROID_API_P__)) { + LOGI("QuirksManager::%s() MMAP not actually supported on this chip." + " Switching off MMAP.", __func__); + isMMapBroken = true; + } + + return !isMMapBroken; + } + +private: + bool isSM8150 = false; + static constexpr int32_t kBottomMargin = 1; +}; + QuirksManager::QuirksManager() { - std::string manufacturer = getPropertyString("ro.product.manufacturer"); - if (manufacturer == "samsung") { - mDeviceQuirks = std::make_unique(); - } else { - mDeviceQuirks = std::make_unique(); + std::string productManufacturer = getPropertyString("ro.product.manufacturer"); + if (productManufacturer == "samsung") { + std::string arch = getPropertyString("ro.arch"); + bool isExynos = (arch.rfind("exynos", 0) == 0); // starts with? + if (isExynos) { + mDeviceQuirks = std::make_unique(); + } + } + if (!mDeviceQuirks) { + std::string socManufacturer = getPropertyString("ro.soc.manufacturer"); + if (socManufacturer == "Qualcomm") { + // This may include Samsung Mobile devices. + mDeviceQuirks = std::make_unique(); + } else { + mDeviceQuirks = std::make_unique(); + } } } @@ -151,6 +200,13 @@ bool QuirksManager::isConversionNeeded( const bool isLowLatency = builder.getPerformanceMode() == PerformanceMode::LowLatency; const bool isInput = builder.getDirection() == Direction::Input; const bool isFloat = builder.getFormat() == AudioFormat::Float; + const bool isIEC61937 = builder.getFormat() == AudioFormat::IEC61937; + + // There should be no conversion for IEC61937. Sample rates and channel counts must be set explicitly. + if (isIEC61937) { + LOGI("QuirksManager::%s() conversion not needed for IEC61937", __func__); + return false; + } // There are multiple bugs involving using callback with a specified callback size. // Issue #778: O to Q had a problem with Legacy INPUT streams for FLOAT streams @@ -174,7 +230,8 @@ bool QuirksManager::isConversionNeeded( conversionNeeded = true; } - // If a SAMPLE RATE is specified for low latency then let the native code choose an optimal rate. + // If a SAMPLE RATE is specified for low latency, let the native code choose an optimal rate. + // This isn't really a workaround. It is an Oboe feature that is convenient to place here. // TODO There may be a problem if the devices supports low latency // at a higher rate than the default. if (builder.getSampleRate() != oboe::Unspecified @@ -187,7 +244,8 @@ bool QuirksManager::isConversionNeeded( // Data Format // OpenSL ES and AAudio before P do not support FAST path for FLOAT capture. - if (isFloat + if (OboeGlobals::areWorkaroundsEnabled() + && isFloat && isInput && builder.isFormatConversionAllowed() && isLowLatency @@ -198,15 +256,17 @@ bool QuirksManager::isConversionNeeded( LOGI("QuirksManager::%s() forcing internal format to I16 for low latency", __func__); } - // Add quirk for float output on API <21 - if (isFloat + // Add quirk for float output when needed. + if (OboeGlobals::areWorkaroundsEnabled() + && isFloat && !isInput - && getSdkVersion() < __ANDROID_API_L__ && builder.isFormatConversionAllowed() + && mDeviceQuirks->shouldConvertFloatToI16ForOutputStreams() ) { childBuilder.setFormat(AudioFormat::I16); conversionNeeded = true; - LOGI("QuirksManager::%s() float was requested but not supported on pre-L devices, " + LOGI("QuirksManager::%s() float was requested but not supported on pre-L devices " + "and some devices like Vivo devices may have issues on L devices, " "creating an underlying I16 stream and using format conversion to provide a float " "stream", __func__); } diff --git a/modules/juce_audio_devices/native/oboe/src/common/QuirksManager.h b/modules/juce_audio_devices/native/oboe/src/common/QuirksManager.h index aeca270ac9ad..c24e974981a4 100644 --- a/modules/juce_audio_devices/native/oboe/src/common/QuirksManager.h +++ b/modules/juce_audio_devices/native/oboe/src/common/QuirksManager.h @@ -106,6 +106,9 @@ class QuirksManager { return true; } + // On some devices, Float does not work so it should be converted to I16. + static bool shouldConvertFloatToI16ForOutputStreams(); + static constexpr int32_t kDefaultBottomMarginInBursts = 0; static constexpr int32_t kDefaultTopMarginInBursts = 0; diff --git a/modules/juce_audio_devices/native/oboe/src/common/README.md b/modules/juce_audio_devices/native/oboe/src/common/README.md new file mode 100644 index 000000000000..d397458890a2 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/common/README.md @@ -0,0 +1,33 @@ +# Notes on Implementation + +## Latency from Resampling + +There are two components of the latency. The resampler itself, and a buffer that +is used to adapt the block sizes. + +1) The resampler is an FIR running at the target sample rate. So its latency is the number of taps. +From MultiChannelResampler.cpp, numTaps is + + Fastest: 2 + Low: 4 + Medium: 8 + High: 16 + Best: 32 + +For output, the device sampling rate is used, which is typically 48000.For input, the app sampling rate is used. + +2) There is a block size adapter that collects odd sized blocks into larger blocks of the correct size. + +The adapter contains one burst of frames, from getFramesPerBurst(). But if the app specifies a +particular size using setFramesPerCallback() then that size will be used. +Here is some pseudo-code to calculate the latency. + + latencyMillis = 0 + targetRate = isOutput ? deviceRate : applicationRate + // Add latency from FIR + latencyMillis += numTaps * 1000.0 / targetRate + // Add latency from block size adaptation + adapterSize = (callbackSize > 0) ? callbackSize : burstSize + if (isOutput && isCallbackUsed) latencyMillis += adapterSize * 1000.0 / deviceRate + else if (isInput && isCallbackUsed) latencyMillis += adapterSize * 1000.0 / applicationRate + else if (isInput && !isCallbackUsed) latencyMillis += adapterSize * 1000.0 / deviceRate diff --git a/modules/juce_audio_devices/native/oboe/src/common/SourceI16Caller.h b/modules/juce_audio_devices/native/oboe/src/common/SourceI16Caller.h index 22c1b9aba3ad..02a57c22167f 100644 --- a/modules/juce_audio_devices/native/oboe/src/common/SourceI16Caller.h +++ b/modules/juce_audio_devices/native/oboe/src/common/SourceI16Caller.h @@ -32,7 +32,8 @@ class SourceI16Caller : public AudioSourceCaller { public: SourceI16Caller(int32_t channelCount, int32_t framesPerCallback) : AudioSourceCaller(channelCount, framesPerCallback, sizeof(int16_t)) { - mConversionBuffer = std::make_unique(channelCount * output.getFramesPerBuffer()); + mConversionBuffer = std::make_unique(static_cast(channelCount) + * static_cast(output.getFramesPerBuffer())); } int32_t onProcess(int32_t numFrames) override; diff --git a/modules/juce_audio_devices/native/oboe/src/common/SourceI24Caller.h b/modules/juce_audio_devices/native/oboe/src/common/SourceI24Caller.h index f8c8e115fb2b..3b5eab726c44 100644 --- a/modules/juce_audio_devices/native/oboe/src/common/SourceI24Caller.h +++ b/modules/juce_audio_devices/native/oboe/src/common/SourceI24Caller.h @@ -33,8 +33,9 @@ class SourceI24Caller : public AudioSourceCaller { public: SourceI24Caller(int32_t channelCount, int32_t framesPerCallback) : AudioSourceCaller(channelCount, framesPerCallback, kBytesPerI24Packed) { - mConversionBuffer = std::make_unique( - kBytesPerI24Packed * channelCount * output.getFramesPerBuffer()); + mConversionBuffer = std::make_unique(static_cast(kBytesPerI24Packed) + * static_cast(channelCount) + * static_cast(output.getFramesPerBuffer())); } int32_t onProcess(int32_t numFrames) override; diff --git a/modules/juce_audio_devices/native/oboe/src/common/SourceI32Caller.h b/modules/juce_audio_devices/native/oboe/src/common/SourceI32Caller.h index d802ccc7aeb8..18c3343a627b 100644 --- a/modules/juce_audio_devices/native/oboe/src/common/SourceI32Caller.h +++ b/modules/juce_audio_devices/native/oboe/src/common/SourceI32Caller.h @@ -34,7 +34,8 @@ class SourceI32Caller : public AudioSourceCaller { public: SourceI32Caller(int32_t channelCount, int32_t framesPerCallback) : AudioSourceCaller(channelCount, framesPerCallback, sizeof(int32_t)) { - mConversionBuffer = std::make_unique(channelCount * output.getFramesPerBuffer()); + mConversionBuffer = std::make_unique(static_cast(channelCount) + * static_cast(output.getFramesPerBuffer())); } int32_t onProcess(int32_t numFrames) override; diff --git a/modules/juce_audio_devices/native/oboe/src/common/StabilizedCallback.cpp b/modules/juce_audio_devices/native/oboe/src/common/StabilizedCallback.cpp index 692db89ba6ed..a2ac54959bbf 100644 --- a/modules/juce_audio_devices/native/oboe/src/common/StabilizedCallback.cpp +++ b/modules/juce_audio_devices/native/oboe/src/common/StabilizedCallback.cpp @@ -109,4 +109,4 @@ void StabilizedCallback::generateLoad(int64_t durationNanos) { mOpsPerNano = kFilterCoefficient * measuredOpsPerNano + (1.0 - kFilterCoefficient) * mOpsPerNano; opsPerStep = (int) (mOpsPerNano * kLoadGenerationStepSizeNanos); } -} \ No newline at end of file +} diff --git a/modules/juce_audio_devices/native/oboe/src/common/Trace.cpp b/modules/juce_audio_devices/native/oboe/src/common/Trace.cpp index 5ed445b5dcdd..f08f36dc5869 100644 --- a/modules/juce_audio_devices/native/oboe/src/common/Trace.cpp +++ b/modules/juce_audio_devices/native/oboe/src/common/Trace.cpp @@ -72,4 +72,4 @@ void Trace::initialize() { mIsTracingSupported = true; } } -} \ No newline at end of file +} diff --git a/modules/juce_audio_devices/native/oboe/src/common/Trace.h b/modules/juce_audio_devices/native/oboe/src/common/Trace.h index c7965f956f1c..dad6c00714d1 100644 --- a/modules/juce_audio_devices/native/oboe/src/common/Trace.h +++ b/modules/juce_audio_devices/native/oboe/src/common/Trace.h @@ -28,4 +28,4 @@ class Trace { static bool mIsTracingSupported; }; -#endif //OBOE_TRACE_H \ No newline at end of file +#endif //OBOE_TRACE_H diff --git a/modules/juce_audio_devices/native/oboe/src/common/Utilities.cpp b/modules/juce_audio_devices/native/oboe/src/common/Utilities.cpp index 177c544b3e05..f6718afca0e9 100644 --- a/modules/juce_audio_devices/native/oboe/src/common/Utilities.cpp +++ b/modules/juce_audio_devices/native/oboe/src/common/Utilities.cpp @@ -66,6 +66,9 @@ int32_t convertFormatToSizeInBytes(AudioFormat format) { case AudioFormat::I32: size = sizeof(int32_t); break; + case AudioFormat::IEC61937: + size = sizeof(int16_t); + break; default: break; } @@ -106,6 +109,7 @@ const char *convertToText(AudioFormat format) { case AudioFormat::Float: return "Float"; case AudioFormat::I24: return "I24"; case AudioFormat::I32: return "I32"; + case AudioFormat::IEC61937: return "IEC61937"; default: return "Unrecognized format"; } } @@ -310,4 +314,20 @@ int getSdkVersion() { return sCachedSdkVersion; } +bool isAtLeastPreReleaseCodename(const std::string& codename) { + std::string buildCodename = getPropertyString("ro.build.version.codename"); + // Special case "REL", which means the build is not a pre-release build. + if ("REL" == buildCodename) { + return false; + } + + // Otherwise lexically compare them. Return true if the build codename is equal to or + // greater than the requested codename. + return buildCodename.compare(codename) >= 0; +} + +int getChannelCountFromChannelMask(ChannelMask channelMask) { + return __builtin_popcount(static_cast(channelMask)); +} + }// namespace oboe diff --git a/modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.cpp b/modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.cpp index d8314bb8c73c..c33315d04896 100644 --- a/modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.cpp +++ b/modules/juce_audio_devices/native/oboe/src/fifo/FifoBuffer.cpp @@ -18,10 +18,10 @@ #include #include -#include "fifo/FifoControllerBase.h" +#include "oboe/FifoControllerBase.h" #include "fifo/FifoController.h" #include "fifo/FifoControllerIndirect.h" -#include "fifo/FifoBuffer.h" +#include "oboe/FifoBuffer.h" namespace oboe { diff --git a/modules/juce_audio_devices/native/oboe/src/fifo/FifoController.cpp b/modules/juce_audio_devices/native/oboe/src/fifo/FifoController.cpp index b2168d138a5b..aa0d5b7db5cb 100644 --- a/modules/juce_audio_devices/native/oboe/src/fifo/FifoController.cpp +++ b/modules/juce_audio_devices/native/oboe/src/fifo/FifoController.cpp @@ -16,7 +16,6 @@ #include -#include "FifoControllerBase.h" #include "FifoController.h" namespace oboe { diff --git a/modules/juce_audio_devices/native/oboe/src/fifo/FifoController.h b/modules/juce_audio_devices/native/oboe/src/fifo/FifoController.h index d3e413e3c9ec..b3e2d079a6fe 100644 --- a/modules/juce_audio_devices/native/oboe/src/fifo/FifoController.h +++ b/modules/juce_audio_devices/native/oboe/src/fifo/FifoController.h @@ -20,7 +20,7 @@ #include #include -#include "FifoControllerBase.h" +#include "oboe/FifoControllerBase.h" namespace oboe { diff --git a/modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.cpp b/modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.cpp index d3419475367e..dc65b87d291b 100644 --- a/modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.cpp +++ b/modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerBase.cpp @@ -18,7 +18,7 @@ #include #include -#include "FifoControllerBase.h" +#include "oboe/FifoControllerBase.h" namespace oboe { diff --git a/modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.h b/modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.h index 32f788190446..c25c60749fea 100644 --- a/modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.h +++ b/modules/juce_audio_devices/native/oboe/src/fifo/FifoControllerIndirect.h @@ -20,7 +20,7 @@ #include #include -#include "FifoControllerBase.h" +#include "oboe/FifoControllerBase.h" namespace oboe { diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/ChannelCountConverter.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/ChannelCountConverter.cpp index b56f8b270847..dc804277d5b7 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/ChannelCountConverter.cpp +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/ChannelCountConverter.cpp @@ -27,7 +27,7 @@ ChannelCountConverter::ChannelCountConverter( , output(*this, outputChannelCount) { } -ChannelCountConverter::~ChannelCountConverter() { } +ChannelCountConverter::~ChannelCountConverter() = default; int32_t ChannelCountConverter::onProcess(int32_t numFrames) { const float *inputBuffer = input.getBuffer(); diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/ChannelCountConverter.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/ChannelCountConverter.h index f688d443259c..858f4d4f1459 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/ChannelCountConverter.h +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/ChannelCountConverter.h @@ -22,8 +22,7 @@ #include "FlowGraphNode.h" -namespace FLOWGRAPH_OUTER_NAMESPACE { -namespace flowgraph { +namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph { /** * Change the number of number of channels without mixing. @@ -48,7 +47,6 @@ namespace flowgraph { FlowGraphPortFloatOutput output; }; -} /* namespace flowgraph */ -} /* namespace FLOWGRAPH_OUTER_NAMESPACE */ +} /* namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph */ #endif //FLOWGRAPH_CHANNEL_COUNT_CONVERTER_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/ClipToRange.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/ClipToRange.h index 4dc82f6c7617..2fddeee7103c 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/ClipToRange.h +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/ClipToRange.h @@ -23,8 +23,7 @@ #include "FlowGraphNode.h" -namespace FLOWGRAPH_OUTER_NAMESPACE { -namespace flowgraph { +namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph { // This is 3 dB, (10^(3/20)), to match the maximum headroom in AudioTrack for float data. // It is designed to allow occasional transient peaks. @@ -64,7 +63,6 @@ class ClipToRange : public FlowGraphFilter { float mMaximum = kDefaultMaxHeadroom; }; -} /* namespace flowgraph */ -} /* namespace FLOWGRAPH_OUTER_NAMESPACE */ +} /* namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph */ #endif //FLOWGRAPH_CLIP_TO_RANGE_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.cpp index 9a62d7d89244..012abe7ef106 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.cpp +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.cpp @@ -68,7 +68,7 @@ FlowGraphPortFloat::FlowGraphPortFloat(FlowGraphNode &parent, : FlowGraphPort(parent, samplesPerFrame) , mFramesPerBuffer(framesPerBuffer) , mBuffer(nullptr) { - size_t numFloats = static_cast(framesPerBuffer * getSamplesPerFrame()); + size_t numFloats = static_cast(framesPerBuffer) * getSamplesPerFrame(); mBuffer = std::make_unique(numFloats); } diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.h index acbee565c5b8..2884c081fb6b 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.h +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/FlowGraphNode.h @@ -38,23 +38,26 @@ // TODO Review use of raw pointers for connect(). Maybe use smart pointers but need to avoid // run-time deallocation in audio thread. -// Set this to 1 if using it inside the Android framework. -// This code is kept here so that it can be moved easily between Oboe and AAudio. +// Set flags FLOWGRAPH_ANDROID_INTERNAL and FLOWGRAPH_OUTER_NAMESPACE based on whether compiler +// flag __ANDROID_NDK__ is defined. __ANDROID_NDK__ should be defined in oboe and not aaudio. + #ifndef FLOWGRAPH_ANDROID_INTERNAL +#ifdef __ANDROID_NDK__ #define FLOWGRAPH_ANDROID_INTERNAL 0 -#endif +#else +#define FLOWGRAPH_ANDROID_INTERNAL 1 +#endif // __ANDROID_NDK__ +#endif // FLOWGRAPH_ANDROID_INTERNAL -// Set this to a name that will prevent AAudio from calling into Oboe. -// AAudio and Oboe both use a version of this flowgraph package. -// There was a problem in the unit tests where AAudio would call a constructor -// in AAudio and then call a destructor in Oboe! That caused memory corruption. -// For more details, see Issue #930. #ifndef FLOWGRAPH_OUTER_NAMESPACE +#ifdef __ANDROID_NDK__ #define FLOWGRAPH_OUTER_NAMESPACE oboe -#endif +#else +#define FLOWGRAPH_OUTER_NAMESPACE aaudio +#endif // __ANDROID_NDK__ +#endif // FLOWGRAPH_OUTER_NAMESPACE -namespace FLOWGRAPH_OUTER_NAMESPACE { -namespace flowgraph { +namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph { // Default block size that can be overridden when the FlowGraphPortFloat is created. // If it is too small then we will have too much overhead from switching between nodes. @@ -70,7 +73,7 @@ class FlowGraphPortFloatInput; */ class FlowGraphNode { public: - FlowGraphNode() {} + FlowGraphNode() = default; virtual ~FlowGraphNode() = default; /** @@ -108,7 +111,7 @@ class FlowGraphNode { virtual void reset(); void addInputPort(FlowGraphPort &port) { - mInputPorts.push_back(port); + mInputPorts.emplace_back(port); } bool isDataPulledAutomatically() const { @@ -164,7 +167,7 @@ class FlowGraphPort { : mContainingNode(parent) , mSamplesPerFrame(samplesPerFrame) { } - + virtual ~FlowGraphPort() = default; // Ports are often declared public. So let's make them non-copyable. @@ -403,7 +406,7 @@ class FlowGraphSink : public FlowGraphNode { FlowGraphPortFloatInput input; /** - * Dummy processor. The work happens in the read() method. + * Do nothing. The work happens in the read() method. * * @param numFrames * @return number of frames actually processed @@ -442,7 +445,6 @@ class FlowGraphFilter : public FlowGraphNode { FlowGraphPortFloatOutput output; }; -} /* namespace flowgraph */ -} /* namespace FLOWGRAPH_OUTER_NAMESPACE */ +} /* namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph */ #endif /* FLOWGRAPH_FLOW_GRAPH_NODE_H */ diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/FlowgraphUtilities.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/FlowgraphUtilities.h index ce2bc82faaeb..5e90588ce9f2 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/FlowgraphUtilities.h +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/FlowgraphUtilities.h @@ -39,9 +39,9 @@ static int32_t clamp32FromFloat(float f) static const float limneg = -1.; if (f <= limneg) { - return -0x80000000; /* or 0x80000000 */ + return INT32_MIN; } else if (f >= limpos) { - return 0x7fffffff; + return INT32_MAX; } f *= scale; /* integer conversion is through truncation (though int to float is not). diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/Limiter.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/Limiter.cpp new file mode 100644 index 000000000000..def905a75246 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/Limiter.cpp @@ -0,0 +1,67 @@ +/* + * Copyright 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include "FlowGraphNode.h" +#include "Limiter.h" + +using namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph; + +Limiter::Limiter(int32_t channelCount) + : FlowGraphFilter(channelCount) { +} + +int32_t Limiter::onProcess(int32_t numFrames) { + const float *inputBuffer = input.getBuffer(); + float *outputBuffer = output.getBuffer(); + + int32_t numSamples = numFrames * output.getSamplesPerFrame(); + + // Cache the last valid output to reduce memory read/write + float lastValidOutput = mLastValidOutput; + + for (int32_t i = 0; i < numSamples; i++) { + // Use the previous output if the input is NaN + if (!isnan(*inputBuffer)) { + lastValidOutput = processFloat(*inputBuffer); + } + inputBuffer++; + *outputBuffer++ = lastValidOutput; + } + mLastValidOutput = lastValidOutput; + + return numFrames; +} + +float Limiter::processFloat(float in) +{ + float in_abs = fabsf(in); + if (in_abs <= 1) { + return in; + } + float out; + if (in_abs < kXWhenYis3Decibels) { + out = (kPolynomialSplineA * in_abs + kPolynomialSplineB) * in_abs + kPolynomialSplineC; + } else { + out = M_SQRT2; + } + if (in < 0) { + out = -out; + } + return out; +} diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/Limiter.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/Limiter.h new file mode 100644 index 000000000000..393a7bf3c67a --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/Limiter.h @@ -0,0 +1,64 @@ +/* + * Copyright 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FLOWGRAPH_LIMITER_H +#define FLOWGRAPH_LIMITER_H + +#include +#include +#include + +#include "FlowGraphNode.h" + +namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph { + +class Limiter : public FlowGraphFilter { +public: + explicit Limiter(int32_t channelCount); + + int32_t onProcess(int32_t numFrames) override; + + const char *getName() override { + return "Limiter"; + } + +private: + // These numbers are based on a polynomial spline for a quadratic solution Ax^2 + Bx + C + // The range is up to 3 dB, (10^(3/20)), to match AudioTrack for float data. + static constexpr float kPolynomialSplineA = -0.6035533905; // -(1+sqrt(2))/4 + static constexpr float kPolynomialSplineB = 2.2071067811; // (3+sqrt(2))/2 + static constexpr float kPolynomialSplineC = -0.6035533905; // -(1+sqrt(2))/4 + static constexpr float kXWhenYis3Decibels = 1.8284271247; // -1+2sqrt(2) + + /** + * Process an input based on the following: + * If between -1 and 1, return the input value. + * If above kXWhenYis3Decibels, return sqrt(2). + * If below -kXWhenYis3Decibels, return -sqrt(2). + * If between 1 and kXWhenYis3Decibels, use a quadratic spline (Ax^2 + Bx + C). + * If between -kXWhenYis3Decibels and -1, use the absolute value for the spline and flip it. + * The derivative of the spline is 1 at 1 and 0 at kXWhenYis3Decibels. + * This way, the graph is both continuous and differentiable. + */ + float processFloat(float in); + + // Use the previous valid output for NaN inputs + float mLastValidOutput = 0.0f; +}; + +} /* namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph */ + +#endif //FLOWGRAPH_LIMITER_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.h index 21a95df5f96a..50644cf913dc 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.h +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/ManyToMultiConverter.h @@ -23,8 +23,7 @@ #include "FlowGraphNode.h" -namespace FLOWGRAPH_OUTER_NAMESPACE { -namespace flowgraph { +namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph { /** * Combine multiple mono inputs into one interleaved multi-channel output. @@ -49,7 +48,6 @@ class ManyToMultiConverter : public flowgraph::FlowGraphNode { private: }; -} /* namespace flowgraph */ -} /* namespace FLOWGRAPH_OUTER_NAMESPACE */ +} /* namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph */ #endif //FLOWGRAPH_MANY_TO_MULTI_CONVERTER_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/MonoBlend.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/MonoBlend.cpp new file mode 100644 index 000000000000..4fd75e19df25 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/MonoBlend.cpp @@ -0,0 +1,46 @@ +/* + * Copyright 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "MonoBlend.h" + +using namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph; + +MonoBlend::MonoBlend(int32_t channelCount) + : FlowGraphFilter(channelCount) + , mInvChannelCount(1. / channelCount) +{ +} + +int32_t MonoBlend::onProcess(int32_t numFrames) { + int32_t channelCount = output.getSamplesPerFrame(); + const float *inputBuffer = input.getBuffer(); + float *outputBuffer = output.getBuffer(); + + for (size_t i = 0; i < numFrames; ++i) { + float accum = 0; + for (size_t j = 0; j < channelCount; ++j) { + accum += *inputBuffer++; + } + accum *= mInvChannelCount; + for (size_t j = 0; j < channelCount; ++j) { + *outputBuffer++ = accum; + } + } + + return numFrames; +} diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/MonoBlend.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/MonoBlend.h new file mode 100644 index 000000000000..f8d44ffb848b --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/MonoBlend.h @@ -0,0 +1,48 @@ +/* + * Copyright 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FLOWGRAPH_MONO_BLEND_H +#define FLOWGRAPH_MONO_BLEND_H + +#include +#include + +#include "FlowGraphNode.h" + +namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph { + +/** + * Combine data between multiple channels so each channel is an average + * of all channels. + */ +class MonoBlend : public FlowGraphFilter { +public: + explicit MonoBlend(int32_t channelCount); + + virtual ~MonoBlend() = default; + + int32_t onProcess(int32_t numFrames) override; + + const char *getName() override { + return "MonoBlend"; + } +private: + const float mInvChannelCount; +}; + +} /* namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph */ + +#endif //FLOWGRAPH_MONO_BLEND diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.cpp index bb471a0f1990..33eed5232aae 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.cpp +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.cpp @@ -25,8 +25,6 @@ MonoToMultiConverter::MonoToMultiConverter(int32_t outputChannelCount) , output(*this, outputChannelCount) { } -MonoToMultiConverter::~MonoToMultiConverter() { } - int32_t MonoToMultiConverter::onProcess(int32_t numFrames) { const float *inputBuffer = input.getBuffer(); float *outputBuffer = output.getBuffer(); diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.h index 9216f1a9ec9b..762edb0a6494 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.h +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/MonoToMultiConverter.h @@ -22,8 +22,7 @@ #include "FlowGraphNode.h" -namespace FLOWGRAPH_OUTER_NAMESPACE { -namespace flowgraph { +namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph { /** * Convert a monophonic stream to a multi-channel interleaved stream @@ -33,7 +32,7 @@ class MonoToMultiConverter : public FlowGraphNode { public: explicit MonoToMultiConverter(int32_t outputChannelCount); - virtual ~MonoToMultiConverter(); + virtual ~MonoToMultiConverter() = default; int32_t onProcess(int32_t numFrames) override; @@ -45,7 +44,6 @@ class MonoToMultiConverter : public FlowGraphNode { FlowGraphPortFloatOutput output; }; -} /* namespace flowgraph */ -} /* namespace FLOWGRAPH_OUTER_NAMESPACE */ +} /* namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph */ #endif //FLOWGRAPH_MONO_TO_MULTI_CONVERTER_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToManyConverter.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToManyConverter.cpp new file mode 100644 index 000000000000..5cdf594bc799 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToManyConverter.cpp @@ -0,0 +1,47 @@ +/* + * Copyright 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "FlowGraphNode.h" +#include "MultiToManyConverter.h" + +using namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph; + +MultiToManyConverter::MultiToManyConverter(int32_t channelCount) + : outputs(channelCount) + , input(*this, channelCount) { + for (int i = 0; i < channelCount; i++) { + outputs[i] = std::make_unique(*this, 1); + } +} + +MultiToManyConverter::~MultiToManyConverter() = default; + +int32_t MultiToManyConverter::onProcess(int32_t numFrames) { + int32_t channelCount = input.getSamplesPerFrame(); + + for (int ch = 0; ch < channelCount; ch++) { + const float *inputBuffer = input.getBuffer() + ch; + float *outputBuffer = outputs[ch]->getBuffer(); + + for (int i = 0; i < numFrames; i++) { + *outputBuffer++ = *inputBuffer; + inputBuffer += channelCount; + } + } + + return numFrames; +} diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToManyConverter.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToManyConverter.h new file mode 100644 index 000000000000..0b222ac6f786 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToManyConverter.h @@ -0,0 +1,49 @@ +/* + * Copyright 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FLOWGRAPH_MULTI_TO_MANY_CONVERTER_H +#define FLOWGRAPH_MULTI_TO_MANY_CONVERTER_H + +#include +#include + +#include "FlowGraphNode.h" + +namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph { + +/** + * Convert a multi-channel interleaved stream to multiple mono-channel + * outputs + */ + class MultiToManyConverter : public FlowGraphNode { + public: + explicit MultiToManyConverter(int32_t channelCount); + + virtual ~MultiToManyConverter(); + + int32_t onProcess(int32_t numFrames) override; + + const char *getName() override { + return "MultiToManyConverter"; + } + + std::vector> outputs; + flowgraph::FlowGraphPortFloatInput input; + }; + +} /* namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph */ + +#endif //FLOWGRAPH_MULTI_TO_MANY_CONVERTER_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToMonoConverter.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToMonoConverter.cpp index 8e895bf69841..467f95ea6305 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToMonoConverter.cpp +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToMonoConverter.cpp @@ -25,7 +25,7 @@ MultiToMonoConverter::MultiToMonoConverter(int32_t inputChannelCount) , output(*this, 1) { } -MultiToMonoConverter::~MultiToMonoConverter() { } +MultiToMonoConverter::~MultiToMonoConverter() = default; int32_t MultiToMonoConverter::onProcess(int32_t numFrames) { const float *inputBuffer = input.getBuffer(); diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToMonoConverter.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToMonoConverter.h index 9cb691145390..bf5b7b601b36 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToMonoConverter.h +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/MultiToMonoConverter.h @@ -22,8 +22,7 @@ #include "FlowGraphNode.h" -namespace FLOWGRAPH_OUTER_NAMESPACE { -namespace flowgraph { +namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph { /** * Convert a multi-channel interleaved stream to a monophonic stream @@ -45,7 +44,6 @@ namespace flowgraph { FlowGraphPortFloatOutput output; }; -} /* namespace flowgraph */ -} /* namespace FLOWGRAPH_OUTER_NAMESPACE */ +} /* namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph */ #endif //FLOWGRAPH_MULTI_TO_MONO_CONVERTER_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/RampLinear.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/RampLinear.h index 8d4c546e9626..3839d6ef968b 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/RampLinear.h +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/RampLinear.h @@ -23,8 +23,7 @@ #include "FlowGraphNode.h" -namespace FLOWGRAPH_OUTER_NAMESPACE { -namespace flowgraph { +namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph { /** * When the target is modified then the output will ramp smoothly @@ -92,7 +91,6 @@ class RampLinear : public FlowGraphFilter { float mLevelTo = 0.0f; }; -} /* namespace flowgraph */ -} /* namespace FLOWGRAPH_OUTER_NAMESPACE */ +} /* namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph */ #endif //FLOWGRAPH_RAMP_LINEAR_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/SampleRateConverter.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/SampleRateConverter.cpp index b1ae4bd82bc6..a15fcb8ce91f 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/SampleRateConverter.cpp +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/SampleRateConverter.cpp @@ -17,9 +17,10 @@ #include "SampleRateConverter.h" using namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph; -using namespace resampler; +using namespace RESAMPLER_OUTER_NAMESPACE::resampler; -SampleRateConverter::SampleRateConverter(int32_t channelCount, MultiChannelResampler &resampler) +SampleRateConverter::SampleRateConverter(int32_t channelCount, + MultiChannelResampler &resampler) : FlowGraphFilter(channelCount) , mResampler(resampler) { setDataPulledAutomatically(false); diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/SampleRateConverter.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/SampleRateConverter.h index 534df49aaeb8..f883e6ce285b 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/SampleRateConverter.h +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/SampleRateConverter.h @@ -14,8 +14,8 @@ * limitations under the License. */ -#ifndef OBOE_SAMPLE_RATE_CONVERTER_H -#define OBOE_SAMPLE_RATE_CONVERTER_H +#ifndef FLOWGRAPH_SAMPLE_RATE_CONVERTER_H +#define FLOWGRAPH_SAMPLE_RATE_CONVERTER_H #include #include @@ -23,12 +23,12 @@ #include "FlowGraphNode.h" #include "resampler/MultiChannelResampler.h" -namespace FLOWGRAPH_OUTER_NAMESPACE { -namespace flowgraph { +namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph { class SampleRateConverter : public FlowGraphFilter { public: - explicit SampleRateConverter(int32_t channelCount, resampler::MultiChannelResampler &mResampler); + explicit SampleRateConverter(int32_t channelCount, + resampler::MultiChannelResampler &mResampler); virtual ~SampleRateConverter() = default; @@ -58,7 +58,6 @@ class SampleRateConverter : public FlowGraphFilter { }; -} /* namespace flowgraph */ -} /* namespace FLOWGRAPH_OUTER_NAMESPACE */ +} /* namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph */ -#endif //OBOE_SAMPLE_RATE_CONVERTER_H +#endif //FLOWGRAPH_SAMPLE_RATE_CONVERTER_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkFloat.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkFloat.cpp index 1242f5f2f795..940a66be8816 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkFloat.cpp +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkFloat.cpp @@ -26,7 +26,6 @@ SinkFloat::SinkFloat(int32_t channelCount) } int32_t SinkFloat::read(void *data, int32_t numFrames) { - // printf("SinkFloat::read(,,%d)\n", numFrames); float *floatData = (float *) data; const int32_t channelCount = input.getSamplesPerFrame(); @@ -34,7 +33,6 @@ int32_t SinkFloat::read(void *data, int32_t numFrames) { while (framesLeft > 0) { // Run the graph and pull data through the input port. int32_t framesPulled = pullData(framesLeft); - // printf("SinkFloat::read: framesLeft = %d, framesPulled = %d\n", framesLeft, framesPulled); if (framesPulled <= 0) { break; } @@ -44,6 +42,5 @@ int32_t SinkFloat::read(void *data, int32_t numFrames) { floatData += numSamples; framesLeft -= framesPulled; } - // printf("SinkFloat returning %d\n", numFrames - framesLeft); return numFrames - framesLeft; } diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkFloat.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkFloat.h index c3f26bdfb082..3be3f5d49e38 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkFloat.h +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkFloat.h @@ -23,8 +23,7 @@ #include "FlowGraphNode.h" -namespace FLOWGRAPH_OUTER_NAMESPACE { -namespace flowgraph { +namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph { /** * AudioSink that lets you read data as 32-bit floats. @@ -41,7 +40,6 @@ class SinkFloat : public FlowGraphSink { } }; -} /* namespace flowgraph */ -} /* namespace FLOWGRAPH_OUTER_NAMESPACE */ +} /* namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph */ #endif //FLOWGRAPH_SINK_FLOAT_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI16.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI16.h index e65ffae59cf6..bf124f55b112 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI16.h +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI16.h @@ -22,8 +22,7 @@ #include "FlowGraphNode.h" -namespace FLOWGRAPH_OUTER_NAMESPACE { -namespace flowgraph { +namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph { /** * AudioSink that lets you read data as 16-bit signed integers. @@ -39,7 +38,6 @@ class SinkI16 : public FlowGraphSink { } }; -} /* namespace flowgraph */ -} /* namespace FLOWGRAPH_OUTER_NAMESPACE */ +} /* namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph */ #endif //FLOWGRAPH_SINK_I16_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI24.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI24.h index 116a57906323..6b4135e97ea9 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI24.h +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI24.h @@ -22,8 +22,7 @@ #include "FlowGraphNode.h" -namespace FLOWGRAPH_OUTER_NAMESPACE { -namespace flowgraph { +namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph { /** * AudioSink that lets you read data as packed 24-bit signed integers. @@ -40,7 +39,6 @@ class SinkI24 : public FlowGraphSink { } }; -} /* namespace flowgraph */ -} /* namespace FLOWGRAPH_OUTER_NAMESPACE */ +} /* namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph */ #endif //FLOWGRAPH_SINK_I24_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI32.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI32.cpp index 504ae4715055..b14b3d2a42f3 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI32.cpp +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI32.cpp @@ -14,14 +14,14 @@ * limitations under the License. */ -#if FLOWGRAPH_ANDROID_INTERNAL -#include -#endif - #include "FlowGraphNode.h" #include "FlowgraphUtilities.h" #include "SinkI32.h" +#if FLOWGRAPH_ANDROID_INTERNAL +#include +#endif + using namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph; SinkI32::SinkI32(int32_t channelCount) diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI32.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI32.h index 6850b40dc5a9..35507ea1a4db 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI32.h +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/SinkI32.h @@ -21,8 +21,7 @@ #include "FlowGraphNode.h" -namespace FLOWGRAPH_OUTER_NAMESPACE { -namespace flowgraph { +namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph { class SinkI32 : public FlowGraphSink { public: @@ -36,7 +35,6 @@ class SinkI32 : public FlowGraphSink { } }; -} /* namespace flowgraph */ -} /* namespace FLOWGRAPH_OUTER_NAMESPACE */ +} /* namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph */ #endif //FLOWGRAPH_SINK_I32_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceFloat.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceFloat.cpp index a27d43b7f8bb..a0c88275a039 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceFloat.cpp +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceFloat.cpp @@ -14,7 +14,6 @@ * limitations under the License. */ -#include "common/OboeDebug.h" #include #include #include "FlowGraphNode.h" diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceFloat.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceFloat.h index cba67581c1a4..78053e511866 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceFloat.h +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceFloat.h @@ -22,8 +22,7 @@ #include "FlowGraphNode.h" -namespace FLOWGRAPH_OUTER_NAMESPACE { -namespace flowgraph { +namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph { /** * AudioSource that reads a block of pre-defined float data. @@ -40,7 +39,6 @@ class SourceFloat : public FlowGraphSourceBuffered { } }; -} /* namespace flowgraph */ -} /* namespace FLOWGRAPH_OUTER_NAMESPACE */ +} /* namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph */ #endif //FLOWGRAPH_SOURCE_FLOAT_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI16.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI16.cpp index 16cd2b3dc835..58c3b1e86ce1 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI16.cpp +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI16.cpp @@ -51,4 +51,4 @@ int32_t SourceI16::onProcess(int32_t numFrames) { mFrameIndex += framesToProcess; return framesToProcess; -} \ No newline at end of file +} diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI16.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI16.h index 3e04c5e5639f..923890cb5033 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI16.h +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI16.h @@ -22,8 +22,7 @@ #include "FlowGraphNode.h" -namespace FLOWGRAPH_OUTER_NAMESPACE { -namespace flowgraph { +namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph { /** * AudioSource that reads a block of pre-defined 16-bit integer data. */ @@ -38,7 +37,6 @@ class SourceI16 : public FlowGraphSourceBuffered { } }; -} /* namespace flowgraph */ -} /* namespace FLOWGRAPH_OUTER_NAMESPACE */ +} /* namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph */ #endif //FLOWGRAPH_SOURCE_I16_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI24.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI24.cpp index 321f732f1978..cd4b7d90c3a3 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI24.cpp +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI24.cpp @@ -17,13 +17,13 @@ #include #include +#include "FlowGraphNode.h" +#include "SourceI24.h" + #if FLOWGRAPH_ANDROID_INTERNAL #include #endif -#include "FlowGraphNode.h" -#include "SourceI24.h" - using namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph; constexpr int kBytesPerI24Packed = 3; @@ -62,4 +62,4 @@ int32_t SourceI24::onProcess(int32_t numFrames) { mFrameIndex += framesToProcess; return framesToProcess; -} \ No newline at end of file +} diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI24.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI24.h index 69044d5264cf..fb66d4a4db74 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI24.h +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI24.h @@ -22,8 +22,7 @@ #include "FlowGraphNode.h" -namespace FLOWGRAPH_OUTER_NAMESPACE { -namespace flowgraph { +namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph { /** * AudioSource that reads a block of pre-defined 24-bit packed integer data. @@ -39,7 +38,6 @@ class SourceI24 : public FlowGraphSourceBuffered { } }; -} /* namespace flowgraph */ -} /* namespace FLOWGRAPH_OUTER_NAMESPACE */ +} /* namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph */ #endif //FLOWGRAPH_SOURCE_I24_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI32.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI32.cpp index e4b8041848ce..b1c8f75ab6e2 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI32.cpp +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI32.cpp @@ -17,13 +17,13 @@ #include #include +#include "FlowGraphNode.h" +#include "SourceI32.h" + #if FLOWGRAPH_ANDROID_INTERNAL #include #endif -#include "FlowGraphNode.h" -#include "SourceI32.h" - using namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph; SourceI32::SourceI32(int32_t channelCount) diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI32.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI32.h index 7ba29e9b234e..71094690402f 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI32.h +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/SourceI32.h @@ -21,8 +21,7 @@ #include "FlowGraphNode.h" -namespace FLOWGRAPH_OUTER_NAMESPACE { -namespace flowgraph { +namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph { class SourceI32 : public FlowGraphSourceBuffered { public: @@ -38,7 +37,6 @@ class SourceI32 : public FlowGraphSourceBuffered { static constexpr float kScale = 1.0 / (1UL << 31); }; -} /* namespace flowgraph */ -} /* namespace FLOWGRAPH_OUTER_NAMESPACE */ +} /* namespace FLOWGRAPH_OUTER_NAMESPACE::flowgraph */ #endif //FLOWGRAPH_SOURCE_I32_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/HyperbolicCosineWindow.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/HyperbolicCosineWindow.h index f6479ae327da..76ec0e70d591 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/HyperbolicCosineWindow.h +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/HyperbolicCosineWindow.h @@ -19,7 +19,9 @@ #include -namespace resampler { +#include "ResamplerDefinitions.h" + +namespace RESAMPLER_OUTER_NAMESPACE::resampler { /** * Calculate a HyperbolicCosineWindow window centered at 0. @@ -64,5 +66,6 @@ class HyperbolicCosineWindow { double mInverseCoshAlpha = 1.0; }; -} // namespace resampler +} /* namespace RESAMPLER_OUTER_NAMESPACE::resampler */ + #endif //RESAMPLER_HYPERBOLIC_COSINE_WINDOW_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/IntegerRatio.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/IntegerRatio.cpp index 4bd75b391626..39e9b245963d 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/IntegerRatio.cpp +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/IntegerRatio.cpp @@ -16,7 +16,7 @@ #include "IntegerRatio.h" -using namespace resampler; +using namespace RESAMPLER_OUTER_NAMESPACE::resampler; // Enough primes to cover the common sample rates. static const int kPrimes[] = { diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/IntegerRatio.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/IntegerRatio.h index fb390f1007d7..a6b524ce1788 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/IntegerRatio.h +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/IntegerRatio.h @@ -14,12 +14,14 @@ * limitations under the License. */ -#ifndef OBOE_INTEGER_RATIO_H -#define OBOE_INTEGER_RATIO_H +#ifndef RESAMPLER_INTEGER_RATIO_H +#define RESAMPLER_INTEGER_RATIO_H #include -namespace resampler { +#include "ResamplerDefinitions.h" + +namespace RESAMPLER_OUTER_NAMESPACE::resampler { /** * Represent the ratio of two integers. @@ -47,6 +49,6 @@ class IntegerRatio { int32_t mDenominator; }; -} +} /* namespace RESAMPLER_OUTER_NAMESPACE::resampler */ -#endif //OBOE_INTEGER_RATIO_H +#endif //RESAMPLER_INTEGER_RATIO_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/KaiserWindow.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/KaiserWindow.h index 73dbc4178534..f99f9b4df902 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/KaiserWindow.h +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/KaiserWindow.h @@ -19,7 +19,9 @@ #include -namespace resampler { +#include "ResamplerDefinitions.h" + +namespace RESAMPLER_OUTER_NAMESPACE::resampler { /** * Calculate a Kaiser window centered at 0. @@ -83,5 +85,6 @@ class KaiserWindow { double mInverseBesselBeta = 1.0; }; -} // namespace resampler +} /* namespace RESAMPLER_OUTER_NAMESPACE::resampler */ + #endif //RESAMPLER_KAISER_WINDOW_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/LinearResampler.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/LinearResampler.cpp index a7748c10fd9c..cb4932a5f89e 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/LinearResampler.cpp +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/LinearResampler.cpp @@ -16,7 +16,7 @@ #include "LinearResampler.h" -using namespace resampler; +using namespace RESAMPLER_OUTER_NAMESPACE::resampler; LinearResampler::LinearResampler(const MultiChannelResampler::Builder &builder) : MultiChannelResampler(builder) { diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/LinearResampler.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/LinearResampler.h index 5dcc88130dbd..5434379cf98b 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/LinearResampler.h +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/LinearResampler.h @@ -14,22 +14,24 @@ * limitations under the License. */ -#ifndef OBOE_LINEAR_RESAMPLER_H -#define OBOE_LINEAR_RESAMPLER_H +#ifndef RESAMPLER_LINEAR_RESAMPLER_H +#define RESAMPLER_LINEAR_RESAMPLER_H #include #include #include + #include "MultiChannelResampler.h" +#include "ResamplerDefinitions.h" -namespace resampler { +namespace RESAMPLER_OUTER_NAMESPACE::resampler { /** * Simple resampler that uses bi-linear interpolation. */ class LinearResampler : public MultiChannelResampler { public: - LinearResampler(const MultiChannelResampler::Builder &builder); + explicit LinearResampler(const MultiChannelResampler::Builder &builder); void writeFrame(const float *frame) override; @@ -40,5 +42,6 @@ class LinearResampler : public MultiChannelResampler { std::unique_ptr mCurrentFrame; }; -} // namespace resampler -#endif //OBOE_LINEAR_RESAMPLER_H +} /* namespace RESAMPLER_OUTER_NAMESPACE::resampler */ + +#endif //RESAMPLER_LINEAR_RESAMPLER_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/MultiChannelResampler.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/MultiChannelResampler.cpp index d63052077e4e..611ddcd152e3 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/MultiChannelResampler.cpp +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/MultiChannelResampler.cpp @@ -25,11 +25,12 @@ #include "SincResampler.h" #include "SincResamplerStereo.h" -using namespace resampler; +using namespace RESAMPLER_OUTER_NAMESPACE::resampler; MultiChannelResampler::MultiChannelResampler(const MultiChannelResampler::Builder &builder) : mNumTaps(builder.getNumTaps()) - , mX(builder.getChannelCount() * builder.getNumTaps() * 2) + , mX(static_cast(builder.getChannelCount()) + * static_cast(builder.getNumTaps()) * 2) , mSingleFrame(builder.getChannelCount()) , mChannelCount(builder.getChannelCount()) { @@ -39,7 +40,7 @@ MultiChannelResampler::MultiChannelResampler(const MultiChannelResampler::Builde ratio.reduce(); mNumerator = ratio.getNumerator(); mDenominator = ratio.getDenominator(); - mIntegerPhase = mDenominator; + mIntegerPhase = mDenominator; // so we start with a write needed } // static factory method @@ -110,7 +111,7 @@ void MultiChannelResampler::writeFrame(const float *frame) { if (--mCursor < 0) { mCursor = getNumTaps() - 1; } - float *dest = &mX[mCursor * getChannelCount()]; + float *dest = &mX[static_cast(mCursor) * static_cast(getChannelCount())]; int offset = getNumTaps() * getChannelCount(); for (int channel = 0; channel < getChannelCount(); channel++) { // Write twice so we avoid having to wrap when reading. @@ -130,14 +131,13 @@ void MultiChannelResampler::generateCoefficients(int32_t inputRate, int32_t numRows, double phaseIncrement, float normalizedCutoff) { - mCoefficients.resize(getNumTaps() * numRows); + mCoefficients.resize(static_cast(getNumTaps()) * static_cast(numRows)); int coefficientIndex = 0; double phase = 0.0; // ranges from 0.0 to 1.0, fraction between samples // Stretch the sinc function for low pass filtering. - const float cutoffScaler = normalizedCutoff * - ((outputRate < inputRate) - ? ((float)outputRate / inputRate) - : ((float)inputRate / outputRate)); + const float cutoffScaler = (outputRate < inputRate) + ? (normalizedCutoff * (float)outputRate / inputRate) + : 1.0f; // Do not filter when upsampling. const int numTapsHalf = getNumTaps() / 2; // numTaps must be even. const float numTapsHalfInverse = 1.0f / numTapsHalf; for (int i = 0; i < numRows; i++) { @@ -150,7 +150,7 @@ void MultiChannelResampler::generateCoefficients(int32_t inputRate, #if MCR_USE_KAISER float window = mKaiserWindow(tapPhase * numTapsHalfInverse); #else - float window = mCoshWindow(tapPhase * numTapsHalfInverse); + float window = mCoshWindow(static_cast(tapPhase) * numTapsHalfInverse); #endif float coefficient = sinc(radians * cutoffScaler) * window; mCoefficients.at(coefficientIndex++) = coefficient; diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/MultiChannelResampler.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/MultiChannelResampler.h index 8b23d810d43f..9e47335a4950 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/MultiChannelResampler.h +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/MultiChannelResampler.h @@ -14,8 +14,8 @@ * limitations under the License. */ -#ifndef OBOE_MULTICHANNEL_RESAMPLER_H -#define OBOE_MULTICHANNEL_RESAMPLER_H +#ifndef RESAMPLER_MULTICHANNEL_RESAMPLER_H +#define RESAMPLER_MULTICHANNEL_RESAMPLER_H #include #include @@ -34,7 +34,9 @@ #include "HyperbolicCosineWindow.h" #endif -namespace resampler { +#include "ResamplerDefinitions.h" + +namespace RESAMPLER_OUTER_NAMESPACE::resampler { class MultiChannelResampler { @@ -109,6 +111,9 @@ class MultiChannelResampler { * Set lower to reduce aliasing. * Default is 0.70. * + * Note that this value is ignored when upsampling, which is when + * the outputRate is higher than the inputRate. + * * @param normalizedCutoff anti-aliasing filter cutoff * @return address of this builder for chaining calls */ @@ -225,6 +230,10 @@ class MultiChannelResampler { /** * Generate the filter coefficients in optimal order. + * + * Note that normalizedCutoff is ignored when upsampling, which is when + * the outputRate is higher than the inputRate. + * * @param inputRate sample rate of the input stream * @param outputRate sample rate of the output stream * @param numRows number of rows in the array that contain a set of tap coefficients @@ -267,5 +276,6 @@ class MultiChannelResampler { const int mChannelCount; }; -} -#endif //OBOE_MULTICHANNEL_RESAMPLER_H +} /* namespace RESAMPLER_OUTER_NAMESPACE::resampler */ + +#endif //RESAMPLER_MULTICHANNEL_RESAMPLER_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResampler.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResampler.cpp index 163cf7cb1941..c16273b79c37 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResampler.cpp +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResampler.cpp @@ -14,12 +14,13 @@ * limitations under the License. */ +#include // Do NOT delete. Needed for LLVM. See #1746 #include #include #include "IntegerRatio.h" #include "PolyphaseResampler.h" -using namespace resampler; +using namespace RESAMPLER_OUTER_NAMESPACE::resampler; PolyphaseResampler::PolyphaseResampler(const MultiChannelResampler::Builder &builder) : MultiChannelResampler(builder) @@ -40,13 +41,11 @@ void PolyphaseResampler::readFrame(float *frame) { // Clear accumulator for mixing. std::fill(mSingleFrame.begin(), mSingleFrame.end(), 0.0); -// printf("PolyphaseResampler: mCoefficientCursor = %4d\n", mCoefficientCursor); // Multiply input times windowed sinc function. float *coefficients = &mCoefficients[mCoefficientCursor]; - float *xFrame = &mX[mCursor * getChannelCount()]; + float *xFrame = &mX[static_cast(mCursor) * static_cast(getChannelCount())]; for (int i = 0; i < mNumTaps; i++) { float coefficient = *coefficients++; -// printf("PolyphaseResampler: coeff = %10.6f, xFrame[0] = %10.6f\n", coefficient, xFrame[0]); for (int channel = 0; channel < getChannelCount(); channel++) { mSingleFrame[channel] += *xFrame++ * coefficient; } diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResampler.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResampler.h index 52671cd21603..3642fcec49df 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResampler.h +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResampler.h @@ -14,16 +14,18 @@ * limitations under the License. */ -#ifndef OBOE_POLYPHASE_RESAMPLER_H -#define OBOE_POLYPHASE_RESAMPLER_H +#ifndef RESAMPLER_POLYPHASE_RESAMPLER_H +#define RESAMPLER_POLYPHASE_RESAMPLER_H #include #include #include #include + #include "MultiChannelResampler.h" +#include "ResamplerDefinitions.h" -namespace resampler { +namespace RESAMPLER_OUTER_NAMESPACE::resampler { /** * Resampler that is optimized for a reduced ratio of sample rates. * All of the coefficients for each possible phase value are pre-calculated. @@ -46,6 +48,6 @@ class PolyphaseResampler : public MultiChannelResampler { }; -} +} /* namespace RESAMPLER_OUTER_NAMESPACE::resampler */ -#endif //OBOE_POLYPHASE_RESAMPLER_H +#endif //RESAMPLER_POLYPHASE_RESAMPLER_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.cpp index c0e29b7cc473..fdaf13ea6aae 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.cpp +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.cpp @@ -17,7 +17,7 @@ #include #include "PolyphaseResamplerMono.h" -using namespace resampler; +using namespace RESAMPLER_OUTER_NAMESPACE::resampler; #define MONO 1 diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.h index d97b513cfb59..fe020b545340 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.h +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerMono.h @@ -14,14 +14,16 @@ * limitations under the License. */ -#ifndef OBOE_POLYPHASE_RESAMPLER_MONO_H -#define OBOE_POLYPHASE_RESAMPLER_MONO_H +#ifndef RESAMPLER_POLYPHASE_RESAMPLER_MONO_H +#define RESAMPLER_POLYPHASE_RESAMPLER_MONO_H #include #include + #include "PolyphaseResampler.h" +#include "ResamplerDefinitions.h" -namespace resampler { +namespace RESAMPLER_OUTER_NAMESPACE::resampler { class PolyphaseResamplerMono : public PolyphaseResampler { public: @@ -34,6 +36,6 @@ class PolyphaseResamplerMono : public PolyphaseResampler { void readFrame(float *frame) override; }; -} +} /* namespace RESAMPLER_OUTER_NAMESPACE::resampler */ -#endif //OBOE_POLYPHASE_RESAMPLER_MONO_H +#endif //RESAMPLER_POLYPHASE_RESAMPLER_MONO_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.cpp index e4bef7423059..b38185186a9a 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.cpp +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.cpp @@ -17,7 +17,7 @@ #include #include "PolyphaseResamplerStereo.h" -using namespace resampler; +using namespace RESAMPLER_OUTER_NAMESPACE::resampler; #define STEREO 2 diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.h index 3dfd4e2d3f8b..ee4cabaad60d 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.h +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.h @@ -14,14 +14,16 @@ * limitations under the License. */ -#ifndef OBOE_POLYPHASE_RESAMPLER_STEREO_H -#define OBOE_POLYPHASE_RESAMPLER_STEREO_H +#ifndef RESAMPLER_POLYPHASE_RESAMPLER_STEREO_H +#define RESAMPLER_POLYPHASE_RESAMPLER_STEREO_H #include #include + #include "PolyphaseResampler.h" +#include "ResamplerDefinitions.h" -namespace resampler { +namespace RESAMPLER_OUTER_NAMESPACE::resampler { class PolyphaseResamplerStereo : public PolyphaseResampler { public: @@ -34,6 +36,6 @@ class PolyphaseResamplerStereo : public PolyphaseResampler { void readFrame(float *frame) override; }; -} +} /* namespace RESAMPLER_OUTER_NAMESPACE::resampler */ -#endif //OBOE_POLYPHASE_RESAMPLER_STEREO_H +#endif //RESAMPLER_POLYPHASE_RESAMPLER_STEREO_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/README.md b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/README.md new file mode 100644 index 000000000000..356f06c7db99 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/README.md @@ -0,0 +1,101 @@ +# Sample Rate Converter + +This folder contains a sample rate converter, or "resampler". + +The converter is based on a sinc function that has been windowed by a hyperbolic cosine. +We found this had fewer artifacts than the more traditional Kaiser window. + +## Building the Resampler + +It is part of [Oboe](https://github.com/google/oboe) but has no dependencies on Oboe. +So the contents of this folder can be used outside of Oboe. + +To build it for use outside of Oboe: + +1. Copy the "resampler" folder to a folder in your project that is in the include path. +2. Add all of the \*.cpp files in the resampler folder to your project IDE or Makefile. +3. In ResamplerDefinitions.h, define RESAMPLER_OUTER_NAMESPACE with your own project name. Alternatively, use -DRESAMPLER_OUTER_NAMESPACE=mynamespace when compiling to avoid modifying the resampler code. + +## Creating a Resampler + +Include the [main header](MultiChannelResampler.h) for the resampler. + + #include "resampler/MultiChannelResampler.h" + +Here is an example of creating a stereo resampler that will convert from 44100 to 48000 Hz. +Only do this once, when you open your stream. Then use the sample resampler to process multiple buffers. + + MultiChannelResampler *resampler = MultiChannelResampler::make( + 2, // channel count + 44100, // input sampleRate + 48000, // output sampleRate + MultiChannelResampler::Quality::Medium); // conversion quality + +Possible values for quality include { Fastest, Low, Medium, High, Best }. +Higher quality levels will sound better but consume more CPU because they have more taps in the filter. + +## Fractional Frame Counts + +Note that the number of output frames generated for a given number of input frames can vary. + +For example, suppose you are converting from 44100 Hz to 48000 Hz and using an input buffer with 960 frames. If you calculate the number of output frames you get: + + 960.0 * 48000 / 44100 = 1044.897959... + +You cannot generate a fractional number of frames. So the resampler will sometimes generate 1044 frames and sometimes 1045 frames. On average it will generate 1044.897959 frames. The resampler stores the fraction internally and keeps track of when to consume or generate a frame. + +You can either use a fixed number of input frames or a fixed number of output frames. The other frame count will vary. + +## Calling the Resampler with a fixed number of OUTPUT frames + +In this example, suppose we have a fixed number of output frames and a variable number of input frames. + +Assume you start with these variables and a method that returns the next input frame: + + float *outputBuffer; // multi-channel buffer to be filled + int numOutputFrames; // number of frames of output + +The resampler has a method isWriteNeeded() that tells you whether to write to or read from the resampler. + + int outputFramesLeft = numOutputFrames; + while (outputFramesLeft > 0) { + if(resampler->isWriteNeeded()) { + const float *frame = getNextInputFrame(); // you provide this + resampler->writeNextFrame(frame); + } else { + resampler->readNextFrame(outputBuffer); + outputBuffer += channelCount; + outputFramesLeft--; + } + } + +## Calling the Resampler with a fixed number of INPUT frames + +In this example, suppose we have a fixed number of input frames and a variable number of output frames. + +Assume you start with these variables: + + float *inputBuffer; // multi-channel buffer to be consumed + float *outputBuffer; // multi-channel buffer to be filled + int numInputFrames; // number of frames of input + int numOutputFrames = 0; + int channelCount; // 1 for mono, 2 for stereo + + int inputFramesLeft = numInputFrames; + while (inputFramesLeft > 0) { + if(resampler->isWriteNeeded()) { + resampler->writeNextFrame(inputBuffer); + inputBuffer += channelCount; + inputFramesLeft--; + } else { + resampler->readNextFrame(outputBuffer); + outputBuffer += channelCount; + numOutputFrames++; + } + } + +## Deleting the Resampler + +When you are done, you should delete the Resampler to avoid a memory leak. + + delete resampler; diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/ResamplerDefinitions.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/ResamplerDefinitions.h new file mode 100644 index 000000000000..c6791ec93727 --- /dev/null +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/ResamplerDefinitions.h @@ -0,0 +1,27 @@ +/* + * Copyright 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Set flag RESAMPLER_OUTER_NAMESPACE based on whether compiler flag +// __ANDROID_NDK__ is defined. __ANDROID_NDK__ should be defined in oboe +// but not in android. + +#ifndef RESAMPLER_OUTER_NAMESPACE +#ifdef __ANDROID_NDK__ +#define RESAMPLER_OUTER_NAMESPACE oboe +#else +#define RESAMPLER_OUTER_NAMESPACE aaudio +#endif // __ANDROID_NDK__ +#endif // RESAMPLER_OUTER_NAMESPACE diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.cpp index 37582109cb32..919f328a2a84 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.cpp +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.cpp @@ -14,20 +14,21 @@ * limitations under the License. */ +#include // Do NOT delete. Needed for LLVM. See #1746 #include #include #include "SincResampler.h" -using namespace resampler; +using namespace RESAMPLER_OUTER_NAMESPACE::resampler; SincResampler::SincResampler(const MultiChannelResampler::Builder &builder) : MultiChannelResampler(builder) , mSingleFrame2(builder.getChannelCount()) { assert((getNumTaps() % 4) == 0); // Required for loop unrolling. - mNumRows = kMaxCoefficients / getNumTaps(); // no guard row needed -// printf("SincResampler: numRows = %d\n", mNumRows); - mPhaseScaler = (double) mNumRows / mDenominator; - double phaseIncrement = 1.0 / mNumRows; + mNumRows = kMaxCoefficients / getNumTaps(); // includes guard row + const int32_t numRowsNoGuard = mNumRows - 1; + mPhaseScaler = (double) numRowsNoGuard / mDenominator; + const double phaseIncrement = 1.0 / numRowsNoGuard; generateCoefficients(builder.getInputRate(), builder.getOutputRate(), mNumRows, @@ -41,37 +42,31 @@ void SincResampler::readFrame(float *frame) { std::fill(mSingleFrame2.begin(), mSingleFrame2.end(), 0.0); // Determine indices into coefficients table. - double tablePhase = getIntegerPhase() * mPhaseScaler; - int index1 = static_cast(floor(tablePhase)); - if (index1 >= mNumRows) { // no guard row needed because we wrap the indices - tablePhase -= mNumRows; - index1 -= mNumRows; - } - - int index2 = index1 + 1; - if (index2 >= mNumRows) { // no guard row needed because we wrap the indices - index2 -= mNumRows; - } - - float *coefficients1 = &mCoefficients[index1 * getNumTaps()]; - float *coefficients2 = &mCoefficients[index2 * getNumTaps()]; + const double tablePhase = getIntegerPhase() * mPhaseScaler; + const int indexLow = static_cast(floor(tablePhase)); + const int indexHigh = indexLow + 1; // OK because using a guard row. + assert (indexHigh < mNumRows); + float *coefficientsLow = &mCoefficients[static_cast(indexLow) + * static_cast(getNumTaps())]; + float *coefficientsHigh = &mCoefficients[static_cast(indexHigh) + * static_cast(getNumTaps())]; - float *xFrame = &mX[mCursor * getChannelCount()]; - for (int i = 0; i < mNumTaps; i++) { - float coefficient1 = *coefficients1++; - float coefficient2 = *coefficients2++; + float *xFrame = &mX[static_cast(mCursor) * static_cast(getChannelCount())]; + for (int tap = 0; tap < mNumTaps; tap++) { + const float coefficientLow = *coefficientsLow++; + const float coefficientHigh = *coefficientsHigh++; for (int channel = 0; channel < getChannelCount(); channel++) { - float sample = *xFrame++; - mSingleFrame[channel] += sample * coefficient1; - mSingleFrame2[channel] += sample * coefficient2; + const float sample = *xFrame++; + mSingleFrame[channel] += sample * coefficientLow; + mSingleFrame2[channel] += sample * coefficientHigh; } } // Interpolate and copy to output. - float fraction = tablePhase - index1; + const float fraction = tablePhase - indexLow; for (int channel = 0; channel < getChannelCount(); channel++) { - float low = mSingleFrame[channel]; - float high = mSingleFrame2[channel]; + const float low = mSingleFrame[channel]; + const float high = mSingleFrame2[channel]; frame[channel] = low + (fraction * (high - low)); } } diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.h index 6ab61c9637d8..05ff0921cf7d 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.h +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResampler.h @@ -14,15 +14,17 @@ * limitations under the License. */ -#ifndef OBOE_SINC_RESAMPLER_H -#define OBOE_SINC_RESAMPLER_H +#ifndef RESAMPLER_SINC_RESAMPLER_H +#define RESAMPLER_SINC_RESAMPLER_H #include #include #include + #include "MultiChannelResampler.h" +#include "ResamplerDefinitions.h" -namespace resampler { +namespace RESAMPLER_OUTER_NAMESPACE::resampler { /** * Resampler that can interpolate between coefficients. @@ -43,5 +45,6 @@ class SincResampler : public MultiChannelResampler { double mPhaseScaler = 1.0; }; -} -#endif //OBOE_SINC_RESAMPLER_H +} /* namespace RESAMPLER_OUTER_NAMESPACE::resampler */ + +#endif //RESAMPLER_SINC_RESAMPLER_H diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResamplerStereo.cpp b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResamplerStereo.cpp index ce0030220662..f9287baad7bc 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResamplerStereo.cpp +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResamplerStereo.cpp @@ -14,12 +14,13 @@ * limitations under the License. */ +#include // Do NOT delete. Needed for LLVM. See #1746 #include #include #include "SincResamplerStereo.h" -using namespace resampler; +using namespace RESAMPLER_OUTER_NAMESPACE::resampler; #define STEREO 2 @@ -54,13 +55,12 @@ void SincResamplerStereo::readFrame(float *frame) { // Determine indices into coefficients table. double tablePhase = getIntegerPhase() * mPhaseScaler; int index1 = static_cast(floor(tablePhase)); - float *coefficients1 = &mCoefficients[index1 * getNumTaps()]; + float *coefficients1 = &mCoefficients[static_cast(index1) + * static_cast(getNumTaps())]; int index2 = (index1 + 1); - if (index2 >= mNumRows) { // no guard row needed because we wrap the indices - index2 = 0; - } - float *coefficients2 = &mCoefficients[index2 * getNumTaps()]; - float *xFrame = &mX[mCursor * getChannelCount()]; + float *coefficients2 = &mCoefficients[static_cast(index2) + * static_cast(getNumTaps())]; + float *xFrame = &mX[static_cast(mCursor) * static_cast(getChannelCount())]; for (int i = 0; i < mNumTaps; i++) { float coefficient1 = *coefficients1++; float coefficient2 = *coefficients2++; diff --git a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResamplerStereo.h b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResamplerStereo.h index 7d66c26fdb85..d5576d18685c 100644 --- a/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResamplerStereo.h +++ b/modules/juce_audio_devices/native/oboe/src/flowgraph/resampler/SincResamplerStereo.h @@ -14,14 +14,16 @@ * limitations under the License. */ -#ifndef OBOE_SINC_RESAMPLER_STEREO_H -#define OBOE_SINC_RESAMPLER_STEREO_H +#ifndef RESAMPLER_SINC_RESAMPLER_STEREO_H +#define RESAMPLER_SINC_RESAMPLER_STEREO_H #include #include + #include "SincResampler.h" +#include "ResamplerDefinitions.h" -namespace resampler { +namespace RESAMPLER_OUTER_NAMESPACE::resampler { class SincResamplerStereo : public SincResampler { public: @@ -35,5 +37,6 @@ class SincResamplerStereo : public SincResampler { }; -} -#endif //OBOE_SINC_RESAMPLER_STEREO_H +} /* namespace RESAMPLER_OUTER_NAMESPACE::resampler */ + +#endif //RESAMPLER_SINC_RESAMPLER_STEREO_H diff --git a/modules/juce_audio_devices/native/oboe/src/opensles/AudioInputStreamOpenSLES.cpp b/modules/juce_audio_devices/native/oboe/src/opensles/AudioInputStreamOpenSLES.cpp index b07b0ccdda97..3653d964ef02 100644 --- a/modules/juce_audio_devices/native/oboe/src/opensles/AudioInputStreamOpenSLES.cpp +++ b/modules/juce_audio_devices/native/oboe/src/opensles/AudioInputStreamOpenSLES.cpp @@ -19,6 +19,7 @@ #include #include +#include "common/OboeDebug.h" #include "oboe/AudioStreamBuilder.h" #include "AudioInputStreamOpenSLES.h" #include "AudioStreamOpenSLES.h" @@ -98,9 +99,10 @@ Result AudioInputStreamOpenSLES::open() { SLuint32 bitsPerSample = static_cast(getBytesPerSample() * kBitsPerByte); // configure audio sink + mBufferQueueLength = calculateOptimalBufferQueueLength(); SLDataLocator_AndroidSimpleBufferQueue loc_bufq = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, // locatorType - static_cast(kBufferQueueLength)}; // numBuffers + static_cast(mBufferQueueLength)}; // numBuffers // Define the audio data format. SLDataFormat_PCM format_pcm = { @@ -194,27 +196,16 @@ Result AudioInputStreamOpenSLES::open() { goto error; } - result = AudioStreamOpenSLES::registerBufferQueueCallback(); + result = finishCommonOpen(configItf); if (SL_RESULT_SUCCESS != result) { goto error; } - result = updateStreamParameters(configItf); - if (SL_RESULT_SUCCESS != result) { - goto error; - } - - oboeResult = configureBufferSizes(mSampleRate); - if (Result::OK != oboeResult) { - goto error; - } - - allocateFifo(); - setState(StreamState::Open); return Result::OK; error: + close(); // Clean up various OpenSL objects and prevent resource leaks. return Result::ErrorInternal; // TODO convert error from SLES to OBOE } @@ -225,7 +216,10 @@ Result AudioInputStreamOpenSLES::close() { if (getState() == StreamState::Closed){ result = Result::ErrorClosed; } else { - requestStop_l(); + (void) requestStop_l(); + if (OboeGlobals::areWorkaroundsEnabled()) { + sleepBeforeClose(); + } // invalidate any interfaces mRecordInterface = nullptr; result = AudioStreamOpenSLES::close_l(); @@ -238,7 +232,7 @@ Result AudioInputStreamOpenSLES::setRecordState_l(SLuint32 newState) { Result result = Result::OK; if (mRecordInterface == nullptr) { - LOGE("AudioInputStreamOpenSLES::%s() mRecordInterface is null", __func__); + LOGW("AudioInputStreamOpenSLES::%s() mRecordInterface is null", __func__); return Result::ErrorInvalidState; } SLresult slResult = (*mRecordInterface)->SetRecordState(mRecordInterface, newState); @@ -270,12 +264,18 @@ Result AudioInputStreamOpenSLES::requestStart() { setDataCallbackEnabled(true); setState(StreamState::Starting); - Result result = setRecordState_l(SL_RECORDSTATE_RECORDING); - if (result == Result::OK) { - setState(StreamState::Started); + + closePerformanceHint(); + + if (getBufferDepth(mSimpleBufferQueueInterface) == 0) { // Enqueue the first buffer to start the streaming. // This does not call the callback function. enqueueCallbackBuffer(mSimpleBufferQueueInterface); + } + + Result result = setRecordState_l(SL_RECORDSTATE_RECORDING); + if (result == Result::OK) { + setState(StreamState::Started); } else { setState(initialState); } @@ -308,6 +308,7 @@ Result AudioInputStreamOpenSLES::requestStop_l() { case StreamState::Stopping: case StreamState::Stopped: return Result::OK; + case StreamState::Uninitialized: case StreamState::Closed: return Result::ErrorClosed; default: diff --git a/modules/juce_audio_devices/native/oboe/src/opensles/AudioOutputStreamOpenSLES.cpp b/modules/juce_audio_devices/native/oboe/src/opensles/AudioOutputStreamOpenSLES.cpp index 5791b5ec59de..91f9882d5063 100644 --- a/modules/juce_audio_devices/native/oboe/src/opensles/AudioOutputStreamOpenSLES.cpp +++ b/modules/juce_audio_devices/native/oboe/src/opensles/AudioOutputStreamOpenSLES.cpp @@ -20,6 +20,7 @@ #include #include +#include "common/OboeDebug.h" #include "oboe/AudioStreamBuilder.h" #include "AudioOutputStreamOpenSLES.h" #include "AudioStreamOpenSLES.h" @@ -140,9 +141,10 @@ Result AudioOutputStreamOpenSLES::open() { SLuint32 bitsPerSample = static_cast(getBytesPerSample() * kBitsPerByte); // configure audio source + mBufferQueueLength = calculateOptimalBufferQueueLength(); SLDataLocator_AndroidSimpleBufferQueue loc_bufq = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, // locatorType - static_cast(kBufferQueueLength)}; // numBuffers + static_cast(mBufferQueueLength)}; // numBuffers // Define the audio data format. SLDataFormat_PCM format_pcm = { @@ -213,27 +215,16 @@ Result AudioOutputStreamOpenSLES::open() { goto error; } - result = AudioStreamOpenSLES::registerBufferQueueCallback(); + result = finishCommonOpen(configItf); if (SL_RESULT_SUCCESS != result) { goto error; } - result = updateStreamParameters(configItf); - if (SL_RESULT_SUCCESS != result) { - goto error; - } - - oboeResult = configureBufferSizes(mSampleRate); - if (Result::OK != oboeResult) { - goto error; - } - - allocateFifo(); - setState(StreamState::Open); return Result::OK; error: + close(); // Clean up various OpenSL objects and prevent resource leaks. return Result::ErrorInternal; // TODO convert error from SLES to OBOE } @@ -249,7 +240,10 @@ Result AudioOutputStreamOpenSLES::close() { if (getState() == StreamState::Closed){ result = Result::ErrorClosed; } else { - requestPause_l(); + (void) requestPause_l(); + if (OboeGlobals::areWorkaroundsEnabled()) { + sleepBeforeClose(); + } // invalidate any interfaces mPlayInterface = nullptr; result = AudioStreamOpenSLES::close_l(); @@ -297,15 +291,27 @@ Result AudioOutputStreamOpenSLES::requestStart() { setDataCallbackEnabled(true); setState(StreamState::Starting); + closePerformanceHint(); + + if (getBufferDepth(mSimpleBufferQueueInterface) == 0) { + // Enqueue the first buffer if needed to start the streaming. + // We may need to stop the current stream. + bool shouldStopStream = processBufferCallback(mSimpleBufferQueueInterface); + if (shouldStopStream) { + LOGD("Stopping the current stream."); + if (requestStop_l() != Result::OK) { + LOGW("Failed to flush the stream. Error %s", convertToText(flush())); + } + setState(initialState); + mLock.unlock(); + return Result::ErrorClosed; + } + } + Result result = setPlayState_l(SL_PLAYSTATE_PLAYING); if (result == Result::OK) { setState(StreamState::Started); mLock.unlock(); - if (getBufferDepth(mSimpleBufferQueueInterface) == 0) { - // Enqueue the first buffer if needed to start the streaming. - // This might call requestStop() so try to avoid a recursive lock. - processBufferCallback(mSimpleBufferQueueInterface); - } } else { setState(initialState); mLock.unlock(); @@ -326,6 +332,7 @@ Result AudioOutputStreamOpenSLES::requestPause_l() { case StreamState::Pausing: case StreamState::Paused: return Result::OK; + case StreamState::Uninitialized: case StreamState::Closed: return Result::ErrorClosed; default: @@ -375,14 +382,19 @@ Result AudioOutputStreamOpenSLES::requestFlush_l() { } Result AudioOutputStreamOpenSLES::requestStop() { - LOGD("AudioOutputStreamOpenSLES(): %s() called", __func__); std::lock_guard lock(mLock); + return requestStop_l(); +} + +Result AudioOutputStreamOpenSLES::requestStop_l() { + LOGD("AudioOutputStreamOpenSLES(): %s() called", __func__); StreamState initialState = getState(); switch (initialState) { case StreamState::Stopping: case StreamState::Stopped: return Result::OK; + case StreamState::Uninitialized: case StreamState::Closed: return Result::ErrorClosed; default: diff --git a/modules/juce_audio_devices/native/oboe/src/opensles/AudioOutputStreamOpenSLES.h b/modules/juce_audio_devices/native/oboe/src/opensles/AudioOutputStreamOpenSLES.h index ed11eb9b9d54..fc57fd374f81 100644 --- a/modules/juce_audio_devices/native/oboe/src/opensles/AudioOutputStreamOpenSLES.h +++ b/modules/juce_audio_devices/native/oboe/src/opensles/AudioOutputStreamOpenSLES.h @@ -61,6 +61,8 @@ class AudioOutputStreamOpenSLES : public AudioStreamOpenSLES { Result requestFlush_l(); + Result requestStop_l(); + /** * Set OpenSL ES PLAYSTATE. * diff --git a/modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamBuffered.cpp b/modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamBuffered.cpp index 298c1eb8115c..9737b72bb9c6 100644 --- a/modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamBuffered.cpp +++ b/modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamBuffered.cpp @@ -18,6 +18,7 @@ #include "oboe/Oboe.h" +#include "common/OboeDebug.h" #include "opensles/AudioStreamBuffered.h" #include "common/AudioClock.h" @@ -54,9 +55,10 @@ void AudioStreamBuffered::allocateFifo() { capacityFrames = numBursts * getFramesPerBurst(); } } - // TODO consider using std::make_unique if we require c++14 - mFifoBuffer.reset(new FifoBuffer(getBytesPerFrame(), capacityFrames)); + + mFifoBuffer = std::make_unique(getBytesPerFrame(), capacityFrames); mBufferCapacityInFrames = capacityFrames; + mBufferSizeInFrames = mBufferCapacityInFrames; } } @@ -280,4 +282,4 @@ bool AudioStreamBuffered::isXRunCountSupported() const { return (!isDataCallbackSpecified()); } -} // namespace oboe \ No newline at end of file +} // namespace oboe diff --git a/modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamBuffered.h b/modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamBuffered.h index be5d607e3061..3080ce610598 100644 --- a/modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamBuffered.h +++ b/modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamBuffered.h @@ -22,7 +22,7 @@ #include "common/OboeDebug.h" #include "oboe/AudioStream.h" #include "oboe/AudioStreamCallback.h" -#include "fifo/FifoBuffer.h" +#include "oboe/FifoBuffer.h" namespace oboe { diff --git a/modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamOpenSLES.cpp b/modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamOpenSLES.cpp index b99568ae6caf..9013d61c551c 100644 --- a/modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamOpenSLES.cpp +++ b/modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamOpenSLES.cpp @@ -16,7 +16,6 @@ #include #include - #include #include #include @@ -71,6 +70,13 @@ Result AudioStreamOpenSLES::open() { LOGI("AudioStreamOpenSLES::open() chans=%d, rate=%d", mChannelCount, mSampleRate); + // OpenSL ES only supports I16 and Float + if (mFormat != AudioFormat::I16 && mFormat != AudioFormat::Float) { + LOGW("%s() Android's OpenSL ES implementation only supports I16 and Float. Format: %d", + __func__, mFormat); + return Result::ErrorInvalidFormat; + } + SLresult result = EngineOpenSLES::getInstance().open(); if (SL_RESULT_SUCCESS != result) { return Result::ErrorInternal; @@ -78,6 +84,7 @@ Result AudioStreamOpenSLES::open() { Result oboeResult = AudioStreamBuffered::open(); if (oboeResult != Result::OK) { + EngineOpenSLES::getInstance().close(); return oboeResult; } // Convert to defaults if UNSPECIFIED @@ -87,41 +94,109 @@ Result AudioStreamOpenSLES::open() { if (mChannelCount == kUnspecified) { mChannelCount = DefaultStreamValues::ChannelCount; } + if (mContentType == kUnspecified) { + mContentType = ContentType::Music; + } + if (static_cast(mUsage) == kUnspecified) { + mUsage = Usage::Media; + } mSharingMode = SharingMode::Shared; return Result::OK; } -Result AudioStreamOpenSLES::configureBufferSizes(int32_t sampleRate) { - LOGD("AudioStreamOpenSLES:%s(%d) initial mFramesPerBurst = %d, mFramesPerCallback = %d", - __func__, sampleRate, mFramesPerBurst, mFramesPerCallback); - // Decide frames per burst based on hints from caller. - if (mFramesPerCallback != kUnspecified) { - // Requested framesPerCallback must be honored. - mFramesPerBurst = mFramesPerCallback; - } else { - mFramesPerBurst = DefaultStreamValues::FramesPerBurst; - // Calculate the size of a fixed duration high latency buffer based on sample rate. - int32_t framesPerHighLatencyBuffer = - (kHighLatencyBufferSizeMillis * sampleRate) / kMillisPerSecond; +SLresult AudioStreamOpenSLES::finishCommonOpen(SLAndroidConfigurationItf configItf) { + // Setting privacy sensitive mode and allowed capture policy are not supported for OpenSL ES. + mPrivacySensitiveMode = PrivacySensitiveMode::Unspecified; + mAllowedCapturePolicy = AllowedCapturePolicy::Unspecified; + + // Spatialization Behavior is not supported for OpenSL ES. + mSpatializationBehavior = SpatializationBehavior::Never; + + SLresult result = registerBufferQueueCallback(); + if (SL_RESULT_SUCCESS != result) { + return result; + } + + result = updateStreamParameters(configItf); + if (SL_RESULT_SUCCESS != result) { + return result; + } + + Result oboeResult = configureBufferSizes(mSampleRate); + if (Result::OK != oboeResult) { + return (SLresult) oboeResult; + } + + allocateFifo(); + + calculateDefaultDelayBeforeCloseMillis(); + + return SL_RESULT_SUCCESS; +} + +static int32_t roundUpDivideByN(int32_t x, int32_t n) { + return (x + n - 1) / n; +} - // For high latency streams, use a larger buffer size. - // Performance Mode support was added in N_MR1 (7.1) - if (getSdkVersion() >= __ANDROID_API_N_MR1__ +int32_t AudioStreamOpenSLES::calculateOptimalBufferQueueLength() { + int32_t queueLength = kBufferQueueLengthDefault; + int32_t likelyFramesPerBurst = estimateNativeFramesPerBurst(); + int32_t minCapacity = mBufferCapacityInFrames; // specified by app or zero + // The buffer capacity needs to be at least twice the size of the requested callbackSize + // so that we can have double buffering. + minCapacity = std::max(minCapacity, kDoubleBufferCount * mFramesPerCallback); + if (minCapacity > 0) { + int32_t queueLengthFromCapacity = roundUpDivideByN(minCapacity, likelyFramesPerBurst); + queueLength = std::max(queueLength, queueLengthFromCapacity); + } + queueLength = std::min(queueLength, kBufferQueueLengthMax); // clip to max + // TODO Investigate the effect of queueLength on latency for normal streams. (not low latency) + return queueLength; +} + +/** + * The best information we have is if DefaultStreamValues::FramesPerBurst + * was set by the app based on AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER. + * Without that we just have to guess. + * @return + */ +int32_t AudioStreamOpenSLES::estimateNativeFramesPerBurst() { + int32_t framesPerBurst = DefaultStreamValues::FramesPerBurst; + LOGD("AudioStreamOpenSLES:%s() DefaultStreamValues::FramesPerBurst = %d", + __func__, DefaultStreamValues::FramesPerBurst); + framesPerBurst = std::max(framesPerBurst, 16); + // Calculate the size of a fixed duration high latency buffer based on sample rate. + // Estimate sample based on default options in order of priority. + int32_t sampleRate = 48000; + sampleRate = (DefaultStreamValues::SampleRate > 0) + ? DefaultStreamValues::SampleRate : sampleRate; + sampleRate = (mSampleRate > 0) ? mSampleRate : sampleRate; + int32_t framesPerHighLatencyBuffer = + (kHighLatencyBufferSizeMillis * sampleRate) / kMillisPerSecond; + // For high latency streams, use a larger buffer size. + // Performance Mode support was added in N_MR1 (7.1) + if (getSdkVersion() >= __ANDROID_API_N_MR1__ && mPerformanceMode != PerformanceMode::LowLatency - && mFramesPerBurst < framesPerHighLatencyBuffer) { - // Find a multiple of framesPerBurst >= framesPerHighLatencyBuffer. - int32_t numBursts = (framesPerHighLatencyBuffer + mFramesPerBurst - 1) / mFramesPerBurst; - mFramesPerBurst *= numBursts; - LOGD("AudioStreamOpenSLES:%s() NOT low latency, set mFramesPerBurst = %d", - __func__, mFramesPerBurst); - } - mFramesPerCallback = mFramesPerBurst; + && framesPerBurst < framesPerHighLatencyBuffer) { + // Find a multiple of framesPerBurst >= framesPerHighLatencyBuffer. + int32_t numBursts = roundUpDivideByN(framesPerHighLatencyBuffer, framesPerBurst); + framesPerBurst *= numBursts; + LOGD("AudioStreamOpenSLES:%s() NOT low latency, numBursts = %d, mSampleRate = %d, set framesPerBurst = %d", + __func__, numBursts, mSampleRate, framesPerBurst); } + return framesPerBurst; +} + +Result AudioStreamOpenSLES::configureBufferSizes(int32_t sampleRate) { + LOGD("AudioStreamOpenSLES:%s(%d) initial mFramesPerBurst = %d, mFramesPerCallback = %d", + __func__, mSampleRate, mFramesPerBurst, mFramesPerCallback); + mFramesPerBurst = estimateNativeFramesPerBurst(); + mFramesPerCallback = (mFramesPerCallback > 0) ? mFramesPerCallback : mFramesPerBurst; LOGD("AudioStreamOpenSLES:%s(%d) final mFramesPerBurst = %d, mFramesPerCallback = %d", - __func__, sampleRate, mFramesPerBurst, mFramesPerCallback); + __func__, mSampleRate, mFramesPerBurst, mFramesPerCallback); mBytesPerCallback = mFramesPerCallback * getBytesPerFrame(); if (mBytesPerCallback <= 0) { @@ -130,10 +205,12 @@ Result AudioStreamOpenSLES::configureBufferSizes(int32_t sampleRate) { return Result::ErrorInvalidFormat; // causing bytesPerFrame == 0 } - mCallbackBuffer = std::make_unique(mBytesPerCallback); + for (int i = 0; i < mBufferQueueLength; ++i) { + mCallbackBuffer[i] = std::make_unique(mBytesPerCallback); + } if (!usingFIFO()) { - mBufferCapacityInFrames = mFramesPerBurst * kBufferQueueLength; + mBufferCapacityInFrames = mFramesPerBurst * mBufferQueueLength; // Check for overflow. if (mBufferCapacityInFrames <= 0) { mBufferCapacityInFrames = 0; @@ -215,6 +292,24 @@ void AudioStreamOpenSLES::logUnsupportedAttributes() { LOGW("SessionId [AudioStreamBuilder::setSessionId()] " "is not supported on OpenSLES streams."); } + + // Privacy Sensitive Mode + if (mPrivacySensitiveMode != PrivacySensitiveMode::Unspecified) { + LOGW("PrivacySensitiveMode [AudioStreamBuilder::setPrivacySensitiveMode()] " + "is not supported on OpenSLES streams."); + } + + // Spatialization Behavior + if (mSpatializationBehavior != SpatializationBehavior::Unspecified) { + LOGW("SpatializationBehavior [AudioStreamBuilder::setSpatializationBehavior()] " + "is not supported on OpenSLES streams."); + } + + // Allowed Capture Policy + if (mAllowedCapturePolicy != AllowedCapturePolicy::Unspecified) { + LOGW("AllowedCapturePolicy [AudioStreamBuilder::setAllowedCapturePolicy()] " + "is not supported on OpenSLES streams."); + } } SLresult AudioStreamOpenSLES::configurePerformanceMode(SLAndroidConfigurationItf configItf) { @@ -288,11 +383,15 @@ Result AudioStreamOpenSLES::close_l() { EngineOpenSLES::getInstance().close(); setState(StreamState::Closed); + return Result::OK; } SLresult AudioStreamOpenSLES::enqueueCallbackBuffer(SLAndroidSimpleBufferQueueItf bq) { - return (*bq)->Enqueue(bq, mCallbackBuffer.get(), mBytesPerCallback); + SLresult result = (*bq)->Enqueue( + bq, mCallbackBuffer[mCallbackBufferIndex].get(), mBytesPerCallback); + mCallbackBufferIndex = (mCallbackBufferIndex + 1) % mBufferQueueLength; + return result; } int32_t AudioStreamOpenSLES::getBufferDepth(SLAndroidSimpleBufferQueueItf bq) { @@ -301,16 +400,17 @@ int32_t AudioStreamOpenSLES::getBufferDepth(SLAndroidSimpleBufferQueueItf bq) { return (result == SL_RESULT_SUCCESS) ? queueState.count : -1; } -void AudioStreamOpenSLES::processBufferCallback(SLAndroidSimpleBufferQueueItf bq) { - bool stopStream = false; +bool AudioStreamOpenSLES::processBufferCallback(SLAndroidSimpleBufferQueueItf bq) { + bool shouldStopStream = false; // Ask the app callback to process the buffer. - DataCallbackResult result = fireDataCallback(mCallbackBuffer.get(), mFramesPerCallback); + DataCallbackResult result = + fireDataCallback(mCallbackBuffer[mCallbackBufferIndex].get(), mFramesPerCallback); if (result == DataCallbackResult::Continue) { // Pass the buffer to OpenSLES. SLresult enqueueResult = enqueueCallbackBuffer(bq); if (enqueueResult != SL_RESULT_SUCCESS) { LOGE("%s() returned %d", __func__, enqueueResult); - stopStream = true; + shouldStopStream = true; } // Update Oboe client position with frames handled by the callback. if (getDirection() == Direction::Input) { @@ -320,19 +420,24 @@ void AudioStreamOpenSLES::processBufferCallback(SLAndroidSimpleBufferQueueItf bq } } else if (result == DataCallbackResult::Stop) { LOGD("Oboe callback returned Stop"); - stopStream = true; + shouldStopStream = true; } else { LOGW("Oboe callback returned unexpected value = %d", result); - stopStream = true; + shouldStopStream = true; } - if (stopStream) { - requestStop(); + if (shouldStopStream) { + mCallbackBufferIndex = 0; } + return shouldStopStream; } // This callback handler is called every time a buffer has been processed by OpenSL ES. static void bqCallbackGlue(SLAndroidSimpleBufferQueueItf bq, void *context) { - (reinterpret_cast(context))->processBufferCallback(bq); + bool shouldStopStream = (reinterpret_cast(context)) + ->processBufferCallback(bq); + if (shouldStopStream) { + (reinterpret_cast(context))->requestStop(); + } } SLresult AudioStreamOpenSLES::registerBufferQueueCallback() { diff --git a/modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamOpenSLES.h b/modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamOpenSLES.h index ebed3e5466b7..0164b839ac4a 100644 --- a/modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamOpenSLES.h +++ b/modules/juce_audio_devices/native/oboe/src/opensles/AudioStreamOpenSLES.h @@ -30,7 +30,8 @@ namespace oboe { constexpr int kBitsPerByte = 8; -constexpr int kBufferQueueLength = 2; // double buffered for callbacks +constexpr int kBufferQueueLengthDefault = 2; // double buffered for callbacks +constexpr int kBufferQueueLengthMax = 8; // AudioFlinger won't use more than 8 /** * INTERNAL USE ONLY @@ -67,8 +68,10 @@ class AudioStreamOpenSLES : public AudioStreamBuffered { * Called by by OpenSL ES framework. * * This is public, but don't call it directly. + * + * @return whether the current stream should be stopped. */ - void processBufferCallback(SLAndroidSimpleBufferQueueItf bq); + bool processBufferCallback(SLAndroidSimpleBufferQueueItf bq); Result waitForStateChange(StreamState currentState, StreamState *nextState, @@ -76,6 +79,14 @@ class AudioStreamOpenSLES : public AudioStreamBuffered { protected: + /** + * Finish setting up the stream. Common for INPUT and OUTPUT. + * + * @param configItf + * @return SL_RESULT_SUCCESS if OK. + */ + SLresult finishCommonOpen(SLAndroidConfigurationItf configItf); + // This must be called under mLock. Result close_l(); @@ -86,21 +97,18 @@ class AudioStreamOpenSLES : public AudioStreamBuffered { static SLuint32 getDefaultByteOrder(); - SLresult registerBufferQueueCallback(); - int32_t getBufferDepth(SLAndroidSimpleBufferQueueItf bq); + int32_t calculateOptimalBufferQueueLength(); + int32_t estimateNativeFramesPerBurst(); + SLresult enqueueCallbackBuffer(SLAndroidSimpleBufferQueueItf bq); SLresult configurePerformanceMode(SLAndroidConfigurationItf configItf); - SLresult updateStreamParameters(SLAndroidConfigurationItf configItf); - PerformanceMode convertPerformanceMode(SLuint32 openslMode) const; SLuint32 convertPerformanceMode(PerformanceMode oboeMode) const; - Result configureBufferSizes(int32_t sampleRate); - void logUnsupportedAttributes(); /** @@ -116,12 +124,21 @@ class AudioStreamOpenSLES : public AudioStreamBuffered { // OpenSLES stuff SLObjectItf mObjectInterface = nullptr; SLAndroidSimpleBufferQueueItf mSimpleBufferQueueInterface = nullptr; + int mBufferQueueLength = 0; int32_t mBytesPerCallback = oboe::kUnspecified; MonotonicCounter mPositionMillis; // for tracking OpenSL ES service position private: - std::unique_ptr mCallbackBuffer; + + constexpr static int kDoubleBufferCount = 2; + + SLresult registerBufferQueueCallback(); + SLresult updateStreamParameters(SLAndroidConfigurationItf configItf); + Result configureBufferSizes(int32_t sampleRate); + + std::unique_ptr mCallbackBuffer[kBufferQueueLengthMax]; + int mCallbackBufferIndex = 0; std::atomic mState{StreamState::Uninitialized}; }; diff --git a/modules/juce_audio_devices/native/oboe/src/opensles/EngineOpenSLES.cpp b/modules/juce_audio_devices/native/oboe/src/opensles/EngineOpenSLES.cpp index d82219ee09d4..e1007d10861c 100644 --- a/modules/juce_audio_devices/native/oboe/src/opensles/EngineOpenSLES.cpp +++ b/modules/juce_audio_devices/native/oboe/src/opensles/EngineOpenSLES.cpp @@ -14,12 +14,47 @@ * limitations under the License. */ +#include #include "common/OboeDebug.h" #include "EngineOpenSLES.h" #include "OpenSLESUtilities.h" using namespace oboe; +// OpenSL ES is deprecated in SDK 30. +// So we use custom dynamic linking to access the library. +#define LIB_OPENSLES_NAME "libOpenSLES.so" +typedef SLresult (*prototype_slCreateEngine)( + SLObjectItf *pEngine, + SLuint32 numOptions, + const SLEngineOption *pEngineOptions, + SLuint32 numInterfaces, + const SLInterfaceID *pInterfaceIds, + const SLboolean *pInterfaceRequired +); +static prototype_slCreateEngine gFunction_slCreateEngine = nullptr; +static void *gLibOpenSlesLibraryHandle = nullptr; + +// Load the OpenSL ES library and the one primary entry point. +// @return true if linked OK +static bool linkOpenSLES() { + if (gLibOpenSlesLibraryHandle == nullptr && gFunction_slCreateEngine == nullptr) { + // Use RTLD_NOW to avoid the unpredictable behavior that RTLD_LAZY can cause. + // Also resolving all the links now will prevent a run-time penalty later. + gLibOpenSlesLibraryHandle = dlopen(LIB_OPENSLES_NAME, RTLD_NOW); + if (gLibOpenSlesLibraryHandle == nullptr) { + LOGE("linkOpenSLES() could not find " LIB_OPENSLES_NAME); + } else { + gFunction_slCreateEngine = (prototype_slCreateEngine) dlsym( + gLibOpenSlesLibraryHandle, + "slCreateEngine"); + LOGD("linkOpenSLES(): dlsym(%s) returned %p", "slCreateEngine", + gFunction_slCreateEngine); + } + } + return gFunction_slCreateEngine != nullptr; +} + EngineOpenSLES &EngineOpenSLES::getInstance() { static EngineOpenSLES sInstance; return sInstance; @@ -30,9 +65,14 @@ SLresult EngineOpenSLES::open() { SLresult result = SL_RESULT_SUCCESS; if (mOpenCount++ == 0) { + // load the library and link to it + if (!linkOpenSLES()) { + result = SL_RESULT_FEATURE_UNSUPPORTED; + goto error; + }; // create engine - result = slCreateEngine(&mEngineObject, 0, NULL, 0, NULL, NULL); + result = (*gFunction_slCreateEngine)(&mEngineObject, 0, NULL, 0, NULL, NULL); if (SL_RESULT_SUCCESS != result) { LOGE("EngineOpenSLES - slCreateEngine() result:%s", getSLErrStr(result)); goto error; diff --git a/modules/juce_audio_devices/native/oboe/src/opensles/OpenSLESUtilities.cpp b/modules/juce_audio_devices/native/oboe/src/opensles/OpenSLESUtilities.cpp index 6d25e79fdbd6..534f641cb496 100644 --- a/modules/juce_audio_devices/native/oboe/src/opensles/OpenSLESUtilities.cpp +++ b/modules/juce_audio_devices/native/oboe/src/opensles/OpenSLESUtilities.cpp @@ -85,6 +85,7 @@ SLuint32 OpenSLES_ConvertFormatToRepresentation(AudioFormat format) { return SL_ANDROID_PCM_REPRESENTATION_FLOAT; case AudioFormat::I24: case AudioFormat::I32: + case AudioFormat::IEC61937: case AudioFormat::Invalid: case AudioFormat::Unspecified: default: diff --git a/modules/juce_audio_formats/codecs/flac/Flac Licence.txt b/modules/juce_audio_formats/codecs/flac/Flac Licence.txt index 1bb5807e9458..6ca17228ad24 100644 --- a/modules/juce_audio_formats/codecs/flac/Flac Licence.txt +++ b/modules/juce_audio_formats/codecs/flac/Flac Licence.txt @@ -20,8 +20,8 @@ distribution, visit the Flac homepage: https://xiph.org/flac/ ===================================================================== libFLAC - Free Lossless Audio Codec library -Copyright (C) 2001-2009 Josh Coalson -Copyright (C) 2011-2016 Xiph.Org Foundation +Copyright (C) 2000-2009 Josh Coalson +Copyright (C) 2011-2023 Xiph.Org Foundation Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -34,7 +34,7 @@ notice, this list of conditions and the following disclaimer. notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -- Neither the name of the Xiph.org Foundation nor the names of its +- Neither the name of the Xiph.Org Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. diff --git a/modules/juce_audio_formats/codecs/flac/JUCE_CHANGES.txt b/modules/juce_audio_formats/codecs/flac/JUCE_CHANGES.txt new file mode 100644 index 000000000000..805d9ba21f4c --- /dev/null +++ b/modules/juce_audio_formats/codecs/flac/JUCE_CHANGES.txt @@ -0,0 +1,55 @@ +The files in this directory are from the FLAC 1.4.3 release downloaded in a tarball from +https://github.com/xiph/flac/releases/tag/1.4.3 + +They have been modified as little as possible, so that when they are included by +juce_FlacAudioFormat.cpp they compile without warnings and work correctly on the supported +platforms. + +Below I will refer to the contents of the tarball as RELEASE and to our repo as JUCE. + +The steps carried out when including the 1.4.3 version +* The contents of RELEASE/include/FLAC and RELEASE/include/share were copied to + JUCE/[..]/codecs/flac +* The contents of RELEASE/libFLAC were copied to JUCE/[..]/codecs/flac/libFLAC +* The includes in all these files were retargeted, to be relative to the file that does the + including, so that we don't have to rely on e.g. flac/libFLAC/include being among the include + directories, like it is when building FLAC with the official makefiles. All this retargeting is + done per-line with a Python script. All the rules used for the retargeting can be seen in the code + excerpt at [1]. +* Then I will do a compile/test/modify loop, until it works and compiles without warnings. The + changes made are mostly C to C++ conversions like adding explicit casts, or fixing warnings, like + eliminating always true branches that refer to preprocessor defines. +* Then I delete all library files, and only re-add those that are needed for successful compilation. + This delete step is propagated back to older commits, so that unneeded files are never added to + the GIT repo. + + +[1]: Code excerpt used for retargeting includes in the copied files +``` +def transform(path: Path, line: str) -> str: + if path.match("libFLAC/*"): + line = line.replace('#include "private', '#include "include/private') + line = line.replace('#include "protected', '#include "include/protected') + line = line.replace('#include "share/', '#include "../') + line = line.replace('#include "FLAC/', '#include "../') + + if path.match("libFLAC/include/private/*") or path.match( + "libFLAC/include/public/*" + ): + line = line.replace('#include "share/', '#include "../../../') + line = line.replace('#include "FLAC/', '#include "../../../') + + if path.match("*"): + line = line.replace('#include "share/', '#include "') + + if path.match("libFLAC/include/private/*"): + line = line.replace('#include "private/', '#include "') + + if path.match("libFLAC/include/protected/*"): + line = line.replace('#include "private/', '#include "../private/') + line = line.replace('#include "FLAC/', '#include "../../../') + + line = line.replace('#include "include/private/macros.h"', "") + + return line +``` diff --git a/modules/juce_audio_formats/codecs/flac/all.h b/modules/juce_audio_formats/codecs/flac/all.h index 161b9a85bdaf..03617ece45e5 100644 --- a/modules/juce_audio_formats/codecs/flac/all.h +++ b/modules/juce_audio_formats/codecs/flac/all.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -56,7 +56,7 @@ * level idea of the structure and how to find the information you * need. As a prerequisite you should have at least a basic * knowledge of the FLAC format, documented - * here. + * here. * * \section c_api FLAC C API * @@ -68,7 +68,7 @@ * * By writing a little code and linking against libFLAC, it is * relatively easy to add FLAC support to another program. The - * library is licensed under Xiph's BSD license. + * library is licensed under Xiph's BSD license. * Complete source code of libFLAC as well as the command-line * encoder and plugins is available and is a useful source of * examples. @@ -101,7 +101,7 @@ * example /usr/include/FLAC++/...). * * libFLAC++ is also licensed under - * Xiph's BSD license. + * Xiph's BSD license. * * \section getting_started Getting Started * @@ -117,7 +117,7 @@ * functions through the links in top bar across this page. * * If you prefer a more hands-on approach, you can jump right to some - * example code. + * example code. * * \section porting_guide Porting Guide * @@ -361,6 +361,85 @@ * \c FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN */ +/** \defgroup porting_1_3_4_to_1_4_0 Porting from FLAC 1.3.4 to 1.4.0 + * \ingroup porting + * + * \brief + * This module describes porting from FLAC 1.3.4 to FLAC 1.4.0. + * + * \section porting_1_3_4_to_1_4_0_summary Summary + * + * Between FLAC 1.3.4 and FLAC 1.4.0, there have four breaking changes + * - the function get_client_data_from_decoder has been renamed to + * FLAC__get_decoder_client_data + * - some data types in the FLAC__Frame struct have changed + * - all functions resizing metadata blocks now return the object + * untouched if memory allocation fails, whereas previously the + * handling varied and was more or less undefined + * - all functions accepting a filename now take UTF-8 encoded filenames + * on Windows instead of filenames in the current codepage + * + * Furthermore, there have been the following additions + * - the functions FLAC__stream_encoder_set_limit_min_bitrate, + * FLAC__stream_encoder_get_limit_min_bitrate, + * FLAC::encoder::file::set_limit_min_bitrate() and + * FLAC::encoder::file::get_limit_min_bitrate() have been added + * - Added FLAC__STREAM_DECODER_ERROR_STATUS_BAD_METADATA to the + * FLAC__StreamDecoderErrorStatus enum + * + * \section porting_1_3_4_to_1_4_0_breaking Breaking changes + * + * The function \b get_client_data_from_decoder was added in FLAC 1.3.3 + * but did not follow the API naming convention and was not properly + * exported. The function is now renamed and properly integrated as + * FLAC__stream_decoder_get_client_data + * + * To accomodate encoding and decoding 32-bit int PCM, some data types + * in the \b FLAC__frame struct were changed. Specifically, warmup + * in both the FLAC__Subframe_Fixed struc and the FLAC__Subframe_LPC + * struct is changed from FLAC__int32 to FLAC__int64. Also, value + * in the FLAC__Subframe_Constant is changed from FLAC__int32 to + * FLAC__int64. Finally, in FLAC__Subframe_Verbatim struct data is + * changes from a FLAC__int32 array to a union containing a FLAC__int32 + * array and a FLAC__int64 array. Also, a new member is added, + * data_type, which clarifies whether the FLAC__int32 or FLAC__int64 + * array is in use. + * + * Furthermore, the following functions now return the object untouched + * if memory allocation fails, whereas previously the handling varied + * and was more or less undefined + * + * - FLAC__metadata_object_seektable_resize_points + * - FLAC__metadata_object_vorbiscomment_resize_comments + * - FLAC__metadata_object_cuesheet_track_resize_indices + * - FLAC__metadata_object_cuesheet_resize_tracks + * + * The last breaking change is that all API functions taking a filename + * as an argument now, on Windows, must be supplied with that filename + * in the UTF-8 character encoding instead of using the current code + * page. libFLAC internally translates these UTF-8 encoded filenames to + * an appropriate representation to use with _wfopen. On all other + * systems, filename is passed to fopen without any translation, as it + * in libFLAC 1.3.4 and earlier. + * + * \section porting_1_3_4_to_1_4_0_additions Additions + * + * To aid in creating properly streamable FLAC files, a set of functions + * was added to make it possible to enfore a minimum bitrate to files + * created through libFLAC's stream_encoder.h interface. With this + * function enabled the resulting FLAC files have a minimum bitrate of + * 1bit/sample independent of the number of channels, i.e. 48kbit/s for + * 48kHz. This can be beneficial for streaming, as very low bitrates for + * silent sections compressed with 'constant' subframes can result in a + * bitrate of 1kbit/s, creating problems with clients that aren't aware + * of this possibility and buffer too much data. + * + * Finally, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_METADATA was added to + * the FLAC__StreamDecoderErrorStatus enum to signal that the decoder + * encountered unreadable metadata. + * + */ + /** \defgroup flac FLAC C API * * The FLAC C API is the interface to libFLAC, a set of structures diff --git a/modules/juce_audio_formats/codecs/flac/alloc.h b/modules/juce_audio_formats/codecs/flac/alloc.h index 81c1fbcd2d17..8e89e9b82055 100644 --- a/modules/juce_audio_formats/codecs/flac/alloc.h +++ b/modules/juce_audio_formats/codecs/flac/alloc.h @@ -1,6 +1,6 @@ /* alloc - Convenience routines for safely allocating memory * Copyright (C) 2007-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -66,19 +66,58 @@ # define SIZE_MAX SIZE_T_MAX #endif +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION +extern int alloc_check_threshold, alloc_check_counter; + +static inline int alloc_check() { + if(alloc_check_threshold == INT32_MAX) + return 0; + else if(alloc_check_counter++ == alloc_check_threshold) + return 1; + else + return 0; +} + +#endif + /* avoid malloc()ing 0 bytes, see: * https://www.securecoding.cert.org/confluence/display/seccode/MEM04-A.+Do+not+make+assumptions+about+the+result+of+allocating+0+bytes?focusedCommentId=5407003 */ + static inline void *safe_malloc_(size_t size) { +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + /* Fail if requested */ + if(alloc_check()) + return NULL; +#endif /* malloc(0) is undefined; FLAC src convention is to always allocate */ if(!size) size++; return malloc(size); } +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION +static inline void *malloc_(size_t size) +{ + /* Fail if requested */ + if(alloc_check()) + return NULL; + return malloc(size); +} +#else +#define malloc_ malloc +#endif + + + static inline void *safe_calloc_(size_t nmemb, size_t size) { +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + /* Fail if requested */ + if(alloc_check()) + return NULL; +#endif if(!nmemb || !size) return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ return calloc(nmemb, size); @@ -130,7 +169,7 @@ static inline void *safe_malloc_mul_3op_(size_t size1, size_t size2, size_t size size1 *= size2; if(size1 > SIZE_MAX / size3) return 0; - return malloc(size1*size3); + return malloc_(size1*size3); } /* size1*size2 + size3 */ @@ -153,28 +192,64 @@ static inline void *safe_malloc_muladd2_(size_t size1, size_t size2, size_t size return 0; if(size1 > SIZE_MAX / size2) return 0; - return malloc(size1*size2); + return malloc_(size1*size2); } static inline void *safe_realloc_(void *ptr, size_t size) { - void *oldptr = ptr; - void *newptr = realloc(ptr, size); + void *oldptr; + void *newptr; +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + /* Fail if requested */ + if(alloc_check() && size > 0) { + free(ptr); + return NULL; + } +#endif + oldptr = ptr; + newptr = realloc(ptr, size); if(size > 0 && newptr == 0) free(oldptr); return newptr; } -static inline void *safe_realloc_add_2op_(void *ptr, size_t size1, size_t size2) + +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION +static inline void *realloc_(void *ptr, size_t size) +{ + /* Fail if requested */ + if(alloc_check()) + return NULL; + return realloc(ptr, size); +} +#else +#define realloc_ realloc +#endif + + +static inline void *safe_realloc_nofree_add_2op_(void *ptr, size_t size1, size_t size2) +{ + size2 += size1; + if(size2 < size1) + return 0; + return realloc_(ptr, size2); +} + +static inline void *safe_realloc_add_3op_(void *ptr, size_t size1, size_t size2, size_t size3) { size2 += size1; if(size2 < size1) { free(ptr); return 0; } - return realloc(ptr, size2); + size3 += size2; + if(size3 < size2) { + free(ptr); + return 0; + } + return safe_realloc_(ptr, size3); } -static inline void *safe_realloc_add_3op_(void *ptr, size_t size1, size_t size2, size_t size3) +static inline void *safe_realloc_nofree_add_3op_(void *ptr, size_t size1, size_t size2, size_t size3) { size2 += size1; if(size2 < size1) @@ -182,10 +257,10 @@ static inline void *safe_realloc_add_3op_(void *ptr, size_t size1, size_t size2, size3 += size2; if(size3 < size2) return 0; - return realloc(ptr, size3); + return realloc_(ptr, size3); } -static inline void *safe_realloc_add_4op_(void *ptr, size_t size1, size_t size2, size_t size3, size_t size4) +static inline void *safe_realloc_nofree_add_4op_(void *ptr, size_t size1, size_t size2, size_t size3, size_t size4) { size2 += size1; if(size2 < size1) @@ -196,27 +271,51 @@ static inline void *safe_realloc_add_4op_(void *ptr, size_t size1, size_t size2, size4 += size3; if(size4 < size3) return 0; - return realloc(ptr, size4); + return realloc_(ptr, size4); } static inline void *safe_realloc_mul_2op_(void *ptr, size_t size1, size_t size2) { if(!size1 || !size2) return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */ - if(size1 > SIZE_MAX / size2) + if(size1 > SIZE_MAX / size2) { + free(ptr); return 0; + } return safe_realloc_(ptr, size1*size2); } +static inline void *safe_realloc_nofree_mul_2op_(void *ptr, size_t size1, size_t size2) +{ + if(!size1 || !size2) + return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */ + if(size1 > SIZE_MAX / size2) + return 0; + return realloc_(ptr, size1*size2); +} + /* size1 * (size2 + size3) */ static inline void *safe_realloc_muladd2_(void *ptr, size_t size1, size_t size2, size_t size3) { if(!size1 || (!size2 && !size3)) return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */ size2 += size3; - if(size2 < size3) + if(size2 < size3) { + free(ptr); return 0; + } return safe_realloc_mul_2op_(ptr, size1, size2); } +/* size1 * (size2 + size3) */ +static inline void *safe_realloc_nofree_muladd2_(void *ptr, size_t size1, size_t size2, size_t size3) +{ + if(!size1 || (!size2 && !size3)) + return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */ + size2 += size3; + if(size2 < size3) + return 0; + return safe_realloc_nofree_mul_2op_(ptr, size1, size2); +} + #endif diff --git a/modules/juce_audio_formats/codecs/flac/assert.h b/modules/juce_audio_formats/codecs/flac/assert.h index 7b2a21aeebd3..7e73ac27877c 100644 --- a/modules/juce_audio_formats/codecs/flac/assert.h +++ b/modules/juce_audio_formats/codecs/flac/assert.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2001-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -34,16 +34,18 @@ #define FLAC__ASSERT_H /* we need this since some compilers (like MSVC) leave assert()s on release code (and we don't want to use their ASSERT) */ +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION +#define FLAC__ASSERT(x) if(!(x)) __builtin_abort(); +#define FLAC__ASSERT_DECLARATION(x) x +#else #ifndef NDEBUG -// JUCE: removed as JUCE already includes standard headers and including -// these in FlacNamespace will cause problems - -//#include +#include #define FLAC__ASSERT(x) assert(x) #define FLAC__ASSERT_DECLARATION(x) x #else #define FLAC__ASSERT(x) #define FLAC__ASSERT_DECLARATION(x) #endif +#endif #endif diff --git a/modules/juce_audio_formats/codecs/flac/callback.h b/modules/juce_audio_formats/codecs/flac/callback.h index 6c9bbbea31f9..8b7a763a7d6f 100644 --- a/modules/juce_audio_formats/codecs/flac/callback.h +++ b/modules/juce_audio_formats/codecs/flac/callback.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2004-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -34,10 +34,7 @@ #define FLAC__CALLBACK_H #include "ordinals.h" - -// JUCE: removed as JUCE already includes this and including stdlib -// in FlacNamespace will cause problems -//#include /* for size_t */ +#include /* for size_t */ /** \file include/FLAC/callback.h * @@ -93,7 +90,9 @@ typedef void* FLAC__IOHandle; /** Signature for the read callback. * The signature and semantics match POSIX fread() implementations - * and can generally be used interchangeably. + * and can generally be used interchangeably. Note that the global + * variable errno from errno.h is read by some libFLAC functions to + * detect read errors. * * \param ptr The address of the read buffer. * \param size The size of the records to be read. @@ -169,14 +168,17 @@ typedef int (*FLAC__IOCallback_Close) (FLAC__IOHandle handle); * * If the seek requirement for an interface is optional, you can signify that * a data source is not seekable by setting the \a seek field to \c NULL. + * + * See the detailed documentation for callbacks in the + * \link flac_callbacks callbacks \endlink module. */ typedef struct { - FLAC__IOCallback_Read read; - FLAC__IOCallback_Write write; - FLAC__IOCallback_Seek seek; - FLAC__IOCallback_Tell tell; - FLAC__IOCallback_Eof eof; - FLAC__IOCallback_Close close; + FLAC__IOCallback_Read read; /**< See FLAC__IOCallbacks */ + FLAC__IOCallback_Write write; /**< See FLAC__IOCallbacks */ + FLAC__IOCallback_Seek seek; /**< See FLAC__IOCallbacks */ + FLAC__IOCallback_Tell tell; /**< See FLAC__IOCallbacks */ + FLAC__IOCallback_Eof eof; /**< See FLAC__IOCallbacks */ + FLAC__IOCallback_Close close; /**< See FLAC__IOCallbacks */ } FLAC__IOCallbacks; /* \} */ diff --git a/modules/juce_audio_formats/codecs/flac/compat.h b/modules/juce_audio_formats/codecs/flac/compat.h index 30887dbb8ef8..15944fd45895 100644 --- a/modules/juce_audio_formats/codecs/flac/compat.h +++ b/modules/juce_audio_formats/codecs/flac/compat.h @@ -1,5 +1,5 @@ /* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2012-2016 Xiph.org Foundation + * Copyright (C) 2012-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -39,8 +39,20 @@ #ifndef FLAC__SHARE__COMPAT_H #define FLAC__SHARE__COMPAT_H +#include +#include + +#if defined _WIN32 && !defined __CYGWIN__ +/* where MSVC puts unlink() */ +# include +#else +# include +#endif + #if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__ +#include /* for off_t */ #define FLAC__off_t __int64 /* use this instead of off_t to fix the 2 GB limit */ +#define FLAC__OFF_T_MAX INT64_MAX #if !defined __MINGW32__ #define fseeko _fseeki64 #define ftello _ftelli64 @@ -52,6 +64,14 @@ #endif #else #define FLAC__off_t off_t +#define FLAC__OFF_T_MAX OFF_T_MAX +#endif + + + +#ifdef HAVE_INTTYPES_H +#define __STDC_FORMAT_MACROS +#include #endif #if defined(_MSC_VER) @@ -85,15 +105,39 @@ #define FLAC__STRNCASECMP strncasecmp #endif +#if defined _MSC_VER || defined __MINGW32__ || defined __EMX__ +#include /* for _setmode(), chmod() */ +#include /* for _O_BINARY */ +#else +#include /* for chown(), unlink() */ +#endif + +#if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__ +#if defined __BORLANDC__ +#include /* for utime() */ +#else +#include /* for utime() */ +#endif +#else +#if defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200809L) +#include +#else +#include /* some flavors of BSD (like OS X) require this to get time_t */ +#include /* for utime() */ +#endif +#endif + #if defined _MSC_VER # if _MSC_VER >= 1800 # include # elif _MSC_VER >= 1600 /* Visual Studio 2010 has decent C99 support */ +# include # define PRIu64 "llu" # define PRId64 "lld" # define PRIx64 "llx" # else +# include # ifndef UINT32_MAX # define UINT32_MAX _UI32_MAX # endif @@ -101,6 +145,29 @@ # define PRId64 "I64d" # define PRIx64 "I64x" # endif +# if defined(_USING_V110_SDK71_) && !defined(_DLL) +# pragma message("WARNING: This compile will NOT FUNCTION PROPERLY on Windows XP. See comments in include/share/compat.h for details") +#define FLAC__USE_FILELENGTHI64 +/* + ************************************************************************************* + * V110_SDK71, in MSVC 2017 also known as v141_xp, is a platform toolset that is supposed + * to target Windows XP. It turns out however that certain functions provided silently fail + * on Windows XP only, which makes debugging challenging. This only occurs when building with + * /MT. This problem has been reported to Microsoft, but there hasn't been a fix for years. See + * https://web.archive.org/web/20170327195018/https://connect.microsoft.com/VisualStudio/feedback/details/1557168/wstat64-returns-1-on-xp-always + * + * It is known that this problem affects the functions _wstat64 (used by flac_stat i.e. + * stat64_utf8) and _fstat64 (i.e. flac_fstat) and therefore affects both libFLAC in + * several places as well as the flac and metaflac command line tools + * + * As the extent of this problem is unknown and Microsoft seems unwilling to fix it, + * users of libFLAC building with Visual Studio are encouraged to not use the /MT compile + * switch when explicitly targeting Windows XP. When use of /MT is deemed necessary with + * this toolset, be sure to check whether your application works properly on Windows XP. + * It is also possible to build for Windows XP with MinGW instead. + ************************************************************************************* +*/ +# endif #endif /* defined _MSC_VER */ #ifdef _WIN32 @@ -111,16 +178,15 @@ #define flac_printf printf_utf8 #define flac_fprintf fprintf_utf8 #define flac_vfprintf vfprintf_utf8 - -#include "windows_unicode_filenames.h" -#define flac_fopen flac_internal_fopen_utf8 -#define flac_chmod flac_internal_chmod_utf8 -#define flac_utime flac_internal_utime_utf8 -#define flac_unlink flac_internal_unlink_utf8 -#define flac_rename flac_internal_rename_utf8 -#define flac_stat flac_internal_stat64_utf8 #endif +#define flac_fopen fopen_utf8 +#define flac_chmod chmod_utf8 +#define flac_utime utime_utf8 +#define flac_unlink unlink_utf8 +#define flac_rename rename_utf8 +#define flac_stat stat64_utf8 + #else #define flac_printf printf diff --git a/modules/juce_audio_formats/codecs/flac/endswap.h b/modules/juce_audio_formats/codecs/flac/endswap.h index 790d1e4edf36..d11ea3d06766 100644 --- a/modules/juce_audio_formats/codecs/flac/endswap.h +++ b/modules/juce_audio_formats/codecs/flac/endswap.h @@ -1,5 +1,5 @@ /* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2012-2016 Xiph.org Foundation + * Copyright (C) 2012-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -31,10 +31,10 @@ /* It is assumed that this header will be included after "config.h". */ -#if HAVE_BSWAP32 /* GCC and Clang */ +#ifdef HAVE_BSWAP32 /* GCC and Clang */ /* GCC prior to 4.8 didn't provide bswap16 on x86_64 */ -#if ! HAVE_BSWAP16 +#ifndef HAVE_BSWAP16 static inline unsigned short __builtin_bswap16(unsigned short a) { return (a<<8)|(a>>8); @@ -55,9 +55,7 @@ static inline unsigned short __builtin_bswap16(unsigned short a) #elif defined HAVE_BYTESWAP_H /* Linux */ -// JUCE: removed as JUCE already includes standard headers and including -// these in FlacNamespace will cause problems -//#include +#include #define ENDSWAP_16(x) (bswap_16 (x)) #define ENDSWAP_32(x) (bswap_32 (x)) diff --git a/modules/juce_audio_formats/codecs/flac/export.h b/modules/juce_audio_formats/codecs/flac/export.h index 1885a428e9ea..5ce224eeb619 100644 --- a/modules/juce_audio_formats/codecs/flac/export.h +++ b/modules/juce_audio_formats/codecs/flac/export.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -49,22 +49,40 @@ * This module contains \#defines and symbols for exporting function * calls, and providing version information and compiled-in features. * - * If you are compiling with MSVC and will link to the static library - * (libFLAC.lib) you should define FLAC__NO_DLL in your project to - * make sure the symbols are exported properly. + * If you are compiling for Windows (with Visual Studio or MinGW for + * example) and will link to the static library (libFLAC++.lib) you + * should define FLAC__NO_DLL in your project to make sure the symbols + * are exported properly. * * \{ */ -#if defined(FLAC__NO_DLL) -#define FLAC_API +/** This \#define is used internally in libFLAC and its headers to make + * sure the correct symbols are exported when working with shared + * libraries. On Windows, this \#define is set to __declspec(dllexport) + * when compiling libFLAC into a library and to __declspec(dllimport) + * when the headers are used to link to that DLL. On non-Windows systems + * it is used to set symbol visibility. + * + * Because of this, the define FLAC__NO_DLL must be defined when linking + * to libFLAC statically or linking will fail. + */ +/* This has grown quite complicated. FLAC__NO_DLL is used by MSVC sln + * files and CMake, which build either static or shared. autotools can + * build static, shared or **both**. Therefore, DLL_EXPORT, which is set + * by libtool, must override FLAC__NO_DLL on building shared components + */ +#if defined(_WIN32) -#elif defined(_WIN32) +#if defined(FLAC__NO_DLL) && !(defined(DLL_EXPORT)) +#define FLAC_API +#else #ifdef FLAC_API_EXPORTS #define FLAC_API __declspec(dllexport) #else #define FLAC_API __declspec(dllimport) #endif +#endif #elif defined(FLAC__USE_VISIBILITY_ATTR) #define FLAC_API __attribute__ ((visibility ("default"))) @@ -77,9 +95,9 @@ /** These \#defines will mirror the libtool-based library version number, see * http://www.gnu.org/software/libtool/manual/libtool.html#Libtool-versioning */ -#define FLAC_API_VERSION_CURRENT 11 +#define FLAC_API_VERSION_CURRENT 13 #define FLAC_API_VERSION_REVISION 0 /**< see above */ -#define FLAC_API_VERSION_AGE 3 /**< see above */ +#define FLAC_API_VERSION_AGE 1 /**< see above */ #ifdef __cplusplus extern "C" { diff --git a/modules/juce_audio_formats/codecs/flac/format.h b/modules/juce_audio_formats/codecs/flac/format.h index 2eb004494bc4..ca8d8fcf2d2c 100644 --- a/modules/juce_audio_formats/codecs/flac/format.h +++ b/modules/juce_audio_formats/codecs/flac/format.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -60,7 +60,7 @@ extern "C" { * structures used by the rest of the interfaces. * * First, you should be familiar with the - * FLAC format. Many of the values here + * FLAC format. Many of the values here * follow directly from the specification. As a user of libFLAC, the * interesting parts really are the structures that describe the frame * header and metadata blocks. @@ -113,19 +113,16 @@ extern "C" { /** The maximum sample resolution permitted by libFLAC. * - * \warning * FLAC__MAX_BITS_PER_SAMPLE is the limit of the FLAC format. However, - * the reference encoder/decoder is currently limited to 24 bits because - * of prevalent 32-bit math, so make sure and use this value when - * appropriate. + * the reference encoder/decoder used to be limited to 24 bits. This + * value was used to signal that limit. */ -#define FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE (24u) +#define FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE (32u) /** The maximum sample rate permitted by the format. The value is - * ((2 ^ 16) - 1) * 10; see FLAC format - * as to why. + * ((2 ^ 20) - 1) */ -#define FLAC__MAX_SAMPLE_RATE (655350u) +#define FLAC__MAX_SAMPLE_RATE (1048575u) /** The maximum LPC order permitted by the format. */ #define FLAC__MAX_LPC_ORDER (32u) @@ -228,7 +225,7 @@ typedef struct { */ } FLAC__EntropyCodingMethod_PartitionedRiceContents; -/** Header for a Rice partitioned residual. (c.f. format specification) +/** Header for a Rice partitioned residual. (c.f. format specification) */ typedef struct { @@ -250,7 +247,7 @@ extern FLAC_API const uint32_t FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCA extern FLAC_API const uint32_t FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER; /**< == (1<format specification) +/** Header for the entropy coding method. (c.f. format specification) */ typedef struct { FLAC__EntropyCodingMethodType type; @@ -279,21 +276,31 @@ typedef enum { extern FLAC_API const char * const FLAC__SubframeTypeString[]; -/** CONSTANT subframe. (c.f. format specification) +/** CONSTANT subframe. (c.f. format specification) */ typedef struct { - FLAC__int32 value; /**< The constant signal value. */ + FLAC__int64 value; /**< The constant signal value. */ } FLAC__Subframe_Constant; +/** An enumeration of the possible verbatim subframe data types. */ +typedef enum { + FLAC__VERBATIM_SUBFRAME_DATA_TYPE_INT32, /**< verbatim subframe has 32-bit int */ + FLAC__VERBATIM_SUBFRAME_DATA_TYPE_INT64 /**< verbatim subframe has 64-bit int */ +} FLAC__VerbatimSubframeDataType; + -/** VERBATIM subframe. (c.f. format specification) +/** VERBATIM subframe. (c.f. format specification) */ typedef struct { - const FLAC__int32 *data; /**< A pointer to verbatim signal. */ + union { + const FLAC__int32 *int32; /**< A FLAC__int32 pointer to verbatim signal. */ + const FLAC__int64 *int64; /**< A FLAC__int64 pointer to verbatim signal. */ + } data; + FLAC__VerbatimSubframeDataType data_type; } FLAC__Subframe_Verbatim; -/** FIXED subframe. (c.f. format specification) +/** FIXED subframe. (c.f. format specification) */ typedef struct { FLAC__EntropyCodingMethod entropy_coding_method; @@ -302,7 +309,7 @@ typedef struct { uint32_t order; /**< The polynomial order. */ - FLAC__int32 warmup[FLAC__MAX_FIXED_ORDER]; + FLAC__int64 warmup[FLAC__MAX_FIXED_ORDER]; /**< Warmup samples to prime the predictor, length == order. */ const FLAC__int32 *residual; @@ -310,7 +317,7 @@ typedef struct { } FLAC__Subframe_Fixed; -/** LPC subframe. (c.f. format specification) +/** LPC subframe. (c.f. format specification) */ typedef struct { FLAC__EntropyCodingMethod entropy_coding_method; @@ -328,7 +335,7 @@ typedef struct { FLAC__int32 qlp_coeff[FLAC__MAX_LPC_ORDER]; /**< FIR filter coefficients. */ - FLAC__int32 warmup[FLAC__MAX_LPC_ORDER]; + FLAC__int64 warmup[FLAC__MAX_LPC_ORDER]; /**< Warmup samples to prime the predictor, length == order. */ const FLAC__int32 *residual; @@ -339,7 +346,7 @@ extern FLAC_API const uint32_t FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN; /**< extern FLAC_API const uint32_t FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN; /**< == 5 (bits) */ -/** FLAC subframe structure. (c.f. format specification) +/** FLAC subframe structure. (c.f. format specification) */ typedef struct { FLAC__SubframeType type; @@ -406,7 +413,7 @@ typedef enum { extern FLAC_API const char * const FLAC__FrameNumberTypeString[]; -/** FLAC frame header structure. (c.f. format specification) +/** FLAC frame header structure. (c.f. format specification) */ typedef struct { uint32_t blocksize; @@ -455,7 +462,7 @@ extern FLAC_API const uint32_t FLAC__FRAME_HEADER_ZERO_PAD_LEN; /**< == 1 (bit) extern FLAC_API const uint32_t FLAC__FRAME_HEADER_CRC_LEN; /**< == 8 (bits) */ -/** FLAC frame footer structure. (c.f. format specification) +/** FLAC frame footer structure. (c.f. format specification) */ typedef struct { FLAC__uint16 crc; @@ -468,7 +475,7 @@ typedef struct { extern FLAC_API const uint32_t FLAC__FRAME_FOOTER_CRC_LEN; /**< == 16 (bits) */ -/** FLAC frame structure. (c.f. format specification) +/** FLAC frame structure. (c.f. format specification) */ typedef struct { FLAC__FrameHeader header; @@ -489,25 +496,25 @@ typedef struct { typedef enum { FLAC__METADATA_TYPE_STREAMINFO = 0, - /**< STREAMINFO block */ + /**< STREAMINFO block */ FLAC__METADATA_TYPE_PADDING = 1, - /**< PADDING block */ + /**< PADDING block */ FLAC__METADATA_TYPE_APPLICATION = 2, - /**< APPLICATION block */ + /**< APPLICATION block */ FLAC__METADATA_TYPE_SEEKTABLE = 3, - /**< SEEKTABLE block */ + /**< SEEKTABLE block */ FLAC__METADATA_TYPE_VORBIS_COMMENT = 4, - /**< VORBISCOMMENT block (a.k.a. FLAC tags) */ + /**< VORBISCOMMENT block (a.k.a. FLAC tags) */ FLAC__METADATA_TYPE_CUESHEET = 5, - /**< CUESHEET block */ + /**< CUESHEET block */ FLAC__METADATA_TYPE_PICTURE = 6, - /**< PICTURE block */ + /**< PICTURE block */ FLAC__METADATA_TYPE_UNDEFINED = 7, /**< marker to denote beginning of undefined type range; this number will increase as new metadata types are added */ @@ -524,7 +531,7 @@ typedef enum { extern FLAC_API const char * const FLAC__MetadataTypeString[]; -/** FLAC STREAMINFO structure. (c.f. format specification) +/** FLAC STREAMINFO structure. (c.f. format specification) */ typedef struct { uint32_t min_blocksize, max_blocksize; @@ -549,7 +556,7 @@ extern FLAC_API const uint32_t FLAC__STREAM_METADATA_STREAMINFO_MD5SUM_LEN; /**< /** The total stream length of the STREAMINFO block in bytes. */ #define FLAC__STREAM_METADATA_STREAMINFO_LENGTH (34u) -/** FLAC PADDING structure. (c.f. format specification) +/** FLAC PADDING structure. (c.f. format specification) */ typedef struct { int dummy; @@ -560,7 +567,7 @@ typedef struct { } FLAC__StreamMetadata_Padding; -/** FLAC APPLICATION structure. (c.f. format specification) +/** FLAC APPLICATION structure. (c.f. format specification) */ typedef struct { FLAC__byte id[4]; @@ -569,7 +576,7 @@ typedef struct { extern FLAC_API const uint32_t FLAC__STREAM_METADATA_APPLICATION_ID_LEN; /**< == 32 (bits) */ -/** SeekPoint structure used in SEEKTABLE blocks. (c.f. format specification) +/** SeekPoint structure used in SEEKTABLE blocks. (c.f. format specification) */ typedef struct { FLAC__uint64 sample_number; @@ -597,7 +604,7 @@ extern FLAC_API const uint32_t FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN extern FLAC_API const FLAC__uint64 FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER; -/** FLAC SEEKTABLE structure. (c.f. format specification) +/** FLAC SEEKTABLE structure. (c.f. format specification) * * \note From the format specification: * - The seek points must be sorted by ascending sample number. @@ -615,7 +622,7 @@ typedef struct { } FLAC__StreamMetadata_SeekTable; -/** Vorbis comment entry structure used in VORBIS_COMMENT blocks. (c.f. format specification) +/** Vorbis comment entry structure used in VORBIS_COMMENT blocks. (c.f. format specification) * * For convenience, the APIs maintain a trailing NUL character at the end of * \a entry which is not counted toward \a length, i.e. @@ -629,7 +636,7 @@ typedef struct { extern FLAC_API const uint32_t FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN; /**< == 32 (bits) */ -/** FLAC VORBIS_COMMENT structure. (c.f. format specification) +/** FLAC VORBIS_COMMENT structure. (c.f. format specification) */ typedef struct { FLAC__StreamMetadata_VorbisComment_Entry vendor_string; @@ -641,7 +648,7 @@ extern FLAC_API const uint32_t FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS /** FLAC CUESHEET track index structure. (See the - * format specification for + * format specification for * the full description of each field.) */ typedef struct { @@ -660,7 +667,7 @@ extern FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN /** FLAC CUESHEET track structure. (See the - * format specification for + * format specification for * the full description of each field.) */ typedef struct { @@ -697,7 +704,7 @@ extern FLAC_API const uint32_t FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_ /** FLAC CUESHEET structure. (See the - * format specification + * format specification * for the full description of each field.) */ typedef struct { @@ -763,7 +770,7 @@ typedef enum { extern FLAC_API const char * const FLAC__StreamMetadata_Picture_TypeString[]; /** FLAC PICTURE structure. (See the - * format specification + * format specification * for the full description of each field.) */ typedef struct { @@ -829,9 +836,9 @@ typedef struct { } FLAC__StreamMetadata_Unknown; -/** FLAC metadata block structure. (c.f. format specification) +/** FLAC metadata block structure. (c.f. format specification) */ -typedef struct { +typedef struct FLAC__StreamMetadata { FLAC__MetadataType type; /**< The type of the metadata block; used determine which member of the * \a data union to dereference. If type >= FLAC__METADATA_TYPE_UNDEFINED diff --git a/modules/juce_audio_formats/codecs/flac/libFLAC/bitmath.c b/modules/juce_audio_formats/codecs/flac/libFLAC/bitmath.c index 18e951b2b873..5c63fa23b187 100644 --- a/modules/juce_audio_formats/codecs/flac/libFLAC/bitmath.c +++ b/modules/juce_audio_formats/codecs/flac/libFLAC/bitmath.c @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2001-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/modules/juce_audio_formats/codecs/flac/libFLAC/bitreader.c b/modules/juce_audio_formats/codecs/flac/libFLAC/bitreader.c index eb401c728db8..b79c8bca6445 100644 --- a/modules/juce_audio_formats/codecs/flac/libFLAC/bitreader.c +++ b/modules/juce_audio_formats/codecs/flac/libFLAC/bitreader.c @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2018 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -39,6 +39,8 @@ #include "include/private/bitmath.h" #include "include/private/bitreader.h" #include "include/private/crc.h" +#include "include/private/cpu.h" + #include "../assert.h" #include "../compat.h" #include "../endswap.h" @@ -110,6 +112,9 @@ struct FLAC__BitReader { uint32_t read_crc16; /* the running frame CRC */ uint32_t crc16_offset; /* the number of words in the current buffer that should not be CRC'd */ uint32_t crc16_align; /* the number of bits in the current consumed word that should not be CRC'd */ + FLAC__bool read_limit_set; /* whether reads are limited */ + uint32_t read_limit; /* the remaining size of what can be read */ + uint32_t last_seen_framesync; /* the location of the last seen framesync, if it is in the buffer, in bits from front of buffer */ FLAC__BitReaderReadCallback read_callback; void *client_data; }; @@ -154,9 +159,16 @@ static FLAC__bool bitreader_read_from_client_(FLAC__BitReader *br) uint32_t start, end; size_t bytes; FLAC__byte *target; +#if WORDS_BIGENDIAN +#else + brword preswap_backup; +#endif /* first shift the unconsumed buffer data toward the front as much as possible */ if(br->consumed_words > 0) { + /* invalidate last seen framesync */ + br->last_seen_framesync = (uint32_t) -1; + crc16_update_block_(br); /* CRC consumed words */ start = br->consumed_words; @@ -185,6 +197,7 @@ static FLAC__bool bitreader_read_from_client_(FLAC__BitReader *br) */ #if WORDS_BIGENDIAN #else + preswap_backup = br->buffer[br->words]; if(br->bytes) br->buffer[br->words] = SWAP_BE_WORD_TO_HOST(br->buffer[br->words]); #endif @@ -197,8 +210,16 @@ static FLAC__bool bitreader_read_from_client_(FLAC__BitReader *br) */ /* read in the data; note that the callback may return a smaller number of bytes */ - if(!br->read_callback(target, &bytes, br->client_data)) + if(!br->read_callback(target, &bytes, br->client_data)){ + /* Despite the read callback failing, the data in the target + * might be used later, when the buffer is rewound. Therefore + * we revert the swap that was just done */ +#if WORDS_BIGENDIAN +#else + br->buffer[br->words] = preswap_backup; +#endif return false; + } /* after reading bytes 66 77 88 99 AA BB CC DD EE FF from the client: * bitstream : 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF @@ -274,6 +295,9 @@ FLAC__bool FLAC__bitreader_init(FLAC__BitReader *br, FLAC__BitReaderReadCallback return false; br->read_callback = rcb; br->client_data = cd; + br->read_limit_set = false; + br->read_limit = (uint32_t) -1; + br->last_seen_framesync = (uint32_t) -1; return true; } @@ -290,42 +314,36 @@ void FLAC__bitreader_free(FLAC__BitReader *br) br->consumed_words = br->consumed_bits = 0; br->read_callback = 0; br->client_data = 0; + br->read_limit_set = false; + br->read_limit = (uint32_t) -1; + br->last_seen_framesync = (uint32_t) -1; } FLAC__bool FLAC__bitreader_clear(FLAC__BitReader *br) { br->words = br->bytes = 0; br->consumed_words = br->consumed_bits = 0; + br->read_limit_set = false; + br->read_limit = (uint32_t) -1; + br->last_seen_framesync = (uint32_t) -1; return true; } -void FLAC__bitreader_dump(const FLAC__BitReader *br, FILE *out) +void FLAC__bitreader_set_framesync_location(FLAC__BitReader *br) +{ + br->last_seen_framesync = br->consumed_words * FLAC__BYTES_PER_WORD + br->consumed_bits / 8; +} + +FLAC__bool FLAC__bitreader_rewind_to_after_last_seen_framesync(FLAC__BitReader *br) { - uint32_t i, j; - if(br == 0) { - fprintf(out, "bitreader is NULL\n"); + if(br->last_seen_framesync == (uint32_t)-1) { + br->consumed_words = br->consumed_bits = 0; + return false; } else { - fprintf(out, "bitreader: capacity=%u words=%u bytes=%u consumed: words=%u, bits=%u\n", br->capacity, br->words, br->bytes, br->consumed_words, br->consumed_bits); - - for(i = 0; i < br->words; i++) { - fprintf(out, "%08X: ", i); - for(j = 0; j < FLAC__BITS_PER_WORD; j++) - if(i < br->consumed_words || (i == br->consumed_words && j < br->consumed_bits)) - fprintf(out, "."); - else - fprintf(out, "%01d", br->buffer[i] & ((brword)1 << (FLAC__BITS_PER_WORD-j-1)) ? 1:0); - fprintf(out, "\n"); - } - if(br->bytes > 0) { - fprintf(out, "%08X: ", i); - for(j = 0; j < br->bytes*8; j++) - if(i < br->consumed_words || (i == br->consumed_words && j < br->consumed_bits)) - fprintf(out, "."); - else - fprintf(out, "%01d", br->buffer[i] & ((brword)1 << (br->bytes*8-j-1)) ? 1:0); - fprintf(out, "\n"); - } + br->consumed_words = (br->last_seen_framesync + 1) / FLAC__BYTES_PER_WORD; + br->consumed_bits = ((br->last_seen_framesync + 1) % FLAC__BYTES_PER_WORD) * 8; + return true; } } @@ -375,6 +393,28 @@ inline uint32_t FLAC__bitreader_get_input_bits_unconsumed(const FLAC__BitReader return (br->words-br->consumed_words)*FLAC__BITS_PER_WORD + br->bytes*8 - br->consumed_bits; } +void FLAC__bitreader_set_limit(FLAC__BitReader *br, uint32_t limit) +{ + br->read_limit = limit; + br->read_limit_set = true; +} + +void FLAC__bitreader_remove_limit(FLAC__BitReader *br) +{ + br->read_limit_set = false; + br->read_limit = (uint32_t) -1; +} + +uint32_t FLAC__bitreader_limit_remaining(FLAC__BitReader *br) +{ + FLAC__ASSERT(br->read_limit_set); + return br->read_limit; +} +void FLAC__bitreader_limit_invalidate(FLAC__BitReader *br) +{ + br->read_limit = (uint32_t) -1; +} + FLAC__bool FLAC__bitreader_read_raw_uint32(FLAC__BitReader *br, FLAC__uint32 *val, uint32_t bits) { FLAC__ASSERT(0 != br); @@ -392,6 +432,15 @@ FLAC__bool FLAC__bitreader_read_raw_uint32(FLAC__BitReader *br, FLAC__uint32 *va return true; } + if(br->read_limit_set && br->read_limit < (uint32_t)-1){ + if(br->read_limit < bits) { + br->read_limit = (uint32_t) -1; + return false; + } + else + br->read_limit -= bits; + } + while((br->words-br->consumed_words)*FLAC__BITS_PER_WORD + br->bytes*8 - br->consumed_bits < bits) { if(!bitreader_read_from_client_(br)) return false; @@ -464,7 +513,7 @@ FLAC__bool FLAC__bitreader_read_raw_int32(FLAC__BitReader *br, FLAC__int32 *val, return false; /* sign-extend *val assuming it is currently bits wide. */ /* From: https://graphics.stanford.edu/~seander/bithacks.html#FixedSignExtend */ - mask = bits >= 33 ? 0 : 1u << (bits - 1); + mask = bits >= 33 ? 0 : 1lu << (bits - 1); *val = (uval ^ mask) - mask; return true; } @@ -490,6 +539,19 @@ FLAC__bool FLAC__bitreader_read_raw_uint64(FLAC__BitReader *br, FLAC__uint64 *va return true; } +FLAC__bool FLAC__bitreader_read_raw_int64(FLAC__BitReader *br, FLAC__int64 *val, uint32_t bits) +{ + FLAC__uint64 uval, mask; + /* OPT: inline raw uint64 code here, or make into a macro if possible in the .h file */ + if (bits < 1 || ! FLAC__bitreader_read_raw_uint64(br, &uval, bits)) + return false; + /* sign-extend *val assuming it is currently bits wide. */ + /* From: https://graphics.stanford.edu/~seander/bithacks.html#FixedSignExtend */ + mask = bits >= 65 ? 0 : 1llu << (bits - 1); + *val = (uval ^ mask) - mask; + return true; +} + inline FLAC__bool FLAC__bitreader_read_uint32_little_endian(FLAC__BitReader *br, FLAC__uint32 *val) { FLAC__uint32 x8, x32 = 0; @@ -558,6 +620,13 @@ FLAC__bool FLAC__bitreader_skip_byte_block_aligned_no_crc(FLAC__BitReader *br, u FLAC__ASSERT(0 != br->buffer); FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(br)); + if(br->read_limit_set && br->read_limit < (uint32_t)-1){ + if(br->read_limit < nvals*8){ + br->read_limit = (uint32_t) -1; + return false; + } + } + /* step 1: skip over partial head word to get word aligned */ while(nvals && br->consumed_bits) { /* i.e. run until we read 'nvals' bytes or we hit the end of the head word */ if(!FLAC__bitreader_read_raw_uint32(br, &x, 8)) @@ -566,11 +635,14 @@ FLAC__bool FLAC__bitreader_skip_byte_block_aligned_no_crc(FLAC__BitReader *br, u } if(0 == nvals) return true; + /* step 2: skip whole words in chunks */ while(nvals >= FLAC__BYTES_PER_WORD) { if(br->consumed_words < br->words) { br->consumed_words++; nvals -= FLAC__BYTES_PER_WORD; + if(br->read_limit_set) + br->read_limit -= FLAC__BITS_PER_WORD; } else if(!bitreader_read_from_client_(br)) return false; @@ -593,6 +665,13 @@ FLAC__bool FLAC__bitreader_read_byte_block_aligned_no_crc(FLAC__BitReader *br, F FLAC__ASSERT(0 != br->buffer); FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(br)); + if(br->read_limit_set && br->read_limit < (uint32_t)-1){ + if(br->read_limit < nvals*8){ + br->read_limit = (uint32_t) -1; + return false; + } + } + /* step 1: read from partial head word to get word aligned */ while(nvals && br->consumed_bits) { /* i.e. run until we read 'nvals' bytes or we hit the end of the head word */ if(!FLAC__bitreader_read_raw_uint32(br, &x, 8)) @@ -626,6 +705,8 @@ FLAC__bool FLAC__bitreader_read_byte_block_aligned_no_crc(FLAC__BitReader *br, F #endif val += FLAC__BYTES_PER_WORD; nvals -= FLAC__BYTES_PER_WORD; + if(br->read_limit_set) + br->read_limit -= FLAC__BITS_PER_WORD; } else if(!bitreader_read_from_client_(br)) return false; @@ -720,6 +801,7 @@ FLAC__bool FLAC__bitreader_read_unary_unsigned(FLAC__BitReader *br, uint32_t *va } #endif +#if 0 /* unused */ FLAC__bool FLAC__bitreader_read_rice_signed(FLAC__BitReader *br, int *val, uint32_t parameter) { FLAC__uint32 lsbs = 0, msbs = 0; @@ -746,146 +828,17 @@ FLAC__bool FLAC__bitreader_read_rice_signed(FLAC__BitReader *br, int *val, uint3 return true; } +#endif /* this is by far the most heavily used reader call. it ain't pretty but it's fast */ FLAC__bool FLAC__bitreader_read_rice_signed_block(FLAC__BitReader *br, int vals[], uint32_t nvals, uint32_t parameter) -{ - /* try and get br->consumed_words and br->consumed_bits into register; - * must remember to flush them back to *br before calling other - * bitreader functions that use them, and before returning */ - uint32_t cwords, words, lsbs, msbs, x, y; - uint32_t ucbits; /* keep track of the number of unconsumed bits in word */ - brword b; - int *val, *end; - - FLAC__ASSERT(0 != br); - FLAC__ASSERT(0 != br->buffer); - /* WATCHOUT: code does not work with <32bit words; we can make things much faster with this assertion */ - FLAC__ASSERT(FLAC__BITS_PER_WORD >= 32); - FLAC__ASSERT(parameter < 32); - /* the above two asserts also guarantee that the binary part never straddles more than 2 words, so we don't have to loop to read it */ - - val = vals; - end = vals + nvals; - - if(parameter == 0) { - while(val < end) { - /* read the unary MSBs and end bit */ - if(!FLAC__bitreader_read_unary_unsigned(br, &msbs)) - return false; - - *val++ = (int)(msbs >> 1) ^ -(int)(msbs & 1); - } - - return true; - } +#include "deduplication/bitreader_read_rice_signed_block.c" - FLAC__ASSERT(parameter > 0); - - cwords = br->consumed_words; - words = br->words; - - /* if we've not consumed up to a partial tail word... */ - if(cwords >= words) { - x = 0; - goto process_tail; - } - - ucbits = FLAC__BITS_PER_WORD - br->consumed_bits; - b = br->buffer[cwords] << br->consumed_bits; /* keep unconsumed bits aligned to left */ - - while(val < end) { - /* read the unary MSBs and end bit */ - x = y = COUNT_ZERO_MSBS2(b); - if(x == FLAC__BITS_PER_WORD) { - x = ucbits; - do { - /* didn't find stop bit yet, have to keep going... */ - cwords++; - if (cwords >= words) - goto incomplete_msbs; - b = br->buffer[cwords]; - y = COUNT_ZERO_MSBS2(b); - x += y; - } while(y == FLAC__BITS_PER_WORD); - } - b <<= y; - b <<= 1; /* account for stop bit */ - ucbits = (ucbits - x - 1) % FLAC__BITS_PER_WORD; - msbs = x; - - /* read the binary LSBs */ - x = (FLAC__uint32)(b >> (FLAC__BITS_PER_WORD - parameter)); /* parameter < 32, so we can cast to 32-bit uint32_t */ - if(parameter <= ucbits) { - ucbits -= parameter; - b <<= parameter; - } else { - /* there are still bits left to read, they will all be in the next word */ - cwords++; - if (cwords >= words) - goto incomplete_lsbs; - b = br->buffer[cwords]; - ucbits += FLAC__BITS_PER_WORD - parameter; - x |= (FLAC__uint32)(b >> ucbits); - b <<= FLAC__BITS_PER_WORD - ucbits; - } - lsbs = x; - - /* compose the value */ - x = (msbs << parameter) | lsbs; - *val++ = (int)(x >> 1) ^ -(int)(x & 1); - - continue; - - /* at this point we've eaten up all the whole words */ -process_tail: - do { - if(0) { -incomplete_msbs: - br->consumed_bits = 0; - br->consumed_words = cwords; - } - - /* read the unary MSBs and end bit */ - if(!FLAC__bitreader_read_unary_unsigned(br, &msbs)) - return false; - msbs += x; - x = ucbits = 0; - - if(0) { -incomplete_lsbs: - br->consumed_bits = 0; - br->consumed_words = cwords; - } - - /* read the binary LSBs */ - if(!FLAC__bitreader_read_raw_uint32(br, &lsbs, parameter - ucbits)) - return false; - lsbs = x | lsbs; - - /* compose the value */ - x = (msbs << parameter) | lsbs; - *val++ = (int)(x >> 1) ^ -(int)(x & 1); - x = 0; - - cwords = br->consumed_words; - words = br->words; - ucbits = FLAC__BITS_PER_WORD - br->consumed_bits; - b = cwords < br->capacity ? br->buffer[cwords] << br->consumed_bits : 0; - } while(cwords >= words && val < end); - } - - if(ucbits == 0 && cwords < words) { - /* don't leave the head word with no unconsumed bits */ - cwords++; - ucbits = FLAC__BITS_PER_WORD; - } - - br->consumed_bits = FLAC__BITS_PER_WORD - ucbits; - br->consumed_words = cwords; - - return true; -} +#ifdef FLAC__BMI2_SUPPORTED +FLAC__SSE_TARGET("bmi2") +FLAC__bool FLAC__bitreader_read_rice_signed_block_bmi2(FLAC__BitReader *br, int vals[], uint32_t nvals, uint32_t parameter) +#include "deduplication/bitreader_read_rice_signed_block.c" +#endif #if 0 /* UNUSED */ FLAC__bool FLAC__bitreader_read_golomb_signed(FLAC__BitReader *br, int *val, uint32_t parameter) diff --git a/modules/juce_audio_formats/codecs/flac/libFLAC/bitwriter.c b/modules/juce_audio_formats/codecs/flac/libFLAC/bitwriter.c index f280dc358733..743e6b5ca5fa 100644 --- a/modules/juce_audio_formats/codecs/flac/libFLAC/bitwriter.c +++ b/modules/juce_audio_formats/codecs/flac/libFLAC/bitwriter.c @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -38,6 +38,9 @@ #include #include "include/private/bitwriter.h" #include "include/private/crc.h" +#include "include/private/format.h" + +#include "include/private/stream_encoder.h" #include "../assert.h" #include "../alloc.h" #include "../compat.h" @@ -50,8 +53,11 @@ #if (ENABLE_64_BIT_WORDS == 0) typedef FLAC__uint32 bwword; +typedef FLAC__uint64 FLAC__bwtemp; #define FLAC__BYTES_PER_WORD 4 /* sizeof bwword */ #define FLAC__BITS_PER_WORD 32 +#define FLAC__TEMP_BITS 64 +#define FLAC__HALF_TEMP_BITS 32 /* SWAP_BE_WORD_TO_HOST swaps bytes in a bwword (which is always big-endian) if necessary to match host byte order */ #if WORDS_BIGENDIAN #define SWAP_BE_WORD_TO_HOST(x) (x) @@ -62,8 +68,11 @@ typedef FLAC__uint32 bwword; #else typedef FLAC__uint64 bwword; +typedef FLAC__uint64 FLAC__bwtemp; #define FLAC__BYTES_PER_WORD 8 /* sizeof bwword */ #define FLAC__BITS_PER_WORD 64 +#define FLAC__TEMP_BITS 64 +#define FLAC__HALF_TEMP_BITS 32 /* SWAP_BE_WORD_TO_HOST swaps bytes in a bwword (which is always big-endian) if necessary to match host byte order */ #if WORDS_BIGENDIAN #define SWAP_BE_WORD_TO_HOST(x) (x) @@ -115,6 +124,13 @@ FLAC__bool bitwriter_grow_(FLAC__BitWriter *bw, uint32_t bits_to_add) if(bw->capacity >= new_capacity) return true; + if(new_capacity * sizeof(bwword) > (1u << FLAC__STREAM_METADATA_LENGTH_LEN)) + /* Requested new capacity is larger than the largest possible metadata block, + * which is also larger than the largest sane framesize. That means something + * went very wrong somewhere and previous checks failed. + * To prevent chrashing, give up */ + return false; + /* round up capacity increase to the nearest FLAC__BITWRITER_DEFAULT_INCREMENT */ if((new_capacity - bw->capacity) % FLAC__BITWRITER_DEFAULT_INCREMENT) new_capacity += FLAC__BITWRITER_DEFAULT_INCREMENT - ((new_capacity - bw->capacity) % FLAC__BITWRITER_DEFAULT_INCREMENT); @@ -123,7 +139,7 @@ FLAC__bool bitwriter_grow_(FLAC__BitWriter *bw, uint32_t bits_to_add) FLAC__ASSERT(new_capacity > bw->capacity); FLAC__ASSERT(new_capacity >= bw->words + ((bw->bits + bits_to_add + FLAC__BITS_PER_WORD - 1) / FLAC__BITS_PER_WORD)); - new_buffer = (bwword*) safe_realloc_mul_2op_(bw->buffer, sizeof(bwword), /*times*/new_capacity); + new_buffer = (bwword*) safe_realloc_nofree_mul_2op_(bw->buffer, sizeof(bwword), /*times*/new_capacity); if(new_buffer == 0) return false; bw->buffer = new_buffer; @@ -188,30 +204,6 @@ void FLAC__bitwriter_clear(FLAC__BitWriter *bw) bw->words = bw->bits = 0; } -void FLAC__bitwriter_dump(const FLAC__BitWriter *bw, FILE *out) -{ - uint32_t i, j; - if(bw == 0) { - fprintf(out, "bitwriter is NULL\n"); - } - else { - fprintf(out, "bitwriter: capacity=%u words=%u bits=%u total_bits=%u\n", bw->capacity, bw->words, bw->bits, FLAC__TOTAL_BITS(bw)); - - for(i = 0; i < bw->words; i++) { - fprintf(out, "%08X: ", i); - for(j = 0; j < FLAC__BITS_PER_WORD; j++) - fprintf(out, "%01d", bw->buffer[i] & ((bwword)1 << (FLAC__BITS_PER_WORD-j-1)) ? 1:0); - fprintf(out, "\n"); - } - if(bw->bits > 0) { - fprintf(out, "%08X: ", i); - for(j = 0; j < bw->bits; j++) - fprintf(out, "%01d", bw->accum & ((bwword)1 << (bw->bits-j-1)) ? 1:0); - fprintf(out, "\n"); - } - } -} - FLAC__bool FLAC__bitwriter_get_write_crc16(FLAC__BitWriter *bw, FLAC__uint16 *crc) { const FLAC__byte *buffer; @@ -389,6 +381,15 @@ inline FLAC__bool FLAC__bitwriter_write_raw_uint64(FLAC__BitWriter *bw, FLAC__ui return FLAC__bitwriter_write_raw_uint32(bw, (FLAC__uint32)val, bits); } +inline FLAC__bool FLAC__bitwriter_write_raw_int64(FLAC__BitWriter *bw, FLAC__int64 val, uint32_t bits) +{ + FLAC__uint64 uval = val; + /* zero-out unused bits */ + if(bits < 64) + uval &= (~(UINT64_MAX << bits)); + return FLAC__bitwriter_write_raw_uint64(bw, uval, bits); +} + inline FLAC__bool FLAC__bitwriter_write_raw_uint32_little_endian(FLAC__BitWriter *bw, FLAC__uint32 val) { /* this doesn't need to be that fast as currently it is only used for vorbis comments */ @@ -432,6 +433,7 @@ FLAC__bool FLAC__bitwriter_write_unary_unsigned(FLAC__BitWriter *bw, uint32_t va FLAC__bitwriter_write_raw_uint32_nocheck(bw, 1, 1); } +#if 0 /* UNUSED */ uint32_t FLAC__bitwriter_rice_bits(FLAC__int32 val, uint32_t parameter) { FLAC__uint32 uval; @@ -446,7 +448,6 @@ uint32_t FLAC__bitwriter_rice_bits(FLAC__int32 val, uint32_t parameter) return 1 + parameter + (uval >> parameter); } -#if 0 /* UNUSED */ uint32_t FLAC__bitwriter_golomb_bits_signed(int val, uint32_t parameter) { uint32_t bits, msbs, uval; @@ -508,7 +509,6 @@ uint32_t FLAC__bitwriter_golomb_bits_unsigned(uint32_t uval, uint32_t parameter) } return bits; } -#endif /* UNUSED */ FLAC__bool FLAC__bitwriter_write_rice_signed(FLAC__BitWriter *bw, FLAC__int32 val, uint32_t parameter) { @@ -537,21 +537,77 @@ FLAC__bool FLAC__bitwriter_write_rice_signed(FLAC__BitWriter *bw, FLAC__int32 va FLAC__bitwriter_write_zeroes(bw, msbs) && /* write the unary MSBs */ FLAC__bitwriter_write_raw_uint32(bw, pattern, interesting_bits); /* write the unary end bit and binary LSBs */ } +#endif /* UNUSED */ + +#if (ENABLE_64_BIT_WORDS == 0) + +#define WIDE_ACCUM_TO_BW { \ + bw->accum = wide_accum >> FLAC__HALF_TEMP_BITS; \ + bw->buffer[bw->words++] = SWAP_BE_WORD_TO_HOST(bw->accum); \ + wide_accum <<= FLAC__HALF_TEMP_BITS; \ + bitpointer += FLAC__HALF_TEMP_BITS; \ +} + +#else + +#define WIDE_ACCUM_TO_BW { \ + FLAC__ASSERT(bw->bits % FLAC__HALF_TEMP_BITS == 0); \ + if(bw->bits == 0) { \ + bw->accum = wide_accum >> FLAC__HALF_TEMP_BITS; \ + wide_accum <<= FLAC__HALF_TEMP_BITS; \ + bw->bits = FLAC__HALF_TEMP_BITS; \ + } \ + else { \ + bw->accum <<= FLAC__HALF_TEMP_BITS; \ + bw->accum += wide_accum >> FLAC__HALF_TEMP_BITS; \ + bw->buffer[bw->words++] = SWAP_BE_WORD_TO_HOST(bw->accum); \ + wide_accum <<= FLAC__HALF_TEMP_BITS; \ + bw->bits = 0; \ + } \ + bitpointer += FLAC__HALF_TEMP_BITS; \ +} + +#endif FLAC__bool FLAC__bitwriter_write_rice_signed_block(FLAC__BitWriter *bw, const FLAC__int32 *vals, uint32_t nvals, uint32_t parameter) { const FLAC__uint32 mask1 = (FLAC__uint32)0xffffffff << parameter; /* we val|=mask1 to set the stop bit above it... */ const FLAC__uint32 mask2 = (FLAC__uint32)0xffffffff >> (31-parameter); /* ...then mask off the bits above the stop bit with val&=mask2 */ FLAC__uint32 uval; - uint32_t left; const uint32_t lsbits = 1 + parameter; uint32_t msbits, total_bits; + FLAC__bwtemp wide_accum = 0; + FLAC__uint32 bitpointer = FLAC__TEMP_BITS; FLAC__ASSERT(0 != bw); FLAC__ASSERT(0 != bw->buffer); FLAC__ASSERT(parameter < 31); /* WATCHOUT: code does not work with <32bit words; we can make things much faster with this assertion */ FLAC__ASSERT(FLAC__BITS_PER_WORD >= 32); +#if (ENABLE_64_BIT_WORDS == 0) + if(bw->bits > 0) { + bitpointer -= bw->bits; + wide_accum = (FLAC__bwtemp)(bw->accum) << bitpointer; + bw->bits = 0; + } +#else + if(bw->bits > 0 && bw->bits < FLAC__HALF_TEMP_BITS) { + bitpointer -= bw->bits; + wide_accum = bw->accum << bitpointer; + bw->bits = 0; + } + else if(bw->bits > FLAC__HALF_TEMP_BITS) { + bitpointer -= (bw->bits - FLAC__HALF_TEMP_BITS); + wide_accum = bw->accum << bitpointer; + bw->accum >>= (bw->bits - FLAC__HALF_TEMP_BITS); + bw->bits = FLAC__HALF_TEMP_BITS; + } +#endif + + /* Reserve one FLAC__TEMP_BITS per symbol, so checks for space are only necessary when very large symbols are encountered + * this might be considered wasteful, but is only at most 8kB more than necessary for a blocksize of 4096 */ + if(bw->capacity * FLAC__BITS_PER_WORD <= bw->words * FLAC__BITS_PER_WORD + nvals * FLAC__TEMP_BITS + bw->bits && !bitwriter_grow_(bw, nvals * FLAC__TEMP_BITS)) + return false; while(nvals) { /* fold signed to uint32_t; actual formula is: negative(v)? -2v-1 : 2v */ @@ -562,73 +618,87 @@ FLAC__bool FLAC__bitwriter_write_rice_signed_block(FLAC__BitWriter *bw, const FL msbits = uval >> parameter; total_bits = lsbits + msbits; - if(bw->bits && bw->bits + total_bits < FLAC__BITS_PER_WORD) { /* i.e. if the whole thing fits in the current bwword */ - /* ^^^ if bw->bits is 0 then we may have filled the buffer and have no free bwword to work in */ - bw->bits += total_bits; - uval |= mask1; /* set stop bit */ - uval &= mask2; /* mask off unused top bits */ - bw->accum <<= total_bits; - bw->accum |= uval; + uval |= mask1; /* set stop bit */ + uval &= mask2; /* mask off unused top bits */ + + + if(total_bits <= bitpointer) { + /* There is room enough to store the symbol whole at once */ + wide_accum |= (FLAC__bwtemp)(uval) << (bitpointer - total_bits); + bitpointer -= total_bits; + if(bitpointer <= FLAC__HALF_TEMP_BITS) { + /* A word is finished, copy the upper 32 bits of the wide_accum */ + WIDE_ACCUM_TO_BW + } } else { - /* slightly pessimistic size check but faster than "<= bw->words + (bw->bits+msbits+lsbits+FLAC__BITS_PER_WORD-1)/FLAC__BITS_PER_WORD" */ - /* OPT: pessimism may cause flurry of false calls to grow_ which eat up all savings before it */ - if(bw->capacity <= bw->words + bw->bits + msbits + 1 /* lsbits always fit in 1 bwword */ && !bitwriter_grow_(bw, total_bits)) - return false; - - if(msbits) { - /* first part gets to word alignment */ - if(bw->bits) { - left = FLAC__BITS_PER_WORD - bw->bits; - if(msbits < left) { - bw->accum <<= msbits; - bw->bits += msbits; - goto break1; - } - else { - bw->accum <<= left; - msbits -= left; - bw->buffer[bw->words++] = SWAP_BE_WORD_TO_HOST(bw->accum); - bw->bits = 0; - } - } - /* do whole words */ - while(msbits >= FLAC__BITS_PER_WORD) { - bw->buffer[bw->words++] = 0; - msbits -= FLAC__BITS_PER_WORD; - } - /* do any leftovers */ - if(msbits > 0) { - bw->accum = 0; - bw->bits = msbits; - } + /* The symbol needs to be split. This code isn't used often */ + /* First check for space in the bitwriter */ + if(total_bits > FLAC__TEMP_BITS) { + FLAC__uint32 oversize_in_bits = total_bits - FLAC__TEMP_BITS; + FLAC__uint32 capacity_needed = bw->words * FLAC__BITS_PER_WORD + bw->bits + nvals * FLAC__TEMP_BITS + oversize_in_bits; + if(bw->capacity * FLAC__BITS_PER_WORD <= capacity_needed && !bitwriter_grow_(bw, nvals * FLAC__TEMP_BITS + oversize_in_bits)) + return false; } -break1: - uval |= mask1; /* set stop bit */ - uval &= mask2; /* mask off unused top bits */ - - left = FLAC__BITS_PER_WORD - bw->bits; - if(lsbits < left) { - bw->accum <<= lsbits; - bw->accum |= uval; - bw->bits += lsbits; + if(msbits > bitpointer) { + /* We have a lot of 0 bits to write, first align with bitwriter word */ + msbits -= bitpointer - FLAC__HALF_TEMP_BITS; + bitpointer = FLAC__HALF_TEMP_BITS; + WIDE_ACCUM_TO_BW + while(msbits > bitpointer) { + /* As the accumulator is already zero, we only need to + * assign zeroes to the bitbuffer */ + WIDE_ACCUM_TO_BW + bitpointer -= FLAC__HALF_TEMP_BITS; + msbits -= FLAC__HALF_TEMP_BITS; + } + /* The remaining bits are zero, and the accumulator already is zero, + * so just subtract the number of bits from bitpointer. When storing, + * we can also just store 0 */ + bitpointer -= msbits; + if(bitpointer <= FLAC__HALF_TEMP_BITS) + WIDE_ACCUM_TO_BW } else { - /* if bw->bits == 0, left==FLAC__BITS_PER_WORD which will always - * be > lsbits (because of previous assertions) so it would have - * triggered the (lsbitsbits); - FLAC__ASSERT(left < FLAC__BITS_PER_WORD); - bw->accum <<= left; - bw->accum |= uval >> (bw->bits = lsbits - left); - bw->buffer[bw->words++] = SWAP_BE_WORD_TO_HOST(bw->accum); - bw->accum = uval; /* unused top bits can contain garbage */ + bitpointer -= msbits; + if(bitpointer <= FLAC__HALF_TEMP_BITS) + WIDE_ACCUM_TO_BW } + /* The lsbs + stop bit always fit 32 bit, so this code mirrors the code above */ + wide_accum |= (FLAC__bwtemp)(uval) << (bitpointer - lsbits); + bitpointer -= lsbits; + if(bitpointer <= FLAC__HALF_TEMP_BITS) { + /* A word is finished, copy the upper 32 bits of the wide_accum */ + WIDE_ACCUM_TO_BW + } } vals++; nvals--; } + /* Now fixup remainder of wide_accum */ +#if (ENABLE_64_BIT_WORDS == 0) + if(bitpointer < FLAC__TEMP_BITS) { + bw->accum = wide_accum >> bitpointer; + bw->bits = FLAC__TEMP_BITS - bitpointer; + } +#else + if(bitpointer < FLAC__TEMP_BITS) { + if(bw->bits == 0) { + bw->accum = wide_accum >> bitpointer; + bw->bits = FLAC__TEMP_BITS - bitpointer; + } + else if (bw->bits == FLAC__HALF_TEMP_BITS) { + bw->accum <<= FLAC__TEMP_BITS - bitpointer; + bw->accum |= (wide_accum >> bitpointer); + bw->bits = FLAC__HALF_TEMP_BITS + FLAC__TEMP_BITS - bitpointer; + } + else { + FLAC__ASSERT(0); + } + } +#endif + + return true; } @@ -880,5 +950,6 @@ extern FLAC__bool FLAC__bitwriter_write_zeroes(FLAC__BitWriter *bw, uint32_t bit extern FLAC__bool FLAC__bitwriter_write_raw_uint32(FLAC__BitWriter *bw, FLAC__uint32 val, uint32_t bits); extern FLAC__bool FLAC__bitwriter_write_raw_int32(FLAC__BitWriter *bw, FLAC__int32 val, uint32_t bits); extern FLAC__bool FLAC__bitwriter_write_raw_uint64(FLAC__BitWriter *bw, FLAC__uint64 val, uint32_t bits); +extern FLAC__bool FLAC__bitwriter_write_raw_int64(FLAC__BitWriter *bw, FLAC__int64 val, uint32_t bits); extern FLAC__bool FLAC__bitwriter_write_raw_uint32_little_endian(FLAC__BitWriter *bw, FLAC__uint32 val); extern FLAC__bool FLAC__bitwriter_write_byte_block(FLAC__BitWriter *bw, const FLAC__byte vals[], uint32_t nvals); diff --git a/modules/juce_audio_formats/codecs/flac/libFLAC/cpu.c b/modules/juce_audio_formats/codecs/flac/libFLAC/cpu.c index 95ff9765974c..d80a37f8a92f 100644 --- a/modules/juce_audio_formats/codecs/flac/libFLAC/cpu.c +++ b/modules/juce_audio_formats/codecs/flac/libFLAC/cpu.c @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2001-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -36,30 +36,28 @@ #include "include/private/cpu.h" #include "../compat.h" -//#include -//#include +#include +#include #if defined _MSC_VER -//#include /* for __cpuid() and _xgetbv() */ +#include /* for __cpuid() and _xgetbv() */ #elif defined __GNUC__ && defined HAVE_CPUID_H #include /* for __get_cpuid() and __get_cpuid_max() */ #endif #ifndef NDEBUG -//#include +#include #define dfprintf fprintf #else /* This is bad practice, it should be a static void empty function */ #define dfprintf(file, format, ...) #endif -#if defined FLAC__CPU_PPC -#if defined(__linux__) || (defined(__FreeBSD__) && (__FreeBSD__ >= 12)) +#if defined(HAVE_SYS_AUXV_H) #include #endif -#endif -#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && (defined FLAC__HAS_NASM || FLAC__HAS_X86INTRIN) && !defined FLAC__NO_ASM +#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN && !defined FLAC__NO_ASM /* these are flags in EDX of CPUID AX=00000001 */ static const uint32_t FLAC__CPUINFO_X86_CPUID_CMOV = 0x00008000; @@ -78,6 +76,7 @@ static const uint32_t FLAC__CPUINFO_X86_CPUID_FMA = 0x00001000; /* these are flags in EBX of CPUID AX=00000007 */ static const uint32_t FLAC__CPUINFO_X86_CPUID_AVX2 = 0x00000020; +static const uint32_t FLAC__CPUINFO_X86_CPUID_BMI2 = 0x00000100; #if FLAC__AVX_SUPPORTED static uint32_t @@ -101,8 +100,6 @@ cpu_have_cpuid(void) #if defined FLAC__CPU_X86_64 || defined __i686__ || defined __SSE__ || (defined _M_IX86_FP && _M_IX86_FP > 0) /* target CPU does have CPUID instruction */ return 1; -#elif defined FLAC__HAS_NASM - return FLAC__cpu_have_cpuid_asm_ia32(); #elif defined __GNUC__ && defined HAVE_CPUID_H if (__get_cpuid_max(0, 0) != 0) return 1; @@ -133,7 +130,7 @@ cpu_have_cpuid(void) } static void -cpuinfo_x86(FLAC__uint32 level, FLAC__uint32 *eax, FLAC__uint32 *ebx, FLAC__uint32 *ecx, FLAC__uint32 *edx) +cpuinfo_x86([[maybe_unused]] FLAC__uint32 level, FLAC__uint32 *eax, FLAC__uint32 *ebx, FLAC__uint32 *ecx, FLAC__uint32 *edx) { #if defined _MSC_VER int cpuinfo[4]; @@ -155,11 +152,7 @@ cpuinfo_x86(FLAC__uint32 level, FLAC__uint32 *eax, FLAC__uint32 *ebx, FLAC__uint __cpuid_count(level, 0, *eax, *ebx, *ecx, *edx); return; } -#elif defined FLAC__HAS_NASM && defined FLAC__CPU_IA32 - FLAC__cpu_info_asm_ia32(level, eax, ebx, ecx, edx); - return; #endif - ignoreUnused (level); *eax = *ebx = *ecx = *edx = 0; } @@ -168,10 +161,10 @@ cpuinfo_x86(FLAC__uint32 level, FLAC__uint32 *eax, FLAC__uint32 *ebx, FLAC__uint static void x86_cpu_info (FLAC__CPUInfo *info) { -#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && (defined FLAC__HAS_NASM || FLAC__HAS_X86INTRIN) && !defined FLAC__NO_ASM -#if FLAC__AVX_SUPPORTED +#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN && !defined FLAC__NO_ASM + #if FLAC__AVX_SUPPORTED FLAC__bool x86_osxsave = false; -#endif + #endif FLAC__bool os_avx = false; FLAC__uint32 flags_eax, flags_ebx, flags_ecx, flags_edx; @@ -192,13 +185,14 @@ x86_cpu_info (FLAC__CPUInfo *info) info->x86.sse41 = (flags_ecx & FLAC__CPUINFO_X86_CPUID_SSE41) ? true : false; info->x86.sse42 = (flags_ecx & FLAC__CPUINFO_X86_CPUID_SSE42) ? true : false; -#if FLAC__AVX_SUPPORTED + #if (FLAC__AVX_SUPPORTED) x86_osxsave = (flags_ecx & FLAC__CPUINFO_X86_CPUID_OSXSAVE) ? true : false; info->x86.avx = (flags_ecx & FLAC__CPUINFO_X86_CPUID_AVX ) ? true : false; info->x86.fma = (flags_ecx & FLAC__CPUINFO_X86_CPUID_FMA ) ? true : false; cpuinfo_x86(7, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx); info->x86.avx2 = (flags_ebx & FLAC__CPUINFO_X86_CPUID_AVX2 ) ? true : false; -#endif + info->x86.bmi2 = (flags_ebx & FLAC__CPUINFO_X86_CPUID_BMI2 ) ? true : false; + #endif #if defined FLAC__CPU_IA32 dfprintf(stderr, "CPU info (IA-32):\n", ""); @@ -218,6 +212,7 @@ x86_cpu_info (FLAC__CPUInfo *info) dfprintf(stderr, " AVX ........ %c\n", info->x86.avx ? 'Y' : 'n'); dfprintf(stderr, " FMA ........ %c\n", info->x86.fma ? 'Y' : 'n'); dfprintf(stderr, " AVX2 ....... %c\n", info->x86.avx2 ? 'Y' : 'n'); + dfprintf(stderr, " BMI2 ....... %c\n", info->x86.bmi2 ? 'Y' : 'n'); } /* @@ -228,7 +223,6 @@ x86_cpu_info (FLAC__CPUInfo *info) os_avx = true; } #endif - if (os_avx) { dfprintf(stderr, " AVX OS sup . %c\n", info->x86.avx ? 'Y' : 'n'); } @@ -243,47 +237,6 @@ x86_cpu_info (FLAC__CPUInfo *info) #endif } -static void -ppc_cpu_info (FLAC__CPUInfo *info) -{ -#if defined FLAC__CPU_PPC -#ifndef PPC_FEATURE2_ARCH_3_00 -#define PPC_FEATURE2_ARCH_3_00 0x00800000 -#endif - -#ifndef PPC_FEATURE2_ARCH_2_07 -#define PPC_FEATURE2_ARCH_2_07 0x80000000 -#endif - -#ifdef __linux__ - if (getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_3_00) { - info->ppc.arch_3_00 = true; - } else if (getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_2_07) { - info->ppc.arch_2_07 = true; - } -#elif defined(__FreeBSD__) && (__FreeBSD__ >= 12) - long hwcaps; - /* elf_aux_info() appeared in FreeBSD 12.0 */ - elf_aux_info(AT_HWCAP2, &hwcaps, sizeof(hwcaps)); - if (hwcaps & PPC_FEATURE2_ARCH_3_00) { - info->ppc.arch_3_00 = true; - } else if (hwcaps & PPC_FEATURE2_ARCH_2_07) { - info->ppc.arch_2_07 = true; - } -#elif defined(__APPLE__) - /* no Mac OS X version supports CPU with Power AVI v2.07 or better */ - info->ppc.arch_2_07 = false; - info->ppc.arch_3_00 = false; -#else -#error Unsupported platform! Please add support for reading ppc hwcaps. -#endif - -#else - info->ppc.arch_2_07 = false; - info->ppc.arch_3_00 = false; -#endif -} - void FLAC__cpu_info (FLAC__CPUInfo *info) { memset(info, 0, sizeof(*info)); @@ -292,8 +245,6 @@ void FLAC__cpu_info (FLAC__CPUInfo *info) info->type = FLAC__CPUINFO_TYPE_IA32; #elif defined FLAC__CPU_X86_64 info->type = FLAC__CPUINFO_TYPE_X86_64; -#elif defined FLAC__CPU_PPC - info->type = FLAC__CPUINFO_TYPE_PPC; #else info->type = FLAC__CPUINFO_TYPE_UNKNOWN; #endif @@ -303,9 +254,6 @@ void FLAC__cpu_info (FLAC__CPUInfo *info) case FLAC__CPUINFO_TYPE_X86_64: x86_cpu_info (info); break; - case FLAC__CPUINFO_TYPE_PPC: - ppc_cpu_info (info); - break; default: info->use_asm = false; break; diff --git a/modules/juce_audio_formats/codecs/flac/libFLAC/crc.c b/modules/juce_audio_formats/codecs/flac/libFLAC/crc.c index 81f426d0de76..c8ab234168d3 100644 --- a/modules/juce_audio_formats/codecs/flac/libFLAC/crc.c +++ b/modules/juce_audio_formats/codecs/flac/libFLAC/crc.c @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2018 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/modules/juce_audio_formats/codecs/flac/libFLAC/deduplication/bitreader_read_rice_signed_block.c b/modules/juce_audio_formats/codecs/flac/libFLAC/deduplication/bitreader_read_rice_signed_block.c new file mode 100644 index 000000000000..d0219f7c6742 --- /dev/null +++ b/modules/juce_audio_formats/codecs/flac/libFLAC/deduplication/bitreader_read_rice_signed_block.c @@ -0,0 +1,143 @@ +{ + /* try and get br->consumed_words and br->consumed_bits into register; + * must remember to flush them back to *br before calling other + * bitreader functions that use them, and before returning */ + uint32_t cwords, words, lsbs, msbs, x, y, limit; + uint32_t ucbits; /* keep track of the number of unconsumed bits in word */ + brword b; + int *val, *end; + + FLAC__ASSERT(0 != br); + FLAC__ASSERT(0 != br->buffer); + /* WATCHOUT: code does not work with <32bit words; we can make things much faster with this assertion */ + FLAC__ASSERT(FLAC__BITS_PER_WORD >= 32); + FLAC__ASSERT(parameter < 32); + /* the above two asserts also guarantee that the binary part never straddles more than 2 words, so we don't have to loop to read it */ + + limit = UINT32_MAX >> parameter; /* Maximal msbs that can occur with residual bounded to int32_t */ + + val = vals; + end = vals + nvals; + + if(parameter == 0) { + while(val < end) { + /* read the unary MSBs and end bit */ + if(!FLAC__bitreader_read_unary_unsigned(br, &msbs)) + return false; + /* Checking limit here would be overzealous: coding UINT32_MAX + * with parameter == 0 would take 4GiB */ + *val++ = (int)(msbs >> 1) ^ -(int)(msbs & 1); + } + + return true; + } + + FLAC__ASSERT(parameter > 0); + + cwords = br->consumed_words; + words = br->words; + + /* if we've not consumed up to a partial tail word... */ + if(cwords >= words) { + x = 0; + goto process_tail; + } + + ucbits = FLAC__BITS_PER_WORD - br->consumed_bits; + b = br->buffer[cwords] << br->consumed_bits; /* keep unconsumed bits aligned to left */ + + while(val < end) { + /* read the unary MSBs and end bit */ + x = y = COUNT_ZERO_MSBS2(b); + if(x == FLAC__BITS_PER_WORD) { + x = ucbits; + do { + /* didn't find stop bit yet, have to keep going... */ + cwords++; + if (cwords >= words) + goto incomplete_msbs; + b = br->buffer[cwords]; + y = COUNT_ZERO_MSBS2(b); + x += y; + } while(y == FLAC__BITS_PER_WORD); + } + b <<= y; + b <<= 1; /* account for stop bit */ + ucbits = (ucbits - x - 1) % FLAC__BITS_PER_WORD; + msbs = x; + + if(x > limit) + return false; + + /* read the binary LSBs */ + x = (FLAC__uint32)(b >> (FLAC__BITS_PER_WORD - parameter)); /* parameter < 32, so we can cast to 32-bit uint32_t */ + if(parameter <= ucbits) { + ucbits -= parameter; + b <<= parameter; + } else { + /* there are still bits left to read, they will all be in the next word */ + cwords++; + if (cwords >= words) + goto incomplete_lsbs; + b = br->buffer[cwords]; + ucbits += FLAC__BITS_PER_WORD - parameter; + x |= (FLAC__uint32)(b >> ucbits); + b <<= FLAC__BITS_PER_WORD - ucbits; + } + lsbs = x; + + /* compose the value */ + x = (msbs << parameter) | lsbs; + *val++ = (int)(x >> 1) ^ -(int)(x & 1); + + continue; + + /* at this point we've eaten up all the whole words */ +process_tail: + do { + if(0) { +incomplete_msbs: + br->consumed_bits = 0; + br->consumed_words = cwords; + } + + /* read the unary MSBs and end bit */ + if(!FLAC__bitreader_read_unary_unsigned(br, &msbs)) + return false; + msbs += x; + x = ucbits = 0; + + if(0) { +incomplete_lsbs: + br->consumed_bits = 0; + br->consumed_words = cwords; + } + + /* read the binary LSBs */ + if(!FLAC__bitreader_read_raw_uint32(br, &lsbs, parameter - ucbits)) + return false; + lsbs = x | lsbs; + + /* compose the value */ + x = (msbs << parameter) | lsbs; + *val++ = (int)(x >> 1) ^ -(int)(x & 1); + x = 0; + + cwords = br->consumed_words; + words = br->words; + ucbits = FLAC__BITS_PER_WORD - br->consumed_bits; + b = cwords < br->capacity ? br->buffer[cwords] << br->consumed_bits : 0; + } while(cwords >= words && val < end); + } + + if(ucbits == 0 && cwords < words) { + /* don't leave the head word with no unconsumed bits */ + cwords++; + ucbits = FLAC__BITS_PER_WORD; + } + + br->consumed_bits = FLAC__BITS_PER_WORD - ucbits; + br->consumed_words = cwords; + + return true; +} diff --git a/modules/juce_audio_formats/codecs/flac/libFLAC/deduplication/lpc_compute_autocorrelation_intrin.c b/modules/juce_audio_formats/codecs/flac/libFLAC/deduplication/lpc_compute_autocorrelation_intrin.c new file mode 100644 index 000000000000..57b1d6781630 --- /dev/null +++ b/modules/juce_audio_formats/codecs/flac/libFLAC/deduplication/lpc_compute_autocorrelation_intrin.c @@ -0,0 +1,14 @@ + int i, j; + (void) lag; + FLAC__ASSERT(lag <= MAX_LAG); + + for(i = 0; i < MAX_LAG; i++) + autoc[i] = 0.0; + + for(i = 0; i < MAX_LAG; i++) + for(j = 0; j <= i; j++) + autoc[j] += (double)data[i] * (double)data[i-j]; + + for(i = MAX_LAG; i < (int)data_len; i++) + for(j = 0; j < MAX_LAG; j++) + autoc[j] += (double)data[i] * (double)data[i-j]; diff --git a/modules/juce_audio_formats/codecs/flac/libFLAC/deduplication/lpc_compute_autocorrelation_intrin_neon.c b/modules/juce_audio_formats/codecs/flac/libFLAC/deduplication/lpc_compute_autocorrelation_intrin_neon.c new file mode 100644 index 000000000000..7970f6079806 --- /dev/null +++ b/modules/juce_audio_formats/codecs/flac/libFLAC/deduplication/lpc_compute_autocorrelation_intrin_neon.c @@ -0,0 +1,70 @@ + int i; + float64x2_t sum0 = vdupq_n_f64(0.0f); + float64x2_t sum1 = vdupq_n_f64(0.0f); + float64x2_t sum2 = vdupq_n_f64(0.0f); + float64x2_t sum3 = vdupq_n_f64(0.0f); + float64x2_t d0 = vdupq_n_f64(0.0f); + float64x2_t d1 = vdupq_n_f64(0.0f); + float64x2_t d2 = vdupq_n_f64(0.0f); + float64x2_t d3 = vdupq_n_f64(0.0f); +#if MAX_LAG > 8 + float64x2_t sum4 = vdupq_n_f64(0.0f); + float64x2_t d4 = vdupq_n_f64(0.0f); +#endif +#if MAX_LAG > 10 + float64x2_t sum5 = vdupq_n_f64(0.0f); + float64x2_t sum6 = vdupq_n_f64(0.0f); + float64x2_t d5 = vdupq_n_f64(0.0f); + float64x2_t d6 = vdupq_n_f64(0.0f); +#endif + float64x2_t d; + + (void)lag; + FLAC__ASSERT(lag <= MAX_LAG); + + // Loop backwards through samples from data_len to 0 + for (i = data_len - 1; i >= 0; i--) + { + d = vdupq_n_f64(data[i]); // Create vector with 2 entries data[i] + + // The next 6 lines of code right-shift the elements through the 7 vectors d0..d6. + // The 7th line adds the newly loaded element to d0. This works like a stack, where + // data[i] is pushed onto the stack every time and the 9th element falls off +#if MAX_LAG > 10 + d6 = vextq_f64(d5,d6,1); + d5 = vextq_f64(d4,d5,1); +#endif +#if MAX_LAG > 8 + d4 = vextq_f64(d3,d4,1); +#endif + d3 = vextq_f64(d2,d3,1); + d2 = vextq_f64(d1,d2,1); + d1 = vextq_f64(d0,d1,1); + d0 = vextq_f64(d,d0,1); + + // Fused multiply-add sum += d * d0..d6 + sum0 = vfmaq_f64(sum0, d, d0); + sum1 = vfmaq_f64(sum1, d, d1); + sum2 = vfmaq_f64(sum2, d, d2); + sum3 = vfmaq_f64(sum3, d, d3); +#if MAX_LAG > 8 + sum4 = vfmaq_f64(sum4, d, d4); +#endif +#if MAX_LAG > 10 + sum5 = vfmaq_f64(sum5, d, d5); + sum6 = vfmaq_f64(sum6, d, d6); +#endif + } + + // Store sum0..sum6 in autoc[0..14] + vst1q_f64(autoc, sum0); + vst1q_f64(autoc + 2, sum1); + vst1q_f64(autoc + 4, sum2); + vst1q_f64(autoc + 6, sum3); +#if MAX_LAG > 8 + vst1q_f64(autoc + 8, sum4); +#endif +#if MAX_LAG > 10 + vst1q_f64(autoc + 10, sum5); + vst1q_f64(autoc + 12, sum6); +#endif diff --git a/modules/juce_audio_formats/codecs/flac/libFLAC/fixed.c b/modules/juce_audio_formats/codecs/flac/libFLAC/fixed.c index a31c8fffaa96..23028fbd0e6a 100644 --- a/modules/juce_audio_formats/codecs/flac/libFLAC/fixed.c +++ b/modules/juce_audio_formats/codecs/flac/libFLAC/fixed.c @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -39,6 +39,7 @@ #include "../compat.h" #include "include/private/bitmath.h" #include "include/private/fixed.h" + #include "../assert.h" #ifdef local_abs @@ -46,6 +47,11 @@ #endif #define local_abs(x) ((uint32_t)((x)<0? -(x) : (x))) +#ifdef local_abs64 +#undef local_abs64 +#endif +#define local_abs64(x) ((uint64_t)((x)<0? -(x) : (x))) + #ifdef FLAC__INTEGER_ONLY_LIBRARY /* rbps stands for residual bits per sample * @@ -218,14 +224,23 @@ uint32_t FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], uint32_t d uint32_t FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]) #endif { + FLAC__uint32 total_error_0 = 0, total_error_1 = 0, total_error_2 = 0, total_error_3 = 0, total_error_4 = 0; + uint32_t order; +#if 0 + /* This code has been around a long time, and was written when compilers weren't able + * to vectorize code. These days, compilers are better in optimizing the next block + * which is also much more readable + */ FLAC__int32 last_error_0 = data[-1]; FLAC__int32 last_error_1 = data[-1] - data[-2]; FLAC__int32 last_error_2 = last_error_1 - (data[-2] - data[-3]); FLAC__int32 last_error_3 = last_error_2 - (data[-2] - 2*data[-3] + data[-4]); FLAC__int32 error, save; - FLAC__uint32 total_error_0 = 0, total_error_1 = 0, total_error_2 = 0, total_error_3 = 0, total_error_4 = 0; - uint32_t i, order; - + uint32_t i; + /* total_error_* are 64-bits to avoid overflow when encoding + * erratic signals when the bits-per-sample and blocksize are + * large. + */ for(i = 0; i < data_len; i++) { error = data[i] ; total_error_0 += local_abs(error); save = error; error -= last_error_0; total_error_1 += local_abs(error); last_error_0 = save; save = error; @@ -233,14 +248,26 @@ uint32_t FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], uint32_t d error -= last_error_2; total_error_3 += local_abs(error); last_error_2 = save; save = error; error -= last_error_3; total_error_4 += local_abs(error); last_error_3 = save; } +#else + int i; + for(i = 0; i < (int)data_len; i++) { + total_error_0 += local_abs(data[i]); + total_error_1 += local_abs(data[i] - data[i-1]); + total_error_2 += local_abs(data[i] - 2 * data[i-1] + data[i-2]); + total_error_3 += local_abs(data[i] - 3 * data[i-1] + 3 * data[i-2] - data[i-3]); + total_error_4 += local_abs(data[i] - 4 * data[i-1] + 6 * data[i-2] - 4 * data[i-3] + data[i-4]); + } +#endif + - if(total_error_0 < flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4)) + /* prefer lower order */ + if(total_error_0 <= flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4)) order = 0; - else if(total_error_1 < flac_min(flac_min(total_error_2, total_error_3), total_error_4)) + else if(total_error_1 <= flac_min(flac_min(total_error_2, total_error_3), total_error_4)) order = 1; - else if(total_error_2 < flac_min(total_error_3, total_error_4)) + else if(total_error_2 <= flac_min(total_error_3, total_error_4)) order = 2; - else if(total_error_3 < total_error_4) + else if(total_error_3 <= total_error_4) order = 3; else order = 4; @@ -276,33 +303,26 @@ uint32_t FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], uint3 uint32_t FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]) #endif { - FLAC__int32 last_error_0 = data[-1]; - FLAC__int32 last_error_1 = data[-1] - data[-2]; - FLAC__int32 last_error_2 = last_error_1 - (data[-2] - data[-3]); - FLAC__int32 last_error_3 = last_error_2 - (data[-2] - 2*data[-3] + data[-4]); - FLAC__int32 error, save; - /* total_error_* are 64-bits to avoid overflow when encoding - * erratic signals when the bits-per-sample and blocksize are - * large. - */ FLAC__uint64 total_error_0 = 0, total_error_1 = 0, total_error_2 = 0, total_error_3 = 0, total_error_4 = 0; - uint32_t i, order; + uint32_t order; + int i; - for(i = 0; i < data_len; i++) { - error = data[i] ; total_error_0 += local_abs(error); save = error; - error -= last_error_0; total_error_1 += local_abs(error); last_error_0 = save; save = error; - error -= last_error_1; total_error_2 += local_abs(error); last_error_1 = save; save = error; - error -= last_error_2; total_error_3 += local_abs(error); last_error_2 = save; save = error; - error -= last_error_3; total_error_4 += local_abs(error); last_error_3 = save; + for(i = 0; i < (int)data_len; i++) { + total_error_0 += local_abs(data[i]); + total_error_1 += local_abs(data[i] - data[i-1]); + total_error_2 += local_abs(data[i] - 2 * data[i-1] + data[i-2]); + total_error_3 += local_abs(data[i] - 3 * data[i-1] + 3 * data[i-2] - data[i-3]); + total_error_4 += local_abs(data[i] - 4 * data[i-1] + 6 * data[i-2] - 4 * data[i-3] + data[i-4]); } - if(total_error_0 < flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4)) + /* prefer lower order */ + if(total_error_0 <= flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4)) order = 0; - else if(total_error_1 < flac_min(flac_min(total_error_2, total_error_3), total_error_4)) + else if(total_error_1 <= flac_min(flac_min(total_error_2, total_error_3), total_error_4)) order = 1; - else if(total_error_2 < flac_min(total_error_3, total_error_4)) + else if(total_error_2 <= flac_min(total_error_3, total_error_4)) order = 2; - else if(total_error_3 < total_error_4) + else if(total_error_3 <= total_error_4) order = 3; else order = 4; @@ -332,6 +352,121 @@ uint32_t FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], uint3 return order; } +#ifndef FLAC__INTEGER_ONLY_LIBRARY +#define CHECK_ORDER_IS_VALID(macro_order) \ +if(order_##macro_order##_is_valid && total_error_##macro_order < smallest_error) { \ + order = macro_order; \ + smallest_error = total_error_##macro_order ; \ + residual_bits_per_sample[ macro_order ] = (float)((total_error_0 > 0) ? log(M_LN2 * (double)total_error_0 / (double)data_len) / M_LN2 : 0.0); \ +} \ +else \ + residual_bits_per_sample[ macro_order ] = 34.0f; +#else +#define CHECK_ORDER_IS_VALID(macro_order) \ +if(order_##macro_order##_is_valid && total_error_##macro_order < smallest_error) { \ + order = macro_order; \ + smallest_error = total_error_##macro_order ; \ + residual_bits_per_sample[ macro_order ] = (total_error_##macro_order > 0) ? local__compute_rbps_wide_integerized(total_error_##macro_order, data_len) : 0; \ +} \ +else \ + residual_bits_per_sample[ macro_order ] = 34 * FLAC__FP_ONE; +#endif + + +#ifndef FLAC__INTEGER_ONLY_LIBRARY +uint32_t FLAC__fixed_compute_best_predictor_limit_residual(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]) +#else +uint32_t FLAC__fixed_compute_best_predictor_limit_residual(const FLAC__int32 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]) +#endif +{ + FLAC__uint64 total_error_0 = 0, total_error_1 = 0, total_error_2 = 0, total_error_3 = 0, total_error_4 = 0, smallest_error = UINT64_MAX; + FLAC__uint64 error_0, error_1, error_2, error_3, error_4; + FLAC__bool order_0_is_valid = true, order_1_is_valid = true, order_2_is_valid = true, order_3_is_valid = true, order_4_is_valid = true; + uint32_t order = 0; + int i; + + for(i = -4; i < (int)data_len; i++) { + error_0 = local_abs64((FLAC__int64)data[i]); + error_1 = (i > -4) ? local_abs64((FLAC__int64)data[i] - data[i-1]) : 0 ; + error_2 = (i > -3) ? local_abs64((FLAC__int64)data[i] - 2 * (FLAC__int64)data[i-1] + data[i-2]) : 0; + error_3 = (i > -2) ? local_abs64((FLAC__int64)data[i] - 3 * (FLAC__int64)data[i-1] + 3 * (FLAC__int64)data[i-2] - data[i-3]) : 0; + error_4 = (i > -1) ? local_abs64((FLAC__int64)data[i] - 4 * (FLAC__int64)data[i-1] + 6 * (FLAC__int64)data[i-2] - 4 * (FLAC__int64)data[i-3] + data[i-4]) : 0; + + total_error_0 += error_0; + total_error_1 += error_1; + total_error_2 += error_2; + total_error_3 += error_3; + total_error_4 += error_4; + + /* residual must not be INT32_MIN because abs(INT32_MIN) is undefined */ + if(error_0 > INT32_MAX) + order_0_is_valid = false; + if(error_1 > INT32_MAX) + order_1_is_valid = false; + if(error_2 > INT32_MAX) + order_2_is_valid = false; + if(error_3 > INT32_MAX) + order_3_is_valid = false; + if(error_4 > INT32_MAX) + order_4_is_valid = false; + } + + CHECK_ORDER_IS_VALID(0); + CHECK_ORDER_IS_VALID(1); + CHECK_ORDER_IS_VALID(2); + CHECK_ORDER_IS_VALID(3); + CHECK_ORDER_IS_VALID(4); + + return order; +} + +#ifndef FLAC__INTEGER_ONLY_LIBRARY +uint32_t FLAC__fixed_compute_best_predictor_limit_residual_33bit(const FLAC__int64 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]) +#else +uint32_t FLAC__fixed_compute_best_predictor_limit_residual_33bit(const FLAC__int64 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]) +#endif +{ + FLAC__uint64 total_error_0 = 0, total_error_1 = 0, total_error_2 = 0, total_error_3 = 0, total_error_4 = 0, smallest_error = UINT64_MAX; + FLAC__uint64 error_0, error_1, error_2, error_3, error_4; + FLAC__bool order_0_is_valid = true, order_1_is_valid = true, order_2_is_valid = true, order_3_is_valid = true, order_4_is_valid = true; + uint32_t order = 0; + int i; + + for(i = -4; i < (int)data_len; i++) { + error_0 = local_abs64(data[i]); + error_1 = (i > -4) ? local_abs64(data[i] - data[i-1]) : 0 ; + error_2 = (i > -3) ? local_abs64(data[i] - 2 * data[i-1] + data[i-2]) : 0; + error_3 = (i > -2) ? local_abs64(data[i] - 3 * data[i-1] + 3 * data[i-2] - data[i-3]) : 0; + error_4 = (i > -1) ? local_abs64(data[i] - 4 * data[i-1] + 6 * data[i-2] - 4 * data[i-3] + data[i-4]) : 0; + + total_error_0 += error_0; + total_error_1 += error_1; + total_error_2 += error_2; + total_error_3 += error_3; + total_error_4 += error_4; + + /* residual must not be INT32_MIN because abs(INT32_MIN) is undefined */ + if(error_0 > INT32_MAX) + order_0_is_valid = false; + if(error_1 > INT32_MAX) + order_1_is_valid = false; + if(error_2 > INT32_MAX) + order_2_is_valid = false; + if(error_3 > INT32_MAX) + order_3_is_valid = false; + if(error_4 > INT32_MAX) + order_4_is_valid = false; + } + + CHECK_ORDER_IS_VALID(0); + CHECK_ORDER_IS_VALID(1); + CHECK_ORDER_IS_VALID(2); + CHECK_ORDER_IS_VALID(3); + CHECK_ORDER_IS_VALID(4); + + return order; +} + void FLAC__fixed_compute_residual(const FLAC__int32 data[], uint32_t data_len, uint32_t order, FLAC__int32 residual[]) { const int idata_len = (int)data_len; @@ -363,6 +498,76 @@ void FLAC__fixed_compute_residual(const FLAC__int32 data[], uint32_t data_len, u } } +void FLAC__fixed_compute_residual_wide(const FLAC__int32 data[], uint32_t data_len, uint32_t order, FLAC__int32 residual[]) +{ + const int idata_len = (int)data_len; + int i; + + switch(order) { + case 0: + FLAC__ASSERT(sizeof(residual[0]) == sizeof(data[0])); + memcpy(residual, data, sizeof(residual[0])*data_len); + break; + case 1: + for(i = 0; i < idata_len; i++) + residual[i] = (FLAC__int64)data[i] - data[i-1]; + break; + case 2: + for(i = 0; i < idata_len; i++) + residual[i] = (FLAC__int64)data[i] - 2*(FLAC__int64)data[i-1] + data[i-2]; + break; + case 3: + for(i = 0; i < idata_len; i++) + residual[i] = (FLAC__int64)data[i] - 3*(FLAC__int64)data[i-1] + 3*(FLAC__int64)data[i-2] - data[i-3]; + break; + case 4: + for(i = 0; i < idata_len; i++) + residual[i] = (FLAC__int64)data[i] - 4*(FLAC__int64)data[i-1] + 6*(FLAC__int64)data[i-2] - 4*(FLAC__int64)data[i-3] + data[i-4]; + break; + default: + FLAC__ASSERT(0); + } +} + +void FLAC__fixed_compute_residual_wide_33bit(const FLAC__int64 data[], uint32_t data_len, uint32_t order, FLAC__int32 residual[]) +{ + const int idata_len = (int)data_len; + int i; + + switch(order) { + case 0: + for(i = 0; i < idata_len; i++) + residual[i] = data[i]; + break; + case 1: + for(i = 0; i < idata_len; i++) + residual[i] = data[i] - data[i-1]; + break; + case 2: + for(i = 0; i < idata_len; i++) + residual[i] = data[i] - 2*data[i-1] + data[i-2]; + break; + case 3: + for(i = 0; i < idata_len; i++) + residual[i] = data[i] - 3*data[i-1] + 3*data[i-2] - data[i-3]; + break; + case 4: + for(i = 0; i < idata_len; i++) + residual[i] = data[i] - 4*data[i-1] + 6*data[i-2] - 4*data[i-3] + data[i-4]; + break; + default: + FLAC__ASSERT(0); + } +} + +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && !defined(FUZZING_BUILD_MODE_FLAC_SANITIZE_SIGNED_INTEGER_OVERFLOW) +/* The attribute below is to silence the undefined sanitizer of oss-fuzz. + * Because fuzzing feeds bogus predictors and residual samples to the + * decoder, having overflows in this section is unavoidable. Also, + * because the calculated values are audio path only, there is no + * potential for security problems */ +__attribute__((no_sanitize("signed-integer-overflow"))) +#endif void FLAC__fixed_restore_signal(const FLAC__int32 residual[], uint32_t data_len, uint32_t order, FLAC__int32 data[]) { int i, idata_len = (int)data_len; @@ -392,3 +597,71 @@ void FLAC__fixed_restore_signal(const FLAC__int32 residual[], uint32_t data_len, FLAC__ASSERT(0); } } + +void FLAC__fixed_restore_signal_wide(const FLAC__int32 residual[], uint32_t data_len, uint32_t order, FLAC__int32 data[]) +{ + int i, idata_len = (int)data_len; + + switch(order) { + case 0: + FLAC__ASSERT(sizeof(residual[0]) == sizeof(data[0])); + memcpy(data, residual, sizeof(residual[0])*data_len); + break; + case 1: + for(i = 0; i < idata_len; i++) + data[i] = (FLAC__int64)residual[i] + (FLAC__int64)data[i-1]; + break; + case 2: + for(i = 0; i < idata_len; i++) + data[i] = (FLAC__int64)residual[i] + 2*(FLAC__int64)data[i-1] - (FLAC__int64)data[i-2]; + break; + case 3: + for(i = 0; i < idata_len; i++) + data[i] = (FLAC__int64)residual[i] + 3*(FLAC__int64)data[i-1] - 3*(FLAC__int64)data[i-2] + (FLAC__int64)data[i-3]; + break; + case 4: + for(i = 0; i < idata_len; i++) + data[i] = (FLAC__int64)residual[i] + 4*(FLAC__int64)data[i-1] - 6*(FLAC__int64)data[i-2] + 4*(FLAC__int64)data[i-3] - (FLAC__int64)data[i-4]; + break; + default: + FLAC__ASSERT(0); + } +} + +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && !defined(FUZZING_BUILD_MODE_FLAC_SANITIZE_SIGNED_INTEGER_OVERFLOW) +/* The attribute below is to silence the undefined sanitizer of oss-fuzz. + * Because fuzzing feeds bogus predictors and residual samples to the + * decoder, having overflows in this section is unavoidable. Also, + * because the calculated values are audio path only, there is no + * potential for security problems */ +__attribute__((no_sanitize("signed-integer-overflow"))) +#endif +void FLAC__fixed_restore_signal_wide_33bit(const FLAC__int32 residual[], uint32_t data_len, uint32_t order, FLAC__int64 data[]) +{ + int i, idata_len = (int)data_len; + + switch(order) { + case 0: + for(i = 0; i < idata_len; i++) + data[i] = residual[i]; + break; + case 1: + for(i = 0; i < idata_len; i++) + data[i] = (FLAC__int64)residual[i] + data[i-1]; + break; + case 2: + for(i = 0; i < idata_len; i++) + data[i] = (FLAC__int64)residual[i] + 2*data[i-1] - data[i-2]; + break; + case 3: + for(i = 0; i < idata_len; i++) + data[i] = (FLAC__int64)residual[i] + 3*data[i-1] - 3*data[i-2] + data[i-3]; + break; + case 4: + for(i = 0; i < idata_len; i++) + data[i] = (FLAC__int64)residual[i] + 4*data[i-1] - 6*data[i-2] + 4*data[i-3] - data[i-4]; + break; + default: + FLAC__ASSERT(0); + } +} diff --git a/modules/juce_audio_formats/codecs/flac/libFLAC/float.c b/modules/juce_audio_formats/codecs/flac/libFLAC/float.c index 86388c3de6eb..dfa7c9377e14 100644 --- a/modules/juce_audio_formats/codecs/flac/libFLAC/float.c +++ b/modules/juce_audio_formats/codecs/flac/libFLAC/float.c @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2004-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/modules/juce_audio_formats/codecs/flac/libFLAC/format.c b/modules/juce_audio_formats/codecs/flac/libFLAC/format.c index cec9b4993cc6..66b88faaf0da 100644 --- a/modules/juce_audio_formats/codecs/flac/libFLAC/format.c +++ b/modules/juce_audio_formats/codecs/flac/libFLAC/format.c @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -43,10 +43,20 @@ #include "../compat.h" #include "include/private/format.h" + +#if (defined GIT_COMMIT_HASH && defined GIT_COMMIT_DATE) +# ifdef GIT_COMMIT_TAG +FLAC_API const char *FLAC__VERSION_STRING = GIT_COMMIT_TAG; +FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC " GIT_COMMIT_TAG " " GIT_COMMIT_DATE; +# else +FLAC_API const char *FLAC__VERSION_STRING = "git-" GIT_COMMIT_HASH " " GIT_COMMIT_DATE; +FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC git-" GIT_COMMIT_HASH " " GIT_COMMIT_DATE; +# endif +#else /* PACKAGE_VERSION should come from configure */ FLAC_API const char *FLAC__VERSION_STRING = PACKAGE_VERSION; - -FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC " PACKAGE_VERSION " 20220220"; +FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC " PACKAGE_VERSION " 20230623"; +#endif FLAC_API const FLAC__byte FLAC__STREAM_SYNC_STRING[4] = { 'f','L','a','C' }; FLAC_API const uint32_t FLAC__STREAM_SYNC = 0x664C6143; @@ -198,7 +208,7 @@ FLAC_API const char * const FLAC__StreamMetadata_Picture_TypeString[] = { FLAC_API FLAC__bool FLAC__format_sample_rate_is_valid(uint32_t sample_rate) { - if(sample_rate == 0 || sample_rate > FLAC__MAX_SAMPLE_RATE) { + if(sample_rate > FLAC__MAX_SAMPLE_RATE) { return false; } else @@ -217,12 +227,10 @@ FLAC_API FLAC__bool FLAC__format_blocksize_is_subset(uint32_t blocksize, uint32_ FLAC_API FLAC__bool FLAC__format_sample_rate_is_subset(uint32_t sample_rate) { - if( - !FLAC__format_sample_rate_is_valid(sample_rate) || - ( - sample_rate >= (1u << 16) && - !(sample_rate % 1000 == 0 || sample_rate % 10 == 0) - ) + if( // sample rate is not subset if + !FLAC__format_sample_rate_is_valid(sample_rate) || // sample rate is invalid or + sample_rate >= ((1u << 16) * 10) || // sample rate is larger then or equal to 655360 or + (sample_rate >= (1u << 16) && sample_rate % 10 != 0) //sample rate is >= 65536 and not divisible by 10 ) { return false; } @@ -239,6 +247,9 @@ FLAC_API FLAC__bool FLAC__format_seektable_is_legal(const FLAC__StreamMetadata_S FLAC__ASSERT(0 != seek_table); + if((FLAC__uint64)(seek_table->num_points) * FLAC__STREAM_METADATA_SEEKPOINT_LENGTH >= (1u << FLAC__STREAM_METADATA_LENGTH_LEN)) + return false; + for(i = 0; i < seek_table->num_points; i++) { if(got_prev) { if( @@ -514,6 +525,7 @@ FLAC_API FLAC__bool FLAC__format_picture_is_legal(const FLAC__StreamMetadata_Pic /* * These routines are private to libFLAC */ +#if 0 /* UNUSED */ uint32_t FLAC__format_get_max_rice_partition_order(uint32_t blocksize, uint32_t predictor_order) { return @@ -523,6 +535,7 @@ uint32_t FLAC__format_get_max_rice_partition_order(uint32_t blocksize, uint32_t predictor_order ); } +#endif uint32_t FLAC__format_get_max_rice_partition_order_from_blocksize(uint32_t blocksize) { @@ -569,13 +582,16 @@ void FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(FLAC__En FLAC__format_entropy_coding_method_partitioned_rice_contents_init(object); } +#if defined(_MSC_VER) +// silence three MSVC warnings 'result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?)' +#pragma warning ( disable : 4334 ) +#endif + FLAC__bool FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(FLAC__EntropyCodingMethod_PartitionedRiceContents *object, uint32_t max_partition_order) { FLAC__ASSERT(0 != object); - FLAC__ASSERT(object->capacity_by_order > 0 || (0 == object->parameters && 0 == object->raw_bits)); - - if(object->capacity_by_order < max_partition_order) { + if(object->capacity_by_order < max_partition_order || object->parameters == NULL || object->raw_bits == NULL) { if(0 == (object->parameters = (uint32_t*) safe_realloc_(object->parameters, sizeof(uint32_t)*(1 << max_partition_order)))) return false; if(0 == (object->raw_bits = (uint32_t*) safe_realloc_(object->raw_bits, sizeof(uint32_t)*(1 << max_partition_order)))) @@ -586,3 +602,7 @@ FLAC__bool FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_s return true; } + +#if defined(_MSC_VER) +#pragma warning ( default : 4334 ) +#endif diff --git a/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/all.h b/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/all.h deleted file mode 100644 index be2cb6410257..000000000000 --- a/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/all.h +++ /dev/null @@ -1,50 +0,0 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Xiph.org Foundation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef FLAC__PRIVATE__ALL_H -#define FLAC__PRIVATE__ALL_H - -#include "bitmath.h" -#include "bitreader.h" -#include "bitwriter.h" -#include "cpu.h" -#include "crc.h" -#include "fixed.h" -#include "float.h" -#include "format.h" -#include "lpc.h" -#include "md5.h" -#include "memory.h" -#include "metadata.h" -#include "stream_encoder_framing.h" - -#endif diff --git a/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitmath.h b/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitmath.h index d4cf69a2e6f4..c5f23fbdcfa2 100644 --- a/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitmath.h +++ b/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitmath.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2001-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitreader.h b/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitreader.h index 35ffc3a11292..408f7d3a919d 100644 --- a/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitreader.h +++ b/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitreader.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -53,7 +53,8 @@ void FLAC__bitreader_delete(FLAC__BitReader *br); FLAC__bool FLAC__bitreader_init(FLAC__BitReader *br, FLAC__BitReaderReadCallback rcb, void *cd); void FLAC__bitreader_free(FLAC__BitReader *br); /* does not 'free(br)' */ FLAC__bool FLAC__bitreader_clear(FLAC__BitReader *br); -void FLAC__bitreader_dump(const FLAC__BitReader *br, FILE *out); +void FLAC__bitreader_set_framesync_location(FLAC__BitReader *br); +FLAC__bool FLAC__bitreader_rewind_to_after_last_seen_framesync(FLAC__BitReader *br); /* * CRC functions @@ -67,6 +68,10 @@ FLAC__uint16 FLAC__bitreader_get_read_crc16(FLAC__BitReader *br); FLAC__bool FLAC__bitreader_is_consumed_byte_aligned(const FLAC__BitReader *br); uint32_t FLAC__bitreader_bits_left_for_byte_alignment(const FLAC__BitReader *br); uint32_t FLAC__bitreader_get_input_bits_unconsumed(const FLAC__BitReader *br); +void FLAC__bitreader_set_limit(FLAC__BitReader *br, uint32_t limit); +void FLAC__bitreader_remove_limit(FLAC__BitReader *br); +uint32_t FLAC__bitreader_limit_remaining(FLAC__BitReader *br); +void FLAC__bitreader_limit_invalidate(FLAC__BitReader *br); /* * read functions @@ -75,6 +80,7 @@ uint32_t FLAC__bitreader_get_input_bits_unconsumed(const FLAC__BitReader *br); FLAC__bool FLAC__bitreader_read_raw_uint32(FLAC__BitReader *br, FLAC__uint32 *val, uint32_t bits); FLAC__bool FLAC__bitreader_read_raw_int32(FLAC__BitReader *br, FLAC__int32 *val, uint32_t bits); FLAC__bool FLAC__bitreader_read_raw_uint64(FLAC__BitReader *br, FLAC__uint64 *val, uint32_t bits); +FLAC__bool FLAC__bitreader_read_raw_int64(FLAC__BitReader *br, FLAC__int64 *val, uint32_t bits); FLAC__bool FLAC__bitreader_read_uint32_little_endian(FLAC__BitReader *br, FLAC__uint32 *val); /*only for bits=32*/ FLAC__bool FLAC__bitreader_skip_bits_no_crc(FLAC__BitReader *br, uint32_t bits); /* WATCHOUT: does not CRC the skipped data! */ /*@@@@ add to unit tests */ FLAC__bool FLAC__bitreader_skip_byte_block_aligned_no_crc(FLAC__BitReader *br, uint32_t nvals); /* WATCHOUT: does not CRC the read data! */ @@ -82,6 +88,10 @@ FLAC__bool FLAC__bitreader_read_byte_block_aligned_no_crc(FLAC__BitReader *br, F FLAC__bool FLAC__bitreader_read_unary_unsigned(FLAC__BitReader *br, uint32_t *val); FLAC__bool FLAC__bitreader_read_rice_signed(FLAC__BitReader *br, int *val, uint32_t parameter); FLAC__bool FLAC__bitreader_read_rice_signed_block(FLAC__BitReader *br, int vals[], uint32_t nvals, uint32_t parameter); +#ifdef FLAC__BMI2_SUPPORTED +FLAC__bool FLAC__bitreader_read_rice_signed_block_bmi2(FLAC__BitReader *br, int vals[], uint32_t nvals, uint32_t parameter); +#endif + #if 0 /* UNUSED */ FLAC__bool FLAC__bitreader_read_golomb_signed(FLAC__BitReader *br, int *val, uint32_t parameter); FLAC__bool FLAC__bitreader_read_golomb_unsigned(FLAC__BitReader *br, uint32_t *val, uint32_t parameter); diff --git a/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitwriter.h b/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitwriter.h index 634bc064bf41..8b41de9dd21b 100644 --- a/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitwriter.h +++ b/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitwriter.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -50,7 +50,6 @@ void FLAC__bitwriter_delete(FLAC__BitWriter *bw); FLAC__bool FLAC__bitwriter_init(FLAC__BitWriter *bw); void FLAC__bitwriter_free(FLAC__BitWriter *bw); /* does not 'free(buffer)' */ void FLAC__bitwriter_clear(FLAC__BitWriter *bw); -void FLAC__bitwriter_dump(const FLAC__BitWriter *bw, FILE *out); /* * CRC functions @@ -83,15 +82,16 @@ FLAC__bool FLAC__bitwriter_write_zeroes(FLAC__BitWriter *bw, uint32_t bits); FLAC__bool FLAC__bitwriter_write_raw_uint32(FLAC__BitWriter *bw, FLAC__uint32 val, uint32_t bits); FLAC__bool FLAC__bitwriter_write_raw_int32(FLAC__BitWriter *bw, FLAC__int32 val, uint32_t bits); FLAC__bool FLAC__bitwriter_write_raw_uint64(FLAC__BitWriter *bw, FLAC__uint64 val, uint32_t bits); +FLAC__bool FLAC__bitwriter_write_raw_int64(FLAC__BitWriter *bw, FLAC__int64 val, uint32_t bits); FLAC__bool FLAC__bitwriter_write_raw_uint32_little_endian(FLAC__BitWriter *bw, FLAC__uint32 val); /*only for bits=32*/ FLAC__bool FLAC__bitwriter_write_byte_block(FLAC__BitWriter *bw, const FLAC__byte vals[], uint32_t nvals); FLAC__bool FLAC__bitwriter_write_unary_unsigned(FLAC__BitWriter *bw, uint32_t val); -uint32_t FLAC__bitwriter_rice_bits(FLAC__int32 val, uint32_t parameter); #if 0 /* UNUSED */ +uint32_t FLAC__bitwriter_rice_bits(FLAC__int32 val, uint32_t parameter); uint32_t FLAC__bitwriter_golomb_bits_signed(int val, uint32_t parameter); uint32_t FLAC__bitwriter_golomb_bits_unsigned(uint32_t val, uint32_t parameter); -#endif FLAC__bool FLAC__bitwriter_write_rice_signed(FLAC__BitWriter *bw, FLAC__int32 val, uint32_t parameter); +#endif FLAC__bool FLAC__bitwriter_write_rice_signed_block(FLAC__BitWriter *bw, const FLAC__int32 *vals, uint32_t nvals, uint32_t parameter); #if 0 /* UNUSED */ FLAC__bool FLAC__bitwriter_write_golomb_signed(FLAC__BitWriter *bw, int val, uint32_t parameter); diff --git a/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/cpu.h b/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/cpu.h index 439f6aad97fb..087e45908404 100644 --- a/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/cpu.h +++ b/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/cpu.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2001-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -66,7 +66,6 @@ typedef enum { FLAC__CPUINFO_TYPE_IA32, FLAC__CPUINFO_TYPE_X86_64, - FLAC__CPUINFO_TYPE_PPC, FLAC__CPUINFO_TYPE_UNKNOWN } FLAC__CPUInfo_Type; @@ -85,18 +84,13 @@ typedef struct { FLAC__bool avx; FLAC__bool avx2; FLAC__bool fma; + FLAC__bool bmi2; } FLAC__CPUInfo_x86; -typedef struct { - FLAC__bool arch_3_00; - FLAC__bool arch_2_07; -} FLAC__CPUInfo_ppc; - typedef struct { FLAC__bool use_asm; FLAC__CPUInfo_Type type; FLAC__CPUInfo_x86 x86; - FLAC__CPUInfo_ppc ppc; } FLAC__CPUInfo; void FLAC__cpu_info(FLAC__CPUInfo *info); diff --git a/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/crc.h b/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/crc.h index 141111c6b4f9..9f62aedafe59 100644 --- a/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/crc.h +++ b/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/crc.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2018 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/fixed.h b/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/fixed.h index 7d9742081b03..866f110c598c 100644 --- a/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/fixed.h +++ b/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/fixed.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -56,24 +56,30 @@ #ifndef FLAC__INTEGER_ONLY_LIBRARY uint32_t FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); uint32_t FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); +uint32_t FLAC__fixed_compute_best_predictor_limit_residual(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); +uint32_t FLAC__fixed_compute_best_predictor_limit_residual_33bit(const FLAC__int64 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); # ifndef FLAC__NO_ASM # if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN # ifdef FLAC__SSE2_SUPPORTED uint32_t FLAC__fixed_compute_best_predictor_intrin_sse2(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]); -uint32_t FLAC__fixed_compute_best_predictor_wide_intrin_sse2(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]); # endif # ifdef FLAC__SSSE3_SUPPORTED uint32_t FLAC__fixed_compute_best_predictor_intrin_ssse3(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); -uint32_t FLAC__fixed_compute_best_predictor_wide_intrin_ssse3(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]); # endif -# endif -# if defined FLAC__CPU_IA32 && defined FLAC__HAS_NASM -uint32_t FLAC__fixed_compute_best_predictor_asm_ia32_mmx_cmov(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); +# ifdef FLAC__SSE4_2_SUPPORTED +uint32_t FLAC__fixed_compute_best_predictor_limit_residual_intrin_sse42(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); +# endif +# ifdef FLAC__AVX2_SUPPORTED +uint32_t FLAC__fixed_compute_best_predictor_wide_intrin_avx2(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); +uint32_t FLAC__fixed_compute_best_predictor_limit_residual_intrin_avx2(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); +# endif # endif # endif #else uint32_t FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); uint32_t FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); +uint32_t FLAC__fixed_compute_best_predictor_limit_residual(const FLAC__int32 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); +uint32_t FLAC__fixed_compute_best_predictor_limit_residual_33bit(const FLAC__int64 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); #endif /* @@ -88,6 +94,8 @@ uint32_t FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], uint3 * OUT residual[0,data_len-1] residual signal */ void FLAC__fixed_compute_residual(const FLAC__int32 data[], uint32_t data_len, uint32_t order, FLAC__int32 residual[]); +void FLAC__fixed_compute_residual_wide(const FLAC__int32 data[], uint32_t data_len, uint32_t order, FLAC__int32 residual[]); +void FLAC__fixed_compute_residual_wide_33bit(const FLAC__int64 data[], uint32_t data_len, uint32_t order, FLAC__int32 residual[]); /* * FLAC__fixed_restore_signal() @@ -103,5 +111,7 @@ void FLAC__fixed_compute_residual(const FLAC__int32 data[], uint32_t data_len, u * OUT data[0,data_len-1] original signal */ void FLAC__fixed_restore_signal(const FLAC__int32 residual[], uint32_t data_len, uint32_t order, FLAC__int32 data[]); +void FLAC__fixed_restore_signal_wide(const FLAC__int32 residual[], uint32_t data_len, uint32_t order, FLAC__int32 data[]); +void FLAC__fixed_restore_signal_wide_33bit(const FLAC__int32 residual[], uint32_t data_len, uint32_t order, FLAC__int64 data[]); #endif diff --git a/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/float.h b/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/float.h index ad4c63338140..649de9e760c1 100644 --- a/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/float.h +++ b/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/float.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2004-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/format.h b/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/format.h index c6ea5e04ea2e..4cd03fdbe7f4 100644 --- a/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/format.h +++ b/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/format.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -35,7 +35,9 @@ #include "../../../format.h" +#if 0 /* UNUSED */ uint32_t FLAC__format_get_max_rice_partition_order(uint32_t blocksize, uint32_t predictor_order); +#endif uint32_t FLAC__format_get_max_rice_partition_order_from_blocksize(uint32_t blocksize); uint32_t FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(uint32_t limit, uint32_t blocksize, uint32_t predictor_order); void FLAC__format_entropy_coding_method_partitioned_rice_contents_init(FLAC__EntropyCodingMethod_PartitionedRiceContents *object); diff --git a/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/lpc.h b/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/lpc.h index 2d3522924ddb..7cb05a151d1e 100644 --- a/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/lpc.h +++ b/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/lpc.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -55,6 +55,9 @@ * IN data_len */ void FLAC__lpc_window_data(const FLAC__int32 in[], const FLAC__real window[], FLAC__real out[], uint32_t data_len); +void FLAC__lpc_window_data_wide(const FLAC__int64 in[], const FLAC__real window[], FLAC__real out[], uint32_t data_len); +void FLAC__lpc_window_data_partial(const FLAC__int32 in[], const FLAC__real window[], FLAC__real out[], uint32_t data_len, uint32_t part_size, uint32_t data_shift); +void FLAC__lpc_window_data_partial_wide(const FLAC__int64 in[], const FLAC__real window[], FLAC__real out[], uint32_t data_len, uint32_t part_size, uint32_t data_shift); /* * FLAC__lpc_compute_autocorrelation() @@ -68,44 +71,28 @@ void FLAC__lpc_window_data(const FLAC__int32 in[], const FLAC__real window[], FL * IN 0 < lag <= data_len * OUT autoc[0,lag-1] */ -void FLAC__lpc_compute_autocorrelation(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); +void FLAC__lpc_compute_autocorrelation(const FLAC__real data[], uint32_t data_len, uint32_t lag, double autoc[]); #ifndef FLAC__NO_ASM -# ifdef FLAC__CPU_IA32 -# ifdef FLAC__HAS_NASM -void FLAC__lpc_compute_autocorrelation_asm_ia32(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); -void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_4_old(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); -void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_8_old(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); -void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_12_old(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); -void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_16_old(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); +# if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN +# ifdef FLAC__SSE2_SUPPORTED +void FLAC__lpc_compute_autocorrelation_intrin_sse2_lag_8(const FLAC__real data[], uint32_t data_len, uint32_t lag, double autoc[]); +void FLAC__lpc_compute_autocorrelation_intrin_sse2_lag_10(const FLAC__real data[], uint32_t data_len, uint32_t lag, double autoc[]); +void FLAC__lpc_compute_autocorrelation_intrin_sse2_lag_14(const FLAC__real data[], uint32_t data_len, uint32_t lag, double autoc[]); # endif # endif -# if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN -# ifdef FLAC__SSE_SUPPORTED -void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4_old(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); -void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8_old(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); -void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12_old(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); -void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16_old(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); -void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4_new(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); -void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8_new(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); -void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12_new(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); -void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16_new(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); +# if defined FLAC__CPU_X86_64 && FLAC__HAS_X86INTRIN +# ifdef FLAC__FMA_SUPPORTED +void FLAC__lpc_compute_autocorrelation_intrin_fma_lag_8(const FLAC__real data[], uint32_t data_len, uint32_t lag, double autoc[]); +void FLAC__lpc_compute_autocorrelation_intrin_fma_lag_12(const FLAC__real data[], uint32_t data_len, uint32_t lag, double autoc[]); +void FLAC__lpc_compute_autocorrelation_intrin_fma_lag_16(const FLAC__real data[], uint32_t data_len, uint32_t lag, double autoc[]); # endif # endif -#if defined(FLAC__CPU_PPC64) && defined(FLAC__USE_VSX) -#ifdef FLAC__HAS_TARGET_POWER9 -void FLAC__lpc_compute_autocorrelation_intrin_power9_vsx_lag_4(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); -void FLAC__lpc_compute_autocorrelation_intrin_power9_vsx_lag_8(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); -void FLAC__lpc_compute_autocorrelation_intrin_power9_vsx_lag_12(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); -void FLAC__lpc_compute_autocorrelation_intrin_power9_vsx_lag_16(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); -#endif -#ifdef FLAC__HAS_TARGET_POWER8 -void FLAC__lpc_compute_autocorrelation_intrin_power8_vsx_lag_4(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); -void FLAC__lpc_compute_autocorrelation_intrin_power8_vsx_lag_8(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); -void FLAC__lpc_compute_autocorrelation_intrin_power8_vsx_lag_12(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); -void FLAC__lpc_compute_autocorrelation_intrin_power8_vsx_lag_16(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); -#endif -#endif +#if defined FLAC__CPU_ARM64 && FLAC__HAS_NEONINTRIN && FLAC__HAS_A64NEONINTRIN +void FLAC__lpc_compute_autocorrelation_intrin_neon_lag_8(const FLAC__real data[], uint32_t data_len, uint32_t lag, double autoc[]); +void FLAC__lpc_compute_autocorrelation_intrin_neon_lag_10(const FLAC__real data[], uint32_t data_len, uint32_t lag, double autoc[]); +void FLAC__lpc_compute_autocorrelation_intrin_neon_lag_14(const FLAC__real data[], uint32_t data_len, uint32_t lag, double autoc[]); #endif +#endif /* FLAC__NO_ASM */ /* * FLAC__lpc_compute_lp_coefficients() @@ -128,7 +115,7 @@ void FLAC__lpc_compute_autocorrelation_intrin_power8_vsx_lag_16(const FLAC__real * in lp_coeff[8][0,8], the LP coefficients for order 8 will be * in lp_coeff[7][0,7], etc. */ -void FLAC__lpc_compute_lp_coefficients(const FLAC__real autoc[], uint32_t *max_order, FLAC__real lp_coeff[][FLAC__MAX_LPC_ORDER], double error[]); +void FLAC__lpc_compute_lp_coefficients(const double autoc[], uint32_t *max_order, FLAC__real lp_coeff[][FLAC__MAX_LPC_ORDER], double error[]); /* * FLAC__lpc_quantize_coefficients() @@ -167,14 +154,14 @@ int FLAC__lpc_quantize_coefficients(const FLAC__real lp_coeff[], uint32_t order, */ void FLAC__lpc_compute_residual_from_qlp_coefficients(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]); void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]); +FLAC__bool FLAC__lpc_compute_residual_from_qlp_coefficients_limit_residual(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]); +FLAC__bool FLAC__lpc_compute_residual_from_qlp_coefficients_limit_residual_33bit(const FLAC__int64 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]); #ifndef FLAC__NO_ASM -# ifdef FLAC__CPU_IA32 -# ifdef FLAC__HAS_NASM -void FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]); -void FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]); -void FLAC__lpc_compute_residual_from_qlp_coefficients_wide_asm_ia32(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]); -# endif -# endif +# ifdef FLAC__CPU_ARM64 +void FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_neon(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]); +void FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_neon(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]); +# endif + # if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN # ifdef FLAC__SSE2_SUPPORTED void FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_sse2(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]); @@ -194,6 +181,9 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_avx2(const FLA #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ +uint32_t FLAC__lpc_max_prediction_before_shift_bps(uint32_t subframe_bps, const FLAC__int32 qlp_coeff[], uint32_t order); +uint32_t FLAC__lpc_max_residual_bps(uint32_t subframe_bps, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization); + /* * FLAC__lpc_restore_signal() * -------------------------------------------------------------------- @@ -211,22 +201,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_avx2(const FLA */ void FLAC__lpc_restore_signal(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 data[]); void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 data[]); -#ifndef FLAC__NO_ASM -# ifdef FLAC__CPU_IA32 -# ifdef FLAC__HAS_NASM -void FLAC__lpc_restore_signal_asm_ia32(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 data[]); -void FLAC__lpc_restore_signal_asm_ia32_mmx(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 data[]); -void FLAC__lpc_restore_signal_wide_asm_ia32(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 data[]); -# endif /* FLAC__HAS_NASM */ -# endif /* FLAC__CPU_IA32 */ -# if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN -# ifdef FLAC__SSE4_1_SUPPORTED -void FLAC__lpc_restore_signal_intrin_sse41(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 data[]); -void FLAC__lpc_restore_signal_16_intrin_sse41(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 data[]); -void FLAC__lpc_restore_signal_wide_intrin_sse41(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 data[]); -# endif -# endif -#endif /* FLAC__NO_ASM */ +void FLAC__lpc_restore_signal_wide_33bit(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int64 data[]); #ifndef FLAC__INTEGER_ONLY_LIBRARY diff --git a/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/memory.h b/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/memory.h index 8765b91ebda0..bb7853f287de 100644 --- a/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/memory.h +++ b/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/memory.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2001-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -48,8 +48,8 @@ void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address); FLAC__bool FLAC__memory_alloc_aligned_int32_array(size_t elements, FLAC__int32 **unaligned_pointer, FLAC__int32 **aligned_pointer); FLAC__bool FLAC__memory_alloc_aligned_uint32_array(size_t elements, FLAC__uint32 **unaligned_pointer, FLAC__uint32 **aligned_pointer); +FLAC__bool FLAC__memory_alloc_aligned_int64_array(size_t elements, FLAC__int64 **unaligned_pointer, FLAC__int64 **aligned_pointer); FLAC__bool FLAC__memory_alloc_aligned_uint64_array(size_t elements, FLAC__uint64 **unaligned_pointer, FLAC__uint64 **aligned_pointer); -FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(size_t elements, uint32_t **unaligned_pointer, uint32_t **aligned_pointer); #ifndef FLAC__INTEGER_ONLY_LIBRARY FLAC__bool FLAC__memory_alloc_aligned_real_array(size_t elements, FLAC__real **unaligned_pointer, FLAC__real **aligned_pointer); #endif diff --git a/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/stream_encoder.h b/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/stream_encoder.h index ba7052795fd1..36bbc24c1e7e 100644 --- a/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/stream_encoder.h +++ b/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/stream_encoder.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/stream_encoder_framing.h b/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/stream_encoder_framing.h index f299747a20db..9e55f3095bc9 100644 --- a/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/stream_encoder_framing.h +++ b/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/stream_encoder_framing.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -36,7 +36,7 @@ #include "../../../format.h" #include "bitwriter.h" -FLAC__bool FLAC__add_metadata_block(const FLAC__StreamMetadata *metadata, FLAC__BitWriter *bw); +FLAC__bool FLAC__add_metadata_block(const FLAC__StreamMetadata *metadata, FLAC__BitWriter *bw, FLAC__bool update_vendor_string); FLAC__bool FLAC__frame_add_header(const FLAC__FrameHeader *header, FLAC__BitWriter *bw); FLAC__bool FLAC__subframe_add_constant(const FLAC__Subframe_Constant *subframe, uint32_t subframe_bps, uint32_t wasted_bits, FLAC__BitWriter *bw); FLAC__bool FLAC__subframe_add_fixed(const FLAC__Subframe_Fixed *subframe, uint32_t residual_samples, uint32_t subframe_bps, uint32_t wasted_bits, FLAC__BitWriter *bw); diff --git a/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/window.h b/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/window.h index f93d8a5de547..512140a380e8 100644 --- a/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/window.h +++ b/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/window.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2006-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/all.h b/modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/all.h deleted file mode 100644 index fd1ec9e889c4..000000000000 --- a/modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/all.h +++ /dev/null @@ -1,39 +0,0 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2001-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the Xiph.org Foundation nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef FLAC__PROTECTED__ALL_H -#define FLAC__PROTECTED__ALL_H - -#include "stream_decoder.h" -#include "stream_encoder.h" - -#endif diff --git a/modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/stream_decoder.h b/modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/stream_decoder.h index 15dfe90dba6e..8c7794b7a2e7 100644 --- a/modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/stream_decoder.h +++ b/modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/stream_decoder.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -53,13 +53,8 @@ typedef struct FLAC__StreamDecoderProtected { } FLAC__StreamDecoderProtected; /* - * return the number of input bytes consumed + * Return the number of input bytes consumed */ uint32_t FLAC__stream_decoder_get_input_bytes_unconsumed(const FLAC__StreamDecoder *decoder); -/* - * return client_data from decoder - */ -FLAC_API void *get_client_data_from_decoder(FLAC__StreamDecoder *decoder); - #endif diff --git a/modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/stream_encoder.h b/modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/stream_encoder.h index 9ddfe558183e..0354fb0b24db 100644 --- a/modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/stream_encoder.h +++ b/modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/stream_encoder.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2001-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -61,6 +61,7 @@ typedef enum { FLAC__APODIZATION_TUKEY, FLAC__APODIZATION_PARTIAL_TUKEY, FLAC__APODIZATION_PUNCHOUT_TUKEY, + FLAC__APODIZATION_SUBDIVIDE_TUKEY, FLAC__APODIZATION_WELCH } FLAC__ApodizationFunction; @@ -78,6 +79,10 @@ typedef struct { FLAC__real start; FLAC__real end; } multiple_tukey; + struct { + FLAC__real p; + FLAC__int32 parts; + } subdivide_tukey; } parameters; } FLAC__ApodizationSpecification; @@ -107,6 +112,7 @@ typedef struct FLAC__StreamEncoderProtected { uint32_t max_residual_partition_order; uint32_t rice_parameter_search_dist; FLAC__uint64 total_samples_estimate; + FLAC__bool limit_min_bitrate; FLAC__StreamMetadata **metadata; uint32_t num_metadata_blocks; FLAC__uint64 streaminfo_offset, seektable_offset, audio_offset; diff --git a/modules/juce_audio_formats/codecs/flac/libFLAC/lpc_flac.c b/modules/juce_audio_formats/codecs/flac/libFLAC/lpc_flac.c index 9835b12bc2c5..e86cd1134f7e 100644 --- a/modules/juce_audio_formats/codecs/flac/libFLAC/lpc_flac.c +++ b/modules/juce_audio_formats/codecs/flac/libFLAC/lpc_flac.c @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -35,12 +35,15 @@ #endif #include +#include #include "../assert.h" #include "../format.h" #include "../compat.h" #include "include/private/bitmath.h" #include "include/private/lpc.h" + + #if !defined(NDEBUG) || defined FLAC__OVERFLOW_DETECT || defined FLAC__OVERFLOW_DETECT_VERBOSE #include #endif @@ -69,11 +72,46 @@ void FLAC__lpc_window_data(const FLAC__int32 in[], const FLAC__real window[], FL out[i] = in[i] * window[i]; } -void FLAC__lpc_compute_autocorrelation(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]) +void FLAC__lpc_window_data_wide(const FLAC__int64 in[], const FLAC__real window[], FLAC__real out[], uint32_t data_len) +{ + uint32_t i; + for(i = 0; i < data_len; i++) + out[i] = in[i] * window[i]; +} + +void FLAC__lpc_window_data_partial(const FLAC__int32 in[], const FLAC__real window[], FLAC__real out[], uint32_t data_len, uint32_t part_size, uint32_t data_shift) +{ + uint32_t i, j; + if((part_size + data_shift) < data_len){ + for(i = 0; i < part_size; i++) + out[i] = in[data_shift+i] * window[i]; + i = flac_min(i,data_len - part_size - data_shift); + for(j = data_len - part_size; j < data_len; i++, j++) + out[i] = in[data_shift+i] * window[j]; + if(i < data_len) + out[i] = 0.0f; + } +} + +void FLAC__lpc_window_data_partial_wide(const FLAC__int64 in[], const FLAC__real window[], FLAC__real out[], uint32_t data_len, uint32_t part_size, uint32_t data_shift) +{ + uint32_t i, j; + if((part_size + data_shift) < data_len){ + for(i = 0; i < part_size; i++) + out[i] = in[data_shift+i] * window[i]; + i = flac_min(i,data_len - part_size - data_shift); + for(j = data_len - part_size; j < data_len; i++, j++) + out[i] = in[data_shift+i] * window[j]; + if(i < data_len) + out[i] = 0.0f; + } +} + +void FLAC__lpc_compute_autocorrelation(const FLAC__real data[], uint32_t data_len, uint32_t lag, double autoc[]) { /* a readable, but slower, version */ #if 0 - FLAC__real d; + double d; uint32_t i; FLAC__ASSERT(lag > 0); @@ -88,37 +126,54 @@ void FLAC__lpc_compute_autocorrelation(const FLAC__real data[], uint32_t data_le */ while(lag--) { for(i = lag, d = 0.0; i < data_len; i++) - d += data[i] * data[i - lag]; + d += data[i] * (double)data[i - lag]; autoc[lag] = d; } #endif + if (data_len < FLAC__MAX_LPC_ORDER || lag > 16) { + /* + * this version tends to run faster because of better data locality + * ('data_len' is usually much larger than 'lag') + */ + double d; + uint32_t sample, coeff; + const uint32_t limit = data_len - lag; + + FLAC__ASSERT(lag > 0); + FLAC__ASSERT(lag <= data_len); - /* - * this version tends to run faster because of better data locality - * ('data_len' is usually much larger than 'lag') - */ - FLAC__real d; - uint32_t sample, coeff; - const uint32_t limit = data_len - lag; - - FLAC__ASSERT(lag > 0); - FLAC__ASSERT(lag <= data_len); - - for(coeff = 0; coeff < lag; coeff++) - autoc[coeff] = 0.0; - for(sample = 0; sample <= limit; sample++) { - d = data[sample]; for(coeff = 0; coeff < lag; coeff++) - autoc[coeff] += d * data[sample+coeff]; + autoc[coeff] = 0.0; + for(sample = 0; sample <= limit; sample++) { + d = data[sample]; + for(coeff = 0; coeff < lag; coeff++) + autoc[coeff] += d * data[sample+coeff]; + } + for(; sample < data_len; sample++) { + d = data[sample]; + for(coeff = 0; coeff < data_len - sample; coeff++) + autoc[coeff] += d * data[sample+coeff]; + } } - for(; sample < data_len; sample++) { - d = data[sample]; - for(coeff = 0; coeff < data_len - sample; coeff++) - autoc[coeff] += d * data[sample+coeff]; + else if(lag <= 8) { + #undef MAX_LAG + #define MAX_LAG 8 + #include "deduplication/lpc_compute_autocorrelation_intrin.c" } + else if(lag <= 12) { + #undef MAX_LAG + #define MAX_LAG 12 + #include "deduplication/lpc_compute_autocorrelation_intrin.c" + } + else if(lag <= 16) { + #undef MAX_LAG + #define MAX_LAG 16 + #include "deduplication/lpc_compute_autocorrelation_intrin.c" + } + } -void FLAC__lpc_compute_lp_coefficients(const FLAC__real autoc[], uint32_t *max_order, FLAC__real lp_coeff[][FLAC__MAX_LPC_ORDER], double error[]) +void FLAC__lpc_compute_lp_coefficients(const double autoc[], uint32_t *max_order, FLAC__real lp_coeff[][FLAC__MAX_LPC_ORDER], double error[]) { uint32_t i, j; double r, err, lpc[FLAC__MAX_LPC_ORDER]; @@ -544,10 +599,6 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 * f history = data; for(j = 0; j < order; j++) sum += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*(--history)); - if(FLAC__bitmath_silog2(sum >> lp_quantization) > 32) { - fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients_wide: OVERFLOW, i=%u, sum=%" PRId64 "\n", i, (sum >> lp_quantization)); - break; - } if(FLAC__bitmath_silog2((FLAC__int64)(*data) - (sum >> lp_quantization)) > 32) { fprintf(stderr,"FLAC__lpc_compute_residual_from_qlp_coefficients_wide: OVERFLOW, i=%u, data=%d, sum=%" PRId64 ", residual=%" PRId64 "\n", i, *data, (int64_t)(sum >> lp_quantization), ((FLAC__int64)(*data) - (sum >> lp_quantization))); break; @@ -586,7 +637,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 * f sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; - residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); + residual[i] = data[i] - (sum >> lp_quantization); } } else { /* order == 11 */ @@ -603,7 +654,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 * f sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; - residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); + residual[i] = data[i] - (sum >> lp_quantization); } } } @@ -621,7 +672,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 * f sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; - residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); + residual[i] = data[i] - (sum >> lp_quantization); } } else { /* order == 9 */ @@ -636,7 +687,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 * f sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; - residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); + residual[i] = data[i] - (sum >> lp_quantization); } } } @@ -654,7 +705,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 * f sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; - residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); + residual[i] = data[i] - (sum >> lp_quantization); } } else { /* order == 7 */ @@ -667,7 +718,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 * f sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; - residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); + residual[i] = data[i] - (sum >> lp_quantization); } } } @@ -681,7 +732,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 * f sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; - residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); + residual[i] = data[i] - (sum >> lp_quantization); } } else { /* order == 5 */ @@ -692,7 +743,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 * f sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; - residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); + residual[i] = data[i] - (sum >> lp_quantization); } } } @@ -706,7 +757,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 * f sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; - residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); + residual[i] = data[i] - (sum >> lp_quantization); } } else { /* order == 3 */ @@ -715,7 +766,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 * f sum += qlp_coeff[2] * (FLAC__int64)data[i-3]; sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; - residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); + residual[i] = data[i] - (sum >> lp_quantization); } } } @@ -725,12 +776,12 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 * f sum = 0; sum += qlp_coeff[1] * (FLAC__int64)data[i-2]; sum += qlp_coeff[0] * (FLAC__int64)data[i-1]; - residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); + residual[i] = data[i] - (sum >> lp_quantization); } } else { /* order == 1 */ for(i = 0; i < (int)data_len; i++) - residual[i] = data[i] - (FLAC__int32)((qlp_coeff[0] * (FLAC__int64)data[i-1]) >> lp_quantization); + residual[i] = data[i] - ((qlp_coeff[0] * (FLAC__int64)data[i-1]) >> lp_quantization); } } } @@ -772,14 +823,155 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 * f sum += qlp_coeff[ 1] * (FLAC__int64)data[i- 2]; sum += qlp_coeff[ 0] * (FLAC__int64)data[i- 1]; } - residual[i] = data[i] - (FLAC__int32)(sum >> lp_quantization); + residual[i] = data[i] - (sum >> lp_quantization); } } } #endif +FLAC__bool FLAC__lpc_compute_residual_from_qlp_coefficients_limit_residual(const FLAC__int32 * flac_restrict data, uint32_t data_len, const FLAC__int32 * flac_restrict qlp_coeff, uint32_t order, int lp_quantization, FLAC__int32 * flac_restrict residual) +{ + int i; + FLAC__int64 sum, residual_to_check; + + FLAC__ASSERT(order > 0); + FLAC__ASSERT(order <= 32); + + for(i = 0; i < (int)data_len; i++) { + sum = 0; + switch(order) { + case 32: sum += qlp_coeff[31] * (FLAC__int64)data[i-32]; /* Falls through. */ + case 31: sum += qlp_coeff[30] * (FLAC__int64)data[i-31]; /* Falls through. */ + case 30: sum += qlp_coeff[29] * (FLAC__int64)data[i-30]; /* Falls through. */ + case 29: sum += qlp_coeff[28] * (FLAC__int64)data[i-29]; /* Falls through. */ + case 28: sum += qlp_coeff[27] * (FLAC__int64)data[i-28]; /* Falls through. */ + case 27: sum += qlp_coeff[26] * (FLAC__int64)data[i-27]; /* Falls through. */ + case 26: sum += qlp_coeff[25] * (FLAC__int64)data[i-26]; /* Falls through. */ + case 25: sum += qlp_coeff[24] * (FLAC__int64)data[i-25]; /* Falls through. */ + case 24: sum += qlp_coeff[23] * (FLAC__int64)data[i-24]; /* Falls through. */ + case 23: sum += qlp_coeff[22] * (FLAC__int64)data[i-23]; /* Falls through. */ + case 22: sum += qlp_coeff[21] * (FLAC__int64)data[i-22]; /* Falls through. */ + case 21: sum += qlp_coeff[20] * (FLAC__int64)data[i-21]; /* Falls through. */ + case 20: sum += qlp_coeff[19] * (FLAC__int64)data[i-20]; /* Falls through. */ + case 19: sum += qlp_coeff[18] * (FLAC__int64)data[i-19]; /* Falls through. */ + case 18: sum += qlp_coeff[17] * (FLAC__int64)data[i-18]; /* Falls through. */ + case 17: sum += qlp_coeff[16] * (FLAC__int64)data[i-17]; /* Falls through. */ + case 16: sum += qlp_coeff[15] * (FLAC__int64)data[i-16]; /* Falls through. */ + case 15: sum += qlp_coeff[14] * (FLAC__int64)data[i-15]; /* Falls through. */ + case 14: sum += qlp_coeff[13] * (FLAC__int64)data[i-14]; /* Falls through. */ + case 13: sum += qlp_coeff[12] * (FLAC__int64)data[i-13]; /* Falls through. */ + case 12: sum += qlp_coeff[11] * (FLAC__int64)data[i-12]; /* Falls through. */ + case 11: sum += qlp_coeff[10] * (FLAC__int64)data[i-11]; /* Falls through. */ + case 10: sum += qlp_coeff[ 9] * (FLAC__int64)data[i-10]; /* Falls through. */ + case 9: sum += qlp_coeff[ 8] * (FLAC__int64)data[i- 9]; /* Falls through. */ + case 8: sum += qlp_coeff[ 7] * (FLAC__int64)data[i- 8]; /* Falls through. */ + case 7: sum += qlp_coeff[ 6] * (FLAC__int64)data[i- 7]; /* Falls through. */ + case 6: sum += qlp_coeff[ 5] * (FLAC__int64)data[i- 6]; /* Falls through. */ + case 5: sum += qlp_coeff[ 4] * (FLAC__int64)data[i- 5]; /* Falls through. */ + case 4: sum += qlp_coeff[ 3] * (FLAC__int64)data[i- 4]; /* Falls through. */ + case 3: sum += qlp_coeff[ 2] * (FLAC__int64)data[i- 3]; /* Falls through. */ + case 2: sum += qlp_coeff[ 1] * (FLAC__int64)data[i- 2]; /* Falls through. */ + case 1: sum += qlp_coeff[ 0] * (FLAC__int64)data[i- 1]; + } + residual_to_check = data[i] - (sum >> lp_quantization); + /* residual must not be INT32_MIN because abs(INT32_MIN) is undefined */ + if(residual_to_check <= INT32_MIN || residual_to_check > INT32_MAX) + return false; + else + residual[i] = residual_to_check; + } + return true; +} + +FLAC__bool FLAC__lpc_compute_residual_from_qlp_coefficients_limit_residual_33bit(const FLAC__int64 * flac_restrict data, uint32_t data_len, const FLAC__int32 * flac_restrict qlp_coeff, uint32_t order, int lp_quantization, FLAC__int32 * flac_restrict residual) +{ + int i; + FLAC__int64 sum, residual_to_check; + + FLAC__ASSERT(order > 0); + FLAC__ASSERT(order <= 32); + + for(i = 0; i < (int)data_len; i++) { + sum = 0; + switch(order) { + case 32: sum += qlp_coeff[31] * data[i-32]; /* Falls through. */ + case 31: sum += qlp_coeff[30] * data[i-31]; /* Falls through. */ + case 30: sum += qlp_coeff[29] * data[i-30]; /* Falls through. */ + case 29: sum += qlp_coeff[28] * data[i-29]; /* Falls through. */ + case 28: sum += qlp_coeff[27] * data[i-28]; /* Falls through. */ + case 27: sum += qlp_coeff[26] * data[i-27]; /* Falls through. */ + case 26: sum += qlp_coeff[25] * data[i-26]; /* Falls through. */ + case 25: sum += qlp_coeff[24] * data[i-25]; /* Falls through. */ + case 24: sum += qlp_coeff[23] * data[i-24]; /* Falls through. */ + case 23: sum += qlp_coeff[22] * data[i-23]; /* Falls through. */ + case 22: sum += qlp_coeff[21] * data[i-22]; /* Falls through. */ + case 21: sum += qlp_coeff[20] * data[i-21]; /* Falls through. */ + case 20: sum += qlp_coeff[19] * data[i-20]; /* Falls through. */ + case 19: sum += qlp_coeff[18] * data[i-19]; /* Falls through. */ + case 18: sum += qlp_coeff[17] * data[i-18]; /* Falls through. */ + case 17: sum += qlp_coeff[16] * data[i-17]; /* Falls through. */ + case 16: sum += qlp_coeff[15] * data[i-16]; /* Falls through. */ + case 15: sum += qlp_coeff[14] * data[i-15]; /* Falls through. */ + case 14: sum += qlp_coeff[13] * data[i-14]; /* Falls through. */ + case 13: sum += qlp_coeff[12] * data[i-13]; /* Falls through. */ + case 12: sum += qlp_coeff[11] * data[i-12]; /* Falls through. */ + case 11: sum += qlp_coeff[10] * data[i-11]; /* Falls through. */ + case 10: sum += qlp_coeff[ 9] * data[i-10]; /* Falls through. */ + case 9: sum += qlp_coeff[ 8] * data[i- 9]; /* Falls through. */ + case 8: sum += qlp_coeff[ 7] * data[i- 8]; /* Falls through. */ + case 7: sum += qlp_coeff[ 6] * data[i- 7]; /* Falls through. */ + case 6: sum += qlp_coeff[ 5] * data[i- 6]; /* Falls through. */ + case 5: sum += qlp_coeff[ 4] * data[i- 5]; /* Falls through. */ + case 4: sum += qlp_coeff[ 3] * data[i- 4]; /* Falls through. */ + case 3: sum += qlp_coeff[ 2] * data[i- 3]; /* Falls through. */ + case 2: sum += qlp_coeff[ 1] * data[i- 2]; /* Falls through. */ + case 1: sum += qlp_coeff[ 0] * data[i- 1]; + } + residual_to_check = data[i] - (sum >> lp_quantization); + /* residual must not be INT32_MIN because abs(INT32_MIN) is undefined */ + if(residual_to_check <= INT32_MIN || residual_to_check > INT32_MAX) + return false; + else + residual[i] = residual_to_check; + } + return true; +} + #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ +uint32_t FLAC__lpc_max_prediction_before_shift_bps(uint32_t subframe_bps, const FLAC__int32 * flac_restrict qlp_coeff, uint32_t order) +{ + /* This used to be subframe_bps + qlp_coeff_precision + FLAC__bitmath_ilog2(order) + * but that treats both the samples as well as the predictor as unknown. The + * predictor is known however, so taking the log2 of the sum of the absolute values + * of all coefficients is a more accurate representation of the predictor */ + FLAC__int32 abs_sum_of_qlp_coeff = 0; + uint32_t i; + for(i = 0; i < order; i++) + abs_sum_of_qlp_coeff += abs(qlp_coeff[i]); + if(abs_sum_of_qlp_coeff == 0) + abs_sum_of_qlp_coeff = 1; + return subframe_bps + FLAC__bitmath_silog2(abs_sum_of_qlp_coeff); +} + + +uint32_t FLAC__lpc_max_residual_bps(uint32_t subframe_bps, const FLAC__int32 * flac_restrict qlp_coeff, uint32_t order, int lp_quantization) +{ + FLAC__int32 predictor_sum_bps = FLAC__lpc_max_prediction_before_shift_bps(subframe_bps, qlp_coeff, order) - lp_quantization; + if((int)subframe_bps > predictor_sum_bps) + return subframe_bps + 1; + else + return predictor_sum_bps + 1; +} + +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && !defined(FUZZING_BUILD_MODE_FLAC_SANITIZE_SIGNED_INTEGER_OVERFLOW) +/* The attribute below is to silence the undefined sanitizer of oss-fuzz. + * Because fuzzing feeds bogus predictors and residual samples to the + * decoder, having overflows in this section is unavoidable. Also, + * because the calculated values are audio path only, there is no + * potential for security problems */ +__attribute__((no_sanitize("signed-integer-overflow"))) +#endif void FLAC__lpc_restore_signal(const FLAC__int32 * flac_restrict residual, uint32_t data_len, const FLAC__int32 * flac_restrict qlp_coeff, uint32_t order, int lp_quantization, FLAC__int32 * flac_restrict data) #if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS) { @@ -803,8 +995,10 @@ void FLAC__lpc_restore_signal(const FLAC__int32 * flac_restrict residual, uint32 for(j = 0; j < order; j++) { sum += qlp_coeff[j] * (*(--history)); sumo += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*history); +#ifdef FLAC__OVERFLOW_DETECT if(sumo > 2147483647ll || sumo < -2147483648ll) fprintf(stderr,"FLAC__lpc_restore_signal: OVERFLOW, i=%u, j=%u, c=%d, d=%d, sumo=%" PRId64 "\n",i,j,qlp_coeff[j],*history,sumo); +#endif } *(data++) = *(r++) + (sum >> lp_quantization); } @@ -1061,15 +1255,13 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 * flac_restrict residual, u history = data; for(j = 0; j < order; j++) sum += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*(--history)); - if(FLAC__bitmath_silog2(sum >> lp_quantization) > 32) { - fprintf(stderr,"FLAC__lpc_restore_signal_wide: OVERFLOW, i=%u, sum=%" PRId64 "\n", i, (sum >> lp_quantization)); - break; - } +#ifdef FLAC__OVERFLOW_DETECT if(FLAC__bitmath_silog2((FLAC__int64)(*r) + (sum >> lp_quantization)) > 32) { fprintf(stderr,"FLAC__lpc_restore_signal_wide: OVERFLOW, i=%u, residual=%d, sum=%" PRId64 ", data=%" PRId64 "\n", i, *r, (sum >> lp_quantization), ((FLAC__int64)(*r) + (sum >> lp_quantization))); break; } - *(data++) = *(r++) + (FLAC__int32)(sum >> lp_quantization); +#endif + *(data++) = (FLAC__int32)(*(r++) + (sum >> lp_quantization)); } } #else /* fully unrolled version for normal use */ @@ -1247,7 +1439,7 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 * flac_restrict residual, u } else { /* order == 1 */ for(i = 0; i < (int)data_len; i++) - data[i] = residual[i] + (FLAC__int32)((qlp_coeff[0] * (FLAC__int64)data[i-1]) >> lp_quantization); + data[i] = (FLAC__int32)(residual[i] + ((qlp_coeff[0] * (FLAC__int64)data[i-1]) >> lp_quantization)); } } } @@ -1295,6 +1487,87 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 * flac_restrict residual, u } #endif +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && !defined(FUZZING_BUILD_MODE_FLAC_SANITIZE_SIGNED_INTEGER_OVERFLOW) +/* The attribute below is to silence the undefined sanitizer of oss-fuzz. + * Because fuzzing feeds bogus predictors and residual samples to the + * decoder, having overflows in this section is unavoidable. Also, + * because the calculated values are audio path only, there is no + * potential for security problems */ +__attribute__((no_sanitize("signed-integer-overflow"))) +#endif +void FLAC__lpc_restore_signal_wide_33bit(const FLAC__int32 * flac_restrict residual, uint32_t data_len, const FLAC__int32 * flac_restrict qlp_coeff, uint32_t order, int lp_quantization, FLAC__int64 * flac_restrict data) +#if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS) +{ + uint32_t i, j; + FLAC__int64 sum; + const FLAC__int32 *r = residual; + const FLAC__int64 *history; + + FLAC__ASSERT(order > 0); + + for(i = 0; i < data_len; i++) { + sum = 0; + history = data; + for(j = 0; j < order; j++) + sum += (FLAC__int64)qlp_coeff[j] * (FLAC__int64)(*(--history)); +#ifdef FLAC__OVERFLOW_DETECT + if(FLAC__bitmath_silog2((FLAC__int64)(*r) + (sum >> lp_quantization)) > 33) { + fprintf(stderr,"FLAC__lpc_restore_signal_33bit: OVERFLOW, i=%u, residual=%d, sum=%" PRId64 ", data=%" PRId64 "\n", i, *r, (sum >> lp_quantization), ((FLAC__int64)(*r) + (sum >> lp_quantization))); + break; + } +#endif + *(data++) = (FLAC__int64)(*(r++)) + (sum >> lp_quantization); + } +} +#else /* unrolled version for normal use */ +{ + int i; + FLAC__int64 sum; + + FLAC__ASSERT(order > 0); + FLAC__ASSERT(order <= 32); + + for(i = 0; i < (int)data_len; i++) { + sum = 0; + switch(order) { + case 32: sum += qlp_coeff[31] * data[i-32]; /* Falls through. */ + case 31: sum += qlp_coeff[30] * data[i-31]; /* Falls through. */ + case 30: sum += qlp_coeff[29] * data[i-30]; /* Falls through. */ + case 29: sum += qlp_coeff[28] * data[i-29]; /* Falls through. */ + case 28: sum += qlp_coeff[27] * data[i-28]; /* Falls through. */ + case 27: sum += qlp_coeff[26] * data[i-27]; /* Falls through. */ + case 26: sum += qlp_coeff[25] * data[i-26]; /* Falls through. */ + case 25: sum += qlp_coeff[24] * data[i-25]; /* Falls through. */ + case 24: sum += qlp_coeff[23] * data[i-24]; /* Falls through. */ + case 23: sum += qlp_coeff[22] * data[i-23]; /* Falls through. */ + case 22: sum += qlp_coeff[21] * data[i-22]; /* Falls through. */ + case 21: sum += qlp_coeff[20] * data[i-21]; /* Falls through. */ + case 20: sum += qlp_coeff[19] * data[i-20]; /* Falls through. */ + case 19: sum += qlp_coeff[18] * data[i-19]; /* Falls through. */ + case 18: sum += qlp_coeff[17] * data[i-18]; /* Falls through. */ + case 17: sum += qlp_coeff[16] * data[i-17]; /* Falls through. */ + case 16: sum += qlp_coeff[15] * data[i-16]; /* Falls through. */ + case 15: sum += qlp_coeff[14] * data[i-15]; /* Falls through. */ + case 14: sum += qlp_coeff[13] * data[i-14]; /* Falls through. */ + case 13: sum += qlp_coeff[12] * data[i-13]; /* Falls through. */ + case 12: sum += qlp_coeff[11] * data[i-12]; /* Falls through. */ + case 11: sum += qlp_coeff[10] * data[i-11]; /* Falls through. */ + case 10: sum += qlp_coeff[ 9] * data[i-10]; /* Falls through. */ + case 9: sum += qlp_coeff[ 8] * data[i- 9]; /* Falls through. */ + case 8: sum += qlp_coeff[ 7] * data[i- 8]; /* Falls through. */ + case 7: sum += qlp_coeff[ 6] * data[i- 7]; /* Falls through. */ + case 6: sum += qlp_coeff[ 5] * data[i- 6]; /* Falls through. */ + case 5: sum += qlp_coeff[ 4] * data[i- 5]; /* Falls through. */ + case 4: sum += qlp_coeff[ 3] * data[i- 4]; /* Falls through. */ + case 3: sum += qlp_coeff[ 2] * data[i- 3]; /* Falls through. */ + case 2: sum += qlp_coeff[ 1] * data[i- 2]; /* Falls through. */ + case 1: sum += qlp_coeff[ 0] * data[i- 1]; + } + data[i] = residual[i] + (sum >> lp_quantization); + } +} +#endif + #if defined(_MSC_VER) #pragma warning ( default : 4028 ) #endif diff --git a/modules/juce_audio_formats/codecs/flac/libFLAC/lpc_intrin_neon.c b/modules/juce_audio_formats/codecs/flac/libFLAC/lpc_intrin_neon.c new file mode 100644 index 000000000000..48f8c800b42b --- /dev/null +++ b/modules/juce_audio_formats/codecs/flac/libFLAC/lpc_intrin_neon.c @@ -0,0 +1,1273 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2000-2009 Josh Coalson + * Copyright (C) 2011-2023 Xiph.Org Foundation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the Xiph.org Foundation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "include/private/cpu.h" + +#ifndef FLAC__INTEGER_ONLY_LIBRARY +#ifndef FLAC__NO_ASM +#if defined FLAC__CPU_ARM64 && FLAC__HAS_NEONINTRIN +#include "include/private/lpc.h" +#include "../assert.h" +#include "../format.h" + +#include + +#if FLAC__HAS_A64NEONINTRIN +void FLAC__lpc_compute_autocorrelation_intrin_neon_lag_14(const FLAC__real data[], uint32_t data_len, uint32_t lag, double autoc[]) +{ +#undef MAX_LAG +#define MAX_LAG 14 +#include "deduplication/lpc_compute_autocorrelation_intrin_neon.c" +} + +void FLAC__lpc_compute_autocorrelation_intrin_neon_lag_10(const FLAC__real data[], uint32_t data_len, uint32_t lag, double autoc[]) +{ +#undef MAX_LAG +#define MAX_LAG 10 +#include "deduplication/lpc_compute_autocorrelation_intrin_neon.c" +} + +void FLAC__lpc_compute_autocorrelation_intrin_neon_lag_8(const FLAC__real data[], uint32_t data_len, uint32_t lag, double autoc[]) +{ +#undef MAX_LAG +#define MAX_LAG 8 +#include "deduplication/lpc_compute_autocorrelation_intrin_neon.c" +} + +#endif /* ifdef FLAC__HAS_A64NEONINTRIN */ + + +#define MUL_32_BIT_LOOP_UNROOL_3(qlp_coeff_vec, lane) \ + summ_0 = vmulq_laneq_s32(tmp_vec[0], qlp_coeff_vec, lane); \ + summ_1 = vmulq_laneq_s32(tmp_vec[4], qlp_coeff_vec, lane); \ + summ_2 = vmulq_laneq_s32(tmp_vec[8], qlp_coeff_vec, lane); + + +#define MACC_32BIT_LOOP_UNROOL_3(tmp_vec_ind, qlp_coeff_vec, lane) \ + summ_0 = vmlaq_laneq_s32(summ_0,tmp_vec[tmp_vec_ind] ,qlp_coeff_vec, lane); \ + summ_1 = vmlaq_laneq_s32(summ_1,tmp_vec[tmp_vec_ind+4] ,qlp_coeff_vec, lane); \ + summ_2 = vmlaq_laneq_s32(summ_2,tmp_vec[tmp_vec_ind+8] ,qlp_coeff_vec, lane); + +void FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_neon(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]) +{ + int i; + FLAC__int32 sum; + int32x4_t tmp_vec[20]; + + FLAC__ASSERT(order > 0); + FLAC__ASSERT(order <= 32); + + // Using prologue reads is valid as encoder->private_->local_lpc_compute_residual_from_qlp_coefficients(signal+order,....) + if(order <= 12) { + if(order > 8) { + if(order > 10) { + if (order == 12) { + int32x4_t qlp_coeff_0 = {qlp_coeff[0], qlp_coeff[1], qlp_coeff[2], qlp_coeff[3]}; + int32x4_t qlp_coeff_1 = {qlp_coeff[4], qlp_coeff[5], qlp_coeff[6], qlp_coeff[7]}; + int32x4_t qlp_coeff_2 = {qlp_coeff[8], qlp_coeff[9], qlp_coeff[10], qlp_coeff[11]}; + + tmp_vec[0] = vld1q_s32(data - 12); + tmp_vec[1] = vld1q_s32(data - 11); + tmp_vec[2] = vld1q_s32(data - 10); + tmp_vec[3] = vld1q_s32(data - 9); + tmp_vec[4] = vld1q_s32(data - 8); + tmp_vec[5] = vld1q_s32(data - 7); + tmp_vec[6] = vld1q_s32(data - 6); + tmp_vec[7] = vld1q_s32(data - 5); + + for (i = 0; i < (int)data_len - 11; i += 12) + { + int32x4_t summ_0, summ_1, summ_2; + + tmp_vec[8] = vld1q_s32(data + i - 4); + tmp_vec[9] = vld1q_s32(data+i-3); + tmp_vec[10] = vld1q_s32(data+i-2); + tmp_vec[11] = vld1q_s32(data+i-1); + tmp_vec[12] = vld1q_s32(data+i); + tmp_vec[13] = vld1q_s32(data+i+1); + tmp_vec[14] = vld1q_s32(data+i+2); + tmp_vec[15] = vld1q_s32(data+i+3); + tmp_vec[16] = vld1q_s32(data + i + 4); + tmp_vec[17] = vld1q_s32(data + i + 5); + tmp_vec[18] = vld1q_s32(data + i + 6); + tmp_vec[19] = vld1q_s32(data + i + 7); + + MUL_32_BIT_LOOP_UNROOL_3(qlp_coeff_2, 3) + MACC_32BIT_LOOP_UNROOL_3(1, qlp_coeff_2, 2) + MACC_32BIT_LOOP_UNROOL_3(2, qlp_coeff_2, 1) + MACC_32BIT_LOOP_UNROOL_3(3, qlp_coeff_2, 0) + MACC_32BIT_LOOP_UNROOL_3(4, qlp_coeff_1, 3) + MACC_32BIT_LOOP_UNROOL_3(5, qlp_coeff_1, 2) + MACC_32BIT_LOOP_UNROOL_3(6, qlp_coeff_1, 1) + MACC_32BIT_LOOP_UNROOL_3(7, qlp_coeff_1, 0) + MACC_32BIT_LOOP_UNROOL_3(8, qlp_coeff_0, 3) + MACC_32BIT_LOOP_UNROOL_3(9, qlp_coeff_0, 2) + MACC_32BIT_LOOP_UNROOL_3(10, qlp_coeff_0, 1) + MACC_32BIT_LOOP_UNROOL_3(11, qlp_coeff_0, 0) + + vst1q_s32(residual+i + 0, vsubq_s32(vld1q_s32(data+i + 0) , vshlq_s32(summ_0,vdupq_n_s32(-lp_quantization)))); + vst1q_s32(residual+i + 4, vsubq_s32(vld1q_s32(data+i + 4) , vshlq_s32(summ_1,vdupq_n_s32(-lp_quantization)))); + vst1q_s32(residual+i + 8, vsubq_s32(vld1q_s32(data+i + 8) , vshlq_s32(summ_2,vdupq_n_s32(-lp_quantization)))); + + tmp_vec[0] = tmp_vec[12]; + tmp_vec[1] = tmp_vec[13]; + tmp_vec[2] = tmp_vec[14]; + tmp_vec[3] = tmp_vec[15]; + tmp_vec[4] = tmp_vec[16]; + tmp_vec[5] = tmp_vec[17]; + tmp_vec[6] = tmp_vec[18]; + tmp_vec[7] = tmp_vec[19]; + } + } + + else { /* order == 11 */ + int32x4_t qlp_coeff_0 = {qlp_coeff[0], qlp_coeff[1], qlp_coeff[2], qlp_coeff[3]}; + int32x4_t qlp_coeff_1 = {qlp_coeff[4], qlp_coeff[5], qlp_coeff[6], qlp_coeff[7]}; + int32x4_t qlp_coeff_2 = {qlp_coeff[8], qlp_coeff[9], qlp_coeff[10], 0}; + + tmp_vec[0] = vld1q_s32(data - 11); + tmp_vec[1] = vld1q_s32(data - 10); + tmp_vec[2] = vld1q_s32(data - 9); + tmp_vec[3] = vld1q_s32(data - 8); + tmp_vec[4] = vld1q_s32(data - 7); + tmp_vec[5] = vld1q_s32(data - 6); + tmp_vec[6] = vld1q_s32(data - 5); + + for (i = 0; i < (int)data_len - 11; i += 12) + { + int32x4_t summ_0, summ_1, summ_2; + tmp_vec[7] = vld1q_s32(data + i - 4); + tmp_vec[8] = vld1q_s32(data + i - 3); + tmp_vec[9] = vld1q_s32(data + i - 2); + tmp_vec[10] = vld1q_s32(data + i - 1); + tmp_vec[11] = vld1q_s32(data + i - 0); + tmp_vec[12] = vld1q_s32(data + i + 1); + tmp_vec[13] = vld1q_s32(data + i + 2); + tmp_vec[14] = vld1q_s32(data + i + 3); + tmp_vec[15] = vld1q_s32(data + i + 4); + tmp_vec[16] = vld1q_s32(data + i + 5); + tmp_vec[17] = vld1q_s32(data + i + 6); + tmp_vec[18] = vld1q_s32(data + i + 7); + + + MUL_32_BIT_LOOP_UNROOL_3(qlp_coeff_2, 2) + MACC_32BIT_LOOP_UNROOL_3(1, qlp_coeff_2, 1) + MACC_32BIT_LOOP_UNROOL_3(2, qlp_coeff_2, 0) + MACC_32BIT_LOOP_UNROOL_3(3, qlp_coeff_1, 3) + MACC_32BIT_LOOP_UNROOL_3(4, qlp_coeff_1, 2) + MACC_32BIT_LOOP_UNROOL_3(5, qlp_coeff_1, 1) + MACC_32BIT_LOOP_UNROOL_3(6, qlp_coeff_1, 0) + MACC_32BIT_LOOP_UNROOL_3(7, qlp_coeff_0, 3) + MACC_32BIT_LOOP_UNROOL_3(8, qlp_coeff_0, 2) + MACC_32BIT_LOOP_UNROOL_3(9, qlp_coeff_0, 1) + MACC_32BIT_LOOP_UNROOL_3(10, qlp_coeff_0, 0) + + vst1q_s32(residual+i + 0, vsubq_s32(vld1q_s32(data+i + 0) , vshlq_s32(summ_0,vdupq_n_s32(-lp_quantization)))); + vst1q_s32(residual+i + 4, vsubq_s32(vld1q_s32(data+i + 4) , vshlq_s32(summ_1,vdupq_n_s32(-lp_quantization)))); + vst1q_s32(residual+i + 8, vsubq_s32(vld1q_s32(data+i + 8) , vshlq_s32(summ_2,vdupq_n_s32(-lp_quantization)))); + + + tmp_vec[0] = tmp_vec[12]; + tmp_vec[1] = tmp_vec[13]; + tmp_vec[2] = tmp_vec[14]; + tmp_vec[3] = tmp_vec[15]; + tmp_vec[4] = tmp_vec[16]; + tmp_vec[5] = tmp_vec[17]; + tmp_vec[6] = tmp_vec[18]; + } + } + } + else { + if(order == 10) { + int32x4_t qlp_coeff_0 = {qlp_coeff[0], qlp_coeff[1], qlp_coeff[2], qlp_coeff[3]}; + int32x4_t qlp_coeff_1 = {qlp_coeff[4], qlp_coeff[5], qlp_coeff[6], qlp_coeff[7]}; + int32x4_t qlp_coeff_2 = {qlp_coeff[8], qlp_coeff[9], 0, 0}; + + tmp_vec[0] = vld1q_s32(data - 10); + tmp_vec[1] = vld1q_s32(data - 9); + tmp_vec[2] = vld1q_s32(data - 8); + tmp_vec[3] = vld1q_s32(data - 7); + tmp_vec[4] = vld1q_s32(data - 6); + tmp_vec[5] = vld1q_s32(data - 5); + + for (i = 0; i < (int)data_len - 11; i += 12) + { + int32x4_t summ_0, summ_1, summ_2; + tmp_vec[6] = vld1q_s32(data + i - 4); + tmp_vec[7] = vld1q_s32(data + i - 3); + tmp_vec[8] = vld1q_s32(data + i - 2); + tmp_vec[9] = vld1q_s32(data + i - 1); + tmp_vec[10] = vld1q_s32(data + i - 0); + tmp_vec[11] = vld1q_s32(data + i + 1); + tmp_vec[12] = vld1q_s32(data + i + 2); + tmp_vec[13] = vld1q_s32(data + i + 3); + tmp_vec[14] = vld1q_s32(data + i + 4); + tmp_vec[15] = vld1q_s32(data + i + 5); + tmp_vec[16] = vld1q_s32(data + i + 6); + tmp_vec[17] = vld1q_s32(data + i + 7); + + + MUL_32_BIT_LOOP_UNROOL_3(qlp_coeff_2, 1) + MACC_32BIT_LOOP_UNROOL_3(1, qlp_coeff_2, 0) + MACC_32BIT_LOOP_UNROOL_3(2, qlp_coeff_1, 3) + MACC_32BIT_LOOP_UNROOL_3(3, qlp_coeff_1, 2) + MACC_32BIT_LOOP_UNROOL_3(4, qlp_coeff_1, 1) + MACC_32BIT_LOOP_UNROOL_3(5, qlp_coeff_1, 0) + MACC_32BIT_LOOP_UNROOL_3(6, qlp_coeff_0, 3) + MACC_32BIT_LOOP_UNROOL_3(7, qlp_coeff_0, 2) + MACC_32BIT_LOOP_UNROOL_3(8, qlp_coeff_0, 1) + MACC_32BIT_LOOP_UNROOL_3(9, qlp_coeff_0, 0) + + vst1q_s32(residual+i + 0, vsubq_s32(vld1q_s32(data+i + 0) , vshlq_s32(summ_0,vdupq_n_s32(-lp_quantization)))); + vst1q_s32(residual+i + 4, vsubq_s32(vld1q_s32(data+i + 4) , vshlq_s32(summ_1,vdupq_n_s32(-lp_quantization)))); + vst1q_s32(residual+i + 8, vsubq_s32(vld1q_s32(data+i + 8) , vshlq_s32(summ_2,vdupq_n_s32(-lp_quantization)))); + + + tmp_vec[0] = tmp_vec[12]; + tmp_vec[1] = tmp_vec[13]; + tmp_vec[2] = tmp_vec[14]; + tmp_vec[3] = tmp_vec[15]; + tmp_vec[4] = tmp_vec[16]; + tmp_vec[5] = tmp_vec[17]; + } + } + else { /* order == 9 */ + int32x4_t qlp_coeff_0 = {qlp_coeff[0], qlp_coeff[1], qlp_coeff[2], qlp_coeff[3]}; + int32x4_t qlp_coeff_1 = {qlp_coeff[4], qlp_coeff[5], qlp_coeff[6], qlp_coeff[7]}; + int32x4_t qlp_coeff_2 = {qlp_coeff[8], 0, 0, 0}; + + tmp_vec[0] = vld1q_s32(data - 9); + tmp_vec[1] = vld1q_s32(data - 8); + tmp_vec[2] = vld1q_s32(data - 7); + tmp_vec[3] = vld1q_s32(data - 6); + tmp_vec[4] = vld1q_s32(data - 5); + + for (i = 0; i < (int)data_len - 11; i += 12) + { + int32x4_t summ_0, summ_1, summ_2; + tmp_vec[5] = vld1q_s32(data + i - 4); + tmp_vec[6] = vld1q_s32(data + i - 3); + tmp_vec[7] = vld1q_s32(data + i - 2); + tmp_vec[8] = vld1q_s32(data + i - 1); + tmp_vec[9] = vld1q_s32(data + i - 0); + tmp_vec[10] = vld1q_s32(data + i + 1); + tmp_vec[11] = vld1q_s32(data + i + 2); + tmp_vec[12] = vld1q_s32(data + i + 3); + tmp_vec[13] = vld1q_s32(data + i + 4); + tmp_vec[14] = vld1q_s32(data + i + 5); + tmp_vec[15] = vld1q_s32(data + i + 6); + tmp_vec[16] = vld1q_s32(data + i + 7); + + MUL_32_BIT_LOOP_UNROOL_3(qlp_coeff_2, 0) + MACC_32BIT_LOOP_UNROOL_3(1, qlp_coeff_1, 3) + MACC_32BIT_LOOP_UNROOL_3(2, qlp_coeff_1, 2) + MACC_32BIT_LOOP_UNROOL_3(3, qlp_coeff_1, 1) + MACC_32BIT_LOOP_UNROOL_3(4, qlp_coeff_1, 0) + MACC_32BIT_LOOP_UNROOL_3(5, qlp_coeff_0, 3) + MACC_32BIT_LOOP_UNROOL_3(6, qlp_coeff_0, 2) + MACC_32BIT_LOOP_UNROOL_3(7, qlp_coeff_0, 1) + MACC_32BIT_LOOP_UNROOL_3(8, qlp_coeff_0, 0) + + vst1q_s32(residual+i + 0, vsubq_s32(vld1q_s32(data+i + 0) , vshlq_s32(summ_0,vdupq_n_s32(-lp_quantization)))); + vst1q_s32(residual+i + 4, vsubq_s32(vld1q_s32(data+i + 4) , vshlq_s32(summ_1,vdupq_n_s32(-lp_quantization)))); + vst1q_s32(residual+i + 8, vsubq_s32(vld1q_s32(data+i + 8) , vshlq_s32(summ_2,vdupq_n_s32(-lp_quantization)))); + + tmp_vec[0] = tmp_vec[12]; + tmp_vec[1] = tmp_vec[13]; + tmp_vec[2] = tmp_vec[14]; + tmp_vec[3] = tmp_vec[15]; + tmp_vec[4] = tmp_vec[16]; + } + } + } + } + else if(order > 4) { + if(order > 6) { + if(order == 8) { + int32x4_t qlp_coeff_0 = {qlp_coeff[0], qlp_coeff[1], qlp_coeff[2], qlp_coeff[3]}; + int32x4_t qlp_coeff_1 = {qlp_coeff[4], qlp_coeff[5], qlp_coeff[6], qlp_coeff[7]}; + + tmp_vec[0] = vld1q_s32(data - 8); + tmp_vec[1] = vld1q_s32(data - 7); + tmp_vec[2] = vld1q_s32(data - 6); + tmp_vec[3] = vld1q_s32(data - 5); + + for (i = 0; i < (int)data_len - 11; i += 12) + { + int32x4_t summ_0, summ_1, summ_2; + tmp_vec[4] = vld1q_s32(data + i - 4); + tmp_vec[5] = vld1q_s32(data + i - 3); + tmp_vec[6] = vld1q_s32(data + i - 2); + tmp_vec[7] = vld1q_s32(data + i - 1); + tmp_vec[8] = vld1q_s32(data + i - 0); + tmp_vec[9] = vld1q_s32(data + i + 1); + tmp_vec[10] = vld1q_s32(data + i + 2); + tmp_vec[11] = vld1q_s32(data + i + 3); + tmp_vec[12] = vld1q_s32(data + i + 4); + tmp_vec[13] = vld1q_s32(data + i + 5); + tmp_vec[14] = vld1q_s32(data + i + 6); + tmp_vec[15] = vld1q_s32(data + i + 7); + + MUL_32_BIT_LOOP_UNROOL_3(qlp_coeff_1, 3) + MACC_32BIT_LOOP_UNROOL_3(1, qlp_coeff_1, 2) + MACC_32BIT_LOOP_UNROOL_3(2, qlp_coeff_1, 1) + MACC_32BIT_LOOP_UNROOL_3(3, qlp_coeff_1, 0) + MACC_32BIT_LOOP_UNROOL_3(4, qlp_coeff_0, 3) + MACC_32BIT_LOOP_UNROOL_3(5, qlp_coeff_0, 2) + MACC_32BIT_LOOP_UNROOL_3(6, qlp_coeff_0, 1) + MACC_32BIT_LOOP_UNROOL_3(7, qlp_coeff_0, 0) + + vst1q_s32(residual+i + 0, vsubq_s32(vld1q_s32(data+i + 0) , vshlq_s32(summ_0,vdupq_n_s32(-lp_quantization)))); + vst1q_s32(residual+i + 4, vsubq_s32(vld1q_s32(data+i + 4) , vshlq_s32(summ_1,vdupq_n_s32(-lp_quantization)))); + vst1q_s32(residual+i + 8, vsubq_s32(vld1q_s32(data+i + 8) , vshlq_s32(summ_2,vdupq_n_s32(-lp_quantization)))); + + tmp_vec[0] = tmp_vec[12]; + tmp_vec[1] = tmp_vec[13]; + tmp_vec[2] = tmp_vec[14]; + tmp_vec[3] = tmp_vec[15]; + } + } + else { /* order == 7 */ + int32x4_t qlp_coeff_0 = {qlp_coeff[0], qlp_coeff[1], qlp_coeff[2], qlp_coeff[3]}; + int32x4_t qlp_coeff_1 = {qlp_coeff[4], qlp_coeff[5], qlp_coeff[6], 0}; + + tmp_vec[0] = vld1q_s32(data - 7); + tmp_vec[1] = vld1q_s32(data - 6); + tmp_vec[2] = vld1q_s32(data - 5); + + for (i = 0; i < (int)data_len - 11; i += 12) + { + int32x4_t summ_0, summ_1, summ_2; + tmp_vec[3] = vld1q_s32(data + i - 4); + tmp_vec[4] = vld1q_s32(data + i - 3); + tmp_vec[5] = vld1q_s32(data + i - 2); + tmp_vec[6] = vld1q_s32(data + i - 1); + tmp_vec[7] = vld1q_s32(data + i - 0); + tmp_vec[8] = vld1q_s32(data + i + 1); + tmp_vec[9] = vld1q_s32(data + i + 2); + tmp_vec[10] = vld1q_s32(data + i + 3); + tmp_vec[11] = vld1q_s32(data + i + 4); + tmp_vec[12] = vld1q_s32(data + i + 5); + tmp_vec[13] = vld1q_s32(data + i + 6); + tmp_vec[14] = vld1q_s32(data + i + 7); + + MUL_32_BIT_LOOP_UNROOL_3(qlp_coeff_1, 2) + MACC_32BIT_LOOP_UNROOL_3(1, qlp_coeff_1, 1) + MACC_32BIT_LOOP_UNROOL_3(2, qlp_coeff_1, 0) + MACC_32BIT_LOOP_UNROOL_3(3, qlp_coeff_0, 3) + MACC_32BIT_LOOP_UNROOL_3(4, qlp_coeff_0, 2) + MACC_32BIT_LOOP_UNROOL_3(5, qlp_coeff_0, 1) + MACC_32BIT_LOOP_UNROOL_3(6, qlp_coeff_0, 0) + + vst1q_s32(residual+i + 0, vsubq_s32(vld1q_s32(data+i + 0) , vshlq_s32(summ_0,vdupq_n_s32(-lp_quantization)))); + vst1q_s32(residual+i + 4, vsubq_s32(vld1q_s32(data+i + 4) , vshlq_s32(summ_1,vdupq_n_s32(-lp_quantization)))); + vst1q_s32(residual+i + 8, vsubq_s32(vld1q_s32(data+i + 8) , vshlq_s32(summ_2,vdupq_n_s32(-lp_quantization)))); + + tmp_vec[0] = tmp_vec[12]; + tmp_vec[1] = tmp_vec[13]; + tmp_vec[2] = tmp_vec[14]; + } + } + } + else { + if(order == 6) { + int32x4_t qlp_coeff_0 = {qlp_coeff[0], qlp_coeff[1], qlp_coeff[2], qlp_coeff[3]}; + int32x4_t qlp_coeff_1 = {qlp_coeff[4], qlp_coeff[5], 0, 0}; + + tmp_vec[0] = vld1q_s32(data - 6); + tmp_vec[1] = vld1q_s32(data - 5); + + for (i = 0; i < (int)data_len - 11; i += 12) + { + int32x4_t summ_0, summ_1, summ_2; + tmp_vec[2] = vld1q_s32(data + i - 4); + tmp_vec[3] = vld1q_s32(data + i - 3); + tmp_vec[4] = vld1q_s32(data + i - 2); + tmp_vec[5] = vld1q_s32(data + i - 1); + tmp_vec[6] = vld1q_s32(data + i - 0); + tmp_vec[7] = vld1q_s32(data + i + 1); + tmp_vec[8] = vld1q_s32(data + i + 2); + tmp_vec[9] = vld1q_s32(data + i + 3); + tmp_vec[10] = vld1q_s32(data + i + 4); + tmp_vec[11] = vld1q_s32(data + i + 5); + tmp_vec[12] = vld1q_s32(data + i + 6); + tmp_vec[13] = vld1q_s32(data + i + 7); + + MUL_32_BIT_LOOP_UNROOL_3(qlp_coeff_1, 1) + MACC_32BIT_LOOP_UNROOL_3(1, qlp_coeff_1, 0) + MACC_32BIT_LOOP_UNROOL_3(2, qlp_coeff_0, 3) + MACC_32BIT_LOOP_UNROOL_3(3, qlp_coeff_0, 2) + MACC_32BIT_LOOP_UNROOL_3(4, qlp_coeff_0, 1) + MACC_32BIT_LOOP_UNROOL_3(5, qlp_coeff_0, 0) + + vst1q_s32(residual+i + 0, vsubq_s32(vld1q_s32(data+i + 0) , vshlq_s32(summ_0,vdupq_n_s32(-lp_quantization)))); + vst1q_s32(residual+i + 4, vsubq_s32(vld1q_s32(data+i + 4) , vshlq_s32(summ_1,vdupq_n_s32(-lp_quantization)))); + vst1q_s32(residual+i + 8, vsubq_s32(vld1q_s32(data+i + 8) , vshlq_s32(summ_2,vdupq_n_s32(-lp_quantization)))); + + tmp_vec[0] = tmp_vec[12]; + tmp_vec[1] = tmp_vec[13]; + } + } + else { /* order == 5 */ + int32x4_t qlp_coeff_0 = {qlp_coeff[0], qlp_coeff[1], qlp_coeff[2], qlp_coeff[3]}; + int32x4_t qlp_coeff_1 = {qlp_coeff[4], 0, 0, 0}; + + tmp_vec[0] = vld1q_s32(data - 5); + + for (i = 0; i < (int)data_len - 11; i += 12) + { + int32x4_t summ_0, summ_1, summ_2; + + tmp_vec[1] = vld1q_s32(data + i - 4); + tmp_vec[2] = vld1q_s32(data + i - 3); + tmp_vec[3] = vld1q_s32(data + i - 2); + tmp_vec[4] = vld1q_s32(data + i - 1); + tmp_vec[5] = vld1q_s32(data + i - 0); + tmp_vec[6] = vld1q_s32(data + i + 1); + tmp_vec[7] = vld1q_s32(data + i + 2); + tmp_vec[8] = vld1q_s32(data + i + 3); + tmp_vec[9] = vld1q_s32(data + i + 4); + tmp_vec[10] = vld1q_s32(data + i + 5); + tmp_vec[11] = vld1q_s32(data + i + 6); + tmp_vec[12] = vld1q_s32(data + i + 7); + + MUL_32_BIT_LOOP_UNROOL_3(qlp_coeff_1, 0) + MACC_32BIT_LOOP_UNROOL_3(1, qlp_coeff_0, 3) + MACC_32BIT_LOOP_UNROOL_3(2, qlp_coeff_0, 2) + MACC_32BIT_LOOP_UNROOL_3(3, qlp_coeff_0, 1) + MACC_32BIT_LOOP_UNROOL_3(4, qlp_coeff_0, 0) + + vst1q_s32(residual+i + 0, vsubq_s32(vld1q_s32(data+i + 0) , vshlq_s32(summ_0,vdupq_n_s32(-lp_quantization)))); + vst1q_s32(residual+i + 4, vsubq_s32(vld1q_s32(data+i + 4) , vshlq_s32(summ_1,vdupq_n_s32(-lp_quantization)))); + vst1q_s32(residual+i + 8, vsubq_s32(vld1q_s32(data+i + 8) , vshlq_s32(summ_2,vdupq_n_s32(-lp_quantization)))); + + tmp_vec[0] = tmp_vec[12]; + } + } + } + } + else { + if(order > 2) { + if(order == 4) { + int32x4_t qlp_coeff_0 = {qlp_coeff[0], qlp_coeff[1], qlp_coeff[2], qlp_coeff[3]}; + + for (i = 0; i < (int)data_len - 11; i += 12) + { + int32x4_t summ_0, summ_1, summ_2; + tmp_vec[0] = vld1q_s32(data + i - 4); + tmp_vec[1] = vld1q_s32(data + i - 3); + tmp_vec[2] = vld1q_s32(data + i - 2); + tmp_vec[3] = vld1q_s32(data + i - 1); + tmp_vec[4] = vld1q_s32(data + i - 0); + tmp_vec[5] = vld1q_s32(data + i + 1); + tmp_vec[6] = vld1q_s32(data + i + 2); + tmp_vec[7] = vld1q_s32(data + i + 3); + tmp_vec[8] = vld1q_s32(data + i + 4); + tmp_vec[9] = vld1q_s32(data + i + 5); + tmp_vec[10] = vld1q_s32(data + i + 6); + tmp_vec[11] = vld1q_s32(data + i + 7); + + MUL_32_BIT_LOOP_UNROOL_3(qlp_coeff_0, 3) + MACC_32BIT_LOOP_UNROOL_3(1, qlp_coeff_0, 2) + MACC_32BIT_LOOP_UNROOL_3(2, qlp_coeff_0, 1) + MACC_32BIT_LOOP_UNROOL_3(3, qlp_coeff_0, 0) + + vst1q_s32(residual+i + 0, vsubq_s32(vld1q_s32(data+i + 0) , vshlq_s32(summ_0,vdupq_n_s32(-lp_quantization)))); + vst1q_s32(residual+i + 4, vsubq_s32(vld1q_s32(data+i + 4) , vshlq_s32(summ_1,vdupq_n_s32(-lp_quantization)))); + vst1q_s32(residual+i + 8, vsubq_s32(vld1q_s32(data+i + 8) , vshlq_s32(summ_2,vdupq_n_s32(-lp_quantization)))); + } + } + else { /* order == 3 */ + int32x4_t qlp_coeff_0 = {qlp_coeff[0], qlp_coeff[1], qlp_coeff[2], 0}; + + for (i = 0; i < (int)data_len - 11; i += 12) + { + int32x4_t summ_0, summ_1, summ_2; + tmp_vec[0] = vld1q_s32(data + i - 3); + tmp_vec[1] = vld1q_s32(data + i - 2); + tmp_vec[2] = vld1q_s32(data + i - 1); + tmp_vec[4] = vld1q_s32(data + i + 1); + tmp_vec[5] = vld1q_s32(data + i + 2); + tmp_vec[6] = vld1q_s32(data + i + 3); + tmp_vec[8] = vld1q_s32(data + i + 5); + tmp_vec[9] = vld1q_s32(data + i + 6); + tmp_vec[10] = vld1q_s32(data + i + 7); + + MUL_32_BIT_LOOP_UNROOL_3(qlp_coeff_0, 2) + MACC_32BIT_LOOP_UNROOL_3(1, qlp_coeff_0, 1) + MACC_32BIT_LOOP_UNROOL_3(2, qlp_coeff_0, 0) + + vst1q_s32(residual+i + 0, vsubq_s32(vld1q_s32(data+i + 0) , vshlq_s32(summ_0,vdupq_n_s32(-lp_quantization)))); + vst1q_s32(residual+i + 4, vsubq_s32(vld1q_s32(data+i + 4) , vshlq_s32(summ_1,vdupq_n_s32(-lp_quantization)))); + vst1q_s32(residual+i + 8, vsubq_s32(vld1q_s32(data+i + 8) , vshlq_s32(summ_2,vdupq_n_s32(-lp_quantization)))); + } + } + } + else { + if(order == 2) { + int32x4_t qlp_coeff_0 = {qlp_coeff[0], qlp_coeff[1], 0, 0}; + + for (i = 0; i < (int)data_len - 11; i += 12) + { + int32x4_t summ_0, summ_1, summ_2; + tmp_vec[0] = vld1q_s32(data + i - 2); + tmp_vec[1] = vld1q_s32(data + i - 1); + tmp_vec[4] = vld1q_s32(data + i + 2); + tmp_vec[5] = vld1q_s32(data + i + 3); + tmp_vec[8] = vld1q_s32(data + i + 6); + tmp_vec[9] = vld1q_s32(data + i + 7); + + MUL_32_BIT_LOOP_UNROOL_3(qlp_coeff_0, 1) + MACC_32BIT_LOOP_UNROOL_3(1, qlp_coeff_0, 0) + + vst1q_s32(residual+i + 0, vsubq_s32(vld1q_s32(data+i + 0) , vshlq_s32(summ_0,vdupq_n_s32(-lp_quantization)))); + vst1q_s32(residual+i + 4, vsubq_s32(vld1q_s32(data+i + 4) , vshlq_s32(summ_1,vdupq_n_s32(-lp_quantization)))); + vst1q_s32(residual+i + 8, vsubq_s32(vld1q_s32(data+i + 8) , vshlq_s32(summ_2,vdupq_n_s32(-lp_quantization)))); + } + } + else { /* order == 1 */ + int32x4_t qlp_coeff_0 = vdupq_n_s32(qlp_coeff[0]); + + for (i = 0; i < (int)data_len - 11; i += 12) + { + int32x4_t summ_0, summ_1, summ_2; + tmp_vec[0] = vld1q_s32(data + i - 1); + tmp_vec[4] = vld1q_s32(data + i + 3); + tmp_vec[8] = vld1q_s32(data + i + 7); + + summ_0 = vmulq_s32(tmp_vec[0], qlp_coeff_0); + summ_1 = vmulq_s32(tmp_vec[4], qlp_coeff_0); + summ_2 = vmulq_s32(tmp_vec[8], qlp_coeff_0); + + vst1q_s32(residual+i + 0, vsubq_s32(vld1q_s32(data+i + 0) , vshlq_s32(summ_0,vdupq_n_s32(-lp_quantization)))); + vst1q_s32(residual+i + 4, vsubq_s32(vld1q_s32(data+i + 4) , vshlq_s32(summ_1,vdupq_n_s32(-lp_quantization)))); + vst1q_s32(residual+i + 8, vsubq_s32(vld1q_s32(data+i + 8) , vshlq_s32(summ_2,vdupq_n_s32(-lp_quantization)))); + } + } + } + } + for(; i < (int)data_len; i++) { + sum = 0; + switch(order) { + case 12: sum += qlp_coeff[11] * data[i-12]; /* Falls through. */ + case 11: sum += qlp_coeff[10] * data[i-11]; /* Falls through. */ + case 10: sum += qlp_coeff[ 9] * data[i-10]; /* Falls through. */ + case 9: sum += qlp_coeff[ 8] * data[i- 9]; /* Falls through. */ + case 8: sum += qlp_coeff[ 7] * data[i- 8]; /* Falls through. */ + case 7: sum += qlp_coeff[ 6] * data[i- 7]; /* Falls through. */ + case 6: sum += qlp_coeff[ 5] * data[i- 6]; /* Falls through. */ + case 5: sum += qlp_coeff[ 4] * data[i- 5]; /* Falls through. */ + case 4: sum += qlp_coeff[ 3] * data[i- 4]; /* Falls through. */ + case 3: sum += qlp_coeff[ 2] * data[i- 3]; /* Falls through. */ + case 2: sum += qlp_coeff[ 1] * data[i- 2]; /* Falls through. */ + case 1: sum += qlp_coeff[ 0] * data[i- 1]; + } + residual[i] = data[i] - (sum >> lp_quantization); + } + } + else { /* order > 12 */ + for(i = 0; i < (int)data_len; i++) { + sum = 0; + switch(order) { + case 32: sum += qlp_coeff[31] * data[i-32]; /* Falls through. */ + case 31: sum += qlp_coeff[30] * data[i-31]; /* Falls through. */ + case 30: sum += qlp_coeff[29] * data[i-30]; /* Falls through. */ + case 29: sum += qlp_coeff[28] * data[i-29]; /* Falls through. */ + case 28: sum += qlp_coeff[27] * data[i-28]; /* Falls through. */ + case 27: sum += qlp_coeff[26] * data[i-27]; /* Falls through. */ + case 26: sum += qlp_coeff[25] * data[i-26]; /* Falls through. */ + case 25: sum += qlp_coeff[24] * data[i-25]; /* Falls through. */ + case 24: sum += qlp_coeff[23] * data[i-24]; /* Falls through. */ + case 23: sum += qlp_coeff[22] * data[i-23]; /* Falls through. */ + case 22: sum += qlp_coeff[21] * data[i-22]; /* Falls through. */ + case 21: sum += qlp_coeff[20] * data[i-21]; /* Falls through. */ + case 20: sum += qlp_coeff[19] * data[i-20]; /* Falls through. */ + case 19: sum += qlp_coeff[18] * data[i-19]; /* Falls through. */ + case 18: sum += qlp_coeff[17] * data[i-18]; /* Falls through. */ + case 17: sum += qlp_coeff[16] * data[i-17]; /* Falls through. */ + case 16: sum += qlp_coeff[15] * data[i-16]; /* Falls through. */ + case 15: sum += qlp_coeff[14] * data[i-15]; /* Falls through. */ + case 14: sum += qlp_coeff[13] * data[i-14]; /* Falls through. */ + case 13: sum += qlp_coeff[12] * data[i-13]; + sum += qlp_coeff[11] * data[i-12]; + sum += qlp_coeff[10] * data[i-11]; + sum += qlp_coeff[ 9] * data[i-10]; + sum += qlp_coeff[ 8] * data[i- 9]; + sum += qlp_coeff[ 7] * data[i- 8]; + sum += qlp_coeff[ 6] * data[i- 7]; + sum += qlp_coeff[ 5] * data[i- 6]; + sum += qlp_coeff[ 4] * data[i- 5]; + sum += qlp_coeff[ 3] * data[i- 4]; + sum += qlp_coeff[ 2] * data[i- 3]; + sum += qlp_coeff[ 1] * data[i- 2]; + sum += qlp_coeff[ 0] * data[i- 1]; + } + residual[i] = data[i] - (sum >> lp_quantization); + } + } +} + + + +#define MUL_64_BIT_LOOP_UNROOL_3(qlp_coeff_vec, lane) \ + summ_l_0 = vmull_laneq_s32(vget_low_s32(tmp_vec[0]),qlp_coeff_vec, lane); \ + summ_h_0 = vmull_high_laneq_s32(tmp_vec[0], qlp_coeff_vec, lane);\ + summ_l_1 = vmull_laneq_s32(vget_low_s32(tmp_vec[4]),qlp_coeff_vec, lane); \ + summ_h_1 = vmull_high_laneq_s32(tmp_vec[4], qlp_coeff_vec, lane);\ + summ_l_2 = vmull_laneq_s32(vget_low_s32(tmp_vec[8]),qlp_coeff_vec, lane);\ + summ_h_2 = vmull_high_laneq_s32(tmp_vec[8], qlp_coeff_vec, lane); + + +#define MACC_64_BIT_LOOP_UNROOL_3(tmp_vec_ind, qlp_coeff_vec, lane) \ + summ_l_0 = vmlal_laneq_s32(summ_l_0,vget_low_s32(tmp_vec[tmp_vec_ind]),qlp_coeff_vec, lane); \ + summ_h_0 = vmlal_high_laneq_s32(summ_h_0, tmp_vec[tmp_vec_ind], qlp_coeff_vec, lane); \ + summ_l_1 = vmlal_laneq_s32(summ_l_1, vget_low_s32(tmp_vec[tmp_vec_ind+4]),qlp_coeff_vec, lane); \ + summ_h_1 = vmlal_high_laneq_s32(summ_h_1, tmp_vec[tmp_vec_ind+4], qlp_coeff_vec, lane); \ + summ_l_2 = vmlal_laneq_s32(summ_l_2, vget_low_s32(tmp_vec[tmp_vec_ind+8]),qlp_coeff_vec, lane);\ + summ_h_2 = vmlal_high_laneq_s32(summ_h_2,tmp_vec[tmp_vec_ind+8], qlp_coeff_vec, lane); + +#define SHIFT_SUMS_64BITS_AND_STORE_SUB() \ + res0 = vuzp1q_s32(vreinterpretq_s32_s64(vshlq_s64(summ_l_0,lp_quantization_vec)), vreinterpretq_s32_s64(vshlq_s64(summ_h_0,lp_quantization_vec))); \ + res1 = vuzp1q_s32(vreinterpretq_s32_s64(vshlq_s64(summ_l_1,lp_quantization_vec)), vreinterpretq_s32_s64(vshlq_s64(summ_h_1,lp_quantization_vec))); \ + res2 = vuzp1q_s32(vreinterpretq_s32_s64(vshlq_s64(summ_l_2,lp_quantization_vec)), vreinterpretq_s32_s64(vshlq_s64(summ_h_2,lp_quantization_vec))); \ + vst1q_s32(residual+i+0, vsubq_s32(vld1q_s32(data+i+0), res0));\ + vst1q_s32(residual+i+4, vsubq_s32(vld1q_s32(data+i+4), res1));\ + vst1q_s32(residual+i+8, vsubq_s32(vld1q_s32(data+i+8), res2)); + +void FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_neon(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]) { + int i; + FLAC__int64 sum; + + int32x4_t tmp_vec[20]; + int32x4_t res0, res1, res2; + int64x2_t lp_quantization_vec = vdupq_n_s64(-lp_quantization); + + FLAC__ASSERT(order > 0); + FLAC__ASSERT(order <= 32); + + // Using prologue reads is valid as encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit(signal+order,....) + if(order <= 12) { + if(order > 8) { + if(order > 10) { + if(order == 12) { + int32x4_t qlp_coeff_0 = {qlp_coeff[0], qlp_coeff[1], qlp_coeff[2], qlp_coeff[3]}; + int32x4_t qlp_coeff_1 = {qlp_coeff[4],qlp_coeff[5],qlp_coeff[6],qlp_coeff[7]}; + int32x4_t qlp_coeff_2 = {qlp_coeff[8],qlp_coeff[9],qlp_coeff[10],qlp_coeff[11]}; + + tmp_vec[0] = vld1q_s32(data - 12); + tmp_vec[1] = vld1q_s32(data - 11); + tmp_vec[2] = vld1q_s32(data - 10); + tmp_vec[3] = vld1q_s32(data - 9); + tmp_vec[4] = vld1q_s32(data - 8); + tmp_vec[5] = vld1q_s32(data - 7); + tmp_vec[6] = vld1q_s32(data - 6); + tmp_vec[7] = vld1q_s32(data - 5); + + for (i = 0; i < (int)data_len - 11; i += 12) + { + int64x2_t summ_l_0, summ_h_0, summ_l_1, summ_h_1, summ_l_2, summ_h_2; + + tmp_vec[8] = vld1q_s32(data+i-4); + tmp_vec[9] = vld1q_s32(data+i-3); + tmp_vec[10] = vld1q_s32(data+i-2); + tmp_vec[11] = vld1q_s32(data+i-1); + tmp_vec[12] = vld1q_s32(data+i); + tmp_vec[13] = vld1q_s32(data+i+1); + tmp_vec[14] = vld1q_s32(data+i+2); + tmp_vec[15] = vld1q_s32(data+i+3); + tmp_vec[16] = vld1q_s32(data + i + 4); + tmp_vec[17] = vld1q_s32(data + i + 5); + tmp_vec[18] = vld1q_s32(data + i + 6); + tmp_vec[19] = vld1q_s32(data + i + 7); + + MUL_64_BIT_LOOP_UNROOL_3(qlp_coeff_2, 3) + MACC_64_BIT_LOOP_UNROOL_3(1, qlp_coeff_2, 2) + MACC_64_BIT_LOOP_UNROOL_3(2, qlp_coeff_2, 1) + MACC_64_BIT_LOOP_UNROOL_3(3, qlp_coeff_2, 0) + MACC_64_BIT_LOOP_UNROOL_3(4, qlp_coeff_1, 3) + MACC_64_BIT_LOOP_UNROOL_3(5, qlp_coeff_1, 2) + MACC_64_BIT_LOOP_UNROOL_3(6, qlp_coeff_1, 1) + MACC_64_BIT_LOOP_UNROOL_3(7, qlp_coeff_1, 0) + MACC_64_BIT_LOOP_UNROOL_3(8, qlp_coeff_0, 3) + MACC_64_BIT_LOOP_UNROOL_3(9, qlp_coeff_0, 2) + MACC_64_BIT_LOOP_UNROOL_3(10,qlp_coeff_0, 1) + MACC_64_BIT_LOOP_UNROOL_3(11,qlp_coeff_0, 0) + + SHIFT_SUMS_64BITS_AND_STORE_SUB() + + tmp_vec[0] = tmp_vec[12]; + tmp_vec[1] = tmp_vec[13]; + tmp_vec[2] = tmp_vec[14]; + tmp_vec[3] = tmp_vec[15]; + tmp_vec[4] = tmp_vec[16]; + tmp_vec[5] = tmp_vec[17]; + tmp_vec[6] = tmp_vec[18]; + tmp_vec[7] = tmp_vec[19]; + } + } + else { /* order == 11 */ + int32x4_t qlp_coeff_0 = {qlp_coeff[0], qlp_coeff[1], qlp_coeff[2], qlp_coeff[3]}; + int32x4_t qlp_coeff_1 = {qlp_coeff[4],qlp_coeff[5],qlp_coeff[6],qlp_coeff[7]}; + int32x4_t qlp_coeff_2 = {qlp_coeff[8],qlp_coeff[9],qlp_coeff[10],0}; + + tmp_vec[0] = vld1q_s32(data - 11); + tmp_vec[1] = vld1q_s32(data - 10); + tmp_vec[2] = vld1q_s32(data - 9); + tmp_vec[3] = vld1q_s32(data - 8); + tmp_vec[4] = vld1q_s32(data - 7); + tmp_vec[5] = vld1q_s32(data - 6); + tmp_vec[6] = vld1q_s32(data - 5); + + for (i = 0; i < (int)data_len - 11; i += 12) + { + int64x2_t summ_l_0, summ_h_0, summ_l_1, summ_h_1, summ_l_2, summ_h_2; + + tmp_vec[7] = vld1q_s32(data+i-4); + tmp_vec[8] = vld1q_s32(data+i-3); + tmp_vec[9] = vld1q_s32(data+i-2); + tmp_vec[10] = vld1q_s32(data+i-1); + tmp_vec[11] = vld1q_s32(data+i); + tmp_vec[12] = vld1q_s32(data+i+1); + tmp_vec[13] = vld1q_s32(data+i+2); + tmp_vec[14] = vld1q_s32(data+i+3); + tmp_vec[15] = vld1q_s32(data + i + 4); + tmp_vec[16] = vld1q_s32(data + i + 5); + tmp_vec[17] = vld1q_s32(data + i + 6); + tmp_vec[18] = vld1q_s32(data + i + 7); + + MUL_64_BIT_LOOP_UNROOL_3(qlp_coeff_2, 2) + MACC_64_BIT_LOOP_UNROOL_3(1, qlp_coeff_2, 1) + MACC_64_BIT_LOOP_UNROOL_3(2, qlp_coeff_2, 0) + MACC_64_BIT_LOOP_UNROOL_3(3, qlp_coeff_1, 3) + MACC_64_BIT_LOOP_UNROOL_3(4, qlp_coeff_1, 2) + MACC_64_BIT_LOOP_UNROOL_3(5, qlp_coeff_1, 1) + MACC_64_BIT_LOOP_UNROOL_3(6, qlp_coeff_1, 0) + MACC_64_BIT_LOOP_UNROOL_3(7, qlp_coeff_0, 3) + MACC_64_BIT_LOOP_UNROOL_3(8, qlp_coeff_0, 2) + MACC_64_BIT_LOOP_UNROOL_3(9, qlp_coeff_0, 1) + MACC_64_BIT_LOOP_UNROOL_3(10,qlp_coeff_0, 0) + + SHIFT_SUMS_64BITS_AND_STORE_SUB() + + tmp_vec[0] = tmp_vec[12]; + tmp_vec[1] = tmp_vec[13]; + tmp_vec[2] = tmp_vec[14]; + tmp_vec[3] = tmp_vec[15]; + tmp_vec[4] = tmp_vec[16]; + tmp_vec[5] = tmp_vec[17]; + tmp_vec[6] = tmp_vec[18]; + } + } + } + else + { + if (order == 10) { + int32x4_t qlp_coeff_0 = {qlp_coeff[0], qlp_coeff[1], qlp_coeff[2], qlp_coeff[3]}; + int32x4_t qlp_coeff_1 = {qlp_coeff[4], qlp_coeff[5], qlp_coeff[6], qlp_coeff[7]}; + int32x4_t qlp_coeff_2 = {qlp_coeff[8], qlp_coeff[9], 0, 0}; + + tmp_vec[0] = vld1q_s32(data - 10); + tmp_vec[1] = vld1q_s32(data - 9); + tmp_vec[2] = vld1q_s32(data - 8); + tmp_vec[3] = vld1q_s32(data - 7); + tmp_vec[4] = vld1q_s32(data - 6); + tmp_vec[5] = vld1q_s32(data - 5); + + + for (i = 0; i < (int)data_len - 11; i += 12) + { + int64x2_t summ_l_0, summ_h_0, summ_l_1, summ_h_1, summ_l_2, summ_h_2; + + tmp_vec[6] = vld1q_s32(data + i - 4); + tmp_vec[7] = vld1q_s32(data + i - 3); + tmp_vec[8] = vld1q_s32(data + i - 2); + tmp_vec[9] = vld1q_s32(data + i - 1); + tmp_vec[10] = vld1q_s32(data + i - 0); + tmp_vec[11] = vld1q_s32(data + i + 1); + tmp_vec[12] = vld1q_s32(data + i + 2); + tmp_vec[13] = vld1q_s32(data + i + 3); + tmp_vec[14] = vld1q_s32(data + i + 4); + tmp_vec[15] = vld1q_s32(data + i + 5); + tmp_vec[16] = vld1q_s32(data + i + 6); + tmp_vec[17] = vld1q_s32(data + i + 7); + + MUL_64_BIT_LOOP_UNROOL_3(qlp_coeff_2, 1) + MACC_64_BIT_LOOP_UNROOL_3(1, qlp_coeff_2, 0) + MACC_64_BIT_LOOP_UNROOL_3(2, qlp_coeff_1, 3) + MACC_64_BIT_LOOP_UNROOL_3(3, qlp_coeff_1, 2) + MACC_64_BIT_LOOP_UNROOL_3(4, qlp_coeff_1, 1) + MACC_64_BIT_LOOP_UNROOL_3(5, qlp_coeff_1, 0) + MACC_64_BIT_LOOP_UNROOL_3(6, qlp_coeff_0, 3) + MACC_64_BIT_LOOP_UNROOL_3(7, qlp_coeff_0, 2) + MACC_64_BIT_LOOP_UNROOL_3(8, qlp_coeff_0, 1) + MACC_64_BIT_LOOP_UNROOL_3(9, qlp_coeff_0, 0) + + SHIFT_SUMS_64BITS_AND_STORE_SUB() + + tmp_vec[0] = tmp_vec[12]; + tmp_vec[1] = tmp_vec[13]; + tmp_vec[2] = tmp_vec[14]; + tmp_vec[3] = tmp_vec[15]; + tmp_vec[4] = tmp_vec[16]; + tmp_vec[5] = tmp_vec[17]; + } + } + + else /* order == 9 */ { + int32x4_t qlp_coeff_0 = {qlp_coeff[0], qlp_coeff[1], qlp_coeff[2], qlp_coeff[3]}; + int32x4_t qlp_coeff_1 = {qlp_coeff[4], qlp_coeff[5], qlp_coeff[6], qlp_coeff[7]}; + int32x4_t qlp_coeff_2 = {qlp_coeff[8], 0, 0, 0}; + + tmp_vec[0] = vld1q_s32(data - 9); + tmp_vec[1] = vld1q_s32(data - 8); + tmp_vec[2] = vld1q_s32(data - 7); + tmp_vec[3] = vld1q_s32(data - 6); + tmp_vec[4] = vld1q_s32(data - 5); + + for (i = 0; i < (int)data_len - 11; i += 12) + { + int64x2_t summ_l_0, summ_h_0, summ_l_1, summ_h_1, summ_l_2, summ_h_2; + + tmp_vec[5] = vld1q_s32(data + i - 4); + tmp_vec[6] = vld1q_s32(data + i - 3); + tmp_vec[7] = vld1q_s32(data + i - 2); + tmp_vec[8] = vld1q_s32(data + i - 1); + tmp_vec[9] = vld1q_s32(data + i - 0); + tmp_vec[10] = vld1q_s32(data + i + 1); + tmp_vec[11] = vld1q_s32(data + i + 2); + tmp_vec[12] = vld1q_s32(data + i + 3); + tmp_vec[13] = vld1q_s32(data + i + 4); + tmp_vec[14] = vld1q_s32(data + i + 5); + tmp_vec[15] = vld1q_s32(data + i + 6); + tmp_vec[16] = vld1q_s32(data + i + 7); + + MUL_64_BIT_LOOP_UNROOL_3(qlp_coeff_2, 0) + MACC_64_BIT_LOOP_UNROOL_3(1, qlp_coeff_1, 3) + MACC_64_BIT_LOOP_UNROOL_3(2, qlp_coeff_1, 2) + MACC_64_BIT_LOOP_UNROOL_3(3, qlp_coeff_1, 1) + MACC_64_BIT_LOOP_UNROOL_3(4, qlp_coeff_1, 0) + MACC_64_BIT_LOOP_UNROOL_3(5, qlp_coeff_0, 3) + MACC_64_BIT_LOOP_UNROOL_3(6, qlp_coeff_0, 2) + MACC_64_BIT_LOOP_UNROOL_3(7, qlp_coeff_0, 1) + MACC_64_BIT_LOOP_UNROOL_3(8, qlp_coeff_0, 0) + + SHIFT_SUMS_64BITS_AND_STORE_SUB() + + tmp_vec[0] = tmp_vec[12]; + tmp_vec[1] = tmp_vec[13]; + tmp_vec[2] = tmp_vec[14]; + tmp_vec[3] = tmp_vec[15]; + tmp_vec[4] = tmp_vec[16]; + } + } + } + } + else if (order > 4) + { + if (order > 6) + { + if (order == 8) + { + int32x4_t qlp_coeff_0 = {qlp_coeff[0], qlp_coeff[1], qlp_coeff[2], qlp_coeff[3]}; + int32x4_t qlp_coeff_1 = {qlp_coeff[4], qlp_coeff[5], qlp_coeff[6], qlp_coeff[7]}; + + tmp_vec[0] = vld1q_s32(data - 8); + tmp_vec[1] = vld1q_s32(data - 7); + tmp_vec[2] = vld1q_s32(data - 6); + tmp_vec[3] = vld1q_s32(data - 5); + + for (i = 0; i < (int)data_len - 11; i += 12) + { + int64x2_t summ_l_0, summ_h_0, summ_l_1, summ_h_1, summ_l_2, summ_h_2; + + tmp_vec[4] = vld1q_s32(data + i - 4); + tmp_vec[5] = vld1q_s32(data + i - 3); + tmp_vec[6] = vld1q_s32(data + i - 2); + tmp_vec[7] = vld1q_s32(data + i - 1); + tmp_vec[8] = vld1q_s32(data + i - 0); + tmp_vec[9] = vld1q_s32(data + i + 1); + tmp_vec[10] = vld1q_s32(data + i + 2); + tmp_vec[11] = vld1q_s32(data + i + 3); + tmp_vec[12] = vld1q_s32(data + i + 4); + tmp_vec[13] = vld1q_s32(data + i + 5); + tmp_vec[14] = vld1q_s32(data + i + 6); + tmp_vec[15] = vld1q_s32(data + i + 7); + + + MUL_64_BIT_LOOP_UNROOL_3(qlp_coeff_1, 3) + MACC_64_BIT_LOOP_UNROOL_3(1, qlp_coeff_1, 2) + MACC_64_BIT_LOOP_UNROOL_3(2, qlp_coeff_1, 1) + MACC_64_BIT_LOOP_UNROOL_3(3, qlp_coeff_1, 0) + MACC_64_BIT_LOOP_UNROOL_3(4, qlp_coeff_0, 3) + MACC_64_BIT_LOOP_UNROOL_3(5, qlp_coeff_0, 2) + MACC_64_BIT_LOOP_UNROOL_3(6, qlp_coeff_0, 1) + MACC_64_BIT_LOOP_UNROOL_3(7, qlp_coeff_0, 0) + + SHIFT_SUMS_64BITS_AND_STORE_SUB() + + tmp_vec[0] = tmp_vec[12]; + tmp_vec[1] = tmp_vec[13]; + tmp_vec[2] = tmp_vec[14]; + tmp_vec[3] = tmp_vec[15]; + } + } + else /* order == 7 */ + { + int32x4_t qlp_coeff_0 = {qlp_coeff[0], qlp_coeff[1], qlp_coeff[2], qlp_coeff[3]}; + int32x4_t qlp_coeff_1 = {qlp_coeff[4], qlp_coeff[5], qlp_coeff[6], 0}; + + tmp_vec[0] = vld1q_s32(data - 7); + tmp_vec[1] = vld1q_s32(data - 6); + tmp_vec[2] = vld1q_s32(data - 5); + + + for (i = 0; i < (int)data_len - 11; i += 12) + { + int64x2_t summ_l_0, summ_h_0, summ_l_1, summ_h_1, summ_l_2, summ_h_2; + tmp_vec[3] = vld1q_s32(data +i - 4); + tmp_vec[4] = vld1q_s32(data + i - 3); + tmp_vec[5] = vld1q_s32(data + i - 2); + tmp_vec[6] = vld1q_s32(data + i - 1); + tmp_vec[7] = vld1q_s32(data + i - 0); + tmp_vec[8] = vld1q_s32(data + i + 1); + tmp_vec[9] = vld1q_s32(data + i + 2); + tmp_vec[10] = vld1q_s32(data + i + 3); + tmp_vec[11] = vld1q_s32(data + i + 4); + tmp_vec[12] = vld1q_s32(data + i + 5); + tmp_vec[13] = vld1q_s32(data + i + 6); + tmp_vec[14] = vld1q_s32(data + i + 7); + + + MUL_64_BIT_LOOP_UNROOL_3(qlp_coeff_1, 2) + MACC_64_BIT_LOOP_UNROOL_3(1, qlp_coeff_1, 1) + MACC_64_BIT_LOOP_UNROOL_3(2, qlp_coeff_1, 0) + MACC_64_BIT_LOOP_UNROOL_3(3, qlp_coeff_0, 3) + MACC_64_BIT_LOOP_UNROOL_3(4, qlp_coeff_0, 2) + MACC_64_BIT_LOOP_UNROOL_3(5, qlp_coeff_0, 1) + MACC_64_BIT_LOOP_UNROOL_3(6, qlp_coeff_0, 0) + + SHIFT_SUMS_64BITS_AND_STORE_SUB() + + tmp_vec[0] = tmp_vec[12]; + tmp_vec[1] = tmp_vec[13]; + tmp_vec[2] = tmp_vec[14]; + } + } + } + else + { + if (order == 6) { + int32x4_t qlp_coeff_0 = {qlp_coeff[0], qlp_coeff[1], qlp_coeff[2], qlp_coeff[3]}; + int32x4_t qlp_coeff_1 = {qlp_coeff[4], qlp_coeff[5], 0, 0}; + + tmp_vec[0] = vld1q_s32(data - 6); + tmp_vec[1] = vld1q_s32(data - 5); + + for (i = 0; i < (int)data_len - 11; i += 12) + { + int64x2_t summ_l_0, summ_h_0, summ_l_1, summ_h_1, summ_l_2, summ_h_2; + + tmp_vec[2] = vld1q_s32(data + i - 4); + tmp_vec[3] = vld1q_s32(data + i - 3); + tmp_vec[4] = vld1q_s32(data + i - 2); + tmp_vec[5] = vld1q_s32(data + i - 1); + tmp_vec[6] = vld1q_s32(data + i - 0); + tmp_vec[7] = vld1q_s32(data + i + 1); + tmp_vec[8] = vld1q_s32(data + i + 2); + tmp_vec[9] = vld1q_s32(data + i + 3); + tmp_vec[10] = vld1q_s32(data + i + 4); + tmp_vec[11] = vld1q_s32(data + i + 5); + tmp_vec[12] = vld1q_s32(data + i + 6); + tmp_vec[13] = vld1q_s32(data + i + 7); + + + MUL_64_BIT_LOOP_UNROOL_3(qlp_coeff_1, 1) + MACC_64_BIT_LOOP_UNROOL_3(1, qlp_coeff_1, 0) + MACC_64_BIT_LOOP_UNROOL_3(2, qlp_coeff_0, 3) + MACC_64_BIT_LOOP_UNROOL_3(3, qlp_coeff_0, 2) + MACC_64_BIT_LOOP_UNROOL_3(4, qlp_coeff_0, 1) + MACC_64_BIT_LOOP_UNROOL_3(5, qlp_coeff_0, 0) + + SHIFT_SUMS_64BITS_AND_STORE_SUB() + + tmp_vec[0] = tmp_vec[12]; + tmp_vec[1] = tmp_vec[13]; + } + } + + else + { /* order == 5 */ + int32x4_t qlp_coeff_0 = {qlp_coeff[0], qlp_coeff[1], qlp_coeff[2], qlp_coeff[3]}; + int32x4_t qlp_coeff_1 = {qlp_coeff[4], 0, 0, 0}; + + tmp_vec[0] = vld1q_s32(data - 5); + + for (i = 0; i < (int)data_len - 11; i += 12) + { + int64x2_t summ_l_0, summ_h_0, summ_l_1, summ_h_1, summ_l_2, summ_h_2; + tmp_vec[1] = vld1q_s32(data + i - 4); + tmp_vec[2] = vld1q_s32(data + i - 3); + tmp_vec[3] = vld1q_s32(data + i - 2); + tmp_vec[4] = vld1q_s32(data + i - 1); + tmp_vec[5] = vld1q_s32(data + i - 0); + tmp_vec[6] = vld1q_s32(data + i + 1); + tmp_vec[7] = vld1q_s32(data + i + 2); + tmp_vec[8] = vld1q_s32(data + i + 3); + tmp_vec[9] = vld1q_s32(data + i + 4); + tmp_vec[10] = vld1q_s32(data + i + 5); + tmp_vec[11] = vld1q_s32(data + i + 6); + tmp_vec[12] = vld1q_s32(data + i + 7); + + MUL_64_BIT_LOOP_UNROOL_3(qlp_coeff_1, 0) + MACC_64_BIT_LOOP_UNROOL_3(1, qlp_coeff_0, 3) + MACC_64_BIT_LOOP_UNROOL_3(2, qlp_coeff_0, 2) + MACC_64_BIT_LOOP_UNROOL_3(3, qlp_coeff_0, 1) + MACC_64_BIT_LOOP_UNROOL_3(4, qlp_coeff_0, 0) + + SHIFT_SUMS_64BITS_AND_STORE_SUB() + + tmp_vec[0] = tmp_vec[12]; + } + } + } + } + else + { + if (order > 2) + { + if (order == 4) + { + int32x4_t qlp_coeff_0 = {qlp_coeff[0], qlp_coeff[1], qlp_coeff[2], qlp_coeff[3]}; + + for (i = 0; i < (int)data_len - 11; i += 12) + { + int64x2_t summ_l_0, summ_h_0, summ_l_1, summ_h_1, summ_l_2, summ_h_2; + tmp_vec[0] = vld1q_s32(data + i - 4); + tmp_vec[1] = vld1q_s32(data + i - 3); + tmp_vec[2] = vld1q_s32(data + i - 2); + tmp_vec[3] = vld1q_s32(data + i - 1); + tmp_vec[4] = vld1q_s32(data + i - 0); + tmp_vec[5] = vld1q_s32(data + i + 1); + tmp_vec[6] = vld1q_s32(data + i + 2); + tmp_vec[7] = vld1q_s32(data + i + 3); + tmp_vec[8] = vld1q_s32(data + i + 4); + tmp_vec[9] = vld1q_s32(data + i + 5); + tmp_vec[10] = vld1q_s32(data + i + 6); + tmp_vec[11] = vld1q_s32(data + i + 7); + + MUL_64_BIT_LOOP_UNROOL_3(qlp_coeff_0, 3) + MACC_64_BIT_LOOP_UNROOL_3(1, qlp_coeff_0, 2) + MACC_64_BIT_LOOP_UNROOL_3(2, qlp_coeff_0, 1) + MACC_64_BIT_LOOP_UNROOL_3(3, qlp_coeff_0, 0) + + SHIFT_SUMS_64BITS_AND_STORE_SUB() + } + } + else + { /* order == 3 */ + + int32x4_t qlp_coeff_0 = {qlp_coeff[0], qlp_coeff[1], qlp_coeff[2], 0}; + + for (i = 0; i < (int)data_len - 11; i += 12) + { + int64x2_t summ_l_0, summ_h_0, summ_l_1, summ_h_1, summ_l_2, summ_h_2; + tmp_vec[0] = vld1q_s32(data + i - 3); + tmp_vec[1] = vld1q_s32(data + i - 2); + tmp_vec[2] = vld1q_s32(data + i - 1); + tmp_vec[4] = vld1q_s32(data + i + 1); + tmp_vec[5] = vld1q_s32(data + i + 2); + tmp_vec[6] = vld1q_s32(data + i + 3); + tmp_vec[8] = vld1q_s32(data + i + 5); + tmp_vec[9] = vld1q_s32(data + i + 6); + tmp_vec[10] = vld1q_s32(data + i + 7); + + MUL_64_BIT_LOOP_UNROOL_3(qlp_coeff_0, 2) + MACC_64_BIT_LOOP_UNROOL_3(1, qlp_coeff_0, 1) + MACC_64_BIT_LOOP_UNROOL_3(2, qlp_coeff_0, 0) + + SHIFT_SUMS_64BITS_AND_STORE_SUB() + } + } + } + else + { + if (order == 2) + { + int32x4_t qlp_coeff_0 = {qlp_coeff[0], qlp_coeff[1], 0, 0}; + + for (i = 0; i < (int)data_len - 11; i += 12) + { + int64x2_t summ_l_0, summ_h_0, summ_l_1, summ_h_1, summ_l_2, summ_h_2; + tmp_vec[0] = vld1q_s32(data + i - 2); + tmp_vec[1] = vld1q_s32(data + i - 1); + tmp_vec[4] = vld1q_s32(data + i + 2); + tmp_vec[5] = vld1q_s32(data + i + 3); + tmp_vec[8] = vld1q_s32(data + i + 6); + tmp_vec[9] = vld1q_s32(data + i + 7); + + MUL_64_BIT_LOOP_UNROOL_3(qlp_coeff_0, 1) + MACC_64_BIT_LOOP_UNROOL_3(1, qlp_coeff_0, 0) + + SHIFT_SUMS_64BITS_AND_STORE_SUB() + } + } + + else + { /* order == 1 */ + + int32x2_t qlp_coeff_0_2 = vdup_n_s32(qlp_coeff[0]); + int32x4_t qlp_coeff_0_4 = vdupq_n_s32(qlp_coeff[0]); + + for (i = 0; i < (int)data_len - 11; i += 12) + { + int64x2_t summ_l_0, summ_h_0, summ_l_1, summ_h_1, summ_l_2, summ_h_2; + tmp_vec[0] = vld1q_s32(data + i - 1); + tmp_vec[4] = vld1q_s32(data + i + 3); + tmp_vec[8] = vld1q_s32(data + i + 7); + + summ_l_0 = vmull_s32(vget_low_s32(tmp_vec[0]), qlp_coeff_0_2); + summ_h_0 = vmull_high_s32(tmp_vec[0], qlp_coeff_0_4); + + summ_l_1 = vmull_s32(vget_low_s32(tmp_vec[4]), qlp_coeff_0_2); + summ_h_1 = vmull_high_s32(tmp_vec[4], qlp_coeff_0_4); + + summ_l_2 = vmull_s32(vget_low_s32(tmp_vec[8]), qlp_coeff_0_2); + summ_h_2 = vmull_high_s32(tmp_vec[8], qlp_coeff_0_4); + + SHIFT_SUMS_64BITS_AND_STORE_SUB() + } + } + } + } + for (; i < (int)data_len; i++) + { + sum = 0; + switch (order) + { + case 12: + sum += qlp_coeff[11] * (FLAC__int64)data[i - 12]; /* Falls through. */ + case 11: + sum += qlp_coeff[10] * (FLAC__int64)data[i - 11]; /* Falls through. */ + case 10: + sum += qlp_coeff[9] * (FLAC__int64)data[i - 10]; /* Falls through. */ + case 9: + sum += qlp_coeff[8] * (FLAC__int64)data[i - 9]; /* Falls through. */ + case 8: + sum += qlp_coeff[7] * (FLAC__int64)data[i - 8]; /* Falls through. */ + case 7: + sum += qlp_coeff[6] * (FLAC__int64)data[i - 7]; /* Falls through. */ + case 6: + sum += qlp_coeff[5] * (FLAC__int64)data[i - 6]; /* Falls through. */ + case 5: + sum += qlp_coeff[4] * (FLAC__int64)data[i - 5]; /* Falls through. */ + case 4: + sum += qlp_coeff[3] * (FLAC__int64)data[i - 4]; /* Falls through. */ + case 3: + sum += qlp_coeff[2] * (FLAC__int64)data[i - 3]; /* Falls through. */ + case 2: + sum += qlp_coeff[1] * (FLAC__int64)data[i - 2]; /* Falls through. */ + case 1: + sum += qlp_coeff[0] * (FLAC__int64)data[i - 1]; + } + residual[i] = data[i] - (sum >> lp_quantization); + } + } + else + { /* order > 12 */ + for (i = 0; i < (int)data_len; i++) + { + sum = 0; + switch (order) + { + case 32: + sum += qlp_coeff[31] * (FLAC__int64)data[i - 32]; /* Falls through. */ + case 31: + sum += qlp_coeff[30] * (FLAC__int64)data[i - 31]; /* Falls through. */ + case 30: + sum += qlp_coeff[29] * (FLAC__int64)data[i - 30]; /* Falls through. */ + case 29: + sum += qlp_coeff[28] * (FLAC__int64)data[i - 29]; /* Falls through. */ + case 28: + sum += qlp_coeff[27] * (FLAC__int64)data[i - 28]; /* Falls through. */ + case 27: + sum += qlp_coeff[26] * (FLAC__int64)data[i - 27]; /* Falls through. */ + case 26: + sum += qlp_coeff[25] * (FLAC__int64)data[i - 26]; /* Falls through. */ + case 25: + sum += qlp_coeff[24] * (FLAC__int64)data[i - 25]; /* Falls through. */ + case 24: + sum += qlp_coeff[23] * (FLAC__int64)data[i - 24]; /* Falls through. */ + case 23: + sum += qlp_coeff[22] * (FLAC__int64)data[i - 23]; /* Falls through. */ + case 22: + sum += qlp_coeff[21] * (FLAC__int64)data[i - 22]; /* Falls through. */ + case 21: + sum += qlp_coeff[20] * (FLAC__int64)data[i - 21]; /* Falls through. */ + case 20: + sum += qlp_coeff[19] * (FLAC__int64)data[i - 20]; /* Falls through. */ + case 19: + sum += qlp_coeff[18] * (FLAC__int64)data[i - 19]; /* Falls through. */ + case 18: + sum += qlp_coeff[17] * (FLAC__int64)data[i - 18]; /* Falls through. */ + case 17: + sum += qlp_coeff[16] * (FLAC__int64)data[i - 17]; /* Falls through. */ + case 16: + sum += qlp_coeff[15] * (FLAC__int64)data[i - 16]; /* Falls through. */ + case 15: + sum += qlp_coeff[14] * (FLAC__int64)data[i - 15]; /* Falls through. */ + case 14: + sum += qlp_coeff[13] * (FLAC__int64)data[i - 14]; /* Falls through. */ + case 13: + sum += qlp_coeff[12] * (FLAC__int64)data[i - 13]; + sum += qlp_coeff[11] * (FLAC__int64)data[i - 12]; + sum += qlp_coeff[10] * (FLAC__int64)data[i - 11]; + sum += qlp_coeff[9] * (FLAC__int64)data[i - 10]; + sum += qlp_coeff[8] * (FLAC__int64)data[i - 9]; + sum += qlp_coeff[7] * (FLAC__int64)data[i - 8]; + sum += qlp_coeff[6] * (FLAC__int64)data[i - 7]; + sum += qlp_coeff[5] * (FLAC__int64)data[i - 6]; + sum += qlp_coeff[4] * (FLAC__int64)data[i - 5]; + sum += qlp_coeff[3] * (FLAC__int64)data[i - 4]; + sum += qlp_coeff[2] * (FLAC__int64)data[i - 3]; + sum += qlp_coeff[1] * (FLAC__int64)data[i - 2]; + sum += qlp_coeff[0] * (FLAC__int64)data[i - 1]; + } + residual[i] = data[i] - (sum >> lp_quantization); + } + } + + return; +} + +#endif /* FLAC__CPU_ARM64 && FLAC__HAS_ARCH64INTRIN */ +#endif /* FLAC__NO_ASM */ +#endif /* FLAC__INTEGER_ONLY_LIBRARY */ diff --git a/modules/juce_audio_formats/codecs/flac/libFLAC/md5.c b/modules/juce_audio_formats/codecs/flac/libFLAC/md5.c index 1676bfbc4b21..06903c68b3e7 100644 --- a/modules/juce_audio_formats/codecs/flac/libFLAC/md5.c +++ b/modules/juce_audio_formats/codecs/flac/libFLAC/md5.c @@ -139,7 +139,7 @@ static void FLAC__MD5Transform(FLAC__uint32 buf[4], FLAC__uint32 const in[16]) //@@@@@@ OPT: use bswap/intrinsics static void byteSwap(FLAC__uint32 *buf, uint32_t words) { - FLAC__uint32 x; + register FLAC__uint32 x; do { x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); @@ -148,7 +148,7 @@ static void byteSwap(FLAC__uint32 *buf, uint32_t words) } static void byteSwapX16(FLAC__uint32 *buf) { - FLAC__uint32 x; + register FLAC__uint32 x; x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); diff --git a/modules/juce_audio_formats/codecs/flac/libFLAC/memory.c b/modules/juce_audio_formats/codecs/flac/libFLAC/memory.c index 27a0046eb525..8d563a6f3775 100644 --- a/modules/juce_audio_formats/codecs/flac/libFLAC/memory.c +++ b/modules/juce_audio_formats/codecs/flac/libFLAC/memory.c @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2001-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -34,9 +34,9 @@ # include #endif -//#ifdef HAVE_STDINT_H -//#include -//#endif +#ifdef HAVE_STDINT_H +#include +#endif #include "include/private/memory.h" #include "../assert.h" @@ -118,11 +118,11 @@ FLAC__bool FLAC__memory_alloc_aligned_uint32_array(size_t elements, FLAC__uint32 } } -FLAC__bool FLAC__memory_alloc_aligned_uint64_array(size_t elements, FLAC__uint64 **unaligned_pointer, FLAC__uint64 **aligned_pointer) +FLAC__bool FLAC__memory_alloc_aligned_int64_array(size_t elements, FLAC__int64 **unaligned_pointer, FLAC__int64 **aligned_pointer) { - FLAC__uint64 *pu; /* unaligned pointer */ + FLAC__int64 *pu; /* unaligned pointer */ union { /* union needed to comply with C99 pointer aliasing rules */ - FLAC__uint64 *pa; /* aligned pointer */ + FLAC__int64 *pa; /* aligned pointer */ void *pv; /* aligned pointer alias */ } u; @@ -134,7 +134,7 @@ FLAC__bool FLAC__memory_alloc_aligned_uint64_array(size_t elements, FLAC__uint64 if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ return false; - pu = (FLAC__uint64*) FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); + pu = (FLAC__int64*) FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); if(0 == pu) { return false; } @@ -147,12 +147,12 @@ FLAC__bool FLAC__memory_alloc_aligned_uint64_array(size_t elements, FLAC__uint64 } } -FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(size_t elements, uint32_t **unaligned_pointer, uint32_t **aligned_pointer) +FLAC__bool FLAC__memory_alloc_aligned_uint64_array(size_t elements, FLAC__uint64 **unaligned_pointer, FLAC__uint64 **aligned_pointer) { - uint32_t *pu; /* unaligned pointer */ + FLAC__uint64 *pu; /* unaligned pointer */ union { /* union needed to comply with C99 pointer aliasing rules */ - uint32_t *pa; /* aligned pointer */ - void *pv; /* aligned pointer alias */ + FLAC__uint64 *pa; /* aligned pointer */ + void *pv; /* aligned pointer alias */ } u; FLAC__ASSERT(elements > 0); @@ -163,7 +163,7 @@ FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(size_t elements, uint32_t * if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ return false; - pu = (uint32_t*) FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); + pu = (FLAC__uint64*) FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); if(0 == pu) { return false; } diff --git a/modules/juce_audio_formats/codecs/flac/libFLAC/stream_decoder.c b/modules/juce_audio_formats/codecs/flac/libFLAC/stream_decoder.c index 60628077d375..bf1b2ba1ed1e 100644 --- a/modules/juce_audio_formats/codecs/flac/libFLAC/stream_decoder.c +++ b/modules/juce_audio_formats/codecs/flac/libFLAC/stream_decoder.c @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -37,8 +37,8 @@ #include #include /* for malloc() */ #include /* for memset/memcpy() */ -#include /* for stat() */ #include /* for off_t */ +#include /* for stat() */ #include "../compat.h" #include "../assert.h" #include "../alloc.h" @@ -54,6 +54,7 @@ #include "include/private/memory.h" + /* technically this should be in an "export.c" but this is convenient enough */ FLAC_API int FLAC_API_SUPPORTS_OGG_FLAC = FLAC__HAS_OGG; @@ -74,7 +75,7 @@ static const FLAC__byte ID3V2_TAG_[3] = { 'I', 'D', '3' }; static void set_defaults_(FLAC__StreamDecoder *decoder); //static FILE *get_binary_stdin_(void); -static FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, uint32_t size, uint32_t channels); +static FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, uint32_t size, uint32_t channels, uint32_t bps); static FLAC__bool has_id_filtered_(FLAC__StreamDecoder *decoder, FLAC__byte *id); static FLAC__bool find_metadata_(FLAC__StreamDecoder *decoder); static FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder); @@ -94,6 +95,7 @@ static FLAC__bool read_subframe_lpc_(FLAC__StreamDecoder *decoder, uint32_t chan static FLAC__bool read_subframe_verbatim_(FLAC__StreamDecoder *decoder, uint32_t channel, uint32_t bps, FLAC__bool do_full_decode); static FLAC__bool read_residual_partitioned_rice_(FLAC__StreamDecoder *decoder, uint32_t predictor_order, uint32_t partition_order, FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents, FLAC__int32 *residual, FLAC__bool is_extended); static FLAC__bool read_zero_padding_(FLAC__StreamDecoder *decoder); +static void undo_channel_coding(FLAC__StreamDecoder *decoder); static FLAC__bool read_callback_(FLAC__byte buffer[], size_t *bytes, void *client_data); #if FLAC__HAS_OGG static FLAC__StreamDecoderReadStatus read_callback_ogg_aspect_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes); @@ -127,17 +129,13 @@ typedef struct FLAC__StreamDecoderPrivate { FLAC__StreamDecoderWriteCallback write_callback; FLAC__StreamDecoderMetadataCallback metadata_callback; FLAC__StreamDecoderErrorCallback error_callback; - /* generic 32-bit datapath: */ - void (*local_lpc_restore_signal)(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 data[]); - /* generic 64-bit datapath: */ - void (*local_lpc_restore_signal_64bit)(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 data[]); - /* for use when the signal is <= 16 bits-per-sample, or <= 15 bits-per-sample on a side channel (which requires 1 extra bit): */ - void (*local_lpc_restore_signal_16bit)(const FLAC__int32 residual[], uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 data[]); void *client_data; FILE *file; /* only used if FLAC__stream_decoder_init_file()/FLAC__stream_decoder_init_file() called, else NULL */ FLAC__BitReader *input; FLAC__int32 *output[FLAC__MAX_CHANNELS]; FLAC__int32 *residual[FLAC__MAX_CHANNELS]; /* WATCHOUT: these are the aligned pointers; the real pointers that should be free()'d are residual_unaligned[] below */ + FLAC__int64 *side_subframe; + FLAC__bool side_subframe_in_use; FLAC__EntropyCodingMethod_PartitionedRiceContents partitioned_rice_contents[FLAC__MAX_CHANNELS]; uint32_t output_capacity, output_channels; FLAC__uint32 fixed_block_size, next_fixed_block_size; @@ -161,11 +159,14 @@ typedef struct FLAC__StreamDecoderPrivate { FLAC__MD5Context md5context; FLAC__byte computed_md5sum[16]; /* this is the sum we computed from the decoded data */ /* (the rest of these are only used for seeking) */ - FLAC__Frame last_frame; /* holds the info of the last frame we seeked to */ + FLAC__Frame last_frame; /* holds the info of the last frame we decoded or seeked to */ + FLAC__bool last_frame_is_set; FLAC__uint64 first_frame_offset; /* hint to the seek routine of where in the stream the first audio frame starts */ + FLAC__uint64 last_seen_framesync; /* if tell callback works, the location of the last seen frame sync code, to rewind to if needed */ FLAC__uint64 target_sample; uint32_t unparseable_frame_count; /* used to tell whether we're decoding a future version of FLAC or just got a bad sync */ FLAC__bool got_a_frame; /* hack needed in Ogg FLAC seek routine to check when process_single() actually writes a frame */ + FLAC__bool (*local_bitreader_read_rice_signed_block)(FLAC__BitReader *br, int vals[], uint32_t nvals, uint32_t parameter); } FLAC__StreamDecoderPrivate; /*********************************************************************** @@ -229,7 +230,8 @@ FLAC_API const char * const FLAC__StreamDecoderErrorStatusString[] = { "FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC", "FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER", "FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH", - "FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM" + "FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM", + "FLAC__STREAM_DECODER_ERROR_STATUS_BAD_METADATA" }; /*********************************************************************** @@ -284,6 +286,8 @@ FLAC_API FLAC__StreamDecoder *FLAC__stream_decoder_new(void) decoder->private_->residual_unaligned[i] = decoder->private_->residual[i] = 0; } + decoder->private_->side_subframe = 0; + decoder->private_->output_capacity = 0; decoder->private_->output_channels = 0; decoder->private_->has_seek_table = false; @@ -370,45 +374,12 @@ static FLAC__StreamDecoderInitStatus init_stream_internal_( return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE; #endif - /* - * get the CPU info and set the function pointers - */ FLAC__cpu_info(&decoder->private_->cpuinfo); - /* first default to the non-asm routines */ - decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal; - decoder->private_->local_lpc_restore_signal_64bit = FLAC__lpc_restore_signal_wide; - decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal; - /* now override with asm where appropriate */ -#ifndef FLAC__NO_ASM - if(decoder->private_->cpuinfo.use_asm) { -#ifdef FLAC__CPU_IA32 - FLAC__ASSERT(decoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_IA32); -#ifdef FLAC__HAS_NASM - decoder->private_->local_lpc_restore_signal_64bit = FLAC__lpc_restore_signal_wide_asm_ia32; /* OPT_IA32: was really necessary for GCC < 4.9 */ - if (decoder->private_->cpuinfo.x86.mmx) { - decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal_asm_ia32; - decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ia32_mmx; - } - else { - decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal_asm_ia32; - decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ia32; - } -#endif -#if FLAC__HAS_X86INTRIN && ! defined FLAC__INTEGER_ONLY_LIBRARY -# if defined FLAC__SSE4_1_SUPPORTED - if (decoder->private_->cpuinfo.x86.sse41) { -# if !defined FLAC__HAS_NASM /* these are not undoubtedly faster than their MMX ASM counterparts */ - decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal_intrin_sse41; - decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_16_intrin_sse41; -# endif - decoder->private_->local_lpc_restore_signal_64bit = FLAC__lpc_restore_signal_wide_intrin_sse41; - } -# endif -#endif -#elif defined FLAC__CPU_X86_64 - FLAC__ASSERT(decoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_X86_64); - /* No useful SSE optimizations yet */ -#endif + decoder->private_->local_bitreader_read_rice_signed_block = FLAC__bitreader_read_rice_signed_block; + +#ifdef FLAC__BMI2_SUPPORTED + if (decoder->private_->cpuinfo.x86.bmi2) { + decoder->private_->local_bitreader_read_rice_signed_block = FLAC__bitreader_read_rice_signed_block_bmi2; } #endif @@ -666,6 +637,10 @@ FLAC_API FLAC__bool FLAC__stream_decoder_finish(FLAC__StreamDecoder *decoder) decoder->private_->residual_unaligned[i] = decoder->private_->residual[i] = 0; } } + if(0 != decoder->private_->side_subframe) { + free(decoder->private_->side_subframe); + decoder->private_->side_subframe = 0; + } decoder->private_->output_capacity = 0; decoder->private_->output_channels = 0; @@ -918,6 +893,11 @@ FLAC_API FLAC__bool FLAC__stream_decoder_get_decode_position(const FLAC__StreamD return true; } +FLAC_API const void *FLAC__stream_decoder_get_client_data(FLAC__StreamDecoder *decoder) +{ + return decoder->private_->client_data; +} + FLAC_API FLAC__bool FLAC__stream_decoder_flush(FLAC__StreamDecoder *decoder) { FLAC__ASSERT(0 != decoder); @@ -929,6 +909,8 @@ FLAC_API FLAC__bool FLAC__stream_decoder_flush(FLAC__StreamDecoder *decoder) decoder->private_->samples_decoded = 0; decoder->private_->do_md5_checking = false; + decoder->private_->last_seen_framesync = 0; + decoder->private_->last_frame_is_set = false; #if FLAC__HAS_OGG if(decoder->private_->is_ogg) @@ -972,8 +954,6 @@ FLAC_API FLAC__bool FLAC__stream_decoder_reset(FLAC__StreamDecoder *decoder) if(decoder->private_->seek_callback && decoder->private_->seek_callback(decoder, 0, decoder->private_->client_data) == FLAC__STREAM_DECODER_SEEK_STATUS_ERROR) return false; /* seekable and seek fails, reset fails */ } - else - decoder->private_->internal_reset_hack = false; decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_METADATA; @@ -996,10 +976,19 @@ FLAC_API FLAC__bool FLAC__stream_decoder_reset(FLAC__StreamDecoder *decoder) * FLAC__stream_decoder_finish() to make sure things are always cleaned up * properly. */ + if(!decoder->private_->internal_reset_hack) { + /* Only finish MD5 context when it has been initialized + * (i.e. when internal_reset_hack is not set) */ + FLAC__MD5Final(decoder->private_->computed_md5sum, &decoder->private_->md5context); + } + else + decoder->private_->internal_reset_hack = false; FLAC__MD5Init(&decoder->private_->md5context); decoder->private_->first_frame_offset = 0; decoder->private_->unparseable_frame_count = 0; + decoder->private_->last_seen_framesync = 0; + decoder->private_->last_frame_is_set = false; return true; } @@ -1035,7 +1024,6 @@ FLAC_API FLAC__bool FLAC__stream_decoder_process_single(FLAC__StreamDecoder *dec case FLAC__STREAM_DECODER_ABORTED: return true; default: - FLAC__ASSERT(0); return false; } } @@ -1062,7 +1050,6 @@ FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_metadata(FLAC__Str case FLAC__STREAM_DECODER_ABORTED: return true; default: - FLAC__ASSERT(0); return false; } } @@ -1096,7 +1083,6 @@ FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_stream(FLAC__Strea case FLAC__STREAM_DECODER_ABORTED: return true; default: - FLAC__ASSERT(0); return false; } } @@ -1127,7 +1113,6 @@ FLAC_API FLAC__bool FLAC__stream_decoder_skip_single_frame(FLAC__StreamDecoder * case FLAC__STREAM_DECODER_ABORTED: return true; default: - FLAC__ASSERT(0); return false; } } @@ -1264,12 +1249,13 @@ FILE *get_binary_stdin_(void) } #endif -FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, uint32_t size, uint32_t channels) +FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, uint32_t size, uint32_t channels, uint32_t bps) { uint32_t i; FLAC__int32 *tmp; - if(size <= decoder->private_->output_capacity && channels <= decoder->private_->output_channels) + if(size <= decoder->private_->output_capacity && channels <= decoder->private_->output_channels && + (bps < 32 || decoder->private_->side_subframe != 0)) return true; /* simply using realloc() is not practical because the number of channels may change mid-stream */ @@ -1285,6 +1271,11 @@ FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, uint32_t size, uint32_ } } + if(0 != decoder->private_->side_subframe) { + free(decoder->private_->side_subframe); + decoder->private_->side_subframe = 0; + } + for(i = 0; i < channels; i++) { /* WATCHOUT: * FLAC__lpc_restore_signal_asm_ia32_mmx() and ..._intrin_sseN() @@ -1306,6 +1297,14 @@ FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, uint32_t size, uint32_ } } + if(bps == 32) { + decoder->private_->side_subframe = (FLAC__int64*) safe_malloc_mul_2op_p(sizeof(FLAC__int64), /*times (*/size); + if(decoder->private_->side_subframe == NULL) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + return false; + } + } + decoder->private_->output_capacity = size; decoder->private_->output_channels = channels; @@ -1329,12 +1328,12 @@ FLAC__bool has_id_filtered_(FLAC__StreamDecoder *decoder, FLAC__byte *id) FLAC__bool find_metadata_(FLAC__StreamDecoder *decoder) { FLAC__uint32 x; - uint32_t i, id_; + uint32_t i, id; FLAC__bool first = true; FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)); - for(i = id_ = 0; i < 4; ) { + for(i = id = 0; i < 4; ) { if(decoder->private_->cached) { x = (FLAC__uint32)decoder->private_->lookahead; decoder->private_->cached = false; @@ -1346,23 +1345,23 @@ FLAC__bool find_metadata_(FLAC__StreamDecoder *decoder) if(x == FLAC__STREAM_SYNC_STRING[i]) { first = true; i++; - id_ = 0; + id = 0; continue; } - if(id_ >= 3) + if(id >= 3) return false; - if(x == ID3V2_TAG_[id_]) { - id_++; + if(x == ID3V2_TAG_[id]) { + id++; i = 0; - if(id_ == 3) { + if(id == 3) { if(!skip_id3v2_tag_(decoder)) return false; /* skip_id3v2_tag_ sets the state for us */ } continue; } - id_ = 0; + id = 0; if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */ decoder->private_->header_warmup[0] = (FLAC__byte)x; if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, 8)) @@ -1422,12 +1421,14 @@ FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder) /* just in case we already have a seek table, and reading the next one fails: */ decoder->private_->has_seek_table = false; - if(!read_metadata_seektable_(decoder, is_last, length)) - return false; + if(length > 0) { + if(!read_metadata_seektable_(decoder, is_last, length)) + return false; - decoder->private_->has_seek_table = true; - if(!decoder->private_->is_seeking && decoder->private_->metadata_filter[FLAC__METADATA_TYPE_SEEKTABLE] && decoder->private_->metadata_callback) - decoder->private_->metadata_callback(decoder, &decoder->private_->seek_table, decoder->private_->client_data); + decoder->private_->has_seek_table = true; + if(!decoder->private_->is_seeking && decoder->private_->metadata_filter[FLAC__METADATA_TYPE_SEEKTABLE] && decoder->private_->metadata_callback) + decoder->private_->metadata_callback(decoder, &decoder->private_->seek_table, decoder->private_->client_data); + } } else { FLAC__bool skip_it = !decoder->private_->metadata_filter[type]; @@ -1460,6 +1461,7 @@ FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder) } else { FLAC__bool ok = true; + FLAC__bitreader_set_limit(decoder->private_->input, real_length*8); switch(type) { case FLAC__METADATA_TYPE_PADDING: /* skip the padding bytes */ @@ -1508,6 +1510,16 @@ FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder) block.data.unknown.data = 0; break; } + if(FLAC__bitreader_limit_remaining(decoder->private_->input) > 0) { + /* Content in metadata block didn't fit in block length + * We cannot know whether the length or the content was + * corrupt, so stop parsing metadata */ + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_METADATA); + if(decoder->protected_->state == FLAC__STREAM_DECODER_READ_METADATA) + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + ok = false; + } + FLAC__bitreader_remove_limit(decoder->private_->input); if(ok && !decoder->private_->is_seeking && decoder->private_->metadata_callback) decoder->private_->metadata_callback(decoder, &block, decoder->private_->client_data); @@ -1530,7 +1542,7 @@ FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder) free(block.data.vorbis_comment.comments); break; case FLAC__METADATA_TYPE_CUESHEET: - if(block.data.cue_sheet.num_tracks > 0) + if(block.data.cue_sheet.num_tracks > 0 && 0 != block.data.cue_sheet.tracks) for(i = 0; i < block.data.cue_sheet.num_tracks; i++) if(0 != block.data.cue_sheet.tracks[i].indices) free(block.data.cue_sheet.tracks[i].indices); @@ -1653,6 +1665,11 @@ FLAC__bool read_metadata_seektable_(FLAC__StreamDecoder *decoder, FLAC__bool is_ decoder->private_->seek_table.is_last = is_last; decoder->private_->seek_table.length = length; + if(length % FLAC__STREAM_METADATA_SEEKPOINT_LENGTH) { + FLAC__bitreader_limit_invalidate(decoder->private_->input); + return false; + } + decoder->private_->seek_table.data.seek_table.num_points = length / FLAC__STREAM_METADATA_SEEKPOINT_LENGTH; /* use realloc since we may pass through here several times (e.g. after seeking) */ @@ -1674,12 +1691,8 @@ FLAC__bool read_metadata_seektable_(FLAC__StreamDecoder *decoder, FLAC__bool is_ decoder->private_->seek_table.data.seek_table.points[i].frame_samples = x; } length -= (decoder->private_->seek_table.data.seek_table.num_points * FLAC__STREAM_METADATA_SEEKPOINT_LENGTH); - /* if there is a partial point left, skip over it */ - if(length > 0) { - /*@@@ do a send_error_to_client_() here? there's an argument for either way */ - if(!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, length)) - return false; /* read_callback_ sets the state for us */ - } + + FLAC__ASSERT(length == 0); return true; } @@ -1696,24 +1709,20 @@ FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__Stre FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN == 32); if (!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->vendor_string.length)) return false; /* read_callback_ sets the state for us */ - if (obj->vendor_string.length > 0) { - if (length < obj->vendor_string.length) { - obj->vendor_string.length = 0; - obj->vendor_string.entry = 0; - goto skip; - } - else - length -= obj->vendor_string.length; - if (0 == (obj->vendor_string.entry = (FLAC__byte*) safe_malloc_add_2op_(obj->vendor_string.length, /*+*/1))) { - decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; - return false; - } - if (!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, obj->vendor_string.entry, obj->vendor_string.length)) - return false; /* read_callback_ sets the state for us */ - obj->vendor_string.entry[obj->vendor_string.length] = '\0'; + if (length < obj->vendor_string.length) { + obj->vendor_string.length = 0; + obj->vendor_string.entry = 0; + goto skip; } else - obj->vendor_string.entry = 0; + length -= obj->vendor_string.length; + if (0 == (obj->vendor_string.entry = (FLAC__byte*) safe_malloc_add_2op_(obj->vendor_string.length, /*+*/1))) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + return false; + } + if (!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, obj->vendor_string.entry, obj->vendor_string.length)) + return false; /* read_callback_ sets the state for us */ + obj->vendor_string.entry[obj->vendor_string.length] = '\0'; /* read num comments */ FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN == 32); @@ -1748,33 +1757,34 @@ FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__Stre obj->num_comments = i; return false; /* read_callback_ sets the state for us */ } - if (obj->comments[i].length > 0) { - if (length < obj->comments[i].length) { - obj->num_comments = i; - goto skip; - } - else - length -= obj->comments[i].length; - if (0 == (obj->comments[i].entry = (FLAC__byte*) safe_malloc_add_2op_(obj->comments[i].length, /*+*/1))) { - decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; - obj->num_comments = i; - return false; - } - memset (obj->comments[i].entry, 0, obj->comments[i].length) ; - if (!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, obj->comments[i].entry, obj->comments[i].length)) { - /* Current i-th entry is bad, so we delete it. */ - free (obj->comments[i].entry) ; - obj->comments[i].entry = NULL ; - obj->num_comments = i; - goto skip; - } - obj->comments[i].entry[obj->comments[i].length] = '\0'; + if (length < obj->comments[i].length) { + obj->num_comments = i; + FLAC__bitreader_limit_invalidate(decoder->private_->input); + return false; } else - obj->comments[i].entry = 0; + length -= obj->comments[i].length; + if (0 == (obj->comments[i].entry = (FLAC__byte*) safe_malloc_add_2op_(obj->comments[i].length, /*+*/1))) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + obj->num_comments = i; + return false; + } + memset (obj->comments[i].entry, 0, obj->comments[i].length) ; + if (!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, obj->comments[i].entry, obj->comments[i].length)) { + /* Current i-th entry is bad, so we delete it. */ + free (obj->comments[i].entry) ; + obj->comments[i].entry = NULL ; + obj->num_comments = i; + goto skip; + } + obj->comments[i].entry[obj->comments[i].length] = '\0'; } } } + else { + FLAC__bitreader_limit_invalidate(decoder->private_->input); + return false; + } skip: if (length > 0) { @@ -1783,8 +1793,8 @@ FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__Stre free(obj->comments); obj->comments = NULL; } - if(!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, length)) - return false; /* read_callback_ sets the state for us */ + FLAC__bitreader_limit_invalidate(decoder->private_->input); + return false; } return true; @@ -1869,6 +1879,10 @@ FLAC__bool read_metadata_cuesheet_(FLAC__StreamDecoder *decoder, FLAC__StreamMet } } } + else { /* obj->num_tracks == 0 */ + FLAC__bitreader_limit_invalidate(decoder->private_->input); + return false; + } return true; } @@ -1882,11 +1896,18 @@ FLAC__bool read_metadata_picture_(FLAC__StreamDecoder *decoder, FLAC__StreamMeta /* read type */ if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_PICTURE_TYPE_LEN)) return false; /* read_callback_ sets the state for us */ - obj->type = (FLAC__StreamMetadata_Picture_Type) x; + if(x < FLAC__STREAM_METADATA_PICTURE_TYPE_UNDEFINED) + obj->type = (FLAC__StreamMetadata_Picture_Type) x; + else + obj->type = FLAC__STREAM_METADATA_PICTURE_TYPE_OTHER; /* read MIME type */ if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN)) return false; /* read_callback_ sets the state for us */ + if(FLAC__bitreader_limit_remaining(decoder->private_->input) < x){ + FLAC__bitreader_limit_invalidate(decoder->private_->input); + return false; + } if(0 == (obj->mime_type = (char*) safe_malloc_add_2op_(x, /*+*/1))) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return false; @@ -1900,6 +1921,10 @@ FLAC__bool read_metadata_picture_(FLAC__StreamDecoder *decoder, FLAC__StreamMeta /* read description */ if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN)) return false; /* read_callback_ sets the state for us */ + if(FLAC__bitreader_limit_remaining(decoder->private_->input) < x){ + FLAC__bitreader_limit_invalidate(decoder->private_->input); + return false; + } if(0 == (obj->description = (FLAC__byte*) safe_malloc_add_2op_(x, /*+*/1))) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return false; @@ -1929,6 +1954,10 @@ FLAC__bool read_metadata_picture_(FLAC__StreamDecoder *decoder, FLAC__StreamMeta /* read data */ if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &(obj->data_length), FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN)) return false; /* read_callback_ sets the state for us */ + if(FLAC__bitreader_limit_remaining(decoder->private_->input) < obj->data_length){ + FLAC__bitreader_limit_invalidate(decoder->private_->input); + return false; + } if(0 == (obj->data = (FLAC__byte*) safe_malloc_(obj->data_length))) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return false; @@ -1968,15 +1997,6 @@ FLAC__bool frame_sync_(FLAC__StreamDecoder *decoder) FLAC__uint32 x; FLAC__bool first = true; - /* If we know the total number of samples in the stream, stop if we've read that many. */ - /* This will stop us, for example, from wasting time trying to sync on an ID3V1 tag. */ - if(FLAC__stream_decoder_get_total_samples(decoder) > 0) { - if(decoder->private_->samples_decoded >= FLAC__stream_decoder_get_total_samples(decoder)) { - decoder->protected_->state = FLAC__STREAM_DECODER_END_OF_STREAM; - return true; - } - } - /* make sure we're byte aligned */ if(!FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)) { if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__bitreader_bits_left_for_byte_alignment(decoder->private_->input))) @@ -2006,6 +2026,12 @@ FLAC__bool frame_sync_(FLAC__StreamDecoder *decoder) else if(x >> 1 == 0x7c) { /* MAGIC NUMBER for the last 6 sync bits and reserved 7th bit */ decoder->private_->header_warmup[1] = (FLAC__byte)x; decoder->protected_->state = FLAC__STREAM_DECODER_READ_FRAME; + + /* Save location so we can rewind in case the frame turns + * out to be invalid after the header */ + FLAC__bitreader_set_framesync_location(decoder->private_->input); + if(!FLAC__stream_decoder_get_decode_position(decoder, &decoder->private_->last_seen_framesync)) + decoder->private_->last_seen_framesync = 0; return true; } } @@ -2022,11 +2048,11 @@ FLAC__bool read_frame_(FLAC__StreamDecoder *decoder, FLAC__bool *got_a_frame, FL { uint32_t channel; uint32_t i; - FLAC__int32 mid, side; uint32_t frame_crc; /* the one we calculate from the input stream */ - FLAC__uint32 x; + FLAC__uint32 x{}; *got_a_frame = false; + decoder->private_->side_subframe_in_use = false; /* init the CRC */ frame_crc = 0; @@ -2038,7 +2064,7 @@ FLAC__bool read_frame_(FLAC__StreamDecoder *decoder, FLAC__bool *got_a_frame, FL return false; if(decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) /* means we didn't sync on a valid header */ return true; - if(!allocate_output_(decoder, decoder->private_->frame.header.blocksize, decoder->private_->frame.header.channels)) + if(!allocate_output_(decoder, decoder->private_->frame.header.blocksize, decoder->private_->frame.header.channels, decoder->private_->frame.header.bits_per_sample)) return false; for(channel = 0; channel < decoder->private_->frame.header.channels; channel++) { /* @@ -2070,98 +2096,183 @@ FLAC__bool read_frame_(FLAC__StreamDecoder *decoder, FLAC__bool *got_a_frame, FL /* * now read it */ - if(!read_subframe_(decoder, channel, bps, do_full_decode)) - return false; - if(decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) /* means bad sync or got corruption */ - return true; + if(!read_subframe_(decoder, channel, bps, do_full_decode)){ + /* read_callback_ sets the state for us */ + if(decoder->protected_->state == FLAC__STREAM_DECODER_END_OF_STREAM) + break; + else + return false; + } + if(decoder->protected_->state != FLAC__STREAM_DECODER_READ_FRAME) + break; } - if(!read_zero_padding_(decoder)) - return false; - if(decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC) /* means bad sync or got corruption (i.e. "zero bits" were not all zeroes) */ - return true; + + if(decoder->protected_->state != FLAC__STREAM_DECODER_END_OF_STREAM) + if(!read_zero_padding_(decoder)) + return false; /* * Read the frame CRC-16 from the footer and check */ - frame_crc = FLAC__bitreader_get_read_crc16(decoder->private_->input); - if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__FRAME_FOOTER_CRC_LEN)) - return false; /* read_callback_ sets the state for us */ -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - if(1){ -#else - if(frame_crc == x) { + if(decoder->protected_->state == FLAC__STREAM_DECODER_READ_FRAME) { + frame_crc = FLAC__bitreader_get_read_crc16(decoder->private_->input); + if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &x, FLAC__FRAME_FOOTER_CRC_LEN)) { + /* read_callback_ sets the state for us */ + if(decoder->protected_->state != FLAC__STREAM_DECODER_END_OF_STREAM) + return false; + } +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + } + if(decoder->protected_->state == FLAC__STREAM_DECODER_READ_FRAME && frame_crc == x) { #endif if(do_full_decode) { /* Undo any special channel coding */ - switch(decoder->private_->frame.header.channel_assignment) { - case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT: - /* do nothing */ - break; - case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE: - FLAC__ASSERT(decoder->private_->frame.header.channels == 2); - for(i = 0; i < decoder->private_->frame.header.blocksize; i++) - decoder->private_->output[1][i] = decoder->private_->output[0][i] - decoder->private_->output[1][i]; - break; - case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE: - FLAC__ASSERT(decoder->private_->frame.header.channels == 2); - for(i = 0; i < decoder->private_->frame.header.blocksize; i++) - decoder->private_->output[0][i] += decoder->private_->output[1][i]; - break; - case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE: - FLAC__ASSERT(decoder->private_->frame.header.channels == 2); - for(i = 0; i < decoder->private_->frame.header.blocksize; i++) { -#if 1 - mid = decoder->private_->output[0][i]; - side = decoder->private_->output[1][i]; - mid = ((uint32_t) mid) << 1; - mid |= (side & 1); /* i.e. if 'side' is odd... */ - decoder->private_->output[0][i] = (mid + side) >> 1; - decoder->private_->output[1][i] = (mid - side) >> 1; -#else - /* OPT: without 'side' temp variable */ - mid = (decoder->private_->output[0][i] << 1) | (decoder->private_->output[1][i] & 1); /* i.e. if 'side' is odd... */ - decoder->private_->output[0][i] = (mid + decoder->private_->output[1][i]) >> 1; - decoder->private_->output[1][i] = (mid - decoder->private_->output[1][i]) >> 1; -#endif + undo_channel_coding(decoder); + /* Check whether decoded data actually fits bps */ + for(channel = 0; channel < decoder->private_->frame.header.channels; channel++) { + for(i = 0; i < decoder->private_->frame.header.blocksize; i++) { + int shift_bits = 32 - decoder->private_->frame.header.bits_per_sample; + /* Check whether shift_bits MSBs are 'empty' by shifting up and down */ + if((decoder->private_->output[channel][i] < (INT32_MIN >> shift_bits)) || + (decoder->private_->output[channel][i] > (INT32_MAX >> shift_bits))) { + /* Bad frame, emit error */ + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH); + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + break; } - break; - default: - FLAC__ASSERT(0); - break; + } } } } - else { - /* Bad frame, emit error and zero the output signal */ +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + else if (decoder->protected_->state == FLAC__STREAM_DECODER_READ_FRAME) { + /* Bad frame, emit error */ send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH); - if(do_full_decode) { - for(channel = 0; channel < decoder->private_->frame.header.channels; channel++) { - memset(decoder->private_->output[channel], 0, sizeof(FLAC__int32) * decoder->private_->frame.header.blocksize); + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + } +#endif + + /* Check whether frames are missing, if so, add silence to compensate */ + if(decoder->private_->last_frame_is_set && decoder->protected_->state == FLAC__STREAM_DECODER_READ_FRAME && !decoder->private_->is_seeking && do_full_decode) { + FLAC__ASSERT(decoder->private_->frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER); + FLAC__ASSERT(decoder->private_->last_frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER); + if(decoder->private_->last_frame.header.number.sample_number + decoder->private_->last_frame.header.blocksize < decoder->private_->frame.header.number.sample_number) { + uint32_t padding_samples_needed = decoder->private_->frame.header.number.sample_number - (decoder->private_->last_frame.header.number.sample_number + decoder->private_->last_frame.header.blocksize); + + /* Do some extra validation to assure last frame an current frame + * header are both valid before adding silence inbetween + * Technically both frames could be valid with differing sample_rates, + * channels and bits_per_sample, but it is quite rare */ + if(decoder->private_->last_frame.header.sample_rate == decoder->private_->frame.header.sample_rate && + decoder->private_->last_frame.header.channels == decoder->private_->frame.header.channels && + decoder->private_->last_frame.header.bits_per_sample == decoder->private_->frame.header.bits_per_sample && + decoder->private_->last_frame.header.blocksize >= 16) { + FLAC__Frame empty_frame; + FLAC__int32 * empty_buffer[FLAC__MAX_CHANNELS] = {NULL}; + empty_frame.header = decoder->private_->last_frame.header; + empty_frame.footer.crc = 0; + for(i = 0; i < empty_frame.header.channels; i++) { + empty_buffer[i] = (FLAC__int32*) safe_calloc_(empty_frame.header.blocksize, sizeof(FLAC__int32)); + if(empty_buffer[i] == NULL) { + for(i = 0; i < empty_frame.header.channels; i++) + if(empty_buffer[i] != NULL) + free(empty_buffer[i]); + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + return false; + } + } + /* No repairs larger than 5 seconds or 50 frames are made, to not + * unexpectedly create enormous files when one of the headers was + * corrupt after all */ + if(padding_samples_needed > (5*empty_frame.header.sample_rate)) + padding_samples_needed = 5*empty_frame.header.sample_rate; + if(padding_samples_needed > (50*empty_frame.header.blocksize)) + padding_samples_needed = 50*empty_frame.header.blocksize; + while(padding_samples_needed){ + empty_frame.header.number.sample_number += empty_frame.header.blocksize; + if(padding_samples_needed < empty_frame.header.blocksize) + empty_frame.header.blocksize = padding_samples_needed; + padding_samples_needed -= empty_frame.header.blocksize; + decoder->protected_->blocksize = empty_frame.header.blocksize; + + FLAC__ASSERT(empty_frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER); + decoder->private_->samples_decoded = empty_frame.header.number.sample_number + empty_frame.header.blocksize; + + for(channel = 0; channel < empty_frame.header.channels; channel++) { + empty_frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_CONSTANT; + empty_frame.subframes[channel].data.constant.value = 0; + empty_frame.subframes[channel].wasted_bits = 0; + } + + if(write_audio_frame_to_client_(decoder, &empty_frame, (const FLAC__int32 * const *)empty_buffer) != FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE) { + decoder->protected_->state = FLAC__STREAM_DECODER_ABORTED; + for(i = 0; i < empty_frame.header.channels; i++) + if(empty_buffer[i] != NULL) + free(empty_buffer[i]); + return false; + } + } + for(i = 0; i < empty_frame.header.channels; i++) + if(empty_buffer[i] != NULL) + free(empty_buffer[i]); + } } } - *got_a_frame = true; + if(decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC || decoder->protected_->state == FLAC__STREAM_DECODER_END_OF_STREAM) { + /* Got corruption, rewind if possible. Return value of seek + * isn't checked, if the seek fails the decoder will continue anyway */ + if(!FLAC__bitreader_rewind_to_after_last_seen_framesync(decoder->private_->input)){ +#ifndef NDEBUG + fprintf(stderr, "Rewinding, seeking necessary\n"); +#endif + if(decoder->private_->seek_callback && decoder->private_->last_seen_framesync){ + /* Last framesync isn't in bitreader anymore, rewind with seek if possible */ +#ifndef NDEBUG + FLAC__uint64 current_decode_position; + if(FLAC__stream_decoder_get_decode_position(decoder, ¤t_decode_position)) + fprintf(stderr, "Bitreader was %" PRIu64 " bytes short\n", current_decode_position-decoder->private_->last_seen_framesync); +#endif + if(decoder->private_->seek_callback(decoder, decoder->private_->last_seen_framesync, decoder->private_->client_data) == FLAC__STREAM_DECODER_SEEK_STATUS_ERROR) { + decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; + return false; + } + if(!FLAC__bitreader_clear(decoder->private_->input)) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + return false; + } + } + } +#ifndef NDEBUG + else{ + fprintf(stderr, "Rewinding, seeking not necessary\n"); + } +#endif + } + else { + *got_a_frame = true; - /* we wait to update fixed_block_size until here, when we're sure we've got a proper frame and hence a correct blocksize */ - if(decoder->private_->next_fixed_block_size) - decoder->private_->fixed_block_size = decoder->private_->next_fixed_block_size; + /* we wait to update fixed_block_size until here, when we're sure we've got a proper frame and hence a correct blocksize */ + if(decoder->private_->next_fixed_block_size) + decoder->private_->fixed_block_size = decoder->private_->next_fixed_block_size; - /* put the latest values into the public section of the decoder instance */ - decoder->protected_->channels = decoder->private_->frame.header.channels; - decoder->protected_->channel_assignment = decoder->private_->frame.header.channel_assignment; - decoder->protected_->bits_per_sample = decoder->private_->frame.header.bits_per_sample; - decoder->protected_->sample_rate = decoder->private_->frame.header.sample_rate; - decoder->protected_->blocksize = decoder->private_->frame.header.blocksize; + /* put the latest values into the public section of the decoder instance */ + decoder->protected_->channels = decoder->private_->frame.header.channels; + decoder->protected_->channel_assignment = decoder->private_->frame.header.channel_assignment; + decoder->protected_->bits_per_sample = decoder->private_->frame.header.bits_per_sample; + decoder->protected_->sample_rate = decoder->private_->frame.header.sample_rate; + decoder->protected_->blocksize = decoder->private_->frame.header.blocksize; - FLAC__ASSERT(decoder->private_->frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER); - decoder->private_->samples_decoded = decoder->private_->frame.header.number.sample_number + decoder->private_->frame.header.blocksize; + FLAC__ASSERT(decoder->private_->frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER); + decoder->private_->samples_decoded = decoder->private_->frame.header.number.sample_number + decoder->private_->frame.header.blocksize; - /* write it */ - if(do_full_decode) { - if(write_audio_frame_to_client_(decoder, &decoder->private_->frame, (const FLAC__int32 * const *)decoder->private_->output) != FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE) { - decoder->protected_->state = FLAC__STREAM_DECODER_ABORTED; - return false; + /* write it */ + if(do_full_decode) { + if(write_audio_frame_to_client_(decoder, &decoder->private_->frame, (const FLAC__int32 * const *)decoder->private_->output) != FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE) { + decoder->protected_->state = FLAC__STREAM_DECODER_ABORTED; + return false; + } } } @@ -2346,6 +2457,9 @@ FLAC__bool read_frame_header_(FLAC__StreamDecoder *decoder) case 2: decoder->private_->frame.header.bits_per_sample = 12; break; + case 3: + is_unparseable = true; + break; case 4: decoder->private_->frame.header.bits_per_sample = 16; break; @@ -2355,20 +2469,14 @@ FLAC__bool read_frame_header_(FLAC__StreamDecoder *decoder) case 6: decoder->private_->frame.header.bits_per_sample = 24; break; - case 3: case 7: - is_unparseable = true; + decoder->private_->frame.header.bits_per_sample = 32; break; default: FLAC__ASSERT(0); break; } - if(decoder->private_->frame.header.bits_per_sample == 32 && decoder->private_->frame.header.channel_assignment != FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT){ - /* Decoder isn't equipped for 33-bit side frame */ - is_unparseable = true; - } - #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION /* check to make sure that reserved bit is 0 */ if(raw_header[3] & 0x01) /* MAGIC NUMBER */ @@ -2419,6 +2527,14 @@ FLAC__bool read_frame_header_(FLAC__StreamDecoder *decoder) x = (x << 8) | _x; } decoder->private_->frame.header.blocksize = x+1; + if(decoder->private_->frame.header.blocksize > 65535) { /* invalid blocksize (65536) specified */ + decoder->private_->lookahead = raw_header[raw_header_len-1]; /* back up as much as we can */ + decoder->private_->cached = true; + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER); + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + return true; + } + } if(sample_rate_hint) { @@ -2504,8 +2620,11 @@ FLAC__bool read_subframe_(FLAC__StreamDecoder *decoder, uint32_t channel, uint32 if(!FLAC__bitreader_read_unary_unsigned(decoder->private_->input, &u)) return false; /* read_callback_ sets the state for us */ decoder->private_->frame.subframes[channel].wasted_bits = u+1; - if (decoder->private_->frame.subframes[channel].wasted_bits >= bps) - return false; + if (decoder->private_->frame.subframes[channel].wasted_bits >= bps) { + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC); + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + return true; + } bps -= decoder->private_->frame.subframes[channel].wasted_bits; } else @@ -2534,12 +2653,6 @@ FLAC__bool read_subframe_(FLAC__StreamDecoder *decoder, uint32_t channel, uint32 } else if(x <= 24) { uint32_t predictor_order = (x>>1)&7; - if(decoder->private_->frame.header.bits_per_sample > 24){ - /* Decoder isn't equipped for fixed subframes with more than 24 bps */ - send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM); - decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; - return true; - } if(decoder->private_->frame.header.blocksize <= predictor_order){ send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC); decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; @@ -2570,9 +2683,21 @@ FLAC__bool read_subframe_(FLAC__StreamDecoder *decoder, uint32_t channel, uint32 if(wasted_bits && do_full_decode) { x = decoder->private_->frame.subframes[channel].wasted_bits; - for(i = 0; i < decoder->private_->frame.header.blocksize; i++) { - uint32_t val = decoder->private_->output[channel][i]; - decoder->private_->output[channel][i] = (val << x); + if((bps + x) < 33) { + for(i = 0; i < decoder->private_->frame.header.blocksize; i++) { + uint32_t val = decoder->private_->output[channel][i]; + decoder->private_->output[channel][i] = (val << x); + } + } + else { + /* When there are wasted bits, bps is never 33 and so + * side_subframe is never already in use */ + FLAC__ASSERT(!decoder->private_->side_subframe_in_use); + decoder->private_->side_subframe_in_use = true; + for(i = 0; i < decoder->private_->frame.header.blocksize; i++) { + uint64_t val = decoder->private_->output[channel][i]; + decoder->private_->side_subframe[i] = (val << x); + } } } @@ -2582,21 +2707,28 @@ FLAC__bool read_subframe_(FLAC__StreamDecoder *decoder, uint32_t channel, uint32 FLAC__bool read_subframe_constant_(FLAC__StreamDecoder *decoder, uint32_t channel, uint32_t bps, FLAC__bool do_full_decode) { FLAC__Subframe_Constant *subframe = &decoder->private_->frame.subframes[channel].data.constant; - FLAC__int32 x; + FLAC__int64 x; uint32_t i; - FLAC__int32 *output = decoder->private_->output[channel]; decoder->private_->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_CONSTANT; - if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &x, bps)) + if(!FLAC__bitreader_read_raw_int64(decoder->private_->input, &x, bps)) return false; /* read_callback_ sets the state for us */ subframe->value = x; /* decode the subframe */ if(do_full_decode) { - for(i = 0; i < decoder->private_->frame.header.blocksize; i++) - output[i] = x; + if(bps <= 32) { + FLAC__int32 *output = decoder->private_->output[channel]; + for(i = 0; i < decoder->private_->frame.header.blocksize; i++) + output[i] = x; + } else { + FLAC__int64 *output = decoder->private_->side_subframe; + decoder->private_->side_subframe_in_use = true; + for(i = 0; i < decoder->private_->frame.header.blocksize; i++) + output[i] = x; + } } return true; @@ -2605,7 +2737,7 @@ FLAC__bool read_subframe_constant_(FLAC__StreamDecoder *decoder, uint32_t channe FLAC__bool read_subframe_fixed_(FLAC__StreamDecoder *decoder, uint32_t channel, uint32_t bps, const uint32_t order, FLAC__bool do_full_decode) { FLAC__Subframe_Fixed *subframe = &decoder->private_->frame.subframes[channel].data.fixed; - FLAC__int32 i32; + FLAC__int64 i64; FLAC__uint32 u32; uint32_t u; @@ -2616,9 +2748,9 @@ FLAC__bool read_subframe_fixed_(FLAC__StreamDecoder *decoder, uint32_t channel, /* read warm-up samples */ for(u = 0; u < order; u++) { - if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &i32, bps)) + if(!FLAC__bitreader_read_raw_int64(decoder->private_->input, &i64, bps)) return false; /* read_callback_ sets the state for us */ - subframe->warmup[u] = i32; + subframe->warmup[u] = i64; } /* read entropy coding method info */ @@ -2658,8 +2790,20 @@ FLAC__bool read_subframe_fixed_(FLAC__StreamDecoder *decoder, uint32_t channel, /* decode the subframe */ if(do_full_decode) { - memcpy(decoder->private_->output[channel], subframe->warmup, sizeof(FLAC__int32) * order); - FLAC__fixed_restore_signal(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, order, decoder->private_->output[channel]+order); + if(bps < 33){ + uint32_t i; + for(i = 0; i < order; i++) + decoder->private_->output[channel][i] = subframe->warmup[i]; + if(bps+order <= 32) + FLAC__fixed_restore_signal(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, order, decoder->private_->output[channel]+order); + else + FLAC__fixed_restore_signal_wide(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, order, decoder->private_->output[channel]+order); + } + else { + decoder->private_->side_subframe_in_use = true; + memcpy(decoder->private_->side_subframe, subframe->warmup, sizeof(FLAC__int64) * order); + FLAC__fixed_restore_signal_wide_33bit(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, order, decoder->private_->side_subframe+order); + } } return true; @@ -2669,6 +2813,7 @@ FLAC__bool read_subframe_lpc_(FLAC__StreamDecoder *decoder, uint32_t channel, ui { FLAC__Subframe_LPC *subframe = &decoder->private_->frame.subframes[channel].data.lpc; FLAC__int32 i32; + FLAC__int64 i64; FLAC__uint32 u32; uint32_t u; @@ -2679,9 +2824,9 @@ FLAC__bool read_subframe_lpc_(FLAC__StreamDecoder *decoder, uint32_t channel, ui /* read warm-up samples */ for(u = 0; u < order; u++) { - if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &i32, bps)) + if(!FLAC__bitreader_read_raw_int64(decoder->private_->input, &i64, bps)) return false; /* read_callback_ sets the state for us */ - subframe->warmup[u] = i32; + subframe->warmup[u] = i64; } /* read qlp coeff precision */ @@ -2748,14 +2893,21 @@ FLAC__bool read_subframe_lpc_(FLAC__StreamDecoder *decoder, uint32_t channel, ui /* decode the subframe */ if(do_full_decode) { - memcpy(decoder->private_->output[channel], subframe->warmup, sizeof(FLAC__int32) * order); - if(bps + subframe->qlp_coeff_precision + FLAC__bitmath_ilog2(order) <= 32) - if(bps <= 16 && subframe->qlp_coeff_precision <= 16) - decoder->private_->local_lpc_restore_signal_16bit(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order); + if(bps <= 32) { + uint32_t i; + for(i = 0; i < order; i++) + decoder->private_->output[channel][i] = subframe->warmup[i]; + if(FLAC__lpc_max_residual_bps(bps, subframe->qlp_coeff, order, subframe->quantization_level) <= 32 && + FLAC__lpc_max_prediction_before_shift_bps(bps, subframe->qlp_coeff, order) <= 32) + FLAC__lpc_restore_signal(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order); else - decoder->private_->local_lpc_restore_signal(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order); - else - decoder->private_->local_lpc_restore_signal_64bit(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order); + FLAC__lpc_restore_signal_wide(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order); + } + else { + decoder->private_->side_subframe_in_use = true; + memcpy(decoder->private_->side_subframe, subframe->warmup, sizeof(FLAC__int64) * order); + FLAC__lpc_restore_signal_wide_33bit(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->side_subframe+order); + } } return true; @@ -2764,22 +2916,39 @@ FLAC__bool read_subframe_lpc_(FLAC__StreamDecoder *decoder, uint32_t channel, ui FLAC__bool read_subframe_verbatim_(FLAC__StreamDecoder *decoder, uint32_t channel, uint32_t bps, FLAC__bool do_full_decode) { FLAC__Subframe_Verbatim *subframe = &decoder->private_->frame.subframes[channel].data.verbatim; - FLAC__int32 x, *residual = decoder->private_->residual[channel]; uint32_t i; decoder->private_->frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_VERBATIM; - subframe->data = residual; + if(bps < 33) { + FLAC__int32 x, *residual = decoder->private_->residual[channel]; - for(i = 0; i < decoder->private_->frame.header.blocksize; i++) { - if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &x, bps)) - return false; /* read_callback_ sets the state for us */ - residual[i] = x; + subframe->data_type = FLAC__VERBATIM_SUBFRAME_DATA_TYPE_INT32; + subframe->data.int32 = residual; + + for(i = 0; i < decoder->private_->frame.header.blocksize; i++) { + if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &x, bps)) + return false; /* read_callback_ sets the state for us */ + residual[i] = x; + } + + /* decode the subframe */ + if(do_full_decode) + memcpy(decoder->private_->output[channel], subframe->data.int32, sizeof(FLAC__int32) * decoder->private_->frame.header.blocksize); } + else { + FLAC__int64 x, *side = decoder->private_->side_subframe; - /* decode the subframe */ - if(do_full_decode) - memcpy(decoder->private_->output[channel], subframe->data, sizeof(FLAC__int32) * decoder->private_->frame.header.blocksize); + subframe->data_type = FLAC__VERBATIM_SUBFRAME_DATA_TYPE_INT64; + subframe->data.int64 = side; + decoder->private_->side_subframe_in_use = true; + + for(i = 0; i < decoder->private_->frame.header.blocksize; i++) { + if(!FLAC__bitreader_read_raw_int64(decoder->private_->input, &x, bps)) + return false; /* read_callback_ sets the state for us */ + side[i] = x; + } + } return true; } @@ -2810,18 +2979,33 @@ FLAC__bool read_residual_partitioned_rice_(FLAC__StreamDecoder *decoder, uint32_ if(rice_parameter < pesc) { partitioned_rice_contents->raw_bits[partition] = 0; u = (partition == 0) ? partition_samples - predictor_order : partition_samples; - if(!FLAC__bitreader_read_rice_signed_block(decoder->private_->input, residual + sample, u, rice_parameter)) - return false; /* read_callback_ sets the state for us */ + if(!decoder->private_->local_bitreader_read_rice_signed_block(decoder->private_->input, residual + sample, u, rice_parameter)){ + if(decoder->protected_->state == FLAC__STREAM_DECODER_READ_FRAME) { + /* no error was set, read_callback_ didn't set it, so + * invalid rice symbol was found */ + send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC); + decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; + return true; + } + else + return false; /* read_callback_ sets the state for us */ + } sample += u; } else { if(!FLAC__bitreader_read_raw_uint32(decoder->private_->input, &rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN)) return false; /* read_callback_ sets the state for us */ partitioned_rice_contents->raw_bits[partition] = rice_parameter; - for(u = (partition == 0)? predictor_order : 0; u < partition_samples; u++, sample++) { - if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &i, rice_parameter)) - return false; /* read_callback_ sets the state for us */ - residual[sample] = i; + if(rice_parameter == 0) { + for(u = (partition == 0)? predictor_order : 0; u < partition_samples; u++, sample++) + residual[sample] = 0; + } + else{ + for(u = (partition == 0)? predictor_order : 0; u < partition_samples; u++, sample++) { + if(!FLAC__bitreader_read_raw_int32(decoder->private_->input, &i, rice_parameter)) + return false; /* read_callback_ sets the state for us */ + residual[sample] = i; + } } } } @@ -2925,6 +3109,66 @@ FLAC__bool read_callback_(FLAC__byte buffer[], size_t *bytes, void *client_data) */ } +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && !defined(FUZZING_BUILD_MODE_FLAC_SANITIZE_SIGNED_INTEGER_OVERFLOW) +/* The attribute below is to silence the undefined sanitizer of oss-fuzz. + * Because fuzzing feeds bogus predictors and residual samples to the + * decoder, having overflows in this section is unavoidable. Also, + * because the calculated values are audio path only, there is no + * potential for security problems */ +__attribute__((no_sanitize("signed-integer-overflow"))) +#endif +void undo_channel_coding(FLAC__StreamDecoder *decoder) { + uint32_t i; + switch(decoder->private_->frame.header.channel_assignment) { + case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT: + /* do nothing */ + break; + case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE: + FLAC__ASSERT(decoder->private_->frame.header.channels == 2); + FLAC__ASSERT(decoder->private_->side_subframe_in_use != /* logical XOR */ (decoder->private_->frame.header.bits_per_sample < 32)); + for(i = 0; i < decoder->private_->frame.header.blocksize; i++) + if(decoder->private_->side_subframe_in_use) + decoder->private_->output[1][i] = decoder->private_->output[0][i] - decoder->private_->side_subframe[i]; + else + decoder->private_->output[1][i] = decoder->private_->output[0][i] - decoder->private_->output[1][i]; + break; + case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE: + FLAC__ASSERT(decoder->private_->frame.header.channels == 2); + FLAC__ASSERT(decoder->private_->side_subframe_in_use != /* logical XOR */ (decoder->private_->frame.header.bits_per_sample < 32)); + for(i = 0; i < decoder->private_->frame.header.blocksize; i++) + if(decoder->private_->side_subframe_in_use) + decoder->private_->output[0][i] = decoder->private_->output[1][i] + decoder->private_->side_subframe[i]; + else + decoder->private_->output[0][i] += decoder->private_->output[1][i]; + break; + case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE: + FLAC__ASSERT(decoder->private_->frame.header.channels == 2); + FLAC__ASSERT(decoder->private_->side_subframe_in_use != /* logical XOR */ (decoder->private_->frame.header.bits_per_sample < 32)); + for(i = 0; i < decoder->private_->frame.header.blocksize; i++) { + if(!decoder->private_->side_subframe_in_use){ + FLAC__int32 mid, side; + mid = decoder->private_->output[0][i]; + side = decoder->private_->output[1][i]; + mid = ((uint32_t) mid) << 1; + mid |= (side & 1); /* i.e. if 'side' is odd... */ + decoder->private_->output[0][i] = (mid + side) >> 1; + decoder->private_->output[1][i] = (mid - side) >> 1; + } + else { /* bps == 32 */ + FLAC__int64 mid; + mid = ((uint64_t)decoder->private_->output[0][i]) << 1; + mid |= (decoder->private_->side_subframe[i] & 1); /* i.e. if 'side' is odd... */ + decoder->private_->output[0][i] = (mid + decoder->private_->side_subframe[i]) >> 1; + decoder->private_->output[1][i] = (mid - decoder->private_->side_subframe[i]) >> 1; + } + } + break; + default: + FLAC__ASSERT(0); + break; + } +} + #if FLAC__HAS_OGG FLAC__StreamDecoderReadStatus read_callback_ogg_aspect_(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes) { @@ -2973,6 +3217,8 @@ FLAC__OggDecoderAspectReadStatus read_callback_proxy_(const void *void_decoder, FLAC__StreamDecoderWriteStatus write_audio_frame_to_client_(FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[]) { + decoder->private_->last_frame = *frame; /* save the frame */ + decoder->private_->last_frame_is_set = true; if(decoder->private_->is_seeking) { FLAC__uint64 this_frame_sample = frame->header.number.sample_number; FLAC__uint64 next_frame_sample = this_frame_sample + (FLAC__uint64)frame->header.blocksize; @@ -2983,7 +3229,6 @@ FLAC__StreamDecoderWriteStatus write_audio_frame_to_client_(FLAC__StreamDecoder #if FLAC__HAS_OGG decoder->private_->got_a_frame = true; #endif - decoder->private_->last_frame = *frame; /* save the frame */ if(this_frame_sample <= target_sample && target_sample < next_frame_sample) { /* we hit our target frame */ uint32_t delta = (uint32_t)(target_sample - this_frame_sample); /* kick out of seek mode */ @@ -2992,8 +3237,12 @@ FLAC__StreamDecoderWriteStatus write_audio_frame_to_client_(FLAC__StreamDecoder if(delta > 0) { uint32_t channel; const FLAC__int32 *newbuffer[FLAC__MAX_CHANNELS]; - for(channel = 0; channel < frame->header.channels; channel++) + for(channel = 0; channel < frame->header.channels; channel++) { newbuffer[channel] = buffer[channel] + delta; + decoder->private_->last_frame.subframes[channel].type = FLAC__SUBFRAME_TYPE_VERBATIM; + decoder->private_->last_frame.subframes[channel].data.verbatim.data_type = FLAC__VERBATIM_SUBFRAME_DATA_TYPE_INT32; + decoder->private_->last_frame.subframes[channel].data.verbatim.data.int32 = newbuffer[channel]; + } decoder->private_->last_frame.header.blocksize -= delta; decoder->private_->last_frame.header.number.sample_number += (FLAC__uint64)delta; /* write the relevant samples */ @@ -3037,7 +3286,7 @@ FLAC__bool seek_to_absolute_sample_(FLAC__StreamDecoder *decoder, FLAC__uint64 s FLAC__int64 pos = -1; int i; uint32_t approx_bytes_per_frame; - FLAC__bool first_seek = true; + FLAC__bool first_seek = true, seek_from_lower_bound = false; const FLAC__uint64 total_samples = FLAC__stream_decoder_get_total_samples(decoder); const uint32_t min_blocksize = decoder->private_->stream_info.data.stream_info.min_blocksize; const uint32_t max_blocksize = decoder->private_->stream_info.data.stream_info.max_blocksize; @@ -3082,7 +3331,8 @@ FLAC__bool seek_to_absolute_sample_(FLAC__StreamDecoder *decoder, FLAC__uint64 s upper_bound = stream_length; upper_bound_sample = total_samples > 0 ? total_samples : target_sample /*estimate it*/; - if(decoder->protected_->state == FLAC__STREAM_DECODER_READ_FRAME) { + if(decoder->protected_->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC && + decoder->private_->samples_decoded != 0) { if(target_sample < decoder->private_->samples_decoded) { if(FLAC__stream_decoder_get_decode_position(decoder, &upper_bound)) upper_bound_sample = decoder->private_->samples_decoded; @@ -3098,7 +3348,9 @@ FLAC__bool seek_to_absolute_sample_(FLAC__StreamDecoder *decoder, FLAC__uint64 s * must be ordered by ascending sample number. * * Note: to protect against invalid seek tables we will ignore points - * that have frame_samples==0 or sample_number>=total_samples + * that have frame_samples==0 or sample_number>=total_samples. Also, + * because math is limited to 64-bit ints, seekpoints with an offset + * larger than 2^63 (8 exbibyte) are rejected. */ if(seek_table) { FLAC__uint64 new_lower_bound = lower_bound; @@ -3159,22 +3411,34 @@ FLAC__bool seek_to_absolute_sample_(FLAC__StreamDecoder *decoder, FLAC__uint64 s decoder->private_->target_sample = target_sample; while(1) { + /* check whether decoder is still valid so bad state isn't overwritten + * with seek error */ + if(decoder->protected_->state == FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR || + decoder->protected_->state == FLAC__STREAM_DECODER_ABORTED) + return false; /* check if the bounds are still ok */ - if (lower_bound_sample >= upper_bound_sample || lower_bound > upper_bound) { + if (lower_bound_sample >= upper_bound_sample || + lower_bound > upper_bound || + upper_bound >= INT64_MAX) { decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; return false; } + if(seek_from_lower_bound) { + pos = lower_bound; + } + else { #ifndef FLAC__INTEGER_ONLY_LIBRARY - pos = (FLAC__int64)lower_bound + (FLAC__int64)((double)(target_sample - lower_bound_sample) / (double)(upper_bound_sample - lower_bound_sample) * (double)(upper_bound - lower_bound)) - approx_bytes_per_frame; + pos = (FLAC__int64)lower_bound + (FLAC__int64)((double)(target_sample - lower_bound_sample) / (double)(upper_bound_sample - lower_bound_sample) * (double)(upper_bound - lower_bound)) - approx_bytes_per_frame; #else - /* a little less accurate: */ - if(upper_bound - lower_bound < 0xffffffff) - pos = (FLAC__int64)lower_bound + (FLAC__int64)(((target_sample - lower_bound_sample) * (upper_bound - lower_bound)) / (upper_bound_sample - lower_bound_sample)) - approx_bytes_per_frame; - else { /* @@@ WATCHOUT, ~2TB limit */ - FLAC__uint64 ratio = (1<<16) / (upper_bound_sample - lower_bound_sample); - pos = (FLAC__int64)lower_bound + (FLAC__int64)((((target_sample - lower_bound_sample)>>8) * ((upper_bound - lower_bound)>>8) * ratio)) - approx_bytes_per_frame; - } + /* a little less accurate: */ + if(upper_bound - lower_bound < 0xffffffff) + pos = (FLAC__int64)lower_bound + (FLAC__int64)(((target_sample - lower_bound_sample) * (upper_bound - lower_bound)) / (upper_bound_sample - lower_bound_sample)) - approx_bytes_per_frame; + else { /* @@@ WATCHOUT, ~2TB limit */ + FLAC__uint64 ratio = (1<<16) / (upper_bound_sample - lower_bound_sample); + pos = (FLAC__int64)lower_bound + (FLAC__int64)((((target_sample - lower_bound_sample)>>8) * ((upper_bound - lower_bound)>>8) * ratio)) - approx_bytes_per_frame; + } #endif + } if(pos >= (FLAC__int64)upper_bound) pos = (FLAC__int64)upper_bound - 1; if(pos < (FLAC__int64)lower_bound) @@ -3194,25 +3458,32 @@ FLAC__bool seek_to_absolute_sample_(FLAC__StreamDecoder *decoder, FLAC__uint64 s * FLAC__stream_decoder_process_single() to return false. */ decoder->private_->unparseable_frame_count = 0; - if(!FLAC__stream_decoder_process_single(decoder) || - decoder->protected_->state == FLAC__STREAM_DECODER_ABORTED) { - decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; - return false; + if(!FLAC__stream_decoder_process_single(decoder) || decoder->protected_->state == FLAC__STREAM_DECODER_ABORTED || 0 == decoder->private_->samples_decoded) { + /* No frame could be decoded */ + if(decoder->protected_->state != FLAC__STREAM_DECODER_ABORTED && decoder->private_->eof_callback(decoder, decoder->private_->client_data) && !seek_from_lower_bound){ + /* decoder has hit end of stream while processing corrupt + * frame. To remedy this, try decoding a frame at the lower + * bound so the seek after that hopefully ends up somewhere + * else */ + seek_from_lower_bound = true; + continue; + } + else { + decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; + return false; + } } + seek_from_lower_bound = false; + /* our write callback will change the state when it gets to the target frame */ /* actually, we could have got_a_frame if our decoder is at FLAC__STREAM_DECODER_END_OF_STREAM so we need to check for that also */ -#if 0 - /*@@@@@@ used to be the following; not clear if the check for end of stream is needed anymore */ - if(decoder->protected_->state != FLAC__SEEKABLE_STREAM_DECODER_SEEKING && decoder->protected_->state != FLAC__STREAM_DECODER_END_OF_STREAM) - break; -#endif if(!decoder->private_->is_seeking) break; FLAC__ASSERT(decoder->private_->last_frame.header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER); this_frame_sample = decoder->private_->last_frame.header.number.sample_number; - if (0 == decoder->private_->samples_decoded || (this_frame_sample + decoder->private_->last_frame.header.blocksize >= upper_bound_sample && !first_seek)) { + if(this_frame_sample + decoder->private_->last_frame.header.blocksize >= upper_bound_sample && !first_seek) { if (pos == (FLAC__int64)lower_bound) { /* can't move back any more than the first frame, something is fatally wrong */ decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; @@ -3286,6 +3557,12 @@ FLAC__bool seek_to_absolute_sample_ogg_(FLAC__StreamDecoder *decoder, FLAC__uint decoder->private_->target_sample = target_sample; for( ; ; iteration++) { + /* Do sanity checks on bounds */ + if(right_pos <= left_pos || right_pos - left_pos < 9) { + /* FLAC frame is at least 9 byte in size */ + decoder->protected_->state = FLAC__STREAM_DECODER_SEEK_ERROR; + return false; + } if (iteration == 0 || this_frame_sample > target_sample || target_sample - this_frame_sample > LINEAR_SEARCH_WITHIN_SAMPLES) { if (iteration >= BINARY_SEARCH_AFTER_ITERATION) { pos = (right_pos + left_pos) / 2; @@ -3439,7 +3716,13 @@ FLAC__StreamDecoderLengthStatus file_length_callback_(const FLAC__StreamDecoder if(decoder->private_->file == stdin) return FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED; - else if(flac_fstat(fileno(decoder->private_->file), &filestats) != 0) + +#ifndef FLAC__USE_FILELENGTHI64 + if(flac_fstat(fileno(decoder->private_->file), &filestats) != 0) +#else + filestats.st_size = _filelengthi64(fileno(decoder->private_->file)); + if(filestats.st_size < 0) +#endif return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR; else { *stream_length = (FLAC__uint64)filestats.st_size; @@ -3454,8 +3737,3 @@ FLAC__bool file_eof_callback_(const FLAC__StreamDecoder *decoder, void *client_d return feof(decoder->private_->file)? true : false; } #endif - -void *get_client_data_from_decoder(FLAC__StreamDecoder *decoder) -{ - return decoder->private_->client_data; -} diff --git a/modules/juce_audio_formats/codecs/flac/libFLAC/stream_encoder.c b/modules/juce_audio_formats/codecs/flac/libFLAC/stream_encoder.c index c48ba8a686e9..c9af0eb5a91a 100644 --- a/modules/juce_audio_formats/codecs/flac/libFLAC/stream_encoder.c +++ b/modules/juce_audio_formats/codecs/flac/libFLAC/stream_encoder.c @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -56,6 +56,7 @@ #include "include/private/lpc.h" #include "include/private/md5.h" #include "include/private/memory.h" + #if FLAC__HAS_OGG #include "include/private/ogg_helper.h" #include "include/private/ogg_mapping.h" @@ -64,6 +65,7 @@ #include "include/private/stream_encoder_framing.h" #include "include/private/window.h" #include "../alloc.h" +#include "../private.h" /* Exact Rice codeword length calculation is off by default. The simple @@ -91,6 +93,15 @@ typedef struct { uint32_t bytes; } verify_output; +#ifndef FLAC__INTEGER_ONLY_LIBRARY +typedef struct { + uint32_t a, b, c; + FLAC__ApodizationSpecification * current_apodization; + double autoc_root[FLAC__MAX_LPC_ORDER+1]; + double autoc[FLAC__MAX_LPC_ORDER+1]; +} apply_apodization_state_struct; +#endif + typedef enum { ENCODER_IN_MAGIC = 0, ENCODER_IN_METADATA = 1, @@ -116,9 +127,9 @@ static const struct CompressionLevels { { false, false, 6, 0, false, false, false, 0, 4, 0, "tukey(5e-1)" }, { true , true , 8, 0, false, false, false, 0, 4, 0, "tukey(5e-1)" }, { true , false, 8, 0, false, false, false, 0, 5, 0, "tukey(5e-1)" }, - { true , false, 8, 0, false, false, false, 0, 6, 0, "tukey(5e-1);partial_tukey(2)" }, - { true , false, 12, 0, false, false, false, 0, 6, 0, "tukey(5e-1);partial_tukey(2)" }, - { true , false, 12, 0, false, false, false, 0, 6, 0, "tukey(5e-1);partial_tukey(2);punchout_tukey(3)" } + { true , false, 8, 0, false, false, false, 0, 6, 0, "subdivide_tukey(2)" }, + { true , false, 12, 0, false, false, false, 0, 6, 0, "subdivide_tukey(2)" }, + { true , false, 12, 0, false, false, false, 0, 6, 0, "subdivide_tukey(3)" } /* here we use locale-independent 5e-1 instead of 0.5 or 0,5 */ }; @@ -138,8 +149,8 @@ static void update_metadata_(const FLAC__StreamEncoder *encoder); #if FLAC__HAS_OGG static void update_ogg_metadata_(FLAC__StreamEncoder *encoder); #endif -static FLAC__bool process_frame_(FLAC__StreamEncoder *encoder, FLAC__bool is_fractional_block, FLAC__bool is_last_block); -static FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__bool is_fractional_block); +static FLAC__bool process_frame_(FLAC__StreamEncoder *encoder, FLAC__bool is_last_block); +static FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder); static FLAC__bool process_subframe_( FLAC__StreamEncoder *encoder, @@ -147,7 +158,7 @@ static FLAC__bool process_subframe_( uint32_t max_partition_order, const FLAC__FrameHeader *frame_header, uint32_t subframe_bps, - const FLAC__int32 integer_signal[], + const void *integer_signal, FLAC__Subframe *subframe[2], FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents[2], FLAC__int32 *residual[2], @@ -155,6 +166,19 @@ static FLAC__bool process_subframe_( uint32_t *best_bits ); +#ifndef FLAC__INTEGER_ONLY_LIBRARY +static FLAC__bool apply_apodization_( + FLAC__StreamEncoder *encoder, + apply_apodization_state_struct *apply_apodization_state, + uint32_t blocksize, + double *lpc_error, + uint32_t *max_lpc_order_this_apodization, + uint32_t subframe_bps, + const void *integer_signal, + uint32_t *guess_lpc_order +); +#endif + static FLAC__bool add_subframe_( FLAC__StreamEncoder *encoder, uint32_t blocksize, @@ -165,7 +189,7 @@ static FLAC__bool add_subframe_( static uint32_t evaluate_constant_subframe_( FLAC__StreamEncoder *encoder, - const FLAC__int32 signal, + const FLAC__int64 signal, uint32_t blocksize, uint32_t subframe_bps, FLAC__Subframe *subframe @@ -173,14 +197,13 @@ static uint32_t evaluate_constant_subframe_( static uint32_t evaluate_fixed_subframe_( FLAC__StreamEncoder *encoder, - const FLAC__int32 signal[], + const void *signal, FLAC__int32 residual[], FLAC__uint64 abs_residual_partition_sums[], uint32_t raw_bits_per_partition[], uint32_t blocksize, uint32_t subframe_bps, uint32_t order, - uint32_t rice_parameter, uint32_t rice_parameter_limit, uint32_t min_partition_order, uint32_t max_partition_order, @@ -193,7 +216,7 @@ static uint32_t evaluate_fixed_subframe_( #ifndef FLAC__INTEGER_ONLY_LIBRARY static uint32_t evaluate_lpc_subframe_( FLAC__StreamEncoder *encoder, - const FLAC__int32 signal[], + const void *signal, FLAC__int32 residual[], FLAC__uint64 abs_residual_partition_sums[], uint32_t raw_bits_per_partition[], @@ -202,7 +225,6 @@ static uint32_t evaluate_lpc_subframe_( uint32_t subframe_bps, uint32_t order, uint32_t qlp_coeff_precision, - uint32_t rice_parameter, uint32_t rice_parameter_limit, uint32_t min_partition_order, uint32_t max_partition_order, @@ -215,7 +237,7 @@ static uint32_t evaluate_lpc_subframe_( static uint32_t evaluate_verbatim_subframe_( FLAC__StreamEncoder *encoder, - const FLAC__int32 signal[], + const void *signal, uint32_t blocksize, uint32_t subframe_bps, FLAC__Subframe *subframe @@ -228,7 +250,6 @@ static uint32_t find_best_partition_order_( uint32_t raw_bits_per_partition[], uint32_t residual_samples, uint32_t predictor_order, - uint32_t rice_parameter, uint32_t rice_parameter_limit, uint32_t min_partition_order, uint32_t max_partition_order, @@ -265,7 +286,6 @@ static FLAC__bool set_partitioned_rice_( const uint32_t raw_bits_per_partition[], const uint32_t residual_samples, const uint32_t predictor_order, - const uint32_t suggested_rice_parameter, const uint32_t rice_parameter_limit, const uint32_t rice_parameter_search_dist, const uint32_t partition_order, @@ -275,6 +295,7 @@ static FLAC__bool set_partitioned_rice_( ); static uint32_t get_wasted_bits_(FLAC__int32 signal[], uint32_t samples); +static uint32_t get_wasted_bits_wide_(FLAC__int64 signal_wide[], FLAC__int32 signal[], uint32_t samples); /* verify-related routines: */ static void append_to_verify_fifo_( @@ -315,6 +336,7 @@ typedef struct FLAC__StreamEncoderPrivate { uint32_t input_capacity; /* current size (in samples) of the signal and residual buffers */ FLAC__int32 *integer_signal[FLAC__MAX_CHANNELS]; /* the integer version of the input signal */ FLAC__int32 *integer_signal_mid_side[2]; /* the integer version of the mid-side input signal (stereo only) */ + FLAC__int64 *integer_signal_33bit_side; /* 33-bit side for 32-bit stereo decorrelation */ #ifndef FLAC__INTEGER_ONLY_LIBRARY FLAC__real *real_signal[FLAC__MAX_CHANNELS]; /* (@@@ currently unused) the floating-point version of the input signal */ FLAC__real *real_signal_mid_side[2]; /* (@@@ currently unused) the floating-point version of the mid-side input signal (stereo only) */ @@ -353,16 +375,25 @@ typedef struct FLAC__StreamEncoderPrivate { #ifndef FLAC__INTEGER_ONLY_LIBRARY uint32_t (*local_fixed_compute_best_predictor)(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); uint32_t (*local_fixed_compute_best_predictor_wide)(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); + uint32_t (*local_fixed_compute_best_predictor_limit_residual)(const FLAC__int32 data[], uint32_t data_len, float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); #else uint32_t (*local_fixed_compute_best_predictor)(const FLAC__int32 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); uint32_t (*local_fixed_compute_best_predictor_wide)(const FLAC__int32 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); + uint32_t (*local_fixed_compute_best_predictor_limit_residual)(const FLAC__int32 data[], uint32_t data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); #endif #ifndef FLAC__INTEGER_ONLY_LIBRARY - void (*local_lpc_compute_autocorrelation)(const FLAC__real data[], uint32_t data_len, uint32_t lag, FLAC__real autoc[]); + void (*local_lpc_compute_autocorrelation)(const FLAC__real data[], uint32_t data_len, uint32_t lag, double autoc[]); void (*local_lpc_compute_residual_from_qlp_coefficients)(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]); void (*local_lpc_compute_residual_from_qlp_coefficients_64bit)(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]); void (*local_lpc_compute_residual_from_qlp_coefficients_16bit)(const FLAC__int32 *data, uint32_t data_len, const FLAC__int32 qlp_coeff[], uint32_t order, int lp_quantization, FLAC__int32 residual[]); #endif + FLAC__bool disable_mmx; + FLAC__bool disable_sse2; + FLAC__bool disable_ssse3; + FLAC__bool disable_sse41; + FLAC__bool disable_sse42; + FLAC__bool disable_avx2; + FLAC__bool disable_fma; FLAC__bool disable_constant_subframes; FLAC__bool disable_fixed_subframes; FLAC__bool disable_verbatim_subframes; @@ -383,6 +414,7 @@ typedef struct FLAC__StreamEncoderPrivate { /* unaligned (original) pointers to allocated data */ FLAC__int32 *integer_signal_unaligned[FLAC__MAX_CHANNELS]; FLAC__int32 *integer_signal_mid_side_unaligned[2]; + FLAC__int64 *integer_signal_33bit_side_unaligned; #ifndef FLAC__INTEGER_ONLY_LIBRARY FLAC__real *real_signal_unaligned[FLAC__MAX_CHANNELS]; /* (@@@ currently unused) */ FLAC__real *real_signal_mid_side_unaligned[2]; /* (@@@ currently unused) */ @@ -534,6 +566,8 @@ FLAC_API FLAC__StreamEncoder *FLAC__stream_encoder_new(void) encoder->private_->file = 0; + encoder->protected_->state = FLAC__STREAM_ENCODER_UNINITIALIZED; + set_defaults_(encoder); encoder->private_->is_being_deleted = false; @@ -566,8 +600,6 @@ FLAC_API FLAC__StreamEncoder *FLAC__stream_encoder_new(void) for(i = 0; i < 2; i++) FLAC__format_entropy_coding_method_partitioned_rice_contents_init(&encoder->private_->partitioned_rice_contents_extra[i]); - encoder->protected_->state = FLAC__STREAM_ENCODER_UNINITIALIZED; - return encoder; } @@ -649,10 +681,7 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_( else if(!encoder->protected_->do_mid_side_stereo) encoder->protected_->loose_mid_side_stereo = false; - if(encoder->protected_->bits_per_sample >= 32) - encoder->protected_->do_mid_side_stereo = false; /* since we currently do 32-bit math, the side channel would have 33 bps and overflow */ - - if(encoder->protected_->bits_per_sample < FLAC__MIN_BITS_PER_SAMPLE || encoder->protected_->bits_per_sample > FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE) + if(encoder->protected_->bits_per_sample < FLAC__MIN_BITS_PER_SAMPLE || encoder->protected_->bits_per_sample > FLAC__MAX_BITS_PER_SAMPLE) return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BITS_PER_SAMPLE; if(!FLAC__format_sample_rate_is_valid(encoder->protected_->sample_rate)) @@ -719,7 +748,8 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_( encoder->protected_->bits_per_sample != 12 && encoder->protected_->bits_per_sample != 16 && encoder->protected_->bits_per_sample != 20 && - encoder->protected_->bits_per_sample != 24 + encoder->protected_->bits_per_sample != 24 && + encoder->protected_->bits_per_sample != 32 ) return FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE; if(encoder->protected_->max_residual_partition_order > FLAC__SUBSET_MAX_RICE_PARTITION_ORDER) @@ -741,6 +771,18 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_( encoder->protected_->min_residual_partition_order = encoder->protected_->max_residual_partition_order; #if FLAC__HAS_OGG + /* drop any seektable for ogg */ + if(is_ogg && 0 != encoder->protected_->metadata && encoder->protected_->num_metadata_blocks > 0) { + uint32_t i1; + for(i1 = 0; i1 < encoder->protected_->num_metadata_blocks; i1++) { + if(0 != encoder->protected_->metadata[i1] && encoder->protected_->metadata[i1]->type == FLAC__METADATA_TYPE_SEEKTABLE) { + encoder->protected_->num_metadata_blocks--; + for( ; i1 < encoder->protected_->num_metadata_blocks; i1++) + encoder->protected_->metadata[i1] = encoder->protected_->metadata[i1+1]; + break; + } + } + } /* reorder metadata if necessary to ensure that any VORBIS_COMMENT is the first, according to the mapping spec */ if(is_ogg && 0 != encoder->protected_->metadata && encoder->protected_->num_metadata_blocks > 1) { uint32_t i1; @@ -832,6 +874,7 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_( encoder->private_->real_signal_mid_side_unaligned[i] = encoder->private_->real_signal_mid_side[i] = 0; #endif } + encoder->private_->integer_signal_33bit_side_unaligned = encoder->private_->integer_signal_33bit_side = 0; #ifndef FLAC__INTEGER_ONLY_LIBRARY for(i = 0; i < encoder->protected_->num_apodizations; i++) encoder->private_->window_unaligned[i] = encoder->private_->window[i] = 0; @@ -853,10 +896,10 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_( encoder->private_->loose_mid_side_stereo_frames = (uint32_t)((double)encoder->protected_->sample_rate * 0.4 / (double)encoder->protected_->blocksize + 0.5); #else /* 26214 is the approximate fixed-point equivalent to 0.4 (0.4 * 2^16) */ - /* sample rate can be up to 655350 Hz, and thus use 20 bits, so we do the multiply÷ by hand */ - FLAC__ASSERT(FLAC__MAX_SAMPLE_RATE <= 655350); + /* sample rate can be up to 1048575 Hz, and thus use 20 bits, so we do the multiply÷ by hand */ + FLAC__ASSERT(FLAC__MAX_SAMPLE_RATE <= 1048575); FLAC__ASSERT(FLAC__MAX_BLOCK_SIZE <= 65535); - FLAC__ASSERT(encoder->protected_->sample_rate <= 655350); + FLAC__ASSERT(encoder->protected_->sample_rate <= 1048575); FLAC__ASSERT(encoder->protected_->blocksize <= 65535); encoder->private_->loose_mid_side_stereo_frames = (uint32_t)FLAC__fixedpoint_trunc((((FLAC__uint64)(encoder->protected_->sample_rate) * (FLAC__uint64)(26214)) << 16) / (encoder->protected_->blocksize<<16) + FLAC__FP_ONE_HALF); #endif @@ -870,6 +913,22 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_( * get the CPU info and set the function pointers */ FLAC__cpu_info(&encoder->private_->cpuinfo); + /* remove cpu info as requested by + * FLAC__stream_encoder_disable_instruction_set */ + if(encoder->private_->disable_mmx) + encoder->private_->cpuinfo.x86.mmx = false; + if(encoder->private_->disable_sse2) + encoder->private_->cpuinfo.x86.sse2 = false; + if(encoder->private_->disable_ssse3) + encoder->private_->cpuinfo.x86.ssse3 = false; + if(encoder->private_->disable_sse41) + encoder->private_->cpuinfo.x86.sse41 = false; + if(encoder->private_->disable_sse42) + encoder->private_->cpuinfo.x86.sse42 = false; + if(encoder->private_->disable_avx2) + encoder->private_->cpuinfo.x86.avx2 = false; + if(encoder->private_->disable_fma) + encoder->private_->cpuinfo.x86.fma = false; /* first default to the non-asm routines */ #ifndef FLAC__INTEGER_ONLY_LIBRARY encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation; @@ -877,6 +936,7 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_( encoder->private_->local_precompute_partition_info_sums = precompute_partition_info_sums_; encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor; encoder->private_->local_fixed_compute_best_predictor_wide = FLAC__fixed_compute_best_predictor_wide; + encoder->private_->local_fixed_compute_best_predictor_limit_residual = FLAC__fixed_compute_best_predictor_limit_residual; #ifndef FLAC__INTEGER_ONLY_LIBRARY encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients; encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit = FLAC__lpc_compute_residual_from_qlp_coefficients_wide; @@ -885,100 +945,35 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_( /* now override with asm where appropriate */ #ifndef FLAC__INTEGER_ONLY_LIBRARY # ifndef FLAC__NO_ASM -#if defined(FLAC__CPU_PPC64) && defined(FLAC__USE_VSX) -#ifdef FLAC__HAS_TARGET_POWER8 -#ifdef FLAC__HAS_TARGET_POWER9 - if (encoder->private_->cpuinfo.ppc.arch_3_00) { - if(encoder->protected_->max_lpc_order < 4) - encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_power9_vsx_lag_4; - else if(encoder->protected_->max_lpc_order < 8) - encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_power9_vsx_lag_8; - else if(encoder->protected_->max_lpc_order < 12) - encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_power9_vsx_lag_12; - else if(encoder->protected_->max_lpc_order < 16) - encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_power9_vsx_lag_16; - else - encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation; - } else -#endif - if (encoder->private_->cpuinfo.ppc.arch_2_07) { - if(encoder->protected_->max_lpc_order < 4) - encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_power8_vsx_lag_4; - else if(encoder->protected_->max_lpc_order < 8) - encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_power8_vsx_lag_8; - else if(encoder->protected_->max_lpc_order < 12) - encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_power8_vsx_lag_12; - else if(encoder->protected_->max_lpc_order < 16) - encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_power8_vsx_lag_16; - else - encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation; - } -#endif +#if defined FLAC__CPU_ARM64 && FLAC__HAS_NEONINTRIN +#if FLAC__HAS_A64NEONINTRIN + if(encoder->protected_->max_lpc_order < 8) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_neon_lag_8; + else if(encoder->protected_->max_lpc_order < 10) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_neon_lag_10; + else if(encoder->protected_->max_lpc_order < 14) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_neon_lag_14; + else + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation; #endif + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_neon; + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_neon; + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit = FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_neon; +#endif /* defined FLAC__CPU_ARM64 && FLAC__HAS_NEONINTRIN */ + if(encoder->private_->cpuinfo.use_asm) { # ifdef FLAC__CPU_IA32 FLAC__ASSERT(encoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_IA32); -# ifdef FLAC__HAS_NASM - if (encoder->private_->cpuinfo.x86.sse) { - if(encoder->protected_->max_lpc_order < 4) - encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_4_old; - else if(encoder->protected_->max_lpc_order < 8) - encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_8_old; - else if(encoder->protected_->max_lpc_order < 12) - encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_12_old; - else if(encoder->protected_->max_lpc_order < 16) - encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_16_old; - else - encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32; - } - else - encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32; - - encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit = FLAC__lpc_compute_residual_from_qlp_coefficients_wide_asm_ia32; /* OPT_IA32: was really necessary for GCC < 4.9 */ - if (encoder->private_->cpuinfo.x86.mmx) { - encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32; - encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx; - } - else { - encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32; - encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32; - } - - if (encoder->private_->cpuinfo.x86.mmx && encoder->private_->cpuinfo.x86.cmov) - encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_asm_ia32_mmx_cmov; -# endif /* FLAC__HAS_NASM */ # if FLAC__HAS_X86INTRIN -# if defined FLAC__SSE_SUPPORTED - if (encoder->private_->cpuinfo.x86.sse) { - if (encoder->private_->cpuinfo.x86.sse42 || !encoder->private_->cpuinfo.x86.intel) { /* use new autocorrelation functions */ - if(encoder->protected_->max_lpc_order < 4) - encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4_new; - else if(encoder->protected_->max_lpc_order < 8) - encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8_new; - else if(encoder->protected_->max_lpc_order < 12) - encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12_new; - else if(encoder->protected_->max_lpc_order < 16) - encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16_new; - else - encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation; - } - else { /* use old autocorrelation functions */ - if(encoder->protected_->max_lpc_order < 4) - encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4_old; - else if(encoder->protected_->max_lpc_order < 8) - encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8_old; - else if(encoder->protected_->max_lpc_order < 12) - encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12_old; - else if(encoder->protected_->max_lpc_order < 16) - encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16_old; - else - encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation; - } - } -# endif - # ifdef FLAC__SSE2_SUPPORTED if (encoder->private_->cpuinfo.x86.sse2) { + if(encoder->protected_->max_lpc_order < 8) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse2_lag_8; + else if(encoder->protected_->max_lpc_order < 10) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse2_lag_10; + else if(encoder->protected_->max_lpc_order < 14) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse2_lag_14; + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_sse2; encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_sse2; } @@ -1000,44 +995,39 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_( # ifdef FLAC__SSE2_SUPPORTED if (encoder->private_->cpuinfo.x86.sse2) { encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_intrin_sse2; - encoder->private_->local_fixed_compute_best_predictor_wide = FLAC__fixed_compute_best_predictor_wide_intrin_sse2; } # endif # ifdef FLAC__SSSE3_SUPPORTED if (encoder->private_->cpuinfo.x86.ssse3) { encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_intrin_ssse3; - encoder->private_->local_fixed_compute_best_predictor_wide = FLAC__fixed_compute_best_predictor_wide_intrin_ssse3; + } +# endif +# ifdef FLAC__SSE4_2_SUPPORTED + if (encoder->private_->cpuinfo.x86.sse42) { + encoder->private_->local_fixed_compute_best_predictor_limit_residual = FLAC__fixed_compute_best_predictor_limit_residual_intrin_sse42; + } +# endif +# ifdef FLAC__AVX2_SUPPORTED + if (encoder->private_->cpuinfo.x86.avx2) { + encoder->private_->local_fixed_compute_best_predictor_wide = FLAC__fixed_compute_best_predictor_wide_intrin_avx2; + encoder->private_->local_fixed_compute_best_predictor_limit_residual = FLAC__fixed_compute_best_predictor_limit_residual_intrin_avx2; } # endif # endif /* FLAC__HAS_X86INTRIN */ # elif defined FLAC__CPU_X86_64 FLAC__ASSERT(encoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_X86_64); # if FLAC__HAS_X86INTRIN -# ifdef FLAC__SSE_SUPPORTED - if(encoder->private_->cpuinfo.x86.sse42 || !encoder->private_->cpuinfo.x86.intel) { /* use new autocorrelation functions */ - if(encoder->protected_->max_lpc_order < 4) - encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4_new; - else if(encoder->protected_->max_lpc_order < 8) - encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8_new; - else if(encoder->protected_->max_lpc_order < 12) - encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12_new; - else if(encoder->protected_->max_lpc_order < 16) - encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16_new; - } - else { - if(encoder->protected_->max_lpc_order < 4) - encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4_old; - else if(encoder->protected_->max_lpc_order < 8) - encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8_old; - else if(encoder->protected_->max_lpc_order < 12) - encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12_old; - else if(encoder->protected_->max_lpc_order < 16) - encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16_old; - } -# endif - # ifdef FLAC__SSE2_SUPPORTED - encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_sse2; + if(encoder->private_->cpuinfo.x86.sse2) { /* For fuzzing */ + if(encoder->protected_->max_lpc_order < 8) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse2_lag_8; + else if(encoder->protected_->max_lpc_order < 10) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse2_lag_10; + else if(encoder->protected_->max_lpc_order < 14) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse2_lag_14; + + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_sse2; + } # endif # ifdef FLAC__SSE4_1_SUPPORTED if(encoder->private_->cpuinfo.x86.sse41) { @@ -1051,25 +1041,48 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_( encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit = FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_avx2; } # endif +# ifdef FLAC__FMA_SUPPORTED + if(encoder->private_->cpuinfo.x86.fma) { + if(encoder->protected_->max_lpc_order < 8) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_fma_lag_8; + else if(encoder->protected_->max_lpc_order < 12) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_fma_lag_12; + else if(encoder->protected_->max_lpc_order < 16) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_fma_lag_16; + } +# endif + # ifdef FLAC__SSE2_SUPPORTED - encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_intrin_sse2; - encoder->private_->local_fixed_compute_best_predictor_wide = FLAC__fixed_compute_best_predictor_wide_intrin_sse2; + if(encoder->private_->cpuinfo.x86.sse2) { /* For fuzzing */ + encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_intrin_sse2; + } # endif # ifdef FLAC__SSSE3_SUPPORTED if (encoder->private_->cpuinfo.x86.ssse3) { encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_intrin_ssse3; - encoder->private_->local_fixed_compute_best_predictor_wide = FLAC__fixed_compute_best_predictor_wide_intrin_ssse3; + } +# endif +# ifdef FLAC__SSE4_2_SUPPORTED + if (encoder->private_->cpuinfo.x86.sse42) { + encoder->private_->local_fixed_compute_best_predictor_limit_residual = FLAC__fixed_compute_best_predictor_limit_residual_intrin_sse42; + } +# endif +# ifdef FLAC__AVX2_SUPPORTED + if (encoder->private_->cpuinfo.x86.avx2) { + encoder->private_->local_fixed_compute_best_predictor_wide = FLAC__fixed_compute_best_predictor_wide_intrin_avx2; + encoder->private_->local_fixed_compute_best_predictor_limit_residual = FLAC__fixed_compute_best_predictor_limit_residual_intrin_avx2; } # endif # endif /* FLAC__HAS_X86INTRIN */ # endif /* FLAC__CPU_... */ } # endif /* !FLAC__NO_ASM */ + #endif /* !FLAC__INTEGER_ONLY_LIBRARY */ #if !defined FLAC__NO_ASM && FLAC__HAS_X86INTRIN if(encoder->private_->cpuinfo.use_asm) { -# if defined FLAC__CPU_IA32 +# if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) # ifdef FLAC__SSE2_SUPPORTED if (encoder->private_->cpuinfo.x86.sse2) encoder->private_->local_precompute_partition_info_sums = FLAC__precompute_partition_info_sums_intrin_sse2; @@ -1082,18 +1095,6 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_( if (encoder->private_->cpuinfo.x86.avx2) encoder->private_->local_precompute_partition_info_sums = FLAC__precompute_partition_info_sums_intrin_avx2; # endif -# elif defined FLAC__CPU_X86_64 -# ifdef FLAC__SSE2_SUPPORTED - encoder->private_->local_precompute_partition_info_sums = FLAC__precompute_partition_info_sums_intrin_sse2; -# endif -# ifdef FLAC__SSSE3_SUPPORTED - if(encoder->private_->cpuinfo.x86.ssse3) - encoder->private_->local_precompute_partition_info_sums = FLAC__precompute_partition_info_sums_intrin_ssse3; -# endif -# ifdef FLAC__AVX2_SUPPORTED - if(encoder->private_->cpuinfo.x86.avx2) - encoder->private_->local_precompute_partition_info_sums = FLAC__precompute_partition_info_sums_intrin_avx2; -# endif # endif /* FLAC__CPU_... */ } #endif /* !FLAC__NO_ASM && FLAC__HAS_X86INTRIN */ @@ -1209,7 +1210,7 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_( memset(encoder->private_->streaminfo.data.stream_info.md5sum, 0, 16); /* we don't know this yet; have to fill it in later */ if(encoder->protected_->do_md5) FLAC__MD5Init(&encoder->private_->md5context); - if(!FLAC__add_metadata_block(&encoder->private_->streaminfo, encoder->private_->frame)) { + if(!FLAC__add_metadata_block(&encoder->private_->streaminfo, encoder->private_->frame, true)) { encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR; return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; } @@ -1245,7 +1246,7 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_( vorbis_comment.data.vorbis_comment.vendor_string.entry = 0; vorbis_comment.data.vorbis_comment.num_comments = 0; vorbis_comment.data.vorbis_comment.comments = 0; - if(!FLAC__add_metadata_block(&vorbis_comment, encoder->private_->frame)) { + if(!FLAC__add_metadata_block(&vorbis_comment, encoder->private_->frame, true)) { encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR; return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; } @@ -1260,7 +1261,7 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_( */ for(i = 0; i < encoder->protected_->num_metadata_blocks; i++) { encoder->protected_->metadata[i]->is_last = (i == encoder->protected_->num_metadata_blocks - 1); - if(!FLAC__add_metadata_block(encoder->protected_->metadata[i], encoder->private_->frame)) { + if(!FLAC__add_metadata_block(encoder->protected_->metadata[i], encoder->private_->frame, true)) { encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR; return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; } @@ -1477,14 +1478,28 @@ FLAC_API FLAC__bool FLAC__stream_encoder_finish(FLAC__StreamEncoder *encoder) FLAC__ASSERT(0 != encoder->private_); FLAC__ASSERT(0 != encoder->protected_); - if(encoder->protected_->state == FLAC__STREAM_ENCODER_UNINITIALIZED) + if(encoder->protected_->state == FLAC__STREAM_ENCODER_UNINITIALIZED){ + if(encoder->protected_->metadata){ // True in case FLAC__stream_encoder_set_metadata was used but init failed + free(encoder->protected_->metadata); + encoder->protected_->metadata = 0; + encoder->protected_->num_metadata_blocks = 0; + } + if(0 != encoder->private_->file) { + if(encoder->private_->file != stdout) + fclose(encoder->private_->file); + encoder->private_->file = 0; + } return true; + } if(encoder->protected_->state == FLAC__STREAM_ENCODER_OK && !encoder->private_->is_being_deleted) { if(encoder->private_->current_sample_number != 0) { - const FLAC__bool is_fractional_block = encoder->protected_->blocksize != encoder->private_->current_sample_number; encoder->protected_->blocksize = encoder->private_->current_sample_number; - if(!process_frame_(encoder, is_fractional_block, /*is_last_block=*/true)) + if(!resize_buffers_(encoder, encoder->protected_->blocksize)) { + /* the above function sets the state for us in case of an error */ + return FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR; + } + if(!process_frame_(encoder, /*is_last_block=*/true)) error = true; } } @@ -1578,7 +1593,15 @@ FLAC_API FLAC__bool FLAC__stream_encoder_set_streamable_subset(FLAC__StreamEncod return true; } -inline FLAC_API FLAC__bool FLAC__stream_encoder_set_do_md5(FLAC__StreamEncoder *encoder, FLAC__bool value) +/* + * The following routine was intended as debug routine and is not in the + * public headers, but SHOULD NOT CHANGE! It is known is is used in + * some non-audio projects needing every last bit of performance. + * See https://github.com/xiph/flac/issues/547 for details. These projects + * provide their own prototype, so changing the signature of this function + * would break building. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_do_md5(FLAC__StreamEncoder *encoder, FLAC__bool value) { FLAC__ASSERT(0 != encoder); FLAC__ASSERT(0 != encoder->private_); @@ -1742,7 +1765,7 @@ FLAC_API FLAC__bool FLAC__stream_encoder_set_apodization(FLAC__StreamEncoder *en encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_TUKEY; } } - else if(n>15 && 0 == strncmp("partial_tukey(" , specification, 14)) { + else if(n>15 && 0 == strncmp("partial_tukey(", specification, 14)) { FLAC__int32 tukey_parts = (FLAC__int32)strtod(specification+14, 0); const char *si_1 = strchr(specification, '/'); FLAC__real overlap = si_1?flac_min((FLAC__real)strtod(si_1+1, 0),0.99f):0.1f; @@ -1763,7 +1786,7 @@ FLAC_API FLAC__bool FLAC__stream_encoder_set_apodization(FLAC__StreamEncoder *en } } } - else if(n>16 && 0 == strncmp("punchout_tukey(" , specification, 15)) { + else if(n>16 && 0 == strncmp("punchout_tukey(", specification, 15)) { FLAC__int32 tukey_parts = (FLAC__int32)strtod(specification+15, 0); const char *si_1 = strchr(specification, '/'); FLAC__real overlap = si_1?flac_min((FLAC__real)strtod(si_1+1, 0),0.99f):0.2f; @@ -1784,6 +1807,20 @@ FLAC_API FLAC__bool FLAC__stream_encoder_set_apodization(FLAC__StreamEncoder *en } } } + else if(n>17 && 0 == strncmp("subdivide_tukey(", specification, 16)){ + FLAC__int32 parts = (FLAC__int32)strtod(specification+16, 0); + if(parts > 1){ + const char *si_1 = strchr(specification, '/'); + FLAC__real p = si_1?(FLAC__real)strtod(si_1+1, 0):5e-1; + if(p > 1) + p = 1; + else if(p < 0) + p = 0; + encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.subdivide_tukey.parts = parts; + encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.subdivide_tukey.p = p/parts; + encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_SUBDIVIDE_TUKEY; + } + } else if(n==5 && 0 == strncmp("welch" , specification, n)) encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_WELCH; if (encoder->protected_->num_apodizations == 32) @@ -1842,8 +1879,10 @@ FLAC_API FLAC__bool FLAC__stream_encoder_set_do_escape_coding(FLAC__StreamEncode FLAC__ASSERT(0 != encoder->protected_); if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) return false; -#if 0 - /*@@@ deprecated: */ +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + /* was deprecated since FLAC 1.0.4 (24-Sep-2002), but is needed for + * full spec coverage, so this should be reenabled at some point. + * For now only enable while fuzzing */ encoder->protected_->do_escape_coding = value; #else (void)value; @@ -1907,7 +1946,7 @@ FLAC_API FLAC__bool FLAC__stream_encoder_set_total_samples_estimate(FLAC__Stream FLAC__ASSERT(0 != encoder->protected_); if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) return false; - value = flac_min(value, (FLAC__uint64) ((FLAC__U64L(1) << FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN) - 1)); + value = flac_min(value, (FLAC__uint64)((FLAC__U64L(1) << FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN) - 1)); encoder->protected_->total_samples_estimate = value; return true; } @@ -1944,11 +1983,39 @@ FLAC_API FLAC__bool FLAC__stream_encoder_set_metadata(FLAC__StreamEncoder *encod return true; } +FLAC_API FLAC__bool FLAC__stream_encoder_set_limit_min_bitrate(FLAC__StreamEncoder *encoder, FLAC__bool value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) + return false; + encoder->protected_->limit_min_bitrate = value; + return true; +} + /* - * These three functions are not static, but not publicly exposed in - * include/FLAC/ either. They are used by the test suite. + * These four functions are not static, but not publicly exposed in + * include/FLAC/ either. They are used by the test suite and in fuzzing */ -inline FLAC_API FLAC__bool FLAC__stream_encoder_disable_constant_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value) +FLAC_API FLAC__bool FLAC__stream_encoder_disable_instruction_set(FLAC__StreamEncoder *encoder, FLAC__bool value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) + return false; + encoder->private_->disable_mmx = value & 1; + encoder->private_->disable_sse2 = value & 2; + encoder->private_->disable_ssse3 = value & 4; + encoder->private_->disable_sse41 = value & 8; + encoder->private_->disable_avx2 = value & 16; + encoder->private_->disable_fma = value & 32; + encoder->private_->disable_sse42 = value & 64; + return true; +} + +FLAC_API FLAC__bool FLAC__stream_encoder_disable_constant_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value) { FLAC__ASSERT(0 != encoder); FLAC__ASSERT(0 != encoder->private_); @@ -1959,7 +2026,7 @@ inline FLAC_API FLAC__bool FLAC__stream_encoder_disable_constant_subframes(FLAC_ return true; } -inline FLAC_API FLAC__bool FLAC__stream_encoder_disable_fixed_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value) +FLAC_API FLAC__bool FLAC__stream_encoder_disable_fixed_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value) { FLAC__ASSERT(0 != encoder); FLAC__ASSERT(0 != encoder->private_); @@ -1970,7 +2037,7 @@ inline FLAC_API FLAC__bool FLAC__stream_encoder_disable_fixed_subframes(FLAC__St return true; } -inline FLAC_API FLAC__bool FLAC__stream_encoder_disable_verbatim_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value) +FLAC_API FLAC__bool FLAC__stream_encoder_disable_verbatim_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value) { FLAC__ASSERT(0 != encoder); FLAC__ASSERT(0 != encoder->private_); @@ -2046,7 +2113,7 @@ FLAC_API FLAC__bool FLAC__stream_encoder_get_streamable_subset(const FLAC__Strea return encoder->protected_->streamable_subset; } -inline FLAC_API FLAC__bool FLAC__stream_encoder_get_do_md5(const FLAC__StreamEncoder *encoder) +FLAC_API FLAC__bool FLAC__stream_encoder_get_do_md5(const FLAC__StreamEncoder *encoder) { FLAC__ASSERT(0 != encoder); FLAC__ASSERT(0 != encoder->private_); @@ -2174,15 +2241,27 @@ FLAC_API FLAC__uint64 FLAC__stream_encoder_get_total_samples_estimate(const FLAC return encoder->protected_->total_samples_estimate; } +FLAC_API FLAC__bool FLAC__stream_encoder_get_limit_min_bitrate(const FLAC__StreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + return encoder->protected_->limit_min_bitrate; +} + FLAC_API FLAC__bool FLAC__stream_encoder_process(FLAC__StreamEncoder *encoder, const FLAC__int32 * const buffer[], uint32_t samples) { - uint32_t i, j = 0, channel; + uint32_t i, j = 0, k = 0, channel; const uint32_t channels = encoder->protected_->channels, blocksize = encoder->protected_->blocksize; + const FLAC__int32 sample_max = INT32_MAX >> (32 - encoder->protected_->bits_per_sample); + const FLAC__int32 sample_min = INT32_MIN >> (32 - encoder->protected_->bits_per_sample); FLAC__ASSERT(0 != encoder); FLAC__ASSERT(0 != encoder->private_); FLAC__ASSERT(0 != encoder->protected_); - FLAC__ASSERT(encoder->protected_->state == FLAC__STREAM_ENCODER_OK); + + if(encoder->protected_->state != FLAC__STREAM_ENCODER_OK) + return false; do { const uint32_t n = flac_min(blocksize+OVERREAD_-encoder->private_->current_sample_number, samples-j); @@ -2194,35 +2273,26 @@ FLAC_API FLAC__bool FLAC__stream_encoder_process(FLAC__StreamEncoder *encoder, c if (buffer[channel] == NULL) { return false; } - memcpy(&encoder->private_->integer_signal[channel][encoder->private_->current_sample_number], &buffer[channel][j], sizeof(buffer[channel][0]) * n); - } - - if(encoder->protected_->do_mid_side_stereo) { - FLAC__ASSERT(channels == 2); - /* "i <= blocksize" to overread 1 sample; see comment in OVERREAD_ decl */ - for(i = encoder->private_->current_sample_number; i <= blocksize && j < samples; i++, j++) { - encoder->private_->integer_signal_mid_side[1][i] = buffer[0][j] - buffer[1][j]; - encoder->private_->integer_signal_mid_side[0][i] = (buffer[0][j] + buffer[1][j]) >> 1; /* NOTE: not the same as 'mid = (buffer[0][j] + buffer[1][j]) / 2' ! */ + for(i = encoder->private_->current_sample_number, k = j; i <= blocksize && k < samples; i++, k++) { + if(buffer[channel][k] < sample_min || buffer[channel][k] > sample_max){ + encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; + return false; + } } + memcpy(&encoder->private_->integer_signal[channel][encoder->private_->current_sample_number], &buffer[channel][j], sizeof(buffer[channel][0]) * n); } - else - j += n; - + j += n; encoder->private_->current_sample_number += n; /* we only process if we have a full block + 1 extra sample; final block is always handled by FLAC__stream_encoder_finish() */ if(encoder->private_->current_sample_number > blocksize) { FLAC__ASSERT(encoder->private_->current_sample_number == blocksize+OVERREAD_); FLAC__ASSERT(OVERREAD_ == 1); /* assert we only overread 1 sample which simplifies the rest of the code below */ - if(!process_frame_(encoder, /*is_fractional_block=*/false, /*is_last_block=*/false)) + if(!process_frame_(encoder, /*is_last_block=*/false)) return false; /* move unprocessed overread samples to beginnings of arrays */ for(channel = 0; channel < channels; channel++) encoder->private_->integer_signal[channel][0] = encoder->private_->integer_signal[channel][blocksize]; - if(encoder->protected_->do_mid_side_stereo) { - encoder->private_->integer_signal_mid_side[0][0] = encoder->private_->integer_signal_mid_side[0][blocksize]; - encoder->private_->integer_signal_mid_side[1][0] = encoder->private_->integer_signal_mid_side[1][blocksize]; - } encoder->private_->current_sample_number = 1; } } while(j < samples); @@ -2233,81 +2303,45 @@ FLAC_API FLAC__bool FLAC__stream_encoder_process(FLAC__StreamEncoder *encoder, c FLAC_API FLAC__bool FLAC__stream_encoder_process_interleaved(FLAC__StreamEncoder *encoder, const FLAC__int32 buffer[], uint32_t samples) { uint32_t i, j, k, channel; - FLAC__int32 x, mid, side; const uint32_t channels = encoder->protected_->channels, blocksize = encoder->protected_->blocksize; + const FLAC__int32 sample_max = INT32_MAX >> (32 - encoder->protected_->bits_per_sample); + const FLAC__int32 sample_min = INT32_MIN >> (32 - encoder->protected_->bits_per_sample); FLAC__ASSERT(0 != encoder); FLAC__ASSERT(0 != encoder->private_); FLAC__ASSERT(0 != encoder->protected_); - FLAC__ASSERT(encoder->protected_->state == FLAC__STREAM_ENCODER_OK); - j = k = 0; - /* - * we have several flavors of the same basic loop, optimized for - * different conditions: - */ - if(encoder->protected_->do_mid_side_stereo && channels == 2) { - /* - * stereo coding: unroll channel loop - */ - do { - if(encoder->protected_->verify) - append_to_verify_fifo_interleaved_(&encoder->private_->verify.input_fifo, buffer, j, channels, flac_min(blocksize+OVERREAD_-encoder->private_->current_sample_number, samples-j)); + if(encoder->protected_->state != FLAC__STREAM_ENCODER_OK) + return false; - /* "i <= blocksize" to overread 1 sample; see comment in OVERREAD_ decl */ - for(i = encoder->private_->current_sample_number; i <= blocksize && j < samples; i++, j++) { - encoder->private_->integer_signal[0][i] = mid = side = buffer[k++]; - x = buffer[k++]; - encoder->private_->integer_signal[1][i] = x; - mid += x; - side -= x; - mid >>= 1; /* NOTE: not the same as 'mid = (left + right) / 2' ! */ - encoder->private_->integer_signal_mid_side[1][i] = side; - encoder->private_->integer_signal_mid_side[0][i] = mid; - } - encoder->private_->current_sample_number = i; - /* we only process if we have a full block + 1 extra sample; final block is always handled by FLAC__stream_encoder_finish() */ - if(i > blocksize) { - if(!process_frame_(encoder, /*is_fractional_block=*/false, /*is_last_block=*/false)) - return false; - /* move unprocessed overread samples to beginnings of arrays */ - FLAC__ASSERT(i == blocksize+OVERREAD_); - FLAC__ASSERT(OVERREAD_ == 1); /* assert we only overread 1 sample which simplifies the rest of the code below */ - encoder->private_->integer_signal[0][0] = encoder->private_->integer_signal[0][blocksize]; - encoder->private_->integer_signal[1][0] = encoder->private_->integer_signal[1][blocksize]; - encoder->private_->integer_signal_mid_side[0][0] = encoder->private_->integer_signal_mid_side[0][blocksize]; - encoder->private_->integer_signal_mid_side[1][0] = encoder->private_->integer_signal_mid_side[1][blocksize]; - encoder->private_->current_sample_number = 1; - } - } while(j < samples); - } - else { - /* - * independent channel coding: buffer each channel in inner loop - */ - do { - if(encoder->protected_->verify) - append_to_verify_fifo_interleaved_(&encoder->private_->verify.input_fifo, buffer, j, channels, flac_min(blocksize+OVERREAD_-encoder->private_->current_sample_number, samples-j)); + j = k = 0; + do { + if(encoder->protected_->verify) + append_to_verify_fifo_interleaved_(&encoder->private_->verify.input_fifo, buffer, j, channels, flac_min(blocksize+OVERREAD_-encoder->private_->current_sample_number, samples-j)); /* "i <= blocksize" to overread 1 sample; see comment in OVERREAD_ decl */ - for(i = encoder->private_->current_sample_number; i <= blocksize && j < samples; i++, j++) { - for(channel = 0; channel < channels; channel++) - encoder->private_->integer_signal[channel][i] = buffer[k++]; - } - encoder->private_->current_sample_number = i; - /* we only process if we have a full block + 1 extra sample; final block is always handled by FLAC__stream_encoder_finish() */ - if(i > blocksize) { - if(!process_frame_(encoder, /*is_fractional_block=*/false, /*is_last_block=*/false)) + for(i = encoder->private_->current_sample_number; i <= blocksize && j < samples; i++, j++) { + for(channel = 0; channel < channels; channel++){ + if(buffer[k] < sample_min || buffer[k] > sample_max){ + encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR; return false; - /* move unprocessed overread samples to beginnings of arrays */ - FLAC__ASSERT(i == blocksize+OVERREAD_); - FLAC__ASSERT(OVERREAD_ == 1); /* assert we only overread 1 sample which simplifies the rest of the code below */ - for(channel = 0; channel < channels; channel++) - encoder->private_->integer_signal[channel][0] = encoder->private_->integer_signal[channel][blocksize]; - encoder->private_->current_sample_number = 1; + } + encoder->private_->integer_signal[channel][i] = buffer[k++]; } - } while(j < samples); - } + } + encoder->private_->current_sample_number = i; + /* we only process if we have a full block + 1 extra sample; final block is always handled by FLAC__stream_encoder_finish() */ + if(i > blocksize) { + if(!process_frame_(encoder, /*is_last_block=*/false)) + return false; + /* move unprocessed overread samples to beginnings of arrays */ + FLAC__ASSERT(i == blocksize+OVERREAD_); + FLAC__ASSERT(OVERREAD_ == 1); /* assert we only overread 1 sample which simplifies the rest of the code below */ + for(channel = 0; channel < channels; channel++) + encoder->private_->integer_signal[channel][0] = encoder->private_->integer_signal[channel][blocksize]; + encoder->private_->current_sample_number = 1; + } + } while(j < samples); return true; } @@ -2349,10 +2383,17 @@ void set_defaults_(FLAC__StreamEncoder *encoder) encoder->protected_->max_residual_partition_order = 0; encoder->protected_->rice_parameter_search_dist = 0; encoder->protected_->total_samples_estimate = 0; + encoder->protected_->limit_min_bitrate = false; encoder->protected_->metadata = 0; encoder->protected_->num_metadata_blocks = 0; encoder->private_->seek_table = 0; + encoder->private_->disable_mmx = false; + encoder->private_->disable_sse2 = false; + encoder->private_->disable_ssse3 = false; + encoder->private_->disable_sse41 = false; + encoder->private_->disable_sse42 = false; + encoder->private_->disable_avx2 = false; encoder->private_->disable_constant_subframes = false; encoder->private_->disable_fixed_subframes = false; encoder->private_->disable_verbatim_subframes = false; @@ -2406,6 +2447,10 @@ void free_(FLAC__StreamEncoder *encoder) } #endif } + if(0 != encoder->private_->integer_signal_33bit_side_unaligned){ + free(encoder->private_->integer_signal_33bit_side_unaligned); + encoder->private_->integer_signal_33bit_side_unaligned = 0; + } #ifndef FLAC__INTEGER_ONLY_LIBRARY for(i = 0; i < encoder->protected_->num_apodizations; i++) { if(0 != encoder->private_->window_unaligned[i]) { @@ -2460,69 +2505,89 @@ FLAC__bool resize_buffers_(FLAC__StreamEncoder *encoder, uint32_t new_blocksize) FLAC__ASSERT(new_blocksize > 0); FLAC__ASSERT(encoder->protected_->state == FLAC__STREAM_ENCODER_OK); - FLAC__ASSERT(encoder->private_->current_sample_number == 0); - - /* To avoid excessive malloc'ing, we only grow the buffer; no shrinking. */ - if(new_blocksize <= encoder->private_->input_capacity) - return true; ok = true; - /* WATCHOUT: FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx() and ..._intrin_sse2() - * require that the input arrays (in our case the integer signals) - * have a buffer of up to 3 zeroes in front (at negative indices) for - * alignment purposes; we use 4 in front to keep the data well-aligned. - */ + /* To avoid excessive malloc'ing, we only grow the buffer; no shrinking. */ + if(new_blocksize > encoder->private_->input_capacity) { - for(i = 0; ok && i < encoder->protected_->channels; i++) { - ok = ok && FLAC__memory_alloc_aligned_int32_array(new_blocksize+4+OVERREAD_, &encoder->private_->integer_signal_unaligned[i], &encoder->private_->integer_signal[i]); - memset(encoder->private_->integer_signal[i], 0, sizeof(FLAC__int32)*4); - encoder->private_->integer_signal[i] += 4; -#ifndef FLAC__INTEGER_ONLY_LIBRARY -#if 0 /* @@@ currently unused */ - if(encoder->protected_->max_lpc_order > 0) - ok = ok && FLAC__memory_alloc_aligned_real_array(new_blocksize+OVERREAD_, &encoder->private_->real_signal_unaligned[i], &encoder->private_->real_signal[i]); -#endif -#endif - } - for(i = 0; ok && i < 2; i++) { - ok = ok && FLAC__memory_alloc_aligned_int32_array(new_blocksize+4+OVERREAD_, &encoder->private_->integer_signal_mid_side_unaligned[i], &encoder->private_->integer_signal_mid_side[i]); - memset(encoder->private_->integer_signal_mid_side[i], 0, sizeof(FLAC__int32)*4); - encoder->private_->integer_signal_mid_side[i] += 4; -#ifndef FLAC__INTEGER_ONLY_LIBRARY -#if 0 /* @@@ currently unused */ - if(encoder->protected_->max_lpc_order > 0) - ok = ok && FLAC__memory_alloc_aligned_real_array(new_blocksize+OVERREAD_, &encoder->private_->real_signal_mid_side_unaligned[i], &encoder->private_->real_signal_mid_side[i]); -#endif -#endif - } + /* WATCHOUT: FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx() and ..._intrin_sse2() + * require that the input arrays (in our case the integer signals) + * have a buffer of up to 3 zeroes in front (at negative indices) for + * alignment purposes; we use 4 in front to keep the data well-aligned. + */ + + for(i = 0; ok && i < encoder->protected_->channels; i++) { + ok = ok && FLAC__memory_alloc_aligned_int32_array(new_blocksize+4+OVERREAD_, &encoder->private_->integer_signal_unaligned[i], &encoder->private_->integer_signal[i]); + if(ok) { + memset(encoder->private_->integer_signal[i], 0, sizeof(FLAC__int32)*4); + encoder->private_->integer_signal[i] += 4; + } + } + for(i = 0; ok && i < 2; i++) { + ok = ok && FLAC__memory_alloc_aligned_int32_array(new_blocksize+4+OVERREAD_, &encoder->private_->integer_signal_mid_side_unaligned[i], &encoder->private_->integer_signal_mid_side[i]); + if(ok) { + memset(encoder->private_->integer_signal_mid_side[i], 0, sizeof(FLAC__int32)*4); + encoder->private_->integer_signal_mid_side[i] += 4; + } + } + ok = ok && FLAC__memory_alloc_aligned_int64_array(new_blocksize+4+OVERREAD_, &encoder->private_->integer_signal_33bit_side_unaligned, &encoder->private_->integer_signal_33bit_side); #ifndef FLAC__INTEGER_ONLY_LIBRARY - if(ok && encoder->protected_->max_lpc_order > 0) { - for(i = 0; ok && i < encoder->protected_->num_apodizations; i++) - ok = ok && FLAC__memory_alloc_aligned_real_array(new_blocksize, &encoder->private_->window_unaligned[i], &encoder->private_->window[i]); - ok = ok && FLAC__memory_alloc_aligned_real_array(new_blocksize, &encoder->private_->windowed_signal_unaligned, &encoder->private_->windowed_signal); - } + if(ok && encoder->protected_->max_lpc_order > 0) { + for(i = 0; ok && i < encoder->protected_->num_apodizations; i++) + ok = ok && FLAC__memory_alloc_aligned_real_array(new_blocksize, &encoder->private_->window_unaligned[i], &encoder->private_->window[i]); + ok = ok && FLAC__memory_alloc_aligned_real_array(new_blocksize, &encoder->private_->windowed_signal_unaligned, &encoder->private_->windowed_signal); + } #endif - for(channel = 0; ok && channel < encoder->protected_->channels; channel++) { - for(i = 0; ok && i < 2; i++) { - ok = ok && FLAC__memory_alloc_aligned_int32_array(new_blocksize, &encoder->private_->residual_workspace_unaligned[channel][i], &encoder->private_->residual_workspace[channel][i]); + for(channel = 0; ok && channel < encoder->protected_->channels; channel++) { + for(i = 0; ok && i < 2; i++) { + ok = ok && FLAC__memory_alloc_aligned_int32_array(new_blocksize, &encoder->private_->residual_workspace_unaligned[channel][i], &encoder->private_->residual_workspace[channel][i]); + } } - } - for(channel = 0; ok && channel < 2; channel++) { + + + for(channel = 0; ok && channel < encoder->protected_->channels; channel++) { + for(i = 0; ok && i < 2; i++) { + ok = ok && FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(&encoder->private_->partitioned_rice_contents_workspace[channel][i], encoder->protected_->max_residual_partition_order); + ok = ok && FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(&encoder->private_->partitioned_rice_contents_workspace[channel][i], encoder->protected_->max_residual_partition_order); + } + } + + for(channel = 0; ok && channel < 2; channel++) { + for(i = 0; ok && i < 2; i++) { + ok = ok && FLAC__memory_alloc_aligned_int32_array(new_blocksize, &encoder->private_->residual_workspace_mid_side_unaligned[channel][i], &encoder->private_->residual_workspace_mid_side[channel][i]); + } + } + + for(channel = 0; ok && channel < 2; channel++) { + for(i = 0; ok && i < 2; i++) { + ok = ok && FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(&encoder->private_->partitioned_rice_contents_workspace_mid_side[channel][i], encoder->protected_->max_residual_partition_order); + } + } + for(i = 0; ok && i < 2; i++) { - ok = ok && FLAC__memory_alloc_aligned_int32_array(new_blocksize, &encoder->private_->residual_workspace_mid_side_unaligned[channel][i], &encoder->private_->residual_workspace_mid_side[channel][i]); + ok = ok && FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(&encoder->private_->partitioned_rice_contents_extra[i], encoder->protected_->max_residual_partition_order); } + + + /* the *2 is an approximation to the series 1 + 1/2 + 1/4 + ... that sums tree occupies in a flat array */ + /*@@@ new_blocksize*2 is too pessimistic, but to fix, we need smarter logic because a smaller new_blocksize can actually increase the # of partitions; would require moving this out into a separate function, then checking its capacity against the need of the current blocksize&min/max_partition_order (and maybe predictor order) */ + ok = ok && FLAC__memory_alloc_aligned_uint64_array(new_blocksize * 2, &encoder->private_->abs_residual_partition_sums_unaligned, &encoder->private_->abs_residual_partition_sums); + if(encoder->protected_->do_escape_coding) + ok = ok && FLAC__memory_alloc_aligned_uint32_array(new_blocksize * 2, &encoder->private_->raw_bits_per_partition_unaligned, &encoder->private_->raw_bits_per_partition); +} + if(ok) + encoder->private_->input_capacity = new_blocksize; + else { + encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; + return ok; } - /* the *2 is an approximation to the series 1 + 1/2 + 1/4 + ... that sums tree occupies in a flat array */ - /*@@@ new_blocksize*2 is too pessimistic, but to fix, we need smarter logic because a smaller new_blocksize can actually increase the # of partitions; would require moving this out into a separate function, then checking its capacity against the need of the current blocksize&min/max_partition_order (and maybe predictor order) */ - ok = ok && FLAC__memory_alloc_aligned_uint64_array(new_blocksize * 2, &encoder->private_->abs_residual_partition_sums_unaligned, &encoder->private_->abs_residual_partition_sums); - if(encoder->protected_->do_escape_coding) - ok = ok && FLAC__memory_alloc_aligned_unsigned_array(new_blocksize * 2, &encoder->private_->raw_bits_per_partition_unaligned, &encoder->private_->raw_bits_per_partition); + /* now adjust the windows if the blocksize has changed */ #ifndef FLAC__INTEGER_ONLY_LIBRARY - if(ok && new_blocksize != encoder->private_->input_capacity && encoder->protected_->max_lpc_order > 0) { - for(i = 0; ok && i < encoder->protected_->num_apodizations; i++) { + if(encoder->protected_->max_lpc_order > 0 && new_blocksize > 1) { + for(i = 0; i < encoder->protected_->num_apodizations; i++) { switch(encoder->protected_->apodizations[i].type) { case FLAC__APODIZATION_BARTLETT: FLAC__window_bartlett(encoder->private_->window[i], new_blocksize); @@ -2572,6 +2637,9 @@ FLAC__bool resize_buffers_(FLAC__StreamEncoder *encoder, uint32_t new_blocksize) case FLAC__APODIZATION_PUNCHOUT_TUKEY: FLAC__window_punchout_tukey(encoder->private_->window[i], new_blocksize, encoder->protected_->apodizations[i].parameters.multiple_tukey.p, encoder->protected_->apodizations[i].parameters.multiple_tukey.start, encoder->protected_->apodizations[i].parameters.multiple_tukey.end); break; + case FLAC__APODIZATION_SUBDIVIDE_TUKEY: + FLAC__window_tukey(encoder->private_->window[i], new_blocksize, encoder->protected_->apodizations[i].parameters.tukey.p); + break; case FLAC__APODIZATION_WELCH: FLAC__window_welch(encoder->private_->window[i], new_blocksize); break; @@ -2583,14 +2651,14 @@ FLAC__bool resize_buffers_(FLAC__StreamEncoder *encoder, uint32_t new_blocksize) } } } + if (new_blocksize <= FLAC__MAX_LPC_ORDER) { + /* intrinsics autocorrelation routines do not all handle cases in which lag might be + * larger than data_len. Lag is one larger than the LPC order */ + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation; + } #endif - if(ok) - encoder->private_->input_capacity = new_blocksize; - else - encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR; - - return ok; + return true; } FLAC__bool write_bitbuffer_(FLAC__StreamEncoder *encoder, uint32_t samples, FLAC__bool is_last_block) @@ -2614,7 +2682,8 @@ FLAC__bool write_bitbuffer_(FLAC__StreamEncoder *encoder, uint32_t samples, FLAC else { if(!FLAC__stream_decoder_process_single(encoder->private_->verify.decoder) || (!is_last_block - && (FLAC__stream_encoder_get_verify_decoder_state(encoder) == FLAC__STREAM_DECODER_END_OF_STREAM))) { + && (FLAC__stream_encoder_get_verify_decoder_state(encoder) == FLAC__STREAM_DECODER_END_OF_STREAM)) + || encoder->protected_->state == FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR /* Happens when error callback was used */) { FLAC__bitwriter_release_buffer(encoder->private_->frame); FLAC__bitwriter_clear(encoder->private_->frame); if(encoder->protected_->state != FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA) @@ -2740,7 +2809,7 @@ void update_metadata_(const FLAC__StreamEncoder *encoder) { FLAC__byte b[flac_max(6u, FLAC__STREAM_METADATA_SEEKPOINT_LENGTH)]; const FLAC__StreamMetadata *metadata = &encoder->private_->streaminfo; - const FLAC__uint64 samples = metadata->data.stream_info.total_samples; + FLAC__uint64 samples = metadata->data.stream_info.total_samples; const uint32_t min_framesize = metadata->data.stream_info.min_framesize; const uint32_t max_framesize = metadata->data.stream_info.max_framesize; const uint32_t bps = metadata->data.stream_info.bits_per_sample; @@ -2797,6 +2866,8 @@ void update_metadata_(const FLAC__StreamEncoder *encoder) FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN - 4 ) / 8; + if(samples > (FLAC__U64L(1) << FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN)) + samples = 0; b[0] = ((FLAC__byte)(bps-1) << 4) | (FLAC__byte)((samples >> 32) & 0x0F); b[1] = (FLAC__byte)((samples >> 24) & 0xFF); @@ -3021,67 +3092,10 @@ void update_ogg_metadata_(FLAC__StreamEncoder *encoder) return; /* state already set */ } simple_ogg_page__clear(&page); - - /* - * Write seektable - */ - if(0 != encoder->private_->seek_table && encoder->private_->seek_table->num_points > 0 && encoder->protected_->seektable_offset > 0) { - uint32_t i; - FLAC__byte *p; - - FLAC__format_seektable_sort(encoder->private_->seek_table); - - FLAC__ASSERT(FLAC__format_seektable_is_legal(encoder->private_->seek_table)); - - simple_ogg_page__init(&page); - if(!simple_ogg_page__get_at(encoder, encoder->protected_->seektable_offset, &page, encoder->private_->seek_callback, encoder->private_->read_callback, encoder->private_->client_data)) { - simple_ogg_page__clear(&page); - return; /* state already set */ - } - - if((FLAC__STREAM_METADATA_HEADER_LENGTH + 18*encoder->private_->seek_table->num_points) != (uint32_t)page.body_len) { - encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR; - simple_ogg_page__clear(&page); - return; - } - - for(i = 0, p = page.body + FLAC__STREAM_METADATA_HEADER_LENGTH; i < encoder->private_->seek_table->num_points; i++, p += 18) { - FLAC__uint64 xx; - uint32_t x; - xx = encoder->private_->seek_table->points[i].sample_number; - b[7] = (FLAC__byte)xx; xx >>= 8; - b[6] = (FLAC__byte)xx; xx >>= 8; - b[5] = (FLAC__byte)xx; xx >>= 8; - b[4] = (FLAC__byte)xx; xx >>= 8; - b[3] = (FLAC__byte)xx; xx >>= 8; - b[2] = (FLAC__byte)xx; xx >>= 8; - b[1] = (FLAC__byte)xx; xx >>= 8; - b[0] = (FLAC__byte)xx; xx >>= 8; - xx = encoder->private_->seek_table->points[i].stream_offset; - b[15] = (FLAC__byte)xx; xx >>= 8; - b[14] = (FLAC__byte)xx; xx >>= 8; - b[13] = (FLAC__byte)xx; xx >>= 8; - b[12] = (FLAC__byte)xx; xx >>= 8; - b[11] = (FLAC__byte)xx; xx >>= 8; - b[10] = (FLAC__byte)xx; xx >>= 8; - b[9] = (FLAC__byte)xx; xx >>= 8; - b[8] = (FLAC__byte)xx; xx >>= 8; - x = encoder->private_->seek_table->points[i].frame_samples; - b[17] = (FLAC__byte)x; x >>= 8; - b[16] = (FLAC__byte)x; x >>= 8; - memcpy(p, b, 18); - } - - if(!simple_ogg_page__set_at(encoder, encoder->protected_->seektable_offset, &page, encoder->private_->seek_callback, encoder->private_->write_callback, encoder->private_->client_data)) { - simple_ogg_page__clear(&page); - return; /* state already set */ - } - simple_ogg_page__clear(&page); - } } #endif -FLAC__bool process_frame_(FLAC__StreamEncoder *encoder, FLAC__bool is_fractional_block, FLAC__bool is_last_block) +FLAC__bool process_frame_(FLAC__StreamEncoder *encoder, FLAC__bool is_last_block) { FLAC__uint16 crc; FLAC__ASSERT(encoder->protected_->state == FLAC__STREAM_ENCODER_OK); @@ -3097,7 +3111,7 @@ FLAC__bool process_frame_(FLAC__StreamEncoder *encoder, FLAC__bool is_fractional /* * Process the frame header and subframes into the frame bitbuffer */ - if(!process_subframes_(encoder, is_fractional_block)) { + if(!process_subframes_(encoder)) { /* the above function sets the state for us in case of an error */ return false; } @@ -3140,22 +3154,18 @@ FLAC__bool process_frame_(FLAC__StreamEncoder *encoder, FLAC__bool is_fractional return true; } -FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__bool is_fractional_block) +FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder) { FLAC__FrameHeader frame_header; uint32_t channel, min_partition_order = encoder->protected_->min_residual_partition_order, max_partition_order; - FLAC__bool do_independent, do_mid_side; + FLAC__bool do_independent, do_mid_side, backup_disable_constant_subframes = encoder->private_->disable_constant_subframes, all_subframes_constant = true; /* * Calculate the min,max Rice partition orders */ - if(is_fractional_block) { - max_partition_order = 0; - } - else { - max_partition_order = FLAC__format_get_max_rice_partition_order_from_blocksize(encoder->protected_->blocksize); - max_partition_order = flac_min(max_partition_order, encoder->protected_->max_residual_partition_order); - } + + max_partition_order = FLAC__format_get_max_rice_partition_order_from_blocksize(encoder->protected_->blocksize); + max_partition_order = flac_min(max_partition_order, encoder->protected_->max_residual_partition_order); min_partition_order = flac_min(min_partition_order, max_partition_order); /* @@ -3195,6 +3205,25 @@ FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__bool is_fracti FLAC__ASSERT(do_independent || do_mid_side); + /* + * Prepare mid-side signals if applicable + */ + if(do_mid_side) { + uint32_t i; + FLAC__ASSERT(encoder->protected_->channels == 2); + if(encoder->protected_->bits_per_sample < 32) + for(i = 0; i < encoder->protected_->blocksize; i++) { + encoder->private_->integer_signal_mid_side[1][i] = encoder->private_->integer_signal[0][i] - encoder->private_->integer_signal[1][i]; + encoder->private_->integer_signal_mid_side[0][i] = (encoder->private_->integer_signal[0][i] + encoder->private_->integer_signal[1][i]) >> 1; /* NOTE: not the same as 'mid = (signal[0][j] + signal[1][j]) / 2' ! */ + } + else + for(i = 0; i <= encoder->protected_->blocksize; i++) { + encoder->private_->integer_signal_33bit_side[i] = (FLAC__int64)encoder->private_->integer_signal[0][i] - (FLAC__int64)encoder->private_->integer_signal[1][i]; + encoder->private_->integer_signal_mid_side[0][i] = ((FLAC__int64)encoder->private_->integer_signal[0][i] + (FLAC__int64)encoder->private_->integer_signal[1][i]) >> 1; /* NOTE: not the same as 'mid = (signal[0][j] + signal[1][j]) / 2' ! */ + } + } + + /* * Check for wasted bits; set effective bps for each subframe */ @@ -3211,7 +3240,12 @@ FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__bool is_fracti if(do_mid_side) { FLAC__ASSERT(encoder->protected_->channels == 2); for(channel = 0; channel < 2; channel++) { - uint32_t w = get_wasted_bits_(encoder->private_->integer_signal_mid_side[channel], encoder->protected_->blocksize); + uint32_t w; + if(encoder->protected_->bits_per_sample < 32 || channel == 0) + w = get_wasted_bits_(encoder->private_->integer_signal_mid_side[channel], encoder->protected_->blocksize); + else + w = get_wasted_bits_wide_(encoder->private_->integer_signal_33bit_side, encoder->private_->integer_signal_mid_side[channel], encoder->protected_->blocksize); + if (w > encoder->protected_->bits_per_sample) { w = encoder->protected_->bits_per_sample; } @@ -3225,6 +3259,12 @@ FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__bool is_fracti */ if(do_independent) { for(channel = 0; channel < encoder->protected_->channels; channel++) { + if(encoder->protected_->limit_min_bitrate && all_subframes_constant && (channel + 1) == encoder->protected_->channels){ + /* This frame contains only constant subframes at this point. + * To prevent the frame from becoming too small, make sure + * the last subframe isn't constant */ + encoder->private_->disable_constant_subframes = true; + } if(! process_subframe_( encoder, @@ -3241,6 +3281,8 @@ FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__bool is_fracti ) ) return false; + if(encoder->private_->subframe_workspace[channel][encoder->private_->best_subframe[channel]].type != FLAC__SUBFRAME_TYPE_CONSTANT) + all_subframes_constant = false; } } @@ -3251,6 +3293,11 @@ FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__bool is_fracti FLAC__ASSERT(encoder->protected_->channels == 2); for(channel = 0; channel < 2; channel++) { + void *integer_signal_; + if(encoder->private_->subframe_bps_mid_side[channel] <= 32) + integer_signal_ = encoder->private_->integer_signal_mid_side[channel]; + else + integer_signal_ = encoder->private_->integer_signal_33bit_side; if(! process_subframe_( encoder, @@ -3258,7 +3305,7 @@ FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__bool is_fracti max_partition_order, &frame_header, encoder->private_->subframe_bps_mid_side[channel], - encoder->private_->integer_signal_mid_side[channel], + integer_signal_, encoder->private_->subframe_workspace_ptr_mid_side[channel], encoder->private_->partitioned_rice_contents_workspace_ptr_mid_side[channel], encoder->private_->residual_workspace_mid_side[channel], @@ -3302,7 +3349,11 @@ FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__bool is_fracti channel_assignment = FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT; min_bits = bits[channel_assignment]; - for(ca = 1; ca <= 3; ca++) { + + /* When doing loose mid-side stereo, ignore left-side + * and right-side options */ + ca = encoder->protected_->loose_mid_side_stereo ? 3 : 1; + for( ; ca <= 3; ca++) { if(bits[ca] < min_bits) { min_bits = bits[ca]; channel_assignment = (FLAC__ChannelAssignment)ca; @@ -3386,6 +3437,7 @@ FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__bool is_fracti } encoder->private_->last_channel_assignment = frame_header.channel_assignment; + encoder->private_->disable_constant_subframes = backup_disable_constant_subframes; return true; } @@ -3396,7 +3448,7 @@ FLAC__bool process_subframe_( uint32_t max_partition_order, const FLAC__FrameHeader *frame_header, uint32_t subframe_bps, - const FLAC__int32 integer_signal[], + const void *integer_signal, FLAC__Subframe *subframe[2], FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents[2], FLAC__int32 *residual[2], @@ -3411,13 +3463,12 @@ FLAC__bool process_subframe_( #endif #ifndef FLAC__INTEGER_ONLY_LIBRARY double lpc_residual_bits_per_sample; - FLAC__real autoc[FLAC__MAX_LPC_ORDER+1]; /* WATCHOUT: the size is important even though encoder->protected_->max_lpc_order might be less; some asm and x86 intrinsic routines need all the space */ + apply_apodization_state_struct apply_apodization_state; double lpc_error[FLAC__MAX_LPC_ORDER]; - uint32_t min_lpc_order, max_lpc_order, lpc_order; + uint32_t min_lpc_order, max_lpc_order, lpc_order, guess_lpc_order; uint32_t min_qlp_coeff_precision, max_qlp_coeff_precision, qlp_coeff_precision; #endif uint32_t min_fixed_order, max_fixed_order, guess_fixed_order, fixed_order; - uint32_t rice_parameter; uint32_t _candidate_bits, _best_bits; uint32_t _best_subframe; /* only use RICE2 partitions if stream bps > 16 */ @@ -3428,16 +3479,33 @@ FLAC__bool process_subframe_( /* verbatim subframe is the baseline against which we measure other compressed subframes */ _best_subframe = 0; if(encoder->private_->disable_verbatim_subframes && frame_header->blocksize >= FLAC__MAX_FIXED_ORDER) - _best_bits = UINT_MAX; + _best_bits = UINT32_MAX; else _best_bits = evaluate_verbatim_subframe_(encoder, integer_signal, frame_header->blocksize, subframe_bps, subframe[_best_subframe]); + *best_bits = _best_bits; - if(frame_header->blocksize >= FLAC__MAX_FIXED_ORDER) { + if(frame_header->blocksize > FLAC__MAX_FIXED_ORDER) { uint32_t signal_is_constant = false; - if(subframe_bps + 4 + FLAC__bitmath_ilog2((frame_header->blocksize-FLAC__MAX_FIXED_ORDER)|1) <= 32) - guess_fixed_order = encoder->private_->local_fixed_compute_best_predictor(integer_signal+FLAC__MAX_FIXED_ORDER, frame_header->blocksize-FLAC__MAX_FIXED_ORDER, fixed_residual_bits_per_sample); + /* The next formula determines when to use a 64-bit accumulator + * for the error of a fixed predictor, and when a 32-bit one. As + * the error of a 4th order predictor for a given sample is the + * sum of 17 sample values (1+4+6+4+1) and there are blocksize - + * order error values to be summed, the maximum total error is + * maximum_sample_value * (blocksize - order) * 17. As ilog2(x) + * calculates floor(2log(x)), the result must be 31 or lower + */ + if(subframe_bps < 28){ + if(subframe_bps + FLAC__bitmath_ilog2((frame_header->blocksize-FLAC__MAX_FIXED_ORDER)*17) < 32) + guess_fixed_order = encoder->private_->local_fixed_compute_best_predictor(((FLAC__int32 *)integer_signal)+FLAC__MAX_FIXED_ORDER, frame_header->blocksize-FLAC__MAX_FIXED_ORDER, fixed_residual_bits_per_sample); + else + guess_fixed_order = encoder->private_->local_fixed_compute_best_predictor_wide(((FLAC__int32 *)integer_signal)+FLAC__MAX_FIXED_ORDER, frame_header->blocksize-FLAC__MAX_FIXED_ORDER, fixed_residual_bits_per_sample); + } else - guess_fixed_order = encoder->private_->local_fixed_compute_best_predictor_wide(integer_signal+FLAC__MAX_FIXED_ORDER, frame_header->blocksize-FLAC__MAX_FIXED_ORDER, fixed_residual_bits_per_sample); + if(subframe_bps <= 32) + guess_fixed_order = encoder->private_->local_fixed_compute_best_predictor_limit_residual(((FLAC__int32 *)integer_signal+FLAC__MAX_FIXED_ORDER),frame_header->blocksize-FLAC__MAX_FIXED_ORDER, fixed_residual_bits_per_sample); + else + guess_fixed_order = FLAC__fixed_compute_best_predictor_limit_residual_33bit(((FLAC__int64 *)integer_signal+FLAC__MAX_FIXED_ORDER),frame_header->blocksize-FLAC__MAX_FIXED_ORDER, fixed_residual_bits_per_sample); + /* check for constant subframe */ if( !encoder->private_->disable_constant_subframes && @@ -3450,15 +3518,31 @@ FLAC__bool process_subframe_( /* the above means it's possible all samples are the same value; now double-check it: */ uint32_t i; signal_is_constant = true; - for(i = 1; i < frame_header->blocksize; i++) { - if(integer_signal[0] != integer_signal[i]) { - signal_is_constant = false; - break; + if(subframe_bps <= 32){ + const FLAC__int32 *integer_signal_ = (FLAC__int32*) integer_signal; + for(i = 1; i < frame_header->blocksize; i++) { + if(integer_signal_[0] != integer_signal_[i]) { + signal_is_constant = false; + break; + } + } + } + else { + const FLAC__int64 *integer_signal_ = (FLAC__int64*) integer_signal; + for(i = 1; i < frame_header->blocksize; i++) { + if(integer_signal_[0] != integer_signal_[i]) { + signal_is_constant = false; + break; + } } } } if(signal_is_constant) { - _candidate_bits = evaluate_constant_subframe_(encoder, integer_signal[0], frame_header->blocksize, subframe_bps, subframe[!_best_subframe]); + if(subframe_bps <= 32) + _candidate_bits = evaluate_constant_subframe_(encoder, ((FLAC__int32 *)integer_signal)[0], frame_header->blocksize, subframe_bps, subframe[!_best_subframe]); + else + _candidate_bits = evaluate_constant_subframe_(encoder, ((FLAC__int64 *)integer_signal)[0], frame_header->blocksize, subframe_bps, subframe[!_best_subframe]); + if(_candidate_bits < _best_bits) { _best_subframe = !_best_subframe; _best_bits = _candidate_bits; @@ -3480,19 +3564,10 @@ FLAC__bool process_subframe_( #ifndef FLAC__INTEGER_ONLY_LIBRARY if(fixed_residual_bits_per_sample[fixed_order] >= (float)subframe_bps) continue; /* don't even try */ - rice_parameter = (fixed_residual_bits_per_sample[fixed_order] > 0.0)? (uint32_t)(fixed_residual_bits_per_sample[fixed_order]+0.5) : 0; /* 0.5 is for rounding */ #else if(FLAC__fixedpoint_trunc(fixed_residual_bits_per_sample[fixed_order]) >= (int)subframe_bps) continue; /* don't even try */ - rice_parameter = (fixed_residual_bits_per_sample[fixed_order] > FLAC__FP_ZERO)? (uint32_t)FLAC__fixedpoint_trunc(fixed_residual_bits_per_sample[fixed_order]+FLAC__FP_ONE_HALF) : 0; /* 0.5 is for rounding */ -#endif - rice_parameter++; /* to account for the signed->uint32_t conversion during rice coding */ - if(rice_parameter >= rice_parameter_limit) { -#ifndef NDEBUG - fprintf(stderr, "clipping rice_parameter (%u -> %u) @0\n", rice_parameter, rice_parameter_limit - 1); #endif - rice_parameter = rice_parameter_limit - 1; - } _candidate_bits = evaluate_fixed_subframe_( encoder, @@ -3503,7 +3578,6 @@ FLAC__bool process_subframe_( frame_header->blocksize, subframe_bps, fixed_order, - rice_parameter, rice_parameter_limit, min_partition_order, max_partition_order, @@ -3527,84 +3601,68 @@ FLAC__bool process_subframe_( else max_lpc_order = encoder->protected_->max_lpc_order; if(max_lpc_order > 0) { - uint32_t a; - for (a = 0; a < encoder->protected_->num_apodizations; a++) { - FLAC__lpc_window_data(integer_signal, encoder->private_->window[a], encoder->private_->windowed_signal, frame_header->blocksize); - encoder->private_->local_lpc_compute_autocorrelation(encoder->private_->windowed_signal, frame_header->blocksize, max_lpc_order+1, autoc); - /* if autoc[0] == 0.0, the signal is constant and we usually won't get here, but it can happen */ - if(autoc[0] != 0.0) { - FLAC__lpc_compute_lp_coefficients(autoc, &max_lpc_order, encoder->private_->lp_coeff, lpc_error); - if(encoder->protected_->do_exhaustive_model_search) { - min_lpc_order = 1; + apply_apodization_state.a = 0; + apply_apodization_state.b = 1; + apply_apodization_state.c = 0; + while (apply_apodization_state.a < encoder->protected_->num_apodizations) { + uint32_t max_lpc_order_this_apodization = max_lpc_order; + + if(!apply_apodization_(encoder, &apply_apodization_state, + frame_header->blocksize, lpc_error, + &max_lpc_order_this_apodization, + subframe_bps, integer_signal, + &guess_lpc_order)) + /* If apply_apodization_ fails, try next apodization */ + continue; + + if(encoder->protected_->do_exhaustive_model_search) { + min_lpc_order = 1; + } + else { + min_lpc_order = max_lpc_order_this_apodization = guess_lpc_order; + } + for(lpc_order = min_lpc_order; lpc_order <= max_lpc_order_this_apodization; lpc_order++) { + lpc_residual_bits_per_sample = FLAC__lpc_compute_expected_bits_per_residual_sample(lpc_error[lpc_order-1], frame_header->blocksize-lpc_order); + if(lpc_residual_bits_per_sample >= (double)subframe_bps) + continue; /* don't even try */ + if(encoder->protected_->do_qlp_coeff_prec_search) { + min_qlp_coeff_precision = FLAC__MIN_QLP_COEFF_PRECISION; + /* try to keep qlp coeff precision such that only 32-bit math is required for decode of <=16bps(+1bps for side channel) streams */ + if(subframe_bps <= 17) { + max_qlp_coeff_precision = flac_min(32 - subframe_bps - FLAC__bitmath_ilog2(lpc_order), FLAC__MAX_QLP_COEFF_PRECISION); + max_qlp_coeff_precision = flac_max(max_qlp_coeff_precision, min_qlp_coeff_precision); + } + else + max_qlp_coeff_precision = FLAC__MAX_QLP_COEFF_PRECISION; } else { - const uint32_t guess_lpc_order = - FLAC__lpc_compute_best_order( - lpc_error, - max_lpc_order, + min_qlp_coeff_precision = max_qlp_coeff_precision = encoder->protected_->qlp_coeff_precision; + } + for(qlp_coeff_precision = min_qlp_coeff_precision; qlp_coeff_precision <= max_qlp_coeff_precision; qlp_coeff_precision++) { + _candidate_bits = + evaluate_lpc_subframe_( + encoder, + integer_signal, + residual[!_best_subframe], + encoder->private_->abs_residual_partition_sums, + encoder->private_->raw_bits_per_partition, + encoder->private_->lp_coeff[lpc_order-1], frame_header->blocksize, - subframe_bps + ( - encoder->protected_->do_qlp_coeff_prec_search? - FLAC__MIN_QLP_COEFF_PRECISION : /* have to guess; use the min possible size to avoid accidentally favoring lower orders */ - encoder->protected_->qlp_coeff_precision - ) + subframe_bps, + lpc_order, + qlp_coeff_precision, + rice_parameter_limit, + min_partition_order, + max_partition_order, + encoder->protected_->do_escape_coding, + encoder->protected_->rice_parameter_search_dist, + subframe[!_best_subframe], + partitioned_rice_contents[!_best_subframe] ); - min_lpc_order = max_lpc_order = guess_lpc_order; - } - if(max_lpc_order >= frame_header->blocksize) - max_lpc_order = frame_header->blocksize - 1; - for(lpc_order = min_lpc_order; lpc_order <= max_lpc_order; lpc_order++) { - lpc_residual_bits_per_sample = FLAC__lpc_compute_expected_bits_per_residual_sample(lpc_error[lpc_order-1], frame_header->blocksize-lpc_order); - if(lpc_residual_bits_per_sample >= (double)subframe_bps) - continue; /* don't even try */ - rice_parameter = (lpc_residual_bits_per_sample > 0.0)? (uint32_t)(lpc_residual_bits_per_sample+0.5) : 0; /* 0.5 is for rounding */ - rice_parameter++; /* to account for the signed->uint32_t conversion during rice coding */ - if(rice_parameter >= rice_parameter_limit) { -#ifndef NDEBUG - fprintf(stderr, "clipping rice_parameter (%u -> %u) @1\n", rice_parameter, rice_parameter_limit - 1); -#endif - rice_parameter = rice_parameter_limit - 1; - } - if(encoder->protected_->do_qlp_coeff_prec_search) { - min_qlp_coeff_precision = FLAC__MIN_QLP_COEFF_PRECISION; - /* try to keep qlp coeff precision such that only 32-bit math is required for decode of <=16bps(+1bps for side channel) streams */ - if(subframe_bps <= 17) { - max_qlp_coeff_precision = flac_min(32 - subframe_bps - FLAC__bitmath_ilog2(lpc_order), FLAC__MAX_QLP_COEFF_PRECISION); - max_qlp_coeff_precision = flac_max(max_qlp_coeff_precision, min_qlp_coeff_precision); - } - else - max_qlp_coeff_precision = FLAC__MAX_QLP_COEFF_PRECISION; - } - else { - min_qlp_coeff_precision = max_qlp_coeff_precision = encoder->protected_->qlp_coeff_precision; - } - for(qlp_coeff_precision = min_qlp_coeff_precision; qlp_coeff_precision <= max_qlp_coeff_precision; qlp_coeff_precision++) { - _candidate_bits = - evaluate_lpc_subframe_( - encoder, - integer_signal, - residual[!_best_subframe], - encoder->private_->abs_residual_partition_sums, - encoder->private_->raw_bits_per_partition, - encoder->private_->lp_coeff[lpc_order-1], - frame_header->blocksize, - subframe_bps, - lpc_order, - qlp_coeff_precision, - rice_parameter, - rice_parameter_limit, - min_partition_order, - max_partition_order, - encoder->protected_->do_escape_coding, - encoder->protected_->rice_parameter_search_dist, - subframe[!_best_subframe], - partitioned_rice_contents[!_best_subframe] - ); - if(_candidate_bits > 0) { /* if == 0, there was a problem quantizing the lpcoeffs */ - if(_candidate_bits < _best_bits) { - _best_subframe = !_best_subframe; - _best_bits = _candidate_bits; - } + if(_candidate_bits > 0) { /* if == 0, there was a problem quantizing the lpcoeffs */ + if(_candidate_bits < _best_bits) { + _best_subframe = !_best_subframe; + _best_bits = _candidate_bits; } } } @@ -3617,7 +3675,7 @@ FLAC__bool process_subframe_( } /* under rare circumstances this can happen when all but lpc subframe types are disabled: */ - if(_best_bits == UINT_MAX) { + if(_best_bits == UINT32_MAX) { FLAC__ASSERT(_best_subframe == 0); _best_bits = evaluate_verbatim_subframe_(encoder, integer_signal, frame_header->blocksize, subframe_bps, subframe[_best_subframe]); } @@ -3628,6 +3686,108 @@ FLAC__bool process_subframe_( return true; } +#ifndef FLAC__INTEGER_ONLY_LIBRARY +static inline void set_next_subdivide_tukey(FLAC__int32 parts, uint32_t * apodizations, uint32_t * current_depth, uint32_t * current_part){ + // current_part is interleaved: even are partial, odd are punchout + if(*current_depth == 2){ + // For depth 2, we only do partial, no punchout as that is almost redundant + if(*current_part == 0){ + *current_part = 2; + }else{ /* *current_path == 2 */ + *current_part = 0; + (*current_depth)++; + } + }else if((*current_part) < (2*(*current_depth)-1)){ + (*current_part)++; + }else{ /* (*current_part) >= (2*(*current_depth)-1) */ + *current_part = 0; + (*current_depth)++; + } + + /* Now check if we are done with this SUBDIVIDE_TUKEY apodization */ + if(*current_depth > (uint32_t) parts){ + (*apodizations)++; + *current_depth = 1; + *current_part = 0; + } +} + +FLAC__bool apply_apodization_(FLAC__StreamEncoder *encoder, + apply_apodization_state_struct *apply_apodization_state, + uint32_t blocksize, + double *lpc_error, + uint32_t *max_lpc_order_this_apodization, + uint32_t subframe_bps, + const void *integer_signal, + uint32_t *guess_lpc_order) +{ + apply_apodization_state->current_apodization = &encoder->protected_->apodizations[apply_apodization_state->a]; + + if(apply_apodization_state->b == 1) { + /* window full subblock */ + if(subframe_bps <= 32) + FLAC__lpc_window_data((const FLAC__int32*) integer_signal, encoder->private_->window[apply_apodization_state->a], encoder->private_->windowed_signal, blocksize); + else + FLAC__lpc_window_data_wide((const FLAC__int64*) integer_signal, encoder->private_->window[apply_apodization_state->a], encoder->private_->windowed_signal, blocksize); + encoder->private_->local_lpc_compute_autocorrelation(encoder->private_->windowed_signal, blocksize, (*max_lpc_order_this_apodization)+1, apply_apodization_state->autoc); + if(apply_apodization_state->current_apodization->type == FLAC__APODIZATION_SUBDIVIDE_TUKEY){ + uint32_t i; + for(i = 0; i < *max_lpc_order_this_apodization; i++) + memcpy(apply_apodization_state->autoc_root, apply_apodization_state->autoc, *max_lpc_order_this_apodization*sizeof(apply_apodization_state->autoc[0])); + + (apply_apodization_state->b)++; + }else{ + (apply_apodization_state->a)++; + } + } + else { + /* window part of subblock */ + if(blocksize/apply_apodization_state->b <= FLAC__MAX_LPC_ORDER) { + /* intrinsics autocorrelation routines do not all handle cases in which lag might be + * larger than data_len, and some routines round lag up to the nearest multiple of 4 + * As little gain is expected from using LPC on part of a signal as small as 32 samples + * and to enable widening this rounding up to larger values in the future, windowing + * parts smaller than or equal to FLAC__MAX_LPC_ORDER (which is 32) samples is not supported */ + set_next_subdivide_tukey(apply_apodization_state->current_apodization->parameters.subdivide_tukey.parts, &apply_apodization_state->a, &apply_apodization_state->b, &apply_apodization_state->c); + return false; + } + if(!(apply_apodization_state->c % 2)) { + /* on even c, evaluate the (c/2)th partial window of size blocksize/b */ + if(subframe_bps <= 32) + FLAC__lpc_window_data_partial((const FLAC__int32*) integer_signal, encoder->private_->window[apply_apodization_state->a], encoder->private_->windowed_signal, blocksize, blocksize/apply_apodization_state->b/2, (apply_apodization_state->c/2*blocksize)/apply_apodization_state->b); + else + FLAC__lpc_window_data_partial_wide((const FLAC__int64*) integer_signal, encoder->private_->window[apply_apodization_state->a], encoder->private_->windowed_signal, blocksize, blocksize/apply_apodization_state->b/2, (apply_apodization_state->c/2*blocksize)/apply_apodization_state->b); + encoder->private_->local_lpc_compute_autocorrelation(encoder->private_->windowed_signal, blocksize/apply_apodization_state->b, (*max_lpc_order_this_apodization)+1, apply_apodization_state->autoc); + } + else { + /* on uneven c, evaluate the root window (over the whole block) minus the previous partial window + * similar to tukey_punchout apodization but more efficient */ + uint32_t i; + for(i = 0; i < *max_lpc_order_this_apodization; i++) + apply_apodization_state->autoc[i] = apply_apodization_state->autoc_root[i] - apply_apodization_state->autoc[i]; + } + /* Next function sets a, b and c appropriate for next iteration */ + set_next_subdivide_tukey(apply_apodization_state->current_apodization->parameters.subdivide_tukey.parts, &apply_apodization_state->a, &apply_apodization_state->b, &apply_apodization_state->c); + } + + if(apply_apodization_state->autoc[0] == 0.0) /* Signal seems to be constant, so we can't do lp. Constant detection is probably disabled */ + return false; + FLAC__lpc_compute_lp_coefficients(apply_apodization_state->autoc, max_lpc_order_this_apodization, encoder->private_->lp_coeff, lpc_error); + *guess_lpc_order = + FLAC__lpc_compute_best_order( + lpc_error, + *max_lpc_order_this_apodization, + blocksize, + subframe_bps + ( + encoder->protected_->do_qlp_coeff_prec_search? + FLAC__MIN_QLP_COEFF_PRECISION : /* have to guess; use the min possible size to avoid accidentally favoring lower orders */ + encoder->protected_->qlp_coeff_precision + ) + ); + return true; +} +#endif + FLAC__bool add_subframe_( FLAC__StreamEncoder *encoder, uint32_t blocksize, @@ -3701,7 +3861,7 @@ static void spotcheck_subframe_estimate_( uint32_t evaluate_constant_subframe_( FLAC__StreamEncoder *encoder, - const FLAC__int32 signal, + const FLAC__int64 signal, uint32_t blocksize, uint32_t subframe_bps, FLAC__Subframe *subframe @@ -3724,14 +3884,13 @@ uint32_t evaluate_constant_subframe_( uint32_t evaluate_fixed_subframe_( FLAC__StreamEncoder *encoder, - const FLAC__int32 signal[], + const void *signal, FLAC__int32 residual[], FLAC__uint64 abs_residual_partition_sums[], uint32_t raw_bits_per_partition[], uint32_t blocksize, uint32_t subframe_bps, uint32_t order, - uint32_t rice_parameter, uint32_t rice_parameter_limit, uint32_t min_partition_order, uint32_t max_partition_order, @@ -3744,7 +3903,12 @@ uint32_t evaluate_fixed_subframe_( uint32_t i, residual_bits, estimate; const uint32_t residual_samples = blocksize - order; - FLAC__fixed_compute_residual(signal+order, residual_samples, order, residual); + if((subframe_bps + order) <= 32) + FLAC__fixed_compute_residual(((FLAC__int32 *)signal)+order, residual_samples, order, residual); + else if(subframe_bps <= 32) + FLAC__fixed_compute_residual_wide(((FLAC__int32 *)signal)+order, residual_samples, order, residual); + else + FLAC__fixed_compute_residual_wide_33bit(((FLAC__int64 *)signal)+order, residual_samples, order, residual); subframe->type = FLAC__SUBFRAME_TYPE_FIXED; @@ -3760,7 +3924,6 @@ uint32_t evaluate_fixed_subframe_( raw_bits_per_partition, residual_samples, order, - rice_parameter, rice_parameter_limit, min_partition_order, max_partition_order, @@ -3771,10 +3934,18 @@ uint32_t evaluate_fixed_subframe_( ); subframe->data.fixed.order = order; - for(i = 0; i < order; i++) - subframe->data.fixed.warmup[i] = signal[i]; + if(subframe_bps <= 32) + for(i = 0; i < order; i++) + subframe->data.fixed.warmup[i] = ((FLAC__int32 *)signal)[i]; + else + for(i = 0; i < order; i++) + subframe->data.fixed.warmup[i] = ((FLAC__int64 *)signal)[i]; - estimate = FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + subframe->wasted_bits + (order * subframe_bps) + residual_bits; + estimate = FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + subframe->wasted_bits + (order * subframe_bps); + if(residual_bits < UINT32_MAX - estimate) // To make sure estimate doesn't overflow + estimate += residual_bits; + else + estimate = UINT32_MAX; #if SPOTCHECK_ESTIMATE spotcheck_subframe_estimate_(encoder, blocksize, subframe_bps, subframe, estimate); @@ -3786,7 +3957,7 @@ uint32_t evaluate_fixed_subframe_( #ifndef FLAC__INTEGER_ONLY_LIBRARY uint32_t evaluate_lpc_subframe_( FLAC__StreamEncoder *encoder, - const FLAC__int32 signal[], + const void *signal, FLAC__int32 residual[], FLAC__uint64 abs_residual_partition_sums[], uint32_t raw_bits_per_partition[], @@ -3795,7 +3966,6 @@ uint32_t evaluate_lpc_subframe_( uint32_t subframe_bps, uint32_t order, uint32_t qlp_coeff_precision, - uint32_t rice_parameter, uint32_t rice_parameter_limit, uint32_t min_partition_order, uint32_t max_partition_order, @@ -3821,13 +3991,23 @@ uint32_t evaluate_lpc_subframe_( if(ret != 0) return 0; /* this is a hack to indicate to the caller that we can't do lp at this order on this subframe */ - if(subframe_bps + qlp_coeff_precision + FLAC__bitmath_ilog2(order) <= 32) - if(subframe_bps <= 16 && qlp_coeff_precision <= 16) - encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit(signal+order, residual_samples, qlp_coeff, order, quantization, residual); + if(FLAC__lpc_max_residual_bps(subframe_bps, qlp_coeff, order, quantization) > 32) { + if(subframe_bps <= 32){ + if(!FLAC__lpc_compute_residual_from_qlp_coefficients_limit_residual(((FLAC__int32 *)signal)+order, residual_samples, qlp_coeff, order, quantization, residual)) + return 0; + } else - encoder->private_->local_lpc_compute_residual_from_qlp_coefficients(signal+order, residual_samples, qlp_coeff, order, quantization, residual); + if(!FLAC__lpc_compute_residual_from_qlp_coefficients_limit_residual_33bit(((FLAC__int64 *)signal)+order, residual_samples, qlp_coeff, order, quantization, residual)) + return 0; + } else - encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit(signal+order, residual_samples, qlp_coeff, order, quantization, residual); + if(FLAC__lpc_max_prediction_before_shift_bps(subframe_bps, qlp_coeff, order) <= 32) + if(subframe_bps <= 16 && qlp_coeff_precision <= 16) + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit(((FLAC__int32 *)signal)+order, residual_samples, qlp_coeff, order, quantization, residual); + else + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients(((FLAC__int32 *)signal)+order, residual_samples, qlp_coeff, order, quantization, residual); + else + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit(((FLAC__int32 *)signal)+order, residual_samples, qlp_coeff, order, quantization, residual); subframe->type = FLAC__SUBFRAME_TYPE_LPC; @@ -3843,7 +4023,6 @@ uint32_t evaluate_lpc_subframe_( raw_bits_per_partition, residual_samples, order, - rice_parameter, rice_parameter_limit, min_partition_order, max_partition_order, @@ -3857,10 +4036,19 @@ uint32_t evaluate_lpc_subframe_( subframe->data.lpc.qlp_coeff_precision = qlp_coeff_precision; subframe->data.lpc.quantization_level = quantization; memcpy(subframe->data.lpc.qlp_coeff, qlp_coeff, sizeof(FLAC__int32)*FLAC__MAX_LPC_ORDER); - for(i = 0; i < order; i++) - subframe->data.lpc.warmup[i] = signal[i]; + if(subframe_bps <= 32) + for(i = 0; i < order; i++) + subframe->data.lpc.warmup[i] = ((FLAC__int32 *)signal)[i]; + else + for(i = 0; i < order; i++) + subframe->data.lpc.warmup[i] = ((FLAC__int64 *)signal)[i]; - estimate = FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + subframe->wasted_bits + FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN + FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN + (order * (qlp_coeff_precision + subframe_bps)) + residual_bits; + + estimate = FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + subframe->wasted_bits + FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN + FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN + (order * (qlp_coeff_precision + subframe_bps)); + if(residual_bits < UINT32_MAX - estimate) // To make sure estimate doesn't overflow + estimate += residual_bits; + else + estimate = UINT32_MAX; #if SPOTCHECK_ESTIMATE spotcheck_subframe_estimate_(encoder, blocksize, subframe_bps, subframe, estimate); @@ -3872,7 +4060,7 @@ uint32_t evaluate_lpc_subframe_( uint32_t evaluate_verbatim_subframe_( FLAC__StreamEncoder *encoder, - const FLAC__int32 signal[], + const void *signal, uint32_t blocksize, uint32_t subframe_bps, FLAC__Subframe *subframe @@ -3882,7 +4070,14 @@ uint32_t evaluate_verbatim_subframe_( subframe->type = FLAC__SUBFRAME_TYPE_VERBATIM; - subframe->data.verbatim.data = signal; + if(subframe_bps <= 32){ + subframe->data.verbatim.data_type = FLAC__VERBATIM_SUBFRAME_DATA_TYPE_INT32; + subframe->data.verbatim.data.int32 = (const FLAC__int32*) signal; + } + else { + subframe->data.verbatim.data_type = FLAC__VERBATIM_SUBFRAME_DATA_TYPE_INT64; + subframe->data.verbatim.data.int64 = (const FLAC__int64*) signal; + } estimate = FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + subframe->wasted_bits + (blocksize * subframe_bps); @@ -3902,7 +4097,6 @@ uint32_t find_best_partition_order_( uint32_t raw_bits_per_partition[], uint32_t residual_samples, uint32_t predictor_order, - uint32_t rice_parameter, uint32_t rice_parameter_limit, uint32_t min_partition_order, uint32_t max_partition_order, @@ -3939,7 +4133,6 @@ uint32_t find_best_partition_order_( raw_bits_per_partition+sum, residual_samples, predictor_order, - rice_parameter, rice_parameter_limit, rice_parameter_search_dist, (uint32_t)partition_order, @@ -3972,10 +4165,9 @@ uint32_t find_best_partition_order_( uint32_t partition; /* save best parameters and raw_bits */ - FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(prc, flac_max(6u, best_partition_order)); - memcpy(prc->parameters, private_->partitioned_rice_contents_extra[best_parameters_index].parameters, sizeof(uint32_t)*(1<<(best_partition_order))); + memcpy(prc->parameters, private_->partitioned_rice_contents_extra[best_parameters_index].parameters, (uint32_t)sizeof(uint32_t)*(1<<(best_partition_order))); if(do_escape_coding) - memcpy(prc->raw_bits, private_->partitioned_rice_contents_extra[best_parameters_index].raw_bits, sizeof(uint32_t)*(1<<(best_partition_order))); + memcpy(prc->raw_bits, private_->partitioned_rice_contents_extra[best_parameters_index].raw_bits, (uint32_t)sizeof(uint32_t)*(1<<(best_partition_order))); /* * Now need to check if the type should be changed to * FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2 based on the @@ -4121,7 +4313,7 @@ static inline uint32_t count_rice_bits_in_partition_( ; for(i = 0; i < partition_samples; i++) partition_bits += ( (FLAC__uint32)((residual[i]<<1)^(residual[i]>>31)) >> rice_parameter ); - return (uint32_t)(flac_min(partition_bits,(uint32_t)(-1))); // To make sure the return value doesn't overflow + return (uint32_t)(flac_min(partition_bits,UINT32_MAX)); // To make sure the return value doesn't overflow } #else static inline uint32_t count_rice_bits_in_partition_( @@ -4138,7 +4330,7 @@ static inline uint32_t count_rice_bits_in_partition_( (abs_residual_partition_sum >> (rice_parameter-1)) /* rice_parameter-1 because the real coder sign-folds instead of using a sign bit */ : (abs_residual_partition_sum << 1) /* can't shift by negative number, so reverse */ ) - - (partition_samples >> 1)),(uint32_t)(-1))); + - (partition_samples >> 1)),UINT32_MAX)); /* -(partition_samples>>1) to subtract out extra contributions to the abs_residual_partition_sum. * The actual number of bits used is closer to the sum(for all i in the partition) of abs(residual[i])>>(rice_parameter-1) * By using the abs_residual_partition sum, we also add in bits in the LSBs that would normally be shifted out. @@ -4157,7 +4349,6 @@ FLAC__bool set_partitioned_rice_( const uint32_t raw_bits_per_partition[], const uint32_t residual_samples, const uint32_t predictor_order, - const uint32_t suggested_rice_parameter, const uint32_t rice_parameter_limit, const uint32_t rice_parameter_search_dist, const uint32_t partition_order, @@ -4170,46 +4361,85 @@ FLAC__bool set_partitioned_rice_( uint32_t best_partition_bits, best_rice_parameter = 0; uint32_t bits_ = FLAC__ENTROPY_CODING_METHOD_TYPE_LEN + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN; uint32_t *parameters, *raw_bits; + uint32_t partition, residual_sample; + uint32_t partition_samples, partition_samples_base; + uint32_t partition_samples_fixed_point_divisor, partition_samples_fixed_point_divisor_base; + const uint32_t partitions = 1u << partition_order; + FLAC__uint64 mean; #ifdef ENABLE_RICE_PARAMETER_SEARCH uint32_t min_rice_parameter, max_rice_parameter; #else (void)rice_parameter_search_dist; #endif - FLAC__ASSERT(suggested_rice_parameter < FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER); FLAC__ASSERT(rice_parameter_limit <= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER); - FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(partitioned_rice_contents, flac_max(6u, partition_order)); parameters = partitioned_rice_contents->parameters; raw_bits = partitioned_rice_contents->raw_bits; - if(partition_order == 0) { - best_partition_bits = (uint32_t)(-1); + partition_samples_base = (residual_samples+predictor_order) >> partition_order; + + /* Integer division is slow. To speed up things, precalculate a fixed point + * divisor, as all partitions except the first are the same size. 18 bits + * are taken because maximum block size is 65535, max partition size for + * partitions other than 0 is 32767 (15 bit), max abs residual is 2^31, + * which leaves 18 bit */ + partition_samples_fixed_point_divisor_base = 0x40000 / partition_samples_base; + + for(partition = residual_sample = 0; partition < partitions; partition++) { + partition_samples = partition_samples_base; + if(partition > 0) { + partition_samples_fixed_point_divisor = partition_samples_fixed_point_divisor_base; + } + else { + if(partition_samples <= predictor_order) + return false; + else + partition_samples -= predictor_order; + partition_samples_fixed_point_divisor = 0x40000 / partition_samples; + } + mean = abs_residual_partition_sums[partition]; + /* 'mean' is not a good name for the variable, it is + * actually the sum of magnitudes of all residual values + * in the partition, so the actual mean is + * mean/partition_samples + */ + if(mean < 2 || (((mean - 1)*partition_samples_fixed_point_divisor)>>18) == 0) + rice_parameter = 0; + else + rice_parameter = FLAC__bitmath_ilog2_wide(((mean - 1)*partition_samples_fixed_point_divisor)>>18) + 1; + + if(rice_parameter >= rice_parameter_limit) { +#ifndef NDEBUG + fprintf(stderr, "clipping rice_parameter (%u -> %u) @6\n", rice_parameter, rice_parameter_limit - 1); +#endif + rice_parameter = rice_parameter_limit - 1; + } + + best_partition_bits = UINT32_MAX; #ifdef ENABLE_RICE_PARAMETER_SEARCH if(rice_parameter_search_dist) { - if(suggested_rice_parameter < rice_parameter_search_dist) + if(rice_parameter < rice_parameter_search_dist) min_rice_parameter = 0; else - min_rice_parameter = suggested_rice_parameter - rice_parameter_search_dist; - max_rice_parameter = suggested_rice_parameter + rice_parameter_search_dist; + min_rice_parameter = rice_parameter - rice_parameter_search_dist; + max_rice_parameter = rice_parameter + rice_parameter_search_dist; if(max_rice_parameter >= rice_parameter_limit) { #ifndef NDEBUG - fprintf(stderr, "clipping rice_parameter (%u -> %u) @5\n", max_rice_parameter, rice_parameter_limit - 1); + fprintf(stderr, "clipping rice_parameter (%u -> %u) @7\n", max_rice_parameter, rice_parameter_limit - 1); #endif max_rice_parameter = rice_parameter_limit - 1; } } else - min_rice_parameter = max_rice_parameter = suggested_rice_parameter; + min_rice_parameter = max_rice_parameter = rice_parameter; for(rice_parameter = min_rice_parameter; rice_parameter <= max_rice_parameter; rice_parameter++) { -#else - rice_parameter = suggested_rice_parameter; #endif #ifdef EXACT_RICE_BITS_CALCULATION - partition_bits = count_rice_bits_in_partition_(rice_parameter, residual_samples, residual); + partition_bits = count_rice_bits_in_partition_(rice_parameter, partition_samples, residual+residual_sample); #else - partition_bits = count_rice_bits_in_partition_(rice_parameter, residual_samples, abs_residual_partition_sums[0]); + partition_bits = count_rice_bits_in_partition_(rice_parameter, partition_samples, abs_residual_partition_sums[partition]); #endif if(partition_bits < best_partition_bits) { best_rice_parameter = rice_parameter; @@ -4219,128 +4449,21 @@ FLAC__bool set_partitioned_rice_( } #endif if(search_for_escapes) { - partition_bits = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN + raw_bits_per_partition[0] * residual_samples; - if(partition_bits <= best_partition_bits) { - raw_bits[0] = raw_bits_per_partition[0]; + partition_bits = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN + raw_bits_per_partition[partition] * partition_samples; + if(partition_bits <= best_partition_bits && raw_bits_per_partition[partition] < 32) { + raw_bits[partition] = raw_bits_per_partition[partition]; best_rice_parameter = 0; /* will be converted to appropriate escape parameter later */ best_partition_bits = partition_bits; } else - raw_bits[0] = 0; + raw_bits[partition] = 0; } - parameters[0] = best_rice_parameter; - if(best_partition_bits < UINT_MAX - bits_) // To make sure _bits doesn't overflow + parameters[partition] = best_rice_parameter; + if(best_partition_bits < UINT32_MAX - bits_) // To make sure _bits doesn't overflow bits_ += best_partition_bits; else - bits_ = UINT_MAX; - } - else { - uint32_t partition, residual_sample; - uint32_t partition_samples; - FLAC__uint64 mean, k; - const uint32_t partitions = 1u << partition_order; - for(partition = residual_sample = 0; partition < partitions; partition++) { - partition_samples = (residual_samples+predictor_order) >> partition_order; - if(partition == 0) { - if(partition_samples <= predictor_order) - return false; - else - partition_samples -= predictor_order; - } - mean = abs_residual_partition_sums[partition]; - /* we are basically calculating the size in bits of the - * average residual magnitude in the partition: - * rice_parameter = floor(log2(mean/partition_samples)) - * 'mean' is not a good name for the variable, it is - * actually the sum of magnitudes of all residual values - * in the partition, so the actual mean is - * mean/partition_samples - */ -#if 0 /* old simple code */ - for(rice_parameter = 0, k = partition_samples; k < mean; rice_parameter++, k <<= 1) - ; -#else -#if defined FLAC__CPU_X86_64 /* and other 64-bit arch, too */ - if(mean <= 0x80000000/512) { /* 512: more or less optimal for both 16- and 24-bit input */ -#else - if(mean <= 0x80000000/8) { /* 32-bit arch: use 32-bit math if possible */ -#endif - FLAC__uint32 k2, mean2 = (FLAC__uint32) mean; - rice_parameter = 0; k2 = partition_samples; - while(k2*8 < mean2) { /* requires: mean <= (2^31)/8 */ - rice_parameter += 4; k2 <<= 4; /* tuned for 16-bit input */ - } - while(k2 < mean2) { /* requires: mean <= 2^31 */ - rice_parameter++; k2 <<= 1; - } - } - else { - rice_parameter = 0; k = partition_samples; - if(mean <= FLAC__U64L(0x8000000000000000)/128) /* usually mean is _much_ smaller than this value */ - while(k*128 < mean) { /* requires: mean <= (2^63)/128 */ - rice_parameter += 8; k <<= 8; /* tuned for 24-bit input */ - } - while(k < mean) { /* requires: mean <= 2^63 */ - rice_parameter++; k <<= 1; - } - } -#endif - if(rice_parameter >= rice_parameter_limit) { -#ifndef NDEBUG - fprintf(stderr, "clipping rice_parameter (%u -> %u) @6\n", rice_parameter, rice_parameter_limit - 1); -#endif - rice_parameter = rice_parameter_limit - 1; - } - - best_partition_bits = (uint32_t)(-1); -#ifdef ENABLE_RICE_PARAMETER_SEARCH - if(rice_parameter_search_dist) { - if(rice_parameter < rice_parameter_search_dist) - min_rice_parameter = 0; - else - min_rice_parameter = rice_parameter - rice_parameter_search_dist; - max_rice_parameter = rice_parameter + rice_parameter_search_dist; - if(max_rice_parameter >= rice_parameter_limit) { -#ifndef NDEBUG - fprintf(stderr, "clipping rice_parameter (%u -> %u) @7\n", max_rice_parameter, rice_parameter_limit - 1); -#endif - max_rice_parameter = rice_parameter_limit - 1; - } - } - else - min_rice_parameter = max_rice_parameter = rice_parameter; - - for(rice_parameter = min_rice_parameter; rice_parameter <= max_rice_parameter; rice_parameter++) { -#endif -#ifdef EXACT_RICE_BITS_CALCULATION - partition_bits = count_rice_bits_in_partition_(rice_parameter, partition_samples, residual+residual_sample); -#else - partition_bits = count_rice_bits_in_partition_(rice_parameter, partition_samples, abs_residual_partition_sums[partition]); -#endif - if(partition_bits < best_partition_bits) { - best_rice_parameter = rice_parameter; - best_partition_bits = partition_bits; - } -#ifdef ENABLE_RICE_PARAMETER_SEARCH - } -#endif - if(search_for_escapes) { - partition_bits = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN + raw_bits_per_partition[partition] * partition_samples; - if(partition_bits <= best_partition_bits) { - raw_bits[partition] = raw_bits_per_partition[partition]; - best_rice_parameter = 0; /* will be converted to appropriate escape parameter later */ - best_partition_bits = partition_bits; - } - else - raw_bits[partition] = 0; - } - parameters[partition] = best_rice_parameter; - if(best_partition_bits < UINT_MAX - bits_) // To make sure _bits doesn't overflow - bits_ += best_partition_bits; - else - bits_ = UINT_MAX; - residual_sample += partition_samples; - } + bits_ = UINT32_MAX; + residual_sample += partition_samples; } *bits = bits_; @@ -4371,6 +4494,31 @@ uint32_t get_wasted_bits_(FLAC__int32 signal[], uint32_t samples) return shift; } +uint32_t get_wasted_bits_wide_(FLAC__int64 signal_wide[], FLAC__int32 signal[], uint32_t samples) +{ + uint32_t i, shift; + FLAC__int64 x = 0; + + for(i = 0; i < samples && !(x&1); i++) + x |= signal_wide[i]; + + if(x == 0) { + shift = 1; + } + else { + for(shift = 0; !(x&1); shift++) + x >>= 1; + } + + if(shift > 0) { + for(i = 0; i < samples; i++) + signal[i] = (FLAC__int32)(signal_wide[i] >> shift); + } + + return shift; +} + + void append_to_verify_fifo_(verify_input_fifo *fifo, const FLAC__int32 * const input[], uint32_t input_offset, uint32_t channels, uint32_t wide_samples) { uint32_t channel; @@ -4441,6 +4589,11 @@ FLAC__StreamDecoderWriteStatus verify_write_callback_(const FLAC__StreamDecoder (void)decoder; + if(encoder->protected_->state == FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR) { + /* This is set when verify_error_callback_ was called */ + return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; + } + for(channel = 0; channel < channels; channel++) { if(0 != memcmp(buffer[channel], encoder->private_->verify.input_fifo.data[channel], bytes_per_block)) { uint32_t i, sample = 0; diff --git a/modules/juce_audio_formats/codecs/flac/libFLAC/stream_encoder_framing.c b/modules/juce_audio_formats/codecs/flac/libFLAC/stream_encoder_framing.c index 5d956dd92aee..aa424b0dedd1 100644 --- a/modules/juce_audio_formats/codecs/flac/libFLAC/stream_encoder_framing.c +++ b/modules/juce_audio_formats/codecs/flac/libFLAC/stream_encoder_framing.c @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -44,10 +44,13 @@ static FLAC__bool add_entropy_coding_method_(FLAC__BitWriter *bw, const FLAC__EntropyCodingMethod *method); static FLAC__bool add_residual_partitioned_rice_(FLAC__BitWriter *bw, const FLAC__int32 residual[], const uint32_t residual_samples, const uint32_t predictor_order, const uint32_t rice_parameters[], const uint32_t raw_bits[], const uint32_t partition_order, const FLAC__bool is_extended); -FLAC__bool FLAC__add_metadata_block(const FLAC__StreamMetadata *metadata, FLAC__BitWriter *bw) +FLAC__bool FLAC__add_metadata_block(const FLAC__StreamMetadata *metadata, FLAC__BitWriter *bw, FLAC__bool update_vendor_string) { - uint32_t i, j; + uint32_t i, j, metadata_length; const uint32_t vendor_string_length = (uint32_t)strlen(FLAC__VENDOR_STRING); + const uint32_t start_bits = FLAC__bitwriter_get_input_bits_unconsumed(bw); + + FLAC__ASSERT(FLAC__bitwriter_is_byte_aligned(bw)); if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->is_last, FLAC__STREAM_METADATA_IS_LAST_LEN)) return false; @@ -58,17 +61,17 @@ FLAC__bool FLAC__add_metadata_block(const FLAC__StreamMetadata *metadata, FLAC__ /* * First, for VORBIS_COMMENTs, adjust the length to reflect our vendor string */ - i = metadata->length; - if(metadata->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) { + metadata_length = metadata->length; + if(metadata->type == FLAC__METADATA_TYPE_VORBIS_COMMENT && update_vendor_string) { FLAC__ASSERT(metadata->data.vorbis_comment.vendor_string.length == 0 || 0 != metadata->data.vorbis_comment.vendor_string.entry); - i -= metadata->data.vorbis_comment.vendor_string.length; - i += vendor_string_length; + metadata_length -= metadata->data.vorbis_comment.vendor_string.length; + metadata_length += vendor_string_length; } - FLAC__ASSERT(i < (1u << FLAC__STREAM_METADATA_LENGTH_LEN)); + FLAC__ASSERT(metadata_length < (1u << FLAC__STREAM_METADATA_LENGTH_LEN)); /* double protection */ - if(i >= (1u << FLAC__STREAM_METADATA_LENGTH_LEN)) + if(metadata_length >= (1u << FLAC__STREAM_METADATA_LENGTH_LEN)) return false; - if(!FLAC__bitwriter_write_raw_uint32(bw, i, FLAC__STREAM_METADATA_LENGTH_LEN)) + if(!FLAC__bitwriter_write_raw_uint32(bw, metadata_length, FLAC__STREAM_METADATA_LENGTH_LEN)) return false; switch(metadata->type) { @@ -96,9 +99,13 @@ FLAC__bool FLAC__add_metadata_block(const FLAC__StreamMetadata *metadata, FLAC__ FLAC__ASSERT(metadata->data.stream_info.bits_per_sample <= (1u << FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN)); if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.stream_info.bits_per_sample-1, FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN)) return false; - FLAC__ASSERT(metadata->data.stream_info.total_samples < (FLAC__U64L(1) << FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN)); - if(!FLAC__bitwriter_write_raw_uint64(bw, metadata->data.stream_info.total_samples, FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN)) - return false; + if(metadata->data.stream_info.total_samples >= (FLAC__U64L(1) << FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN)){ + if(!FLAC__bitwriter_write_raw_uint64(bw, 0, FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN)) + return false; + }else{ + if(!FLAC__bitwriter_write_raw_uint64(bw, metadata->data.stream_info.total_samples, FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN)) + return false; + } if(!FLAC__bitwriter_write_byte_block(bw, metadata->data.stream_info.md5sum, 16)) return false; break; @@ -123,10 +130,18 @@ FLAC__bool FLAC__add_metadata_block(const FLAC__StreamMetadata *metadata, FLAC__ } break; case FLAC__METADATA_TYPE_VORBIS_COMMENT: - if(!FLAC__bitwriter_write_raw_uint32_little_endian(bw, vendor_string_length)) - return false; - if(!FLAC__bitwriter_write_byte_block(bw, (const FLAC__byte*)FLAC__VENDOR_STRING, vendor_string_length)) - return false; + if(update_vendor_string) { + if(!FLAC__bitwriter_write_raw_uint32_little_endian(bw, vendor_string_length)) + return false; + if(!FLAC__bitwriter_write_byte_block(bw, (const FLAC__byte*)FLAC__VENDOR_STRING, vendor_string_length)) + return false; + } + else { + if(!FLAC__bitwriter_write_raw_uint32_little_endian(bw, metadata->data.vorbis_comment.vendor_string.length)) + return false; + if(!FLAC__bitwriter_write_byte_block(bw, metadata->data.vorbis_comment.vendor_string.entry, metadata->data.vorbis_comment.vendor_string.length)) + return false; + } if(!FLAC__bitwriter_write_raw_uint32_little_endian(bw, metadata->data.vorbis_comment.num_comments)) return false; for(i = 0; i < metadata->data.vorbis_comment.num_comments; i++) { @@ -213,6 +228,16 @@ FLAC__bool FLAC__add_metadata_block(const FLAC__StreamMetadata *metadata, FLAC__ break; } + /* Now check whether metadata block length was correct */ + { + uint32_t length_in_bits = FLAC__bitwriter_get_input_bits_unconsumed(bw); + if(length_in_bits < start_bits) + return false; + length_in_bits -= start_bits; + if(length_in_bits % 8 != 0 || length_in_bits != (metadata_length*8+32)) + return false; + } + FLAC__ASSERT(FLAC__bitwriter_is_byte_aligned(bw)); return true; } @@ -278,7 +303,7 @@ FLAC__bool FLAC__frame_add_header(const FLAC__FrameHeader *header, FLAC__BitWrit default: if(header->sample_rate <= 255000 && header->sample_rate % 1000 == 0) sample_rate_hint = u = 12; - else if(header->sample_rate % 10 == 0) + else if(header->sample_rate <= 655350 && header->sample_rate % 10 == 0) sample_rate_hint = u = 14; else if(header->sample_rate <= 0xffff) sample_rate_hint = u = 13; @@ -319,6 +344,7 @@ FLAC__bool FLAC__frame_add_header(const FLAC__FrameHeader *header, FLAC__BitWrit case 16: u = 4; break; case 20: u = 5; break; case 24: u = 6; break; + case 32: u = 7; break; default: u = 0; break; } if(!FLAC__bitwriter_write_raw_uint32(bw, u, FLAC__FRAME_HEADER_BITS_PER_SAMPLE_LEN)) @@ -371,7 +397,7 @@ FLAC__bool FLAC__subframe_add_constant(const FLAC__Subframe_Constant *subframe, ok = FLAC__bitwriter_write_raw_uint32(bw, FLAC__SUBFRAME_TYPE_CONSTANT_BYTE_ALIGNED_MASK | (wasted_bits? 1:0), FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN) && (wasted_bits? FLAC__bitwriter_write_unary_unsigned(bw, wasted_bits-1) : true) && - FLAC__bitwriter_write_raw_int32(bw, subframe->value, subframe_bps) + FLAC__bitwriter_write_raw_int64(bw, subframe->value, subframe_bps) ; return ok; @@ -388,7 +414,7 @@ FLAC__bool FLAC__subframe_add_fixed(const FLAC__Subframe_Fixed *subframe, uint32 return false; for(i = 0; i < subframe->order; i++) - if(!FLAC__bitwriter_write_raw_int32(bw, subframe->warmup[i], subframe_bps)) + if(!FLAC__bitwriter_write_raw_int64(bw, subframe->warmup[i], subframe_bps)) return false; if(!add_entropy_coding_method_(bw, &subframe->entropy_coding_method)) @@ -426,7 +452,7 @@ FLAC__bool FLAC__subframe_add_lpc(const FLAC__Subframe_LPC *subframe, uint32_t r return false; for(i = 0; i < subframe->order; i++) - if(!FLAC__bitwriter_write_raw_int32(bw, subframe->warmup[i], subframe_bps)) + if(!FLAC__bitwriter_write_raw_int64(bw, subframe->warmup[i], subframe_bps)) return false; if(!FLAC__bitwriter_write_raw_uint32(bw, subframe->qlp_coeff_precision-1, FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN)) @@ -464,7 +490,6 @@ FLAC__bool FLAC__subframe_add_lpc(const FLAC__Subframe_LPC *subframe, uint32_t r FLAC__bool FLAC__subframe_add_verbatim(const FLAC__Subframe_Verbatim *subframe, uint32_t samples, uint32_t subframe_bps, uint32_t wasted_bits, FLAC__BitWriter *bw) { uint32_t i; - const FLAC__int32 *signal = subframe->data; if(!FLAC__bitwriter_write_raw_uint32(bw, FLAC__SUBFRAME_TYPE_VERBATIM_BYTE_ALIGNED_MASK | (wasted_bits? 1:0), FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN)) return false; @@ -472,9 +497,24 @@ FLAC__bool FLAC__subframe_add_verbatim(const FLAC__Subframe_Verbatim *subframe, if(!FLAC__bitwriter_write_unary_unsigned(bw, wasted_bits-1)) return false; - for(i = 0; i < samples; i++) - if(!FLAC__bitwriter_write_raw_int32(bw, signal[i], subframe_bps)) - return false; + if(subframe->data_type == FLAC__VERBATIM_SUBFRAME_DATA_TYPE_INT32) { + const FLAC__int32 *signal = subframe->data.int32; + + FLAC__ASSERT(subframe_bps < 33); + + for(i = 0; i < samples; i++) + if(!FLAC__bitwriter_write_raw_int32(bw, signal[i], subframe_bps)) + return false; + } + else { + const FLAC__int64 *signal = subframe->data.int64; + + FLAC__ASSERT(subframe_bps == 33); + + for(i = 0; i < samples; i++) + if(!FLAC__bitwriter_write_raw_int64(bw, (FLAC__int64)signal[i], subframe_bps)) + return false; + } return true; } diff --git a/modules/juce_audio_formats/codecs/flac/libFLAC/window_flac.c b/modules/juce_audio_formats/codecs/flac/libFLAC/window_flac.c index 05cb08daad4f..79e2e2ca0cbd 100644 --- a/modules/juce_audio_formats/codecs/flac/libFLAC/window_flac.c +++ b/modules/juce_audio_formats/codecs/flac/libFLAC/window_flac.c @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2006-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -42,6 +42,10 @@ #ifndef FLAC__INTEGER_ONLY_LIBRARY +#if defined(_MSC_VER) +// silence 25 MSVC warnings 'conversion from 'double' to 'float', possible loss of data' +#pragma warning ( disable : 4244 ) +#endif void FLAC__window_bartlett(FLAC__real *window, const FLAC__int32 L) { @@ -118,9 +122,15 @@ void FLAC__window_gauss(FLAC__real *window, const FLAC__int32 L, const FLAC__rea const double N2 = (double)N / 2.; FLAC__int32 n; - for (n = 0; n <= N; n++) { - const double k = ((double)n - N2) / (stddev * N2); - window[n] = (FLAC__real)exp(-0.5f * k * k); + if(!(stddev > 0.0f && stddev <= 0.5f)) + /* stddev is not between 0 and 0.5, might be NaN. + * Default to 0.5 */ + FLAC__window_gauss(window, L, 0.25f); + else { + for (n = 0; n <= N; n++) { + const double k = ((double)n - N2) / (stddev * N2); + window[n] = (FLAC__real)exp(-0.5f * k * k); + } } } @@ -192,6 +202,10 @@ void FLAC__window_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__rea FLAC__window_rectangle(window, L); else if (p >= 1.0) FLAC__window_hann(window, L); + else if (!(p > 0.0f && p < 1.0f)) + /* p is not between 0 and 1, probably NaN. + * Default to 0.5 */ + FLAC__window_tukey(window, L, 0.5f); else { const FLAC__int32 Np = (FLAC__int32)(p / 2.0f * L) - 1; FLAC__int32 n; @@ -218,6 +232,10 @@ void FLAC__window_partial_tukey(FLAC__real *window, const FLAC__int32 L, const F FLAC__window_partial_tukey(window, L, 0.05f, start, end); else if (p >= 1.0f) FLAC__window_partial_tukey(window, L, 0.95f, start, end); + else if (!(p > 0.0f && p < 1.0f)) + /* p is not between 0 and 1, probably NaN. + * Default to 0.5 */ + FLAC__window_partial_tukey(window, L, 0.5f, start, end); else { Np = (FLAC__int32)(p / 2.0f * N); @@ -245,6 +263,10 @@ void FLAC__window_punchout_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__window_punchout_tukey(window, L, 0.05f, start, end); else if (p >= 1.0f) FLAC__window_punchout_tukey(window, L, 0.95f, start, end); + else if (!(p > 0.0f && p < 1.0f)) + /* p is not between 0 and 1, probably NaN. + * Default to 0.5 */ + FLAC__window_punchout_tukey(window, L, 0.5f, start, end); else { Ns = (FLAC__int32)(p / 2.0f * start_n); @@ -279,4 +301,8 @@ void FLAC__window_welch(FLAC__real *window, const FLAC__int32 L) } } +#if defined(_MSC_VER) +#pragma warning ( default : 4244 ) +#endif + #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ diff --git a/modules/juce_audio_formats/codecs/flac/metadata.h b/modules/juce_audio_formats/codecs/flac/metadata.h index ebba19d6acaa..88763a0f42ce 100644 --- a/modules/juce_audio_formats/codecs/flac/metadata.h +++ b/modules/juce_audio_formats/codecs/flac/metadata.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2001-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -33,6 +33,7 @@ #ifndef FLAC__METADATA_H #define FLAC__METADATA_H +#include /* for off_t */ #include "export.h" #include "callback.h" #include "format.h" @@ -133,6 +134,11 @@ extern "C" { * STREAMINFO, VORBIS_COMMENT, CUESHEET, and PICTURE blocks, requiring * only a filename. * + * On Windows, filename must be a UTF-8 encoded filename, which libFLAC + * internally translates to an appropriate representation to use with + * _wfopen. On all other systems, filename is passed to fopen without + * any translation. + * * They try to skip any ID3v2 tag at the head of the file. * * \{ @@ -386,6 +392,11 @@ FLAC_API FLAC__Metadata_SimpleIteratorStatus FLAC__metadata_simple_iterator_stat /** Initialize the iterator to point to the first metadata block in the * given FLAC file. * + * On Windows, filename must be a UTF-8 encoded filename, which libFLAC + * internally translates to an appropriate representation to use with + * _wfopen. On all other systems, filename is passed to fopen without + * any translation. + * * \param iterator A pointer to an existing iterator. * \param filename The path to the FLAC file. * \param read_only If \c true, the FLAC file will be opened @@ -499,7 +510,7 @@ FLAC_API FLAC__MetadataType FLAC__metadata_simple_iterator_get_block_type(const * \retval uint32_t * The length of the metadata block at the current iterator position. * The is same length as that in the - * metadata block header, + * metadata block header, * i.e. the length of the metadata body that follows the header. */ FLAC_API uint32_t FLAC__metadata_simple_iterator_get_block_length(const FLAC__Metadata_SimpleIterator *iterator); @@ -818,6 +829,11 @@ FLAC_API void FLAC__metadata_chain_delete(FLAC__Metadata_Chain *chain); FLAC_API FLAC__Metadata_ChainStatus FLAC__metadata_chain_status(FLAC__Metadata_Chain *chain); /** Read all metadata from a FLAC file into the chain. + * + * On Windows, filename must be a UTF-8 encoded filename, which libFLAC + * internally translates to an appropriate representation to use with + * _wfopen. On all other systems, filename is passed to fopen without + * any translation. * * \param chain A pointer to an existing chain. * \param filename The path to the FLAC file to read. @@ -832,6 +848,11 @@ FLAC_API FLAC__Metadata_ChainStatus FLAC__metadata_chain_status(FLAC__Metadata_C FLAC_API FLAC__bool FLAC__metadata_chain_read(FLAC__Metadata_Chain *chain, const char *filename); /** Read all metadata from an Ogg FLAC file into the chain. + * + * On Windows, filename must be a UTF-8 encoded filename, which libFLAC + * internally translates to an appropriate representation to use with + * _wfopen. On all other systems, filename is passed to fopen without + * any translation. * * \note Ogg FLAC metadata data writing is not supported yet and * FLAC__metadata_chain_write() will fail. @@ -1377,7 +1398,8 @@ FLAC_API FLAC__bool FLAC__metadata_object_application_set_data(FLAC__StreamMetad /** Resize the seekpoint array. * * If the size shrinks, elements will truncated; if it grows, new placeholder - * points will be added to the end. + * points will be added to the end. If this function returns false, the + * object is left untouched. * * \param object A pointer to an existing SEEKTABLE object. * \param new_num_points The desired length of the array; may be \c 0. @@ -1590,7 +1612,8 @@ FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_set_vendor_string(FLAC__ /** Resize the comment array. * * If the size shrinks, elements will truncated; if it grows, new empty - * fields will be added to the end. + * fields will be added to the end. If this function returns false, the + * object is left untouched. * * \param object A pointer to an existing VORBIS_COMMENT object. * \param new_num_comments The desired length of the array; may be \c 0. @@ -1870,7 +1893,8 @@ FLAC_API void FLAC__metadata_object_cuesheet_track_delete(FLAC__StreamMetadata_C /** Resize a track's index point array. * * If the size shrinks, elements will truncated; if it grows, new blank - * indices will be added to the end. + * indices will be added to the end. If this function returns false, the + * track object is left untouched. * * \param object A pointer to an existing CUESHEET object. * \param track_num The index of the track to modify. NOTE: this is not @@ -1956,7 +1980,8 @@ FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_delete_index(FLAC__Stre /** Resize the track array. * * If the size shrinks, elements will truncated; if it grows, new blank - * tracks will be added to the end. + * tracks will be added to the end. If this function returns false, the + * object is left untouched. * * \param object A pointer to an existing CUESHEET object. * \param new_num_tracks The desired length of the array; may be \c 0. @@ -2172,6 +2197,34 @@ FLAC_API FLAC__bool FLAC__metadata_object_picture_set_data(FLAC__StreamMetadata */ FLAC_API FLAC__bool FLAC__metadata_object_picture_is_legal(const FLAC__StreamMetadata *object, const char **violation); + +/** Get the raw (binary) representation of a FLAC__StreamMetadata objeect. + * After use, free() the returned buffer. The length of the buffer is + * the length of the input metadata object plus 4 bytes for the header. + * + * \param object A pointer to metadata block to be converted. + * \assert + * \code object != NULL \endcode + * \retval FLAC__byte* + * \c NULL if there was an error, else a pointer to a buffer holding + * the requested data. + */ +FLAC_API FLAC__byte * FLAC__metadata_object_get_raw(const FLAC__StreamMetadata *object); + + +/** Turn a raw (binary) representation into a FLAC__StreamMetadata objeect. + * The returned object must be deleted with FLAC__metadata_object_delete() + * after use. + * + * \param buffer A pointer to a buffer containing a binary representation + * to be converted to a FLAC__StreamMetadata object + * \param length The length of the supplied buffer + * \retval FLAC__StreamMetadata* + * \c NULL if there was an error, else a pointer to a FLAC__StreamMetadata + * holding the requested data. + */ + +FLAC_API FLAC__StreamMetadata * FLAC__metadata_object_set_raw(FLAC__byte *buffer, FLAC__uint32 length); /* \} */ #ifdef __cplusplus diff --git a/modules/juce_audio_formats/codecs/flac/ordinals.h b/modules/juce_audio_formats/codecs/flac/ordinals.h index c62bf3a971be..81fa20103771 100644 --- a/modules/juce_audio_formats/codecs/flac/ordinals.h +++ b/modules/juce_audio_formats/codecs/flac/ordinals.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -33,26 +33,10 @@ #ifndef FLAC__ORDINALS_H #define FLAC__ORDINALS_H -#if defined(_MSC_VER) && _MSC_VER < 1600 +/* This of course assumes C99 headers */ -/* Microsoft Visual Studio earlier than the 2010 version did not provide - * the 1999 ISO C Standard header file . - */ - -typedef signed __int8 FLAC__int8; -typedef signed __int16 FLAC__int16; -typedef signed __int32 FLAC__int32; -typedef signed __int64 FLAC__int64; -typedef unsigned __int8 FLAC__uint8; -typedef unsigned __int16 FLAC__uint16; -typedef unsigned __int32 FLAC__uint32; -typedef unsigned __int64 FLAC__uint64; - -#else - -/* For MSVC 2010 and everything else which provides . */ - -//#include +#include +#include typedef int8_t FLAC__int8; typedef uint8_t FLAC__uint8; @@ -64,22 +48,8 @@ typedef uint16_t FLAC__uint16; typedef uint32_t FLAC__uint32; typedef uint64_t FLAC__uint64; -#endif - typedef int FLAC__bool; typedef FLAC__uint8 FLAC__byte; - -#ifdef true -#undef true -#endif -#ifdef false -#undef false -#endif -#ifndef __cplusplus -#define true 1 -#define false 0 -#endif - #endif diff --git a/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/metadata.h b/modules/juce_audio_formats/codecs/flac/private.h similarity index 52% rename from modules/juce_audio_formats/codecs/flac/libFLAC/include/private/metadata.h rename to modules/juce_audio_formats/codecs/flac/private.h index 8dbfa90fb76e..a043e47b3bc5 100644 --- a/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/metadata.h +++ b/modules/juce_audio_formats/codecs/flac/private.h @@ -1,6 +1,5 @@ /* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2002-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2013-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -30,17 +29,26 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef FLAC__PRIVATE__METADATA_H -#define FLAC__PRIVATE__METADATA_H +#ifndef FLAC__SHARE__PRIVATE_H +#define FLAC__SHARE__PRIVATE_H -#include "../../../metadata.h" - -/* WATCHOUT: all malloc()ed data in the block is free()ed; this may not - * be a consistent state (e.g. PICTURE) or equivalent to the initial - * state after FLAC__metadata_object_new() +/* + * Unpublished debug routines from libFLAC. This should not be used from any + * client code other than code shipped with the FLAC sources. */ -void FLAC__metadata_object_delete_data(FLAC__StreamMetadata *object); - -void FLAC__metadata_object_cuesheet_track_delete_data(FLAC__StreamMetadata_CueSheet_Track *object); +FLAC_API FLAC__bool FLAC__stream_encoder_disable_instruction_set(FLAC__StreamEncoder *encoder, int value); +FLAC_API FLAC__bool FLAC__stream_encoder_disable_constant_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value); +FLAC_API FLAC__bool FLAC__stream_encoder_disable_fixed_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value); +FLAC_API FLAC__bool FLAC__stream_encoder_disable_verbatim_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value); +/* + * The following two routines were intended as debug routines and are not + * in the public headers, but SHOULD NOT CHANGE! It is known they are used + * in some non-audio projects needing every last bit of performance. + * See https://github.com/xiph/flac/issues/547 for details. These projects + * provide their own prototypes, so changing the signature of these + * functions would break building. + */ +FLAC_API FLAC__bool FLAC__stream_encoder_set_do_md5(FLAC__StreamEncoder *encoder, FLAC__bool value); +FLAC_API FLAC__bool FLAC__stream_encoder_get_do_md5(const FLAC__StreamEncoder *encoder); -#endif +#endif /* FLAC__SHARE__PRIVATE_H */ diff --git a/modules/juce_audio_formats/codecs/flac/stream_decoder.h b/modules/juce_audio_formats/codecs/flac/stream_decoder.h index 76eb12329f9e..ff1981fcc0d6 100644 --- a/modules/juce_audio_formats/codecs/flac/stream_decoder.h +++ b/modules/juce_audio_formats/codecs/flac/stream_decoder.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -33,6 +33,7 @@ #ifndef FLAC__STREAM_DECODER_H #define FLAC__STREAM_DECODER_H +#include /* for FILE */ #include "export.h" #include "format.h" @@ -421,7 +422,11 @@ extern FLAC_API const char * const FLAC__StreamDecoderWriteStatusString[]; * could be because the decoder encountered a valid frame made by a future * version of the encoder which it cannot parse, or because of a false * sync making it appear as though an encountered frame was generated by - * a future encoder. + * a future encoder. \c FLAC__STREAM_DECODER_ERROR_STATUS_BAD_METADATA is + * caused by finding data that doesn't fit a metadata block (too large + * or too small) or finding inconsistencies in the metadata, for example + * a PICTURE block with an image that exceeds the size of the metadata + * block. */ typedef enum { @@ -434,9 +439,12 @@ typedef enum { FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH, /**< The frame's data did not match the CRC in the footer. */ - FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM + FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM, /**< The decoder encountered reserved fields in use in the stream. */ + FLAC__STREAM_DECODER_ERROR_STATUS_BAD_METADATA + /**< The decoder encountered a corrupted metadata block. */ + } FLAC__StreamDecoderErrorStatus; /** Maps a FLAC__StreamDecoderErrorStatus to a C string. @@ -673,7 +681,7 @@ typedef FLAC__bool (*FLAC__StreamDecoderEofCallback)(const FLAC__StreamDecoder * * samples of length \a frame->header.blocksize. * Channels will be ordered according to the FLAC * specification; see the documentation for the - * frame header. + * frame header. * \param client_data The callee's client data set through * FLAC__stream_decoder_init_*(). * \retval FLAC__StreamDecoderWriteStatus @@ -1005,6 +1013,16 @@ FLAC_API uint32_t FLAC__stream_decoder_get_blocksize(const FLAC__StreamDecoder * */ FLAC_API FLAC__bool FLAC__stream_decoder_get_decode_position(const FLAC__StreamDecoder *decoder, FLAC__uint64 *position); +/** Return client_data from decoder. + * The data pointed to by the pointer should not be modified. + * + * \param decoder A decoder instance. + * \retval const void * + * The callee's client data set through FLAC__stream_decoder_init_*(). + * Do not modify the contents. + */ +FLAC_API const void *FLAC__stream_decoder_get_client_data(FLAC__StreamDecoder *decoder); + /** Initialize the decoder instance to decode native FLAC streams. * * This flavor of initialization sets up the decoder to decode from a @@ -1262,11 +1280,15 @@ FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_FILE( /** Initialize the decoder instance to decode native FLAC files. * * This flavor of initialization sets up the decoder to decode from a plain - * native FLAC file. If POSIX fopen() semantics are not sufficient, (for - * example, with Unicode filenames on Windows), you must use - * FLAC__stream_decoder_init_FILE(), or FLAC__stream_decoder_init_stream() + * native FLAC file. If POSIX fopen() semantics are not sufficient, you must + * use FLAC__stream_decoder_init_FILE(), or FLAC__stream_decoder_init_stream() * and provide callbacks for the I/O. * + * On Windows, filename must be a UTF-8 encoded filename, which libFLAC + * internally translates to an appropriate representation to use with + * _wfopen. On all other systems, filename is passed to fopen without + * any translation. + * * This function should be called after FLAC__stream_decoder_new() and * FLAC__stream_decoder_set_*() but before any of the * FLAC__stream_decoder_process_*() functions. Will set and return the @@ -1304,11 +1326,15 @@ FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_file( /** Initialize the decoder instance to decode Ogg FLAC files. * * This flavor of initialization sets up the decoder to decode from a plain - * Ogg FLAC file. If POSIX fopen() semantics are not sufficient, (for - * example, with Unicode filenames on Windows), you must use + * Ogg FLAC file. If POSIX fopen() semantics are not sufficient, you must use * FLAC__stream_decoder_init_ogg_FILE(), or FLAC__stream_decoder_init_ogg_stream() * and provide callbacks for the I/O. * + * On Windows, filename must be a UTF-8 encoded filename, which libFLAC + * internally translates to an appropriate representation to use with + * _wfopen. On all other systems, filename is passed to fopen without + * any translation. + * * This function should be called after FLAC__stream_decoder_new() and * FLAC__stream_decoder_set_*() but before any of the * FLAC__stream_decoder_process_*() functions. Will set and return the diff --git a/modules/juce_audio_formats/codecs/flac/stream_encoder.h b/modules/juce_audio_formats/codecs/flac/stream_encoder.h index c14528cb4e45..6d2d1d11ef8f 100644 --- a/modules/juce_audio_formats/codecs/flac/stream_encoder.h +++ b/modules/juce_audio_formats/codecs/flac/stream_encoder.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2016 Xiph.Org Foundation + * Copyright (C) 2011-2023 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -33,6 +33,7 @@ #ifndef FLAC__STREAM_ENCODER_H #define FLAC__STREAM_ENCODER_H +#include /* for FILE */ #include "export.h" #include "format.h" #include "stream_decoder.h" @@ -128,8 +129,8 @@ extern "C" { * Unlike the decoders, the stream encoder has many options that can * affect the speed and compression ratio. When setting these parameters * you should have some basic knowledge of the format (see the - * user-level documentation - * or the formal description). The + * user-level documentation + * or the formal description). The * FLAC__stream_encoder_set_*() functions themselves do not validate the * values as many are interdependent. The FLAC__stream_encoder_init_*() * functions will do this, so make sure to pay attention to the state @@ -310,8 +311,7 @@ typedef enum { FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BITS_PER_SAMPLE, /**< The encoder has an invalid setting for bits-per-sample. - * FLAC supports 4-32 bps but the reference encoder currently supports - * only up to 24 bps. + * FLAC supports 4-32 bps. */ FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_SAMPLE_RATE, @@ -330,7 +330,7 @@ typedef enum { /**< The specified block size is less than the maximum LPC order. */ FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE, - /**< The encoder is bound to the Subset but other settings violate it. */ + /**< The encoder is bound to the Subset but other settings violate it. */ FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA, /**< The metadata input to the encoder is invalid, in one of the following ways: @@ -742,7 +742,7 @@ FLAC_API FLAC__bool FLAC__stream_encoder_set_ogg_serial_number(FLAC__StreamEncod */ FLAC_API FLAC__bool FLAC__stream_encoder_set_verify(FLAC__StreamEncoder *encoder, FLAC__bool value); -/** Set the Subset flag. If \c true, +/** Set the Subset flag. If \c true, * the encoder will comply with the Subset and will check the * settings during FLAC__stream_encoder_init_*() to see if all settings * comply. If \c false, the settings may take advantage of the full @@ -842,15 +842,15 @@ FLAC_API FLAC__bool FLAC__stream_encoder_set_sample_rate(FLAC__StreamEncoder *en * max residual partition order * rice parameter search dist * - * 0 false false tukey(0.5) 0 0 false false false 0 3 0 - * 1 true true tukey(0.5) 0 0 false false false 0 3 0 - * 2 true false tukey(0.5) 0 0 false false false 0 3 0 - * 3 false false tukey(0.5) 6 0 false false false 0 4 0 - * 4 true true tukey(0.5) 8 0 false false false 0 4 0 - * 5 true false tukey(0.5) 8 0 false false false 0 5 0 - * 6 true false tukey(0.5);partial_tukey(2) 8 0 false false false 0 6 0 - * 7 true false tukey(0.5);partial_tukey(2) 12 0 false false false 0 6 0 - * 8 true false tukey(0.5);partial_tukey(2);punchout_tukey(3) 12 0 false false false 0 6 0 + * 0 false false tukey(0.5) 0 0 false false false 0 3 0 + * 1 true true tukey(0.5) 0 0 false false false 0 3 0 + * 2 true false tukey(0.5) 0 0 false false false 0 3 0 + * 3 false false tukey(0.5) 6 0 false false false 0 4 0 + * 4 true true tukey(0.5) 8 0 false false false 0 4 0 + * 5 true false tukey(0.5) 8 0 false false false 0 5 0 + * 6 true false subdivide_tukey(2) 8 0 false false false 0 6 0 + * 7 true false subdivide_tukey(2) 12 0 false false false 0 6 0 + * 8 true false subdivide_tukey(3) 12 0 false false false 0 6 0 * * * \default \c 5 @@ -920,7 +920,7 @@ FLAC_API FLAC__bool FLAC__stream_encoder_set_loose_mid_side_stereo(FLAC__StreamE * \c blackman, \c blackman_harris_4term_92db, \c connes, \c flattop, * \c gauss(STDDEV), \c hamming, \c hann, \c kaiser_bessel, \c nuttall, * \c rectangle, \c triangle, \c tukey(P), \c partial_tukey(n[/ov[/P]]), - * \c punchout_tukey(n[/ov[/P]]), \c welch. + * \c punchout_tukey(n[/ov[/P]]), \c subdivide_tukey(n[/P]), \c welch. * * For \c gauss(STDDEV), STDDEV specifies the standard deviation * (0Subset flag. * * \param encoder An encoder instance to query. * \assert @@ -1428,6 +1458,16 @@ FLAC_API uint32_t FLAC__stream_encoder_get_rice_parameter_search_dist(const FLAC */ FLAC_API FLAC__uint64 FLAC__stream_encoder_get_total_samples_estimate(const FLAC__StreamEncoder *encoder); +/** Get the "limit_min_bitrate" flag. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__stream_encoder_set_limit_min_bitrate(). + */ +FLAC_API FLAC__bool FLAC__stream_encoder_get_limit_min_bitrate(const FLAC__StreamEncoder *encoder); + /** Initialize the encoder instance to encode native FLAC streams. * * This flavor of initialization sets up the encoder to encode to a @@ -1632,11 +1672,15 @@ FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_ogg_FILE(FLAC__ /** Initialize the encoder instance to encode native FLAC files. * * This flavor of initialization sets up the encoder to encode to a plain - * FLAC file. If POSIX fopen() semantics are not sufficient (for example, - * with Unicode filenames on Windows), you must use + * FLAC file. If POSIX fopen() semantics are not sufficient you must use * FLAC__stream_encoder_init_FILE(), or FLAC__stream_encoder_init_stream() * and provide callbacks for the I/O. * + * On Windows, filename must be a UTF-8 encoded filename, which libFLAC + * internally translates to an appropriate representation to use with + * _wfopen. On all other systems, filename is passed to fopen without + * any translation. + * * This function should be called after FLAC__stream_encoder_new() and * FLAC__stream_encoder_set_*() but before FLAC__stream_encoder_process() * or FLAC__stream_encoder_process_interleaved(). @@ -1664,11 +1708,15 @@ FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_file(FLAC__Stre /** Initialize the encoder instance to encode Ogg FLAC files. * * This flavor of initialization sets up the encoder to encode to a plain - * Ogg FLAC file. If POSIX fopen() semantics are not sufficient (for example, - * with Unicode filenames on Windows), you must use + * Ogg FLAC file. If POSIX fopen() semantics are not sufficient, you must use * FLAC__stream_encoder_init_ogg_FILE(), or FLAC__stream_encoder_init_ogg_stream() * and provide callbacks for the I/O. * + * On Windows, filename must be a UTF-8 encoded filename, which libFLAC + * internally translates to an appropriate representation to use with + * _wfopen. On all other systems, filename is passed to fopen without + * any translation. + * * This function should be called after FLAC__stream_encoder_new() and * FLAC__stream_encoder_set_*() but before FLAC__stream_encoder_process() * or FLAC__stream_encoder_process_interleaved(). @@ -1733,7 +1781,7 @@ FLAC_API FLAC__bool FLAC__stream_encoder_finish(FLAC__StreamEncoder *encoder); * * For applications where channel order is important, channels must * follow the order as described in the - * frame header. + * frame header. * * \param encoder An initialized encoder instance in the OK state. * \param buffer An array of pointers to each channel's signal. @@ -1762,7 +1810,7 @@ FLAC_API FLAC__bool FLAC__stream_encoder_process(FLAC__StreamEncoder *encoder, c * * For applications where channel order is important, channels must * follow the order as described in the - * frame header. + * frame header. * * \param encoder An initialized encoder instance in the OK state. * \param buffer An array of channel-interleaved data (see above). diff --git a/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.cpp b/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.cpp index c689bccc55ed..00eaa38236e7 100644 --- a/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.cpp +++ b/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.cpp @@ -93,7 +93,7 @@ namespace FlacNamespace #if JUCE_INCLUDE_FLAC_CODE || ! defined (JUCE_INCLUDE_FLAC_CODE) #undef PACKAGE_VERSION - #define PACKAGE_VERSION "1.3.4" + #define PACKAGE_VERSION "1.4.3" #define FLAC__NO_DLL 1 @@ -132,6 +132,15 @@ namespace FlacNamespace #define FLAC__HAS_X86INTRIN 1 #endif + #if JUCE_ARM && JUCE_64BIT + #define FLAC__CPU_ARM64 1 + + #if JUCE_USE_ARM_NEON + #define FLAC__HAS_NEONINTRIN 1 + #define FLAC__HAS_A64NEONINTRIN 1 + #endif + #endif + #define flac_max jmax #define flac_min jmin @@ -153,6 +162,7 @@ namespace FlacNamespace #include "flac/libFLAC/float.c" #include "flac/libFLAC/format.c" #include "flac/libFLAC/lpc_flac.c" + #include "flac/libFLAC/lpc_intrin_neon.c" #include "flac/libFLAC/md5.c" #include "flac/libFLAC/memory.c" #include "flac/libFLAC/stream_decoder.c" diff --git a/modules/juce_audio_plugin_client/AU/AudioUnitSDK/AUBase.h b/modules/juce_audio_plugin_client/AU/AudioUnitSDK/AUBase.h index 02f0d3d827ec..165a1663bc3f 100644 --- a/modules/juce_audio_plugin_client/AU/AudioUnitSDK/AUBase.h +++ b/modules/juce_audio_plugin_client/AU/AudioUnitSDK/AUBase.h @@ -490,7 +490,7 @@ class AUBase : public ComponentBase { if (inShouldRelease) { ioInfo.flags |= kAudioUnitParameterFlag_CFNameRelease; } - CFStringGetCString(inName, &ioInfo.name[0], offsetof(AudioUnitParameterInfo, clumpID), + CFStringGetCString(inName, std::data(ioInfo.name), std::size(ioInfo.name), kCFStringEncodingUTF8); } diff --git a/modules/juce_audio_plugin_client/AU/AudioUnitSDK/JUCE CHANGES.txt b/modules/juce_audio_plugin_client/AU/AudioUnitSDK/JUCE CHANGES.txt index df6e3ca7dc63..16f1a7723cec 100644 --- a/modules/juce_audio_plugin_client/AU/AudioUnitSDK/JUCE CHANGES.txt +++ b/modules/juce_audio_plugin_client/AU/AudioUnitSDK/JUCE CHANGES.txt @@ -1 +1,7 @@ AUScopeElement.cpp - The method AUScope::RestoreElementNames was changed to only call AUElement::SetName if the name actually changed (instead of always). This is a workaround for a Ableton Live 11 bug which crashes on duplicating AUs with more than 16 output busses. + +AUBase.h - The line that reads + CFStringGetCString(inName, std::data(ioInfo.name), std::size(ioInfo.name), ... +previously read + CFStringGetCString(inName, &ioInfo.name[0], offsetof(AudioUnitParameterInfo, clumpID), ... +This change is necessary because AudioUnitParameterInfo includes another data member between the `name` and `clumpID` members. diff --git a/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU_1.mm b/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU_1.mm index 9f5c44c78942..c1ed41aa97c9 100644 --- a/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU_1.mm +++ b/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU_1.mm @@ -89,18 +89,14 @@ // make sure the audio processor is initialized before the AUBase class struct AudioProcessorHolder { - AudioProcessorHolder (bool initialiseGUI) + AudioProcessorHolder() { - if (initialiseGUI) - initialiseJuce_GUI(); - - juceFilter = createPluginFilterOfType (AudioProcessor::wrapperType_AudioUnit); - // audio units do not have a notion of enabled or un-enabled buses juceFilter->enableAllBuses(); } - std::unique_ptr juceFilter; + ScopedJuceInitialiser_GUI scopedInitialiser; + std::unique_ptr juceFilter { createPluginFilterOfType (AudioProcessor::wrapperType_AudioUnit) }; }; //============================================================================== @@ -111,8 +107,7 @@ { public: JuceAU (AudioUnit component) - : AudioProcessorHolder (activePlugins.size() + activeUIs.size() == 0), - MusicDeviceBase (component, + : MusicDeviceBase (component, (UInt32) AudioUnitHelpers::getBusCountForWrapper (*juceFilter, true), (UInt32) AudioUnitHelpers::getBusCountForWrapper (*juceFilter, false)) { @@ -173,9 +168,6 @@ jassert (activePlugins.contains (this)); activePlugins.removeFirstMatchingValue (this); - - if (activePlugins.size() + activeUIs.size() == 0) - shutdownJuce_GUI(); } //============================================================================== @@ -1723,6 +1715,7 @@ void resizeHostWindow() } private: + ScopedJuceInitialiser_GUI scopedInitialiser; Rectangle lastBounds; JUCE_DECLARE_NON_COPYABLE (EditorCompHolder) @@ -1823,8 +1816,6 @@ static void shutdown (id self) // there's some kind of component currently modal, but the host // is trying to delete our plugin.. jassert (Component::getCurrentlyModalComponent() == nullptr); - - shutdownJuce_GUI(); } } }; diff --git a/modules/juce_audio_processors/format_types/juce_LV2PluginFormat.cpp b/modules/juce_audio_processors/format_types/juce_LV2PluginFormat.cpp index d0710fddf549..62dcd423f29e 100644 --- a/modules/juce_audio_processors/format_types/juce_LV2PluginFormat.cpp +++ b/modules/juce_audio_processors/format_types/juce_LV2PluginFormat.cpp @@ -1438,23 +1438,6 @@ class Messages final : public MessageBufferInterface
}; //============================================================================== -class LambdaTimer final : private Timer -{ -public: - explicit LambdaTimer (std::function c) : callback (c) {} - - ~LambdaTimer() noexcept override { stopTimer(); } - - using Timer::startTimer; - using Timer::startTimerHz; - using Timer::stopTimer; - -private: - void timerCallback() override { callback(); } - - std::function callback; -}; - struct UiEventListener : public MessageBufferInterface { virtual int idle() = 0; @@ -1482,7 +1465,7 @@ class ProcessorToUi final : public MessageBufferInterface private: Messages processorToUi; std::set activeUis; - LambdaTimer timer { [this] + TimedCallback timer { [this] { for (auto* l : activeUis) if (l->idle() != 0) @@ -1785,6 +1768,13 @@ class AtomPort SupportsTime time = SupportsTime::no; }; +struct FreeString { void operator() (void* ptr) const noexcept { lilv_free (ptr); } }; + +static File bundlePathFromUri (const char* uri) +{ + return File { std::unique_ptr { lilv_file_uri_parse (uri, nullptr) }.get() }; +} + class Plugins { public: @@ -1800,6 +1790,17 @@ class Plugins return lilv_plugins_get_by_uri (plugins, uri.get()); } + const LilvPlugin* getByFile (const File& file) const + { + for (const auto* plugin : *this) + { + if (bundlePathFromUri (lilv_node_as_uri (lilv_plugin_get_bundle_uri (plugin))) == file) + return plugin; + } + + return nullptr; + } + private: const LilvPlugins* plugins = nullptr; }; @@ -2135,8 +2136,6 @@ class PortMap JUCE_LEAK_DETECTOR (PortMap) }; -struct FreeString { void operator() (void* ptr) const noexcept { lilv_free (ptr); } }; - class PluginState { public: @@ -2584,11 +2583,6 @@ class UiInstanceArgs auto withPluginUri (URL v) const noexcept { return withMember (*this, &UiInstanceArgs::pluginUri, std::move (v)); } }; -static File bundlePathFromUri (const char* uri) -{ - return File { std::unique_ptr { lilv_file_uri_parse (uri, nullptr) }.get() }; -} - /* Creates and holds a UI instance for a plugin with a specific URI, using the provided descriptor. */ @@ -4324,7 +4318,7 @@ class OptionalEditor Component::SafePointer editorPointer = nullptr; String uiBundleUri; UiDescriptor uiDescriptor; - LambdaTimer changedParameterFlusher; + TimedCallback changedParameterFlusher; }; template <> @@ -5213,10 +5207,17 @@ class LV2PluginFormat::Pimpl void findAllTypesForFile (OwnedArray& result, const String& identifier) { - auto desc = getDescription (findPluginByUri (identifier)); + if (File::isAbsolutePath (identifier)) + world->loadBundle (world->newFileUri (nullptr, File::addTrailingSeparator (identifier).toRawUTF8())); - if (desc.fileOrIdentifier.isNotEmpty()) - result.add (std::make_unique (desc)); + for (const auto& plugin : { findPluginByUri (identifier), findPluginByFile (identifier) }) + { + if (auto desc = getDescription (plugin); desc.fileOrIdentifier.isNotEmpty()) + { + result.add (std::make_unique (desc)); + break; + } + } } bool fileMightContainThisPluginType (const String& file) const @@ -5226,7 +5227,7 @@ class LV2PluginFormat::Pimpl const auto numBytes = file.getNumBytesAsUTF8(); std::vector vec (numBytes + 1, 0); std::copy (data, data + numBytes, vec.begin()); - return serd_uri_string_has_scheme (vec.data()); + return serd_uri_string_has_scheme (vec.data()) || file.endsWith (".lv2"); } String getNameOfPluginFromIdentifier (const String& identifier) @@ -5488,6 +5489,11 @@ class LV2PluginFormat::Pimpl return world->getAllPlugins().getByUri (world->newUri (s.toRawUTF8())); } + const LilvPlugin* findPluginByFile (const File& f) + { + return world->getAllPlugins().getByFile (f); + } + template void visitParentClasses (const LilvPluginClass* c, Fn&& fn) const { diff --git a/modules/juce_audio_processors/format_types/juce_VST3Common.h b/modules/juce_audio_processors/format_types/juce_VST3Common.h index 48e2286a8a14..2e05413509e4 100644 --- a/modules/juce_audio_processors/format_types/juce_VST3Common.h +++ b/modules/juce_audio_processors/format_types/juce_VST3Common.h @@ -1490,12 +1490,14 @@ class MidiEventList : public Steinberg::Vst::IEventList return e; } - static Steinberg::Vst::Event createSysExEvent (const MidiMessage& msg, const uint8* midiEventData) noexcept + static Steinberg::Vst::Event createSysExEvent (const MidiMessage& msg, const uint8* data) noexcept { + jassert (msg.isSysEx()); + Steinberg::Vst::Event e{}; e.type = Steinberg::Vst::Event::kDataEvent; - e.data.bytes = midiEventData + 1; - e.data.size = (uint32) msg.getSysExDataSize(); + e.data.bytes = data; + e.data.size = (uint32) msg.getRawDataSize(); e.data.type = Steinberg::Vst::DataEvent::kMidiSysEx; return e; } @@ -1649,6 +1651,28 @@ class MidiEventList : public Steinberg::Vst::IEventList } } + static Optional toMidiMessage (const Steinberg::Vst::DataEvent& e) + { + if (e.type != Steinberg::Vst::DataEvent::kMidiSysEx || e.size < 2) + { + // Only sysex data messages can be converted to MIDI + jassertfalse; + return {}; + } + + const auto header = e.bytes[0]; + const auto footer = e.bytes[e.size - 1]; + + if (header != 0xf0 || footer != 0xf7) + { + // The sysex header/footer bytes are missing + jassertfalse; + return {}; + } + + return MidiMessage::createSysExMessage (e.bytes + 1, (int) e.size - 2); + } + static Optional toMidiMessage (const Steinberg::Vst::Event& e) { switch (e.type) @@ -1669,7 +1693,7 @@ class MidiEventList : public Steinberg::Vst::IEventList (Steinberg::uint8) denormaliseToMidiValue (e.polyPressure.pressure)); case Steinberg::Vst::Event::kDataEvent: - return MidiMessage::createSysExMessage (e.data.bytes, (int) e.data.size); + return toMidiMessage (e.data); case Steinberg::Vst::Event::kLegacyMIDICCOutEvent: return toMidiMessage (e.midiCCOut); diff --git a/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp b/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp index 107506a3e98c..be22c7daaab6 100644 --- a/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp +++ b/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp @@ -2244,7 +2244,7 @@ class ParameterChanges final : public Vst::IParameterChanges for (const auto* item : queues) { auto* ptr = item->ptr.get(); - callback (ptr->getParameterId(), ptr->get()); + callback (ptr->getParameterIndex(), ptr->getParameterId(), ptr->get()); } } @@ -2753,8 +2753,12 @@ class VST3PluginInstance final : public AudioPluginInstance processor->process (data); - outputParameterChanges->forEach ([&] (Vst::ParamID id, float value) + outputParameterChanges->forEach ([&] (Steinberg::int32 vstParamIndex, Vst::ParamID id, float value) { + // Send the parameter value from the processor to the editor + parameterDispatcher.push (vstParamIndex, value); + + // Update the host's parameter value if (auto* param = getParameterForID (id)) param->setValueWithoutUpdatingProcessor (value); }); diff --git a/modules/juce_audio_processors/juce_audio_processors.cpp b/modules/juce_audio_processors/juce_audio_processors.cpp index 71a64c38f5af..a82ed97a8482 100644 --- a/modules/juce_audio_processors/juce_audio_processors.cpp +++ b/modules/juce_audio_processors/juce_audio_processors.cpp @@ -220,7 +220,6 @@ struct NSViewComponentWithParent : public NSViewComponent, #include "utilities/juce_ParameterAttachments.cpp" #include "utilities/juce_AudioProcessorValueTreeState.cpp" #include "utilities/juce_PluginHostType.cpp" -#include "utilities/juce_NativeScaleFactorNotifier.cpp" #include "utilities/juce_AAXClientExtensions.cpp" #include "utilities/juce_VST2ClientExtensions.cpp" #include "utilities/ARA/juce_ARA_utils.cpp" diff --git a/modules/juce_audio_processors/juce_audio_processors.h b/modules/juce_audio_processors/juce_audio_processors.h index c50dfe0a08af..c039fca1c5d8 100644 --- a/modules/juce_audio_processors/juce_audio_processors.h +++ b/modules/juce_audio_processors/juce_audio_processors.h @@ -133,7 +133,6 @@ #include "utilities/juce_AAXClientExtensions.h" #include "utilities/juce_VST2ClientExtensions.h" #include "utilities/juce_VST3ClientExtensions.h" -#include "utilities/juce_NativeScaleFactorNotifier.h" #include "format_types/juce_ARACommon.h" #include "utilities/juce_ExtensionsVisitor.h" #include "processors/juce_AudioProcessorParameter.h" diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp b/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp index 078c9387fb90..675a3cfeeb5b 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp +++ b/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp @@ -541,10 +541,13 @@ void AudioProcessor::addParameterGroup (std::unique_ptr delays; + std::unordered_map delays; int totalLatency = 0; int getNodeDelay (NodeID nodeID) const noexcept { - return delays[nodeID.uid]; + const auto iter = delays.find (nodeID.uid); + return iter != delays.end() ? iter->second : 0; } int getInputLatencyForNode (const Connections& c, NodeID nodeID) const @@ -1379,7 +1380,7 @@ class RenderSequenceBuilder auto totalChans = jmax (numIns, numOuts); Array audioChannelsToUse; - auto maxLatency = getInputLatencyForNode (c, node.nodeID); + const auto maxInputLatency = getInputLatencyForNode (c, node.nodeID); for (int inputChan = 0; inputChan < numIns; ++inputChan) { @@ -1390,7 +1391,7 @@ class RenderSequenceBuilder node, inputChan, ourRenderingIndex, - maxLatency); + maxInputLatency); jassert (index >= 0); audioChannelsToUse.add (index); @@ -1413,10 +1414,11 @@ class RenderSequenceBuilder if (processor.producesMidi()) midiBuffers.getReference (midiBufferToUse).channel = { node.nodeID, midiChannelIndex }; - delays.set (node.nodeID.uid, maxLatency + processor.getLatencySamples()); + const auto thisNodeLatency = maxInputLatency + processor.getLatencySamples(); + delays[node.nodeID.uid] = thisNodeLatency; if (numOuts == 0) - totalLatency = maxLatency; + totalLatency = jmax (totalLatency, thisNodeLatency); sequence.addProcessOp (node, audioChannelsToUse, totalChans, midiBufferToUse); } @@ -1548,6 +1550,25 @@ class RenderSequence SequenceAndLatency sequence; }; +//============================================================================== +/* Holds information about the properties of a graph node at the point it was prepared. + + If the bus layout or latency of a given node changes, the graph should be rebuilt so + that channel connections are ordered correctly, and the graph's internal delay lines have + the correct delay. +*/ +class NodeAttributes +{ + auto tie() const { return std::tie (layout, latencySamples); } + +public: + AudioProcessor::BusesLayout layout; + int latencySamples = 0; + + bool operator== (const NodeAttributes& other) const { return tie() == other.tie(); } + bool operator!= (const NodeAttributes& other) const { return tie() != other.tie(); } +}; + //============================================================================== /* Holds information about a particular graph configuration, without sharing ownership of any graph nodes. Can be checked for equality with other RenderSequenceSignature instances to see @@ -1565,7 +1586,7 @@ class RenderSequenceSignature bool operator!= (const RenderSequenceSignature& other) const { return tie() != other.tie(); } private: - using NodeMap = std::map; + using NodeMap = std::map; static NodeMap getNodeMap (const Nodes& n) { @@ -1573,7 +1594,12 @@ class RenderSequenceSignature NodeMap result; for (const auto& node : nodeRefs) - result.emplace (node->nodeID, node->getProcessor()->getBusesLayout()); + { + auto* proc = node->getProcessor(); + result.emplace (node->nodeID, + NodeAttributes { proc->getBusesLayout(), + proc->getLatencySamples() }); + } return result; } @@ -1694,7 +1720,7 @@ class AudioProcessorGraph::Pimpl } Node::Ptr addNode (std::unique_ptr newProcessor, - const NodeID nodeID, + std::optional nodeID, UpdateKind updateKind) { if (newProcessor.get() == owner) @@ -1703,7 +1729,7 @@ class AudioProcessorGraph::Pimpl return nullptr; } - const auto idToUse = nodeID == NodeID() ? NodeID { ++(lastNodeID.uid) } : nodeID; + const auto idToUse = nodeID.value_or (NodeID { lastNodeID.uid + 1 }); auto added = nodes.addNode (std::move (newProcessor), idToUse); @@ -1912,7 +1938,6 @@ class AudioProcessorGraph::Pimpl } } - AudioProcessorGraph* owner = nullptr; Nodes nodes; Connections connections; @@ -1957,7 +1982,7 @@ bool AudioProcessorGraph::isAnInputTo (const Node& source, const Node& destinati bool AudioProcessorGraph::isAnInputTo (NodeID source, NodeID destination) const noexcept { return pimpl->isAnInputTo (source, destination); } AudioProcessorGraph::Node::Ptr AudioProcessorGraph::addNode (std::unique_ptr newProcessor, - NodeID nodeId, + std::optional nodeId, UpdateKind updateKind) { return pimpl->addNode (std::move (newProcessor), nodeId, updateKind); @@ -2204,6 +2229,42 @@ class AudioProcessorGraphTests final : public UnitTest } } + beginTest ("rebuilding the graph recalculates overall latency"); + { + AudioProcessorGraph graph; + + const auto nodeA = graph.addNode (BasicProcessor::make (BasicProcessor::getStereoProperties(), MidiIn::no, MidiOut::no))->nodeID; + const auto nodeB = graph.addNode (BasicProcessor::make (BasicProcessor::getStereoProperties(), MidiIn::no, MidiOut::no))->nodeID; + const auto final = graph.addNode (BasicProcessor::make (BasicProcessor::getInputOnlyProperties(), MidiIn::no, MidiOut::no))->nodeID; + + expect (graph.addConnection ({ { nodeA, 0 }, { nodeB, 0 } })); + expect (graph.addConnection ({ { nodeA, 1 }, { nodeB, 1 } })); + expect (graph.addConnection ({ { nodeB, 0 }, { final, 0 } })); + expect (graph.addConnection ({ { nodeB, 1 }, { final, 1 } })); + + expect (graph.getLatencySamples() == 0); + + // Graph isn't built, latency is 0 if prepareToPlay hasn't been called yet + const auto nodeALatency = 100; + graph.getNodeForId (nodeA)->getProcessor()->setLatencySamples (nodeALatency); + graph.rebuild(); + expect (graph.getLatencySamples() == 0); + + graph.prepareToPlay (44100, 512); + + expect (graph.getLatencySamples() == nodeALatency); + + const auto nodeBLatency = 200; + graph.getNodeForId (nodeB)->getProcessor()->setLatencySamples (nodeBLatency); + graph.rebuild(); + expect (graph.getLatencySamples() == nodeALatency + nodeBLatency); + + const auto finalLatency = 300; + graph.getNodeForId (final)->getProcessor()->setLatencySamples (finalLatency); + graph.rebuild(); + expect (graph.getLatencySamples() == nodeALatency + nodeBLatency + finalLatency); + } + beginTest ("large render sequence can be built"); { AudioProcessorGraph graph; @@ -2275,6 +2336,11 @@ class AudioProcessorGraphTests final : public UnitTest return std::make_unique (layout, midiIn, midiOut); } + static BusesProperties getInputOnlyProperties() + { + return BusesProperties().withInput ("in", AudioChannelSet::stereo()); + } + static BusesProperties getStereoProperties() { return BusesProperties().withInput ("in", AudioChannelSet::stereo()) diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h b/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h index 62dda07de409..7533a933e75f 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h +++ b/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h @@ -252,7 +252,7 @@ class JUCE_API AudioProcessorGraph : public AudioProcessor, If this succeeds, it returns a pointer to the newly-created node. */ - Node::Ptr addNode (std::unique_ptr newProcessor, NodeID nodeId = {}, UpdateKind = UpdateKind::sync); + Node::Ptr addNode (std::unique_ptr newProcessor, std::optional nodeId = std::nullopt, UpdateKind = UpdateKind::sync); /** Deletes a node within the graph which has the specified ID. This will also delete any connections that are attached to this node. diff --git a/modules/juce_audio_processors/utilities/ARA/juce_ARADocumentController.cpp b/modules/juce_audio_processors/utilities/ARA/juce_ARADocumentController.cpp index 5c505e1f44de..ef48727709d7 100644 --- a/modules/juce_audio_processors/utilities/ARA/juce_ARADocumentController.cpp +++ b/modules/juce_audio_processors/utilities/ARA/juce_ARADocumentController.cpp @@ -26,8 +26,7 @@ namespace juce { -class ARADocumentControllerSpecialisation::ARADocumentControllerImpl : public ARADocumentController, - private juce::Timer +class ARADocumentControllerSpecialisation::ARADocumentControllerImpl : public ARADocumentController { public: ARADocumentControllerImpl (const ARA::PlugIn::PlugInEntry* entry, @@ -204,10 +203,6 @@ class ARADocumentControllerSpecialisation::ARADocumentControllerImpl : public A void didUpdatePlaybackRegionProperties (ARA::PlugIn::PlaybackRegion* playbackRegion) noexcept override; void willDestroyPlaybackRegion (ARA::PlugIn::PlaybackRegion* playbackRegion) noexcept override; - //============================================================================== - // juce::Timer overrides - void timerCallback() override; - public: //============================================================================== /** @internal */ @@ -248,6 +243,9 @@ class ARADocumentControllerSpecialisation::ARADocumentControllerImpl : public A std::atomic internalAnalysisProgressIsSynced { true }; ScopedJuceInitialiser_GUI libraryInitialiser; int activeAudioSourcesCount = 0; + std::optional analysisTimer; + + void analysisTimerCallback(); //============================================================================== template @@ -363,10 +361,15 @@ void ARADocumentControllerSpecialisation::ARADocumentControllerImpl::didEndEditi { notifyListeners (&ARADocument::Listener::didEndEditing, static_cast (getDocument())); - if (isTimerRunning() && (activeAudioSourcesCount == 0)) - stopTimer(); - else if (! isTimerRunning() && (activeAudioSourcesCount > 0)) - startTimerHz (20); + if (activeAudioSourcesCount == 0) + { + analysisTimer.reset(); + } + else if (! analysisTimer.has_value() && (activeAudioSourcesCount > 0)) + { + analysisTimer.emplace ([this] { analysisTimerCallback(); }); + analysisTimer->startTimerHz (20); + } } void ARADocumentControllerSpecialisation::ARADocumentControllerImpl::willNotifyModelUpdates() noexcept @@ -760,7 +763,7 @@ namespace ModelUpdateControllerProgressAdapter } } -void ARADocumentControllerSpecialisation::ARADocumentControllerImpl::timerCallback() +void ARADocumentControllerSpecialisation::ARADocumentControllerImpl::analysisTimerCallback() { if (! internalAnalysisProgressIsSynced.exchange (true, std::memory_order_release)) for (auto& audioSource : getDocument()->getAudioSources()) diff --git a/modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.cpp b/modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.cpp index ae27633d7bcc..6d964bb0ef16 100644 --- a/modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.cpp +++ b/modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.cpp @@ -207,6 +207,63 @@ struct AudioDeviceSetupDetails static String getNoDeviceString() { return "<< " + TRANS ("none") + " >>"; } +//============================================================================== +class AudioDeviceSelectorComponent::MidiOutputSelector final : public Component, + private ChangeListener +{ +public: + explicit MidiOutputSelector (AudioDeviceManager& dm) + : deviceManager (dm) + { + deviceManager.addChangeListener (this); + selector.onChange = [&] + { + const auto selectedId = selector.getSelectedId(); + jassert (selectedId != 0); + + const auto deviceId = selectedId == -1 + ? String{} + : MidiOutput::getAvailableDevices()[selectedId - 1].identifier; + deviceManager.setDefaultMidiOutputDevice (deviceId); + }; + + updateListOfDevices(); + addAndMakeVisible (selector); + } + + ~MidiOutputSelector() final + { + deviceManager.removeChangeListener (this); + } + + void resized() final { selector.setBounds (getLocalBounds()); } + +private: + void updateListOfDevices() + { + selector.clear(); + + const auto midiOutputs = MidiOutput::getAvailableDevices(); + + selector.addItem (getNoDeviceString(), -1); + selector.setSelectedId (-1, dontSendNotification); + selector.addSeparator(); + + for (auto [id, midiOutput] : enumerate (midiOutputs, 1)) + { + selector.addItem (midiOutput.name, id); + + if (midiOutput.identifier == deviceManager.getDefaultMidiOutputIdentifier()) + selector.setSelectedId (id, dontSendNotification); + } + } + + void changeListenerCallback (ChangeBroadcaster*) final { updateListOfDevices(); } + + ComboBox selector; + AudioDeviceManager& deviceManager; +}; + //============================================================================== class AudioDeviceSettingsPanel : public Component, private ChangeListener @@ -1036,9 +1093,8 @@ AudioDeviceSelectorComponent::AudioDeviceSelectorComponent (AudioDeviceManager& if (showMidiOutputSelector) { - midiOutputSelector = std::make_unique(); + midiOutputSelector = std::make_unique (deviceManager); addAndMakeVisible (midiOutputSelector.get()); - midiOutputSelector->onChange = [this] { updateMidiOutput(); }; midiOutputLabel = std::make_unique