From: Mike Brady Date: Sat, 22 Jul 2017 15:37:02 +0000 (+0200) Subject: Allow a zero silent lead-in time. X-Git-Tag: 3.1~10^2~22 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ede276d4afd15916e2ec6c859f4b9dbf6fbeadae;p=thirdparty%2Fshairport-sync.git Allow a zero silent lead-in time. --- diff --git a/audio.c b/audio.c index 1ba178ec..a1fcf614 100644 --- 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; diff --git a/player.c b/player.c index bdf665d3..450c3d17 100644 --- 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) diff --git a/scripts/shairport-sync.conf b/scripts/shairport-sync.conf index 3fcbac06..ed471ea3 100644 --- a/scripts/shairport-sync.conf +++ b/scripts/shairport-sync.conf @@ -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. }; diff --git a/shairport.c b/shairport.c index 8226083b..24ff176b 100644 --- a/shairport.c +++ b/shairport.c @@ -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);