From: Harlan Stenn Date: Thu, 24 Oct 2002 03:30:41 +0000 (-0400) Subject: Changes from Dave Mills. Sawtooth filter for audio IRIG, mainly. X-Git-Tag: NTP_4_1_73~32 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=036147cfe1069852bd1245072d74ab447761e1fc;p=thirdparty%2Fntp.git Changes from Dave Mills. Sawtooth filter for audio IRIG, mainly. bk: 3db76961qOL8YXKuYKUvwcuDq8h5Kw --- diff --git a/ntpd/ntp_proto.c b/ntpd/ntp_proto.c index 017f653e9a..cf8a33f689 100644 --- a/ntpd/ntp_proto.c +++ b/ntpd/ntp_proto.c @@ -1884,7 +1884,7 @@ clock_select(void) */ low = 1e9; high = -1e9; - for (allow = 0; allow < nlist / 2; allow++) { + for (allow = 0; 2 * allow < nlist; allow++) { int found; /* diff --git a/ntpd/ntp_request.c b/ntpd/ntp_request.c index 0aced1f87a..61c664c310 100644 --- a/ntpd/ntp_request.c +++ b/ntpd/ntp_request.c @@ -2636,7 +2636,7 @@ get_clock_info( ic->timestarted = htonl((u_int32)clock_stat.timereset); DTOLFP(clock_stat.fudgetime1, <mp); HTONL_FP(<mp, &ic->fudgetime1); - DTOLFP(clock_stat.fudgetime1, <mp); + DTOLFP(clock_stat.fudgetime2, <mp); HTONL_FP(<mp, &ic->fudgetime2); ic->fudgeval1 = htonl((u_int32)clock_stat.fudgeval1); ic->fudgeval2 = htonl((u_int32)clock_stat.fudgeval2); diff --git a/ntpd/refclock_irig.c b/ntpd/refclock_irig.c index e9f40cd04b..e34c405994 100644 --- a/ntpd/refclock_irig.c +++ b/ntpd/refclock_irig.c @@ -97,9 +97,9 @@ * * The timecode format used for debugging and data recording includes * data helpful in diagnosing problems with the IRIG signal and codec - * connections. With debugging enabled (-d -d -d on the ntpd command - * line), the driver produces one line for each timecode in the - * following format: + * connections. With debugging enabled (-d on the ntpd command line), + * the driver produces one line for each timecode in the following + * format: * * 00 1 98 23 19:26:52 721 143 0.694 20 0.1 66.5 3094572411.00027 * @@ -116,9 +116,13 @@ * timestamp in NTP format. * * The fraction part of the on-time timestamp is a good indicator of how - * well the driver is doing. With an UltrSPARC 30, this thing can keep - * the clock within a few tens of microseconds relative to the IRIG-B - * signal. Accuracy with IRIG-E is about ten times worse. + * well the driver is doing. With an UltrSPARC 30 and Solaris 2.7, this + * thing can keep the clock within a few tens of microseconds relative + * to the IRIG-B signal. Accuracy with IRIG-E is about ten times worse. + * Unfortunately, Sun broke the 2.7 audio driver in 2.8, which has a + * 10-ms sawtooth modulation. The driver attempts to remove the + * modulation by some clever estimation techniques which mostly work. + * Your experience may vary. * * Unlike other drivers, which can have multiple instantiations, this * one supports only one. It does not seem likely that more than one @@ -246,6 +250,9 @@ struct irigunit { int fieldcnt; /* subfield count in field */ int bits; /* demodulated bits */ int bitcnt; /* bit count in subfield */ + l_fp waggle; /* sawtooth accumulator (s) */ + l_fp wiggle; /* sawtooth correction (s) */ + l_fp wuggle; /* sawtooth monitor (s) */ }; /* @@ -822,7 +829,64 @@ irig_decode( up->fieldcnt = 0; up->lastbit = 0; if (up->errflg == 0) { - refclock_process(pp); + l_fp ltemp, mtemp; + + /* + * You didn't see this; I wasn't here. + * + * Recent Sun kernels have developed an evil + * 10-ms sawtooth modulation that ruined what + * once was an excellent, low-jitter time + * reference. This code tries to unmodulate the + * sawtooth by using each measured time + * difference to estimate the next one as the + * sawtooth amplitude increases with time. Upon + * retrace, the accumulated difference relative + * to the current offset is uset to interpolate + * and produce an unbiased result. + * + * It's important to remember these samples are + * processed by the median filter, which tosses + * out noisy samples and averages the rest. This + * just helps reduce the jitter and leave at + * least some good samples for the middle of the + * filter. + */ + mtemp = pp->lastrec; + if (L_ISZERO(&pp->lastrec) || + L_ISZERO(&pp->lastref)) { + L_CLR(<emp); + } else { + ltemp = pp->lastrec; + L_SUB(<emp, &pp->lastref); + } + if (ltemp.l_f < 0) + ltemp.l_i = -1; + else + ltemp.l_i = 0; + L_SUB(&pp->lastrec, &up->waggle); + if (!L_ISNEG(<emp)) { + L_ADD(<emp, &up->waggle); + up->waggle = ltemp; + } else { + L_SUB(<emp, &up->wiggle); + if (L_ISNEG(<emp)) { + L_NEG(<emp); + L_RSHIFT(<emp); + L_RSHIFT(<emp); + L_RSHIFT(<emp); + L_NEG(<emp); + } else { + L_RSHIFT(<emp); + L_RSHIFT(<emp); + L_RSHIFT(<emp); + } + L_ADD(&up->wiggle, <emp); + L_ADD(&up->waggle, &up->wiggle); + refclock_process(pp); + up->wuggle = pp->lastrec; + } + pp->lastrec = mtemp; pp->lastref = pp->lastrec; } up->errflg = 0; @@ -880,7 +944,7 @@ irig_decode( pp->hour, pp->minute, pp->second, up->maxsignal, up->gain, up->modndx, up->tc, up->exing * 1e6 / SECOND, up->freq * - 1e6 / SECOND, ulfptoa(&pp->lastrec, 6)); + 1e6 / SECOND, ulfptoa(&up->wuggle, 6)); pp->lencode = strlen(pp->a_lastcode); if (pp->sloppyclockflag & CLK_FLAG4) { record_clock_stats(&peer->srcadr,