* add IMD generator
  * modified IMD computation for continuous operation
    vice only during DCD
pull/4/head
David Freese 2016-02-25 05:18:30 -06:00
rodzic 4fec333973
commit 4c9f1404ca
6 zmienionych plików z 150 dodań i 47 usunięć

Wyświetl plik

@ -316,9 +316,13 @@ static void cb_noiseDB(Fl_Counter2* o, void*) {
progdefaults.s2n = o->value();
}
Fl_Check_Button *btnOffsetOn=(Fl_Check_Button *)0;
Fl_Counter *ctrl_freq_offset=(Fl_Counter *)0;
Fl_Check_Button *btnOffsetOn=(Fl_Check_Button *)0;
Fl_Check_Button *btn_imd_on=(Fl_Check_Button *)0;
Fl_Counter2 *xmtimd=(Fl_Counter2 *)0;
Fl_Group *tabUI=(Fl_Group *)0;
@ -5943,7 +5947,7 @@ Fl_Double_Window* ConfigureDialog() {
inpMyAntenna->when(FL_WHEN_RELEASE);
inpMyAntenna->labelsize(FL_NORMAL_SIZE);
} // Fl_Input2* inpMyAntenna
{ grpNoise = new Fl_Group(55, 231, 490, 114, _("Test Signal - Do NOT use with transmitter"));
{ grpNoise = new Fl_Group(55, 231, 490, 143, _("Test Signal - Do NOT use with transmitter"));
grpNoise->box(FL_ENGRAVED_FRAME);
grpNoise->align(Fl_Align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE));
grpNoise->hide();
@ -5952,7 +5956,7 @@ Fl_Double_Window* ConfigureDialog() {
btnNoiseOn->callback((Fl_Callback*)cb_btnNoiseOn);
o->value(progdefaults.noise);
} // Fl_Check_Button* btnNoiseOn
{ Fl_Counter2* o = noiseDB = new Fl_Counter2(312, 264, 130, 21, _("dB"));
{ Fl_Counter2* o = noiseDB = new Fl_Counter2(340, 264, 130, 21, _("dB"));
noiseDB->box(FL_UP_BOX);
noiseDB->color(FL_BACKGROUND_COLOR);
noiseDB->selection_color(FL_INACTIVE_COLOR);
@ -5969,16 +5973,35 @@ Fl_Double_Window* ConfigureDialog() {
o->value(progdefaults.s2n);
o->lstep(1);
} // Fl_Counter2* noiseDB
{ Fl_Counter* o = ctrl_freq_offset = new Fl_Counter(312, 304, 130, 21, _("freq-offset"));
{ btnOffsetOn = new Fl_Check_Button(93, 307, 70, 15, _("Offset on"));
btnOffsetOn->down_box(FL_DOWN_BOX);
} // Fl_Check_Button* btnOffsetOn
{ Fl_Counter* o = ctrl_freq_offset = new Fl_Counter(340, 304, 130, 21, _("freq-offset"));
ctrl_freq_offset->tooltip(_("ONLY FOR TESTING !"));
ctrl_freq_offset->minimum(-250);
ctrl_freq_offset->maximum(250);
ctrl_freq_offset->align(Fl_Align(FL_ALIGN_LEFT));
o->lstep(10);
} // Fl_Counter* ctrl_freq_offset
{ btnOffsetOn = new Fl_Check_Button(93, 307, 70, 15, _("Offset on"));
btnOffsetOn->down_box(FL_DOWN_BOX);
} // Fl_Check_Button* btnOffsetOn
{ btn_imd_on = new Fl_Check_Button(93, 342, 70, 15, _("ALC emulation on"));
btn_imd_on->down_box(FL_DOWN_BOX);
} // Fl_Check_Button* btn_imd_on
{ Fl_Counter2* o = xmtimd = new Fl_Counter2(340, 339, 130, 21, _("ALC level"));
xmtimd->box(FL_UP_BOX);
xmtimd->color(FL_BACKGROUND_COLOR);
xmtimd->selection_color(FL_INACTIVE_COLOR);
xmtimd->labeltype(FL_NORMAL_LABEL);
xmtimd->labelfont(0);
xmtimd->labelsize(14);
xmtimd->labelcolor(FL_FOREGROUND_COLOR);
xmtimd->minimum(0.5);
xmtimd->maximum(1);
xmtimd->step(0.01);
xmtimd->value(1);
xmtimd->align(Fl_Align(FL_ALIGN_LEFT));
xmtimd->when(FL_WHEN_CHANGED);
o->lstep(.1);
} // Fl_Counter2* xmtimd
grpNoise->end();
} // Fl_Group* grpNoise
tabOperator->end();

Wyświetl plik

@ -366,7 +366,7 @@ static const char szProsigns[] = "~|%|&|+|=|{|}|<|>|[|]| ";} {}
} {
Fl_Group tabOperator {
label Operator
callback {progdefaults.changed = true;} open selected
callback {progdefaults.changed = true;} open
tooltip {Operator information} xywh {0 25 600 355} when 1
} {
Fl_Group {} {
@ -427,8 +427,8 @@ progdefaults.changed = true;}
class Fl_Input2
}
Fl_Group grpNoise {
label {Test Signal - Do NOT use with transmitter} open
xywh {55 231 490 114} box ENGRAVED_FRAME align 21 hide
label {Test Signal - Do NOT use with transmitter} open selected
xywh {55 231 490 143} box ENGRAVED_FRAME align 21 hide
} {
Fl_Check_Button btnNoiseOn {
label {Noise on}
@ -439,20 +439,30 @@ progdefaults.changed = true;}
Fl_Counter noiseDB {
label dB
callback {progdefaults.s2n = o->value();}
xywh {312 264 130 21} align 4 minimum -18 maximum 60 value 20
xywh {340 264 130 21} align 4 minimum -18 maximum 60 value 20
code0 {o->value(progdefaults.s2n);}
code1 {o->lstep(1);}
class Fl_Counter2
}
Fl_Counter ctrl_freq_offset {
label {freq-offset}
tooltip {ONLY FOR TESTING !} xywh {312 304 130 21} align 4 minimum -250 maximum 250
code0 {o->lstep(10);}
}
Fl_Check_Button btnOffsetOn {
label {Offset on}
xywh {93 307 70 15} down_box DOWN_BOX
}
Fl_Counter ctrl_freq_offset {
label {freq-offset}
tooltip {ONLY FOR TESTING !} xywh {340 304 130 21} align 4 minimum -250 maximum 250
code0 {o->lstep(10);}
}
Fl_Check_Button btn_imd_on {
label {ALC emulation on}
xywh {93 342 70 15} down_box DOWN_BOX
}
Fl_Counter xmtimd {
label {ALC level}
xywh {340 339 130 21} align 4 minimum 0.5 maximum 1 step 0.01 value 1
code1 {o->lstep(.1);}
class Fl_Counter2
}
}
}
Fl_Group tabUI {

Wyświetl plik

@ -32,9 +32,11 @@ extern Fl_Group *grpNoise;
#include <FL/Fl_Check_Button.H>
extern Fl_Check_Button *btnNoiseOn;
extern Fl_Counter2 *noiseDB;
extern Fl_Check_Button *btnOffsetOn;
#include <FL/Fl_Counter.H>
extern Fl_Counter *ctrl_freq_offset;
extern Fl_Check_Button *btnOffsetOn;
extern Fl_Check_Button *btn_imd_on;
extern Fl_Counter2 *xmtimd;
extern Fl_Group *tabUI;
extern Fl_Tabs *tabsUI;
extern Fl_Group *tabBrowser;

Wyświetl plik

@ -83,6 +83,10 @@ private:
double *fir2c;
Cmovavg *snfilt;
Cmovavg *imdfilt;
Cmovavg *e0_filt;
Cmovavg *e1_filt;
Cmovavg *e2_filt;
bool displaysn;
double I1[NUM_FILTERS];
double I2[NUM_FILTERS];
@ -166,6 +170,9 @@ private:
double *tx_shape;
int preamble;
C_FIR_filter *xmtfilt;
void transmit(double *buf, int len);
void tx_carriers();
void tx_symbol(int sym);
void tx_bit(int bit);

Wyświetl plik

@ -51,6 +51,8 @@
#include "Viewer.h"
#include "macros.h"
#include "confdialog.h"
extern waterfall *wf;
// Change the following for DCD low pass filter adjustment
@ -153,6 +155,12 @@ void psk::tx_init(SoundBase *sc)
vphase = 0;
maxamp = 0;
double bw2 = 6.0 * bandwidth;
double flo = (get_txfreq_woffset() - bw2);
if (flo <= 0) flo = 0;
double fhi = (get_txfreq_woffset() + bw2);
if (fhi >= 0.48*samplerate) fhi = 0.48*samplerate;
xmtfilt->init_bandpass (127, 1, flo/samplerate, fhi/samplerate);
}
void psk::rx_init()
@ -179,7 +187,6 @@ void psk::rx_init()
else sigsearch = 0;
put_MODEstatus(mode);
resetSN_IMD();
imdValid = false;
afcmetric = 0.0;
// interleaver, split incoming bit stream into two, one late by one bit
rxbitstate = 0;
@ -223,6 +230,9 @@ psk::~psk()
}
if (snfilt) delete snfilt;
if (imdfilt) delete imdfilt;
if (e0_filt) delete e0_filt;
if (e1_filt) delete e1_filt;
if (e2_filt) delete e2_filt;
if (pskviewer) delete pskviewer;
if (evalpsk) delete evalpsk;
@ -233,6 +243,8 @@ psk::~psk()
if (Txinlv) delete Txinlv;
if (vestigial_sfft) delete vestigial_sfft;
if (xmtfilt) delete xmtfilt;
}
psk::psk(trx_mode pskmode) : modem()
@ -732,6 +744,9 @@ psk::psk(trx_mode pskmode) : modem()
snfilt = new Cmovavg(16);
imdfilt = new Cmovavg(16);
e0_filt = new Cmovavg(dcdbits / 2);
e1_filt = new Cmovavg(dcdbits / 2);
e2_filt = new Cmovavg(dcdbits / 2);
if (_disablefec) {
enc = NULL;
@ -827,6 +842,9 @@ psk::psk(trx_mode pskmode) : modem()
vestigial_sfft = new sfft(sfft_size, bin - 5, bin + 6); // 11 bins
for (int i = 0; i < 11; i++) sfft_bins[i] = cmplx(0,0);
}
xmtfilt = new C_FIR_filter();
}
//=============================================================================
@ -1059,6 +1077,10 @@ int waitcount = 0;
void psk::findsignal()
{
put_Status1("");
put_Status2("");
put_status("");
int ftest, f1, f2;
if (sigsearch > 0) {
@ -1171,7 +1193,6 @@ void psk::afc()
phaseafc();
}
void psk::rx_symbol(cmplx symbol, int car)
{
int n;
@ -1278,8 +1299,7 @@ void psk::rx_symbol(cmplx symbol, int car)
dcdshreg = ( dcdshreg << (symbits+1) ) | bits;
int set_dcdON = -1; // 1 sets DCD on ; 0 sets DCD off ; -1 does neither (no-op)
imdValid = false;
//printf("\n%.8X", dcdshreg);
switch (dcdshreg) {
// bpsk DCD on
@ -1360,11 +1380,12 @@ void psk::rx_symbol(cmplx symbol, int car)
}
}
displaysn = false;
if ( 1 == set_dcdON ) {
displaysn = true;
dcd = true;
acquire = 0;
quality = cmplx (1.0, 0.0);
imdValid = true;
if (progdefaults.Pskmails2nreport && (mailserver || mailclient))
s2n_sum = s2n_sum2 = s2n_ncount = 0.0;
//printf("\n DCD ON!!");
@ -1448,18 +1469,24 @@ void psk::rx_symbol(cmplx symbol, int car)
}
}
static double e0, e1, e2;
void psk::signalquality()
{
// double e0, e1, e2;
e0 = e0_filt->run(m_Energy[0]);
e1 = e1_filt->run(m_Energy[1]);
e2 = e2_filt->run(m_Energy[2]);
if (m_Energy[1])
snratio = snfilt->run(m_Energy[0]/m_Energy[1]);
if (((e0 - e1) > 0) && (e1 > 0))
snratio = (e0 - e1) / e1;
else
snratio = snfilt->run(1.0);
snratio = 1000.0;
if (m_Energy[0] && imdValid)
imdratio = imdfilt->run(m_Energy[2]/m_Energy[0]);
if (((e0 - e1) > 0) && ((e2 - e1) > 0) )
imdratio = (e2 - e1) / (e0 - e1);
else
imdratio = imdfilt->run(0.001);
imdratio = 0.001;
}
@ -1470,19 +1497,30 @@ void psk::update_syncscope()
display_metric(metric);
memset(msg1, 0, sizeof(msg1));
memset(msg2, 0, sizeof(msg2));
if (displaysn) {
memset(msg1, 0, sizeof(msg1));
memset(msg2, 0, sizeof(msg2));
s2n = 10.0*log10( snratio );
snprintf(msg1, sizeof(msg1)-1, "s/n %2d dB", (int)(floor(s2n)));
s2n = 10.0*log10( snratio );
snprintf(msg1, sizeof(msg1), "s/n %2.0f dB", s2n);
imd = 10.0*log10( imdratio );
snprintf(msg2, sizeof(msg2)-1, "imd %3d dB", (int)(floor(imd)));
imd = 10.0*log10( imdratio );
snprintf(msg2, sizeof(msg2), "imd %2.0f dB", imd);
if (imdValid) {
put_Status1(msg1, progdefaults.StatusTimeout, progdefaults.StatusDim ? STATUS_DIM : STATUS_CLEAR);
put_Status2(msg2, progdefaults.StatusTimeout, progdefaults.StatusDim ? STATUS_DIM : STATUS_CLEAR);
put_Status1( msg1,
progdefaults.StatusTimeout,
progdefaults.StatusDim ? STATUS_DIM : STATUS_CLEAR);
put_Status2( msg2,
progdefaults.StatusTimeout,
progdefaults.StatusDim ? STATUS_DIM : STATUS_CLEAR);
}
//static char msg3[50];
//memset(msg3, 0, sizeof(msg3));
//snprintf(msg3, sizeof(msg3), "%10.3f, %10.3f, %10.3f",
//e0, e1, e2);
//put_status(msg3);
}
char bitstatus[100];
@ -1675,6 +1713,14 @@ int psk::rx_process(const double *buf, int len)
// transmit processes
//=====================================================================
void psk::transmit(double *buf, int len)
{
// if (btn_imd_on->value())
for (int i = 0; i < len; i++) xmtfilt->Irun(buf[i], buf[i]);
ModulateXmtr(buf, len);
}
#define SVP_MASK 0xF
#define SVP_COUNT (SVP_MASK + 1)
@ -1744,8 +1790,11 @@ void psk::tx_carriers()
} else {
outbuf[i] = (ival * cos(phaseacc[car]) + qval * sin(phaseacc[car])) / numcarriers;
}
if (maxamp < fabs(outbuf[i]))
maxamp = fabs(outbuf[i]);
// create an imd value
double maxmag = xmtimd->value();
if (btn_imd_on->value())
if (fabs(outbuf[i]) > maxmag)
outbuf[i] = maxmag * (outbuf[i] < 0 ? -1 : 1);
phaseacc[car] += delta[car];
if (phaseacc[car] > TWOPI) phaseacc[car] -= TWOPI;
@ -1765,11 +1814,16 @@ void psk::tx_carriers()
}
}
maxamp = 0;
for (int i = 0; i < symbollen; i++)
if (maxamp < fabs(outbuf[i])) maxamp = fabs(outbuf[i]);
maxamp *= 1.02;
if (maxamp) {
for (int i = 0; i < symbollen; i++) outbuf[i] *= (0.9 * maxamp);
for (int i = 0; i < symbollen; i++)
outbuf[i] /= maxamp;
}
ModulateXmtr(outbuf, symbollen);
transmit(outbuf, symbollen);
}
void psk::tx_symbol(int sym)
@ -2154,7 +2208,7 @@ void psk::initSN_IMD()
m_NCount = 0;
COEF[0] = 2.0 * cos(TWOPI * 9 / GOERTZEL);
COEF[1] = 2.0 * cos(TWOPI * 18 / GOERTZEL);
COEF[1] = 2.0 * cos(TWOPI * 36 / GOERTZEL);
COEF[2] = 2.0 * cos(TWOPI * 27 / GOERTZEL);
}

Wyświetl plik

@ -382,7 +382,7 @@ double modem::sigmaN (double es_ovr_n0)
case MODE_PSK125: case MODE_PSK250: case MODE_PSK500:
case MODE_QPSK31: case MODE_QPSK63: case MODE_QPSK125: case MODE_QPSK250:
case MODE_PSK125R: case MODE_PSK250R: case MODE_PSK500R:
mode_factor *= 16;
mode_factor = 400;
break;
case MODE_THROB1: case MODE_THROB2: case MODE_THROB4:
case MODE_THROBX1: case MODE_THROBX2: case MODE_THROBX4:
@ -431,13 +431,20 @@ double modem::gauss(double sigma) {
// simulating the noise that is added to the signal.
// return signal + noise, limiting value to +/- 1.0
//static double mag;
void modem::add_noise(double *buffer, int len)
{
double sigma = sigmaN(progdefaults.s2n);
double sigma = sigmaN(noiseDB->value());
double sn = 0;
for (int n = 0; n < len; n++) {
sn = (buffer[n] + gauss(sigma)) / (1.0 + 3.0 * sigma);
buffer[n] = clamp(sn, -1.0, 1.0);
// mag = fabs(buffer[n]);
// if (btn_imd_on->value())
// buffer[n] *= (1.0 - mag *xmtimd->value())/(1.0 - xmtimd->value());
if (btnNoiseOn->value()) {
sn = (buffer[n] + gauss(sigma)) / (1.0 + 3.0 * sigma);
buffer[n] = clamp(sn, -1.0, 1.0);
}
}
}
@ -469,7 +476,7 @@ void modem::ModulateXmtr(double *buffer, int len)
!(PERFORM_CPS_TEST || active_modem->XMLRPC_CPS_TEST))
trx_xmit_wfall_queue(samplerate, buffer, (size_t)len);
if (withnoise && progdefaults.noise) add_noise(buffer, len);
if (withnoise) add_noise(buffer, len);
double mult = pow(10, progdefaults.txlevel / 20.0);
if (mult > 0.99) mult = 0.99;