Audio: Expose 2D/3D panning strength parameters

This commit is contained in:
Ellen Poe 2022-03-06 08:53:56 -08:00 committed by Rémi Verschelde
parent 78944fef82
commit d384d84f45
8 changed files with 70 additions and 4 deletions

View File

@ -1200,6 +1200,10 @@ ProjectSettings::ProjectSettings() {
GLOBAL_DEF_BASIC("audio/buses/default_bus_layout", "res://default_bus_layout.tres");
custom_prop_info["audio/buses/default_bus_layout"] = PropertyInfo(Variant::STRING, "audio/buses/default_bus_layout", PROPERTY_HINT_FILE, "*.tres");
GLOBAL_DEF_RST("audio/general/2d_panning_strength", 1.0f);
custom_prop_info["audio/general/2d_panning_strength"] = PropertyInfo(Variant::FLOAT, "audio/general/2d_panning_strength", PROPERTY_HINT_RANGE, "0,4,0.01");
GLOBAL_DEF_RST("audio/general/3d_panning_strength", 1.0f);
custom_prop_info["audio/general/3d_panning_strength"] = PropertyInfo(Variant::FLOAT, "audio/general/3d_panning_strength", PROPERTY_HINT_RANGE, "0,4,0.01");
PackedStringArray extensions = PackedStringArray();
extensions.push_back("gd");

View File

@ -64,6 +64,9 @@
<member name="max_polyphony" type="int" setter="set_max_polyphony" getter="get_max_polyphony" default="1">
The maximum number of sounds this node can play at the same time. Playing additional sounds after this value is reached will cut off the oldest sounds.
</member>
<member name="panning_strength" type="float" setter="set_panning_strength" getter="get_panning_strength" default="1.0">
Scales the panning strength for this node by multiplying the base [member ProjectSettings.audio/general/2d_panning_strength] with this factor. Higher values will pan audio from left to right more dramatically than lower values.
</member>
<member name="pitch_scale" type="float" setter="set_pitch_scale" getter="get_pitch_scale" default="1.0">
The pitch and the tempo of the audio, as a multiplier of the audio sample's sample rate.
</member>

View File

@ -86,6 +86,9 @@
<member name="max_polyphony" type="int" setter="set_max_polyphony" getter="get_max_polyphony" default="1">
The maximum number of sounds this node can play at the same time. Playing additional sounds after this value is reached will cut off the oldest sounds.
</member>
<member name="panning_strength" type="float" setter="set_panning_strength" getter="get_panning_strength" default="1.0">
Scales the panning strength for this node by multiplying the base [member ProjectSettings.audio/general/3d_panning_strength] with this factor. Higher values will pan audio from left to right more dramatically than lower values.
</member>
<member name="pitch_scale" type="float" setter="set_pitch_scale" getter="get_pitch_scale" default="1.0">
The pitch and the tempo of the audio, as a multiplier of the audio sample's sample rate.
</member>

View File

@ -307,6 +307,12 @@
<member name="audio/driver/output_latency.web" type="int" setter="" getter="" default="50">
Safer override for [member audio/driver/output_latency] in the Web platform, to avoid audio issues especially on mobile devices.
</member>
<member name="audio/general/2d_panning_strength" type="float" setter="" getter="" default="1.0">
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].
</member>
<member name="audio/general/3d_panning_strength" type="float" setter="" getter="" default="1.0">
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].
</member>
<member name="audio/video/video_delay_compensation_ms" type="int" setter="" getter="" default="0">
Setting to hardcode audio delay when playing video. Best to leave this untouched unless you know what you are doing.
</member>

View File

@ -30,6 +30,7 @@
#include "audio_stream_player_2d.h"
#include "core/config/project_settings.h"
#include "scene/2d/area_2d.h"
#include "scene/2d/audio_listener_2d.h"
#include "scene/main/window.h"
@ -186,7 +187,14 @@ void AudioStreamPlayer2D::_update_panning() {
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;
@ -391,6 +399,15 @@ int AudioStreamPlayer2D::get_max_polyphony() const {
return max_polyphony;
}
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);
@ -432,6 +449,9 @@ void AudioStreamPlayer2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_max_polyphony", "max_polyphony"), &AudioStreamPlayer2D::set_max_polyphony);
ClassDB::bind_method(D_METHOD("get_max_polyphony"), &AudioStreamPlayer2D::get_max_polyphony);
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);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "stream", PROPERTY_HINT_RESOURCE_TYPE, "AudioStream"), "set_stream", "get_stream");
@ -443,6 +463,7 @@ void AudioStreamPlayer2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_distance", PROPERTY_HINT_RANGE, "1,4096,1,or_greater,exp,suffix:px"), "set_max_distance", "get_max_distance");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "attenuation", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_attenuation", "get_attenuation");
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_polyphony", PROPERTY_HINT_NONE, ""), "set_max_polyphony", "get_max_polyphony");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "panning_strength", PROPERTY_HINT_RANGE, "0,3,0.01,or_greater"), "set_panning_strength", "get_panning_strength");
ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "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");
@ -451,6 +472,7 @@ void AudioStreamPlayer2D::_bind_methods() {
AudioStreamPlayer2D::AudioStreamPlayer2D() {
AudioServer::get_singleton()->connect("bus_layout_changed", callable_mp(this, &AudioStreamPlayer2D::_bus_layout_changed));
cached_global_panning_strength = ProjectSettings::get_singleton()->get("audio/general/2d_panning_strength");
}
AudioStreamPlayer2D::~AudioStreamPlayer2D() {

View File

@ -81,6 +81,9 @@ private:
float max_distance = 2000.0;
float attenuation = 1.0;
float panning_strength = 1.0f;
float cached_global_panning_strength = 1.0f;
protected:
void _validate_property(PropertyInfo &property) const override;
void _notification(int p_what);
@ -123,6 +126,9 @@ public:
void set_max_polyphony(int p_max_polyphony);
int get_max_polyphony() const;
void set_panning_strength(float p_panning_strength);
float get_panning_strength() const;
Ref<AudioStreamPlayback> get_stream_playback();
AudioStreamPlayer2D();

View File

@ -30,6 +30,7 @@
#include "audio_stream_player_3d.h"
#include "core/config/project_settings.h"
#include "scene/3d/area_3d.h"
#include "scene/3d/audio_listener_3d.h"
#include "scene/3d/camera_3d.h"
@ -462,9 +463,10 @@ Vector<AudioFrame> AudioStreamPlayer3D::_update_panning() {
for (Ref<AudioStreamPlayback> &playback : stream_playbacks) {
AudioServer::get_singleton()->set_playback_highshelf_params(playback, linear_attenuation, attenuation_filter_cutoff_hz);
}
//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_volume_vector);
// 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_volume_vector);
for (unsigned int k = 0; k < 4; k++) {
output_volume_vector.write[k] = multiplier * output_volume_vector[k];
@ -792,6 +794,15 @@ int AudioStreamPlayer3D::get_max_polyphony() const {
return max_polyphony;
}
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);
@ -857,6 +868,9 @@ void AudioStreamPlayer3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_max_polyphony", "max_polyphony"), &AudioStreamPlayer3D::set_max_polyphony);
ClassDB::bind_method(D_METHOD("get_max_polyphony"), &AudioStreamPlayer3D::get_max_polyphony);
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);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "stream", PROPERTY_HINT_RESOURCE_TYPE, "AudioStream"), "set_stream", "get_stream");
@ -870,6 +884,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::FLOAT, "max_distance", PROPERTY_HINT_RANGE, "0,4096,0.01,or_greater,suffix:m"), "set_max_distance", "get_max_distance");
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_polyphony", PROPERTY_HINT_NONE, ""), "set_max_polyphony", "get_max_polyphony");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "panning_strength", PROPERTY_HINT_RANGE, "0,3,0.01,or_greater"), "set_panning_strength", "get_panning_strength");
ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "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");
@ -898,6 +913,7 @@ AudioStreamPlayer3D::AudioStreamPlayer3D() {
velocity_tracker.instantiate();
AudioServer::get_singleton()->connect("bus_layout_changed", callable_mp(this, &AudioStreamPlayer3D::_bus_layout_changed));
set_disable_scale(true);
cached_global_panning_strength = ProjectSettings::get_singleton()->get("audio/general/3d_panning_strength");
}
AudioStreamPlayer3D::~AudioStreamPlayer3D() {

View File

@ -116,6 +116,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 override;
void _notification(int p_what);
@ -182,6 +185,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<AudioStreamPlayback> get_stream_playback();
AudioStreamPlayer3D();