From c5dcbeb160b37d8ffd70061d76eb980756fe36b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Tue, 12 Feb 2019 17:18:13 +0100 Subject: Scene: Ensure classes match their header filename Also drop some unused files. Renamed: - `scene/2d/navigation2d.h` -> `navigation_2d.h` - `scene/2d/screen_button.h` -> `touch_screen_button.h` - `scene/3d/scenario_fx.h` -> `world_environment.h` - `scene/audio/audio_player.h` -> `audio_stream_player.h` - `scene/resources/bit_mask.h` -> `bit_map.h` - `scene/resources/color_ramp.h` -> `gradient.h` - `scene/resources/shape_line_2d.h` -> `line_shape_2d.h` - `scene/resources/scene_format_text.h` -> `resource_format_text.h` - `scene/resources/sky_box.h` -> `sky.h` Dropped: - `scene/resources/bounds.h` --- scene/audio/audio_player.cpp | 395 ------------------------------------ scene/audio/audio_player.h | 113 ----------- scene/audio/audio_stream_player.cpp | 395 ++++++++++++++++++++++++++++++++++++ scene/audio/audio_stream_player.h | 114 +++++++++++ 4 files changed, 509 insertions(+), 508 deletions(-) delete mode 100644 scene/audio/audio_player.cpp delete mode 100644 scene/audio/audio_player.h create mode 100644 scene/audio/audio_stream_player.cpp create mode 100644 scene/audio/audio_stream_player.h (limited to 'scene/audio') diff --git a/scene/audio/audio_player.cpp b/scene/audio/audio_player.cpp deleted file mode 100644 index 4eae3b04e7..0000000000 --- a/scene/audio/audio_player.cpp +++ /dev/null @@ -1,395 +0,0 @@ -/*************************************************************************/ -/* audio_player.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "audio_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); - } - - 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; - - AudioFrame *targets[4] = { NULL, NULL, NULL, NULL }; - - if (AudioServer::get_singleton()->get_speaker_mode() == AudioServer::SPEAKER_MODE_STEREO) { - targets[0] = AudioServer::get_singleton()->thread_get_channel_mix_buffer(bus_index, 0); - } else { - switch (mix_target) { - case MIX_TARGET_STEREO: { - targets[0] = AudioServer::get_singleton()->thread_get_channel_mix_buffer(bus_index, 0); - } break; - case MIX_TARGET_SURROUND: { - for (int i = 0; i < AudioServer::get_singleton()->get_channel_count(); i++) { - targets[i] = AudioServer::get_singleton()->thread_get_channel_mix_buffer(bus_index, i); - } - } break; - case MIX_TARGET_CENTER: { - targets[0] = AudioServer::get_singleton()->thread_get_channel_mix_buffer(bus_index, 1); - } break; - } - } - - for (int c = 0; c < 4; c++) { - if (!targets[c]) - break; - for (int i = 0; i < buffer_size; i++) { - targets[c][i] += buffer[i]; - } - } -} - -void AudioStreamPlayer::_mix_audio() { - - if (!stream_playback.is_valid() || !active) - return; - - if (stream_paused) { - if (stream_paused_fade) { - _mix_internal(true); - stream_paused_fade = false; - } - return; - } - - if (setseek >= 0.0) { - 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 - } - - _mix_internal(false); -} - -void AudioStreamPlayer::_notification(int p_what) { - - if (p_what == NOTIFICATION_ENTER_TREE) { - - AudioServer::get_singleton()->add_callback(_mix_audios, this); - if (autoplay && !Engine::get_singleton()->is_editor_hint()) { - play(); - } - } - - if (p_what == NOTIFICATION_INTERNAL_PROCESS) { - - if (!active || (setseek < 0 && !stream_playback->is_playing())) { - active = false; - set_process_internal(false); - emit_signal("finished"); - } - } - - if (p_what == NOTIFICATION_EXIT_TREE) { - - AudioServer::get_singleton()->remove_callback(_mix_audios, this); - } - - if (p_what == NOTIFICATION_PAUSED) { - if (!can_process()) { - // Node can't process so we start fading out to silence - set_stream_paused(true); - } - } - - if (p_what == NOTIFICATION_UNPAUSED) { - set_stream_paused(false); - } -} - -void AudioStreamPlayer::set_stream(Ref p_stream) { - - AudioServer::get_singleton()->lock(); - - mix_buffer.resize(AudioServer::get_singleton()->thread_get_mix_buffer_size()); - - if (stream_playback.is_valid()) { - stream_playback.unref(); - stream.unref(); - active = false; - setseek = -1; - } - - if (p_stream.is_valid()) { - stream = p_stream; - stream_playback = p_stream->instance_playback(); - } - - AudioServer::get_singleton()->unlock(); - - if (p_stream.is_valid() && stream_playback.is_null()) { - stream.unref(); - } -} - -Ref AudioStreamPlayer::get_stream() const { - - return stream; -} - -void AudioStreamPlayer::set_volume_db(float p_volume) { - - volume_db = p_volume; -} -float AudioStreamPlayer::get_volume_db() const { - - return volume_db; -} - -void AudioStreamPlayer::set_pitch_scale(float p_pitch_scale) { - ERR_FAIL_COND(p_pitch_scale <= 0.0); - pitch_scale = p_pitch_scale; -} -float AudioStreamPlayer::get_pitch_scale() const { - return pitch_scale; -} - -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; - active = true; - set_process_internal(true); - } -} - -void AudioStreamPlayer::seek(float p_seconds) { - - if (stream_playback.is_valid()) { - setseek = p_seconds; - } -} - -void AudioStreamPlayer::stop() { - - if (stream_playback.is_valid()) { - stream_playback->stop(); - active = false; - set_process_internal(false); - } -} - -bool AudioStreamPlayer::is_playing() const { - - if (stream_playback.is_valid()) { - return active; //&& stream_playback->is_playing(); - } - - return false; -} - -float AudioStreamPlayer::get_playback_position() { - - if (stream_playback.is_valid()) { - return stream_playback->get_playback_position(); - } - - return 0; -} - -void AudioStreamPlayer::set_bus(const StringName &p_bus) { - - //if audio is active, must lock this - AudioServer::get_singleton()->lock(); - bus = p_bus; - AudioServer::get_singleton()->unlock(); -} -StringName AudioStreamPlayer::get_bus() const { - - for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) { - if (AudioServer::get_singleton()->get_bus_name(i) == bus) { - return bus; - } - } - return "Master"; -} - -void AudioStreamPlayer::set_autoplay(bool p_enable) { - - autoplay = p_enable; -} -bool AudioStreamPlayer::is_autoplay_enabled() { - - return autoplay; -} - -void AudioStreamPlayer::set_mix_target(MixTarget p_target) { - - mix_target = p_target; -} - -AudioStreamPlayer::MixTarget AudioStreamPlayer::get_mix_target() const { - - return mix_target; -} - -void AudioStreamPlayer::_set_playing(bool p_enable) { - - if (p_enable) - play(); - else - stop(); -} -bool AudioStreamPlayer::_is_active() const { - - return active; -} - -void AudioStreamPlayer::set_stream_paused(bool p_pause) { - - if (p_pause != stream_paused) { - stream_paused = p_pause; - stream_paused_fade = p_pause ? true : false; - } -} - -bool AudioStreamPlayer::get_stream_paused() const { - - return stream_paused; -} - -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++) { - if (i > 0) - options += ","; - String name = AudioServer::get_singleton()->get_bus_name(i); - options += name; - } - - property.hint_string = options; - } -} - -void AudioStreamPlayer::_bus_layout_changed() { - - _change_notify(); -} - -void AudioStreamPlayer::_bind_methods() { - - ClassDB::bind_method(D_METHOD("set_stream", "stream"), &AudioStreamPlayer::set_stream); - ClassDB::bind_method(D_METHOD("get_stream"), &AudioStreamPlayer::get_stream); - - ClassDB::bind_method(D_METHOD("set_volume_db", "volume_db"), &AudioStreamPlayer::set_volume_db); - ClassDB::bind_method(D_METHOD("get_volume_db"), &AudioStreamPlayer::get_volume_db); - - ClassDB::bind_method(D_METHOD("set_pitch_scale", "pitch_scale"), &AudioStreamPlayer::set_pitch_scale); - ClassDB::bind_method(D_METHOD("get_pitch_scale"), &AudioStreamPlayer::get_pitch_scale); - - ClassDB::bind_method(D_METHOD("play", "from_position"), &AudioStreamPlayer::play, DEFVAL(0.0)); - ClassDB::bind_method(D_METHOD("seek", "to_position"), &AudioStreamPlayer::seek); - ClassDB::bind_method(D_METHOD("stop"), &AudioStreamPlayer::stop); - - ClassDB::bind_method(D_METHOD("is_playing"), &AudioStreamPlayer::is_playing); - ClassDB::bind_method(D_METHOD("get_playback_position"), &AudioStreamPlayer::get_playback_position); - - ClassDB::bind_method(D_METHOD("set_bus", "bus"), &AudioStreamPlayer::set_bus); - ClassDB::bind_method(D_METHOD("get_bus"), &AudioStreamPlayer::get_bus); - - ClassDB::bind_method(D_METHOD("set_autoplay", "enable"), &AudioStreamPlayer::set_autoplay); - ClassDB::bind_method(D_METHOD("is_autoplay_enabled"), &AudioStreamPlayer::is_autoplay_enabled); - - ClassDB::bind_method(D_METHOD("set_mix_target", "mix_target"), &AudioStreamPlayer::set_mix_target); - ClassDB::bind_method(D_METHOD("get_mix_target"), &AudioStreamPlayer::get_mix_target); - - ClassDB::bind_method(D_METHOD("_set_playing", "enable"), &AudioStreamPlayer::_set_playing); - ClassDB::bind_method(D_METHOD("_is_active"), &AudioStreamPlayer::_is_active); - - ClassDB::bind_method(D_METHOD("_bus_layout_changed"), &AudioStreamPlayer::_bus_layout_changed); - - 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); - - 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"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_playing", "is_playing"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "autoplay"), "set_autoplay", "is_autoplay_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "stream_paused", PROPERTY_HINT_NONE, ""), "set_stream_paused", "get_stream_paused"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "mix_target", PROPERTY_HINT_ENUM, "Stereo,Surround,Center"), "set_mix_target", "get_mix_target"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "bus", PROPERTY_HINT_ENUM, ""), "set_bus", "get_bus"); - - ADD_SIGNAL(MethodInfo("finished")); - - BIND_ENUM_CONSTANT(MIX_TARGET_STEREO); - BIND_ENUM_CONSTANT(MIX_TARGET_SURROUND); - BIND_ENUM_CONSTANT(MIX_TARGET_CENTER); -} - -AudioStreamPlayer::AudioStreamPlayer() { - - mix_volume_db = 0; - pitch_scale = 1.0; - volume_db = 0; - autoplay = false; - setseek = -1; - active = false; - stream_paused = false; - stream_paused_fade = false; - mix_target = MIX_TARGET_STEREO; - - AudioServer::get_singleton()->connect("bus_layout_changed", this, "_bus_layout_changed"); -} - -AudioStreamPlayer::~AudioStreamPlayer() { -} diff --git a/scene/audio/audio_player.h b/scene/audio/audio_player.h deleted file mode 100644 index 2e9526c335..0000000000 --- a/scene/audio/audio_player.h +++ /dev/null @@ -1,113 +0,0 @@ -/*************************************************************************/ -/* audio_player.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef AUDIOPLAYER_H -#define AUDIOPLAYER_H - -#include "scene/main/node.h" -#include "servers/audio/audio_stream.h" - -class AudioStreamPlayer : public Node { - - GDCLASS(AudioStreamPlayer, Node) - -public: - enum MixTarget { - MIX_TARGET_STEREO, - MIX_TARGET_SURROUND, - MIX_TARGET_CENTER - }; - -private: - Ref stream_playback; - Ref stream; - Vector mix_buffer; - - volatile float setseek; - volatile bool active; - - float mix_volume_db; - float pitch_scale; - float volume_db; - bool autoplay; - bool stream_paused; - bool stream_paused_fade; - StringName bus; - - MixTarget mix_target; - - void _mix_internal(bool p_fadeout); - void _mix_audio(); - static void _mix_audios(void *self) { reinterpret_cast(self)->_mix_audio(); } - - void _set_playing(bool p_enable); - bool _is_active() const; - - void _bus_layout_changed(); - -protected: - void _validate_property(PropertyInfo &property) const; - void _notification(int p_what); - static void _bind_methods(); - -public: - void set_stream(Ref p_stream); - Ref get_stream() const; - - void set_volume_db(float p_volume); - float get_volume_db() const; - - void set_pitch_scale(float p_pitch_scale); - float get_pitch_scale() const; - - void play(float p_from_pos = 0.0); - void seek(float p_seconds); - void stop(); - bool is_playing() const; - float get_playback_position(); - - void set_bus(const StringName &p_bus); - StringName get_bus() const; - - void set_autoplay(bool p_enable); - bool is_autoplay_enabled(); - - void set_mix_target(MixTarget p_target); - MixTarget get_mix_target() const; - - void set_stream_paused(bool p_pause); - bool get_stream_paused() const; - - AudioStreamPlayer(); - ~AudioStreamPlayer(); -}; - -VARIANT_ENUM_CAST(AudioStreamPlayer::MixTarget) -#endif // AUDIOPLAYER_H diff --git a/scene/audio/audio_stream_player.cpp b/scene/audio/audio_stream_player.cpp new file mode 100644 index 0000000000..e6864e2117 --- /dev/null +++ b/scene/audio/audio_stream_player.cpp @@ -0,0 +1,395 @@ +/*************************************************************************/ +/* audio_stream_player.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#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); + } + + 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; + + AudioFrame *targets[4] = { NULL, NULL, NULL, NULL }; + + if (AudioServer::get_singleton()->get_speaker_mode() == AudioServer::SPEAKER_MODE_STEREO) { + targets[0] = AudioServer::get_singleton()->thread_get_channel_mix_buffer(bus_index, 0); + } else { + switch (mix_target) { + case MIX_TARGET_STEREO: { + targets[0] = AudioServer::get_singleton()->thread_get_channel_mix_buffer(bus_index, 0); + } break; + case MIX_TARGET_SURROUND: { + for (int i = 0; i < AudioServer::get_singleton()->get_channel_count(); i++) { + targets[i] = AudioServer::get_singleton()->thread_get_channel_mix_buffer(bus_index, i); + } + } break; + case MIX_TARGET_CENTER: { + targets[0] = AudioServer::get_singleton()->thread_get_channel_mix_buffer(bus_index, 1); + } break; + } + } + + for (int c = 0; c < 4; c++) { + if (!targets[c]) + break; + for (int i = 0; i < buffer_size; i++) { + targets[c][i] += buffer[i]; + } + } +} + +void AudioStreamPlayer::_mix_audio() { + + if (!stream_playback.is_valid() || !active) + return; + + if (stream_paused) { + if (stream_paused_fade) { + _mix_internal(true); + stream_paused_fade = false; + } + return; + } + + if (setseek >= 0.0) { + 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 + } + + _mix_internal(false); +} + +void AudioStreamPlayer::_notification(int p_what) { + + if (p_what == NOTIFICATION_ENTER_TREE) { + + AudioServer::get_singleton()->add_callback(_mix_audios, this); + if (autoplay && !Engine::get_singleton()->is_editor_hint()) { + play(); + } + } + + if (p_what == NOTIFICATION_INTERNAL_PROCESS) { + + if (!active || (setseek < 0 && !stream_playback->is_playing())) { + active = false; + set_process_internal(false); + emit_signal("finished"); + } + } + + if (p_what == NOTIFICATION_EXIT_TREE) { + + AudioServer::get_singleton()->remove_callback(_mix_audios, this); + } + + if (p_what == NOTIFICATION_PAUSED) { + if (!can_process()) { + // Node can't process so we start fading out to silence + set_stream_paused(true); + } + } + + if (p_what == NOTIFICATION_UNPAUSED) { + set_stream_paused(false); + } +} + +void AudioStreamPlayer::set_stream(Ref p_stream) { + + AudioServer::get_singleton()->lock(); + + mix_buffer.resize(AudioServer::get_singleton()->thread_get_mix_buffer_size()); + + if (stream_playback.is_valid()) { + stream_playback.unref(); + stream.unref(); + active = false; + setseek = -1; + } + + if (p_stream.is_valid()) { + stream = p_stream; + stream_playback = p_stream->instance_playback(); + } + + AudioServer::get_singleton()->unlock(); + + if (p_stream.is_valid() && stream_playback.is_null()) { + stream.unref(); + } +} + +Ref AudioStreamPlayer::get_stream() const { + + return stream; +} + +void AudioStreamPlayer::set_volume_db(float p_volume) { + + volume_db = p_volume; +} +float AudioStreamPlayer::get_volume_db() const { + + return volume_db; +} + +void AudioStreamPlayer::set_pitch_scale(float p_pitch_scale) { + ERR_FAIL_COND(p_pitch_scale <= 0.0); + pitch_scale = p_pitch_scale; +} +float AudioStreamPlayer::get_pitch_scale() const { + return pitch_scale; +} + +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; + active = true; + set_process_internal(true); + } +} + +void AudioStreamPlayer::seek(float p_seconds) { + + if (stream_playback.is_valid()) { + setseek = p_seconds; + } +} + +void AudioStreamPlayer::stop() { + + if (stream_playback.is_valid()) { + stream_playback->stop(); + active = false; + set_process_internal(false); + } +} + +bool AudioStreamPlayer::is_playing() const { + + if (stream_playback.is_valid()) { + return active; //&& stream_playback->is_playing(); + } + + return false; +} + +float AudioStreamPlayer::get_playback_position() { + + if (stream_playback.is_valid()) { + return stream_playback->get_playback_position(); + } + + return 0; +} + +void AudioStreamPlayer::set_bus(const StringName &p_bus) { + + //if audio is active, must lock this + AudioServer::get_singleton()->lock(); + bus = p_bus; + AudioServer::get_singleton()->unlock(); +} +StringName AudioStreamPlayer::get_bus() const { + + for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) { + if (AudioServer::get_singleton()->get_bus_name(i) == bus) { + return bus; + } + } + return "Master"; +} + +void AudioStreamPlayer::set_autoplay(bool p_enable) { + + autoplay = p_enable; +} +bool AudioStreamPlayer::is_autoplay_enabled() { + + return autoplay; +} + +void AudioStreamPlayer::set_mix_target(MixTarget p_target) { + + mix_target = p_target; +} + +AudioStreamPlayer::MixTarget AudioStreamPlayer::get_mix_target() const { + + return mix_target; +} + +void AudioStreamPlayer::_set_playing(bool p_enable) { + + if (p_enable) + play(); + else + stop(); +} +bool AudioStreamPlayer::_is_active() const { + + return active; +} + +void AudioStreamPlayer::set_stream_paused(bool p_pause) { + + if (p_pause != stream_paused) { + stream_paused = p_pause; + stream_paused_fade = p_pause ? true : false; + } +} + +bool AudioStreamPlayer::get_stream_paused() const { + + return stream_paused; +} + +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++) { + if (i > 0) + options += ","; + String name = AudioServer::get_singleton()->get_bus_name(i); + options += name; + } + + property.hint_string = options; + } +} + +void AudioStreamPlayer::_bus_layout_changed() { + + _change_notify(); +} + +void AudioStreamPlayer::_bind_methods() { + + ClassDB::bind_method(D_METHOD("set_stream", "stream"), &AudioStreamPlayer::set_stream); + ClassDB::bind_method(D_METHOD("get_stream"), &AudioStreamPlayer::get_stream); + + ClassDB::bind_method(D_METHOD("set_volume_db", "volume_db"), &AudioStreamPlayer::set_volume_db); + ClassDB::bind_method(D_METHOD("get_volume_db"), &AudioStreamPlayer::get_volume_db); + + ClassDB::bind_method(D_METHOD("set_pitch_scale", "pitch_scale"), &AudioStreamPlayer::set_pitch_scale); + ClassDB::bind_method(D_METHOD("get_pitch_scale"), &AudioStreamPlayer::get_pitch_scale); + + ClassDB::bind_method(D_METHOD("play", "from_position"), &AudioStreamPlayer::play, DEFVAL(0.0)); + ClassDB::bind_method(D_METHOD("seek", "to_position"), &AudioStreamPlayer::seek); + ClassDB::bind_method(D_METHOD("stop"), &AudioStreamPlayer::stop); + + ClassDB::bind_method(D_METHOD("is_playing"), &AudioStreamPlayer::is_playing); + ClassDB::bind_method(D_METHOD("get_playback_position"), &AudioStreamPlayer::get_playback_position); + + ClassDB::bind_method(D_METHOD("set_bus", "bus"), &AudioStreamPlayer::set_bus); + ClassDB::bind_method(D_METHOD("get_bus"), &AudioStreamPlayer::get_bus); + + ClassDB::bind_method(D_METHOD("set_autoplay", "enable"), &AudioStreamPlayer::set_autoplay); + ClassDB::bind_method(D_METHOD("is_autoplay_enabled"), &AudioStreamPlayer::is_autoplay_enabled); + + ClassDB::bind_method(D_METHOD("set_mix_target", "mix_target"), &AudioStreamPlayer::set_mix_target); + ClassDB::bind_method(D_METHOD("get_mix_target"), &AudioStreamPlayer::get_mix_target); + + ClassDB::bind_method(D_METHOD("_set_playing", "enable"), &AudioStreamPlayer::_set_playing); + ClassDB::bind_method(D_METHOD("_is_active"), &AudioStreamPlayer::_is_active); + + ClassDB::bind_method(D_METHOD("_bus_layout_changed"), &AudioStreamPlayer::_bus_layout_changed); + + 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); + + 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"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_playing", "is_playing"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "autoplay"), "set_autoplay", "is_autoplay_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "stream_paused", PROPERTY_HINT_NONE, ""), "set_stream_paused", "get_stream_paused"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "mix_target", PROPERTY_HINT_ENUM, "Stereo,Surround,Center"), "set_mix_target", "get_mix_target"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "bus", PROPERTY_HINT_ENUM, ""), "set_bus", "get_bus"); + + ADD_SIGNAL(MethodInfo("finished")); + + BIND_ENUM_CONSTANT(MIX_TARGET_STEREO); + BIND_ENUM_CONSTANT(MIX_TARGET_SURROUND); + BIND_ENUM_CONSTANT(MIX_TARGET_CENTER); +} + +AudioStreamPlayer::AudioStreamPlayer() { + + mix_volume_db = 0; + pitch_scale = 1.0; + volume_db = 0; + autoplay = false; + setseek = -1; + active = false; + stream_paused = false; + stream_paused_fade = false; + mix_target = MIX_TARGET_STEREO; + + AudioServer::get_singleton()->connect("bus_layout_changed", this, "_bus_layout_changed"); +} + +AudioStreamPlayer::~AudioStreamPlayer() { +} diff --git a/scene/audio/audio_stream_player.h b/scene/audio/audio_stream_player.h new file mode 100644 index 0000000000..0f7713bf33 --- /dev/null +++ b/scene/audio/audio_stream_player.h @@ -0,0 +1,114 @@ +/*************************************************************************/ +/* audio_stream_player.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef AUDIO_STREAM_PLAYER_H +#define AUDIO_STREAM_PLAYER_H + +#include "scene/main/node.h" +#include "servers/audio/audio_stream.h" + +class AudioStreamPlayer : public Node { + + GDCLASS(AudioStreamPlayer, Node) + +public: + enum MixTarget { + MIX_TARGET_STEREO, + MIX_TARGET_SURROUND, + MIX_TARGET_CENTER + }; + +private: + Ref stream_playback; + Ref stream; + Vector mix_buffer; + + volatile float setseek; + volatile bool active; + + float mix_volume_db; + float pitch_scale; + float volume_db; + bool autoplay; + bool stream_paused; + bool stream_paused_fade; + StringName bus; + + MixTarget mix_target; + + void _mix_internal(bool p_fadeout); + void _mix_audio(); + static void _mix_audios(void *self) { reinterpret_cast(self)->_mix_audio(); } + + void _set_playing(bool p_enable); + bool _is_active() const; + + void _bus_layout_changed(); + +protected: + void _validate_property(PropertyInfo &property) const; + void _notification(int p_what); + static void _bind_methods(); + +public: + void set_stream(Ref p_stream); + Ref get_stream() const; + + void set_volume_db(float p_volume); + float get_volume_db() const; + + void set_pitch_scale(float p_pitch_scale); + float get_pitch_scale() const; + + void play(float p_from_pos = 0.0); + void seek(float p_seconds); + void stop(); + bool is_playing() const; + float get_playback_position(); + + void set_bus(const StringName &p_bus); + StringName get_bus() const; + + void set_autoplay(bool p_enable); + bool is_autoplay_enabled(); + + void set_mix_target(MixTarget p_target); + MixTarget get_mix_target() const; + + void set_stream_paused(bool p_pause); + bool get_stream_paused() const; + + AudioStreamPlayer(); + ~AudioStreamPlayer(); +}; + +VARIANT_ENUM_CAST(AudioStreamPlayer::MixTarget) + +#endif // AUDIO_STREAM_PLAYER_H -- cgit v1.2.3