Exemple #1
0
    def setup_bpsk0(self):
        self.tb = gr.top_block()

        # Build the constellation object
        arity = 2
        bps = 1
        pts, code = digital.psk_2_0x0()
        constellation = digital.constellation_psk(pts, code, 2)

        # Create BPSK data to pass to the demodulator
        src = blocks.vector_source_b(self.src_data_bpsk)
        p2u = blocks.unpacked_to_packed_bb(1, gr.GR_MSB_FIRST)
        mod = digital.generic_mod(constellation, True, self.sps, True, self.eb)
        snk = blocks.vector_sink_c()

        tb = gr.top_block()
        tb.connect(src, p2u, mod, snk)
        tb.run()

        self.src = blocks.vector_source_c(snk.data())
        self.freq_recov = digital.fll_band_edge_cc(self.sps, self.eb,
                                                   self.fll_ntaps, self.freq_bw)
        self.time_recov = digital.pfb_clock_sync_ccf(self.sps, self.timing_bw, self.taps,
                                                     self.nfilts, self.nfilts//2, self.timing_max_dev)
        self.receiver = digital.constellation_receiver_cb(
            constellation.base(), self.phase_bw, self.fmin, self.fmax)
        self.diffdec = digital.diff_decoder_bb(arity)
        self.symbol_mapper = digital.map_bb(
            mod_codes.invert_code(constellation.pre_diff_code()))
        self.unpack = blocks.unpack_k_bits_bb(bps)
        self.snk = blocks.null_sink(gr.sizeof_char)

        self.tb.connect(self.src, self.freq_recov, self.time_recov, self.receiver)
        self.tb.connect(self.receiver, self.diffdec, self.symbol_mapper, self.unpack)
        self.tb.connect(self.unpack, self.snk)
Exemple #2
0
def make_non_differential_constellation(m, gray_coded):
    side = int(pow(m, 0.5))
    if (not isinstance(m, int) or m < 4 or not is_power_of_four(m)):
        raise ValueError("m must be a power of 4 integer.")
    # Each symbol holds k bits.
    k = int(log(m) / log(2.0))
    if gray_coded:
        # Number rows and columns using gray codes.
        gcs = gray_code(side)
        # Get inverse gray codes.
        i_gcs = mod_codes.invert_code(gcs)
    else:
        i_gcs = range(0, side)
    # The distance between points is found.
    step = 2.0 / (side - 1)

    gc_to_x = [-1 + i_gcs[gc] * step for gc in range(0, side)]
    # First k/2 bits determine x position.
    # Following k/2 bits determine y position.
    const_map = []
    for i in range(m):
        y = gc_to_x[get_bits(i, 0, k / 2)]
        x = gc_to_x[get_bits(i, k / 2, k / 2)]
        const_map.append(complex(x, y))
    return const_map
Exemple #3
0
    def setup_bpsk0(self):
        self.tb = gr.top_block()

        # Build the constellation object
        arity = 2
        bps = 1
        pts, code = digital.psk_2_0x0()
        constellation = digital.constellation_psk(pts, code, 2)

        # Create BPSK data to pass to the demodulator
        src = blocks.vector_source_b(self.src_data_bpsk)
        p2u = blocks.unpacked_to_packed_bb(1, gr.GR_MSB_FIRST)
        mod = digital.generic_mod(constellation, True, self.sps, True, self.eb)
        snk = blocks.vector_sink_c()

        tb = gr.top_block()
        tb.connect(src, p2u, mod, snk)
        tb.run()

        self.src = blocks.vector_source_c(snk.data())
        self.freq_recov = digital.fll_band_edge_cc(self.sps, self.eb,
                                                   self.fll_ntaps, self.freq_bw)
        self.time_recov = digital.pfb_clock_sync_ccf(self.sps, self.timing_bw, self.taps,
                                                     self.nfilts, self.nfilts//2, self.timing_max_dev)
        self.receiver = digital.constellation_receiver_cb(
            constellation.base(), self.phase_bw, self.fmin, self.fmax)
        self.diffdec = digital.diff_decoder_bb(arity)
        self.symbol_mapper = digital.map_bb(
            mod_codes.invert_code(constellation.pre_diff_code()))
        self.unpack = blocks.unpack_k_bits_bb(bps)
        self.snk = blocks.null_sink(gr.sizeof_char)

        self.tb.connect(self.src, self.freq_recov, self.time_recov, self.receiver)
        self.tb.connect(self.receiver, self.diffdec, self.symbol_mapper, self.unpack)
        self.tb.connect(self.unpack, self.snk)
Exemple #4
0
def make_non_differential_constellation(m, gray_coded):
    side = int(pow(m, 0.5))
    if (not isinstance(m, int) or m < 4 or not is_power_of_four(m)):
        raise ValueError("m must be a power of 4 integer.")
    # Each symbol holds k bits.
    k = int(log(m) / log(2.0))
    if gray_coded:
        # Number rows and columns using gray codes.
        gcs = gray_code(side)
        # Get inverse gray codes.
        i_gcs = mod_codes.invert_code(gcs)
    else:
        i_gcs = range(0, side)
    # The distance between points is found.
    step = 2.0/(side-1)

    gc_to_x = [-1 + i_gcs[gc]*step for gc in range(0, side)]
    # First k/2 bits determine x position.
    # Following k/2 bits determine y position.
    const_map = []
    for i in range(m):
        y = gc_to_x[get_bits(i, 0, k/2)]
        x = gc_to_x[get_bits(i, k/2, k/2)]
        const_map.append(complex(x,y))
    return const_map
Exemple #5
0
    def __init__(self, constellation, differential, rotation):
        if constellation.arity() > 256:
            # If this becomes limiting some of the blocks should be generalised so
            # that they can work with shorts and ints as well as chars.
            raise ValueError("Constellation cannot contain more than 256 points.")

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

        arity = constellation.arity()

        # TX
        self.constellation = constellation
        self.differential = differential
        import weakref

        self.blocks = [weakref.proxy(self)]
        # We expect a stream of unpacked bits.
        # First step is to pack them.
        self.blocks.append(blocks.unpacked_to_packed_bb(1, gr.GR_MSB_FIRST))
        # Second step we unpack them such that we have k bits in each byte where
        # each constellation symbol hold k bits.
        self.blocks.append(blocks.packed_to_unpacked_bb(self.constellation.bits_per_symbol(), gr.GR_MSB_FIRST))
        # Apply any pre-differential coding
        # Gray-coding is done here if we're also using differential coding.
        if self.constellation.apply_pre_diff_code():
            self.blocks.append(digital.map_bb(self.constellation.pre_diff_code()))
        # Differential encoding.
        if self.differential:
            self.blocks.append(digital.diff_encoder_bb(arity))
        # Convert to constellation symbols.
        self.blocks.append(
            digital.chunks_to_symbols_bc(self.constellation.points(), self.constellation.dimensionality())
        )
        # CHANNEL
        # Channel just consists of a rotation to check differential coding.
        if rotation is not None:
            self.blocks.append(blocks.multiply_const_cc(rotation))

        # RX
        # Convert the constellation symbols back to binary values.
        self.blocks.append(digital.constellation_decoder_cb(self.constellation.base()))
        # Differential decoding.
        if self.differential:
            self.blocks.append(digital.diff_decoder_bb(arity))
        # Decode any pre-differential coding.
        if self.constellation.apply_pre_diff_code():
            self.blocks.append(digital.map_bb(mod_codes.invert_code(self.constellation.pre_diff_code())))
        # unpack the k bit vector into a stream of bits
        self.blocks.append(blocks.unpack_k_bits_bb(self.constellation.bits_per_symbol()))
        # connect to block output
        check_index = len(self.blocks)
        self.blocks = self.blocks[:check_index]
        self.blocks.append(weakref.proxy(self))

        self.connect(*self.blocks)
    def __init__(self, constellation, differential, rotation):
        if constellation.arity() > 256:
            # If this becomes limiting some of the blocks should be generalised so
            # that they can work with shorts and ints as well as chars.
            raise ValueError("Constellation cannot contain more than 256 points.")

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

        arity = constellation.arity()

        # TX
        self.constellation = constellation
        self.differential = differential
        import weakref
        self.blocks = [weakref.proxy(self)]
        # We expect a stream of unpacked bits.
        # First step is to pack them.
        self.blocks.append(blocks.unpacked_to_packed_bb(1, gr.GR_MSB_FIRST))
        # Second step we unpack them such that we have k bits in each byte where
        # each constellation symbol hold k bits.
        self.blocks.append(
            blocks.packed_to_unpacked_bb(self.constellation.bits_per_symbol(),
                                         gr.GR_MSB_FIRST))
        # Apply any pre-differential coding
        # Gray-coding is done here if we're also using differential coding.
        if self.constellation.apply_pre_diff_code():
            self.blocks.append(digital.map_bb(self.constellation.pre_diff_code()))
        # Differential encoding.
        if self.differential:
            self.blocks.append(digital.diff_encoder_bb(arity))
        # Convert to constellation symbols.
        self.blocks.append(digital.chunks_to_symbols_bc(self.constellation.points(),
                                                        self.constellation.dimensionality()))
        # CHANNEL
        # Channel just consists of a rotation to check differential coding.
        if rotation is not None:
            self.blocks.append(blocks.multiply_const_cc(rotation))

        # RX
        # Convert the constellation symbols back to binary values.
        self.blocks.append(digital.constellation_decoder_cb(self.constellation.base()))
        # Differential decoding.
        if self.differential:
            self.blocks.append(digital.diff_decoder_bb(arity))
        # Decode any pre-differential coding.
        if self.constellation.apply_pre_diff_code():
            self.blocks.append(digital.map_bb(
                mod_codes.invert_code(self.constellation.pre_diff_code())))
        # unpack the k bit vector into a stream of bits
        self.blocks.append(blocks.unpack_k_bits_bb(
                self.constellation.bits_per_symbol()))
        # connect to block output
        check_index = len(self.blocks)
        self.blocks = self.blocks[:check_index]
        self.blocks.append(weakref.proxy(self))

        self.connect(*self.blocks)
Exemple #7
0
def psk_constellation(m=_def_constellation_points, mod_code=_def_mod_code):
    """
    Creates a PSK constellation object.
    """
    k = log(m) / log(2.0)
    if (k != int(k)):
        raise StandardError('Number of constellation points must be a power of two.')
    points = [exp(2*pi*(0+1j)*i/m) for i in range(0,m)]
    pre_diff_code, post_diff_code = create_encodings(mod_code, m)
    if post_diff_code is not None:
        inverse_post_diff_code = mod_codes.invert_code(post_diff_code)
        points = [points[x] for x in inverse_post_diff_code]
    constellation = digital_swig.constellation_psk(points, pre_diff_code, m)
    return constellation
Exemple #8
0
def psk_constellation(m=_def_constellation_points, mod_code=_def_mod_code):
    """
    Creates a PSK constellation object.
    """
    k = log(m) / log(2.0)
    if (k != int(k)):
        raise StandardError(
            'Number of constellation points must be a power of two.')
    points = [exp(2 * pi * (0 + 1j) * i / m) for i in range(0, m)]
    pre_diff_code, post_diff_code = create_encodings(mod_code, m)
    if post_diff_code is not None:
        inverse_post_diff_code = mod_codes.invert_code(post_diff_code)
        points = [points[x] for x in inverse_post_diff_code]
    constellation = digital_swig.constellation_psk(points, pre_diff_code, m)
    return constellation
    def __init__(self,
                 bits_per_symbol=_def_bits_per_symbol,
                 differential=_def_differential,
                 mod_code=_def_mod_code,
                 debug=False):
        #GNURadio constructor
        gr.hier_block2.__init__(self, "psk_constellation_demod",
                                gr.io_signature(1, 1, gr.sizeof_gr_complex),
                                gr.io_signature(1, 1, gr.sizeof_char))

        #Init internal attributes and basic building blocks
        self._bits_per_symbol = bits_per_symbol
        self._constellation_points = pow(2, bits_per_symbol)
        self._constellation = psk_constellation(self._constellation_points,
                                                mod_code, differential)
        self._constellation_decoder = digital_swig.constellation_decoder_cb(
            self._constellation.base())
        self._differential = differential
        self._mod_code = mod_code
        self._pre_diff_code = self._constellation.apply_pre_diff_code()
        if self._differential:
            self._diffdec = digital_swig.diff_decoder_bb(
                self._constellation_points)
        if self._pre_diff_code:
            self._symbol_mapper = digital_swig.map_bb(
                mod_codes.invert_code(self._constellation.pre_diff_code()))

        # unpack the k bit vector into a stream of bits
        self.unpack = blocks.unpack_k_bits_bb(self.bits_per_symbol())

        # Connect and Initialize base class
        self._blocks = [self, self._constellation_decoder]
        if self._differential:
            self._blocks.append(self._diffdec)
        if self._pre_diff_code:
            self._blocks.append(self._symbol_mapper)
        self._blocks += [self.unpack, self]
        if debug:
            self.debug_internal_state()
        self.connect(*self._blocks)