Imported Upstream version 3.2.2
[debian/gnuradio] / gnuradio-core / src / python / gnuradio / blks2impl / rational_resampler.py
1 #
2 # Copyright 2005,2007 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, gru
23
24 _plot = None
25
26 def design_filter(interpolation, decimation, fractional_bw):
27     """
28     Given the interpolation rate, decimation rate and a fractional bandwidth,
29     design a set of taps.
30
31     @param interpolation: interpolation factor
32     @type  interpolation: integer > 0
33     @param decimation: decimation factor
34     @type  decimation: integer > 0
35     @param fractional_bw: fractional bandwidth in (0, 0.5)  0.4 works well.
36     @type  fractional_bw: float
37     @returns: sequence of numbers
38     """
39
40     if fractional_bw >= 0.5 or fractional_bw <= 0:
41         raise ValueError, "Invalid fractional_bandwidth, must be in (0, 0.5)"
42
43     beta = 5.0
44     trans_width = 0.5 - fractional_bw
45     mid_transition_band = 0.5 - trans_width/2
46
47     taps = gr.firdes.low_pass(interpolation,                     # gain
48                               1,                                 # Fs
49                               mid_transition_band/interpolation, # trans mid point
50                               trans_width/interpolation,         # transition width
51                               gr.firdes.WIN_KAISER,
52                               beta                               # beta
53                               )
54
55     return taps
56
57
58
59 class _rational_resampler_base(gr.hier_block2):
60     """
61     base class for all rational resampler variants.
62     """
63     def __init__(self, resampler_base,
64                  interpolation, decimation, taps=None, fractional_bw=None):
65         """
66         Rational resampling polyphase FIR filter.
67
68         Either taps or fractional_bw may be specified, but not both.
69         If neither is specified, a reasonable default, 0.4, is used as
70         the fractional_bw.
71
72         @param interpolation: interpolation factor
73         @type  interpolation: integer > 0
74         @param decimation: decimation factor
75         @type  decimation: integer > 0
76         @param taps: optional filter coefficients
77         @type  taps: sequence
78         @param fractional_bw: fractional bandwidth in (0, 0.5), measured at final freq (use 0.4)
79         @type  fractional_bw: float
80         """
81
82         if not isinstance(interpolation, int) or interpolation < 1:
83             raise ValueError, "interpolation must be an integer >= 1"
84
85         if not isinstance(decimation, int) or decimation < 1:
86             raise ValueError, "decimation must be an integer >= 1"
87
88         if taps is None and fractional_bw is None:
89             fractional_bw = 0.4
90
91         d = gru.gcd(interpolation, decimation)
92         interpolation = interpolation // d
93         decimation = decimation // d
94         
95         if taps is None:
96             taps = design_filter(interpolation, decimation, fractional_bw)
97
98         resampler = resampler_base(interpolation, decimation, taps)
99         gr.hier_block2.__init__(self, "rational_resampler",
100                                 gr.io_signature(1, 1, resampler.input_signature().sizeof_stream_item(0)),
101                                 gr.io_signature(1, 1, resampler.output_signature().sizeof_stream_item(0)))
102
103         self.connect(self, resampler, self)
104
105
106 class rational_resampler_fff(_rational_resampler_base):
107     def __init__(self, interpolation, decimation, taps=None, fractional_bw=None):
108         """
109         Rational resampling polyphase FIR filter with
110         float input, float output and float taps.
111         """
112         _rational_resampler_base.__init__(self, gr.rational_resampler_base_fff,
113                                           interpolation, decimation, taps, fractional_bw)
114
115 class rational_resampler_ccf(_rational_resampler_base):
116     def __init__(self, interpolation, decimation, taps=None, fractional_bw=None):
117         """
118         Rational resampling polyphase FIR filter with
119         complex input, complex output and float taps.
120         """
121         _rational_resampler_base.__init__(self, gr.rational_resampler_base_ccf, 
122                                           interpolation, decimation, taps, fractional_bw)
123
124 class rational_resampler_ccc(_rational_resampler_base):
125     def __init__(self, interpolation, decimation, taps=None, fractional_bw=None):
126         """
127         Rational resampling polyphase FIR filter with
128         complex input, complex output and complex taps.
129         """
130         _rational_resampler_base.__init__(self, gr.rational_resampler_base_ccc, 
131                                           interpolation, decimation, taps, fractional_bw)