From 2b7e51f1df82a9647daf66d5b4ab71a586b60e06 Mon Sep 17 00:00:00 2001 From: James H Ball Date: Wed, 21 Aug 2024 13:35:26 +0100 Subject: [PATCH 1/7] Only have a single instance of visualiser settings per app --- Source/PluginEditor.cpp | 12 ++++++++++++ Source/PluginEditor.h | 6 +++++- Source/components/VisualiserComponent.cpp | 17 +++-------------- Source/components/VisualiserComponent.h | 9 +++++---- Source/components/VisualiserSettings.cpp | 2 +- Source/components/VisualiserSettings.h | 4 +--- 6 files changed, 27 insertions(+), 23 deletions(-) diff --git a/Source/PluginEditor.cpp b/Source/PluginEditor.cpp index 9661f4d..19b50aa 100644 --- a/Source/PluginEditor.cpp +++ b/Source/PluginEditor.cpp @@ -102,6 +102,18 @@ OscirenderAudioProcessorEditor::OscirenderAudioProcessorEditor(OscirenderAudioPr addAndMakeVisible(lua); addAndMakeVisible(luaResizerBar); addAndMakeVisible(visualiser); + + visualiser.openSettings = [this] { + visualiserSettingsWindow.setVisible(true); + visualiserSettingsWindow.toFront(true); + }; + + visualiserSettingsWindow.setResizable(false, false); + visualiserSettingsWindow.setUsingNativeTitleBar(true); + visualiserSettings.setLookAndFeel(&getLookAndFeel()); + visualiserSettings.setSize(550, 230); + visualiserSettingsWindow.setContentNonOwned(&visualiserSettings, true); + visualiserSettingsWindow.centreWithSize(550, 230); tooltipDropShadow.setOwner(&tooltipWindow); } diff --git a/Source/PluginEditor.h b/Source/PluginEditor.h index 2d43787..c5c98a4 100644 --- a/Source/PluginEditor.h +++ b/Source/PluginEditor.h @@ -9,6 +9,7 @@ #include "LookAndFeel.h" #include "components/ErrorCodeEditorComponent.h" #include "components/LuaConsole.h" +#include "components/VisualiserSettings.h" class OscirenderAudioProcessorEditor : public juce::AudioProcessorEditor, private juce::CodeDocument::Listener, public juce::AsyncUpdater, public juce::ChangeListener { public: @@ -48,7 +49,10 @@ public: std::atomic editingCustomFunction = false; - VisualiserComponent visualiser{audioProcessor, nullptr, audioProcessor.legacyVisualiserEnabled->getBoolValue()}; + VisualiserSettings visualiserSettings = VisualiserSettings(audioProcessor); + SettingsWindow visualiserSettingsWindow = SettingsWindow("Visualiser Settings"); + VisualiserComponent visualiser{audioProcessor, visualiserSettings, nullptr, audioProcessor.legacyVisualiserEnabled->getBoolValue()}; + std::atomic visualiserFullScreen = false; SettingsComponent settings{audioProcessor, *this}; diff --git a/Source/components/VisualiserComponent.cpp b/Source/components/VisualiserComponent.cpp index ee49ff1..2c5ff66 100644 --- a/Source/components/VisualiserComponent.cpp +++ b/Source/components/VisualiserComponent.cpp @@ -1,20 +1,13 @@ #include "../LookAndFeel.h" #include "VisualiserComponent.h" -VisualiserComponent::VisualiserComponent(OscirenderAudioProcessor& p, VisualiserComponent* parent, bool useOldVisualiser) : backgroundColour(juce::Colours::black), waveformColour(juce::Colour(0xff00ff00)), audioProcessor(p), oldVisualiser(useOldVisualiser), juce::Thread("VisualiserComponent"), parent(parent) { +VisualiserComponent::VisualiserComponent(OscirenderAudioProcessor& p, VisualiserSettings& settings, VisualiserComponent* parent, bool useOldVisualiser) : settings(settings), backgroundColour(juce::Colours::black), waveformColour(juce::Colour(0xff00ff00)), audioProcessor(p), oldVisualiser(useOldVisualiser), juce::Thread("VisualiserComponent"), parent(parent) { setVisualiserType(oldVisualiser); resetBuffer(); startTimerHz(60); startThread(); - settingsWindow.setResizable(false, false); - settingsWindow.setUsingNativeTitleBar(true); - settings.setLookAndFeel(&getLookAndFeel()); - settings.setSize(550, 230); - settingsWindow.setContentNonOwned(&settings, true); - settingsWindow.centreWithSize(550, 230); - setMouseCursor(juce::MouseCursor::PointingHandCursor); setWantsKeyboardFocus(true); @@ -349,8 +342,9 @@ void VisualiserComponent::childChanged() { } void VisualiserComponent::popoutWindow() { - auto visualiser = new VisualiserComponent(audioProcessor, this, oldVisualiser); + auto visualiser = new VisualiserComponent(audioProcessor, settings, this, oldVisualiser); visualiser->settings.setLookAndFeel(&getLookAndFeel()); + visualiser->openSettings = openSettings; child = visualiser; childChanged(); popOutButton.setVisible(false); @@ -365,8 +359,3 @@ void VisualiserComponent::popoutWindow() { resized(); popOutButton.setVisible(false); } - -void VisualiserComponent::openSettings() { - settingsWindow.setVisible(true); - settingsWindow.toFront(true); -} diff --git a/Source/components/VisualiserComponent.h b/Source/components/VisualiserComponent.h index 85e9b7c..cab52ad 100644 --- a/Source/components/VisualiserComponent.h +++ b/Source/components/VisualiserComponent.h @@ -18,10 +18,11 @@ enum class FullScreenMode { class VisualiserWindow; class VisualiserComponent : public juce::Component, public juce::Timer, public juce::Thread, public juce::MouseListener, public juce::SettableTooltipClient { public: - VisualiserComponent(OscirenderAudioProcessor& p, VisualiserComponent* parent = nullptr, bool useOldVisualiser = false); + VisualiserComponent(OscirenderAudioProcessor& p, VisualiserSettings& settings, VisualiserComponent* parent = nullptr, bool useOldVisualiser = false); ~VisualiserComponent() override; - void openSettings(); + std::function openSettings; + void childChanged(); void enableFullScreen(); void setFullScreenCallback(std::function callback); @@ -76,8 +77,8 @@ private: std::shared_ptr consumer; std::function fullScreenCallback; - VisualiserSettings settings = VisualiserSettings(audioProcessor, *this); - SettingsWindow settingsWindow = SettingsWindow("Visualiser Settings"); + + VisualiserSettings& settings; juce::WebBrowserComponent::ResourceProvider provider = [this](const juce::String& path) { juce::String mimeType; diff --git a/Source/components/VisualiserSettings.cpp b/Source/components/VisualiserSettings.cpp index af78ce7..025525c 100644 --- a/Source/components/VisualiserSettings.cpp +++ b/Source/components/VisualiserSettings.cpp @@ -2,7 +2,7 @@ #include "VisualiserComponent.h" #include "../PluginEditor.h" -VisualiserSettings::VisualiserSettings(OscirenderAudioProcessor& p, VisualiserComponent& visualiser) : audioProcessor(p), visualiser(visualiser) { +VisualiserSettings::VisualiserSettings(OscirenderAudioProcessor& p) : audioProcessor(p) { addAndMakeVisible(intensity); addAndMakeVisible(persistence); addAndMakeVisible(hue); diff --git a/Source/components/VisualiserSettings.h b/Source/components/VisualiserSettings.h index 5ea48f6..4a44a65 100644 --- a/Source/components/VisualiserSettings.h +++ b/Source/components/VisualiserSettings.h @@ -6,17 +6,15 @@ #include "../LookAndFeel.h" #include "SwitchButton.h" -class VisualiserComponent; class VisualiserSettings : public juce::Component { public: - VisualiserSettings(OscirenderAudioProcessor&, VisualiserComponent&); + VisualiserSettings(OscirenderAudioProcessor&); ~VisualiserSettings(); void resized() override; juce::var getSettings(); private: OscirenderAudioProcessor& audioProcessor; - VisualiserComponent& visualiser; EffectComponent intensity{audioProcessor, *audioProcessor.intensityEffect}; EffectComponent persistence{audioProcessor, *audioProcessor.persistenceEffect}; From ddba403e149d6fbd202caff3fd4f9ac76eda19c9 Mon Sep 17 00:00:00 2001 From: James H Ball Date: Wed, 21 Aug 2024 13:43:30 +0100 Subject: [PATCH 2/7] Close visualiser settings when going from new to legacy visualiser --- Source/PluginEditor.cpp | 4 ++++ Source/components/VisualiserComponent.cpp | 4 ++++ Source/components/VisualiserComponent.h | 1 + 3 files changed, 9 insertions(+) diff --git a/Source/PluginEditor.cpp b/Source/PluginEditor.cpp index 19b50aa..4eb3581 100644 --- a/Source/PluginEditor.cpp +++ b/Source/PluginEditor.cpp @@ -108,6 +108,10 @@ OscirenderAudioProcessorEditor::OscirenderAudioProcessorEditor(OscirenderAudioPr visualiserSettingsWindow.toFront(true); }; + visualiser.closeSettings = [this] { + visualiserSettingsWindow.setVisible(false); + }; + visualiserSettingsWindow.setResizable(false, false); visualiserSettingsWindow.setUsingNativeTitleBar(true); visualiserSettings.setLookAndFeel(&getLookAndFeel()); diff --git a/Source/components/VisualiserComponent.cpp b/Source/components/VisualiserComponent.cpp index 2c5ff66..fb107f2 100644 --- a/Source/components/VisualiserComponent.cpp +++ b/Source/components/VisualiserComponent.cpp @@ -221,6 +221,9 @@ void VisualiserComponent::setVisualiserType(bool oldVisualiser) { } if (oldVisualiser) { browser.reset(); + if (closeSettings != nullptr) { + closeSettings(); + } } else { initialiseBrowser(); } @@ -345,6 +348,7 @@ void VisualiserComponent::popoutWindow() { auto visualiser = new VisualiserComponent(audioProcessor, settings, this, oldVisualiser); visualiser->settings.setLookAndFeel(&getLookAndFeel()); visualiser->openSettings = openSettings; + visualiser->closeSettings = closeSettings; child = visualiser; childChanged(); popOutButton.setVisible(false); diff --git a/Source/components/VisualiserComponent.h b/Source/components/VisualiserComponent.h index cab52ad..547d90a 100644 --- a/Source/components/VisualiserComponent.h +++ b/Source/components/VisualiserComponent.h @@ -22,6 +22,7 @@ public: ~VisualiserComponent() override; std::function openSettings; + std::function closeSettings; void childChanged(); void enableFullScreen(); From 2071cc9a1827c04378f5cf64aba466502d036011 Mon Sep 17 00:00:00 2001 From: James H Ball Date: Thu, 22 Aug 2024 13:12:46 +0100 Subject: [PATCH 3/7] Add several Lua functions --- Source/lua/LuaParser.cpp | 312 ++++++++++++++++++++++++++++++++++++++- Source/shape/Line.cpp | 15 ++ Source/shape/Line.h | 1 + osci-render.jucer | 4 +- 4 files changed, 327 insertions(+), 5 deletions(-) diff --git a/Source/lua/LuaParser.cpp b/Source/lua/LuaParser.cpp index aa64cc8..091cb61 100644 --- a/Source/lua/LuaParser.cpp +++ b/Source/lua/LuaParser.cpp @@ -1,5 +1,8 @@ #include "LuaParser.h" #include "luaimport.h" +#include "../shape/Line.h" +#include "../shape/CircleArc.h" +#include "../shape/QuadraticBezierCurve.h" std::function LuaParser::onPrint; std::function LuaParser::onClear; @@ -21,6 +24,293 @@ void LuaParser::resetMaximumInstructions(lua_State*& L) { lua_sethook(L, LuaParser::maximumInstructionsReached, 0, 0); } +static int pointToTable(lua_State* L, Point point, int numDims) { + lua_newtable(L); + if (numDims == 1) { + lua_pushnumber(L, point.x); + lua_rawseti(L, -2, 1); + } else if (numDims == 2) { + lua_pushnumber(L, point.x); + lua_rawseti(L, -2, 1); + lua_pushnumber(L, point.y); + lua_rawseti(L, -2, 2); + } else { + lua_pushnumber(L, point.x); + lua_rawseti(L, -2, 1); + lua_pushnumber(L, point.y); + lua_rawseti(L, -2, 2); + lua_pushnumber(L, point.z); + lua_rawseti(L, -2, 3); + } + + return 1; +} + +static Point tableToPoint(lua_State* L, int index) { + Point point; + lua_pushinteger(L, 1); + lua_gettable(L, index); + point.x = lua_tonumber(L, -1); + lua_pop(L, 1); + + lua_pushinteger(L, 2); + lua_gettable(L, index); + point.y = lua_tonumber(L, -1); + lua_pop(L, 1); + + lua_pushinteger(L, 3); + lua_gettable(L, index); + point.z = lua_tonumber(L, -1); + lua_pop(L, 1); + + return point; +} + +static int luaLine(lua_State* L) { + double t = lua_tonumber(L, 1) / juce::MathConstants::twoPi; + Point point1 = tableToPoint(L, 2); + Point point2 = tableToPoint(L, 3); + + Line line = Line(point1, point2); + Point point = line.nextVector(t); + + return pointToTable(L, point, 3); +} + +static Point genericRect(double phase, Point topLeft, double width, double height) { + double t = phase / juce::MathConstants::twoPi; + double totalLength = 2 * (width + height); + double progress = t * totalLength; + + Line line = Line(0, 0); + double adjustedProgress; + double x = topLeft.x; + double y = topLeft.y; + + if (progress < width) { + line = Line(x, y, x + width, y); + adjustedProgress = progress / width; + } else if (progress < width + height) { + line = Line(x + width, y, x + width, y + height); + adjustedProgress = (progress - width) / height; + } else if (progress < 2 * width + height) { + line = Line(x + width, y + height, x, y + height); + adjustedProgress = (progress - width - height) / width; + } else { + line = Line(x, y + height, x, y); + adjustedProgress = (progress - 2 * width - height) / height; + } + + return line.nextVector(adjustedProgress); +} + +static int luaRect(lua_State* L) { + int nargs = lua_gettop(L); + + double phase = lua_tonumber(L, 1); + double width = lua_tonumber(L, 2); + double height = lua_tonumber(L, 3); + + Point topLeft = nargs == 4 ? tableToPoint(L, 4) : Point(-width / 2, -height / 2); + Point point = genericRect(phase, topLeft, width, height); + + return pointToTable(L, point, 2); +} + +static int luaSquare(lua_State* L) { + int nargs = lua_gettop(L); + + double phase = lua_tonumber(L, 1); + double width = lua_tonumber(L,2); + + Point topLeft = nargs == 3 ? tableToPoint(L, 3) : Point(-width / 2, -width / 2); + Point point = genericRect(phase, topLeft, width, width); + + return pointToTable(L, point, 2); +} + +static int luaEllipse(lua_State* L) { + double t = lua_tonumber(L, 1) / juce::MathConstants::twoPi; + double radiusX = lua_tonumber(L, 2); + double radiuxY = lua_tonumber(L, 3); + + CircleArc ellipse = CircleArc(0, 0, radiusX, radiuxY, 0, juce::MathConstants::twoPi); + Point point = ellipse.nextVector(t); + + return pointToTable(L, point, 2); +} + +static int luaCircle(lua_State* L) { + double t = lua_tonumber(L, 1) / juce::MathConstants::twoPi; + double radius = lua_tonumber(L, 2); + + CircleArc ellipse = CircleArc(0, 0, radius, radius, 0, juce::MathConstants::twoPi); + Point point = ellipse.nextVector(t); + + return pointToTable(L, point, 2); +} + +static int luaArc(lua_State* L) { + double t = lua_tonumber(L, 1) / juce::MathConstants::twoPi; + double radiusX = lua_tonumber(L, 2); + double radiusY = lua_tonumber(L, 3); + double startAngle = lua_tonumber(L, 4); + double endAngle = lua_tonumber(L, 5); + + CircleArc arc = CircleArc(0, 0, radiusX, radiusY, startAngle, endAngle); + Point point = arc.nextVector(t); + + return pointToTable(L, point, 2); +} + +static int luaPolygon(lua_State* L) { + double n = lua_tonumber(L, 2); + double t = n * lua_tonumber(L, 1) / juce::MathConstants::twoPi; + + int floor_t = (int) t; + + double pi_n = juce::MathConstants::pi / n; + double two_floor_t_plus_one = 2 * floor_t + 1; + double inner_cos = cos(pi_n * two_floor_t_plus_one); + double inner_sin = sin(pi_n * two_floor_t_plus_one); + double multiplier = 2 * t - 2 * floor_t - 1; + + double x = cos(pi_n) * inner_cos - multiplier * sin(pi_n) * inner_sin; + double y = cos(pi_n) * inner_sin + multiplier * sin(pi_n) * inner_cos; + + return pointToTable(L, Point(x, y), 2); +} + +static int luaBezier(lua_State* L) { + int nargs = lua_gettop(L); + + double t = lua_tonumber(L, 1) / juce::MathConstants::twoPi; + Point point1 = tableToPoint(L, 2); + Point point2 = tableToPoint(L, 3); + Point point3 = tableToPoint(L, 4); + + Point point; + + if (nargs == 4) { + QuadraticBezierCurve curve = QuadraticBezierCurve(point1.x, point1.y, point2.x, point2.y, point3.x, point3.y); + point = curve.nextVector(t); + } else { + Point point4 = tableToPoint(L, 5); + + CubicBezierCurve curve = CubicBezierCurve(point1.x, point1.y, point2.x, point2.y, point3.x, point3.y, point4.x, point4.y); + point = curve.nextVector(t); + } + + return pointToTable(L, point, 2); +} + +static int luaLissajous(lua_State* L) { + int nargs = lua_gettop(L); + + double theta = lua_tonumber(L, 1); + double radius = lua_tonumber(L, 2); + double ratioA = lua_tonumber(L, 3); + double ratioB = lua_tonumber(L, 4); + double phase = lua_tonumber(L, 5); + + double x = radius * sin(ratioA * theta); + double y = radius * cos(ratioB * theta + phase); + + return pointToTable(L, Point(x, y), 2); +} + +static double squareWave(double phase) { + double t = phase / juce::MathConstants::twoPi; + return (t - (int) t < 0.5) ? 1 : 0; +} + +static double sawWave(double phase) { + double t = phase / juce::MathConstants::twoPi; + return t - std::floor(t); +} + +static double triangleWave(double phase) { + double t = phase / juce::MathConstants::twoPi; + return abs(2 * (t - std::floor(t)) - 1); +} + +static int luaSquareWave(lua_State* L) { + double phase = lua_tonumber(L, 1); + lua_pushnumber(L, squareWave(phase)); + return 1; +} + +static int luaSawWave(lua_State* L) { + double phase = lua_tonumber(L, 1); + lua_pushnumber(L, sawWave(phase)); + return 1; +} + +static int luaTriangleWave(lua_State* L) { + double phase = lua_tonumber(L, 1); + lua_pushnumber(L, triangleWave(phase)); + return 1; +} + +static int luaMix(lua_State* L) { + int nargs = lua_gettop(L); + + Point point1 = tableToPoint(L, 1); + Point point2 = tableToPoint(L, 2); + double weight = lua_tonumber(L, 3); + + Point point = Point( + point1.x * (1 - weight) + point2.x * weight, + point1.y * (1 - weight) + point2.y * weight, + point1.z * (1 - weight) + point2.z * weight + ); + + return pointToTable(L, point, 3); +} + +static int luaTranslate(lua_State* L) { + Point point = tableToPoint(L, 1); + Point translation = tableToPoint(L, 2); + + point.translate(translation.x, translation.y, translation.z); + + return pointToTable(L, point, 3); +} + +static int luaScale(lua_State* L) { + Point point = tableToPoint(L, 1); + Point scale = tableToPoint(L, 2); + + point.scale(scale.x, scale.y, scale.z); + + return pointToTable(L, point, 3); +} + +static int luaRotate(lua_State* L) { + double nargs = lua_gettop(L); + bool twoDimRotate = nargs == 2; + + Point point; + + if (twoDimRotate) { + Point point = tableToPoint(L, 1); + double angle = lua_tonumber(L, 2); + + point.rotate(0, 0, angle); + + return pointToTable(L, point, 2); + } else { + Point point = tableToPoint(L, 1); + double xRotate = lua_tonumber(L, 2); + double yRotate = lua_tonumber(L, 3); + double zRotate = lua_tonumber(L, 4); + + point.rotate(xRotate, yRotate, zRotate); + + return pointToTable(L, point, 3); + } +} + static int luaPrint(lua_State* L) { int nargs = lua_gettop(L); @@ -38,9 +328,25 @@ static int luaClear(lua_State* L) { } static const struct luaL_Reg luaLib[] = { - {"print", luaPrint}, - {"clear", luaClear}, - {NULL, NULL} /* end of array */ + {"osci_line", luaLine}, + {"osci_rect", luaRect}, + {"osci_ellipse", luaEllipse}, + {"osci_circle", luaCircle}, + {"osci_arc", luaArc}, + {"osci_polygon", luaPolygon}, + {"osci_bezier", luaBezier}, + {"osci_square", luaSquare}, + {"osci_lissajous", luaLissajous}, + {"osci_square_wave", luaSquareWave}, + {"osci_saw_wave", luaSawWave}, + {"osci_triangle_wave", luaTriangleWave}, + {"osci_mix", luaMix}, + {"osci_translate", luaTranslate}, + {"osci_scale", luaScale}, + {"osci_rotate", luaRotate}, + {"print", luaPrint}, + {"clear", luaClear}, + {NULL, NULL} /* end of array */ }; extern int luaopen_customprintlib(lua_State* L) { diff --git a/Source/shape/Line.cpp b/Source/shape/Line.cpp index e25dd94..dc812db 100644 --- a/Source/shape/Line.cpp +++ b/Source/shape/Line.cpp @@ -50,3 +50,18 @@ std::unique_ptr Line::clone() { std::string Line::type() { return std::string("Line"); } + +Line& Line::operator=(const Line& other) { + if (this == &other) { + return *this; + } + + this->x1 = other.x1; + this->y1 = other.y1; + this->z1 = other.z1; + this->x2 = other.x2; + this->y2 = other.y2; + this->z2 = other.z2; + + return *this; +} diff --git a/Source/shape/Line.h b/Source/shape/Line.h index 7f8a744..e55286a 100644 --- a/Source/shape/Line.h +++ b/Source/shape/Line.h @@ -16,6 +16,7 @@ public: double length() override; std::unique_ptr clone() override; std::string type() override; + Line& operator=(const Line& other); double x1, y1, z1, x2, y2, z2; diff --git a/osci-render.jucer b/osci-render.jucer index b3c18e0..48c3f14 100644 --- a/osci-render.jucer +++ b/osci-render.jucer @@ -654,9 +654,9 @@ - + + debugInformationFormat="ProgramDatabase" enablePluginBinaryCopyStep="1"/> From 9672e826ace7865285bcc5bb9df94c24696c5869 Mon Sep 17 00:00:00 2001 From: James H Ball Date: Thu, 22 Aug 2024 14:18:04 +0100 Subject: [PATCH 4/7] Add default implementations for all Lua functions if no additional parameters are provided --- Source/lua/LuaParser.cpp | 64 +++++++++++++++++++++++----------------- 1 file changed, 37 insertions(+), 27 deletions(-) diff --git a/Source/lua/LuaParser.cpp b/Source/lua/LuaParser.cpp index 091cb61..a996d5a 100644 --- a/Source/lua/LuaParser.cpp +++ b/Source/lua/LuaParser.cpp @@ -67,9 +67,11 @@ static Point tableToPoint(lua_State* L, int index) { } static int luaLine(lua_State* L) { + int nargs = lua_gettop(L); + double t = lua_tonumber(L, 1) / juce::MathConstants::twoPi; - Point point1 = tableToPoint(L, 2); - Point point2 = tableToPoint(L, 3); + Point point1 = nargs == 3 ? tableToPoint(L, 2) : Point(-1, -1); + Point point2 = nargs == 3 ? tableToPoint(L, 3) : Point(1, 1); Line line = Line(point1, point2); Point point = line.nextVector(t); @@ -108,8 +110,8 @@ static int luaRect(lua_State* L) { int nargs = lua_gettop(L); double phase = lua_tonumber(L, 1); - double width = lua_tonumber(L, 2); - double height = lua_tonumber(L, 3); + double width = nargs == 1 ? 1 : lua_tonumber(L, 2); + double height = nargs == 1 ? 1.5 : lua_tonumber(L, 3); Point topLeft = nargs == 4 ? tableToPoint(L, 4) : Point(-width / 2, -height / 2); Point point = genericRect(phase, topLeft, width, height); @@ -121,7 +123,7 @@ static int luaSquare(lua_State* L) { int nargs = lua_gettop(L); double phase = lua_tonumber(L, 1); - double width = lua_tonumber(L,2); + double width = nargs == 1 ? 1 : lua_tonumber(L,2); Point topLeft = nargs == 3 ? tableToPoint(L, 3) : Point(-width / 2, -width / 2); Point point = genericRect(phase, topLeft, width, width); @@ -130,9 +132,11 @@ static int luaSquare(lua_State* L) { } static int luaEllipse(lua_State* L) { + int nargs = lua_gettop(L); + double t = lua_tonumber(L, 1) / juce::MathConstants::twoPi; - double radiusX = lua_tonumber(L, 2); - double radiuxY = lua_tonumber(L, 3); + double radiusX = nargs == 1 ? 0.6 : lua_tonumber(L, 2); + double radiuxY = nargs == 1 ? 0.8 : lua_tonumber(L, 3); CircleArc ellipse = CircleArc(0, 0, radiusX, radiuxY, 0, juce::MathConstants::twoPi); Point point = ellipse.nextVector(t); @@ -141,8 +145,10 @@ static int luaEllipse(lua_State* L) { } static int luaCircle(lua_State* L) { + int nargs = lua_gettop(L); + double t = lua_tonumber(L, 1) / juce::MathConstants::twoPi; - double radius = lua_tonumber(L, 2); + double radius = nargs == 1 ? 0.8 : lua_tonumber(L, 2); CircleArc ellipse = CircleArc(0, 0, radius, radius, 0, juce::MathConstants::twoPi); Point point = ellipse.nextVector(t); @@ -151,11 +157,13 @@ static int luaCircle(lua_State* L) { } static int luaArc(lua_State* L) { + int nargs = lua_gettop(L); + double t = lua_tonumber(L, 1) / juce::MathConstants::twoPi; - double radiusX = lua_tonumber(L, 2); - double radiusY = lua_tonumber(L, 3); - double startAngle = lua_tonumber(L, 4); - double endAngle = lua_tonumber(L, 5); + double radiusX = nargs == 1 ? 1 : lua_tonumber(L, 2); + double radiusY = nargs == 1 ? 1 : lua_tonumber(L, 3); + double startAngle = nargs == 1 ? 0 : lua_tonumber(L, 4); + double endAngle = nargs == 1 ? juce::MathConstants::halfPi : lua_tonumber(L, 5); CircleArc arc = CircleArc(0, 0, radiusX, radiusY, startAngle, endAngle); Point point = arc.nextVector(t); @@ -164,7 +172,9 @@ static int luaArc(lua_State* L) { } static int luaPolygon(lua_State* L) { - double n = lua_tonumber(L, 2); + int nargs = lua_gettop(L); + + double n = nargs == 1 ? 5 : lua_tonumber(L, 2); double t = n * lua_tonumber(L, 1) / juce::MathConstants::twoPi; int floor_t = (int) t; @@ -185,20 +195,20 @@ static int luaBezier(lua_State* L) { int nargs = lua_gettop(L); double t = lua_tonumber(L, 1) / juce::MathConstants::twoPi; - Point point1 = tableToPoint(L, 2); - Point point2 = tableToPoint(L, 3); - Point point3 = tableToPoint(L, 4); + Point point1 = nargs == 1 ? Point(-1, -1) : tableToPoint(L, 2); + Point point2 = nargs == 1 ? Point(-1, 1) : tableToPoint(L, 3); + Point point3 = nargs == 1 ? Point(1, 1) : tableToPoint(L, 4); Point point; - if (nargs == 4) { - QuadraticBezierCurve curve = QuadraticBezierCurve(point1.x, point1.y, point2.x, point2.y, point3.x, point3.y); - point = curve.nextVector(t); - } else { + if (nargs == 5) { Point point4 = tableToPoint(L, 5); CubicBezierCurve curve = CubicBezierCurve(point1.x, point1.y, point2.x, point2.y, point3.x, point3.y, point4.x, point4.y); point = curve.nextVector(t); + } else { + QuadraticBezierCurve curve = QuadraticBezierCurve(point1.x, point1.y, point2.x, point2.y, point3.x, point3.y); + point = curve.nextVector(t); } return pointToTable(L, point, 2); @@ -207,14 +217,14 @@ static int luaBezier(lua_State* L) { static int luaLissajous(lua_State* L) { int nargs = lua_gettop(L); - double theta = lua_tonumber(L, 1); - double radius = lua_tonumber(L, 2); - double ratioA = lua_tonumber(L, 3); - double ratioB = lua_tonumber(L, 4); - double phase = lua_tonumber(L, 5); + double phase = lua_tonumber(L, 1); + double radius = nargs == 1 ? 1 : lua_tonumber(L, 2); + double ratioA = nargs == 1 ? 1 : lua_tonumber(L, 3); + double ratioB = nargs == 1 ? 5 : lua_tonumber(L, 4); + double theta = nargs == 1 ? 0 : lua_tonumber(L, 5); - double x = radius * sin(ratioA * theta); - double y = radius * cos(ratioB * theta + phase); + double x = radius * sin(ratioA * phase); + double y = radius * cos(ratioB * phase + theta); return pointToTable(L, Point(x, y), 2); } From 997de907bcd740652eb867e778d1933a8a09e30c Mon Sep 17 00:00:00 2001 From: James H Ball Date: Thu, 22 Aug 2024 14:42:54 +0100 Subject: [PATCH 5/7] Save visualiser fullscreen state to project --- Source/MainComponent.cpp | 12 ++++++------ Source/PluginEditor.cpp | 2 +- Source/PluginEditor.h | 1 - Source/PluginProcessor.cpp | 1 + Source/PluginProcessor.h | 2 ++ osci-render.jucer | 4 ++-- 6 files changed, 12 insertions(+), 10 deletions(-) diff --git a/Source/MainComponent.cpp b/Source/MainComponent.cpp index b1af041..3f6cad4 100644 --- a/Source/MainComponent.cpp +++ b/Source/MainComponent.cpp @@ -124,19 +124,19 @@ MainComponent::MainComponent(OscirenderAudioProcessor& p, OscirenderAudioProcess createFile.triggerClick(); }; - if (!pluginEditor.visualiserFullScreen) { + if (!audioProcessor.visualiserFullScreen->getBoolValue()) { addAndMakeVisible(pluginEditor.visualiser); } pluginEditor.visualiser.setFullScreenCallback([this](FullScreenMode mode) { if (mode == FullScreenMode::TOGGLE) { - pluginEditor.visualiserFullScreen = !pluginEditor.visualiserFullScreen; + audioProcessor.visualiserFullScreen->setBoolValueNotifyingHost(!audioProcessor.visualiserFullScreen->getBoolValue()); } else if (mode == FullScreenMode::FULL_SCREEN) { - pluginEditor.visualiserFullScreen = true; + audioProcessor.visualiserFullScreen->setBoolValueNotifyingHost(true); } else if (mode == FullScreenMode::MAIN_COMPONENT) { - pluginEditor.visualiserFullScreen = false; + audioProcessor.visualiserFullScreen->setBoolValueNotifyingHost(false); } - pluginEditor.visualiser.setFullScreen(pluginEditor.visualiserFullScreen); + pluginEditor.visualiser.setFullScreen(audioProcessor.visualiserFullScreen->getBoolValue()); pluginEditor.resized(); pluginEditor.repaint(); @@ -234,7 +234,7 @@ void MainComponent::resized() { frequencyLabel.setBounds(bounds.removeFromTop(20)); bounds.removeFromTop(padding); - if (!pluginEditor.visualiserFullScreen) { + if (!audioProcessor.visualiserFullScreen->getBoolValue()) { auto minDim = juce::jmin(bounds.getWidth(), bounds.getHeight()); juce::Point localTopLeft = {bounds.getX(), bounds.getY()}; juce::Point topLeft = pluginEditor.getLocalPoint(this, localTopLeft); diff --git a/Source/PluginEditor.cpp b/Source/PluginEditor.cpp index 9661f4d..7f1769b 100644 --- a/Source/PluginEditor.cpp +++ b/Source/PluginEditor.cpp @@ -143,7 +143,7 @@ void OscirenderAudioProcessorEditor::paint(juce::Graphics& g) { void OscirenderAudioProcessorEditor::resized() { auto area = getLocalBounds(); - if (visualiserFullScreen) { + if (audioProcessor.visualiserFullScreen->getBoolValue()) { visualiser.setBounds(area); return; } diff --git a/Source/PluginEditor.h b/Source/PluginEditor.h index 2d43787..8f367e6 100644 --- a/Source/PluginEditor.h +++ b/Source/PluginEditor.h @@ -49,7 +49,6 @@ public: std::atomic editingCustomFunction = false; VisualiserComponent visualiser{audioProcessor, nullptr, audioProcessor.legacyVisualiserEnabled->getBoolValue()}; - std::atomic visualiserFullScreen = false; SettingsComponent settings{audioProcessor, *this}; juce::ComponentAnimator codeEditorAnimator; diff --git a/Source/PluginProcessor.cpp b/Source/PluginProcessor.cpp index ce9baaf..6e44d0a 100644 --- a/Source/PluginProcessor.cpp +++ b/Source/PluginProcessor.cpp @@ -179,6 +179,7 @@ OscirenderAudioProcessor::OscirenderAudioProcessor() booleanParameters.push_back(smudgesEnabled); booleanParameters.push_back(upsamplingEnabled); booleanParameters.push_back(legacyVisualiserEnabled); + booleanParameters.push_back(visualiserFullScreen); for (auto parameter : booleanParameters) { addParameter(parameter); diff --git a/Source/PluginProcessor.h b/Source/PluginProcessor.h index 55ddf32..3cbe9ca 100644 --- a/Source/PluginProcessor.h +++ b/Source/PluginProcessor.h @@ -162,6 +162,8 @@ public: BooleanParameter* smudgesEnabled = new BooleanParameter("Show Smudges", "smudgesEnabled", VERSION_HINT, true, "Adds a subtle layer of dirt/smudges to the oscilloscope display to make it look more realistic."); BooleanParameter* upsamplingEnabled = new BooleanParameter("Upsample Audio", "upsamplingEnabled", VERSION_HINT, false, "Upsamples the audio before visualising it to make it appear more realistic, at the expense of performance."); BooleanParameter* legacyVisualiserEnabled = new BooleanParameter("Use Legacy Visualiser", "legacyVisualiserEnabled", VERSION_HINT, false, "Replaces the realistic oscilloscope visualiser with the legacy visualiser. This may improve performance."); + BooleanParameter* visualiserFullScreen = new BooleanParameter("Visualiser Fullscreen", "visualiserFullScreen", VERSION_HINT, false, "Makes the software visualiser fullscreen."); + std::shared_ptr persistenceEffect = std::make_shared( new EffectParameter( "Persistence", diff --git a/osci-render.jucer b/osci-render.jucer index 48c3f14..59e19f7 100644 --- a/osci-render.jucer +++ b/osci-render.jucer @@ -654,9 +654,9 @@ - + + debugInformationFormat="ProgramDatabase"/> From 557b9f33719dbedd34670b25bd24a9195e81474f Mon Sep 17 00:00:00 2001 From: James H Ball Date: Thu, 22 Aug 2024 16:59:21 +0100 Subject: [PATCH 6/7] Add support for .wav and .aiff files --- Source/MainComponent.cpp | 2 +- Source/PluginEditor.cpp | 2 +- Source/parser/FileParser.cpp | 13 +++++++++-- Source/parser/FileParser.h | 3 +++ Source/wav/WavParser.cpp | 43 ++++++++++++++++++++++++++++++++++++ Source/wav/WavParser.h | 22 ++++++++++++++++++ osci-render.jucer | 4 ++++ 7 files changed, 85 insertions(+), 4 deletions(-) create mode 100644 Source/wav/WavParser.cpp create mode 100644 Source/wav/WavParser.h diff --git a/Source/MainComponent.cpp b/Source/MainComponent.cpp index 3f6cad4..f87d182 100644 --- a/Source/MainComponent.cpp +++ b/Source/MainComponent.cpp @@ -10,7 +10,7 @@ MainComponent::MainComponent(OscirenderAudioProcessor& p, OscirenderAudioProcess fileButton.setButtonText("Choose File(s)"); fileButton.onClick = [this] { - chooser = std::make_unique("Open", audioProcessor.lastOpenedDirectory, "*.obj;*.svg;*.lua;*.txt;*.gpla;*.gif;*.png;*.jpg;*.jpeg"); + chooser = std::make_unique("Open", audioProcessor.lastOpenedDirectory, "*.obj;*.svg;*.lua;*.txt;*.gpla;*.gif;*.png;*.jpg;*.jpeg;*.wav;*.aiff"); auto flags = juce::FileBrowserComponent::openMode | juce::FileBrowserComponent::canSelectMultipleItems | juce::FileBrowserComponent::canSelectFiles; diff --git a/Source/PluginEditor.cpp b/Source/PluginEditor.cpp index 7f1769b..c1c2406 100644 --- a/Source/PluginEditor.cpp +++ b/Source/PluginEditor.cpp @@ -121,7 +121,7 @@ OscirenderAudioProcessorEditor::~OscirenderAudioProcessorEditor() { } bool OscirenderAudioProcessorEditor::isBinaryFile(juce::String name) { - return name.endsWith(".gpla") || name.endsWith(".gif") || name.endsWith(".png") || name.endsWith(".jpg") || name.endsWith(".jpeg"); + return name.endsWith(".gpla") || name.endsWith(".gif") || name.endsWith(".png") || name.endsWith(".jpg") || name.endsWith(".jpeg") || name.endsWith(".wav") || name.endsWith(".aiff"); } // parsersLock must be held diff --git a/Source/parser/FileParser.cpp b/Source/parser/FileParser.cpp index 6d8e7e8..568b323 100644 --- a/Source/parser/FileParser.cpp +++ b/Source/parser/FileParser.cpp @@ -18,6 +18,7 @@ void FileParser::parse(juce::String fileId, juce::String extension, std::unique_ gpla = nullptr; lua = nullptr; img = nullptr; + wav = nullptr; if (extension == ".obj") { object = std::make_shared(stream->readEntireStreamAsString().toStdString()); @@ -33,10 +34,12 @@ void FileParser::parse(juce::String fileId, juce::String extension, std::unique_ juce::MemoryBlock buffer{}; int bytesRead = stream->readIntoMemoryBlock(buffer); img = std::make_shared(audioProcessor, extension, buffer); + } else if (extension == ".wav" || extension == ".aiff") { + wav = std::make_shared(audioProcessor, std::move(stream)); } isAnimatable = gpla != nullptr || (img != nullptr && extension == ".gif"); - sampleSource = lua != nullptr || img != nullptr; + sampleSource = lua != nullptr || img != nullptr || wav != nullptr; } std::vector> FileParser::nextFrame() { @@ -72,7 +75,9 @@ Point FileParser::nextSample(lua_State*& L, LuaVariables& vars) { } } else if (img != nullptr) { return img->getSample(); - } + } else if (wav != nullptr) { + return wav->getSample(); + } return Point(); } @@ -122,3 +127,7 @@ std::shared_ptr FileParser::getLua() { std::shared_ptr FileParser::getImg() { return img; } + +std::shared_ptr FileParser::getWav() { + return wav; +} diff --git a/Source/parser/FileParser.h b/Source/parser/FileParser.h index 5750df9..5755fc7 100644 --- a/Source/parser/FileParser.h +++ b/Source/parser/FileParser.h @@ -8,6 +8,7 @@ #include "../gpla/LineArtParser.h" #include "../lua/LuaParser.h" #include "../img/ImageParser.h" +#include "../wav/WavParser.h" class OscirenderAudioProcessor; class FileParser { @@ -29,6 +30,7 @@ public: std::shared_ptr getLineArt(); std::shared_ptr getLua(); std::shared_ptr getImg(); + std::shared_ptr getWav(); bool isAnimatable = false; @@ -46,6 +48,7 @@ private: std::shared_ptr gpla; std::shared_ptr lua; std::shared_ptr img; + std::shared_ptr wav; juce::String fallbackLuaScript = "return { 0.0, 0.0 }"; diff --git a/Source/wav/WavParser.cpp b/Source/wav/WavParser.cpp new file mode 100644 index 0000000..45b1fed --- /dev/null +++ b/Source/wav/WavParser.cpp @@ -0,0 +1,43 @@ +#include "WavParser.h" +#include "../PluginProcessor.h" + + +WavParser::WavParser(OscirenderAudioProcessor& p, std::unique_ptr stream) : audioProcessor(p) { + juce::AudioFormatManager formatManager; + formatManager.registerBasicFormats(); + juce::AudioFormatReader* reader = formatManager.createReaderFor(std::move(stream)); + auto* afSource = new juce::AudioFormatReaderSource(reader, true); + afSource->setLooping(true); + source = std::make_unique(afSource, true); + fileSampleRate = reader->sampleRate; + audioBuffer.setSize(reader->numChannels, 1); + setSampleRate(audioProcessor.currentSampleRate); + source->prepareToPlay(1, audioProcessor.currentSampleRate); +} + +WavParser::~WavParser() { +} + +void WavParser::setSampleRate(double sampleRate) { + double ratio = fileSampleRate / sampleRate; + source->setResamplingRatio(ratio); + source->prepareToPlay(1, sampleRate); + currentSampleRate = sampleRate; +} + +Point WavParser::getSample() { + if (currentSampleRate != audioProcessor.currentSampleRate) { + setSampleRate(audioProcessor.currentSampleRate); + } + if (source == nullptr) { + return Point(); + } + + source->getNextAudioBlock(juce::AudioSourceChannelInfo(audioBuffer)); + + if (audioBuffer.getNumChannels() == 1) { + return Point(audioBuffer.getSample(0, 0), audioBuffer.getSample(0, 0)); + } else { + return Point(audioBuffer.getSample(0, 0), audioBuffer.getSample(1, 0)); + } +} diff --git a/Source/wav/WavParser.h b/Source/wav/WavParser.h new file mode 100644 index 0000000..7504508 --- /dev/null +++ b/Source/wav/WavParser.h @@ -0,0 +1,22 @@ +#pragma once +#include "../shape/Point.h" +#include + +class OscirenderAudioProcessor; +class WavParser { +public: + WavParser(OscirenderAudioProcessor& p, std::unique_ptr stream); + ~WavParser(); + + Point getSample(); + +private: + void setSampleRate(double sampleRate); + + std::unique_ptr source; + juce::AudioBuffer audioBuffer; + int currentSample = 0; + int fileSampleRate; + int currentSampleRate; + OscirenderAudioProcessor& audioProcessor; +}; \ No newline at end of file diff --git a/osci-render.jucer b/osci-render.jucer index 59e19f7..a2eebc5 100644 --- a/osci-render.jucer +++ b/osci-render.jucer @@ -584,6 +584,10 @@ + + + + Date: Fri, 23 Aug 2024 11:06:50 +0100 Subject: [PATCH 7/7] Add separate brightness and intensity sliders --- Resources/oscilloscope/oscilloscope.html | 3 ++- Resources/oscilloscope/oscilloscope.js | 7 ++++--- Source/PluginEditor.cpp | 4 ++-- Source/PluginProcessor.cpp | 1 + Source/PluginProcessor.h | 10 +++++++++- Source/components/VisualiserSettings.cpp | 9 +++++++-- Source/components/VisualiserSettings.h | 1 + 7 files changed, 26 insertions(+), 9 deletions(-) diff --git a/Resources/oscilloscope/oscilloscope.html b/Resources/oscilloscope/oscilloscope.html index ae76d74..69138cc 100644 --- a/Resources/oscilloscope/oscilloscope.html +++ b/Resources/oscilloscope/oscilloscope.html @@ -103,7 +103,8 @@ sweepMsDiv : 1, sweepTriggerValue : 0, mainGain : 0.0, - exposureStops : 0.0, + brightness : 0.0, + intensity: 0.02, hue : 125, invertXY : false, grid : true, diff --git a/Resources/oscilloscope/oscilloscope.js b/Resources/oscilloscope/oscilloscope.js index 5af39a6..baf4cc3 100644 --- a/Resources/oscilloscope/oscilloscope.js +++ b/Resources/oscilloscope/oscilloscope.js @@ -297,7 +297,7 @@ var Render = this.activateTargetTexture(null); this.setShader(this.outputShader); - var brightness = Math.pow(2, controls.exposureStops-2.0); + var brightness = Math.pow(2, controls.brightness-2.0); //if (controls.disableFilter) brightness *= Filter.steps; gl.uniform1f(this.outputShader.uExposure, brightness); gl.uniform1f(this.outputShader.uResizeForCanvas, this.lineTexture.width/1024); @@ -433,7 +433,7 @@ var Render = if (controls.invertXY) gl.uniform1f(program.uInvert, -1.0); else gl.uniform1f(program.uInvert, 1.0); - var intensity = 0.02 * (41000 / externalSampleRate); + var intensity = controls.intensity * (41000 / externalSampleRate); if (controls.disableFilter) gl.uniform1f(program.uIntensity, intensity *(Filter.steps+1.5)); // +1.5 needed above for some reason for the brightness to match @@ -688,7 +688,8 @@ function doScriptProcessor(bufferBase64) { const getSettingsFn = Juce.getNativeFunction("getSettings"); getSettingsFn().then(settings => { - controls.exposureStops = settings.intensity; + controls.brightness = settings.brightness; + controls.intensity = settings.intensity; controls.persistence = settings.persistence; controls.hue = settings.hue; controls.disableFilter = !settings.upsampling; diff --git a/Source/PluginEditor.cpp b/Source/PluginEditor.cpp index bf8a484..fa52505 100644 --- a/Source/PluginEditor.cpp +++ b/Source/PluginEditor.cpp @@ -115,9 +115,9 @@ OscirenderAudioProcessorEditor::OscirenderAudioProcessorEditor(OscirenderAudioPr visualiserSettingsWindow.setResizable(false, false); visualiserSettingsWindow.setUsingNativeTitleBar(true); visualiserSettings.setLookAndFeel(&getLookAndFeel()); - visualiserSettings.setSize(550, 230); + visualiserSettings.setSize(550, 260); visualiserSettingsWindow.setContentNonOwned(&visualiserSettings, true); - visualiserSettingsWindow.centreWithSize(550, 230); + visualiserSettingsWindow.centreWithSize(550, 260); tooltipDropShadow.setOwner(&tooltipWindow); } diff --git a/Source/PluginProcessor.cpp b/Source/PluginProcessor.cpp index 6e44d0a..7bb6e5d 100644 --- a/Source/PluginProcessor.cpp +++ b/Source/PluginProcessor.cpp @@ -149,6 +149,7 @@ OscirenderAudioProcessor::OscirenderAudioProcessor() permanentEffects.push_back(thresholdEffect); permanentEffects.push_back(imageThreshold); permanentEffects.push_back(imageStride); + permanentEffects.push_back(brightnessEffect); permanentEffects.push_back(intensityEffect); permanentEffects.push_back(persistenceEffect); permanentEffects.push_back(hueEffect); diff --git a/Source/PluginProcessor.h b/Source/PluginProcessor.h index 3cbe9ca..b7f198a 100644 --- a/Source/PluginProcessor.h +++ b/Source/PluginProcessor.h @@ -180,10 +180,18 @@ public: VERSION_HINT, 125, 0, 359, 1 ) ); + std::shared_ptr brightnessEffect = std::make_shared( + new EffectParameter( + "Brightness", + "Controls how bright the light glows for on the oscilloscope display.", + "brightness", + VERSION_HINT, 3.0, 0.0, 10.0 + ) + ); std::shared_ptr intensityEffect = std::make_shared( new EffectParameter( "Intensity", - "Controls how bright the light glows for on the oscilloscope display.", + "Controls how bright the electron beam of the oscilloscope is.", "intensity", VERSION_HINT, 3.0, 0.0, 10.0 ) diff --git a/Source/components/VisualiserSettings.cpp b/Source/components/VisualiserSettings.cpp index 025525c..b83b590 100644 --- a/Source/components/VisualiserSettings.cpp +++ b/Source/components/VisualiserSettings.cpp @@ -2,14 +2,17 @@ #include "VisualiserComponent.h" #include "../PluginEditor.h" + VisualiserSettings::VisualiserSettings(OscirenderAudioProcessor& p) : audioProcessor(p) { - addAndMakeVisible(intensity); + addAndMakeVisible(brightness); + addAndMakeVisible(intensity); addAndMakeVisible(persistence); addAndMakeVisible(hue); addAndMakeVisible(graticuleToggle); addAndMakeVisible(smudgeToggle); addAndMakeVisible(upsamplingToggle); + brightness.setSliderOnValueChange(); intensity.setSliderOnValueChange(); persistence.setSliderOnValueChange(); hue.setSliderOnValueChange(); @@ -20,6 +23,7 @@ VisualiserSettings::~VisualiserSettings() {} void VisualiserSettings::resized() { auto area = getLocalBounds().reduced(20); double rowHeight = 30; + brightness.setBounds(area.removeFromTop(rowHeight)); intensity.setBounds(area.removeFromTop(rowHeight)); persistence.setBounds(area.removeFromTop(rowHeight)); hue.setBounds(area.removeFromTop(rowHeight)); @@ -30,7 +34,8 @@ void VisualiserSettings::resized() { juce::var VisualiserSettings::getSettings() { auto settings = new juce::DynamicObject(); - settings->setProperty("intensity", audioProcessor.intensityEffect->getActualValue() - 2); + settings->setProperty("brightness", audioProcessor.brightnessEffect->getActualValue() - 2); + settings->setProperty("intensity", audioProcessor.intensityEffect->getActualValue() / 100); settings->setProperty("persistence", audioProcessor.persistenceEffect->getActualValue() - 1.33); settings->setProperty("hue", audioProcessor.hueEffect->getActualValue()); settings->setProperty("graticule", audioProcessor.graticuleEnabled->getBoolValue()); diff --git a/Source/components/VisualiserSettings.h b/Source/components/VisualiserSettings.h index 4a44a65..5be228d 100644 --- a/Source/components/VisualiserSettings.h +++ b/Source/components/VisualiserSettings.h @@ -16,6 +16,7 @@ public: private: OscirenderAudioProcessor& audioProcessor; + EffectComponent brightness{audioProcessor, *audioProcessor.brightnessEffect}; EffectComponent intensity{audioProcessor, *audioProcessor.intensityEffect}; EffectComponent persistence{audioProcessor, *audioProcessor.persistenceEffect}; EffectComponent hue{audioProcessor, *audioProcessor.hueEffect};