diff --git a/CHANGELOG b/CHANGELOG new file mode 100644 index 0000000..05f2fd6 --- /dev/null +++ b/CHANGELOG @@ -0,0 +1,27 @@ + +# CHANGELOG + +- 20210210 added control over LAN for rigs that support it + has been tested on the 705, 7610, 785x, 9700. + should work on 7700, 7800, other rigs. + added different sampling rates for rx + added different codecs + added scope data for 7610, 785x. + several cosmetic changes in the UI + fixed a slew of bugs + builds on MAC-OS, Linux, Windows + added ToFixed + implemented connect/disconnect rig + improved USB serial code + fixed memory leak + redesigned rx audio path for better performance + added round trip time for network connected devices + added detection code of rigtype + automatic detection of CIV control address + added logfile capability + works on a raspberry pi (USB and ethernet) + + + + + diff --git a/INSTALL.md b/INSTALL.md index 73067cd..f08cbdf 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -53,6 +53,8 @@ sudo chown $USER /dev/ttyUSB* - most linux systems just need to have you added to the dialout group as that's persistent and more secure. +sudo usermod -aG dialout $USER +(don't forget to log out and log in) ### opensuse install ### diff --git a/calibrationwindow.cpp b/calibrationwindow.cpp new file mode 100644 index 0000000..ec136c6 --- /dev/null +++ b/calibrationwindow.cpp @@ -0,0 +1,76 @@ +#include "calibrationwindow.h" +#include "ui_calibrationwindow.h" + +calibrationWindow::calibrationWindow(QWidget *parent) : + QDialog(parent), + ui(new Ui::calibrationWindow) +{ + ui->setupUi(this); + ui->calCourseSlider->setDisabled(true); + ui->calCourseSpinbox->setDisabled(true); + + ui->calFineSlider->setDisabled(true); + ui->calFineSpinbox->setDisabled(true); + +} + +calibrationWindow::~calibrationWindow() +{ + delete ui; +} + +void calibrationWindow::handleCurrentFreq(double tunedFreq) +{ + (void)tunedFreq; +} + +void calibrationWindow::handleSpectrumPeak(double peakFreq) +{ + (void)peakFreq; +} + +void calibrationWindow::handleRefAdjustCourse(unsigned char value) +{ + ui->calCourseSlider->setDisabled(false); + ui->calCourseSpinbox->setDisabled(false); + + ui->calCourseSlider->blockSignals(true); + ui->calCourseSpinbox->blockSignals(true); + + ui->calCourseSlider->setValue((int) value); + ui->calCourseSpinbox->setValue((int) value); + + ui->calCourseSlider->blockSignals(false); + ui->calCourseSpinbox->blockSignals(false); +} + +void calibrationWindow::handleRefAdjustFine(unsigned char value) +{ + ui->calFineSlider->setDisabled(false); + ui->calFineSpinbox->setDisabled(false); + + ui->calFineSlider->blockSignals(true); + ui->calFineSpinbox->blockSignals(true); + + ui->calFineSlider->setValue((int) value); + ui->calFineSpinbox->setValue((int) value); + + ui->calFineSlider->blockSignals(false); + ui->calFineSpinbox->blockSignals(false); +} + +void calibrationWindow::on_calReadRigCalBtn_clicked() +{ + emit requestRefAdjustCourse(); + emit requestRefAdjustFine(); +} + +void calibrationWindow::on_calCourseSlider_valueChanged(int value) +{ + emit setRefAdjustCourse((unsigned char) value); +} + +void calibrationWindow::on_calFineSlider_valueChanged(int value) +{ + emit setRefAdjustFine((unsigned char) value); +} diff --git a/calibrationwindow.h b/calibrationwindow.h new file mode 100644 index 0000000..42e2e5c --- /dev/null +++ b/calibrationwindow.h @@ -0,0 +1,43 @@ +#ifndef CALIBRATIONWINDOW_H +#define CALIBRATIONWINDOW_H + +#include + +namespace Ui { +class calibrationWindow; +} + +class calibrationWindow : public QDialog +{ + Q_OBJECT + +public: + explicit calibrationWindow(QWidget *parent = 0); + ~calibrationWindow(); + +public slots: + void handleSpectrumPeak(double peakFreq); + void handleCurrentFreq(double tunedFreq); + void handleRefAdjustCourse(unsigned char); + void handleRefAdjustFine(unsigned char); + +signals: + void requestSpectrumPeak(double peakFreq); + void requestCurrentFreq(double tunedFreq); + void requestRefAdjustCourse(); + void requestRefAdjustFine(); + void setRefAdjustCourse(unsigned char); + void setRefAdjustFine(unsigned char); + +private slots: + void on_calReadRigCalBtn_clicked(); + + void on_calCourseSlider_valueChanged(int value); + + void on_calFineSlider_valueChanged(int value); + +private: + Ui::calibrationWindow *ui; +}; + +#endif // CALIBRATIONWINDOW_H diff --git a/calibrationwindow.ui b/calibrationwindow.ui new file mode 100644 index 0000000..1bd7d90 --- /dev/null +++ b/calibrationwindow.ui @@ -0,0 +1,280 @@ + + + calibrationWindow + + + + 0 + 0 + 400 + 300 + + + + Dialog + + + + + 9 + 9 + 381 + 281 + + + + + + + + + IC-9700 + + + + + + + Reference Adjustment + + + + + + + + + + + + + Peak + + + + + + + 446.000125 + + + + + + + + + + + Tune + + + + + + + 446.00000 + + + + + + + + + + + Delta + + + + + + + -0.125 + + + + + + + + + + + + + + + Course + + + + + + + Fine + + + + + + + + + 10 + + + + + + + + + 255 + + + Qt::Horizontal + + + + + + + 255 + + + Qt::Horizontal + + + + + + + + + 10 + + + 10 + + + + + 255 + + + + + + + 255 + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + 0 + + + + + <html><head/><body><p>Save the calibration data to the indicated slot in the preference file. </p></body></html> + + + Save + + + + + + + <html><head/><body><p>Load the calibration data fromthe indicated slot in the preference file. </p></body></html> + + + Load + + + + + + + Slot: + + + + + + + + 1 + + + + + 2 + + + + + 3 + + + + + 4 + + + + + 5 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Read Current Rig Calibration + + + + + + + + + diff --git a/main.cpp b/main.cpp index 3ec8994..6eb7457 100644 --- a/main.cpp +++ b/main.cpp @@ -28,7 +28,8 @@ int main(int argc, char *argv[]) QString currentArg; - const QString helpText = QString("Usage: -p --port /dev/port, -h --host remotehostname, -c --civ 0xAddr, -l --logfile filename.log"); // TODO... + + const QString helpText = QString("\nUsage: -p --port /dev/port, -h --host remotehostname, -c --civ 0xAddr, -l --logfile filename.log\n"); // TODO... for(int c=1; c>4)*10; + rtnVal += (tensunits & 0x0f); + + return rtnVal; +} + +QByteArray rigCommander::bcdEncodeInt(unsigned int num) +{ + if(num > 9999) + { + qDebug() << __FUNCTION__ << "Error, number is too big for four-digit conversion: " << num; + return QByteArray(); + } + + char thousands = num / 1000; + char hundreds = (num - (1000*thousands)) / 100; + char tens = (num - (1000*thousands) - (100*hundreds)) / 10; + char units = (num - (1000*thousands) - (100*hundreds) - (10*tens)); + + char b0 = hundreds | (thousands << 4); + char b1 = units | (tens << 4); + + qDebug() << __FUNCTION__ << " encoding value " << num << " as hex:"; + //printHex(QByteArray(b0), false, true); + //printHex(QByteArray(b1), false, true); + + + QByteArray result; + result.append(b0).append(b1); + qDebug() << "Result: " << result; + return result; +} + void rigCommander::parseFrequency() { // process payloadIn, which is stripped. @@ -1375,6 +1482,12 @@ void rigCommander::parseMode() case '\x08': mode = "RTTY-R"; break; + case '\x17': + mode = "DV"; + break; + case '\x22': + mode = "DD"; + break; default: qDebug() << "Mode: Unknown: " << payloadIn[01]; printHex(payloadIn, false, true); diff --git a/rigcommander.h b/rigcommander.h index 34ba7bd..40c3019 100644 --- a/rigcommander.h +++ b/rigcommander.h @@ -55,6 +55,7 @@ public slots: void getRfGain(); void getAfGain(); void getSql(); + void setSquelch(unsigned char level); void setRfGain(unsigned char level); void setAfGain(unsigned char level); void startATU(); @@ -63,6 +64,10 @@ public slots: void getRigID(); void findRigs(); void setCIVAddr(unsigned char civAddr); + void getRefAdjustCourse(); + void getRefAdjustFine(); + void setRefAdjustCourse(unsigned char level); + void setRefAdjustFine(unsigned char level); void handleNewData(const QByteArray &data); void handleSerialPortError(const QString port, const QString errorText); void handleStatusUpdate(const QString text); @@ -91,6 +96,9 @@ signals: void haveAfGain(unsigned char level); void haveSql(unsigned char level); void haveTxPower(unsigned char level); + void thing(); + void haveRefAdjustCourse(unsigned char level); + void haveRefAdjustFine(unsigned char level); void dataForComm(const QByteArray &outData); void getMoreDebug(); void finished(); @@ -105,6 +113,8 @@ private: void parseData(QByteArray data); // new data come here void parseCommand(); unsigned char bcdHexToDecimal(unsigned char in); + unsigned char bcdHexToDecimal(unsigned char hundreds, unsigned char tensunits); + QByteArray bcdEncodeInt(unsigned int); void parseFrequency(); float parseFrequency(QByteArray data, unsigned char lastPosition); // supply index where Mhz is found QByteArray makeFreqPayload(double frequency); diff --git a/rigidentities.h b/rigidentities.h index c26325e..a91faa7 100644 --- a/rigidentities.h +++ b/rigidentities.h @@ -43,6 +43,9 @@ struct rigCapabilities { quint16 spectAmpMax; quint16 spectLenMax; + bool hasDD; + bool hasDV; + }; diff --git a/rxaudiohandler.cpp b/rxaudiohandler.cpp new file mode 100644 index 0000000..4cc665f --- /dev/null +++ b/rxaudiohandler.cpp @@ -0,0 +1,104 @@ +#include "rxaudiohandler.h" + +rxAudioHandler::rxAudioHandler() +{ + +} + +rxAudioHandler::~rxAudioHandler() +{ + audio->stop(); + delete audio; +} + +void rxAudioHandler::process() +{ + qDebug() << "rxAudio Handler created."; +} + +void rxAudioHandler::setup(const QAudioFormat format, const quint16 bufferSize, const bool isUlaw) +{ + this->format = format; + this->bufferSize = bufferSize; + this->isUlaw = isUlaw; + audio = new QAudioOutput(format); + audio->setBufferSize(bufferSize); + device = audio->start(); +} + + +void rxAudioHandler::incomingAudio(const QByteArray data) +{ + QMutexLocker locker(&mutex); + if (isUlaw) { + device->write(uLawDecode(data)); + } + else { + device->write(data, data.length()); + } +} + +void rxAudioHandler::changeBufferSize(const quint16 newSize) +{ + QMutexLocker locker(&mutex); + qDebug() << "Changing buffer size to: " << newSize << " from " << audio->bufferSize(); + audio->stop(); + audio->setBufferSize(newSize); + device = audio->start(); +} + +void rxAudioHandler::getBufferSize() +{ + emit sendBufferSize(audio->bufferSize()); +} + + + +QByteArray rxAudioHandler::uLawDecode(const QByteArray in) +{ + static const qint16 ulaw_decode[256] = { + -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956, + -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764, + -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412, + -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316, + -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140, + -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092, + -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004, + -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980, + -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436, + -1372, -1308, -1244, -1180, -1116, -1052, -988, -924, + -876, -844, -812, -780, -748, -716, -684, -652, + -620, -588, -556, -524, -492, -460, -428, -396, + -372, -356, -340, -324, -308, -292, -276, -260, + -244, -228, -212, -196, -180, -164, -148, -132, + -120, -112, -104, -96, -88, -80, -72, -64, + -56, -48, -40, -32, -24, -16, -8, 0, + 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956, + 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764, + 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412, + 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316, + 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140, + 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092, + 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004, + 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980, + 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436, + 1372, 1308, 1244, 1180, 1116, 1052, 988, 924, + 876, 844, 812, 780, 748, 716, 684, 652, + 620, 588, 556, 524, 492, 460, 428, 396, + 372, 356, 340, 324, 308, 292, 276, 260, + 244, 228, 212, 196, 180, 164, 148, 132, + 120, 112, 104, 96, 88, 80, 72, 64, + 56, 48, 40, 32, 24, 16, 8, 0 }; + + QByteArray out; + foreach(qint8 const temp, in) + { + qint16 decoded = ulaw_decode[0]; + if (temp != 0) { + decoded = ulaw_decode[static_cast(temp)]; + } + out.append(static_cast(decoded & 0xff)); + out.append(static_cast(decoded >> 8 & 0xff)); + } + return out; +} diff --git a/rxaudiohandler.h b/rxaudiohandler.h new file mode 100644 index 0000000..fa4a05e --- /dev/null +++ b/rxaudiohandler.h @@ -0,0 +1,47 @@ +#ifndef RXAUDIOHANDLER_H +#define RXAUDIOHANDLER_H + +#include + +#include +#include +#include + +#include + +class rxAudioHandler : public QObject +{ + Q_OBJECT + +public: + rxAudioHandler(); + ~rxAudioHandler(); + + +public slots: + void process(); + void setup(const QAudioFormat format, const quint16 bufferSize, const bool isulaw); + + void incomingAudio(const QByteArray data); + void changeBufferSize(const quint16 newSize); + void getBufferSize(); + +signals: + void audioMessage(QString message); + void sendBufferSize(quint16 newSize); + + +private: + QByteArray uLawDecode(const QByteArray in); + + QAudioOutput* audio; + QAudioFormat format; + QIODevice* device; + int bufferSize; + QMutex mutex; + bool isUlaw; + + +}; + +#endif // RXAUDIOHANDLER_H diff --git a/udphandler.cpp b/udphandler.cpp index 68091c0..8f5225d 100644 --- a/udphandler.cpp +++ b/udphandler.cpp @@ -312,6 +312,7 @@ qint64 udpHandler::SendRequestSerialAndAudio() quint8* usernameEncoded = Passcode(username); int txSeqBufLengthMs = 50; + const quint8 p[] = { 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, static_cast(localSID >> 24 & 0xff), static_cast(localSID >> 16 & 0xff), static_cast(localSID >> 8 & 0xff), static_cast(localSID & 0xff), @@ -575,12 +576,6 @@ udpAudio::udpAudio(QHostAddress local, QHostAddress ip, quint16 aport, quint16 b if (rxCodec == 0x02 || rxCodec == 0x8) rxNumSamples = 8; // uLaw is actually 16bit. - if (txCodec == 0x01) - txIsUlawCodec = true; - else if (txCodec == 0x02) - txNumSamples = 8; // uLaw is actually 16bit. - - rxaudio = new audioHandler(); rxAudioThread = new QThread(this); @@ -623,6 +618,7 @@ udpAudio::~udpAudio() rxAudioThread->quit(); rxAudioThread->wait(); } + if (txAudioThread) { txAudioThread->quit(); txAudioThread->wait(); @@ -652,6 +648,7 @@ void udpAudio::sendTxAudio(QByteArray audio) SendTrackedPacket(tx); sendAudioSeq++; } + } void udpAudio::changeBufferSize(quint16 value) diff --git a/udphandler.h b/udphandler.h index 1dc533c..164097b 100644 --- a/udphandler.h +++ b/udphandler.h @@ -18,7 +18,6 @@ #include #include - #include #include "audiohandler.h" @@ -125,15 +124,16 @@ public: signals: void haveAudioData(QByteArray data); + void setupTxAudio(const quint8 samples, const quint8 channels, const quint16 samplerate, const quint16 bufferSize, const bool isUlaw, const bool isInput); void setupRxAudio(const quint8 samples, const quint8 channels, const quint16 samplerate, const quint16 bufferSize, const bool isUlaw, const bool isInput); + void haveChangeBufferSize(quint16 value); public slots: void changeBufferSize(quint16 value); void sendTxAudio(QByteArray d); - private: void DataReceived(); @@ -158,6 +158,7 @@ private: audioHandler* txaudio; QThread* txAudioThread; + }; diff --git a/wfmain.cpp b/wfmain.cpp index 7348e76..ec9dfcb 100644 --- a/wfmain.cpp +++ b/wfmain.cpp @@ -23,6 +23,8 @@ wfmain::wfmain(const QString serialPortCL, const QString hostCL, QWidget *parent this->serialPortCL = serialPortCL; this->hostCL = hostCL; + cal = new calibrationWindow(); + haveRigCaps = false; ui->bandStkLastUsedBtn->setVisible(false); @@ -210,9 +212,14 @@ wfmain::wfmain(const QString serialPortCL, const QString hostCL, QWidget *parent modes << "LSB" << "USB" << "AM" << "CW" << "RTTY"; // 5 6 7 8 9 modes << "FM" << "CW-R" << "RTTY-R" << "LSB-D" << "USB-D"; - // TODO: Add FM-D and AM-D which seem to exist + // TODO: Add FM-D and AM-D and where applicable D-Star hich seem to exist ui->modeSelectCombo->insertItems(0, modes); + QStringList filters; + filters << "1" << "2" << "3" << "Setup..."; + ui->modeFilterCombo->addItems(filters); + + spans << "2.5k" << "5.0k" << "10k" << "25k"; spans << "50k" << "100k" << "250k" << "500k"; ui->scopeBWCombo->insertItems(0, spans); @@ -277,6 +284,7 @@ wfmain::wfmain(const QString serialPortCL, const QString hostCL, QWidget *parent connect(rig, SIGNAL(haveAfGain(unsigned char)), this, SLOT(receiveAfGain(unsigned char))); connect(this, SIGNAL(getSql()), rig, SLOT(getSql())); connect(rig, SIGNAL(haveSql(unsigned char)), this, SLOT(receiveSql(unsigned char))); + connect(this, SIGNAL(setSql(unsigned char)), rig, SLOT(setSquelch(unsigned char))); connect(this, SIGNAL(startATU()), rig, SLOT(startATU())); connect(this, SIGNAL(setATU(bool)), rig, SLOT(setATU(bool))); connect(this, SIGNAL(getATUStatus()), rig, SLOT(getATUStatus())); @@ -289,6 +297,15 @@ wfmain::wfmain(const QString serialPortCL, const QString hostCL, QWidget *parent connect(this, SIGNAL(sayFrequency()), rig, SLOT(sayFrequency())); connect(this, SIGNAL(sayMode()), rig, SLOT(sayMode())); + // calibration window: + connect(cal, SIGNAL(requestRefAdjustCourse()), rig, SLOT(getRefAdjustCourse())); + connect(cal, SIGNAL(requestRefAdjustFine()), rig, SLOT(getRefAdjustFine())); + connect(rig, SIGNAL(haveRefAdjustCourse(unsigned char)), cal, SLOT(handleRefAdjustCourse(unsigned char))); + connect(rig, SIGNAL(haveRefAdjustFine(unsigned char)), cal, SLOT(handleRefAdjustFine(unsigned char))); + connect(cal, SIGNAL(setRefAdjustCourse(unsigned char)), rig, SLOT(setRefAdjustCourse(unsigned char))); + connect(cal, SIGNAL(setRefAdjustFine(unsigned char)), rig, SLOT(setRefAdjustFine(unsigned char))); + + // Plot user interaction connect(plot, SIGNAL(mouseDoubleClick(QMouseEvent*)), this, SLOT(handlePlotDoubleClick(QMouseEvent*))); connect(wf, SIGNAL(mouseDoubleClick(QMouseEvent*)), this, SLOT(handleWFDoubleClick(QMouseEvent*))); @@ -535,6 +552,22 @@ void wfmain::receiveFoundRigID(rigCapabilities rigCaps) // Entry point for unknown rig being identified at the start of the program. //now we know what the rig ID is: //qDebug() << "In wfview, we now have a reply to our request for rig identity sent to CIV BROADCAST."; + + // We have to be careful here: + // If we enter this a second time, we will get two sets of DV and DD modes + // Also, if ever there is a rig with DV but without DV, we'll be off by one. + // A better solution is to translate the combo selection to a shared type + // such as an enum or even the actual CIV mode byte. + + if(rigCaps.hasDV) + { + ui->modeSelectCombo->addItem("DV"); + } + if(rigCaps.hasDD) + { + ui->modeSelectCombo->addItem("DD"); + } + delayedCommand->setInterval(100); // faster polling is ok now. receiveRigID(rigCaps); getInitialRigState(); @@ -1099,7 +1132,7 @@ void wfmain:: getInitialRigState() cmdOutQue.append(cmdGetRxGain); cmdOutQue.append(cmdGetAfGain); - // cmdOutQue.append(cmdGetSql); // implimented but not used + cmdOutQue.append(cmdGetSql); // implimented but not used // TODO: // get TX level // get Scope reference Level @@ -2148,9 +2181,8 @@ void wfmain::receiveAfGain(unsigned char level) void wfmain::receiveSql(unsigned char level) { - // TODO: Maybe add squelch control - // qDebug() << "Receive SQL level of " << (int)level << " = " << 100*level/255.0 << "%"; - // ui->sqlSlider->setValue(level); // No SQL control so far + qDebug() << "Receive SQL level of " << (int)level << " = " << 100*level/255.0 << "%"; + ui->sqlSlider->setValue(level); (void)level; } @@ -2367,6 +2399,22 @@ void wfmain::on_connectBtn_clicked() } } +void wfmain::on_sqlSlider_valueChanged(int value) +{ + emit setSql((unsigned char)value); +} + +void wfmain::on_modeFilterCombo_activated(int index) +{ + //TODO: + if(index >2) + { + //filterSetup->show(); + } + + // emit setFilterSel((unsigned char)index); +} + // --- DEBUG FUNCTION --- void wfmain::on_debugBtn_clicked() { @@ -2378,7 +2426,7 @@ void wfmain::on_debugBtn_clicked() //emit getScopeSpan(); // in khz, only in "center" mode //qDebug() << "Debug: finding rigs attached. Let's see if this works. "; //rig->findRigs(); + cal->show(); } - diff --git a/wfmain.h b/wfmain.h index 0e27923..c7c7fbe 100644 --- a/wfmain.h +++ b/wfmain.h @@ -16,6 +16,8 @@ #include "freqmemory.h" #include "rigidentities.h" +#include "calibrationwindow.h" + #include #include @@ -49,6 +51,7 @@ signals: void getDebug(); void setRfGain(unsigned char level); void setAfGain(unsigned char level); + void setSql(unsigned char level); void startATU(); void setATU(bool atuEnabled); void getATUStatus(); @@ -277,6 +280,10 @@ private slots: void on_scopeEnableWFBtn_clicked(bool checked); + void on_sqlSlider_valueChanged(int value); + + void on_modeFilterCombo_activated(int index); + private: Ui::wfmain *ui; QSettings settings; @@ -433,6 +440,8 @@ private: rigCapabilities rigCaps; bool haveRigCaps; + calibrationWindow *cal; + void bandStackBtnClick(); bool waitingForBandStackRtn; char bandStkBand; diff --git a/wfmain.ui b/wfmain.ui index 10c60ca..54360e9 100644 --- a/wfmain.ui +++ b/wfmain.ui @@ -213,6 +213,23 @@ + + + + 10 + + + + + Receive Filter + + + + + + + + @@ -291,6 +308,42 @@ + + + + 0 + + + + + + 16777215 + 60 + + + + 255 + + + Qt::Vertical + + + + + + + + 16777215 + 15 + + + + SQ + + + + + diff --git a/wfview.pro b/wfview.pro index cfd89d0..d084ef9 100644 --- a/wfview.pro +++ b/wfview.pro @@ -81,7 +81,8 @@ SOURCES += main.cpp\ rigidentities.cpp \ udphandler.cpp \ logcategories.cpp \ - rxaudiohandler.cpp + rxaudiohandler.cpp \ + calibrationwindow.cpp HEADERS += wfmain.h \ commhandler.h \ @@ -90,8 +91,10 @@ HEADERS += wfmain.h \ rigidentities.h \ udphandler.h \ logcategories.h \ - rxaudiohandler.h - -FORMS += wfmain.ui + + +FORMS += wfmain.ui \ + calibrationwindow.ui +