OSDN Git Service

added detect callback to output for the auto-detection of
authorTakashi Iwai <tiwai@suse.de>
Thu, 18 Sep 2003 09:23:59 +0000 (09:23 +0000)
committerTakashi Iwai <tiwai@suse.de>
Thu, 18 Sep 2003 09:23:59 +0000 (09:23 +0000)
fallback devices.

timidity/aRts_a.c
timidity/alsa_a.c
timidity/esd_a.c
timidity/jack_a.c
timidity/oss_a.c
timidity/output.h
timidity/timidity.c

index 912b2b1..759a5a4 100755 (executable)
@@ -64,6 +64,7 @@ static int open_output(void); /* 0=success, 1=warning, -1=fatal error */
 static void close_output(void);
 static int output_data(char *buf, int32 nbytes);
 static int acntl(int request, void *arg);
+static int detect(int probing);
 
 /* export the playback mode */
 
@@ -81,7 +82,8 @@ PlayMode dpm = {
     open_output,
     close_output,
     output_data,
-    acntl
+    acntl,
+    detect
 };
 
 PlayMode arts_play_mode2 = {
@@ -95,9 +97,19 @@ PlayMode arts_play_mode2 = {
     open_output,
     close_output,
     output_data,
-    acntl
+    acntl,
+    detect
 };
 
+static int detect(int probing)
+{
+    if (arts_init() == 0) {
+       arts_free();
+       return 1; /* ok, found */
+    }
+    return 0;
+}
+
 /*************************************************************************/
 /* We currently only honor the PE_MONO bit, and the sample rate. */
 
index 75ec361..1b41095 100644 (file)
@@ -41,7 +41,7 @@
 #endif
 
 /*ALSA header file*/
-#if HAHE_ALSA_ASOUNDLIB_H
+#if HAVE_ALSA_ASOUNDLIB_H
 #include <alsa/asoundlib.h>
 #else
 #include <sys/asoundlib.h>
@@ -70,6 +70,9 @@ static int open_output(void); /* 0=success, 1=warning, -1=fatal error */
 static void close_output(void);
 static int output_data(char *buf, int32 nbytes);
 static int acntl(int request, void *arg);
+#if ALSA_LIB >= 5
+static int detect(void);
+#endif
 
 /* export the playback mode */
 
@@ -86,7 +89,10 @@ PlayMode dpm = {
   open_output,
   close_output,
   output_data,
-  acntl
+  acntl,
+#if ALSA_LIB >= 5
+  detect
+#endif
 };
 
 /*************************************************************************/
@@ -247,6 +253,31 @@ static int check_sound_cards (int* card__, int* device__,
  * ALSA API version 0.9.x
  *================================================================*/
 
+static char *get_pcm_name(void)
+{
+  char *name;
+  if (dpm.name && *dpm.name)
+    return dpm.name;
+  name = getenv("TIMIDITY_PCM_NAME");
+  if (! name || ! *name)
+    name = "default";
+  return name;
+}
+
+static void error_handle(const char *file, int line, const char *func, int err, const char *fmt, ...)
+{
+}
+
+static int detect(void)
+{
+  snd_pcm_t *pcm;
+  snd_lib_error_set_handler(error_handle);
+  if (snd_pcm_open(&pcm, get_pcm_name(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK) < 0)
+    return 0;
+  snd_pcm_close(pcm);
+  return 1; /* found */
+}
+
 /*return value == 0 sucess
                == 1 warning
                == -1 fails
@@ -257,18 +288,11 @@ static int open_output(void)
   int ret_val = 0;
   int tmp, frags, r, pfds;
   int buf_time, rate;
-  static const char default_pcm_name[] = "default";
-  const char* env_pcm_name = getenv("TIMIDITY_PCM_NAME");
   snd_pcm_hw_params_t *pinfo;
   snd_pcm_sw_params_t *swpinfo;
 
-  if (! dpm.name || ! *dpm.name) {
-    if (env_pcm_name && *env_pcm_name)
-      dpm.name = safe_strdup(env_pcm_name);
-  }
-  if (! dpm.name || ! *dpm.name)
-    dpm.name = safe_strdup(default_pcm_name);
-
+  dpm.name = get_pcm_name();
+  snd_lib_error_set_handler(NULL);
   tmp = snd_pcm_open(&handle, dpm.name, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); /* avoid blocking by open */
   if (tmp < 0) {
     ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Can't open pcm device '%s'.", dpm.name);
@@ -791,6 +815,15 @@ static int set_playback_info (snd_pcm_t* handle__,
 }
 
 
+static int detect(void)
+{
+  snd_pcm_t *pcm;
+  if (snd_pcm_open(&pcm, card, device, SND_PCM_OPEN_PLAYBACK | SND_PCM_OPEN_NONBLOCK) < 0)
+    return 0;
+  snd_pcm_close(pcm);
+  return 1; /* found */
+}
+
 static int open_output(void)
 {
   int tmp, warnings=0;
index d1820f8..f40c788 100644 (file)
@@ -53,7 +53,7 @@ static int open_output(void); /* 0=success, 1=warning, -1=fatal error */
 static void close_output(void);
 static int output_data(char *buf, int32 nbytes);
 static int acntl(int request, void *arg);
-
+static int detect(void);
 
 
 /* export the playback mode */
@@ -71,16 +71,14 @@ PlayMode dpm = {
     open_output,
     close_output,
     output_data,
-    acntl
+    acntl,
+    detect
 };
 
 
-/*************************************************************************/
-/* We currently only honor the PE_MONO bit, and the sample rate. */
-
-static int open_output(void)
+static int try_open(void)
 {
-    int fd, tmp, i, warnings = 0;
+    int fd, tmp, i;
     int include_enc, exclude_enc;
     esd_format_t esdformat;
 
@@ -95,7 +93,32 @@ static int open_output(void)
     /* Open the audio device */
     esdformat = (dpm.encoding & PE_16BIT) ? ESD_BITS16 : ESD_BITS8;
     esdformat |= (dpm.encoding & PE_MONO) ? ESD_MONO : ESD_STEREO;
-    fd = esd_play_stream_fallback(esdformat,dpm.rate,NULL,"timidity");
+    return esd_play_stream_fallback(esdformat,dpm.rate,NULL,"timidity");
+}
+
+
+static int detect(void)
+{
+    int fd;
+
+    /* FIXME: do we need to set this? */
+    /* setenv("ESD_NO_SPAWN", "1", 0); */
+    fd = try_open();
+    if (fd < 0)
+       return 0;
+    close(fd);
+    return 1; /* found */
+}
+
+/*************************************************************************/
+/* We currently only honor the PE_MONO bit, and the sample rate. */
+
+static int open_output(void)
+{
+    int fd;
+
+    fd = try_open();
+
     if(fd < 0)
     {
        ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s",
@@ -106,7 +129,7 @@ static int open_output(void)
 
     dpm.fd = fd;
 
-    return warnings;
+    return 0;
 }
 
 static int output_data(char *buf, int32 nbytes)
index cde1ab3..0de96d3 100644 (file)
@@ -71,6 +71,7 @@ static int open_jack(void);
 static void close_jack(void);
 static int write_jack(char *buf, int32 nbytes);
 static int actl_jack(int request, void *arg);
+static int detect(void);
 
 
 /*
@@ -89,7 +90,8 @@ PlayMode dpm = {
        open_jack,
        close_jack,
        write_jack,
-       actl_jack
+       actl_jack,
+       detect
 };
 
 /*
@@ -258,6 +260,16 @@ static struct tm_jack jack_ctx;
 #define TIMIDITY_JACK_CLIENT_NAME      "TiMidity"
 #define TIMIDITY_JACK_PORT_NAME                "port_%d"
 
+static int detect(void)
+{
+       jack_client_t *client;
+       client = jack_client_new(TIMIDITY_JACK_CLIENT_NAME);
+       if (! client)
+               return 0;
+       jack_client_close(client);
+       return 1; /* found */
+}
+
 static int open_jack(void)
 {
        int i, rate;
index e2e0271..d7a0174 100644 (file)
@@ -72,6 +72,7 @@ static int open_output(void); /* 0=success, 1=warning, -1=fatal error */
 static void close_output(void);
 static int output_data(char *buf, int32 nbytes);
 static int acntl(int request, void *arg);
+static int detect(void);
 static int output_counter;
 static int total_bytes; /* Maximum buffer size in bytes */
 
@@ -94,9 +95,20 @@ PlayMode dpm = {
     open_output,
     close_output,
     output_data,
-    acntl
+    acntl,
+    detect
 };
 
+static int detect(void)
+{
+    int fd;
+    fd = open(dpm.name, O_WRONLY | O_NONBLOCK);
+    if (fd < 0)
+       return 0;
+    close(fd);
+    return 1; /* found */
+}
+
 /*************************************************************************/
 /* We currently only honor the PE_MONO bit, the sample rate, and the
    number of buffer fragments. We try 16-bit signed data first, and
index 85295d5..02ba07c 100644 (file)
@@ -134,6 +134,7 @@ typedef struct {
     int (* acntl)(int request, void *arg); /* see PM_REQ_* above
                                            * return: 0=success, -1=fail
                                            */
+    int (* detect)(void); /* 0=not available, 1=available */
 } PlayMode;
 
 extern PlayMode *play_mode_list[], *play_mode;
index 5ca9004..6f0d4ad 100644 (file)
@@ -4289,7 +4289,6 @@ MAIN_INTERFACE void timidity_start_initialize(void)
        char *output_id;
        int i;
 
-       play_mode = play_mode_list[0];
        output_id = getenv("TIMIDITY_OUTPUT_ID");
 #ifdef TIMIDITY_OUTPUT_ID
        if(output_id == NULL)
@@ -4300,11 +4299,32 @@ MAIN_INTERFACE void timidity_start_initialize(void)
            for(i = 0; play_mode_list[i]; i++)
                if(play_mode_list[i]->id_character == *output_id)
                {
+                   if (! play_mode_list[i]->detect ||
+                       play_mode_list[i]->detect()) {
+                       play_mode = play_mode_list[i];
+                       break;
+                   }
+               }
+       }
+    }
+
+    if (play_mode == NULL) {
+       /* try to detect the first available device */  
+       for(i = 0; play_mode_list[i]; i++) {
+           /* check only the devices with detect callback */
+           if (play_mode_list[i]->detect) {
+               if (play_mode_list[i]->detect()) {
                    play_mode = play_mode_list[i];
                    break;
                }
+           }
        }
     }
+    
+    if (play_mode == NULL) {
+       fprintf(stderr, "Couldn't open output device" NLS);
+       exit(1);
+    }
 
     if(is_first) /* initialize once time */
     {
@@ -4806,34 +4826,6 @@ int main(int argc, char **argv)
     }
 #endif
 
-#ifdef AU_ARTS
-    if(play_mode == NULL && arts_init()==0) {
-           arts_free();
-           set_play_mode("k");
-    }
-#endif
-#ifdef AU_PORTAUDIO
-    if(play_mode == NULL)
-           set_play_mode("p");
-#endif
-#ifdef AU_ESD
-    if(play_mode == NULL) {
-#if defined(__x86_64__) || (__powerpc64__)
-           const char *libesd_path = "/usr/lib64/libesd.so.0";
-#else
-           const char *libesd_path = "/usr/lib/libesd.so.0";
-#endif
-           if(!access(libesd_path, R_OK)) {
-                   setenv("ESD_NO_SPAWN", "1", 0);
-                   set_play_mode("e");
-           }
-    }
-#endif
-#ifdef AU_OSS
-    if(play_mode == NULL)
-           set_play_mode("d");
-#endif
-    
     if((err = timidity_pre_load_configuration()) != 0)
        return err;