/[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 1279 - (show annotations)
Sun Oct 1 14:03:43 2006 UTC (17 years, 7 months ago) by stargo
File MIME type: text/plain
File size: 7416 byte(s)
make it possible for the driver to switch resampling on and off
dynamically. this will be needed for the OSS driver.

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

  ViewVC Help
Powered by ViewVC 1.1.26