From 81f00f66526a69547e874d3ee5522b192bb0ebb1 Mon Sep 17 00:00:00 2001 From: Stelios Bounanos Date: Thu, 26 Jul 2007 01:52:01 +0100 Subject: [PATCH] Upstream version 1.36e --- src/dialogs/TextView.cxx | 117 +++++++++++++++++++++++------------- src/dialogs/fl_digi.cxx | 52 +++++++++------- src/include/TextView.h | 3 + src/include/configuration.h | 2 +- src/include/psk.h | 1 + src/include/version.h | 2 +- src/misc/configuration.cxx | 14 ++--- src/psk/psk.cxx | 89 ++++++++++++++++----------- src/waterfall/waterfall.cxx | 11 ++-- 9 files changed, 180 insertions(+), 111 deletions(-) diff --git a/src/dialogs/TextView.cxx b/src/dialogs/TextView.cxx index 62326bbf..c0b157fa 100644 --- a/src/dialogs/TextView.cxx +++ b/src/dialogs/TextView.cxx @@ -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 + 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 diff --git a/src/dialogs/fl_digi.cxx b/src/dialogs/fl_digi.cxx index 2a646f3d..4fa645db 100644 --- a/src/dialogs/fl_digi.cxx +++ b/src/dialogs/fl_digi.cxx @@ -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) diff --git a/src/include/TextView.h b/src/include/TextView.h index 799f9c2b..42f80ab4 100644 --- a/src/include/TextView.h +++ b/src/include/TextView.h @@ -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); diff --git a/src/include/configuration.h b/src/include/configuration.h index a55a51b5..861f1b2e 100644 --- a/src/include/configuration.h +++ b/src/include/configuration.h @@ -66,7 +66,7 @@ struct configuration { // DOMINOEX double DOMINOEX_BW; // User interface data - int Font; + int Fontnbr; int FontSize; int FontColor; uchar red; diff --git a/src/include/psk.h b/src/include/psk.h index f1ea114d..af552c16 100644 --- a/src/include/psk.h +++ b/src/include/psk.h @@ -87,6 +87,7 @@ private: void update_syncscope(); // void goertzel(complex); void afc(); + void findsignal(); public: psk(trx_mode mode); diff --git a/src/include/version.h b/src/include/version.h index 69ba9c70..9ef1b0b0 100644 --- a/src/include/version.h +++ b/src/include/version.h @@ -1,6 +1,6 @@ #ifndef _VERSION_H #define _VERSION_H -#define FLDIGI_VERSION "1.36c" +#define FLDIGI_VERSION "1.36e" #endif diff --git a/src/misc/configuration.cxx b/src/misc/configuration.cxx index 2af73b3c..714d8908 100644 --- a/src/misc/configuration.cxx +++ b/src/misc/configuration.cxx @@ -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); diff --git a/src/psk/psk.cxx b/src/psk/psk.cxx index 66800bc1..454e716f 100644 --- a/src/psk/psk.cxx +++ b/src/psk/psk.cxx @@ -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++) { diff --git a/src/waterfall/waterfall.cxx b/src/waterfall/waterfall.cxx index 44329870..8a65117a 100644 --- a/src/waterfall/waterfall.cxx +++ b/src/waterfall/waterfall.cxx @@ -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)