19 |
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
20 |
*/ |
*/ |
21 |
|
|
22 |
|
#include <assert.h> |
23 |
|
|
24 |
#include "rdesktop.h" |
#include "rdesktop.h" |
25 |
#include "rdpsnd.h" |
#include "rdpsnd.h" |
26 |
|
#include "rdpsnd_dsp.h" |
27 |
|
|
28 |
#define RDPSND_CLOSE 1 |
#define RDPSND_CLOSE 1 |
29 |
#define RDPSND_WRITE 2 |
#define RDPSND_WRITE 2 |
196 |
static uint16 tick, format; |
static uint16 tick, format; |
197 |
static uint8 packet_index; |
static uint8 packet_index; |
198 |
static BOOL awaiting_data_packet; |
static BOOL awaiting_data_packet; |
199 |
|
static unsigned char missing_bytes[4] = { 0, 0, 0, 0 }; |
200 |
|
|
201 |
#ifdef RDPSND_DEBUG |
#ifdef RDPSND_DEBUG |
202 |
printf("RDPSND recv:\n"); |
printf("RDPSND recv:\n"); |
229 |
current_format = format; |
current_format = format; |
230 |
} |
} |
231 |
|
|
232 |
current_driver->wave_out_write(s, tick, packet_index); |
/* Insert the 4 missing bytes retrieved from last RDPSND_WRITE */ |
233 |
|
memcpy(s->data, missing_bytes, 4); |
234 |
|
|
235 |
|
current_driver-> |
236 |
|
wave_out_write(rdpsnd_dsp_process |
237 |
|
(s, current_driver, &formats[current_format]), tick, |
238 |
|
packet_index); |
239 |
awaiting_data_packet = False; |
awaiting_data_packet = False; |
240 |
return; |
return; |
241 |
} |
} |
250 |
in_uint16_le(s, tick); |
in_uint16_le(s, tick); |
251 |
in_uint16_le(s, format); |
in_uint16_le(s, format); |
252 |
in_uint8(s, packet_index); |
in_uint8(s, packet_index); |
253 |
|
/* Here are our lost bytes, but why? */ |
254 |
|
memcpy(missing_bytes, s->end - 4, 4); |
255 |
awaiting_data_packet = True; |
awaiting_data_packet = True; |
256 |
break; |
break; |
257 |
case RDPSND_CLOSE: |
case RDPSND_CLOSE: |
278 |
} |
} |
279 |
} |
} |
280 |
|
|
281 |
BOOL |
static BOOL |
|
rdpsnd_init(void) |
|
|
{ |
|
|
rdpsnd_channel = |
|
|
channel_register("rdpsnd", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP, |
|
|
rdpsnd_process); |
|
|
|
|
|
return (rdpsnd_channel != NULL); |
|
|
} |
|
|
|
|
|
BOOL |
|
282 |
rdpsnd_auto_open(void) |
rdpsnd_auto_open(void) |
283 |
{ |
{ |
284 |
current_driver = drivers; |
static BOOL failed = False; |
285 |
while (current_driver != NULL) |
|
286 |
|
if (!failed) |
287 |
{ |
{ |
288 |
DEBUG(("trying %s...\n", current_driver->name)); |
struct audio_driver *auto_driver = current_driver; |
289 |
if (current_driver->wave_out_open()) |
|
290 |
|
current_driver = drivers; |
291 |
|
while (current_driver != NULL) |
292 |
{ |
{ |
293 |
DEBUG(("selected %s\n", current_driver->name)); |
DEBUG(("trying %s...\n", current_driver->name)); |
294 |
return True; |
if (current_driver->wave_out_open()) |
295 |
|
{ |
296 |
|
DEBUG(("selected %s\n", current_driver->name)); |
297 |
|
return True; |
298 |
|
} |
299 |
|
g_dsp_fd = 0; |
300 |
|
current_driver = current_driver->next; |
301 |
} |
} |
|
g_dsp_fd = 0; |
|
|
current_driver = current_driver->next; |
|
|
} |
|
302 |
|
|
303 |
warning("no working audio-driver found\n"); |
warning("no working audio-driver found\n"); |
304 |
|
failed = True; |
305 |
|
current_driver = auto_driver; |
306 |
|
} |
307 |
|
|
308 |
return False; |
return False; |
309 |
} |
} |
310 |
|
|
311 |
void |
static void |
312 |
rdpsnd_register_drivers(char *options) |
rdpsnd_register_drivers(char *options) |
313 |
{ |
{ |
314 |
struct audio_driver **reg; |
struct audio_driver **reg; |
318 |
reg = &drivers; |
reg = &drivers; |
319 |
#if defined(RDPSND_ALSA) |
#if defined(RDPSND_ALSA) |
320 |
*reg = alsa_register(options); |
*reg = alsa_register(options); |
321 |
reg = &((*reg)->next); |
assert(*reg); |
|
#endif |
|
|
#if defined(RDPSND_OSS) |
|
|
*reg = oss_register(options); |
|
322 |
reg = &((*reg)->next); |
reg = &((*reg)->next); |
323 |
#endif |
#endif |
324 |
#if defined(RDPSND_SUN) |
#if defined(RDPSND_SUN) |
325 |
*reg = sun_register(options); |
*reg = sun_register(options); |
326 |
|
assert(*reg); |
327 |
|
reg = &((*reg)->next); |
328 |
|
#endif |
329 |
|
#if defined(RDPSND_OSS) |
330 |
|
*reg = oss_register(options); |
331 |
|
assert(*reg); |
332 |
reg = &((*reg)->next); |
reg = &((*reg)->next); |
333 |
#endif |
#endif |
334 |
#if defined(RDPSND_SGI) |
#if defined(RDPSND_SGI) |
335 |
*reg = sgi_register(options); |
*reg = sgi_register(options); |
336 |
|
assert(*reg); |
337 |
reg = &((*reg)->next); |
reg = &((*reg)->next); |
338 |
#endif |
#endif |
339 |
#if defined(RDPSND_LIBAO) |
#if defined(RDPSND_LIBAO) |
340 |
*reg = libao_register(options); |
*reg = libao_register(options); |
341 |
|
assert(*reg); |
342 |
reg = &((*reg)->next); |
reg = &((*reg)->next); |
343 |
#endif |
#endif |
344 |
} |
} |
345 |
|
|
346 |
BOOL |
BOOL |
347 |
rdpsnd_select_driver(char *driver, char *options) |
rdpsnd_init(char *optarg) |
348 |
{ |
{ |
349 |
static struct audio_driver auto_driver; |
static struct audio_driver auto_driver; |
350 |
struct audio_driver *pos; |
struct audio_driver *pos; |
351 |
|
char *driver = NULL, *options = NULL; |
352 |
|
|
353 |
drivers = NULL; |
drivers = NULL; |
354 |
|
|
355 |
|
rdpsnd_channel = |
356 |
|
channel_register("rdpsnd", CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP, |
357 |
|
rdpsnd_process); |
358 |
|
|
359 |
|
if (rdpsnd_channel == NULL) |
360 |
|
{ |
361 |
|
error("channel_register\n"); |
362 |
|
return False; |
363 |
|
} |
364 |
|
|
365 |
|
if (optarg != NULL && strlen(optarg) > 0) |
366 |
|
{ |
367 |
|
driver = options = optarg; |
368 |
|
|
369 |
|
while (*options != '\0' && *options != ':') |
370 |
|
options++; |
371 |
|
|
372 |
|
if (*options == ':') |
373 |
|
{ |
374 |
|
*options = '\0'; |
375 |
|
options++; |
376 |
|
} |
377 |
|
|
378 |
|
if (*options == '\0') |
379 |
|
options = NULL; |
380 |
|
} |
381 |
|
|
382 |
rdpsnd_register_drivers(options); |
rdpsnd_register_drivers(options); |
383 |
|
|
384 |
if (!driver) |
if (!driver) |
417 |
} |
} |
418 |
} |
} |
419 |
|
|
420 |
inline void |
void |
421 |
rdpsnd_play(void) |
rdpsnd_play(void) |
422 |
{ |
{ |
423 |
current_driver->wave_out_play(); |
current_driver->wave_out_play(); |
440 |
packet->s = *s; |
packet->s = *s; |
441 |
packet->tick = tick; |
packet->tick = tick; |
442 |
packet->index = index; |
packet->index = index; |
|
packet->s.p += 4; |
|
|
|
|
|
/* we steal the data buffer from s, give it a new one */ |
|
|
s->data = malloc(s->size); |
|
443 |
|
|
444 |
if (!g_dsp_busy) |
if (!g_dsp_busy) |
445 |
current_driver->wave_out_play(); |
current_driver->wave_out_play(); |
446 |
} |
} |
447 |
|
|
448 |
inline struct audio_packet * |
struct audio_packet * |
449 |
rdpsnd_queue_current_packet(void) |
rdpsnd_queue_current_packet(void) |
450 |
{ |
{ |
451 |
return &packet_queue[queue_lo]; |
return &packet_queue[queue_lo]; |
452 |
} |
} |
453 |
|
|
454 |
inline BOOL |
BOOL |
455 |
rdpsnd_queue_empty(void) |
rdpsnd_queue_empty(void) |
456 |
{ |
{ |
457 |
return (queue_lo == queue_hi); |
return (queue_lo == queue_hi); |
458 |
} |
} |
459 |
|
|
460 |
inline void |
void |
461 |
rdpsnd_queue_init(void) |
rdpsnd_queue_init(void) |
462 |
{ |
{ |
463 |
queue_lo = queue_hi = 0; |
queue_lo = queue_hi = 0; |
464 |
} |
} |
465 |
|
|
466 |
inline void |
void |
467 |
rdpsnd_queue_next(void) |
rdpsnd_queue_next(void) |
468 |
{ |
{ |
469 |
free(packet_queue[queue_lo].s.data); |
xfree(packet_queue[queue_lo].s.data); |
470 |
queue_lo = (queue_lo + 1) % MAX_QUEUE; |
queue_lo = (queue_lo + 1) % MAX_QUEUE; |
471 |
} |
} |
472 |
|
|
473 |
inline int |
int |
474 |
rdpsnd_queue_next_tick(void) |
rdpsnd_queue_next_tick(void) |
475 |
{ |
{ |
476 |
if (((queue_lo + 1) % MAX_QUEUE) != queue_hi) |
if (((queue_lo + 1) % MAX_QUEUE) != queue_hi) |