From: Mike Brady Date: Sun, 17 May 2020 11:48:25 +0000 (+0100) Subject: Add the ability to set the silent lead-in parameters initial_period, minimum number... X-Git-Tag: 3.3.7d12~92 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=012dd26c77c6abf89a73076bc085ad97cf3639de;p=thirdparty%2Fshairport-sync.git Add the ability to set the silent lead-in parameters initial_period, minimum number of adjustments and adjustment interval, and give them sensible defaults. --- diff --git a/common.h b/common.h index d2d90421..ec9f35a1 100644 --- a/common.h +++ b/common.h @@ -212,6 +212,10 @@ typedef struct { // buffer double disable_standby_mode_silence_scan_interval; // check the threshold this often + double lead_in_silence_initial_period; // the size of the first block of silence to send to the DAC + int lead_in_silence_minimum_adjustments_to_make; // make at least this number of checks and timing adjustments + double lead_in_silence_adjustment_interval; // make checks and adjustments at this interval + 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 int audio_backend_silent_lead_in_time_auto; // true if the lead-in time should be from as soon as packets are received diff --git a/player.c b/player.c index f36417c5..2d8f635e 100644 --- a/player.c +++ b/player.c @@ -1129,12 +1129,8 @@ static abuf_t *buffer_get_frame(rtsp_conn_info *conn) { // setting // In fact, if should be some fraction of them, to allow for adjustment. - double adjustment_interval_seconds = 0.025; - int64_t minimum_adjustments_to_make = 3; - double initial_silence_seconds = 0.2; - - int64_t adjustment_interval_frames = (int64_t)(adjustment_interval_seconds * conn->input_rate); - int64_t initial_silence_frames = (int64_t)(initial_silence_seconds * conn->input_rate); + int64_t adjustment_interval_frames = (int64_t)(config.lead_in_silence_adjustment_interval * conn->input_rate); + int64_t initial_silence_frames = (int64_t)(config.lead_in_silence_initial_period * conn->input_rate); int64_t max_dac_delay = effective_latency; if (config.audio_backend_silent_lead_in_time_auto == 0) @@ -1146,11 +1142,11 @@ static abuf_t *buffer_get_frame(rtsp_conn_info *conn) { int64_t filler_size = adjustment_interval_frames; if (have_sent_prefiller_silence == 0) { - int64_t delay_before_adjustments = max_dac_delay - minimum_adjustments_to_make * adjustment_interval_frames; + int64_t delay_before_adjustments = max_dac_delay - config.lead_in_silence_minimum_adjustments_to_make * adjustment_interval_frames; if (delay_before_adjustments > initial_silence_frames) filler_size = initial_silence_frames; else - filler_size = max_dac_delay / (minimum_adjustments_to_make + 1); + filler_size = max_dac_delay / (config.lead_in_silence_minimum_adjustments_to_make + 1); // debug(1,"Initial filler size: %" PRId64 " frames.", filler_size); } diff --git a/scripts/shairport-sync.conf b/scripts/shairport-sync.conf index e4137638..33db5d91 100644 --- a/scripts/shairport-sync.conf +++ b/scripts/shairport-sync.conf @@ -47,6 +47,10 @@ general = // audio_backend_buffer_desired_length_in_seconds = 0.2; // If set too small, buffer underflow occurs on low-powered machines. Too long and the response time to volume changes becomes annoying. Default is 0.2 seconds in the alsa backend, 0.35 seconds in the pa backend and 1.0 seconds otherwise. // audio_backend_buffer_interpolation_threshold_in_seconds = 0.075; // Advanced feature. If the buffer size drops below this, stop using time-consuming interpolation like soxr to avoid dropouts due to underrun. // audio_backend_silent_lead_in_time = "auto"; // This optional advanced setting, either "auto" or a positive number, sets the length of the period of silence that precedes the start of the audio. The default is "auto" -- the silent lead-in starts as soon as the player starts sending packets. Values greater than the latency are ignored. Values that are too low will affect initial synchronisation. +// audio_backend_silent_lead_in_initial_period = 0.5; // This optional advanced setting sets the length, in seconds, of the first "block" of silence sent to the DAC -- some DACs need a fairly substantial block to prevent lots of initial underrun. +// audio_backend_silent_lead_in_minimum_adjustments_to_make = 3; // This optional advanced setting sets the minimum number of times Shairport Sync will readjust the length of the silent lead in to ensure that the audio starts at precisely the correct time. +// audio_backend_silent_lead_in_adjustment_interval = 0.1; // This optional advanced setting sets the interval, in seconds, between adjustments of the silent lead in to ensure that the audio starts at precisely the correct time. + // dbus_service_bus = "system"; // The Shairport Sync dbus interface, if selected at compilation, will appear // as "org.gnome.ShairportSync" on the whichever bus you specify here: "system" (default) or "session". // mpris_service_bus = "system"; // The Shairport Sync mpris interface, if selected at compilation, will appear diff --git a/shairport.c b/shairport.c index ead93b2d..60bfb4a0 100644 --- a/shairport.c +++ b/shairport.c @@ -751,9 +751,9 @@ int parse_options(int argc, char **argv) { * range set by the mixer. */ if (config_lookup_int(config.cfg, "general.volume_range_db", &value)) { if ((value < 30) || (value > 150)) - die("Invalid volume range \"%sd\". It should be between 30 and 150 dB. Zero means use " - "the mixer's native range", - value); + die("Invalid volume range %d dB. It should be between 30 and 150 dB. Zero means use " + "the mixer's native range. The setting reamins at %d.", + value, config.volume_range_db); else config.volume_range_db = value; } @@ -779,7 +779,7 @@ int parse_options(int argc, char **argv) { if ((dvalue >= 0.0) && (dvalue <= 3.0)) config.resend_control_first_check_time = dvalue; else - warn("Invalid general resend_control_first_check_time setting \"%d\". It should " + warn("Invalid general resend_control_first_check_time setting \"%f\". It should " "be " "between 0.0 and 3.0, " "inclusive. The setting remains at %f seconds.", @@ -791,7 +791,7 @@ int parse_options(int argc, char **argv) { if ((dvalue >= 0.0) && (dvalue <= 3.0)) config.resend_control_check_interval_time = dvalue; else - warn("Invalid general resend_control_check_interval_time setting \"%d\". It should " + warn("Invalid general resend_control_check_interval_time setting \"%f\". It should " "be " "between 0.0 and 3.0, " "inclusive. The setting remains at %f seconds.", @@ -803,7 +803,7 @@ int parse_options(int argc, char **argv) { if ((dvalue >= 0.0) && (dvalue <= 3.0)) config.resend_control_last_check_time = dvalue; else - warn("Invalid general resend_control_last_check_time setting \"%d\". It should " + warn("Invalid general resend_control_last_check_time setting \"%f\". It should " "be " "between 0.0 and 3.0, " "inclusive. The setting remains at %f seconds.", @@ -815,7 +815,7 @@ int parse_options(int argc, char **argv) { if ((dvalue >= 0.0) && (dvalue <= 300.0)) config.missing_port_dacp_scan_interval_seconds = dvalue; else - warn("Invalid general missing_port_dacp_scan_interval_seconds setting \"%d\". It should " + warn("Invalid general missing_port_dacp_scan_interval_seconds setting \"%f\". It should " "be " "between 0.0 and 300.0, " "inclusive. The setting remains at %f seconds.", @@ -826,6 +826,40 @@ int parse_options(int argc, char **argv) { if (config_lookup_int(config.cfg, "latencies.default", &value)) config.userSuppliedLatency = value; + /* Get the lead-in silence settings. */ + if (config_lookup_float(config.cfg, "general.audio_backend_silent_lead_in_initial_period", + &dvalue)) { + if ((dvalue >= 0.0) && (dvalue <= 3.0)) + config.lead_in_silence_initial_period = dvalue; + else + warn("Invalid general audio_backend_silent_lead_in_initial_period setting \"%f\". It should " + "be " + "between 0.0 and 3.0, " + "inclusive. The setting remains at %f seconds.", + dvalue, config.lead_in_silence_initial_period); + } + + if (config_lookup_int(config.cfg, "general.audio_backend_silent_lead_in_minimum_adjustments_to_make", &value)) { + if (value < 0) + die("Invalid audio_backend_silent_lead_in_minimum_adjustments_to_make range \"%d\". It must be positive. The setting remains at %d.", + value, config.lead_in_silence_minimum_adjustments_to_make); + else + config.lead_in_silence_minimum_adjustments_to_make = value; + } + + if (config_lookup_float(config.cfg, "general.audio_backend_silent_lead_in_adjustment_interval", + &dvalue)) { + if ((dvalue >= 0.0) && (dvalue <= 3.0)) + config.lead_in_silence_adjustment_interval = dvalue; + else + warn("Invalid general audio_backend_silent_lead_in_adjustment_interval setting \"%f\". It should " + "be " + "between 0.0 and 3.0, " + "inclusive. The setting remains at %f seconds.", + dvalue, config.lead_in_silence_adjustment_interval); + } + + #ifdef CONFIG_METADATA /* Get the metadata setting. */ config.metadata_enabled = 1; // if metadata support is included, then enable it by default @@ -1498,6 +1532,9 @@ int main(int argc, char **argv) { config.output_rate_auto_requested = 1; // default auto select format config.decoders_supported = 1 << decoder_hammerton; // David Hammerton's decoder supported by default + config.lead_in_silence_initial_period = 0.5; // the size of the first block of silence to send to the DAC + config.lead_in_silence_minimum_adjustments_to_make = 3; // make at least this number of checks and timing adjustments + config.lead_in_silence_adjustment_interval = 0.025; // make checks and adjustments at this interval #ifdef CONFIG_APPLE_ALAC config.decoders_supported += 1 << decoder_apple_alac; config.use_apple_decoder = 1; // use the ALAC decoder by default if support has been included @@ -1793,6 +1830,13 @@ int main(int argc, char **argv) { else debug(1, "audio backend silence lead-in time is %f seconds.", config.audio_backend_silent_lead_in_time); + + debug(1, "audio backend silent lead-in initial period is %f seconds.", + config.lead_in_silence_initial_period); + debug(1, "audio backend silent lead-in minimum adjustments to make is %d.", config.lead_in_silence_minimum_adjustments_to_make); + debug(1, "audio backend silent lead-in adjustment interval is %f seconds.", + config.lead_in_silence_adjustment_interval); + debug(1, "zeroconf regtype is \"%s\".", config.regtype); debug(1, "decoders_supported field is %d.", config.decoders_supported); debug(1, "use_apple_decoder is %d.", config.use_apple_decoder);