kopia lustrzana https://github.com/jamescoxon/dl-fldigi
Add 8PSK 125FL 250FL
* Lowered CPU requirements to allow for use on Android/Netbook devices: - Added modes 125FL and 250FL with constraint length 13 FEC - Adjusted maximum traceback memory for viterbi decoder - Set traceback to an optimally-high value in viterbi.cxx constructor - 8PSK - 500F 1000F & 1200F now use only 1 viterbi decoder without voting - Assigned secondary RsID codes to 125FL and 250FL. * Code cleanups in psk.cxxpull/4/head
rodzic
082564eec8
commit
51535ff236
|
@ -553,8 +553,10 @@ static const Fl_Menu_Item quick_change_8psk[] = {
|
|||
{ mode_info[MODE_8PSK250].name, 0, cb_init_mode, (void *)MODE_8PSK250 },
|
||||
{ mode_info[MODE_8PSK500].name, 0, cb_init_mode, (void *)MODE_8PSK500 },
|
||||
{ mode_info[MODE_8PSK1000].name, 0, cb_init_mode, (void *)MODE_8PSK1000 },
|
||||
{ mode_info[MODE_8PSK125FL].name, 0, cb_init_mode, (void *)MODE_8PSK125FL },
|
||||
{ mode_info[MODE_8PSK125F].name, 0, cb_init_mode, (void *)MODE_8PSK125F },
|
||||
{ mode_info[MODE_8PSK250F].name, 0, cb_init_mode, (void *)MODE_8PSK250F },
|
||||
{ mode_info[MODE_8PSK250FL].name, 0, cb_init_mode, (void *)MODE_8PSK250FL },
|
||||
{ mode_info[MODE_8PSK500F].name, 0, cb_init_mode, (void *)MODE_8PSK500F },
|
||||
{ mode_info[MODE_8PSK1000F].name, 0, cb_init_mode, (void *)MODE_8PSK1000F },
|
||||
{ mode_info[MODE_8PSK1200F].name, 0, cb_init_mode, (void *)MODE_8PSK1200F },
|
||||
|
@ -1529,7 +1531,9 @@ void init_modem(trx_mode mode, int freq)
|
|||
case MODE_8PSK250:
|
||||
case MODE_8PSK500:
|
||||
case MODE_8PSK1000:
|
||||
case MODE_8PSK125FL:
|
||||
case MODE_8PSK125F:
|
||||
case MODE_8PSK250FL:
|
||||
case MODE_8PSK250F:
|
||||
case MODE_8PSK500F:
|
||||
case MODE_8PSK1000F:
|
||||
|
@ -4136,7 +4140,9 @@ static Fl_Menu_Item menu_[] = {
|
|||
{ mode_info[MODE_8PSK250].name, 0, cb_init_mode, (void *)MODE_8PSK250, 0, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
{ mode_info[MODE_8PSK500].name, 0, cb_init_mode, (void *)MODE_8PSK500, 0, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
{ mode_info[MODE_8PSK1000].name, 0, cb_init_mode, (void *)MODE_8PSK1000, 0, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
{ mode_info[MODE_8PSK125FL].name, 0, cb_init_mode, (void *)MODE_8PSK125FL, 0, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
{ mode_info[MODE_8PSK125F].name, 0, cb_init_mode, (void *)MODE_8PSK125F, 0, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
{ mode_info[MODE_8PSK250FL].name, 0, cb_init_mode, (void *)MODE_8PSK250FL, 0, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
{ mode_info[MODE_8PSK250F].name, 0, cb_init_mode, (void *)MODE_8PSK250F, 0, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
{ mode_info[MODE_8PSK500F].name, 0, cb_init_mode, (void *)MODE_8PSK500F, 0, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
{ mode_info[MODE_8PSK1000F].name, 0, cb_init_mode, (void *)MODE_8PSK1000F, 0, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
|
@ -6903,7 +6909,9 @@ static Fl_Menu_Item alt_menu_[] = {
|
|||
{ mode_info[MODE_8PSK250].name, 0, cb_init_mode, (void *)MODE_8PSK250, 0, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
{ mode_info[MODE_8PSK500].name, 0, cb_init_mode, (void *)MODE_8PSK500, 0, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
{ mode_info[MODE_8PSK1000].name, 0, cb_init_mode, (void *)MODE_8PSK1000, 0, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
{ mode_info[MODE_8PSK125FL].name, 0, cb_init_mode, (void *)MODE_8PSK125FL, 0, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
{ mode_info[MODE_8PSK125F].name, 0, cb_init_mode, (void *)MODE_8PSK125F, 0, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
{ mode_info[MODE_8PSK250FL].name, 0, cb_init_mode, (void *)MODE_8PSK250FL, 0, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
{ mode_info[MODE_8PSK250F].name, 0, cb_init_mode, (void *)MODE_8PSK250F, 0, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
{ mode_info[MODE_8PSK500F].name, 0, cb_init_mode, (void *)MODE_8PSK500F, 0, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
{ mode_info[MODE_8PSK1000F].name, 0, cb_init_mode, (void *)MODE_8PSK1000F, 0, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
|
|
|
@ -63,7 +63,7 @@ viterbi::~viterbi()
|
|||
void viterbi::init(void)
|
||||
{
|
||||
if(output) {
|
||||
_traceback = PATHMEM - 1;
|
||||
_traceback = _k * 12; // takes >= 12 constraint lengths to calculate from an arbitrary state, when punctured
|
||||
_chunksize = 8;
|
||||
|
||||
for (int i = 0; i < outsize; i++) {
|
||||
|
|
|
@ -118,8 +118,10 @@ const struct mode_info_t mode_info[NUM_MODES] = {
|
|||
{ MODE_QPSK500, &qpsk500_modem, "QPSK500", "QPSK-500", "QPSK500", "QPSK500", "Q500", ARQ_IO | KISS_IO },
|
||||
|
||||
{ MODE_8PSK125, &_8psk125_modem, "8PSK125", "8PSK-125", "8PSK125", "8PSK125", "8PSK125", ARQ_IO | KISS_IO },
|
||||
{ MODE_8PSK125FL, &_8psk125fl_modem, "8PSK125FL", "8PSK-125FL", "8PSK125FL", "8PSK125FL", "8PSK125FL", ARQ_IO | KISS_IO },
|
||||
{ MODE_8PSK125F, &_8psk125f_modem, "8PSK125F", "8PSK-125F", "8PSK125F", "8PSK125F", "8PSK125F", ARQ_IO | KISS_IO },
|
||||
{ MODE_8PSK250, &_8psk250_modem, "8PSK250", "8PSK-250", "8PSK250", "8PSK250", "8PSK250", ARQ_IO | KISS_IO },
|
||||
{ MODE_8PSK250FL, &_8psk250fl_modem, "8PSK250FL", "8PSK-250FL", "8PSK250FL", "8PSK250FL", "8PSK250FL", ARQ_IO | KISS_IO },
|
||||
{ MODE_8PSK250F, &_8psk250f_modem, "8PSK250F", "8PSK-250F", "8PSK250F", "8PSK250F", "8PSK250F", ARQ_IO | KISS_IO },
|
||||
{ MODE_8PSK500, &_8psk500_modem, "8PSK500", "8PSK-500", "8PSK500", "8PSK500", "8PSK500", ARQ_IO | KISS_IO },
|
||||
{ MODE_8PSK500F, &_8psk500f_modem, "8PSK500F", "8PSK-500F", "8PSK500F", "8PSK500F", "8PSK500F", ARQ_IO | KISS_IO },
|
||||
|
|
|
@ -137,8 +137,10 @@ enum {
|
|||
MODE_QPSK_LAST = MODE_QPSK500,
|
||||
|
||||
MODE_8PSK125,
|
||||
MODE_8PSK125FL,
|
||||
MODE_8PSK125F,
|
||||
MODE_8PSK250,
|
||||
MODE_8PSK250FL,
|
||||
MODE_8PSK250F,
|
||||
MODE_8PSK500,
|
||||
MODE_8PSK500F,
|
||||
|
|
|
@ -323,7 +323,9 @@ extern modem *_8psk1000_modem;
|
|||
extern modem *_8psk1200_modem;
|
||||
extern modem *_8psk1333_modem;
|
||||
|
||||
extern modem *_8psk125fl_modem;
|
||||
extern modem *_8psk125f_modem;
|
||||
extern modem *_8psk250fl_modem;
|
||||
extern modem *_8psk250f_modem;
|
||||
extern modem *_8psk500f_modem;
|
||||
extern modem *_8psk1000f_modem;
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#ifndef VITERBI_H
|
||||
#define VITERBI_H
|
||||
|
||||
#define PATHMEM 128
|
||||
#define PATHMEM 256
|
||||
|
||||
class viterbi {
|
||||
private:
|
||||
|
|
|
@ -80,17 +80,6 @@ extern waterfall *wf;
|
|||
#define K13_POLY1 016461 // 7473
|
||||
#define K13_POLY2 012767 // 5623
|
||||
|
||||
// Poorly performing code: Do not use
|
||||
#define K9 9
|
||||
#define K9_POLY1 0677 // 447
|
||||
#define K9_POLY2 0515 // 333
|
||||
|
||||
// df=18 : correct up to 8 bits
|
||||
#define K15 15
|
||||
#define K15_POLY1 044735 // 18909
|
||||
#define K15_POLY2 063057 // 26159
|
||||
|
||||
|
||||
// df=19 : correct up to 9 bits
|
||||
#define K16 16
|
||||
#define K16_POLY1 0152711 // 54729
|
||||
|
@ -101,7 +90,7 @@ extern waterfall *wf;
|
|||
// - One of the bits is still known with 100% certianty.
|
||||
// - Only up to 1 bit can be in error
|
||||
static cmplx graymapped_8psk_pos[] = {
|
||||
// Degrees Bits In Mapped Soft-Symbol
|
||||
// Degrees Bits In Mapped Soft-Symbol
|
||||
cmplx (1.0, 0.0), // 0 | 0b000 | 025,000,025
|
||||
cmplx (0.7071, 0.7071), // 45 | 0b001 | 000,025,230
|
||||
cmplx (-0.7071, 0.7071), // 135 | 0b010 | 025,255,025
|
||||
|
@ -365,6 +354,26 @@ psk::psk(trx_mode pskmode) : modem()
|
|||
break;
|
||||
|
||||
// 8psk modes with FEC
|
||||
case MODE_8PSK125FL:
|
||||
symbollen = 128;
|
||||
idepth = 384; // 1024 milliseconds
|
||||
flushlength = 38;
|
||||
samplerate = 16000;
|
||||
_8psk = true;
|
||||
dcdbits = 128;
|
||||
vestigial = true;
|
||||
cap |= CAP_REV;
|
||||
break;
|
||||
case MODE_8PSK250FL: // 250 baud | 375 bits/sec @ 1/2 Rate FEC
|
||||
symbollen = 64;
|
||||
idepth = 512; // 682 milliseconds
|
||||
flushlength = 47;
|
||||
samplerate = 16000;
|
||||
_8psk = true;
|
||||
dcdbits = 256;
|
||||
vestigial = true;
|
||||
cap |= CAP_REV;
|
||||
break;
|
||||
case MODE_8PSK125F:
|
||||
symbollen = 128;
|
||||
idepth = 384; // 1024 milliseconds
|
||||
|
@ -732,7 +741,7 @@ psk::psk(trx_mode pskmode) : modem()
|
|||
enc = new encoder(K, POLY1, POLY2);
|
||||
dec = new viterbi(K, POLY1, POLY2);
|
||||
|
||||
} else if (_pskr || mode == MODE_8PSK1200F || PSKviterbi) {
|
||||
} else if (_pskr || PSKviterbi) {
|
||||
// FEC for BPSK. Use a 2nd Viterbi decoder for comparison.
|
||||
// Set decode size to 4 since some characters can be as small
|
||||
// as 3 bits long. This minimises intercharacters decoding
|
||||
|
@ -743,27 +752,26 @@ psk::psk(trx_mode pskmode) : modem()
|
|||
dec2 = new viterbi(PSKR_K, PSKR_POLY1, PSKR_POLY2);
|
||||
dec2->setchunksize(4);
|
||||
|
||||
} else if (_puncturing) {
|
||||
// Use the FEC code best suited for puncturing
|
||||
enc = new encoder(K13, K13_POLY1, K13_POLY2);
|
||||
dec = new viterbi(K13, K13_POLY1, K13_POLY2);
|
||||
// long constraint length codes require long traceback
|
||||
dec->settraceback (PATHMEM);
|
||||
dec->setchunksize(4);
|
||||
dec2 = new viterbi(K13, K13_POLY1, K13_POLY2);
|
||||
dec2->settraceback (PATHMEM);
|
||||
dec2->setchunksize(4);
|
||||
|
||||
} else if (_xpsk || _8psk || _16psk) {
|
||||
// Use the code with the best FEC capabilities
|
||||
} else if (mode == MODE_8PSK125F || mode == MODE_8PSK250F) {
|
||||
enc = new encoder(K16, K16_POLY1, K16_POLY2);
|
||||
dec = new viterbi(K16, K16_POLY1, K16_POLY2);
|
||||
// long constraint length codes require long traceback
|
||||
dec->settraceback (PATHMEM);
|
||||
dec->setchunksize(4);
|
||||
dec2 = new viterbi(K16, K16_POLY1, K16_POLY2);
|
||||
dec2->settraceback (PATHMEM);
|
||||
dec2 = new viterbi(K13, K16_POLY1, K16_POLY2);
|
||||
dec2->setchunksize(4);
|
||||
|
||||
} else if (_xpsk || _8psk || _16psk) {
|
||||
enc = new encoder(K13, K13_POLY1, K13_POLY2);
|
||||
dec = new viterbi(K13, K13_POLY1, K13_POLY2);
|
||||
dec->setchunksize(4);
|
||||
// Second viterbi decoder is only needed when modem has an odd number of bits/symbol.
|
||||
if ( _8psk && !_puncturing ) { // (punctured 8psk has 3-real bits + 1-punctured bit per transmitted symbol)
|
||||
dec2 = new viterbi(K13, K13_POLY1, K13_POLY2);
|
||||
dec2->setchunksize(4);
|
||||
}
|
||||
if (_puncturing) { // punctured codes benefit from a longer traceback
|
||||
dec->settraceback(K13 * 16);
|
||||
if (dec2) dec2->settraceback(K13 * 16);
|
||||
}
|
||||
}
|
||||
|
||||
// Interleaver. For PSKR to maintain constant time delay between bits,
|
||||
|
@ -773,7 +781,7 @@ psk::psk(trx_mode pskmode) : modem()
|
|||
|
||||
Txinlv = new interleave (isize, idepth, INTERLEAVE_FWD);
|
||||
Rxinlv = new interleave (isize, idepth, INTERLEAVE_REV);
|
||||
Rxinlv2 = new interleave (isize, idepth, INTERLEAVE_REV);
|
||||
if (dec2) Rxinlv2 = new interleave (isize, idepth, INTERLEAVE_REV);
|
||||
|
||||
bitshreg = 0;
|
||||
rxbitstate = 0;
|
||||
|
@ -962,6 +970,13 @@ void psk::rx_pskr(unsigned char symbol)
|
|||
// fecmet2 = -9999.0;
|
||||
// return;
|
||||
// }
|
||||
// XPSK and 16PSK have even number of bits/symbol
|
||||
// Punctured 8PSK has even number of bits/symbol (3 real + 1 punctured)
|
||||
// so bit order known: can use only one decoder to reduce CPU usage
|
||||
if ( _xpsk || _16psk || (_8psk && _puncturing) ) {
|
||||
fecmet2 = -9999.0;
|
||||
return;
|
||||
}
|
||||
// copy to avoid scrambling symbolpair for the next bit
|
||||
twosym[0] = symbolpair[0];
|
||||
twosym[1] = symbolpair[1];
|
||||
|
|
|
@ -288,6 +288,9 @@ const int cRsId::rsid_ids_size1 = sizeof(rsid_ids_1)/sizeof(*rsid_ids_1) - 1;
|
|||
ELEM2_(1078, PSK8P1000F, MODE_8PSK1000F) \
|
||||
ELEM2_(1058, PSK8P1200F, MODE_8PSK1200F) \
|
||||
\
|
||||
ELEM2_(1239, PSK8P125FL, MODE_8PSK125FL) \
|
||||
ELEM2_(2052, PSK8P250FL, MODE_8PSK250FL) \
|
||||
\
|
||||
ELEM2_(1171, IFKP, MODE_IFKP) \
|
||||
\
|
||||
ELEM2_(0, NONE2, NUM_MODES)
|
||||
|
|
|
@ -102,7 +102,9 @@ modem *_8psk1000_modem = 0;
|
|||
modem *_8psk1200_modem = 0;
|
||||
modem *_8psk1333_modem = 0;
|
||||
|
||||
modem *_8psk125fl_modem = 0;
|
||||
modem *_8psk125f_modem = 0;
|
||||
modem *_8psk250fl_modem = 0;
|
||||
modem *_8psk250f_modem = 0;
|
||||
modem *_8psk500f_modem = 0;
|
||||
modem *_8psk1000f_modem = 0;
|
||||
|
|
Ładowanie…
Reference in New Issue