kopia lustrzana https://github.com/jamescoxon/dl-fldigi
Merge with upstream
commit
6e7ea86d91
|
@ -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, [preU])
|
||||
m4_define(FLDIGI_PATCH, [preW])
|
||||
|
||||
AC_INIT([fldigi], FLDIGI_MAJOR.FLDIGI_MINOR[FLDIGI_PATCH], [w1hkj AT w1hkj DOT com])
|
||||
|
||||
|
|
|
@ -221,6 +221,7 @@ Fl_Menu_Item quick_change_mfsk_exp[] = {
|
|||
{ mode_info[MODE_MFSK4].name, 0, cb_init_mode, (void *)MODE_MFSK4 },
|
||||
{ mode_info[MODE_MFSK11].name, 0, cb_init_mode, (void *)MODE_MFSK11 },
|
||||
{ mode_info[MODE_MFSK22].name, 0, cb_init_mode, (void *)MODE_MFSK22 },
|
||||
{ mode_info[MODE_MFSK31].name, 0, cb_init_mode, (void *)MODE_MFSK31 },
|
||||
{ mode_info[MODE_MFSK64].name, 0, cb_init_mode, (void *)MODE_MFSK64 },
|
||||
{ 0 }
|
||||
};
|
||||
|
@ -588,6 +589,7 @@ void init_modem(trx_mode mode)
|
|||
case MODE_MFSK4:
|
||||
case MODE_MFSK11:
|
||||
case MODE_MFSK22:
|
||||
case MODE_MFSK31:
|
||||
case MODE_MFSK64:
|
||||
case MODE_MFSK8:
|
||||
case MODE_MFSK16:
|
||||
|
@ -1344,6 +1346,7 @@ Fl_Menu_Item menu_[] = {
|
|||
{ mode_info[MODE_MFSK4].name, 0, cb_init_mode, (void *)MODE_MFSK4, 0, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
{ mode_info[MODE_MFSK11].name, 0, cb_init_mode, (void *)MODE_MFSK11, 0, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
{ mode_info[MODE_MFSK22].name, 0, cb_init_mode, (void *)MODE_MFSK22, 0, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
{ mode_info[MODE_MFSK31].name, 0, cb_init_mode, (void *)MODE_MFSK31, 0, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
{ mode_info[MODE_MFSK64].name, 0, cb_init_mode, (void *)MODE_MFSK64, 0, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
|
||||
{0,0,0,0,0,0,0,0,0},
|
||||
|
@ -1471,6 +1474,8 @@ void activate_experimental()
|
|||
m_exp->show();
|
||||
if ((m_exp = getMenuItem(mode_info[MODE_MFSK22].name)) != 0)
|
||||
m_exp->show();
|
||||
if ((m_exp = getMenuItem(mode_info[MODE_MFSK31].name)) != 0)
|
||||
m_exp->show();
|
||||
if ((m_exp = getMenuItem(mode_info[MODE_MFSK64].name)) != 0)
|
||||
m_exp->show();
|
||||
if ((m_exp = getMenuItem(mode_info[MODE_MFSK32].name)) != 0)
|
||||
|
@ -1482,6 +1487,8 @@ void activate_experimental()
|
|||
m_exp->hide();
|
||||
if ((m_exp = getMenuItem(mode_info[MODE_MFSK22].name)) != 0)
|
||||
m_exp->hide();
|
||||
if ((m_exp = getMenuItem(mode_info[MODE_MFSK31].name)) != 0)
|
||||
m_exp->hide();
|
||||
if ((m_exp = getMenuItem(mode_info[MODE_MFSK64].name)) != 0)
|
||||
m_exp->hide();
|
||||
}
|
||||
|
|
|
@ -71,6 +71,7 @@ const struct mode_info_t mode_info[NUM_MODES] = {
|
|||
{ MODE_MFSK4, &mfsk4_modem, "MFSK-4", "MFSK-4", "MFSK4", "MFSK4" },
|
||||
{ MODE_MFSK11, &mfsk11_modem, "MFSK-11", "MFSK-11", "MFSK11", "MFSK11" },
|
||||
{ MODE_MFSK22, &mfsk22_modem, "MFSK-22", "MFSK-22", "MFSK22", "MFSK22" },
|
||||
{ MODE_MFSK31, &mfsk31_modem, "MFSK-31", "MFSK-31", "MFSK31", "MFSK31" },
|
||||
{ MODE_MFSK64, &mfsk64_modem, "MFSK-64", "MFSK-64", "MFSK64", "MFSK64" },
|
||||
|
||||
{ MODE_MT63_500, &mt63_500_modem, "MT63-500", "MT63-500", "MT63-500", "MT63" },
|
||||
|
|
|
@ -75,6 +75,7 @@ enum {
|
|||
MODE_MFSK4,
|
||||
MODE_MFSK11,
|
||||
MODE_MFSK22,
|
||||
MODE_MFSK31,
|
||||
MODE_MFSK64,
|
||||
|
||||
MODE_MT63_500,
|
||||
|
|
|
@ -130,8 +130,6 @@ protected:
|
|||
C_FIR_filter *hbfilt;
|
||||
sfft *binsfft;
|
||||
C_FIR_filter *bpfilt;
|
||||
Cmovavg *met1filt;
|
||||
Cmovavg *met2filt;
|
||||
Cmovavg *vidfilter[SCOPESIZE];
|
||||
Cmovavg *syncfilter;
|
||||
|
||||
|
@ -182,7 +180,7 @@ protected:
|
|||
interleave *txinlv;
|
||||
unsigned int bitshreg;
|
||||
int bitstate;
|
||||
|
||||
|
||||
// Picutre data and methods
|
||||
int picturesize;
|
||||
char picheader[PICHEADER];
|
||||
|
@ -198,7 +196,7 @@ protected:
|
|||
int picH;
|
||||
bool color;
|
||||
|
||||
unsigned char picprologue[44];
|
||||
unsigned char picprologue[176];
|
||||
int xmtbytes;
|
||||
bool startpic;
|
||||
bool abortxmt;
|
||||
|
|
|
@ -181,6 +181,7 @@ extern modem *mfsk32_modem;
|
|||
extern modem *mfsk4_modem;
|
||||
extern modem *mfsk11_modem;
|
||||
extern modem *mfsk22_modem;
|
||||
extern modem *mfsk31_modem;
|
||||
extern modem *mfsk64_modem;
|
||||
|
||||
extern modem *mt63_500_modem;
|
||||
|
|
|
@ -38,9 +38,10 @@ interleave::interleave (int _size, int dir)
|
|||
if (size == -1) { // dominoEX interleaver
|
||||
size = 4;
|
||||
depth = 4;
|
||||
} else if (size == 4)
|
||||
} else if (size == 5)
|
||||
depth = 5;
|
||||
else
|
||||
depth = 10;
|
||||
else depth = 5;
|
||||
direction = dir;
|
||||
table = new unsigned char [depth * size * size];
|
||||
memset(table, 0, depth * size * size);
|
||||
|
|
|
@ -57,7 +57,7 @@ void mfsk::tx_init(SoundBase *sc)
|
|||
scard = sc;
|
||||
txstate = TX_STATE_PREAMBLE;
|
||||
bitstate = 0;
|
||||
counter = 0;
|
||||
|
||||
videoText();
|
||||
}
|
||||
|
||||
|
@ -116,8 +116,6 @@ mfsk::~mfsk()
|
|||
if (pipe) delete [] pipe;
|
||||
if (hbfilt) delete hbfilt;
|
||||
if (binsfft) delete binsfft;
|
||||
if (met1filt) delete met1filt;
|
||||
if (met2filt) delete met2filt;
|
||||
for (int i = 0; i < SCOPESIZE; i++) {
|
||||
if (vidfilter[i]) delete vidfilter[i];
|
||||
}
|
||||
|
@ -138,19 +136,22 @@ mfsk::mfsk(trx_mode mfsk_mode) : modem()
|
|||
symlen = 1024;
|
||||
symbits = 5;
|
||||
basetone = 128;
|
||||
numtones = 32;
|
||||
break;
|
||||
case MODE_MFSK16:
|
||||
samplerate = 8000;
|
||||
symlen = 512;
|
||||
symbits = 4;
|
||||
basetone = 64;
|
||||
numtones = 16;
|
||||
cap |= CAP_IMG;
|
||||
break;
|
||||
case MODE_MFSK32:
|
||||
samplerate = 8000;
|
||||
symlen = 256;
|
||||
symbits = 4;
|
||||
symbits = 4;
|
||||
basetone = 32;
|
||||
numtones = 16;
|
||||
cap |= CAP_IMG;
|
||||
break;
|
||||
// experimental modes
|
||||
|
@ -159,12 +160,22 @@ mfsk::mfsk(trx_mode mfsk_mode) : modem()
|
|||
symlen = 2048;
|
||||
symbits = 5;
|
||||
basetone = 256;
|
||||
numtones = 32;
|
||||
break;
|
||||
case MODE_MFSK31:
|
||||
samplerate = 8000;
|
||||
symlen = 256;
|
||||
symbits = 3;
|
||||
basetone = 32;
|
||||
numtones = 8;
|
||||
cap |= CAP_IMG;
|
||||
break;
|
||||
case MODE_MFSK64:
|
||||
samplerate = 8000;
|
||||
symlen = 128;
|
||||
symbits = 4;
|
||||
basetone = 16;
|
||||
numtones = 16;
|
||||
cap |= CAP_IMG;
|
||||
break;
|
||||
case MODE_MFSK11:
|
||||
|
@ -172,6 +183,7 @@ mfsk::mfsk(trx_mode mfsk_mode) : modem()
|
|||
symlen = 1024;
|
||||
symbits = 4;
|
||||
basetone = 93;
|
||||
numtones = 16;
|
||||
cap |= CAP_IMG;
|
||||
break;
|
||||
case MODE_MFSK22:
|
||||
|
@ -179,6 +191,7 @@ mfsk::mfsk(trx_mode mfsk_mode) : modem()
|
|||
symlen = 512;
|
||||
symbits = 4;
|
||||
basetone = 46;
|
||||
numtones = 16;
|
||||
cap |= CAP_IMG;
|
||||
break;
|
||||
//
|
||||
|
@ -187,19 +200,17 @@ mfsk::mfsk(trx_mode mfsk_mode) : modem()
|
|||
symlen = 512;
|
||||
symbits = 4;
|
||||
basetone = 64;
|
||||
numtones = 16;
|
||||
break;
|
||||
}
|
||||
|
||||
numtones = 1 << symbits;
|
||||
tonespacing = (double) samplerate / symlen;
|
||||
// basetone = (int)floor(1000.0 * symlen / samplerate + 0.5);
|
||||
basefreq = 1.0 * samplerate * basetone / symlen;
|
||||
|
||||
binsfft = new sfft (symlen, basetone, basetone + numtones );//+ 3); // ?
|
||||
binsfft = new sfft (symlen, basetone, basetone + numtones );
|
||||
hbfilt = new C_FIR_filter();
|
||||
hbfilt->init_hilbert(37, 1);
|
||||
met1filt = new Cmovavg(32);
|
||||
met2filt = new Cmovavg(32);
|
||||
|
||||
syncfilter = new Cmovavg(8);
|
||||
|
||||
for (int i = 0; i < SCOPESIZE; i++)
|
||||
|
@ -323,8 +334,6 @@ void mfsk::recvpic(complex z)
|
|||
picf += (prevz % z).arg() * samplerate / TWOPI;
|
||||
prevz = z;
|
||||
|
||||
// if ((counter % SAMPLES_PER_PIXEL) == 0) {
|
||||
// picf = 256 * (picf / SAMPLES_PER_PIXEL - 1000) / bandwidth;
|
||||
if ((counter % RXspp) == 0) {
|
||||
picf = 256 * (picf / RXspp - basefreq) / bandwidth;
|
||||
byte = (int)CLAMP(picf, 0.0, 255.0);
|
||||
|
@ -366,8 +375,12 @@ void mfsk::recvchar(int c)
|
|||
return;
|
||||
|
||||
if (check_picture_header(c) == true) {
|
||||
counter = 44 * RXspp;
|
||||
if (symbolbit == 4) counter += symlen;
|
||||
// 44 nulls at 8 samples per pixel
|
||||
// 88 nulls at 4 samples per pixel
|
||||
// 176 nulls at 2 samples per pixel
|
||||
counter = 352;
|
||||
// if (symbolbit == 4) counter += symlen;
|
||||
if (symbolbit == symbits) counter += symlen;
|
||||
rxstate = RX_STATE_PICTURE_START;
|
||||
picturesize = RXspp * picW * picH * (color ? 3 : 1);
|
||||
pixelnbr = 0;
|
||||
|
@ -378,6 +391,7 @@ void mfsk::recvchar(int c)
|
|||
picheader[PICHEADER -1] = 0;
|
||||
}
|
||||
put_rx_char(c);
|
||||
|
||||
}
|
||||
|
||||
void mfsk::recvbit(int bit)
|
||||
|
@ -402,19 +416,19 @@ void mfsk::decodesymbol(unsigned char symbol)
|
|||
|
||||
symcounter = symcounter ? 0 : 1;
|
||||
|
||||
// only modes with 5 symbits need a vote
|
||||
if (symbits == 5) {
|
||||
// only modes with 3 or 5 symbits need a vote
|
||||
if (symbits == 5 || symbits == 3) {
|
||||
if (symcounter) {
|
||||
if ((c = dec1->decode(symbolpair, &met)) == -1)
|
||||
return;
|
||||
met1 = met1filt->run(met);
|
||||
met1 = decayavg(met1, met, 32);
|
||||
if (met1 < met2)
|
||||
return;
|
||||
metric = met1 / 2.0;
|
||||
} else {
|
||||
if ((c = dec2->decode(symbolpair, &met)) == -1)
|
||||
return;
|
||||
met2 = met2filt->run(met);
|
||||
met2 = decayavg(met2, met, 32);
|
||||
if (met2 < met1)
|
||||
return;
|
||||
metric = met2 / 2.0;
|
||||
|
@ -423,7 +437,8 @@ void mfsk::decodesymbol(unsigned char symbol)
|
|||
if (symcounter) return;
|
||||
if ((c = dec2->decode(symbolpair, &met)) == -1)
|
||||
return;
|
||||
metric = met2filt->run(met / 2.0);
|
||||
met2 = decayavg(met2, met, 32);
|
||||
metric = met2 / 2.0;
|
||||
}
|
||||
|
||||
display_metric(metric);
|
||||
|
@ -437,7 +452,7 @@ void mfsk::decodesymbol(unsigned char symbol)
|
|||
|
||||
void mfsk::softdecode(complex *bins)
|
||||
{
|
||||
double tone, sum, b[symbits];
|
||||
double binmag, sum, b[symbits];
|
||||
unsigned char symbols[symbits];
|
||||
int i, j, k;
|
||||
|
||||
|
@ -455,17 +470,20 @@ void mfsk::softdecode(complex *bins)
|
|||
else
|
||||
k = i;
|
||||
|
||||
tone = bins[k].mag();
|
||||
binmag = bins[k].mag();
|
||||
|
||||
for (k = 0; k < symbits; k++)
|
||||
b[k] += (j & (1 << (symbits - k - 1))) ? tone : -tone;
|
||||
b[k] += (j & (1 << (symbits - k - 1))) ? binmag : -binmag;
|
||||
|
||||
sum += tone;
|
||||
sum += binmag;
|
||||
}
|
||||
|
||||
// shift to range 0...260 ??? symbols are unsigned char
|
||||
// shift to range 0...255
|
||||
for (i = 0; i < symbits; i++)
|
||||
symbols[i] = (unsigned char)clamp(128.0 + (b[i] / sum * 128.0), 0, 255);// 260);
|
||||
if (staticburst)
|
||||
symbols[i] = 0; // puncturing
|
||||
else
|
||||
symbols[i] = (unsigned char)clamp(128.0 + (b[i] / sum * 128.0), 0, 255);
|
||||
|
||||
rxinlv->symbols(symbols);
|
||||
|
||||
|
@ -516,13 +534,13 @@ int mfsk::harddecode(complex *in)
|
|||
if (x > 2.0 * avg) burstcount++;
|
||||
}
|
||||
|
||||
staticburst = (burstcount > numtones / 2);
|
||||
|
||||
staticburst = (burstcount == numtones);
|
||||
|
||||
if (!staticburst)
|
||||
afcmetric = 0.95*afcmetric + 0.05 * (2 * max / avg);
|
||||
else
|
||||
afcmetric = 0.0;
|
||||
|
||||
|
||||
return symbol;
|
||||
}
|
||||
|
||||
|
@ -576,6 +594,7 @@ void mfsk::synchronize()
|
|||
|
||||
void mfsk::reset_afc() {
|
||||
freqerr = 0.0;
|
||||
syncfilter->reset();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -583,8 +602,8 @@ void mfsk::afc()
|
|||
{
|
||||
complex z;
|
||||
complex prevvector;
|
||||
double f, f1, f2;
|
||||
double ts = tonespacing / 8;
|
||||
double f, f1;
|
||||
double ts = tonespacing / 4;
|
||||
|
||||
if (sigsearch) {
|
||||
reset_afc();
|
||||
|
@ -595,8 +614,12 @@ void mfsk::afc()
|
|||
return;
|
||||
if (metric < progStatus.sldrSquelchValue)
|
||||
return;
|
||||
if (afcmetric < 6.0)
|
||||
if (afcmetric < 3.0)
|
||||
return;
|
||||
if (currsymbol != prev1symbol)
|
||||
return;
|
||||
// if (prev1symbol != prev2symbol)
|
||||
// return;
|
||||
|
||||
if (pipeptr == 0)
|
||||
prevvector = pipe[2*symlen - 1].vector[currsymbol];
|
||||
|
@ -607,16 +630,13 @@ void mfsk::afc()
|
|||
f = z.arg() * samplerate / TWOPI;
|
||||
|
||||
f1 = tonespacing * (basetone + currsymbol);
|
||||
f1 -= f;
|
||||
|
||||
f1 /= numtones;
|
||||
|
||||
f2 = CLAMP ( f1, freqerr - ts, freqerr + ts);
|
||||
if ( fabs(f1 - f) < ts) {
|
||||
freqerr = decayavg(freqerr, (f1 - f), 32);
|
||||
set_freq(frequency - freqerr);
|
||||
set_AFCind( freqerr );
|
||||
}
|
||||
|
||||
freqerr = decayavg ( freqerr, f2, 128 );
|
||||
|
||||
set_freq(frequency - freqerr);
|
||||
set_AFCind( freqerr );
|
||||
}
|
||||
|
||||
void mfsk::eval_s2n()
|
||||
|
@ -691,15 +711,21 @@ int mfsk::rx_process(const double *buf, int len)
|
|||
|
||||
currsymbol = harddecode(bins);
|
||||
currvector = bins[currsymbol];
|
||||
// frequency tracking
|
||||
afc();
|
||||
|
||||
eval_s2n();
|
||||
// decode symbol
|
||||
softdecode(bins);
|
||||
|
||||
// frequency tracking
|
||||
// afc();
|
||||
// eval_s2n();
|
||||
// decode symbol
|
||||
// softdecode(bins);
|
||||
|
||||
// symbol sync
|
||||
synchronize();
|
||||
|
||||
// frequency tracking
|
||||
afc();
|
||||
eval_s2n();
|
||||
|
||||
prev2symbol = prev1symbol;
|
||||
prev2vector = prev1vector;
|
||||
prev1symbol = currsymbol;
|
||||
|
@ -889,8 +915,9 @@ int mfsk::tx_process()
|
|||
return -1;
|
||||
|
||||
case TX_STATE_PICTURE_START:
|
||||
memset(picprologue, 0, 44);
|
||||
sendpic(picprologue, 44);
|
||||
// 176 samples
|
||||
memset(picprologue, 0, 44 * 8 / TXspp);
|
||||
sendpic(picprologue, 44 * 8 / TXspp);
|
||||
txstate = TX_STATE_PICTURE;
|
||||
break;
|
||||
|
||||
|
@ -925,7 +952,6 @@ int mfsk::tx_process()
|
|||
btnpicTxClose->show();
|
||||
abortxmt = false;
|
||||
rxstate = RX_STATE_DATA;
|
||||
counter = 0;
|
||||
memset(picheader, ' ', PICHEADER - 1);
|
||||
picheader[PICHEADER -1] = 0;
|
||||
FL_UNLOCK_E();
|
||||
|
|
|
@ -22,6 +22,7 @@ modem *mfsk32_modem = 0;
|
|||
modem *mfsk4_modem = 0;
|
||||
modem *mfsk11_modem = 0;
|
||||
modem *mfsk22_modem = 0;
|
||||
modem *mfsk31_modem = 0;
|
||||
modem *mfsk64_modem = 0;
|
||||
|
||||
modem *mt63_500_modem = 0;
|
||||
|
|
|
@ -966,23 +966,23 @@ int FTextEdit::handle_key(int key)
|
|||
break;
|
||||
}
|
||||
|
||||
// insert a macro
|
||||
if (key >= FL_F && key <= FL_F_Last && insert_position() >= txpos)
|
||||
return handle_key_macro(key);
|
||||
// insert a macro
|
||||
if (key >= FL_F && key <= FL_F_Last && insert_position() >= txpos)
|
||||
return handle_key_macro(key);
|
||||
|
||||
// read ctl-ddd, where d is a digit, as ascii characters (in base 10)
|
||||
// and insert verbatim; e.g. ctl-001 inserts a <soh>
|
||||
if (Fl::event_state() & FL_CTRL && (isdigit(key) || isdigit(key - FL_KP)) &&
|
||||
insert_position() >= txpos)
|
||||
return handle_key_ascii(key);
|
||||
ascii_cnt = 0; // restart the numeric keypad entries.
|
||||
ascii_chr = 0;
|
||||
// do not insert printable characters in the transmitted text
|
||||
if (insert_position() < txpos) {
|
||||
int d;
|
||||
if (Fl::compose(d))
|
||||
return 1;
|
||||
}
|
||||
// read ctl-ddd, where d is a digit, as ascii characters (in base 10)
|
||||
// and insert verbatim; e.g. ctl-001 inserts a <soh>
|
||||
if (Fl::event_state() & FL_CTRL && (isdigit(key) || isdigit(key - FL_KP)) &&
|
||||
insert_position() >= txpos)
|
||||
return handle_key_ascii(key);
|
||||
ascii_cnt = 0; // restart the numeric keypad entries.
|
||||
ascii_chr = 0;
|
||||
// do not insert printable characters in the transmitted text
|
||||
if (insert_position() < txpos) {
|
||||
int d;
|
||||
if (Fl::compose(d))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue