1 // ----------------------------------------------------------------------------
2 // pskeval.cxx -- psk signal evaluator
3 //
4 // Copyright (C) 2008-2009
5 // Dave Freese, W1HKJ
6 //
7 // This file is part of fldigi. Adapted from code contained in gmfsk source code
8 // distribution.
9 //
10 // Fldigi is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Fldigi is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with fldigi. If not, see <http://www.gnu.org/licenses/>.
22 // ----------------------------------------------------------------------------
23
24 #include <config.h>
25
26 #include "fl_digi.h"
27 #include "pskeval.h"
28 #include "configuration.h"
29 #include "misc.h"
30
31 using namespace std;
32 //=============================================================================
33 //========================== psk signal evaluation ============================
34 //=============================================================================
35
pskeval()36 pskeval::pskeval() {
37 bw = 31.25;
38 clear();
39 }
40
~pskeval()41 pskeval::~pskeval() {
42 }
43
44 int countdown = 8;
45 int rows = 0;
46
sigdensity()47 void pskeval::sigdensity() {
48 int ihbw = (int)(0.6*bw);
49 int ibw = 2 * ihbw;
50
51 double *vals = new double[ibw];
52 double sig = 0.0;
53 double val = 0.0;
54
55 int low = progdefaults.LowFreqCutoff;
56 if (low < ihbw) low = ihbw;
57 int high = progdefaults.HighFreqCutoff;
58 if (high > WF_FFTLEN - ihbw) high = WF_FFTLEN - ihbw;
59 int nbr = high - low;
60
61 sigmin = 1e6;
62
63 for (int i = 0; i < ibw; i++) {
64 val = vals[i] = wf->Pwr(i + low - ihbw);
65 sig += val;
66 }
67 for (int i = 0, j = 0; i < nbr; i++) {
68 sigpwr[i + low] = decayavg(sigpwr[i + low], sig, 32);
69 sig -= vals[j];
70 val = vals[j] = wf->Pwr(i + ihbw + low);
71 sig += val;
72 if (++j == ibw) j = 0;
73 if (sig < sigmin) sigmin = sig;
74 }
75
76 if (sigmin < 1e-8) sigmin = 1e-8;
77 delete [] vals;
78 }
79
sigpeak(int & f,int f1,int f2)80 double pskeval::sigpeak(int &f, int f1, int f2)
81 {
82 double peak = 0;
83 f1 -= bw;
84 if (f1 <= progdefaults.LowFreqCutoff) f1 = progdefaults.LowFreqCutoff;
85 f2 += bw;
86 if (f2 >= progdefaults.HighFreqCutoff) f2 = progdefaults.HighFreqCutoff;
87
88 int fa = f2, fb = f1;
89
90 for (int i = f1; i < f2; i++) if (sigpwr[i] > peak) peak = sigpwr[i];
91 if (!peak) return 0;
92 for (int i = f1; i < f2; i++)
93 if (sigpwr[i] > peak*0.75) fb = i;
94 for (int i = f2; i > f1; i--)
95 if (sigpwr[i] > peak*0.75) fa = i;
96 if (fa > fb) return 0;
97 f = (fa + fb) / 2;
98 return peak / sigmin / bw;
99 }
100
peak(int & f0,int f1,int f2,double db)101 double pskeval::peak(int &f0, int f1, int f2, double db)
102 {
103 double peak = 0;
104
105 int fa = f2, fb = f1;
106 double level = pow(10, (10 + db) / 10.0);
107
108 //step 1
109 for (int i = f1; i < f2; i++) if (sigpwr[i] > peak) peak = sigpwr[i];
110
111 if (((peak-sigmin) / sigmin ) < level) {
112 return 0;
113 }
114
115 for (int i = f1; i < f2; i++)
116 if (sigpwr[i] > peak*0.75) fb = i;
117 for (int i = f2; i > f1; i--)
118 if (sigpwr[i] > peak*0.75) fa = i;
119 if (fa > fb) {
120 return 0;
121 }
122 f0 = (fa + fb) / 2;
123 //step 2
124 f1 = f0 - 1.5*bw;
125 if (f1 < bw) f1 = bw;
126 f2 = f0 + 1.5*bw;
127 fb = f1; fa = f2;
128 peak = 0;
129 for (int i = f1; i < f2; i++) if (sigpwr[i] > peak) peak = sigpwr[i];
130 for (int i = f1; i < f2; i++)
131 if (sigpwr[i] > peak*0.75) fb = i;
132 for (int i = f2; i > f1; i--)
133 if (sigpwr[i] > peak*0.75) fa = i;
134 if (fa > fb) {
135 return 0;
136 }
137 f0 = (fa + fb) / 2;
138 return (peak - sigmin) / sigmin ;
139 }
140
clear()141 void pskeval::clear() {
142 for (int i = 0; i < WF_FFTLEN; i++) sigpwr[i] = 0.0;
143 }
144