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

Contents of /sourceforge.net/trunk/rdesktop/rdpsnd.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1411 - (show annotations)
Mon Jun 18 08:31:27 2007 UTC (16 years, 11 months ago) by ossman_
File MIME type: text/plain
File size: 20568 byte(s)
None of the drivers requires it to be open to determine supported formats,
so let's not require it. This allows the device to be busy when rdesktop starts
but can be used later when it becomes free.

1 /* -*- c-basic-offset: 8 -*-
2 rdesktop: A Remote Desktop Protocol client.
3 Sound Channel Process Functions
4 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
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include <assert.h>
24
25 #include "rdesktop.h"
26 #include "rdpsnd.h"
27 #include "rdpsnd_dsp.h"
28
29 #define RDPSND_CLOSE 1
30 #define RDPSND_WRITE 2
31 #define RDPSND_SET_VOLUME 3
32 #define RDPSND_UNKNOWN4 4
33 #define RDPSND_COMPLETION 5
34 #define RDPSND_PING 6
35 #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
46 #define MAX_QUEUE 50
47
48 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 RD_BOOL device_open;
54 static RD_BOOL rec_device_open;
55
56 static RD_WAVEFORMATEX formats[MAX_FORMATS];
57 static unsigned int format_count;
58 static unsigned int current_format;
59
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];
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)
81 {
82 STREAM s;
83
84 s = channel_init(rdpsnd_channel, size + 4);
85 out_uint16_le(s, type);
86 out_uint16_le(s, size);
87 return s;
88 }
89
90 static void
91 rdpsnd_send(STREAM s)
92 {
93 channel_send(s, rdpsnd_channel);
94 }
95
96 static void
97 rdpsnd_send_completion(uint16 tick, uint8 packet_index)
98 {
99 STREAM s;
100
101 s = rdpsnd_init_packet(RDPSND_COMPLETION, 4);
102 out_uint16_le(s, tick);
103 out_uint8(s, packet_index);
104 out_uint8(s, 0);
105 s_mark_end(s);
106 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
210 rdpsnd_process_negotiate(STREAM in)
211 {
212 uint16 in_format_count, i;
213 uint8 pad;
214 uint16 version;
215 RD_WAVEFORMATEX *format;
216 STREAM out;
217 RD_BOOL device_available = False;
218 int readcnt;
219 int discardcnt;
220
221 in_uint8s(in, 14); /* initial bytes not valid from server */
222 in_uint16_le(in, in_format_count);
223 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;
240 if (s_check_rem(in, 18 * in_format_count))
241 {
242 for (i = 0; i < in_format_count; i++)
243 {
244 format = &formats[format_count];
245 in_uint16_le(in, format->wFormatTag);
246 in_uint16_le(in, format->nChannels);
247 in_uint32_le(in, format->nSamplesPerSec);
248 in_uint32_le(in, format->nAvgBytesPerSec);
249 in_uint16_le(in, format->nBlockAlign);
250 in_uint16_le(in, format->wBitsPerSample);
251 in_uint16_le(in, format->cbSize);
252
253 /* 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 (current_driver && current_driver->wave_out_format_supported(format))
267 {
268 format_count++;
269 if (format_count == MAX_FORMATS)
270 break;
271 }
272 }
273 }
274
275 out = rdpsnd_init_packet(RDPSND_NEGOTIATE | 0x200, 20 + 18 * format_count);
276 out_uint32_le(out, 0x00800003); /* flags */
277 out_uint32(out, 0xffffffff); /* volume */
278 out_uint32(out, 0); /* pitch */
279 out_uint16(out, 0); /* UDP port */
280
281 out_uint16_le(out, format_count);
282 out_uint8(out, 0); /* padding */
283 out_uint16_le(out, 2); /* version */
284 out_uint8(out, 0); /* padding */
285
286 for (i = 0; i < format_count; i++)
287 {
288 format = &formats[i];
289 out_uint16_le(out, format->wFormatTag);
290 out_uint16_le(out, format->nChannels);
291 out_uint32_le(out, format->nSamplesPerSec);
292 out_uint32_le(out, format->nAvgBytesPerSec);
293 out_uint16_le(out, format->nBlockAlign);
294 out_uint16_le(out, format->wBitsPerSample);
295 out_uint16(out, 0); /* cbSize */
296 }
297
298 s_mark_end(out);
299
300 DEBUG_SOUND(("RDPSND: -> RDPSND_NEGOTIATE(formats: %d)\n", (int) format_count));
301
302 rdpsnd_send(out);
303 }
304
305 static void
306 rdpsnd_process_ping(STREAM in)
307 {
308 uint16 tick;
309 STREAM out;
310
311 in_uint16_le(in, tick);
312
313 DEBUG_SOUND(("RDPSND: RDPSND_PING(tick: 0x%04x)\n", (unsigned) tick));
314
315 out = rdpsnd_init_packet(RDPSND_PING | 0x2300, 4);
316 out_uint16_le(out, tick);
317 out_uint16_le(out, 0);
318 s_mark_end(out);
319 rdpsnd_send(out);
320
321 DEBUG_SOUND(("RDPSND: -> (tick: 0x%04x)\n", (unsigned) tick));
322 }
323
324 static void
325 rdpsnd_process_rec_negotiate(STREAM in)
326 {
327 uint16 in_format_count, i;
328 uint16 version;
329 RD_WAVEFORMATEX *format;
330 STREAM out;
331 RD_BOOL device_available = False;
332 int readcnt;
333 int discardcnt;
334
335 in_uint8s(in, 8); /* initial bytes not valid from server */
336 in_uint16_le(in, in_format_count);
337 in_uint16_le(in, version);
338
339 DEBUG_SOUND(("RDPSND: RDPSND_REC_NEGOTIATE(formats: %d, version: %x)\n",
340 (int) in_format_count, (unsigned) version));
341
342 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 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 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 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 (current_driver && 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 (!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 ((s->end - s->p) < 4)
548 {
549 error("RDPSND: Split at packet header. Things will go south from here...\n");
550 return;
551 }
552 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 if ((packet.p - packet.data) < 12)
571 len = MIN(len, 12 - (packet.p - packet.data));
572 else if ((packet.p - packet.data) == 12)
573 {
574 DEBUG_SOUND(("RDPSND: Eating 4 bytes of %d bytes...\n",
575 len));
576 in_uint8s(s, 4);
577 len -= 4;
578 }
579 }
580
581 in_uint8a(s, packet.p, len);
582 packet.p += len;
583 }
584
585 /* Packet fully assembled */
586 if (packet.p == packet.end)
587 {
588 packet.p = packet.data;
589 rdpsnd_process_packet(packet_opcode, &packet);
590 packet.size = 0;
591 }
592 }
593 }
594
595 static RD_BOOL
596 rdpsnddbg_line_handler(const char *line, void *data)
597 {
598 #ifdef WITH_DEBUG_SOUND
599 fprintf(stderr, "SNDDBG: %s\n", line);
600 #endif
601 return True;
602 }
603
604 static void
605 rdpsnddbg_process(STREAM s)
606 {
607 unsigned int pkglen;
608 static char *rest = NULL;
609 char *buf;
610
611 pkglen = s->end - s->p;
612 /* str_handle_lines requires null terminated strings */
613 buf = (char *) xmalloc(pkglen + 1);
614 STRNCPY(buf, (char *) s->p, pkglen + 1);
615
616 str_handle_lines(buf, &rest, rdpsnddbg_line_handler, NULL);
617
618 xfree(buf);
619 }
620
621 static void
622 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 RD_BOOL
658 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 =
670 channel_register("rdpsnd", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP,
671 rdpsnd_process);
672
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 }

  ViewVC Help
Powered by ViewVC 1.1.26