ladspa-pitchshift/formantshifter.h

75 lines
2.3 KiB
C
Raw Normal View History

2023-10-30 00:52:43 +00:00
/**
* @file formantshifter.h
* @author 9exa
* @brief Shifts the formants of a signal in real time.
* @date 2023-06-08
*/
#ifndef MENGU_FORMANT_SHIFTER
#define MENGU_FORMANT_SHIFTER
#include "common.h"
#include "correlation.h"
#include "effect.h"
#include "loudness.h"
#include "vecdeque.h"
#include <cstdint>
namespace Mengu {
namespace dsp {
// shifts formants using lpc envelope estimation
class LPCFormantShifter: public Effect {
public:
LPCFormantShifter();
// tells an EffectChain what type of input the effect expects
virtual InputDomain get_input_domain() override;
// push new value of signal
virtual void push_signal(const Complex *input, const uint32_t &size) override;
// Last value of transformed signal
virtual uint32_t pop_transformed_signal(Complex *output, const uint32_t &size) override;
// number of samples that can be output given the current pushed signals of the Effect
virtual uint32_t n_transformed_ready() const override;
// resets state of effect to make it reading to take in a new sample
virtual void reset() override;
// The properties that this Effect exposes to be changed by GUI.
// The index that they are put in is considered the props id
virtual std::vector<EffectPropDesc> get_property_descs() const override;
// Sets a property with the specified id the value declared in the payload
virtual void set_property(uint32_t id, EffectPropPayload data) override;
// Gets the value of a property with the specified id
virtual EffectPropPayload get_property(uint32_t id) const override;
private:
VecDeque<Complex> _raw_buffer;
VecDeque<Complex> _transformed_buffer;
static constexpr uint32_t ProcSize = 1 << 11;
static constexpr uint32_t HopSize = ProcSize * 4 / 5;
static constexpr uint32_t OverlapSize = ProcSize - HopSize;
LPC<ProcSize, 60> _lpc;
void _shift_by_env(const Complex *input,
Complex *output,
const float *envelope,
const float shift_factor);
float _shift_factor = 1.0f;
// Amplifies the formant_shifted samples so they have the same LUFS loudness as the raw_sample
LoudnessNormalizer<Complex, ProcSize, 2> _loudness_norm;
LUFSFilter _raw_sample_filter;
LUFSFilter _shifted_sample_filter;
};
}
}
#endif