DSPRelated.com
Forums

A Stupid FM Demod Question?

Started by Randy Yates April 3, 2007
On Apr 6, 1:26 pm, "robert bristow-johnson"
<r...@audioimagination.com> wrote:
> On Apr 6, 10:00 am, Grant Griffin <nos...@yahoo.com> wrote: > > > Vladimir Vassilevsky wrote: > > >>> The straightforward way would be not to use the phase > > >>> representation. Work with the complex derivatives directly: > > > >>> IdQ/dt - QdI/dt > > >>> --------------- > > >>> I^2 + Q^2 > > > >> I guess the key advantage is that you don't have to implement an > > >> arctan function? > > > > Atan is not that big of a deal. > > especially when you know that the argument to it is small. > > > > What is bad is that you have to do the > > > costly division no matter if you are using atan() or not. What is good > > > is that with I' and Q' there is no phase wrapping problem. > > > I guess I've always just used delta(atan(Q/I)) for this. Even if the > > data representation doesn't automatically handle the phase wrapping, > > handling it specially is less computation than doing all the arithmetic > > above. > > well, if-then statements (needed for explicit phase unwrapping) are > sorta costly and ugly in DSP code, me thinks. this is why i liked: > > 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]) } > > = arctan( (Q[n]*I[n-1] - I[n]*Q[n-1]) > / (I[n]*I[n-1] + Q[n]*Q[n-1]) ) > > but it does (or *might*) require a division. if you are confident > that the denominator > > I[n]*I[n-1] + Q[n]*Q[n-1] > > is close enough to > > I[n]*I[n] + Q[n]*Q[n] > > and that is constant, you can skip the division. even if not, you can > compute the *new* denominator, multiply it by the previous reciprocal > and use the difference of that from 1 in a sorta servo feedback loop > to skip the division. also the arctan() might be able to be tossed if > you know that the change in angle is small for each sample. then you > get > > omega[n] = Constant*( Q[n]*I[n-1] - I[n]*Q[n-1] ) > > and that's about as simple as it can get. > > > Coincidentally, one of the very first DSP designs I ever did, circa > > 1985, was a hardware implementation of the above, using > > now-seemingly-gigantic DIP parts such as a look-up EPROM, adder, etc. > > > =g2 > > _____________________________________________________________________ > > > Grant R. Griffin > > Publisher of dspGuru http://www.dspguru.com > > Iowegian International Corporation http://www.iowegian.com > > Seehttp://www.iowegian.com/img/contact.giffore-mail address > > it's nice to see this sig again. > > r b-j
Hi RBJ, omega[n] = arg{ I[n] + j*Q[n] } - arg{ I[n-1] + j*Q[n-1] } (adjusted for wrap) = arg{ (I[n] + j*Q[n]) * conjugate( I[n-1] + j*Q[n-1] ) } with no division = arg{ (I[n] + j*Q[n]) * (I[n-1] - j*Q[n-1]) } with no division Dirk
On Apr 6, 1:51 pm, "dbell" <bellda2...@cox.net> wrote:
> On Apr 6, 1:26 pm, "robert bristow-johnson" wrote: > >
...
> > > but it does (or *might*) require a division. if you are confident > > that the denominator > > > I[n]*I[n-1] + Q[n]*Q[n-1] > > > is close enough to > > > I[n]*I[n] + Q[n]*Q[n] > > > and that is constant, you can skip the division. even if not, you can > > compute the *new* denominator, multiply it by the previous reciprocal > > and use the difference of that from 1 in a sorta servo feedback loop > > to skip the division. also the arctan() might be able to be tossed if > > you know that the change in angle is small for each sample. then you > > get > > > omega[n] = Constant*( Q[n]*I[n-1] - I[n]*Q[n-1] ) > > > and that's about as simple as it can get. >
...
> > omega[n] = arg{ I[n] + j*Q[n] } - arg{ I[n-1] + j*Q[n-1] } > (adjusted for wrap) > = arg{ (I[n] + j*Q[n]) * conjugate( I[n-1] + j*Q[n-1] ) } > with no division > = arg{ (I[n] + j*Q[n]) * (I[n-1] - j*Q[n-1]) } > with no division
well, not yet anyway. so assuming omega[n] doesn't get so big, then omega[n] = 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*(I[n-1]*Q[n] - I[n]*Q[n-1] ) } now, Dirk, how're you gonna do that arg{} ? r b-j
On Apr 6, 3:48 pm, "robert bristow-johnson"
<r...@audioimagination.com> wrote:
> On Apr 6, 1:51 pm, "dbell" <bellda2...@cox.net> wrote: > > > > > > > On Apr 6, 1:26 pm, "robert bristow-johnson" wrote: > > ... > > > > but it does (or *might*) require a division. if you are confident > > > that the denominator > > > > I[n]*I[n-1] + Q[n]*Q[n-1] > > > > is close enough to > > > > I[n]*I[n] + Q[n]*Q[n] > > > > and that is constant, you can skip the division. even if not, you can > > > compute the *new* denominator, multiply it by the previous reciprocal > > > and use the difference of that from 1 in a sorta servo feedback loop > > > to skip the division. also the arctan() might be able to be tossed if > > > you know that the change in angle is small for each sample. then you > > > get > > > > omega[n] = Constant*( Q[n]*I[n-1] - I[n]*Q[n-1] ) > > > > and that's about as simple as it can get. > > ... > > > omega[n] = arg{ I[n] + j*Q[n] } - arg{ I[n-1] + j*Q[n-1] } > > (adjusted for wrap) > > = arg{ (I[n] + j*Q[n]) * conjugate( I[n-1] + j*Q[n-1] ) } > > with no division > > = arg{ (I[n] + j*Q[n]) * (I[n-1] - j*Q[n-1]) } > > with no division > > well, not yet anyway. > > so assuming omega[n] doesn't get so big, then > > omega[n] = 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*(I[n-1]*Q[n] - I[n]*Q[n-1] ) } > > now, Dirk, how're you gonna do that arg{} ? > > r b-j- Hide quoted text - > > - Show quoted text -
Depends. Not someway that depends on unity magnitude going into arg of course. IIRC coordic algorithm would do, but I would need to verify that. Dirk

Ahmed wrote:

>>FYI, I'm really leaning toward Vladimir's solution (Q'I - I'Q / (I^2 + Q^2))
> This technique is named the "cross-correlator receiver" in some > papers.
What a fancy name for the simple thing.
> It is shown to have performance comparable to the Limiter- > Discriminator receiver.
It is obvious. This is just one of many different ways of implementing the old good discriminator. As long as the underlying math is the same, all methods are equivalent.
> So even though you would not have to worry > about phase wrapping issues, the performance will suffer below > threshold due to click noise.
To be more precise, it has to do with the suboptimal approach to the task of the frequency estimation in the presence of noise. All of the discriminators do the frequency measurement in the bandwidth of the input signal, and then average the result to the bandwidth of the modulating signal. Vladimir Vassilevsky DSP and Mixed Signal Design Consultant http://www.abvolt.com
"Ahmed" <ahsenahmed@hotmail.com> writes:
> [...] > It is shown to have performance comparable to the Limiter- > Discriminator receiver. So even though you would not have to worry > about phase wrapping issues, the performance will suffer below > threshold due to click noise.
Ahmed, If I'm interpreting [schartzcommtechniques] (section 3-9, around page 157) correctly, the threshold extension offered by FMFB techniques (FM with FeedBack, i.e., using a PLL for FM demodulation) is only available when the input signal is relatively wideband FM (beta >> 1). Since beta = 1 in the BTSC SAP channel, this technique is not applicable here and a plain, old FM discriminator is about as good as you're gonna' get. Would you agree with this? If not, why not? Is there another technique for extending the threshold that works with narrowband FM? --Randy @book{schwartzcommtechniques, title = "Communication Systems and Techniques", author = "Mischa Schwartz and William R. Bennett and Seymour Stein", publisher = "IEEE Press (reissue, originally New York: McGraw-Hill 1966)", year = "1996"} -- % Randy Yates % "She tells me that she likes me very much, %% Fuquay-Varina, NC % but when I try to touch, she makes it %%% 919-577-9882 % all too clear." %%%% <yates@ieee.org> % 'Yours Truly, 2095', *Time*, ELO http://home.earthlink.net/~yatescr
On Apr 6, 4:03 pm, "dbell" <bellda2...@cox.net> wrote:
> On Apr 6, 3:48 pm, "robert bristow-johnson" > > > > > > > > <r...@audioimagination.com> wrote: > > On Apr 6, 1:51 pm, "dbell" <bellda2...@cox.net> wrote: > > > > On Apr 6, 1:26 pm, "robert bristow-johnson" wrote: > > > ... > > > > > but it does (or *might*) require a division. if you are confident > > > > that the denominator > > > > > I[n]*I[n-1] + Q[n]*Q[n-1] > > > > > is close enough to > > > > > I[n]*I[n] + Q[n]*Q[n] > > > > > and that is constant, you can skip the division. even if not, you can > > > > compute the *new* denominator, multiply it by the previous reciprocal > > > > and use the difference of that from 1 in a sorta servo feedback loop > > > > to skip the division. also the arctan() might be able to be tossed if > > > > you know that the change in angle is small for each sample. then you > > > > get > > > > > omega[n] = Constant*( Q[n]*I[n-1] - I[n]*Q[n-1] ) > > > > > and that's about as simple as it can get. > > > ... > > > > omega[n] = arg{ I[n] + j*Q[n] } - arg{ I[n-1] + j*Q[n-1] } > > > (adjusted for wrap) > > > = arg{ (I[n] + j*Q[n]) * conjugate( I[n-1] + j*Q[n-1] ) } > > > with no division > > > = arg{ (I[n] + j*Q[n]) * (I[n-1] - j*Q[n-1]) } > > > with no division > > > well, not yet anyway. > > > so assuming omega[n] doesn't get so big, then > > > omega[n] = 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*(I[n-1]*Q[n] - I[n]*Q[n-1] ) } > > > now, Dirk, how're you gonna do that arg{} ? > > > r b-j- Hide quoted text - > > > - Show quoted text - > > Depends. > > Not someway that depends on unity magnitude going into arg of course.
i dunno. might not be such a bad assumption.
> IIRC coordic algorithm would do, but I would need to verify that. >
maybe you'll have to do the arg{} the old-fashioned way by dividing the imag part with the real part and arctanning. it might never be that big, going into the arg and maybe you can just call it the unity gain function. maybe not. r b-j