6 /*------------------------------------------------------------------------------*/
8 /*------------------------------------------------------------------------------*/
17 REAL fac = TWOPI / samprate;
18 am->pll.freq.f = freq * fac;
19 am->pll.freq.l = lofreq * fac;
20 am->pll.freq.h = hifreq * fac;
24 am->pll.iir.alpha = bandwidth * fac; /* arm filter */
25 am->pll.alpha = am->pll.iir.alpha * 0.3; /* pll bandwidth */
26 am->pll.beta = am->pll.alpha * am->pll.alpha * 0.25; /* second order term */
27 am->pll.fast_alpha = am->pll.alpha;
31 pll(AMD am, COMPLEX sig) {
32 COMPLEX z = Cmplx(cos(am->pll.phs), sin(am->pll.phs));
35 am->pll.delay.re = z.re * sig.re + z.im * sig.im;
36 am->pll.delay.im = -z.im * sig.re + z.re * sig.im;
37 diff = Cmag(sig) * ATAN2(am->pll.delay.im, am->pll.delay.re);
39 am->pll.freq.f += am->pll.beta * diff;
41 if (am->pll.freq.f < am->pll.freq.l)
42 am->pll.freq.f = am->pll.freq.l;
43 if (am->pll.freq.f > am->pll.freq.h)
44 am->pll.freq.f = am->pll.freq.h;
46 am->pll.phs += am->pll.freq.f + am->pll.alpha * diff;
48 while (am->pll.phs >= TWOPI) am->pll.phs -= TWOPI;
49 while (am->pll.phs < 0) am->pll.phs += TWOPI;
54 am->lock.curr = 0.999 * am->lock.curr + 0.001 * fabs(am->pll.delay.im);
57 /* if ((am->lock.curr < 0.05) && (am->lock.prev >= 0.05)) {
58 am->pll.alpha = 0.1 * am->pll.fast_alpha;
59 am->pll.beta = am->pll.alpha * am->pll.alpha * 0.25;
60 } else if ((am->pll.alpha > 0.05) && (am->lock.prev <= 0.05)) {
61 am->pll.alpha = am->pll.fast_alpha;
63 am->lock.prev = am->lock.curr;
64 am->dc = 0.99*am->dc + 0.01*am->pll.delay.re;
65 return am->pll.delay.re-am->dc;
68 /*------------------------------------------------------------------------------*/
70 /*------------------------------------------------------------------------------*/
78 for (i = 0; i < am->size; i++) {
79 pll(am, CXBdata(am->ibuf, i));
81 CXBdata(am->obuf, i) = Cmplx(demout, demout);
85 for (i = 0; i < am->size; i++) {
86 am->lock.curr = Cmag(CXBdata(am->ibuf, i));
87 am->dc = 0.9999 * am->dc + 0.0001 * am->lock.curr;
88 am->smooth = 0.5 * am->smooth + 0.5 * (am->lock.curr - am->dc);
89 /* demout = am->smooth; */
90 CXBdata(am->obuf, i) = Cmplx(am->smooth, am->smooth);
107 AMD am = (AMD) safealloc(1, sizeof(AMDDesc), tag);
110 am->ibuf = newCXB(size, ivec, tag);
111 am->obuf = newCXB(size, ovec, tag);
132 safefree((char *) am);