Statistics
| Branch: | Tag: | Revision:

root / grc / src / grc_gnuradio / blks2 / selector.py @ d52c462e

History | View | Annotate | Download (5 kB)

1
#!/usr/bin/env python
2
#
3
# Copyright 2008 Free Software Foundation, Inc.
4
# 
5
# This file is part of GNU Radio
6
# 
7
# GNU Radio is free software; you can redistribute it and/or modify
8
# it under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3, or (at your option)
10
# any later version.
11
# 
12
# GNU Radio is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
# GNU General Public License for more details.
16
# 
17
# You should have received a copy of the GNU General Public License
18
# along with GNU Radio; see the file COPYING.  If not, write to
19
# the Free Software Foundation, Inc., 51 Franklin Street,
20
# Boston, MA 02110-1301, USA.
21
# 
22
23
from gnuradio import gr
24
                
25
class selector(gr.hier_block2):
26
        """A hier2 block with N inputs and M outputs, where data is only forwarded through input n to output m."""
27
        def __init__(self, item_size, num_inputs, num_outputs, input_index, output_index):        
28
                """!
29
                SelectorHelper constructor.
30
                @param item_size the size of the gr data stream in bytes
31
                @param num_inputs the number of inputs (integer)
32
                @param num_outputs the number of outputs (integer)
33
                @param input_index the index for the source data
34
                @param output_index the index for the destination data
35
                """        
36
                gr.hier_block2.__init__(
37
                        self, 'selector', 
38
                        gr.io_signature(num_inputs, num_inputs, item_size), 
39
                        gr.io_signature(num_outputs, num_outputs, item_size),
40
                )
41
                #terminator blocks for unused inputs and outputs        
42
                self.input_terminators = [gr.null_sink(item_size)] * num_inputs
43
                self.output_terminators = [gr.head(item_size, 0)] * num_outputs
44
                self.copy = None
45
                #connections                
46
                for i in range(num_inputs): self.connect((self, i), self.input_terminators[i])
47
                for i in range(num_outputs): self.connect(gr.null_source(item_size), self.output_terminators[i], (self, i))        
48
                self.item_size = item_size                
49
                self.input_index = input_index
50
                self.output_index = output_index        
51
                self.num_inputs = num_inputs
52
                self.num_outputs = num_outputs
53
                self._connect_current()
54
                
55
        def _indexes_valid(self):
56
                """!
57
                Are the input and output indexes within range of the number of inputs and outputs?
58
                @return true if input index and output index are in range
59
                """
60
                return self.input_index in range(self.num_inputs) and self.output_index in range(self.num_outputs)
61
                
62
        def _connect_current(self):
63
                """If the input and output indexes are valid: 
64
                disconnect the blocks at the input and output index from their terminators, 
65
                and connect them to one another. Then connect the terminators to one another."""
66
                if self._indexes_valid():
67
                        self.disconnect((self, self.input_index), self.input_terminators[self.input_index])                                
68
                        self.disconnect(self.output_terminators[self.output_index], (self, self.output_index))
69
                        self.copy = gr.skiphead(self.item_size, 0)
70
                        self.connect((self, self.input_index), self.copy)
71
                        self.connect(self.copy, (self, self.output_index))                
72
                        self.connect(self.output_terminators[self.output_index], self.input_terminators[self.input_index])        
73
                
74
        def _disconnect_current(self):
75
                """If the input and output indexes are valid: 
76
                disconnect the blocks at the input and output index from one another, 
77
                and the terminators at the input and output index from one another.
78
                Reconnect the blocks to the terminators."""
79
                if self._indexes_valid():
80
                        self.disconnect((self, self.input_index), self.copy)
81
                        self.disconnect(self.copy, (self, self.output_index))
82
                        self.disconnect(self.output_terminators[self.output_index], self.input_terminators[self.input_index])
83
                        del self.copy                        
84
                        self.copy = None                        
85
                        self.connect((self, self.input_index), self.input_terminators[self.input_index])
86
                        self.connect(self.output_terminators[self.output_index], (self, self.output_index))
87
                
88
        def set_input_index(self, input_index):
89
                """!
90
                Change the block to the new input index if the index changed.
91
                @param input_index the new input index
92
                """
93
                if self.input_index != input_index:
94
                        self.lock()
95
                        self._disconnect_current()
96
                        self.input_index = input_index
97
                        self._connect_current()
98
                        self.unlock()                
99
                
100
        def set_output_index(self, output_index):
101
                """!
102
                Change the block to the new output index if the index changed.
103
                @param output_index the new output index
104
                """                
105
                if self.output_index != output_index:        
106
                        self.lock()
107
                        self._disconnect_current()
108
                        self.output_index = output_index
109
                        self._connect_current()                        
110
                        self.unlock()        
111
112
class valve(selector):
113
        """Wrapper for selector with 1 input and 1 output."""
114
        
115
        def __init__(self, item_size, open):
116
                """!
117
                Constructor for valve.
118
                @param item_size the size of the gr data stream in bytes
119
                @param open true if initial valve state is open
120
                """
121
                if open: output_index = -1
122
                else: output_index = 0
123
                selector.__init__(self, item_size, 1, 1, 0, output_index)
124
                
125
        def set_open(self, open):
126
                """!
127
                Callback to set open state.
128
                @param open true to set valve state to open
129
                """
130
                if open: output_index = -1
131
                else: output_index = 0
132
                self.set_output_index(output_index)
133