/[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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1339 - (hide annotations)
Wed Dec 6 13:01:45 2006 UTC (17 years, 5 months ago) by ossman_
Original Path: sourceforge.net/trunk/rdesktop/rdpsnd.c
File MIME type: text/plain
File size: 12512 byte(s)
Change servertick to ping according to new information.

1 astrand 963 /* -*- c-basic-offset: 8 -*-
2 matthewc 474 rdesktop: A Remote Desktop Protocol client.
3     Sound Channel Process Functions
4     Copyright (C) Matthew Chapman 2003
5     Copyright (C) GuoJunBo guojunbo@ict.ac.cn 2003
6    
7     This program is free software; you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation; either version 2 of the License, or
10     (at your option) any later version.
11    
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     GNU General Public License for more details.
16    
17     You should have received a copy of the GNU General Public License
18     along with this program; if not, write to the Free Software
19     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20     */
21    
22 ossman_ 1298 #include <assert.h>
23    
24 matthewc 432 #include "rdesktop.h"
25 stargo 1254 #include "rdpsnd.h"
26 stargo 1258 #include "rdpsnd_dsp.h"
27 matthewc 432
28 matthewc 474 #define RDPSND_CLOSE 1
29     #define RDPSND_WRITE 2
30     #define RDPSND_SET_VOLUME 3
31     #define RDPSND_UNKNOWN4 4
32     #define RDPSND_COMPLETION 5
33 ossman_ 1339 #define RDPSND_PING 6
34 matthewc 474 #define RDPSND_NEGOTIATE 7
35    
36     #define MAX_FORMATS 10
37 stargo 1254 #define MAX_QUEUE 10
38 matthewc 474
39 stargo 1254 BOOL g_dsp_busy = False;
40     int g_dsp_fd;
41    
42 matthewc 432 static VCHANNEL *rdpsnd_channel;
43 stargo 1255 static struct audio_driver *drivers = NULL;
44 stargo 1256 struct audio_driver *current_driver = NULL;
45 matthewc 432
46 matthewc 474 static BOOL device_open;
47     static WAVEFORMATEX formats[MAX_FORMATS];
48     static unsigned int format_count;
49     static unsigned int current_format;
50 ossman_ 1302 unsigned int queue_hi, queue_lo, queue_pending;
51 stargo 1256 struct audio_packet packet_queue[MAX_QUEUE];
52 matthewc 474
53 stargo 1255 void (*wave_out_play) (void);
54    
55 ossman_ 1302 static void rdpsnd_queue_write(STREAM s, uint16 tick, uint8 index);
56     static void rdpsnd_queue_init(void);
57     static void rdpsnd_queue_complete_pending(void);
58     static long rdpsnd_queue_next_completion(void);
59    
60 astrand 665 static STREAM
61 matthewc 474 rdpsnd_init_packet(uint16 type, uint16 size)
62     {
63     STREAM s;
64    
65 astrand 499 s = channel_init(rdpsnd_channel, size + 4);
66 matthewc 474 out_uint16_le(s, type);
67     out_uint16_le(s, size);
68     return s;
69     }
70    
71 astrand 665 static void
72 matthewc 474 rdpsnd_send(STREAM s)
73     {
74     #ifdef RDPSND_DEBUG
75     printf("RDPSND send:\n");
76 astrand 499 hexdump(s->channel_hdr + 8, s->end - s->channel_hdr - 8);
77 matthewc 474 #endif
78    
79     channel_send(s, rdpsnd_channel);
80     }
81    
82 ossman_ 1302 static void
83 astrand 499 rdpsnd_send_completion(uint16 tick, uint8 packet_index)
84 matthewc 474 {
85     STREAM s;
86    
87     s = rdpsnd_init_packet(RDPSND_COMPLETION, 4);
88 stargo 1254 out_uint16_le(s, tick);
89 matthewc 474 out_uint8(s, packet_index);
90     out_uint8(s, 0);
91     s_mark_end(s);
92     rdpsnd_send(s);
93     }
94    
95 astrand 665 static void
96 matthewc 474 rdpsnd_process_negotiate(STREAM in)
97     {
98     unsigned int in_format_count, i;
99     WAVEFORMATEX *format;
100     STREAM out;
101 stargo 491 BOOL device_available = False;
102 stargo 493 int readcnt;
103     int discardcnt;
104 matthewc 474
105     in_uint8s(in, 14); /* flags, volume, pitch, UDP port */
106     in_uint16_le(in, in_format_count);
107     in_uint8s(in, 4); /* pad, status, pad */
108    
109 stargo 1255 if (current_driver->wave_out_open())
110 stargo 491 {
111 stargo 1255 current_driver->wave_out_close();
112 stargo 491 device_available = True;
113     }
114    
115 matthewc 474 format_count = 0;
116 astrand 499 if (s_check_rem(in, 18 * in_format_count))
117 matthewc 474 {
118     for (i = 0; i < in_format_count; i++)
119     {
120     format = &formats[format_count];
121     in_uint16_le(in, format->wFormatTag);
122     in_uint16_le(in, format->nChannels);
123     in_uint32_le(in, format->nSamplesPerSec);
124     in_uint32_le(in, format->nAvgBytesPerSec);
125     in_uint16_le(in, format->nBlockAlign);
126     in_uint16_le(in, format->wBitsPerSample);
127     in_uint16_le(in, format->cbSize);
128    
129 stargo 492 /* read in the buffer of unknown use */
130 stargo 493 readcnt = format->cbSize;
131     discardcnt = 0;
132 stargo 492 if (format->cbSize > MAX_CBSIZE)
133     {
134 astrand 499 fprintf(stderr, "cbSize too large for buffer: %d\n",
135     format->cbSize);
136 stargo 492 readcnt = MAX_CBSIZE;
137     discardcnt = format->cbSize - MAX_CBSIZE;
138     }
139     in_uint8a(in, format->cb, readcnt);
140     in_uint8s(in, discardcnt);
141    
142 stargo 1255 if (device_available && current_driver->wave_out_format_supported(format))
143 matthewc 474 {
144     format_count++;
145     if (format_count == MAX_FORMATS)
146     break;
147     }
148     }
149     }
150    
151 astrand 499 out = rdpsnd_init_packet(RDPSND_NEGOTIATE | 0x200, 20 + 18 * format_count);
152     out_uint32_le(out, 3); /* flags */
153 matthewc 474 out_uint32(out, 0xffffffff); /* volume */
154 astrand 499 out_uint32(out, 0); /* pitch */
155     out_uint16(out, 0); /* UDP port */
156 matthewc 474
157     out_uint16_le(out, format_count);
158 astrand 499 out_uint8(out, 0x95); /* pad? */
159     out_uint16_le(out, 2); /* status */
160     out_uint8(out, 0x77); /* pad? */
161 matthewc 474
162     for (i = 0; i < format_count; i++)
163     {
164     format = &formats[i];
165     out_uint16_le(out, format->wFormatTag);
166     out_uint16_le(out, format->nChannels);
167     out_uint32_le(out, format->nSamplesPerSec);
168     out_uint32_le(out, format->nAvgBytesPerSec);
169     out_uint16_le(out, format->nBlockAlign);
170     out_uint16_le(out, format->wBitsPerSample);
171 astrand 499 out_uint16(out, 0); /* cbSize */
172 matthewc 474 }
173    
174     s_mark_end(out);
175     rdpsnd_send(out);
176     }
177    
178 astrand 665 static void
179 ossman_ 1339 rdpsnd_process_ping(STREAM in)
180 matthewc 474 {
181 ossman_ 1339 uint16 tick;
182 matthewc 474 STREAM out;
183    
184 ossman_ 1339 in_uint16_le(in, tick);
185 matthewc 474
186 ossman_ 1339 out = rdpsnd_init_packet(RDPSND_PING | 0x2300, 4);
187     out_uint16_le(out, tick);
188     out_uint16_le(out, 0);
189 matthewc 474 s_mark_end(out);
190     rdpsnd_send(out);
191     }
192    
193 astrand 665 static void
194 matthewc 432 rdpsnd_process(STREAM s)
195     {
196 matthewc 474 uint8 type;
197     uint16 datalen;
198 stargo 491 uint32 volume;
199 matthewc 474 static uint16 tick, format;
200     static uint8 packet_index;
201     static BOOL awaiting_data_packet;
202 stargo 1265 static unsigned char missing_bytes[4] = { 0, 0, 0, 0 };
203 matthewc 474
204     #ifdef RDPSND_DEBUG
205     printf("RDPSND recv:\n");
206 astrand 499 hexdump(s->p, s->end - s->p);
207 matthewc 474 #endif
208    
209     if (awaiting_data_packet)
210     {
211     if (format >= MAX_FORMATS)
212     {
213     error("RDPSND: Invalid format index\n");
214     return;
215     }
216    
217     if (!device_open || (format != current_format))
218     {
219 stargo 1255 if (!device_open && !current_driver->wave_out_open())
220 matthewc 474 {
221     rdpsnd_send_completion(tick, packet_index);
222     return;
223     }
224 stargo 1255 if (!current_driver->wave_out_set_format(&formats[format]))
225 matthewc 474 {
226     rdpsnd_send_completion(tick, packet_index);
227 stargo 1255 current_driver->wave_out_close();
228 matthewc 474 device_open = False;
229     return;
230     }
231     device_open = True;
232     current_format = format;
233     }
234    
235 stargo 1265 /* Insert the 4 missing bytes retrieved from last RDPSND_WRITE */
236     memcpy(s->data, missing_bytes, 4);
237    
238 ossman_ 1302 rdpsnd_queue_write(rdpsnd_dsp_process
239     (s, current_driver, &formats[current_format]), tick,
240     packet_index);
241 matthewc 474 awaiting_data_packet = False;
242     return;
243     }
244    
245     in_uint8(s, type);
246 astrand 499 in_uint8s(s, 1); /* unknown? */
247 matthewc 474 in_uint16_le(s, datalen);
248    
249     switch (type)
250     {
251 astrand 499 case RDPSND_WRITE:
252     in_uint16_le(s, tick);
253     in_uint16_le(s, format);
254     in_uint8(s, packet_index);
255 stargo 1265 /* Here are our lost bytes, but why? */
256     memcpy(missing_bytes, s->end - 4, 4);
257 astrand 499 awaiting_data_packet = True;
258     break;
259     case RDPSND_CLOSE:
260 stargo 1255 current_driver->wave_out_close();
261 astrand 499 device_open = False;
262     break;
263     case RDPSND_NEGOTIATE:
264     rdpsnd_process_negotiate(s);
265     break;
266 ossman_ 1339 case RDPSND_PING:
267     rdpsnd_process_ping(s);
268 astrand 499 break;
269     case RDPSND_SET_VOLUME:
270     in_uint32(s, volume);
271     if (device_open)
272     {
273 stargo 1255 current_driver->wave_out_volume((volume & 0xffff),
274     (volume & 0xffff0000) >> 16);
275 astrand 499 }
276     break;
277     default:
278     unimpl("RDPSND packet type %d\n", type);
279     break;
280 matthewc 474 }
281 matthewc 432 }
282    
283 stargo 1274 static BOOL
284 stargo 1255 rdpsnd_auto_open(void)
285     {
286 stargo 1271 static BOOL failed = False;
287    
288     if (!failed)
289 stargo 1255 {
290 stargo 1271 struct audio_driver *auto_driver = current_driver;
291    
292     current_driver = drivers;
293     while (current_driver != NULL)
294 stargo 1255 {
295 stargo 1271 DEBUG(("trying %s...\n", current_driver->name));
296     if (current_driver->wave_out_open())
297     {
298     DEBUG(("selected %s\n", current_driver->name));
299     return True;
300     }
301     g_dsp_fd = 0;
302     current_driver = current_driver->next;
303 stargo 1255 }
304 stargo 1271
305     warning("no working audio-driver found\n");
306     failed = True;
307     current_driver = auto_driver;
308 stargo 1255 }
309    
310     return False;
311     }
312    
313 stargo 1274 static void
314 stargo 1255 rdpsnd_register_drivers(char *options)
315     {
316     struct audio_driver **reg;
317    
318     /* The order of registrations define the probe-order
319     when opening the device for the first time */
320     reg = &drivers;
321     #if defined(RDPSND_ALSA)
322     *reg = alsa_register(options);
323 ossman_ 1298 assert(*reg);
324 stargo 1255 reg = &((*reg)->next);
325     #endif
326 stargo 1264 #if defined(RDPSND_SUN)
327     *reg = sun_register(options);
328 ossman_ 1298 assert(*reg);
329 stargo 1264 reg = &((*reg)->next);
330     #endif
331 stargo 1255 #if defined(RDPSND_OSS)
332     *reg = oss_register(options);
333 ossman_ 1298 assert(*reg);
334 stargo 1255 reg = &((*reg)->next);
335     #endif
336     #if defined(RDPSND_SGI)
337     *reg = sgi_register(options);
338 ossman_ 1298 assert(*reg);
339 stargo 1255 reg = &((*reg)->next);
340     #endif
341     #if defined(RDPSND_LIBAO)
342     *reg = libao_register(options);
343 ossman_ 1302 assert(*reg);
344 stargo 1255 reg = &((*reg)->next);
345     #endif
346 stargo 1332 *reg = NULL;
347 stargo 1255 }
348    
349     BOOL
350 stargo 1272 rdpsnd_init(char *optarg)
351 stargo 1255 {
352     static struct audio_driver auto_driver;
353     struct audio_driver *pos;
354 stargo 1272 char *driver = NULL, *options = NULL;
355 stargo 1255
356     drivers = NULL;
357 stargo 1272
358     rdpsnd_channel =
359     channel_register("rdpsnd", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP,
360     rdpsnd_process);
361    
362     if (rdpsnd_channel == NULL)
363     {
364     error("channel_register\n");
365     return False;
366     }
367    
368 ossman_ 1302 rdpsnd_queue_init();
369    
370 stargo 1272 if (optarg != NULL && strlen(optarg) > 0)
371     {
372     driver = options = optarg;
373    
374     while (*options != '\0' && *options != ':')
375     options++;
376    
377     if (*options == ':')
378     {
379     *options = '\0';
380     options++;
381     }
382    
383     if (*options == '\0')
384     options = NULL;
385     }
386    
387 stargo 1255 rdpsnd_register_drivers(options);
388    
389     if (!driver)
390     {
391     auto_driver.wave_out_open = &rdpsnd_auto_open;
392     current_driver = &auto_driver;
393     return True;
394     }
395    
396     pos = drivers;
397     while (pos != NULL)
398     {
399     if (!strcmp(pos->name, driver))
400     {
401     DEBUG(("selected %s\n", pos->name));
402     current_driver = pos;
403     return True;
404     }
405     pos = pos->next;
406     }
407     return False;
408     }
409    
410     void
411     rdpsnd_show_help(void)
412     {
413     struct audio_driver *pos;
414    
415     rdpsnd_register_drivers(NULL);
416    
417     pos = drivers;
418     while (pos != NULL)
419     {
420     fprintf(stderr, " %s:\t%s\n", pos->name, pos->description);
421     pos = pos->next;
422     }
423     }
424    
425 stargo 1273 void
426 stargo 1255 rdpsnd_play(void)
427     {
428     current_driver->wave_out_play();
429     }
430    
431 ossman_ 1299 void
432 ossman_ 1302 rdpsnd_add_fds(int *n, fd_set * rfds, fd_set * wfds, struct timeval *tv)
433     {
434     long next_pending;
435    
436     if (g_dsp_busy)
437     {
438     FD_SET(g_dsp_fd, wfds);
439     *n = (g_dsp_fd > *n) ? g_dsp_fd : *n;
440     }
441    
442     next_pending = rdpsnd_queue_next_completion();
443     if (next_pending >= 0)
444     {
445     long cur_timeout;
446    
447     cur_timeout = tv->tv_sec * 1000000 + tv->tv_usec;
448     if (cur_timeout > next_pending)
449     {
450     tv->tv_sec = next_pending / 1000000;
451     tv->tv_usec = next_pending % 1000000;
452     }
453     }
454     }
455    
456     void
457     rdpsnd_check_fds(fd_set * rfds, fd_set * wfds)
458     {
459     rdpsnd_queue_complete_pending();
460    
461     if (g_dsp_busy && FD_ISSET(g_dsp_fd, wfds))
462     rdpsnd_play();
463     }
464    
465     static void
466 stargo 1254 rdpsnd_queue_write(STREAM s, uint16 tick, uint8 index)
467     {
468     struct audio_packet *packet = &packet_queue[queue_hi];
469     unsigned int next_hi = (queue_hi + 1) % MAX_QUEUE;
470    
471 ossman_ 1302 if (next_hi == queue_pending)
472 stargo 1254 {
473     error("No space to queue audio packet\n");
474     return;
475     }
476    
477     queue_hi = next_hi;
478    
479     packet->s = *s;
480     packet->tick = tick;
481     packet->index = index;
482    
483 ossman_ 1302 gettimeofday(&packet->arrive_tv, NULL);
484    
485 stargo 1254 if (!g_dsp_busy)
486 stargo 1255 current_driver->wave_out_play();
487 stargo 1254 }
488    
489 ossman_ 1299 struct audio_packet *
490 stargo 1254 rdpsnd_queue_current_packet(void)
491     {
492     return &packet_queue[queue_lo];
493     }
494    
495 ossman_ 1299 BOOL
496 stargo 1254 rdpsnd_queue_empty(void)
497     {
498     return (queue_lo == queue_hi);
499     }
500    
501 ossman_ 1302 static void
502 stargo 1254 rdpsnd_queue_init(void)
503     {
504 ossman_ 1302 queue_pending = queue_lo = queue_hi = 0;
505 stargo 1254 }
506    
507 ossman_ 1299 void
508 ossman_ 1302 rdpsnd_queue_next(unsigned long completed_in_us)
509 stargo 1254 {
510 ossman_ 1302 struct audio_packet *packet;
511    
512     assert(!rdpsnd_queue_empty());
513    
514     packet = &packet_queue[queue_lo];
515    
516     gettimeofday(&packet->completion_tv, NULL);
517    
518     packet->completion_tv.tv_usec += completed_in_us;
519     packet->completion_tv.tv_sec += packet->completion_tv.tv_usec / 1000000;
520     packet->completion_tv.tv_usec %= 1000000;
521    
522 stargo 1254 queue_lo = (queue_lo + 1) % MAX_QUEUE;
523 ossman_ 1302
524     rdpsnd_queue_complete_pending();
525 stargo 1254 }
526    
527 ossman_ 1299 int
528 stargo 1254 rdpsnd_queue_next_tick(void)
529     {
530     if (((queue_lo + 1) % MAX_QUEUE) != queue_hi)
531     {
532     return packet_queue[(queue_lo + 1) % MAX_QUEUE].tick;
533     }
534     else
535     {
536     return (packet_queue[queue_lo].tick + 65535) % 65536;
537     }
538     }
539 ossman_ 1302
540     static void
541     rdpsnd_queue_complete_pending(void)
542     {
543     struct timeval now;
544     long elapsed;
545     struct audio_packet *packet;
546    
547     gettimeofday(&now, NULL);
548    
549     while (queue_pending != queue_lo)
550     {
551     packet = &packet_queue[queue_pending];
552    
553     if (now.tv_sec < packet->completion_tv.tv_sec)
554     break;
555    
556     if ((now.tv_sec == packet->completion_tv.tv_sec) &&
557     (now.tv_usec < packet->completion_tv.tv_usec))
558     break;
559    
560     elapsed = (packet->completion_tv.tv_sec - packet->arrive_tv.tv_sec) * 1000000 +
561     (packet->completion_tv.tv_usec - packet->arrive_tv.tv_usec);
562 ossman_ 1337 elapsed /= 1000;
563 ossman_ 1302
564     xfree(packet->s.data);
565     rdpsnd_send_completion((packet->tick + elapsed) % 65536, packet->index);
566     queue_pending = (queue_pending + 1) % MAX_QUEUE;
567     }
568     }
569    
570     static long
571     rdpsnd_queue_next_completion(void)
572     {
573     struct audio_packet *packet;
574     long remaining;
575     struct timeval now;
576    
577     if (queue_pending == queue_lo)
578     return -1;
579    
580     gettimeofday(&now, NULL);
581    
582     packet = &packet_queue[queue_pending];
583    
584     remaining = (packet->completion_tv.tv_sec - now.tv_sec) * 1000000 +
585     (packet->completion_tv.tv_usec - now.tv_usec);
586    
587     if (remaining < 0)
588     return 0;
589    
590     return remaining;
591     }

  ViewVC Help
Powered by ViewVC 1.1.26