Exemplo n.º 1
0
def run_test(tb, channel, fft_rotate, fft_filter):
    N = 1000  # number of samples to use
    M = 5  # Number of channels
    fs = 5000.0  # baseband sampling rate
    ifs = M * fs  # input samp rate to decimator

    taps = filter.firdes.low_pass_2(1,
                                    ifs,
                                    fs / 2,
                                    fs / 10,
                                    attenuation_dB=80,
                                    window=filter.firdes.WIN_BLACKMAN_hARRIS)

    signals = list()
    add = blocks.add_cc()
    freqs = [-230., 121., 110., -513., 203.]
    Mch = ((len(freqs) - 1) // 2 + channel) % len(freqs)
    for i in range(len(freqs)):
        f = freqs[i] + (M // 2 - M + i + 1) * fs
        data = sig_source_c(ifs, f, 1, N)
        signals.append(blocks.vector_source_c(data))
        tb.connect(signals[i], (add, i))

    s2ss = blocks.stream_to_streams(gr.sizeof_gr_complex, M)
    pfb = filter.pfb_decimator_ccf(M, taps, channel, fft_rotate, fft_filter)
    snk = blocks.vector_sink_c()

    tb.connect(add, s2ss)
    for i in range(M):
        tb.connect((s2ss, i), (pfb, i))
    tb.connect(pfb, snk)
    tb.run()

    L = len(snk.data())

    # Adjusted phase rotations for data
    phase = [
        0.11058476216852586, 4.5108246571401693, 3.9739891674564594,
        2.2820531095511924, 1.3782797467397869
    ]
    phase = phase[channel]

    # Filter delay is the normal delay of each arm
    tpf = math.ceil(len(taps) / float(M))
    delay = -(tpf - 1.0) / 2.0
    delay = int(delay)

    # Create a time scale that's delayed to match the filter delay
    t = [float(x) / fs for x in range(delay, L + delay)]

    # Create known data as complex sinusoids for the baseband freq
    # of the extracted channel is due to decimator output order.
    expected_data = [
        math.cos(2. * math.pi * freqs[Mch] * x + phase) +
        1j * math.sin(2. * math.pi * freqs[Mch] * x + phase) for x in t
    ]
    dst_data = snk.data()

    return (dst_data, expected_data)
Exemplo n.º 2
0
def run_test(tb, channel, fft_rotate, fft_filter):
        N = 1000         # number of samples to use
        M = 5            # Number of channels
        fs = 5000.0      # baseband sampling rate
        ifs = M*fs       # input samp rate to decimator

        taps = filter.firdes.low_pass_2(1, ifs, fs/2, fs/10,
                                        attenuation_dB=80,
                                        window=filter.firdes.WIN_BLACKMAN_hARRIS)

        signals = list()
        add = blocks.add_cc()
        freqs = [-230., 121., 110., -513., 203.]
        Mch = ((len(freqs)-1)/2 + channel) % len(freqs)
        for i in xrange(len(freqs)):
            f = freqs[i] + (M/2-M+i+1)*fs
            data = sig_source_c(ifs, f, 1, N)
            signals.append(blocks.vector_source_c(data))
            tb.connect(signals[i], (add,i))

        s2ss = blocks.stream_to_streams(gr.sizeof_gr_complex, M)
        pfb = filter.pfb_decimator_ccf(M, taps, channel, fft_rotate, fft_filter)
        snk = blocks.vector_sink_c()

        tb.connect(add, s2ss)
        for i in xrange(M):
            tb.connect((s2ss,i), (pfb,i))
        tb.connect(pfb, snk)
        tb.run()

        L = len(snk.data())

        # Adjusted phase rotations for data
        phase = [ 0.11058476216852586,
                  4.5108246571401693,
                  3.9739891674564594,
                  2.2820531095511924,
                  1.3782797467397869]
        phase = phase[channel]

        # Filter delay is the normal delay of each arm
        tpf = math.ceil(len(taps) / float(M))
        delay = -(tpf - 1.0) / 2.0
        delay = int(delay)

        # Create a time scale that's delayed to match the filter delay
        t = map(lambda x: float(x)/fs, xrange(delay, L+delay))

        # Create known data as complex sinusoids for the baseband freq
        # of the extracted channel is due to decimator output order.
        expected_data = map(lambda x: math.cos(2.*math.pi*freqs[Mch]*x+phase) + \
                                1j*math.sin(2.*math.pi*freqs[Mch]*x+phase), t)
        dst_data = snk.data()

        return (dst_data, expected_data)
Exemplo n.º 3
0
def run_test(tb, channel):
    N = 1000  # number of samples to use
    M = 5  # Number of channels
    fs = 5000.0  # baseband sampling rate
    ifs = M * fs  # input samp rate to decimator

    taps = filter.firdes.low_pass_2(1,
                                    ifs,
                                    fs / 2,
                                    fs / 10,
                                    attenuation_dB=80,
                                    window=filter.firdes.WIN_BLACKMAN_hARRIS)

    signals = list()
    add = blocks.add_cc()
    freqs = [-230., 121., 110., -513., 203.]
    Mch = ((len(freqs) - 1) / 2 + channel) % len(freqs)
    for i in xrange(len(freqs)):
        f = freqs[i] + (M / 2 - M + i + 1) * fs
        data = sig_source_c(ifs, f, 1, N)
        signals.append(blocks.vector_source_c(data))
        tb.connect(signals[i], (add, i))

    s2ss = blocks.stream_to_streams(gr.sizeof_gr_complex, M)
    pfb = filter.pfb_decimator_ccf(M, taps, channel)
    snk = blocks.vector_sink_c()

    tb.connect(add, s2ss)
    for i in xrange(M):
        tb.connect((s2ss, i), (pfb, i))
    tb.connect(pfb, snk)
    tb.run()

    L = len(snk.data())

    # Each channel is rotated by 2pi/M
    phase = -2 * math.pi * channel / M

    # Filter delay is the normal delay of each arm
    tpf = math.ceil(len(taps) / float(M))
    delay = -(tpf - 1.0) / 2.0
    delay = int(delay)

    # Create a time scale that's delayed to match the filter delay
    t = map(lambda x: float(x) / fs, xrange(delay, L + delay))

    # Create known data as complex sinusoids for the baseband freq
    # of the extracted channel is due to decimator output order.
    expected_data = map(lambda x: math.cos(2.*math.pi*freqs[Mch]*x+phase) + \
                            1j*math.sin(2.*math.pi*freqs[Mch]*x+phase), t)
    dst_data = snk.data()

    return (dst_data, expected_data)
Exemplo n.º 4
0
    def test_000(self):
        N = 1000         # number of samples to use
        M = 5            # Number of channels
        fs = 1000        # baseband sampling rate
        ifs = M*fs       # input samp rate to decimator
        channel = 0      # Extract channel 0

        taps = filter.firdes.low_pass_2(1, ifs, fs/2, fs/10,
                                        attenuation_dB=80,
                                        window=filter.firdes.WIN_BLACKMAN_hARRIS)

        signals = list()
        add = blocks.add_cc()
        freqs = [-200, -100, 0, 100, 200]
        for i in xrange(len(freqs)):
            f = freqs[i] + (M/2-M+i+1)*fs
            data = sig_source_c(ifs, f, 1, N)
            signals.append(blocks.vector_source_c(data))
            self.tb.connect(signals[i], (add,i))

        head = blocks.head(gr.sizeof_gr_complex, N)
        s2ss = blocks.stream_to_streams(gr.sizeof_gr_complex, M)
        pfb = filter.pfb_decimator_ccf(M, taps, channel)
        snk = blocks.vector_sink_c()

        self.tb.connect(add, head, s2ss)
        for i in xrange(M):
            self.tb.connect((s2ss,i), (pfb,i))
        self.tb.connect(pfb, snk)

        self.tb.run() 

        Ntest = 50
        L = len(snk.data())
        t = map(lambda x: float(x)/fs, xrange(L))

        # Create known data as complex sinusoids for the baseband freq
        # of the extracted channel is due to decimator output order.
        phase = 0
        expected_data = map(lambda x: math.cos(2.*math.pi*freqs[2]*x+phase) + \
                                1j*math.sin(2.*math.pi*freqs[2]*x+phase), t)

        dst_data = snk.data()

        self.assertComplexTuplesAlmostEqual(expected_data[-Ntest:], dst_data[-Ntest:], 4)
Exemplo n.º 5
0
    def __init__(self):
        grc_wxgui.top_block_gui.__init__(self, title="Top Block")

        options = get_options()

        self.ifreq = options.frequency
        self.rfgain = options.gain

        self.src = osmosdr.source(options.args)
        self.src.set_center_freq(self.ifreq)
        self.src.set_sample_rate(int(options.sample_rate))
        #sq5bpf: dodalem ppm
        self.src.set_freq_corr(8)

        if self.rfgain is None:
            self.src.set_gain_mode(1)
            self.iagc = 1
            self.rfgain = 0
        else:
            self.iagc = 0
            self.src.set_gain_mode(0)
            self.src.set_gain(self.rfgain)

        # may differ from the requested rate
        sample_rate = self.src.get_sample_rate()
        sys.stderr.write("sample rate: %d\n" % (sample_rate))

        symbol_rate = 18000
        sps = 2  # output rate will be 36,000
        out_sample_rate = symbol_rate * sps

        options.low_pass = options.low_pass / 2.0

        if sample_rate == 96000:  # FunCube Dongle
            first_decim = 2
        else:
            first_decim = 10

        self.offset = 0

        taps = filter.firdes.low_pass(1.0, sample_rate, options.low_pass,
                                      options.low_pass * 0.2,
                                      filter.firdes.WIN_HANN)
        self.tuner = filter.freq_xlating_fir_filter_ccf(
            first_decim, taps, self.offset, sample_rate)

        self.demod = cqpsk.cqpsk_demod(samples_per_symbol=sps,
                                       excess_bw=0.35,
                                       costas_alpha=0.03,
                                       gain_mu=0.05,
                                       mu=0.05,
                                       omega_relative_limit=0.05,
                                       log=options.log,
                                       verbose=options.verbose)

        self.output = blocks.file_sink(gr.sizeof_float, options.output_file)

        rerate = float(
            sample_rate / float(first_decim)) / float(out_sample_rate)
        sys.stderr.write("resampling factor: %f\n" % rerate)

        if rerate.is_integer():
            sys.stderr.write("using pfb decimator\n")
            self.resamp = filter.pfb_decimator_ccf(int(rerate))
        else:
            sys.stderr.write("using pfb resampler\n")
            self.resamp = filter.pfb_arb_resampler_ccf(1 / rerate)

        self.connect(self.src, self.tuner, self.resamp, self.demod,
                     self.output)

        self.Main = wx.Notebook(self.GetWin(), style=wx.NB_TOP)
        self.Main.AddPage(grc_wxgui.Panel(self.Main), "Wideband Spectrum")
        self.Main.AddPage(grc_wxgui.Panel(self.Main), "Channel Spectrum")
        self.Main.AddPage(grc_wxgui.Panel(self.Main), "Soft Bits")

        def set_ifreq(ifreq):
            self.ifreq = ifreq
            self._ifreq_text_box.set_value(self.ifreq)
            self.src.set_center_freq(self.ifreq)

        self._ifreq_text_box = forms.text_box(
            parent=self.GetWin(),
            value=self.ifreq,
            callback=set_ifreq,
            label="Center Frequency",
            converter=forms.float_converter(),
        )
        self.Add(self._ifreq_text_box)

        def set_iagc(iagc):
            self.iagc = iagc
            self._agc_check_box.set_value(self.iagc)
            self.src.set_gain_mode(self.iagc, 0)
            self.src.set_gain(0 if self.iagc == 1 else self.rfgain, 0)

        self._agc_check_box = forms.check_box(
            parent=self.GetWin(),
            value=self.iagc,
            callback=set_iagc,
            label="Automatic Gain",
            true=1,
            false=0,
        )

        self.Add(self._agc_check_box)

        def set_rfgain(rfgain):
            self.rfgain = rfgain
            self._rfgain_slider.set_value(self.rfgain)
            self._rfgain_text_box.set_value(self.rfgain)
            self.src.set_gain(0 if self.iagc == 1 else self.rfgain, 0)

        _rfgain_sizer = wx.BoxSizer(wx.VERTICAL)
        self._rfgain_text_box = forms.text_box(
            parent=self.GetWin(),
            sizer=_rfgain_sizer,
            value=self.rfgain,
            callback=set_rfgain,
            label="RF Gain",
            converter=forms.float_converter(),
            proportion=0,
        )
        self._rfgain_slider = forms.slider(
            parent=self.GetWin(),
            sizer=_rfgain_sizer,
            value=self.rfgain,
            callback=set_rfgain,
            minimum=0,
            maximum=50,
            num_steps=200,
            style=wx.SL_HORIZONTAL,
            cast=float,
            proportion=1,
        )

        self.Add(_rfgain_sizer)

        self.Add(self.Main)

        def fftsink2_callback(x, y):
            x = x - self.ifreq
            sys.stderr.write("sq5bpf: x: %d \n" % x)
            if abs(x / (sample_rate / 2)) > 0.9:
                set_ifreq(self.ifreq + x / 2)
            else:
                sys.stderr.write("coarse tuned to: %d Hz\n" % x)
                self.offset = -x
                self.tuner.set_center_freq(self.offset)
                self._rxfreq_text_box.set_value(self.ifreq -
                                                self.offset)  #sq5bpf

        self.scope = fftsink2.fft_sink_c(
            self.Main.GetPage(0).GetWin(),
            title="Wideband Spectrum (click to coarse tune)",
            baseband_freq=self.ifreq,  #sq5bpf
            fft_size=1024,
            sample_rate=sample_rate,
            ref_scale=2.0,
            ref_level=0,
            y_divs=10,
            fft_rate=10,
            average=False,
            avg_alpha=0.6)

        self.Main.GetPage(0).Add(self.scope.win)
        self.scope.set_callback(fftsink2_callback)

        self.connect(self.src, self.scope)

        def fftsink2_callback2(x, y):
            self.offset = self.offset - (x / 10)
            sys.stderr.write("fine tuned to: %d Hz\n" % self.offset)
            self.tuner.set_center_freq(self.offset)
            self._rxfreq_text_box.set_value(self.ifreq - self.offset)  #sq5bpf

        self.scope2 = fftsink2.fft_sink_c(
            self.Main.GetPage(1).GetWin(),
            title="Channel Spectrum (click to fine tune)",
            fft_size=1024,
            sample_rate=out_sample_rate,
            ref_scale=2.0,
            ref_level=-20,
            y_divs=10,
            fft_rate=10,
            average=False,
            avg_alpha=0.6)

        self.Main.GetPage(1).Add(self.scope2.win)
        self.scope2.set_callback(fftsink2_callback2)

        self.connect(self.resamp, self.scope2)

        self.scope3 = scopesink2.scope_sink_f(
            self.Main.GetPage(2).GetWin(),
            title="Soft Bits",
            sample_rate=out_sample_rate,
            v_scale=0,
            v_offset=0,
            t_scale=0.001,
            ac_couple=False,
            xy_mode=False,
            num_inputs=1,
            trig_mode=wxgui.TRIG_MODE_AUTO,
            y_axis_label="Counts",
        )
        self.Main.GetPage(2).Add(self.scope3.win)

        self.connect(self.demod, self.scope3)
        #sq5bpf
        self._rxfreq_text_box = forms.text_box(
            parent=self.GetWin(),
            value=self.ifreq - self.offset,
            label="RX Freq",
            converter=forms.float_converter(),
        )
        self.Add(self._rxfreq_text_box)
Exemplo n.º 6
0
        self.connect((self,1), (ftc,1))
        self.connect(ftc,mag,(self,0))
        self.connect(ftc,arg,(self,1))


tb = gr.top_block()

source= adc_signal(samp_rate)

#Ddc mixer
mixer = ddc_mixer(samp_rate, 20e6)

#Decimation filter. Both must have the same taps, so, calculate it once
taps = filter.firdes.low_pass_2(1, samp_rate, 5e3, 3e3, 60,
                                filter.firdes.WIN_BLACKMAN_HARRIS)
filter_I = filter.pfb_decimator_ccf(int(1e3), taps, 0)
filter_Q = filter.pfb_decimator_ccf(int(1e3), taps, 0)

#now, calculate Magnitude and Argument
cordic = float_cordic()

#output the result
sink = blocks.vector_sink_f()

tb.connect(source, head)
tb.connect(head, mixer)

tb.connect((mixer,0), filter_I)
tb.connect((mixer,1), filter_Q)

tb.connect(filter_I, (cordic,0))