From 4321de2f27285a10a64220b7da18b7afeaa69545 Mon Sep 17 00:00:00 2001 From: James H Ball Date: Sun, 27 Jul 2025 17:23:44 +0100 Subject: [PATCH] Add initial version of multiplex effect --- Source/CommonPluginEditor.cpp | 2 +- Source/PluginProcessor.cpp | 14 +++++++ Source/audio/DashedLineEffect.cpp | 0 Source/audio/MultiplexEffect.h | 65 ++++++++++++++++++++++++++++++ Source/audio/PerspectiveEffect.cpp | 0 modules/osci_render_core | 2 +- osci-render.jucer | 6 +-- packaging/osci-render.iss | 2 +- packaging/sosci.iss | 2 +- 9 files changed, 85 insertions(+), 8 deletions(-) delete mode 100644 Source/audio/DashedLineEffect.cpp create mode 100644 Source/audio/MultiplexEffect.h delete mode 100644 Source/audio/PerspectiveEffect.cpp diff --git a/Source/CommonPluginEditor.cpp b/Source/CommonPluginEditor.cpp index 828d3f2b..2486d5a9 100644 --- a/Source/CommonPluginEditor.cpp +++ b/Source/CommonPluginEditor.cpp @@ -3,7 +3,7 @@ #include "CustomStandaloneFilterWindow.h" CommonPluginEditor::CommonPluginEditor(CommonAudioProcessor& p, juce::String appName, juce::String projectFileType, int defaultWidth, int defaultHeight) - : AudioProcessorEditor(&p), audioProcessor(p), appName(appName), projectFileType(projectFileType) + : AudioProcessorEditor(&p), audioProcessor(p), appName(appName), projectFileType(projectFileType) { #if JUCE_LINUX // use OpenGL on Linux for much better performance. The default on Mac is CoreGraphics, and on Window is Direct2D which is much faster. diff --git a/Source/PluginProcessor.cpp b/Source/PluginProcessor.cpp index 1bed9344..71c0fb98 100644 --- a/Source/PluginProcessor.cpp +++ b/Source/PluginProcessor.cpp @@ -12,6 +12,7 @@ #include "audio/BitCrushEffect.h" #include "audio/BulgeEffect.h" #include "audio/DistortEffect.h" +#include "audio/MultiplexEffect.h" #include "audio/SmoothEffect.h" #include "audio/VectorCancellingEffect.h" #include "parser/FileParser.h" @@ -31,6 +32,19 @@ OscirenderAudioProcessor::OscirenderAudioProcessor() : CommonAudioProcessor(Buse toggleableEffects.push_back(std::make_shared( std::make_shared(), new osci::EffectParameter("Bulge", "Applies a bulge that makes the centre of the image larger, and squishes the edges of the image. This applies a distortion to the audio.", "bulge", VERSION_HINT, 0.5, 0.0, 1.0))); + auto multiplexEffect = std::make_shared( + std::make_shared(), + std::vector{ + new osci::EffectParameter("Multiplex Grid X", "Controls the horizontal grid size for the multiplex effect.", "multiplexGridX", VERSION_HINT, 1.0, 1.0, 8.0), + new osci::EffectParameter("Multiplex Grid Y", "Controls the vertical grid size for the multiplex effect.", "multiplexGridY", VERSION_HINT, 1.0, 1.0, 8.0), + new osci::EffectParameter("Multiplex Grid Z", "Controls the depth grid size for the multiplex effect.", "multiplexGridZ", VERSION_HINT, 1.0, 1.0, 8.0), + new osci::EffectParameter("Multiplex Smooth", "Controls the smoothness of transitions between grid sizes.", "multiplexSmooth", VERSION_HINT, 1.0, 0.0, 1.0), + new osci::EffectParameter("Grid Phase", "Controls the current phase of the grid animation.", "gridPhase", VERSION_HINT, 0.0, -1.0, 1.0), + }); + // Set up the Grid Phase parameter with sawtooth LFO at 100Hz + multiplexEffect->getParameter("gridPhase")->lfo->setUnnormalisedValueNotifyingHost((int)osci::LfoType::Sawtooth); + multiplexEffect->getParameter("gridPhase")->lfoRate->setUnnormalisedValueNotifyingHost(100.0); + toggleableEffects.push_back(multiplexEffect); toggleableEffects.push_back(std::make_shared( std::make_shared(), new osci::EffectParameter("Vector Cancelling", "Inverts the audio and image every few samples to 'cancel out' the audio, making the audio quiet, and distorting the image.", "vectorCancelling", VERSION_HINT, 0.1111111, 0.0, 1.0))); diff --git a/Source/audio/DashedLineEffect.cpp b/Source/audio/DashedLineEffect.cpp deleted file mode 100644 index e69de29b..00000000 diff --git a/Source/audio/MultiplexEffect.h b/Source/audio/MultiplexEffect.h new file mode 100644 index 00000000..e4e8d302 --- /dev/null +++ b/Source/audio/MultiplexEffect.h @@ -0,0 +1,65 @@ +#pragma once +#include +#include + +class MultiplexEffect : public osci::EffectApplication { +public: + osci::Point apply(int index, osci::Point input, const std::vector>& values, double sampleRate) override { + jassert(values.size() >= 5); + + double gridX = values[0].load(); + double gridY = values[1].load(); + double gridZ = values[2].load(); + double interpolation = values[3].load(); + double phase = values[4].load(); + + osci::Point grid = osci::Point(gridX, gridY, gridZ); + osci::Point gridFloor = osci::Point(std::floor(gridX), std::floor(gridY), std::floor(gridZ)); + + gridFloor.x = std::max(gridFloor.x, 1.0); + gridFloor.y = std::max(gridFloor.y, 1.0); + gridFloor.z = std::max(gridFloor.z, 1.0); + + double totalPositions = gridFloor.x * gridFloor.y * gridFloor.z; + double position = phase * totalPositions; + + osci::Point nextGrid = gridFloor + 1.0; + + osci::Point current = multiplex(input, position, gridFloor); + osci::Point next = multiplex(input, position, nextGrid); + + // Calculate interpolation factors + osci::Point gridDiff = grid - gridFloor; + osci::Point interpolationFactor = gridDiff * interpolation; + + return (1.0 - interpolationFactor) * current + interpolationFactor * next; + } + +private: + osci::Point multiplex(osci::Point point, double position, osci::Point grid) { + osci::Point unit = 1.0 / grid; + + point *= unit; + point.x = -point.x; + point.y = -point.y; + + double xPosRaw = std::floor(position); + double yPosRaw = std::floor(position / grid.x); + double zPosRaw = std::floor(position / (grid.x * grid.y)); + + // Use fmod for positive modulo with doubles + double xPos = std::fmod(std::fmod(xPosRaw, grid.x) + grid.x, grid.x); + double yPos = std::fmod(std::fmod(yPosRaw, grid.y) + grid.y, grid.y); + double zPos = std::fmod(std::fmod(zPosRaw, grid.z) + grid.z, grid.z); + + point.x -= (grid.x - 1.0) / grid.x; + point.y += (grid.y - 1.0) / grid.y; + point.z += (grid.z - 1.0) / grid.z; + + point.x += xPos * 2.0 * unit.x; + point.y -= yPos * 2.0 * unit.y; + point.z -= zPos * 2.0 * unit.z; + + return point; + } +}; diff --git a/Source/audio/PerspectiveEffect.cpp b/Source/audio/PerspectiveEffect.cpp deleted file mode 100644 index e69de29b..00000000 diff --git a/modules/osci_render_core b/modules/osci_render_core index a517f09b..913c3b05 160000 --- a/modules/osci_render_core +++ b/modules/osci_render_core @@ -1 +1 @@ -Subproject commit a517f09beac37a919fe43772e98e779ffc1f0ba3 +Subproject commit 913c3b052404818c45ad93c5e6022244d57df5e9 diff --git a/osci-render.jucer b/osci-render.jucer index 7e42d3ba..be38c779 100644 --- a/osci-render.jucer +++ b/osci-render.jucer @@ -86,14 +86,12 @@ - - +