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
127
rdpsnd_oss.c
127
rdpsnd_oss.c
@ -28,6 +28,8 @@
|
|||||||
#undef _FILE_OFFSET_BITS
|
#undef _FILE_OFFSET_BITS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#include "rdesktop.h"
|
#include "rdesktop.h"
|
||||||
#include "rdpsnd.h"
|
#include "rdpsnd.h"
|
||||||
#include "rdpsnd_dsp.h"
|
#include "rdpsnd_dsp.h"
|
||||||
@ -46,14 +48,10 @@
|
|||||||
|
|
||||||
static int dsp_fd = -1;
|
static int dsp_fd = -1;
|
||||||
static int dsp_mode;
|
static int dsp_mode;
|
||||||
static int dsp_refs;
|
|
||||||
|
|
||||||
static RD_BOOL dsp_configured;
|
static RD_BOOL dsp_configured;
|
||||||
static RD_BOOL dsp_broken;
|
static RD_BOOL dsp_broken;
|
||||||
|
|
||||||
static RD_BOOL dsp_out;
|
|
||||||
static RD_BOOL dsp_in;
|
|
||||||
|
|
||||||
static int stereo;
|
static int stereo;
|
||||||
static int format;
|
static int format;
|
||||||
static uint32 snd_rate;
|
static uint32 snd_rate;
|
||||||
@ -66,6 +64,7 @@ static struct audio_driver oss_driver;
|
|||||||
|
|
||||||
static void oss_play(void);
|
static void oss_play(void);
|
||||||
static void oss_record(void);
|
static void oss_record(void);
|
||||||
|
static RD_BOOL oss_set_format(RD_WAVEFORMATEX * pwfx);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
oss_add_fds(int *n, fd_set * rfds, fd_set * wfds, struct timeval *tv)
|
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)
|
if (dsp_fd == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (dsp_out && !rdpsnd_queue_empty())
|
if ((dsp_mode == O_WRONLY || dsp_mode == O_RDWR) && !rdpsnd_queue_empty())
|
||||||
FD_SET(dsp_fd, wfds);
|
FD_SET(dsp_fd, wfds);
|
||||||
if (dsp_in)
|
if (dsp_mode == O_RDONLY || dsp_mode == O_RDWR)
|
||||||
FD_SET(dsp_fd, rfds);
|
FD_SET(dsp_fd, rfds);
|
||||||
if (dsp_fd > *n)
|
if (dsp_fd > *n)
|
||||||
*n = dsp_fd;
|
*n = dsp_fd;
|
||||||
@ -112,55 +111,72 @@ detect_esddsp(void)
|
|||||||
return True;
|
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)
|
if (dsp_fd != -1)
|
||||||
{
|
{
|
||||||
dsp_refs++;
|
if (wanted == dsp_mode)
|
||||||
|
{
|
||||||
if (dsp_mode == O_RDWR)
|
/* should probably not happen */
|
||||||
return True;
|
return True;
|
||||||
|
}
|
||||||
if (dsp_mode == fallback)
|
else
|
||||||
return True;
|
{
|
||||||
|
/* device open but not our mode. Before
|
||||||
dsp_refs--;
|
reopening O_RDWR, verify that the device is
|
||||||
return False;
|
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_configured = False;
|
||||||
dsp_broken = False;
|
dsp_broken = False;
|
||||||
|
|
||||||
dsp_mode = O_RDWR;
|
dsp_fd = open(dsp_dev, dsp_mode | O_NONBLOCK);
|
||||||
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)
|
if (dsp_fd == -1)
|
||||||
{
|
{
|
||||||
dsp_mode = fallback;
|
perror(dsp_dev);
|
||||||
|
return False;
|
||||||
dsp_fd = open(dsp_dev, dsp_mode | O_NONBLOCK);
|
|
||||||
if (dsp_fd == -1)
|
|
||||||
{
|
|
||||||
perror(dsp_dev);
|
|
||||||
return False;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dsp_refs++;
|
|
||||||
|
|
||||||
in_esddsp = detect_esddsp();
|
in_esddsp = detect_esddsp();
|
||||||
|
|
||||||
return True;
|
return True;
|
||||||
@ -169,11 +185,6 @@ oss_open(int fallback)
|
|||||||
static void
|
static void
|
||||||
oss_close(void)
|
oss_close(void)
|
||||||
{
|
{
|
||||||
dsp_refs--;
|
|
||||||
|
|
||||||
if (dsp_refs != 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
close(dsp_fd);
|
close(dsp_fd);
|
||||||
dsp_fd = -1;
|
dsp_fd = -1;
|
||||||
}
|
}
|
||||||
@ -184,8 +195,6 @@ oss_open_out(void)
|
|||||||
if (!oss_open(O_WRONLY))
|
if (!oss_open(O_WRONLY))
|
||||||
return False;
|
return False;
|
||||||
|
|
||||||
dsp_out = True;
|
|
||||||
|
|
||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,12 +202,15 @@ static void
|
|||||||
oss_close_out(void)
|
oss_close_out(void)
|
||||||
{
|
{
|
||||||
oss_close();
|
oss_close();
|
||||||
|
if (dsp_mode == O_RDWR)
|
||||||
|
{
|
||||||
|
if (oss_open(O_RDONLY))
|
||||||
|
oss_restore_format();
|
||||||
|
}
|
||||||
|
|
||||||
/* Ack all remaining packets */
|
/* Ack all remaining packets */
|
||||||
while (!rdpsnd_queue_empty())
|
while (!rdpsnd_queue_empty())
|
||||||
rdpsnd_queue_next(0);
|
rdpsnd_queue_next(0);
|
||||||
|
|
||||||
dsp_out = False;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static RD_BOOL
|
static RD_BOOL
|
||||||
@ -207,8 +219,6 @@ oss_open_in(void)
|
|||||||
if (!oss_open(O_RDONLY))
|
if (!oss_open(O_RDONLY))
|
||||||
return False;
|
return False;
|
||||||
|
|
||||||
dsp_in = True;
|
|
||||||
|
|
||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,8 +226,11 @@ static void
|
|||||||
oss_close_in(void)
|
oss_close_in(void)
|
||||||
{
|
{
|
||||||
oss_close();
|
oss_close();
|
||||||
|
if (dsp_mode == O_RDWR)
|
||||||
dsp_in = False;
|
{
|
||||||
|
if (oss_open(O_WRONLY))
|
||||||
|
oss_restore_format();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static RD_BOOL
|
static RD_BOOL
|
||||||
@ -239,6 +252,8 @@ oss_set_format(RD_WAVEFORMATEX * pwfx)
|
|||||||
int fragments;
|
int fragments;
|
||||||
static RD_BOOL driver_broken = False;
|
static RD_BOOL driver_broken = False;
|
||||||
|
|
||||||
|
assert(dsp_fd != -1);
|
||||||
|
|
||||||
if (dsp_configured)
|
if (dsp_configured)
|
||||||
{
|
{
|
||||||
if ((pwfx->wBitsPerSample == 8) && (format != AFMT_U8))
|
if ((pwfx->wBitsPerSample == 8) && (format != AFMT_U8))
|
||||||
@ -378,6 +393,8 @@ oss_play(void)
|
|||||||
ssize_t len;
|
ssize_t len;
|
||||||
STREAM out;
|
STREAM out;
|
||||||
|
|
||||||
|
assert(dsp_fd != -1);
|
||||||
|
|
||||||
/* We shouldn't be called if the queue is empty, but still */
|
/* We shouldn't be called if the queue is empty, but still */
|
||||||
if (rdpsnd_queue_empty())
|
if (rdpsnd_queue_empty())
|
||||||
return;
|
return;
|
||||||
@ -446,6 +463,8 @@ oss_record(void)
|
|||||||
char buffer[32768];
|
char buffer[32768];
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
|
assert(dsp_fd != -1);
|
||||||
|
|
||||||
len = read(dsp_fd, buffer, sizeof(buffer));
|
len = read(dsp_fd, buffer, sizeof(buffer));
|
||||||
if (len == -1)
|
if (len == -1)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user