summaryrefslogtreecommitdiffstats
path: root/sesman/chansrv/sound.c
diff options
context:
space:
mode:
authorLaxmikant Rashinkar <LK.Rashinkar@gmail.com>2012-09-19 20:51:34 -0700
committerLaxmikant Rashinkar <LK.Rashinkar@gmail.com>2012-09-19 20:51:34 -0700
commit1123323fda6d128fb98b0427e0ea5f6a2dc9e632 (patch)
tree3407a3771a069f812554312ce7c36db625139cc2 /sesman/chansrv/sound.c
parent3cedfae76a2351bc8b1e5bd2ee33bbf8630dbacf (diff)
downloadxrdp-proprietary-1123323fda6d128fb98b0427e0ea5f6a2dc9e632.tar.gz
xrdp-proprietary-1123323fda6d128fb98b0427e0ea5f6a2dc9e632.zip
o moved from GNU General Public License to Apache License, Version 2.0
o applied new coding standards to all .c files o moved some files around
Diffstat (limited to 'sesman/chansrv/sound.c')
-rw-r--r--sesman/chansrv/sound.c820
1 files changed, 425 insertions, 395 deletions
diff --git a/sesman/chansrv/sound.c b/sesman/chansrv/sound.c
index e4d54bb0..e8b801c6 100644
--- a/sesman/chansrv/sound.c
+++ b/sesman/chansrv/sound.c
@@ -28,100 +28,100 @@ static int g_training_sent_time = 0;
static int g_cBlockNo = 0;
#if defined(XRDP_SIMPLESOUND)
-static void* DEFAULT_CC
-read_raw_audio_data(void* arg);
+static void *DEFAULT_CC
+read_raw_audio_data(void *arg);
#endif
/*****************************************************************************/
static int APP_CC
sound_send_server_formats(void)
{
- struct stream* s;
- int bytes;
- char* size_ptr;
-
- print_got_here();
-
- make_stream(s);
- init_stream(s, 8182);
- out_uint16_le(s, SNDC_FORMATS);
- size_ptr = s->p;
- out_uint16_le(s, 0); /* size, set later */
- out_uint32_le(s, 0); /* dwFlags */
- out_uint32_le(s, 0); /* dwVolume */
- out_uint32_le(s, 0); /* dwPitch */
- out_uint16_le(s, 0); /* wDGramPort */
- out_uint16_le(s, 1); /* wNumberOfFormats */
- out_uint8(s, g_cBlockNo); /* cLastBlockConfirmed */
- out_uint16_le(s, 2); /* wVersion */
- out_uint8(s, 0); /* bPad */
-
- /* sndFormats */
- /*
- wFormatTag 2 byte offset 0
- nChannels 2 byte offset 2
- nSamplesPerSec 4 byte offset 4
- nAvgBytesPerSec 4 byte offset 8
- nBlockAlign 2 byte offset 12
- wBitsPerSample 2 byte offset 14
- cbSize 2 byte offset 16
- data variable offset 18
- */
-
- /* examples
- 01 00 02 00 44 ac 00 00 10 b1 02 00 04 00 10 00 ....D...........
- 00 00
- 01 00 02 00 22 56 00 00 88 58 01 00 04 00 10 00 ...."V...X......
- 00 00
- */
-
- out_uint16_le(s, 1); // wFormatTag - WAVE_FORMAT_PCM
- out_uint16_le(s, 2); // num of channels
- out_uint32_le(s, 44100); // samples per sec
- out_uint32_le(s, 176400); // avg bytes per sec
- out_uint16_le(s, 4); // block align
- out_uint16_le(s, 16); // bits per sample
- out_uint16_le(s, 0); // size
-
- s_mark_end(s);
- bytes = (int)((s->end - s->data) - 4);
- size_ptr[0] = bytes;
- size_ptr[1] = bytes >> 8;
- bytes = (int)(s->end - s->data);
- send_channel_data(g_rdpsnd_chan_id, s->data, bytes);
- free_stream(s);
- return 0;
+ struct stream *s;
+ int bytes;
+ char *size_ptr;
+
+ print_got_here();
+
+ make_stream(s);
+ init_stream(s, 8182);
+ out_uint16_le(s, SNDC_FORMATS);
+ size_ptr = s->p;
+ out_uint16_le(s, 0); /* size, set later */
+ out_uint32_le(s, 0); /* dwFlags */
+ out_uint32_le(s, 0); /* dwVolume */
+ out_uint32_le(s, 0); /* dwPitch */
+ out_uint16_le(s, 0); /* wDGramPort */
+ out_uint16_le(s, 1); /* wNumberOfFormats */
+ out_uint8(s, g_cBlockNo); /* cLastBlockConfirmed */
+ out_uint16_le(s, 2); /* wVersion */
+ out_uint8(s, 0); /* bPad */
+
+ /* sndFormats */
+ /*
+ wFormatTag 2 byte offset 0
+ nChannels 2 byte offset 2
+ nSamplesPerSec 4 byte offset 4
+ nAvgBytesPerSec 4 byte offset 8
+ nBlockAlign 2 byte offset 12
+ wBitsPerSample 2 byte offset 14
+ cbSize 2 byte offset 16
+ data variable offset 18
+ */
+
+ /* examples
+ 01 00 02 00 44 ac 00 00 10 b1 02 00 04 00 10 00 ....D...........
+ 00 00
+ 01 00 02 00 22 56 00 00 88 58 01 00 04 00 10 00 ...."V...X......
+ 00 00
+ */
+
+ out_uint16_le(s, 1); // wFormatTag - WAVE_FORMAT_PCM
+ out_uint16_le(s, 2); // num of channels
+ out_uint32_le(s, 44100); // samples per sec
+ out_uint32_le(s, 176400); // avg bytes per sec
+ out_uint16_le(s, 4); // block align
+ out_uint16_le(s, 16); // bits per sample
+ out_uint16_le(s, 0); // size
+
+ s_mark_end(s);
+ bytes = (int)((s->end - s->data) - 4);
+ size_ptr[0] = bytes;
+ size_ptr[1] = bytes >> 8;
+ bytes = (int)(s->end - s->data);
+ send_channel_data(g_rdpsnd_chan_id, s->data, bytes);
+ free_stream(s);
+ return 0;
}
/*****************************************************************************/
static int
sound_send_training(void)
{
- struct stream* s;
- int bytes;
- int time;
- char* size_ptr;
-
- print_got_here();
-
- make_stream(s);
- init_stream(s, 8182);
- out_uint16_le(s, SNDC_TRAINING);
- size_ptr = s->p;
- out_uint16_le(s, 0); /* size, set later */
- time = g_time2();
- g_training_sent_time = time;
- out_uint16_le(s, time);
- out_uint16_le(s, 1024);
- out_uint8s(s, (1024 - 4));
- s_mark_end(s);
- bytes = (int)((s->end - s->data) - 4);
- size_ptr[0] = bytes;
- size_ptr[1] = bytes >> 8;
- bytes = (int)(s->end - s->data);
- send_channel_data(g_rdpsnd_chan_id, s->data, bytes);
- free_stream(s);
- return 0;
+ struct stream *s;
+ int bytes;
+ int time;
+ char *size_ptr;
+
+ print_got_here();
+
+ make_stream(s);
+ init_stream(s, 8182);
+ out_uint16_le(s, SNDC_TRAINING);
+ size_ptr = s->p;
+ out_uint16_le(s, 0); /* size, set later */
+ time = g_time2();
+ g_training_sent_time = time;
+ out_uint16_le(s, time);
+ out_uint16_le(s, 1024);
+ out_uint8s(s, (1024 - 4));
+ s_mark_end(s);
+ bytes = (int)((s->end - s->data) - 4);
+ size_ptr[0] = bytes;
+ size_ptr[1] = bytes >> 8;
+ bytes = (int)(s->end - s->data);
+ send_channel_data(g_rdpsnd_chan_id, s->data, bytes);
+ free_stream(s);
+ return 0;
}
/*****************************************************************************/
@@ -132,318 +132,339 @@ sound_send_training(void)
*/
static int APP_CC
-sound_process_formats(struct stream* s, int size)
+sound_process_formats(struct stream *s, int size)
{
- int num_formats;
-
- print_got_here();
-
- LOG(0, ("sound_process_formats:"));
- if (size < 16)
- {
- return 1;
- }
- in_uint8s(s, 14);
- in_uint16_le(s, num_formats);
- if (num_formats > 0)
- {
- sound_send_training();
- }
- return 0;
+ int num_formats;
+
+ print_got_here();
+
+ LOG(0, ("sound_process_formats:"));
+
+ if (size < 16)
+ {
+ return 1;
+ }
+
+ in_uint8s(s, 14);
+ in_uint16_le(s, num_formats);
+
+ if (num_formats > 0)
+ {
+ sound_send_training();
+ }
+
+ return 0;
}
/*****************************************************************************/
static int
-sound_send_wave_data(char* data, int data_bytes)
+sound_send_wave_data(char *data, int data_bytes)
{
- struct stream* s;
- int bytes;
- int time;
- char* size_ptr;
-
- print_got_here();
-
- if ((data_bytes < 4) || (data_bytes > 32 * 1024))
- {
- LOG(0, ("sound_send_wave_data: bad data_bytes %d", data_bytes));
- }
-
- /* part one of 2 PDU wave info */
-
- LOG(10, ("sound_send_wave_data: sending %d bytes", data_bytes));
-
- make_stream(s);
- init_stream(s, data_bytes);
- out_uint16_le(s, SNDC_WAVE);
- size_ptr = s->p;
- out_uint16_le(s, 0); /* size, set later */
- time = g_time2();
- out_uint16_le(s, time);
- out_uint16_le(s, 0); /* wFormatNo */
- g_cBlockNo++;
- out_uint8(s, g_cBlockNo);
-
- LOG(10, ("sound_send_wave_data: sending time %d, g_cBlockNo %d",
- time & 0xffff, g_cBlockNo & 0xff));
-
- out_uint8s(s, 3);
- out_uint8a(s, data, 4);
- s_mark_end(s);
- bytes = (int)((s->end - s->data) - 4);
- bytes += data_bytes;
- bytes -= 4;
- size_ptr[0] = bytes;
- size_ptr[1] = bytes >> 8;
- bytes = (int)(s->end - s->data);
- send_channel_data(g_rdpsnd_chan_id, s->data, bytes);
-
- /* part two of 2 PDU wave info */
- init_stream(s, data_bytes);
- out_uint32_le(s, 0);
- out_uint8a(s, data + 4, data_bytes - 4);
- s_mark_end(s);
- bytes = (int)(s->end - s->data);
- send_channel_data(g_rdpsnd_chan_id, s->data, bytes);
- free_stream(s);
- return 0;
+ struct stream *s;
+ int bytes;
+ int time;
+ char *size_ptr;
+
+ print_got_here();
+
+ if ((data_bytes < 4) || (data_bytes > 32 * 1024))
+ {
+ LOG(0, ("sound_send_wave_data: bad data_bytes %d", data_bytes));
+ }
+
+ /* part one of 2 PDU wave info */
+
+ LOG(10, ("sound_send_wave_data: sending %d bytes", data_bytes));
+
+ make_stream(s);
+ init_stream(s, data_bytes);
+ out_uint16_le(s, SNDC_WAVE);
+ size_ptr = s->p;
+ out_uint16_le(s, 0); /* size, set later */
+ time = g_time2();
+ out_uint16_le(s, time);
+ out_uint16_le(s, 0); /* wFormatNo */
+ g_cBlockNo++;
+ out_uint8(s, g_cBlockNo);
+
+ LOG(10, ("sound_send_wave_data: sending time %d, g_cBlockNo %d",
+ time & 0xffff, g_cBlockNo & 0xff));
+
+ out_uint8s(s, 3);
+ out_uint8a(s, data, 4);
+ s_mark_end(s);
+ bytes = (int)((s->end - s->data) - 4);
+ bytes += data_bytes;
+ bytes -= 4;
+ size_ptr[0] = bytes;
+ size_ptr[1] = bytes >> 8;
+ bytes = (int)(s->end - s->data);
+ send_channel_data(g_rdpsnd_chan_id, s->data, bytes);
+
+ /* part two of 2 PDU wave info */
+ init_stream(s, data_bytes);
+ out_uint32_le(s, 0);
+ out_uint8a(s, data + 4, data_bytes - 4);
+ s_mark_end(s);
+ bytes = (int)(s->end - s->data);
+ send_channel_data(g_rdpsnd_chan_id, s->data, bytes);
+ free_stream(s);
+ return 0;
}
/*****************************************************************************/
static int APP_CC
-sound_process_training(struct stream* s, int size)
+sound_process_training(struct stream *s, int size)
{
- int time_diff;
+ int time_diff;
- print_got_here();
+ print_got_here();
- time_diff = g_time2() - g_training_sent_time;
- LOG(0, ("sound_process_training: round trip time %u", time_diff));
- return 0;
+ time_diff = g_time2() - g_training_sent_time;
+ LOG(0, ("sound_process_training: round trip time %u", time_diff));
+ return 0;
}
/*****************************************************************************/
static int APP_CC
-sound_process_wave_confirm(struct stream* s, int size)
+sound_process_wave_confirm(struct stream *s, int size)
{
- int wTimeStamp;
- int cConfirmedBlockNo;
+ int wTimeStamp;
+ int cConfirmedBlockNo;
- print_got_here();
+ print_got_here();
- in_uint16_le(s, wTimeStamp);
- in_uint8(s, cConfirmedBlockNo);
+ in_uint16_le(s, wTimeStamp);
+ in_uint8(s, cConfirmedBlockNo);
- LOG(10, ("sound_process_wave_confirm: wTimeStamp %d, cConfirmedBlockNo %d",
- wTimeStamp, cConfirmedBlockNo));
+ LOG(10, ("sound_process_wave_confirm: wTimeStamp %d, cConfirmedBlockNo %d",
+ wTimeStamp, cConfirmedBlockNo));
- return 0;
+ return 0;
}
/*****************************************************************************/
static int APP_CC
-process_pcm_message(int id, int size, struct stream* s)
+process_pcm_message(int id, int size, struct stream *s)
{
- print_got_here();
+ print_got_here();
- sound_send_wave_data(s->p, size);
- return 0;
+ sound_send_wave_data(s->p, size);
+ return 0;
}
/*****************************************************************************/
/* data coming in from audio source, eg pulse, alsa */
static int DEFAULT_CC
-sound_trans_audio_data_in(struct trans* trans)
+sound_trans_audio_data_in(struct trans *trans)
{
- struct stream *s;
- int id;
- int size;
- int error;
+ struct stream *s;
+ int id;
+ int size;
+ int error;
- if (trans == 0)
- {
- return 0;
- }
- if (trans != g_audio_c_trans)
- {
- return 1;
- }
- s = trans_get_in_s(trans);
- in_uint32_le(s, id);
- in_uint32_le(s, size);
- if ((id != 0) || (size > 32 * 1024 + 8) || (size < 1))
- {
- LOG(0, ("sound_trans_audio_data_in: bad message id %d size %d", id, size));
- return 1;
- }
- error = trans_force_read(trans, size - 8);
- if (error == 0)
- {
- /* here, the entire message block is read in, process it */
- error = process_pcm_message(id, size - 8, s);
- }
- return error;
+ if (trans == 0)
+ {
+ return 0;
+ }
+
+ if (trans != g_audio_c_trans)
+ {
+ return 1;
+ }
+
+ s = trans_get_in_s(trans);
+ in_uint32_le(s, id);
+ in_uint32_le(s, size);
+
+ if ((id != 0) || (size > 32 * 1024 + 8) || (size < 1))
+ {
+ LOG(0, ("sound_trans_audio_data_in: bad message id %d size %d", id, size));
+ return 1;
+ }
+
+ error = trans_force_read(trans, size - 8);
+
+ if (error == 0)
+ {
+ /* here, the entire message block is read in, process it */
+ error = process_pcm_message(id, size - 8, s);
+ }
+
+ return error;
}
/*****************************************************************************/
static int DEFAULT_CC
sound_trans_audio_conn_in(struct trans *trans, struct trans *new_trans)
{
- print_got_here();
-
- if (trans == 0)
- {
- return 1;
- }
- if (trans != g_audio_l_trans)
- {
- return 1;
- }
- if (g_audio_c_trans != 0) /* if already set, error */
- {
- return 1;
- }
- if (new_trans == 0)
- {
- return 1;
- }
- g_audio_c_trans = new_trans;
- g_audio_c_trans->trans_data_in = sound_trans_audio_data_in;
- g_audio_c_trans->header_size = 8;
- trans_delete(g_audio_l_trans);
- g_audio_l_trans = 0;
- return 0;
+ print_got_here();
+
+ if (trans == 0)
+ {
+ return 1;
+ }
+
+ if (trans != g_audio_l_trans)
+ {
+ return 1;
+ }
+
+ if (g_audio_c_trans != 0) /* if already set, error */
+ {
+ return 1;
+ }
+
+ if (new_trans == 0)
+ {
+ return 1;
+ }
+
+ g_audio_c_trans = new_trans;
+ g_audio_c_trans->trans_data_in = sound_trans_audio_data_in;
+ g_audio_c_trans->header_size = 8;
+ trans_delete(g_audio_l_trans);
+ g_audio_l_trans = 0;
+ return 0;
}
/*****************************************************************************/
int APP_CC
sound_init(void)
{
- char port[256];
- int error;
-
- print_got_here();
- LOG(0, ("sound_init:"));
-
- sound_send_server_formats();
- g_audio_l_trans = trans_create(2, 33 * 1024, 8192);
- g_snprintf(port, 255, "/tmp/xrdp_chansrv_audio_socket_%d", g_display_num);
- g_audio_l_trans->trans_conn_in = sound_trans_audio_conn_in;
- error = trans_listen(g_audio_l_trans, port);
- if (error != 0)
- {
- LOG(0, ("sound_init: trans_listen failed"));
- }
+ char port[256];
+ int error;
+
+ print_got_here();
+ LOG(0, ("sound_init:"));
+
+ sound_send_server_formats();
+ g_audio_l_trans = trans_create(2, 33 * 1024, 8192);
+ g_snprintf(port, 255, "/tmp/xrdp_chansrv_audio_socket_%d", g_display_num);
+ g_audio_l_trans->trans_conn_in = sound_trans_audio_conn_in;
+ error = trans_listen(g_audio_l_trans, port);
+
+ if (error != 0)
+ {
+ LOG(0, ("sound_init: trans_listen failed"));
+ }
#if defined(XRDP_SIMPLESOUND)
- /* start thread to read raw audio data from pulseaudio device */
- tc_thread_create(read_raw_audio_data, 0);
+ /* start thread to read raw audio data from pulseaudio device */
+ tc_thread_create(read_raw_audio_data, 0);
#endif
- return 0;
+ return 0;
}
/*****************************************************************************/
int APP_CC
sound_deinit(void)
{
- print_got_here();
+ print_got_here();
- if (g_audio_l_trans != 0)
- {
- trans_delete(g_audio_l_trans);
- g_audio_l_trans = 0;
- }
- if (g_audio_c_trans != 0)
- {
- trans_delete(g_audio_c_trans);
- g_audio_l_trans = 0;
- }
+ if (g_audio_l_trans != 0)
+ {
+ trans_delete(g_audio_l_trans);
+ g_audio_l_trans = 0;
+ }
- return 0;
+ if (g_audio_c_trans != 0)
+ {
+ trans_delete(g_audio_c_trans);
+ g_audio_l_trans = 0;
+ }
+
+ return 0;
}
/*****************************************************************************/
/* data in from client ( clinet -> xrdp -> chansrv ) */
int APP_CC
-sound_data_in(struct stream* s, int chan_id, int chan_flags, int length,
+sound_data_in(struct stream *s, int chan_id, int chan_flags, int length,
int total_length)
{
- int code;
- int size;
-
- print_got_here();
-
- in_uint8(s, code);
- in_uint8s(s, 1);
- in_uint16_le(s, size);
- switch (code)
- {
- case SNDC_WAVECONFIRM:
- sound_process_wave_confirm(s, size);
- break;
-
- case SNDC_TRAINING:
- sound_process_training(s, size);
- break;
-
- case SNDC_FORMATS:
- sound_process_formats(s, size);
- break;
-
- default:
- LOG(0, ("sound_data_in: unknown code %d size %d", code, size));
- break;
- }
- return 0;
+ int code;
+ int size;
+
+ print_got_here();
+
+ in_uint8(s, code);
+ in_uint8s(s, 1);
+ in_uint16_le(s, size);
+
+ switch (code)
+ {
+ case SNDC_WAVECONFIRM:
+ sound_process_wave_confirm(s, size);
+ break;
+
+ case SNDC_TRAINING:
+ sound_process_training(s, size);
+ break;
+
+ case SNDC_FORMATS:
+ sound_process_formats(s, size);
+ break;
+
+ default:
+ LOG(0, ("sound_data_in: unknown code %d size %d", code, size));
+ break;
+ }
+
+ return 0;
}
/*****************************************************************************/
int APP_CC
-sound_get_wait_objs(tbus* objs, int* count, int* timeout)
+sound_get_wait_objs(tbus *objs, int *count, int *timeout)
{
- int lcount;
-
- lcount = *count;
- if (g_audio_l_trans != 0)
- {
- objs[lcount] = g_audio_l_trans->sck;
- lcount++;
- }
- if (g_audio_c_trans != 0)
- {
- objs[lcount] = g_audio_c_trans->sck;
- lcount++;
- }
- *count = lcount;
- return 0;
+ int lcount;
+
+ lcount = *count;
+
+ if (g_audio_l_trans != 0)
+ {
+ objs[lcount] = g_audio_l_trans->sck;
+ lcount++;
+ }
+
+ if (g_audio_c_trans != 0)
+ {
+ objs[lcount] = g_audio_c_trans->sck;
+ lcount++;
+ }
+
+ *count = lcount;
+ return 0;
}
/*****************************************************************************/
int APP_CC
sound_check_wait_objs(void)
{
- if (g_audio_l_trans != 0)
- {
- trans_check_wait_objs(g_audio_l_trans);
- }
+ if (g_audio_l_trans != 0)
+ {
+ trans_check_wait_objs(g_audio_l_trans);
+ }
- if (g_audio_c_trans != 0)
- {
- trans_check_wait_objs(g_audio_c_trans);
- }
+ if (g_audio_c_trans != 0)
+ {
+ trans_check_wait_objs(g_audio_c_trans);
+ }
- return 0;
+ return 0;
}
#if defined(XRDP_SIMPLESOUND)
static int DEFAULT_CC
-sttrans_data_in(struct trans* self)
+sttrans_data_in(struct trans *self)
{
- LOG(0, ("sttrans_data_in:\n"));
- return 0;
+ LOG(0, ("sttrans_data_in:\n"));
+ return 0;
}
/**
@@ -451,103 +472,112 @@ sttrans_data_in(struct trans* self)
* to a unix domain socket on which trans server is listening
*/
-static void* DEFAULT_CC
-read_raw_audio_data(void* arg)
+static void *DEFAULT_CC
+read_raw_audio_data(void *arg)
{
- pa_sample_spec samp_spec;
- pa_simple* simple = NULL;
- uint32_t bytes_read;
- char* cptr;
- int i;
- int error;
- struct trans* strans;
- char path[256];
- struct stream* outs;
-
- strans = trans_create(TRANS_MODE_UNIX, 8192, 8192);
- if (strans == 0)
- {
- LOG(0, ("read_raw_audio_data: trans_create failed\n"));
- return 0;
- }
- strans->trans_data_in = sttrans_data_in;
- g_snprintf(path, 255, "/tmp/xrdp_chansrv_audio_socket_%d", g_display_num);
- if (trans_connect(strans, "", path, 100) != 0)
- {
- LOG(0, ("read_raw_audio_data: trans_connect failed\n"));
- trans_delete(strans);
- return 0;
- }
-
- /* setup audio format */
- samp_spec.format = PA_SAMPLE_S16LE;
- samp_spec.rate = 44100;
- samp_spec.channels = 2;
-
- /* if we are root, then for first 8 seconds connection to pulseaudo server
- fails; if we are non-root, then connection succeeds on first attempt;
- for now we have changed code to be non-root, but this may change in the
- future - so pretend we are root and try connecting to pulseaudio server
- for upto one minute */
- for (i = 0; i < 60; i++)
- {
- simple = pa_simple_new(NULL, "xrdp", PA_STREAM_RECORD, NULL,
- "record", &samp_spec, NULL, NULL, &error);
- if (simple)
+ pa_sample_spec samp_spec;
+ pa_simple *simple = NULL;
+ uint32_t bytes_read;
+ char *cptr;
+ int i;
+ int error;
+ struct trans *strans;
+ char path[256];
+ struct stream *outs;
+
+ strans = trans_create(TRANS_MODE_UNIX, 8192, 8192);
+
+ if (strans == 0)
{
- /* connected to pulseaudio server */
- LOG(0, ("read_raw_audio_data: connected to pulseaudio server\n"));
- break;
+ LOG(0, ("read_raw_audio_data: trans_create failed\n"));
+ return 0;
}
- LOG(0, ("read_raw_audio_data: ERROR creating PulseAudio async interface\n"));
- LOG(0, ("read_raw_audio_data: %s\n", pa_strerror(error)));
- g_sleep(1000);
- }
-
- if (i == 60)
- {
- /* failed to connect to audio server */
- trans_delete(strans);
- return NULL;
- }
-
- /* insert header just once */
- outs = trans_get_out_s(strans, 8192);
- out_uint32_le(outs, 0);
- out_uint32_le(outs, AUDIO_BUF_SIZE + 8);
- cptr = outs->p;
- out_uint8s(outs, AUDIO_BUF_SIZE);
- s_mark_end(outs);
-
- while (1)
- {
- /* read a block of raw audio data... */
- g_memset(cptr, 0, 4);
- bytes_read = pa_simple_read(simple, cptr, AUDIO_BUF_SIZE, &error);
- if (bytes_read < 0)
+
+ strans->trans_data_in = sttrans_data_in;
+ g_snprintf(path, 255, "/tmp/xrdp_chansrv_audio_socket_%d", g_display_num);
+
+ if (trans_connect(strans, "", path, 100) != 0)
{
- LOG(0, ("read_raw_audio_data: ERROR reading from pulseaudio stream\n"));
- LOG(0, ("read_raw_audio_data: %s\n", pa_strerror(error)));
- break;
+ LOG(0, ("read_raw_audio_data: trans_connect failed\n"));
+ trans_delete(strans);
+ return 0;
}
- /* bug workaround:
- even when there is no audio data, pulseaudio is returning without
- errors but the data itself is zero; we use this zero data to
- determine that there is no audio data present */
- if (*cptr == 0 && *(cptr + 1) == 0 && *(cptr + 2) == 0 && *(cptr + 3) == 0)
+
+ /* setup audio format */
+ samp_spec.format = PA_SAMPLE_S16LE;
+ samp_spec.rate = 44100;
+ samp_spec.channels = 2;
+
+ /* if we are root, then for first 8 seconds connection to pulseaudo server
+ fails; if we are non-root, then connection succeeds on first attempt;
+ for now we have changed code to be non-root, but this may change in the
+ future - so pretend we are root and try connecting to pulseaudio server
+ for upto one minute */
+ for (i = 0; i < 60; i++)
{
- g_sleep(10);
- continue;
+ simple = pa_simple_new(NULL, "xrdp", PA_STREAM_RECORD, NULL,
+ "record", &samp_spec, NULL, NULL, &error);
+
+ if (simple)
+ {
+ /* connected to pulseaudio server */
+ LOG(0, ("read_raw_audio_data: connected to pulseaudio server\n"));
+ break;
+ }
+
+ LOG(0, ("read_raw_audio_data: ERROR creating PulseAudio async interface\n"));
+ LOG(0, ("read_raw_audio_data: %s\n", pa_strerror(error)));
+ g_sleep(1000);
}
- if (trans_force_write_s(strans, outs) != 0)
+
+ if (i == 60)
{
- LOG(0, ("read_raw_audio_data: ERROR writing audio data to server\n"));
- break;
+ /* failed to connect to audio server */
+ trans_delete(strans);
+ return NULL;
}
- }
- pa_simple_free(simple);
- trans_delete(strans);
- return NULL;
+
+ /* insert header just once */
+ outs = trans_get_out_s(strans, 8192);
+ out_uint32_le(outs, 0);
+ out_uint32_le(outs, AUDIO_BUF_SIZE + 8);
+ cptr = outs->p;
+ out_uint8s(outs, AUDIO_BUF_SIZE);
+ s_mark_end(outs);
+
+ while (1)
+ {
+ /* read a block of raw audio data... */
+ g_memset(cptr, 0, 4);
+ bytes_read = pa_simple_read(simple, cptr, AUDIO_BUF_SIZE, &error);
+
+ if (bytes_read < 0)
+ {
+ LOG(0, ("read_raw_audio_data: ERROR reading from pulseaudio stream\n"));
+ LOG(0, ("read_raw_audio_data: %s\n", pa_strerror(error)));
+ break;
+ }
+
+ /* bug workaround:
+ even when there is no audio data, pulseaudio is returning without
+ errors but the data itself is zero; we use this zero data to
+ determine that there is no audio data present */
+ if (*cptr == 0 && *(cptr + 1) == 0 && *(cptr + 2) == 0 && *(cptr + 3) == 0)
+ {
+ g_sleep(10);
+ continue;
+ }
+
+ if (trans_force_write_s(strans, outs) != 0)
+ {
+ LOG(0, ("read_raw_audio_data: ERROR writing audio data to server\n"));
+ break;
+ }
+ }
+
+ pa_simple_free(simple);
+ trans_delete(strans);
+ return NULL;
}
#endif