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