c95682d81148 — Chris Cannam tip 3 hours ago
Apply gradual phase-reset on unity in the R2 stretcher (R3 already does this)
M src/faster/StretcherChannelData.cpp +2 -0
@@ 87,6 87,8 @@ R2Stretcher::ChannelData::construct(cons
     interpolator = allocate_and_zero<float>(maxSize);
     interpolatorScale = 0;
 
+    unityResetLow = 16000.f;
+
     for (std::set<size_t>::const_iterator i = sizes.begin();
          i != sizes.end(); ++i) {
         ffts[*i] = new FFT(*i);

          
M src/faster/StretcherChannelData.h +1 -0
@@ 113,6 113,7 @@ public:
     float *ms; // only used when mid-side processing
     float *interpolator; // only used when time-domain smoothing is on
     int interpolatorScale;
+    float unityResetLow; // for gradual phase-reset on unity ratio
 
     float *fltbuf;
     process_t *dblbuf; // owned by FFT object, only used for time domain FFT i/o

          
M src/faster/StretcherProcess.cpp +19 -2
@@ 744,12 744,29 @@ R2Stretcher::modifyChunk(size_t channel,
     int bandlow = lrint((150 * m_fftSize) / rate);
     int bandhigh = lrint((1000 * m_fftSize) / rate);
 
+    float r = getEffectiveRatio();
+
+    bool unity = (fabsf(r - 1.f) < 1.e-6f);
+    if (unity) {
+        if (!phaseReset) {
+            phaseReset = true;
+            bandlimited = true;
+            bandlow = lrint((cd.unityResetLow * m_fftSize) / rate);
+            bandhigh = count;
+            if (bandlow > 0) {
+                m_log.log(2, "unity: bandlow & high", bandlow, bandhigh);
+            }
+        }
+        cd.unityResetLow *= 0.9f;
+    } else {
+        cd.unityResetLow = 16000.f;
+    }
+
     float freq0 = m_freq0;
     float freq1 = m_freq1;
     float freq2 = m_freq2;
-
+    
     if (laminar) {
-        float r = getEffectiveRatio();
         if (r > 1) {
             float rf0 = 600 + (600 * ((r-1)*(r-1)*(r-1)*2));
             float f1ratio = freq1 / freq0;