Or in DttSP:

void
correctIQ(CXB sigbuf, IQ iq) {
int i;
for (i = 0; i < CXBhave(sigbuf); i++) {
CXBimag(sigbuf, i) += iq->phase * CXBreal(sigbuf, i);
CXBreal(sigbuf, i) *= iq->gain;
}
}


On 11/21/05, Jim Lux <[EMAIL PROTECTED]> wrote:
At 05:05 AM 11/21/2005, Philip Covington wrote:
>unsafe public void DoIQCorrection(float* real, float* imag, Receiver state)
>         {
>             for (int i = 0; i < this.size; i++)
>             {
>                 imag[i] += real[i] * state.IQPhaseValue;
>                 real[i] *= (1.0F + state.IQGainValue);
>             }
>         }

Is this in time or frequency domain?

I haven't worked through the algebra to see if they are equivalent, but I
would have thought you'd have something that would take 4 (real) multiplies
and possibly some adds?  Don't you want to change the signal you've
measured with two non-orthogonal basis vectors into something orthogonal
and scaled identically.


That is, you've got to compensate for the difference in gain between I and
Q, and also the phase shift.. the latter usually requiring a rotation of
the vector, which, in general, is a 2x2 matrix multiply.  qnew =
qold*cos(theta)+iold*sin(theta); inew=iold*cos(theta)-qold*sin(theta) or
something like that (I might have the signs backwards.. the coffee hasn't
had time to work yet)


I can see how scaling either imaginary or real can accomplish this
(essentially ignoring an overall gain term), but the adding a piece of the
real to the imaginary seems incorrect (unless the phase error is small
enough that the small angle approximation (sin(theta)=theta) is valid).  If
you're looking for 40 dB rejection though, your errors have got to be down
in the <0.01 area (half a degree) for this to work.




--
Philip A Covington
http://www.philcovington.com



Reply via email to