Explorar el Código

Make FFT size and oversampling adjustable for pitchshifting

Martin Dahlgren hace 6 años
padre
commit
f78c7377c9

+ 40 - 2
servers/audio/effects/audio_effect_pitch_shift.cpp

@@ -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;
 }

+ 21 - 1
servers/audio/effects/audio_effect_pitch_shift.h

@@ -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