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:
parent
ec4862937f
commit
07b5b9e41c
46
configure.ac
46
configure.ac
@ -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
11
proto.h
@ -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);
|
||||||
|
40
rdesktop.c
40
rdesktop.c
@ -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
127
rdpsnd.c
@ -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 *
|
||||||
|
21
rdpsnd.h
21
rdpsnd.h
@ -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);
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
53
rdpsnd_oss.c
53
rdpsnd_oss.c
@ -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;
|
||||||
|
}
|
||||||
|
43
rdpsnd_sgi.c
43
rdpsnd_sgi.c
@ -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;
|
||||||
|
}
|
||||||
|
53
rdpsnd_sun.c
53
rdpsnd_sun.c
@ -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;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user