Many changes toward GUI support for JT65B2 and JT65C2 sub-modes.

git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/map65@2547 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
Joe Taylor 2012-08-31 15:51:58 +00:00
parent 025a4a3473
commit fce75f9d07
10 changed files with 129 additions and 75 deletions

View File

@ -6,9 +6,9 @@
extern qint16 id[4*60*96000];
void getfile(QString fname, bool xpol, int dbDgrd)
void getfile(QString fname, bool xpol, int dbDgrd, int nfast)
{
int npts=2*52*96000;
int npts=2*52*96000/nfast;
if(xpol) npts=2*npts;
// Degrade S/N by dbDgrd dB -- for tests only!!
@ -52,9 +52,9 @@ void getfile(QString fname, bool xpol, int dbDgrd)
}
}
void savetf2(QString fname, bool xpol)
void savetf2(QString fname, bool xpol, int nfast)
{
int npts=2*52*96000;
int npts=2*52*96000/nfast;
if(xpol) npts=2*npts;
qint16* buf=(qint16*)malloc(2*npts);

View File

@ -5,8 +5,8 @@
#include <QDebug>
#include "commons.h"
void getfile(QString fname, bool xpol, int dbDgrd);
void savetf2(QString fname, bool xpol);
void getfile(QString fname, bool xpol, int dbDgrd, int nfast);
void savetf2(QString fname, bool xpol, int nfast);
float gran();
#endif // GETFILE_H

View File

@ -53,6 +53,7 @@ program mapsim
if(mode(1:1).eq.'C') mode65=4
nfast=1
if(mode(2:2).eq.'2') nfast=2
npts=NMAX/nfast
open(12,file='msgs.txt',status='old')
write(*,1000)
@ -67,7 +68,7 @@ program mapsim
open(10,file=fname//'.iq',access='stream',status='unknown')
open(11,file=fname//'.tf2',access='stream',status='unknown')
call noisegen(d4,NMAX) !Generate Gaussuian noise
call noisegen(d4,npts) !Generate Gaussuian noise
if(msg0.ne.' ') then
call cgen65(message,mode65,nfast,samfac,nsendingsh,msgsent,cwave,nwave)
@ -113,7 +114,7 @@ program mapsim
enddo
enddo
do i=1,NMAX
do i=1,npts
id4(1,i)=nint(rms*d4(1,i))
id4(2,i)=nint(rms*d4(2,i))
id4(3,i)=nint(rms*d4(3,i))
@ -122,8 +123,8 @@ program mapsim
id2(2,i)=id4(2,i)
enddo
write(10) fcenter,id2
write(11) fcenter,id4
write(10) fcenter,id2(1:2,1:npts)
write(11) fcenter,id4(1:4,1:npts)
close(10)
close(11)
enddo

View File

@ -57,6 +57,8 @@ MainWindow::MainWindow(QWidget *parent) :
ui->actionJT65A->setActionGroup(modeGroup);
ui->actionJT65B->setActionGroup(modeGroup);
ui->actionJT65C->setActionGroup(modeGroup);
ui->actionJT65B2->setActionGroup(modeGroup);
ui->actionJT65C2->setActionGroup(modeGroup);
QActionGroup* saveGroup = new QActionGroup(this);
ui->actionSave_all->setActionGroup(saveGroup);
@ -199,6 +201,8 @@ MainWindow::MainWindow(QWidget *parent) :
if(m_mode=="JT65A") on_actionJT65A_triggered();
if(m_mode=="JT65B") on_actionJT65B_triggered();
if(m_mode=="JT65C") on_actionJT65C_triggered();
if(m_mode=="JT65B2") on_actionJT65B2_triggered();
if(m_mode=="JT65C2") on_actionJT65C2_triggered();
future1 = new QFuture<void>;
watcher1 = new QFutureWatcher<void>;
@ -461,7 +465,7 @@ void MainWindow::dataSink(int k)
static int n=0;
static int ihsym=0;
static int nzap=0;
static int n60z=0;
static int ntrz=0;
static int nkhz;
static int nfsample=96000;
static int nxpol=0;
@ -536,27 +540,34 @@ void MainWindow::dataSink(int k)
// Time according to this computer
qint64 ms = QDateTime::currentMSecsSinceEpoch() % 86400000;
int n60 = (ms/1000) % 60;
if((m_diskData && ihsym <= m_waterfallAvg) || (!m_diskData && n60<n60z)) {
int ntr = (ms/1000) % m_TRperiod;
if((m_diskData && ihsym <= m_waterfallAvg) || (!m_diskData && ntr<ntrz)) {
for (int i=0; i<NFFT; i++) {
splot[i] = 1.e30;
}
}
n60z=n60;
ntrz=ntr;
n=0;
}
if(ihsym == 279) {
if(ihsym == 279/m_nfast) {
datcom_.newdat=1;
datcom_.nagain=0;
QDateTime t = QDateTime::currentDateTimeUtc();
m_dateTime=t.toString("yyyy-MMM-dd hh:mm");
decode(); //Start the decoder
if(m_saveAll) {
if(m_saveAll and !m_diskData) {
QString fname=m_saveDir + "/" + t.date().toString("yyMMdd") + "_" +
t.time().toString("hhmm");
if(m_nfast==2) {
if(t.time().second() < 30) {
fname += "00";
} else {
fname += "30";
}
}
if(m_xpol) fname += ".tf2";
if(!m_xpol) fname += ".iq";
*future2 = QtConcurrent::run(savetf2, fname, m_xpol);
*future2 = QtConcurrent::run(savetf2, fname, m_xpol, m_nfast);
watcher2->setFuture(*future2);
}
}
@ -970,7 +981,7 @@ void MainWindow::on_actionOpen_triggered() //Open File
m_diskData=true;
int dbDgrd=0;
if(m_myCall=="K1JT" and m_idInt<0) dbDgrd=m_idInt;
*future1 = QtConcurrent::run(getfile, fname, m_xpol, dbDgrd);
*future1 = QtConcurrent::run(getfile, fname, m_xpol, dbDgrd, m_nfast);
watcher1->setFuture(*future1);
}
}
@ -1005,7 +1016,7 @@ void MainWindow::on_actionOpen_next_in_directory_triggered() //Open Next
m_diskData=true;
int dbDgrd=0;
if(m_myCall=="K1JT" and m_idInt<0) dbDgrd=m_idInt;
*future1 = QtConcurrent::run(getfile, fname, m_xpol, dbDgrd);
*future1 = QtConcurrent::run(getfile, fname, m_xpol, dbDgrd, m_nfast);
watcher1->setFuture(*future1);
return;
}
@ -1027,14 +1038,14 @@ void MainWindow::diskDat() //diskDat()
if(m_fs96000) hsym=2048.0*96000.0/11025.0; //Samples per JT65 half-symbol
if(!m_fs96000) hsym=2048.0*95238.1/11025.0;
for(int i=0; i<281; i++) { // Do the half-symbol FFTs
for(int i=0; i<282/m_nfast; i++) { // Do the half-symbol FFTs
int k = i*hsym + 2048.5;
dataSink(k);
if(i%10 == 0) qApp->processEvents(); //Keep the GUI responsive
if(i%10 == 0) qApp->processEvents(); //Keep the GUI responsive
}
}
void MainWindow::diskWriteFinished() //diskWriteFinished
void MainWindow::diskWriteFinished() //diskWriteFinished
{
// qDebug() << "diskWriteFinished";
}
@ -1133,8 +1144,11 @@ void MainWindow::on_actionAvailable_suffixes_and_add_on_prefixes_triggered()
void MainWindow::on_DecodeButton_clicked() //Decode request
{
int n=m_sec0%60;
if(m_monitoring and n>47 and (n<52 or m_decoderBusy)) return;
int n=m_sec0%m_TRperiod;
if(m_nfast==1) {
if(m_monitoring and n>47 and (n<52 or m_decoderBusy)) return;
} else {
if(m_monitoring and n>21 and (n<26 or m_decoderBusy)) return; }
if(!m_decoderBusy) {
datcom_.newdat=0;
datcom_.nagain=1;
@ -1343,8 +1357,8 @@ void MainWindow::guiUpdate()
double tx2=126.0*4096.0/11025.0 + 1.8; //### depend on TxDelay? ###
if(!m_txFirst) {
tx1 += 60.0;
tx2 += 60.0;
tx1 += m_TRperiod;
tx2 += m_TRperiod;
}
qint64 ms = QDateTime::currentMSecsSinceEpoch() % 86400000;
int nsec=ms/1000;
@ -1900,7 +1914,7 @@ void MainWindow::on_logQSOButton_clicked() //Log QSO button
QDateTime t = QDateTime::currentDateTimeUtc();
QString logEntry=t.date().toString("yyyy-MMM-dd,") +
t.time().toString("hh:mm,") + m_hisCall + "," + m_hisGrid + "," +
QString::number(nMHz) + ",JT65B\n";
QString::number(nMHz) + "," + m_mode;
QFile f("wsjt.log");
if(!f.open(QFile::Append)) {
msgBox("Cannot open file \"wsjt.log\".");
@ -1937,6 +1951,9 @@ void MainWindow::on_actionJT65A_triggered()
{
m_mode="JT65A";
m_mode65=1;
m_nfast=1;
m_TRperiod=60;
soundInThread.setPeriod(m_TRperiod);
g_pWideGraph->setMode65(m_mode65);
lab5->setText(m_mode);
ui->actionJT65A->setChecked(true);
@ -1946,6 +1963,9 @@ void MainWindow::on_actionJT65B_triggered()
{
m_mode="JT65B";
m_mode65=2;
m_nfast=1;
m_TRperiod=60;
soundInThread.setPeriod(m_TRperiod);
g_pWideGraph->setMode65(m_mode65);
lab5->setText(m_mode);
ui->actionJT65B->setChecked(true);
@ -1955,11 +1975,38 @@ void MainWindow::on_actionJT65C_triggered()
{
m_mode="JT65C";
m_mode65=4;
m_nfast=1;
m_TRperiod=60;
soundInThread.setPeriod(m_TRperiod);
g_pWideGraph->setMode65(m_mode65);
lab5->setText(m_mode);
ui->actionJT65C->setChecked(true);
}
void MainWindow::on_actionJT65B2_triggered()
{
m_mode="JT65B2";
m_mode65=2;
m_nfast=2;
m_TRperiod=30;
soundInThread.setPeriod(m_TRperiod);
g_pWideGraph->setMode65(m_mode65);
lab5->setText(m_mode);
ui->actionJT65B2->setChecked(true);
}
void MainWindow::on_actionJT65C2_triggered()
{
m_mode="JT65C2";
m_mode65=4;
m_nfast=2;
m_TRperiod=30;
soundInThread.setPeriod(m_TRperiod);
g_pWideGraph->setMode65(m_mode65);
lab5->setText(m_mode);
ui->actionJT65C2->setChecked(true);
}
void MainWindow::on_NBcheckBox_toggled(bool checked)
{
m_NB=checked;

View File

@ -5,6 +5,7 @@
#include <QTimer>
#include <QDateTime>
#include <QHash>
#include "getfile.h"
#include "soundin.h"
#include "soundout.h"
#include "commons.h"
@ -123,6 +124,10 @@ private slots:
void on_actionFUNcube_Dongle_triggered();
void on_actionJT65B2_triggered();
void on_actionJT65C2_triggered();
private:
Ui::MainWindow *ui;
qint32 m_nDevIn;
@ -157,6 +162,7 @@ private:
qint32 m_nfast;
qint32 m_nsum;
qint32 m_nsave;
qint32 m_TRperiod;
double m_fAdd;
double m_IQamp;

View File

@ -1225,6 +1225,8 @@ p, li { white-space: pre-wrap; }
<addaction name="actionJT65A"/>
<addaction name="actionJT65B"/>
<addaction name="actionJT65C"/>
<addaction name="actionJT65B2"/>
<addaction name="actionJT65C2"/>
</widget>
<addaction name="menuFile"/>
<addaction name="menuSetup"/>
@ -1568,6 +1570,22 @@ p, li { white-space: pre-wrap; }
<string>FUNcube Dongle Settings</string>
</property>
</action>
<action name="actionJT65B2">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>JT65B2</string>
</property>
</action>
<action name="actionJT65C2">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>JT65C2</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>

View File

@ -187,10 +187,10 @@ void SoundInThread::run() //SoundInThread::run()
// const PaStreamInfo* p=Pa_GetStreamInfo(inStream);
bool qe = quitExecution;
int n60z=99;
int ntrz=99;
int k=0;
int nsec;
int n60;
int ntr;
int nBusy=0;
int nhsym0=0;
@ -200,10 +200,10 @@ void SoundInThread::run() //SoundInThread::run()
if (qe) break;
qint64 ms = QDateTime::currentMSecsSinceEpoch() % 86400000;
nsec = ms/1000; // Time according to this computer
n60 = nsec % 60;
ntr = nsec % m_TRperiod;
// Reset buffer pointer and symbol number at start of minute
if(n60 < n60z or !m_monitoring) {
if(ntr < ntrz or !m_monitoring) {
nhsym0=0;
udata.bzero=true;
}
@ -228,7 +228,7 @@ void SoundInThread::run() //SoundInThread::run()
}
}
msleep(100);
n60z=n60;
ntrz=ntr;
}
Pa_StopStream(inStream);
Pa_CloseStream(inStream);
@ -314,6 +314,11 @@ int SoundInThread::mhsym()
return m_hsym;
}
void SoundInThread::setPeriod(int n)
{
m_TRperiod=n;
}
//--------------------------------------------------------------- inputUDP()
void SoundInThread::inputUDP()
{
@ -341,10 +346,10 @@ void SoundInThread::inputUDP()
double d8[174];
} b;
int n60z=99;
int ntrz=99;
int k=0;
int nsec;
int n60;
int ntr;
int nhsym0=0;
int iz=174;
int nBusy=0;
@ -361,14 +366,14 @@ void SoundInThread::inputUDP()
qint64 ms = QDateTime::currentMSecsSinceEpoch() % 86400000;
nsec = ms/1000; // Time according to this computer
n60 = nsec % 60;
ntr = nsec % m_TRperiod;
// Reset buffer pointer and symbol number at start of minute
if(n60 < n60z) {
if(ntr < ntrz) {
k=0;
nhsym0=0;
}
n60z=n60;
ntrz=ntr;
if(m_monitoring) {
m_nrx=b.nrx;

View File

@ -47,6 +47,7 @@ public:
void setNrx(int n);
void setForceCenterFreqBool(bool b);
void setForceCenterFreqMHz(double d);
void setPeriod(int n);
int nrx();
int mhsym();
@ -73,6 +74,7 @@ private:
qint32 m_hsym;
qint32 m_nDevIn;
qint32 m_udpPort;
qint32 m_TRperiod;
QUdpSocket *udpSocket;
};

View File

@ -15,7 +15,7 @@ extern double outputLatency;
typedef struct //Parameters sent to or received from callback function
{
int dummy;
int nTRperiod;
} paUserData;
//--------------------------------------------------------------- d2aCallback
@ -29,14 +29,11 @@ extern "C" int d2aCallback(const void *inputBuffer, void *outputBuffer,
short *wptr = (short*)outputBuffer;
unsigned int i,n;
static int ic=0;
// static int ic0=0;
// static int nsec0=-99;
static bool btxok0=false;
static int nminStart=0;
// static t0,t1;
double tsec,tstart;
int nsec;
int nTRperiod=udata->nTRperiod;
// Get System time
qint64 ms = QDateTime::currentMSecsSinceEpoch() % 86400000;
@ -44,46 +41,21 @@ extern "C" int d2aCallback(const void *inputBuffer, void *outputBuffer,
nsec = ms/1000;
if(btxok and !btxok0) { //Start (or re-start) a transmission
n=nsec/60;
tstart=tsec - n*60.0 - 1.0;
n=nsec/nTRperiod;
tstart=tsec - n*nTRperiod - 1.0;
if(tstart<1.0) {
ic=0; //Start of minute, set starting index to 0
// ic0=ic;
nminStart=n;
// t0=timeInfo->currentTime;
} else {
if(n != nminStart) { //Late start in new minute: compute starting index
ic=(int)(tstart*11025.0);
// ic0=ic;
// t0=timeInfo->currentTime;
// qDebug() << "B" << t0 << ic0;
nminStart=n;
}
}
/*
qDebug() << "A" << n << ic
<< QString::number( tsec, 'f', 3 )
<< QString::number( tstart, 'f', 3 )
<< QString::number( timeInfo->currentTime, 'f', 3 )
<< QString::number( timeInfo->outputBufferDacTime, 'f', 3 )
<< QString::number( timeInfo->outputBufferDacTime -
timeInfo->currentTime, 'f', 3 )
<< QString::number( timeInfo->currentTime - tsec, 'f', 3 );
*/
}
btxok0=btxok;
/*
if(nsec!=nsec0) {
double txt=timeInfo->currentTime - t0;
double r=0.0;
if(txt>0.0) r=(ic-ic0)/txt;
qDebug() << "C" << txt << ic-ic0 << r;
nsec0=nsec;
}
*/
if(btxok) {
for(i=0 ; i<framesToProcess; i++ ) {
short int i2=iwave[ic];
@ -122,6 +94,8 @@ void SoundOutThread::run()
outParam.suggestedLatency=0.05;
outParam.hostApiSpecificStreamInfo=NULL;
udata.nTRperiod=m_TRperiod;
paerr=Pa_IsFormatSupported(NULL,&outParam,11025.0);
if(paerr<0) {
qDebug() << "PortAudio says requested output format not supported.";
@ -129,9 +103,6 @@ void SoundOutThread::run()
return;
}
// udata.nwave=m_nwave;
// udata.btxok=false;
paerr=Pa_OpenStream(&outStream, //Output stream
NULL, //No input parameters
&outParam, //Output parameters
@ -154,9 +125,6 @@ void SoundOutThread::run()
while (!qe) {
qe = quitExecution;
if (qe) break;
// udata.nwave=m_nwave;
// if(m_txOK) udata.btxok=1;
// if(!m_txOK) udata.btxok=0;
msleep(100);
}
Pa_StopStream(outStream);
@ -168,3 +136,8 @@ void SoundOutThread::setOutputDevice(int n) //setOutputDevice()
if (isRunning()) return;
this->m_nDevOut=n;
}
void SoundOutThread::setPeriod(int n)
{
m_TRperiod=n;
}

View File

@ -27,6 +27,7 @@ public:
public:
void setOutputDevice(qint32 n);
void setPeriod(int n);
bool quitExecution; //If true, thread exits gracefully
@ -35,6 +36,7 @@ private:
double m_rate; //Sample rate
qint32 m_nDevOut; //Output device number
qint32 m_nwave; //Length of wave file
qint32 m_TRperiod; //T/R period (30 or 60 s)
bool m_txOK; //Enable Tx audio
bool m_txMute; //Mute temporarily
};