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

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

revision 1286 by stargo, Sun Oct 1 18:47:04 2006 UTC revision 1302 by ossman_, Thu Oct 26 09:47:17 2006 UTC
# Line 33  Line 33 
33  #include <unistd.h>  #include <unistd.h>
34  #include <fcntl.h>  #include <fcntl.h>
35  #include <errno.h>  #include <errno.h>
36    #include <unistd.h>
37  #include <sys/time.h>  #include <sys/time.h>
38  #include <sys/ioctl.h>  #include <sys/ioctl.h>
39  #include <sys/soundcard.h>  #include <sys/soundcard.h>
40    #include <sys/types.h>
41    #include <sys/stat.h>
42    
43  #define DEFAULTDEVICE   "/dev/dsp"  #define DEFAULTDEVICE   "/dev/dsp"
44  #define MAX_LEN         512  #define MAX_LEN         512
# Line 44  static int snd_rate; Line 47  static int snd_rate;
47  static short samplewidth;  static short samplewidth;
48  static char *dsp_dev;  static char *dsp_dev;
49  static struct audio_driver oss_driver;  static struct audio_driver oss_driver;
50    static BOOL in_esddsp;
51    
52    static BOOL
53    detect_esddsp(void)
54    {
55            struct stat s;
56            char *preload;
57    
58            if (fstat(g_dsp_fd, &s) == -1)
59                    return False;
60    
61            if (S_ISCHR(s.st_mode) || S_ISBLK(s.st_mode))
62                    return False;
63    
64            preload = getenv("LD_PRELOAD");
65            if (preload == NULL)
66                    return False;
67    
68            if (strstr(preload, "esddsp") == NULL)
69                    return False;
70    
71            return True;
72    }
73    
74  BOOL  BOOL
75  oss_open(void)  oss_open(void)
# Line 54  oss_open(void) Line 80  oss_open(void)
80                  return False;                  return False;
81          }          }
82    
83            in_esddsp = detect_esddsp();
84    
85          return True;          return True;
86  }  }
87    
# Line 202  oss_play(void) Line 230  oss_play(void)
230          struct audio_packet *packet;          struct audio_packet *packet;
231          ssize_t len;          ssize_t len;
232          STREAM out;          STREAM out;
         static long startedat_us;  
         static long startedat_s;  
         static BOOL started = False;  
         struct timeval tv;  
233    
234          if (rdpsnd_queue_empty())          if (rdpsnd_queue_empty())
235          {          {
# Line 216  oss_play(void) Line 240  oss_play(void)
240          packet = rdpsnd_queue_current_packet();          packet = rdpsnd_queue_current_packet();
241          out = &packet->s;          out = &packet->s;
242    
         if (!started)  
         {  
                 gettimeofday(&tv, NULL);  
                 startedat_us = tv.tv_usec;  
                 startedat_s = tv.tv_sec;  
                 started = True;  
         }  
   
243          len = out->end - out->p;          len = out->end - out->p;
244    
245          len = write(g_dsp_fd, out->p, (len > MAX_LEN) ? MAX_LEN : len);          len = write(g_dsp_fd, out->p, (len > MAX_LEN) ? MAX_LEN : len);
# Line 236  oss_play(void) Line 252  oss_play(void)
252          }          }
253    
254          out->p += len;          out->p += len;
255    
256          if (out->p == out->end)          if (out->p == out->end)
257          {          {
258                  long long duration;                  int delay_bytes;
259                  long elapsed;                  unsigned long delay_us;
260                    audio_buf_info info;
261    
262                  gettimeofday(&tv, NULL);                  if (in_esddsp)
263                  duration = (out->size * (1000000 / (samplewidth * snd_rate)));                  {
264                  elapsed = (tv.tv_sec - startedat_s) * 1000000 + (tv.tv_usec - startedat_us);                          /* EsounD has no way of querying buffer status, so we have to
265                             * go with a fixed size. */
266                  if (elapsed >= (duration * 85) / 100)                          delay_bytes = out->size;
                 {  
                         /* We need to add 50 to tell windows that time has passed while  
                          * playing this packet */  
                         rdpsnd_send_completion(packet->tick + 50, packet->index);  
                         rdpsnd_queue_next();  
                         started = False;  
267                  }                  }
268                  else                  else
269                  {                  {
270                          g_dsp_busy = 1;  #ifdef SNDCTL_DSP_GETODELAY
271                          return;                          delay_bytes = 0;
272                            if (ioctl(g_dsp_fd, SNDCTL_DSP_GETODELAY, &delay_bytes) == -1)
273                                    delay_bytes = -1;
274    #else
275                            delay_bytes = -1;
276    #endif
277    
278                            if (delay_bytes == -1)
279                            {
280                                    if (ioctl(g_dsp_fd, SNDCTL_DSP_GETOSPACE, &info) != -1)
281                                            delay_bytes = info.fragstotal * info.fragsize - info.bytes;
282                                    else
283                                            delay_bytes = out->size;
284                            }
285                  }                  }
286    
287                    delay_us = delay_bytes * (1000000 / (samplewidth * snd_rate));
288                    rdpsnd_queue_next(delay_us);
289          }          }
290          g_dsp_busy = 1;          else
291            {
292                    g_dsp_busy = 1;
293            }
294    
295          return;          return;
296  }  }
297    
298  struct audio_driver *  struct audio_driver *
299  oss_register(char *options)  oss_register(char *options)
300  {  {
         oss_driver.wave_out_write = rdpsnd_queue_write;  
301          oss_driver.wave_out_open = oss_open;          oss_driver.wave_out_open = oss_open;
302          oss_driver.wave_out_close = oss_close;          oss_driver.wave_out_close = oss_close;
303          oss_driver.wave_out_format_supported = oss_format_supported;          oss_driver.wave_out_format_supported = oss_format_supported;

Legend:
Removed from v.1286  
changed lines
  Added in v.1302

  ViewVC Help
Powered by ViewVC 1.1.26