DSPRelated.com
Forums

Carrier recovery for FM demodulation

Started by shandilyasaurabh December 15, 2010
On Dec 18, 11:41&#4294967295;am, Vladimir Vassilevsky <nos...@nowhere.com> wrote:
> robert bristow-johnson wrote: > > On Dec 18, 12:41 am, "shandilyasaurabh" > > <saurabh.shandilya2010@n_o_s_p_a_m.gmail.com> wrote: > > >>I tried all combinations but phase differentiation using > >>(I*dQ-Q*dI)/(I^2+Q^2) > >>seems to be simple to implement with good performance. > > > the expression above isn't really meaningful in discrete-time. &#4294967295;if you > > were to approximate it with > > > &#4294967295; &#4294967295; &#4294967295;I[n]*(Q[n]-Q[n-1]) - Q[n]*(I[n]-I[n-1]) > > &#4294967295; &#4294967295; ----------------------------------------- > > &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295;(I[n])^2 + (Q[n])^2 > > > which is > > > &#4294967295; &#4294967295; &#4294967295; &#4294967295;Q[n]*I[n-1] - I[n]*Q[n-1] > > &#4294967295; &#4294967295; ------------------------------- > > &#4294967295; &#4294967295; &#4294967295; &#4294967295; &#4294967295; (I[n])^2 + (Q[n])^2 > > > that would be close, but not entirely accurate. &#4294967295;it should be > > > &#4294967295; &#4294967295; &#4294967295; &#4294967295;Q[n]*I[n-1] - I[n]*Q[n-1] > > &#4294967295; &#4294967295; ------------------------------- &#4294967295; &#4294967295;. > > &#4294967295; &#4294967295; &#4294967295; &#4294967295;I[n]*I[n-1] + Q[n]*Q[n-1] > > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > > There should be abs values in denominator.
i think, Vlad, what it needs is an arctan( ). (and i don't think it needs an abs( ). ) there is some trig identity, i think it's tan(x-y) = (tan(x) - tan(y))/(1 + tan(x)*tan(y)) you can arctan( ) both sides and get x - y = arctan( (tan(x) - tan(y))/(1 + tan(x)*tan(y)) ) define u = tan(x) v = tan(y) arctan(u) - arctan(v) = arctan( (u - v)/(1 + u*v) ) let u = Q[n]/I[n] v = Q[n-1]/I[n-1] omega[n] = arg{ I[n] + j*Q[n] } - arg{ I[n-1] + j*Q[n-1] } = arctan( Q[n]/I[n] ) - arctan( Q[n-1]/I[n-1] ) = arctan( (Q[n]*I[n-1] - I[n]*Q[n-1])/(I[n]*I[n-1] + Q[n]*Q[n-1]) ) all this is only guaranteed for when all of the angles are between +/-pi/2. another simpler way to look at it is: omega[n] = arg{ I[n] + j*Q[n] } - arg{ I[n-1] + j*Q[n-1] } = arg{ (I[n] + j*Q[n]) / (I[n-1] + j*Q[n-1]) } = arg{ (I[n] + j*Q[n]) * (I[n-1] - j*Q[n-1]) } = arg{(I[n]*I[n-1] + Q[n]*Q[n-1]) + j*(Q[n]*I[n-1] - I[n]*Q[n-1])} = arctan( (Q[n]*I[n-1] - I[n]*Q[n-1])/(I[n]*I[n-1] + Q[n]*Q[n-1]) ) i think this only requires -pi/2 < omega[n] < +pi/2, so it's a better way to look at it.
> How about this? > > &#4294967295; 1 &#4294967295; &#4294967295; &#4294967295;Q[n]I[n-2] - I[n]Q[n-2] > &#4294967295; - &#4294967295;x &#4294967295;------------------------- > &#4294967295; 2 &#4294967295; &#4294967295; &#4294967295;I[n-1]^2 &#4294967295;+ Q[n-1]^2
looks okay for omega[n-1] ( whereas mine looks like it should be for omega[n - 1/2] ) and it might also be missing the arctan( ), which is small potatoes if the difference in angle is small. r b-j
http://www.digitalsignallabs.com/fm.htm

--Randy

On 12/18/2010 11:33 PM, robert bristow-johnson wrote:
> On Dec 18, 11:41 am, Vladimir Vassilevsky<nos...@nowhere.com> wrote: >> robert bristow-johnson wrote: >>> On Dec 18, 12:41 am, "shandilyasaurabh" >>> <saurabh.shandilya2010@n_o_s_p_a_m.gmail.com> wrote: >> >>>> I tried all combinations but phase differentiation using >>>> (I*dQ-Q*dI)/(I^2+Q^2) >>>> seems to be simple to implement with good performance. >> >>> the expression above isn't really meaningful in discrete-time. if you >>> were to approximate it with >> >>> I[n]*(Q[n]-Q[n-1]) - Q[n]*(I[n]-I[n-1]) >>> ----------------------------------------- >>> (I[n])^2 + (Q[n])^2 >> >>> which is >> >>> Q[n]*I[n-1] - I[n]*Q[n-1] >>> ------------------------------- >>> (I[n])^2 + (Q[n])^2 >> >>> that would be close, but not entirely accurate. it should be >> >>> Q[n]*I[n-1] - I[n]*Q[n-1] >>> ------------------------------- . >>> I[n]*I[n-1] + Q[n]*Q[n-1] >> >> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >> >> There should be abs values in denominator. > > i think, Vlad, what it needs is an arctan( ). (and i don't think it > needs an abs( ). ) > > there is some trig identity, i think it's > > tan(x-y) = (tan(x) - tan(y))/(1 + tan(x)*tan(y)) > > you can arctan( ) both sides and get > > x - y = arctan( (tan(x) - tan(y))/(1 + tan(x)*tan(y)) ) > > define u = tan(x) v = tan(y) > > arctan(u) - arctan(v) = arctan( (u - v)/(1 + u*v) ) > > > > let u = Q[n]/I[n] v = Q[n-1]/I[n-1] > > omega[n] = arg{ I[n] + j*Q[n] } - arg{ I[n-1] + j*Q[n-1] } > > = arctan( Q[n]/I[n] ) - arctan( Q[n-1]/I[n-1] ) > > = arctan( (Q[n]*I[n-1] - I[n]*Q[n-1])/(I[n]*I[n-1] + Q[n]*Q[n-1]) ) > > all this is only guaranteed for when all of the angles are between > +/-pi/2. > > another simpler way to look at it is: > > omega[n] = arg{ I[n] + j*Q[n] } - arg{ I[n-1] + j*Q[n-1] } > > = arg{ (I[n] + j*Q[n]) / (I[n-1] + j*Q[n-1]) } > > = arg{ (I[n] + j*Q[n]) * (I[n-1] - j*Q[n-1]) } > > = arg{(I[n]*I[n-1] + Q[n]*Q[n-1]) + j*(Q[n]*I[n-1] - I[n]*Q[n-1])} > > = arctan( (Q[n]*I[n-1] - I[n]*Q[n-1])/(I[n]*I[n-1] + Q[n]*Q[n-1]) ) > > i think this only requires -pi/2< omega[n]< +pi/2, so it's a better > way to look at it. > >> How about this? >> >> 1 Q[n]I[n-2] - I[n]Q[n-2] >> - x ------------------------- >> 2 I[n-1]^2 + Q[n-1]^2 > > looks okay for omega[n-1] > > ( whereas mine looks like it should be for omega[n - 1/2] ) > > and it might also be missing the arctan( ), which is small potatoes if > the difference in angle is small. > > r b-j
-- Randy Yates % "My Shangri-la has gone away, fading like Digital Signal Labs % the Beatles on 'Hey Jude'" yates@digitalsignallabs.com % http://www.digitalsignallabs.com % 'Shangri-La', *A New World Record*, ELO
On 12/18/2010 10:49 AM, robert bristow-johnson wrote:
> On Dec 18, 12:41 am, "shandilyasaurabh" > <saurabh.shandilya2010@n_o_s_p_a_m.gmail.com> wrote: >> I tried all combinations but phase differentiation using >> (I*dQ-Q*dI)/(I^2+Q^2) >> seems to be simple to implement with good performance. > > the expression above isn't really meaningful in discrete-time.
With the understanding that "dX" means "dX/dt", why not? The only question is, how do you get "dX" from "X" in discrete time. -- Randy Yates % "My Shangri-la has gone away, fading like Digital Signal Labs % the Beatles on 'Hey Jude'" yates@digitalsignallabs.com % http://www.digitalsignallabs.com % 'Shangri-La', *A New World Record*, ELO
On Dec 19, 10:51&#4294967295;am, Randy Yates <ya...@ieee.org> wrote:
> On 12/18/2010 10:49 AM, robert bristow-johnson wrote: > > > On Dec 18, 12:41 am, "shandilyasaurabh" > > <saurabh.shandilya2010@n_o_s_p_a_m.gmail.com> &#4294967295;wrote: > >> I tried all combinations but phase differentiation using > >> (I*dQ-Q*dI)/(I^2+Q^2) > >> seems to be simple to implement with good performance. > > > the expression above isn't really meaningful in discrete-time. > > With the understanding that "dX" means "dX/dt", why not? The > only question is, how do you get "dX" from "X" in discrete > time.
sure, but then it's a different expression. he didn't code no dQ nor dI into MATLAB. dx is infinitesimally small while x[n] - x[n-1] is not. but it might be the best approximation (with a scale factor) for dx that we can get in a discrete and real-time system. the equation for omega[n] that i posted is one for the finite displacement of phase angle, phi[n] - phi[n-1]. it's not precisely the instantaneous frequency, but if you accumulate omega[n] (discrete- time "integration"), you get exactly the phase back. r b-j

robert bristow-johnson wrote:


> the equation for omega[n] that i posted is one for the finite > displacement of phase angle, phi[n] - phi[n-1]. it's not precisely > the instantaneous frequency, but if you accumulate omega[n] (discrete- > time "integration"), you get exactly the phase back.
If using atan(), then the finite difference instead of derivative will result in the linear distortion, i.e. high frequency rolloff. This wouldn't be a big deal; BUT the atan() should be accurate enough so it would not introduce the nonlinearity. Approximation of atan2() to 16 bits or so is no cheap. The idea is get rid of atan and calculate IdQ - QdI. However now the derivatives must be accurate. The second order approximation of derivatives is better then the first difference and as easy to compute: (I[0]-I[2])Q[1] - (Q[0] - Q[2))I[1] So here we go. As for denominator, I^2 + Q^2 supposed to be the constant amplitude^2 which is taken care off by AGC (unless instant clipping is preferred). Vladimir Vassilevsky DSP and Mixed Signal Design Consultant http://www.abvolt.com
On Dec 19, 3:19&#4294967295;pm, Vladimir Vassilevsky <nos...@nowhere.com> wrote:
> robert bristow-johnson wrote: > > the equation for omega[n] that i posted is one for the finite > > displacement of phase angle, phi[n] - phi[n-1]. &#4294967295;it's not precisely > > the instantaneous frequency, but if you accumulate omega[n] (discrete- > > time "integration"), you get exactly the phase back. > > If using atan(), then the finite difference instead of derivative will > result in the linear distortion, i.e. high frequency rolloff.
right, i think it is a linear distortion if (d/dt)p(t) = m*x(t) s*P(s) = m*X(s) I(t) + j*Q(t) = exp(j*p(t)) I(t) = cos(p(t)) = cos( m*integral{x(t) dt} ) Q(t) = sin(p(t)) = sin( m*integral{x(t) dt} ) (m is the modulation index and has dimension of 1/time.) omega[n] = arctan( (Q[n]*I[n-1] - I[n]*Q[n-1]) / I[n]*I[n-1] + Q[n]*Q[n-1] ) or omega(nT) = arctan( (Q(nT)*I(nT-T) - I(nT)*Q(nT-T)) / (I(nT)*I(nT-T) + Q(nT)*Q(nT-T)) ) = arctan( sin(p(nT) - p(nT-T)) / cos(p(nT) - p(nT-T)) ) = arctan( tan(p(nT) - p(nT-T)) ) = p(nT) - p(nT-T) can we say this can be generalized as: omega(t) = p(t) - p(t-T) ? Omega(s) = FT{ omega(t) } = (1 - e^(-sT))*P(s) = (1 - e^(-sT))*(m/s)*X(s) = m*T * (1 - e^(-sT))/(sT) * X(s) so, assuming no aliasing, the audio waveform i create from the samples is an LTI filtered and scaled copy of the input audio for FM. now, what if i construct by some combination of I[n] and Q[n] without the arctan()? might not there be some non-linear distortion.
> This > wouldn't be a big deal; BUT the atan() should be accurate enough so it > would not introduce the nonlinearity. Approximation of atan2() to 16 > bits or so is no cheap.
okay. depends on how big the argument to arctan() is. and i don't think it has to be the two quadrant thing if you start with a limited difference anyway. but my point is, isn't *any* linear alg operating on I[n], I[n-1], etc. and Q[n], Q[n-1], etc. without arctan() in there somewhere going to come up with a signal that has tan() implicitly applied? i think that first-order approximation arctan(u) = u will have more distortion than either some table-lookup (with linear interpolation) or power series approximation, even for small u.
> The idea is get rid of atan and calculate IdQ - QdI.
but you can't get dQ exactly nor dI. them's ain't discrete-time quantities you have at your disposal.
> However now the derivatives must be accurate. > The second order approximation of derivatives is better then the first > difference and as easy to compute: (I[0]-I[2])Q[1] - (Q[0] - Q[2))I[1] > So here we go. As for denominator, I^2 + Q^2 supposed to be the constant > &#4294967295; amplitude^2 which is taken care off by AGC (unless instant clipping is > preferred).
but, to compare apples to apples, what does the AGC do to the quadrature signal. what little ripples might you see in the I^2 + Q^2 signal? express your differentials as the finite differences of the alg and plug in the actual I(nT) and Q(nT) and see what you get as a function of x(nT) (and past samples). i think that the missing arctan will result in some kinda non-linear distortion that gets smaller as T gets smaller. but the other way makes no assumption on T and has no non- linear distortion for any reasonable T but a *linear* filter rolloff that can be compensated with a simple filter (and more delay). no? i dunno. i should think about this a little more. i just have to think that the arctan() has to come in there somewhere to keep the inherent tan() distortion from happening. all this is with the assumption of no noise. dunno which way is better when I and Q get uncorrelated additive noise. r b-j
On Dec 19, 8:50=A0pm, robert bristow-johnson <r...@audioimagination.com>
wrote:
> On Dec 19, 3:19=A0pm, Vladimir Vassilevsky <nos...@nowhere.com> wrote: > > > robert bristow-johnson wrote: > > > the equation for omega[n] that i posted is one for the finite > > > displacement of phase angle, phi[n] - phi[n-1]. =A0it's not precisely > > > the instantaneous frequency, but if you accumulate omega[n] (discrete=
-
> > > time "integration"), you get exactly the phase back. > > > If using atan(), then the finite difference instead of derivative will > > result in the linear distortion, i.e. high frequency rolloff. >
...
> > =A0 =A0(d/dt)p(t) =3D m*x(t) > > =A0 =A0s*P(s) =3D m*X(s) > > =A0 =A0I(t) + j*Q(t) =3D exp(j*p(t)) > > =A0 =A0I(t) =3D cos(p(t)) > =A0 =A0Q(t) =3D sin(p(t)) > > (m is the modulation index and has dimension of 1/time.) >
...
> > express your differentials as the finite differences of the alg and > plug in the actual I(nT) and Q(nT) and see what you get as a function > of x(nT) (and past samples).
okay, so i'll do it. 1 Q[n]I[n-2] - I[n]Q[n-2] - x ------------------------- 2 I[n-1]^2 + Q[n-1]^2 is (1/2)*sin(p(nT) - p(nT-2T)) so you have to apply some (1/2)*arcsin(2*u) correction to that, then you get (1/2)*(p(nT) - p(nT-2T)) which is m*T * (1 - e^(-2sT))/(2sT) * X(s) which is even more LPF sinc-like filtering. i'm wondering, given the issues you bring up, Vlad, why your expression is better. it has more LPF filtering than mine, and your missing an arcsin() function, implying that there is linear distortion added before you would compensate with the un-sinc filter. r b-j