Continuing to work on SoundIn, SoundOut...

git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/jtms3@2483 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
Joe Taylor 2012-07-04 16:27:57 +00:00
parent 0a3c96fab0
commit 2075b69fb3
8 changed files with 81 additions and 238 deletions

View File

@ -6,7 +6,10 @@
extern "C" {
extern struct { //This is "common/datcom/..." in Fortran
float d4[4*5760000]; //Raw I/Q data from Linrad
float d4[30*48000]; //Raw data
int kin;
int ndiskdat;
/*
float ss[4*322*NFFT]; //Half-symbol spectra at 0,45,90,135 deg pol
float savg[4*NFFT]; //Avg spectra at 0,45,90,135 deg pol
double fcenter; //Center freq from Linrad (MHz)
@ -36,6 +39,7 @@ extern struct { //This is "common/datcom/..." in Fortran
char hiscall[12];
char hisgrid[6];
char datetime[20];
*/
} datcom_;
}

View File

@ -22,7 +22,7 @@ void getfile(QString fname, bool xpol, int dbDgrd)
FILE* fp=fopen(name,"rb");
if(fp != NULL) {
fread(&datcom_.fcenter,sizeof(datcom_.fcenter),1,fp);
// fread(&datcom_.fcenter,sizeof(datcom_.fcenter),1,fp);
fread(id,2,npts,fp);
int j=0;
@ -41,6 +41,7 @@ void getfile(QString fname, bool xpol, int dbDgrd)
}
fclose(fp);
/*
datcom_.ndiskdat=1;
int nfreq=(int)datcom_.fcenter;
if(nfreq!=144 and nfreq != 432 and nfreq != 1296) datcom_.fcenter=144.125;
@ -49,11 +50,13 @@ void getfile(QString fname, bool xpol, int dbDgrd)
datcom_.nutc=0;
if(i0>0) datcom_.nutc=100*fname.mid(i0-4,2).toInt() +
fname.mid(i0-2,2).toInt();
*/
}
}
void savetf2(QString fname, bool xpol)
{
/*
int npts=2*52*96000;
if(xpol) npts=2*npts;
@ -74,6 +77,7 @@ void savetf2(QString fname, bool xpol)
fclose(fp);
}
free(buf);
*/
}
//#define MAX_RANDOM 0x7fffffff

View File

@ -141,7 +141,7 @@ MainWindow::MainWindow(QWidget *parent) :
QString::number(iret));
}
#endif
/*
if(!mem_m65.attach()) {
if (!mem_m65.create(sizeof(datcom_))) {
msgBox("Unable to create shared memory segment.");
@ -155,7 +155,7 @@ MainWindow::MainWindow(QWidget *parent) :
size -= noffset;
}
memset(to,0,size); //Zero all decoding params in shared memory
*/
PaError paerr=Pa_Initialize(); //Initialize Portaudio
if(paerr!=paNoError) {
msgBox("Unable to initialize PortAudio.");
@ -424,7 +424,6 @@ void MainWindow::dataSink(int k)
static float rejecty;
static float slimit;
if(m_diskData) {
ndiskdat=1;
datcom_.ndiskdat=1;
@ -432,41 +431,26 @@ void MainWindow::dataSink(int k)
ndiskdat=0;
datcom_.ndiskdat=0;
}
// Get x and y power, polarized spectrum, nkhz, and ihsym
nb=0;
if(m_NB) nb=1;
nfsample=96000;
if(!m_fs96000) nfsample=95238;
nxpol=0;
if(m_xpol) nxpol=1;
fgreen=(float)g_pWideGraph->fGreen();
nadj++;
if(m_adjustIQ==0) nadj=0;
symspec_(&k, &nxpol, &ndiskdat, &nb, &m_NBslider, &m_dPhi, &nfsample,
&fgreen, &m_adjustIQ, &m_applyIQcal, &m_gainx, &m_gainy, &m_phasex,
&m_phasey, &rejectx, &rejecty, &px, &py, s, &nkhz,
&ihsym, &nzap, &slimit, lstrong);
double sq=0.0;
float x;
for(int i=0; i<6192; i++) {
x=datcom_.d4[k-6192+i];
sq += x*x;
}
px = 10.0*log10(sq/6192.0) + 70.0; // Why +70 ???
if(px>60.0) px=60.0;
if(px<0.0) px=0.0;
QString t;
m_pctZap=nzap/178.3;
if(m_xpol) t.sprintf(" Rx noise: %5.1f %5.1f %5.1f %% ",px,py,m_pctZap);
if(!m_xpol) t.sprintf(" Rx noise: %5.1f %5.1f %% ",px,m_pctZap);
t.sprintf(" Rx noise: %5.1f ",px);
lab4->setText(t);
ui->xThermo->setValue((double)px); //Update the bargraphs
/*
if(m_monitoring || m_diskData) {
g_pWideGraph->dataSink2(s,nkhz,ihsym,m_diskData,lstrong);
}
if(nadj == 10) {
if(m_xpol) {
t.sprintf("Amp: %6.4f %6.4f Phase: %6.4f %6.4f",
m_gainx,m_gainy,m_phasex,m_phasey);
} else {
t.sprintf("Amp: %6.4f Phase: %6.4f",m_gainx,m_phasex);
}
ui->decodedTextBrowser->append(t);
m_adjustIQ=0;
}
//Average over specified number of spectra
if (n==0) {
for (int i=0; i<NFFT; i++)
@ -493,6 +477,7 @@ void MainWindow::dataSink(int k)
n60z=n60;
n=0;
}
if(ihsym == 279) {
datcom_.newdat=1;
datcom_.nagain=0;
@ -508,6 +493,7 @@ void MainWindow::dataSink(int k)
watcher2->setFuture(*future2);
}
}
*/
soundInThread.m_dataSinkBusy=false;
}
@ -870,7 +856,7 @@ void MainWindow::diskDat() //diskDat()
double hsym;
//These may be redundant??
m_diskData=true;
datcom_.newdat=1;
// datcom_.newdat=1;
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;
@ -973,6 +959,7 @@ 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;
if(!m_decoderBusy) {
@ -980,10 +967,12 @@ void MainWindow::on_DecodeButton_clicked() //Decode request
datcom_.nagain=1;
decode();
}
*/
}
void MainWindow::freezeDecode(int n) //freezeDecode()
{
/*
if(n==2) {
ui->tolSpinBox->setValue(5);
datcom_.ntol=m_tol;
@ -997,10 +986,12 @@ void MainWindow::freezeDecode(int n) //freezeDecode()
datcom_.newdat=0;
decode();
}
*/
}
void MainWindow::decode() //decode()
{
/*
ui->DecodeButton->setStyleSheet(m_pbdecoding_style1);
if(datcom_.nagain==0 && (!m_diskData)) {
qint64 ms = QDateTime::currentMSecsSinceEpoch() % 86400000;
@ -1077,6 +1068,7 @@ void MainWindow::decode() //decode()
lockFile.remove();
decodeBusy(true);
*/
}
void MainWindow::m65_error() //m65_error
@ -1287,12 +1279,6 @@ void MainWindow::guiUpdate()
if(nsec != m_sec0) { //Once per second
if(m_pctZap>30.0 and !m_transmitting) {
lab4->setStyleSheet("QLabel{background-color: #ff0000}");
} else {
lab4->setStyleSheet("");
}
if(m_transmitting) {
if(nsendingsh==1) {
lab1->setStyleSheet("QLabel{background-color: #66ffff}");
@ -1306,7 +1292,7 @@ void MainWindow::guiUpdate()
lab1->setText(s);
} else if(m_monitoring) {
lab1->setStyleSheet("QLabel{background-color: #00ff00}");
khsym=soundInThread.mhsym();
khsym=soundInThread.mstep();
QString t;
if(m_network) {
if(m_nrx==-1) t="F1";
@ -1330,13 +1316,12 @@ void MainWindow::guiUpdate()
}
QDateTime t = QDateTime::currentDateTimeUtc();
int fQSO=g_pWideGraph->QSOfreq();
m_setftx=0;
QString utc = " " + t.time().toString() + " ";
ui->labUTC->setText(utc);
if((!m_monitoring and !m_diskData) or (khsym==m_hsym0)) {
ui->xThermo->setValue(0.0); // Set Rx level to 20
lab4->setText(" Rx noise: 0.0 0.0% ");
lab4->setText(" Rx noise: 0.0 ");
}
m_hsym0=khsym;
m_sec0=nsec;
@ -1701,7 +1686,7 @@ void MainWindow::on_genStdMsgsPushButton_clicked() //genStdMsgs button
void MainWindow::on_logQSOButton_clicked() //Log QSO button
{
int nMHz=int(datcom_.fcenter);
int nMHz=144;
QDateTime t = QDateTime::currentDateTimeUtc();
QString logEntry=t.date().toString("yyyy-MMM-dd,") +
t.time().toString("hh:mm,") + m_hisCall + "," + m_hisGrid + "," +

View File

@ -219,6 +219,7 @@ void CPlotter::draw(float s[], int i0, float splot[]) //dr
void CPlotter::UTCstr()
{
/*
int ihr,imin;
if(datcom_.ndiskdat != 0) {
ihr=datcom_.nutc/100;
@ -230,6 +231,7 @@ void CPlotter::UTCstr()
imin=imin % 60;
}
sprintf(m_sutc,"%2.2d:%2.2d",ihr,imin);
*/
}
void CPlotter::DrawOverlay() //DrawOverlay()

View File

@ -7,46 +7,15 @@
extern "C" {
#include <portaudio.h>
extern struct {
double d8[2*60*96000]; //This is "common/datcom/..." in fortran
float ss[4*322*NFFT];
float savg[4*NFFT];
double fcenter;
int nutc;
int idphi; //Phase correction for Y pol'n, degrees
int mousedf; //User-selected DF
int mousefqso; //User-selected QSO freq (kHz)
int nagain; //1 ==> decode only at fQSO +/- Tol
int ndepth; //How much hinted decoding to do?
int ndiskdat; //1 ==> data read from *.tf2 or *.iq file
int neme; //Hinted decoding tries only for EME calls
int newdat; //1 ==> new data, must do long FFT
int nfa; //Low decode limit (kHz)
int nfb; //High decode limit (kHz)
int nfcal; //Frequency correction, for calibration (Hz)
int nfshift; //Shift of displayed center freq (kHz)
int mcall3; //1 ==> CALL3.TXT has been modified
int ntimeout; //Max for timeouts in Messages and BandMap
int ntol; //+/- decoding range around fQSO (Hz)
int nxant; //1 ==> add 45 deg to measured pol angle
int map65RxLog; //Flags to control log files
int nfsample; //Input sample rate
int nxpol; //1 if using xpol antennas, 0 otherwise
int mode65; //JT65 sub-mode: A=1, B=2, C=4
char mycall[12];
char mygrid[6];
char hiscall[12];
char hisgrid[6];
char datetime[20];
float d4[30*48000]; //This is "common/datcom/..." in fortran
int kin;
} datcom_;
}
typedef struct
{
int kin; //Parameters sent to/from the portaudio callback function
int nrx;
bool bzero;
bool iqswap;
bool b10db;
} paUserData;
//--------------------------------------------------------------- a2dCallback
@ -65,71 +34,34 @@ extern "C" int a2dCallback( const void *inputBuffer, void *outputBuffer,
(void) outputBuffer; //Prevent unused variable warnings.
(void) timeInfo;
(void) userData;
int nbytes,i,j;
float d4[4*FRAMES_PER_BUFFER];
float d4a[4*FRAMES_PER_BUFFER];
float tmp;
float fac;
int nbytes,i,j,k;
if(framesToProcess != -99) return paContinue; //###
// if(framesToProcess != -99) return paContinue; //###
if( (statusFlags&paInputOverflow) != 0) {
qDebug() << "Input Overflow";
}
if(udata->bzero) { //Start of a new minute
if(udata->bzero) { //Start of a new Rx sequence
udata->kin=0; //Reset buffer pointer
udata->bzero=false;
}
nbytes=udata->nrx*8*framesToProcess; //Bytes per frame
memcpy(d4,inputBuffer,nbytes); //Copy all samples to d4
fac=32767.0;
if(udata->b10db) fac=103618.35;
if(udata->nrx==2) {
for(i=0; i<4*int(framesToProcess); i++) { //Negate odd-numbered frames
d4[i]=fac*d4[i];
j=i/4;
if((j%2)==1) d4[i]=-d4[i];
}
if(!udata->iqswap) {
for(i=0; i<int(framesToProcess); i++) {
j=4*i;
tmp=d4[j];
d4[j]=d4[j+1];
d4[j+1]=tmp;
tmp=d4[j+2];
d4[j+2]=d4[j+3];
d4[j+3]=tmp;
}
}
memcpy(&datcom_.d8[2*udata->kin],d4,nbytes); //Copy from d4 to dd()
} else {
int k=0;
for(i=0; i<2*int(framesToProcess); i+=2) { //Negate odd-numbered frames
j=i/2;
if(j%2==0) {
d4a[k++]=fac*d4[i];
d4a[k++]=fac*d4[i+1];
} else {
d4a[k++]=-fac*d4[i];
d4a[k++]=-fac*d4[i+1];
}
d4a[k++]=0.0;
d4a[k++]=0.0;
}
if(!udata->iqswap) {
for(i=0; i<int(framesToProcess); i++) {
j=4*i;
tmp=d4a[j];
d4a[j]=d4a[j+1];
d4a[j+1]=tmp;
}
}
memcpy(&datcom_.d8[2*udata->kin],d4a,2*nbytes); //Copy from d4a to dd()
}
nbytes=4*framesToProcess; //Bytes per frame
k=udata->kin;
memcpy(&datcom_.d4[k],inputBuffer,nbytes); //Copy all samples to d4
udata->kin += framesToProcess;
datcom_.kin=udata->kin;
/*
double sq=0.0;
float x;
for(i=0; i<int(framesToProcess); i++) {
x=datcom_.d4[k++];
sq += x*x;
}
float rms = 32767.0*sqrt(sq/framesToProcess);
qDebug() << "A" << udata->kin/48000.0 << rms;
*/
return paContinue;
}
@ -138,8 +70,6 @@ void SoundInThread::run() //SoundInThread::run()
quitExecution = false;
//---------------------------------------------------- Soundcard Setup
qDebug() << "Start souncard input";
PaError paerr;
PaStreamParameters inParam;
PaStream *inStream;
@ -149,7 +79,7 @@ void SoundInThread::run() //SoundInThread::run()
udata.bzero=false; //Flag to request reset of kin
inParam.device=m_nDevIn; //### Input Device Number ###
inParam.channelCount=2; //Number of analog channels
inParam.channelCount=1; //Number of analog channels
inParam.sampleFormat=paFloat32; //Get floats from Portaudio
inParam.suggestedLatency=0.05;
inParam.hostApiSpecificStreamInfo=NULL;
@ -174,7 +104,6 @@ void SoundInThread::run() //SoundInThread::run()
emit error("Failed to start audio input stream.");
return;
}
// const PaStreamInfo* p=Pa_GetStreamInfo(inStream);
bool qe = quitExecution;
int n30z=99;
@ -182,7 +111,7 @@ void SoundInThread::run() //SoundInThread::run()
int nsec;
int n30;
int nBusy=0;
int nhsym0=0;
int nstep0=0;
//---------------------------------------------- Soundcard input loop
while (!qe) {
@ -194,20 +123,20 @@ void SoundInThread::run() //SoundInThread::run()
// Reset buffer pointer and symbol number at start of minute
if(n30 < n30z or !m_monitoring) {
nhsym0=0;
nstep0=0;
udata.bzero=true;
}
k=udata.kin;
if(m_monitoring) {
m_hsym=(k-2048)*11025.0/(2048.0*m_rate);
if(m_hsym != nhsym0) {
m_step=k/(2*6192);
if(m_step != nstep0) {
if(m_dataSinkBusy) {
nBusy++;
} else {
m_dataSinkBusy=true;
// emit readyForFFT(k); //Signal to compute new FFTs
// m_dataSinkBusy=true;
emit readyForFFT(k); //Signal to compute new FFTs
}
nhsym0=m_hsym;
nstep0=m_step;
}
}
msleep(100);
@ -234,7 +163,7 @@ void SoundInThread::setMonitoring(bool b) //setMonitoring()
}
int SoundInThread::mhsym()
int SoundInThread::mstep()
{
return m_hsym;
return m_step;
}

View File

@ -3,13 +3,7 @@
#include <QtCore>
#include <QDebug>
#include <valarray>
#ifdef Q_OS_WIN32
#include <winsock.h>
#else
#include <sys/socket.h>
#endif //Q_OS_WIN32
// Thread gets audio data from soundcard and signals when a buffer of
// specified size is available.
@ -17,8 +11,6 @@ class SoundInThread : public QThread
{
Q_OBJECT
bool quitExecution; // if true, thread exits gracefully
double m_rate; // sample rate
unsigned bufSize; // user's buffer size
protected:
virtual void run();
@ -28,18 +20,15 @@ public:
SoundInThread():
quitExecution(false),
m_dataSinkBusy(false),
m_rate(0),
bufSize(0)
m_dataSinkBusy(false)
{
}
void setInputDevice(qint32 n);
void setMonitoring(bool b);
int mhsym();
int mstep();
signals:
void bufferAvailable(std::valarray<qint16> samples, double rate);
void readyForFFT(int k);
void error(const QString& message);
void status(const QString& message);
@ -49,15 +38,8 @@ public slots:
private:
double m_fAdd;
bool m_net;
bool m_monitoring;
bool m_bForceCenterFreq;
bool m_IQswap;
bool m_10db;
double m_dForceCenterFreq;
qint32 m_nrx;
qint32 m_hsym;
qint32 m_step;
qint32 m_nDevIn;
};

View File

@ -7,7 +7,6 @@ extern "C" {
}
extern float gran(); //Noise generator (for tests only)
extern short int iwave[30*48000]; //Wave file for Tx audio
extern int nwave;
extern bool btxok;
@ -29,80 +28,22 @@ 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;
// Get System time
qint64 ms = QDateTime::currentMSecsSinceEpoch() % 86400000;
tsec = 0.001*ms;
nsec = ms/1000;
if(btxok and !btxok0) { //Start (or re-start) a transmission
n=nsec/60;
tstart=tsec - n*60.0 - 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*48000.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];
if(ic > nwave) i2=0;
for(i=0 ; i<framesToProcess; i++ ) {
short int i2=iwave[ic];
if(ic > nwave) i2=0;
// i2 = 500.0*(i2/32767.0 + 5.0*gran()); //Add noise (tests only!)
if(!btxok) i2=0;
*wptr++ = i2; //left
*wptr++ = i2; //right
ic++;
}
} else {
for(i=0 ; i<framesToProcess; i++ ) {
*wptr++ = 0;
*wptr++ = 0;
ic++;
}
if(!btxok) i2=0;
*wptr++ = i2; //left
// *wptr++ = i2; //right
ic++;
}
if(ic > nwave) {
btxok=0;
// btxok=0;
ic=0;
}
return 0;
@ -117,7 +58,7 @@ void SoundOutThread::run()
quitExecution = false;
outParam.device=m_nDevOut; //Output device number
outParam.channelCount=2; //Number of analog channels
outParam.channelCount=1; //Number of analog channels
outParam.sampleFormat=paInt16; //Send short ints to PortAudio
outParam.suggestedLatency=0.05;
outParam.hostApiSpecificStreamInfo=NULL;

View File

@ -18,8 +18,6 @@ public:
// Constructs (but does not start) a SoundOutThread
SoundOutThread()
: quitExecution(false) // Initialize some private members
, m_rate(0)
, m_nwave(48*11025)
, m_txOK(false)
, m_txMute(false)
{
@ -32,9 +30,7 @@ public:
// Private members
private:
double m_rate; //Sample rate
qint32 m_nDevOut; //Output device number
qint32 m_nwave; //Length of wave file
bool m_txOK; //Enable Tx audio
bool m_txMute; //Mute temporarily
};