CVS: rdesktop rdpsnd_sgi.c,NONE,1.1 configure.ac,1.3,1.4

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-serv13820

Modified Files:
	configure.ac 
Added Files:
	rdpsnd_sgi.c 
Log Message:
SGI sound support from Jeremy Meng <[email protected]>


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

   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 <errno.h>
#include <dmedia/audio.h>

#define IRIX_DEBUG 1

#define IRIX_MAX_VOL     65535

#define MAX_QUEUE	10

int g_dsp_fd;
ALconfig audioconfig;
ALport output_port;

BOOL g_dsp_busy = False;
static BOOL g_swapaudio;
static int g_snd_rate;
static BOOL g_swapaudio;
static short g_samplewidth;
static int width = AL_SAMPLE_16;

double min_volume, max_volume, volume_range;
int resource, maxFillable;
int combinedFrameSize;

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)
{
  ALparamInfo pinfo;

#if (defined(IRIX_DEBUG))
    fprintf(stderr, "wave_out_open: begin\n");
#endif

  if ( alGetParamInfo(AL_DEFAULT_OUTPUT, AL_GAIN, &pinfo) < 0 )
  {
    fprintf(stderr, "wave_out_open: alGetParamInfo failed: %s\n", 
						alGetErrorString(oserror()));
  }
  min_volume = alFixedToDouble(pinfo.min.ll);
  max_volume = alFixedToDouble(pinfo.max.ll);
  volume_range = (max_volume - min_volume);
#if (defined(IRIX_DEBUG))
		fprintf(stderr, "wave_out_open: minvol = %lf, maxvol= %lf, range = %lf.\n",
						min_volume, max_volume, volume_range);
#endif

	queue_lo = queue_hi = 0;

	audioconfig = alNewConfig();
	if (audioconfig < 0) {
    fprintf(stderr, "wave_out_open: alNewConfig failed: %s\n",
            alGetErrorString(oserror()));
		return False;
	}

	output_port = alOpenPort("rdpsnd", "w", 0);
	if (output_port == (ALport) 0) {
    fprintf(stderr, "wave_out_open: alOpenPort failed: %s\n", 
						alGetErrorString(oserror()));
		return False;
	}

#if (defined(IRIX_DEBUG))
    fprintf(stderr, "wave_out_open: returning\n");
#endif
	return True;
}

void
wave_out_close(void)
{
	/* Ack all remaining packets */
#if (defined(IRIX_DEBUG))
    fprintf(stderr, "wave_out_close: begin\n");
#endif
	
	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;
	}
	alDiscardFrames(output_port, 0);	
	
	alClosePort(output_port);
	alFreeConfig(audioconfig);
#if (defined(IRIX_DEBUG))
    fprintf(stderr, "wave_out_close: returning\n");
#endif
}

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;

	return True;
}

BOOL
wave_out_set_format(WAVEFORMATEX * pwfx)
{
	int channels;
  int frameSize, channelCount;
  ALpv	params;
	
#if (defined(IRIX_DEBUG))
		fprintf(stderr, "wave_out_set_format: init...\n");
#endif
	/* limited support to configure an opened audio port in IRIX */
	/* have to reopen the audio port, using same config */
	alClosePort(output_port);

	g_swapaudio = False;

	if (pwfx->wBitsPerSample == 8)
		width = AL_SAMPLE_8;
	else if (pwfx->wBitsPerSample == 16) {
		width = AL_SAMPLE_16;
		/* Do we need to swap the 16bit values? (Are we BigEndian) */
#if (defined(IRIX_DEBUG))
		g_swapaudio = 1;
#else
		g_swapaudio = 0;
#endif
	}

	g_samplewidth = pwfx->wBitsPerSample / 8;
	channels = pwfx->nChannels;
	g_snd_rate = pwfx->nSamplesPerSec;

	alSetSampFmt(audioconfig, AL_SAMPFMT_TWOSCOMP);
	alSetWidth(audioconfig, width);
	alSetChannels(audioconfig, channels);

	output_port = alOpenPort("rdpsnd", "w", audioconfig);

	if (output_port == (ALport) 0) { 
    fprintf(stderr, "wave_out_set_format: alOpenPort failed: %s\n",
            alGetErrorString(oserror()));
		return False;
	}

	resource = alGetResource(output_port);
	maxFillable = alGetFillable(output_port);
  channelCount = alGetChannels(audioconfig);
  frameSize = alGetWidth(audioconfig);

  if (frameSize == 0 || channelCount == 0)
  {
    fprintf(stderr, "wave_out_set_format: bad frameSize or channelCount\n");
    return False;
  }
  combinedFrameSize = frameSize * channelCount;

  params.param = AL_RATE;
  params.value.ll = (long long) g_snd_rate << 32;

  if (alSetParams(resource, &params, 1) < 0)
  {
    fprintf(stderr, "wave_set_format: alSetParams failed: %s\n", 
						alGetErrorString(oserror()));
    return False;
  }
  if( params.sizeOut < 0 )
  {
    fprintf(stderr, "wave_set_format: invalid rate %d\n", g_snd_rate);
    return False;
  }

#if (defined(IRIX_DEBUG))
		fprintf(stderr, "wave_out_set_format: returning...\n");
#endif
	return True;
}

void
wave_out_volume(uint16 left, uint16 right)
{
  double gainleft, gainright;
  ALpv pv[1];
  ALfixed gain[8];

#if (defined(IRIX_DEBUG))
    fprintf(stderr, "wave_out_volume: begin\n");
    fprintf(stderr, "left='%d', right='%d'\n", left, right);
#endif
	
	gainleft =  (double)  left / IRIX_MAX_VOL;
	gainright = (double) right / IRIX_MAX_VOL;

  gain[0] = alDoubleToFixed(min_volume + gainleft  * volume_range);
  gain[1] = alDoubleToFixed(min_volume + gainright * volume_range);

  pv[0].param = AL_GAIN;
  pv[0].value.ptr = gain;
  pv[0].sizeIn = 8;
  if( alSetParams(AL_DEFAULT_OUTPUT, pv, 1) < 0)
  {
    fprintf(stderr, "wave_out_volume: alSetParams failed: %s\n", alGetErrorString(oserror()));
    return;
  }

#if (defined(IRIX_DEBUG))
    fprintf(stderr, "wave_out_volume: returning\n");
#endif
}

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)
	{
		fprintf(stderr, "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;
	ssize_t len;
	unsigned int i;
	uint8 swap;
	STREAM out;
	static long startedat_us;
	static long startedat_s;
	static BOOL started = False;
	static BOOL swapped = False;
	struct timeval tv;
	int gf;
	static long long temp;

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

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

		/* Swap the current packet, but only once */
		if (g_swapaudio && !swapped)
		{
			for (i = 0; i < out->end - out->p; i += 2)
			{
				swap = *(out->p + i);
				*(out->p + i) = *(out->p + i + 1);
				*(out->p + i + 1) = swap;
			}
			swapped = True;
		}

		if (!started)
		{
			gettimeofday(&tv, NULL);
			startedat_us = tv.tv_usec;
			startedat_s = tv.tv_sec;
			started = True;
		}

		len = out->end - out->p;
		gf = alGetFillable(output_port);		
		if (len > gf) {
			//len = gf * combinedFrameSize;
#if (defined(IRIX_DEBUG))
			//fprintf(stderr,"Fillable...\n");
#endif
		}

		alWriteFrames(output_port, out->p, len/combinedFrameSize);

		out->p += len;
		if (out->p == out->end)
		{
			long long duration;
			long elapsed;

			gettimeofday(&tv, NULL);
			duration = (out->size * (1000000 / (g_samplewidth * g_snd_rate)));
			elapsed =  (tv.tv_sec - startedat_s) * 1000000 
				       + (tv.tv_usec - startedat_us);
			/* 7/10 is not good for IRIX audio port, 4x/100 is suitable */
			if (elapsed >= (duration * 485) / 1000)
			{
				rdpsnd_send_completion(packet->tick, packet->index);
				free(out->data);
				queue_lo = (queue_lo + 1) % MAX_QUEUE;
				started = False;
				swapped = False;
			}
			else
			{
#if (defined(IRIX_DEBUG))
				//fprintf(stderr,"Busy playing...\n");
#endif
				g_dsp_busy = True;
				return;
			}
		}
	}
}

Index: configure.ac
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/configure.ac,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** configure.ac	8 Aug 2004 11:17:12 -0000	1.3
--- configure.ac	9 Aug 2004 11:39:49 -0000	1.4
***************
*** 133,137 ****
  sound="yes"
  AC_ARG_WITH(sound,
!     [  --with-sound            select sound system ("oss" or "sun") ],
      [ 
      sound="$withval" 
--- 133,137 ----
  sound="yes"
  AC_ARG_WITH(sound,
!     [  --with-sound            select sound system ("oss", "sgi" or "sun") ],
      [ 
      sound="$withval" 
***************
*** 139,142 ****
--- 139,143 ----
  if test "$sound" = yes; then
      AC_CHECK_HEADER(sys/soundcard.h, [sound=oss])
+     AC_CHECK_HEADER(dmedia/audio.h, [sound=sgi])
      AC_CHECK_HEADER(sys/audioio.h, [sound=sun])
  fi
***************
*** 146,149 ****
--- 147,154 ----
      SOUNDOBJ="rdpsnd.o rdpsnd_oss.o"
      AC_DEFINE(WITH_RDPSND)
+ elif test "$sound" = sgi; then
+     SOUNDOBJ="rdpsnd.o rdpsnd_sgi.o"
+     LDFLAGS="$LDFLAGS -laudio"
+     AC_DEFINE(WITH_RDPSND)
  elif test "$sound" = sun; then
      SOUNDOBJ="rdpsnd.o rdpsnd_sun.o"
***************
*** 151,155 ****
  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) and Sun/BSD (sun)])
  fi
  AC_SUBST(SOUNDOBJ)
--- 156,160 ----
  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)
***************
*** 274,277 ****
--- 279,286 ----
      CFLAGS="$CFLAGS -D_XOPEN_SOURCE_EXTENDED"
      ;;
+ *-*-irix6.5*)
+     LIBS="$LIBS -L$ssldir/lib32 -lcrypto"
+     CFLAGS="$CFLAGS -D__SGI_IRIX__"
+     ;;
  esac
  



-------------------------------------------------------
This SF.Net email is sponsored by OSTG. Have you noticed the changes on
Linux.com, ITManagersJournal and NewsForge in the past few weeks? Now,
one more big change to announce. We are now OSTG- Open Source Technology
Group. Come see the changes on the new OSTG site. www.ostg.com
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.