Ability to remove buses while they are being used on 2D and 3D stream players. Fixes #15115

This commit is contained in:
Juan Linietsky 2018-11-13 18:16:33 -03:00
parent 5613aa489e
commit 65111ba996
4 changed files with 27 additions and 1 deletions

View file

@ -92,6 +92,9 @@ void AudioStreamPlayer2D::_mix_audio() {
int cc = AudioServer::get_singleton()->get_channel_count();
if (cc == 1) {
if (!AudioServer::get_singleton()->thread_has_channel_mix_buffer(current.bus_index, 0))
continue; //may have been removed
AudioFrame *target = AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, 0);
for (int j = 0; j < buffer_size; j++) {
@ -102,11 +105,20 @@ void AudioStreamPlayer2D::_mix_audio() {
} else {
AudioFrame *targets[4];
bool valid = true;
for (int k = 0; k < cc; k++) {
if (!AudioServer::get_singleton()->thread_has_channel_mix_buffer(current.bus_index, k)) {
valid = false; //may have been removed
break;
}
targets[k] = AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, k);
}
if (!valid)
continue;
for (int j = 0; j < buffer_size; j++) {
AudioFrame frame = buffer[j] * vol;

View file

@ -112,8 +112,10 @@ void AudioStreamPlayer3D::_mix_audio() {
AudioFrame vol_inc = (target_volume - vol_prev) / float(buffer_size);
AudioFrame vol = stream_paused_fade_in ? AudioFrame(0.f, 0.f) : current.vol[k];
AudioFrame *target = AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, k);
if (!AudioServer::get_singleton()->thread_has_channel_mix_buffer(current.bus_index, k))
continue; //may have been deleted, will be updated on process
AudioFrame *target = AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, k);
current.filter.set_mode(AudioFilterSW::HIGHSHELF);
current.filter.set_sampling_rate(AudioServer::get_singleton()->get_mix_rate());
current.filter.set_cutoff(attenuation_filter_cutoff_hz);
@ -159,6 +161,9 @@ void AudioStreamPlayer3D::_mix_audio() {
if (current.reverb_bus_index >= 0) {
if (!AudioServer::get_singleton()->thread_has_channel_mix_buffer(current.reverb_bus_index, k))
continue; //may have been deleted, will be updated on process
AudioFrame *rtarget = AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.reverb_bus_index, k);
if (current.reverb_bus_index == prev_outputs[i].reverb_bus_index) {

View file

@ -460,6 +460,14 @@ void AudioServer::_mix_step() {
to_mix = buffer_size;
}
bool AudioServer::thread_has_channel_mix_buffer(int p_bus, int p_buffer) const {
if (p_bus < 0 || p_bus >= buses.size())
return false;
if (p_buffer < 0 || p_buffer >= buses[p_bus]->channels.size())
return false;
return true;
}
AudioFrame *AudioServer::thread_get_channel_mix_buffer(int p_bus, int p_buffer) {
ERR_FAIL_INDEX_V(p_bus, buses.size(), NULL);

View file

@ -282,6 +282,7 @@ public:
}
//do not use from outside audio thread
bool thread_has_channel_mix_buffer(int p_bus, int p_buffer) const;
AudioFrame *thread_get_channel_mix_buffer(int p_bus, int p_buffer);
int thread_get_mix_buffer_size() const;
int thread_find_bus_index(const StringName &p_name);