discuss-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Discuss-gnuradio] SSB Phasing - working at last.


From: Ramakrishnan Muthukrishnan
Subject: [Discuss-gnuradio] SSB Phasing - working at last.
Date: Sat, 26 Feb 2005 09:33:18 +0530
User-agent: Gnus/5.1006 (Gnus v5.10.6) Emacs/21.3 (gnu/linux)

Folks:

Here is the working phasing SSB receiver. Thanks to the help from Chuck, the
issue was imperfect delay,hilbert pair. 

The following script cancels the other sideband perfectly! I don't have any
hardware setup yet, so still working with the files from KD7LMO.

Enjoy.
-- 
    Ramakrishnan                   http://www.hackGNU.org/
    Use Free Software -- Help stamp out Software Hoarding!



http://www.hackgnu.org/gnuradio/ssb_phasing.py


#!/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 <address@hidden>
#
# 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
from gnuradio.wxgui import stdgui, fftsink, scopesink
import sys
import os
import wx

class app_flow_graph (stdgui.gui_flow_graph):
    def __init__(self, frame, panel, vbox, argv):
        stdgui.gui_flow_graph.__init__ (self, frame, panel, vbox, argv)

        sampling_freq = 256e3
        bandwidth = 10e3   # 20khz
        trans_bw = 1e3
        audio_rate = 48e3  # 32khz

        filename, if_freq, side_band = parse_arguments (argv[1:])
        
        decim = long (sampling_freq / audio_rate)
        
        rf_lo = if_freq

        real = gr.complex_to_real()
        imag = gr.complex_to_imag()
        
        # file is our source.
        src = gr.file_source (gr.sizeof_gr_complex, filename, 1)

        # create a probe
        block, fft_win = fftsink.make_fft_sink_f (self, panel, "Spectrum", 
2048, sampling_freq)
        #block, scope_win = scopesink.make_scope_sink_f (self, panel, 
"Spectrum", sampling_freq)
        
        # LO
        lo_i = gr.sig_source_f (sampling_freq,gr.GR_COS_WAVE,rf_lo,1.0,0) 
        lo_q = gr.sig_source_f (sampling_freq,gr.GR_SIN_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 = 501
        hilb_filter = gr.firdes_hilbert (n_taps, gr.firdes.WIN_BLACKMAN)
        hilbert = gr.fir_filter_fff (1, hilb_filter)
        
        delay_taps = []
        for i in range((n_taps-1)/2 + 1):
            delay_taps.append (0)
            
        delay_taps[((n_taps-1)/2)] = 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,
                   sampling_freq,
                   3e3,
                   150,
                   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':
            print "lsb"
            sum = gr.add_ff ()
        else:
            print "usb"
            sum = 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
        self.connect (src, real)

        self.connect (real, (mix_i,0))
        self.connect (real, (mix_q,0))

        self.connect (lo_i, (mix_i,1))
        self.connect (lo_q, (mix_q,1))

        self.connect (mix_i, lpf1)
        self.connect (mix_q, lpf2)

        self.connect (lpf1, delay)
        self.connect (lpf2, hilbert)
            
        self.connect (delay, (sum,0))
        self.connect (hilbert, (sum,1))
            
        self.connect (sum, gain)
        self.connect (gain, audio_sink)
            
        self.connect (gain, block)        
        vbox.Add (fft_win, 1, wx.EXPAND)
            
def parse_arguments (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)
    return filename, freq, args[3]


if __name__ == '__main__':
    app = stdgui.stdapp (app_flow_graph, "Spectrum")
    app.MainLoop ()
    
                    
                    
                    




reply via email to

[Prev in Thread] Current Thread [Next in Thread]