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
This commit is contained in:
Joe Taylor 2015-02-11 00:50:35 +00:00
parent 88bbb988ef
commit a93e55fef0
18 changed files with 494 additions and 420 deletions

View File

@ -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

View File

@ -26,6 +26,7 @@
#include <QStandardPaths>
#include <QFont>
#include <QFontDialog>
#include <QColorDialog>
#include <QDebug>
#include "ui_Configuration.h"
@ -251,6 +252,7 @@ public:
Q_SLOT void reject () override;
Q_SLOT void done (int) override;
private:
typedef QList<QAudioDeviceInfo> 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_

View File

@ -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,
//

View File

@ -22,6 +22,12 @@
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QTabWidget" name="configuration_tabs">
<property name="minimumSize">
<size>
<width>80</width>
<height>20</height>
</size>
</property>
<property name="toolTip">
<string>Select tab to change configuration parameters.</string>
</property>
@ -1682,6 +1688,183 @@ Right click for insert and delete options.</string>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>Colors</string>
</attribute>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>44</x>
<y>60</y>
<width>198</width>
<height>141</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_13">
<item row="0" column="0">
<widget class="QPushButton" name="pbCQmsg">
<property name="minimumSize">
<size>
<width>110</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>CQ in message</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="labCQ">
<property name="minimumSize">
<size>
<width>80</width>
<height>20</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QLabel{background-color: #66ff66}</string>
</property>
<property name="text">
<string>K1ABC</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="pbMyCall">
<property name="minimumSize">
<size>
<width>110</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>My Call in message</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="labMyCall">
<property name="minimumSize">
<size>
<width>80</width>
<height>20</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QLabel{background-color: #ff6666}</string>
</property>
<property name="text">
<string>K1ABC</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QPushButton" name="pbTxMsg">
<property name="minimumSize">
<size>
<width>110</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Transmitted message</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="labTx">
<property name="minimumSize">
<size>
<width>80</width>
<height>20</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QLabel{background-color: yellow}</string>
</property>
<property name="text">
<string>K1ABC</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QPushButton" name="pbNewDXCC">
<property name="minimumSize">
<size>
<width>110</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>New DXCC</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="labDXCC">
<property name="minimumSize">
<size>
<width>80</width>
<height>20</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QLabel{background-color: #ff66ff}</string>
</property>
<property name="text">
<string>K1ABC</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QPushButton" name="pbNewCall">
<property name="minimumSize">
<size>
<width>110</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>New Call</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="labNewCall">
<property name="minimumSize">
<size>
<width>80</width>
<height>20</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QLabel{background-color: #66ffff}</string>
</property>
<property name="text">
<string>K1ABC</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</widget>
</item>
<item>
@ -1834,12 +2017,12 @@ soundcard changes</string>
</connection>
</connections>
<buttongroups>
<buttongroup name="TX_mode_button_group"/>
<buttongroup name="CAT_stop_bits_button_group"/>
<buttongroup name="split_mode_button_group"/>
<buttongroup name="CAT_data_bits_button_group"/>
<buttongroup name="CAT_handshake_button_group"/>
<buttongroup name="PTT_method_button_group"/>
<buttongroup name="TX_mode_button_group"/>
<buttongroup name="TX_audio_source_button_group"/>
<buttongroup name="split_mode_button_group"/>
<buttongroup name="PTT_method_button_group"/>
</buttongroups>
</ui>

View File

@ -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;

View File

@ -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);
};

View File

@ -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)

View File

@ -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)

View File

@ -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

50
lib/flat4.f90 Normal file
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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; i<iz; i++) {
if(i>iz) 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<m_binsPerPixel; k++) {
sum+=jt9com_.savg[j++];
}
y2=gain*6.0*log10(sum/m_binsPerPixel) - 10.0;
y2 += m_plotZero;
y2=1.3*gain*sum/m_binsPerPixel + m_plotZero - 15;
if(m_Flatten==0) y2 += 40;
}
if(m_bLinearAvg) {
@ -137,7 +142,7 @@ void CPlotter::draw(float swide[]) //draw()
for(int k=0; k<m_binsPerPixel; k++) {
sum+=jt9w_.syellow[j++];
}
y2=sum/m_binsPerPixel * (0.2*m_h/50.0) - 20.0;
y2=gain*sum/m_binsPerPixel * (m_h/50.0) - 20.0;
}
if(i==iz-1) painter2D.drawPolyline(LineBuf,j);
@ -470,3 +475,9 @@ void CPlotter::setDialFreq(double d)
DrawOverlay();
update();
}
void CPlotter::setFlatten(bool b)
{
m_Flatten=0;
if(b) m_Flatten=1;
}

View File

@ -60,24 +60,18 @@ public:
void SetPercent2DScreen(int percent){m_Percent2DScreen=percent;}
int getFmax();
void setDialFreq(double d);
void setCurrent(bool b) {m_bCurrent = b;}
bool current() const {return m_bCurrent;}
void setCumulative(bool b) {m_bCumulative = b;}
bool cumulative() const {return m_bCumulative;}
void setLinearAvg(bool b) {m_bLinearAvg = b;}
bool linearAvg() const {return m_bLinearAvg;}
void setBreadth(qint32 w) {m_w = w;}
qint32 breadth() const {return m_w;}
float fSpan() const {return m_fSpan;}
void setLockTxFreq(bool b) {m_lockTxFreq = b;}
void setColours(QVector<QColor> 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

View File

@ -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)