diff options
Diffstat (limited to 'drivers/pulseaudio/audio_driver_pulseaudio.cpp')
| -rw-r--r-- | drivers/pulseaudio/audio_driver_pulseaudio.cpp | 56 | 
1 files changed, 48 insertions, 8 deletions
diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.cpp b/drivers/pulseaudio/audio_driver_pulseaudio.cpp index 5e87bc019b..5e2431d44e 100644 --- a/drivers/pulseaudio/audio_driver_pulseaudio.cpp +++ b/drivers/pulseaudio/audio_driver_pulseaudio.cpp @@ -35,18 +35,28 @@  #include "core/config/project_settings.h"  #include "core/os/os.h" +#ifdef ALSAMIDI_ENABLED +#include "drivers/alsa/asound-so_wrap.h" +#endif +  void AudioDriverPulseAudio::pa_state_cb(pa_context *c, void *userdata) {  	AudioDriverPulseAudio *ad = (AudioDriverPulseAudio *)userdata;  	switch (pa_context_get_state(c)) {  		case PA_CONTEXT_TERMINATED: +			print_verbose("PulseAudio: context terminated"); +			ad->pa_ready = -1; +			break;  		case PA_CONTEXT_FAILED: +			print_verbose("PulseAudio: context failed");  			ad->pa_ready = -1;  			break;  		case PA_CONTEXT_READY: +			print_verbose("PulseAudio: context ready");  			ad->pa_ready = 1;  			break;  		default: +			print_verbose("PulseAudio: context other");  			// TODO: Check if we want to handle some of the other  			// PA context states like PA_CONTEXT_UNCONNECTED.  			break; @@ -61,6 +71,13 @@ void AudioDriverPulseAudio::pa_sink_info_cb(pa_context *c, const pa_sink_info *l  		return;  	} +	// If eol is set to a negative number there's an error. +	if (eol < 0) { +		ERR_PRINT("PulseAudio: sink info error: " + String(pa_strerror(pa_context_errno(c)))); +		ad->pa_status--; +		return; +	} +  	ad->pa_map = l->channel_map;  	ad->pa_status++;  } @@ -73,6 +90,13 @@ void AudioDriverPulseAudio::pa_source_info_cb(pa_context *c, const pa_source_inf  		return;  	} +	// If eol is set to a negative number there's an error. +	if (eol < 0) { +		ERR_PRINT("PulseAudio: sink info error: " + String(pa_strerror(pa_context_errno(c)))); +		ad->pa_status--; +		return; +	} +  	ad->pa_rec_map = l->channel_map;  	ad->pa_status++;  } @@ -86,7 +110,7 @@ void AudioDriverPulseAudio::pa_server_info_cb(pa_context *c, const pa_server_inf  	ad->pa_status++;  } -void AudioDriverPulseAudio::detect_channels(bool capture) { +Error AudioDriverPulseAudio::detect_channels(bool capture) {  	pa_channel_map_init_stereo(capture ? &pa_rec_map : &pa_map);  	String device = capture ? capture_device_name : device_name; @@ -104,7 +128,8 @@ void AudioDriverPulseAudio::detect_channels(bool capture) {  			pa_operation_unref(pa_op);  		} else { -			ERR_PRINT("pa_context_get_server_info error"); +			ERR_PRINT("pa_context_get_server_info error: " + String(pa_strerror(pa_context_errno(pa_ctx)))); +			return FAILED;  		}  	} @@ -114,6 +139,7 @@ void AudioDriverPulseAudio::detect_channels(bool capture) {  	} else {  		strcpy(dev, device.utf8().get_data());  	} +	print_verbose("PulseAudio: Detecting channels for device: " + String(dev));  	// Now using the device name get the amount of channels  	pa_status = 0; @@ -133,6 +159,10 @@ void AudioDriverPulseAudio::detect_channels(bool capture) {  		}  		pa_operation_unref(pa_op); + +		if (pa_status == -1) { +			return FAILED; +		}  	} else {  		if (capture) {  			ERR_PRINT("pa_context_get_source_info_by_name error"); @@ -140,6 +170,8 @@ void AudioDriverPulseAudio::detect_channels(bool capture) {  			ERR_PRINT("pa_context_get_sink_info_by_name error");  		}  	} + +	return OK;  }  Error AudioDriverPulseAudio::init_device() { @@ -156,7 +188,13 @@ Error AudioDriverPulseAudio::init_device() {  	// Note: If using an even amount of channels (2, 4, etc) channels and pa_map.channels will be equal,  	// if not then pa_map.channels will have the real amount of channels PulseAudio is using and channels  	// will have the amount of channels Godot is using (in this case it's pa_map.channels + 1) -	detect_channels(); +	Error err = detect_channels(); +	if (err != OK) { +		// This most likely means there are no sinks. +		ERR_PRINT("PulseAudio: init device failed to detect number of channels"); +		return err; +	} +  	switch (pa_map.channels) {  		case 1: // Mono  		case 3: // Surround 2.1 @@ -238,6 +276,10 @@ Error AudioDriverPulseAudio::init() {  #else  	int dylibloader_verbose = 0;  #endif +#ifdef ALSAMIDI_ENABLED +	// If using PulseAudio with ALSA MIDI, we need to initialize ALSA as well +	initialize_asound(dylibloader_verbose); +#endif  	if (initialize_pulse(dylibloader_verbose)) {  		return ERR_CANT_OPEN;  	} @@ -294,10 +336,8 @@ Error AudioDriverPulseAudio::init() {  		return ERR_CANT_OPEN;  	} -	Error err = init_device(); -	if (err == OK) { -		thread.start(AudioDriverPulseAudio::thread_func, this); -	} +	init_device(); +	thread.start(AudioDriverPulseAudio::thread_func, this);  	return OK;  } @@ -441,7 +481,7 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {  					pa_operation_unref(pa_op);  				} else { -					ERR_PRINT("pa_context_get_server_info error"); +					ERR_PRINT("pa_context_get_server_info error: " + String(pa_strerror(pa_context_errno(ad->pa_ctx))));  				}  				if (old_default_device != ad->default_device) {  |