Skip to content

Commit

Permalink
Add latency and buffer length options for libao
Browse files Browse the repository at this point in the history
  • Loading branch information
mikebrady committed Oct 31, 2015
1 parent c960142 commit 026b970
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 5 deletions.
33 changes: 30 additions & 3 deletions audio_ao.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,44 @@ static void help(void) {
}

static int init(int argc, char **argv) {
const char *str;
int value;
ao_initialize();
int driver = ao_default_driver_id();
ao_option *ao_opts = NULL;

config.audio_backend_buffer_desired_length = 44100; // one second.
config.audio_backend_latency_offset = 0;

// get settings from settings file first, allow them to be overridden by command line options

if (config.cfg != NULL) {
/* Get the desired buffer size setting. */
if (config_lookup_int(config.cfg, "ao.audio_backend_buffer_desired_length_software", &value)) {
if ((value < 0) || (value > 66150))
die("Invalid a0 audio backend buffer desired length \"%d\". It should be between 0 and "
"66150, default is 44100",
value);
else {
config.audio_backend_buffer_desired_length = value;
}
}

/* Get the latency offset. */
if (config_lookup_int(config.cfg, "ao.audio_backend_latency_offset", &value)) {
if ((value < -66150) || (value > 66150))
die("Invalid ao audio backend buffer latency offset \"%d\". It should be between -66150 and +66150, default is 0",
value);
else
config.audio_backend_latency_offset = value;
}
}


optind = 1; // optind=0 is equivalent to optind=1 plus special behaviour
argv--; // so we shift the arguments to satisfy getopt()
argc++;

config.audio_backend_buffer_desired_length = 44100; // one second.
config.audio_backend_latency_offset = 0;

// some platforms apparently require optreset = 1; - which?
int opt;
char *mid;
Expand Down
31 changes: 29 additions & 2 deletions man/shairport-sync.7.xml
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@
You can offset the time of initial audio output relative to its nominal time using this setting.
For example to send an audio stream to stdout 100 milliseconds before it is due to be played, set this to -4410. Default setting is 0.</optdesc>
</option>

<option>
<p><opt>audio_backend_buffer_desired_length=</opt><arg>buffer_length_in_frames</arg><opt>;</opt></p>
<optdesc>
Expand All @@ -306,7 +306,34 @@
shairport-sync performs no stuffing or interpolation when writing to stdout. Default setting is 44,100 frames.
</optdesc>
</option>


<option><p><opt>"AO" SETTINGS</opt></p></option>
<p>These settings are for the AO backend, used for the libao audio library.</p>
<p>There are two settings affecting timing. The <arg>audio_backend_latency_offset</arg> affects precisely when the first audio packet is sent
and the <arg>audio_backend_buffer_desired_length</arg> setting affects the nominal output buffer size.</p>
<p>These are the settings available within the <opt>ao</opt> group:</p>


<option>
<p><opt>audio_backend_latency_offset=</opt><arg>offset_in_frames</arg><opt>;</opt></p>
<optdesc>
Packets of audio frames are written to the libao system synchronously -- that is, they are written at exactly the time they should be played.
You can offset the time of initial audio output relative to its nominal time using this setting.
For example to send an audio stream to stdout 100 milliseconds before it is due to be played, set this to -4410. Default setting is 0.</optdesc>
</option>

<option>
<p><opt>audio_backend_buffer_desired_length=</opt><arg>buffer_length_in_frames</arg><opt>;</opt></p>
<optdesc>
Use this setting, in frames, to set the size of the output buffer. It works by determining how soon the second and subsequent packets of
audio frames are sent to to the libao system.
For example, if you send the first packet of audio exactly when it is due and, using a <arg>audio_backend_buffer_desired_length</arg> setting of 44100,
send subsequent packets of audio a second before they are due to be played, they will be buffered in the stdout reader's buffer, giving it a nominal buffer size of 44,100 frames.
Note that if the libao system consumes audio packets faster or slower than they are supplied, the buffer will eventually empty or overflow --
shairport-sync performs no stuffing or interpolation when writing to libao. Default setting is 44,100 frames.
</optdesc>
</option>

<option><p><opt>"METADATA" SETTINGS</opt></p></option>
<p>shairport-sync can process metadata provided by the source, such as Track Number, Album Name, cover art, etc. and can provide additional metadata such as volume level,
pause/resume, etc. It sends the metadata to a pipe, by default <file>/tmp/shairport-sync-metadata</file>.
Expand Down
7 changes: 7 additions & 0 deletions scripts/shairport-sync.conf
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,13 @@ stdout =
// audio_backend_buffer_desired_length = 44100; // Having started to send audio at the right time, send all subsequent audio this many frames ahead of time, creating a buffer this size.
};

// These are parameters for the "ao" audio back end. No interpolation is done.
ao =
{
// audio_backend_latency_offset = 0; // Set this offset to compensate for a fixed delay in the audio back end. E.g. if the output device delays by 100 ms, set this to -4410.
// audio_backend_buffer_desired_length = 44100; // Having started to send audio at the right time, send all subsequent audio this many frames ahead of time, creating a buffer this size.
};

// The following static latency settings are deprecated -- do not use them for new installations. Shairport Sync now sets latencies automatically.
// To compensate for a delay in the output device please use the alsa/stdio/pipe "audio_backend_latency_offset" setting.

Expand Down

0 comments on commit 026b970

Please sign in to comment.