]> git.gag.com Git - debian/gnuradio/blob - grc/src/grc_gnuradio/blks2/selector.py
probe hier wrappers
[debian/gnuradio] / grc / src / grc_gnuradio / blks2 / selector.py
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 from gnuradio import gr
23
24 class selector(gr.hier_block2):
25         """A hier2 block with N inputs and M outputs, where data is only forwarded through input n to output m."""
26         def __init__(self, item_size, num_inputs, num_outputs, input_index, output_index):
27                 """
28                 SelectorHelper constructor.
29                 @param item_size the size of the gr data stream in bytes
30                 @param num_inputs the number of inputs (integer)
31                 @param num_outputs the number of outputs (integer)
32                 @param input_index the index for the source data
33                 @param output_index the index for the destination data
34                 """
35                 gr.hier_block2.__init__(
36                         self, 'selector',
37                         gr.io_signature(num_inputs, num_inputs, item_size),
38                         gr.io_signature(num_outputs, num_outputs, item_size),
39                 )
40                 #terminator blocks for unused inputs and outputs
41                 self.input_terminators = [gr.null_sink(item_size)] * num_inputs
42                 self.output_terminators = [gr.head(item_size, 0)] * num_outputs
43                 self.copy = None
44                 #connections
45                 for i in range(num_inputs): self.connect((self, i), self.input_terminators[i])
46                 for i in range(num_outputs): self.connect(gr.null_source(item_size), self.output_terminators[i], (self, i))
47                 self.item_size = item_size
48                 self.input_index = input_index
49                 self.output_index = output_index
50                 self.num_inputs = num_inputs
51                 self.num_outputs = num_outputs
52                 self._connect_current()
53
54         def _indexes_valid(self):
55                 """
56                 Are the input and output indexes within range of the number of inputs and outputs?
57                 @return true if input index and output index are in range
58                 """
59                 return self.input_index in range(self.num_inputs) and self.output_index in range(self.num_outputs)
60
61         def _connect_current(self):
62                 """If the input and output indexes are valid:
63                 disconnect the blocks at the input and output index from their terminators,
64                 and connect them to one another. Then connect the terminators to one another."""
65                 if self._indexes_valid():
66                         self.disconnect((self, self.input_index), self.input_terminators[self.input_index])
67                         self.disconnect(self.output_terminators[self.output_index], (self, self.output_index))
68                         self.copy = gr.skiphead(self.item_size, 0)
69                         self.connect((self, self.input_index), self.copy)
70                         self.connect(self.copy, (self, self.output_index))
71                         self.connect(self.output_terminators[self.output_index], self.input_terminators[self.input_index])
72
73         def _disconnect_current(self):
74                 """If the input and output indexes are valid:
75                 disconnect the blocks at the input and output index from one another,
76                 and the terminators at the input and output index from one another.
77                 Reconnect the blocks to the terminators."""
78                 if self._indexes_valid():
79                         self.disconnect((self, self.input_index), self.copy)
80                         self.disconnect(self.copy, (self, self.output_index))
81                         self.disconnect(self.output_terminators[self.output_index], self.input_terminators[self.input_index])
82                         del self.copy
83                         self.copy = None
84                         self.connect((self, self.input_index), self.input_terminators[self.input_index])
85                         self.connect(self.output_terminators[self.output_index], (self, self.output_index))
86
87         def set_input_index(self, input_index):
88                 """
89                 Change the block to the new input index if the index changed.
90                 @param input_index the new input index
91                 """
92                 if self.input_index != input_index:
93                         self.lock()
94                         self._disconnect_current()
95                         self.input_index = input_index
96                         self._connect_current()
97                         self.unlock()
98
99         def set_output_index(self, output_index):
100                 """
101                 Change the block to the new output index if the index changed.
102                 @param output_index the new output index
103                 """
104                 if self.output_index != output_index:
105                         self.lock()
106                         self._disconnect_current()
107                         self.output_index = output_index
108                         self._connect_current()
109                         self.unlock()
110
111 class valve(selector):
112         """Wrapper for selector with 1 input and 1 output."""
113
114         def __init__(self, item_size, open):
115                 """
116                 Constructor for valve.
117                 @param item_size the size of the gr data stream in bytes
118                 @param open true if initial valve state is open
119                 """
120                 if open: output_index = -1
121                 else: output_index = 0
122                 selector.__init__(self, item_size, 1, 1, 0, output_index)
123
124         def set_open(self, open):
125                 """
126                 Callback to set open state.
127                 @param open true to set valve state to open
128                 """
129                 if open: output_index = -1
130                 else: output_index = 0
131                 self.set_output_index(output_index)