VirtualBox

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

Last change on this file since 50926 was 37224, checked in by vboxsync, 14 years ago

RDP/client: fix OSE

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