]> git.ipfire.org Git - thirdparty/shairport-sync.git/commitdiff
Add the ability to set the silent lead-in parameters initial_period, minimum number...
authorMike Brady <mikebradydublin@icloud.com>
Sun, 17 May 2020 11:48:25 +0000 (12:48 +0100)
committerMike Brady <mikebradydublin@icloud.com>
Sun, 17 May 2020 11:48:25 +0000 (12:48 +0100)
common.h
player.c
scripts/shairport-sync.conf
shairport.c

index d2d9042187a1f0f6a763aa1d7747070748383eb5..ec9f35a1228eb3e76e46e228bb5891d1d9a59fdf 100644 (file)
--- 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
index f36417c5eac23f8edb97b2b2c20247ff9a487436..2d8f635e1c8b30dabce74fd848a16d46e738dcdf 100644 (file)
--- 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);
             }
 
index e413763819fcdbd33d354a94ceb945f5b33e5981..33db5d91771048a34b18982a65e5c293d432b0ba 100644 (file)
@@ -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
index ead93b2d75860d6b573baf601168a06db5998d54..60bfb4a047159f7e443dad0e15ffdd9964a884b3 100644 (file)
@@ -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);