/[rdesktop]/jpeg/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

Annotation of /jpeg/rdesktop/trunk/rdpsnd.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1507 - (hide annotations)
Mon Jul 20 16:45:11 2009 UTC (14 years, 10 months ago) by dpavlin
File MIME type: text/plain
File size: 20841 byte(s)
branch for integration of Daniel Jarboe <daniel.jarboe(at)gmail.com>
patches for jpeg
1 astrand 963 /* -*- c-basic-offset: 8 -*-
2 matthewc 474 rdesktop: A Remote Desktop Protocol client.
3     Sound Channel Process Functions
4 jsorg71 1475 Copyright 2006-2008 Pierre Ossman <ossman@cendio.se> for Cendio AB
5     Copyright (C) Matthew Chapman 2003-2008
6 matthewc 474 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 ossman_ 1298 #include <assert.h>
24    
25 matthewc 432 #include "rdesktop.h"
26 stargo 1254 #include "rdpsnd.h"
27 stargo 1258 #include "rdpsnd_dsp.h"
28 matthewc 432
29 matthewc 474 #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 ossman_ 1339 #define RDPSND_PING 6
35 matthewc 474 #define RDPSND_NEGOTIATE 7
36    
37 ossman_ 1359 #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 matthewc 474 #define MAX_FORMATS 10
46 ossman_ 1359 #define MAX_QUEUE 50
47 matthewc 474
48 matthewc 432 static VCHANNEL *rdpsnd_channel;
49 ossman_ 1359 static VCHANNEL *rdpsnddbg_channel;
50 stargo 1255 static struct audio_driver *drivers = NULL;
51 stargo 1256 struct audio_driver *current_driver = NULL;
52 matthewc 432
53 jsorg71 1372 static RD_BOOL device_open;
54     static RD_BOOL rec_device_open;
55 ossman_ 1359
56 jsorg71 1364 static RD_WAVEFORMATEX formats[MAX_FORMATS];
57 matthewc 474 static unsigned int format_count;
58     static unsigned int current_format;
59 ossman_ 1359
60 jsorg71 1364 static RD_WAVEFORMATEX rec_formats[MAX_FORMATS];
61 ossman_ 1359 static unsigned int rec_format_count;
62 ossman_ 1430 static unsigned int rec_current_format;
63 ossman_ 1359
64 ossman_ 1302 unsigned int queue_hi, queue_lo, queue_pending;
65 stargo 1256 struct audio_packet packet_queue[MAX_QUEUE];
66 matthewc 474
67 ossman_ 1359 static char record_buffer[8192];
68 jsorg71 1382 static uint32 record_buffer_size;
69 ossman_ 1359
70 ossman_ 1342 static uint8 packet_opcode;
71     static struct stream packet;
72    
73 stargo 1255 void (*wave_out_play) (void);
74    
75 ossman_ 1302 static void rdpsnd_queue_write(STREAM s, uint16 tick, uint8 index);
76     static void rdpsnd_queue_init(void);
77     static void rdpsnd_queue_complete_pending(void);
78     static long rdpsnd_queue_next_completion(void);
79    
80 astrand 665 static STREAM
81 matthewc 474 rdpsnd_init_packet(uint16 type, uint16 size)
82     {
83     STREAM s;
84    
85 astrand 499 s = channel_init(rdpsnd_channel, size + 4);
86 matthewc 474 out_uint16_le(s, type);
87     out_uint16_le(s, size);
88     return s;
89     }
90    
91 astrand 665 static void
92 matthewc 474 rdpsnd_send(STREAM s)
93     {
94     channel_send(s, rdpsnd_channel);
95     }
96    
97 ossman_ 1302 static void
98 astrand 499 rdpsnd_send_completion(uint16 tick, uint8 packet_index)
99 matthewc 474 {
100     STREAM s;
101    
102     s = rdpsnd_init_packet(RDPSND_COMPLETION, 4);
103 stargo 1254 out_uint16_le(s, tick);
104 matthewc 474 out_uint8(s, packet_index);
105     out_uint8(s, 0);
106     s_mark_end(s);
107     rdpsnd_send(s);
108 ossman_ 1343
109     DEBUG_SOUND(("RDPSND: -> RDPSND_COMPLETION(tick: %u, index: %u)\n",
110     (unsigned) tick, (unsigned) packet_index));
111 matthewc 474 }
112    
113 ossman_ 1359 static void
114     rdpsnd_flush_record(void)
115     {
116     STREAM s;
117     unsigned int chunk_size;
118     char *data;
119 ossman_ 1346
120 ossman_ 1359 if (record_buffer_size == 0)
121     return;
122    
123     assert(record_buffer_size <= sizeof(record_buffer));
124    
125     data = record_buffer;
126    
127     /*
128     * Microsoft's RDP server keeps dropping chunks, so we need to
129     * transmit everything inside one channel fragment or we risk
130     * making the rdpsnd server go out of sync with the byte stream.
131     */
132     while (record_buffer_size)
133     {
134     if (record_buffer_size < 1596)
135     chunk_size = record_buffer_size;
136     else
137     chunk_size = 1596;
138    
139     s = rdpsnd_init_packet(RDPSND_REC_DATA, chunk_size);
140     out_uint8p(s, data, chunk_size);
141    
142     s_mark_end(s);
143     rdpsnd_send(s);
144    
145     data = data + chunk_size;
146     record_buffer_size -= chunk_size;
147    
148     DEBUG_SOUND(("RDPSND: -> RDPSND_REC_DATA(length: %u)\n", (unsigned) chunk_size));
149     }
150    
151     record_buffer_size = 0;
152     }
153    
154     void
155     rdpsnd_record(const void *data, unsigned int size)
156     {
157 ossman_ 1430 uint32 remain, chunk;
158 ossman_ 1359
159     assert(rec_device_open);
160    
161     while (size)
162     {
163     remain = sizeof(record_buffer) - record_buffer_size;
164    
165     if (size >= remain)
166 ossman_ 1430 chunk = remain;
167     else
168     chunk = size;
169    
170     memcpy(record_buffer + record_buffer_size, data, chunk);
171    
172     #ifdef B_ENDIAN
173     if (current_driver->need_byteswap_on_be)
174     rdpsnd_dsp_swapbytes(record_buffer + record_buffer_size,
175     chunk, &rec_formats[rec_current_format]);
176     #endif
177    
178     record_buffer_size += chunk;
179    
180     data = (const char *) data + chunk;
181     size -= chunk;
182    
183     if (record_buffer_size == sizeof(record_buffer))
184 ossman_ 1359 rdpsnd_flush_record();
185     }
186     }
187    
188 jsorg71 1372 static RD_BOOL
189 ossman_ 1346 rdpsnd_auto_select(void)
190     {
191 jsorg71 1372 static RD_BOOL failed = False;
192 ossman_ 1346
193     if (!failed)
194     {
195     current_driver = drivers;
196     while (current_driver != NULL)
197     {
198     DEBUG(("trying %s...\n", current_driver->name));
199     if (current_driver->wave_out_open())
200     {
201     DEBUG(("selected %s\n", current_driver->name));
202 stargo 1350 current_driver->wave_out_close();
203 ossman_ 1346 return True;
204     }
205     current_driver = current_driver->next;
206     }
207    
208     warning("no working audio-driver found\n");
209     failed = True;
210     current_driver = NULL;
211     }
212    
213     return False;
214     }
215    
216 astrand 665 static void
217 matthewc 474 rdpsnd_process_negotiate(STREAM in)
218     {
219 ossman_ 1340 uint16 in_format_count, i;
220     uint8 pad;
221     uint16 version;
222 jsorg71 1364 RD_WAVEFORMATEX *format;
223 matthewc 474 STREAM out;
224 jsorg71 1372 RD_BOOL device_available = False;
225 stargo 493 int readcnt;
226     int discardcnt;
227 matthewc 474
228 ossman_ 1340 in_uint8s(in, 14); /* initial bytes not valid from server */
229 matthewc 474 in_uint16_le(in, in_format_count);
230 ossman_ 1340 in_uint8(in, pad);
231     in_uint16_le(in, version);
232     in_uint8s(in, 1); /* padding */
233 matthewc 474
234 ossman_ 1344 DEBUG_SOUND(("RDPSND: RDPSND_NEGOTIATE(formats: %d, pad: 0x%02x, version: %x)\n",
235     (int) in_format_count, (unsigned) pad, (unsigned) version));
236 ossman_ 1343
237 ossman_ 1346 if (!current_driver)
238 stargo 1353 device_available = rdpsnd_auto_select();
239 ossman_ 1346
240 stargo 1353 if (current_driver && !device_available && current_driver->wave_out_open())
241 stargo 491 {
242 stargo 1353 current_driver->wave_out_close();
243 stargo 491 device_available = True;
244     }
245    
246 matthewc 474 format_count = 0;
247 astrand 499 if (s_check_rem(in, 18 * in_format_count))
248 matthewc 474 {
249     for (i = 0; i < in_format_count; i++)
250     {
251     format = &formats[format_count];
252     in_uint16_le(in, format->wFormatTag);
253     in_uint16_le(in, format->nChannels);
254     in_uint32_le(in, format->nSamplesPerSec);
255     in_uint32_le(in, format->nAvgBytesPerSec);
256     in_uint16_le(in, format->nBlockAlign);
257     in_uint16_le(in, format->wBitsPerSample);
258     in_uint16_le(in, format->cbSize);
259    
260 stargo 492 /* read in the buffer of unknown use */
261 stargo 493 readcnt = format->cbSize;
262     discardcnt = 0;
263 stargo 492 if (format->cbSize > MAX_CBSIZE)
264     {
265 astrand 499 fprintf(stderr, "cbSize too large for buffer: %d\n",
266     format->cbSize);
267 stargo 492 readcnt = MAX_CBSIZE;
268     discardcnt = format->cbSize - MAX_CBSIZE;
269     }
270     in_uint8a(in, format->cb, readcnt);
271     in_uint8s(in, discardcnt);
272    
273 ossman_ 1411 if (current_driver && current_driver->wave_out_format_supported(format))
274 matthewc 474 {
275     format_count++;
276     if (format_count == MAX_FORMATS)
277     break;
278     }
279     }
280     }
281    
282 astrand 499 out = rdpsnd_init_packet(RDPSND_NEGOTIATE | 0x200, 20 + 18 * format_count);
283 ossman_ 1359 out_uint32_le(out, 0x00800003); /* flags */
284 matthewc 474 out_uint32(out, 0xffffffff); /* volume */
285 astrand 499 out_uint32(out, 0); /* pitch */
286     out_uint16(out, 0); /* UDP port */
287 matthewc 474
288     out_uint16_le(out, format_count);
289 ossman_ 1340 out_uint8(out, 0); /* padding */
290     out_uint16_le(out, 2); /* version */
291     out_uint8(out, 0); /* padding */
292 matthewc 474
293     for (i = 0; i < format_count; i++)
294     {
295     format = &formats[i];
296     out_uint16_le(out, format->wFormatTag);
297     out_uint16_le(out, format->nChannels);
298     out_uint32_le(out, format->nSamplesPerSec);
299     out_uint32_le(out, format->nAvgBytesPerSec);
300     out_uint16_le(out, format->nBlockAlign);
301     out_uint16_le(out, format->wBitsPerSample);
302 astrand 499 out_uint16(out, 0); /* cbSize */
303 matthewc 474 }
304    
305     s_mark_end(out);
306 ossman_ 1343
307     DEBUG_SOUND(("RDPSND: -> RDPSND_NEGOTIATE(formats: %d)\n", (int) format_count));
308    
309 matthewc 474 rdpsnd_send(out);
310     }
311    
312 astrand 665 static void
313 ossman_ 1339 rdpsnd_process_ping(STREAM in)
314 matthewc 474 {
315 ossman_ 1339 uint16 tick;
316 matthewc 474 STREAM out;
317    
318 ossman_ 1339 in_uint16_le(in, tick);
319 matthewc 474
320 ossman_ 1343 DEBUG_SOUND(("RDPSND: RDPSND_PING(tick: 0x%04x)\n", (unsigned) tick));
321    
322 ossman_ 1339 out = rdpsnd_init_packet(RDPSND_PING | 0x2300, 4);
323     out_uint16_le(out, tick);
324     out_uint16_le(out, 0);
325 matthewc 474 s_mark_end(out);
326     rdpsnd_send(out);
327 ossman_ 1343
328     DEBUG_SOUND(("RDPSND: -> (tick: 0x%04x)\n", (unsigned) tick));
329 matthewc 474 }
330    
331 astrand 665 static void
332 ossman_ 1359 rdpsnd_process_rec_negotiate(STREAM in)
333     {
334     uint16 in_format_count, i;
335     uint16 version;
336 jsorg71 1364 RD_WAVEFORMATEX *format;
337 ossman_ 1359 STREAM out;
338 jsorg71 1372 RD_BOOL device_available = False;
339 ossman_ 1359 int readcnt;
340     int discardcnt;
341    
342     in_uint8s(in, 8); /* initial bytes not valid from server */
343     in_uint16_le(in, in_format_count);
344     in_uint16_le(in, version);
345    
346     DEBUG_SOUND(("RDPSND: RDPSND_REC_NEGOTIATE(formats: %d, version: %x)\n",
347     (int) in_format_count, (unsigned) version));
348    
349     if (!current_driver)
350     device_available = rdpsnd_auto_select();
351    
352     if (current_driver && !device_available && current_driver->wave_in_open
353     && current_driver->wave_in_open())
354     {
355     current_driver->wave_in_close();
356     device_available = True;
357     }
358    
359     rec_format_count = 0;
360     if (s_check_rem(in, 18 * in_format_count))
361     {
362     for (i = 0; i < in_format_count; i++)
363     {
364     format = &rec_formats[rec_format_count];
365     in_uint16_le(in, format->wFormatTag);
366     in_uint16_le(in, format->nChannels);
367     in_uint32_le(in, format->nSamplesPerSec);
368     in_uint32_le(in, format->nAvgBytesPerSec);
369     in_uint16_le(in, format->nBlockAlign);
370     in_uint16_le(in, format->wBitsPerSample);
371     in_uint16_le(in, format->cbSize);
372    
373     /* read in the buffer of unknown use */
374     readcnt = format->cbSize;
375     discardcnt = 0;
376     if (format->cbSize > MAX_CBSIZE)
377     {
378     fprintf(stderr, "cbSize too large for buffer: %d\n",
379     format->cbSize);
380     readcnt = MAX_CBSIZE;
381     discardcnt = format->cbSize - MAX_CBSIZE;
382     }
383     in_uint8a(in, format->cb, readcnt);
384     in_uint8s(in, discardcnt);
385    
386 ossman_ 1427 if (current_driver && current_driver->wave_in_format_supported
387     && current_driver->wave_in_format_supported(format))
388 ossman_ 1359 {
389     rec_format_count++;
390     if (rec_format_count == MAX_FORMATS)
391     break;
392     }
393     }
394     }
395    
396     out = rdpsnd_init_packet(RDPSND_REC_NEGOTIATE, 12 + 18 * rec_format_count);
397     out_uint32_le(out, 0x00000000); /* flags */
398     out_uint32_le(out, 0xffffffff); /* volume */
399     out_uint16_le(out, rec_format_count);
400     out_uint16_le(out, 1); /* version */
401    
402     for (i = 0; i < rec_format_count; i++)
403     {
404     format = &rec_formats[i];
405     out_uint16_le(out, format->wFormatTag);
406     out_uint16_le(out, format->nChannels);
407     out_uint32_le(out, format->nSamplesPerSec);
408     out_uint32_le(out, format->nAvgBytesPerSec);
409     out_uint16_le(out, format->nBlockAlign);
410     out_uint16_le(out, format->wBitsPerSample);
411     out_uint16(out, 0); /* cbSize */
412     }
413    
414     s_mark_end(out);
415    
416     DEBUG_SOUND(("RDPSND: -> RDPSND_REC_NEGOTIATE(formats: %d)\n", (int) rec_format_count));
417    
418     rdpsnd_send(out);
419     }
420    
421     static void
422 ossman_ 1342 rdpsnd_process_packet(uint8 opcode, STREAM s)
423 matthewc 432 {
424 ossman_ 1341 uint16 vol_left, vol_right;
425 matthewc 474 static uint16 tick, format;
426     static uint8 packet_index;
427    
428 ossman_ 1342 switch (opcode)
429 matthewc 474 {
430 ossman_ 1342 case RDPSND_WRITE:
431     in_uint16_le(s, tick);
432     in_uint16_le(s, format);
433     in_uint8(s, packet_index);
434     in_uint8s(s, 3);
435 ossman_ 1343 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));
436 matthewc 474
437 ossman_ 1342 if (format >= MAX_FORMATS)
438 matthewc 474 {
439 ossman_ 1342 error("RDPSND: Invalid format index\n");
440     break;
441 matthewc 474 }
442 ossman_ 1342
443     if (!device_open || (format != current_format))
444 matthewc 474 {
445 ossman_ 1346 /*
446     * If we haven't selected a device by now, then either
447     * we've failed to find a working device, or the server
448     * is sending bogus RDPSND_WRITE.
449     */
450     if (!current_driver)
451     {
452     rdpsnd_send_completion(tick, packet_index);
453     break;
454     }
455 ossman_ 1342 if (!device_open && !current_driver->wave_out_open())
456     {
457     rdpsnd_send_completion(tick, packet_index);
458     break;
459     }
460     if (!current_driver->wave_out_set_format(&formats[format]))
461     {
462     rdpsnd_send_completion(tick, packet_index);
463     current_driver->wave_out_close();
464     device_open = False;
465     break;
466     }
467     device_open = True;
468     current_format = format;
469 matthewc 474 }
470    
471 ossman_ 1342 rdpsnd_queue_write(rdpsnd_dsp_process
472     (s->p, s->end - s->p, current_driver,
473     &formats[current_format]), tick, packet_index);
474     return;
475 astrand 499 break;
476     case RDPSND_CLOSE:
477 ossman_ 1343 DEBUG_SOUND(("RDPSND: RDPSND_CLOSE()\n"));
478 ossman_ 1346 if (device_open)
479     current_driver->wave_out_close();
480 astrand 499 device_open = False;
481     break;
482     case RDPSND_NEGOTIATE:
483     rdpsnd_process_negotiate(s);
484     break;
485 ossman_ 1339 case RDPSND_PING:
486     rdpsnd_process_ping(s);
487 astrand 499 break;
488     case RDPSND_SET_VOLUME:
489 ossman_ 1341 in_uint16_le(s, vol_left);
490     in_uint16_le(s, vol_right);
491 ossman_ 1343 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));
492 astrand 499 if (device_open)
493 ossman_ 1341 current_driver->wave_out_volume(vol_left, vol_right);
494 astrand 499 break;
495 ossman_ 1359 case RDPSND_REC_NEGOTIATE:
496     rdpsnd_process_rec_negotiate(s);
497     break;
498     case RDPSND_REC_START:
499     in_uint16_le(s, format);
500     DEBUG_SOUND(("RDPSND: RDPSND_REC_START(format: %u)\n", (unsigned) format));
501    
502     if (format >= MAX_FORMATS)
503     {
504     error("RDPSND: Invalid format index\n");
505     break;
506     }
507    
508     if (rec_device_open)
509     {
510     error("RDPSND: Multiple RDPSND_REC_START\n");
511     break;
512     }
513    
514     if (!current_driver->wave_in_open())
515     break;
516    
517     if (!current_driver->wave_in_set_format(&rec_formats[format]))
518     {
519     error("RDPSND: Device not accepting format\n");
520     current_driver->wave_in_close();
521     break;
522     }
523 ossman_ 1430 rec_current_format = format;
524 ossman_ 1359 rec_device_open = True;
525     break;
526     case RDPSND_REC_STOP:
527     DEBUG_SOUND(("RDPSND: RDPSND_REC_STOP()\n"));
528     rdpsnd_flush_record();
529     if (rec_device_open)
530     current_driver->wave_in_close();
531     rec_device_open = False;
532     break;
533     case RDPSND_REC_SET_VOLUME:
534     in_uint16_le(s, vol_left);
535     in_uint16_le(s, vol_right);
536     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));
537     if (rec_device_open)
538     current_driver->wave_in_volume(vol_left, vol_right);
539     break;
540 astrand 499 default:
541 ossman_ 1342 unimpl("RDPSND packet type %x\n", opcode);
542 astrand 499 break;
543 matthewc 474 }
544 matthewc 432 }
545    
546 ossman_ 1342 static void
547     rdpsnd_process(STREAM s)
548     {
549     uint16 len;
550    
551     while (!s_check_end(s))
552     {
553     /* New packet */
554     if (packet.size == 0)
555     {
556     if ((s->end - s->p) < 4)
557     {
558     error("RDPSND: Split at packet header. Things will go south from here...\n");
559     return;
560     }
561     in_uint8(s, packet_opcode);
562     in_uint8s(s, 1); /* Padding */
563     in_uint16_le(s, len);
564    
565 ossman_ 1343 DEBUG_SOUND(("RDPSND: == Opcode %x Length: %d ==\n",
566     (int) packet_opcode, (int) len));
567    
568 ossman_ 1342 packet.p = packet.data;
569     packet.end = packet.data + len;
570     packet.size = len;
571     }
572     else
573     {
574     len = MIN(s->end - s->p, packet.end - packet.p);
575    
576     /* Microsoft's server is so broken it's not even funny... */
577     if (packet_opcode == RDPSND_WRITE)
578     {
579     if ((packet.p - packet.data) < 12)
580     len = MIN(len, 12 - (packet.p - packet.data));
581     else if ((packet.p - packet.data) == 12)
582     {
583 ossman_ 1343 DEBUG_SOUND(("RDPSND: Eating 4 bytes of %d bytes...\n",
584     len));
585 ossman_ 1342 in_uint8s(s, 4);
586     len -= 4;
587     }
588     }
589    
590     in_uint8a(s, packet.p, len);
591     packet.p += len;
592     }
593    
594     /* Packet fully assembled */
595     if (packet.p == packet.end)
596     {
597     packet.p = packet.data;
598     rdpsnd_process_packet(packet_opcode, &packet);
599     packet.size = 0;
600     }
601     }
602     }
603    
604 jsorg71 1372 static RD_BOOL
605 ossman_ 1359 rdpsnddbg_line_handler(const char *line, void *data)
606     {
607     #ifdef WITH_DEBUG_SOUND
608     fprintf(stderr, "SNDDBG: %s\n", line);
609     #endif
610     return True;
611     }
612    
613 stargo 1274 static void
614 ossman_ 1359 rdpsnddbg_process(STREAM s)
615     {
616     unsigned int pkglen;
617     static char *rest = NULL;
618     char *buf;
619    
620     pkglen = s->end - s->p;
621     /* str_handle_lines requires null terminated strings */
622 jsorg71 1382 buf = (char *) xmalloc(pkglen + 1);
623 ossman_ 1359 STRNCPY(buf, (char *) s->p, pkglen + 1);
624    
625     str_handle_lines(buf, &rest, rdpsnddbg_line_handler, NULL);
626    
627     xfree(buf);
628     }
629    
630     static void
631 stargo 1255 rdpsnd_register_drivers(char *options)
632     {
633     struct audio_driver **reg;
634    
635     /* The order of registrations define the probe-order
636     when opening the device for the first time */
637     reg = &drivers;
638     #if defined(RDPSND_ALSA)
639     *reg = alsa_register(options);
640 ossman_ 1298 assert(*reg);
641 stargo 1255 reg = &((*reg)->next);
642     #endif
643 stargo 1264 #if defined(RDPSND_SUN)
644     *reg = sun_register(options);
645 ossman_ 1298 assert(*reg);
646 stargo 1264 reg = &((*reg)->next);
647     #endif
648 stargo 1255 #if defined(RDPSND_OSS)
649     *reg = oss_register(options);
650 ossman_ 1298 assert(*reg);
651 stargo 1255 reg = &((*reg)->next);
652     #endif
653     #if defined(RDPSND_SGI)
654     *reg = sgi_register(options);
655 ossman_ 1298 assert(*reg);
656 stargo 1255 reg = &((*reg)->next);
657     #endif
658     #if defined(RDPSND_LIBAO)
659     *reg = libao_register(options);
660 ossman_ 1302 assert(*reg);
661 stargo 1255 reg = &((*reg)->next);
662     #endif
663 stargo 1332 *reg = NULL;
664 stargo 1255 }
665    
666 jsorg71 1372 RD_BOOL
667 stargo 1272 rdpsnd_init(char *optarg)
668 stargo 1255 {
669     struct audio_driver *pos;
670 stargo 1272 char *driver = NULL, *options = NULL;
671 stargo 1255
672     drivers = NULL;
673 stargo 1272
674 jsorg71 1382 packet.data = (uint8 *) xmalloc(65536);
675 ossman_ 1342 packet.p = packet.end = packet.data;
676     packet.size = 0;
677    
678 stargo 1272 rdpsnd_channel =
679     channel_register("rdpsnd", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP,
680     rdpsnd_process);
681    
682 ossman_ 1359 rdpsnddbg_channel =
683     channel_register("snddbg", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP,
684     rdpsnddbg_process);
685    
686     if ((rdpsnd_channel == NULL) || (rdpsnddbg_channel == NULL))
687 stargo 1272 {
688     error("channel_register\n");
689     return False;
690     }
691    
692 ossman_ 1302 rdpsnd_queue_init();
693    
694 stargo 1272 if (optarg != NULL && strlen(optarg) > 0)
695     {
696     driver = options = optarg;
697    
698     while (*options != '\0' && *options != ':')
699     options++;
700    
701     if (*options == ':')
702     {
703     *options = '\0';
704     options++;
705     }
706    
707     if (*options == '\0')
708     options = NULL;
709     }
710    
711 stargo 1255 rdpsnd_register_drivers(options);
712    
713     if (!driver)
714     return True;
715    
716     pos = drivers;
717     while (pos != NULL)
718     {
719     if (!strcmp(pos->name, driver))
720     {
721     DEBUG(("selected %s\n", pos->name));
722     current_driver = pos;
723     return True;
724     }
725     pos = pos->next;
726     }
727     return False;
728     }
729    
730     void
731     rdpsnd_show_help(void)
732     {
733     struct audio_driver *pos;
734    
735     rdpsnd_register_drivers(NULL);
736    
737     pos = drivers;
738     while (pos != NULL)
739     {
740     fprintf(stderr, " %s:\t%s\n", pos->name, pos->description);
741     pos = pos->next;
742     }
743     }
744    
745 stargo 1273 void
746 ossman_ 1302 rdpsnd_add_fds(int *n, fd_set * rfds, fd_set * wfds, struct timeval *tv)
747     {
748     long next_pending;
749    
750 ossman_ 1359 if (device_open || rec_device_open)
751 ossman_ 1346 current_driver->add_fds(n, rfds, wfds, tv);
752 ossman_ 1302
753     next_pending = rdpsnd_queue_next_completion();
754     if (next_pending >= 0)
755     {
756     long cur_timeout;
757    
758     cur_timeout = tv->tv_sec * 1000000 + tv->tv_usec;
759     if (cur_timeout > next_pending)
760     {
761     tv->tv_sec = next_pending / 1000000;
762     tv->tv_usec = next_pending % 1000000;
763     }
764     }
765     }
766    
767     void
768     rdpsnd_check_fds(fd_set * rfds, fd_set * wfds)
769     {
770     rdpsnd_queue_complete_pending();
771    
772 ossman_ 1359 if (device_open || rec_device_open)
773 ossman_ 1346 current_driver->check_fds(rfds, wfds);
774 ossman_ 1302 }
775    
776     static void
777 stargo 1254 rdpsnd_queue_write(STREAM s, uint16 tick, uint8 index)
778     {
779     struct audio_packet *packet = &packet_queue[queue_hi];
780     unsigned int next_hi = (queue_hi + 1) % MAX_QUEUE;
781    
782 ossman_ 1302 if (next_hi == queue_pending)
783 stargo 1254 {
784     error("No space to queue audio packet\n");
785     return;
786     }
787    
788     queue_hi = next_hi;
789    
790     packet->s = *s;
791     packet->tick = tick;
792     packet->index = index;
793    
794 ossman_ 1302 gettimeofday(&packet->arrive_tv, NULL);
795 stargo 1254 }
796    
797 ossman_ 1299 struct audio_packet *
798 stargo 1254 rdpsnd_queue_current_packet(void)
799     {
800     return &packet_queue[queue_lo];
801     }
802    
803 jsorg71 1372 RD_BOOL
804 stargo 1254 rdpsnd_queue_empty(void)
805     {
806     return (queue_lo == queue_hi);
807     }
808    
809 ossman_ 1302 static void
810 stargo 1254 rdpsnd_queue_init(void)
811     {
812 ossman_ 1302 queue_pending = queue_lo = queue_hi = 0;
813 stargo 1254 }
814    
815 ossman_ 1299 void
816 ossman_ 1302 rdpsnd_queue_next(unsigned long completed_in_us)
817 stargo 1254 {
818 ossman_ 1302 struct audio_packet *packet;
819    
820     assert(!rdpsnd_queue_empty());
821    
822     packet = &packet_queue[queue_lo];
823    
824     gettimeofday(&packet->completion_tv, NULL);
825    
826     packet->completion_tv.tv_usec += completed_in_us;
827     packet->completion_tv.tv_sec += packet->completion_tv.tv_usec / 1000000;
828     packet->completion_tv.tv_usec %= 1000000;
829    
830 stargo 1254 queue_lo = (queue_lo + 1) % MAX_QUEUE;
831 ossman_ 1302
832     rdpsnd_queue_complete_pending();
833 stargo 1254 }
834    
835 ossman_ 1299 int
836 stargo 1254 rdpsnd_queue_next_tick(void)
837     {
838     if (((queue_lo + 1) % MAX_QUEUE) != queue_hi)
839     {
840     return packet_queue[(queue_lo + 1) % MAX_QUEUE].tick;
841     }
842     else
843     {
844     return (packet_queue[queue_lo].tick + 65535) % 65536;
845     }
846     }
847 ossman_ 1302
848     static void
849     rdpsnd_queue_complete_pending(void)
850     {
851     struct timeval now;
852     long elapsed;
853     struct audio_packet *packet;
854    
855     gettimeofday(&now, NULL);
856    
857     while (queue_pending != queue_lo)
858     {
859     packet = &packet_queue[queue_pending];
860    
861     if (now.tv_sec < packet->completion_tv.tv_sec)
862     break;
863    
864     if ((now.tv_sec == packet->completion_tv.tv_sec) &&
865     (now.tv_usec < packet->completion_tv.tv_usec))
866     break;
867    
868     elapsed = (packet->completion_tv.tv_sec - packet->arrive_tv.tv_sec) * 1000000 +
869     (packet->completion_tv.tv_usec - packet->arrive_tv.tv_usec);
870 ossman_ 1337 elapsed /= 1000;
871 ossman_ 1302
872     xfree(packet->s.data);
873     rdpsnd_send_completion((packet->tick + elapsed) % 65536, packet->index);
874     queue_pending = (queue_pending + 1) % MAX_QUEUE;
875     }
876     }
877    
878     static long
879     rdpsnd_queue_next_completion(void)
880     {
881     struct audio_packet *packet;
882     long remaining;
883     struct timeval now;
884    
885     if (queue_pending == queue_lo)
886     return -1;
887    
888     gettimeofday(&now, NULL);
889    
890     packet = &packet_queue[queue_pending];
891    
892     remaining = (packet->completion_tv.tv_sec - now.tv_sec) * 1000000 +
893     (packet->completion_tv.tv_usec - now.tv_usec);
894    
895     if (remaining < 0)
896     return 0;
897    
898     return remaining;
899     }

  ViewVC Help
Powered by ViewVC 1.1.26