/[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 1507 - (show annotations)
Mon Jul 20 16:45:11 2009 UTC (14 years, 9 months ago) by dpavlin
File MIME type: text/plain
File size: 7468 byte(s)
branch for integration of Daniel Jarboe <daniel.jarboe(at)gmail.com>
patches for jpeg
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-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 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 if (output_port != (ALport) 0 && !rdpsnd_queue_empty())
49 FD_SET(0, wfds);
50 }
51
52 void
53 sgi_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
62 RD_BOOL
63 sgi_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
111 void
112 sgi_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
131 RD_BOOL
132 sgi_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
144 RD_BOOL
145 sgi_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
219 void
220 sgi_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
252 void
253 sgi_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
293 struct audio_driver *
294 sgi_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 }

  ViewVC Help
Powered by ViewVC 1.1.26