I finally took the time to really understand the polyphase synthesis filterbank and how to use it to reconstruct previously channelized signals. Once again, I looked to fred harris' work on the subject and have cracked it. The keys are in creating an M-to-2fs PFB channelizer, a 2-to-Pn PFB synthesizer, and perfect reconstruction filters (-6 dB at the edge of the passband).
I plan on writing up a more thurough look into this, and all of the code to do the proper synthesis filter will be going into GNU Radio soon, but for now, some pretty pictures.
First, we start off with a QPSK signal with very little noise:
Here, I split the signal up into 4 equally spaced channels. Channel 0 is around DC (0 Hz) and goes from -1000 - 1000 Hz, channel 1 is from 1000 - 3000 Hz, and channel 3 is from -3000 to -1000 Hz. Now, channel 2 actually spans from 3000 - 4000 and then wraps around to go from -4000 to -3000 Hz. These have a 1000 Hz bandwidth but are sampled at 2 samps/symbol so the channel sample rate is 2000 Hz.
I then go through the 2-to-Pn synthesizer where Pn is actually 8. This synthesis filter takes 4 channels in and produces four channels but at twice the sampling rate, so we now have a signal that is the original signal but sampled at twice the orignal rate. Notice also that it's offset by a bit in frequency in the PSD. That's a result of my plotting that I don't feel like correcting (it's related to the reason why channel 2 spans the edge of the positive and negative spectrum). Obviously, the constellation is not rotating, so we're ok.
Notice also that this signal was first split up, filtered, and then put back together again. Perfectly. That constellation should be enough proof of that. This has some huge implications to what we can do with this concept once I generalize it. This was a simple demonstration to get the algorithm and math correct, but now we can have some serious fun!
For those of you into such things, this is the filter I used for this example:
I generated it using GNU Radio firdes.low_pass_2 filter generator with these parameters:
- Gain = 1
- Sample Rate = 8000 Hz
- Bandwidth = 1000 Hz
- Transition bandwidth = 200 Hz
- Attenuation = 80 dB
- Window: Blackman-harris
The code to do this now exists in GNU Radio between the gr_pfb_channelizer_ccf and gr_pfb_synthesizer_ccf. An example that exercises this concept can be found in gnuradio-examples/python/pfb/reconstruction.py.
As of right now, this code exists on the 'next' branch of gnuradio.org and will be a part of the 3.6.0 release. The reason for this is that there's a slight change in the default behavior of the synthesizer filterbank with regards to the positioning of the channels. See the block documentation for more details.