From c698e2a7dd0ba8eb22431a9a7500ce8ab569f9d6 Mon Sep 17 00:00:00 2001 From: Anthony Hall Date: Mon, 8 Sep 2025 04:21:43 -0700 Subject: [PATCH] Polish duplication boundary handling --- Source/audio/HarmonicDuplicatorEffect.h | 10 ++++------ Source/audio/KaleidoscopeEffect.h | 4 ++-- Source/audio/MultiplexEffect.h | 10 ++++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Source/audio/HarmonicDuplicatorEffect.h b/Source/audio/HarmonicDuplicatorEffect.h index 7b2bfa67..50c1f383 100644 --- a/Source/audio/HarmonicDuplicatorEffect.h +++ b/Source/audio/HarmonicDuplicatorEffect.h @@ -9,13 +9,11 @@ public: osci::Point apply(int index, osci::Point input, const std::vector>& values, double sampleRate) override { const double twoPi = juce::MathConstants::twoPi; double copies = juce::jmax(1.0, values[0].load()); + double ceilCopies = std::ceil(copies - 1e-3); double spread = juce::jlimit(0.0, 1.0, values[1].load()); double angleOffset = values[2].load() * juce::MathConstants::twoPi; - // Ensure values extremely close to integer don't get rounded up - double fractionalPart = copies - std::floor(copies); - double ceilCopies = fractionalPart > 1e-4 ? std::ceil(copies) : std::floor(copies); - + // Offset moves each time the input shape is drawn once double theta = std::floor(framePhase * copies) / copies * twoPi + angleOffset; osci::Point offset(std::cos(theta), std::sin(theta), 0.0); @@ -37,8 +35,8 @@ public: "harmonicDuplicatorSpread", VERSION_HINT, 0.4, 0.0, 1.0), new osci::EffectParameter("Angle Offset", "Rotates the offsets between copies without rotating the input shape.", - "harmonicDuplicatorAngle", VERSION_HINT, 0.0, 0.0, 1.0, 0.0001, osci::LfoType::Sawtooth, 0.2) - } + "harmonicDuplicatorAngle", VERSION_HINT, 0.0, 0.0, 1.0, 0.0001, osci::LfoType::Sawtooth, 0.1) + } ); eff->setName("Harmonic Duplicator"); eff->setIcon(BinaryData::kaleidoscope_svg); diff --git a/Source/audio/KaleidoscopeEffect.h b/Source/audio/KaleidoscopeEffect.h index be76c0bb..7d662b41 100644 --- a/Source/audio/KaleidoscopeEffect.h +++ b/Source/audio/KaleidoscopeEffect.h @@ -22,7 +22,7 @@ public: int fullSegments = (int)std::floor(segments); double fractionalPart = segments - fullSegments; // in [0,1) - fullSegments = fractionalPart > 1e-4 ? fullSegments : fullSegments - 1; + fullSegments = fractionalPart > 1e-3 ? fullSegments : fullSegments - 1; phase = nextPhase(audioProcessor.frequency / (fullSegments + 1), sampleRate) / (2.0 * std::numbers::pi); @@ -33,7 +33,7 @@ public: // Base full wedge angle (all full wedges) and size of partial wedge double baseWedgeAngle = juce::MathConstants::twoPi / segments; // size of a "unit" wedge - double partialScale = (currentSegmentIndex == fullSegments && fractionalPart > 1e-4) ? fractionalPart : 1.0; + double partialScale = (currentSegmentIndex == fullSegments && fractionalPart > 1e-3) ? fractionalPart : 1.0; double wedgeAngle = baseWedgeAngle * partialScale; // Normalize theta to [0,1) for compression diff --git a/Source/audio/MultiplexEffect.h b/Source/audio/MultiplexEffect.h index 4bef9f91..fdb9328b 100644 --- a/Source/audio/MultiplexEffect.h +++ b/Source/audio/MultiplexEffect.h @@ -11,9 +11,9 @@ 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() + 0.0001; - double gridY = values[1].load() + 0.0001; - double gridZ = values[2].load() + 0.0001; + double gridX = values[0].load(); + double gridY = values[1].load(); + double gridZ = values[2].load(); double interpolation = values[3].load(); double gridDelay = values[4].load(); @@ -24,7 +24,9 @@ public: buffer[head] = input; osci::Point grid = osci::Point(gridX, gridY, gridZ); - osci::Point gridFloor = osci::Point(std::floor(gridX), std::floor(gridY), std::floor(gridZ)); + osci::Point gridFloor = osci::Point(std::floor(gridX + 1e-3), + std::floor(gridY + 1e-3), + std::floor(gridZ + 1e-3)); gridFloor.x = std::max(gridFloor.x, 1.0); gridFloor.y = std::max(gridFloor.y, 1.0);