ladspa-pitchshift/pitchshifter.h

138 lines
3.9 KiB
C++

/*
* (Real time) Pitch shifting object implementations
*/
#ifndef MENGA_PITCH_SHIFTER
#define MENGA_PITCH_SHIFTER
#include "correlation.h"
#include "effect.h"
#include "sampling.h"
#include "timestretcher.h"
#include "fft.h"
#include <cstdint>
#include "common.h"
#include "cyclequeue.h"
#include "vecdeque.h"
#include <vector>
namespace Mengu {
namespace dsp {
class PitchShifter: public Effect {
public:
~PitchShifter() {}
virtual InputDomain get_input_domain() override {
return InputDomain::Time;
}
virtual void set_shift_factor(const float &factor) {
_shift_factor = factor;
};
virtual std::vector<EffectPropDesc> get_property_descs() const override;
virtual void set_property(uint32_t id, EffectPropPayload data) override;
virtual EffectPropPayload get_property(uint32_t id) const override;
protected:
float _shift_factor = 1.0f;
};
// Shifter in the frequency domain that uses LPC to estimate formant preservation.
class PhaseVocoderPitchShifterV2: public PitchShifter {
public:
PhaseVocoderPitchShifterV2();
~PhaseVocoderPitchShifterV2();
virtual void push_signal(const Complex *input, const uint32_t &size) override;
virtual uint32_t pop_transformed_signal(Complex *output, const uint32_t &size) override;
virtual uint32_t n_transformed_ready() const override;
virtual void reset() override;
private:
// raw time-domain data
VecDeque<Complex> _raw_buffer;
// time domain data after pitch_shift
VecDeque<Complex> _transformed_buffer;
static constexpr uint32_t ProcSize = 1 << 9;
static constexpr uint32_t OverlapSize = 1 << 6;
LPC<ProcSize, 30> _lpc;
uint32_t _samples_processed;
};
// Shifts by resampling a time stretcher
class TimeStretchPitchShifter: public PitchShifter {
public:
TimeStretchPitchShifter(TimeStretcher *stretcher, uint32_t nchannels);
~TimeStretchPitchShifter();
virtual void push_signal(const Complex *input, const uint32_t &size) override;
virtual uint32_t pop_transformed_signal(Complex *output, const uint32_t &size) override;
virtual uint32_t n_transformed_ready() const override;
virtual void reset() override;
virtual void set_shift_factor(const float &factor) override;
protected:
float _formant_shift = 1.0f;
private:
static constexpr uint32_t MinResampleInputSize = 1 << 10;
// Size of transformed buffer before we increase resampling to compensate for drift
static constexpr uint32_t IncreaseResampleThreshold = 5000;
static constexpr uint32_t StandardResampleThreshold = 3000;
// raw time-domain data
VecDeque<Complex> _raw_buffer;
// time domain data after pitch_shift
VecDeque<Complex> _transformed_buffer;
LinearResampler _resampler;
TimeStretcher *_stretcher;
};
/*
class PTimeStretchPitchShifter: public PitchShifter {
public:
PTimeStretchPitchShifter(uint32_t nchannels);
~PTimeStretchPitchShifter();
virtual void push_signal(const Complex *input, const uint32_t &size) override;
virtual uint32_t pop_transformed_signal(Complex *output, const uint32_t &size) override;
virtual uint32_t n_transformed_ready() override;
virtual void reset() override;
virtual void set_shift_factor(const float &factor) override;
private:
static constexpr uint32_t MinResampleInputSize = 1 << 10;
// Size of transformed buffer before we increase resampling to compensate for drift
static constexpr uint32_t IncreaseResampleThreshold = 10000;
static constexpr uint32_t StandardResampleThreshold = 4000;
// raw time-domain data
VecDeque<Complex> _raw_buffer;
// time domain data after pitch_shift
VecDeque<Complex> _transformed_buffer;
LinearResampler _resampler;
PSOLATimeStretcher _pitch_shifting_stretcher;
};
*/
}; // namespace dsp
}; // namespace Mengu
#endif