summaryrefslogtreecommitdiff
path: root/scene/audio
diff options
context:
space:
mode:
Diffstat (limited to 'scene/audio')
-rw-r--r--scene/audio/audio_stream_player.cpp (renamed from scene/audio/audio_player.cpp)133
-rw-r--r--scene/audio/audio_stream_player.h (renamed from scene/audio/audio_player.h)17
2 files changed, 108 insertions, 42 deletions
diff --git a/scene/audio/audio_player.cpp b/scene/audio/audio_stream_player.cpp
index 4eae3b04e7..144e58d8b9 100644
--- a/scene/audio/audio_player.cpp
+++ b/scene/audio/audio_stream_player.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* audio_player.cpp */
+/* audio_stream_player.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,37 +28,14 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "audio_player.h"
+#include "audio_stream_player.h"
#include "core/engine.h"
-void AudioStreamPlayer::_mix_internal(bool p_fadeout) {
-
- int bus_index = AudioServer::get_singleton()->thread_find_bus_index(bus);
- //get data
- AudioFrame *buffer = mix_buffer.ptrw();
- int buffer_size = mix_buffer.size();
-
- if (p_fadeout) {
- // Short fadeout ramp
- buffer_size = MIN(buffer_size, 128);
- }
+void AudioStreamPlayer::_mix_to_bus(const AudioFrame *p_frames,int p_amount) {
- stream_playback->mix(buffer, pitch_scale, buffer_size);
-
- //multiply volume interpolating to avoid clicks if this changes
- float target_volume = p_fadeout ? -80.0 : volume_db;
- float vol = Math::db2linear(mix_volume_db);
- float vol_inc = (Math::db2linear(target_volume) - vol) / float(buffer_size);
-
- for (int i = 0; i < buffer_size; i++) {
- buffer[i] *= vol;
- vol += vol_inc;
- }
-
- //set volume for next mix
- mix_volume_db = target_volume;
+ int bus_index = AudioServer::get_singleton()->thread_find_bus_index(bus);
AudioFrame *targets[4] = { NULL, NULL, NULL, NULL };
@@ -83,16 +60,55 @@ void AudioStreamPlayer::_mix_internal(bool p_fadeout) {
for (int c = 0; c < 4; c++) {
if (!targets[c])
break;
- for (int i = 0; i < buffer_size; i++) {
- targets[c][i] += buffer[i];
+ for (int i = 0; i < p_amount; i++) {
+ targets[c][i] += p_frames[i];
}
}
}
+
+void AudioStreamPlayer::_mix_internal(bool p_fadeout) {
+
+
+ //get data
+ AudioFrame *buffer = mix_buffer.ptrw();
+ int buffer_size = mix_buffer.size();
+
+ if (p_fadeout) {
+ // Short fadeout ramp
+ buffer_size = MIN(buffer_size, 128);
+ }
+
+ stream_playback->mix(buffer, pitch_scale, buffer_size);
+
+ //multiply volume interpolating to avoid clicks if this changes
+ float target_volume = p_fadeout ? -80.0 : volume_db;
+ float vol = Math::db2linear(mix_volume_db);
+ float vol_inc = (Math::db2linear(target_volume) - vol) / float(buffer_size);
+
+ for (int i = 0; i < buffer_size; i++) {
+ buffer[i] *= vol;
+ vol += vol_inc;
+ }
+
+ //set volume for next mix
+ mix_volume_db = target_volume;
+
+ _mix_to_bus(buffer,buffer_size);
+
+}
+
void AudioStreamPlayer::_mix_audio() {
- if (!stream_playback.is_valid() || !active)
+ if (use_fadeout) {
+ _mix_to_bus(fadeout_buffer.ptr(),fadeout_buffer.size());
+ use_fadeout=false;
+ }
+
+ if (!stream_playback.is_valid() || !active ||
+ (stream_paused && !stream_paused_fade)) {
return;
+ }
if (stream_paused) {
if (stream_paused_fade) {
@@ -102,17 +118,26 @@ void AudioStreamPlayer::_mix_audio() {
return;
}
- if (setseek >= 0.0) {
+ if (setstop) {
+ _mix_internal(true);
+ stream_playback->stop();
+ setstop=false;
+ }
+
+ if (setseek >= 0.0 && !stop_has_priority) {
if (stream_playback->is_playing()) {
//fade out to avoid pops
_mix_internal(true);
}
+
stream_playback->start(setseek);
setseek = -1.0; //reset seek
mix_volume_db = volume_db; //reset ramp
}
+ stop_has_priority = false;
+
_mix_internal(false);
}
@@ -129,7 +154,7 @@ void AudioStreamPlayer::_notification(int p_what) {
if (p_what == NOTIFICATION_INTERNAL_PROCESS) {
if (!active || (setseek < 0 && !stream_playback->is_playing())) {
- active = false;
+ active = false;
set_process_internal(false);
emit_signal("finished");
}
@@ -156,6 +181,28 @@ void AudioStreamPlayer::set_stream(Ref<AudioStream> p_stream) {
AudioServer::get_singleton()->lock();
+ if (active && stream_playback.is_valid() && !stream_paused) {
+ //changing streams out of the blue is not a great idea, but at least
+ //lets try to somehow avoid a click
+
+ AudioFrame *buffer = fadeout_buffer.ptrw();
+ int buffer_size = fadeout_buffer.size();
+
+ stream_playback->mix(buffer, pitch_scale, buffer_size);
+
+ //multiply volume interpolating to avoid clicks if this changes
+ float target_volume = -80.0;
+ float vol = Math::db2linear(mix_volume_db);
+ float vol_inc = (Math::db2linear(target_volume) - vol) / float(buffer_size);
+
+ for (int i = 0; i < buffer_size; i++) {
+ buffer[i] *= vol;
+ vol += vol_inc;
+ }
+
+ use_fadeout=true;
+ }
+
mix_buffer.resize(AudioServer::get_singleton()->thread_get_mix_buffer_size());
if (stream_playback.is_valid()) {
@@ -163,6 +210,7 @@ void AudioStreamPlayer::set_stream(Ref<AudioStream> p_stream) {
stream.unref();
active = false;
setseek = -1;
+ setstop = false;
}
if (p_stream.is_valid()) {
@@ -204,6 +252,7 @@ void AudioStreamPlayer::play(float p_from_pos) {
if (stream_playback.is_valid()) {
//mix_volume_db = volume_db; do not reset volume ramp here, can cause clicks
setseek = p_from_pos;
+ stop_has_priority=false;
active = true;
set_process_internal(true);
}
@@ -218,17 +267,16 @@ void AudioStreamPlayer::seek(float p_seconds) {
void AudioStreamPlayer::stop() {
- if (stream_playback.is_valid()) {
- stream_playback->stop();
- active = false;
- set_process_internal(false);
+ if (stream_playback.is_valid() && active) {
+ setstop=true;
+ stop_has_priority=true;
}
}
bool AudioStreamPlayer::is_playing() const {
if (stream_playback.is_valid()) {
- return active; //&& stream_playback->is_playing();
+ return active && !setstop; //&& stream_playback->is_playing();
}
return false;
@@ -309,7 +357,7 @@ void AudioStreamPlayer::_validate_property(PropertyInfo &property) const {
if (property.name == "bus") {
String options;
- for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) {
+ for (int i = 0; i <AudioServer::get_singleton()->get_bus_count(); i++) {
if (i > 0)
options += ",";
String name = AudioServer::get_singleton()->get_bus_name(i);
@@ -325,6 +373,10 @@ void AudioStreamPlayer::_bus_layout_changed() {
_change_notify();
}
+Ref<AudioStreamPlayback> AudioStreamPlayer::get_stream_playback() {
+ return stream_playback;
+}
+
void AudioStreamPlayer::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_stream", "stream"), &AudioStreamPlayer::set_stream);
@@ -360,6 +412,8 @@ void AudioStreamPlayer::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_stream_paused", "pause"), &AudioStreamPlayer::set_stream_paused);
ClassDB::bind_method(D_METHOD("get_stream_paused"), &AudioStreamPlayer::get_stream_paused);
+ ClassDB::bind_method(D_METHOD("get_stream_playback"), &AudioStreamPlayer::get_stream_playback);
+
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "stream", PROPERTY_HINT_RESOURCE_TYPE, "AudioStream"), "set_stream", "get_stream");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "volume_db", PROPERTY_HINT_RANGE, "-80,24"), "set_volume_db", "get_volume_db");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "pitch_scale", PROPERTY_HINT_RANGE, "0.01,32,0.01"), "set_pitch_scale", "get_pitch_scale");
@@ -387,6 +441,9 @@ AudioStreamPlayer::AudioStreamPlayer() {
stream_paused = false;
stream_paused_fade = false;
mix_target = MIX_TARGET_STEREO;
+ fadeout_buffer.resize(512);
+ setstop=false;
+ use_fadeout=false;
AudioServer::get_singleton()->connect("bus_layout_changed", this, "_bus_layout_changed");
}
diff --git a/scene/audio/audio_player.h b/scene/audio/audio_stream_player.h
index 2e9526c335..0b782b67e7 100644
--- a/scene/audio/audio_player.h
+++ b/scene/audio/audio_stream_player.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* audio_player.h */
+/* audio_stream_player.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef AUDIOPLAYER_H
-#define AUDIOPLAYER_H
+#ifndef AUDIO_STREAM_PLAYER_H
+#define AUDIO_STREAM_PLAYER_H
#include "scene/main/node.h"
#include "servers/audio/audio_stream.h"
@@ -49,9 +49,13 @@ private:
Ref<AudioStreamPlayback> stream_playback;
Ref<AudioStream> stream;
Vector<AudioFrame> mix_buffer;
+ Vector<AudioFrame> fadeout_buffer;
+ bool use_fadeout;
volatile float setseek;
volatile bool active;
+ volatile bool setstop;
+ volatile bool stop_has_priority;
float mix_volume_db;
float pitch_scale;
@@ -71,6 +75,7 @@ private:
bool _is_active() const;
void _bus_layout_changed();
+ void _mix_to_bus(const AudioFrame *p_frames, int p_amount);
protected:
void _validate_property(PropertyInfo &property) const;
@@ -105,9 +110,13 @@ public:
void set_stream_paused(bool p_pause);
bool get_stream_paused() const;
+ Ref<AudioStreamPlayback> get_stream_playback();
+
+
AudioStreamPlayer();
~AudioStreamPlayer();
};
VARIANT_ENUM_CAST(AudioStreamPlayer::MixTarget)
-#endif // AUDIOPLAYER_H
+
+#endif // AUDIO_STREAM_PLAYER_H