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 "C" {
extern struct { //This is "common/datcom/..." in Fortran 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 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 float savg[4*NFFT]; //Avg spectra at 0,45,90,135 deg pol
double fcenter; //Center freq from Linrad (MHz) double fcenter; //Center freq from Linrad (MHz)
@ -36,6 +39,7 @@ extern struct { //This is "common/datcom/..." in Fortran
char hiscall[12]; char hiscall[12];
char hisgrid[6]; char hisgrid[6];
char datetime[20]; char datetime[20];
*/
} datcom_; } datcom_;
} }

View File

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

View File

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

View File

@ -7,46 +7,15 @@
extern "C" { extern "C" {
#include <portaudio.h> #include <portaudio.h>
extern struct { extern struct {
double d8[2*60*96000]; //This is "common/datcom/..." in fortran float d4[30*48000]; //This is "common/datcom/..." in fortran
float ss[4*322*NFFT]; int kin;
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];
} datcom_; } datcom_;
} }
typedef struct typedef struct
{ {
int kin; //Parameters sent to/from the portaudio callback function int kin; //Parameters sent to/from the portaudio callback function
int nrx;
bool bzero; bool bzero;
bool iqswap;
bool b10db;
} paUserData; } paUserData;
//--------------------------------------------------------------- a2dCallback //--------------------------------------------------------------- a2dCallback
@ -65,71 +34,34 @@ extern "C" int a2dCallback( const void *inputBuffer, void *outputBuffer,
(void) outputBuffer; //Prevent unused variable warnings. (void) outputBuffer; //Prevent unused variable warnings.
(void) timeInfo; (void) timeInfo;
(void) userData; (void) userData;
int nbytes,i,j; int nbytes,i,j,k;
float d4[4*FRAMES_PER_BUFFER];
float d4a[4*FRAMES_PER_BUFFER];
float tmp;
float fac;
if(framesToProcess != -99) return paContinue; //### // if(framesToProcess != -99) return paContinue; //###
if( (statusFlags&paInputOverflow) != 0) { if( (statusFlags&paInputOverflow) != 0) {
qDebug() << "Input Overflow"; 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->kin=0; //Reset buffer pointer
udata->bzero=false; udata->bzero=false;
} }
nbytes=udata->nrx*8*framesToProcess; //Bytes per frame nbytes=4*framesToProcess; //Bytes per frame
memcpy(d4,inputBuffer,nbytes); //Copy all samples to d4 k=udata->kin;
memcpy(&datcom_.d4[k],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()
}
udata->kin += framesToProcess; 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; return paContinue;
} }
@ -138,8 +70,6 @@ void SoundInThread::run() //SoundInThread::run()
quitExecution = false; quitExecution = false;
//---------------------------------------------------- Soundcard Setup //---------------------------------------------------- Soundcard Setup
qDebug() << "Start souncard input";
PaError paerr; PaError paerr;
PaStreamParameters inParam; PaStreamParameters inParam;
PaStream *inStream; PaStream *inStream;
@ -149,7 +79,7 @@ void SoundInThread::run() //SoundInThread::run()
udata.bzero=false; //Flag to request reset of kin udata.bzero=false; //Flag to request reset of kin
inParam.device=m_nDevIn; //### Input Device Number ### 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.sampleFormat=paFloat32; //Get floats from Portaudio
inParam.suggestedLatency=0.05; inParam.suggestedLatency=0.05;
inParam.hostApiSpecificStreamInfo=NULL; inParam.hostApiSpecificStreamInfo=NULL;
@ -174,7 +104,6 @@ void SoundInThread::run() //SoundInThread::run()
emit error("Failed to start audio input stream."); emit error("Failed to start audio input stream.");
return; return;
} }
// const PaStreamInfo* p=Pa_GetStreamInfo(inStream);
bool qe = quitExecution; bool qe = quitExecution;
int n30z=99; int n30z=99;
@ -182,7 +111,7 @@ void SoundInThread::run() //SoundInThread::run()
int nsec; int nsec;
int n30; int n30;
int nBusy=0; int nBusy=0;
int nhsym0=0; int nstep0=0;
//---------------------------------------------- Soundcard input loop //---------------------------------------------- Soundcard input loop
while (!qe) { while (!qe) {
@ -194,20 +123,20 @@ void SoundInThread::run() //SoundInThread::run()
// Reset buffer pointer and symbol number at start of minute // Reset buffer pointer and symbol number at start of minute
if(n30 < n30z or !m_monitoring) { if(n30 < n30z or !m_monitoring) {
nhsym0=0; nstep0=0;
udata.bzero=true; udata.bzero=true;
} }
k=udata.kin; k=udata.kin;
if(m_monitoring) { if(m_monitoring) {
m_hsym=(k-2048)*11025.0/(2048.0*m_rate); m_step=k/(2*6192);
if(m_hsym != nhsym0) { if(m_step != nstep0) {
if(m_dataSinkBusy) { if(m_dataSinkBusy) {
nBusy++; nBusy++;
} else { } else {
m_dataSinkBusy=true; // m_dataSinkBusy=true;
// emit readyForFFT(k); //Signal to compute new FFTs emit readyForFFT(k); //Signal to compute new FFTs
} }
nhsym0=m_hsym; nstep0=m_step;
} }
} }
msleep(100); 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 <QtCore>
#include <QDebug> #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 // Thread gets audio data from soundcard and signals when a buffer of
// specified size is available. // specified size is available.
@ -17,8 +11,6 @@ class SoundInThread : public QThread
{ {
Q_OBJECT Q_OBJECT
bool quitExecution; // if true, thread exits gracefully bool quitExecution; // if true, thread exits gracefully
double m_rate; // sample rate
unsigned bufSize; // user's buffer size
protected: protected:
virtual void run(); virtual void run();
@ -28,18 +20,15 @@ public:
SoundInThread(): SoundInThread():
quitExecution(false), quitExecution(false),
m_dataSinkBusy(false), m_dataSinkBusy(false)
m_rate(0),
bufSize(0)
{ {
} }
void setInputDevice(qint32 n); void setInputDevice(qint32 n);
void setMonitoring(bool b); void setMonitoring(bool b);
int mhsym(); int mstep();
signals: signals:
void bufferAvailable(std::valarray<qint16> samples, double rate);
void readyForFFT(int k); void readyForFFT(int k);
void error(const QString& message); void error(const QString& message);
void status(const QString& message); void status(const QString& message);
@ -49,15 +38,8 @@ public slots:
private: private:
double m_fAdd;
bool m_net;
bool m_monitoring; bool m_monitoring;
bool m_bForceCenterFreq; qint32 m_step;
bool m_IQswap;
bool m_10db;
double m_dForceCenterFreq;
qint32 m_nrx;
qint32 m_hsym;
qint32 m_nDevIn; qint32 m_nDevIn;
}; };

View File

@ -7,7 +7,6 @@ extern "C" {
} }
extern float gran(); //Noise generator (for tests only) extern float gran(); //Noise generator (for tests only)
extern short int iwave[30*48000]; //Wave file for Tx audio extern short int iwave[30*48000]; //Wave file for Tx audio
extern int nwave; extern int nwave;
extern bool btxok; extern bool btxok;
@ -29,80 +28,22 @@ extern "C" int d2aCallback(const void *inputBuffer, void *outputBuffer,
short *wptr = (short*)outputBuffer; short *wptr = (short*)outputBuffer;
unsigned int i,n; unsigned int i,n;
static int ic=0; static int ic=0;
// static int ic0=0;
// static int nsec0=-99;
static bool btxok0=false; static bool btxok0=false;
static int nminStart=0; static int nminStart=0;
// static t0,t1;
double tsec,tstart; double tsec,tstart;
int nsec; 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++ ) { for(i=0 ; i<framesToProcess; i++ ) {
short int i2=iwave[ic]; short int i2=iwave[ic];
if(ic > nwave) i2=0; if(ic > nwave) i2=0;
// i2 = 500.0*(i2/32767.0 + 5.0*gran()); //Add noise (tests only!) // i2 = 500.0*(i2/32767.0 + 5.0*gran()); //Add noise (tests only!)
if(!btxok) i2=0; if(!btxok) i2=0;
*wptr++ = i2; //left *wptr++ = i2; //left
*wptr++ = i2; //right // *wptr++ = i2; //right
ic++; ic++;
} }
} else {
for(i=0 ; i<framesToProcess; i++ ) {
*wptr++ = 0;
*wptr++ = 0;
ic++;
}
}
if(ic > nwave) { if(ic > nwave) {
btxok=0; // btxok=0;
ic=0; ic=0;
} }
return 0; return 0;
@ -117,7 +58,7 @@ void SoundOutThread::run()
quitExecution = false; quitExecution = false;
outParam.device=m_nDevOut; //Output device number 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.sampleFormat=paInt16; //Send short ints to PortAudio
outParam.suggestedLatency=0.05; outParam.suggestedLatency=0.05;
outParam.hostApiSpecificStreamInfo=NULL; outParam.hostApiSpecificStreamInfo=NULL;

View File

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