/[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 1254 by stargo, Sun Sep 17 10:32:18 2006 UTC revision 1337 by ossman_, Wed Dec 6 12:31:58 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"
27    
28  #define RDPSND_CLOSE            1  #define RDPSND_CLOSE            1
29  #define RDPSND_WRITE            2  #define RDPSND_WRITE            2
# Line 37  BOOL g_dsp_busy = False; Line 40  BOOL g_dsp_busy = False;
40  int g_dsp_fd;  int g_dsp_fd;
41    
42  static VCHANNEL *rdpsnd_channel;  static VCHANNEL *rdpsnd_channel;
43    static struct audio_driver *drivers = NULL;
44    struct audio_driver *current_driver = NULL;
45    
46  static BOOL device_open;  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  static unsigned int queue_hi, queue_lo;  unsigned int queue_hi, queue_lo, queue_pending;
51  static struct audio_packet packet_queue[MAX_QUEUE];  struct audio_packet packet_queue[MAX_QUEUE];
52    
53    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)
# Line 67  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 94  rdpsnd_process_negotiate(STREAM in) Line 106  rdpsnd_process_negotiate(STREAM in)
106          in_uint16_le(in, in_format_count);          in_uint16_le(in, in_format_count);
107          in_uint8s(in, 4);       /* pad, status, pad */          in_uint8s(in, 4);       /* pad, status, pad */
108    
109          if (wave_out_open())          if (current_driver->wave_out_open())
110          {          {
111                  wave_out_close();                  current_driver->wave_out_close();
112                  device_available = True;                  device_available = True;
113          }          }
114    
# Line 127  rdpsnd_process_negotiate(STREAM in) Line 139  rdpsnd_process_negotiate(STREAM in)
139                          in_uint8a(in, format->cb, readcnt);                          in_uint8a(in, format->cb, readcnt);
140                          in_uint8s(in, discardcnt);                          in_uint8s(in, discardcnt);
141    
142                          if (device_available && wave_out_format_supported(format))                          if (device_available && current_driver->wave_out_format_supported(format))
143                          {                          {
144                                  format_count++;                                  format_count++;
145                                  if (format_count == MAX_FORMATS)                                  if (format_count == MAX_FORMATS)
# Line 189  rdpsnd_process(STREAM s) Line 201  rdpsnd_process(STREAM s)
201          static uint16 tick, format;          static uint16 tick, format;
202          static uint8 packet_index;          static uint8 packet_index;
203          static BOOL awaiting_data_packet;          static BOOL awaiting_data_packet;
204            static unsigned char missing_bytes[4] = { 0, 0, 0, 0 };
205    
206  #ifdef RDPSND_DEBUG  #ifdef RDPSND_DEBUG
207          printf("RDPSND recv:\n");          printf("RDPSND recv:\n");
# Line 205  rdpsnd_process(STREAM s) Line 218  rdpsnd_process(STREAM s)
218    
219                  if (!device_open || (format != current_format))                  if (!device_open || (format != current_format))
220                  {                  {
221                          if (!device_open && !wave_out_open())                          if (!device_open && !current_driver->wave_out_open())
222                          {                          {
223                                  rdpsnd_send_completion(tick, packet_index);                                  rdpsnd_send_completion(tick, packet_index);
224                                  return;                                  return;
225                          }                          }
226                          if (!wave_out_set_format(&formats[format]))                          if (!current_driver->wave_out_set_format(&formats[format]))
227                          {                          {
228                                  rdpsnd_send_completion(tick, packet_index);                                  rdpsnd_send_completion(tick, packet_index);
229                                  wave_out_close();                                  current_driver->wave_out_close();
230                                  device_open = False;                                  device_open = False;
231                                  return;                                  return;
232                          }                          }
# Line 221  rdpsnd_process(STREAM s) Line 234  rdpsnd_process(STREAM s)
234                          current_format = format;                          current_format = format;
235                  }                  }
236    
237                  rdpsnd_queue_write(s, tick, packet_index);                  /* Insert the 4 missing bytes retrieved from last RDPSND_WRITE */
238                    memcpy(s->data, missing_bytes, 4);
239    
240                    rdpsnd_queue_write(rdpsnd_dsp_process
241                                       (s, current_driver, &formats[current_format]), tick,
242                                       packet_index);
243                  awaiting_data_packet = False;                  awaiting_data_packet = False;
244                  return;                  return;
245          }          }
# Line 236  rdpsnd_process(STREAM s) Line 254  rdpsnd_process(STREAM s)
254                          in_uint16_le(s, tick);                          in_uint16_le(s, tick);
255                          in_uint16_le(s, format);                          in_uint16_le(s, format);
256                          in_uint8(s, packet_index);                          in_uint8(s, packet_index);
257                            /* Here are our lost bytes, but why? */
258                            memcpy(missing_bytes, s->end - 4, 4);
259                          awaiting_data_packet = True;                          awaiting_data_packet = True;
260                          break;                          break;
261                  case RDPSND_CLOSE:                  case RDPSND_CLOSE:
262                          wave_out_close();                          current_driver->wave_out_close();
263                          device_open = False;                          device_open = False;
264                          break;                          break;
265                  case RDPSND_NEGOTIATE:                  case RDPSND_NEGOTIATE:
# Line 252  rdpsnd_process(STREAM s) Line 272  rdpsnd_process(STREAM s)
272                          in_uint32(s, volume);                          in_uint32(s, volume);
273                          if (device_open)                          if (device_open)
274                          {                          {
275                                  wave_out_volume((volume & 0xffff), (volume & 0xffff0000) >> 16);                                  current_driver->wave_out_volume((volume & 0xffff),
276                                                                    (volume & 0xffff0000) >> 16);
277                          }                          }
278                          break;                          break;
279                  default:                  default:
# Line 261  rdpsnd_process(STREAM s) Line 282  rdpsnd_process(STREAM s)
282          }          }
283  }  }
284    
285    static BOOL
286    rdpsnd_auto_open(void)
287    {
288            static BOOL failed = False;
289    
290            if (!failed)
291            {
292                    struct audio_driver *auto_driver = current_driver;
293    
294                    current_driver = drivers;
295                    while (current_driver != NULL)
296                    {
297                            DEBUG(("trying %s...\n", current_driver->name));
298                            if (current_driver->wave_out_open())
299                            {
300                                    DEBUG(("selected %s\n", current_driver->name));
301                                    return True;
302                            }
303                            g_dsp_fd = 0;
304                            current_driver = current_driver->next;
305                    }
306    
307                    warning("no working audio-driver found\n");
308                    failed = True;
309                    current_driver = auto_driver;
310            }
311    
312            return False;
313    }
314    
315    static void
316    rdpsnd_register_drivers(char *options)
317    {
318            struct audio_driver **reg;
319    
320            /* The order of registrations define the probe-order
321               when opening the device for the first time */
322            reg = &drivers;
323    #if defined(RDPSND_ALSA)
324            *reg = alsa_register(options);
325            assert(*reg);
326            reg = &((*reg)->next);
327    #endif
328    #if defined(RDPSND_SUN)
329            *reg = sun_register(options);
330            assert(*reg);
331            reg = &((*reg)->next);
332    #endif
333    #if defined(RDPSND_OSS)
334            *reg = oss_register(options);
335            assert(*reg);
336            reg = &((*reg)->next);
337    #endif
338    #if defined(RDPSND_SGI)
339            *reg = sgi_register(options);
340            assert(*reg);
341            reg = &((*reg)->next);
342    #endif
343    #if defined(RDPSND_LIBAO)
344            *reg = libao_register(options);
345            assert(*reg);
346            reg = &((*reg)->next);
347    #endif
348            *reg = NULL;
349    }
350    
351  BOOL  BOOL
352  rdpsnd_init(void)  rdpsnd_init(char *optarg)
353  {  {
354            static struct audio_driver auto_driver;
355            struct audio_driver *pos;
356            char *driver = NULL, *options = NULL;
357    
358            drivers = NULL;
359    
360          rdpsnd_channel =          rdpsnd_channel =
361                  channel_register("rdpsnd", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP,                  channel_register("rdpsnd", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP,
362                                   rdpsnd_process);                                   rdpsnd_process);
363    
364          return (rdpsnd_channel != NULL);          if (rdpsnd_channel == NULL)
365            {
366                    error("channel_register\n");
367                    return False;
368            }
369    
370            rdpsnd_queue_init();
371    
372            if (optarg != NULL && strlen(optarg) > 0)
373            {
374                    driver = options = optarg;
375    
376                    while (*options != '\0' && *options != ':')
377                            options++;
378    
379                    if (*options == ':')
380                    {
381                            *options = '\0';
382                            options++;
383                    }
384    
385                    if (*options == '\0')
386                            options = NULL;
387            }
388    
389            rdpsnd_register_drivers(options);
390    
391            if (!driver)
392            {
393                    auto_driver.wave_out_open = &rdpsnd_auto_open;
394                    current_driver = &auto_driver;
395                    return True;
396            }
397    
398            pos = drivers;
399            while (pos != NULL)
400            {
401                    if (!strcmp(pos->name, driver))
402                    {
403                            DEBUG(("selected %s\n", pos->name));
404                            current_driver = pos;
405                            return True;
406                    }
407                    pos = pos->next;
408            }
409            return False;
410    }
411    
412    void
413    rdpsnd_show_help(void)
414    {
415            struct audio_driver *pos;
416    
417            rdpsnd_register_drivers(NULL);
418    
419            pos = drivers;
420            while (pos != NULL)
421            {
422                    fprintf(stderr, "                     %s:\t%s\n", pos->name, pos->description);
423                    pos = pos->next;
424            }
425    }
426    
427    void
428    rdpsnd_play(void)
429    {
430            current_driver->wave_out_play();
431    }
432    
433    void
434    rdpsnd_add_fds(int *n, fd_set * rfds, fd_set * wfds, struct timeval *tv)
435    {
436            long next_pending;
437    
438            if (g_dsp_busy)
439            {
440                    FD_SET(g_dsp_fd, wfds);
441                    *n = (g_dsp_fd > *n) ? g_dsp_fd : *n;
442            }
443    
444            next_pending = rdpsnd_queue_next_completion();
445            if (next_pending >= 0)
446            {
447                    long cur_timeout;
448    
449                    cur_timeout = tv->tv_sec * 1000000 + tv->tv_usec;
450                    if (cur_timeout > next_pending)
451                    {
452                            tv->tv_sec = next_pending / 1000000;
453                            tv->tv_usec = next_pending % 1000000;
454                    }
455            }
456  }  }
457    
458  void  void
459    rdpsnd_check_fds(fd_set * rfds, fd_set * wfds)
460    {
461            rdpsnd_queue_complete_pending();
462    
463            if (g_dsp_busy && FD_ISSET(g_dsp_fd, wfds))
464                    rdpsnd_play();
465    }
466    
467    static void
468  rdpsnd_queue_write(STREAM s, uint16 tick, uint8 index)  rdpsnd_queue_write(STREAM s, uint16 tick, uint8 index)
469  {  {
470          struct audio_packet *packet = &packet_queue[queue_hi];          struct audio_packet *packet = &packet_queue[queue_hi];
471          unsigned int next_hi = (queue_hi + 1) % MAX_QUEUE;          unsigned int next_hi = (queue_hi + 1) % MAX_QUEUE;
472    
473          if (next_hi == queue_lo)          if (next_hi == queue_pending)
474          {          {
475                  error("No space to queue audio packet\n");                  error("No space to queue audio packet\n");
476                  return;                  return;
# Line 288  rdpsnd_queue_write(STREAM s, uint16 tick Line 481  rdpsnd_queue_write(STREAM s, uint16 tick
481          packet->s = *s;          packet->s = *s;
482          packet->tick = tick;          packet->tick = tick;
483          packet->index = index;          packet->index = index;
         packet->s.p += 4;  
484    
485          /* we steal the data buffer from s, give it a new one */          gettimeofday(&packet->arrive_tv, NULL);
         s->data = malloc(s->size);  
486    
487          if (!g_dsp_busy)          if (!g_dsp_busy)
488                  wave_out_play();                  current_driver->wave_out_play();
489  }  }
490    
491  inline struct audio_packet *  struct audio_packet *
492  rdpsnd_queue_current_packet(void)  rdpsnd_queue_current_packet(void)
493  {  {
494          return &packet_queue[queue_lo];          return &packet_queue[queue_lo];
495  }  }
496    
497  inline BOOL  BOOL
498  rdpsnd_queue_empty(void)  rdpsnd_queue_empty(void)
499  {  {
500          return (queue_lo == queue_hi);          return (queue_lo == queue_hi);
501  }  }
502    
503  inline void  static void
504  rdpsnd_queue_init(void)  rdpsnd_queue_init(void)
505  {  {
506          queue_lo = queue_hi = 0;          queue_pending = queue_lo = queue_hi = 0;
507  }  }
508    
509  inline void  void
510  rdpsnd_queue_next(void)  rdpsnd_queue_next(unsigned long completed_in_us)
511  {  {
512          free(packet_queue[queue_lo].s.data);          struct audio_packet *packet;
513    
514            assert(!rdpsnd_queue_empty());
515    
516            packet = &packet_queue[queue_lo];
517    
518            gettimeofday(&packet->completion_tv, NULL);
519    
520            packet->completion_tv.tv_usec += completed_in_us;
521            packet->completion_tv.tv_sec += packet->completion_tv.tv_usec / 1000000;
522            packet->completion_tv.tv_usec %= 1000000;
523    
524          queue_lo = (queue_lo + 1) % MAX_QUEUE;          queue_lo = (queue_lo + 1) % MAX_QUEUE;
525    
526            rdpsnd_queue_complete_pending();
527  }  }
528    
529  inline int  int
530  rdpsnd_queue_next_tick(void)  rdpsnd_queue_next_tick(void)
531  {  {
532          if (((queue_lo + 1) % MAX_QUEUE) != queue_hi)          if (((queue_lo + 1) % MAX_QUEUE) != queue_hi)
# Line 334  rdpsnd_queue_next_tick(void) Line 538  rdpsnd_queue_next_tick(void)
538                  return (packet_queue[queue_lo].tick + 65535) % 65536;                  return (packet_queue[queue_lo].tick + 65535) % 65536;
539          }          }
540  }  }
541    
542    static void
543    rdpsnd_queue_complete_pending(void)
544    {
545            struct timeval now;
546            long elapsed;
547            struct audio_packet *packet;
548    
549            gettimeofday(&now, NULL);
550    
551            while (queue_pending != queue_lo)
552            {
553                    packet = &packet_queue[queue_pending];
554    
555                    if (now.tv_sec < packet->completion_tv.tv_sec)
556                            break;
557    
558                    if ((now.tv_sec == packet->completion_tv.tv_sec) &&
559                        (now.tv_usec < packet->completion_tv.tv_usec))
560                            break;
561    
562                    elapsed = (packet->completion_tv.tv_sec - packet->arrive_tv.tv_sec) * 1000000 +
563                            (packet->completion_tv.tv_usec - packet->arrive_tv.tv_usec);
564                    elapsed /= 1000;
565    
566                    xfree(packet->s.data);
567                    rdpsnd_send_completion((packet->tick + elapsed) % 65536, packet->index);
568                    queue_pending = (queue_pending + 1) % MAX_QUEUE;
569            }
570    }
571    
572    static long
573    rdpsnd_queue_next_completion(void)
574    {
575            struct audio_packet *packet;
576            long remaining;
577            struct timeval now;
578    
579            if (queue_pending == queue_lo)
580                    return -1;
581    
582            gettimeofday(&now, NULL);
583    
584            packet = &packet_queue[queue_pending];
585    
586            remaining = (packet->completion_tv.tv_sec - now.tv_sec) * 1000000 +
587                    (packet->completion_tv.tv_usec - now.tv_usec);
588    
589            if (remaining < 0)
590                    return 0;
591    
592            return remaining;
593    }

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

  ViewVC Help
Powered by ViewVC 1.1.26