1 |
/* -*- c-basic-offset: 8 -*- |
/* -*- c-basic-offset: 8 -*- |
2 |
rdesktop: A Remote Desktop Protocol client. |
rdesktop: A Remote Desktop Protocol client. |
3 |
Sound Channel Process Functions |
Sound Channel Process Functions |
4 |
Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB |
Copyright 2006-2008 Pierre Ossman <ossman@cendio.se> for Cendio AB |
5 |
Copyright (C) Matthew Chapman 2003 |
Copyright (C) Matthew Chapman 2003-2008 |
6 |
Copyright (C) GuoJunBo guojunbo@ict.ac.cn 2003 |
Copyright (C) GuoJunBo guojunbo@ict.ac.cn 2003 |
7 |
|
|
8 |
This program is free software; you can redistribute it and/or modify |
This program is free software; you can redistribute it and/or modify |
50 |
static struct audio_driver *drivers = NULL; |
static struct audio_driver *drivers = NULL; |
51 |
struct audio_driver *current_driver = NULL; |
struct audio_driver *current_driver = NULL; |
52 |
|
|
53 |
static BOOL device_open; |
static RD_BOOL device_open; |
54 |
static BOOL rec_device_open; |
static RD_BOOL rec_device_open; |
55 |
|
|
56 |
static WAVEFORMATEX formats[MAX_FORMATS]; |
static RD_WAVEFORMATEX formats[MAX_FORMATS]; |
57 |
static unsigned int format_count; |
static unsigned int format_count; |
58 |
static unsigned int current_format; |
static unsigned int current_format; |
59 |
|
|
60 |
static WAVEFORMATEX rec_formats[MAX_FORMATS]; |
static RD_WAVEFORMATEX rec_formats[MAX_FORMATS]; |
61 |
static unsigned int rec_format_count; |
static unsigned int rec_format_count; |
62 |
|
static unsigned int rec_current_format; |
63 |
|
|
64 |
unsigned int queue_hi, queue_lo, queue_pending; |
unsigned int queue_hi, queue_lo, queue_pending; |
65 |
struct audio_packet packet_queue[MAX_QUEUE]; |
struct audio_packet packet_queue[MAX_QUEUE]; |
66 |
|
|
67 |
static char record_buffer[8192]; |
static char record_buffer[8192]; |
68 |
static int record_buffer_size; |
static uint32 record_buffer_size; |
69 |
|
|
70 |
static uint8 packet_opcode; |
static uint8 packet_opcode; |
71 |
static struct stream packet; |
static struct stream packet; |
154 |
void |
void |
155 |
rdpsnd_record(const void *data, unsigned int size) |
rdpsnd_record(const void *data, unsigned int size) |
156 |
{ |
{ |
157 |
int remain; |
uint32 remain, chunk; |
158 |
|
|
159 |
assert(rec_device_open); |
assert(rec_device_open); |
160 |
|
|
163 |
remain = sizeof(record_buffer) - record_buffer_size; |
remain = sizeof(record_buffer) - record_buffer_size; |
164 |
|
|
165 |
if (size >= remain) |
if (size >= remain) |
166 |
{ |
chunk = remain; |
|
memcpy(record_buffer + record_buffer_size, data, remain); |
|
|
record_buffer_size += remain; |
|
|
rdpsnd_flush_record(); |
|
|
data = (const char *) data + remain; |
|
|
size -= remain; |
|
|
} |
|
167 |
else |
else |
168 |
{ |
chunk = size; |
169 |
memcpy(record_buffer + record_buffer_size, data, size); |
|
170 |
record_buffer_size += size; |
memcpy(record_buffer + record_buffer_size, data, chunk); |
171 |
size = 0; |
|
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 |
|
rdpsnd_flush_record(); |
185 |
} |
} |
186 |
} |
} |
187 |
|
|
188 |
static BOOL |
static RD_BOOL |
189 |
rdpsnd_auto_select(void) |
rdpsnd_auto_select(void) |
190 |
{ |
{ |
191 |
static BOOL failed = False; |
static RD_BOOL failed = False; |
192 |
|
|
193 |
if (!failed) |
if (!failed) |
194 |
{ |
{ |
219 |
uint16 in_format_count, i; |
uint16 in_format_count, i; |
220 |
uint8 pad; |
uint8 pad; |
221 |
uint16 version; |
uint16 version; |
222 |
WAVEFORMATEX *format; |
RD_WAVEFORMATEX *format; |
223 |
STREAM out; |
STREAM out; |
224 |
BOOL device_available = False; |
RD_BOOL device_available = False; |
225 |
int readcnt; |
int readcnt; |
226 |
int discardcnt; |
int discardcnt; |
227 |
|
|
270 |
in_uint8a(in, format->cb, readcnt); |
in_uint8a(in, format->cb, readcnt); |
271 |
in_uint8s(in, discardcnt); |
in_uint8s(in, discardcnt); |
272 |
|
|
273 |
if (device_available && current_driver->wave_out_format_supported(format)) |
if (current_driver && current_driver->wave_out_format_supported(format)) |
274 |
{ |
{ |
275 |
format_count++; |
format_count++; |
276 |
if (format_count == MAX_FORMATS) |
if (format_count == MAX_FORMATS) |
333 |
{ |
{ |
334 |
uint16 in_format_count, i; |
uint16 in_format_count, i; |
335 |
uint16 version; |
uint16 version; |
336 |
WAVEFORMATEX *format; |
RD_WAVEFORMATEX *format; |
337 |
STREAM out; |
STREAM out; |
338 |
BOOL device_available = False; |
RD_BOOL device_available = False; |
339 |
int readcnt; |
int readcnt; |
340 |
int discardcnt; |
int discardcnt; |
341 |
|
|
383 |
in_uint8a(in, format->cb, readcnt); |
in_uint8a(in, format->cb, readcnt); |
384 |
in_uint8s(in, discardcnt); |
in_uint8s(in, discardcnt); |
385 |
|
|
386 |
if (device_available && current_driver->wave_in_format_supported(format)) |
if (current_driver && current_driver->wave_in_format_supported |
387 |
|
&& current_driver->wave_in_format_supported(format)) |
388 |
{ |
{ |
389 |
rec_format_count++; |
rec_format_count++; |
390 |
if (rec_format_count == MAX_FORMATS) |
if (rec_format_count == MAX_FORMATS) |
520 |
current_driver->wave_in_close(); |
current_driver->wave_in_close(); |
521 |
break; |
break; |
522 |
} |
} |
523 |
|
rec_current_format = format; |
524 |
rec_device_open = True; |
rec_device_open = True; |
525 |
break; |
break; |
526 |
case RDPSND_REC_STOP: |
case RDPSND_REC_STOP: |
601 |
} |
} |
602 |
} |
} |
603 |
|
|
604 |
static BOOL |
static RD_BOOL |
605 |
rdpsnddbg_line_handler(const char *line, void *data) |
rdpsnddbg_line_handler(const char *line, void *data) |
606 |
{ |
{ |
607 |
#ifdef WITH_DEBUG_SOUND |
#ifdef WITH_DEBUG_SOUND |
619 |
|
|
620 |
pkglen = s->end - s->p; |
pkglen = s->end - s->p; |
621 |
/* str_handle_lines requires null terminated strings */ |
/* str_handle_lines requires null terminated strings */ |
622 |
buf = xmalloc(pkglen + 1); |
buf = (char *) xmalloc(pkglen + 1); |
623 |
STRNCPY(buf, (char *) s->p, pkglen + 1); |
STRNCPY(buf, (char *) s->p, pkglen + 1); |
624 |
|
|
625 |
str_handle_lines(buf, &rest, rdpsnddbg_line_handler, NULL); |
str_handle_lines(buf, &rest, rdpsnddbg_line_handler, NULL); |
663 |
*reg = NULL; |
*reg = NULL; |
664 |
} |
} |
665 |
|
|
666 |
BOOL |
RD_BOOL |
667 |
rdpsnd_init(char *optarg) |
rdpsnd_init(char *optarg) |
668 |
{ |
{ |
669 |
struct audio_driver *pos; |
struct audio_driver *pos; |
671 |
|
|
672 |
drivers = NULL; |
drivers = NULL; |
673 |
|
|
674 |
packet.data = xmalloc(65536); |
packet.data = (uint8 *) xmalloc(65536); |
675 |
packet.p = packet.end = packet.data; |
packet.p = packet.end = packet.data; |
676 |
packet.size = 0; |
packet.size = 0; |
677 |
|
|
800 |
return &packet_queue[queue_lo]; |
return &packet_queue[queue_lo]; |
801 |
} |
} |
802 |
|
|
803 |
BOOL |
RD_BOOL |
804 |
rdpsnd_queue_empty(void) |
rdpsnd_queue_empty(void) |
805 |
{ |
{ |
806 |
return (queue_lo == queue_hi); |
return (queue_lo == queue_hi); |