kopia lustrzana https://github.com/jamescoxon/dl-fldigi
144 wiersze
3.6 KiB
C++
144 wiersze
3.6 KiB
C++
// ----------------------------------------------------------------------------
|
|
// pskeval.cxx -- psk signal evaluator
|
|
//
|
|
// Copyright (C) 2008-2009
|
|
// Dave Freese, W1HKJ
|
|
//
|
|
// This file is part of fldigi. Adapted from code contained in gmfsk source code
|
|
// distribution.
|
|
//
|
|
// Fldigi is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// Fldigi is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with fldigi. If not, see <http://www.gnu.org/licenses/>.
|
|
// ----------------------------------------------------------------------------
|
|
|
|
#include <config.h>
|
|
|
|
#include "fl_digi.h"
|
|
#include "pskeval.h"
|
|
#include "configuration.h"
|
|
#include "misc.h"
|
|
|
|
using namespace std;
|
|
//=============================================================================
|
|
//========================== psk signal evaluation ============================
|
|
//=============================================================================
|
|
|
|
pskeval::pskeval() {
|
|
bw = 31.25;
|
|
clear();
|
|
}
|
|
|
|
pskeval::~pskeval() {
|
|
}
|
|
|
|
int countdown = 8;
|
|
int rows = 0;
|
|
|
|
void pskeval::sigdensity() {
|
|
int ihbw = (int)(0.6*bw);
|
|
int ibw = 2 * ihbw;
|
|
|
|
double *vals = new double[ibw];
|
|
double sig = 0.0;
|
|
double val = 0.0;
|
|
|
|
int low = progdefaults.LowFreqCutoff;
|
|
if (low < ihbw) low = ihbw;
|
|
int high = progdefaults.HighFreqCutoff;
|
|
if (high > FFT_LEN - ihbw) high = FFT_LEN - ihbw;
|
|
int nbr = high - low;
|
|
|
|
sigmin = 1e6;
|
|
|
|
for (int i = 0; i < ibw; i++) {
|
|
val = vals[i] = wf->Pwr(i + low - ihbw);
|
|
sig += val;
|
|
}
|
|
for (int i = 0, j = 0; i < nbr; i++) {
|
|
sigpwr[i + low] = decayavg(sigpwr[i + low], sig, 32);
|
|
sig -= vals[j];
|
|
val = vals[j] = wf->Pwr(i + ihbw + low);
|
|
sig += val;
|
|
if (++j == ibw) j = 0;
|
|
if (sig < sigmin) sigmin = sig;
|
|
}
|
|
|
|
if (sigmin < 1e-8) sigmin = 1e-8;
|
|
delete [] vals;
|
|
}
|
|
|
|
double pskeval::sigpeak(int &f, int f1, int f2)
|
|
{
|
|
double peak = 0;
|
|
f1 -= bw;
|
|
if (f1 <= progdefaults.LowFreqCutoff) f1 = progdefaults.LowFreqCutoff;
|
|
f2 += bw;
|
|
if (f2 >= progdefaults.HighFreqCutoff) f2 = progdefaults.HighFreqCutoff;
|
|
|
|
int fa = f2, fb = f1;
|
|
|
|
for (int i = f1; i < f2; i++) if (sigpwr[i] > peak) peak = sigpwr[i];
|
|
if (!peak) return 0;
|
|
for (int i = f1; i < f2; i++)
|
|
if (sigpwr[i] > peak*0.75) fb = i;
|
|
for (int i = f2; i > f1; i--)
|
|
if (sigpwr[i] > peak*0.75) fa = i;
|
|
if (fa > fb) return 0;
|
|
f = (fa + fb) / 2;
|
|
return peak / sigmin / bw;
|
|
}
|
|
|
|
double pskeval::peak(int &f0, int f1, int f2, double db)
|
|
{
|
|
double peak = 0;
|
|
|
|
int fa = f2, fb = f1;
|
|
double level = pow(10, (10 + db) / 10.0);
|
|
|
|
//step 1
|
|
for (int i = f1; i < f2; i++) if (sigpwr[i] > peak) peak = sigpwr[i];
|
|
|
|
if (((peak-sigmin) / sigmin ) < level) {
|
|
return 0;
|
|
}
|
|
|
|
for (int i = f1; i < f2; i++)
|
|
if (sigpwr[i] > peak*0.75) fb = i;
|
|
for (int i = f2; i > f1; i--)
|
|
if (sigpwr[i] > peak*0.75) fa = i;
|
|
if (fa > fb) {
|
|
return 0;
|
|
}
|
|
f0 = (fa + fb) / 2;
|
|
//step 2
|
|
f1 = f0 - 1.5*bw;
|
|
if (f1 < bw) f1 = bw;
|
|
f2 = f0 + 1.5*bw;
|
|
fb = f1; fa = f2;
|
|
peak = 0;
|
|
for (int i = f1; i < f2; i++) if (sigpwr[i] > peak) peak = sigpwr[i];
|
|
for (int i = f1; i < f2; i++)
|
|
if (sigpwr[i] > peak*0.75) fb = i;
|
|
for (int i = f2; i > f1; i--)
|
|
if (sigpwr[i] > peak*0.75) fa = i;
|
|
if (fa > fb) {
|
|
return 0;
|
|
}
|
|
f0 = (fa + fb) / 2;
|
|
return (peak - sigmin) / sigmin ;
|
|
}
|
|
|
|
void pskeval::clear() {
|
|
for (int i = 0; i < FFT_LEN; i++) sigpwr[i] = 0.0;
|
|
}
|