kopia lustrzana https://github.com/jamescoxon/dl-fldigi
Merge with upstream
commit
3248b76856
|
@ -1,5 +1,9 @@
|
|||
Change Log:
|
||||
|
||||
2.10 1) Added history (ctrl-Left-click in waterfall). Available after tracking
|
||||
has started. This does not start a new signal acquisition.
|
||||
2) Psk and ViewPsk use shared signal detection class
|
||||
|
||||
2.09 1) Modified src/Makefile.am for FreeBSD name space clash
|
||||
2) Added psk multi-channel viewer with regex search capability
|
||||
3) Rewrote audio capture/playback/generate routines to use the
|
||||
|
|
|
@ -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.09], [w1hkj AT w1hkj DOT com])
|
||||
AC_INIT([fldigi], [2.10A], [w1hkj AT w1hkj DOT com])
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
AM_INIT_AUTOMAKE([-Wall foreign std-options 1.9.6])
|
||||
AM_MAINTAINER_MODE
|
||||
|
|
|
@ -154,6 +154,7 @@ fldigi_SOURCES += \
|
|||
include/viewpsk.h \
|
||||
include/pskcoeff.h \
|
||||
include/pskvaricode.h \
|
||||
include/pskeval.h \
|
||||
include/ptt.h \
|
||||
include/qrunner.h \
|
||||
include/qrzcall.h \
|
||||
|
@ -217,6 +218,7 @@ fldigi_SOURCES += \
|
|||
psk/pskcoeff.cxx \
|
||||
psk/pskvaricode.cxx \
|
||||
psk/viewpsk.cxx \
|
||||
psk/pskeval.cxx \
|
||||
qrunner/fqueue.h \
|
||||
qrunner/qrunner.cxx \
|
||||
rigcontrol/FreqControl.cxx \
|
||||
|
|
|
@ -965,8 +965,8 @@ Fl_Menu_Item menu_[] = {
|
|||
{" ", 0, 0, 0, FL_MENU_INACTIVE, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
{"Rig", 0, (Fl_Callback*)cb_mnuRig, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
{" ", 0, 0, 0, FL_MENU_INACTIVE, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
{"Viewer", 0, (Fl_Callback*)cb_mnuViewer, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
|
||||
{"Viewer", 0, (Fl_Callback*)cb_mnuViewer, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
{" ", 0, 0, 0, FL_MENU_INACTIVE, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
|
||||
{"Help", 0, 0, 0, FL_SUBMENU, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
|
|
|
@ -89,7 +89,7 @@ public:
|
|||
double get_squelch() { return squelch; }
|
||||
void set_sqlchOnOff(bool val) {squelchon = val;}
|
||||
bool get_sqlchOnOff() { return squelchon;}
|
||||
void set_afcOnOff(bool val) {afcon = val;}
|
||||
void set_afcOnOff(int val) {afcon = val;}
|
||||
bool get_afcOnOff() { return afcon;}
|
||||
|
||||
// void set_mode(trx_mode);
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
#define PipeLen (64)
|
||||
|
||||
#define SNTHRESHOLD 2.0
|
||||
#define AFCDECAY 8
|
||||
#define AFCDECAYSLOW 8
|
||||
//=====================================================================
|
||||
|
||||
class psk : public modem {
|
||||
|
@ -53,6 +53,7 @@ private:
|
|||
|
||||
C_FIR_filter *fir1;
|
||||
C_FIR_filter *fir2;
|
||||
// C_FIR_filter *fir3;
|
||||
double *fir1c;
|
||||
double *fir2c;
|
||||
|
||||
|
@ -69,6 +70,7 @@ private:
|
|||
int dcd;
|
||||
int dcdbits;
|
||||
complex quality;
|
||||
|
||||
void rx_symbol(complex symbol);
|
||||
void rx_bit(int bit);
|
||||
void rx_qpsk(int bits);
|
||||
|
@ -78,6 +80,8 @@ private:
|
|||
double I11, I12, I21, I22, I31, I32;
|
||||
double snratio, s2n, imdratio, imd;
|
||||
double E1, E2, E3;
|
||||
double twopi;
|
||||
|
||||
// complex thirdorder;
|
||||
// tx variables & functions
|
||||
double *tx_shape;
|
||||
|
@ -91,6 +95,7 @@ private:
|
|||
void findsignal();
|
||||
void phaseafc();
|
||||
void afc();
|
||||
void coreafc();
|
||||
|
||||
public:
|
||||
psk(trx_mode mode);
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
// pskeval.cxx -- psk signal evaluator
|
||||
//
|
||||
// Copyright (C) 2008
|
||||
// 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 2 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, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _PSKEVAL_H
|
||||
#define _PSKEVAL_H
|
||||
|
||||
#include "complex.h"
|
||||
#include "trx.h"
|
||||
#include "filters.h"
|
||||
#include "fldigi-config.h"
|
||||
#include "waterfall.h"
|
||||
|
||||
#define FLOWER 200
|
||||
#define FUPPER 4000
|
||||
|
||||
class pskeval {
|
||||
private:
|
||||
double sigpwr[FFT_LEN];
|
||||
double sigavg;
|
||||
double bw;
|
||||
public:
|
||||
pskeval();
|
||||
~pskeval();
|
||||
void clear();
|
||||
void setbw(double w) { bw = w;}
|
||||
void sigdensity();
|
||||
double sigpeak(int &f, int f1, int f2);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -53,4 +53,6 @@ extern modem *active_modem;
|
|||
|
||||
extern cSound *scard;
|
||||
|
||||
extern bool bHistory;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
// psk.h -- psk modem
|
||||
// viewpsk.h -- psk modem
|
||||
//
|
||||
// Copyright (C) 2006
|
||||
// Copyright (C) 2008
|
||||
// Dave Freese, W1HKJ
|
||||
//
|
||||
// This file is part of fldigi. Adapted from code contained in gmfsk source code
|
||||
|
|
|
@ -30,11 +30,13 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <iomanip>
|
||||
|
||||
#include "psk.h"
|
||||
#include "waterfall.h"
|
||||
#include "configuration.h"
|
||||
#include "viewpsk.h"
|
||||
#include "pskeval.h"
|
||||
|
||||
extern waterfall *wf;
|
||||
|
||||
|
@ -47,6 +49,7 @@ extern waterfall *wf;
|
|||
|
||||
// Change the following for DCD low pass filter adjustment
|
||||
#define SQLCOEFF 0.01
|
||||
#define SQLDECAY 100
|
||||
|
||||
//=====================================================================
|
||||
|
||||
|
@ -56,6 +59,7 @@ extern waterfall *wf;
|
|||
|
||||
char pskmsg[80];
|
||||
viewpsk *pskviewer = (viewpsk *)0;
|
||||
pskeval *evalpsk = (pskeval *)0;
|
||||
|
||||
void psk::tx_init(cSound *sc)
|
||||
{
|
||||
|
@ -86,6 +90,8 @@ void psk::restart()
|
|||
{
|
||||
if (!pskviewer) pskviewer = new viewpsk(mode);
|
||||
else pskviewer->restart(mode);
|
||||
if (!evalpsk) evalpsk = new pskeval;
|
||||
evalpsk->setbw(bandwidth);
|
||||
}
|
||||
|
||||
void psk::init()
|
||||
|
@ -107,6 +113,8 @@ psk::~psk()
|
|||
psk::psk(trx_mode pskmode) : modem()
|
||||
{
|
||||
mode = pskmode;
|
||||
|
||||
twopi = 2.0 * M_PI;
|
||||
|
||||
switch (mode) {
|
||||
case MODE_BPSK31:
|
||||
|
@ -172,6 +180,7 @@ psk::psk(trx_mode pskmode) : modem()
|
|||
|
||||
wsincfilt(fir1c, 1.0 / symbollen, true); // creates fir1c matched sin(x)/x filter w blackman
|
||||
wsincfilt(fir2c, 1.0 / 16.0, true); // creates fir2c matched sin(x)/x filter w blackman
|
||||
|
||||
// wsincfilt(fir1c, 1.0 / symbollen, false); // creates fir1c matched sin(x)/x filter w hamming
|
||||
// wsincfilt(fir2c, 1.0 / 16.0, false); // creates fir2c matched sin(x)/x filter w hamming
|
||||
// wsincfilt(fir2c, 1.0 / 22.0, false); // 1/22 with Hamming window
|
||||
|
@ -185,6 +194,7 @@ psk::psk(trx_mode pskmode) : modem()
|
|||
fir2 = new C_FIR_filter();
|
||||
fir2->init(FIRLEN, 1, fir2c, fir2c);
|
||||
|
||||
|
||||
if (_qpsk) {
|
||||
enc = new encoder(K, POLY1, POLY2);
|
||||
dec = new viterbi(K, POLY1, POLY2);
|
||||
|
@ -330,31 +340,40 @@ void psk::findsignal()
|
|||
}
|
||||
} else {
|
||||
// normal signal search
|
||||
searchBW = progdefaults.SearchRange;
|
||||
ftest = wf->peakFreq((int)(frequency), searchBW);
|
||||
sigpwr = wf->powerDensity(ftest, bandwidth);
|
||||
noise = wf->powerDensity(ftest + 2 * bandwidth / 2, bandwidth / 2) +
|
||||
wf->powerDensity(ftest - 2 * bandwidth / 2, bandwidth / 2) + 1e-20;
|
||||
if (sigpwr/noise > SNTHRESHOLD) { // larger than the detection threshold)
|
||||
frequency = ftest;
|
||||
set_freq(frequency);
|
||||
freqerr = 0.0;
|
||||
}
|
||||
int ftest;
|
||||
int f1 = (int)(frequency - progdefaults.SearchRange/2);
|
||||
int f2 = (int)(frequency + progdefaults.SearchRange/2);
|
||||
if (evalpsk->sigpeak(ftest, f1, f2) > SNTHRESHOLD ){//SNTHRESHOLD) {
|
||||
frequency = ftest;
|
||||
set_freq(frequency);
|
||||
freqerr = 0.0;
|
||||
}
|
||||
// searchBW = progdefaults.SearchRange;
|
||||
// ftest = wf->peakFreq((int)(frequency), searchBW);
|
||||
// sigpwr = wf->powerDensity(ftest, bandwidth);
|
||||
// noise = wf->powerDensity(ftest + 2 * bandwidth / 2, bandwidth / 2) +
|
||||
// wf->powerDensity(ftest - 2 * bandwidth / 2, bandwidth / 2) + 1e-20;
|
||||
// if (sigpwr/noise > SNTHRESHOLD) { // larger than the detection threshold)
|
||||
// frequency = ftest;
|
||||
// set_freq(frequency);
|
||||
// freqerr = 0.0;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void psk::phaseafc()
|
||||
{
|
||||
double error;
|
||||
error = (phase - bits * M_PI / 2);
|
||||
if (error < M_PI / 2)
|
||||
error += 2 * M_PI;
|
||||
if (error > M_PI / 2)
|
||||
error -= 2 * M_PI;
|
||||
error *= ((samplerate / (symbollen * 2 * M_PI)/16));
|
||||
error = (phase - bits * M_PI / 2.0);
|
||||
if (error < -M_PI/2.0)
|
||||
error += twopi;
|
||||
if (error > M_PI/2.0)
|
||||
error -= twopi;
|
||||
error *= ((samplerate / twopi) / (16.0 * symbollen));
|
||||
if (fabs(error) < bandwidth) {
|
||||
freqerr = decayavg( freqerr, error, AFCDECAY);
|
||||
freqerr = decayavg( freqerr, error, AFCDECAYSLOW);
|
||||
frequency -= freqerr;
|
||||
set_freq (frequency);
|
||||
}
|
||||
|
@ -378,7 +397,7 @@ void psk::rx_symbol(complex symbol)
|
|||
prevsymbol = symbol;
|
||||
|
||||
if (phase < 0)
|
||||
phase += 2 * M_PI;
|
||||
phase += twopi;
|
||||
if (_qpsk) {
|
||||
bits = ((int) (phase / M_PI_2 + 0.5)) & 3;
|
||||
n = 4;
|
||||
|
@ -389,9 +408,9 @@ void psk::rx_symbol(complex symbol)
|
|||
// simple low pass filter for quality of signal
|
||||
// quality.re = 0.02 * cos(n * phase) + 0.98 * quality.re;
|
||||
// quality.im = 0.02 * sin(n * phase) + 0.98 * quality.im;
|
||||
quality.re = SQLCOEFF * cos(n * phase) + (1.0 - SQLCOEFF) * quality.re;
|
||||
quality.im = SQLCOEFF * sin(n * phase) + (1.0 - SQLCOEFF) * quality.im;
|
||||
|
||||
quality.re = decayavg(quality.re, cos(n*phase), SQLDECAY);
|
||||
quality.im = decayavg(quality.im, cos(n*phase), SQLDECAY);
|
||||
|
||||
metric = 100.0 * quality.norm();
|
||||
|
||||
dcdshreg = (dcdshreg << 2) | bits;
|
||||
|
@ -460,11 +479,15 @@ char bitstatus[100];
|
|||
int psk::rx_process(const double *buf, int len)
|
||||
{
|
||||
double delta;
|
||||
complex z;
|
||||
complex z, z2;//, z3;
|
||||
|
||||
if (pskviewer) pskviewer->rx_process(buf, len);
|
||||
|
||||
delta = 2.0 * M_PI * frequency / samplerate;
|
||||
if (pskviewer && !bHistory) pskviewer->rx_process(buf, len);
|
||||
if (evalpsk) evalpsk->sigdensity();
|
||||
|
||||
if (afcon == 2)
|
||||
sigsearch = 0;
|
||||
|
||||
delta = twopi * frequency / samplerate;
|
||||
|
||||
signalquality();
|
||||
|
||||
|
@ -474,27 +497,30 @@ int psk::rx_process(const double *buf, int len)
|
|||
buf++;
|
||||
phaseacc += delta;
|
||||
if (phaseacc > M_PI)
|
||||
phaseacc -= 2.0 * M_PI;
|
||||
phaseacc -= twopi;
|
||||
// Filter and downsample
|
||||
// by 16 (psk31, qpsk31)
|
||||
// by 8 (psk63, qpsk63)
|
||||
// by 4 (psk125, qpsk125)
|
||||
// by 2 (psk250, qpsk250)
|
||||
// first filter
|
||||
if (fir1->run( z, z )) { // fir1 returns true every Nth sample
|
||||
// final filter
|
||||
fir2->run( z, z ); // fir3 returns value on every sample
|
||||
|
||||
fir2->run( z, z2 ); // fir2 returns value on every sample
|
||||
|
||||
// fir3->run( z, z3);
|
||||
// coreafc(z3);
|
||||
|
||||
int idx = (int) bitclk;
|
||||
double sum = 0.0;
|
||||
double ampsum = 0.0;
|
||||
syncbuf[idx] = 0.8 * syncbuf[idx] + 0.2 * z.mag();
|
||||
syncbuf[idx] = 0.8 * syncbuf[idx] + 0.2 * z2.mag();
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
sum += (syncbuf[i] - syncbuf[i+8]);
|
||||
ampsum += (syncbuf[i] + syncbuf[i+8]);
|
||||
}
|
||||
// added correction as per PocketDigi
|
||||
// vastly improved performance with synchronous interference !!
|
||||
sum = (ampsum == 0 ? 0 : sum / ampsum);
|
||||
|
||||
bitclk -= sum / 5.0;
|
||||
|
@ -503,7 +529,7 @@ int psk::rx_process(const double *buf, int len)
|
|||
if (bitclk < 0) bitclk += 16.0;
|
||||
if (bitclk >= 16.0) {
|
||||
bitclk -= 16.0;
|
||||
rx_symbol(z);
|
||||
rx_symbol(z2);
|
||||
update_syncscope();
|
||||
afc();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
// pskeval.cxx -- psk signal evaluator
|
||||
//
|
||||
// Copyright (C) 2008
|
||||
// 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 2 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, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "pskeval.h"
|
||||
|
||||
//=============================================================================
|
||||
//========================== psk signal evaluation ============================
|
||||
//=============================================================================
|
||||
|
||||
double alpha = 0.125;
|
||||
|
||||
pskeval::pskeval() {
|
||||
bw = 31.25;
|
||||
clear();
|
||||
}
|
||||
|
||||
pskeval::~pskeval() {
|
||||
}
|
||||
|
||||
//static int evalcount = 1;
|
||||
|
||||
void pskeval::sigdensity() {
|
||||
double sig = 0.0;
|
||||
double val;
|
||||
int ihbw = (int)(bw / 2 + 0.5) + 1;
|
||||
int ibw = 2 * ihbw;
|
||||
int fstart = FLOWER + ibw;
|
||||
double *vals = new double[ibw + 1];
|
||||
for (int i = 0; i < ibw + 1; i++) vals[i] = 0.0;
|
||||
int j = -1;
|
||||
sigavg = 0.0;
|
||||
for (int i = FLOWER; i < IMAGE_WIDTH; i++) {
|
||||
j++;
|
||||
if (j == ibw + 1) j = 0;
|
||||
val = wf->Pwr(i);
|
||||
if (i >= fstart) {
|
||||
sigpwr[i - ihbw - 1] = (1-alpha)*sigpwr[i - ihbw - 1] + alpha * sig;
|
||||
// sigpwr[i - ihbw - 1] = sig;
|
||||
sig -= vals[j];
|
||||
}
|
||||
vals[j] = val;
|
||||
sig += val;
|
||||
sigavg += val;
|
||||
}
|
||||
sigavg /= (FFT_LEN - FLOWER);
|
||||
if (sigavg == 0) sigavg = 1e-20;
|
||||
// if (evalcount++ < 100) {
|
||||
// for (int i = FLOWER; i < IMAGE_WIDTH; i++)
|
||||
// std::cout << i << "," << sigpwr[i] / sigavg << std::endl;
|
||||
// std::cout.flush();
|
||||
// }
|
||||
}
|
||||
|
||||
double pskeval::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 / bw;
|
||||
}
|
||||
|
||||
void pskeval::clear() {
|
||||
for (int i = 0; i < FFT_LEN; i++) sigpwr[i] = 0.0;
|
||||
}
|
|
@ -34,6 +34,7 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "viewpsk.h"
|
||||
#include "pskeval.h"
|
||||
#include "pskcoeff.h"
|
||||
#include "pskvaricode.h"
|
||||
#include "waterfall.h"
|
||||
|
@ -42,6 +43,7 @@
|
|||
#include "qrunner.h"
|
||||
|
||||
extern waterfall *wf;
|
||||
extern pskeval *evalpsk;
|
||||
|
||||
//=====================================================================
|
||||
// Change the following for DCD low pass filter adjustment
|
||||
|
@ -144,22 +146,20 @@ 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;
|
||||
int flower = progdefaults.VIEWERstart - 50;
|
||||
int fupper = flower + 100 * progdefaults.VIEWERchannels + 100;
|
||||
double *vals = new double[twohbw + 1];
|
||||
int j = -1;
|
||||
sigavg = 0.0;
|
||||
// sigmin = 1e6;
|
||||
sigmin = 1e6;
|
||||
for (int i = flower - hbw; i < fupper + hbw; i++) {
|
||||
j++;
|
||||
if (j == twohbw + 1) j = 0;
|
||||
|
@ -171,14 +171,9 @@ void viewpsk::sigdensity() {
|
|||
vals[j] = val;
|
||||
sig += val;
|
||||
sigavg += val;
|
||||
// if (sig && sig < sigmin) sigmin = sig;
|
||||
if (sig > 0 && 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)
|
||||
|
@ -205,7 +200,7 @@ 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 == '\n') c = ' ';
|
||||
if (c >= ' ' && c <= 'z') {
|
||||
REQ(&viewaddchr, ch, (int)frequency[ch], c);
|
||||
timeout[ch] = now + progdefaults.VIEWERtimeout;
|
||||
|
@ -215,36 +210,21 @@ void viewpsk::rx_bit(int ch, int bit)
|
|||
|
||||
void viewpsk::findsignal(int ch)
|
||||
{
|
||||
// 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;
|
||||
sigsearch[ch] = 0;
|
||||
}
|
||||
else
|
||||
frequency[ch] = nomfreq[ch];
|
||||
freqerr[ch] = 0.0;
|
||||
// }
|
||||
int ftest;
|
||||
int f1 = (int)(nomfreq[ch] - VSEARCHWIDTH);
|
||||
int f2 = (int)(nomfreq[ch] + VSEARCHWIDTH);
|
||||
if (evalpsk->sigpeak(ftest, f1, f2) > VSNTHRESHOLD) {
|
||||
frequency[ch] = ftest;
|
||||
sigsearch[ch] = 0;
|
||||
}
|
||||
else
|
||||
frequency[ch] = nomfreq[ch];
|
||||
freqerr[ch] = 0.0;
|
||||
}
|
||||
|
||||
void viewpsk::afc(int ch)
|
||||
|
@ -322,7 +302,7 @@ int viewpsk::rx_process(const double *buf, int len)
|
|||
complex z[MAXCHANNELS];
|
||||
|
||||
now = time(NULL);
|
||||
sigdensity();
|
||||
// sigdensity();
|
||||
|
||||
while (len-- > 0) {
|
||||
// process all CHANNELS (25)
|
||||
|
@ -369,34 +349,10 @@ int viewpsk::rx_process(const double *buf, int len)
|
|||
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] = 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) {
|
||||
if (sigpwr[(int)(frequency[channel])] / sigavg < VSNTHRESHOLD) {
|
||||
waitcount[channel] = VWAITCOUNT;
|
||||
sigsearch[channel] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -73,6 +73,11 @@ short int *sidata;
|
|||
// is used asynchronously by the GUI thread.
|
||||
mbuffer<double, SCBLOCKSIZE * 2, 2> _trx_scdbl;
|
||||
|
||||
#define HISTSIZE 1024 * SCBLOCKSIZE
|
||||
double histbuff[HISTSIZE];
|
||||
size_t numinbuff = 0;
|
||||
bool bHistory = false;
|
||||
|
||||
static int dummy = 0;
|
||||
static bool trxrunning = false;
|
||||
#include "tune.cxx"
|
||||
|
@ -117,9 +122,25 @@ void trx_trx_receive_loop()
|
|||
if (numread == -1 || (trx_state != STATE_RX))
|
||||
break;
|
||||
if (numread > 0) {
|
||||
REQ(&waterfall::sig_data, wf, _trx_scdbl.c_array(), numread);
|
||||
active_modem->rx_process(_trx_scdbl, numread);
|
||||
_trx_scdbl.next(); // change buffers
|
||||
|
||||
if (bHistory) {
|
||||
active_modem->set_afcOnOff(0);
|
||||
active_modem->rx_process( histbuff, numinbuff );
|
||||
active_modem->set_afcOnOff(1);
|
||||
bHistory = false;
|
||||
}
|
||||
|
||||
active_modem->rx_process(_trx_scdbl, numread);
|
||||
|
||||
if (numinbuff + numread > HISTSIZE) {
|
||||
memcpy( &histbuff[0], &histbuff[numread], (numinbuff - numread)*sizeof(double));
|
||||
numinbuff -= numread;
|
||||
}
|
||||
for (int n = 0; n < numread; n++)
|
||||
histbuff[numinbuff++] = _trx_scdbl[n];
|
||||
|
||||
REQ(&waterfall::sig_data, wf, _trx_scdbl.c_array(), numread);
|
||||
_trx_scdbl.next(); // change buffers
|
||||
}
|
||||
}
|
||||
if (!scard->full_duplex())
|
||||
|
|
|
@ -630,9 +630,11 @@ void WFdisp::update_waterfall() {
|
|||
p4 = p3;
|
||||
for (int col = 0; col < disp_width; col++) {
|
||||
if (step == 4)
|
||||
sig = MAX( MAX ( MAX ( *p2, *(p2+1) ), *(p2+2) ), *(p2+3) );
|
||||
// sig = MAX( MAX ( MAX ( *p2, *(p2+1) ), *(p2+2) ), *(p2+3) );
|
||||
sig = (*p2+ *(p2+1)+ *(p2+2)+ *(p2+3))/4;
|
||||
else if (step == 2)
|
||||
sig = MAX( *p2, *(p2 + 1) );
|
||||
// sig = MAX( *p2, *(p2 + 1) );
|
||||
sig = (*p2 + *(p2 + 1))/2;
|
||||
else
|
||||
sig = *p2;
|
||||
*p4 = mag2RGBI[ sig ];
|
||||
|
@ -1405,12 +1407,16 @@ int WFdisp::handle(int event)
|
|||
}
|
||||
// fall through
|
||||
case FL_LEFT_MOUSE:
|
||||
newcarrier = cursorFreq(xpos);
|
||||
active_modem->set_freq(newcarrier);
|
||||
if (!(Fl::event_state() & FL_SHIFT))
|
||||
active_modem->set_sigsearch(SIGSEARCH);
|
||||
redrawCursor();
|
||||
restoreFocus();
|
||||
if ((Fl::event_state() & FL_CTRL))
|
||||
bHistory = true;
|
||||
else {
|
||||
newcarrier = cursorFreq(xpos);
|
||||
active_modem->set_freq(newcarrier);
|
||||
if (!(Fl::event_state() & FL_SHIFT))
|
||||
active_modem->set_sigsearch(SIGSEARCH);
|
||||
redrawCursor();
|
||||
restoreFocus();
|
||||
}
|
||||
break;
|
||||
case FL_MIDDLE_MOUSE:
|
||||
if (event == FL_DRAG)
|
||||
|
|
Ładowanie…
Reference in New Issue