Merge pull request #29037 from mdahlgrengadd/master
Make FFT size and oversampling adjustable in smbPitchShifter, add windowing to smbFFT
This commit is contained in:
commit
0eb8484c8a
3 changed files with 64 additions and 5 deletions
|
@ -293,14 +293,16 @@ void AudioEffectPitchShiftInstance::process(const AudioFrame *p_src_frames, Audi
|
|||
float *out_l = (float *)p_dst_frames;
|
||||
float *out_r = out_l + 1;
|
||||
|
||||
shift_l.PitchShift(base->pitch_scale, p_frame_count, 2048, 4, sample_rate, in_l, out_l, 2);
|
||||
shift_r.PitchShift(base->pitch_scale, p_frame_count, 2048, 4, sample_rate, in_r, out_r, 2);
|
||||
shift_l.PitchShift(base->pitch_scale, p_frame_count, fft_size, base->oversampling, sample_rate, in_l, out_l, 2);
|
||||
shift_r.PitchShift(base->pitch_scale, p_frame_count, fft_size, base->oversampling, sample_rate, in_r, out_r, 2);
|
||||
}
|
||||
|
||||
Ref<AudioEffectInstance> AudioEffectPitchShift::instance() {
|
||||
Ref<AudioEffectPitchShiftInstance> ins;
|
||||
ins.instance();
|
||||
ins->base = Ref<AudioEffectPitchShift>(this);
|
||||
static const int fft_sizes[FFT_SIZE_MAX] = { 256, 512, 1024, 2048, 4096 };
|
||||
ins->fft_size = fft_sizes[fft_size];
|
||||
|
||||
return ins;
|
||||
}
|
||||
|
@ -315,14 +317,50 @@ float AudioEffectPitchShift::get_pitch_scale() const {
|
|||
return pitch_scale;
|
||||
}
|
||||
|
||||
void AudioEffectPitchShift::set_oversampling(int p_oversampling) {
|
||||
ERR_FAIL_COND(p_oversampling < 4);
|
||||
oversampling = p_oversampling;
|
||||
}
|
||||
|
||||
int AudioEffectPitchShift::get_oversampling() const {
|
||||
|
||||
return oversampling;
|
||||
}
|
||||
|
||||
void AudioEffectPitchShift::set_fft_size(FFT_Size p_fft_size) {
|
||||
ERR_FAIL_INDEX(p_fft_size, FFT_SIZE_MAX);
|
||||
fft_size = p_fft_size;
|
||||
}
|
||||
|
||||
AudioEffectPitchShift::FFT_Size AudioEffectPitchShift::get_fft_size() const {
|
||||
return fft_size;
|
||||
}
|
||||
|
||||
void AudioEffectPitchShift::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_pitch_scale", "rate"), &AudioEffectPitchShift::set_pitch_scale);
|
||||
ClassDB::bind_method(D_METHOD("get_pitch_scale"), &AudioEffectPitchShift::get_pitch_scale);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_oversampling", "amount"), &AudioEffectPitchShift::set_oversampling);
|
||||
ClassDB::bind_method(D_METHOD("get_oversampling"), &AudioEffectPitchShift::get_oversampling);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_fft_size", "size"), &AudioEffectPitchShift::set_fft_size);
|
||||
ClassDB::bind_method(D_METHOD("get_fft_size"), &AudioEffectPitchShift::get_fft_size);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "pitch_scale", PROPERTY_HINT_RANGE, "0.01,16,0.01"), "set_pitch_scale", "get_pitch_scale");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "oversampling", PROPERTY_HINT_RANGE, "4,32,1"), "set_oversampling", "get_oversampling");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "fft_size", PROPERTY_HINT_ENUM, "256,512,1024,2048,4096"), "set_fft_size", "get_fft_size");
|
||||
|
||||
BIND_ENUM_CONSTANT(FFT_SIZE_256);
|
||||
BIND_ENUM_CONSTANT(FFT_SIZE_512);
|
||||
BIND_ENUM_CONSTANT(FFT_SIZE_1024);
|
||||
BIND_ENUM_CONSTANT(FFT_SIZE_2048);
|
||||
BIND_ENUM_CONSTANT(FFT_SIZE_4096);
|
||||
BIND_ENUM_CONSTANT(FFT_SIZE_MAX);
|
||||
}
|
||||
|
||||
AudioEffectPitchShift::AudioEffectPitchShift() {
|
||||
pitch_scale = 1.0;
|
||||
oversampling = 4;
|
||||
fft_size = FFT_SIZE_2048;
|
||||
}
|
||||
|
|
|
@ -76,6 +76,7 @@ class AudioEffectPitchShiftInstance : public AudioEffectInstance {
|
|||
friend class AudioEffectPitchShift;
|
||||
Ref<AudioEffectPitchShift> base;
|
||||
|
||||
int fft_size;
|
||||
SMBPitchShift shift_l;
|
||||
SMBPitchShift shift_r;
|
||||
|
||||
|
@ -85,11 +86,22 @@ public:
|
|||
|
||||
class AudioEffectPitchShift : public AudioEffect {
|
||||
GDCLASS(AudioEffectPitchShift, AudioEffect)
|
||||
public:
|
||||
enum FFT_Size {
|
||||
FFT_SIZE_256,
|
||||
FFT_SIZE_512,
|
||||
FFT_SIZE_1024,
|
||||
FFT_SIZE_2048,
|
||||
FFT_SIZE_4096,
|
||||
FFT_SIZE_MAX
|
||||
};
|
||||
|
||||
public:
|
||||
friend class AudioEffectPitchShiftInstance;
|
||||
|
||||
float pitch_scale;
|
||||
int window_size;
|
||||
int oversampling;
|
||||
FFT_Size fft_size;
|
||||
float wet;
|
||||
float dry;
|
||||
bool filter;
|
||||
|
@ -103,7 +115,15 @@ public:
|
|||
void set_pitch_scale(float p_pitch_scale);
|
||||
float get_pitch_scale() const;
|
||||
|
||||
void set_oversampling(int p_oversampling);
|
||||
int get_oversampling() const;
|
||||
|
||||
void set_fft_size(FFT_Size);
|
||||
FFT_Size get_fft_size() const;
|
||||
|
||||
AudioEffectPitchShift();
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(AudioEffectPitchShift::FFT_Size);
|
||||
|
||||
#endif // AUDIO_EFFECT_PITCH_SHIFT_H
|
||||
|
|
|
@ -111,9 +111,10 @@ void AudioEffectSpectrumAnalyzerInstance::process(const AudioFrame *p_src_frames
|
|||
|
||||
float *fftw = temporal_fft.ptrw();
|
||||
for (int i = 0; i < to_fill; i++) { //left and right buffers
|
||||
fftw[(i + temporal_fft_pos) * 2] = p_src_frames[i].l;
|
||||
float window = -0.5 * Math::cos(2.0 * Math_PI * (double)i / (double)to_fill) + 0.5;
|
||||
fftw[(i + temporal_fft_pos) * 2] = window * p_src_frames[i].l;
|
||||
fftw[(i + temporal_fft_pos) * 2 + 1] = 0;
|
||||
fftw[(i + temporal_fft_pos + fft_size * 2) * 2] = p_src_frames[i].r;
|
||||
fftw[(i + temporal_fft_pos + fft_size * 2) * 2] = window * p_src_frames[i].r;
|
||||
fftw[(i + temporal_fft_pos + fft_size * 2) * 2 + 1] = 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue