/[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 1345 - (show annotations)
Thu Dec 7 11:54:29 2006 UTC (17 years, 5 months ago) by ossman_
Original Path: sourceforge.net/trunk/rdesktop/rdpsnd_sgi.c
File MIME type: text/plain
File size: 6935 byte(s)
Restructure driver registration structures a bit so it is easier to add
new fields (and also reduce some memory usage/leaks).

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

  ViewVC Help
Powered by ViewVC 1.1.26