📄 refclock_irig.c
字号:
if (!io_addclock(&pp->io)) { (void)close(fd); free(up); return (0); } /* * Initialize miscellaneous variables */ peer->precision = PRECISION; pp->clockdesc = DESCRIPTION; memcpy((char *)&pp->refid, REFID, 4); up->tc = MINTC; up->decim = 1; up->fdelay = IRIG_B; up->gain = 127; /* * The companded samples are encoded sign-magnitude. The table * contains all the 256 values in the interest of speed. */ up->comp[0] = up->comp[OFFSET] = 0.; up->comp[1] = 1; up->comp[OFFSET + 1] = -1.; up->comp[2] = 3; up->comp[OFFSET + 2] = -3.; step = 2.; for (i = 3; i < OFFSET; i++) { up->comp[i] = up->comp[i - 1] + step; up->comp[OFFSET + i] = -up->comp[i]; if (i % 16 == 0) step *= 2.; } DTOLFP(1. / SECOND, &up->tick); return (1);}/* * irig_shutdown - shut down the clock */static voidirig_shutdown( int unit, /* instance number (not used) */ struct peer *peer /* peer structure pointer */ ){ struct refclockproc *pp; struct irigunit *up; pp = peer->procptr; up = (struct irigunit *)pp->unitptr; io_closeclock(&pp->io); free(up);}/* * irig_receive - receive data from the audio device * * This routine reads input samples and adjusts the logical clock to * track the irig clock by dropping or duplicating codec samples. */static voidirig_receive( struct recvbuf *rbufp /* receive buffer structure pointer */ ){ struct peer *peer; struct refclockproc *pp; struct irigunit *up; /* * Local variables */ double sample; /* codec sample */ u_char *dpt; /* buffer pointer */ int bufcnt; /* buffer counter */ l_fp ltemp; /* l_fp temp */ peer = (struct peer *)rbufp->recv_srcclock; pp = peer->procptr; up = (struct irigunit *)pp->unitptr; /* * Main loop - read until there ain't no more. Note codec * samples are bit-inverted. */ DTOLFP((double)rbufp->recv_length / SECOND, <emp); L_SUB(&rbufp->recv_time, <emp); up->timestamp = rbufp->recv_time; dpt = rbufp->recv_buffer; for (bufcnt = 0; bufcnt < rbufp->recv_length; bufcnt++) { sample = up->comp[~*dpt++ & 0xff]; /* * Clip noise spikes greater than MAXSIG. If no clips, * increase the gain a tad; if the clips are too high, * decrease a tad. */ if (sample > MAXSIG) { sample = MAXSIG; up->clipcnt++; } else if (sample < -MAXSIG) { sample = -MAXSIG; up->clipcnt++; } /* * Variable frequency oscillator. The codec oscillator * runs at the nominal rate of 8000 samples per second, * or 125 us per sample. A frequency change of one unit * results in either duplicating or deleting one sample * per second, which results in a frequency change of * 125 PPM. */ up->phase += up->freq / SECOND; up->phase += pp->fudgetime2 / 1e6; if (up->phase >= .5) { up->phase -= 1.; } else if (up->phase < -.5) { up->phase += 1.; irig_rf(peer, sample); irig_rf(peer, sample); } else { irig_rf(peer, sample); } L_ADD(&up->timestamp, &up->tick); /* * Once each second, determine the IRIG format and gain. */ up->seccnt = (up->seccnt + 1) % SECOND; if (up->seccnt == 0) { if (up->irig_b > up->irig_e) { up->decim = 1; up->fdelay = IRIG_B; } else { up->decim = 10; up->fdelay = IRIG_E; } irig_gain(peer); up->irig_b = up->irig_e = 0; } } /* * Set the input port and monitor gain for the next buffer. */ if (pp->sloppyclockflag & CLK_FLAG2) up->port = 2; else up->port = 1; if (pp->sloppyclockflag & CLK_FLAG3) up->mongain = MONGAIN; else up->mongain = 0;}/* * irig_rf - RF processing * * This routine filters the RF signal using a highpass filter for IRIG-B * and a lowpass filter for IRIG-E. In case of IRIG-E, the samples are * decimated by a factor of ten. The lowpass filter functions also as a * decimation filter in this case. Note that the codec filters function * as roofing filters to attenuate both the high and low ends of the * passband. IIR filter coefficients were determined using Matlab Signal * Processing Toolkit. */static voidirig_rf( struct peer *peer, /* peer structure pointer */ double sample /* current signal sample */ ){ struct refclockproc *pp; struct irigunit *up; /* * Local variables */ double irig_b, irig_e; /* irig filter outputs */ pp = peer->procptr; up = (struct irigunit *)pp->unitptr; /* * IRIG-B filter. 4th-order elliptic, 800-Hz highpass, 0.3 dB * passband ripple, -50 dB stopband ripple, phase delay .0022 * s) */ irig_b = (up->hpf[4] = up->hpf[3]) * 2.322484e-01; irig_b += (up->hpf[3] = up->hpf[2]) * -1.103929e+00; irig_b += (up->hpf[2] = up->hpf[1]) * 2.351081e+00; irig_b += (up->hpf[1] = up->hpf[0]) * -2.335036e+00; up->hpf[0] = sample - irig_b; irig_b = up->hpf[0] * 4.335855e-01 + up->hpf[1] * -1.695859e+00 + up->hpf[2] * 2.525004e+00 + up->hpf[3] * -1.695859e+00 + up->hpf[4] * 4.335855e-01; up->irig_b += irig_b * irig_b; /* * IRIG-E filter. 4th-order elliptic, 130-Hz lowpass, 0.3 dB * passband ripple, -50 dB stopband ripple, phase delay .0219 s. */ irig_e = (up->lpf[4] = up->lpf[3]) * 8.694604e-01; irig_e += (up->lpf[3] = up->lpf[2]) * -3.589893e+00; irig_e += (up->lpf[2] = up->lpf[1]) * 5.570154e+00; irig_e += (up->lpf[1] = up->lpf[0]) * -3.849667e+00; up->lpf[0] = sample - irig_e; irig_e = up->lpf[0] * 3.215696e-03 + up->lpf[1] * -1.174951e-02 + up->lpf[2] * 1.712074e-02 + up->lpf[3] * -1.174951e-02 + up->lpf[4] * 3.215696e-03; up->irig_e += irig_e * irig_e; /* * Decimate by a factor of either 1 (IRIG-B) or 10 (IRIG-E). */ up->badcnt = (up->badcnt + 1) % up->decim; if (up->badcnt == 0) { if (up->decim == 1) irig_base(peer, irig_b); else irig_base(peer, irig_e); }}/* * irig_base - baseband processing * * This routine processes the baseband signal and demodulates the AM * carrier using a synchronous detector. It then synchronizes to the * data frame at the baud rate and decodes the data pulses. */static voidirig_base( struct peer *peer, /* peer structure pointer */ double sample /* current signal sample */ ){ struct refclockproc *pp; struct irigunit *up; /* * Local variables */ double xxing; /* phase detector interpolated output */ double lope; /* integrator output */ double env; /* envelope detector output */ double dtemp; /* double temp */ pp = peer->procptr; up = (struct irigunit *)pp->unitptr; /* * Synchronous baud integrator. Corresponding samples of current * and past baud intervals are integrated to refine the envelope * amplitude and phase estimate. We keep one cycle of both the * raw and integrated data for later use. */ up->envphase = (up->envphase + 1) % BAUD; up->carphase = (up->carphase + 1) % CYCLE; up->integ[up->envphase] += (sample - up->integ[up->envphase]) / (5 * up->tc); lope = up->integ[up->envphase]; up->lastenv[up->carphase] = sample; up->lastint[up->carphase] = lope; /* * Phase detector. Sample amplitudes are integrated over the * baud interval. Cycle phase is determined from these * amplitudes using an eight-sample cyclic buffer. A phase * change of 360 degrees produces an output change of one unit. */ if (up->lastsig > 0 && lope <= 0) { xxing = lope / (up->lastsig - lope); up->zxing += (up->carphase - 4 + xxing) / CYCLE; } up->lastsig = lope; /* * Update signal/noise estimates and PLL phase/frequency. */ if (up->envphase == 0) { /* * Update envelope signal and noise estimates and mess * with error bits. */ up->maxsignal = up->intmax; up->noise = up->intmin; if (up->maxsignal < DRPOUT) up->errflg |= IRIG_ERR_AMP; if (up->maxsignal > 0) up->modndx = (up->intmax - up->intmin) / up->intmax; else up->modndx = 0; if (up->modndx < MODMIN) up->errflg |= IRIG_ERR_MOD; up->intmin = 1e6; up->intmax = 0; if (up->errflg & (IRIG_ERR_AMP | IRIG_ERR_FREQ | IRIG_ERR_MOD | IRIG_ERR_SYNCH)) { up->tc = MINTC; up->tcount = 0; } /* * Update PLL phase and frequency. The PLL time constant * is set initially to stabilize the frequency within a * minute or two, then increases to the maximum. The * frequency is clamped so that the PLL capture range * cannot be exceeded. */ dtemp = up->zxing * up->decim / BAUD; up->yxing = dtemp; up->zxing = 0.; up->phase += dtemp / up->tc; up->freq += dtemp / (4. * up->tc * up->tc); if (up->freq > MAXFREQ) { up->freq = MAXFREQ; up->errflg |= IRIG_ERR_FREQ; } else if (up->freq < -MAXFREQ) { up->freq = -MAXFREQ; up->errflg |= IRIG_ERR_FREQ; } } /* * Synchronous demodulator. There are eight samples in the cycle * and ten cycles in the baud interval. The amplitude of each * cycle is determined at the last sample in the cycle. The * beginning of the data pulse is determined from the integrated * samples, while the end of the pulse is determined from the * raw samples. The raw data bits are demodulated relative to * the slice level and left-shifted in the decoding register. */ if (up->carphase != 7) return; env = (up->lastenv[2] - up->lastenv[6]) / 2.; lope = (up->lastint[2] - up->lastint[6]) / 2.; if (lope > up->intmax) up->intmax = lope; if (lope < up->intmin) up->intmin = lope;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -