/[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 1298 by ossman_, Thu Oct 19 11:27:40 2006 UTC revision 1427 by ossman_, Fri Jan 18 15:11:57 2008 UTC
# Line 1  Line 1 
1  /* -*- c-basic-offset: 8 -*-  /* -*- c-basic-offset: 8 -*-
2     rdesktop: A Remote Desktop Protocol client.     rdesktop: A Remote Desktop Protocol client.
3     Sound Channel Process Functions     Sound Channel Process Functions
4     Copyright (C) Matthew Chapman 2003     Copyright 2006-2007 Pierre Ossman <ossman@cendio.se> for Cendio AB
5       Copyright (C) Matthew Chapman 2003-2007
6     Copyright (C) GuoJunBo guojunbo@ict.ac.cn 2003     Copyright (C) GuoJunBo guojunbo@ict.ac.cn 2003
7    
8     This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
# Line 30  Line 31 
31  #define RDPSND_SET_VOLUME       3  #define RDPSND_SET_VOLUME       3
32  #define RDPSND_UNKNOWN4         4  #define RDPSND_UNKNOWN4         4
33  #define RDPSND_COMPLETION       5  #define RDPSND_COMPLETION       5
34  #define RDPSND_SERVERTICK       6  #define RDPSND_PING                     6
35  #define RDPSND_NEGOTIATE        7  #define RDPSND_NEGOTIATE        7
36    
37  #define MAX_FORMATS             10  #define RDPSND_REC_NEGOTIATE    39
38  #define MAX_QUEUE               10  #define RDPSND_REC_START                40
39    #define RDPSND_REC_STOP                 41
40    #define RDPSND_REC_DATA                 42
41    #define RDPSND_REC_SET_VOLUME   43
42    
43    #define RDPSND_FLAG_RECORD              0x00800000
44    
45  BOOL g_dsp_busy = False;  #define MAX_FORMATS             10
46  int g_dsp_fd;  #define MAX_QUEUE               50
47    
48  static VCHANNEL *rdpsnd_channel;  static VCHANNEL *rdpsnd_channel;
49    static VCHANNEL *rdpsnddbg_channel;
50  static struct audio_driver *drivers = NULL;  static struct audio_driver *drivers = NULL;
51  struct audio_driver *current_driver = NULL;  struct audio_driver *current_driver = NULL;
52    
53  static BOOL device_open;  static RD_BOOL device_open;
54  static WAVEFORMATEX formats[MAX_FORMATS];  static RD_BOOL rec_device_open;
55    
56    static RD_WAVEFORMATEX formats[MAX_FORMATS];
57  static unsigned int format_count;  static unsigned int format_count;
58  static unsigned int current_format;  static unsigned int current_format;
59  unsigned int queue_hi, queue_lo;  
60    static RD_WAVEFORMATEX rec_formats[MAX_FORMATS];
61    static unsigned int rec_format_count;
62    
63    unsigned int queue_hi, queue_lo, queue_pending;
64  struct audio_packet packet_queue[MAX_QUEUE];  struct audio_packet packet_queue[MAX_QUEUE];
65    
66    static char record_buffer[8192];
67    static uint32 record_buffer_size;
68    
69    static uint8 packet_opcode;
70    static struct stream packet;
71    
72  void (*wave_out_play) (void);  void (*wave_out_play) (void);
73    
74    static void rdpsnd_queue_write(STREAM s, uint16 tick, uint8 index);
75    static void rdpsnd_queue_init(void);
76    static void rdpsnd_queue_complete_pending(void);
77    static long rdpsnd_queue_next_completion(void);
78    
79  static STREAM  static STREAM
80  rdpsnd_init_packet(uint16 type, uint16 size)  rdpsnd_init_packet(uint16 type, uint16 size)
81  {  {
# Line 66  rdpsnd_init_packet(uint16 type, uint16 s Line 90  rdpsnd_init_packet(uint16 type, uint16 s
90  static void  static void
91  rdpsnd_send(STREAM s)  rdpsnd_send(STREAM s)
92  {  {
 #ifdef RDPSND_DEBUG  
         printf("RDPSND send:\n");  
         hexdump(s->channel_hdr + 8, s->end - s->channel_hdr - 8);  
 #endif  
   
93          channel_send(s, rdpsnd_channel);          channel_send(s, rdpsnd_channel);
94  }  }
95    
96  void  static void
97  rdpsnd_send_completion(uint16 tick, uint8 packet_index)  rdpsnd_send_completion(uint16 tick, uint8 packet_index)
98  {  {
99          STREAM s;          STREAM s;
# Line 85  rdpsnd_send_completion(uint16 tick, uint Line 104  rdpsnd_send_completion(uint16 tick, uint
104          out_uint8(s, 0);          out_uint8(s, 0);
105          s_mark_end(s);          s_mark_end(s);
106          rdpsnd_send(s);          rdpsnd_send(s);
107    
108            DEBUG_SOUND(("RDPSND: -> RDPSND_COMPLETION(tick: %u, index: %u)\n",
109                         (unsigned) tick, (unsigned) packet_index));
110    }
111    
112    static void
113    rdpsnd_flush_record(void)
114    {
115            STREAM s;
116            unsigned int chunk_size;
117            char *data;
118    
119            if (record_buffer_size == 0)
120                    return;
121    
122            assert(record_buffer_size <= sizeof(record_buffer));
123    
124            data = record_buffer;
125    
126            /*
127             * Microsoft's RDP server keeps dropping chunks, so we need to
128             * transmit everything inside one channel fragment or we risk
129             * making the rdpsnd server go out of sync with the byte stream.
130             */
131            while (record_buffer_size)
132            {
133                    if (record_buffer_size < 1596)
134                            chunk_size = record_buffer_size;
135                    else
136                            chunk_size = 1596;
137    
138                    s = rdpsnd_init_packet(RDPSND_REC_DATA, chunk_size);
139                    out_uint8p(s, data, chunk_size);
140    
141                    s_mark_end(s);
142                    rdpsnd_send(s);
143    
144                    data = data + chunk_size;
145                    record_buffer_size -= chunk_size;
146    
147                    DEBUG_SOUND(("RDPSND: -> RDPSND_REC_DATA(length: %u)\n", (unsigned) chunk_size));
148            }
149    
150            record_buffer_size = 0;
151    }
152    
153    void
154    rdpsnd_record(const void *data, unsigned int size)
155    {
156            uint32 remain;
157    
158            assert(rec_device_open);
159    
160            while (size)
161            {
162                    remain = sizeof(record_buffer) - record_buffer_size;
163    
164                    if (size >= remain)
165                    {
166                            memcpy(record_buffer + record_buffer_size, data, remain);
167                            record_buffer_size += remain;
168                            rdpsnd_flush_record();
169                            data = (const char *) data + remain;
170                            size -= remain;
171                    }
172                    else
173                    {
174                            memcpy(record_buffer + record_buffer_size, data, size);
175                            record_buffer_size += size;
176                            size = 0;
177                    }
178            }
179    }
180    
181    static RD_BOOL
182    rdpsnd_auto_select(void)
183    {
184            static RD_BOOL failed = False;
185    
186            if (!failed)
187            {
188                    current_driver = drivers;
189                    while (current_driver != NULL)
190                    {
191                            DEBUG(("trying %s...\n", current_driver->name));
192                            if (current_driver->wave_out_open())
193                            {
194                                    DEBUG(("selected %s\n", current_driver->name));
195                                    current_driver->wave_out_close();
196                                    return True;
197                            }
198                            current_driver = current_driver->next;
199                    }
200    
201                    warning("no working audio-driver found\n");
202                    failed = True;
203                    current_driver = NULL;
204            }
205    
206            return False;
207  }  }
208    
209  static void  static void
210  rdpsnd_process_negotiate(STREAM in)  rdpsnd_process_negotiate(STREAM in)
211  {  {
212          unsigned int in_format_count, i;          uint16 in_format_count, i;
213          WAVEFORMATEX *format;          uint8 pad;
214            uint16 version;
215            RD_WAVEFORMATEX *format;
216          STREAM out;          STREAM out;
217          BOOL device_available = False;          RD_BOOL device_available = False;
218          int readcnt;          int readcnt;
219          int discardcnt;          int discardcnt;
220    
221          in_uint8s(in, 14);      /* flags, volume, pitch, UDP port */          in_uint8s(in, 14);      /* initial bytes not valid from server */
222          in_uint16_le(in, in_format_count);          in_uint16_le(in, in_format_count);
223          in_uint8s(in, 4);       /* pad, status, pad */          in_uint8(in, pad);
224            in_uint16_le(in, version);
225            in_uint8s(in, 1);       /* padding */
226    
227            DEBUG_SOUND(("RDPSND: RDPSND_NEGOTIATE(formats: %d, pad: 0x%02x, version: %x)\n",
228                         (int) in_format_count, (unsigned) pad, (unsigned) version));
229    
230            if (!current_driver)
231                    device_available = rdpsnd_auto_select();
232    
233          if (current_driver->wave_out_open())          if (current_driver && !device_available && current_driver->wave_out_open())
234          {          {
235                  current_driver->wave_out_close();                  current_driver->wave_out_close();
236                  device_available = True;                  device_available = True;
# Line 134  rdpsnd_process_negotiate(STREAM in) Line 263  rdpsnd_process_negotiate(STREAM in)
263                          in_uint8a(in, format->cb, readcnt);                          in_uint8a(in, format->cb, readcnt);
264                          in_uint8s(in, discardcnt);                          in_uint8s(in, discardcnt);
265    
266                          if (device_available && current_driver->wave_out_format_supported(format))                          if (current_driver && current_driver->wave_out_format_supported(format))
267                          {                          {
268                                  format_count++;                                  format_count++;
269                                  if (format_count == MAX_FORMATS)                                  if (format_count == MAX_FORMATS)
# Line 144  rdpsnd_process_negotiate(STREAM in) Line 273  rdpsnd_process_negotiate(STREAM in)
273          }          }
274    
275          out = rdpsnd_init_packet(RDPSND_NEGOTIATE | 0x200, 20 + 18 * format_count);          out = rdpsnd_init_packet(RDPSND_NEGOTIATE | 0x200, 20 + 18 * format_count);
276          out_uint32_le(out, 3);  /* flags */          out_uint32_le(out, 0x00800003); /* flags */
277          out_uint32(out, 0xffffffff);    /* volume */          out_uint32(out, 0xffffffff);    /* volume */
278          out_uint32(out, 0);     /* pitch */          out_uint32(out, 0);     /* pitch */
279          out_uint16(out, 0);     /* UDP port */          out_uint16(out, 0);     /* UDP port */
280    
281          out_uint16_le(out, format_count);          out_uint16_le(out, format_count);
282          out_uint8(out, 0x95);   /* pad? */          out_uint8(out, 0);      /* padding */
283          out_uint16_le(out, 2);  /* status */          out_uint16_le(out, 2);  /* version */
284          out_uint8(out, 0x77);   /* pad? */          out_uint8(out, 0);      /* padding */
285    
286          for (i = 0; i < format_count; i++)          for (i = 0; i < format_count; i++)
287          {          {
# Line 167  rdpsnd_process_negotiate(STREAM in) Line 296  rdpsnd_process_negotiate(STREAM in)
296          }          }
297    
298          s_mark_end(out);          s_mark_end(out);
299    
300            DEBUG_SOUND(("RDPSND: -> RDPSND_NEGOTIATE(formats: %d)\n", (int) format_count));
301    
302          rdpsnd_send(out);          rdpsnd_send(out);
303  }  }
304    
305  static void  static void
306  rdpsnd_process_servertick(STREAM in)  rdpsnd_process_ping(STREAM in)
307  {  {
308          uint16 tick1, tick2;          uint16 tick;
309          STREAM out;          STREAM out;
310    
311          /* in_uint8s(in, 4); unknown */          in_uint16_le(in, tick);
312          in_uint16_le(in, tick1);  
313          in_uint16_le(in, tick2);          DEBUG_SOUND(("RDPSND: RDPSND_PING(tick: 0x%04x)\n", (unsigned) tick));
314    
315          out = rdpsnd_init_packet(RDPSND_SERVERTICK | 0x2300, 4);          out = rdpsnd_init_packet(RDPSND_PING | 0x2300, 4);
316          out_uint16_le(out, tick1);          out_uint16_le(out, tick);
317          out_uint16_le(out, tick2);          out_uint16_le(out, 0);
318          s_mark_end(out);          s_mark_end(out);
319          rdpsnd_send(out);          rdpsnd_send(out);
320    
321            DEBUG_SOUND(("RDPSND: -> (tick: 0x%04x)\n", (unsigned) tick));
322  }  }
323    
324  static void  static void
325  rdpsnd_process(STREAM s)  rdpsnd_process_rec_negotiate(STREAM in)
326  {  {
327          uint8 type;          uint16 in_format_count, i;
328          uint16 datalen;          uint16 version;
329          uint32 volume;          RD_WAVEFORMATEX *format;
330          static uint16 tick, format;          STREAM out;
331          static uint8 packet_index;          RD_BOOL device_available = False;
332          static BOOL awaiting_data_packet;          int readcnt;
333          static unsigned char missing_bytes[4] = { 0, 0, 0, 0 };          int discardcnt;
334    
335  #ifdef RDPSND_DEBUG          in_uint8s(in, 8);       /* initial bytes not valid from server */
336          printf("RDPSND recv:\n");          in_uint16_le(in, in_format_count);
337          hexdump(s->p, s->end - s->p);          in_uint16_le(in, version);
338  #endif  
339            DEBUG_SOUND(("RDPSND: RDPSND_REC_NEGOTIATE(formats: %d, version: %x)\n",
340                         (int) in_format_count, (unsigned) version));
341    
342          if (awaiting_data_packet)          if (!current_driver)
343                    device_available = rdpsnd_auto_select();
344    
345            if (current_driver && !device_available && current_driver->wave_in_open
346                && current_driver->wave_in_open())
347          {          {
348                  if (format >= MAX_FORMATS)                  current_driver->wave_in_close();
349                  {                  device_available = True;
350                          error("RDPSND: Invalid format index\n");          }
                         return;  
                 }  
351    
352                  if (!device_open || (format != current_format))          rec_format_count = 0;
353            if (s_check_rem(in, 18 * in_format_count))
354            {
355                    for (i = 0; i < in_format_count; i++)
356                  {                  {
357                          if (!device_open && !current_driver->wave_out_open())                          format = &rec_formats[rec_format_count];
358                            in_uint16_le(in, format->wFormatTag);
359                            in_uint16_le(in, format->nChannels);
360                            in_uint32_le(in, format->nSamplesPerSec);
361                            in_uint32_le(in, format->nAvgBytesPerSec);
362                            in_uint16_le(in, format->nBlockAlign);
363                            in_uint16_le(in, format->wBitsPerSample);
364                            in_uint16_le(in, format->cbSize);
365    
366                            /* read in the buffer of unknown use */
367                            readcnt = format->cbSize;
368                            discardcnt = 0;
369                            if (format->cbSize > MAX_CBSIZE)
370                          {                          {
371                                  rdpsnd_send_completion(tick, packet_index);                                  fprintf(stderr, "cbSize too large for buffer: %d\n",
372                                  return;                                          format->cbSize);
373                                    readcnt = MAX_CBSIZE;
374                                    discardcnt = format->cbSize - MAX_CBSIZE;
375                          }                          }
376                          if (!current_driver->wave_out_set_format(&formats[format]))                          in_uint8a(in, format->cb, readcnt);
377                            in_uint8s(in, discardcnt);
378    
379                            if (current_driver && current_driver->wave_in_format_supported
380                                && current_driver->wave_in_format_supported(format))
381                          {                          {
382                                  rdpsnd_send_completion(tick, packet_index);                                  rec_format_count++;
383                                  current_driver->wave_out_close();                                  if (rec_format_count == MAX_FORMATS)
384                                  device_open = False;                                          break;
                                 return;  
385                          }                          }
                         device_open = True;  
                         current_format = format;  
386                  }                  }
387            }
388    
389                  /* Insert the 4 missing bytes retrieved from last RDPSND_WRITE */          out = rdpsnd_init_packet(RDPSND_REC_NEGOTIATE, 12 + 18 * rec_format_count);
390                  memcpy(s->data, missing_bytes, 4);          out_uint32_le(out, 0x00000000); /* flags */
391            out_uint32_le(out, 0xffffffff); /* volume */
392            out_uint16_le(out, rec_format_count);
393            out_uint16_le(out, 1);  /* version */
394    
395                  current_driver->          for (i = 0; i < rec_format_count; i++)
396                          wave_out_write(rdpsnd_dsp_process          {
397                                         (s, current_driver, &formats[current_format]), tick,                  format = &rec_formats[i];
398                                         packet_index);                  out_uint16_le(out, format->wFormatTag);
399                  awaiting_data_packet = False;                  out_uint16_le(out, format->nChannels);
400                  return;                  out_uint32_le(out, format->nSamplesPerSec);
401                    out_uint32_le(out, format->nAvgBytesPerSec);
402                    out_uint16_le(out, format->nBlockAlign);
403                    out_uint16_le(out, format->wBitsPerSample);
404                    out_uint16(out, 0);     /* cbSize */
405          }          }
406    
407          in_uint8(s, type);          s_mark_end(out);
408          in_uint8s(s, 1);        /* unknown? */  
409          in_uint16_le(s, datalen);          DEBUG_SOUND(("RDPSND: -> RDPSND_REC_NEGOTIATE(formats: %d)\n", (int) rec_format_count));
410    
411            rdpsnd_send(out);
412    }
413    
414    static void
415    rdpsnd_process_packet(uint8 opcode, STREAM s)
416    {
417            uint16 vol_left, vol_right;
418            static uint16 tick, format;
419            static uint8 packet_index;
420    
421          switch (type)          switch (opcode)
422          {          {
423                  case RDPSND_WRITE:                  case RDPSND_WRITE:
424                          in_uint16_le(s, tick);                          in_uint16_le(s, tick);
425                          in_uint16_le(s, format);                          in_uint16_le(s, format);
426                          in_uint8(s, packet_index);                          in_uint8(s, packet_index);
427                          /* Here are our lost bytes, but why? */                          in_uint8s(s, 3);
428                          memcpy(missing_bytes, s->end - 4, 4);                          DEBUG_SOUND(("RDPSND: RDPSND_WRITE(tick: %u, format: %u, index: %u, data: %u bytes)\n", (unsigned) tick, (unsigned) format, (unsigned) packet_index, (unsigned) s->size - 8));
429                          awaiting_data_packet = True;  
430                            if (format >= MAX_FORMATS)
431                            {
432                                    error("RDPSND: Invalid format index\n");
433                                    break;
434                            }
435    
436                            if (!device_open || (format != current_format))
437                            {
438                                    /*
439                                     * If we haven't selected a device by now, then either
440                                     * we've failed to find a working device, or the server
441                                     * is sending bogus RDPSND_WRITE.
442                                     */
443                                    if (!current_driver)
444                                    {
445                                            rdpsnd_send_completion(tick, packet_index);
446                                            break;
447                                    }
448                                    if (!device_open && !current_driver->wave_out_open())
449                                    {
450                                            rdpsnd_send_completion(tick, packet_index);
451                                            break;
452                                    }
453                                    if (!current_driver->wave_out_set_format(&formats[format]))
454                                    {
455                                            rdpsnd_send_completion(tick, packet_index);
456                                            current_driver->wave_out_close();
457                                            device_open = False;
458                                            break;
459                                    }
460                                    device_open = True;
461                                    current_format = format;
462                            }
463    
464                            rdpsnd_queue_write(rdpsnd_dsp_process
465                                               (s->p, s->end - s->p, current_driver,
466                                                &formats[current_format]), tick, packet_index);
467                            return;
468                          break;                          break;
469                  case RDPSND_CLOSE:                  case RDPSND_CLOSE:
470                          current_driver->wave_out_close();                          DEBUG_SOUND(("RDPSND: RDPSND_CLOSE()\n"));
471                            if (device_open)
472                                    current_driver->wave_out_close();
473                          device_open = False;                          device_open = False;
474                          break;                          break;
475                  case RDPSND_NEGOTIATE:                  case RDPSND_NEGOTIATE:
476                          rdpsnd_process_negotiate(s);                          rdpsnd_process_negotiate(s);
477                          break;                          break;
478                  case RDPSND_SERVERTICK:                  case RDPSND_PING:
479                          rdpsnd_process_servertick(s);                          rdpsnd_process_ping(s);
480                          break;                          break;
481                  case RDPSND_SET_VOLUME:                  case RDPSND_SET_VOLUME:
482                          in_uint32(s, volume);                          in_uint16_le(s, vol_left);
483                            in_uint16_le(s, vol_right);
484                            DEBUG_SOUND(("RDPSND: RDPSND_VOLUME(left: 0x%04x (%u %%), right: 0x%04x (%u %%))\n", (unsigned) vol_left, (unsigned) vol_left / 655, (unsigned) vol_right, (unsigned) vol_right / 655));
485                          if (device_open)                          if (device_open)
486                                    current_driver->wave_out_volume(vol_left, vol_right);
487                            break;
488                    case RDPSND_REC_NEGOTIATE:
489                            rdpsnd_process_rec_negotiate(s);
490                            break;
491                    case RDPSND_REC_START:
492                            in_uint16_le(s, format);
493                            DEBUG_SOUND(("RDPSND: RDPSND_REC_START(format: %u)\n", (unsigned) format));
494    
495                            if (format >= MAX_FORMATS)
496                          {                          {
497                                  current_driver->wave_out_volume((volume & 0xffff),                                  error("RDPSND: Invalid format index\n");
498                                                                  (volume & 0xffff0000) >> 16);                                  break;
499                          }                          }
500    
501                            if (rec_device_open)
502                            {
503                                    error("RDPSND: Multiple RDPSND_REC_START\n");
504                                    break;
505                            }
506    
507                            if (!current_driver->wave_in_open())
508                                    break;
509    
510                            if (!current_driver->wave_in_set_format(&rec_formats[format]))
511                            {
512                                    error("RDPSND: Device not accepting format\n");
513                                    current_driver->wave_in_close();
514                                    break;
515                            }
516                            rec_device_open = True;
517                            break;
518                    case RDPSND_REC_STOP:
519                            DEBUG_SOUND(("RDPSND: RDPSND_REC_STOP()\n"));
520                            rdpsnd_flush_record();
521                            if (rec_device_open)
522                                    current_driver->wave_in_close();
523                            rec_device_open = False;
524                            break;
525                    case RDPSND_REC_SET_VOLUME:
526                            in_uint16_le(s, vol_left);
527                            in_uint16_le(s, vol_right);
528                            DEBUG_SOUND(("RDPSND: RDPSND_REC_VOLUME(left: 0x%04x (%u %%), right: 0x%04x (%u %%))\n", (unsigned) vol_left, (unsigned) vol_left / 655, (unsigned) vol_right, (unsigned) vol_right / 655));
529                            if (rec_device_open)
530                                    current_driver->wave_in_volume(vol_left, vol_right);
531                          break;                          break;
532                  default:                  default:
533                          unimpl("RDPSND packet type %d\n", type);                          unimpl("RDPSND packet type %x\n", opcode);
534                          break;                          break;
535          }          }
536  }  }
537    
538  static BOOL  static void
539  rdpsnd_auto_open(void)  rdpsnd_process(STREAM s)
540  {  {
541          static BOOL failed = False;          uint16 len;
542    
543          if (!failed)          while (!s_check_end(s))
544          {          {
545                  struct audio_driver *auto_driver = current_driver;                  /* New packet */
546                    if (packet.size == 0)
                 current_driver = drivers;  
                 while (current_driver != NULL)  
547                  {                  {
548                          DEBUG(("trying %s...\n", current_driver->name));                          if ((s->end - s->p) < 4)
                         if (current_driver->wave_out_open())  
549                          {                          {
550                                  DEBUG(("selected %s\n", current_driver->name));                                  error("RDPSND: Split at packet header. Things will go south from here...\n");
551                                  return True;                                  return;
552                          }                          }
553                          g_dsp_fd = 0;                          in_uint8(s, packet_opcode);
554                          current_driver = current_driver->next;                          in_uint8s(s, 1);        /* Padding */
555                            in_uint16_le(s, len);
556    
557                            DEBUG_SOUND(("RDPSND: == Opcode %x Length: %d ==\n",
558                                         (int) packet_opcode, (int) len));
559    
560                            packet.p = packet.data;
561                            packet.end = packet.data + len;
562                            packet.size = len;
563                  }                  }
564                    else
565                    {
566                            len = MIN(s->end - s->p, packet.end - packet.p);
567    
568                  warning("no working audio-driver found\n");                          /* Microsoft's server is so broken it's not even funny... */
569                  failed = True;                          if (packet_opcode == RDPSND_WRITE)
570                  current_driver = auto_driver;                          {
571                                    if ((packet.p - packet.data) < 12)
572                                            len = MIN(len, 12 - (packet.p - packet.data));
573                                    else if ((packet.p - packet.data) == 12)
574                                    {
575                                            DEBUG_SOUND(("RDPSND: Eating 4 bytes of %d bytes...\n",
576                                                         len));
577                                            in_uint8s(s, 4);
578                                            len -= 4;
579                                    }
580                            }
581    
582                            in_uint8a(s, packet.p, len);
583                            packet.p += len;
584                    }
585    
586                    /* Packet fully assembled */
587                    if (packet.p == packet.end)
588                    {
589                            packet.p = packet.data;
590                            rdpsnd_process_packet(packet_opcode, &packet);
591                            packet.size = 0;
592                    }
593          }          }
594    }
595    
596          return False;  static RD_BOOL
597    rdpsnddbg_line_handler(const char *line, void *data)
598    {
599    #ifdef WITH_DEBUG_SOUND
600            fprintf(stderr, "SNDDBG: %s\n", line);
601    #endif
602            return True;
603    }
604    
605    static void
606    rdpsnddbg_process(STREAM s)
607    {
608            unsigned int pkglen;
609            static char *rest = NULL;
610            char *buf;
611    
612            pkglen = s->end - s->p;
613            /* str_handle_lines requires null terminated strings */
614            buf = (char *) xmalloc(pkglen + 1);
615            STRNCPY(buf, (char *) s->p, pkglen + 1);
616    
617            str_handle_lines(buf, &rest, rdpsnddbg_line_handler, NULL);
618    
619            xfree(buf);
620  }  }
621    
622  static void  static void
# Line 338  rdpsnd_register_drivers(char *options) Line 649  rdpsnd_register_drivers(char *options)
649  #endif  #endif
650  #if defined(RDPSND_LIBAO)  #if defined(RDPSND_LIBAO)
651          *reg = libao_register(options);          *reg = libao_register(options);
652      assert(*reg);          assert(*reg);
653          reg = &((*reg)->next);          reg = &((*reg)->next);
654  #endif  #endif
655            *reg = NULL;
656  }  }
657    
658  BOOL  RD_BOOL
659  rdpsnd_init(char *optarg)  rdpsnd_init(char *optarg)
660  {  {
         static struct audio_driver auto_driver;  
661          struct audio_driver *pos;          struct audio_driver *pos;
662          char *driver = NULL, *options = NULL;          char *driver = NULL, *options = NULL;
663    
664          drivers = NULL;          drivers = NULL;
665    
666            packet.data = (uint8 *) xmalloc(65536);
667            packet.p = packet.end = packet.data;
668            packet.size = 0;
669    
670          rdpsnd_channel =          rdpsnd_channel =
671                  channel_register("rdpsnd", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP,                  channel_register("rdpsnd", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP,
672                                   rdpsnd_process);                                   rdpsnd_process);
673    
674          if (rdpsnd_channel == NULL)          rdpsnddbg_channel =
675                    channel_register("snddbg", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP,
676                                     rdpsnddbg_process);
677    
678            if ((rdpsnd_channel == NULL) || (rdpsnddbg_channel == NULL))
679          {          {
680                  error("channel_register\n");                  error("channel_register\n");
681                  return False;                  return False;
682          }          }
683    
684            rdpsnd_queue_init();
685    
686          if (optarg != NULL && strlen(optarg) > 0)          if (optarg != NULL && strlen(optarg) > 0)
687          {          {
688                  driver = options = optarg;                  driver = options = optarg;
# Line 382  rdpsnd_init(char *optarg) Line 703  rdpsnd_init(char *optarg)
703          rdpsnd_register_drivers(options);          rdpsnd_register_drivers(options);
704    
705          if (!driver)          if (!driver)
         {  
                 auto_driver.wave_out_open = &rdpsnd_auto_open;  
                 current_driver = &auto_driver;  
706                  return True;                  return True;
         }  
707    
708          pos = drivers;          pos = drivers;
709          while (pos != NULL)          while (pos != NULL)
# Line 418  rdpsnd_show_help(void) Line 735  rdpsnd_show_help(void)
735  }  }
736    
737  void  void
738  rdpsnd_play(void)  rdpsnd_add_fds(int *n, fd_set * rfds, fd_set * wfds, struct timeval *tv)
739  {  {
740          current_driver->wave_out_play();          long next_pending;
741    
742            if (device_open || rec_device_open)
743                    current_driver->add_fds(n, rfds, wfds, tv);
744    
745            next_pending = rdpsnd_queue_next_completion();
746            if (next_pending >= 0)
747            {
748                    long cur_timeout;
749    
750                    cur_timeout = tv->tv_sec * 1000000 + tv->tv_usec;
751                    if (cur_timeout > next_pending)
752                    {
753                            tv->tv_sec = next_pending / 1000000;
754                            tv->tv_usec = next_pending % 1000000;
755                    }
756            }
757  }  }
758    
759  inline void  void
760    rdpsnd_check_fds(fd_set * rfds, fd_set * wfds)
761    {
762            rdpsnd_queue_complete_pending();
763    
764            if (device_open || rec_device_open)
765                    current_driver->check_fds(rfds, wfds);
766    }
767    
768    static void
769  rdpsnd_queue_write(STREAM s, uint16 tick, uint8 index)  rdpsnd_queue_write(STREAM s, uint16 tick, uint8 index)
770  {  {
771          struct audio_packet *packet = &packet_queue[queue_hi];          struct audio_packet *packet = &packet_queue[queue_hi];
772          unsigned int next_hi = (queue_hi + 1) % MAX_QUEUE;          unsigned int next_hi = (queue_hi + 1) % MAX_QUEUE;
773    
774          if (next_hi == queue_lo)          if (next_hi == queue_pending)
775          {          {
776                  error("No space to queue audio packet\n");                  error("No space to queue audio packet\n");
777                  return;                  return;
# Line 441  rdpsnd_queue_write(STREAM s, uint16 tick Line 783  rdpsnd_queue_write(STREAM s, uint16 tick
783          packet->tick = tick;          packet->tick = tick;
784          packet->index = index;          packet->index = index;
785    
786          if (!g_dsp_busy)          gettimeofday(&packet->arrive_tv, NULL);
                 current_driver->wave_out_play();  
787  }  }
788    
789  inline struct audio_packet *  struct audio_packet *
790  rdpsnd_queue_current_packet(void)  rdpsnd_queue_current_packet(void)
791  {  {
792          return &packet_queue[queue_lo];          return &packet_queue[queue_lo];
793  }  }
794    
795  inline BOOL  RD_BOOL
796  rdpsnd_queue_empty(void)  rdpsnd_queue_empty(void)
797  {  {
798          return (queue_lo == queue_hi);          return (queue_lo == queue_hi);
799  }  }
800    
801  inline void  static void
802  rdpsnd_queue_init(void)  rdpsnd_queue_init(void)
803  {  {
804          queue_lo = queue_hi = 0;          queue_pending = queue_lo = queue_hi = 0;
805  }  }
806    
807  inline void  void
808  rdpsnd_queue_next(void)  rdpsnd_queue_next(unsigned long completed_in_us)
809  {  {
810          xfree(packet_queue[queue_lo].s.data);          struct audio_packet *packet;
811    
812            assert(!rdpsnd_queue_empty());
813    
814            packet = &packet_queue[queue_lo];
815    
816            gettimeofday(&packet->completion_tv, NULL);
817    
818            packet->completion_tv.tv_usec += completed_in_us;
819            packet->completion_tv.tv_sec += packet->completion_tv.tv_usec / 1000000;
820            packet->completion_tv.tv_usec %= 1000000;
821    
822          queue_lo = (queue_lo + 1) % MAX_QUEUE;          queue_lo = (queue_lo + 1) % MAX_QUEUE;
823    
824            rdpsnd_queue_complete_pending();
825  }  }
826    
827  inline int  int
828  rdpsnd_queue_next_tick(void)  rdpsnd_queue_next_tick(void)
829  {  {
830          if (((queue_lo + 1) % MAX_QUEUE) != queue_hi)          if (((queue_lo + 1) % MAX_QUEUE) != queue_hi)
# Line 482  rdpsnd_queue_next_tick(void) Line 836  rdpsnd_queue_next_tick(void)
836                  return (packet_queue[queue_lo].tick + 65535) % 65536;                  return (packet_queue[queue_lo].tick + 65535) % 65536;
837          }          }
838  }  }
839    
840    static void
841    rdpsnd_queue_complete_pending(void)
842    {
843            struct timeval now;
844            long elapsed;
845            struct audio_packet *packet;
846    
847            gettimeofday(&now, NULL);
848    
849            while (queue_pending != queue_lo)
850            {
851                    packet = &packet_queue[queue_pending];
852    
853                    if (now.tv_sec < packet->completion_tv.tv_sec)
854                            break;
855    
856                    if ((now.tv_sec == packet->completion_tv.tv_sec) &&
857                        (now.tv_usec < packet->completion_tv.tv_usec))
858                            break;
859    
860                    elapsed = (packet->completion_tv.tv_sec - packet->arrive_tv.tv_sec) * 1000000 +
861                            (packet->completion_tv.tv_usec - packet->arrive_tv.tv_usec);
862                    elapsed /= 1000;
863    
864                    xfree(packet->s.data);
865                    rdpsnd_send_completion((packet->tick + elapsed) % 65536, packet->index);
866                    queue_pending = (queue_pending + 1) % MAX_QUEUE;
867            }
868    }
869    
870    static long
871    rdpsnd_queue_next_completion(void)
872    {
873            struct audio_packet *packet;
874            long remaining;
875            struct timeval now;
876    
877            if (queue_pending == queue_lo)
878                    return -1;
879    
880            gettimeofday(&now, NULL);
881    
882            packet = &packet_queue[queue_pending];
883    
884            remaining = (packet->completion_tv.tv_sec - now.tv_sec) * 1000000 +
885                    (packet->completion_tv.tv_usec - now.tv_usec);
886    
887            if (remaining < 0)
888                    return 0;
889    
890            return remaining;
891    }

Legend:
Removed from v.1298  
changed lines
  Added in v.1427

  ViewVC Help
Powered by ViewVC 1.1.26