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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 784 by stargo, Fri Oct 15 18:04:16 2004 UTC revision 1256 by stargo, Sun Sep 17 11:42:22 2006 UTC
# Line 1  Line 1 
1  /*  /* -*- c-basic-offset: 8 -*-
2     rdesktop: A Remote Desktop Protocol client.     rdesktop: A Remote Desktop Protocol client.
3     Sound Channel Process Functions - SGI/IRIX     Sound Channel Process Functions - SGI/IRIX
4     Copyright (C) Matthew Chapman 2003     Copyright (C) Matthew Chapman 2003
5     Copyright (C) GuoJunBo guojunbo@ict.ac.cn 2003     Copyright (C) GuoJunBo guojunbo@ict.ac.cn 2003
6     Copyright (C) Jeremy Meng voidfoo@cwazy.co.uk 2004     Copyright (C) Jeremy Meng void.foo@gmail.com 2004, 2005
7    
8     This program is free software; you can redistribute it and/or modify     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     it under the terms of the GNU General Public License as published by
# Line 24  Line 24 
24  #include <errno.h>  #include <errno.h>
25  #include <dmedia/audio.h>  #include <dmedia/audio.h>
26    
27  #define IRIX_DEBUG 1  /* #define IRIX_DEBUG 1 */
28    
29  #define IRIX_MAX_VOL     65535  #define IRIX_MAX_VOL     65535
30    
 #define MAX_QUEUE       10  
   
 int g_dsp_fd;  
31  ALconfig audioconfig;  ALconfig audioconfig;
32  ALport output_port;  ALport output_port;
33    
 BOOL g_dsp_busy = False;  
34  static BOOL g_swapaudio;  static BOOL g_swapaudio;
35  static int g_snd_rate;  static int g_snd_rate;
36  static BOOL g_swapaudio;  static BOOL g_swapaudio;
 static short g_samplewidth;  
37  static int width = AL_SAMPLE_16;  static int width = AL_SAMPLE_16;
38    static char *sgi_output_device = NULL;
39    
40  double min_volume, max_volume, volume_range;  double min_volume, max_volume, volume_range;
41  int resource, maxFillable;  int resource, maxFillable;
42  int combinedFrameSize;  int combinedFrameSize;
43    
 static struct audio_packet  
 {  
         struct stream s;  
         uint16 tick;  
         uint8 index;  
 } packet_queue[MAX_QUEUE];  
 static unsigned int queue_hi, queue_lo;  
   
44  BOOL  BOOL
45  wave_out_open(void)  sgi_open(void)
46  {  {
47          ALparamInfo pinfo;          ALparamInfo pinfo;
48            static int warned = 0;
49    
50  #if (defined(IRIX_DEBUG))  #if (defined(IRIX_DEBUG))
51          fprintf(stderr, "wave_out_open: begin\n");          fprintf(stderr, "sgi_open: begin\n");
52  #endif  #endif
53    
54            if (!warned && sgi_output_device)
55            {
56                    warning("device-options not supported for libao-driver\n");
57                    warned = 1;
58            }
59    
60          if (alGetParamInfo(AL_DEFAULT_OUTPUT, AL_GAIN, &pinfo) < 0)          if (alGetParamInfo(AL_DEFAULT_OUTPUT, AL_GAIN, &pinfo) < 0)
61          {          {
62                  fprintf(stderr, "wave_out_open: alGetParamInfo failed: %s\n",                  fprintf(stderr, "sgi_open: alGetParamInfo failed: %s\n",
63                          alGetErrorString(oserror()));                          alGetErrorString(oserror()));
64          }          }
65          min_volume = alFixedToDouble(pinfo.min.ll);          min_volume = alFixedToDouble(pinfo.min.ll);
66          max_volume = alFixedToDouble(pinfo.max.ll);          max_volume = alFixedToDouble(pinfo.max.ll);
67          volume_range = (max_volume - min_volume);          volume_range = (max_volume - min_volume);
68  #if (defined(IRIX_DEBUG))  #if (defined(IRIX_DEBUG))
69          fprintf(stderr, "wave_out_open: minvol = %lf, maxvol= %lf, range = %lf.\n",          fprintf(stderr, "sgi_open: minvol = %lf, maxvol= %lf, range = %lf.\n",
70                  min_volume, max_volume, volume_range);                  min_volume, max_volume, volume_range);
71  #endif  #endif
72    
73          queue_lo = queue_hi = 0;          rdpsnd_queue_init();
74    
75          audioconfig = alNewConfig();          audioconfig = alNewConfig();
76          if (audioconfig < 0)          if (audioconfig == (ALconfig) 0)
77          {          {
78                  fprintf(stderr, "wave_out_open: alNewConfig failed: %s\n",                  fprintf(stderr, "sgi_open: alNewConfig failed: %s\n", alGetErrorString(oserror()));
                         alGetErrorString(oserror()));  
79                  return False;                  return False;
80          }          }
81    
82          output_port = alOpenPort("rdpsnd", "w", 0);          output_port = alOpenPort("rdpsnd", "w", 0);
83          if (output_port == (ALport) 0)          if (output_port == (ALport) 0)
84          {          {
85                  fprintf(stderr, "wave_out_open: alOpenPort failed: %s\n",                  fprintf(stderr, "sgi_open: alOpenPort failed: %s\n", alGetErrorString(oserror()));
                         alGetErrorString(oserror()));  
86                  return False;                  return False;
87          }          }
88    
89  #if (defined(IRIX_DEBUG))  #if (defined(IRIX_DEBUG))
90          fprintf(stderr, "wave_out_open: returning\n");          fprintf(stderr, "sgi_open: returning\n");
91  #endif  #endif
92          return True;          return True;
93  }  }
94    
95  void  void
96  wave_out_close(void)  sgi_close(void)
97  {  {
98          /* Ack all remaining packets */          /* Ack all remaining packets */
99  #if (defined(IRIX_DEBUG))  #if (defined(IRIX_DEBUG))
100          fprintf(stderr, "wave_out_close: begin\n");          fprintf(stderr, "sgi_close: begin\n");
101  #endif  #endif
102    
103          while (queue_lo != queue_hi)          while (!rdpsnd_queue_empty())
104          {          {
105                  rdpsnd_send_completion(packet_queue[queue_lo].tick, packet_queue[queue_lo].index);                  /* We need to add 50 to tell windows that time has passed while
106                  free(packet_queue[queue_lo].s.data);                   * playing this packet */
107                  queue_lo = (queue_lo + 1) % MAX_QUEUE;                  rdpsnd_send_completion(rdpsnd_queue_current_packet()->tick + 50,
108                                           rdpsnd_queue_current_packet()->index);
109                    rdpsnd_queue_next();
110          }          }
111          alDiscardFrames(output_port, 0);          alDiscardFrames(output_port, 0);
112    
113          alClosePort(output_port);          alClosePort(output_port);
114          alFreeConfig(audioconfig);          alFreeConfig(audioconfig);
115  #if (defined(IRIX_DEBUG))  #if (defined(IRIX_DEBUG))
116          fprintf(stderr, "wave_out_close: returning\n");          fprintf(stderr, "sgi_close: returning\n");
117  #endif  #endif
118  }  }
119    
120  BOOL  BOOL
121  wave_out_format_supported(WAVEFORMATEX * pwfx)  sgi_format_supported(WAVEFORMATEX * pwfx)
122  {  {
123          if (pwfx->wFormatTag != WAVE_FORMAT_PCM)          if (pwfx->wFormatTag != WAVE_FORMAT_PCM)
124                  return False;                  return False;
# Line 136  wave_out_format_supported(WAVEFORMATEX * Line 131  wave_out_format_supported(WAVEFORMATEX *
131  }  }
132    
133  BOOL  BOOL
134  wave_out_set_format(WAVEFORMATEX * pwfx)  sgi_set_format(WAVEFORMATEX * pwfx)
135  {  {
136          int channels;          int channels;
137          int frameSize, channelCount;          int frameSize, channelCount;
138          ALpv params;          ALpv params;
139    
140  #if (defined(IRIX_DEBUG))  #if (defined(IRIX_DEBUG))
141          fprintf(stderr, "wave_out_set_format: init...\n");          fprintf(stderr, "sgi_set_format: init...\n");
142  #endif  #endif
         /* limited support to configure an opened audio port in IRIX */  
         /* have to reopen the audio port, using same config */  
         alClosePort(output_port);  
143    
144          g_swapaudio = False;          g_swapaudio = False;
   
145          if (pwfx->wBitsPerSample == 8)          if (pwfx->wBitsPerSample == 8)
146                  width = AL_SAMPLE_8;                  width = AL_SAMPLE_8;
147          else if (pwfx->wBitsPerSample == 16)          else if (pwfx->wBitsPerSample == 16)
148          {          {
149                  width = AL_SAMPLE_16;                  width = AL_SAMPLE_16;
150                  /* Do we need to swap the 16bit values? (Are we BigEndian) */                  /* Do we need to swap the 16bit values? (Are we BigEndian) */
151  #if (defined(IRIX_DEBUG))  #if (defined(B_ENDIAN))
152                  g_swapaudio = 1;                  g_swapaudio = 1;
153  #else  #else
154                  g_swapaudio = 0;                  g_swapaudio = 0;
155  #endif  #endif
156          }          }
157    
158          g_samplewidth = pwfx->wBitsPerSample / 8;          /* Limited support to configure an opened audio port in IRIX.  The
159               number of channels is a static setting and can not be changed after
160               a port is opened.  So if the number of channels remains the same, we
161               can configure other settings; otherwise we have to reopen the audio
162               port, using same config. */
163    
164          channels = pwfx->nChannels;          channels = pwfx->nChannels;
165          g_snd_rate = pwfx->nSamplesPerSec;          g_snd_rate = pwfx->nSamplesPerSec;
166    
167          alSetSampFmt(audioconfig, AL_SAMPFMT_TWOSCOMP);          alSetSampFmt(audioconfig, AL_SAMPFMT_TWOSCOMP);
168          alSetWidth(audioconfig, width);          alSetWidth(audioconfig, width);
169          alSetChannels(audioconfig, channels);          if (channels != alGetChannels(audioconfig))
170            {
171                    alClosePort(output_port);
172                    alSetChannels(audioconfig, channels);
173                    output_port = alOpenPort("rdpsnd", "w", audioconfig);
174    
175          output_port = alOpenPort("rdpsnd", "w", audioconfig);                  if (output_port == (ALport) 0)
176                    {
177                            fprintf(stderr, "sgi_set_format: alOpenPort failed: %s\n",
178                                    alGetErrorString(oserror()));
179                            return False;
180                    }
181    
         if (output_port == (ALport) 0)  
         {  
                 fprintf(stderr, "wave_out_set_format: alOpenPort failed: %s\n",  
                         alGetErrorString(oserror()));  
                 return False;  
182          }          }
183    
184          resource = alGetResource(output_port);          resource = alGetResource(output_port);
# Line 188  wave_out_set_format(WAVEFORMATEX * pwfx) Line 188  wave_out_set_format(WAVEFORMATEX * pwfx)
188    
189          if (frameSize == 0 || channelCount == 0)          if (frameSize == 0 || channelCount == 0)
190          {          {
191                  fprintf(stderr, "wave_out_set_format: bad frameSize or channelCount\n");                  fprintf(stderr, "sgi_set_format: bad frameSize or channelCount\n");
192                  return False;                  return False;
193          }          }
194          combinedFrameSize = frameSize * channelCount;          combinedFrameSize = frameSize * channelCount;
# Line 209  wave_out_set_format(WAVEFORMATEX * pwfx) Line 209  wave_out_set_format(WAVEFORMATEX * pwfx)
209          }          }
210    
211  #if (defined(IRIX_DEBUG))  #if (defined(IRIX_DEBUG))
212          fprintf(stderr, "wave_out_set_format: returning...\n");          fprintf(stderr, "sgi_set_format: returning...\n");
213  #endif  #endif
214          return True;          return True;
215  }  }
216    
217  void  void
218  wave_out_volume(uint16 left, uint16 right)  sgi_volume(uint16 left, uint16 right)
219  {  {
220          double gainleft, gainright;          double gainleft, gainright;
221          ALpv pv[1];          ALpv pv[1];
222          ALfixed gain[8];          ALfixed gain[8];
223    
224  #if (defined(IRIX_DEBUG))  #if (defined(IRIX_DEBUG))
225          fprintf(stderr, "wave_out_volume: begin\n");          fprintf(stderr, "sgi_volume: begin\n");
226          fprintf(stderr, "left='%d', right='%d'\n", left, right);          fprintf(stderr, "left='%d', right='%d'\n", left, right);
227  #endif  #endif
228    
# Line 237  wave_out_volume(uint16 left, uint16 righ Line 237  wave_out_volume(uint16 left, uint16 righ
237          pv[0].sizeIn = 8;          pv[0].sizeIn = 8;
238          if (alSetParams(AL_DEFAULT_OUTPUT, pv, 1) < 0)          if (alSetParams(AL_DEFAULT_OUTPUT, pv, 1) < 0)
239          {          {
240                  fprintf(stderr, "wave_out_volume: alSetParams failed: %s\n",                  fprintf(stderr, "sgi_volume: alSetParams failed: %s\n",
241                          alGetErrorString(oserror()));                          alGetErrorString(oserror()));
242                  return;                  return;
243          }          }
244    
245  #if (defined(IRIX_DEBUG))  #if (defined(IRIX_DEBUG))
246          fprintf(stderr, "wave_out_volume: returning\n");          fprintf(stderr, "sgi_volume: returning\n");
247  #endif  #endif
248  }  }
249    
250  void  void
251  wave_out_write(STREAM s, uint16 tick, uint8 index)  sgi_play(void)
 {  
         struct audio_packet *packet = &packet_queue[queue_hi];  
         unsigned int next_hi = (queue_hi + 1) % MAX_QUEUE;  
   
         if (next_hi == queue_lo)  
         {  
                 fprintf(stderr, "No space to queue audio packet\n");  
                 return;  
         }  
   
         queue_hi = next_hi;  
   
         packet->s = *s;  
         packet->tick = tick;  
         packet->index = index;  
         packet->s.p += 4;  
   
         /* we steal the data buffer from s, give it a new one */  
         s->data = malloc(s->size);  
   
         if (!g_dsp_busy)  
                 wave_out_play();  
 }  
   
 void  
 wave_out_play(void)  
252  {  {
253          struct audio_packet *packet;          struct audio_packet *packet;
254          ssize_t len;          ssize_t len;
255          unsigned int i;          unsigned int i;
256          uint8 swap;          uint8 swap;
257          STREAM out;          STREAM out;
         static long startedat_us;  
         static long startedat_s;  
         static BOOL started = False;  
258          static BOOL swapped = False;          static BOOL swapped = False;
         struct timeval tv;  
259          int gf;          int gf;
         static long long temp;  
260    
261          while (1)          while (1)
262          {          {
263                  if (queue_lo == queue_hi)                  if (rdpsnd_queue_empty())
264                  {                  {
265                          g_dsp_busy = False;                          g_dsp_busy = False;
266                          return;                          return;
267                  }                  }
268    
269                  packet = &packet_queue[queue_lo];                  packet = rdpsnd_queue_current_packet();
270                  out = &packet->s;                  out = &packet->s;
271    
272                  /* Swap the current packet, but only once */                  /* Swap the current packet, but only once */
# Line 312  wave_out_play(void) Line 281  wave_out_play(void)
281                          swapped = True;                          swapped = True;
282                  }                  }
283    
                 if (!started)  
                 {  
                         gettimeofday(&tv, NULL);  
                         startedat_us = tv.tv_usec;  
                         startedat_s = tv.tv_sec;  
                         started = True;  
                 }  
   
284                  len = out->end - out->p;                  len = out->end - out->p;
                 gf = alGetFillable(output_port);  
                 if (len > gf)  
                 {  
                         //len = gf * combinedFrameSize;  
 #if (defined(IRIX_DEBUG))  
                         //fprintf(stderr,"Fillable...\n");  
 #endif  
                 }  
285    
286                  alWriteFrames(output_port, out->p, len / combinedFrameSize);                  alWriteFrames(output_port, out->p, len / combinedFrameSize);
287    
288                  out->p += len;                  out->p += len;
289                  if (out->p == out->end)                  if (out->p == out->end)
290                  {                  {
291                          long long duration;                          gf = alGetFilled(output_port);
292                          long elapsed;                          if (gf < (4 * maxFillable / 10))
   
                         gettimeofday(&tv, NULL);  
                         duration = (out->size * (1000000 / (g_samplewidth * g_snd_rate)));  
                         elapsed = (tv.tv_sec - startedat_s) * 1000000 + (tv.tv_usec - startedat_us);  
                         /* 7/10 is not good for IRIX audio port, 4x/100 is suitable */  
                         if (elapsed >= (duration * 485) / 1000)  
293                          {                          {
294                                  rdpsnd_send_completion(packet->tick, packet->index);                                  rdpsnd_send_completion(packet->tick, packet->index);
295                                  free(out->data);                                  rdpsnd_queue_next();
                                 queue_lo = (queue_lo + 1) % MAX_QUEUE;  
                                 started = False;  
296                                  swapped = False;                                  swapped = False;
297                          }                          }
298                          else                          else
299                          {                          {
300  #if (defined(IRIX_DEBUG))  #if (defined(IRIX_DEBUG))
301                                  //fprintf(stderr,"Busy playing...\n");  /*                              fprintf(stderr,"Busy playing...\n"); */
302  #endif  #endif
303                                  g_dsp_busy = True;                                  g_dsp_busy = True;
304                                    usleep(10);
305                                  return;                                  return;
306                          }                          }
307                  }                  }
308          }          }
309  }  }
310    
311    struct audio_driver *
312    sgi_register(char *options)
313    {
314            static struct audio_driver sgi_driver;
315    
316            sgi_driver.wave_out_write = rdpsnd_queue_write;
317            sgi_driver.wave_out_open = sgi_open;
318            sgi_driver.wave_out_close = sgi_close;
319            sgi_driver.wave_out_format_supported = sgi_format_supported;
320            sgi_driver.wave_out_set_format = sgi_set_format;
321            sgi_driver.wave_out_volume = sgi_volume;
322            sgi_driver.wave_out_play = sgi_play;
323            sgi_driver.name = xstrdup("sgi");
324            sgi_driver.description = xstrdup("SGI output driver");
325            sgi_driver.next = NULL;
326    
327            if (options)
328            {
329                    sgi_output_device = xstrdup(options);
330            }
331            return &sgi_driver;
332    }

Legend:
Removed from v.784  
changed lines
  Added in v.1256

  ViewVC Help
Powered by ViewVC 1.1.26