feat: updated engine version to 4.4-rc1

This commit is contained in:
Sara 2025-02-23 14:38:14 +01:00
parent ee00efde1f
commit 21ba8e33af
5459 changed files with 1128836 additions and 198305 deletions

View file

@ -1,4 +1,5 @@
#!/usr/bin/env python
from misc.utility.scons_hints import *
Import("env")

View file

@ -30,7 +30,6 @@
#include "audio_driver_dummy.h"
#include "core/config/project_settings.h"
#include "core/os/os.h"
AudioDriverDummy *AudioDriverDummy::singleton = nullptr;
@ -45,7 +44,7 @@ Error AudioDriverDummy::init() {
}
channels = get_channels();
samples_in = memnew_arr(int32_t, (size_t)buffer_frames * channels);
samples_in = memnew_arr(int32_t, size_t(buffer_frames) * channels);
if (use_threads) {
thread.start(AudioDriverDummy::thread_func, this);

View file

@ -61,7 +61,7 @@ class AudioDriverDummy : public AudioDriver {
public:
virtual const char *get_name() const override {
return "Dummy";
};
}
virtual Error init() override;
virtual void start() override;

View file

@ -31,7 +31,7 @@
#include "audio_effect.h"
void AudioEffectInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) {
GDVIRTUAL_REQUIRED_CALL(_process, p_src_frames, p_dst_frames, p_frame_count);
GDVIRTUAL_CALL(_process, p_src_frames, p_dst_frames, p_frame_count);
}
bool AudioEffectInstance::process_silence() const {
bool ret = false;
@ -48,7 +48,7 @@ void AudioEffectInstance::_bind_methods() {
Ref<AudioEffectInstance> AudioEffect::instantiate() {
Ref<AudioEffectInstance> ret;
GDVIRTUAL_REQUIRED_CALL(_instantiate, ret);
GDVIRTUAL_CALL(_instantiate, ret);
return ret;
}
void AudioEffect::_bind_methods() {

View file

@ -40,7 +40,7 @@ class AudioEffectInstance : public RefCounted {
GDCLASS(AudioEffectInstance, RefCounted);
protected:
GDVIRTUAL3(_process, GDExtensionConstPtr<AudioFrame>, GDExtensionPtr<AudioFrame>, int)
GDVIRTUAL3_REQUIRED(_process, GDExtensionConstPtr<AudioFrame>, GDExtensionPtr<AudioFrame>, int)
GDVIRTUAL0RC(bool, _process_silence)
static void _bind_methods();
@ -53,7 +53,7 @@ class AudioEffect : public Resource {
GDCLASS(AudioEffect, Resource);
protected:
GDVIRTUAL0R(Ref<AudioEffectInstance>, _instantiate)
GDVIRTUAL0R_REQUIRED(Ref<AudioEffectInstance>, _instantiate)
static void _bind_methods();
public:

View file

@ -30,6 +30,8 @@
#include "audio_filter_sw.h"
#include "core/math/math_funcs.h"
void AudioFilterSW::set_mode(Mode p_mode) {
mode = p_mode;
}

View file

@ -31,16 +31,16 @@
#ifndef AUDIO_FILTER_SW_H
#define AUDIO_FILTER_SW_H
#include "core/math/math_funcs.h"
#include "core/typedefs.h"
class AudioFilterSW {
public:
struct Coeffs {
float a1 = 0.0f;
float a2 = 0.0f;
float b0 = 0.0f;
float b1 = 0.0f;
float b2 = 0.0f;
double a1 = 0.0;
double a2 = 0.0;
double b0 = 0.0;
double b1 = 0.0;
double b2 = 0.0;
};
enum Mode {

View file

@ -29,9 +29,9 @@
/**************************************************************************/
#include "audio_rb_resampler.h"
#include "core/math/math_funcs.h"
#include "core/os/os.h"
#include "servers/audio_server.h"
#include "core/math/audio_frame.h"
#include "core/os/memory.h"
int AudioRBResampler::get_channel_count() const {
if (!rb) {

View file

@ -31,10 +31,9 @@
#ifndef AUDIO_RB_RESAMPLER_H
#define AUDIO_RB_RESAMPLER_H
#include "core/os/memory.h"
#include "core/math/audio_frame.h"
#include "core/templates/safe_refcount.h"
#include "core/typedefs.h"
#include "servers/audio_server.h"
struct AudioRBResampler {
uint32_t rb_bits;
@ -87,7 +86,7 @@ public:
} else if (w < r) {
space = r - w - 1;
} else {
space = (rb_len - r) + w - 1;
space = (rb_len - w) + (r - 1);
}
return space;

View file

@ -31,7 +31,6 @@
#include "audio_stream.h"
#include "core/config/project_settings.h"
#include "core/os/os.h"
void AudioStreamPlayback::start(double p_from_pos) {
if (GDVIRTUAL_CALL(_start, p_from_pos)) {
@ -72,10 +71,46 @@ void AudioStreamPlayback::seek(double p_time) {
int AudioStreamPlayback::mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) {
int ret = 0;
GDVIRTUAL_REQUIRED_CALL(_mix, p_buffer, p_rate_scale, p_frames, ret);
GDVIRTUAL_CALL(_mix, p_buffer, p_rate_scale, p_frames, ret);
return ret;
}
PackedVector2Array AudioStreamPlayback::_mix_audio_bind(float p_rate_scale, int p_frames) {
Vector<AudioFrame> frames = mix_audio(p_rate_scale, p_frames);
PackedVector2Array res;
res.resize(frames.size());
Vector2 *res_ptrw = res.ptrw();
for (int i = 0; i < frames.size(); i++) {
res_ptrw[i] = Vector2(frames[i].left, frames[i].right);
}
return res;
}
Vector<AudioFrame> AudioStreamPlayback::mix_audio(float p_rate_scale, int p_frames) {
Vector<AudioFrame> res;
res.resize(p_frames);
int frames = mix(res.ptrw(), p_rate_scale, p_frames);
res.resize(frames);
return res;
}
void AudioStreamPlayback::start_playback(double p_from_pos) {
start(p_from_pos);
}
void AudioStreamPlayback::stop_playback() {
stop();
}
void AudioStreamPlayback::seek_playback(double p_time) {
seek(p_time);
}
void AudioStreamPlayback::tag_used_streams() {
GDVIRTUAL_CALL(_tag_used_streams);
}
@ -108,6 +143,13 @@ void AudioStreamPlayback::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_sample_playback", "playback_sample"), &AudioStreamPlayback::set_sample_playback);
ClassDB::bind_method(D_METHOD("get_sample_playback"), &AudioStreamPlayback::get_sample_playback);
ClassDB::bind_method(D_METHOD("mix_audio", "rate_scale", "frames"), &AudioStreamPlayback::_mix_audio_bind);
ClassDB::bind_method(D_METHOD("start", "from_pos"), &AudioStreamPlayback::start_playback, DEFVAL(0.0));
ClassDB::bind_method(D_METHOD("seek", "time"), &AudioStreamPlayback::seek_playback, DEFVAL(0.0));
ClassDB::bind_method(D_METHOD("stop"), &AudioStreamPlayback::stop_playback);
ClassDB::bind_method(D_METHOD("get_loop_count"), &AudioStreamPlayback::get_loop_count);
ClassDB::bind_method(D_METHOD("get_playback_position"), &AudioStreamPlayback::get_playback_position);
ClassDB::bind_method(D_METHOD("is_playing"), &AudioStreamPlayback::is_playing);
}
AudioStreamPlayback::AudioStreamPlayback() {}
@ -132,12 +174,12 @@ void AudioStreamPlaybackResampled::begin_resample() {
int AudioStreamPlaybackResampled::_mix_internal(AudioFrame *p_buffer, int p_frames) {
int ret = 0;
GDVIRTUAL_REQUIRED_CALL(_mix_resampled, p_buffer, p_frames, ret);
GDVIRTUAL_CALL(_mix_resampled, p_buffer, p_frames, ret);
return ret;
}
float AudioStreamPlaybackResampled::get_stream_sampling_rate() {
float ret = 0;
GDVIRTUAL_REQUIRED_CALL(_get_stream_sampling_rate, ret);
GDVIRTUAL_CALL(_get_stream_sampling_rate, ret);
return ret;
}
@ -173,12 +215,12 @@ int AudioStreamPlaybackResampled::mix(AudioFrame *p_buffer, float p_rate_scale,
}
float mu2 = mu * mu;
AudioFrame a0 = 3 * y1 - 3 * y2 + y3 - y0;
AudioFrame a1 = 2 * y0 - 5 * y1 + 4 * y2 - y3;
AudioFrame a2 = y2 - y0;
AudioFrame a3 = 2 * y1;
float h11 = mu2 * (mu - 1);
float z = mu2 - h11;
float h01 = z - h11;
float h10 = mu - z;
p_buffer[i] = (a0 * mu * mu2 + a1 * mu2 + a2 * mu + a3) / 2;
p_buffer[i] = y1 + (y2 - y1) * h01 + ((y2 - y0) * h10 + (y3 - y1) * h11) * 0.5;
mix_offset += mix_increment;
@ -238,7 +280,7 @@ double AudioStream::get_bpm() const {
}
bool AudioStream::has_loop() const {
bool ret = 0;
bool ret = false;
GDVIRTUAL_CALL(_has_loop, ret);
return ret;
}
@ -309,6 +351,8 @@ void AudioStream::_bind_methods() {
GDVIRTUAL_BIND(_get_bpm)
GDVIRTUAL_BIND(_get_beat_count)
GDVIRTUAL_BIND(_get_parameter_list)
GDVIRTUAL_BIND(_has_loop);
GDVIRTUAL_BIND(_get_bar_beats);
ADD_SIGNAL(MethodInfo("parameter_list_changed"));
}
@ -342,18 +386,12 @@ bool AudioStreamMicrophone::is_monophonic() const {
return true;
}
void AudioStreamMicrophone::_bind_methods() {
}
AudioStreamMicrophone::AudioStreamMicrophone() {
}
int AudioStreamPlaybackMicrophone::_mix_internal(AudioFrame *p_buffer, int p_frames) {
AudioDriver::get_singleton()->lock();
Vector<int32_t> buf = AudioDriver::get_singleton()->get_input_buffer();
unsigned int input_size = AudioDriver::get_singleton()->get_input_size();
int mix_rate = AudioDriver::get_singleton()->get_mix_rate();
int mix_rate = AudioDriver::get_singleton()->get_input_mix_rate();
unsigned int playback_delay = MIN(((50 * mix_rate) / 1000) * 2, buf.size() >> 1);
#ifdef DEBUG_ENABLED
unsigned int input_position = AudioDriver::get_singleton()->get_input_position();
@ -404,7 +442,7 @@ int AudioStreamPlaybackMicrophone::mix(AudioFrame *p_buffer, float p_rate_scale,
}
float AudioStreamPlaybackMicrophone::get_stream_sampling_rate() {
return AudioDriver::get_singleton()->get_mix_rate();
return AudioDriver::get_singleton()->get_input_mix_rate();
}
void AudioStreamPlaybackMicrophone::start(double p_from_pos) {

View file

@ -31,10 +31,8 @@
#ifndef AUDIO_STREAM_H
#define AUDIO_STREAM_H
#include "core/io/image.h"
#include "core/io/resource.h"
#include "scene/property_list_helper.h"
#include "servers/audio/audio_filter_sw.h"
#include "servers/audio_server.h"
#include "core/object/gdvirtual.gen.inc"
@ -48,8 +46,10 @@ class AudioSamplePlayback : public RefCounted {
public:
Ref<AudioStream> stream;
Ref<AudioStreamPlayback> stream_playback;
float offset = 0.0f;
float pitch_scale = 1.0;
Vector<AudioFrame> volume_vector;
StringName bus;
};
@ -81,13 +81,14 @@ class AudioStreamPlayback : public RefCounted {
protected:
static void _bind_methods();
PackedVector2Array _mix_audio_bind(float p_rate_scale, int p_frames);
GDVIRTUAL1(_start, double)
GDVIRTUAL0(_stop)
GDVIRTUAL0RC(bool, _is_playing)
GDVIRTUAL0RC(int, _get_loop_count)
GDVIRTUAL0RC(double, _get_playback_position)
GDVIRTUAL1(_seek, double)
GDVIRTUAL3R(int, _mix, GDExtensionPtr<AudioFrame>, float, int)
GDVIRTUAL3R_REQUIRED(int, _mix, GDExtensionPtr<AudioFrame>, float, int)
GDVIRTUAL0(_tag_used_streams)
GDVIRTUAL2(_set_parameter, const StringName &, const Variant &)
GDVIRTUAL1RC(Variant, _get_parameter, const StringName &)
@ -116,6 +117,11 @@ public:
AudioStreamPlayback();
~AudioStreamPlayback();
Vector<AudioFrame> mix_audio(float p_rate_scale, int p_frames);
void start_playback(double p_from_pos = 0.0);
void stop_playback();
void seek_playback(double p_time);
};
class AudioStreamPlaybackResampled : public AudioStreamPlayback {
@ -139,8 +145,8 @@ protected:
virtual int _mix_internal(AudioFrame *p_buffer, int p_frames);
virtual float get_stream_sampling_rate();
GDVIRTUAL2R(int, _mix_resampled, GDExtensionPtr<AudioFrame>, int)
GDVIRTUAL0RC(float, _get_stream_sampling_rate)
GDVIRTUAL2R_REQUIRED(int, _mix_resampled, GDExtensionPtr<AudioFrame>, int)
GDVIRTUAL0RC_REQUIRED(float, _get_stream_sampling_rate)
static void _bind_methods();
@ -219,9 +225,6 @@ class AudioStreamMicrophone : public AudioStream {
HashSet<AudioStreamPlaybackMicrophone *> playbacks;
protected:
static void _bind_methods();
public:
virtual Ref<AudioStreamPlayback> instantiate_playback() override;
virtual String get_stream_name() const override;
@ -229,8 +232,6 @@ public:
virtual double get_length() const override; //if supported, otherwise return 0
virtual bool is_monophonic() const override;
AudioStreamMicrophone();
};
class AudioStreamPlaybackMicrophone : public AudioStreamPlaybackResampled {

View file

@ -1,4 +1,5 @@
#!/usr/bin/env python
from misc.utility.scons_hints import *
Import("env")

View file

@ -60,11 +60,22 @@ float AudioEffectAmplify::get_volume_db() const {
return volume_db;
}
void AudioEffectAmplify::set_volume_linear(float p_volume) {
set_volume_db(Math::linear_to_db(p_volume));
}
float AudioEffectAmplify::get_volume_linear() const {
return Math::db_to_linear(get_volume_db());
}
void AudioEffectAmplify::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_volume_db", "volume"), &AudioEffectAmplify::set_volume_db);
ClassDB::bind_method(D_METHOD("get_volume_db"), &AudioEffectAmplify::get_volume_db);
ClassDB::bind_method(D_METHOD("set_volume_linear", "volume"), &AudioEffectAmplify::set_volume_linear);
ClassDB::bind_method(D_METHOD("get_volume_linear"), &AudioEffectAmplify::get_volume_linear);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volume_db", PROPERTY_HINT_RANGE, "-80,24,0.01,suffix:dB"), "set_volume_db", "get_volume_db");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volume_linear", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_volume_linear", "get_volume_linear");
}
AudioEffectAmplify::AudioEffectAmplify() {

View file

@ -60,6 +60,9 @@ public:
void set_volume_db(float p_volume);
float get_volume_db() const;
void set_volume_linear(float p_volume);
float get_volume_linear() const;
AudioEffectAmplify();
};

View file

@ -30,6 +30,8 @@
#include "audio_effect_capture.h"
#include "servers/audio_server.h"
bool AudioEffectCapture::can_get_buffer(int p_frames) const {
return buffer.data_left() >= p_frames;
}

View file

@ -31,13 +31,10 @@
#ifndef AUDIO_EFFECT_CAPTURE_H
#define AUDIO_EFFECT_CAPTURE_H
#include "core/config/engine.h"
#include "core/math/audio_frame.h"
#include "core/object/ref_counted.h"
#include "core/templates/ring_buffer.h"
#include "core/templates/vector.h"
#include "servers/audio/audio_effect.h"
#include "servers/audio_server.h"
class AudioEffectCapture;

View file

@ -29,7 +29,6 @@
/**************************************************************************/
#include "audio_effect_phaser.h"
#include "core/math/math_funcs.h"
#include "servers/audio_server.h"
void AudioEffectPhaserInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) {

View file

@ -286,6 +286,11 @@ void SMBPitchShift::smbFft(float *fftBuffer, long fftFrameSize, long sign)
/* clang-format on */
void AudioEffectPitchShiftInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) {
// Avoid distortion by skipping processing if pitch_scale is 1.0.
if (Math::is_equal_approx(base->pitch_scale, 1.0f)) {
return;
}
float sample_rate = AudioServer::get_singleton()->get_mix_rate();
float *in_l = (float *)p_src_frames;

View file

@ -77,7 +77,7 @@ class AudioEffectPitchShift : public AudioEffect {
public:
friend class AudioEffectPitchShiftInstance;
enum FFTSize {
enum FFTSize : unsigned int {
FFT_SIZE_256,
FFT_SIZE_512,
FFT_SIZE_1024,

View file

@ -30,10 +30,7 @@
#include "audio_effect_record.h"
#ifdef TOOLS_ENABLED
// FIXME: This file shouldn't depend on editor stuff.
#include "editor/import/resource_importer_wav.h"
#endif
#include "core/io/marshalls.h"
void AudioEffectRecordInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) {
if (!is_recording) {
@ -125,7 +122,7 @@ Ref<AudioEffectInstance> AudioEffectRecord::instantiate() {
ins.instantiate();
ins->is_recording = false;
//Re-using the buffer size calculations from audio_effect_delay.cpp
// Reusing the buffer size calculations from audio_effect_delay.cpp.
float ring_buffer_max_size = IO_BUFFER_SIZE_MS;
ring_buffer_max_size /= 1000.0; //convert to seconds
ring_buffer_max_size *= AudioServer::get_singleton()->get_mix_rate();
@ -149,7 +146,7 @@ Ref<AudioEffectInstance> AudioEffectRecord::instantiate() {
ensure_thread_stopped();
bool is_currently_recording = false;
if (current_instance != nullptr) {
if (current_instance.is_valid()) {
is_currently_recording = current_instance->is_recording;
}
if (is_currently_recording) {
@ -161,28 +158,28 @@ Ref<AudioEffectInstance> AudioEffectRecord::instantiate() {
}
void AudioEffectRecord::ensure_thread_stopped() {
if (current_instance != nullptr) {
if (current_instance.is_valid()) {
current_instance->finish();
}
}
void AudioEffectRecord::set_recording_active(bool p_record) {
if (p_record) {
if (current_instance == nullptr) {
if (current_instance.is_null()) {
WARN_PRINT("Recording should not be set as active before Godot has initialized.");
return;
}
ensure_thread_stopped();
current_instance->init();
} else {
if (current_instance != nullptr) {
if (current_instance.is_valid()) {
current_instance->is_recording = false;
}
}
}
bool AudioEffectRecord::is_recording_active() const {
if (current_instance == nullptr) {
if (current_instance.is_null()) {
return false;
} else {
return current_instance->is_recording;
@ -241,12 +238,8 @@ Ref<AudioStreamWAV> AudioEffectRecord::get_recording() const {
Vector<uint8_t> bleft;
Vector<uint8_t> bright;
#ifdef TOOLS_ENABLED
ResourceImporterWAV::_compress_ima_adpcm(left, bleft);
ResourceImporterWAV::_compress_ima_adpcm(right, bright);
#else
ERR_PRINT("AudioEffectRecord cannot do IMA ADPCM compression at runtime.");
#endif
AudioStreamWAV::_compress_ima_adpcm(left, bleft);
AudioStreamWAV::_compress_ima_adpcm(right, bright);
int dl = bleft.size();
dst_data.resize(dl * 2);
@ -259,6 +252,12 @@ Ref<AudioStreamWAV> AudioEffectRecord::get_recording() const {
w[i * 2 + 0] = rl[i];
w[i * 2 + 1] = rr[i];
}
} else if (dst_format == AudioStreamWAV::FORMAT_QOA) {
qoa_desc desc = {};
desc.samples = current_instance->recording_data.size() / 2;
desc.samplerate = AudioServer::get_singleton()->get_mix_rate();
desc.channels = 2;
AudioStreamWAV::_compress_qoa(current_instance->recording_data, dst_data, &desc);
} else {
ERR_PRINT("Format not implemented.");
}
@ -283,7 +282,7 @@ void AudioEffectRecord::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_format"), &AudioEffectRecord::get_format);
ClassDB::bind_method(D_METHOD("get_recording"), &AudioEffectRecord::get_recording);
ADD_PROPERTY(PropertyInfo(Variant::INT, "format", PROPERTY_HINT_ENUM, "8-Bit,16-Bit,IMA-ADPCM"), "set_format", "get_format");
ADD_PROPERTY(PropertyInfo(Variant::INT, "format", PROPERTY_HINT_ENUM, "8-Bit,16-Bit,IMA ADPCM,Quite OK Audio"), "set_format", "get_format");
}
AudioEffectRecord::AudioEffectRecord() {

View file

@ -31,9 +31,6 @@
#ifndef AUDIO_EFFECT_RECORD_H
#define AUDIO_EFFECT_RECORD_H
#include "core/io/file_access.h"
#include "core/io/marshalls.h"
#include "core/os/os.h"
#include "core/os/thread.h"
#include "scene/resources/audio_stream_wav.h"
#include "servers/audio/audio_effect.h"

View file

@ -145,8 +145,8 @@ void AudioEffectSpectrumAnalyzerInstance::process(const AudioFrame *p_src_frames
}
//determine time of capture
double remainer_sec = (temporal_fft_pos / mix_rate); //subtract remainder from mix time
last_fft_time = time - uint64_t(remainer_sec * 1000000.0);
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() {

View file

@ -39,34 +39,34 @@ void AudioEffectStereoEnhanceInstance::process(const AudioFrame *p_src_frames, A
unsigned int delay_frames = (base->time_pullout / 1000.0) * AudioServer::get_singleton()->get_mix_rate();
for (int i = 0; i < p_frame_count; i++) {
float l = p_src_frames[i].left;
float r = p_src_frames[i].right;
float left = p_src_frames[i].left;
float right = p_src_frames[i].right;
float center = (l + r) / 2.0f;
float center = (left + right) / 2.0f;
l = (center + (l - center) * intensity);
r = (center + (r - center) * intensity);
left = (center + (left - center) * intensity);
right = (center + (right - center) * intensity);
if (surround_mode) {
float val = (l + r) / 2.0;
float val = (left + right) / 2.0;
delay_ringbuff[ringbuff_pos & ringbuff_mask] = val;
float out = delay_ringbuff[(ringbuff_pos - delay_frames) & ringbuff_mask] * surround_amount;
l += out;
r += -out;
left += out;
right += -out;
} else {
float val = r;
float val = right;
delay_ringbuff[ringbuff_pos & ringbuff_mask] = val;
//r is delayed
r = delay_ringbuff[(ringbuff_pos - delay_frames) & ringbuff_mask];
// The right channel is delayed.
right = delay_ringbuff[(ringbuff_pos - delay_frames) & ringbuff_mask];
}
p_dst_frames[i].left = l;
p_dst_frames[i].right = r;
p_dst_frames[i].left = left;
p_dst_frames[i].right = right;
ringbuff_pos++;
}
}

View file

@ -38,6 +38,15 @@ float AudioStreamGenerator::get_mix_rate() const {
return mix_rate;
}
void AudioStreamGenerator::set_mix_rate_mode(AudioStreamGenerator::AudioStreamGeneratorMixRate p_mix_rate_mode) {
ERR_FAIL_INDEX(p_mix_rate_mode, AudioStreamGeneratorMixRate::MIX_RATE_MAX);
mix_rate_mode = p_mix_rate_mode;
}
AudioStreamGenerator::AudioStreamGeneratorMixRate AudioStreamGenerator::get_mix_rate_mode() const {
return mix_rate_mode;
}
void AudioStreamGenerator::set_buffer_length(float p_seconds) {
buffer_len = p_seconds;
}
@ -46,11 +55,22 @@ float AudioStreamGenerator::get_buffer_length() const {
return buffer_len;
}
float AudioStreamGenerator::_get_target_rate() const {
switch (mix_rate_mode) {
case AudioStreamGeneratorMixRate::MIX_RATE_OUTPUT:
return AudioServer::get_singleton()->get_mix_rate();
case AudioStreamGeneratorMixRate::MIX_RATE_INPUT:
return AudioServer::get_singleton()->get_input_mix_rate();
default:
return mix_rate;
}
}
Ref<AudioStreamPlayback> AudioStreamGenerator::instantiate_playback() {
Ref<AudioStreamGeneratorPlayback> playback;
playback.instantiate();
playback->generator = this;
int target_buffer_size = mix_rate * buffer_len;
int target_buffer_size = _get_target_rate() * buffer_len;
playback->buffer.resize(nearest_shift(target_buffer_size));
playback->buffer.clear();
return playback;
@ -72,16 +92,20 @@ void AudioStreamGenerator::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_mix_rate", "hz"), &AudioStreamGenerator::set_mix_rate);
ClassDB::bind_method(D_METHOD("get_mix_rate"), &AudioStreamGenerator::get_mix_rate);
ClassDB::bind_method(D_METHOD("set_mix_rate_mode", "mode"), &AudioStreamGenerator::set_mix_rate_mode);
ClassDB::bind_method(D_METHOD("get_mix_rate_mode"), &AudioStreamGenerator::get_mix_rate_mode);
ClassDB::bind_method(D_METHOD("set_buffer_length", "seconds"), &AudioStreamGenerator::set_buffer_length);
ClassDB::bind_method(D_METHOD("get_buffer_length"), &AudioStreamGenerator::get_buffer_length);
ADD_PROPERTY(PropertyInfo(Variant::INT, "mix_rate_mode", PROPERTY_HINT_ENUM, "System Output Rate,System Input Rate,Custom Rate"), "set_mix_rate_mode", "get_mix_rate_mode");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mix_rate", PROPERTY_HINT_RANGE, "20,192000,1,suffix:Hz"), "set_mix_rate", "get_mix_rate");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "buffer_length", PROPERTY_HINT_RANGE, "0.01,10,0.01,suffix:s"), "set_buffer_length", "get_buffer_length");
}
AudioStreamGenerator::AudioStreamGenerator() {
mix_rate = 44100;
buffer_len = 0.5;
BIND_ENUM_CONSTANT(MIX_RATE_OUTPUT);
BIND_ENUM_CONSTANT(MIX_RATE_INPUT);
BIND_ENUM_CONSTANT(MIX_RATE_CUSTOM);
BIND_ENUM_CONSTANT(MIX_RATE_MAX);
}
////////////////
@ -162,12 +186,12 @@ int AudioStreamGeneratorPlayback::_mix_internal(AudioFrame *p_buffer, int p_fram
skips++;
}
mixed += p_frames / generator->get_mix_rate();
mixed += p_frames / generator->_get_target_rate();
return p_frames;
}
float AudioStreamGeneratorPlayback::get_stream_sampling_rate() {
return generator->get_mix_rate();
return generator->_get_target_rate();
}
void AudioStreamGeneratorPlayback::start(double p_from_pos) {

View file

@ -37,16 +37,31 @@
class AudioStreamGenerator : public AudioStream {
GDCLASS(AudioStreamGenerator, AudioStream);
float mix_rate;
float buffer_len;
public:
enum AudioStreamGeneratorMixRate {
MIX_RATE_OUTPUT,
MIX_RATE_INPUT,
MIX_RATE_CUSTOM,
MIX_RATE_MAX,
};
private:
AudioStreamGeneratorMixRate mix_rate_mode = MIX_RATE_CUSTOM;
float mix_rate = 44100;
float buffer_len = 0.5;
protected:
static void _bind_methods();
public:
float _get_target_rate() const;
void set_mix_rate(float p_mix_rate);
float get_mix_rate() const;
void set_mix_rate_mode(AudioStreamGeneratorMixRate p_mix_rate_mode);
AudioStreamGeneratorMixRate get_mix_rate_mode() const;
void set_buffer_length(float p_seconds);
float get_buffer_length() const;
@ -55,7 +70,7 @@ public:
virtual double get_length() const override;
virtual bool is_monophonic() const override;
AudioStreamGenerator();
AudioStreamGenerator() {}
};
class AudioStreamGeneratorPlayback : public AudioStreamPlaybackResampled {
@ -96,4 +111,6 @@ public:
AudioStreamGeneratorPlayback();
};
VARIANT_ENUM_CAST(AudioStreamGenerator::AudioStreamGeneratorMixRate);
#endif // AUDIO_STREAM_GENERATOR_H

View file

@ -31,7 +31,7 @@
#include "eq_filter.h"
#include "core/error/error_macros.h"
#include "core/math/math_funcs.h"
#include "core/math/math_defs.h"
#include <math.h>

View file

@ -32,7 +32,6 @@
#define EQ_FILTER_H
#include "core/templates/vector.h"
#include "core/typedefs.h"
class EQ {
public:

View file

@ -30,7 +30,8 @@
#include "reverb_filter.h"
#include "core/math/math_funcs.h"
#include "core/math/audio_frame.h"
#include "core/os/memory.h"
#include <math.h>

View file

@ -31,10 +31,6 @@
#ifndef REVERB_FILTER_H
#define REVERB_FILTER_H
#include "core/math/audio_frame.h"
#include "core/os/memory.h"
#include "core/typedefs.h"
class Reverb {
public:
enum {