summaryrefslogtreecommitdiff
path: root/servers/audio
diff options
context:
space:
mode:
Diffstat (limited to 'servers/audio')
-rw-r--r--servers/audio/audio_driver_dummy.cpp4
-rw-r--r--servers/audio/audio_rb_resampler.cpp14
-rw-r--r--servers/audio/audio_rb_resampler.h57
-rw-r--r--servers/audio/audio_stream.cpp20
-rw-r--r--servers/audio/effects/audio_effect_capture.cpp8
-rw-r--r--servers/audio/effects/audio_effect_capture.h4
-rw-r--r--servers/audio/effects/audio_effect_distortion.cpp3
7 files changed, 58 insertions, 52 deletions
diff --git a/servers/audio/audio_driver_dummy.cpp b/servers/audio/audio_driver_dummy.cpp
index faddced155..a28dcb1015 100644
--- a/servers/audio/audio_driver_dummy.cpp
+++ b/servers/audio/audio_driver_dummy.cpp
@@ -39,11 +39,11 @@ Error AudioDriverDummy::init() {
exit_thread = false;
samples_in = nullptr;
- mix_rate = GLOBAL_GET("audio/mix_rate");
+ mix_rate = GLOBAL_GET("audio/driver/mix_rate");
speaker_mode = SPEAKER_MODE_STEREO;
channels = 2;
- int latency = GLOBAL_GET("audio/output_latency");
+ int latency = GLOBAL_GET("audio/driver/output_latency");
buffer_frames = closest_power_of_2(latency * mix_rate / 1000);
samples_in = memnew_arr(int32_t, buffer_frames * channels);
diff --git a/servers/audio/audio_rb_resampler.cpp b/servers/audio/audio_rb_resampler.cpp
index efdcb916ed..3c8a1469cd 100644
--- a/servers/audio/audio_rb_resampler.cpp
+++ b/servers/audio/audio_rb_resampler.cpp
@@ -131,7 +131,7 @@ bool AudioRBResampler::mix(AudioFrame *p_dest, int p_frames) {
src_read = read_space;
}
- rb_read_pos = (rb_read_pos + src_read) & rb_mask;
+ rb_read_pos.set((rb_read_pos.get() + src_read) & rb_mask);
// Create fadeout effect for the end of stream (note that it can be because of slow writer)
if (p_frames - target_todo > 0) {
@@ -183,8 +183,8 @@ Error AudioRBResampler::setup(int p_channels, int p_src_mix_rate, int p_target_m
src_mix_rate = p_src_mix_rate;
target_mix_rate = p_target_mix_rate;
offset = 0;
- rb_read_pos = 0;
- rb_write_pos = 0;
+ rb_read_pos.set(0);
+ rb_write_pos.set(0);
//avoid maybe strange noises upon load
for (unsigned int i = 0; i < (rb_len * channels); i++) {
@@ -205,8 +205,8 @@ void AudioRBResampler::clear() {
memdelete_arr(read_buf);
rb = nullptr;
offset = 0;
- rb_read_pos = 0;
- rb_write_pos = 0;
+ rb_read_pos.set(0);
+ rb_write_pos.set(0);
read_buf = nullptr;
}
@@ -214,8 +214,8 @@ AudioRBResampler::AudioRBResampler() {
rb = nullptr;
offset = 0;
read_buf = nullptr;
- rb_read_pos = 0;
- rb_write_pos = 0;
+ rb_read_pos.set(0);
+ rb_write_pos.set(0);
rb_bits = 0;
rb_len = 0;
diff --git a/servers/audio/audio_rb_resampler.h b/servers/audio/audio_rb_resampler.h
index 7b74e3a2a1..c0f981704b 100644
--- a/servers/audio/audio_rb_resampler.h
+++ b/servers/audio/audio_rb_resampler.h
@@ -32,6 +32,7 @@
#define AUDIO_RB_RESAMPLER_H
#include "core/os/memory.h"
+#include "core/templates/safe_refcount.h"
#include "core/typedefs.h"
#include "servers/audio_server.h"
@@ -44,8 +45,8 @@ struct AudioRBResampler {
uint32_t src_mix_rate;
uint32_t target_mix_rate;
- volatile int rb_read_pos;
- volatile int rb_write_pos;
+ SafeNumeric<int> rb_read_pos;
+ SafeNumeric<int> rb_write_pos;
int32_t offset; //contains the fractional remainder of the resampler
enum {
@@ -62,8 +63,8 @@ struct AudioRBResampler {
public:
_FORCE_INLINE_ void flush() {
- rb_read_pos = 0;
- rb_write_pos = 0;
+ rb_read_pos.set(0);
+ rb_write_pos.set(0);
offset = 0;
}
@@ -78,8 +79,8 @@ public:
_FORCE_INLINE_ int get_writer_space() const {
int space, r, w;
- r = rb_read_pos;
- w = rb_write_pos;
+ r = rb_read_pos.get();
+ w = rb_write_pos.get();
if (r == w) {
space = rb_len - 1;
@@ -95,8 +96,8 @@ public:
_FORCE_INLINE_ int get_reader_space() const {
int space, r, w;
- r = rb_read_pos;
- w = rb_write_pos;
+ r = rb_read_pos.get();
+ w = rb_write_pos.get();
if (r == w) {
space = 0;
@@ -110,48 +111,52 @@ public:
}
_FORCE_INLINE_ bool has_data() const {
- return rb && rb_read_pos != rb_write_pos;
+ return rb && rb_read_pos.get() != rb_write_pos.get();
}
_FORCE_INLINE_ float *get_write_buffer() { return read_buf; }
_FORCE_INLINE_ void write(uint32_t p_frames) {
ERR_FAIL_COND(p_frames >= rb_len);
+ int wp = rb_write_pos.get();
+
switch (channels) {
case 1: {
for (uint32_t i = 0; i < p_frames; i++) {
- rb[rb_write_pos] = read_buf[i];
- rb_write_pos = (rb_write_pos + 1) & rb_mask;
+ rb[wp] = read_buf[i];
+ wp = (wp + 1) & rb_mask;
}
} break;
case 2: {
for (uint32_t i = 0; i < p_frames; i++) {
- rb[(rb_write_pos << 1) + 0] = read_buf[(i << 1) + 0];
- rb[(rb_write_pos << 1) + 1] = read_buf[(i << 1) + 1];
- rb_write_pos = (rb_write_pos + 1) & rb_mask;
+ rb[(wp << 1) + 0] = read_buf[(i << 1) + 0];
+ rb[(wp << 1) + 1] = read_buf[(i << 1) + 1];
+ wp = (wp + 1) & rb_mask;
}
} break;
case 4: {
for (uint32_t i = 0; i < p_frames; i++) {
- rb[(rb_write_pos << 2) + 0] = read_buf[(i << 2) + 0];
- rb[(rb_write_pos << 2) + 1] = read_buf[(i << 2) + 1];
- rb[(rb_write_pos << 2) + 2] = read_buf[(i << 2) + 2];
- rb[(rb_write_pos << 2) + 3] = read_buf[(i << 2) + 3];
- rb_write_pos = (rb_write_pos + 1) & rb_mask;
+ rb[(wp << 2) + 0] = read_buf[(i << 2) + 0];
+ rb[(wp << 2) + 1] = read_buf[(i << 2) + 1];
+ rb[(wp << 2) + 2] = read_buf[(i << 2) + 2];
+ rb[(wp << 2) + 3] = read_buf[(i << 2) + 3];
+ wp = (wp + 1) & rb_mask;
}
} break;
case 6: {
for (uint32_t i = 0; i < p_frames; i++) {
- rb[(rb_write_pos * 6) + 0] = read_buf[(i * 6) + 0];
- rb[(rb_write_pos * 6) + 1] = read_buf[(i * 6) + 1];
- rb[(rb_write_pos * 6) + 2] = read_buf[(i * 6) + 2];
- rb[(rb_write_pos * 6) + 3] = read_buf[(i * 6) + 3];
- rb[(rb_write_pos * 6) + 4] = read_buf[(i * 6) + 4];
- rb[(rb_write_pos * 6) + 5] = read_buf[(i * 6) + 5];
- rb_write_pos = (rb_write_pos + 1) & rb_mask;
+ rb[(wp * 6) + 0] = read_buf[(i * 6) + 0];
+ rb[(wp * 6) + 1] = read_buf[(i * 6) + 1];
+ rb[(wp * 6) + 2] = read_buf[(i * 6) + 2];
+ rb[(wp * 6) + 3] = read_buf[(i * 6) + 3];
+ rb[(wp * 6) + 4] = read_buf[(i * 6) + 4];
+ rb[(wp * 6) + 5] = read_buf[(i * 6) + 5];
+ wp = (wp + 1) & rb_mask;
}
} break;
}
+
+ rb_write_pos.set(wp);
}
int get_channel_count() const;
diff --git a/servers/audio/audio_stream.cpp b/servers/audio/audio_stream.cpp
index 91fce5d34e..ae07f999ed 100644
--- a/servers/audio/audio_stream.cpp
+++ b/servers/audio/audio_stream.cpp
@@ -54,21 +54,21 @@ void AudioStreamPlaybackResampled::mix(AudioFrame *p_buffer, float p_rate_scale,
for (int i = 0; i < p_frames; i++) {
uint32_t idx = CUBIC_INTERP_HISTORY + uint32_t(mix_offset >> FP_BITS);
- //standard cubic interpolation (great quality/performance ratio)
- //this used to be moved to a LUT for greater performance, but nowadays CPU speed is generally faster than memory.
+ // 4 point, 4th order optimal resampling algorithm from: http://yehar.com/blog/wp-content/uploads/2009/08/deip.pdf
float mu = (mix_offset & FP_MASK) / float(FP_LEN);
AudioFrame y0 = internal_buffer[idx - 3];
AudioFrame y1 = internal_buffer[idx - 2];
AudioFrame y2 = internal_buffer[idx - 1];
AudioFrame y3 = internal_buffer[idx - 0];
- float mu2 = mu * mu;
- AudioFrame a0 = y3 - y2 - y0 + y1;
- AudioFrame a1 = y0 - y1 - a0;
- AudioFrame a2 = y2 - y0;
- AudioFrame a3 = y1;
-
- p_buffer[i] = (a0 * mu * mu2 + a1 * mu2 + a2 * mu + a3);
+ AudioFrame even1 = y2 + y1, odd1 = y2 - y1;
+ AudioFrame even2 = y3 + y0, odd2 = y3 - y0;
+ AudioFrame c0 = even1 * 0.46835497211269561 + even2 * 0.03164502784253309;
+ AudioFrame c1 = odd1 * 0.56001293337091440 + odd2 * 0.14666238593949288;
+ AudioFrame c2 = even1 * -0.250038759826233691 + even2 * 0.25003876124297131;
+ AudioFrame c3 = odd1 * -0.49949850957839148 + odd2 * 0.16649935475113800;
+ AudioFrame c4 = even1 * 0.00016095224137360 + even2 * -0.00016095810460478;
+ p_buffer[i] = (((c4 * mu + c3) * mu + c2) * mu + c1) * mu + c0;
mix_offset += mix_increment;
@@ -184,7 +184,7 @@ void AudioStreamPlaybackMicrophone::start(float p_from_pos) {
return;
}
- if (!GLOBAL_GET("audio/enable_audio_input")) {
+ if (!GLOBAL_GET("audio/driver/enable_input")) {
WARN_PRINT("Need to enable Project settings > Audio > Enable Audio Input option to use capturing.");
return;
}
diff --git a/servers/audio/effects/audio_effect_capture.cpp b/servers/audio/effects/audio_effect_capture.cpp
index f37938eec8..37e4122e50 100644
--- a/servers/audio/effects/audio_effect_capture.cpp
+++ b/servers/audio/effects/audio_effect_capture.cpp
@@ -106,7 +106,7 @@ int AudioEffectCapture::get_frames_available() const {
}
int64_t AudioEffectCapture::get_discarded_frames() const {
- return discarded_frames;
+ return discarded_frames.get();
}
int AudioEffectCapture::get_buffer_length_frames() const {
@@ -115,7 +115,7 @@ int AudioEffectCapture::get_buffer_length_frames() const {
}
int64_t AudioEffectCapture::get_pushed_frames() const {
- return pushed_frames;
+ return pushed_frames.get();
}
void AudioEffectCaptureInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) {
@@ -129,9 +129,9 @@ void AudioEffectCaptureInstance::process(const AudioFrame *p_src_frames, AudioFr
// Add incoming audio frames to the IO ring buffer
int32_t ret = buffer.write(p_src_frames, p_frame_count);
ERR_FAIL_COND_MSG(ret != p_frame_count, "Failed to add data to effect capture ring buffer despite sufficient space.");
- atomic_add(&base->pushed_frames, p_frame_count);
+ base->pushed_frames.add(p_frame_count);
} else {
- atomic_add(&base->discarded_frames, p_frame_count);
+ base->discarded_frames.add(p_frame_count);
}
}
diff --git a/servers/audio/effects/audio_effect_capture.h b/servers/audio/effects/audio_effect_capture.h
index b154be85de..81d4ed6b0f 100644
--- a/servers/audio/effects/audio_effect_capture.h
+++ b/servers/audio/effects/audio_effect_capture.h
@@ -55,8 +55,8 @@ class AudioEffectCapture : public AudioEffect {
friend class AudioEffectCaptureInstance;
RingBuffer<AudioFrame> buffer;
- uint64_t discarded_frames = 0;
- uint64_t pushed_frames = 0;
+ SafeNumeric<uint64_t> discarded_frames;
+ SafeNumeric<uint64_t> pushed_frames;
float buffer_length_seconds = 0.1f;
bool buffer_initialized = false;
diff --git a/servers/audio/effects/audio_effect_distortion.cpp b/servers/audio/effects/audio_effect_distortion.cpp
index b79434e7c2..06d51776a3 100644
--- a/servers/audio/effects/audio_effect_distortion.cpp
+++ b/servers/audio/effects/audio_effect_distortion.cpp
@@ -58,7 +58,8 @@ void AudioEffectDistortionInstance::process(const AudioFrame *p_src_frames, Audi
switch (base->mode) {
case AudioEffectDistortion::MODE_CLIP: {
- a = powf(a, 1.0001 - drive_f);
+ float a_sign = a < 0 ? -1.0f : 1.0f;
+ a = powf(abs(a), 1.0001 - drive_f) * a_sign;
if (a > 1.0) {
a = 1.0;
} else if (a < (-1.0)) {