From 07b5b9e41c3570a9267289946d80419e8230ac8f Mon Sep 17 00:00:00 2001 From: Michael Gernoth Date: Sun, 17 Sep 2006 11:04:50 +0000 Subject: [PATCH] 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 --- configure.ac | 46 ++++++++++++++++-- proto.h | 11 ++--- rdesktop.c | 40 +++++++++++++++- rdpsnd.c | 127 +++++++++++++++++++++++++++++++++++++++++++++---- rdpsnd.h | 21 ++++++++ rdpsnd_alsa.c | 47 +++++++++++++----- rdpsnd_libao.c | 44 ++++++++++++++--- rdpsnd_oss.c | 53 ++++++++++++++++----- rdpsnd_sgi.c | 43 ++++++++++++++--- rdpsnd_sun.c | 53 ++++++++++++++++----- xwin.c | 2 +- 11 files changed, 413 insertions(+), 74 deletions(-) diff --git a/configure.ac b/configure.ac index 167ca69..4d470a0 100644 --- a/configure.ac +++ b/configure.ac @@ -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]) diff --git a/proto.h b/proto.h index e809304..b6a240a 100644 --- a/proto.h +++ b/proto.h @@ -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); diff --git a/rdesktop.c b/rdesktop.c index ffd796d..531d2b6 100644 --- a/rdesktop.c +++ b/rdesktop.c @@ -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 diff --git a/rdpsnd.c b/rdpsnd.c index 0d05233..4bf6b11 100644 --- a/rdpsnd.c +++ b/rdpsnd.c @@ -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 * diff --git a/rdpsnd.h b/rdpsnd.h index e2e9989..628aeb2 100644 --- a/rdpsnd.h +++ b/rdpsnd.h @@ -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); diff --git a/rdpsnd_alsa.c b/rdpsnd_alsa.c index d1c394a..00c6797 100644 --- a/rdpsnd_alsa.c +++ b/rdpsnd_alsa.c @@ -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; +} diff --git a/rdpsnd_libao.c b/rdpsnd_libao.c index 19c9020..3f99f89 100644 --- a/rdpsnd_libao.c +++ b/rdpsnd_libao.c @@ -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; +} diff --git a/rdpsnd_oss.c b/rdpsnd_oss.c index c62475e..a709d7a 100644 --- a/rdpsnd_oss.c +++ b/rdpsnd_oss.c @@ -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; +} diff --git a/rdpsnd_sgi.c b/rdpsnd_sgi.c index 5b81928..b863c9d 100644 --- a/rdpsnd_sgi.c +++ b/rdpsnd_sgi.c @@ -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; +} diff --git a/rdpsnd_sun.c b/rdpsnd_sun.c index af9aceb..e3aee96 100644 --- a/rdpsnd_sun.c +++ b/rdpsnd_sun.c @@ -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; +} diff --git a/xwin.c b/xwin.c index d5c5fd6..d6f6875 100644 --- a/xwin.c +++ b/xwin.c @@ -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 } }