| 
									
										
										
										
											2018-01-05 00:50:27 +01:00
										 |  |  | /**************************************************************************/ | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | /*  audio_stream_player_3d.cpp                                            */ | 
					
						
							| 
									
										
										
										
											2018-01-05 00:50:27 +01:00
										 |  |  | /**************************************************************************/ | 
					
						
							| 
									
										
										
										
											2017-09-06 22:03:04 -03:00
										 |  |  | /*                         This file is part of:                          */ | 
					
						
							| 
									
										
										
										
											2018-01-05 00:50:27 +01:00
										 |  |  | /*                             GODOT ENGINE                               */ | 
					
						
							|  |  |  | /*                        https://godotengine.org                         */ | 
					
						
							|  |  |  | /**************************************************************************/ | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ | 
					
						
							|  |  |  | /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.                  */ | 
					
						
							| 
									
										
										
										
											2018-01-05 00:50:27 +01:00
										 |  |  | /*                                                                        */ | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | /* 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    */ | 
					
						
							| 
									
										
										
										
											2017-09-06 22:03:04 -03:00
										 |  |  | /* 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  */ | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | /* the following conditions:                                              */ | 
					
						
							| 
									
										
										
										
											2018-01-05 00:50:27 +01:00
										 |  |  | /*                                                                        */ | 
					
						
							| 
									
										
										
										
											2017-09-06 22:03:04 -03:00
										 |  |  | /* The above copyright notice and this permission notice shall be         */ | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | /* included in all copies or substantial portions of the Software.        */ | 
					
						
							| 
									
										
										
										
											2018-01-05 00:50:27 +01:00
										 |  |  | /*                                                                        */ | 
					
						
							| 
									
										
										
										
											2017-09-06 22:03:04 -03:00
										 |  |  | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,        */ | 
					
						
							|  |  |  | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF     */ | 
					
						
							| 
									
										
										
										
											2017-08-22 18:27:17 -03:00
										 |  |  | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ | 
					
						
							| 
									
										
										
										
											2017-09-06 22:03:04 -03:00
										 |  |  | /* 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.                 */ | 
					
						
							| 
									
										
										
										
											2018-01-05 00:50:27 +01:00
										 |  |  | /**************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | #include "audio_stream_player_3d.h"
 | 
					
						
							| 
									
										
										
										
											2024-01-06 20:29:43 -06:00
										 |  |  | #include "audio_stream_player_3d.compat.inc"
 | 
					
						
							| 
									
										
										
										
											2020-03-27 16:04:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-06 08:53:56 -08:00
										 |  |  | #include "core/config/project_settings.h"
 | 
					
						
							| 
									
										
										
										
											2021-09-16 15:28:20 -04:00
										 |  |  | #include "scene/3d/audio_listener_3d.h"
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | #include "scene/3d/camera_3d.h"
 | 
					
						
							| 
									
										
										
										
											2024-02-26 07:15:31 +01:00
										 |  |  | #include "scene/3d/physics/area_3d.h"
 | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | #include "scene/3d/velocity_tracker_3d.h"
 | 
					
						
							|  |  |  | #include "scene/audio/audio_stream_player_internal.h"
 | 
					
						
							| 
									
										
										
										
											2021-08-12 18:05:59 -05:00
										 |  |  | #include "scene/main/viewport.h"
 | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | #include "servers/audio/audio_stream.h"
 | 
					
						
							| 
									
										
										
										
											2023-12-23 17:30:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-01 22:35:07 +02:00
										 |  |  | // Based on "A Novel Multichannel Panning Method for Standard and Arbitrary Loudspeaker Configurations" by Ramy Sadek and Chris Kyriakakis (2004)
 | 
					
						
							|  |  |  | // Speaker-Placement Correction Amplitude Panning (SPCAP)
 | 
					
						
							|  |  |  | class Spcap { | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  | 	struct Speaker { | 
					
						
							|  |  |  | 		Vector3 direction; | 
					
						
							| 
									
										
										
										
											2021-02-07 22:29:31 +01:00
										 |  |  | 		real_t effective_number_of_speakers = 0; // precalculated
 | 
					
						
							|  |  |  | 		mutable real_t squared_gain = 0; // temporary
 | 
					
						
							| 
									
										
										
										
											2019-07-01 22:35:07 +02:00
										 |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 	Vector<Speaker> speakers; | 
					
						
							| 
									
										
										
										
											2019-07-01 22:35:07 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  | 	Spcap(unsigned int speaker_count, const Vector3 *speaker_directions) { | 
					
						
							| 
									
										
										
										
											2024-01-28 21:51:39 +01:00
										 |  |  | 		speakers.resize(speaker_count); | 
					
						
							|  |  |  | 		Speaker *w = speakers.ptrw(); | 
					
						
							| 
									
										
										
										
											2019-07-01 22:35:07 +02:00
										 |  |  | 		for (unsigned int speaker_num = 0; speaker_num < speaker_count; speaker_num++) { | 
					
						
							|  |  |  | 			w[speaker_num].direction = speaker_directions[speaker_num]; | 
					
						
							|  |  |  | 			w[speaker_num].squared_gain = 0.0; | 
					
						
							|  |  |  | 			w[speaker_num].effective_number_of_speakers = 0.0; | 
					
						
							|  |  |  | 			for (unsigned int other_speaker_num = 0; other_speaker_num < speaker_count; other_speaker_num++) { | 
					
						
							|  |  |  | 				w[speaker_num].effective_number_of_speakers += 0.5 * (1.0 + w[speaker_num].direction.dot(w[other_speaker_num].direction)); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	unsigned int get_speaker_count() const { | 
					
						
							| 
									
										
										
										
											2024-01-28 21:51:39 +01:00
										 |  |  | 		return (unsigned int)speakers.size(); | 
					
						
							| 
									
										
										
										
											2019-07-01 22:35:07 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Vector3 get_speaker_direction(unsigned int index) const { | 
					
						
							| 
									
										
										
										
											2024-01-28 21:51:39 +01:00
										 |  |  | 		return speakers.ptr()[index].direction; | 
					
						
							| 
									
										
										
										
											2019-07-01 22:35:07 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	void calculate(const Vector3 &source_direction, real_t tightness, unsigned int volume_count, real_t *volumes) const { | 
					
						
							| 
									
										
										
										
											2024-01-28 21:51:39 +01:00
										 |  |  | 		const Speaker *r = speakers.ptr(); | 
					
						
							| 
									
										
										
										
											2019-07-01 22:35:07 +02:00
										 |  |  | 		real_t sum_squared_gains = 0.0; | 
					
						
							| 
									
										
										
										
											2024-01-28 21:51:39 +01:00
										 |  |  | 		for (unsigned int speaker_num = 0; speaker_num < (unsigned int)speakers.size(); speaker_num++) { | 
					
						
							| 
									
										
										
										
											2019-07-01 22:35:07 +02:00
										 |  |  | 			real_t initial_gain = 0.5 * powf(1.0 + r[speaker_num].direction.dot(source_direction), tightness) / r[speaker_num].effective_number_of_speakers; | 
					
						
							|  |  |  | 			r[speaker_num].squared_gain = initial_gain * initial_gain; | 
					
						
							|  |  |  | 			sum_squared_gains += r[speaker_num].squared_gain; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-28 21:51:39 +01:00
										 |  |  | 		for (unsigned int speaker_num = 0; speaker_num < MIN(volume_count, (unsigned int)speakers.size()); speaker_num++) { | 
					
						
							| 
									
										
										
										
											2019-07-01 22:35:07 +02:00
										 |  |  | 			volumes[speaker_num] = sqrtf(r[speaker_num].squared_gain / sum_squared_gains); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //TODO: hardcoded main speaker directions for 2, 3.1, 5.1 and 7.1 setups - these are simplified and could also be made configurable
 | 
					
						
							|  |  |  | static const Vector3 speaker_directions[7] = { | 
					
						
							|  |  |  | 	Vector3(-1.0, 0.0, -1.0).normalized(), // front-left
 | 
					
						
							|  |  |  | 	Vector3(1.0, 0.0, -1.0).normalized(), // front-right
 | 
					
						
							|  |  |  | 	Vector3(0.0, 0.0, -1.0).normalized(), // center
 | 
					
						
							|  |  |  | 	Vector3(-1.0, 0.0, 1.0).normalized(), // rear-left
 | 
					
						
							|  |  |  | 	Vector3(1.0, 0.0, 1.0).normalized(), // rear-right
 | 
					
						
							|  |  |  | 	Vector3(-1.0, 0.0, 0.0).normalized(), // side-left
 | 
					
						
							|  |  |  | 	Vector3(1.0, 0.0, 0.0).normalized(), // side-right
 | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | void AudioStreamPlayer3D::_calc_output_vol(const Vector3 &source_dir, real_t tightness, Vector<AudioFrame> &output) { | 
					
						
							| 
									
										
										
										
											2020-03-27 16:04:01 +01:00
										 |  |  | 	unsigned int speaker_count = 0; // only main speakers (no LFE)
 | 
					
						
							| 
									
										
										
										
											2019-07-01 22:35:07 +02:00
										 |  |  | 	switch (AudioServer::get_singleton()->get_speaker_mode()) { | 
					
						
							| 
									
										
										
										
											2020-02-22 20:47:50 +01:00
										 |  |  | 		case AudioServer::SPEAKER_MODE_STEREO: | 
					
						
							|  |  |  | 			speaker_count = 2; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case AudioServer::SPEAKER_SURROUND_31: | 
					
						
							|  |  |  | 			speaker_count = 3; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case AudioServer::SPEAKER_SURROUND_51: | 
					
						
							|  |  |  | 			speaker_count = 5; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case AudioServer::SPEAKER_SURROUND_71: | 
					
						
							|  |  |  | 			speaker_count = 7; | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2019-07-01 22:35:07 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Spcap spcap(speaker_count, speaker_directions); //TODO: should only be created/recreated once the speaker mode / speaker positions changes
 | 
					
						
							|  |  |  | 	real_t volumes[7]; | 
					
						
							|  |  |  | 	spcap.calculate(source_dir, tightness, speaker_count, volumes); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (AudioServer::get_singleton()->get_speaker_mode()) { | 
					
						
							|  |  |  | 		case AudioServer::SPEAKER_SURROUND_71: | 
					
						
							| 
									
										
										
										
											2024-01-09 15:01:12 +01:00
										 |  |  | 			output.write[3].left = volumes[5]; // side-left
 | 
					
						
							|  |  |  | 			output.write[3].right = volumes[6]; // side-right
 | 
					
						
							| 
									
										
										
										
											2020-02-22 20:47:50 +01:00
										 |  |  | 			[[fallthrough]]; | 
					
						
							| 
									
										
										
										
											2019-07-01 22:35:07 +02:00
										 |  |  | 		case AudioServer::SPEAKER_SURROUND_51: | 
					
						
							| 
									
										
										
										
											2024-01-09 15:01:12 +01:00
										 |  |  | 			output.write[2].left = volumes[3]; // rear-left
 | 
					
						
							|  |  |  | 			output.write[2].right = volumes[4]; // rear-right
 | 
					
						
							| 
									
										
										
										
											2020-02-22 20:47:50 +01:00
										 |  |  | 			[[fallthrough]]; | 
					
						
							| 
									
										
										
										
											2019-07-01 22:35:07 +02:00
										 |  |  | 		case AudioServer::SPEAKER_SURROUND_31: | 
					
						
							| 
									
										
										
										
											2024-01-09 15:01:12 +01:00
										 |  |  | 			output.write[1].right = 1.0; // LFE - always full power
 | 
					
						
							|  |  |  | 			output.write[1].left = volumes[2]; // center
 | 
					
						
							| 
									
										
										
										
											2020-02-22 20:47:50 +01:00
										 |  |  | 			[[fallthrough]]; | 
					
						
							| 
									
										
										
										
											2019-07-01 22:35:07 +02:00
										 |  |  | 		case AudioServer::SPEAKER_MODE_STEREO: | 
					
						
							| 
									
										
										
										
											2024-01-09 15:01:12 +01:00
										 |  |  | 			output.write[0].right = volumes[1]; // front-right
 | 
					
						
							|  |  |  | 			output.write[0].left = volumes[0]; // front-left
 | 
					
						
							| 
									
										
										
										
											2020-02-22 20:47:50 +01:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2019-07-01 22:35:07 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | void AudioStreamPlayer3D::_calc_reverb_vol(Area3D *area, Vector3 listener_area_pos, Vector<AudioFrame> direct_path_vol, Vector<AudioFrame> &reverb_vol) { | 
					
						
							|  |  |  | 	reverb_vol.resize(4); | 
					
						
							|  |  |  | 	reverb_vol.write[0] = AudioFrame(0, 0); | 
					
						
							|  |  |  | 	reverb_vol.write[1] = AudioFrame(0, 0); | 
					
						
							|  |  |  | 	reverb_vol.write[2] = AudioFrame(0, 0); | 
					
						
							|  |  |  | 	reverb_vol.write[3] = AudioFrame(0, 0); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | 	float uniformity = area->get_reverb_uniformity(); | 
					
						
							|  |  |  | 	float area_send = area->get_reverb_amount(); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | 	if (uniformity > 0.0) { | 
					
						
							|  |  |  | 		float distance = listener_area_pos.length(); | 
					
						
							| 
									
										
										
										
											2022-08-13 17:45:42 +02:00
										 |  |  | 		float attenuation = Math::db_to_linear(_get_attenuation_db(distance)); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | 		// Determine the fraction of sound that would come from each speaker if they were all driven uniformly.
 | 
					
						
							|  |  |  | 		float center_val[3] = { 0.5f, 0.25f, 0.16666f }; | 
					
						
							|  |  |  | 		int channel_count = AudioServer::get_singleton()->get_channel_count(); | 
					
						
							|  |  |  | 		AudioFrame center_frame(center_val[channel_count - 1], center_val[channel_count - 1]); | 
					
						
							| 
									
										
										
										
											2018-07-08 21:30:26 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | 		if (attenuation < 1.0) { | 
					
						
							|  |  |  | 			//pan the uniform sound
 | 
					
						
							|  |  |  | 			Vector3 rev_pos = listener_area_pos; | 
					
						
							|  |  |  | 			rev_pos.y = 0; | 
					
						
							|  |  |  | 			rev_pos.normalize(); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-22 23:09:30 +01:00
										 |  |  | 			// Stereo pair.
 | 
					
						
							|  |  |  | 			float c = rev_pos.x * 0.5 + 0.5; | 
					
						
							| 
									
										
										
										
											2024-01-09 15:01:12 +01:00
										 |  |  | 			reverb_vol.write[0].left = 1.0 - c; | 
					
						
							|  |  |  | 			reverb_vol.write[0].right = c; | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | 			if (channel_count >= 3) { | 
					
						
							|  |  |  | 				// Center pair + Side pair
 | 
					
						
							|  |  |  | 				float xl = Vector3(-1, 0, -1).normalized().dot(rev_pos) * 0.5 + 0.5; | 
					
						
							|  |  |  | 				float xr = Vector3(1, 0, -1).normalized().dot(rev_pos) * 0.5 + 0.5; | 
					
						
							| 
									
										
										
										
											2019-06-26 15:08:25 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-09 15:01:12 +01:00
										 |  |  | 				reverb_vol.write[1].left = xl; | 
					
						
							|  |  |  | 				reverb_vol.write[1].right = xr; | 
					
						
							|  |  |  | 				reverb_vol.write[2].left = 1.0 - xr; | 
					
						
							|  |  |  | 				reverb_vol.write[2].right = 1.0 - xl; | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-05-27 15:29:10 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | 			if (channel_count >= 4) { | 
					
						
							|  |  |  | 				// Rear pair
 | 
					
						
							|  |  |  | 				// FIXME: Not sure what math should be done here
 | 
					
						
							| 
									
										
										
										
											2024-01-09 15:01:12 +01:00
										 |  |  | 				reverb_vol.write[3].left = 1.0 - c; | 
					
						
							|  |  |  | 				reverb_vol.write[3].right = c; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | 			for (int i = 0; i < channel_count; i++) { | 
					
						
							|  |  |  | 				reverb_vol.write[i] = reverb_vol[i].lerp(center_frame, attenuation); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | 		} else { | 
					
						
							|  |  |  | 			for (int i = 0; i < channel_count; i++) { | 
					
						
							|  |  |  | 				reverb_vol.write[i] = center_frame; | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | 		for (int i = 0; i < channel_count; i++) { | 
					
						
							|  |  |  | 			reverb_vol.write[i] = direct_path_vol[i].lerp(reverb_vol[i] * attenuation, uniformity); | 
					
						
							|  |  |  | 			reverb_vol.write[i] *= area_send; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | 	} else { | 
					
						
							|  |  |  | 		for (int i = 0; i < 4; i++) { | 
					
						
							|  |  |  | 			reverb_vol.write[i] = direct_path_vol[i] * area_send; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | float AudioStreamPlayer3D::_get_attenuation_db(float p_distance) const { | 
					
						
							| 
									
										
										
										
											2017-09-01 22:33:39 +02:00
										 |  |  | 	float att = 0; | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	switch (attenuation_model) { | 
					
						
							|  |  |  | 		case ATTENUATION_INVERSE_DISTANCE: { | 
					
						
							| 
									
										
										
										
											2022-08-13 17:45:42 +02:00
										 |  |  | 			att = Math::linear_to_db(1.0 / ((p_distance / unit_size) + CMP_EPSILON)); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 		} break; | 
					
						
							|  |  |  | 		case ATTENUATION_INVERSE_SQUARE_DISTANCE: { | 
					
						
							|  |  |  | 			float d = (p_distance / unit_size); | 
					
						
							|  |  |  | 			d *= d; | 
					
						
							| 
									
										
										
										
											2022-08-13 17:45:42 +02:00
										 |  |  | 			att = Math::linear_to_db(1.0 / (d + CMP_EPSILON)); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 		} break; | 
					
						
							|  |  |  | 		case ATTENUATION_LOGARITHMIC: { | 
					
						
							| 
									
										
										
										
											2019-01-17 01:41:36 +03:00
										 |  |  | 			att = -20 * Math::log(p_distance / unit_size + CMP_EPSILON); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2020-05-10 13:00:47 +02:00
										 |  |  | 		case ATTENUATION_DISABLED: | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2017-09-01 22:33:39 +02:00
										 |  |  | 		default: { | 
					
						
							|  |  |  | 			ERR_PRINT("Unknown attenuation type"); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 	att += internal->volume_db; | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	if (att > max_db) { | 
					
						
							|  |  |  | 		att = max_db; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return att; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AudioStreamPlayer3D::_notification(int p_what) { | 
					
						
							| 
									
										
										
										
											2024-01-30 00:56:12 -06:00
										 |  |  | 	internal->notification(p_what); | 
					
						
							| 
									
										
										
										
											2022-02-15 18:06:48 +01:00
										 |  |  | 	switch (p_what) { | 
					
						
							|  |  |  | 		case NOTIFICATION_ENTER_TREE: { | 
					
						
							|  |  |  | 			velocity_tracker->reset(get_global_transform().origin); | 
					
						
							|  |  |  | 			AudioServer::get_singleton()->add_listener_changed_callback(_listener_changed_cb, this); | 
					
						
							|  |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-15 18:06:48 +01:00
										 |  |  | 		case NOTIFICATION_EXIT_TREE: { | 
					
						
							|  |  |  | 			AudioServer::get_singleton()->remove_listener_changed_callback(_listener_changed_cb, this); | 
					
						
							|  |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2018-05-27 15:29:10 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-15 18:06:48 +01:00
										 |  |  | 		case NOTIFICATION_TRANSFORM_CHANGED: { | 
					
						
							|  |  |  | 			if (doppler_tracking != DOPPLER_TRACKING_DISABLED) { | 
					
						
							|  |  |  | 				velocity_tracker->update_position(get_global_transform().origin); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-15 18:06:48 +01:00
										 |  |  | 		case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { | 
					
						
							|  |  |  | 			// Update anything related to position first, if possible of course.
 | 
					
						
							|  |  |  | 			Vector<AudioFrame> volume_vector; | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 			if (setplay.get() > 0 || (internal->active.is_set() && last_mix_count != AudioServer::get_singleton()->get_mix_count()) || force_update_panning) { | 
					
						
							| 
									
										
										
										
											2022-05-25 12:13:12 -07:00
										 |  |  | 				force_update_panning = false; | 
					
						
							| 
									
										
										
										
											2022-02-15 18:06:48 +01:00
										 |  |  | 				volume_vector = _update_panning(); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-28 03:25:49 +09:00
										 |  |  | 			if (setplayback.is_valid() && setplay.get() >= 0) { | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 				internal->active.set(); | 
					
						
							| 
									
										
										
										
											2022-05-13 15:04:37 +02:00
										 |  |  | 				HashMap<StringName, Vector<AudioFrame>> bus_map; | 
					
						
							| 
									
										
										
										
											2022-02-15 18:06:48 +01:00
										 |  |  | 				bus_map[_get_actual_bus()] = volume_vector; | 
					
						
							| 
									
										
										
										
											2023-01-28 03:25:49 +09:00
										 |  |  | 				AudioServer::get_singleton()->start_playback_stream(setplayback, bus_map, setplay.get(), actual_pitch_scale, linear_attenuation, attenuation_filter_cutoff_hz); | 
					
						
							|  |  |  | 				setplayback.unref(); | 
					
						
							| 
									
										
										
										
											2022-02-15 18:06:48 +01:00
										 |  |  | 				setplay.set(-1); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 			if (!internal->stream_playbacks.is_empty() && internal->active.is_set()) { | 
					
						
							|  |  |  | 				internal->process(); | 
					
						
							| 
									
										
										
										
											2022-02-15 18:06:48 +01:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 			internal->ensure_playback_limit(); | 
					
						
							| 
									
										
										
										
											2022-02-15 18:06:48 +01:00
										 |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-25 12:13:12 -07:00
										 |  |  | // Interacts with PhysicsServer3D, so can only be called during _physics_process
 | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | Area3D *AudioStreamPlayer3D::_get_overriding_area() { | 
					
						
							|  |  |  | 	//check if any area is diverting sound into a bus
 | 
					
						
							|  |  |  | 	Ref<World3D> world_3d = get_world_3d(); | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(world_3d.is_null(), nullptr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Vector3 global_pos = get_global_transform().origin; | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | 	PhysicsDirectSpaceState3D *space_state = PhysicsServer3D::get_singleton()->space_get_direct_state(world_3d->get_space()); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | 	PhysicsDirectSpaceState3D::ShapeResult sr[MAX_INTERSECT_AREAS]; | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-01 18:00:58 -07:00
										 |  |  | 	PhysicsDirectSpaceState3D::PointParameters point_params; | 
					
						
							|  |  |  | 	point_params.position = global_pos; | 
					
						
							|  |  |  | 	point_params.collision_mask = area_mask; | 
					
						
							|  |  |  | 	point_params.collide_with_bodies = false; | 
					
						
							|  |  |  | 	point_params.collide_with_areas = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	int areas = space_state->intersect_point(point_params, sr, MAX_INTERSECT_AREAS); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | 	for (int i = 0; i < areas; i++) { | 
					
						
							|  |  |  | 		if (!sr[i].collider) { | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Area3D *tarea = Object::cast_to<Area3D>(sr[i].collider); | 
					
						
							|  |  |  | 		if (!tarea) { | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (!tarea->is_overriding_audio_bus() && !tarea->is_using_reverb_bus()) { | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return tarea; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nullptr; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | // Interacts with PhysicsServer3D, so can only be called during _physics_process.
 | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | StringName AudioStreamPlayer3D::_get_actual_bus() { | 
					
						
							|  |  |  | 	Area3D *overriding_area = _get_overriding_area(); | 
					
						
							|  |  |  | 	if (overriding_area && overriding_area->is_overriding_audio_bus() && !overriding_area->is_using_reverb_bus()) { | 
					
						
							|  |  |  | 		return overriding_area->get_audio_bus_name(); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 	return internal->bus; | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | // Interacts with PhysicsServer3D, so can only be called during _physics_process.
 | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | Vector<AudioFrame> AudioStreamPlayer3D::_update_panning() { | 
					
						
							|  |  |  | 	Vector<AudioFrame> output_volume_vector; | 
					
						
							|  |  |  | 	output_volume_vector.resize(4); | 
					
						
							|  |  |  | 	for (AudioFrame &frame : output_volume_vector) { | 
					
						
							|  |  |  | 		frame = AudioFrame(0, 0); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 	if (!internal->active.is_set() || internal->stream.is_null()) { | 
					
						
							| 
									
										
										
										
											2021-08-27 21:51:03 -07:00
										 |  |  | 		return output_volume_vector; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | 	Vector3 linear_velocity; | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | 	//compute linear velocity for doppler
 | 
					
						
							|  |  |  | 	if (doppler_tracking != DOPPLER_TRACKING_DISABLED) { | 
					
						
							|  |  |  | 		linear_velocity = velocity_tracker->get_tracked_linear_velocity(); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | 	Vector3 global_pos = get_global_transform().origin; | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | 	Ref<World3D> world_3d = get_world_3d(); | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(world_3d.is_null(), output_volume_vector); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-19 17:00:06 +02:00
										 |  |  | 	HashSet<Camera3D *> cameras = world_3d->get_cameras(); | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | 	cameras.insert(get_viewport()->get_camera_3d()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	PhysicsDirectSpaceState3D *space_state = PhysicsServer3D::get_singleton()->space_get_direct_state(world_3d->get_space()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (Camera3D *camera : cameras) { | 
					
						
							| 
									
										
										
										
											2021-10-27 16:06:09 -07:00
										 |  |  | 		if (!camera) { | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | 		Viewport *vp = camera->get_viewport(); | 
					
						
							| 
									
										
										
										
											2021-10-27 16:06:09 -07:00
										 |  |  | 		if (!vp) { | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | 		if (!vp->is_audio_listener_3d()) { | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		bool listener_is_camera = true; | 
					
						
							|  |  |  | 		Node3D *listener_node = camera; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-16 15:28:20 -04:00
										 |  |  | 		AudioListener3D *listener = vp->get_audio_listener_3d(); | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | 		if (listener) { | 
					
						
							|  |  |  | 			listener_node = listener; | 
					
						
							|  |  |  | 			listener_is_camera = false; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Vector3 local_pos = listener_node->get_global_transform().orthonormalized().affine_inverse().xform(global_pos); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		float dist = local_pos.length(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Vector3 area_sound_pos; | 
					
						
							|  |  |  | 		Vector3 listener_area_pos; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Area3D *area = _get_overriding_area(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (area && area->is_using_reverb_bus() && area->get_reverb_uniformity() > 0) { | 
					
						
							|  |  |  | 			area_sound_pos = space_state->get_closest_point_to_object_volume(area->get_rid(), listener_node->get_global_transform().origin); | 
					
						
							|  |  |  | 			listener_area_pos = listener_node->get_global_transform().affine_inverse().xform(area_sound_pos); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (max_distance > 0) { | 
					
						
							|  |  |  | 			float total_max = max_distance; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (area && area->is_using_reverb_bus() && area->get_reverb_uniformity() > 0) { | 
					
						
							|  |  |  | 				total_max = MAX(total_max, listener_area_pos.length()); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | 			if (total_max > max_distance) { | 
					
						
							|  |  |  | 				continue; //can't hear this sound in this listener
 | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-13 17:45:42 +02:00
										 |  |  | 		float multiplier = Math::db_to_linear(_get_attenuation_db(dist)); | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | 		if (max_distance > 0) { | 
					
						
							|  |  |  | 			multiplier *= MAX(0, 1.0 - (dist / max_distance)); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | 		float db_att = (1.0 - MIN(1.0, multiplier)) * attenuation_filter_db; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (emission_angle_enabled) { | 
					
						
							|  |  |  | 			Vector3 listenertopos = global_pos - listener_node->get_global_transform().origin; | 
					
						
							| 
									
										
										
										
											2022-05-03 07:50:35 -05:00
										 |  |  | 			float c = listenertopos.normalized().dot(get_global_transform().basis.get_column(2).normalized()); //it's z negative
 | 
					
						
							| 
									
										
										
										
											2022-08-13 17:45:42 +02:00
										 |  |  | 			float angle = Math::rad_to_deg(Math::acos(c)); | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | 			if (angle > emission_angle) { | 
					
						
							|  |  |  | 				db_att -= -emission_angle_filter_attenuation_db; | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-13 17:45:42 +02:00
										 |  |  | 		linear_attenuation = Math::db_to_linear(db_att); | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 		for (Ref<AudioStreamPlayback> &playback : internal->stream_playbacks) { | 
					
						
							| 
									
										
										
										
											2021-08-27 21:51:03 -07:00
										 |  |  | 			AudioServer::get_singleton()->set_playback_highshelf_params(playback, linear_attenuation, attenuation_filter_cutoff_hz); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2022-03-06 08:53:56 -08:00
										 |  |  | 		// 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); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | 		for (unsigned int k = 0; k < 4; k++) { | 
					
						
							|  |  |  | 			output_volume_vector.write[k] = multiplier * output_volume_vector[k]; | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-13 15:04:37 +02:00
										 |  |  | 		HashMap<StringName, Vector<AudioFrame>> bus_volumes; | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | 		if (area) { | 
					
						
							|  |  |  | 			if (area->is_overriding_audio_bus()) { | 
					
						
							|  |  |  | 				//override audio bus
 | 
					
						
							|  |  |  | 				bus_volumes[area->get_audio_bus_name()] = output_volume_vector; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (area->is_using_reverb_bus()) { | 
					
						
							| 
									
										
										
										
											2022-09-21 18:56:03 +02:00
										 |  |  | 				StringName reverb_bus_name = area->get_reverb_bus_name(); | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | 				Vector<AudioFrame> reverb_vol; | 
					
						
							|  |  |  | 				_calc_reverb_vol(area, listener_area_pos, output_volume_vector, reverb_vol); | 
					
						
							|  |  |  | 				bus_volumes[reverb_bus_name] = reverb_vol; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 			bus_volumes[internal->bus] = output_volume_vector; | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-08-27 21:51:03 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 		for (Ref<AudioStreamPlayback> &playback : internal->stream_playbacks) { | 
					
						
							| 
									
										
										
										
											2021-08-27 21:51:03 -07:00
										 |  |  | 			AudioServer::get_singleton()->set_playback_bus_volumes_linear(playback, bus_volumes); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | 		if (doppler_tracking != DOPPLER_TRACKING_DISABLED) { | 
					
						
							|  |  |  | 			Vector3 listener_velocity; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (listener_is_camera) { | 
					
						
							|  |  |  | 				listener_velocity = camera->get_doppler_tracked_velocity(); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			Vector3 local_velocity = listener_node->get_global_transform().orthonormalized().basis.xform_inv(linear_velocity - listener_velocity); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-27 21:51:03 -07:00
										 |  |  | 			if (local_velocity != Vector3()) { | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | 				float approaching = local_pos.normalized().dot(local_velocity.normalized()); | 
					
						
							|  |  |  | 				float velocity = local_velocity.length(); | 
					
						
							|  |  |  | 				float speed_of_sound = 343.0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 				float doppler_pitch_scale = internal->pitch_scale * speed_of_sound / (speed_of_sound + velocity * approaching); | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | 				doppler_pitch_scale = CLAMP(doppler_pitch_scale, (1 / 8.0), 8.0); //avoid crazy stuff
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-27 21:51:03 -07:00
										 |  |  | 				actual_pitch_scale = doppler_pitch_scale; | 
					
						
							|  |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 				actual_pitch_scale = internal->pitch_scale; | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 			actual_pitch_scale = internal->pitch_scale; | 
					
						
							| 
									
										
										
										
											2021-08-27 21:51:03 -07:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 		for (Ref<AudioStreamPlayback> &playback : internal->stream_playbacks) { | 
					
						
							| 
									
										
										
										
											2021-08-27 21:51:03 -07:00
										 |  |  | 			AudioServer::get_singleton()->set_playback_pitch_scale(playback, actual_pitch_scale); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-08-27 10:28:23 -07:00
										 |  |  | 	return output_volume_vector; | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AudioStreamPlayer3D::set_stream(Ref<AudioStream> p_stream) { | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 	internal->set_stream(p_stream); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Ref<AudioStream> AudioStreamPlayer3D::get_stream() const { | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 	return internal->stream; | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-17 14:34:43 +02:00
										 |  |  | void AudioStreamPlayer3D::set_volume_db(float p_volume) { | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 	internal->volume_db = p_volume; | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-17 14:34:43 +02:00
										 |  |  | float AudioStreamPlayer3D::get_volume_db() const { | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 	return internal->volume_db; | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AudioStreamPlayer3D::set_unit_size(float p_volume) { | 
					
						
							|  |  |  | 	unit_size = p_volume; | 
					
						
							| 
									
										
										
										
											2022-04-25 19:36:48 +02:00
										 |  |  | 	update_gizmos(); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | float AudioStreamPlayer3D::get_unit_size() const { | 
					
						
							|  |  |  | 	return unit_size; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AudioStreamPlayer3D::set_max_db(float p_boost) { | 
					
						
							|  |  |  | 	max_db = p_boost; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | float AudioStreamPlayer3D::get_max_db() const { | 
					
						
							|  |  |  | 	return max_db; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-01 22:23:16 +01:00
										 |  |  | void AudioStreamPlayer3D::set_pitch_scale(float p_pitch_scale) { | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 	internal->set_pitch_scale(p_pitch_scale); | 
					
						
							| 
									
										
										
										
											2018-01-01 22:23:16 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-01 22:23:16 +01:00
										 |  |  | float AudioStreamPlayer3D::get_pitch_scale() const { | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 	return internal->pitch_scale; | 
					
						
							| 
									
										
										
										
											2018-01-01 22:23:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | void AudioStreamPlayer3D::play(float p_from_pos) { | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 	Ref<AudioStreamPlayback> stream_playback = internal->play_basic(); | 
					
						
							|  |  |  | 	if (stream_playback.is_null()) { | 
					
						
							| 
									
										
										
										
											2021-08-27 21:51:03 -07:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-01-28 03:25:49 +09:00
										 |  |  | 	setplayback = stream_playback; | 
					
						
							| 
									
										
										
										
											2021-08-27 21:51:03 -07:00
										 |  |  | 	setplay.set(p_from_pos); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AudioStreamPlayer3D::seek(float p_seconds) { | 
					
						
							| 
									
										
										
										
											2023-01-28 03:25:49 +09:00
										 |  |  | 	if (is_playing()) { | 
					
						
							|  |  |  | 		stop(); | 
					
						
							|  |  |  | 		play(p_seconds); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AudioStreamPlayer3D::stop() { | 
					
						
							| 
									
										
										
										
											2021-08-27 21:51:03 -07:00
										 |  |  | 	setplay.set(-1); | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 	internal->stop(); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool AudioStreamPlayer3D::is_playing() const { | 
					
						
							| 
									
										
										
										
											2022-09-05 22:08:12 +02:00
										 |  |  | 	if (setplay.get() >= 0) { | 
					
						
							|  |  |  | 		return true; // play() has been called this frame, but no playback exists just yet.
 | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 	return internal->is_playing(); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-21 00:31:36 -03:00
										 |  |  | float AudioStreamPlayer3D::get_playback_position() { | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 	return internal->get_playback_position(); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AudioStreamPlayer3D::set_bus(const StringName &p_bus) { | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 	internal->bus = p_bus; // This will be pushed to the audio server during the next physics timestep, which is fast enough.
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | StringName AudioStreamPlayer3D::get_bus() const { | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 	return internal->get_bus(); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AudioStreamPlayer3D::set_autoplay(bool p_enable) { | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 	internal->autoplay = p_enable; | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-06 20:29:43 -06:00
										 |  |  | bool AudioStreamPlayer3D::is_autoplay_enabled() const { | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 	return internal->autoplay; | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AudioStreamPlayer3D::_set_playing(bool p_enable) { | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 	internal->set_playing(p_enable); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | bool AudioStreamPlayer3D::_is_active() const { | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 	return internal->is_active(); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-12 23:57:11 +03:00
										 |  |  | void AudioStreamPlayer3D::_validate_property(PropertyInfo &p_property) const { | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 	internal->validate_property(p_property); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AudioStreamPlayer3D::set_max_distance(float p_metres) { | 
					
						
							|  |  |  | 	ERR_FAIL_COND(p_metres < 0.0); | 
					
						
							|  |  |  | 	max_distance = p_metres; | 
					
						
							| 
									
										
										
										
											2022-04-25 19:36:48 +02:00
										 |  |  | 	update_gizmos(); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | float AudioStreamPlayer3D::get_max_distance() const { | 
					
						
							|  |  |  | 	return max_distance; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AudioStreamPlayer3D::set_area_mask(uint32_t p_mask) { | 
					
						
							|  |  |  | 	area_mask = p_mask; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | uint32_t AudioStreamPlayer3D::get_area_mask() const { | 
					
						
							|  |  |  | 	return area_mask; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AudioStreamPlayer3D::set_emission_angle_enabled(bool p_enable) { | 
					
						
							|  |  |  | 	emission_angle_enabled = p_enable; | 
					
						
							| 
									
										
										
										
											2021-06-23 16:49:50 +02:00
										 |  |  | 	update_gizmos(); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool AudioStreamPlayer3D::is_emission_angle_enabled() const { | 
					
						
							|  |  |  | 	return emission_angle_enabled; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AudioStreamPlayer3D::set_emission_angle(float p_angle) { | 
					
						
							|  |  |  | 	ERR_FAIL_COND(p_angle < 0 || p_angle > 90); | 
					
						
							|  |  |  | 	emission_angle = p_angle; | 
					
						
							| 
									
										
										
										
											2021-06-23 16:49:50 +02:00
										 |  |  | 	update_gizmos(); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | float AudioStreamPlayer3D::get_emission_angle() const { | 
					
						
							|  |  |  | 	return emission_angle; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AudioStreamPlayer3D::set_emission_angle_filter_attenuation_db(float p_angle_attenuation_db) { | 
					
						
							|  |  |  | 	emission_angle_filter_attenuation_db = p_angle_attenuation_db; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | float AudioStreamPlayer3D::get_emission_angle_filter_attenuation_db() const { | 
					
						
							|  |  |  | 	return emission_angle_filter_attenuation_db; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AudioStreamPlayer3D::set_attenuation_filter_cutoff_hz(float p_hz) { | 
					
						
							|  |  |  | 	attenuation_filter_cutoff_hz = p_hz; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | float AudioStreamPlayer3D::get_attenuation_filter_cutoff_hz() const { | 
					
						
							|  |  |  | 	return attenuation_filter_cutoff_hz; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AudioStreamPlayer3D::set_attenuation_filter_db(float p_db) { | 
					
						
							|  |  |  | 	attenuation_filter_db = p_db; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | float AudioStreamPlayer3D::get_attenuation_filter_db() const { | 
					
						
							|  |  |  | 	return attenuation_filter_db; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AudioStreamPlayer3D::set_attenuation_model(AttenuationModel p_model) { | 
					
						
							| 
									
										
										
										
											2019-03-10 13:25:54 +00:00
										 |  |  | 	ERR_FAIL_INDEX((int)p_model, 4); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	attenuation_model = p_model; | 
					
						
							| 
									
										
										
										
											2022-04-25 19:36:48 +02:00
										 |  |  | 	update_gizmos(); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | AudioStreamPlayer3D::AttenuationModel AudioStreamPlayer3D::get_attenuation_model() const { | 
					
						
							|  |  |  | 	return attenuation_model; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AudioStreamPlayer3D::set_doppler_tracking(DopplerTracking p_tracking) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (doppler_tracking == p_tracking) { | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	doppler_tracking = p_tracking; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (doppler_tracking != DOPPLER_TRACKING_DISABLED) { | 
					
						
							|  |  |  | 		set_notify_transform(true); | 
					
						
							| 
									
										
										
										
											2017-09-30 16:19:07 +02:00
										 |  |  | 		velocity_tracker->set_track_physics_step(doppler_tracking == DOPPLER_TRACKING_PHYSICS_STEP); | 
					
						
							| 
									
										
										
										
											2019-02-26 09:15:51 -03:00
										 |  |  | 		if (is_inside_tree()) { | 
					
						
							|  |  |  | 			velocity_tracker->reset(get_global_transform().origin); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	} else { | 
					
						
							|  |  |  | 		set_notify_transform(false); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | AudioStreamPlayer3D::DopplerTracking AudioStreamPlayer3D::get_doppler_tracking() const { | 
					
						
							|  |  |  | 	return doppler_tracking; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-27 15:29:10 -03:00
										 |  |  | void AudioStreamPlayer3D::set_stream_paused(bool p_pause) { | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 	internal->set_stream_paused(p_pause); | 
					
						
							| 
									
										
										
										
											2018-05-27 15:29:10 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool AudioStreamPlayer3D::get_stream_paused() const { | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 	return internal->get_stream_paused(); | 
					
						
							| 
									
										
										
										
											2018-05-27 15:29:10 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-28 03:25:49 +09:00
										 |  |  | bool AudioStreamPlayer3D::has_stream_playback() { | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 	return internal->has_stream_playback(); | 
					
						
							| 
									
										
										
										
											2023-01-28 03:25:49 +09:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-10 12:57:03 -03:00
										 |  |  | Ref<AudioStreamPlayback> AudioStreamPlayer3D::get_stream_playback() { | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 	return internal->get_stream_playback(); | 
					
						
							| 
									
										
										
										
											2021-08-27 21:51:03 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AudioStreamPlayer3D::set_max_polyphony(int p_max_polyphony) { | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 	internal->set_max_polyphony(p_max_polyphony); | 
					
						
							| 
									
										
										
										
											2021-08-27 21:51:03 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int AudioStreamPlayer3D::get_max_polyphony() const { | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 	return internal->max_polyphony; | 
					
						
							| 
									
										
										
										
											2019-04-10 12:57:03 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-06 08:53:56 -08:00
										 |  |  | 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; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-23 17:30:32 +01:00
										 |  |  | bool AudioStreamPlayer3D::_set(const StringName &p_name, const Variant &p_value) { | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 	return internal->set(p_name, p_value); | 
					
						
							| 
									
										
										
										
											2023-12-23 17:30:32 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool AudioStreamPlayer3D::_get(const StringName &p_name, Variant &r_ret) const { | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 	return internal->get(p_name, r_ret); | 
					
						
							| 
									
										
										
										
											2023-12-23 17:30:32 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void AudioStreamPlayer3D::_get_property_list(List<PropertyInfo> *p_list) const { | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 	internal->get_property_list(p_list); | 
					
						
							| 
									
										
										
										
											2023-12-23 17:30:32 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | void AudioStreamPlayer3D::_bind_methods() { | 
					
						
							| 
									
										
										
										
											2017-08-09 13:19:41 +02:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("set_stream", "stream"), &AudioStreamPlayer3D::set_stream); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("get_stream"), &AudioStreamPlayer3D::get_stream); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-17 14:34:43 +02:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("set_volume_db", "volume_db"), &AudioStreamPlayer3D::set_volume_db); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_volume_db"), &AudioStreamPlayer3D::get_volume_db); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("set_unit_size", "unit_size"), &AudioStreamPlayer3D::set_unit_size); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_unit_size"), &AudioStreamPlayer3D::get_unit_size); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("set_max_db", "max_db"), &AudioStreamPlayer3D::set_max_db); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_max_db"), &AudioStreamPlayer3D::get_max_db); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-01 22:23:16 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("set_pitch_scale", "pitch_scale"), &AudioStreamPlayer3D::set_pitch_scale); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_pitch_scale"), &AudioStreamPlayer3D::get_pitch_scale); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-10 15:37:49 +02:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("play", "from_position"), &AudioStreamPlayer3D::play, DEFVAL(0.0)); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("seek", "to_position"), &AudioStreamPlayer3D::seek); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("stop"), &AudioStreamPlayer3D::stop); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("is_playing"), &AudioStreamPlayer3D::is_playing); | 
					
						
							| 
									
										
										
										
											2017-09-21 00:31:36 -03:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("get_playback_position"), &AudioStreamPlayer3D::get_playback_position); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("set_bus", "bus"), &AudioStreamPlayer3D::set_bus); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_bus"), &AudioStreamPlayer3D::get_bus); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("set_autoplay", "enable"), &AudioStreamPlayer3D::set_autoplay); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("is_autoplay_enabled"), &AudioStreamPlayer3D::is_autoplay_enabled); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("_set_playing", "enable"), &AudioStreamPlayer3D::_set_playing); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("_is_active"), &AudioStreamPlayer3D::_is_active); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-21 12:25:29 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("set_max_distance", "meters"), &AudioStreamPlayer3D::set_max_distance); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("get_max_distance"), &AudioStreamPlayer3D::get_max_distance); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("set_area_mask", "mask"), &AudioStreamPlayer3D::set_area_mask); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_area_mask"), &AudioStreamPlayer3D::get_area_mask); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("set_emission_angle", "degrees"), &AudioStreamPlayer3D::set_emission_angle); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_emission_angle"), &AudioStreamPlayer3D::get_emission_angle); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("set_emission_angle_enabled", "enabled"), &AudioStreamPlayer3D::set_emission_angle_enabled); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("is_emission_angle_enabled"), &AudioStreamPlayer3D::is_emission_angle_enabled); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("set_emission_angle_filter_attenuation_db", "db"), &AudioStreamPlayer3D::set_emission_angle_filter_attenuation_db); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_emission_angle_filter_attenuation_db"), &AudioStreamPlayer3D::get_emission_angle_filter_attenuation_db); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("set_attenuation_filter_cutoff_hz", "degrees"), &AudioStreamPlayer3D::set_attenuation_filter_cutoff_hz); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_attenuation_filter_cutoff_hz"), &AudioStreamPlayer3D::get_attenuation_filter_cutoff_hz); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("set_attenuation_filter_db", "db"), &AudioStreamPlayer3D::set_attenuation_filter_db); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_attenuation_filter_db"), &AudioStreamPlayer3D::get_attenuation_filter_db); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("set_attenuation_model", "model"), &AudioStreamPlayer3D::set_attenuation_model); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_attenuation_model"), &AudioStreamPlayer3D::get_attenuation_model); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("set_doppler_tracking", "mode"), &AudioStreamPlayer3D::set_doppler_tracking); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_doppler_tracking"), &AudioStreamPlayer3D::get_doppler_tracking); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-27 15:29:10 -03:00
										 |  |  | 	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); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-27 21:51:03 -07:00
										 |  |  | 	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); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-06 08:53:56 -08:00
										 |  |  | 	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); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-28 03:25:49 +09:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("has_stream_playback"), &AudioStreamPlayer3D::has_stream_playback); | 
					
						
							| 
									
										
										
										
											2019-04-10 12:57:03 -03:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("get_stream_playback"), &AudioStreamPlayer3D::get_stream_playback); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "stream", PROPERTY_HINT_RESOURCE_TYPE, "AudioStream"), "set_stream", "get_stream"); | 
					
						
							| 
									
										
										
										
											2021-09-17 10:14:32 +02:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::INT, "attenuation_model", PROPERTY_HINT_ENUM, "Inverse,Inverse Square,Logarithmic,Disabled"), "set_attenuation_model", "get_attenuation_model"); | 
					
						
							| 
									
										
										
										
											2022-09-17 14:34:43 +02:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volume_db", PROPERTY_HINT_RANGE, "-80,80,suffix:dB"), "set_volume_db", "get_volume_db"); | 
					
						
							| 
									
										
										
										
											2020-04-26 14:26:01 +02:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "unit_size", PROPERTY_HINT_RANGE, "0.1,100,0.01,or_greater"), "set_unit_size", "get_unit_size"); | 
					
						
							| 
									
										
										
										
											2021-12-02 18:09:19 -06:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_db", PROPERTY_HINT_RANGE, "-24,6,suffix:dB"), "set_max_db", "get_max_db"); | 
					
						
							| 
									
										
										
											
												Variant: Added 64-bit packed arrays, renamed Variant::REAL to FLOAT.
- Renames PackedIntArray to PackedInt32Array.
- Renames PackedFloatArray to PackedFloat32Array.
- Adds PackedInt64Array and PackedFloat64Array.
- Renames Variant::REAL to Variant::FLOAT for consistency.
Packed arrays are for storing large amount of data and creating stuff like
meshes, buffers. textures, etc. Forcing them to be 64 is a huge waste of
memory. That said, many users requested the ability to have 64 bits packed
arrays for their games, so this is just an optional added type.
For Variant, the float datatype is always 64 bits, and exposed as `float`.
We still have `real_t` which is the datatype that can change from 32 to 64
bits depending on a compile flag (not entirely working right now, but that's
the idea). It affects math related datatypes and code only.
Neither Variant nor PackedArray make use of real_t, which is only intended
for math precision, so the term is removed from there to keep only float.
											
										 
											2020-02-24 15:20:53 -03:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pitch_scale", PROPERTY_HINT_RANGE, "0.01,4,0.01,or_greater"), "set_pitch_scale", "get_pitch_scale"); | 
					
						
							| 
									
										
										
										
											2017-09-13 08:40:41 -03:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_playing", "is_playing"); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "autoplay"), "set_autoplay", "is_autoplay_enabled"); | 
					
						
							| 
									
										
										
										
											2018-05-27 15:29:10 -03:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "stream_paused", PROPERTY_HINT_NONE, ""), "set_stream_paused", "get_stream_paused"); | 
					
						
							| 
									
										
										
										
											2021-12-02 18:09:19 -06:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_distance", PROPERTY_HINT_RANGE, "0,4096,0.01,or_greater,suffix:m"), "set_max_distance", "get_max_distance"); | 
					
						
							| 
									
										
										
										
											2021-08-27 21:51:03 -07:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::INT, "max_polyphony", PROPERTY_HINT_NONE, ""), "set_max_polyphony", "get_max_polyphony"); | 
					
						
							| 
									
										
										
										
											2022-03-06 08:53:56 -08:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "panning_strength", PROPERTY_HINT_RANGE, "0,3,0.01,or_greater"), "set_panning_strength", "get_panning_strength"); | 
					
						
							| 
									
										
										
										
											2020-02-20 18:58:05 -03:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "bus", PROPERTY_HINT_ENUM, ""), "set_bus", "get_bus"); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::INT, "area_mask", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_area_mask", "get_area_mask"); | 
					
						
							|  |  |  | 	ADD_GROUP("Emission Angle", "emission_angle"); | 
					
						
							|  |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "emission_angle_enabled"), "set_emission_angle_enabled", "is_emission_angle_enabled"); | 
					
						
							| 
									
										
										
											
												Fix editor suffixes and degrees conversion
* Functions to convert to/from degrees are all gone. Conversion is done by the editor.
* Use PROPERTY_HINT_ANGLE instead of PROPERTY_HINT_RANGE to edit radian angles in degrees.
* Added possibility to add suffixes to range properties, use "min,max[,step][,suffix:<something>]" example "0,100,1,suffix:m"
* In general, can add suffixes for EditorSpinSlider
Not covered by this PR, will have to be addressed by future ones:
* Ability to switch radians/degrees in the inspector for angle properties (if actually wanted).
* Animations previously made will most likely break, need to add a way to make old ones compatible.
* Only added a "px" suffix to 2D position and a "m" one to 3D position, someone needs to go through the rest of the engine and add all remaining suffixes.
* Likely also need to track down usage of EditorSpinSlider outside properties to add suffixes to it too.
											
										 
											2021-06-29 16:42:12 -03:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_angle_degrees", PROPERTY_HINT_RANGE, "0.1,90,0.1,degrees"), "set_emission_angle", "get_emission_angle"); | 
					
						
							| 
									
										
										
										
											2021-12-02 18:09:19 -06:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_angle_filter_attenuation_db", PROPERTY_HINT_RANGE, "-80,0,0.1,suffix:dB"), "set_emission_angle_filter_attenuation_db", "get_emission_angle_filter_attenuation_db"); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	ADD_GROUP("Attenuation Filter", "attenuation_filter_"); | 
					
						
							| 
									
										
										
										
											2021-12-02 18:09:19 -06:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "attenuation_filter_cutoff_hz", PROPERTY_HINT_RANGE, "1,20500,1,suffix:Hz"), "set_attenuation_filter_cutoff_hz", "get_attenuation_filter_cutoff_hz"); | 
					
						
							|  |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "attenuation_filter_db", PROPERTY_HINT_RANGE, "-80,0,0.1,suffix:dB"), "set_attenuation_filter_db", "get_attenuation_filter_db"); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 	ADD_GROUP("Doppler", "doppler_"); | 
					
						
							| 
									
										
										
										
											2017-10-21 21:28:08 +07:00
										 |  |  | 	ADD_PROPERTY(PropertyInfo(Variant::INT, "doppler_tracking", PROPERTY_HINT_ENUM, "Disabled,Idle,Physics"), "set_doppler_tracking", "get_doppler_tracking"); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-20 17:45:01 +02:00
										 |  |  | 	BIND_ENUM_CONSTANT(ATTENUATION_INVERSE_DISTANCE); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(ATTENUATION_INVERSE_SQUARE_DISTANCE); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(ATTENUATION_LOGARITHMIC); | 
					
						
							| 
									
										
										
										
											2019-03-10 13:25:54 +00:00
										 |  |  | 	BIND_ENUM_CONSTANT(ATTENUATION_DISABLED); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-20 17:45:01 +02:00
										 |  |  | 	BIND_ENUM_CONSTANT(DOPPLER_TRACKING_DISABLED); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(DOPPLER_TRACKING_IDLE_STEP); | 
					
						
							| 
									
										
										
										
											2017-09-30 16:19:07 +02:00
										 |  |  | 	BIND_ENUM_CONSTANT(DOPPLER_TRACKING_PHYSICS_STEP); | 
					
						
							| 
									
										
										
										
											2017-08-25 11:58:21 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	ADD_SIGNAL(MethodInfo("finished")); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | AudioStreamPlayer3D::AudioStreamPlayer3D() { | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 	internal = memnew(AudioStreamPlayerInternal(this, callable_mp(this, &AudioStreamPlayer3D::play), true)); | 
					
						
							| 
									
										
										
										
											2021-06-17 16:03:09 -06:00
										 |  |  | 	velocity_tracker.instantiate(); | 
					
						
							| 
									
										
										
										
											2018-07-18 13:47:42 -03:00
										 |  |  | 	set_disable_scale(true); | 
					
						
							| 
									
										
										
										
											2022-10-18 16:43:37 +02:00
										 |  |  | 	cached_global_panning_strength = GLOBAL_GET("audio/general/3d_panning_strength"); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | AudioStreamPlayer3D::~AudioStreamPlayer3D() { | 
					
						
							| 
									
										
										
										
											2024-01-10 21:48:16 +01:00
										 |  |  | 	memdelete(internal); | 
					
						
							| 
									
										
										
										
											2017-07-15 01:23:10 -03:00
										 |  |  | } |