From: Mike Brady Date: Mon, 13 Aug 2018 13:06:40 +0000 (+0100) Subject: display the number of samples used to calculcate drift, clean up the settings for... X-Git-Tag: 3.3RC0~260 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a8cfc9915f05e3fcb8dc725dd89f0197bb4ee234;p=thirdparty%2Fshairport-sync.git display the number of samples used to calculcate drift, clean up the settings for the number of samples to skip at the start and for the minimum number of samples to use. Store 64 samples. --- diff --git a/player.c b/player.c index 595c1fda..f2e1a7fd 100644 --- a/player.c +++ b/player.c @@ -2416,7 +2416,8 @@ void *player_thread_func(void *arg) { "%*d," /* max buffer occupancy */ "%*.2f," /* input frame rate */ "%*.2f," /* output frame rate */ - "%*.2f", /* client clock to local clock drift in ppm */ + "%*.2f," /* output frame rate */ + "%*d", /* sample count */ 10, 1000 * moving_average_sync_error / config.output_rate, 10, moving_average_correction * 1000000 / (352 * conn->output_sample_ratio), @@ -2425,7 +2426,7 @@ void *player_thread_func(void *arg) { 12, play_number, 7, conn->missing_packets, 7, conn->late_packets, 7, conn->too_late_packets, 7, conn->resend_requests, 7, minimum_dac_queue_size, 5, minimum_buffer_occupancy, 5, - maximum_buffer_occupancy, 11, conn->input_frame_rate, 11, conn->frame_rate , 10, (1.0-conn->local_to_remote_time_gradient)*1000000); + maximum_buffer_occupancy, 11, conn->input_frame_rate, 11, conn->frame_rate , 10, (1.0-conn->local_to_remote_time_gradient)*1000000, 6, conn->local_to_remote_time_gradient_sample_count); } else { inform("%*.2f," /* Sync error in milliseconds */ "%*d," /* total packets */ diff --git a/player.h b/player.h index 5402a18f..a7d961a5 100644 --- a/player.h +++ b/player.h @@ -24,7 +24,7 @@ #include "alac.h" #include "audio.h" -#define time_ping_history 32 +#define time_ping_history 64 // at 1 per three seconds, approximately three minutes of records typedef struct time_ping_record { uint64_t local_to_remote_difference; @@ -207,6 +207,7 @@ typedef struct { pthread_mutex_t reference_time_mutex; double local_to_remote_time_gradient; // if no drift, this would be exactly 1.0; likely it's slightly above or below. + int local_to_remote_time_gradient_sample_count; // the number of samples used to calculate the gradient uint64_t local_to_remote_time_difference; // used to switch between local and remote clocks uint64_t local_to_remote_time_difference_measurement_time; // when the above was calculated diff --git a/rtp.c b/rtp.c index df71f413..96bb0fcf 100644 --- a/rtp.c +++ b/rtp.c @@ -702,9 +702,12 @@ void *rtp_timing_receiver(void *arg) { uint64_t x_bar = 0; // local timestamp average int sample_count = 0; - + // approximate time in seconds to let the system settle down + const int settling_time = 60; + // number of points to have for calculating a valid drift + const int sample_point_minimum = 8; for (cc = 0; cc < conn->time_ping_count; cc++) - if ((conn->time_pings[cc].chosen) && (conn->time_pings[cc].sequence_number>9)) { // wait for a minute or so.... + if ((conn->time_pings[cc].chosen) && (conn->time_pings[cc].sequence_number>(settling_time/3))) { // wait for a approximate settling time y_bar += (conn->time_pings[cc].remote_time>>12); //precision is down to 1/4th of a microsecond x_bar += (conn->time_pings[cc].local_time>>12); sample_count++; @@ -717,7 +720,7 @@ void *rtp_timing_receiver(void *arg) { int64_t mtl, mbl; mtl=0;mbl=0; for (cc = 0; cc < conn->time_ping_count; cc++) - if ((conn->time_pings[cc].chosen) && (conn->time_pings[cc].sequence_number>9)) { + if ((conn->time_pings[cc].chosen) && (conn->time_pings[cc].sequence_number>(settling_time/3))) { uint64_t slt = conn->time_pings[cc].local_time>>12; if (slt > x_bar) @@ -734,8 +737,9 @@ void *rtp_timing_receiver(void *arg) { mtl = mtl + xid*yid; mbl = mbl + xid*xid; } - if (sample_count > 2) { - conn->local_to_remote_time_gradient = (1.0*mtl)/mbl; + conn->local_to_remote_time_gradient_sample_count = sample_count; + if (sample_count > sample_point_minimum) { + conn->local_to_remote_time_gradient = (1.0*mtl)/mbl; // debug(1,"Drift is %12.2f ppm, based on %d samples.",(1.0-conn->local_to_remote_time_gradient)*1000000,sample_count); } else { conn->local_to_remote_time_gradient = 1.0; @@ -971,13 +975,16 @@ int have_timestamp_timing_information(rtsp_conn_info *conn) { return 1; } +// set this to zero to use the rates supplied by the sources, which might not always be completely right... +const int use_nominal_rate = 1; // specify whether to use the nominal input rate, usually 44100 fps + int sanitised_source_rate_information(int64_t *frames, uint64_t *time, rtsp_conn_info *conn) { int result = 0; - *frames = conn->input_rate; + *frames = conn->input_rate; *time = (uint64_t)(0x100000000); // one second in fp form int64_t local_frames = conn->reference_to_previous_frame_difference; uint64_t local_time = conn->reference_to_previous_time_difference; - if ((local_frames == 0) || (local_time == 0)) { + if ((local_frames == 0) || (local_time == 0) || (use_nominal_rate)) { result = 1; } else { double calculated_frame_rate = ((1.0*local_frames)/local_time)*(uint64_t)0x100000000;