Skip to content

Commit f81aa49

Browse files
Change playback position type from float to double
Two reasons to change this: * At a default mix rate of 44100, the playback position in seconds can experience rounding errors with a 32-bit type if the value is high enough. 44100 requires 15 free bits in the mantissa to be within 1/2 an audio frame, so the cutoff is 512 seconds before rounding issues occur (512=2^9, and 9+15 > 23 mantissa bits in 32-bit float). * Internally, AudioStreamPlayback and AudioStream use a 64-bit type for playback position. See this discussion: #105510 (comment)
1 parent f1e6dc6 commit f81aa49

10 files changed

+87
-18
lines changed

misc/extension_api_validation/4.4-stable.expected

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,18 @@ Validate extension JSON: Error: Field 'classes/TextServerExtension/methods/_shap
8282
Validate extension JSON: Error: Field 'classes/TextServerExtension/methods/_shaped_text_draw_outline/arguments': size changed value in new API, from 7 to 8.
8383

8484
Optional "oversmpling" argument added. Compatibility methods registered.
85+
86+
87+
GH-105545
88+
---------
89+
Validate extension JSON: Error: Field 'classes/AudioStreamPlayer/methods/get_playback_position/return_value': meta changed value in new API, from "float" to "double".
90+
Validate extension JSON: Error: Field 'classes/AudioStreamPlayer/methods/play/arguments/0': meta changed value in new API, from "float" to "double".
91+
Validate extension JSON: Error: Field 'classes/AudioStreamPlayer/methods/seek/arguments/0': meta changed value in new API, from "float" to "double".
92+
Validate extension JSON: Error: Field 'classes/AudioStreamPlayer2D/methods/get_playback_position/return_value': meta changed value in new API, from "float" to "double".
93+
Validate extension JSON: Error: Field 'classes/AudioStreamPlayer2D/methods/play/arguments/0': meta changed value in new API, from "float" to "double".
94+
Validate extension JSON: Error: Field 'classes/AudioStreamPlayer2D/methods/seek/arguments/0': meta changed value in new API, from "float" to "double".
95+
Validate extension JSON: Error: Field 'classes/AudioStreamPlayer3D/methods/get_playback_position/return_value': meta changed value in new API, from "float" to "double".
96+
Validate extension JSON: Error: Field 'classes/AudioStreamPlayer3D/methods/play/arguments/0': meta changed value in new API, from "float" to "double".
97+
Validate extension JSON: Error: Field 'classes/AudioStreamPlayer3D/methods/seek/arguments/0': meta changed value in new API, from "float" to "double".
98+
99+
Playback position return/param type changed from float to double for higher precision. Compatibility methods registered.

scene/2d/audio_stream_player_2d.compat.inc

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,23 @@ bool AudioStreamPlayer2D::_is_autoplay_enabled_bind_compat_86907() {
3434
return is_autoplay_enabled();
3535
}
3636

37+
void AudioStreamPlayer2D::_play_bind_compat_105545(float p_from_pos) {
38+
play(p_from_pos);
39+
}
40+
41+
void AudioStreamPlayer2D::_seek_bind_compat_105545(float p_seconds) {
42+
seek(p_seconds);
43+
}
44+
45+
float AudioStreamPlayer2D::_get_playback_position_bind_compat_105545() {
46+
return get_playback_position();
47+
}
48+
3749
void AudioStreamPlayer2D::_bind_compatibility_methods() {
3850
ClassDB::bind_compatibility_method(D_METHOD("is_autoplay_enabled"), &AudioStreamPlayer2D::_is_autoplay_enabled_bind_compat_86907);
51+
ClassDB::bind_compatibility_method(D_METHOD("play", "from_position"), &AudioStreamPlayer2D::_play_bind_compat_105545, DEFVAL(0.0));
52+
ClassDB::bind_compatibility_method(D_METHOD("seek", "to_position"), &AudioStreamPlayer2D::_seek_bind_compat_105545);
53+
ClassDB::bind_compatibility_method(D_METHOD("get_playback_position"), &AudioStreamPlayer2D::_get_playback_position_bind_compat_105545);
3954
}
4055

4156
#endif // DISABLE_DEPRECATED

scene/2d/audio_stream_player_2d.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ void AudioStreamPlayer2D::_play_internal(double p_from_pos) {
253253
}
254254
}
255255

256-
void AudioStreamPlayer2D::play(float p_from_pos) {
256+
void AudioStreamPlayer2D::play(double p_from_pos) {
257257
internal->scheduled_time = 0;
258258
_play_internal(p_from_pos);
259259
}
@@ -263,7 +263,7 @@ void AudioStreamPlayer2D::play_scheduled(double p_abs_time, double p_from_pos) {
263263
_play_internal(p_from_pos);
264264
}
265265

266-
void AudioStreamPlayer2D::seek(float p_seconds) {
266+
void AudioStreamPlayer2D::seek(double p_seconds) {
267267
internal->seek(p_seconds);
268268
}
269269

@@ -279,7 +279,7 @@ bool AudioStreamPlayer2D::is_playing() const {
279279
return internal->is_playing();
280280
}
281281

282-
float AudioStreamPlayer2D::get_playback_position() {
282+
double AudioStreamPlayer2D::get_playback_position() {
283283
if (setplay.get() >= 0) {
284284
return setplay.get(); // play() has been called this frame, but no playback exists just yet.
285285
}

scene/2d/audio_stream_player_2d.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@ class AudioStreamPlayer2D : public Node2D {
9595

9696
#ifndef DISABLE_DEPRECATED
9797
bool _is_autoplay_enabled_bind_compat_86907();
98+
void _play_bind_compat_105545(float p_from_pos = 0.0);
99+
void _seek_bind_compat_105545(float p_seconds);
100+
float _get_playback_position_bind_compat_105545();
98101
static void _bind_compatibility_methods();
99102
#endif // DISABLE_DEPRECATED
100103

@@ -111,12 +114,12 @@ class AudioStreamPlayer2D : public Node2D {
111114
void set_pitch_scale(float p_pitch_scale);
112115
float get_pitch_scale() const;
113116

114-
void play(float p_from_pos = 0.0);
117+
void play(double p_from_pos = 0.0);
115118
void play_scheduled(double p_abs_time, double p_from_pos = 0.0);
116-
void seek(float p_seconds);
119+
void seek(double p_seconds);
117120
void stop();
118121
bool is_playing() const;
119-
float get_playback_position();
122+
double get_playback_position();
120123

121124
void set_bus(const StringName &p_bus);
122125
StringName get_bus() const;

scene/3d/audio_stream_player_3d.compat.inc

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,23 @@ bool AudioStreamPlayer3D::_is_autoplay_enabled_bind_compat_86907() {
3434
return is_autoplay_enabled();
3535
}
3636

37+
void AudioStreamPlayer3D::_play_bind_compat_105545(float p_from_pos) {
38+
play(p_from_pos);
39+
}
40+
41+
void AudioStreamPlayer3D::_seek_bind_compat_105545(float p_seconds) {
42+
seek(p_seconds);
43+
}
44+
45+
float AudioStreamPlayer3D::_get_playback_position_bind_compat_105545() {
46+
return get_playback_position();
47+
}
48+
3749
void AudioStreamPlayer3D::_bind_compatibility_methods() {
3850
ClassDB::bind_compatibility_method(D_METHOD("is_autoplay_enabled"), &AudioStreamPlayer3D::_is_autoplay_enabled_bind_compat_86907);
51+
ClassDB::bind_compatibility_method(D_METHOD("play", "from_position"), &AudioStreamPlayer3D::_play_bind_compat_105545, DEFVAL(0.0));
52+
ClassDB::bind_compatibility_method(D_METHOD("seek", "to_position"), &AudioStreamPlayer3D::_seek_bind_compat_105545);
53+
ClassDB::bind_compatibility_method(D_METHOD("get_playback_position"), &AudioStreamPlayer3D::_get_playback_position_bind_compat_105545);
3954
}
4055

4156
#endif // DISABLE_DEPRECATED

scene/3d/audio_stream_player_3d.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -613,7 +613,7 @@ void AudioStreamPlayer3D::_play_internal(double p_from_pos) {
613613
}
614614
}
615615

616-
void AudioStreamPlayer3D::play(float p_from_pos) {
616+
void AudioStreamPlayer3D::play(double p_from_pos) {
617617
internal->scheduled_time = 0;
618618
_play_internal(p_from_pos);
619619
}
@@ -623,7 +623,7 @@ void AudioStreamPlayer3D::play_scheduled(double p_abs_time, double p_from_pos) {
623623
_play_internal(p_from_pos);
624624
}
625625

626-
void AudioStreamPlayer3D::seek(float p_seconds) {
626+
void AudioStreamPlayer3D::seek(double p_seconds) {
627627
internal->seek(p_seconds);
628628
}
629629

@@ -639,7 +639,7 @@ bool AudioStreamPlayer3D::is_playing() const {
639639
return internal->is_playing();
640640
}
641641

642-
float AudioStreamPlayer3D::get_playback_position() {
642+
double AudioStreamPlayer3D::get_playback_position() {
643643
if (setplay.get() >= 0) {
644644
return setplay.get(); // play() has been called this frame, but no playback exists just yet.
645645
}

scene/3d/audio_stream_player_3d.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,9 @@ class AudioStreamPlayer3D : public Node3D {
134134

135135
#ifndef DISABLE_DEPRECATED
136136
bool _is_autoplay_enabled_bind_compat_86907();
137+
void _play_bind_compat_105545(float p_from_pos = 0.0);
138+
void _seek_bind_compat_105545(float p_seconds);
139+
float _get_playback_position_bind_compat_105545();
137140
static void _bind_compatibility_methods();
138141
#endif // DISABLE_DEPRECATED
139142

@@ -156,12 +159,12 @@ class AudioStreamPlayer3D : public Node3D {
156159
void set_pitch_scale(float p_pitch_scale);
157160
float get_pitch_scale() const;
158161

159-
void play(float p_from_pos = 0.0);
162+
void play(double p_from_pos = 0.0);
160163
void play_scheduled(double p_abs_time, double p_from_pos = 0.0);
161-
void seek(float p_seconds);
164+
void seek(double p_seconds);
162165
void stop();
163166
bool is_playing() const;
164-
float get_playback_position();
167+
double get_playback_position();
165168

166169
void set_bus(const StringName &p_bus);
167170
StringName get_bus() const;

scene/audio/audio_stream_player.compat.inc

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,23 @@ bool AudioStreamPlayer::_is_autoplay_enabled_bind_compat_86907() {
3434
return is_autoplay_enabled();
3535
}
3636

37+
void AudioStreamPlayer::_play_bind_compat_105545(float p_from_pos) {
38+
play(p_from_pos);
39+
}
40+
41+
void AudioStreamPlayer::_seek_bind_compat_105545(float p_seconds) {
42+
seek(p_seconds);
43+
}
44+
45+
float AudioStreamPlayer::_get_playback_position_bind_compat_105545() {
46+
return get_playback_position();
47+
}
48+
3749
void AudioStreamPlayer::_bind_compatibility_methods() {
3850
ClassDB::bind_compatibility_method(D_METHOD("is_autoplay_enabled"), &AudioStreamPlayer::_is_autoplay_enabled_bind_compat_86907);
51+
ClassDB::bind_compatibility_method(D_METHOD("play", "from_position"), &AudioStreamPlayer::_play_bind_compat_105545, DEFVAL(0.0));
52+
ClassDB::bind_compatibility_method(D_METHOD("seek", "to_position"), &AudioStreamPlayer::_seek_bind_compat_105545);
53+
ClassDB::bind_compatibility_method(D_METHOD("get_playback_position"), &AudioStreamPlayer::_get_playback_position_bind_compat_105545);
3954
}
4055

4156
#endif // DISABLE_DEPRECATED

scene/audio/audio_stream_player.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ void AudioStreamPlayer::_play_internal(double p_from_pos) {
126126
}
127127
}
128128

129-
void AudioStreamPlayer::play(float p_from_pos) {
129+
void AudioStreamPlayer::play(double p_from_pos) {
130130
internal->scheduled_time = 0;
131131
_play_internal(p_from_pos);
132132
}
@@ -136,7 +136,7 @@ void AudioStreamPlayer::play_scheduled(double p_abs_time, double p_from_pos) {
136136
_play_internal(p_from_pos);
137137
}
138138

139-
void AudioStreamPlayer::seek(float p_seconds) {
139+
void AudioStreamPlayer::seek(double p_seconds) {
140140
internal->seek(p_seconds);
141141
}
142142

@@ -148,7 +148,7 @@ bool AudioStreamPlayer::is_playing() const {
148148
return internal->is_playing();
149149
}
150150

151-
float AudioStreamPlayer::get_playback_position() {
151+
double AudioStreamPlayer::get_playback_position() {
152152
return internal->get_playback_position();
153153
}
154154

scene/audio/audio_stream_player.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ class AudioStreamPlayer : public Node {
7171

7272
#ifndef DISABLE_DEPRECATED
7373
bool _is_autoplay_enabled_bind_compat_86907();
74+
void _play_bind_compat_105545(float p_from_pos = 0.0);
75+
void _seek_bind_compat_105545(float p_seconds);
76+
float _get_playback_position_bind_compat_105545();
7477
static void _bind_compatibility_methods();
7578
#endif // DISABLE_DEPRECATED
7679

@@ -90,12 +93,12 @@ class AudioStreamPlayer : public Node {
9093
void set_max_polyphony(int p_max_polyphony);
9194
int get_max_polyphony() const;
9295

93-
void play(float p_from_pos = 0.0);
96+
void play(double p_from_pos = 0.0);
9497
void play_scheduled(double p_abs_time, double p_from_pos = 0.0);
95-
void seek(float p_seconds);
98+
void seek(double p_seconds);
9699
void stop();
97100
bool is_playing() const;
98-
float get_playback_position();
101+
double get_playback_position();
99102

100103
void set_bus(const StringName &p_bus);
101104
StringName get_bus() const;

0 commit comments

Comments
 (0)