discuss-gnuradio
[Top][All Lists]
Advanced

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

[Discuss-gnuradio] SSB Phasing


From: Ramakrishnan Muthukrishnan
Subject: [Discuss-gnuradio] SSB Phasing
Date: Thu, 17 Feb 2005 21:12:00 +0530
User-agent: Gnus/5.1006 (Gnus v5.10.6) Emacs/21.3 (gnu/linux)

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 <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
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!




reply via email to

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