Looper with oversampling and linear interpolation
unknown
c_cpp
a year ago
3.5 kB
26
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