kopia lustrzana https://github.com/jamescoxon/dl-fldigi
Upstream version 3.0preS
rodzic
9f8298afa5
commit
9da69cb0be
|
@ -9,7 +9,7 @@ dnl major and minor must be integers; patch may
|
|||
dnl contain other characters or be empty
|
||||
m4_define(FLDIGI_MAJOR, [3])
|
||||
m4_define(FLDIGI_MINOR, [0])
|
||||
m4_define(FLDIGI_PATCH, [preR])
|
||||
m4_define(FLDIGI_PATCH, [preS])
|
||||
|
||||
AC_INIT([fldigi], FLDIGI_MAJOR.FLDIGI_MINOR[FLDIGI_PATCH], [w1hkj AT w1hkj DOT com])
|
||||
|
||||
|
|
|
@ -197,9 +197,13 @@ Fl_Menu_Item quick_change_qpsk[] = {
|
|||
|
||||
Fl_Menu_Item quick_change_mfsk[] = {
|
||||
{ mode_info[MODE_MFSK8].name, 0, cb_init_mode, (void *)MODE_MFSK8 },
|
||||
#ifdef EXPERIMENTAL
|
||||
{ mode_info[MODE_MFSK11].name, 0, cb_init_mode, (void *)MODE_MFSK11 },
|
||||
#endif
|
||||
{ mode_info[MODE_MFSK16].name, 0, cb_init_mode, (void *)MODE_MFSK16 },
|
||||
#ifdef EXPERIMENTAL
|
||||
{ mode_info[MODE_MFSK22].name, 0, cb_init_mode, (void *)MODE_MFSK22 },
|
||||
#endif
|
||||
{ mode_info[MODE_MFSK32].name, 0, cb_init_mode, (void *)MODE_MFSK32 },
|
||||
{ 0 }
|
||||
};
|
||||
|
@ -443,10 +447,12 @@ void init_modem(trx_mode mode)
|
|||
modem_config_tab = tabFeld;
|
||||
break;
|
||||
|
||||
case MODE_MFSK8:
|
||||
#ifdef EXPERIMENTAL
|
||||
case MODE_MFSK11:
|
||||
case MODE_MFSK22:
|
||||
#endif
|
||||
case MODE_MFSK8:
|
||||
case MODE_MFSK16:
|
||||
case MODE_MFSK22:
|
||||
case MODE_MFSK32:
|
||||
startup_modem(*mode_info[mode].modem ? *mode_info[mode].modem :
|
||||
*mode_info[mode].modem = new mfsk(mode));
|
||||
|
@ -1193,9 +1199,13 @@ Fl_Menu_Item menu_[] = {
|
|||
|
||||
{"MFSK", 0, 0, 0, FL_SUBMENU, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
{ mode_info[MODE_MFSK8].name, 0, cb_init_mode, (void *)MODE_MFSK8, 0, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
#ifdef EXPERIMENTAL
|
||||
{ mode_info[MODE_MFSK11].name, 0, cb_init_mode, (void *)MODE_MFSK11, 0, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
#endif
|
||||
{ mode_info[MODE_MFSK16].name, 0, cb_init_mode, (void *)MODE_MFSK16, 0, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
#ifdef EXPERIMENTAL
|
||||
{ mode_info[MODE_MFSK22].name, 0, cb_init_mode, (void *)MODE_MFSK22, 0, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
#endif
|
||||
{ mode_info[MODE_MFSK32].name, 0, cb_init_mode, (void *)MODE_MFSK32, 0, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
{0,0,0,0,0,0,0,0,0},
|
||||
|
||||
|
|
|
@ -48,6 +48,8 @@
|
|||
|
||||
#define DEFAULT_IMAGE_WIDTH 3000
|
||||
//=============================================================================
|
||||
// enable the following line for experimental mode such as MFSK11 & MFSK22
|
||||
//#define EXPERIMENTAL
|
||||
|
||||
// widget sizes internal to the waterfall widget
|
||||
#define BEZEL 2
|
||||
|
|
|
@ -130,6 +130,7 @@ protected:
|
|||
Cmovavg *met1filt;
|
||||
Cmovavg *met2filt;
|
||||
Cmovavg *vidfilter[SCOPESIZE];
|
||||
Cmovavg *syncfilter;
|
||||
|
||||
viterbi *dec1;
|
||||
viterbi *dec2;
|
||||
|
@ -156,6 +157,8 @@ protected:
|
|||
double s2n;
|
||||
double sig;
|
||||
double noise;
|
||||
double afcmetric;
|
||||
bool staticburst;
|
||||
|
||||
double currfreq;
|
||||
|
||||
|
|
|
@ -79,6 +79,8 @@ void mfsk::rx_init()
|
|||
picheader[PICHEADER -1] = 0;
|
||||
put_MODEstatus(mode);
|
||||
set_AFCrange(tonespacing / 10.0);
|
||||
syncfilter->reset();
|
||||
staticburst = false;
|
||||
}
|
||||
|
||||
void mfsk::init()
|
||||
|
@ -107,6 +109,7 @@ mfsk::~mfsk()
|
|||
}
|
||||
deleteRxViewer();
|
||||
deleteTxViewer();
|
||||
if (syncfilter) delete syncfilter;
|
||||
}
|
||||
|
||||
mfsk::mfsk(trx_mode mfsk_mode) : modem()
|
||||
|
@ -120,50 +123,53 @@ mfsk::mfsk(trx_mode mfsk_mode) : modem()
|
|||
samplerate = 8000;
|
||||
symlen = 1024;
|
||||
symbits = 5;
|
||||
AFC_COUNT = 16;
|
||||
basetone = 128;
|
||||
break;
|
||||
case MODE_MFSK16:
|
||||
samplerate = 8000;
|
||||
symlen = 512;
|
||||
symbits = 4;
|
||||
AFC_COUNT = 16;
|
||||
basetone = 64;
|
||||
break;
|
||||
case MODE_MFSK32:
|
||||
samplerate = 8000;
|
||||
symlen = 256;
|
||||
symbits = 4;
|
||||
AFC_COUNT = 32;
|
||||
basetone = 32;
|
||||
break;
|
||||
#ifdef EXPERIMENTAL
|
||||
case MODE_MFSK11:
|
||||
samplerate = 11025;
|
||||
symlen = 1024;
|
||||
symbits = 4;
|
||||
AFC_COUNT = 16;
|
||||
basetone = 93;
|
||||
break;
|
||||
case MODE_MFSK22:
|
||||
samplerate = 11025;
|
||||
symlen = 512;
|
||||
symbits = 4;
|
||||
AFC_COUNT = 32;
|
||||
basetone = 46;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
samplerate = 8000;
|
||||
symlen = 512;
|
||||
symbits = 4;
|
||||
AFC_COUNT = 32;
|
||||
basetone = 64;
|
||||
break;
|
||||
}
|
||||
|
||||
numtones = 1 << symbits;
|
||||
tonespacing = (double) samplerate / symlen;
|
||||
basetone = (int)floor(1000.0 * symlen / samplerate + 0.5);
|
||||
// basetone = (int)floor(1000.0 * symlen / samplerate + 0.5);
|
||||
|
||||
binsfft = new sfft (symlen, basetone, basetone + numtones + 3);
|
||||
binsfft = new sfft (symlen, basetone, basetone + numtones );//+ 3); // ?
|
||||
hbfilt = new C_FIR_filter();
|
||||
hbfilt->init_hilbert(37, 1);
|
||||
afcfilt = new Cmovavg(AFC_COUNT);
|
||||
met1filt = new Cmovavg(32);
|
||||
met2filt = new Cmovavg(32);
|
||||
syncfilter = new Cmovavg(8);
|
||||
|
||||
for (int i = 0; i < SCOPESIZE; i++)
|
||||
vidfilter[i] = new Cmovavg(16);
|
||||
|
@ -366,31 +372,30 @@ void mfsk::decodesymbol(unsigned char symbol)
|
|||
|
||||
symcounter = symcounter ? 0 : 1;
|
||||
|
||||
/* MFSK16 doesn't need a vote */
|
||||
if (mode == MODE_MFSK16 && symcounter)
|
||||
return;
|
||||
|
||||
if (symcounter) {
|
||||
if ((c = dec1->decode(symbolpair, &met)) == -1)
|
||||
return;
|
||||
|
||||
met1 = met1filt->run(met);
|
||||
|
||||
if (met1 < met2)
|
||||
return;
|
||||
|
||||
metric = met1 / 2.0;
|
||||
// only MFSK8 needs a vote
|
||||
if (mode == MODE_MFSK8) {
|
||||
if (symcounter) {
|
||||
if ((c = dec1->decode(symbolpair, &met)) == -1)
|
||||
return;
|
||||
met1 = met1filt->run(met);
|
||||
if (met1 < met2)
|
||||
return;
|
||||
metric = met1 / 2.0;
|
||||
} else {
|
||||
if ((c = dec2->decode(symbolpair, &met)) == -1)
|
||||
return;
|
||||
met2 = met2filt->run(met);
|
||||
if (met2 < met1)
|
||||
return;
|
||||
metric = met2 / 2.0;
|
||||
}
|
||||
} else {
|
||||
if (symcounter) return;
|
||||
if ((c = dec2->decode(symbolpair, &met)) == -1)
|
||||
return;
|
||||
|
||||
met2 = met2filt->run(met);
|
||||
|
||||
if (met2 < met1)
|
||||
return;
|
||||
|
||||
metric = met2 / 2.0;
|
||||
metric = met2filt->run(met / 2.0);
|
||||
}
|
||||
|
||||
display_metric(metric);
|
||||
|
||||
if (progStatus.sqlonoff && metric < progStatus.sldrSquelchValue)
|
||||
|
@ -461,17 +466,32 @@ complex mfsk::mixer(complex in, double f)
|
|||
|
||||
int mfsk::harddecode(complex *in)
|
||||
{
|
||||
double x, max = 0.0;
|
||||
double x, max = 0.0, avg = 0.0;
|
||||
int i, symbol = 0;
|
||||
int burstcount = 0;
|
||||
|
||||
for (int i = 0; i < numtones; i++)
|
||||
avg += in[i].mag();
|
||||
avg /= numtones;
|
||||
|
||||
if (avg < 1e-20) avg = 1e-20;
|
||||
|
||||
for (i = 0; i < numtones; i++) {
|
||||
x = in[i].mag();
|
||||
if ( x > max) {
|
||||
max = x;
|
||||
symbol = i;
|
||||
}
|
||||
if (x > 2.0 * avg) burstcount++;
|
||||
}
|
||||
maxval = max;
|
||||
|
||||
staticburst = (burstcount > numtones / 2);
|
||||
|
||||
if (!staticburst)
|
||||
afcmetric = 0.95*afcmetric + 0.05 * (2 * max / avg);
|
||||
else
|
||||
afcmetric = 0.0;
|
||||
|
||||
return symbol;
|
||||
}
|
||||
|
||||
|
@ -479,8 +499,8 @@ void mfsk::update_syncscope()
|
|||
{
|
||||
int j;
|
||||
int pipelen = 2 * symlen;
|
||||
double max = prevmaxval;
|
||||
if (max == 0.0) max = 1e10;
|
||||
// double max = prevmaxval;
|
||||
// if (max == 0.0) max = 1e10;
|
||||
memset(scopedata, 0, 2 * symlen * sizeof(double));
|
||||
if (!progStatus.sqlonoff || metric >= progStatus.sldrSquelchValue)
|
||||
for (unsigned int i = 0; i < SCOPESIZE; i++) {
|
||||
|
@ -496,7 +516,8 @@ void mfsk::update_syncscope()
|
|||
|
||||
void mfsk::synchronize()
|
||||
{
|
||||
int i, j, syn = -1;
|
||||
int i, j;
|
||||
double syn = -1;
|
||||
double val, max = 0.0;
|
||||
|
||||
if (currsymbol == prev1symbol)
|
||||
|
@ -517,6 +538,8 @@ void mfsk::synchronize()
|
|||
j = (j + 1) % (2 * symlen);
|
||||
}
|
||||
|
||||
syn = syncfilter->run(syn);
|
||||
|
||||
synccounter += (int) floor((syn - symlen) / numtones + 0.5);
|
||||
|
||||
update_syncscope();
|
||||
|
@ -539,28 +562,33 @@ void mfsk::afc()
|
|||
reset_afc();
|
||||
sigsearch = 0;
|
||||
}
|
||||
|
||||
if ( progStatus.afconoff == true && metric > progStatus.sldrSquelchValue ) {
|
||||
|
||||
if (pipeptr == 0)
|
||||
prevvector = pipe[2*symlen - 1].vector[currsymbol];
|
||||
else
|
||||
prevvector = pipe[pipeptr - 1].vector[currsymbol];
|
||||
|
||||
z = prevvector % currvector;
|
||||
|
||||
f = z.arg() * samplerate / twopi;
|
||||
|
||||
f1 = 1000 + tonespacing * currsymbol - f;
|
||||
f1 /= numtones;
|
||||
if (staticburst || !progStatus.afconoff)
|
||||
return;
|
||||
if (metric < progStatus.sldrSquelchValue)
|
||||
return;
|
||||
if (afcmetric < 6.0)
|
||||
return;
|
||||
|
||||
f2 = CLAMP ( f1, freqerr - ts, freqerr + ts);
|
||||
if (pipeptr == 0)
|
||||
prevvector = pipe[2*symlen - 1].vector[currsymbol];
|
||||
else
|
||||
prevvector = pipe[pipeptr - 1].vector[currsymbol];
|
||||
z = prevvector % currvector;
|
||||
|
||||
freqerr = decayavg ( freqerr, f2, 64 );
|
||||
f = z.arg() * samplerate / twopi;
|
||||
|
||||
f1 = tonespacing * (basetone + currsymbol);
|
||||
f1 -= f;
|
||||
|
||||
set_freq(frequency - freqerr);
|
||||
set_AFCind( freqerr );
|
||||
} else set_AFCind(0.0);
|
||||
f1 /= numtones;
|
||||
|
||||
f2 = CLAMP ( f1, freqerr - ts, freqerr + ts);
|
||||
|
||||
freqerr = decayavg ( freqerr, f2, 128 );
|
||||
|
||||
set_freq(frequency - freqerr);
|
||||
set_AFCind( freqerr );
|
||||
}
|
||||
|
||||
void mfsk::eval_s2n()
|
||||
|
@ -658,7 +686,7 @@ int mfsk::rx_process(const double *buf, int len)
|
|||
prev2vector = prev1vector;
|
||||
prev1symbol = currsymbol;
|
||||
prev1vector = currvector;
|
||||
prevmaxval = maxval;
|
||||
// prevmaxval = maxval;
|
||||
}
|
||||
pipeptr = (pipeptr + 1) % (2 * symlen);
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ configuration progdefaults = {
|
|||
false, // bool rsidWideSearch;
|
||||
false, // bool TransmitRSid;
|
||||
true, // bool slowcpu;
|
||||
|
||||
false, // bool changed;
|
||||
-20.0, // double wfRefLevel;
|
||||
70.0, // double wfAmpSpan;
|
||||
|
|
|
@ -73,9 +73,13 @@ RSIDs cRsId::rsid_ids[] = {
|
|||
{ 60, MODE_MFSK8 }, // MFSK8
|
||||
{ 57, MODE_MFSK16 }, // MFSK16
|
||||
{ 147, MODE_MFSK32 }, // MFSK32
|
||||
#ifdef EXPERIMENTAL
|
||||
{ 148, MODE_MFSK11 }, // MFSK11
|
||||
{ 152, MODE_MFSK22 }, // MFSK22
|
||||
|
||||
#else
|
||||
{ 148, NUM_MODES }, // MFSK11
|
||||
{ 152, NUM_MODES }, // MFSK22
|
||||
#endif
|
||||
{ 61, NUM_MODES }, // RTTYM-8-250
|
||||
{ 62, NUM_MODES }, // RTTYM-16-500
|
||||
{ 63, NUM_MODES }, // RTTYM-32-1000
|
||||
|
|
Ładowanie…
Reference in New Issue