From 90762b9660d613841bd58659621c2ac1ccd1b790 Mon Sep 17 00:00:00 2001 From: Marcin Nowak Date: Thu, 18 Aug 2022 17:34:12 +0200 Subject: [PATCH] [3.x] Backport panning strength parameters from 4.0 --- core/project_settings.cpp | 4 ++++ doc/classes/AudioStreamPlayer2D.xml | 3 +++ doc/classes/AudioStreamPlayer3D.xml | 3 +++ doc/classes/ProjectSettings.xml | 6 ++++++ scene/2d/audio_stream_player_2d.cpp | 24 +++++++++++++++++++++++- scene/2d/audio_stream_player_2d.h | 6 ++++++ scene/3d/audio_stream_player_3d.cpp | 22 +++++++++++++++++++--- scene/3d/audio_stream_player_3d.h | 6 ++++++ 8 files changed, 70 insertions(+), 4 deletions(-) diff --git a/core/project_settings.cpp b/core/project_settings.cpp index f75b7c9d97a..e17549198aa 100644 --- a/core/project_settings.cpp +++ b/core/project_settings.cpp @@ -1085,6 +1085,10 @@ ProjectSettings::ProjectSettings() { GLOBAL_DEF("audio/default_bus_layout", "res://default_bus_layout.tres"); custom_prop_info["audio/default_bus_layout"] = PropertyInfo(Variant::STRING, "audio/default_bus_layout", PROPERTY_HINT_FILE, "*.tres"); + GLOBAL_DEF_RST("audio/2d_panning_strength", 1.0f); + custom_prop_info["audio/2d_panning_strength"] = PropertyInfo(Variant::REAL, "audio/2d_panning_strength", PROPERTY_HINT_RANGE, "0,4,0.01"); + GLOBAL_DEF_RST("audio/3d_panning_strength", 1.0f); + custom_prop_info["audio/3d_panning_strength"] = PropertyInfo(Variant::REAL, "audio/3d_panning_strength", PROPERTY_HINT_RANGE, "0,4,0.01"); PoolStringArray extensions = PoolStringArray(); extensions.push_back("gd"); diff --git a/doc/classes/AudioStreamPlayer2D.xml b/doc/classes/AudioStreamPlayer2D.xml index 2ffaeb7f2e5..504cb5c9b5b 100644 --- a/doc/classes/AudioStreamPlayer2D.xml +++ b/doc/classes/AudioStreamPlayer2D.xml @@ -62,6 +62,9 @@ Maximum distance from which audio is still hearable. + + Scales the panning strength for this node by multiplying the base [member ProjectSettings.audio/2d_panning_strength] with this factor. Higher values will pan audio from left to right more dramatically than lower values. + The pitch and the tempo of the audio, as a multiplier of the audio sample's sample rate. diff --git a/doc/classes/AudioStreamPlayer3D.xml b/doc/classes/AudioStreamPlayer3D.xml index e9286ab4216..fba2eea2f82 100644 --- a/doc/classes/AudioStreamPlayer3D.xml +++ b/doc/classes/AudioStreamPlayer3D.xml @@ -88,6 +88,9 @@ Decides if audio should pause when source is outside of [member max_distance] range. + + Scales the panning strength for this node by multiplying the base [member ProjectSettings.audio/3d_panning_strength] with this factor. Higher values will pan audio from left to right more dramatically than lower values. + The pitch and the tempo of the audio, as a multiplier of the audio sample's sample rate. diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index de61488de23..0ef32cf1d15 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -259,6 +259,12 @@ Path to the main scene file that will be loaded when the project runs. + + The base strength of the panning effect for all AudioStreamPlayer2D nodes. The panning strength can be further scaled on each Node using [member AudioStreamPlayer2D.panning_strength]. + + + The base strength of the panning effect for all AudioStreamPlayer3D nodes. The panning strength can be further scaled on each Node using [member AudioStreamPlayer3D.panning_strength]. + Audio buses will disable automatically when sound goes below a given dB threshold for a given time. This saves CPU as effects assigned to that bus will no longer do any processing. diff --git a/scene/2d/audio_stream_player_2d.cpp b/scene/2d/audio_stream_player_2d.cpp index 5dc61439a38..9b069609835 100644 --- a/scene/2d/audio_stream_player_2d.cpp +++ b/scene/2d/audio_stream_player_2d.cpp @@ -31,6 +31,7 @@ #include "audio_stream_player_2d.h" #include "core/engine.h" +#include "core/project_settings.h" #include "scene/2d/area_2d.h" #include "scene/2d/listener_2d.h" #include "scene/main/viewport.h" @@ -232,7 +233,14 @@ void AudioStreamPlayer2D::_notification(int p_what) { float multiplier = Math::pow(1.0f - dist / max_distance, attenuation); multiplier *= Math::db2linear(volume_db); //also apply player volume! - float pan = CLAMP((relative_to_listener.x + screen_size.x * 0.5) / screen_size.x, 0.0, 1.0); + float pan = relative_to_listener.x / screen_size.x; + // Don't let the panning effect extend (too far) beyond the screen. + pan = CLAMP(pan, -1, 1); + + // Bake in a constant factor here to allow the project setting defaults for 2d and 3d to be normalized to 1.0. + pan *= panning_strength * cached_global_panning_strength * 0.5f; + + pan = CLAMP(pan + 0.5, 0.0, 1.0); float l = 1.0 - pan; float r = pan; @@ -458,6 +466,15 @@ Ref AudioStreamPlayer2D::get_stream_playback() { return stream_playback; } +void AudioStreamPlayer2D::set_panning_strength(float p_panning_strength) { + ERR_FAIL_COND_MSG(p_panning_strength < 0, "Panning strength must be a positive number."); + panning_strength = p_panning_strength; +} + +float AudioStreamPlayer2D::get_panning_strength() const { + return panning_strength; +} + void AudioStreamPlayer2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_stream", "stream"), &AudioStreamPlayer2D::set_stream); ClassDB::bind_method(D_METHOD("get_stream"), &AudioStreamPlayer2D::get_stream); @@ -496,6 +513,9 @@ void AudioStreamPlayer2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_stream_paused", "pause"), &AudioStreamPlayer2D::set_stream_paused); ClassDB::bind_method(D_METHOD("get_stream_paused"), &AudioStreamPlayer2D::get_stream_paused); + ClassDB::bind_method(D_METHOD("set_panning_strength", "panning_strength"), &AudioStreamPlayer2D::set_panning_strength); + ClassDB::bind_method(D_METHOD("get_panning_strength"), &AudioStreamPlayer2D::get_panning_strength); + ClassDB::bind_method(D_METHOD("get_stream_playback"), &AudioStreamPlayer2D::get_stream_playback); ClassDB::bind_method(D_METHOD("_bus_layout_changed"), &AudioStreamPlayer2D::_bus_layout_changed); @@ -508,6 +528,7 @@ void AudioStreamPlayer2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "stream_paused", PROPERTY_HINT_NONE, ""), "set_stream_paused", "get_stream_paused"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_distance", PROPERTY_HINT_EXP_RANGE, "1,4096,1,or_greater"), "set_max_distance", "get_max_distance"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "attenuation", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_attenuation", "get_attenuation"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "panning_strength", PROPERTY_HINT_RANGE, "0,3,0.01,or_greater"), "set_panning_strength", "get_panning_strength"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "bus", PROPERTY_HINT_ENUM, ""), "set_bus", "get_bus"); ADD_PROPERTY(PropertyInfo(Variant::INT, "area_mask", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_area_mask", "get_area_mask"); @@ -528,6 +549,7 @@ AudioStreamPlayer2D::AudioStreamPlayer2D() { stream_paused_fade_in = false; stream_paused_fade_out = false; AudioServer::get_singleton()->connect("bus_layout_changed", this, "_bus_layout_changed"); + cached_global_panning_strength = ProjectSettings::get_singleton()->get("audio/2d_panning_strength"); } AudioStreamPlayer2D::~AudioStreamPlayer2D() { diff --git a/scene/2d/audio_stream_player_2d.h b/scene/2d/audio_stream_player_2d.h index 4829500c35c..042fa6ed48b 100644 --- a/scene/2d/audio_stream_player_2d.h +++ b/scene/2d/audio_stream_player_2d.h @@ -89,6 +89,9 @@ private: float max_distance; float attenuation; + float panning_strength = 1.0f; + float cached_global_panning_strength = 1.0f; + protected: void _validate_property(PropertyInfo &property) const; void _notification(int p_what); @@ -122,6 +125,9 @@ public: void set_attenuation(float p_curve); float get_attenuation() const; + void set_panning_strength(float p_panning_strength); + float get_panning_strength() const; + void set_area_mask(uint32_t p_mask); uint32_t get_area_mask() const; diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp index 31cd574950f..07ccdb1ebe9 100644 --- a/scene/3d/audio_stream_player_3d.cpp +++ b/scene/3d/audio_stream_player_3d.cpp @@ -30,6 +30,7 @@ #include "audio_stream_player_3d.h" #include "core/engine.h" +#include "core/project_settings.h" #include "scene/3d/area.h" #include "scene/3d/camera.h" #include "scene/3d/listener.h" @@ -471,9 +472,10 @@ void AudioStreamPlayer3D::_notification(int p_what) { output.filter_gain = Math::db2linear(db_att); - //TODO: The lower the second parameter (tightness) the more the sound will "enclose" the listener (more undirected / playing from - // speakers not facing the source) - this could be made distance dependent. - _calc_output_vol(local_pos.normalized(), 4.0, output); + // Bake in a constant factor here to allow the project setting defaults for 2d and 3d to be normalized to 1.0. + float tightness = cached_global_panning_strength * 2.0f; + tightness *= panning_strength; + _calc_output_vol(local_pos.normalized(), tightness, output); unsigned int cc = AudioServer::get_singleton()->get_channel_count(); for (unsigned int k = 0; k < cc; k++) { @@ -898,6 +900,15 @@ Ref AudioStreamPlayer3D::get_stream_playback() { return stream_playback; } +void AudioStreamPlayer3D::set_panning_strength(float p_panning_strength) { + ERR_FAIL_COND_MSG(p_panning_strength < 0, "Panning strength must be a positive number."); + panning_strength = p_panning_strength; +} + +float AudioStreamPlayer3D::get_panning_strength() const { + return panning_strength; +} + void AudioStreamPlayer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_stream", "stream"), &AudioStreamPlayer3D::set_stream); ClassDB::bind_method(D_METHOD("get_stream"), &AudioStreamPlayer3D::get_stream); @@ -963,6 +974,9 @@ void AudioStreamPlayer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_stream_paused", "pause"), &AudioStreamPlayer3D::set_stream_paused); ClassDB::bind_method(D_METHOD("get_stream_paused"), &AudioStreamPlayer3D::get_stream_paused); + ClassDB::bind_method(D_METHOD("set_panning_strength", "panning_strength"), &AudioStreamPlayer3D::set_panning_strength); + ClassDB::bind_method(D_METHOD("get_panning_strength"), &AudioStreamPlayer3D::get_panning_strength); + ClassDB::bind_method(D_METHOD("get_stream_playback"), &AudioStreamPlayer3D::get_stream_playback); ClassDB::bind_method(D_METHOD("_bus_layout_changed"), &AudioStreamPlayer3D::_bus_layout_changed); @@ -978,6 +992,7 @@ void AudioStreamPlayer3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "stream_paused", PROPERTY_HINT_NONE, ""), "set_stream_paused", "get_stream_paused"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_distance", PROPERTY_HINT_RANGE, "0,4096,0.01,or_greater"), "set_max_distance", "get_max_distance"); ADD_PROPERTY(PropertyInfo(Variant::INT, "out_of_range_mode", PROPERTY_HINT_ENUM, "Mix,Pause"), "set_out_of_range_mode", "get_out_of_range_mode"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "panning_strength", PROPERTY_HINT_RANGE, "0,3,0.01,or_greater"), "set_panning_strength", "get_panning_strength"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "bus", PROPERTY_HINT_ENUM, ""), "set_bus", "get_bus"); ADD_PROPERTY(PropertyInfo(Variant::INT, "area_mask", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_area_mask", "get_area_mask"); ADD_GROUP("Emission Angle", "emission_angle"); @@ -1031,6 +1046,7 @@ AudioStreamPlayer3D::AudioStreamPlayer3D() { velocity_tracker.instance(); AudioServer::get_singleton()->connect("bus_layout_changed", this, "_bus_layout_changed"); set_disable_scale(true); + cached_global_panning_strength = ProjectSettings::get_singleton()->get("audio/3d_panning_strength"); } AudioStreamPlayer3D::~AudioStreamPlayer3D() { } diff --git a/scene/3d/audio_stream_player_3d.h b/scene/3d/audio_stream_player_3d.h index b4429a988a1..4f301974ad0 100644 --- a/scene/3d/audio_stream_player_3d.h +++ b/scene/3d/audio_stream_player_3d.h @@ -141,6 +141,9 @@ private: float _get_attenuation_db(float p_distance) const; + float panning_strength = 1.0f; + float cached_global_panning_strength = 1.0f; + protected: void _validate_property(PropertyInfo &property) const; void _notification(int p_what); @@ -207,6 +210,9 @@ public: void set_stream_paused(bool p_pause); bool get_stream_paused() const; + void set_panning_strength(float p_panning_strength); + float get_panning_strength() const; + Ref get_stream_playback(); AudioStreamPlayer3D();