@@ -14,6 +14,12 @@ static constexpr int P_MIX = 2;
1414// Grain window size in seconds (~23 ms at 48kHz = 1024 samples)
1515static constexpr float GRAIN_WINDOW_SEC = 0 .023f ;
1616
17+ static float wrap_phase (float phase, int buf_size) {
18+ phase = std::fmod (phase, static_cast <float >(buf_size));
19+ if (phase < 0 .0f ) phase += static_cast <float >(buf_size);
20+ return phase;
21+ }
22+
1723PitchShifter::PitchShifter () {
1824 params_ = {
1925 {" Shift" , 0 .0f , -12 .0f , 12 .0f , 0 .0f , " st" ,
@@ -35,9 +41,7 @@ void PitchShifter::set_sample_rate(int sample_rate) {
3541}
3642
3743float PitchShifter::read_linear (float phase) const {
38- // Wrap phase into [0, buf_size_)
39- phase = std::fmod (phase, static_cast <float >(buf_size_));
40- if (phase < 0 .0f ) phase += buf_size_;
44+ phase = wrap_phase (phase, buf_size_);
4145
4246 int pos0 = static_cast <int >(phase);
4347 int pos1 = (pos0 + 1 ) % buf_size_;
@@ -77,11 +81,9 @@ void PitchShifter::process(float* buffer, int num_samples) {
7781 read_phase_a_ += drift;
7882 read_phase_b_ += drift;
7983
80- // Wrap phases into [0, buf_size_)
81- while (read_phase_a_ < 0 .0f ) read_phase_a_ += buf_size_;
82- while (read_phase_a_ >= buf_size_) read_phase_a_ -= buf_size_;
83- while (read_phase_b_ < 0 .0f ) read_phase_b_ += buf_size_;
84- while (read_phase_b_ >= buf_size_) read_phase_b_ -= buf_size_;
84+ // Wrap phases into [0, buf_size_) in constant time.
85+ read_phase_a_ = wrap_phase (read_phase_a_, buf_size_);
86+ read_phase_b_ = wrap_phase (read_phase_b_, buf_size_);
8587
8688 // Compute absolute read positions in the buffer
8789 float pos_a = static_cast <float >(write_pos_) - read_phase_a_;
0 commit comments