root / gr-wxgui / src / python / waterfallsink_gl.py @ 36649d4e
History | View | Annotate | Download (5.6 kB)
| 1 | #
|
|---|---|
| 2 | # Copyright 2008 Free Software Foundation, Inc.
|
| 3 | #
|
| 4 | # This file is part of GNU Radio
|
| 5 | #
|
| 6 | # GNU Radio is free software; you can redistribute it and/or modify
|
| 7 | # it under the terms of the GNU General Public License as published by
|
| 8 | # the Free Software Foundation; either version 3, or (at your option)
|
| 9 | # any later version.
|
| 10 | #
|
| 11 | # GNU Radio is distributed in the hope that it will be useful,
|
| 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 14 | # GNU General Public License for more details.
|
| 15 | #
|
| 16 | # You should have received a copy of the GNU General Public License
|
| 17 | # along with GNU Radio; see the file COPYING. If not, write to
|
| 18 | # the Free Software Foundation, Inc., 51 Franklin Street,
|
| 19 | # Boston, MA 02110-1301, USA.
|
| 20 | #
|
| 21 | |
| 22 | ##################################################
|
| 23 | # Imports
|
| 24 | ##################################################
|
| 25 | import waterfall_window |
| 26 | import common |
| 27 | from gnuradio import gr, blks2 |
| 28 | from pubsub import pubsub |
| 29 | from constants import * |
| 30 | |
| 31 | ##################################################
|
| 32 | # Waterfall sink block (wrapper for old wxgui)
|
| 33 | ##################################################
|
| 34 | class _waterfall_sink_base(gr.hier_block2, common.prop_setter): |
| 35 | """!
|
| 36 | An fft block with real/complex inputs and a gui window.
|
| 37 | """ |
| 38 | |
| 39 | def __init__( |
| 40 | self,
|
| 41 | parent, |
| 42 | baseband_freq=0,
|
| 43 | y_per_div=None, #ignore (old wrapper) |
| 44 | ref_level=50,
|
| 45 | sample_rate=1,
|
| 46 | fft_size=512,
|
| 47 | fft_rate=waterfall_window.DEFAULT_FRAME_RATE, |
| 48 | average=False,
|
| 49 | avg_alpha=None,
|
| 50 | title='',
|
| 51 | size=waterfall_window.DEFAULT_WIN_SIZE, |
| 52 | ref_scale=2.0,
|
| 53 | dynamic_range=80,
|
| 54 | num_lines=256,
|
| 55 | ): |
| 56 | #ensure avg alpha
|
| 57 | if avg_alpha is None: avg_alpha = 2.0/fft_rate |
| 58 | #init
|
| 59 | gr.hier_block2.__init__( |
| 60 | self,
|
| 61 | "waterfall_sink",
|
| 62 | gr.io_signature(1, 1, self._item_size), |
| 63 | gr.io_signature(0, 0, 0), |
| 64 | ) |
| 65 | #blocks
|
| 66 | copy = gr.kludge_copy(self._item_size)
|
| 67 | fft = self._fft_chain(
|
| 68 | sample_rate=sample_rate, |
| 69 | fft_size=fft_size, |
| 70 | frame_rate=fft_rate, |
| 71 | ref_scale=ref_scale, |
| 72 | avg_alpha=avg_alpha, |
| 73 | average=average, |
| 74 | ) |
| 75 | msgq = gr.msg_queue(2)
|
| 76 | sink = gr.message_sink(gr.sizeof_float*fft_size, msgq, True)
|
| 77 | #connect
|
| 78 | self.connect(self, copy, fft, sink) |
| 79 | #controller
|
| 80 | self.controller = pubsub()
|
| 81 | self.controller.subscribe(AVERAGE_KEY, fft.set_average)
|
| 82 | self.controller.publish(AVERAGE_KEY, fft.average)
|
| 83 | self.controller.subscribe(AVG_ALPHA_KEY, fft.set_avg_alpha)
|
| 84 | self.controller.publish(AVG_ALPHA_KEY, fft.avg_alpha)
|
| 85 | self.controller.subscribe(SAMPLE_RATE_KEY, fft.set_sample_rate)
|
| 86 | self.controller.publish(SAMPLE_RATE_KEY, fft.sample_rate)
|
| 87 | self.controller.subscribe(DECIMATION_KEY, fft.set_decimation)
|
| 88 | self.controller.publish(DECIMATION_KEY, fft.decimation)
|
| 89 | self.controller.subscribe(FRAME_RATE_KEY, fft.set_vec_rate)
|
| 90 | self.controller.publish(FRAME_RATE_KEY, fft.frame_rate)
|
| 91 | #start input watcher
|
| 92 | def setter(p, k, x): # lambdas can't have assignments :( |
| 93 | p[k] = x |
| 94 | common.input_watcher(msgq, lambda x: setter(self.controller, MSG_KEY, x)) |
| 95 | #create window
|
| 96 | self.win = waterfall_window.waterfall_window(
|
| 97 | parent=parent, |
| 98 | controller=self.controller,
|
| 99 | size=size, |
| 100 | title=title, |
| 101 | real=self._real,
|
| 102 | fft_size=fft_size, |
| 103 | num_lines=num_lines, |
| 104 | baseband_freq=baseband_freq, |
| 105 | decimation_key=DECIMATION_KEY, |
| 106 | sample_rate_key=SAMPLE_RATE_KEY, |
| 107 | frame_rate_key=FRAME_RATE_KEY, |
| 108 | dynamic_range=dynamic_range, |
| 109 | ref_level=ref_level, |
| 110 | average_key=AVERAGE_KEY, |
| 111 | avg_alpha_key=AVG_ALPHA_KEY, |
| 112 | msg_key=MSG_KEY, |
| 113 | ) |
| 114 | #register callbacks from window for external use
|
| 115 | for attr in filter(lambda a: a.startswith('set_'), dir(self.win)): |
| 116 | setattr(self, attr, getattr(self.win, attr)) |
| 117 | self._register_set_prop(self.controller, SAMPLE_RATE_KEY) |
| 118 | self._register_set_prop(self.controller, AVERAGE_KEY) |
| 119 | self._register_set_prop(self.controller, AVG_ALPHA_KEY) |
| 120 | |
| 121 | class waterfall_sink_f(_waterfall_sink_base): |
| 122 | _fft_chain = blks2.logpwrfft_f |
| 123 | _item_size = gr.sizeof_float |
| 124 | _real = True
|
| 125 | |
| 126 | class waterfall_sink_c(_waterfall_sink_base): |
| 127 | _fft_chain = blks2.logpwrfft_c |
| 128 | _item_size = gr.sizeof_gr_complex |
| 129 | _real = False
|
| 130 | |
| 131 | # ----------------------------------------------------------------
|
| 132 | # Standalone test app
|
| 133 | # ----------------------------------------------------------------
|
| 134 | |
| 135 | import wx |
| 136 | from gnuradio.wxgui import stdgui2 |
| 137 | |
| 138 | class test_top_block (stdgui2.std_top_block): |
| 139 | def __init__(self, frame, panel, vbox, argv): |
| 140 | stdgui2.std_top_block.__init__ (self, frame, panel, vbox, argv)
|
| 141 | |
| 142 | fft_size = 512
|
| 143 | |
| 144 | # build our flow graph
|
| 145 | input_rate = 20.000e3
|
| 146 | |
| 147 | # Generate a complex sinusoid
|
| 148 | self.src1 = gr.sig_source_c (input_rate, gr.GR_SIN_WAVE, 5.75e3, 1000) |
| 149 | #src1 = gr.sig_source_c (input_rate, gr.GR_CONST_WAVE, 5.75e3, 1000)
|
| 150 | |
| 151 | # We add these throttle blocks so that this demo doesn't
|
| 152 | # suck down all the CPU available. Normally you wouldn't use these.
|
| 153 | self.thr1 = gr.throttle(gr.sizeof_gr_complex, input_rate)
|
| 154 | |
| 155 | sink1 = waterfall_sink_c (panel, title="Complex Data", fft_size=fft_size,
|
| 156 | sample_rate=input_rate, baseband_freq=100e3)
|
| 157 | self.connect(self.src1, self.thr1, sink1) |
| 158 | vbox.Add (sink1.win, 1, wx.EXPAND)
|
| 159 | |
| 160 | # generate a real sinusoid
|
| 161 | self.src2 = gr.sig_source_f (input_rate, gr.GR_SIN_WAVE, 5.75e3, 1000) |
| 162 | self.thr2 = gr.throttle(gr.sizeof_float, input_rate)
|
| 163 | sink2 = waterfall_sink_f (panel, title="Real Data", fft_size=fft_size,
|
| 164 | sample_rate=input_rate, baseband_freq=100e3)
|
| 165 | self.connect(self.src2, self.thr2, sink2) |
| 166 | vbox.Add (sink2.win, 1, wx.EXPAND)
|
| 167 | |
| 168 | |
| 169 | def main (): |
| 170 | app = stdgui2.stdapp (test_top_block, "Waterfall Sink Test App")
|
| 171 | app.MainLoop () |
| 172 | |
| 173 | if __name__ == '__main__': |
| 174 | main () |
| 175 |