Add constants. Tweak latency.

This commit is contained in:
Michael Jumper 2013-08-09 18:21:32 -07:00
parent fa3dcea44b
commit 5df7f34ee8
4 changed files with 65 additions and 11 deletions

View File

@ -69,7 +69,8 @@ const char* GUAC_CLIENT_ARGS[] = {
#endif #endif
#ifdef ENABLE_PULSE #ifdef ENABLE_PULSE
"disable-audio", "enable-audio",
"audio-servername",
#endif #endif
NULL NULL
@ -91,7 +92,8 @@ enum VNC_ARGS_IDX {
#endif #endif
#ifdef ENABLE_PULSE #ifdef ENABLE_PULSE
IDX_DISABLE_AUDIO, IDX_ENABLE_AUDIO,
IDX_AUDIO_SERVERNAME,
#endif #endif
VNC_ARGS_COUNT VNC_ARGS_COUNT
@ -161,13 +163,21 @@ int guac_client_init(guac_client* client, int argc, char** argv) {
guac_vnc_set_pixel_format(rfb_client, atoi(argv[IDX_COLOR_DEPTH])); guac_vnc_set_pixel_format(rfb_client, atoi(argv[IDX_COLOR_DEPTH]));
#ifdef ENABLE_PULSE #ifdef ENABLE_PULSE
guac_client_data->audio_enabled = (strcmp(argv[IDX_DISABLE_AUDIO], "true") != 0); guac_client_data->audio_enabled =
(strcmp(argv[IDX_ENABLE_AUDIO], "true") == 0);
/* If an encoding is available, load an audio stream */ /* If an encoding is available, load an audio stream */
if (guac_client_data->audio_enabled) { if (guac_client_data->audio_enabled) {
guac_client_data->audio = guac_audio_stream_alloc(client, NULL); guac_client_data->audio = guac_audio_stream_alloc(client, NULL);
/* Load servername if specified */
if (argv[IDX_AUDIO_SERVERNAME][0] != '\0')
guac_client_data->pa_servername =
strdup(argv[IDX_AUDIO_SERVERNAME]);
else
guac_client_data->pa_servername = NULL;
/* If successful, init audio system */ /* If successful, init audio system */
if (guac_client_data->audio != NULL) { if (guac_client_data->audio != NULL) {

View File

@ -68,6 +68,11 @@ typedef struct vnc_guac_client_data {
*/ */
guac_audio_stream* audio; guac_audio_stream* audio;
/**
* The name of the PulseAudio server to connect to.
*/
char* pa_servername;
/** /**
* PulseAudio event loop. * PulseAudio event loop.
*/ */

View File

@ -41,6 +41,7 @@
#include <pulse/pulseaudio.h> #include <pulse/pulseaudio.h>
#include "client.h" #include "client.h"
#include "pulse.h"
static void __stream_read_callback(pa_stream* stream, size_t length, static void __stream_read_callback(pa_stream* stream, size_t length,
void* data) { void* data) {
@ -58,9 +59,12 @@ static void __stream_read_callback(pa_stream* stream, size_t length,
guac_audio_stream_write_pcm(audio, buffer, length); guac_audio_stream_write_pcm(audio, buffer, length);
/* Flush occasionally */ /* Flush occasionally */
if (audio->pcm_bytes_written > 10000) { if (audio->pcm_bytes_written > GUAC_VNC_PCM_WRITE_RATE) {
guac_audio_stream_end(audio); guac_audio_stream_end(audio);
guac_audio_stream_begin(client_data->audio, 44100, 2, 16); guac_audio_stream_begin(client_data->audio,
GUAC_VNC_AUDIO_RATE,
GUAC_VNC_AUDIO_CHANNELS,
GUAC_VNC_AUDIO_BPS);
} }
/* Advance buffer */ /* Advance buffer */
@ -110,6 +114,7 @@ static void __context_get_sink_info_callback(pa_context* context,
guac_client* client = (guac_client*) data; guac_client* client = (guac_client*) data;
pa_stream* stream; pa_stream* stream;
pa_sample_spec spec; pa_sample_spec spec;
pa_buffer_attr attr;
/* Stop if end of list reached */ /* Stop if end of list reached */
if (is_last) if (is_last)
@ -120,8 +125,11 @@ static void __context_get_sink_info_callback(pa_context* context,
/* Set format */ /* Set format */
spec.format = PA_SAMPLE_S16LE; spec.format = PA_SAMPLE_S16LE;
spec.rate = 44100; spec.rate = GUAC_VNC_AUDIO_RATE;
spec.channels = 2; spec.channels = GUAC_VNC_AUDIO_CHANNELS;
attr.maxlength = GUAC_VNC_AUDIO_BUFFER_SIZE;
attr.fragsize = attr.maxlength;
/* Create stream */ /* Create stream */
stream = pa_stream_new(context, "Guacamole Audio", &spec, NULL); stream = pa_stream_new(context, "Guacamole Audio", &spec, NULL);
@ -131,8 +139,9 @@ static void __context_get_sink_info_callback(pa_context* context,
pa_stream_set_read_callback(stream, __stream_read_callback, client); pa_stream_set_read_callback(stream, __stream_read_callback, client);
/* Start stream */ /* Start stream */
pa_stream_connect_record(stream, info->monitor_source_name, NULL, pa_stream_connect_record(stream, info->monitor_source_name, &attr,
PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND); PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND
| PA_STREAM_ADJUST_LATENCY);
} }
@ -211,7 +220,10 @@ void guac_pa_start_stream(guac_client* client) {
pa_context* context; pa_context* context;
guac_client_log_info(client, "Starting audio stream"); guac_client_log_info(client, "Starting audio stream");
guac_audio_stream_begin(client_data->audio, 44100, 2, 16); guac_audio_stream_begin(client_data->audio,
GUAC_VNC_AUDIO_RATE,
GUAC_VNC_AUDIO_CHANNELS,
GUAC_VNC_AUDIO_BPS);
/* Init main loop */ /* Init main loop */
client_data->pa_mainloop = pa_threaded_mainloop_new(); client_data->pa_mainloop = pa_threaded_mainloop_new();
@ -223,7 +235,8 @@ void guac_pa_start_stream(guac_client* client) {
/* Set up context */ /* Set up context */
pa_context_set_state_callback(context, __context_state_callback, client); pa_context_set_state_callback(context, __context_state_callback, client);
pa_context_connect(context, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL); pa_context_connect(context, client_data->pa_servername,
PA_CONTEXT_NOAUTOSPAWN, NULL);
/* Start loop */ /* Start loop */
pa_threaded_mainloop_start(client_data->pa_mainloop); pa_threaded_mainloop_start(client_data->pa_mainloop);

View File

@ -38,6 +38,32 @@
#ifndef __GUAC_VNC_PULSE_H #ifndef __GUAC_VNC_PULSE_H
#define __GUAC_VNC_PULSE_H #define __GUAC_VNC_PULSE_H
/**
* The number of bytes to request for the PulseAudio buffers.
*/
#define GUAC_VNC_AUDIO_BUFFER_SIZE 10240
/**
* The minimum number of PCM bytes to wait for before flushing an audio
* packet.
*/
#define GUAC_VNC_PCM_WRITE_RATE 10240
/**
* Rate of audio to stream, in Hz.
*/
#define GUAC_VNC_AUDIO_RATE 44100
/**
* The number of channels to stream.
*/
#define GUAC_VNC_AUDIO_CHANNELS 2
/**
* The number of bits per sample.
*/
#define GUAC_VNC_AUDIO_BPS 16
/** /**
* Starts streaming audio from PulseAudio to the given Guacamole client. * Starts streaming audio from PulseAudio to the given Guacamole client.
* *