Atsc_cpll *almost* works

After converting atsc_fpll to handle complex input (to eliminate one
upconverter) it almost works, only the video out has problems.

The problem starts when this:

float I = input.real() * a_sin;
float Q = input.real() * a_cos;

is changed to this:

gr_complex IQ = input * gr_complex(a_cos,-a_sin);

which would be necessary to handle negative frequencies I think.
Everything else checks out ok, I even tried using gr_sincos.h in place
of gr_nco.h like in gr_pll_carriertracking_cc and it behaves exectly the
same.

Working:

gr_complex input = agc.scale(in[k]);
gr_sincosf(d_phase,&a_sin,&a_cos);

float I = input.real() * a_sin;
float Q = input.real() * a_cos;

out[k] = I;
gr_complex filtered_IQ = afc.filter(gr_complex(I,Q));
float x = phase_detector(filtered_IQ,0);
static const float alpha = 0.001;
static const float beta = alpha * alpha / 4;
d_freq = d_freq + beta * x;
d_phase = mod_2pi(d_phase + d_freq + alpha * x);

mpeg_packet_error_rate.py: 485526 errors out of 2165316 packets. 1679790
good packets. Error rate = 0.224

Almost working:

gr_complex input = agc.scale(in[k]);
gr_sincosf(d_phase,&a_sin,&a_cos);

gr_complex IQ = input * gr_complex(a_cos,-a_sin);

out[k] = IQ.real();
gr_complex filtered_IQ = afc.filter(gr_complex(I,Q));
float x = phase_detector(filtered_IQ,0);
static const float alpha = 0.001;
static const float beta = alpha * alpha / 4;
d_freq = d_freq + beta * x;
d_phase = mod_2pi(d_phase + d_freq + alpha * x);

mpeg_packet_error_rate.py: 258539 errors out of 2165280 packets. 1906741
good packets. Error rate = 0.119

Looks like a 36 missing packets, even tho the error rate is less, as the
video is certainly worse in mplayer.

–Chuck

On Tue, May 20, 2008 at 8:52 PM, Charles S. [email protected]
wrote:

gr_complex IQ = input * gr_complex(a_cos,-a_sin);
gr_sincosf(d_phase,&a_sin,&a_cos);
d_phase = mod_2pi(d_phase + d_freq + alpha * x);
gr_complex IQ = input * gr_complex(a_cos,-a_sin);
good packets. Error rate = 0.119

Looks like a 36 missing packets, even tho the error rate is less, as the
video is certainly worse in mplayer.

–Chuck

I don’t know much about 8-VSB, but I was under the impression that
it’s a single sideband modulation scheme that benefits from being real
only to avoid all the complex math associated with other modulation
schemes.

Do you know if this is true? I suppose I am just a little ignorant on
the subject and looking to be enlightened.

Thanks in advance.

Brian

On Tue, 2008-05-20 at 21:00 -0400, Brian P. wrote:

On Tue, May 20, 2008 at 8:52 PM, Charles S. [email protected] wrote:

gr_complex IQ = input * gr_complex(a_cos,-a_sin);

which would be necessary to handle negative frequencies I think.

I don’t know much about 8-VSB, but I was under the impression that
it’s a single sideband modulation scheme that benefits from being real
only to avoid all the complex math associated with other modulation
schemes.

The issue turned out to be jiggering the numbers that say “I strongly
suggest that you not mess with these…” * by .707 for the bit timing
loop worked :wink:

We want a complex pll so it can take data directly from the usrp
centered on DC, w/o having to mix it up to 5.75e6 and converting to
real for the old fpll, which was just a trick to look like the old
mc4020 adc boards.

–Chuck

On Tue, May 20, 2008 at 9:38 PM, Charles S. [email protected]
wrote:

The issue turned out to be jiggering the numbers that say “I strongly
suggest that you not mess with these…” * by .707 for the bit timing
loop worked :wink:

We want a complex pll so it can take data directly from the usrp
centered on DC, w/o having to mix it up to 5.75e6 and converting to
real for the old fpll, which was just a trick to look like the old
mc4020 adc boards.

Sorry, Chuck. I am still not sure I understand the whole deal. I am
not even sure how a PLL is being used since it’s all AM and there’s no
real phase information being transmitted - is there?

I was starting to read this:

http://www.broadcast.net/~sbe1/8vsb/8vsb.htm

And it just made me more confused as to what you’re trying to
accomplish using complex operations on a signal where the lower
sideband has been filtered away.

Any more help?

Thanks,
Brian

On Tue, 2008-05-20 at 21:55 -0400, Brian P. wrote:

On Tue, May 20, 2008 at 9:38 PM, Charles S. [email protected] wrote:

The issue turned out to be jiggering the numbers that say “I strongly
suggest that you not mess with these…” * by .707 for the bit timing
loop worked :wink:

Sorry, Chuck. I am still not sure I understand the whole deal. I am
not even sure how a PLL is being used since it’s all AM and there’s no
real phase information being transmitted - is there?

I was starting to read this:

http://www.broadcast.net/~sbe1/8vsb/8vsb.htm

Hi Brian - you are correct about 8vsb modulation - the document states:

“In 8-VSB, the digital information is transmitted exclusively in the
amplitude of the RF envelope and not in the phase. This is unlike other
digital modulation formats, such as QAM, where each point in the signal
constellation is a certain vector combination of carrier amplitude and
phase.”

The part I’m wrestling with is the purely rf front end before we even
begin the 8vsb processing, specifically:

"The first “helper” signal is the ATSC pilot. Just before modulation, a
small DC shift is applied to the 8-VSB baseband signal (which was
previously centered about zero volts with no DC component). This causes
a small residual carrier to appear at the zero frequency point of the
resulting modulated spectrum. This is the ATSC pilot. This gives the RF
PLL circuits in the 8-VSB receiver something to lock onto that is
independent of the data being transmitted. "

We get a complex datastream from the usrp with signals from -3.2 to
+3.2Mhz (6.4Mhz wide, easy /10 decimation - Eric wants 8Mhz ;).
Previously we had to upconvert the spectrum to 5.75Mhz so that it’s all
positive frequencies, then we take just the real part
(gr.complex_to_float) and then let the atsc_fpll lock onto the carrier
and shift it down to 0Hz and then the 8vsb demodulation magic starts
like you expected. But why upconvert, then down-mix again? Why not
just make a pll that would lock onto the carrier when it’s somewhere
around -3 + .31 Mhz and elimate one whole mixer? That’s what atsc_cpll
(complex in, real out) is for.

Now my question: Is it possible to tune the usrp so the carrier is at
+.31 Mhz ? (band center at 3, from -.2 to 6.2Mhz?) Then we could run
the cpll at 6.4 or 8Msps and get another big performance boost, maybe.
Right now the pll at 19.2 Mhz (6.4 * 3) is an expensive part. Eric, I
guess the bit timing loop would work at 24Mhz (8 * 3).

–Chuck

On Wed, May 21, 2008 at 07:12:39AM -0400, Charles S. wrote:

Now my question: Is it possible to tune the usrp so the carrier is at
+.31 Mhz ? (band center at 3, from -.2 to 6.2Mhz?) Then we could run
the cpll at 6.4 or 8Msps and get another big performance boost, maybe.
Right now the pll at 19.2 Mhz (6.4 * 3) is an expensive part.

No problem tuning the USRP where ever you want. Between the VCO on
the d’board the DDC we’ve got 0.01Hz resolution.

Eric, I guess the bit timing loop would work at 24Mhz (8 * 3).

I wouldn’t expect that to be a problem.

Eric

On Tue, May 20, 2008 at 09:38:21PM -0400, Charles S. wrote:

schemes.
–Chuck
Cool! Glad to hear that it’s working.

While you’re at it, can you have it work with a sample rate of 8 MHz?
As I recall, you’re currently using something like 6.1 or such, which
seems a bit narrow, given the roll off on the edges.

Eric

On Wed, May 21, 2008 at 7:12 AM, Charles S. [email protected]
wrote:

We get a complex datastream from the usrp with signals from -3.2 to
+3.2Mhz (6.4Mhz wide, easy /10 decimation - Eric wants 8Mhz ;).
Previously we had to upconvert the spectrum to 5.75Mhz so that it’s all
positive frequencies, then we take just the real part
(gr.complex_to_float) and then let the atsc_fpll lock onto the carrier
and shift it down to 0Hz and then the 8vsb demodulation magic starts
like you expected. But why upconvert, then down-mix again? Why not
just make a pll that would lock onto the carrier when it’s somewhere
around -3 + .31 Mhz and elimate one whole mixer? That’s what atsc_cpll
(complex in, real out) is for.

I didn’t realize the USRP couldn’t do a real-only signal stream. I
see what you’re doing now.

Now my question: Is it possible to tune the usrp so the carrier is at
+.31 Mhz ? (band center at 3, from -.2 to 6.2Mhz?) Then we could run
the cpll at 6.4 or 8Msps and get another big performance boost, maybe.
Right now the pll at 19.2 Mhz (6.4 * 3) is an expensive part. Eric, I
guess the bit timing loop would work at 24Mhz (8 * 3).

Wouldn’t it all work better if it was just done in the FPGA, and the
host was responsible for significantly less? Your PLL could also work
at the full 64Msps sample rate if it were inside the FPGA.

To make space in the FPGA, you can fix the decimation rate at the
input of the CIC to be 8 which saves the muxing logic on the output
and eliminates a whole slew of registers and logic.

You can also eliminate the halfband filter and go straight to the RRC
filter to offload a good portion of the processing from the host.

Since a single ATSC channel takes up all the available bandwidth of
the USB connection, you can also reduce the number of channels from 4
or even 2 downto the single 1, and keep it real-only. I can easily
see this fitting within that FPGA.

Brian