summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--audio_alsa.c34
-rw-r--r--audio_ao.c31
-rw-r--r--audio_pipe.c34
-rw-r--r--audio_stdout.c31
-rw-r--r--common.h12
-rw-r--r--player.c37
-rw-r--r--scripts/shairport-sync.conf26
-rw-r--r--shairport.c31
8 files changed, 128 insertions, 108 deletions
diff --git a/audio_alsa.c b/audio_alsa.c
index db864f6..c736e20 100644
--- a/audio_alsa.c
+++ b/audio_alsa.c
@@ -136,40 +136,40 @@ static int init(int argc, char **argv) {
// debug(2,"audio_alsa init called.");
const char *str;
int value;
+ double dvalue;
set_period_size_request = 0;
set_buffer_size_request = 0;
- config.audio_backend_latency_offset = 0; // this is the default for ALSA
- config.audio_backend_buffer_desired_length =
- 6615; // default for alsa with a software mixer
+ config.audio_backend_latency_offset = 0;
+ config.audio_backend_buffer_desired_length = 0.15;
// 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,
- "alsa.audio_backend_buffer_desired_length", &value)) {
- if ((value < 0) || (value > 66150))
- die("Invalid alsa audio backend buffer desired length \"%d\". It "
+ if (config_lookup_float(config.cfg,
+ "alsa.audio_backend_buffer_desired_length", &dvalue)) {
+ if ((dvalue < 0) || (value > 1.5))
+ die("Invalid alsa audio backend buffer desired length \"%f\". It "
"should be between 0 and "
- "66150, default is 6615",
- value);
+ "1.5, default is 0.15 seconds",
+ dvalue);
else {
- config.audio_backend_buffer_desired_length = value;
+ config.audio_backend_buffer_desired_length = dvalue;
}
}
/* Get the latency offset. */
- if (config_lookup_int(config.cfg, "alsa.audio_backend_latency_offset",
- &value)) {
- if ((value < -66150) || (value > 66150))
- die("Invalid alsa audio backend buffer latency offset \"%d\". It "
- "should be between -66150 and +66150, default is 0",
- value);
+ if (config_lookup_float(config.cfg, "alsa.audio_backend_latency_offset",
+ &dvalue)) {
+ if ((dvalue < -1.0) || (value > 1.5))
+ die("Invalid alsa audio backend buffer latency offset \"%f\". It "
+ "should be between -1.0 and +1.5, default is 0 seconds",
+ dvalue);
else
- config.audio_backend_latency_offset = value;
+ config.audio_backend_latency_offset = dvalue;
}
/* Get the Output Device Name. */
diff --git a/audio_ao.c b/audio_ao.c
index b6a09a0..51cf333 100644
--- a/audio_ao.c
+++ b/audio_ao.c
@@ -47,34 +47,37 @@ static int init(int argc, char **argv) {
int driver = ao_default_driver_id();
ao_option *ao_opts = NULL;
- config.audio_backend_buffer_desired_length = 44100; // one second.
+ config.audio_backend_buffer_desired_length = 1.0;
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", &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);
+ if (config_lookup_float(config.cfg,
+ "ao.audio_backend_buffer_desired_length", &dvalue)) {
+ if ((dvalue < 0) || (value > 1.5))
+ die("Invalid ao audio backend buffer desired length \"%f\". It "
+ "should be between 0 and "
+ "1.5, default is 1.0 second",
+ dvalue);
else {
- config.audio_backend_buffer_desired_length = value;
+ config.audio_backend_buffer_desired_length = dvalue;
}
}
-
+
/* 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);
+ if (config_lookup_float(config.cfg, "ao.audio_backend_latency_offset",
+ &dvalue)) {
+ if ((dvalue < -1.0) || (value > 1.5))
+ die("Invalid ao audio backend buffer latency offset \"%f\". It "
+ "should be between -1.0 and +1.5, default is 0 seconds",
+ dvalue);
else
- config.audio_backend_latency_offset = value;
+ config.audio_backend_latency_offset = dvalue;
}
}
-
optind = 1; // optind=0 is equivalent to optind=1 plus special behaviour
argv--; // so we shift the arguments to satisfy getopt()
argc++;
diff --git a/audio_pipe.c b/audio_pipe.c
index dfde2a9..155e9b0 100644
--- a/audio_pipe.c
+++ b/audio_pipe.c
@@ -69,8 +69,9 @@ static int init(int argc, char **argv) {
debug(1, "pipe init");
const char *str;
int value;
-
- config.audio_backend_buffer_desired_length = 44100; // one second.
+ double dvalue;
+
+ config.audio_backend_buffer_desired_length = 1.0;
config.audio_backend_latency_offset = 0;
if (config.cfg != NULL) {
@@ -84,24 +85,29 @@ static int init(int argc, char **argv) {
die("Can't use \"pipe\" backend for STDOUT. Use the \"stdout\" backend instead.");
/* Get the desired buffer size setting. */
- if (config_lookup_int(config.cfg, "pipe.audio_backend_buffer_desired_length", &value)) {
- if ((value < 0) || (value > 132300))
- die("Invalid pipe audio backend buffer desired length \"%d\". It should be between 0 and 132300, default is 44100",
- value);
- else
- config.audio_backend_buffer_desired_length = value;
+ if (config_lookup_float(config.cfg,
+ "pipe.audio_backend_buffer_desired_length", &dvalue)) {
+ if ((dvalue < 0) || (value > 1.5))
+ die("Invalid pipe audio backend buffer desired length \"%f\". It "
+ "should be between 0 and "
+ "1.5, default is 1.0 second",
+ dvalue);
+ else {
+ config.audio_backend_buffer_desired_length = dvalue;
+ }
}
/* Get the latency offset. */
- if (config_lookup_int(config.cfg, "pipe.audio_backend_latency_offset", &value)) {
- if ((value < -66150) || (value > 66150))
- die("Invalid pipe audio backend buffer latency offset \"%d\". It should be between -66150 and +66150, default is 0",
- value);
+ if (config_lookup_float(config.cfg, "pipe.audio_backend_latency_offset",
+ &dvalue)) {
+ if ((dvalue < -1.0) || (value > 1.5))
+ die("Invalid pipe audio backend buffer latency offset \"%f\". It "
+ "should be between -1.0 and +1.5, default is 0 seconds",
+ dvalue);
else
- config.audio_backend_latency_offset = value;
+ config.audio_backend_latency_offset = dvalue;
}
}
-
if ((pipename == NULL) && (argc != 1))
die("bad or missing argument(s) to pipe");
diff --git a/audio_stdout.c b/audio_stdout.c
index cb11a99..b24e0da 100644
--- a/audio_stdout.c
+++ b/audio_stdout.c
@@ -53,27 +53,34 @@ static void stop(void) {
static int init(int argc, char **argv) {
const char *str;
int value;
+ double dvalue;
- config.audio_backend_buffer_desired_length = 44100; // one second.
+ config.audio_backend_buffer_desired_length = 1.0;
config.audio_backend_latency_offset = 0;
if (config.cfg != NULL) {
/* Get the desired buffer size setting. */
- if (config_lookup_int(config.cfg, "stdout.audio_backend_buffer_desired_length", &value)) {
- if ((value < 0) || (value > 132300))
- die("Invalid stdout audio backend buffer desired length \"%d\". It should be between 0 and 132300, default is 44100",
- value);
- else
- config.audio_backend_buffer_desired_length = value;
+ if (config_lookup_float(config.cfg,
+ "stdout.audio_backend_buffer_desired_length", &dvalue)) {
+ if ((dvalue < 0) || (dvalue > 1.5))
+ die("Invalid stdout audio backend buffer desired length \"%f\". It "
+ "should be between 0 and "
+ "1.5, default is 1.0 second",
+ dvalue);
+ else {
+ config.audio_backend_buffer_desired_length = dvalue;
+ }
}
/* Get the latency offset. */
- if (config_lookup_int(config.cfg, "stdout.audio_backend_latency_offset", &value)) {
- if ((value < -66150) || (value > 66150))
- die("Invalid stdout audio backend buffer latency offset \"%d\". It should be between -66150 and +66150, default is 0",
- value);
+ if (config_lookup_float(config.cfg, "stdout.audio_backend_latency_offset",
+ &dvalue)) {
+ if ((dvalue < -1.0) || (value > 1.5))
+ die("Invalid stdout audio backend buffer latency offset \"%f\". It "
+ "should be between -1.0 and +1.5, default is 0 seconds",
+ dvalue);
else
- config.audio_backend_latency_offset = value;
+ config.audio_backend_latency_offset = dvalue;
}
}
return 0;
diff --git a/common.h b/common.h
index c273fd1..4e6b114 100644
--- a/common.h
+++ b/common.h
@@ -95,8 +95,8 @@ typedef struct {
int ignore_volume_control;
int no_sync; // disable synchronisation, even if it's available
int no_mmap; // disable use of mmap-based output, even if it's available
- int resyncthreshold; // if it get's out of whack my more than this, resync. Zero means never
- // resync.
+ double resyncthreshold; // if it get's out of whack my more than this number of seconds, resync. Zero means never
+ // resync.
int allow_session_interruption;
int timeout; // while in play mode, exit if no packets of audio come in for more than this number
// of seconds . Zero means never exit.
@@ -117,7 +117,7 @@ typedef struct {
enum playback_mode_type playback_mode;
char *cmd_start, *cmd_stop;
int cmd_blocking;
- int tolerance; // allow this much drift before attempting to correct it
+ double tolerance; // allow this much drift before attempting to correct it
enum stuffing_type packet_stuffing;
int decoders_supported;
int use_apple_decoder; // set to 1 if you want to use the apple decoder instead of the original by David Hammerton
@@ -126,9 +126,9 @@ typedef struct {
// char *errfile;
char *configfile;
char *regtype; // The regtype is the service type followed by the protocol, separated by a dot, by default “_raop._tcp.”.
- long audio_backend_buffer_desired_length; // this will be the desired number of frames in the
- // audio backend buffer -- the DAC buffer for ALSA
- long audio_backend_latency_offset; // this will be the offset to compensate for any fixed latency there might be in the audio path
+ double audio_backend_buffer_desired_length; // this will be the length in seconds of the
+ // audio backend buffer -- the DAC buffer for ALSA
+ double audio_backend_latency_offset; // this will be the offset in seconds to compensate for any fixed latency there might be in the audio path
uint32_t volume_range_db; // the range, in dB, from max dB to min dB. Zero means use the mixer's native range.
enum sps_format_t output_format;
int output_rate;
diff --git a/player.c b/player.c
index 532252a..7edc2b3 100644
--- a/player.c
+++ b/player.c
@@ -743,7 +743,7 @@ static abuf_t *buffer_get_frame(void) {
// if would be in sync. To do this, we would give it a latency offset of -100 ms, i.e.
// -4410 frames.
- int64_t delta = (first_packet_timestamp - reference_timestamp)+config.latency+config.audio_backend_latency_offset;
+ int64_t delta = (first_packet_timestamp - reference_timestamp)+config.latency+config.audio_backend_latency_offset*output_sample_rate;
if (delta>=0) {
int64_t delta_fp_sec = (delta << 32) / output_sample_rate; // int64_t which is positive
@@ -765,7 +765,7 @@ static abuf_t *buffer_get_frame(void) {
if (first_packet_time_to_play != 0) {
// recalculate first_packet_time_to_play -- the latency might change
- int64_t delta = (first_packet_timestamp - reference_timestamp)+config.latency+config.audio_backend_latency_offset;
+ int64_t delta = (first_packet_timestamp - reference_timestamp)+config.latency+config.audio_backend_latency_offset*output_sample_rate;
if (delta>=0) {
int64_t delta_fp_sec = (delta << 32) / output_sample_rate; // int64_t which is positive
@@ -885,8 +885,8 @@ static abuf_t *buffer_get_frame(void) {
if (reference_timestamp) { // if we have a reference time
int64_t packet_timestamp = curframe->timestamp; // types okay
int64_t delta = packet_timestamp - reference_timestamp;
- int64_t offset = config.latency + config.audio_backend_latency_offset -
- config.audio_backend_buffer_desired_length; // all arguments are int32_t, so expression promotion okay
+ int64_t offset = config.latency + config.audio_backend_latency_offset*output_sample_rate -
+ config.audio_backend_buffer_desired_length*output_sample_rate; // all arguments are int32_t, so expression promotion okay
int64_t net_offset = delta + offset; // okay
uint64_t time_to_play = reference_timestamp_time; // type okay
if (net_offset >= 0) {
@@ -1160,7 +1160,7 @@ static void *player_thread_func(void *arg) {
// check that there are enough buffers to accommodate the desired latency and the latency offset
- int maximum_latency = config.latency+config.audio_backend_latency_offset;
+ int maximum_latency = config.latency+config.audio_backend_latency_offset*output_sample_rate;
if ((maximum_latency+(352-1))/352 + 10 > BUFFER_FRAMES)
die("Not enough buffers available for a total latency of %d frames. A maximum of %d 352-frame packets may be accommodated.",maximum_latency,BUFFER_FRAMES);
connection_state_to_output = get_requested_connection_state_to_output();
@@ -1243,7 +1243,7 @@ static void *player_thread_func(void *arg) {
if (config.statistics_requested) {
if ((config.output->delay)) {
if (config.no_sync==0) {
- inform("sync error in frames, "
+ inform("sync error in milliseconds, "
"net correction in ppm, "
"corrections in ppm, "
"total packets, "
@@ -1255,7 +1255,7 @@ static void *player_thread_func(void *arg) {
"min buffer occupancy, "
"max buffer occupancy");
} else {
- inform("sync error in frames, "
+ inform("sync error in milliseconds, "
"total packets, "
"missing packets, "
"late packets, "
@@ -1266,7 +1266,8 @@ static void *player_thread_func(void *arg) {
"max buffer occupancy");
}
} else {
- inform("total packets, "
+ inform("sync error in milliseconds, "
+ "total packets, "
"missing packets, "
"late packets, "
"too late packets, "
@@ -1477,10 +1478,10 @@ static void *player_thread_func(void *arg) {
// before we finally commit to this frame, check its sequencing and timing
// require a certain error before bothering to fix it...
- if (sync_error > config.tolerance) { // int64_t > int, okay
+ if (sync_error > config.tolerance*output_sample_rate) { // int64_t > int, okay
amount_to_stuff = -1;
}
- if (sync_error < -config.tolerance) {
+ if (sync_error < -config.tolerance*output_sample_rate) {
amount_to_stuff = 1;
}
@@ -1576,8 +1577,8 @@ static void *player_thread_func(void *arg) {
if (abs_sync_error<0)
abs_sync_error = -abs_sync_error;
- if ((config.no_sync==0) && (inframe->timestamp != 0) && (!please_stop) && (config.resyncthreshold != 0) &&
- (abs_sync_error > config.resyncthreshold)) {
+ if ((config.no_sync==0) && (inframe->timestamp != 0) && (!please_stop) && (config.resyncthreshold > 0.0) &&
+ (abs_sync_error > config.resyncthreshold*output_sample_rate)) {
sync_error_out_of_bounds++;
// debug(1,"Sync error out of bounds: Error: %lld; previous error: %lld; DAC: %lld;
// timestamp: %llx, time now
@@ -1684,7 +1685,7 @@ static void *player_thread_func(void *arg) {
if (at_least_one_frame_seen) {
if ((config.output->delay)) {
if (config.no_sync==0) {
- inform("%*.1f," /* Sync error inf frames */
+ inform("%*.1f," /* Sync error in milliseconds */
"%*.1f," /* net correction in ppm */
"%*.1f," /* corrections in ppm */
"%*d," /* total packets */
@@ -1695,7 +1696,7 @@ static void *player_thread_func(void *arg) {
"%*lli," /* min DAC queue size */
"%*d," /* min buffer occupancy */
"%*d", /* max buffer occupancy */
- 10, moving_average_sync_error,
+ 10, 1000*moving_average_sync_error/output_sample_rate,
10, moving_average_correction * 1000000 / (352*output_sample_ratio),
10, moving_average_insertions_plus_deletions * 1000000 / (352*output_sample_ratio),
12, play_number,
@@ -1707,7 +1708,7 @@ static void *player_thread_func(void *arg) {
5, minimum_buffer_occupancy,
5, maximum_buffer_occupancy);
} else {
- inform("%*.1f," /* Sync error inf frames */
+ inform("%*.1f," /* Sync error in milliseconds */
"%*d," /* total packets */
"%*llu," /* missing packets */
"%*llu," /* late packets */
@@ -1716,7 +1717,7 @@ static void *player_thread_func(void *arg) {
"%*lli," /* min DAC queue size */
"%*d," /* min buffer occupancy */
"%*d", /* max buffer occupancy */
- 10, moving_average_sync_error,
+ 10, 1000*moving_average_sync_error/output_sample_rate,
12, play_number,
7, missing_packets,
7, late_packets,
@@ -1727,7 +1728,7 @@ static void *player_thread_func(void *arg) {
5, maximum_buffer_occupancy);
}
} else {
- inform("%*.1f," /* Sync error inf frames */
+ inform("%*.1f," /* Sync error in milliseconds */
"%*d," /* total packets */
"%*llu," /* missing packets */
"%*llu," /* late packets */
@@ -1735,7 +1736,7 @@ static void *player_thread_func(void *arg) {
"%*llu," /* resend requests */
"%*d," /* min buffer occupancy */
"%*d", /* max buffer occupancy */
- 10, moving_average_sync_error,
+ 10, 1000*moving_average_sync_error/output_sample_rate,
12, play_number,
7, missing_packets,
7, late_packets,
diff --git a/scripts/shairport-sync.conf b/scripts/shairport-sync.conf
index 0502720..50d0f79 100644
--- a/scripts/shairport-sync.conf
+++ b/scripts/shairport-sync.conf
@@ -8,8 +8,8 @@ general =
// The default is "<Hostname>" -- the first letter is capitalised (ASCII only.)
// You can use %h for the hostname,
// %H for the Hostname (i.e. with first letter capitalised (ASCII only)),
-// %v for the version number, e.g. 2.8.4 and
-// %V for the full version string, e.g. 2.8.4-OpenSSL-Avahi-ALSA-soxr-metadata
+// %v for the version number, e.g. 3.2.1 and
+// %V for the full version string, e.g. 3.2.1-OpenSSL-Avahi-ALSA-soxr-metadata
// Overall length can not exceed 50 characters. Example: "Shairport Sync %v on %H".
// password = "secret"; // leave this commented out if you don't want to require a password
// interpolation = "basic"; // aka "stuffing". Default is "basic", alternative is "soxr". Use "soxr" only if you have a reasonably fast processor.
@@ -19,8 +19,8 @@ general =
// udp_port_base = 6001; // start allocating UDP ports from this port number when needed
// udp_port_range = 100; // look for free ports in this number of places, starting at the UDP port base (only three are needed).
// statistics = "no"; // set to "yes" to print statistics in the log
-// drift = 88; // allow this number of frames of drift away from exact synchronisation before attempting to correct it
-// resync_threshold = 2205; // a synchronisation error greater than this will cause resynchronisation; 0 disables it
+// drift = 0.002; // allow a timing error of this number of seconds of drift away from exact synchronisation before attempting to correct it
+// resync_threshold = 0.050; // a synchronisation error greater than this number of seconds will cause resynchronisation; 0 disables it
// log_verbosity = 0; // "0" means no debug verbosity, "3" is most verbose.
// ignore_volume_control = "no"; // set this to "yes" if you want the volume to be at 100% no matter what the source's volume control is set to.
// volume_range_db = 60 ; // use this to set the range, in dB, you want between the maximum volume and the minimum volume. Range is 30 to 150 dB. Leave it commented out to use mixer's native range.
@@ -60,8 +60,10 @@ alsa =
// output_device = "default"; // the name of the alsa output device. Use "alsamixer" or "aplay" to find out the names of devices, mixers, etc.
// mixer_control_name = "PCM"; // the name of the mixer to use to adjust output volume. If not specified, volume in adjusted in software.
// mixer_device = "default"; // the mixer_device default is whatever the output_device is. Normally you wouldn't have to use this.
-// 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 = 6615; // If set too small, buffer underflow occurs on low-powered machines. Too long and the response times with software mixer become annoying.
+// output_rate = 44100; // can be 44100, 88200, 176400, 352800, but the device must be capable of it
+// output_format = "S16_LE"; // can be "S16_LE", "S24_LE" or "S32_LE", but the device must be capable of it
+// audio_backend_latency_offset = 0.0; // Set this offset in seconds to compensate for a fixed delay in the audio back end. E.g. if the output device delays by 100 ms, set this to -0.1.
+// audio_backend_buffer_desired_length = 0.15; // Given in seconds. If set too small, buffer underflow occurs on low-powered machines. Too long and the response times with software mixer become annoying.
// disable_synchronization = "no"; // Set to "yes" to disable synchronization. Default is "no".
// period_size = <number>; // Use this optional advanced setting to set the alsa period size near to this value
// buffer_size = <number>; // Use this optional advanced setting to set the alsa buffer size near to this value
@@ -72,22 +74,22 @@ alsa =
pipe =
{
// name = "/path/to/pipe"; // there is no default pipe name for the output
-// 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.
+// audio_backend_latency_offset = 0.0; // Set this offset in seconds to compensate for a fixed delay in the audio back end. E.g. if the output device delays by 100 ms, set this to -0.1.
+// audio_backend_buffer_desired_length = 1.0; // Having started to send audio at the right time, send all subsequent audio this much ahead of time, creating a buffer this length.
};
// These are parameters for the "stdout" audio back end, a back end that directs raw CD-style audio output to stdout. No interpolation is done.
stdout =
{
-// 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.
+// audio_backend_latency_offset = 0.0; // Set this offset in seconds to compensate for a fixed delay in the audio back end. E.g. if the output device delays by 100 ms, set this to -0.1.
+// audio_backend_buffer_desired_length = 1.0; // Having started to send audio at the right time, send all subsequent audio this much ahead of time, creating a buffer this length.
};
// 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.
+// audio_backend_latency_offset = 0.0; // Set this offset in seconds to compensate for a fixed delay in the audio back end. E.g. if the output device delays by 100 ms, set this to -0.1.
+// audio_backend_buffer_desired_length = 1.0; // Having started to send audio at the right time, send all subsequent audio this much ahead of time, creating a buffer this length.
};
// Static latency settings are deprecated and the settings have been removed.
diff --git a/shairport.c b/shairport.c
index afcccac..1b74692 100644
--- a/shairport.c
+++ b/shairport.c
@@ -214,14 +214,14 @@ void usage(char *progname) {
printf(" -m, --mdns=BACKEND force the use of BACKEND to advertize the service.\n");
printf(" if no mdns provider is specified,\n");
printf(" shairport tries them all until one works.\n");
- printf(" -r, --resync=THRESHOLD resync if error exceeds this number of frames. Set to 0 to "
+ printf(" -r, --resync=THRESHOLD resync if timing error exceeds this number of seconds. Set to 0 to "
"stop resyncing.\n");
printf(" -t, --timeout=SECONDS go back to idle mode from play mode after a break in "
"communications of this many seconds (default 120). Set to 0 never to exit play mode.\n");
printf(" --statistics print some interesting statistics -- output to the logfile "
"if running as a daemon.\n");
- printf(" --tolerance=TOLERANCE allow a synchronization error of TOLERANCE frames (default "
- "88) before trying to correct it.\n");
+ printf(" --tolerance=TOLERANCE allow a synchronization error of TOLERANCE seconds (default "
+ "0.002) before trying to correct it.\n");
printf(" --password=PASSWORD require PASSWORD to connect. Default is not to require a "
"password.\n");
#ifdef CONFIG_METADATA
@@ -264,10 +264,10 @@ int parse_options(int argc, char **argv) {
{"iTunesLatency", 'i', POPT_ARG_INT, &config.iTunesLatency, 0, NULL},
{"forkedDaapdLatency", 0, POPT_ARG_INT, &config.ForkedDaapdLatency, 0, NULL},
{"stuffing", 'S', POPT_ARG_STRING, &stuffing, 'S', NULL},
- {"resync", 'r', POPT_ARG_INT, &config.resyncthreshold, 0, NULL},
+ {"resync", 'r', POPT_ARG_DOUBLE, &config.resyncthreshold, 0, NULL},
{"timeout", 't', POPT_ARG_INT, &config.timeout, 't', NULL},
{"password", 0, POPT_ARG_STRING, &config.password, 0, NULL},
- {"tolerance", 0, POPT_ARG_INT, &config.tolerance, 0, NULL},
+ {"tolerance", 0, POPT_ARG_DOUBLE, &config.tolerance, 0, NULL},
#ifdef CONFIG_METADATA
{"metadata-pipename", 'M', POPT_ARG_STRING, &config.metadata_pipename, 'M', NULL},
{"get-coverart", 'g', POPT_ARG_NONE, &config.get_coverart, 'g', NULL},
@@ -302,6 +302,7 @@ int parse_options(int argc, char **argv) {
config_setting_t *setting;
const char *str=0;
int value=0;
+ double dvalue = 0.0;
debug(1,"Looking for the configuration file \"%s\".",config.configfile);
@@ -390,12 +391,12 @@ int parse_options(int argc, char **argv) {
}
/* Get the drift tolerance setting. */
- if (config_lookup_int(config.cfg, "general.drift", &value))
- config.tolerance = value;
+ if (config_lookup_float(config.cfg, "general.drift", &dvalue))
+ config.tolerance = dvalue;
/* Get the resync setting. */
- if (config_lookup_int(config.cfg, "general.resync_threshold", &value))
- config.resyncthreshold = value;
+ if (config_lookup_float(config.cfg, "general.resync_threshold", &dvalue))
+ config.resyncthreshold = dvalue;
/* Get the verbosity setting. */
if (config_lookup_int(config.cfg, "general.log_verbosity", &value)) {
@@ -759,9 +760,9 @@ int main(int argc, char **argv) {
config.AirPlayLatency = -1; // -1 means not set. 88200 seems to work well for AirPlay -- Syncs sound and
// vision on AppleTV, but also used for iPhone/iPod/iPad sources
config.ForkedDaapdLatency = -1; // -1 means not set. 99400 seems to be right
- config.resyncthreshold = 441 * 5; // this number of frames is 50 ms
+ config.resyncthreshold = 0.05; // 50 ms
config.timeout = 120; // this number of seconds to wait for [more] audio before switching to idle.
- config.tolerance = 88; // this number of frames of error before attempting to correct it.
+ config.tolerance = 0.002; // this number of seconds of timing error before attempting to correct it.
config.buffer_start_fill = 220;
config.port = 5000;
config.packet_stuffing = ST_basic; // simple interpolation or deletion
@@ -1024,10 +1025,10 @@ int main(int argc, char **argv) {
debug(2, "iTunesLatency is %d.", config.iTunesLatency);
debug(2, "forkedDaapdLatency is %d.", config.ForkedDaapdLatency);
debug(1, "stuffing option is \"%d\" (0-basic, 1-soxr).", config.packet_stuffing);
- debug(1, "resync time is %d.", config.resyncthreshold);
+ debug(1, "resync time is %f seconds.", config.resyncthreshold);
debug(1, "allow a session to be interrupted: %d.", config.allow_session_interruption);
debug(1, "busy timeout time is %d.", config.timeout);
- debug(1, "drift tolerance is %d frames.", config.tolerance);
+ debug(1, "drift tolerance is %f seconds.", config.tolerance);
debug(1, "password is \"%s\".", config.password);
debug(1, "ignore_volume_control is %d.", config.ignore_volume_control);
debug(1, "playback_mode is %d (0-stereo, 1-mono).", config.playback_mode);
@@ -1035,9 +1036,9 @@ int main(int argc, char **argv) {
debug(1, "use_mmap_if_available is %d.", config.no_mmap ? 0 : 1);
debug(1, "output_rate is %d (0 means 44,100).", config.output_rate);
debug(1, "output_format is %d (0 means S16_LE).", config.output_format);
- debug(1, "audio backend desired buffer length is %d.",
+ debug(1, "audio backend desired buffer length is %f seconds.",
config.audio_backend_buffer_desired_length);
- debug(1, "audio backend latency offset is %d.", config.audio_backend_latency_offset);
+ debug(1, "audio backend latency offset is %f seconds.", config.audio_backend_latency_offset);
debug(1, "volume range in dB (zero means use the range specified by the mixer): %u.", config.volume_range_db);
debug(1, "zeroconf regtype is \"%s\".", config.regtype);
debug(1, "decoders_supported field is %d.", config.decoders_supported);