]> git.ipfire.org Git - thirdparty/shairport-sync.git/commitdiff
Fix calculation of latency -- honour the signs of the offset and account for the...
authorMike Brady <mikebradydublin@icloud.com>
Thu, 14 May 2020 18:51:32 +0000 (19:51 +0100)
committerMike Brady <mikebradydublin@icloud.com>
Thu, 14 May 2020 18:51:32 +0000 (19:51 +0100)
audio.c
common.h
dacp.c
player.h
shairport.c

diff --git a/audio.c b/audio.c
index 8b2762f459c6bf609232502218b90ed42aa205c3..f219527938b7ad0331ad7645a2dfc8fa8853d2fd 100644 (file)
--- a/audio.c
+++ b/audio.c
@@ -147,10 +147,10 @@ void parse_general_audio_options(void) {
     /* Get the desired buffer size setting in seconds. */
     if (config_lookup_float(config.cfg, "general.audio_backend_buffer_desired_length_in_seconds",
                             &dvalue)) {
-      if ((dvalue < 0) || (dvalue > 1.5)) {
+      if (dvalue < 0) {
         die("Invalid audio_backend_buffer_desired_length_in_seconds value: \"%f\". It "
-            "should be between 0 and "
-            "1.5, default is %.3f seconds",
+            "should be 0.0 or greater."
+            " The default is %.3f seconds",
             dvalue, config.audio_backend_buffer_desired_length);
       } else {
         config.audio_backend_buffer_desired_length = dvalue;
@@ -190,13 +190,7 @@ void parse_general_audio_options(void) {
     /* Get the latency offset in seconds. */
     if (config_lookup_float(config.cfg, "general.audio_backend_latency_offset_in_seconds",
                             &dvalue)) {
-      if ((dvalue < -1.75) || (dvalue > 1.75)) {
-        die("Invalid audio_backend_latency_offset_in_seconds \"%f\". It "
-            "should be between -1.75 and +1.75, default is 0 seconds",
-            dvalue);
-      } else {
         config.audio_backend_latency_offset = dvalue;
-      }
     }
 
     /* Get the desired length of the silent lead-in. */
index d5aad23027466af196162ada6bd68f225a7b9196..dd2675506865b960059287d0a2f261b213b936f3 100644 (file)
--- a/common.h
+++ b/common.h
@@ -215,6 +215,7 @@ typedef struct {
   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
   double audio_backend_silent_lead_in_time; // the length of the silence that should precede a play.
+  uint32_t minimum_free_buffer_headroom; // when effective latency is calculated, ensure this number of buffers are unallocated
   double active_state_timeout; // the amount of time from when play ends to when the system leaves
                                // into the "active" mode.
   uint32_t volume_range_db; // the range, in dB, from max dB to min dB. Zero means use the mixer's
diff --git a/dacp.c b/dacp.c
index dc794d4d5b2fed71085a333fc36b6d58f5546526..b8e41d6789a5425ff99edf31a6d3b803511c8780 100644 (file)
--- a/dacp.c
+++ b/dacp.c
@@ -1248,7 +1248,7 @@ int dacp_get_volume(int32_t *the_actual_volume) {
     } else {
       debug(1, "Unexpected return code %d from dacp_get_speaker_list.", http_response);
     }
-  } else {
+  } else if (http_response != 400){
     debug(3, "Unexpected return code %d from dacp_get_client_volume.", http_response);
   }
   if (the_actual_volume) {
index 3845ca9ff9ba87550b60dd1eef4ec6fa58faa044..483d4feef3eb858a2d15fe6d5c1d0a46afa9b930 100644 (file)
--- a/player.h
+++ b/player.h
@@ -87,6 +87,7 @@ typedef struct {
   uint32_t maximum_latency;  // set if an a=max-latency: line appears in the ANNOUNCE message; zero
                              // otherwise
   int software_mute_enabled; // if we don't have a real mute that we can use
+  int unachievable_audio_backend_latency_offset_notified; // set when a latency warning is issued
 
   int fd;
   int authorized;   // set if a password is required and has been supplied
index ec5a259acbd07613ce2d97c62928d9eeae0d6b4a..867938edbdc6d073f4d91f6fe04683b0dc9b7659 100644 (file)
@@ -407,6 +407,10 @@ int parse_options(int argc, char **argv) {
   config.resend_control_last_check_time = 0.10; // give up if the packet is still missing this close to when it's needed
   config.missing_port_dacp_scan_interval_seconds = 2.0; // check at this interval if no DACP port number is known
 
+  config.minimum_free_buffer_headroom = 125; // leave approximately one second's worth of buffers free after calculating the effective latency.
+  // e.g. if we have 1024 buffers or 352 frames = 8.17 seconds and we have a nominal latency of 2.0 seconds
+  // then we can add an offset of 5.17 seconds and still leave a second's worth of buffers for unexpected circumstances
+
 #ifdef CONFIG_METADATA_HUB
   config.cover_art_cache_dir = "/tmp/shairport-sync/.cache/coverart";
   config.scan_interval_when_active =