CVS: rdesktop rdpsnd_dsp.c, 1.7, 1.8 rdpsnd_dsp.h, 1.2, 1.3 rdpsnd_libao.c, 1.22, 1.23

Michael Gernoth <[email protected]> Sun, 01 Oct 2006 05:16:52 -0700
Newsgroups gmane.network.rdesktop.cvs
Message-ID <[email protected]>
Update of /cvsroot/rdesktop/rdesktop
In directory sc8-pr-cvs9.sourceforge.net:/tmp/cvs-serv3145

Modified Files:
	rdpsnd_dsp.c rdpsnd_dsp.h rdpsnd_libao.c 
Log Message:
move simple resample algorithm from rdpsnd_libao.c to rdpsnd_dsp.c to
provide a base for a better resample-algorithm


Index: rdpsnd_dsp.c
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/rdpsnd_dsp.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -C2 -d -r1.7 -r1.8
*** rdpsnd_dsp.c	18 Sep 2006 10:20:02 -0000	1.7
--- rdpsnd_dsp.c	1 Oct 2006 12:16:50 -0000	1.8
***************
*** 27,30 ****
--- 27,33 ----
  static uint16 softvol_left = MAX_VOLUME;
  static uint16 softvol_right = MAX_VOLUME;
+ static uint32 resample_to_srate = 44100;
+ static uint16 resample_to_bitspersample = 16;
+ static uint16 resample_to_channels = 2;
  
  void
***************
*** 114,120 ****
  }
  
  
  STREAM
! rdpsnd_dsp_process(STREAM s, struct audio_driver *current_driver, WAVEFORMATEX * format)
  {
  	static struct stream out;
--- 117,210 ----
  }
  
+ BOOL
+ rdpsnd_dsp_resample_set(uint32 device_srate, uint16 device_bitspersample, uint16 device_channels)
+ {
+ 	if (device_srate != 44100 && device_srate != 22050)
+ 		return False;
+ 
+ 	if (device_bitspersample != 16 && device_bitspersample != 8)
+ 		return False;
+ 
+ 	if (device_channels != 1 && device_channels != 2)
+ 		return False;
+ 
+ 	resample_to_srate = device_srate;
+ 	resample_to_bitspersample = device_bitspersample;
+ 	resample_to_channels = device_channels;
+ 
+ 	return True;
+ }
+ 
+ BOOL
+ rdpsnd_dsp_resample_supported(WAVEFORMATEX * format)
+ {
+ 	if (format->wFormatTag != WAVE_FORMAT_PCM)
+ 		return False;
+ 	if ((format->nChannels != 1) && (format->nChannels != 2))
+ 		return False;
+ 	if ((format->wBitsPerSample != 8) && (format->wBitsPerSample != 16))
+ 		return False;
+ 	if ((format->nSamplesPerSec != 44100) && (format->nSamplesPerSec != 22050))
+ 		return False;
+ 
+ 	return True;
+ }
+ 
+ uint32
+ rdpsnd_dsp_resample(unsigned char **out, unsigned char *in, unsigned int size,
+ 		    WAVEFORMATEX * format)
+ {
+ 	static BOOL warned = False;
+ 	int outsize, offset;
+ 	int samplewidth = format->wBitsPerSample / 8;
+ 	int i;
+ 
+ 	if ((resample_to_bitspersample != format->wBitsPerSample) ||
+ 	    (resample_to_channels != format->nChannels) ||
+ 	    ((format->nSamplesPerSec != 44100) && (format->nSamplesPerSec != 22050)))
+ 	{
+ 		if (!warned)
+ 		{
+ 			warning("unsupported resample-settings (%u/%u/%u), not resampling!\n",
+ 				format->nSamplesPerSec, format->wBitsPerSample, format->nChannels);
+ 			warned = True;
+ 		}
+ 		return 0;
+ 	}
+ 
+ 	if (format->nSamplesPerSec == 22050)
+ 	{
+ 		outsize = size * 2;
+ 		*out = xmalloc(outsize);
+ 
+ 		/* Resample to 44100 */
+ 		for (i = 0; i < (size / samplewidth); i++)
+ 		{
+ 			/* On a stereo-channel we must make sure that left and right
+ 			   does not get mixed up, so we need to expand the sample-
+ 			   data with channels in mind: 1234 -> 12123434
+ 			   If we have a mono-channel, we can expand the data by simply
+ 			   doubling the sample-data: 1234 -> 11223344 */
+ 			if (resample_to_channels == 2)
+ 				offset = ((i * 2) - (i & 1)) * samplewidth;
+ 			else
+ 				offset = (i * 2) * samplewidth;
+ 
+ 			memcpy(*out + offset, in + (i * samplewidth), samplewidth);
+ 			memcpy(*out + (resample_to_channels * samplewidth + offset),
+ 			       in + (i * samplewidth), samplewidth);
+ 
+ 		}
+ 	}
+ 	else
+ 	{
+ 		outsize = 0;
+ 	}
+ 
+ 	return outsize;
+ }
  
  STREAM
! rdpsnd_dsp_process(STREAM s, struct audio_driver * current_driver, WAVEFORMATEX * format)
  {
  	static struct stream out;
***************
*** 130,138 ****
  #endif
  
! 	out.data = xmalloc(s->size);
  
! 	memcpy(out.data, s->data, s->size);
  
- 	out.size = s->size;
  	out.p = out.data;
  	out.end = out.p + out.size;
--- 220,237 ----
  #endif
  
! 	out.data = NULL;
  
! 	if (current_driver->wave_out_format_supported == rdpsnd_dsp_resample_supported)
! 	{
! 		out.size = rdpsnd_dsp_resample(&out.data, s->data, s->size, format);
! 	}
! 
! 	if (out.data == NULL)
! 	{
! 		out.data = xmalloc(s->size);
! 		memcpy(out.data, s->data, s->size);
! 		out.size = s->size;
! 	}
  
  	out.p = out.data;
  	out.end = out.p + out.size;

Index: rdpsnd_dsp.h
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/rdpsnd_dsp.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** rdpsnd_dsp.h	17 Sep 2006 18:08:51 -0000	1.2
--- rdpsnd_dsp.h	1 Oct 2006 12:16:50 -0000	1.3
***************
*** 19,23 ****
--- 19,29 ----
  */
  
+ /* Software volume control */
  void rdpsnd_dsp_softvol_set(uint16 left, uint16 right);
  
+ /* Resample control */
+ BOOL rdpsnd_dsp_resample_set(uint32 device_srate, uint16 device_bitspersample,
+ 			     uint16 device_channels);
+ BOOL rdpsnd_dsp_resample_supported(WAVEFORMATEX * pwfx);
+ 
  STREAM rdpsnd_dsp_process(STREAM s, struct audio_driver *current_driver, WAVEFORMATEX * format);

Index: rdpsnd_libao.c
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/rdpsnd_libao.c,v
retrieving revision 1.22
retrieving revision 1.23
diff -C2 -d -r1.22 -r1.23
*** rdpsnd_libao.c	18 Sep 2006 09:34:34 -0000	1.22
--- rdpsnd_libao.c	1 Oct 2006 12:16:50 -0000	1.23
***************
*** 34,41 ****
  static ao_device *o_device = NULL;
  static int default_driver;
- static int samplerate;
- static int audiochannels;
  static BOOL reopened;
- static short samplewidth;
  static char *libao_device = NULL;
  
--- 34,38 ----
***************
*** 58,64 ****
  	format.bits = 16;
  	format.channels = 2;
- 	audiochannels = 2;
  	format.rate = 44100;
- 	samplerate = 44100;
  	format.byte_format = AO_FMT_LITTLE;
  
--- 55,59 ----
***************
*** 95,115 ****
  
  BOOL
- libao_format_supported(WAVEFORMATEX * pwfx)
- {
- 	if (pwfx->wFormatTag != WAVE_FORMAT_PCM)
- 		return False;
- 	if ((pwfx->nChannels != 1) && (pwfx->nChannels != 2))
- 		return False;
- 	if ((pwfx->wBitsPerSample != 8) && (pwfx->wBitsPerSample != 16))
- 		return False;
- 	/* The only common denominator between libao output drivers is a sample-rate of
- 	   44100, we need to upsample 22050 to it */
- 	if ((pwfx->nSamplesPerSec != 44100) && (pwfx->nSamplesPerSec != 22050))
- 		return False;
- 
- 	return True;
- }
- 
- BOOL
  libao_set_format(WAVEFORMATEX * pwfx)
  {
--- 90,93 ----
***************
*** 118,128 ****
  	format.bits = pwfx->wBitsPerSample;
  	format.channels = pwfx->nChannels;
- 	audiochannels = pwfx->nChannels;
  	format.rate = 44100;
- 	samplerate = pwfx->nSamplesPerSec;
  	format.byte_format = AO_FMT_LITTLE;
  
- 	samplewidth = pwfx->wBitsPerSample / 8;
- 
  	if (o_device != NULL)
  		ao_close(o_device);
--- 96,102 ----
***************
*** 134,137 ****
--- 108,116 ----
  	}
  
+ 	if (rdpsnd_dsp_resample_set(44100, pwfx->wBitsPerSample, pwfx->nChannels) == False)
+ 	{
+ 		return False;
+ 	}
+ 
  	reopened = True;
  
***************
*** 144,149 ****
  	struct audio_packet *packet;
  	STREAM out;
! 	char outbuf[WAVEOUTBUF];
! 	int offset, len, i;
  	static long prev_s, prev_us;
  	unsigned int duration;
--- 123,127 ----
  	struct audio_packet *packet;
  	STREAM out;
! 	int len;
  	static long prev_s, prev_us;
  	unsigned int duration;
***************
*** 170,206 ****
  	next_tick = rdpsnd_queue_next_tick();
  
! 	len = 0;
! 
! 	if (samplerate == 22050)
! 	{
! 		/* Resample to 44100 */
! 		for (i = 0; (i < ((WAVEOUTBUF / 4) * (3 - samplewidth))) && (out->p < out->end);
! 		     i++)
! 		{
! 			/* On a stereo-channel we must make sure that left and right
! 			   does not get mixed up, so we need to expand the sample-
! 			   data with channels in mind: 1234 -> 12123434
! 			   If we have a mono-channel, we can expand the data by simply
! 			   doubling the sample-data: 1234 -> 11223344 */
! 			if (audiochannels == 2)
! 				offset = ((i * 2) - (i & 1)) * samplewidth;
! 			else
! 				offset = (i * 2) * samplewidth;
! 
! 			memcpy(&outbuf[offset], out->p, samplewidth);
! 			memcpy(&outbuf[audiochannels * samplewidth + offset], out->p, samplewidth);
! 
! 			out->p += samplewidth;
! 			len += 2 * samplewidth;
! 		}
! 	}
! 	else
! 	{
! 		len = (WAVEOUTBUF > (out->end - out->p)) ? (out->end - out->p) : WAVEOUTBUF;
! 		memcpy(outbuf, out->p, len);
! 		out->p += len;
! 	}
! 
! 	ao_play(o_device, outbuf, len);
  
  	gettimeofday(&tv, NULL);
--- 148,154 ----
  	next_tick = rdpsnd_queue_next_tick();
  
! 	len = (WAVEOUTBUF > (out->end - out->p)) ? (out->end - out->p) : WAVEOUTBUF;
! 	ao_play(o_device, (char *) out->p, len);
! 	out->p += len;
  
  	gettimeofday(&tv, NULL);
***************
*** 241,245 ****
  	libao_driver.wave_out_open = libao_open;
  	libao_driver.wave_out_close = libao_close;
! 	libao_driver.wave_out_format_supported = libao_format_supported;
  	libao_driver.wave_out_set_format = libao_set_format;
  	libao_driver.wave_out_volume = rdpsnd_dsp_softvol_set;
--- 189,193 ----
  	libao_driver.wave_out_open = libao_open;
  	libao_driver.wave_out_close = libao_close;
! 	libao_driver.wave_out_format_supported = rdpsnd_dsp_resample_supported;
  	libao_driver.wave_out_set_format = libao_set_format;
  	libao_driver.wave_out_volume = rdpsnd_dsp_softvol_set;
***************
*** 257,261 ****
  	{
  		snprintf(description, 100, "libao output driver, default device: %s",
! 				libao_info->short_name);
  	}
  	else
--- 205,209 ----
  	{
  		snprintf(description, 100, "libao output driver, default device: %s",
! 			 libao_info->short_name);
  	}
  	else


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV