Implemented multiband channelizer as gr-gsm block.
diff --git a/python/receiver/gsm_wideband_input.py b/python/receiver/gsm_wideband_input.py
new file mode 100644
index 0000000..d1f704b
--- /dev/null
+++ b/python/receiver/gsm_wideband_input.py
@@ -0,0 +1,115 @@
+#!/usr/bin/env python
+##################################################
+# Gnuradio Python Flow Graph
+# Title: GSM wideband input adaptor
+# Author: Piotr Krysik
+# Co-author: Pieter Robyns
+# Description: Adaptor of input stream for the GSM receiver. Contains frequency ofset corrector doing also resampling to integer multiplies of GSM sample rate and LP filter filtering GSM channel.
+##################################################
+
+from gnuradio import filter
+from gnuradio import gr
+from gnuradio import eng_notation
+from gnuradio.filter import firdes
+import grgsm.arfcn as arfcn
+import grgsm
+
+class gsm_wideband_input(gr.hier_block2):
+    def __init__(self, ppm=0, osr=4, fc=925.2e6, samp_rate_in=20e6, ca=[]):
+        self.num_streams = len(ca)
+        gr.hier_block2.__init__(
+            self, "GSM wideband input adaptor",
+            gr.io_signature(1, 1, gr.sizeof_gr_complex*1),
+            gr.io_signature(self.num_streams, self.num_streams, gr.sizeof_gr_complex*1),
+        )
+
+        ##################################################
+        # Parameters
+        ##################################################
+        self.ppm = ppm
+        self.osr = osr
+        self.fc = fc
+        self.samp_rate_in = samp_rate_in
+        self.ca = ca
+        self.blocks_fir_filters = {}
+        self.blocks_resamplers = {}
+        self.blocks_ocs = {}
+        self.band = 'E-GSM'  # TODO make selectable
+        band = 'E-GSM'
+
+        ##################################################
+        # Variables
+        ##################################################
+        self.samp_rate_out = samp_rate_out = 1625000.0/6.0*osr
+        #self.samp_rate_out = samp_rate_out = 1000000
+
+        ##################################################
+        # Blocks
+        ##################################################
+        self.ppm_in = None
+        self.message_port_register_hier_out("ppm_in")
+        #self.lpf = firdes.low_pass(1, samp_rate_out, 125e3, 5e3, firdes.WIN_HAMMING, 6.76)
+        self.lpf = firdes.low_pass(1, samp_rate_in, 125e3, 75e3, firdes.WIN_HAMMING, 6.76)
+        self.gsm_clock_offset_corrector_0 = grgsm.clock_offset_corrector(
+            fc=fc,
+            ppm=ppm,
+            samp_rate_in=samp_rate_in,
+        )
+
+        c0_arfcn = arfcn.downlink2arfcn(fc, band)
+        print("Extracting channels %s, given that the center frequency is at ARFCN %d (%s)" % (str(ca), c0_arfcn, eng_notation.num_to_str(fc)))
+
+        self.connect((self, 0), (self.gsm_clock_offset_corrector_0, 0))
+
+
+        output_port = 0
+        for channel in ca:
+            channel_freq = arfcn.arfcn2downlink(channel, band)
+            if channel_freq is None:
+                print("Warning: invalid ARFCN %d for band %s" % (channel, band))
+                continue
+            freq_diff = channel_freq - fc
+            print("ARFCN %d is at C0 %+d KHz" % (channel, int(freq_diff / 1000.0)))
+
+            #self.blocks_ocs[channel] = grgsm.clock_offset_corrector(fc=fc, ppm=ppm, samp_rate_in=samp_rate_in)
+            self.blocks_resamplers[channel] = filter.fractional_resampler_cc(0, samp_rate_in/samp_rate_out)
+            self.blocks_fir_filters[channel] = filter.freq_xlating_fir_filter_ccc(1, (self.lpf), freq_diff, samp_rate_in)
+            self.connect((self.gsm_clock_offset_corrector_0, 0), (self.blocks_fir_filters[channel], 0))
+            self.connect((self.blocks_fir_filters[channel], 0), (self.blocks_resamplers[channel], 0))
+            self.connect((self.blocks_resamplers[channel], 0), (self, output_port))
+            output_port += 1
+
+
+        """"
+        output_port = 0
+        for channel in ca:
+            channel_freq = arfcn.arfcn2downlink(channel, band)
+            if channel_freq is None:
+                print("Warning: invalid ARFCN %d for band %s" % (channel, band))
+                continue
+            freq_diff = channel_freq - fc
+            print("ARFCN %d is at C0 %+d KHz" % (channel, int(freq_diff / 1000.0)))
+            self.blocks_fir_filters[channel] = filter.freq_xlating_fir_filter_ccc(20, (firdes.low_pass(1, samp_rate_in, 300000, 100000)), freq_diff, samp_rate_in)
+            self.connect((self, 0), (self.blocks_fir_filters[channel], 0))
+            self.connect((self.blocks_fir_filters[channel], 0), (self, output_port))
+            output_port += 1
+        """
+
+        ##################################################
+        # Asynch Message Connections
+        ##################################################
+        self.msg_connect(self, "ppm_in", self.gsm_clock_offset_corrector_0, "ppm_in")
+
+    def get_ppm(self):
+        return self.ppm
+
+    def set_ppm(self, ppm):
+        self.ppm = ppm
+        self.gsm_clock_offset_corrector_0.set_ppm(self.ppm)
+
+    def get_fc(self):
+        return self.fc
+
+    def set_fc(self, fc):
+        self.fc = fc
+        self.gsm_clock_offset_corrector_0.set_fc(self.fc)