I've run a comparison test of - the "old" GR dqpsk block - the "new" one (dqpsk2) - the "op25" cqpsk (Gardner/Costas) block
The resulting constellation diagrams are viewable at http://www.lightlink.com/mhp/qpsk2/ The results are: Gardner is the winner, the old GR blocks take second, the new ones are last (intriguingly as shown in the symbol plot, things seem to start off nicely but then go awry)... The problem could be caused by dumb user error - D.U.E. (TM) or something fixable by simple parameter tweakage? The input file used in all three cases is a complex capture taken from a system using so-called "LSM/CQPSK". Basically, that appears to mean something like: a) simulcast distortion is added; b) PI/4 DQPSK is used; c) pulse shaping is stretched so as to fit the bandwidth of the signal into a 12.5 KHz channel; d) a "non-standard" waveform is used which results in the signal passing through the origin (0,0) point, introducing a rather severe AM component. There are two further wrinkles in this particular case which should be noted: 1) the complex file was captured using a "very poor man's USRP", *not* a real USRP [ see http://www.lightlink.com/mhp/iq/ ]. However the file formats are fully compatible. Further, a DBSRX capture exhibits all the same characteristics. 2) the receiving location is outside the designed coverage area of the system The results of all of this, plus the fact that the capture was made prior to verifying that the hardware even was functional for LSM, makes for a very "difficult" specimen (perfect for torture-testing RX codes)... Best Regards Max -------------------------------------------------------------------------- #!/usr/bin/env python import sys import os import math from gnuradio import gr, gru, audio, eng_notation, blks2 from gnuradio.eng_option import eng_option from optparse import OptionParser from math import pi class my_top_block(gr.top_block): def __init__(self): gr.top_block.__init__(self) parser = OptionParser(option_class=eng_option) parser.add_option("-d", "--debug", action="store_true", default=False, help="allow time at init to attach gdb") parser.add_option("-i", "--input-file", type="string", default="in.dat", help="specify the input file") parser.add_option("-o", "--output-file", type="string", default="out.dat", help="specify the output file") parser.add_option("-s", "--sample-rate", type="int", default=19200, help="input sample rate") (options, args) = parser.parse_args() sample_rate = options.sample_rate symbol_rate = 4800 samples_per_symbol = sample_rate // symbol_rate IN = gr.file_source(gr.sizeof_gr_complex, options.input_file) print "sps %d" % samples_per_symbol DEMOD = blks2.dqpsk2_demod(samples_per_symbol = samples_per_symbol, excess_bw = 0.35, verbose = True, log = True, sync_out = False) OUT = gr.file_sink(gr.sizeof_char, options.output_file) self.connect(IN, DEMOD, OUT) if options.debug: print 'Ready for GDB to attach (pid = %d)' % (os.getpid(),) raw_input("Press 'Enter' to continue...") if __name__ == "__main__": try: my_top_block().run() except KeyboardInterrupt: tb.stop() _______________________________________________ Discuss-gnuradio mailing list Discuss-gnuradio@gnu.org http://lists.gnu.org/mailman/listinfo/discuss-gnuradio