def qam32_holeinside_constellation(large_ampls_to_corners=False): # First make constellation for one quadrant. # 0 1 2 # 2 - 010 111 110 # 1 - 011 101 100 # 0 - 000 001 # Have put hole in the side rather than corner. # Corner point is helpful for frequency locking. # It has an attempt at some gray-coding, but not # a very good one. # Indices are (horizontal, vertical). indices_and_numbers = ( ((0, 0), 0b000), ((0, 1), 0b011), ((0, 2), 0b010), ((1, 0), 0b001), ((1, 1), 0b101), ((1, 2), 0b111), ((2, 1), 0b100), ((2, 2), 0b110), ) points = [None] * 32 for indices, number in indices_and_numbers: p_in_quadrant = 0.5 + indices[0] + 1j * (0.5 + indices[1]) for quadrant in range(4): index = number + 8 * quadrant rotation = pow(1j, quadrant) p = p_in_quadrant * rotation points[index] = p side = 6 width = 1 # Double number of boxes on side # This is so that points in the 'hole' get assigned correctly. side = 12 width = 0.5 pre_diff_code = [] if not large_ampls_to_corners: constellation = digital_swig.constellation_rect( points, pre_diff_code, 4, side, side, width, width) else: sector_values = large_ampls_to_corners_mapping(side, points, width) constellation = digital_swig.constellation_expl_rect( points, pre_diff_code, 4, side, side, width, width, sector_values) return constellation
def qam32_holeinside_constellation(large_ampls_to_corners=False): # First make constellation for one quadrant. # 0 1 2 # 2 - 010 111 110 # 1 - 011 101 100 # 0 - 000 001 # Have put hole in the side rather than corner. # Corner point is helpful for frequency locking. # It has an attempt at some gray-coding, but not # a very good one. # Indices are (horizontal, vertical). indices_and_numbers = ( ((0, 0), 0b000), ((0, 1), 0b011), ((0, 2), 0b010), ((1, 0), 0b001), ((1, 1), 0b101), ((1, 2), 0b111), ((2, 1), 0b100), ((2, 2), 0b110), ) points = [None]*32 for indices, number in indices_and_numbers: p_in_quadrant = 0.5+indices[0] + 1j*(0.5+indices[1]) for quadrant in range(4): index = number + 8 * quadrant rotation = pow(1j, quadrant) p = p_in_quadrant * rotation points[index] = p side = 6 width = 1 # Double number of boxes on side # This is so that points in the 'hole' get assigned correctly. side = 12 width = 0.5 pre_diff_code = [] if not large_ampls_to_corners: constellation = digital_swig.constellation_rect(points, pre_diff_code, 4, side, side, width, width) else: sector_values = large_ampls_to_corners_mapping(side, points, width) constellation = digital_swig.constellation_expl_rect( points, pre_diff_code, 4, side, side, width, width, sector_values) return constellation
def qam_constellation(constellation_points=_def_constellation_points, differential=_def_differential, mod_code=_def_mod_code, large_ampls_to_corners=False): """ Creates a QAM constellation object. If large_ampls_to_corners=True then sectors that are probably occupied due to a phase offset, are not mapped to the closest constellation point. Rather we take into account the fact that a phase offset is probably the problem and map them to the closest corner point. It's a bit hackish but it seems to improve frequency locking. """ if mod_code == mod_codes.GRAY_CODE: gray_coded = True elif mod_code == mod_codes.NO_CODE: gray_coded = False else: raise ValueError("Mod code is not implemented for QAM") if differential: points = make_differential_constellation(constellation_points, gray_coded=False) else: points = make_non_differential_constellation(constellation_points, gray_coded) side = int(sqrt(constellation_points)) width = 2.0/(side-1) # No pre-diff code # Should add one so that we can gray-code the quadrant bits too. pre_diff_code = [] if not large_ampls_to_corners: constellation = digital.constellation_rect(points, pre_diff_code, 4, side, side, width, width) else: sector_values = large_ampls_to_corners_mapping(side, points, width) constellation = digital.constellation_expl_rect( points, pre_diff_code, 4, side, side, width, width, sector_values) return constellation