summaryrefslogtreecommitdiff
path: root/servers
diff options
context:
space:
mode:
Diffstat (limited to 'servers')
-rw-r--r--servers/arvr/arvr_interface.cpp2
-rw-r--r--servers/arvr/arvr_interface.h2
-rw-r--r--servers/arvr_server.cpp19
-rw-r--r--servers/arvr_server.h1
-rw-r--r--servers/audio/audio_rb_resampler.cpp210
-rw-r--r--servers/audio/audio_rb_resampler.h49
-rw-r--r--servers/audio_server.cpp2
-rw-r--r--servers/physics_server.cpp1
-rw-r--r--servers/visual/visual_server_viewport.cpp2
9 files changed, 135 insertions, 153 deletions
diff --git a/servers/arvr/arvr_interface.cpp b/servers/arvr/arvr_interface.cpp
index 55707def7c..458459a843 100644
--- a/servers/arvr/arvr_interface.cpp
+++ b/servers/arvr/arvr_interface.cpp
@@ -43,7 +43,7 @@ void ARVRInterface::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_tracking_status"), &ARVRInterface::get_tracking_status);
- ClassDB::bind_method(D_METHOD("get_recommended_render_targetsize"), &ARVRInterface::get_recommended_render_targetsize);
+ ClassDB::bind_method(D_METHOD("get_render_targetsize"), &ARVRInterface::get_render_targetsize);
ClassDB::bind_method(D_METHOD("is_stereo"), &ARVRInterface::is_stereo);
ADD_GROUP("Interface", "interface_");
diff --git a/servers/arvr/arvr_interface.h b/servers/arvr/arvr_interface.h
index 880f6e4595..1599c1a64f 100644
--- a/servers/arvr/arvr_interface.h
+++ b/servers/arvr/arvr_interface.h
@@ -103,7 +103,7 @@ public:
/** rendering and internal **/
- virtual Size2 get_recommended_render_targetsize() = 0; /* returns the recommended render target size per eye for this device */
+ virtual Size2 get_render_targetsize() = 0; /* returns the recommended render target size per eye for this device */
virtual bool is_stereo() = 0; /* returns true if this interface requires stereo rendering (for VR HMDs) or mono rendering (for mobile AR) */
virtual Transform get_transform_for_eye(ARVRInterface::Eyes p_eye, const Transform &p_cam_transform) = 0; /* get each eyes camera transform, also implement EYE_MONO */
virtual CameraMatrix get_projection_for_eye(ARVRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) = 0; /* get each eyes projection matrix */
diff --git a/servers/arvr_server.cpp b/servers/arvr_server.cpp
index ede080b424..1e73d6753c 100644
--- a/servers/arvr_server.cpp
+++ b/servers/arvr_server.cpp
@@ -49,15 +49,13 @@ void ARVRServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_interface_count"), &ARVRServer::get_interface_count);
ClassDB::bind_method(D_METHOD("get_interface", "idx"), &ARVRServer::get_interface);
+ ClassDB::bind_method(D_METHOD("get_interfaces"), &ARVRServer::get_interfaces);
ClassDB::bind_method(D_METHOD("find_interface", "name"), &ARVRServer::find_interface);
ClassDB::bind_method(D_METHOD("get_tracker_count"), &ARVRServer::get_tracker_count);
ClassDB::bind_method(D_METHOD("get_tracker", "idx"), &ARVRServer::get_tracker);
ClassDB::bind_method(D_METHOD("set_primary_interface", "interface"), &ARVRServer::set_primary_interface);
- ClassDB::bind_method(D_METHOD("add_interface", "interface"), &ARVRServer::add_interface);
- ClassDB::bind_method(D_METHOD("remove_interface", "interface"), &ARVRServer::remove_interface);
-
BIND_ENUM_CONSTANT(TRACKER_CONTROLLER);
BIND_ENUM_CONSTANT(TRACKER_BASESTATION);
BIND_ENUM_CONSTANT(TRACKER_ANCHOR);
@@ -191,6 +189,21 @@ Ref<ARVRInterface> ARVRServer::find_interface(const String &p_name) const {
return interfaces[idx];
};
+Array ARVRServer::get_interfaces() const {
+ Array ret;
+
+ for (int i = 0; i < interfaces.size(); i++) {
+ Dictionary iface_info;
+
+ iface_info["id"] = i;
+ iface_info["name"] = interfaces[i]->get_name();
+
+ ret.push_back(iface_info);
+ };
+
+ return ret;
+};
+
/*
A little extra info on the tracker ids, these are unique per tracker type so we get soem consistency in recognising our trackers, specifically controllers.
diff --git a/servers/arvr_server.h b/servers/arvr_server.h
index 948895cb27..9b84ee2e99 100644
--- a/servers/arvr_server.h
+++ b/servers/arvr_server.h
@@ -137,6 +137,7 @@ public:
int get_interface_count() const;
Ref<ARVRInterface> get_interface(int p_index) const;
Ref<ARVRInterface> find_interface(const String &p_name) const;
+ Array get_interfaces() const;
/*
note, more then one interface can technically be active, especially on mobile, but only one interface is used for
diff --git a/servers/audio/audio_rb_resampler.cpp b/servers/audio/audio_rb_resampler.cpp
index 113e356612..b0b94a1f49 100644
--- a/servers/audio/audio_rb_resampler.cpp
+++ b/servers/audio/audio_rb_resampler.cpp
@@ -28,6 +28,9 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "audio_rb_resampler.h"
+#include "core/math/math_funcs.h"
+#include "os/os.h"
+#include "servers/audio_server.h"
int AudioRBResampler::get_channel_count() const {
@@ -37,8 +40,11 @@ int AudioRBResampler::get_channel_count() const {
return channels;
}
+// Linear interpolation based sample rate convertion (low quality)
+// Note that AudioStreamPlaybackResampled::mix has better algorithm,
+// but it wasn't obvious to integrate that with VideoPlayer
template <int C>
-uint32_t AudioRBResampler::_resample(int32_t *p_dest, int p_todo, int32_t p_increment) {
+uint32_t AudioRBResampler::_resample(AudioFrame *p_dest, int p_todo, int32_t p_increment) {
uint32_t read = offset & MIX_FRAC_MASK;
@@ -47,186 +53,128 @@ uint32_t AudioRBResampler::_resample(int32_t *p_dest, int p_todo, int32_t p_incr
offset = (offset + p_increment) & (((1 << (rb_bits + MIX_FRAC_BITS)) - 1));
read += p_increment;
uint32_t pos = offset >> MIX_FRAC_BITS;
- uint32_t frac = offset & MIX_FRAC_MASK;
-#ifndef FAST_AUDIO
+ float frac = float(offset & MIX_FRAC_MASK) / float(MIX_FRAC_LEN);
ERR_FAIL_COND_V(pos >= rb_len, 0);
-#endif
uint32_t pos_next = (pos + 1) & rb_mask;
- //printf("rb pos %i\n",pos);
// since this is a template with a known compile time value (C), conditionals go away when compiling.
if (C == 1) {
- int32_t v0 = rb[pos];
- int32_t v0n = rb[pos_next];
-#ifndef FAST_AUDIO
- v0 += (v0n - v0) * (int32_t)frac >> MIX_FRAC_BITS;
-#endif
- v0 <<= 16;
- p_dest[i] = v0;
+ float v0 = rb[pos];
+ float v0n = rb[pos_next];
+ v0 += (v0n - v0) * frac;
+ p_dest[i] = AudioFrame(v0, v0);
}
+
if (C == 2) {
- int32_t v0 = rb[(pos << 1) + 0];
- int32_t v1 = rb[(pos << 1) + 1];
- int32_t v0n = rb[(pos_next << 1) + 0];
- int32_t v1n = rb[(pos_next << 1) + 1];
-
-#ifndef FAST_AUDIO
- v0 += (v0n - v0) * (int32_t)frac >> MIX_FRAC_BITS;
- v1 += (v1n - v1) * (int32_t)frac >> MIX_FRAC_BITS;
-#endif
- v0 <<= 16;
- v1 <<= 16;
- p_dest[(i << 1) + 0] = v0;
- p_dest[(i << 1) + 1] = v1;
+ float v0 = rb[(pos << 1) + 0];
+ float v1 = rb[(pos << 1) + 1];
+ float v0n = rb[(pos_next << 1) + 0];
+ float v1n = rb[(pos_next << 1) + 1];
+
+ v0 += (v0n - v0) * frac;
+ v1 += (v1n - v1) * frac;
+ p_dest[i] = AudioFrame(v0, v1);
}
+ // For now, channels higher than stereo are almost ignored
if (C == 4) {
- int32_t v0 = rb[(pos << 2) + 0];
- int32_t v1 = rb[(pos << 2) + 1];
- int32_t v2 = rb[(pos << 2) + 2];
- int32_t v3 = rb[(pos << 2) + 3];
- int32_t v0n = rb[(pos_next << 2) + 0];
- int32_t v1n = rb[(pos_next << 2) + 1];
- int32_t v2n = rb[(pos_next << 2) + 2];
- int32_t v3n = rb[(pos_next << 2) + 3];
-
-#ifndef FAST_AUDIO
- v0 += (v0n - v0) * (int32_t)frac >> MIX_FRAC_BITS;
- v1 += (v1n - v1) * (int32_t)frac >> MIX_FRAC_BITS;
- v2 += (v2n - v2) * (int32_t)frac >> MIX_FRAC_BITS;
- v3 += (v3n - v3) * (int32_t)frac >> MIX_FRAC_BITS;
-#endif
- v0 <<= 16;
- v1 <<= 16;
- v2 <<= 16;
- v3 <<= 16;
- p_dest[(i << 2) + 0] = v0;
- p_dest[(i << 2) + 1] = v1;
- p_dest[(i << 2) + 2] = v2;
- p_dest[(i << 2) + 3] = v3;
+ float v0 = rb[(pos << 2) + 0];
+ float v1 = rb[(pos << 2) + 1];
+ float v2 = rb[(pos << 2) + 2];
+ float v3 = rb[(pos << 2) + 3];
+ float v0n = rb[(pos_next << 2) + 0];
+ float v1n = rb[(pos_next << 2) + 1];
+ float v2n = rb[(pos_next << 2) + 2];
+ float v3n = rb[(pos_next << 2) + 3];
+
+ v0 += (v0n - v0) * frac;
+ v1 += (v1n - v1) * frac;
+ v2 += (v2n - v2) * frac;
+ v3 += (v3n - v3) * frac;
+ p_dest[i] = AudioFrame(v0, v1);
}
if (C == 6) {
- int32_t v0 = rb[(pos * 6) + 0];
- int32_t v1 = rb[(pos * 6) + 1];
- int32_t v2 = rb[(pos * 6) + 2];
- int32_t v3 = rb[(pos * 6) + 3];
- int32_t v4 = rb[(pos * 6) + 4];
- int32_t v5 = rb[(pos * 6) + 5];
- int32_t v0n = rb[(pos_next * 6) + 0];
- int32_t v1n = rb[(pos_next * 6) + 1];
- int32_t v2n = rb[(pos_next * 6) + 2];
- int32_t v3n = rb[(pos_next * 6) + 3];
- int32_t v4n = rb[(pos_next * 6) + 4];
- int32_t v5n = rb[(pos_next * 6) + 5];
-
-#ifndef FAST_AUDIO
- v0 += (v0n - v0) * (int32_t)frac >> MIX_FRAC_BITS;
- v1 += (v1n - v1) * (int32_t)frac >> MIX_FRAC_BITS;
- v2 += (v2n - v2) * (int32_t)frac >> MIX_FRAC_BITS;
- v3 += (v3n - v3) * (int32_t)frac >> MIX_FRAC_BITS;
- v4 += (v4n - v4) * (int32_t)frac >> MIX_FRAC_BITS;
- v5 += (v5n - v5) * (int32_t)frac >> MIX_FRAC_BITS;
-#endif
- v0 <<= 16;
- v1 <<= 16;
- v2 <<= 16;
- v3 <<= 16;
- v4 <<= 16;
- v5 <<= 16;
- p_dest[(i * 6) + 0] = v0;
- p_dest[(i * 6) + 1] = v1;
- p_dest[(i * 6) + 2] = v2;
- p_dest[(i * 6) + 3] = v3;
- p_dest[(i * 6) + 4] = v4;
- p_dest[(i * 6) + 5] = v5;
+ float v0 = rb[(pos * 6) + 0];
+ float v1 = rb[(pos * 6) + 1];
+ float v2 = rb[(pos * 6) + 2];
+ float v3 = rb[(pos * 6) + 3];
+ float v4 = rb[(pos * 6) + 4];
+ float v5 = rb[(pos * 6) + 5];
+ float v0n = rb[(pos_next * 6) + 0];
+ float v1n = rb[(pos_next * 6) + 1];
+ float v2n = rb[(pos_next * 6) + 2];
+ float v3n = rb[(pos_next * 6) + 3];
+ float v4n = rb[(pos_next * 6) + 4];
+ float v5n = rb[(pos_next * 6) + 5];
+
+ p_dest[i] = AudioFrame(v0, v1);
}
}
- return read >> MIX_FRAC_BITS; //rb_read_pos=offset>>MIX_FRAC_BITS;
+ return read >> MIX_FRAC_BITS; //rb_read_pos = offset >> MIX_FRAC_BITS;
}
-bool AudioRBResampler::mix(int32_t *p_dest, int p_frames) {
+bool AudioRBResampler::mix(AudioFrame *p_dest, int p_frames) {
if (!rb)
return false;
- int write_pos_cache = rb_write_pos;
-
int32_t increment = (src_mix_rate * MIX_FRAC_LEN) / target_mix_rate;
-
- int rb_todo;
-
- if (write_pos_cache == rb_read_pos) {
- return false; //out of buffer
-
- } else if (rb_read_pos < write_pos_cache) {
-
- rb_todo = write_pos_cache - rb_read_pos; //-1?
- } else {
-
- rb_todo = (rb_len - rb_read_pos) + write_pos_cache; //-1?
- }
-
- int todo = MIN(((int64_t(rb_todo) << MIX_FRAC_BITS) / increment) + 1, p_frames);
+ int read_space = get_reader_space();
+ int target_todo = MIN(get_num_of_ready_frames(), p_frames);
{
-
- int read = 0;
+ int src_read = 0;
switch (channels) {
- case 1: read = _resample<1>(p_dest, todo, increment); break;
- case 2: read = _resample<2>(p_dest, todo, increment); break;
- case 4: read = _resample<4>(p_dest, todo, increment); break;
- case 6: read = _resample<6>(p_dest, todo, increment); break;
+ case 1: src_read = _resample<1>(p_dest, target_todo, increment); break;
+ case 2: src_read = _resample<2>(p_dest, target_todo, increment); break;
+ case 4: src_read = _resample<4>(p_dest, target_todo, increment); break;
+ case 6: src_read = _resample<6>(p_dest, target_todo, increment); break;
}
- //end of stream, fadeout
- int remaining = p_frames - todo;
- if (remaining && todo > 0) {
-
- //print_line("fadeout");
- for (uint32_t c = 0; c < channels; c++) {
+ if (src_read > read_space)
+ src_read = read_space;
- for (int i = 0; i < todo; i++) {
+ rb_read_pos = (rb_read_pos + src_read) & rb_mask;
- int32_t samp = p_dest[i * channels + c] >> 8;
- uint32_t mul = (todo - i) * 256 / todo;
- //print_line("mul: "+itos(i)+" "+itos(mul));
- p_dest[i * channels + c] = samp * mul;
- }
+ // Create fadeout effect for the end of stream (note that it can be because of slow writer)
+ if (p_frames - target_todo > 0) {
+ for (int i = 0; i < target_todo; i++) {
+ p_dest[i] = p_dest[i] * float(target_todo - i) / float(target_todo);
}
}
- //zero out what remains there to avoid glitches
- for (uint32_t i = todo * channels; i < int(p_frames) * channels; i++) {
-
- p_dest[i] = 0;
+ // Fill zeros (silence) for the rest of frames
+ for (uint32_t i = target_todo; i < p_frames; i++) {
+ p_dest[i] = AudioFrame(0, 0);
}
-
- if (read > rb_todo)
- read = rb_todo;
-
- rb_read_pos = (rb_read_pos + read) & rb_mask;
}
return true;
}
+int AudioRBResampler::get_num_of_ready_frames() {
+ if (!is_ready())
+ return 0;
+ int32_t increment = (src_mix_rate * MIX_FRAC_LEN) / target_mix_rate;
+ int read_space = get_reader_space();
+ return (int64_t(read_space) << MIX_FRAC_BITS) / increment;
+}
+
Error AudioRBResampler::setup(int p_channels, int p_src_mix_rate, int p_target_mix_rate, int p_buffer_msec, int p_minbuff_needed) {
ERR_FAIL_COND_V(p_channels != 1 && p_channels != 2 && p_channels != 4 && p_channels != 6, ERR_INVALID_PARAMETER);
- //float buffering_sec = int(GLOBAL_DEF("audio/stream_buffering_ms",500))/1000.0;
int desired_rb_bits = nearest_shift(MAX((p_buffer_msec / 1000.0) * p_src_mix_rate, p_minbuff_needed));
bool recreate = !rb;
if (rb && (uint32_t(desired_rb_bits) != rb_bits || channels != uint32_t(p_channels))) {
- //recreate
memdelete_arr(rb);
memdelete_arr(read_buf);
@@ -239,8 +187,8 @@ Error AudioRBResampler::setup(int p_channels, int p_src_mix_rate, int p_target_m
rb_bits = desired_rb_bits;
rb_len = (1 << rb_bits);
rb_mask = rb_len - 1;
- rb = memnew_arr(int16_t, rb_len * p_channels);
- read_buf = memnew_arr(int16_t, rb_len * p_channels);
+ rb = memnew_arr(float, rb_len *p_channels);
+ read_buf = memnew_arr(float, rb_len *p_channels);
}
src_mix_rate = p_src_mix_rate;
diff --git a/servers/audio/audio_rb_resampler.h b/servers/audio/audio_rb_resampler.h
index bc1f924ab5..08c7a5a668 100644
--- a/servers/audio/audio_rb_resampler.h
+++ b/servers/audio/audio_rb_resampler.h
@@ -31,6 +31,7 @@
#define AUDIO_RB_RESAMPLER_H
#include "os/memory.h"
+#include "servers/audio_server.h"
#include "typedefs.h"
struct AudioRBResampler {
@@ -53,11 +54,11 @@ struct AudioRBResampler {
MIX_FRAC_MASK = MIX_FRAC_LEN - 1,
};
- int16_t *read_buf;
- int16_t *rb;
+ float *read_buf;
+ float *rb;
template <int C>
- uint32_t _resample(int32_t *p_dest, int p_todo, int32_t p_increment);
+ uint32_t _resample(AudioFrame *p_dest, int p_todo, int32_t p_increment);
public:
_FORCE_INLINE_ void flush() {
@@ -71,33 +72,48 @@ public:
}
_FORCE_INLINE_ int get_total() const {
-
return rb_len - 1;
}
- _FORCE_INLINE_ int get_todo() const { //return amount of frames to mix
-
- int todo;
- int read_pos_cache = rb_read_pos;
+ _FORCE_INLINE_ int get_writer_space() const {
+ int space, r, w;
- if (read_pos_cache == rb_write_pos) {
- todo = rb_len - 1;
- } else if (read_pos_cache > rb_write_pos) {
+ r = rb_read_pos;
+ w = rb_write_pos;
- todo = read_pos_cache - rb_write_pos - 1;
+ if (r == w) {
+ space = rb_len - 1;
+ } else if (w < r) {
+ space = r - w - 1;
} else {
+ space = (rb_len - r) + w - 1;
+ }
+
+ return space;
+ }
+
+ _FORCE_INLINE_ int get_reader_space() const {
+ int space, r, w;
- todo = (rb_len - rb_write_pos) + read_pos_cache - 1;
+ r = rb_read_pos;
+ w = rb_write_pos;
+
+ if (r == w) {
+ space = 0;
+ } else if (w < r) {
+ space = rb_len - r + w;
+ } else {
+ space = w - r;
}
- return todo;
+ return space;
}
_FORCE_INLINE_ bool has_data() const {
return rb && rb_read_pos != rb_write_pos;
}
- _FORCE_INLINE_ int16_t *get_write_buffer() { return read_buf; }
+ _FORCE_INLINE_ float *get_write_buffer() { return read_buf; }
_FORCE_INLINE_ void write(uint32_t p_frames) {
ERR_FAIL_COND(p_frames >= rb_len);
@@ -151,7 +167,8 @@ public:
Error setup(int p_channels, int p_src_mix_rate, int p_target_mix_rate, int p_buffer_msec, int p_minbuff_needed = -1);
void clear();
- bool mix(int32_t *p_dest, int p_frames);
+ bool mix(AudioFrame *p_dest, int p_frames);
+ int get_num_of_ready_frames();
AudioRBResampler();
~AudioRBResampler();
diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp
index 697abead68..6a10d7539d 100644
--- a/servers/audio_server.cpp
+++ b/servers/audio_server.cpp
@@ -876,6 +876,8 @@ void AudioServer::init() {
#ifdef TOOLS_ENABLED
set_edited(false); //avoid editors from thinking this was edited
#endif
+
+ GLOBAL_DEF("audio/video_delay_compensation_ms", 0);
}
void AudioServer::load_default_bus_layout() {
diff --git a/servers/physics_server.cpp b/servers/physics_server.cpp
index 76fb5bc46b..88cd728a94 100644
--- a/servers/physics_server.cpp
+++ b/servers/physics_server.cpp
@@ -678,6 +678,7 @@ void PhysicsServer::_bind_methods() {
BIND_ENUM_CONSTANT(BODY_MODE_STATIC);
BIND_ENUM_CONSTANT(BODY_MODE_KINEMATIC);
BIND_ENUM_CONSTANT(BODY_MODE_RIGID);
+ BIND_ENUM_CONSTANT(BODY_MODE_SOFT);
BIND_ENUM_CONSTANT(BODY_MODE_CHARACTER);
BIND_ENUM_CONSTANT(BODY_PARAM_BOUNCE);
diff --git a/servers/visual/visual_server_viewport.cpp b/servers/visual/visual_server_viewport.cpp
index 92c431e393..fbf593f5b9 100644
--- a/servers/visual/visual_server_viewport.cpp
+++ b/servers/visual/visual_server_viewport.cpp
@@ -268,7 +268,7 @@ void VisualServerViewport::draw_viewports() {
if (vp->use_arvr && arvr_interface.is_valid()) {
// override our size, make sure it matches our required size
- Size2 size = arvr_interface->get_recommended_render_targetsize();
+ Size2 size = arvr_interface->get_render_targetsize();
VSG::storage->render_target_set_size(vp->render_target, size.x, size.y);
// render mono or left eye first