Reworked device opening, only open the device with the access that we
currently needs. Avoids transmitting recording data on playback with padsp. git-svn-id: svn://svn.code.sf.net/p/rdesktop/code/trunk/rdesktop@1480 423420c4-83ab-492f-b58f-81f9feb106b5
This commit is contained in:
parent
edbae085f1
commit
d87e27483f
121
rdpsnd_oss.c
121
rdpsnd_oss.c
@ -28,6 +28,8 @@
|
||||
#undef _FILE_OFFSET_BITS
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "rdesktop.h"
|
||||
#include "rdpsnd.h"
|
||||
#include "rdpsnd_dsp.h"
|
||||
@ -46,14 +48,10 @@
|
||||
|
||||
static int dsp_fd = -1;
|
||||
static int dsp_mode;
|
||||
static int dsp_refs;
|
||||
|
||||
static RD_BOOL dsp_configured;
|
||||
static RD_BOOL dsp_broken;
|
||||
|
||||
static RD_BOOL dsp_out;
|
||||
static RD_BOOL dsp_in;
|
||||
|
||||
static int stereo;
|
||||
static int format;
|
||||
static uint32 snd_rate;
|
||||
@ -66,6 +64,7 @@ static struct audio_driver oss_driver;
|
||||
|
||||
static void oss_play(void);
|
||||
static void oss_record(void);
|
||||
static RD_BOOL oss_set_format(RD_WAVEFORMATEX * pwfx);
|
||||
|
||||
static void
|
||||
oss_add_fds(int *n, fd_set * rfds, fd_set * wfds, struct timeval *tv)
|
||||
@ -73,9 +72,9 @@ oss_add_fds(int *n, fd_set * rfds, fd_set * wfds, struct timeval *tv)
|
||||
if (dsp_fd == -1)
|
||||
return;
|
||||
|
||||
if (dsp_out && !rdpsnd_queue_empty())
|
||||
if ((dsp_mode == O_WRONLY || dsp_mode == O_RDWR) && !rdpsnd_queue_empty())
|
||||
FD_SET(dsp_fd, wfds);
|
||||
if (dsp_in)
|
||||
if (dsp_mode == O_RDONLY || dsp_mode == O_RDWR)
|
||||
FD_SET(dsp_fd, rfds);
|
||||
if (dsp_fd > *n)
|
||||
*n = dsp_fd;
|
||||
@ -112,54 +111,71 @@ detect_esddsp(void)
|
||||
return True;
|
||||
}
|
||||
|
||||
static RD_BOOL
|
||||
oss_open(int fallback)
|
||||
{
|
||||
int caps;
|
||||
|
||||
static void
|
||||
oss_restore_format()
|
||||
{
|
||||
RD_WAVEFORMATEX wfx;
|
||||
memset(&wfx, 0, sizeof(RD_WAVEFORMATEX));
|
||||
switch (format)
|
||||
{
|
||||
case AFMT_U8:
|
||||
wfx.wBitsPerSample = 8;
|
||||
break;
|
||||
case AFMT_S16_LE:
|
||||
wfx.wBitsPerSample = 16;
|
||||
break;
|
||||
default:
|
||||
wfx.wBitsPerSample = 0;
|
||||
}
|
||||
wfx.nChannels = stereo ? 2 : 1;
|
||||
wfx.nSamplesPerSec = snd_rate;
|
||||
oss_set_format(&wfx);
|
||||
}
|
||||
|
||||
|
||||
static RD_BOOL
|
||||
oss_open(int wanted)
|
||||
{
|
||||
if (dsp_fd != -1)
|
||||
{
|
||||
dsp_refs++;
|
||||
|
||||
if (dsp_mode == O_RDWR)
|
||||
if (wanted == dsp_mode)
|
||||
{
|
||||
/* should probably not happen */
|
||||
return True;
|
||||
|
||||
if (dsp_mode == fallback)
|
||||
return True;
|
||||
|
||||
dsp_refs--;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* device open but not our mode. Before
|
||||
reopening O_RDWR, verify that the device is
|
||||
duplex capable */
|
||||
int caps;
|
||||
ioctl(dsp_fd, SNDCTL_DSP_SETDUPLEX, 0);
|
||||
if ((ioctl(dsp_fd, SNDCTL_DSP_GETCAPS, &caps) < 0)
|
||||
|| !(caps & DSP_CAP_DUPLEX))
|
||||
{
|
||||
warning("This device is not capable of full duplex operation.\n");
|
||||
return False;
|
||||
}
|
||||
close(dsp_fd);
|
||||
dsp_mode = O_RDWR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dsp_mode = wanted;
|
||||
}
|
||||
|
||||
dsp_configured = False;
|
||||
dsp_broken = False;
|
||||
|
||||
dsp_mode = O_RDWR;
|
||||
dsp_fd = open(dsp_dev, O_RDWR | O_NONBLOCK);
|
||||
if (dsp_fd != -1)
|
||||
{
|
||||
ioctl(dsp_fd, SNDCTL_DSP_SETDUPLEX, 0);
|
||||
|
||||
if ((ioctl(dsp_fd, SNDCTL_DSP_GETCAPS, &caps) < 0) || !(caps & DSP_CAP_DUPLEX))
|
||||
{
|
||||
close(dsp_fd);
|
||||
dsp_fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (dsp_fd == -1)
|
||||
{
|
||||
dsp_mode = fallback;
|
||||
|
||||
dsp_fd = open(dsp_dev, dsp_mode | O_NONBLOCK);
|
||||
|
||||
if (dsp_fd == -1)
|
||||
{
|
||||
perror(dsp_dev);
|
||||
return False;
|
||||
}
|
||||
}
|
||||
|
||||
dsp_refs++;
|
||||
|
||||
in_esddsp = detect_esddsp();
|
||||
|
||||
@ -169,11 +185,6 @@ oss_open(int fallback)
|
||||
static void
|
||||
oss_close(void)
|
||||
{
|
||||
dsp_refs--;
|
||||
|
||||
if (dsp_refs != 0)
|
||||
return;
|
||||
|
||||
close(dsp_fd);
|
||||
dsp_fd = -1;
|
||||
}
|
||||
@ -184,8 +195,6 @@ oss_open_out(void)
|
||||
if (!oss_open(O_WRONLY))
|
||||
return False;
|
||||
|
||||
dsp_out = True;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
@ -193,12 +202,15 @@ static void
|
||||
oss_close_out(void)
|
||||
{
|
||||
oss_close();
|
||||
if (dsp_mode == O_RDWR)
|
||||
{
|
||||
if (oss_open(O_RDONLY))
|
||||
oss_restore_format();
|
||||
}
|
||||
|
||||
/* Ack all remaining packets */
|
||||
while (!rdpsnd_queue_empty())
|
||||
rdpsnd_queue_next(0);
|
||||
|
||||
dsp_out = False;
|
||||
}
|
||||
|
||||
static RD_BOOL
|
||||
@ -207,8 +219,6 @@ oss_open_in(void)
|
||||
if (!oss_open(O_RDONLY))
|
||||
return False;
|
||||
|
||||
dsp_in = True;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
@ -216,8 +226,11 @@ static void
|
||||
oss_close_in(void)
|
||||
{
|
||||
oss_close();
|
||||
|
||||
dsp_in = False;
|
||||
if (dsp_mode == O_RDWR)
|
||||
{
|
||||
if (oss_open(O_WRONLY))
|
||||
oss_restore_format();
|
||||
}
|
||||
}
|
||||
|
||||
static RD_BOOL
|
||||
@ -239,6 +252,8 @@ oss_set_format(RD_WAVEFORMATEX * pwfx)
|
||||
int fragments;
|
||||
static RD_BOOL driver_broken = False;
|
||||
|
||||
assert(dsp_fd != -1);
|
||||
|
||||
if (dsp_configured)
|
||||
{
|
||||
if ((pwfx->wBitsPerSample == 8) && (format != AFMT_U8))
|
||||
@ -378,6 +393,8 @@ oss_play(void)
|
||||
ssize_t len;
|
||||
STREAM out;
|
||||
|
||||
assert(dsp_fd != -1);
|
||||
|
||||
/* We shouldn't be called if the queue is empty, but still */
|
||||
if (rdpsnd_queue_empty())
|
||||
return;
|
||||
@ -446,6 +463,8 @@ oss_record(void)
|
||||
char buffer[32768];
|
||||
int len;
|
||||
|
||||
assert(dsp_fd != -1);
|
||||
|
||||
len = read(dsp_fd, buffer, sizeof(buffer));
|
||||
if (len == -1)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user