/[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

Annotation of /sourceforge.net/trunk/rdesktop/rdpsnd_sgi.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 744 - (hide annotations)
Mon Aug 9 11:39:49 2004 UTC (19 years, 10 months ago) by stargo
File MIME type: text/plain
File size: 8454 byte(s)
SGI sound support from Jeremy Meng <voidfoo@cwazy.co.uk>

1 stargo 744 /*
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) Michael Gernoth mike@zerfleddert.de 2003
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     #define MAX_QUEUE 10
32    
33     int g_dsp_fd;
34     ALconfig audioconfig;
35     ALport output_port;
36    
37     BOOL g_dsp_busy = False;
38     static BOOL g_swapaudio;
39     static int g_snd_rate;
40     static BOOL g_swapaudio;
41     static short g_samplewidth;
42     static int width = AL_SAMPLE_16;
43    
44     double min_volume, max_volume, volume_range;
45     int resource, maxFillable;
46     int combinedFrameSize;
47    
48     static struct audio_packet
49     {
50     struct stream s;
51     uint16 tick;
52     uint8 index;
53     } packet_queue[MAX_QUEUE];
54     static unsigned int queue_hi, queue_lo;
55    
56     BOOL
57     wave_out_open(void)
58     {
59     ALparamInfo pinfo;
60    
61     #if (defined(IRIX_DEBUG))
62     fprintf(stderr, "wave_out_open: begin\n");
63     #endif
64    
65     if ( alGetParamInfo(AL_DEFAULT_OUTPUT, AL_GAIN, &pinfo) < 0 )
66     {
67     fprintf(stderr, "wave_out_open: alGetParamInfo failed: %s\n",
68     alGetErrorString(oserror()));
69     }
70     min_volume = alFixedToDouble(pinfo.min.ll);
71     max_volume = alFixedToDouble(pinfo.max.ll);
72     volume_range = (max_volume - min_volume);
73     #if (defined(IRIX_DEBUG))
74     fprintf(stderr, "wave_out_open: minvol = %lf, maxvol= %lf, range = %lf.\n",
75     min_volume, max_volume, volume_range);
76     #endif
77    
78     queue_lo = queue_hi = 0;
79    
80     audioconfig = alNewConfig();
81     if (audioconfig < 0) {
82     fprintf(stderr, "wave_out_open: alNewConfig failed: %s\n",
83     alGetErrorString(oserror()));
84     return False;
85     }
86    
87     output_port = alOpenPort("rdpsnd", "w", 0);
88     if (output_port == (ALport) 0) {
89     fprintf(stderr, "wave_out_open: alOpenPort failed: %s\n",
90     alGetErrorString(oserror()));
91     return False;
92     }
93    
94     #if (defined(IRIX_DEBUG))
95     fprintf(stderr, "wave_out_open: returning\n");
96     #endif
97     return True;
98     }
99    
100     void
101     wave_out_close(void)
102     {
103     /* Ack all remaining packets */
104     #if (defined(IRIX_DEBUG))
105     fprintf(stderr, "wave_out_close: begin\n");
106     #endif
107    
108     while (queue_lo != queue_hi)
109     {
110     rdpsnd_send_completion(packet_queue[queue_lo].tick, packet_queue[queue_lo].index);
111     free(packet_queue[queue_lo].s.data);
112     queue_lo = (queue_lo + 1) % MAX_QUEUE;
113     }
114     alDiscardFrames(output_port, 0);
115    
116     alClosePort(output_port);
117     alFreeConfig(audioconfig);
118     #if (defined(IRIX_DEBUG))
119     fprintf(stderr, "wave_out_close: returning\n");
120     #endif
121     }
122    
123     BOOL
124     wave_out_format_supported(WAVEFORMATEX * pwfx)
125     {
126     if (pwfx->wFormatTag != WAVE_FORMAT_PCM)
127     return False;
128     if ((pwfx->nChannels != 1) && (pwfx->nChannels != 2))
129     return False;
130     if ((pwfx->wBitsPerSample != 8) && (pwfx->wBitsPerSample != 16))
131     return False;
132    
133     return True;
134     }
135    
136     BOOL
137     wave_out_set_format(WAVEFORMATEX * pwfx)
138     {
139     int channels;
140     int frameSize, channelCount;
141     ALpv params;
142    
143     #if (defined(IRIX_DEBUG))
144     fprintf(stderr, "wave_out_set_format: init...\n");
145     #endif
146     /* limited support to configure an opened audio port in IRIX */
147     /* have to reopen the audio port, using same config */
148     alClosePort(output_port);
149    
150     g_swapaudio = False;
151    
152     if (pwfx->wBitsPerSample == 8)
153     width = AL_SAMPLE_8;
154     else if (pwfx->wBitsPerSample == 16) {
155     width = AL_SAMPLE_16;
156     /* Do we need to swap the 16bit values? (Are we BigEndian) */
157     #if (defined(IRIX_DEBUG))
158     g_swapaudio = 1;
159     #else
160     g_swapaudio = 0;
161     #endif
162     }
163    
164     g_samplewidth = pwfx->wBitsPerSample / 8;
165     channels = pwfx->nChannels;
166     g_snd_rate = pwfx->nSamplesPerSec;
167    
168     alSetSampFmt(audioconfig, AL_SAMPFMT_TWOSCOMP);
169     alSetWidth(audioconfig, width);
170     alSetChannels(audioconfig, channels);
171    
172     output_port = alOpenPort("rdpsnd", "w", audioconfig);
173    
174     if (output_port == (ALport) 0) {
175     fprintf(stderr, "wave_out_set_format: alOpenPort failed: %s\n",
176     alGetErrorString(oserror()));
177     return False;
178     }
179    
180     resource = alGetResource(output_port);
181     maxFillable = alGetFillable(output_port);
182     channelCount = alGetChannels(audioconfig);
183     frameSize = alGetWidth(audioconfig);
184    
185     if (frameSize == 0 || channelCount == 0)
186     {
187     fprintf(stderr, "wave_out_set_format: bad frameSize or channelCount\n");
188     return False;
189     }
190     combinedFrameSize = frameSize * channelCount;
191    
192     params.param = AL_RATE;
193     params.value.ll = (long long) g_snd_rate << 32;
194    
195     if (alSetParams(resource, &params, 1) < 0)
196     {
197     fprintf(stderr, "wave_set_format: alSetParams failed: %s\n",
198     alGetErrorString(oserror()));
199     return False;
200     }
201     if( params.sizeOut < 0 )
202     {
203     fprintf(stderr, "wave_set_format: invalid rate %d\n", g_snd_rate);
204     return False;
205     }
206    
207     #if (defined(IRIX_DEBUG))
208     fprintf(stderr, "wave_out_set_format: returning...\n");
209     #endif
210     return True;
211     }
212    
213     void
214     wave_out_volume(uint16 left, uint16 right)
215     {
216     double gainleft, gainright;
217     ALpv pv[1];
218     ALfixed gain[8];
219    
220     #if (defined(IRIX_DEBUG))
221     fprintf(stderr, "wave_out_volume: begin\n");
222     fprintf(stderr, "left='%d', right='%d'\n", left, right);
223     #endif
224    
225     gainleft = (double) left / IRIX_MAX_VOL;
226     gainright = (double) right / IRIX_MAX_VOL;
227    
228     gain[0] = alDoubleToFixed(min_volume + gainleft * volume_range);
229     gain[1] = alDoubleToFixed(min_volume + gainright * volume_range);
230    
231     pv[0].param = AL_GAIN;
232     pv[0].value.ptr = gain;
233     pv[0].sizeIn = 8;
234     if( alSetParams(AL_DEFAULT_OUTPUT, pv, 1) < 0)
235     {
236     fprintf(stderr, "wave_out_volume: alSetParams failed: %s\n", alGetErrorString(oserror()));
237     return;
238     }
239    
240     #if (defined(IRIX_DEBUG))
241     fprintf(stderr, "wave_out_volume: returning\n");
242     #endif
243     }
244    
245     void
246     wave_out_write(STREAM s, uint16 tick, uint8 index)
247     {
248     struct audio_packet *packet = &packet_queue[queue_hi];
249     unsigned int next_hi = (queue_hi + 1) % MAX_QUEUE;
250    
251     if (next_hi == queue_lo)
252     {
253     fprintf(stderr, "No space to queue audio packet\n");
254     return;
255     }
256    
257     queue_hi = next_hi;
258    
259     packet->s = *s;
260     packet->tick = tick;
261     packet->index = index;
262     packet->s.p += 4;
263    
264     /* we steal the data buffer from s, give it a new one */
265     s->data = malloc(s->size);
266    
267     if (!g_dsp_busy)
268     wave_out_play();
269     }
270    
271     void
272     wave_out_play(void)
273     {
274     struct audio_packet *packet;
275     ssize_t len;
276     unsigned int i;
277     uint8 swap;
278     STREAM out;
279     static long startedat_us;
280     static long startedat_s;
281     static BOOL started = False;
282     static BOOL swapped = False;
283     struct timeval tv;
284     int gf;
285     static long long temp;
286    
287     while (1)
288     {
289     if (queue_lo == queue_hi)
290     {
291     g_dsp_busy = False;
292     return;
293     }
294    
295     packet = &packet_queue[queue_lo];
296     out = &packet->s;
297    
298     /* Swap the current packet, but only once */
299     if (g_swapaudio && !swapped)
300     {
301     for (i = 0; i < out->end - out->p; i += 2)
302     {
303     swap = *(out->p + i);
304     *(out->p + i) = *(out->p + i + 1);
305     *(out->p + i + 1) = swap;
306     }
307     swapped = True;
308     }
309    
310     if (!started)
311     {
312     gettimeofday(&tv, NULL);
313     startedat_us = tv.tv_usec;
314     startedat_s = tv.tv_sec;
315     started = True;
316     }
317    
318     len = out->end - out->p;
319     gf = alGetFillable(output_port);
320     if (len > gf) {
321     //len = gf * combinedFrameSize;
322     #if (defined(IRIX_DEBUG))
323     //fprintf(stderr,"Fillable...\n");
324     #endif
325     }
326    
327     alWriteFrames(output_port, out->p, len/combinedFrameSize);
328    
329     out->p += len;
330     if (out->p == out->end)
331     {
332     long long duration;
333     long elapsed;
334    
335     gettimeofday(&tv, NULL);
336     duration = (out->size * (1000000 / (g_samplewidth * g_snd_rate)));
337     elapsed = (tv.tv_sec - startedat_s) * 1000000
338     + (tv.tv_usec - startedat_us);
339     /* 7/10 is not good for IRIX audio port, 4x/100 is suitable */
340     if (elapsed >= (duration * 485) / 1000)
341     {
342     rdpsnd_send_completion(packet->tick, packet->index);
343     free(out->data);
344     queue_lo = (queue_lo + 1) % MAX_QUEUE;
345     started = False;
346     swapped = False;
347     }
348     else
349     {
350     #if (defined(IRIX_DEBUG))
351     //fprintf(stderr,"Busy playing...\n");
352     #endif
353     g_dsp_busy = True;
354     return;
355     }
356     }
357     }
358     }

  ViewVC Help
Powered by ViewVC 1.1.26