From e2a6e8ae10e6b134f71704334f42bcb6704c32f9 Mon Sep 17 00:00:00 2001 From: Anthony Hall Date: Thu, 4 Sep 2025 15:57:53 -0700 Subject: [PATCH 1/5] Add radial wrap effect (complex power) --- Source/PluginProcessor.cpp | 2 ++ Source/audio/RadialWrapEffect.h | 36 +++++++++++++++++++++++++++++++++ osci-render.jucer | 2 ++ 3 files changed, 40 insertions(+) create mode 100644 Source/audio/RadialWrapEffect.h diff --git a/Source/PluginProcessor.cpp b/Source/PluginProcessor.cpp index 7c577688..0950dd5a 100644 --- a/Source/PluginProcessor.cpp +++ b/Source/PluginProcessor.cpp @@ -26,6 +26,7 @@ #include "audio/SwirlEffect.h" #include "audio/BounceEffect.h" #include "audio/SkewEffect.h" +#include "audio/RadialWrapEffect.h" #include "parser/FileParser.h" #include "parser/FrameProducer.h" @@ -56,6 +57,7 @@ OscirenderAudioProcessor::OscirenderAudioProcessor() : CommonAudioProcessor(Buse toggleableEffects.push_back(BounceEffect().build()); toggleableEffects.push_back(TwistEffect().build()); toggleableEffects.push_back(SkewEffect().build()); + toggleableEffects.push_back(RadialWrapEffect().build()); #endif auto scaleEffect = ScaleEffectApp().build(); diff --git a/Source/audio/RadialWrapEffect.h b/Source/audio/RadialWrapEffect.h new file mode 100644 index 00000000..4d9ee11e --- /dev/null +++ b/Source/audio/RadialWrapEffect.h @@ -0,0 +1,36 @@ +#pragma once +#include + +class RadialWrapEffect : public osci::EffectApplication { +public: + osci::Point apply(int index, osci::Point input, const std::vector> &values, double sampleRate) override { + // Treat input as complex number and raise to integer power + // Disallowing non-integer and negative exponents because of the branch cut + // Note 90 degree rotation: Theta is treated relative to +Y rather than +X + double effectScale = juce::jlimit(0.0, 1.0, values[0].load()); + double exponent = juce::jmax(1.0, std::floor(values[1].load() + 0.0001)); + + osci::Point output(0, 0, input.z); + if (input.x != 0 || input.y != 0) { + double r2 = input.x * input.x + input.y * input.y; + double theta = std::atan2(-input.x, input.y); + + double outR = std::pow(r2, 0.5 * exponent); + double outTheta = exponent * theta; + output.x = outR * -std::sin(outTheta); + output.y = outR * std::cos(outTheta); + } + return (1 - effectScale) * input + effectScale * output; + } + + std::shared_ptr build() const override { + auto eff = std::make_shared( + std::make_shared(), + std::vector{ + new osci::EffectParameter("Radial Wrap", "Distorts the shape by multiplying the angle and warping the length of each point.", "radialWrapEnable", VERSION_HINT, 1.0, 0.0, 1.0), + new osci::EffectParameter("Wrap Degree", "The multiplier applied to each point's angle.", "radialWrapDegree", VERSION_HINT, 2.0, 1.0, 6.0) + }); + eff->setIcon(BinaryData::twist_svg); + return eff; + } +}; \ No newline at end of file diff --git a/osci-render.jucer b/osci-render.jucer index c77d7694..1a8c6714 100644 --- a/osci-render.jucer +++ b/osci-render.jucer @@ -166,6 +166,8 @@ + Date: Sun, 7 Sep 2025 02:30:18 -0700 Subject: [PATCH 2/5] Add ref angle control, 60% default dry/wet (now 1000x cooler) --- Source/audio/RadialWrapEffect.h | 63 ++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 28 deletions(-) diff --git a/Source/audio/RadialWrapEffect.h b/Source/audio/RadialWrapEffect.h index 4d9ee11e..0bd71a1e 100644 --- a/Source/audio/RadialWrapEffect.h +++ b/Source/audio/RadialWrapEffect.h @@ -3,34 +3,41 @@ class RadialWrapEffect : public osci::EffectApplication { public: - osci::Point apply(int index, osci::Point input, const std::vector> &values, double sampleRate) override { - // Treat input as complex number and raise to integer power - // Disallowing non-integer and negative exponents because of the branch cut - // Note 90 degree rotation: Theta is treated relative to +Y rather than +X - double effectScale = juce::jlimit(0.0, 1.0, values[0].load()); - double exponent = juce::jmax(1.0, std::floor(values[1].load() + 0.0001)); + osci::Point apply(int index, osci::Point input, const std::vector> &values, double sampleRate) override { + // Treat input as complex number and raise to integer power + // Disallowing non-integer and negative exponents because of the branch cut + double effectScale = juce::jlimit(0.0, 1.0, values[0].load()); + double exponent = juce::jmax(1.0, std::floor(values[1].load() + 0.0001)); + double refTheta = values[2].load() * juce::MathConstants::twoPi; - osci::Point output(0, 0, input.z); - if (input.x != 0 || input.y != 0) { - double r2 = input.x * input.x + input.y * input.y; - double theta = std::atan2(-input.x, input.y); + osci::Point output(0, 0, input.z); + if (input.x != 0 || input.y != 0) { + double r2 = input.x * input.x + input.y * input.y; + double theta = std::atan2(input.y, input.x) - refTheta; - double outR = std::pow(r2, 0.5 * exponent); - double outTheta = exponent * theta; - output.x = outR * -std::sin(outTheta); - output.y = outR * std::cos(outTheta); - } - return (1 - effectScale) * input + effectScale * output; - } + double outR = std::pow(r2, 0.5 * exponent); + double outTheta = exponent * theta + refTheta; + output.x = outR * std::cos(outTheta); + output.y = outR * std::sin(outTheta); + } + return (1 - effectScale) * input + effectScale * output; + } - std::shared_ptr build() const override { - auto eff = std::make_shared( - std::make_shared(), - std::vector{ - new osci::EffectParameter("Radial Wrap", "Distorts the shape by multiplying the angle and warping the length of each point.", "radialWrapEnable", VERSION_HINT, 1.0, 0.0, 1.0), - new osci::EffectParameter("Wrap Degree", "The multiplier applied to each point's angle.", "radialWrapDegree", VERSION_HINT, 2.0, 1.0, 6.0) - }); - eff->setIcon(BinaryData::twist_svg); - return eff; - } -}; \ No newline at end of file + std::shared_ptr build() const override { + auto eff = std::make_shared( + std::make_shared(), + std::vector{ + new osci::EffectParameter("Radial Wrap", + "Distorts the shape by multiplying the angle and warping the length of each point.", "radialWrapEnable", + VERSION_HINT, 0.6, 0.0, 1.0), + new osci::EffectParameter("Wrap Degree", + "The multiplier applied to each point's angle.", "radialWrapDegree", + VERSION_HINT, 2.0, 1.0, 6.0), + new osci::EffectParameter("Reference Angle", + "The reference angle from which each point's angle is multiplied.", "radialWrapRefAngle", + VERSION_HINT, 0.25, 0.0, 1.0, 0.0001, osci::LfoType::Sawtooth, 0.2) + }); + eff->setIcon(BinaryData::twist_svg); + return eff; + } +}; From c6c08877fb7f87625dbd069cd6917a4431caf000 Mon Sep 17 00:00:00 2001 From: Anthony Hall Date: Tue, 9 Sep 2025 15:41:11 -0700 Subject: [PATCH 3/5] Adjust parameters --- Source/audio/RadialWrapEffect.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Source/audio/RadialWrapEffect.h b/Source/audio/RadialWrapEffect.h index 0bd71a1e..7bcf8bdb 100644 --- a/Source/audio/RadialWrapEffect.h +++ b/Source/audio/RadialWrapEffect.h @@ -7,7 +7,7 @@ public: // Treat input as complex number and raise to integer power // Disallowing non-integer and negative exponents because of the branch cut double effectScale = juce::jlimit(0.0, 1.0, values[0].load()); - double exponent = juce::jmax(1.0, std::floor(values[1].load() + 0.0001)); + double exponent = juce::jmax(1.0, std::floor(values[1].load() + 0.001)); double refTheta = values[2].load() * juce::MathConstants::twoPi; osci::Point output(0, 0, input.z); @@ -28,14 +28,14 @@ public: std::make_shared(), std::vector{ new osci::EffectParameter("Radial Wrap", - "Distorts the shape by multiplying the angle and warping the length of each point.", "radialWrapEnable", - VERSION_HINT, 0.6, 0.0, 1.0), + "Distorts the shape by multiplying the angle and warping the length of each point.", + "radialWrap", VERSION_HINT, 0.6, 0.0, 1.0), new osci::EffectParameter("Wrap Degree", - "The multiplier applied to each point's angle.", "radialWrapDegree", - VERSION_HINT, 2.0, 1.0, 6.0), + "The multiplier applied to each point's angle.", + "radialWrapDegree", VERSION_HINT, 2.0, 2.0, 6.0, 1.0), new osci::EffectParameter("Reference Angle", - "The reference angle from which each point's angle is multiplied.", "radialWrapRefAngle", - VERSION_HINT, 0.25, 0.0, 1.0, 0.0001, osci::LfoType::Sawtooth, 0.2) + "The reference angle from which each point's angle is multiplied.", + "radialWrapRefAngle", VERSION_HINT, 0.25, 0.0, 1.0, 0.0001, osci::LfoType::Sawtooth, 0.2) }); eff->setIcon(BinaryData::twist_svg); return eff; From ff5752fc09c21f21c9fb0ffc197e66c95d8e5983 Mon Sep 17 00:00:00 2001 From: James H Ball Date: Thu, 11 Sep 2025 21:33:19 +0100 Subject: [PATCH 4/5] Add icon and rename radial wrap to vortex --- Resources/svg/vortex.svg | 1 + Source/PluginProcessor.cpp | 4 +-- Source/audio/GodRayEffect.h | 1 + .../{RadialWrapEffect.h => VortexEffect.h} | 25 ++++++++++--------- osci-render.jucer | 4 +-- 5 files changed, 19 insertions(+), 16 deletions(-) create mode 100644 Resources/svg/vortex.svg rename Source/audio/{RadialWrapEffect.h => VortexEffect.h} (59%) diff --git a/Resources/svg/vortex.svg b/Resources/svg/vortex.svg new file mode 100644 index 00000000..6a0b7979 --- /dev/null +++ b/Resources/svg/vortex.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Source/PluginProcessor.cpp b/Source/PluginProcessor.cpp index eca28158..95b0f63f 100644 --- a/Source/PluginProcessor.cpp +++ b/Source/PluginProcessor.cpp @@ -28,7 +28,7 @@ #include "audio/SwirlEffect.h" #include "audio/BounceEffect.h" #include "audio/SkewEffect.h" -#include "audio/RadialWrapEffect.h" +#include "audio/VortexEffect.h" #include "audio/GodRayEffect.h" #include "parser/FileParser.h" #include "parser/FrameProducer.h" @@ -61,7 +61,7 @@ OscirenderAudioProcessor::OscirenderAudioProcessor() : CommonAudioProcessor(Buse toggleableEffects.push_back(BounceEffect().build()); toggleableEffects.push_back(TwistEffect().build()); toggleableEffects.push_back(SkewEffect().build()); - toggleableEffects.push_back(RadialWrapEffect().build()); + toggleableEffects.push_back(VortexEffect().build()); toggleableEffects.push_back(GodRayEffect().build()); toggleableEffects.push_back(SpiralBitCrushEffect().build()); #endif diff --git a/Source/audio/GodRayEffect.h b/Source/audio/GodRayEffect.h index c035235c..77b61444 100644 --- a/Source/audio/GodRayEffect.h +++ b/Source/audio/GodRayEffect.h @@ -31,6 +31,7 @@ public: "Controls whether the rays appear to be radiating inward or outward.", "godRayPosition", VERSION_HINT, 0.8, -1.0, 1.0) }); + eff->setName("God Ray"); eff->setIcon(BinaryData::god_ray_svg); return eff; } diff --git a/Source/audio/RadialWrapEffect.h b/Source/audio/VortexEffect.h similarity index 59% rename from Source/audio/RadialWrapEffect.h rename to Source/audio/VortexEffect.h index 7bcf8bdb..a4faa4a9 100644 --- a/Source/audio/RadialWrapEffect.h +++ b/Source/audio/VortexEffect.h @@ -1,7 +1,7 @@ #pragma once #include -class RadialWrapEffect : public osci::EffectApplication { +class VortexEffect : public osci::EffectApplication { public: osci::Point apply(int index, osci::Point input, const std::vector> &values, double sampleRate) override { // Treat input as complex number and raise to integer power @@ -25,19 +25,20 @@ public: std::shared_ptr build() const override { auto eff = std::make_shared( - std::make_shared(), + std::make_shared(), std::vector{ - new osci::EffectParameter("Radial Wrap", - "Distorts the shape by multiplying the angle and warping the length of each point.", - "radialWrap", VERSION_HINT, 0.6, 0.0, 1.0), - new osci::EffectParameter("Wrap Degree", - "The multiplier applied to each point's angle.", - "radialWrapDegree", VERSION_HINT, 2.0, 2.0, 6.0, 1.0), - new osci::EffectParameter("Reference Angle", - "The reference angle from which each point's angle is multiplied.", - "radialWrapRefAngle", VERSION_HINT, 0.25, 0.0, 1.0, 0.0001, osci::LfoType::Sawtooth, 0.2) + new osci::EffectParameter("Vortex Strength", + "Controls the strength of the vortex effect.", + "vortexStrength", VERSION_HINT, 0.6, 0.0, 1.0), + new osci::EffectParameter("Vortex Amount", + "The multiplier applied to each point's angle, creating more vortexes.", + "vortexAmount", VERSION_HINT, 2.0, 2.0, 6.0, 1.0), + new osci::EffectParameter("Vortex Rotation", + "The rotation applied to each point.", + "vortexRotation", VERSION_HINT, 0.25, 0.0, 1.0, 0.0001, osci::LfoType::Sawtooth, 0.2) }); - eff->setIcon(BinaryData::twist_svg); + eff->setName("Vortex"); + eff->setIcon(BinaryData::vortex_svg); return eff; } }; diff --git a/osci-render.jucer b/osci-render.jucer index 33fb14f1..730537dd 100644 --- a/osci-render.jucer +++ b/osci-render.jucer @@ -156,6 +156,7 @@ + @@ -170,8 +171,7 @@ - + Date: Thu, 11 Sep 2025 21:35:45 +0100 Subject: [PATCH 5/5] fix JUCE modules path --- osci-render.jucer | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osci-render.jucer b/osci-render.jucer index 730537dd..ac51ec2e 100644 --- a/osci-render.jucer +++ b/osci-render.jucer @@ -854,7 +854,7 @@ - + @@ -912,3 +912,4 @@ +