@@ -53,16 +53,19 @@ namespace {
5353/* To keep from being too intensive with these FFTs, only process up to second
5454 * order (9 channels) and upsample higher orders.
5555 */
56- constexpr auto EffectMaxOrder = 2_uz ;
56+ constexpr auto EffectMaxOrder = 2u ;
5757constexpr auto UpsampleMatrix = std::span{AmbiScale::SecondOrderUp};
5858constexpr auto NumLines = AmbiChannelsFromOrder(EffectMaxOrder);
5959
6060
6161using complex_f = std::complex <float >;
6262
63- constexpr auto StftSize = 1024_uz;
64- constexpr auto StftHalfSize = StftSize >> 1 ;
65- constexpr auto OversampleFactor = 8_uz;
63+ constexpr auto StftSize = 1024u ;
64+ constexpr auto StftHalfSize = StftSize >> 1u ;
65+ constexpr auto OversampleFactor = 8u ;
66+
67+ static_assert (std::popcount(OversampleFactor) == 1 , " Factor must be a power of two" );
68+ constexpr auto OversampleMask = OversampleFactor - 1u ;
6669
6770static_assert (StftSize%OversampleFactor == 0 , " Factor must be a clean divisor of the size" );
6871constexpr auto StftStep = StftSize / OversampleFactor;
@@ -289,7 +292,7 @@ void PshifterState::process(const size_t samplesToDo,
289292 * increments by 1/OversampleFactor for every frequency
290293 * bin. So, the offset wraps every 'OversampleFactor' bin.
291294 */
292- auto const bin_offset = static_cast <float >(k % OversampleFactor );
295+ auto const bin_offset = static_cast <float >(k & OversampleMask );
293296 auto tmp = (phase - mLastPhase [k]) - bin_offset*expected_cycles;
294297 /* Store the actual phase for the next update. */
295298 mLastPhase [k] = phase;
@@ -331,16 +334,28 @@ void PshifterState::process(const size_t samplesToDo,
331334 for (auto k = 0_uz;k < StftHalfSize+1 ;++k)
332335 {
333336 /* Calculate the actual delta phase for this bin's target
334- * frequency bin, and accumulate it to get the actual bin
335- * phase.
337+ * frequency bin. Subtract the bin index and convert the
338+ * bin deviation to phase deviation, accounting for
339+ * oversampling. Also add the expected phase cycle for this
340+ * index, accounting for oversampling.
341+ *
342+ * tmp = (freqbin - k) * pi*2 / oversamplefactor
343+ * tmp += (k&oversamplemask) * expected_cycles
344+ *
345+ * Equivalently:
346+ *
347+ * tmp = (freqbin-k)*expected_cycles + (k&oversamplemask)*expected_cycles
348+ * = (freqbin - k + (k&oversamplemask)) * expected_cycles
349+ * = (freqbin - (k - (k&oversamplemask))) * expected_cycles
350+ * = (freqbin - (k & ~oversamplemask)) * expected_cycles
336351 */
337- auto const bin_offset = static_cast <float >(k%OversampleFactor)
338- - static_cast <float >(k);
339- auto tmp = (mSynthesisBuffer [k].FreqBin +bin_offset) * expected_cycles;
352+ auto const bin_offset = static_cast <float >(k & ~std::size_t {OversampleMask});
353+ auto tmp = (mSynthesisBuffer [k].FreqBin -bin_offset) * expected_cycles;
340354
341- /* Wrap between -pi and +pi for the sum. If mSumPhase is
342- * left to accumulate indefinitely, it will lose precision
343- * and produce less exact phase over time.
355+ /* Accumulate the phase delta to get the actual bin phase,
356+ * and wrap between -pi and +pi for the sum. If mSumPhase
357+ * is left to accumulate indefinitely, it will grow and
358+ * lose precision, producing less exact phase over time.
344359 */
345360 tmp = (tmp+mSumPhase [k]) * std::numbers::inv_pi_v<float >;
346361 auto const qpd = float2int (tmp);
@@ -361,7 +376,7 @@ void PshifterState::process(const size_t samplesToDo,
361376 }
362377 else
363378 {
364- static constexpr auto bin_limit = size_t {
379+ static constexpr auto bin_limit = unsigned {
365380 ((StftHalfSize+1 )<<MixerFracBits)-MixerFracHalf - 1 };
366381 auto const bin_count = size_t {std::min (StftHalfSize+1 ,
367382 bin_limit/mPitchShiftI + 1 )};
0 commit comments