/[rdesktop]/sourceforge.net/trunk/rdesktop/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 /sourceforge.net/trunk/rdesktop/rdpsnd_sgi.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1346 - (show annotations)
Thu Dec 7 15:23:45 2006 UTC (17 years, 6 months ago) by ossman_
File MIME type: text/plain
File size: 7176 byte(s)
Abstract select() handling in rdpsnd so that backends can do their thing
more correctly.

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

  ViewVC Help
Powered by ViewVC 1.1.26