/[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 1272 - (hide annotations)
Thu Sep 21 19:00:11 2006 UTC (17 years, 8 months ago) by stargo
Original Path: sourceforge.net/trunk/rdesktop/rdpsnd.c
File MIME type: text/plain
File size: 10139 byte(s)
move sound-driver selection code in rdpsnd_init

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 matthewc 432 #include "rdesktop.h"
23 stargo 1254 #include "rdpsnd.h"
24 stargo 1258 #include "rdpsnd_dsp.h"
25 matthewc 432
26 matthewc 474 #define RDPSND_CLOSE 1
27     #define RDPSND_WRITE 2
28     #define RDPSND_SET_VOLUME 3
29     #define RDPSND_UNKNOWN4 4
30     #define RDPSND_COMPLETION 5
31 stargo 1044 #define RDPSND_SERVERTICK 6
32 matthewc 474 #define RDPSND_NEGOTIATE 7
33    
34     #define MAX_FORMATS 10
35 stargo 1254 #define MAX_QUEUE 10
36 matthewc 474
37 stargo 1254 BOOL g_dsp_busy = False;
38     int g_dsp_fd;
39    
40 matthewc 432 static VCHANNEL *rdpsnd_channel;
41 stargo 1255 static struct audio_driver *drivers = NULL;
42 stargo 1256 struct audio_driver *current_driver = NULL;
43 matthewc 432
44 matthewc 474 static BOOL device_open;
45     static WAVEFORMATEX formats[MAX_FORMATS];
46     static unsigned int format_count;
47     static unsigned int current_format;
48 stargo 1256 unsigned int queue_hi, queue_lo;
49     struct audio_packet packet_queue[MAX_QUEUE];
50 matthewc 474
51 stargo 1255 void (*wave_out_play) (void);
52    
53 astrand 665 static STREAM
54 matthewc 474 rdpsnd_init_packet(uint16 type, uint16 size)
55     {
56     STREAM s;
57    
58 astrand 499 s = channel_init(rdpsnd_channel, size + 4);
59 matthewc 474 out_uint16_le(s, type);
60     out_uint16_le(s, size);
61     return s;
62     }
63    
64 astrand 665 static void
65 matthewc 474 rdpsnd_send(STREAM s)
66     {
67     #ifdef RDPSND_DEBUG
68     printf("RDPSND send:\n");
69 astrand 499 hexdump(s->channel_hdr + 8, s->end - s->channel_hdr - 8);
70 matthewc 474 #endif
71    
72     channel_send(s, rdpsnd_channel);
73     }
74    
75 astrand 499 void
76     rdpsnd_send_completion(uint16 tick, uint8 packet_index)
77 matthewc 474 {
78     STREAM s;
79    
80     s = rdpsnd_init_packet(RDPSND_COMPLETION, 4);
81 stargo 1254 out_uint16_le(s, tick);
82 matthewc 474 out_uint8(s, packet_index);
83     out_uint8(s, 0);
84     s_mark_end(s);
85     rdpsnd_send(s);
86     }
87    
88 astrand 665 static void
89 matthewc 474 rdpsnd_process_negotiate(STREAM in)
90     {
91     unsigned int in_format_count, i;
92     WAVEFORMATEX *format;
93     STREAM out;
94 stargo 491 BOOL device_available = False;
95 stargo 493 int readcnt;
96     int discardcnt;
97 matthewc 474
98     in_uint8s(in, 14); /* flags, volume, pitch, UDP port */
99     in_uint16_le(in, in_format_count);
100     in_uint8s(in, 4); /* pad, status, pad */
101    
102 stargo 1255 if (current_driver->wave_out_open())
103 stargo 491 {
104 stargo 1255 current_driver->wave_out_close();
105 stargo 491 device_available = True;
106     }
107    
108 matthewc 474 format_count = 0;
109 astrand 499 if (s_check_rem(in, 18 * in_format_count))
110 matthewc 474 {
111     for (i = 0; i < in_format_count; i++)
112     {
113     format = &formats[format_count];
114     in_uint16_le(in, format->wFormatTag);
115     in_uint16_le(in, format->nChannels);
116     in_uint32_le(in, format->nSamplesPerSec);
117     in_uint32_le(in, format->nAvgBytesPerSec);
118     in_uint16_le(in, format->nBlockAlign);
119     in_uint16_le(in, format->wBitsPerSample);
120     in_uint16_le(in, format->cbSize);
121    
122 stargo 492 /* read in the buffer of unknown use */
123 stargo 493 readcnt = format->cbSize;
124     discardcnt = 0;
125 stargo 492 if (format->cbSize > MAX_CBSIZE)
126     {
127 astrand 499 fprintf(stderr, "cbSize too large for buffer: %d\n",
128     format->cbSize);
129 stargo 492 readcnt = MAX_CBSIZE;
130     discardcnt = format->cbSize - MAX_CBSIZE;
131     }
132     in_uint8a(in, format->cb, readcnt);
133     in_uint8s(in, discardcnt);
134    
135 stargo 1255 if (device_available && current_driver->wave_out_format_supported(format))
136 matthewc 474 {
137     format_count++;
138     if (format_count == MAX_FORMATS)
139     break;
140     }
141     }
142     }
143    
144 astrand 499 out = rdpsnd_init_packet(RDPSND_NEGOTIATE | 0x200, 20 + 18 * format_count);
145     out_uint32_le(out, 3); /* flags */
146 matthewc 474 out_uint32(out, 0xffffffff); /* volume */
147 astrand 499 out_uint32(out, 0); /* pitch */
148     out_uint16(out, 0); /* UDP port */
149 matthewc 474
150     out_uint16_le(out, format_count);
151 astrand 499 out_uint8(out, 0x95); /* pad? */
152     out_uint16_le(out, 2); /* status */
153     out_uint8(out, 0x77); /* pad? */
154 matthewc 474
155     for (i = 0; i < format_count; i++)
156     {
157     format = &formats[i];
158     out_uint16_le(out, format->wFormatTag);
159     out_uint16_le(out, format->nChannels);
160     out_uint32_le(out, format->nSamplesPerSec);
161     out_uint32_le(out, format->nAvgBytesPerSec);
162     out_uint16_le(out, format->nBlockAlign);
163     out_uint16_le(out, format->wBitsPerSample);
164 astrand 499 out_uint16(out, 0); /* cbSize */
165 matthewc 474 }
166    
167     s_mark_end(out);
168     rdpsnd_send(out);
169     }
170    
171 astrand 665 static void
172 stargo 1044 rdpsnd_process_servertick(STREAM in)
173 matthewc 474 {
174 stargo 1044 uint16 tick1, tick2;
175 matthewc 474 STREAM out;
176    
177     /* in_uint8s(in, 4); unknown */
178 stargo 1044 in_uint16_le(in, tick1);
179     in_uint16_le(in, tick2);
180 matthewc 474
181 stargo 1044 out = rdpsnd_init_packet(RDPSND_SERVERTICK | 0x2300, 4);
182     out_uint16_le(out, tick1);
183     out_uint16_le(out, tick2);
184 matthewc 474 s_mark_end(out);
185     rdpsnd_send(out);
186     }
187    
188 astrand 665 static void
189 matthewc 432 rdpsnd_process(STREAM s)
190     {
191 matthewc 474 uint8 type;
192     uint16 datalen;
193 stargo 491 uint32 volume;
194 matthewc 474 static uint16 tick, format;
195     static uint8 packet_index;
196     static BOOL awaiting_data_packet;
197 stargo 1265 static unsigned char missing_bytes[4] = { 0, 0, 0, 0 };
198 matthewc 474
199     #ifdef RDPSND_DEBUG
200     printf("RDPSND recv:\n");
201 astrand 499 hexdump(s->p, s->end - s->p);
202 matthewc 474 #endif
203    
204     if (awaiting_data_packet)
205     {
206     if (format >= MAX_FORMATS)
207     {
208     error("RDPSND: Invalid format index\n");
209     return;
210     }
211    
212     if (!device_open || (format != current_format))
213     {
214 stargo 1255 if (!device_open && !current_driver->wave_out_open())
215 matthewc 474 {
216     rdpsnd_send_completion(tick, packet_index);
217     return;
218     }
219 stargo 1255 if (!current_driver->wave_out_set_format(&formats[format]))
220 matthewc 474 {
221     rdpsnd_send_completion(tick, packet_index);
222 stargo 1255 current_driver->wave_out_close();
223 matthewc 474 device_open = False;
224     return;
225     }
226     device_open = True;
227     current_format = format;
228     }
229    
230 stargo 1265 /* Insert the 4 missing bytes retrieved from last RDPSND_WRITE */
231     memcpy(s->data, missing_bytes, 4);
232    
233 stargo 1263 current_driver->
234     wave_out_write(rdpsnd_dsp_process
235     (s, current_driver, &formats[current_format]), tick,
236     packet_index);
237 matthewc 474 awaiting_data_packet = False;
238     return;
239     }
240    
241     in_uint8(s, type);
242 astrand 499 in_uint8s(s, 1); /* unknown? */
243 matthewc 474 in_uint16_le(s, datalen);
244    
245     switch (type)
246     {
247 astrand 499 case RDPSND_WRITE:
248     in_uint16_le(s, tick);
249     in_uint16_le(s, format);
250     in_uint8(s, packet_index);
251 stargo 1265 /* Here are our lost bytes, but why? */
252     memcpy(missing_bytes, s->end - 4, 4);
253 astrand 499 awaiting_data_packet = True;
254     break;
255     case RDPSND_CLOSE:
256 stargo 1255 current_driver->wave_out_close();
257 astrand 499 device_open = False;
258     break;
259     case RDPSND_NEGOTIATE:
260     rdpsnd_process_negotiate(s);
261     break;
262 stargo 1044 case RDPSND_SERVERTICK:
263     rdpsnd_process_servertick(s);
264 astrand 499 break;
265     case RDPSND_SET_VOLUME:
266     in_uint32(s, volume);
267     if (device_open)
268     {
269 stargo 1255 current_driver->wave_out_volume((volume & 0xffff),
270     (volume & 0xffff0000) >> 16);
271 astrand 499 }
272     break;
273     default:
274     unimpl("RDPSND packet type %d\n", type);
275     break;
276 matthewc 474 }
277 matthewc 432 }
278    
279     BOOL
280 stargo 1255 rdpsnd_auto_open(void)
281     {
282 stargo 1271 static BOOL failed = False;
283    
284     if (!failed)
285 stargo 1255 {
286 stargo 1271 struct audio_driver *auto_driver = current_driver;
287    
288     current_driver = drivers;
289     while (current_driver != NULL)
290 stargo 1255 {
291 stargo 1271 DEBUG(("trying %s...\n", current_driver->name));
292     if (current_driver->wave_out_open())
293     {
294     DEBUG(("selected %s\n", current_driver->name));
295     return True;
296     }
297     g_dsp_fd = 0;
298     current_driver = current_driver->next;
299 stargo 1255 }
300 stargo 1271
301     warning("no working audio-driver found\n");
302     failed = True;
303     current_driver = auto_driver;
304 stargo 1255 }
305    
306     return False;
307     }
308    
309 stargo 1254 void
310 stargo 1255 rdpsnd_register_drivers(char *options)
311     {
312     struct audio_driver **reg;
313    
314     /* The order of registrations define the probe-order
315     when opening the device for the first time */
316     reg = &drivers;
317     #if defined(RDPSND_ALSA)
318     *reg = alsa_register(options);
319     reg = &((*reg)->next);
320     #endif
321 stargo 1264 #if defined(RDPSND_SUN)
322     *reg = sun_register(options);
323     reg = &((*reg)->next);
324     #endif
325 stargo 1255 #if defined(RDPSND_OSS)
326     *reg = oss_register(options);
327     reg = &((*reg)->next);
328     #endif
329     #if defined(RDPSND_SGI)
330     *reg = sgi_register(options);
331     reg = &((*reg)->next);
332     #endif
333     #if defined(RDPSND_LIBAO)
334     *reg = libao_register(options);
335     reg = &((*reg)->next);
336     #endif
337     }
338    
339     BOOL
340 stargo 1272 rdpsnd_init(char *optarg)
341 stargo 1255 {
342     static struct audio_driver auto_driver;
343     struct audio_driver *pos;
344 stargo 1272 char *driver = NULL, *options = NULL;
345 stargo 1255
346     drivers = NULL;
347 stargo 1272
348     rdpsnd_channel =
349     channel_register("rdpsnd", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP,
350     rdpsnd_process);
351    
352     if (rdpsnd_channel == NULL)
353     {
354     error("channel_register\n");
355     return False;
356     }
357    
358     if (optarg != NULL && strlen(optarg) > 0)
359     {
360     driver = options = optarg;
361    
362     while (*options != '\0' && *options != ':')
363     options++;
364    
365     if (*options == ':')
366     {
367     *options = '\0';
368     options++;
369     }
370    
371     if (*options == '\0')
372     options = NULL;
373     }
374    
375 stargo 1255 rdpsnd_register_drivers(options);
376    
377     if (!driver)
378     {
379     auto_driver.wave_out_open = &rdpsnd_auto_open;
380     current_driver = &auto_driver;
381     return True;
382     }
383    
384     pos = drivers;
385     while (pos != NULL)
386     {
387     if (!strcmp(pos->name, driver))
388     {
389     DEBUG(("selected %s\n", pos->name));
390     current_driver = pos;
391     return True;
392     }
393     pos = pos->next;
394     }
395     return False;
396     }
397    
398     void
399     rdpsnd_show_help(void)
400     {
401     struct audio_driver *pos;
402    
403     rdpsnd_register_drivers(NULL);
404    
405     pos = drivers;
406     while (pos != NULL)
407     {
408     fprintf(stderr, " %s:\t%s\n", pos->name, pos->description);
409     pos = pos->next;
410     }
411     }
412    
413     inline void
414     rdpsnd_play(void)
415     {
416     current_driver->wave_out_play();
417     }
418    
419     void
420 stargo 1254 rdpsnd_queue_write(STREAM s, uint16 tick, uint8 index)
421     {
422     struct audio_packet *packet = &packet_queue[queue_hi];
423     unsigned int next_hi = (queue_hi + 1) % MAX_QUEUE;
424    
425     if (next_hi == queue_lo)
426     {
427     error("No space to queue audio packet\n");
428     return;
429     }
430    
431     queue_hi = next_hi;
432    
433     packet->s = *s;
434     packet->tick = tick;
435     packet->index = index;
436    
437     if (!g_dsp_busy)
438 stargo 1255 current_driver->wave_out_play();
439 stargo 1254 }
440    
441     inline struct audio_packet *
442     rdpsnd_queue_current_packet(void)
443     {
444     return &packet_queue[queue_lo];
445     }
446    
447     inline BOOL
448     rdpsnd_queue_empty(void)
449     {
450     return (queue_lo == queue_hi);
451     }
452    
453     inline void
454     rdpsnd_queue_init(void)
455     {
456     queue_lo = queue_hi = 0;
457     }
458    
459     inline void
460     rdpsnd_queue_next(void)
461     {
462 stargo 1258 xfree(packet_queue[queue_lo].s.data);
463 stargo 1254 queue_lo = (queue_lo + 1) % MAX_QUEUE;
464     }
465    
466     inline int
467     rdpsnd_queue_next_tick(void)
468     {
469     if (((queue_lo + 1) % MAX_QUEUE) != queue_hi)
470     {
471     return packet_queue[(queue_lo + 1) % MAX_QUEUE].tick;
472     }
473     else
474     {
475     return (packet_queue[queue_lo].tick + 65535) % 65536;
476     }
477     }

  ViewVC Help
Powered by ViewVC 1.1.26