|
@@ -40,13 +40,19 @@ void AudioDriverPulseAudio::pa_state_cb(pa_context *c, void *userdata) {
|
|
|
|
|
|
switch (pa_context_get_state(c)) {
|
|
switch (pa_context_get_state(c)) {
|
|
case PA_CONTEXT_TERMINATED:
|
|
case PA_CONTEXT_TERMINATED:
|
|
|
|
+ print_verbose("PulseAudio: context terminated");
|
|
|
|
+ ad->pa_ready = -1;
|
|
|
|
+ break;
|
|
case PA_CONTEXT_FAILED:
|
|
case PA_CONTEXT_FAILED:
|
|
|
|
+ print_verbose("PulseAudio: context failed");
|
|
ad->pa_ready = -1;
|
|
ad->pa_ready = -1;
|
|
break;
|
|
break;
|
|
case PA_CONTEXT_READY:
|
|
case PA_CONTEXT_READY:
|
|
|
|
+ print_verbose("PulseAudio: context ready");
|
|
ad->pa_ready = 1;
|
|
ad->pa_ready = 1;
|
|
break;
|
|
break;
|
|
default:
|
|
default:
|
|
|
|
+ print_verbose("PulseAudio: context other");
|
|
// TODO: Check if we want to handle some of the other
|
|
// TODO: Check if we want to handle some of the other
|
|
// PA context states like PA_CONTEXT_UNCONNECTED.
|
|
// PA context states like PA_CONTEXT_UNCONNECTED.
|
|
break;
|
|
break;
|
|
@@ -61,6 +67,13 @@ void AudioDriverPulseAudio::pa_sink_info_cb(pa_context *c, const pa_sink_info *l
|
|
return;
|
|
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_map = l->channel_map;
|
|
ad->pa_status++;
|
|
ad->pa_status++;
|
|
}
|
|
}
|
|
@@ -73,6 +86,13 @@ void AudioDriverPulseAudio::pa_source_info_cb(pa_context *c, const pa_source_inf
|
|
return;
|
|
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_rec_map = l->channel_map;
|
|
ad->pa_status++;
|
|
ad->pa_status++;
|
|
}
|
|
}
|
|
@@ -86,7 +106,7 @@ void AudioDriverPulseAudio::pa_server_info_cb(pa_context *c, const pa_server_inf
|
|
ad->pa_status++;
|
|
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);
|
|
pa_channel_map_init_stereo(capture ? &pa_rec_map : &pa_map);
|
|
|
|
|
|
String device = capture ? capture_device_name : device_name;
|
|
String device = capture ? capture_device_name : device_name;
|
|
@@ -104,7 +124,8 @@ void AudioDriverPulseAudio::detect_channels(bool capture) {
|
|
|
|
|
|
pa_operation_unref(pa_op);
|
|
pa_operation_unref(pa_op);
|
|
} else {
|
|
} 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 +135,7 @@ void AudioDriverPulseAudio::detect_channels(bool capture) {
|
|
} else {
|
|
} else {
|
|
strcpy(dev, device.utf8().get_data());
|
|
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
|
|
// Now using the device name get the amount of channels
|
|
pa_status = 0;
|
|
pa_status = 0;
|
|
@@ -133,6 +155,10 @@ void AudioDriverPulseAudio::detect_channels(bool capture) {
|
|
}
|
|
}
|
|
|
|
|
|
pa_operation_unref(pa_op);
|
|
pa_operation_unref(pa_op);
|
|
|
|
+
|
|
|
|
+ if (pa_status == -1) {
|
|
|
|
+ return FAILED;
|
|
|
|
+ }
|
|
} else {
|
|
} else {
|
|
if (capture) {
|
|
if (capture) {
|
|
ERR_PRINT("pa_context_get_source_info_by_name error");
|
|
ERR_PRINT("pa_context_get_source_info_by_name error");
|
|
@@ -140,6 +166,8 @@ void AudioDriverPulseAudio::detect_channels(bool capture) {
|
|
ERR_PRINT("pa_context_get_sink_info_by_name error");
|
|
ERR_PRINT("pa_context_get_sink_info_by_name error");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ return OK;
|
|
}
|
|
}
|
|
|
|
|
|
Error AudioDriverPulseAudio::init_device() {
|
|
Error AudioDriverPulseAudio::init_device() {
|
|
@@ -156,7 +184,13 @@ Error AudioDriverPulseAudio::init_device() {
|
|
// Note: If using an even amount of channels (2, 4, etc) channels and pa_map.channels will be equal,
|
|
// 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
|
|
// 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)
|
|
// 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) {
|
|
switch (pa_map.channels) {
|
|
case 1: // Mono
|
|
case 1: // Mono
|
|
case 3: // Surround 2.1
|
|
case 3: // Surround 2.1
|
|
@@ -294,10 +328,8 @@ Error AudioDriverPulseAudio::init() {
|
|
return ERR_CANT_OPEN;
|
|
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;
|
|
return OK;
|
|
}
|
|
}
|
|
@@ -441,7 +473,7 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
|
|
|
|
|
|
pa_operation_unref(pa_op);
|
|
pa_operation_unref(pa_op);
|
|
} else {
|
|
} 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) {
|
|
if (old_default_device != ad->default_device) {
|