CVS: rdesktop rdpsnd_sun.c,1.31,1.32
Pierre Ossman <[email protected]> Tue, 22 Jan 2008 02:42:57 -0800
| Newsgroups | gmane.network.rdesktop.cvs |
|---|---|
| Message-ID | <[email protected]> |
Update of /cvsroot/rdesktop/rdesktop
In directory sc8-pr-cvs9.sourceforge.net:/tmp/cvs-serv17918
Modified Files:
rdpsnd_sun.c
Log Message:
Record support for Sun audio backend. Also do some general improvements and
get it more in line with the OSS backend.
Index: rdpsnd_sun.c
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/rdpsnd_sun.c,v
retrieving revision 1.31
retrieving revision 1.32
diff -C2 -d -r1.31 -r1.32
*** rdpsnd_sun.c 8 Jan 2007 04:47:06 -0000 1.31
--- rdpsnd_sun.c 22 Jan 2008 10:42:55 -0000 1.32
***************
*** 5,8 ****
--- 5,9 ----
Copyright (C) GuoJunBo [email protected] 2003
Copyright (C) Michael Gernoth [email protected] 2003-2007
+ Copyright 2007 Pierre Ossman <[email protected]> for Cendio AB
This program is free software; you can redistribute it and/or modify
***************
*** 34,46 ****
#define DEFAULTDEVICE "/dev/audio"
static int dsp_fd = -1;
! static RD_BOOL dsp_busy;
! static RD_BOOL g_reopened;
! static short g_samplewidth;
static char *dsp_dev;
void sun_play(void);
void
--- 35,60 ----
#define DEFAULTDEVICE "/dev/audio"
+ #define MAX_LEN 512
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;
! static short samplewidth;
static char *dsp_dev;
+ static uint_t written_samples;
+
void sun_play(void);
+ void sun_record(void);
void
***************
*** 50,57 ****
return;
! if (rdpsnd_queue_empty())
! return;
!
! FD_SET(dsp_fd, wfds);
if (dsp_fd > *n)
*n = dsp_fd;
--- 64,71 ----
return;
! if (dsp_out && !rdpsnd_queue_empty())
! FD_SET(dsp_fd, wfds);
! if (dsp_in)
! FD_SET(dsp_fd, rfds);
if (dsp_fd > *n)
*n = dsp_fd;
***************
*** 63,81 ****
if (FD_ISSET(dsp_fd, wfds))
sun_play();
}
RD_BOOL
! sun_open(void)
{
! if ((dsp_fd = open(dsp_dev, O_WRONLY | O_NONBLOCK)) == -1)
{
! perror(dsp_dev);
return False;
}
! /* Non-blocking so that user interface is responsive */
! fcntl(dsp_fd, F_SETFL, fcntl(dsp_fd, F_GETFL) | O_NONBLOCK);
! g_reopened = True;
return True;
--- 77,135 ----
if (FD_ISSET(dsp_fd, wfds))
sun_play();
+ if (FD_ISSET(dsp_fd, rfds))
+ sun_record();
}
RD_BOOL
! sun_open(int mode)
{
! audio_info_t info;
!
! if (dsp_fd != -1)
{
! dsp_refs++;
!
! if (dsp_mode == O_RDWR)
! return True;
!
! if (dsp_mode == mode)
! return True;
!
! dsp_refs--;
return False;
}
! dsp_configured = False;
! dsp_broken = False;
! written_samples = 0;
!
! dsp_mode = O_RDWR;
! dsp_fd = open(dsp_dev, O_RDWR | O_NONBLOCK);
! if (dsp_fd != -1)
! {
! AUDIO_INITINFO(&info);
!
! if ((ioctl(dsp_fd, AUDIO_GETINFO, &info) == -1)
! || !(info.hw_features & AUDIO_HWFEATURE_DUPLEX))
! {
! close(dsp_fd);
! dsp_fd = -1;
! }
! }
!
! if (dsp_fd == -1)
! {
! dsp_mode = mode;
!
! dsp_fd = open(dsp_dev, dsp_mode | O_NONBLOCK);
! if (dsp_fd == -1)
! {
! perror(dsp_dev);
! return False;
! }
! }
!
! dsp_refs++;
return True;
***************
*** 85,92 ****
sun_close(void)
{
! /* Ack all remaining packets */
! while (!rdpsnd_queue_empty())
! rdpsnd_queue_next(0);
#if defined I_FLUSH && defined FLUSHW
/* Flush the audiobuffer */
--- 139,165 ----
sun_close(void)
{
! dsp_refs--;
!
! if (dsp_refs != 0)
! return;
+ close(dsp_fd);
+ dsp_fd = -1;
+ }
+
+ RD_BOOL
+ sun_open_out(void)
+ {
+ if (!sun_open(O_WRONLY))
+ return False;
+
+ dsp_out = True;
+
+ return True;
+ }
+
+ void
+ sun_close_out(void)
+ {
#if defined I_FLUSH && defined FLUSHW
/* Flush the audiobuffer */
***************
*** 96,101 ****
ioctl(dsp_fd, AUDIO_FLUSH, NULL);
#endif
! close(dsp_fd);
! dsp_fd = -1;
}
--- 169,199 ----
ioctl(dsp_fd, AUDIO_FLUSH, NULL);
#endif
!
! sun_close();
!
! /* Ack all remaining packets */
! while (!rdpsnd_queue_empty())
! rdpsnd_queue_next(0);
!
! dsp_out = False;
! }
!
! RD_BOOL
! sun_open_in(void)
! {
! if (!sun_open(O_RDONLY))
! return False;
!
! dsp_in = True;
!
! return True;
! }
!
! void
! sun_close_in(void)
! {
! sun_close();
!
! dsp_in = False;
}
***************
*** 121,124 ****
--- 219,237 ----
AUDIO_INITINFO(&info);
+ if (dsp_configured)
+ {
+ if ((pwfx->wBitsPerSample == 8) && (format != AUDIO_ENCODING_LINEAR8))
+ return False;
+ if ((pwfx->wBitsPerSample == 16) && (format != AUDIO_ENCODING_LINEAR))
+ return False;
+
+ if ((pwfx->nChannels == 2) != !!stereo)
+ return False;
+
+ if (pwfx->nSamplesPerSec != snd_rate)
+ return False;
+
+ return True;
+ }
if (pwfx->wBitsPerSample == 8)
***************
*** 131,135 ****
}
! g_samplewidth = pwfx->wBitsPerSample / 8;
if (pwfx->nChannels == 1)
--- 244,248 ----
}
! samplewidth = pwfx->wBitsPerSample / 8;
if (pwfx->nChannels == 1)
***************
*** 140,146 ****
{
info.play.channels = 2;
! g_samplewidth *= 2;
}
info.play.sample_rate = pwfx->nSamplesPerSec;
info.play.precision = pwfx->wBitsPerSample;
--- 253,261 ----
{
info.play.channels = 2;
! samplewidth *= 2;
}
+ snd_rate = pwfx->nSamplesPerSec;
+
info.play.sample_rate = pwfx->nSamplesPerSec;
info.play.precision = pwfx->wBitsPerSample;
***************
*** 148,152 ****
info.play.eof = 0;
info.play.error = 0;
! g_reopened = True;
if (ioctl(dsp_fd, AUDIO_SETINFO, &info) == -1)
--- 263,273 ----
info.play.eof = 0;
info.play.error = 0;
!
! info.record.sample_rate = info.play.sample_rate;
! info.record.channels = info.play.channels;
! info.record.precision = info.play.precision;
! info.record.encoding = info.play.encoding;
! info.record.samples = 0;
! info.record.error = 0;
if (ioctl(dsp_fd, AUDIO_SETINFO, &info) == -1)
***************
*** 157,160 ****
--- 278,283 ----
}
+ dsp_configured = True;
+
return True;
}
***************
*** 196,266 ****
{
struct audio_packet *packet;
- audio_info_t info;
ssize_t len;
- unsigned int i;
STREAM out;
- static RD_BOOL sentcompletion = True;
- static uint32 samplecnt = 0;
- static uint32 numsamples;
! while (1)
{
! if (g_reopened)
{
! /* Device was just (re)openend */
! samplecnt = 0;
! sentcompletion = True;
! g_reopened = False;
}
! if (rdpsnd_queue_empty())
! return;
! packet = rdpsnd_queue_current_packet();
! out = &packet->s;
! if (sentcompletion)
! {
! sentcompletion = False;
! numsamples = (out->end - out->p) / g_samplewidth;
! }
! len = 0;
! if (out->end != out->p)
! {
! len = write(dsp_fd, out->p, out->end - out->p);
! if (len == -1)
! {
! if (errno != EWOULDBLOCK)
! perror("write audio");
! return;
! }
! }
! out->p += len;
! if (out->p == out->end)
! {
! if (ioctl(dsp_fd, AUDIO_GETINFO, &info) == -1)
! {
! perror("AUDIO_GETINFO");
! return;
! }
! /* Ack the packet, if we have played at least 70% */
! if (info.play.samples >= samplecnt + ((numsamples * 7) / 10))
! {
! samplecnt += numsamples;
! /* We need to add 50 to tell windows that time has passed while
! * playing this packet */
! rdpsnd_queue_next(50);
! sentcompletion = True;
! }
! else
! {
! return;
! }
! }
}
}
--- 319,384 ----
{
struct audio_packet *packet;
ssize_t len;
STREAM out;
! /* We shouldn't be called if the queue is empty, but still */
! if (rdpsnd_queue_empty())
! return;
!
! packet = rdpsnd_queue_current_packet();
! out = &packet->s;
!
! len = out->end - out->p;
!
! len = write(dsp_fd, out->p, (len > MAX_LEN) ? MAX_LEN : len);
! if (len == -1)
{
! if (errno != EWOULDBLOCK)
{
! if (!dsp_broken)
! perror("RDPSND: write()");
! dsp_broken = True;
! rdpsnd_queue_next(0);
}
+ return;
+ }
! written_samples += len / (samplewidth * (stereo ? 2 : 1));
! dsp_broken = False;
! out->p += len;
! if (out->p == out->end)
! {
! audio_info_t info;
! uint_t delay_samples;
! unsigned long delay_us;
! if (ioctl(dsp_fd, AUDIO_GETINFO, &info) != -1)
! delay_samples = written_samples - info.play.samples;
! else
! delay_samples = out->size / (samplewidth * (stereo ? 2 : 1));
! delay_us = delay_samples * (1000000 / snd_rate);
! rdpsnd_queue_next(delay_us);
! }
! }
! void
! sun_record(void)
! {
! char buffer[32768];
! int len;
!
! len = read(dsp_fd, buffer, sizeof(buffer));
! if (len == -1)
! {
! if (errno != EWOULDBLOCK)
! perror("read audio");
! return;
}
+
+ rdpsnd_record(buffer, len);
}
***************
*** 279,288 ****
sun_driver.check_fds = sun_check_fds;
! sun_driver.wave_out_open = sun_open;
! sun_driver.wave_out_close = sun_close;
sun_driver.wave_out_format_supported = sun_format_supported;
sun_driver.wave_out_set_format = sun_set_format;
sun_driver.wave_out_volume = sun_volume;
sun_driver.need_byteswap_on_be = 1;
sun_driver.need_resampling = 0;
--- 397,412 ----
sun_driver.check_fds = sun_check_fds;
! sun_driver.wave_out_open = sun_open_out;
! sun_driver.wave_out_close = sun_close_out;
sun_driver.wave_out_format_supported = sun_format_supported;
sun_driver.wave_out_set_format = sun_set_format;
sun_driver.wave_out_volume = sun_volume;
+ sun_driver.wave_in_open = sun_open_in;
+ sun_driver.wave_in_close = sun_close_in;
+ sun_driver.wave_in_format_supported = sun_format_supported;
+ sun_driver.wave_in_set_format = sun_set_format;
+ sun_driver.wave_in_volume = NULL; /* FIXME */
+
sun_driver.need_byteswap_on_be = 1;
sun_driver.need_resampling = 0;
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/