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

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

revision 476 by matthewc, Sat Oct 4 00:03:24 2003 UTC revision 560 by stargo, Thu Dec 11 14:59:54 2003 UTC
# Line 25  Line 25 
25  #include <fcntl.h>  #include <fcntl.h>
26  #include <errno.h>  #include <errno.h>
27  #include <sys/ioctl.h>  #include <sys/ioctl.h>
28  #include <sys/audio.h>  #include <sys/audioio.h>
29    
30    #if (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
31  #include <stropts.h>  #include <stropts.h>
32    #endif
33    
34  #define MAX_QUEUE       10  #define MAX_QUEUE       10
35    
36  int g_dsp_fd;  int g_dsp_fd;
37  BOOL g_dsp_busy;  BOOL g_dsp_busy = False;
38  static BOOL swapaudio;  static BOOL g_reopened;
39  static short samplewidth;  static BOOL g_swapaudio;
40    static short g_samplewidth;
41    
42  static struct audio_packet {  static struct audio_packet
43    {
44          struct stream s;          struct stream s;
45          uint16 tick;          uint16 tick;
46          uint8 index;          uint8 index;
# Line 45  static unsigned int queue_hi, queue_lo; Line 50  static unsigned int queue_hi, queue_lo;
50  BOOL  BOOL
51  wave_out_open(void)  wave_out_open(void)
52  {  {
53          char *dsp_dev = "/dev/audio";          char *dsp_dev = getenv("AUDIODEV");
54    
55            if (dsp_dev == NULL)
56            {
57                    dsp_dev = "/dev/audio";
58            }
59    
60          if ((g_dsp_fd = open(dsp_dev, O_WRONLY|O_NONBLOCK)) == -1)          if ((g_dsp_fd = open(dsp_dev, O_WRONLY | O_NONBLOCK)) == -1)
61          {          {
62                  perror(dsp_dev);                  perror(dsp_dev);
63                  return False;                  return False;
64          }          }
65    
   
66          /* Non-blocking so that user interface is responsive */          /* Non-blocking so that user interface is responsive */
67          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);
68    
69          queue_lo = queue_hi = 0;          queue_lo = queue_hi = 0;
70            g_reopened = True;
71    
72          return True;          return True;
73  }  }
74    
75  void  void
76  wave_out_close(void)  wave_out_close(void)
77  {  {
78          ioctl(g_dsp_fd,I_FLUSH,FLUSHW);          /* Ack all remaining packets */
79            while (queue_lo != queue_hi)
80            {
81                    rdpsnd_send_completion(packet_queue[queue_lo].tick, packet_queue[queue_lo].index);
82                    free(packet_queue[queue_lo].s.data);
83                    queue_lo = (queue_lo + 1) % MAX_QUEUE;
84            }
85    
86    #if defined I_FLUSH && defined FLUSHW
87            /* Flush the audiobuffer */
88            ioctl(g_dsp_fd, I_FLUSH, FLUSHW);
89    #endif
90          close(g_dsp_fd);          close(g_dsp_fd);
91  }  }
92    
93  BOOL  BOOL
94  wave_out_format_supported(WAVEFORMATEX *pwfx)  wave_out_format_supported(WAVEFORMATEX * pwfx)
95  {  {
96          if (pwfx->wFormatTag != WAVE_FORMAT_PCM)          if (pwfx->wFormatTag != WAVE_FORMAT_PCM)
97                  return False;                  return False;
# Line 81  wave_out_format_supported(WAVEFORMATEX * Line 104  wave_out_format_supported(WAVEFORMATEX *
104  }  }
105    
106  BOOL  BOOL
107  wave_out_set_format(WAVEFORMATEX *pwfx)  wave_out_set_format(WAVEFORMATEX * pwfx)
108  {  {
109          audio_info_t info;          audio_info_t info;
110          int test = 1;          int test = 1;
111    
112          ioctl(g_dsp_fd, AUDIO_DRAIN, 0);          ioctl(g_dsp_fd, AUDIO_DRAIN, 0);
113          swapaudio = False;          g_swapaudio = False;
114          AUDIO_INITINFO(&info);          AUDIO_INITINFO(&info);
115    
116    
117          if (pwfx->wBitsPerSample == 8)          if (pwfx->wBitsPerSample == 8)
118          {          {
119                  info.play.encoding = AUDIO_ENCODING_LINEAR8;                  info.play.encoding = AUDIO_ENCODING_LINEAR8;
                 samplewidth=1;  
120          }          }
121          else if (pwfx->wBitsPerSample == 16)          else if (pwfx->wBitsPerSample == 16)
122          {          {
123                  info.play.encoding = AUDIO_ENCODING_LINEAR;                  info.play.encoding = AUDIO_ENCODING_LINEAR;
124                  swapaudio = !(*(uint8 *) (&test));                  /* Do we need to swap the 16bit values? (Are we BigEndian) */
125                  samplewidth=2;                  g_swapaudio = !(*(uint8 *) (&test));
126          }          }
127    
128          if (pwfx->nChannels == 1 )          g_samplewidth = pwfx->wBitsPerSample / 8;
129          {        
130                  info.play.channels = AUDIO_CHANNELS_MONO;          if (pwfx->nChannels == 1)
131            {
132                    info.play.channels = 1;
133          }          }
134          else if (pwfx->nChannels == 2 )          else if (pwfx->nChannels == 2)
135          {          {
136                  info.play.channels = AUDIO_CHANNELS_STEREO;                  info.play.channels = 2;
137                  samplewidth*=2;                  g_samplewidth *= 2;
138          }          }
139    
140          info.play.sample_rate = pwfx->nSamplesPerSec;          info.play.sample_rate = pwfx->nSamplesPerSec;
# Line 118  wave_out_set_format(WAVEFORMATEX *pwfx) Line 142  wave_out_set_format(WAVEFORMATEX *pwfx)
142          info.play.samples = 0;          info.play.samples = 0;
143          info.play.eof = 0;          info.play.eof = 0;
144          info.play.error = 0;          info.play.error = 0;
145            g_reopened = True;
146    
147          if (ioctl(g_dsp_fd, AUDIO_SETINFO, &info) == -1)          if (ioctl(g_dsp_fd, AUDIO_SETINFO, &info) == -1)
148          {          {
# Line 130  wave_out_set_format(WAVEFORMATEX *pwfx) Line 155  wave_out_set_format(WAVEFORMATEX *pwfx)
155  }  }
156    
157  void  void
158    wave_out_volume(uint16 left, uint16 right)
159    {
160            audio_info_t info;
161            uint balance;
162            uint volume;
163    
164            if (ioctl(g_dsp_fd, AUDIO_GETINFO, &info) == -1)
165            {
166                    perror("AUDIO_GETINFO");
167                    return;
168            }
169    
170            volume = (left > right) ? left : right;
171    
172            if (volume / AUDIO_MID_BALANCE != 0)
173            {
174                    balance =
175                            AUDIO_MID_BALANCE - (left / (volume / AUDIO_MID_BALANCE)) +
176                            (right / (volume / AUDIO_MID_BALANCE));
177            }
178            else
179            {
180                    balance = AUDIO_MID_BALANCE;
181            }
182    
183            info.play.gain = volume / (65536 / AUDIO_MAX_GAIN);
184            info.play.balance = balance;
185    
186            if (ioctl(g_dsp_fd, AUDIO_SETINFO, &info) == -1)
187            {
188                    perror("AUDIO_SETINFO");
189                    return;
190            }
191    }
192    
193    void
194  wave_out_write(STREAM s, uint16 tick, uint8 index)  wave_out_write(STREAM s, uint16 tick, uint8 index)
195  {  {
196          struct audio_packet *packet = &packet_queue[queue_hi];          struct audio_packet *packet = &packet_queue[queue_hi];
# Line 140  wave_out_write(STREAM s, uint16 tick, ui Line 201  wave_out_write(STREAM s, uint16 tick, ui
201                  error("No space to queue audio packet\n");                  error("No space to queue audio packet\n");
202                  return;                  return;
203          }          }
204            
205          queue_hi = next_hi;          queue_hi = next_hi;
206    
207          packet->s = *s;          packet->s = *s;
208          packet->tick = tick;          packet->tick = tick;
209          packet->index = index;          packet->index = index;
210            packet->s.p += 4;
211    
212          /* we steal the data buffer from s, give it a new one */          /* we steal the data buffer from s, give it a new one */
213          s->data = malloc(s->size);          s->data = malloc(s->size);
# Line 165  wave_out_play(void) Line 227  wave_out_play(void)
227          STREAM out;          STREAM out;
228          static BOOL swapped = False;          static BOOL swapped = False;
229          static BOOL sentcompletion = True;          static BOOL sentcompletion = True;
230          static int samplecnt;          static uint32 samplecnt = 0;
231          static int numsamples;          static uint32 numsamples;
232    
233          while (1)          while (1)
234          {          {
235                    if (g_reopened)
236                    {
237                            /* Device was just (re)openend */
238                            samplecnt = 0;
239                            swapped = False;
240                            sentcompletion = True;
241                            g_reopened = False;
242                    }
243    
244                  if (queue_lo == queue_hi)                  if (queue_lo == queue_hi)
245                  {                  {
246                          g_dsp_busy = 0;                          g_dsp_busy = 0;
# Line 179  wave_out_play(void) Line 250  wave_out_play(void)
250                  packet = &packet_queue[queue_lo];                  packet = &packet_queue[queue_lo];
251                  out = &packet->s;                  out = &packet->s;
252    
253                  if ( swapaudio && ! swapped )                  /* Swap the current packet, but only once */
254                    if (g_swapaudio && !swapped)
255                  {                  {
256                          for ( i = 0; i < out->end - out->p; i+=2 )                          for (i = 0; i < out->end - out->p; i += 2)
257                          {                          {
258                                  swap = *(out->p + i);                                  swap = *(out->p + i);
259                                  *(out->p + i ) = *(out->p + i + 1);                                  *(out->p + i) = *(out->p + i + 1);
260                                  *(out->p + i + 1) = swap;                                  *(out->p + i + 1) = swap;
                                 swapped = True;  
261                          }                          }
262                            swapped = True;
263                  }                  }
264    
265                  if ( sentcompletion )                  if (sentcompletion)
266                  {                  {
                         if (ioctl(g_dsp_fd, AUDIO_GETINFO, &info) == -1)  
                         {  
                                 perror("AUDIO_GETINFO");  
                                 return;  
                         }  
                         samplecnt=info.play.samples;  
267                          sentcompletion = False;                          sentcompletion = False;
268                          numsamples = (out->end-out->p)/samplewidth;                          numsamples = (out->end - out->p) / g_samplewidth;
269                  }                  }
270    
271                  len=0;                  len = 0;
272    
273                  if ( out->end - out->p != 0 )                  if (out->end != out->p)
274                  {                  {
275                          len = write(g_dsp_fd, out->p, out->end - out->p);                          len = write(g_dsp_fd, out->p, out->end - out->p);
276                          if (len == -1)                          if (len == -1)
# Line 224  wave_out_play(void) Line 290  wave_out_play(void)
290                                  perror("AUDIO_GETINFO");                                  perror("AUDIO_GETINFO");
291                                  return;                                  return;
292                          }                          }
293                          if ( info.play.samples >= samplecnt+(numsamples)*0.9 )  
294                            /* Ack the packet, if we have played at least 70% */
295                            if (info.play.samples >= samplecnt + ((numsamples * 7) / 10))
296                          {                          {
297                                    samplecnt += numsamples;
298                                  rdpsnd_send_completion(packet->tick, packet->index);                                  rdpsnd_send_completion(packet->tick, packet->index);
299                                  free(out->data);                                  free(out->data);
300                                  queue_lo = (queue_lo + 1) % MAX_QUEUE;                                  queue_lo = (queue_lo + 1) % MAX_QUEUE;

Legend:
Removed from v.476  
changed lines
  Added in v.560

  ViewVC Help
Powered by ViewVC 1.1.26