Upstream version 2.11T

pull/2/head
Stelios Bounanos 2008-04-28 01:19:25 +01:00
rodzic 92268e341f
commit 967748da7d
13 zmienionych plików z 249 dodań i 229 usunięć

Wyświetl plik

@ -36,6 +36,13 @@ Change Log:
2) fading fixed length vector display
3) fading variable length vector display; length proportional to
signal quality.
18) Completely new DominoEX decoder - similar in theory to ZL2AFP
DominoEX, which has FFT bin resolution 4x the tone spacing. No AFC is
required for proper tracking of the Rx signal.
19) Removed ZOH and Linear interpolator choices from the resampling choice
menu under Sound Card configuration.
20) Fixed a bug in the global.cxx structures. Missing field in "CW"
definition.
2.10.3)
1) Corrected memory leak bug.

Wyświetl plik

@ -9,7 +9,7 @@ dnl major and minor must be integers; patch may
dnl contain other characters or be empty
m4_define(FLDIGI_MAJOR, [2])
m4_define(FLDIGI_MINOR, [11])
m4_define(FLDIGI_PATCH, [S])
m4_define(FLDIGI_PATCH, [T])
AC_INIT([fldigi], FLDIGI_MAJOR.FLDIGI_MINOR[FLDIGI_PATCH], [w1hkj AT w1hkj DOT com])

Wyświetl plik

@ -881,8 +881,9 @@ Fl_Group *tabDomEX=(Fl_Group *)0;
Fl_Input *txtSecondary=(Fl_Input *)0;
static void cb_txtSecondary(Fl_Input*, void*) {
progdefaults.changed = true;
static void cb_txtSecondary(Fl_Input* o, void*) {
progdefaults.secText = o->value();
progdefaults.changed = true;
}
Fl_Button *btnRestartDomEX=(Fl_Button *)0;
@ -1669,6 +1670,7 @@ static const char szBaudRates[] = "300|600|1200|2400|4800|9600|19200|38400|57600
{ tabAudio = new Fl_Group(0, 50, 400, 170, "Audio devices");
tabAudio->color((Fl_Color)51);
tabAudio->selection_color((Fl_Color)51);
tabAudio->hide();
{ AudioOSS = new Fl_Group(5, 58, 391, 35);
AudioOSS->box(FL_ENGRAVED_FRAME);
{ btnAudioIO[0] = new Fl_Round_Button(5, 63, 100, 25, "OSS");
@ -1727,7 +1729,6 @@ static const char szBaudRates[] = "300|600|1200|2400|4800|9600|19200|38400|57600
{ tabAudioOpt = new Fl_Group(0, 50, 400, 170, "Audio settings");
tabAudioOpt->color((Fl_Color)51);
tabAudioOpt->selection_color((Fl_Color)51);
tabAudioOpt->hide();
{ Fl_Spinner* o = cntRxRateCorr = new Fl_Spinner(5, 160, 85, 25, "RX ppm");
cntRxRateCorr->value(1);
cntRxRateCorr->callback((Fl_Callback*)cb_cntRxRateCorr);
@ -2019,14 +2020,15 @@ l with your sound hardware.");
{ tabDomEX = new Fl_Group(0, 50, 400, 170, "DomEX");
tabDomEX->color((Fl_Color)51);
tabDomEX->selection_color((Fl_Color)51);
tabDomEX->hide();
{ txtSecondary = new Fl_Input(20, 75, 360, 44, "Secondary Text");
txtSecondary->type(4);
txtSecondary->callback((Fl_Callback*)cb_txtSecondary);
txtSecondary->align(FL_ALIGN_TOP_LEFT);
txtSecondary->when(FL_WHEN_CHANGED);
} // Fl_Input* txtSecondary
{ btnRestartDomEX = new Fl_Button(300, 172, 79, 28, "Restart");
btnRestartDomEX->callback((Fl_Callback*)cb_btnRestartDomEX);
btnRestartDomEX->hide();
} // Fl_Button* btnRestartDomEX
{ Fl_Counter* o = valDominoEX_BW = new Fl_Counter(25, 134, 63, 21, "BW factor:");
valDominoEX_BW->type(1);
@ -2035,6 +2037,7 @@ l with your sound hardware.");
valDominoEX_BW->step(0.1);
valDominoEX_BW->value(2);
valDominoEX_BW->callback((Fl_Callback*)cb_valDominoEX_BW);
valDominoEX_BW->hide();
o->value(progdefaults.DOMINOEX_BW);
} // Fl_Counter* valDominoEX_BW
tabDomEX->end();
@ -2250,6 +2253,7 @@ l with your sound hardware.");
{ tabRTTY = new Fl_Group(0, 50, 400, 170, "RTTY");
tabRTTY->color((Fl_Color)51);
tabRTTY->selection_color((Fl_Color)51);
tabRTTY->hide();
{ Fl_Choice* o = selShift = new Fl_Choice(48, 60, 77, 22, "Shift");
selShift->down_box(FL_BORDER_BOX);
selShift->callback((Fl_Callback*)cb_selShift);

Wyświetl plik

@ -661,7 +661,7 @@ o->label((inpQRZuserpassword->type() & FL_SECRET_INPUT) ? "Show" : "Hide");}
} {
Fl_Group tabAudio {
label {Audio devices} open
xywh {0 50 400 170} color 51 selection_color 51
xywh {0 50 400 170} color 51 selection_color 51 hide
} {
Fl_Group AudioOSS {open
xywh {5 58 391 35} box ENGRAVED_FRAME
@ -743,7 +743,7 @@ resetSoundCard();}
}
Fl_Group tabAudioOpt {
label {Audio settings} open
xywh {0 50 400 170} color 51 selection_color 51 hide
xywh {0 50 400 170} color 51 selection_color 51
} {
Fl_Spinner cntRxRateCorr {
label {RX ppm}
@ -1037,24 +1037,25 @@ progdefaults.changed = true;}
}
Fl_Group tabDomEX {
label DomEX open
xywh {0 50 400 170} color 51 selection_color 51 hide
xywh {0 50 400 170} color 51 selection_color 51
} {
Fl_Input txtSecondary {
label {Secondary Text}
callback {progdefaults.changed = true;}
xywh {20 75 360 44} type Multiline align 5
callback {progdefaults.secText = o->value();
progdefaults.changed = true;} selected
xywh {20 75 360 44} type Multiline align 5 when 1
}
Fl_Button btnRestartDomEX {
label Restart
callback {progdefaults.storeDefaults();
resetDOMEX();}
xywh {300 172 79 28}
xywh {300 172 79 28} hide
}
Fl_Counter valDominoEX_BW {
label {BW factor:}
callback {progdefaults.DOMINOEX_BW=o->value();
progdefaults.changed = true;}
xywh {25 134 63 21} type Simple minimum 1 maximum 3 step 0.1 value 2
xywh {25 134 63 21} type Simple minimum 1 maximum 3 step 0.1 value 2 hide
code0 {o->value(progdefaults.DOMINOEX_BW);}
}
}
@ -1289,7 +1290,7 @@ progdefaults.changed = true;}
}
Fl_Group tabRTTY {
label RTTY open
xywh {0 50 400 170} color 51 selection_color 51
xywh {0 50 400 170} color 51 selection_color 51 hide
} {
Fl_Choice selShift {
label Shift
@ -1327,7 +1328,7 @@ resetRTTY();} open
label Stop
callback {progdefaults.changed = true;
progdefaults.storeDefaults();
resetRTTY();} open selected
resetRTTY();} open
xywh {48 158 77 22} down_box BORDER_BOX when 1
code0 {o->add(szStopBits);}
} {}

Wyświetl plik

@ -1725,7 +1725,7 @@ void put_sec_char( char chr )
{
if (chr >= ' ' && chr <= 'z') {
strSecText.append(1, chr);
if (strSecText.length() > 60)
if (strSecText.length() > 50)
strSecText.erase(0,1);
FL_LOCK_D();
REQ(static_cast<void (Fl_Box::*)(const char *)>(&Fl_Box::label), StatusBar, strSecText.c_str());

Wyświetl plik

@ -1,10 +1,7 @@
//
// dominoex.cxx -- DominoEX modem
//
// Copyright (C) 2001, 2002, 2003
// Tomi Manninen (oh2bns@sral.fi)
// Copyright (C) 2006
// Hamish Moffatt (hamish@debian.org)
// Copyright (C) 2008
// Copyright (C) 2006
// David Freese (w1hkj@w1hkj.com)
// fldigi is free software; you can redistribute it and/or modify
@ -40,10 +37,6 @@
using namespace std;
#define RESOLUTION 1
#define AFC_COUNT 64
char dommsg[80];
void dominoex::tx_init(SoundBase *sc)
@ -52,7 +45,7 @@ void dominoex::tx_init(SoundBase *sc)
txstate = TX_STATE_PREAMBLE;
txprevtone = 0;
counter = 0;
phaseacc = 0.0;
txphase = 0;
videoText();
}
@ -63,34 +56,37 @@ void dominoex::rx_init()
met1 = 0.0;
met2 = 0.0;
counter = 0;
phaseacc = 0.0;
freqerr = 0.0;
phase[0] = phase[1] = phase[2] = phase[3] = 0.0;
put_MODEstatus(mode);
put_sec_char(0);
}
void dominoex::restart()
{
double flo, fhi, bw, cf;
// basetone is always 1000 Hz
// mid frequency is always 1000 Hz + bandwidth / 2
/*
double flo, fhi, bw, cf;
bw = bandwidth * progdefaults.DOMINOEX_BW;
cf = 1000.0 + bandwidth / 2.0;
flo = (cf - bw/2) / samplerate;
fhi = (cf + bw/2) / samplerate;
if (filt)
filt->init_bandpass (127, 1, flo, fhi);
if (filt[0])
filt[0]->init_bandpass (127, 1, flo, fhi);
if (filt[1])
filt[1]->init_bandpass (127, 1, flo, fhi);
if (filt[2])
filt[2]->init_bandpass (127, 1, flo, fhi);
if (filt[3])
filt[3]->init_bandpass (127, 1, flo, fhi);
*/
strSecXmtText = txtSecondary->value();
if (strSecXmtText.length() == 0)
strSecXmtText = "fldigi "PACKAGE_VERSION" ";
prev1symbol = prev2symbol = 0;
prev1vector = prev2vector = complex(0.0, 0.0);
// prev1vector = prev2vector = complex(0.0, 0.0);
}
@ -104,17 +100,25 @@ void dominoex::init()
dominoex::~dominoex()
{
if (binsfft) delete binsfft;
if (hilbert) delete hilbert;
/*
if (filt[0]) delete filt[0];
if (filt[1]) delete filt[1];
if (filt[2]) delete filt[2];
if (filt[3]) delete filt[3];
*/
if (binsfft[0]) delete binsfft[0];
if (binsfft[1]) delete binsfft[1];
if (binsfft[2]) delete binsfft[2];
if (binsfft[3]) delete binsfft[3];
if (pipe) delete [] pipe;
if (filt) delete filt;
}
dominoex::dominoex(trx_mode md)
{
double cf, bw, flo, fhi;
// double cf, bw, flo, fhi;
numtones = DOMNUMTONES;
mode = md;
switch (mode) {
@ -171,44 +175,64 @@ dominoex::dominoex(trx_mode md)
tonespacing = (double) (samplerate * ((doublespaced) ? 2 : 1)) / symlen;
// binsfft = new sfft( symlen,
// basetone - numtones*(doublespaced?2:1),
// basetone + 2*numtones*(doublespaced ? 2 : 1) );
//exp
binsfft = new sfft( RESOLUTION * symlen,
RESOLUTION * (basetone - numtones*(doublespaced ? 2 : 1)),
RESOLUTION * (basetone + 2*numtones*(doublespaced ? 2 : 1)) );
binsfft[0] = new sfft( symlen,
basetone - 1 * NUMTONES,
basetone + 2 * NUMTONES );
// basetone - 2 * NUMTONES,
// basetone + 4 * NUMTONES );
binsfft[1] = new sfft( symlen,
basetone - 1 * NUMTONES,
basetone + 2 * NUMTONES );
// basetone - 2 * NUMTONES,
// basetone + 4 * NUMTONES );
binsfft[2] = new sfft( symlen,
basetone - 1 * NUMTONES,
basetone + 2 * NUMTONES );
// basetone - 2 * NUMTONES,
// basetone + 4 * NUMTONES );
binsfft[3] = new sfft( symlen,
basetone - 1 * NUMTONES,
basetone + 2 * NUMTONES );
// basetone - 2 * NUMTONES,
// basetone + 4 * NUMTONES );
hilbert = new C_FIR_filter();
hilbert->init_hilbert(37, 1);
afcfilt = new Cmovavg(AFC_COUNT);
twosym = 2 * symlen;
pipe = new domrxpipe[twosym];
scopedata.alloc(twosym);
videodata.alloc(RESOLUTION * numtones * 6);
videodata.alloc(NUMBINS);
pipeptr = 0;
symcounter = 0;
metric = 0.0;
bandwidth = numtones * tonespacing;
bw = bandwidth * progdefaults.DOMINOEX_BW;
bandwidth = NUMTONES * tonespacing;
/*
bw = bandwidth * 2.0; //progdefaults.DOMINOEX_BW;
cf = 1000.0 + bandwidth / 2.0;
flo = (cf - bw/2) / samplerate;
fhi = (cf + bw/2) / samplerate;
filt = new C_FIR_filter();
filt->init_bandpass (127, 1, flo, fhi);
filt[0] = new C_FIR_filter();
filt[0]->init_bandpass (127, 1, flo, fhi);
filt[1] = new C_FIR_filter();
filt[1]->init_bandpass (127, 1, flo, fhi);
filt[2] = new C_FIR_filter();
filt[2]->init_bandpass (127, 1, flo, fhi);
filt[3] = new C_FIR_filter();
filt[3]->init_bandpass (127, 1, flo, fhi);
*/
fragmentsize = symlen;
s2n = 0.0;
prev1symbol = prev2symbol = 0;
prev1vector = prev2vector = complex(0.0, 0.0);
// prev1vector = prev2vector = complex(0.0, 0.0);
init();
}
@ -216,19 +240,21 @@ dominoex::dominoex(trx_mode md)
//=====================================================================
// rx modules
complex dominoex::mixer(complex in, double f)
complex dominoex::mixer(int n, complex in)
{
complex z;
double f;
// Basetone is always 1000 Hz
f -= (1000.0 + bandwidth/2);
z.re = cos(phaseacc);
z.im = sin(phaseacc);
// 4 mixers are supported each separated by 1/4 bin size
f = frequency - 1000.0 - bandwidth/2 + (samplerate / symlen) * (n / 4.0);
z.re = cos(phase[n]);
z.im = sin(phase[n]);
z = z * in;
phaseacc -= twopi * f / samplerate;
if (phaseacc > M_PI)
phaseacc -= twopi;
else if (phaseacc < M_PI)
phaseacc += twopi;
phase[n] -= twopi * f / samplerate;
if (phase[n] > M_PI)
phase[n] -= twopi;
else if (phase[n] < M_PI)
phase[n] += twopi;
return z;
}
@ -242,20 +268,19 @@ void dominoex::recvchar(int c)
put_rx_char(c & 0xFF);
}
void dominoex::decodesymbol(unsigned char curtone, unsigned char prevtone)
void dominoex::decodesymbol()
{
int c, sym, ch;
int diff;
// Decode the IFK+ sequence, which results in a single nibble
diff = curtone - prevtone;
diff = currsymbol - prev1symbol;
if (reverse) diff = -diff;
diff /= 4; // 4 sets of interleaved bins
if (doublespaced) diff /= 2;
diff /= RESOLUTION;
diff -= 2;
if (diff < 0) diff += numtones;
if (diff < 0) diff += NUMTONES;
c = diff;
// If the new symbol is the start of a new character (MSB is low), complete the previous character
@ -283,13 +308,12 @@ void dominoex::decodesymbol(unsigned char curtone, unsigned char prevtone)
}
int dominoex::harddecode(complex *in)
int dominoex::harddecode()
{
double x, max = 0.0;
int symbol = 0;
int count = RESOLUTION * numtones * 3 *(doublespaced?2:1);
for (int i = 0; i < count; i++) {
x = in[i].mag();
for (int i = 0; i < NUMBINS; i++) {
x = pipe[pipeptr].vector[i].mag();
if (x > max) {
max = x;
symbol = i;
@ -298,22 +322,22 @@ int dominoex::harddecode(complex *in)
return symbol;
}
void dominoex::update_syncscope(complex *bins)
void dominoex::update_syncscope()
{
/*
double max = 0, min = 1e6, range, mag;
int numbins = RESOLUTION * (numtones * 3 * (doublespaced ? 2 : 1)); //exp
// dom waterfall
for (int i = 0; i < numbins; i++ ) {
mag = bins[i].mag();
for (int i = 0; i < NUMBINS; i++ ) {
mag = pipe[pipeptr].vector[i].mag();
if (max < mag) max = mag;
if (min > mag) min = mag;
}
range = max - min;
memset(videodata, 0, numbins * sizeof(double));
for (int i = 0; i < numbins; i++ ) {
memset(videodata, 0, NUMBINS * sizeof(double));
for (int i = 0; i < NUMBINS; i++ ) {
if (range > 2) {
mag = (bins[i].mag() - min) / range;
mag = (pipe[pipeptr].vector[i].mag() - min) / range;
mag = 1 + log10(mag);
if (mag < 0) mag = 0;
} else
@ -321,14 +345,15 @@ void dominoex::update_syncscope(complex *bins)
videodata[i] = 255*mag;
}
if (!progStatus.sqlonoff || metric >= progStatus.sldrSquelchValue) {
set_video(videodata, numbins);
set_video(videodata, NUMBINS);
videodata.next(); // change buffers
}
*/
// dom symbol synch data
memset(scopedata, 0, twosym * sizeof(double));
if (!progStatus.sqlonoff || metric >= progStatus.sldrSquelchValue) {
for (int i = 0, j = 0; i < twosym; i++) {
for (unsigned int i = 0, j = 0; i < twosym; i++) {
j = (pipeptr + i + 1) % (twosym);
scopedata[i] = pipe[j].vector[prev1symbol].mag();
}
@ -347,7 +372,7 @@ void dominoex::synchronize()
if (prev1symbol == prev2symbol)
return;
for (int i = 0, j = pipeptr; i < twosym; i++) {
for (unsigned int i = 0, j = pipeptr; i < twosym; i++) {
val = (pipe[j].vector[prev1symbol]).mag();
if (val > max) {
max = val;
@ -355,107 +380,65 @@ void dominoex::synchronize()
}
j = (j + 1) % twosym;
}
synccounter += (int) floor(1.0 * (syn - symlen) / numtones + 0.5);
synccounter += (int) floor(1.0 * (syn - symlen) / NUMTONES + 0.5);
}
void dominoex::reset_afc() {
freqerr = 0.0;
// for (int i = 0; i < AFC_COUNT; i++) afcfilt->run(0.0);
afcfilt->reset();
return;
}
void dominoex::afc()
void dominoex::eval_s2n()
{
complex z;
complex vec1, vec2;
double f, fsym, err;
double ds = doublespaced ? 2 : 1;
if (currsymbol != prev1symbol && prev1symbol != prev2symbol) {
sig = pipe[pipeptr].vector[currsymbol].mag();
noise = pipe[pipeptr].vector[prev2symbol].mag();
if (sigsearch) {
reset_afc();
sigsearch = 0;
}
if (noise < 1.0e-6) noise = 1e-6;
s2n = decayavg( s2n, sig / noise, 8);
vec1 = pipe[pipeptr].vector[currsymbol];
if (pipeptr == 0)
vec2 = pipe[2*symlen].vector[currsymbol];
else
vec2 = pipe[pipeptr - 1].vector[currsymbol];
// z = prevvector % currvector;
z = vec2 % vec1;
f = z.arg() * samplerate / twopi;
fsym = (currsymbol/RESOLUTION - numtones * ds) * samplerate / symlen;
fsym += 1000;
err = fsym - f;
// freqerr = afcfilt->run(err / numtones);
freqerr = decayavg(freqerr, err / numtones, 32);
//std::cout << currsymbol << ", " << fsym << ", " << f << ", " << err << ", " << freqerr << std::endl;
if (progStatus.afconoff && (metric > progStatus.sldrSquelchValue || progStatus.sqlonoff == false)) {
set_freq(frequency - freqerr);
metric = 20*log10(s2n);
display_metric(metric);
snprintf(dommsg, sizeof(dommsg), "s/n %3.0f dB", metric);
put_Status1(dommsg);
}
}
void dominoex::eval_s2n(complex curr, complex n)
{
sig = curr.mag(); // signal + noise energy
noise = n.mag();// + 1e-10; // noise energy
if (noise < 1e-20) noise = 1e-20;
s2n = decayavg( s2n, sig / noise, 8);
metric = 20*log10(s2n);
display_metric(metric);
snprintf(dommsg, sizeof(dommsg), "s/n %3.0f dB", metric);
put_Status1(dommsg);
}
int testcount = 2;
int dominoex::rx_process(const double *buf, int len)
{
complex z, *bins, noise;
complex zref, z, *bins;
while (len) {
// create analytic signal...shift in frequency to base band & bandpass filter
z.re = z.im = *buf++;
hilbert->run(z, z);
z = mixer(z, frequency);
filt->run(z, z);
// feed it to the sliding FFT
bins = binsfft->run(z);
zref.re = zref.im = *buf++;
hilbert->run(zref, zref);
// copy current vector to the pipe
for (int i = 0; i < RESOLUTION * numtones * 3 * (doublespaced?2:1); i++) {
pipe[pipeptr].vector[i] = bins[i];
// process 4 sets of sliding FFTs spaced at 1/4 bin intervals each of which
// is a matched filter for the current symbol length
for (int n = 0; n < 4; n++) {
z = mixer(n, zref);
// filt[n]->run(z, z);
// feed it to the sliding FFTs
bins = binsfft[n]->run(z);
// copy current vector to the pipe interleaving the FFT vectors
for (int i = 0; i < NUMTONES * 3; i++) { // NUMTONES * 6; i++) {
pipe[pipeptr].vector[n + 4 * i] = bins[i];
}
}
if (--synccounter <= 0) {
synccounter = symlen;
currsymbol = harddecode(bins);
//std::cout << currsymbol << " "; std::cout.flush();
currvector = bins[currsymbol];
currsymbol = harddecode();
// currvector = pipe[pipeptr].vector[currsymbol];
// decode symbol
decodesymbol(currsymbol, prev1symbol);
// update the scope
// update_syncscope(bins);
decodesymbol();
// symbol sync
synchronize();
// update the scope
update_syncscope(bins);
// frequency tracking
afc();
eval_s2n(currvector, bins[RESOLUTION * (numtones + 2) * (doublespaced ? 2 : 1)]);
update_syncscope();
// evaluate signal to noise ratio
eval_s2n();
prev2symbol = prev1symbol;
prev2vector = prev1vector;
prev1symbol = currsymbol;
prev1vector = currvector;
}
pipeptr++;
if (pipeptr >= twosym)
@ -486,22 +469,22 @@ void dominoex::sendsymbol(int sym)
int tone;
double f, phaseincr;
tone = (txprevtone + 2 + sym) % numtones;
tone = (txprevtone + 2 + sym) % NUMTONES;
txprevtone = tone;
if (reverse)
tone = (numtones - 1) - tone;
tone = (NUMTONES - 1) - tone;
f = tone * tonespacing + get_txfreq_woffset() - bandwidth / 2;
phaseincr = twopi * f / samplerate;
for (int i = 0; i < symlen; i++) {
outbuf[i] = cos(phaseacc);
phaseacc -= phaseincr;
if (phaseacc > M_PI)
phaseacc -= twopi;
else if (phaseacc < M_PI)
phaseacc += twopi;
outbuf[i] = cos(txphase);
txphase -= phaseincr;
if (txphase > M_PI)
txphase -= twopi;
else if (txphase < M_PI)
txphase += twopi;
}
ModulateXmtr(outbuf, symlen);

Wyświetl plik

@ -43,8 +43,7 @@ const char *state_names[] = {
// Elements are in enum trx_mode order. Mode name video-id uses the
// first string (sname), so its length should be a multiple of 2.
const struct mode_info_t mode_info[NUM_MODES] = {
{ MODE_CW, &cw_modem, "CW", "CW", "CW" },
{ MODE_CW, &cw_modem, "CW", "CW", "CW", "CW" },
{ MODE_DOMINOEX4, &dominoex4_modem, "DomEX4", "DominoEX 4", "DOMINOEX4", "DOMINO" }, // These aren't Domino FEC, right?
{ MODE_DOMINOEX5, &dominoex5_modem, "DomEX5", "DominoEX 5", "DOMINOEX5", "DOMINO" },
{ MODE_DOMINOEX8, &dominoex8_modem, "DomEX8", "DominoEX 8", "DOMINOEX8", "DOMINO" },

Wyświetl plik

@ -38,11 +38,12 @@
using namespace std;
#define MAXRESOLUTION 4
#define DOMNUMTONES 18
#define NUMTONES 18
//#define NUMBINS (4 * NUMTONES * 6)
#define NUMBINS (4 * NUMTONES * 3)
struct domrxpipe {
complex vector[MAXRESOLUTION * DOMNUMTONES * 6]; /* numtones <= 18 */
complex vector[NUMBINS];
};
class dominoex : public modem {
@ -56,9 +57,9 @@ public:
};
protected:
// common variables
double phaseacc;
double phase[4];
double txphase;
int symlen;
int numtones;
int basetone;
int doublespaced;
double tonespacing;
@ -67,9 +68,8 @@ protected:
// rx variables
C_FIR_filter *hilbert;
C_FIR_filter *filt;
sfft *binsfft;
Cmovavg *afcfilt;
C_FIR_filter *filt[4];
sfft *binsfft[4];
domrxpipe *pipe;
unsigned int pipeptr;
@ -78,8 +78,6 @@ protected:
mbuffer<double, 0, 2> videodata;
complex currvector;
complex prev1vector;
complex prev2vector;
int currsymbol;
int prev1symbol;
@ -105,15 +103,15 @@ protected:
string strSecXmtText;
private:
complex mixer(complex in, double f);
complex mixer(int n, complex in);
void recvchar(int c);
void decodesymbol(unsigned char curtone, unsigned char prevtone);
int harddecode(complex *in);
void update_syncscope(complex *);
void decodesymbol();
int harddecode();
void update_syncscope();
void synchronize();
void afc();
void reset_afc();
void eval_s2n(complex, complex);
void eval_s2n();
void sendsymbol(int sym);
void sendchar(unsigned char c, int secondary);
void sendidle();

Wyświetl plik

@ -525,9 +525,12 @@ void mfsk::afc()
void mfsk::eval_s2n(complex c, complex n)
{
sig = c.mag(); // signal + noise energy
noise = n.mag() + 1e-10; // noise energy
noise = n.mag() + 1e-20; // noise energy
s2n = decayavg( s2n, fabs((sig - noise) / noise), 8);
if (metric > progStatus.sldrSquelchValue)
s2n = decayavg( s2n, fabs(sig / noise), 16 );
else
s2n = decayavg( s2n, 1.0, 16 );
}
int mfsk::rx_process(const double *buf, int len)
@ -601,7 +604,7 @@ int mfsk::rx_process(const double *buf, int len)
// frequency tracking
afc();
eval_s2n(currvector, bins[numtones + 2]);
eval_s2n(currvector, bins[(currsymbol + numtones/2) % numtones]);
// decode symbol
softdecode(bins);
// symbol sync

Wyświetl plik

@ -6,6 +6,7 @@
#include "status.h"
#include "configuration.h"
#include "fl_digi.h"
#include "versions.h"
#include "waterfall.h"
@ -115,10 +116,16 @@ void status::saveLastState()
scopeW = scopeview->w();
scopeH = scopeview->h();
}
string str = PACKAGE_NAME;
str.append(" ");
str.append(PACKAGE_VERSION);
string deffname = HomeDir;
deffname.append("fldigi.status");
ofstream deffile(deffname.c_str(), ios::out);
deffile << str.c_str() << endl;
deffile << lastmode << endl;
deffile << mainX << endl;
deffile << mainY << endl;
@ -154,43 +161,51 @@ void status::saveLastState()
void status::loadLastState()
{
char line[255];
string str = PACKAGE_NAME;
str.append(" ");
str.append(PACKAGE_VERSION);
string deffname = HomeDir;
deffname.append("fldigi.status");
ifstream deffile(deffname.c_str(), ios::in);
if (deffile) {
deffile >> lastmode;
deffile >> mainX;
deffile >> mainY;
deffile >> mainW;
deffile >> mainH;
deffile >> rigShown;
deffile >> rigX;
deffile >> rigY;
deffile >> RxTextHeight;
deffile >> carrier;
deffile >> mag;
deffile >> speed;
deffile >> reflevel;
deffile >> ampspan;
deffile >> VIEWERnchars;
deffile >> VIEWERxpos;
deffile >> VIEWERypos;
deffile >> VIEWERvisible;
deffile >> LOGenabled;
deffile >> sldrSquelchValue;
deffile >> afconoff;
deffile >> sqlonoff;
deffile >> RcvMixer;
deffile >> XmtMixer;
deffile >> scopeX;
deffile >> scopeY;
deffile >> scopeVisible;
deffile >> scopeW;
deffile >> scopeH;
deffile.close();
progdefaults.wfRefLevel = reflevel;
progdefaults.wfAmpSpan = ampspan;
bLastStateRead = true;
deffile.getline(line, 255);
if (str == line) {
deffile >> lastmode;
deffile >> mainX;
deffile >> mainY;
deffile >> mainW;
deffile >> mainH;
deffile >> rigShown;
deffile >> rigX;
deffile >> rigY;
deffile >> RxTextHeight;
deffile >> carrier;
deffile >> mag;
deffile >> speed;
deffile >> reflevel;
deffile >> ampspan;
deffile >> VIEWERnchars;
deffile >> VIEWERxpos;
deffile >> VIEWERypos;
deffile >> VIEWERvisible;
deffile >> LOGenabled;
deffile >> sldrSquelchValue;
deffile >> afconoff;
deffile >> sqlonoff;
deffile >> RcvMixer;
deffile >> XmtMixer;
deffile >> scopeX;
deffile >> scopeY;
deffile >> scopeVisible;
deffile >> scopeW;
deffile >> scopeH;
deffile.close();
progdefaults.wfRefLevel = reflevel;
progdefaults.wfAmpSpan = ampspan;
bLastStateRead = true;
}
}
}

Wyświetl plik

@ -1062,7 +1062,7 @@ void SoundPort::src_data_reset(int mode)
rbsize = ceil2((unsigned)(2 * CHANNELS * SCBLOCKSIZE *
MAX(req_sample_rate, sd[0].dev_sample_rate) /
MIN(req_sample_rate, sd[0].dev_sample_rate)));
rbsize = MAX(rbsize, 4096);
rbsize = 2 * MAX(rbsize, 4096);
#ifndef NDEBUG
cerr << "input rbsize=" << rbsize << endl;
#endif

Wyświetl plik

@ -193,8 +193,11 @@ static void sound_init_options(void)
menuOutSampleRate->menu(sample_rate_menu);
const char* cname;
for (int i = 0; (cname = src_get_name(i)); i++)
for (int i = 0; (cname = src_get_name(i)); i++) {
if (strstr( cname, "ZOH") != 0) continue;
if (strstr( cname, "Linear") != 0) continue;
menuSampleConverter->add(cname);
}
menuSampleConverter->value(progdefaults.sample_converter);
menuSampleConverter->tooltip(src_get_description(progdefaults.sample_converter));

Wyświetl plik

@ -396,7 +396,7 @@ void Digiscope::draw_video()
void Digiscope::draw()
{
draw_box();
if (_mode == WWV || _mode == DOMWF)
if (_mode == WWV) // || _mode == DOMWF)
draw_video();
else {
switch (_mode) {
@ -407,7 +407,14 @@ void Digiscope::draw()
case XHAIRS : draw_xy(); break;
case DOMDATA : draw_scope(); break;
case BLANK :
default: break;
default:
fl_clip(x()+2,y()+2,w()-4,h()-4);
fl_color(FL_BLACK);
fl_rectf(x()+2,y()+2,w()-4,h()-4);
fl_push_matrix();
fl_pop_matrix();
fl_pop_clip();
break;
}
}
}
@ -432,12 +439,12 @@ int Digiscope::handle(int event)
case XHAIRS:
_mode = RTTY;
break;
case DOMDATA:
_mode = DOMWF;
break;
case DOMWF:
_mode = DOMDATA;
break;
// case DOMDATA:
// _mode = DOMWF;
// break;
// case DOMWF:
// _mode = DOMDATA;
// break;
case WWV:
event = Fl::event_button();
if (event == FL_LEFT_MOUSE)