/[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 474 by matthewc, Tue Sep 30 09:11:08 2003 UTC revision 1382 by jsorg71, Thu Jan 18 05:42:11 2007 UTC
# Line 1  Line 1 
1  /*  /* -*- 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 19  Line 20 
20     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */  */
22    
23    #include <assert.h>
24    
25  #include "rdesktop.h"  #include "rdesktop.h"
26    #include "rdpsnd.h"
27    #include "rdpsnd_dsp.h"
28    
29  #define RDPSND_CLOSE            1  #define RDPSND_CLOSE            1
30  #define RDPSND_WRITE            2  #define RDPSND_WRITE            2
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_UNKNOWN6         6  #define RDPSND_PING                     6
35  #define RDPSND_NEGOTIATE        7  #define RDPSND_NEGOTIATE        7
36    
37    #define RDPSND_REC_NEGOTIATE    39
38    #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  #define MAX_FORMATS             10  #define MAX_FORMATS             10
46    #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;
51    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    
60  STREAM  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];
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);
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
80  rdpsnd_init_packet(uint16 type, uint16 size)  rdpsnd_init_packet(uint16 type, uint16 size)
81  {  {
82          STREAM s;          STREAM s;
83    
84          s = channel_init(rdpsnd_channel, size+4);          s = channel_init(rdpsnd_channel, size + 4);
85          out_uint16_le(s, type);          out_uint16_le(s, type);
86          out_uint16_le(s, size);          out_uint16_le(s, size);
87          return s;          return s;
88  }  }
89    
90  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 rdpsnd_send_completion(uint16 tick, uint8 packet_index)  static void
97    rdpsnd_send_completion(uint16 tick, uint8 packet_index)
98  {  {
99          STREAM s;          STREAM s;
100    
101          s = rdpsnd_init_packet(RDPSND_COMPLETION, 4);          s = rdpsnd_init_packet(RDPSND_COMPLETION, 4);
102          out_uint16_le(s, tick+50);          out_uint16_le(s, tick);
103          out_uint8(s, packet_index);          out_uint8(s, packet_index);
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  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
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            RD_BOOL device_available = False;
218            int readcnt;
219            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 && !device_available && current_driver->wave_out_open())
234            {
235                    current_driver->wave_out_close();
236                    device_available = True;
237            }
238    
239          format_count = 0;          format_count = 0;
240          if (s_check_rem(in, 18*in_format_count))          if (s_check_rem(in, 18 * in_format_count))
241          {          {
242                  for (i = 0; i < in_format_count; i++)                  for (i = 0; i < in_format_count; i++)
243                  {                  {
# Line 97  rdpsnd_process_negotiate(STREAM in) Line 250  rdpsnd_process_negotiate(STREAM in)
250                          in_uint16_le(in, format->wBitsPerSample);                          in_uint16_le(in, format->wBitsPerSample);
251                          in_uint16_le(in, format->cbSize);                          in_uint16_le(in, format->cbSize);
252    
253                          if (wave_out_format_supported(format))                          /* read in the buffer of unknown use */
254                            readcnt = format->cbSize;
255                            discardcnt = 0;
256                            if (format->cbSize > MAX_CBSIZE)
257                            {
258                                    fprintf(stderr, "cbSize too large for buffer: %d\n",
259                                            format->cbSize);
260                                    readcnt = MAX_CBSIZE;
261                                    discardcnt = format->cbSize - MAX_CBSIZE;
262                            }
263                            in_uint8a(in, format->cb, readcnt);
264                            in_uint8s(in, discardcnt);
265    
266                            if (device_available && 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 106  rdpsnd_process_negotiate(STREAM in) Line 272  rdpsnd_process_negotiate(STREAM in)
272                  }                  }
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 126  rdpsnd_process_negotiate(STREAM in) Line 292  rdpsnd_process_negotiate(STREAM in)
292                  out_uint32_le(out, format->nAvgBytesPerSec);                  out_uint32_le(out, format->nAvgBytesPerSec);
293                  out_uint16_le(out, format->nBlockAlign);                  out_uint16_le(out, format->nBlockAlign);
294                  out_uint16_le(out, format->wBitsPerSample);                  out_uint16_le(out, format->wBitsPerSample);
295                  out_uint16(out, 0); /* cbSize */                  out_uint16(out, 0);     /* cbSize */
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  void  static void
306  rdpsnd_process_unknown6(STREAM in)  rdpsnd_process_ping(STREAM in)
307  {  {
308          uint16 unknown1, unknown2;          uint16 tick;
309          STREAM out;          STREAM out;
310    
311          /* in_uint8s(in, 4); unknown */          in_uint16_le(in, tick);
312          in_uint16_le(in, unknown1);  
313          in_uint16_le(in, unknown2);          DEBUG_SOUND(("RDPSND: RDPSND_PING(tick: 0x%04x)\n", (unsigned) tick));
314    
315          out = rdpsnd_init_packet(RDPSND_UNKNOWN6 | 0x2300, 4);          out = rdpsnd_init_packet(RDPSND_PING | 0x2300, 4);
316          out_uint16_le(out, unknown1);          out_uint16_le(out, tick);
317          out_uint16_le(out, unknown2);          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  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          static uint16 tick, format;          RD_WAVEFORMATEX *format;
330          static uint8 packet_index;          STREAM out;
331          static BOOL awaiting_data_packet;          RD_BOOL device_available = False;
332            int readcnt;
333            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            }
351    
352            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                          error("RDPSND: Invalid format index\n");                          format = &rec_formats[rec_format_count];
358                          return;                          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                                    fprintf(stderr, "cbSize too large for buffer: %d\n",
372                                            format->cbSize);
373                                    readcnt = MAX_CBSIZE;
374                                    discardcnt = format->cbSize - MAX_CBSIZE;
375                            }
376                            in_uint8a(in, format->cb, readcnt);
377                            in_uint8s(in, discardcnt);
378    
379                            if (device_available && current_driver->wave_in_format_supported(format))
380                            {
381                                    rec_format_count++;
382                                    if (rec_format_count == MAX_FORMATS)
383                                            break;
384                            }
385                  }                  }
386            }
387    
388            out = rdpsnd_init_packet(RDPSND_REC_NEGOTIATE, 12 + 18 * rec_format_count);
389            out_uint32_le(out, 0x00000000); /* flags */
390            out_uint32_le(out, 0xffffffff); /* volume */
391            out_uint16_le(out, rec_format_count);
392            out_uint16_le(out, 1);  /* version */
393    
394            for (i = 0; i < rec_format_count; i++)
395            {
396                    format = &rec_formats[i];
397                    out_uint16_le(out, format->wFormatTag);
398                    out_uint16_le(out, format->nChannels);
399                    out_uint32_le(out, format->nSamplesPerSec);
400                    out_uint32_le(out, format->nAvgBytesPerSec);
401                    out_uint16_le(out, format->nBlockAlign);
402                    out_uint16_le(out, format->wBitsPerSample);
403                    out_uint16(out, 0);     /* cbSize */
404            }
405    
406            s_mark_end(out);
407    
408            DEBUG_SOUND(("RDPSND: -> RDPSND_REC_NEGOTIATE(formats: %d)\n", (int) rec_format_count));
409    
410            rdpsnd_send(out);
411    }
412    
413    static void
414    rdpsnd_process_packet(uint8 opcode, STREAM s)
415    {
416            uint16 vol_left, vol_right;
417            static uint16 tick, format;
418            static uint8 packet_index;
419    
420            switch (opcode)
421            {
422                    case RDPSND_WRITE:
423                            in_uint16_le(s, tick);
424                            in_uint16_le(s, format);
425                            in_uint8(s, packet_index);
426                            in_uint8s(s, 3);
427                            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));
428    
429                            if (format >= MAX_FORMATS)
430                            {
431                                    error("RDPSND: Invalid format index\n");
432                                    break;
433                            }
434    
435                            if (!device_open || (format != current_format))
436                            {
437                                    /*
438                                     * If we haven't selected a device by now, then either
439                                     * we've failed to find a working device, or the server
440                                     * is sending bogus RDPSND_WRITE.
441                                     */
442                                    if (!current_driver)
443                                    {
444                                            rdpsnd_send_completion(tick, packet_index);
445                                            break;
446                                    }
447                                    if (!device_open && !current_driver->wave_out_open())
448                                    {
449                                            rdpsnd_send_completion(tick, packet_index);
450                                            break;
451                                    }
452                                    if (!current_driver->wave_out_set_format(&formats[format]))
453                                    {
454                                            rdpsnd_send_completion(tick, packet_index);
455                                            current_driver->wave_out_close();
456                                            device_open = False;
457                                            break;
458                                    }
459                                    device_open = True;
460                                    current_format = format;
461                            }
462    
463                            rdpsnd_queue_write(rdpsnd_dsp_process
464                                               (s->p, s->end - s->p, current_driver,
465                                                &formats[current_format]), tick, packet_index);
466                            return;
467                            break;
468                    case RDPSND_CLOSE:
469                            DEBUG_SOUND(("RDPSND: RDPSND_CLOSE()\n"));
470                            if (device_open)
471                                    current_driver->wave_out_close();
472                            device_open = False;
473                            break;
474                    case RDPSND_NEGOTIATE:
475                            rdpsnd_process_negotiate(s);
476                            break;
477                    case RDPSND_PING:
478                            rdpsnd_process_ping(s);
479                            break;
480                    case RDPSND_SET_VOLUME:
481                            in_uint16_le(s, vol_left);
482                            in_uint16_le(s, vol_right);
483                            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));
484                            if (device_open)
485                                    current_driver->wave_out_volume(vol_left, vol_right);
486                            break;
487                    case RDPSND_REC_NEGOTIATE:
488                            rdpsnd_process_rec_negotiate(s);
489                            break;
490                    case RDPSND_REC_START:
491                            in_uint16_le(s, format);
492                            DEBUG_SOUND(("RDPSND: RDPSND_REC_START(format: %u)\n", (unsigned) format));
493    
494                            if (format >= MAX_FORMATS)
495                            {
496                                    error("RDPSND: Invalid format index\n");
497                                    break;
498                            }
499    
500                            if (rec_device_open)
501                            {
502                                    error("RDPSND: Multiple RDPSND_REC_START\n");
503                                    break;
504                            }
505    
506                            if (!current_driver->wave_in_open())
507                                    break;
508    
509                  if (!device_open || (format != current_format))                          if (!current_driver->wave_in_set_format(&rec_formats[format]))
510                            {
511                                    error("RDPSND: Device not accepting format\n");
512                                    current_driver->wave_in_close();
513                                    break;
514                            }
515                            rec_device_open = True;
516                            break;
517                    case RDPSND_REC_STOP:
518                            DEBUG_SOUND(("RDPSND: RDPSND_REC_STOP()\n"));
519                            rdpsnd_flush_record();
520                            if (rec_device_open)
521                                    current_driver->wave_in_close();
522                            rec_device_open = False;
523                            break;
524                    case RDPSND_REC_SET_VOLUME:
525                            in_uint16_le(s, vol_left);
526                            in_uint16_le(s, vol_right);
527                            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));
528                            if (rec_device_open)
529                                    current_driver->wave_in_volume(vol_left, vol_right);
530                            break;
531                    default:
532                            unimpl("RDPSND packet type %x\n", opcode);
533                            break;
534            }
535    }
536    
537    static void
538    rdpsnd_process(STREAM s)
539    {
540            uint16 len;
541    
542            while (!s_check_end(s))
543            {
544                    /* New packet */
545                    if (packet.size == 0)
546                  {                  {
547                          if (!device_open && !wave_out_open())                          if ((s->end - s->p) < 4)
548                          {                          {
549                                  rdpsnd_send_completion(tick, packet_index);                                  error("RDPSND: Split at packet header. Things will go south from here...\n");
550                                  return;                                  return;
551                          }                          }
552                          if (!wave_out_set_format(&formats[format]))                          in_uint8(s, packet_opcode);
553                            in_uint8s(s, 1);        /* Padding */
554                            in_uint16_le(s, len);
555    
556                            DEBUG_SOUND(("RDPSND: == Opcode %x Length: %d ==\n",
557                                         (int) packet_opcode, (int) len));
558    
559                            packet.p = packet.data;
560                            packet.end = packet.data + len;
561                            packet.size = len;
562                    }
563                    else
564                    {
565                            len = MIN(s->end - s->p, packet.end - packet.p);
566    
567                            /* Microsoft's server is so broken it's not even funny... */
568                            if (packet_opcode == RDPSND_WRITE)
569                          {                          {
570                                  rdpsnd_send_completion(tick, packet_index);                                  if ((packet.p - packet.data) < 12)
571                                  wave_out_close();                                          len = MIN(len, 12 - (packet.p - packet.data));
572                                  device_open = False;                                  else if ((packet.p - packet.data) == 12)
573                                  return;                                  {
574                                            DEBUG_SOUND(("RDPSND: Eating 4 bytes of %d bytes...\n",
575                                                         len));
576                                            in_uint8s(s, 4);
577                                            len -= 4;
578                                    }
579                          }                          }
580                          device_open = True;  
581                          current_format = format;                          in_uint8a(s, packet.p, len);
582                            packet.p += len;
583                  }                  }
584    
585                  wave_out_write(s, tick, packet_index);                  /* Packet fully assembled */
586                  awaiting_data_packet = False;                  if (packet.p == packet.end)
587                  return;                  {
588                            packet.p = packet.data;
589                            rdpsnd_process_packet(packet_opcode, &packet);
590                            packet.size = 0;
591                    }
592          }          }
593    }
594    
595          in_uint8(s, type);  static RD_BOOL
596          in_uint8s(s, 1); /* unknown? */  rdpsnddbg_line_handler(const char *line, void *data)
597          in_uint16_le(s, datalen);  {
598    #ifdef WITH_DEBUG_SOUND
599          switch (type)          fprintf(stderr, "SNDDBG: %s\n", line);
600          {  #endif
601          case RDPSND_WRITE:          return True;
602                  in_uint16_le(s, tick);  }
603                  in_uint16_le(s, format);  
604                  in_uint8(s, packet_index);  static void
605                  awaiting_data_packet = True;  rdpsnddbg_process(STREAM s)
606                  break;  {
607          case RDPSND_CLOSE:          unsigned int pkglen;
608                  wave_out_close();          static char *rest = NULL;
609                  device_open = False;          char *buf;
610                  break;  
611          case RDPSND_NEGOTIATE:          pkglen = s->end - s->p;
612                  rdpsnd_process_negotiate(s);          /* str_handle_lines requires null terminated strings */
613                  break;          buf = (char *) xmalloc(pkglen + 1);
614          case RDPSND_UNKNOWN6:          STRNCPY(buf, (char *) s->p, pkglen + 1);
615                  rdpsnd_process_unknown6(s);  
616                  break;          str_handle_lines(buf, &rest, rdpsnddbg_line_handler, NULL);
617          case RDPSND_SET_VOLUME:  
618                  /* uint32 volume */          xfree(buf);
619                  break;  }
620          default:  
621                  unimpl("RDPSND packet type %d\n", type);  static void
622                  break;  rdpsnd_register_drivers(char *options)
623          }  {
624            struct audio_driver **reg;
625    
626            /* The order of registrations define the probe-order
627               when opening the device for the first time */
628            reg = &drivers;
629    #if defined(RDPSND_ALSA)
630            *reg = alsa_register(options);
631            assert(*reg);
632            reg = &((*reg)->next);
633    #endif
634    #if defined(RDPSND_SUN)
635            *reg = sun_register(options);
636            assert(*reg);
637            reg = &((*reg)->next);
638    #endif
639    #if defined(RDPSND_OSS)
640            *reg = oss_register(options);
641            assert(*reg);
642            reg = &((*reg)->next);
643    #endif
644    #if defined(RDPSND_SGI)
645            *reg = sgi_register(options);
646            assert(*reg);
647            reg = &((*reg)->next);
648    #endif
649    #if defined(RDPSND_LIBAO)
650            *reg = libao_register(options);
651            assert(*reg);
652            reg = &((*reg)->next);
653    #endif
654            *reg = NULL;
655  }  }
656    
657  BOOL  RD_BOOL
658  rdpsnd_init(void)  rdpsnd_init(char *optarg)
659  {  {
660            struct audio_driver *pos;
661            char *driver = NULL, *options = NULL;
662    
663            drivers = NULL;
664    
665            packet.data = (uint8 *) xmalloc(65536);
666            packet.p = packet.end = packet.data;
667            packet.size = 0;
668    
669          rdpsnd_channel =          rdpsnd_channel =
670                  channel_register("rdpsnd", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP,                  channel_register("rdpsnd", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP,
671                                   rdpsnd_process);                                   rdpsnd_process);
672          return (rdpsnd_channel != NULL);  
673            rdpsnddbg_channel =
674                    channel_register("snddbg", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP,
675                                     rdpsnddbg_process);
676    
677            if ((rdpsnd_channel == NULL) || (rdpsnddbg_channel == NULL))
678            {
679                    error("channel_register\n");
680                    return False;
681            }
682    
683            rdpsnd_queue_init();
684    
685            if (optarg != NULL && strlen(optarg) > 0)
686            {
687                    driver = options = optarg;
688    
689                    while (*options != '\0' && *options != ':')
690                            options++;
691    
692                    if (*options == ':')
693                    {
694                            *options = '\0';
695                            options++;
696                    }
697    
698                    if (*options == '\0')
699                            options = NULL;
700            }
701    
702            rdpsnd_register_drivers(options);
703    
704            if (!driver)
705                    return True;
706    
707            pos = drivers;
708            while (pos != NULL)
709            {
710                    if (!strcmp(pos->name, driver))
711                    {
712                            DEBUG(("selected %s\n", pos->name));
713                            current_driver = pos;
714                            return True;
715                    }
716                    pos = pos->next;
717            }
718            return False;
719    }
720    
721    void
722    rdpsnd_show_help(void)
723    {
724            struct audio_driver *pos;
725    
726            rdpsnd_register_drivers(NULL);
727    
728            pos = drivers;
729            while (pos != NULL)
730            {
731                    fprintf(stderr, "                     %s:\t%s\n", pos->name, pos->description);
732                    pos = pos->next;
733            }
734    }
735    
736    void
737    rdpsnd_add_fds(int *n, fd_set * rfds, fd_set * wfds, struct timeval *tv)
738    {
739            long next_pending;
740    
741            if (device_open || rec_device_open)
742                    current_driver->add_fds(n, rfds, wfds, tv);
743    
744            next_pending = rdpsnd_queue_next_completion();
745            if (next_pending >= 0)
746            {
747                    long cur_timeout;
748    
749                    cur_timeout = tv->tv_sec * 1000000 + tv->tv_usec;
750                    if (cur_timeout > next_pending)
751                    {
752                            tv->tv_sec = next_pending / 1000000;
753                            tv->tv_usec = next_pending % 1000000;
754                    }
755            }
756    }
757    
758    void
759    rdpsnd_check_fds(fd_set * rfds, fd_set * wfds)
760    {
761            rdpsnd_queue_complete_pending();
762    
763            if (device_open || rec_device_open)
764                    current_driver->check_fds(rfds, wfds);
765    }
766    
767    static void
768    rdpsnd_queue_write(STREAM s, uint16 tick, uint8 index)
769    {
770            struct audio_packet *packet = &packet_queue[queue_hi];
771            unsigned int next_hi = (queue_hi + 1) % MAX_QUEUE;
772    
773            if (next_hi == queue_pending)
774            {
775                    error("No space to queue audio packet\n");
776                    return;
777            }
778    
779            queue_hi = next_hi;
780    
781            packet->s = *s;
782            packet->tick = tick;
783            packet->index = index;
784    
785            gettimeofday(&packet->arrive_tv, NULL);
786    }
787    
788    struct audio_packet *
789    rdpsnd_queue_current_packet(void)
790    {
791            return &packet_queue[queue_lo];
792    }
793    
794    RD_BOOL
795    rdpsnd_queue_empty(void)
796    {
797            return (queue_lo == queue_hi);
798    }
799    
800    static void
801    rdpsnd_queue_init(void)
802    {
803            queue_pending = queue_lo = queue_hi = 0;
804    }
805    
806    void
807    rdpsnd_queue_next(unsigned long completed_in_us)
808    {
809            struct audio_packet *packet;
810    
811            assert(!rdpsnd_queue_empty());
812    
813            packet = &packet_queue[queue_lo];
814    
815            gettimeofday(&packet->completion_tv, NULL);
816    
817            packet->completion_tv.tv_usec += completed_in_us;
818            packet->completion_tv.tv_sec += packet->completion_tv.tv_usec / 1000000;
819            packet->completion_tv.tv_usec %= 1000000;
820    
821            queue_lo = (queue_lo + 1) % MAX_QUEUE;
822    
823            rdpsnd_queue_complete_pending();
824    }
825    
826    int
827    rdpsnd_queue_next_tick(void)
828    {
829            if (((queue_lo + 1) % MAX_QUEUE) != queue_hi)
830            {
831                    return packet_queue[(queue_lo + 1) % MAX_QUEUE].tick;
832            }
833            else
834            {
835                    return (packet_queue[queue_lo].tick + 65535) % 65536;
836            }
837    }
838    
839    static void
840    rdpsnd_queue_complete_pending(void)
841    {
842            struct timeval now;
843            long elapsed;
844            struct audio_packet *packet;
845    
846            gettimeofday(&now, NULL);
847    
848            while (queue_pending != queue_lo)
849            {
850                    packet = &packet_queue[queue_pending];
851    
852                    if (now.tv_sec < packet->completion_tv.tv_sec)
853                            break;
854    
855                    if ((now.tv_sec == packet->completion_tv.tv_sec) &&
856                        (now.tv_usec < packet->completion_tv.tv_usec))
857                            break;
858    
859                    elapsed = (packet->completion_tv.tv_sec - packet->arrive_tv.tv_sec) * 1000000 +
860                            (packet->completion_tv.tv_usec - packet->arrive_tv.tv_usec);
861                    elapsed /= 1000;
862    
863                    xfree(packet->s.data);
864                    rdpsnd_send_completion((packet->tick + elapsed) % 65536, packet->index);
865                    queue_pending = (queue_pending + 1) % MAX_QUEUE;
866            }
867    }
868    
869    static long
870    rdpsnd_queue_next_completion(void)
871    {
872            struct audio_packet *packet;
873            long remaining;
874            struct timeval now;
875    
876            if (queue_pending == queue_lo)
877                    return -1;
878    
879            gettimeofday(&now, NULL);
880    
881            packet = &packet_queue[queue_pending];
882    
883            remaining = (packet->completion_tv.tv_sec - now.tv_sec) * 1000000 +
884                    (packet->completion_tv.tv_usec - now.tv_usec);
885    
886            if (remaining < 0)
887                    return 0;
888    
889            return remaining;
890  }  }

Legend:
Removed from v.474  
changed lines
  Added in v.1382

  ViewVC Help
Powered by ViewVC 1.1.26