kopia lustrzana https://github.com/jamescoxon/dl-fldigi
Upstream version 2.09I
rodzic
bf19d9d6f8
commit
e2083f2f0c
|
|
@ -4,7 +4,7 @@
|
|||
AC_COPYRIGHT([Copyright (C) 2007 Stelios Bounanos, M0GLD (m0gld AT enotty DOT net)])
|
||||
|
||||
AC_PREREQ(2.61)
|
||||
AC_INIT([fldigi], [2.09H], [w1hkj AT w1hkj DOT com])
|
||||
AC_INIT([fldigi], [2.09I], [w1hkj AT w1hkj DOT com])
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
AM_INIT_AUTOMAKE([-Wall foreign std-options 1.9.6])
|
||||
AM_MAINTAINER_MODE
|
||||
|
|
|
|||
|
|
@ -1,3 +1,11 @@
|
|||
// special test version of Viewer.cxx
|
||||
//
|
||||
// To enable REGULAR EXPRESSION EVALUATION FOR THE FIND STRING
|
||||
// uncomment the following line
|
||||
|
||||
#define REGEX
|
||||
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "Viewer.h"
|
||||
|
|
@ -17,6 +25,10 @@
|
|||
|
||||
string bwsrfreq;
|
||||
string bwsrline[MAXCHANNELS];
|
||||
#ifndef REGEX
|
||||
string ucaseline[MAXCHANNELS];
|
||||
string tofind;
|
||||
#endif
|
||||
|
||||
static int brwsFreq[MAXCHANNELS];
|
||||
static int freq;
|
||||
|
|
@ -73,6 +85,7 @@ string fline;
|
|||
return fline;
|
||||
}
|
||||
|
||||
#ifdef REGEX
|
||||
regex_t* seek_re = 0;
|
||||
void re_comp(const char* needle)
|
||||
{
|
||||
|
|
@ -111,6 +124,8 @@ char* strcasestr(const char* haystack, const char* needle)
|
|||
}
|
||||
#endif // !HAVE_STRCASESTR
|
||||
|
||||
#endif // REGEX
|
||||
|
||||
void pskBrowser::resize(int x, int y, int w, int h) {
|
||||
unsigned int nuchars = (w - cols[0] - (sbarwidth + border)) / cwidth;
|
||||
string bline;
|
||||
|
|
@ -121,11 +136,20 @@ void pskBrowser::resize(int x, int y, int w, int h) {
|
|||
if (len > nuchars)
|
||||
bwsrline[i] = bwsrline[i].substr(len - nuchars);
|
||||
bline = freqformat(i);
|
||||
#ifndef REGEX
|
||||
if (!tofind.empty())
|
||||
if (ucaseline[i].find(tofind) != string::npos)
|
||||
bline.append(dkred);
|
||||
else if (!progdefaults.myCall.empty())
|
||||
if (ucaseline[i].find(progdefaults.myCall) != string::npos)
|
||||
bline.append(dkgreen);
|
||||
#else
|
||||
if (re_find(bwsrline[i].c_str()))
|
||||
bline.append(dkred);
|
||||
else if (!progdefaults.myCall.empty() &&
|
||||
strcasestr(bwsrline[i].c_str(), progdefaults.myCall.c_str()))
|
||||
bline.append(dkgreen);
|
||||
#endif
|
||||
bline.append("@.").append(bwsrline[i]);
|
||||
Fl_Hold_Browser::add(bline.c_str());
|
||||
}
|
||||
|
|
@ -223,6 +247,9 @@ void ClearViewer() {
|
|||
|
||||
bline = freqformat(i);
|
||||
bwsrline[i].clear();
|
||||
#ifndef REGEX
|
||||
ucaseline[i].clear();
|
||||
#endif
|
||||
brwsViewer->add(bline.c_str());
|
||||
}
|
||||
if (progdefaults.VIEWERshowfreq)
|
||||
|
|
@ -256,7 +283,13 @@ static void cb_brwsViewer(Fl_Hold_Browser*, void*) {
|
|||
|
||||
static void cb_Seek(Fl_Input *, void *)
|
||||
{
|
||||
#ifndef REGEX
|
||||
tofind = inpSeek->value();
|
||||
for (size_t i = 0; i < tofind.length(); i++)
|
||||
tofind[i] = toupper(tofind[i]);
|
||||
#else
|
||||
re_comp(inpSeek->value());
|
||||
#endif
|
||||
}
|
||||
|
||||
static void cb_Squelch(Fl_Slider *, void *)
|
||||
|
|
@ -360,22 +393,47 @@ void viewaddchr(int ch, int freq, char c) {
|
|||
|
||||
int index = progdefaults.VIEWERchannels - 1 - ch;
|
||||
if (progdefaults.VIEWERmarquee) {
|
||||
if (bwsrline[index].length() > progStatus.VIEWERnchars )
|
||||
if (bwsrline[index].length() > progStatus.VIEWERnchars ) {
|
||||
bwsrline[index].erase(0,1);
|
||||
if (c >= ' ' && c <= '~')
|
||||
#ifndef REGEX
|
||||
ucaseline[index].erase(0,1);
|
||||
#endif
|
||||
}
|
||||
if (c >= ' ' && c <= '~') {
|
||||
bwsrline[index] += c;
|
||||
else
|
||||
#ifndef REGEX
|
||||
ucaseline[index] += toupper(c);
|
||||
#endif
|
||||
} else {
|
||||
bwsrline[index] += ' ';
|
||||
#ifndef REGEX
|
||||
ucaseline[index] += ' ';
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
if (c >= ' ' && c <= '~')
|
||||
if (c >= ' ' && c <= '~') {
|
||||
bwsrline[index] += c;
|
||||
else
|
||||
#ifndef REGEX
|
||||
ucaseline[index] += toupper(c);
|
||||
#endif
|
||||
} else {
|
||||
bwsrline[index] += ' ';
|
||||
#ifndef REGEX
|
||||
ucaseline[index] += ' ';
|
||||
#endif
|
||||
}
|
||||
if (bwsrline[index].length() > progStatus.VIEWERnchars)
|
||||
bwsrline[index].clear();
|
||||
}
|
||||
nuline = freqformat(index);
|
||||
|
||||
#ifndef REGEX
|
||||
if (!tofind.empty())
|
||||
if (ucaseline[index].find(tofind) != string::npos)
|
||||
nuline.append(dkred);
|
||||
else if (!progdefaults.myCall.empty())
|
||||
if (ucaseline[index].find(progdefaults.myCall) != string::npos)
|
||||
nuline.append(dkgreen);
|
||||
#else
|
||||
if (re_find(bwsrline[index].c_str())) {
|
||||
nuline.append(dkred);
|
||||
// if (chkBeep->value())
|
||||
|
|
@ -387,7 +445,7 @@ void viewaddchr(int ch, int freq, char c) {
|
|||
// if (chkBeep->value())
|
||||
// fl_beep();
|
||||
}
|
||||
|
||||
#endif
|
||||
nuline.append("@.").append(bwsrline[index]);
|
||||
brwsViewer->text(1 + index, nuline.c_str());
|
||||
brwsViewer->redraw();
|
||||
|
|
@ -398,6 +456,9 @@ void viewclearchannel(int ch)
|
|||
int index = progdefaults.VIEWERchannels - 1 - ch;
|
||||
string nuline = freqformat(index);
|
||||
bwsrline[index] = "";
|
||||
#ifndef REGEX
|
||||
ucaseline[index] = "";
|
||||
#endif
|
||||
brwsViewer->text( 1 + index, nuline.c_str());
|
||||
brwsViewer->redraw();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,13 +28,14 @@
|
|||
#include "complex.h"
|
||||
#include "trx.h"
|
||||
#include "filters.h"
|
||||
#include "fldigi-config.h"
|
||||
|
||||
//=====================================================================
|
||||
#define VPSKSAMPLERATE (8000)
|
||||
#define VSNTHRESHOLD 2.0
|
||||
#define VSNTHRESHOLD 2.0 // 3 db s/n
|
||||
#define VAFCDECAY 8
|
||||
#define MAXCHANNELS 30
|
||||
#define VSEARCHWIDTH 60
|
||||
#define VSEARCHWIDTH 50
|
||||
#define VSIGSEARCH 5
|
||||
#define VWAITCOUNT 4
|
||||
//=====================================================================
|
||||
|
|
@ -58,6 +59,11 @@ private:
|
|||
|
||||
C_FIR_filter *fir1[MAXCHANNELS];
|
||||
C_FIR_filter *fir2[MAXCHANNELS];
|
||||
|
||||
double sigpwr[4000];
|
||||
double sigavg;
|
||||
double sigmin;
|
||||
Cmovavg *power[MAXCHANNELS];
|
||||
|
||||
int bits[MAXCHANNELS];
|
||||
double bitclk[MAXCHANNELS];
|
||||
|
|
@ -75,6 +81,8 @@ private:
|
|||
|
||||
void findsignal(int);
|
||||
void afc(int);
|
||||
void sigdensity();
|
||||
double sigpeak(int &f, int f1, int f2);
|
||||
|
||||
public:
|
||||
viewpsk(trx_mode mode);
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include "fft.h"
|
||||
#include "sound.h"
|
||||
#include "globals.h"
|
||||
#include "fldigi-config.h"
|
||||
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/fl_draw.H>
|
||||
|
|
@ -271,6 +272,7 @@ private:
|
|||
void drawgrayWF();
|
||||
void drawspectrum();
|
||||
void drawsignal();
|
||||
|
||||
|
||||
protected:
|
||||
public:
|
||||
|
|
@ -280,6 +282,10 @@ public:
|
|||
int newcarrier;
|
||||
int oldcarrier;
|
||||
bool tmp_carrier;
|
||||
double Pwr(int i) {
|
||||
if ( i > 0 && i < IMAGE_WIDTH) return pwr[i];
|
||||
return 0.0;
|
||||
}
|
||||
};
|
||||
|
||||
class waterfall: public Fl_Group {
|
||||
|
|
@ -354,7 +360,7 @@ public:
|
|||
qsy->deactivate();
|
||||
wfdisp->useBands(!on);
|
||||
}
|
||||
|
||||
double Pwr(int i) { return wfdisp->Pwr(i); }
|
||||
|
||||
int handle(int event);
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -53,7 +53,14 @@ viewpsk::viewpsk(trx_mode pskmode)
|
|||
for (int i = 0; i < MAXCHANNELS; i++) {
|
||||
fir1[i] = (C_FIR_filter *)0;
|
||||
fir2[i] = (C_FIR_filter *)0;
|
||||
power[i] = (Cmovavg *)0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4000; i++)
|
||||
sigpwr[i] = 0.0;
|
||||
sigavg = 0.0;
|
||||
sigmin = 1e6;
|
||||
|
||||
viewmode = MODE_PREV;
|
||||
restart(pskmode);
|
||||
}
|
||||
|
|
@ -63,6 +70,7 @@ viewpsk::~viewpsk()
|
|||
for (int i = 0; i < MAXCHANNELS; i++) {
|
||||
if (fir1[i]) delete fir1[i];
|
||||
if (fir2[i]) delete fir2[i];
|
||||
if (power[i]) delete power[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -126,6 +134,9 @@ void viewpsk::restart(trx_mode pskmode)
|
|||
if (fir2[i]) delete fir2[i];
|
||||
fir2[i] = new C_FIR_filter();
|
||||
fir2[i]->init(FIRLEN, 1, fir2c, fir2c);
|
||||
|
||||
if (power[i]) delete power[i];
|
||||
power[i] = new Cmovavg(8);
|
||||
}
|
||||
|
||||
bandwidth = VPSKSAMPLERATE / symbollen;
|
||||
|
|
@ -133,9 +144,58 @@ void viewpsk::restart(trx_mode pskmode)
|
|||
init();
|
||||
}
|
||||
|
||||
int sigcnt = 0;
|
||||
//=============================================================================
|
||||
//========================== viewpsk signal evaluation ========================
|
||||
//=============================================================================
|
||||
void viewpsk::sigdensity() {
|
||||
sigcnt++;
|
||||
double sig = 0.0;
|
||||
double val;
|
||||
int hbw = (int)(bandwidth / 2);
|
||||
int twohbw = 2 * hbw;
|
||||
int flower = progdefaults.VIEWERstart - 50; //nomfreq[0] - 50;
|
||||
int fupper = flower + 100 * progdefaults.VIEWERchannels + 100; //nomfreq[MAXCHANNELS-1] + 50;
|
||||
double *vals = new double[twohbw + 1];
|
||||
int j = -1;
|
||||
sigavg = 0.0;
|
||||
// sigmin = 1e6;
|
||||
for (int i = flower - hbw; i < fupper + hbw; i++) {
|
||||
j++;
|
||||
if (j == twohbw + 1) j = 0;
|
||||
val = wf->Pwr(i);
|
||||
if (i >= flower + twohbw) {
|
||||
sigpwr[i - hbw - 1] = sig;
|
||||
sig -= vals[j];
|
||||
}
|
||||
vals[j] = val;
|
||||
sig += val;
|
||||
sigavg += val;
|
||||
// if (sig && sig < sigmin) sigmin = sig;
|
||||
}
|
||||
|
||||
sigavg /= (fupper - flower - 100);
|
||||
//if (sigcnt == 32)
|
||||
// for (int i = flower; i <= fupper; i++)
|
||||
// std::cout << i << ", " << sigpwr[i] / sigavg << std::endl;
|
||||
|
||||
}
|
||||
|
||||
double viewpsk::sigpeak(int &f, int f1, int f2)
|
||||
{
|
||||
double peak = 0;
|
||||
f = (f1 + f2) / 2;
|
||||
for (int i = f1; i <= f2; i++)
|
||||
if (sigpwr[i] > peak) {
|
||||
peak = sigpwr[i];
|
||||
f = i;
|
||||
}
|
||||
return peak / sigavg;
|
||||
// return peak / sigmin;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//=========================== viewpsk receive routines ==========================
|
||||
//========================= viewpsk receive routines ==========================
|
||||
//=============================================================================
|
||||
|
||||
void viewpsk::rx_bit(int ch, int bit)
|
||||
|
|
@ -145,7 +205,8 @@ void viewpsk::rx_bit(int ch, int bit)
|
|||
if ((shreg[ch] & 3) == 0) {
|
||||
c = psk_varicode_decode(shreg[ch] >> 2);
|
||||
shreg[ch] = 0;
|
||||
if (c != -1) {
|
||||
// if (c != -1) {
|
||||
if (c >= ' ' && c <= 'z') {
|
||||
REQ(&viewaddchr, ch, (int)frequency[ch], c);
|
||||
timeout[ch] = now + progdefaults.VIEWERtimeout;
|
||||
}
|
||||
|
|
@ -154,23 +215,36 @@ void viewpsk::rx_bit(int ch, int bit)
|
|||
|
||||
void viewpsk::findsignal(int ch)
|
||||
{
|
||||
double ftest, sigpwr, noise;
|
||||
if (sigsearch[ch] > 0) {
|
||||
sigsearch[ch]--;
|
||||
ftest = wf->peakFreq((int)(frequency[ch]), VSEARCHWIDTH + (int)(bandwidth / 2));
|
||||
sigpwr = wf->powerDensity(ftest, bandwidth);
|
||||
noise = wf->powerDensity(ftest + 2 * bandwidth, bandwidth / 2) +
|
||||
wf->powerDensity(ftest - 2 * bandwidth, bandwidth / 2) + 1e-20;
|
||||
if (sigpwr/noise > VSNTHRESHOLD) { // larger than the search threshold
|
||||
if (ftest - nomfreq[ch] > VSEARCHWIDTH) ftest = nomfreq[ch] + VSEARCHWIDTH;
|
||||
if (ftest - nomfreq[ch] < -VSEARCHWIDTH) ftest = nomfreq[ch] - VSEARCHWIDTH;
|
||||
// double ftest, sigpwr, noise;
|
||||
if (waitcount[ch] > 0) {
|
||||
waitcount[ch]--;
|
||||
return;
|
||||
}
|
||||
|
||||
// ftest = wf->peakFreq((int)(frequency[ch]), VSEARCHWIDTH + (int)(bandwidth / 2));
|
||||
// sigpwr = wf->powerDensity(ftest, bandwidth);
|
||||
// noise = wf->powerDensity(ftest + 2 * bandwidth, bandwidth / 2) +
|
||||
// wf->powerDensity(ftest - 2 * bandwidth, bandwidth / 2) + 1e-20;
|
||||
|
||||
// if (sigpwr/noise > VSNTHRESHOLD) { // larger than the search threshold
|
||||
// if (ftest - nomfreq[ch] > VSEARCHWIDTH) ftest = nomfreq[ch] + VSEARCHWIDTH;
|
||||
// if (ftest - nomfreq[ch] < -VSEARCHWIDTH) ftest = nomfreq[ch] - VSEARCHWIDTH;
|
||||
// frequency[ch] = ftest;
|
||||
// } else { // less than the detection threshold
|
||||
// frequency[ch] = nomfreq[ch];
|
||||
// sigsearch[ch] = VSIGSEARCH;
|
||||
// }
|
||||
int ftest;
|
||||
int f1 = (int)(nomfreq[ch] - VSEARCHWIDTH);
|
||||
int f2 = (int)(nomfreq[ch] + VSEARCHWIDTH);
|
||||
if (sigpeak(ftest, f1, f2) > VSNTHRESHOLD) {
|
||||
frequency[ch] = ftest;
|
||||
} else { // less than the detection threshold
|
||||
frequency[ch] = nomfreq[ch];
|
||||
sigsearch[ch] = VSIGSEARCH;
|
||||
sigsearch[ch] = 0;
|
||||
}
|
||||
else
|
||||
frequency[ch] = nomfreq[ch];
|
||||
freqerr[ch] = 0.0;
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
void viewpsk::afc(int ch)
|
||||
|
|
@ -225,12 +299,16 @@ void viewpsk::rx_symbol(int ch, complex symbol)
|
|||
default:
|
||||
if (metric[ch] > progdefaults.VIEWERsquelch)
|
||||
dcd[ch] = true;
|
||||
else
|
||||
else
|
||||
dcd[ch] = false;
|
||||
}
|
||||
|
||||
if (dcd[ch] == true)
|
||||
rx_bit(ch, !bits[ch]);
|
||||
else {
|
||||
sigsearch[ch] = 1;
|
||||
waitcount[ch] = VWAITCOUNT;
|
||||
}
|
||||
}
|
||||
|
||||
int viewpsk::rx_process(const double *buf, int len)
|
||||
|
|
@ -244,6 +322,7 @@ int viewpsk::rx_process(const double *buf, int len)
|
|||
complex z[MAXCHANNELS];
|
||||
|
||||
now = time(NULL);
|
||||
sigdensity();
|
||||
|
||||
while (len-- > 0) {
|
||||
// process all CHANNELS (25)
|
||||
|
|
@ -286,28 +365,38 @@ int viewpsk::rx_process(const double *buf, int len)
|
|||
}
|
||||
for (int channel = 0; channel < progdefaults.VIEWERchannels; channel++) {
|
||||
if (timeout[channel] != -1 && timeout[channel] < now) {
|
||||
frequency[channel] = nomfreq[channel];
|
||||
REQ( &viewclearchannel, channel);
|
||||
timeout[channel] = -1;
|
||||
}
|
||||
// if (sigpwr[(int)(frequency[channel])] / sigmin < VSNTHRESHOLD)
|
||||
if (sigpwr[(int)(frequency[channel])] / sigavg < VSNTHRESHOLD)
|
||||
sigsearch[channel] = 1;
|
||||
if (sigsearch[channel])
|
||||
findsignal(channel);
|
||||
|
||||
/* if (sigsearch[channel])
|
||||
findsignal(channel);
|
||||
else {
|
||||
if (waitcount[channel] > 0) {
|
||||
--waitcount[channel];
|
||||
if (waitcount[channel] == 0) {
|
||||
sigsearch[channel] = VSIGSEARCH;
|
||||
// sigsearch[channel] = VSIGSEARCH;
|
||||
sigsearch[channel] = 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
double E1 = wf->powerDensity(frequency[channel], bandwidth);
|
||||
double E2 = wf->powerDensity(frequency[channel] - 2 * bandwidth, bandwidth/2) +
|
||||
wf->powerDensity(frequency[channel] + 2 * bandwidth, bandwidth/2);
|
||||
if ( E1/ E2 <= VSNTHRESHOLD) {
|
||||
// double E1 = wf->powerDensity(frequency[channel], bandwidth);
|
||||
// double E2 = wf->powerDensity(frequency[channel] - 2 * bandwidth, bandwidth/2) +
|
||||
// wf->powerDensity(frequency[channel] + 2 * bandwidth, bandwidth/2);
|
||||
// if ( E1/ E2 <= VSNTHRESHOLD) {
|
||||
if (sigpwr[(int)(frequency[channel])] / sigavg < VSNTHRESHOLD) {
|
||||
waitcount[channel] = VWAITCOUNT;
|
||||
sigsearch[channel] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Ładowanie…
Reference in New Issue