/[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 865 by stargo, Tue Mar 15 11:25:50 2005 UTC revision 1475 by jsorg71, Fri Jul 11 03:51:23 2008 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-2008
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;  
 static BOOL g_swapaudio;  
34  static int g_snd_rate;  static int g_snd_rate;
 static BOOL g_swapaudio;  
 static short g_samplewidth;  
35  static int width = AL_SAMPLE_16;  static int width = AL_SAMPLE_16;
36    static char *sgi_output_device = NULL;
37    
38  double min_volume, max_volume, volume_range;  double min_volume, max_volume, volume_range;
39  int resource, maxFillable;  int resource, maxFillable;
40  int combinedFrameSize;  int combinedFrameSize;
41    
42  static struct audio_packet  void sgi_play(void);
43    
44    void
45    sgi_add_fds(int *n, fd_set * rfds, fd_set * wfds, struct timeval *tv)
46  {  {
47          struct stream s;          /* We need to be called rather often... */
48          uint16 tick;          if (output_port != (ALport) 0 && !rdpsnd_queue_empty())
49          uint8 index;                  FD_SET(0, wfds);
50  } packet_queue[MAX_QUEUE];  }
51  static unsigned int queue_hi, queue_lo;  
52    void
53    sgi_check_fds(fd_set * rfds, fd_set * wfds)
54    {
55            if (output_port == (ALport) 0)
56                    return;
57    
58  BOOL          if (!rdpsnd_queue_empty())
59  wave_out_open(void)                  sgi_play();
60    }
61    
62    RD_BOOL
63    sgi_open(void)
64  {  {
65          ALparamInfo pinfo;          ALparamInfo pinfo;
66            static int warned = 0;
67    
68  #if (defined(IRIX_DEBUG))  #if (defined(IRIX_DEBUG))
69          fprintf(stderr, "wave_out_open: begin\n");          fprintf(stderr, "sgi_open: begin\n");
70  #endif  #endif
71    
72            if (!warned && sgi_output_device)
73            {
74                    warning("device-options not supported for libao-driver\n");
75                    warned = 1;
76            }
77    
78          if (alGetParamInfo(AL_DEFAULT_OUTPUT, AL_GAIN, &pinfo) < 0)          if (alGetParamInfo(AL_DEFAULT_OUTPUT, AL_GAIN, &pinfo) < 0)
79          {          {
80                  fprintf(stderr, "wave_out_open: alGetParamInfo failed: %s\n",                  fprintf(stderr, "sgi_open: alGetParamInfo failed: %s\n",
81                          alGetErrorString(oserror()));                          alGetErrorString(oserror()));
82          }          }
83          min_volume = alFixedToDouble(pinfo.min.ll);          min_volume = alFixedToDouble(pinfo.min.ll);
84          max_volume = alFixedToDouble(pinfo.max.ll);          max_volume = alFixedToDouble(pinfo.max.ll);
85          volume_range = (max_volume - min_volume);          volume_range = (max_volume - min_volume);
86  #if (defined(IRIX_DEBUG))  #if (defined(IRIX_DEBUG))
87          fprintf(stderr, "wave_out_open: minvol = %lf, maxvol= %lf, range = %lf.\n",          fprintf(stderr, "sgi_open: minvol = %lf, maxvol= %lf, range = %lf.\n",
88                  min_volume, max_volume, volume_range);                  min_volume, max_volume, volume_range);
89  #endif  #endif
90    
         queue_lo = queue_hi = 0;  
   
91          audioconfig = alNewConfig();          audioconfig = alNewConfig();
92          if (audioconfig < 0)          if (audioconfig == (ALconfig) 0)
93          {          {
94                  fprintf(stderr, "wave_out_open: alNewConfig failed: %s\n",                  fprintf(stderr, "sgi_open: alNewConfig failed: %s\n", alGetErrorString(oserror()));
                         alGetErrorString(oserror()));  
95                  return False;                  return False;
96          }          }
97    
98          output_port = alOpenPort("rdpsnd", "w", 0);          output_port = alOpenPort("rdpsnd", "w", 0);
99          if (output_port == (ALport) 0)          if (output_port == (ALport) 0)
100          {          {
101                  fprintf(stderr, "wave_out_open: alOpenPort failed: %s\n",                  fprintf(stderr, "sgi_open: alOpenPort failed: %s\n", alGetErrorString(oserror()));
                         alGetErrorString(oserror()));  
102                  return False;                  return False;
103          }          }
104    
105  #if (defined(IRIX_DEBUG))  #if (defined(IRIX_DEBUG))
106          fprintf(stderr, "wave_out_open: returning\n");          fprintf(stderr, "sgi_open: returning\n");
107  #endif  #endif
108          return True;          return True;
109  }  }
110    
111  void  void
112  wave_out_close(void)  sgi_close(void)
113  {  {
114          /* Ack all remaining packets */          /* Ack all remaining packets */
115  #if (defined(IRIX_DEBUG))  #if (defined(IRIX_DEBUG))
116          fprintf(stderr, "wave_out_close: begin\n");          fprintf(stderr, "sgi_close: begin\n");
117  #endif  #endif
118    
119          while (queue_lo != queue_hi)          while (!rdpsnd_queue_empty())
120          {                  rdpsnd_queue_next(0);
                 rdpsnd_send_completion(packet_queue[queue_lo].tick, packet_queue[queue_lo].index);  
                 free(packet_queue[queue_lo].s.data);  
                 queue_lo = (queue_lo + 1) % MAX_QUEUE;  
         }  
121          alDiscardFrames(output_port, 0);          alDiscardFrames(output_port, 0);
122    
123          alClosePort(output_port);          alClosePort(output_port);
124            output_port = (ALport) 0;
125          alFreeConfig(audioconfig);          alFreeConfig(audioconfig);
126  #if (defined(IRIX_DEBUG))  #if (defined(IRIX_DEBUG))
127          fprintf(stderr, "wave_out_close: returning\n");          fprintf(stderr, "sgi_close: returning\n");
128  #endif  #endif
129  }  }
130    
131  BOOL  RD_BOOL
132  wave_out_format_supported(WAVEFORMATEX * pwfx)  sgi_format_supported(RD_WAVEFORMATEX * pwfx)
133  {  {
134          if (pwfx->wFormatTag != WAVE_FORMAT_PCM)          if (pwfx->wFormatTag != WAVE_FORMAT_PCM)
135                  return False;                  return False;
# Line 135  wave_out_format_supported(WAVEFORMATEX * Line 141  wave_out_format_supported(WAVEFORMATEX *
141          return True;          return True;
142  }  }
143    
144  BOOL  RD_BOOL
145  wave_out_set_format(WAVEFORMATEX * pwfx)  sgi_set_format(RD_WAVEFORMATEX * pwfx)
146  {  {
147          int channels;          int channels;
148          int frameSize, channelCount;          int frameSize, channelCount;
149          ALpv params;          ALpv params;
150    
151  #if (defined(IRIX_DEBUG))  #if (defined(IRIX_DEBUG))
152          fprintf(stderr, "wave_out_set_format: init...\n");          fprintf(stderr, "sgi_set_format: init...\n");
153  #endif  #endif
         /* limited support to configure an opened audio port in IRIX */  
         /* have to reopen the audio port, using same config */  
         alClosePort(output_port);  
   
         g_swapaudio = False;  
154    
155          if (pwfx->wBitsPerSample == 8)          if (pwfx->wBitsPerSample == 8)
156                  width = AL_SAMPLE_8;                  width = AL_SAMPLE_8;
157          else if (pwfx->wBitsPerSample == 16)          else if (pwfx->wBitsPerSample == 16)
         {  
158                  width = AL_SAMPLE_16;                  width = AL_SAMPLE_16;
                 /* Do we need to swap the 16bit values? (Are we BigEndian) */  
 #if (defined(IRIX_DEBUG))  
                 g_swapaudio = 1;  
 #else  
                 g_swapaudio = 0;  
 #endif  
         }  
159    
160          g_samplewidth = pwfx->wBitsPerSample / 8;          /* Limited support to configure an opened audio port in IRIX.  The
161               number of channels is a static setting and can not be changed after
162               a port is opened.  So if the number of channels remains the same, we
163               can configure other settings; otherwise we have to reopen the audio
164               port, using same config. */
165    
166          channels = pwfx->nChannels;          channels = pwfx->nChannels;
167          g_snd_rate = pwfx->nSamplesPerSec;          g_snd_rate = pwfx->nSamplesPerSec;
168    
169          alSetSampFmt(audioconfig, AL_SAMPFMT_TWOSCOMP);          alSetSampFmt(audioconfig, AL_SAMPFMT_TWOSCOMP);
170          alSetWidth(audioconfig, width);          alSetWidth(audioconfig, width);
171          alSetChannels(audioconfig, channels);          if (channels != alGetChannels(audioconfig))
172            {
173                    alClosePort(output_port);
174                    alSetChannels(audioconfig, channels);
175                    output_port = alOpenPort("rdpsnd", "w", audioconfig);
176    
177          output_port = alOpenPort("rdpsnd", "w", audioconfig);                  if (output_port == (ALport) 0)
178                    {
179                            fprintf(stderr, "sgi_set_format: alOpenPort failed: %s\n",
180                                    alGetErrorString(oserror()));
181                            return False;
182                    }
183    
         if (output_port == (ALport) 0)  
         {  
                 fprintf(stderr, "wave_out_set_format: alOpenPort failed: %s\n",  
                         alGetErrorString(oserror()));  
                 return False;  
184          }          }
185    
186          resource = alGetResource(output_port);          resource = alGetResource(output_port);
# Line 188  wave_out_set_format(WAVEFORMATEX * pwfx) Line 190  wave_out_set_format(WAVEFORMATEX * pwfx)
190    
191          if (frameSize == 0 || channelCount == 0)          if (frameSize == 0 || channelCount == 0)
192          {          {
193                  fprintf(stderr, "wave_out_set_format: bad frameSize or channelCount\n");                  fprintf(stderr, "sgi_set_format: bad frameSize or channelCount\n");
194                  return False;                  return False;
195          }          }
196          combinedFrameSize = frameSize * channelCount;          combinedFrameSize = frameSize * channelCount;
# Line 209  wave_out_set_format(WAVEFORMATEX * pwfx) Line 211  wave_out_set_format(WAVEFORMATEX * pwfx)
211          }          }
212    
213  #if (defined(IRIX_DEBUG))  #if (defined(IRIX_DEBUG))
214          fprintf(stderr, "wave_out_set_format: returning...\n");          fprintf(stderr, "sgi_set_format: returning...\n");
215  #endif  #endif
216          return True;          return True;
217  }  }
218    
219  void  void
220  wave_out_volume(uint16 left, uint16 right)  sgi_volume(uint16 left, uint16 right)
221  {  {
222          double gainleft, gainright;          double gainleft, gainright;
223          ALpv pv[1];          ALpv pv[1];
224          ALfixed gain[8];          ALfixed gain[8];
225    
226  #if (defined(IRIX_DEBUG))  #if (defined(IRIX_DEBUG))
227          fprintf(stderr, "wave_out_volume: begin\n");          fprintf(stderr, "sgi_volume: begin\n");
228          fprintf(stderr, "left='%d', right='%d'\n", left, right);          fprintf(stderr, "left='%d', right='%d'\n", left, right);
229  #endif  #endif
230    
# Line 237  wave_out_volume(uint16 left, uint16 righ Line 239  wave_out_volume(uint16 left, uint16 righ
239          pv[0].sizeIn = 8;          pv[0].sizeIn = 8;
240          if (alSetParams(AL_DEFAULT_OUTPUT, pv, 1) < 0)          if (alSetParams(AL_DEFAULT_OUTPUT, pv, 1) < 0)
241          {          {
242                  fprintf(stderr, "wave_out_volume: alSetParams failed: %s\n",                  fprintf(stderr, "sgi_volume: alSetParams failed: %s\n",
243                          alGetErrorString(oserror()));                          alGetErrorString(oserror()));
244                  return;                  return;
245          }          }
246    
247  #if (defined(IRIX_DEBUG))  #if (defined(IRIX_DEBUG))
248          fprintf(stderr, "wave_out_volume: returning\n");          fprintf(stderr, "sgi_volume: returning\n");
249  #endif  #endif
250  }  }
251    
252  void  void
253  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)  
254  {  {
255          struct audio_packet *packet;          struct audio_packet *packet;
256          ssize_t len;          ssize_t len;
257          unsigned int i;          unsigned int i;
         uint8 swap;  
258          STREAM out;          STREAM out;
         static long startedat_us;  
         static long startedat_s;  
         static BOOL started = 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())
                 {  
                         g_dsp_busy = False;  
264                          return;                          return;
                 }  
265    
266                  packet = &packet_queue[queue_lo];                  packet = rdpsnd_queue_current_packet();
267                  out = &packet->s;                  out = &packet->s;
268    
                 /* Swap the current packet, but only once */  
                 if (g_swapaudio && !swapped)  
                 {  
                         for (i = 0; i < out->end - out->p; i += 2)  
                         {  
                                 swap = *(out->p + i);  
                                 *(out->p + i) = *(out->p + i + 1);  
                                 *(out->p + i + 1) = swap;  
                         }  
                         swapped = True;  
                 }  
   
                 if (!started)  
                 {  
                         gettimeofday(&tv, NULL);  
                         startedat_us = tv.tv_usec;  
                         startedat_s = tv.tv_sec;  
                         started = True;  
                 }  
   
269                  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  
                 }  
270    
271                  alWriteFrames(output_port, out->p, len / combinedFrameSize);                  alWriteFrames(output_port, out->p, len / combinedFrameSize);
272    
273                  out->p += len;                  out->p += len;
274                  if (out->p == out->end)                  if (out->p == out->end)
275                  {                  {
276                          long long duration;                          gf = alGetFilled(output_port);
277                          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)  
278                          {                          {
279                                  rdpsnd_send_completion(packet->tick, packet->index);                                  rdpsnd_queue_next(0);
                                 free(out->data);  
                                 queue_lo = (queue_lo + 1) % MAX_QUEUE;  
                                 started = False;  
                                 swapped = False;  
280                          }                          }
281                          else                          else
282                          {                          {
283  #if (defined(IRIX_DEBUG))  #if (defined(IRIX_DEBUG))
284                                  /* fprintf(stderr,"Busy playing...\n"); */  /*                              fprintf(stderr,"Busy playing...\n"); */
285  #endif  #endif
286                                  g_dsp_busy = True;                                  usleep(10);
287                                  return;                                  return;
288                          }                          }
289                  }                  }
290          }          }
291  }  }
292    
293    struct audio_driver *
294    sgi_register(char *options)
295    {
296            static struct audio_driver sgi_driver;
297    
298            memset(&sgi_driver, 0, sizeof(sgi_driver));
299    
300            sgi_driver.name = "sgi";
301            sgi_driver.description = "SGI output driver";
302    
303            sgi_driver.add_fds = sgi_add_fds;
304            sgi_driver.check_fds = sgi_check_fds;
305    
306            sgi_driver.wave_out_open = sgi_open;
307            sgi_driver.wave_out_close = sgi_close;
308            sgi_driver.wave_out_format_supported = sgi_format_supported;
309            sgi_driver.wave_out_set_format = sgi_set_format;
310            sgi_driver.wave_out_volume = sgi_volume;
311    
312            sgi_driver.need_byteswap_on_be = 1;
313            sgi_driver.need_resampling = 0;
314    
315            if (options)
316            {
317                    sgi_output_device = xstrdup(options);
318            }
319            return &sgi_driver;
320    }

Legend:
Removed from v.865  
changed lines
  Added in v.1475

  ViewVC Help
Powered by ViewVC 1.1.26