VirtualBox

source: vbox/trunk/src/VBox/RDP/client-1.8.3/rdpsnd_sgi.c@ 55121

最後變更 在這個檔案從55121是 55121,由 vboxsync 提交於 10 年 前

rdesktop 1.8.3 unmodified

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

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