1
0
Fork 0
mirror of https://github.com/hb9fxq/gr-digitalhf synced 2024-12-22 15:10:00 +00:00

preparations for XOR scrambling

work on 110C mode (intermediate)
This commit is contained in:
cmayer 2019-05-14 22:39:57 +02:00
parent be31566ff1
commit 6cf9752275
9 changed files with 207 additions and 81 deletions

View file

@ -164,7 +164,7 @@
</param> </param>
<param> <param>
<key>value</key> <key>value</key>
<value>'600/L'</value> <value>'1200/L'</value>
</param> </param>
<param> <param>
<key>_enabled</key> <key>_enabled</key>
@ -240,7 +240,7 @@
</param> </param>
<param> <param>
<key>options</key> <key>options</key>
<value>['2400/L', '1200/L', '600/L', '300/L', '150/L', '75/L']</value> <value>['2400/L', '1200/L', '600/L', '300/L', '150/L', '75/L', '2400/S', '1200/S', '600/S', '300/S', '150/S', '75/S']</value>
</param> </param>
<param> <param>
<key>orient</key> <key>orient</key>
@ -877,11 +877,11 @@
</param> </param>
<param> <param>
<key>file</key> <key>file</key>
<value>/Users/chm/Software/gr-digitalhf/examples/on5kq.ddns.net_2019-03-20T12_49_38Z_2381.40_iq.wav</value> <value>/Users/chm/Downloads/sdr.loginto.me_2019-05-14T13_46_37Z_7938.80_iq.wav</value>
</param> </param>
<param> <param>
<key>_coordinate</key> <key>_coordinate</key>
<value>(10, 154)</value> <value>(21, 154)</value>
</param> </param>
<param> <param>
<key>_rotation</key> <key>_rotation</key>

View file

@ -83,6 +83,7 @@ adaptive_dfe_impl::adaptive_dfe_impl(int sps, // samples per symbol
, _constellation_index() , _constellation_index()
, _symbols() , _symbols()
, _scramble() , _scramble()
, _scramble_xor()
, _descrambled_symbols() , _descrambled_symbols()
, _symbol_counter(0) , _symbol_counter(0)
, _save_soft_decisions(false) , _save_soft_decisions(false)
@ -280,7 +281,12 @@ gr_complex adaptive_dfe_impl::filter(gr_complex const* start, gr_complex const*
float const err = std::abs(descrambled_filter_output - descrambled_symbol); float const err = std::abs(descrambled_filter_output - descrambled_symbol);
std::vector<float> const soft_dec = constell->calc_soft_dec std::vector<float> const soft_dec = constell->calc_soft_dec
(descrambled_filter_output, _npwr[_constellation_index].filter(err)); (descrambled_filter_output, _npwr[_constellation_index].filter(err));
std::copy(soft_dec.begin(), soft_dec.end(), std::back_inserter<std::vector<float> >(_vec_soft_decisions)); // std::cout << "SD: " << descrambled_filter_output << " : ";
for (int j=0, m=soft_dec.size(); j<m; ++j) {
_vec_soft_decisions.push_back(soft_dec[j] * _scramble_xor[_symbol_counter][j]);
// std::cout << " " << _vec_soft_decisions.back();
}
// std::cout << std::endl;
} }
known_symbol = _scramble[_symbol_counter] * descrambled_symbol; known_symbol = _scramble[_symbol_counter] * descrambled_symbol;
} }
@ -289,6 +295,8 @@ gr_complex adaptive_dfe_impl::filter(gr_complex const* start, gr_complex const*
if (is_known || update_taps) { if (is_known || update_taps) {
// (3a) update of adaptive filter taps // (3a) update of adaptive filter taps
gr_complex const err = filter_output - known_symbol; gr_complex const err = filter_output - known_symbol;
if (std::abs(err)>0.5)
std::cout << "err= " << std::abs(err) << std::endl;
// taps_samples // taps_samples
for (int j=0; j<_nB+_nF+1; ++j) { for (int j=0; j<_nB+_nF+1; ++j) {
_last_taps_samples[j] = _taps_samples[j]; _last_taps_samples[j] = _taps_samples[j];
@ -311,7 +319,7 @@ gr_complex adaptive_dfe_impl::filter(gr_complex const* start, gr_complex const*
for (int j=_nB+1-2*_sps; j<_nB+1+2*_sps+1; ++j) for (int j=_nB+1-2*_sps; j<_nB+1+2*_sps+1; ++j)
acc += std::conj(_last_taps_samples[j]) * _taps_samples[j]; acc += std::conj(_last_taps_samples[j]) * _taps_samples[j];
float const frequency_err = gr::fast_atan2f(acc)/(1+0*_num_samples_since_filter_update); // frequency error (rad/sample) float const frequency_err = gr::fast_atan2f(acc)/(1+0*_num_samples_since_filter_update); // frequency error (rad/sample)
std::cout << "frequency_err " << frequency_err << " " << _num_samples_since_filter_update << std::endl; GR_LOG_DEBUG(d_logger, str(boost::format("frequency_err= %f %d") % frequency_err % _num_samples_since_filter_update));
_control_loop.advance_loop(frequency_err); _control_loop.advance_loop(frequency_err);
_control_loop.phase_wrap(); _control_loop.phase_wrap();
_control_loop.frequency_limit(); _control_loop.frequency_limit();
@ -390,8 +398,7 @@ void adaptive_dfe_impl::update_constellations(pmt::pmt_t data) {
int const n = pmt::length(data); int const n = pmt::length(data);
_constellations.resize(n); _constellations.resize(n);
_npwr.resize(n); _npwr.resize(n);
std::cout << "adaptive_dfe_impl::update_constellations " << data << std::endl; GR_LOG_DEBUG(d_logger, str(boost::format("update_constellations %s n=%d") % data % n));
std::cout << "adaptive_dfe_impl::update_constellations n=" << n << std::endl;
unsigned int const rotational_symmetry = 0; unsigned int const rotational_symmetry = 0;
unsigned int const dimensionality = 1; unsigned int const dimensionality = 1;
@ -415,6 +422,18 @@ void adaptive_dfe_impl::update_frame_info(pmt::pmt_t data)
_constellation_index = pmt::to_long(pmt::dict_ref(data, pmt::intern("constellation_idx"), pmt::PMT_NIL)); _constellation_index = pmt::to_long(pmt::dict_ref(data, pmt::intern("constellation_idx"), pmt::PMT_NIL));
_save_soft_decisions = pmt::to_bool(pmt::dict_ref(data, pmt::intern("save_soft_dec"), pmt::PMT_F)); _save_soft_decisions = pmt::to_bool(pmt::dict_ref(data, pmt::intern("save_soft_dec"), pmt::PMT_F));
bool const do_continue = pmt::to_bool(pmt::dict_ref(data, pmt::intern("do_continue"), pmt::PMT_F)); bool const do_continue = pmt::to_bool(pmt::dict_ref(data, pmt::intern("do_continue"), pmt::PMT_F));
// make table +-1
std::vector<std::uint8_t> const scr_xor = pmt::u8vector_elements(pmt::dict_ref(data, pmt::intern("scramble_xor"), pmt::PMT_NIL));
_scramble_xor.resize(scr_xor.size());
gr::digital::constellation_sptr constell = _constellations[_constellation_index];
for (int i=0, n=scr_xor.size(); i<n; ++i) {
for (int j=0, m=constell->bits_per_symbol(); j<m; ++j) {
_scramble_xor[i][m-j-1] = 1 - 2*bool(scr_xor[i] & (1<<j));
// GR_LOG_DEBUG(d_logger, str(boost::format("XOR %3d %3d %d") % i % j % _scramble_xor[i][j]));
}
}
assert(_symbols.size() == _scramble.size()); assert(_symbols.size() == _scramble.size());
_descrambled_symbols.resize(_symbols.size()); _descrambled_symbols.resize(_symbols.size());
_vec_soft_decisions.clear(); _vec_soft_decisions.clear();

View file

@ -80,9 +80,10 @@ private:
std::vector<constellation_distance_filter> _npwr; std::vector<constellation_distance_filter> _npwr;
int _npwr_max_time_constant; int _npwr_max_time_constant;
int _constellation_index; int _constellation_index;
std::vector<gr_complex> _symbols; std::vector<gr_complex> _symbols;
std::vector<gr_complex> _scramble; std::vector<gr_complex> _scramble; // PSK-8 scramble symbols
std::vector<gr_complex> _descrambled_symbols; std::vector<std::array<int,8> > _scramble_xor; // signs for XOR scrambling
std::vector<gr_complex> _descrambled_symbols;
int _symbol_counter; int _symbol_counter;
bool _save_soft_decisions; bool _save_soft_decisions;

View file

@ -74,6 +74,7 @@ class msg_proxy(gr.basic_block):
msg_out = pmt.make_dict() msg_out = pmt.make_dict()
msg_out = pmt.dict_add(msg_out, pmt.intern('symb'), pmt.to_pmt(symb['symb'])) msg_out = pmt.dict_add(msg_out, pmt.intern('symb'), pmt.to_pmt(symb['symb']))
msg_out = pmt.dict_add(msg_out, pmt.intern('scramble'), pmt.to_pmt(symb['scramble'])) msg_out = pmt.dict_add(msg_out, pmt.intern('scramble'), pmt.to_pmt(symb['scramble']))
msg_out = pmt.dict_add(msg_out, pmt.intern('scramble_xor'), pmt.to_pmt(symb['scramble_xor']))
msg_out = pmt.dict_add(msg_out, pmt.intern('constellation_idx'), pmt.to_pmt(constellation_idx)) msg_out = pmt.dict_add(msg_out, pmt.intern('constellation_idx'), pmt.to_pmt(constellation_idx))
msg_out = pmt.dict_add(msg_out, pmt.intern('do_continue'), pmt.to_pmt(np.bool(do_continue))) msg_out = pmt.dict_add(msg_out, pmt.intern('do_continue'), pmt.to_pmt(np.bool(do_continue)))
msg_out = pmt.dict_add(msg_out, pmt.intern('save_soft_dec'), pmt.to_pmt(np.bool(save_soft_dec))) msg_out = pmt.dict_add(msg_out, pmt.intern('save_soft_dec'), pmt.to_pmt(np.bool(save_soft_dec)))

View file

@ -199,9 +199,7 @@ class PhysicalLayer(object):
self._frame_counter = 0 self._frame_counter = 0
scramble_for_frame = common.n_psk(8, np.array([self._scr_data.next() scramble_for_frame = common.n_psk(8, np.array([self._scr_data.next()
for _ in range(self._frame_len)])) for _ in range(self._frame_len)]))
a = np.array(zip(scramble_for_frame, a = common.make_scr(scramble_for_frame, scramble_for_frame)
scramble_for_frame),
common.SYMB_SCRAMBLE_DTYPE)
n_unknown = self._mode['unknown'] n_unknown = self._mode['unknown']
a['symb'][0:n_unknown] = 0 a['symb'][0:n_unknown] = 0
if self._mode['known'] != 0 and self._frame_counter >= self._num_frames_per_block-2: if self._mode['known'] != 0 and self._frame_counter >= self._num_frames_per_block-2:
@ -296,10 +294,8 @@ class PhysicalLayer(object):
@staticmethod @staticmethod
def get_preamble(): def get_preamble():
"""preamble symbols + scrambler""" """preamble symbols + scrambler"""
return np.array(zip(PRE_SCRAMBLE*PRE_SYMBOLS, return common.make_scr(PRE_SCRAMBLE*PRE_SYMBOLS,
PRE_SCRAMBLE), PRE_SCRAMBLE)
common.SYMB_SCRAMBLE_DTYPE)
def get_preamble_z(self): def get_preamble_z(self):
"""preamble symbols for preamble correlation""" """preamble symbols for preamble correlation"""
a = PhysicalLayer.get_preamble() a = PhysicalLayer.get_preamble()

View file

@ -3,11 +3,12 @@
from __future__ import print_function from __future__ import print_function
import numpy as np import numpy as np
import common import common
from digitalhf.digitalhf_swig import viterbi27
## ---- constellations ----------------------------------------------------------- ## ---- constellations -----------------------------------------------------------
BPSK=np.array(zip(np.exp(2j*np.pi*np.arange(2)/2), [0,1]), common.CONST_DTYPE) BPSK=np.array(zip(np.exp(2j*np.pi*np.arange(2)/2), [0,1]), common.CONST_DTYPE)
QPSK=np.array(zip(np.exp(2j*np.pi*np.arange(4)/4), [0,1,3,2]), common.CONST_DTYPE) QPSK=np.array(zip(np.exp(2j*np.pi*np.arange(4)/4), [0,1,3,2]), common.CONST_DTYPE)
PSK8=np.array(zip(np.exp(2j*np.pi*np.arange(8)/8), [0,1,3,2,7,6,4,5]), common.CONST_DTYPE) PSK8=np.array(zip(np.exp(2j*np.pi*np.arange(8)/8), [1,0,2,3,7,6,4,5]), common.CONST_DTYPE)
QAM16=np.array( QAM16=np.array(
zip([+0.866025+0.500000j, 0.500000+0.866025j, 1.000000+0.000000j, 0.258819+0.258819j, zip([+0.866025+0.500000j, 0.500000+0.866025j, 1.000000+0.000000j, 0.258819+0.258819j,
-0.500000+0.866025j, 0.000000+1.000000j, -0.866025+0.500000j, -0.258819+0.258819j, -0.500000+0.866025j, 0.000000+1.000000j, -0.866025+0.500000j, -0.258819+0.258819j,
@ -104,29 +105,93 @@ MINI_PROBE=[common.n_psk(8, np.array([0,0,0,0,0,2,4,6,0,4,0,4,0,6,4,2,0,0,0,0,0,
TO_DIBIT=[(0,0),(0,1),(1,1),(1,0)] TO_DIBIT=[(0,0),(0,1),(1,1),(1,0)]
## ---- rate ------------------------------------------------------------------- ## ---- rate -------------------------------------------------------------------
TO_RATE={(0,0,0): {'baud': 0, 'bits_per_symbol': 0}, ## reserved TO_RATE={(0,0,0): {'baud': '--------', 'bits_per_symbol': 0}, ## reserved
(0,0,1): {'baud': 3200, 'bits_per_symbol': 2, 'ci': MODE_QPSK}, (0,0,1): {'baud': '3200 bps', 'bits_per_symbol': 2, 'ci': MODE_QPSK},
(0,1,0): {'baud': 4800, 'bits_per_symbol': 3, 'ci': MODE_8PSK}, (0,1,0): {'baud': '4800 bps', 'bits_per_symbol': 3, 'ci': MODE_8PSK},
(0,1,1): {'baud': 6400, 'bits_per_symbol': 4, 'ci': MODE_16QAM}, (0,1,1): {'baud': '6400 bps', 'bits_per_symbol': 4, 'ci': MODE_16QAM},
(1,0,0): {'baud': 8000, 'bits_per_symbol': 5, 'ci': MODE_32QAM}, (1,0,0): {'baud': '8000 bps', 'bits_per_symbol': 5, 'ci': MODE_32QAM},
(1,0,1): {'baud': 9600, 'bits_per_symbol': 6, 'ci': MODE_64QAM}, (1,0,1): {'baud': '9600 bps', 'bits_per_symbol': 6, 'ci': MODE_64QAM},
(1,1,0): {'baud':12800, 'bits_per_symbol': 6, 'ci': MODE_64QAM}, (1,1,0): {'baud':'12800 bps', 'bits_per_symbol': 6, 'ci': MODE_64QAM},
(1,1,1): {'baud': 0, 'bits_per_symbol': 0}} ## reserved (1,1,1): {'baud': '--------', 'bits_per_symbol': 0}} ## reserved
## ---- interleaver ------------------------------------------------------------ ## ---- interleaver ------------------------------------------------------------
TO_INTERLEAVER={(0,0,0): {'frames': -1, 'name': 'illegal'}, TO_INTERLEAVER={(0,0,0): {'frames': -1, 'id': '--', 'name': 'illegal'},
(0,0,1): {'frames': 1, 'name': 'Ultra Short (US)'}, (0,0,1): {'frames': 1, 'id': 'US', 'name': 'Ultra Short'},
(0,1,0): {'frames': 3, 'name': 'Very Short (VS)'}, (0,1,0): {'frames': 3, 'id': 'VS', 'name': 'Very Short'},
(0,1,1): {'frames': 9, 'name': 'Short (S)'}, (0,1,1): {'frames': 9, 'id': 'S', 'name': 'Short'},
(1,0,0): {'frames': 18, 'name': 'Medium (M)'}, (1,0,0): {'frames': 18, 'id': 'M', 'name': 'Medium'},
(1,0,1): {'frames': 36, 'name': 'Long (L)'}, (1,0,1): {'frames': 36, 'id': 'L', 'name': 'Long'},
(1,1,0): {'frames': 72, 'name': 'very Long (VL)'}, (1,1,0): {'frames': 72, 'id': 'VL', 'name': 'Very Long'},
(1,1,1): {'frames': -1, 'name': 'illegal'}} (1,1,1): {'frames': -1, 'id': '--', 'name': 'illegal'}}
MP_COUNTER=[(0,0,1), ## 1st
(0,1,0), ## 2nd
(0,1,1), ## 3rd
(1,0,0)] ## 4th
## ---- interleaver size
INTL_SIZE = { ## 1 3 9 18 36 72
'--------': {'US': 0, 'VS': 0, 'S': 0, 'M': 0, 'L': 0, 'VL': 0},
'3200 bps': {'US': 512, 'VS': 1536, 'S': 4608, 'M': 9216, 'L': 18432, 'VL': 36864},
'4800 bps': {'US': 768, 'VS': 2304, 'S': 6912, 'M': 13824, 'L': 27648, 'VL': 55296},
'6400 bps': {'US': 1024, 'VS': 3072, 'S': 9216, 'M': 18432, 'L': 36864, 'VL': 73728},
'8000 bps': {'US': 1280, 'VS': 3840, 'S': 11520, 'M': 23040, 'L': 46080, 'VL': 92160},
'9600 bps': {'US': 1536, 'VS': 4608, 'S': 13824, 'M': 27648, 'L': 55296, 'VL': 110592}
}
## ---- interleaver increment
INTL_INCR = { ## 1 3 9 18 36 72
'--------': {'US': 0, 'VS': 0, 'S': 0, 'M': 0, 'L': 0, 'VL': 0},
'3200 bps': {'US': 97, 'VS': 229, 'S': 805, 'M': 1393, 'L': 3281, 'VL': 6985},
'4800 bps': {'US': 145, 'VS': 361, 'S': 1045, 'M': 2089, 'L': 5137, 'VL': 10273},
'6400 bps': {'US': 189, 'VS': 481, 'S': 1393, 'M': 3281, 'L': 6985, 'VL': 11141},
'8000 bps': {'US': 201, 'VS': 601, 'S': 1741, 'M': 3481, 'L': 8561, 'VL': 14441},
'9600 bps': {'US': 229, 'VS': 805, 'S': 2089, 'M': 5137, 'L': 10273, 'VL': 17329}
}
## ---- deinterleaver+depuncturer
class DeIntl_DePunct(object):
"""deinterleave"""
def __init__(self, size, incr):
self._size = size
self._i = 0
self._array = np.zeros(size, dtype=np.float32)
self._idx = np.mod(incr*np.arange(size, dtype=np.uint32), size)
print('deinterleaver: ', size, incr, self._idx[0:100])
def fetch(self, a):
pass
def load(self, a):
n = len(a)
i = self._i
if i==0:
self._array[:] = 0
print('deinterleaver load buffer:', i,len(self._array),n)
assert(i+n <= self._size)
self._array[i:i+n] = a
self._i += n
result = np.zeros(0, dtype=np.float64)
if self._i == self._size:
print('==== TEST ====', self._array)
#tmp = np.zeros(self._size, dtype=np.float32)
tmp = self._array[self._idx]
result = np.zeros(self._size*6//4, dtype=np.float64)
assert(len(result[0::6]) == len(tmp[0::4]))
assert(len(result[1::6]) == len(tmp[1::4]))
assert(len(result[2::6]) == len(tmp[2::4]))
assert(len(result[5::6]) == len(tmp[3::4]))
result[0::6] = tmp[0::4]
result[1::6] = tmp[1::4]
result[2::6] = tmp[2::4]
result[3::6] = 0
result[4::6] = 0
result[5::6] = tmp[3::4]
print('==================== interleaver is full! ====================',
len(result[0::6]), len(tmp[0::4]), np.sum(result==0))
self._i = 0
return result
MP_COUNTER=[(0,0,1),
(0,1,0),
(0,1,1),
(1,0,0)]
## ---- physcal layer class ----------------------------------------------------- ## ---- physcal layer class -----------------------------------------------------
class PhysicalLayer(object): class PhysicalLayer(object):
@ -138,7 +203,8 @@ class PhysicalLayer(object):
self._frame_counter = -2 self._frame_counter = -2
self._constellations = [BPSK, QPSK, PSK8, QAM16, QAM32, QAM64] self._constellations = [BPSK, QPSK, PSK8, QAM16, QAM32, QAM64]
self._preamble = self.get_preamble() self._preamble = self.get_preamble()
self._interleaver_length = 72 ## set in decode_reinserted preamble to the actual value self._scramble = ScrambleData()
self._viterbi_decoder = viterbi27(0x6d, 0x4f)
def get_constellations(self): def get_constellations(self):
return self._constellations return self._constellations
@ -153,6 +219,8 @@ class PhysicalLayer(object):
print('-------------------- get_frame --------------------', self._frame_counter) print('-------------------- get_frame --------------------', self._frame_counter)
success = True success = True
if self._frame_counter == -2: ## ---- preamble if self._frame_counter == -2: ## ---- preamble
self._deintl_depunct = None
self._mode = {}
self._preamble_offset = 0 self._preamble_offset = 0
self._frame_counter += 1 self._frame_counter += 1
return [self._preamble,MODE_BPSK,success,False] return [self._preamble,MODE_BPSK,success,False]
@ -215,46 +283,67 @@ class PhysicalLayer(object):
def decode_reinserted_preamble(self, symbols): def decode_reinserted_preamble(self, symbols):
## decode D0,D1,D2 ## decode D0,D1,D2
success = True
z = np.array([np.mean(symbols[-71+i*13:-71+(i+1)*13]) for i in range(3)]) z = np.array([np.mean(symbols[-71+i*13:-71+(i+1)*13]) for i in range(3)])
print('decode_reinserted_preamble', symbols[0:-71], symbols[-71:-71+3*13], symbols[-71+4*13:], z) if np.mean(np.abs(z)) < 0.4:
return False
print('decode_reinserted_preamble',
'\nHH', symbols[0:-71],
'\nD0', symbols[-71 :-71+13],
'\nD1', symbols[-71+13:-71+26],
'\nD2', symbols[-71+26:-71+39],
'\nTT', symbols[-71+4*13:], z)
d0d1d2 = map(np.uint8, np.mod(np.round(np.angle(z)/np.pi*2),4)) d0d1d2 = map(np.uint8, np.mod(np.round(np.angle(z)/np.pi*2),4))
dibits = [TO_DIBIT[idx] for idx in d0d1d2] dibits = [TO_DIBIT[idx] for idx in d0d1d2]
self._mode = {'rate': tuple([x[0] for x in dibits]), mode = {'rate': tuple([x[0] for x in dibits]),
'interleaver': tuple([x[1] for x in dibits])} 'interleaver': tuple([x[1] for x in dibits])}
print('======== rate,interleaver:', if self._mode != {}:
TO_RATE[self._mode['rate']], success = (mode == self._mode)
TO_INTERLEAVER[self._mode['interleaver']]) if not success:
self._interleaver_length = TO_INTERLEAVER[self._mode['interleaver']]['frames'] return success
rate_info = TO_RATE[self._mode['rate']] self._mode = mode
print('rate_info', rate_info) self._rate_info = rate_info = TO_RATE[self._mode['rate']]
self._intl_info = intl_info = TO_INTERLEAVER[self._mode['interleaver']]
print('======== rate,interleaver:', rate_info, intl_info)
self._interleaver_frames = intl_info['frames']
baud = rate_info['baud']
intl_id = intl_info['id']
intl_size = INTL_SIZE[baud][intl_id]
intl_incr = INTL_INCR[baud][intl_id]
if self._deintl_depunct == None:
self._deintl_depunct = DeIntl_DePunct(size=intl_size,
incr=intl_incr)
self._constellation_index = rate_info['ci'] self._constellation_index = rate_info['ci']
print('constellation index', self._constellation_index) print('constellation index', self._constellation_index)
scr = ScrambleData() self._scramble.reset()
iscr = [scr.next(rate_info['bits_per_symbol']) for _ in range(256)] num_bits = max(3, rate_info['bits_per_symbol'])
iscr = np.array([self._scramble.next(num_bits) for _ in range(256)],
dtype=np.uint8)
print('iscr=', iscr)
self._data_scramble = np.ones (256, dtype=np.complex64)
self._data_scramble_xor = np.zeros(256, dtype=np.uint8)
if rate_info['ci'] > MODE_8PSK: if rate_info['ci'] > MODE_8PSK:
self._data_scramble = np.ones(256, dtype=np.complex64) self._data_scramble_xor = iscr
else: else:
constell = self._constellations[rate_info['ci']] self._data_scramble = common.n_psk(8, iscr)
self._data_scramble = constell[iscr]['points']
success = True ## TODO
return success return success
def make_reinserted_preamble(self, offset, success): def make_reinserted_preamble(self, offset, success):
""" offset= 0 -> 1st reinserted preamble """ offset= 0 -> 1st reinsesrted preamble
offset=-72 -> all following reinserted preambles""" offset=-72 -> all following reinserted preambles"""
a=np.array(zip(REINSERTED_PREAMBLE[offset:], a = common.make_scr(REINSERTED_PREAMBLE[offset:], REINSERTED_PREAMBLE[offset:])
REINSERTED_PREAMBLE[offset:]),
common.SYMB_SCRAMBLE_DTYPE)
a['symb'][-71:-71+3*13] = 0 ## D0,D1,D2 a['symb'][-71:-71+3*13] = 0 ## D0,D1,D2
print('make_reinserted_preamble', offset, success, len(a['symb']), a['symb'], a['scramble']) print('make_reinserted_preamble', offset, success, len(a['symb']))
if not success: if not success:
self._frame_counter = -1 self._frame_counter = -2
return a return a
def make_data_frame(self, success): def make_data_frame(self, success):
self._preamble_offset = -72 ## all following reinserted preambles start at index -72 self._preamble_offset = -72 ## all following reinserted preambles start at index -72
a = np.zeros(256+31, common.SYMB_SCRAMBLE_DTYPE) a = np.zeros(256+31, common.SYMB_SCRAMBLE_DTYPE)
a['scramble'][:256] = self._data_scramble a['scramble'][:256] = self._data_scramble
a['scramble_xor'][:256] = self._data_scramble_xor
n = (self._frame_counter-1)%72 n = (self._frame_counter-1)%72
if self._frame_counter == 72: if self._frame_counter == 72:
self._frame_counter = -1 self._frame_counter = -1
@ -267,18 +356,25 @@ class PhysicalLayer(object):
a['symb'][256:] = MINI_PROBE[self._mp[m]] a['symb'][256:] = MINI_PROBE[self._mp[m]]
a['scramble'][256:] = MINI_PROBE[self._mp[m]] a['scramble'][256:] = MINI_PROBE[self._mp[m]]
if not success: if not success:
self._frame_counter = -1 self._frame_counter = -2
return a return a
def decode_soft_dec(self, soft_dec): def decode_soft_dec(self, soft_dec):
return soft_dec r = self._deintl_depunct.load(soft_dec)
if r.shape[0] == 0:
return []
self._viterbi_decoder.reset()
decoded_bits = self._viterbi_decoder.udpate(r)
print('bits=', decoded_bits[:100])
print('quality={}% ({},{})'.format(120.0*self._viterbi_decoder.quality()/(2*len(decoded_bits)),
self._viterbi_decoder.quality(),
len(decoded_bits)))
return decoded_bits
@staticmethod @staticmethod
def get_preamble(): def get_preamble():
"""preamble symbols + scrambler""" """preamble symbols + scrambler"""
return np.array(zip(PREAMBLE, return common.make_scr(PREAMBLE, PREAMBLE)
PREAMBLE),
common.SYMB_SCRAMBLE_DTYPE)
def get_preamble_z(self): def get_preamble_z(self):
"""preamble symbols for preamble correlation""" """preamble symbols for preamble correlation"""

View file

@ -772,9 +772,14 @@ class PhysicalLayer(object):
else: else:
self._state = 'MP' self._state = 'MP'
a = np.zeros(self._unknown, common.SYMB_SCRAMBLE_DTYPE) a = np.zeros(self._unknown, common.SYMB_SCRAMBLE_DTYPE)
a['scramble'][:] = 1
self._scr_data.reset() self._scr_data.reset()
for i in range(self._unknown): ## TODO: handle QAM modes if self._wid_mode <= MODE_8PSK: ## not QAM
a['scramble'][i] = np.exp(2j*np.pi*self._scr_data.next()/8) for i in range(self._unknown):
a['scramble'][i] = np.exp(2j*np.pi*self._scr_data.next()/8)
else: ## QAM modes
for i in range(self._unknown):
a['scramble_xor'][i] = self._scr_data.next()
return self._data_mode,a return self._data_mode,a
def get_doppler(self, iq_samples): def get_doppler(self, iq_samples):
@ -869,16 +874,12 @@ class PhysicalLayer(object):
CNT_SCR = common.n_psk(8, np.concatenate([CNT_PN for _ in range(4)]))[:len(CNT_SYMB)] CNT_SCR = common.n_psk(8, np.concatenate([CNT_PN for _ in range(4)]))[:len(CNT_SYMB)]
WID_SCR = common.n_psk(8, np.concatenate([WID_PN for _ in range(5)]))[:len(WID_SYMB)] WID_SCR = common.n_psk(8, np.concatenate([WID_PN for _ in range(5)]))[:len(WID_SYMB)]
self._fixed_s = np.array(zip(SYNC_SCR*SYNC_SYMB, self._fixed_s = common.make_scr(SYNC_SCR*SYNC_SYMB,
SYNC_SCR), SYNC_SCR)
common.SYMB_SCRAMBLE_DTYPE) self._cnt_s = common.make_scr(CNT_SCR*CNT_SYMB,
self._cnt_s = np.array(zip(CNT_SCR*CNT_SYMB, CNT_SCR)
CNT_SCR), self._wid_s = common.make_scr(WID_SCR*WID_SYMB,
common.SYMB_SCRAMBLE_DTYPE) WID_SCR)
self._wid_s = np.array(zip(WID_SCR*WID_SYMB,
WID_SCR),
common.SYMB_SCRAMBLE_DTYPE)
def decode_soft_dec(self, soft_dec): def decode_soft_dec(self, soft_dec):
print('decode_soft_dec', len(soft_dec), soft_dec.dtype) print('decode_soft_dec', len(soft_dec), soft_dec.dtype)

View file

@ -6,7 +6,19 @@ CONST_DTYPE=np.dtype([('points', np.complex64),
('symbols', np.int32)]) ('symbols', np.int32)])
SYMB_SCRAMBLE_DTYPE=np.dtype([('symb', np.complex64), SYMB_SCRAMBLE_DTYPE=np.dtype([('symb', np.complex64),
('scramble', np.complex64)]) ('scramble', np.complex64),
('scramble_xor', np.uint8)])
def make_scr(s1, s2=None, s3=None):
a = np.zeros(len(s1), SYMB_SCRAMBLE_DTYPE)
a['symb'][:] = s1
if s2 is not None:
assert(len(s2) == len(s1))
a['scramble'][:] = s2
if s3 is not None:
assert(len(s3) == len(s1))
a['scramble_xor'][:] = s3
return a
def n_psk(n,x): def n_psk(n,x):
"""n-ary PSK constellation""" """n-ary PSK constellation"""

View file

@ -60,7 +60,7 @@ class physical_layer_driver(gr.hier_block2):
self._corr_est = digital.corr_est_cc(symbols = (preamble_samples.tolist()), self._corr_est = digital.corr_est_cc(symbols = (preamble_samples.tolist()),
sps = sps, sps = sps,
mark_delay = preamble_offset, mark_delay = preamble_offset,
threshold = 0.5, threshold = 0.3,
threshold_method = 1) threshold_method = 1)
self._doppler_correction = digitalhf.doppler_correction_cc(preamble_length, len(preamble_samples)) self._doppler_correction = digitalhf.doppler_correction_cc(preamble_length, len(preamble_samples))
self._adaptive_filter = digitalhf.adaptive_dfe(sps, nB, nF, nW, mu, alpha) self._adaptive_filter = digitalhf.adaptive_dfe(sps, nB, nF, nW, mu, alpha)