# HG changeset patch # User Chris Cannam # Date 1656928370 -3600 # Mon Jul 04 10:52:50 2022 +0100 # Branch r3 # Node ID e272b4f17165d72afade9185e7c7594204c24a15 # Parent 12f7b6f687a1cb0cae52525a940ca186e68ff9c1 Connect up the ChannelsTogether option in R3 as well, to extend the channel lock range upward diff --git a/rubberband/RubberBandStretcher.h b/rubberband/RubberBandStretcher.h --- a/rubberband/RubberBandStretcher.h +++ b/rubberband/RubberBandStretcher.h @@ -331,25 +331,30 @@ * the others in the case where the pitch scale is exactly 1.0. * * 11. Flags prefixed \c OptionChannels control the method used - * for processing two-channel audio in the R2 engine. These - * options have no effect when using the R3 engine. These options + * for processing two-channel stereo audio. These have different, + * but related, effects in the R2 and R3 engines. These options * may not be changed after construction. * - * \li \c OptionChannelsApart - Each channel is processed - * individually, though timing is synchronised and phases are - * synchronised at transients (depending on the OptionTransients - * setting). This gives the highest quality for the individual - * channels but a relative lack of stereo focus and unrealistic - * increase in "width". This is the default. + * \li \c OptionChannelsApart - Channels are handled for maximum + * individual fidelity, with less tight synchronisation. In the + * R3 engine, this means stereo synchronisation is maintained + * more closely for lower-frequency content than higher. In R2, + * it means the stereo channels are processed individually and + * only synchronised at transients. In both engines this gives + * the highest quality for the individual channels but a more + * diffuse stereo image and an unnatural increase in "width". + * This option is the default. * - * \li \c OptionChannelsTogether - The first two channels (where - * two or more are present) are considered to be a stereo pair - * and are processed in mid-side format; mid and side are - * processed individually, with timing synchronised and phases - * synchronised at transients (depending on the OptionTransients - * setting). This usually leads to better focus in the centre - * but a loss of stereo space and width. Any channels beyond - * the first two are processed individually. + * \li \c OptionChannelsTogether - Channels are handled for + * tighter synchronisation at the expense of individual + * fidelity. In the R3 engine, this means stereo synchronisation + * is maintained more closely for the full frequency range. In + * R2, it means the first two channels are considered to be a + * stereo pair and are processed in mid-side format, with mid + * and side processed as if they were separate channels before + * being recombined. This usually leads to better focus in the + * centre but relatively less stereo space and width and lower + * fidelity for individual channel content. * * Finally, flags prefixed \c OptionStretch are obsolete flags * provided for backward compatibility only. They are ignored by diff --git a/src/finer/Guide.h b/src/finer/Guide.h --- a/src/finer/Guide.h +++ b/src/finer/Guide.h @@ -156,6 +156,7 @@ double meanMagnitude, int unityCount, bool realtime, + bool tighterChannelLock, Guidance &guidance) const { bool hadPhaseReset = guidance.phaseReset.present; @@ -191,7 +192,12 @@ guidance.channelLock.present = true; guidance.channelLock.f0 = 0.0; - guidance.channelLock.f1 = 600.0; + + if (tighterChannelLock) { + guidance.channelLock.f1 = nyquist; + } else { + guidance.channelLock.f1 = 600.0; + } bool kick = (segmentation.percussiveBelow > 40.0) && diff --git a/src/finer/R3Stretcher.cpp b/src/finer/R3Stretcher.cpp --- a/src/finer/R3Stretcher.cpp +++ b/src/finer/R3Stretcher.cpp @@ -968,7 +968,10 @@ } else { m_unityCount = 0; } - + + bool tighterChannelLock = + m_parameters.options & RubberBandStretcher::OptionChannelsTogether; + m_guide.updateGuidance(ratio, prevOuthop, classifyScale->mag.data(), @@ -980,6 +983,7 @@ v_mean(classifyScale->mag.data() + 1, classify/2), m_unityCount, isRealTime(), + tighterChannelLock, cd->guidance); /* if (c == 0) {