def test02(self):
        # Test float/float version
        omega = 2
        gain_omega = 0.01
        mu = 0.5
        gain_mu = 0.01
        omega_rel_lim = 0.001

        self.test = digital_swig.clock_recovery_mm_ff(omega, gain_omega, mu, gain_mu, omega_rel_lim)

        data = 100 * [1]
        self.src = gr.vector_source_f(data, False)
        self.snk = gr.vector_sink_f()

        self.tb.connect(self.src, self.test, self.snk)
        self.tb.run()

        expected_result = 100 * [0.99972]  # doesn't quite get to 1.0
        dst_data = self.snk.data()

        # Only compare last Ncmp samples
        Ncmp = 30
        len_e = len(expected_result)
        len_d = len(dst_data)
        expected_result = expected_result[len_e - Ncmp :]
        dst_data = dst_data[len_d - Ncmp :]

        # print expected_result
        # print dst_data

        self.assertFloatTuplesAlmostEqual(expected_result, dst_data, 5)
Example #2
0
    def test02(self):
        # Test float/float version
        omega = 2
        gain_omega = 0.01
        mu = 0.5
        gain_mu = 0.01
        omega_rel_lim = 0.001

        self.test = digital.clock_recovery_mm_ff(omega, gain_omega,
                                                 mu, gain_mu,
                                                 omega_rel_lim)
        
        data = 100*[1,]
        self.src = blocks.vector_source_f(data, False)
        self.snk = blocks.vector_sink_f()

        self.tb.connect(self.src, self.test, self.snk)
        self.tb.run()
        
        expected_result = 100*[0.99972, ] # doesn't quite get to 1.0
        dst_data = self.snk.data()

        # Only compare last Ncmp samples
        Ncmp = 30
        len_e = len(expected_result)
        len_d = len(dst_data)
        expected_result = expected_result[len_e - Ncmp:]
        dst_data = dst_data[len_d - Ncmp:]

        #print expected_result
        #print dst_data
        
        self.assertFloatTuplesAlmostEqual(expected_result, dst_data, 5)
    def test04(self):
        # Test float/float version
        omega = 2
        gain_omega = 0.01
        mu = 0.25
        gain_mu = 0.1
        omega_rel_lim = 0.001

        self.test = digital.clock_recovery_mm_ff(omega, gain_omega,
                                                 mu, gain_mu,
                                                 omega_rel_lim)
        
        data = 1000*[1, 1, -1, -1]
        self.src = blocks.vector_source_f(data, False)
        self.snk = blocks.vector_sink_f()

        self.tb.connect(self.src, self.test, self.snk)
        self.tb.run()
        
        expected_result = 1000*[-1.31, 1.31]
        dst_data = self.snk.data()

        # Only compare last Ncmp samples
        Ncmp = 100
        len_e = len(expected_result)
        len_d = len(dst_data)
        expected_result = expected_result[len_e - Ncmp:]
        dst_data = dst_data[len_d - Ncmp:]

        #print expected_result
        #print dst_data
        
        self.assertFloatTuplesAlmostEqual(expected_result, dst_data, 1)
Example #4
0
    def __init__(self,
                 samples_per_symbol=_def_samples_per_symbol,
                 gain_mu=_def_gain_mu,
                 mu=_def_mu,
                 omega_relative_limit=_def_omega_relative_limit,
                 freq_error=_def_freq_error,
                 verbose=_def_verbose,
                 log=_def_log):

        gr.hier_block2.__init__(
            self,
            "gmsk_demod",
            gr.io_signature(1, 1, gr.sizeof_gr_complex),  # Input signature
            gr.io_signature(1, 1, gr.sizeof_char))  # Output signature

        self._samples_per_symbol = samples_per_symbol
        self._gain_mu = gain_mu
        self._mu = mu
        self._omega_relative_limit = omega_relative_limit
        self._freq_error = freq_error
        self._differential = False

        if samples_per_symbol < 2:
            raise TypeError, "samples_per_symbol >= 2, is %f" % samples_per_symbol

        self._omega = samples_per_symbol * (1 + self._freq_error)

        if not self._gain_mu:
            self._gain_mu = 0.175

        self._gain_omega = .25 * self._gain_mu * self._gain_mu  # critically damped

        # Demodulate FM
        sensitivity = (pi / 2) / samples_per_symbol
        self.fmdemod = analog.quadrature_demod_cf(1.0 / sensitivity)

        # the clock recovery block tracks the symbol clock and resamples as needed.
        # the output of the block is a stream of soft symbols (float)
        self.clock_recovery = digital.clock_recovery_mm_ff(
            self._omega, self._gain_omega, self._mu, self._gain_mu,
            self._omega_relative_limit)

        # slice the floats at 0, outputting 1 bit (the LSB of the output byte) per sample
        self.slicer = digital.binary_slicer_fb()

        if verbose:
            self._print_verbage()

        if log:
            self._setup_logging()

        # Connect & Initialize base class
        self.connect(self, self.fmdemod, self.clock_recovery, self.slicer,
                     self)
Example #5
0
    def __init__(self,
                 samples_per_symbol=_def_samples_per_symbol,
                 gain_mu=_def_gain_mu,
                 mu=_def_mu,
                 omega_relative_limit=_def_omega_relative_limit,
                 freq_error=_def_freq_error,
                 verbose=_def_verbose,
                 log=_def_log):

	gr.hier_block2.__init__(self, "gmsk_demod",
				gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
				gr.io_signature(1, 1, gr.sizeof_char))       # Output signature

        self._samples_per_symbol = samples_per_symbol
        self._gain_mu = gain_mu
        self._mu = mu
        self._omega_relative_limit = omega_relative_limit
        self._freq_error = freq_error
        self._differential = False
        
        if samples_per_symbol < 2:
            raise TypeError, "samples_per_symbol >= 2, is %f" % samples_per_symbol

        self._omega = samples_per_symbol*(1+self._freq_error)

        if not self._gain_mu:
            self._gain_mu = 0.175
            
	self._gain_omega = .25 * self._gain_mu * self._gain_mu        # critically damped

	# Demodulate FM
	sensitivity = (pi / 2) / samples_per_symbol
	self.fmdemod = analog.quadrature_demod_cf(1.0 / sensitivity)

	# the clock recovery block tracks the symbol clock and resamples as needed.
	# the output of the block is a stream of soft symbols (float)
	self.clock_recovery = digital.clock_recovery_mm_ff(self._omega, self._gain_omega,
                                                           self._mu, self._gain_mu,
                                                           self._omega_relative_limit)

        # slice the floats at 0, outputting 1 bit (the LSB of the output byte) per sample
        self.slicer = digital.binary_slicer_fb()

        if verbose:
            self._print_verbage()
         
        if log:
            self._setup_logging()

	# Connect & Initialize base class
	self.connect(self, self.fmdemod, self.clock_recovery, self.slicer, self)
Example #6
0
    def __init__(self,
                 samples_per_symbol=_def_samples_per_symbol,
                 sensitivity=_def_sensitivity,
                 gain_mu=_def_gain_mu,
                 mu=_def_mu,
                 omega_relative_limit=_def_omega_relative_limit,
                 freq_error=_def_freq_error,
                 verbose=_def_verbose,
                 log=_def_log):
        """
	Hierarchical block for Gaussian Minimum Shift Key (GFSK)
	demodulation.

	The input is the complex modulated signal at baseband.
	The output is a stream of bits packed 1 bit per byte (the LSB)

	@param samples_per_symbol: samples per baud
	@type samples_per_symbol: integer
        @param verbose: Print information about modulator?
        @type verbose: bool
        @param log: Print modualtion data to files?
        @type log: bool 

        Clock recovery parameters.  These all have reasonble defaults.
        
        @param gain_mu: controls rate of mu adjustment
        @type gain_mu: float
        @param mu: fractional delay [0.0, 1.0]
        @type mu: float
        @param omega_relative_limit: sets max variation in omega
        @type omega_relative_limit: float, typically 0.000200 (200 ppm)
        @param freq_error: bit rate error as a fraction
        @param float
	"""

	gr.hier_block2.__init__(self, "gfsk_demod",
				gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
				gr.io_signature(1, 1, gr.sizeof_char))       # Output signature

        self._samples_per_symbol = samples_per_symbol
        self._gain_mu = gain_mu
        self._mu = mu
        self._omega_relative_limit = omega_relative_limit
        self._freq_error = freq_error
        self._differential = False
        
        if samples_per_symbol < 2:
            raise TypeError, "samples_per_symbol >= 2, is %f" % samples_per_symbol

        self._omega = samples_per_symbol*(1+self._freq_error)

        if not self._gain_mu:
            self._gain_mu = 0.175
            
	self._gain_omega = .25 * self._gain_mu * self._gain_mu        # critically damped

	# Demodulate FM
	#sensitivity = (pi / 2) / samples_per_symbol
	self.fmdemod = gr.quadrature_demod_cf(1.0 / sensitivity)

	# the clock recovery block tracks the symbol clock and resamples as needed.
	# the output of the block is a stream of soft symbols (float)
	self.clock_recovery = digital.clock_recovery_mm_ff(self._omega, self._gain_omega,
                                                           self._mu, self._gain_mu,
                                                           self._omega_relative_limit)

        # slice the floats at 0, outputting 1 bit (the LSB of the output byte) per sample
        self.slicer = digital.binary_slicer_fb()

        if verbose:
            self._print_verbage()
         
        if log:
            self._setup_logging()

	# Connect & Initialize base class
	self.connect(self, self.fmdemod, self.clock_recovery, self.slicer, self)