fallback devices.
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 */
open_output,
close_output,
output_data,
- acntl
+ acntl,
+ detect
};
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. */
#endif
/*ALSA header file*/
-#if HAHE_ALSA_ASOUNDLIB_H
+#if HAVE_ALSA_ASOUNDLIB_H
#include <alsa/asoundlib.h>
#else
#include <sys/asoundlib.h>
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 */
open_output,
close_output,
output_data,
- acntl
+ acntl,
+#if ALSA_LIB >= 5
+ detect
+#endif
};
/*************************************************************************/
* 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
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);
}
+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;
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 */
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;
/* 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",
dpm.fd = fd;
- return warnings;
+ return 0;
}
static int output_data(char *buf, int32 nbytes)
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);
/*
open_jack,
close_jack,
write_jack,
- actl_jack
+ actl_jack,
+ detect
};
/*
#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;
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 */
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
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;
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)
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 */
{
}
#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;