From 2c05efe8cd745ce9bd8713f0fd6d0e7d6b0bfbfe Mon Sep 17 00:00:00 2001 From: Ahmet Inan Date: Thu, 7 Aug 2025 00:14:22 +0200 Subject: [PATCH] preparing to play with partial transmit sequence --- common.hh | 11 ++++----- decode.cc | 45 +++++++++++++++---------------------- encode.cc | 67 +++++++++++++++++++++++++------------------------------ 3 files changed, 53 insertions(+), 70 deletions(-) diff --git a/common.hh b/common.hh index da36a1d..16cc2cd 100644 --- a/common.hh +++ b/common.hh @@ -8,7 +8,6 @@ Copyright 2025 Ahmet Inan #include "crc.hh" #include "polar_tables.hh" -#include "hadamard_encoder.hh" struct Common { @@ -22,15 +21,13 @@ struct Common static const int mls1_poly = 0x43; static const int mls2_poly = 0x163; static const int data_tones = 256; - static const int seed_tones = 64; - static const int tone_count = data_tones + seed_tones; + static const int pilot_tones = 64; + static const int tone_count = data_tones + pilot_tones; static const int block_length = 5; static const int block_skew = 3; - static const int first_seed = 4; + static const int first_pilot = 4; CODE::CRC crc0; CODE::CRC crc1; - CODE::HadamardEncoder<7> hadamard_encoder; - int8_t seed[seed_tones]; uint8_t data[data_max]; const uint32_t *frozen_bits; int mod_bits; @@ -39,7 +36,7 @@ struct Common int code_order; int oper_mode; int tone_off; - int seed_off; + int pilot_off; int symbol_count; Common() : crc0(0xA8F4), crc1(0x8F6E37A0) {} diff --git a/decode.cc b/decode.cc index fd31b76..339d878 100644 --- a/decode.cc +++ b/decode.cc @@ -29,7 +29,6 @@ namespace DSP { using std::abs; using std::min; using std::cos; using std::sin; #include "psk.hh" #include "qam.hh" #include "polar_list_decoder.hh" -#include "hadamard_decoder.hh" template struct Decoder : Common @@ -51,7 +50,6 @@ struct Decoder : Common DSP::BipBuffer input_hist; DSP::TheilSenEstimator tse; SchmidlCox correlator; - CODE::HadamardDecoder<7> hadamard_decoder; CODE::PolarListDecoder polar_decoder; mesg_type mesg[bits_max]; code_type code[bits_max], perm[bits_max]; @@ -278,12 +276,11 @@ struct Decoder : Common osc(); fwd(fdom, tdom); CODE::MLS seq1(mls1_poly); - auto clamp = [](int v){ return v < -127 ? -127 : v > 127 ? 127 : v; }; mod_bits = 1; oper_mode = -1; symbol_count = 0; for (int j = 0, k = 0; j < symbol_count + 1; ++j) { - seed_off = (block_skew * j + first_seed) % block_length; + pilot_off = (block_skew * j + first_pilot) % block_length; if (j) { for (int i = 0; i < extended_len; ++i) correlator(buf = next_sample()); @@ -295,44 +292,38 @@ struct Decoder : Common } for (int i = 0; i < tone_count; ++i) tone[i] = fdom[bin(i+tone_off)]; - for (int i = seed_off; i < tone_count; i += block_length) + for (int i = pilot_off; i < tone_count; i += block_length) 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 < seed_tones; ++i) - seed[i] = clamp(std::nearbyint(127 * demod[i*block_length+seed_off].real())); - int seed_value = hadamard_decoder(seed); - if (seed_value < 0) { - std::cerr << "seed value damaged" << std::endl; + value pilot_sum = 0; + for (int i = 0; i < pilot_tones; ++i) + pilot_sum += demod[i*block_length+pilot_off].real(); + int pilot_phase = DSP::signum(pilot_sum); + if (std::abs(pilot_sum) < pilot_tones / 4) { + std::cerr << "pilot phase damaged" << std::endl; oper_mode = -1; break; } - hadamard_encoder(seed, seed_value); - for (int i = 0; i < seed_tones; ++i) { - tone[block_length*i+seed_off] *= seed[i]; - demod[block_length*i+seed_off] *= seed[i]; + for (int i = 0; i < tone_count; ++i) { + tone[i] *= pilot_phase; + demod[i] *= pilot_phase; } - for (int i = 0; i < seed_tones; ++i) { - index[i] = tone_off + block_length * i + seed_off; - phase[i] = arg(demod[block_length*i+seed_off]); + for (int i = 0; i < pilot_tones; ++i) { + index[i] = tone_off + block_length * i + pilot_off; + phase[i] = arg(demod[block_length*i+pilot_off]); } - tse.compute(index, phase, seed_tones); + tse.compute(index, phase, pilot_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) demod[i] *= DSP::polar(1, -tse(i+tone_off)); for (int i = 0; i < tone_count; ++i) chan[i] *= DSP::polar(1, tse(i+tone_off)); - if (seed_value) { - CODE::MLS seq(mls2_poly, seed_value); - for (int i = 0; i < tone_count; ++i) - if (i % block_length != seed_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 != seed_off) { + if (i % block_length != pilot_off) { int bits = mod_bits; if (mod_bits == 3 && l % 32 == 30) bits = 2; @@ -354,7 +345,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 != seed_off) { + if (i % block_length != pilot_off) { int bits = mod_bits; if (mod_bits == 3 && k % 32 == 30) bits = 2; @@ -391,7 +382,7 @@ struct Decoder : Common correlator(buf = next_sample()); std::cerr << "oper mode: " << oper_mode << std::endl; } - for (int i = seed_off; i < tone_count; i += block_length) + for (int i = pilot_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 fc97f63..4834563 100644 --- a/encode.cc +++ b/encode.cc @@ -38,11 +38,11 @@ struct Encoder : public Common code_type code[bits_max], perm[bits_max], mesg[bits_max], meta[data_tones]; cmplx fdom[symbol_len]; cmplx tdom[symbol_len]; + cmplx temp[symbol_len]; cmplx best[symbol_len]; cmplx kern[symbol_len]; cmplx guard[guard_len]; cmplx tone[tone_count]; - cmplx temp[tone_count]; value weight[guard_len]; value papr[symbols_max]; @@ -79,47 +79,42 @@ struct Encoder : public Common void symbol(int symbol_number) { value scale = value(0.5) / std::sqrt(value(tone_count)); - value best_papr = 1000; - for (int seed_value = 0; seed_value < 128; ++seed_value) { - for (int i = 0; i < tone_count; ++i) - temp[i] = tone[i]; - if (symbol_number >= 0) { - hadamard_encoder(seed, seed_value); - for (int i = 0; i < seed_tones; ++i) - temp[i*block_length+seed_off] *= seed[i]; - if (seed_value) { - CODE::MLS seq(mls2_poly, seed_value); - for (int i = 0; i < tone_count; ++i) - if (i % block_length != seed_off) - temp[i] *= nrz(seq()); - } - } + if (symbol_number < 0) { for (int i = 0; i < symbol_len; ++i) fdom[i] = 0; for (int i = 0; i < tone_count; ++i) - fdom[bin(i+tone_off)] = temp[i]; + fdom[bin(i+tone_off)] = tone[i]; bwd(tdom, fdom); for (int i = 0; i < symbol_len; ++i) tdom[i] *= scale; - if (symbol_number < 0) - break; - value peak = 0, mean = 0; - for (int i = 0; i < symbol_len; ++i) { - value power(norm(tdom[i])); - peak = std::max(peak, power); - mean += power; - } - mean /= symbol_len; - value cand_papr(peak / mean); - if (cand_papr < best_papr) { - best_papr = cand_papr; + } else { + for (int i = 0; i < symbol_len; ++i) + fdom[i] = 0; + for (int i = 0; i < tone_count; ++i) + fdom[bin(i+tone_off)] = tone[i]; + bwd(temp, fdom); + for (int i = 0; i < symbol_len; ++i) + temp[i] *= scale; + value best_papr = 1000; + for (value pilot_phase = -1; pilot_phase < 2; pilot_phase += 2) { for (int i = 0; i < symbol_len; ++i) - best[i] = tdom[i]; - if (cand_papr < 5) - break; + tdom[i] = pilot_phase * temp[i]; + value peak = 0, mean = 0; + for (int i = 0; i < symbol_len; ++i) { + value power(norm(tdom[i])); + peak = std::max(peak, power); + mean += power; + } + mean /= symbol_len; + value cand_papr(peak / mean); + if (cand_papr < best_papr) { + best_papr = cand_papr; + for (int i = 0; i < symbol_len; ++i) + best[i] = tdom[i]; + if (cand_papr < 5) + break; + } } - } - if (symbol_number >= 0) { for (int i = 0; i < symbol_len; ++i) tdom[i] = best[i]; papr[symbol_number] = best_papr; @@ -299,9 +294,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) { - seed_off = (block_skew * j + first_seed) % block_length; + pilot_off = (block_skew * j + first_pilot) % block_length; for (int i = 0; i < tone_count; ++i) { - if (i % block_length == seed_off) { + if (i % block_length == pilot_off) { tone[i] = nrz(seq1()); } else if (j) { int bits = mod_bits;