mirror of
https://github.com/godotengine/godot.git
synced 2026-02-07 11:21:49 +00:00
Fix spectrum analyzer
This commit is contained in:
@@ -18,8 +18,6 @@
|
||||
<member name="fft_size" type="int" setter="set_fft_size" getter="get_fft_size" enum="AudioEffectSpectrumAnalyzer.FFTSize" default="2">
|
||||
The size of the [url=https://en.wikipedia.org/wiki/Fast_Fourier_transform]Fast Fourier transform[/url] buffer. Higher values smooth out the spectrum analysis over time, but have greater latency. The effects of this higher latency are especially noticeable with sudden amplitude changes.
|
||||
</member>
|
||||
<member name="tap_back_pos" type="float" setter="set_tap_back_pos" getter="get_tap_back_pos" default="0.01">
|
||||
</member>
|
||||
</members>
|
||||
<constants>
|
||||
<constant name="FFT_SIZE_256" value="0" enum="FFTSize">
|
||||
|
||||
8
misc/extension_api_validation/4.6-stable/GH-114355.txt
Normal file
8
misc/extension_api_validation/4.6-stable/GH-114355.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
GH-114355
|
||||
---------
|
||||
Validate extension JSON: API was removed: classes/AudioEffectSpectrumAnalyzer/methods/set_tap_back_pos
|
||||
Validate extension JSON: API was removed: classes/AudioEffectSpectrumAnalyzer/methods/get_tap_back_pos
|
||||
Validate extension JSON: API was removed: classes/AudioEffectSpectrumAnalyzer/properties/tap_back_pos
|
||||
|
||||
Removed this property because it caused buggy behavior for no discernible benefit.
|
||||
Compatibility methods registered.
|
||||
@@ -0,0 +1,47 @@
|
||||
/**************************************************************************/
|
||||
/* audio_effect_spectrum_analyzer.compat.inc */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef DISABLE_DEPRECATED
|
||||
|
||||
void AudioEffectSpectrumAnalyzer::_set_tap_back_pos_bind_compat_114355(float p_seconds) {
|
||||
WARN_PRINT_ONCE("AudioEffectSpectrumAnalyzer.set_tap_back_pos() is deprecated and the value will be discarded.");
|
||||
}
|
||||
|
||||
float AudioEffectSpectrumAnalyzer::_get_tap_back_pos_bind_compat_114355() {
|
||||
WARN_PRINT_ONCE("AudioEffectSpectrumAnalyzer.get_tap_back_pos() is deprecated and will only return the original default value.");
|
||||
return 0.01;
|
||||
}
|
||||
|
||||
void AudioEffectSpectrumAnalyzer::_bind_compatibility_methods() {
|
||||
ClassDB::bind_compatibility_method(D_METHOD("set_tap_back_pos", "seconds"), &AudioEffectSpectrumAnalyzer::_set_tap_back_pos_bind_compat_114355);
|
||||
ClassDB::bind_compatibility_method(D_METHOD("get_tap_back_pos"), &AudioEffectSpectrumAnalyzer::_get_tap_back_pos_bind_compat_114355);
|
||||
}
|
||||
|
||||
#endif // DISABLE_DEPRECATED
|
||||
@@ -29,6 +29,7 @@
|
||||
/**************************************************************************/
|
||||
|
||||
#include "audio_effect_spectrum_analyzer.h"
|
||||
#include "audio_effect_spectrum_analyzer.compat.inc"
|
||||
#include "servers/audio/audio_server.h"
|
||||
|
||||
static void smbFft(float *fftBuffer, long fftFrameSize, long sign)
|
||||
@@ -99,8 +100,6 @@ static void smbFft(float *fftBuffer, long fftFrameSize, long sign)
|
||||
}
|
||||
|
||||
void AudioEffectSpectrumAnalyzerInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) {
|
||||
uint64_t time = OS::get_singleton()->get_ticks_usec();
|
||||
|
||||
//copy everything over first, since this only really does capture
|
||||
for (int i = 0; i < p_frame_count; i++) {
|
||||
p_dst_frames[i] = p_src_frames[i];
|
||||
@@ -143,10 +142,6 @@ void AudioEffectSpectrumAnalyzerInstance::process(const AudioFrame *p_src_frames
|
||||
temporal_fft_pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//determine time of capture
|
||||
double remainder_sec = (temporal_fft_pos / mix_rate); //subtract remainder from mix time
|
||||
last_fft_time = time - uint64_t(remainder_sec * 1000000.0);
|
||||
}
|
||||
|
||||
void AudioEffectSpectrumAnalyzerInstance::_bind_methods() {
|
||||
@@ -156,24 +151,8 @@ void AudioEffectSpectrumAnalyzerInstance::_bind_methods() {
|
||||
}
|
||||
|
||||
Vector2 AudioEffectSpectrumAnalyzerInstance::get_magnitude_for_frequency_range(float p_begin, float p_end, MagnitudeMode p_mode) const {
|
||||
if (last_fft_time == 0) {
|
||||
return Vector2();
|
||||
}
|
||||
uint64_t time = OS::get_singleton()->get_ticks_usec();
|
||||
float diff = double(time - last_fft_time) / 1000000.0 + base->get_tap_back_pos();
|
||||
diff -= AudioServer::get_singleton()->get_output_latency();
|
||||
float fft_time_size = float(fft_size) / mix_rate;
|
||||
|
||||
int fft_index = fft_pos;
|
||||
|
||||
while (diff > fft_time_size) {
|
||||
diff -= fft_time_size;
|
||||
fft_index -= 1;
|
||||
if (fft_index < 0) {
|
||||
fft_index = fft_count - 1;
|
||||
}
|
||||
}
|
||||
|
||||
int begin_pos = p_begin * fft_size / (mix_rate * 0.5);
|
||||
int end_pos = p_end * fft_size / (mix_rate * 0.5);
|
||||
|
||||
@@ -216,7 +195,6 @@ Ref<AudioEffectInstance> AudioEffectSpectrumAnalyzer::instantiate() {
|
||||
ins->mix_rate = AudioServer::get_singleton()->get_mix_rate();
|
||||
ins->fft_count = (buffer_length / (float(ins->fft_size) / ins->mix_rate)) + 1;
|
||||
ins->fft_pos = 0;
|
||||
ins->last_fft_time = 0;
|
||||
ins->fft_history.resize(ins->fft_count);
|
||||
ins->temporal_fft.resize(ins->fft_size * 8); //x2 stereo, x2 amount of samples for freqs, x2 for input
|
||||
ins->temporal_fft_pos = 0;
|
||||
@@ -237,14 +215,6 @@ float AudioEffectSpectrumAnalyzer::get_buffer_length() const {
|
||||
return buffer_length;
|
||||
}
|
||||
|
||||
void AudioEffectSpectrumAnalyzer::set_tap_back_pos(float p_seconds) {
|
||||
tapback_pos = p_seconds;
|
||||
}
|
||||
|
||||
float AudioEffectSpectrumAnalyzer::get_tap_back_pos() const {
|
||||
return tapback_pos;
|
||||
}
|
||||
|
||||
void AudioEffectSpectrumAnalyzer::set_fft_size(FFTSize p_fft_size) {
|
||||
ERR_FAIL_INDEX(p_fft_size, FFT_SIZE_MAX);
|
||||
fft_size = p_fft_size;
|
||||
@@ -258,14 +228,10 @@ void AudioEffectSpectrumAnalyzer::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_buffer_length", "seconds"), &AudioEffectSpectrumAnalyzer::set_buffer_length);
|
||||
ClassDB::bind_method(D_METHOD("get_buffer_length"), &AudioEffectSpectrumAnalyzer::get_buffer_length);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_tap_back_pos", "seconds"), &AudioEffectSpectrumAnalyzer::set_tap_back_pos);
|
||||
ClassDB::bind_method(D_METHOD("get_tap_back_pos"), &AudioEffectSpectrumAnalyzer::get_tap_back_pos);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_fft_size", "size"), &AudioEffectSpectrumAnalyzer::set_fft_size);
|
||||
ClassDB::bind_method(D_METHOD("get_fft_size"), &AudioEffectSpectrumAnalyzer::get_fft_size);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "buffer_length", PROPERTY_HINT_RANGE, "0.1,4,0.1,suffix:s"), "set_buffer_length", "get_buffer_length");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "tap_back_pos", PROPERTY_HINT_RANGE, "0.1,4,0.1"), "set_tap_back_pos", "get_tap_back_pos");
|
||||
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);
|
||||
@@ -278,6 +244,5 @@ void AudioEffectSpectrumAnalyzer::_bind_methods() {
|
||||
|
||||
AudioEffectSpectrumAnalyzer::AudioEffectSpectrumAnalyzer() {
|
||||
buffer_length = 2;
|
||||
tapback_pos = 0.01;
|
||||
fft_size = FFT_SIZE_1024;
|
||||
}
|
||||
|
||||
@@ -54,7 +54,6 @@ private:
|
||||
int fft_count;
|
||||
int fft_pos;
|
||||
float mix_rate;
|
||||
uint64_t last_fft_time;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
@@ -82,18 +81,21 @@ public:
|
||||
public:
|
||||
friend class AudioEffectSpectrumAnalyzerInstance;
|
||||
float buffer_length;
|
||||
float tapback_pos;
|
||||
FFTSize fft_size;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
#ifndef DISABLE_DEPRECATED
|
||||
void _set_tap_back_pos_bind_compat_114355(float p_seconds);
|
||||
float _get_tap_back_pos_bind_compat_114355();
|
||||
static void _bind_compatibility_methods();
|
||||
#endif
|
||||
|
||||
public:
|
||||
Ref<AudioEffectInstance> instantiate() override;
|
||||
void set_buffer_length(float p_seconds);
|
||||
float get_buffer_length() const;
|
||||
void set_tap_back_pos(float p_seconds);
|
||||
float get_tap_back_pos() const;
|
||||
|
||||
void set_fft_size(FFTSize);
|
||||
FFTSize get_fft_size() const;
|
||||
|
||||
Reference in New Issue
Block a user