1 /*************************************************************************/
2 /* audio_stream_player_3d.cpp */
3 /*************************************************************************/
4 /* This file is part of: */
5 /* GODOT ENGINE */
6 /* https://godotengine.org */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
9 /* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
10 /* */
11 /* Permission is hereby granted, free of charge, to any person obtaining */
12 /* a copy of this software and associated documentation files (the */
13 /* "Software"), to deal in the Software without restriction, including */
14 /* without limitation the rights to use, copy, modify, merge, publish, */
15 /* distribute, sublicense, and/or sell copies of the Software, and to */
16 /* permit persons to whom the Software is furnished to do so, subject to */
17 /* the following conditions: */
18 /* */
19 /* The above copyright notice and this permission notice shall be */
20 /* included in all copies or substantial portions of the Software. */
21 /* */
22 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29 /*************************************************************************/
30
31 #include "audio_stream_player_3d.h"
32 #include "core/engine.h"
33 #include "scene/3d/area.h"
34 #include "scene/3d/camera.h"
35 #include "scene/3d/listener.h"
36 #include "scene/main/viewport.h"
37
38 // Based on "A Novel Multichannel Panning Method for Standard and Arbitrary Loudspeaker Configurations" by Ramy Sadek and Chris Kyriakakis (2004)
39 // Speaker-Placement Correction Amplitude Panning (SPCAP)
40 class Spcap {
41 private:
42 struct Speaker {
43 Vector3 direction;
44 real_t effective_number_of_speakers; // precalculated
45 mutable real_t squared_gain; // temporary
46 };
47
48 PoolVector<Speaker> speakers;
49
50 public:
Spcap(unsigned int speaker_count,const Vector3 * speaker_directions)51 Spcap(unsigned int speaker_count, const Vector3 *speaker_directions) {
52 this->speakers.resize(speaker_count);
53 PoolVector<Speaker>::Write w = this->speakers.write();
54 for (unsigned int speaker_num = 0; speaker_num < speaker_count; speaker_num++) {
55 w[speaker_num].direction = speaker_directions[speaker_num];
56 w[speaker_num].squared_gain = 0.0;
57 w[speaker_num].effective_number_of_speakers = 0.0;
58 for (unsigned int other_speaker_num = 0; other_speaker_num < speaker_count; other_speaker_num++) {
59 w[speaker_num].effective_number_of_speakers += 0.5 * (1.0 + w[speaker_num].direction.dot(w[other_speaker_num].direction));
60 }
61 }
62 }
63
get_speaker_count() const64 unsigned int get_speaker_count() const {
65 return (unsigned int)this->speakers.size();
66 }
67
get_speaker_direction(unsigned int index) const68 Vector3 get_speaker_direction(unsigned int index) const {
69 return this->speakers.read()[index].direction;
70 }
71
calculate(const Vector3 & source_direction,real_t tightness,unsigned int volume_count,real_t * volumes) const72 void calculate(const Vector3 &source_direction, real_t tightness, unsigned int volume_count, real_t *volumes) const {
73 PoolVector<Speaker>::Read r = this->speakers.read();
74 real_t sum_squared_gains = 0.0;
75 for (unsigned int speaker_num = 0; speaker_num < (unsigned int)this->speakers.size(); speaker_num++) {
76 real_t initial_gain = 0.5 * powf(1.0 + r[speaker_num].direction.dot(source_direction), tightness) / r[speaker_num].effective_number_of_speakers;
77 r[speaker_num].squared_gain = initial_gain * initial_gain;
78 sum_squared_gains += r[speaker_num].squared_gain;
79 }
80
81 for (unsigned int speaker_num = 0; speaker_num < MIN(volume_count, (unsigned int)this->speakers.size()); speaker_num++) {
82 volumes[speaker_num] = sqrtf(r[speaker_num].squared_gain / sum_squared_gains);
83 }
84 }
85 };
86
87 //TODO: hardcoded main speaker directions for 2, 3.1, 5.1 and 7.1 setups - these are simplified and could also be made configurable
88 static const Vector3 speaker_directions[7] = {
89 Vector3(-1.0, 0.0, -1.0).normalized(), // front-left
90 Vector3(1.0, 0.0, -1.0).normalized(), // front-right
91 Vector3(0.0, 0.0, -1.0).normalized(), // center
92 Vector3(-1.0, 0.0, 1.0).normalized(), // rear-left
93 Vector3(1.0, 0.0, 1.0).normalized(), // rear-right
94 Vector3(-1.0, 0.0, 0.0).normalized(), // side-left
95 Vector3(1.0, 0.0, 0.0).normalized(), // side-right
96 };
97
_calc_output_vol(const Vector3 & source_dir,real_t tightness,AudioStreamPlayer3D::Output & output)98 void AudioStreamPlayer3D::_calc_output_vol(const Vector3 &source_dir, real_t tightness, AudioStreamPlayer3D::Output &output) {
99 unsigned int speaker_count; // only main speakers (no LFE)
100 switch (AudioServer::get_singleton()->get_speaker_mode()) {
101 default: //fallthrough
102 case AudioServer::SPEAKER_MODE_STEREO: speaker_count = 2; break;
103 case AudioServer::SPEAKER_SURROUND_31: speaker_count = 3; break;
104 case AudioServer::SPEAKER_SURROUND_51: speaker_count = 5; break;
105 case AudioServer::SPEAKER_SURROUND_71: speaker_count = 7; break;
106 }
107
108 Spcap spcap(speaker_count, speaker_directions); //TODO: should only be created/recreated once the speaker mode / speaker positions changes
109 real_t volumes[7];
110 spcap.calculate(source_dir, tightness, speaker_count, volumes);
111
112 switch (AudioServer::get_singleton()->get_speaker_mode()) {
113 case AudioServer::SPEAKER_SURROUND_71:
114 output.vol[3].l = volumes[5]; // side-left
115 output.vol[3].r = volumes[6]; // side-right
116 //fallthrough
117 case AudioServer::SPEAKER_SURROUND_51:
118 output.vol[2].l = volumes[3]; // rear-left
119 output.vol[2].r = volumes[4]; // rear-right
120 //fallthrough
121 case AudioServer::SPEAKER_SURROUND_31:
122 output.vol[1].r = 1.0; // LFE - always full power
123 output.vol[1].l = volumes[2]; // center
124 //fallthrough
125 case AudioServer::SPEAKER_MODE_STEREO:
126 output.vol[0].r = volumes[1]; // front-right
127 output.vol[0].l = volumes[0]; // front-left
128 }
129 }
130
_mix_audio()131 void AudioStreamPlayer3D::_mix_audio() {
132
133 if (!stream_playback.is_valid() || !active ||
134 (stream_paused && !stream_paused_fade_out)) {
135 return;
136 }
137
138 bool started = false;
139 if (setseek >= 0.0) {
140 stream_playback->start(setseek);
141 setseek = -1.0; //reset seek
142 started = true;
143 }
144
145 //get data
146 AudioFrame *buffer = mix_buffer.ptrw();
147 int buffer_size = mix_buffer.size();
148
149 if (stream_paused_fade_out) {
150 // Short fadeout ramp
151 buffer_size = MIN(buffer_size, 128);
152 }
153
154 // Mix if we're not paused or we're fading out
155 if ((output_count > 0 || out_of_range_mode == OUT_OF_RANGE_MIX)) {
156
157 float output_pitch_scale = 0.0;
158 if (output_count) {
159 //used for doppler, not realistic but good enough
160 for (int i = 0; i < output_count; i++) {
161 output_pitch_scale += outputs[i].pitch_scale;
162 }
163 output_pitch_scale /= float(output_count);
164 } else {
165 output_pitch_scale = 1.0;
166 }
167
168 stream_playback->mix(buffer, pitch_scale * output_pitch_scale, buffer_size);
169 }
170
171 //write all outputs
172 for (int i = 0; i < output_count; i++) {
173
174 Output current = outputs[i];
175
176 //see if current output exists, to keep volume ramp
177 bool found = false;
178 for (int j = i; j < prev_output_count; j++) {
179 if (prev_outputs[j].viewport == current.viewport) {
180 if (j != i) {
181 SWAP(prev_outputs[j], prev_outputs[i]);
182 }
183 found = true;
184 break;
185 }
186 }
187
188 bool interpolate_filter = !started;
189
190 if (!found) {
191 //create new if was not used before
192 if (prev_output_count < MAX_OUTPUTS) {
193 prev_outputs[prev_output_count] = prev_outputs[i]; //may be owned by another viewport
194 prev_output_count++;
195 }
196 prev_outputs[i] = current;
197 interpolate_filter = false;
198 }
199
200 //mix!
201
202 int buffers = AudioServer::get_singleton()->get_channel_count();
203
204 for (int k = 0; k < buffers; k++) {
205 AudioFrame target_volume = stream_paused_fade_out ? AudioFrame(0.f, 0.f) : current.vol[k];
206 AudioFrame vol_prev = stream_paused_fade_in ? AudioFrame(0.f, 0.f) : prev_outputs[i].vol[k];
207 AudioFrame vol_inc = (target_volume - vol_prev) / float(buffer_size);
208 AudioFrame vol = vol_prev;
209
210 if (!AudioServer::get_singleton()->thread_has_channel_mix_buffer(current.bus_index, k))
211 continue; //may have been deleted, will be updated on process
212
213 AudioFrame *target = AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, k);
214 current.filter.set_mode(AudioFilterSW::HIGHSHELF);
215 current.filter.set_sampling_rate(AudioServer::get_singleton()->get_mix_rate());
216 current.filter.set_cutoff(attenuation_filter_cutoff_hz);
217 current.filter.set_resonance(1);
218 current.filter.set_stages(1);
219 current.filter.set_gain(current.filter_gain);
220
221 if (interpolate_filter) {
222
223 current.filter_process[k * 2 + 0] = prev_outputs[i].filter_process[k * 2 + 0];
224 current.filter_process[k * 2 + 1] = prev_outputs[i].filter_process[k * 2 + 1];
225
226 current.filter_process[k * 2 + 0].set_filter(¤t.filter, false);
227 current.filter_process[k * 2 + 1].set_filter(¤t.filter, false);
228
229 current.filter_process[k * 2 + 0].update_coeffs(buffer_size);
230 current.filter_process[k * 2 + 1].update_coeffs(buffer_size);
231 for (int j = 0; j < buffer_size; j++) {
232
233 AudioFrame f = buffer[j] * vol;
234 current.filter_process[k * 2 + 0].process_one_interp(f.l);
235 current.filter_process[k * 2 + 1].process_one_interp(f.r);
236
237 target[j] += f;
238 vol += vol_inc;
239 }
240 } else {
241 current.filter_process[k * 2 + 0].set_filter(¤t.filter);
242 current.filter_process[k * 2 + 1].set_filter(¤t.filter);
243
244 current.filter_process[k * 2 + 0].update_coeffs();
245 current.filter_process[k * 2 + 1].update_coeffs();
246 for (int j = 0; j < buffer_size; j++) {
247
248 AudioFrame f = buffer[j] * vol;
249 current.filter_process[k * 2 + 0].process_one(f.l);
250 current.filter_process[k * 2 + 1].process_one(f.r);
251
252 target[j] += f;
253 vol += vol_inc;
254 }
255 }
256
257 if (current.reverb_bus_index >= 0) {
258
259 if (!AudioServer::get_singleton()->thread_has_channel_mix_buffer(current.reverb_bus_index, k))
260 continue; //may have been deleted, will be updated on process
261
262 AudioFrame *rtarget = AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.reverb_bus_index, k);
263
264 if (current.reverb_bus_index == prev_outputs[i].reverb_bus_index) {
265 AudioFrame rvol_inc = (current.reverb_vol[k] - prev_outputs[i].reverb_vol[k]) / float(buffer_size);
266 AudioFrame rvol = prev_outputs[i].reverb_vol[k];
267
268 for (int j = 0; j < buffer_size; j++) {
269
270 rtarget[j] += buffer[j] * rvol;
271 rvol += rvol_inc;
272 }
273 } else {
274
275 AudioFrame rvol = current.reverb_vol[k];
276 for (int j = 0; j < buffer_size; j++) {
277
278 rtarget[j] += buffer[j] * rvol;
279 }
280 }
281 }
282 }
283
284 prev_outputs[i] = current;
285 }
286
287 prev_output_count = output_count;
288
289 //stream is no longer active, disable this.
290 if (!stream_playback->is_playing()) {
291 active = false;
292 }
293
294 output_ready = false;
295 stream_paused_fade_in = false;
296 stream_paused_fade_out = false;
297 }
298
_get_attenuation_db(float p_distance) const299 float AudioStreamPlayer3D::_get_attenuation_db(float p_distance) const {
300
301 float att = 0;
302 switch (attenuation_model) {
303 case ATTENUATION_INVERSE_DISTANCE: {
304 att = Math::linear2db(1.0 / ((p_distance / unit_size) + CMP_EPSILON));
305 } break;
306 case ATTENUATION_INVERSE_SQUARE_DISTANCE: {
307 float d = (p_distance / unit_size);
308 d *= d;
309 att = Math::linear2db(1.0 / (d + CMP_EPSILON));
310 } break;
311 case ATTENUATION_LOGARITHMIC: {
312 att = -20 * Math::log(p_distance / unit_size + CMP_EPSILON);
313 } break;
314 case ATTENUATION_DISABLED: break;
315 default: {
316 ERR_PRINT("Unknown attenuation type");
317 break;
318 }
319 }
320
321 att += unit_db;
322 if (att > max_db) {
323 att = max_db;
324 }
325
326 return att;
327 }
328
_update_sound()329 void _update_sound() {
330 }
331
_notification(int p_what)332 void AudioStreamPlayer3D::_notification(int p_what) {
333
334 if (p_what == NOTIFICATION_ENTER_TREE) {
335
336 velocity_tracker->reset(get_global_transform().origin);
337 AudioServer::get_singleton()->add_callback(_mix_audios, this);
338 if (autoplay && !Engine::get_singleton()->is_editor_hint()) {
339 play();
340 }
341 }
342
343 if (p_what == NOTIFICATION_EXIT_TREE) {
344
345 AudioServer::get_singleton()->remove_callback(_mix_audios, this);
346 }
347
348 if (p_what == NOTIFICATION_PAUSED) {
349 if (!can_process()) {
350 // Node can't process so we start fading out to silence
351 set_stream_paused(true);
352 }
353 }
354
355 if (p_what == NOTIFICATION_UNPAUSED) {
356 set_stream_paused(false);
357 }
358
359 if (p_what == NOTIFICATION_TRANSFORM_CHANGED) {
360
361 if (doppler_tracking != DOPPLER_TRACKING_DISABLED) {
362 velocity_tracker->update_position(get_global_transform().origin);
363 }
364 }
365
366 if (p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS) {
367
368 //update anything related to position first, if possible of course
369
370 if (!output_ready) {
371
372 Vector3 linear_velocity;
373
374 //compute linear velocity for doppler
375 if (doppler_tracking != DOPPLER_TRACKING_DISABLED) {
376 linear_velocity = velocity_tracker->get_tracked_linear_velocity();
377 }
378
379 Ref<World> world = get_world();
380 ERR_FAIL_COND(world.is_null());
381
382 int new_output_count = 0;
383
384 Vector3 global_pos = get_global_transform().origin;
385
386 int bus_index = AudioServer::get_singleton()->thread_find_bus_index(bus);
387
388 //check if any area is diverting sound into a bus
389
390 PhysicsDirectSpaceState *space_state = PhysicsServer::get_singleton()->space_get_direct_state(world->get_space());
391
392 PhysicsDirectSpaceState::ShapeResult sr[MAX_INTERSECT_AREAS];
393
394 int areas = space_state->intersect_point(global_pos, sr, MAX_INTERSECT_AREAS, Set<RID>(), area_mask, false, true);
395 Area *area = NULL;
396
397 for (int i = 0; i < areas; i++) {
398 if (!sr[i].collider)
399 continue;
400
401 Area *tarea = Object::cast_to<Area>(sr[i].collider);
402 if (!tarea)
403 continue;
404
405 if (!tarea->is_overriding_audio_bus() && !tarea->is_using_reverb_bus())
406 continue;
407
408 area = tarea;
409 break;
410 }
411
412 List<Camera *> cameras;
413 world->get_camera_list(&cameras);
414
415 for (List<Camera *>::Element *E = cameras.front(); E; E = E->next()) {
416
417 Camera *camera = E->get();
418 Viewport *vp = camera->get_viewport();
419 if (!vp->is_audio_listener())
420 continue;
421
422 bool listener_is_camera = true;
423 Spatial *listener_node = camera;
424
425 Listener *listener = vp->get_listener();
426 if (listener) {
427 listener_node = listener;
428 listener_is_camera = false;
429 }
430
431 Vector3 local_pos = listener_node->get_global_transform().orthonormalized().affine_inverse().xform(global_pos);
432
433 float dist = local_pos.length();
434
435 Vector3 area_sound_pos;
436 Vector3 listener_area_pos;
437
438 if (area && area->is_using_reverb_bus() && area->get_reverb_uniformity() > 0) {
439 area_sound_pos = space_state->get_closest_point_to_object_volume(area->get_rid(), listener_node->get_global_transform().origin);
440 listener_area_pos = listener_node->get_global_transform().affine_inverse().xform(area_sound_pos);
441 }
442
443 if (max_distance > 0) {
444
445 float total_max = max_distance;
446
447 if (area && area->is_using_reverb_bus() && area->get_reverb_uniformity() > 0) {
448 total_max = MAX(total_max, listener_area_pos.length());
449 }
450 if (total_max > max_distance) {
451 continue; //can't hear this sound in this listener
452 }
453 }
454
455 float multiplier = Math::db2linear(_get_attenuation_db(dist));
456 if (max_distance > 0) {
457 multiplier *= MAX(0, 1.0 - (dist / max_distance));
458 }
459
460 Output output;
461 output.bus_index = bus_index;
462 output.reverb_bus_index = -1; //no reverb by default
463 output.viewport = vp;
464
465 float db_att = (1.0 - MIN(1.0, multiplier)) * attenuation_filter_db;
466
467 if (emission_angle_enabled) {
468 Vector3 listenertopos = global_pos - listener_node->get_global_transform().origin;
469 float c = listenertopos.normalized().dot(get_global_transform().basis.get_axis(2).normalized()); //it's z negative
470 float angle = Math::rad2deg(Math::acos(c));
471 if (angle > emission_angle)
472 db_att -= -emission_angle_filter_attenuation_db;
473 }
474
475 output.filter_gain = Math::db2linear(db_att);
476
477 //TODO: The lower the second parameter (tightness) the more the sound will "enclose" the listener (more undirected / playing from
478 // speakers not facing the source) - this could be made distance dependent.
479 _calc_output_vol(local_pos.normalized(), 4.0, output);
480
481 unsigned int cc = AudioServer::get_singleton()->get_channel_count();
482 for (unsigned int k = 0; k < cc; k++) {
483 output.vol[k] *= multiplier;
484 }
485
486 bool filled_reverb = false;
487 int vol_index_max = AudioServer::get_singleton()->get_speaker_mode() + 1;
488
489 if (area) {
490
491 if (area->is_overriding_audio_bus()) {
492 //override audio bus
493 StringName bus_name = area->get_audio_bus();
494 output.bus_index = AudioServer::get_singleton()->thread_find_bus_index(bus_name);
495 }
496
497 if (area->is_using_reverb_bus()) {
498
499 filled_reverb = true;
500 StringName bus_name = area->get_reverb_bus();
501 output.reverb_bus_index = AudioServer::get_singleton()->thread_find_bus_index(bus_name);
502
503 float uniformity = area->get_reverb_uniformity();
504 float area_send = area->get_reverb_amount();
505
506 if (uniformity > 0.0) {
507
508 float distance = listener_area_pos.length();
509 float attenuation = Math::db2linear(_get_attenuation_db(distance));
510
511 //float dist_att_db = -20 * Math::log(dist + 0.00001); //logarithmic attenuation, like in real life
512
513 float center_val[3] = { 0.5f, 0.25f, 0.16666f };
514 AudioFrame center_frame(center_val[vol_index_max - 1], center_val[vol_index_max - 1]);
515
516 if (attenuation < 1.0) {
517 //pan the uniform sound
518 Vector3 rev_pos = listener_area_pos;
519 rev_pos.y = 0;
520 rev_pos.normalize();
521
522 if (cc >= 1) {
523 // Stereo pair
524 float c = rev_pos.x * 0.5 + 0.5;
525 output.reverb_vol[0].l = 1.0 - c;
526 output.reverb_vol[0].r = c;
527 }
528
529 if (cc >= 3) {
530 // Center pair + Side pair
531 float xl = Vector3(-1, 0, -1).normalized().dot(rev_pos) * 0.5 + 0.5;
532 float xr = Vector3(1, 0, -1).normalized().dot(rev_pos) * 0.5 + 0.5;
533
534 output.reverb_vol[1].l = xl;
535 output.reverb_vol[1].r = xr;
536 output.reverb_vol[2].l = 1.0 - xr;
537 output.reverb_vol[2].r = 1.0 - xl;
538 }
539
540 if (cc >= 4) {
541 // Rear pair
542 // FIXME: Not sure what math should be done here
543 float c = rev_pos.x * 0.5 + 0.5;
544 output.reverb_vol[3].l = 1.0 - c;
545 output.reverb_vol[3].r = c;
546 }
547
548 for (int i = 0; i < vol_index_max; i++) {
549
550 output.reverb_vol[i] = output.reverb_vol[i].linear_interpolate(center_frame, attenuation);
551 }
552 } else {
553 for (int i = 0; i < vol_index_max; i++) {
554
555 output.reverb_vol[i] = center_frame;
556 }
557 }
558
559 for (int i = 0; i < vol_index_max; i++) {
560
561 output.reverb_vol[i] = output.vol[i].linear_interpolate(output.reverb_vol[i] * attenuation, uniformity);
562 output.reverb_vol[i] *= area_send;
563 }
564
565 } else {
566
567 for (int i = 0; i < vol_index_max; i++) {
568
569 output.reverb_vol[i] = output.vol[i] * area_send;
570 }
571 }
572 }
573 }
574
575 if (doppler_tracking != DOPPLER_TRACKING_DISABLED) {
576
577 Vector3 listener_velocity;
578
579 if (listener_is_camera) {
580 listener_velocity = camera->get_doppler_tracked_velocity();
581 }
582
583 Vector3 local_velocity = listener_node->get_global_transform().orthonormalized().basis.xform_inv(linear_velocity - listener_velocity);
584
585 if (local_velocity == Vector3()) {
586 output.pitch_scale = 1.0;
587 } else {
588 float approaching = local_pos.normalized().dot(local_velocity.normalized());
589 float velocity = local_velocity.length();
590 float speed_of_sound = 343.0;
591
592 output.pitch_scale = speed_of_sound / (speed_of_sound + velocity * approaching);
593 output.pitch_scale = CLAMP(output.pitch_scale, (1 / 8.0), 8.0); //avoid crazy stuff
594 }
595
596 } else {
597 output.pitch_scale = 1.0;
598 }
599
600 if (!filled_reverb) {
601
602 for (int i = 0; i < vol_index_max; i++) {
603
604 output.reverb_vol[i] = AudioFrame(0, 0);
605 }
606 }
607
608 outputs[new_output_count] = output;
609 new_output_count++;
610 if (new_output_count == MAX_OUTPUTS)
611 break;
612 }
613
614 output_count = new_output_count;
615 output_ready = true;
616 }
617
618 //start playing if requested
619 if (setplay >= 0.0) {
620 setseek = setplay;
621 active = true;
622 setplay = -1;
623 //do not update, this makes it easier to animate (will shut off otherwise)
624 ///_change_notify("playing"); //update property in editor
625 }
626
627 //stop playing if no longer active
628 if (!active) {
629 set_physics_process_internal(false);
630 //do not update, this makes it easier to animate (will shut off otherwise)
631 //_change_notify("playing"); //update property in editor
632 emit_signal("finished");
633 }
634 }
635 }
636
set_stream(Ref<AudioStream> p_stream)637 void AudioStreamPlayer3D::set_stream(Ref<AudioStream> p_stream) {
638
639 AudioServer::get_singleton()->lock();
640
641 mix_buffer.resize(AudioServer::get_singleton()->thread_get_mix_buffer_size());
642
643 if (stream_playback.is_valid()) {
644 stream_playback.unref();
645 stream.unref();
646 active = false;
647 setseek = -1;
648 }
649
650 if (p_stream.is_valid()) {
651 stream = p_stream;
652 stream_playback = p_stream->instance_playback();
653 }
654
655 AudioServer::get_singleton()->unlock();
656
657 if (p_stream.is_valid() && stream_playback.is_null()) {
658 stream.unref();
659 }
660 }
661
get_stream() const662 Ref<AudioStream> AudioStreamPlayer3D::get_stream() const {
663
664 return stream;
665 }
666
set_unit_db(float p_volume)667 void AudioStreamPlayer3D::set_unit_db(float p_volume) {
668
669 unit_db = p_volume;
670 }
get_unit_db() const671 float AudioStreamPlayer3D::get_unit_db() const {
672
673 return unit_db;
674 }
675
set_unit_size(float p_volume)676 void AudioStreamPlayer3D::set_unit_size(float p_volume) {
677
678 unit_size = p_volume;
679 }
get_unit_size() const680 float AudioStreamPlayer3D::get_unit_size() const {
681
682 return unit_size;
683 }
684
set_max_db(float p_boost)685 void AudioStreamPlayer3D::set_max_db(float p_boost) {
686
687 max_db = p_boost;
688 }
get_max_db() const689 float AudioStreamPlayer3D::get_max_db() const {
690
691 return max_db;
692 }
693
set_pitch_scale(float p_pitch_scale)694 void AudioStreamPlayer3D::set_pitch_scale(float p_pitch_scale) {
695 ERR_FAIL_COND(p_pitch_scale <= 0.0);
696 pitch_scale = p_pitch_scale;
697 }
get_pitch_scale() const698 float AudioStreamPlayer3D::get_pitch_scale() const {
699 return pitch_scale;
700 }
701
play(float p_from_pos)702 void AudioStreamPlayer3D::play(float p_from_pos) {
703
704 if (!is_playing()) {
705 // Reset the prev_output_count if the stream is stopped
706 prev_output_count = 0;
707 }
708
709 if (stream_playback.is_valid()) {
710 active = true;
711 setplay = p_from_pos;
712 output_ready = false;
713 set_physics_process_internal(true);
714 }
715 }
716
seek(float p_seconds)717 void AudioStreamPlayer3D::seek(float p_seconds) {
718
719 if (stream_playback.is_valid()) {
720 setseek = p_seconds;
721 }
722 }
723
stop()724 void AudioStreamPlayer3D::stop() {
725
726 if (stream_playback.is_valid()) {
727 active = false;
728 set_physics_process_internal(false);
729 setplay = -1;
730 }
731 }
732
is_playing() const733 bool AudioStreamPlayer3D::is_playing() const {
734
735 if (stream_playback.is_valid()) {
736 return active; // && stream_playback->is_playing();
737 }
738
739 return false;
740 }
741
get_playback_position()742 float AudioStreamPlayer3D::get_playback_position() {
743
744 if (stream_playback.is_valid()) {
745 return stream_playback->get_playback_position();
746 }
747
748 return 0;
749 }
750
set_bus(const StringName & p_bus)751 void AudioStreamPlayer3D::set_bus(const StringName &p_bus) {
752
753 //if audio is active, must lock this
754 AudioServer::get_singleton()->lock();
755 bus = p_bus;
756 AudioServer::get_singleton()->unlock();
757 }
get_bus() const758 StringName AudioStreamPlayer3D::get_bus() const {
759
760 for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) {
761 if (AudioServer::get_singleton()->get_bus_name(i) == bus) {
762 return bus;
763 }
764 }
765 return "Master";
766 }
767
set_autoplay(bool p_enable)768 void AudioStreamPlayer3D::set_autoplay(bool p_enable) {
769
770 autoplay = p_enable;
771 }
is_autoplay_enabled()772 bool AudioStreamPlayer3D::is_autoplay_enabled() {
773
774 return autoplay;
775 }
776
_set_playing(bool p_enable)777 void AudioStreamPlayer3D::_set_playing(bool p_enable) {
778
779 if (p_enable)
780 play();
781 else
782 stop();
783 }
_is_active() const784 bool AudioStreamPlayer3D::_is_active() const {
785
786 return active;
787 }
788
_validate_property(PropertyInfo & property) const789 void AudioStreamPlayer3D::_validate_property(PropertyInfo &property) const {
790
791 if (property.name == "bus") {
792
793 String options;
794 for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) {
795 if (i > 0)
796 options += ",";
797 String name = AudioServer::get_singleton()->get_bus_name(i);
798 options += name;
799 }
800
801 property.hint_string = options;
802 }
803 }
804
_bus_layout_changed()805 void AudioStreamPlayer3D::_bus_layout_changed() {
806
807 _change_notify();
808 }
809
set_max_distance(float p_metres)810 void AudioStreamPlayer3D::set_max_distance(float p_metres) {
811
812 ERR_FAIL_COND(p_metres < 0.0);
813 max_distance = p_metres;
814 }
815
get_max_distance() const816 float AudioStreamPlayer3D::get_max_distance() const {
817
818 return max_distance;
819 }
820
set_area_mask(uint32_t p_mask)821 void AudioStreamPlayer3D::set_area_mask(uint32_t p_mask) {
822
823 area_mask = p_mask;
824 }
825
get_area_mask() const826 uint32_t AudioStreamPlayer3D::get_area_mask() const {
827
828 return area_mask;
829 }
830
set_emission_angle_enabled(bool p_enable)831 void AudioStreamPlayer3D::set_emission_angle_enabled(bool p_enable) {
832 emission_angle_enabled = p_enable;
833 update_gizmo();
834 }
835
is_emission_angle_enabled() const836 bool AudioStreamPlayer3D::is_emission_angle_enabled() const {
837 return emission_angle_enabled;
838 }
839
set_emission_angle(float p_angle)840 void AudioStreamPlayer3D::set_emission_angle(float p_angle) {
841 ERR_FAIL_COND(p_angle < 0 || p_angle > 90);
842 emission_angle = p_angle;
843 update_gizmo();
844 _change_notify("emission_angle");
845 }
846
get_emission_angle() const847 float AudioStreamPlayer3D::get_emission_angle() const {
848 return emission_angle;
849 }
850
set_emission_angle_filter_attenuation_db(float p_angle_attenuation_db)851 void AudioStreamPlayer3D::set_emission_angle_filter_attenuation_db(float p_angle_attenuation_db) {
852
853 emission_angle_filter_attenuation_db = p_angle_attenuation_db;
854 }
855
get_emission_angle_filter_attenuation_db() const856 float AudioStreamPlayer3D::get_emission_angle_filter_attenuation_db() const {
857
858 return emission_angle_filter_attenuation_db;
859 }
860
set_attenuation_filter_cutoff_hz(float p_hz)861 void AudioStreamPlayer3D::set_attenuation_filter_cutoff_hz(float p_hz) {
862
863 attenuation_filter_cutoff_hz = p_hz;
864 }
get_attenuation_filter_cutoff_hz() const865 float AudioStreamPlayer3D::get_attenuation_filter_cutoff_hz() const {
866
867 return attenuation_filter_cutoff_hz;
868 }
869
set_attenuation_filter_db(float p_db)870 void AudioStreamPlayer3D::set_attenuation_filter_db(float p_db) {
871
872 attenuation_filter_db = p_db;
873 }
get_attenuation_filter_db() const874 float AudioStreamPlayer3D::get_attenuation_filter_db() const {
875
876 return attenuation_filter_db;
877 }
878
set_attenuation_model(AttenuationModel p_model)879 void AudioStreamPlayer3D::set_attenuation_model(AttenuationModel p_model) {
880 ERR_FAIL_INDEX((int)p_model, 4);
881 attenuation_model = p_model;
882 }
883
get_attenuation_model() const884 AudioStreamPlayer3D::AttenuationModel AudioStreamPlayer3D::get_attenuation_model() const {
885 return attenuation_model;
886 }
887
set_out_of_range_mode(OutOfRangeMode p_mode)888 void AudioStreamPlayer3D::set_out_of_range_mode(OutOfRangeMode p_mode) {
889
890 ERR_FAIL_INDEX((int)p_mode, 2);
891 out_of_range_mode = p_mode;
892 }
893
get_out_of_range_mode() const894 AudioStreamPlayer3D::OutOfRangeMode AudioStreamPlayer3D::get_out_of_range_mode() const {
895
896 return out_of_range_mode;
897 }
898
set_doppler_tracking(DopplerTracking p_tracking)899 void AudioStreamPlayer3D::set_doppler_tracking(DopplerTracking p_tracking) {
900
901 if (doppler_tracking == p_tracking)
902 return;
903
904 doppler_tracking = p_tracking;
905
906 if (doppler_tracking != DOPPLER_TRACKING_DISABLED) {
907 set_notify_transform(true);
908 velocity_tracker->set_track_physics_step(doppler_tracking == DOPPLER_TRACKING_PHYSICS_STEP);
909 if (is_inside_tree()) {
910 velocity_tracker->reset(get_global_transform().origin);
911 }
912 } else {
913 set_notify_transform(false);
914 }
915 }
916
get_doppler_tracking() const917 AudioStreamPlayer3D::DopplerTracking AudioStreamPlayer3D::get_doppler_tracking() const {
918
919 return doppler_tracking;
920 }
921
set_stream_paused(bool p_pause)922 void AudioStreamPlayer3D::set_stream_paused(bool p_pause) {
923
924 if (p_pause != stream_paused) {
925 stream_paused = p_pause;
926 stream_paused_fade_in = !stream_paused;
927 stream_paused_fade_out = stream_paused;
928 }
929 }
930
get_stream_paused() const931 bool AudioStreamPlayer3D::get_stream_paused() const {
932
933 return stream_paused;
934 }
935
get_stream_playback()936 Ref<AudioStreamPlayback> AudioStreamPlayer3D::get_stream_playback() {
937 return stream_playback;
938 }
939
_bind_methods()940 void AudioStreamPlayer3D::_bind_methods() {
941
942 ClassDB::bind_method(D_METHOD("set_stream", "stream"), &AudioStreamPlayer3D::set_stream);
943 ClassDB::bind_method(D_METHOD("get_stream"), &AudioStreamPlayer3D::get_stream);
944
945 ClassDB::bind_method(D_METHOD("set_unit_db", "unit_db"), &AudioStreamPlayer3D::set_unit_db);
946 ClassDB::bind_method(D_METHOD("get_unit_db"), &AudioStreamPlayer3D::get_unit_db);
947
948 ClassDB::bind_method(D_METHOD("set_unit_size", "unit_size"), &AudioStreamPlayer3D::set_unit_size);
949 ClassDB::bind_method(D_METHOD("get_unit_size"), &AudioStreamPlayer3D::get_unit_size);
950
951 ClassDB::bind_method(D_METHOD("set_max_db", "max_db"), &AudioStreamPlayer3D::set_max_db);
952 ClassDB::bind_method(D_METHOD("get_max_db"), &AudioStreamPlayer3D::get_max_db);
953
954 ClassDB::bind_method(D_METHOD("set_pitch_scale", "pitch_scale"), &AudioStreamPlayer3D::set_pitch_scale);
955 ClassDB::bind_method(D_METHOD("get_pitch_scale"), &AudioStreamPlayer3D::get_pitch_scale);
956
957 ClassDB::bind_method(D_METHOD("play", "from_position"), &AudioStreamPlayer3D::play, DEFVAL(0.0));
958 ClassDB::bind_method(D_METHOD("seek", "to_position"), &AudioStreamPlayer3D::seek);
959 ClassDB::bind_method(D_METHOD("stop"), &AudioStreamPlayer3D::stop);
960
961 ClassDB::bind_method(D_METHOD("is_playing"), &AudioStreamPlayer3D::is_playing);
962 ClassDB::bind_method(D_METHOD("get_playback_position"), &AudioStreamPlayer3D::get_playback_position);
963
964 ClassDB::bind_method(D_METHOD("set_bus", "bus"), &AudioStreamPlayer3D::set_bus);
965 ClassDB::bind_method(D_METHOD("get_bus"), &AudioStreamPlayer3D::get_bus);
966
967 ClassDB::bind_method(D_METHOD("set_autoplay", "enable"), &AudioStreamPlayer3D::set_autoplay);
968 ClassDB::bind_method(D_METHOD("is_autoplay_enabled"), &AudioStreamPlayer3D::is_autoplay_enabled);
969
970 ClassDB::bind_method(D_METHOD("_set_playing", "enable"), &AudioStreamPlayer3D::_set_playing);
971 ClassDB::bind_method(D_METHOD("_is_active"), &AudioStreamPlayer3D::_is_active);
972
973 ClassDB::bind_method(D_METHOD("set_max_distance", "metres"), &AudioStreamPlayer3D::set_max_distance);
974 ClassDB::bind_method(D_METHOD("get_max_distance"), &AudioStreamPlayer3D::get_max_distance);
975
976 ClassDB::bind_method(D_METHOD("set_area_mask", "mask"), &AudioStreamPlayer3D::set_area_mask);
977 ClassDB::bind_method(D_METHOD("get_area_mask"), &AudioStreamPlayer3D::get_area_mask);
978
979 ClassDB::bind_method(D_METHOD("set_emission_angle", "degrees"), &AudioStreamPlayer3D::set_emission_angle);
980 ClassDB::bind_method(D_METHOD("get_emission_angle"), &AudioStreamPlayer3D::get_emission_angle);
981
982 ClassDB::bind_method(D_METHOD("set_emission_angle_enabled", "enabled"), &AudioStreamPlayer3D::set_emission_angle_enabled);
983 ClassDB::bind_method(D_METHOD("is_emission_angle_enabled"), &AudioStreamPlayer3D::is_emission_angle_enabled);
984
985 ClassDB::bind_method(D_METHOD("set_emission_angle_filter_attenuation_db", "db"), &AudioStreamPlayer3D::set_emission_angle_filter_attenuation_db);
986 ClassDB::bind_method(D_METHOD("get_emission_angle_filter_attenuation_db"), &AudioStreamPlayer3D::get_emission_angle_filter_attenuation_db);
987
988 ClassDB::bind_method(D_METHOD("set_attenuation_filter_cutoff_hz", "degrees"), &AudioStreamPlayer3D::set_attenuation_filter_cutoff_hz);
989 ClassDB::bind_method(D_METHOD("get_attenuation_filter_cutoff_hz"), &AudioStreamPlayer3D::get_attenuation_filter_cutoff_hz);
990
991 ClassDB::bind_method(D_METHOD("set_attenuation_filter_db", "db"), &AudioStreamPlayer3D::set_attenuation_filter_db);
992 ClassDB::bind_method(D_METHOD("get_attenuation_filter_db"), &AudioStreamPlayer3D::get_attenuation_filter_db);
993
994 ClassDB::bind_method(D_METHOD("set_attenuation_model", "model"), &AudioStreamPlayer3D::set_attenuation_model);
995 ClassDB::bind_method(D_METHOD("get_attenuation_model"), &AudioStreamPlayer3D::get_attenuation_model);
996
997 ClassDB::bind_method(D_METHOD("set_out_of_range_mode", "mode"), &AudioStreamPlayer3D::set_out_of_range_mode);
998 ClassDB::bind_method(D_METHOD("get_out_of_range_mode"), &AudioStreamPlayer3D::get_out_of_range_mode);
999
1000 ClassDB::bind_method(D_METHOD("set_doppler_tracking", "mode"), &AudioStreamPlayer3D::set_doppler_tracking);
1001 ClassDB::bind_method(D_METHOD("get_doppler_tracking"), &AudioStreamPlayer3D::get_doppler_tracking);
1002
1003 ClassDB::bind_method(D_METHOD("set_stream_paused", "pause"), &AudioStreamPlayer3D::set_stream_paused);
1004 ClassDB::bind_method(D_METHOD("get_stream_paused"), &AudioStreamPlayer3D::get_stream_paused);
1005
1006 ClassDB::bind_method(D_METHOD("get_stream_playback"), &AudioStreamPlayer3D::get_stream_playback);
1007
1008 ClassDB::bind_method(D_METHOD("_bus_layout_changed"), &AudioStreamPlayer3D::_bus_layout_changed);
1009
1010 ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "stream", PROPERTY_HINT_RESOURCE_TYPE, "AudioStream"), "set_stream", "get_stream");
1011 ADD_PROPERTY(PropertyInfo(Variant::INT, "attenuation_model", PROPERTY_HINT_ENUM, "Inverse,InverseSquare,Log,Disabled"), "set_attenuation_model", "get_attenuation_model");
1012 ADD_PROPERTY(PropertyInfo(Variant::REAL, "unit_db", PROPERTY_HINT_RANGE, "-80,80"), "set_unit_db", "get_unit_db");
1013 ADD_PROPERTY(PropertyInfo(Variant::REAL, "unit_size", PROPERTY_HINT_RANGE, "0.1,100,0.1"), "set_unit_size", "get_unit_size");
1014 ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_db", PROPERTY_HINT_RANGE, "-24,6"), "set_max_db", "get_max_db");
1015 ADD_PROPERTY(PropertyInfo(Variant::REAL, "pitch_scale", PROPERTY_HINT_RANGE, "0.01,4,0.01,or_greater"), "set_pitch_scale", "get_pitch_scale");
1016 ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_playing", "is_playing");
1017 ADD_PROPERTY(PropertyInfo(Variant::BOOL, "autoplay"), "set_autoplay", "is_autoplay_enabled");
1018 ADD_PROPERTY(PropertyInfo(Variant::BOOL, "stream_paused", PROPERTY_HINT_NONE, ""), "set_stream_paused", "get_stream_paused");
1019 ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_distance", PROPERTY_HINT_EXP_RANGE, "0,4096,1,or_greater"), "set_max_distance", "get_max_distance");
1020 ADD_PROPERTY(PropertyInfo(Variant::INT, "out_of_range_mode", PROPERTY_HINT_ENUM, "Mix,Pause"), "set_out_of_range_mode", "get_out_of_range_mode");
1021 ADD_PROPERTY(PropertyInfo(Variant::STRING, "bus", PROPERTY_HINT_ENUM, ""), "set_bus", "get_bus");
1022 ADD_PROPERTY(PropertyInfo(Variant::INT, "area_mask", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_area_mask", "get_area_mask");
1023 ADD_GROUP("Emission Angle", "emission_angle");
1024 ADD_PROPERTY(PropertyInfo(Variant::BOOL, "emission_angle_enabled"), "set_emission_angle_enabled", "is_emission_angle_enabled");
1025 ADD_PROPERTY(PropertyInfo(Variant::REAL, "emission_angle_degrees", PROPERTY_HINT_RANGE, "0.1,90,0.1"), "set_emission_angle", "get_emission_angle");
1026 ADD_PROPERTY(PropertyInfo(Variant::REAL, "emission_angle_filter_attenuation_db", PROPERTY_HINT_RANGE, "-80,0,0.1"), "set_emission_angle_filter_attenuation_db", "get_emission_angle_filter_attenuation_db");
1027 ADD_GROUP("Attenuation Filter", "attenuation_filter_");
1028 ADD_PROPERTY(PropertyInfo(Variant::REAL, "attenuation_filter_cutoff_hz", PROPERTY_HINT_RANGE, "1,20500,1"), "set_attenuation_filter_cutoff_hz", "get_attenuation_filter_cutoff_hz");
1029 ADD_PROPERTY(PropertyInfo(Variant::REAL, "attenuation_filter_db", PROPERTY_HINT_RANGE, "-80,0,0.1"), "set_attenuation_filter_db", "get_attenuation_filter_db");
1030 ADD_GROUP("Doppler", "doppler_");
1031 ADD_PROPERTY(PropertyInfo(Variant::INT, "doppler_tracking", PROPERTY_HINT_ENUM, "Disabled,Idle,Physics"), "set_doppler_tracking", "get_doppler_tracking");
1032
1033 BIND_ENUM_CONSTANT(ATTENUATION_INVERSE_DISTANCE);
1034 BIND_ENUM_CONSTANT(ATTENUATION_INVERSE_SQUARE_DISTANCE);
1035 BIND_ENUM_CONSTANT(ATTENUATION_LOGARITHMIC);
1036 BIND_ENUM_CONSTANT(ATTENUATION_DISABLED);
1037
1038 BIND_ENUM_CONSTANT(OUT_OF_RANGE_MIX);
1039 BIND_ENUM_CONSTANT(OUT_OF_RANGE_PAUSE);
1040
1041 BIND_ENUM_CONSTANT(DOPPLER_TRACKING_DISABLED);
1042 BIND_ENUM_CONSTANT(DOPPLER_TRACKING_IDLE_STEP);
1043 BIND_ENUM_CONSTANT(DOPPLER_TRACKING_PHYSICS_STEP);
1044
1045 ADD_SIGNAL(MethodInfo("finished"));
1046 }
1047
AudioStreamPlayer3D()1048 AudioStreamPlayer3D::AudioStreamPlayer3D() {
1049
1050 unit_db = 0;
1051 unit_size = 1;
1052 attenuation_model = ATTENUATION_INVERSE_DISTANCE;
1053 max_db = 3;
1054 pitch_scale = 1.0;
1055 autoplay = false;
1056 setseek = -1;
1057 active = false;
1058 output_count = 0;
1059 prev_output_count = 0;
1060 max_distance = 0;
1061 setplay = -1;
1062 output_ready = false;
1063 area_mask = 1;
1064 emission_angle = 45;
1065 emission_angle_enabled = false;
1066 emission_angle_filter_attenuation_db = -12;
1067 attenuation_filter_cutoff_hz = 5000;
1068 attenuation_filter_db = -24;
1069 out_of_range_mode = OUT_OF_RANGE_MIX;
1070 doppler_tracking = DOPPLER_TRACKING_DISABLED;
1071 stream_paused = false;
1072 stream_paused_fade_in = false;
1073 stream_paused_fade_out = false;
1074
1075 velocity_tracker.instance();
1076 AudioServer::get_singleton()->connect("bus_layout_changed", this, "_bus_layout_changed");
1077 set_disable_scale(true);
1078 }
~AudioStreamPlayer3D()1079 AudioStreamPlayer3D::~AudioStreamPlayer3D() {
1080 }
1081