VirtualBox

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

Last change on this file since 10753 was 9902, checked in by vboxsync, 17 years ago

Added rdesktop 1.6.0.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.3 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#include "rdesktop.h"
24#include <errno.h>
25#include <dmedia/audio.h>
26
27/* #define IRIX_DEBUG 1 */
28
29#define IRIX_MAX_VOL 65535
30
31ALconfig audioconfig;
32ALport output_port;
33
34static int g_snd_rate;
35static int width = AL_SAMPLE_16;
36static char *sgi_output_device = NULL;
37
38double min_volume, max_volume, volume_range;
39int resource, maxFillable;
40int combinedFrameSize;
41
42void sgi_play(void);
43
44void
45sgi_add_fds(int *n, fd_set * rfds, fd_set * wfds, struct timeval *tv)
46{
47 /* We need to be called rather often... */
48 if (output_port != (ALport) 0 && !rdpsnd_queue_empty())
49 FD_SET(0, wfds);
50}
51
52void
53sgi_check_fds(fd_set * rfds, fd_set * wfds)
54{
55 if (output_port == (ALport) 0)
56 return;
57
58 if (!rdpsnd_queue_empty())
59 sgi_play();
60}
61
62RD_BOOL
63sgi_open(void)
64{
65 ALparamInfo pinfo;
66 static int warned = 0;
67
68#if (defined(IRIX_DEBUG))
69 fprintf(stderr, "sgi_open: begin\n");
70#endif
71
72 if (!warned && sgi_output_device)
73 {
74 warning("device-options not supported for libao-driver\n");
75 warned = 1;
76 }
77
78 if (alGetParamInfo(AL_DEFAULT_OUTPUT, AL_GAIN, &pinfo) < 0)
79 {
80 fprintf(stderr, "sgi_open: alGetParamInfo failed: %s\n",
81 alGetErrorString(oserror()));
82 }
83 min_volume = alFixedToDouble(pinfo.min.ll);
84 max_volume = alFixedToDouble(pinfo.max.ll);
85 volume_range = (max_volume - min_volume);
86#if (defined(IRIX_DEBUG))
87 fprintf(stderr, "sgi_open: minvol = %lf, maxvol= %lf, range = %lf.\n",
88 min_volume, max_volume, volume_range);
89#endif
90
91 audioconfig = alNewConfig();
92 if (audioconfig == (ALconfig) 0)
93 {
94 fprintf(stderr, "sgi_open: alNewConfig failed: %s\n", alGetErrorString(oserror()));
95 return False;
96 }
97
98 output_port = alOpenPort("rdpsnd", "w", 0);
99 if (output_port == (ALport) 0)
100 {
101 fprintf(stderr, "sgi_open: alOpenPort failed: %s\n", alGetErrorString(oserror()));
102 return False;
103 }
104
105#if (defined(IRIX_DEBUG))
106 fprintf(stderr, "sgi_open: returning\n");
107#endif
108 return True;
109}
110
111void
112sgi_close(void)
113{
114 /* Ack all remaining packets */
115#if (defined(IRIX_DEBUG))
116 fprintf(stderr, "sgi_close: begin\n");
117#endif
118
119 while (!rdpsnd_queue_empty())
120 rdpsnd_queue_next(0);
121 alDiscardFrames(output_port, 0);
122
123 alClosePort(output_port);
124 output_port = (ALport) 0;
125 alFreeConfig(audioconfig);
126#if (defined(IRIX_DEBUG))
127 fprintf(stderr, "sgi_close: returning\n");
128#endif
129}
130
131RD_BOOL
132sgi_format_supported(RD_WAVEFORMATEX * pwfx)
133{
134 if (pwfx->wFormatTag != WAVE_FORMAT_PCM)
135 return False;
136 if ((pwfx->nChannels != 1) && (pwfx->nChannels != 2))
137 return False;
138 if ((pwfx->wBitsPerSample != 8) && (pwfx->wBitsPerSample != 16))
139 return False;
140
141 return True;
142}
143
144RD_BOOL
145sgi_set_format(RD_WAVEFORMATEX * pwfx)
146{
147 int channels;
148 int frameSize, channelCount;
149 ALpv params;
150
151#if (defined(IRIX_DEBUG))
152 fprintf(stderr, "sgi_set_format: init...\n");
153#endif
154
155 if (pwfx->wBitsPerSample == 8)
156 width = AL_SAMPLE_8;
157 else if (pwfx->wBitsPerSample == 16)
158 width = AL_SAMPLE_16;
159
160 /* Limited support to configure an opened audio port in IRIX. The
161 number of channels is a static setting and can not be changed after
162 a port is opened. So if the number of channels remains the same, we
163 can configure other settings; otherwise we have to reopen the audio
164 port, using same config. */
165
166 channels = pwfx->nChannels;
167 g_snd_rate = pwfx->nSamplesPerSec;
168
169 alSetSampFmt(audioconfig, AL_SAMPFMT_TWOSCOMP);
170 alSetWidth(audioconfig, width);
171 if (channels != alGetChannels(audioconfig))
172 {
173 alClosePort(output_port);
174 alSetChannels(audioconfig, channels);
175 output_port = alOpenPort("rdpsnd", "w", audioconfig);
176
177 if (output_port == (ALport) 0)
178 {
179 fprintf(stderr, "sgi_set_format: alOpenPort failed: %s\n",
180 alGetErrorString(oserror()));
181 return False;
182 }
183
184 }
185
186 resource = alGetResource(output_port);
187 maxFillable = alGetFillable(output_port);
188 channelCount = alGetChannels(audioconfig);
189 frameSize = alGetWidth(audioconfig);
190
191 if (frameSize == 0 || channelCount == 0)
192 {
193 fprintf(stderr, "sgi_set_format: bad frameSize or channelCount\n");
194 return False;
195 }
196 combinedFrameSize = frameSize * channelCount;
197
198 params.param = AL_RATE;
199 params.value.ll = (long long) g_snd_rate << 32;
200
201 if (alSetParams(resource, &params, 1) < 0)
202 {
203 fprintf(stderr, "wave_set_format: alSetParams failed: %s\n",
204 alGetErrorString(oserror()));
205 return False;
206 }
207 if (params.sizeOut < 0)
208 {
209 fprintf(stderr, "wave_set_format: invalid rate %d\n", g_snd_rate);
210 return False;
211 }
212
213#if (defined(IRIX_DEBUG))
214 fprintf(stderr, "sgi_set_format: returning...\n");
215#endif
216 return True;
217}
218
219void
220sgi_volume(uint16 left, uint16 right)
221{
222 double gainleft, gainright;
223 ALpv pv[1];
224 ALfixed gain[8];
225
226#if (defined(IRIX_DEBUG))
227 fprintf(stderr, "sgi_volume: begin\n");
228 fprintf(stderr, "left='%d', right='%d'\n", left, right);
229#endif
230
231 gainleft = (double) left / IRIX_MAX_VOL;
232 gainright = (double) right / IRIX_MAX_VOL;
233
234 gain[0] = alDoubleToFixed(min_volume + gainleft * volume_range);
235 gain[1] = alDoubleToFixed(min_volume + gainright * volume_range);
236
237 pv[0].param = AL_GAIN;
238 pv[0].value.ptr = gain;
239 pv[0].sizeIn = 8;
240 if (alSetParams(AL_DEFAULT_OUTPUT, pv, 1) < 0)
241 {
242 fprintf(stderr, "sgi_volume: alSetParams failed: %s\n",
243 alGetErrorString(oserror()));
244 return;
245 }
246
247#if (defined(IRIX_DEBUG))
248 fprintf(stderr, "sgi_volume: returning\n");
249#endif
250}
251
252void
253sgi_play(void)
254{
255 struct audio_packet *packet;
256 ssize_t len;
257 unsigned int i;
258 STREAM out;
259 int gf;
260
261 while (1)
262 {
263 if (rdpsnd_queue_empty())
264 return;
265
266 packet = rdpsnd_queue_current_packet();
267 out = &packet->s;
268
269 len = out->end - out->p;
270
271 alWriteFrames(output_port, out->p, len / combinedFrameSize);
272
273 out->p += len;
274 if (out->p == out->end)
275 {
276 gf = alGetFilled(output_port);
277 if (gf < (4 * maxFillable / 10))
278 {
279 rdpsnd_queue_next(0);
280 }
281 else
282 {
283#if (defined(IRIX_DEBUG))
284/* fprintf(stderr,"Busy playing...\n"); */
285#endif
286 usleep(10);
287 return;
288 }
289 }
290 }
291}
292
293struct audio_driver *
294sgi_register(char *options)
295{
296 static struct audio_driver sgi_driver;
297
298 memset(&sgi_driver, 0, sizeof(sgi_driver));
299
300 sgi_driver.name = "sgi";
301 sgi_driver.description = "SGI output driver";
302
303 sgi_driver.add_fds = sgi_add_fds;
304 sgi_driver.check_fds = sgi_check_fds;
305
306 sgi_driver.wave_out_open = sgi_open;
307 sgi_driver.wave_out_close = sgi_close;
308 sgi_driver.wave_out_format_supported = sgi_format_supported;
309 sgi_driver.wave_out_set_format = sgi_set_format;
310 sgi_driver.wave_out_volume = sgi_volume;
311
312 sgi_driver.need_byteswap_on_be = 1;
313 sgi_driver.need_resampling = 0;
314
315 if (options)
316 {
317 sgi_output_device = xstrdup(options);
318 }
319 return &sgi_driver;
320}
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