37 |
#define MAX_FORMATS 10 |
#define MAX_FORMATS 10 |
38 |
#define MAX_QUEUE 10 |
#define MAX_QUEUE 10 |
39 |
|
|
|
BOOL g_dsp_busy = False; |
|
|
int g_dsp_fd; |
|
|
|
|
40 |
static VCHANNEL *rdpsnd_channel; |
static VCHANNEL *rdpsnd_channel; |
41 |
static struct audio_driver *drivers = NULL; |
static struct audio_driver *drivers = NULL; |
42 |
struct audio_driver *current_driver = NULL; |
struct audio_driver *current_driver = NULL; |
91 |
(unsigned) tick, (unsigned) packet_index)); |
(unsigned) tick, (unsigned) packet_index)); |
92 |
} |
} |
93 |
|
|
94 |
|
|
95 |
|
static BOOL |
96 |
|
rdpsnd_auto_select(void) |
97 |
|
{ |
98 |
|
static BOOL failed = False; |
99 |
|
|
100 |
|
if (!failed) |
101 |
|
{ |
102 |
|
current_driver = drivers; |
103 |
|
while (current_driver != NULL) |
104 |
|
{ |
105 |
|
DEBUG(("trying %s...\n", current_driver->name)); |
106 |
|
if (current_driver->wave_out_open()) |
107 |
|
{ |
108 |
|
DEBUG(("selected %s\n", current_driver->name)); |
109 |
|
return True; |
110 |
|
} |
111 |
|
current_driver = current_driver->next; |
112 |
|
} |
113 |
|
|
114 |
|
warning("no working audio-driver found\n"); |
115 |
|
failed = True; |
116 |
|
current_driver = NULL; |
117 |
|
} |
118 |
|
|
119 |
|
return False; |
120 |
|
} |
121 |
|
|
122 |
static void |
static void |
123 |
rdpsnd_process_negotiate(STREAM in) |
rdpsnd_process_negotiate(STREAM in) |
124 |
{ |
{ |
140 |
DEBUG_SOUND(("RDPSND: RDPSND_NEGOTIATE(formats: %d, pad: 0x%02x, version: %x)\n", |
DEBUG_SOUND(("RDPSND: RDPSND_NEGOTIATE(formats: %d, pad: 0x%02x, version: %x)\n", |
141 |
(int) in_format_count, (unsigned) pad, (unsigned) version)); |
(int) in_format_count, (unsigned) pad, (unsigned) version)); |
142 |
|
|
143 |
if (current_driver->wave_out_open()) |
if (!current_driver) |
144 |
|
rdpsnd_auto_select(); |
145 |
|
|
146 |
|
if (current_driver && current_driver->wave_out_open()) |
147 |
{ |
{ |
148 |
current_driver->wave_out_close(); |
current_driver->wave_out_close(); |
149 |
device_available = True; |
device_available = True; |
258 |
|
|
259 |
if (!device_open || (format != current_format)) |
if (!device_open || (format != current_format)) |
260 |
{ |
{ |
261 |
|
/* |
262 |
|
* If we haven't selected a device by now, then either |
263 |
|
* we've failed to find a working device, or the server |
264 |
|
* is sending bogus RDPSND_WRITE. |
265 |
|
*/ |
266 |
|
if (!current_driver) |
267 |
|
{ |
268 |
|
rdpsnd_send_completion(tick, packet_index); |
269 |
|
break; |
270 |
|
} |
271 |
if (!device_open && !current_driver->wave_out_open()) |
if (!device_open && !current_driver->wave_out_open()) |
272 |
{ |
{ |
273 |
rdpsnd_send_completion(tick, packet_index); |
rdpsnd_send_completion(tick, packet_index); |
291 |
break; |
break; |
292 |
case RDPSND_CLOSE: |
case RDPSND_CLOSE: |
293 |
DEBUG_SOUND(("RDPSND: RDPSND_CLOSE()\n")); |
DEBUG_SOUND(("RDPSND: RDPSND_CLOSE()\n")); |
294 |
current_driver->wave_out_close(); |
if (device_open) |
295 |
|
current_driver->wave_out_close(); |
296 |
device_open = False; |
device_open = False; |
297 |
break; |
break; |
298 |
case RDPSND_NEGOTIATE: |
case RDPSND_NEGOTIATE: |
372 |
} |
} |
373 |
} |
} |
374 |
|
|
|
static BOOL |
|
|
rdpsnd_auto_open(void) |
|
|
{ |
|
|
static BOOL failed = False; |
|
|
|
|
|
if (!failed) |
|
|
{ |
|
|
struct audio_driver *auto_driver = current_driver; |
|
|
|
|
|
current_driver = drivers; |
|
|
while (current_driver != NULL) |
|
|
{ |
|
|
DEBUG(("trying %s...\n", current_driver->name)); |
|
|
if (current_driver->wave_out_open()) |
|
|
{ |
|
|
DEBUG(("selected %s\n", current_driver->name)); |
|
|
return True; |
|
|
} |
|
|
g_dsp_fd = 0; |
|
|
current_driver = current_driver->next; |
|
|
} |
|
|
|
|
|
warning("no working audio-driver found\n"); |
|
|
failed = True; |
|
|
current_driver = auto_driver; |
|
|
} |
|
|
|
|
|
return False; |
|
|
} |
|
|
|
|
375 |
static void |
static void |
376 |
rdpsnd_register_drivers(char *options) |
rdpsnd_register_drivers(char *options) |
377 |
{ |
{ |
411 |
BOOL |
BOOL |
412 |
rdpsnd_init(char *optarg) |
rdpsnd_init(char *optarg) |
413 |
{ |
{ |
|
static struct audio_driver auto_driver; |
|
414 |
struct audio_driver *pos; |
struct audio_driver *pos; |
415 |
char *driver = NULL, *options = NULL; |
char *driver = NULL, *options = NULL; |
416 |
|
|
452 |
rdpsnd_register_drivers(options); |
rdpsnd_register_drivers(options); |
453 |
|
|
454 |
if (!driver) |
if (!driver) |
|
{ |
|
|
auto_driver.wave_out_open = &rdpsnd_auto_open; |
|
|
current_driver = &auto_driver; |
|
455 |
return True; |
return True; |
|
} |
|
456 |
|
|
457 |
pos = drivers; |
pos = drivers; |
458 |
while (pos != NULL) |
while (pos != NULL) |
484 |
} |
} |
485 |
|
|
486 |
void |
void |
|
rdpsnd_play(void) |
|
|
{ |
|
|
current_driver->wave_out_play(); |
|
|
} |
|
|
|
|
|
void |
|
487 |
rdpsnd_add_fds(int *n, fd_set * rfds, fd_set * wfds, struct timeval *tv) |
rdpsnd_add_fds(int *n, fd_set * rfds, fd_set * wfds, struct timeval *tv) |
488 |
{ |
{ |
489 |
long next_pending; |
long next_pending; |
490 |
|
|
491 |
if (g_dsp_busy) |
if (device_open) |
492 |
{ |
current_driver->add_fds(n, rfds, wfds, tv); |
|
FD_SET(g_dsp_fd, wfds); |
|
|
*n = (g_dsp_fd > *n) ? g_dsp_fd : *n; |
|
|
} |
|
493 |
|
|
494 |
next_pending = rdpsnd_queue_next_completion(); |
next_pending = rdpsnd_queue_next_completion(); |
495 |
if (next_pending >= 0) |
if (next_pending >= 0) |
510 |
{ |
{ |
511 |
rdpsnd_queue_complete_pending(); |
rdpsnd_queue_complete_pending(); |
512 |
|
|
513 |
if (g_dsp_busy && FD_ISSET(g_dsp_fd, wfds)) |
if (device_open) |
514 |
rdpsnd_play(); |
current_driver->check_fds(rfds, wfds); |
515 |
} |
} |
516 |
|
|
517 |
static void |
static void |
533 |
packet->index = index; |
packet->index = index; |
534 |
|
|
535 |
gettimeofday(&packet->arrive_tv, NULL); |
gettimeofday(&packet->arrive_tv, NULL); |
|
|
|
|
if (!g_dsp_busy) |
|
|
current_driver->wave_out_play(); |
|
536 |
} |
} |
537 |
|
|
538 |
struct audio_packet * |
struct audio_packet * |