mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-11-25 21:58:38 -05:00
First working code offering optional computation and use of a reference
spectrum. git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@6608 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
parent
3541d12a67
commit
b843894061
@ -62,6 +62,7 @@ extern struct dec_data {
|
|||||||
extern struct {
|
extern struct {
|
||||||
float syellow[NSMAX];
|
float syellow[NSMAX];
|
||||||
float ref[3457];
|
float ref[3457];
|
||||||
|
float filter[3457];
|
||||||
} spectra_;
|
} spectra_;
|
||||||
|
|
||||||
extern struct {
|
extern struct {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
subroutine refspectrum(id2,brefspec)
|
subroutine refspectrum(id2,brefspec,buseref,fname)
|
||||||
|
|
||||||
! Input:
|
! Input:
|
||||||
! id2 i*2 Raw 16-bit integer data, 12000 Hz sample rate
|
! id2 i*2 Raw 16-bit integer data, 12000 Hz sample rate
|
||||||
@ -6,24 +6,41 @@ subroutine refspectrum(id2,brefspec)
|
|||||||
|
|
||||||
parameter (NFFT=6912,NH=NFFT/2)
|
parameter (NFFT=6912,NH=NFFT/2)
|
||||||
integer*2 id2(NH)
|
integer*2 id2(NH)
|
||||||
logical brefspec,brefspec0
|
logical*1 brefspec,buseref
|
||||||
real x(NFFT)
|
|
||||||
real s(0:NH)
|
real x0(0:NH-1) !Input samples
|
||||||
complex cx(0:NH)
|
real x1(0:NH-1) !Output samples (delayed by one block)
|
||||||
common/spectra/syellow(6827),ref(0:NH)
|
real x0s(0:NH-1) !Saved upper half of input samples
|
||||||
|
real x1s(0:NH-1) !Saved upper half of output samples
|
||||||
|
real x(0:NFFT-1) !Work array
|
||||||
|
real*4 w(0:NFFT-1) !Window function
|
||||||
|
real*4 s(0:NH) !Average spectrum
|
||||||
|
real*4 fil(0:NH)
|
||||||
|
logical first,firstuse
|
||||||
|
complex cx(0:NH) !Complex frequency-domain work array
|
||||||
|
character*(*) fname
|
||||||
|
common/spectra/syellow(6827),ref(0:NH),filter(0:NH)
|
||||||
equivalence(x,cx)
|
equivalence(x,cx)
|
||||||
data nsave/0/,brefspec0/.false./
|
data first/.true./,firstuse/.true./
|
||||||
! save brefspec0,nsave,ref
|
|
||||||
save
|
save
|
||||||
|
|
||||||
if(brefspec) then
|
if(first) then
|
||||||
if(.not.brefspec0) then
|
pi=4.0*atan(1.0)
|
||||||
nsave=0
|
do i=0,NFFT-1
|
||||||
s=0.
|
ww=sin(i*pi/NFFT)
|
||||||
endif
|
w(i)=ww*ww/NFFT
|
||||||
|
enddo
|
||||||
|
nsave=0
|
||||||
|
s=0.0
|
||||||
|
filter=1.0
|
||||||
|
x0s=0.
|
||||||
|
x1s=0.
|
||||||
|
first=.false.
|
||||||
|
endif
|
||||||
|
|
||||||
x(1:NH)=0.001*id2
|
if(brefspec) then
|
||||||
x(NH+1:)=0.0
|
x(0:NH-1)=0.001*id2
|
||||||
|
x(NH:NFFT-1)=0.0
|
||||||
call four2a(x,NFFT,1,-1,0) !r2c FFT
|
call four2a(x,NFFT,1,-1,0) !r2c FFT
|
||||||
|
|
||||||
do i=1,NH
|
do i=1,NH
|
||||||
@ -31,27 +48,80 @@ subroutine refspectrum(id2,brefspec)
|
|||||||
enddo
|
enddo
|
||||||
nsave=nsave+1
|
nsave=nsave+1
|
||||||
|
|
||||||
if(mod(nsave,34).eq.0) then !About 9.8 sec
|
fac0=0.9
|
||||||
|
if(mod(nsave,4).eq.0) then
|
||||||
df=12000.0/NFFT
|
df=12000.0/NFFT
|
||||||
ia=nint(500.0/df)
|
ia=nint(1000.0/df)
|
||||||
ib=nint(2500.0/df)
|
ib=nint(2000.0/df)
|
||||||
call pctile(s(ia),ib-ia+1,50,xmed)
|
avemid=sum(s(ia:ib))/(ib-ia+1)
|
||||||
db0=db(xmed)
|
do i=0,NH
|
||||||
! nhadd=10
|
fil(i)=0.
|
||||||
open(16,file='refspec.dat',status='unknown')
|
filter(i)=-60.0
|
||||||
|
if(s(i).gt.0.0) then
|
||||||
|
fil(i)=sqrt(avemid/s(i))
|
||||||
|
endif
|
||||||
|
enddo
|
||||||
|
|
||||||
|
ia=nint(240.0/df)
|
||||||
|
fac=fac0
|
||||||
|
do i=ia,1,-1
|
||||||
|
fac=fac*fac0
|
||||||
|
fil(i)=fac*fil(i)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
ib=nint(4000.0/df)
|
||||||
|
fac=fac0
|
||||||
|
do i=ib,NH
|
||||||
|
fac=fac*fac0
|
||||||
|
fil(i)=fac*fil(i)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
do iter=1,1000 !### ??? ###
|
||||||
|
call smo121(fil,NH)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
do i=0,NH
|
||||||
|
filter(i)=-60.0
|
||||||
|
if(s(i).gt.0.0) filter(i)=20.0*log10(fil(i))
|
||||||
|
enddo
|
||||||
|
|
||||||
|
! open(16,file='refspec.dat',status='unknown')
|
||||||
|
open(16,file=fname,status='unknown')
|
||||||
do i=1,NH
|
do i=1,NH
|
||||||
freq=i*df
|
freq=i*df
|
||||||
! ia=max(1,i-nhadd)
|
ref(i)=db(s(i)/avemid)
|
||||||
! ib=min(NH,i+nhadd)
|
write(16,1000) freq,s(i),ref(i),fil(i),filter(i)
|
||||||
! smo=sum(s(ia:ib))/(ib-ia+1)
|
1000 format(f10.3,e12.3,f12.6,e12.3,f12.6)
|
||||||
ref(i)=db(s(i)) - db0
|
|
||||||
write(16,1000) freq,s(i),ref(i)
|
|
||||||
1000 format(f10.3,e12.3,f12.6)
|
|
||||||
enddo
|
enddo
|
||||||
close(16)
|
close(16)
|
||||||
endif
|
endif
|
||||||
|
return
|
||||||
endif
|
endif
|
||||||
brefspec0=brefspec
|
|
||||||
|
if(buseref) then
|
||||||
|
if(firstuse) then
|
||||||
|
! open(16,file='refspec.dat',status='unknown')
|
||||||
|
fil=1.0
|
||||||
|
open(16,file=fname,status='old',err=10)
|
||||||
|
do i=1,NH
|
||||||
|
read(16,1000,err=10,end=10) freq,s(i),ref(i),fil(i),filter(i)
|
||||||
|
enddo
|
||||||
|
10 close(16)
|
||||||
|
firstuse=.false.
|
||||||
|
endif
|
||||||
|
x0=id2
|
||||||
|
x(0:NH-1)=x0s !Previous 2nd half to new 1st half
|
||||||
|
x(NH:NFFT-1)=x0 !New 2nd half
|
||||||
|
x0s=x0 !Save the new 2nd half
|
||||||
|
x=w*x !Apply window
|
||||||
|
call four2a(x,NFFT,1,-1,0) !r2c FFT (to frequency domain)
|
||||||
|
cx=fil*cx
|
||||||
|
call four2a(cx,NFFT,1,1,-1) !c2r FFT (back to time domain)
|
||||||
|
x1=x1s + x(0:NH-1) !Add previous segment's 2nd half
|
||||||
|
id2=nint(x1)
|
||||||
|
x1s=x(NH:NFFT-1) !Save the new 2nd half
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
return
|
return
|
||||||
end subroutine refspectrum
|
end subroutine refspectrum
|
||||||
|
@ -30,7 +30,7 @@ subroutine symspec(shared_data,k,ntrperiod,nsps,ingain,nminw,pxdb,s, &
|
|||||||
complex cx(0:MAXFFT3/2)
|
complex cx(0:MAXFFT3/2)
|
||||||
integer nch(7)
|
integer nch(7)
|
||||||
|
|
||||||
common/spectra/syellow(NSMAX),ref(0:3456)
|
common/spectra/syellow(NSMAX),ref(0:3456),filter(0:3456)
|
||||||
data rms/999.0/,k0/99999999/,nfft3z/0/
|
data rms/999.0/,k0/99999999/,nfft3z/0/
|
||||||
data nch/1,2,4,9,18,36,72/
|
data nch/1,2,4,9,18,36,72/
|
||||||
equivalence (xc,cx)
|
equivalence (xc,cx)
|
||||||
|
@ -99,7 +99,8 @@ extern "C" {
|
|||||||
void hash_calls_(char calls[], int* ih9, int len);
|
void hash_calls_(char calls[], int* ih9, int len);
|
||||||
void degrade_snr_(short d2[], int* n, float* db, float* bandwidth);
|
void degrade_snr_(short d2[], int* n, float* db, float* bandwidth);
|
||||||
void wav12_(short d2[], short d1[], int* nbytes, short* nbitsam2);
|
void wav12_(short d2[], short d1[], int* nbytes, short* nbitsam2);
|
||||||
void refspectrum_(short int d2[], bool* brefspec);
|
void refspectrum_(short int d2[], bool* brefspec, bool* buseref,
|
||||||
|
const char* c_fname, int len);
|
||||||
}
|
}
|
||||||
|
|
||||||
int volatile itone[NUM_ISCAT_SYMBOLS]; //Audio tones for all Tx symbols
|
int volatile itone[NUM_ISCAT_SYMBOLS]; //Audio tones for all Tx symbols
|
||||||
@ -874,7 +875,12 @@ void MainWindow::dataSink(qint64 frames)
|
|||||||
static float df3;
|
static float df3;
|
||||||
|
|
||||||
int k (frames);
|
int k (frames);
|
||||||
if(m_bRefSpec) refspectrum_(&dec_data.d2[k-3456],&m_bRefSpec);
|
QString fname {QDir::toNativeSeparators(m_dataDir.absoluteFilePath ("refspec.dat"))};
|
||||||
|
QByteArray bafname = fname.toLatin1();
|
||||||
|
const char *c_fname = bafname.data();
|
||||||
|
int len=fname.length();
|
||||||
|
m_bUseRef=m_wideGraph->useRef();
|
||||||
|
refspectrum_(&dec_data.d2[k-3456],&m_bRefSpec,&m_bUseRef,c_fname,len);
|
||||||
|
|
||||||
if(m_diskData) {
|
if(m_diskData) {
|
||||||
dec_data.params.ndiskdat=1;
|
dec_data.params.ndiskdat=1;
|
||||||
@ -4043,7 +4049,7 @@ void MainWindow::band_changed (Frequency f)
|
|||||||
if (f + m_wideGraph->nStartFreq () > m_freqNominal + ui->TxFreqSpinBox->value ()
|
if (f + m_wideGraph->nStartFreq () > m_freqNominal + ui->TxFreqSpinBox->value ()
|
||||||
|| f + m_wideGraph->nStartFreq () + m_wideGraph->fSpan () <=
|
|| f + m_wideGraph->nStartFreq () + m_wideGraph->fSpan () <=
|
||||||
m_freqNominal + ui->TxFreqSpinBox->value ()) {
|
m_freqNominal + ui->TxFreqSpinBox->value ()) {
|
||||||
qDebug () << "start f:" << m_wideGraph->nStartFreq () << "span:" << m_wideGraph->fSpan () << "DF:" << ui->TxFreqSpinBox->value ();
|
// qDebug () << "start f:" << m_wideGraph->nStartFreq () << "span:" << m_wideGraph->fSpan () << "DF:" << ui->TxFreqSpinBox->value ();
|
||||||
// disable auto Tx if "blind" QSY outside of waterfall
|
// disable auto Tx if "blind" QSY outside of waterfall
|
||||||
ui->stopTxButton->click (); // halt any transmission
|
ui->stopTxButton->click (); // halt any transmission
|
||||||
auto_tx_mode (false); // disable auto Tx
|
auto_tx_mode (false); // disable auto Tx
|
||||||
@ -5344,6 +5350,7 @@ void MainWindow::fastPick(int x0, int x1, int y)
|
|||||||
|
|
||||||
void MainWindow::on_actionSave_reference_spectrum_triggered()
|
void MainWindow::on_actionSave_reference_spectrum_triggered()
|
||||||
{
|
{
|
||||||
|
if(!m_monitoring) on_monitorButton_clicked (true);
|
||||||
m_bRefSpec=true;
|
m_bRefSpec=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -426,6 +426,7 @@ private:
|
|||||||
bool m_bFastDecodeCalled;
|
bool m_bFastDecodeCalled;
|
||||||
bool m_bDoubleClickAfterCQnnn;
|
bool m_bDoubleClickAfterCQnnn;
|
||||||
bool m_bRefSpec;
|
bool m_bRefSpec;
|
||||||
|
bool m_bUseRef;
|
||||||
float m_pctZap;
|
float m_pctZap;
|
||||||
|
|
||||||
char m_msg[100][80];
|
char m_msg[100][80];
|
||||||
|
@ -176,7 +176,9 @@ void CPlotter::draw(float swide[], bool bScroll) //dr
|
|||||||
if(m_bReference) { //Reference (red)
|
if(m_bReference) { //Reference (red)
|
||||||
float df_ref=12000.0/6912.0;
|
float df_ref=12000.0/6912.0;
|
||||||
int j=FreqfromX(i)/df_ref + 0.5;
|
int j=FreqfromX(i)/df_ref + 0.5;
|
||||||
y2=gain2d*spectra_.ref[j] + m_plot2dZero;
|
y2=spectra_.ref[j] + m_plot2dZero;
|
||||||
|
if(gain2d>1.5) y2=spectra_.filter[j] + m_plot2dZero;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(i==iz-1) painter2D.drawPolyline(LineBuf,j);
|
if(i==iz-1) painter2D.drawPolyline(LineBuf,j);
|
||||||
|
@ -51,6 +51,8 @@ WideGraph::WideGraph(QSettings * settings, QWidget *parent) :
|
|||||||
m_bFlatten=m_settings->value("Flatten",true).toBool();
|
m_bFlatten=m_settings->value("Flatten",true).toBool();
|
||||||
ui->cbFlatten->setChecked(m_bFlatten);
|
ui->cbFlatten->setChecked(m_bFlatten);
|
||||||
ui->widePlot->setFlatten(m_bFlatten);
|
ui->widePlot->setFlatten(m_bFlatten);
|
||||||
|
m_bRef=m_settings->value("UseRef",false).toBool();
|
||||||
|
ui->cbRef->setChecked(m_bRef);
|
||||||
ui->widePlot->setBreadth(m_settings->value("PlotWidth",1000).toInt());
|
ui->widePlot->setBreadth(m_settings->value("PlotWidth",1000).toInt());
|
||||||
ui->bppSpinBox->setValue(n);
|
ui->bppSpinBox->setValue(n);
|
||||||
m_nsmo=m_settings->value("SmoothYellow",1).toInt();
|
m_nsmo=m_settings->value("SmoothYellow",1).toInt();
|
||||||
@ -130,6 +132,7 @@ void WideGraph::saveSettings() //saveS
|
|||||||
m_settings->setValue ("UserPalette", QVariant::fromValue (m_userPalette.colours ()));
|
m_settings->setValue ("UserPalette", QVariant::fromValue (m_userPalette.colours ()));
|
||||||
m_settings->setValue ("Fmin", m_fMin);
|
m_settings->setValue ("Fmin", m_fMin);
|
||||||
m_settings->setValue("Flatten",m_bFlatten);
|
m_settings->setValue("Flatten",m_bFlatten);
|
||||||
|
m_settings->setValue("UseRef",m_bRef);
|
||||||
m_settings->endGroup ();
|
m_settings->endGroup ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -377,9 +380,22 @@ void WideGraph::on_paletteComboBox_activated (QString const& palette) //palet
|
|||||||
void WideGraph::on_cbFlatten_toggled(bool b) //Flatten On/Off
|
void WideGraph::on_cbFlatten_toggled(bool b) //Flatten On/Off
|
||||||
{
|
{
|
||||||
m_bFlatten=b;
|
m_bFlatten=b;
|
||||||
|
if(m_bRef and m_bFlatten) {
|
||||||
|
m_bRef=false;
|
||||||
|
ui->cbRef->setChecked(false);
|
||||||
|
}
|
||||||
ui->widePlot->setFlatten(m_bFlatten);
|
ui->widePlot->setFlatten(m_bFlatten);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WideGraph::on_cbRef_toggled(bool b)
|
||||||
|
{
|
||||||
|
m_bRef=b;
|
||||||
|
if(m_bRef and m_bFlatten) {
|
||||||
|
m_bFlatten=false;
|
||||||
|
ui->cbFlatten->setChecked(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void WideGraph::on_adjust_palette_push_button_clicked (bool) //Adjust Palette
|
void WideGraph::on_adjust_palette_push_button_clicked (bool) //Adjust Palette
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -404,6 +420,11 @@ bool WideGraph::flatten() //Flatten
|
|||||||
return m_bFlatten;
|
return m_bFlatten;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool WideGraph::useRef() //Flatten
|
||||||
|
{
|
||||||
|
return m_bRef;
|
||||||
|
}
|
||||||
|
|
||||||
void WideGraph::on_gainSlider_valueChanged(int value) //Gain
|
void WideGraph::on_gainSlider_valueChanged(int value) //Gain
|
||||||
{
|
{
|
||||||
ui->widePlot->setPlotGain(value);
|
ui->widePlot->setPlotGain(value);
|
||||||
|
@ -40,6 +40,7 @@ public:
|
|||||||
void setModeTx(QString modeTx);
|
void setModeTx(QString modeTx);
|
||||||
void setLockTxFreq(bool b);
|
void setLockTxFreq(bool b);
|
||||||
bool flatten();
|
bool flatten();
|
||||||
|
bool useRef();
|
||||||
void setTol(int n);
|
void setTol(int n);
|
||||||
int smoothYellow();
|
int smoothYellow();
|
||||||
void setRxBand(QString band);
|
void setRxBand(QString band);
|
||||||
@ -68,6 +69,7 @@ private slots:
|
|||||||
void on_fStartSpinBox_valueChanged(int n);
|
void on_fStartSpinBox_valueChanged(int n);
|
||||||
void on_paletteComboBox_activated(const QString &palette);
|
void on_paletteComboBox_activated(const QString &palette);
|
||||||
void on_cbFlatten_toggled(bool b);
|
void on_cbFlatten_toggled(bool b);
|
||||||
|
void on_cbRef_toggled(bool b);
|
||||||
void on_adjust_palette_push_button_clicked (bool);
|
void on_adjust_palette_push_button_clicked (bool);
|
||||||
void on_gainSlider_valueChanged(int value);
|
void on_gainSlider_valueChanged(int value);
|
||||||
void on_zeroSlider_valueChanged(int value);
|
void on_zeroSlider_valueChanged(int value);
|
||||||
@ -99,6 +101,7 @@ private:
|
|||||||
|
|
||||||
bool m_lockTxFreq;
|
bool m_lockTxFreq;
|
||||||
bool m_bFlatten;
|
bool m_bFlatten;
|
||||||
|
bool m_bRef;
|
||||||
bool m_bHaveTransmitted; //Set true at end of a WSPR transmission
|
bool m_bHaveTransmitted; //Set true at end of a WSPR transmission
|
||||||
|
|
||||||
QString m_mode;
|
QString m_mode;
|
||||||
|
@ -562,14 +562,14 @@
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="cbFlatten">
|
<widget class="QCheckBox" name="cbFlatten">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Flat</string>
|
<string>Flatten</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="cbRef">
|
<widget class="QCheckBox" name="cbRef">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Ref</string>
|
<string>Ref Spec</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
Loading…
Reference in New Issue
Block a user