mirror of
https://github.com/hb9fxq/gr-digitalhf
synced 2024-12-21 23:09:59 +00:00
preparations for XOR scrambling
work on 110C mode (intermediate)
This commit is contained in:
parent
be31566ff1
commit
6cf9752275
|
@ -164,7 +164,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<key>value</key>
|
||||
<value>'600/L'</value>
|
||||
<value>'1200/L'</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_enabled</key>
|
||||
|
@ -240,7 +240,7 @@
|
|||
</param>
|
||||
<param>
|
||||
<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>
|
||||
<key>orient</key>
|
||||
|
@ -877,11 +877,11 @@
|
|||
</param>
|
||||
<param>
|
||||
<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>
|
||||
<key>_coordinate</key>
|
||||
<value>(10, 154)</value>
|
||||
<value>(21, 154)</value>
|
||||
</param>
|
||||
<param>
|
||||
<key>_rotation</key>
|
||||
|
|
|
@ -83,6 +83,7 @@ adaptive_dfe_impl::adaptive_dfe_impl(int sps, // samples per symbol
|
|||
, _constellation_index()
|
||||
, _symbols()
|
||||
, _scramble()
|
||||
, _scramble_xor()
|
||||
, _descrambled_symbols()
|
||||
, _symbol_counter(0)
|
||||
, _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);
|
||||
std::vector<float> const soft_dec = constell->calc_soft_dec
|
||||
(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;
|
||||
}
|
||||
|
@ -289,6 +295,8 @@ gr_complex adaptive_dfe_impl::filter(gr_complex const* start, gr_complex const*
|
|||
if (is_known || update_taps) {
|
||||
// (3a) update of adaptive filter taps
|
||||
gr_complex const err = filter_output - known_symbol;
|
||||
if (std::abs(err)>0.5)
|
||||
std::cout << "err= " << std::abs(err) << std::endl;
|
||||
// taps_samples
|
||||
for (int j=0; j<_nB+_nF+1; ++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)
|
||||
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)
|
||||
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.phase_wrap();
|
||||
_control_loop.frequency_limit();
|
||||
|
@ -390,8 +398,7 @@ void adaptive_dfe_impl::update_constellations(pmt::pmt_t data) {
|
|||
int const n = pmt::length(data);
|
||||
_constellations.resize(n);
|
||||
_npwr.resize(n);
|
||||
std::cout << "adaptive_dfe_impl::update_constellations " << data << std::endl;
|
||||
std::cout << "adaptive_dfe_impl::update_constellations n=" << n << std::endl;
|
||||
GR_LOG_DEBUG(d_logger, str(boost::format("update_constellations %s n=%d") % data % n));
|
||||
unsigned int const rotational_symmetry = 0;
|
||||
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));
|
||||
_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));
|
||||
|
||||
// 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());
|
||||
_descrambled_symbols.resize(_symbols.size());
|
||||
_vec_soft_decisions.clear();
|
||||
|
|
|
@ -80,9 +80,10 @@ private:
|
|||
std::vector<constellation_distance_filter> _npwr;
|
||||
int _npwr_max_time_constant;
|
||||
int _constellation_index;
|
||||
std::vector<gr_complex> _symbols;
|
||||
std::vector<gr_complex> _scramble;
|
||||
std::vector<gr_complex> _descrambled_symbols;
|
||||
std::vector<gr_complex> _symbols;
|
||||
std::vector<gr_complex> _scramble; // PSK-8 scramble symbols
|
||||
std::vector<std::array<int,8> > _scramble_xor; // signs for XOR scrambling
|
||||
std::vector<gr_complex> _descrambled_symbols;
|
||||
int _symbol_counter;
|
||||
|
||||
bool _save_soft_decisions;
|
||||
|
|
|
@ -74,6 +74,7 @@ class msg_proxy(gr.basic_block):
|
|||
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('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('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)))
|
||||
|
|
|
@ -199,9 +199,7 @@ class PhysicalLayer(object):
|
|||
self._frame_counter = 0
|
||||
scramble_for_frame = common.n_psk(8, np.array([self._scr_data.next()
|
||||
for _ in range(self._frame_len)]))
|
||||
a = np.array(zip(scramble_for_frame,
|
||||
scramble_for_frame),
|
||||
common.SYMB_SCRAMBLE_DTYPE)
|
||||
a = common.make_scr(scramble_for_frame, scramble_for_frame)
|
||||
n_unknown = self._mode['unknown']
|
||||
a['symb'][0:n_unknown] = 0
|
||||
if self._mode['known'] != 0 and self._frame_counter >= self._num_frames_per_block-2:
|
||||
|
@ -296,10 +294,8 @@ class PhysicalLayer(object):
|
|||
@staticmethod
|
||||
def get_preamble():
|
||||
"""preamble symbols + scrambler"""
|
||||
return np.array(zip(PRE_SCRAMBLE*PRE_SYMBOLS,
|
||||
PRE_SCRAMBLE),
|
||||
common.SYMB_SCRAMBLE_DTYPE)
|
||||
|
||||
return common.make_scr(PRE_SCRAMBLE*PRE_SYMBOLS,
|
||||
PRE_SCRAMBLE)
|
||||
def get_preamble_z(self):
|
||||
"""preamble symbols for preamble correlation"""
|
||||
a = PhysicalLayer.get_preamble()
|
||||
|
|
|
@ -3,11 +3,12 @@
|
|||
from __future__ import print_function
|
||||
import numpy as np
|
||||
import common
|
||||
from digitalhf.digitalhf_swig import viterbi27
|
||||
|
||||
## ---- constellations -----------------------------------------------------------
|
||||
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)
|
||||
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(
|
||||
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,
|
||||
|
@ -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)]
|
||||
|
||||
## ---- rate -------------------------------------------------------------------
|
||||
TO_RATE={(0,0,0): {'baud': 0, 'bits_per_symbol': 0}, ## reserved
|
||||
(0,0,1): {'baud': 3200, 'bits_per_symbol': 2, 'ci': MODE_QPSK},
|
||||
(0,1,0): {'baud': 4800, 'bits_per_symbol': 3, 'ci': MODE_8PSK},
|
||||
(0,1,1): {'baud': 6400, 'bits_per_symbol': 4, 'ci': MODE_16QAM},
|
||||
(1,0,0): {'baud': 8000, 'bits_per_symbol': 5, 'ci': MODE_32QAM},
|
||||
(1,0,1): {'baud': 9600, 'bits_per_symbol': 6, 'ci': MODE_64QAM},
|
||||
(1,1,0): {'baud':12800, 'bits_per_symbol': 6, 'ci': MODE_64QAM},
|
||||
(1,1,1): {'baud': 0, 'bits_per_symbol': 0}} ## reserved
|
||||
TO_RATE={(0,0,0): {'baud': '--------', 'bits_per_symbol': 0}, ## reserved
|
||||
(0,0,1): {'baud': '3200 bps', 'bits_per_symbol': 2, 'ci': MODE_QPSK},
|
||||
(0,1,0): {'baud': '4800 bps', 'bits_per_symbol': 3, 'ci': MODE_8PSK},
|
||||
(0,1,1): {'baud': '6400 bps', 'bits_per_symbol': 4, 'ci': MODE_16QAM},
|
||||
(1,0,0): {'baud': '8000 bps', 'bits_per_symbol': 5, 'ci': MODE_32QAM},
|
||||
(1,0,1): {'baud': '9600 bps', 'bits_per_symbol': 6, 'ci': MODE_64QAM},
|
||||
(1,1,0): {'baud':'12800 bps', 'bits_per_symbol': 6, 'ci': MODE_64QAM},
|
||||
(1,1,1): {'baud': '--------', 'bits_per_symbol': 0}} ## reserved
|
||||
|
||||
## ---- interleaver ------------------------------------------------------------
|
||||
TO_INTERLEAVER={(0,0,0): {'frames': -1, 'name': 'illegal'},
|
||||
(0,0,1): {'frames': 1, 'name': 'Ultra Short (US)'},
|
||||
(0,1,0): {'frames': 3, 'name': 'Very Short (VS)'},
|
||||
(0,1,1): {'frames': 9, 'name': 'Short (S)'},
|
||||
(1,0,0): {'frames': 18, 'name': 'Medium (M)'},
|
||||
(1,0,1): {'frames': 36, 'name': 'Long (L)'},
|
||||
(1,1,0): {'frames': 72, 'name': 'very Long (VL)'},
|
||||
(1,1,1): {'frames': -1, 'name': 'illegal'}}
|
||||
TO_INTERLEAVER={(0,0,0): {'frames': -1, 'id': '--', 'name': 'illegal'},
|
||||
(0,0,1): {'frames': 1, 'id': 'US', 'name': 'Ultra Short'},
|
||||
(0,1,0): {'frames': 3, 'id': 'VS', 'name': 'Very Short'},
|
||||
(0,1,1): {'frames': 9, 'id': 'S', 'name': 'Short'},
|
||||
(1,0,0): {'frames': 18, 'id': 'M', 'name': 'Medium'},
|
||||
(1,0,1): {'frames': 36, 'id': 'L', 'name': 'Long'},
|
||||
(1,1,0): {'frames': 72, 'id': 'VL', 'name': 'Very Long'},
|
||||
(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 -----------------------------------------------------
|
||||
class PhysicalLayer(object):
|
||||
|
@ -138,7 +203,8 @@ class PhysicalLayer(object):
|
|||
self._frame_counter = -2
|
||||
self._constellations = [BPSK, QPSK, PSK8, QAM16, QAM32, QAM64]
|
||||
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):
|
||||
return self._constellations
|
||||
|
@ -153,6 +219,8 @@ class PhysicalLayer(object):
|
|||
print('-------------------- get_frame --------------------', self._frame_counter)
|
||||
success = True
|
||||
if self._frame_counter == -2: ## ---- preamble
|
||||
self._deintl_depunct = None
|
||||
self._mode = {}
|
||||
self._preamble_offset = 0
|
||||
self._frame_counter += 1
|
||||
return [self._preamble,MODE_BPSK,success,False]
|
||||
|
@ -215,46 +283,67 @@ class PhysicalLayer(object):
|
|||
|
||||
def decode_reinserted_preamble(self, symbols):
|
||||
## decode D0,D1,D2
|
||||
success = True
|
||||
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))
|
||||
dibits = [TO_DIBIT[idx] for idx in d0d1d2]
|
||||
self._mode = {'rate': tuple([x[0] for x in dibits]),
|
||||
'interleaver': tuple([x[1] for x in dibits])}
|
||||
print('======== rate,interleaver:',
|
||||
TO_RATE[self._mode['rate']],
|
||||
TO_INTERLEAVER[self._mode['interleaver']])
|
||||
self._interleaver_length = TO_INTERLEAVER[self._mode['interleaver']]['frames']
|
||||
rate_info = TO_RATE[self._mode['rate']]
|
||||
print('rate_info', rate_info)
|
||||
mode = {'rate': tuple([x[0] for x in dibits]),
|
||||
'interleaver': tuple([x[1] for x in dibits])}
|
||||
if self._mode != {}:
|
||||
success = (mode == self._mode)
|
||||
if not success:
|
||||
return success
|
||||
self._mode = mode
|
||||
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']
|
||||
print('constellation index', self._constellation_index)
|
||||
scr = ScrambleData()
|
||||
iscr = [scr.next(rate_info['bits_per_symbol']) for _ in range(256)]
|
||||
self._scramble.reset()
|
||||
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:
|
||||
self._data_scramble = np.ones(256, dtype=np.complex64)
|
||||
self._data_scramble_xor = iscr
|
||||
else:
|
||||
constell = self._constellations[rate_info['ci']]
|
||||
self._data_scramble = constell[iscr]['points']
|
||||
success = True ## TODO
|
||||
self._data_scramble = common.n_psk(8, iscr)
|
||||
return success
|
||||
|
||||
def make_reinserted_preamble(self, offset, success):
|
||||
""" offset= 0 -> 1st reinserted preamble
|
||||
""" offset= 0 -> 1st reinsesrted preamble
|
||||
offset=-72 -> all following reinserted preambles"""
|
||||
a=np.array(zip(REINSERTED_PREAMBLE[offset:],
|
||||
REINSERTED_PREAMBLE[offset:]),
|
||||
common.SYMB_SCRAMBLE_DTYPE)
|
||||
a = common.make_scr(REINSERTED_PREAMBLE[offset:], REINSERTED_PREAMBLE[offset:])
|
||||
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:
|
||||
self._frame_counter = -1
|
||||
self._frame_counter = -2
|
||||
return a
|
||||
|
||||
def make_data_frame(self, success):
|
||||
self._preamble_offset = -72 ## all following reinserted preambles start at index -72
|
||||
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
|
||||
if self._frame_counter == 72:
|
||||
self._frame_counter = -1
|
||||
|
@ -267,18 +356,25 @@ class PhysicalLayer(object):
|
|||
a['symb'][256:] = MINI_PROBE[self._mp[m]]
|
||||
a['scramble'][256:] = MINI_PROBE[self._mp[m]]
|
||||
if not success:
|
||||
self._frame_counter = -1
|
||||
self._frame_counter = -2
|
||||
return a
|
||||
|
||||
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
|
||||
def get_preamble():
|
||||
"""preamble symbols + scrambler"""
|
||||
return np.array(zip(PREAMBLE,
|
||||
PREAMBLE),
|
||||
common.SYMB_SCRAMBLE_DTYPE)
|
||||
return common.make_scr(PREAMBLE, PREAMBLE)
|
||||
|
||||
def get_preamble_z(self):
|
||||
"""preamble symbols for preamble correlation"""
|
||||
|
|
|
@ -772,9 +772,14 @@ class PhysicalLayer(object):
|
|||
else:
|
||||
self._state = 'MP'
|
||||
a = np.zeros(self._unknown, common.SYMB_SCRAMBLE_DTYPE)
|
||||
a['scramble'][:] = 1
|
||||
self._scr_data.reset()
|
||||
for i in range(self._unknown): ## TODO: handle QAM modes
|
||||
a['scramble'][i] = np.exp(2j*np.pi*self._scr_data.next()/8)
|
||||
if self._wid_mode <= MODE_8PSK: ## not QAM
|
||||
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
|
||||
|
||||
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)]
|
||||
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,
|
||||
SYNC_SCR),
|
||||
common.SYMB_SCRAMBLE_DTYPE)
|
||||
self._cnt_s = np.array(zip(CNT_SCR*CNT_SYMB,
|
||||
CNT_SCR),
|
||||
common.SYMB_SCRAMBLE_DTYPE)
|
||||
self._wid_s = np.array(zip(WID_SCR*WID_SYMB,
|
||||
WID_SCR),
|
||||
common.SYMB_SCRAMBLE_DTYPE)
|
||||
|
||||
self._fixed_s = common.make_scr(SYNC_SCR*SYNC_SYMB,
|
||||
SYNC_SCR)
|
||||
self._cnt_s = common.make_scr(CNT_SCR*CNT_SYMB,
|
||||
CNT_SCR)
|
||||
self._wid_s = common.make_scr(WID_SCR*WID_SYMB,
|
||||
WID_SCR)
|
||||
|
||||
def decode_soft_dec(self, soft_dec):
|
||||
print('decode_soft_dec', len(soft_dec), soft_dec.dtype)
|
||||
|
|
|
@ -6,7 +6,19 @@ CONST_DTYPE=np.dtype([('points', np.complex64),
|
|||
('symbols', np.int32)])
|
||||
|
||||
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):
|
||||
"""n-ary PSK constellation"""
|
||||
|
|
|
@ -60,7 +60,7 @@ class physical_layer_driver(gr.hier_block2):
|
|||
self._corr_est = digital.corr_est_cc(symbols = (preamble_samples.tolist()),
|
||||
sps = sps,
|
||||
mark_delay = preamble_offset,
|
||||
threshold = 0.5,
|
||||
threshold = 0.3,
|
||||
threshold_method = 1)
|
||||
self._doppler_correction = digitalhf.doppler_correction_cc(preamble_length, len(preamble_samples))
|
||||
self._adaptive_filter = digitalhf.adaptive_dfe(sps, nB, nF, nW, mu, alpha)
|
||||
|
|
Loading…
Reference in a new issue