| 117 | |
| 118 | #################################spectrum sense specific code############################# |
| 119 | |
| 120 | |
| 121 | self.min_freq = 462.4825e6 # setting min and max frequency inside the init rather than taking it from the command line |
| 122 | self.max_freq = 462.4825e6 |
| 123 | |
| 124 | if self.min_freq > self.max_freq: |
| 125 | self.min_freq, self.max_freq = self.max_freq, self.min_freq # swap them |
| 126 | |
| 127 | self.fft_size = 128 |
| 128 | |
| 129 | |
| 130 | #if not options.real_time: |
| 131 | # realtime = False |
| 132 | |
| 133 | #else: |
| 134 | # # Attempt to enable realtime scheduling |
| 135 | # r = gr.enable_realtime_scheduling() |
| 136 | # if r == gr.RT_OK: |
| 137 | # realtime = True |
| 138 | # else: |
| 139 | # realtime = False |
| 140 | # print "Note: failed to enable realtime scheduling" |
| 141 | |
| 142 | # If the user hasn't set the fusb_* parameters on the command line, |
| 143 | # pick some values that will reduce latency. |
| 144 | |
| 145 | #if 1: |
| 146 | # if options.fusb_block_size == 0 and options.fusb_nblocks == 0: |
| 147 | # if realtime: # be more aggressive |
| 148 | # options.fusb_block_size = gr.prefs().get_long('fusb', 'rt_block_size', 1024) |
| 149 | # options.fusb_nblocks = gr.prefs().get_long('fusb', 'rt_nblocks', 16) |
| 150 | # else: |
| 151 | # options.fusb_block_size = gr.prefs().get_long('fusb', 'block_size', 4096) |
| 152 | # options.fusb_nblocks = gr.prefs().get_long('fusb', 'nblocks', 16) |
| 153 | |
| 154 | #print "fusb_block_size =", options.fusb_block_size |
| 155 | #print "fusb_nblocks =", options.fusb_nblocks |
| 156 | |
| 157 | # build graph |
| 158 | |
| 159 | #self.u = usrp_options.create_usrp_source(options) |
| 160 | |
| 161 | |
| 162 | #adc_rate = self.u.adc_rate() # 64 MS/s |
| 163 | #usrp_decim = options.decim |
| 164 | #self.u.set_decim_rate(usrp_decim) |
| 165 | usrp_rate = adc_rate / usrp_decim |
| 166 | |
| 167 | self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec)) |
| 168 | self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec) |
| 169 | print "Using RX d'board %s" % (self.subdev.side_and_name(),) |
| 170 | |
| 171 | |
| 172 | #s2v = gr.stream_to_vector(gr.sizeof_gr_complex, self.fft_size) |
| 173 | self.s2v = gr.stream_to_vector(gr.sizeof_gr_complex, self.fft_size) # making it an attribute of the class |
| 174 | |
| 175 | mywindow = window.blackmanharris(self.fft_size) |
| 176 | self.fft = gr.fft_vcc(self.fft_size, True, mywindow) #making it an attribute of the class |
| 177 | power = 0 |
| 178 | for tap in mywindow: |
| 179 | power += tap*tap |
| 180 | |
| 181 | #c2mag = gr.complex_to_mag_squared(self.fft_size) # making it an attribute of the class |
| 182 | self.c2mag = gr.complex_to_mag_squared(self.fft_size) |
| 183 | print "print c2mag ",c2mag,"\n" |
| 184 | # FIXME the log10 primitive is dog slow |
| 185 | log = gr.nlog10_ff(10, self.fft_size, |
| 186 | -20*math.log10(self.fft_size)-10*math.log10(power/self.fft_size)) |
| 187 | |
| 188 | # Set the freq_step to 75% of the actual data throughput. |
| 189 | # This allows us to discard the bins on both ends of the spectrum. |
| 190 | |
| 191 | self.freq_step = 0.75 * usrp_rate |
| 192 | self.min_center_freq = self.min_freq + self.freq_step/2 |
| 193 | nsteps = math.ceil((self.max_freq - self.min_freq) / self.freq_step) |
| 194 | self.max_center_freq = self.min_center_freq + (nsteps * self.freq_step) |
| 195 | |
| 196 | self.next_freq = self.min_center_freq |
| 197 | |
| 198 | tune_delay = max(0, int(round(options.tune_delay * usrp_rate / self.fft_size))) # in fft_frames |
| 199 | dwell_delay = max(1, int(round(options.dwell_delay * usrp_rate / self.fft_size))) # in fft_frames |
| 200 | |
| 201 | self.msgq = gr.msg_queue(16) |
| 202 | self._tune_callback = tune(self) # hang on to this to keep it from being GC'd |
| 203 | #stats = gr.bin_statistics_f(self.fft_size, self.msgq, |
| 204 | # self._tune_callback, tune_delay, dwell_delay) |
| 205 | |
| 206 | self.stats = gr.bin_statistics_f(self.fft_size, self.msgq, |
| 207 | self._tune_callback, tune_delay, dwell_delay) #making it an attribute of the class |
| 208 | |
| 209 | |
| 210 | |
| 211 | # FIXME leave out the log10 until we speed it up |
| 212 | #self.connect(self.u, s2v, fft, c2mag, log, stats) |
| 213 | #self.connect(self.u, s2v, fft, c2mag, stats) # taking care of the connect in benchmark_txrx |
| 214 | |
| 215 | if options.gain is None: |
| 216 | # if no gain was specified, use the mid-point in dB |
| 217 | g = self.subdev.gain_range() |
| 218 | options.gain = float(g[0]+g[1])/2 |
| 219 | |
| 220 | self.set_gain(options.gain) |
| 221 | print "gain =", options.gain |
| 222 | |
| 223 | ########################################################################################## |
| 337 | |
| 338 | |
| 339 | ##################### Spectrum sense specific classes################################## |
| 340 | |
| 341 | class tune(gr.feval_dd): |
| 342 | """ |
| 343 | This class allows C++ code to callback into python. |
| 344 | """ |
| 345 | def __init__(self, tb): |
| 346 | gr.feval_dd.__init__(self) |
| 347 | self.tb = tb |
| 348 | |
| 349 | def eval(self, ignore): |
| 350 | """ |
| 351 | This method is called from gr.bin_statistics_f when it wants to change |
| 352 | the center frequency. This method tunes the front end to the new center |
| 353 | frequency, and returns the new frequency as its result. |
| 354 | """ |
| 355 | try: |
| 356 | # We use this try block so that if something goes wrong from here |
| 357 | # down, at least we'll have a prayer of knowing what went wrong. |
| 358 | # Without this, you get a very mysterious: |
| 359 | # |
| 360 | # terminate called after throwing an instance of 'Swig::DirectorMethodException' |
| 361 | # Aborted |
| 362 | # |
| 363 | # message on stderr. Not exactly helpful ;) |
| 364 | |
| 365 | new_freq = self.tb.set_next_freq() |
| 366 | return new_freq |
| 367 | |
| 368 | except Exception, e: |
| 369 | print "tune: Exception: ", e |
| 370 | |
| 371 | |
| 372 | class parse_msg(object): |
| 373 | def __init__(self, msg): |
| 374 | self.center_freq = msg.arg1() |
| 375 | self.vlen = int(msg.arg2()) |
| 376 | assert(msg.length() == self.vlen * gr.sizeof_float) |
| 377 | |
| 378 | # FIXME consider using Numarray or NumPy vector |
| 379 | t = msg.to_string() |
| 380 | self.raw_data = t |
| 381 | self.data = struct.unpack('%df' % (self.vlen,), t) |
| 382 | |
| 383 | |
| 384 | ######################################################################################## |