void correctIQ (CXB sigbuf, IQ iq, BOOLEAN isTX, int subchan) { int i; REAL doit; if (IQdoit == 0) return; if (subchan == 0) doit = iq->mu; else doit = 0; if(!isTX) { // if (subchan == 0) // removed so that sub rx's will get IQ correction for (i = 0; i < CXBhave (sigbuf); i++) { iq->del[iq->index] = CXBdata(sigbuf,i); iq->y[iq->index] = Cadd(iq->del[iq->index],Cmul(iq->w[0],Conjg(iq->del[iq->index]))); iq->y[iq->index] = Cadd(iq->y[iq->index],Cmul(iq->w[1],Conjg(iq->y[iq->index]))); iq->w[1] = Csub(iq->w[1], Cscl(Cmul(iq->y[iq->index],iq->y[iq->index]), doit)); // this is where the adaption happens CXBdata(sigbuf,i)=iq->y[iq->index]; iq->index = (iq->index+iq->MASK)&iq->MASK; } //fprintf(stderr, "w1 real: %g, w1 imag: %g\n", iq->w[1].re, iq->w[1].im); fflush(stderr); } else { for (i = 0; i < CXBhave (sigbuf); i++) { CXBimag (sigbuf, i) += iq->phase * CXBreal (sigbuf, i); CXBreal (sigbuf, i) *= iq->gain; } } }
void fixrts(float d[], int m) { void zroots(fcomplex a[], int m, fcomplex roots[], int polish); int i,j,polish; fcomplex a[NMAX],roots[NMAX]; a[m]=ONE; for (j=m-1;j>=0;j--) a[j]=Complex(-d[m-j],0.0); polish=1; zroots(a,m,roots,polish); for (j=1;j<=m;j++) if (Cabs(roots[j]) > 1.0) roots[j]=Cdiv(ONE,Conjg(roots[j])); a[0]=Csub(ZERO,roots[1]); a[1]=ONE; for (j=2;j<=m;j++) { a[j]=ONE; for (i=j;i>=2;i--) a[i-1]=Csub(a[i-2],Cmul(roots[j],a[i-1])); a[0]=Csub(ZERO,Cmul(roots[j],a[0])); } for (j=0;j<=m-1;j++) d[m-j] = -a[j].r; }
void blms_adapt (BLMS blms) { int sigsize = CXBhave (blms->signal); int sigidx = 0; // fputs("Inside\n",stderr),fflush(stderr); do { int j; memcpy (blms->delay_line, &blms->delay_line[128], sizeof (COMPLEX) * 128); // do overlap move memcpy (&blms->delay_line[128], &CXBdata (blms->signal, sigidx), sizeof (COMPLEX) * 128); // copy in new data fftwf_execute (blms->Xplan); // compute transform of input data for (j = 0; j < 256; j++) { blms->Yhat[j] = Cmul (blms->What[j], blms->Xhat[j]); // Filter new signal in freq. domain blms->Xhat[j] = Conjg (blms->Xhat[j]); // take input data's complex conjugate } fftwf_execute (blms->Yplan); //compute output signal transform for (j = 128; j < 256; j++) blms->y[j] = Cscl (blms->y[j], BLKSCL); memset (blms->y, 0, 128 * sizeof (COMPLEX)); for (j = 128; j < 256; j++) blms->error[j] = Csub (blms->delay_line[j], blms->y[j]); // compute error signal if (blms->filter_type) memcpy (&CXBdata (blms->signal, sigidx), &blms->y[128], 128 * sizeof (COMPLEX)); // if noise filter, output y else memcpy (&CXBdata (blms->signal, sigidx), &blms->error[128], 128 * sizeof (COMPLEX)); // if notch filter, output error fftwf_execute (blms->Errhatplan); // compute transform of the error signal for (j = 0; j < 256; j++) blms->Errhat[j] = Cmul (blms->Errhat[j], blms->Xhat[j]); // compute cross correlation transform fftwf_execute (blms->UPDplan); // compute inverse transform of cross correlation transform for (j = 0; j < 128; j++) blms->update[j] = Cscl (blms->update[j], BLKSCL); memset (&blms->update[128], 0, sizeof (COMPLEX) * 128); // zero the last block of the update, so we get // filter coefficients only at front of buffer fftwf_execute (blms->Wplan); for (j = 0; j < 256; j++) { blms->What[j] = Cadd (Cscl (blms->What[j], blms->leak_rate), // leak the W away Cscl (blms->Update[j], blms->adaptation_rate)); // update at adaptation rate } sigidx += 128; // move to next block in the signal buffer } while (sigidx < sigsize); // done? }