From d0ad1ae4131ee94ba6dd7c0c64c5bfccc6a2b691 Mon Sep 17 00:00:00 2001 From: f4exb Date: Sat, 14 Mar 2026 03:46:48 +0100 Subject: [PATCH] FT8 demod: Sonar fixes (2) --- ft8/ft4.cpp | 20 ++++++++++---------- ft8/ft4.h | 50 +++++++++++++++++++++++++------------------------- ft8/ft8.cpp | 40 ++++++++++++++++++++-------------------- ft8/ft8.h | 40 ++++++++++++++++++++-------------------- 4 files changed, 75 insertions(+), 75 deletions(-) diff --git a/ft8/ft4.cpp b/ft8/ft4.cpp index dc45d8e8b..ec32153f8 100644 --- a/ft8/ft4.cpp +++ b/ft8/ft4.cpp @@ -1071,7 +1071,7 @@ std::vector FT4::fft_shift_f( return out; } -// shift the frequency by a fraction of 20.833, +// shift the frequency by a fraction of 23.4, // to center hz on bin 2 (46.8 hz). std::vector FT4::shift200( const std::vector &samples200, @@ -1532,7 +1532,7 @@ std::vector> FT4::soft_c2m(const FFTEngine::ffts_t &c103) con // // c103 is 103x4 complex tones, before un-gray-coding. // -void FT4::soft_decode(const FFTEngine::ffts_t &c103, float ll174[]) +void FT4::soft_decode(const FFTEngine::ffts_t &c103, float ll174[]) const { std::vector> m103(103); // m103 = absolute values of c103. @@ -1629,7 +1629,7 @@ void FT4::soft_decode(const FFTEngine::ffts_t &c103, float ll174[]) // // c103 is 103x4 complex tones, before un-gray-coding. // -void FT4::c_soft_decode(const FFTEngine::ffts_t &c103x, float ll174[]) +void FT4::c_soft_decode(const FFTEngine::ffts_t &c103x, float ll174[]) const { FFTEngine::ffts_t c103 = c_convert_to_snr(c103x); std::vector> maxes(103); @@ -1857,7 +1857,7 @@ std::vector FT4::extract_bits(const std::vector &syms, const std::ve void FT4::soft_decode_pairs( const FFTEngine::ffts_t &m103x, float ll174[] -) +) const { FFTEngine::ffts_t m103 = c_convert_to_snr(m103x); @@ -1910,7 +1910,7 @@ void FT4::soft_decode_pairs( { int bitind = (si + 0) * 2 + (1 - bit); - if ((i & (1 << bit))) + if (i & (1 << bit)) { // symbol i would make this bit a one. if (x > bitinfo[bitind].one) { @@ -1935,7 +1935,7 @@ void FT4::soft_decode_pairs( { int bitind = (si + 1) * 2 + (1 - bit); - if ((i & (1 << bit))) + if (i & (1 << bit)) { // symbol i would make this bit a one. if (x > bitinfo[bitind].one) { @@ -1987,7 +1987,7 @@ void FT4::soft_decode_pairs( void FT4::soft_decode_triples( const FFTEngine::ffts_t &m103x, float ll174[] -) +) const { FFTEngine::ffts_t m103 = c_convert_to_snr(m103x); @@ -3234,7 +3234,7 @@ void FT4::subtract( // int FT4::try_decode( const std::vector &samples200, - float ll174[174], + const float ll174[174], float best_hz, int best_off_samples, float hz0_for_cb, @@ -3432,8 +3432,8 @@ void FT4Decoder::entry( int rate, float min_hz, float max_hz, - int hints1[], - int hints2[], + const int hints1[], + const int hints2[], double time_left, double total_time_left, CallbackInterface *cb, diff --git a/ft8/ft4.h b/ft8/ft4.h index 1f62fbf67..9f391fc0d 100644 --- a/ft8/ft4.h +++ b/ft8/ft4.h @@ -178,34 +178,34 @@ private: int rate, float hz ); - // shift the frequency by a fraction of 6.25, - // to center hz on bin 4 (25 hz). + // shift the frequency by a fraction of 23.4, + // to center hz on bin 2 (46.8 hz). std::vector shift200( const std::vector &samples200, int off, int len, float hz ); - // returns a mini-FFT of 79 8-tone symbols. + // returns a mini-FFT of 103 4-tone symbols. FFTEngine::ffts_t extract(const std::vector &samples200, float, int off); // - // m79 is a 79x8 array of complex. + // m103 is a 103x4 array of complex. // - FFTEngine::ffts_t un_gray_code_c(const FFTEngine::ffts_t &m79) const; + FFTEngine::ffts_t un_gray_code_c(const FFTEngine::ffts_t &m103) const; // - // m79 is a 79x8 array of float. + // m103 is a 103x4 array of float. // - std::vector> un_gray_code_r(const std::vector> &m79) const; + std::vector> un_gray_code_r(const std::vector> &m103) const; // // normalize levels by windowed median. // this helps, but why? // - std::vector> convert_to_snr(const std::vector> &m79) const; + std::vector> convert_to_snr(const std::vector> &m103) const; // normalize levels by windowed median. // this helps, but why? // std::vector>> c_convert_to_snr( - const std::vector>> &m79 + const std::vector>> &m103 ) const; // // statistics to decide soft probabilities, @@ -214,11 +214,11 @@ private: // distribution of noise. // static void make_stats( - const std::vector> &m79, + const std::vector> &m103, Stats &bests, Stats &all ); - // convert 79x8 complex FFT bins to magnitudes. + // convert 103x4 complex FFT bins to magnitudes. // // exploits local phase coherence by decreasing magnitudes of bins // whose phase is far from the phases of nearby strongest tones. @@ -228,18 +228,18 @@ private: // number of cycles and thus preserves phase from one symbol to the // next. // - std::vector> soft_c2m(const FFTEngine::ffts_t &c79) const; - // c79 is 79x8 complex tones, before un-gray-coding. + std::vector> soft_c2m(const FFTEngine::ffts_t &c103) const; + // c103 is 103x4 complex tones, before un-gray-coding. // - void soft_decode(const FFTEngine::ffts_t &c79, float ll174[]); + void soft_decode(const FFTEngine::ffts_t &c103, float ll174[]) const; // - // c79 is 79x8 complex tones, before un-gray-coding. + // c103 is 103x4 complex tones, before un-gray-coding. // - void c_soft_decode(const FFTEngine::ffts_t &c79x, float ll174[]); + void c_soft_decode(const FFTEngine::ffts_t &c103x, float ll174[]) const; // - // turn 79 symbol numbers into 174 bits. + // turn 103 symbol numbers into 174 bits. // strip out the three Costas sync blocks, - // leaving 58 symbol numbers. + // leaving 87 symbol numbers. // each represents three bits. // (all post-un-gray-code). // str is per-symbol strength; must be positive. @@ -251,13 +251,13 @@ private: // that they have the same phase, by summing the complex // correlations for each possible pair and using the max. void soft_decode_pairs( - const FFTEngine::ffts_t &m79x, + const FFTEngine::ffts_t &m103x, float ll174[] - ); + ) const; void soft_decode_triples( - const FFTEngine::ffts_t &m79x, + const FFTEngine::ffts_t &m103x, float ll174[] - ); + ) const; // // bandpass filter some FFT bins. // smooth transition from stop-band to pass-band, @@ -348,7 +348,7 @@ private: // int try_decode( const std::vector &samples200, - float ll174[174], + const float ll174[174], float best_hz, int best_off_samples, float hz0_for_cb, @@ -429,8 +429,8 @@ public: int rate, float min_hz, float max_hz, - int hints1[], - int hints2[], + const int hints1[], + const int hints2[], double time_left, double total_time_left, CallbackInterface *cb, diff --git a/ft8/ft8.cpp b/ft8/ft8.cpp index 69e5c3086..c2eb48843 100644 --- a/ft8/ft8.cpp +++ b/ft8/ft8.cpp @@ -76,12 +76,12 @@ FT8::FT8( float max_hz, int start, int rate, - int hints1[], - int hints2[], + const int hints1[], + const int hints2[], double deadline, double final_deadline, CallbackInterface *cb, - std::vector prevdecs, + const std::vector &prevdecs, FFTEngine *fftEngine ) { @@ -124,7 +124,7 @@ void FT8::start_work() // strength of costas block of signal with tone 0 at bi0, // and symbol zero at si0. -float FT8::one_coarse_strength(const FFTEngine::ffts_t &bins, int bi0, int si0) +float FT8::one_coarse_strength(const FFTEngine::ffts_t &bins, int bi0, int si0) const { int costas[] = {3, 1, 4, 0, 6, 5, 2}; @@ -224,7 +224,7 @@ float FT8::one_coarse_strength(const FFTEngine::ffts_t &bins, int bi0, int si0) // return symbol length in samples at the given rate. // insist on integer symbol lengths so that we can // use whole FFT bins. -int FT8::blocksize(int rate) +int FT8::blocksize(int rate) const { // FT8 symbol length is 1920 at 12000 samples/second. int xblock = (1920*rate) / 12000; @@ -1124,7 +1124,7 @@ FFTEngine::ffts_t FT8::extract(const std::vector &samples200, float, int // // m79 is a 79x8 array of complex. // -FFTEngine::ffts_t FT8::un_gray_code_c(const FFTEngine::ffts_t &m79) +FFTEngine::ffts_t FT8::un_gray_code_c(const FFTEngine::ffts_t &m79) const { FFTEngine::ffts_t m79a(79); int map[] = {0, 1, 3, 2, 6, 4, 5, 7}; @@ -1144,7 +1144,7 @@ FFTEngine::ffts_t FT8::un_gray_code_c(const FFTEngine::ffts_t &m79) // // m79 is a 79x8 array of float. // -std::vector> FT8::un_gray_code_r(const std::vector> &m79) +std::vector> FT8::un_gray_code_r(const std::vector> &m79) const { std::vector> m79a(79); int map[] = {0, 1, 3, 2, 6, 4, 5, 7}; @@ -1191,7 +1191,7 @@ std::vector> FT8::un_gray_code_r_gen(const std::vector> FT8::convert_to_snr(const std::vector> &m79) +std::vector> FT8::convert_to_snr(const std::vector> &m79) const { if (params.snr_how < 0 || params.snr_win < 0) { return m79; @@ -1281,7 +1281,7 @@ std::vector> FT8::convert_to_snr(const std::vector>> FT8::c_convert_to_snr( const std::vector>> &m79 -) +) const { if (params.snr_how < 0 || params.snr_win < 0) { return m79; @@ -1554,7 +1554,7 @@ void FT8::make_stats_gen( // number of cycles and thus preserves phase from one symbol to the // next. // -std::vector> FT8::soft_c2m(const FFTEngine::ffts_t &c79) +std::vector> FT8::soft_c2m(const FFTEngine::ffts_t &c79) const { std::vector> m79(79); std::vector raw_phases(79); // of strongest tone in each symbol time @@ -1729,7 +1729,7 @@ float FT8::bayes( // // c79 is 79x8 complex tones, before un-gray-coding. // -void FT8::soft_decode(const FFTEngine::ffts_t &c79, float ll174[]) +void FT8::soft_decode(const FFTEngine::ffts_t &c79, float ll174[]) const { std::vector> m79(79); // m79 = absolute values of c79. @@ -1928,7 +1928,7 @@ void FT8::soft_decode_mags(FT8Params& params, const std::vector 0 for zero, // scaled by str. // -std::vector FT8::extract_bits(const std::vector &syms, const std::vector str) +std::vector FT8::extract_bits(const std::vector &syms, const std::vector str) const { // assert(syms.size() == 79); // assert(str.size() == 79); @@ -2196,7 +2196,7 @@ std::vector FT8::extract_bits(const std::vector &syms, const std::ve void FT8::soft_decode_pairs( const FFTEngine::ffts_t &m79x, float ll174[] -) +) const { FFTEngine::ffts_t m79 = c_convert_to_snr(m79x); @@ -2328,7 +2328,7 @@ void FT8::soft_decode_pairs( void FT8::soft_decode_triples( const FFTEngine::ffts_t &m79x, float ll174[] -) +) const { FFTEngine::ffts_t m79 = c_convert_to_snr(m79x); @@ -2585,7 +2585,7 @@ std::vector> FT8::fbandpass( float low_inner, // start of flat area float high_inner, // end of flat area float high_outer // end of transition -) +) const { // assert(low_outer <= low_inner); // assert(low_inner <= high_inner); @@ -2790,7 +2790,7 @@ int FT8::one_iter(const std::vector &samples200, int best_off, float hz_f // estimate SNR, yielding numbers vaguely similar to WSJT-X. // m79 is a 79x8 complex FFT output. // -float FT8::guess_snr(const FFTEngine::ffts_t &m79) +float FT8::guess_snr(const FFTEngine::ffts_t &m79) const { int costas[] = {3, 1, 4, 0, 6, 5, 2}; float pnoises = 0; @@ -2861,7 +2861,7 @@ float FT8::guess_snr(const FFTEngine::ffts_t &m79) // adj_off is the amount to change the offset, in samples. // should be subtracted from offset. // -void FT8::fine(const FFTEngine::ffts_t &m79, int, float &adj_hz, float &adj_off) +void FT8::fine(const FFTEngine::ffts_t &m79, int, float &adj_hz, float &adj_off) const { adj_hz = 0.0; adj_off = 0.0; @@ -3459,7 +3459,7 @@ void FT8::subtract( // int FT8::try_decode( const std::vector &samples200, - float ll174[174], + const float ll174[174], float best_hz, int best_off_samples, float hz0_for_cb, @@ -3566,7 +3566,7 @@ int FT8::try_decode( // used to help ensure that subtraction subtracts // at the right place. // -std::vector FT8::recode(int a174[]) +std::vector FT8::recode(int a174[]) const { int i174 = 0; int costas[] = {3, 1, 4, 0, 6, 5, 2}; diff --git a/ft8/ft8.h b/ft8/ft8.h index fe92ef27d..dd2f1b234 100644 --- a/ft8/ft8.h +++ b/ft8/ft8.h @@ -242,12 +242,12 @@ public: float max_hz, int start, int rate, - int hints1[], - int hints2[], + const int hints1[], + const int hints2[], double deadline, double final_deadline, CallbackInterface *cb, - std::vector prevdecs, + const std::vector& prevdecs, FFTEngine *fftEngine ); ~FT8(); @@ -257,11 +257,11 @@ public: void start_work(); // strength of costas block of signal with tone 0 at bi0, // and symbol zero at si0. - float one_coarse_strength(const FFTEngine::ffts_t &bins, int bi0, int si0); + float one_coarse_strength(const FFTEngine::ffts_t &bins, int bi0, int si0) const; // return symbol length in samples at the given rate. // insist on integer symbol lengths so that we can // use whole FFT bins. - int blocksize(int rate); + int blocksize(int rate) const; // // look for potential signals by searching FFT bins for Costas symbol // blocks. returns a vector of candidate positions. @@ -407,16 +407,16 @@ private: // // m79 is a 79x8 array of complex. // - FFTEngine::ffts_t un_gray_code_c(const FFTEngine::ffts_t &m79); + FFTEngine::ffts_t un_gray_code_c(const FFTEngine::ffts_t &m79) const; // // m79 is a 79x8 array of float. // - std::vector> un_gray_code_r(const std::vector> &m79); + std::vector> un_gray_code_r(const std::vector> &m79) const; // // normalize levels by windowed median. // this helps, but why? // - std::vector> convert_to_snr(const std::vector> &m79); + std::vector> convert_to_snr(const std::vector> &m79) const; // // normalize levels by windowed median. // this helps, but why? @@ -428,7 +428,7 @@ private: // std::vector>> c_convert_to_snr( const std::vector>> &m79 - ); + ) const; // // statistics to decide soft probabilities, // to drive LDPC decoder. @@ -461,7 +461,7 @@ private: // number of cycles and thus preserves phase from one symbol to the // next. // - std::vector> soft_c2m(const FFTEngine::ffts_t &c79); + std::vector> soft_c2m(const FFTEngine::ffts_t &c79) const; public: // // guess the probability that a bit is zero vs one, @@ -482,11 +482,11 @@ private: // // c79 is 79x8 complex tones, before un-gray-coding. // - void soft_decode(const FFTEngine::ffts_t &c79, float ll174[]); + void soft_decode(const FFTEngine::ffts_t &c79, float ll174[]) const; // // c79 is 79x8 complex tones, before un-gray-coding. // - void c_soft_decode(const FFTEngine::ffts_t &c79x, float ll174[]); + void c_soft_decode(const FFTEngine::ffts_t &c79x, float ll174[]) const; // // turn 79 symbol numbers into 174 bits. // strip out the three Costas sync blocks, @@ -497,18 +497,18 @@ private: // each returned element is < 0 for 1, > 0 for zero, // scaled by str. // - std::vector extract_bits(const std::vector &syms, const std::vector str); + std::vector extract_bits(const std::vector &syms, const std::vector str) const; // decode successive pairs of symbols. exploits the likelihood // that they have the same phase, by summing the complex // correlations for each possible pair and using the max. void soft_decode_pairs( const FFTEngine::ffts_t &m79x, float ll174[] - ); + ) const; void soft_decode_triples( const FFTEngine::ffts_t &m79x, float ll174[] - ); + ) const; // // bandpass filter some FFT bins. // smooth transition from stop-band to pass-band, @@ -522,7 +522,7 @@ private: float low_inner, // start of flat area float high_inner, // end of flat area float high_outer // end of transition - ); + ) const; // // move hz down to 25, filter+convert to 200 samples/second. // @@ -554,7 +554,7 @@ private: // estimate SNR, yielding numbers vaguely similar to WSJT-X. // m79 is a 79x8 complex FFT output. // - float guess_snr(const FFTEngine::ffts_t &m79); + float guess_snr(const FFTEngine::ffts_t &m79) const; // // compare phases of successive symbols to guess whether // the starting offset is a little too high or low. @@ -575,7 +575,7 @@ private: // adj_off is the amount to change the offset, in samples. // should be subtracted from offset. // - void fine(const FFTEngine::ffts_t &m79, int, float &adj_hz, float &adj_off); + void fine(const FFTEngine::ffts_t &m79, int, float &adj_hz, float &adj_off) const; // // subtract a corrected decoded signal from nsamples_, // perhaps revealing a weaker signal underneath, @@ -599,7 +599,7 @@ private: // int try_decode( const std::vector &samples200, - float ll174[174], + const float ll174[174], float best_hz, int best_off_samples, float hz0_for_cb, @@ -615,7 +615,7 @@ private: // used to help ensure that subtraction subtracts // at the right place. // - std::vector recode(int a174[]); + std::vector recode(int a174[]) const; // // the signal is at roughly 25 hz in samples200. //