def __init__(self, sample_rate, fft_size, ref_scale, frame_rate): gr.hier_block2.__init__( self, "logpowerfft_win", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(1, 1, gr.sizeof_float * fft_size)) self._sd = blocks.stream_to_vector_decimator( item_size=gr.sizeof_gr_complex, sample_rate=sample_rate, vec_rate=frame_rate, vec_len=fft_size) fft_window = fft_lib.window_hamming(fft_size) fft = fft_lib.fft_vcc(fft_size, True, fft_window, True) window_power = sum([x * x for x in fft_window]) c2magsq = blocks.complex_to_mag_squared(fft_size) self._avg = filter.single_pole_iir_filter_ff(1.0, fft_size) self._log = blocks.nlog10_ff( 10, fft_size, -20 * math.log10(fft_size) # Adjust for number of bins - 10 * math.log10( float(window_power) / fft_size) # Adjust for windowing loss - 20 * math.log10(float(ref_scale) / 2)) # Adjust for reference scale self.connect(self, self._sd, fft, c2magsq, self._avg, self._log, self)
def __init__(self, sample_rate, pspectrum_len, ref_scale, frame_rate, avg_alpha, average, n, m, nsamples, estimator='esprit'): """ Create an log10(abs(spectrum_estimate)) stream chain. Provide access to the setting the filter and sample rate. @param sample_rate Incoming stream sample rate @param pspectrum_len Number of FFT bins @param ref_scale Sets 0 dB value input amplitude @param frame_rate Output frame rate @param avg_alpha averaging (over time) constant [0.0-1.0] @param average Whether to average [True, False] @param n Parameter n for the estimator @param m Parameter m for the estimator @param nsamples Number of samples to use for estimation @param estimator Estimator to use, can be either 'esprit' or 'music' """ gr.hier_block2.__init__( self, self._name, gr.io_signature(1, 1, self._item_size), # Input signature gr.io_signature(1, 1, gr.sizeof_float * pspectrum_len)) # Output signature self._sd = blocks.stream_to_vector_decimator(item_size=self._item_size, sample_rate=sample_rate, vec_rate=frame_rate, vec_len=nsamples) if estimator == 'esprit': est = specest.esprit_spectrum_vcf(n, m, nsamples, pspectrum_len) elif estimator == 'music': est = specest.music_spectrum_vcf(n, m, nsamples, pspectrum_len) else: est = specest.esprit_spectrum_vcf(n, m, nsamples, pspectrum_len) self._avg = filter.single_pole_iir_filter_ff(1.0, pspectrum_len) self._log = blocks.nlog10_ff( 20, pspectrum_len, -20 * math.log10(pspectrum_len) # Adjust for number of bins - 20 * math.log10(ref_scale / 2) + 3.0) # Adjust for reference scale self.connect(self, self._sd, est, self._avg, self._log, self) self._average = average self._avg_alpha = avg_alpha self.set_avg_alpha(avg_alpha) self.set_average(average)
def __init__(self): gr.top_block.__init__(self) self.sample_rate = 5000000 self.ampl = 0.1 self.freq = 144000000 self.uhd = uhd.usrp_source( ",".join(("", "")), uhd.stream_args( cpu_format="fc32", channels=range(1), ), ) self.uhd.set_samp_rate(self.sample_rate) self.uhd.set_center_freq(self.freq, 0) self.uhd.set_gain(0, 0) self.uhd.set_antenna("RX2", 0) self.fft_vxx_0 = fft.fft_vcc(1024, True, (window.blackmanharris(1024)), True, 1) self.throttle = blocks.throttle(gr.sizeof_gr_complex*1, self.sample_rate,True) self.blocks_throttle_0 = blocks.throttle(gr.sizeof_gr_complex*1, self.sample_rate,True) self.stream = blocks.stream_to_vector_decimator( item_size=gr.sizeof_gr_complex, sample_rate=self.sample_rate, vec_rate=30, vec_len=1024, ) self.probe = blocks.probe_signal_vf(1024) self.fft = fft.fft_vcc(1024, True, (window.blackmanharris(1024)), True, 1) src0 = analog.sig_source_c(self.sample_rate, analog.GR_SIN_WAVE, self.freq, self.ampl) dst = audio.sink(self.sample_rate, "") self.sqrt = blocks.complex_to_mag_squared(1024) def fft_out(): while 1: val = self.probe.level() print max(val) freq = (val.index(max(val)) * (self.sample_rate/1024.0)) + (self.freq - (self.sample_rate/2.0)) print freq time.sleep(1) fft_thread = threading.Thread(target=fft_out) fft_thread.daemon = True fft_thread.start() self.connect((self.uhd,0),(self.throttle, 0)) self.connect((self.throttle,0),(self.stream,0)) self.connect((self.stream, 0),(self.fft, 0)) self.connect((self.fft, 0),(self.sqrt, 0)) self.connect((self.sqrt, 0),(self.probe, 0))
def __init__(self, sample_rate, fft_size, ref_scale, frame_rate, avg_alpha, average, win=None, shift=False): """ Create an log10(abs(fft)) stream chain. Provide access to the setting the filter and sample rate. Args: sample_rate: Incoming stream sample rate fft_size: Number of FFT bins ref_scale: Sets 0 dB value input amplitude frame_rate: Output frame rate avg_alpha: FFT averaging (over time) constant [0.0-1.0] average: Whether to average [True, False] win: the window taps generation function shift: shift zero-frequency component to center of spectrum """ gr.hier_block2.__init__( self, self._name, # Input signature gr.io_signature(1, 1, self._item_size), gr.io_signature(1, 1, gr.sizeof_float * fft_size)) # Output signature self._sd = blocks.stream_to_vector_decimator(item_size=self._item_size, sample_rate=sample_rate, vec_rate=frame_rate, vec_len=fft_size) if win is None: win = window.blackmanharris fft_window = win(fft_size) fft = self._fft_block[0](fft_size, True, fft_window, shift=shift) window_power = sum([x * x for x in fft_window]) c2magsq = blocks.complex_to_mag_squared(fft_size) self._avg = filter.single_pole_iir_filter_ff(1.0, fft_size) self._log = blocks.nlog10_ff( 10, fft_size, # Adjust for number of bins -20 * math.log10(fft_size) - # Adjust for windowing loss 10 * math.log10(float(window_power) / fft_size) - 20 * math.log10(float(ref_scale) / 2)) # Adjust for reference scale self.connect(self, self._sd, fft, c2magsq, self._avg, self._log, self) self._average = average self._avg_alpha = avg_alpha self.set_avg_alpha(avg_alpha) self.set_average(average)
def __rebuild(self): if self.__signal_type.is_analytic(): input_length = self.__freq_resolution output_length = self.__freq_resolution self.__after_fft = None else: # use vector_to_streams to cut the output in half and discard the redundant part input_length = self.__freq_resolution * 2 output_length = self.__freq_resolution self.__after_fft = blocks.vector_to_streams( itemsize=output_length * gr.sizeof_float, nstreams=2) sample_rate = self.__signal_type.get_sample_rate() overlap_factor = int( math.ceil(_maximum_fft_rate * input_length / sample_rate)) # sanity limit -- OverlapGimmick is not free overlap_factor = min(16, overlap_factor) self.__gate = blocks.copy(gr.sizeof_gr_complex) self.__gate.set_enabled(not self.__paused) self.__fft_sink = MessageDistributorSink( itemsize=output_length * gr.sizeof_char, context=self.__context, migrate=self.__fft_sink, notify=self.__update_interested) self.__overlapper = _OverlapGimmick(size=input_length, factor=overlap_factor, itemsize=self.__itemsize) # Adjusts units so displayed level is independent of resolution and sample rate. Also throw in the packing offset compensation = to_dB(input_length / sample_rate) + self.__power_offset # TODO: Consider not using the logpwrfft block self.__logpwrfft = logpwrfft.logpwrfft_c( sample_rate=sample_rate * overlap_factor, fft_size=input_length, ref_scale=10.0**(-compensation / 20.0) * 2, # not actually using this as a reference scale value but avoiding needing to use a separate add operation to apply the unit change -- this expression is the inverse of what logpwrfft does internally frame_rate=self.__frame_rate, avg_alpha=1.0, average=False) # It would make slightly more sense to use unsigned chars, but blocks.float_to_uchar does not support vlen. self.__fft_converter = blocks.float_to_char( vlen=self.__freq_resolution, scale=1.0) self.__scope_sink = MessageDistributorSink( itemsize=self.__time_length * gr.sizeof_gr_complex, context=self.__context, migrate=self.__scope_sink, notify=self.__update_interested) self.__scope_chunker = blocks.stream_to_vector_decimator( item_size=gr.sizeof_gr_complex, sample_rate=sample_rate, vec_rate=self.__frame_rate, # TODO doesn't need to be coupled vec_len=self.__time_length)
def __rebuild(self): if self.__signal_type.is_analytic(): input_length = self.__freq_resolution output_length = self.__freq_resolution self.__after_fft = None else: # use vector_to_streams to cut the output in half and discard the redundant part input_length = self.__freq_resolution * 2 output_length = self.__freq_resolution self.__after_fft = blocks.vector_to_streams(itemsize=output_length * gr.sizeof_float, nstreams=2) sample_rate = self.__signal_type.get_sample_rate() overlap_factor = int(math.ceil(_maximum_fft_rate * input_length / sample_rate)) # sanity limit -- OverlapGimmick is not free overlap_factor = min(16, overlap_factor) self.__gate = blocks.copy(gr.sizeof_gr_complex) self.__gate.set_enabled(not self.__paused) self.__fft_sink = MessageDistributorSink( itemsize=output_length * gr.sizeof_char, context=self.__context, migrate=self.__fft_sink, notify=self.__update_interested) self.__overlapper = _OverlapGimmick( size=input_length, factor=overlap_factor, itemsize=self.__itemsize) # Adjusts units so displayed level is independent of resolution and sample rate. Also throw in the packing offset compensation = to_dB(input_length / sample_rate) + self.__power_offset # TODO: Consider not using the logpwrfft block self.__logpwrfft = logpwrfft.logpwrfft_c( sample_rate=sample_rate * overlap_factor, fft_size=input_length, ref_scale=10.0 ** (-compensation / 20.0) * 2, # not actually using this as a reference scale value but avoiding needing to use a separate add operation to apply the unit change -- this expression is the inverse of what logpwrfft does internally frame_rate=self.__frame_rate, avg_alpha=1.0, average=False) # It would make slightly more sense to use unsigned chars, but blocks.float_to_uchar does not support vlen. self.__fft_converter = blocks.float_to_char(vlen=self.__freq_resolution, scale=1.0) self.__scope_sink = MessageDistributorSink( itemsize=self.__time_length * gr.sizeof_gr_complex, context=self.__context, migrate=self.__scope_sink, notify=self.__update_interested) self.__scope_chunker = blocks.stream_to_vector_decimator( item_size=gr.sizeof_gr_complex, sample_rate=sample_rate, vec_rate=self.__frame_rate, # TODO doesn't need to be coupled vec_len=self.__time_length)
def test_log_level_for_hier_block(self): # Test the python API for getting and setting log levels for hier blocks nsrc = blocks.null_source(4) nsnk = blocks.null_sink(4) b = blocks.stream_to_vector_decimator(4, 1, 1, 1) # just a random hier block that exists tb = gr.top_block() tb.connect(nsrc, b, nsnk) tb.set_log_level("debug") self.assertEqual(tb.log_level(), "debug") self.assertEqual(nsrc.log_level(), "debug") self.assertEqual(nsnk.log_level(), "debug") self.assertEqual(b.one_in_n.log_level(), "debug") tb.set_log_level("alert") self.assertEqual(tb.log_level(), "alert") self.assertEqual(nsrc.log_level(), "alert") self.assertEqual(nsnk.log_level(), "alert") self.assertEqual(b.one_in_n.log_level(), "alert")
def __init__(self, sample_rate, pspectrum_len, ref_scale, frame_rate, avg_alpha, average, n, m, nsamples, estimator = 'esprit'): """ Create an log10(abs(spectrum_estimate)) stream chain. Provide access to the setting the filter and sample rate. @param sample_rate Incoming stream sample rate @param pspectrum_len Number of FFT bins @param ref_scale Sets 0 dB value input amplitude @param frame_rate Output frame rate @param avg_alpha averaging (over time) constant [0.0-1.0] @param average Whether to average [True, False] @param n Parameter n for the estimator @param m Parameter m for the estimator @param nsamples Number of samples to use for estimation @param estimator Estimator to use, can be either 'esprit' or 'music' """ gr.hier_block2.__init__(self, self._name, gr.io_signature(1, 1, self._item_size), # Input signature gr.io_signature(1, 1, gr.sizeof_float*pspectrum_len)) # Output signature self._sd = blocks.stream_to_vector_decimator(item_size=self._item_size, sample_rate=sample_rate, vec_rate=frame_rate, vec_len=nsamples) if estimator == 'esprit': est = specest.esprit_spectrum_vcf(n,m,nsamples,pspectrum_len) elif estimator == 'music': est = specest.music_spectrum_vcf(n,m,nsamples,pspectrum_len) else: est = specest.esprit_spectrum_vcf(n,m,nsamples,pspectrum_len) self._avg = gr.single_pole_iir_filter_ff(1.0, pspectrum_len) self._log = gr.nlog10_ff(20, pspectrum_len, -20*math.log10(pspectrum_len) # Adjust for number of bins -20*math.log10(ref_scale/2)+3.0) # Adjust for reference scale self.connect(self, self._sd, est, self._avg, self._log, self) self._average = average self._avg_alpha = avg_alpha self.set_avg_alpha(avg_alpha) self.set_average(average)
def __init__(self, sample_rate, fft_size, ref_scale, frame_rate, avg_alpha, average, win=None): """ Create an log10(abs(fft)) stream chain. Provide access to the setting the filter and sample rate. Args: sample_rate: Incoming stream sample rate fft_size: Number of FFT bins ref_scale: Sets 0 dB value input amplitude frame_rate: Output frame rate avg_alpha: FFT averaging (over time) constant [0.0-1.0] average: Whether to average [True, False] win: the window taps generation function """ gr.hier_block2.__init__(self, self._name, gr.io_signature(1, 1, self._item_size), # Input signature gr.io_signature(1, 1, gr.sizeof_float*fft_size)) # Output signature self._sd = blocks.stream_to_vector_decimator(item_size=self._item_size, sample_rate=sample_rate, vec_rate=frame_rate, vec_len=fft_size) if win is None: win = window.blackmanharris fft_window = win(fft_size) fft = self._fft_block[0](fft_size, True, fft_window) window_power = sum(map(lambda x: x*x, fft_window)) c2magsq = blocks.complex_to_mag_squared(fft_size) self._avg = filter.single_pole_iir_filter_ff(1.0, fft_size) self._log = blocks.nlog10_ff(10, fft_size, -20*math.log10(fft_size) # Adjust for number of bins -10*math.log10(window_power/fft_size) # Adjust for windowing loss -20*math.log10(ref_scale/2)) # Adjust for reference scale self.connect(self, self._sd, fft, c2magsq, self._avg, self._log, self) self._average = average self._avg_alpha = avg_alpha self.set_avg_alpha(avg_alpha) self.set_average(average)
def __init__(self): gr.top_block.__init__(self) self.sample_rate = 5000000 self.ampl = 0.1 self.freq = 144000000 self.stream = blocks.stream_to_vector_decimator( item_size=gr.sizeof_gr_complex, sample_rate=self.sample_rate, vec_rate=30, vec_len=1024, ) self.probe = blocks.probe_signal_vf(1024) self.fft = fft.fft_vcc(1024, True, (window.blackmanharris(1024)), True, 1) src0 = analog.sig_source_c(self.sample_rate, analog.GR_SIN_WAVE, self.freq, self.ampl) dst = audio.sink(self.sample_rate, "") self.sqrt = blocks.complex_to_mag_squared(1024) def fft_out(): while 1: val = self.probe.level() print max(val) freq = (val.index(max(val)) - 512) * (self.sample_rate/1024.0) print freq time.sleep(1) fft_thread = threading.Thread(target=fft_out) fft_thread.daemon = True fft_thread.start() self.connect((src0,0),(self.stream, 0)) self.connect((self.stream, 0),(self.fft, 0)) self.connect((self.fft, 0),(self.sqrt, 0)) self.connect((self.sqrt, 0),(self.probe, 0))
def __init__( self, parent, unit='units', minval=0, maxval=1, factor=1, decimal_places=3, ref_level=0, sample_rate=1, number_rate=number_window.DEFAULT_NUMBER_RATE, average=False, avg_alpha=None, label='Number Plot', size=number_window.DEFAULT_WIN_SIZE, peak_hold=False, show_gauge=True, **kwargs #catchall for backwards compatibility ): #ensure avg alpha if avg_alpha is None: avg_alpha = 2.0/number_rate #init gr.hier_block2.__init__( self, "number_sink", gr.io_signature(1, 1, self._item_size), gr.io_signature(0, 0, 0), ) #blocks sd = blocks.stream_to_vector_decimator( item_size=self._item_size, sample_rate=sample_rate, vec_rate=number_rate, vec_len=1, ) if self._real: mult = blocks.multiply_const_ff(factor) add = blocks.add_const_ff(ref_level) avg = filter.single_pole_iir_filter_ff(1.0) else: mult = blocks.multiply_const_cc(factor) add = blocks.add_const_cc(ref_level) avg = filter.single_pole_iir_filter_cc(1.0) msgq = gr.msg_queue(2) sink = blocks.message_sink(self._item_size, msgq, True) #controller self.controller = pubsub() self.controller.subscribe(SAMPLE_RATE_KEY, sd.set_sample_rate) self.controller.publish(SAMPLE_RATE_KEY, sd.sample_rate) self.controller[AVERAGE_KEY] = average self.controller[AVG_ALPHA_KEY] = avg_alpha def update_avg(*args): if self.controller[AVERAGE_KEY]: avg.set_taps(self.controller[AVG_ALPHA_KEY]) else: avg.set_taps(1.0) update_avg() self.controller.subscribe(AVERAGE_KEY, update_avg) self.controller.subscribe(AVG_ALPHA_KEY, update_avg) #start input watcher common.input_watcher(msgq, self.controller, MSG_KEY) #create window self.win = number_window.number_window( parent=parent, controller=self.controller, size=size, title=label, units=unit, real=self._real, minval=minval, maxval=maxval, decimal_places=decimal_places, show_gauge=show_gauge, average_key=AVERAGE_KEY, avg_alpha_key=AVG_ALPHA_KEY, peak_hold=peak_hold, msg_key=MSG_KEY, sample_rate_key=SAMPLE_RATE_KEY, ) common.register_access_methods(self, self.controller) #backwards compadibility self.set_show_gauge = self.win.show_gauges #connect self.wxgui_connect(self, sd, mult, add, avg, sink)
def __init__(self, parent, minval=0, maxval=1, sample_rate=1, graphing_rate=1, size=antdiag_window.DEFAULT_WIN_SIZE, peak_hold=False, serial_port='/dev/ttyUSB0', rotation_speed=60, **kwargs #catchall for backwards compatibility ): #init self._item_size=gr.sizeof_float gr.hier_block2.__init__( self, "antenna_diagram", gr.io_signature(1, 1, self._item_size), gr.io_signature(0, 0, 0), ) #blocks sd = blocks.stream_to_vector_decimator( item_size=gr.sizeof_float, sample_rate=sample_rate, vec_rate=graphing_rate, vec_len=1, ) #mult = blocks.multiply_const_ff(factor) #add = blocks.add_const_ff(ref_level) #avg = filter.single_pole_iir_filter_ff(1.0) msgq = gr.msg_queue(2) sink = blocks.message_sink(self._item_size, msgq, True) #controller self.controller = pubsub() self.controller.subscribe(SAMPLE_RATE_KEY, sd.set_sample_rate) self.controller.publish(SAMPLE_RATE_KEY, sd.sample_rate) self.controller[antdiag_window.SERIAL_PORT_KEY] = serial_port #self.controller[AVERAGE_KEY] = False #self.controller[AVG_ALPHA_KEY] = None #def update_avg(*args): # if self.controller[AVERAGE_KEY]: avg.set_taps(self.controller[AVG_ALPHA_KEY]) # else: avg.set_taps(1.0) #update_avg() #self.controller.subscribe(AVERAGE_KEY, update_avg) #self.controller.subscribe(AVG_ALPHA_KEY, update_avg) #start input watcher common.input_watcher(msgq, self.controller, MSG_KEY) #create window self.win = antdiag_window.antdiag_window( parent=parent, controller=self.controller, size=size, minval=minval, maxval=maxval, peak_hold=peak_hold, msg_key=MSG_KEY, graphing_rate=graphing_rate, rotation_speed=rotation_speed ) common.register_access_methods(self, self.controller) #backwards compadibility self.set_show_gauge = self.win.show_gauges #connect #self.wxgui_connect(self, sd, mult, add, avg, sink) self.wxgui_connect(self, sd, sink)
def __init__(self): gr.top_block.__init__(self) self.sample_rate = 5000000 self.ampl = 1 self.freq = 144000000 self.counter = 0 # --- Sources ---- self.uhd = uhd.usrp_source( ",".join(("", "")), uhd.stream_args( cpu_format="fc32", channels=range(1), ), ) self.uhd.set_samp_rate(self.sample_rate) self.uhd.set_center_freq(self.freq, 0) self.uhd.set_gain(0, 0) self.uhd.set_antenna("RX2", 0) # --- Blocks ----- self.throttle = blocks.throttle(gr.sizeof_gr_complex*1, self.sample_rate,True) self.streamToVector = blocks.stream_to_vector_decimator( item_size=gr.sizeof_gr_complex, sample_rate=self.sample_rate, vec_rate=30, vec_len=1024, ) self.fft = fft.fft_vcc(1024, True, (window.blackmanharris(1024)), 1) self.complexToMag = blocks.complex_to_mag_squared(1024) self.probe = blocks.probe_signal_vf(1024) # --- Functions ---- def fft_cal(): while 1: val = self.probe.level() print "Index: {} Max: {}".format(val.index(max(val)),max(val)) if max(val): pow_ran = [] freq_ran = [] for i in val: pow_ran.append(float(i)/max(val)) for i in range(1024): freq_ran.append((i*self.sample_rate/1024.0) + (self.freq - (self.sample_rate/2.0)) ) fig = plt.plot(freq_ran,pow_ran) plt.ylim(-0.3,1.2) plt.xlim(min(freq_ran),max(freq_ran)) plt.show() time.sleep(1) # --- Start Thread --- fft_thread = threading.Thread(target=fft_cal) fft_thread.daemon = True fft_thread.start() # --- Conections --- self.connect((self.uhd, 0), (self.throttle, 0)) self.connect((self.throttle, 0), (self.streamToVector, 0)) self.connect((self.streamToVector, 0), (self.fft, 0)) self.connect((self.fft, 0),(self.complexToMag, 0)) self.connect((self.complexToMag, 0),(self.probe, 0))
def __do_connect(self): itemsize = self.__itemsize if self.__signal_type.is_analytic(): input_length = self.__freq_resolution output_length = self.__freq_resolution self.__after_fft = None else: # use vector_to_streams to cut the output in half and discard the redundant part input_length = self.__freq_resolution * 2 output_length = self.__freq_resolution self.__after_fft = blocks.vector_to_streams( itemsize=output_length * gr.sizeof_float, nstreams=2) sample_rate = self.__signal_type.get_sample_rate() overlap_factor = int( math.ceil(_maximum_fft_rate * input_length / sample_rate)) # sanity limit -- OverlapGimmick is not free overlap_factor = min(16, overlap_factor) self.__frame_rate_to_decimation_conversion = sample_rate * overlap_factor / input_length self.__gate = blocks.copy(itemsize) self.__gate.set_enabled(not self.__paused) overlapper = _OverlappedStreamToVector(size=input_length, factor=overlap_factor, itemsize=itemsize) self.__frame_dec = blocks.keep_one_in_n( itemsize=itemsize * input_length, n=max( 1, int( round(self.__frame_rate_to_decimation_conversion / self.__frame_rate)))) # the actual FFT logic, which is similar to GR's logpwrfft_c window = windows.build(self.__window_type, input_length, 6.76) window_power = sum(x * x for x in window) # TODO: use fft_vfc when applicable fft_block = (fft_vcc if itemsize == gr.sizeof_gr_complex else fft_vfc)( fft_size=input_length, forward=True, window=window) mag_squared = blocks.complex_to_mag_squared(input_length) logarithmizer = blocks.nlog10_ff( n=10, # the "deci" in "decibel" vlen=input_length, k=( -to_dB(window_power) + # compensate for window -to_dB(sample_rate) + # convert from power-per-sample to power-per-Hz self.__power_offset # offset for packing into bytes )) # It would make slightly more sense to use unsigned chars, but blocks.float_to_uchar does not support vlen. self.__fft_converter = blocks.float_to_char( vlen=self.__freq_resolution, scale=1.0) fft_sink = self.__fft_cell.create_sink_internal( numpy.dtype((numpy.int8, output_length))) scope_sink = self.__scope_cell.create_sink_internal( numpy.dtype(('c8', self.__time_length))) scope_chunker = blocks.stream_to_vector_decimator( item_size=gr.sizeof_gr_complex, sample_rate=sample_rate, vec_rate=self.__frame_rate, # TODO doesn't need to be coupled vec_len=self.__time_length) # connect everything self.__context.lock() try: self.disconnect_all() self.connect(self, self.__gate, overlapper, self.__frame_dec, fft_block, mag_squared, logarithmizer) if self.__after_fft is not None: self.connect(logarithmizer, self.__after_fft) self.connect(self.__after_fft, self.__fft_converter, fft_sink) self.connect( (self.__after_fft, 1), blocks.null_sink(gr.sizeof_float * self.__freq_resolution)) else: self.connect(logarithmizer, self.__fft_converter, fft_sink) if self.__enable_scope: self.connect(self.__gate, scope_chunker, scope_sink) finally: self.__context.unlock()
def __init__(self): gr.top_block.__init__(self) self.sample_rate = 3000 self.ampl = 1 self.freq = 1900 self.cen_freq = 0 self.counter = 0 # --- Sources ---- self.src0 = analog.sig_source_f(self.sample_rate, analog.GR_COS_WAVE, self.freq, 1, 0) self.src1 = analog.sig_source_f(self.sample_rate, analog.GR_COS_WAVE, self.freq/2, 1, 0) # --- Audio Out --- self.audioOut = audio.sink(32000, "", True) # --- Blocks ----- self.add = blocks.add_vff(1) #Add Block #self.throttle = blocks.throttle(gr.sizeof_float*1, self.sample_rate,True) self.streamToVector = blocks.stream_to_vector_decimator( item_size=gr.sizeof_float, sample_rate=self.sample_rate, vec_rate=30, vec_len=1024, ) self.fft = fft.fft_vfc(1024, True, (window.blackmanharris(1024)), 1) self.complexToMag = blocks.complex_to_mag_squared(1024) self.probe = blocks.probe_signal_vf(1024) # --- Functions ---- def fft_cal(): while 1: val = self.probe.level() print "Index: {}".format(val.index(max(val))) freq = (val.index(max(val))) * (self.sample_rate/1024.0) print freq print len(val) time.sleep(1) #self.set_freq(self.freq+100) pow_ran = [] freq_ran = [] if self.counter: for i in val: pow_ran.append(float(i)/max(val)) for i in range(1024): freq_ran.append(i*self.sample_rate/1024.0) fig = plt.plot(freq_ran,pow_ran) plt.ylim(-0.3,1.2) plt.xlim(min(freq_ran),max(freq_ran)) plt.show() self.counter+=1 # --- Start Thread --- fft_thread = threading.Thread(target=fft_cal) fft_thread.daemon = True fft_thread.start() # --- Conections --- #self.connect((self.src0, 0), (self.add, 0)) #self.connect((self.src1, 0), (self.add, 1)) #self.connect((self.add, 0), (self.audioOut, 0)) #self.connect((self.src0, 0), (self.throttle, 0)) #self.connect((self.throttle, 0), (self.streamToVector, 0)) self.connect((self.src0, 0), (self.streamToVector, 0)) self.connect((self.streamToVector, 0), (self.fft, 0)) self.connect((self.fft, 0),(self.complexToMag, 0)) self.connect((self.complexToMag, 0),(self.probe, 0))
def __init__(self): gr.top_block.__init__(self, "Not titled yet") Qt.QWidget.__init__(self) self.setWindowTitle("Not titled yet") qtgui.util.check_set_qss() try: self.setWindowIcon(Qt.QIcon.fromTheme('gnuradio-grc')) except: pass self.top_scroll_layout = Qt.QVBoxLayout() self.setLayout(self.top_scroll_layout) self.top_scroll = Qt.QScrollArea() self.top_scroll.setFrameStyle(Qt.QFrame.NoFrame) self.top_scroll_layout.addWidget(self.top_scroll) self.top_scroll.setWidgetResizable(True) self.top_widget = Qt.QWidget() self.top_scroll.setWidget(self.top_widget) self.top_layout = Qt.QVBoxLayout(self.top_widget) self.top_grid_layout = Qt.QGridLayout() self.top_layout.addLayout(self.top_grid_layout) self.settings = Qt.QSettings("GNU Radio", "test") try: if StrictVersion(Qt.qVersion()) < StrictVersion("5.0.0"): self.restoreGeometry(self.settings.value("geometry").toByteArray()) else: self.restoreGeometry(self.settings.value("geometry")) except: pass ################################################## # Variables ################################################## self.samp_rate = samp_rate = 10 ################################################## # Blocks ################################################## self.rational_resampler_xxx_2 = filter.rational_resampler_fff( interpolation=10, decimation=1, taps=None, fractional_bw=None) self.qtgui_time_sink_x_1 = qtgui.time_sink_f( 300, #size samp_rate, #samp_rate "", #name 2 #number of inputs ) self.qtgui_time_sink_x_1.set_update_time(1) self.qtgui_time_sink_x_1.set_y_axis(-1, 10) self.qtgui_time_sink_x_1.set_y_label('Amplitude', "") self.qtgui_time_sink_x_1.enable_tags(True) self.qtgui_time_sink_x_1.set_trigger_mode(qtgui.TRIG_MODE_FREE, qtgui.TRIG_SLOPE_POS, 0.0, 0, 0, "") self.qtgui_time_sink_x_1.enable_autoscale(False) self.qtgui_time_sink_x_1.enable_grid(False) self.qtgui_time_sink_x_1.enable_axis_labels(True) self.qtgui_time_sink_x_1.enable_control_panel(False) self.qtgui_time_sink_x_1.enable_stem_plot(False) labels = ['Signal 1', 'Signal 2', 'Signal 3', 'Signal 4', 'Signal 5', 'Signal 6', 'Signal 7', 'Signal 8', 'Signal 9', 'Signal 10'] widths = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] colors = ['blue', 'red', 'green', 'black', 'cyan', 'magenta', 'yellow', 'dark red', 'dark green', 'dark blue'] alphas = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] styles = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] markers = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1] for i in range(2): if len(labels[i]) == 0: self.qtgui_time_sink_x_1.set_line_label(i, "Data {0}".format(i)) else: self.qtgui_time_sink_x_1.set_line_label(i, labels[i]) self.qtgui_time_sink_x_1.set_line_width(i, widths[i]) self.qtgui_time_sink_x_1.set_line_color(i, colors[i]) self.qtgui_time_sink_x_1.set_line_style(i, styles[i]) self.qtgui_time_sink_x_1.set_line_marker(i, markers[i]) self.qtgui_time_sink_x_1.set_line_alpha(i, alphas[i]) self._qtgui_time_sink_x_1_win = sip.wrapinstance(self.qtgui_time_sink_x_1.pyqwidget(), Qt.QWidget) self.top_grid_layout.addWidget(self._qtgui_time_sink_x_1_win) self.qtgui_time_sink_x_0 = qtgui.time_sink_f( 30, #size samp_rate / 10, #samp_rate "", #name 1 #number of inputs ) self.qtgui_time_sink_x_0.set_update_time(1) self.qtgui_time_sink_x_0.set_y_axis(-1, 10) self.qtgui_time_sink_x_0.set_y_label('Amplitude', "") self.qtgui_time_sink_x_0.enable_tags(False) self.qtgui_time_sink_x_0.set_trigger_mode(qtgui.TRIG_MODE_FREE, qtgui.TRIG_SLOPE_POS, 0.0, 0, 0, "") self.qtgui_time_sink_x_0.enable_autoscale(False) self.qtgui_time_sink_x_0.enable_grid(False) self.qtgui_time_sink_x_0.enable_axis_labels(True) self.qtgui_time_sink_x_0.enable_control_panel(False) self.qtgui_time_sink_x_0.enable_stem_plot(False) labels = ['Signal 1', 'Signal 2', 'Signal 3', 'Signal 4', 'Signal 5', 'Signal 6', 'Signal 7', 'Signal 8', 'Signal 9', 'Signal 10'] widths = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] colors = ['blue', 'red', 'green', 'black', 'cyan', 'magenta', 'yellow', 'dark red', 'dark green', 'dark blue'] alphas = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] styles = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] markers = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1] for i in range(1): if len(labels[i]) == 0: self.qtgui_time_sink_x_0.set_line_label(i, "Data {0}".format(i)) else: self.qtgui_time_sink_x_0.set_line_label(i, labels[i]) self.qtgui_time_sink_x_0.set_line_width(i, widths[i]) self.qtgui_time_sink_x_0.set_line_color(i, colors[i]) self.qtgui_time_sink_x_0.set_line_style(i, styles[i]) self.qtgui_time_sink_x_0.set_line_marker(i, markers[i]) self.qtgui_time_sink_x_0.set_line_alpha(i, alphas[i]) self._qtgui_time_sink_x_0_win = sip.wrapinstance(self.qtgui_time_sink_x_0.pyqwidget(), Qt.QWidget) self.top_grid_layout.addWidget(self._qtgui_time_sink_x_0_win) self.find_max_channel_0 = find_max_channel.find_max_channel(10, 8) self.blocks_throttle_0 = blocks.throttle(gr.sizeof_float*1, samp_rate,True) self.blocks_stream_to_vector_decimator_0 = blocks.stream_to_vector_decimator( item_size=gr.sizeof_float, sample_rate=samp_rate, vec_rate=samp_rate / 10, vec_len=10) self.blocks_int_to_float_0 = blocks.int_to_float(1, 1) self.analog_random_source_x_0 = blocks.vector_source_i(list(map(int, numpy.random.randint(0, 10, 300))), True) ################################################## # Connections ################################################## self.connect((self.analog_random_source_x_0, 0), (self.blocks_int_to_float_0, 0)) self.connect((self.blocks_int_to_float_0, 0), (self.blocks_throttle_0, 0)) self.connect((self.blocks_stream_to_vector_decimator_0, 0), (self.find_max_channel_0, 0)) self.connect((self.blocks_throttle_0, 0), (self.blocks_stream_to_vector_decimator_0, 0)) self.connect((self.blocks_throttle_0, 0), (self.qtgui_time_sink_x_1, 1)) self.connect((self.find_max_channel_0, 0), (self.qtgui_time_sink_x_0, 0)) self.connect((self.find_max_channel_0, 0), (self.rational_resampler_xxx_2, 0)) self.connect((self.rational_resampler_xxx_2, 0), (self.qtgui_time_sink_x_1, 0))
def __init__(self, sample_rate, fft_size, ref_scale, frame_rate, avg_alpha, average, win=None): """ Create an log10(abs(fft)) stream chain. Provide access to the setting the filter and sample rate. Args: sample_rate: Incoming stream sample rate fft_size: Number of FFT bins ref_scale: Sets 0 dB value input amplitude frame_rate: Output frame rate avg_alpha: FFT averaging (over time) constant [0.0-1.0] average: Whether to average [True, False] win: the window taps generation function """ gr.hier_block2.__init__(self, self._name, gr.io_signature(1, 1, self._item_size), # Input signature gr.io_signature(1, 1, gr.sizeof_float*fft_size)) # Output signature self._sd = blocks.stream_to_vector_decimator(item_size=self._item_size, sample_rate=sample_rate, vec_rate=frame_rate, vec_len=fft_size) if win is None: win = window.blackmanharris fft_window = win(fft_size) fft = self._fft_block[0](fft_size, True, fft_window) window_power = sum(map(lambda x: x*x, fft_window)) c2magsq = blocks.complex_to_mag_squared(fft_size) self._avg = filter.single_pole_iir_filter_ff(1.0, fft_size) # Computes the average # Separate stream into 30 samples self.deint= blocks.deinterleave(gr.sizeof_float*fft_size, 1)#vector length, blocks size=1, since we need to separate in blocks of 1 vector of 1024 samples (is fft_size=1024) #Add the 30 new streams self.add = blocks.add_vff(fft_size)#floats in, floats out, vector of fft_zise elements # Divide in 30= multiply *(1/30) self.factor=1.0/30.0 self.divide= blocks.multiply_const_vff((fft_size*[self.factor]))#float in, floats out, divide in a vector of length fft_size and values of self.factor # Logarithm is only needed to show the result in the GUI self._log = blocks.nlog10_ff(10, fft_size, -20*math.log10(fft_size) # Adjust for number of bins -10*math.log10(window_power/fft_size) # Adjust for windowing loss -20*math.log10(ref_scale/2)) # Adjust for reference scale #vector to str #self.dst=blocks.vector_sink_f() self.connect(self, self._sd, fft, c2magsq, self.deint) #self.connect(self._log, self.dst) #Connects blocks which are an average. We should have 30 ports for i in range (0,29): self.connect((self.deint, i), (self.add, i)) # Divide in 30 self.connect(self.add , self) #self.connect(self.add ,self._log, self) self._average = average self._avg_alpha = avg_alpha self.set_avg_alpha(avg_alpha) self.set_average(average)
def __do_connect(self): itemsize = self.__itemsize if self.__signal_type.is_analytic(): input_length = self.__freq_resolution output_length = self.__freq_resolution self.__after_fft = None else: # use vector_to_streams to cut the output in half and discard the redundant part input_length = self.__freq_resolution * 2 output_length = self.__freq_resolution self.__after_fft = blocks.vector_to_streams(itemsize=output_length * gr.sizeof_float, nstreams=2) sample_rate = self.__signal_type.get_sample_rate() overlap_factor = int(math.ceil(_maximum_fft_rate * input_length / sample_rate)) # sanity limit -- OverlapGimmick is not free overlap_factor = min(16, overlap_factor) self.__frame_rate_to_decimation_conversion = sample_rate * overlap_factor / input_length self.__gate = blocks.copy(itemsize) self.__gate.set_enabled(not self.__paused) overlapper = _OverlappedStreamToVector( size=input_length, factor=overlap_factor, itemsize=itemsize) self.__frame_dec = blocks.keep_one_in_n( itemsize=itemsize * input_length, n=int(round(self.__frame_rate_to_decimation_conversion / self.__frame_rate))) # the actual FFT logic, which is similar to GR's logpwrfft_c window = windows.blackmanharris(input_length) window_power = sum(x * x for x in window) # TODO: use fft_vfc when applicable fft_block = (fft_vcc if itemsize == gr.sizeof_gr_complex else fft_vfc)( fft_size=input_length, forward=True, window=window) mag_squared = blocks.complex_to_mag_squared(input_length) logarithmizer = blocks.nlog10_ff( n=10, # the "deci" in "decibel" vlen=input_length, k=( -to_dB(window_power) + # compensate for window -to_dB(sample_rate) + # convert from power-per-sample to power-per-Hz self.__power_offset # offset for packing into bytes )) # It would make slightly more sense to use unsigned chars, but blocks.float_to_uchar does not support vlen. self.__fft_converter = blocks.float_to_char(vlen=self.__freq_resolution, scale=1.0) self.__fft_sink = MessageDistributorSink( itemsize=output_length * gr.sizeof_char, context=self.__context, migrate=self.__fft_sink, notify=self.__update_interested) self.__scope_sink = MessageDistributorSink( itemsize=self.__time_length * gr.sizeof_gr_complex, context=self.__context, migrate=self.__scope_sink, notify=self.__update_interested) scope_chunker = blocks.stream_to_vector_decimator( item_size=gr.sizeof_gr_complex, sample_rate=sample_rate, vec_rate=self.__frame_rate, # TODO doesn't need to be coupled vec_len=self.__time_length) # connect everything self.__context.lock() try: self.disconnect_all() self.connect( self, self.__gate, overlapper, self.__frame_dec, fft_block, mag_squared, logarithmizer) if self.__after_fft is not None: self.connect(logarithmizer, self.__after_fft) self.connect(self.__after_fft, self.__fft_converter, self.__fft_sink) self.connect((self.__after_fft, 1), blocks.null_sink(gr.sizeof_float * self.__freq_resolution)) else: self.connect(logarithmizer, self.__fft_converter, self.__fft_sink) if self.__enable_scope: self.connect( self.__gate, scope_chunker, self.__scope_sink) finally: self.__context.unlock()
def __init__( self, parent, unit='units', minval=0, maxval=1, factor=1, decimal_places=3, ref_level=0, sample_rate=1, number_rate=number_window.DEFAULT_NUMBER_RATE, average=False, avg_alpha=None, label='Number Plot', size=number_window.DEFAULT_WIN_SIZE, peak_hold=False, show_gauge=True, **kwargs #catchall for backwards compatibility ): #ensure avg alpha if avg_alpha is None: avg_alpha = 2.0 / number_rate #init gr.hier_block2.__init__( self, "number_sink", gr.io_signature(1, 1, self._item_size), gr.io_signature(0, 0, 0), ) #blocks sd = blocks.stream_to_vector_decimator( item_size=self._item_size, sample_rate=sample_rate, vec_rate=number_rate, vec_len=1, ) if self._real: mult = blocks.multiply_const_ff(factor) add = blocks.add_const_ff(ref_level) avg = filter.single_pole_iir_filter_ff(1.0) else: mult = blocks.multiply_const_cc(factor) add = blocks.add_const_cc(ref_level) avg = filter.single_pole_iir_filter_cc(1.0) msgq = gr.msg_queue(2) sink = blocks.message_sink(self._item_size, msgq, True) #controller self.controller = pubsub() self.controller.subscribe(SAMPLE_RATE_KEY, sd.set_sample_rate) self.controller.publish(SAMPLE_RATE_KEY, sd.sample_rate) self.controller[AVERAGE_KEY] = average self.controller[AVG_ALPHA_KEY] = avg_alpha def update_avg(*args): if self.controller[AVERAGE_KEY]: avg.set_taps(self.controller[AVG_ALPHA_KEY]) else: avg.set_taps(1.0) update_avg() self.controller.subscribe(AVERAGE_KEY, update_avg) self.controller.subscribe(AVG_ALPHA_KEY, update_avg) #start input watcher common.input_watcher(msgq, self.controller, MSG_KEY) #create window self.win = number_window.number_window( parent=parent, controller=self.controller, size=size, title=label, units=unit, real=self._real, minval=minval, maxval=maxval, decimal_places=decimal_places, show_gauge=show_gauge, average_key=AVERAGE_KEY, avg_alpha_key=AVG_ALPHA_KEY, peak_hold=peak_hold, msg_key=MSG_KEY, sample_rate_key=SAMPLE_RATE_KEY, ) common.register_access_methods(self, self.controller) #backwards compadibility self.set_show_gauge = self.win.show_gauges #connect self.wxgui_connect(self, sd, mult, add, avg, sink)
def __init__( self, parent, title='', sample_rate=1, size=const_window.DEFAULT_WIN_SIZE, frame_rate=const_window.DEFAULT_FRAME_RATE, const_size=const_window.DEFAULT_CONST_SIZE, #mpsk recv params M=4, theta=0, loop_bw=6.28/100.0, fmax=0.06, mu=0.5, gain_mu=0.005, symbol_rate=1, omega_limit=0.005, ): #init gr.hier_block2.__init__( self, "const_sink", gr.io_signature(1, 1, gr.sizeof_gr_complex), gr.io_signature(0, 0, 0), ) #blocks sd = blocks.stream_to_vector_decimator( item_size=gr.sizeof_gr_complex, sample_rate=sample_rate, vec_rate=frame_rate, vec_len=const_size, ) fmin = -fmax gain_omega = .25*gain_mu**2 #redundant, will be updated omega = 1 #set_sample_rate will update this # Costas frequency/phase recovery loop # Critically damped 2nd order PLL self._costas = digital.costas_loop_cc(loop_bw, M) # Timing recovery loop # Critically damped 2nd order DLL self._retime = digital.clock_recovery_mm_cc(omega, gain_omega, mu, gain_mu, omega_limit) #sync = gr.mpsk_receiver_cc( # M, #psk order # theta, # alpha, # beta, # fmin, # fmax, # mu, # gain_mu, # omega, # gain_omega, # omega_limit, #) agc = analog.feedforward_agc_cc(16, 1) msgq = gr.msg_queue(2) sink = blocks.message_sink(gr.sizeof_gr_complex*const_size, msgq, True) #controller def setter(p, k, x): p[k] = x self.controller = pubsub() self.controller.subscribe(LOOP_BW_KEY, self._costas.set_loop_bandwidth) self.controller.publish(LOOP_BW_KEY, self._costas.get_loop_bandwidth) self.controller.subscribe(GAIN_MU_KEY, self._retime.set_gain_mu) self.controller.publish(GAIN_MU_KEY, self._retime.gain_mu) self.controller.subscribe(OMEGA_KEY, self._retime.set_omega) self.controller.publish(OMEGA_KEY, self._retime.omega) self.controller.subscribe(GAIN_OMEGA_KEY, self._retime.set_gain_omega) self.controller.publish(GAIN_OMEGA_KEY, self._retime.gain_omega) self.controller.subscribe(SAMPLE_RATE_KEY, sd.set_sample_rate) self.controller.subscribe(SAMPLE_RATE_KEY, lambda x: setter(self.controller, OMEGA_KEY, float(x)/symbol_rate)) self.controller.publish(SAMPLE_RATE_KEY, sd.sample_rate) #initial update self.controller[SAMPLE_RATE_KEY] = sample_rate #start input watcher common.input_watcher(msgq, self.controller, MSG_KEY) #create window self.win = const_window.const_window( parent=parent, controller=self.controller, size=size, title=title, msg_key=MSG_KEY, loop_bw_key=LOOP_BW_KEY, gain_mu_key=GAIN_MU_KEY, gain_omega_key=GAIN_OMEGA_KEY, omega_key=OMEGA_KEY, sample_rate_key=SAMPLE_RATE_KEY, ) common.register_access_methods(self, self.win) #connect self.wxgui_connect(self, self._costas, self._retime, agc, sd, sink)