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

Annotation of /jpeg/rdesktop/trunk/rdpsnd_sgi.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 784 - (hide annotations)
Fri Oct 15 18:04:16 2004 UTC (19 years, 7 months ago) by stargo
Original Path: sourceforge.net/trunk/rdesktop/rdpsnd_sgi.c
File MIME type: text/plain
File size: 8318 byte(s)
correct author in rdpsnd_sgi

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

  ViewVC Help
Powered by ViewVC 1.1.26