diff --git a/decode.cc b/decode.cc index a3efda3..89dd397 100644 --- a/decode.cc +++ b/decode.cc @@ -188,6 +188,8 @@ struct Decoder static const int search_pos = buffer_len - 4 * (symbol_len + guard_len); DSP::ReadPCM *pcm; DSP::FastFourierTransform fwd; + DSP::FastFourierTransform fwd2; + DSP::FastFourierTransform bwd2; DSP::BlockDC blockdc; DSP::Hilbert hilbert; DSP::BipBuffer input_hist; @@ -203,6 +205,7 @@ struct Decoder code_type code[65536]; cmplx cons[cons_max], prev[cols_max]; cmplx fdom[symbol_len], tdom[symbol_len]; + cmplx head[symbol_len/2], tail[symbol_len/2]; value index[cols_max], phase[cols_max]; value cfo_rad, sfo_rad; const uint32_t *frozen_bits; @@ -241,6 +244,19 @@ struct Decoder fdom[(i+mls0_off/2+symbol_len/2)%(symbol_len/2)] = nrz(seq0()); return fdom; } + int displacement() + { + for (int i = 0; i < symbol_len/2; ++i) + head[i] *= conj(tail[i]); + bwd2(tail, head); + int idx = 0; + for (int i = 0; i < symbol_len/2; ++i) + if (norm(tail[i]) > norm(tail[idx])) + idx = i; + if (idx > symbol_len/4) + idx -= symbol_len/2; + return -idx; + } void lengthen() { int code_bits = 1 << code_order; @@ -463,6 +479,9 @@ struct Decoder int cons_rows = cons_cnt / cons_cols; int code_off = - cons_cols / 2; + // get middle half of S&C symbol for coarse SFO estimation + fwd2(head, buf + symbol_pos + symbol_len / 4); + for (int i = 0; i < symbol_pos+2*(symbol_len+guard_len); ++i) buf = next_sample(); for (int i = 0; i < symbol_len; ++i) @@ -486,6 +505,11 @@ struct Decoder std::cerr << "."; } std::cerr << " done" << std::endl; + + fwd2(tail, buf + symbol_len + guard_len + symbol_len / 4); + value dis_sfo_rad = (displacement() * Const::TwoPi()) / ((cons_rows+2)*(symbol_len+guard_len)); + std::cerr << "dis sfo: " << 1000000 * dis_sfo_rad / Const::TwoPi() << " ppm" << std::endl; + if (1) { value sum_slope = 0, sum_yint = 0; for (int j = 0; j < cons_rows; ++j) { @@ -509,8 +533,8 @@ struct Decoder // cons[i] *= DSP::polar(1, -(avg_yint+avg_slope*((i%cons_cols)+code_off))); sfo_rad -= avg_slope * symbol_len / value(symbol_len+guard_len); cfo_rad += avg_yint / (symbol_len+guard_len); - std::cerr << "coarse sfo: " << 1000000 * sfo_rad / Const::TwoPi() << " ppm" << std::endl; - std::cerr << "finer cfo: " << cfo_rad * (rate / Const::TwoPi()) << " Hz " << std::endl; + std::cerr << "avg sfo: " << 1000000 * sfo_rad / Const::TwoPi() << " ppm" << std::endl; + std::cerr << "avg cfo: " << cfo_rad * (rate / Const::TwoPi()) << " Hz " << std::endl; } value precision = 16; if (1) {