Browse Source

Merge pull request #17599 from marcelofg55/channels_crashfix

Fix possible crash when audio channels change
Rémi Verschelde 7 năm trước cách đây
mục cha
commit
bb5e5fca43
2 tập tin đã thay đổi với 33 bổ sung11 xóa
  1. 30 11
      servers/audio_server.cpp
  2. 3 0
      servers/audio_server.h

+ 30 - 11
servers/audio_server.cpp

@@ -172,6 +172,12 @@ void AudioServer::_driver_process(int p_frames, int32_t *p_buffer) {
 
 	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) {
 
 		if (to_mix == 0) {
@@ -485,8 +491,8 @@ void AudioServer::set_bus_count(int p_count) {
 		}
 
 		buses[i] = memnew(Bus);
-		buses[i]->channels.resize(get_channel_count());
-		for (int j = 0; j < get_channel_count(); j++) {
+		buses[i]->channels.resize(channel_count);
+		for (int j = 0; j < channel_count; j++) {
 			buses[i]->channels[j].buffer.resize(buffer_size);
 		}
 		buses[i]->name = attempt;
@@ -557,8 +563,8 @@ void AudioServer::add_bus(int p_at_pos) {
 	}
 
 	Bus *bus = memnew(Bus);
-	bus->channels.resize(get_channel_count());
-	for (int j = 0; j < get_channel_count(); j++) {
+	bus->channels.resize(channel_count);
+	for (int j = 0; j < channel_count; j++) {
 		bus->channels[j].buffer.resize(buffer_size);
 	}
 	bus->name = attempt;
@@ -860,17 +866,29 @@ bool AudioServer::is_bus_channel_active(int p_bus, int p_channel) const {
 	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() {
 
 	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();
 	buffer_size = 1024; //hardcoded for now
 
-	temp_buffer.resize(get_channel_count());
-
-	for (int i = 0; i < temp_buffer.size(); i++) {
-		temp_buffer[i].resize(buffer_size);
-	}
+	init_channels_and_buffers();
 
 	mix_count = 0;
 	set_bus_count(1);
@@ -1052,8 +1070,8 @@ void AudioServer::set_bus_layout(const Ref<AudioBusLayout> &p_bus_layout) {
 		bus_map[bus->name] = bus;
 		buses[i] = bus;
 
-		buses[i]->channels.resize(get_channel_count());
-		for (int j = 0; j < get_channel_count(); j++) {
+		buses[i]->channels.resize(channel_count);
+		for (int j = 0; j < channel_count; j++) {
 			buses[i]->channels[j].buffer.resize(buffer_size);
 		}
 		_update_bus_effects(i);
@@ -1154,6 +1172,7 @@ AudioServer::AudioServer() {
 	audio_data_max_mem = 0;
 	audio_data_lock = Mutex::create();
 	mix_frames = 0;
+	channel_count = 0;
 	to_mix = 0;
 }
 

+ 3 - 0
servers/audio_server.h

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