1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
#!/usr/bin/env python
from gnuradio import gr, gru, eng_notation, optfir
from gnuradio import audio
from gnuradio import usrp
from gnuradio import blks
from gnuradio.eng_option import eng_option
from optparse import OptionParser
import usrp_dbid
import sys
import math
def pick_subdevice(u):
"""
The user didn't specify a subdevice on the command line.
Try for one of these, in order: TV_RX, BASIC_RX, whatever is on side A.
@return a subdev_spec
"""
return usrp.pick_subdev(u, (usrp_dbid.TV_RX,
usrp_dbid.TV_RX_REV_2,
usrp_dbid.BASIC_RX))
class wfm_rx_graph (gr.flow_graph):
def __init__(self):
gr.flow_graph.__init__(self)
parser=OptionParser(option_class=eng_option)
parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None,
help="select USRP Rx side A or B (default=A)")
parser.add_option("-f", "--freq", type="eng_float", default=100.1e6,
help="set frequency to FREQ", metavar="FREQ")
parser.add_option("-g", "--gain", type="eng_float", default=None,
help="set gain in dB (default is midpoint)")
parser.add_option("-O", "--audio-output", type="string", default="",
help="pcm device name. E.g., hw:0,0 or surround51 or /dev/dsp")
(options, args) = parser.parse_args()
if len(args) != 0:
parser.print_help()
sys.exit(1)
self.vol = .1
self.state = "FREQ"
self.freq = 0
# build graph
self.u = usrp.source_c() # usrp is data source
adc_rate = self.u.adc_rate() # 64 MS/s
usrp_decim = 200
self.u.set_decim_rate(usrp_decim)
usrp_rate = adc_rate / usrp_decim # 320 kS/s
chanfilt_decim = 1
demod_rate = usrp_rate / chanfilt_decim
audio_decimation = 10
audio_rate = demod_rate / audio_decimation # 32 kHz
if options.rx_subdev_spec is None:
options.rx_subdev_spec = pick_subdevice(self.u)
self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec))
self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec)
print "Using RX d'board %s" % (self.subdev.side_and_name(),)
chan_filt_coeffs = optfir.low_pass (1, # gain
usrp_rate, # sampling rate
80e3, # passband cutoff
115e3, # stopband cutoff
0.1, # passband ripple
60) # stopband attenuation
#print len(chan_filt_coeffs)
chan_filt = gr.fir_filter_ccf (chanfilt_decim, chan_filt_coeffs)
self.guts = blks.wfm_rcv (self, demod_rate, audio_decimation)
self.volume_control = gr.multiply_const_ff(self.vol)
# sound card as final sink
audio_sink = audio.sink(int(audio_rate),
options.audio_output,
False) # ok_to_block
# now wire it all together
self.connect (self.u, chan_filt, self.guts, self.volume_control, audio_sink)
if options.gain is None:
# if no gain was specified, use the mid-point in dB
g = self.subdev.gain_range()
options.gain = float(g[0]+g[1])/2
if abs(options.freq) < 1e6:
options.freq *= 1e6
# set initial values
self.set_gain(options.gain)
if not(self.set_freq(options.freq)):
self._set_status_msg("Failed to set initial frequency")
def set_vol (self, vol):
self.vol = vol
self.volume_control.set_k(self.vol)
self.update_status_bar ()
def set_freq(self, target_freq):
"""
Set the center frequency we're interested in.
@param target_freq: frequency in Hz
@rypte: bool
Tuning is a two step process. First we ask the front-end to
tune as close to the desired frequency as it can. Then we use
the result of that operation and our target_frequency to
determine the value for the digital down converter.
"""
r = self.u.tune(0, self.subdev, target_freq)
if r:
self.freq = target_freq
self.update_status_bar()
self._set_status_msg("OK", 0)
return True
self._set_status_msg("Failed", 0)
return False
def set_gain(self, gain):
self.subdev.set_gain(gain)
def update_status_bar (self):
msg = "Freq: %s Volume:%f Setting:%s" % (
eng_notation.num_to_str(self.freq), self.vol, self.state)
self._set_status_msg(msg, 1)
def _set_status_msg(self, msg, which=0):
print msg
if __name__ == '__main__':
fg = wfm_rx_graph()
try:
fg.run()
except KeyboardInterrupt:
pass
|