/[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 1302 - (show annotations)
Thu Oct 26 09:47:17 2006 UTC (17 years, 8 months ago) by ossman_
File MIME type: text/plain
File size: 7288 byte(s)
Rewrite the queue management a bit so that blocks are not completed until
they have finished playing. This also makes the queue system mandatory for
all backends.

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

  ViewVC Help
Powered by ViewVC 1.1.26