kopia lustrzana https://github.com/jamescoxon/dl-fldigi
Upstream version 1.36e
rodzic
a4c5c49d9d
commit
81f00f6652
|
@ -71,9 +71,9 @@ TextBase::TextBase(int x, int y, int w, int h, const char *l)
|
|||
highlight_data(sbuf, styles, NSTYLES, DEFAULT, 0, 0);
|
||||
|
||||
wrap_mode(wrap, wrap_col);
|
||||
// change by W1HKJ
|
||||
// scrollbar_width((int)floor(scrollbar_width() * 3.0/4.0));
|
||||
scrollbar_width(16);
|
||||
|
||||
// Do we want narrower scrollbars? The default width is 16.
|
||||
// scrollbar_width((int)floor(scrollbar_width() * 3.0/4.0));
|
||||
|
||||
// set some defaults
|
||||
set_style(NSTYLES, FL_COURIER, 12, FL_FOREGROUND_COLOR);
|
||||
|
@ -115,7 +115,7 @@ void TextBase::resize(int X, int Y, int W, int H)
|
|||
#ifdef HSCROLLBAR_KLUDGE
|
||||
# include "TextView_resize.cxx"
|
||||
#else
|
||||
Fl_Text_Editor::resize(int X, int Y, int W, int H);
|
||||
Fl_Text_Editor::resize(X, Y, W, H);
|
||||
#endif // HSCROLLBAR_KLUDGE
|
||||
}
|
||||
|
||||
|
@ -467,30 +467,9 @@ void TextView::changed_cb(int pos, int nins, int ndel, int nsty, const char *dte
|
|||
// it to run *before* our callback, so call it now.
|
||||
v->buffer_modified_cb(pos, nins, ndel, nsty, dtext, arg);
|
||||
|
||||
// Is the last line visible? To scroll when it isn't would make
|
||||
// text selection impossible while receiving.
|
||||
if (v->mTopLineNum + v->mNVisibleLines > v->mNBufferLines) {
|
||||
if (v->wrap) {
|
||||
// v->scroll(v->mNBufferLines, 0);
|
||||
|
||||
// The scrolling code below is a little expensive, but
|
||||
// takes care of the only known case where the simple
|
||||
// scroll above is not enough. Specifically, the height
|
||||
// of the widget and font can be such that the last text
|
||||
// line is partially outside the text area, but
|
||||
// technically still visible. This can only happen once,
|
||||
// until the next newline displays the scrollbar, so I
|
||||
// am just being pedantic here.
|
||||
|
||||
// scroll if the last character is vertically outside the text area
|
||||
int x, y;
|
||||
if (v->position_to_xy(v->tbuf->length() - 1, &x, &y) == 0 ||
|
||||
y + fl_height() >= v->text_area.h)
|
||||
v->show_insert_position();
|
||||
}
|
||||
else
|
||||
v->show_insert_position();
|
||||
}
|
||||
// Only scroll when the end of the text is visible.
|
||||
if (v->mTopLineNum - 1 + v->mNVisibleLines >= v->mNBufferLines)
|
||||
v->show_insert_position();
|
||||
}
|
||||
|
||||
/// Removes Fl_Text_Edit keybindings that would modify text and put it out of
|
||||
|
@ -616,10 +595,21 @@ void TextEdit::add(const char *s, text_attr_t attr)
|
|||
char a[n + 1];
|
||||
memset(a, attr, n);
|
||||
a[n] = '\0';
|
||||
sbuf->replace(sbuf->length() - n, sbuf->length(), a);
|
||||
sbuf->replace(insert_position() - n, insert_position(), a);
|
||||
}
|
||||
|
||||
insert_position(tbuf->length());
|
||||
show_insert_position();
|
||||
/// @see TextEdit::add
|
||||
///
|
||||
/// @param s
|
||||
/// @param attr
|
||||
///
|
||||
void TextEdit::add(char c, text_attr_t attr)
|
||||
{
|
||||
char s[] = { c, '\0' };
|
||||
insert(s);
|
||||
|
||||
s[0] = attr;
|
||||
sbuf->replace(insert_position() - 1, insert_position(), s);
|
||||
}
|
||||
|
||||
/// Clears the buffer.
|
||||
|
@ -777,17 +767,15 @@ int TextEdit::handle_key(int key)
|
|||
// return 1;
|
||||
// break;
|
||||
default:
|
||||
if (key >= FL_F && key <= FL_F_Last) { // insert a macro
|
||||
int b = key - FL_F - 1;
|
||||
if (b > 9)
|
||||
return 0;
|
||||
// insert a macro
|
||||
if (key >= FL_F && key <= FL_F_Last && insert_position() >= txpos)
|
||||
return handle_key_macro(key);
|
||||
|
||||
b += (altMacros ? 10 : 0);
|
||||
if (!(macros.text[b]).empty())
|
||||
macros.execute(b);
|
||||
|
||||
return 1;
|
||||
}
|
||||
// read A/M-ddd, where d is a digit, as ascii characters (in base 10)
|
||||
// and insert verbatim; e.g. M-001 inserts a <soh>
|
||||
if (Fl::event_state() & (FL_META | FL_ALT) && isdigit(key) &&
|
||||
insert_position() >= txpos)
|
||||
return handle_key_ascii(key);
|
||||
|
||||
// do not insert printable characters in the transmitted text
|
||||
if (insert_position() < txpos) {
|
||||
|
@ -801,6 +789,53 @@ int TextEdit::handle_key(int key)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/// Inserts the macro for function key \c key.
|
||||
///
|
||||
/// @param key An integer in the range [FL_F, FL_F_Last]
|
||||
///
|
||||
/// @return 1
|
||||
///
|
||||
int TextEdit::handle_key_macro(int key)
|
||||
{
|
||||
key -= FL_F + 1;
|
||||
if (key > 9)
|
||||
return 0;
|
||||
|
||||
key += (altMacros ? 10 : 0);
|
||||
if (!(macros.text[key]).empty())
|
||||
macros.execute(key);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/// Composes ascii characters and adds them to the TextEdit buffer.
|
||||
/// Control characters are inserted with the CTRL style. Values larger than 127
|
||||
/// (0x7f) are ignored. We cannot really add NULs for the time being.
|
||||
///
|
||||
/// @param key A digit character
|
||||
///
|
||||
/// @return 1
|
||||
///
|
||||
int TextEdit::handle_key_ascii(int key)
|
||||
{
|
||||
static char ascii_cnt = 0;
|
||||
static unsigned ascii_chr = 0;
|
||||
|
||||
key -= '0';
|
||||
ascii_cnt++;
|
||||
for (int i = 0; i < 3 - ascii_cnt; i++)
|
||||
key *= 10;
|
||||
ascii_chr += key;
|
||||
if (ascii_cnt == 3) {
|
||||
if (ascii_chr <= 0x7F)
|
||||
add(ascii_chr, (iscntrl(ascii_chr) ? CTRL : DEFAULT));
|
||||
ascii_cnt = ascii_chr = 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/// The context menu handler
|
||||
///
|
||||
/// @param val
|
||||
|
|
|
@ -731,7 +731,7 @@ void cb_FontBrowser(Font_Browser*, void* v)
|
|||
TransmitText->setFont(fnt);
|
||||
TransmitText->setFontSize(size);
|
||||
|
||||
progdefaults.Font = (int)(fnt);
|
||||
progdefaults.Fontnbr = (int)(fnt);
|
||||
progdefaults.FontSize = size;
|
||||
// progdefaults.FontColor = (int)clr;
|
||||
|
||||
|
@ -742,7 +742,7 @@ void cb_mnuConfigFonts(Fl_Menu_*, void *) {
|
|||
static Font_Browser *b = (Font_Browser *)0;
|
||||
if (!b) {
|
||||
b = new Font_Browser;
|
||||
b->fontNumber((Fl_Font)progdefaults.Font);
|
||||
b->fontNumber((Fl_Font)progdefaults.Fontnbr);
|
||||
b->fontSize(progdefaults.FontSize);
|
||||
// b->fontColor(progdefaults.FontColor);
|
||||
}
|
||||
|
@ -1341,26 +1341,29 @@ void set_video(double *data, int len)
|
|||
|
||||
void put_rx_char(unsigned int data)
|
||||
{
|
||||
static bool nulinepending = false;
|
||||
static unsigned int last = 0;
|
||||
const char **asc = ascii;
|
||||
rxmsgid = msgget( (key_t) 9876, 0666);
|
||||
|
||||
|
||||
if (mailclient || mailserver || rxmsgid != -1)
|
||||
asc = ascii2;
|
||||
|
||||
if (data == '\r') {
|
||||
ReceiveText->add(asc['\n' & 0x7F], TextBase::RCV);
|
||||
nulinepending = true;
|
||||
} else if (nulinepending && data == '\r') {
|
||||
ReceiveText->add(asc['\n' & 0x7F], TextBase::RCV);
|
||||
} else if (nulinepending && data == '\n') {
|
||||
nulinepending = false;
|
||||
} else if (nulinepending && data != '\n') {
|
||||
ReceiveText->add(asc[data & 0x7F], TextBase::RCV);
|
||||
nulinepending = false;
|
||||
} else {
|
||||
ReceiveText->add(asc[data & 0x7F], TextBase::RCV);
|
||||
switch (data) {
|
||||
case '\n':
|
||||
if (last == '\r')
|
||||
break;
|
||||
// or fall through to insert \n
|
||||
case '\r':
|
||||
ReceiveText->add('\n', TextBase::RCV);
|
||||
break;
|
||||
default:
|
||||
if (asc == ascii2 && iscntrl(data & 0x7F))
|
||||
ReceiveText->add(data & 0x7F, TextBase::CTRL);
|
||||
else
|
||||
ReceiveText->add(asc[data & 0x7F], TextBase::RCV);
|
||||
}
|
||||
last = data;
|
||||
|
||||
if ( rxmsgid != -1) {
|
||||
rxmsgst.msg_type = 1;
|
||||
rxmsgst.c = data & 0x7F;
|
||||
|
@ -1508,17 +1511,20 @@ char get_tx_char(void)
|
|||
|
||||
void put_echo_char(unsigned int data)
|
||||
{
|
||||
static bool nulinepending = false;
|
||||
static unsigned int last = 0;
|
||||
const char **asc = ascii;
|
||||
|
||||
if (mailclient || mailserver || arqmode)
|
||||
asc = ascii2;
|
||||
if (data == '\r' && nulinepending) // reject multiple CRs
|
||||
|
||||
if (data == '\r' && last == '\r') // reject multiple CRs
|
||||
return;
|
||||
if (data == '\r') nulinepending = true;
|
||||
if (nulinepending && data == '\n') {
|
||||
nulinepending = false;
|
||||
}
|
||||
ReceiveText->add(asc[data & 0x7F], TextBase::XMT);
|
||||
if (asc == ascii2 && iscntrl(data & 0x7F))
|
||||
ReceiveText->add(data & 0x7F, TextBase::CTRL);
|
||||
else
|
||||
ReceiveText->add(asc[data & 0x7F], TextBase::XMT);
|
||||
last = data;
|
||||
|
||||
if (Maillogfile)
|
||||
Maillogfile->log_to_file(cLogfile::LOG_TX, asc[data & 0x7F]);
|
||||
if (logging)
|
||||
|
|
|
@ -143,6 +143,7 @@ public:
|
|||
|
||||
virtual int handle(int event);
|
||||
virtual void add(const char *s, text_attr_t attr = DEFAULT);
|
||||
virtual void add(char c, text_attr_t attr = DEFAULT);
|
||||
void clear(void);
|
||||
int nextChar(void);
|
||||
|
||||
|
@ -152,6 +153,8 @@ protected:
|
|||
TX_MENU_WRAP
|
||||
};
|
||||
int handle_key(int key);
|
||||
int handle_key_macro(int key);
|
||||
int handle_key_ascii(int key);
|
||||
virtual void menu_cb(int val);
|
||||
static void changed_cb(int pos, int nins, int ndel, int nsty,
|
||||
const char *dtext, void *arg);
|
||||
|
|
|
@ -66,7 +66,7 @@ struct configuration {
|
|||
// DOMINOEX
|
||||
double DOMINOEX_BW;
|
||||
// User interface data
|
||||
int Font;
|
||||
int Fontnbr;
|
||||
int FontSize;
|
||||
int FontColor;
|
||||
uchar red;
|
||||
|
|
|
@ -87,6 +87,7 @@ private:
|
|||
void update_syncscope();
|
||||
// void goertzel(complex);
|
||||
void afc();
|
||||
void findsignal();
|
||||
|
||||
public:
|
||||
psk(trx_mode mode);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#ifndef _VERSION_H
|
||||
#define _VERSION_H
|
||||
|
||||
#define FLDIGI_VERSION "1.36c"
|
||||
#define FLDIGI_VERSION "1.36e"
|
||||
|
||||
#endif
|
||||
|
|
|
@ -69,8 +69,8 @@ configuration progdefaults = {
|
|||
// DOMINOEX
|
||||
2.0, // double DOMINOEX_BW;
|
||||
//
|
||||
0, // int Font
|
||||
0, // int Fontsize
|
||||
0, // int Fontnbr
|
||||
16, // int Fontsize
|
||||
0, // int Fontcolor
|
||||
0, // uchar red
|
||||
255, // uchar green
|
||||
|
@ -203,7 +203,7 @@ void configuration::writeDefaultsXML()
|
|||
writeXMLdbl(f, "SQUELCH", squelch);
|
||||
writeXMLdbl(f, "WFREFLEVEL", wfRefLevel);
|
||||
writeXMLdbl(f, "WFAMPSPAN", wfAmpSpan);
|
||||
writeXMLint(f, "FONT", Font);
|
||||
writeXMLint(f, "FONT", Fontnbr);
|
||||
writeXMLint(f, "FONTSIZE", FontSize);
|
||||
writeXMLint(f, "FONTCOLOR", FontColor);
|
||||
|
||||
|
@ -326,7 +326,7 @@ void configuration::writeDefaults(ofstream &f)
|
|||
f << rtty_msbfirst << endl;
|
||||
f << oliviatones << endl;
|
||||
f << oliviabw << endl;
|
||||
f << Font << endl;
|
||||
f << Fontnbr << endl;
|
||||
f << FontSize << endl;
|
||||
f << FontColor << endl;
|
||||
f << btnPTTis << endl;
|
||||
|
@ -438,7 +438,7 @@ void configuration::readDefaults(ifstream &f)
|
|||
f >> rtty_msbfirst;
|
||||
f >> oliviatones;
|
||||
f >> oliviabw;
|
||||
f >> Font;
|
||||
f >> Fontnbr;
|
||||
f >> FontSize;
|
||||
f >> FontColor;
|
||||
f >> btnPTTis;
|
||||
|
@ -807,10 +807,10 @@ int configuration::openDefaults() {
|
|||
|
||||
enableMixer(EnableMixer);
|
||||
|
||||
ReceiveText->setFont((Fl_Font)Font);
|
||||
ReceiveText->setFont((Fl_Font)Fontnbr);
|
||||
ReceiveText->setFontSize(FontSize);
|
||||
|
||||
TransmitText->setFont((Fl_Font)Font);
|
||||
TransmitText->setFont((Fl_Font)Fontnbr);
|
||||
TransmitText->setFontSize(FontSize);
|
||||
|
||||
wf->setPrefilter(wfPreFilter);
|
||||
|
|
|
@ -278,53 +278,69 @@ void psk::searchUp()
|
|||
}
|
||||
}
|
||||
|
||||
//static char phasemsg[50];
|
||||
|
||||
void psk::afc()
|
||||
void psk::findsignal()
|
||||
{
|
||||
double error, ftest, sigpwr, noise;
|
||||
if (mailserver && progdefaults.PSKmailSweetSpot)
|
||||
ftest = wf->peakFreq((int)progdefaults.PSKsweetspot, (int) bandwidth);
|
||||
else
|
||||
ftest = wf->peakFreq((int)frequency, (int)(bandwidth) );
|
||||
sigpwr = wf->powerDensity(ftest, bandwidth);
|
||||
noise = wf->powerDensity(ftest + 3 * bandwidth / 2, bandwidth);
|
||||
double ftest, sigpwr, noise;
|
||||
// fast search for peak signal frequency
|
||||
if (sigsearch) {
|
||||
if (mailserver && progdefaults.PSKmailSweetSpot) {
|
||||
ftest = wf->peakFreq((int)(progdefaults.PSKsweetspot), (int) (bandwidth));
|
||||
} else {
|
||||
ftest = wf->peakFreq((int)(frequency), (int)(bandwidth));
|
||||
}
|
||||
sigpwr = wf->powerDensity(ftest, bandwidth);
|
||||
noise = wf->powerDensity(ftest + 3 * bandwidth / 2, bandwidth / 2) +
|
||||
wf->powerDensity(ftest - 3 * bandwidth / 2, bandwidth / 2) + 1e-20;
|
||||
|
||||
freqerr = 0.0;
|
||||
if (sigpwr/noise > 2.0) {//afcthreshold) {
|
||||
if (!mailserver || (mailserver && !progdefaults.PSKmailSweetSpot) ||
|
||||
(mailserver && (fabs(progdefaults.PSKsweetspot - ftest) < 15))) {
|
||||
if ( !mailserver || (mailserver && !progdefaults.PSKmailSweetSpot) ) {
|
||||
if ( fabs(frequency - ftest) < (bandwidth) ) {
|
||||
frequency = ftest;
|
||||
set_freq(frequency);
|
||||
sigsearch--;
|
||||
}
|
||||
} else if (mailserver && (fabs(progdefaults.PSKsweetspot - ftest) < (bandwidth) )) {
|
||||
frequency = ftest;
|
||||
set_freq(frequency);
|
||||
sigsearch--;
|
||||
}
|
||||
}
|
||||
} else if (mailserver && progdefaults.PSKmailSweetSpot) {
|
||||
frequency = progdefaults.PSKsweetspot;
|
||||
set_freq(frequency);
|
||||
}
|
||||
else
|
||||
if (!mailserver)
|
||||
sigsearch = 0;
|
||||
}
|
||||
// continuous AFC based on phase error
|
||||
else if (dcd == true) {
|
||||
error = (phase - bits * M_PI / 2);
|
||||
if (error < M_PI / 2)
|
||||
error += 2 * M_PI;
|
||||
if (error > M_PI / 2)
|
||||
error -= 2 * M_PI;
|
||||
error *= ((samplerate / (symbollen * 2 * M_PI)/16));
|
||||
freqerr = decayavg( freqerr, error, 8);//32);
|
||||
frequency -= freqerr;
|
||||
sigsearch--;
|
||||
|
||||
} else if (mailserver && progdefaults.PSKmailSweetSpot) {
|
||||
frequency = progdefaults.PSKsweetspot;
|
||||
set_freq(frequency);
|
||||
sigsearch = 3;
|
||||
}
|
||||
}
|
||||
|
||||
void psk::afc()
|
||||
{
|
||||
double error;
|
||||
error = (phase - bits * M_PI / 2);
|
||||
if (error < M_PI / 2)
|
||||
error += 2 * M_PI;
|
||||
if (error > M_PI / 2)
|
||||
error -= 2 * M_PI;
|
||||
error *= ((samplerate / (symbollen * 2 * M_PI)/16));
|
||||
if (fabs(error) < (bandwidth / 2.0)) {
|
||||
// freqerr = decayavg( freqerr, error, 4);//32);
|
||||
// frequency -= freqerr;
|
||||
frequency -= error;
|
||||
set_freq (frequency);
|
||||
//sprintf(phasemsg,"%5.4f %8.2f", freqerr, frequency);
|
||||
//put_status(phasemsg);
|
||||
} else if (mailserver && progdefaults.PSKmailSweetSpot)
|
||||
}
|
||||
if (mailserver && progdefaults.PSKmailSweetSpot)
|
||||
sigsearch = 3;
|
||||
}
|
||||
|
||||
void psk::rx_symbol(complex symbol)
|
||||
{
|
||||
// double phase, error;
|
||||
// int bits, n;
|
||||
int n;
|
||||
phase = (prevsymbol % symbol).arg();
|
||||
prevsymbol = symbol;
|
||||
|
@ -358,7 +374,7 @@ void psk::rx_symbol(complex symbol)
|
|||
break;
|
||||
|
||||
default:
|
||||
if (metric > squelch)// && snratio > 0.0)
|
||||
if (metric > squelch)
|
||||
dcd = true;
|
||||
else dcd = false;
|
||||
}
|
||||
|
@ -377,8 +393,6 @@ void psk::rx_symbol(complex symbol)
|
|||
rx_bit(!bits);
|
||||
}
|
||||
|
||||
if (afcon == true)
|
||||
afc();
|
||||
}
|
||||
|
||||
void psk::update_syncscope()
|
||||
|
@ -459,9 +473,13 @@ int psk::rx_process(double *buf, int len)
|
|||
bitclk -= 16;
|
||||
rx_symbol(z);
|
||||
update_syncscope();
|
||||
if (dcd && afcon)
|
||||
afc();
|
||||
}
|
||||
pipeptr = (pipeptr + 1) % PipeLen;
|
||||
}
|
||||
if (!dcd && afcon)
|
||||
findsignal();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -496,7 +514,10 @@ void psk::tx_symbol(int sym)
|
|||
}
|
||||
symbol = prevsymbol * symbol; // complex multiplication
|
||||
|
||||
delta = 2.0 * M_PI * get_txfreq_woffset() / samplerate;
|
||||
if (mailserver && progdefaults.PSKmailSweetSpot)
|
||||
delta = 2.0 * M_PI * (progdefaults.PSKsweetspot - progdefaults.TxOffset) / samplerate;
|
||||
else
|
||||
delta = 2.0 * M_PI * get_txfreq_woffset() / samplerate;
|
||||
|
||||
for (int i = 0; i < symbollen; i++) {
|
||||
|
||||
|
|
|
@ -259,17 +259,20 @@ int WFdisp::peakFreq(int f0, int delta)
|
|||
double avg = 0.0;
|
||||
int f1, fmin = (int)((f0 - delta)),
|
||||
f2, fmax = (int)((f0 + delta));
|
||||
f1 = fmax; f2 = fmin;
|
||||
f1 = fmin; f2 = fmax;
|
||||
if (fmin < 0 || fmax > image_width) return f0;
|
||||
for (int f = fmin; f <= fmax; f++)
|
||||
avg += pwr[f];
|
||||
avg /= 2*(delta + 1);
|
||||
for (int f = fmin; f <= fmax; f++)
|
||||
if (pwr[f] > avg) {
|
||||
if (f < f1) f1 = f;
|
||||
if (f > f2) f2 = f;
|
||||
f1 = f;
|
||||
}
|
||||
return (int)((f1 + f2) / 2.0);
|
||||
for (int f = fmax; f >= fmin; f--)
|
||||
if (pwr[f] > avg) {
|
||||
f2 = f;
|
||||
}
|
||||
return (f1 + f2) / 2;
|
||||
}
|
||||
|
||||
double WFdisp::powerDensity(double f0, double bw)
|
||||
|
|
Ładowanie…
Reference in New Issue