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"
])
if test "$sound" = yes; then
AC_CHECK_HEADER(ao/ao.h, [sound=libao])
AC_CHECK_HEADER(sys/soundcard.h, [sound=oss])
AC_CHECK_HEADER(dmedia/audio.h, [sound=sgi])
AC_CHECK_HEADER(sys/audioio.h, [sound=sun])
AC_CHECK_HEADER(ao/ao.h,
[
sound=auto
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
if test "$sound" = no; then
break
elif test "$sound" = auto; then
SOUNDOBJ="$SOUNDOBJ rdpsnd.o"
AC_DEFINE(WITH_RDPSND)
elif test "$sound" = oss; then
SOUNDOBJ="rdpsnd.o rdpsnd_oss.o"
AC_DEFINE(WITH_RDPSND)
elif test "$sound" = sgi; then
SOUNDOBJ="rdpsnd.o rdpsnd_sgi.o"
LDFLAGS="$LDFLAGS -laudio"
elif test "$sound" = yes; then
SOUNDOBJ="$SOUNDOBJ rdpsnd.o"
AC_DEFINE(WITH_RDPSND)
elif test "$sound" = sun; then
SOUNDOBJ="rdpsnd.o rdpsnd_sun.o"
@ -176,11 +211,12 @@ elif test "$sound" = sun; then
elif test "$sound" = libao; then
SOUNDOBJ="rdpsnd.o rdpsnd_libao.o"
LDFLAGS="$LDFLAGS -lao"
AC_DEFINE(WITH_RDPSND)
AC_DEFINE(RDPSND_SUN)
elif test "$sound" = alsa; then
SOUNDOBJ="rdpsnd.o rdpsnd_alsa.o"
LDFLAGS="$LDFLAGS -lasound"
AC_DEFINE(WITH_RDPSND)
AC_DEFINE(RDPSND_ALSA)
else
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])

11
proto.h
View File

@ -165,14 +165,9 @@ BOOL rdpdr_abort_io(uint32 fd, uint32 major, NTSTATUS status);
/* rdpsnd.c */
void rdpsnd_send_completion(uint16 tick, uint8 packet_index);
BOOL rdpsnd_init(void);
/* rdpsnd_oss.c */
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_write(STREAM s, uint16 tick, uint8 index);
void wave_out_play(void);
BOOL rdpsnd_select_driver(char *driver, char *options);
void rdpsnd_show_help(void);
inline void rdpsnd_play(void);
/* secure.c */
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);

View File

@ -179,8 +179,13 @@ usage(char *program)
fprintf(stderr, " '-r printer:mydeskjet': enable printer redirection\n");
fprintf(stderr,
" 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, " available drivers for 'local':\n");
rdpsnd_show_help();
#endif
fprintf(stderr,
" '-r clipboard:[off|PRIMARYCLIPBOARD|CLIPBOARD]': enable clipboard\n");
fprintf(stderr, " redirection.\n");
@ -663,7 +668,36 @@ main(int argc, char *argv[])
if (str_startswith(optarg, "local"))
#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;
if (!rdpsnd_select_driver
(driver, options))
{
warning("Driver not available\n");
}
}
#else
warning("Not compiled with sound support\n");
#endif
@ -682,6 +716,10 @@ main(int argc, char *argv[])
{
#ifdef WITH_RDPSND
g_rdpsnd = True;
if (!rdpsnd_select_driver(NULL, NULL))
{
warning("No sound-driver available\n");
}
#else
warning("Not compiled with sound support\n");
#endif

127
rdpsnd.c
View File

@ -37,6 +37,8 @@ BOOL g_dsp_busy = False;
int g_dsp_fd;
static VCHANNEL *rdpsnd_channel;
static struct audio_driver *drivers = NULL;
static struct audio_driver *current_driver = NULL;
static BOOL device_open;
static WAVEFORMATEX formats[MAX_FORMATS];
@ -45,6 +47,8 @@ static unsigned int current_format;
static unsigned int queue_hi, queue_lo;
static struct audio_packet packet_queue[MAX_QUEUE];
void (*wave_out_play) (void);
static STREAM
rdpsnd_init_packet(uint16 type, uint16 size)
{
@ -94,9 +98,9 @@ rdpsnd_process_negotiate(STREAM in)
in_uint16_le(in, in_format_count);
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;
}
@ -127,7 +131,7 @@ rdpsnd_process_negotiate(STREAM in)
in_uint8a(in, format->cb, readcnt);
in_uint8s(in, discardcnt);
if (device_available && wave_out_format_supported(format))
if (device_available && current_driver->wave_out_format_supported(format))
{
format_count++;
if (format_count == MAX_FORMATS)
@ -205,15 +209,15 @@ rdpsnd_process(STREAM s)
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);
return;
}
if (!wave_out_set_format(&formats[format]))
if (!current_driver->wave_out_set_format(&formats[format]))
{
rdpsnd_send_completion(tick, packet_index);
wave_out_close();
current_driver->wave_out_close();
device_open = False;
return;
}
@ -221,7 +225,7 @@ rdpsnd_process(STREAM s)
current_format = format;
}
rdpsnd_queue_write(s, tick, packet_index);
current_driver->wave_out_write(s, tick, packet_index);
awaiting_data_packet = False;
return;
}
@ -239,7 +243,7 @@ rdpsnd_process(STREAM s)
awaiting_data_packet = True;
break;
case RDPSND_CLOSE:
wave_out_close();
current_driver->wave_out_close();
device_open = False;
break;
case RDPSND_NEGOTIATE:
@ -252,7 +256,8 @@ rdpsnd_process(STREAM s)
in_uint32(s, volume);
if (device_open)
{
wave_out_volume((volume & 0xffff), (volume & 0xffff0000) >> 16);
current_driver->wave_out_volume((volume & 0xffff),
(volume & 0xffff0000) >> 16);
}
break;
default:
@ -271,6 +276,108 @@ rdpsnd_init(void)
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
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);
if (!g_dsp_busy)
wave_out_play();
current_driver->wave_out_play();
}
inline struct audio_packet *

View File

@ -25,6 +25,20 @@ struct audio_packet
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 int g_dsp_fd;
@ -34,3 +48,10 @@ inline BOOL rdpsnd_queue_empty(void);
inline void rdpsnd_queue_init(void);
inline void rdpsnd_queue_next(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 short samplewidth;
static int audiochannels;
static char *pcm_name;
BOOL
wave_out_open(void)
alsa_open(void)
{
char *pcm_name;
int err;
pcm_name = xstrdup(DEFAULTDEVICE);
if ((err = snd_pcm_open(&pcm_handle, pcm_name, stream, 0)) < 0)
{
error("snd_pcm_open: %s\n", snd_strerror(err));
@ -60,7 +58,7 @@ wave_out_open(void)
}
void
wave_out_close(void)
alsa_close(void)
{
/* Ack all remaining packets */
while (!rdpsnd_queue_empty())
@ -70,7 +68,6 @@ wave_out_close(void)
rdpsnd_queue_next();
}
if (pcm_handle)
{
snd_pcm_drop(pcm_handle);
@ -79,7 +76,7 @@ wave_out_close(void)
}
BOOL
wave_out_format_supported(WAVEFORMATEX * pwfx)
alsa_format_supported(WAVEFORMATEX * pwfx)
{
#if 0
int err;
@ -112,7 +109,7 @@ wave_out_format_supported(WAVEFORMATEX * pwfx)
}
BOOL
wave_out_set_format(WAVEFORMATEX * pwfx)
alsa_set_format(WAVEFORMATEX * pwfx)
{
snd_pcm_hw_params_t *hwparams = NULL;
unsigned int rate, exact_rate;
@ -210,19 +207,19 @@ wave_out_set_format(WAVEFORMATEX * pwfx)
}
void
wave_out_volume(uint16 left, uint16 right)
alsa_volume(uint16 left, uint16 right)
{
static int warned = 0;
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;
}
}
void
wave_out_play(void)
alsa_play(void)
{
struct audio_packet *packet;
STREAM out;
@ -285,3 +282,31 @@ wave_out_play(void)
g_dsp_busy = 1;
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 BOOL reopened;
static short samplewidth;
static char *libao_device = NULL;
BOOL
wave_out_open(void)
libao_open(void)
{
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();
default_driver = ao_default_driver_id();
@ -67,7 +75,7 @@ wave_out_open(void)
}
void
wave_out_close(void)
libao_close(void)
{
/* Ack all remaining packets */
while (!rdpsnd_queue_empty())
@ -84,7 +92,7 @@ wave_out_close(void)
}
BOOL
wave_out_format_supported(WAVEFORMATEX * pwfx)
libao_format_supported(WAVEFORMATEX * pwfx)
{
if (pwfx->wFormatTag != WAVE_FORMAT_PCM)
return False;
@ -101,7 +109,7 @@ wave_out_format_supported(WAVEFORMATEX * pwfx)
}
BOOL
wave_out_set_format(WAVEFORMATEX * pwfx)
libao_set_format(WAVEFORMATEX * pwfx)
{
ao_sample_format format;
@ -129,13 +137,13 @@ wave_out_set_format(WAVEFORMATEX * pwfx)
}
void
wave_out_volume(uint16 left, uint16 right)
libao_volume(uint16 left, uint16 right)
{
warning("volume changes not supported with libao-output\n");
}
void
wave_out_play(void)
libao_play(void)
{
struct audio_packet *packet;
STREAM out;
@ -225,3 +233,27 @@ wave_out_play(void)
g_dsp_busy = 1;
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 short samplewidth;
static char *dsp_dev;
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)
{
perror(dsp_dev);
@ -62,13 +56,13 @@ wave_out_open(void)
}
void
wave_out_close(void)
oss_close(void)
{
close(g_dsp_fd);
}
BOOL
wave_out_format_supported(WAVEFORMATEX * pwfx)
oss_format_supported(WAVEFORMATEX * pwfx)
{
if (pwfx->wFormatTag != WAVE_FORMAT_PCM)
return False;
@ -81,7 +75,7 @@ wave_out_format_supported(WAVEFORMATEX * pwfx)
}
BOOL
wave_out_set_format(WAVEFORMATEX * pwfx)
oss_set_format(WAVEFORMATEX * pwfx)
{
int stereo, format, fragments;
static BOOL driver_broken = False;
@ -157,7 +151,7 @@ wave_out_set_format(WAVEFORMATEX * pwfx)
}
void
wave_out_volume(uint16 left, uint16 right)
oss_volume(uint16 left, uint16 right)
{
static BOOL use_dev_mixer = False;
uint32 volume;
@ -192,7 +186,7 @@ wave_out_volume(uint16 left, uint16 right)
}
void
wave_out_play(void)
oss_play(void)
{
struct audio_packet *packet;
ssize_t len;
@ -257,3 +251,36 @@ wave_out_play(void)
g_dsp_busy = 1;
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 BOOL g_swapaudio;
static int width = AL_SAMPLE_16;
static char *sgi_output_device = NULL;
double min_volume, max_volume, volume_range;
int resource, maxFillable;
int combinedFrameSize;
BOOL
wave_out_open(void)
sgi_open(void)
{
ALparamInfo pinfo;
static int warned = 0;
#if (defined(IRIX_DEBUG))
fprintf(stderr, "sgi_open: begin\n");
#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)
{
fprintf(stderr, "sgi_open: alGetParamInfo failed: %s\n",
@ -85,7 +93,7 @@ wave_out_open(void)
}
void
wave_out_close(void)
sgi_close(void)
{
/* Ack all remaining packets */
#if (defined(IRIX_DEBUG))
@ -110,7 +118,7 @@ wave_out_close(void)
}
BOOL
wave_out_format_supported(WAVEFORMATEX * pwfx)
sgi_format_supported(WAVEFORMATEX * pwfx)
{
if (pwfx->wFormatTag != WAVE_FORMAT_PCM)
return False;
@ -123,7 +131,7 @@ wave_out_format_supported(WAVEFORMATEX * pwfx)
}
BOOL
wave_out_set_format(WAVEFORMATEX * pwfx)
sgi_set_format(WAVEFORMATEX * pwfx)
{
int channels;
int frameSize, channelCount;
@ -207,7 +215,7 @@ wave_out_set_format(WAVEFORMATEX * pwfx)
}
void
wave_out_volume(uint16 left, uint16 right)
sgi_volume(uint16 left, uint16 right)
{
double gainleft, gainright;
ALpv pv[1];
@ -240,7 +248,7 @@ wave_out_volume(uint16 left, uint16 right)
}
void
wave_out_play(void)
sgi_play(void)
{
struct audio_packet *packet;
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_swapaudio;
static short g_samplewidth;
static char *dsp_dev;
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)
{
perror(dsp_dev);
@ -64,7 +58,7 @@ wave_out_open(void)
}
void
wave_out_close(void)
sun_close(void)
{
/* Ack all remaining packets */
while (!rdpsnd_queue_empty())
@ -85,7 +79,7 @@ wave_out_close(void)
}
BOOL
wave_out_format_supported(WAVEFORMATEX * pwfx)
sun_format_supported(WAVEFORMATEX * pwfx)
{
if (pwfx->wFormatTag != WAVE_FORMAT_PCM)
return False;
@ -98,7 +92,7 @@ wave_out_format_supported(WAVEFORMATEX * pwfx)
}
BOOL
wave_out_set_format(WAVEFORMATEX * pwfx)
sun_set_format(WAVEFORMATEX * pwfx)
{
audio_info_t info;
@ -152,7 +146,7 @@ wave_out_set_format(WAVEFORMATEX * pwfx)
}
void
wave_out_volume(uint16 left, uint16 right)
sun_volume(uint16 left, uint16 right)
{
audio_info_t info;
uint balance;
@ -184,7 +178,7 @@ wave_out_volume(uint16 left, uint16 right)
}
void
wave_out_play(void)
sun_play(void)
{
struct audio_packet *packet;
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
if (g_dsp_busy && FD_ISSET(g_dsp_fd, &wfds))
wave_out_play();
rdpsnd_play();
#endif
}
}