Switching filter taps in rational resampler

Dear All,

I’m trying to correct for clock drift, and implement clock recovery,
reading data from a USRP1. I can’t use MM clock recovery. The signal is
DSSS, and I can produce accurate estimates of the phase / timing error,
but not on a continuous stream in real time. I hope therefore to make
periodic measurements and feed this correction information back to the
main data stream.

I’m using a rational resampling filter to pulse shape and produce a chip
rate data stream at a ratio of interp/decim. In order to sample the
signal at the centre of its energy, it occurred to me that I could
adjust the phase of the filter by shifting the polyphase taps over;
essentially padding with zeros at one end. This moves the centre of the
filter over by 1/decim chips for each pad zero, allowing me to sample
the signal at any selected sub-chip phase.

I’m short of CPU power, so can’t afford to do too much processing to the
signal, hence combining pulse shaping, resampling and clock phase
correction into a single filter step.

The USRP sampling clock has a frequency error in it. I’m typically
seeing about 8 samples error per second, sampling at 8MHz (ie.
decimating by 8 on the USRP), though this varies considerably with
temperature. At rational resampling decim = 23, this would mean changing
the filter taps around 8*23 times a second to track the clock phase and
sampling error, though I can probably tolerate a worse error than 1/23
of a chip, so, perhaps 1/3 of this rate.

How efficient is it to alter the filter taps on the fly? Is there much
overhead? If instead I switched between a bank of 23 filters, how would
I ensure continuity of data?

When I “wrap around”, ie. change to / from filter (delay == 0), to
(filter delay == (decim-1)), I will need to adjust the data stream to
repeat or skip a chip. I would probably subclass the rational_resampler
class and override the general_work() method to achieve this. I would
have to make the “private” data “protected” in the resampler code too;
perhaps it should be “protected” to allow this generally?

Does this approach make sense? Is there a better way?

– Dave Berkeley