1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2026-08-01 16:38:06 -04:00

FT8 demod: Sonar fixes (2)

This commit is contained in:
f4exb
2026-03-14 03:46:48 +01:00
parent b09e8df343
commit d0ad1ae413
4 changed files with 75 additions and 75 deletions
+10 -10
View File
@@ -1071,7 +1071,7 @@ std::vector<float> 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<float> FT4::shift200(
const std::vector<float> &samples200,
@@ -1532,7 +1532,7 @@ std::vector<std::vector<float>> 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<std::vector<float>> 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<std::complex<float>> maxes(103);
@@ -1857,7 +1857,7 @@ std::vector<float> FT4::extract_bits(const std::vector<int> &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<float> &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,
+25 -25
View File
@@ -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<float> shift200(
const std::vector<float> &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<float> &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<std::vector<float>> un_gray_code_r(const std::vector<std::vector<float>> &m79) const;
std::vector<std::vector<float>> un_gray_code_r(const std::vector<std::vector<float>> &m103) const;
//
// normalize levels by windowed median.
// this helps, but why?
//
std::vector<std::vector<float>> convert_to_snr(const std::vector<std::vector<float>> &m79) const;
std::vector<std::vector<float>> convert_to_snr(const std::vector<std::vector<float>> &m103) const;
// normalize levels by windowed median.
// this helps, but why?
//
std::vector<std::vector<std::complex<float>>> c_convert_to_snr(
const std::vector<std::vector<std::complex<float>>> &m79
const std::vector<std::vector<std::complex<float>>> &m103
) const;
//
// statistics to decide soft probabilities,
@@ -214,11 +214,11 @@ private:
// distribution of noise.
//
static void make_stats(
const std::vector<std::vector<float>> &m79,
const std::vector<std::vector<float>> &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<std::vector<float>> soft_c2m(const FFTEngine::ffts_t &c79) const;
// c79 is 79x8 complex tones, before un-gray-coding.
std::vector<std::vector<float>> 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<float> &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,
+20 -20
View File
@@ -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<cdecode> prevdecs,
const std::vector<cdecode> &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<float> &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<std::vector<float>> FT8::un_gray_code_r(const std::vector<std::vector<float>> &m79)
std::vector<std::vector<float>> FT8::un_gray_code_r(const std::vector<std::vector<float>> &m79) const
{
std::vector<std::vector<float>> m79a(79);
int map[] = {0, 1, 3, 2, 6, 4, 5, 7};
@@ -1191,7 +1191,7 @@ std::vector<std::vector<float>> FT8::un_gray_code_r_gen(const std::vector<std::v
// normalize levels by windowed median.
// this helps, but why?
//
std::vector<std::vector<float>> FT8::convert_to_snr(const std::vector<std::vector<float>> &m79)
std::vector<std::vector<float>> FT8::convert_to_snr(const std::vector<std::vector<float>> &m79) const
{
if (params.snr_how < 0 || params.snr_win < 0) {
return m79;
@@ -1281,7 +1281,7 @@ std::vector<std::vector<float>> FT8::convert_to_snr(const std::vector<std::vecto
//
std::vector<std::vector<std::complex<float>>> FT8::c_convert_to_snr(
const std::vector<std::vector<std::complex<float>>> &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<std::vector<float>> FT8::soft_c2m(const FFTEngine::ffts_t &c79)
std::vector<std::vector<float>> FT8::soft_c2m(const FFTEngine::ffts_t &c79) const
{
std::vector<std::vector<float>> m79(79);
std::vector<float> 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<std::vector<float>> m79(79);
// m79 = absolute values of c79.
@@ -1928,7 +1928,7 @@ void FT8::soft_decode_mags(FT8Params& params, const std::vector<std::vector<floa
//
// c79 is 79x8 complex tones, before un-gray-coding.
//
void FT8::c_soft_decode(const FFTEngine::ffts_t &c79x, float ll174[])
void FT8::c_soft_decode(const FFTEngine::ffts_t &c79x, float ll174[]) const
{
FFTEngine::ffts_t c79 = c_convert_to_snr(c79x);
int costas[] = {3, 1, 4, 0, 6, 5, 2};
@@ -2166,7 +2166,7 @@ void FT8::set_ones_zeroes(int ones[], int zeroes[], int nbBits, int bitIndex)
// each returned element is < 0 for 1, > 0 for zero,
// scaled by str.
//
std::vector<float> FT8::extract_bits(const std::vector<int> &syms, const std::vector<float> str)
std::vector<float> FT8::extract_bits(const std::vector<int> &syms, const std::vector<float> str) const
{
// assert(syms.size() == 79);
// assert(str.size() == 79);
@@ -2196,7 +2196,7 @@ std::vector<float> FT8::extract_bits(const std::vector<int> &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<std::complex<float>> 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<float> &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<float> &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<int> FT8::recode(int a174[])
std::vector<int> FT8::recode(int a174[]) const
{
int i174 = 0;
int costas[] = {3, 1, 4, 0, 6, 5, 2};
+20 -20
View File
@@ -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<cdecode> prevdecs,
const std::vector<cdecode>& 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<std::vector<float>> un_gray_code_r(const std::vector<std::vector<float>> &m79);
std::vector<std::vector<float>> un_gray_code_r(const std::vector<std::vector<float>> &m79) const;
//
// normalize levels by windowed median.
// this helps, but why?
//
std::vector<std::vector<float>> convert_to_snr(const std::vector<std::vector<float>> &m79);
std::vector<std::vector<float>> convert_to_snr(const std::vector<std::vector<float>> &m79) const;
//
// normalize levels by windowed median.
// this helps, but why?
@@ -428,7 +428,7 @@ private:
//
std::vector<std::vector<std::complex<float>>> c_convert_to_snr(
const std::vector<std::vector<std::complex<float>>> &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<std::vector<float>> soft_c2m(const FFTEngine::ffts_t &c79);
std::vector<std::vector<float>> 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<float> extract_bits(const std::vector<int> &syms, const std::vector<float> str);
std::vector<float> extract_bits(const std::vector<int> &syms, const std::vector<float> 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<float> &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<int> recode(int a174[]);
std::vector<int> recode(int a174[]) const;
//
// the signal is at roughly 25 hz in samples200.
//