Merge branch 'upstream' into dfsg-orig
[debian/gnuradio] / gnuradio-examples / python / pfb / interpolate.py
1 #!/usr/bin/env python
2 #
3 # Copyright 2009 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, blks2
24 import os
25 import scipy, pylab
26 from scipy import fftpack
27 from pylab import mlab
28 import time
29
30 #print os.getpid()
31 #raw_input()
32
33 class pfb_top_block(gr.top_block):
34     def __init__(self):
35         gr.top_block.__init__(self)
36
37         self._N = 100000        # number of samples to use
38         self._fs = 2000         # initial sampling rate
39         self._interp = 5        # Interpolation rate for PFB interpolator
40         self._ainterp = 5.5       # Resampling rate for the PFB arbitrary resampler
41
42         # Frequencies of the signals we construct 
43         freq1 = 100
44         freq2 = 200
45
46         # Create a set of taps for the PFB interpolator
47         # This is based on the post-interpolation sample rate
48         self._taps = gr.firdes.low_pass_2(self._interp, self._interp*self._fs, freq2+50, 50, 
49                                           attenuation_dB=120, window=gr.firdes.WIN_BLACKMAN_hARRIS)
50
51         # Create a set of taps for the PFB arbitrary resampler
52         # The filter size is the number of filters in the filterbank; 32 will give very low side-lobes,
53         # and larger numbers will reduce these even farther
54         # The taps in this filter are based on a sampling rate of the filter size since it acts
55         # internally as an interpolator.
56         flt_size = 32
57         self._taps2 = gr.firdes.low_pass_2(flt_size, flt_size*self._fs, freq2+50, 150, 
58                                            attenuation_dB=120, window=gr.firdes.WIN_BLACKMAN_hARRIS)
59
60         # Calculate the number of taps per channel for our own information
61         tpc = scipy.ceil(float(len(self._taps)) /  float(self._interp))
62         print "Number of taps:     ", len(self._taps)
63         print "Number of filters:  ", self._interp
64         print "Taps per channel:   ", tpc
65
66         # Create a couple of signals at different frequencies
67         self.signal1 = gr.sig_source_c(self._fs, gr.GR_SIN_WAVE, freq1, 0.5)
68         self.signal2 = gr.sig_source_c(self._fs, gr.GR_SIN_WAVE, freq2, 0.5)
69         self.signal = gr.add_cc()
70         
71         self.head = gr.head(gr.sizeof_gr_complex, self._N)
72
73         # Construct the PFB interpolator filter
74         self.pfb = blks2.pfb_interpolator_ccf(self._interp, self._taps)
75
76         # Construct the PFB arbitrary resampler filter
77         self.pfb_ar = blks2.pfb_arb_resampler_ccf(self._ainterp, self._taps2, flt_size)
78         self.snk_i = gr.vector_sink_c()
79
80         #self.pfb_ar.pfb.print_taps()
81         #self.pfb.pfb.print_taps()
82         
83         # Connect the blocks
84         self.connect(self.signal1, self.head, (self.signal,0))
85         self.connect(self.signal2, (self.signal,1))
86         self.connect(self.signal, self.pfb)
87         self.connect(self.signal, self.pfb_ar)
88         self.connect(self.signal, self.snk_i)
89
90         # Create the sink for the interpolated signals
91         self.snk1 = gr.vector_sink_c()
92         self.snk2 = gr.vector_sink_c()
93         self.connect(self.pfb, self.snk1)
94         self.connect(self.pfb_ar, self.snk2)
95                              
96
97 def main():
98     tb = pfb_top_block()
99
100     tstart = time.time()
101     tb.run()
102     tend = time.time()
103     print "Run time: %f" % (tend - tstart)
104
105
106     if 1:
107         fig1 = pylab.figure(1, figsize=(12,10), facecolor="w")
108         fig2 = pylab.figure(2, figsize=(12,10), facecolor="w")
109         fig3 = pylab.figure(3, figsize=(12,10), facecolor="w")
110         
111         Ns = 10000
112         Ne = 10000
113
114         fftlen = 8192
115         winfunc = scipy.blackman
116
117         # Plot input signal
118         fs = tb._fs
119
120         d = tb.snk_i.data()[Ns:Ns+Ne]
121         sp1_f = fig1.add_subplot(2, 1, 1)
122
123         X,freq = mlab.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs,
124                           window = lambda d: d*winfunc(fftlen),
125                           scale_by_freq=True)
126         X_in = 10.0*scipy.log10(abs(fftpack.fftshift(X)))
127         f_in = scipy.arange(-fs/2.0, fs/2.0, fs/float(X_in.size))
128         p1_f = sp1_f.plot(f_in, X_in, "b")
129         sp1_f.set_xlim([min(f_in), max(f_in)+1]) 
130         sp1_f.set_ylim([-200.0, 50.0]) 
131
132
133         sp1_f.set_title("Input Signal", weight="bold")
134         sp1_f.set_xlabel("Frequency (Hz)")
135         sp1_f.set_ylabel("Power (dBW)")
136
137         Ts = 1.0/fs
138         Tmax = len(d)*Ts
139         
140         t_in = scipy.arange(0, Tmax, Ts)
141         x_in = scipy.array(d)
142         sp1_t = fig1.add_subplot(2, 1, 2)
143         p1_t = sp1_t.plot(t_in, x_in.real, "b-o")
144         #p1_t = sp1_t.plot(t_in, x_in.imag, "r-o")
145         sp1_t.set_ylim([-2.5, 2.5])
146
147         sp1_t.set_title("Input Signal", weight="bold")
148         sp1_t.set_xlabel("Time (s)")
149         sp1_t.set_ylabel("Amplitude")
150
151
152         # Plot output of PFB interpolator
153         fs_int = tb._fs*tb._interp
154
155         sp2_f = fig2.add_subplot(2, 1, 1)
156         d = tb.snk1.data()[Ns:Ns+(tb._interp*Ne)]
157         X,freq = mlab.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs,
158                           window = lambda d: d*winfunc(fftlen),
159                           scale_by_freq=True)
160         X_o = 10.0*scipy.log10(abs(fftpack.fftshift(X)))
161         f_o = scipy.arange(-fs_int/2.0, fs_int/2.0, fs_int/float(X_o.size))
162         p2_f = sp2_f.plot(f_o, X_o, "b")
163         sp2_f.set_xlim([min(f_o), max(f_o)+1]) 
164         sp2_f.set_ylim([-200.0, 50.0]) 
165
166         sp2_f.set_title("Output Signal from PFB Interpolator", weight="bold")
167         sp2_f.set_xlabel("Frequency (Hz)")
168         sp2_f.set_ylabel("Power (dBW)")
169
170         Ts_int = 1.0/fs_int
171         Tmax = len(d)*Ts_int
172
173         t_o = scipy.arange(0, Tmax, Ts_int)
174         x_o1 = scipy.array(d)
175         sp2_t = fig2.add_subplot(2, 1, 2)
176         p2_t = sp2_t.plot(t_o, x_o1.real, "b-o")
177         #p2_t = sp2_t.plot(t_o, x_o.imag, "r-o")
178         sp2_t.set_ylim([-2.5, 2.5])
179
180         sp2_t.set_title("Output Signal from PFB Interpolator", weight="bold")
181         sp2_t.set_xlabel("Time (s)")
182         sp2_t.set_ylabel("Amplitude")
183
184
185         # Plot output of PFB arbitrary resampler
186         fs_aint = tb._fs * tb._ainterp
187
188         sp3_f = fig3.add_subplot(2, 1, 1)
189         d = tb.snk2.data()[Ns:Ns+(tb._interp*Ne)]
190         X,freq = mlab.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs,
191                           window = lambda d: d*winfunc(fftlen),
192                           scale_by_freq=True)
193         X_o = 10.0*scipy.log10(abs(fftpack.fftshift(X)))
194         f_o = scipy.arange(-fs_aint/2.0, fs_aint/2.0, fs_aint/float(X_o.size))
195         p3_f = sp3_f.plot(f_o, X_o, "b")
196         sp3_f.set_xlim([min(f_o), max(f_o)+1]) 
197         sp3_f.set_ylim([-200.0, 50.0]) 
198
199         sp3_f.set_title("Output Signal from PFB Arbitrary Resampler", weight="bold")
200         sp3_f.set_xlabel("Frequency (Hz)")
201         sp3_f.set_ylabel("Power (dBW)")
202
203         Ts_aint = 1.0/fs_aint
204         Tmax = len(d)*Ts_aint
205
206         t_o = scipy.arange(0, Tmax, Ts_aint)
207         x_o2 = scipy.array(d)
208         sp3_f = fig3.add_subplot(2, 1, 2)
209         p3_f = sp3_f.plot(t_o, x_o2.real, "b-o")
210         p3_f = sp3_f.plot(t_o, x_o1.real, "m-o")
211         #p3_f = sp3_f.plot(t_o, x_o2.imag, "r-o")
212         sp3_f.set_ylim([-2.5, 2.5])
213         
214         sp3_f.set_title("Output Signal from PFB Arbitrary Resampler", weight="bold")
215         sp3_f.set_xlabel("Time (s)")
216         sp3_f.set_ylabel("Amplitude")
217
218         pylab.show()
219
220
221 if __name__ == "__main__":
222     try:
223         main()
224     except KeyboardInterrupt:
225         pass
226