CVS: rdesktop rdpsnd_libao.c,NONE,1.1 configure.ac,1.7,1.8

Michael Gernoth <[email protected]>
Newsgroups gmane.network.rdesktop.cvs
Message-ID <[email protected]>
Update of /cvsroot/rdesktop/rdesktop
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20027

Modified Files:
	configure.ac 
Added Files:
	rdpsnd_libao.c 
Log Message:
basic libao output-driver. works on Mac OSX.
no volume control possible


--- NEW FILE: rdpsnd_libao.c ---
/* 
   rdesktop: A Remote Desktop Protocol client.
   Sound Channel Process Functions - libao-driver
   Copyright (C) Matthew Chapman 2003
   Copyright (C) GuoJunBo [email protected] 2003
   Copyright (C) Michael Gernoth [email protected] 2005

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "rdesktop.h"
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <ao/ao.h>

#define MAX_QUEUE	10

int g_dsp_fd;
ao_device *o_device = NULL;
int default_driver;
BOOL g_dsp_busy = False;
static short g_samplewidth;

static struct audio_packet
{
	struct stream s;
	uint16 tick;
	uint8 index;
} packet_queue[MAX_QUEUE];
static unsigned int queue_hi, queue_lo;

BOOL
wave_out_open(void)
{
	ao_sample_format format;

	ao_initialize();
	default_driver = ao_default_driver_id();

	format.bits = 16;
	format.channels = 2;
	format.rate = 44100;
	format.byte_format = AO_FMT_LITTLE;

	o_device = ao_open_live(default_driver, &format, NULL);
	if (o_device == NULL)
	{
		return False;
	}

	g_dsp_fd = 0;
	queue_lo = queue_hi = 0;

	return True;
}

void
wave_out_close(void)
{
	/* Ack all remaining packets */
	while (queue_lo != queue_hi)
	{
		rdpsnd_send_completion(packet_queue[queue_lo].tick, packet_queue[queue_lo].index);
		free(packet_queue[queue_lo].s.data);
		queue_lo = (queue_lo + 1) % MAX_QUEUE;
	}

	if (o_device != NULL)
		ao_close(o_device);
	ao_shutdown();
}

BOOL
wave_out_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, windows gives a max of 22050. we need to upsample that...
	   TODO: support 11025, too */
	if (pwfx->nSamplesPerSec != 22050)
		return False;

	return True;
}

BOOL
wave_out_set_format(WAVEFORMATEX * pwfx)
{
	ao_sample_format format;

	printf("%d\n",pwfx->wBitsPerSample);
	format.bits = pwfx->wBitsPerSample;
	format.channels = pwfx->nChannels;
	format.rate = 44100;
	format.byte_format = AO_FMT_LITTLE;

	g_samplewidth = pwfx->wBitsPerSample / 8;

	if(o_device != NULL)
		ao_close(o_device);

	o_device = ao_open_live(default_driver, &format, NULL);
	if (o_device == NULL)
	{
		return False;
	}


	return True;
}

void
wave_out_volume(uint16 left, uint16 right)
{
}

void
wave_out_write(STREAM s, uint16 tick, uint8 index)
{
	struct audio_packet *packet = &packet_queue[queue_hi];
	unsigned int next_hi = (queue_hi + 1) % MAX_QUEUE;

	if (next_hi == queue_lo)
	{
		error("No space to queue audio packet\n");
		return;
	}

	queue_hi = next_hi;

	packet->s = *s;
	packet->tick = tick;
	packet->index = index;
	packet->s.p += 4;

	/* we steal the data buffer from s, give it a new one */
	s->data = malloc(s->size);

	if (!g_dsp_busy)
		wave_out_play();
}

void
wave_out_play(void)
{
	struct audio_packet *packet;
	STREAM out;
	unsigned char expanded[8];

	while (1)
	{
		if (queue_lo == queue_hi)
		{
			g_dsp_busy = 0;
			return;
		}

		packet = &packet_queue[queue_lo];
		out = &packet->s;

		/* Resample 22050 -> 44100 */
		/* TODO: Do this for 11025, too... */
		memcpy(&expanded[0],out->p,g_samplewidth);
		memcpy(&expanded[2*g_samplewidth],out->p,g_samplewidth);
		out->p += 2;
		memcpy(&expanded[1*g_samplewidth],out->p,g_samplewidth);
		memcpy(&expanded[3*g_samplewidth],out->p,g_samplewidth);
		out->p += 2;

		ao_play(o_device, expanded, g_samplewidth*4);

		if (out->p == out->end)
		{
			rdpsnd_send_completion(packet->tick, packet->index);
			free(out->data);
			queue_lo = (queue_lo + 1) % MAX_QUEUE;
		} else {
			g_dsp_busy = 1;
			return;
		}
	}
}

Index: configure.ac
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/configure.ac,v
retrieving revision 1.7
retrieving revision 1.8
diff -C2 -d -r1.7 -r1.8
*** configure.ac	6 Mar 2005 21:11:04 -0000	1.7
--- configure.ac	8 Mar 2005 03:33:36 -0000	1.8
***************
*** 136,146 ****
  # sound
  #
  sound="yes"
  AC_ARG_WITH(sound,
!     [  --with-sound            select sound system ("oss", "sgi" or "sun") ],
      [ 
      sound="$withval" 
      ])
  if test "$sound" = yes; then
      AC_CHECK_HEADER(sys/soundcard.h, [sound=oss])
      AC_CHECK_HEADER(dmedia/audio.h, [sound=sgi])
--- 136,157 ----
  # sound
  #
+ AC_ARG_WITH(libao,
+     [  --with-libao=DIR        look for libao at DIR/include, DIR/lib],
+     [
+     CFLAGS="$CFLAGS -I$withval/include"
+     CPPFLAGS="$CPPFLAGS -I$withval/include"
+     LIBS="$LIBS -L$withval/lib"
+     rpath="$rpath:$withval/lib"
+     ]
+ )
+ 
  sound="yes"
  AC_ARG_WITH(sound,
!     [  --with-sound            select sound system ("oss", "sgi", "sun" or "libao") ],
      [ 
      sound="$withval" 
      ])
  if test "$sound" = yes; then
+     AC_CHECK_HEADER(ao/ao.h, [sound=libao])
      AC_CHECK_HEADER(sys/soundcard.h, [sound=oss])
      AC_CHECK_HEADER(dmedia/audio.h, [sound=sgi])
***************
*** 159,168 ****
      SOUNDOBJ="rdpsnd.o rdpsnd_sun.o"
      AC_DEFINE(WITH_RDPSND)
  else
!    AC_MSG_WARN([sound support disabled (no sys/soundcard.h or sys/audioio.h)])
!    AC_MSG_WARN([Currently supported systems are Open Sound System (oss), SGI AL (sgi) and Sun/BSD (sun)])
  fi
  AC_SUBST(SOUNDOBJ)
  
  #
  # dirfd
--- 170,185 ----
      SOUNDOBJ="rdpsnd.o rdpsnd_sun.o"
      AC_DEFINE(WITH_RDPSND)
+ elif test "$sound" = libao; then
+     SOUNDOBJ="rdpsnd.o rdpsnd_libao.o"
+     LDFLAGS="$LDFLAGS -lao"
+     AC_DEFINE(WITH_RDPSND)
  else
!    AC_MSG_WARN([sound support disabled])
!    AC_MSG_WARN([Currently supported systems are Open Sound System (oss), SGI AL (sgi), Sun/BSD (sun) and libao])
  fi
  AC_SUBST(SOUNDOBJ)
  
+ AC_MSG_CHECKING([checking for sound support])
+ 
  #
  # dirfd



-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.