> I am new to this list and am wondering if anyone here is using the linux
> soundmodem module with their setup.
> Is it reliable?  Also I was wondering if anyone knows how exactly it works..
> I tried making a soundcard modem in visualbasic using a fast fourier transform
> but it only could handle several bits/second.

Before I go into a longish talk about transforms, I's, and Q's, is there
anyone out there that regularly runs newqpsk? I'm loopback testing the
modem on vhf fm and I get a 50% error rate. 

I've used the afsk1200 baud modem in the linux kernel, I've also written a
packet modem that works with the 'newqpsk' userspace soundmodem code.
Both the modulator and the demodulator work on the air, but they're mainly
a learning tool. 

The problem with demoding fsk with dfft's is that your burning cpu cycles
calculating the power levels for frequencies you don't care about. You
want to run two I/Q detectors. Take a set S[p] of N samples that contain
an fsk symbol and generate 4 arrays (assume array indexes start at 0 as
in C) :
1200hz I/Q detector:
Ia[p] = Sin[(p/N)*2*Pi]
Qa[p] = Cos[(p/N)*2*Pi + Pi]

2200hz I/Q detector:
Ib[p] = Sin[(1.8333333*p/N)*2*Pi]
Qb[p] = Cos[(1.8333333*p/N)*2*Pi + Pi]

Now to figure out what the power levels are do a convolution
 where a convolution is something like this:
 convolution(X[],Y[]) := X[0]*Y[0]+X[1]*Y[1]+X[2]*Y[2]+...+X[n]*Y[n]
 
power in 1200 hz = convolution(S[],Ia[])^2+convolution(S[],Qa[])^2
  because sin^2+cos^2=1 or something along that line. 
and
power in 2200 hz = convolution(S[],Ib[])^2+convolution(S[],Qb[])^2

The dft is the ultimate I/Q detector because it calculates I and Q for
every possible frequency, but even though there are some fast dfft's it
doesn't mean your good old 386 will do it at 1200 baud. For reference the
real part of the dft is the I and the imaginary is Q. 

To get the symbol clock do whole convolution thing for every sample. I.E.
do:
 Go forward one sample;
 make array of last N samples;
 do convolution
 decision = (power in 2200) - (power in 1200)
 if decision != lastloopsdecision then push symbol clock slightly forward
        or backward  as necessary to ease the transition into the right place
 if (symbol clock says DING) then take decision and pass it to
        hdlc decoder etc.
loop

 This is essentially what the kernel afsk 1200 code does, minus the dcd
stuff which I don't think I'll ever get. It's written for speed and not
legibility. My code low pass filters the decision for pll purposes and it
does the clocks and detectors in floating point.

To decode 1200b psk drop the 2200 detector and just use the Ia versus Qa.
Take ArcTan(convolution(S[],Ia[]/convolution(S[],Qa[])) and use that to
make the decision. The symbol clock is a bit messy, in this case, because
you need to update the clock on big transitions AND update the
detector frequency (1200hz) because the carriers probably aren't matched.
In between transitions the first derivative of ArcTan is how far the
carriers are mismatched, so that's pretty easy. It the mismatch is more
than 50 hz or so you may as well for a dfft before you start the
demodulator to initialize the detector at the right frequency.



-------===Dustin Moore===---------


Reply via email to