From ac5c8f77eb5568e711d5ea5ba58b54693c79b009 Mon Sep 17 00:00:00 2001 From: Jeff Martin Date: Tue, 23 Jun 2026 09:36:53 -0500 Subject: [PATCH 1/2] added phase wrapping to pv stretch --- src/pv/pvStretch.cpp | 80 ++++++++++++++++++----- src/rubberband/rubberBandStretcherBuf.cpp | 13 ---- 2 files changed, 64 insertions(+), 29 deletions(-) diff --git a/src/pv/pvStretch.cpp b/src/pv/pvStretch.cpp index cc4b71c..9db9cc1 100644 --- a/src/pv/pvStretch.cpp +++ b/src/pv/pvStretch.cpp @@ -361,7 +361,10 @@ void Stretch2( float instantaneousFreq = omegaK + phaseInc/hopSize; // Compute the new phase - outFrame->bin[xxk].phase = outFramePrev->bin[xxk].phase + hopSize * instantaneousFreq; + outFrame->bin[xxk].phase = sc_wrap( + outFramePrev->bin[xxk].phase + static_cast(hopSize * instantaneousFreq), + 0.f, + static_cast(twopi)); } } @@ -411,7 +414,10 @@ void Stretch2Puckette( } // Compute the new phase - outFrame->bin[xxk].phase = prevPhase + hopSize * instantaneousFreq; + outFrame->bin[xxk].phase = sc_wrap( + prevPhase + static_cast(hopSize * instantaneousFreq), + 0.f, + static_cast(twopi)); } } @@ -454,7 +460,10 @@ void Stretch2LarocheDolson( double instantaneousFreq = omegaK + phaseInc/hopSize; // Compute the phase - outFrame->bin[xxk].phase = outFramePrev->bin[xxk].phase + hopSize * instantaneousFreq; + outFrame->bin[xxk].phase = sc_wrap( + outFramePrev->bin[xxk].phase + static_cast(hopSize * instantaneousFreq), + 0.f, + static_cast(twopi)); } } else { // Update any bins that occur below the lowest peak's region of influence @@ -468,7 +477,10 @@ void Stretch2LarocheDolson( double instantaneousFreq = omegaK + phaseInc/hopSize; // Compute the phase - outFrame->bin[xxk].phase = outFramePrev->bin[xxk].phase + hopSize * instantaneousFreq; + outFrame->bin[xxk].phase = sc_wrap( + outFramePrev->bin[xxk].phase + static_cast(hopSize * instantaneousFreq), + 0.f, + static_cast(twopi)); } // Update any bins that occur above the highest peak's region of influence @@ -482,7 +494,10 @@ void Stretch2LarocheDolson( double instantaneousFreq = omegaK + phaseInc/hopSize; // Compute the phase - outFrame->bin[xxk].phase = outFramePrev->bin[xxk].phase + hopSize * instantaneousFreq; + outFrame->bin[xxk].phase = sc_wrap( + outFramePrev->bin[xxk].phase + static_cast(hopSize * instantaneousFreq), + 0.f, + static_cast(twopi)); } // Update all other peaks @@ -498,16 +513,25 @@ void Stretch2LarocheDolson( double instantaneousFreq = omegaK + phaseInc/hopSize; // Compute the phase - outFrame->bin[peak.peak].phase = outFramePrev->bin[peak.peak].phase + hopSize * instantaneousFreq; + outFrame->bin[peak.peak].phase = sc_wrap( + outFramePrev->bin[peak.peak].phase + static_cast(hopSize * instantaneousFreq), + 0.f, + static_cast(twopi)); // Then we update the phases of all other peaks for (size_t xxo = peak.leftValley; xxo < peak.peak; xxo++) { outFrame->bin[xxo].mag = frame->bin[xxo].mag; - outFrame->bin[xxo].phase = outFrame->bin[peak.peak].phase + frame->bin[xxo].phase - frame->bin[peak.peak].phase; + outFrame->bin[xxo].phase = sc_wrap( + outFrame->bin[peak.peak].phase + frame->bin[xxo].phase - frame->bin[peak.peak].phase, + 0.f, + static_cast(twopi)); } for (size_t xxo = peak.peak + 1; xxo <= peak.rightValley; xxo++) { outFrame->bin[xxo].mag = frame->bin[xxo].mag; - outFrame->bin[xxo].phase = outFrame->bin[peak.peak].phase + frame->bin[xxo].phase - frame->bin[peak.peak].phase; + outFrame->bin[xxo].phase = sc_wrap( + outFrame->bin[peak.peak].phase + frame->bin[xxo].phase - frame->bin[peak.peak].phase, + 0.f, + static_cast(twopi)); } } } @@ -556,7 +580,10 @@ void Stretch3( float instantaneousFreq = INTERP(instantaneousFreqPrev, instantaneousFreqNext, pos); // Compute the new phase - outFrame->bin[xxk].phase = outFramePrev->bin[xxk].phase + hopSize * instantaneousFreq; + outFrame->bin[xxk].phase = sc_wrap( + outFramePrev->bin[xxk].phase + static_cast(hopSize * instantaneousFreq), + 0.f, + static_cast(twopi)); } } @@ -619,7 +646,10 @@ void Stretch3Puckette( } // Compute the new phase - outFrame->bin[xxk].phase = prevPhase + hopSize * instantaneousFreq; + outFrame->bin[xxk].phase = sc_wrap( + prevPhase + static_cast(hopSize * instantaneousFreq), + 0.f, + static_cast(twopi)); } } @@ -683,7 +713,10 @@ static void Stretch3LarocheDolson( double instantaneousFreq = INTERP(instantaneousFreqPrev, instantaneousFreqNext, pos); // Compute the new phase - outFrame->bin[xxk].phase = outFramePrev->bin[xxk].phase + hopSize * instantaneousFreq; + outFrame->bin[xxk].phase = sc_wrap( + outFramePrev->bin[xxk].phase + static_cast(hopSize * instantaneousFreq), + 0.f, + static_cast(twopi)); } } else { // Update any bins that occur below the lowest peak's region of influence @@ -706,7 +739,10 @@ static void Stretch3LarocheDolson( double instantaneousFreq = INTERP(instantaneousFreqPrev, instantaneousFreqNext, pos); // Compute the phase - outFrame->bin[xxk].phase = outFramePrev->bin[xxk].phase + hopSize * instantaneousFreq; + outFrame->bin[xxk].phase = sc_wrap( + outFramePrev->bin[xxk].phase + static_cast(hopSize * instantaneousFreq), + 0.f, + static_cast(twopi)); } // Update any bins that occur above the highest peak's region of influence @@ -729,7 +765,10 @@ static void Stretch3LarocheDolson( double instantaneousFreq = INTERP(instantaneousFreqPrev, instantaneousFreqNext, pos); // Compute the phase - outFrame->bin[xxk].phase = outFramePrev->bin[xxk].phase + hopSize * instantaneousFreq; + outFrame->bin[xxk].phase = sc_wrap( + outFramePrev->bin[xxk].phase + static_cast(hopSize * instantaneousFreq), + 0.f, + static_cast(twopi)); } for (size_t xxn = 0; xxn < peakFinder->size(); xxn++) { @@ -753,16 +792,25 @@ static void Stretch3LarocheDolson( double instantaneousFreq = INTERP(instantaneousFreqPrev, instantaneousFreqNext, pos); // Compute the phase - outFrame->bin[peak.peak].phase = outFramePrev->bin[peak.peak].phase + hopSize * instantaneousFreq; + outFrame->bin[peak.peak].phase = sc_wrap( + outFramePrev->bin[peak.peak].phase + static_cast(hopSize * instantaneousFreq), + 0.f, + static_cast(twopi)); // Then we update all bins in the region of influence for (size_t xxo = peak.leftValley; xxo < peak.peak; xxo++) { outFrame->bin[xxo].mag = INTERP(framePrev1->bin[xxo].mag, frameNext->bin[xxo].mag, pos); - outFrame->bin[xxo].phase = outFrame->bin[peak.peak].phase + cframe->bin[xxo].phase - cframe->bin[peak.peak].phase; + outFrame->bin[xxo].phase = sc_wrap( + outFrame->bin[peak.peak].phase + cframe->bin[xxo].phase - cframe->bin[peak.peak].phase, + 0.f, + static_cast(twopi)); } for (size_t xxo = peak.peak + 1; xxo <= peak.rightValley; xxo++) { outFrame->bin[xxo].mag = INTERP(framePrev1->bin[xxo].mag, frameNext->bin[xxo].mag, pos); - outFrame->bin[xxo].phase = outFrame->bin[peak.peak].phase + cframe->bin[xxo].phase - cframe->bin[peak.peak].phase; + outFrame->bin[xxo].phase = sc_wrap( + outFrame->bin[peak.peak].phase + cframe->bin[xxo].phase - cframe->bin[peak.peak].phase, + 0.f, + static_cast(twopi)); } } } diff --git a/src/rubberband/rubberBandStretcherBuf.cpp b/src/rubberband/rubberBandStretcherBuf.cpp index 976d10c..8445966 100644 --- a/src/rubberband/rubberBandStretcherBuf.cpp +++ b/src/rubberband/rubberBandStretcherBuf.cpp @@ -29,13 +29,6 @@ along with this program. If not, see . extern InterfaceTable *ft; void RubberBandStretcherBuf_Ctor(RubberBandStretcherBuf *unit) { - - /* arg in, bufnum=0, offset=0.0, recLevel=1.0, preLevel=0.0, run=1.0, loop=1.0, trigger=1.0, - 8 timeRatio=1.0, pitchRatio=1.0, formantRatio=0.0, transientsMode=0, - 12 detectorMode=0, phaseMode=0, pitchQuality=0, windowOption=0, - 16 smoothing=0, engine=0, doneAction=0; - */ - float timeRatio = IN0(8); float pitchRatio = IN0(9); float formantRatio = IN0(10); @@ -159,12 +152,6 @@ void RubberBandStretcherBuf_Dtor(RubberBandStretcherBuf *unit) { } void RubberBandStretcherBuf_next(RubberBandStretcherBuf *unit, int inNumSamples) { - /* arg in, bufnum=0, offset=0.0, recLevel=1.0, preLevel=0.0, run=1.0, loop=1.0, trigger=1.0, - 8 timeRatio=1.0, pitchRatio=1.0, formantRatio=0.0, transientsMode=0, - 12 detectorMode=0, phaseMode=0, pitchQuality=0, windowOption=0, - 16 smoothing=0, engine=0, doneAction=0; - */ - // Step 1: acquire the sound buffer const SndBuf *writeBuf = unit->m_buf; if (!writeBuf) { From 8efdf2a78f0ac7b3fa8b3d42b87c608162dc1f1d Mon Sep 17 00:00:00 2001 From: Jeff Martin Date: Sat, 11 Jul 2026 18:19:14 -0500 Subject: [PATCH 2/2] updated version for next release --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4bfc63a..46805f3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ # are adapted from the prototype CMakeLists.txt provided with the SuperCollider plugin starter code. cmake_minimum_required(VERSION 3.20) -project(flexplugins) +project(flexplugins VERSION 0.1.3) # To make a ZIP archive set(CPACK_GENERATOR "ZIP")