From a93e55fef015b1a1a425ecca71473662449f9409 Mon Sep 17 00:00:00 2001 From: Joe Taylor Date: Wed, 11 Feb 2015 00:50:35 +0000 Subject: [PATCH] Improved, simplified sort routine; faster and better "flatten" procedure; better window functions for some FFTs, resulting in better decoder performance; User-selectable colors for backgrounds of decoded messages. NB: more testing is desirable! git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@4951 ab8295b8-cf94-4d9e-aec4-7959e3be5d79 --- CMakeLists.txt | 3 +- Configuration.cpp | 91 +++++++++++----- Configuration.hpp | 5 + Configuration.ui | 189 +++++++++++++++++++++++++++++++- displaytext.cpp | 28 +++-- displaytext.h | 10 +- lib/Makefile.jtsdk | 4 +- lib/Makefile.linux | 4 +- lib/flat3.f90 | 74 ------------- lib/flat4.f90 | 50 +++++++++ lib/sort.f90 | 87 ++++++++++++++- lib/ssort.f90 | 264 --------------------------------------------- lib/symspec.f90 | 10 +- lib/symspec65.f90 | 21 +++- mainwindow.cpp | 30 +++++- plotter.cpp | 29 +++-- plotter.h | 13 ++- widegraph.cpp | 2 + 18 files changed, 494 insertions(+), 420 deletions(-) delete mode 100644 lib/flat3.f90 create mode 100644 lib/flat4.f90 delete mode 100644 lib/ssort.f90 diff --git a/CMakeLists.txt b/CMakeLists.txt index e38d18ce8..b565b8997 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -291,7 +291,7 @@ set (wsjt_FSRCS lib/fillcom.f90 lib/flat1.f90 lib/flat2.f90 - lib/flat3.f90 + lib/flat4.f90 lib/flat65.f90 lib/four2a.f90 lib/fmtmsg.f90 @@ -335,7 +335,6 @@ set (wsjt_FSRCS lib/smo121.f90 lib/softsym.f90 lib/sort.f90 - lib/ssort.f90 lib/stdmsg.f90 lib/sun.f90 lib/symspec.f90 diff --git a/Configuration.cpp b/Configuration.cpp index 0122fcf81..71f5b1b8a 100644 --- a/Configuration.cpp +++ b/Configuration.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include "ui_Configuration.h" @@ -251,6 +252,7 @@ public: Q_SLOT void reject () override; Q_SLOT void done (int) override; + private: typedef QList AudioDevices; @@ -272,59 +274,41 @@ private: Q_SLOT void on_font_push_button_clicked (); Q_SLOT void on_decoded_text_font_push_button_clicked (); - Q_SLOT void on_PTT_port_combo_box_activated (int); - Q_SLOT void on_CAT_port_combo_box_activated (int); - Q_SLOT void on_CAT_serial_baud_combo_box_currentIndexChanged (int); - Q_SLOT void on_CAT_data_bits_button_group_buttonClicked (int); - Q_SLOT void on_CAT_stop_bits_button_group_buttonClicked (int); - Q_SLOT void on_CAT_handshake_button_group_buttonClicked (int); - Q_SLOT void on_CAT_poll_interval_spin_box_valueChanged (int); - Q_SLOT void on_split_mode_button_group_buttonClicked (int); - Q_SLOT void on_test_CAT_push_button_clicked (); - Q_SLOT void on_test_PTT_push_button_clicked (); - Q_SLOT void on_CAT_DTR_check_box_toggled (bool); - Q_SLOT void on_CAT_RTS_check_box_toggled (bool); - Q_SLOT void on_rig_combo_box_currentIndexChanged (int); - Q_SLOT void on_sound_input_combo_box_currentTextChanged (QString const&); Q_SLOT void on_sound_output_combo_box_currentTextChanged (QString const&); - Q_SLOT void on_add_macro_push_button_clicked (bool = false); Q_SLOT void on_delete_macro_push_button_clicked (bool = false); - Q_SLOT void on_PTT_method_button_group_buttonClicked (int); - Q_SLOT void on_callsign_line_edit_editingFinished (); - Q_SLOT void on_grid_line_edit_editingFinished (); - Q_SLOT void on_add_macro_line_edit_editingFinished (); Q_SLOT void delete_macro (); void delete_selected_macros (QModelIndexList); - Q_SLOT void on_save_path_select_push_button_clicked (bool); - Q_SLOT void delete_frequencies (); Q_SLOT void insert_frequency (); - Q_SLOT void delete_stations (); Q_SLOT void insert_station (); - Q_SLOT void handle_transceiver_update (TransceiverState); Q_SLOT void handle_transceiver_failure (QString reason); + Q_SLOT void on_pbCQmsg_clicked(); + Q_SLOT void on_pbMyCall_clicked(); + Q_SLOT void on_pbTxMsg_clicked(); + Q_SLOT void on_pbNewDXCC_clicked(); + Q_SLOT void on_pbNewCall_clicked(); // typenames used as arguments must match registered type names :( Q_SIGNAL void stop_transceiver () const; @@ -409,6 +393,11 @@ private: // configuration fields that we publish QString my_callsign_; QString my_grid_; + QColor color_CQ_; + QColor color_MyCall_; + QColor color_TxMsg_; + QColor color_DXCC_; + QColor color_NewCall_; qint32 id_interval_; bool id_after_73_; bool tx_QSY_allowed_; @@ -466,6 +455,11 @@ float Configuration::jt9w_min_dt () const {return m_->jt9w_min_dt_;} float Configuration::jt9w_max_dt () const {return m_->jt9w_max_dt_;} QString Configuration::my_callsign () const {return m_->my_callsign_;} QString Configuration::my_grid () const {return m_->my_grid_;} +QColor Configuration::color_CQ () const {return m_->color_CQ_;} +QColor Configuration::color_MyCall () const {return m_->color_MyCall_;} +QColor Configuration::color_TxMsg () const {return m_->color_TxMsg_;} +QColor Configuration::color_DXCC () const {return m_->color_DXCC_;} +QColor Configuration::color_NewCall () const {return m_->color_NewCall_;} QFont Configuration::decoded_text_font () const {return m_->decoded_text_font_;} qint32 Configuration::id_interval () const {return m_->id_interval_;} bool Configuration::id_after_73 () const {return m_->id_after_73_;} @@ -872,6 +866,11 @@ void Configuration::impl::initialise_models () ui_->grid_line_edit->setPalette (pal); ui_->callsign_line_edit->setText (my_callsign_); ui_->grid_line_edit->setText (my_grid_); + ui_->labCQ->setStyleSheet(QString("background: %1").arg(color_CQ_.name())); + ui_->labMyCall->setStyleSheet(QString("background: %1").arg(color_MyCall_.name())); + ui_->labTx->setStyleSheet(QString("background: %1").arg(color_TxMsg_.name())); + ui_->labDXCC->setStyleSheet(QString("background: %1").arg(color_DXCC_.name())); + ui_->labNewCall->setStyleSheet(QString("background: %1").arg(color_NewCall_.name())); font_changed_ = false; decoded_text_font_changed_ = false; ui_->CW_id_interval_spin_box->setValue (id_interval_); @@ -945,6 +944,11 @@ void Configuration::impl::read_settings () my_callsign_ = settings_->value ("MyCall", "").toString (); my_grid_ = settings_->value ("MyGrid", "").toString (); + color_CQ_ = settings_->value("colorCQ","#66ff66").toString(); + color_MyCall_ = settings_->value("colorMyCall","#ff6666").toString(); + color_TxMsg_ = settings_->value("colorTxMsg","#ffff00").toString(); + color_DXCC_ = settings_->value("colorDXCC","#ff00ff").toString(); + color_NewCall_ = settings_->value("colorNewCall","#ffaaff").toString(); if (next_font_.fromString (settings_->value ("Font", QGuiApplication::font ().toString ()).toString ()) && next_font_ != QGuiApplication::font ()) @@ -1073,12 +1077,14 @@ void Configuration::impl::write_settings () settings_->setValue ("MyCall", my_callsign_); settings_->setValue ("MyGrid", my_grid_); - + settings_->setValue("colorCQ",color_CQ_); + settings_->setValue("colorMyCall",color_MyCall_); + settings_->setValue("colorTxMsg",color_TxMsg_); + settings_->setValue("colorDXCC",color_DXCC_); + settings_->setValue("colorNewCall",color_NewCall_); settings_->setValue ("Font", font_.toString ()); settings_->setValue ("DecodedTextFont", decoded_text_font_.toString ()); - settings_->setValue ("IDint", id_interval_); - settings_->setValue ("PTTMethod", QVariant::fromValue (rig_params_.PTT_method_)); settings_->setValue ("PTTport", rig_params_.PTT_port_); settings_->setValue ("SaveDir", save_directory_.absolutePath ()); @@ -1531,6 +1537,39 @@ void Configuration::impl::on_font_push_button_clicked () next_font_ = QFontDialog::getFont (&font_changed_, this); } +void Configuration::impl::on_pbCQmsg_clicked() +{ + color_CQ_ = QColorDialog::getColor("#6666ff"); + ui_->labCQ->setStyleSheet(QString("background: %1").arg(color_CQ_.name())); +} + +void Configuration::impl::on_pbMyCall_clicked() +{ + color_MyCall_ = QColorDialog::getColor("#ff6666"); + ui_->labMyCall->setStyleSheet(QString("background: %1").arg(color_MyCall_.name())); +} + +void Configuration::impl::on_pbTxMsg_clicked() +{ + color_TxMsg_ = QColorDialog::getColor("#ffff00"); + ui_->labTx->setStyleSheet(QString("background: %1").arg(color_TxMsg_.name())); +} + +void Configuration::impl::on_pbNewDXCC_clicked() +{ + color_DXCC_ = QColorDialog::getColor("#ff00ff"); + ui_->labDXCC->setStyleSheet(QString("background: %1").arg(color_DXCC_.name())); +} + +void Configuration::impl::on_pbNewCall_clicked() +{ + color_NewCall_ = QColorDialog::getColor("#ffaaff"); + ui_->labNewCall->setStyleSheet(QString("background: %1").arg(color_NewCall_.name())); +} + + + + void Configuration::impl::on_decoded_text_font_push_button_clicked () { next_decoded_text_font_ = QFontDialog::getFont (&decoded_text_font_changed_ diff --git a/Configuration.hpp b/Configuration.hpp index 4101ee8e2..5c10f7dba 100644 --- a/Configuration.hpp +++ b/Configuration.hpp @@ -110,6 +110,11 @@ public: unsigned jt9w_bw_mult () const; float jt9w_min_dt () const; float jt9w_max_dt () const; + QColor color_CQ () const; + QColor color_MyCall () const; + QColor color_TxMsg () const; + QColor color_DXCC () const; + QColor color_NewCall () const; // This method queries if a CAT and PTT connection is operational, // diff --git a/Configuration.ui b/Configuration.ui index be8183747..fddd9fdc9 100644 --- a/Configuration.ui +++ b/Configuration.ui @@ -22,6 +22,12 @@ + + + 80 + 20 + + Select tab to change configuration parameters. @@ -1682,6 +1688,183 @@ Right click for insert and delete options. + + + Colors + + + + + 44 + 60 + 198 + 141 + + + + + + + + 110 + 0 + + + + CQ in message + + + + + + + + 80 + 20 + + + + QLabel{background-color: #66ff66} + + + K1ABC + + + Qt::AlignCenter + + + + + + + + 110 + 0 + + + + My Call in message + + + + + + + + 80 + 20 + + + + QLabel{background-color: #ff6666} + + + K1ABC + + + Qt::AlignCenter + + + + + + + + 110 + 0 + + + + Transmitted message + + + + + + + + 80 + 20 + + + + QLabel{background-color: yellow} + + + K1ABC + + + Qt::AlignCenter + + + + + + + + 110 + 0 + + + + New DXCC + + + + + + + + 80 + 20 + + + + QLabel{background-color: #ff66ff} + + + K1ABC + + + Qt::AlignCenter + + + + + + + + 110 + 0 + + + + New Call + + + + + + + + 80 + 20 + + + + QLabel{background-color: #66ffff} + + + K1ABC + + + Qt::AlignCenter + + + + + + @@ -1834,12 +2017,12 @@ soundcard changes + - - - + + diff --git a/displaytext.cpp b/displaytext.cpp index f91e1a6d0..e4d9b138a 100644 --- a/displaytext.cpp +++ b/displaytext.cpp @@ -59,7 +59,10 @@ void DisplayText::_insertText(const QString text, const QString bg) } -void DisplayText::_appendDXCCWorkedB4(/*mod*/DecodedText& t1, QString& bg, /*uses*/LogBook logBook) +void DisplayText::_appendDXCCWorkedB4(DecodedText& t1, QString& bg, + LogBook logBook, QColor color_CQ, + QColor color_DXCC, + QColor color_NewCall) { // extract the CQer's call TODO: does this work with all call formats? What about 'CQ DX'? int s1 = 4 + t1.indexOf(" CQ "); @@ -86,18 +89,18 @@ void DisplayText::_appendDXCCWorkedB4(/*mod*/DecodedText& t1, QString& bg, /*use if (!countryWorkedBefore) // therefore not worked call either { t1 += "!"; - bg = "#66ff66"; // strong green + bg=color_DXCC.name(); } else if (!callWorkedBefore) // but have worked the country { t1 += "~"; - bg = "#76cd76"; // mid green + bg=color_NewCall.name(); } else { t1 += " "; // have worked this call before - bg="#9cc79c"; // pale green + bg=color_CQ.name(); } charsAvail -= 1; @@ -107,29 +110,34 @@ void DisplayText::_appendDXCCWorkedB4(/*mod*/DecodedText& t1, QString& bg, /*use } } -void DisplayText::displayDecodedText(DecodedText decodedText, QString myCall, bool displayDXCCEntity, LogBook logBook) +void DisplayText::displayDecodedText(DecodedText decodedText, QString myCall, + bool displayDXCCEntity, LogBook logBook, + QColor color_CQ, QColor color_MyCall, + QColor color_DXCC, QColor color_NewCall) { QString bg="white"; bool CQcall = false; if (decodedText.indexOf(" CQ ") > 0) { CQcall = true; - bg="#66ff66"; //green + bg=color_CQ.name(); } if (myCall != "" and decodedText.indexOf(" " + myCall + " ") > 0) - bg="#ff6666"; //red + bg=color_MyCall.name(); // if enabled add the DXCC entity and B4 status to the end of the preformated text line t1 if (displayDXCCEntity && CQcall) - _appendDXCCWorkedB4(/*mod*/decodedText,bg,logBook); + _appendDXCCWorkedB4(/*mod*/decodedText,bg,logBook,color_CQ, + color_DXCC,color_NewCall); _insertText(decodedText.string(),bg); } -void DisplayText::displayTransmittedText(QString text, QString modeTx, qint32 txFreq) +void DisplayText::displayTransmittedText(QString text, QString modeTx, qint32 txFreq, + QColor color_TxMsg) { - QString bg="yellow"; + QString bg=color_TxMsg.name(); QString t1=" @ "; if(modeTx=="JT65") t1=" # "; QString t2; diff --git a/displaytext.h b/displaytext.h index 8ed3b0ac4..9c293016d 100644 --- a/displaytext.h +++ b/displaytext.h @@ -16,8 +16,11 @@ public: void setFont(QFont const& font); void insertLineSpacer(); - void displayDecodedText(DecodedText decodedText, QString myCall, bool displayDXCCEntity, LogBook logBook); - void displayTransmittedText(QString text, QString modeTx, qint32 txFreq); + void displayDecodedText(DecodedText decodedText, QString myCall, bool displayDXCCEntity, + LogBook logBook, QColor color_CQ, QColor color_MyCall, + QColor color_DXCC, QColor color_NewCall); + void displayTransmittedText(QString text, QString modeTx, qint32 txFreq, + QColor color_TxMsg); signals: void selectCallsign(bool shift, bool ctrl); @@ -33,7 +36,8 @@ private: int _fontWidth; int _maxDisplayedCharacters; void _insertText(const QString text, const QString bg); - void _appendDXCCWorkedB4(/*mod*/DecodedText& t1, QString &bg, LogBook logBook); + void _appendDXCCWorkedB4(/*mod*/DecodedText& t1, QString &bg, LogBook logBook, + QColor color_CQ, QColor color_DXCC, QColor color_NewCall); }; diff --git a/lib/Makefile.jtsdk b/lib/Makefile.jtsdk index 77876fdb7..ce113a572 100644 --- a/lib/Makefile.jtsdk +++ b/lib/Makefile.jtsdk @@ -30,7 +30,7 @@ CFLAGS = -I. -DWIN32 all: libjt9.a libastro.a jt9.exe jt9code.exe jt65code.exe jt9sim.exe -OBJS1 = pctile.o graycode.o sort.o ssort.o chkmsg.o \ +OBJS1 = pctile.o graycode.o sort.o chkmsg.o \ unpackmsg.o igray.o unpackcall.o unpackgrid.o \ grid2k.o unpacktext.o getpfx2.o packmsg.o deg2grid.o \ packtext.o getpfx1.o packcall.o k2grid.o packgrid.o \ @@ -47,7 +47,7 @@ OBJS1 = pctile.o graycode.o sort.o ssort.o chkmsg.o \ extract.o fchisq65.o demod64a.o chkhist.o interleave63.o ccf2.o \ move.o indexx.o graycode65.o twkfreq65.o smo121.o \ wrapkarn.o init_rs.o encode_rs.o decode_rs.o gen65.o fil4.o \ - flat3.o polfit.o determ.o baddata.o prog_args.o \ + flat4.o polfit.o determ.o baddata.o prog_args.o \ options.o fmtmsg.o decjt9.o libjt9.a: $(OBJS1) diff --git a/lib/Makefile.linux b/lib/Makefile.linux index 923eff4fc..14bc077a0 100644 --- a/lib/Makefile.linux +++ b/lib/Makefile.linux @@ -31,7 +31,7 @@ all: libjt9.a jt9sim jt9 jt9code jt65code OBJS1 = astrosub.o astro0.o astro.o tm2.o sun.o moondop.o coord.o tmoonsub.o \ fmtmsg.o geocentric.o moon2.o toxyz.o dot.o dcoord.o \ - prog_args.o options.o pctile.o graycode.o sort.o ssort.o chkmsg.o \ + prog_args.o options.o pctile.o graycode.o sort.o chkmsg.o \ unpackmsg.o igray.o unpackcall.o unpackgrid.o \ grid2k.o unpacktext.o getpfx2.o packmsg.o deg2grid.o \ packtext.o getpfx1.o packcall.o k2grid.o packgrid.o \ @@ -49,7 +49,7 @@ OBJS1 = astrosub.o astro0.o astro.o tm2.o sun.o moondop.o coord.o tmoonsub.o \ extract.o fchisq65.o demod64a.o chkhist.o interleave63.o ccf2.o \ move.o indexx.o graycode65.o twkfreq65.o smo.o smo121.o \ wrapkarn.o init_rs.o encode_rs.o decode_rs.o gen65.o fil4.o \ - flat3.o polfit.o determ.o baddata.o + flat4.o polfit.o determ.o baddata.o libjt9.a: $(OBJS1) $(AR) libjt9.a $(OBJS1) diff --git a/lib/flat3.f90 b/lib/flat3.f90 deleted file mode 100644 index 7c97c2ec0..000000000 --- a/lib/flat3.f90 +++ /dev/null @@ -1,74 +0,0 @@ -subroutine flat3(s0,iz,nfa,nfb,nterms,ynoise,s) - - implicit real*8 (a-h,o-z) - parameter (NSMAX=6827) - real*4 s0(iz) - real*4 s(iz) - real*4 ynoise,y4,db - - real*8 x(NSMAX) - real*8 y(NSMAX) - real*8 y0(NSMAX) - real*8 yfit(NSMAX) - real*8 a(10) - integer ii(NSMAX) - - npts0=999999 - df=12000.0/16384.0 - - do i=1,iz - y0(i)=db(s0(i)) - enddo - ia=(nfa+200.0)/df - ib=5000.0/df - if(nfb.gt.0) ib=nfb/df - j=0 - do i=ia,ib - j=j+1 - x(j)=i*df - y(j)=y0(i) - ii(j)=i - enddo - - npts=j - mode=0 - a=0.0 - - do iter=1,99 - call polfit(x,y,y,npts,nterms,mode,a,chisqr) - - do i=1,ib - f=i*df - yfit(i)=a(nterms) - do n=nterms-1,1,-1 - yfit(i)=f*yfit(i) + a(n) - enddo -! write(21,1010) f,y0(i),yfit(i),y0(i)-yfit(i) -!1010 format(4f12.3) - enddo - k=0 - do j=1,npts - y1=y(j)-yfit(ii(j)) - if(y1.lt.ynoise) then -! if(y1.lt.ynoise .and. y1.gt.-ynoise) then - k=k+1 - x(k)=x(j) - y(k)=y(j) - ii(k)=ii(j) - endif - enddo - npts=k - if(npts.eq.npts0 .or. npts.lt.(ib-ia)/10) exit - npts0=npts - enddo - -! do j=1,npts -! write(22,1010) x(j),y(j),yfit(ii(j)),y(j)-yfit(ii(j)) -! enddo - - do i=1,ib - y4=y0(i)-yfit(i) - 10.0 - s(i)=10.0**(0.1*y4) - enddo - -end subroutine flat3 diff --git a/lib/flat4.f90 b/lib/flat4.f90 new file mode 100644 index 000000000..64e7b7f93 --- /dev/null +++ b/lib/flat4.f90 @@ -0,0 +1,50 @@ +subroutine flat4(s,npts,nflatten) + +! Flatten a spectrum for optimum display +! Input: s(npts) Linear scale in power +! nflatten If nflatten=0, convert to dB but do not flatten +! Output: s(npts) Flattened, with dB scale + + + implicit real*8 (a-h,o-z) + real*4 s(6827) + real*4 base + real*8 x(1000),y(1000),a(5) + data nseg/10/,npct/10/ + + if(s(1).gt.1.e29) go to 900 !Boundary between Rx intervals: do nothing + do i=1,npts + s(i)=10.0*log10(s(i)) !Convert to dB scale + enddo + if(nflatten.eq.0) go to 900 + + nlen=npts/nseg !Length of test segment + i0=npts/2 !Midpoint + k=0 + do n=2,nseg !Skip first segment, likely rolloff here + ib=n*nlen + ia=ib-nlen+1 + if(n.eq.nseg) ib=npts + call pctile(s(ia),ib-ia+1,npct,base) !Find lowest npct of points in segment + do i=ia,ib + if(s(i).le.base) then + k=k+1 !Save thesde "lower envelope" points + x(k)=i-i0 + y(k)=s(i) + endif + enddo + enddo + kz=k + a=0. + nterms=3 + + call polfit(x,y,y,kz,nterms,0,a,chisqr) !Fit a low-order polynomial + + do i=1,npts + t=i-i0 + yfit=a(1)+t*(a(2)+t*(a(3)+t*(a(4)+t*(a(5))))) + s(i)=s(i)-yfit !Subtract the fitted baseline + enddo + +900 return +end subroutine flat4 diff --git a/lib/sort.f90 b/lib/sort.f90 index 281ce0275..993dafd76 100644 --- a/lib/sort.f90 +++ b/lib/sort.f90 @@ -1,4 +1,87 @@ subroutine sort(n,arr) - call ssort(arr,tmp,n,1) - return + + integer n,m,nstack + real arr(n) + parameter (m=7,nstack=50) + integer i,ir,j,jstack,k,l,istack(nstack) + real a,temp + + jstack=0 + l=1 + ir=n + +1 if(ir-l.lt.m) then + do j=l+1,ir + a=arr(j) + do i=j-1,1,-1 + if(arr(i).le.a) goto 2 + arr(i+1)=arr(i) + enddo + i=0 +2 arr(i+1)=a + enddo + + if(jstack.eq.0) return + + ir=istack(jstack) + l=istack(jstack-1) + jstack=jstack-2 + + else + k=(l+ir)/2 + temp=arr(k) + arr(k)=arr(l+1) + arr(l+1)=temp + + if(arr(l+1).gt.arr(ir)) then + temp=arr(l+1) + arr(l+1)=arr(ir) + arr(ir)=temp + endif + + if(arr(l).gt.arr(ir)) then + temp=arr(l) + arr(l)=arr(ir) + arr(ir)=temp + endif + + if(arr(l+1).gt.arr(l)) then + temp=arr(l+1) + arr(l+1)=arr(l) + arr(l)=temp + endif + + i=l+1 + j=ir + a=arr(l) +3 i=i+1 + if(arr(i).lt.a) goto 3 + +4 j=j-1 + if(arr(j).gt.a) goto 4 + + if(j.lt.i) goto 5 + temp=arr(i) + arr(i)=arr(j) + arr(j)=temp + goto 3 + +5 arr(l)=arr(j) + arr(j)=a + jstack=jstack+2 + if(jstack.gt.nstack) stop 'nstack too small in sort' + + if(ir-i+1.ge.j-l) then + istack(jstack)=ir + istack(jstack-1)=i + ir=j-1 + else + istack(jstack)=j-1 + istack(jstack-1)=l + l=i + endif + + endif + goto 1 + end subroutine sort diff --git a/lib/ssort.f90 b/lib/ssort.f90 deleted file mode 100644 index 7d712388d..000000000 --- a/lib/ssort.f90 +++ /dev/null @@ -1,264 +0,0 @@ -subroutine ssort (x,y,n,kflag) -! Sort an array and optionally make the same interchanges in -! an auxiliary array. the array may be sorted in increasing -! or decreasing order. a slightly modified quicksort -! algorithm is used. - -! ssort sorts array x and optionally makes the same interchanges in -! array y. the array x may be sorted in increasing order or -! decreasing order. a slightly modified quicksort algorithm is used. - -! Description of parameters -! x - array of values to be sorted -! y - array to be (optionally) carried along -! n - number of values in array x to be sorted -! kflag - control parameter -! = 2 means sort x in increasing order and carry y along. -! = 1 means sort x in increasing order (ignoring y) -! = -1 means sort x in decreasing order (ignoring y) -! = -2 means sort x in decreasing order and carry y along. - - integer kflag, n - integer x(n), y(n) - real r - integer t, tt, tty, ty - integer i, ij, j, k, kk, l, m, nn - integer il(21), iu(21) - - nn = n - if (nn .lt. 1) then -! print*,'ssort: The number of sort elements is not positive.' -! print*,'ssort: n = ',nn,' kflag = ',kflag - return - endif - - kk = abs(kflag) - if (kk.ne.1 .and. kk.ne.2) then - print *,'the sort control parameter, k, is not 2, 1, -1, or -2.' - return - endif - -! Alter array x to get decreasing order if needed - - if (kflag .le. -1) then - do i=1,nn - x(i) = -x(i) - enddo - endif - - if (kk .eq. 2) go to 100 - -! Sort x only - - m = 1 - i = 1 - j = nn - r = 0.375e0 - -20 if (i .eq. j) go to 60 - if (r .le. 0.5898437e0) then - r = r+3.90625e-2 - else - r = r-0.21875e0 - endif - -30 k = i - -! Select a central element of the array and save it in location t - - ij = i + int((j-i)*r) - t = x(ij) - -! If first element of array is greater than t, interchange with t - - if (x(i) .gt. t) then - x(ij) = x(i) - x(i) = t - t = x(ij) - endif - l = j - -! If last element of array is less than than t, interchange with t - if (x(j) .lt. t) then - x(ij) = x(j) - x(j) = t - t = x(ij) - -! If first element of array is greater than t, interchange with t - if (x(i) .gt. t) then - x(ij) = x(i) - x(i) = t - t = x(ij) - endif - endif - -! Find an element in the second half of the array which is smaller than t -40 l = l-1 - if (x(l) .gt. t) go to 40 - -! Find an element in the first half of the array which is greater than t -50 k = k+1 - if (x(k) .lt. t) go to 50 - -! Interchange these elements - if (k .le. l) then - tt = x(l) - x(l) = x(k) - x(k) = tt - go to 40 - endif - -! Save upper and lower subscripts of the array yet to be sorted - if (l-i .gt. j-k) then - il(m) = i - iu(m) = l - i = k - m = m+1 - else - il(m) = k - iu(m) = j - j = l - m = m+1 - endif - go to 70 - -! Begin again on another portion of the unsorted array -60 m = m-1 - if (m .eq. 0) go to 190 - i = il(m) - j = iu(m) - -70 if (j-i .ge. 1) go to 30 - if (i .eq. 1) go to 20 - i = i-1 - -80 i = i+1 - if (i .eq. j) go to 60 - t = x(i+1) - if (x(i) .le. t) go to 80 - k = i - -90 x(k+1) = x(k) - k = k-1 - if (t .lt. x(k)) go to 90 - x(k+1) = t - go to 80 - -! Sort x and carry y along - -100 m = 1 - i = 1 - j = nn - r = 0.375e0 - -110 if (i .eq. j) go to 150 - if (r .le. 0.5898437e0) then - r = r+3.90625e-2 - else - r = r-0.21875e0 - endif - - 120 k = i -! Select a central element of the array and save it in location t - ij = i + int((j-i)*r) - t = x(ij) - ty = y(ij) - -! If first element of array is greater than t, interchange with t - if (x(i) .gt. t) then - x(ij) = x(i) - x(i) = t - t = x(ij) - y(ij) = y(i) - y(i) = ty - ty = y(ij) - endif - l = j - -! If last element of array is less than t, interchange with t - if (x(j) .lt. t) then - x(ij) = x(j) - x(j) = t - t = x(ij) - y(ij) = y(j) - y(j) = ty - ty = y(ij) - -! If first element of array is greater than t, interchange with t - if (x(i) .gt. t) then - x(ij) = x(i) - x(i) = t - t = x(ij) - y(ij) = y(i) - y(i) = ty - ty = y(ij) - endif - endif - -! Find an element in the second half of the array which is smaller than t -130 l = l-1 - if (x(l) .gt. t) go to 130 - -! Find an element in the first half of the array which is greater than t -140 k = k+1 - if (x(k) .lt. t) go to 140 - -! Interchange these elements - if (k .le. l) then - tt = x(l) - x(l) = x(k) - x(k) = tt - tty = y(l) - y(l) = y(k) - y(k) = tty - go to 130 - endif - -! Save upper and lower subscripts of the array yet to be sorted - if (l-i .gt. j-k) then - il(m) = i - iu(m) = l - i = k - m = m+1 - else - il(m) = k - iu(m) = j - j = l - m = m+1 - endif - go to 160 - -! Begin again on another portion of the unsorted array -150 m = m-1 - if (m .eq. 0) go to 190 - i = il(m) - j = iu(m) - -160 if (j-i .ge. 1) go to 120 - if (i .eq. 1) go to 110 - i = i-1 - -170 i = i+1 - if (i .eq. j) go to 150 - t = x(i+1) - ty = y(i+1) - if (x(i) .le. t) go to 170 - k = i - -180 x(k+1) = x(k) - y(k+1) = y(k) - k = k-1 - if (t .lt. x(k)) go to 180 - x(k+1) = t - y(k+1) = ty - go to 170 - -! Clean up -190 if (kflag .le. -1) then - do i=1,nn - x(i) = -x(i) - enddo - endif - - return -end subroutine ssort diff --git a/lib/symspec.f90 b/lib/symspec.f90 index be87637a5..8a9c1d7a9 100644 --- a/lib/symspec.f90 +++ b/lib/symspec.f90 @@ -45,8 +45,10 @@ subroutine symspec(k,ntrperiod,nsps,ingain,nflatten,pxdb,s,df3,ihsym,npts8) if(nfft3.ne.nfft3z) then ! Compute new window pi=4.0*atan(1.0) + width=0.25*nsps do i=1,nfft3 - w3(i)=2.0*(sin(i*pi/nfft3))**2 !Window for nfft3 spectrum + z=(i-nfft3/2)/width + w3(i)=exp(-z*z) enddo nfft3z=nfft3 endif @@ -115,12 +117,6 @@ subroutine symspec(k,ntrperiod,nsps,ingain,nflatten,pxdb,s,df3,ihsym,npts8) where(syellow<0) syellow=0. endif - if(nflatten.ne.0) then - call flat3(s,iz,nfa,nfb,3,1.0,s) - call flat3(savg,iz,nfa,nfb,3,1.0,savg) - savg=7.0*savg - endif - 900 npts8=k/8 return diff --git a/lib/symspec65.f90 b/lib/symspec65.f90 index 5f6da88fd..e9879edf8 100644 --- a/lib/symspec65.f90 +++ b/lib/symspec65.f90 @@ -10,22 +10,35 @@ subroutine symspec65(dd,npts,ss,nhsym,savg) real*4 ss(MAXHSYM,NSZ) real*4 savg(NSZ) real*4 x(NFFT) + real*4 w(NFFT) complex c(0:NFFT/2) + logical first common/refspec/dfref,ref(NSZ) equivalence (x,c) - save /refspec/ + data first/.true./ + save /refspec/,first,w hstep=2048.d0*12000.d0/11025.d0 !half-symbol = 2229.116 samples nsps=nint(2*hstep) df=12000.0/NFFT - nhsym=npts/hstep - 1.0 + nhsym=(npts-NFFT)/hstep savg=0. fac1=1.e-3 + if(first) then +! Compute the FFT window + pi=4.0*atan(1.0) + width=0.25*nsps + do i=1,NFFT + z=(i-NFFT/2)/width + w(i)=exp(-z*z) + enddo + first=.false. + endif + do j=1,nhsym i0=(j-1)*hstep - x(1:nsps)=fac1*dd(i0+1:i0+nsps) - x(nsps+1:)=0. + x=fac1*w*dd(i0+1:i0+NFFT) call four2a(c,NFFT,1,-1,0) !r2c forward FFT do i=1,NSZ s=real(c(i))**2 + aimag(c(i))**2 diff --git a/mainwindow.cpp b/mainwindow.cpp index 26658bd1f..64fcd85e4 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -1384,12 +1384,23 @@ void MainWindow::readFromStdout() //readFromStdout ui->decodedTextBrowser->displayDecodedText (decodedtext , m_config.my_callsign () , m_config.DXCC () - , m_logBook); + , m_logBook + , m_config.color_CQ() + , m_config.color_MyCall() + , m_config.color_DXCC() + , m_config.color_NewCall()); if (abs(decodedtext.frequencyOffset() - m_wideGraph->rxFreq()) <= 10) // this msg is within 10 hertz of our tuned frequency { // the right QSO window - ui->decodedTextBrowser2->displayDecodedText(decodedtext,m_config.my_callsign (),false,m_logBook); + ui->decodedTextBrowser2->displayDecodedText(decodedtext + , m_config.my_callsign () + , false + , m_logBook + , m_config.color_CQ() + , m_config.color_MyCall() + , m_config.color_DXCC() + , m_config.color_NewCall()); bool b65=decodedtext.isJT65(); if(b65 and m_modeTx!="JT65") on_pbTxMode_clicked(); @@ -1575,7 +1586,8 @@ void MainWindow::guiUpdate() } if (m_config.TX_messages ()) { - ui->decodedTextBrowser2->displayTransmittedText(t,m_modeTx,ui->TxFreqSpinBox->value ()); + ui->decodedTextBrowser2->displayTransmittedText(t,m_modeTx, + ui->TxFreqSpinBox->value(),m_config.color_TxMsg()); } } @@ -1651,7 +1663,8 @@ void MainWindow::guiUpdate() if (m_config.TX_messages () && !m_tune) { - ui->decodedTextBrowser2->displayTransmittedText(t,m_modeTx,ui->TxFreqSpinBox->value ()); + ui->decodedTextBrowser2->displayTransmittedText(t,m_modeTx, + ui->TxFreqSpinBox->value(),m_config.color_TxMsg()); } m_transmitting = true; @@ -1917,7 +1930,14 @@ void MainWindow::doubleClickOnCall(bool shift, bool ctrl) int i9=m_QSOText.indexOf(decodedtext.string()); if (i9<0 and !decodedtext.isTX()) { - ui->decodedTextBrowser2->displayDecodedText(decodedtext,m_config.my_callsign (),false,m_logBook); + ui->decodedTextBrowser2->displayDecodedText(decodedtext + , m_config.my_callsign () + , false + , m_logBook + , m_config.color_CQ() + , m_config.color_MyCall() + , m_config.color_DXCC() + , m_config.color_NewCall()); m_QSOText=decodedtext; } diff --git a/plotter.cpp b/plotter.cpp index 06c1c8608..d91929be7 100644 --- a/plotter.cpp +++ b/plotter.cpp @@ -90,7 +90,7 @@ void CPlotter::draw(float swide[]) //draw() int j,j0,y2; float y; - double gain = pow(10.0,0.05*(m_plotGain+7)); + double gain = pow(10.0,0.05*m_plotGain); //move current data down one line (must do this before attaching a QPainter object) m_WaterfallPixmap.scroll(0,1,0,0,m_w,m_h1); @@ -108,27 +108,32 @@ void CPlotter::draw(float swide[]) //draw() j=0; j0=int(m_startFreq/m_fftBinWidth + 0.5); int iz=XfromFreq(5000.0); + int jz=iz*m_binsPerPixel; m_fMax=FreqfromX(iz); + + flat4_(swide,&iz,&m_Flatten); + flat4_(&jt9com_.savg[j0],&jz,&m_Flatten); + for(int i=0; iiz) swide[i]=0; - y=0.0; - if(swide[i]>0.0) y = 10.0*log10(swide[i]); - int y1 = 5.0*gain*y + 10*(m_plotZero-4); + y=swide[i]; + int y1 = 10.0*gain*y + 10*m_plotZero +40; if (y1<0) y1=0; if (y1>254) y1=254; if (swide[i]>1.e29) y1=255; painter1.setPen(m_ColorTbl[y1]); painter1.drawPoint(i,0); + y2=0; - if(m_bCurrent) y2 = 0.4*gain*y - 15; + if(m_bCurrent) y2 = gain*y - 15; + if(m_bCumulative) { float sum=0.0; int j=j0+m_binsPerPixel*i; for(int k=0; k const& cl) {m_ColorTbl = cl;} + void setFlatten(bool b); signals: void freezeDecode1(int n); @@ -109,6 +103,7 @@ private: qint32 m_nSpan; qint32 m_binsPerPixel; qint32 m_w; + qint32 m_Flatten; QPixmap m_WaterfallPixmap; QPixmap m_2DPixmap; @@ -156,4 +151,8 @@ private slots: void mouseDoubleClickEvent(QMouseEvent *event); }; +extern "C" { + void flat4_(float swide[], int* iz, int* nflatten); +} + #endif // PLOTTER_H diff --git a/widegraph.cpp b/widegraph.cpp index b4874340d..7271eee5e 100644 --- a/widegraph.cpp +++ b/widegraph.cpp @@ -49,6 +49,7 @@ WideGraph::WideGraph(QSettings * settings, QWidget *parent) : int n = m_settings->value("FreqSpan",2).toInt(); m_bFlatten=m_settings->value("Flatten",true).toBool(); ui->cbFlatten->setChecked(m_bFlatten); + ui->widePlot->setFlatten(m_bFlatten); ui->widePlot->setBreadth(m_settings->value("PlotWidth",1000).toInt()); ui->freqSpanSpinBox->setValue(n); ui->widePlot->setNSpan(n); @@ -364,6 +365,7 @@ void WideGraph::on_paletteComboBox_activated (QString const& palette) void WideGraph::on_cbFlatten_toggled(bool b) { m_bFlatten=b; + ui->widePlot->setFlatten(m_bFlatten); } void WideGraph::on_adjust_palette_push_button_clicked (bool)