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

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

revision 1271 by stargo, Mon Sep 18 21:42:50 2006 UTC revision 1302 by ossman_, Thu Oct 26 09:47:17 2006 UTC
# Line 19  Line 19 
19     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  */  */
21    
22    #include <assert.h>
23    
24  #include "rdesktop.h"  #include "rdesktop.h"
25  #include "rdpsnd.h"  #include "rdpsnd.h"
26  #include "rdpsnd_dsp.h"  #include "rdpsnd_dsp.h"
# Line 45  static BOOL device_open; Line 47  static BOOL device_open;
47  static WAVEFORMATEX formats[MAX_FORMATS];  static WAVEFORMATEX formats[MAX_FORMATS];
48  static unsigned int format_count;  static unsigned int format_count;
49  static unsigned int current_format;  static unsigned int current_format;
50  unsigned int queue_hi, queue_lo;  unsigned int queue_hi, queue_lo, queue_pending;
51  struct audio_packet packet_queue[MAX_QUEUE];  struct audio_packet packet_queue[MAX_QUEUE];
52    
53  void (*wave_out_play) (void);  void (*wave_out_play) (void);
54    
55    static void rdpsnd_queue_write(STREAM s, uint16 tick, uint8 index);
56    static void rdpsnd_queue_init(void);
57    static void rdpsnd_queue_complete_pending(void);
58    static long rdpsnd_queue_next_completion(void);
59    
60  static STREAM  static STREAM
61  rdpsnd_init_packet(uint16 type, uint16 size)  rdpsnd_init_packet(uint16 type, uint16 size)
62  {  {
# Line 72  rdpsnd_send(STREAM s) Line 79  rdpsnd_send(STREAM s)
79          channel_send(s, rdpsnd_channel);          channel_send(s, rdpsnd_channel);
80  }  }
81    
82  void  static void
83  rdpsnd_send_completion(uint16 tick, uint8 packet_index)  rdpsnd_send_completion(uint16 tick, uint8 packet_index)
84  {  {
85          STREAM s;          STREAM s;
# Line 230  rdpsnd_process(STREAM s) Line 237  rdpsnd_process(STREAM s)
237                  /* Insert the 4 missing bytes retrieved from last RDPSND_WRITE */                  /* Insert the 4 missing bytes retrieved from last RDPSND_WRITE */
238                  memcpy(s->data, missing_bytes, 4);                  memcpy(s->data, missing_bytes, 4);
239    
240                  current_driver->                  rdpsnd_queue_write(rdpsnd_dsp_process
241                          wave_out_write(rdpsnd_dsp_process                                     (s, current_driver, &formats[current_format]), tick,
242                                         (s, current_driver, &formats[current_format]), tick,                                     packet_index);
                                        packet_index);  
243                  awaiting_data_packet = False;                  awaiting_data_packet = False;
244                  return;                  return;
245          }          }
# Line 276  rdpsnd_process(STREAM s) Line 282  rdpsnd_process(STREAM s)
282          }          }
283  }  }
284    
285  BOOL  static BOOL
 rdpsnd_init(void)  
 {  
         rdpsnd_channel =  
                 channel_register("rdpsnd", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP,  
                                  rdpsnd_process);  
   
         return (rdpsnd_channel != NULL);  
 }  
   
 BOOL  
286  rdpsnd_auto_open(void)  rdpsnd_auto_open(void)
287  {  {
288          static BOOL failed = False;          static BOOL failed = False;
# Line 316  rdpsnd_auto_open(void) Line 312  rdpsnd_auto_open(void)
312          return False;          return False;
313  }  }
314    
315  void  static void
316  rdpsnd_register_drivers(char *options)  rdpsnd_register_drivers(char *options)
317  {  {
318          struct audio_driver **reg;          struct audio_driver **reg;
# Line 326  rdpsnd_register_drivers(char *options) Line 322  rdpsnd_register_drivers(char *options)
322          reg = &drivers;          reg = &drivers;
323  #if defined(RDPSND_ALSA)  #if defined(RDPSND_ALSA)
324          *reg = alsa_register(options);          *reg = alsa_register(options);
325            assert(*reg);
326          reg = &((*reg)->next);          reg = &((*reg)->next);
327  #endif  #endif
328  #if defined(RDPSND_SUN)  #if defined(RDPSND_SUN)
329          *reg = sun_register(options);          *reg = sun_register(options);
330            assert(*reg);
331          reg = &((*reg)->next);          reg = &((*reg)->next);
332  #endif  #endif
333  #if defined(RDPSND_OSS)  #if defined(RDPSND_OSS)
334          *reg = oss_register(options);          *reg = oss_register(options);
335            assert(*reg);
336          reg = &((*reg)->next);          reg = &((*reg)->next);
337  #endif  #endif
338  #if defined(RDPSND_SGI)  #if defined(RDPSND_SGI)
339          *reg = sgi_register(options);          *reg = sgi_register(options);
340            assert(*reg);
341          reg = &((*reg)->next);          reg = &((*reg)->next);
342  #endif  #endif
343  #if defined(RDPSND_LIBAO)  #if defined(RDPSND_LIBAO)
344          *reg = libao_register(options);          *reg = libao_register(options);
345            assert(*reg);
346          reg = &((*reg)->next);          reg = &((*reg)->next);
347  #endif  #endif
348  }  }
349    
350  BOOL  BOOL
351  rdpsnd_select_driver(char *driver, char *options)  rdpsnd_init(char *optarg)
352  {  {
353          static struct audio_driver auto_driver;          static struct audio_driver auto_driver;
354          struct audio_driver *pos;          struct audio_driver *pos;
355            char *driver = NULL, *options = NULL;
356    
357          drivers = NULL;          drivers = NULL;
358    
359            rdpsnd_channel =
360                    channel_register("rdpsnd", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP,
361                                     rdpsnd_process);
362    
363            if (rdpsnd_channel == NULL)
364            {
365                    error("channel_register\n");
366                    return False;
367            }
368    
369            rdpsnd_queue_init();
370    
371            if (optarg != NULL && strlen(optarg) > 0)
372            {
373                    driver = options = optarg;
374    
375                    while (*options != '\0' && *options != ':')
376                            options++;
377    
378                    if (*options == ':')
379                    {
380                            *options = '\0';
381                            options++;
382                    }
383    
384                    if (*options == '\0')
385                            options = NULL;
386            }
387    
388          rdpsnd_register_drivers(options);          rdpsnd_register_drivers(options);
389    
390          if (!driver)          if (!driver)
# Line 391  rdpsnd_show_help(void) Line 423  rdpsnd_show_help(void)
423          }          }
424  }  }
425    
426  inline void  void
427  rdpsnd_play(void)  rdpsnd_play(void)
428  {  {
429          current_driver->wave_out_play();          current_driver->wave_out_play();
430  }  }
431    
432  void  void
433    rdpsnd_add_fds(int *n, fd_set * rfds, fd_set * wfds, struct timeval *tv)
434    {
435            long next_pending;
436    
437            if (g_dsp_busy)
438            {
439                    FD_SET(g_dsp_fd, wfds);
440                    *n = (g_dsp_fd > *n) ? g_dsp_fd : *n;
441            }
442    
443            next_pending = rdpsnd_queue_next_completion();
444            if (next_pending >= 0)
445            {
446                    long cur_timeout;
447    
448                    cur_timeout = tv->tv_sec * 1000000 + tv->tv_usec;
449                    if (cur_timeout > next_pending)
450                    {
451                            tv->tv_sec = next_pending / 1000000;
452                            tv->tv_usec = next_pending % 1000000;
453                    }
454            }
455    }
456    
457    void
458    rdpsnd_check_fds(fd_set * rfds, fd_set * wfds)
459    {
460            rdpsnd_queue_complete_pending();
461    
462            if (g_dsp_busy && FD_ISSET(g_dsp_fd, wfds))
463                    rdpsnd_play();
464    }
465    
466    static void
467  rdpsnd_queue_write(STREAM s, uint16 tick, uint8 index)  rdpsnd_queue_write(STREAM s, uint16 tick, uint8 index)
468  {  {
469          struct audio_packet *packet = &packet_queue[queue_hi];          struct audio_packet *packet = &packet_queue[queue_hi];
470          unsigned int next_hi = (queue_hi + 1) % MAX_QUEUE;          unsigned int next_hi = (queue_hi + 1) % MAX_QUEUE;
471    
472          if (next_hi == queue_lo)          if (next_hi == queue_pending)
473          {          {
474                  error("No space to queue audio packet\n");                  error("No space to queue audio packet\n");
475                  return;                  return;
# Line 415  rdpsnd_queue_write(STREAM s, uint16 tick Line 481  rdpsnd_queue_write(STREAM s, uint16 tick
481          packet->tick = tick;          packet->tick = tick;
482          packet->index = index;          packet->index = index;
483    
484            gettimeofday(&packet->arrive_tv, NULL);
485    
486          if (!g_dsp_busy)          if (!g_dsp_busy)
487                  current_driver->wave_out_play();                  current_driver->wave_out_play();
488  }  }
489    
490  inline struct audio_packet *  struct audio_packet *
491  rdpsnd_queue_current_packet(void)  rdpsnd_queue_current_packet(void)
492  {  {
493          return &packet_queue[queue_lo];          return &packet_queue[queue_lo];
494  }  }
495    
496  inline BOOL  BOOL
497  rdpsnd_queue_empty(void)  rdpsnd_queue_empty(void)
498  {  {
499          return (queue_lo == queue_hi);          return (queue_lo == queue_hi);
500  }  }
501    
502  inline void  static void
503  rdpsnd_queue_init(void)  rdpsnd_queue_init(void)
504  {  {
505          queue_lo = queue_hi = 0;          queue_pending = queue_lo = queue_hi = 0;
506  }  }
507    
508  inline void  void
509  rdpsnd_queue_next(void)  rdpsnd_queue_next(unsigned long completed_in_us)
510  {  {
511          xfree(packet_queue[queue_lo].s.data);          struct audio_packet *packet;
512    
513            assert(!rdpsnd_queue_empty());
514    
515            packet = &packet_queue[queue_lo];
516    
517            gettimeofday(&packet->completion_tv, NULL);
518    
519            packet->completion_tv.tv_usec += completed_in_us;
520            packet->completion_tv.tv_sec += packet->completion_tv.tv_usec / 1000000;
521            packet->completion_tv.tv_usec %= 1000000;
522    
523          queue_lo = (queue_lo + 1) % MAX_QUEUE;          queue_lo = (queue_lo + 1) % MAX_QUEUE;
524    
525            rdpsnd_queue_complete_pending();
526  }  }
527    
528  inline int  int
529  rdpsnd_queue_next_tick(void)  rdpsnd_queue_next_tick(void)
530  {  {
531          if (((queue_lo + 1) % MAX_QUEUE) != queue_hi)          if (((queue_lo + 1) % MAX_QUEUE) != queue_hi)
# Line 456  rdpsnd_queue_next_tick(void) Line 537  rdpsnd_queue_next_tick(void)
537                  return (packet_queue[queue_lo].tick + 65535) % 65536;                  return (packet_queue[queue_lo].tick + 65535) % 65536;
538          }          }
539  }  }
540    
541    static void
542    rdpsnd_queue_complete_pending(void)
543    {
544            struct timeval now;
545            long elapsed;
546            struct audio_packet *packet;
547    
548            gettimeofday(&now, NULL);
549    
550            while (queue_pending != queue_lo)
551            {
552                    packet = &packet_queue[queue_pending];
553    
554                    if (now.tv_sec < packet->completion_tv.tv_sec)
555                            break;
556    
557                    if ((now.tv_sec == packet->completion_tv.tv_sec) &&
558                        (now.tv_usec < packet->completion_tv.tv_usec))
559                            break;
560    
561                    elapsed = (packet->completion_tv.tv_sec - packet->arrive_tv.tv_sec) * 1000000 +
562                            (packet->completion_tv.tv_usec - packet->arrive_tv.tv_usec);
563    
564                    xfree(packet->s.data);
565                    rdpsnd_send_completion((packet->tick + elapsed) % 65536, packet->index);
566                    queue_pending = (queue_pending + 1) % MAX_QUEUE;
567            }
568    }
569    
570    static long
571    rdpsnd_queue_next_completion(void)
572    {
573            struct audio_packet *packet;
574            long remaining;
575            struct timeval now;
576    
577            if (queue_pending == queue_lo)
578                    return -1;
579    
580            gettimeofday(&now, NULL);
581    
582            packet = &packet_queue[queue_pending];
583    
584            remaining = (packet->completion_tv.tv_sec - now.tv_sec) * 1000000 +
585                    (packet->completion_tv.tv_usec - now.tv_usec);
586    
587            if (remaining < 0)
588                    return 0;
589    
590            return remaining;
591    }

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

  ViewVC Help
Powered by ViewVC 1.1.26