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/