1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2026-04-29 02:43:59 -04:00

Removed redundant functions between FT8 and FT4

This commit is contained in:
f4exb 2026-03-12 21:26:35 +01:00
parent 58c4bac3d8
commit 71d6208fe9
2 changed files with 0 additions and 298 deletions

View File

@ -1178,32 +1178,6 @@ std::vector<std::vector<float>> FT4::un_gray_code_r(const std::vector<std::vecto
return m103a;
}
//
// Generic Gray decoding for magnitudes (floats)
//
std::vector<std::vector<float>> FT4::un_gray_code_r_gen(const std::vector<std::vector<float>> &mags)
{
if (mags.size() == 0) {
return mags;
}
std::vector<std::vector<float>> magsa(mags.size());
int nsyms = mags.front().size();
for (unsigned int si = 0; si < mags.size(); si++)
{
magsa[si].resize(nsyms);
for (int bini = 0; bini < nsyms; bini++)
{
int grayi = bini ^ (bini >> 1);
magsa[si][bini] = mags[si][grayi];
}
}
return magsa;
}
//
// normalize levels by windowed median.
// this helps, but why?
@ -1382,93 +1356,6 @@ std::vector<std::vector<std::complex<float>>> FT4::c_convert_to_snr(
return n103;
}
std::vector<std::vector<float>> FT4::convert_to_snr_gen(const FT4Params& params, int nbSymbolBits, const std::vector<std::vector<float>> &mags)
{
if (params.snr_how < 0 || params.snr_win < 0) {
return mags;
}
//
// for each symbol time, what's its "noise" level?
//
std::vector<float> mm(mags.size());
int nbSymbols = 1<<nbSymbolBits;
for (int si = 0; si < (int) mags.size(); si++)
{
std::vector<float> v(nbSymbols);
float sum = 0.0;
for (int bini = 0; bini < nbSymbols; bini++)
{
float x = mags[si][bini];
v[bini] = x;
sum += x;
}
if (params.snr_how != 1) {
std::sort(v.begin(), v.end());
}
int mid = nbSymbols / 2;
if (params.snr_how == 0) {
// median
mm[si] = (v[mid-1] + v[mid]) / 2;
} else if (params.snr_how == 1) {
mm[si] = sum / nbSymbols;
} else if (params.snr_how == 2) {
// all but strongest tone.
mm[si] = std::accumulate(v.begin(), v.end() - 1, 0.0f) / (v.size() - 1);
} else if (params.snr_how == 3) {
mm[si] = v.front(); // weakest tone
} else if (params.snr_how == 4) {
mm[si] = v.back(); // strongest tone
} else if (params.snr_how == 5) {
mm[si] = v[v.size()-2]; // second-strongest tone
} else {
mm[si] = 1.0;
}
}
// we're going to take a windowed average.
std::vector<float> winwin;
if (params.snr_win > 0) {
winwin = blackman(2 * params.snr_win + 1);
} else {
winwin.push_back(1.0);
}
std::vector<std::vector<float>> snr(mags.size());
for (int si = 0; si < (int) mags.size(); si++)
{
float sum = 0;
for (int dd = si - params.snr_win; dd <= si + params.snr_win; dd++)
{
int wi = dd - (si - params.snr_win);
if (dd >= 0 && dd < (int) mags.size()) {
sum += mm[dd] * winwin[wi];
} else if (dd < 0) {
sum += mm[0] * winwin[wi];
} else {
sum += mm[mags.size()-1] * winwin[wi];
}
}
snr[si].resize(nbSymbols);
for (int bi = 0; bi < nbSymbols; bi++) {
snr[si][bi] = mags[si][bi] / sum;
}
}
return snr;
}
//
// statistics to decide soft probabilities,
// to drive LDPC decoder.
@ -1544,39 +1431,6 @@ void FT4::make_stats(
}
}
//
// generalized version of the above for any number of symbols and no Costas
// used by FT-chirp decoder
// Probably not needed here. The FT8 one may be used.
//
void FT4::make_stats_gen(
const std::vector<std::vector<float>> &mags,
int nbSymbolBits,
Stats &bests,
Stats &all
)
{
int nbBins = 1<<nbSymbolBits;
for (unsigned int si = 0; si < mags.size(); si++)
{
float mx = 0;
for (int bi = 0; bi < nbBins; bi++)
{
float x = mags[si][bi];
if (x > mx) {
mx = x;
}
all.add(x);
}
bests.add(mx);
}
}
//
// convert 103x4 complex FFT bins to magnitudes.
//
@ -1873,87 +1727,6 @@ void FT4::soft_decode(const FFTEngine::ffts_t &c103, float ll174[])
// assert(lli == 174);
}
//
// mags is the vector of 2^nbSymbolBits vector of magnitudes at each symbol time
// ll174 is the resulting 174 soft bits of payload
// used in FT-chirp modulation scheme - generalized to any number of symbol bits
//
void FT4::soft_decode_mags(FT4Params& params, const std::vector<std::vector<float>>& mags_, int nbSymbolBits, float ll174[])
{
if ((nbSymbolBits > 16) || (nbSymbolBits < 1)) {
return;
}
std::vector<std::vector<float>> mags = convert_to_snr_gen(params, nbSymbolBits, mags_);
// statistics to decide soft probabilities.
// distribution of strongest tones, and
// distribution of noise.
Stats bests(params.problt_how_sig, params.log_tail, params.log_rate);
Stats all(params.problt_how_noise, params.log_tail, params.log_rate);
make_stats_gen(mags, nbSymbolBits, bests, all);
mags = un_gray_code_r_gen(mags);
int lli = 0;
int zoX = 1<<(nbSymbolBits-1);
int zoY = nbSymbolBits;
std::vector<int> zeroi(zoX*zoY);
std::vector<int> onei(zoX*zoY);
for (int biti = 0; biti < nbSymbolBits; biti++)
{
int i = biti * zoX;
set_ones_zeroes(&onei[i], &zeroi[i], nbSymbolBits, biti);
}
for (unsigned int si = 0; si < mags.size(); si++)
{
// for each of the symbol bits, look at the strongest tone
// that would make it a zero, and the strongest tone that
// would make it a one. use Bayes to decide which is more
// likely, comparing each against the distribution of noise
// and the distribution of strongest tones.
// most-significant-bit first.
for (int biti = nbSymbolBits - 1; biti >= 0; biti--)
{
// strongest tone that would make this bit be zero.
int got_best_zero = 0;
float best_zero = 0;
for (int i = 0; i < 1<<(nbSymbolBits-1); i++)
{
float x = mags[si][zeroi[i+biti*zoX]];
// printf("FT8::soft_decode_mags:: biti: %d i: %d zeroi: %d x: %f best_zero: %f\n", biti, i, zeroi[i+biti*zoX], x, best_zero);
if (got_best_zero == 0 || x > best_zero)
{
got_best_zero = 1;
best_zero = x;
}
}
// strongest tone that would make this bit be one.
int got_best_one = 0;
float best_one = 0;
for (int i = 0; i < 1<<(nbSymbolBits-1); i++)
{
float x = mags[si][onei[i+biti*zoX]];
// printf("FT8::soft_decode_mags:: biti: %d i: %d onei: %d x: %f best_one: %f\n", biti, i, onei[i+biti*zoX], x, best_one);
if (got_best_one == 0 || x > best_one)
{
got_best_one = 1;
best_one = x;
}
}
// printf("FT8::soft_decode_mags: biti: %d best_zero: %f best_one: %f\n", biti, best_zero, best_one);
float ll = bayes(params, best_zero, best_one, lli, bests, all);
ll174[lli++] = ll;
}
}
}
//
// c103 is 103x4 complex tones, before un-gray-coding.
//
@ -2143,43 +1916,6 @@ void FT4::c_soft_decode(const FFTEngine::ffts_t &c103x, float ll174[])
// assert(lli == 174);
}
//
// set ones and zero symbol indexes. Bit index is LSB
//
void FT4::set_ones_zeroes(int ones[], int zeroes[], int nbBits, int bitIndex)
{
int nbIndexes = 1 << (nbBits - 1);
if (bitIndex == 0)
{
for (int i = 0; i < nbIndexes; i++)
{
zeroes[i] = i<<1;
ones[i] = zeroes[i] | 1;
}
}
else if (bitIndex == nbBits - 1)
{
for (int i = 0; i < nbIndexes; i++)
{
zeroes[i] = i;
ones[i] = (1<<(nbBits-1)) | zeroes[i];
}
}
else
{
int mask = (1<<nbBits) - 1;
int maskLow = (1<<bitIndex) - 1;
int maskHigh = mask ^ maskLow;
for (int i = 0; i < nbIndexes; i++)
{
zeroes[i] = (i & maskLow) + ((i & maskHigh)<<1);
ones[i] = zeroes[i] + (1<<bitIndex);
}
}
}
//
// turn 103 symbol numbers into 174 bits.
// strip out the four FT4 sync blocks,

View File

@ -245,23 +245,6 @@ public:
// append the 83 bits to the 91 bits message e+ crc to obtain the 174 bit payload
static void encode(int a174[], const int s77[]);
//
// set ones and zero symbol indexes
//
static void set_ones_zeroes(int ones[], int zeroes[], int nbBits, int bitIndex);
//
// mags is the vector of 2^nbSymbolBits vector of magnitudes at each symbol time
// ll174 is the resulting 174 soft bits of payload
// used in FT-chirp modulation scheme - generalized to any number of symbol bits
//
static void soft_decode_mags(FT4Params& params, const std::vector<std::vector<float>>& mags, int nbSymbolBits, float ll174[]);
//
// Generic Gray decoding for magnitudes (floats)
//
static std::vector<std::vector<float>> un_gray_code_r_gen(const std::vector<std::vector<float>> &mags);
private:
//
// reduce the sample rate from arate to brate.
@ -382,12 +365,6 @@ private:
// this helps, but why?
//
std::vector<std::vector<float>> convert_to_snr(const std::vector<std::vector<float>> &m79);
//
// normalize levels by windowed median.
// this helps, but why?
//
static std::vector<std::vector<float>> convert_to_snr_gen(const FT4Params& params, int nbSymbolBits, const std::vector<std::vector<float>> &mags);
//
// normalize levels by windowed median.
// this helps, but why?
//
@ -405,17 +382,6 @@ private:
Stats &bests,
Stats &all
);
//
// generalized version of the above for any number of symbols and no Costas
// used by FT-chirp decoder
//
static void make_stats_gen(
const std::vector<std::vector<float>> &mags,
int nbSymbolBits,
Stats &bests,
Stats &all
);
//
// convert 79x8 complex FFT bins to magnitudes.
//
// exploits local phase coherence by decreasing magnitudes of bins