From 9da69cb0be62144a01dc3b8396eba5f0071ae8c3 Mon Sep 17 00:00:00 2001 From: Stelios Bounanos Date: Wed, 9 Jul 2008 03:02:31 +0100 Subject: [PATCH] Upstream version 3.0preS --- configure.ac | 2 +- src/dialogs/fl_digi.cxx | 14 +++- src/include/fldigi-config.h | 2 + src/include/mfsk.h | 3 + src/mfsk/mfsk.cxx | 134 ++++++++++++++++++++++-------------- src/misc/configuration.cxx | 1 + src/rsid/rsid.cxx | 6 +- 7 files changed, 105 insertions(+), 57 deletions(-) diff --git a/configure.ac b/configure.ac index e55be1e1..5082a0f5 100644 --- a/configure.ac +++ b/configure.ac @@ -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]) diff --git a/src/dialogs/fl_digi.cxx b/src/dialogs/fl_digi.cxx index 811e6019..1304ab2c 100644 --- a/src/dialogs/fl_digi.cxx +++ b/src/dialogs/fl_digi.cxx @@ -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}, diff --git a/src/include/fldigi-config.h b/src/include/fldigi-config.h index dc760af6..88929b1f 100644 --- a/src/include/fldigi-config.h +++ b/src/include/fldigi-config.h @@ -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 diff --git a/src/include/mfsk.h b/src/include/mfsk.h index 77f4bc41..0dbfc96e 100644 --- a/src/include/mfsk.h +++ b/src/include/mfsk.h @@ -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; diff --git a/src/mfsk/mfsk.cxx b/src/mfsk/mfsk.cxx index 8aa5e93d..8686ba48 100644 --- a/src/mfsk/mfsk.cxx +++ b/src/mfsk/mfsk.cxx @@ -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); } diff --git a/src/misc/configuration.cxx b/src/misc/configuration.cxx index de20e12d..1c5cbb0a 100644 --- a/src/misc/configuration.cxx +++ b/src/misc/configuration.cxx @@ -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; diff --git a/src/rsid/rsid.cxx b/src/rsid/rsid.cxx index edd96f21..2b4e708a 100644 --- a/src/rsid/rsid.cxx +++ b/src/rsid/rsid.cxx @@ -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