summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--frontend/audio_hotplug.h49
-rw-r--r--frontend/plat_trimui.c9
2 files changed, 58 insertions, 0 deletions
diff --git a/frontend/audio_hotplug.h b/frontend/audio_hotplug.h
new file mode 100644
index 0000000..db4eb59
--- /dev/null
+++ b/frontend/audio_hotplug.h
@@ -0,0 +1,49 @@
+#ifndef CHECK_AUDIO_H
+#define CHECK_AUDIO_H
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <unistd.h>
+
+/* Only check once every 60 calls, so this can be called every frame
+ * without much penalty */
+#define AUDIO_CHECK_THROTTLE 60
+
+bool found_usb_audio = false;
+bool has_usb_audio = false;
+
+/* Every AUDIO_CHECK_THROTTLE calls, check to see if the USB audio
+ * device has been plugged or unplugged. When the status changes,
+ * calls `reinit_callback` with the new status. */
+void audio_hotplug_check(void (*reinit_callback)(bool has_usb_audio)) {
+ static int count;
+
+ if (++count < AUDIO_CHECK_THROTTLE) return;
+
+ count = 0;
+
+ if (access("/dev/dsp1", R_OK | W_OK) == 0) {
+ found_usb_audio = true;
+ } else {
+ found_usb_audio = false;
+ }
+
+ if (!has_usb_audio && found_usb_audio) {
+ has_usb_audio = true;
+ reinit_callback(true);
+ } else if (has_usb_audio && !found_usb_audio) {
+ has_usb_audio = false;
+ reinit_callback(false);
+ }
+}
+
+/* For SDL apps, set audio to the correct device. */
+void audio_hotplug_set_device(bool has_usb_audio) {
+ if (has_usb_audio) {
+ SDL_putenv("AUDIODEV=/dev/dsp1");
+ } else {
+ SDL_putenv("AUDIODEV=/dev/dsp");
+ }
+}
+
+#endif
diff --git a/frontend/plat_trimui.c b/frontend/plat_trimui.c
index bdd5a92..2925f5f 100644
--- a/frontend/plat_trimui.c
+++ b/frontend/plat_trimui.c
@@ -1,6 +1,7 @@
#include <SDL/SDL.h>
#include "common.h"
+#include "frontend/audio_hotplug.h"
#include "frontend/main.h"
#include "frontend/plat.h"
#include "frontend/scale.h"
@@ -185,6 +186,7 @@ int plat_sound_init(void)
if (SDL_OpenAudio(&spec, NULL) < 0) {
plat_sound_finish();
+ fprintf(stderr, "SDL audio failed to open: %s\n", SDL_GetError());
return -1;
}
@@ -192,6 +194,12 @@ int plat_sound_init(void)
return 0;
}
+static void plat_sound_reinit(bool has_usb_audio) {
+ plat_sound_finish();
+ audio_hotplug_set_device(has_usb_audio);
+ plat_sound_init();
+}
+
float plat_sound_capacity(void)
{
int buffered = 0;
@@ -205,6 +213,7 @@ float plat_sound_capacity(void)
void plat_sound_write(void *data, int bytes)
{
short *sound_data = (short *)data;
+ audio_hotplug_check(plat_sound_reinit);
SDL_LockAudio();
while (bytes > 0) {