Most of these changes are thanks to G4WJS. Audio I/O is now done using

Qt's built-in QAudio calls rather than PortAudio.  Also includes some
refactoring of the arrangement for these calls, and more use of C++ style.


git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@3523 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
Joe Taylor 2013-08-05 13:57:55 +00:00
parent e9f9180088
commit 61f023ddd1
21 changed files with 1227 additions and 1709 deletions

View File

@ -3,13 +3,12 @@
#define NSMAX 6827 #define NSMAX 6827
#define NTMAX 120 #define NTMAX 120
#define RX_SAMPLE_RATE 12000
extern "C" { extern struct FortranCommon {
extern struct {
float ss[184*NSMAX]; //This is "common/jt9com/..." in fortran float ss[184*NSMAX]; //This is "common/jt9com/..." in fortran
float savg[NSMAX]; float savg[NSMAX];
short int d2[NTMAX*12000]; short int d2[NTMAX*RX_SAMPLE_RATE];
int nutc; //UTC as integer, HHMM int nutc; //UTC as integer, HHMM
int ndiskdat; //1 ==> data read from *.wav file int ndiskdat; //1 ==> data read from *.wav file
int ntrperiod; //TR period (seconds) int ntrperiod; //TR period (seconds)
@ -29,6 +28,4 @@ extern struct {
char datetime[20]; char datetime[20];
} jt9com_; } jt9com_;
}
#endif // COMMONS_H #endif // COMMONS_H

View File

@ -1,7 +1,6 @@
#include "devsetup.h" #include "devsetup.h"
#include <QDebug> #include <QDebug>
#include <QSettings> #include <QSettings>
#include <portaudio.h>
#include <QAudioDeviceInfo> #include <QAudioDeviceInfo>
#include <QAudioInput> #include <QAudioInput>
@ -12,7 +11,10 @@ qint32 g2_iptt;
qint32 g2_COMportOpen; qint32 g2_COMportOpen;
//----------------------------------------------------------- DevSetup() //----------------------------------------------------------- DevSetup()
DevSetup::DevSetup(QWidget *parent) : QDialog(parent) DevSetup::DevSetup(QWidget *parent)
: QDialog(parent)
, m_audioInputDevices (QAudioDeviceInfo::availableDevices (QAudio::AudioInput))
, m_audioOutputDevices (QAudioDeviceInfo::availableDevices (QAudio::AudioOutput))
{ {
ui.setupUi(this); //setup the dialog form ui.setupUi(this); //setup the dialog form
m_restartSoundIn=false; m_restartSoundIn=false;
@ -37,109 +39,43 @@ void DevSetup::initDlg()
QString catPortDriver = settings.value("CATdriver","None").toString(); QString catPortDriver = settings.value("CATdriver","None").toString();
settings.endGroup(); settings.endGroup();
/* //
QList<QAudioDeviceInfo> InDevices; // loaad combo boxes with setup choices
QList<QAudioDeviceInfo> OutDevices; //
QAudioDeviceInfo deviceInfo; {
int currentIndex = -1;
InDevices = deviceInfo.availableDevices(QAudio::AudioInput); int defaultIndex = 0;
OutDevices = deviceInfo.availableDevices(QAudio::AudioOutput); for (AudioDevices::const_iterator p = m_audioInputDevices.begin (); p != m_audioInputDevices.end (); ++p)
{
foreach (const QAudioDeviceInfo &deviceInfo, InDevices) { ui.comboBoxSndIn->addItem (p->deviceName ());
ui.comboBoxSndIn->addItem(deviceInfo.deviceName(), if (*p == m_audioInputDevice)
qVariantFromValue(deviceInfo)); {
} currentIndex = p - m_audioInputDevices.begin ();
}
foreach (const QAudioDeviceInfo &deviceInfo, OutDevices) { else if (*p == QAudioDeviceInfo::defaultInputDevice ())
ui.comboBoxSndOut->addItem(deviceInfo.deviceName(), {
qVariantFromValue(deviceInfo)); defaultIndex = p - m_audioInputDevices.begin ();
} }
*/ }
ui.comboBoxSndIn->setCurrentIndex (currentIndex != -1 ? currentIndex : defaultIndex);
int k,id;
int numDevices=Pa_GetDeviceCount();
const PaDeviceInfo *pdi;
int nchin;
int nchout;
char pa_device_name[128];
char pa_device_hostapi[128];
k=0;
for(id=0; id<numDevices; id++ ) {
pdi=Pa_GetDeviceInfo(id);
nchin=pdi->maxInputChannels;
if(nchin>0) {
m_inDevList[k]=id;
if (id == m_paInDevice)
m_nDevIn = k;
k++;
sprintf((char*)(pa_device_name),"%s",pdi->name);
sprintf((char*)(pa_device_hostapi),"%s",
Pa_GetHostApiInfo(pdi->hostApi)->name);
#ifdef WIN32
char *p,*p1;
char p2[50];
p1=(char*)"";
p=strstr(pa_device_hostapi,"MME");
if(p!=NULL) p1=(char*)"MME";
p=strstr(pa_device_hostapi,"Direct");
if(p!=NULL) p1=(char*)"DirectX";
p=strstr(pa_device_hostapi,"WASAPI");
if(p!=NULL) p1=(char*)"WASAPI";
p=strstr(pa_device_hostapi,"ASIO");
if(p!=NULL) p1=(char*)"ASIO";
p=strstr(pa_device_hostapi,"WDM-KS");
if(p!=NULL) p1=(char*)"WDM-KS";
sprintf(p2,"%2d %d %-8s %-39s",id,nchin,p1,pa_device_name);
QString t(p2);
#else
QString t;
t.sprintf("%2d %d %-8s %-39s",id,nchin,
Pa_GetHostApiInfo(pdi->hostApi)->name,pdi->name);
#endif
ui.comboBoxSndIn->addItem(t);
}
} }
k=0; {
for(id=0; id<numDevices; id++ ) { int currentIndex = -1;
pdi=Pa_GetDeviceInfo(id); int defaultIndex = 0;
nchout=pdi->maxOutputChannels; for (AudioDevices::const_iterator p = m_audioOutputDevices.begin (); p != m_audioOutputDevices.end (); ++p)
if(nchout>0) { {
m_outDevList[k]=id; ui.comboBoxSndOut->addItem (p->deviceName ());
if (id == m_paOutDevice) if (*p == m_audioOutputDevice)
m_nDevOut = k; {
k++; currentIndex = p - m_audioOutputDevices.begin ();
sprintf((char*)(pa_device_name),"%s",pdi->name); }
sprintf((char*)(pa_device_hostapi),"%s", else if (*p == QAudioDeviceInfo::defaultOutputDevice ())
Pa_GetHostApiInfo(pdi->hostApi)->name); {
defaultIndex = p - m_audioOutputDevices.begin ();
#ifdef WIN32 }
char *p,*p1; }
char p2[50]; ui.comboBoxSndOut->setCurrentIndex (currentIndex != -1 ? currentIndex : defaultIndex);
p1=(char*)"";
p=strstr(pa_device_hostapi,"MME");
if(p!=NULL) p1=(char*)"MME";
p=strstr(pa_device_hostapi,"Direct");
if(p!=NULL) p1=(char*)"DirectX";
p=strstr(pa_device_hostapi,"WASAPI");
if(p!=NULL) p1=(char*)"WASAPI";
p=strstr(pa_device_hostapi,"ASIO");
if(p!=NULL) p1=(char*)"ASIO";
p=strstr(pa_device_hostapi,"WDM-KS");
if(p!=NULL) p1=(char*)"WDM-KS";
sprintf(p2,"%2d %d %-8s %-39s",id,nchout,p1,pa_device_name);
QString t(p2);
#else
QString t;
t.sprintf("%2d %d %-8s %-39s",id,nchout,
Pa_GetHostApiInfo(pdi->hostApi)->name,pdi->name);
#endif
ui.comboBoxSndOut->addItem(t);
}
} }
connect(&p4, SIGNAL(readyReadStandardOutput()), connect(&p4, SIGNAL(readyReadStandardOutput()),
@ -167,8 +103,6 @@ void DevSetup::initDlg()
ui.idIntSpinBox->setValue(m_idInt); ui.idIntSpinBox->setValue(m_idInt);
ui.pttMethodComboBox->setCurrentIndex(m_pttMethodIndex); ui.pttMethodComboBox->setCurrentIndex(m_pttMethodIndex);
ui.saveDirEntry->setText(m_saveDir); ui.saveDirEntry->setText(m_saveDir);
ui.comboBoxSndIn->setCurrentIndex(m_nDevIn);
ui.comboBoxSndOut->setCurrentIndex(m_nDevOut);
ui.cbID73->setChecked(m_After73); ui.cbID73->setChecked(m_After73);
ui.cbPSKReporter->setChecked(m_pskReporter); ui.cbPSKReporter->setChecked(m_pskReporter);
ui.cbSplit->setChecked(m_bSplit and m_catEnabled); ui.cbSplit->setChecked(m_bSplit and m_catEnabled);
@ -302,11 +236,17 @@ void DevSetup::accept()
// Check to see whether SoundInThread must be restarted, // Check to see whether SoundInThread must be restarted,
// and save user parameters. // and save user parameters.
if(m_nDevIn!=ui.comboBoxSndIn->currentIndex() or if (m_audioInputDevice != m_audioInputDevices[ui.comboBoxSndIn->currentIndex ()])
m_paInDevice!=m_inDevList[m_nDevIn]) m_restartSoundIn=true; {
m_audioInputDevice = m_audioInputDevices[ui.comboBoxSndIn->currentIndex ()];
m_restartSoundIn = true;
}
if(m_nDevOut!=ui.comboBoxSndOut->currentIndex() or if (m_audioOutputDevice != m_audioOutputDevices[ui.comboBoxSndOut->currentIndex ()])
m_paOutDevice!=m_outDevList[m_nDevOut]) m_restartSoundOut=true; {
m_audioOutputDevice = m_audioOutputDevices[ui.comboBoxSndOut->currentIndex ()];
m_restartSoundOut = true;
}
m_myCall=ui.myCallEntry->text(); m_myCall=ui.myCallEntry->text();
m_myGrid=ui.myGridEntry->text(); m_myGrid=ui.myGridEntry->text();
@ -314,10 +254,6 @@ void DevSetup::accept()
m_pttMethodIndex=ui.pttMethodComboBox->currentIndex(); m_pttMethodIndex=ui.pttMethodComboBox->currentIndex();
m_pttPort=ui.pttComboBox->currentIndex(); m_pttPort=ui.pttComboBox->currentIndex();
m_saveDir=ui.saveDirEntry->text(); m_saveDir=ui.saveDirEntry->text();
m_nDevIn=ui.comboBoxSndIn->currentIndex();
m_paInDevice=m_inDevList[m_nDevIn];
m_nDevOut=ui.comboBoxSndOut->currentIndex();
m_paOutDevice=m_outDevList[m_nDevOut];
m_macro.clear(); m_macro.clear();
m_macro.append(ui.macro1->text()); m_macro.append(ui.macro1->text());

View File

@ -1,10 +1,13 @@
#ifndef DEVSETUP_H #ifndef DEVSETUP_H
#define DEVSETUP_H #define DEVSETUP_H
#include "ui_devsetup.h"
#include <QDialog> #include <QDialog>
#include <QProcess> #include <QProcess>
#include <QMessageBox> #include <QMessageBox>
#include "ui_devsetup.h" #include <QAudioDeviceInfo>
#include "rigclass.h" #include "rigclass.h"
class DevSetup : public QDialog class DevSetup : public QDialog
@ -19,12 +22,6 @@ public:
qint32 m_idInt; qint32 m_idInt;
qint32 m_pttMethodIndex; qint32 m_pttMethodIndex;
qint32 m_pttPort; qint32 m_pttPort;
qint32 m_nDevIn;
qint32 m_nDevOut;
qint32 m_inDevList[100];
qint32 m_outDevList[100];
qint32 m_paInDevice;
qint32 m_paOutDevice;
qint32 m_catPortIndex; qint32 m_catPortIndex;
qint32 m_rig; qint32 m_rig;
qint32 m_rigIndex; qint32 m_rigIndex;
@ -39,8 +36,14 @@ public:
qint32 m_poll; qint32 m_poll;
qint32 m_tmp; qint32 m_tmp;
typedef QList<QAudioDeviceInfo> AudioDevices;
AudioDevices m_audioInputDevices; /* available input devices */
AudioDevices m_audioOutputDevices; /* available output devices */
QAudioDeviceInfo m_audioInputDevice; /* selected input device */
QAudioDeviceInfo m_audioOutputDevice; /* selected output device */
bool m_restartSoundIn; bool m_restartSoundIn;
bool m_restartSoundOut; bool m_restartSoundOut;
bool m_pskReporter; bool m_pskReporter;
bool m_firstCall; bool m_firstCall;
bool m_catEnabled; bool m_catEnabled;

View File

@ -9,8 +9,8 @@ EXE_DIR = ../../wsjtx_install
# -I'c:/QtSDK/Desktop/Qt/4.7.4/mingw/include/ActiveQt' \ # -I'c:/QtSDK/Desktop/Qt/4.7.4/mingw/include/ActiveQt' \
# -I'release' -I'.' -I'c:/QtSDK/Desktop/Qt/4.7.4/mingw/mkspecs/win32-g++' # -I'release' -I'.' -I'c:/QtSDK/Desktop/Qt/4.7.4/mingw/mkspecs/win32-g++'
INCPATH = -I'C:/Qt/Qt5.0.2/5.0.2/mingw47_32/include/QtCore' \ INCPATH = -I'C:/Qt/Qt5.1.0/5.1.0/mingw48_32/include/QtCore' \
-I'C:/Qt/Qt5.0.2/5.0.2/mingw47_32/include' \ -I'C:/Qt/Qt5.1.0/5.1.0/mingw48_32/include' \
# Compilers # Compilers
CC = gcc CC = gcc
@ -57,11 +57,10 @@ libjt9.a: $(OBJS1)
ranlib libjt9.a ranlib libjt9.a
OBJS2 = jt9.o jt9a.o jt9b.o jt9c.o ipcomm.o sec_midn.o usleep.o OBJS2 = jt9.o jt9a.o jt9b.o jt9c.o ipcomm.o sec_midn.o usleep.o
#LIBS2 = -L'c:/QtSDK/Desktop/Qt/4.7.4/mingw/lib' -lQtCore4 LIBS2 = -L'C:/Qt/Qt5.1.0/5.1.0/mingw48_32/lib' -lQt5Core
LIBS2 = -L'C:/Qt/Qt5.0.2/5.0.2/mingw47_32/lib' -lQt5Core
jt9.exe: $(OBJS2) libjt9.a jt9.exe: $(OBJS2) libjt9.a
$(CXX) -o jt9.exe $(OBJS2) $(LIBS2) libjt9.a ../libfftw3f_win.a \ $(CXX) -o jt9.exe -static $(OBJS2) $(LIBS2) libjt9.a \
c:/MinGW/lib/libf95.a ../libfftw3f_win.a c:/MinGW/lib/libf95.a
mkdir -p $(EXE_DIR) mkdir -p $(EXE_DIR)
cp jt9.exe $(EXE_DIR) cp jt9.exe $(EXE_DIR)

5
lib/usleep.c Normal file
View File

@ -0,0 +1,5 @@
/* usleep(3) */
void usleep_(unsigned long *microsec)
{
usleep(*microsec);
}

View File

@ -4,9 +4,10 @@
#include <QtGui> #include <QtGui>
#endif #endif
#include <QApplication> #include <QApplication>
#include <portaudio.h>
#include "mainwindow.h" #include "mainwindow.h"
// Multiple instances: // Multiple instances:
QSharedMemory mem_jt9; QSharedMemory mem_jt9;
QUuid my_uuid; QUuid my_uuid;
@ -48,13 +49,6 @@ int main(int argc, char *argv[])
} }
memset(to,0,size); //Zero all decoding params in shared memory memset(to,0,size); //Zero all decoding params in shared memory
//Initialize Portaudio
PaError paerr=Pa_Initialize();
if(paerr!=paNoError) {
QMessageBox::critical( 0, "Error", "Unable to initialize PortAudio.");
exit(1);
}
// Multiple instances: Call MainWindow() with the UUID key // Multiple instances: Call MainWindow() with the UUID key
MainWindow w(&mem_jt9, &my_key, fontSize2, fontWeight2); MainWindow w(&mem_jt9, &my_key, fontSize2, fontWeight2);
w.show(); w.show();

View File

@ -1,13 +1,17 @@
//--------------------------------------------------------------- MainWindow //--------------------------------------------------------------- MainWindow
#include "mainwindow.h" #include "mainwindow.h"
#include "ui_mainwindow.h" #include "ui_mainwindow.h"
#include <vector>
#include <QScopedPointer>
#include "devsetup.h" #include "devsetup.h"
#include "plotter.h" #include "plotter.h"
#include "about.h" #include "about.h"
#include "widegraph.h" #include "widegraph.h"
#include "sleep.h" #include "sleep.h"
#include "getfile.h" #include "getfile.h"
#include <portaudio.h>
#include "logqso.h" #include "logqso.h"
#ifdef QT5 #ifdef QT5
@ -15,8 +19,14 @@
#include <QtConcurrent/QtConcurrentRun> #include <QtConcurrent/QtConcurrentRun>
#endif #endif
int itone[126]; //Audio tones for all Tx symbols #define NUM_JT65_SYMBOLS 126
int icw[250]; //Dits for CW ID #define NUM_JT9_SYMBOLS 85
#define NUM_CW_SYMBOLS 250
#define TX_SAMPLE_RATE 48000
int itone[NUM_JT65_SYMBOLS]; //Audio tones for all Tx symbols
int icw[NUM_CW_SYMBOLS]; //Dits for CW ID
int outBufSize; int outBufSize;
int rc; int rc;
qint32 g_COMportOpen; qint32 g_COMportOpen;
@ -41,10 +51,16 @@ MainWindow::MainWindow(QSharedMemory *shdmem, QString *thekey, \
qint32 fontSize2, qint32 fontWeight2, \ qint32 fontSize2, qint32 fontWeight2, \
QWidget *parent) : QWidget *parent) :
QMainWindow(parent), QMainWindow(parent),
ui(new Ui::MainWindow) ui(new Ui::MainWindow),
m_audioInputDevice (QAudioDeviceInfo::defaultInputDevice ()), // start with default
m_detector (RX_SAMPLE_RATE, NTMAX / 2, 6912 / 2 * sizeof (jt9com_.d2[0]), this),
m_audioOutputDevice (QAudioDeviceInfo::defaultOutputDevice ()), // start with default
m_modulator (TX_SAMPLE_RATE, NTMAX / 2, this)
{ {
ui->setupUi(this); ui->setupUi(this);
m_detector.open ();
on_EraseButton_clicked(); on_EraseButton_clicked();
QActionGroup* paletteGroup = new QActionGroup(this); QActionGroup* paletteGroup = new QActionGroup(this);
ui->actionCuteSDR->setActionGroup(paletteGroup); ui->actionCuteSDR->setActionGroup(paletteGroup);
@ -83,12 +99,15 @@ MainWindow::MainWindow(QSharedMemory *shdmem, QString *thekey, \
SLOT(doubleClickOnCall2(bool,bool))); SLOT(doubleClickOnCall2(bool,bool)));
setWindowTitle(Program_Title_Version); setWindowTitle(Program_Title_Version);
connect(&m_soundInput, SIGNAL(readyForFFT(int)), connect(&m_detector, &Detector::bytesWritten, this, &MainWindow::dataSink);
this, SLOT(dataSink(int)));
connect(&m_soundInput, SIGNAL(error(QString)), this, connect(&m_soundInput, SIGNAL(error(QString)), this,
SLOT(showSoundInError(QString))); SLOT(showSoundInError(QString)));
connect(&m_soundOutput, SIGNAL(error(QString)), this,
SLOT(showSoundOutError(QString)));
connect(&m_soundInput, SIGNAL(status(QString)), this, connect(&m_soundInput, SIGNAL(status(QString)), this,
SLOT(showStatusMessage(QString))); SLOT(showStatusMessage(QString)));
// connect(&m_soundOutput, SIGNAL(status(QString)), this,
// SLOT(showStatusMessage(QString)));
createStatusBar(); createStatusBar();
connect(&proc_jt9, SIGNAL(readyReadStandardOutput()), connect(&proc_jt9, SIGNAL(readyReadStandardOutput()),
@ -146,7 +165,7 @@ MainWindow::MainWindow(QSharedMemory *shdmem, QString *thekey, \
m_auto=false; m_auto=false;
m_waterfallAvg = 1; m_waterfallAvg = 1;
m_txFirst=false; m_txFirst=false;
m_soundOutput.mute(false); m_modulator.mute(false);
m_btxMute=false; m_btxMute=false;
m_btxok=false; m_btxok=false;
m_restart=false; m_restart=false;
@ -299,11 +318,11 @@ MainWindow::MainWindow(QSharedMemory *shdmem, QString *thekey, \
watcher2 = new QFutureWatcher<void>; watcher2 = new QFutureWatcher<void>;
connect(watcher2, SIGNAL(finished()),this,SLOT(diskWriteFinished())); connect(watcher2, SIGNAL(finished()),this,SLOT(diskWriteFinished()));
m_soundInput.start(m_paInDevice); m_soundInput.start(m_audioInputDevice, RX_SAMPLE_RATE / 10, &m_detector);
m_soundOutput.setTxFreq(m_txFreq); m_modulator.setFrequency(m_txFreq - (m_bSplit || m_bXIT ? m_XIT : 0));
m_soundOutput.tune(false); m_modulator.tune(false);
m_monitoring=!m_monitorStartOFF; // Start with Monitoring ON/OFF m_monitoring=!m_monitorStartOFF; // Start with Monitoring ON/OFF
m_soundInput.setMonitoring(m_monitoring); m_detector.setMonitoring(m_monitoring);
m_diskData=false; m_diskData=false;
// Create "m_worked", a dictionary of all calls in wsjtx.log // Create "m_worked", a dictionary of all calls in wsjtx.log
@ -371,10 +390,12 @@ MainWindow::~MainWindow()
{ {
writeSettings(); writeSettings();
m_soundOutput.stop(); m_soundOutput.stop();
m_modulator.close();
if(!m_decoderBusy) { if(!m_decoderBusy) {
QFile lockFile(m_appDir + "/.lock"); QFile lockFile(m_appDir + "/.lock");
lockFile.remove(); lockFile.remove();
} }
m_detector.close ();
delete ui; delete ui;
} }
@ -404,19 +425,8 @@ void MainWindow::writeSettings()
settings.setValue("PTTmethod",m_pttMethodIndex); settings.setValue("PTTmethod",m_pttMethodIndex);
settings.setValue("PTTport",m_pttPort); settings.setValue("PTTport",m_pttPort);
settings.setValue("SaveDir",m_saveDir); settings.setValue("SaveDir",m_saveDir);
char soundName[128]; settings.setValue("SoundInName", m_audioInputDevice.deviceName ());
if (Pa_GetDeviceInfo( m_paInDevice)) { // store name, number may be different next time settings.setValue("SoundOutName", m_audioOutputDevice.deviceName ());
snprintf( soundName, sizeof( soundName), "%s:%s",
Pa_GetHostApiInfo( Pa_GetDeviceInfo( m_paInDevice)->hostApi)->name,
Pa_GetDeviceInfo( m_paInDevice)->name);
settings.setValue("SoundInName", soundName);
}
if (Pa_GetDeviceInfo( m_paOutDevice)) { // store name, number may be different next time
snprintf( soundName, sizeof( soundName), "%s:%s",
Pa_GetHostApiInfo( Pa_GetDeviceInfo( m_paOutDevice)->hostApi)->name,
Pa_GetDeviceInfo( m_paOutDevice)->name);
settings.setValue("SoundOutName", soundName);
}
settings.setValue("PaletteCuteSDR",ui->actionCuteSDR->isChecked()); settings.setValue("PaletteCuteSDR",ui->actionCuteSDR->isChecked());
settings.setValue("PaletteLinrad",ui->actionLinrad->isChecked()); settings.setValue("PaletteLinrad",ui->actionLinrad->isChecked());
settings.setValue("PaletteAFMHot",ui->actionAFMHot->isChecked()); settings.setValue("PaletteAFMHot",ui->actionAFMHot->isChecked());
@ -511,33 +521,34 @@ void MainWindow::readSettings()
m_pttPort=settings.value("PTTport",0).toInt(); m_pttPort=settings.value("PTTport",0).toInt();
m_saveDir=settings.value("SaveDir",m_appDir + "/save").toString(); m_saveDir=settings.value("SaveDir",m_appDir + "/save").toString();
char soundName[128]; {
QString savedName = settings.value( "SoundInName", "default").toString(); //
for (m_paInDevice = Pa_GetDeviceCount() - 1; m_paInDevice >= 0; m_paInDevice--) { // retrieve audio input device
snprintf( soundName, sizeof( soundName), "%s:%s", //
Pa_GetHostApiInfo( Pa_GetDeviceInfo( m_paInDevice)->hostApi)->name, QString savedName = settings.value( "SoundInName", "default").toString();
Pa_GetDeviceInfo( m_paInDevice)->name); QList<QAudioDeviceInfo> audioInputDevices (QAudioDeviceInfo::availableDevices (QAudio::AudioInput)); // available audio input devices
if ((savedName == soundName) && (Pa_GetDeviceInfo(m_paInDevice)->maxInputChannels > 0)) for (QList<QAudioDeviceInfo>::const_iterator p = audioInputDevices.begin (); p != audioInputDevices.end (); ++p)
break; {
} if (p->deviceName () == savedName)
if (m_paInDevice < 0) { // no match for device name? {
m_paInDevice = Pa_GetDefaultInputDevice(); m_audioInputDevice = *p;
if (m_paInDevice == paNoDevice) // no default input device? }
m_paInDevice = 0; }
} }
savedName = settings.value("SoundOutName", "default").toString(); {
for (m_paOutDevice = Pa_GetDeviceCount() - 1; m_paOutDevice >= 0; m_paOutDevice--) { //
snprintf( soundName, sizeof( soundName), "%s:%s", // retrieve audio output device
Pa_GetHostApiInfo( Pa_GetDeviceInfo( m_paOutDevice)->hostApi)->name, //
Pa_GetDeviceInfo( m_paOutDevice)->name); QString savedName = settings.value("SoundOutName", "default").toString();
if ((savedName == soundName) && (Pa_GetDeviceInfo(m_paOutDevice)->maxOutputChannels > 0)) QList<QAudioDeviceInfo> audioOutputDevices (QAudioDeviceInfo::availableDevices (QAudio::AudioOutput)); // available audio output devices
break; for (QList<QAudioDeviceInfo>::const_iterator p = audioOutputDevices.begin (); p != audioOutputDevices.end (); ++p)
} {
if (m_paOutDevice < 0) { // no match for device name? if (p->deviceName () == savedName)
m_paOutDevice = Pa_GetDefaultOutputDevice(); {
if (m_paOutDevice == paNoDevice) // no default output device? m_audioOutputDevice = *p;
m_paOutDevice = 0; }
}
} }
ui->actionCuteSDR->setChecked(settings.value( ui->actionCuteSDR->setChecked(settings.value(
@ -563,7 +574,7 @@ void MainWindow::readSettings()
ui->RxFreqSpinBox->setValue(m_rxFreq); ui->RxFreqSpinBox->setValue(m_rxFreq);
m_txFreq=settings.value("TxFreq",1500).toInt(); m_txFreq=settings.value("TxFreq",1500).toInt();
ui->TxFreqSpinBox->setValue(m_txFreq); ui->TxFreqSpinBox->setValue(m_txFreq);
m_soundOutput.setTxFreq(m_txFreq); m_modulator.setFrequency(m_txFreq - (m_bSplit || m_bXIT ? m_XIT : 0));
m_saveDecoded=ui->actionSave_decoded->isChecked(); m_saveDecoded=ui->actionSave_decoded->isChecked();
m_saveAll=ui->actionSave_all->isChecked(); m_saveAll=ui->actionSave_all->isChecked();
m_ndepth=settings.value("NDepth",3).toInt(); m_ndepth=settings.value("NDepth",3).toInt();
@ -655,7 +666,7 @@ void MainWindow::readSettings()
} }
//-------------------------------------------------------------- dataSink() //-------------------------------------------------------------- dataSink()
void MainWindow::dataSink(int k) void MainWindow::dataSink(qint64 bytes)
{ {
static float s[NSMAX]; static float s[NSMAX];
static int ihsym=0; static int ihsym=0;
@ -676,6 +687,7 @@ void MainWindow::dataSink(int k)
trmin=m_TRperiod/60; trmin=m_TRperiod/60;
slope=0.0; slope=0.0;
if(g_pWideGraph!=NULL) slope=(float)g_pWideGraph->getSlope(); if(g_pWideGraph!=NULL) slope=(float)g_pWideGraph->getSlope();
int k (bytes / sizeof (jt9com_.d2[0]) - 1);
symspec_(&k,&trmin,&m_nsps,&m_inGain,&slope,&px,s,&df3,&ihsym,&npts8); symspec_(&k,&trmin,&m_nsps,&m_inGain,&slope,&px,s,&df3,&ihsym,&npts8);
if(ihsym <=0) return; if(ihsym <=0) return;
QString t; QString t;
@ -710,7 +722,10 @@ void MainWindow::dataSink(int k)
} }
void MainWindow::showSoundInError(const QString& errorMsg) void MainWindow::showSoundInError(const QString& errorMsg)
{QMessageBox::critical(this, tr("Error in SoundIn"), errorMsg);} {QMessageBox::critical(this, tr("Error in SoundInput"), errorMsg);}
void MainWindow::showSoundOutError(const QString& errorMsg)
{QMessageBox::critical(this, tr("Error in SoundOutput"), errorMsg);}
void MainWindow::showStatusMessage(const QString& statusMsg) void MainWindow::showStatusMessage(const QString& statusMsg)
{statusBar()->showMessage(statusMsg);} {statusBar()->showMessage(statusMsg);}
@ -724,8 +739,8 @@ void MainWindow::on_actionDeviceSetup_triggered() //Setup Dialog
dlg.m_pttMethodIndex=m_pttMethodIndex; dlg.m_pttMethodIndex=m_pttMethodIndex;
dlg.m_pttPort=m_pttPort; dlg.m_pttPort=m_pttPort;
dlg.m_saveDir=m_saveDir; dlg.m_saveDir=m_saveDir;
dlg.m_paInDevice=m_paInDevice; dlg.m_audioInputDevice = m_audioInputDevice;
dlg.m_paOutDevice=m_paOutDevice; dlg.m_audioOutputDevice = m_audioOutputDevice;
dlg.m_pskReporter=m_pskReporter; dlg.m_pskReporter=m_pskReporter;
dlg.m_After73=m_After73; dlg.m_After73=m_After73;
dlg.m_macro=m_macro; dlg.m_macro=m_macro;
@ -769,8 +784,8 @@ void MainWindow::on_actionDeviceSetup_triggered() //Setup Dialog
m_pttMethodIndex=dlg.m_pttMethodIndex; m_pttMethodIndex=dlg.m_pttMethodIndex;
m_pttPort=dlg.m_pttPort; m_pttPort=dlg.m_pttPort;
m_saveDir=dlg.m_saveDir; m_saveDir=dlg.m_saveDir;
m_paInDevice=dlg.m_paInDevice; m_audioInputDevice = dlg.m_audioInputDevice;
m_paOutDevice=dlg.m_paOutDevice; m_audioOutputDevice = dlg.m_audioOutputDevice;
m_macro=dlg.m_macro; m_macro=dlg.m_macro;
m_dFreq=dlg.m_dFreq; m_dFreq=dlg.m_dFreq;
m_antDescription=dlg.m_antDescription; m_antDescription=dlg.m_antDescription;
@ -826,11 +841,11 @@ void MainWindow::on_actionDeviceSetup_triggered() //Setup Dialog
m_After73=dlg.m_After73; m_After73=dlg.m_After73;
if(dlg.m_restartSoundIn) { if(dlg.m_restartSoundIn) {
m_soundInput.start(m_paInDevice); m_soundInput.start(m_audioInputDevice, RX_SAMPLE_RATE / 10, &m_detector);
} }
if(dlg.m_restartSoundOut) { if(dlg.m_restartSoundOut) {
m_soundOutput.start(m_paOutDevice,m_modeTx,m_TRperiod,m_nsps,m_txFreq,m_bSplit || m_bXIT ? m_XIT : 0); transmit ();
} }
} }
m_catEnabled=dlg.m_catEnabled; m_catEnabled=dlg.m_catEnabled;
@ -859,7 +874,7 @@ void MainWindow::on_actionDeviceSetup_triggered() //Setup Dialog
void MainWindow::on_monitorButton_clicked() //Monitor void MainWindow::on_monitorButton_clicked() //Monitor
{ {
m_monitoring=true; m_monitoring=true;
m_soundInput.setMonitoring(true); m_detector.setMonitoring(true);
m_diskData=false; m_diskData=false;
} }
@ -901,7 +916,7 @@ void MainWindow::on_autoButton_clicked() //Auto
ui->autoButton->setStyleSheet(m_pbAutoOn_style); ui->autoButton->setStyleSheet(m_pbAutoOn_style);
} else { } else {
m_btxok=false; m_btxok=false;
m_soundOutput.mute(); m_modulator.mute();
ui->autoButton->setStyleSheet(""); ui->autoButton->setStyleSheet("");
on_monitorButton_clicked(); on_monitorButton_clicked();
m_repeatMsg=0; m_repeatMsg=0;
@ -1122,7 +1137,7 @@ void MainWindow::OnExit()
void MainWindow::on_stopButton_clicked() //stopButton void MainWindow::on_stopButton_clicked() //stopButton
{ {
m_monitoring=false; m_monitoring=false;
m_soundInput.setMonitoring(m_monitoring); m_detector.setMonitoring(m_monitoring);
m_loopall=false; m_loopall=false;
} }
@ -1163,7 +1178,7 @@ void MainWindow::on_actionWide_Waterfall_triggered() //Display Waterfalls
void MainWindow::on_actionOpen_triggered() //Open File void MainWindow::on_actionOpen_triggered() //Open File
{ {
m_monitoring=false; m_monitoring=false;
m_soundInput.setMonitoring(m_monitoring); m_detector.setMonitoring(m_monitoring);
QString fname; QString fname;
fname=QFileDialog::getOpenFileName(this, "Open File", m_path, fname=QFileDialog::getOpenFileName(this, "Open File", m_path,
"WSJT Files (*.wav)"); "WSJT Files (*.wav)");
@ -1223,7 +1238,7 @@ void MainWindow::diskDat() //diskDat()
for(int n=1; n<=m_hsymStop; n++) { // Do the half-symbol FFTs for(int n=1; n<=m_hsymStop; n++) { // Do the half-symbol FFTs
k=(n+1)*kstep; k=(n+1)*kstep;
jt9com_.npts8=k/8; jt9com_.npts8=k/8;
dataSink(k); dataSink(k * sizeof (jt9com_.d2[0]));
if(n%10 == 1 or n == m_hsymStop) if(n%10 == 1 or n == m_hsymStop)
qApp->processEvents(); //Keep GUI responsive qApp->processEvents(); //Keep GUI responsive
} }
@ -1718,7 +1733,7 @@ void MainWindow::guiUpdate()
} }
if(!bTxTime || m_btxMute) { if(!bTxTime || m_btxMute) {
m_btxok=false; m_btxok=false;
m_soundOutput.mute(); m_modulator.mute();
} }
} }
@ -1815,9 +1830,9 @@ void MainWindow::guiUpdate()
signalMeter->setValue(0); signalMeter->setValue(0);
m_monitoring=false; m_monitoring=false;
m_soundInput.setMonitoring(false); m_detector.setMonitoring(false);
m_btxok=true; m_btxok=true;
m_soundOutput.mute(false); m_modulator.mute(false);
m_transmitting=true; m_transmitting=true;
ui->pbTxMode->setEnabled(false); ui->pbTxMode->setEnabled(false);
if(!m_tune) { if(!m_tune) {
@ -1940,12 +1955,12 @@ void MainWindow::startTx2()
QString t=ui->tx6->text(); QString t=ui->tx6->text();
double snr=t.mid(1,5).toDouble(); double snr=t.mid(1,5).toDouble();
if(snr>0.0 or snr < -50.0) snr=99.0; if(snr>0.0 or snr < -50.0) snr=99.0;
m_soundOutput.start(m_paOutDevice,m_modeTx,m_TRperiod,m_nsps,m_txFreq,m_bSplit || m_bXIT ? m_XIT : 0,snr); transmit (snr);
signalMeter->setValue(0); signalMeter->setValue(0);
m_monitoring=false; m_monitoring=false;
m_soundInput.setMonitoring(false); m_detector.setMonitoring(false);
m_btxok=true; m_btxok=true;
m_soundOutput.mute(false); m_modulator.mute(false);
m_transmitting=true; m_transmitting=true;
ui->pbTxMode->setEnabled(false); ui->pbTxMode->setEnabled(false);
} }
@ -1954,6 +1969,7 @@ void MainWindow::startTx2()
void MainWindow::stopTx() void MainWindow::stopTx()
{ {
m_soundOutput.stop(); m_soundOutput.stop();
m_modulator.close ();
m_transmitting=false; m_transmitting=false;
ui->pbTxMode->setEnabled(true); ui->pbTxMode->setEnabled(true);
g_iptt=0; g_iptt=0;
@ -1961,7 +1977,7 @@ void MainWindow::stopTx()
lab1->setText(""); lab1->setText("");
ptt0Timer->start(200); //Sequencer delay ptt0Timer->start(200); //Sequencer delay
m_monitoring=true; m_monitoring=true;
m_soundInput.setMonitoring(true); m_detector.setMonitoring(true);
} }
void MainWindow::stopTx2() void MainWindow::stopTx2()
@ -2573,7 +2589,6 @@ void MainWindow::on_actionJT9_1_triggered()
m_TRperiod=60; m_TRperiod=60;
m_nsps=6912; m_nsps=6912;
m_hsymStop=173; m_hsymStop=173;
m_soundInput.setPeriod(m_TRperiod,m_nsps);
lab3->setStyleSheet("QLabel{background-color: #ff6ec7}"); lab3->setStyleSheet("QLabel{background-color: #ff6ec7}");
lab3->setText(m_mode); lab3->setText(m_mode);
ui->actionJT9_1->setChecked(true); ui->actionJT9_1->setChecked(true);
@ -2591,7 +2606,6 @@ void MainWindow::on_actionJT65_triggered()
m_TRperiod=60; m_TRperiod=60;
m_nsps=6912; //For symspec only m_nsps=6912; //For symspec only
m_hsymStop=173; m_hsymStop=173;
m_soundInput.setPeriod(m_TRperiod,m_nsps);
lab3->setStyleSheet("QLabel{background-color: #ffff00}"); lab3->setStyleSheet("QLabel{background-color: #ffff00}");
lab3->setText(m_mode); lab3->setText(m_mode);
ui->actionJT65->setChecked(true); ui->actionJT65->setChecked(true);
@ -2609,7 +2623,6 @@ void MainWindow::on_actionJT9_JT65_triggered()
m_TRperiod=60; m_TRperiod=60;
m_nsps=6912; m_nsps=6912;
m_hsymStop=173; m_hsymStop=173;
m_soundInput.setPeriod(m_TRperiod,m_nsps);
lab3->setStyleSheet("QLabel{background-color: #ffa500}"); lab3->setStyleSheet("QLabel{background-color: #ffa500}");
lab3->setText(m_mode); lab3->setText(m_mode);
ui->actionJT9_JT65->setChecked(true); ui->actionJT9_JT65->setChecked(true);
@ -2624,7 +2637,7 @@ void MainWindow::on_TxFreqSpinBox_valueChanged(int n)
m_txFreq=n; m_txFreq=n;
if(g_pWideGraph!=NULL) g_pWideGraph->setTxFreq(n); if(g_pWideGraph!=NULL) g_pWideGraph->setTxFreq(n);
if(m_lockTxFreq) ui->RxFreqSpinBox->setValue(n); if(m_lockTxFreq) ui->RxFreqSpinBox->setValue(n);
m_soundOutput.setTxFreq(n); m_modulator.setFrequency(m_txFreq - (m_bSplit || m_bXIT ? m_XIT : 0));
} }
void MainWindow::on_RxFreqSpinBox_valueChanged(int n) void MainWindow::on_RxFreqSpinBox_valueChanged(int n)
@ -2954,7 +2967,7 @@ void MainWindow::on_tuneButton_clicked()
} else { } else {
m_tune=true; m_tune=true;
m_sent73=false; m_sent73=false;
m_soundOutput.tune(m_tune); m_modulator.tune();
m_repeatMsg=0; m_repeatMsg=0;
ui->tuneButton->setStyleSheet(m_pbTune_style); ui->tuneButton->setStyleSheet(m_pbTune_style);
} }
@ -2964,11 +2977,11 @@ void MainWindow::on_stopTxButton_clicked() //Stop Tx
{ {
if(m_tune) { if(m_tune) {
m_tune=false; m_tune=false;
m_soundOutput.tune(m_tune); m_modulator.tune(m_tune);
} }
if(m_auto) on_autoButton_clicked(); if(m_auto) on_autoButton_clicked();
m_btxok=false; m_btxok=false;
m_soundOutput.mute(); m_modulator.mute();
m_repeatMsg=0; m_repeatMsg=0;
ui->tuneButton->setStyleSheet(""); ui->tuneButton->setStyleSheet("");
} }
@ -3024,15 +3037,20 @@ void MainWindow::rigOpen()
} else { } else {
ui->readFreq->setStyleSheet("QPushButton{background-color: orange; \ ui->readFreq->setStyleSheet("QPushButton{background-color: orange; \
border-width: 0px; border-radius: 5px;}"); border-width: 0px; border-radius: 5px;}");
} }
if(m_bSplit) ui->readFreq->setText("S");
if(!m_bSplit) ui->readFreq->setText(""); QFont font=ui->readFreq->font();
} else { font.setPointSize(9);
if(m_CATerror) ui->readFreq->setStyleSheet("QPushButton{background-color: red; \ font.setWeight(75);
ui->readFreq->setFont(font);
if(m_bSplit) ui->readFreq->setText("S");
if(!m_bSplit) ui->readFreq->setText("");
} else {
if(m_CATerror) ui->readFreq->setStyleSheet("QPushButton{background-color: red; \
border-width: 0px; border-radius: 5px;}"); border-width: 0px; border-radius: 5px;}");
if(!m_CATerror) ui->readFreq->setStyleSheet(""); if(!m_CATerror) ui->readFreq->setStyleSheet("");
ui->readFreq->setText(""); ui->readFreq->setText("");
} }
} }
void MainWindow::on_actionAllow_multiple_instances_triggered(bool checked) void MainWindow::on_actionAllow_multiple_instances_triggered(bool checked)
@ -3104,8 +3122,7 @@ void MainWindow::setXIT(int n)
ret=rig->setSplitFreq(MHz(m_dialFreq)+m_XIT,RIG_VFO_B); ret=rig->setSplitFreq(MHz(m_dialFreq)+m_XIT,RIG_VFO_B);
} }
} }
if(m_bSplit) m_soundOutput.setXIT(m_XIT); m_modulator.setFrequency(m_txFreq - (m_bSplit || m_bXIT ? m_XIT : 0));
if(!m_bSplit) m_soundOutput.setXIT(0);
} }
void MainWindow::setFreq4(int rxFreq, int txFreq) void MainWindow::setFreq4(int rxFreq, int txFreq)
@ -3151,10 +3168,29 @@ void MainWindow::pollRigFreq()
m_catEnabled=false; m_catEnabled=false;
ui->readFreq->setStyleSheet("QPushButton{background-color: red; \ ui->readFreq->setStyleSheet("QPushButton{background-color: red; \
border-width: 0px; border-radius: 5px;}"); border-width: 0px; border-radius: 5px;}");
}
} else {
int ndiff=1000000.0*(fMHz-m_dialFreq);
if(ndiff!=0) dialFreqChanged2(fMHz);
} }
} else {
int ndiff=1000000.0*(fMHz-m_dialFreq);
if(ndiff!=0) dialFreqChanged2(fMHz);
} }
} }
void MainWindow::transmit (double snr)
{
QScopedPointer<std::vector<int> > cw (new std::vector<int> (NUM_CW_SYMBOLS));
cw->assign (icw, icw + NUM_CW_SYMBOLS); // load data
if (m_modeTx == "JT65")
{
QScopedPointer<std::vector<int> > symbols (new std::vector<int> (NUM_JT65_SYMBOLS));
symbols->assign (itone, itone + NUM_JT65_SYMBOLS); // load data
m_modulator.open (symbols.take (), cw.take (), 4096.0 * 12000.0 / 11025.0, m_txFreq - (m_bSplit || m_bXIT ? m_XIT : 0), snr);
}
else
{
QScopedPointer<std::vector<int> > symbols (new std::vector<int> (NUM_JT65_SYMBOLS));
symbols->assign (itone, itone + NUM_JT9_SYMBOLS); // load data
m_modulator.open (symbols.take (), cw.take (), m_nsps, m_txFreq - (m_bSplit || m_bXIT ? m_XIT : 0), snr);
}
m_soundOutput.start(m_audioOutputDevice, &m_modulator);
} }

View File

@ -7,6 +7,9 @@
#endif #endif
#include <QTimer> #include <QTimer>
#include <QDateTime> #include <QDateTime>
#include <QList>
#include <QAudioDeviceInfo>
#include "soundin.h" #include "soundin.h"
#include "soundout.h" #include "soundout.h"
#include "commons.h" #include "commons.h"
@ -14,6 +17,8 @@
#include "rigclass.h" #include "rigclass.h"
#include "signalmeter.h" #include "signalmeter.h"
#include "logbook/logbook.h" #include "logbook/logbook.h"
#include "Detector.hpp"
#include "Modulator.hpp"
#ifdef WIN32 #ifdef WIN32
#include "PSKReporter.h" #include "PSKReporter.h"
@ -37,8 +42,9 @@ public:
public slots: public slots:
void showSoundInError(const QString& errorMsg); void showSoundInError(const QString& errorMsg);
void showSoundOutError(const QString& errorMsg);
void showStatusMessage(const QString& statusMsg); void showStatusMessage(const QString& statusMsg);
void dataSink(int k); void dataSink(qint64 bytes);
void diskDat(); void diskDat();
void diskWriteFinished(); void diskWriteFinished();
void freezeDecode(int n); void freezeDecode(int n);
@ -191,8 +197,10 @@ private:
qint32 m_nutc0; qint32 m_nutc0;
qint32 m_nrx; qint32 m_nrx;
qint32 m_hsym; qint32 m_hsym;
qint32 m_paInDevice; QAudioDeviceInfo m_audioInputDevice;
qint32 m_paOutDevice; Detector m_detector;
QAudioDeviceInfo m_audioOutputDevice;
Modulator m_modulator;
qint32 m_TRperiod; qint32 m_TRperiod;
qint32 m_nsps; qint32 m_nsps;
qint32 m_hsymStop; qint32 m_hsymStop;
@ -372,6 +380,7 @@ private:
void pollRigFreq(); void pollRigFreq();
bool gridOK(QString g); bool gridOK(QString g);
QString baseCall(QString t); QString baseCall(QString t);
void transmit (double snr = 99.);
}; };
extern void getfile(QString fname, int ntrperiod); extern void getfile(QString fname, int ntrperiod);

View File

@ -1,51 +1,51 @@
// Simple bargraph meter // Simple bargraph meter
// Implemented by Edson Pereira PY2SDR // Implemented by Edson Pereira PY2SDR
#include "meterwidget.h" #include "meterwidget.h"
MeterWidget::MeterWidget(QWidget *parent) : MeterWidget::MeterWidget(QWidget *parent) :
QWidget(parent), QWidget(parent),
m_signal(0) m_signal(0)
{ {
for ( int i = 0; i < 10; i++ ) { for ( int i = 0; i < 10; i++ ) {
signalQueue.enqueue(0); signalQueue.enqueue(0);
} }
} }
void MeterWidget::setValue(int value) void MeterWidget::setValue(int value)
{ {
m_signal = value; m_signal = value;
signalQueue.enqueue(value); signalQueue.enqueue(value);
signalQueue.dequeue(); signalQueue.dequeue();
// Get signal peak // Get signal peak
int tmp = 0; int tmp = 0;
for (int i = 0; i < signalQueue.size(); ++i) { for (int i = 0; i < signalQueue.size(); ++i) {
if (signalQueue.at(i) > tmp) if (signalQueue.at(i) > tmp)
tmp = signalQueue.at(i); tmp = signalQueue.at(i);
} }
m_sigPeak = tmp; m_sigPeak = tmp;
update(); update();
} }
void MeterWidget::paintEvent( QPaintEvent * ) void MeterWidget::paintEvent( QPaintEvent * )
{ {
int pos; int pos;
QPainter p; QPainter p;
p.begin(this); p.begin(this);
// Sanitize // Sanitize
m_signal = m_signal < 0 ? 0 : m_signal; m_signal = m_signal < 0 ? 0 : m_signal;
m_signal = m_signal > 60 ? 60 : m_signal; m_signal = m_signal > 60 ? 60 : m_signal;
pos = m_signal * 2; pos = m_signal * 2;
QRect r(0, height() - pos, width(), pos ); QRect r(0, height() - pos, width(), pos );
p.fillRect(r, QColor( 255, 150, 0 )); p.fillRect(r, QColor( 255, 150, 0 ));
// Draw peak hold indicator // Draw peak hold indicator
p.setPen(Qt::black); p.setPen(Qt::black);
pos = m_sigPeak * 2; pos = m_sigPeak * 2;
p.drawLine(0, height() - pos, 10, height() - pos); p.drawLine(0, height() - pos, 10, height() - pos);
} }

View File

@ -1,30 +1,30 @@
#ifndef METERWIDGET_H #ifndef METERWIDGET_H
#define METERWIDGET_H #define METERWIDGET_H
#include <QWidget> #include <QWidget>
#include <QtGui> #include <QtGui>
#include <QQueue> #include <QQueue>
class MeterWidget : public QWidget class MeterWidget : public QWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit MeterWidget(QWidget *parent = 0); explicit MeterWidget(QWidget *parent = 0);
signals: signals:
public slots: public slots:
void setValue(int value); void setValue(int value);
private: private:
QQueue<int> signalQueue; QQueue<int> signalQueue;
int m_signal; int m_signal;
int m_sigPeak; int m_sigPeak;
protected: protected:
void paintEvent( QPaintEvent * ); void paintEvent( QPaintEvent * );
}; };
#endif // METERWIDGET_H #endif // METERWIDGET_H

View File

@ -1,112 +1,112 @@
// KISS Interface for posting spots to PSK Reporter web site // KISS Interface for posting spots to PSK Reporter web site
// Implemented by Edson Pereira PY2SDR // Implemented by Edson Pereira PY2SDR
// //
// Reports will be sent in batch mode every 5 minutes. // Reports will be sent in batch mode every 5 minutes.
#include "psk_reporter.h" #include "psk_reporter.h"
PSK_Reporter::PSK_Reporter(QObject *parent) : PSK_Reporter::PSK_Reporter(QObject *parent) :
QObject(parent), QObject(parent),
m_sequenceNumber(0) m_sequenceNumber(0)
{ {
m_header_h = "000Allllttttttttssssssssiiiiiiii"; m_header_h = "000Allllttttttttssssssssiiiiiiii";
// We use 50E2 and 50E3 for link Id // We use 50E2 and 50E3 for link Id
m_rxInfoDescriptor_h = "0003002C50E200040000" m_rxInfoDescriptor_h = "0003002C50E200040000"
"8002FFFF0000768F" // 2. Rx Call "8002FFFF0000768F" // 2. Rx Call
"8004FFFF0000768F" // 4. Rx Grid "8004FFFF0000768F" // 4. Rx Grid
"8008FFFF0000768F" // 8. Rx Soft "8008FFFF0000768F" // 8. Rx Soft
"8009FFFF0000768F" // 9. Rx Antenna "8009FFFF0000768F" // 9. Rx Antenna
"0000"; "0000";
m_txInfoDescriptor_h = "0002003C50E30007" m_txInfoDescriptor_h = "0002003C50E30007"
"8001FFFF0000768F" // 1. Tx Call "8001FFFF0000768F" // 1. Tx Call
"800500040000768F" // 5. Tx Freq "800500040000768F" // 5. Tx Freq
"800600010000768F" // 6. Tx snr "800600010000768F" // 6. Tx snr
"800AFFFF0000768F" // 10. Tx Mode "800AFFFF0000768F" // 10. Tx Mode
"8003FFFF0000768F" // 3. Tx Grid "8003FFFF0000768F" // 3. Tx Grid
"800B00010000768F" // 11. Tx info src "800B00010000768F" // 11. Tx info src
"00960004"; // Report time "00960004"; // Report time
qsrand(QDateTime::currentDateTime().toTime_t()); qsrand(QDateTime::currentDateTime().toTime_t());
m_randomId_h = QString("%1").arg(qrand(),8,16,QChar('0')); m_randomId_h = QString("%1").arg(qrand(),8,16,QChar('0'));
m_udpSocket = new QUdpSocket(this); m_udpSocket = new QUdpSocket(this);
reportTimer = new QTimer(this); reportTimer = new QTimer(this);
connect(reportTimer, SIGNAL(timeout()), this, SLOT(sendReport())); connect(reportTimer, SIGNAL(timeout()), this, SLOT(sendReport()));
reportTimer->start(5*60*1000); // 5 minutes; reportTimer->start(5*60*1000); // 5 minutes;
} }
void PSK_Reporter::setLocalStation(QString call, QString gridSquare, QString antenna, QString programInfo) void PSK_Reporter::setLocalStation(QString call, QString gridSquare, QString antenna, QString programInfo)
{ {
m_rxCall = call; m_rxCall = call;
m_rxGrid = gridSquare; m_rxGrid = gridSquare;
m_rxAnt = antenna; m_rxAnt = antenna;
m_progId = programInfo; m_progId = programInfo;
//qDebug() << "PSK_Reporter::setLocalStation. Antenna:" << antenna; //qDebug() << "PSK_Reporter::setLocalStation. Antenna:" << antenna;
} }
void PSK_Reporter::addRemoteStation(QString call, QString grid, QString freq, QString mode, QString snr, QString time ) void PSK_Reporter::addRemoteStation(QString call, QString grid, QString freq, QString mode, QString snr, QString time )
{ {
QHash<QString,QString> spot; QHash<QString,QString> spot;
spot["call"] = call; spot["call"] = call;
spot["grid"] = grid; spot["grid"] = grid;
spot["snr"] = snr; spot["snr"] = snr;
spot["freq"] = freq; spot["freq"] = freq;
spot["mode"] = mode; spot["mode"] = mode;
spot["time"] = time; spot["time"] = time;
m_spotQueue.enqueue(spot); m_spotQueue.enqueue(spot);
} }
void PSK_Reporter::sendReport() void PSK_Reporter::sendReport()
{ {
QString report_h; QString report_h;
// Header // Header
QString header_h = m_header_h; QString header_h = m_header_h;
header_h.replace("tttttttt", QString("%1").arg(QDateTime::currentDateTime().toTime_t(),8,16,QChar('0'))); header_h.replace("tttttttt", QString("%1").arg(QDateTime::currentDateTime().toTime_t(),8,16,QChar('0')));
header_h.replace("ssssssss", QString("%1").arg(++m_sequenceNumber,8,16,QChar('0'))); header_h.replace("ssssssss", QString("%1").arg(++m_sequenceNumber,8,16,QChar('0')));
header_h.replace("iiiiiiii", m_randomId_h); header_h.replace("iiiiiiii", m_randomId_h);
// Receiver information // Receiver information
QString rxInfoData_h = "50E2llll"; QString rxInfoData_h = "50E2llll";
rxInfoData_h += QString("%1").arg(m_rxCall.length(),2,16,QChar('0')) + m_rxCall.toUtf8().toHex(); rxInfoData_h += QString("%1").arg(m_rxCall.length(),2,16,QChar('0')) + m_rxCall.toUtf8().toHex();
rxInfoData_h += QString("%1").arg(m_rxGrid.length(),2,16,QChar('0')) + m_rxGrid.toUtf8().toHex(); rxInfoData_h += QString("%1").arg(m_rxGrid.length(),2,16,QChar('0')) + m_rxGrid.toUtf8().toHex();
rxInfoData_h += QString("%1").arg(m_progId.length(),2,16,QChar('0')) + m_progId.toUtf8().toHex(); rxInfoData_h += QString("%1").arg(m_progId.length(),2,16,QChar('0')) + m_progId.toUtf8().toHex();
rxInfoData_h += QString("%1").arg(m_rxAnt.length(),2,16,QChar('0')) + m_rxAnt.toUtf8().toHex(); rxInfoData_h += QString("%1").arg(m_rxAnt.length(),2,16,QChar('0')) + m_rxAnt.toUtf8().toHex();
rxInfoData_h += "0000"; rxInfoData_h += "0000";
rxInfoData_h.replace("50E2llll", "50E2" + QString("%1").arg(rxInfoData_h.length()/2,4,16,QChar('0'))); rxInfoData_h.replace("50E2llll", "50E2" + QString("%1").arg(rxInfoData_h.length()/2,4,16,QChar('0')));
// Sender information // Sender information
if (! m_spotQueue.isEmpty()) { if (! m_spotQueue.isEmpty()) {
QString txInfoData_h = "50E3llll"; QString txInfoData_h = "50E3llll";
while (!m_spotQueue.isEmpty()) { while (!m_spotQueue.isEmpty()) {
QHash<QString,QString> spot = m_spotQueue.dequeue(); QHash<QString,QString> spot = m_spotQueue.dequeue();
txInfoData_h += QString("%1").arg(spot["call"].length(),2,16,QChar('0')) + spot["call"].toUtf8().toHex(); txInfoData_h += QString("%1").arg(spot["call"].length(),2,16,QChar('0')) + spot["call"].toUtf8().toHex();
txInfoData_h += QString("%1").arg(spot["freq"].toLongLong(),8,16,QChar('0')); txInfoData_h += QString("%1").arg(spot["freq"].toLongLong(),8,16,QChar('0'));
txInfoData_h += QString("%1").arg(spot["snr"].toInt(),8,16,QChar('0')).right(2); txInfoData_h += QString("%1").arg(spot["snr"].toInt(),8,16,QChar('0')).right(2);
txInfoData_h += QString("%1").arg(spot["mode"].length(),2,16,QChar('0')) + spot["mode"].toUtf8().toHex(); txInfoData_h += QString("%1").arg(spot["mode"].length(),2,16,QChar('0')) + spot["mode"].toUtf8().toHex();
txInfoData_h += QString("%1").arg(spot["grid"].length(),2,16,QChar('0')) + spot["grid"].toUtf8().toHex(); txInfoData_h += QString("%1").arg(spot["grid"].length(),2,16,QChar('0')) + spot["grid"].toUtf8().toHex();
txInfoData_h += QString("%1").arg(1,2,16,QChar('0')); // REPORTER_SOURCE_AUTOMATIC txInfoData_h += QString("%1").arg(1,2,16,QChar('0')); // REPORTER_SOURCE_AUTOMATIC
txInfoData_h += QString("%1").arg(spot["time"].toInt(),8,16,QChar('0')); txInfoData_h += QString("%1").arg(spot["time"].toInt(),8,16,QChar('0'));
} }
txInfoData_h += "0000"; txInfoData_h += "0000";
txInfoData_h.replace("50E3llll", "50E3" + QString("%1").arg(txInfoData_h.length()/2,4,16,QChar('0'))); txInfoData_h.replace("50E3llll", "50E3" + QString("%1").arg(txInfoData_h.length()/2,4,16,QChar('0')));
report_h = header_h + m_rxInfoDescriptor_h + m_txInfoDescriptor_h + rxInfoData_h + txInfoData_h; report_h = header_h + m_rxInfoDescriptor_h + m_txInfoDescriptor_h + rxInfoData_h + txInfoData_h;
//qDebug() << "Sending Report TX: "; //qDebug() << "Sending Report TX: ";
} else { } else {
report_h = header_h + m_rxInfoDescriptor_h + rxInfoData_h; report_h = header_h + m_rxInfoDescriptor_h + rxInfoData_h;
//qDebug() << "Sending Report RX: "; //qDebug() << "Sending Report RX: ";
} }
report_h.replace("000Allll", "000A" + QString("%1").arg(report_h.length()/2,4,16,QChar('0'))); report_h.replace("000Allll", "000A" + QString("%1").arg(report_h.length()/2,4,16,QChar('0')));
QByteArray report = QByteArray::fromHex(report_h.toUtf8()); QByteArray report = QByteArray::fromHex(report_h.toUtf8());
// Get IP address for pskreporter.info and send report via UDP // Get IP address for pskreporter.info and send report via UDP
QHostInfo info = QHostInfo::fromName("report.pskreporter.info"); QHostInfo info = QHostInfo::fromName("report.pskreporter.info");
m_udpSocket->writeDatagram(report,info.addresses().at(0),4739); m_udpSocket->writeDatagram(report,info.addresses().at(0),4739);
} }

View File

@ -1,42 +1,42 @@
#ifndef PSK_REPORTER_H #ifndef PSK_REPORTER_H
#define PSK_REPORTER_H #define PSK_REPORTER_H
#include <QtCore> #include <QtCore>
#include <QUdpSocket> #include <QUdpSocket>
#include <QHostInfo> #include <QHostInfo>
class PSK_Reporter : public QObject class PSK_Reporter : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit PSK_Reporter(QObject *parent = 0); explicit PSK_Reporter(QObject *parent = 0);
void setLocalStation(QString call, QString grid, QString antenna, QString programInfo); void setLocalStation(QString call, QString grid, QString antenna, QString programInfo);
void addRemoteStation(QString call, QString grid, QString freq, QString mode, QString snr, QString time); void addRemoteStation(QString call, QString grid, QString freq, QString mode, QString snr, QString time);
signals: signals:
public slots: public slots:
void sendReport(); void sendReport();
private: private:
QString m_header_h; QString m_header_h;
QString m_rxInfoDescriptor_h; QString m_rxInfoDescriptor_h;
QString m_txInfoDescriptor_h; QString m_txInfoDescriptor_h;
QString m_randomId_h; QString m_randomId_h;
QString m_linkId_h; QString m_linkId_h;
QString m_rxCall; QString m_rxCall;
QString m_rxGrid; QString m_rxGrid;
QString m_rxAnt; QString m_rxAnt;
QString m_progId; QString m_progId;
QQueue< QHash<QString,QString> > m_spotQueue; QQueue< QHash<QString,QString> > m_spotQueue;
QUdpSocket *m_udpSocket; QUdpSocket *m_udpSocket;
QTimer *reportTimer; QTimer *reportTimer;
int m_sequenceNumber; int m_sequenceNumber;
}; };
#endif // PSK_REPORTER_H #endif // PSK_REPORTER_H

View File

@ -1,332 +1,332 @@
/** /**
* \file src/rigclass.cc * \file src/rigclass.cc
* \brief Ham Radio Control Libraries C++ interface * \brief Ham Radio Control Libraries C++ interface
* \author Stephane Fillod * \author Stephane Fillod
* \date 2001-2003 * \date 2001-2003
* *
* Hamlib C++ interface is a frontend implementing wrapper functions. * Hamlib C++ interface is a frontend implementing wrapper functions.
*/ */
/** /**
* *
* Hamlib C++ bindings - main file * Hamlib C++ bindings - main file
* Copyright (c) 2001-2003 by Stephane Fillod * Copyright (c) 2001-2003 by Stephane Fillod
* *
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either * License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version. * version 2.1 of the License, or (at your option) any later version.
* *
* This library is distributed in the hope that it will be useful, * This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details. * Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software * License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* *
*/ */
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
#include <hamlib/rig.h> #include <hamlib/rig.h>
#include "rigclass.h" #include "rigclass.h"
#include <QDebug> #include <QDebug>
#include <QHostAddress> #include <QHostAddress>
#define NUMTRIES 5 #define NUMTRIES 5
static int hamlibpp_freq_event(RIG *rig, vfo_t vfo, freq_t freq, rig_ptr_t arg); static int hamlibpp_freq_event(RIG *rig, vfo_t vfo, freq_t freq, rig_ptr_t arg);
static int hamlibpp_freq_event(RIG *rig, vfo_t vfo, freq_t freq, rig_ptr_t arg) static int hamlibpp_freq_event(RIG *rig, vfo_t vfo, freq_t freq, rig_ptr_t arg)
{ {
if (!rig || !rig->state.obj) if (!rig || !rig->state.obj)
return -RIG_EINVAL; return -RIG_EINVAL;
/* assert rig == ((Rig*)rig->state.obj).theRig */ /* assert rig == ((Rig*)rig->state.obj).theRig */
return ((Rig*)rig->state.obj)->FreqEvent(vfo, freq, arg); return ((Rig*)rig->state.obj)->FreqEvent(vfo, freq, arg);
} }
Rig::Rig() Rig::Rig()
{ {
rig_set_debug_level( RIG_DEBUG_WARN); rig_set_debug_level( RIG_DEBUG_WARN);
} }
Rig::~Rig() { Rig::~Rig() {
theRig->state.obj = NULL; theRig->state.obj = NULL;
rig_cleanup(theRig); rig_cleanup(theRig);
caps = NULL; caps = NULL;
} }
int Rig::init(rig_model_t rig_model) int Rig::init(rig_model_t rig_model)
{ {
int initOk; int initOk;
theRig = rig_init(rig_model); theRig = rig_init(rig_model);
if (!theRig) if (!theRig)
initOk = false; initOk = false;
else else
initOk = true; initOk = true;
caps = theRig->caps; caps = theRig->caps;
theRig->callbacks.freq_event = &hamlibpp_freq_event; theRig->callbacks.freq_event = &hamlibpp_freq_event;
theRig->state.obj = (rig_ptr_t)this; theRig->state.obj = (rig_ptr_t)this;
return initOk; return initOk;
} }
int Rig::open(int n) { int Rig::open(int n) {
m_hrd=false; m_hrd=false;
m_cmndr=false; m_cmndr=false;
if(n<9900) { if(n<9900) {
if(n==-99999) return -1; //Silence compiler warning if(n==-99999) return -1; //Silence compiler warning
return rig_open(theRig); return rig_open(theRig);
} }
#ifdef WIN32 // Ham radio Deluxe or Commander (Windows only) #ifdef WIN32 // Ham radio Deluxe or Commander (Windows only)
if(n==9999) { if(n==9999) {
m_hrd=true; m_hrd=true;
bool bConnect=false; bool bConnect=false;
bConnect = HRDInterfaceConnect(L"localhost",7809); bConnect = HRDInterfaceConnect(L"localhost",7809);
if(bConnect) { if(bConnect) {
const wchar_t* context=HRDInterfaceSendMessage(L"Get Context"); const wchar_t* context=HRDInterfaceSendMessage(L"Get Context");
m_context="[" + QString::fromWCharArray (context,-1) + "] "; m_context="[" + QString::fromWCharArray (context,-1) + "] ";
HRDInterfaceFreeString(context); HRDInterfaceFreeString(context);
return 0; return 0;
} else { } else {
m_hrd=false; m_hrd=false;
return -1; return -1;
} }
} }
if(n==9998) { if(n==9998) {
if(commanderSocket->state()==QAbstractSocket::ConnectedState) { if(commanderSocket->state()==QAbstractSocket::ConnectedState) {
commanderSocket->abort(); commanderSocket->abort();
} }
if(commanderSocket->state()==QAbstractSocket::UnconnectedState) { if(commanderSocket->state()==QAbstractSocket::UnconnectedState) {
commanderSocket->connectToHost(QHostAddress::LocalHost, 52002); commanderSocket->connectToHost(QHostAddress::LocalHost, 52002);
if(!commanderSocket->waitForConnected(1000)) { if(!commanderSocket->waitForConnected(1000)) {
return -1; return -1;
} }
} }
QString t; QString t;
t="<command:10>CmdGetFreq<parameters:0>"; t="<command:10>CmdGetFreq<parameters:0>";
QByteArray ba = t.toLocal8Bit(); QByteArray ba = t.toLocal8Bit();
const char* buf=ba.data(); const char* buf=ba.data();
commanderSocket->write(buf); commanderSocket->write(buf);
commanderSocket->waitForReadyRead(1000); commanderSocket->waitForReadyRead(1000);
QByteArray reply=commanderSocket->read(128); QByteArray reply=commanderSocket->read(128);
if(reply.indexOf("<CmdFreq:")==0) { if(reply.indexOf("<CmdFreq:")==0) {
m_cmndr=true; m_cmndr=true;
return 0; return 0;
} }
} }
#endif #endif
return -1; return -1;
} }
int Rig::close(void) { int Rig::close(void) {
#ifdef WIN32 // Ham Radio Deluxe only on Windows #ifdef WIN32 // Ham Radio Deluxe only on Windows
if(m_hrd) { if(m_hrd) {
HRDInterfaceDisconnect(); HRDInterfaceDisconnect();
return 0; return 0;
} else if(m_cmndr) { } else if(m_cmndr) {
commanderSocket->close(); commanderSocket->close();
return 0; return 0;
} else } else
#endif #endif
{ {
return rig_close(theRig); return rig_close(theRig);
} }
} }
int Rig::setConf(const char *name, const char *val) int Rig::setConf(const char *name, const char *val)
{ {
return rig_set_conf(theRig, tokenLookup(name), val); return rig_set_conf(theRig, tokenLookup(name), val);
} }
int Rig::setFreq(freq_t freq, vfo_t vfo) { int Rig::setFreq(freq_t freq, vfo_t vfo) {
#ifdef WIN32 // Ham Radio Deluxe (only on Windows) #ifdef WIN32 // Ham Radio Deluxe (only on Windows)
if(m_hrd) { if(m_hrd) {
QString t; QString t;
int nhz=(int)freq; int nhz=(int)freq;
t=m_context + "Set Frequency-Hz " + QString::number(nhz); t=m_context + "Set Frequency-Hz " + QString::number(nhz);
const wchar_t* cmnd = (const wchar_t*) t.utf16(); const wchar_t* cmnd = (const wchar_t*) t.utf16();
const wchar_t* result=HRDInterfaceSendMessage(cmnd); const wchar_t* result=HRDInterfaceSendMessage(cmnd);
QString t2=QString::fromWCharArray (result,-1); QString t2=QString::fromWCharArray (result,-1);
HRDInterfaceFreeString(result); HRDInterfaceFreeString(result);
if(t2=="OK") { if(t2=="OK") {
return 0; return 0;
} else { } else {
return -1; return -1;
} }
} else if(m_cmndr) { } else if(m_cmndr) {
QString t; QString t;
double f=0.001*freq; double f=0.001*freq;
t.sprintf("<command:10>CmdSetFreq<parameters:23><xcvrfreq:10>%10.3f",f); t.sprintf("<command:10>CmdSetFreq<parameters:23><xcvrfreq:10>%10.3f",f);
QLocale locale; QLocale locale;
t.replace(".",locale.decimalPoint()); t.replace(".",locale.decimalPoint());
QByteArray ba = t.toLocal8Bit(); QByteArray ba = t.toLocal8Bit();
const char* buf=ba.data(); const char* buf=ba.data();
commanderSocket->write(buf); commanderSocket->write(buf);
commanderSocket->waitForBytesWritten(1000); commanderSocket->waitForBytesWritten(1000);
return 0; return 0;
} else } else
#endif #endif
{ {
return rig_set_freq(theRig, vfo, freq); return rig_set_freq(theRig, vfo, freq);
} }
} }
int Rig::setXit(shortfreq_t xit, vfo_t vfo) int Rig::setXit(shortfreq_t xit, vfo_t vfo)
{ {
return rig_set_xit(theRig, vfo, xit); return rig_set_xit(theRig, vfo, xit);
} }
int Rig::setVFO(vfo_t vfo) int Rig::setVFO(vfo_t vfo)
{ {
return rig_set_vfo(theRig, vfo); return rig_set_vfo(theRig, vfo);
} }
vfo_t Rig::getVFO() vfo_t Rig::getVFO()
{ {
vfo_t vfo; vfo_t vfo;
rig_get_vfo(theRig, &vfo); rig_get_vfo(theRig, &vfo);
return vfo; return vfo;
} }
int Rig::setSplitFreq(freq_t tx_freq, vfo_t vfo) { int Rig::setSplitFreq(freq_t tx_freq, vfo_t vfo) {
#ifdef WIN32 // Ham Radio Deluxe only on Windows #ifdef WIN32 // Ham Radio Deluxe only on Windows
if(m_hrd) { if(m_hrd) {
QString t; QString t;
int nhz=(int)tx_freq; int nhz=(int)tx_freq;
t=m_context + "Set Frequency-Hz " + QString::number(nhz); t=m_context + "Set Frequency-Hz " + QString::number(nhz);
const wchar_t* cmnd = (const wchar_t*) t.utf16(); const wchar_t* cmnd = (const wchar_t*) t.utf16();
const wchar_t* result=HRDInterfaceSendMessage(cmnd); const wchar_t* result=HRDInterfaceSendMessage(cmnd);
QString t2=QString::fromWCharArray (result,-1); QString t2=QString::fromWCharArray (result,-1);
HRDInterfaceFreeString(result); HRDInterfaceFreeString(result);
if(t2=="OK") { if(t2=="OK") {
return 0; return 0;
} else { } else {
return -1; return -1;
} }
} else if(m_cmndr) { } else if(m_cmndr) {
QString t; QString t;
double f=0.001*tx_freq; double f=0.001*tx_freq;
t.sprintf("<command:12>CmdSetTxFreq<parameters:23><xcvrfreq:10>%10.3f",f); t.sprintf("<command:12>CmdSetTxFreq<parameters:23><xcvrfreq:10>%10.3f",f);
QLocale locale; QLocale locale;
t.replace(".",locale.decimalPoint()); t.replace(".",locale.decimalPoint());
QByteArray ba = t.toLocal8Bit(); QByteArray ba = t.toLocal8Bit();
const char* buf=ba.data(); const char* buf=ba.data();
commanderSocket->write(buf); commanderSocket->write(buf);
commanderSocket->waitForBytesWritten(1000); commanderSocket->waitForBytesWritten(1000);
return 0; return 0;
} else } else
#endif #endif
{ {
return rig_set_split_freq(theRig, vfo, tx_freq); return rig_set_split_freq(theRig, vfo, tx_freq);
} }
} }
freq_t Rig::getFreq(vfo_t vfo) freq_t Rig::getFreq(vfo_t vfo)
{ {
freq_t freq; freq_t freq;
#ifdef WIN32 // Ham Radio Deluxe (only on Windows) #ifdef WIN32 // Ham Radio Deluxe (only on Windows)
if(m_hrd) { if(m_hrd) {
const wchar_t* cmnd = (const wchar_t*) (m_context+"Get Frequency").utf16(); const wchar_t* cmnd = (const wchar_t*) (m_context+"Get Frequency").utf16();
const wchar_t* freqString=HRDInterfaceSendMessage(cmnd); const wchar_t* freqString=HRDInterfaceSendMessage(cmnd);
QString t2=QString::fromWCharArray (freqString,-1); QString t2=QString::fromWCharArray (freqString,-1);
HRDInterfaceFreeString(freqString); HRDInterfaceFreeString(freqString);
freq=t2.toDouble(); freq=t2.toDouble();
return freq; return freq;
} else if(m_cmndr) { } else if(m_cmndr) {
QString t; QString t;
t="<command:10>CmdGetFreq<parameters:0>"; t="<command:10>CmdGetFreq<parameters:0>";
QByteArray ba = t.toLocal8Bit(); QByteArray ba = t.toLocal8Bit();
const char* buf=ba.data(); const char* buf=ba.data();
commanderSocket->write(buf); commanderSocket->write(buf);
commanderSocket->waitForReadyRead(1000); commanderSocket->waitForReadyRead(1000);
QByteArray reply=commanderSocket->read(128); QByteArray reply=commanderSocket->read(128);
QString t2(reply); QString t2(reply);
if(t2.indexOf("<CmdFreq:")==0) { if(t2.indexOf("<CmdFreq:")==0) {
int i1=t2.indexOf(">"); int i1=t2.indexOf(">");
t2=t2.mid(i1+1).replace(",",""); t2=t2.mid(i1+1).replace(",","");
freq=1000.0*t2.toDouble(); freq=1000.0*t2.toDouble();
return freq; return freq;
} else { } else {
return -1.0; return -1.0;
} }
} else } else
#endif #endif
{ {
freq=-1.0; freq=-1.0;
for(int i=0; i<NUMTRIES; i++) { for(int i=0; i<NUMTRIES; i++) {
int iret=rig_get_freq(theRig, vfo, &freq); int iret=rig_get_freq(theRig, vfo, &freq);
if(iret==RIG_OK) break; if(iret==RIG_OK) break;
} }
return freq; return freq;
} }
} }
int Rig::setMode(rmode_t mode, pbwidth_t width, vfo_t vfo) { int Rig::setMode(rmode_t mode, pbwidth_t width, vfo_t vfo) {
return rig_set_mode(theRig, vfo, mode, width); return rig_set_mode(theRig, vfo, mode, width);
} }
rmode_t Rig::getMode(pbwidth_t& width, vfo_t vfo) { rmode_t Rig::getMode(pbwidth_t& width, vfo_t vfo) {
rmode_t mode; rmode_t mode;
rig_get_mode(theRig, vfo, &mode, &width); rig_get_mode(theRig, vfo, &mode, &width);
return mode; return mode;
} }
int Rig::setPTT(ptt_t ptt, vfo_t vfo) int Rig::setPTT(ptt_t ptt, vfo_t vfo)
{ {
#ifdef WIN32 // Ham Radio Deluxe only on Windows #ifdef WIN32 // Ham Radio Deluxe only on Windows
if(m_hrd) { if(m_hrd) {
wchar_t* cmnd; wchar_t* cmnd;
if(ptt==0) { if(ptt==0) {
cmnd = (wchar_t*) (m_context + cmnd = (wchar_t*) (m_context +
"Set Button-Select TX 0").utf16(); "Set Button-Select TX 0").utf16();
} else { } else {
cmnd = (wchar_t*) (m_context + cmnd = (wchar_t*) (m_context +
"Set Button-Select TX 1").utf16(); "Set Button-Select TX 1").utf16();
} }
const wchar_t* result=HRDInterfaceSendMessage(cmnd); const wchar_t* result=HRDInterfaceSendMessage(cmnd);
QString t2=QString::fromWCharArray (result,-1); QString t2=QString::fromWCharArray (result,-1);
HRDInterfaceFreeString(result); HRDInterfaceFreeString(result);
if(t2=="OK") { if(t2=="OK") {
return 0; return 0;
} else { } else {
return -1; return -1;
} }
} else if(m_cmndr) { } else if(m_cmndr) {
QString t; QString t;
if(ptt==0) t="<command:5>CmdRX<parameters:0>"; if(ptt==0) t="<command:5>CmdRX<parameters:0>";
if(ptt>0) t="<command:5>CmdTX<parameters:0>"; if(ptt>0) t="<command:5>CmdTX<parameters:0>";
QByteArray ba = t.toLocal8Bit(); QByteArray ba = t.toLocal8Bit();
const char* buf=ba.data(); const char* buf=ba.data();
commanderSocket->write(buf); commanderSocket->write(buf);
commanderSocket->waitForBytesWritten(1000); commanderSocket->waitForBytesWritten(1000);
return 0; return 0;
} else } else
#endif #endif
{ {
return rig_set_ptt(theRig, vfo, ptt); return rig_set_ptt(theRig, vfo, ptt);
} }
} }
ptt_t Rig::getPTT(vfo_t vfo) ptt_t Rig::getPTT(vfo_t vfo)
{ {
ptt_t ptt; ptt_t ptt;
rig_get_ptt(theRig, vfo, &ptt); rig_get_ptt(theRig, vfo, &ptt);
return ptt; return ptt;
} }
token_t Rig::tokenLookup(const char *name) token_t Rig::tokenLookup(const char *name)
{ {
return rig_token_lookup(theRig, name); return rig_token_lookup(theRig, name);
} }

View File

@ -1,98 +1,98 @@
/* /*
* Hamlib C++ bindings - API header * Hamlib C++ bindings - API header
* Copyright (c) 2001-2002 by Stephane Fillod * Copyright (c) 2001-2002 by Stephane Fillod
* *
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either * License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version. * version 2.1 of the License, or (at your option) any later version.
* *
* This library is distributed in the hope that it will be useful, * This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details. * Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software * License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* *
*/ */
#ifndef _RIGCLASS_H #ifndef _RIGCLASS_H
#define _RIGCLASS_H 1 #define _RIGCLASS_H 1
#include <hamlib/rig.h> #include <hamlib/rig.h>
#include <iostream> #include <iostream>
#include <QString> #include <QString>
#include <QTcpSocket> #include <QTcpSocket>
extern QTcpSocket* commanderSocket; extern QTcpSocket* commanderSocket;
class BACKEND_IMPEXP Rig { class BACKEND_IMPEXP Rig {
private: private:
RIG* theRig; // Global ref. to the rig RIG* theRig; // Global ref. to the rig
bool m_hrd; bool m_hrd;
bool m_cmndr; bool m_cmndr;
QString m_context; QString m_context;
protected: protected:
public: public:
Rig(); Rig();
virtual ~Rig(); virtual ~Rig();
const struct rig_caps *caps; const struct rig_caps *caps;
// Initialize rig // Initialize rig
int init(rig_model_t rig_model); int init(rig_model_t rig_model);
// This method open the communication port to the rig // This method open the communication port to the rig
int open(int n); int open(int n);
// This method close the communication port to the rig // This method close the communication port to the rig
int close(void); int close(void);
int setConf(const char *name, const char *val); int setConf(const char *name, const char *val);
token_t tokenLookup(const char *name); token_t tokenLookup(const char *name);
int setFreq(freq_t freq, vfo_t vfo = RIG_VFO_CURR); int setFreq(freq_t freq, vfo_t vfo = RIG_VFO_CURR);
freq_t getFreq(vfo_t vfo = RIG_VFO_CURR); freq_t getFreq(vfo_t vfo = RIG_VFO_CURR);
int setMode(rmode_t, pbwidth_t width = RIG_PASSBAND_NORMAL, vfo_t vfo = RIG_VFO_CURR); int setMode(rmode_t, pbwidth_t width = RIG_PASSBAND_NORMAL, vfo_t vfo = RIG_VFO_CURR);
rmode_t getMode(pbwidth_t&, vfo_t vfo = RIG_VFO_CURR); rmode_t getMode(pbwidth_t&, vfo_t vfo = RIG_VFO_CURR);
int setVFO(vfo_t); int setVFO(vfo_t);
vfo_t getVFO(); vfo_t getVFO();
int setXit(shortfreq_t xit, vfo_t vfo); int setXit(shortfreq_t xit, vfo_t vfo);
int setSplitFreq(freq_t tx_freq, vfo_t vfo = RIG_VFO_CURR); int setSplitFreq(freq_t tx_freq, vfo_t vfo = RIG_VFO_CURR);
int setPTT (ptt_t ptt, vfo_t vfo = RIG_VFO_CURR); int setPTT (ptt_t ptt, vfo_t vfo = RIG_VFO_CURR);
ptt_t getPTT (vfo_t vfo = RIG_VFO_CURR); ptt_t getPTT (vfo_t vfo = RIG_VFO_CURR);
// callbacks available in your derived object // callbacks available in your derived object
virtual int FreqEvent(vfo_t, freq_t, rig_ptr_t) const { virtual int FreqEvent(vfo_t, freq_t, rig_ptr_t) const {
return RIG_OK; return RIG_OK;
} }
virtual int ModeEvent(vfo_t, rmode_t, pbwidth_t, rig_ptr_t) const { virtual int ModeEvent(vfo_t, rmode_t, pbwidth_t, rig_ptr_t) const {
return RIG_OK; return RIG_OK;
} }
virtual int VFOEvent(vfo_t, rig_ptr_t) const { virtual int VFOEvent(vfo_t, rig_ptr_t) const {
return RIG_OK; return RIG_OK;
} }
virtual int PTTEvent(vfo_t, ptt_t, rig_ptr_t) const { virtual int PTTEvent(vfo_t, ptt_t, rig_ptr_t) const {
return RIG_OK; return RIG_OK;
} }
virtual int DCDEvent(vfo_t, dcd_t, rig_ptr_t) const { virtual int DCDEvent(vfo_t, dcd_t, rig_ptr_t) const {
return RIG_OK; return RIG_OK;
} }
}; };
#ifdef WIN32 #ifdef WIN32
extern "C" { extern "C" {
bool HRDInterfaceConnect(const wchar_t *host, const ushort); bool HRDInterfaceConnect(const wchar_t *host, const ushort);
void HRDInterfaceDisconnect(); void HRDInterfaceDisconnect();
bool HRDInterfaceIsConnected(); bool HRDInterfaceIsConnected();
wchar_t* HRDInterfaceSendMessage(const wchar_t *msg); wchar_t* HRDInterfaceSendMessage(const wchar_t *msg);
void HRDInterfaceFreeString(const wchar_t *lstring); void HRDInterfaceFreeString(const wchar_t *lstring);
} }
#endif #endif
#endif // _RIGCLASS_H #endif // _RIGCLASS_H

View File

@ -1,53 +1,53 @@
// Simple bargraph dB meter // Simple bargraph dB meter
// Implemented by Edson Pereira PY2SDR // Implemented by Edson Pereira PY2SDR
// //
// Limits and geometry are hardcded for now. // Limits and geometry are hardcded for now.
#include "signalmeter.h" #include "signalmeter.h"
SignalMeter::SignalMeter(QWidget *parent) : SignalMeter::SignalMeter(QWidget *parent) :
QWidget(parent) QWidget(parent)
{ {
resize(parent->size()); resize(parent->size());
m_meter = new MeterWidget(this); m_meter = new MeterWidget(this);
m_meter->setGeometry(10, 10, 10, 120); m_meter->setGeometry(10, 10, 10, 120);
m_label = new QLabel(this); m_label = new QLabel(this);
m_label->setGeometry(10, 135, 20, 20); m_label->setGeometry(10, 135, 20, 20);
QLabel *dbLabel = new QLabel(this); QLabel *dbLabel = new QLabel(this);
dbLabel->setText("dB"); dbLabel->setText("dB");
dbLabel->setGeometry(30, 135, 20, 20); dbLabel->setGeometry(30, 135, 20, 20);
} }
SignalMeter::~SignalMeter() SignalMeter::~SignalMeter()
{ {
} }
void SignalMeter::paintEvent( QPaintEvent * ) void SignalMeter::paintEvent( QPaintEvent * )
{ {
QPainter p; QPainter p;
p.begin(this); p.begin(this);
p.drawLine(22, 10, 22, 130); p.drawLine(22, 10, 22, 130);
for ( int i = 0; i <= 60; i += 10 ) { for ( int i = 0; i <= 60; i += 10 ) {
p.drawLine(22, i*2 + 10, 25, i*2 + 10); p.drawLine(22, i*2 + 10, 25, i*2 + 10);
} }
for ( int i = 10; i < 60; i += 10 ) { for ( int i = 10; i < 60; i += 10 ) {
p.drawText(30, i*2 + 15, QString::number(60 - i)); p.drawText(30, i*2 + 15, QString::number(60 - i));
} }
} }
void SignalMeter::setValue(int value) void SignalMeter::setValue(int value)
{ {
m_meter->setValue(value); m_meter->setValue(value);
m_label->setText(QString::number(value)); m_label->setText(QString::number(value));
} }
void SignalMeter::resizeEvent(QResizeEvent *s) void SignalMeter::resizeEvent(QResizeEvent *s)
{ {
resize(s->size()); resize(s->size());
} }

View File

@ -1,32 +1,32 @@
#ifndef SIGNALMETER_H #ifndef SIGNALMETER_H
#define SIGNALMETER_H #define SIGNALMETER_H
#include <QtGui> #include <QtGui>
#include <QLabel> #include <QLabel>
#include <meterwidget.h> #include <meterwidget.h>
class SignalMeter : public QWidget class SignalMeter : public QWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit SignalMeter(QWidget *parent = 0); explicit SignalMeter(QWidget *parent = 0);
~SignalMeter(); ~SignalMeter();
public slots: public slots:
void setValue(int value); void setValue(int value);
private: private:
MeterWidget *m_meter; MeterWidget *m_meter;
QLabel *m_label; QLabel *m_label;
int m_signal; int m_signal;
int m_sigPeak; int m_sigPeak;
protected: protected:
void paintEvent( QPaintEvent * ); void paintEvent( QPaintEvent * );
void resizeEvent(QResizeEvent *s); void resizeEvent(QResizeEvent *s);
}; };
#endif // SIGNALMETER_H #endif // SIGNALMETER_H

View File

@ -1,375 +1,127 @@
#ifndef QAUDIO_INPUT
#include "soundin.h" #include "soundin.h"
#include <QDateTime> #include <QAudioDeviceInfo>
#include <QAudioFormat>
#include <QAudioInput>
#include <QDebug> #include <QDebug>
#define FRAMES_PER_BUFFER 1024 bool SoundInput::audioError () const
#define NSMAX 6827
#define NTMAX 120
extern "C" {
#include <portaudio.h>
extern struct {
float ss[184*NSMAX]; //This is "common/jt9com/..." in fortran
float savg[NSMAX];
// float c0[2*NTMAX*1500];
short int d2[NTMAX*12000];
int nutc; //UTC as integer, HHMM
int ndiskdat; //1 ==> data read from *.wav file
int ntrperiod; //TR period (seconds)
int mousefqso; //User-selected QSO freq (kHz)
int newdat; //1 ==> new data, must do long FFT
int npts8; //npts in c0() array
int nfa; //Low decode limit (Hz)
int nfb; //High decode limit (Hz)
int ntol; //+/- decoding range around fQSO (Hz)
int kin;
int nzhsym;
int nsave;
int nagain;
int ndepth;
int ntxmode;
int nmode;
char datetime[20];
} jt9com_;
}
//--------------------------------------------------------------- a2dCallback
int a2dCallback( const void *inputBuffer, void * /* outputBuffer */,
unsigned long framesToProcess,
const PaStreamCallbackTimeInfo * /* timeInfo */,
PaStreamCallbackFlags statusFlags,
void *userData )
// This routine called by the PortAudio engine when samples are available.
// It may be called at interrupt level, so don't do anything
// that could mess up the system like calling malloc() or free().
{ {
SoundInput::CallbackData * udata = reinterpret_cast<SoundInput::CallbackData *>(userData); bool result (true);
int nbytes,k;
if( (statusFlags&paInputOverflow) != 0) { Q_ASSERT_X (m_stream, "SoundInput", "programming error");
qDebug() << "Input Overflow in a2dCallback"; if (m_stream)
} {
if(udata->bzero) switch (m_stream->error ())
{ //Start of a new Rx sequence {
udata->kin = 0; //Reset buffer pointer case QAudio::OpenError:
udata->bzero = false; Q_EMIT error (tr ("An error opening the audio input device has occurred."));
break;
case QAudio::IOError:
Q_EMIT error (tr ("An error occurred during read from the audio input device."));
break;
case QAudio::UnderrunError:
Q_EMIT error (tr ("Audio data not being fed to the audio input device fast enough."));
break;
case QAudio::FatalError:
Q_EMIT error (tr ("Non-recoverable error, audio input device not usable at this time."));
break;
case QAudio::NoError:
result = false;
break;
}
} }
return result;
nbytes=2*framesToProcess; //Bytes per frame
k=udata->kin;
if(udata->monitoring) {
memcpy(&jt9com_.d2[k],inputBuffer,nbytes); //Copy all samples to d2
}
udata->kin+=framesToProcess;
jt9com_.kin=udata->kin; // we are the only writer to jt9com_ so no MT issue here
return paContinue;
} }
SoundInput::SoundInput() bool SoundInput::start(QAudioDeviceInfo const& device, int framesPerBuffer, QIODevice * sink)
: m_inStream(0),
m_TRperiod(60),
m_nsps(6912),
m_monitoring(false),
m_intervalTimer(this)
{
connect(&m_intervalTimer, SIGNAL(timeout()), this,SLOT(intervalNotify()));
}
void SoundInput::start(qint32 device)
{ {
stop(); stop();
//---------------------------------------------------- Soundcard Setup QAudioFormat format (device.preferredFormat());
PaError paerr; format.setChannelCount (1);
PaStreamParameters inParam; format.setCodec ("audio/pcm");
format.setSampleRate (12000);
format.setSampleType (QAudioFormat::SignedInt);
format.setSampleSize (16);
m_callbackData.kin = 0; //Buffer pointer if (!format.isValid ())
m_callbackData.bzero = false; //Flag to request reset of kin
m_callbackData.monitoring = m_monitoring;
inParam.device=device; //### Input Device Number ###
inParam.channelCount=1; //Number of analog channels
inParam.sampleFormat=paInt16; //Get i*2 from Portaudio
inParam.suggestedLatency=0.05;
inParam.hostApiSpecificStreamInfo=NULL;
paerr=Pa_IsFormatSupported(&inParam,NULL,12000.0);
if(paerr<0) {
emit error("PortAudio says requested soundcard format not supported.");
}
paerr=Pa_OpenStream(&m_inStream, //Input stream
&inParam, //Input parameters
NULL, //No output parameters
12000.0, //Sample rate
FRAMES_PER_BUFFER, //Frames per buffer
// paClipOff+paDitherOff, //No clipping or dithering
paClipOff, //No clipping
a2dCallback, //Input callback routine
&m_callbackData); //userdata
paerr=Pa_StartStream(m_inStream);
if(paerr<0) {
emit error("Failed to start audio input stream.");
return;
}
m_ntr0 = 99; // initial value higher than any expected
m_intervalTimer.start(100);
m_ms0 = QDateTime::currentMSecsSinceEpoch();
m_nsps0 = 0;
}
void SoundInput::intervalNotify()
{
m_callbackData.monitoring = m_monitoring; // update monitoring
// status
qint64 ms = QDateTime::currentMSecsSinceEpoch();
ms=ms % 86400000;
int nsec = ms/1000; // Time according to this computer
int ntr = nsec % m_TRperiod;
int k=m_callbackData.kin; // get a copy of kin to mitigate the
// potential race condition with the
// callback handler when a buffer
// reset is requested below
// Reset buffer pointer and symbol number at start of minute
if(ntr < m_ntr0 or !m_monitoring or m_nsps!=m_nsps0) {
m_nstep0=0;
m_nsps0=m_nsps;
m_callbackData.bzero = true; // request callback to reset buffer pointer
}
if(m_monitoring) {
int kstep=m_nsps/2;
// m_step=k/kstep;
m_step=(k-1)/kstep;
if(m_step != m_nstep0) {
emit readyForFFT(k-1); //Signal to compute new FFTs
m_nstep0=m_step;
}
}
m_ntr0=ntr;
}
SoundInput::~SoundInput()
{
if (m_inStream)
{ {
Pa_CloseStream(m_inStream), m_inStream = 0; Q_EMIT error (tr ("Requested input audio format is not valid."));
return false;
}
// this function lies!
// if (!device.isFormatSupported (format))
// {
// Q_EMIT error (tr ("Requested input audio format is not supported on device."));
// return false;
// }
m_stream.reset (new QAudioInput (device, format, this));
if (audioError ())
{
return false;
}
connect (m_stream.data(), &QAudioInput::stateChanged, this, &SoundInput::handleStateChanged);
m_stream->setBufferSize (m_stream->format ().bytesForFrames (framesPerBuffer));
m_stream->start (sink);
qDebug () << "audio input buffer size = " << m_stream->bufferSize () << " bytes\n";
return audioError () ? false : true;
}
void SoundInput::handleStateChanged (QAudio::State newState) const
{
switch (newState)
{
case QAudio::IdleState:
qDebug () << "SoundInput idle\n";
Q_EMIT status (tr ("Idle"));
break;
case QAudio::ActiveState:
qDebug () << "SoundInput active\n";
Q_EMIT status (tr ("Receiving"));
break;
case QAudio::SuspendedState:
qDebug () << "SoundInput suspended\n";
Q_EMIT status (tr ("Suspended"));
break;
case QAudio::StoppedState:
if (audioError ())
{
qDebug () << "SoundInput error\n";
Q_EMIT status (tr ("Error"));
}
else
{
qDebug () << "SoundInput stopped\n";
Q_EMIT status (tr ("Stopped"));
}
break;
} }
} }
void SoundInput::stop() void SoundInput::stop()
{ {
m_intervalTimer.stop(); if (m_stream)
if (m_inStream)
{ {
Pa_StopStream(m_inStream); m_stream->stop ();
Pa_CloseStream(m_inStream), m_inStream = 0;
} }
m_stream.reset ();
} }
#else // QAUDIO_INPUT SoundInput::~SoundInput ()
#include "soundin.h"
#include <QDateTime>
#define FRAMES_PER_BUFFER 1024
#define NSMAX 6827
#define NTMAX 120
extern "C" {
#include <portaudio.h>
extern struct {
float ss[184*NSMAX]; //This is "common/jt9com/..." in fortran
float savg[NSMAX];
// float c0[2*NTMAX*1500];
short int d2[NTMAX*12000];
int nutc; //UTC as integer, HHMM
int ndiskdat; //1 ==> data read from *.wav file
int ntrperiod; //TR period (seconds)
int mousefqso; //User-selected QSO freq (kHz)
int newdat; //1 ==> new data, must do long FFT
int npts8; //npts in c0() array
int nfa; //Low decode limit (Hz)
int nfb; //High decode limit (Hz)
int ntol; //+/- decoding range around fQSO (Hz)
int kin;
int nzhsym;
int nsave;
int nagain;
int ndepth;
int ntxmode;
int nmode;
char datetime[20];
} jt9com_;
}
QString reportAudioError(QAudio::Error audioError)
{ {
switch (audioError) {
case QAudio::NoError: Q_ASSERT(false);
case QAudio::OpenError: return QObject::tr(
"An error opening the audio device has occurred.");
case QAudio::IOError: return QObject::tr(
"An error occurred during read/write of audio device.");
case QAudio::UnderrunError: return QObject::tr(
"Audio data not being fed to the audio device fast enough.");
case QAudio::FatalError: return QObject::tr(
"Non-recoverable error, audio device not usable at this time.");
}
Q_ASSERT(false);
return "";
} }
SoundInput::SoundInput()
: m_dataSinkBusy(false),
m_TRperiod(60),
m_nsps(6912),
m_monitoring(false),
m_intervalTimer(this)
{
// qDebug() << "A";
connect(&m_intervalTimer, SIGNAL(timeout()), this,SLOT(intervalNotify()));
}
void SoundInput::start(qint32 device)
{
stop();
//---------------------------------------------------- Soundcard Setup
m_callbackData.kin=0; //Buffer pointer
m_callbackData.ncall=0; //Number of callbacks
m_callbackData.bzero=false; //Flag to request reset of kin
m_callbackData.monitoring=m_monitoring;
//### Temporary: hardwired device selection
QAudioDeviceInfo DeviceInfo;
QList<QAudioDeviceInfo> m_InDevices;
QAudioDeviceInfo m_InDeviceInfo;
m_InDevices = DeviceInfo.availableDevices(QAudio::AudioInput);
inputDevice = m_InDevices.at(0);
//###
// qDebug() << "B" << m_InDevices.length() << inputDevice.deviceName();
const char* pcmCodec = "audio/pcm";
QAudioFormat audioFormat = inputDevice.preferredFormat();
audioFormat.setChannelCount(1);
audioFormat.setCodec(pcmCodec);
audioFormat.setSampleRate(12000);
audioFormat.setSampleType(QAudioFormat::SignedInt);
audioFormat.setSampleSize(16);
// qDebug() << "C" << audioFormat << audioFormat.isValid();
if (!audioFormat.isValid()) {
emit error(tr("Requested audio format is not available."));
return;
}
audioInput = new QAudioInput(inputDevice, audioFormat);
// qDebug() << "D" << audioInput->error() << QAudio::NoError;
if (audioInput->error() != QAudio::NoError) {
emit error(reportAudioError(audioInput->error()));
return;
}
stream = audioInput->start();
// qDebug() << "E" << stream->errorString();
m_ntr0 = 99; // initial value higher than any expected
m_nBusy = 0;
m_intervalTimer.start(100);
m_ms0 = QDateTime::currentMSecsSinceEpoch();
m_nsps0 = 0;
}
void SoundInput::intervalNotify()
{
m_callbackData.monitoring=m_monitoring;
qint64 ms = QDateTime::currentMSecsSinceEpoch();
ms=ms % 86400000;
int nsec = ms/1000; // Time according to this computer
int ntr = nsec % m_TRperiod;
static int k=0;
// qDebug() << "a" << ms << nsec;
// Reset buffer pointer and symbol number at start of minute
if(ntr < m_ntr0 or !m_monitoring or m_nsps!=m_nsps0) {
m_nstep0=0;
m_nsps0=m_nsps;
m_callbackData.bzero=true;
k=0;
}
// int k=m_callbackData.kin;
// How many new samples are available?
const qint32 bytesReady = audioInput->bytesReady();
// qDebug() << "b" << bytesReady;
Q_ASSERT(bytesReady >= 0);
Q_ASSERT(bytesReady % 2 == 0);
if (bytesReady == 0) {
return;
}
qint32 bytesRead;
bytesRead = stream->read((char*)&jt9com_.d2[k], bytesReady); // Get the new samples
k += bytesRead/2;
// qDebug() << "c" << bytesReady << bytesRead;
Q_ASSERT(bytesRead <= bytesReady);
if (bytesRead < 0) {
emit error(tr("audio stream QIODevice::read returned -1."));
return;
}
Q_ASSERT(bytesRead % 2 == 0);
if(m_monitoring) {
int kstep=m_nsps/2;
m_step=(k-1)/kstep;
if(m_step != m_nstep0) {
if(m_dataSinkBusy) {
m_nBusy++;
} else {
emit readyForFFT(k-1); //Signal to compute new FFTs
}
m_nstep0=m_step;
}
}
m_ntr0=ntr;
}
SoundInput::~SoundInput()
{
/*
if (m_inStream)
{
Pa_CloseStream(m_inStream), m_inStream = 0;
}
*/
}
/*
// memcpy(jt9com_.d2[k],buf0,bytesRead);
// k+=bytesRead/2;
for(int i=0; i<bytesRead/2; i++) {
jt9com_.d2[k++]=buf0[i];
}
*/
void SoundInput::stop()
{
m_intervalTimer.stop();
/*
if (m_inStream)
{
Pa_StopStream(m_inStream);
Pa_CloseStream(m_inStream), m_inStream = 0;
}
*/
}
#endif // QAUDIO_INPUT

147
soundin.h
View File

@ -1,140 +1,47 @@
#ifndef QAUDIO_INPUT #ifndef SOUNDIN_H__
#ifndef SOUNDIN_H #define SOUNDIN_H__
#define SOUNDIN_H
#include <portaudio.h>
#include <QObject> #include <QObject>
#include <QTimer>
#include <QString> #include <QString>
#include <QScopedPointer>
#include <QAudioInput>
extern "C" int a2dCallback( const void *, void *, unsigned long, PaStreamCallbackTimeInfo const *, PaStreamCallbackFlags, void *); class QAudioDeviceInfo;
class QAudioInput;
class QIODevice;
// Gets audio data from soundcard and signals when a buffer of // Gets audio data from sound sample source and passes it to a sink device
// specified size is available.
class SoundInput : public QObject class SoundInput : public QObject
{ {
Q_OBJECT Q_OBJECT;
public: private:
SoundInput(); Q_DISABLE_COPY (SoundInput);
~SoundInput();
int mstep() const {return m_step;} public:
SoundInput (QObject * parent = 0)
/* these can be called while processing samples */ : QObject (parent)
void setMonitoring(bool b) {m_monitoring = b;}
void setPeriod(int ntrperiod, int nsps)
{ {
m_TRperiod=ntrperiod;
m_nsps=nsps;
} }
signals: ~SoundInput ();
void readyForFFT(int k);
void error(const QString& message);
void status(const QString& message);
public slots: Q_SIGNALS:
void start(qint32 device); void error (QString message) const;
void status (QString message) const;
public Q_SLOTS:
// sink must exist from the start call to any following stop () call
bool start(QAudioDeviceInfo const&, int framesPerBuffer, QIODevice * sink);
void stop(); void stop();
private: private:
PaStream * m_inStream; bool audioError () const;
qint32 m_step;
qint32 m_TRperiod;
qint32 m_TRperiod0;
qint32 m_nsps;
bool m_monitoring;
qint64 m_ms0;
int m_ntr0;
int m_nstep0;
int m_nsps0;
QTimer m_intervalTimer; QScopedPointer<QAudioInput> m_stream;
struct CallbackData private Q_SLOTS:
{ void handleStateChanged (QAudio::State) const;
//Parameters sent to/from the portaudio callback function
int volatile kin;
bool volatile bzero;
bool volatile monitoring;
} m_callbackData;
private slots:
void intervalNotify();
friend int a2dCallback(void const *, void *, unsigned long, PaStreamCallbackTimeInfo const *, PaStreamCallbackFlags, void *);
}; };
#endif // SOUNDIN_H #endif
#else // QAUDIO_INPUT
#ifndef SOUNDIN_H
#define SOUNDIN_H
#include <QObject>
#include <QTimer>
#include <QAudioDeviceInfo>
#include <QAudioInput>
// Gets audio data from soundcard and signals when a buffer of
// specified size is available.
class SoundInput : public QObject
{
Q_OBJECT
public:
SoundInput();
~SoundInput();
void setMonitoring(bool b) {m_monitoring = b;}
void setPeriod(int ntrperiod, int nsps) /* this can be called while processing samples */
{
m_TRperiod=ntrperiod;
m_nsps=nsps;
}
int mstep() const {return m_step;}
double samFacIn() const {return m_SamFacIn;}
signals:
void readyForFFT(int k);
void error(const QString& message);
void status(const QString& message);
public slots:
void start(qint32 device);
void stop();
private:
bool m_dataSinkBusy;
double m_SamFacIn; //(Input sample rate)/12000.0
qint32 m_step;
qint32 m_TRperiod;
qint32 m_TRperiod0;
qint32 m_nsps;
bool m_monitoring;
qint64 m_ms0;
int m_ntr0;
int m_nBusy;
int m_nstep0;
int m_nsps0;
QTimer m_intervalTimer;
QAudioDeviceInfo inputDevice; // audioinput device name
QAudioInput* audioInput;
QIODevice* stream;
struct CallbackData
{
int kin;
int ncall;
bool bzero;
bool monitoring;
} m_callbackData; //Parameters sent to/from the Notify function
private slots:
void intervalNotify();
};
#endif // SOUNDIN_H
#endif // QAUDIO_INPUT

View File

@ -1,217 +1,112 @@
#include "soundout.h" #include "soundout.h"
#include <cmath>
#include <cstring>
#include <QDateTime> #include <QDateTime>
#include <QAudioDeviceInfo>
#include <QAudioOutput>
#include <QDebug> #include <QDebug>
//#define FRAMES_PER_BUFFER 1024 bool SoundOutput::audioError () const
extern float gran(); //Noise generator (for tests only)
extern int itone[126]; //Audio tones for all Tx symbols
extern int icw[250]; //Dits for CW ID
extern int outBufSize;
//--------------------------------------------------------------- d2aCallback
int d2aCallback(const void *inputBuffer, void *outputBuffer,
unsigned long framesToProcess,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{ {
SoundOutput::CallbackData * udata = reinterpret_cast<SoundOutput::CallbackData *>(userData); bool result (true);
short * wptr = reinterpret_cast<short *>(outputBuffer);
static double twopi=2.0*3.141592653589793238462; Q_ASSERT_X (m_stream, "SoundOutput", "programming error");
static double baud; if (m_stream)
static double phi=0.0; {
static double dphi; switch (m_stream->error ())
static double freq; {
static double snr; case QAudio::OpenError:
static double fac; Q_EMIT error (tr ("An error opening the audio output device has occurred."));
static double amp; break;
static int ic=0,j=0;
static int isym0=-999;
static short int i2;
int isym,nspd;
udata->ncall++; case QAudio::IOError:
if(udata->bRestart) { Q_EMIT error (tr ("An error occurred during write to the audio output device."));
// Time according to this computer break;
qint64 ms = QDateTime::currentMSecsSinceEpoch() % 86400000;
int mstr = ms % (1000*udata->ntrperiod );
if(mstr<1000)
{
std::memset(wptr, 0, framesToProcess * sizeof(*wptr)); // output silence
return paContinue;
}
ic=(mstr-1000)*48;
udata->bRestart=false;
srand(mstr); //Initialize random seed
}
isym=ic/(4.0*udata->dnsps); //Actual fsample=48000
if(udata->tune) isym=0; //If tuning, send pure tone
if(udata->txsnrdb < 0.0) {
snr=std::pow(10.0,0.05*(udata->txsnrdb-6.0));
fac=3000.0;
if(snr>1.0) fac=3000.0/snr;
}
if(isym>=udata->nsym and icw[0]>0) { //Output the CW ID case QAudio::UnderrunError:
freq=udata->ntxfreq - udata->xit; Q_EMIT error (tr ("Audio data not being fed to the audio output device fast enough."));
dphi=twopi*freq/48000.0; break;
// float wpm=20.0; case QAudio::FatalError:
// int nspd=1.2*48000.0/wpm; Q_EMIT error (tr ("Non-recoverable error, audio output device not usable at this time."));
// nspd=3072; //18.75 WPM break;
nspd=2048 + 512; //22.5 WPM
int ic0=udata->nsym*4*udata->dnsps; case QAudio::NoError:
for(uint i=0 ; i<framesToProcess; i++ ) { result = false;
phi += dphi; break;
if(phi>twopi) phi -= twopi; }
i2=32767.0*std::sin(phi);
j=(ic-ic0)/nspd + 1;
if(icw[j]==0) i2=0;
if(udata->txsnrdb < 0.0) {
int i4=fac*(gran() + i2*snr/32768.0);
if(i4>32767) i4=32767;
if(i4<-32767) i4=-32767;
i2=i4;
}
if(udata->mute) i2=0;
*wptr++ = i2; //left
#ifdef UNIX
*wptr++ = i2; //right
#endif
ic++;
} }
if(j>icw[0]) return paComplete; return result;
if(statusFlags==999999 and timeInfo==NULL and
inputBuffer==NULL) return paContinue; //Silence compiler warning:
return paContinue;
}
baud=12000.0/udata->dnsps;
amp=32767.0;
int i0=(udata->nsym-0.017)*4.0*udata->dnsps;
int i1=udata->nsym*4.0*udata->dnsps;
bool tune = udata->tune;
if(tune) { //If tuning, no ramp down
i0=999*udata->dnsps;
i1=i0;
}
for(uint i=0 ; i<framesToProcess; i++ ) {
isym=ic/(4.0*udata->dnsps); //Actual fsample=48000
if(tune) isym=0; //If tuning, send pure tone
if(isym!=isym0) {
freq=udata->ntxfreq + itone[isym]*baud - udata->xit;
dphi=twopi*freq/48000.0;
isym0=isym;
}
phi += dphi;
if(phi>twopi) phi -= twopi;
if(ic>i0) amp=0.98*amp;
if(ic>i1) amp=0.0;
i2=amp*std::sin(phi);
if(udata->txsnrdb < 0.0) {
int i4=fac*(gran() + i2*snr/32768.0);
if(i4>32767) i4=32767;
if(i4<-32767) i4=-32767;
i2=i4;
}
if(udata->mute) i2=0;
*wptr++ = i2; //left
#ifdef UNIX
*wptr++ = i2; //right
#endif
ic++;
}
if(amp==0.0) {
if(icw[0]==0) return paComplete;
phi=0.0;
}
return paContinue;
} }
SoundOutput::SoundOutput() bool SoundOutput::start(QAudioDeviceInfo const& device, QIODevice * source)
: m_stream(0)
, m_outputLatency(0.)
, m_active(false)
{ {
} Q_ASSERT (source);
void SoundOutput::start(qint32 deviceNumber,QString const& mode,int TRPeriod
,int nsps,int txFreq,int xit,double txsnrdb)
{
stop(); stop();
PaStreamParameters outParam; QAudioFormat format (device.preferredFormat());
format.setChannelCount (1);
format.setCodec ("audio/pcm");
format.setSampleRate (48000);
format.setSampleType (QAudioFormat::SignedInt);
format.setSampleSize (16);
if (!format.isValid ())
{
Q_EMIT error (tr ("Requested output audio format is not valid."));
return false;
}
if (!device.isFormatSupported (format))
{
Q_EMIT error (tr ("Requested output audio format is not supported on device."));
return false;
}
outParam.device=deviceNumber; //Output device number m_stream.reset (new QAudioOutput (device, format, this));
outParam.channelCount=1; //Number of analog channels if (audioError ())
#ifdef UNIX {
outParam.channelCount=2; //Number of analog channels return false;
#endif }
outParam.sampleFormat=paInt16; //Send short ints to PortAudio connect (m_stream.data(), &QAudioOutput::stateChanged, this, &SoundOutput::handleStateChanged);
outParam.suggestedLatency=0.05;
outParam.hostApiSpecificStreamInfo=NULL;
PaError paerr = Pa_IsFormatSupported(NULL,&outParam,48000.0); m_stream->start (source);
if(paerr<0) { if (audioError ()) // start the input stream
qDebug() << "PortAudio says requested output format not supported."; {
qDebug() << paerr << deviceNumber; return false;
return; }
}
m_callbackData.txsnrdb=txsnrdb;
m_callbackData.dnsps=nsps;
m_callbackData.nsym=85;
if(mode=="JT65") {
m_callbackData.dnsps=4096.0*12000.0/11025.0;
m_callbackData.nsym=126;
}
m_callbackData.ntrperiod=TRPeriod;
m_callbackData.ntxfreq=txFreq;
m_callbackData.xit=xit;
m_callbackData.ncall=0;
m_callbackData.bRestart=true;
paerr=Pa_OpenStream(&m_stream, //Output stream
NULL, //No input parameters
&outParam, //Output parameters
48000.0, //Sample rate
outBufSize, //Frames per buffer
paClipOff, //No clipping
d2aCallback, //output callbeck routine
&m_callbackData); //userdata
paerr=Pa_StartStream(m_stream);
if(paerr<0) {
qDebug() << "Failed to start audio output stream.";
return;
}
const PaStreamInfo* p=Pa_GetStreamInfo(m_stream);
m_outputLatency = p->outputLatency;
m_ms0 = QDateTime::currentMSecsSinceEpoch();
m_active = true; m_active = true;
return true;
}
void SoundOutput::handleStateChanged (QAudio::State newState) const
{
switch (newState)
{
case QAudio::IdleState: Q_EMIT status (tr ("Idle")); break;
case QAudio::ActiveState: Q_EMIT status (tr ("Sending")); break;
case QAudio::SuspendedState: Q_EMIT status (tr ("Suspended")); break;
case QAudio::StoppedState:
if (audioError ())
{
Q_EMIT status (tr ("Error"));
}
else
{
Q_EMIT status (tr ("Stopped"));
}
break;
}
} }
void SoundOutput::stop() void SoundOutput::stop()
{ {
if (m_stream) m_stream.reset ();
{
Pa_StopStream(m_stream);
Pa_CloseStream(m_stream), m_stream = 0;
}
m_active = false; m_active = false;
} }
SoundOutput::~SoundOutput() SoundOutput::~SoundOutput()
{ {
if (m_stream) stop ();
{
Pa_CloseStream(m_stream), m_stream = 0;
}
} }

View File

@ -1,76 +1,52 @@
#ifndef SOUNDOUT_H #ifndef SOUNDOUT_H__
#define SOUNDOUT_H #define SOUNDOUT_H__
#include <portaudio.h>
#include <QObject> #include <QObject>
#include <QString> #include <QString>
#include <QAudioOutput>
extern "C" int d2aCallback(const void *, void *, #include "Modulator.hpp"
unsigned long,
PaStreamCallbackTimeInfo const *, class QAudioDeviceInfo;
PaStreamCallbackFlags,
void *);
// An instance of this sends audio data to a specified soundcard. // An instance of this sends audio data to a specified soundcard.
// Output can be muted while underway, preserving waveform timing when
// transmission is resumed.
class SoundOutput : public QObject class SoundOutput : public QObject
{ {
Q_OBJECT; Q_OBJECT;
Q_PROPERTY(bool running READ isRunning); Q_PROPERTY(bool running READ isRunning);
Q_PROPERTY(bool mute READ isMuted WRITE mute);
Q_PROPERTY(bool tune READ isTuning WRITE tune);
public: private:
SoundOutput(); Q_DISABLE_COPY (SoundOutput);
~SoundOutput();
public:
SoundOutput ()
: m_active(false)
{
}
~SoundOutput ();
bool isRunning() const {return m_active;} bool isRunning() const {return m_active;}
bool isMuted() const {return m_callbackData.mute;}
bool isTuning() const {return m_callbackData.tune;}
double outputLatency() const {return m_outputLatency;}
// the following can be called while the stream is running public Q_SLOTS:
void setTxFreq(int n) {m_callbackData.ntxfreq = n;} bool start(QAudioDeviceInfo const& device, QIODevice * source);
void setXIT(int n) {m_callbackData.xit = n;}
void mute(bool b = true) {m_callbackData.mute = b;}
void tune(bool b = true) {m_callbackData.tune = b;}
public slots:
void start(qint32 deviceNumber, QString const& mode,int TRPeriod,int nsps,int txFreq,int xit,double txsnrdb = 99.);
void stop(); void stop();
// Private members Q_SIGNALS:
void error (QString message) const;
void status (QString message) const;
private: private:
PaStream * m_stream; bool audioError () const;
PaTime m_outputLatency;
struct CallbackData private Q_SLOTS:
{ void handleStateChanged (QAudio::State) const;
//Parameters sent to or received from callback function
double volatile txsnrdb; private:
double volatile dnsps; //Samples per symbol (at 12000 Hz) QScopedPointer<QAudioOutput> m_stream;
int volatile ntrperiod; //T/R period (s)
int volatile ntxfreq;
int volatile xit;
int volatile ncall;
int volatile nsym;
bool volatile mute;
bool volatile bRestart;
bool volatile tune;
} m_callbackData;
qint64 m_ms0;
bool m_active; bool m_active;
friend int d2aCallback(const void *, void *,
unsigned long,
PaStreamCallbackTimeInfo const *,
PaStreamCallbackFlags,
void *);
}; };
#endif #endif

View File

@ -4,7 +4,7 @@
# #
#------------------------------------------------- #-------------------------------------------------
QT += core gui network multimedia QT += network multimedia
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += thread CONFIG += thread
#CONFIG += console #CONFIG += console
@ -16,7 +16,6 @@ VERSION = 1.1
TEMPLATE = app TEMPLATE = app
#DEFINES = QT4 #DEFINES = QT4
DEFINES = QT5 DEFINES = QT5
#DEFINES += QAUDIO_INPUT
win32 { win32 {
DEFINES += WIN32 DEFINES += WIN32
@ -36,16 +35,31 @@ gfortran.input = F90_SOURCES
QMAKE_EXTRA_COMPILERS += gfortran QMAKE_EXTRA_COMPILERS += gfortran
} }
SOURCES += main.cpp mainwindow.cpp plotter.cpp about.cpp \ #
soundin.cpp soundout.cpp devsetup.cpp widegraph.cpp \ # Order matters here as the link is in this order so referrers need to be after referred
getfile.cpp displaytext.cpp getdev.cpp logqso.cpp \ #
psk_reporter.cpp rigclass.cpp \ SOURCES += \
signalmeter.cpp \ logbook/adif.cpp \
meterwidget.cpp \ logbook/countrydat.cpp \
logbook/logbook.cpp \ logbook/countriesworked.cpp \
logbook/countrydat.cpp \ logbook/logbook.cpp \
logbook/countriesworked.cpp \ rigclass.cpp \
logbook/adif.cpp psk_reporter.cpp \
Modulator.cpp \
Detector.cpp \
logqso.cpp \
displaytext.cpp \
getfile.cpp \
soundout.cpp \
soundin.cpp \
meterwidget.cpp \
signalmeter.cpp \
plotter.cpp \
widegraph.cpp \
devsetup.cpp \
about.cpp \
mainwindow.cpp \
main.cpp
win32 { win32 {
SOURCES += killbyname.cpp SOURCES += killbyname.cpp
@ -54,7 +68,7 @@ SOURCES += killbyname.cpp
HEADERS += mainwindow.h plotter.h soundin.h soundout.h \ HEADERS += mainwindow.h plotter.h soundin.h soundout.h \
about.h devsetup.h widegraph.h getfile.h \ about.h devsetup.h widegraph.h getfile.h \
commons.h sleep.h displaytext.h logqso.h \ commons.h sleep.h displaytext.h logqso.h \
psk_reporter.h rigclass.h \ Detector.hpp Modulator.hpp psk_reporter.h rigclass.h \
signalmeter.h \ signalmeter.h \
meterwidget.h \ meterwidget.h \
logbook/logbook.h \ logbook/logbook.h \
@ -62,9 +76,6 @@ HEADERS += mainwindow.h plotter.h soundin.h soundout.h \
logbook/countriesworked.h \ logbook/countriesworked.h \
logbook/adif.h logbook/adif.h
# (Is the following really needed???)
#DEFINES += __cplusplus
FORMS += mainwindow.ui about.ui devsetup.ui widegraph.ui \ FORMS += mainwindow.ui about.ui devsetup.ui widegraph.ui \
logqso.ui logqso.ui
@ -73,7 +84,7 @@ RC_FILE = wsjtx.rc
unix { unix {
LIBS += ../wsjtx/lib/libjt9.a LIBS += ../wsjtx/lib/libjt9.a
LIBS += -lhamlib LIBS += -lhamlib
LIBS += -lportaudio -lgfortran -lfftw3f LIBS += -lgfortran -lfftw3f
} }
win32 { win32 {
@ -84,8 +95,6 @@ LIBS += ../wsjtx/lib/libjt9.a
LIBS += ../wsjtx/libfftw3f_win.a LIBS += ../wsjtx/libfftw3f_win.a
LIBS += ../wsjtx/libpskreporter.a LIBS += ../wsjtx/libpskreporter.a
LIBS += ../wsjtx/libHRDInterface001.a LIBS += ../wsjtx/libHRDInterface001.a
#LIBS += ../QtSupport/palir-02.dll
LIBS += /users/joe/wsjt/QtSupport/palir-02.dll
LIBS += libwsock32 LIBS += libwsock32
LIBS += C:/MinGW/lib/libf95.a LIBS += C:/MinGW/lib/libf95.a