allow multiple sound-drivers to be compiled in simultaneously and

make the runtime selectable


git-svn-id: svn://svn.code.sf.net/p/rdesktop/code/trunk/rdesktop@1254 423420c4-83ab-492f-b58f-81f9feb106b5
This commit is contained in:
Michael Gernoth 2006-09-17 11:04:50 +00:00
parent ec4862937f
commit 07b5b9e41c
11 changed files with 413 additions and 74 deletions

View File

@ -156,19 +156,54 @@ AC_ARG_WITH(sound,
sound="$withval" sound="$withval"
]) ])
if test "$sound" = yes; then if test "$sound" = yes; then
AC_CHECK_HEADER(ao/ao.h, [sound=libao]) AC_CHECK_HEADER(ao/ao.h,
AC_CHECK_HEADER(sys/soundcard.h, [sound=oss]) [
AC_CHECK_HEADER(dmedia/audio.h, [sound=sgi]) sound=auto
AC_CHECK_HEADER(sys/audioio.h, [sound=sun]) SOUNDOBJ="$SOUNDOBJ rdpsnd_libao.o"
LDFLAGS="$LDFLAGS -lao"
AC_DEFINE(RDPSND_LIBAO)
])
AC_CHECK_HEADER(sys/soundcard.h,
[
sound=auto
SOUNDOBJ="$SOUNDOBJ rdpsnd_oss.o"
AC_DEFINE(RDPSND_OSS)
])
AC_CHECK_HEADER(dmedia/audio.h,
[
sound=auto
SOUNDOBJ="$SOUNDOBJ rdpsnd_sgi.o"
LDFLAGS="$LDFLAGS -laudio"
AC_DEFINE(RDPSND_SGI)
])
AC_CHECK_HEADER(sys/audioio.h,
[
sound=auto
SOUNDOBJ="$SOUNDOBJ rdpsnd_sun.o"
AC_DEFINE(RDPSND_SUN)
])
AC_CHECK_HEADER(alsa/asoundlib.h,
[
sound=auto
SOUNDOBJ="$SOUNDOBJ rdpsnd_alsa.o"
LDFLAGS="$LDFLAGS -lasound"
AC_DEFINE(RDPSND_ALSA)
])
fi fi
if test "$sound" = no; then if test "$sound" = no; then
break break
elif test "$sound" = auto; then
SOUNDOBJ="$SOUNDOBJ rdpsnd.o"
AC_DEFINE(WITH_RDPSND)
elif test "$sound" = oss; then elif test "$sound" = oss; then
SOUNDOBJ="rdpsnd.o rdpsnd_oss.o" SOUNDOBJ="rdpsnd.o rdpsnd_oss.o"
AC_DEFINE(WITH_RDPSND) AC_DEFINE(WITH_RDPSND)
elif test "$sound" = sgi; then elif test "$sound" = sgi; then
SOUNDOBJ="rdpsnd.o rdpsnd_sgi.o" SOUNDOBJ="rdpsnd.o rdpsnd_sgi.o"
LDFLAGS="$LDFLAGS -laudio" LDFLAGS="$LDFLAGS -laudio"
elif test "$sound" = yes; then
SOUNDOBJ="$SOUNDOBJ rdpsnd.o"
AC_DEFINE(WITH_RDPSND) AC_DEFINE(WITH_RDPSND)
elif test "$sound" = sun; then elif test "$sound" = sun; then
SOUNDOBJ="rdpsnd.o rdpsnd_sun.o" SOUNDOBJ="rdpsnd.o rdpsnd_sun.o"
@ -176,11 +211,12 @@ elif test "$sound" = sun; then
elif test "$sound" = libao; then elif test "$sound" = libao; then
SOUNDOBJ="rdpsnd.o rdpsnd_libao.o" SOUNDOBJ="rdpsnd.o rdpsnd_libao.o"
LDFLAGS="$LDFLAGS -lao" LDFLAGS="$LDFLAGS -lao"
AC_DEFINE(WITH_RDPSND) AC_DEFINE(RDPSND_SUN)
elif test "$sound" = alsa; then elif test "$sound" = alsa; then
SOUNDOBJ="rdpsnd.o rdpsnd_alsa.o" SOUNDOBJ="rdpsnd.o rdpsnd_alsa.o"
LDFLAGS="$LDFLAGS -lasound" LDFLAGS="$LDFLAGS -lasound"
AC_DEFINE(WITH_RDPSND) AC_DEFINE(WITH_RDPSND)
AC_DEFINE(RDPSND_ALSA)
else else
AC_MSG_WARN([sound support disabled]) AC_MSG_WARN([sound support disabled])
AC_MSG_WARN([Currently supported systems are Open Sound System (oss), SGI AL (sgi), Sun/BSD (sun), ALSA (alsa) and libao]) AC_MSG_WARN([Currently supported systems are Open Sound System (oss), SGI AL (sgi), Sun/BSD (sun), ALSA (alsa) and libao])

11
proto.h
View File

@ -165,14 +165,9 @@ BOOL rdpdr_abort_io(uint32 fd, uint32 major, NTSTATUS status);
/* rdpsnd.c */ /* rdpsnd.c */
void rdpsnd_send_completion(uint16 tick, uint8 packet_index); void rdpsnd_send_completion(uint16 tick, uint8 packet_index);
BOOL rdpsnd_init(void); BOOL rdpsnd_init(void);
/* rdpsnd_oss.c */ BOOL rdpsnd_select_driver(char *driver, char *options);
BOOL wave_out_open(void); void rdpsnd_show_help(void);
void wave_out_close(void); inline void rdpsnd_play(void);
BOOL wave_out_format_supported(WAVEFORMATEX * pwfx);
BOOL wave_out_set_format(WAVEFORMATEX * pwfx);
void wave_out_volume(uint16 left, uint16 right);
void wave_out_write(STREAM s, uint16 tick, uint8 index);
void wave_out_play(void);
/* secure.c */ /* secure.c */
void sec_hash_48(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2, uint8 salt); void sec_hash_48(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2, uint8 salt);
void sec_hash_16(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2); void sec_hash_16(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2);

View File

@ -179,8 +179,13 @@ usage(char *program)
fprintf(stderr, " '-r printer:mydeskjet': enable printer redirection\n"); fprintf(stderr, " '-r printer:mydeskjet': enable printer redirection\n");
fprintf(stderr, fprintf(stderr,
" or mydeskjet=\"HP LaserJet IIIP\" to enter server driver as well\n"); " or mydeskjet=\"HP LaserJet IIIP\" to enter server driver as well\n");
fprintf(stderr, " '-r sound:[local|off|remote]': enable sound redirection\n"); #ifdef WITH_RDPSND
fprintf(stderr,
" '-r sound:[local[:driver[:device]]|off|remote]': enable sound redirection\n");
fprintf(stderr, " remote would leave sound on server\n"); fprintf(stderr, " remote would leave sound on server\n");
fprintf(stderr, " available drivers for 'local':\n");
rdpsnd_show_help();
#endif
fprintf(stderr, fprintf(stderr,
" '-r clipboard:[off|PRIMARYCLIPBOARD|CLIPBOARD]': enable clipboard\n"); " '-r clipboard:[off|PRIMARYCLIPBOARD|CLIPBOARD]': enable clipboard\n");
fprintf(stderr, " redirection.\n"); fprintf(stderr, " redirection.\n");
@ -663,7 +668,36 @@ main(int argc, char *argv[])
if (str_startswith(optarg, "local")) if (str_startswith(optarg, "local"))
#ifdef WITH_RDPSND #ifdef WITH_RDPSND
{
char *driver = NULL, *options =
NULL;
if ((driver =
next_arg(optarg, ':')))
{
if (!strlen(driver))
{
driver = NULL;
}
else if ((options =
next_arg(driver,
':')))
{
if (!strlen
(options))
options =
NULL;
}
}
g_rdpsnd = True; g_rdpsnd = True;
if (!rdpsnd_select_driver
(driver, options))
{
warning("Driver not available\n");
}
}
#else #else
warning("Not compiled with sound support\n"); warning("Not compiled with sound support\n");
#endif #endif
@ -682,6 +716,10 @@ main(int argc, char *argv[])
{ {
#ifdef WITH_RDPSND #ifdef WITH_RDPSND
g_rdpsnd = True; g_rdpsnd = True;
if (!rdpsnd_select_driver(NULL, NULL))
{
warning("No sound-driver available\n");
}
#else #else
warning("Not compiled with sound support\n"); warning("Not compiled with sound support\n");
#endif #endif

127
rdpsnd.c
View File

@ -37,6 +37,8 @@ BOOL g_dsp_busy = False;
int g_dsp_fd; int g_dsp_fd;
static VCHANNEL *rdpsnd_channel; static VCHANNEL *rdpsnd_channel;
static struct audio_driver *drivers = NULL;
static struct audio_driver *current_driver = NULL;
static BOOL device_open; static BOOL device_open;
static WAVEFORMATEX formats[MAX_FORMATS]; static WAVEFORMATEX formats[MAX_FORMATS];
@ -45,6 +47,8 @@ static unsigned int current_format;
static unsigned int queue_hi, queue_lo; static unsigned int queue_hi, queue_lo;
static struct audio_packet packet_queue[MAX_QUEUE]; static struct audio_packet packet_queue[MAX_QUEUE];
void (*wave_out_play) (void);
static STREAM static STREAM
rdpsnd_init_packet(uint16 type, uint16 size) rdpsnd_init_packet(uint16 type, uint16 size)
{ {
@ -94,9 +98,9 @@ rdpsnd_process_negotiate(STREAM in)
in_uint16_le(in, in_format_count); in_uint16_le(in, in_format_count);
in_uint8s(in, 4); /* pad, status, pad */ in_uint8s(in, 4); /* pad, status, pad */
if (wave_out_open()) if (current_driver->wave_out_open())
{ {
wave_out_close(); current_driver->wave_out_close();
device_available = True; device_available = True;
} }
@ -127,7 +131,7 @@ rdpsnd_process_negotiate(STREAM in)
in_uint8a(in, format->cb, readcnt); in_uint8a(in, format->cb, readcnt);
in_uint8s(in, discardcnt); in_uint8s(in, discardcnt);
if (device_available && wave_out_format_supported(format)) if (device_available && current_driver->wave_out_format_supported(format))
{ {
format_count++; format_count++;
if (format_count == MAX_FORMATS) if (format_count == MAX_FORMATS)
@ -205,15 +209,15 @@ rdpsnd_process(STREAM s)
if (!device_open || (format != current_format)) if (!device_open || (format != current_format))
{ {
if (!device_open && !wave_out_open()) if (!device_open && !current_driver->wave_out_open())
{ {
rdpsnd_send_completion(tick, packet_index); rdpsnd_send_completion(tick, packet_index);
return; return;
} }
if (!wave_out_set_format(&formats[format])) if (!current_driver->wave_out_set_format(&formats[format]))
{ {
rdpsnd_send_completion(tick, packet_index); rdpsnd_send_completion(tick, packet_index);
wave_out_close(); current_driver->wave_out_close();
device_open = False; device_open = False;
return; return;
} }
@ -221,7 +225,7 @@ rdpsnd_process(STREAM s)
current_format = format; current_format = format;
} }
rdpsnd_queue_write(s, tick, packet_index); current_driver->wave_out_write(s, tick, packet_index);
awaiting_data_packet = False; awaiting_data_packet = False;
return; return;
} }
@ -239,7 +243,7 @@ rdpsnd_process(STREAM s)
awaiting_data_packet = True; awaiting_data_packet = True;
break; break;
case RDPSND_CLOSE: case RDPSND_CLOSE:
wave_out_close(); current_driver->wave_out_close();
device_open = False; device_open = False;
break; break;
case RDPSND_NEGOTIATE: case RDPSND_NEGOTIATE:
@ -252,7 +256,8 @@ rdpsnd_process(STREAM s)
in_uint32(s, volume); in_uint32(s, volume);
if (device_open) if (device_open)
{ {
wave_out_volume((volume & 0xffff), (volume & 0xffff0000) >> 16); current_driver->wave_out_volume((volume & 0xffff),
(volume & 0xffff0000) >> 16);
} }
break; break;
default: default:
@ -271,6 +276,108 @@ rdpsnd_init(void)
return (rdpsnd_channel != NULL); return (rdpsnd_channel != NULL);
} }
BOOL
rdpsnd_auto_open(void)
{
current_driver = drivers;
while (current_driver != NULL)
{
DEBUG(("trying %s...\n", current_driver->name));
if (current_driver->wave_out_open())
{
DEBUG(("selected %s\n", current_driver->name));
return True;
}
g_dsp_fd = 0;
current_driver = current_driver->next;
}
warning("no working audio-driver found\n");
return False;
}
void
rdpsnd_register_drivers(char *options)
{
struct audio_driver **reg;
/* The order of registrations define the probe-order
when opening the device for the first time */
reg = &drivers;
#if defined(RDPSND_ALSA)
*reg = alsa_register(options);
reg = &((*reg)->next);
#endif
#if defined(RDPSND_OSS)
*reg = oss_register(options);
reg = &((*reg)->next);
#endif
#if defined(RDPSND_SUN)
*reg = sun_register(options);
reg = &((*reg)->next);
#endif
#if defined(RDPSND_SGI)
*reg = sgi_register(options);
reg = &((*reg)->next);
#endif
#if defined(RDPSND_LIBAO)
*reg = libao_register(options);
reg = &((*reg)->next);
#endif
}
BOOL
rdpsnd_select_driver(char *driver, char *options)
{
static struct audio_driver auto_driver;
struct audio_driver *pos;
drivers = NULL;
rdpsnd_register_drivers(options);
if (!driver)
{
auto_driver.wave_out_open = &rdpsnd_auto_open;
current_driver = &auto_driver;
return True;
}
pos = drivers;
while (pos != NULL)
{
if (!strcmp(pos->name, driver))
{
DEBUG(("selected %s\n", pos->name));
current_driver = pos;
return True;
}
pos = pos->next;
}
return False;
}
void
rdpsnd_show_help(void)
{
struct audio_driver *pos;
rdpsnd_register_drivers(NULL);
pos = drivers;
while (pos != NULL)
{
fprintf(stderr, " %s:\t%s\n", pos->name, pos->description);
pos = pos->next;
}
}
inline void
rdpsnd_play(void)
{
current_driver->wave_out_play();
}
void void
rdpsnd_queue_write(STREAM s, uint16 tick, uint8 index) rdpsnd_queue_write(STREAM s, uint16 tick, uint8 index)
{ {
@ -294,7 +401,7 @@ rdpsnd_queue_write(STREAM s, uint16 tick, uint8 index)
s->data = malloc(s->size); s->data = malloc(s->size);
if (!g_dsp_busy) if (!g_dsp_busy)
wave_out_play(); current_driver->wave_out_play();
} }
inline struct audio_packet * inline struct audio_packet *

View File

@ -25,6 +25,20 @@ struct audio_packet
uint8 index; uint8 index;
}; };
struct audio_driver
{
void (*wave_out_write) (STREAM s, uint16 tick, uint8 index);
BOOL(*wave_out_open) (void);
void (*wave_out_close) (void);
BOOL(*wave_out_format_supported) (WAVEFORMATEX * pwfx);
BOOL(*wave_out_set_format) (WAVEFORMATEX * pwfx);
void (*wave_out_volume) (uint16 left, uint16 right);
void (*wave_out_play) (void);
char *name;
char *description;
struct audio_driver *next;
};
extern BOOL g_dsp_busy; extern BOOL g_dsp_busy;
extern int g_dsp_fd; extern int g_dsp_fd;
@ -34,3 +48,10 @@ inline BOOL rdpsnd_queue_empty(void);
inline void rdpsnd_queue_init(void); inline void rdpsnd_queue_init(void);
inline void rdpsnd_queue_next(void); inline void rdpsnd_queue_next(void);
inline int rdpsnd_queue_next_tick(void); inline int rdpsnd_queue_next_tick(void);
/* Driver register functions */
struct audio_driver *alsa_register(char *options);
struct audio_driver *libao_register(char *options);
struct audio_driver *oss_register(char *options);
struct audio_driver *sgi_register(char *options);
struct audio_driver *sun_register(char *options);

View File

@ -36,15 +36,13 @@ static snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK;
static BOOL reopened; static BOOL reopened;
static short samplewidth; static short samplewidth;
static int audiochannels; static int audiochannels;
static char *pcm_name;
BOOL BOOL
wave_out_open(void) alsa_open(void)
{ {
char *pcm_name;
int err; int err;
pcm_name = xstrdup(DEFAULTDEVICE);
if ((err = snd_pcm_open(&pcm_handle, pcm_name, stream, 0)) < 0) if ((err = snd_pcm_open(&pcm_handle, pcm_name, stream, 0)) < 0)
{ {
error("snd_pcm_open: %s\n", snd_strerror(err)); error("snd_pcm_open: %s\n", snd_strerror(err));
@ -60,7 +58,7 @@ wave_out_open(void)
} }
void void
wave_out_close(void) alsa_close(void)
{ {
/* Ack all remaining packets */ /* Ack all remaining packets */
while (!rdpsnd_queue_empty()) while (!rdpsnd_queue_empty())
@ -70,7 +68,6 @@ wave_out_close(void)
rdpsnd_queue_next(); rdpsnd_queue_next();
} }
if (pcm_handle) if (pcm_handle)
{ {
snd_pcm_drop(pcm_handle); snd_pcm_drop(pcm_handle);
@ -79,7 +76,7 @@ wave_out_close(void)
} }
BOOL BOOL
wave_out_format_supported(WAVEFORMATEX * pwfx) alsa_format_supported(WAVEFORMATEX * pwfx)
{ {
#if 0 #if 0
int err; int err;
@ -112,7 +109,7 @@ wave_out_format_supported(WAVEFORMATEX * pwfx)
} }
BOOL BOOL
wave_out_set_format(WAVEFORMATEX * pwfx) alsa_set_format(WAVEFORMATEX * pwfx)
{ {
snd_pcm_hw_params_t *hwparams = NULL; snd_pcm_hw_params_t *hwparams = NULL;
unsigned int rate, exact_rate; unsigned int rate, exact_rate;
@ -210,19 +207,19 @@ wave_out_set_format(WAVEFORMATEX * pwfx)
} }
void void
wave_out_volume(uint16 left, uint16 right) alsa_volume(uint16 left, uint16 right)
{ {
static int warned = 0; static int warned = 0;
if (!warned) if (!warned)
{ {
warning("volume changes currently not supported with experimental alsa-output\n"); warning("volume changes currently not supported with alsa-output\n");
warned = 1; warned = 1;
} }
} }
void void
wave_out_play(void) alsa_play(void)
{ {
struct audio_packet *packet; struct audio_packet *packet;
STREAM out; STREAM out;
@ -285,3 +282,31 @@ wave_out_play(void)
g_dsp_busy = 1; g_dsp_busy = 1;
return; return;
} }
static struct audio_driver alsa_driver = {
wave_out_write:rdpsnd_queue_write,
wave_out_open:alsa_open,
wave_out_close:alsa_close,
wave_out_format_supported:alsa_format_supported,
wave_out_set_format:alsa_set_format,
wave_out_volume:alsa_volume,
wave_out_play:alsa_play,
name:"alsa",
description:"ALSA output driver, default device: " DEFAULTDEVICE,
next:NULL,
};
struct audio_driver *
alsa_register(char *options)
{
if (options)
{
pcm_name = xstrdup(options);
}
else
{
pcm_name = xstrdup(DEFAULTDEVICE);
}
return &alsa_driver;
}

View File

@ -36,11 +36,19 @@ static int samplerate;
static int audiochannels; static int audiochannels;
static BOOL reopened; static BOOL reopened;
static short samplewidth; static short samplewidth;
static char *libao_device = NULL;
BOOL BOOL
wave_out_open(void) libao_open(void)
{ {
ao_sample_format format; ao_sample_format format;
static int warned = 0;
if (!warned && libao_device)
{
warning("device-options not supported for libao-driver\n");
warned = 1;
}
ao_initialize(); ao_initialize();
default_driver = ao_default_driver_id(); default_driver = ao_default_driver_id();
@ -67,7 +75,7 @@ wave_out_open(void)
} }
void void
wave_out_close(void) libao_close(void)
{ {
/* Ack all remaining packets */ /* Ack all remaining packets */
while (!rdpsnd_queue_empty()) while (!rdpsnd_queue_empty())
@ -84,7 +92,7 @@ wave_out_close(void)
} }
BOOL BOOL
wave_out_format_supported(WAVEFORMATEX * pwfx) libao_format_supported(WAVEFORMATEX * pwfx)
{ {
if (pwfx->wFormatTag != WAVE_FORMAT_PCM) if (pwfx->wFormatTag != WAVE_FORMAT_PCM)
return False; return False;
@ -101,7 +109,7 @@ wave_out_format_supported(WAVEFORMATEX * pwfx)
} }
BOOL BOOL
wave_out_set_format(WAVEFORMATEX * pwfx) libao_set_format(WAVEFORMATEX * pwfx)
{ {
ao_sample_format format; ao_sample_format format;
@ -129,13 +137,13 @@ wave_out_set_format(WAVEFORMATEX * pwfx)
} }
void void
wave_out_volume(uint16 left, uint16 right) libao_volume(uint16 left, uint16 right)
{ {
warning("volume changes not supported with libao-output\n"); warning("volume changes not supported with libao-output\n");
} }
void void
wave_out_play(void) libao_play(void)
{ {
struct audio_packet *packet; struct audio_packet *packet;
STREAM out; STREAM out;
@ -225,3 +233,27 @@ wave_out_play(void)
g_dsp_busy = 1; g_dsp_busy = 1;
return; return;
} }
static struct audio_driver libao_driver = {
wave_out_write:rdpsnd_queue_write,
wave_out_open:libao_open,
wave_out_close:libao_close,
wave_out_format_supported:libao_format_supported,
wave_out_set_format:libao_set_format,
wave_out_volume:libao_volume,
wave_out_play:libao_play,
name:"libao",
description:"libao output driver",
next:NULL,
};
struct audio_driver *
libao_register(char *options)
{
if (options)
{
libao_device = xstrdup(options);
}
return &libao_driver;
}

View File

@ -41,17 +41,11 @@
static int snd_rate; static int snd_rate;
static short samplewidth; static short samplewidth;
static char *dsp_dev;
BOOL BOOL
wave_out_open(void) oss_open(void)
{ {
char *dsp_dev = getenv("AUDIODEV");
if (dsp_dev == NULL)
{
dsp_dev = xstrdup(DEFAULTDEVICE);
}
if ((g_dsp_fd = open(dsp_dev, O_WRONLY)) == -1) if ((g_dsp_fd = open(dsp_dev, O_WRONLY)) == -1)
{ {
perror(dsp_dev); perror(dsp_dev);
@ -62,13 +56,13 @@ wave_out_open(void)
} }
void void
wave_out_close(void) oss_close(void)
{ {
close(g_dsp_fd); close(g_dsp_fd);
} }
BOOL BOOL
wave_out_format_supported(WAVEFORMATEX * pwfx) oss_format_supported(WAVEFORMATEX * pwfx)
{ {
if (pwfx->wFormatTag != WAVE_FORMAT_PCM) if (pwfx->wFormatTag != WAVE_FORMAT_PCM)
return False; return False;
@ -81,7 +75,7 @@ wave_out_format_supported(WAVEFORMATEX * pwfx)
} }
BOOL BOOL
wave_out_set_format(WAVEFORMATEX * pwfx) oss_set_format(WAVEFORMATEX * pwfx)
{ {
int stereo, format, fragments; int stereo, format, fragments;
static BOOL driver_broken = False; static BOOL driver_broken = False;
@ -157,7 +151,7 @@ wave_out_set_format(WAVEFORMATEX * pwfx)
} }
void void
wave_out_volume(uint16 left, uint16 right) oss_volume(uint16 left, uint16 right)
{ {
static BOOL use_dev_mixer = False; static BOOL use_dev_mixer = False;
uint32 volume; uint32 volume;
@ -192,7 +186,7 @@ wave_out_volume(uint16 left, uint16 right)
} }
void void
wave_out_play(void) oss_play(void)
{ {
struct audio_packet *packet; struct audio_packet *packet;
ssize_t len; ssize_t len;
@ -257,3 +251,36 @@ wave_out_play(void)
g_dsp_busy = 1; g_dsp_busy = 1;
return; return;
} }
static struct audio_driver oss_driver = {
wave_out_write:rdpsnd_queue_write,
wave_out_open:oss_open,
wave_out_close:oss_close,
wave_out_format_supported:oss_format_supported,
wave_out_set_format:oss_set_format,
wave_out_volume:oss_volume,
wave_out_play:oss_play,
name:"oss",
description:"OSS output driver, default device: " DEFAULTDEVICE " or $AUDIODEV",
next:NULL,
};
struct audio_driver *
oss_register(char *options)
{
if (options)
{
dsp_dev = xstrdup(options);
}
else
{
dsp_dev = getenv("AUDIODEV");
if (dsp_dev == NULL)
{
dsp_dev = xstrdup(DEFAULTDEVICE);
}
}
return &oss_driver;
}

View File

@ -35,20 +35,28 @@ static BOOL g_swapaudio;
static int g_snd_rate; static int g_snd_rate;
static BOOL g_swapaudio; static BOOL g_swapaudio;
static int width = AL_SAMPLE_16; static int width = AL_SAMPLE_16;
static char *sgi_output_device = NULL;
double min_volume, max_volume, volume_range; double min_volume, max_volume, volume_range;
int resource, maxFillable; int resource, maxFillable;
int combinedFrameSize; int combinedFrameSize;
BOOL BOOL
wave_out_open(void) sgi_open(void)
{ {
ALparamInfo pinfo; ALparamInfo pinfo;
static int warned = 0;
#if (defined(IRIX_DEBUG)) #if (defined(IRIX_DEBUG))
fprintf(stderr, "sgi_open: begin\n"); fprintf(stderr, "sgi_open: begin\n");
#endif #endif
if (!warned && sgi_output_device)
{
warning("device-options not supported for libao-driver\n");
warned = 1;
}
if (alGetParamInfo(AL_DEFAULT_OUTPUT, AL_GAIN, &pinfo) < 0) if (alGetParamInfo(AL_DEFAULT_OUTPUT, AL_GAIN, &pinfo) < 0)
{ {
fprintf(stderr, "sgi_open: alGetParamInfo failed: %s\n", fprintf(stderr, "sgi_open: alGetParamInfo failed: %s\n",
@ -85,7 +93,7 @@ wave_out_open(void)
} }
void void
wave_out_close(void) sgi_close(void)
{ {
/* Ack all remaining packets */ /* Ack all remaining packets */
#if (defined(IRIX_DEBUG)) #if (defined(IRIX_DEBUG))
@ -110,7 +118,7 @@ wave_out_close(void)
} }
BOOL BOOL
wave_out_format_supported(WAVEFORMATEX * pwfx) sgi_format_supported(WAVEFORMATEX * pwfx)
{ {
if (pwfx->wFormatTag != WAVE_FORMAT_PCM) if (pwfx->wFormatTag != WAVE_FORMAT_PCM)
return False; return False;
@ -123,7 +131,7 @@ wave_out_format_supported(WAVEFORMATEX * pwfx)
} }
BOOL BOOL
wave_out_set_format(WAVEFORMATEX * pwfx) sgi_set_format(WAVEFORMATEX * pwfx)
{ {
int channels; int channels;
int frameSize, channelCount; int frameSize, channelCount;
@ -207,7 +215,7 @@ wave_out_set_format(WAVEFORMATEX * pwfx)
} }
void void
wave_out_volume(uint16 left, uint16 right) sgi_volume(uint16 left, uint16 right)
{ {
double gainleft, gainright; double gainleft, gainright;
ALpv pv[1]; ALpv pv[1];
@ -240,7 +248,7 @@ wave_out_volume(uint16 left, uint16 right)
} }
void void
wave_out_play(void) sgi_play(void)
{ {
struct audio_packet *packet; struct audio_packet *packet;
ssize_t len; ssize_t len;
@ -299,3 +307,26 @@ wave_out_play(void)
} }
} }
} }
static struct audio_driver sgi_driver = {
wave_out_write:rdpsnd_queue_write,
wave_out_open:sgi_open,
wave_out_close:sgi_close,
wave_out_format_supported:sgi_format_supported,
wave_out_set_format:sgi_set_format,
wave_out_volume:sgi_volume,
wave_out_play:sgi_play,
name:"sgi",
description:"SGI output driver",
next:NULL,
};
struct audio_driver *
sgi_register(char *options)
{
if (options)
{
sgi_output_device = xstrdup(options);
}
return &sgi_driver;
}

View File

@ -37,17 +37,11 @@
static BOOL g_reopened; static BOOL g_reopened;
static BOOL g_swapaudio; static BOOL g_swapaudio;
static short g_samplewidth; static short g_samplewidth;
static char *dsp_dev;
BOOL BOOL
wave_out_open(void) sun_open(void)
{ {
char *dsp_dev = getenv("AUDIODEV");
if (dsp_dev == NULL)
{
dsp_dev = xstrdup(DEFAULTDEVICE);
}
if ((g_dsp_fd = open(dsp_dev, O_WRONLY | O_NONBLOCK)) == -1) if ((g_dsp_fd = open(dsp_dev, O_WRONLY | O_NONBLOCK)) == -1)
{ {
perror(dsp_dev); perror(dsp_dev);
@ -64,7 +58,7 @@ wave_out_open(void)
} }
void void
wave_out_close(void) sun_close(void)
{ {
/* Ack all remaining packets */ /* Ack all remaining packets */
while (!rdpsnd_queue_empty()) while (!rdpsnd_queue_empty())
@ -85,7 +79,7 @@ wave_out_close(void)
} }
BOOL BOOL
wave_out_format_supported(WAVEFORMATEX * pwfx) sun_format_supported(WAVEFORMATEX * pwfx)
{ {
if (pwfx->wFormatTag != WAVE_FORMAT_PCM) if (pwfx->wFormatTag != WAVE_FORMAT_PCM)
return False; return False;
@ -98,7 +92,7 @@ wave_out_format_supported(WAVEFORMATEX * pwfx)
} }
BOOL BOOL
wave_out_set_format(WAVEFORMATEX * pwfx) sun_set_format(WAVEFORMATEX * pwfx)
{ {
audio_info_t info; audio_info_t info;
@ -152,7 +146,7 @@ wave_out_set_format(WAVEFORMATEX * pwfx)
} }
void void
wave_out_volume(uint16 left, uint16 right) sun_volume(uint16 left, uint16 right)
{ {
audio_info_t info; audio_info_t info;
uint balance; uint balance;
@ -184,7 +178,7 @@ wave_out_volume(uint16 left, uint16 right)
} }
void void
wave_out_play(void) sun_play(void)
{ {
struct audio_packet *packet; struct audio_packet *packet;
audio_info_t info; audio_info_t info;
@ -277,3 +271,36 @@ wave_out_play(void)
} }
} }
} }
static struct audio_driver sun_driver = {
wave_out_write:rdpsnd_queue_write,
wave_out_open:sun_open,
wave_out_close:sun_close,
wave_out_format_supported:sun_format_supported,
wave_out_set_format:sun_set_format,
wave_out_volume:sun_volume,
wave_out_play:sun_play,
name:"sun",
description:"SUN/BSD output driver, default device: " DEFAULTDEVICE " or $AUDIODEV",
next:NULL,
};
struct audio_driver *
sun_register(char *options)
{
if (options)
{
dsp_dev = xstrdup(options);
}
else
{
dsp_dev = getenv("AUDIODEV");
if (dsp_dev == NULL)
{
dsp_dev = xstrdup(DEFAULTDEVICE);
}
}
return &sun_driver;
}

2
xwin.c
View File

@ -2305,7 +2305,7 @@ ui_select(int rdp_socket)
#ifdef WITH_RDPSND #ifdef WITH_RDPSND
if (g_dsp_busy && FD_ISSET(g_dsp_fd, &wfds)) if (g_dsp_busy && FD_ISSET(g_dsp_fd, &wfds))
wave_out_play(); rdpsnd_play();
#endif #endif
} }
} }