From 10e5bc7aff742fd3b280e2100f88f3944fa0d20d Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Thu, 26 Mar 2026 15:29:23 +0100 Subject: [PATCH 01/74] feat: add Mac Debug Perfetto configuration for macOS --- CMakePresets.json | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/CMakePresets.json b/CMakePresets.json index c73292db..01c4ab2c 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -92,6 +92,29 @@ "rhs": "Darwin" } }, + { + "name": "Mac Debug Perfetto", + "hidden": false, + "description": "Debug configuration for macOS", + "generator": "Ninja", + "binaryDir": "${sourceDir}/build", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_C_COMPILER": "/usr/bin/clang", + "CMAKE_CXX_COMPILER": "/usr/bin/clang++", + "CMAKE_OSX_DEPLOYMENT_TARGET": "10.15", + "CMAKE_CXX_FLAGS": "/DPERFETTO=1" + }, + "environment": { + "CC": "/usr/bin/clang", + "CXX": "/usr/bin/clang++" + }, + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Darwin" + } + }, { "name": "Mac Release", "hidden": false, From 3f48d6396eba2ad298a0cf187106dc15ce9a03e8 Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Thu, 26 Mar 2026 15:51:21 +0100 Subject: [PATCH 02/74] feat: enhance shadow rendering with melatonin library integration --- src/dmt/gui/widget/Shadow.h | 38 ++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/src/dmt/gui/widget/Shadow.h b/src/dmt/gui/widget/Shadow.h index 53aff869..0b0c8f9e 100644 --- a/src/dmt/gui/widget/Shadow.h +++ b/src/dmt/gui/widget/Shadow.h @@ -33,6 +33,7 @@ #include "utility/Scaleable.h" #include "utility/Settings.h" #include +#include //============================================================================== @@ -228,15 +229,8 @@ class Shadow inline void drawInnerForPath(juce::Graphics& _g, juce::Path _target) { TRACER("Shadow::drawInnerForPath"); - juce::Graphics::ScopedSaveState saveState(_g); - juce::Path shadowPath(_target); - shadowPath.addRectangle(_target.getBounds().expanded(10 * scale)); - shadowPath.setUsingNonZeroWinding(false); - _g.reduceClipRegion(_target); - juce::DropShadow ds(*colour, - static_cast(radius * size * scale), - offset * scale); // dereference pointer - ds.drawForPath(_g, shadowPath); + updateShadowParameters(); + innerShadowRenderer.render(_g, _target); } //============================================================================== @@ -258,13 +252,28 @@ class Shadow shadowPath.addRectangle(_target.getBounds().expanded(10 * scale)); shadowPath.setUsingNonZeroWinding(false); _g.reduceClipRegion(shadowPath); - juce::DropShadow ds(*colour, - static_cast(radius * size * scale), - offset * scale); // dereference pointer - ds.drawForPath(_g, _target); + updateShadowParameters(); + outerShadowRenderer.render(_g, _target); } private: + inline void updateShadowParameters() + { + const auto scaledRadius = static_cast(radius * size * scale); + const auto scaledOffset = juce::Point( + static_cast(offset.x) * static_cast(scale), + static_cast(offset.y) * static_cast(scale)); + + if (inner) { + innerShadowRenderer.setColor(*colour).setRadius(scaledRadius).setOffset( + scaledOffset); + return; + } + + outerShadowRenderer.setColor(*colour).setRadius(scaledRadius).setOffset( + scaledOffset); + } + inline void refreshCachedImageIfNeeded(bool forceRepaint = false) { if (getWidth() == 0 || getHeight() == 0) @@ -303,6 +312,9 @@ class Shadow bool needsRepaint = true; float lastRenderedScale = 0.0f; + melatonin::DropShadow outerShadowRenderer; + melatonin::InnerShadow innerShadowRenderer; + Image image = Image(PixelFormat::ARGB, 1, 1, true); //============================================================================== From 804e10a1675920ad92ce3c4bb19f36f3eb171b95 Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Fri, 27 Mar 2026 08:17:39 +0100 Subject: [PATCH 03/74] refactor: reorder components in AbstractButton for improved rendering --- src/dmt/gui/widget/AbstractButton.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/dmt/gui/widget/AbstractButton.h b/src/dmt/gui/widget/AbstractButton.h index af2071f5..34416f14 100644 --- a/src/dmt/gui/widget/AbstractButton.h +++ b/src/dmt/gui/widget/AbstractButton.h @@ -140,6 +140,13 @@ class AbstractButton hoverIconImageComponent.setVisible(false); addMouseListener(this, true); + + // Reorder the components + innerShadow.toBack(); + outerShadow.toBack(); + clickedBackgroundImageComponent.toBack(); + hoverBackgroundImageComponent.toBack(); + backgroundImageComponent.toBack(); } //============================================================================== @@ -292,13 +299,6 @@ class AbstractButton innerShadowPath.addRoundedRectangle(_innerBounds, _cornerRadius); innerShadow.setPath(innerShadowPath); innerShadow.setBoundsRelative(0.0f, 0.0f, 1.0f, 1.0f); - - // Reorder the components - innerShadow.toBack(); - outerShadow.toBack(); - clickedBackgroundImageComponent.toBack(); - hoverBackgroundImageComponent.toBack(); - backgroundImageComponent.toBack(); } //============================================================================== From aa8948ec06e0adaaddfdc38c2ef8b72495bd741d Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Fri, 27 Mar 2026 08:37:55 +0100 Subject: [PATCH 04/74] performance: Optimize size factor propagation in Compositor and AbstractButton --- external/dmt | 1 + src/dmt/gui/widget/AbstractButton.h | 16 +++++++++++++++- src/dmt/gui/window/Compositor.h | 19 +++++++++++++++++++ src/dmt/utility/Scaleable.h | 2 +- 4 files changed, 36 insertions(+), 2 deletions(-) create mode 160000 external/dmt diff --git a/external/dmt b/external/dmt new file mode 160000 index 00000000..dc66506a --- /dev/null +++ b/external/dmt @@ -0,0 +1 @@ +Subproject commit dc66506a83c1b38f3a255c042ef1fdd4562c2509 diff --git a/src/dmt/gui/widget/AbstractButton.h b/src/dmt/gui/widget/AbstractButton.h index 34416f14..365f12bb 100644 --- a/src/dmt/gui/widget/AbstractButton.h +++ b/src/dmt/gui/widget/AbstractButton.h @@ -171,8 +171,19 @@ class AbstractButton TRACER("AbstractButton::resized"); auto bounds = getLocalBounds(); const auto buttonPadding = rawButtonPadding * size; - auto innerBounds = bounds.reduced(buttonPadding); + const auto innerBounds = bounds.reduced(buttonPadding); const auto cornerRadius = rawCornerRadius * size; + const auto currentScale = static_cast(scale); + + if (innerBounds == lastInnerBounds && + juce::approximatelyEqual(cornerRadius, lastCornerRadius) && + juce::approximatelyEqual(currentScale, lastScaleFactor)) { + return; + } + + lastInnerBounds = innerBounds; + lastCornerRadius = cornerRadius; + lastScaleFactor = currentScale; setShadowBounds(innerBounds, cornerRadius); setBackgroundBounds(innerBounds); @@ -472,6 +483,9 @@ class AbstractButton ImageComponent iconImageComponent; Image hoverIconImage; ImageComponent hoverIconImageComponent; + juce::Rectangle lastInnerBounds; + float lastCornerRadius = -1.0f; + float lastScaleFactor = -1.0f; //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(AbstractButton) diff --git a/src/dmt/gui/window/Compositor.h b/src/dmt/gui/window/Compositor.h index 20eb5be7..a5fbf245 100644 --- a/src/dmt/gui/window/Compositor.h +++ b/src/dmt/gui/window/Compositor.h @@ -178,6 +178,7 @@ class Compositor void resized() noexcept override { TRACER("Compositor::resized"); + propagateSizeFactor(); const auto bounds = getLocalBounds(); // Alerts @@ -408,6 +409,8 @@ class Compositor TRACER("Compositor::resetSettingsCallback"); properties.resetToFallback(); + propagateSizeFactor(); + // Gotta call this first to recalculate the global size const auto& parent = getParentComponent(); if (parent != nullptr) { @@ -462,6 +465,7 @@ class Compositor void valueEditorListenerCallback() override { TRACER("Compositor::valueEditorListenerCallback"); + propagateSizeFactor(); resizedRecursively(this); } @@ -572,6 +576,15 @@ class Compositor void propagateSizeFactor() noexcept { TRACER("Compositor::propagateSizeFactor"); + if (isPropagatingSizeFactor) + return; + + if (juce::approximatelyEqual(lastPropagatedSizeFactor, sizeFactor)) + return; + + const juce::ScopedValueSetter isPropagatingGuard( + isPropagatingSizeFactor, true); + lastPropagatedSizeFactor = sizeFactor; setSizeFactorRecursively(this); } @@ -656,6 +669,7 @@ class Compositor { if (!c) return; + c->removeComponentListener(this); c->addComponentListener(this); for (auto* child : c->getChildren()) if (auto* cc = dynamic_cast(child)) @@ -737,6 +751,9 @@ class Compositor */ void componentChildrenChanged(juce::Component& component) override { + if (isPropagatingSizeFactor) + return; + addListenerToChildren(&component); propagateSizeFactor(); } @@ -759,6 +776,8 @@ class Compositor int baseHeight = 0; int baseWidth = 0; const float& sizeFactor; + float lastPropagatedSizeFactor = std::numeric_limits::quiet_NaN(); + bool isPropagatingSizeFactor = false; //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Compositor) diff --git a/src/dmt/utility/Scaleable.h b/src/dmt/utility/Scaleable.h index c1018446..47c4b1cb 100644 --- a/src/dmt/utility/Scaleable.h +++ b/src/dmt/utility/Scaleable.h @@ -282,7 +282,7 @@ class Scaleable : public IScaleable */ void setSizeFactor(const float& newSize) noexcept override { - if (&newSize != &internalSize) { + if (!juce::approximatelyEqual(newSize, internalSize)) { internalSize = newSize; } } From cb8300e19d03152028110fe28e480e1be1a1244e Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Fri, 27 Mar 2026 10:18:50 +0100 Subject: [PATCH 05/74] docs: Remove implemented todos from README.md --- README.md | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 0c8c3da4..9677fd24 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,6 @@ If it feels familiar, that's no accident. Disflux is a lovingly crafted take on Image of the GUI - ## πŸ”₯ Features - **Free & Open-Source** – No paywalls, no restrictions. @@ -27,10 +26,8 @@ If it feels familiar, that's no accident. Disflux is a lovingly crafted take on ## 🚧 Coming Soon Here are some of the exciting things you can expect in future updates: - -- **Bug Fixes** – We are actively working on fixing bugs and improving stability. + - **Preset Menu** – Add functionality to select and save presets. -- **Performance** – While performance is already solid, we’re working to optimize it even further. - **Oversampling** – Implementing oversampling to minimize aliasing and improve the quality of high-frequency content. - **Themes** - We already allow heavy theming, but we want to make it easier to export and share themes with the community. - **Mobile Support** – We are planning to release Disflux for iOS and Android in the future. @@ -54,21 +51,25 @@ If you want to compile Plasma from source yourself, follow these steps: ### 1. Prerequisites **Ubuntu** + - Install build tools: `sudo apt-get install build-essential cmake ninja-build` - Install dependencies: `sudo apt install libasound2-dev libjack-jackd2-dev ladspa-sdk libcurl4-openssl-dev libfreetype-dev libfontconfig1-dev libx11-dev libxcomposite-dev libxcursor-dev libxext-dev libxinerama-dev libxrandr-dev libxrender-dev libwebkit2gtk-4.1-dev libglu1-mesa-dev mesa-common-dev curl` -**MacOS** +**MacOS** + 1. Install [Homebrew](https://brew.sh/) 2. Install build tools: `brew install ninja osxutils` **Windows** + 1. Install [Git](https://git-scm.com/downloads) 2. Install [Visual Studio Build Tools](https://visualstudio.microsoft.com/visual-cpp-build-tools/). - - During installation, make sure to select package "Desktop development with C++" -4. Install [Chocolatey](https://chocolatey.org/install) (open **PowerShell** as Admin and follow instructions on their site) -5. Use **Chocolatey** to install required tools: `choco install cmake ninja llvm` - + - During installation, make sure to select package "Desktop development with C++" +3. Install [Chocolatey](https://chocolatey.org/install) (open **PowerShell** as Admin and follow instructions on their site) +4. Use **Chocolatey** to install required tools: `choco install cmake ninja llvm` + ### 2. Clone the Repository + ```bash git clone https://github.com/yourusername/Disflux.git cd Disflux @@ -79,16 +80,19 @@ cd Disflux Run CMake to configure the project. Use the appropriate preset for your platform: **Ubuntu** + ```bash cmake --preset "Linux Release" ``` **MacOS** + ```bash cmake --preset "Mac Release" -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" ``` **Windows** + ```bash cmake --preset "Windows Release" ``` @@ -96,6 +100,7 @@ cmake --preset "Windows Release" ### 4. Build the project After configuring with CMake, build the project using the following command: + ```bash cmake --build build --config "Release" ``` @@ -103,6 +108,7 @@ cmake --build build --config "Release" ### 5. Locate the Build Artifacts After the build process completes, you can find the compiled artifacts in the build directory under the following paths: + - **VST3:** `build/src/DisfluxPlugin_artefacts/Release/VST3/Disflux.vst3` - **CLAP:** `build/src/DisfluxPlugin_artefacts/Release/CLAP/Disflux.clap` - **LV2:** `build/src/DisfluxPlugin_artefacts/Release/LV2/Disflux.lv2` @@ -110,7 +116,6 @@ After the build process completes, you can find the compiled artifacts in the bu You can move these to your plugin folder. - ## πŸ” Privacy **Disflux** is built with privacy in mind. It **does not collect any personal data** or send any telemetry. We are committed to **never sharing or selling your data**. It makes us sad that in today's day and age, we consider this to be a standout point, but here we are. From 88dedba5a513625a19f80ab644442e2e918f510a Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Fri, 27 Mar 2026 10:19:21 +0100 Subject: [PATCH 06/74] chore: update project version to 1.2.0 in CI workflows and CMakeLists --- .github/workflows/ci-development.yml | 2 +- .github/workflows/ci-release.yml | 2 +- .github/workflows/ci-snapshot.yml | 2 +- CMakeLists.txt | 2 +- src/CMakeLists.txt | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci-development.yml b/.github/workflows/ci-development.yml index 030a9ce8..f56e9120 100644 --- a/.github/workflows/ci-development.yml +++ b/.github/workflows/ci-development.yml @@ -20,7 +20,7 @@ env: PROJECT_NAME: Disflux BUNDLE_NAME: disflux BUNDLE_ID: com.dimethoxy.disflux - VERSION: 1.1.2 # Disflux-Version + VERSION: 1.2.0 # Disflux-Version BUILD_DIR: build DISPLAY: :0 # Linux pluginval needs this HOMEBREW_NO_INSTALL_CLEANUP: 1 diff --git a/.github/workflows/ci-release.yml b/.github/workflows/ci-release.yml index 767aa31e..a5849b25 100644 --- a/.github/workflows/ci-release.yml +++ b/.github/workflows/ci-release.yml @@ -20,7 +20,7 @@ env: PROJECT_NAME: Disflux BUNDLE_NAME: disflux BUNDLE_ID: com.dimethoxy.disflux - VERSION: 1.1.2 # Disflux-Version + VERSION: 1.2.0 # Disflux-Version BUILD_DIR: build DISPLAY: :0 # Linux pluginval needs this HOMEBREW_NO_INSTALL_CLEANUP: 1 diff --git a/.github/workflows/ci-snapshot.yml b/.github/workflows/ci-snapshot.yml index e5626a4c..2a2c848b 100644 --- a/.github/workflows/ci-snapshot.yml +++ b/.github/workflows/ci-snapshot.yml @@ -22,7 +22,7 @@ env: PROJECT_NAME: Disflux BUNDLE_NAME: disflux BUNDLE_ID: com.dimethoxy.disflux - VERSION: 1.1.2 # Disflux-Version + VERSION: 1.2.0 # Disflux-Version BUILD_DIR: build DISPLAY: :0 # Linux pluginval needs this HOMEBREW_NO_INSTALL_CLEANUP: 1 diff --git a/CMakeLists.txt b/CMakeLists.txt index 9a818828..47cdb62d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ #============================================================================== cmake_minimum_required(VERSION 3.30) -project(Disflux VERSION 1.1.2) # Disflux-Version +project(Disflux VERSION 1.2.0) # Disflux-Version set(CMAKE_CXX_STANDARD 23) set(CMAKE_SUPPRESS_DEVELOPER_WARNINGS TRUE) set(EXT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 92828bcd..c78e0655 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,7 +3,7 @@ #============================================================================== cmake_minimum_required(VERSION 3.22) -project(DisfluxPlugin VERSION 1.1.2) # Disflux-Version +project(DisfluxPlugin VERSION 1.2.0) # Disflux-Version # If we are on MacOS, we need to build for arm64 and x86_64 if (APPLE) From 53c39c2ba26212ffaa35da3d16a774885e369c2c Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Fri, 27 Mar 2026 10:28:53 +0100 Subject: [PATCH 07/74] chore: update subproject commits for dmt and melatonin_blur --- external/melatonin_blur | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external/melatonin_blur b/external/melatonin_blur index f5764e3a..989a6e1f 160000 --- a/external/melatonin_blur +++ b/external/melatonin_blur @@ -1 +1 @@ -Subproject commit f5764e3a5c98f7b2849fe4c9c2205a854a658fa3 +Subproject commit 989a6e1f8d79b7183c9daa6271cb71f7f8800229 From 93fbdcf2852e34e6ffc862b0bc568d175b797f7c Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Fri, 27 Mar 2026 13:38:31 +0100 Subject: [PATCH 08/74] refactor: Move code from PluginProcessor to AbstractPluginProcessor --- .vscode/c_cpp_properties.json | 5 +- external/dmt | 1 - src/app/PluginProcessor.cpp | 154 ++----------------------- src/app/PluginProcessor.h | 33 +----- src/dmt/DmtHeader.h | 1 + src/dmt/app/AbstractPluginProcessor.h | 155 +++++++++++++++++++++++++- 6 files changed, 169 insertions(+), 180 deletions(-) delete mode 160000 external/dmt diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 4d49ce61..76689a51 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -2,9 +2,10 @@ "configurations": [ { "name": "Linux", + "compileCommands": "${workspaceFolder}/build/compile_commands.json", "includePath": [ - "${workspaceFolder}/external/**", - "${workspaceFolder}/src/**" + "${workspaceFolder}/src/**", + "${workspaceFolder}/external/**" ], "defines": [], "compilerPath": "/usr/bin/clang", diff --git a/external/dmt b/external/dmt deleted file mode 160000 index dc66506a..00000000 --- a/external/dmt +++ /dev/null @@ -1 +0,0 @@ -Subproject commit dc66506a83c1b38f3a255c042ef1fdd4562c2509 diff --git a/src/app/PluginProcessor.cpp b/src/app/PluginProcessor.cpp index db64a27a..051c26a3 100644 --- a/src/app/PluginProcessor.cpp +++ b/src/app/PluginProcessor.cpp @@ -3,16 +3,7 @@ #include "PluginEditor.h" //============================================================================== PluginProcessor::PluginProcessor() - : AudioProcessor( - BusesProperties() -#if !JucePlugin_IsMidiEffect -#if !JucePlugin_IsSynth - .withInput("Input", juce::AudioChannelSet::stereo(), true) -#endif - .withOutput("Output", juce::AudioChannelSet::stereo(), true) -#endif - ) - , apvts(*this, nullptr, ProjectInfo::projectName, createParameterLayout()) + : dmt::app::AbstractPluginProcessor(createParameterLayout) , oscilloscopeBuffer(2, 4096) , disfluxProcessor(apvts, dmt::Settings::Audio::frequencySmoothness, @@ -22,18 +13,10 @@ PluginProcessor::PluginProcessor() dmt::Settings::Audio::outputHighpassFrequency, dmt::Settings::Audio::smoothingInterval) { -#if PERFETTO - MelatoninPerfetto::get().beginSession(); -#endif properties.initialize(); } -PluginProcessor::~PluginProcessor() -{ -#if PERFETTO - MelatoninPerfetto::get().endSession(); -#endif -} +PluginProcessor::~PluginProcessor() = default; //============================================================================== const juce::String @@ -42,75 +25,6 @@ PluginProcessor::getName() const return "Disflux"; } -bool -PluginProcessor::acceptsMidi() const -{ -#if JucePlugin_WantsMidiInput - return true; -#else - return false; -#endif -} - -bool -PluginProcessor::producesMidi() const -{ -#if JucePlugin_ProducesMidiOutput - return true; -#else - return false; -#endif -} - -bool -PluginProcessor::isMidiEffect() const -{ -#if JucePlugin_IsMidiEffect - return true; -#else - return false; -#endif -} - -double -PluginProcessor::getTailLengthSeconds() const -{ - return 0.0; -} - -int -PluginProcessor::getNumPrograms() -{ - return 1; // NB: some hosts don't cope very well if you tell them there are 0 - // programs, so this should be at least 1, even if you're not really - // implementing programs. -} - -int -PluginProcessor::getCurrentProgram() -{ - return 0; -} - -void -PluginProcessor::setCurrentProgram(int index) -{ - juce::ignoreUnused(index); -} - -const juce::String -PluginProcessor::getProgramName(int index) -{ - juce::ignoreUnused(index); - return {}; -} - -void -PluginProcessor::changeProgramName(int index, const juce::String& newName) -{ - juce::ignoreUnused(index, newName); -} - //============================================================================== void PluginProcessor::prepareToPlay(double sampleRate, int samplesPerBlock) @@ -120,6 +34,7 @@ PluginProcessor::prepareToPlay(double sampleRate, int samplesPerBlock) disfluxProcessor.prepare(sampleRate); } +//============================================================================== void PluginProcessor::releaseResources() { @@ -127,51 +42,22 @@ PluginProcessor::releaseResources() // spare memory, etc. } -bool -PluginProcessor::isBusesLayoutSupported(const BusesLayout& layouts) const -{ -#if JucePlugin_IsMidiEffect - juce::ignoreUnused(layouts); - return true; -#else - // This is the place where you check if the layout is supported. - // In this template code we only support mono or stereo. - // Some plugin hosts, such as certain GarageBand versions, will only - // load plugins that support stereo bus layouts. - if (layouts.getMainOutputChannelSet() != juce::AudioChannelSet::mono() && - layouts.getMainOutputChannelSet() != juce::AudioChannelSet::stereo()) - return false; - - // This checks if the input layout matches the output layout -#if !JucePlugin_IsSynth - if (layouts.getMainOutputChannelSet() != layouts.getMainInputChannelSet()) - return false; -#endif - - return true; -#endif -} - +//============================================================================== void PluginProcessor::processBlock(juce::AudioBuffer& buffer, juce::MidiBuffer& midiMessages) { + // Boilerplate juce::ignoreUnused(midiMessages); juce::ScopedNoDenormals noDenormals; auto totalNumInputChannels = getTotalNumInputChannels(); auto totalNumOutputChannels = getTotalNumOutputChannels(); - // In case we have more outputs than inputs, this code clears any output - // channels that didn't contain input data, (because these aren't - // guaranteed to be empty - they may contain garbage). - // This is here to avoid people getting screaming feedback - // when they first compile a plugin, but obviously you don't need to keep - // this code if your algorithm always overwrites all the output channels. for (auto i = totalNumInputChannels; i < totalNumOutputChannels; ++i) buffer.clear(i, 0, buffer.getNumSamples()); - //============================================================================ + // Start actual processing TRACE_DSP(); const auto* bypassParam = apvts.getRawParameterValue("GlobalBypass"); bool isBypassed = bypassParam->load() > 0.5f; @@ -183,39 +69,17 @@ PluginProcessor::processBlock(juce::AudioBuffer& buffer, } //============================================================================== -bool -PluginProcessor::hasEditor() const -{ - return true; // (change this to false if you choose to not supply an editor) -} - +// This creates new instances of the plugin.. juce::AudioProcessorEditor* PluginProcessor::createEditor() { return new PluginEditor(*this); } -//============================================================================== -void -PluginProcessor::getStateInformation(juce::MemoryBlock& destData) -{ - juce::MemoryOutputStream mos(destData, true); - apvts.state.writeToStream(mos); -} - -void -PluginProcessor::setStateInformation(const void* data, int sizeInBytes) -{ - auto tree = juce::ValueTree::readFromData(data, sizeInBytes); - if (tree.isValid()) { - apvts.replaceState(tree); - } -} - -//============================================================================== -// This creates new instances of the plugin.. juce::AudioProcessor* JUCE_CALLTYPE createPluginFilter() { return new PluginProcessor(); } + +// KEEP diff --git a/src/app/PluginProcessor.h b/src/app/PluginProcessor.h index 8c668042..b5cbd216 100644 --- a/src/app/PluginProcessor.h +++ b/src/app/PluginProcessor.h @@ -5,7 +5,7 @@ #include //============================================================================== -class PluginProcessor final : public juce::AudioProcessor +class PluginProcessor final : public dmt::app::AbstractPluginProcessor { public: //============================================================================== @@ -13,39 +13,13 @@ class PluginProcessor final : public juce::AudioProcessor ~PluginProcessor() override; //============================================================================== + const juce::String getName() const override; void prepareToPlay(double sampleRate, int samplesPerBlock) override; void releaseResources() override; - - bool isBusesLayoutSupported(const BusesLayout& layouts) const override; - void processBlock(juce::AudioBuffer&, juce::MidiBuffer&) override; - using AudioProcessor::processBlock; //============================================================================== juce::AudioProcessorEditor* createEditor() override; - bool hasEditor() const override; - - //============================================================================== - const juce::String getName() const override; - - bool acceptsMidi() const override; - bool producesMidi() const override; - bool isMidiEffect() const override; - double getTailLengthSeconds() const override; - - //============================================================================== - int getNumPrograms() override; - int getCurrentProgram() override; - void setCurrentProgram(int index) override; - const juce::String getProgramName(int index) override; - void changeProgramName(int index, const juce::String& newName) override; - - //============================================================================== - void getStateInformation(juce::MemoryBlock& destData) override; - void setStateInformation(const void* data, int sizeInBytes) override; - - //============================================================================== - juce::AudioProcessorValueTreeState apvts; //============================================================================== dmt::configuration::Properties properties; @@ -62,9 +36,6 @@ class PluginProcessor final : public juce::AudioProcessor void setSizeFactor(float newSize) { sizeFactor = newSize; } private: -#if PERFETTO - std::unique_ptr tracingSession; -#endif //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginProcessor) }; diff --git a/src/dmt/DmtHeader.h b/src/dmt/DmtHeader.h index b3390cb6..52f895ff 100644 --- a/src/dmt/DmtHeader.h +++ b/src/dmt/DmtHeader.h @@ -17,6 +17,7 @@ //============================================================================== #include "../melatonin_perfetto/melatonin_perfetto/melatonin_perfetto.h" //============================================================================== +#include "./app/App.h" #include "./configuration/Configuration.h" #include "./dsp/Dsp.h" #include "./gui/Gui.h" diff --git a/src/dmt/app/AbstractPluginProcessor.h b/src/dmt/app/AbstractPluginProcessor.h index e743115c..b6b1e434 100644 --- a/src/dmt/app/AbstractPluginProcessor.h +++ b/src/dmt/app/AbstractPluginProcessor.h @@ -1,3 +1,156 @@ #pragma once -#include \ No newline at end of file +#include + +namespace dmt { +namespace app { +class AbstractPluginProcessor : public juce::AudioProcessor +{ +public: + //============================================================================== + AbstractPluginProcessor( + std::function + createParameterLayout) + : AudioProcessor( + BusesProperties() +#if !JucePlugin_IsMidiEffect +#if !JucePlugin_IsSynth + .withInput("Input", juce::AudioChannelSet::stereo(), true) +#endif + .withOutput("Output", juce::AudioChannelSet::stereo(), true) +#endif + ) + , apvts(*this, nullptr, ProjectInfo::projectName, createParameterLayout()) + { +#if PERFETTO + MelatoninPerfetto::get().beginSession(); +#endif + } + + //============================================================================== + ~AbstractPluginProcessor() override + { +#if PERFETTO + MelatoninPerfetto::get().endSession(); +#endif + } + + //============================================================================== + // Program Management + + double getTailLengthSeconds() const { return 0.0; } + + int getNumPrograms() + { + return 1; // NB: some hosts don't cope very well if you tell them there are + // 0 programs, so this should be at least 1, even if you're not + // really implementing programs. + } + + int getCurrentProgram() { return 0; } + + void setCurrentProgram(int index) { juce::ignoreUnused(index); } + + const juce::String getProgramName(int index) + { + juce::ignoreUnused(index); + return {}; + } + + void changeProgramName(int index, const juce::String& newName) + { + juce::ignoreUnused(index, newName); + } + + //============================================================================== + // Midi + + bool acceptsMidi() const override + { +#if JucePlugin_WantsMidiInput + return true; +#else + return false; +#endif + } + bool producesMidi() const override + { +#if JucePlugin_ProducesMidiOutput + return true; +#else + return false; +#endif + } + + bool isMidiEffect() const override + { +#if JucePlugin_IsMidiEffect + return true; +#else + return false; +#endif + } + + //============================================================================== + // Preset Save/Load + + void getStateInformation(juce::MemoryBlock& destData) override + { + juce::MemoryOutputStream mos(destData, true); + apvts.state.writeToStream(mos); + } + + void setStateInformation(const void* data, int sizeInBytes) override + { + auto tree = juce::ValueTree::readFromData(data, sizeInBytes); + if (tree.isValid()) { + apvts.replaceState(tree); + } + } + + //============================================================================== + // + + bool isBusesLayoutSupported(const BusesLayout& layouts) const + { +#if JucePlugin_IsMidiEffect + juce::ignoreUnused(layouts); + return true; +#else + // This is the place where you check if the layout is supported. + // In this template code we only support mono or stereo. + // Some plugin hosts, such as certain GarageBand versions, will only + // load plugins that support stereo bus layouts. + if (layouts.getMainOutputChannelSet() != juce::AudioChannelSet::mono() && + layouts.getMainOutputChannelSet() != juce::AudioChannelSet::stereo()) + return false; + + // This checks if the input layout matches the output layout +#if !JucePlugin_IsSynth + if (layouts.getMainOutputChannelSet() != layouts.getMainInputChannelSet()) + return false; +#endif + + return true; +#endif + } + + bool hasEditor() const + { + return true; // (change this to false if you choose to not supply an editor) + } + +public: + //============================================================================== + juce::AudioProcessorValueTreeState apvts; + +private: +#if PERFETTO + std::unique_ptr tracingSession; +#endif + + //============================================================================== + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(AbstractPluginProcessor) +}; +} +} \ No newline at end of file From 714f2811e2db822b1ba0332a19ead4474593816d Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Fri, 27 Mar 2026 13:43:53 +0100 Subject: [PATCH 09/74] refactor: Move properties and version manager to AbstractPluginProcessor --- src/app/PluginProcessor.cpp | 3 --- src/app/PluginProcessor.h | 10 ---------- src/dmt/app/AbstractPluginProcessor.h | 13 +++++++++++++ 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/app/PluginProcessor.cpp b/src/app/PluginProcessor.cpp index 051c26a3..d882ef6c 100644 --- a/src/app/PluginProcessor.cpp +++ b/src/app/PluginProcessor.cpp @@ -13,7 +13,6 @@ PluginProcessor::PluginProcessor() dmt::Settings::Audio::outputHighpassFrequency, dmt::Settings::Audio::smoothingInterval) { - properties.initialize(); } PluginProcessor::~PluginProcessor() = default; @@ -81,5 +80,3 @@ createPluginFilter() { return new PluginProcessor(); } - -// KEEP diff --git a/src/app/PluginProcessor.h b/src/app/PluginProcessor.h index b5cbd216..e1ec9ee5 100644 --- a/src/app/PluginProcessor.h +++ b/src/app/PluginProcessor.h @@ -21,20 +21,10 @@ class PluginProcessor final : public dmt::app::AbstractPluginProcessor //============================================================================== juce::AudioProcessorEditor* createEditor() override; - //============================================================================== - dmt::configuration::Properties properties; - dmt::version::Manager versionManager; - //============================================================================== dmt::dsp::data::FifoAudioBuffer oscilloscopeBuffer; dmt::dsp::effect::DisfluxProcessor disfluxProcessor; - //============================================================================== - // Store scale factor for editor window - float sizeFactor = 1.0f; - float getSizeFactor() const { return sizeFactor; } - void setSizeFactor(float newSize) { sizeFactor = newSize; } - private: //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginProcessor) diff --git a/src/dmt/app/AbstractPluginProcessor.h b/src/dmt/app/AbstractPluginProcessor.h index b6b1e434..ad653104 100644 --- a/src/dmt/app/AbstractPluginProcessor.h +++ b/src/dmt/app/AbstractPluginProcessor.h @@ -1,5 +1,7 @@ #pragma once +#include "configuration/Properties.h" +#include "version/Manager.h" #include namespace dmt { @@ -25,6 +27,7 @@ class AbstractPluginProcessor : public juce::AudioProcessor #if PERFETTO MelatoninPerfetto::get().beginSession(); #endif + properties.initialize(); } //============================================================================== @@ -144,6 +147,16 @@ class AbstractPluginProcessor : public juce::AudioProcessor //============================================================================== juce::AudioProcessorValueTreeState apvts; + //============================================================================== + dmt::configuration::Properties properties; + dmt::version::Manager versionManager; + + //============================================================================== + float sizeFactor = 1.0f; + float getSizeFactor() const { return sizeFactor; } + void setSizeFactor(float newSize) { sizeFactor = newSize; } + + //============================================================================== private: #if PERFETTO std::unique_ptr tracingSession; From bb2d2d0913b183a9fe905a2c0925c463dca15bcf Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Wed, 8 Apr 2026 09:34:52 +0200 Subject: [PATCH 10/74] chore: update macOS deployment target to 10.13 --- CMakeLists.txt | 4 ---- src/CMakeLists.txt | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 47cdb62d..d23fa6b3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,10 +9,6 @@ set(CMAKE_SUPPRESS_DEVELOPER_WARNINGS TRUE) set(EXT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external) # Set macOS deployment target for older macOS compatibility -if(APPLE) - # macOS 12.0 (Monterey) is the minimum for reliable C++23 support - set(CMAKE_OSX_DEPLOYMENT_TARGET "12.0" CACHE STRING "Minimum macOS deployment target") -endif() include(cmake/get_cpm.cmake) # Add external dependencies diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c78e0655..383e4404 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -10,7 +10,7 @@ if (APPLE) set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64") # Apparently macOS 12.0 is the minimum for reliable C++23 support # But we yolo it and just hope for the best on older macOS versions - set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15") + set(CMAKE_OSX_DEPLOYMENT_TARGET "10.13") endif() # Option to disable update notification (default OFF) From d6f4248483608940cdf3da10798893522408a9ed Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Wed, 8 Apr 2026 09:49:51 +0200 Subject: [PATCH 11/74] chore: update versioning to read from VERSION.md --- CMakeLists.txt | 4 +++- VERSION | 0 VERSION.md | 1 + src/CMakeLists.txt | 6 +++++- 4 files changed, 9 insertions(+), 2 deletions(-) delete mode 100644 VERSION create mode 100644 VERSION.md diff --git a/CMakeLists.txt b/CMakeLists.txt index d23fa6b3..10ca7a35 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,9 @@ #============================================================================== cmake_minimum_required(VERSION 3.30) -project(Disflux VERSION 1.2.0) # Disflux-Version +file(READ "${CMAKE_CURRENT_LIST_DIR}/VERSION.md" DISFLUX_VERSION) +string(STRIP "${DISFLUX_VERSION}" DISFLUX_VERSION) +project(Disflux VERSION ${DISFLUX_VERSION}) # Disflux-Version set(CMAKE_CXX_STANDARD 23) set(CMAKE_SUPPRESS_DEVELOPER_WARNINGS TRUE) set(EXT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external) diff --git a/VERSION b/VERSION deleted file mode 100644 index e69de29b..00000000 diff --git a/VERSION.md b/VERSION.md new file mode 100644 index 00000000..26aaba0e --- /dev/null +++ b/VERSION.md @@ -0,0 +1 @@ +1.2.0 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 383e4404..53a60d7f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,7 +3,11 @@ #============================================================================== cmake_minimum_required(VERSION 3.22) -project(DisfluxPlugin VERSION 1.2.0) # Disflux-Version +if(NOT DEFINED DISFLUX_VERSION) + file(READ "${CMAKE_CURRENT_LIST_DIR}/../VERSION.md" DISFLUX_VERSION) + string(STRIP "${DISFLUX_VERSION}" DISFLUX_VERSION) +endif() +project(DisfluxPlugin VERSION ${DISFLUX_VERSION}) # Disflux-Version # If we are on MacOS, we need to build for arm64 and x86_64 if (APPLE) From 66cd94517bf3ddf02c550e2216daefecc06e1a2c Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Wed, 8 Apr 2026 09:51:35 +0200 Subject: [PATCH 12/74] chore: update CI workflows to read version from VERSION.md --- .github/workflows/ci-development.yml | 19 +++++++++++++++++-- .github/workflows/ci-release.yml | 19 +++++++++++++++++-- .github/workflows/ci-snapshot.yml | 19 +++++++++++++++++-- 3 files changed, 51 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci-development.yml b/.github/workflows/ci-development.yml index f56e9120..0ee8e0e4 100644 --- a/.github/workflows/ci-development.yml +++ b/.github/workflows/ci-development.yml @@ -20,7 +20,6 @@ env: PROJECT_NAME: Disflux BUNDLE_NAME: disflux BUNDLE_ID: com.dimethoxy.disflux - VERSION: 1.2.0 # Disflux-Version BUILD_DIR: build DISPLAY: :0 # Linux pluginval needs this HOMEBREW_NO_INSTALL_CLEANUP: 1 @@ -46,6 +45,10 @@ jobs: with: ref: development + - name: Read Version + run: | + echo "VERSION=$(tr -d '[:space:]' < VERSION.md)" >> $GITHUB_ENV + - name: Setup MSVC uses: TheMrMilchmann/setup-msvc-dev@v3 with: @@ -129,6 +132,10 @@ jobs: with: ref: development + - name: Read Version + run: | + echo "VERSION=$(tr -d '[:space:]' < VERSION.md)" >> $GITHUB_ENV + - name: Set Up Mac run: brew install ninja osxutils @@ -265,6 +272,10 @@ jobs: with: ref: development + - name: Read Version + run: | + echo "VERSION=$(tr -d '[:space:]' < VERSION.md)" >> $GITHUB_ENV + - name: Set Up Linux run: | sudo apt-get update @@ -342,7 +353,7 @@ jobs: # Set PACKAGE_NAME for envsubst export PACKAGE_NAME=${{env.BUNDLE_NAME}} - export PACKAGE_VERSION=${{env.VERSION}} + export PACKAGE_VERSION=$VERSION # Replace PACKAGE_NAME in control file and copy to Debian package directory envsubst < $UBUNTU_CONTROL_FILE > $UBUNTU_PACKAGE_DIR/DEBIAN/control @@ -382,6 +393,10 @@ jobs: with: ref: development + - name: Read Version + run: | + echo "VERSION=$(tr -d '[:space:]' < VERSION.md)" >> $GITHUB_ENV + - name: Create user for build process run: | useradd -m dimethoxy diff --git a/.github/workflows/ci-release.yml b/.github/workflows/ci-release.yml index a5849b25..413eb0e3 100644 --- a/.github/workflows/ci-release.yml +++ b/.github/workflows/ci-release.yml @@ -20,7 +20,6 @@ env: PROJECT_NAME: Disflux BUNDLE_NAME: disflux BUNDLE_ID: com.dimethoxy.disflux - VERSION: 1.2.0 # Disflux-Version BUILD_DIR: build DISPLAY: :0 # Linux pluginval needs this HOMEBREW_NO_INSTALL_CLEANUP: 1 @@ -44,6 +43,10 @@ jobs: - name: Checkout Code uses: actions/checkout@v4 + - name: Read Version + run: | + echo "VERSION=$(tr -d '[:space:]' < VERSION.md)" >> $GITHUB_ENV + - name: Setup MSVC uses: TheMrMilchmann/setup-msvc-dev@v3 with: @@ -125,6 +128,10 @@ jobs: - name: Checkout Code uses: actions/checkout@v4 + - name: Read Version + run: | + echo "VERSION=$(tr -d '[:space:]' < VERSION.md)" >> $GITHUB_ENV + - name: Set Up Mac run: brew install ninja osxutils @@ -259,6 +266,10 @@ jobs: - name: Checkout Code uses: actions/checkout@v4 + - name: Read Version + run: | + echo "VERSION=$(tr -d '[:space:]' < VERSION.md)" >> $GITHUB_ENV + - name: Set Up Linux run: | sudo apt-get update @@ -336,7 +347,7 @@ jobs: # Set PACKAGE_NAME for envsubst export PACKAGE_NAME=${{env.BUNDLE_NAME}} - export PACKAGE_VERSION=${{env.VERSION}} + export PACKAGE_VERSION=$VERSION # Replace PACKAGE_NAME in control file and copy to Debian package directory envsubst < $UBUNTU_CONTROL_FILE > $UBUNTU_PACKAGE_DIR/DEBIAN/control @@ -374,6 +385,10 @@ jobs: - name: Checkout Repository uses: actions/checkout@v4 + - name: Read Version + run: | + echo "VERSION=$(tr -d '[:space:]' < VERSION.md)" >> $GITHUB_ENV + - name: Create user for build process run: | useradd -m dimethoxy diff --git a/.github/workflows/ci-snapshot.yml b/.github/workflows/ci-snapshot.yml index 2a2c848b..81359521 100644 --- a/.github/workflows/ci-snapshot.yml +++ b/.github/workflows/ci-snapshot.yml @@ -22,7 +22,6 @@ env: PROJECT_NAME: Disflux BUNDLE_NAME: disflux BUNDLE_ID: com.dimethoxy.disflux - VERSION: 1.2.0 # Disflux-Version BUILD_DIR: build DISPLAY: :0 # Linux pluginval needs this HOMEBREW_NO_INSTALL_CLEANUP: 1 @@ -46,6 +45,10 @@ jobs: - name: Checkout Code uses: actions/checkout@v4 + - name: Read Version + run: | + echo "VERSION=$(tr -d '[:space:]' < VERSION.md)" >> $GITHUB_ENV + - name: Setup MSVC uses: TheMrMilchmann/setup-msvc-dev@v3 with: @@ -127,6 +130,10 @@ jobs: - name: Checkout Code uses: actions/checkout@v4 + - name: Read Version + run: | + echo "VERSION=$(tr -d '[:space:]' < VERSION.md)" >> $GITHUB_ENV + - name: Set Up Mac run: brew install ninja osxutils @@ -261,6 +268,10 @@ jobs: - name: Checkout Code uses: actions/checkout@v4 + - name: Read Version + run: | + echo "VERSION=$(tr -d '[:space:]' < VERSION.md)" >> $GITHUB_ENV + - name: Set Up Linux run: | sudo apt-get update @@ -338,7 +349,7 @@ jobs: # Set PACKAGE_NAME for envsubst export PACKAGE_NAME=${{env.BUNDLE_NAME}}-snapshot - export PACKAGE_VERSION=${{env.VERSION}} + export PACKAGE_VERSION=$VERSION # Replace PACKAGE_NAME in control file and copy to Debian package directory envsubst < $UBUNTU_CONTROL_FILE > $UBUNTU_PACKAGE_DIR/DEBIAN/control @@ -376,6 +387,10 @@ jobs: - name: Checkout Repository uses: actions/checkout@v4 + - name: Read Version + run: | + echo "VERSION=$(tr -d '[:space:]' < VERSION.md)" >> $GITHUB_ENV + - name: Create user for build process run: | useradd -m dimethoxy From 99326c253b2740ace650db149c2641fe79744e68 Mon Sep 17 00:00:00 2001 From: David Hess <76759448+Lunix-420@users.noreply.github.com> Date: Wed, 8 Apr 2026 10:02:17 +0200 Subject: [PATCH 13/74] Update webkit2gtk version in PKGBUILD --- pkg/arch/git/PKGBUILD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/arch/git/PKGBUILD b/pkg/arch/git/PKGBUILD index 9d8c2a9d..fba0c887 100644 --- a/pkg/arch/git/PKGBUILD +++ b/pkg/arch/git/PKGBUILD @@ -18,7 +18,7 @@ sha256sums=('SKIP') # Build and runtime dependencies – adjust as necessary for your project. makedepends=('gcc' 'git' 'cmake' 'ninja' 'pkg-config' 'alsa-lib' 'jack' 'ladspa' 'curl' 'freetype2' 'fontconfig' 'libx11' 'libxcomposite' 'libxcursor' - 'libxext' 'libxinerama' 'libxrandr' 'libxrender' 'webkit2gtk' 'glu' 'mesa') + 'libxext' 'libxinerama' 'libxrandr' 'libxrender' 'webkit2gtk-4.1' 'glu' 'mesa') depends=('curl') # Generate a proper pkgver from the git commit (using git describe) From d9e587ee805ec20ef2d29210dccd9d34c6e5aca8 Mon Sep 17 00:00:00 2001 From: David Hess <76759448+Lunix-420@users.noreply.github.com> Date: Wed, 8 Apr 2026 10:02:43 +0200 Subject: [PATCH 14/74] Update webkit2gtk version in PKGBUILD --- pkg/arch/release/PKGBUILD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/arch/release/PKGBUILD b/pkg/arch/release/PKGBUILD index 8af6b231..9288457d 100644 --- a/pkg/arch/release/PKGBUILD +++ b/pkg/arch/release/PKGBUILD @@ -18,7 +18,7 @@ sha256sums=('SKIP') # Build and runtime dependencies – adjust as necessary for your project. makedepends=('gcc' 'git' 'cmake' 'ninja' 'pkg-config' 'alsa-lib' 'jack' 'ladspa' 'curl' 'freetype2' 'fontconfig' 'libx11' 'libxcomposite' 'libxcursor' - 'libxext' 'libxinerama' 'libxrandr' 'libxrender' 'webkit2gtk' 'glu' 'mesa' 'libxml2') + 'libxext' 'libxinerama' 'libxrandr' 'libxrender' 'webkit2gtk-4.1' 'glu' 'mesa' 'libxml2') depends=('curl') build() { From f404f956e85ee36a86c23037e654ce6ee502be36 Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Wed, 8 Apr 2026 10:28:09 +0200 Subject: [PATCH 15/74] gui: fix broken hidpi scaling of shadows --- src/dmt/gui/widget/Shadow.h | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/dmt/gui/widget/Shadow.h b/src/dmt/gui/widget/Shadow.h index 0b0c8f9e..af7752de 100644 --- a/src/dmt/gui/widget/Shadow.h +++ b/src/dmt/gui/widget/Shadow.h @@ -249,7 +249,7 @@ class Shadow TRACER("Shadow::drawOuterForPath"); juce::Graphics::ScopedSaveState saveState(_g); juce::Path shadowPath(_target); - shadowPath.addRectangle(_target.getBounds().expanded(10 * scale)); + shadowPath.addRectangle(_target.getBounds().expanded(10.0f)); shadowPath.setUsingNonZeroWinding(false); _g.reduceClipRegion(shadowPath); updateShadowParameters(); @@ -259,19 +259,22 @@ class Shadow private: inline void updateShadowParameters() { - const auto scaledRadius = static_cast(radius * size * scale); - const auto scaledOffset = juce::Point( - static_cast(offset.x) * static_cast(scale), - static_cast(offset.y) * static_cast(scale)); + // Rendering uses a graphics transform for HiDPI, so keep shadow parameters + // in logical units to avoid applying scale twice. + const auto scaledRadius = static_cast(radius * size); + const auto scaledOffset = juce::Point(static_cast(offset.x), + static_cast(offset.y)); if (inner) { - innerShadowRenderer.setColor(*colour).setRadius(scaledRadius).setOffset( - scaledOffset); + innerShadowRenderer.setColor(*colour) + .setRadius(scaledRadius) + .setOffset(scaledOffset); return; } - outerShadowRenderer.setColor(*colour).setRadius(scaledRadius).setOffset( - scaledOffset); + outerShadowRenderer.setColor(*colour) + .setRadius(scaledRadius) + .setOffset(scaledOffset); } inline void refreshCachedImageIfNeeded(bool forceRepaint = false) From 96e4101547b2ad0f2cf2ae9f013a53db097231df Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Wed, 8 Apr 2026 10:37:25 +0200 Subject: [PATCH 16/74] gui: fix hdpi scaling not working when ValueEditorList dynamically adds children --- src/dmt/gui/window/Compositor.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/dmt/gui/window/Compositor.h b/src/dmt/gui/window/Compositor.h index a5fbf245..f75f7514 100644 --- a/src/dmt/gui/window/Compositor.h +++ b/src/dmt/gui/window/Compositor.h @@ -570,16 +570,21 @@ class Compositor * components that implement the IScaleable interface receive the updated * size factor. * + * @param force If true, propagation runs even when the size factor itself + * did not change. This is required for dynamically added + * scaleable children. + * * @note This is typically triggered by the Compositor in response to * hierarchy changes or user scaling actions. */ - void propagateSizeFactor() noexcept + void propagateSizeFactor(const bool force = false) noexcept { TRACER("Compositor::propagateSizeFactor"); if (isPropagatingSizeFactor) return; - if (juce::approximatelyEqual(lastPropagatedSizeFactor, sizeFactor)) + if (!force && + juce::approximatelyEqual(lastPropagatedSizeFactor, sizeFactor)) return; const juce::ScopedValueSetter isPropagatingGuard( @@ -755,7 +760,7 @@ class Compositor return; addListenerToChildren(&component); - propagateSizeFactor(); + propagateSizeFactor(true); } private: From 1d2d4b69d5d367b089642458ed2059c5e24013b3 Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Wed, 8 Apr 2026 11:49:25 +0200 Subject: [PATCH 17/74] app: refactor plugin editor to inherit from AbstractPluginEditor --- src/app/PluginEditor.cpp | 2 +- src/app/PluginEditor.h | 2 +- src/dmt/app/AbstractPluginEditor.h | 18 +++++++++++++++++- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/app/PluginEditor.cpp b/src/app/PluginEditor.cpp index 113a8f1d..24f9c2fd 100644 --- a/src/app/PluginEditor.cpp +++ b/src/app/PluginEditor.cpp @@ -31,7 +31,7 @@ juceFilteredGLDebugCallback(GLenum source, //============================================================================== PluginEditor::PluginEditor(PluginProcessor& p) - : AudioProcessorEditor(&p) + : dmt::app::AbstractPluginEditor(p) , p(p) , sizeFactor(p.sizeFactor) , mainLayout({}, {}) diff --git a/src/app/PluginEditor.h b/src/app/PluginEditor.h index 5b50e89f..80f1f83b 100644 --- a/src/app/PluginEditor.h +++ b/src/app/PluginEditor.h @@ -5,7 +5,7 @@ //============================================================================== class PluginEditor - : public juce::AudioProcessorEditor + : public dmt::app::AbstractPluginEditor , private juce::Timer { using Image = juce::Image; diff --git a/src/dmt/app/AbstractPluginEditor.h b/src/dmt/app/AbstractPluginEditor.h index e743115c..efe9b44f 100644 --- a/src/dmt/app/AbstractPluginEditor.h +++ b/src/dmt/app/AbstractPluginEditor.h @@ -1,3 +1,19 @@ #pragma once -#include \ No newline at end of file +#include "./AbstractPluginProcessor.h" +#include + +namespace dmt { +namespace app { +class AbstractPluginEditor : public juce::AudioProcessorEditor +{ +public: + explicit AbstractPluginEditor(dmt::app::AbstractPluginProcessor& p) + : juce::AudioProcessorEditor(&p) + { + } + + ~AbstractPluginEditor() override = default; +}; +} // namespace app +} // namespace dmt \ No newline at end of file From 135e5fd554ead52fb19f7606f2436a986596357c Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Wed, 8 Apr 2026 14:21:30 +0200 Subject: [PATCH 18/74] refactor: move more logic to AbstractPluginEditor --- src/app/PluginEditor.cpp | 105 +---------------------- src/app/PluginEditor.h | 33 +------- src/dmt/app/AbstractPluginEditor.h | 128 ++++++++++++++++++++++++++++- 3 files changed, 131 insertions(+), 135 deletions(-) diff --git a/src/app/PluginEditor.cpp b/src/app/PluginEditor.cpp index 24f9c2fd..b27df79d 100644 --- a/src/app/PluginEditor.cpp +++ b/src/app/PluginEditor.cpp @@ -1,42 +1,11 @@ #include "PluginEditor.h" #include "PluginProcessor.h" -namespace { -// Filter out notification-level GL debug messages -static void KHRONOS_APIENTRY -juceFilteredGLDebugCallback(GLenum source, - GLenum type, - GLuint id, - GLenum severity, - GLsizei length, - const GLchar* message, - const void* userParam) -{ - // Ignore low-priority notifications - if (severity == juce::gl::GL_DEBUG_SEVERITY_NOTIFICATION) - return; - - // Log other messages so we don't lose important info - juce::String msg = - (message != nullptr) ? juce::String(message) : juce::String(); - DBG("OpenGL DBG message: " << msg); - - // Keep JUCE's behaviour for serious errors - if (type == juce::gl::GL_DEBUG_TYPE_ERROR && - severity == juce::gl::GL_DEBUG_SEVERITY_HIGH) - jassertfalse; -} - -} // anonymous namespace - //============================================================================== PluginEditor::PluginEditor(PluginProcessor& p) - : dmt::app::AbstractPluginEditor(p) - , p(p) - , sizeFactor(p.sizeFactor) + : dmt::app::AbstractPluginEditor(p, mainLayout) , mainLayout({}, {}) - , compositor("DisFlux", mainLayout, p.apvts, p.properties, sizeFactor) - , compositorAttached(true) + , p(p) { mainLayout.addPanel>( 0, 0, 1, 1, p.apvts, p.oscilloscopeBuffer); @@ -174,72 +143,4 @@ PluginEditor::resized() return; } detachCompositorForResize(); -} - -void -PluginEditor::detachCompositorForResize() -{ - if (compositorAttached) { - // Take a snapshot before detaching - updateCompositorSnapshot(); - - // Remove compositor from view - removeChildComponent(&compositor); - compositorAttached = false; - } - - // Restart debounce timer (100ms) - stopTimer(); - startTimer(100); -} - -void -PluginEditor::attachCompositorAfterResize() -{ - if (!compositorAttached) { - // Snap to the correct aspect ratio, considering header visibility - auto bounds = getLocalBounds(); - bool headerVisible = compositor.isHeaderVisible(); - int aspectHeight = headerVisible ? (baseHeight + headerHeight) : baseHeight; - const double aspect = (double)baseWidth / (double)aspectHeight; - int w = bounds.getWidth(); - int h = bounds.getHeight(); - double currentAspect = (double)w / (double)h; - - if (currentAspect > aspect) { - // Too wide, adjust width - w = static_cast(h * aspect); - } else if (currentAspect < aspect) { - // Too tall, adjust height - h = static_cast(w / aspect); - } - setSize(w, h); - - // Set compositor bounds to fill the editor - addAndMakeVisible(compositor); - compositor.setBounds(getLocalBounds()); - compositorAttached = true; - repaint(); - } -} - -void -PluginEditor::updateCompositorSnapshot() -{ - // Render compositor to an image at its current size - if (getWidth() > 0 && getHeight() > 0) { - compositorSnapshot = - juce::Image(juce::Image::ARGB, getWidth(), getHeight(), true); - juce::Graphics g(compositorSnapshot); - compositor.paintEntireComponent(g, true); - } -} - -void -PluginEditor::timerCallback() -{ - // Timer expired: reattach compositor and repaint - stopTimer(); - attachCompositorAfterResize(); - repaint(); -} +} \ No newline at end of file diff --git a/src/app/PluginEditor.h b/src/app/PluginEditor.h index 80f1f83b..2e2ce2fe 100644 --- a/src/app/PluginEditor.h +++ b/src/app/PluginEditor.h @@ -4,22 +4,13 @@ #include //============================================================================== -class PluginEditor - : public dmt::app::AbstractPluginEditor - , private juce::Timer +class PluginEditor : public dmt::app::AbstractPluginEditor { using Image = juce::Image; using ImageComponent = juce::ImageComponent; using PixelFormat = juce::Image::PixelFormat; using OpenGLContext = juce::OpenGLContext; - // Window size - const int baseWidth = 500; - const int baseHeight = 270; - - // Window header - const int& headerHeight = dmt::Settings::Header::height; - public: explicit PluginEditor(PluginProcessor&); ~PluginEditor() override; @@ -30,32 +21,12 @@ class PluginEditor void setConstraints(int width, int height); void handleHeaderVisibilityChange(bool isHeaderVisible); - // Debounced resizing - void timerCallback() override; - void detachCompositorForResize(); - void attachCompositorAfterResize(); - void updateCompositorSnapshot(); - private: //============================================================================== PluginProcessor& p; OpenGLContext openGLContext; //============================================================================== - - int lastWidth = baseWidth; - int lastHeight = baseHeight; - double ratio = baseWidth / baseHeight; - float& sizeFactor = p.sizeFactor; - bool firstDraw = true; - //============================================================================== - Image image; - bool isResizing = false; - //============================================================================== dmt::gui::window::Layout mainLayout; - dmt::gui::window::Compositor compositor; - //============================================================================== - juce::Image compositorSnapshot; - bool compositorAttached = true; - //============================================================================== + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginEditor) }; diff --git a/src/dmt/app/AbstractPluginEditor.h b/src/dmt/app/AbstractPluginEditor.h index efe9b44f..2684c1dc 100644 --- a/src/dmt/app/AbstractPluginEditor.h +++ b/src/dmt/app/AbstractPluginEditor.h @@ -1,19 +1,143 @@ #pragma once #include "./AbstractPluginProcessor.h" +#include "gui/window/Compositor.h" #include +namespace { +// Filter out notification-level GL debug messages +static void KHRONOS_APIENTRY +juceFilteredGLDebugCallback(GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar* message, + const void* userParam) +{ + // Ignore low-priority notifications + if (severity == juce::gl::GL_DEBUG_SEVERITY_NOTIFICATION) + return; + + // Log other messages so we don't lose important info + juce::String msg = + (message != nullptr) ? juce::String(message) : juce::String(); + DBG("OpenGL DBG message: " << msg); + + // Keep JUCE's behaviour for serious errors + if (type == juce::gl::GL_DEBUG_TYPE_ERROR && + severity == juce::gl::GL_DEBUG_SEVERITY_HIGH) + jassertfalse; +} + +} // anonymous namespace + namespace dmt { namespace app { -class AbstractPluginEditor : public juce::AudioProcessorEditor +class AbstractPluginEditor + : public juce::AudioProcessorEditor + , protected juce::Timer { public: - explicit AbstractPluginEditor(dmt::app::AbstractPluginProcessor& p) + AbstractPluginEditor(dmt::app::AbstractPluginProcessor& p, + dmt::gui::window::Layout& mainLayout) : juce::AudioProcessorEditor(&p) + , sizeFactor(p.sizeFactor) + , compositorAttached(true) + , compositor("DisFlux", mainLayout, p.apvts, p.properties, sizeFactor) { } ~AbstractPluginEditor() override = default; + + //============================================================================== + // Debounced resizing + + // Debounce timer callback: reattach compositor and repaint + void timerCallback() override + { + stopTimer(); + attachCompositorAfterResize(); + repaint(); // TODO: Redundanr call, maybe remove this? + } + + // Detach compositor to improve resize performance + void detachCompositorForResize() + { + if (compositorAttached) { + // Take a snapshot before detaching + updateCompositorSnapshot(); + + // Remove compositor from view + removeChildComponent(&compositor); + compositorAttached = false; + } + + // Restart debounce timer (100ms) + stopTimer(); + startTimer(100); + } + + // Reattach compositor and repaint after resizing + void attachCompositorAfterResize() + { + if (!compositorAttached) { + // Snap to the correct aspect ratio, considering header visibility + auto bounds = getLocalBounds(); + bool headerVisible = compositor.isHeaderVisible(); + int aspectHeight = + headerVisible ? (baseHeight + headerHeight) : baseHeight; + const double aspect = (double)baseWidth / (double)aspectHeight; + int w = bounds.getWidth(); + int h = bounds.getHeight(); + double currentAspect = (double)w / (double)h; + + if (currentAspect > aspect) { + // Too wide, adjust width + w = static_cast(h * aspect); + } else if (currentAspect < aspect) { + // Too tall, adjust height + h = static_cast(w / aspect); + } + setSize(w, h); + + // Set compositor bounds to fill the editor + addAndMakeVisible(compositor); + compositor.setBounds(getLocalBounds()); + compositorAttached = true; + repaint(); + } + } + + // Capture the current compositor state into an image for smooth resizing + void updateCompositorSnapshot() + { + // Render compositor to an image at its current size + if (getWidth() > 0 && getHeight() > 0) { + compositorSnapshot = + juce::Image(juce::Image::ARGB, getWidth(), getHeight(), true); + juce::Graphics g(compositorSnapshot); + compositor.paintEntireComponent(g, true); + } + } + +protected: + const int& headerHeight = dmt::Settings::Header::height; + const int baseWidth = 500; + const int baseHeight = 270; + int lastWidth = baseWidth; + int lastHeight = baseHeight; + double ratio = baseWidth / baseHeight; + float& sizeFactor; + bool firstDraw = true; + + juce::Image compositorSnapshot; + bool compositorAttached = true; + + Image image; + bool isResizing = false; + + dmt::gui::window::Compositor compositor; }; } // namespace app } // namespace dmt \ No newline at end of file From c52df6edb30edad7d5bbf96446581b6c7e586484 Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Thu, 9 Apr 2026 13:20:57 +0200 Subject: [PATCH 19/74] refactor: use callback injection to initialize layout in AbstractPluginEditor --- src/app/PluginEditor.cpp | 9 ++++----- src/app/PluginEditor.h | 2 -- src/dmt/app/AbstractPluginEditor.h | 17 +++++++++++++++-- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/app/PluginEditor.cpp b/src/app/PluginEditor.cpp index b27df79d..1ca7357f 100644 --- a/src/app/PluginEditor.cpp +++ b/src/app/PluginEditor.cpp @@ -3,12 +3,12 @@ //============================================================================== PluginEditor::PluginEditor(PluginProcessor& p) - : dmt::app::AbstractPluginEditor(p, mainLayout) - , mainLayout({}, {}) + : dmt::app::AbstractPluginEditor(p, [&p](dmt::gui::window::Layout& layout) { + layout.addPanel>( + 0, 0, 1, 1, p.apvts, p.oscilloscopeBuffer); + }) , p(p) { - mainLayout.addPanel>( - 0, 0, 1, 1, p.apvts, p.oscilloscopeBuffer); if (OS_IS_WINDOWS) { setResizable(false, true); @@ -55,7 +55,6 @@ PluginEditor::PluginEditor(PluginProcessor& p) } setConstraints(baseWidth, baseHeight + headerHeight); - addAndMakeVisible(compositor); setResizable(false, true); const auto startWidth = baseWidth * sizeFactor; diff --git a/src/app/PluginEditor.h b/src/app/PluginEditor.h index 2e2ce2fe..79a3c564 100644 --- a/src/app/PluginEditor.h +++ b/src/app/PluginEditor.h @@ -25,8 +25,6 @@ class PluginEditor : public dmt::app::AbstractPluginEditor //============================================================================== PluginProcessor& p; OpenGLContext openGLContext; - //============================================================================== - dmt::gui::window::Layout mainLayout; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginEditor) }; diff --git a/src/dmt/app/AbstractPluginEditor.h b/src/dmt/app/AbstractPluginEditor.h index 2684c1dc..5a40b647 100644 --- a/src/dmt/app/AbstractPluginEditor.h +++ b/src/dmt/app/AbstractPluginEditor.h @@ -3,6 +3,7 @@ #include "./AbstractPluginProcessor.h" #include "gui/window/Compositor.h" #include +#include namespace { // Filter out notification-level GL debug messages @@ -39,13 +40,22 @@ class AbstractPluginEditor , protected juce::Timer { public: + // Strategy function type for layout initialization + using LayoutInitializer = std::function; + AbstractPluginEditor(dmt::app::AbstractPluginProcessor& p, - dmt::gui::window::Layout& mainLayout) + LayoutInitializer&& layoutInit) : juce::AudioProcessorEditor(&p) , sizeFactor(p.sizeFactor) - , compositorAttached(true) + , mainLayout({}, {}) , compositor("DisFlux", mainLayout, p.apvts, p.properties, sizeFactor) + , compositorAttached(true) { + // Initialize the layout via strategy function + layoutInit(mainLayout); + + // Now that layout is fully configured, attach the compositor + addAndMakeVisible(compositor); } ~AbstractPluginEditor() override = default; @@ -121,6 +131,8 @@ class AbstractPluginEditor } } + dmt::gui::window::Layout& getMainLayout() { return mainLayout; } + protected: const int& headerHeight = dmt::Settings::Header::height; const int baseWidth = 500; @@ -137,6 +149,7 @@ class AbstractPluginEditor Image image; bool isResizing = false; + dmt::gui::window::Layout mainLayout; dmt::gui::window::Compositor compositor; }; } // namespace app From 29897968663e503fbbcf7ca7d69aa3e0314523a8 Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Thu, 9 Apr 2026 13:41:52 +0200 Subject: [PATCH 20/74] gui: update border button font color to use background color --- src/dmt/utility/Settings.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dmt/utility/Settings.h b/src/dmt/utility/Settings.h index 564d8fc7..40142f41 100644 --- a/src/dmt/utility/Settings.h +++ b/src/dmt/utility/Settings.h @@ -213,7 +213,8 @@ struct Settings container.add("Header.BorderButtonBorderColour", Colours::success.darker(0.5f)); static inline auto& borderButtonFontColour = - container.add("Header.BorderButtonFontColour", Colours::shadow); + container.add("Header.BorderButtonFontColour", + Colours::background); static inline auto& borderButtonFontSize = container.add("Header.BorderButtonFontSize", 20.0f); static inline auto& borderButtonHeight = From 2255459df013b802a583934825a9cb0bc9d34138 Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Thu, 9 Apr 2026 18:38:23 +0200 Subject: [PATCH 21/74] refactor: move even more logic to AbstractPluginEditor --- src/app/PluginEditor.cpp | 137 +------------------- src/app/PluginEditor.h | 13 -- src/dmt/app/AbstractPluginEditor.h | 194 ++++++++++++++++++++++++----- 3 files changed, 168 insertions(+), 176 deletions(-) diff --git a/src/app/PluginEditor.cpp b/src/app/PluginEditor.cpp index 1ca7357f..6be07d20 100644 --- a/src/app/PluginEditor.cpp +++ b/src/app/PluginEditor.cpp @@ -4,142 +4,11 @@ //============================================================================== PluginEditor::PluginEditor(PluginProcessor& p) : dmt::app::AbstractPluginEditor(p, [&p](dmt::gui::window::Layout& layout) { - layout.addPanel>( - 0, 0, 1, 1, p.apvts, p.oscilloscopeBuffer); - }) - , p(p) + layout.addPanel>( + 0, 0, 1, 1, p.apvts, p.oscilloscopeBuffer); + }) { - - if (OS_IS_WINDOWS) { - setResizable(false, true); - } - - if (OS_IS_DARWIN) { - setResizable(false, true); - } - - if (OS_IS_LINUX) { - openGLContext.setComponentPaintingEnabled(true); - openGLContext.setContinuousRepainting(false); - openGLContext.attachTo(*getTopLevelComponent()); - std::thread([this]() { - for (int i = 0; i < 200; ++i) { - if (openGLContext.isAttached() && - openGLContext.getRawContext() != nullptr) - break; - std::this_thread::sleep_for(std::chrono::milliseconds(25)); - } - - if (!openGLContext.isAttached() || - openGLContext.getRawContext() == nullptr) - return; - - openGLContext.executeOnGLThread( - [](juce::OpenGLContext&) { - if (juce::gl::glDebugMessageControl) { - juce::gl::glDebugMessageControl( - juce::gl::GL_DEBUG_SOURCE_API, - juce::gl::GL_DEBUG_TYPE_OTHER, - juce::gl::GL_DEBUG_SEVERITY_NOTIFICATION, - 0, - nullptr, - juce::gl::GL_FALSE); - } - - if (juce::gl::glDebugMessageCallback) - juce::gl::glDebugMessageCallback(juceFilteredGLDebugCallback, - nullptr); - }, - true); - }).detach(); - } - - setConstraints(baseWidth, baseHeight + headerHeight); - setResizable(false, true); - - const auto startWidth = baseWidth * sizeFactor; - const auto startHeight = (baseHeight + headerHeight) * sizeFactor; - setSize(startWidth, startHeight); - - // Set the callback for header visibility changes - compositor.setHeaderVisibilityCallback([this](bool isHeaderVisible) { - handleHeaderVisibilityChange(isHeaderVisible); - }); } -void -PluginEditor::handleHeaderVisibilityChange(bool isHeaderVisible) -{ - const int adjustedHeight = - isHeaderVisible ? baseHeight + headerHeight : baseHeight; - setConstraints(baseWidth, adjustedHeight); - setSize(baseWidth * sizeFactor, adjustedHeight * sizeFactor); -} //============================================================================== PluginEditor::~PluginEditor() {} - -//============================================================================== -void -PluginEditor::paint(juce::Graphics& g) -{ - TRACER("PluginEditor::paint"); - - // Just painting the background - g.fillAll(dmt::Settings::Window::backgroundColour); - - if (!compositorAttached && compositorSnapshot.isValid()) { - // Draw the last compositor snapshot, scaled to fit - auto bounds = getLocalBounds().toFloat(); - g.drawImage( - compositorSnapshot, bounds, juce::RectanglePlacement::stretchToFit); - return; - } -} - -//============================================================================== -void -PluginEditor::setConstraints(int width, int height) -{ - if (auto* constrainer = this->getConstrainer()) { - const auto aspectRatio = (double)width / (double)height; - constrainer->setFixedAspectRatio(aspectRatio); - const auto minWidth = width / 2; - const auto minHeight = height / 2; - const auto maxWidth = width * 2; - const auto maxHeight = height * 2; - constrainer->setSizeLimits(minWidth, minHeight, maxWidth, maxHeight); - } else { - jassertfalse; // Constrainer not set - } -} - -//============================================================================== -void -PluginEditor::resized() -{ - TRACER("PluginEditor::resized"); - - // Set the global size - const int currentHeight = getHeight(); - const float newSize = - (float)currentHeight / - (compositor.isHeaderVisible() ? baseHeight + headerHeight : baseHeight); - - // Make sure the size makes sense - if (newSize <= 0.0f || std::isinf(newSize)) { - jassertfalse; - } - - // Update the processor's scale factor - sizeFactor = newSize; - p.setSizeFactor(newSize); - - // Debounced resizing logic - if (firstDraw) { - // On first draw, skip debounce and just layout normally - compositor.setBounds(getLocalBounds()); - firstDraw = false; - return; - } - detachCompositorForResize(); -} \ No newline at end of file diff --git a/src/app/PluginEditor.h b/src/app/PluginEditor.h index 79a3c564..07ff6886 100644 --- a/src/app/PluginEditor.h +++ b/src/app/PluginEditor.h @@ -6,25 +6,12 @@ //============================================================================== class PluginEditor : public dmt::app::AbstractPluginEditor { - using Image = juce::Image; - using ImageComponent = juce::ImageComponent; - using PixelFormat = juce::Image::PixelFormat; - using OpenGLContext = juce::OpenGLContext; - public: explicit PluginEditor(PluginProcessor&); ~PluginEditor() override; - //============================================================================== - void paint(juce::Graphics&) override; - void resized() override; - void setConstraints(int width, int height); - void handleHeaderVisibilityChange(bool isHeaderVisible); - private: //============================================================================== - PluginProcessor& p; - OpenGLContext openGLContext; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginEditor) }; diff --git a/src/dmt/app/AbstractPluginEditor.h b/src/dmt/app/AbstractPluginEditor.h index 5a40b647..84abddcc 100644 --- a/src/dmt/app/AbstractPluginEditor.h +++ b/src/dmt/app/AbstractPluginEditor.h @@ -5,40 +5,17 @@ #include #include -namespace { -// Filter out notification-level GL debug messages -static void KHRONOS_APIENTRY -juceFilteredGLDebugCallback(GLenum source, - GLenum type, - GLuint id, - GLenum severity, - GLsizei length, - const GLchar* message, - const void* userParam) -{ - // Ignore low-priority notifications - if (severity == juce::gl::GL_DEBUG_SEVERITY_NOTIFICATION) - return; - - // Log other messages so we don't lose important info - juce::String msg = - (message != nullptr) ? juce::String(message) : juce::String(); - DBG("OpenGL DBG message: " << msg); - - // Keep JUCE's behaviour for serious errors - if (type == juce::gl::GL_DEBUG_TYPE_ERROR && - severity == juce::gl::GL_DEBUG_SEVERITY_HIGH) - jassertfalse; -} - -} // anonymous namespace - namespace dmt { namespace app { class AbstractPluginEditor : public juce::AudioProcessorEditor , protected juce::Timer { + using Image = juce::Image; + using ImageComponent = juce::ImageComponent; + using PixelFormat = juce::Image::PixelFormat; + using OpenGLContext = juce::OpenGLContext; + public: // Strategy function type for layout initialization using LayoutInitializer = std::function; @@ -46,6 +23,7 @@ class AbstractPluginEditor AbstractPluginEditor(dmt::app::AbstractPluginProcessor& p, LayoutInitializer&& layoutInit) : juce::AudioProcessorEditor(&p) + , p(p) , sizeFactor(p.sizeFactor) , mainLayout({}, {}) , compositor("DisFlux", mainLayout, p.apvts, p.properties, sizeFactor) @@ -56,10 +34,139 @@ class AbstractPluginEditor // Now that layout is fully configured, attach the compositor addAndMakeVisible(compositor); + + if (OS_IS_WINDOWS) { + setResizable(false, true); + } + + if (OS_IS_DARWIN) { + setResizable(false, true); + } + + if (OS_IS_LINUX) { + openGLContext.setComponentPaintingEnabled(true); + openGLContext.setContinuousRepainting(false); + openGLContext.attachTo(*getTopLevelComponent()); + std::thread([this]() { + for (int i = 0; i < 200; ++i) { + if (openGLContext.isAttached() && + openGLContext.getRawContext() != nullptr) + break; + std::this_thread::sleep_for(std::chrono::milliseconds(25)); + } + + if (!openGLContext.isAttached() || + openGLContext.getRawContext() == nullptr) + return; + + openGLContext.executeOnGLThread( + [](juce::OpenGLContext&) { + if (juce::gl::glDebugMessageControl) { + juce::gl::glDebugMessageControl( + juce::gl::GL_DEBUG_SOURCE_API, + juce::gl::GL_DEBUG_TYPE_OTHER, + juce::gl::GL_DEBUG_SEVERITY_NOTIFICATION, + 0, + nullptr, + juce::gl::GL_FALSE); + } + + if (juce::gl::glDebugMessageCallback) + juce::gl::glDebugMessageCallback(juceFilteredGLDebugCallback, + nullptr); + }, + true); + }).detach(); + } + + setConstraints(baseWidth, baseHeight + headerHeight); + setResizable(false, true); + + const auto startWidth = baseWidth * sizeFactor; + const auto startHeight = (baseHeight + headerHeight) * sizeFactor; + setSize(startWidth, startHeight); + + // Set the callback for header visibility changes + compositor.setHeaderVisibilityCallback([this](bool isHeaderVisible) { + handleHeaderVisibilityChange(isHeaderVisible); + }); } ~AbstractPluginEditor() override = default; + //============================================================================== + // + + void paint(juce::Graphics& g) + { + TRACER("PluginEditor::paint"); + + // Just painting the background + g.fillAll(dmt::Settings::Window::backgroundColour); + + if (!compositorAttached && compositorSnapshot.isValid()) { + // Draw the last compositor snapshot, scaled to fit + auto bounds = getLocalBounds().toFloat(); + g.drawImage( + compositorSnapshot, bounds, juce::RectanglePlacement::stretchToFit); + return; + } + } + + void resized() + { + TRACER("PluginEditor::resized"); + + // Set the global size + const int currentHeight = getHeight(); + const float newSize = + (float)currentHeight / + (compositor.isHeaderVisible() ? baseHeight + headerHeight : baseHeight); + + // Make sure the size makes sense + if (newSize <= 0.0f || std::isinf(newSize)) { + jassertfalse; + } + + // Update the processor's scale factor + sizeFactor = newSize; + p.setSizeFactor(newSize); + + // Debounced resizing logic + if (firstDraw) { + // On first draw, skip debounce and just layout normally + compositor.setBounds(getLocalBounds()); + firstDraw = false; + return; + } + detachCompositorForResize(); + } + + void setConstraints(int width, int height) + { + if (auto* constrainer = this->getConstrainer()) { + const auto aspectRatio = (double)width / (double)height; + constrainer->setFixedAspectRatio(aspectRatio); + const auto minWidth = width / 2; + const auto minHeight = height / 2; + const auto maxWidth = width * 2; + const auto maxHeight = height * 2; + constrainer->setSizeLimits(minWidth, minHeight, maxWidth, maxHeight); + } else { + jassertfalse; // Constrainer not set + } + } + + void handleHeaderVisibilityChange(bool isHeaderVisible) + { + const int adjustedHeight = + isHeaderVisible ? baseHeight + headerHeight : baseHeight; + setConstraints(baseWidth, adjustedHeight); + setSize(baseWidth * sizeFactor, adjustedHeight * sizeFactor); + } + + dmt::gui::window::Layout& getMainLayout() { return mainLayout; } + //============================================================================== // Debounced resizing @@ -131,9 +238,36 @@ class AbstractPluginEditor } } - dmt::gui::window::Layout& getMainLayout() { return mainLayout; } + //============================================================================== + // OpenGL debug overwrite + + static void KHRONOS_APIENTRY + juceFilteredGLDebugCallback(GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar* message, + const void* userParam) + { + // Ignore low-priority notifications + if (severity == juce::gl::GL_DEBUG_SEVERITY_NOTIFICATION) + return; + + // Log other messages so we don't lose important info + juce::String msg = + (message != nullptr) ? juce::String(message) : juce::String(); + DBG("OpenGL DBG message: " << msg); + + // Keep JUCE's behaviour for serious errors + if (type == juce::gl::GL_DEBUG_TYPE_ERROR && + severity == juce::gl::GL_DEBUG_SEVERITY_HIGH) + jassertfalse; + } protected: + dmt::app::AbstractPluginProcessor& p; + const int& headerHeight = dmt::Settings::Header::height; const int baseWidth = 500; const int baseHeight = 270; @@ -151,6 +285,8 @@ class AbstractPluginEditor dmt::gui::window::Layout mainLayout; dmt::gui::window::Compositor compositor; + + OpenGLContext openGLContext; }; } // namespace app } // namespace dmt \ No newline at end of file From eb72d7d2aad0d1f0ce7116f718d88e31ebcdaa46 Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Thu, 9 Apr 2026 20:39:58 +0200 Subject: [PATCH 22/74] refactor: fix AbstractPluginEditor abstraction --- src/app/PluginEditor.cpp | 13 +++++++++---- src/dmt/app/AbstractPluginEditor.h | 23 +++++++++++++++-------- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/app/PluginEditor.cpp b/src/app/PluginEditor.cpp index 6be07d20..624be54f 100644 --- a/src/app/PluginEditor.cpp +++ b/src/app/PluginEditor.cpp @@ -3,10 +3,15 @@ //============================================================================== PluginEditor::PluginEditor(PluginProcessor& p) - : dmt::app::AbstractPluginEditor(p, [&p](dmt::gui::window::Layout& layout) { - layout.addPanel>( - 0, 0, 1, 1, p.apvts, p.oscilloscopeBuffer); - }) + : dmt::app::AbstractPluginEditor( + p, + "DisFlux", + 500, + 270, + [&p](dmt::gui::window::Layout& layout) { + layout.addPanel>( + 0, 0, 1, 1, p.apvts, p.oscilloscopeBuffer); + }) { } diff --git a/src/dmt/app/AbstractPluginEditor.h b/src/dmt/app/AbstractPluginEditor.h index 84abddcc..b30916d2 100644 --- a/src/dmt/app/AbstractPluginEditor.h +++ b/src/dmt/app/AbstractPluginEditor.h @@ -20,17 +20,22 @@ class AbstractPluginEditor // Strategy function type for layout initialization using LayoutInitializer = std::function; - AbstractPluginEditor(dmt::app::AbstractPluginProcessor& p, - LayoutInitializer&& layoutInit) - : juce::AudioProcessorEditor(&p) - , p(p) + AbstractPluginEditor(dmt::app::AbstractPluginProcessor& _p, + juce::String _name, + int _baseWidth, + int _baseHeight, + LayoutInitializer&& _layoutInit) + : juce::AudioProcessorEditor(&_p) + , p(_p) + , baseWidth(_baseWidth) + , baseHeight(_baseHeight) , sizeFactor(p.sizeFactor) , mainLayout({}, {}) - , compositor("DisFlux", mainLayout, p.apvts, p.properties, sizeFactor) + , compositor(_name, mainLayout, p.apvts, p.properties, sizeFactor) , compositorAttached(true) { // Initialize the layout via strategy function - layoutInit(mainLayout); + _layoutInit(mainLayout); // Now that layout is fully configured, attach the compositor addAndMakeVisible(compositor); @@ -269,8 +274,8 @@ class AbstractPluginEditor dmt::app::AbstractPluginProcessor& p; const int& headerHeight = dmt::Settings::Header::height; - const int baseWidth = 500; - const int baseHeight = 270; + const int baseWidth; + const int baseHeight; int lastWidth = baseWidth; int lastHeight = baseHeight; double ratio = baseWidth / baseHeight; @@ -287,6 +292,8 @@ class AbstractPluginEditor dmt::gui::window::Compositor compositor; OpenGLContext openGLContext; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(AbstractPluginEditor) }; } // namespace app } // namespace dmt \ No newline at end of file From b9d5f00141ae090e7e609dade244ecf6cac9de78 Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Fri, 10 Apr 2026 15:15:14 +0200 Subject: [PATCH 23/74] refactor: minor cleanup shit --- src/dmt/app/AbstractPluginEditor.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/dmt/app/AbstractPluginEditor.h b/src/dmt/app/AbstractPluginEditor.h index b30916d2..8e64f76a 100644 --- a/src/dmt/app/AbstractPluginEditor.h +++ b/src/dmt/app/AbstractPluginEditor.h @@ -1,6 +1,6 @@ #pragma once -#include "./AbstractPluginProcessor.h" +#include "app/AbstractPluginProcessor.h" #include "gui/window/Compositor.h" #include #include @@ -100,7 +100,7 @@ class AbstractPluginEditor ~AbstractPluginEditor() override = default; //============================================================================== - // + // JUCE overrides void paint(juce::Graphics& g) { @@ -147,6 +147,9 @@ class AbstractPluginEditor detachCompositorForResize(); } + //============================================================================== + // JUCE overrides + void setConstraints(int width, int height) { if (auto* constrainer = this->getConstrainer()) { @@ -292,7 +295,6 @@ class AbstractPluginEditor dmt::gui::window::Compositor compositor; OpenGLContext openGLContext; - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(AbstractPluginEditor) }; } // namespace app From 8fd15a4352400b1a0707a8faf0b05b1df97b23ce Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Mon, 13 Apr 2026 08:52:17 +0200 Subject: [PATCH 24/74] refactor: standardize version variable naming in CMakeLists.txt --- CMakeLists.txt | 6 +++--- src/CMakeLists.txt | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 10ca7a35..396ed279 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,9 +3,9 @@ #============================================================================== cmake_minimum_required(VERSION 3.30) -file(READ "${CMAKE_CURRENT_LIST_DIR}/VERSION.md" DISFLUX_VERSION) -string(STRIP "${DISFLUX_VERSION}" DISFLUX_VERSION) -project(Disflux VERSION ${DISFLUX_VERSION}) # Disflux-Version +file(READ "${CMAKE_CURRENT_LIST_DIR}/VERSION.md" FILE_VERSION) +string(STRIP "${FILE_VERSION}" FILE_VERSION) +project(Disflux VERSION ${FILE_VERSION}) set(CMAKE_CXX_STANDARD 23) set(CMAKE_SUPPRESS_DEVELOPER_WARNINGS TRUE) set(EXT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 53a60d7f..084093f8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,11 +3,11 @@ #============================================================================== cmake_minimum_required(VERSION 3.22) -if(NOT DEFINED DISFLUX_VERSION) - file(READ "${CMAKE_CURRENT_LIST_DIR}/../VERSION.md" DISFLUX_VERSION) - string(STRIP "${DISFLUX_VERSION}" DISFLUX_VERSION) +if(NOT DEFINED FILE_VERSION) + file(READ "${CMAKE_CURRENT_LIST_DIR}/../VERSION.md" FILE_VERSION) + string(STRIP "${FILE_VERSION}" FILE_VERSION) endif() -project(DisfluxPlugin VERSION ${DISFLUX_VERSION}) # Disflux-Version +project(DisfluxPlugin VERSION ${FILE_VERSION}) # If we are on MacOS, we need to build for arm64 and x86_64 if (APPLE) From edcaa82437355d5fcd40b397331ecec01bb66c6d Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Mon, 13 Apr 2026 08:54:32 +0200 Subject: [PATCH 25/74] refactor: update project name in CMakeLists.txt files --- CMakeLists.txt | 2 +- src/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 396ed279..951f0f5b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ #============================================================================== -# Main CMakeLists.txt file for the Oscilloscope project +# Main CMakeLists.txt file for the Disflux project #============================================================================== cmake_minimum_required(VERSION 3.30) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 084093f8..c057dc47 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,5 @@ #============================================================================== -# Oscilloscope Source Folder CMakeLists.txt file +# Disflux Source Folder CMakeLists.txt file #============================================================================== cmake_minimum_required(VERSION 3.22) From fa2512d7d04f166c3f163af836564cc98f981da3 Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Mon, 13 Apr 2026 09:02:36 +0200 Subject: [PATCH 26/74] refactor: standardize plugin format variable naming in CMakeLists.txt --- src/CMakeLists.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c057dc47..d79427e1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -22,19 +22,19 @@ option(DMT_DISABLE_UPDATE_NOTIFICATION "Disable update notification in the GUI" # JUCE setup if(WIN32) - set(DISFLUX_PLUGIN_FORMATS "VST3;CLAP;Standalone") + set(OS_PLUGIN_FORMATS "VST3;CLAP;Standalone") elseif(APPLE) - set(DISFLUX_PLUGIN_FORMATS "VST3;CLAP;AU;Standalone") + set(OS_PLUGIN_FORMATS "VST3;CLAP;AU;Standalone") elseif(UNIX) - set(DISFLUX_PLUGIN_FORMATS "VST3;CLAP;LV2;Standalone") + set(OS_PLUGIN_FORMATS "VST3;CLAP;LV2;Standalone") else() - set(DISFLUX_PLUGIN_FORMATS "VST3;CLAP;Standalone") + set(OS_PLUGIN_FORMATS "VST3;CLAP;Standalone") endif() juce_add_plugin(${PROJECT_NAME} PRODUCT_NAME "Disflux" COMPANY_NAME "Dimethoxy" - FORMATS ${DISFLUX_PLUGIN_FORMATS} + FORMATS ${OS_PLUGIN_FORMATS} VST3_CATEGORIES "Fx" "Analyzer" IS_SYNTH FALSE NEEDS_MIDI_INPUT FALSE From b24c6c823107f50ee3498fa93242432ac7bdcc3e Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Thu, 16 Apr 2026 23:02:31 +0200 Subject: [PATCH 27/74] Squashed 'src/dmt/' changes from 43e0b73..acd21b9 acd21b9 dsp: prepare model for development c82a142 chore: throw out old shit f10b25f Merge commit '78e5029f6407ced818d1fcdb68197a0abe371fd3' as 'src/dmt' fb87e2a chore: remove non indexed dmt eff753f chore: missing stuff from last commit d45400c chore: copy disflux project to development 9e85611 refactor: minor cleanup shit bd99f88 refactor: fix AbstractPluginEditor abstraction fda349f refactor: move even more logic to AbstractPluginEditor e5d61cf gui: update border button font color to use background color 8949634 refactor: use callback injection to initialize layout in AbstractPluginEditor 58fb8e7 refactor: move more logic to AbstractPluginEditor 8276105 app: refactor plugin editor to inherit from AbstractPluginEditor 34d11c1 gui: fix hdpi scaling not working when ValueEditorList dynamically adds children 54573e9 gui: fix broken hidpi scaling of shadows fbd0cc6 refactor: Move properties and version manager to AbstractPluginProcessor f09144f refactor: Move code from PluginProcessor to AbstractPluginProcessor e650cc5 performance: Optimize size factor propagation in Compositor and AbstractButton 497755e refactor: reorder components in AbstractButton for improved rendering 6d17b04 feat: enhance shadow rendering with melatonin library integration 8ef1ee3 feat: create App.h header file with plugin editor and processor includes 3f2f469 refactor: remove unused AbstractEditor include from Window.h 43f2616 feat: add AbstractPluginEditor and AbstractPluginProcessor header files 788195d refactor: remove AbstractEditor class and associated code d7ed30d gui: add bottom border to BorderBottom 52b1f77 fix: faulty padding for BorderButton in Compositor 2536388 gui: Fix hidpi scaling on macOS by using the main display's scale factor instead of the component's scale factor, which is currently unreliable 6626747 shadows: fix faulty offset and scale on startup 7fa9a50 panel: fix shadows getting cut off by reworking window margin a57489c gui: fix hiDPI scaling of tooltips, alerts, buttons, icons and shadows 27ecf7c misc: cleanup some includes and comments 0d9ac87 oscilloscope: Refactor comments c91587a settings: Change default window margin from 10.0f to 7.0f beea570 gui/slider: Refactor LinearSliderComponent layout and fix a label layout bug from switch falltrough 064b9bf gui/component: Remove conditional macros for slider graphics and labels 1aee225 gui/window: Simplify comments in Compositor layout logic 2aabd06 gui/window: Fix window margin 9b16c98 oscilloscope: Implement MinMaxRenderer for faster rendering dac78c3 oscilloscope: Update rainbow mode f9af077 oscilloscope: Fix scrolling artifacts 7cabe53 oscilloscope: Add rainbow colour mode for debugging 53aeb8c misc: Update file header comments ad38379 gui/widget: Update file headers c8b632c gui/preset: Update file header 2baba82 misc: Update library info and license notice in files 9ff31fa gui/display: Update library info and license notice in all files 39c55b3 gui/component: Update header comments and seperators 4fee81e gui/display: update header ascii art c1f0a39 gui/display: refactor header ascii art 84a2608 component: refactor header ascii art e4e2d8a dsp: refactor header ascii art 28cb2bf doc(renderer): Enhance PathStrokeRenderer documentation fd37272 feat(oscilloscope): Implement dynamic rendering strategy for oscilloscope 1778399 fix(sliders): Enable main slider graphics by setting DMT_EXCLUDE_SLIDER_GRAPHICS to 0 392c17d feat(scripts): Add push_subtree script for git subtree operations b83c92d fix(sliders): Enable slider labels again and disable slider graphics a41a930 fix(sliders): Enable Oscilloscope and disable labels a8b2cd4 fix(panel): Exclude DisfluxDisplay from the build by setting DMT_EXCLUDE_DISFLUX_DISPLAY to 1 e50e8b4 fix(sliders): Enable slider graphics by setting DMT_EXCLUDE_SLIDER_GRAPHICS to 0 a5102fc feat(sliders): Add configuration options to exclude slider graphics and labels 65f9989 Update imports 56c35f7 Need to repair Oscilloscope now 460250b Starting move to shared DMT 5e4c20a Add fps constant to AppSettings bc23fa1 Cleanup OscillatorDisplayComponent b67560a Update OscillatorDisplayComponent settings in AppSettings.h 1126c3c Delete TODO.md 517965e Update rotary slider type and range for voicing panel, adjust thumb size in app settings, and modify semitone display in unit utility 8678460 Refactor distortion effects and update UI eb1c56c Removed old Distortion code a0987fb Updated Selektor 02f3db7 Implemented Selector a7d1b6c Start RotarySelector implementation f81e601 Update envelope parameter default values e397b7b Update default parameters 6415627 Refactor variable and parameter names 828ef81 Refactor SynthVoice 85bc539 Refactor NeutrinoAudioProcessor class 1fdac42 Merge branch 'master' of https://github.com/Dimethoxy/Neutrino dd154dc Update voice parameters and waveform distortion panel abc875b Update TODO.md 19f13eb Refactor oscillator parameters and add waveform distortion and OSC send parameter groups 3ec742d Update AnalogPitchPanel.h with new parameter names and units 4c9c6d4 Update analog gain panel and AHD envelope parameters 17a4da7 Refactor envelope parameter group IDs and names 09f99e4 Refactor model 70e6522 Refactor parameter layout in ParameterLayout.h dd69899 Add VoiceParameters to ParameterLayout 022a146 Add parameters to model 6901cb2 Add new sliders to VoicingPanel.h b9b04e2 Update VoicingPanel layout 7367197 Add sliders to VoicingPanel 3a9c938 Refactor file paths and include statements 8cbd447 Compressed layout 621cc92 Adjust layout and grid points in AnalogPitchPanel and WaveformDistortionPanel 4f2fa57 Fiex layout d431aad Fixed sliders but broke layout bb983e1 Refactor slider bounds and orientation 0a77a94 Set OpenGL context properties and updated layout 3821698 Add OpenGL context to PluginEditor 5c075f2 Fixed resizing bug 00e7714 Removed unimplemented panels from UI 180d6d4 Add LinearSlider to OscSendPanel and update layout 9b75c2e Implemented gridOffsetY to Panel e851651 Fixed pitch and gain evelope panels c624688 Implemented BipolarLinearSlider dc556b3 Implemented LinearSlider Thumb b1418c8 Implemented LinearSlider upper rail drawing bcf26cd Add Analog Waveforms implementation fccc260 Adjust layout and sizing in LinearSliderComponent and WaveformDistortionPanel 1598d01 Fixed lowerRail drawing 53f41c8 Implemented LinearSliderComponent 7561173 Implemented drawing for LinearSLider lower rail 35d2b43 Updated LinearSlider cf1af29 Implemented LinearSlider.setBoundsByPoints() 7fa9b13 Dynamic font scaling for macOS 0508c7e Adjust font size for macOS 17c0022 Fix font size calculation in Label widget and simplify distortion logic 50bbaa2 Add sliders to WaveformDistortionPanel 6520b31 Refactor LOC counting script and add language-specific line count b544f34 Fixed all compiler warnings d82157a Fixed most compiler warnings 5e39fd9 Fixed even more compiler warnings 1751679 Fixed more compiler warnings e6cdd4c Fixed several comiler warnings 6946c56 Updated Label and Panel classes 20f1cff Update font binary data and build script configurations 1a85968 Updated locc.ps1 31f1f64 Renamed workspace settings 5cbf050 Delete output/windows directory ee3669b Fixed IntelliSense and updated AppSettings fc6f708 Fix file paths and variable names 69951f9 Add output/ directory to .gitignore 3a57193 Readded src 9d014f7 Delete src directory d93b2c9 Cleared Gitignore fcdd3dc Improved build script 5747e2c First successful CMake build 2c94bd2 Fixed BinaryData error 2396af2 Renamed source to src 9945cf8 Reupload Folders c4d819c Removed Folders aaa1c87 Finished new root folder structure b592e63 Started changing folder structure 0b1c0b5 Project compiles 950adff Fixed build system 5a8fe9c Changed build system to CMake 9736ecc RotarySelector Boilerplate e79f452 Started new smaller Layout 50b5098 Fixed MacOS compiler Errors 43a02e0 Panel Title is now a Label 6a6ea2a Added Laben to Panel f369be2 Implemented Thumb a019a83 Added Keyboard back 7cd98a2 RotarySlider Nuances 9f205db UpperRail Drawing Routine implemented 0448afe Implemented Rail Drawing Routine f00131e Implemented Tick to RotarySlider.drawShaft() 20f9b09 Implemented drawShaft to RotarySlider 1b3a3b6 Implemented LeakDetection 02ee79b Fixed Carousel not working on first click bd8b441 Implemented RotarySliderLabel 165d05a Refactoring 6d29f0c Fixed PanelLayoutGrid 8f90190 Fixed OscSendPanel 2d9aac6 Completed Slider Plumbing 56dbe98 Reworked SliderComponents 1bfd1be Reworked Slider Widgets 1dbc63c Fixed Layout e4e67ec Fixed Carousels 593910d Stuff 0b18234 Added RotarySlider and implemented new Math Utils 93a18a1 Minor changes to Panel 008d437 Implemented Grid to Panel 5f9483c TriangleButton now looks kinda sick 1367355 Changed Style 749732e I hate refactoring 1752b25 Design changes b01327c Refactoring + Introducing bugs e4d8b77 Triangle Button Shadows bff6aa0 Improved TriangleButton caeb40f TriangleButtons almost fully functional 25e1ac3 TriangleButton Drawing 015a2ea Carousel actually working now 3fcd166 TriangleButtons render now a57b15e Implemented Carousel and TriangleButton e8c46b1 Carousel now partially working 9599b68 Stuff 6fd057e Started implementing TriangleButton 1b48177 Existential Crisis 4ed8074 Started rebuilding GUI 61745e9 Refactoring c4eb788 Namespace Refactoring b5f8cc1 ArcButtonComponent Documentation 88bed70 Documentation added 312c213 Fixed Bugs 6ede060 Refactoring d8dce2a Moved Distortion to Oscillator and changed Bias Implementation c700f0c OscillatorDisplayComponent now updates 6be148a Implemented Path Generation for OscillatorDisplayComponent a77aaa6 More Refactoring fffcaa3 Refactoring 08bebe6 FIxed compiler errors b70c101 Added Semitone and Octave Functionality to Oscillator fed16a7 Bend, PWM and Sync are finally working 100% 07b4b5f Didn't test any of this, but hopefully I fixed the Oscillators Sync, PWM and Bend not working together 3b33754 Implemented Osc Modifier Parameters 7a8c3f3 Removed Docs again + Refactoring 8ff717f Documentation for AnalogOscillator 007a692 More Parameters + Docs 3a56e45 Refactoring 5a2219a Fixed Oscillator 499e27f Almost fixed Oscillator a773417 Design Changes 1411d21 Fixed Math.h... I hope 3970f6d Created Math.h 126d617 Improved Exponential Conversion dc1d229 Added Sync to AnalogOscillator 6204c55 Changes to Bend in AnalogOscillator 5b5b93a Implemented PWM and Bend to AnalogOscillator 74ffb03 Fixed Oscillator 1a8d972 Added Pitch Parameters a049fba Design changes 667f0cf Made LinearSliders work a89c2de Dumb bullshit refactoring 913099a Added more legacy Classes 645ef10 Added Classes for LinearSlider Implementation 8d0db1a More Refactoring 82adaba Refactoring 9308cff Changed Theme 0e4d45c Implemented PanelTop 606063a Minor Changes d8d6644 Fixed AngleButton 0d721a4 Refactoring (mostly) 0538ff5 ArcButton now looks nice 67b0f96 ArcButton now has a basic Triangle d6e7041 Started with ArcButton fa7413d OscillatorDisplayComponent is now round 649c508 Changed Style + Refactoring 401e02f Refactoring dce84d0 Help 23488b3 Struggeling with making a path glow be14511 Partially implemented OscillatorPanel 37e8619 More styling for Panel 90d8e8b Implemented Panel Graphics e063e24 Implemented AppSettings 7c77dfa Implemented more Filters eb39343 Lowpass Implementation f1a11b4 Implemented Filter e537e9a Implemented Filter Callback ab44c13 Implemented Bias for Oscillator 9019596 Even more refactoring e1572d2 More Refactoring d30f9b3 Refactoring ae8665a Implemented more parameters 92a64d0 Refactoring 9654881 Refactoring + Added new Waveforms to Oscillator Class 7365276 Implemented Saturation for Oscillator b751ceb New oscillator + Fixed the god damn popping 99ad848 Connected APVTS to SynthVoice 710c68e Testing 9eaf92b Minor Adjustments c59346c Minor Changes c02a601 Fixed Envelope f9af1e5 AhdEnvelope Implementation a3e7509 Mostly implemented getNextSample for AhdEnvelope 4c763d9 Added AHD State fe5fd5e Added AHD Envelope Class 77721b1 Implemented Triangle Wave 414b3ec Implemented kick sound generation ab77892 Added basic oscillator 9d59906 Edited Projucer settings 524ccac SynthVoice boilerplate 23fa9fb Added SynthVoice and SynthSound 3573073 FolderPanel buttons deee5c7 Fixed preset save bug 41d9171 PresetManager 088e0d1 Add project files. c67abd4 Add .gitattributes, .gitignore, README.md, and LICENSE.txt. git-subtree-dir: src/dmt git-subtree-split: acd21b952a88609c385183eb434e73519de213e9 --- DmtHeader.h | 1 + app/AbstractPluginEditor.h | 301 +++++++++++++++++++++ app/AbstractPluginProcessor.h | 169 ++++++++++++ app/App.h | 6 + configuration/Configuration.h | 25 +- configuration/Container.h | 13 +- configuration/Options.h | 19 +- configuration/Properties.h | 13 +- configuration/TreeAdapter.h | 19 +- dsp/Dsp.h | 30 ++ dsp/data/Data.h | 25 +- dsp/data/FifoAudioBuffer.h | 13 +- dsp/data/RingAudioBuffer.h | 19 +- dsp/data/RingBufferInterface.h | 13 +- dsp/effect/DisfluxProcessor.h | 25 +- dsp/effect/Distortion.h | 25 +- dsp/effect/Effect.h | 25 +- dsp/effect/HeretikProcessor.h | 27 ++ dsp/effect/LowpassProcessor.h | 25 +- dsp/envelope/AdhEnvelope.h | 19 +- dsp/envelope/Envelope.h | 25 +- dsp/filter/Filter.h | 13 +- dsp/synth/AnalogOscillator.h | 40 +-- dsp/synth/AnalogWaveform.h | 19 +- dsp/synth/Synth.h | 13 +- dsp/synth/SynthSound.h | 19 +- dsp/synth/SynthVoice.h | 22 +- gui/Gui.h | 30 ++ gui/component/AbstractSliderComponent.h | 42 ++- gui/component/Component.h | 30 ++ gui/component/LinearSliderComponent.h | 156 +++++++---- gui/component/OscillatorDisplayComponent.h | 31 +++ gui/component/RotarySliderComponent.h | 28 +- gui/component/SettingsEditorComponent.h | 30 ++ gui/display/AbstractDisplay.h | 19 +- gui/display/DisfluxDisplay.h | 23 +- gui/display/Display.h | 29 ++ gui/display/OscilloscopeDisplay.h | 34 +++ gui/display/SettingsEditorDisplay.h | 27 ++ gui/panel/AbstractPanel.h | 19 +- gui/panel/AnalogGainPanel.h | 30 ++ gui/panel/AnalogOscillatorPanel.h | 29 ++ gui/panel/AnalogPitchPanel.h | 29 ++ gui/panel/Carousel.h | 32 +++ gui/panel/DisfluxPanel.h | 19 +- gui/panel/GainPanel.h | 29 ++ gui/panel/HeretikDrivePanel.h | 25 ++ gui/panel/HeretikFeedbackPanel.h | 26 ++ gui/panel/HeretikPanel.h | 26 ++ gui/panel/ModernGainPanel.h | 28 ++ gui/panel/ModernOscillatorPanel.h | 32 ++- gui/panel/ModernPitchPanel.h | 30 ++ gui/panel/OscSendPanel.h | 32 +++ gui/panel/OscillatorPanel.h | 30 ++ gui/panel/OscilloscopePanel.h | 33 +++ gui/panel/Panel.h | 30 ++ gui/panel/PitchPanel.h | 29 ++ gui/panel/SettingsPanel.h | 32 +++ gui/panel/VoicingPanel.h | 30 ++ gui/panel/WaveformDistortionPanel.h | 32 +++ gui/preset/FolderManager.h | 38 ++- gui/preset/FolderPanel.h | 188 +++++++------ gui/preset/PresetManager.h | 39 ++- gui/preset/PresetPanel.h | 40 ++- gui/widget/AbstractButton.h | 57 ++-- gui/widget/BorderButton.h | 36 ++- gui/widget/CallbackButton.h | 19 +- gui/widget/Graph.h | 19 +- gui/widget/Label.h | 21 +- gui/widget/LinearSlider.h | 21 +- gui/widget/MinMaxRenderer.h | 265 ++++++++++++++++++ gui/widget/Oscilloscope.h | 89 +++--- gui/widget/OscilloscopeRenderer.h | 191 +++++++++++++ gui/widget/PathStrokeRenderer.h | 137 ++++++++++ gui/widget/RotarySlider.h | 19 +- gui/widget/Shadow.h | 123 ++++++--- gui/widget/TextEditor.h | 29 ++ gui/widget/ToggleButton.h | 25 +- gui/widget/TriangleButton.h | 19 +- gui/widget/ValueCategoryList.h | 28 ++ gui/widget/ValueEditor.h | 32 +++ gui/widget/ValueEditorList.h | 28 ++ gui/widget/Widget.h | 30 ++ gui/window/AbstractEditor.h | 122 --------- gui/window/Alerts.h | 24 +- gui/window/Compositor.h | 60 ++-- gui/window/Header.h | 22 +- gui/window/Layout.h | 39 ++- gui/window/Popover.h | 26 +- gui/window/Tooltip.h | 33 +-- gui/window/Window.h | 61 ++--- model/AhdEnvelopeParameters.h | 61 ----- model/Model.h | 1 + model/NeutrinoParameters.h | 33 +++ model/OscSendParameterGroup.h | 34 --- model/OscillatorParameters.h | 36 --- model/ParameterLayout.h | 34 --- model/VoiceParameters.h | 104 ------- scripts/push_subtree.sh | 3 + utility/Fonts.h | 19 +- utility/HostContextMenu.h | 26 ++ utility/Icon.h | 19 +- utility/Math.h | 19 +- utility/RepaintTimer.h | 19 +- utility/Scaleable.h | 146 ++++++++-- utility/Settings.h | 36 ++- utility/Unit.h | 19 +- utility/Utility.h | 34 +-- version/Info.h | 19 +- version/Manager.h | 19 +- version/Networking.h | 19 +- version/Utility.h | 19 +- version/Version.h | 34 +-- 113 files changed, 3375 insertions(+), 1302 deletions(-) create mode 100644 app/AbstractPluginEditor.h create mode 100644 app/AbstractPluginProcessor.h create mode 100644 app/App.h create mode 100644 gui/widget/MinMaxRenderer.h create mode 100644 gui/widget/OscilloscopeRenderer.h create mode 100644 gui/widget/PathStrokeRenderer.h delete mode 100644 gui/window/AbstractEditor.h delete mode 100644 model/AhdEnvelopeParameters.h create mode 100644 model/NeutrinoParameters.h delete mode 100644 model/OscSendParameterGroup.h delete mode 100644 model/OscillatorParameters.h delete mode 100644 model/ParameterLayout.h delete mode 100644 model/VoiceParameters.h create mode 100644 scripts/push_subtree.sh diff --git a/DmtHeader.h b/DmtHeader.h index b3390cb6..52f895ff 100644 --- a/DmtHeader.h +++ b/DmtHeader.h @@ -17,6 +17,7 @@ //============================================================================== #include "../melatonin_perfetto/melatonin_perfetto/melatonin_perfetto.h" //============================================================================== +#include "./app/App.h" #include "./configuration/Configuration.h" #include "./dsp/Dsp.h" #include "./gui/Gui.h" diff --git a/app/AbstractPluginEditor.h b/app/AbstractPluginEditor.h new file mode 100644 index 00000000..8e64f76a --- /dev/null +++ b/app/AbstractPluginEditor.h @@ -0,0 +1,301 @@ +#pragma once + +#include "app/AbstractPluginProcessor.h" +#include "gui/window/Compositor.h" +#include +#include + +namespace dmt { +namespace app { +class AbstractPluginEditor + : public juce::AudioProcessorEditor + , protected juce::Timer +{ + using Image = juce::Image; + using ImageComponent = juce::ImageComponent; + using PixelFormat = juce::Image::PixelFormat; + using OpenGLContext = juce::OpenGLContext; + +public: + // Strategy function type for layout initialization + using LayoutInitializer = std::function; + + AbstractPluginEditor(dmt::app::AbstractPluginProcessor& _p, + juce::String _name, + int _baseWidth, + int _baseHeight, + LayoutInitializer&& _layoutInit) + : juce::AudioProcessorEditor(&_p) + , p(_p) + , baseWidth(_baseWidth) + , baseHeight(_baseHeight) + , sizeFactor(p.sizeFactor) + , mainLayout({}, {}) + , compositor(_name, mainLayout, p.apvts, p.properties, sizeFactor) + , compositorAttached(true) + { + // Initialize the layout via strategy function + _layoutInit(mainLayout); + + // Now that layout is fully configured, attach the compositor + addAndMakeVisible(compositor); + + if (OS_IS_WINDOWS) { + setResizable(false, true); + } + + if (OS_IS_DARWIN) { + setResizable(false, true); + } + + if (OS_IS_LINUX) { + openGLContext.setComponentPaintingEnabled(true); + openGLContext.setContinuousRepainting(false); + openGLContext.attachTo(*getTopLevelComponent()); + std::thread([this]() { + for (int i = 0; i < 200; ++i) { + if (openGLContext.isAttached() && + openGLContext.getRawContext() != nullptr) + break; + std::this_thread::sleep_for(std::chrono::milliseconds(25)); + } + + if (!openGLContext.isAttached() || + openGLContext.getRawContext() == nullptr) + return; + + openGLContext.executeOnGLThread( + [](juce::OpenGLContext&) { + if (juce::gl::glDebugMessageControl) { + juce::gl::glDebugMessageControl( + juce::gl::GL_DEBUG_SOURCE_API, + juce::gl::GL_DEBUG_TYPE_OTHER, + juce::gl::GL_DEBUG_SEVERITY_NOTIFICATION, + 0, + nullptr, + juce::gl::GL_FALSE); + } + + if (juce::gl::glDebugMessageCallback) + juce::gl::glDebugMessageCallback(juceFilteredGLDebugCallback, + nullptr); + }, + true); + }).detach(); + } + + setConstraints(baseWidth, baseHeight + headerHeight); + setResizable(false, true); + + const auto startWidth = baseWidth * sizeFactor; + const auto startHeight = (baseHeight + headerHeight) * sizeFactor; + setSize(startWidth, startHeight); + + // Set the callback for header visibility changes + compositor.setHeaderVisibilityCallback([this](bool isHeaderVisible) { + handleHeaderVisibilityChange(isHeaderVisible); + }); + } + + ~AbstractPluginEditor() override = default; + + //============================================================================== + // JUCE overrides + + void paint(juce::Graphics& g) + { + TRACER("PluginEditor::paint"); + + // Just painting the background + g.fillAll(dmt::Settings::Window::backgroundColour); + + if (!compositorAttached && compositorSnapshot.isValid()) { + // Draw the last compositor snapshot, scaled to fit + auto bounds = getLocalBounds().toFloat(); + g.drawImage( + compositorSnapshot, bounds, juce::RectanglePlacement::stretchToFit); + return; + } + } + + void resized() + { + TRACER("PluginEditor::resized"); + + // Set the global size + const int currentHeight = getHeight(); + const float newSize = + (float)currentHeight / + (compositor.isHeaderVisible() ? baseHeight + headerHeight : baseHeight); + + // Make sure the size makes sense + if (newSize <= 0.0f || std::isinf(newSize)) { + jassertfalse; + } + + // Update the processor's scale factor + sizeFactor = newSize; + p.setSizeFactor(newSize); + + // Debounced resizing logic + if (firstDraw) { + // On first draw, skip debounce and just layout normally + compositor.setBounds(getLocalBounds()); + firstDraw = false; + return; + } + detachCompositorForResize(); + } + + //============================================================================== + // JUCE overrides + + void setConstraints(int width, int height) + { + if (auto* constrainer = this->getConstrainer()) { + const auto aspectRatio = (double)width / (double)height; + constrainer->setFixedAspectRatio(aspectRatio); + const auto minWidth = width / 2; + const auto minHeight = height / 2; + const auto maxWidth = width * 2; + const auto maxHeight = height * 2; + constrainer->setSizeLimits(minWidth, minHeight, maxWidth, maxHeight); + } else { + jassertfalse; // Constrainer not set + } + } + + void handleHeaderVisibilityChange(bool isHeaderVisible) + { + const int adjustedHeight = + isHeaderVisible ? baseHeight + headerHeight : baseHeight; + setConstraints(baseWidth, adjustedHeight); + setSize(baseWidth * sizeFactor, adjustedHeight * sizeFactor); + } + + dmt::gui::window::Layout& getMainLayout() { return mainLayout; } + + //============================================================================== + // Debounced resizing + + // Debounce timer callback: reattach compositor and repaint + void timerCallback() override + { + stopTimer(); + attachCompositorAfterResize(); + repaint(); // TODO: Redundanr call, maybe remove this? + } + + // Detach compositor to improve resize performance + void detachCompositorForResize() + { + if (compositorAttached) { + // Take a snapshot before detaching + updateCompositorSnapshot(); + + // Remove compositor from view + removeChildComponent(&compositor); + compositorAttached = false; + } + + // Restart debounce timer (100ms) + stopTimer(); + startTimer(100); + } + + // Reattach compositor and repaint after resizing + void attachCompositorAfterResize() + { + if (!compositorAttached) { + // Snap to the correct aspect ratio, considering header visibility + auto bounds = getLocalBounds(); + bool headerVisible = compositor.isHeaderVisible(); + int aspectHeight = + headerVisible ? (baseHeight + headerHeight) : baseHeight; + const double aspect = (double)baseWidth / (double)aspectHeight; + int w = bounds.getWidth(); + int h = bounds.getHeight(); + double currentAspect = (double)w / (double)h; + + if (currentAspect > aspect) { + // Too wide, adjust width + w = static_cast(h * aspect); + } else if (currentAspect < aspect) { + // Too tall, adjust height + h = static_cast(w / aspect); + } + setSize(w, h); + + // Set compositor bounds to fill the editor + addAndMakeVisible(compositor); + compositor.setBounds(getLocalBounds()); + compositorAttached = true; + repaint(); + } + } + + // Capture the current compositor state into an image for smooth resizing + void updateCompositorSnapshot() + { + // Render compositor to an image at its current size + if (getWidth() > 0 && getHeight() > 0) { + compositorSnapshot = + juce::Image(juce::Image::ARGB, getWidth(), getHeight(), true); + juce::Graphics g(compositorSnapshot); + compositor.paintEntireComponent(g, true); + } + } + + //============================================================================== + // OpenGL debug overwrite + + static void KHRONOS_APIENTRY + juceFilteredGLDebugCallback(GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar* message, + const void* userParam) + { + // Ignore low-priority notifications + if (severity == juce::gl::GL_DEBUG_SEVERITY_NOTIFICATION) + return; + + // Log other messages so we don't lose important info + juce::String msg = + (message != nullptr) ? juce::String(message) : juce::String(); + DBG("OpenGL DBG message: " << msg); + + // Keep JUCE's behaviour for serious errors + if (type == juce::gl::GL_DEBUG_TYPE_ERROR && + severity == juce::gl::GL_DEBUG_SEVERITY_HIGH) + jassertfalse; + } + +protected: + dmt::app::AbstractPluginProcessor& p; + + const int& headerHeight = dmt::Settings::Header::height; + const int baseWidth; + const int baseHeight; + int lastWidth = baseWidth; + int lastHeight = baseHeight; + double ratio = baseWidth / baseHeight; + float& sizeFactor; + bool firstDraw = true; + + juce::Image compositorSnapshot; + bool compositorAttached = true; + + Image image; + bool isResizing = false; + + dmt::gui::window::Layout mainLayout; + dmt::gui::window::Compositor compositor; + + OpenGLContext openGLContext; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(AbstractPluginEditor) +}; +} // namespace app +} // namespace dmt \ No newline at end of file diff --git a/app/AbstractPluginProcessor.h b/app/AbstractPluginProcessor.h new file mode 100644 index 00000000..ad653104 --- /dev/null +++ b/app/AbstractPluginProcessor.h @@ -0,0 +1,169 @@ +#pragma once + +#include "configuration/Properties.h" +#include "version/Manager.h" +#include + +namespace dmt { +namespace app { +class AbstractPluginProcessor : public juce::AudioProcessor +{ +public: + //============================================================================== + AbstractPluginProcessor( + std::function + createParameterLayout) + : AudioProcessor( + BusesProperties() +#if !JucePlugin_IsMidiEffect +#if !JucePlugin_IsSynth + .withInput("Input", juce::AudioChannelSet::stereo(), true) +#endif + .withOutput("Output", juce::AudioChannelSet::stereo(), true) +#endif + ) + , apvts(*this, nullptr, ProjectInfo::projectName, createParameterLayout()) + { +#if PERFETTO + MelatoninPerfetto::get().beginSession(); +#endif + properties.initialize(); + } + + //============================================================================== + ~AbstractPluginProcessor() override + { +#if PERFETTO + MelatoninPerfetto::get().endSession(); +#endif + } + + //============================================================================== + // Program Management + + double getTailLengthSeconds() const { return 0.0; } + + int getNumPrograms() + { + return 1; // NB: some hosts don't cope very well if you tell them there are + // 0 programs, so this should be at least 1, even if you're not + // really implementing programs. + } + + int getCurrentProgram() { return 0; } + + void setCurrentProgram(int index) { juce::ignoreUnused(index); } + + const juce::String getProgramName(int index) + { + juce::ignoreUnused(index); + return {}; + } + + void changeProgramName(int index, const juce::String& newName) + { + juce::ignoreUnused(index, newName); + } + + //============================================================================== + // Midi + + bool acceptsMidi() const override + { +#if JucePlugin_WantsMidiInput + return true; +#else + return false; +#endif + } + bool producesMidi() const override + { +#if JucePlugin_ProducesMidiOutput + return true; +#else + return false; +#endif + } + + bool isMidiEffect() const override + { +#if JucePlugin_IsMidiEffect + return true; +#else + return false; +#endif + } + + //============================================================================== + // Preset Save/Load + + void getStateInformation(juce::MemoryBlock& destData) override + { + juce::MemoryOutputStream mos(destData, true); + apvts.state.writeToStream(mos); + } + + void setStateInformation(const void* data, int sizeInBytes) override + { + auto tree = juce::ValueTree::readFromData(data, sizeInBytes); + if (tree.isValid()) { + apvts.replaceState(tree); + } + } + + //============================================================================== + // + + bool isBusesLayoutSupported(const BusesLayout& layouts) const + { +#if JucePlugin_IsMidiEffect + juce::ignoreUnused(layouts); + return true; +#else + // This is the place where you check if the layout is supported. + // In this template code we only support mono or stereo. + // Some plugin hosts, such as certain GarageBand versions, will only + // load plugins that support stereo bus layouts. + if (layouts.getMainOutputChannelSet() != juce::AudioChannelSet::mono() && + layouts.getMainOutputChannelSet() != juce::AudioChannelSet::stereo()) + return false; + + // This checks if the input layout matches the output layout +#if !JucePlugin_IsSynth + if (layouts.getMainOutputChannelSet() != layouts.getMainInputChannelSet()) + return false; +#endif + + return true; +#endif + } + + bool hasEditor() const + { + return true; // (change this to false if you choose to not supply an editor) + } + +public: + //============================================================================== + juce::AudioProcessorValueTreeState apvts; + + //============================================================================== + dmt::configuration::Properties properties; + dmt::version::Manager versionManager; + + //============================================================================== + float sizeFactor = 1.0f; + float getSizeFactor() const { return sizeFactor; } + void setSizeFactor(float newSize) { sizeFactor = newSize; } + + //============================================================================== +private: +#if PERFETTO + std::unique_ptr tracingSession; +#endif + + //============================================================================== + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(AbstractPluginProcessor) +}; +} +} \ No newline at end of file diff --git a/app/App.h b/app/App.h new file mode 100644 index 00000000..eb72dd03 --- /dev/null +++ b/app/App.h @@ -0,0 +1,6 @@ +#pragma once + +//============================================================================== + +#include "./AbstractPluginEditor.h" +#include "./AbstractPluginProcessor.h" \ No newline at end of file diff --git a/configuration/Configuration.h b/configuration/Configuration.h index 0e8bda0d..b33efed7 100644 --- a/configuration/Configuration.h +++ b/configuration/Configuration.h @@ -1,22 +1,21 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and - * modify this code under the terms of this license. You must adhere GPLv3 - * license for any project using this code or parts of it. Your are not allowed - * to use this code in any closed-source project. + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. * * Description: * Configuration header to include all necessary configuration files. diff --git a/configuration/Container.h b/configuration/Container.h index 457d364a..7da22e0e 100644 --- a/configuration/Container.h +++ b/configuration/Container.h @@ -1,11 +1,10 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * * This file is part of the Dimethoxy Library, a collection of essential diff --git a/configuration/Options.h b/configuration/Options.h index 5f0fb6e3..909d3c98 100644 --- a/configuration/Options.h +++ b/configuration/Options.h @@ -1,16 +1,15 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and diff --git a/configuration/Properties.h b/configuration/Properties.h index 14890344..45f37550 100644 --- a/configuration/Properties.h +++ b/configuration/Properties.h @@ -1,11 +1,10 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * * This file is part of the Dimethoxy Library, a collection of essential diff --git a/configuration/TreeAdapter.h b/configuration/TreeAdapter.h index 0535b480..0ef3bf36 100644 --- a/configuration/TreeAdapter.h +++ b/configuration/TreeAdapter.h @@ -1,16 +1,15 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and diff --git a/dsp/Dsp.h b/dsp/Dsp.h index 4eb9cdee..3e197b51 100644 --- a/dsp/Dsp.h +++ b/dsp/Dsp.h @@ -1,4 +1,34 @@ +//============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * DSP header file. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== + #pragma once + +//============================================================================== + #include "./data/Data.h" #include "./effect/Effect.h" #include "./envelope/Envelope.h" diff --git a/dsp/data/Data.h b/dsp/data/Data.h index 3cd37b70..f24fab8d 100644 --- a/dsp/data/Data.h +++ b/dsp/data/Data.h @@ -1,22 +1,21 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and - * modify this code under the terms of this license. You must adhere GPLv3 - * license for any project using this code or parts of it. Your are not allowed - * to use this code in any closed-source project. + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. * * Description: * Data header to include all necessary data files. diff --git a/dsp/data/FifoAudioBuffer.h b/dsp/data/FifoAudioBuffer.h index 251327ad..ec5d6388 100644 --- a/dsp/data/FifoAudioBuffer.h +++ b/dsp/data/FifoAudioBuffer.h @@ -1,11 +1,10 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * * This file is part of the Dimethoxy Library, a collection of essential diff --git a/dsp/data/RingAudioBuffer.h b/dsp/data/RingAudioBuffer.h index 18ebd641..1b12b020 100644 --- a/dsp/data/RingAudioBuffer.h +++ b/dsp/data/RingAudioBuffer.h @@ -1,16 +1,15 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and diff --git a/dsp/data/RingBufferInterface.h b/dsp/data/RingBufferInterface.h index 79ad9bfa..1c0741fd 100644 --- a/dsp/data/RingBufferInterface.h +++ b/dsp/data/RingBufferInterface.h @@ -1,11 +1,10 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * * This file is part of the Dimethoxy Library, a collection of essential diff --git a/dsp/effect/DisfluxProcessor.h b/dsp/effect/DisfluxProcessor.h index af401b7a..33ab1884 100644 --- a/dsp/effect/DisfluxProcessor.h +++ b/dsp/effect/DisfluxProcessor.h @@ -1,22 +1,21 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and - * modify this code under the terms of this license. You must adhere GPLv3 - * license for any project using this code or parts of it. Your are not allowed - * to use this code in any closed-source project. + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. * * Description: * Disflux Processor class for processing audio buffers with a series of diff --git a/dsp/effect/Distortion.h b/dsp/effect/Distortion.h index 10cba38f..93c16c03 100644 --- a/dsp/effect/Distortion.h +++ b/dsp/effect/Distortion.h @@ -1,22 +1,21 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and - * modify this code under the terms of this license. You must adhere GPLv3 - * license for any project using this code or parts of it. Your are not allowed - * to use this code in any closed-source project. + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. * * Description: * Distortion effect processor. diff --git a/dsp/effect/Effect.h b/dsp/effect/Effect.h index 6f926b30..5224abb6 100644 --- a/dsp/effect/Effect.h +++ b/dsp/effect/Effect.h @@ -1,22 +1,21 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and - * modify this code under the terms of this license. You must adhere GPLv3 - * license for any project using this code or parts of it. Your are not allowed - * to use this code in any closed-source project. + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. * * Description: * Effect header file. diff --git a/dsp/effect/HeretikProcessor.h b/dsp/effect/HeretikProcessor.h index 0f52e9de..f86e3b77 100644 --- a/dsp/effect/HeretikProcessor.h +++ b/dsp/effect/HeretikProcessor.h @@ -1,4 +1,31 @@ //============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * This file defines the HeretikProcessor class, which applies a special kind of + * distortion effect to audio buffers that is based on a delay line that is + * modulated by the input signal. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== #pragma once diff --git a/dsp/effect/LowpassProcessor.h b/dsp/effect/LowpassProcessor.h index b2be93e1..9e1eccb2 100644 --- a/dsp/effect/LowpassProcessor.h +++ b/dsp/effect/LowpassProcessor.h @@ -1,22 +1,21 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and - * modify this code under the terms of this license. You must adhere GPLv3 - * license for any project using this code or parts of it. Your are not allowed - * to use this code in any closed-source project. + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. * * Description: * Lowpass Processor class for processing audio buffers with a low-pass filter. diff --git a/dsp/envelope/AdhEnvelope.h b/dsp/envelope/AdhEnvelope.h index 323b450b..2e184ebf 100644 --- a/dsp/envelope/AdhEnvelope.h +++ b/dsp/envelope/AdhEnvelope.h @@ -1,16 +1,15 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and diff --git a/dsp/envelope/Envelope.h b/dsp/envelope/Envelope.h index 53525148..51354545 100644 --- a/dsp/envelope/Envelope.h +++ b/dsp/envelope/Envelope.h @@ -1,22 +1,21 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and - * modify this code under the terms of this license. You must adhere GPLv3 - * license for any project using this code or parts of it. Your are not allowed - * to use this code in any closed-source project. + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. * * Description: * Envelope header file. diff --git a/dsp/filter/Filter.h b/dsp/filter/Filter.h index 18bd90f8..238f438b 100644 --- a/dsp/filter/Filter.h +++ b/dsp/filter/Filter.h @@ -1,11 +1,10 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * * This file is part of the Dimethoxy Library, a collection of essential diff --git a/dsp/synth/AnalogOscillator.h b/dsp/synth/AnalogOscillator.h index bab36c58..6dc04b0b 100644 --- a/dsp/synth/AnalogOscillator.h +++ b/dsp/synth/AnalogOscillator.h @@ -1,22 +1,21 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and - * modify this code under the terms of this license. You must adhere GPLv3 - * license for any project using this code or parts of it. Your are not allowed - * to use this code in any closed-source project. + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. * * Description: * High-performance analog oscillator for real-time audio synthesis. @@ -123,9 +122,10 @@ class alignas(64) AnalogOscillator * @brief Sets the drive level for waveform distortion. * @param _newDrive The new drive level. */ - inline void setDrive(const float _newDrive) noexcept { + inline void setDrive(const float _newDrive) noexcept + { TRACER("AnalogOscillator::setDrive"); - drive = _newDrive; + drive = _newDrive; } //============================================================================== @@ -133,9 +133,10 @@ class alignas(64) AnalogOscillator * @brief Sets the bias level for waveform distortion. * @param _newBias The new bias level. */ - inline void setBias(const float _newBias) noexcept { + inline void setBias(const float _newBias) noexcept + { TRACER("AnalogOscillator::setBias"); - bias = _newBias; + bias = _newBias; } //============================================================================== @@ -143,9 +144,10 @@ class alignas(64) AnalogOscillator * @brief Sets the initial phase of the oscillator. * @param _newPhase The new phase value. */ - inline void setPhase(const float _newPhase) noexcept { + inline void setPhase(const float _newPhase) noexcept + { TRACER("AnalogOscillator::setPhase"); - phase = _newPhase; + phase = _newPhase; } //============================================================================== diff --git a/dsp/synth/AnalogWaveform.h b/dsp/synth/AnalogWaveform.h index 2a586e8e..a590cc4d 100644 --- a/dsp/synth/AnalogWaveform.h +++ b/dsp/synth/AnalogWaveform.h @@ -1,16 +1,15 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and diff --git a/dsp/synth/Synth.h b/dsp/synth/Synth.h index bb503490..54b42c87 100644 --- a/dsp/synth/Synth.h +++ b/dsp/synth/Synth.h @@ -1,11 +1,10 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * * This file is part of the Dimethoxy Library, a collection of essential diff --git a/dsp/synth/SynthSound.h b/dsp/synth/SynthSound.h index 2573b7aa..a9bd8c27 100644 --- a/dsp/synth/SynthSound.h +++ b/dsp/synth/SynthSound.h @@ -1,16 +1,15 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and diff --git a/dsp/synth/SynthVoice.h b/dsp/synth/SynthVoice.h index e9ad4462..0be08335 100644 --- a/dsp/synth/SynthVoice.h +++ b/dsp/synth/SynthVoice.h @@ -1,16 +1,15 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and @@ -99,7 +98,8 @@ class alignas(64) SynthVoice : public juce::SynthesiserVoice * * @param newPitchWheelValue The new value of the pitch wheel. */ - void pitchWheelMoved(int /*newPitchWheelValue*/) noexcept override { + void pitchWheelMoved(int /*newPitchWheelValue*/) noexcept override + { TRACER("SynthVoice::pitchWheelMoved"); } diff --git a/gui/Gui.h b/gui/Gui.h index 661e0f8e..3dab4b5d 100644 --- a/gui/Gui.h +++ b/gui/Gui.h @@ -1,4 +1,34 @@ +//============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * Gui header file. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== + #pragma once + +//============================================================================== + #include "./component/Component.h" #include "./display/Display.h" #include "./panel/Panel.h" diff --git a/gui/component/AbstractSliderComponent.h b/gui/component/AbstractSliderComponent.h index 9d70d1a5..d9ee4b12 100644 --- a/gui/component/AbstractSliderComponent.h +++ b/gui/component/AbstractSliderComponent.h @@ -1,12 +1,37 @@ -/** - * @file AbstractSliderComponent.h - * @description - * @author - * @copyright +//============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * AbstractSliderComponent provides a base class for slider components with + * parameter binding, labels, and context menu support. It encapsulates common + * logic for displaying the parameter value with units and showing the host + * context menu. + * + * Authors: + * Lunix-420 (Primary Author) */ +//============================================================================== #pragma once +//============================================================================== + #include "gui/widget/Label.h" #include "utility/Fonts.h" #include "utility/HostContextMenu.h" @@ -14,18 +39,21 @@ #include "utility/Unit.h" #include +//============================================================================== + namespace dmt { namespace gui { namespace component { +//============================================================================== /** * @brief Abstract base class for slider components with parameter binding, * labels, and context menu. * * @details * Encapsulates common logic for parameter binding, title/info labels, unit - * display, and context menu. Derived classes should implement layout, painting, - * and slider instantiation. + * display, and context menu. Derived classes should implement layout, + * painting, and slider instantiation. */ template class AbstractSliderComponent diff --git a/gui/component/Component.h b/gui/component/Component.h index ce22671e..5f73c825 100644 --- a/gui/component/Component.h +++ b/gui/component/Component.h @@ -1,4 +1,34 @@ +//============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * Component header file. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== + #pragma once + +//============================================================================== + #include "./LinearSliderComponent.h" #include "./OscillatorDisplayComponent.h" #include "./RotarySliderComponent.h" diff --git a/gui/component/LinearSliderComponent.h b/gui/component/LinearSliderComponent.h index 7c8f9826..8b67b656 100644 --- a/gui/component/LinearSliderComponent.h +++ b/gui/component/LinearSliderComponent.h @@ -1,16 +1,15 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and @@ -29,7 +28,9 @@ //============================================================================== #pragma once + //============================================================================== + #include "gui/component/AbstractSliderComponent.h" #include "gui/widget/Label.h" #include "gui/widget/LinearSlider.h" @@ -39,12 +40,18 @@ #include "utility/Settings.h" #include "utility/Unit.h" #include + //============================================================================== + +// Slider graphics and labels are always included; remove conditional macros + +//============================================================================== + namespace dmt { namespace gui { namespace component { -//============================================================================== +//============================================================================== /** * @brief Composite slider component with optional SVG title and parameter * binding. @@ -132,47 +139,85 @@ class LinearSliderComponent slider.setAlwaysOnTop(true); switch (orientation) { case Orientation::Horizontal: { - const int32_t rawHorizontalSliderOffset = - static_cast(1.0f * this->size); - const juce::Point offset(0, rawHorizontalSliderOffset); - const auto centre = bounds.getCentre() + offset; - auto sliderBounds = - bounds.reduced(static_cast(padding)).withCentre(centre); - slider.setBounds( - bounds.reduced(static_cast(padding)).withCentre(centre)); - auto titleLabelBounds = sliderBounds; - const auto titleLabelHeight = - static_cast(2 * titleFontSize * this->size); - const auto titleLabelOffset = static_cast(4 * this->size); - const auto titleSliderBounds = - titleLabelBounds.removeFromTop(titleLabelHeight) - .reduced(titleLabelOffset); - this->titleLabel.setBounds(titleSliderBounds); - auto infoLabelBounds = sliderBounds; - const auto infoLabelHeight = - static_cast(2 * infoFontSize * this->size); - const auto infoLabelOffset = static_cast(9 * this->size); - const auto infoSliderBounds = - infoLabelBounds.removeFromBottom(infoLabelHeight) - .reduced(infoLabelOffset); - this->infoLabel.setBounds(infoSliderBounds); + layoutHorizontal(bounds, padding); + break; } case Orientation::Vertical: { - this->titleLabel.setBounds( - bounds.withTrimmedTop(static_cast(padding))); - this->infoLabel.setBounds( - bounds.withTrimmedBottom(static_cast(padding))); - - auto sliderBounds = bounds; - sliderBounds.removeFromTop( - static_cast(titleFontSize * this->size + padding)); - sliderBounds.removeFromBottom( - static_cast(infoFontSize * this->size + padding)); - slider.setBounds(sliderBounds); + layoutVertical(bounds, padding); + break; } } } + /** + * @brief Lays out the child components for horizontal orientation. + * + * @param bounds The bounds of the component. + * @param padding The padding to apply around the components. + * + * @details + * Arranges the slider in the center with title and info labels above and + * below, respectively. Padding and font sizes are scaled for DPI awareness. + */ + void layoutHorizontal(juce::Rectangle bounds, float padding) noexcept + { + // Calculate the center point and offset for the slider + const int rawHorizontalSliderOffset = static_cast(this->size); + const juce::Point offset(0, rawHorizontalSliderOffset); + const auto centre = bounds.getCentre() + offset; + + // Main slider bounds + auto sliderBounds = + bounds.reduced(static_cast(padding)).withCentre(centre); + slider.setBounds( + bounds.reduced(static_cast(padding)).withCentre(centre)); + + // Title label bounds + auto titleLabelBounds = sliderBounds; + const auto titleLabelHeight = + static_cast(2 * titleFontSize * this->size); + const auto titleLabelOffset = static_cast(4 * this->size); + const auto titleSliderBounds = + titleLabelBounds.removeFromTop(titleLabelHeight) + .reduced(titleLabelOffset); + this->titleLabel.setBounds(titleSliderBounds); + + // Info label bounds + auto infoLabelBounds = sliderBounds; + const auto infoLabelHeight = + static_cast(2 * infoFontSize * this->size); + const auto infoLabelOffset = static_cast(9 * this->size); + const auto infoSliderBounds = + infoLabelBounds.removeFromBottom(infoLabelHeight) + .reduced(infoLabelOffset); + this->infoLabel.setBounds(infoSliderBounds); + } + + /** + * @brief Lays out the child components for vertical orientation. + * + * @param bounds The bounds of the component. + * @param padding The padding to apply around the components. + * + * @details + * Arranges the slider in the center with title and info labels above and + * below, respectively. Padding and font sizes are scaled for DPI awareness. + */ + void layoutVertical(juce::Rectangle bounds, float padding) noexcept + { + this->titleLabel.setBounds( + bounds.withTrimmedTop(static_cast(padding))); + this->infoLabel.setBounds( + bounds.withTrimmedBottom(static_cast(padding))); + + auto sliderBounds = bounds; + sliderBounds.removeFromTop( + static_cast(titleFontSize * this->size + padding)); + sliderBounds.removeFromBottom( + static_cast(infoFontSize * this->size + padding)); + slider.setBounds(sliderBounds); + } + /** * @brief Paints the component, including optional SVG icon. * @@ -225,8 +270,8 @@ class LinearSliderComponent * Used for interactive placement or resizing. Ensures minimum size and * orientation-specific layout. */ - inline void setBoundsByPoints(juce::Point _primaryPoint, - juce::Point _secondaryPoint) noexcept + inline void setBoundsByPoints(juce::Point _primaryPoint, + juce::Point _secondaryPoint) noexcept { TRACER("LinearSliderComponent::setBoundsByPoints"); const float padding = 2.0f * rawPadding * this->size; @@ -234,21 +279,20 @@ class LinearSliderComponent const float minWidth = 40 * this->size; const auto centre = (_primaryPoint + _secondaryPoint).toFloat() / 2.0f; - const int32_t pointDistance = - _primaryPoint.getDistanceFrom(_secondaryPoint); + const int pointDistance = _primaryPoint.getDistanceFrom(_secondaryPoint); switch (orientation) { case Orientation::Horizontal: { - setBounds(juce::Rectangle() - .withSize(pointDistance, static_cast(minHeight)) - .expanded(static_cast(padding)) + setBounds(juce::Rectangle() + .withSize(pointDistance, static_cast(minHeight)) + .expanded(static_cast(padding)) .withCentre(centre.toInt())); return; } case Orientation::Vertical: { - setBounds(juce::Rectangle() - .withSize(static_cast(minWidth), pointDistance) - .expanded(static_cast(padding)) + setBounds(juce::Rectangle() + .withSize(static_cast(minWidth), pointDistance) + .expanded(static_cast(padding)) .withCentre(centre.toInt())); return; } diff --git a/gui/component/OscillatorDisplayComponent.h b/gui/component/OscillatorDisplayComponent.h index b60849f1..5bc25d84 100644 --- a/gui/component/OscillatorDisplayComponent.h +++ b/gui/component/OscillatorDisplayComponent.h @@ -1,7 +1,38 @@ //============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * OscillatorDisplayComponent provides a real-time visualization of an + * oscillator's waveform. It uses a lookup table to efficiently render the + * waveform based on the current oscillator parameters. The component supports + * customizable shadows for enhanced visual appeal and is designed to be + * responsive to parameter changes, updating the display accordingly. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== #pragma once +//============================================================================== + #include "dsp/synth/AnalogOscillator.h" #include "gui/widget/Shadow.h" #include "utility/Settings.h" diff --git a/gui/component/RotarySliderComponent.h b/gui/component/RotarySliderComponent.h index b4fbcfd2..538e490f 100644 --- a/gui/component/RotarySliderComponent.h +++ b/gui/component/RotarySliderComponent.h @@ -1,16 +1,15 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and @@ -29,7 +28,9 @@ //============================================================================== #pragma once + //============================================================================== + #include "gui/component/AbstractSliderComponent.h" #include "gui/widget/Label.h" #include "gui/widget/RotarySlider.h" @@ -39,13 +40,18 @@ #include "utility/Settings.h" #include "utility/Unit.h" #include + +//============================================================================== + +// Slider graphics and labels are always included; remove conditional macros + //============================================================================== namespace dmt { namespace gui { namespace component { -//============================================================================== +//============================================================================== /** * @brief Composite rotary slider component with parameter binding and context * menu. diff --git a/gui/component/SettingsEditorComponent.h b/gui/component/SettingsEditorComponent.h index 6ab35fe3..7f4f164b 100644 --- a/gui/component/SettingsEditorComponent.h +++ b/gui/component/SettingsEditorComponent.h @@ -1,4 +1,34 @@ //============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * SettingsEditorComponent provides a user interface for editing application + * settings in a structured and user-friendly way. It displays settings + * categories in a scrollable list on the left, and when a category is selected, + * it shows the corresponding settings editors on the right. The component + * supports dynamic resizing, customizable scrollbars, and is designed to be + * easily extendable for different types of settings. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== #pragma once diff --git a/gui/display/AbstractDisplay.h b/gui/display/AbstractDisplay.h index 02bca8fc..46f868eb 100644 --- a/gui/display/AbstractDisplay.h +++ b/gui/display/AbstractDisplay.h @@ -1,16 +1,15 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and diff --git a/gui/display/DisfluxDisplay.h b/gui/display/DisfluxDisplay.h index f0206846..bd1e41e6 100644 --- a/gui/display/DisfluxDisplay.h +++ b/gui/display/DisfluxDisplay.h @@ -1,16 +1,15 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and @@ -28,14 +27,18 @@ #pragma once +//============================================================================== + #include "dsp/data/FifoAudioBuffer.h" #include "gui/display/OscilloscopeDisplay.h" #include //============================================================================== + namespace dmt { namespace gui { namespace display { + //============================================================================== /** diff --git a/gui/display/Display.h b/gui/display/Display.h index 2bc6ad2a..35446bff 100644 --- a/gui/display/Display.h +++ b/gui/display/Display.h @@ -1,5 +1,34 @@ +//============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided.. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * Display header file. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== + #pragma once +//============================================================================== + #include "./AbstractDisplay.h" #include "./DisfluxDisplay.h" #include "./OscilloscopeDisplay.h" diff --git a/gui/display/OscilloscopeDisplay.h b/gui/display/OscilloscopeDisplay.h index 192cae4a..bf6866e4 100644 --- a/gui/display/OscilloscopeDisplay.h +++ b/gui/display/OscilloscopeDisplay.h @@ -1,5 +1,36 @@ +//============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * OscilloscopeDisplay provides a real-time visualization of the audios + * waveform. It uses a ring buffer to efficiently render the waveform based on + * the current audio data. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== + #pragma once + //============================================================================== + #include "dsp/data/FifoAudioBuffer.h" #include "dsp/data/RingAudioBuffer.h" #include "gui/display/AbstractDisplay.h" @@ -8,10 +39,13 @@ #include "utility/RepaintTimer.h" #include "utility/Settings.h" #include + //============================================================================== + namespace dmt { namespace gui { namespace display { + //============================================================================== template class OscilloscopeDisplay diff --git a/gui/display/SettingsEditorDisplay.h b/gui/display/SettingsEditorDisplay.h index 9fda5560..1249db4a 100644 --- a/gui/display/SettingsEditorDisplay.h +++ b/gui/display/SettingsEditorDisplay.h @@ -1,4 +1,31 @@ //============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * AbstractDisplay provides a base class for all display components + * that require custom painting, shadow/border rendering, and repaint timing. + * Designed for extensibility and real-time GUI performance. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== #pragma once diff --git a/gui/panel/AbstractPanel.h b/gui/panel/AbstractPanel.h index cc6a0ce3..e18aab3d 100644 --- a/gui/panel/AbstractPanel.h +++ b/gui/panel/AbstractPanel.h @@ -1,16 +1,15 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and diff --git a/gui/panel/AnalogGainPanel.h b/gui/panel/AnalogGainPanel.h index 92598f19..7f0b556b 100644 --- a/gui/panel/AnalogGainPanel.h +++ b/gui/panel/AnalogGainPanel.h @@ -1,15 +1,45 @@ //============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * AnalogGainPanel is a GUI component that provides controls for an analog gain + * envelope. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== #pragma once +//============================================================================== + #include "gui/component/LinearSliderComponent.h" #include "gui/panel/AbstractPanel.h" #include //============================================================================== + namespace dmt { namespace gui { namespace panel { + //============================================================================== class AnalogGainPanel : public dmt::gui::panel::AbstractPanel { diff --git a/gui/panel/AnalogOscillatorPanel.h b/gui/panel/AnalogOscillatorPanel.h index bb12fd19..1ad9f7df 100644 --- a/gui/panel/AnalogOscillatorPanel.h +++ b/gui/panel/AnalogOscillatorPanel.h @@ -1,14 +1,43 @@ //============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * AnalogOscillatorPanel is a GUI component that provides controls for an analog + * oscillator. + * + * Authors: Lunix-420 (Primary Author) + */ +//============================================================================== #pragma once +//============================================================================== + #include "gui/panel/AbstractPanel.h" #include //============================================================================== + namespace dmt { namespace gui { namespace panel { + //============================================================================== class AnalogOscillatorPanel : public dmt::gui::panel::AbstractPanel { diff --git a/gui/panel/AnalogPitchPanel.h b/gui/panel/AnalogPitchPanel.h index 9c0cc504..22228368 100644 --- a/gui/panel/AnalogPitchPanel.h +++ b/gui/panel/AnalogPitchPanel.h @@ -1,15 +1,44 @@ //============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * AnalogPitchPanel is a GUI component that provides controls for an analog + * pitch envelope. + * + * Authors: Lunix-420 (Primary Author) + */ +//============================================================================== #pragma once +//============================================================================== + #include "gui/component/LinearSliderComponent.h" #include "gui/panel/AbstractPanel.h" #include //============================================================================== + namespace dmt { namespace gui { namespace panel { + //============================================================================== class AnalogPitchPanel : public dmt::gui::panel::AbstractPanel { diff --git a/gui/panel/Carousel.h b/gui/panel/Carousel.h index 528cf9e9..7abe9da3 100644 --- a/gui/panel/Carousel.h +++ b/gui/panel/Carousel.h @@ -1,11 +1,43 @@ +//============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * Carousel is a GUI component that manages multiple AbstractPanel instances, + * allowing navigation between them using next and previous buttons. + * + * Authors: Lunix-420 (Primary Author) + */ +//============================================================================== + #pragma once + //============================================================================== + #include "gui/panel/AbstractPanel.h" #include + //============================================================================== + namespace dmt { namespace gui { namespace panel { + //============================================================================== class Carousel : public juce::Component { diff --git a/gui/panel/DisfluxPanel.h b/gui/panel/DisfluxPanel.h index 611f416a..a915bba4 100644 --- a/gui/panel/DisfluxPanel.h +++ b/gui/panel/DisfluxPanel.h @@ -1,16 +1,15 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and diff --git a/gui/panel/GainPanel.h b/gui/panel/GainPanel.h index 979c6370..02e8f4cc 100644 --- a/gui/panel/GainPanel.h +++ b/gui/panel/GainPanel.h @@ -1,7 +1,34 @@ //============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * GainPanel is a GUI component that provides controls for gain envelopes. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== #pragma once +//============================================================================== + #include "gui/panel/AbstractPanel.h" #include "gui/panel/AnalogGainPanel.h" #include "gui/panel/Carousel.h" @@ -9,9 +36,11 @@ #include //============================================================================== + namespace dmt { namespace gui { namespace panel { + //============================================================================== class GainPanel : public dmt::gui::panel::Carousel { diff --git a/gui/panel/HeretikDrivePanel.h b/gui/panel/HeretikDrivePanel.h index 7ad659ae..ddd699f5 100644 --- a/gui/panel/HeretikDrivePanel.h +++ b/gui/panel/HeretikDrivePanel.h @@ -1,4 +1,29 @@ //============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * HeretikDrivePanel is one of three panels used to control the Heretik effect. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== #pragma once diff --git a/gui/panel/HeretikFeedbackPanel.h b/gui/panel/HeretikFeedbackPanel.h index dd0913e0..55f17ea2 100644 --- a/gui/panel/HeretikFeedbackPanel.h +++ b/gui/panel/HeretikFeedbackPanel.h @@ -1,4 +1,30 @@ //============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * HeretikFeedbackPanel is one of three panels used to control the Heretik + * effect. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== #pragma once diff --git a/gui/panel/HeretikPanel.h b/gui/panel/HeretikPanel.h index 1f1f62cf..8263c04a 100644 --- a/gui/panel/HeretikPanel.h +++ b/gui/panel/HeretikPanel.h @@ -1,4 +1,30 @@ //============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * DisfluxPanel is the main panel for the Disflux effect. + * It also comes with an oscilloscope display. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== #pragma once diff --git a/gui/panel/ModernGainPanel.h b/gui/panel/ModernGainPanel.h index a4abddfb..71dbf730 100644 --- a/gui/panel/ModernGainPanel.h +++ b/gui/panel/ModernGainPanel.h @@ -1,7 +1,35 @@ //============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * ModernGainPanel is a GUI component that provides controls for modern gain + * envelopes. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== #pragma once +//============================================================================== + #include "gui/panel/AbstractPanel.h" #include diff --git a/gui/panel/ModernOscillatorPanel.h b/gui/panel/ModernOscillatorPanel.h index 258372a9..ebcf1d6c 100644 --- a/gui/panel/ModernOscillatorPanel.h +++ b/gui/panel/ModernOscillatorPanel.h @@ -1,18 +1,48 @@ //============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * ModernOscillatorPanel is a GUI component that provides controls for modern + * oscillators. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== #pragma once +//============================================================================== + #include "gui/panel/AbstractPanel.h" #include //============================================================================== + namespace dmt { namespace gui { namespace panel { + //============================================================================== + class ModernOscillatorPanel : public dmt::gui::panel::AbstractPanel { - public: ModernOscillatorPanel(/*juce::AudioProcessorValueTreeState& apvts*/) : AbstractPanel("Modern Oscillator") diff --git a/gui/panel/ModernPitchPanel.h b/gui/panel/ModernPitchPanel.h index 601e3f57..9f845a9f 100644 --- a/gui/panel/ModernPitchPanel.h +++ b/gui/panel/ModernPitchPanel.h @@ -1,14 +1,44 @@ //============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * ModernPitchPanel is a GUI component that provides controls for a modern pitch + * envelope. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== #pragma once +//============================================================================== + #include "gui/panel/AbstractPanel.h" #include //============================================================================== + namespace dmt { namespace gui { namespace panel { + //============================================================================== class ModernPitchPanel : public dmt::gui::panel::AbstractPanel { diff --git a/gui/panel/OscSendPanel.h b/gui/panel/OscSendPanel.h index b296f47a..20b6bb81 100644 --- a/gui/panel/OscSendPanel.h +++ b/gui/panel/OscSendPanel.h @@ -1,15 +1,47 @@ //============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * OscSendPanel is a GUI component that provides controls for oscillator send + * levels and pan. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== + #pragma once + //============================================================================== + #include "gui/component/LinearSliderComponent.h" #include "gui/component/RotarySliderComponent.h" #include "gui/panel/AbstractPanel.h" #include "utility/Unit.h" #include + //============================================================================== + namespace dmt { namespace gui { namespace panel { + //============================================================================== class OscSendPanel : public dmt::gui::panel::AbstractPanel { diff --git a/gui/panel/OscillatorPanel.h b/gui/panel/OscillatorPanel.h index 1c1f1c47..fd844409 100644 --- a/gui/panel/OscillatorPanel.h +++ b/gui/panel/OscillatorPanel.h @@ -1,7 +1,35 @@ //============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * OscillatorPanel is a GUI component that provides controls for oscillator + * settings. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== #pragma once +//============================================================================== + #include "gui/panel/AbstractPanel.h" #include "gui/panel/AnalogOscillatorPanel.h" #include "gui/panel/Carousel.h" @@ -9,9 +37,11 @@ #include //============================================================================== + namespace dmt { namespace gui { namespace panel { + //============================================================================== class OscillatorPanel : public dmt::gui::panel::Carousel { diff --git a/gui/panel/OscilloscopePanel.h b/gui/panel/OscilloscopePanel.h index 59ffa82a..e1eab2ae 100644 --- a/gui/panel/OscilloscopePanel.h +++ b/gui/panel/OscilloscopePanel.h @@ -1,14 +1,47 @@ +//============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * OscilloscopePanel is a GUI component that provides controls for the + * oscilloscope display. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== + #pragma once + //============================================================================== + #include "gui/component/LinearSliderComponent.h" #include "gui/display/OscilloscopeDisplay.h" #include "gui/panel/AbstractPanel.h" #include "utility/Unit.h" #include + //============================================================================== + namespace dmt { namespace gui { namespace panel { + //============================================================================== template class OscilloscopePanel : public dmt::gui::panel::AbstractPanel diff --git a/gui/panel/Panel.h b/gui/panel/Panel.h index f7aeb22a..894599be 100644 --- a/gui/panel/Panel.h +++ b/gui/panel/Panel.h @@ -1,4 +1,34 @@ +//============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * Panel header file. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== + #pragma once + +//============================================================================== + #include "./AbstractPanel.h" #include "./AnalogGainPanel.h" #include "./AnalogOscillatorPanel.h" diff --git a/gui/panel/PitchPanel.h b/gui/panel/PitchPanel.h index 58af672b..55b52689 100644 --- a/gui/panel/PitchPanel.h +++ b/gui/panel/PitchPanel.h @@ -1,7 +1,34 @@ //============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * PitchPanel is a GUI component that provides controls for pitch settings. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== #pragma once +//============================================================================== + #include "gui/panel/AbstractPanel.h" #include "gui/panel/AnalogPitchPanel.h" #include "gui/panel/Carousel.h" @@ -9,9 +36,11 @@ #include //============================================================================== + namespace dmt { namespace gui { namespace panel { + //============================================================================== class PitchPanel : public dmt::gui::panel::Carousel { diff --git a/gui/panel/SettingsPanel.h b/gui/panel/SettingsPanel.h index 00c6d036..a536d52c 100644 --- a/gui/panel/SettingsPanel.h +++ b/gui/panel/SettingsPanel.h @@ -1,6 +1,34 @@ //============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * SettingsPanel is a GUI component that provides controls for global settings. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== + #pragma once + //============================================================================== + #include "gui/component/LinearSliderComponent.h" #include "gui/component/RotarySliderComponent.h" #include "gui/display/SettingsEditorDisplay.h" @@ -8,11 +36,15 @@ #include "utility/Settings.h" #include "utility/Unit.h" #include + //============================================================================== + namespace dmt { namespace gui { namespace panel { + //============================================================================== + class SettingsPanel : public dmt::gui::panel::AbstractPanel { using RotarySliderComponent = dmt::gui::component::RotarySliderComponent; diff --git a/gui/panel/VoicingPanel.h b/gui/panel/VoicingPanel.h index d877afed..6cc6fa6e 100644 --- a/gui/panel/VoicingPanel.h +++ b/gui/panel/VoicingPanel.h @@ -1,16 +1,46 @@ //============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * VoicingPanel is a GUI component that provides controls for oscillator voicing + * settings. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== #pragma once +//============================================================================== + #include "gui/component/LinearSliderComponent.h" #include "gui/component/RotarySliderComponent.h" #include "gui/panel/AbstractPanel.h" #include //============================================================================== + namespace dmt { namespace gui { namespace panel { + //============================================================================== class VoicingPanel : public dmt::gui::panel::AbstractPanel { diff --git a/gui/panel/WaveformDistortionPanel.h b/gui/panel/WaveformDistortionPanel.h index 898ec6c8..fbdc75f3 100644 --- a/gui/panel/WaveformDistortionPanel.h +++ b/gui/panel/WaveformDistortionPanel.h @@ -1,15 +1,47 @@ //============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * WaveformDistortionPanel is a GUI component that provides controls for + * waveform distortion settings. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== + #pragma once + //============================================================================== + #include "gui/component/LinearSliderComponent.h" #include "gui/component/RotarySliderComponent.h" #include "gui/panel/AbstractPanel.h" #include "utility/Unit.h" #include + //============================================================================== + namespace dmt { namespace gui { namespace panel { + //============================================================================== class WaveformDistortionPanel : public dmt::gui::panel::AbstractPanel { diff --git a/gui/preset/FolderManager.h b/gui/preset/FolderManager.h index 40fcbc5f..29076b95 100644 --- a/gui/preset/FolderManager.h +++ b/gui/preset/FolderManager.h @@ -1,12 +1,32 @@ -/* - ============================================================================== - - FolderManager.h - Created: 28 Dec 2022 3:02:41pm - Author: Lunix - - ============================================================================== -*/ +//============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * FolderManager is responsible for managing preset folders within the plugin's + * preset system. It listens to changes in the AudioProcessorValueTreeState to + * update the current folder and maintain a list of available folders. It also + * ensures that a default directory for presets exists and is accessible. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== #pragma once diff --git a/gui/preset/FolderPanel.h b/gui/preset/FolderPanel.h index 801fb483..b7c2ebf1 100644 --- a/gui/preset/FolderPanel.h +++ b/gui/preset/FolderPanel.h @@ -1,92 +1,116 @@ -/* - ============================================================================== - - FolderPanel.h - Created: 28 Dec 2022 3:02:30pm - Author: Lunix - - ============================================================================== +//============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * FolderPanel is a GUI component that provides an interface for managing preset + * folders. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== */ #pragma once #include -//============================================================================== + //============================================================================== -namespace dmt { -namespace gui { -namespace preset { -class FolderPanel - : public juce::Component - , juce::Button::Listener - , juce::ComboBox::Listener + namespace dmt { -public: - FolderPanel() + namespace gui { + namespace preset { + class FolderPanel + : public juce::Component + , juce::Button::Listener + , juce::ComboBox::Listener { - configureButton(newButton, "New"); - configureButton(previousFolderButton, "<"); - configureButton(nextFolderButton, ">"); - configureButton(deleteButton, "Delete"); - - folderListBox.setTextWhenNothingSelected("No Folder Selected"); - folderListBox.setTextWhenNoChoicesAvailable("No Folder Available"); - folderListBox.setMouseCursor(juce::MouseCursor::PointingHandCursor); - addAndMakeVisible(folderListBox); - folderListBox.addListener(this); - } - - ~FolderPanel() override - { - newButton.removeListener(this); - previousFolderButton.removeListener(this); - nextFolderButton.removeListener(this); - deleteButton.removeListener(this); - folderListBox.removeListener(this); - } - - void paint(juce::Graphics&) override {} - - void resized() override - { - auto padding = 1; - const auto container = getLocalBounds().reduced(padding); - auto bounds = container; - - newButton.setBounds( - bounds.removeFromLeft(container.proportionOfWidth(0.2)).reduced(padding)); - previousFolderButton.setBounds( - bounds.removeFromLeft(container.proportionOfWidth(0.1)).reduced(padding)); - folderListBox.setBounds( - bounds.removeFromLeft(container.proportionOfWidth(0.4)).reduced(padding)); - nextFolderButton.setBounds( - bounds.removeFromLeft(container.proportionOfWidth(0.1)).reduced(padding)); - deleteButton.setBounds(bounds.reduced(padding)); - } - -private: - void buttonClicked(juce::Button* button) override {} - - void comboBoxChanged(juce::ComboBox* comboBoxThatHasChanged) override {} - - void configureButton(juce::Button& button, const juce::String& buttontext) - { - button.setButtonText(buttontext); - button.setMouseCursor(juce::MouseCursor::PointingHandCursor); - addAndMakeVisible(button); - button.addListener(this); - } - - juce::TextButton newButton; - juce::TextButton previousFolderButton; - juce::TextButton nextFolderButton; - juce::TextButton deleteButton; - - juce::ComboBox folderListBox; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(FolderPanel) -}; -} // namespace preset -} // namespace gui + public: + FolderPanel() + { + configureButton(newButton, "New"); + configureButton(previousFolderButton, "<"); + configureButton(nextFolderButton, ">"); + configureButton(deleteButton, "Delete"); + + folderListBox.setTextWhenNothingSelected("No Folder Selected"); + folderListBox.setTextWhenNoChoicesAvailable("No Folder Available"); + folderListBox.setMouseCursor(juce::MouseCursor::PointingHandCursor); + addAndMakeVisible(folderListBox); + folderListBox.addListener(this); + } + + ~FolderPanel() override + { + newButton.removeListener(this); + previousFolderButton.removeListener(this); + nextFolderButton.removeListener(this); + deleteButton.removeListener(this); + folderListBox.removeListener(this); + } + + void paint(juce::Graphics&) override {} + + void resized() override + { + auto padding = 1; + const auto container = getLocalBounds().reduced(padding); + auto bounds = container; + + newButton.setBounds( + bounds.removeFromLeft(container.proportionOfWidth(0.2)) + .reduced(padding)); + previousFolderButton.setBounds( + bounds.removeFromLeft(container.proportionOfWidth(0.1)) + .reduced(padding)); + folderListBox.setBounds( + bounds.removeFromLeft(container.proportionOfWidth(0.4)) + .reduced(padding)); + nextFolderButton.setBounds( + bounds.removeFromLeft(container.proportionOfWidth(0.1)) + .reduced(padding)); + deleteButton.setBounds(bounds.reduced(padding)); + } + + private: + void buttonClicked(juce::Button* button) override {} + + void comboBoxChanged(juce::ComboBox* comboBoxThatHasChanged) override {} + + void configureButton(juce::Button& button, const juce::String& buttontext) + { + button.setButtonText(buttontext); + button.setMouseCursor(juce::MouseCursor::PointingHandCursor); + addAndMakeVisible(button); + button.addListener(this); + } + + juce::TextButton newButton; + juce::TextButton previousFolderButton; + juce::TextButton nextFolderButton; + juce::TextButton deleteButton; + + juce::ComboBox folderListBox; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(FolderPanel) + }; + } // namespace preset + } // namespace gui } // namespace dmt \ No newline at end of file diff --git a/gui/preset/PresetManager.h b/gui/preset/PresetManager.h index df4ef5b4..1548b800 100644 --- a/gui/preset/PresetManager.h +++ b/gui/preset/PresetManager.h @@ -1,14 +1,31 @@ -/* - ============================================================================== - - PresetManager.h - Created: 20 Dec 2022 11:46:29pm - Author: Lunix - - Source: https://youtu.be/YwAtWuGA4Cg - - ============================================================================== -*/ +//============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * PresetManager is responsible for managing presets within the plugin's preset + * system. It provides functionality to save, load, and delete presets, as well + * as navigate through available presets. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== #pragma once diff --git a/gui/preset/PresetPanel.h b/gui/preset/PresetPanel.h index 3bc69da5..b0af5db3 100644 --- a/gui/preset/PresetPanel.h +++ b/gui/preset/PresetPanel.h @@ -1,14 +1,32 @@ -/* - ============================================================================== - - PresetPanel.h - Created: 20 Dec 2022 10:29:23pm - Author: Lunix - - Source: https://youtu.be/YwAtWuGA4Cg - - ============================================================================== -*/ +//============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * PresetPanel is a GUI component that provides an interface for managing + * presets in a plugin. It allows users to save, load, and delete presets, as + * well as navigate through them using previous and next buttons. It also + * includes a combo box for selecting presets from a list. + * + * Authors: Lunix-420 + * (Primary Author) + */ +//============================================================================== #pragma once diff --git a/gui/widget/AbstractButton.h b/gui/widget/AbstractButton.h index a670dd95..365f12bb 100644 --- a/gui/widget/AbstractButton.h +++ b/gui/widget/AbstractButton.h @@ -1,16 +1,15 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and @@ -141,6 +140,13 @@ class AbstractButton hoverIconImageComponent.setVisible(false); addMouseListener(this, true); + + // Reorder the components + innerShadow.toBack(); + outerShadow.toBack(); + clickedBackgroundImageComponent.toBack(); + hoverBackgroundImageComponent.toBack(); + backgroundImageComponent.toBack(); } //============================================================================== @@ -165,8 +171,19 @@ class AbstractButton TRACER("AbstractButton::resized"); auto bounds = getLocalBounds(); const auto buttonPadding = rawButtonPadding * size; - auto innerBounds = bounds.reduced(buttonPadding); + const auto innerBounds = bounds.reduced(buttonPadding); const auto cornerRadius = rawCornerRadius * size; + const auto currentScale = static_cast(scale); + + if (innerBounds == lastInnerBounds && + juce::approximatelyEqual(cornerRadius, lastCornerRadius) && + juce::approximatelyEqual(currentScale, lastScaleFactor)) { + return; + } + + lastInnerBounds = innerBounds; + lastCornerRadius = cornerRadius; + lastScaleFactor = currentScale; setShadowBounds(innerBounds, cornerRadius); setBackgroundBounds(innerBounds); @@ -293,13 +310,6 @@ class AbstractButton innerShadowPath.addRoundedRectangle(_innerBounds, _cornerRadius); innerShadow.setPath(innerShadowPath); innerShadow.setBoundsRelative(0.0f, 0.0f, 1.0f, 1.0f); - - // Reorder the components - innerShadow.toBack(); - outerShadow.toBack(); - clickedBackgroundImageComponent.toBack(); - hoverBackgroundImageComponent.toBack(); - backgroundImageComponent.toBack(); } //============================================================================== @@ -321,8 +331,8 @@ class AbstractButton return; // HiDPI support: render background images at higher resolution - const int hiResWidth = static_cast(_innerBounds.getWidth() * scale); - const int hiResHeight = static_cast(_innerBounds.getHeight() * scale); + const int hiResWidth = int(_innerBounds.getWidth() * scale); + const int hiResHeight = int(_innerBounds.getHeight() * scale); backgroundImage = Image(Image::ARGB, hiResWidth, hiResHeight, true); backgroundImageComponent.setBounds(_innerBounds); @@ -354,8 +364,8 @@ class AbstractButton return; // Render the icon images at higher resolution - const int hiResWidth = static_cast(iconArea.getWidth() * scale); - const int hiResHeight = static_cast(iconArea.getHeight() * scale); + const int hiResWidth = int(iconArea.getWidth() * scale); + const int hiResHeight = int(iconArea.getHeight() * scale); iconImage = juce::Image(juce::Image::ARGB, hiResWidth, hiResHeight, true); iconImageComponent.setBounds(iconArea); @@ -473,6 +483,9 @@ class AbstractButton ImageComponent iconImageComponent; Image hoverIconImage; ImageComponent hoverIconImageComponent; + juce::Rectangle lastInnerBounds; + float lastCornerRadius = -1.0f; + float lastScaleFactor = -1.0f; //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(AbstractButton) diff --git a/gui/widget/BorderButton.h b/gui/widget/BorderButton.h index a72532fb..175e1e96 100644 --- a/gui/widget/BorderButton.h +++ b/gui/widget/BorderButton.h @@ -1,16 +1,15 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and @@ -68,7 +67,10 @@ class BorderButton const Colour& backgroundColour = Settings::Header::borderButtonBackgroundColour; const Colour& fontColour = Settings::Header::borderButtonFontColour; + const Colour& borderColour = Settings::Header::borderButtonBorderColour; const float& rawFontSize = Settings::Header::borderButtonFontSize; + const float& borderButtonBorderThickness = + Settings::Header::borderButtonBorderThickness; // Constants for opacity and raw fade speed static constexpr float MAX_OPACITY = 1.0f; // Fully visible @@ -224,22 +226,26 @@ class BorderButton } // HiDPI support: render cached image at higher resolution - const int hiResWidth = static_cast(width * scale); - const int hiResHeight = static_cast(height * scale); + const int hiResWidth = juce::jmax(1, juce::roundToInt(width * scale)); + const int hiResHeight = juce::jmax(1, juce::roundToInt(height * scale)); cachedImage = Image(juce::Image::ARGB, hiResWidth, hiResHeight, true); Graphics g(cachedImage); g.addTransform(juce::AffineTransform::scale(scale, scale)); - g.fillAll(juce::Colours::transparentBlack); g.fillAll(backgroundColour); + // Draw border at the bottom + const int borderThickness = int(borderButtonBorderThickness * size); + g.setColour(borderColour); + g.fillRect(getBounds().removeFromBottom(borderThickness)); + const auto fontSize = static_cast(rawFontSize * size); - const auto font = fonts.medium.withHeight(fontSize); + const auto font = fonts.bold.withHeight(fontSize); g.setFont(font); g.setColour(fontColour); - g.drawText("Click to Show Header", + g.drawText(String("Click to Show Header"), juce::Rectangle(0, 0, width, height), juce::Justification::centred); } diff --git a/gui/widget/CallbackButton.h b/gui/widget/CallbackButton.h index 2f912fb4..0142894d 100644 --- a/gui/widget/CallbackButton.h +++ b/gui/widget/CallbackButton.h @@ -1,16 +1,15 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and diff --git a/gui/widget/Graph.h b/gui/widget/Graph.h index 5df35089..9c23f34a 100644 --- a/gui/widget/Graph.h +++ b/gui/widget/Graph.h @@ -1,16 +1,15 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and diff --git a/gui/widget/Label.h b/gui/widget/Label.h index a2d12188..d5fea56c 100644 --- a/gui/widget/Label.h +++ b/gui/widget/Label.h @@ -1,16 +1,15 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and @@ -120,7 +119,7 @@ class Label _g.fillAll(*backgroundColour); // Draw bounds debug - _g.setColour(juce::Colours::red); + _g.setColour(juce::Colours::magenta); if (Settings::debugBounds) _g.drawRect(bounds, 1); diff --git a/gui/widget/LinearSlider.h b/gui/widget/LinearSlider.h index baff8b0d..88b02b72 100644 --- a/gui/widget/LinearSlider.h +++ b/gui/widget/LinearSlider.h @@ -1,16 +1,15 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and @@ -209,7 +208,7 @@ class LinearSlider // Debug draw anchor points and rail bounds if (Settings::debugBounds) { - _g.setColour(juce::Colours::red); + _g.setColour(juce::Colours::green); _g.drawRect(railBounds, 1); _g.setColour(juce::Colours::yellow); _g.fillEllipse(primaryPoint.getX() - 8, primaryPoint.getY() - 8, 16, 16); diff --git a/gui/widget/MinMaxRenderer.h b/gui/widget/MinMaxRenderer.h new file mode 100644 index 00000000..92f40485 --- /dev/null +++ b/gui/widget/MinMaxRenderer.h @@ -0,0 +1,265 @@ +//============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * Min/Max binned oscilloscope renderer optimized for high frame rates. Bins + * samples to pixel columns, drawing only the minimum and maximum sample per + * bin while preserving temporal order. This dramatically reduces path + * complexity compared to per-sample rendering, trading visual fidelity for + * significantly lower CPU usage at high sample densities. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== + +#pragma once + +//============================================================================== + +#include "gui/widget/OscilloscopeRenderer.h" +#include + +//============================================================================== + +namespace dmt { +namespace gui { +namespace widget { + +//============================================================================== +/** + * @brief Min/Max binned oscilloscope renderer for high-framerate waveform + * drawing. + * + * @tparam SampleType The sample type (e.g., float, double) used for audio data. + * + * @details + * Instead of drawing one point per sample like PathStrokeRenderer, this + * renderer bins samples into pixel columns and draws only two points per bin: + * the minimum and maximum sample values. The temporal order of min and max + * within each bin is tracked, so the path correctly represents whether the + * waveform went up or down first in that pixel column. + * + * This produces at most 2 path points per pixel column instead of potentially + * many points per pixel, resulting in a much simpler path that is far cheaper + * to stroke. The visual result is nearly identical to per-sample rendering at + * typical zoom levels where multiple samples map to a single pixel. + * + * The renderer maintains persistent state (currentX and currentSample) between + * frames to ensure visual continuity of the waveform across render calls. + */ +template +class MinMaxRenderer : public OscilloscopeRenderer +{ + //============================================================================ +public: + using RingBuffer = typename OscilloscopeRenderer::RingBuffer; + using RenderContext = + typename OscilloscopeRenderer::RenderContext; + + //============================================================================ + /** + * @brief Draws a waveform segment using min/max binned path stroking. + * + * @param _graphics The JUCE Graphics context targeting the oscilloscope + * image. + * @param _ringBuffer Reference to the ring buffer containing audio samples. + * @param _channel The audio channel index to read from. + * @param _context Pre-computed rendering parameters for this frame. + * + * @details + * Bins samples to pixel columns and builds a path through the min/max + * extremes of each bin, preserving temporal order for accurate waveform + * representation. The path is then stroked using the shared strokePath. + */ + inline void draw(juce::Graphics& _graphics, + RingBuffer& _ringBuffer, + int _channel, + const RenderContext& _context) override + { + this->currentX = _context.drawStartX; + const auto path = buildPath(_ringBuffer, _channel, _context); + this->strokePath(_graphics, path, _context); + } + + //============================================================================ +private: + //============================================================================ + /** + * @brief Holds the min/max state for a single pixel column bin. + * + * @details + * Tracks the minimum and maximum sample values encountered within a pixel + * column, along with their sample indices to determine temporal ordering. + */ + struct Bin + { + SampleType minSample = static_cast(0.0f); + SampleType maxSample = static_cast(0.0f); + size_t minIndex = 0; + size_t maxIndex = 0; + size_t count = 0; + + /** @brief Resets the bin with the first sample of a new pixel column. */ + inline void reset(SampleType _sample, size_t _index) noexcept + { + minSample = _sample; + maxSample = _sample; + minIndex = _index; + maxIndex = _index; + count = 1; + } + + /** @brief Adds a sample to the bin, updating min/max as needed. */ + inline void addSample(SampleType _sample, size_t _index) noexcept + { + if (_sample < minSample) { + minSample = _sample; + minIndex = _index; + } + if (_sample > maxSample) { + maxSample = _sample; + maxIndex = _index; + } + ++count; + } + + /** @brief Returns true if the minimum sample occurred before the max. */ + [[nodiscard]] inline bool minFirst() const noexcept + { + return minIndex <= maxIndex; + } + }; + + //============================================================================ + /** + * @brief Builds a min/max binned path from the ring buffer samples. + * + * @param _ringBuffer Reference to the ring buffer containing audio samples. + * @param _channel The audio channel index to read from. + * @param _context Pre-computed rendering parameters for this frame. + * + * @return The constructed JUCE Path representing the waveform segment. + * + * @details + * Iterates through all samples, grouping them into pixel column bins. + * For each completed bin, two points are added to the path in temporal + * order (whichever extreme occurred first is drawn first). This preserves + * the waveform's directional movement while reducing the point count to + * at most two per pixel column. + * + * When only one sample falls in a bin, a single point is drawn. + * The persistent currentX tracks the pixel column boundary for sub-pixel + * continuity between frames. + */ + [[nodiscard]] inline juce::Path buildPath(RingBuffer& _ringBuffer, + int _channel, + const RenderContext& _context) + { + juce::Path path; + + // Start the path from the last sample of the previous frame + path.startNewSubPath(this->currentX, + this->sampleToY(this->currentSample, + _context.halfHeight, + _context.amplitude)); + + const float samplesPerPixel = 1.0f / _context.pixelsPerSample; + float nextBinBoundary = this->currentX + 1.0f; + + Bin bin; + bool binActive = false; + + for (size_t i = 0; i < static_cast(_context.sampleCount); ++i) { + const int sampleIndex = _context.firstSampleIndex + static_cast(i); + const SampleType sample = _ringBuffer.getSample(_channel, sampleIndex); + const float sampleX = + this->currentX + static_cast(i + 1) * _context.pixelsPerSample; + + if (!binActive) { + bin.reset(sample, i); + binActive = true; + } else { + bin.addSample(sample, i); + } + + // Check if the next sample would cross into a new pixel column + const float nextSampleX = + this->currentX + static_cast(i + 2) * _context.pixelsPerSample; + const bool isLastSample = + (i + 1 >= static_cast(_context.sampleCount)); + const bool crossesBoundary = (nextSampleX >= nextBinBoundary); + + if (isLastSample || crossesBoundary) { + // Finalize the current bin + const float binX = std::min(sampleX, nextBinBoundary - 0.5f); + + if (bin.count == 1) { + // Single sample in bin, draw one point + path.lineTo(binX, + this->sampleToY(bin.minSample, + _context.halfHeight, + _context.amplitude)); + } else { + // Multiple samples, draw min and max in temporal order + if (bin.minFirst()) { + path.lineTo(binX, + this->sampleToY(bin.minSample, + _context.halfHeight, + _context.amplitude)); + path.lineTo(binX, + this->sampleToY(bin.maxSample, + _context.halfHeight, + _context.amplitude)); + } else { + path.lineTo(binX, + this->sampleToY(bin.maxSample, + _context.halfHeight, + _context.amplitude)); + path.lineTo(binX, + this->sampleToY(bin.minSample, + _context.halfHeight, + _context.amplitude)); + } + } + + if (crossesBoundary) { + nextBinBoundary = std::floor(nextSampleX) + 1.0f; + binActive = false; + } + } + } + + // Update persistent state for frame continuity + const float totalAdvance = + static_cast(_context.sampleCount) * _context.pixelsPerSample; + this->currentX += totalAdvance; + if (_context.sampleCount > 0) { + const int lastIndex = + _context.firstSampleIndex + _context.sampleCount - 1; + this->currentSample = _ringBuffer.getSample(_channel, lastIndex); + } + + return path; + } +}; + +} // namespace widget +} // namespace gui +} // namespace dmt diff --git a/gui/widget/Oscilloscope.h b/gui/widget/Oscilloscope.h index b6a14bbd..37c8d02a 100644 --- a/gui/widget/Oscilloscope.h +++ b/gui/widget/Oscilloscope.h @@ -1,16 +1,15 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and @@ -31,7 +30,10 @@ //============================================================================== +#include "gui/widget/MinMaxRenderer.h" +#include "gui/widget/PathStrokeRenderer.h" #include +#include //============================================================================== @@ -72,6 +74,7 @@ class alignas(64) Oscilloscope : public juce::Thread using PixelFormat = juce::Image::PixelFormat; using ReadWriteLock = juce::ReadWriteLock; using Settings = dmt::Settings; + using Renderer = OscilloscopeRenderer; //============================================================================== /** @@ -91,6 +94,7 @@ class alignas(64) Oscilloscope : public juce::Thread , ringBuffer(_ringBuffer) , channel(_channel) , size(_sizeFactor) + , renderer(std::make_unique>()) { startThread(); } @@ -187,6 +191,23 @@ class alignas(64) Oscilloscope : public juce::Thread thickness = _newThickness; } + //============================================================================== + /** + * @brief Sets the rendering strategy for the oscilloscope. + * + * @param _newRenderer A unique pointer to the new renderer implementation. + * + * @details + * Swaps the current rendering strategy under the write lock to ensure + * thread safety with the rendering thread. The previous renderer is + * destroyed when the new one is set. + */ + inline void setRenderer(std::unique_ptr _newRenderer) + { + const ScopedWriteLock writeLock(imageLock); + renderer = std::move(_newRenderer); + } + //============================================================================== protected: //============================================================================== @@ -229,6 +250,7 @@ class alignas(64) Oscilloscope : public juce::Thread } image = Image(PixelFormat::ARGB, _width + 10, _height, true); + subPixelOffset = 0.0f; juce::Graphics imageGraphics(image); imageGraphics.setColour(juce::Colours::white); @@ -265,7 +287,10 @@ class alignas(64) Oscilloscope : public juce::Thread const int samplesToDraw = jmin(samplesToRead, maxSamplesToDraw); const int firstSamplesToDraw = readPosition; - const int pixelToDraw = static_cast(samplesToDraw / samplesPerPixel); + const float exactPixelsToDraw = + static_cast(samplesToDraw) / samplesPerPixel; + const float totalShift = exactPixelsToDraw + subPixelOffset; + const int pixelToDraw = static_cast(totalShift); ringBuffer.incrementReadPosition(channel, samplesToDraw); // Image move @@ -282,32 +307,20 @@ class alignas(64) Oscilloscope : public juce::Thread width - pixelToDraw + 10, 0, pixelToDraw, height); image.clear(clearRect, juce::Colours::transparentBlack); - // Generate path for new samples - currentX = currentX - static_cast(currentX) + width - pixelToDraw; - float pixelsPerSample = 1.0f / samplesPerPixel; - - const float startY = halfHeight + currentSample * halfHeight * amplitude; - const auto startPoint = juce::Point(currentX, startY); - - juce::Path path; - path.startNewSubPath(startPoint); - - for (size_t i = 0; i < static_cast(samplesToDraw); ++i) { - const int sampleIndex = firstSamplesToDraw + static_cast(i); - currentSample = ringBuffer.getSample(channel, sampleIndex); - currentX += pixelsPerSample; - const float y = halfHeight + currentSample * halfHeight * amplitude; - const auto point = juce::Point(currentX, y); - path.lineTo(point); - } - - juce::PathStrokeType strokeType(thickness * size, - juce::PathStrokeType::JointStyle::mitered, - juce::PathStrokeType::EndCapStyle::square); - + // Delegate drawing to the active renderer juce::Graphics imageGraphics(image); - imageGraphics.setColour(juce::Colours::white); - imageGraphics.strokePath(path, strokeType); + const typename Renderer::RenderContext context{ + firstSamplesToDraw, + samplesToDraw, + static_cast(width - pixelToDraw) + subPixelOffset, + 1.0f / samplesPerPixel, + halfHeight, + amplitude, + thickness, + size + }; + subPixelOffset = totalShift - static_cast(pixelToDraw); + renderer->draw(imageGraphics, ringBuffer, channel, context); } //============================================================================== @@ -323,8 +336,8 @@ class alignas(64) Oscilloscope : public juce::Thread Image image = Image(PixelFormat::ARGB, 1, 1, true); ReadWriteLock imageLock; - SampleType currentSample = static_cast(0.0f); - float currentX = 0.0f; + std::unique_ptr renderer; + float subPixelOffset = 0.0f; float rawSamplesPerPixel = 10.0f; float amplitude = 1.0f; float thickness = 3.0f; diff --git a/gui/widget/OscilloscopeRenderer.h b/gui/widget/OscilloscopeRenderer.h new file mode 100644 index 00000000..11cf9341 --- /dev/null +++ b/gui/widget/OscilloscopeRenderer.h @@ -0,0 +1,191 @@ +//============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * Abstract base class for oscilloscope rendering strategies. Defines the + * interface for drawing waveform data onto a JUCE Graphics context. Concrete + * implementations provide different visualization algorithms while the + * Oscilloscope class handles image management, scrolling, and threading. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== + +#pragma once + +//============================================================================== + +#include + +//============================================================================== + +namespace dmt { +namespace gui { +namespace widget { + +//============================================================================== +/** + * @brief Abstract base class for oscilloscope rendering strategies. + * + * @tparam SampleType The sample type (e.g., float, double) used for audio data. + * + * @details + * This class defines the interface for rendering waveform data onto a JUCE + * Graphics context. Concrete implementations provide different visualization + * algorithms (e.g., path stroking, point plotting, filled waveforms). + * + * The renderer reads sample data directly from the ring buffer by reference, + * avoiding any additional allocations or data copies. The Oscilloscope class + * handles all image management (scrolling, clearing) and passes a + * pre-configured Graphics context along with a RenderContext struct containing + * the parameters needed for drawing. + * + * Renderers may maintain their own persistent state between frames (e.g., + * sub-pixel position tracking) to ensure visual continuity. + * + * Common helper functions for coordinate conversion and path stroking are + * provided here to avoid duplication across renderer implementations. + */ +template +class OscilloscopeRenderer +{ + //============================================================================ +public: + using RingBuffer = dmt::dsp::data::RingAudioBuffer; + + //============================================================================ + /** + * @brief Parameters passed from the Oscilloscope to the renderer each frame. + * + * @details + * This struct contains all pre-computed values the renderer needs to draw + * the new waveform segment. The Oscilloscope computes these from its own + * state and the ring buffer, then passes them to the renderer. This avoids + * the renderer needing to know about image scrolling or buffer management. + */ + struct RenderContext + { + /** Index of the first sample to read from the ring buffer. */ + int firstSampleIndex; + + /** Number of samples to draw in this frame. */ + int sampleCount; + + /** X coordinate where the new drawing region starts on the image. */ + float drawStartX; + + /** Horizontal spacing: pixels per sample. */ + float pixelsPerSample; + + /** Vertical center of the drawing area in pixels. */ + int halfHeight; + + /** Amplitude scaling factor for the waveform. */ + float amplitude; + + /** Stroke thickness for the waveform. */ + float thickness; + + /** Global size scaling factor. */ + float sizeFactor; + }; + + //============================================================================ + /** + * @brief Virtual destructor for safe polymorphic deletion. + */ + virtual ~OscilloscopeRenderer() = default; + + //============================================================================ + /** + * @brief Draws a waveform segment onto the provided Graphics context. + * + * @param _graphics The JUCE Graphics context targeting the oscilloscope + * image. Already configured for the current frame. + * @param _ringBuffer Reference to the ring buffer containing audio samples. + * Read directly β€” no data is copied. + * @param _channel The audio channel index to read from. + * @param _context Pre-computed rendering parameters for this frame. + * + * @details + * Implementations should read samples directly from the ring buffer using + * the indices provided in the context. The Graphics context is already + * attached to the oscilloscope image, and the image has already been + * scrolled and cleared by the Oscilloscope class. + */ + virtual void draw(juce::Graphics& _graphics, + RingBuffer& _ringBuffer, + int _channel, + const RenderContext& _context) = 0; + + //============================================================================ +protected: + //============================================================================ + /** + * @brief Converts a sample value to a Y pixel coordinate. + * + * @param _sample The sample value to convert. + * @param _halfHeight The vertical center of the drawing area in pixels. + * @param _amplitude The amplitude scaling factor. + * + * @return The Y coordinate in pixels. + */ + [[nodiscard]] inline float sampleToY(SampleType _sample, + int _halfHeight, + float _amplitude) const noexcept + { + return static_cast(_halfHeight) + _sample * _halfHeight * _amplitude; + } + + //============================================================================ + /** + * @brief Strokes the given path onto the graphics context. + * + * @param _graphics The JUCE Graphics context targeting the oscilloscope + * image. + * @param _path The waveform path to stroke. + * @param _context Pre-computed rendering parameters for this frame. + * + * @details + * Configures the stroke type with beveled joints and rounded end caps, + * and uses a solid white colour for the stroke. + */ + inline void strokePath(juce::Graphics& _graphics, + const juce::Path& _path, + const RenderContext& _context) const + { + juce::PathStrokeType strokeType(_context.thickness * _context.sizeFactor, + juce::PathStrokeType::JointStyle::beveled, + juce::PathStrokeType::EndCapStyle::rounded); + _graphics.setColour(juce::Colours::white); + _graphics.strokePath(_path, strokeType); + } + + //============================================================================ + /** Last sample value for waveform continuity between frames. */ + SampleType currentSample = static_cast(0.0f); + + /** Current X position with sub-pixel precision for visual continuity. */ + float currentX = 0.0f; +}; + +} // namespace widget +} // namespace gui +} // namespace dmt diff --git a/gui/widget/PathStrokeRenderer.h b/gui/widget/PathStrokeRenderer.h new file mode 100644 index 00000000..0f41570a --- /dev/null +++ b/gui/widget/PathStrokeRenderer.h @@ -0,0 +1,137 @@ +//============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * Path stroke oscilloscope renderer. Draws a continuous waveform path using + * JUCE's Path and PathStrokeType for high-quality, anti-aliased rendering. + * This is the original (and most expensive) rendering algorithm. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== + +#pragma once + +//============================================================================== + +#include "gui/widget/OscilloscopeRenderer.h" +#include + +//============================================================================== + +namespace dmt { +namespace gui { +namespace widget { + +//============================================================================== +/** + * @brief Path stroke oscilloscope renderer for high-quality waveform drawing. + * + * @tparam SampleType The sample type (e.g., float, double) used for audio data. + * + * @details + * This is a very simple renderer that draws a path with one point for each + * sample. It's non-hardware-accelerated, and produces high-quality visuals at + * the cost of increased CPU usage. + * + * The renderer maintains persistent state (currentX and currentSample) between + * frames to ensure visual continuity of the waveform across render calls. + * Sub-pixel positioning is preserved to avoid visual jitter. + * + * Samples are read directly from the ring buffer, no data is copied. + */ +template +class PathStrokeRenderer : public OscilloscopeRenderer +{ + //============================================================================ +public: + using RingBuffer = typename OscilloscopeRenderer::RingBuffer; + using RenderContext = + typename OscilloscopeRenderer::RenderContext; + + //============================================================================ + /** + * @brief Draws a waveform segment using path stroking. + * + * @param _graphics The JUCE Graphics context targeting the oscilloscope + * image. + * @param _ringBuffer Reference to the ring buffer containing audio samples. + * @param _channel The audio channel index to read from. + * @param _context Pre-computed rendering parameters for this frame. + * + * @details + * Builds a continuous path from the provided samples, maintaining sub-pixel + * continuity with the previous frame via the persistent currentX state. + * The path is stroked with beveled joints and rounded end caps for a clean + * waveform appearance. + */ + inline void draw(juce::Graphics& _graphics, + RingBuffer& _ringBuffer, + int _channel, + const RenderContext& _context) override + { + this->currentX = _context.drawStartX; + const auto path = buildPath(_ringBuffer, _channel, _context); + this->strokePath(_graphics, path, _context); + } + + //============================================================================ +private: + //============================================================================ + /** + * @brief Builds a continuous path from the ring buffer samples. + * + * @param _ringBuffer Reference to the ring buffer containing audio samples. + * @param _channel The audio channel index to read from. + * @param _context Pre-computed rendering parameters for this frame. + * + * @return The constructed JUCE Path representing the waveform segment. + * + * @details + * Reads samples directly from the ring buffer and advances the persistent + * currentX position to maintain sub-pixel continuity between frames. + */ + [[nodiscard]] inline juce::Path buildPath(RingBuffer& _ringBuffer, + int _channel, + const RenderContext& _context) + { + juce::Path path; + path.startNewSubPath(this->currentX, + this->sampleToY(this->currentSample, + _context.halfHeight, + _context.amplitude)); + + for (size_t i = 0; i < static_cast(_context.sampleCount); ++i) { + const int sampleIndex = _context.firstSampleIndex + static_cast(i); + this->currentSample = _ringBuffer.getSample(_channel, sampleIndex); + this->currentX += _context.pixelsPerSample; + path.lineTo(this->currentX, + this->sampleToY(this->currentSample, + _context.halfHeight, + _context.amplitude)); + } + + return path; + } +}; + +} // namespace widget +} // namespace gui +} // namespace dmt diff --git a/gui/widget/RotarySlider.h b/gui/widget/RotarySlider.h index 039d23a1..662d156e 100644 --- a/gui/widget/RotarySlider.h +++ b/gui/widget/RotarySlider.h @@ -1,16 +1,15 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and diff --git a/gui/widget/Shadow.h b/gui/widget/Shadow.h index 16aa003b..af7752de 100644 --- a/gui/widget/Shadow.h +++ b/gui/widget/Shadow.h @@ -1,16 +1,15 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and @@ -26,17 +25,23 @@ * Lunix-420 (Primary Author) */ //============================================================================== + #pragma once + //============================================================================== + #include "utility/Scaleable.h" #include "utility/Settings.h" #include +#include + //============================================================================== + namespace dmt { namespace gui { namespace widget { -//============================================================================== +//============================================================================== /** * @brief Component for rendering drop shadows on arbitrary paths. * @@ -101,12 +106,24 @@ class Shadow if (!visibility) return; + refreshCachedImageIfNeeded(); + if (!needsRepaint) { - _g.drawImageAt(image, 0, 0); + _g.drawImage(image, + 0.0f, + 0.0f, + static_cast(getWidth()), + static_cast(getHeight()), + 0, + 0, + image.getWidth(), + image.getHeight()); return; } juce::Graphics imageGraphics(image); + imageGraphics.addTransform(juce::AffineTransform::scale(scale, scale)); + imageGraphics.fillAll(juce::Colours::transparentBlack); imageGraphics.setColour(*colour); // dereference pointer if (inner) @@ -115,7 +132,15 @@ class Shadow drawOuterForPath(imageGraphics, path); needsRepaint = false; - _g.drawImageAt(image, 0, 0); + _g.drawImage(image, + 0.0f, + 0.0f, + static_cast(getWidth()), + static_cast(getHeight()), + 0, + 0, + image.getWidth(), + image.getHeight()); } //============================================================================== @@ -130,10 +155,7 @@ class Shadow inline void resized() override { TRACER("Shadow::resized"); - if (getWidth() == 0 || getHeight() == 0) - return; - image = Image(PixelFormat::ARGB, getWidth(), getHeight(), true); - needsRepaint = true; + refreshCachedImageIfNeeded(true); } //============================================================================== @@ -207,15 +229,8 @@ class Shadow inline void drawInnerForPath(juce::Graphics& _g, juce::Path _target) { TRACER("Shadow::drawInnerForPath"); - juce::Graphics::ScopedSaveState saveState(_g); - juce::Path shadowPath(_target); - shadowPath.addRectangle(_target.getBounds().expanded(10 * scale)); - shadowPath.setUsingNonZeroWinding(false); - _g.reduceClipRegion(_target); - juce::DropShadow ds(*colour, - static_cast(radius * size * scale), - offset * scale); // dereference pointer - ds.drawForPath(_g, shadowPath); + updateShadowParameters(); + innerShadowRenderer.render(_g, _target); } //============================================================================== @@ -234,16 +249,58 @@ class Shadow TRACER("Shadow::drawOuterForPath"); juce::Graphics::ScopedSaveState saveState(_g); juce::Path shadowPath(_target); - shadowPath.addRectangle(_target.getBounds().expanded(10 * scale)); + shadowPath.addRectangle(_target.getBounds().expanded(10.0f)); shadowPath.setUsingNonZeroWinding(false); _g.reduceClipRegion(shadowPath); - juce::DropShadow ds(*colour, - static_cast(radius * size * scale), - offset * scale); // dereference pointer - ds.drawForPath(_g, _target); + updateShadowParameters(); + outerShadowRenderer.render(_g, _target); } private: + inline void updateShadowParameters() + { + // Rendering uses a graphics transform for HiDPI, so keep shadow parameters + // in logical units to avoid applying scale twice. + const auto scaledRadius = static_cast(radius * size); + const auto scaledOffset = juce::Point(static_cast(offset.x), + static_cast(offset.y)); + + if (inner) { + innerShadowRenderer.setColor(*colour) + .setRadius(scaledRadius) + .setOffset(scaledOffset); + return; + } + + outerShadowRenderer.setColor(*colour) + .setRadius(scaledRadius) + .setOffset(scaledOffset); + } + + inline void refreshCachedImageIfNeeded(bool forceRepaint = false) + { + if (getWidth() == 0 || getHeight() == 0) + return; + + const auto currentScale = static_cast(scale); + const auto scaledWidth = + juce::jmax(1, juce::roundToInt(getWidth() * currentScale)); + const auto scaledHeight = + juce::jmax(1, juce::roundToInt(getHeight() * currentScale)); + + const auto scaleChanged = + !juce::approximatelyEqual(lastRenderedScale, currentScale); + const auto imageSizeChanged = + image.getWidth() != scaledWidth || image.getHeight() != scaledHeight; + + if (!forceRepaint && !scaleChanged && !imageSizeChanged) + return; + + image = Image(PixelFormat::ARGB, scaledWidth, scaledHeight, true); + lastRenderedScale = currentScale; + needsRepaint = true; + } + //============================================================================== // Members initialized in the initializer list const bool& visibility; @@ -256,6 +313,10 @@ class Shadow juce::Point offset = { 0, 0 }; juce::Path path; bool needsRepaint = true; + float lastRenderedScale = 0.0f; + + melatonin::DropShadow outerShadowRenderer; + melatonin::InnerShadow innerShadowRenderer; Image image = Image(PixelFormat::ARGB, 1, 1, true); diff --git a/gui/widget/TextEditor.h b/gui/widget/TextEditor.h index dc442ff0..9b7a4ddd 100644 --- a/gui/widget/TextEditor.h +++ b/gui/widget/TextEditor.h @@ -1,5 +1,34 @@ //============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * TextEditor is a custom text editor component that extends the functionality + * of juce::TextEditor. It provides additional features such as handling arrow + * key navigation and filtering input characters. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== + #pragma once + //============================================================================== #include diff --git a/gui/widget/ToggleButton.h b/gui/widget/ToggleButton.h index f492dc98..233bdd94 100644 --- a/gui/widget/ToggleButton.h +++ b/gui/widget/ToggleButton.h @@ -1,16 +1,15 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and @@ -92,9 +91,9 @@ class ToggleButton bool _shouldDrawBackground = true, bool _shouldDrawShadow = true, bool _alternativeIconHover = false) noexcept - : AbstractButton(_name, - _iconName, - _tooltip, + : AbstractButton(_name, + _iconName, + _tooltip, _shouldDrawBorder, _shouldDrawBackground, _shouldDrawShadow, diff --git a/gui/widget/TriangleButton.h b/gui/widget/TriangleButton.h index 3ceeb779..3b50407d 100644 --- a/gui/widget/TriangleButton.h +++ b/gui/widget/TriangleButton.h @@ -1,16 +1,15 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and diff --git a/gui/widget/ValueCategoryList.h b/gui/widget/ValueCategoryList.h index 42bb6afd..7564e081 100644 --- a/gui/widget/ValueCategoryList.h +++ b/gui/widget/ValueCategoryList.h @@ -1,4 +1,31 @@ //============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * ValueCategoryList is a GUI component that displays a list of categories, each + * with a label. It allows the user to select a category, which triggers a + * callback. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== #pragma once @@ -15,6 +42,7 @@ namespace dmt { namespace gui { namespace component { + //============================================================================== class ValueCategoryList : public juce::Component diff --git a/gui/widget/ValueEditor.h b/gui/widget/ValueEditor.h index 5980c22a..554a16f4 100644 --- a/gui/widget/ValueEditor.h +++ b/gui/widget/ValueEditor.h @@ -1,4 +1,36 @@ //============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * ValueEditor is a GUI component that provides an interface for editing a + * single value from the configuration. It consists of a label and a text + * editor. The label displays the name of the value, and the text editor allows + * the user to edit the value. When the user finishes editing (by losing focus + * or pressing Enter), the new value is parsed and set in the configuration. If + * the new value is invalid, it reverts to the previous value. It also notifies + * a listener (if one exists) about the change, allowing for UI updates or other + * reactions. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== #pragma once diff --git a/gui/widget/ValueEditorList.h b/gui/widget/ValueEditorList.h index e0a8c60c..fc5eb1d5 100644 --- a/gui/widget/ValueEditorList.h +++ b/gui/widget/ValueEditorList.h @@ -1,4 +1,31 @@ //============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * ValueEditorList is a GUI component that displays a list of editable values + * based on a selected category. It allows the user to edit values and navigate + * between them using the up and down arrow keys. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== #pragma once @@ -14,6 +41,7 @@ namespace dmt { namespace gui { namespace component { + //============================================================================== class ValueEditorList : public juce::Component diff --git a/gui/widget/Widget.h b/gui/widget/Widget.h index 277237de..18652262 100644 --- a/gui/widget/Widget.h +++ b/gui/widget/Widget.h @@ -1,4 +1,34 @@ +//============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * Widget header file. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== + #pragma once + +//============================================================================== + #include "./Label.h" #include "./LinearSlider.h" #include "./RotarySlider.h" diff --git a/gui/window/AbstractEditor.h b/gui/window/AbstractEditor.h deleted file mode 100644 index eb13a264..00000000 --- a/gui/window/AbstractEditor.h +++ /dev/null @@ -1,122 +0,0 @@ -// #pragma once - -// #include "gui/panel/AbstractPanel.h" -// #include "gui/window/Compositor.h" -// #include - -// namespace dmt { -// namespace gui { -// namespace window { - -// class AbstractEditor : public juce::AudioProcessorEditor -// { -// using AbstractPanel = dmt::gui::panel::AbstractPanel; -// float& size = dmt::Settings::Window::size; -// const int& headerHeight = dmt::Settings::Header::height; - -// public: -// AbstractEditor(juce::String _name, -// juce::AudioProcessor& _processor, -// AbstractPanel& _mainPanel, -// int _baseWidth, -// int _baseHeight) -// : AudioProcessorEditor(_processor) -// , compositor(_name, _mainPanel, _processor.apvts) -// , baseWidth(_baseWidth) -// , baseHeight(_baseHeight) -// { -// TRACER("AbstractEditor::AbstractEditor"); -// if (OS_IS_WINDOWS) { -// setResizable(true, true); -// } - -// if (OS_IS_DARWIN) { -// setResizable(true, true); -// } - -// if (OS_IS_LINUX) { -// openGLContext.setComponentPaintingEnabled(true); -// openGLContext.setContinuousRepainting(false); -// openGLContext.attachTo(*getTopLevelComponent()); -// setResizable(true, true); -// } - -// setConstraints(baseWidth, baseHeight + headerHeight); -// addAndMakeVisible(compositor); -// setResizable(true, true); -// setSize(baseWidth, baseHeight); - -// // Set the callback for header visibility changes -// compositor.setHeaderVisibilityCallback([this](bool isHeaderVisible) { -// handleHeaderVisibilityChange(isHeaderVisible); -// }); -// } - -// ~AbstractEditor() override = default; - -// void paint(juce::Graphics& g) -// { -// TRACER("AbstractEditor::paint"); - -// // Just painting the background -// g.fillAll(dmt::Settings::Window::backgroundColour); -// } - -// void resized() override -// { -// TRACER("AbstractEditor::resized"); - -// // Set the global size -// const int currentHeight = getHeight(); -// const float newSize = -// (float)currentHeight / -// (compositor.isHeaderVisible() ? baseHeight + headerHeight : -// baseHeight); - -// // Make sure the size makes sense -// if (newSize <= 0.0f || std::isinf(newSize)) { -// jassertfalse; -// } - -// dmt::Settings::Window::size = newSize; - -// // Set the bounds of the compositor to the bounds of the PluginEditor -// compositor.setBoundsRelative(0.0f, 0.0f, 1.0f, 1.0f); -// } - -// protected: -// void handleHeaderVisibilityChange(bool isHeaderVisible) -// { -// TRACER("AbstractEditor::handleHeaderVisibilityChange"); -// const int adjustedHeight = -// isHeaderVisible ? baseHeight + headerHeight : baseHeight; -// setConstraints(baseWidth, adjustedHeight); -// setSize(baseWidth, adjustedHeight); -// } - -// void setConstraints(int width, int height) -// { -// TRACER("AbstractEditor::setConstraints"); -// if (auto* constrainer = this->getConstrainer()) { -// const auto aspectRatio = (double)width / (double)height; -// constrainer->setFixedAspectRatio(aspectRatio); -// const auto minWidth = width / 2; -// const auto minHeight = height / 2; -// const auto maxWidth = width * 4; -// const auto maxHeight = height * 4; -// constrainer->setSizeLimits(minWidth, minHeight, maxWidth, maxHeight); -// } else { -// jassertfalse; // Constrainer not set -// } -// } - -// private: -// dmt::gui::window::Compositor compositor; -// int baseWidth = 0; -// int baseHeight = 0; -// juce::OpenGLContext openGLContext; -// }; - -// } // namespace window -// } // namespace gui -// } // namespace dmt \ No newline at end of file diff --git a/gui/window/Alerts.h b/gui/window/Alerts.h index c5aedcb7..44505048 100644 --- a/gui/window/Alerts.h +++ b/gui/window/Alerts.h @@ -1,16 +1,15 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and @@ -308,12 +307,13 @@ class Alerts inline void renderAlertToImage(AlertData& _alert) { TRACER("Alerts::renderAlertToImage"); + const auto alertWidth = rawAlertWidth * size; const auto alertHeight = rawAlertHeight * size; // HiDPI support: render at higher resolution - const int hiResWidth = static_cast(alertWidth * scale); - const int hiResHeight = static_cast(alertHeight * scale); + const int hiResWidth = int(alertWidth * scale); + const int hiResHeight = int(alertHeight * scale); _alert.cachedComponentImage = juce::Image(juce::Image::ARGB, hiResWidth, hiResHeight, true); diff --git a/gui/window/Compositor.h b/gui/window/Compositor.h index 2773f400..f75f7514 100644 --- a/gui/window/Compositor.h +++ b/gui/window/Compositor.h @@ -1,16 +1,15 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and @@ -179,6 +178,7 @@ class Compositor void resized() noexcept override { TRACER("Compositor::resized"); + propagateSizeFactor(); const auto bounds = getLocalBounds(); // Alerts @@ -194,13 +194,13 @@ class Compositor tooltip.setAlwaysOnTop(true); // Main layout + const auto padding = rawPadding * size * 0.5f; if (header.isVisible()) { const auto headerHeight = rawHeaderHeight * size; const auto headerBounds = juce::Rectangle(bounds).removeFromTop( static_cast(headerHeight * 2.0f)); header.setBounds(headerBounds); - const auto padding = rawPadding * size; const auto contentHeight = bounds.getHeight() - headerHeight - 2 * padding; const auto contentBounds = @@ -209,12 +209,13 @@ class Compositor mainLayout.setBounds(contentBounds); settingsPanel.setBounds(contentBounds); - borderButton.setVisible( - false); // Hide the BorderButton when the header is visible + // Hide the BorderButton when header visible + borderButton.setVisible(false); } else { - // If the header is hidden, the main layout takes the full bounds - mainLayout.setBounds(bounds); - settingsPanel.setBounds(bounds); + // If the header is hidden, keep the same margin around the layout + const auto padded = bounds.reduced(padding); + mainLayout.setBounds(padded); + settingsPanel.setBounds(padded); // Show the BorderButton at the top with half the height of the header const auto borderButtonHeight = rawBorderButtonHeight * size; @@ -408,6 +409,8 @@ class Compositor TRACER("Compositor::resetSettingsCallback"); properties.resetToFallback(); + propagateSizeFactor(); + // Gotta call this first to recalculate the global size const auto& parent = getParentComponent(); if (parent != nullptr) { @@ -462,6 +465,7 @@ class Compositor void valueEditorListenerCallback() override { TRACER("Compositor::valueEditorListenerCallback"); + propagateSizeFactor(); resizedRecursively(this); } @@ -566,12 +570,26 @@ class Compositor * components that implement the IScaleable interface receive the updated * size factor. * + * @param force If true, propagation runs even when the size factor itself + * did not change. This is required for dynamically added + * scaleable children. + * * @note This is typically triggered by the Compositor in response to * hierarchy changes or user scaling actions. */ - void propagateSizeFactor() noexcept + void propagateSizeFactor(const bool force = false) noexcept { TRACER("Compositor::propagateSizeFactor"); + if (isPropagatingSizeFactor) + return; + + if (!force && + juce::approximatelyEqual(lastPropagatedSizeFactor, sizeFactor)) + return; + + const juce::ScopedValueSetter isPropagatingGuard( + isPropagatingSizeFactor, true); + lastPropagatedSizeFactor = sizeFactor; setSizeFactorRecursively(this); } @@ -656,6 +674,7 @@ class Compositor { if (!c) return; + c->removeComponentListener(this); c->addComponentListener(this); for (auto* child : c->getChildren()) if (auto* cc = dynamic_cast(child)) @@ -737,8 +756,11 @@ class Compositor */ void componentChildrenChanged(juce::Component& component) override { + if (isPropagatingSizeFactor) + return; + addListenerToChildren(&component); - propagateSizeFactor(); + propagateSizeFactor(true); } private: @@ -759,6 +781,8 @@ class Compositor int baseHeight = 0; int baseWidth = 0; const float& sizeFactor; + float lastPropagatedSizeFactor = std::numeric_limits::quiet_NaN(); + bool isPropagatingSizeFactor = false; //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Compositor) diff --git a/gui/window/Header.h b/gui/window/Header.h index 090c0038..bc2438b0 100644 --- a/gui/window/Header.h +++ b/gui/window/Header.h @@ -1,17 +1,15 @@ //============================================================================== -/** - - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and @@ -310,7 +308,7 @@ class Header // Members initialized in the initializer list Shadow outerShadow; Shadow innerShadow; - Fonts fonts; // <-- Moved this above Label title + Fonts fonts; Label title; CallbackButton settingsButton; CallbackButton settingsExitButton; diff --git a/gui/window/Layout.h b/gui/window/Layout.h index 1a733c31..a72773e2 100644 --- a/gui/window/Layout.h +++ b/gui/window/Layout.h @@ -1,14 +1,50 @@ +//============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * Layout is a GUI component that manages the arrangement of panels components + * in a grid layout. It allows for flexible panel placement and resizing based + * on specified column and row separators. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== + #pragma once +//============================================================================== + #include "dmt/gui/panel/AbstractPanel.h" +//============================================================================== + namespace dmt { namespace gui { namespace window { +//============================================================================== + using GridSeparatorLayout = std::vector; -// Layout is now a JUCE Component +//============================================================================== + class Layout : public juce::Component { using AbstractPanel = dmt::gui::panel::AbstractPanel; @@ -89,7 +125,6 @@ class Layout : public juce::Component auto panel = std::make_shared(std::forward(_args)...); panels.push_back(panel); panelSpans.emplace_back(_startCol, _startRow, _endCol, _endRow); - // Add to JUCE component tree addAndMakeVisible(panel.get()); } diff --git a/gui/window/Popover.h b/gui/window/Popover.h index 999c705c..83fad5d0 100644 --- a/gui/window/Popover.h +++ b/gui/window/Popover.h @@ -1,17 +1,21 @@ //============================================================================== -/** - - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and diff --git a/gui/window/Tooltip.h b/gui/window/Tooltip.h index 2533938a..bd9c6d48 100644 --- a/gui/window/Tooltip.h +++ b/gui/window/Tooltip.h @@ -1,16 +1,15 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and @@ -142,6 +141,7 @@ class Tooltip { TRACER("Tooltip::paint"); if (!tooltipImage.isNull()) { + const int imageWidth = tooltipImage.getWidth(); const int imageHeight = tooltipImage.getHeight(); const int width = getWidth(); @@ -152,17 +152,17 @@ class Tooltip // Flip horizontally if tooltip would go off right edge if (drawPositionX + imageWidth / scale > width) - drawPositionX = std::max( - 0, lastMousePosition.x - static_cast(imageWidth / scale)); + drawPositionX = + std::max(0, lastMousePosition.x - int(imageWidth / scale)); // Flip vertically if tooltip would go off bottom edge if (drawPositionY + imageHeight / scale > height) - drawPositionY = std::max( - 0, lastMousePosition.y - static_cast(imageHeight / scale)); + drawPositionY = + std::max(0, lastMousePosition.y - int(imageHeight / scale)); _graphics.drawImage(tooltipImage, - static_cast(drawPositionX), - static_cast(drawPositionY), + float(drawPositionX), + float(drawPositionY), imageWidth / scale, imageHeight / scale, 0, @@ -248,6 +248,7 @@ class Tooltip inline void renderTooltipImage(const juce::String& _text) { TRACER("Tooltip::renderTooltipImage"); + // Font size and style const auto fontSize = rawFontSize * size; diff --git a/gui/window/Window.h b/gui/window/Window.h index 83f24aa3..0c85436b 100644 --- a/gui/window/Window.h +++ b/gui/window/Window.h @@ -1,47 +1,34 @@ //============================================================================== -// β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ -// β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ -// β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ -// β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ -// β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ -// -// Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) -// -// This file is part of the Dimethoxy Library, a collection of essential -// classes used across various Dimethoxy projects. -// These files are primarily designed for internal use within our repositories. -// -// License: -// This code is licensed under the GPLv3 license. You are permitted to use and -// modify this code under the terms of this license. -// You must adhere GPLv3 license for any project using this code or parts of it. -// Your are not allowed to use this code in any closed-source project. -// -// Description: -// Aggregates all Dimethoxy window-related headers for convenient inclusion. -// Provides a single entry point for window, editor, alerts, compositor, header, -// popover, and tooltip classes. -// -// Authors: -// Lunix-420 (Primary Author) +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * Window header file. + * + * Authors: + * Lunix-420 (Primary Author) + */ //============================================================================== #pragma once //============================================================================== -/** - * @brief Aggregates all Dimethoxy window-related headers for convenient - * inclusion. - * - * @details - * This header includes all core window modules (editor, alerts, compositor, - * header, popover, tooltip) in a single file. Use this header to ensure - * consistent access to all window features across the codebase. Designed for - * real-time safety and deterministic resource management. - */ -//============================================================================== -#include "./AbstractEditor.h" #include "./Alerts.h" #include "./Compositor.h" #include "./Header.h" diff --git a/model/AhdEnvelopeParameters.h b/model/AhdEnvelopeParameters.h deleted file mode 100644 index 5a055083..00000000 --- a/model/AhdEnvelopeParameters.h +++ /dev/null @@ -1,61 +0,0 @@ -#pragma once - -#include - -//============================================================================== -namespace dmt { -namespace model { -static inline juce::AudioProcessorParameterGroup -envelopeParameterGroup(juce::String parentUid, - juce::String suffix, - std::array defaultValues) -{ - using ParameterInt = juce::AudioParameterInt; - using ParameterFloat = juce::AudioParameterFloat; - using ParameterChoice = juce::AudioParameterChoice; - using NormalisableRange = juce::NormalisableRange; - - juce::String uid = parentUid + suffix + "Env"; - - return juce::AudioProcessorParameterGroup( - uid, // group ID - suffix + "Envelope", // group name - "|", // separator - std::make_unique(uid + "Attack", // parameter ID - "Attack", // parameter name - NormalisableRange(0.0f, // rangeStart - 0.3f, // rangeEnd - 0.001f, // intervalValue - 0.5f), // skewFactor - defaultValues[0]), // defaultValue - std::make_unique(uid + "Hold", // parameter ID - "Hold", // parameter name - NormalisableRange(0.0f, // rangeStart - 0.3f, // rangeEnd - 0.001f, // intervalValue - 0.5f), // skewFactor - defaultValues[1]), // defaultValue - std::make_unique(uid + "Decay", // parameter ID - "Decay", // parameter name - NormalisableRange(0.0f, // rangeStart - 1.0f, // rangeEnd - 0.001f, // intervalValue - 0.5f), // skewFactor - defaultValues[2]), // defaultValue - std::make_unique(uid + "Depth", // parameter ID - "Depth", // parameter name - NormalisableRange(0.0f, // rangeStart - 1.0f, // rangeEnd - 0.001f, // intervalValue - 0.5f), // skewFactor - defaultValues[3]), // defaultValue - std::make_unique(uid + "Skew", // parameter ID - "Skew", // parameter name - NormalisableRange(0.0f, // rangeStart - 16.0f, // rangeEnd - 0.1f, // intervalValue - 1.0f), // skewFactor - defaultValues[4])); // defaultValue -} -} // namespace model -} // namespace dmt \ No newline at end of file diff --git a/model/Model.h b/model/Model.h index 7b1df985..1b7a5846 100644 --- a/model/Model.h +++ b/model/Model.h @@ -2,4 +2,5 @@ #include "DisfluxParameters.h" #include "GlobalParameters.h" #include "HeretikParameters.h" +#include "NeutrinoParameters.h" #include "OscilloscopeParameters.h" diff --git a/model/NeutrinoParameters.h b/model/NeutrinoParameters.h new file mode 100644 index 00000000..fabf1473 --- /dev/null +++ b/model/NeutrinoParameters.h @@ -0,0 +1,33 @@ +#pragma once +//============================================================================== +#include +//============================================================================== +namespace dmt { +namespace model { +//============================================================================== +static inline juce::AudioProcessorParameterGroup +neutrinoParameterGroup(juce::String parentUid, int versionHint) +{ + using ParameterInt = juce::AudioParameterInt; + using ParameterFloat = juce::AudioParameterFloat; + // using ParameterChoice = juce::AudioParameterChoice; + using NormalisableRange = juce::NormalisableRange; + + juce::String uid = parentUid + "Neutrino"; + + return juce::AudioProcessorParameterGroup( + uid, // group ID + "Neutrino", // group name + "|", // separator + + // Symmetry + std::make_unique(uid + "Symmetry", + "Symmetry", + NormalisableRange(-1.f, // rangeStart + 1.f, // rangeEnd + .01f, // intervalValue + 1.f), // skewFactor + .0f)); +} +} // namespace model +} // namespace dmt \ No newline at end of file diff --git a/model/OscSendParameterGroup.h b/model/OscSendParameterGroup.h deleted file mode 100644 index afbc7652..00000000 --- a/model/OscSendParameterGroup.h +++ /dev/null @@ -1,34 +0,0 @@ -#include -//============================================================================== -namespace dmt { -namespace model { -static inline juce::AudioProcessorParameterGroup -oscSendParameterGroup(juce::String parentUid, juce::String channel) -{ - using ParameterFloat = juce::AudioParameterFloat; - using NormalisableRange = juce::NormalisableRange; - - juce::String uid = parentUid + "Send" + channel; - - return juce::AudioProcessorParameterGroup( - uid, // group ID - "OscSend", // group name - "|", // separator - std::make_unique(uid + "Gain", // parameter ID - "Gain", // parameter name - NormalisableRange(-96.f, // rangeStart - 0.f, // rangeEnd - .1f, // intervalValue - 1.f), // skewFactor - 0.f), - std::make_unique(uid + "Pan", // parameter ID - "Pan", // parameter name - NormalisableRange(-1.f, // rangeStart - 1.f, // rangeEnd - .01f, // intervalValue - 1.f), // skewFactor - 0.f)); // defaultValue -} - -} // namespace model -} // namespace dmt \ No newline at end of file diff --git a/model/OscillatorParameters.h b/model/OscillatorParameters.h deleted file mode 100644 index 2ddaf9c6..00000000 --- a/model/OscillatorParameters.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include "../dsp/synth/AnalogWaveform.h" -#include "AhdEnvelopeParameters.h" -#include "DistortionParameters.h" -#include "OscSendParameterGroup.h" -#include "VoiceParameters.h" -#include "WaveformParameters.h" -#include -//============================================================================== -namespace dmt { -namespace model { -static inline juce::AudioProcessorParameterGroup -oscillatorParameterGroup(int index) -{ - using ParameterGroup = juce::AudioProcessorParameterGroup; - - juce::String uid = juce::String("osc" + juce::String(index)); - - return juce::AudioProcessorParameterGroup( - uid, // group ID - "Oscillator", // group name - "|", // separator - std::make_unique(waveformParameterGroup(uid)), - std::make_unique(voiceParameterGroup(uid)), - std::make_unique(distortionParameterGroup(uid)), - std::make_unique( - envelopeParameterGroup(uid, "Gain", { 0.0f, 0.04f, 0.335f, 0.0f, 2.0f })), - std::make_unique( - envelopeParameterGroup(uid, "Pitch", { 0.0f, 0.0f, 0.144f, 1.0f, 7.5f })), - std::make_unique(oscSendParameterGroup(uid, "A")), - std::make_unique(oscSendParameterGroup(uid, "B")), - std::make_unique(oscSendParameterGroup(uid, "C"))); -} -} // namespace model -} // namespace dmt \ No newline at end of file diff --git a/model/ParameterLayout.h b/model/ParameterLayout.h deleted file mode 100644 index 46d60d5e..00000000 --- a/model/ParameterLayout.h +++ /dev/null @@ -1,34 +0,0 @@ -//============================================================================== - -#pragma once - -#include "../dsp/filter/FilterProcessor.h" - -#include "OscillatorParameters.h" - -#include - -//============================================================================== -namespace dmt { -//============================================================================== -static inline juce::AudioProcessorValueTreeState::ParameterLayout -createParameterLayout() -{ - using ParameterInt = juce::AudioParameterInt; - using ParameterFloat = juce::AudioParameterFloat; - using ParameterChoice = juce::AudioParameterChoice; - using ParameterGroup = juce::AudioProcessorParameterGroup; - using NormalisableRange = juce::NormalisableRange; - namespace Model = dmt::model; - return juce::AudioProcessorValueTreeState::ParameterLayout{ - std::make_unique("oscGain", // parameter ID - "Attack", // parameter name - NormalisableRange(0.0f, // rangeStart - 1.0f, // rangeEnd - 0.001f, // intervalValue - 0.5f), // skewFactor - 0.0f), // defaultValue - std::make_unique(Model::oscillatorParameterGroup(1)) - }; -} -} // namespace dmt diff --git a/model/VoiceParameters.h b/model/VoiceParameters.h deleted file mode 100644 index 90a713e4..00000000 --- a/model/VoiceParameters.h +++ /dev/null @@ -1,104 +0,0 @@ -#pragma once - -#include - -//============================================================================== -namespace dmt { -namespace model { -static inline juce::AudioProcessorParameterGroup -voiceParameterGroup(juce::String parentUid) -{ - using ParameterInt = juce::AudioParameterInt; - using ParameterFloat = juce::AudioParameterFloat; - using ParameterChoice = juce::AudioParameterChoice; - using NormalisableRange = juce::NormalisableRange; - - juce::String uid = parentUid + "Voice"; - - return juce::AudioProcessorParameterGroup( - uid, // group ID - "Voice", // group name - "|", // separator - std::make_unique(uid + "Octave", // parameter ID - "Octave", // parameter name - -4, // rangeStart - 4, // rangeEnd - 0), // defaultValue - std::make_unique(uid + "Semitone", // parameter ID - "Semitones", // parameter name - 0, // rangeStart - 11, // rangeEnd - 0), // defaultValue - std::make_unique(uid + "Fine", // parameter ID - "Fine", // parameter name - NormalisableRange(-100.f, // rangeStart - 100.f, // rangeEnd - .1f, // intervalValue - 1.f), // skewFactor - 0), - std::make_unique(uid + "Density", // parameter ID - "Density", // parameter name - 1, // rangeStart - 8, // rangeEnd - 1), // defaultValue - std::make_unique(uid + "Detune", // parameter ID - "Detune", // parameter name - NormalisableRange(0.f, // rangeStart - 100.f, - .1f, - 1.f), - 0.f), - std::make_unique(uid + "Distribution", // parameter ID - "Distribution", // parameter name - juce::StringArray{ "Linear", - "Quadratic", - "Cubic", - "Octic", - "Square Root", - "Cube Root", - "Octic Root", - "Sine", - "Random" }, // choices - 0), // default index - std::make_unique(uid + "Blend", // parameter ID - "Blend", // parameter name - NormalisableRange(0.f, // rangeStart - 100.f, // rangeEnd - .1f, // intervalValue - 1.f), // skewFactor - 0.f), // defaultValue - std::make_unique(uid + "Width", // parameter ID - "Width", // parameter name - NormalisableRange(0.f, // rangeStart - 100.f, // rangeEnd - .1f, // intervalValue - 1.f), // skewFactor - 0.f), // defaultValue - std::make_unique( - uid + "Seed", // parameter ID - "Seed", // parameter name - juce::StringArray{ "Random", - "Equal", - "Static #1", - "Static #2", - "Static #3", - "Static #4", - "Static #5" }, // choices - 0), // default index - std::make_unique(uid + "Random", // parameter ID - "Random", // parameter name - NormalisableRange(0.f, // rangeStart - 100.f, // rangeEnd - .1f, // intervalValue - 1.f), // skewFactor - 0.f), - std::make_unique(uid + "Phase", // parameter ID - "Phase", // parameter name - NormalisableRange(0.f, // rangeStart - 100.f, // rangeEnd - .1f, // intervalValue - 1.f), // skewFactor - 0.f)); // defaultValue -} -} // namespace model -} // namespace dmt \ No newline at end of file diff --git a/scripts/push_subtree.sh b/scripts/push_subtree.sh new file mode 100644 index 00000000..5c8346bb --- /dev/null +++ b/scripts/push_subtree.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +git subtree push --prefix=src/dmt dmt-upstream main \ No newline at end of file diff --git a/utility/Fonts.h b/utility/Fonts.h index 9638a7be..a85ac9b8 100644 --- a/utility/Fonts.h +++ b/utility/Fonts.h @@ -1,16 +1,15 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and diff --git a/utility/HostContextMenu.h b/utility/HostContextMenu.h index 133c7f25..b48e5cd5 100644 --- a/utility/HostContextMenu.h +++ b/utility/HostContextMenu.h @@ -1,4 +1,30 @@ //============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * HostContextMenu provides a CRTP base class for components that want to call + * the host's context menu for a parameter. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== #pragma once diff --git a/utility/Icon.h b/utility/Icon.h index 1a3cd2b7..83449986 100644 --- a/utility/Icon.h +++ b/utility/Icon.h @@ -1,16 +1,15 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and diff --git a/utility/Math.h b/utility/Math.h index aa579a56..a6cae533 100644 --- a/utility/Math.h +++ b/utility/Math.h @@ -1,16 +1,15 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and diff --git a/utility/RepaintTimer.h b/utility/RepaintTimer.h index a4250207..c8006aa9 100644 --- a/utility/RepaintTimer.h +++ b/utility/RepaintTimer.h @@ -1,16 +1,15 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and diff --git a/utility/Scaleable.h b/utility/Scaleable.h index 6cbb77ba..47c4b1cb 100644 --- a/utility/Scaleable.h +++ b/utility/Scaleable.h @@ -1,16 +1,15 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and @@ -109,6 +108,78 @@ class Scaleable : public IScaleable friend class gui::window::Compositor; public: + class LiveScale + { + public: + explicit LiveScale(const Scaleable& ownerIn) noexcept + : owner(ownerIn) + { + } + + [[nodiscard]] operator float() const noexcept + { + return owner.getScaleFactor(); + } + + // Allow implicit conversion for JUCE geometry types + friend juce::Point operator*(juce::Point point, + const LiveScale& scale) noexcept + { + return point * static_cast(scale); + } + + friend juce::Point operator*(juce::Point point, + const LiveScale& scale) noexcept + { + return point * static_cast(scale); + } + + friend juce::Point operator*(juce::Point point, + const LiveScale& scale) noexcept + { + return point * static_cast(static_cast(scale)); + } + + friend juce::Point operator*(const LiveScale& scale, + juce::Point point) noexcept + { + return point * static_cast(scale); + } + + friend juce::Point operator*(const LiveScale& scale, + juce::Point point) noexcept + { + return point * static_cast(scale); + } + + friend juce::Point operator*(const LiveScale& scale, + juce::Point point) noexcept + { + return point * static_cast(static_cast(scale)); + } + + friend juce::Rectangle operator/(juce::Rectangle rectangle, + const LiveScale& scale) noexcept + { + return rectangle / static_cast(scale); + } + + friend juce::Rectangle operator/(juce::Rectangle rectangle, + const LiveScale& scale) noexcept + { + return rectangle / static_cast(scale); + } + + friend juce::Rectangle operator/(juce::Rectangle rectangle, + const LiveScale& scale) noexcept + { + return rectangle / static_cast(static_cast(scale)); + } + + private: + const Scaleable& owner; + }; + //============================================================================ /** * @brief Reference to the current scaling factor for this component. @@ -122,7 +193,7 @@ class Scaleable : public IScaleable * * This is automatically calculated based on the OS and display. */ - const float scale; + const LiveScale scale; //============================================================================ /** @@ -131,10 +202,36 @@ class Scaleable : public IScaleable * Initializes the scaling references. */ Scaleable() - : scale(getScaleFactor()) + : scale(*this) { } + //============================================================================ + /** + * @brief Get the current desktop scale factor for this component. + * + * This resolves the scale from the actual component hierarchy instead of + * caching the primary display's scale at construction time. + */ + [[nodiscard]] float getScaleFactor() const noexcept + { + // TODO: Component Scale factor is fucked, for now we just use the main + // display's scale factor using the fallback + /* + const auto* component = static_cast(getSelf()); + + if (component != nullptr) { + const auto componentScale = + juce::Component::getApproximateScaleFactorForComponent(component); + + if (std::isfinite(componentScale) && componentScale > 0.0f) + return componentScale; + } + */ + + return getFallbackScaleFactor(); + } + private: //============================================================================ /** @@ -144,11 +241,20 @@ class Scaleable : public IScaleable //============================================================================ /** - * @brief Get the platform DPI scaling factor. + * @brief Helper to get the derived class pointer (CRTP). + */ + inline const Derived* getSelf() const noexcept + { + return static_cast(this); + } + + //============================================================================ + /** + * @brief Get a fallback platform DPI scaling factor. * - * On macOS, multiplies by 2.0 for Retina displays. + * Used when the component is not yet attached to a hierarchy. */ - const float getScaleFactor() noexcept + static float getFallbackScaleFactor() noexcept { // Find the main display auto* mainDisplay = @@ -160,8 +266,12 @@ class Scaleable : public IScaleable } // Get the scale factor from the main display - float tempScale = static_cast(mainDisplay->scale); - return tempScale; + const auto fallbackScale = static_cast(mainDisplay->scale); + + if (std::isfinite(fallbackScale) && fallbackScale > 0.0f) + return fallbackScale; + + return 1.0f; } /** @@ -172,7 +282,7 @@ class Scaleable : public IScaleable */ void setSizeFactor(const float& newSize) noexcept override { - if (&newSize != &internalSize) { + if (!juce::approximatelyEqual(newSize, internalSize)) { internalSize = newSize; } } diff --git a/utility/Settings.h b/utility/Settings.h index 46b4ba64..40142f41 100644 --- a/utility/Settings.h +++ b/utility/Settings.h @@ -1,16 +1,15 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and @@ -114,6 +113,7 @@ struct Settings static inline dmt::configuration::Container container; //============================================================================== + static inline auto appName = juce::String(""); // TODO: Remove this //============================================================================== @@ -127,7 +127,7 @@ struct Settings static inline auto& displayUpdateNotifications = container.add("General.DisplayUpdateNotifications", true); static inline auto& themeVersion = - container.add("General.ThemeVersion", 1); + container.add("General.ThemeVersion", 2); private: //============================================================================== @@ -172,7 +172,7 @@ struct Settings struct Window { //============================================================================== - static inline auto& margin = container.add("Window.Margin", 5.0f); + static inline auto& margin = container.add("Window.Margin", 10.0f); static inline auto& backgroundColour = container.add("Window.BackgroundColour", Colours::background); }; @@ -208,13 +208,19 @@ struct Settings static inline auto& height = container.add("Header.Height", 50); static inline auto& borderButtonBackgroundColour = container.add("Header.BorderButtonBackgroundColour", - Colours::primary); + Colours::success); + static inline auto& borderButtonBorderColour = + container.add("Header.BorderButtonBorderColour", + Colours::success.darker(0.5f)); static inline auto& borderButtonFontColour = - container.add("Header.BorderButtonFontColour", Colours::shadow); + container.add("Header.BorderButtonFontColour", + Colours::background); static inline auto& borderButtonFontSize = - container.add("Header.BorderButtonFontSize", 22.0f); + container.add("Header.BorderButtonFontSize", 20.0f); static inline auto& borderButtonHeight = container.add("Header.BorderButtonHeight", 25); + static inline auto& borderButtonBorderThickness = + container.add("Header.BorderButtonBorderThickness", 3.0f); }; //============================================================================== diff --git a/utility/Unit.h b/utility/Unit.h index bbd75f7e..7de6072c 100644 --- a/utility/Unit.h +++ b/utility/Unit.h @@ -1,16 +1,15 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and diff --git a/utility/Utility.h b/utility/Utility.h index ea08ea33..f37f5937 100644 --- a/utility/Utility.h +++ b/utility/Utility.h @@ -1,16 +1,15 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and @@ -19,9 +18,7 @@ * Your are not allowed to use this code in any closed-source project. * * Description: - * Aggregates all Dimethoxy utility headers for convenient inclusion. - * Provides a single entry point for utility classes, math, icons, fonts, - * settings, and real-time safe helpers. + * Utility header file. * * Authors: * Lunix-420 (Primary Author) @@ -31,17 +28,6 @@ #pragma once //============================================================================== -/** - * @brief Aggregates all Dimethoxy utility headers for convenient inclusion. - * - * @details - * This header includes all core utility modules (fonts, icons, math, repaint - * timer, scaleable, settings, and unit conversion) in a single file. Use this - * header to ensure consistent access to all utility features across the - * codebase. Designed for real-time safety and deterministic resource - * management. - */ -//============================================================================== #include "./Fonts.h" #include "./Icon.h" diff --git a/version/Info.h b/version/Info.h index e6cb3214..4d6257c5 100644 --- a/version/Info.h +++ b/version/Info.h @@ -1,16 +1,15 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and diff --git a/version/Manager.h b/version/Manager.h index 5044cd73..a284266b 100644 --- a/version/Manager.h +++ b/version/Manager.h @@ -1,16 +1,15 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and diff --git a/version/Networking.h b/version/Networking.h index f17e6d11..efedec54 100644 --- a/version/Networking.h +++ b/version/Networking.h @@ -1,16 +1,15 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and diff --git a/version/Utility.h b/version/Utility.h index e9acbdd6..d03fa6ad 100644 --- a/version/Utility.h +++ b/version/Utility.h @@ -1,16 +1,15 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and diff --git a/version/Version.h b/version/Version.h index 8e7fa94f..cd738432 100644 --- a/version/Version.h +++ b/version/Version.h @@ -1,16 +1,15 @@ //============================================================================== -/* - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ - * β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ - * +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) * - * This file is part of the Dimethoxy Library, a collection of essential - * classes used across various Dimethoxy projects. - * These files are primarily designed for internal use within our repositories. + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. * * License: * This code is licensed under the GPLv3 license. You are permitted to use and @@ -19,9 +18,7 @@ * Your are not allowed to use this code in any closed-source project. * * Description: - * Aggregates all Dimethoxy version management headers for convenient inclusion. - * Provides a single entry point for version management classes, including Info, - * Manager, Networking, and Utility. + * Version header file. * * Authors: * Lunix-420 (Primary Author) @@ -31,17 +28,6 @@ #pragma once //============================================================================== -/** - * @brief Aggregates all Dimethoxy version management headers for convenient - * inclusion. - * - * @details - * This header includes all core version management modules (Info, Manager, - * Networking, and Utility) in a single file. Use this header to ensure - * consistent access to all version management features across the codebase. - * Designed for real-time safety and deterministic resource management. - */ -//============================================================================== #include "./Info.h" #include "./Manager.h" From bfd4b698edf162d486fafd8dae62ec5eb750aa04 Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Thu, 23 Apr 2026 14:12:50 +0200 Subject: [PATCH 28/74] gui: fix oscilloscope overdraw --- .../gui/component/SettingsEditorComponent.h | 2 +- src/dmt/gui/display/AbstractDisplay.h | 22 +++++++++---------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/dmt/gui/component/SettingsEditorComponent.h b/src/dmt/gui/component/SettingsEditorComponent.h index 7f4f164b..a7bbe607 100644 --- a/src/dmt/gui/component/SettingsEditorComponent.h +++ b/src/dmt/gui/component/SettingsEditorComponent.h @@ -130,7 +130,7 @@ class SettingsEditor void onCategorySelectedCallback(TreeAdapter::Category& category) { TRACER("SettingsEditor::onCategorySelectedCallback"); - std::cout << "Selected category: " << category.name << std::endl; + valueEditorList.setCategory(category); valueEditorList.setOptimalSize(editorViewport.getWidth()); } diff --git a/src/dmt/gui/display/AbstractDisplay.h b/src/dmt/gui/display/AbstractDisplay.h index 46f868eb..34080e51 100644 --- a/src/dmt/gui/display/AbstractDisplay.h +++ b/src/dmt/gui/display/AbstractDisplay.h @@ -67,6 +67,8 @@ class AbstractDisplay // General using Display = dmt::Settings::Display; const juce::Colour& backgroundColour = Display::backgroundColour; + const juce::Colour& displayForegroundColour = + dmt::Settings::Panel::backgroundColour; // Layout const float& rawCornerSize = Display::cornerSize; @@ -121,26 +123,22 @@ class AbstractDisplay // Precalculation const auto borderStrength = rawBorderStrength * size; const auto cornerSize = rawCornerSize * size; + const auto padding = rawPadding * size; const float outerCornerSize = cornerSize; const float innerCornerSize = std::clamp( outerCornerSize - (borderStrength * 0.5f), 0.0f, outerCornerSize); - // Draw background if border is disabled - if (!drawBorder) { - _g.setColour(backgroundColour); - _g.fillRoundedRectangle(outerBounds.toFloat(), outerCornerSize); - } + // Draw background + _g.setColour(backgroundColour); + _g.fillRoundedRectangle(innerBounds.toFloat(), innerCornerSize); - // Draw background and border if border is enabled - if (drawBorder) { - _g.setColour(borderColour); - _g.fillRoundedRectangle(outerBounds.toFloat(), outerCornerSize); - _g.setColour(backgroundColour); - _g.fillRoundedRectangle(innerBounds.toFloat(), innerCornerSize); - } // Draw display paintDisplay(_g, innerBounds); + // Draw outer background to hide display overdraw + _g.setColour(displayForegroundColour); + _g.drawRect(getLocalBounds().toFloat(), padding); + // We need to draw the border again because drawing it once didn't cut it if (drawBorder) { _g.setColour(borderColour); From 70c3348dc25b62b1063617f4b0e1ea7f247ceacc Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Thu, 23 Apr 2026 14:23:22 +0200 Subject: [PATCH 29/74] gui: change default button theme --- src/dmt/utility/Settings.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dmt/utility/Settings.h b/src/dmt/utility/Settings.h index 40142f41..d7ed02ec 100644 --- a/src/dmt/utility/Settings.h +++ b/src/dmt/utility/Settings.h @@ -427,9 +427,9 @@ struct Settings static inline auto& fontColour = container.add("Button.FontColour", Colours::font); static inline auto& hoverColour = - container.add("Button.HoverColour", Colours::primary); + container.add("Button.HoverColour", Colours::font); static inline auto& clickColour = - container.add("Button.ClickColour", Colours::font); + container.add("Button.ClickColour", Colours::primary); static inline auto& outerShadowRadius = container.add("Button.OuterShadowRadius", 5.0f); static inline auto& innerShadowRadius = From 57dcee348f7fa9c2f50443f5bcaed72a173b3fd2 Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Thu, 23 Apr 2026 14:32:06 +0200 Subject: [PATCH 30/74] feat: add option to disable hardware acceleration and update notification setting --- src/dmt/utility/Settings.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/dmt/utility/Settings.h b/src/dmt/utility/Settings.h index d7ed02ec..c572ee3b 100644 --- a/src/dmt/utility/Settings.h +++ b/src/dmt/utility/Settings.h @@ -125,9 +125,11 @@ struct Settings static inline auto& debugGrid = container.add("General.ShowDebugGrid", false); static inline auto& displayUpdateNotifications = - container.add("General.DisplayUpdateNotifications", true); + container.add("General.DisplayUpdateNotifications", false); static inline auto& themeVersion = container.add("General.ThemeVersion", 2); + static inline auto& disableHardwareAcceleration = + container.add("General.DisableHardwareAcceleration", false); private: //============================================================================== From 672b7632c40e6e4958c845b549d0650a969d6441 Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Thu, 23 Apr 2026 15:00:23 +0200 Subject: [PATCH 31/74] feat: implement hardware acceleration control based on OS and Wine detection --- src/dmt/app/AbstractPluginEditor.h | 144 ++++++++++++++++++++++------- src/dmt/utility/Settings.h | 36 +++++++- 2 files changed, 144 insertions(+), 36 deletions(-) diff --git a/src/dmt/app/AbstractPluginEditor.h b/src/dmt/app/AbstractPluginEditor.h index 8e64f76a..33f317f8 100644 --- a/src/dmt/app/AbstractPluginEditor.h +++ b/src/dmt/app/AbstractPluginEditor.h @@ -1,5 +1,11 @@ #pragma once +//============================================================================== +// Preprocessor flags for renderer control +#define DMT_SUPPRESS_GL_DEBUG_MESSAGES 1 + +//============================================================================== + #include "app/AbstractPluginProcessor.h" #include "gui/window/Compositor.h" #include @@ -40,48 +46,51 @@ class AbstractPluginEditor // Now that layout is fully configured, attach the compositor addAndMakeVisible(compositor); + // Determine if hardware acceleration should be used + bool shouldUseHardwareAccel = !dmt::Settings::disableHardwareAcceleration; + DBG("[AbstractPluginEditor] Hardware acceleration: " + << (shouldUseHardwareAccel ? "ENABLED" : "DISABLED")); + if (OS_IS_WINDOWS) { - setResizable(false, true); + // Windows: D2D (Direct2D) is hardware accelerated by default. + // To disable it, we need to wait for the peer to be created and then + // call setCurrentRenderingEngine(0) for software rendering. +#if OS_IS_WINDOWS + if (!shouldUseHardwareAccel) { + DBG("[AbstractPluginEditor] Windows: Using software renderer (Direct2D " + "disabled)"); + awaitingPeerForDirect2D = true; + } else { + DBG("[AbstractPluginEditor] Windows: Using Direct2D renderer"); + } +#endif } if (OS_IS_DARWIN) { + // macOS: Use OpenGL for hardware acceleration if enabled + if (shouldUseHardwareAccel) { + DBG("[AbstractPluginEditor] macOS: Using OpenGL renderer"); + openGLContext.setComponentPaintingEnabled(true); + openGLContext.setContinuousRepainting(false); + openGLContext.attachTo(*getTopLevelComponent()); + setupOpenGLContext(); + } else { + DBG("[AbstractPluginEditor] macOS: Using default renderer (software)"); + } setResizable(false, true); } if (OS_IS_LINUX) { - openGLContext.setComponentPaintingEnabled(true); - openGLContext.setContinuousRepainting(false); - openGLContext.attachTo(*getTopLevelComponent()); - std::thread([this]() { - for (int i = 0; i < 200; ++i) { - if (openGLContext.isAttached() && - openGLContext.getRawContext() != nullptr) - break; - std::this_thread::sleep_for(std::chrono::milliseconds(25)); - } - - if (!openGLContext.isAttached() || - openGLContext.getRawContext() == nullptr) - return; - - openGLContext.executeOnGLThread( - [](juce::OpenGLContext&) { - if (juce::gl::glDebugMessageControl) { - juce::gl::glDebugMessageControl( - juce::gl::GL_DEBUG_SOURCE_API, - juce::gl::GL_DEBUG_TYPE_OTHER, - juce::gl::GL_DEBUG_SEVERITY_NOTIFICATION, - 0, - nullptr, - juce::gl::GL_FALSE); - } - - if (juce::gl::glDebugMessageCallback) - juce::gl::glDebugMessageCallback(juceFilteredGLDebugCallback, - nullptr); - }, - true); - }).detach(); + // Linux: Use OpenGL for hardware acceleration if enabled + if (shouldUseHardwareAccel) { + DBG("[AbstractPluginEditor] Linux: Using OpenGL renderer"); + openGLContext.setComponentPaintingEnabled(true); + openGLContext.setContinuousRepainting(false); + openGLContext.attachTo(*getTopLevelComponent()); + setupOpenGLContext(); + } else { + DBG("[AbstractPluginEditor] Linux: Using default renderer (software)"); + } } setConstraints(baseWidth, baseHeight + headerHeight); @@ -147,6 +156,24 @@ class AbstractPluginEditor detachCompositorForResize(); } + //============================================================================== + // Handle peer creation for Windows Direct2D setup + + void parentHierarchyChanged() override + { +#if OS_IS_WINDOWS + // Try to disable Direct2D when peer is created + if (awaitingPeerForDirect2D) { + if (auto peer = getPeer()) { + DBG("[AbstractPluginEditor] Windows peer created - switching to " + "software renderer"); + peer->setCurrentRenderingEngine(0); // 0 = software, 1 = Direct2D + awaitingPeerForDirect2D = false; + } + } +#endif + } + //============================================================================== // JUCE overrides @@ -183,7 +210,7 @@ class AbstractPluginEditor { stopTimer(); attachCompositorAfterResize(); - repaint(); // TODO: Redundanr call, maybe remove this? + repaint(); // TODO: Redundant call, maybe remove this? } // Detach compositor to improve resize performance @@ -246,6 +273,49 @@ class AbstractPluginEditor } } + //============================================================================== + // OpenGL initialization + + void setupOpenGLContext() + { + std::thread([this]() { + for (int i = 0; i < 200; ++i) { + if (openGLContext.isAttached() && + openGLContext.getRawContext() != nullptr) + break; + std::this_thread::sleep_for(std::chrono::milliseconds(25)); + } + + if (!openGLContext.isAttached() || + openGLContext.getRawContext() == nullptr) + return; + + openGLContext.executeOnGLThread( + [](juce::OpenGLContext&) { +#if DMT_SUPPRESS_GL_DEBUG_MESSAGES + DBG("[AbstractPluginEditor] GL debug message suppression: ENABLED"); + // Suppress low-priority GL debug messages + if (juce::gl::glDebugMessageControl) { + juce::gl::glDebugMessageControl( + juce::gl::GL_DEBUG_SOURCE_API, + juce::gl::GL_DEBUG_TYPE_OTHER, + juce::gl::GL_DEBUG_SEVERITY_NOTIFICATION, + 0, + nullptr, + juce::gl::GL_FALSE); + } +#else + DBG("[AbstractPluginEditor] GL debug message suppression: DISABLED"); +#endif + // Set up callback for GL debug messages + if (juce::gl::glDebugMessageCallback) + juce::gl::glDebugMessageCallback(juceFilteredGLDebugCallback, + nullptr); + }, + true); + }).detach(); + } + //============================================================================== // OpenGL debug overwrite @@ -291,6 +361,10 @@ class AbstractPluginEditor Image image; bool isResizing = false; +#if OS_IS_WINDOWS + bool awaitingPeerForDirect2D = false; +#endif + dmt::gui::window::Layout mainLayout; dmt::gui::window::Compositor compositor; diff --git a/src/dmt/utility/Settings.h b/src/dmt/utility/Settings.h index c572ee3b..f975b3fc 100644 --- a/src/dmt/utility/Settings.h +++ b/src/dmt/utility/Settings.h @@ -71,6 +71,39 @@ static constexpr bool DMT_DISABLE_UPDATE_NOTIFICATION = false; namespace dmt { +//============================================================================== +/** + * @brief Detects if the application is running under Wine on Windows. + * + * @details + * Wine is a compatibility layer that allows Windows applications to run on + * Linux and other Unix-like systems. This function detects its presence by + * looking for the wine_get_version export in ntdll.dll. + * + * @return true if running under Wine, false otherwise (or on non-Windows) + */ +inline bool +isRunningUnderWine() +{ +#if OS_IS_WINDOWS + auto hntdll = GetModuleHandleA("ntdll.dll"); + if (!hntdll) + return false; + + auto pwine_get_version = GetProcAddress(hntdll, "wine_get_version"); + bool isWine = (pwine_get_version != nullptr); + + if (isWine) { + DBG( + "[Settings] Wine detected - disabling hardware acceleration by default"); + } + + return isWine; +#else + return false; +#endif +} + //============================================================================== /** * @brief Centralized static settings and theme configuration for Dimethoxy UI. @@ -129,7 +162,8 @@ struct Settings static inline auto& themeVersion = container.add("General.ThemeVersion", 2); static inline auto& disableHardwareAcceleration = - container.add("General.DisableHardwareAcceleration", false); + container.add("General.DisableHardwareAcceleration", + isRunningUnderWine()); // Disable by default under Wine private: //============================================================================== From d5810773375b5f167c342b6b7b1c9ca44b5389d3 Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Mon, 4 May 2026 20:38:40 +0200 Subject: [PATCH 32/74] fix: update debug messages for renderer selection and change GL debug suppression flag --- src/dmt/app/AbstractPluginEditor.h | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/dmt/app/AbstractPluginEditor.h b/src/dmt/app/AbstractPluginEditor.h index 33f317f8..f74745fe 100644 --- a/src/dmt/app/AbstractPluginEditor.h +++ b/src/dmt/app/AbstractPluginEditor.h @@ -2,7 +2,7 @@ //============================================================================== // Preprocessor flags for renderer control -#define DMT_SUPPRESS_GL_DEBUG_MESSAGES 1 +#define DMT_SUPPRESS_GL_DEBUG_MESSAGES 0 //============================================================================== @@ -57,11 +57,10 @@ class AbstractPluginEditor // call setCurrentRenderingEngine(0) for software rendering. #if OS_IS_WINDOWS if (!shouldUseHardwareAccel) { - DBG("[AbstractPluginEditor] Windows: Using software renderer (Direct2D " - "disabled)"); + DBG("[AbstractPluginEditor] Using Windows Direct2D renderer"); awaitingPeerForDirect2D = true; } else { - DBG("[AbstractPluginEditor] Windows: Using Direct2D renderer"); + DBG("[AbstractPluginEditor] Using Windows software renderer"); } #endif } @@ -69,13 +68,13 @@ class AbstractPluginEditor if (OS_IS_DARWIN) { // macOS: Use OpenGL for hardware acceleration if enabled if (shouldUseHardwareAccel) { - DBG("[AbstractPluginEditor] macOS: Using OpenGL renderer"); + DBG("[AbstractPluginEditor] Using macOS OpenGL renderer"); openGLContext.setComponentPaintingEnabled(true); openGLContext.setContinuousRepainting(false); openGLContext.attachTo(*getTopLevelComponent()); setupOpenGLContext(); } else { - DBG("[AbstractPluginEditor] macOS: Using default renderer (software)"); + DBG("[AbstractPluginEditor] Using macOS software renderer"); } setResizable(false, true); } @@ -83,13 +82,13 @@ class AbstractPluginEditor if (OS_IS_LINUX) { // Linux: Use OpenGL for hardware acceleration if enabled if (shouldUseHardwareAccel) { - DBG("[AbstractPluginEditor] Linux: Using OpenGL renderer"); + DBG("[AbstractPluginEditor] Using Linux OpenGL renderer"); openGLContext.setComponentPaintingEnabled(true); openGLContext.setContinuousRepainting(false); openGLContext.attachTo(*getTopLevelComponent()); setupOpenGLContext(); } else { - DBG("[AbstractPluginEditor] Linux: Using default renderer (software)"); + DBG("[AbstractPluginEditor] Using Linux software renderer"); } } @@ -161,12 +160,11 @@ class AbstractPluginEditor void parentHierarchyChanged() override { + DBG("[AbstractPluginEditor] parentHierarchyChanged called"); #if OS_IS_WINDOWS // Try to disable Direct2D when peer is created if (awaitingPeerForDirect2D) { if (auto peer = getPeer()) { - DBG("[AbstractPluginEditor] Windows peer created - switching to " - "software renderer"); peer->setCurrentRenderingEngine(0); // 0 = software, 1 = Direct2D awaitingPeerForDirect2D = false; } From d884a9a89b7491900842ed7f366679b7919c572c Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Tue, 5 May 2026 12:25:07 +0200 Subject: [PATCH 33/74] refactor: streamline hardware acceleration logic and OS detection in settings --- external/clap | 2 +- src/dmt/app/AbstractPluginEditor.h | 45 +++++------------------- src/dmt/configuration/Options.h | 9 +++-- src/dmt/utility/Settings.h | 55 +++++++----------------------- 4 files changed, 29 insertions(+), 82 deletions(-) diff --git a/external/clap b/external/clap index e1f67893..e8de9e85 160000 --- a/external/clap +++ b/external/clap @@ -1 +1 @@ -Subproject commit e1f67893cc409a40c1154fa2e78c97046da24ce0 +Subproject commit e8de9e8571626633b8541a54c2406fccc4272767 diff --git a/src/dmt/app/AbstractPluginEditor.h b/src/dmt/app/AbstractPluginEditor.h index f74745fe..29b12e9b 100644 --- a/src/dmt/app/AbstractPluginEditor.h +++ b/src/dmt/app/AbstractPluginEditor.h @@ -46,28 +46,15 @@ class AbstractPluginEditor // Now that layout is fully configured, attach the compositor addAndMakeVisible(compositor); +#if OS_IS_DARWIN || OS_IS_LINUX // Determine if hardware acceleration should be used - bool shouldUseHardwareAccel = !dmt::Settings::disableHardwareAcceleration; - DBG("[AbstractPluginEditor] Hardware acceleration: " - << (shouldUseHardwareAccel ? "ENABLED" : "DISABLED")); - - if (OS_IS_WINDOWS) { - // Windows: D2D (Direct2D) is hardware accelerated by default. - // To disable it, we need to wait for the peer to be created and then - // call setCurrentRenderingEngine(0) for software rendering. -#if OS_IS_WINDOWS - if (!shouldUseHardwareAccel) { - DBG("[AbstractPluginEditor] Using Windows Direct2D renderer"); - awaitingPeerForDirect2D = true; - } else { - DBG("[AbstractPluginEditor] Using Windows software renderer"); - } -#endif - } + bool shouldUseOpenGL = !dmt::Settings::useOpenGL; + DBG("[AbstractPluginEditor] OpenGL renderer: " + << (shouldUseOpenGL ? "ENABLED" : "DISABLED")); if (OS_IS_DARWIN) { // macOS: Use OpenGL for hardware acceleration if enabled - if (shouldUseHardwareAccel) { + if (shouldUseOpenGL) { DBG("[AbstractPluginEditor] Using macOS OpenGL renderer"); openGLContext.setComponentPaintingEnabled(true); openGLContext.setContinuousRepainting(false); @@ -81,7 +68,7 @@ class AbstractPluginEditor if (OS_IS_LINUX) { // Linux: Use OpenGL for hardware acceleration if enabled - if (shouldUseHardwareAccel) { + if (shouldUseOpenGL) { DBG("[AbstractPluginEditor] Using Linux OpenGL renderer"); openGLContext.setComponentPaintingEnabled(true); openGLContext.setContinuousRepainting(false); @@ -92,6 +79,8 @@ class AbstractPluginEditor } } +#endif + setConstraints(baseWidth, baseHeight + headerHeight); setResizable(false, true); @@ -158,19 +147,7 @@ class AbstractPluginEditor //============================================================================== // Handle peer creation for Windows Direct2D setup - void parentHierarchyChanged() override - { - DBG("[AbstractPluginEditor] parentHierarchyChanged called"); -#if OS_IS_WINDOWS - // Try to disable Direct2D when peer is created - if (awaitingPeerForDirect2D) { - if (auto peer = getPeer()) { - peer->setCurrentRenderingEngine(0); // 0 = software, 1 = Direct2D - awaitingPeerForDirect2D = false; - } - } -#endif - } + void parentHierarchyChanged() override {} //============================================================================== // JUCE overrides @@ -359,10 +336,6 @@ class AbstractPluginEditor Image image; bool isResizing = false; -#if OS_IS_WINDOWS - bool awaitingPeerForDirect2D = false; -#endif - dmt::gui::window::Layout mainLayout; dmt::gui::window::Compositor compositor; diff --git a/src/dmt/configuration/Options.h b/src/dmt/configuration/Options.h index 909d3c98..ca53bef3 100644 --- a/src/dmt/configuration/Options.h +++ b/src/dmt/configuration/Options.h @@ -55,12 +55,15 @@ getOptions() noexcept options.filenameSuffix = ".config"; options.storageFormat = juce::PropertiesFile::storeAsXML; - if constexpr (OS_IS_WINDOWS) { + if (OS_IS_WINDOWS) { options.folderName = juce::String("Dimethoxy/") + name; - } else if constexpr (OS_IS_DARWIN) { + } else if (OS_IS_DARWIN) { options.folderName = juce::String("Dimethoxy/") + name; - } else if constexpr (OS_IS_LINUX) { + } else if (OS_IS_LINUX) { options.folderName = juce::String(".config/Dimethoxy/") + name; + } else { + // What the hell is the OS? + options.folderName = juce::String("Dimethoxy/") + name; } options.osxLibrarySubFolder = "Application Support"; diff --git a/src/dmt/utility/Settings.h b/src/dmt/utility/Settings.h index f975b3fc..7d410073 100644 --- a/src/dmt/utility/Settings.h +++ b/src/dmt/utility/Settings.h @@ -39,21 +39,21 @@ // OS constexprs set by CMake preprocessor definitions #if defined(CMAKE_OS_IS_WINDOWS) && CMAKE_OS_IS_WINDOWS -static constexpr bool OS_IS_WINDOWS = true; +#define OS_IS_WINDOWS 1 #else -static constexpr bool OS_IS_WINDOWS = false; +#define OS_IS_WINDOWS 0 #endif #if defined(CMAKE_OS_IS_DARWIN) && CMAKE_OS_IS_DARWIN -static constexpr bool OS_IS_DARWIN = true; +#define OS_IS_DARWIN 1 #else -static constexpr bool OS_IS_DARWIN = false; +#define OS_IS_DARWIN 0 #endif #if defined(CMAKE_OS_IS_LINUX) && CMAKE_OS_IS_LINUX -static constexpr bool OS_IS_LINUX = true; +#define OS_IS_LINUX 1 #else -static constexpr bool OS_IS_LINUX = false; +#define OS_IS_LINUX 0 #endif static_assert( @@ -71,39 +71,6 @@ static constexpr bool DMT_DISABLE_UPDATE_NOTIFICATION = false; namespace dmt { -//============================================================================== -/** - * @brief Detects if the application is running under Wine on Windows. - * - * @details - * Wine is a compatibility layer that allows Windows applications to run on - * Linux and other Unix-like systems. This function detects its presence by - * looking for the wine_get_version export in ntdll.dll. - * - * @return true if running under Wine, false otherwise (or on non-Windows) - */ -inline bool -isRunningUnderWine() -{ -#if OS_IS_WINDOWS - auto hntdll = GetModuleHandleA("ntdll.dll"); - if (!hntdll) - return false; - - auto pwine_get_version = GetProcAddress(hntdll, "wine_get_version"); - bool isWine = (pwine_get_version != nullptr); - - if (isWine) { - DBG( - "[Settings] Wine detected - disabling hardware acceleration by default"); - } - - return isWine; -#else - return false; -#endif -} - //============================================================================== /** * @brief Centralized static settings and theme configuration for Dimethoxy UI. @@ -161,9 +128,13 @@ struct Settings container.add("General.DisplayUpdateNotifications", false); static inline auto& themeVersion = container.add("General.ThemeVersion", 2); - static inline auto& disableHardwareAcceleration = - container.add("General.DisableHardwareAcceleration", - isRunningUnderWine()); // Disable by default under Wine +#if OS_IS_LINUX + static inline auto& useOpenGL = + container.add("General.UseOpenGL", true); +#elif OS_IS_DARWIN + static inline auto& useOpenGL = + container.add("General.UseOpenGL", false); +#endif private: //============================================================================== From 7b48828271bc46b4fbee1c0924e23ad952df5bb9 Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Tue, 5 May 2026 12:29:22 +0200 Subject: [PATCH 34/74] fix: adjust default values for panel shadow radius settings --- src/dmt/utility/Settings.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dmt/utility/Settings.h b/src/dmt/utility/Settings.h index 7d410073..029aeb44 100644 --- a/src/dmt/utility/Settings.h +++ b/src/dmt/utility/Settings.h @@ -480,9 +480,9 @@ struct Settings static inline auto& innerShadowColour = container.add("Panel.InnerShadowColour", Colours::shadow); static inline auto& outerShadowRadius = - container.add("Panel.OuterShadowRadius", 10.0f); + container.add("Panel.OuterShadowRadius", 5.0f); static inline auto& innerShadowRadius = - container.add("Panel.InnerShadowRadius", 10.0f); + container.add("Panel.InnerShadowRadius", 5.0f); static inline auto& fontColor = container.add("Panel.FontColor", Colours::font); static inline auto& fontSize = From d3b9edaa3b0647df988444981612cf7a8036fc70 Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Tue, 5 May 2026 13:46:41 +0200 Subject: [PATCH 35/74] fix: more hardware acceleration stuff --- CMakeLists.txt | 2 +- external/juce | 2 +- src/dmt/app/AbstractPluginEditor.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 951f0f5b..e453cd29 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ include(cmake/get_cpm.cmake) CPMAddPackage( NAME JUCE GITHUB_REPOSITORY juce-framework/JUCE - GIT_TAG master + GIT_TAG develop SOURCE_DIR ${EXT_DIR}/juce ) CPMAddPackage( diff --git a/external/juce b/external/juce index 501c0767..fe21fd1f 160000 --- a/external/juce +++ b/external/juce @@ -1 +1 @@ -Subproject commit 501c07674e1ad693085a7e7c398f205c2677f5da +Subproject commit fe21fd1feb06aaf1b56dba91ec322c7ff41f7fa9 diff --git a/src/dmt/app/AbstractPluginEditor.h b/src/dmt/app/AbstractPluginEditor.h index 29b12e9b..39a5dbe6 100644 --- a/src/dmt/app/AbstractPluginEditor.h +++ b/src/dmt/app/AbstractPluginEditor.h @@ -48,7 +48,7 @@ class AbstractPluginEditor #if OS_IS_DARWIN || OS_IS_LINUX // Determine if hardware acceleration should be used - bool shouldUseOpenGL = !dmt::Settings::useOpenGL; + bool shouldUseOpenGL = dmt::Settings::useOpenGL; DBG("[AbstractPluginEditor] OpenGL renderer: " << (shouldUseOpenGL ? "ENABLED" : "DISABLED")); From db5a4769857afdcce14cdfb461333165c741a3d7 Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Tue, 5 May 2026 18:19:14 +0200 Subject: [PATCH 36/74] fix: pin JUCE to version 8.0.12 --- CMakeLists.txt | 2 +- external/juce | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e453cd29..babd942b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ include(cmake/get_cpm.cmake) CPMAddPackage( NAME JUCE GITHUB_REPOSITORY juce-framework/JUCE - GIT_TAG develop + GIT_TAG 8.0.12 SOURCE_DIR ${EXT_DIR}/juce ) CPMAddPackage( diff --git a/external/juce b/external/juce index fe21fd1f..29396c22 160000 --- a/external/juce +++ b/external/juce @@ -1 +1 @@ -Subproject commit fe21fd1feb06aaf1b56dba91ec322c7ff41f7fa9 +Subproject commit 29396c22c93392d6738e021b83196283d6e4d850 From c5dbf641800d32db5c83917efa48785a4a586771 Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Tue, 5 May 2026 18:20:52 +0200 Subject: [PATCH 37/74] Squashed 'src/dmt/' changes from acd21b9..93f7d04 93f7d04 dsp: fix neutrino pwm dc13e6c dsp: implement oscillator warp for neutrino c75d7a7 dsp: refactor neutrino pitch envelope logic 4eaf20c dsp: add another pitch envelope to neutrino voice 6168a07 dsp: improve PWM handling in DigitalOscillator 9ef22ef dsp: remove analog oscillator 0283d17 dsp: update getSample method in AnalogWaveform to include delta parameter c7ca368 dsp: fix sample rate setting in AnalogOscillator to call reset function 8d6c106 dsp: clear out analog waveform and oscillator 4be398b dsp: integrate AnalogOscillator into NeutrinoSynthVoice and add parameters 320d6f4 dsp: implement AnalogOscillator and AnalogWaveform classes 0ad390e dsp: adjust neutrino default preset cda280f dsp: add small comment d12ad65 dsp: fix AdhEnvelope bend causing artifacts 0470ed4 dsp: fix neutrino init sound and osc reset 5b52c68 fix: correct waveform type assignment and update modulation depth source 8038bd5 dsp: fix parameter reading 382afcf fix: misc compiler errors from refactor 81af4a6 dsp: refactor DigitalOscillator to use parameter struct bcfe571 dsp: wire up neutrino voice 2da73e2 dsp: first wave of synth refactoring c68561e feat: replace random sample generation with JUCE Random for improved randomness 9c3ac94 feat: update NeutrinoProcessor to handle MIDI messages and adjust synth voice settings d94e16d dsp: wire up basic synth voice and processor structure b7afd47 feat: add NeutrinoProcessor class for kick drum sound processing 09510ca feat: add script to pull DMT repository as a subtree ab113e2 dsp: retire old oscillator d80f690 feat: add script to integrate DMT repository as a subtree git-subtree-dir: src/dmt git-subtree-split: 93f7d048e8823b5116c696b2c2b80c28fa3a5efc --- dsp/effect/Effect.h | 1 + .../effect/NeutrinoProcessor.h | 161 +++-- dsp/envelope/AdhEnvelope.h | 80 ++- dsp/synth/AnalogOscillator.h | 297 -------- dsp/synth/DigitalOscillator.h | 356 ++++++++++ .../{AnalogWaveform.h => DigitalWaveform.h} | 306 ++++----- .../{SynthVoice.h => NeutrinoSynthVoice.h} | 641 +++++++++--------- dsp/synth/Synth.h | 6 +- gui/component/OscillatorDisplayComponent.h | 321 ++++----- gui/panel/AnalogGainPanel.h | 26 +- gui/panel/AnalogPitchPanel.h | 38 +- gui/panel/OscillatorPanel.h | 2 - gui/panel/Panel.h | 1 - model/AhdEnvelopeParameters.h | 73 ++ model/DigitalOscillatorParameters.h | 83 +++ model/NeutrinoParameters.h | 25 +- model/WaveformParameters.h | 51 -- scripts/add_subtree.sh | 7 + scripts/pull_subtree.sh | 1 + utility/Unit.h | 5 +- 20 files changed, 1370 insertions(+), 1111 deletions(-) rename gui/panel/AnalogOscillatorPanel.h => dsp/effect/NeutrinoProcessor.h (52%) delete mode 100644 dsp/synth/AnalogOscillator.h create mode 100644 dsp/synth/DigitalOscillator.h rename dsp/synth/{AnalogWaveform.h => DigitalWaveform.h} (95%) rename dsp/synth/{SynthVoice.h => NeutrinoSynthVoice.h} (69%) create mode 100644 model/AhdEnvelopeParameters.h create mode 100644 model/DigitalOscillatorParameters.h delete mode 100644 model/WaveformParameters.h create mode 100644 scripts/add_subtree.sh create mode 100644 scripts/pull_subtree.sh diff --git a/dsp/effect/Effect.h b/dsp/effect/Effect.h index 5224abb6..8942637e 100644 --- a/dsp/effect/Effect.h +++ b/dsp/effect/Effect.h @@ -33,5 +33,6 @@ #include "./Distortion.h" #include "./HeretikProcessor.h" #include "./LowpassProcessor.h" +#include "./NeutrinoProcessor.h" //============================================================================== \ No newline at end of file diff --git a/gui/panel/AnalogOscillatorPanel.h b/dsp/effect/NeutrinoProcessor.h similarity index 52% rename from gui/panel/AnalogOscillatorPanel.h rename to dsp/effect/NeutrinoProcessor.h index 1ad9f7df..cb1f2da3 100644 --- a/gui/panel/AnalogOscillatorPanel.h +++ b/dsp/effect/NeutrinoProcessor.h @@ -1,56 +1,105 @@ -//============================================================================== -/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— - * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• - * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• - * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ - * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• - * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) - * - * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. - * External use is permitted but not recommended. - * No support or compatibility guarantees are provided. - * - * License: - * This code is licensed under the GPLv3 license. You are permitted to use and - * modify this code under the terms of this license. - * You must adhere GPLv3 license for any project using this code or parts of it. - * Your are not allowed to use this code in any closed-source project. - * - * Description: - * AnalogOscillatorPanel is a GUI component that provides controls for an analog - * oscillator. - * - * Authors: Lunix-420 (Primary Author) - */ -//============================================================================== - -#pragma once - -//============================================================================== - -#include "gui/panel/AbstractPanel.h" -#include - -//============================================================================== - -namespace dmt { -namespace gui { -namespace panel { - -//============================================================================== -class AnalogOscillatorPanel : public dmt::gui::panel::AbstractPanel -{ -public: - AnalogOscillatorPanel(/*juce::AudioProcessorValueTreeState& apvts*/) - : AbstractPanel("Classic Oscillator") - { // - } - -private: - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(AnalogOscillatorPanel) -}; -//============================================================================== -} // namespace panels -} // namespace gui -} // namespace dmt +//============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * Neutrino Processor class for processing audio buffers to generate a kick drum + * sound. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== + +#pragma once + +//============================================================================== + +#include "dsp/synth/NeutrinoSynthVoice.h" +#include "dsp/synth/SynthSound.h" +#include +#include + +namespace dmt { +namespace dsp { +namespace effect { + +//============================================================================== + +/** + * @brief Neutrino Processor + * + * This class processes audio buffers to generate a kick drum sound. + */ +class alignas(64) NeutrinoProcessor +{ + constexpr static float MIN_FREQUENCY = 20.0f; + constexpr static float MAX_FREQUENCY = 20000.0f; + + using AudioBuffer = juce::AudioBuffer; + using SynthVoice = dmt::dsp::synth::NeutrinoSynthVoice; + using SynthSound = dmt::dsp::synth::SynthSound; + +public: + NeutrinoProcessor(juce::AudioProcessorValueTreeState& _apvts) + : apvts(_apvts) + { + synth.addSound(new SynthSound()); + synth.addVoice(new SynthVoice(apvts)); + } + + //============================================================================== + /** + * @brief Prepares the processor with the given sample rate. + * + * @param _newSampleRate The sample rate. + */ + inline void prepare(const double _newSampleRate, + const int _samplesPerBlock) noexcept + { + sampleRate = static_cast(_newSampleRate); + + synth.setCurrentPlaybackSampleRate(sampleRate); + + for (int i = 0; i < synth.getNumVoices(); i++) { + auto voice = dynamic_cast(synth.getVoice(i)); + voice->prepareToPlay(sampleRate, _samplesPerBlock, 2); + } + } + + inline void processBlock(AudioBuffer& _buffer, + juce::MidiBuffer& _midiMessages) noexcept + { + if (sampleRate <= 0.0f) { + return; + } + + synth.renderNextBlock(_buffer, _midiMessages, 0, _buffer.getNumSamples()); + } + +private: + //============================================================================== + juce::Synthesiser synth; + juce::AudioProcessorValueTreeState& apvts; + float sampleRate = -1.0f; +}; + +//============================================================================== +} // namespace effect +} // namespace dsp +} // namespace dmt \ No newline at end of file diff --git a/dsp/envelope/AdhEnvelope.h b/dsp/envelope/AdhEnvelope.h index 2e184ebf..f37bfb47 100644 --- a/dsp/envelope/AdhEnvelope.h +++ b/dsp/envelope/AdhEnvelope.h @@ -50,16 +50,18 @@ class AhdEnvelope public: struct Parameters { + bool enabled = true; float attack = 0.015f; float hold = 0.08f; float decay = 0.5f; - - float attackSkew = 0; - float decaySkew = 10; + float attackBend = 0; + float decayBend = 0; + float depth = 1.0f; }; enum class State { + Disabled, Attack, Hold, Decay, @@ -68,6 +70,20 @@ class AhdEnvelope constexpr AhdEnvelope() noexcept = default; + inline void setParameters(const juce::AudioProcessorValueTreeState& apvts, + juce::String prefix) noexcept + { + juce::String base = prefix + "Env"; + params.enabled = + apvts.getRawParameterValue(base + "Enabled")->load() > 0.5f; + params.attack = apvts.getRawParameterValue(base + "Attack")->load(); + params.hold = apvts.getRawParameterValue(base + "Hold")->load(); + params.decay = apvts.getRawParameterValue(base + "Decay")->load(); + params.attackBend = apvts.getRawParameterValue(base + "AttackBend")->load(); + params.decayBend = apvts.getRawParameterValue(base + "DecayBend")->load(); + params.depth = apvts.getRawParameterValue(base + "Depth")->load(); + } + /** * @brief Set the envelope parameters. * @param _newParams The new parameters to set. @@ -77,6 +93,13 @@ class AhdEnvelope params = _newParams; } + /** + * @brief Get the Parameters object + * + * @return The current Parameters object + */ + inline Parameters getParameters() const noexcept { return params; } + /** * @brief Set the sample rate. * @param _newSampleRate The new sample rate to set. @@ -97,11 +120,13 @@ class AhdEnvelope */ [[nodiscard]] inline State getState() const noexcept { - if (sampleIndex < getHoldStart()) [[likely]] + if (!params.enabled) + return State::Disabled; + if (sampleIndex < getHoldStart()) return State::Attack; - if (sampleIndex < getDecayStart()) [[likely]] + if (sampleIndex < getDecayStart()) return State::Hold; - if (sampleIndex < getDecayEnd()) [[likely]] + if (sampleIndex < getDecayEnd()) return State::Decay; return State::Idle; } @@ -130,11 +155,13 @@ class AhdEnvelope constexpr float zero = 0.0f; switch (_state) { + case State::Disabled: + return 0.0f; case State::Attack: { const float normalizedPosition = static_cast(sampleIndex) / sampleRate; - const float skew = getSkew(State::Attack); - return std::pow(normalizedPosition / params.attack, skew); + const float phaseProgress = normalizedPosition / params.attack; + return applyAtanBend(phaseProgress, params.attackBend); } case State::Hold: return one; @@ -142,8 +169,8 @@ class AhdEnvelope const float decayStart = static_cast(getDecayStart()); const float normalizedPosition = (static_cast(sampleIndex) - decayStart) / sampleRate; - const float skew = getSkew(State::Decay); - return one - std::pow(normalizedPosition / params.decay, skew); + const float phaseProgress = normalizedPosition / params.decay; + return one - applyAtanBend(phaseProgress, params.decayBend); } default: return zero; @@ -151,20 +178,29 @@ class AhdEnvelope } /** - * @brief Get the skew value for the given state. - * @param _state The current state of the envelope. - * @return The skew value. + * @brief Apply atan-based bend to normalized phase in range [0, 1]. */ - [[nodiscard]] inline float getSkew(const State _state) const noexcept + [[nodiscard]] static inline float applyAtanBend(float normalizedPhase, + float bend) noexcept { - switch (_state) { - case State::Attack: - return dmt::math::linearToExponent(params.attackSkew); - case State::Decay: - return dmt::math::linearToExponent(-params.decaySkew); - default: - return 1.0f; - } + using juce::jlimit; + using std::atan, std::pow, std::abs; + + // We make the bend curve more exponential to make it feel linear + const float k = pow(0.5f * abs(bend), 2.0f); + const float x = jlimit(0.0f, 1.0f, normalizedPhase); + const float normalizer = atan(k); + + // No bend + if (k <= 0.01f) [[unlikely]] + return x; + + // Positive bend + if (bend > 0.0f) + return atan(k * x) / normalizer; + + // Negative bend + return 1.0f - (atan(k * (1.0f - x)) / normalizer); } /** diff --git a/dsp/synth/AnalogOscillator.h b/dsp/synth/AnalogOscillator.h deleted file mode 100644 index 6dc04b0b..00000000 --- a/dsp/synth/AnalogOscillator.h +++ /dev/null @@ -1,297 +0,0 @@ -//============================================================================== -/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— - * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• - * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• - * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ - * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• - * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) - * - * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. - * External use is permitted but not recommended. - * No support or compatibility guarantees are provided. - * - * License: - * This code is licensed under the GPLv3 license. You are permitted to use and - * modify this code under the terms of this license. - * You must adhere GPLv3 license for any project using this code or parts of it. - * Your are not allowed to use this code in any closed-source project. - * - * Description: - * High-performance analog oscillator for real-time audio synthesis. - * - * Authors: - * Lunix-420 (Primary Author) - */ -//============================================================================== - -#pragma once - -//============================================================================== - -#include "AnalogWaveform.h" -#include - -//============================================================================== - -namespace dmt { -namespace dsp { -namespace synth { - -//============================================================================== - -/** - * @class AnalogOscillator - * @brief High-performance analog oscillator for real-time audio synthesis. - * - * This class is designed for maximum real-time performance, using aggressive - * optimizations such as constexpr, inline, noexcept, and forceinline. It - * generates analog waveforms with various modulation capabilities. - */ -class alignas(64) AnalogOscillator -{ - using Math = juce::dsp::FastMathApproximations; - static constexpr float twoPi = juce::MathConstants::twoPi; - static constexpr float pi = juce::MathConstants::pi; - -public: - //============================================================================== - /** - * @brief Sets the sample rate for the oscillator. - * @param _newSampleRate The new sample rate in Hz. - */ - inline void setSampleRate(const float _newSampleRate) noexcept - { - TRACER("AnalogOscillator::setSampleRate"); - float rangeEnd = - std::nextafter(392000.0f, std::numeric_limits::max()); - const juce::Range validRange(20.0f, rangeEnd); - jassert(validRange.contains(_newSampleRate)); - sampleRate = _newSampleRate; - } - - //============================================================================== - /** - * @brief Generates the next sample of the waveform. - * @return The next sample value. - */ - [[nodiscard]] forcedinline float getNextSample() noexcept - { - TRACER("AnalogOscillator::getNextSample"); - if (sampleRate <= 0.0f) - return 0.0f; - - advancePhase(); - - auto syncedPhase = getSyncedPhase(phase * pwmModifier); - auto bendedPhase = getBendedPhase(syncedPhase); - - if (phase >= twoPi / pwmModifier) - return 0.0f; - - float sample = waveform.getSample(bendedPhase); - distortSample(sample); - return std::clamp(sample, -1.0f, +1.0f); - } - - //============================================================================== - /** - * @brief Sets the frequency of the oscillator. - * @param _newFrequency The new frequency in Hz. - */ - inline void setFrequency(const float _newFrequency) noexcept - { - TRACER("AnalogOscillator::setFrequency"); - frequency = _newFrequency; - } - - //============================================================================== - /** - * @brief Sets the waveform type of the oscillator. - * @param _type The new waveform type. - */ - inline void setWaveformType( - const dmt::dsp::synth::AnalogWaveform::Type _type) noexcept - { - TRACER("AnalogOscillator::setWaveformType"); - waveform.type = _type; - } - - //============================================================================== - /** - * @brief Sets the drive level for waveform distortion. - * @param _newDrive The new drive level. - */ - inline void setDrive(const float _newDrive) noexcept - { - TRACER("AnalogOscillator::setDrive"); - drive = _newDrive; - } - - //============================================================================== - /** - * @brief Sets the bias level for waveform distortion. - * @param _newBias The new bias level. - */ - inline void setBias(const float _newBias) noexcept - { - TRACER("AnalogOscillator::setBias"); - bias = _newBias; - } - - //============================================================================== - /** - * @brief Sets the initial phase of the oscillator. - * @param _newPhase The new phase value. - */ - inline void setPhase(const float _newPhase) noexcept - { - TRACER("AnalogOscillator::setPhase"); - phase = _newPhase; - } - - //============================================================================== - /** - * @brief Sets the bend modifier for waveform shaping. - * @param _newBendModifier The new bend modifier value. - */ - inline void setBend(const float _newBendModifier) noexcept - { - TRACER("AnalogOscillator::setBend"); - float rangeEnd = std::nextafter(100.0f, std::numeric_limits::max()); - const juce::NormalisableRange sourceRange(-100.0f, rangeEnd); - jassert(sourceRange.getRange().contains(_newBendModifier)); - const auto normalisedValue = sourceRange.convertTo0to1(_newBendModifier); - const juce::NormalisableRange targetRange(0.1f, 0.9f); - posityCycleRatio = targetRange.convertFrom0to1(normalisedValue); - } - - //============================================================================== - /** - * @brief Sets the PWM (Pulse Width Modulation) modifier. - * @param _newPwmModifier The new PWM modifier value. - */ - inline void setPwm(const float _newPwmModifier) noexcept - { - TRACER("AnalogOscillator::setPwm"); - float rangeEnd = std::nextafter(100.0f, std::numeric_limits::max()); - const juce::NormalisableRange sourceRange(0.0f, rangeEnd); - jassert(sourceRange.getRange().contains(_newPwmModifier)); - const auto normalisedValue = sourceRange.convertTo0to1(_newPwmModifier); - const juce::NormalisableRange targetRange(1.0f, 5.0f); - pwmModifier = targetRange.convertFrom0to1(normalisedValue); - } - - //============================================================================== - /** - * @brief Sets the sync modifier for phase synchronization. - * @param _newSyncModifier The new sync modifier value. - */ - inline void setSync(const float _newSyncModifier) noexcept - { - TRACER("AnalogOscillator::setSync"); - float rangeEnd = std::nextafter(100.0f, std::numeric_limits::max()); - const juce::NormalisableRange sourceRange(0.0f, rangeEnd); - jassert(sourceRange.getRange().contains(_newSyncModifier)); - const auto normalisedValue = sourceRange.convertTo0to1(_newSyncModifier); - const juce::NormalisableRange targetRange(1.0f, 5.0f); - syncModifier = targetRange.convertFrom0to1(normalisedValue); - } - -private: - dmt::dsp::synth::AnalogWaveform waveform; - float frequency = 50.0f; - float sampleRate = -1.0f; - float phase = 0.0f; - - float drive = 0.0f; - float bias = 0.0f; - float pwmModifier = 1.0f; - float syncModifier = 1.0f; - float posityCycleRatio = 0.5f; - - //============================================================================== - /** - * @brief Advances the phase of the oscillator. - */ - forcedinline void advancePhase() noexcept - { - TRACER("AnalogOscillator::advancePhase"); - float cycleLength = sampleRate / frequency; - float phaseDelta = twoPi / cycleLength; - phase += phaseDelta; - - if (phase >= twoPi) { - phase -= twoPi; - } - } - - //============================================================================== - /** - * @brief Computes the synced phase based on the raw phase and sync modifier. - * @param _rawPhase The raw phase value. - * @return The synced phase value. - */ - forcedinline float getSyncedPhase(float _rawPhase) const noexcept - { - TRACER("AnalogOscillator::getSyncedPhase"); - float syncedPhase = _rawPhase * syncModifier; - while (syncedPhase >= twoPi) { - syncedPhase -= twoPi; - } - return syncedPhase; - } - - //============================================================================== - /** - * @brief Computes the bended phase based on the raw phase and bend modifier. - * @param _rawPhase The raw phase value. - * @return The bended phase value. - */ - forcedinline float getBendedPhase(float _rawPhase) const noexcept - { - TRACER("AnalogOscillator::getBendedPhase"); - auto bendedPhase = _rawPhase; - - float positiveCycleSize = posityCycleRatio * twoPi; - float negativeCycleRatio = 1.0f - posityCycleRatio; - float negativeCycleSize = negativeCycleRatio * twoPi; - - if (_rawPhase <= positiveCycleSize) { - bendedPhase /= (posityCycleRatio * 2.0f); - } - - if (_rawPhase > positiveCycleSize) { - bendedPhase = (_rawPhase - positiveCycleSize) / negativeCycleSize; - bendedPhase = bendedPhase * pi + pi; - } - return bendedPhase; - } - - //============================================================================== - /** - * @brief Applies distortion to the sample based on the drive and bias - * settings. - * @param _sample The sample value to be distorted. - */ - forcedinline void distortSample(float& _sample) const noexcept - { - TRACER("AnalogOscillator::distortSample"); - constexpr float magicNumber = 0.7615941559558f; - if (drive >= 1.0f) { - _sample = Math::tanh(drive * _sample); - } else { - float invertedDrive = 1.0f - drive; - float wetSample = drive * Math::tanh(_sample); - float drySample = invertedDrive * _sample * magicNumber; - _sample = wetSample + drySample; - } - - _sample = _sample + bias; - } -}; - -//============================================================================== -} // namespace synth -} // namespace dsp -} // namespace dmt diff --git a/dsp/synth/DigitalOscillator.h b/dsp/synth/DigitalOscillator.h new file mode 100644 index 00000000..ee551dde --- /dev/null +++ b/dsp/synth/DigitalOscillator.h @@ -0,0 +1,356 @@ +//============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * High-performance digital oscillator for real-time audio synthesis. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== + +#pragma once + +//============================================================================== + +#include "dsp/synth/DigitalWaveform.h" +#include + +//============================================================================== + +namespace dmt { +namespace dsp { +namespace synth { +//============================================================================== + +/** + * @class DigitalOscillator + * @brief High-performance digital oscillator for real-time audio synthesis. + * + * This class is designed for maximum real-time performance, using aggressive + * optimizations such as constexpr, inline, noexcept, and forceinline. It + * generates digital waveforms with various modulation capabilities. + */ +class alignas(64) DigitalOscillator +{ + using Math = juce::dsp::FastMathApproximations; + using String = juce::String; + using DigitalWaveform = dmt::dsp::synth::DigitalWaveform; + + static constexpr float twoPi = juce::MathConstants::twoPi; + static constexpr float halfPi = juce::MathConstants::halfPi; + static constexpr float pi = juce::MathConstants::pi; + +public: + struct Parameters + { + public: + DigitalWaveform::Type type = DigitalWaveform::Type::Sine; + float bias = 0.0f; + float drive = 0.0f; + float pwm = 0.0f; + float clip = 0.0f; + float warp = 0.0f; + + private: + float sync = 0.0f; + float bend = 0.0f; + + public: + //============================================================================== + inline float getBend() const noexcept { return bend; } + inline void setBend(const float _newBend) noexcept + { + TRACER("DigitalOscillator::setBend"); + float rangeEnd = + std::nextafter(100.0f, std::numeric_limits::max()); + const juce::NormalisableRange sourceRange(-100.0f, rangeEnd); + jassert(sourceRange.getRange().contains(_newBend)); + const auto normalisedValue = sourceRange.convertTo0to1(_newBend); + const juce::NormalisableRange targetRange(0.1f, 0.9f); + bend = targetRange.convertFrom0to1(normalisedValue); + } + + //============================================================================== + inline float getSync() const noexcept { return sync; } + inline void setSync(const float _newSync) noexcept + { + TRACER("DigitalOscillator::setSync"); + float rangeEnd = + std::nextafter(100.0f, std::numeric_limits::max()); + const juce::NormalisableRange sourceRange(0.0f, rangeEnd); + jassert(sourceRange.getRange().contains(_newSync)); + const auto normalisedValue = sourceRange.convertTo0to1(_newSync); + const juce::NormalisableRange targetRange(1.0f, 5.0f); + sync = targetRange.convertFrom0to1(normalisedValue); + } + }; + + //============================================================================== + // Oscillator +public: + inline void setParameters(const juce::AudioProcessorValueTreeState& apvts, + String prefix) + { + auto type = params.type; + float warp = params.warp; + float bend = params.getBend(); + float pwm = params.pwm; + float sync = params.getSync(); + float bias = params.bias; + float clip = params.clip; + float drive = params.drive; + + String base = prefix + "DigitalOscillator"; + type = static_cast( + apvts.getRawParameterValue(base + "Type")->load()); + bend = apvts.getRawParameterValue(base + "Bend")->load(); + warp = apvts.getRawParameterValue(base + "Warp")->load(); + pwm = apvts.getRawParameterValue(base + "Pwm")->load(); + sync = apvts.getRawParameterValue(base + "Sync")->load(); + bias = apvts.getRawParameterValue(base + "Bias")->load(); + clip = apvts.getRawParameterValue(base + "Clip")->load(); + drive = apvts.getRawParameterValue(base + "Drive")->load(); + + // These don't need mapping so we can set them directly + waveform.type = type; + params.pwm = pwm; + params.bias = bias; + params.clip = clip; + params.drive = drive; + params.warp = warp; + + // These need mapping so we use setters to do that + params.setBend(bend); + params.setSync(sync); + + // Eagerly compute PWM end sample + computePwmEndSample(); + } + + //============================================================================== + /** + * @brief Sets the sample rate for the oscillator. + * @param _newSampleRate The new sample rate in Hz. + */ + inline void setSampleRate(const float _newSampleRate) noexcept + { + TRACER("DigitalOscillator::setSampleRate"); + sampleRate = _newSampleRate; + computePwmEndSample(); + } + + //============================================================================== + /** + * @brief Generates the next sample of the waveform. + * @return The next sample value. + */ + [[nodiscard]] forcedinline float getNextSample() noexcept + { + TRACER("DigitalOscillator::getNextSample"); + + using std::pow, std::clamp; + + if (sampleRate <= 0.0f) + return 0.0f; + + advancePhase(); + + auto warpedPhase = getWarpPhase(phase); + auto syncedPhase = getSyncedPhase(warpedPhase); + auto bendedPhase = getBendedPhase(syncedPhase); + + auto pwmPhase = bendedPhase; + auto pwm = params.pwm; + const float pwmNormalized = 1.0f - (pwm / 100.0f); // 0.8 + + if (pwmPhase >= twoPi * pwmNormalized) { + return pwmEndSample; + } + + if (pwmNormalized > 0.0f || pwmNormalized < 1.0f) { + pwmPhase = clamp(pwmPhase / pwmNormalized, 0.0f, twoPi); + } + + float sample = waveform.getSample(pwmPhase); + sample = distortSample(sample); + return clamp(sample, -1.0f, +1.0f); + } + + //============================================================================== + // Experimental phase warp function + float getWarpPhase(float _phase) const noexcept + { + const float k = params.warp; + const float normalizedPhase = _phase / pi; // Normalize phase to [0, 2] + + auto b = [k](float x) { return (1.0 + 2.0 * k) * x; }; + auto c = [k](float x) { return (1.0 - 2.0 * k) * x + 2.0 * k; }; + auto d = [k](float x) { return (1.0 + 2.0 * k) * x - 4.0 * k; }; + + if (normalizedPhase < 0.5) { + return b(normalizedPhase) * pi; + } + + if (normalizedPhase < 1.5) { + return c(normalizedPhase) * pi; + } + + return d(normalizedPhase) * pi; + } + + //============================================================================== + void reset() noexcept + { + TRACER("DigitalOscillator::reset"); + phase = 0.0f; + computePwmEndSample(); + } + + //============================================================================== + /** + * @brief Sets the frequency of the oscillator. + * @param _newFrequency The new frequency in Hz. + */ + inline void setFrequency(const float _newFrequency) noexcept + { + TRACER("DigitalOscillator::setFrequency"); + frequency = _newFrequency; + } + + //============================================================================== + /** + * @brief Advances the phase of the oscillator. + */ + forcedinline void advancePhase() noexcept + { + TRACER("DigitalOscillator::advancePhase"); + float cycleLength = sampleRate / frequency; + float phaseDelta = twoPi / cycleLength; + phase += phaseDelta; + + if (phase >= twoPi) { + phase -= twoPi; + } + } + + //============================================================================== + /** + * @brief Computes the synced phase based on the raw phase and sync modifier. + * @param _rawPhase The raw phase value. + * @return The synced phase value. + */ + forcedinline float getSyncedPhase(float _rawPhase) const noexcept + { + TRACER("DigitalOscillator::getSyncedPhase"); + float syncedPhase = _rawPhase * params.getSync(); + while (syncedPhase >= twoPi) { + syncedPhase -= twoPi; + } + return syncedPhase; + } + + //============================================================================== + /** + * @brief Computes the bended phase based on the raw phase and bend modifier. + * @param _rawPhase The raw phase value. + * @return The bended phase value. + */ + forcedinline float getBendedPhase(float _rawPhase) const noexcept + { + TRACER("DigitalOscillator::getBendedPhase"); + auto bendedPhase = _rawPhase; + + const float bend = params.getBend(); + float positiveCycleSize = bend * twoPi; + float negativeCycleRatio = 1.0f - bend; + float negativeCycleSize = negativeCycleRatio * twoPi; + + if (_rawPhase <= positiveCycleSize) { + bendedPhase /= (bend * 2.0f); + } + + if (_rawPhase > positiveCycleSize) { + bendedPhase = (_rawPhase - positiveCycleSize) / negativeCycleSize; + bendedPhase = bendedPhase * pi + pi; + } + return bendedPhase; + } + + //============================================================================== + /** + * @brief Applies distortion to the sample based on the drive and bias + * settings. + * @param _sample The sample value to be distorted. + */ + forcedinline float distortSample(float _sample) const noexcept + { + TRACER("DigitalOscillator::distortSample"); + + using std::clamp, std::abs, std::atan, std::tan; + + float drive = params.drive; + float bias = params.bias; + float clip = params.clip + 1.0f; + float k = abs(drive); + + float biasSample = _sample + bias; + float clipSample = clamp(biasSample * clip, -1.0f, 1.0f); + + if (k < 0.01f) + return clipSample; + + if (drive > 0.0f) { + float normalizer = atan(k); + return atan(k * clipSample) / normalizer; + } else { + float normalizer = atan(k * 0.2f); + return tan(clipSample * normalizer) / (k * 0.2f); + } + } + +private: + //============================================================================== + /** + * @brief Computes the PWM end-of-cycle sample. + */ + void computePwmEndSample() noexcept + { + TRACER("DigitalOscillator::computePwmEndSample"); + + // We sample the waveform at 2Ο€ to get it's last sample and use it as PWM + // fill + float endPhase = getBendedPhase(getSyncedPhase(twoPi)); + pwmEndSample = waveform.getSample(endPhase); + distortSample(pwmEndSample); + pwmEndSample = std::clamp(pwmEndSample, -1.0f, +1.0f); + } + + //============================================================================== + DigitalWaveform waveform; + Parameters params; + float frequency = 50.0f; + float sampleRate = -1.0f; + float phase = 0.0f; + float pwmEndSample = 0.0f; + //============================================================================== +}; +} // namespace synth +} // namespace dsp +} // namespace dmt diff --git a/dsp/synth/AnalogWaveform.h b/dsp/synth/DigitalWaveform.h similarity index 95% rename from dsp/synth/AnalogWaveform.h rename to dsp/synth/DigitalWaveform.h index a590cc4d..c3408776 100644 --- a/dsp/synth/AnalogWaveform.h +++ b/dsp/synth/DigitalWaveform.h @@ -1,153 +1,153 @@ -//============================================================================== -/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— - * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• - * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• - * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ - * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• - * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) - * - * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. - * External use is permitted but not recommended. - * No support or compatibility guarantees are provided. - * - * License: - * This code is licensed under the GPLv3 license. You are permitted to use and - * modify this code under the terms of this license. - * You must adhere GPLv3 license for any project using this code or parts of it. - * Your are not allowed to use this code in any closed-source project. - * - * Description: - * Get the options for the properties file with predefined settings. - * - * Authors: - * Lunix-420 (Primary Author) - */ -//============================================================================== - -#pragma once - -//============================================================================== - -#include - -//============================================================================== - -namespace dmt { -namespace dsp { -namespace synth { - -//============================================================================== -/** - * @brief Represents different types of analog waveforms. - */ -struct AnalogWaveform -{ - static constexpr float twoPi = juce::MathConstants::twoPi; - static constexpr float pi = juce::MathConstants::pi; - - //============================================================================== - /** - * @brief Enumeration of waveform types. - */ - enum class Type - { - Sine, - Saw, - Triangle, - Square - }; - - static const inline juce::StringArray waveformNames = { "Sine", - "Saw", - "Triangle", - "Square" }; - - //============================================================================== - - Type type = Type::Sine; - - //============================================================================== - /** - * @brief Generate a triangle waveform sample. - * @param _x The phase of the waveform. - * @return The waveform sample. - */ - inline float triangle(float _x) const noexcept - { - while (_x > twoPi) - _x -= twoPi; - float result = 2.0f * (_x / twoPi - 0.5f); - if (result > 0.5f) - result = 1.0f - result; - if (result < -0.5f) - result = -1.0f - result; - return 2 * result; - } - - //============================================================================== - /** - * @brief Generate a saw waveform sample. - * @param _x The phase of the waveform. - * @return The waveform sample. - */ - inline float saw(float _x) const noexcept - { - while (_x > twoPi) - _x -= twoPi; - return 2.0f * (_x / twoPi - 0.5f); - } - - //============================================================================== - /** - * @brief Generate a sine waveform sample. - * @param _x The phase of the waveform. - * @return The waveform sample. - */ - inline float sine(float _x) const noexcept { return std::sin(_x); } - - //============================================================================== - /** - * @brief Generate a square waveform sample. - * @param _x The phase of the waveform. - * @return The waveform sample. - */ - inline float square(float _x) const noexcept - { - return (sine(_x) > 0.0f) ? 1.0f : -1.0f; - } - - //============================================================================== - /** - * @brief Get the waveform sample based on the current type. - * @param _x The phase of the waveform. - * @return The waveform sample. - */ - [[nodiscard]] inline float getSample(float _x) const noexcept - { - switch (type) { - case Type::Sine: - return sine(_x); - case Type::Saw: - return saw(_x); - case Type::Triangle: - return triangle(_x); - case Type::Square: - return square(_x); - default: - // impossible to reach this point, exit with assertion - jassert(false); - return 0.0f; - } - } - - //============================================================================== -}; - -//============================================================================== - -} // namespace synth -} // namespace dsp -} // namespace dmt - -//============================================================================== +//============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * Get the options for the properties file with predefined settings. + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== + +#pragma once + +//============================================================================== + +#include + +//============================================================================== + +namespace dmt { +namespace dsp { +namespace synth { + +//============================================================================== +/** + * @brief Represents different types of digital waveforms. + */ +struct DigitalWaveform +{ + static constexpr float twoPi = juce::MathConstants::twoPi; + static constexpr float pi = juce::MathConstants::pi; + + //============================================================================== + /** + * @brief Enumeration of waveform types. + */ + enum class Type + { + Sine, + Saw, + Triangle, + Square + }; + + static const inline juce::StringArray waveformNames = { "Sine", + "Saw", + "Triangle", + "Square" }; + + //============================================================================== + + Type type = Type::Sine; + + //============================================================================== + /** + * @brief Generate a triangle waveform sample. + * @param _x The phase of the waveform. + * @return The waveform sample. + */ + inline float triangle(float _x) const noexcept + { + while (_x > twoPi) + _x -= twoPi; + float result = 2.0f * (_x / twoPi - 0.5f); + if (result > 0.5f) + result = 1.0f - result; + if (result < -0.5f) + result = -1.0f - result; + return 2 * result; + } + + //============================================================================== + /** + * @brief Generate a saw waveform sample. + * @param _x The phase of the waveform. + * @return The waveform sample. + */ + inline float saw(float _x) const noexcept + { + while (_x > twoPi) + _x -= twoPi; + return 2.0f * (_x / twoPi - 0.5f); + } + + //============================================================================== + /** + * @brief Generate a sine waveform sample. + * @param _x The phase of the waveform. + * @return The waveform sample. + */ + inline float sine(float _x) const noexcept { return std::sin(_x); } + + //============================================================================== + /** + * @brief Generate a square waveform sample. + * @param _x The phase of the waveform. + * @return The waveform sample. + */ + inline float square(float _x) const noexcept + { + return (sine(_x) > 0.0f) ? 1.0f : -1.0f; + } + + //============================================================================== + /** + * @brief Get the waveform sample based on the current type. + * @param _x The phase of the waveform. + * @return The waveform sample. + */ + [[nodiscard]] inline float getSample(float _x) const noexcept + { + switch (type) { + case Type::Sine: + return sine(_x); + case Type::Saw: + return saw(_x); + case Type::Triangle: + return triangle(_x); + case Type::Square: + return square(_x); + default: + // impossible to reach this point, exit with assertion + jassert(false); + return 0.0f; + } + } + + //============================================================================== +}; + +//============================================================================== + +} // namespace synth +} // namespace dsp +} // namespace dmt + +//============================================================================== diff --git a/dsp/synth/SynthVoice.h b/dsp/synth/NeutrinoSynthVoice.h similarity index 69% rename from dsp/synth/SynthVoice.h rename to dsp/synth/NeutrinoSynthVoice.h index 0be08335..d93cc742 100644 --- a/dsp/synth/SynthVoice.h +++ b/dsp/synth/NeutrinoSynthVoice.h @@ -1,324 +1,317 @@ -//============================================================================== -/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— - * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• - * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• - * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ - * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• - * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) - * - * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. - * External use is permitted but not recommended. - * No support or compatibility guarantees are provided. - * - * License: - * This code is licensed under the GPLv3 license. You are permitted to use and - * modify this code under the terms of this license. - * You must adhere GPLv3 license for any project using this code or parts of it. - * Your are not allowed to use this code in any closed-source project. - * - * Description: - * Get the options for the properties file with predefined settings. - * - * Authors: - * Lunix-420 (Primary Author) - */ -//============================================================================== - -#pragma once - -//============================================================================== - -#include "dsp/envelope/AdhEnvelope.h" -#include "dsp/synth/AnalogOscillator.h" -#include - -//============================================================================== - -namespace dmt { -namespace dsp { -namespace synth { - -//============================================================================== - -/** - * @class SynthVoice - * @brief A class representing a synthesizer voice. - */ -class alignas(64) SynthVoice : public juce::SynthesiserVoice -{ -public: - //============================================================================== - /** - * @brief Constructor for SynthVoice. - * @param _apvts Reference to the AudioProcessorValueTreeState. - */ - SynthVoice(juce::AudioProcessorValueTreeState& _apvts) noexcept - : apvts(_apvts) - { - TRACER("SynthVoice::SynthVoice"); - } - - //============================================================================== - /** - * @brief Determines if the voice can play a given sound. - * @param _sound Pointer to the SynthesiserSound. - * @return True if the sound can be played, false otherwise. - */ - bool canPlaySound(juce::SynthesiserSound* _sound) override - { - TRACER("SynthVoice::canPlaySound"); - return dynamic_cast(_sound) != nullptr; - } - - //============================================================================== - /** - * @brief Handles the event when a controller is moved. - * - * This function is called when a controller is moved, providing the - * controller number and the new value of the controller. It is intended to be - * overridden by derived classes to implement specific behavior for controller - * movements. - * - * @param controllerNumber The number of the controller that was moved. - * @param newControllerValue The new value of the controller. - */ - void controllerMoved(int /*controllerNumber*/, - int /*newControllerValue*/) noexcept override - { - TRACER("SynthVoice::controllerMoved"); - } - - //============================================================================== - /** - * @brief Handles the event when the pitch wheel is moved. - * - * This function is called whenever the pitch wheel is moved. The new pitch - * wheel value is passed as an argument, but it is currently unused. - * - * @param newPitchWheelValue The new value of the pitch wheel. - */ - void pitchWheelMoved(int /*newPitchWheelValue*/) noexcept override - { - TRACER("SynthVoice::pitchWheelMoved"); - } - - //============================================================================== - /** - * @brief Prepares the voice to play. - * @param _sampleRate The sample rate. - * @param _samplesPerBlock Number of samples per block. - * @param _outputChannels Number of output channels. - */ - void prepareToPlay(double _sampleRate, - int /*_samplesPerBlock*/, - int /*_outputChannels*/) noexcept - { - TRACER("SynthVoice::prepareToPlay"); - if (_sampleRate <= 0) - return; - - gainEnvelope.setSampleRate(static_cast(_sampleRate)); - pitchEnvelope.setSampleRate(static_cast(_sampleRate)); - osc.setSampleRate(static_cast(_sampleRate)); - - isPrepared = true; - } - - //============================================================================== - /** - * @brief Starts a note. - * @param _midiNoteNumber The MIDI note number. - * @param _velocity The velocity of the note. - * @param _sound Pointer to the SynthesiserSound. - * @param _currentPitchWheelPosition The current pitch wheel position. - */ - void startNote(int _midiNoteNumber, - float /*_velocity*/, - juce::SynthesiserSound* /*_sound*/, - int /*_currentPitchWheelPosition*/) noexcept override - { - TRACER("SynthVoice::startNote"); - osc.setPhase(0.0f); - note = _midiNoteNumber; - - updateEnvelopeParameters(); - gainEnvelope.noteOn(); - pitchEnvelope.noteOn(); - - callOnNoteReceivers(); - } - - //============================================================================== - void stopNote(float /*_velocity*/, bool /*_allowTailOff*/) noexcept override - { - TRACER("SynthVoice::stopNote"); - } - - /** - * @brief Renders the next block of audio. - * @param _outputBuffer The output buffer. - * @param _startSample The start sample index. - * @param _numSamples The number of samples to render. - */ - void renderNextBlock(juce::AudioBuffer& _outputBuffer, - int _startSample, - int _numSamples) noexcept override - { - TRACER("SynthVoice::renderNextBlock"); - if (!isVoiceActive() || !isPrepared) - return; - - updateEnvelopeParameters(); - updateOscillatorParameters(); - - const float oscGain = - apvts.getRawParameterValue("osc1DistortionPreGain")->load(); - const int oscOctave = apvts.getRawParameterValue("osc1VoiceOctave")->load(); - const int oscSemitone = - apvts.getRawParameterValue("osc1VoiceSemitone")->load(); - const float oscModDepth = - apvts.getRawParameterValue("osc1PitchEnvDepth")->load(); - - const auto endSample = _numSamples + _startSample; - auto* leftChannel = _outputBuffer.getWritePointer(0); - auto* rightChannel = _outputBuffer.getWritePointer(1); - - for (int sample = _startSample; sample < endSample; ++sample) { - osc.setFrequency(getNextFrequency(oscOctave, oscSemitone, oscModDepth)); - const auto rawSample = osc.getNextSample(); - const auto gainedSample = applyGain(rawSample, oscGain); - leftChannel[sample] = gainedSample; - rightChannel[sample] = gainedSample; - } - } - - //============================================================================== - /** - * @brief Adds a callback function to be called when a note is received. - * @param _callbackFunction The callback function. - */ - void addOnNoteReceivers(std::function _callbackFunction) noexcept - { - TRACER("SynthVoice::addOnNoteReceivers"); - onNoteReceivers.push_back(std::move(_callbackFunction)); - } - - //============================================================================== - /** - * @brief Calls all registered note receiver callback functions. - */ - void callOnNoteReceivers() noexcept - { - TRACER("SynthVoice::callOnNoteReceivers"); - for (const auto& func : onNoteReceivers) { - func(); - } - } - -protected: - //============================================================================== - /** - * @brief Updates the envelope parameters from the - * AudioProcessorValueTreeState. - */ - void updateEnvelopeParameters() noexcept - { - TRACER("SynthVoice::updateEnvelopeParameters"); - dmt::dsp::envelope::AhdEnvelope::Parameters gainEnvParameters; - gainEnvParameters.attack = - apvts.getRawParameterValue("osc1GainEnvAttack")->load(); - gainEnvParameters.hold = - apvts.getRawParameterValue("osc1GainEnvHold")->load(); - gainEnvParameters.decay = - apvts.getRawParameterValue("osc1GainEnvDecay")->load(); - gainEnvParameters.decaySkew = - apvts.getRawParameterValue("osc1GainEnvSkew")->load(); - gainEnvParameters.attackSkew = 0; - gainEnvelope.setParameters(gainEnvParameters); - - dmt::dsp::envelope::AhdEnvelope::Parameters pitchEnvParameters; - pitchEnvParameters.attack = 0; - pitchEnvParameters.hold = - apvts.getRawParameterValue("osc1PitchEnvHold")->load(); - pitchEnvParameters.decay = - apvts.getRawParameterValue("osc1PitchEnvDecay")->load(); - pitchEnvParameters.decaySkew = - apvts.getRawParameterValue("osc1PitchEnvSkew")->load(); - pitchEnvParameters.attackSkew = 0; - pitchEnvelope.setParameters(pitchEnvParameters); - } - - //============================================================================== - /** - * @brief Updates the oscillator parameters from the - * AudioProcessorValueTreeState. - */ - void updateOscillatorParameters() noexcept - { - TRACER("SynthVoice::updateOscillatorParameters"); - osc.setWaveformType(static_cast( - apvts.getRawParameterValue("osc1WaveformType")->load())); - osc.setDrive(apvts.getRawParameterValue("osc1DistortionType")->load()); - osc.setBias(apvts.getRawParameterValue("osc1DistortionSymmetry")->load()); - osc.setBend(apvts.getRawParameterValue("osc1WaveformBend")->load()); - osc.setPwm(apvts.getRawParameterValue("osc1WaveformPwm")->load()); - osc.setSync(apvts.getRawParameterValue("osc1WaveformSync")->load()); - } - - //============================================================================== - /** - * @brief Calculates the next frequency for the oscillator. - * @param _rawOctave The raw octave value. - * @param _rawSemitone The raw semitone value. - * @param _rawModDepth The raw modulation depth. - * @return The next frequency. - */ - [[nodiscard]] float getNextFrequency(const int _rawOctave, - const int _rawSemitone, - const float _rawModDepth) noexcept - { - TRACER("SynthVoice::getNextFrequency"); - const int octaves = 12 * _rawOctave; - const int semitone = octaves + _rawSemitone; - const int baseNote = note + semitone; - const float baseFreq = juce::MidiMessage::getMidiNoteInHertz(baseNote); - const float modDepth = _rawModDepth * 2e4f; - const float envelopeSample = pitchEnvelope.getNextSample(); - const float maxFreq = std::clamp(baseFreq + modDepth, baseFreq, 2e4f); - const float newFreq = juce::mapToLog10(envelopeSample, baseFreq, maxFreq); - return std::clamp(newFreq, 20.0f, 2e4f); - } - - //============================================================================== - /** - * @brief Applies gain to a sample. - * @param _sample The input sample. - * @param _oscGain The oscillator gain. - * @return The gained sample. - */ - [[nodiscard]] float applyGain(float _sample, float _oscGain) noexcept - { - TRACER("SynthVoice::applyGain"); - const float envGain = gainEnvelope.getNextSample(); - const float gain = juce::Decibels::decibelsToGain(_oscGain, -96.0f); - return _sample * envGain * gain; - } - -private: - juce::AudioProcessorValueTreeState& apvts; - dmt::dsp::synth::AnalogOscillator osc; - dmt::dsp::envelope::AhdEnvelope gainEnvelope; - dmt::dsp::envelope::AhdEnvelope pitchEnvelope; - int note = 0; - bool isPrepared = false; - std::vector> onNoteReceivers; -}; - -//============================================================================== - -} // namespace synth -} // namespace dsp -} // namespace dmt - -//============================================================================== +//============================================================================== +/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— + * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• + * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ + * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• + * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) + * + * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. + * External use is permitted but not recommended. + * No support or compatibility guarantees are provided. + * + * License: + * This code is licensed under the GPLv3 license. You are permitted to use and + * modify this code under the terms of this license. + * You must adhere GPLv3 license for any project using this code or parts of it. + * Your are not allowed to use this code in any closed-source project. + * + * Description: + * + * + * Authors: + * Lunix-420 (Primary Author) + */ +//============================================================================== + +#pragma once + +//============================================================================== + +#include "dsp/envelope/AdhEnvelope.h" +#include "dsp/synth/DigitalOscillator.h" +#include + +//============================================================================== + +namespace dmt { +namespace dsp { +namespace synth { + +//============================================================================== + +class alignas(64) NeutrinoSynthVoice : public juce::SynthesiserVoice +{ + using DigitalOscillator = dmt::dsp::synth::DigitalOscillator; + using DigitalWaveform = dmt::dsp::synth::DigitalWaveform; + using AhdEnvelope = dmt::dsp::envelope::AhdEnvelope; + +public: + //============================================================================== + /** + * @brief Constructor for SynthVoice. + * @param _apvts Reference to the AudioProcessorValueTreeState. + */ + NeutrinoSynthVoice(juce::AudioProcessorValueTreeState& _apvts) noexcept + : apvts(_apvts) + { + TRACER("NeutrinoSynthVoice::NeutrinoSynthVoice"); + } + + //============================================================================== + /** + * @brief Determines if the voice can play a given sound. + * @param _sound Pointer to the SynthesiserSound. + * @return True if the sound can be played, false otherwise. + */ + bool canPlaySound(juce::SynthesiserSound* _sound) override + { + TRACER("NeutrinoSynthVoice::canPlaySound"); + return dynamic_cast(_sound) != nullptr; + } + + //============================================================================== + /** + * @brief Handles the event when a controller is moved. + * + * This function is called when a controller is moved, providing the + * controller number and the new value of the controller. It is intended to be + * overridden by derived classes to implement specific behavior for controller + * movements. + * + * @param controllerNumber The number of the controller that was moved. + * @param newControllerValue The new value of the controller. + */ + void controllerMoved(int /*controllerNumber*/, + int /*newControllerValue*/) noexcept override + { + TRACER("NeutrinoSynthVoice::controllerMoved"); + } + + //============================================================================== + /** + * @brief Handles the event when the pitch wheel is moved. + * + * This function is called whenever the pitch wheel is moved. The new pitch + * wheel value is passed as an argument, but it is currently unused. + * + * @param newPitchWheelValue The new value of the pitch wheel. + */ + void pitchWheelMoved(int /*newPitchWheelValue*/) noexcept override + { + TRACER("NeutrinoSynthVoice::pitchWheelMoved"); + } + + //============================================================================== + /** + * @brief Prepares the voice to play. + * @param _sampleRate The sample rate. + * @param _samplesPerBlock Number of samples per block. + * @param _outputChannels Number of output channels. + */ + void prepareToPlay(double _sampleRate, + int /*_samplesPerBlock*/, + int /*_outputChannels*/) noexcept + { + TRACER("NeutrinoSynthVoice::prepareToPlay"); + if (_sampleRate <= 0) + return; + + gainEnvelope.setSampleRate(static_cast(_sampleRate)); + pitchEnv1.setSampleRate(static_cast(_sampleRate)); + pitchEnv2.setSampleRate(static_cast(_sampleRate)); + osc.setSampleRate(static_cast(_sampleRate)); + + isPrepared = true; + } + + //============================================================================== + /** + * @brief Starts a note. + * @param _midiNoteNumber The MIDI note number. + * @param _velocity The velocity of the note. + * @param _sound Pointer to the SynthesiserSound. + * @param _currentPitchWheelPosition The current pitch wheel position. + */ + void startNote(int _midiNoteNumber, + float /*_velocity*/, + juce::SynthesiserSound* /*_sound*/, + int /*_currentPitchWheelPosition*/) noexcept override + { + TRACER("NeutrinoSynthVoice::startNote"); + + note = _midiNoteNumber; + + updateEnvelopeParameters(); + gainEnvelope.noteOn(); + pitchEnv1.noteOn(); + pitchEnv2.noteOn(); + osc.reset(); + + callOnNoteReceivers(); + } + + //============================================================================== + void stopNote(float /*_velocity*/, bool /*_allowTailOff*/) noexcept override + { + TRACER("NeutrinoSynthVoice::stopNote"); + // clearCurrentNote(); + } + + /** + * @brief Renders the next block of audio. + * @param _outputBuffer The output buffer. + * @param _startSample The start sample index. + * @param _numSamples The number of samples to render. + */ + void renderNextBlock(juce::AudioBuffer& _outputBuffer, + int _startSample, + int _numSamples) noexcept override + { + TRACER("NeutrinoSynthVoice::renderNextBlock"); + if (!isVoiceActive() || !isPrepared) + return; + + updateEnvelopeParameters(); + updateOscillatorParameters(); + + const float oscGain = 0.0f; + + const auto endSample = _numSamples + _startSample; + auto* leftChannel = _outputBuffer.getWritePointer(0); + auto* rightChannel = _outputBuffer.getWritePointer(1); + + for (int sample = _startSample; sample < endSample; ++sample) { + const float freq = getNextFrequency(); + osc.setFrequency(freq); + + float rawSample = osc.getNextSample(); + + const auto gainedSample = applyGain(rawSample, oscGain); + leftChannel[sample] += gainedSample; + rightChannel[sample] += gainedSample; + } + } + + //============================================================================== + /** + * @brief Calculates the next frequency for the oscillator. + * @param _rawOctave The raw octave value. + * @param _rawSemitone The raw semitone value. + * @param _rawModDepth The raw modulation depth. + * @return The next frequency. + */ + [[nodiscard]] float getNextFrequency() noexcept + { + TRACER("SynthVoice::getNextFrequency"); + using juce::mapToLog10, juce::MidiMessage; + using std::clamp; + + const int octave = -1; + const int semitone = 0; + const float minFreq = 20.0f; + const float maxFreq = 20000.0f; + const int baseNote = (note + semitone + (octave * 12)); + const float baseFreq = MidiMessage::getMidiNoteInHertz(baseNote); + + // How far the envelope should modulate, in 0.0f to 1.0f representing 0% to + // 100% of the frequency range. + const float oscModDepth1 = pitchEnv1.getParameters().depth; + const float oscModDepth2 = pitchEnv2.getParameters().depth; + + // These are 0.0f to +1.0f of the envelope value + const float osc1Sample = pitchEnv1.getNextSample(); + const float osc2Sample = pitchEnv2.getNextSample(); + + const float osc1ModSample = + mapToLog10(osc1Sample * oscModDepth1, minFreq, maxFreq); + + const float osc2ModSample = + mapToLog10(osc2Sample * oscModDepth2, minFreq, maxFreq); + + const float modulatedFreq = baseFreq + osc1ModSample + osc2ModSample; + return clamp(modulatedFreq, minFreq, maxFreq); + } + + //============================================================================== + /** + * @brief Adds a callback function to be called when a note is received. + * @param _callbackFunction The callback function. + */ + void addOnNoteReceivers(std::function _callbackFunction) noexcept + { + TRACER("SynthVoice::addOnNoteReceivers"); + onNoteReceivers.push_back(std::move(_callbackFunction)); + } + + //============================================================================== + /** + * @brief Calls all registered note receiver callback functions. + */ + void callOnNoteReceivers() noexcept + { + TRACER("SynthVoice::callOnNoteReceivers"); + for (const auto& func : onNoteReceivers) { + func(); + } + } + +protected: + //============================================================================== + /** + * @brief Updates the envelope parameters from the + * AudioProcessorValueTreeState. + */ + void updateEnvelopeParameters() noexcept + { + TRACER("SynthVoice::updateEnvelopeParameters"); + gainEnvelope.setParameters(apvts, "NeutrinoGain"); + pitchEnv1.setParameters(apvts, "NeutrinoPitch1"); + pitchEnv2.setParameters(apvts, "NeutrinoPitch2"); + } + + //============================================================================== + /** + * @brief Updates the oscillator parameters from the + * AudioProcessorValueTreeState. + */ + void updateOscillatorParameters() noexcept + { + TRACER("SynthVoice::updateOscillatorParameters"); + osc.setParameters(apvts, "Neutrino"); + } + + //============================================================================== + /** + * @brief Applies gain to a sample. + * @param _sample The input sample. + * @param _oscGain The oscillator gain. + * @return The gained sample. + */ + [[nodiscard]] float applyGain(float _sample, float _oscGain) noexcept + { + TRACER("SynthVoice::applyGain"); + const float envGain = gainEnvelope.getNextSample(); + const float gain = juce::Decibels::decibelsToGain(_oscGain, -96.0f); + return _sample * envGain * gain; + } + +private: + juce::AudioProcessorValueTreeState& apvts; + DigitalOscillator osc; + AhdEnvelope gainEnvelope; + AhdEnvelope pitchEnv1; + AhdEnvelope pitchEnv2; + int note = 0; + bool isPrepared = false; + std::vector> onNoteReceivers; +}; + +//============================================================================== + +} // namespace synth +} // namespace dsp +} // namespace dmt + +//============================================================================== diff --git a/dsp/synth/Synth.h b/dsp/synth/Synth.h index 54b42c87..cb03414d 100644 --- a/dsp/synth/Synth.h +++ b/dsp/synth/Synth.h @@ -29,9 +29,9 @@ //============================================================================== -#include "./AnalogOscillator.h" -#include "./AnalogWaveform.h" +#include "./DigitalOscillator.h" +#include "./DigitalWaveform.h" +#include "./NeutrinoSynthVoice.h" #include "./SynthSound.h" -#include "./SynthVoice.h" //============================================================================== \ No newline at end of file diff --git a/gui/component/OscillatorDisplayComponent.h b/gui/component/OscillatorDisplayComponent.h index 5bc25d84..b0ae96b2 100644 --- a/gui/component/OscillatorDisplayComponent.h +++ b/gui/component/OscillatorDisplayComponent.h @@ -1,159 +1,162 @@ -//============================================================================== -/* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— - * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• - * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• - * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• - * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ - * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• - * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) - * - * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. - * External use is permitted but not recommended. - * No support or compatibility guarantees are provided. - * - * License: - * This code is licensed under the GPLv3 license. You are permitted to use and - * modify this code under the terms of this license. - * You must adhere GPLv3 license for any project using this code or parts of it. - * Your are not allowed to use this code in any closed-source project. - * - * Description: - * OscillatorDisplayComponent provides a real-time visualization of an - * oscillator's waveform. It uses a lookup table to efficiently render the - * waveform based on the current oscillator parameters. The component supports - * customizable shadows for enhanced visual appeal and is designed to be - * responsive to parameter changes, updating the display accordingly. - * - * Authors: - * Lunix-420 (Primary Author) - */ -//============================================================================== - -#pragma once - -//============================================================================== - -#include "dsp/synth/AnalogOscillator.h" -#include "gui/widget/Shadow.h" -#include "utility/Settings.h" -#include - -//============================================================================== -namespace dmt { -namespace gui { -namespace component { -//============================================================================== -// TODO: Make this use the new display system -class OscillatorDisplayComponent - : public juce::Component - , public juce::Timer - , public dmt::Scaleable -{ - using Shadow = dmt::gui::widget::Shadow; - using AnalogOscillator = dmt::dsp::synth::AnalogOscillator; - - //============================================================================ - // General - using Settings = dmt::Settings::OscillatorDisplay; - const int& fps = dmt::Settings::framerate; - const int& resolution = Settings::resolution; - - // Shadows - const bool& drawOuterShadow = Settings::drawOuterShadow; - const bool& drawInnerShadow = Settings::drawInnerShadow; - const juce::Colour& outerShadowColour = Settings::outerShadowColour; - const juce::Colour& innerShadowColour = Settings::innerShadowColour; - const float& outerShadowRadius = Settings::outerShadowRadius; - const float& innerShadowRadius = Settings::innerShadowRadius; - -public: - //============================================================================ - OscillatorDisplayComponent(juce::AudioProcessorValueTreeState& apvts) - : apvts(apvts) - { - TRACER("OscillatorDisplayComponent::OscillatorDisplayComponent"); - osc.setSampleRate((float)resolution + 1.0f); - osc.setFrequency(1.0f); - startTimerHz(60); - } - //============================================================================ - void paint(juce::Graphics& g) override - { - TRACER("OscillatorDisplayComponent::paint"); - const auto bounds = this->getLocalBounds().toFloat(); - } - -protected: - //============================================================================== - void timerCallback() - { - TRACER("OscillatorDisplayComponent::timerCallback"); - if (isParametersChanged()) { - this->buildTable(); - this->repaint(); - } - } - - void buildTable() - { - TRACER("OscillatorDisplayComponent::buildTable"); - osc.setPhase(0.0f); - table.initialise( - [&](std::size_t index) { return (float)osc.getNextSample(); }, - resolution); - } - - bool isParametersChanged() - { - TRACER("OscillatorDisplayComponent::isParametersChanged"); - } - - //============================================================================== - juce::Path getPath(juce::Rectangle bounds) - { - TRACER("OscillatorDisplayComponent::getPath"); - bounds.setY(bounds.getY() + (bounds.getHeight() / 10.0f)); - bounds.setHeight(bounds.getHeight() - (bounds.getHeight() / 5.0f)); - - auto outerBounds = bounds; - bounds = bounds.reduced(bounds.getWidth() / 6.0f); - - juce::Path path; - - auto startX = bounds.getX(); - auto startY = bounds.getY() + (bounds.getHeight() / 2.0f); - juce::Point start(startX, startY); - path.startNewSubPath(start); - - auto width = bounds.getWidth(); - - for (size_t i = 0; i < width; i++) { - auto x = bounds.getX() + i; - auto y = bounds.getY() + (bounds.getHeight() / 2.0f) - - (table[i / width * resolution] * bounds.getHeight() / 2.0f); - juce::Point p(x, y); - path.lineTo(p); - } - - auto endX = bounds.getX() + bounds.getWidth(); - auto endY = bounds.getY() + (bounds.getHeight() / 2.0f); - juce::Point end(endX, endY); - path.lineTo(end); - - return path; - } - //============================================================================ -private: - Shadow outerShadow = - Shadow(drawOuterShadow, outerShadowColour, outerShadowRadius, false); - Shadow innerShadow = - Shadow(drawInnerShadow, innerShadowColour, innerShadowRadius, true); - - AnalogOscillator osc; - juce::dsp::LookupTable table; - juce::AudioProcessorValueTreeState& apvts; - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(OscillatorDisplayComponent) -}; -} // namespace components -} // namespace gui -} // namespace dmt \ No newline at end of file +// //============================================================================== +// /* β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— +// * β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•šβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β• +// * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β• β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• +// * β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ•”β• +// * β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘ +// * β•šβ•β•β•β•β•β• β•šβ•β•β•šβ•β• β•šβ•β•β•šβ•β•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β• +// * Copyright (C) 2024 Dimethoxy Audio (https://dimethoxy.com) +// * +// * Part of the Dimethoxy Library, primarily intended for Dimethoxy plugins. +// * External use is permitted but not recommended. +// * No support or compatibility guarantees are provided. +// * +// * License: +// * This code is licensed under the GPLv3 license. You are permitted to use +// and +// * modify this code under the terms of this license. +// * You must adhere GPLv3 license for any project using this code or parts of +// it. +// * Your are not allowed to use this code in any closed-source project. +// * +// * Description: +// * OscillatorDisplayComponent provides a real-time visualization of an +// * oscillator's waveform. It uses a lookup table to efficiently render the +// * waveform based on the current oscillator parameters. The component +// supports +// * customizable shadows for enhanced visual appeal and is designed to be +// * responsive to parameter changes, updating the display accordingly. +// * +// * Authors: +// * Lunix-420 (Primary Author) +// */ +// //============================================================================== + +// #pragma once + +// //============================================================================== + +// #include "dsp/synth/AnalogOscillator.h" +// #include "gui/widget/Shadow.h" +// #include "utility/Settings.h" +// #include + +// //============================================================================== +// namespace dmt { +// namespace gui { +// namespace component { +// //============================================================================== +// // TODO: Make this use the new display system +// class OscillatorDisplayComponent +// : public juce::Component +// , public juce::Timer +// , public dmt::Scaleable +// { +// using Shadow = dmt::gui::widget::Shadow; +// using AnalogOscillator = dmt::dsp::synth::AnalogOscillator; + +// //============================================================================ +// // General +// using Settings = dmt::Settings::OscillatorDisplay; +// const int& fps = dmt::Settings::framerate; +// const int& resolution = Settings::resolution; + +// // Shadows +// const bool& drawOuterShadow = Settings::drawOuterShadow; +// const bool& drawInnerShadow = Settings::drawInnerShadow; +// const juce::Colour& outerShadowColour = Settings::outerShadowColour; +// const juce::Colour& innerShadowColour = Settings::innerShadowColour; +// const float& outerShadowRadius = Settings::outerShadowRadius; +// const float& innerShadowRadius = Settings::innerShadowRadius; + +// public: +// //============================================================================ +// OscillatorDisplayComponent(juce::AudioProcessorValueTreeState& apvts) +// : apvts(apvts) +// { +// TRACER("OscillatorDisplayComponent::OscillatorDisplayComponent"); +// osc.setSampleRate((float)resolution + 1.0f); +// osc.setFrequency(1.0f); +// startTimerHz(60); +// } +// //============================================================================ +// void paint(juce::Graphics& g) override +// { +// TRACER("OscillatorDisplayComponent::paint"); +// const auto bounds = this->getLocalBounds().toFloat(); +// } + +// protected: +// //============================================================================== +// void timerCallback() +// { +// TRACER("OscillatorDisplayComponent::timerCallback"); +// if (isParametersChanged()) { +// this->buildTable(); +// this->repaint(); +// } +// } + +// void buildTable() +// { +// TRACER("OscillatorDisplayComponent::buildTable"); +// osc.setPhase(0.0f); +// table.initialise( +// [&](std::size_t index) { return (float)osc.getNextSample(); }, +// resolution); +// } + +// bool isParametersChanged() +// { +// TRACER("OscillatorDisplayComponent::isParametersChanged"); +// } + +// //============================================================================== +// juce::Path getPath(juce::Rectangle bounds) +// { +// TRACER("OscillatorDisplayComponent::getPath"); +// bounds.setY(bounds.getY() + (bounds.getHeight() / 10.0f)); +// bounds.setHeight(bounds.getHeight() - (bounds.getHeight() / 5.0f)); + +// auto outerBounds = bounds; +// bounds = bounds.reduced(bounds.getWidth() / 6.0f); + +// juce::Path path; + +// auto startX = bounds.getX(); +// auto startY = bounds.getY() + (bounds.getHeight() / 2.0f); +// juce::Point start(startX, startY); +// path.startNewSubPath(start); + +// auto width = bounds.getWidth(); + +// for (size_t i = 0; i < width; i++) { +// auto x = bounds.getX() + i; +// auto y = bounds.getY() + (bounds.getHeight() / 2.0f) - +// (table[i / width * resolution] * bounds.getHeight() / 2.0f); +// juce::Point p(x, y); +// path.lineTo(p); +// } + +// auto endX = bounds.getX() + bounds.getWidth(); +// auto endY = bounds.getY() + (bounds.getHeight() / 2.0f); +// juce::Point end(endX, endY); +// path.lineTo(end); + +// return path; +// } +// //============================================================================ +// private: +// Shadow outerShadow = +// Shadow(drawOuterShadow, outerShadowColour, outerShadowRadius, false); +// Shadow innerShadow = +// Shadow(drawInnerShadow, innerShadowColour, innerShadowRadius, true); + +// AnalogOscillator osc; +// juce::dsp::LookupTable table; +// juce::AudioProcessorValueTreeState& apvts; +// JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(OscillatorDisplayComponent) +// }; +// } // namespace components +// } // namespace gui +// } // namespace dmt \ No newline at end of file diff --git a/gui/panel/AnalogGainPanel.h b/gui/panel/AnalogGainPanel.h index 7f0b556b..2ba41662 100644 --- a/gui/panel/AnalogGainPanel.h +++ b/gui/panel/AnalogGainPanel.h @@ -70,10 +70,10 @@ class AnalogGainPanel : public dmt::gui::panel::AbstractPanel Unit::Type::Milliseconds, LinearSliderType::Positive, LinearSliderOrientation::Vertical) - , skewSlider(apvts, - juce::String("Skew"), - juce::String("osc1GainEnvSkew"), - Unit::Type::EnvelopeSkew, + , bendSlider(apvts, + juce::String("Bend"), + juce::String("osc1GainEnvBend"), + Unit::Type::EnvelopeBend, LinearSliderType::Positive, LinearSliderOrientation::Vertical) { @@ -82,7 +82,7 @@ class AnalogGainPanel : public dmt::gui::panel::AbstractPanel addAndMakeVisible(attackSlider); addAndMakeVisible(holdSlider); addAndMakeVisible(decaySlider); - addAndMakeVisible(skewSlider); + addAndMakeVisible(bendSlider); } void extendResize() noexcept override @@ -96,7 +96,7 @@ class AnalogGainPanel : public dmt::gui::panel::AbstractPanel const int attackCol = 7; const int holdCol = 11; const int decayCol = 15; - const int skewCol = 19; + const int bendCol = 19; const auto attackSliderPrimaryPoint = this->getGridPoint(bounds, attackCol, primaryRow); @@ -119,19 +119,19 @@ class AnalogGainPanel : public dmt::gui::panel::AbstractPanel decaySlider.setBoundsByPoints(decaySliderPrimaryPoint, decaySliderSecondaryPoint); - const auto skewSliderPrimaryPoint = - this->getGridPoint(bounds, skewCol, primaryRow); - const auto skewSliderSecondaryPoint = - this->getGridPoint(bounds, skewCol, secundaryRow); - skewSlider.setBoundsByPoints(skewSliderPrimaryPoint, - skewSliderSecondaryPoint); + const auto bendSliderPrimaryPoint = + this->getGridPoint(bounds, bendCol, primaryRow); + const auto bendSliderSecondaryPoint = + this->getGridPoint(bounds, bendCol, secundaryRow); + bendSlider.setBoundsByPoints(bendSliderPrimaryPoint, + bendSliderSecondaryPoint); } private: LinearSliderComponent attackSlider; LinearSliderComponent holdSlider; LinearSliderComponent decaySlider; - LinearSliderComponent skewSlider; + LinearSliderComponent bendSlider; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(AnalogGainPanel) }; diff --git a/gui/panel/AnalogPitchPanel.h b/gui/panel/AnalogPitchPanel.h index 22228368..dd3eb7b6 100644 --- a/gui/panel/AnalogPitchPanel.h +++ b/gui/panel/AnalogPitchPanel.h @@ -56,30 +56,30 @@ class AnalogPitchPanel : public dmt::gui::panel::AbstractPanel Unit::Type::Milliseconds, LinearSliderType::Positive, LinearSliderOrientation::Vertical) + , depthSlider(apvts, + juce::String("Depth"), + juce::String("osc1PitchEnvDepth"), + Unit::Type::Frequency, + LinearSliderType::Positive, + LinearSliderOrientation::Vertical) , decaySlider(apvts, juce::String("Decay"), juce::String("osc1PitchEnvDecay"), Unit::Type::Milliseconds, LinearSliderType::Positive, LinearSliderOrientation::Vertical) - , skewSlider(apvts, - juce::String("Skew"), - juce::String("osc1PitchEnvSkew"), - Unit::Type::EnvelopeSkew, + , bendSlider(apvts, + juce::String("Bend"), + juce::String("osc1PitchEnvBend"), + Unit::Type::EnvelopeBend, LinearSliderType::Positive, LinearSliderOrientation::Vertical) - , depthSlider(apvts, - juce::String("Depth"), - juce::String("osc1PitchEnvDepth"), - Unit::Type::Frequency, - LinearSliderType::Positive, - LinearSliderOrientation::Vertical) { setLayout({ 25, 32 }); addAndMakeVisible(attackSlider); addAndMakeVisible(depthSlider); addAndMakeVisible(decaySlider); - addAndMakeVisible(skewSlider); + addAndMakeVisible(bendSlider); } void extendResize() noexcept override @@ -91,7 +91,7 @@ class AnalogPitchPanel : public dmt::gui::panel::AbstractPanel const int attackCol = 7; const int decayCol = 11; - const int skewCol = 15; + const int bendCol = 15; const int depthCol = 19; const auto attackSliderPrimaryPoint = @@ -108,12 +108,12 @@ class AnalogPitchPanel : public dmt::gui::panel::AbstractPanel decaySlider.setBoundsByPoints(decaySliderPrimaryPoint, decaySliderSecondaryPoint); - const auto skewSliderPrimaryPoint = - this->getGridPoint(bounds, skewCol, primaryRow); - const auto skewSliderSecondaryPoint = - this->getGridPoint(bounds, skewCol, secundaryRow); - skewSlider.setBoundsByPoints(skewSliderPrimaryPoint, - skewSliderSecondaryPoint); + const auto bendSliderPrimaryPoint = + this->getGridPoint(bounds, bendCol, primaryRow); + const auto bendSliderSecondaryPoint = + this->getGridPoint(bounds, bendCol, secundaryRow); + bendSlider.setBoundsByPoints(bendSliderPrimaryPoint, + bendSliderSecondaryPoint); const auto depthSliderPrimaryPoint = this->getGridPoint(bounds, depthCol, primaryRow); @@ -127,7 +127,7 @@ class AnalogPitchPanel : public dmt::gui::panel::AbstractPanel LinearSliderComponent attackSlider; LinearSliderComponent depthSlider; LinearSliderComponent decaySlider; - LinearSliderComponent skewSlider; + LinearSliderComponent bendSlider; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(AnalogPitchPanel) }; //============================================================================== diff --git a/gui/panel/OscillatorPanel.h b/gui/panel/OscillatorPanel.h index fd844409..a4ece0b1 100644 --- a/gui/panel/OscillatorPanel.h +++ b/gui/panel/OscillatorPanel.h @@ -31,7 +31,6 @@ //============================================================================== #include "gui/panel/AbstractPanel.h" -#include "gui/panel/AnalogOscillatorPanel.h" #include "gui/panel/Carousel.h" #include "gui/panel/ModernOscillatorPanel.h" #include @@ -49,7 +48,6 @@ class OscillatorPanel : public dmt::gui::panel::Carousel OscillatorPanel() : Carousel() { - panels.push_back(std::make_unique()); panels.push_back(std::make_unique()); init(); } diff --git a/gui/panel/Panel.h b/gui/panel/Panel.h index 894599be..204288ff 100644 --- a/gui/panel/Panel.h +++ b/gui/panel/Panel.h @@ -31,7 +31,6 @@ #include "./AbstractPanel.h" #include "./AnalogGainPanel.h" -#include "./AnalogOscillatorPanel.h" #include "./AnalogPitchPanel.h" #include "./Carousel.h" #include "./DisfluxPanel.h" diff --git a/model/AhdEnvelopeParameters.h b/model/AhdEnvelopeParameters.h new file mode 100644 index 00000000..21f6e2bd --- /dev/null +++ b/model/AhdEnvelopeParameters.h @@ -0,0 +1,73 @@ +#pragma once + +#include + +//============================================================================== +namespace dmt { +namespace model { +static inline juce::AudioProcessorParameterGroup +envelopeParameterGroup(juce::String parentUid, + juce::String suffix, + std::array defaultValues) +{ + using ParameterInt = juce::AudioParameterInt; + using ParameterFloat = juce::AudioParameterFloat; + using ParameterChoice = juce::AudioParameterChoice; + using NormalisableRange = juce::NormalisableRange; + + juce::String uid = parentUid + suffix + "Env"; + + return juce::AudioProcessorParameterGroup( + uid, // group ID + suffix + "Envelope", // group name + "|", // separator + std::make_unique(uid + "Enabled", // parameter ID + "Enabled", // parameter name + StringArray{ "Off", "On" }, // choices + 1), // defaultValue + std::make_unique(uid + "Attack", // parameter ID + "Attack", // parameter name + NormalisableRange(0.0f, // rangeStart + 0.3f, // rangeEnd + 0.001f, // intervalValue + 0.5f), // skewFactor + defaultValues[0]), // defaultValue + std::make_unique(uid + "Hold", // parameter ID + "Hold", // parameter name + NormalisableRange(0.0f, // rangeStart + 0.3f, // rangeEnd + 0.001f, // intervalValue + 0.5f), // skewFactor + defaultValues[1]), // defaultValue + std::make_unique(uid + "Decay", // parameter ID + "Decay", // parameter name + NormalisableRange(0.0f, // rangeStart + 1.0f, // rangeEnd + 0.001f, // intervalValue + 0.5f), // skewFactor + defaultValues[2]), // defaultValue + std::make_unique(uid + "Depth", // parameter ID + "Depth", // parameter name + NormalisableRange(0.0f, // rangeStart + 1.0f, // rangeEnd + 0.001f, // intervalValue + 0.5f), // skewFactor + defaultValues[3]), // defaultValue + std::make_unique(uid + "AttackBend", // parameter ID + "Attack Bend", // parameter name + NormalisableRange(-20.0f, // rangeStart + 20.0f, // rangeEnd + 0.1f, // intervalValue + 1.0f), // skewFactor + defaultValues[4]), // defaultValue + std::make_unique(uid + "DecayBend", // parameter ID + "Decay Bend", // parameter name + NormalisableRange(-20.0f, // rangeStart + 20.0f, // rangeEnd + 0.1f, // intervalValue + 1.0f), // skewFactor + defaultValues[5]) // defaultValue + ); +} +} // namespace model +} // namespace dmt \ No newline at end of file diff --git a/model/DigitalOscillatorParameters.h b/model/DigitalOscillatorParameters.h new file mode 100644 index 00000000..99758438 --- /dev/null +++ b/model/DigitalOscillatorParameters.h @@ -0,0 +1,83 @@ +#pragma once + +#include "../dsp/synth/DigitalOscillator.h" +#include + +//============================================================================== +namespace dmt { +namespace model { +static inline juce::AudioProcessorParameterGroup +digitalOscillatorParameterGroup(juce::String parentUid) +{ + // using ParameterInt = juce::AudioParameterInt; + using ParameterFloat = juce::AudioParameterFloat; + using ParameterChoice = juce::AudioParameterChoice; + using NormalisableRange = juce::NormalisableRange; + using ParameterGroup = juce::AudioProcessorParameterGroup; + using String = juce::String; + + using DigitalWaveform = dmt::dsp::synth::DigitalWaveform; + + String uid = parentUid + "DigitalOscillator"; + + return juce::AudioProcessorParameterGroup( + uid, // group ID + "Waveform", // group name + "|", // separator + std::make_unique(uid + "Type", // parameter ID + "Type", // parameter name + DigitalWaveform::waveformNames, // choices + 2), // defaultValue + std::make_unique(uid + "Warp", + "Warp", + NormalisableRange(0.f, // rangeStart + 1.f, // rangeEnd + .01f, // intervalValue + 1.f), // skewFactor + 0.0f), + std::make_unique(uid + "Bend", + "Bend", + NormalisableRange(-100.f, // rangeStart + 100.f, // rangeEnd + .01f, // intervalValue + 1.f), // skewFactor + 0.0f), // defaultValue + std::make_unique(uid + "Pwm", + "Pwm", + NormalisableRange(1.0f, // rangeStart + 100.f, // rangeEnd + .1f, // intervalValue + 1.f), // skewFactor + 0.0f), // defaultValue + std::make_unique(uid + "Sync", + "Sync", + NormalisableRange(0.f, // rangeStart + 100.f, // rangeEnd + .01f, // intervalValue + 1.f), // skewFactor + .0f), // defaultValue + std::make_unique(uid + "Bias", + "Bias", + NormalisableRange(-1.f, // rangeStart + 1.f, // rangeEnd + .01f, // intervalValue + 1.f), // skewFactor + 0.0f), // defaultValue + std::make_unique(uid + "Clip", + "Clip", + NormalisableRange(0.f, // rangeStart + 1.f, // rangeEnd + .01f, // intervalValue + 1.f), // skewFactor + 0.0f), // defaultValue + std::make_unique(uid + "Drive", + "Drive", + NormalisableRange(-20.f, // rangeStart + +20.f, // rangeEnd + .01f, // intervalValue + 1.f), // skewFactor + 3.0f) // defaultValue + ); +} +} // namespace model +} // namespace dmt \ No newline at end of file diff --git a/model/NeutrinoParameters.h b/model/NeutrinoParameters.h index fabf1473..83d27bf1 100644 --- a/model/NeutrinoParameters.h +++ b/model/NeutrinoParameters.h @@ -1,17 +1,20 @@ #pragma once //============================================================================== +#include "AhdEnvelopeParameters.h" +#include "DigitalOscillatorParameters.h" #include //============================================================================== namespace dmt { namespace model { //============================================================================== static inline juce::AudioProcessorParameterGroup -neutrinoParameterGroup(juce::String parentUid, int versionHint) +neutrinoParameterGroup(juce::String parentUid, [[maybe_unused]] int versionHint) { using ParameterInt = juce::AudioParameterInt; using ParameterFloat = juce::AudioParameterFloat; - // using ParameterChoice = juce::AudioParameterChoice; + using ParameterChoice = juce::AudioParameterChoice; using NormalisableRange = juce::NormalisableRange; + using ParameterGroup = juce::AudioProcessorParameterGroup; juce::String uid = parentUid + "Neutrino"; @@ -20,14 +23,16 @@ neutrinoParameterGroup(juce::String parentUid, int versionHint) "Neutrino", // group name "|", // separator - // Symmetry - std::make_unique(uid + "Symmetry", - "Symmetry", - NormalisableRange(-1.f, // rangeStart - 1.f, // rangeEnd - .01f, // intervalValue - 1.f), // skewFactor - .0f)); + // Oscillators + std::make_unique(digitalOscillatorParameterGroup(uid)), + + // Envelopes + std::make_unique(envelopeParameterGroup( + uid, "Gain", { 0.0f, 0.055f, 0.350f, 0.0f, 0.0f, 0.0f })), + std::make_unique(envelopeParameterGroup( + uid, "Pitch1", { 0.0f, 0.0f, 0.185f, 0.033f, 0.0f, 0.0f })), + std::make_unique(envelopeParameterGroup( + uid, "Pitch2", { 0.0f, 0.0f, 0.02f, 0.033f, 0.0f, 0.0f }))); } } // namespace model } // namespace dmt \ No newline at end of file diff --git a/model/WaveformParameters.h b/model/WaveformParameters.h deleted file mode 100644 index fd61baf5..00000000 --- a/model/WaveformParameters.h +++ /dev/null @@ -1,51 +0,0 @@ -#pragma once - -#include -#include "../dsp/synth/AnalogWaveform.h" - -//============================================================================== -namespace dmt { -namespace model { -static inline juce::AudioProcessorParameterGroup -waveformParameterGroup(juce::String parentUid) -{ - using ParameterInt = juce::AudioParameterInt; - using ParameterFloat = juce::AudioParameterFloat; - using ParameterChoice = juce::AudioParameterChoice; - using NormalisableRange = juce::NormalisableRange; - - juce::String uid = parentUid + "Waveform"; - - return juce::AudioProcessorParameterGroup( - uid, // group ID - "Waveform", // group name - "|", // separator - std::make_unique(uid + "Type", // parameter ID - "Type", // parameter name - dmt::dsp::synth::AnalogWaveform::waveformNames, // choices - 2), // defaultIndex - std::make_unique(uid + "Bend", - "Bend", - NormalisableRange(-100.f, // rangeStart - 100.f, // rangeEnd - .01f, // intervalValue - 1.f), // skewFactor - .0f), // defaultValue - std::make_unique(uid + "Pwm", - "Pwm", - NormalisableRange(.0f, // rangeStart - 100.f, // rangeEnd - .01f, // intervalValue - 1.f), // skewFactor - 4.f), // defaultValue - std::make_unique(uid + "Sync", - "Sync", - NormalisableRange(0.f, // rangeStart - 100.f, // rangeEnd - .01f, // intervalValue - 1.f), // skewFactor - .0f) // defaultValue) - ); -} -} // namespace model -} // namespace dmt \ No newline at end of file diff --git a/scripts/add_subtree.sh b/scripts/add_subtree.sh new file mode 100644 index 00000000..0cb19e59 --- /dev/null +++ b/scripts/add_subtree.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +git remote add dmt-upstream https://github.com/Dimethoxy/DMT.git + +git fetch dmt-upstream + +git subtree add --prefix=src/dmt dmt-upstream main --squash \ No newline at end of file diff --git a/scripts/pull_subtree.sh b/scripts/pull_subtree.sh new file mode 100644 index 00000000..be0d2863 --- /dev/null +++ b/scripts/pull_subtree.sh @@ -0,0 +1 @@ +git subtree pull --prefix=src/dmt dmt-upstream main --squash \ No newline at end of file diff --git a/utility/Unit.h b/utility/Unit.h index 7de6072c..6cfa04ad 100644 --- a/utility/Unit.h +++ b/utility/Unit.h @@ -83,7 +83,7 @@ struct alignas(8) Unit Bitdepth, VoiceDensity, VoiceDistribution, - EnvelopeSkew, + EnvelopeBend, Milliseconds, OscilloscopeZoom, OscilloscopeThickness, @@ -168,6 +168,9 @@ struct alignas(8) Unit return String(static_cast(static_cast(_value * 100.0f))) + String("%"); break; + case Type::EnvelopeBend: + return String(_value, 1) + String("x"); + break; // Heretik case Type::HeretikPreGain: From 5808346ed7e5188555bf8c7c7410cebbbfee747e Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Tue, 5 May 2026 18:42:01 +0200 Subject: [PATCH 38/74] build: update CI snapshot workflow --- .github/workflows/ci-development.yml | 438 --------------------------- .github/workflows/ci-snapshot.yml | 6 +- 2 files changed, 5 insertions(+), 439 deletions(-) delete mode 100644 .github/workflows/ci-development.yml diff --git a/.github/workflows/ci-development.yml b/.github/workflows/ci-development.yml deleted file mode 100644 index 0ee8e0e4..00000000 --- a/.github/workflows/ci-development.yml +++ /dev/null @@ -1,438 +0,0 @@ -#=========================================================================================== -# This workflow will build the project for Windows, macOS, and Linux. -# It will also build an Arch Linux and Fedora package using Docker containers. -# The artifacts will be uploaded to the release page. -# -# TODO: -# - Add a step after release to update the AUR repository -#=========================================================================================== - -name: Build Development -on: - workflow_dispatch: -defaults: - run: - shell: bash - -#=========================================================================================== -# Environment Variables -env: - PROJECT_NAME: Disflux - BUNDLE_NAME: disflux - BUNDLE_ID: com.dimethoxy.disflux - BUILD_DIR: build - DISPLAY: :0 # Linux pluginval needs this - HOMEBREW_NO_INSTALL_CLEANUP: 1 - IPP_DIR: C:\Program Files (x86)\Intel\oneAPI\ipp\latest\lib\cmake\ipp - -#=========================================================================================== -# Build Jobs -#=========================================================================================== -jobs: - #========================================================================================= - # Windows Build - #========================================================================================= - build-windows: - runs-on: windows-latest - steps: - - name: Export Variables - run: | - echo "BUILD_ARTIFACTS_DIR=$BUILD_DIR/src/${{env.PROJECT_NAME}}Plugin_artefacts/Release" >> $GITHUB_ENV - echo "WINDOWS-PACKAGE=${{env.BUNDLE_NAME}}-windows.exe" >> $GITHUB_ENV - - - name: Checkout Code - uses: actions/checkout@v4 - with: - ref: development - - - name: Read Version - run: | - echo "VERSION=$(tr -d '[:space:]' < VERSION.md)" >> $GITHUB_ENV - - - name: Setup MSVC - uses: TheMrMilchmann/setup-msvc-dev@v3 - with: - arch: x64 - spectre: true - - - name: Set Up Windows - run: | - choco install ninja - choco install innosetup - - - name: Cache IPP (Windows) - id: cache-ipp - uses: actions/cache@v4 - with: - key: ipp-v6 - path: C:\Program Files (x86)\Intel - - - name: Install IPP (Windows) - if: steps.cache-ipp.outputs.cache-hit != 'true' - run: | - curl --output oneapi.exe https://registrationcenter-download.intel.com/akdlm/IRC_NAS/2e89fab4-e1c7-4f14-a1ef-6cddba8c5fa7/intel-ipp-2022.0.0.796_offline.exe - ./oneapi.exe -s -x -f oneapi - ./oneapi/bootstrapper.exe -s -c --action install --components=intel.oneapi.win.ipp.devel --eula=accept -p=NEED_VS2022_INTEGRATION=1 --log-dir=. - - - name: Save IPP cache - if: steps.cache-ipp.outputs.cache-hit != 'true' - uses: actions/cache/save@v4 - with: - path: C:\Program Files (x86)\Intel - key: ipp-v6 - - - name: Select CMake Preset - run: | - cmake --preset "Windows Release" - - - name: Build - run: cmake --build build --config "Release" - - - name: Copy Build Artifacts - run: | - mkdir -p artifacts - cp -r ${{env.BUILD_ARTIFACTS_DIR}}/VST3/${{env.PROJECT_NAME}}.vst3 \ - artifacts/ - cp -r ${{env.BUILD_ARTIFACTS_DIR}}/CLAP/${{env.PROJECT_NAME}}.clap \ - artifacts/ - shell: bash - - - name: Create Installer - run: | - # Create the packaging directory - mkdir -p packaging - - # Create the Inno Setup - envsubst < pkg/windows/Setup.iss > packaging/Setup.iss - iscc packaging/Setup.iss - - # Move the installer to the artifacts directory - mv packaging/Output/"${{env.PROJECT_NAME}}_Setup.exe" artifacts/${{env.WINDOWS-PACKAGE}} - shell: bash - - - name: Upload Artifacts - uses: actions/upload-artifact@v4 - with: - name: artifacts-windows - path: artifacts - - #========================================================================================= - # macOS Build - #========================================================================================= - build-macos: - runs-on: macos-latest - steps: - - name: Export Variables - run: | - echo "BUILD_ARTIFACTS_DIR=$BUILD_DIR/src/${{env.PROJECT_NAME}}Plugin_artefacts/Release" >> $GITHUB_ENV - echo "MAC_PACKAGE=${{env.BUNDLE_NAME}}-macos.pkg" >> $GITHUB_ENV - - - name: Checkout Code - uses: actions/checkout@v4 - with: - ref: development - - - name: Read Version - run: | - echo "VERSION=$(tr -d '[:space:]' < VERSION.md)" >> $GITHUB_ENV - - - name: Set Up Mac - run: brew install ninja osxutils - - - name: Select CMake Preset - run: | - cmake --preset "Mac Release" \ - -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" - - - name: Build - run: cmake --build build --config "Release" - - - name: Copy Build Artifacts - run: | - mkdir -p artifacts - cp -r ${{env.BUILD_ARTIFACTS_DIR}}/VST3/${{env.PROJECT_NAME}}.vst3 \ - artifacts/ - cp -r ${{env.BUILD_ARTIFACTS_DIR}}/CLAP/${{env.PROJECT_NAME}}.clap \ - artifacts/ - cp -r ${{env.BUILD_ARTIFACTS_DIR}}/AU/${{env.PROJECT_NAME}}.component \ - artifacts/ - shell: bash - - - name: Import Certificates - uses: sudara/basic-macos-keychain-action@v1 - id: keychain - with: - dev-id-app-cert: ${{ secrets.DEV_ID_APP_CERT }} - dev-id-app-password: ${{ secrets.DEV_ID_PASSWORD }} - dev-id-installer-cert: ${{ secrets.DEV_ID_INSTALL_CERT }} - dev-id-installer-password: ${{ secrets.DEV_ID_PASSWORD }} - - - name: Codesign (macOS) - run: | - # Set variables - VST3_BIN="artifacts/${{env.PROJECT_NAME}}.vst3/Contents/MacOS/${{env.PROJECT_NAME}}" - CLAP_BIN="artifacts/${{env.PROJECT_NAME}}.clap/Contents/MacOS/${{env.PROJECT_NAME}}" - AU_BIN="artifacts/${{env.PROJECT_NAME}}.component/Contents/MacOS/${{env.PROJECT_NAME}}" - - # Codesign the binaries - codesign \ - --force -s "${{secrets.DEVELOPER_ID_APPLICATION}}" \ - -v "$VST3_BIN" \ - --deep --strict --options=runtime --timestamp - codesign \ - --force -s "${{secrets.DEVELOPER_ID_APPLICATION}}" \ - -v "$CLAP_BIN" \ - --deep --strict --options=runtime --timestamp - codesign \ - --force -s "${{secrets.DEVELOPER_ID_APPLICATION}}" \ - -v "$AU_BIN" \ - --deep --strict --options=runtime --timestamp - shell: bash - - - name: Create Installer - run: | - # Set variables - VST3_PATH="artifacts/${{env.PROJECT_NAME}}.vst3" - CLAP_PATH="artifacts/${{env.PROJECT_NAME}}.clap" - AU_PATH="artifacts/${{env.PROJECT_NAME}}.component" - PACKAGE_NAME="${{env.PROJECT_NAME}}-macos.pkg" - - # Create the packaging directory - mkdir -p packaging - - # Create the distribution file - envsubst < pkg/mac/distribution.xml > packaging/distribution.xml - - # Create the VST subpackage - pkgbuild \ - --identifier "${{env.BUNDLE_ID}}.vst3.pkg" \ - --version "$VERSION" \ - --component "$VST3_PATH" \ - --install-location "/Library/Audio/Plug-Ins/VST3" \ - "packaging/${{env.PROJECT_NAME}}.vst3.pkg" - - # Create the CLAP subpackage - pkgbuild \ - --identifier "${{env.BUNDLE_ID}}.clap.pkg" \ - --version "$VERSION" \ - --component "$CLAP_PATH" \ - --install-location "/Library/Audio/Plug-Ins/CLAP" \ - "packaging/${{env.PROJECT_NAME}}.clap.pkg" - - # Create the AU subpackage - pkgbuild \ - --identifier "${{env.BUNDLE_ID}}.au.pkg" \ - --version "$VERSION" \ - --component "$AU_PATH" \ - --install-location "/Library/Audio/Plug-Ins/Components" \ - "packaging/${{env.PROJECT_NAME}}.au.pkg" - - # Create the main package - cd packaging - productbuild \ - --resources ./resources \ - --distribution distribution.xml \ - --sign "${{secrets.DEVELOPER_ID_INSTALLER}}" \ - --timestamp "${{env.PROJECT_NAME}}.pkg" - - # Notarize the package - xcrun notarytool submit "${{env.PROJECT_NAME}}.pkg" \ - --apple-id ${{secrets.NOTARIZATION_USERNAME}} \ - --password ${{secrets.NOTARIZATION_PASSWORD}} \ - --team-id ${{secrets.TEAM_ID}} \ - --wait - - # Staple the package - xcrun stapler staple "${{env.PROJECT_NAME}}.pkg" - - # Move the package to the artifacts directory - mv ${{env.PROJECT_NAME}}.pkg ../artifacts/${{env.MAC_PACKAGE}} - shell: bash - - - name: Upload Artifacts - uses: actions/upload-artifact@v4 - with: - name: artifacts-macos - path: artifacts - - #========================================================================================= - # Ubuntu Linux Build - #========================================================================================= - build-ubuntu: - runs-on: ubuntu-latest - steps: - - name: Export Variables - run: | - echo "BUILD_ARTIFACTS_DIR=$BUILD_DIR/src/${{env.PROJECT_NAME}}Plugin_artefacts/Release" >> $GITHUB_ENV - echo "UBUNTU_PACKAGE=${{env.BUNDLE_NAME}}-linux-ubuntu.deb" >> $GITHUB_ENV - echo "LINUX_PACKAGE=${{env.BUNDLE_NAME}}-linux-vanilla.zip" >> $GITHUB_ENV - - - name: Checkout Code - uses: actions/checkout@v4 - with: - ref: development - - - name: Read Version - run: | - echo "VERSION=$(tr -d '[:space:]' < VERSION.md)" >> $GITHUB_ENV - - - name: Set Up Linux - run: | - sudo apt-get update - sudo apt-get install ninja-build - sudo apt install libasound2-dev \ - libjack-jackd2-dev \ - ladspa-sdk \ - libcurl4-openssl-dev \ - libfreetype-dev \ - libfontconfig1-dev \ - libx11-dev \ - libxcomposite-dev \ - libxcursor-dev \ - libxext-dev \ - libxinerama-dev \ - libxrandr-dev \ - libxrender-dev \ - libwebkit2gtk-4.1-dev \ - libglu1-mesa-dev mesa-common-dev - sudo apt install curl - sudo apt-get install -y dpkg-dev devscripts - sudo /usr/bin/Xvfb $DISPLAY & - shell: bash - - - name: Select CMake Preset - run: | - cmake --preset "Linux Release" - - - name: Build - run: cmake --build build --config "Release" - - - name: Copy Artifacts - run: | - mkdir -p artifacts - cp -r ${{env.BUILD_ARTIFACTS_DIR}}/VST3/${{env.PROJECT_NAME}}.vst3 \ - artifacts/ - cp -r ${{env.BUILD_ARTIFACTS_DIR}}/CLAP/${{env.PROJECT_NAME}}.clap \ - artifacts/ - cp -r ${{env.BUILD_ARTIFACTS_DIR}}/LV2/${{env.PROJECT_NAME}}.lv2 \ - artifacts/ - shell: bash - - - name: Package Linux Artifacts - run: | - # Set variables - UBUNTU_PACKAGE_DIR="${{env.BUNDLE_NAME}}-linux-ubuntu" - UBUNTU_CONTROL_FILE="pkg/ubuntu/control" - VST3_INSTALL_DIR="/usr/lib/vst3/${{env.PROJECT_NAME}}" - CLAP_INSTALL_DIR="/usr/lib/clap/${{env.PROJECT_NAME}}" - LV2_INSTALL_DIR="/usr/lib/lv2/${{env.PROJECT_NAME}}" - - # Create Vanilla package directory - mkdir -p vanilla - cp -r artifacts/${{env.PROJECT_NAME}}.vst3 vanilla/ - cp -r artifacts/${{env.PROJECT_NAME}}.clap vanilla/ - cp -r artifacts/${{env.PROJECT_NAME}}.lv2 vanilla/ - - # Zip and move the package to the artifacts directory - zip -r ${{env.LINUX_PACKAGE}} vanilla/* - mv ${{env.LINUX_PACKAGE}} artifacts/$LINUX_PACKAGE - - # Create Debian package directory - mkdir -p $UBUNTU_PACKAGE_DIR/DEBIAN - mkdir -p $UBUNTU_PACKAGE_DIR/$VST3_INSTALL_DIR - mkdir -p $UBUNTU_PACKAGE_DIR/$CLAP_INSTALL_DIR - mkdir -p $UBUNTU_PACKAGE_DIR/$LV2_INSTALL_DIR - - # Copy files to Debian package directory - cp -r artifacts/${{env.PROJECT_NAME}}.vst3 \ - $UBUNTU_PACKAGE_DIR/$VST3_INSTALL_DIR/ - cp -r artifacts/${{env.PROJECT_NAME}}.clap \ - $UBUNTU_PACKAGE_DIR/$CLAP_INSTALL_DIR/ - cp -r artifacts/${{env.PROJECT_NAME}}.lv2 \ - $UBUNTU_PACKAGE_DIR/$LV2_INSTALL_DIR/ - - # Set PACKAGE_NAME for envsubst - export PACKAGE_NAME=${{env.BUNDLE_NAME}} - export PACKAGE_VERSION=$VERSION - - # Replace PACKAGE_NAME in control file and copy to Debian package directory - envsubst < $UBUNTU_CONTROL_FILE > $UBUNTU_PACKAGE_DIR/DEBIAN/control - - # Build Debian package - dpkg-deb --build $UBUNTU_PACKAGE_DIR - - # Move the package to the artifacts directory - cp -r *.deb artifacts/${{env.UBUNTU_PACKAGE}} - shell: bash - - - name: Upload Artifacts - uses: actions/upload-artifact@v4 - with: - name: artifacts-ubuntu - path: artifacts - - #========================================================================================= - # Arch Linux Build - #========================================================================================= - build-archlinux: - runs-on: ubuntu-latest - container: - image: archlinux:latest - steps: - - name: Export Variables - run: | - echo "BUILD_ARTIFACTS_DIR=$BUILD_DIR/src/${{env.PROJECT_NAME}}Plugin_artefacts/Release" >> $GITHUB_ENV - echo "PACKAGE_NAME=${{env.BUNDLE_NAME}}-linux-arch.pkg.tar.zst" >> $GITHUB_ENV - - - name: Install Base Packages - run: | - pacman -Sy --noconfirm base-devel git - - - name: Checkout Repository - uses: actions/checkout@v4 - with: - ref: development - - - name: Read Version - run: | - echo "VERSION=$(tr -d '[:space:]' < VERSION.md)" >> $GITHUB_ENV - - - name: Create user for build process - run: | - useradd -m dimethoxy - sudo su - dimethoxy - - - name: Set permissions for the build directory - run: | - sudo chown -R dimethoxy:dimethoxy /__w/${{env.PROJECT_NAME}}/${{env.PROJECT_NAME}}/pkg/arch/release - sudo chmod -R u+rw /__w/${{env.PROJECT_NAME}}/${{env.PROJECT_NAME}}/pkg/arch/release - - - name: Disable sudo password prompt - run: | - echo 'dimethoxy ALL=(ALL) NOPASSWD: ALL' | sudo tee -a /etc/sudoers - - - name: Build Package - run: | - sudo -u dimethoxy bash -c 'cd pkg/arch/release && makepkg -s --noconfirm' - - - name: Package Artifacts - run: | - # Remove the default package - rm pkg/arch/release/*debug*.pkg.tar.zst - - # Move the package to the root directory - mv pkg/arch/release/*.pkg.tar.zst . - - # Rename the package - mv *.pkg.tar.zst ${{env.PACKAGE_NAME}} - - # Move the package to the artifacts directory - mkdir -p artifacts - mv ${{env.PACKAGE_NAME}} artifacts/ - shell: bash - - - name: Upload Artifacts - uses: actions/upload-artifact@v4 - with: - name: artifacts-archlinux - path: artifacts diff --git a/.github/workflows/ci-snapshot.yml b/.github/workflows/ci-snapshot.yml index 81359521..55b54ea1 100644 --- a/.github/workflows/ci-snapshot.yml +++ b/.github/workflows/ci-snapshot.yml @@ -11,7 +11,11 @@ name: Build Snapshot on: workflow_dispatch: pull_request: + branches: + - main push: + branches: + - main defaults: run: shell: bash @@ -436,7 +440,7 @@ jobs: #========================================================================================= release: runs-on: ubuntu-latest - needs: [build-windows, build-ubuntu, build-macos, build-archlinux] + needs: [ build-windows, build-ubuntu, build-macos, build-archlinux ] env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 1044a1447e17fb6104cc9d756f0271cc42b2e2e3 Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Tue, 5 May 2026 18:49:24 +0200 Subject: [PATCH 39/74] Squashed 'src/dmt/' changes from 93f7d04..9d799be 9d799be chore: revise usage warnings and library description in README 86c0d66 Merge commit 'c5dbf641800d32db5c83917efa48785a4a586771' into development 6458fbc fix: more hardware acceleration stuff 1cf0391 fix: adjust default values for panel shadow radius settings 6e755e9 refactor: streamline hardware acceleration logic and OS detection in settings aca7c9b fix: update debug messages for renderer selection and change GL debug suppression flag 5692685 Merge remote-tracking branch 'origin/development' into development bd6ed29 feat: implement hardware acceleration control based on OS and Wine detection 3d083f4 feat: add option to disable hardware acceleration and update notification setting 75ee9c7 gui: change default button theme b3f6b2a gui: fix oscilloscope overdraw git-subtree-dir: src/dmt git-subtree-split: 9d799be1370e369144516c8603bc6d17142789f2 --- README.md | 33 ++++--- app/AbstractPluginEditor.h | 119 ++++++++++++++++-------- configuration/Options.h | 9 +- gui/component/SettingsEditorComponent.h | 2 +- gui/display/AbstractDisplay.h | 22 ++--- utility/Settings.h | 29 +++--- 6 files changed, 137 insertions(+), 77 deletions(-) diff --git a/README.md b/README.md index 87743ea1..ce41b775 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,30 @@ # Dimethoxy Library -> [!WARNING] -> This library is under active development and primarily intended for use within Dimethoxy projects \ -> External use is unsupported. +> [!CAUTION] +> **Do NOT use this library in your own projects if you expect support.**
+> We will **not fix your issues, bugs, or integration problems** if you use it externally. +> +> This library is under active development and is built **exclusively for Dimethoxy projects**.
+> External use is entirely at your own risk. -The Dimethoxy Library is the core engine behind all Dimethoxy plugins β€” a modular C++ codebase built for high-performance digital signal processing and plugin development. -From custom DSP algorithms to GUI systems and utility wrappers, this library powers nearly every aspect of our audio tools. +The Dimethoxy Library is the core engine behind all Dimethoxy plugins.
+While technically usable outside the ecosystem, it is **not designed, tested, or maintained** for third-party use. -## Features -- πŸš€ High-performance DSP tailored for aggressive electronic music (Hardstyle, Hardcore, Uptempo, etc.) -- πŸŽ›οΈ Modular components for efficient plugin development -- 🧱 Shared utilities, math, parameter handling, and UI helpers -- πŸ§ͺ Designed for maintainability and extensibility across multiple projects +No guarantees are made regarding: + +* Stability +* Compatibility +* API consistency +* Build success on your setup + +If it breaks, you own the pieces. ## Used In -- [Disflux](https://github.com/Dimethoxy/Disflux) β€” Transient Smearing Audio Plugin for Windows, MacOS and Linux -- [Oscilloscope](https://github.com/Dimethoxy/Oscilloscope) β€” Work in Progress Oscilloscope Audio Plugin for Windows, MacOS and Linux +* [Disflux](https://github.com/Dimethoxy/Disflux): Transient Smearing Audio Plugin for Windows, macOS, and Linux +* [Oscilloscope](https://github.com/Dimethoxy/Oscilloscope): Work-in-progress Oscilloscope Audio Plugin for Windows, macOS, and Linux ## License -This project is licensed under AGPLv3. \ + +This project is licensed under AGPLv3. Any project using **any** part of this library **must** also be licensed under AGPLv3 or a compatible open-source license. diff --git a/app/AbstractPluginEditor.h b/app/AbstractPluginEditor.h index 8e64f76a..39a5dbe6 100644 --- a/app/AbstractPluginEditor.h +++ b/app/AbstractPluginEditor.h @@ -1,5 +1,11 @@ #pragma once +//============================================================================== +// Preprocessor flags for renderer control +#define DMT_SUPPRESS_GL_DEBUG_MESSAGES 0 + +//============================================================================== + #include "app/AbstractPluginProcessor.h" #include "gui/window/Compositor.h" #include @@ -40,50 +46,41 @@ class AbstractPluginEditor // Now that layout is fully configured, attach the compositor addAndMakeVisible(compositor); - if (OS_IS_WINDOWS) { - setResizable(false, true); - } +#if OS_IS_DARWIN || OS_IS_LINUX + // Determine if hardware acceleration should be used + bool shouldUseOpenGL = dmt::Settings::useOpenGL; + DBG("[AbstractPluginEditor] OpenGL renderer: " + << (shouldUseOpenGL ? "ENABLED" : "DISABLED")); if (OS_IS_DARWIN) { + // macOS: Use OpenGL for hardware acceleration if enabled + if (shouldUseOpenGL) { + DBG("[AbstractPluginEditor] Using macOS OpenGL renderer"); + openGLContext.setComponentPaintingEnabled(true); + openGLContext.setContinuousRepainting(false); + openGLContext.attachTo(*getTopLevelComponent()); + setupOpenGLContext(); + } else { + DBG("[AbstractPluginEditor] Using macOS software renderer"); + } setResizable(false, true); } if (OS_IS_LINUX) { - openGLContext.setComponentPaintingEnabled(true); - openGLContext.setContinuousRepainting(false); - openGLContext.attachTo(*getTopLevelComponent()); - std::thread([this]() { - for (int i = 0; i < 200; ++i) { - if (openGLContext.isAttached() && - openGLContext.getRawContext() != nullptr) - break; - std::this_thread::sleep_for(std::chrono::milliseconds(25)); - } - - if (!openGLContext.isAttached() || - openGLContext.getRawContext() == nullptr) - return; - - openGLContext.executeOnGLThread( - [](juce::OpenGLContext&) { - if (juce::gl::glDebugMessageControl) { - juce::gl::glDebugMessageControl( - juce::gl::GL_DEBUG_SOURCE_API, - juce::gl::GL_DEBUG_TYPE_OTHER, - juce::gl::GL_DEBUG_SEVERITY_NOTIFICATION, - 0, - nullptr, - juce::gl::GL_FALSE); - } - - if (juce::gl::glDebugMessageCallback) - juce::gl::glDebugMessageCallback(juceFilteredGLDebugCallback, - nullptr); - }, - true); - }).detach(); + // Linux: Use OpenGL for hardware acceleration if enabled + if (shouldUseOpenGL) { + DBG("[AbstractPluginEditor] Using Linux OpenGL renderer"); + openGLContext.setComponentPaintingEnabled(true); + openGLContext.setContinuousRepainting(false); + openGLContext.attachTo(*getTopLevelComponent()); + setupOpenGLContext(); + } else { + DBG("[AbstractPluginEditor] Using Linux software renderer"); + } } +#endif + setConstraints(baseWidth, baseHeight + headerHeight); setResizable(false, true); @@ -147,6 +144,11 @@ class AbstractPluginEditor detachCompositorForResize(); } + //============================================================================== + // Handle peer creation for Windows Direct2D setup + + void parentHierarchyChanged() override {} + //============================================================================== // JUCE overrides @@ -183,7 +185,7 @@ class AbstractPluginEditor { stopTimer(); attachCompositorAfterResize(); - repaint(); // TODO: Redundanr call, maybe remove this? + repaint(); // TODO: Redundant call, maybe remove this? } // Detach compositor to improve resize performance @@ -246,6 +248,49 @@ class AbstractPluginEditor } } + //============================================================================== + // OpenGL initialization + + void setupOpenGLContext() + { + std::thread([this]() { + for (int i = 0; i < 200; ++i) { + if (openGLContext.isAttached() && + openGLContext.getRawContext() != nullptr) + break; + std::this_thread::sleep_for(std::chrono::milliseconds(25)); + } + + if (!openGLContext.isAttached() || + openGLContext.getRawContext() == nullptr) + return; + + openGLContext.executeOnGLThread( + [](juce::OpenGLContext&) { +#if DMT_SUPPRESS_GL_DEBUG_MESSAGES + DBG("[AbstractPluginEditor] GL debug message suppression: ENABLED"); + // Suppress low-priority GL debug messages + if (juce::gl::glDebugMessageControl) { + juce::gl::glDebugMessageControl( + juce::gl::GL_DEBUG_SOURCE_API, + juce::gl::GL_DEBUG_TYPE_OTHER, + juce::gl::GL_DEBUG_SEVERITY_NOTIFICATION, + 0, + nullptr, + juce::gl::GL_FALSE); + } +#else + DBG("[AbstractPluginEditor] GL debug message suppression: DISABLED"); +#endif + // Set up callback for GL debug messages + if (juce::gl::glDebugMessageCallback) + juce::gl::glDebugMessageCallback(juceFilteredGLDebugCallback, + nullptr); + }, + true); + }).detach(); + } + //============================================================================== // OpenGL debug overwrite diff --git a/configuration/Options.h b/configuration/Options.h index 909d3c98..ca53bef3 100644 --- a/configuration/Options.h +++ b/configuration/Options.h @@ -55,12 +55,15 @@ getOptions() noexcept options.filenameSuffix = ".config"; options.storageFormat = juce::PropertiesFile::storeAsXML; - if constexpr (OS_IS_WINDOWS) { + if (OS_IS_WINDOWS) { options.folderName = juce::String("Dimethoxy/") + name; - } else if constexpr (OS_IS_DARWIN) { + } else if (OS_IS_DARWIN) { options.folderName = juce::String("Dimethoxy/") + name; - } else if constexpr (OS_IS_LINUX) { + } else if (OS_IS_LINUX) { options.folderName = juce::String(".config/Dimethoxy/") + name; + } else { + // What the hell is the OS? + options.folderName = juce::String("Dimethoxy/") + name; } options.osxLibrarySubFolder = "Application Support"; diff --git a/gui/component/SettingsEditorComponent.h b/gui/component/SettingsEditorComponent.h index 7f4f164b..a7bbe607 100644 --- a/gui/component/SettingsEditorComponent.h +++ b/gui/component/SettingsEditorComponent.h @@ -130,7 +130,7 @@ class SettingsEditor void onCategorySelectedCallback(TreeAdapter::Category& category) { TRACER("SettingsEditor::onCategorySelectedCallback"); - std::cout << "Selected category: " << category.name << std::endl; + valueEditorList.setCategory(category); valueEditorList.setOptimalSize(editorViewport.getWidth()); } diff --git a/gui/display/AbstractDisplay.h b/gui/display/AbstractDisplay.h index 46f868eb..34080e51 100644 --- a/gui/display/AbstractDisplay.h +++ b/gui/display/AbstractDisplay.h @@ -67,6 +67,8 @@ class AbstractDisplay // General using Display = dmt::Settings::Display; const juce::Colour& backgroundColour = Display::backgroundColour; + const juce::Colour& displayForegroundColour = + dmt::Settings::Panel::backgroundColour; // Layout const float& rawCornerSize = Display::cornerSize; @@ -121,26 +123,22 @@ class AbstractDisplay // Precalculation const auto borderStrength = rawBorderStrength * size; const auto cornerSize = rawCornerSize * size; + const auto padding = rawPadding * size; const float outerCornerSize = cornerSize; const float innerCornerSize = std::clamp( outerCornerSize - (borderStrength * 0.5f), 0.0f, outerCornerSize); - // Draw background if border is disabled - if (!drawBorder) { - _g.setColour(backgroundColour); - _g.fillRoundedRectangle(outerBounds.toFloat(), outerCornerSize); - } + // Draw background + _g.setColour(backgroundColour); + _g.fillRoundedRectangle(innerBounds.toFloat(), innerCornerSize); - // Draw background and border if border is enabled - if (drawBorder) { - _g.setColour(borderColour); - _g.fillRoundedRectangle(outerBounds.toFloat(), outerCornerSize); - _g.setColour(backgroundColour); - _g.fillRoundedRectangle(innerBounds.toFloat(), innerCornerSize); - } // Draw display paintDisplay(_g, innerBounds); + // Draw outer background to hide display overdraw + _g.setColour(displayForegroundColour); + _g.drawRect(getLocalBounds().toFloat(), padding); + // We need to draw the border again because drawing it once didn't cut it if (drawBorder) { _g.setColour(borderColour); diff --git a/utility/Settings.h b/utility/Settings.h index 40142f41..029aeb44 100644 --- a/utility/Settings.h +++ b/utility/Settings.h @@ -39,21 +39,21 @@ // OS constexprs set by CMake preprocessor definitions #if defined(CMAKE_OS_IS_WINDOWS) && CMAKE_OS_IS_WINDOWS -static constexpr bool OS_IS_WINDOWS = true; +#define OS_IS_WINDOWS 1 #else -static constexpr bool OS_IS_WINDOWS = false; +#define OS_IS_WINDOWS 0 #endif #if defined(CMAKE_OS_IS_DARWIN) && CMAKE_OS_IS_DARWIN -static constexpr bool OS_IS_DARWIN = true; +#define OS_IS_DARWIN 1 #else -static constexpr bool OS_IS_DARWIN = false; +#define OS_IS_DARWIN 0 #endif #if defined(CMAKE_OS_IS_LINUX) && CMAKE_OS_IS_LINUX -static constexpr bool OS_IS_LINUX = true; +#define OS_IS_LINUX 1 #else -static constexpr bool OS_IS_LINUX = false; +#define OS_IS_LINUX 0 #endif static_assert( @@ -125,9 +125,16 @@ struct Settings static inline auto& debugGrid = container.add("General.ShowDebugGrid", false); static inline auto& displayUpdateNotifications = - container.add("General.DisplayUpdateNotifications", true); + container.add("General.DisplayUpdateNotifications", false); static inline auto& themeVersion = container.add("General.ThemeVersion", 2); +#if OS_IS_LINUX + static inline auto& useOpenGL = + container.add("General.UseOpenGL", true); +#elif OS_IS_DARWIN + static inline auto& useOpenGL = + container.add("General.UseOpenGL", false); +#endif private: //============================================================================== @@ -427,9 +434,9 @@ struct Settings static inline auto& fontColour = container.add("Button.FontColour", Colours::font); static inline auto& hoverColour = - container.add("Button.HoverColour", Colours::primary); + container.add("Button.HoverColour", Colours::font); static inline auto& clickColour = - container.add("Button.ClickColour", Colours::font); + container.add("Button.ClickColour", Colours::primary); static inline auto& outerShadowRadius = container.add("Button.OuterShadowRadius", 5.0f); static inline auto& innerShadowRadius = @@ -473,9 +480,9 @@ struct Settings static inline auto& innerShadowColour = container.add("Panel.InnerShadowColour", Colours::shadow); static inline auto& outerShadowRadius = - container.add("Panel.OuterShadowRadius", 10.0f); + container.add("Panel.OuterShadowRadius", 5.0f); static inline auto& innerShadowRadius = - container.add("Panel.InnerShadowRadius", 10.0f); + container.add("Panel.InnerShadowRadius", 5.0f); static inline auto& fontColor = container.add("Panel.FontColor", Colours::font); static inline auto& fontSize = From 2d6a41463775d074c5080bcdf41e1c865d994b7c Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Tue, 5 May 2026 21:31:49 +0200 Subject: [PATCH 40/74] refactor: improve scale factor retrieval in Scaleable class --- src/dmt/utility/Scaleable.h | 75 +++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 36 deletions(-) diff --git a/src/dmt/utility/Scaleable.h b/src/dmt/utility/Scaleable.h index 47c4b1cb..fdd594ac 100644 --- a/src/dmt/utility/Scaleable.h +++ b/src/dmt/utility/Scaleable.h @@ -215,23 +215,52 @@ class Scaleable : public IScaleable */ [[nodiscard]] float getScaleFactor() const noexcept { - // TODO: Component Scale factor is fucked, for now we just use the main - // display's scale factor using the fallback - /* - const auto* component = static_cast(getSelf()); - if (component != nullptr) { - const auto componentScale = - juce::Component::getApproximateScaleFactorForComponent(component); + const auto* comp = static_cast(getSelf()); - if (std::isfinite(componentScale) && componentScale > 0.0f) - return componentScale; + // Try to get the scale factor from the host peer + if (comp != nullptr) { + if (auto* peer = comp->getPeer()) + return peer->getPlatformScaleFactor(); } - */ + // Fallback to desktop scale factor return getFallbackScaleFactor(); } + //============================================================================ + /** + * @brief Get a fallback platform DPI scaling factor. + * + * Used when the component is not yet attached to a hierarchy. + */ + static float getFallbackScaleFactor( + const juce::Component* comp = nullptr) noexcept + { + auto& displays = juce::Desktop::getInstance().getDisplays(); + + // 1. Try to resolve display from component position (BEST fallback) + if (comp != nullptr) { + const auto screenPos = comp->getScreenPosition(); + + if (auto* d = displays.getDisplayForPoint(screenPos)) { + const auto s = static_cast(d->scale); + if (std::isfinite(s) && s > 0.0f) + return s; + } + } + + // 2. Fallback to primary display (ok, but not always correct in DAWs) + if (auto* primary = displays.getPrimaryDisplay()) { + const auto s = static_cast(primary->scale); + if (std::isfinite(s) && s > 0.0f) + return s; + } + + // 3. Absolute safety fallback (if everything else fails) + return 1.0f; + } + private: //============================================================================ /** @@ -248,32 +277,6 @@ class Scaleable : public IScaleable return static_cast(this); } - //============================================================================ - /** - * @brief Get a fallback platform DPI scaling factor. - * - * Used when the component is not yet attached to a hierarchy. - */ - static float getFallbackScaleFactor() noexcept - { - // Find the main display - auto* mainDisplay = - juce::Desktop::getInstance().getDisplays().getPrimaryDisplay(); - - if (mainDisplay == nullptr) { - jassertfalse; // Could not find main display - return 1.0f; - } - - // Get the scale factor from the main display - const auto fallbackScale = static_cast(mainDisplay->scale); - - if (std::isfinite(fallbackScale) && fallbackScale > 0.0f) - return fallbackScale; - - return 1.0f; - } - /** * @brief Set the scaling factor for this component. * From b0e6ac0c91fa25b517679dd643ef5808af2c4e70 Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Tue, 5 May 2026 22:48:52 +0200 Subject: [PATCH 41/74] refactor: enhance scale factor retrieval logic in Scaleable class --- src/dmt/utility/Scaleable.h | 55 ++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/src/dmt/utility/Scaleable.h b/src/dmt/utility/Scaleable.h index fdd594ac..0e4f17d3 100644 --- a/src/dmt/utility/Scaleable.h +++ b/src/dmt/utility/Scaleable.h @@ -217,47 +217,52 @@ class Scaleable : public IScaleable { const auto* comp = static_cast(getSelf()); + auto& displays = juce::Desktop::getInstance().getDisplays(); - // Try to get the scale factor from the host peer + // 1. Try to get the scale factor from the host peer + float hostScale = -1.0f; if (comp != nullptr) { if (auto* peer = comp->getPeer()) - return peer->getPlatformScaleFactor(); + hostScale = peer->getPlatformScaleFactor(); } - // Fallback to desktop scale factor - return getFallbackScaleFactor(); - } - - //============================================================================ - /** - * @brief Get a fallback platform DPI scaling factor. - * - * Used when the component is not yet attached to a hierarchy. - */ - static float getFallbackScaleFactor( - const juce::Component* comp = nullptr) noexcept - { - auto& displays = juce::Desktop::getInstance().getDisplays(); + // 2. Try to get the scale factor from the component itself + float componentScale = -1.0f; + if (component != nullptr) { + componentScale = + juce::Component::getApproximateScaleFactorForComponent(component); + } - // 1. Try to resolve display from component position (BEST fallback) + // 3. Try to resolve display from component position + float displayScale = -1.0f; if (comp != nullptr) { const auto screenPos = comp->getScreenPosition(); if (auto* d = displays.getDisplayForPoint(screenPos)) { - const auto s = static_cast(d->scale); - if (std::isfinite(s) && s > 0.0f) - return s; + displayScale = static_cast(d->scale); } } - // 2. Fallback to primary display (ok, but not always correct in DAWs) + // 4. Fallback to primary display (ok, but not always correct in DAWs) + float primaryScale = -1.0f; if (auto* primary = displays.getPrimaryDisplay()) { - const auto s = static_cast(primary->scale); - if (std::isfinite(s) && s > 0.0f) - return s; + primaryScale = static_cast(primary->scale); } - // 3. Absolute safety fallback (if everything else fails) + // Heuristic: if any any is greater 1 we most likely wanna use it + if (hostScale > 1.0f) + return hostScale; + + if (componentScale > 1.0f) + return componentScale; + + if (displayScale > 1.0f) + return displayScale; + + if (primaryScale > 1.0f) + return primaryScale; + + // If none is greater than 1, just return 1 (no scaling) return 1.0f; } From eb212d6cd0c21543ead325d376d3c7c20e68e150 Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Tue, 5 May 2026 23:03:20 +0200 Subject: [PATCH 42/74] refactor: rename variable for clarity in getScaleFactor method --- src/dmt/utility/Scaleable.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/dmt/utility/Scaleable.h b/src/dmt/utility/Scaleable.h index 0e4f17d3..eb125237 100644 --- a/src/dmt/utility/Scaleable.h +++ b/src/dmt/utility/Scaleable.h @@ -216,13 +216,13 @@ class Scaleable : public IScaleable [[nodiscard]] float getScaleFactor() const noexcept { - const auto* comp = static_cast(getSelf()); + const auto* component = static_cast(getSelf()); auto& displays = juce::Desktop::getInstance().getDisplays(); // 1. Try to get the scale factor from the host peer float hostScale = -1.0f; - if (comp != nullptr) { - if (auto* peer = comp->getPeer()) + if (component != nullptr) { + if (auto* peer = component->getPeer()) hostScale = peer->getPlatformScaleFactor(); } @@ -235,15 +235,15 @@ class Scaleable : public IScaleable // 3. Try to resolve display from component position float displayScale = -1.0f; - if (comp != nullptr) { - const auto screenPos = comp->getScreenPosition(); + if (component != nullptr) { + const auto screenPos = component->getScreenPosition(); if (auto* d = displays.getDisplayForPoint(screenPos)) { displayScale = static_cast(d->scale); } } - // 4. Fallback to primary display (ok, but not always correct in DAWs) + // 4. Fallback to primary display float primaryScale = -1.0f; if (auto* primary = displays.getPrimaryDisplay()) { primaryScale = static_cast(primary->scale); From e75b6ba97d619c93d0b82c84d5cf3d3ee6fb7ee4 Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Tue, 5 May 2026 23:30:51 +0200 Subject: [PATCH 43/74] fix: improve hidpi scale factor detection for the 9th million time --- src/dmt/utility/Scaleable.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/dmt/utility/Scaleable.h b/src/dmt/utility/Scaleable.h index eb125237..356a7b72 100644 --- a/src/dmt/utility/Scaleable.h +++ b/src/dmt/utility/Scaleable.h @@ -249,17 +249,19 @@ class Scaleable : public IScaleable primaryScale = static_cast(primary->scale); } - // Heuristic: if any any is greater 1 we most likely wanna use it - if (hostScale > 1.0f) + // Very hacky heuristic to determine the most likely correct scale factor + using juce::approximatelyEqual(); + + if (!approximatelyEqual(hostScale, 1.0f) && hostScale > 0.0f) return hostScale; - if (componentScale > 1.0f) + if (!approximatelyEqual(componentScale, 1.0f) && componentScale > 0.0f) return componentScale; - if (displayScale > 1.0f) + if (!approximatelyEqual(displayScale, 1.0f) && displayScale > 0.0f) return displayScale; - if (primaryScale > 1.0f) + if (!approximatelyEqual(primaryScale, 1.0f) && primaryScale > 0.0f) return primaryScale; // If none is greater than 1, just return 1 (no scaling) From 57b26b74944b5b504f1883593333e7b5447d015b Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Tue, 5 May 2026 23:47:13 +0200 Subject: [PATCH 44/74] fix: typo --- src/dmt/utility/Scaleable.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dmt/utility/Scaleable.h b/src/dmt/utility/Scaleable.h index 356a7b72..7e610ac9 100644 --- a/src/dmt/utility/Scaleable.h +++ b/src/dmt/utility/Scaleable.h @@ -250,7 +250,7 @@ class Scaleable : public IScaleable } // Very hacky heuristic to determine the most likely correct scale factor - using juce::approximatelyEqual(); + using juce::approximatelyEqual; if (!approximatelyEqual(hostScale, 1.0f) && hostScale > 0.0f) return hostScale; From be24273f45ca2d56ebbf2fdcd8959add5c6f07ff Mon Sep 17 00:00:00 2001 From: David Hess Date: Wed, 6 May 2026 17:08:29 +0200 Subject: [PATCH 45/74] fix: properly destruct OscilloscopeDisplay and remove parameter listeners --- .vscode/launch.json | 2 +- src/dmt/gui/display/OscilloscopeDisplay.h | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index a015b0cb..28ec4e92 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -47,7 +47,7 @@ "name": "Launch FL Studio (Windows)", "type": "cppvsdbg", "request": "launch", - "program": "C:\\Program Files\\Image-Line\\FL Studio 2024\\FL64.exe", + "program": "C:\\Program Files\\Image-Line\\FL Studio 2025\\FL64.exe", "args": [], "stopAtEntry": false, "cwd": "${workspaceFolder}", diff --git a/src/dmt/gui/display/OscilloscopeDisplay.h b/src/dmt/gui/display/OscilloscopeDisplay.h index bf6866e4..a3992377 100644 --- a/src/dmt/gui/display/OscilloscopeDisplay.h +++ b/src/dmt/gui/display/OscilloscopeDisplay.h @@ -101,6 +101,18 @@ class OscilloscopeDisplay setHeight(dmt::Settings::Oscilloscope::defaultGain); } } + + ~OscilloscopeDisplay() override + { + // Remove parameter listeners + if (!useDefaultSettings) { + // Assuming you have access to the AudioProcessorValueTreeState instance + // here, you would remove the listeners. This is just a placeholder. + _apvts.removeParameterListener("OscilloscopeZoom", this); + _apvts.removeParameterListener("OscilloscopeThickness", this); + _apvts.removeParameterListener("OscilloscopeGain", this); + } + } //============================================================================== void extendResized( const juce::Rectangle& _displayBounds) noexcept override From 28d2765f825c919f8ce8b5b0dbebf4b57efadedf Mon Sep 17 00:00:00 2001 From: David Hess Date: Wed, 6 May 2026 17:21:20 +0200 Subject: [PATCH 46/74] fix: not saving APVTS reference in OscilloscopeDisplay constructor --- src/dmt/gui/display/OscilloscopeDisplay.h | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/dmt/gui/display/OscilloscopeDisplay.h b/src/dmt/gui/display/OscilloscopeDisplay.h index a3992377..6d8592b3 100644 --- a/src/dmt/gui/display/OscilloscopeDisplay.h +++ b/src/dmt/gui/display/OscilloscopeDisplay.h @@ -84,16 +84,17 @@ class OscilloscopeDisplay OscilloscopeDisplay(FifoAudioBuffer& _fifoBuffer, AudioProcessorValueTreeState& _apvts, bool _useDefaultSettings = false) - : ringBuffer(2, 4096) + : apvts(_apvts) + , ringBuffer(2, 4096) , fifoBuffer(_fifoBuffer) , leftOscilloscope(ringBuffer, 0, size) , rightOscilloscope(ringBuffer, 1, size) , useDefaultSettings(_useDefaultSettings) { if (!useDefaultSettings) { - _apvts.addParameterListener("OscilloscopeZoom", this); - _apvts.addParameterListener("OscilloscopeThickness", this); - _apvts.addParameterListener("OscilloscopeGain", this); + apvts.addParameterListener("OscilloscopeZoom", this); + apvts.addParameterListener("OscilloscopeThickness", this); + apvts.addParameterListener("OscilloscopeGain", this); } else { // Use default values from dmt::Settings::Oscilloscope setZoom(dmt::Settings::Oscilloscope::defaultZoom); @@ -108,9 +109,9 @@ class OscilloscopeDisplay if (!useDefaultSettings) { // Assuming you have access to the AudioProcessorValueTreeState instance // here, you would remove the listeners. This is just a placeholder. - _apvts.removeParameterListener("OscilloscopeZoom", this); - _apvts.removeParameterListener("OscilloscopeThickness", this); - _apvts.removeParameterListener("OscilloscopeGain", this); + apvts.removeParameterListener("OscilloscopeZoom", this); + apvts.removeParameterListener("OscilloscopeThickness", this); + apvts.removeParameterListener("OscilloscopeGain", this); } } //============================================================================== @@ -268,11 +269,13 @@ class OscilloscopeDisplay } //============================================================================== private: + AudioProcessorValueTreeState& apvts; RingAudioBuffer ringBuffer; FifoAudioBuffer& fifoBuffer; Oscilloscope leftOscilloscope; Oscilloscope rightOscilloscope; bool useDefaultSettings; + //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(OscilloscopeDisplay) From f0df2fa8a142a49d1a4b20cf77d69da460b74180 Mon Sep 17 00:00:00 2001 From: David Hess Date: Wed, 6 May 2026 22:03:53 +0200 Subject: [PATCH 47/74] fix: add symbolSearchPath for FL Studio launch configuration --- .vscode/launch.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 28ec4e92..bf286a9c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -52,7 +52,8 @@ "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], - "console": "internalConsole" + "console": "internalConsole", + "symbolSearchPath": "C:\\Program Files\\Common Files\\VST3\\Dimethoxy\\Disflux" }, { "name": "Launch Bitwig Studio (Linux)", From b413deb0c0bbb7504149261244c7e84701198111 Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Thu, 7 May 2026 12:02:59 +0200 Subject: [PATCH 48/74] fix: add JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR to multiple classes --- external/juce | 2 +- src/dmt/configuration/Properties.h | 2 ++ src/dmt/dsp/effect/DisfluxProcessor.h | 2 ++ src/dmt/dsp/effect/Distortion.h | 2 ++ src/dmt/dsp/effect/HeretikProcessor.h | 2 ++ src/dmt/dsp/effect/LowpassProcessor.h | 2 ++ src/dmt/dsp/effect/NeutrinoProcessor.h | 2 ++ src/dmt/dsp/envelope/AdhEnvelope.h | 2 ++ src/dmt/dsp/synth/DigitalOscillator.h | 2 ++ src/dmt/dsp/synth/DigitalWaveform.h | 2 ++ src/dmt/dsp/synth/NeutrinoSynthVoice.h | 2 ++ src/dmt/dsp/synth/SynthSound.h | 2 ++ src/dmt/gui/component/AbstractSliderComponent.h | 2 ++ src/dmt/gui/preset/FolderManager.h | 2 ++ src/dmt/gui/preset/PresetManager.h | 2 ++ src/dmt/gui/widget/MinMaxRenderer.h | 2 ++ src/dmt/gui/widget/OscilloscopeRenderer.h | 2 ++ src/dmt/gui/widget/PathStrokeRenderer.h | 2 ++ src/dmt/gui/window/Layout.h | 2 ++ src/dmt/utility/HostContextMenu.h | 2 ++ 20 files changed, 39 insertions(+), 1 deletion(-) diff --git a/external/juce b/external/juce index 29396c22..501c0767 160000 --- a/external/juce +++ b/external/juce @@ -1 +1 @@ -Subproject commit 29396c22c93392d6738e021b83196283d6e4d850 +Subproject commit 501c07674e1ad693085a7e7c398f205c2677f5da diff --git a/src/dmt/configuration/Properties.h b/src/dmt/configuration/Properties.h index 45f37550..08b3944c 100644 --- a/src/dmt/configuration/Properties.h +++ b/src/dmt/configuration/Properties.h @@ -203,6 +203,8 @@ class Properties private: juce::ApplicationProperties file; juce::PropertySet fallbackPropertySet; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Properties) }; } // namespace configuration } // namespace dmt \ No newline at end of file diff --git a/src/dmt/dsp/effect/DisfluxProcessor.h b/src/dmt/dsp/effect/DisfluxProcessor.h index 33ab1884..fd27ff41 100644 --- a/src/dmt/dsp/effect/DisfluxProcessor.h +++ b/src/dmt/dsp/effect/DisfluxProcessor.h @@ -317,6 +317,8 @@ class alignas(64) DisfluxProcessor juce::IIRFilter outputHighpassLeft; juce::IIRFilter outputHighpassRight; float lastHighpassFrequency = -1.0f; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(DisfluxProcessor) }; //============================================================================== diff --git a/src/dmt/dsp/effect/Distortion.h b/src/dmt/dsp/effect/Distortion.h index 93c16c03..a1fdfdbb 100644 --- a/src/dmt/dsp/effect/Distortion.h +++ b/src/dmt/dsp/effect/Distortion.h @@ -354,6 +354,8 @@ struct alignas(64) Distortion } } } + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Distortion) }; //============================================================================== diff --git a/src/dmt/dsp/effect/HeretikProcessor.h b/src/dmt/dsp/effect/HeretikProcessor.h index f86e3b77..e1d15506 100644 --- a/src/dmt/dsp/effect/HeretikProcessor.h +++ b/src/dmt/dsp/effect/HeretikProcessor.h @@ -160,6 +160,8 @@ class alignas(64) HeretikProcessor std::array feedbackBuffer; Filter leftFilter; Filter rightFilter; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(HeretikProcessor) }; //============================================================================== diff --git a/src/dmt/dsp/effect/LowpassProcessor.h b/src/dmt/dsp/effect/LowpassProcessor.h index 9e1eccb2..7fe5227d 100644 --- a/src/dmt/dsp/effect/LowpassProcessor.h +++ b/src/dmt/dsp/effect/LowpassProcessor.h @@ -262,6 +262,8 @@ class alignas(64) LowpassProcessor // They do the actual filtering of the audio. FilterArray leftFilters; FilterArray rightFilters; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(LowpassProcessor) }; //============================================================================== diff --git a/src/dmt/dsp/effect/NeutrinoProcessor.h b/src/dmt/dsp/effect/NeutrinoProcessor.h index cb1f2da3..5acb9fd3 100644 --- a/src/dmt/dsp/effect/NeutrinoProcessor.h +++ b/src/dmt/dsp/effect/NeutrinoProcessor.h @@ -97,6 +97,8 @@ class alignas(64) NeutrinoProcessor juce::Synthesiser synth; juce::AudioProcessorValueTreeState& apvts; float sampleRate = -1.0f; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NeutrinoProcessor) }; //============================================================================== diff --git a/src/dmt/dsp/envelope/AdhEnvelope.h b/src/dmt/dsp/envelope/AdhEnvelope.h index f37bfb47..cbe50e5e 100644 --- a/src/dmt/dsp/envelope/AdhEnvelope.h +++ b/src/dmt/dsp/envelope/AdhEnvelope.h @@ -235,6 +235,8 @@ class AhdEnvelope float sampleRate = -1.0f; Parameters params; size_t sampleIndex = 0; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(AhdEnvelope) }; //============================================================================== diff --git a/src/dmt/dsp/synth/DigitalOscillator.h b/src/dmt/dsp/synth/DigitalOscillator.h index ee551dde..72ff816c 100644 --- a/src/dmt/dsp/synth/DigitalOscillator.h +++ b/src/dmt/dsp/synth/DigitalOscillator.h @@ -349,6 +349,8 @@ class alignas(64) DigitalOscillator float sampleRate = -1.0f; float phase = 0.0f; float pwmEndSample = 0.0f; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(DigitalOscillator) //============================================================================== }; } // namespace synth diff --git a/src/dmt/dsp/synth/DigitalWaveform.h b/src/dmt/dsp/synth/DigitalWaveform.h index c3408776..c5ad8cf2 100644 --- a/src/dmt/dsp/synth/DigitalWaveform.h +++ b/src/dmt/dsp/synth/DigitalWaveform.h @@ -142,6 +142,8 @@ struct DigitalWaveform } //============================================================================== + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(DigitalWaveform) }; //============================================================================== diff --git a/src/dmt/dsp/synth/NeutrinoSynthVoice.h b/src/dmt/dsp/synth/NeutrinoSynthVoice.h index d93cc742..b4b6336f 100644 --- a/src/dmt/dsp/synth/NeutrinoSynthVoice.h +++ b/src/dmt/dsp/synth/NeutrinoSynthVoice.h @@ -306,6 +306,8 @@ class alignas(64) NeutrinoSynthVoice : public juce::SynthesiserVoice int note = 0; bool isPrepared = false; std::vector> onNoteReceivers; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(NeutrinoSynthVoice) }; //============================================================================== diff --git a/src/dmt/dsp/synth/SynthSound.h b/src/dmt/dsp/synth/SynthSound.h index a9bd8c27..8144766b 100644 --- a/src/dmt/dsp/synth/SynthSound.h +++ b/src/dmt/dsp/synth/SynthSound.h @@ -48,6 +48,8 @@ class SynthSound : public juce::SynthesiserSound //============================================================================== bool appliesToNote [[nodiscard]] (int) noexcept override { return true; } bool appliesToChannel [[nodiscard]] (int) noexcept override { return true; } + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(SynthSound) }; //============================================================================== diff --git a/src/dmt/gui/component/AbstractSliderComponent.h b/src/dmt/gui/component/AbstractSliderComponent.h index d9ee4b12..8734ad8d 100644 --- a/src/dmt/gui/component/AbstractSliderComponent.h +++ b/src/dmt/gui/component/AbstractSliderComponent.h @@ -138,6 +138,8 @@ class AbstractSliderComponent Label infoLabel; Unit::Type unitType; Fonts fonts; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(AbstractSliderComponent) }; } // namespace component diff --git a/src/dmt/gui/preset/FolderManager.h b/src/dmt/gui/preset/FolderManager.h index 29076b95..88e977b0 100644 --- a/src/dmt/gui/preset/FolderManager.h +++ b/src/dmt/gui/preset/FolderManager.h @@ -69,6 +69,8 @@ class FolderManager : juce::ValueTree::Listener juce::AudioProcessorValueTreeState& valueTreeState; juce::StringArray folderList; juce::Value currentFolder; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(FolderManager) }; } // namespace preset } // namespace gui diff --git a/src/dmt/gui/preset/PresetManager.h b/src/dmt/gui/preset/PresetManager.h index 1548b800..758a4829 100644 --- a/src/dmt/gui/preset/PresetManager.h +++ b/src/dmt/gui/preset/PresetManager.h @@ -182,6 +182,8 @@ class PresetManager : juce::ValueTree::Listener //============================================================================== juce::AudioProcessorValueTreeState& valueTreeState; juce::Value currentPreset; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PresetManager) }; } // namespace preset } // namespace gui diff --git a/src/dmt/gui/widget/MinMaxRenderer.h b/src/dmt/gui/widget/MinMaxRenderer.h index 92f40485..accce091 100644 --- a/src/dmt/gui/widget/MinMaxRenderer.h +++ b/src/dmt/gui/widget/MinMaxRenderer.h @@ -258,6 +258,8 @@ class MinMaxRenderer : public OscilloscopeRenderer return path; } + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(MinMaxRenderer) }; } // namespace widget diff --git a/src/dmt/gui/widget/OscilloscopeRenderer.h b/src/dmt/gui/widget/OscilloscopeRenderer.h index 11cf9341..dcfc70e1 100644 --- a/src/dmt/gui/widget/OscilloscopeRenderer.h +++ b/src/dmt/gui/widget/OscilloscopeRenderer.h @@ -184,6 +184,8 @@ class OscilloscopeRenderer /** Current X position with sub-pixel precision for visual continuity. */ float currentX = 0.0f; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(OscilloscopeRenderer) }; } // namespace widget diff --git a/src/dmt/gui/widget/PathStrokeRenderer.h b/src/dmt/gui/widget/PathStrokeRenderer.h index 0f41570a..6decb29c 100644 --- a/src/dmt/gui/widget/PathStrokeRenderer.h +++ b/src/dmt/gui/widget/PathStrokeRenderer.h @@ -130,6 +130,8 @@ class PathStrokeRenderer : public OscilloscopeRenderer return path; } + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PathStrokeRenderer) }; } // namespace widget diff --git a/src/dmt/gui/window/Layout.h b/src/dmt/gui/window/Layout.h index a72773e2..359b54a9 100644 --- a/src/dmt/gui/window/Layout.h +++ b/src/dmt/gui/window/Layout.h @@ -134,6 +134,8 @@ class Layout : public juce::Component PanelSpanList panelSpans; GridSeparatorLayout columnSeparators; GridSeparatorLayout rowSeparators; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Layout) }; } // namespace window diff --git a/src/dmt/utility/HostContextMenu.h b/src/dmt/utility/HostContextMenu.h index b48e5cd5..179b6ffb 100644 --- a/src/dmt/utility/HostContextMenu.h +++ b/src/dmt/utility/HostContextMenu.h @@ -146,5 +146,7 @@ class HostContextMenu jassertfalse; // Could not find the editor in the hierarchy return nullptr; } + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(HostContextMenu) }; } // namespace dmt \ No newline at end of file From 48b355d38467a42251290a9b41d20d9446794676 Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Thu, 7 May 2026 12:23:17 +0200 Subject: [PATCH 49/74] feat: add opt-in sanitizer support and documentation for Windows builds Co-authored-by: Copilot --- CMakeLists.txt | 3 + CMakePresets.json | 88 +++++++++++++++++++ cmake/Sanitizers.cmake | 70 +++++++++++++++ docs/windows-crash-debugging.md | 150 ++++++++++++++++++++++++++++++++ external/juce | 2 +- src/CMakeLists.txt | 3 + 6 files changed, 315 insertions(+), 1 deletion(-) create mode 100644 cmake/Sanitizers.cmake create mode 100644 docs/windows-crash-debugging.md diff --git a/CMakeLists.txt b/CMakeLists.txt index babd942b..df5fdb5b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,6 +10,9 @@ set(CMAKE_CXX_STANDARD 23) set(CMAKE_SUPPRESS_DEVELOPER_WARNINGS TRUE) set(EXT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external) +# Sanitizer helpers are opt-in through presets (DMT_ENABLE_ASAN / DMT_ENABLE_UBSAN) +include(${CMAKE_CURRENT_LIST_DIR}/cmake/Sanitizers.cmake) + # Set macOS deployment target for older macOS compatibility include(cmake/get_cpm.cmake) diff --git a/CMakePresets.json b/CMakePresets.json index 01c4ab2c..14c3ed41 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -70,6 +70,94 @@ "rhs": "Windows" } }, + { + "name": "Windows ASan", + "hidden": false, + "description": "Debug + AddressSanitizer (MSVC cl)", + "generator": "Ninja", + "binaryDir": "${sourceDir}/build/windows-asan", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_C_COMPILER": "cl", + "CMAKE_CXX_COMPILER": "cl", + "DMT_ENABLE_ASAN": "ON" + }, + "environment": { + "CC": "cl", + "CXX": "cl" + }, + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Windows" + } + }, + { + "name": "Windows RelWithDebInfo ASan", + "hidden": false, + "description": "RelWithDebInfo + AddressSanitizer (MSVC cl)", + "generator": "Ninja", + "binaryDir": "${sourceDir}/build/windows-relwithdebinfo-asan", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "RelWithDebInfo", + "CMAKE_C_COMPILER": "cl", + "CMAKE_CXX_COMPILER": "cl", + "DMT_ENABLE_ASAN": "ON" + }, + "environment": { + "CC": "cl", + "CXX": "cl" + }, + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Windows" + } + }, + { + "name": "Windows Clang ASan", + "hidden": false, + "description": "Debug + AddressSanitizer (clang-cl, if installed)", + "generator": "Ninja", + "binaryDir": "${sourceDir}/build/windows-clang-asan", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_C_COMPILER": "clang-cl", + "CMAKE_CXX_COMPILER": "clang-cl", + "DMT_ENABLE_ASAN": "ON" + }, + "environment": { + "CC": "clang-cl", + "CXX": "clang-cl" + }, + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Windows" + } + }, + { + "name": "Windows Clang UBSan", + "hidden": false, + "description": "Debug + UndefinedBehaviorSanitizer (clang-cl, if installed)", + "generator": "Ninja", + "binaryDir": "${sourceDir}/build/windows-clang-ubsan", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_C_COMPILER": "clang-cl", + "CMAKE_CXX_COMPILER": "clang-cl", + "DMT_ENABLE_UBSAN": "ON" + }, + "environment": { + "CC": "clang-cl", + "CXX": "clang-cl" + }, + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Windows" + } + }, { "name": "Mac Debug", "hidden": false, diff --git a/cmake/Sanitizers.cmake b/cmake/Sanitizers.cmake new file mode 100644 index 00000000..a1558a44 --- /dev/null +++ b/cmake/Sanitizers.cmake @@ -0,0 +1,70 @@ +#============================================================================== +# Opt-in sanitizer and debug-symbol configuration. +# This module is intentionally target-scoped so normal builds are untouched. +#============================================================================== + +option(DMT_ENABLE_ASAN "Enable AddressSanitizer for selected targets" OFF) +option(DMT_ENABLE_UBSAN "Enable UndefinedBehaviorSanitizer for selected targets" OFF) + +function(dmt_target_enable_sanitizers target_name) + if(NOT TARGET ${target_name}) + message(FATAL_ERROR "dmt_target_enable_sanitizers: unknown target '${target_name}'") + endif() + + if(NOT (DMT_ENABLE_ASAN OR DMT_ENABLE_UBSAN)) + return() + endif() + + target_compile_definitions(${target_name} PRIVATE DMT_SANITIZERS_ENABLED=1) + + # MSVC cl.exe: supports ASan on modern toolsets, but not UBSan. + if(MSVC AND NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + if(DMT_ENABLE_UBSAN) + message(WARNING "DMT_ENABLE_UBSAN is not supported with MSVC cl; ignoring UBSan for ${target_name}") + endif() + + if(DMT_ENABLE_ASAN) + target_compile_options(${target_name} PRIVATE /fsanitize=address) + target_link_options(${target_name} PRIVATE /fsanitize=address) + endif() + + # Symbol and stack quality for debugger + sanitizer crash reports. + target_compile_options(${target_name} PRIVATE /Zi /Oy-) + target_link_options(${target_name} PRIVATE /DEBUG /INCREMENTAL:NO) + return() + endif() + + # Clang/GCC style sanitizers (including clang-cl frontend). + set(enabled_sanitizers "") + if(DMT_ENABLE_ASAN) + list(APPEND enabled_sanitizers address) + endif() + if(DMT_ENABLE_UBSAN) + list(APPEND enabled_sanitizers undefined) + endif() + + if(NOT enabled_sanitizers) + return() + endif() + + string(JOIN "," sanitizer_arg ${enabled_sanitizers}) + + target_compile_options(${target_name} + PRIVATE + -fsanitize=${sanitizer_arg} + -fno-omit-frame-pointer + ) + + target_link_options(${target_name} + PRIVATE + -fsanitize=${sanitizer_arg} + ) + + if(WIN32) + # Keep PDB/debugger quality high on Windows clang/clang-cl presets. + target_compile_options(${target_name} PRIVATE /Zi /Oy-) + target_link_options(${target_name} PRIVATE /DEBUG /INCREMENTAL:NO) + else() + target_compile_options(${target_name} PRIVATE -g) + endif() +endfunction() diff --git a/docs/windows-crash-debugging.md b/docs/windows-crash-debugging.md new file mode 100644 index 00000000..1c50bf49 --- /dev/null +++ b/docs/windows-crash-debugging.md @@ -0,0 +1,150 @@ +# Windows Crash Debugging for Intermittent VST/Plugin Failures + +This guide focuses on Windows-only, hard-to-reproduce crashes in DAWs using the sanitizer presets added to this project. + +## Presets Added + +- Windows ASan +- Windows RelWithDebInfo ASan +- Windows Clang ASan (requires clang-cl) +- Windows Clang UBSan (requires clang-cl) + +These are isolated from your normal presets and use separate build directories. + +## Build from VS Code + +1. Open Command Palette. +2. Run `CMake: Select Configure Preset` and choose one of: + - `Windows ASan` + - `Windows RelWithDebInfo ASan` + - `Windows Clang ASan` + - `Windows Clang UBSan` +3. Run `CMake: Configure`. +4. Run `CMake: Build`. + +You can also use terminal commands: + +```powershell +cmake --preset "Windows ASan" +cmake --build build/windows-asan +``` + +```powershell +cmake --preset "Windows RelWithDebInfo ASan" +cmake --build build/windows-relwithdebinfo-asan +``` + +## Why These Flags Were Added + +Sanitizer builds enable these flags through `cmake/Sanitizers.cmake` only when `DMT_ENABLE_ASAN` or `DMT_ENABLE_UBSAN` is ON. + +- `/fsanitize=address` + - MSVC AddressSanitizer runtime. Detects use-after-free, heap buffer overflow, and related memory corruption. +- `-fsanitize=address` + - Clang equivalent of ASan. +- `-fsanitize=undefined` + - Clang UBSan runtime for undefined behavior checks. +- `-fno-omit-frame-pointer` + - Preserves frame pointers so crash call stacks remain useful. +- `/Zi` + - Produces full PDB debug information. +- `/DEBUG` + - Emits and links debug symbols into final binaries for debugger stack traces. +- `/Oy-` + - Disables frame-pointer omission on MSVC, improving stack-walk reliability. +- `/INCREMENTAL:NO` + - Reduces linker/debugger oddities in sanitizer-oriented sessions. + +## Attach Visual Studio Debugger to a DAW + +1. Start the DAW normally. +2. Open Visual Studio. +3. `Debug -> Attach to Process...` +4. Select your DAW process (for example `Ableton Live`, `Reaper`, `Cubase`, etc). +5. Ensure code type is Native. +6. Trigger plugin load/use scenario until crash reproduces. + +Tip: when possible, disable plugin sandboxing or run in-process for better stack visibility. + +## Enable First-Chance Exceptions + +In Visual Studio: + +1. Open `Debug -> Windows -> Exception Settings`. +2. Enable first-chance break for: + - Access violation (`0xC0000005`) + - Heap corruption (`0xC0000374`) + - C++ exceptions (as needed) +3. Reproduce crash. Break at first throw/fault, not at final DAW termination. + +## Page Heap (gflags) + +Enable full page heap for the DAW executable: + +```powershell +gflags /p /enable YourDAW.exe /full +``` + +Check status: + +```powershell +gflags /p +``` + +Disable when done: + +```powershell +gflags /p /disable YourDAW.exe +``` + +Page Heap often turns silent heap corruption into deterministic early crashes. + +## Application Verifier + +1. Launch Application Verifier. +2. Add the DAW executable. +3. Enable checks, at minimum: + - Basics + - Heaps + - Handles + - Locks +4. Re-run the DAW under debugger and reproduce. + +Use with ASan for broader coverage across allocator, handle, and lock misuse. + +## Interpreting AddressSanitizer Reports + +Look for these report sections: + +- Error type (`heap-use-after-free`, `heap-buffer-overflow`, etc) +- Faulting address +- Access type (`READ` or `WRITE`) +- Stack at access site +- Stack at allocation site +- Stack at free site + +Prioritize fixes by matching: + +1. Free site owner +2. Last surviving owner assumptions +3. Cross-thread handoff paths (message thread vs audio thread) + +## Limitations and Tradeoffs + +- MSVC `cl`: + - ASan is available in modern toolsets. + - UBSan is not generally available like Clang UBSan. +- clang-cl: + - Supports both ASan and UBSan flags used here. + - Behavior may differ from MSVC ABI/runtime edge cases in DAW/plugin hosting. +- Sanitizers in DAWs: + - Some host/plugin combinations may be noisy or unsupported. + - Use a reproducible host/project pair first, then expand matrix. + +## Recommended Workflow + +1. Start with `Windows ASan` for best compatibility with existing MSVC flow. +2. Reproduce crash in a single DAW with debugger attached and first-chance exceptions enabled. +3. If issue remains unclear, enable Page Heap and Application Verifier. +4. If UB is suspected, try `Windows Clang UBSan`. +5. Keep Release builds unchanged for shipping validation. diff --git a/external/juce b/external/juce index 501c0767..29396c22 160000 --- a/external/juce +++ b/external/juce @@ -1 +1 @@ -Subproject commit 501c07674e1ad693085a7e7c398f205c2677f5da +Subproject commit 29396c22c93392d6738e021b83196283d6e4d850 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d79427e1..5a038198 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -122,6 +122,9 @@ target_link_libraries(${PROJECT_NAME} juce::juce_recommended_warning_flags ) + # Apply opt-in sanitizers and debug-symbol settings for crash diagnostics. + dmt_target_enable_sanitizers(${PROJECT_NAME}) + # Conditionally link curl only on Linux if(UNIX AND NOT APPLE) target_link_libraries(${PROJECT_NAME} From 9295a15622724369b371ced3c5697c8065b10174 Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Thu, 7 May 2026 12:57:10 +0200 Subject: [PATCH 50/74] fix: add default constructors to DigitalOscillator, DigitalWaveform, and SynthSound classes --- src/dmt/dsp/synth/DigitalOscillator.h | 4 ++++ src/dmt/dsp/synth/DigitalWaveform.h | 6 ++++++ src/dmt/dsp/synth/SynthSound.h | 2 ++ 3 files changed, 12 insertions(+) diff --git a/src/dmt/dsp/synth/DigitalOscillator.h b/src/dmt/dsp/synth/DigitalOscillator.h index 72ff816c..7d274e77 100644 --- a/src/dmt/dsp/synth/DigitalOscillator.h +++ b/src/dmt/dsp/synth/DigitalOscillator.h @@ -104,6 +104,10 @@ class alignas(64) DigitalOscillator //============================================================================== // Oscillator + + //============================================================================ + DigitalOscillator() = default; + public: inline void setParameters(const juce::AudioProcessorValueTreeState& apvts, String prefix) diff --git a/src/dmt/dsp/synth/DigitalWaveform.h b/src/dmt/dsp/synth/DigitalWaveform.h index c5ad8cf2..32253786 100644 --- a/src/dmt/dsp/synth/DigitalWaveform.h +++ b/src/dmt/dsp/synth/DigitalWaveform.h @@ -46,6 +46,12 @@ struct DigitalWaveform static constexpr float twoPi = juce::MathConstants::twoPi; static constexpr float pi = juce::MathConstants::pi; + //============================================================================ + /** + * @brief Construct a new Digital Waveform object + */ + DigitalWaveform() = default; + //============================================================================== /** * @brief Enumeration of waveform types. diff --git a/src/dmt/dsp/synth/SynthSound.h b/src/dmt/dsp/synth/SynthSound.h index 8144766b..f30d1d74 100644 --- a/src/dmt/dsp/synth/SynthSound.h +++ b/src/dmt/dsp/synth/SynthSound.h @@ -45,6 +45,8 @@ namespace synth { class SynthSound : public juce::SynthesiserSound { public: + SynthSound() = default; + //============================================================================== bool appliesToNote [[nodiscard]] (int) noexcept override { return true; } bool appliesToChannel [[nodiscard]] (int) noexcept override { return true; } From e8828c3ba3f27ea2f9a13e635a1ff0568f5fcbc9 Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Thu, 7 May 2026 12:59:05 +0200 Subject: [PATCH 51/74] feat: add default constructor to Properties class --- src/dmt/configuration/Properties.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/dmt/configuration/Properties.h b/src/dmt/configuration/Properties.h index 08b3944c..d8ae4bb7 100644 --- a/src/dmt/configuration/Properties.h +++ b/src/dmt/configuration/Properties.h @@ -56,6 +56,12 @@ class Properties using String = juce::String; public: + //============================================================================ + /** + * @brief Construct a new Properties object + */ + Properties() = default; + //============================================================================ /** * @brief Initialize the properties with options and settings. From 7572bb44361411abf45d0ecb28c624932c9da98b Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Thu, 7 May 2026 13:47:29 +0200 Subject: [PATCH 52/74] feat: add default constructors to MinMaxRenderer and OscilloscopeRenderer classes Co-authored-by: Copilot --- src/dmt/gui/widget/MinMaxRenderer.h | 4 ++++ src/dmt/gui/widget/OscilloscopeRenderer.h | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/src/dmt/gui/widget/MinMaxRenderer.h b/src/dmt/gui/widget/MinMaxRenderer.h index accce091..459f1e06 100644 --- a/src/dmt/gui/widget/MinMaxRenderer.h +++ b/src/dmt/gui/widget/MinMaxRenderer.h @@ -67,6 +67,10 @@ namespace widget { template class MinMaxRenderer : public OscilloscopeRenderer { + //============================================================================ +public: + MinMaxRenderer() = default; + //============================================================================ public: using RingBuffer = typename OscilloscopeRenderer::RingBuffer; diff --git a/src/dmt/gui/widget/OscilloscopeRenderer.h b/src/dmt/gui/widget/OscilloscopeRenderer.h index dcfc70e1..2db1da00 100644 --- a/src/dmt/gui/widget/OscilloscopeRenderer.h +++ b/src/dmt/gui/widget/OscilloscopeRenderer.h @@ -106,6 +106,11 @@ class OscilloscopeRenderer /** Global size scaling factor. */ float sizeFactor; }; + //============================================================================ + /** + * @brief Default constructor for OscilloscopeRenderer. + */ + OscilloscopeRenderer() = default; //============================================================================ /** From 55c33ec943a55f8504c15869bfcbd9878fe9a9df Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Thu, 7 May 2026 14:03:43 +0200 Subject: [PATCH 53/74] oscilloscope: impleent double buffering and atomic renderer swapping Co-authored-by: Copilot --- src/dmt/gui/widget/Oscilloscope.h | 109 +++++++++++++++++++++--------- 1 file changed, 76 insertions(+), 33 deletions(-) diff --git a/src/dmt/gui/widget/Oscilloscope.h b/src/dmt/gui/widget/Oscilloscope.h index 37c8d02a..732ad1d3 100644 --- a/src/dmt/gui/widget/Oscilloscope.h +++ b/src/dmt/gui/widget/Oscilloscope.h @@ -33,7 +33,6 @@ #include "gui/widget/MinMaxRenderer.h" #include "gui/widget/PathStrokeRenderer.h" #include -#include //============================================================================== @@ -72,7 +71,6 @@ class alignas(64) Oscilloscope : public juce::Thread using String = juce::String; using Thread = juce::Thread; using PixelFormat = juce::Image::PixelFormat; - using ReadWriteLock = juce::ReadWriteLock; using Settings = dmt::Settings; using Renderer = OscilloscopeRenderer; @@ -94,7 +92,7 @@ class alignas(64) Oscilloscope : public juce::Thread , ringBuffer(_ringBuffer) , channel(_channel) , size(_sizeFactor) - , renderer(std::make_unique>()) + , renderer(std::make_shared>()) { startThread(); } @@ -119,8 +117,8 @@ class alignas(64) Oscilloscope : public juce::Thread */ [[nodiscard]] inline juce::Image getImage() const { - const ScopedReadLock readLock(imageLock); - return image.createCopy(); + const int frontIndex = frontBufferIndex.load(std::memory_order_acquire); + return images[static_cast(frontIndex)].createCopy(); } //============================================================================== @@ -134,8 +132,11 @@ class alignas(64) Oscilloscope : public juce::Thread */ inline void setBounds(juce::Rectangle _newBounds) { - resizeImage(_newBounds.getWidth(), _newBounds.getHeight()); bounds = _newBounds; + + renderWidth.store(_newBounds.getWidth(), std::memory_order_relaxed); + renderHeight.store(_newBounds.getHeight(), std::memory_order_relaxed); + resizePending.store(true, std::memory_order_release); } //============================================================================== @@ -204,8 +205,10 @@ class alignas(64) Oscilloscope : public juce::Thread */ inline void setRenderer(std::unique_ptr _newRenderer) { - const ScopedWriteLock writeLock(imageLock); - renderer = std::move(_newRenderer); + std::atomic_store_explicit( + &renderer, + std::shared_ptr(std::move(_newRenderer)), + std::memory_order_release); } //============================================================================== @@ -224,7 +227,12 @@ class alignas(64) Oscilloscope : public juce::Thread { while (!threadShouldExit()) { wait(10000); - const ScopedWriteLock writeLock(imageLock); + + if (resizePending.exchange(false, std::memory_order_acq_rel)) { + resizeImage(renderWidth.load(std::memory_order_relaxed), + renderHeight.load(std::memory_order_relaxed)); + } + render(); } } @@ -242,23 +250,28 @@ class alignas(64) Oscilloscope : public juce::Thread inline void resizeImage(const int _width, const int _height) { TRACER("Oscilloscope::resizeImage"); - const ScopedWriteLock writeLock(imageLock); // Avoid illegal sizes if (_width <= 0 || _height <= 0) { return; } - image = Image(PixelFormat::ARGB, _width + 10, _height, true); + for (auto& image : images) { + image = Image(PixelFormat::ARGB, _width + 10, _height, true); + } + + frontBufferIndex.store(0, std::memory_order_release); subPixelOffset = 0.0f; - juce::Graphics imageGraphics(image); - imageGraphics.setColour(juce::Colours::white); - imageGraphics.drawLine(0, - static_cast(_height) / 2.0f, - static_cast(_width + 10), - static_cast(_height) / 2.0f, - 3.0f); + for (auto& image : images) { + juce::Graphics imageGraphics(image); + imageGraphics.setColour(juce::Colours::white); + imageGraphics.drawLine(0, + static_cast(_height) / 2.0f, + static_cast(_width + 10), + static_cast(_height) / 2.0f, + 3.0f); + } } //============================================================================== @@ -273,11 +286,20 @@ class alignas(64) Oscilloscope : public juce::Thread inline void render() { TRACER("Oscilloscope::render"); - const int width = bounds.getWidth(); - const int height = bounds.getHeight(); + const int width = renderWidth.load(std::memory_order_relaxed); + const int height = renderHeight.load(std::memory_order_relaxed); + + if (width <= 0 || height <= 0) { + return; + } + const int halfHeight = height / 2; float samplesPerPixel = rawSamplesPerPixel * size; + if (samplesPerPixel <= 0.0f) { + return; + } + const int bufferSize = ringBuffer.getNumSamples(); const int readPosition = ringBuffer.getReadPosition(channel); const int samplesToRead = bufferSize - readPosition; @@ -291,24 +313,35 @@ class alignas(64) Oscilloscope : public juce::Thread static_cast(samplesToDraw) / samplesPerPixel; const float totalShift = exactPixelsToDraw + subPixelOffset; const int pixelToDraw = static_cast(totalShift); + + if (pixelToDraw <= 0) { + return; + } + ringBuffer.incrementReadPosition(channel, samplesToDraw); + const int currentFront = frontBufferIndex.load(std::memory_order_acquire); + const int backIndex = currentFront == 0 ? 1 : 0; + auto& backImage = images[static_cast(backIndex)]; + + backImage = images[static_cast(currentFront)].createCopy(); + // Image move const int destX = 0 - pixelToDraw; - image.moveImageSection(destX, // destX - 0, // destY - 0, // srcX - 0, // srcY - width + 10, // width - height); // height + backImage.moveImageSection(destX, // destX + 0, // destY + 0, // srcX + 0, // srcY + width + 10, // width + height); // height // Clear the new part of the image juce::Rectangle clearRect( width - pixelToDraw + 10, 0, pixelToDraw, height); - image.clear(clearRect, juce::Colours::transparentBlack); + backImage.clear(clearRect, juce::Colours::transparentBlack); // Delegate drawing to the active renderer - juce::Graphics imageGraphics(image); + juce::Graphics imageGraphics(backImage); const typename Renderer::RenderContext context{ firstSamplesToDraw, samplesToDraw, @@ -320,7 +353,13 @@ class alignas(64) Oscilloscope : public juce::Thread size }; subPixelOffset = totalShift - static_cast(pixelToDraw); - renderer->draw(imageGraphics, ringBuffer, channel, context); + + if (auto currentRenderer = + std::atomic_load_explicit(&renderer, std::memory_order_acquire)) { + currentRenderer->draw(imageGraphics, ringBuffer, channel, context); + } + + frontBufferIndex.store(backIndex, std::memory_order_release); } //============================================================================== @@ -333,10 +372,14 @@ class alignas(64) Oscilloscope : public juce::Thread //============================================================================== // Other members juce::Rectangle bounds = juce::Rectangle(0, 0, 1, 1); - Image image = Image(PixelFormat::ARGB, 1, 1, true); - ReadWriteLock imageLock; - - std::unique_ptr renderer; + std::array images = { Image(PixelFormat::ARGB, 1, 1, true), + Image(PixelFormat::ARGB, 1, 1, true) }; + std::atomic frontBufferIndex{ 0 }; + std::atomic renderWidth{ 1 }; + std::atomic renderHeight{ 1 }; + std::atomic resizePending{ true }; + + std::shared_ptr renderer; float subPixelOffset = 0.0f; float rawSamplesPerPixel = 10.0f; float amplitude = 1.0f; From a67f9d8b2676fe42b2d35e01c884ebb430f0bb75 Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Thu, 7 May 2026 14:11:22 +0200 Subject: [PATCH 54/74] feat: replace float variables with atomic for thread-safe access in Oscilloscope Co-authored-by: Copilot --- src/dmt/gui/widget/Oscilloscope.h | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/dmt/gui/widget/Oscilloscope.h b/src/dmt/gui/widget/Oscilloscope.h index 732ad1d3..22a231ff 100644 --- a/src/dmt/gui/widget/Oscilloscope.h +++ b/src/dmt/gui/widget/Oscilloscope.h @@ -161,7 +161,7 @@ class alignas(64) Oscilloscope : public juce::Thread */ inline void setRawSamplesPerPixel(float _newRawSamplesPerPixel) noexcept { - rawSamplesPerPixel = _newRawSamplesPerPixel; + rawSamplesPerPixel.store(_newRawSamplesPerPixel, std::memory_order_relaxed); } //============================================================================== @@ -175,7 +175,7 @@ class alignas(64) Oscilloscope : public juce::Thread */ inline void setAmplitude(float _newAmplitude) noexcept { - amplitude = _newAmplitude; + amplitude.store(_newAmplitude, std::memory_order_relaxed); } //============================================================================== @@ -189,7 +189,7 @@ class alignas(64) Oscilloscope : public juce::Thread */ inline void setThickness(float _newThickness) noexcept { - thickness = _newThickness; + thickness.store(_newThickness, std::memory_order_relaxed); } //============================================================================== @@ -294,7 +294,8 @@ class alignas(64) Oscilloscope : public juce::Thread } const int halfHeight = height / 2; - float samplesPerPixel = rawSamplesPerPixel * size; + const float samplesPerPixel = + rawSamplesPerPixel.load(std::memory_order_relaxed) * size; if (samplesPerPixel <= 0.0f) { return; @@ -348,8 +349,8 @@ class alignas(64) Oscilloscope : public juce::Thread static_cast(width - pixelToDraw) + subPixelOffset, 1.0f / samplesPerPixel, halfHeight, - amplitude, - thickness, + amplitude.load(std::memory_order_relaxed), + thickness.load(std::memory_order_relaxed), size }; subPixelOffset = totalShift - static_cast(pixelToDraw); @@ -381,9 +382,9 @@ class alignas(64) Oscilloscope : public juce::Thread std::shared_ptr renderer; float subPixelOffset = 0.0f; - float rawSamplesPerPixel = 10.0f; - float amplitude = 1.0f; - float thickness = 3.0f; + std::atomic rawSamplesPerPixel{ 10.0f }; + std::atomic amplitude{ 1.0f }; + std::atomic thickness{ 3.0f }; const float& size; //============================================================================== From 7961922c4c6574c98788e2b6635ae1016c74b4ee Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Thu, 7 May 2026 14:25:59 +0200 Subject: [PATCH 55/74] refactor: update image retrieval methods to use getFrontImage() for better clarity and performance Co-authored-by: Copilot --- src/dmt/gui/display/OscilloscopeDisplay.h | 4 ++-- src/dmt/gui/widget/Oscilloscope.h | 25 +++++++++++------------ 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/dmt/gui/display/OscilloscopeDisplay.h b/src/dmt/gui/display/OscilloscopeDisplay.h index 6d8592b3..36d10531 100644 --- a/src/dmt/gui/display/OscilloscopeDisplay.h +++ b/src/dmt/gui/display/OscilloscopeDisplay.h @@ -173,10 +173,10 @@ class OscilloscopeDisplay rightScopeBounds.getHeight()); // Draw oscilloscope images - g.drawImageAt(leftOscilloscope.getImage(), + g.drawImageAt(leftOscilloscope.getFrontImage(), leftOscilloscope.getBounds().getX(), leftOscilloscope.getBounds().getY()); - g.drawImageAt(rightOscilloscope.getImage(), + g.drawImageAt(rightOscilloscope.getFrontImage(), rightOscilloscope.getBounds().getX(), rightOscilloscope.getBounds().getY()); } diff --git a/src/dmt/gui/widget/Oscilloscope.h b/src/dmt/gui/widget/Oscilloscope.h index 22a231ff..8a72547d 100644 --- a/src/dmt/gui/widget/Oscilloscope.h +++ b/src/dmt/gui/widget/Oscilloscope.h @@ -51,14 +51,14 @@ namespace widget { * buffers, optimized for real-time use in GUI applications. It leverages a * background thread to render the waveform into a JUCE image, which can be * efficiently displayed in the GUI. The design ensures thread safety and - * minimal locking overhead, using a read-write lock for image access. + * minimal overhead using lock-free double buffering for image access. * * The oscilloscope is intended to be used with a lock-free ring buffer for * audio data, and supports customization of amplitude, thickness, and * samples-per-pixel for flexible display scaling. * * The rendering thread is started upon construction and stopped on destruction. - * The image is updated periodically, and can be retrieved via getImage(). + * The image is updated periodically, and can be retrieved via getFrontImage(). */ template class alignas(64) Oscilloscope : public juce::Thread @@ -108,17 +108,18 @@ class alignas(64) Oscilloscope : public juce::Thread //============================================================================== /** - * @brief Retrieves a copy of the current oscilloscope image. + * @brief Retrieves the current front image for GUI rendering. * - * @return A copy of the rendered JUCE image. + * @return A reference to the front buffer image. * * @details - * The returned image is thread-safe and can be used in the GUI. + * The render thread only writes to the back buffer, so the front image is + * safe for concurrent GUI reads. */ - [[nodiscard]] inline juce::Image getImage() const + [[nodiscard]] inline const juce::Image& getFrontImage() const noexcept { const int frontIndex = frontBufferIndex.load(std::memory_order_acquire); - return images[static_cast(frontIndex)].createCopy(); + return images[static_cast(frontIndex)]; } //============================================================================== @@ -199,9 +200,9 @@ class alignas(64) Oscilloscope : public juce::Thread * @param _newRenderer A unique pointer to the new renderer implementation. * * @details - * Swaps the current rendering strategy under the write lock to ensure - * thread safety with the rendering thread. The previous renderer is - * destroyed when the new one is set. + * Swaps the current rendering strategy atomically to avoid contention with + * the rendering thread. The previous renderer is destroyed when the new one + * is set. */ inline void setRenderer(std::unique_ptr _newRenderer) { @@ -219,7 +220,7 @@ class alignas(64) Oscilloscope : public juce::Thread * * @details * Periodically updates the oscilloscope image by rendering the latest audio - * samples. Uses a write lock to ensure exclusive access to the image. + * samples. Uses a back buffer to avoid GUI contention. * The wait interval is set high to minimize CPU usage; rendering is not * continuous but event-driven. */ @@ -325,8 +326,6 @@ class alignas(64) Oscilloscope : public juce::Thread const int backIndex = currentFront == 0 ? 1 : 0; auto& backImage = images[static_cast(backIndex)]; - backImage = images[static_cast(currentFront)].createCopy(); - // Image move const int destX = 0 - pixelToDraw; backImage.moveImageSection(destX, // destX From c553fb1a6dfc93049855e99f284331e34c240e1b Mon Sep 17 00:00:00 2001 From: David Hess Date: Thu, 7 May 2026 20:02:05 +0200 Subject: [PATCH 56/74] refactor: update sanitizer configuration to apply flags globally for consistency --- cmake/Sanitizers.cmake | 91 +++++++++++++++++++----------------------- 1 file changed, 42 insertions(+), 49 deletions(-) diff --git a/cmake/Sanitizers.cmake b/cmake/Sanitizers.cmake index a1558a44..eaae5ea9 100644 --- a/cmake/Sanitizers.cmake +++ b/cmake/Sanitizers.cmake @@ -1,70 +1,63 @@ #============================================================================== # Opt-in sanitizer and debug-symbol configuration. -# This module is intentionally target-scoped so normal builds are untouched. +# Supports both target-scoped (for selective sanitization) and global (for consistency). #============================================================================== -option(DMT_ENABLE_ASAN "Enable AddressSanitizer for selected targets" OFF) -option(DMT_ENABLE_UBSAN "Enable UndefinedBehaviorSanitizer for selected targets" OFF) +option(DMT_ENABLE_ASAN "Enable AddressSanitizer for all targets" OFF) +option(DMT_ENABLE_UBSAN "Enable UndefinedBehaviorSanitizer for all targets" OFF) -function(dmt_target_enable_sanitizers target_name) - if(NOT TARGET ${target_name}) - message(FATAL_ERROR "dmt_target_enable_sanitizers: unknown target '${target_name}'") - endif() - - if(NOT (DMT_ENABLE_ASAN OR DMT_ENABLE_UBSAN)) - return() - endif() - - target_compile_definitions(${target_name} PRIVATE DMT_SANITIZERS_ENABLED=1) - - # MSVC cl.exe: supports ASan on modern toolsets, but not UBSan. +# Apply sanitizer flags globally when enabled to ensure consistency across all compilation units +if(DMT_ENABLE_ASAN OR DMT_ENABLE_UBSAN) if(MSVC AND NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang") if(DMT_ENABLE_UBSAN) - message(WARNING "DMT_ENABLE_UBSAN is not supported with MSVC cl; ignoring UBSan for ${target_name}") + message(WARNING "DMT_ENABLE_UBSAN is not supported with MSVC cl; ignoring UBSan") endif() if(DMT_ENABLE_ASAN) - target_compile_options(${target_name} PRIVATE /fsanitize=address) - target_link_options(${target_name} PRIVATE /fsanitize=address) + add_compile_options(/fsanitize=address) + add_link_options(/fsanitize=address) + # Disable incremental linking with ASAN + add_link_options(/INCREMENTAL:NO) endif() # Symbol and stack quality for debugger + sanitizer crash reports. - target_compile_options(${target_name} PRIVATE /Zi /Oy-) - target_link_options(${target_name} PRIVATE /DEBUG /INCREMENTAL:NO) - return() - endif() + add_compile_options(/Zi /Oy-) + add_link_options(/DEBUG) + else() + # Clang/GCC style sanitizers (including clang-cl frontend). + set(enabled_sanitizers "") + if(DMT_ENABLE_ASAN) + list(APPEND enabled_sanitizers address) + endif() + if(DMT_ENABLE_UBSAN) + list(APPEND enabled_sanitizers undefined) + endif() - # Clang/GCC style sanitizers (including clang-cl frontend). - set(enabled_sanitizers "") - if(DMT_ENABLE_ASAN) - list(APPEND enabled_sanitizers address) - endif() - if(DMT_ENABLE_UBSAN) - list(APPEND enabled_sanitizers undefined) - endif() + if(enabled_sanitizers) + string(JOIN "," sanitizer_arg ${enabled_sanitizers}) + add_compile_options(-fsanitize=${sanitizer_arg} -fno-omit-frame-pointer) + add_link_options(-fsanitize=${sanitizer_arg}) + endif() - if(NOT enabled_sanitizers) - return() + if(WIN32) + # Keep PDB/debugger quality high on Windows clang/clang-cl presets. + add_compile_options(/Zi /Oy-) + add_link_options(/DEBUG /INCREMENTAL:NO) + else() + add_compile_options(-g) + endif() endif() +endif() - string(JOIN "," sanitizer_arg ${enabled_sanitizers}) - - target_compile_options(${target_name} - PRIVATE - -fsanitize=${sanitizer_arg} - -fno-omit-frame-pointer - ) +add_compile_definitions($,DMT_SANITIZERS_ENABLED=1,>) - target_link_options(${target_name} - PRIVATE - -fsanitize=${sanitizer_arg} - ) +function(dmt_target_enable_sanitizers target_name) + if(NOT TARGET ${target_name}) + message(FATAL_ERROR "dmt_target_enable_sanitizers: unknown target '${target_name}'") + endif() - if(WIN32) - # Keep PDB/debugger quality high on Windows clang/clang-cl presets. - target_compile_options(${target_name} PRIVATE /Zi /Oy-) - target_link_options(${target_name} PRIVATE /DEBUG /INCREMENTAL:NO) - else() - target_compile_options(${target_name} PRIVATE -g) + # Sanitizers are now applied globally, so this function is a no-op for backwards compatibility + if(DMT_ENABLE_ASAN) + target_compile_definitions(${target_name} PRIVATE DMT_SANITIZERS_ENABLED=1) endif() endfunction() From 7385e35c9de688d00a4f178a51d55dc33a34e069 Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Thu, 7 May 2026 22:16:07 +0200 Subject: [PATCH 57/74] fix: remove constexpr from AhdEnvelope constructor for compatibility --- src/dmt/dsp/envelope/AdhEnvelope.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dmt/dsp/envelope/AdhEnvelope.h b/src/dmt/dsp/envelope/AdhEnvelope.h index cbe50e5e..a862bbe6 100644 --- a/src/dmt/dsp/envelope/AdhEnvelope.h +++ b/src/dmt/dsp/envelope/AdhEnvelope.h @@ -68,7 +68,7 @@ class AhdEnvelope Idle }; - constexpr AhdEnvelope() noexcept = default; + AhdEnvelope() noexcept = default; inline void setParameters(const juce::AudioProcessorValueTreeState& apvts, juce::String prefix) noexcept From 41d4c04e237bc7caa1bd4a59ebdb6d9c14187fc5 Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Thu, 7 May 2026 22:16:41 +0200 Subject: [PATCH 58/74] fix: oscilloscope chunks not connected correctly --- src/dmt/gui/widget/Oscilloscope.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/dmt/gui/widget/Oscilloscope.h b/src/dmt/gui/widget/Oscilloscope.h index 8a72547d..97f7b5d8 100644 --- a/src/dmt/gui/widget/Oscilloscope.h +++ b/src/dmt/gui/widget/Oscilloscope.h @@ -326,6 +326,8 @@ class alignas(64) Oscilloscope : public juce::Thread const int backIndex = currentFront == 0 ? 1 : 0; auto& backImage = images[static_cast(backIndex)]; + backImage = images[static_cast(currentFront)].createCopy(); + // Image move const int destX = 0 - pixelToDraw; backImage.moveImageSection(destX, // destX From d210a5193c24c59defe7d3abcd0ae52bf5bc4a98 Mon Sep 17 00:00:00 2001 From: David Hess Date: Fri, 8 May 2026 02:29:41 +0200 Subject: [PATCH 59/74] chore: update build presets --- CMakePresets.json | 69 +++------------ cmake/Sanitizers.cmake | 26 +----- docs/windows-crash-debugging.md | 150 -------------------------------- 3 files changed, 15 insertions(+), 230 deletions(-) delete mode 100644 docs/windows-crash-debugging.md diff --git a/CMakePresets.json b/CMakePresets.json index 14c3ed41..afadad1e 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -49,16 +49,15 @@ } }, { - "name": "Windows Perfetto", + "name": "Windows Release With Debug Info", "hidden": false, - "description": "Perfetto Debug configuration", + "description": "Release configuration with debug symbols", "generator": "Ninja", "binaryDir": "${sourceDir}/build", "cacheVariables": { - "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_BUILD_TYPE": "RelWithDebInfo", "CMAKE_C_COMPILER": "cl", - "CMAKE_CXX_COMPILER": "cl", - "CMAKE_CXX_FLAGS": "/DPERFETTO=1" + "CMAKE_CXX_COMPILER": "cl" }, "environment": { "CC": "cl", @@ -71,16 +70,16 @@ } }, { - "name": "Windows ASan", + "name": "Windows Perfetto", "hidden": false, - "description": "Debug + AddressSanitizer (MSVC cl)", + "description": "Perfetto Debug configuration", "generator": "Ninja", - "binaryDir": "${sourceDir}/build/windows-asan", + "binaryDir": "${sourceDir}/build", "cacheVariables": { "CMAKE_BUILD_TYPE": "Debug", "CMAKE_C_COMPILER": "cl", "CMAKE_CXX_COMPILER": "cl", - "DMT_ENABLE_ASAN": "ON" + "CMAKE_CXX_FLAGS": "/DPERFETTO=1" }, "environment": { "CC": "cl", @@ -93,13 +92,13 @@ } }, { - "name": "Windows RelWithDebInfo ASan", + "name": "Windows ASan", "hidden": false, - "description": "RelWithDebInfo + AddressSanitizer (MSVC cl)", + "description": "Debug + AddressSanitizer (MSVC cl)", "generator": "Ninja", - "binaryDir": "${sourceDir}/build/windows-relwithdebinfo-asan", + "binaryDir": "${sourceDir}/build", "cacheVariables": { - "CMAKE_BUILD_TYPE": "RelWithDebInfo", + "CMAKE_BUILD_TYPE": "Debug", "CMAKE_C_COMPILER": "cl", "CMAKE_CXX_COMPILER": "cl", "DMT_ENABLE_ASAN": "ON" @@ -114,50 +113,6 @@ "rhs": "Windows" } }, - { - "name": "Windows Clang ASan", - "hidden": false, - "description": "Debug + AddressSanitizer (clang-cl, if installed)", - "generator": "Ninja", - "binaryDir": "${sourceDir}/build/windows-clang-asan", - "cacheVariables": { - "CMAKE_BUILD_TYPE": "Debug", - "CMAKE_C_COMPILER": "clang-cl", - "CMAKE_CXX_COMPILER": "clang-cl", - "DMT_ENABLE_ASAN": "ON" - }, - "environment": { - "CC": "clang-cl", - "CXX": "clang-cl" - }, - "condition": { - "type": "equals", - "lhs": "${hostSystemName}", - "rhs": "Windows" - } - }, - { - "name": "Windows Clang UBSan", - "hidden": false, - "description": "Debug + UndefinedBehaviorSanitizer (clang-cl, if installed)", - "generator": "Ninja", - "binaryDir": "${sourceDir}/build/windows-clang-ubsan", - "cacheVariables": { - "CMAKE_BUILD_TYPE": "Debug", - "CMAKE_C_COMPILER": "clang-cl", - "CMAKE_CXX_COMPILER": "clang-cl", - "DMT_ENABLE_UBSAN": "ON" - }, - "environment": { - "CC": "clang-cl", - "CXX": "clang-cl" - }, - "condition": { - "type": "equals", - "lhs": "${hostSystemName}", - "rhs": "Windows" - } - }, { "name": "Mac Debug", "hidden": false, diff --git a/cmake/Sanitizers.cmake b/cmake/Sanitizers.cmake index eaae5ea9..7b5318f8 100644 --- a/cmake/Sanitizers.cmake +++ b/cmake/Sanitizers.cmake @@ -7,8 +7,9 @@ option(DMT_ENABLE_ASAN "Enable AddressSanitizer for all targets" OFF) option(DMT_ENABLE_UBSAN "Enable UndefinedBehaviorSanitizer for all targets" OFF) # Apply sanitizer flags globally when enabled to ensure consistency across all compilation units +# Windows MSVC only - no sanitizers on Mac or Linux if(DMT_ENABLE_ASAN OR DMT_ENABLE_UBSAN) - if(MSVC AND NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + if(MSVC) if(DMT_ENABLE_UBSAN) message(WARNING "DMT_ENABLE_UBSAN is not supported with MSVC cl; ignoring UBSan") endif() @@ -24,28 +25,7 @@ if(DMT_ENABLE_ASAN OR DMT_ENABLE_UBSAN) add_compile_options(/Zi /Oy-) add_link_options(/DEBUG) else() - # Clang/GCC style sanitizers (including clang-cl frontend). - set(enabled_sanitizers "") - if(DMT_ENABLE_ASAN) - list(APPEND enabled_sanitizers address) - endif() - if(DMT_ENABLE_UBSAN) - list(APPEND enabled_sanitizers undefined) - endif() - - if(enabled_sanitizers) - string(JOIN "," sanitizer_arg ${enabled_sanitizers}) - add_compile_options(-fsanitize=${sanitizer_arg} -fno-omit-frame-pointer) - add_link_options(-fsanitize=${sanitizer_arg}) - endif() - - if(WIN32) - # Keep PDB/debugger quality high on Windows clang/clang-cl presets. - add_compile_options(/Zi /Oy-) - add_link_options(/DEBUG /INCREMENTAL:NO) - else() - add_compile_options(-g) - endif() + message(WARNING "Sanitizers are only supported on Windows with MSVC; ignoring DMT_ENABLE_ASAN and DMT_ENABLE_UBSAN") endif() endif() diff --git a/docs/windows-crash-debugging.md b/docs/windows-crash-debugging.md deleted file mode 100644 index 1c50bf49..00000000 --- a/docs/windows-crash-debugging.md +++ /dev/null @@ -1,150 +0,0 @@ -# Windows Crash Debugging for Intermittent VST/Plugin Failures - -This guide focuses on Windows-only, hard-to-reproduce crashes in DAWs using the sanitizer presets added to this project. - -## Presets Added - -- Windows ASan -- Windows RelWithDebInfo ASan -- Windows Clang ASan (requires clang-cl) -- Windows Clang UBSan (requires clang-cl) - -These are isolated from your normal presets and use separate build directories. - -## Build from VS Code - -1. Open Command Palette. -2. Run `CMake: Select Configure Preset` and choose one of: - - `Windows ASan` - - `Windows RelWithDebInfo ASan` - - `Windows Clang ASan` - - `Windows Clang UBSan` -3. Run `CMake: Configure`. -4. Run `CMake: Build`. - -You can also use terminal commands: - -```powershell -cmake --preset "Windows ASan" -cmake --build build/windows-asan -``` - -```powershell -cmake --preset "Windows RelWithDebInfo ASan" -cmake --build build/windows-relwithdebinfo-asan -``` - -## Why These Flags Were Added - -Sanitizer builds enable these flags through `cmake/Sanitizers.cmake` only when `DMT_ENABLE_ASAN` or `DMT_ENABLE_UBSAN` is ON. - -- `/fsanitize=address` - - MSVC AddressSanitizer runtime. Detects use-after-free, heap buffer overflow, and related memory corruption. -- `-fsanitize=address` - - Clang equivalent of ASan. -- `-fsanitize=undefined` - - Clang UBSan runtime for undefined behavior checks. -- `-fno-omit-frame-pointer` - - Preserves frame pointers so crash call stacks remain useful. -- `/Zi` - - Produces full PDB debug information. -- `/DEBUG` - - Emits and links debug symbols into final binaries for debugger stack traces. -- `/Oy-` - - Disables frame-pointer omission on MSVC, improving stack-walk reliability. -- `/INCREMENTAL:NO` - - Reduces linker/debugger oddities in sanitizer-oriented sessions. - -## Attach Visual Studio Debugger to a DAW - -1. Start the DAW normally. -2. Open Visual Studio. -3. `Debug -> Attach to Process...` -4. Select your DAW process (for example `Ableton Live`, `Reaper`, `Cubase`, etc). -5. Ensure code type is Native. -6. Trigger plugin load/use scenario until crash reproduces. - -Tip: when possible, disable plugin sandboxing or run in-process for better stack visibility. - -## Enable First-Chance Exceptions - -In Visual Studio: - -1. Open `Debug -> Windows -> Exception Settings`. -2. Enable first-chance break for: - - Access violation (`0xC0000005`) - - Heap corruption (`0xC0000374`) - - C++ exceptions (as needed) -3. Reproduce crash. Break at first throw/fault, not at final DAW termination. - -## Page Heap (gflags) - -Enable full page heap for the DAW executable: - -```powershell -gflags /p /enable YourDAW.exe /full -``` - -Check status: - -```powershell -gflags /p -``` - -Disable when done: - -```powershell -gflags /p /disable YourDAW.exe -``` - -Page Heap often turns silent heap corruption into deterministic early crashes. - -## Application Verifier - -1. Launch Application Verifier. -2. Add the DAW executable. -3. Enable checks, at minimum: - - Basics - - Heaps - - Handles - - Locks -4. Re-run the DAW under debugger and reproduce. - -Use with ASan for broader coverage across allocator, handle, and lock misuse. - -## Interpreting AddressSanitizer Reports - -Look for these report sections: - -- Error type (`heap-use-after-free`, `heap-buffer-overflow`, etc) -- Faulting address -- Access type (`READ` or `WRITE`) -- Stack at access site -- Stack at allocation site -- Stack at free site - -Prioritize fixes by matching: - -1. Free site owner -2. Last surviving owner assumptions -3. Cross-thread handoff paths (message thread vs audio thread) - -## Limitations and Tradeoffs - -- MSVC `cl`: - - ASan is available in modern toolsets. - - UBSan is not generally available like Clang UBSan. -- clang-cl: - - Supports both ASan and UBSan flags used here. - - Behavior may differ from MSVC ABI/runtime edge cases in DAW/plugin hosting. -- Sanitizers in DAWs: - - Some host/plugin combinations may be noisy or unsupported. - - Use a reproducible host/project pair first, then expand matrix. - -## Recommended Workflow - -1. Start with `Windows ASan` for best compatibility with existing MSVC flow. -2. Reproduce crash in a single DAW with debugger attached and first-chance exceptions enabled. -3. If issue remains unclear, enable Page Heap and Application Verifier. -4. If UB is suspected, try `Windows Clang UBSan`. -5. Keep Release builds unchanged for shipping validation. From d462b41f685f0219c45cc5c9c4ab03bffe94464a Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Fri, 8 May 2026 02:36:47 +0200 Subject: [PATCH 60/74] feat: add CI workflow for building Disflux on multiple platforms --- .github/workflows/ci-debug.yml | 430 +++++++++++++++++++++++++++++++++ 1 file changed, 430 insertions(+) create mode 100644 .github/workflows/ci-debug.yml diff --git a/.github/workflows/ci-debug.yml b/.github/workflows/ci-debug.yml new file mode 100644 index 00000000..96baff44 --- /dev/null +++ b/.github/workflows/ci-debug.yml @@ -0,0 +1,430 @@ +#=========================================================================================== +# This workflow will build the project for Windows, macOS, and Linux. +# It will also build an Arch Linux and Fedora package using Docker containers. +# The artifacts will be uploaded to the release page. +# +# TODO: +# - Add a step after release to update the AUR repository +#=========================================================================================== + +name: Build Debug +on: + workflow_dispatch: +defaults: + run: + shell: bash + +#=========================================================================================== +# Environment Variables +env: + PROJECT_NAME: Disflux + BUNDLE_NAME: disflux + BUNDLE_ID: com.dimethoxy.disflux + BUILD_DIR: build + DISPLAY: :0 # Linux pluginval needs this + HOMEBREW_NO_INSTALL_CLEANUP: 1 + IPP_DIR: C:\Program Files (x86)\Intel\oneAPI\ipp\latest\lib\cmake\ipp + +#=========================================================================================== +# Build Jobs +#=========================================================================================== +jobs: + #========================================================================================= + # Windows Build + #========================================================================================= + build-windows: + runs-on: windows-latest + steps: + - name: Export Variables + run: | + echo "BUILD_ARTIFACTS_DIR=$BUILD_DIR/src/${{env.PROJECT_NAME}}Plugin_artefacts/Debug" >> $GITHUB_ENV + echo "WINDOWS-PACKAGE=${{env.BUNDLE_NAME}}-windows-debug.exe" >> $GITHUB_ENV + + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Read Version + run: | + echo "VERSION=$(tr -d '[:space:]' < VERSION.md)" >> $GITHUB_ENV + + - name: Setup MSVC + uses: TheMrMilchmann/setup-msvc-dev@v3 + with: + arch: x64 + spectre: true + + - name: Set Up Windows + run: | + choco install ninja + choco install innosetup + + - name: Cache IPP (Windows) + id: cache-ipp + uses: actions/cache@v4 + with: + key: ipp-v6 + path: C:\Program Files (x86)\Intel + + - name: Install IPP (Windows) + if: steps.cache-ipp.outputs.cache-hit != 'true' + run: | + curl --output oneapi.exe https://registrationcenter-download.intel.com/akdlm/IRC_NAS/2e89fab4-e1c7-4f14-a1ef-6cddba8c5fa7/intel-ipp-2022.0.0.796_offline.exe + ./oneapi.exe -s -x -f oneapi + ./oneapi/bootstrapper.exe -s -c --action install --components=intel.oneapi.win.ipp.devel --eula=accept -p=NEED_VS2022_INTEGRATION=1 --log-dir=. + + - name: Save IPP cache + if: steps.cache-ipp.outputs.cache-hit != 'true' + uses: actions/cache/save@v4 + with: + path: C:\Program Files (x86)\Intel + key: ipp-v6 + + - name: Select CMake Preset + run: | + cmake --preset "Windows Debug" + + - name: Build + run: cmake --build build --config "Debug" + + - name: Copy Build Artifacts + run: | + mkdir -p artifacts + cp -r ${{env.BUILD_ARTIFACTS_DIR}}/VST3/${{env.PROJECT_NAME}}.vst3 \ + artifacts/ + cp -r ${{env.BUILD_ARTIFACTS_DIR}}/CLAP/${{env.PROJECT_NAME}}.clap \ + artifacts/ + shell: bash + + - name: Create Installer + run: | + # Create the packaging directory + mkdir -p packaging + + # Create the Inno Setup + envsubst < pkg/windows/Setup.iss > packaging/Setup.iss + iscc packaging/Setup.iss + + # Move the installer to the artifacts directory + mv packaging/Output/"${{env.PROJECT_NAME}}_Setup.exe" artifacts/${{env.WINDOWS-PACKAGE}} + shell: bash + + - name: Upload Artifacts + uses: actions/upload-artifact@v4 + with: + name: artifacts-windows-debug + path: artifacts + + #========================================================================================= + # macOS Build + #========================================================================================= + build-macos: + runs-on: macos-latest + steps: + - name: Export Variables + run: | + echo "BUILD_ARTIFACTS_DIR=$BUILD_DIR/src/${{env.PROJECT_NAME}}Plugin_artefacts/Debug" >> $GITHUB_ENV + echo "MAC_PACKAGE=${{env.BUNDLE_NAME}}-macos-debug.pkg" >> $GITHUB_ENV + + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Read Version + run: | + echo "VERSION=$(tr -d '[:space:]' < VERSION.md)" >> $GITHUB_ENV + + - name: Set Up Mac + run: brew install ninja osxutils + + - name: Select CMake Preset + run: | + cmake --preset "Mac Debug" \ + -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" + + - name: Build + run: cmake --build build --config "Debug" + + - name: Copy Build Artifacts + run: | + mkdir -p artifacts + cp -r ${{env.BUILD_ARTIFACTS_DIR}}/VST3/${{env.PROJECT_NAME}}.vst3 \ + artifacts/ + cp -r ${{env.BUILD_ARTIFACTS_DIR}}/CLAP/${{env.PROJECT_NAME}}.clap \ + artifacts/ + cp -r ${{env.BUILD_ARTIFACTS_DIR}}/AU/${{env.PROJECT_NAME}}.component \ + artifacts/ + shell: bash + + - name: Import Certificates + uses: sudara/basic-macos-keychain-action@v1 + id: keychain + with: + dev-id-app-cert: ${{ secrets.DEV_ID_APP_CERT }} + dev-id-app-password: ${{ secrets.DEV_ID_PASSWORD }} + dev-id-installer-cert: ${{ secrets.DEV_ID_INSTALL_CERT }} + dev-id-installer-password: ${{ secrets.DEV_ID_PASSWORD }} + + - name: Codesign (macOS) + run: | + # Set variables + VST3_BIN="artifacts/${{env.PROJECT_NAME}}.vst3/Contents/MacOS/${{env.PROJECT_NAME}}" + CLAP_BIN="artifacts/${{env.PROJECT_NAME}}.clap/Contents/MacOS/${{env.PROJECT_NAME}}" + AU_BIN="artifacts/${{env.PROJECT_NAME}}.component/Contents/MacOS/${{env.PROJECT_NAME}}" + + # Codesign the binaries + codesign \ + --force -s "${{secrets.DEVELOPER_ID_APPLICATION}}" \ + -v "$VST3_BIN" \ + --deep --strict --options=runtime --timestamp + codesign \ + --force -s "${{secrets.DEVELOPER_ID_APPLICATION}}" \ + -v "$CLAP_BIN" \ + --deep --strict --options=runtime --timestamp + codesign \ + --force -s "${{secrets.DEVELOPER_ID_APPLICATION}}" \ + -v "$AU_BIN" \ + --deep --strict --options=runtime --timestamp + shell: bash + + - name: Create Installer + run: | + # Set variables + VST3_PATH="artifacts/${{env.PROJECT_NAME}}.vst3" + CLAP_PATH="artifacts/${{env.PROJECT_NAME}}.clap" + AU_PATH="artifacts/${{env.PROJECT_NAME}}.component" + PACKAGE_NAME="${{env.PROJECT_NAME}}-macos-debug.pkg" + + # Create the packaging directory + mkdir -p packaging + + # Create the distribution file + envsubst < pkg/mac/distribution.xml > packaging/distribution.xml + + # Create the VST subpackage + pkgbuild \ + --identifier "${{env.BUNDLE_ID}}.vst3.pkg" \ + --version "$VERSION" \ + --component "$VST3_PATH" \ + --install-location "/Library/Audio/Plug-Ins/VST3" \ + "packaging/${{env.PROJECT_NAME}}.vst3.pkg" + + # Create the CLAP subpackage + pkgbuild \ + --identifier "${{env.BUNDLE_ID}}.clap.pkg" \ + --version "$VERSION" \ + --component "$CLAP_PATH" \ + --install-location "/Library/Audio/Plug-Ins/CLAP" \ + "packaging/${{env.PROJECT_NAME}}.clap.pkg" + + # Create the AU subpackage + pkgbuild \ + --identifier "${{env.BUNDLE_ID}}.au.pkg" \ + --version "$VERSION" \ + --component "$AU_PATH" \ + --install-location "/Library/Audio/Plug-Ins/Components" \ + "packaging/${{env.PROJECT_NAME}}.au.pkg" + + # Create the main package + cd packaging + productbuild \ + --resources ./resources \ + --distribution distribution.xml \ + --sign "${{secrets.DEVELOPER_ID_INSTALLER}}" \ + --timestamp "${{env.PROJECT_NAME}}.pkg" + + # Notarize the package + xcrun notarytool submit "${{env.PROJECT_NAME}}.pkg" \ + --apple-id ${{secrets.NOTARIZATION_USERNAME}} \ + --password ${{secrets.NOTARIZATION_PASSWORD}} \ + --team-id ${{secrets.TEAM_ID}} \ + --wait + + # Staple the package + xcrun stapler staple "${{env.PROJECT_NAME}}.pkg" + + # Move the package to the artifacts directory + mv ${{env.PROJECT_NAME}}.pkg ../artifacts/${{env.MAC_PACKAGE}} + shell: bash + + - name: Upload Artifacts + uses: actions/upload-artifact@v4 + with: + name: artifacts-macos-debug + path: artifacts + + #========================================================================================= + # Ubuntu Linux Build + #========================================================================================= + build-ubuntu: + runs-on: ubuntu-latest + steps: + - name: Export Variables + run: | + echo "BUILD_ARTIFACTS_DIR=$BUILD_DIR/src/${{env.PROJECT_NAME}}Plugin_artefacts/Debug" >> $GITHUB_ENV + echo "UBUNTU_PACKAGE=${{env.BUNDLE_NAME}}-linux-ubuntu-debug.deb" >> $GITHUB_ENV + echo "LINUX_PACKAGE=${{env.BUNDLE_NAME}}-linux-vanilla-debug.zip" >> $GITHUB_ENV + + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Read Version + run: | + echo "VERSION=$(tr -d '[:space:]' < VERSION.md)" >> $GITHUB_ENV + + - name: Set Up Linux + run: | + sudo apt-get update + sudo apt-get install ninja-build + sudo apt install libasound2-dev \ + libjack-jackd2-dev \ + ladspa-sdk \ + libcurl4-openssl-dev \ + libfreetype-dev \ + libfontconfig1-dev \ + libx11-dev \ + libxcomposite-dev \ + libxcursor-dev \ + libxext-dev \ + libxinerama-dev \ + libxrandr-dev \ + libxrender-dev \ + libwebkit2gtk-4.1-dev \ + libglu1-mesa-dev mesa-common-dev + sudo apt install curl + sudo apt-get install -y dpkg-dev devscripts + sudo /usr/bin/Xvfb $DISPLAY & + shell: bash + + - name: Select CMake Preset + run: | + cmake --preset "Linux Debug" + + - name: Build + run: cmake --build build --config "Debug" + + - name: Copy Artifacts + run: | + mkdir -p artifacts + cp -r ${{env.BUILD_ARTIFACTS_DIR}}/VST3/${{env.PROJECT_NAME}}.vst3 \ + artifacts/ + cp -r ${{env.BUILD_ARTIFACTS_DIR}}/CLAP/${{env.PROJECT_NAME}}.clap \ + artifacts/ + cp -r ${{env.BUILD_ARTIFACTS_DIR}}/LV2/${{env.PROJECT_NAME}}.lv2 \ + artifacts/ + shell: bash + + - name: Package Linux Artifacts + run: | + # Set variables + UBUNTU_PACKAGE_DIR="${{env.BUNDLE_NAME}}-linux-ubuntu-debug" + UBUNTU_CONTROL_FILE="pkg/ubuntu/control" + VST3_INSTALL_DIR="/usr/lib/vst3/${{env.PROJECT_NAME}}" + CLAP_INSTALL_DIR="/usr/lib/clap/${{env.PROJECT_NAME}}" + LV2_INSTALL_DIR="/usr/lib/lv2/${{env.PROJECT_NAME}}" + + # Create Vanilla package directory + mkdir -p vanilla + cp -r artifacts/${{env.PROJECT_NAME}}.vst3 vanilla/ + cp -r artifacts/${{env.PROJECT_NAME}}.clap vanilla/ + cp -r artifacts/${{env.PROJECT_NAME}}.lv2 vanilla/ + + # Zip and move the package to the artifacts directory + zip -r ${{env.LINUX_PACKAGE}} vanilla/* + mv ${{env.LINUX_PACKAGE}} artifacts/$LINUX_PACKAGE + + # Create Debian package directory + mkdir -p $UBUNTU_PACKAGE_DIR/DEBIAN + mkdir -p $UBUNTU_PACKAGE_DIR/$VST3_INSTALL_DIR + mkdir -p $UBUNTU_PACKAGE_DIR/$CLAP_INSTALL_DIR + mkdir -p $UBUNTU_PACKAGE_DIR/$LV2_INSTALL_DIR + + # Copy files to Debian package directory + cp -r artifacts/${{env.PROJECT_NAME}}.vst3 \ + $UBUNTU_PACKAGE_DIR/$VST3_INSTALL_DIR/ + cp -r artifacts/${{env.PROJECT_NAME}}.clap \ + $UBUNTU_PACKAGE_DIR/$CLAP_INSTALL_DIR/ + cp -r artifacts/${{env.PROJECT_NAME}}.lv2 \ + $UBUNTU_PACKAGE_DIR/$LV2_INSTALL_DIR/ + + # Set PACKAGE_NAME for envsubst + export PACKAGE_NAME=${{env.BUNDLE_NAME}} + export PACKAGE_VERSION=$VERSION + + # Replace PACKAGE_NAME in control file and copy to Debian package directory + envsubst < $UBUNTU_CONTROL_FILE > $UBUNTU_PACKAGE_DIR/DEBIAN/control + + # Build Debian package + dpkg-deb --build $UBUNTU_PACKAGE_DIR + + # Move the package to the artifacts directory + cp -r *.deb artifacts/${{env.UBUNTU_PACKAGE}} + shell: bash + + - name: Upload Artifacts + uses: actions/upload-artifact@v4 + with: + name: artifacts-ubuntu-debug + path: artifacts + + #========================================================================================= + # Arch Linux Build + #========================================================================================= + build-archlinux: + runs-on: ubuntu-latest + container: + image: archlinux:latest + steps: + - name: Export Variables + run: | + echo "BUILD_ARTIFACTS_DIR=$BUILD_DIR/src/${{env.PROJECT_NAME}}Plugin_artefacts/Debug" >> $GITHUB_ENV + echo "PACKAGE_NAME=${{env.BUNDLE_NAME}}-linux-arch-debug.pkg.tar.zst" >> $GITHUB_ENV + + - name: Install Base Packages + run: | + pacman -Sy --noconfirm base-devel git + + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Read Version + run: | + echo "VERSION=$(tr -d '[:space:]' < VERSION.md)" >> $GITHUB_ENV + + - name: Create user for build process + run: | + useradd -m dimethoxy + sudo su - dimethoxy + + - name: Set permissions for the build directory + run: | + sudo chown -R dimethoxy:dimethoxy /__w/${{env.PROJECT_NAME}}/${{env.PROJECT_NAME}}/pkg/arch/release + sudo chmod -R u+rw /__w/${{env.PROJECT_NAME}}/${{env.PROJECT_NAME}}/pkg/arch/release + + - name: Disable sudo password prompt + run: | + echo 'dimethoxy ALL=(ALL) NOPASSWD: ALL' | sudo tee -a /etc/sudoers + + - name: Build Package + run: | + sudo -u dimethoxy bash -c 'cd pkg/arch/release && makepkg -s --noconfirm' + + - name: Package Artifacts + run: | + # Remove the default package + rm pkg/arch/release/*debug*.pkg.tar.zst + + # Move the package to the root directory + mv pkg/arch/release/*.pkg.tar.zst . + + # Rename the package + mv *.pkg.tar.zst ${{env.PACKAGE_NAME}} + + # Move the package to the artifacts directory + mkdir -p artifacts + mv ${{env.PACKAGE_NAME}} artifacts/ + shell: bash + + - name: Upload Artifacts + uses: actions/upload-artifact@v4 + with: + name: artifacts-archlinux-debug + path: artifacts From 23164234a1739d425f05321041f039e36d707606 Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Fri, 8 May 2026 02:49:16 +0200 Subject: [PATCH 61/74] feat: add packaging for debug symbols across Windows, macOS, and Linux builds --- .github/workflows/ci-debug.yml | 66 ++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/.github/workflows/ci-debug.yml b/.github/workflows/ci-debug.yml index 96baff44..ca12c75a 100644 --- a/.github/workflows/ci-debug.yml +++ b/.github/workflows/ci-debug.yml @@ -95,6 +95,18 @@ jobs: artifacts/ shell: bash + - name: Package Debug Symbols (Windows) + run: | + mkdir -p artifacts/debug-symbols + find ${{env.BUILD_ARTIFACTS_DIR}} -name "*.pdb" -type f | while read pdb; do + cp "$pdb" artifacts/debug-symbols/ + done + if [ -f artifacts/debug-symbols/*.pdb ]; then + cd artifacts + zip -r ${{env.BUNDLE_NAME}}-windows-debug-symbols.zip debug-symbols/ + fi + shell: bash + - name: Create Installer run: | # Create the packaging directory @@ -154,6 +166,37 @@ jobs: artifacts/ shell: bash + - name: Package Debug Symbols (macOS) + run: | + mkdir -p artifacts/debug-symbols + + # Extract dSYM from binaries if they exist + VST3_BIN="${{env.BUILD_ARTIFACTS_DIR}}/VST3/${{env.PROJECT_NAME}}.vst3/Contents/MacOS/${{env.PROJECT_NAME}}" + CLAP_BIN="${{env.BUILD_ARTIFACTS_DIR}}/CLAP/${{env.PROJECT_NAME}}.clap/Contents/MacOS/${{env.PROJECT_NAME}}" + AU_BIN="${{env.BUILD_ARTIFACTS_DIR}}/AU/${{env.PROJECT_NAME}}.component/Contents/MacOS/${{env.PROJECT_NAME}}" + + for binary in "$VST3_BIN" "$CLAP_BIN" "$AU_BIN"; do + if [ -f "$binary" ]; then + # Copy the dSYM if it exists + dSYM_PATH="${binary}.dSYM" + if [ -d "$dSYM_PATH" ]; then + cp -r "$dSYM_PATH" artifacts/debug-symbols/ + fi + fi + done + + # Also check the build directory for dSYM files + find build -name "*.dSYM" -type d 2>/dev/null | while read dsym; do + cp -r "$dsym" artifacts/debug-symbols/ + done + + # Create debug symbols archive if any symbols were found + if [ -n "$(ls artifacts/debug-symbols/ 2>/dev/null)" ]; then + cd artifacts + zip -r ${{env.BUNDLE_NAME}}-macos-debug-symbols.zip debug-symbols/ + fi + shell: bash + - name: Import Certificates uses: sudara/basic-macos-keychain-action@v1 id: keychain @@ -312,6 +355,29 @@ jobs: artifacts/ shell: bash + - name: Extract Debug Symbols (Linux) + run: | + mkdir -p artifacts/debug-symbols + + # Extract debug symbols from binaries using objcopy + find ${{env.BUILD_ARTIFACTS_DIR}} -type f -name "${{env.PROJECT_NAME}}" -o -name "*.so" 2>/dev/null | while read binary; do + if file "$binary" | grep -q ELF; then + # Get the basename for the debug file + basename=$(basename "$binary") + debug_file="artifacts/debug-symbols/${basename}.debug" + objcopy --only-keep-debug "$binary" "$debug_file" 2>/dev/null || true + # Strip the binary + objcopy --strip-debug "$binary" 2>/dev/null || true + fi + done + + # Create debug symbols archive if any symbols were found + if [ -n "$(ls artifacts/debug-symbols/ 2>/dev/null)" ]; then + cd artifacts + zip -r ${{env.LINUX_PACKAGE%.*}}-symbols.zip debug-symbols/ + fi + shell: bash + - name: Package Linux Artifacts run: | # Set variables From c17461934eed93b2175b13dbfc5ad3475d178616 Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Fri, 8 May 2026 02:55:27 +0200 Subject: [PATCH 62/74] fix: remove macOS and Linux build steps from CI workflow --- .github/workflows/ci-debug.yml | 369 --------------------------------- 1 file changed, 369 deletions(-) diff --git a/.github/workflows/ci-debug.yml b/.github/workflows/ci-debug.yml index ca12c75a..44dadc76 100644 --- a/.github/workflows/ci-debug.yml +++ b/.github/workflows/ci-debug.yml @@ -125,372 +125,3 @@ jobs: with: name: artifacts-windows-debug path: artifacts - - #========================================================================================= - # macOS Build - #========================================================================================= - build-macos: - runs-on: macos-latest - steps: - - name: Export Variables - run: | - echo "BUILD_ARTIFACTS_DIR=$BUILD_DIR/src/${{env.PROJECT_NAME}}Plugin_artefacts/Debug" >> $GITHUB_ENV - echo "MAC_PACKAGE=${{env.BUNDLE_NAME}}-macos-debug.pkg" >> $GITHUB_ENV - - - name: Checkout Code - uses: actions/checkout@v4 - - - name: Read Version - run: | - echo "VERSION=$(tr -d '[:space:]' < VERSION.md)" >> $GITHUB_ENV - - - name: Set Up Mac - run: brew install ninja osxutils - - - name: Select CMake Preset - run: | - cmake --preset "Mac Debug" \ - -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" - - - name: Build - run: cmake --build build --config "Debug" - - - name: Copy Build Artifacts - run: | - mkdir -p artifacts - cp -r ${{env.BUILD_ARTIFACTS_DIR}}/VST3/${{env.PROJECT_NAME}}.vst3 \ - artifacts/ - cp -r ${{env.BUILD_ARTIFACTS_DIR}}/CLAP/${{env.PROJECT_NAME}}.clap \ - artifacts/ - cp -r ${{env.BUILD_ARTIFACTS_DIR}}/AU/${{env.PROJECT_NAME}}.component \ - artifacts/ - shell: bash - - - name: Package Debug Symbols (macOS) - run: | - mkdir -p artifacts/debug-symbols - - # Extract dSYM from binaries if they exist - VST3_BIN="${{env.BUILD_ARTIFACTS_DIR}}/VST3/${{env.PROJECT_NAME}}.vst3/Contents/MacOS/${{env.PROJECT_NAME}}" - CLAP_BIN="${{env.BUILD_ARTIFACTS_DIR}}/CLAP/${{env.PROJECT_NAME}}.clap/Contents/MacOS/${{env.PROJECT_NAME}}" - AU_BIN="${{env.BUILD_ARTIFACTS_DIR}}/AU/${{env.PROJECT_NAME}}.component/Contents/MacOS/${{env.PROJECT_NAME}}" - - for binary in "$VST3_BIN" "$CLAP_BIN" "$AU_BIN"; do - if [ -f "$binary" ]; then - # Copy the dSYM if it exists - dSYM_PATH="${binary}.dSYM" - if [ -d "$dSYM_PATH" ]; then - cp -r "$dSYM_PATH" artifacts/debug-symbols/ - fi - fi - done - - # Also check the build directory for dSYM files - find build -name "*.dSYM" -type d 2>/dev/null | while read dsym; do - cp -r "$dsym" artifacts/debug-symbols/ - done - - # Create debug symbols archive if any symbols were found - if [ -n "$(ls artifacts/debug-symbols/ 2>/dev/null)" ]; then - cd artifacts - zip -r ${{env.BUNDLE_NAME}}-macos-debug-symbols.zip debug-symbols/ - fi - shell: bash - - - name: Import Certificates - uses: sudara/basic-macos-keychain-action@v1 - id: keychain - with: - dev-id-app-cert: ${{ secrets.DEV_ID_APP_CERT }} - dev-id-app-password: ${{ secrets.DEV_ID_PASSWORD }} - dev-id-installer-cert: ${{ secrets.DEV_ID_INSTALL_CERT }} - dev-id-installer-password: ${{ secrets.DEV_ID_PASSWORD }} - - - name: Codesign (macOS) - run: | - # Set variables - VST3_BIN="artifacts/${{env.PROJECT_NAME}}.vst3/Contents/MacOS/${{env.PROJECT_NAME}}" - CLAP_BIN="artifacts/${{env.PROJECT_NAME}}.clap/Contents/MacOS/${{env.PROJECT_NAME}}" - AU_BIN="artifacts/${{env.PROJECT_NAME}}.component/Contents/MacOS/${{env.PROJECT_NAME}}" - - # Codesign the binaries - codesign \ - --force -s "${{secrets.DEVELOPER_ID_APPLICATION}}" \ - -v "$VST3_BIN" \ - --deep --strict --options=runtime --timestamp - codesign \ - --force -s "${{secrets.DEVELOPER_ID_APPLICATION}}" \ - -v "$CLAP_BIN" \ - --deep --strict --options=runtime --timestamp - codesign \ - --force -s "${{secrets.DEVELOPER_ID_APPLICATION}}" \ - -v "$AU_BIN" \ - --deep --strict --options=runtime --timestamp - shell: bash - - - name: Create Installer - run: | - # Set variables - VST3_PATH="artifacts/${{env.PROJECT_NAME}}.vst3" - CLAP_PATH="artifacts/${{env.PROJECT_NAME}}.clap" - AU_PATH="artifacts/${{env.PROJECT_NAME}}.component" - PACKAGE_NAME="${{env.PROJECT_NAME}}-macos-debug.pkg" - - # Create the packaging directory - mkdir -p packaging - - # Create the distribution file - envsubst < pkg/mac/distribution.xml > packaging/distribution.xml - - # Create the VST subpackage - pkgbuild \ - --identifier "${{env.BUNDLE_ID}}.vst3.pkg" \ - --version "$VERSION" \ - --component "$VST3_PATH" \ - --install-location "/Library/Audio/Plug-Ins/VST3" \ - "packaging/${{env.PROJECT_NAME}}.vst3.pkg" - - # Create the CLAP subpackage - pkgbuild \ - --identifier "${{env.BUNDLE_ID}}.clap.pkg" \ - --version "$VERSION" \ - --component "$CLAP_PATH" \ - --install-location "/Library/Audio/Plug-Ins/CLAP" \ - "packaging/${{env.PROJECT_NAME}}.clap.pkg" - - # Create the AU subpackage - pkgbuild \ - --identifier "${{env.BUNDLE_ID}}.au.pkg" \ - --version "$VERSION" \ - --component "$AU_PATH" \ - --install-location "/Library/Audio/Plug-Ins/Components" \ - "packaging/${{env.PROJECT_NAME}}.au.pkg" - - # Create the main package - cd packaging - productbuild \ - --resources ./resources \ - --distribution distribution.xml \ - --sign "${{secrets.DEVELOPER_ID_INSTALLER}}" \ - --timestamp "${{env.PROJECT_NAME}}.pkg" - - # Notarize the package - xcrun notarytool submit "${{env.PROJECT_NAME}}.pkg" \ - --apple-id ${{secrets.NOTARIZATION_USERNAME}} \ - --password ${{secrets.NOTARIZATION_PASSWORD}} \ - --team-id ${{secrets.TEAM_ID}} \ - --wait - - # Staple the package - xcrun stapler staple "${{env.PROJECT_NAME}}.pkg" - - # Move the package to the artifacts directory - mv ${{env.PROJECT_NAME}}.pkg ../artifacts/${{env.MAC_PACKAGE}} - shell: bash - - - name: Upload Artifacts - uses: actions/upload-artifact@v4 - with: - name: artifacts-macos-debug - path: artifacts - - #========================================================================================= - # Ubuntu Linux Build - #========================================================================================= - build-ubuntu: - runs-on: ubuntu-latest - steps: - - name: Export Variables - run: | - echo "BUILD_ARTIFACTS_DIR=$BUILD_DIR/src/${{env.PROJECT_NAME}}Plugin_artefacts/Debug" >> $GITHUB_ENV - echo "UBUNTU_PACKAGE=${{env.BUNDLE_NAME}}-linux-ubuntu-debug.deb" >> $GITHUB_ENV - echo "LINUX_PACKAGE=${{env.BUNDLE_NAME}}-linux-vanilla-debug.zip" >> $GITHUB_ENV - - - name: Checkout Code - uses: actions/checkout@v4 - - - name: Read Version - run: | - echo "VERSION=$(tr -d '[:space:]' < VERSION.md)" >> $GITHUB_ENV - - - name: Set Up Linux - run: | - sudo apt-get update - sudo apt-get install ninja-build - sudo apt install libasound2-dev \ - libjack-jackd2-dev \ - ladspa-sdk \ - libcurl4-openssl-dev \ - libfreetype-dev \ - libfontconfig1-dev \ - libx11-dev \ - libxcomposite-dev \ - libxcursor-dev \ - libxext-dev \ - libxinerama-dev \ - libxrandr-dev \ - libxrender-dev \ - libwebkit2gtk-4.1-dev \ - libglu1-mesa-dev mesa-common-dev - sudo apt install curl - sudo apt-get install -y dpkg-dev devscripts - sudo /usr/bin/Xvfb $DISPLAY & - shell: bash - - - name: Select CMake Preset - run: | - cmake --preset "Linux Debug" - - - name: Build - run: cmake --build build --config "Debug" - - - name: Copy Artifacts - run: | - mkdir -p artifacts - cp -r ${{env.BUILD_ARTIFACTS_DIR}}/VST3/${{env.PROJECT_NAME}}.vst3 \ - artifacts/ - cp -r ${{env.BUILD_ARTIFACTS_DIR}}/CLAP/${{env.PROJECT_NAME}}.clap \ - artifacts/ - cp -r ${{env.BUILD_ARTIFACTS_DIR}}/LV2/${{env.PROJECT_NAME}}.lv2 \ - artifacts/ - shell: bash - - - name: Extract Debug Symbols (Linux) - run: | - mkdir -p artifacts/debug-symbols - - # Extract debug symbols from binaries using objcopy - find ${{env.BUILD_ARTIFACTS_DIR}} -type f -name "${{env.PROJECT_NAME}}" -o -name "*.so" 2>/dev/null | while read binary; do - if file "$binary" | grep -q ELF; then - # Get the basename for the debug file - basename=$(basename "$binary") - debug_file="artifacts/debug-symbols/${basename}.debug" - objcopy --only-keep-debug "$binary" "$debug_file" 2>/dev/null || true - # Strip the binary - objcopy --strip-debug "$binary" 2>/dev/null || true - fi - done - - # Create debug symbols archive if any symbols were found - if [ -n "$(ls artifacts/debug-symbols/ 2>/dev/null)" ]; then - cd artifacts - zip -r ${{env.LINUX_PACKAGE%.*}}-symbols.zip debug-symbols/ - fi - shell: bash - - - name: Package Linux Artifacts - run: | - # Set variables - UBUNTU_PACKAGE_DIR="${{env.BUNDLE_NAME}}-linux-ubuntu-debug" - UBUNTU_CONTROL_FILE="pkg/ubuntu/control" - VST3_INSTALL_DIR="/usr/lib/vst3/${{env.PROJECT_NAME}}" - CLAP_INSTALL_DIR="/usr/lib/clap/${{env.PROJECT_NAME}}" - LV2_INSTALL_DIR="/usr/lib/lv2/${{env.PROJECT_NAME}}" - - # Create Vanilla package directory - mkdir -p vanilla - cp -r artifacts/${{env.PROJECT_NAME}}.vst3 vanilla/ - cp -r artifacts/${{env.PROJECT_NAME}}.clap vanilla/ - cp -r artifacts/${{env.PROJECT_NAME}}.lv2 vanilla/ - - # Zip and move the package to the artifacts directory - zip -r ${{env.LINUX_PACKAGE}} vanilla/* - mv ${{env.LINUX_PACKAGE}} artifacts/$LINUX_PACKAGE - - # Create Debian package directory - mkdir -p $UBUNTU_PACKAGE_DIR/DEBIAN - mkdir -p $UBUNTU_PACKAGE_DIR/$VST3_INSTALL_DIR - mkdir -p $UBUNTU_PACKAGE_DIR/$CLAP_INSTALL_DIR - mkdir -p $UBUNTU_PACKAGE_DIR/$LV2_INSTALL_DIR - - # Copy files to Debian package directory - cp -r artifacts/${{env.PROJECT_NAME}}.vst3 \ - $UBUNTU_PACKAGE_DIR/$VST3_INSTALL_DIR/ - cp -r artifacts/${{env.PROJECT_NAME}}.clap \ - $UBUNTU_PACKAGE_DIR/$CLAP_INSTALL_DIR/ - cp -r artifacts/${{env.PROJECT_NAME}}.lv2 \ - $UBUNTU_PACKAGE_DIR/$LV2_INSTALL_DIR/ - - # Set PACKAGE_NAME for envsubst - export PACKAGE_NAME=${{env.BUNDLE_NAME}} - export PACKAGE_VERSION=$VERSION - - # Replace PACKAGE_NAME in control file and copy to Debian package directory - envsubst < $UBUNTU_CONTROL_FILE > $UBUNTU_PACKAGE_DIR/DEBIAN/control - - # Build Debian package - dpkg-deb --build $UBUNTU_PACKAGE_DIR - - # Move the package to the artifacts directory - cp -r *.deb artifacts/${{env.UBUNTU_PACKAGE}} - shell: bash - - - name: Upload Artifacts - uses: actions/upload-artifact@v4 - with: - name: artifacts-ubuntu-debug - path: artifacts - - #========================================================================================= - # Arch Linux Build - #========================================================================================= - build-archlinux: - runs-on: ubuntu-latest - container: - image: archlinux:latest - steps: - - name: Export Variables - run: | - echo "BUILD_ARTIFACTS_DIR=$BUILD_DIR/src/${{env.PROJECT_NAME}}Plugin_artefacts/Debug" >> $GITHUB_ENV - echo "PACKAGE_NAME=${{env.BUNDLE_NAME}}-linux-arch-debug.pkg.tar.zst" >> $GITHUB_ENV - - - name: Install Base Packages - run: | - pacman -Sy --noconfirm base-devel git - - - name: Checkout Repository - uses: actions/checkout@v4 - - - name: Read Version - run: | - echo "VERSION=$(tr -d '[:space:]' < VERSION.md)" >> $GITHUB_ENV - - - name: Create user for build process - run: | - useradd -m dimethoxy - sudo su - dimethoxy - - - name: Set permissions for the build directory - run: | - sudo chown -R dimethoxy:dimethoxy /__w/${{env.PROJECT_NAME}}/${{env.PROJECT_NAME}}/pkg/arch/release - sudo chmod -R u+rw /__w/${{env.PROJECT_NAME}}/${{env.PROJECT_NAME}}/pkg/arch/release - - - name: Disable sudo password prompt - run: | - echo 'dimethoxy ALL=(ALL) NOPASSWD: ALL' | sudo tee -a /etc/sudoers - - - name: Build Package - run: | - sudo -u dimethoxy bash -c 'cd pkg/arch/release && makepkg -s --noconfirm' - - - name: Package Artifacts - run: | - # Remove the default package - rm pkg/arch/release/*debug*.pkg.tar.zst - - # Move the package to the root directory - mv pkg/arch/release/*.pkg.tar.zst . - - # Rename the package - mv *.pkg.tar.zst ${{env.PACKAGE_NAME}} - - # Move the package to the artifacts directory - mkdir -p artifacts - mv ${{env.PACKAGE_NAME}} artifacts/ - shell: bash - - - name: Upload Artifacts - uses: actions/upload-artifact@v4 - with: - name: artifacts-archlinux-debug - path: artifacts From 927eb243bc86d58e9dfb8316db518c58535bbfc2 Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Fri, 8 May 2026 10:46:55 +0200 Subject: [PATCH 63/74] fix: make sure to properly stop timers in destructors --- src/dmt/app/AbstractPluginEditor.h | 11 ++++++++++- src/dmt/gui/display/AbstractDisplay.h | 5 +++++ src/dmt/gui/display/OscilloscopeDisplay.h | 3 +++ src/dmt/gui/widget/BorderButton.h | 7 ++++++- src/dmt/gui/window/Alerts.h | 6 ++++++ src/dmt/gui/window/Compositor.h | 9 ++++++++- src/dmt/gui/window/Tooltip.h | 2 +- src/dmt/utility/RepaintTimer.h | 2 +- 8 files changed, 40 insertions(+), 5 deletions(-) diff --git a/src/dmt/app/AbstractPluginEditor.h b/src/dmt/app/AbstractPluginEditor.h index 39a5dbe6..0a8214a9 100644 --- a/src/dmt/app/AbstractPluginEditor.h +++ b/src/dmt/app/AbstractPluginEditor.h @@ -94,7 +94,16 @@ class AbstractPluginEditor }); } - ~AbstractPluginEditor() override = default; + ~AbstractPluginEditor() + { + // Ensure OpenGL context is detached before destruction + if (openGLContext.isAttached()) { + openGLContext.detach(); + } + + // Stop the debounce timer if it's running + stopTimer(); + } //============================================================================== // JUCE overrides diff --git a/src/dmt/gui/display/AbstractDisplay.h b/src/dmt/gui/display/AbstractDisplay.h index 34080e51..0aa88115 100644 --- a/src/dmt/gui/display/AbstractDisplay.h +++ b/src/dmt/gui/display/AbstractDisplay.h @@ -106,6 +106,11 @@ class AbstractDisplay addAndMakeVisible(innerShadow); } + //============================================================================ + /** @brief Destructor for `AbstractDisplay`. + */ + inline ~AbstractDisplay() { stopRepaintTimer(); } + //============================================================================== /** * @brief Paints the component, including background, border, and display diff --git a/src/dmt/gui/display/OscilloscopeDisplay.h b/src/dmt/gui/display/OscilloscopeDisplay.h index 36d10531..3b7c00de 100644 --- a/src/dmt/gui/display/OscilloscopeDisplay.h +++ b/src/dmt/gui/display/OscilloscopeDisplay.h @@ -113,6 +113,9 @@ class OscilloscopeDisplay apvts.removeParameterListener("OscilloscopeThickness", this); apvts.removeParameterListener("OscilloscopeGain", this); } + + // Stop the repaint timer + stopRepaintTimer(); } //============================================================================== void extendResized( diff --git a/src/dmt/gui/widget/BorderButton.h b/src/dmt/gui/widget/BorderButton.h index 175e1e96..3865c5ed 100644 --- a/src/dmt/gui/widget/BorderButton.h +++ b/src/dmt/gui/widget/BorderButton.h @@ -101,7 +101,12 @@ class BorderButton /** * @brief Destructor for BorderButton. */ - ~BorderButton() override = default; + ~BorderButton() override + { + TRACER("BorderButton::~BorderButton"); + // Stop the repaint timer to clean up resources + stopRepaintTimer(); + } //============================================================================== /** diff --git a/src/dmt/gui/window/Alerts.h b/src/dmt/gui/window/Alerts.h index 44505048..c9c47b33 100644 --- a/src/dmt/gui/window/Alerts.h +++ b/src/dmt/gui/window/Alerts.h @@ -174,6 +174,12 @@ class Alerts startRepaintTimer(); } + //============================================================================== + /** + * @brief Destructor for `Alerts`. + */ + inline ~Alerts() { stopRepaintTimer(); } + //============================================================================== /** * @brief Pushes a new alert to the overlay. diff --git a/src/dmt/gui/window/Compositor.h b/src/dmt/gui/window/Compositor.h index f75f7514..5083a398 100644 --- a/src/dmt/gui/window/Compositor.h +++ b/src/dmt/gui/window/Compositor.h @@ -159,7 +159,14 @@ class Compositor //============================================================================ /** @brief Destructor for `Compositor`. */ - ~Compositor() noexcept override { removeListenerRecursively(this); } + ~Compositor() + { + // Stop listening for hierarchy changes + removeListenerRecursively(this); + + // Stop timer if it's running + stopTimer(); + } //============================================================================ /** @brief Paints the component. */ diff --git a/src/dmt/gui/window/Tooltip.h b/src/dmt/gui/window/Tooltip.h index bd9c6d48..f90556bc 100644 --- a/src/dmt/gui/window/Tooltip.h +++ b/src/dmt/gui/window/Tooltip.h @@ -110,7 +110,7 @@ class Tooltip /** * @brief Destructor. */ - inline ~Tooltip() override = default; + inline ~Tooltip() { stopRepaintTimer(); } //============================================================================== /** diff --git a/src/dmt/utility/RepaintTimer.h b/src/dmt/utility/RepaintTimer.h index c8006aa9..75ac0819 100644 --- a/src/dmt/utility/RepaintTimer.h +++ b/src/dmt/utility/RepaintTimer.h @@ -85,7 +85,7 @@ class RepaintTimer : private juce::Timer * Ensures that the timer is stopped and resources are released. No * side-effects beyond JUCE Timer cleanup. */ - inline ~RepaintTimer() noexcept override = default; + inline ~RepaintTimer() { stopRepaintTimer(); } //============================================================================ /** From 83dd0d48caa2f77d962e77134571c039bba5f5ac Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Fri, 8 May 2026 12:25:58 +0200 Subject: [PATCH 64/74] fix: implement destructors to properly remove listeners in GUI components --- src/dmt/gui/component/LinearSliderComponent.h | 11 +++++++++++ src/dmt/gui/component/RotarySliderComponent.h | 10 ++++++++++ src/dmt/gui/panel/AbstractPanel.h | 13 +++++++++++++ src/dmt/gui/preset/FolderManager.h | 2 ++ src/dmt/gui/window/Compositor.h | 10 +++++----- 5 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/dmt/gui/component/LinearSliderComponent.h b/src/dmt/gui/component/LinearSliderComponent.h index 8b67b656..35f63633 100644 --- a/src/dmt/gui/component/LinearSliderComponent.h +++ b/src/dmt/gui/component/LinearSliderComponent.h @@ -123,6 +123,17 @@ class LinearSliderComponent }; } + /** + * @brief + * + */ + ~LinearSliderComponent() + { + TRACER("LinearSliderComponent::~LinearSliderComponent"); + // Remove slider listener + slider.removeListener(this); + } + /** * @brief Lays out the child components. * diff --git a/src/dmt/gui/component/RotarySliderComponent.h b/src/dmt/gui/component/RotarySliderComponent.h index 538e490f..4f6ecd52 100644 --- a/src/dmt/gui/component/RotarySliderComponent.h +++ b/src/dmt/gui/component/RotarySliderComponent.h @@ -110,6 +110,16 @@ class RotarySliderComponent }; } + /** + * @brief Destructor for `RotarySliderComponent`. + */ + ~RotarySliderComponent() + { + TRACER("RotarySliderComponent::~RotarySliderComponent"); + // Remove slider listener + slider.removeListener(this); + } + /** * @brief Handles component resizing and lays out child widgets. * diff --git a/src/dmt/gui/panel/AbstractPanel.h b/src/dmt/gui/panel/AbstractPanel.h index e18aab3d..14193cf5 100644 --- a/src/dmt/gui/panel/AbstractPanel.h +++ b/src/dmt/gui/panel/AbstractPanel.h @@ -142,6 +142,19 @@ class AbstractPanel addAndMakeVisible(innerShadow); } + //============================================================================== + /** + * @brief Destructor for `AbstractPanel`. + */ + ~AbstractPanel() override + { + TRACER("AbstractPanel::~AbstractPanel"); + + // Remove listeners + nextButton.removeListener(this); + prevButton.removeListener(this); + } + //============================================================================== /** * @brief Paints the panel, including background, border, and debug overlays. diff --git a/src/dmt/gui/preset/FolderManager.h b/src/dmt/gui/preset/FolderManager.h index 88e977b0..ea4a8fb4 100644 --- a/src/dmt/gui/preset/FolderManager.h +++ b/src/dmt/gui/preset/FolderManager.h @@ -64,6 +64,8 @@ class FolderManager : juce::ValueTree::Listener valueTreeState.state.getPropertyAsValue(folderNameProperty, nullptr)); } + ~FolderManager() override { valueTreeState.state.removeListener(this); } + private: //============================================================================== juce::AudioProcessorValueTreeState& valueTreeState; diff --git a/src/dmt/gui/window/Compositor.h b/src/dmt/gui/window/Compositor.h index 5083a398..e5e5320e 100644 --- a/src/dmt/gui/window/Compositor.h +++ b/src/dmt/gui/window/Compositor.h @@ -159,13 +159,13 @@ class Compositor //============================================================================ /** @brief Destructor for `Compositor`. */ - ~Compositor() + ~Compositor() noexcept override { - // Stop listening for hierarchy changes - removeListenerRecursively(this); - - // Stop timer if it's running + // Stop timer FIRST to prevent callbacks during destruction stopTimer(); + + // Remove all component listeners to prevent callbacks from child components + removeListenerRecursively(this); } //============================================================================ From 67f9f662532948763f5cdafb3f0545bf92c63a26 Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Fri, 8 May 2026 12:33:29 +0200 Subject: [PATCH 65/74] fix: update Intel IPP installation to use the latest oneAPI toolkit version --- .github/workflows/ci-release.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci-release.yml b/.github/workflows/ci-release.yml index 413eb0e3..f4c61fd8 100644 --- a/.github/workflows/ci-release.yml +++ b/.github/workflows/ci-release.yml @@ -68,9 +68,8 @@ jobs: - name: Install IPP (Windows) if: steps.cache-ipp.outputs.cache-hit != 'true' run: | - curl --output oneapi.exe https://registrationcenter-download.intel.com/akdlm/IRC_NAS/2e89fab4-e1c7-4f14-a1ef-6cddba8c5fa7/intel-ipp-2022.0.0.796_offline.exe - ./oneapi.exe -s -x -f oneapi - ./oneapi/bootstrapper.exe -s -c --action install --components=intel.oneapi.win.ipp.devel --eula=accept -p=NEED_VS2022_INTEGRATION=1 --log-dir=. + curl --output intel-oneapi-toolkit-2026.0.0.193_offline.exe https://registrationcenter-download.intel.com/akdlm/IRC_NAS/bae85ab1-cfcd-4251-8d42-a0c27949ea33/intel-oneapi-toolkit-2026.0.0.193_offline.exe + ./intel-oneapi-toolkit-2026.0.0.193_offline.exe -s -a --silent --eula accept -p=NEED_VS2022_INTEGRATION=1 - name: Save IPP cache if: steps.cache-ipp.outputs.cache-hit != 'true' From f6ac4db119cd7e796691de9b80cba11888bc16c7 Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Fri, 8 May 2026 12:40:09 +0200 Subject: [PATCH 66/74] fix: update IPP cache key to reflect the latest version --- .github/workflows/ci-release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-release.yml b/.github/workflows/ci-release.yml index f4c61fd8..6595af9f 100644 --- a/.github/workflows/ci-release.yml +++ b/.github/workflows/ci-release.yml @@ -62,7 +62,7 @@ jobs: id: cache-ipp uses: actions/cache@v4 with: - key: ipp-v6 + key: ipp-2026-0-0-193 path: C:\Program Files (x86)\Intel - name: Install IPP (Windows) @@ -76,7 +76,7 @@ jobs: uses: actions/cache/save@v4 with: path: C:\Program Files (x86)\Intel - key: ipp-v6 + key: ipp-2026-0-0-193 - name: Select CMake Preset run: | From 8c3f26b2cd29f1a756a53f6852b449373eb27b53 Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Fri, 8 May 2026 12:53:09 +0200 Subject: [PATCH 67/74] fix: update IPP installation to use the latest oneAPI toolkit version --- .github/workflows/ci-debug.yml | 9 ++++----- .github/workflows/ci-snapshot.yml | 11 +++++------ 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci-debug.yml b/.github/workflows/ci-debug.yml index 44dadc76..12e4f318 100644 --- a/.github/workflows/ci-debug.yml +++ b/.github/workflows/ci-debug.yml @@ -62,22 +62,21 @@ jobs: id: cache-ipp uses: actions/cache@v4 with: - key: ipp-v6 + key: ipp-2026-0-0-193 path: C:\Program Files (x86)\Intel - name: Install IPP (Windows) if: steps.cache-ipp.outputs.cache-hit != 'true' run: | - curl --output oneapi.exe https://registrationcenter-download.intel.com/akdlm/IRC_NAS/2e89fab4-e1c7-4f14-a1ef-6cddba8c5fa7/intel-ipp-2022.0.0.796_offline.exe - ./oneapi.exe -s -x -f oneapi - ./oneapi/bootstrapper.exe -s -c --action install --components=intel.oneapi.win.ipp.devel --eula=accept -p=NEED_VS2022_INTEGRATION=1 --log-dir=. + curl --output intel-oneapi-toolkit-2026.0.0.193_offline.exe https://registrationcenter-download.intel.com/akdlm/IRC_NAS/bae85ab1-cfcd-4251-8d42-a0c27949ea33/intel-oneapi-toolkit-2026.0.0.193_offline.exe + ./intel-oneapi-toolkit-2026.0.0.193_offline.exe -s -a --silent --eula accept -p=NEED_VS2022_INTEGRATION=1 - name: Save IPP cache if: steps.cache-ipp.outputs.cache-hit != 'true' uses: actions/cache/save@v4 with: path: C:\Program Files (x86)\Intel - key: ipp-v6 + key: ipp-2026-0-0-193 - name: Select CMake Preset run: | diff --git a/.github/workflows/ci-snapshot.yml b/.github/workflows/ci-snapshot.yml index 55b54ea1..a9151386 100644 --- a/.github/workflows/ci-snapshot.yml +++ b/.github/workflows/ci-snapshot.yml @@ -68,22 +68,21 @@ jobs: id: cache-ipp uses: actions/cache@v4 with: - key: ipp-v6 + key: ipp-2026-0-0-193 path: C:\Program Files (x86)\Intel - name: Install IPP (Windows) if: steps.cache-ipp.outputs.cache-hit != 'true' run: | - curl --output oneapi.exe https://registrationcenter-download.intel.com/akdlm/IRC_NAS/2e89fab4-e1c7-4f14-a1ef-6cddba8c5fa7/intel-ipp-2022.0.0.796_offline.exe - ./oneapi.exe -s -x -f oneapi - ./oneapi/bootstrapper.exe -s -c --action install --components=intel.oneapi.win.ipp.devel --eula=accept -p=NEED_VS2022_INTEGRATION=1 --log-dir=. + curl --output intel-oneapi-toolkit-2026.0.0.193_offline.exe https://registrationcenter-download.intel.com/akdlm/IRC_NAS/bae85ab1-cfcd-4251-8d42-a0c27949ea33/intel-oneapi-toolkit-2026.0.0.193_offline.exe + ./intel-oneapi-toolkit-2026.0.0.193_offline.exe -s -a --silent --eula accept -p=NEED_VS2022_INTEGRATION=1 - name: Save IPP cache if: steps.cache-ipp.outputs.cache-hit != 'true' uses: actions/cache/save@v4 with: path: C:\Program Files (x86)\Intel - key: ipp-v6 + key: ipp-2026-0-0-193 - name: Select CMake Preset run: | @@ -440,7 +439,7 @@ jobs: #========================================================================================= release: runs-on: ubuntu-latest - needs: [ build-windows, build-ubuntu, build-macos, build-archlinux ] + needs: [build-windows, build-ubuntu, build-macos, build-archlinux] env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 5f83645ae104a8d9f0aa68f27ea483504bcad882 Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Fri, 8 May 2026 14:00:26 +0200 Subject: [PATCH 68/74] fix: track last repaint time for frame-independent timing in Alerts --- src/dmt/gui/window/Alerts.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/dmt/gui/window/Alerts.h b/src/dmt/gui/window/Alerts.h index c9c47b33..120c9726 100644 --- a/src/dmt/gui/window/Alerts.h +++ b/src/dmt/gui/window/Alerts.h @@ -128,6 +128,8 @@ class Alerts const bool& drawInnerShadow = AlertSettings::drawInnerShadow; public: + // Track last repaint time for frame-independent timing + double lastRepaintTimeMs = juce::Time::getMillisecondCounterHiRes(); //============================================================================== /** * @brief Alert type enumeration. @@ -290,8 +292,11 @@ class Alerts inline void repaintTimerCallback() noexcept override { TRACER("Alerts::repaintTimerCallback"); + double nowMs = juce::Time::getMillisecondCounterHiRes(); + double elapsedSec = (nowMs - lastRepaintTimeMs) * 0.001; + lastRepaintTimeMs = nowMs; for (int i = static_cast(alerts.size()); --i >= 0;) { - alerts.getReference(i).age += Settings::framerate / 1000.0f; + alerts.getReference(i).age += static_cast(elapsedSec); if (alerts.getReference(i).age >= maxAge) alerts.remove(i); } From e60cda0179e38e70db1fa0c703a37255374c074d Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Sat, 9 May 2026 01:51:43 +0200 Subject: [PATCH 69/74] debug: lobotomize the oscilloscope image scrolling to isolate a crash cause --- src/dmt/gui/widget/Oscilloscope.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/dmt/gui/widget/Oscilloscope.h b/src/dmt/gui/widget/Oscilloscope.h index 97f7b5d8..08c61251 100644 --- a/src/dmt/gui/widget/Oscilloscope.h +++ b/src/dmt/gui/widget/Oscilloscope.h @@ -329,18 +329,18 @@ class alignas(64) Oscilloscope : public juce::Thread backImage = images[static_cast(currentFront)].createCopy(); // Image move - const int destX = 0 - pixelToDraw; - backImage.moveImageSection(destX, // destX - 0, // destY - 0, // srcX - 0, // srcY - width + 10, // width - height); // height + // const int destX = 0 - pixelToDraw; + // backImage.moveImageSection(destX, // destX + // 0, // destY + // 0, // srcX + // 0, // srcY + // width + 10, // width + // height); // height // Clear the new part of the image - juce::Rectangle clearRect( - width - pixelToDraw + 10, 0, pixelToDraw, height); - backImage.clear(clearRect, juce::Colours::transparentBlack); + // juce::Rectangle clearRect( + // width - pixelToDraw + 10, 0, pixelToDraw, height); + // backImage.clear(clearRect, juce::Colours::transparentBlack); // Delegate drawing to the active renderer juce::Graphics imageGraphics(backImage); From 9190371fee07ba8f7ae10c85e832479ac980b3b1 Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Sat, 9 May 2026 02:28:39 +0200 Subject: [PATCH 70/74] fix: enable clearing of the oscilloscope image with a defined rectangle --- src/dmt/gui/widget/Oscilloscope.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dmt/gui/widget/Oscilloscope.h b/src/dmt/gui/widget/Oscilloscope.h index 08c61251..2c6b8c6f 100644 --- a/src/dmt/gui/widget/Oscilloscope.h +++ b/src/dmt/gui/widget/Oscilloscope.h @@ -338,9 +338,9 @@ class alignas(64) Oscilloscope : public juce::Thread // height); // height // Clear the new part of the image - // juce::Rectangle clearRect( - // width - pixelToDraw + 10, 0, pixelToDraw, height); - // backImage.clear(clearRect, juce::Colours::transparentBlack); + juce::Rectangle clearRect( + width - pixelToDraw + 10, 0, pixelToDraw, height); + backImage.clear(clearRect, juce::Colours::transparentBlack); // Delegate drawing to the active renderer juce::Graphics imageGraphics(backImage); From b9e0ac82dcdccf3f68f9ca301e8a09eb2fb7e6a7 Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Sat, 9 May 2026 03:02:35 +0200 Subject: [PATCH 71/74] fix: optimize oscilloscope rendering for improved performance and stability --- src/dmt/gui/widget/Oscilloscope.h | 70 ++++++++++++++++--------------- 1 file changed, 37 insertions(+), 33 deletions(-) diff --git a/src/dmt/gui/widget/Oscilloscope.h b/src/dmt/gui/widget/Oscilloscope.h index 2c6b8c6f..bb7908a9 100644 --- a/src/dmt/gui/widget/Oscilloscope.h +++ b/src/dmt/gui/widget/Oscilloscope.h @@ -287,78 +287,82 @@ class alignas(64) Oscilloscope : public juce::Thread inline void render() { TRACER("Oscilloscope::render"); + const int width = renderWidth.load(std::memory_order_relaxed); const int height = renderHeight.load(std::memory_order_relaxed); - if (width <= 0 || height <= 0) { + if (width <= 0 || height <= 0) return; - } const int halfHeight = height / 2; + const float samplesPerPixel = rawSamplesPerPixel.load(std::memory_order_relaxed) * size; - if (samplesPerPixel <= 0.0f) { + if (samplesPerPixel <= 0.0f) return; - } const int bufferSize = ringBuffer.getNumSamples(); const int readPosition = ringBuffer.getReadPosition(channel); const int samplesToRead = bufferSize - readPosition; const int maxSamplesToDraw = - static_cast(std::floor(samplesPerPixel * static_cast(width))); + (int)std::floor(samplesPerPixel * (float)width); + const int samplesToDraw = jmin(samplesToRead, maxSamplesToDraw); const int firstSamplesToDraw = readPosition; - const float exactPixelsToDraw = - static_cast(samplesToDraw) / samplesPerPixel; + const float exactPixelsToDraw = (float)samplesToDraw / samplesPerPixel; + const float totalShift = exactPixelsToDraw + subPixelOffset; - const int pixelToDraw = static_cast(totalShift); + const int pixelToDraw = (int)totalShift; - if (pixelToDraw <= 0) { + if (pixelToDraw <= 0) return; - } ringBuffer.incrementReadPosition(channel, samplesToDraw); const int currentFront = frontBufferIndex.load(std::memory_order_acquire); const int backIndex = currentFront == 0 ? 1 : 0; - auto& backImage = images[static_cast(backIndex)]; - - backImage = images[static_cast(currentFront)].createCopy(); - - // Image move - // const int destX = 0 - pixelToDraw; - // backImage.moveImageSection(destX, // destX - // 0, // destY - // 0, // srcX - // 0, // srcY - // width + 10, // width - // height); // height - - // Clear the new part of the image - juce::Rectangle clearRect( - width - pixelToDraw + 10, 0, pixelToDraw, height); - backImage.clear(clearRect, juce::Colours::transparentBlack); - - // Delegate drawing to the active renderer - juce::Graphics imageGraphics(backImage); + + auto& backImage = images[(size_t)backIndex]; + + backImage = images[(size_t)currentFront].createCopy(); + + // Left scrolling 2.0: Hopefully without crashing host DAWs + const int shift = jmin(pixelToDraw, width); + if (shift > 0) { + // Move content LEFT safely inside bounds + backImage.moveImageSection(0, + 0, // destX, destY + shift, + 0, // sourceX, sourceY + width - shift, + height); + + backImage.clear(juce::Rectangle(width - shift, 0, shift, height), + juce::Colours::transparentBlack); + } + + // Render new audio data + juce::Graphics g(backImage); + const typename Renderer::RenderContext context{ firstSamplesToDraw, samplesToDraw, - static_cast(width - pixelToDraw) + subPixelOffset, + (float)(width - shift) + subPixelOffset, 1.0f / samplesPerPixel, halfHeight, amplitude.load(std::memory_order_relaxed), thickness.load(std::memory_order_relaxed), size }; - subPixelOffset = totalShift - static_cast(pixelToDraw); + + subPixelOffset = totalShift - (float)pixelToDraw; if (auto currentRenderer = std::atomic_load_explicit(&renderer, std::memory_order_acquire)) { - currentRenderer->draw(imageGraphics, ringBuffer, channel, context); + currentRenderer->draw(g, ringBuffer, channel, context); } frontBufferIndex.store(backIndex, std::memory_order_release); From 16cc9dfa9f84994236af516051024bfcdf01886a Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Sat, 9 May 2026 03:37:56 +0200 Subject: [PATCH 72/74] fix: comment out backImage.clear to prevent unwanted clearing during rendering --- src/dmt/gui/widget/Oscilloscope.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dmt/gui/widget/Oscilloscope.h b/src/dmt/gui/widget/Oscilloscope.h index bb7908a9..61456303 100644 --- a/src/dmt/gui/widget/Oscilloscope.h +++ b/src/dmt/gui/widget/Oscilloscope.h @@ -340,8 +340,8 @@ class alignas(64) Oscilloscope : public juce::Thread width - shift, height); - backImage.clear(juce::Rectangle(width - shift, 0, shift, height), - juce::Colours::transparentBlack); + // backImage.clear(juce::Rectangle(width - shift, 0, shift, height), + // juce::Colours::transparentBlack); } // Render new audio data From bbef42cd67e01e1ad12f156438daf35a6bd1d873 Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Sat, 9 May 2026 03:53:52 +0200 Subject: [PATCH 73/74] fix: adjust oscilloscope image section movement and enable clearing with transparency --- src/dmt/gui/widget/Oscilloscope.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/dmt/gui/widget/Oscilloscope.h b/src/dmt/gui/widget/Oscilloscope.h index 61456303..5469b2ca 100644 --- a/src/dmt/gui/widget/Oscilloscope.h +++ b/src/dmt/gui/widget/Oscilloscope.h @@ -333,15 +333,15 @@ class alignas(64) Oscilloscope : public juce::Thread const int shift = jmin(pixelToDraw, width); if (shift > 0) { // Move content LEFT safely inside bounds - backImage.moveImageSection(0, - 0, // destX, destY - shift, - 0, // sourceX, sourceY - width - shift, - height); - - // backImage.clear(juce::Rectangle(width - shift, 0, shift, height), - // juce::Colours::transparentBlack); + // backImage.moveImageSection(0, + // 0, // destX, destY + // shift, + // 0, // sourceX, sourceY + // width - shift, + // height); + + backImage.clear(juce::Rectangle(width - shift, 0, shift, height), + juce::Colours::transparentBlack); } // Render new audio data From ae84a261461177f33c0a13cac83ee2224bc0f764 Mon Sep 17 00:00:00 2001 From: Lunix-420 Date: Sat, 9 May 2026 13:41:02 +0200 Subject: [PATCH 74/74] fix: adjust image initialization for Windows and non-Windows platforms --- src/dmt/gui/widget/Oscilloscope.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/dmt/gui/widget/Oscilloscope.h b/src/dmt/gui/widget/Oscilloscope.h index 5469b2ca..eb50d02e 100644 --- a/src/dmt/gui/widget/Oscilloscope.h +++ b/src/dmt/gui/widget/Oscilloscope.h @@ -257,9 +257,16 @@ class alignas(64) Oscilloscope : public juce::Thread return; } +#if OS_IS_WINDOWS for (auto& image : images) { - image = Image(PixelFormat::ARGB, _width + 10, _height, true); + image = Image( + PixelFormat::ARGB, _width + 10, _height, true, juce::OpenGLImageType()); } +#else + for (auto& image : images) { + image = Image(PixelFormat::ARGB, _width, _height, true); + } +#endif frontBufferIndex.store(0, std::memory_order_release); subPixelOffset = 0.0f;