/[rdesktop]/jpeg/rdesktop/trunk/rdpsnd_sgi.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /jpeg/rdesktop/trunk/rdpsnd_sgi.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1356 - (show annotations)
Tue Jan 2 11:39:56 2007 UTC (17 years, 4 months ago) by ossman_
Original Path: sourceforge.net/trunk/rdesktop/rdpsnd_sgi.c
File MIME type: text/plain
File size: 7390 byte(s)
Fix audio_driver initialisation to avoid problem with uninitialised
variables and reduce the memory leakage.

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
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
31 ALconfig audioconfig;
32 ALport output_port;
33
34 static int g_snd_rate;
35 static int width = AL_SAMPLE_16;
36 static char *sgi_output_device = NULL;
37
38 double min_volume, max_volume, volume_range;
39 int resource, maxFillable;
40 int combinedFrameSize;
41
42 void sgi_play(void);
43
44 void
45 sgi_add_fds(int *n, fd_set * rfds, fd_set * wfds, struct timeval *tv)
46 {
47 /* We need to be called rather often... */
48 FD_SET(0, wfds);
49 }
50
51 void
52 sgi_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
61 BOOL
62 sgi_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
110 void
111 sgi_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
130 BOOL
131 sgi_format_supported(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
143 BOOL
144 sgi_set_format(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
218 void
219 sgi_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
251 void
252 sgi_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
292 struct audio_driver *
293 sgi_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 }

  ViewVC Help
Powered by ViewVC 1.1.26