summaryrefslogtreecommitdiffstats
path: root/sesman/chansrv/sound.c
diff options
context:
space:
mode:
authorJay Sorg <jay.sorg@gmail.com>2013-05-12 18:03:32 -0700
committerJay Sorg <jay.sorg@gmail.com>2013-05-12 18:03:32 -0700
commit21df0406d7e13bf85b5c5ca99f89edb2b9a55f15 (patch)
treeab6d925f21ea4f637ba40a96f0f9dd38c13f7f11 /sesman/chansrv/sound.c
parent8c9fe9452f822db29517c808e3607c19ca7847ba (diff)
downloadxrdp-proprietary-21df0406d7e13bf85b5c5ca99f89edb2b9a55f15.tar.gz
xrdp-proprietary-21df0406d7e13bf85b5c5ca99f89edb2b9a55f15.zip
pulse work and cleanup
Diffstat (limited to 'sesman/chansrv/sound.c')
-rw-r--r--sesman/chansrv/sound.c217
1 files changed, 172 insertions, 45 deletions
diff --git a/sesman/chansrv/sound.c b/sesman/chansrv/sound.c
index a4a94437..55f6f88d 100644
--- a/sesman/chansrv/sound.c
+++ b/sesman/chansrv/sound.c
@@ -23,43 +23,95 @@
extern int g_rdpsnd_chan_id; /* in chansrv.c */
extern int g_display_num; /* in chansrv.c */
-static struct trans *g_audio_l_trans = 0; // listener
-static struct trans *g_audio_c_trans = 0; // connection
+static struct trans *g_audio_l_trans = 0; /* listener */
+static struct trans *g_audio_c_trans = 0; /* connection */
static int g_training_sent_time = 0;
static int g_cBlockNo = 0;
#define BBUF_SIZE (1024 * 8)
char g_buffer[BBUF_SIZE];
int g_buf_index = 0;
+int g_sent_time[256];
#if defined(XRDP_SIMPLESOUND)
static void *DEFAULT_CC
read_raw_audio_data(void *arg);
#endif
+#define CHANSRV_PORT_STR "/tmp/.xrdp/xrdp_chansrv_audio_socket_%d"
+
+struct xr_wave_format_ex
+{
+ int wFormatTag;
+ int nChannels;
+ int nSamplesPerSec;
+ int nAvgBytesPerSec;
+ int nBlockAlign;
+ int wBitsPerSample;
+ int cbSize;
+ char *data;
+};
+
+static char g_pmc_22050_data[] = { 0 };
+static struct xr_wave_format_ex g_pmc_22050 =
+{
+ 1, /* wFormatTag - WAVE_FORMAT_PCM */
+ 2, /* num of channels */
+ 22050, /* samples per sec */
+ 88200, /* avg bytes per sec */
+ 4, /* block align */
+ 16, /* bits per sample */
+ 0, /* data size */
+ g_pmc_22050_data /* data */
+};
+
+static char g_pmc_44100_data[] = { 0 };
+static struct xr_wave_format_ex g_pmc_44100 =
+{
+ 1, /* wFormatTag - WAVE_FORMAT_PCM */
+ 2, /* num of channels */
+ 44100, /* samples per sec */
+ 176400, /* avg bytes per sec */
+ 4, /* block align */
+ 16, /* bits per sample */
+ 0, /* data size */
+ g_pmc_44100_data /* data */
+};
+
+#define NUM_BUILT_IN 2
+static struct xr_wave_format_ex *g_wave_formats[NUM_BUILT_IN] =
+{
+ &g_pmc_44100,
+ &g_pmc_22050
+};
+
+/* index into list from client */
+static int g_current_client_format_index = 0;
+/* index into list from server */
+static int g_current_server_format_index = 0;
+
/*****************************************************************************/
static int APP_CC
sound_send_server_formats(void)
{
struct stream *s;
int bytes;
+ int index;
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 */
+ 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, NUM_BUILT_IN); /* wNumberOfFormats */
+ out_uint8(s, g_cBlockNo); /* cLastBlockConfirmed */
+ out_uint16_le(s, 2); /* wVersion */
+ out_uint8(s, 0); /* bPad */
/* sndFormats */
/*
@@ -80,13 +132,21 @@ sound_send_server_formats(void)
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
+ for (index = 0; index < NUM_BUILT_IN; index++)
+ {
+ out_uint16_le(s, g_wave_formats[index]->wFormatTag);
+ out_uint16_le(s, g_wave_formats[index]->nChannels);
+ out_uint32_le(s, g_wave_formats[index]->nSamplesPerSec);
+ out_uint32_le(s, g_wave_formats[index]->nAvgBytesPerSec);
+ out_uint16_le(s, g_wave_formats[index]->nBlockAlign);
+ out_uint16_le(s, g_wave_formats[index]->wBitsPerSample);
+ bytes = g_wave_formats[index]->cbSize;
+ out_uint16_le(s, bytes);
+ if (bytes > 0)
+ {
+ out_uint8p(s, g_wave_formats[index]->data, bytes);
+ }
+ }
s_mark_end(s);
bytes = (int)((s->end - s->data) - 4);
@@ -107,8 +167,6 @@ sound_send_training(void)
int time;
char *size_ptr;
- print_got_here();
-
make_stream(s);
init_stream(s, 8182);
out_uint16_le(s, SNDC_TRAINING);
@@ -130,6 +188,52 @@ sound_send_training(void)
}
/*****************************************************************************/
+static int APP_CC
+sound_process_format(int aindex, int wFormatTag, int nChannels,
+ int nSamplesPerSec, int nAvgBytesPerSec,
+ int nBlockAlign, int wBitsPerSample,
+ int cbSize, char *data)
+{
+ int lindex;
+
+ LOG(0, ("sound_process_format:"));
+ LOG(0, (" wFormatTag %d", wFormatTag));
+ LOG(0, (" nChannels %d", nChannels));
+ LOG(0, (" nSamplesPerSec %d", nSamplesPerSec));
+ LOG(0, (" nAvgBytesPerSec %d", nAvgBytesPerSec));
+ LOG(0, (" nBlockAlign %d", nBlockAlign));
+ LOG(0, (" wBitsPerSample %d", wBitsPerSample));
+ LOG(0, (" cbSize %d", cbSize));
+ g_hexdump(data, cbSize);
+ if (wFormatTag == g_pmc_44100.wFormatTag &&
+ nChannels == g_pmc_44100.nChannels &&
+ nSamplesPerSec == g_pmc_44100.nSamplesPerSec &&
+ nAvgBytesPerSec == g_pmc_44100.nAvgBytesPerSec &&
+ nBlockAlign == g_pmc_44100.nBlockAlign &&
+ wBitsPerSample == g_pmc_44100.wBitsPerSample)
+ {
+ g_current_client_format_index = aindex;
+ g_current_server_format_index = 0;
+ }
+#if 0
+ for (lindex = 0; lindex < NUM_BUILT_IN; lindex++)
+ {
+ if (wFormatTag == g_wave_formats[lindex]->wFormatTag &&
+ nChannels == g_wave_formats[lindex]->nChannels &&
+ nSamplesPerSec == g_wave_formats[lindex]->nSamplesPerSec &&
+ nAvgBytesPerSec == g_wave_formats[lindex]->nAvgBytesPerSec &&
+ nBlockAlign == g_wave_formats[lindex]->nBlockAlign &&
+ wBitsPerSample == g_wave_formats[lindex]->wBitsPerSample)
+ {
+ g_current_client_format_index = aindex;
+ g_current_server_format_index = lindex;
+ }
+ }
+#endif
+ return 0;
+}
+
+/*****************************************************************************/
/*
0000 07 02 26 00 03 00 80 00 ff ff ff ff 00 00 00 00 ..&.............
0010 00 00 01 00 00 02 00 00 01 00 02 00 44 ac 00 00 ............D...
@@ -140,8 +244,15 @@ static int APP_CC
sound_process_formats(struct stream *s, int size)
{
int num_formats;
-
- print_got_here();
+ int index;
+ int wFormatTag;
+ int nChannels;
+ int nSamplesPerSec;
+ int nAvgBytesPerSec;
+ int nBlockAlign;
+ int wBitsPerSample;
+ int cbSize;
+ char *data;
LOG(0, ("sound_process_formats:"));
@@ -152,9 +263,24 @@ sound_process_formats(struct stream *s, int size)
in_uint8s(s, 14);
in_uint16_le(s, num_formats);
+ in_uint8s(s, 4);
if (num_formats > 0)
{
+ for (index = 0; index < num_formats; index++)
+ {
+ in_uint16_le(s, wFormatTag);
+ in_uint16_le(s, nChannels);
+ in_uint32_le(s, nSamplesPerSec);
+ in_uint32_le(s, nAvgBytesPerSec);
+ in_uint16_le(s, nBlockAlign);
+ in_uint16_le(s, wBitsPerSample);
+ in_uint16_le(s, cbSize);
+ in_uint8p(s, data, cbSize);
+ sound_process_format(index, wFormatTag, nChannels, nSamplesPerSec,
+ nAvgBytesPerSec, nBlockAlign, wBitsPerSample,
+ cbSize, data);
+ }
sound_send_training();
}
@@ -162,6 +288,7 @@ sound_process_formats(struct stream *s, int size)
}
/*****************************************************************************/
+/* send wave message to client */
static int
sound_send_wave_data_chunk(char *data, int data_bytes)
{
@@ -170,7 +297,7 @@ sound_send_wave_data_chunk(char *data, int data_bytes)
int time;
char *size_ptr;
- print_got_here();
+ LOG(10, ("sound_send_wave_data_chunk: data_bytes %d", data_bytes));
if ((data_bytes < 4) || (data_bytes > 128 * 1024))
{
@@ -188,9 +315,10 @@ sound_send_wave_data_chunk(char *data, int data_bytes)
out_uint16_le(s, 0); /* size, set later */
time = g_time2();
out_uint16_le(s, time);
- out_uint16_le(s, 0); /* wFormatNo */
+ out_uint16_le(s, g_current_client_format_index); /* wFormatNo */
g_cBlockNo++;
out_uint8(s, g_cBlockNo);
+ g_sent_time[g_cBlockNo & 0xff] = time;
LOG(10, ("sound_send_wave_data_chunk: sending time %d, g_cBlockNo %d",
time & 0xffff, g_cBlockNo & 0xff));
@@ -220,6 +348,7 @@ sound_send_wave_data_chunk(char *data, int data_bytes)
}
/*****************************************************************************/
+/* send wave message to client, buffer first */
static int
sound_send_wave_data(char *data, int data_bytes)
{
@@ -252,6 +381,7 @@ sound_send_wave_data(char *data, int data_bytes)
}
/*****************************************************************************/
+/* send close message to client */
static int
sound_send_close(void)
{
@@ -260,7 +390,6 @@ sound_send_close(void)
char *size_ptr;
LOG(10, ("sound_send_close:"));
- print_got_here();
/* send any left over data */
sound_send_wave_data_chunk(g_buffer, g_buf_index);
@@ -282,42 +411,45 @@ sound_send_close(void)
}
/*****************************************************************************/
+/* from client */
static int APP_CC
sound_process_training(struct stream *s, int size)
{
int time_diff;
- print_got_here();
-
time_diff = g_time2() - g_training_sent_time;
LOG(0, ("sound_process_training: round trip time %u", time_diff));
return 0;
}
/*****************************************************************************/
+/* from client */
static int APP_CC
sound_process_wave_confirm(struct stream *s, int size)
{
int wTimeStamp;
int cConfirmedBlockNo;
+ int time;
+ int time_diff;
- print_got_here();
-
+ time = g_time2();
in_uint16_le(s, wTimeStamp);
in_uint8(s, cConfirmedBlockNo);
+ time_diff = time - g_sent_time[cConfirmedBlockNo];
- LOG(10, ("sound_process_wave_confirm: wTimeStamp %d, cConfirmedBlockNo %d",
- wTimeStamp, cConfirmedBlockNo));
+ LOG(10, ("sound_process_wave_confirm: wTimeStamp %d, "
+ "cConfirmedBlockNo %d time diff %d",
+ wTimeStamp, cConfirmedBlockNo, time_diff));
return 0;
}
/*****************************************************************************/
+/* process message in from the audio source, eg pulse, alsa
+ on it's way to the client */
static int APP_CC
process_pcm_message(int id, int size, struct stream *s)
{
- print_got_here();
-
switch (id)
{
case 0:
@@ -334,7 +466,7 @@ process_pcm_message(int id, int size, struct stream *s)
}
/*****************************************************************************/
-/* data coming in from audio source, eg pulse, alsa */
+/* data in from audio source, eg pulse, alsa */
static int DEFAULT_CC
sound_trans_audio_data_in(struct trans *trans)
{
@@ -376,11 +508,11 @@ sound_trans_audio_data_in(struct trans *trans)
}
/*****************************************************************************/
+/* this is a connection in on the unix domain socket */
static int DEFAULT_CC
sound_trans_audio_conn_in(struct trans *trans, struct trans *new_trans)
{
LOG(0, ("sound_trans_audio_conn_in:"));
- print_got_here();
if (trans == 0)
{
@@ -410,8 +542,6 @@ sound_trans_audio_conn_in(struct trans *trans, struct trans *new_trans)
return 0;
}
-#define CHANSRV_PORT_STR "/tmp/.xrdp/xrdp_chansrv_audio_socket_%d"
-
/*****************************************************************************/
int APP_CC
sound_init(void)
@@ -419,7 +549,6 @@ sound_init(void)
char port[256];
int error;
- print_got_here();
LOG(0, ("sound_init:"));
sound_send_server_formats();
@@ -447,8 +576,6 @@ sound_init(void)
int APP_CC
sound_deinit(void)
{
- print_got_here();
-
if (g_audio_l_trans != 0)
{
trans_delete(g_audio_l_trans);
@@ -465,7 +592,7 @@ sound_deinit(void)
}
/*****************************************************************************/
-/* data in from client ( clinet -> xrdp -> chansrv ) */
+/* data in from client ( client -> xrdp -> chansrv ) */
int APP_CC
sound_data_in(struct stream *s, int chan_id, int chan_flags, int length,
int total_length)
@@ -473,8 +600,6 @@ sound_data_in(struct stream *s, int chan_id, int chan_flags, int length,
int code;
int size;
- print_got_here();
-
in_uint8(s, code);
in_uint8s(s, 1);
in_uint16_le(s, size);
@@ -544,6 +669,8 @@ sound_check_wait_objs(void)
#if defined(XRDP_SIMPLESOUND)
+#define AUDIO_BUF_SIZE 2048
+
static int DEFAULT_CC
sttrans_data_in(struct trans *self)
{