mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-11-23 12:48:40 -05:00
Basic functionality of Echo spectrum is in place.
git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@5557 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
parent
477d45a72c
commit
be5eb31884
@ -262,6 +262,7 @@ set (wsjt_FSRCS
|
||||
lib/astro.f90
|
||||
lib/astrosub.f90
|
||||
lib/astro0.f90
|
||||
lib/avecho.f90
|
||||
lib/avg4.f90
|
||||
lib/azdist.f90
|
||||
lib/baddata.f90
|
||||
|
@ -44,6 +44,13 @@ extern "C" {
|
||||
extern struct {
|
||||
float syellow[NSMAX];
|
||||
} jt9w_;
|
||||
extern struct {
|
||||
int nclearave;
|
||||
int nsum;
|
||||
float blue[2000];
|
||||
float red[2000];
|
||||
} echocom_;
|
||||
|
||||
}
|
||||
|
||||
#endif // COMMONS_H
|
||||
|
@ -1,4 +1,4 @@
|
||||
//#include "commons.h"
|
||||
#include "commons.h"
|
||||
#include <QSettings>
|
||||
#include "echoplot.h"
|
||||
#include "echograph.h"
|
||||
@ -27,6 +27,7 @@ EchoGraph::EchoGraph(QSettings * settings, QWidget *parent) :
|
||||
ui->zeroSlider->setValue(ui->echoPlot->getPlotZero());
|
||||
ui->gainSlider->setValue(ui->echoPlot->getPlotGain());
|
||||
ui->smoothSpinBox->setValue(m_settings->value("Smooth",0).toInt());
|
||||
ui->binsPerPixelSpinBox->setValue(m_settings->value("EchoBPP",0).toInt());
|
||||
ui->echoPlot->m_blue=m_settings->value("BlueCurve",false).toBool();
|
||||
ui->cbBlue->setChecked(ui->echoPlot->m_blue);
|
||||
m_settings->endGroup();
|
||||
@ -52,6 +53,7 @@ void EchoGraph::saveSettings()
|
||||
m_settings->setValue("PlotZero",ui->echoPlot->m_plotZero);
|
||||
m_settings->setValue("PlotGain",ui->echoPlot->m_plotGain);
|
||||
m_settings->setValue("Smooth",ui->echoPlot->m_smooth);
|
||||
m_settings->setValue("EchoBPP",ui->echoPlot->m_binsPerPixel);
|
||||
m_settings->setValue("BlueCurve",ui->echoPlot->m_blue);
|
||||
m_settings->endGroup();
|
||||
}
|
||||
@ -84,3 +86,10 @@ void EchoGraph::on_zeroSlider_valueChanged(int value)
|
||||
ui->echoPlot->setPlotZero(value);
|
||||
ui->echoPlot->draw();
|
||||
}
|
||||
|
||||
void EchoGraph::on_binsPerPixelSpinBox_valueChanged(int n)
|
||||
{
|
||||
ui->echoPlot->m_binsPerPixel=n;
|
||||
ui->echoPlot->DrawOverlay();
|
||||
ui->echoPlot->draw();
|
||||
}
|
||||
|
@ -26,7 +26,8 @@ private slots:
|
||||
void on_smoothSpinBox_valueChanged(int n);
|
||||
void on_cbBlue_toggled(bool checked);
|
||||
void on_gainSlider_valueChanged(int value);
|
||||
void on_zeroSlider_valueChanged(int value);
|
||||
void on_zeroSlider_valueChanged(int value);
|
||||
void on_binsPerPixelSpinBox_valueChanged(int n);
|
||||
|
||||
private:
|
||||
QSettings * m_settings;
|
||||
|
35
echograph.ui
35
echograph.ui
@ -89,6 +89,25 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="binsPerPixelSpinBox">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string>Bins/Pixel </string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>10</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
@ -161,15 +180,17 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Smooth</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="smoothSpinBox">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string>Smooth </string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>20</number>
|
||||
</property>
|
||||
|
16
echoplot.cpp
16
echoplot.cpp
@ -1,5 +1,5 @@
|
||||
#include "echoplot.h"
|
||||
//#include "commons.h"
|
||||
#include "commons.h"
|
||||
#include <math.h>
|
||||
#include <QDebug>
|
||||
#include "moc_echoplot.cpp"
|
||||
@ -18,7 +18,7 @@ EPlotter::EPlotter(QWidget *parent) : //EPlotter Constructor
|
||||
setAttribute(Qt::WA_NoSystemBackground, true);
|
||||
|
||||
m_StartFreq = -200;
|
||||
m_fftBinWidth=48000.0/131072.0;
|
||||
m_fftBinWidth=12000.0/32768.0;
|
||||
m_fSpan=1000.0;
|
||||
m_hdivs = HORZ_DIVS;
|
||||
m_Running = false;
|
||||
@ -81,7 +81,7 @@ void EPlotter::paintEvent(QPaintEvent *) // paintEvent()
|
||||
m_paintEventBusy=false;
|
||||
}
|
||||
|
||||
void EPlotter::draw() //draw()
|
||||
void EPlotter::draw() //draw()
|
||||
{
|
||||
int i,j,y;
|
||||
float blue[2000],red[2000];
|
||||
@ -91,16 +91,16 @@ void EPlotter::draw() //draw()
|
||||
QPainter painter2D(&m_2DPixmap);
|
||||
QRect tmp(0,0,m_w,m_h2);
|
||||
painter2D.fillRect(tmp,Qt::black);
|
||||
/*
|
||||
if(datcom_.nclearave==0) {
|
||||
|
||||
if(echocom_.nclearave==0) {
|
||||
QPoint LineBuf[MAX_SCREENSIZE];
|
||||
QPen penBlue(QColor(0,255,255),1);
|
||||
QPen penRed(Qt::red,1);
|
||||
j=0;
|
||||
int i0=1000 + int(m_StartFreq/m_fftBinWidth);
|
||||
for(i=0; i<2000; i++) {
|
||||
blue[i]=datcom_.blue[i];
|
||||
red[i]=datcom_.red[i];
|
||||
blue[i]=echocom_.blue[i];
|
||||
red[i]=echocom_.red[i];
|
||||
}
|
||||
if(m_smooth>0) {
|
||||
for(i=0; i<m_smooth; i++) {
|
||||
@ -132,7 +132,7 @@ void EPlotter::draw() //draw()
|
||||
}
|
||||
painter2D.drawPolyline(LineBuf,j);
|
||||
}
|
||||
*/
|
||||
|
||||
update(); //trigger a new paintEvent
|
||||
}
|
||||
|
||||
|
@ -31,9 +31,10 @@ public:
|
||||
qint32 m_plotZero;
|
||||
qint32 m_plotGain;
|
||||
qint32 m_smooth;
|
||||
qint32 m_binsPerPixel;
|
||||
bool m_blue;
|
||||
|
||||
void draw(); //Update the waterfall
|
||||
void draw(); //Update the Echo plot
|
||||
void SetRunningState(bool running);
|
||||
void setPlotZero(int plotZero);
|
||||
int getPlotZero();
|
||||
|
119
lib/avecho.f90
Normal file
119
lib/avecho.f90
Normal file
@ -0,0 +1,119 @@
|
||||
subroutine avecho(id2,ndop,nfrit,nqual,f1,rms0,sigdb,snr,dfreq,width)
|
||||
|
||||
integer TXLENGTH
|
||||
parameter (TXLENGTH=27648) !27*1024
|
||||
parameter (NFFT=32768,NH=NFFT/2)
|
||||
integer*2 id2(34560) !Buffer for Rx data
|
||||
real sa(2000) !Avg spectrum relative to initial Doppler echo freq
|
||||
real sb(2000) !Avg spectrum with Dither and changing Doppler removed
|
||||
integer nsum !Number of integrations
|
||||
real dop0 !Doppler shift for initial integration (Hz)
|
||||
real doppler !Doppler shift for current integration (Hz)
|
||||
real s(8192)
|
||||
real x(NFFT)
|
||||
integer ipkv(1)
|
||||
complex c(0:NH)
|
||||
equivalence (x,c),(ipk,ipkv)
|
||||
common/echocom/nclearave,nsum,blue(2000),red(2000)
|
||||
save dop0,sa,sb
|
||||
|
||||
dop=ndop
|
||||
doppler=dop
|
||||
sq=0.
|
||||
do i=1,TXLENGTH
|
||||
x(i)=id2(i)
|
||||
sq=sq + x(i)*x(i)
|
||||
enddo
|
||||
rms0=sqrt(sq/TXLENGTH)
|
||||
|
||||
if(nclearave.ne.0) nsum=0
|
||||
nclearave=0
|
||||
if(nsum.eq.0) then
|
||||
dop0=doppler !Remember the initial Doppler
|
||||
sa=0. !Clear the average arrays
|
||||
sb=0.
|
||||
endif
|
||||
|
||||
x(TXLENGTH+1:)=0.
|
||||
x=x/TXLENGTH
|
||||
call four2a(x,NFFT,1,-1,0)
|
||||
df=12000.0/NFFT
|
||||
do i=1,8192 !Get spectrum 0 - 3 kHz
|
||||
s(i)=real(c(i))**2 + aimag(c(i))**2
|
||||
enddo
|
||||
|
||||
fnominal=1500.0 !Nominal audio frequency w/o doppler or dither
|
||||
ia=nint((fnominal+dop0-nfrit)/df)
|
||||
ib=nint((f1+doppler-nfrit)/df)
|
||||
if(ia.lt.600 .or. ib.lt.600) go to 900
|
||||
if(ia.gt.7590 .or. ib.gt.7590) go to 900
|
||||
|
||||
nsum=nsum+1
|
||||
|
||||
do i=1,2000
|
||||
sa(i)=sa(i) + s(ia+i-1000) !Center at initial doppler freq
|
||||
sb(i)=sb(i) + s(ib+i-1000) !Center at expected echo freq
|
||||
enddo
|
||||
|
||||
call pctile(sb,200,50,r0)
|
||||
call pctile(sb(1800),200,50,r1)
|
||||
|
||||
sum=0.
|
||||
sq=0.
|
||||
do i=1,2000
|
||||
y=r0 + (r1-r0)*(i-100.0)/1800.0
|
||||
blue(i)=sa(i)/y
|
||||
red(i)=sb(i)/y
|
||||
if(i.le.500 .or. i.ge.1501) then
|
||||
sum=sum+red(i)
|
||||
sq=sq + (red(i)-1.0)**2
|
||||
endif
|
||||
enddo
|
||||
ave=sum/1000.0
|
||||
rms=sqrt(sq/1000.0)
|
||||
|
||||
redmax=maxval(red)
|
||||
ipkv=maxloc(red)
|
||||
fac=10.0/max(redmax,10.0)
|
||||
dfreq=(ipk-1000)*df
|
||||
snr=(redmax-ave)/rms
|
||||
|
||||
sigdb=-99.0
|
||||
if(ave.gt.0.0) sigdb=10.0*log10(redmax/ave - 1.0) - 35.7
|
||||
|
||||
nqual=0
|
||||
if(nsum.ge.2 .and. nsum.lt.4) nqual=(snr-4)/5
|
||||
if(nsum.ge.4 .and. nsum.lt.8) nqual=(snr-3)/4
|
||||
if(nsum.ge.8 .and. nsum.lt.12) nqual=(snr-3)/3
|
||||
if(nsum.ge.12) nqual=(snr-2.5)/2.5
|
||||
if(nqual.lt.0) nqual=0
|
||||
if(nqual.gt.10) nqual=10
|
||||
|
||||
! Scale for plotting
|
||||
blue=fac*blue
|
||||
red=fac*red
|
||||
|
||||
sum=0.
|
||||
do i=ipk,ipk+300
|
||||
if(red(i).lt.1.0) exit
|
||||
sum=sum+(red(i)-1.0)
|
||||
enddo
|
||||
do i=ipk-1,ipk-300,-1
|
||||
if(red(i).lt.1.0) exit
|
||||
sum=sum+(red(i)-1.0)
|
||||
enddo
|
||||
bins=sum/(red(ipk)-1.0)
|
||||
width=df*bins
|
||||
nsmo=max(0.0,0.25*bins)
|
||||
|
||||
do i=1,nsmo
|
||||
call smo121(red,2000)
|
||||
call smo121(blue,2000)
|
||||
enddo
|
||||
|
||||
900 continue
|
||||
write(*,3001) ia,ib,nclearave,nsum,width,snr,nqual
|
||||
3001 format('avecho:',4i6,2f7.1,i5)
|
||||
|
||||
return
|
||||
end subroutine avecho
|
@ -437,6 +437,10 @@ MainWindow::MainWindow(bool multiple, QSettings * settings, QSharedMemory *shdme
|
||||
m_bHaveTransmitted=false;
|
||||
m_bEchoTxOK=false;
|
||||
m_bTransmittedEcho=false;
|
||||
m_nDop=0;
|
||||
m_nDop00=0;
|
||||
m_nDopr=0;
|
||||
m_nclearave=1;
|
||||
|
||||
signalMeter = new SignalMeter(ui->meterFrame);
|
||||
signalMeter->resize(50, 160);
|
||||
@ -820,8 +824,20 @@ void MainWindow::dataSink(qint64 frames)
|
||||
|
||||
if(ihsym == m_hsymStop) {
|
||||
if(m_mode=="Echo") {
|
||||
qDebug() << "call plotSpec()" << m_s6;
|
||||
float snr=0;
|
||||
int nfrit=0;
|
||||
int nqual=0;
|
||||
float f1=1500.0;
|
||||
float rms=0.0;
|
||||
float sigdb=0.0;
|
||||
float dfreq=0.0;
|
||||
float width=0.0;
|
||||
echocom_.nclearave=m_nclearave;
|
||||
avecho_(&jt9com_.d2[0],&m_nDop00,&nfrit,&nqual,&f1,&rms,&sigdb,
|
||||
&snr,&dfreq,&width);
|
||||
qDebug() << "A" << echocom_.nclearave << echocom_.nsum << rms << sigdb;
|
||||
if(m_echoGraph->isVisible()) m_echoGraph->plotSpec();
|
||||
m_nclearave=0;
|
||||
return;
|
||||
}
|
||||
if( m_dialFreqRxWSPR==0) m_dialFreqRxWSPR=m_dialFreq;
|
||||
@ -2145,9 +2161,8 @@ void MainWindow::guiUpdate()
|
||||
QDateTime t = QDateTime::currentDateTimeUtc();
|
||||
if(m_astroWidget) {
|
||||
m_freqMoon=m_dialFreq + 1000*m_astroWidget->m_kHz + m_astroWidget->m_Hz;
|
||||
int ndop,ndop00;
|
||||
m_astroWidget->astroUpdate(t, m_config.my_grid (), m_hisGrid,m_freqMoon,
|
||||
&ndop, &ndop00, m_transmitting,
|
||||
&m_nDop, &m_nDop00, m_transmitting,
|
||||
m_config.data_dir().absoluteFilePath("JPLEPH"));
|
||||
|
||||
//Apply Doppler corrections only for 50 MHz and above
|
||||
@ -2155,23 +2170,28 @@ void MainWindow::guiUpdate()
|
||||
|
||||
if(m_astroWidget->m_bDopplerTracking) {
|
||||
|
||||
int ndopr=0; // No Doppler Correction
|
||||
if(m_DopplerMethod==1) {
|
||||
// All Doppler correction done here; DX station stays at nominal dial frequency.
|
||||
ndopr=m_astroWidget->m_stepHz*qRound(double(ndop)/double(m_astroWidget->m_stepHz));
|
||||
// All Doppler correction done here; DX station stays at nominal dial frequency.
|
||||
m_nDopr=m_astroWidget->m_stepHz*qRound(double(m_nDop)/double(
|
||||
m_astroWidget->m_stepHz));
|
||||
}
|
||||
if(m_DopplerMethod==2) {
|
||||
// Doppler correction to constant frequency on Moon
|
||||
ndopr=m_astroWidget->m_stepHz*qRound(double(ndop00/2.0)/double(m_astroWidget->m_stepHz));
|
||||
m_nDopr=m_astroWidget->m_stepHz*qRound(double(m_nDop00/2.0)/double(
|
||||
m_astroWidget->m_stepHz));
|
||||
}
|
||||
|
||||
if(m_transmitting) {
|
||||
m_dialFreqTx=m_freqNominal + 1000*m_astroWidget->m_kHz + m_astroWidget->m_Hz - ndopr;
|
||||
ui->labDialFreq->setText (Radio::pretty_frequency_MHz_string (m_dialFreqTx));
|
||||
m_dialFreqTx=m_freqNominal + 1000*m_astroWidget->m_kHz +
|
||||
m_astroWidget->m_Hz - m_nDopr;
|
||||
ui->labDialFreq->setText (Radio::pretty_frequency_MHz_string (
|
||||
m_dialFreqTx));
|
||||
Q_EMIT m_config.transceiver_tx_frequency (m_dialFreqTx);
|
||||
} else {
|
||||
m_dialFreq=m_freqNominal + 1000*m_astroWidget->m_kHz + m_astroWidget->m_Hz + ndopr;
|
||||
ui->labDialFreq->setText (Radio::pretty_frequency_MHz_string (m_dialFreq));
|
||||
m_dialFreq=m_freqNominal + 1000*m_astroWidget->m_kHz +
|
||||
m_astroWidget->m_Hz + m_nDopr;
|
||||
ui->labDialFreq->setText (Radio::pretty_frequency_MHz_string (
|
||||
m_dialFreq));
|
||||
Q_EMIT m_config.transceiver_frequency(m_dialFreq);
|
||||
}
|
||||
}
|
||||
@ -2216,7 +2236,6 @@ void MainWindow::guiUpdate()
|
||||
if(!m_monitoring and !m_diskData) {
|
||||
signalMeter->setValue(0);
|
||||
}
|
||||
|
||||
m_sec0=nsec;
|
||||
}
|
||||
|
||||
|
@ -333,6 +333,9 @@ private:
|
||||
qint32 m_dBm;
|
||||
qint32 m_pctx;
|
||||
qint32 m_nseq;
|
||||
qint32 m_nDop; //Doppler shift of EME DX station
|
||||
qint32 m_nDop00; //EME self-Doppler
|
||||
qint32 m_nDopr; //Applied Doppler, rounded to nearest 1, 10 or 100 Hz
|
||||
|
||||
bool m_btxok; //True if OK to transmit
|
||||
bool m_diskData;
|
||||
@ -555,6 +558,10 @@ extern "C" {
|
||||
|
||||
void wspr_downsample_(short int d2[], int* k);
|
||||
void savec2_(char* fname, int* m_TRseconds, double* m_dialFreq, int len1);
|
||||
|
||||
void avecho_( short id2[], int* dop, int* nfrit, int* nqual, float* f1,
|
||||
float* rms, float* sigdb, float* snr, float* dfreq,
|
||||
float* width);
|
||||
}
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
|
Loading…
Reference in New Issue
Block a user