FreeBSD/contrib/ntp/ntpd/refclock_wwv.c
/*
 * wwv_qrz - identify and acquire WWV/WWVH minute sync pulse
 *
 * This routine implements a virtual station process used to acquire
 * minute sync and to mitigate among the ten frequency and station
 * combinations. During minute sync acquisition the process probes each
 * frequency and station in turn for the minute pulse, which
 * involves searching through the entire 480,000-sample minute. The
 * process finds the maximum signal and RMS noise plus signal. Then, the
 * actual noise is determined by subtracting the energy of the matched
 * filter.
 *
 * Students of radar receiver technology will discover this algorithm
 * amounts to a range-gate discriminator. A valid pulse must have peak
 * amplitude at least QTHR (2500) and SNR at least QSNR (20) dB and the
 * difference between the current and previous epoch must be less than
 * AWND (20 ms). Note that the discriminator peak occurs about 800 ms
 * into the second, so the timing is retarded to the previous second
 * epoch.
 */
identify and acquire WWV/WWVH minute sync pulse
This routine implements a virtual station process used to acquire
minute sync and to mitigate among the ten frequency and station
combinations. During minute sync acquisition the process probes each
frequency and station in turn for the minute pulse, which
involves searching through the entire 480,000-sample minute. The
process finds the maximum signal and RMS noise plus signal. Then, the
actual noise is determined by subtracting the energy of the matched
filter.

Students of radar receiver technology will discover this algorithm
amounts to a range-gate discriminator. A valid pulse must have peak
amplitude at least QTHR (2500) and SNR at least QSNR (20) dB and the
difference between the current and previous epoch must be less than
AWND (20 ms). Note that the discriminator peak occurs about 800 ms
into the second, so the timing is retarded to the previous second
epoch.
identify and acquire WWV / WWVH minute sync pulse This routine implements a virtual station process used to acquire minute sync and to mitigate among the ten frequency and station combinations . During minute sync acquisition the process probes each frequency and station in turn for the minute pulse which involves searching through the entire 480 000 - sample minute . The process finds the maximum signal and RMS noise plus signal . Then the actual noise is determined by subtracting the energy of the matched filter . Students of radar receiver technology will discover this algorithm amounts to a range - gate discriminator . A valid pulse must have peak amplitude at least QTHR ( 2500 ) and SNR at least QSNR ( 20 ) dB and the difference between the current and previous epoch must be less than AWND ( 20 ms ) . Note that the discriminator peak occurs about 800 ms into the second so the timing is retarded to the previous second epoch .
static void
wwv_qrz(
	struct peer *peer,	
	struct sync *sp,	
	int	pdelay		
	)
{
	struct refclockproc *pp;
	struct wwvunit *up;
	char	tbuf[TBUF];	
	long	epoch;
	pp = peer->procptr;
	up = pp->unitptr;
	epoch = up->mphase - pdelay - SYNSIZ;
	if (epoch < 0)
		epoch += WWV_MIN;
	if (sp->amp > sp->maxeng) {
		sp->maxeng = sp->amp;
		sp->pos = epoch;
	}
	sp->noieng += sp->amp;
	if (up->mphase == 0) {
		sp->synmax = sp->maxeng;
		sp->synsnr = wwv_snr(sp->synmax, (sp->noieng -
		    sp->synmax) / WWV_MIN);
		if (sp->count == 0)
			sp->lastpos = sp->pos;
		epoch = (sp->pos - sp->lastpos) % WWV_MIN;
		sp->reach <<= 1;
		if (sp->reach & (1 << AMAX))
			sp->count--;
		if (sp->synmax > ATHR && sp->synsnr > ASNR) {
			if (labs(epoch) < AWND * MS) {
				sp->reach |= 1;
				sp->count++;
				sp->mepoch = sp->lastpos = sp->pos;
			} else if (sp->count == 1) {
				sp->lastpos = sp->pos;
			}
		}
		if (up->watch > ACQSN)
			sp->metric = 0;
		else
			sp->metric = wwv_metric(sp);
		if (pp->sloppyclockflag & CLK_FLAG4) {
			snprintf(tbuf, sizeof(tbuf),
			    "wwv8 %04x %3d %s %04x %.0f %.0f/%.1f %ld %ld",
			    up->status, up->gain, sp->refid,
			    sp->reach & 0xffff, sp->metric, sp->synmax,
			    sp->synsnr, sp->pos % WWV_SEC, epoch);
			record_clock_stats(&peer->srcadr, tbuf);
#ifdef DEBUG
			if (debug)
				printf("%s\n", tbuf);
#endif 
		}
		sp->maxeng = sp->noieng = 0;
	}
}
static void wwv_qrz ( struct peer * peer , struct sync * sp , int pdelay ) { struct refclockproc * pp ; struct wwvunit * up ; char tbuf [ TBUF ] ; long epoch ; pp = peer -> procptr ; up = pp -> unitptr ; epoch = up -> mphase - pdelay - SYNSIZ ; if ( epoch < 0 ) epoch += WWV_MIN ; if ( sp -> amp > sp -> maxeng ) { sp -> maxeng = sp -> amp ; sp -> pos = epoch ; } sp -> noieng += sp -> amp ; if ( up -> mphase == 0 ) { sp -> synmax = sp -> maxeng ; sp -> synsnr = wwv_snr ( sp -> synmax , ( sp -> noieng - sp -> synmax ) / WWV_MIN ) ; if ( sp -> count == 0 ) sp -> lastpos = sp -> pos ; epoch = ( sp -> pos - sp -> lastpos ) % WWV_MIN ; sp -> reach <<= 1 ; if ( sp -> reach & ( 1 << AMAX ) ) sp -> count -- ; if ( sp -> synmax > ATHR && sp -> synsnr > ASNR ) { if ( labs ( epoch ) < AWND * MS ) { sp -> reach |= 1 ; sp -> count ++ ; sp -> mepoch = sp -> lastpos = sp -> pos ; } else if ( sp -> count == 1 ) { sp -> lastpos = sp -> pos ; } } if ( up -> watch > ACQSN ) sp -> metric = 0 ; else sp -> metric = wwv_metric ( sp ) ; if ( pp -> sloppyclockflag & CLK_FLAG4 ) { snprintf ( tbuf , sizeof ( tbuf ) , " " , up -> status , up -> gain , sp -> refid , sp -> reach & 0xffff , sp -> metric , sp -> synmax , sp -> synsnr , sp -> pos % WWV_SEC , epoch ) ; record_clock_stats ( & peer -> srcadr , tbuf ) ; #ifdef DEBUG if ( debug ) printf ( " \n " , tbuf ) ; #endif } sp -> maxeng = sp -> noieng = 0 ; } }
wwv_qrz - identify and acquire WWV/WWVH minute sync pulse
 This routine implements a virtual station process used to acquire
 minute sync and to mitigate among the ten frequency and station
 combinations.
wwv_qrz - identify and acquire WWV / WWVH minute sync pulse This routine implements a virtual station process used to acquire minute sync and to mitigate among the ten frequency and station combinations .
/* peer structure pointer */ /* sync channel structure */ /* propagation delay (samples) */ /* monitor buffer */ /*
	 * Find the sample with peak amplitude, which defines the minute
	 * epoch. Accumulate all samples to determine the total noise
	 * energy.
	 */ /*
	 * At the end of the minute, determine the epoch of the minute
	 * sync pulse, as well as the difference between the current and
	 * previous epoches due to the intrinsic frequency error plus
	 * jitter. When calculating the SNR, subtract the pulse energy
	 * from the total noise energy and then normalize.
	 */ /* DEBUG */