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.cxx
pull/4/head
John Phelps 2015-10-19 15:42:25 -05:00 zatwierdzone przez David Freese
rodzic 082564eec8
commit 51535ff236
9 zmienionych plików z 67 dodań i 33 usunięć

Wyświetl plik

@ -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},

Wyświetl plik

@ -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++) {

Wyświetl plik

@ -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 },

Wyświetl plik

@ -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,

Wyświetl plik

@ -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;

Wyświetl plik

@ -25,7 +25,7 @@
#ifndef VITERBI_H
#define VITERBI_H
#define PATHMEM 128
#define PATHMEM 256
class viterbi {
private:

Wyświetl plik

@ -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];

Wyświetl plik

@ -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)

Wyświetl plik

@ -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;