From: Mike Brady Date: Thu, 14 May 2020 18:51:32 +0000 (+0100) Subject: Fix calculation of latency -- honour the signs of the offset and account for the... X-Git-Tag: 3.3.7d12~99 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=72d715352951efe3b4cecd412ec7528659ad18f2;p=thirdparty%2Fshairport-sync.git Fix calculation of latency -- honour the signs of the offset and account for the DAC buffer size. --- diff --git a/audio.c b/audio.c index 8b2762f4..f2195279 100644 --- 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. */ diff --git a/common.h b/common.h index d5aad230..dd267550 100644 --- 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 dc794d4d..b8e41d67 100644 --- 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) { diff --git a/player.h b/player.h index 3845ca9f..483d4fee 100644 --- 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 diff --git a/shairport.c b/shairport.c index ec5a259a..867938ed 100644 --- a/shairport.c +++ b/shairport.c @@ -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 =