Looper with oversampling and linear interpolation
unknown
c_cpp
5 months ago
3.5 kB
15
Indexable
class Looper { public: Looper() : crossfade_length_(1200), oversample_factor_(8) {} ~Looper() {} void Init(float *mem1, size_t size) { buffer_size_ = size * oversample_factor_; buff_ = mem1; InitBuff(); antialias_filter_.Init(48000); } /** Handles reading/writing to the Buffer depending on the mode. */ float Process(const float input, float speed) { float sig = 0.f; float filteredsig = 0.f; inc = changePitch(speed); antialias_filter_.SetFreq(24000); switch(state_) { case State::PLAYING: switch(mode_) { case Mode::SOS: sig = Read(pos_); antialias_filter_.Process(sig); filteredsig = antialias_filter_.Low(); pos_ += oversample_factor_ * inc; } case State::REC_DUB: switch(mode_) { case Mode::SOS: { sig = Read(pos_); antialias_filter_.Process(sig); filteredsig = antialias_filter_.Low(); for (unsigned int i = 0; i < oversample_factor_; i++) { Write(pos_ + i, input + sig * blend); } pos_ += oversample_factor_ * inc; // Adjust position increment for oversampling } return filteredsig * blend; } float changePitch(float pknob) { static const float speedValues[] = { 0.5f, // -12 semitones 0.529732f, // -11 semitones 0.561231f, // -10 semitones 0.594604f, // -9 semitones 0.629961f, // -8 semitones 0.667420f, // -7 semitones 0.707107f, // -6 semitones 0.749154f, // -5 semitones 0.793701f, // -4 semitones 0.840896f, // -3 semitones 0.890899f, // -2 semitones 0.943874f, // -1 semitone 1.0f, // 0 semitones (unchanged) 1.059463f, // +1 semitone 1.122462f, // +2 semitones 1.189207f, // +3 semitones 1.259921f, // +4 semitones 1.334840f, // +5 semitones 1.414214f, // +6 semitones 1.498307f, // +7 semitones 1.587401f, // +8 semitones 1.681793f, // +9 semitones 1.781797f, // +10 semitones 1.887749f, // +11 semitones 2.0f // +12 semitones }; int index = static_cast<int>(pknob * 24.999); return speedValues[std::min(index, 24)]; } void InitBuff() { std::fill(&buff_[0], &buff_[buffer_size_], 0); } inline float Read(float pos) const { int int_pos = static_cast<int>(pos); float frac = pos - int_pos; float y0 = buff_[int_pos % buffer_size_]; float y1 = buff_[(int_pos + 1) % buffer_size_]; // Perform linear interpolation return y0 + frac * (y1 - y0); } inline void Write(size_t pos, float val) { buff_[pos] = val; } /** Private Member Variables */ Mode mode_; State state_; float *buff_; unsigned int writebuff_; size_t buffer_size_; float pos_, wpos_ float inc; size_t recsize_, playsize_; const int oversample_factor_; Svf antialias_filter_; }; }
Editor is loading...
Leave a Comment