[Top][All Lists]
[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Discuss-gnuradio] FM Stereo Transmitter Code,
James Smith <=