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

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

revision 1253 by stargo, Sun Sep 17 10:00:55 2006 UTC revision 1254 by stargo, Sun Sep 17 10:32:18 2006 UTC
# 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>
# Line 28  Line 29 
29  #include <sys/time.h>  #include <sys/time.h>
30    
31  #define DEFAULTDEVICE   "default"  #define DEFAULTDEVICE   "default"
 #define MAX_QUEUE       10  
32  #define MAX_FRAMES      32  #define MAX_FRAMES      32
33    
 int g_dsp_fd;  
 BOOL g_dsp_busy = False;  
34  static snd_pcm_t *pcm_handle = NULL;  static snd_pcm_t *pcm_handle = NULL;
35  static snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK;  static snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK;
36  static BOOL reopened;  static BOOL reopened;
37  static short samplewidth;  static short samplewidth;
38  static int audiochannels;  static int audiochannels;
39    
 static struct audio_packet  
 {  
         struct stream s;  
         uint16 tick;  
         uint8 index;  
 } packet_queue[MAX_QUEUE];  
 static unsigned int queue_hi, queue_lo;  
   
40  BOOL  BOOL
41  wave_out_open(void)  wave_out_open(void)
42  {  {
# Line 62  wave_out_open(void) Line 52  wave_out_open(void)
52          }          }
53    
54          g_dsp_fd = 0;          g_dsp_fd = 0;
55          queue_lo = queue_hi = 0;          rdpsnd_queue_init();
56    
57          reopened = True;          reopened = True;
58    
# Line 73  void Line 63  void
63  wave_out_close(void)  wave_out_close(void)
64  {  {
65          /* Ack all remaining packets */          /* Ack all remaining packets */
66          while (queue_lo != queue_hi)          while (!rdpsnd_queue_empty())
67          {          {
68                  rdpsnd_send_completion(packet_queue[queue_lo].tick, packet_queue[queue_lo].index);                  rdpsnd_send_completion(rdpsnd_queue_current_packet()->tick,
69                  free(packet_queue[queue_lo].s.data);                                         rdpsnd_queue_current_packet()->index);
70                  queue_lo = (queue_lo + 1) % MAX_QUEUE;                  rdpsnd_queue_next();
71          }          }
72    
73    
74          if (pcm_handle)          if (pcm_handle)
75          {          {
76                  snd_pcm_drop(pcm_handle);                  snd_pcm_drop(pcm_handle);
# Line 231  wave_out_volume(uint16 left, uint16 righ Line 222  wave_out_volume(uint16 left, uint16 righ
222  }  }
223    
224  void  void
 wave_out_write(STREAM s, uint16 tick, uint8 index)  
 {  
         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 = (uint8 *) malloc(s->size);  
   
         if (!g_dsp_busy)  
                 wave_out_play();  
 }  
   
 void  
225  wave_out_play(void)  wave_out_play(void)
226  {  {
227          struct audio_packet *packet;          struct audio_packet *packet;
# Line 275  wave_out_play(void) Line 240  wave_out_play(void)
240                  prev_us = tv.tv_usec;                  prev_us = tv.tv_usec;
241          }          }
242    
243          if (queue_lo == queue_hi)          if (rdpsnd_queue_empty())
244          {          {
245                  g_dsp_busy = 0;                  g_dsp_busy = 0;
246                  return;                  return;
247          }          }
248    
249          packet = &packet_queue[queue_lo];          packet = rdpsnd_queue_current_packet();
250          out = &packet->s;          out = &packet->s;
251    
252          if (((queue_lo + 1) % MAX_QUEUE) != queue_hi)          next_tick = rdpsnd_queue_next_tick();
         {  
                 next_tick = packet_queue[(queue_lo + 1) % MAX_QUEUE].tick;  
         }  
         else  
         {  
                 next_tick = (packet->tick + 65535) % 65536;  
         }  
253    
254          len = (out->end - out->p) / (samplewidth * audiochannels);          len = (out->end - out->p) / (samplewidth * audiochannels);
255          if ((len = snd_pcm_writei(pcm_handle, out->p, ((MAX_FRAMES < len) ? MAX_FRAMES : len))) < 0)          if ((len = snd_pcm_writei(pcm_handle, out->p, ((MAX_FRAMES < len) ? MAX_FRAMES : len))) < 0)
# Line 320  wave_out_play(void) Line 278  wave_out_play(void)
278                                 (packet->tick + duration) % 65536, next_tick % 65536));                                 (packet->tick + duration) % 65536, next_tick % 65536));
279                  }                  }
280    
281                  /* Until all drivers are using the windows sound-ticks, we need to                  rdpsnd_send_completion(((packet->tick + duration) % 65536), packet->index);
282                     substract the 50 ticks added later by rdpsnd.c */                  rdpsnd_queue_next();
                 rdpsnd_send_completion(((packet->tick + duration) % 65536) - 50, packet->index);  
                 free(out->data);  
                 queue_lo = (queue_lo + 1) % MAX_QUEUE;  
283          }          }
284    
285          g_dsp_busy = 1;          g_dsp_busy = 1;

Legend:
Removed from v.1253  
changed lines
  Added in v.1254

  ViewVC Help
Powered by ViewVC 1.1.26