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:
Peter Åstrand 2008-10-02 18:21:58 +00:00
parent edbae085f1
commit d87e27483f

View File

@ -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)
{