From cec02bb851b9cc5e7fda31fe61c4bf81f98d4b8a Mon Sep 17 00:00:00 2001 From: Ahmet Inan Date: Tue, 29 Jul 2025 12:25:45 +0200 Subject: [PATCH] merge head and tail to side (information) --- common.hh | 18 +++++++--------- decode.cc | 62 +++++++++++++++++++------------------------------------ encode.cc | 20 +++++++----------- 3 files changed, 35 insertions(+), 65 deletions(-) diff --git a/common.hh b/common.hh index 73eefd3..d1f55a4 100644 --- a/common.hh +++ b/common.hh @@ -22,21 +22,18 @@ struct Common static const int mls1_poly = 0x43; static const int mls2_poly = 0x163; static const int data_tones = 256; - static const int head_tones = 32; - static const int tail_tones = 32; - static const int tone_count = data_tones + head_tones + tail_tones; - static const int block_length = 10; + static const int side_tones = 64; + static const int tone_count = data_tones + side_tones; + static const int block_length = 5; static const int block_skew = 3; - static const int first_head = 4; - static const int first_tail = 9; + static const int first_side = 4; static constexpr int slm_poly[16] = { 0x11d, 0x12b, 0x12d, 0x14d, 0x15f, 0x163, 0x165, 0x169, 0x171, 0x187, 0x18d, 0x1a9, 0x1c3, 0x1cf, 0x1e7, 0x1f5 }; CODE::CRC crc0; CODE::CRC crc1; - CODE::HadamardEncoder<6> hadamard_encoder; - int8_t head[32]; - int8_t tail[32]; + CODE::HadamardEncoder<7> hadamard_encoder; + int8_t side[64]; uint8_t data[data_max]; const uint32_t *frozen_bits; int mod_bits; @@ -45,8 +42,7 @@ struct Common int code_order; int oper_mode; int tone_off; - int head_off; - int tail_off; + int side_off; int symbol_count; Common() : crc0(0xA8F4), crc1(0x8F6E37A0) {} diff --git a/decode.cc b/decode.cc index c0c1a88..2d80d69 100644 --- a/decode.cc +++ b/decode.cc @@ -51,7 +51,7 @@ struct Decoder : Common DSP::BipBuffer input_hist; DSP::TheilSenEstimator tse; SchmidlCox correlator; - CODE::HadamardDecoder<6> hadamard_decoder; + CODE::HadamardDecoder<7> hadamard_decoder; CODE::PolarListDecoder polar_decoder; mesg_type mesg[bits_max]; code_type code[bits_max], perm[bits_max]; @@ -283,8 +283,7 @@ struct Decoder : Common oper_mode = -1; symbol_count = 0; for (int j = 0, k = 0; j < symbol_count + 1; ++j) { - head_off = (block_skew * j + first_head) % block_length; - tail_off = (block_skew * j + first_tail) % block_length; + side_off = (block_skew * j + first_side) % block_length; if (j) { for (int i = 0; i < extended_len; ++i) correlator(buf = next_sample()); @@ -297,45 +296,28 @@ struct Decoder : Common for (int i = 0; i < tone_count; ++i) tone[i] = fdom[bin(i+tone_off)]; for (int i = 0; i < tone_count; ++i) - if (i % block_length == head_off || i % block_length == tail_off) + if (i % block_length == side_off) tone[i] *= nrz(seq1()); for (int i = 0; i < tone_count; ++i) demod[i] = demod_or_erase(tone[i], chan[i]); - for (int i = 0; i < head_tones; ++i) - head[i] = clamp(std::nearbyint(127 * demod[i*block_length+head_off].real())); - int head_data = hadamard_decoder(head); - if (head_data < 0) { - std::cerr << "head data damaged" << std::endl; + for (int i = 0; i < side_tones; ++i) + side[i] = clamp(std::nearbyint(127 * demod[i*block_length+side_off].real())); + int side_data = hadamard_decoder(side); + if (side_data < 0) { + std::cerr << "side data damaged" << std::endl; oper_mode = -1; break; } - hadamard_encoder(head, head_data); - for (int i = 0; i < head_tones; ++i) { - tone[block_length*i+head_off] *= head[i]; - demod[block_length*i+head_off] *= head[i]; + hadamard_encoder(side, side_data); + for (int i = 0; i < side_tones; ++i) { + tone[block_length*i+side_off] *= side[i]; + demod[block_length*i+side_off] *= side[i]; } - for (int i = 0; i < head_tones; ++i) { - index[i] = tone_off + block_length * i + head_off; - phase[i] = arg(demod[block_length*i+head_off]); + for (int i = 0; i < side_tones; ++i) { + index[i] = tone_off + block_length * i + side_off; + phase[i] = arg(demod[block_length*i+side_off]); } - for (int i = 0; i < tail_tones; ++i) - tail[i] = clamp(std::nearbyint(127 * demod[i*block_length+tail_off].real())); - int tail_data = hadamard_decoder(tail); - if (tail_data < 0) { - std::cerr << "tail data damaged" << std::endl; - oper_mode = -1; - break; - } - hadamard_encoder(tail, tail_data); - for (int i = 0; i < tail_tones; ++i) { - tone[block_length*i+tail_off] *= tail[i]; - demod[block_length*i+tail_off] *= tail[i]; - } - for (int i = 0; i < tail_tones; ++i) { - index[i+head_tones] = tone_off + block_length * i + tail_off; - phase[i+head_tones] = arg(demod[block_length*i+tail_off]); - } - tse.compute(index, phase, head_tones + tail_tones); + tse.compute(index, phase, side_tones); //std::cerr << "Theil-Sen slope = " << tse.slope() << std::endl; //std::cerr << "Theil-Sen yint = " << tse.yint() << std::endl; for (int i = 0; i < tone_count; ++i) @@ -343,7 +325,7 @@ struct Decoder : Common for (int i = 0; i < tone_count; ++i) chan[i] *= DSP::polar(1, tse(i+tone_off)); CODE::XorShiftMask combination; - int trial = (head_data << 6) | tail_data; + int trial = side_data; int comb = 0; for (int i = 0; i <= trial; ++i) comb = combination(); @@ -353,12 +335,12 @@ struct Decoder : Common std::cerr << "reserved seed value detected" << std::endl; CODE::MLS seq(slm_poly[poly_index], seed_value); for (int i = 0; i < tone_count; ++i) - if (i % block_length != head_off && i % block_length != tail_off) + if (i % block_length != side_off) demod[i] *= nrz(seq()); value sp = 0, np = 0; for (int i = 0, l = k; i < tone_count; ++i) { cmplx hard(1, 0); - if (i % block_length != head_off && i % block_length != tail_off) { + if (i % block_length != side_off) { int bits = mod_bits; if (mod_bits == 3 && l % 32 == 30) bits = 2; @@ -380,7 +362,7 @@ struct Decoder : Common snr[j] = precision; precision = std::min(precision, value(1023)); for (int i = 0; i < tone_count; ++i) { - if (i % block_length != head_off && i % block_length != tail_off) { + if (i % block_length != side_off) { int bits = mod_bits; if (mod_bits == 3 && k % 32 == 30) bits = 2; @@ -417,9 +399,7 @@ struct Decoder : Common correlator(buf = next_sample()); std::cerr << "oper mode: " << oper_mode << std::endl; } - for (int i = head_off; i < tone_count; i += block_length) - chan[i] = DSP::lerp(chan[i], tone[i], value(0.5)); - for (int i = tail_off; i < tone_count; i += block_length) + for (int i = side_off; i < tone_count; i += block_length) chan[i] = DSP::lerp(chan[i], tone[i], value(0.5)); } if (oper_mode < 0) diff --git a/encode.cc b/encode.cc index a4a1a97..38338a3 100644 --- a/encode.cc +++ b/encode.cc @@ -80,25 +80,20 @@ struct Encoder : public Common value scale = value(0.5) / std::sqrt(value(tone_count)); value best_papr = 1000; CODE::XorShiftMask combination; - for (int trial = 0; trial < 4096; ++trial) { + for (int trial = 0; trial < 128; ++trial) { for (int i = 0; i < tone_count; ++i) temp[i] = tone[i]; if (symbol_number >= 0) { + hadamard_encoder(side, trial); int comb = combination(); - int head_data = trial >> 6; - hadamard_encoder(head, head_data); - int tail_data = trial & 63; - hadamard_encoder(tail, tail_data); int poly_index = comb & 15; int seed_value = comb >> 4; if (seed_value == 0) continue; CODE::MLS seq(slm_poly[poly_index], seed_value); - for (int i = 0, m = 0, s = 0; i < tone_count; ++i) - if (i % block_length == head_off) - temp[i] *= head[m++]; - else if (i % block_length == tail_off) - temp[i] *= tail[s++]; + for (int i = 0, s = 0; i < tone_count; ++i) + if (i % block_length == side_off) + temp[i] *= side[s++]; else temp[i] *= nrz(seq()); } @@ -307,10 +302,9 @@ struct Encoder : public Common shuffle(perm, code, code_order); CODE::MLS seq1(mls1_poly); for (int j = 0, k = 0, m = 0; j < symbol_count + 1; ++j) { - head_off = (block_skew * j + first_head) % block_length; - tail_off = (block_skew * j + first_tail) % block_length; + side_off = (block_skew * j + first_side) % block_length; for (int i = 0; i < tone_count; ++i) { - if (i % block_length == head_off || i % block_length == tail_off) { + if (i % block_length == side_off) { tone[i] = nrz(seq1()); } else if (j) { int bits = mod_bits;