diff --git a/configure.ac b/configure.ac index a3c6d26e..6f16f178 100644 --- a/configure.ac +++ b/configure.ac @@ -4,7 +4,7 @@ AC_COPYRIGHT([Copyright (C) 2007 Stelios Bounanos, M0GLD (m0gld AT enotty DOT net)]) AC_PREREQ(2.61) -AC_INIT([fldigi], [2.09], [w1hkj AT w1hkj DOT com]) +AC_INIT([fldigi], [2.09A], [w1hkj AT w1hkj DOT com]) AC_CONFIG_AUX_DIR([build-aux]) AM_INIT_AUTOMAKE([-Wall foreign std-options 1.9.6]) AM_MAINTAINER_MODE diff --git a/src/dialogs/Viewer.cxx b/src/dialogs/Viewer.cxx index 717b9c5b..0db5d0f8 100644 --- a/src/dialogs/Viewer.cxx +++ b/src/dialogs/Viewer.cxx @@ -1,6 +1,9 @@ #include "Viewer.h" #include "main.h" #include "viewpsk.h" +#include "configuration.h" +#include "waterfall.h" +#include #include @@ -11,14 +14,57 @@ Fl_Double_Window *dlgViewer = (Fl_Double_Window *)0; Fl_Button *btnCloseViewer=(Fl_Button *)0; Fl_Button *btnClearViewer=(Fl_Button *)0; Fl_Hold_Browser *brwsViewer=(Fl_Hold_Browser *)0; +Fl_Input *inpSeek = (Fl_Input *)0; -string bwsrfreq[25]; +string bwsrfreq; //[25]; string bwsrline[25]; +string ucaseline[25]; +string tofind; static char empty[] = "@f "; // "@f1234567890123456789012345678901234567890"; -static char szFreq[20]; +static char szFreq[40]; static int brwsFreq[25]; static int freq; +static double dfreq; + +static long long rfc; +static bool usb; + +string dkred; +string dkblue; +string dkgreen; +string bkblue; +string white; + +static void make_colors() +{ + char tempstr[20]; + sprintf(tempstr,"@C%d", + fl_color_cube(128 * (FL_NUM_RED - 1) / 255, + 0 * (FL_NUM_GREEN - 1) / 255, + 0 * (FL_NUM_BLUE - 1) / 255)); // dark red + dkred = tempstr; + sprintf(tempstr,"@C%d", + fl_color_cube(0 * (FL_NUM_RED - 1) / 255, + 128 * (FL_NUM_GREEN - 1) / 255, + 0 * (FL_NUM_BLUE - 1) / 255)); // dark green + dkgreen = tempstr; + sprintf(tempstr,"@C%d", + fl_color_cube(0 * (FL_NUM_RED - 1) / 255, + 0 * (FL_NUM_GREEN - 1) / 255, + 128 * (FL_NUM_BLUE - 1) / 255)); // dark blue + dkblue = tempstr; + sprintf(tempstr,"@B%d", + fl_color_cube(0 * (FL_NUM_RED - 1) / 255, + 0 * (FL_NUM_GREEN - 1) / 255, + 160 * (FL_NUM_BLUE - 1) / 255)); // dard blue background + bkblue = tempstr; + sprintf(tempstr,"@C%d", + fl_color_cube(248 * (FL_NUM_RED - 1) / 255, + 248 * (FL_NUM_GREEN - 1) / 255, + 248 * (FL_NUM_BLUE - 1) / 255)); // white foreground + white = tempstr; +} static void cb_btnCloseViewer(Fl_Button*, void*) { dlgViewer->hide(); @@ -26,15 +72,26 @@ static void cb_btnCloseViewer(Fl_Button*, void*) { static void ClearViewer() { brwsViewer->clear(); + usb = wf->USB(); + rfc = wf->rfcarrier(); + for (int i = 0; i < 25; i++) { - if (pskviewer) freq = pskviewer->get_freq(i); - else freq = 500 + 100 * i; + if (pskviewer) freq = pskviewer->get_freq(24 - i); + else freq = 500 + 100 * (24 - i); + if (rfc != 0) { + if (usb) dfreq = rfc + freq; + else dfreq = rfc - freq; + } else dfreq = freq; + brwsFreq[i] = freq; - sprintf(szFreq,"@f@b%4d", freq); - bwsrfreq[i] = szFreq; - bwsrfreq[i] += '\t'; +// sprintf(szFreq,"@f@b%11.3f", dfreq / 1.0e3); + sprintf(szFreq,"@f%s%s%11.3f", bkblue.c_str(), white.c_str(), dfreq / 1.0e3); + + bwsrfreq = szFreq; + bwsrfreq += '\t'; bwsrline[i] = empty; - brwsViewer->add(bwsrfreq[i].c_str()); + ucaseline[i] = empty; + brwsViewer->add(bwsrfreq.c_str()); } } @@ -49,21 +106,51 @@ static void cb_brwsViewer(Fl_Hold_Browser*, void*) { active_modem->set_freq(brwsFreq[sel - 1]); } -int cols[] = {60, 0}; +static void cb_Seek(Fl_Input *, void *) +{ + tofind = inpSeek->value(); + for (size_t i = 0; i < tofind.length(); i++) + tofind[i] = toupper(tofind[i]); +} + +int cols[] = {100, 0}; Fl_Double_Window* createViewer() { Fl_Double_Window* w; - w = new Fl_Double_Window(400, 470, "Psk Viewer"); - w->color(FL_DARK2); - w->selection_color((Fl_Color)51); - w->align(FL_ALIGN_CLIP|FL_ALIGN_INSIDE); - btnCloseViewer = new Fl_Button(295, 440, 100, 25, "Close"); - btnCloseViewer->callback((Fl_Callback*)cb_btnCloseViewer); - btnClearViewer = new Fl_Button(170, 440, 100, 25, "Clear"); - btnClearViewer->callback((Fl_Callback*)cb_btnClearViewer); - brwsViewer = new Fl_Hold_Browser(0, 5, 390, 430); + Fl_Pack *p; + make_colors(); + w = new Fl_Double_Window(450, 480, "Psk Viewer"); + p = new Fl_Pack(0,0,450,490); + Fl_Pack *p1 = new Fl_Pack(0, 0, 450, 25); + p1->type(1); + Fl_Box *bx = new Fl_Box(0,0,50, 25); + inpSeek = new Fl_Input(50, 5, 200, 25, "Find: "); + inpSeek->callback((Fl_Callback*)cb_Seek); + inpSeek->when(FL_WHEN_CHANGED); + inpSeek->value("CQ"); + bx = new Fl_Box(250, 5, 200, 25); + p1->resizable(bx); + p1->end(); + tofind = "CQ"; + + brwsViewer = new Fl_Hold_Browser(2, 35, 446, 430); brwsViewer->callback((Fl_Callback*)cb_brwsViewer); brwsViewer->column_widths(cols); + + Fl_Pack *p2 = new Fl_Pack(0, 470, 450, 25); + p2->type(1); + bx = new Fl_Box(0,470, 10, 25); + btnClearViewer = new Fl_Button(10, 470, 65, 25, "Clear"); + btnClearViewer->callback((Fl_Callback*)cb_btnClearViewer); + bx = new Fl_Box(75, 470, 10, 25); + btnCloseViewer = new Fl_Button(85, 470, 65, 25, "Close"); + btnCloseViewer->callback((Fl_Callback*)cb_btnCloseViewer); + bx = new Fl_Box(150, 470, 300, 25); + p2->resizable(bx); + p2->end(); + p->resizable(brwsViewer); + p->end(); + w->resizable(p); w->end(); return w; } @@ -74,28 +161,66 @@ void openViewer() { ClearViewer(); } dlgViewer->show(); + dlgViewer->redraw(); +} + +void viewer_redraw() +{ + if (!dlgViewer) return; + usb = wf->USB(); + rfc = wf->rfcarrier(); + + for (int i = 0; i < 25; i++) { + if (pskviewer) freq = pskviewer->get_freq(24 - i); + else freq = 500 + 100 * (24 - i); + if (rfc) { + if (usb) dfreq = rfc + freq; + else dfreq = rfc - freq; + } else dfreq = freq; + + brwsFreq[i] = freq; + sprintf(szFreq,"@f%s%s%11.3f", bkblue.c_str(), white.c_str(), dfreq / 1.0e3); + bwsrfreq = szFreq; + bwsrfreq += '\t'; + brwsViewer->text(i + 1, bwsrfreq.c_str()); + } } void viewaddchr(int ch, int freq, char c) { if (!dlgViewer) return; - + + if (rfc != wf->rfcarrier() || usb != wf->USB()) viewer_redraw(); + static string nuline; - bwsrline[ch].erase(2,1); - if (c >= ' ' && c <= 'z') - bwsrline[ch] += c; - else - bwsrline[ch] += ' '; - brwsFreq[ch] = freq; - sprintf(szFreq,"@f@b%4d", freq); - bwsrfreq[ch] = szFreq; - bwsrfreq[ch] += '\t'; - nuline = bwsrfreq[ch]; - if (bwsrline[ch].find("CQ ") != string::npos || - bwsrline[ch].find("cq ") != string::npos || - bwsrline[ch].find("Cq ") != string::npos || - bwsrline[ch].find("cQ ") != string::npos) - nuline.append("@C128"); - nuline.append(bwsrline[ch]); - brwsViewer->text(ch + 1, nuline.c_str()); + bwsrline[24 - ch].erase(2,1); + ucaseline[24 - ch].erase(2,1); + if (c >= ' ' && c <= 'z') { + bwsrline[24 - ch] += c; + ucaseline[24 - ch] += toupper(c); + } else { + bwsrline[24 - ch] += ' '; + ucaseline[24 - ch] += ' '; + } + brwsFreq[24 - ch] = freq; + if (rfc) { + if (usb) dfreq = rfc + freq; + else dfreq = rfc - freq; + } else dfreq = freq; + + sprintf(szFreq,"@f%s%s%11.3f", bkblue.c_str(), white.c_str(), dfreq / 1.0e3); + + bwsrfreq = szFreq; + bwsrfreq += '\t'; + nuline = bwsrfreq; + + if (!tofind.empty()) + if (ucaseline[24 - ch].find(tofind) != string::npos) + nuline.append(dkred); + else if (!progdefaults.myCall.empty()) + if (ucaseline[24 - ch].find(progdefaults.myCall) != string::npos) + nuline.append(dkgreen); + + nuline.append(bwsrline[24 - ch]); + brwsViewer->text(25 - ch, nuline.c_str()); brwsViewer->redraw(); } diff --git a/src/include/Viewer.h b/src/include/Viewer.h index fff5dd21..762ec3e4 100644 --- a/src/include/Viewer.h +++ b/src/include/Viewer.h @@ -4,6 +4,8 @@ #include #include #include +#include +#include extern Fl_Double_Window *dlgViewer; extern Fl_Button *btnCloseViewer; diff --git a/src/include/viewpsk.h b/src/include/viewpsk.h index 91dbd432..cc391248 100644 --- a/src/include/viewpsk.h +++ b/src/include/viewpsk.h @@ -41,6 +41,8 @@ class viewpsk { private: + trx_mode viewmode; + int symbollen; double phaseacc[CHANNELS]; complex prevsymbol[CHANNELS]; diff --git a/src/psk/psk.cxx b/src/psk/psk.cxx index d4c7341f..ce3006e2 100644 --- a/src/psk/psk.cxx +++ b/src/psk/psk.cxx @@ -84,7 +84,8 @@ void psk::rx_init() void psk::restart() { -// reverse = false; + if (!pskviewer) pskviewer = new viewpsk(mode); + else pskviewer->restart(mode); } void psk::init() @@ -101,15 +102,10 @@ psk::~psk() if (dec) delete dec; if (fir1) delete fir1; if (fir2) delete fir2; - if (pskviewer) delete pskviewer; -// if (wfid) delete wfid; } psk::psk(trx_mode pskmode) : modem() { - if (!pskviewer) pskviewer = new viewpsk(pskmode); - else pskviewer->restart(pskmode); - mode = pskmode; switch (mode) { @@ -204,9 +200,7 @@ psk::psk(trx_mode pskmode) : modem() fragmentsize = symbollen; bandwidth = samplerate / symbollen; snratio = s2n = imdratio = imd = 0; -// wfid = new id(this); - -// pipeptr = 0; + if (mailserver && progdefaults.PSKmailSweetSpot) sigsearch = SIGSEARCH; else diff --git a/src/psk/viewpsk.cxx b/src/psk/viewpsk.cxx index d5d5a081..1d1e2c4c 100644 --- a/src/psk/viewpsk.cxx +++ b/src/psk/viewpsk.cxx @@ -52,7 +52,8 @@ viewpsk::viewpsk(trx_mode pskmode) for (int i = 0; i < CHANNELS; i++) { fir1[i] = (C_FIR_filter *)0; fir2[i] = (C_FIR_filter *)0; - } + } + viewmode = MODE_PREV; restart(pskmode); } @@ -84,15 +85,13 @@ void viewpsk::init() void viewpsk::restart(trx_mode pskmode) { + if (viewmode == pskmode) return; + viewmode = pskmode; + double fir1c[64]; double fir2c[64]; - for (int i = 0; i < CHANNELS; i++) { - if (fir1[i]) delete fir1[i]; - if (fir2[i]) delete fir2[i]; - } - - switch (pskmode) { + switch (viewmode) { case MODE_BPSK31: symbollen = 256; dcdbits = 32; @@ -118,9 +117,11 @@ void viewpsk::restart(trx_mode pskmode) wsincfilt(fir2c, 1.0 / 16.0, true); // creates fir2c matched sin(x)/x filter w blackman for (int i = 0; i < CHANNELS; i++) { + if (fir1[i]) delete fir1[i]; fir1[i] = new C_FIR_filter(); fir1[i]->init(FIRLEN, symbollen / 16, fir1c, fir1c); + if (fir2[i]) delete fir2[i]; fir2[i] = new C_FIR_filter(); fir2[i]->init(FIRLEN, 1, fir2c, fir2c); } @@ -152,15 +153,14 @@ void viewpsk::findsignal(int ch) double ftest, sigpwr, noise; if (sigsearch[ch] > 0) { sigsearch[ch]--; - ftest = wf->peakFreq((int)(frequency[ch]), VSEARCHWIDTH); + ftest = wf->peakFreq((int)(frequency[ch]), VSEARCHWIDTH + (int)(bandwidth / 2)); sigpwr = wf->powerDensity(ftest, bandwidth); noise = wf->powerDensity(ftest + 2 * bandwidth, bandwidth / 2) + wf->powerDensity(ftest - 2 * bandwidth, bandwidth / 2) + 1e-20; if (sigpwr/noise > VSNTHRESHOLD) { // larger than the search threshold - if (fabs(ftest - nomfreq[ch]) > VSEARCHWIDTH) - frequency[ch] = nomfreq[ch]; - else - frequency[ch] = ftest; + if (ftest - nomfreq[ch] > VSEARCHWIDTH) ftest = nomfreq[ch] + VSEARCHWIDTH; + if (ftest - nomfreq[ch] < -VSEARCHWIDTH) ftest = nomfreq[ch] - VSEARCHWIDTH; + frequency[ch] = ftest; } else { // less than the detection threshold frequency[ch] = nomfreq[ch]; sigsearch[ch] = VSIGSEARCH; diff --git a/src/waterfall/waterfall.cxx b/src/waterfall/waterfall.cxx index 15361426..a2b60684 100644 --- a/src/waterfall/waterfall.cxx +++ b/src/waterfall/waterfall.cxx @@ -1186,7 +1186,9 @@ void waterfall::Carrier(int f) } void waterfall::rfcarrier(long long cf) { +extern void viewer_redraw(); wfdisp->rfcarrier(cf); + viewer_redraw(); } long long waterfall::rfcarrier() {