/[rdesktop]/jpeg/rdesktop/trunk/rdpsnd_sun.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 /jpeg/rdesktop/trunk/rdpsnd_sun.c

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

revision 504 by stargo, Sun Oct 19 11:59:41 2003 UTC revision 1260 by stargo, Sun Sep 17 15:25:10 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 - Sun     Sound Channel Process Functions - Sun
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) Michael Gernoth mike@zerfleddert.de 2003     Copyright (C) Michael Gernoth mike@zerfleddert.de 2003-2006
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 21  Line 21 
21  */  */
22    
23  #include "rdesktop.h"  #include "rdesktop.h"
24    #include "rdpsnd.h"
25  #include <unistd.h>  #include <unistd.h>
26  #include <fcntl.h>  #include <fcntl.h>
27  #include <errno.h>  #include <errno.h>
28  #include <sys/ioctl.h>  #include <sys/ioctl.h>
29  #include <sys/audioio.h>  #include <sys/audioio.h>
 #include <stropts.h>  
30    
31  #define MAX_QUEUE       10  #if (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
32    #include <stropts.h>
33    #endif
34    
35  int g_dsp_fd;  #define DEFAULTDEVICE   "/dev/audio"
 BOOL g_dsp_busy = False;  
 static BOOL reopened;  
 static BOOL swapaudio;  
 static short samplewidth;  
36    
37  static struct audio_packet  static BOOL g_reopened;
38  {  static short g_samplewidth;
39          struct stream s;  static char *dsp_dev;
         uint16 tick;  
         uint8 index;  
 } packet_queue[MAX_QUEUE];  
 static unsigned int queue_hi, queue_lo;  
40    
41  BOOL  BOOL
42  wave_out_open(void)  sun_open(void)
43  {  {
         char *dsp_dev = getenv("AUDIODEV");  
   
         if (dsp_dev == NULL)  
         {  
                 dsp_dev = "/dev/audio";  
         }  
   
44          if ((g_dsp_fd = open(dsp_dev, O_WRONLY | O_NONBLOCK)) == -1)          if ((g_dsp_fd = open(dsp_dev, O_WRONLY | O_NONBLOCK)) == -1)
45          {          {
46                  perror(dsp_dev);                  perror(dsp_dev);
# Line 63  wave_out_open(void) Line 50  wave_out_open(void)
50          /* Non-blocking so that user interface is responsive */          /* Non-blocking so that user interface is responsive */
51          fcntl(g_dsp_fd, F_SETFL, fcntl(g_dsp_fd, F_GETFL) | O_NONBLOCK);          fcntl(g_dsp_fd, F_SETFL, fcntl(g_dsp_fd, F_GETFL) | O_NONBLOCK);
52    
53          queue_lo = queue_hi = 0;          rdpsnd_queue_init();
54          reopened = True;          g_reopened = True;
55    
56          return True;          return True;
57  }  }
58    
59  void  void
60  wave_out_close(void)  sun_close(void)
61  {  {
62          /* Ack all remaining packets */          /* Ack all remaining packets */
63          while (queue_lo != queue_hi)          while (!rdpsnd_queue_empty())
64          {          {
65                  rdpsnd_send_completion(packet_queue[queue_lo].tick, packet_queue[queue_lo].index);                  rdpsnd_send_completion(rdpsnd_queue_current_packet()->tick,
66                  free(packet_queue[queue_lo].s.data);                                         rdpsnd_queue_current_packet()->index);
67                  queue_lo = (queue_lo + 1) % MAX_QUEUE;                  rdpsnd_queue_next();
68          }          }
69    
70    #if defined I_FLUSH && defined FLUSHW
71          /* Flush the audiobuffer */          /* Flush the audiobuffer */
72          ioctl(g_dsp_fd, I_FLUSH, FLUSHW);          ioctl(g_dsp_fd, I_FLUSH, FLUSHW);
73    #endif
74    #if defined AUDIO_FLUSH
75            ioctl(g_dsp_fd, AUDIO_FLUSH, NULL);
76    #endif
77          close(g_dsp_fd);          close(g_dsp_fd);
78  }  }
79    
80  BOOL  BOOL
81  wave_out_format_supported(WAVEFORMATEX * pwfx)  sun_format_supported(WAVEFORMATEX * pwfx)
82  {  {
83          if (pwfx->wFormatTag != WAVE_FORMAT_PCM)          if (pwfx->wFormatTag != WAVE_FORMAT_PCM)
84                  return False;                  return False;
# Line 99  wave_out_format_supported(WAVEFORMATEX * Line 91  wave_out_format_supported(WAVEFORMATEX *
91  }  }
92    
93  BOOL  BOOL
94  wave_out_set_format(WAVEFORMATEX * pwfx)  sun_set_format(WAVEFORMATEX * pwfx)
95  {  {
96          audio_info_t info;          audio_info_t info;
         int test = 1;  
97    
98          ioctl(g_dsp_fd, AUDIO_DRAIN, 0);          ioctl(g_dsp_fd, AUDIO_DRAIN, 0);
         swapaudio = False;  
99          AUDIO_INITINFO(&info);          AUDIO_INITINFO(&info);
100    
101    
# Line 116  wave_out_set_format(WAVEFORMATEX * pwfx) Line 106  wave_out_set_format(WAVEFORMATEX * pwfx)
106          else if (pwfx->wBitsPerSample == 16)          else if (pwfx->wBitsPerSample == 16)
107          {          {
108                  info.play.encoding = AUDIO_ENCODING_LINEAR;                  info.play.encoding = AUDIO_ENCODING_LINEAR;
                 /* Do we need to swap the 16bit values? (Are we BigEndian) */  
                 swapaudio = !(*(uint8 *) (&test));  
109          }          }
110    
111          samplewidth = pwfx->wBitsPerSample / 8;          g_samplewidth = pwfx->wBitsPerSample / 8;
112    
113          if (pwfx->nChannels == 1)          if (pwfx->nChannels == 1)
114          {          {
115                  info.play.channels = AUDIO_CHANNELS_MONO;                  info.play.channels = 1;
116          }          }
117          else if (pwfx->nChannels == 2)          else if (pwfx->nChannels == 2)
118          {          {
119                  info.play.channels = AUDIO_CHANNELS_STEREO;                  info.play.channels = 2;
120                  samplewidth *= 2;                  g_samplewidth *= 2;
121          }          }
122    
123          info.play.sample_rate = pwfx->nSamplesPerSec;          info.play.sample_rate = pwfx->nSamplesPerSec;
# Line 137  wave_out_set_format(WAVEFORMATEX * pwfx) Line 125  wave_out_set_format(WAVEFORMATEX * pwfx)
125          info.play.samples = 0;          info.play.samples = 0;
126          info.play.eof = 0;          info.play.eof = 0;
127          info.play.error = 0;          info.play.error = 0;
128          reopened = True;          g_reopened = True;
129    
130          if (ioctl(g_dsp_fd, AUDIO_SETINFO, &info) == -1)          if (ioctl(g_dsp_fd, AUDIO_SETINFO, &info) == -1)
131          {          {
# Line 150  wave_out_set_format(WAVEFORMATEX * pwfx) Line 138  wave_out_set_format(WAVEFORMATEX * pwfx)
138  }  }
139    
140  void  void
141  wave_out_volume(uint16 left, uint16 right)  sun_volume(uint16 left, uint16 right)
142  {  {
143          audio_info_t info;          audio_info_t info;
144          uint balance;          uint balance;
145          uint volume;          uint volume;
146    
147          if (ioctl(g_dsp_fd, AUDIO_GETINFO, &info) == -1)          AUDIO_INITINFO(&info);
         {  
                 perror("AUDIO_GETINFO");  
                 return;  
         }  
148    
149          volume = (left > right) ? left : right;          volume = (left > right) ? left : right;
150    
# Line 186  wave_out_volume(uint16 left, uint16 righ Line 170  wave_out_volume(uint16 left, uint16 righ
170  }  }
171    
172  void  void
173  wave_out_write(STREAM s, uint16 tick, uint8 index)  sun_play(void)
 {  
         struct audio_packet *packet = &packet_queue[queue_hi];  
         unsigned int next_hi = (queue_hi + 1) % MAX_QUEUE;  
   
         if (next_hi == queue_lo)  
         {  
                 error("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)  
174  {  {
175          struct audio_packet *packet;          struct audio_packet *packet;
176          audio_info_t info;          audio_info_t info;
177          ssize_t len;          ssize_t len;
178          unsigned int i;          unsigned int i;
         uint8 swap;  
179          STREAM out;          STREAM out;
         static BOOL swapped = False;  
180          static BOOL sentcompletion = True;          static BOOL sentcompletion = True;
181          static uint32 samplecnt = 0;          static uint32 samplecnt = 0;
182          static uint32 numsamples;          static uint32 numsamples;
183    
184          while (1)          while (1)
185          {          {
186                  if (reopened)                  if (g_reopened)
187                  {                  {
188                          /* Device was just (re)openend */                          /* Device was just (re)openend */
189                          samplecnt = 0;                          samplecnt = 0;
                         swapped = False;  
190                          sentcompletion = True;                          sentcompletion = True;
191                          reopened = False;                          g_reopened = False;
192                  }                  }
193    
194                  if (queue_lo == queue_hi)                  if (rdpsnd_queue_empty())
195                  {                  {
196                          g_dsp_busy = 0;                          g_dsp_busy = 0;
197                          return;                          return;
198                  }                  }
199    
200                  packet = &packet_queue[queue_lo];                  packet = rdpsnd_queue_current_packet();
201                  out = &packet->s;                  out = &packet->s;
202    
                 /* Swap the current packet, but only once */  
                 if (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;  
                 }  
   
203                  if (sentcompletion)                  if (sentcompletion)
204                  {                  {
205                          sentcompletion = False;                          sentcompletion = False;
206                          numsamples = (out->end - out->p) / samplewidth;                          numsamples = (out->end - out->p) / g_samplewidth;
207                  }                  }
208    
209                  len = 0;                  len = 0;
# Line 290  wave_out_play(void) Line 233  wave_out_play(void)
233                          if (info.play.samples >= samplecnt + ((numsamples * 7) / 10))                          if (info.play.samples >= samplecnt + ((numsamples * 7) / 10))
234                          {                          {
235                                  samplecnt += numsamples;                                  samplecnt += numsamples;
236                                  rdpsnd_send_completion(packet->tick, packet->index);                                  /* We need to add 50 to tell windows that time has passed while
237                                  free(out->data);                                   * playing this packet */
238                                  queue_lo = (queue_lo + 1) % MAX_QUEUE;                                  rdpsnd_send_completion(packet->tick + 50, packet->index);
239                                  swapped = False;                                  rdpsnd_queue_next();
240                                  sentcompletion = True;                                  sentcompletion = True;
241                          }                          }
242                          else                          else
# Line 304  wave_out_play(void) Line 247  wave_out_play(void)
247                  }                  }
248          }          }
249  }  }
250    
251    struct audio_driver *
252    sun_register(char *options)
253    {
254            static struct audio_driver sun_driver;
255    
256            sun_driver.wave_out_write = rdpsnd_queue_write;
257            sun_driver.wave_out_open = sun_open;
258            sun_driver.wave_out_close = sun_close;
259            sun_driver.wave_out_format_supported = sun_format_supported;
260            sun_driver.wave_out_set_format = sun_set_format;
261            sun_driver.wave_out_volume = sun_volume;
262            sun_driver.wave_out_play = sun_play;
263            sun_driver.name = xstrdup("sun");
264            sun_driver.description =
265                    xstrdup("SUN/BSD output driver, default device: " DEFAULTDEVICE " or $AUDIODEV");
266            sun_driver.need_byteswap_on_be = 1;
267            sun_driver.next = NULL;
268    
269            if (options)
270            {
271                    dsp_dev = xstrdup(options);
272            }
273            else
274            {
275                    dsp_dev = getenv("AUDIODEV");
276    
277                    if (dsp_dev == NULL)
278                    {
279                            dsp_dev = xstrdup(DEFAULTDEVICE);
280                    }
281            }
282    
283            return &sun_driver;
284    }

Legend:
Removed from v.504  
changed lines
  Added in v.1260

  ViewVC Help
Powered by ViewVC 1.1.26