discuss-gnuradio
[Top][All Lists]
Advanced

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

[Discuss-gnuradio] FM Stereo Transmitter Code


From: James Smith
Subject: [Discuss-gnuradio] FM Stereo Transmitter Code
Date: Tue, 14 Jun 2005 21:56:13 -0700 (PDT)

I've witten some code to transmit an fm stereo signal.
I don't have a USRP to test it with a hardware
reciever, but I did check the output with the fm
stereo recieving code avalible.  If anyone with a USRP
could test this code I would apperciate it.  What I am
most intereted in finding out is if the basictx card
can generate a signal in the fm broadcast band from
the aliasing of the dac.

I have not added preemphasis because I'm not sure of
how to do it accurately.  





#!/usr/bin/env python

from gnuradio import gr, eng_notation, optfir
# from gnuradio import usrp         # uncomment for
usrp output
from gnuradio import audio
from gnuradio.eng_option import eng_option
from optparse import OptionParser
import math

from gnuradio.wxgui import stdgui, fftsink, scopesink
import wx

def stereompxgen( fg , audio_rate , audio_interp ):
    mpx_rate= audio_rate * audio_interp

    pilot = gr.sig_source_f (mpx_rate, gr.GR_SIN_WAVE,
19000, .08) 
      # pilot amplitune default is .08 , may be set to
zero for test purposes
    subcar = gr.sig_source_f (mpx_rate,
gr.GR_SIN_WAVE, 38000, 1)
    lplusr = gr.add_ff()
    lminusr = gr.sub_ff()

    laudio = gr.multiply_const_ff( .9 )
    raudio = gr.multiply_const_ff( .9 )

    lminusr_sig = gr.multiply_ff()
    mpxcomposite = gr.add_ff()
    

    sw_interp = audio_interp
    fs = mpx_rate
    upsample_taps =  gr.firdes.low_pass (sw_interp,   
  # gain
                                           fs,        
    # sampling rate
                                           16000, #
cutoff
                                           2500,   #
trans width
                                          
gr.firdes.WIN_HANN)

    print "length of audio filters ( 2 ) = ", len
(upsample_taps)

    lplusr_or = gr.interp_fir_filter_fff (sw_interp,
upsample_taps)
    lminusr_or = gr.interp_fir_filter_fff (sw_interp,
upsample_taps)
    

    fg.connect (laudio, (lplusr, 0))
    fg.connect (raudio, (lplusr, 1))
    fg.connect (laudio, (lminusr, 0))
    fg.connect (raudio, (lminusr, 1))
    fg.connect (lplusr, lplusr_or )
    fg.connect (lminusr, lminusr_or )
    fg.connect (lminusr_or, (lminusr_sig,0) )
    fg.connect (subcar, (lminusr_sig,1) )
    fg.connect (lplusr_or, (mpxcomposite,0) )
    fg.connect (lminusr_sig, (mpxcomposite,1) )
    fg.connect (pilot, (mpxcomposite,2) )

    return ( laudio,raudio , mpxcomposite )

def fold_freq(freq, fs):
    while freq > fs:
        freq = freq - fs
    if freq > fs/2:
        freq = fs - freq
    return freq

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

        parser = OptionParser
(option_class=eng_option)
        parser.add_option ("-c", "--cordic-freq",
type="eng_float", default=96.9e6,
                           help="set Tx cordic
frequency to FREQ", metavar="FREQ")
        parser.add_option ("-d", "--device",
type="string",
                           default="hw:0,0",
                           help="set audio input
device")
        parser.add_option ("-f", "--filename",
type="string",
                          
default="fmstereooutput_512k_complex.dat",
                           help="write output to
FILENAME")
        parser.add_option ("-g", "--gain",
type="eng_float", default=0,
                           help="set Tx PGA gain in dB
[-20, 0] (default=0)")
        (options, args) = parser.parse_args ()
        cordic_freq=fold_freq( options.cordic_freq ,
128000000 )
        print "cordic_freq = %s" %
(eng_notation.num_to_str (cordic_freq))

        #
----------------------------------------------------------------

        audio_rate = 32000
        audio_interp = 8
        mpx_interp = 2
        mpx_low_rate = audio_rate * audio_interp
        mpx_high_rate = audio_rate * audio_interp *
mpx_interp

        self.usrp_interp = int (128e6 / mpx_high_rate
)

        max_deviation = 75e3

        print "audio rate  = ", audio_rate
        print "audio interp  = ", audio_interp
        print "baseband interp = ", mpx_interp
        print "fm complex sample rate = ",
eng_notation.num_to_str(mpx_high_rate)
        print "usrp_interp  = ", self.usrp_interp

        src = audio.source ( audio_rate ,
options.device )
        ltone = gr.sig_source_f (audio_rate,
gr.GR_SIN_WAVE, 1000, .92)
        rtone = gr.sig_source_f (audio_rate,
gr.GR_SIN_WAVE, 1000, 0)
                
        
        interp_taps =  gr.firdes.low_pass (mpx_interp,
     # gain
                                          
mpx_high_rate,   # sampling rate
                                           70e3, #
cutoff
                                           30e3,   #
trans width
                                          
gr.firdes.WIN_HANN)
        print "len = ", len (interp_taps)

        (mpxinl, mpxinr, mpxout) = stereompxgen( self
, audio_rate , audio_interp )
        k = 2 * math.pi * max_deviation /
mpx_high_rate
        fmmod = gr.frequency_modulator_fc (k)
        interp = gr.interp_fir_filter_fff (mpx_interp,
interp_taps)

        gain = gr.multiply_const_cc (4000)  # was
16000
        fsink = gr.file_sink( gr.sizeof_gr_complex ,
options.filename )

        self.frame = frame
        msg = "Frequency: %s" %
(eng_notation.num_to_str(options.cordic_freq) ) 
        self.frame.SetStatusText (msg,0 )
        msg = "Fundamental: %s" %
(eng_notation.num_to_str(cordic_freq) ) 
        self.frame.SetStatusText (msg,1 )

        if 1: # 1 for audio 0 for test tones
            self.connect ((src,0) , (mpxinl) )
            self.connect ((src,1) , (mpxinr) )
        else:
            self.connect (ltone , (mpxinl) )
            self.connect (rtone , (mpxinr) )

        self.connect (mpxout , interp , fmmod , gain )
        
        if 0: # 1 for usrp output
           u = usrp.sink_c (0, self.usrp_interp)
           u.set_tx_freq (0, cordic_freq)
           u.set_pga (0, options.gain)
           u.set_pga (1, options.gain)
           self.connect ( gain, u)
        else:
           self.connect ( gain, fsink )

        probe = gr.file_sink( gr.sizeof_float ,
"fmstereompx.dat" )
     #   self.connect (mpxout, probe )

        if 1: 
           mpx_scope = \
             scopesink.scope_sink_f(self, panel, "MPX
Baseband", sample_rate=mpx_low_rate)
           self.connect ( mpxout , (mpx_scope, 0))
           vbox.Add (mpx_scope.win, 1, wx.EXPAND)

        if 1:
            mpx_fft = fftsink.fft_sink_f (self, panel,
fft_size=1024, fft_rate=10, sample_rate=mpx_low_rate,
ref_level=40 , title="MPX Baseband FFT" )
            self.connect (mpxout , mpx_fft)
            vbox.Add (mpx_fft.win, 1, wx.EXPAND) 

 
def main ():
    app = stdgui.stdapp (fsk_tx_graph, "FM Stereo Tx")
    app.MainLoop ()

if __name__ == '__main__':
    main ()

# eof


                
__________________________________ 
Discover Yahoo! 
Get on-the-go sports scores, stock quotes, news and more. Check it out! 
http://discover.yahoo.com/mobile.html




reply via email to

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