src/audio/SDL_audiodev.c
changeset 2049 5f6550e5184f
parent 1895 c121d94672cb
child 2060 866052b01ee5
--- a/src/audio/SDL_audiodev.c	Sun Oct 01 16:10:41 2006 +0000
+++ b/src/audio/SDL_audiodev.c	Tue Oct 17 09:15:21 2006 +0000
@@ -46,14 +46,63 @@
 #define _PATH_DEV_AUDIO	"/dev/audio"
 #endif
 
+static inline void
+test_device(const char *fname, int flags, int (*test)(int fd),
+            char ***devices, int *devCount)
+{
+    struct stat sb;
+    if ( (stat(fname, &sb) == 0) && (S_ISCHR(sb.st_mode)) ) {
+        int audio_fd = open(fname, flags, 0);
+        if ( (audio_fd >= 0) && (test(audio_fd)) ) {
+            void *p = SDL_realloc(*devices, ((*devCount)+1) * sizeof (char *));
+            if (p != NULL) {
+                size_t len = strlen(fname) + 1;
+                char *str = (char *) SDL_malloc(len);
+                *devices = (char **) p;
+                if (str != NULL) {
+                    SDL_strlcpy(str, fname, len);
+                    (*devices)[(*devCount)++] = str;
+                }
+            }
+            close(audio_fd);
+        }
+    }
+}
 
-int
-SDL_OpenAudioPath(char *path, int maxlen, int flags, int classic)
+void
+SDL_FreeUnixAudioDevices(char ***devices, int *devCount)
+{
+    int i = *devCount;
+    if ((i > 0) && (*devices != NULL)) {
+        while (i--) {
+            SDL_free( (*devices)[*devCount] );
+        }
+    }
+
+    if (*devices != NULL) {
+        SDL_free(*devices);
+    }
+
+    *devices = NULL;
+    *devCount = 0;
+}
+
+static int
+test_stub(int fd)
+{
+    return 1;
+}
+
+void
+SDL_EnumUnixAudioDevices(int flags, int classic, int (*test)(int fd),
+                         char ***devices, int *devCount)
 {
     const char *audiodev;
-    int audio_fd;
     char audiopath[1024];
 
+    if (test == NULL)
+        test = test_stub;
+
     /* Figure out what our audio device is */
     if (((audiodev = SDL_getenv("SDL_PATH_DSP")) == NULL) &&
         ((audiodev = SDL_getenv("AUDIODEV")) == NULL)) {
@@ -72,111 +121,16 @@
             }
         }
     }
-    audio_fd = open(audiodev, flags, 0);
-
-    /* If the first open fails, look for other devices */
-    if ((audio_fd < 0) && (SDL_strlen(audiodev) < (sizeof(audiopath) - 3))) {
-        int exists, instance;
-        struct stat sb;
-
-        instance = 1;
-        do {                    /* Don't use errno ENOENT - it may not be thread-safe */
-            SDL_snprintf(audiopath, SDL_arraysize(audiopath),
-                         "%s%d", audiodev, instance++);
-            exists = 0;
-            if (stat(audiopath, &sb) == 0) {
-                exists = 1;
-                audio_fd = open(audiopath, flags, 0);
-            }
-        }
-        while (exists && (audio_fd < 0));
-        audiodev = audiopath;
-    }
-    if (path != NULL) {
-        SDL_strlcpy(path, audiodev, maxlen);
-        path[maxlen - 1] = '\0';
-    }
-    return (audio_fd);
-}
-
-#elif SDL_AUDIO_DRIVER_PAUD
-
-/* Get the name of the audio device we use for output */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include "SDL_stdinc.h"
-#include "SDL_audiodev_c.h"
-
-#ifndef _PATH_DEV_DSP
-#define _PATH_DEV_DSP	"/dev/%caud%c/%c"
-#endif
+    test_device(audiodev, flags, test, devices, devCount);
 
-char devsettings[][3] = {
-    {'p', '0', '1'}, {'p', '0', '2'}, {'p', '0', '3'}, {'p', '0', '4'},
-    {'p', '1', '1'}, {'p', '1', '2'}, {'p', '1', '3'}, {'p', '1', '4'},
-    {'p', '2', '1'}, {'p', '2', '2'}, {'p', '2', '3'}, {'p', '2', '4'},
-    {'p', '3', '1'}, {'p', '3', '2'}, {'p', '3', '3'}, {'p', '3', '4'},
-    {'b', '0', '1'}, {'b', '0', '2'}, {'b', '0', '3'}, {'b', '0', '4'},
-    {'b', '1', '1'}, {'b', '1', '2'}, {'b', '1', '3'}, {'b', '1', '4'},
-    {'b', '2', '1'}, {'b', '2', '2'}, {'b', '2', '3'}, {'b', '2', '4'},
-    {'b', '3', '1'}, {'b', '3', '2'}, {'b', '3', '3'}, {'b', '3', '4'},
-    {'\0', '\0', '\0'}
-};
-
-static int
-OpenUserDefinedDevice(char *path, int maxlen, int flags)
-{
-    const char *audiodev;
-    int audio_fd;
-
-    /* Figure out what our audio device is */
-    if ((audiodev = SDL_getenv("SDL_PATH_DSP")) == NULL) {
-        audiodev = SDL_getenv("AUDIODEV");
-    }
-    if (audiodev == NULL) {
-        return -1;
-    }
-    audio_fd = open(audiodev, flags, 0);
-    if (path != NULL) {
-        SDL_strlcpy(path, audiodev, maxlen);
-        path[maxlen - 1] = '\0';
-    }
-    return audio_fd;
-}
-
-int
-SDL_OpenAudioPath(char *path, int maxlen, int flags, int classic)
-{
-    struct stat sb;
-    int audio_fd;
-    char audiopath[1024];
-    int cycle;
-
-    audio_fd = OpenUserDefinedDevice(path, maxlen, flags);
-    if (audio_fd != -1) {
-        return audio_fd;
-    }
-
-    cycle = 0;
-    while (devsettings[cycle][0] != '\0') {
-        SDL_snprintf(audiopath, SDL_arraysize(audiopath),
-                     _PATH_DEV_DSP,
-                     devsettings[cycle][0],
-                     devsettings[cycle][1], devsettings[cycle][2]);
-
-        if (stat(audiopath, &sb) == 0) {
-            audio_fd = open(audiopath, flags, 0);
-            if (audio_fd > 0) {
-                if (path != NULL) {
-                    SDL_strlcpy(path, audiopath, maxlen);
-                }
-                return audio_fd;
-            }
+    if (SDL_strlen(audiodev) < (sizeof(audiopath) - 3)) {
+        int instance = 0;
+        while (instance++ <= 64) {
+            SDL_snprintf(audiopath, SDL_arraysize(audiopath),
+                         "%s%d", audiodev, instance);
+            test_device(audiopath, flags, test, devices, devCount);
         }
     }
-    return -1;
 }
 
 #endif /* Audio driver selection */