VirtualBox

source: vbox/trunk/src/VBox/RDP/client/rdpsnd_sgi.c@ 21395

Last change on this file since 21395 was 11982, checked in by vboxsync, 16 years ago

All: license header changes for 2.0 (OSE headers, add Sun GPL/LGPL disclaimer)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.8 KB
Line 
1/* -*- c-basic-offset: 8 -*-
2 rdesktop: A Remote Desktop Protocol client.
3 Sound Channel Process Functions - SGI/IRIX
4 Copyright (C) Matthew Chapman 2003-2007
5 Copyright (C) GuoJunBo guojunbo@ict.ac.cn 2003
6 Copyright (C) Jeremy Meng void.foo@gmail.com 2004, 2005
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21*/
22
23/*
24 * Sun GPL Disclaimer: For the avoidance of doubt, except that if any license choice
25 * other than GPL or LGPL is available it will apply instead, Sun elects to use only
26 * the General Public License version 2 (GPLv2) at this time for any software where
27 * a choice of GPL license versions is made available with the language indicating
28 * that GPLv2 or any later version may be used, or where a choice of which version
29 * of the GPL is applied is otherwise unspecified.
30 */
31
32#include "rdesktop.h"
33#include <errno.h>
34#include <dmedia/audio.h>
35
36/* #define IRIX_DEBUG 1 */
37
38#define IRIX_MAX_VOL 65535
39
40ALconfig audioconfig;
41ALport output_port;
42
43static int g_snd_rate;
44static int width = AL_SAMPLE_16;
45static char *sgi_output_device = NULL;
46
47double min_volume, max_volume, volume_range;
48int resource, maxFillable;
49int combinedFrameSize;
50
51void sgi_play(void);
52
53void
54sgi_add_fds(int *n, fd_set * rfds, fd_set * wfds, struct timeval *tv)
55{
56 /* We need to be called rather often... */
57 if (output_port != (ALport) 0 && !rdpsnd_queue_empty())
58 FD_SET(0, wfds);
59}
60
61void
62sgi_check_fds(fd_set * rfds, fd_set * wfds)
63{
64 if (output_port == (ALport) 0)
65 return;
66
67 if (!rdpsnd_queue_empty())
68 sgi_play();
69}
70
71RD_BOOL
72sgi_open(void)
73{
74 ALparamInfo pinfo;
75 static int warned = 0;
76
77#if (defined(IRIX_DEBUG))
78 fprintf(stderr, "sgi_open: begin\n");
79#endif
80
81 if (!warned && sgi_output_device)
82 {
83 warning("device-options not supported for libao-driver\n");
84 warned = 1;
85 }
86
87 if (alGetParamInfo(AL_DEFAULT_OUTPUT, AL_GAIN, &pinfo) < 0)
88 {
89 fprintf(stderr, "sgi_open: alGetParamInfo failed: %s\n",
90 alGetErrorString(oserror()));
91 }
92 min_volume = alFixedToDouble(pinfo.min.ll);
93 max_volume = alFixedToDouble(pinfo.max.ll);
94 volume_range = (max_volume - min_volume);
95#if (defined(IRIX_DEBUG))
96 fprintf(stderr, "sgi_open: minvol = %lf, maxvol= %lf, range = %lf.\n",
97 min_volume, max_volume, volume_range);
98#endif
99
100 audioconfig = alNewConfig();
101 if (audioconfig == (ALconfig) 0)
102 {
103 fprintf(stderr, "sgi_open: alNewConfig failed: %s\n", alGetErrorString(oserror()));
104 return False;
105 }
106
107 output_port = alOpenPort("rdpsnd", "w", 0);
108 if (output_port == (ALport) 0)
109 {
110 fprintf(stderr, "sgi_open: alOpenPort failed: %s\n", alGetErrorString(oserror()));
111 return False;
112 }
113
114#if (defined(IRIX_DEBUG))
115 fprintf(stderr, "sgi_open: returning\n");
116#endif
117 return True;
118}
119
120void
121sgi_close(void)
122{
123 /* Ack all remaining packets */
124#if (defined(IRIX_DEBUG))
125 fprintf(stderr, "sgi_close: begin\n");
126#endif
127
128 while (!rdpsnd_queue_empty())
129 rdpsnd_queue_next(0);
130 alDiscardFrames(output_port, 0);
131
132 alClosePort(output_port);
133 output_port = (ALport) 0;
134 alFreeConfig(audioconfig);
135#if (defined(IRIX_DEBUG))
136 fprintf(stderr, "sgi_close: returning\n");
137#endif
138}
139
140RD_BOOL
141sgi_format_supported(RD_WAVEFORMATEX * pwfx)
142{
143 if (pwfx->wFormatTag != WAVE_FORMAT_PCM)
144 return False;
145 if ((pwfx->nChannels != 1) && (pwfx->nChannels != 2))
146 return False;
147 if ((pwfx->wBitsPerSample != 8) && (pwfx->wBitsPerSample != 16))
148 return False;
149
150 return True;
151}
152
153RD_BOOL
154sgi_set_format(RD_WAVEFORMATEX * pwfx)
155{
156 int channels;
157 int frameSize, channelCount;
158 ALpv params;
159
160#if (defined(IRIX_DEBUG))
161 fprintf(stderr, "sgi_set_format: init...\n");
162#endif
163
164 if (pwfx->wBitsPerSample == 8)
165 width = AL_SAMPLE_8;
166 else if (pwfx->wBitsPerSample == 16)
167 width = AL_SAMPLE_16;
168
169 /* Limited support to configure an opened audio port in IRIX. The
170 number of channels is a static setting and can not be changed after
171 a port is opened. So if the number of channels remains the same, we
172 can configure other settings; otherwise we have to reopen the audio
173 port, using same config. */
174
175 channels = pwfx->nChannels;
176 g_snd_rate = pwfx->nSamplesPerSec;
177
178 alSetSampFmt(audioconfig, AL_SAMPFMT_TWOSCOMP);
179 alSetWidth(audioconfig, width);
180 if (channels != alGetChannels(audioconfig))
181 {
182 alClosePort(output_port);
183 alSetChannels(audioconfig, channels);
184 output_port = alOpenPort("rdpsnd", "w", audioconfig);
185
186 if (output_port == (ALport) 0)
187 {
188 fprintf(stderr, "sgi_set_format: alOpenPort failed: %s\n",
189 alGetErrorString(oserror()));
190 return False;
191 }
192
193 }
194
195 resource = alGetResource(output_port);
196 maxFillable = alGetFillable(output_port);
197 channelCount = alGetChannels(audioconfig);
198 frameSize = alGetWidth(audioconfig);
199
200 if (frameSize == 0 || channelCount == 0)
201 {
202 fprintf(stderr, "sgi_set_format: bad frameSize or channelCount\n");
203 return False;
204 }
205 combinedFrameSize = frameSize * channelCount;
206
207 params.param = AL_RATE;
208 params.value.ll = (long long) g_snd_rate << 32;
209
210 if (alSetParams(resource, &params, 1) < 0)
211 {
212 fprintf(stderr, "wave_set_format: alSetParams failed: %s\n",
213 alGetErrorString(oserror()));
214 return False;
215 }
216 if (params.sizeOut < 0)
217 {
218 fprintf(stderr, "wave_set_format: invalid rate %d\n", g_snd_rate);
219 return False;
220 }
221
222#if (defined(IRIX_DEBUG))
223 fprintf(stderr, "sgi_set_format: returning...\n");
224#endif
225 return True;
226}
227
228void
229sgi_volume(uint16 left, uint16 right)
230{
231 double gainleft, gainright;
232 ALpv pv[1];
233 ALfixed gain[8];
234
235#if (defined(IRIX_DEBUG))
236 fprintf(stderr, "sgi_volume: begin\n");
237 fprintf(stderr, "left='%d', right='%d'\n", left, right);
238#endif
239
240 gainleft = (double) left / IRIX_MAX_VOL;
241 gainright = (double) right / IRIX_MAX_VOL;
242
243 gain[0] = alDoubleToFixed(min_volume + gainleft * volume_range);
244 gain[1] = alDoubleToFixed(min_volume + gainright * volume_range);
245
246 pv[0].param = AL_GAIN;
247 pv[0].value.ptr = gain;
248 pv[0].sizeIn = 8;
249 if (alSetParams(AL_DEFAULT_OUTPUT, pv, 1) < 0)
250 {
251 fprintf(stderr, "sgi_volume: alSetParams failed: %s\n",
252 alGetErrorString(oserror()));
253 return;
254 }
255
256#if (defined(IRIX_DEBUG))
257 fprintf(stderr, "sgi_volume: returning\n");
258#endif
259}
260
261void
262sgi_play(void)
263{
264 struct audio_packet *packet;
265 ssize_t len;
266 unsigned int i;
267 STREAM out;
268 int gf;
269
270 while (1)
271 {
272 if (rdpsnd_queue_empty())
273 return;
274
275 packet = rdpsnd_queue_current_packet();
276 out = &packet->s;
277
278 len = out->end - out->p;
279
280 alWriteFrames(output_port, out->p, len / combinedFrameSize);
281
282 out->p += len;
283 if (out->p == out->end)
284 {
285 gf = alGetFilled(output_port);
286 if (gf < (4 * maxFillable / 10))
287 {
288 rdpsnd_queue_next(0);
289 }
290 else
291 {
292#if (defined(IRIX_DEBUG))
293/* fprintf(stderr,"Busy playing...\n"); */
294#endif
295 usleep(10);
296 return;
297 }
298 }
299 }
300}
301
302struct audio_driver *
303sgi_register(char *options)
304{
305 static struct audio_driver sgi_driver;
306
307 memset(&sgi_driver, 0, sizeof(sgi_driver));
308
309 sgi_driver.name = "sgi";
310 sgi_driver.description = "SGI output driver";
311
312 sgi_driver.add_fds = sgi_add_fds;
313 sgi_driver.check_fds = sgi_check_fds;
314
315 sgi_driver.wave_out_open = sgi_open;
316 sgi_driver.wave_out_close = sgi_close;
317 sgi_driver.wave_out_format_supported = sgi_format_supported;
318 sgi_driver.wave_out_set_format = sgi_set_format;
319 sgi_driver.wave_out_volume = sgi_volume;
320
321 sgi_driver.need_byteswap_on_be = 1;
322 sgi_driver.need_resampling = 0;
323
324 if (options)
325 {
326 sgi_output_device = xstrdup(options);
327 }
328 return &sgi_driver;
329}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette