I reached essentially the same conclusions that Chuck reached afew weeks back on SSB Phasing receiver, the code of which is given below. The program seem to be a son't care on the sideband and demodulates lsb even if we ask it to demodulate usb. Can someone throw light on it? I derived all the math with the preenvelope calculations etc and verified it. It all seem to be right.
It seem to me that hilbert transform is goofing up somewhere. The next step may be to verify whether the coefficients of hilbert filter look alright or not. #!/usr/bin/python # SSB receiver using I/Q synchronous detection # Donald ducking is due to difference in freq b/n carrier and LO. # copyright (c) 2005, FSF under the GNU GPL v2 or later # Author: Ramakrishnan Muthukrishnan <[EMAIL PROTECTED]> # # Phasing SSB receiver based on block diagram from the article # "High Performance, Single-Signal Direct Conversion Receivers" # by Rick Campbell, KK7B, QST Jan 1993 # Program usage with the OTA capture samples from KD7LMO: # ssb_phasing.py offset bfo ssb_lsb_256k_complex.dat {l|L|u|U} # eg: ssb_phasing.py 50000 3100 ssb_lsb_256k_complex.dat l from gnuradio import gr from gnuradio import audio import sys import os def build_graph (filename, if_freq, side_band): sampling_freq = 256e3 bandwidth = 10e3 # 20khz trans_bw = 1e3 audio_rate = 48e3 # 32khz decim = long (sampling_freq / audio_rate) rf_lo = if_freq # file is our source. src = gr.file_source (gr.sizeof_gr_complex, filename, 1) # LO lo_i = gr.sig_source_f (sampling_freq,gr.GR_SIN_WAVE,rf_lo,1.0,0) lo_q = gr.sig_source_f (sampling_freq,gr.GR_COS_WAVE,rf_lo,1.0,0) # mixers mix_i = gr.multiply_ff () mix_q = gr.multiply_ff () # hilbert coefficients for N = 49 taps # perform hilbert transform and delay. Output is gr_complex n_taps = 79 hilb_filter = gr.firdes_hilbert (n_taps, gr.firdes.WIN_HAMMING) hilbert = gr.fir_filter_fff (1, hilb_filter) delay_taps = [] for i in range((n_taps-1)/2): delay_taps.append (0) delay_taps[((n_taps-1)/2) - 1] = 1 delay = gr.fir_filter_fff (1, delay_taps) # output of the above block is complex. Split into floats split1 = gr.complex_to_float () # create LPFs lpf_coeffs = gr.firdes.low_pass ( \ 1.0, audio_rate, 5e3, 500, gr.firdes.WIN_HAMMING) lpf1 = gr.fir_filter_fff ( \ decim, lpf_coeffs) lpf2 = gr.fir_filter_fff ( \ decim, lpf_coeffs) # adder if side_band == 'L' or side_band == 'l': sum = gr.add_ff () else: sum = gr.sub_ff () adder = gr.add_ff () sub = gr.sub_ff () gain = gr.multiply_const_ff(.00002) # audio output audio_sink = audio.sink (int (audio_rate)) # add required blocks created. Now build the flow graph fg = gr.flow_graph () fg.connect (src, split1) fg.connect ((split1,0), (mix_i,0)) fg.connect (lo_i, (mix_i,1)) fg.connect ((split1,1), (mix_q,0)) fg.connect (lo_q, (mix_q,1)) fg.connect (mix_i, lpf1) fg.connect (mix_q, lpf2) fg.connect (lpf1, delay) fg.connect (lpf2, hilbert) fg.connect (delay, (sum,0)) fg.connect (hilbert, (sum,1)) fg.connect (sum, gain) fg.connect (gain, audio_sink) return fg def main (args): filename = args[2] bfo = float(args[1]) freq = float (args[0]) freq = freq + bfo print "Tuning to freq %d" % (freq) print "filename is %s" %(filename) fg = build_graph (filename, freq,args[3][0]) fg.start () raw_input ('Press Enter to quit: ') fg.stop () if __name__ == '__main__': main (sys.argv[1:]) -- Ramakrishnan http://www.hackGNU.org/ Use Free Software -- Help stamp out Software Hoarding! _______________________________________________ Discuss-gnuradio mailing list Discuss-gnuradio@gnu.org http://lists.gnu.org/mailman/listinfo/discuss-gnuradio