]> git.ipfire.org Git - thirdparty/shairport-sync.git/commitdiff
Allow a zero silent lead-in time.
authorMike Brady <mikebrady@eircom.net>
Sat, 22 Jul 2017 15:37:02 +0000 (17:37 +0200)
committerMike Brady <mikebrady@eircom.net>
Sat, 22 Jul 2017 15:37:02 +0000 (17:37 +0200)
audio.c
player.c
scripts/shairport-sync.conf
shairport.c

diff --git a/audio.c b/audio.c
index 1ba178ec624884d24675cd8d8248581cebff9379..a1fcf614d344feafec9f56b152c60c7af7739d41 100644 (file)
--- a/audio.c
+++ b/audio.c
@@ -180,9 +180,9 @@ void parse_general_audio_options(void) {
     /* Get the desired length of the silent lead-in. */
     if (config_lookup_float(config.cfg, "general.audio_backend_silent_lead_in_time",
                             &dvalue)) {
-      if ((dvalue < 0.05) || (dvalue > 4)) {
+      if ((dvalue < 0.0) || (dvalue > 4)) {
         die("Invalid audio_backend_silent_lead_in_time \"%f\". It "
-            "must be between 0.050 and 4.0 seconds. Omit setting to use the default value, which is approximately the latency specified by the source (typically 2 seconds). A value greater than the latency is ignored.",
+            "must be between 0.0 and 4.0 seconds. Omit setting to use the default value",
             dvalue);
       } else {
         config.audio_backend_silent_lead_in_time = dvalue;
index bdf665d34b0223b086793ff3a701e7dc888d36cc..450c3d1755af80bcdd346fa74edb0120226a9cd3 100644 (file)
--- a/player.c
+++ b/player.c
@@ -869,8 +869,13 @@ static abuf_t *buffer_get_frame(rtsp_conn_info *conn) {
                   (abs_delta << 32) / config.output_rate; // int64_t which is positive
               conn->first_packet_time_to_play = reference_timestamp_time - delta_fp_sec;
             }
-
-            int64_t max_dac_delay = config.output_rate / 10;
+            
+            // now, the size of the initial silence must be affected by the lead-in time.
+            // it must be somewhat less than the lead-in time so that dynamic adjustments can be made
+            // to compensate for delays due to paging, etc.
+            // The suggestion is that it should be at least 100 ms less than the lead-in time.
+            
+            int64_t max_dac_delay = config.output_rate / 10; // so the lead-in time must be greater than this, say 0.2 sec, to allow for dynamic adjustment
             int64_t filler_size = max_dac_delay; // 0.1 second -- the maximum we'll add to the DAC
 
             if (local_time_now >= conn->first_packet_time_to_play) {
@@ -896,14 +901,15 @@ static abuf_t *buffer_get_frame(rtsp_conn_info *conn) {
               // do some calculations
               int64_t lead_time = conn->first_packet_time_to_play-local_time_now;
               int64_t lead_in_time = (int64_t)(config.audio_backend_silent_lead_in_time*(int64_t)0x100000000);
-              //debug(1,"Lead in time is %llx.",lead_in_time);
-              // an audio_backend_silent_lead_in_time of less than zero means start filling ASAP 
+              // debug(1,"Lead time is %llx at fpttp %llx.",lead_time,conn->first_packet_time_to_play);
+              // an audio_backend_silent_lead_in_time of less than zero means start filling ASAP
               if ((lead_in_time<0) || (lead_time<=lead_in_time)) {
-                // debug(1,"Continuing...");
+                // debug(1,"Checking");
                 if (config.output->delay) {
                   // conn->first_packet_time_to_play is definitely later than local_time_now
                   if (have_sent_prefiller_silence != 0) {
                     int resp = config.output->delay(&dac_delay);
+                    
                     if (resp != 0) {
                       debug(1, "Error %d getting dac_delay in buffer_get_frame.", resp);
                       dac_delay = 0;
@@ -916,6 +922,7 @@ static abuf_t *buffer_get_frame(rtsp_conn_info *conn) {
                   int64_t exact_frame_gap = gross_frame_gap - dac_delay;
                   if (exact_frame_gap < 0) {
                     // we've gone past the time...
+                    // debug(1,"Run past time.");
                     // debug(1,"Run a bit past the exact start time by %lld frames, with time now of
                     // %llx, fpttp of %llx and dac_delay of %d and %d packets;
                     // flush.",-exact_frame_gap,tn,conn->first_packet_time_to_play,dac_delay,seq_diff(ab_read,
@@ -950,18 +957,18 @@ static abuf_t *buffer_get_frame(rtsp_conn_info *conn) {
                     // the fs (number of frames of silence to play) can be zero in the DAC doesn't start
                     // ouotputting frames for a while -- it could get loaded up but not start responding
                     // for many milliseconds.
-                    if (fs != 0) {
+                    if (fs > 0) {
                       silence = malloc(conn->output_bytes_per_frame * fs);
                       if (silence == NULL)
                         debug(1, "Failed to allocate %d byte silence buffer.", fs);
                       else {
                         memset(silence, 0, conn->output_bytes_per_frame * fs);
-                        // debug(1,"Frames to start: %llu, DAC delay %ld, buffer: %d packets.",exact_frame_gap,dac_delay,seq_diff(conn->ab_read, conn->ab_write, conn->ab_read));
+                        // debug(1,"Frames to start: %llu, DAC delay %d, buffer: %d packets.",exact_frame_gap,dac_delay,seq_diff(conn->ab_read, conn->ab_write, conn->ab_read));
                         config.output->play(silence, fs);
                         free(silence);
-                        have_sent_prefiller_silence = 1;
                       }
                     }
+                    have_sent_prefiller_silence = 1; // even if we haven't sent silence because it's zero frames long...
                   }
                 } else {
                   //no delay function on back end -- just send the prefiller silence
@@ -1078,6 +1085,7 @@ static abuf_t *buffer_get_frame(rtsp_conn_info *conn) {
       time_to_wait_for_wakeup_fp *= 4 * 352;      // four full 352-frame packets
       time_to_wait_for_wakeup_fp /= 3;            // four thirds of a packet time
 
+
 #ifdef COMPILE_FOR_LINUX_AND_FREEBSD_AND_CYGWIN
       uint64_t time_of_wakeup_fp = local_time_now + time_to_wait_for_wakeup_fp;
       uint64_t sec = time_of_wakeup_fp >> 32;
@@ -1086,7 +1094,6 @@ static abuf_t *buffer_get_frame(rtsp_conn_info *conn) {
       struct timespec time_of_wakeup;
       time_of_wakeup.tv_sec = sec;
       time_of_wakeup.tv_nsec = nsec;
-
       pthread_cond_timedwait(&conn->flowcontrol, &conn->ab_mutex, &time_of_wakeup);
 // int rc = pthread_cond_timedwait(&flowcontrol,&ab_mutex,&time_of_wakeup);
 // if (rc!=0)
index 3fcbac06ef4c0242b9c3a4168d6e816fd3d8c072..ed471ea374b5ffce377a595b5e12ac7033043920 100644 (file)
@@ -41,7 +41,7 @@ general =
 
 //  audio_backend_latency_offset_in_seconds = 0.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 -0.1.
 //  audio_backend_buffer_desired_length_in_seconds = 0.15; // 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.15 seconds in the alsa backend, 0.35 seconds in the pa backend and 1.0 seconds otherwise.
-//  audio_backend_silent_lead_in_time = 2.0; // Use this optional advanced setting, between 0.050 and 4.0 seconds, to set the length of the period of silence that precedes the start of the audio. The default is the latency, usually 2.0 seconds. Values greater than the latency are ignored.
+//  audio_backend_silent_lead_in_time = 2.0; // This optional advanced setting, from 0.0 and 4.0 seconds, sets the length of the period of silence that precedes the start of the audio. The default is the latency, usually 2.0 seconds. Values greater than the latency are ignored. Values that are too low will affect initial synchronisation.
 };
 
 
index 8226083b5ed85e5b9dba765df8546bd202f5fd27..24ff176b1b055b7284fda7b910ed023c182d4a11 100644 (file)
@@ -1316,7 +1316,7 @@ int main(int argc, char **argv) {
   debug(1, "audio backend desired buffer length is %f seconds.",
         config.audio_backend_buffer_desired_length);
   debug(1, "audio backend latency offset is %f seconds.", config.audio_backend_latency_offset);
-  debug(1, "audio backend silence lead-in time is %f seconds. The value -1.0 means use the default.", config.audio_backend_silent_lead_in_time);
+  debug(1, "audio backend silence lead-in time is %f seconds. A value -1.0 means use the default.", config.audio_backend_silent_lead_in_time);
   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);