diff --git a/commons.h b/commons.h index a0a261a9e..52bc6086c 100644 --- a/commons.h +++ b/commons.h @@ -7,8 +7,8 @@ extern "C" { extern struct { short int d2[1800*12000]; //This is "common/jt8com/..." in fortran - float ss[184*32768]; - float savg[32768]; + float ss[184*4400]; + float savg[4400]; double fcenter; //USB dial freq (kHz) int nutc; //UTC as integer, HHMM int ntrperiod; //TR period (seconds) diff --git a/libm65/symspecx.f90 b/libm65/symspecx.f90 index f1d800e8e..22d96f08a 100644 --- a/libm65/symspecx.f90 +++ b/libm65/symspecx.f90 @@ -1,51 +1,37 @@ -subroutine symspecx(k,ndiskdat,nb,nbslider,ntrperiod,pxdb,sdis,nkhz, & - ihsym,nzap,slimit,lstrong) +subroutine symspecx(k,nsps,ndiskdat,nb,nbslider,pxdb,s,nkhz,ihsym, & + nzap,slimit,lstrong) ! k pointer to the most recent new data +! nsps samples per symbol (at 12000 Hz) ! ndiskdat 0/1 to indicate if data from disk ! nb 0/1 status of noise blanker (off/on) ! pxdb power (0-60 dB) -! sdis spectrum for waterfall display +! s spectrum for waterfall display ! nkhz integer kHz portion of center frequency, e.g., 125 for 144.125 ! ihsym index number of this half-symbol (1-322) ! nzap number of samples zero'ed by noise blanker - parameter (NSMAX=1800*12000) !Total sample intervals per 30 minutes - parameter (MAXFFT=32768) !Max length of FFTs - parameter (NDMAX=1800*375) + parameter (NMAX=1800*12000) !Total sample intervals per 30 minutes + parameter (NSMAX=4400) !Max length of saved spectra + parameter (MAXFFT=262144) !Max length of FFTs integer*2 id2 real*8 ts,hsym real*8 fcenter - common/jt8com/id2(NSMAX),ss(184,MAXFFT),savg(MAXFFT),fcenter,nutc,junk(20), & - cdat(NDMAX) - real*4 sdis(MAXFFT),w(MAXFFT) - complex cx(MAXFFT) - complex cx00(MAXFFT) - real x0(0:2047) - complex cx0(0:1023),cx1(0:1023) - logical*1 lstrong(0:1023) - equivalence (x0,cx0) + common/jt8com/id2(NMAX),ss(184,NSMAX),savg(NSMAX),fcenter,nutc,junk(20) + real*4 s(NSMAX) + real x(MAXFFT) + complex cx(0:MAXFFT/2) + equivalence (x,cx) data rms/999.0/,k0/99999999/,ntrperiod0/0/ save - if(k.gt.NSMAX) go to 999 + nfft=nsps + hsym=nsps/2 + if(k.gt.NMAX) go to 999 if(k.lt.nfft) then ihsym=0 go to 999 !Wait for enough samples to start endif - if(ntrperiod.ne.ntrperiod0) then - nfft=960 - if(ntrperiod.eq.120) nfft=2048 - if(ntrperiod.eq.300) nfft=5376 - if(ntrperiod.eq.600) nfft=10752 - if(ntrperiod.eq.1800) nfft=32768 - nsps=8*nfft - hsym=0.5d0*nsps - pi=4.0*atan(1.0) - do i=1,nfft - w(i)=(sin(i*pi/nfft))**2 !Window - enddo - endif if(k.lt.k0) then ts=1.d0 - hsym @@ -60,61 +46,42 @@ subroutine symspecx(k,ndiskdat,nb,nbslider,ntrperiod,pxdb,sdis,nkhz, & sigmas=1.5*(10.0**(0.01*nbslider)) + 0.7 peaklimit=sigmas*max(10.0,rms) faclim=3.0 - px=0. - nwindow=2 - nfft2=1024 - kstep=nfft2 - if(nwindow.ne.0) kstep=nfft2/2 - nblks=(k-k1)/kstep - do nblk=1,nblks - j=k1+1 - do i=0,nfft2-1 - x0(i)=id2(j+i) - enddo - call timf2x(k,nfft2,ntrperiod,nwindow,nb,peaklimit,faclim,cx0,cx1, & - slimit,lstrong,px,nzap) - do i=0,kstep-1 - cdat(j+i)=cx1(i) - enddo - k1=k1+kstep - enddo - - npts=nfft !Samples used in each half-symbol FFT ts=ts+hsym ja=ts !Index of first sample - jb=ja+npts-1 !Last sample + jb=ja+nfft-1 !Last sample i=0 - fac=0.0002 + sq=0. do j=ja,jb !Copy data into cx, cy i=i+1 - cx(i)=fac*cdat(j) + x(i)=id2(j) + sq=sq + x(i)*x(i) enddo - - if(nzap/178.lt.50 .and. (ndiskdat.eq.0 .or. ihsym.lt.280)) then - nsum=nblks*kstep - nzap - if(nsum.le.0) nsum=1 - rms=sqrt(0.5*px/nsum) - endif + rms=sqrt(sq/nfft) pxdb=0. if(rms.gt.1.0) pxdb=20.0*log10(rms) if(pxdb.gt.60.0) pxdb=60.0 - cx00=cx ihsym=ihsym+1 - cx=w*cx00 !Apply window for 2nd forward FFT - call four2a(cx,nfft,1,1,1) !Second forward FFT (X) - n=min(184,ihsym) - do i=1,nfft - sx=real(cx(i))**2 + aimag(cx(i))**2 - ss(n,i)=sx - sdis(i)=sx + call four2a(x,nfft,1,-1,0) !Forward FFT of symbol length + df=12000.0/nfft + nzh=min(nint(500.0/df),2200) + nz=2*nzh + i0=nint(1500.0/df) - nzh +! rewind 71 + do i=1,nz + sx=real(cx(i0+i))**2 + aimag(cx(i0+i))**2 + sx=1.e-5*sx + s(i)=sx savg(i)=savg(i) + sx + if(ihsym.le.184) ss(ihsym,i)=sx +! write(71,3001) (i-1)*df,savg(i) +!3001 format(f12.6,e12.3) enddo +! flush(71) - nkhz=nint(1000.d0*(fcenter-int(fcenter))) - if(fcenter.eq.0.d0) nkhz=125 + nkhz=100 999 return end subroutine symspecx diff --git a/mainwindow.cpp b/mainwindow.cpp index fc0b44804..c6cae25d9 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -148,7 +148,6 @@ MainWindow::MainWindow(QWidget *parent) : // Assign input device and start input thread soundInThread.setInputDevice(m_paInDevice); soundInThread.start(QThread::HighestPriority); - // Assign output device and start output thread soundOutThread.setOutputDevice(m_paOutDevice); // soundOutThread.start(QThread::HighPriority); @@ -333,13 +332,10 @@ void MainWindow::dataSink(int k) static int nzap=0; static int ntr0=0; static int nkhz; - static int nfsample=96000; - static int nxpol=0; - static float fgreen; static int ndiskdat; - static int nb; static int nadj=0; - static float px=0.0,py=0.0; + static int nb; + static float px=0.0; static uchar lstrong[1024]; static float slimit; @@ -354,16 +350,16 @@ void MainWindow::dataSink(int k) // Get power, spectrum, nkhz, and ihsym nb=0; if(m_NB) nb=1; - symspecx_(&k, &ndiskdat, &nb, &m_NBslider, &m_TRperiod, - &px, s, &nkhz, &ihsym, &nzap, &slimit, lstrong); -// qDebug() << "A" << k << k/12000 << m_TRperiod << ihsym << px; + symspecx_(&k, & m_nsps, &ndiskdat, &nb, &m_NBslider, &px, s, + &nkhz, &ihsym, &nzap, &slimit, lstrong); + if(ihsym <=0) return; QString t; m_pctZap=nzap/178.3; t.sprintf(" Rx noise: %5.1f %5.1f %% ",px,m_pctZap); lab4->setText(t); ui->xThermo->setValue((double)px); //Update the thermometer if(m_monitoring || m_diskData) { -// g_pWideGraph->dataSink2(s,nkhz,ihsym,m_diskData,lstrong); + g_pWideGraph->dataSink2(s,nkhz,ihsym,m_diskData,lstrong); } if(nadj == 10) { @@ -1021,24 +1017,7 @@ void MainWindow::guiUpdate() lab1->setText(s); } else if(m_monitoring) { lab1->setStyleSheet("QLabel{background-color: #00ff00}"); - khsym=soundInThread.mstep(); - QString t; - if(m_network) { - if(m_nrx==-1) t="F1"; - if(m_nrx==1) t="I1"; - if(m_nrx==-2) t="F2"; - if(m_nrx==+2) t="I2"; - } else { - if(m_nrx==1) t="S1"; - if(m_nrx==2) t="S2"; - } - if((abs(m_nrx)==1 and m_xpol) or (abs(m_nrx)==2 and !m_xpol)) - lab1->setStyleSheet("QLabel{background-color: #ff1493}"); - if(khsym==m_hsym0) { - t="Nil"; - lab1->setStyleSheet("QLabel{background-color: #ffc0cb}"); - } - lab1->setText("Receiving " + t); + lab1->setText("Receiving "); } else if (!m_diskData) { lab1->setStyleSheet(""); lab1->setText(""); @@ -1048,7 +1027,7 @@ void MainWindow::guiUpdate() m_setftx=0; QString utc = " " + t.time().toString() + " "; ui->labUTC->setText(utc); - if((!m_monitoring and !m_diskData) or (khsym==m_hsym0)) { + if(!m_monitoring and !m_diskData) { ui->xThermo->setValue(0.0); // Set Rx level to 20 lab2->setText(" Rx noise: 0.0 "); } @@ -1126,7 +1105,7 @@ void MainWindow::on_txb6_clicked() //txb6 m_restart=true; } -void MainWindow::selectCall2(bool ctrl) //selectCall2 +void MainWindow::selectCall2(bool ctrl) //selectCall2 { QString t = ui->decodedTextBrowser->toPlainText(); //Full contents int i=ui->decodedTextBrowser->textCursor().position(); @@ -1453,9 +1432,10 @@ void MainWindow::on_actionJT8_1_triggered() { m_mode="JT8-1"; m_TRperiod=60; - soundInThread.setPeriod(m_TRperiod); - soundOutThread.setPeriod(m_TRperiod); - g_pWideGraph->setPeriod(m_TRperiod); + m_nsps=7168; + soundInThread.setPeriod(m_TRperiod,m_nsps); + soundOutThread.setPeriod(m_TRperiod,m_nsps); + g_pWideGraph->setPeriod(m_TRperiod,m_nsps); lab5->setStyleSheet("QLabel{background-color: #ff6ec7}"); lab5->setText(m_mode); ui->actionJT8_1->setChecked(true); @@ -1465,9 +1445,10 @@ void MainWindow::on_actionJT8_2_triggered() { m_mode="JT8-2"; m_TRperiod=120; - soundInThread.setPeriod(m_TRperiod); - soundOutThread.setPeriod(m_TRperiod); - g_pWideGraph->setPeriod(m_TRperiod); + m_nsps=16000; + soundInThread.setPeriod(m_TRperiod,m_nsps); + soundOutThread.setPeriod(m_TRperiod,m_nsps); + g_pWideGraph->setPeriod(m_TRperiod,m_nsps); lab5->setStyleSheet("QLabel{background-color: #ffff00}"); lab5->setText(m_mode); ui->actionJT8_2->setChecked(true); @@ -1477,9 +1458,10 @@ void MainWindow::on_actionJT8_5_triggered() { m_mode="JT8-5"; m_TRperiod=300; - soundInThread.setPeriod(m_TRperiod); - soundOutThread.setPeriod(m_TRperiod); - g_pWideGraph->setPeriod(m_TRperiod); + m_nsps=42336; + soundInThread.setPeriod(m_TRperiod,m_nsps); + soundOutThread.setPeriod(m_TRperiod,m_nsps); + g_pWideGraph->setPeriod(m_TRperiod,m_nsps); lab5->setStyleSheet("QLabel{background-color: #ffa500}"); lab5->setText(m_mode); ui->actionJT8_5->setChecked(true); @@ -1489,9 +1471,10 @@ void MainWindow::on_actionJT8_10_triggered() { m_mode="JT8-10"; m_TRperiod=600; - soundInThread.setPeriod(m_TRperiod); - soundOutThread.setPeriod(m_TRperiod); - g_pWideGraph->setPeriod(m_TRperiod); + m_nsps=86400; + soundInThread.setPeriod(m_TRperiod,m_nsps); + soundOutThread.setPeriod(m_TRperiod,m_nsps); + g_pWideGraph->setPeriod(m_TRperiod,m_nsps); lab5->setStyleSheet("QLabel{background-color: #7fff00}"); lab5->setText(m_mode); ui->actionJT8_10->setChecked(true); @@ -1501,9 +1484,10 @@ void MainWindow::on_actionJT8_30_triggered() { m_mode="JT8-30"; m_TRperiod=1800; - soundInThread.setPeriod(m_TRperiod); - soundOutThread.setPeriod(m_TRperiod); - g_pWideGraph->setPeriod(m_TRperiod); + m_nsps=262144; + soundInThread.setPeriod(m_TRperiod,m_nsps); + soundOutThread.setPeriod(m_TRperiod,m_nsps); + g_pWideGraph->setPeriod(m_TRperiod,m_nsps); lab5->setStyleSheet("QLabel{background-color: #97ffff}"); lab5->setText(m_mode); ui->actionJT8_30->setChecked(true); diff --git a/mainwindow.h b/mainwindow.h index 1c2b172fe..e49a60937 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -148,6 +148,7 @@ private: qint32 m_applyIQcal; qint32 m_mult570; qint32 m_TRperiod; + qint32 m_nsps; double m_fAdd; double m_IQamp; @@ -247,9 +248,9 @@ extern void getDev(int* numDevices,char hostAPI_DeviceName[][50], extern "C" { //----------------------------------------------------- C and Fortran routines -void symspecx_(int* k, int* ndiskdat, int* nb, int* m_NBslider, - int* ntrperiod, float* px, float s[], int* nkhz, - int* nhsym, int* nzap, float* slimit, uchar lstrong[]); +void symspecx_(int* k, int* nsps, int* ndiskdat, int* nb, int* m_NBslider, + float* px, float s[], int* nkhz, int* nhsym, int* nzap, + float* slimit, uchar lstrong[]); void genjt8_(char* msg, char* msgsent, short itone[], int* nsym, int len1, int len2); int ptt_(int* nport, int* itx, int* iptt); diff --git a/soundin.cpp b/soundin.cpp index dd2bbaffb..3544b0400 100644 --- a/soundin.cpp +++ b/soundin.cpp @@ -7,8 +7,8 @@ extern "C" { #include extern struct { short int d2[1800*12000]; //This is "common/jt8com/..." in fortran - float ss[184*32768]; - float savg[32768]; + float ss[184*4400]; + float savg[4400]; double fcenter; //USB dial freq (kHz) int nutc; //UTC as integer, HHMM int ntrperiod; //TR period (seconds) @@ -114,7 +114,7 @@ void SoundInThread::run() //SoundInThread::run() } bool qe = quitExecution; - int ntr0=99; + static int ntr0=99; int k=0; int nsec; int ntr; @@ -136,7 +136,8 @@ void SoundInThread::run() //SoundInThread::run() } k=udata.kin; if(m_monitoring) { - m_step=k/2048; + int kstep=m_nsps/2; + m_step=k/kstep; if(m_step != nstep0) { if(m_dataSinkBusy) { nBusy++; @@ -147,7 +148,7 @@ void SoundInThread::run() //SoundInThread::run() nstep0=m_step; } } - msleep(10); + msleep(100); ntr0=ntr; } Pa_StopStream(inStream); @@ -170,9 +171,10 @@ void SoundInThread::setMonitoring(bool b) //setMonitoring() m_monitoring = b; } -void SoundInThread::setPeriod(int n) +void SoundInThread::setPeriod(int ntrperiod, int nsps) { - m_TRperiod=n; + m_TRperiod=ntrperiod; + m_nsps=nsps; } int SoundInThread::mstep() diff --git a/soundin.h b/soundin.h index a2e06e4b3..3daa71ea2 100644 --- a/soundin.h +++ b/soundin.h @@ -26,7 +26,7 @@ public: void setInputDevice(qint32 n); void setMonitoring(bool b); - void setPeriod(int n); + void setPeriod(int ntrperiod, int nsps); int mstep(); signals: @@ -44,6 +44,7 @@ private: qint32 m_nDevIn; qint32 m_TRperiod; qint32 m_TRperiod0; + qint32 m_nsps; }; diff --git a/soundout.cpp b/soundout.cpp index 1e48136cb..480ee1f1a 100644 --- a/soundout.cpp +++ b/soundout.cpp @@ -104,7 +104,8 @@ void SoundOutThread::setOutputDevice(int n) //setOutputDevice() this->m_nDevOut=n; } -void SoundOutThread::setPeriod(int n) +void SoundOutThread::setPeriod(int ntrperiod, int nsps) { - m_TRperiod=n; + m_TRperiod=ntrperiod; + m_nsps=nsps; } diff --git a/soundout.h b/soundout.h index b74f98938..9c5013406 100644 --- a/soundout.h +++ b/soundout.h @@ -25,17 +25,16 @@ public: public: void setOutputDevice(qint32 n); - void setPeriod(int n); + void setPeriod(int ntrperiod, int nsps); bool quitExecution; //If true, thread exits gracefully - // Private members private: qint32 m_nDevOut; //Output device number bool m_txOK; //Enable Tx audio bool m_txMute; //Mute temporarily qint32 m_TRperiod; //T/R period (30 or 60 s) - + qint32 m_nsps; //Samples per symbol (at 12000 Hz) }; #endif diff --git a/widegraph.cpp b/widegraph.cpp index b39be7470..c2812dc35 100644 --- a/widegraph.cpp +++ b/widegraph.cpp @@ -1,7 +1,7 @@ #include "widegraph.h" #include "ui_widegraph.h" -#define NFFT 32768 +#define NSMAX 4400 WideGraph::WideGraph(QWidget *parent) : QDialog(parent), @@ -71,7 +71,7 @@ void WideGraph::saveSettings() void WideGraph::dataSink2(float s[], int nkhz, int ihsym, int ndiskdata, uchar lstrong[]) { - static float splot[NFFT]; + static float splot[NSMAX]; float swide[2048]; float smax; double df; @@ -80,7 +80,7 @@ void WideGraph::dataSink2(float s[], int nkhz, int ihsym, int ndiskdata, static int nkhz0=-999; static int ntrz=0; - df = m_fSample/32768.0; + df = 12000.0/m_nsps; if(nkhz != nkhz0) { ui->widePlot->setNkhz(nkhz); //Why do we need both? ui->widePlot->SetCenterFreq(nkhz); //Why do we need both? @@ -90,16 +90,16 @@ void WideGraph::dataSink2(float s[], int nkhz, int ihsym, int ndiskdata, //Average spectra over specified number, m_waterfallAvg if (n==0) { - for (int i=0; i=m_waterfallAvg) { - for (int i=0; iwidePlot->startFreq()) ui->widePlot->SetStartFreq(sf); int i0=16384.0+(ui->widePlot->startFreq()-nkhz+1.27046+0.001*m_fCal) * 1000.0/df + 0.5; + i0=0; //### + nbpp=1; //### int i=i0; for (int j=0; j<2048; j++) { smax=0; @@ -119,6 +121,7 @@ void WideGraph::dataSink2(float s[], int nkhz, int ihsym, int ndiskdata, if(lstrong[1 + i/32]!=0) swide[j]=-smax; //Tag strong signals } +// qDebug() << "B" << ihsym << smax << s[100]; // Time according to this computer qint64 ms = QDateTime::currentMSecsSinceEpoch() % 86400000; int ntr = (ms/1000) % m_TRperiod; @@ -279,7 +282,8 @@ double WideGraph::fGreen() return ui->widePlot->fGreen(); } -void WideGraph::setPeriod(int n) +void WideGraph::setPeriod(int ntrperiod, int nsps) { - m_TRperiod=n; + m_TRperiod=ntrperiod; + m_nsps=nsps; } diff --git a/widegraph.h b/widegraph.h index 116cf8fe5..b619c157c 100644 --- a/widegraph.h +++ b/widegraph.h @@ -31,7 +31,7 @@ public: void setPalette(QString palette); void setFsample(int n); void setMode65(int n); - void setPeriod(int n); + void setPeriod(int ntrperiod, int nsps); double fGreen(); qint32 m_qsoFreq; @@ -64,6 +64,7 @@ private: qint32 m_fSample; qint32 m_mode65; qint32 m_TRperiod; + qint32 m_nsps; Ui::WideGraph *ui; };