a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* -*- c-basic-offset: 8 -*-
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdesktop: A Remote Desktop Protocol client.
a180a41bba1d50822df23fff0099e90b86638b89vboxsync Sound Channel Process Functions - SGI/IRIX
a180a41bba1d50822df23fff0099e90b86638b89vboxsync Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 2003-2008
a180a41bba1d50822df23fff0099e90b86638b89vboxsync Copyright (C) GuoJunBo <guojunbo@ict.ac.cn> 2003
a180a41bba1d50822df23fff0099e90b86638b89vboxsync Copyright (C) Jeremy Meng <void.foo@gmail.com> 2004-2005
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync This program is free software: you can redistribute it and/or modify
a180a41bba1d50822df23fff0099e90b86638b89vboxsync it under the terms of the GNU General Public License as published by
a180a41bba1d50822df23fff0099e90b86638b89vboxsync the Free Software Foundation, either version 3 of the License, or
a180a41bba1d50822df23fff0099e90b86638b89vboxsync (at your option) any later version.
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync This program is distributed in the hope that it will be useful,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync but WITHOUT ANY WARRANTY; without even the implied warranty of
a180a41bba1d50822df23fff0099e90b86638b89vboxsync MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
a180a41bba1d50822df23fff0099e90b86638b89vboxsync GNU General Public License for more details.
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync You should have received a copy of the GNU General Public License
a180a41bba1d50822df23fff0099e90b86638b89vboxsync along with this program. If not, see <http://www.gnu.org/licenses/>.
a180a41bba1d50822df23fff0099e90b86638b89vboxsync*/
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
6e9aa255e3376b2da5824c09c4c62bc233463bfevboxsync/*
6e9aa255e3376b2da5824c09c4c62bc233463bfevboxsync * Oracle GPL Disclaimer: For the avoidance of doubt, except that if any license choice
6e9aa255e3376b2da5824c09c4c62bc233463bfevboxsync * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
6e9aa255e3376b2da5824c09c4c62bc233463bfevboxsync * the General Public License version 2 (GPLv2) at this time for any software where
6e9aa255e3376b2da5824c09c4c62bc233463bfevboxsync * a choice of GPL license versions is made available with the language indicating
6e9aa255e3376b2da5824c09c4c62bc233463bfevboxsync * that GPLv2 or any later version may be used, or where a choice of which version
6e9aa255e3376b2da5824c09c4c62bc233463bfevboxsync * of the GPL is applied is otherwise unspecified.
6e9aa255e3376b2da5824c09c4c62bc233463bfevboxsync */
6e9aa255e3376b2da5824c09c4c62bc233463bfevboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#include "rdesktop.h"
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#include <errno.h>
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#include <dmedia/audio.h>
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* #define IRIX_DEBUG 1 */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#define IRIX_MAX_VOL 65535
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncALconfig audioconfig;
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncALport output_port;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncstatic int g_snd_rate;
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncstatic int width = AL_SAMPLE_16;
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncstatic char *sgi_output_device = NULL;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncdouble min_volume, max_volume, volume_range;
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncint resource, maxFillable;
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncint combinedFrameSize;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncvoid sgi_play(void);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncvoid
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncsgi_add_fds(int *n, fd_set * rfds, fd_set * wfds, struct timeval *tv)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync{
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* We need to be called rather often... */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (output_port != (ALport) 0 && !rdpsnd_queue_empty())
a180a41bba1d50822df23fff0099e90b86638b89vboxsync FD_SET(0, wfds);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync}
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncvoid
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncsgi_check_fds(fd_set * rfds, fd_set * wfds)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync{
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (output_port == (ALport) 0)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (!rdpsnd_queue_empty())
a180a41bba1d50822df23fff0099e90b86638b89vboxsync sgi_play();
a180a41bba1d50822df23fff0099e90b86638b89vboxsync}
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncRD_BOOL
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncsgi_open(void)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync{
a180a41bba1d50822df23fff0099e90b86638b89vboxsync ALparamInfo pinfo;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync static int warned = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#if (defined(IRIX_DEBUG))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync fprintf(stderr, "sgi_open: begin\n");
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#endif
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (!warned && sgi_output_device)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync warning("device-options not supported for libao-driver\n");
a180a41bba1d50822df23fff0099e90b86638b89vboxsync warned = 1;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (alGetParamInfo(AL_DEFAULT_OUTPUT, AL_GAIN, &pinfo) < 0)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync fprintf(stderr, "sgi_open: alGetParamInfo failed: %s\n",
a180a41bba1d50822df23fff0099e90b86638b89vboxsync alGetErrorString(oserror()));
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync min_volume = alFixedToDouble(pinfo.min.ll);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync max_volume = alFixedToDouble(pinfo.max.ll);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync volume_range = (max_volume - min_volume);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#if (defined(IRIX_DEBUG))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync fprintf(stderr, "sgi_open: minvol = %lf, maxvol= %lf, range = %lf.\n",
a180a41bba1d50822df23fff0099e90b86638b89vboxsync min_volume, max_volume, volume_range);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#endif
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync audioconfig = alNewConfig();
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (audioconfig == (ALconfig) 0)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync fprintf(stderr, "sgi_open: alNewConfig failed: %s\n", alGetErrorString(oserror()));
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return False;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync output_port = alOpenPort("rdpsnd", "w", 0);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (output_port == (ALport) 0)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync fprintf(stderr, "sgi_open: alOpenPort failed: %s\n", alGetErrorString(oserror()));
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return False;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#if (defined(IRIX_DEBUG))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync fprintf(stderr, "sgi_open: returning\n");
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#endif
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return True;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync}
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncvoid
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncsgi_close(void)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync{
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* Ack all remaining packets */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#if (defined(IRIX_DEBUG))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync fprintf(stderr, "sgi_close: begin\n");
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#endif
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync while (!rdpsnd_queue_empty())
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdpsnd_queue_next(0);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync alDiscardFrames(output_port, 0);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync alClosePort(output_port);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync output_port = (ALport) 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync alFreeConfig(audioconfig);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#if (defined(IRIX_DEBUG))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync fprintf(stderr, "sgi_close: returning\n");
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#endif
a180a41bba1d50822df23fff0099e90b86638b89vboxsync}
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncRD_BOOL
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncsgi_format_supported(RD_WAVEFORMATEX * pwfx)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync{
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (pwfx->wFormatTag != WAVE_FORMAT_PCM)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return False;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if ((pwfx->nChannels != 1) && (pwfx->nChannels != 2))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return False;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if ((pwfx->wBitsPerSample != 8) && (pwfx->wBitsPerSample != 16))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return False;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return True;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync}
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncRD_BOOL
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncsgi_set_format(RD_WAVEFORMATEX * pwfx)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync{
a180a41bba1d50822df23fff0099e90b86638b89vboxsync int channels;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync int frameSize, channelCount;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync ALpv params;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#if (defined(IRIX_DEBUG))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync fprintf(stderr, "sgi_set_format: init...\n");
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#endif
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (pwfx->wBitsPerSample == 8)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync width = AL_SAMPLE_8;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync else if (pwfx->wBitsPerSample == 16)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync width = AL_SAMPLE_16;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* Limited support to configure an opened audio port in IRIX. The
a180a41bba1d50822df23fff0099e90b86638b89vboxsync number of channels is a static setting and can not be changed after
a180a41bba1d50822df23fff0099e90b86638b89vboxsync a port is opened. So if the number of channels remains the same, we
a180a41bba1d50822df23fff0099e90b86638b89vboxsync can configure other settings; otherwise we have to reopen the audio
a180a41bba1d50822df23fff0099e90b86638b89vboxsync port, using same config. */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync channels = pwfx->nChannels;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync g_snd_rate = pwfx->nSamplesPerSec;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync alSetSampFmt(audioconfig, AL_SAMPFMT_TWOSCOMP);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync alSetWidth(audioconfig, width);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (channels != alGetChannels(audioconfig))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync alClosePort(output_port);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync alSetChannels(audioconfig, channels);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync output_port = alOpenPort("rdpsnd", "w", audioconfig);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (output_port == (ALport) 0)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync fprintf(stderr, "sgi_set_format: alOpenPort failed: %s\n",
a180a41bba1d50822df23fff0099e90b86638b89vboxsync alGetErrorString(oserror()));
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return False;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync resource = alGetResource(output_port);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync maxFillable = alGetFillable(output_port);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync channelCount = alGetChannels(audioconfig);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync frameSize = alGetWidth(audioconfig);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (frameSize == 0 || channelCount == 0)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync fprintf(stderr, "sgi_set_format: bad frameSize or channelCount\n");
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return False;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync combinedFrameSize = frameSize * channelCount;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync params.param = AL_RATE;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync params.value.ll = (long long) g_snd_rate << 32;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (alSetParams(resource, &params, 1) < 0)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync fprintf(stderr, "wave_set_format: alSetParams failed: %s\n",
a180a41bba1d50822df23fff0099e90b86638b89vboxsync alGetErrorString(oserror()));
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return False;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (params.sizeOut < 0)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync fprintf(stderr, "wave_set_format: invalid rate %d\n", g_snd_rate);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return False;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#if (defined(IRIX_DEBUG))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync fprintf(stderr, "sgi_set_format: returning...\n");
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#endif
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return True;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync}
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncvoid
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncsgi_volume(uint16 left, uint16 right)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync{
a180a41bba1d50822df23fff0099e90b86638b89vboxsync double gainleft, gainright;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync ALpv pv[1];
a180a41bba1d50822df23fff0099e90b86638b89vboxsync ALfixed gain[8];
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#if (defined(IRIX_DEBUG))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync fprintf(stderr, "sgi_volume: begin\n");
a180a41bba1d50822df23fff0099e90b86638b89vboxsync fprintf(stderr, "left='%d', right='%d'\n", left, right);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#endif
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync gainleft = (double) left / IRIX_MAX_VOL;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync gainright = (double) right / IRIX_MAX_VOL;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync gain[0] = alDoubleToFixed(min_volume + gainleft * volume_range);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync gain[1] = alDoubleToFixed(min_volume + gainright * volume_range);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync pv[0].param = AL_GAIN;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync pv[0].value.ptr = gain;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync pv[0].sizeIn = 8;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (alSetParams(AL_DEFAULT_OUTPUT, pv, 1) < 0)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync fprintf(stderr, "sgi_volume: alSetParams failed: %s\n",
a180a41bba1d50822df23fff0099e90b86638b89vboxsync alGetErrorString(oserror()));
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#if (defined(IRIX_DEBUG))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync fprintf(stderr, "sgi_volume: returning\n");
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#endif
a180a41bba1d50822df23fff0099e90b86638b89vboxsync}
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncvoid
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncsgi_play(void)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync{
a180a41bba1d50822df23fff0099e90b86638b89vboxsync struct audio_packet *packet;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync ssize_t len;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync unsigned int i;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync STREAM out;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync int gf;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync while (1)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (rdpsnd_queue_empty())
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync packet = rdpsnd_queue_current_packet();
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out = &packet->s;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync len = out->end - out->p;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync alWriteFrames(output_port, out->p, len / combinedFrameSize);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out->p += len;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (out->p == out->end)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync gf = alGetFilled(output_port);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (gf < (4 * maxFillable / 10))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdpsnd_queue_next(0);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync else
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#if (defined(IRIX_DEBUG))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* fprintf(stderr,"Busy playing...\n"); */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#endif
a180a41bba1d50822df23fff0099e90b86638b89vboxsync usleep(10);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync}
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncstruct audio_driver *
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncsgi_register(char *options)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync{
a180a41bba1d50822df23fff0099e90b86638b89vboxsync static struct audio_driver sgi_driver;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync memset(&sgi_driver, 0, sizeof(sgi_driver));
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync sgi_driver.name = "sgi";
a180a41bba1d50822df23fff0099e90b86638b89vboxsync sgi_driver.description = "SGI output driver";
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync sgi_driver.add_fds = sgi_add_fds;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync sgi_driver.check_fds = sgi_check_fds;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync sgi_driver.wave_out_open = sgi_open;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync sgi_driver.wave_out_close = sgi_close;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync sgi_driver.wave_out_format_supported = sgi_format_supported;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync sgi_driver.wave_out_set_format = sgi_set_format;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync sgi_driver.wave_out_volume = sgi_volume;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync sgi_driver.need_byteswap_on_be = 1;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync sgi_driver.need_resampling = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (options)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync {
a180a41bba1d50822df23fff0099e90b86638b89vboxsync sgi_output_device = xstrdup(options);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync }
a180a41bba1d50822df23fff0099e90b86638b89vboxsync return &sgi_driver;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync}