Fix possible crash when audio channels change

(cherry picked from commit 87ebdd6041)
This commit is contained in:
Marcelo Fernandez 2018-03-17 22:43:32 -03:00 committed by Hein-Pieter van Braam
parent a7ea441504
commit a91d9cb918
2 changed files with 33 additions and 11 deletions

View File

@ -184,6 +184,12 @@ void AudioServer::_driver_process(int p_frames, int32_t *p_buffer) {
int todo = p_frames; int todo = p_frames;
if (channel_count != get_channel_count()) {
// Amount of channels changed due to a device change
// reinitialize the buses channels and buffers
init_channels_and_buffers();
}
while (todo) { while (todo) {
if (to_mix == 0) { if (to_mix == 0) {
@ -497,8 +503,8 @@ void AudioServer::set_bus_count(int p_count) {
} }
buses[i] = memnew(Bus); buses[i] = memnew(Bus);
buses[i]->channels.resize(get_channel_count()); buses[i]->channels.resize(channel_count);
for (int j = 0; j < get_channel_count(); j++) { for (int j = 0; j < channel_count; j++) {
buses[i]->channels[j].buffer.resize(buffer_size); buses[i]->channels[j].buffer.resize(buffer_size);
} }
buses[i]->name = attempt; buses[i]->name = attempt;
@ -569,8 +575,8 @@ void AudioServer::add_bus(int p_at_pos) {
} }
Bus *bus = memnew(Bus); Bus *bus = memnew(Bus);
bus->channels.resize(get_channel_count()); bus->channels.resize(channel_count);
for (int j = 0; j < get_channel_count(); j++) { for (int j = 0; j < channel_count; j++) {
bus->channels[j].buffer.resize(buffer_size); bus->channels[j].buffer.resize(buffer_size);
} }
bus->name = attempt; bus->name = attempt;
@ -872,17 +878,29 @@ bool AudioServer::is_bus_channel_active(int p_bus, int p_channel) const {
return buses[p_bus]->channels[p_channel].active; return buses[p_bus]->channels[p_channel].active;
} }
void AudioServer::init_channels_and_buffers() {
channel_count = get_channel_count();
temp_buffer.resize(channel_count);
for (int i = 0; i < temp_buffer.size(); i++) {
temp_buffer[i].resize(buffer_size);
}
for (int i = 0; i < buses.size(); i++) {
buses[i]->channels.resize(channel_count);
for (int j = 0; j < channel_count; j++) {
buses[i]->channels[j].buffer.resize(buffer_size);
}
}
}
void AudioServer::init() { void AudioServer::init() {
channel_disable_threshold_db = GLOBAL_DEF("audio/channel_disable_threshold_db", -60.0); channel_disable_threshold_db = GLOBAL_DEF("audio/channel_disable_threshold_db", -60.0);
channel_disable_frames = float(GLOBAL_DEF("audio/channel_disable_time", 2.0)) * get_mix_rate(); channel_disable_frames = float(GLOBAL_DEF("audio/channel_disable_time", 2.0)) * get_mix_rate();
buffer_size = 1024; //hardcoded for now buffer_size = 1024; //hardcoded for now
temp_buffer.resize(get_channel_count()); init_channels_and_buffers();
for (int i = 0; i < temp_buffer.size(); i++) {
temp_buffer[i].resize(buffer_size);
}
mix_count = 0; mix_count = 0;
set_bus_count(1); set_bus_count(1);
@ -1064,8 +1082,8 @@ void AudioServer::set_bus_layout(const Ref<AudioBusLayout> &p_bus_layout) {
bus_map[bus->name] = bus; bus_map[bus->name] = bus;
buses[i] = bus; buses[i] = bus;
buses[i]->channels.resize(get_channel_count()); buses[i]->channels.resize(channel_count);
for (int j = 0; j < get_channel_count(); j++) { for (int j = 0; j < channel_count; j++) {
buses[i]->channels[j].buffer.resize(buffer_size); buses[i]->channels[j].buffer.resize(buffer_size);
} }
_update_bus_effects(i); _update_bus_effects(i);
@ -1184,6 +1202,7 @@ AudioServer::AudioServer() {
audio_data_max_mem = 0; audio_data_max_mem = 0;
audio_data_lock = Mutex::create(); audio_data_lock = Mutex::create();
mix_frames = 0; mix_frames = 0;
channel_count = 0;
to_mix = 0; to_mix = 0;
} }

View File

@ -133,6 +133,7 @@ private:
float channel_disable_threshold_db; float channel_disable_threshold_db;
uint32_t channel_disable_frames; uint32_t channel_disable_frames;
int channel_count;
int to_mix; int to_mix;
struct Bus { struct Bus {
@ -189,6 +190,8 @@ private:
Mutex *audio_data_lock; Mutex *audio_data_lock;
void init_channels_and_buffers();
void _mix_step(); void _mix_step();
struct CallbackItem { struct CallbackItem {