Merge master into shuttle

half-duplex
Phil Taylor 2022-09-18 16:36:52 +01:00
commit 546330e829
39 zmienionych plików z 3911 dodań i 737 usunięć

104
CHANGELOG
Wyświetl plik

@ -1,5 +1,109 @@
# CHANGELOG # CHANGELOG
- 20220918
merged bits from log branch into master
updated to v.1.45
- 20220917
Log will automatically scroll to bottom on show.
Remove focus from connect button once clicked.
Move connect button
Update wfmain.cpp
Add enable/disable audioSystemServerCombo
Add "Cancel" to connect button
Fixed bug where the frequency dial skipped extra when crossing zero.
- 20220915
Merge branch log:
Minor edit to margins
Removed some additional padding that was left in parts of the UI.
Changed windows 'open log' command to launch notepad.
Removed extra disconnect message from logging host.
Added flush to the text stream to termbin.
Better scrolling behavior. The log is now aware if you are not at the
bottom and will not force scroll if so. Otherwise, it will bring the
horizontal scroll back to the left-edge.
Renamed URL message box in case we add an additional message box later.
Clarified control label to Scroll Down versus To Bottom.
Changed font for better compatibility. Added some controls for scrolling
behavior.
Debug mode can now be toggled from the logging window.
Removed extra output on non-server builds.
Added debug logging button, however, it doesn't propagate the debug
signal through all the modules yet. So, for now, it is hidden.
Restored version to log file, fixed reversed log entries.
updated to v.1.44
- 20220914
Removed word wrapping from the log
Cut log window polling rate in half for lower CPU. 100ms is plenty fast.
Removed audio volume logging.
Keep the logging window up after the message box. Added "log" logging
category.
Added logging window capability with termbin support.
- 20220909
Merge branch resize:
Found an extra 10 pixels due to some layout padding I left in
accidently.
Main window may now be made smaller. Settings combo box sizes now
limited.
Fixed issue where build paths with a space in the name would cause the
git hash to fail capture.
updated to v1.43
- 20220826
Merge branch 'audiometer'
This adds audiometer for the second meter TxAudio, RxAudio and TxRxAudio
updated to v.1.42
- 20220824
Merge branch 'color'
This adds color picker support so that you can define several UI element colors
updated to v1.41
- 20220819
version bumped to 1.4
temporary squashed logs; may redo later
audio fixes at exit
introduction of peak decays at the scope
resizing of top and bottom scope/waterfall
various fixes on the spectrum display
- 20220414 - 20220414
this is a cherrypicked CHANGELOG add as there are loads of changes due to different this is a cherrypicked CHANGELOG add as there are loads of changes due to different

Wyświetl plik

@ -6,3 +6,12 @@ the following people currently contribute to this Project:
- Jim PA8E - Jim PA8E
- Phil M0VSE - Phil M0VSE
- Roeland PA3MET - Roeland PA3MET
Also contributions by:
Daniele Forsi <dforsi@gmail.com>
Russ Woodman - K5TUX <k5tux@k5tux.us>
(and some others I will add too)

Wyświetl plik

@ -14,6 +14,9 @@ sudo apt-get install libqt5multimedia5-plugins
sudo apt-get install qtmultimedia5-dev sudo apt-get install qtmultimedia5-dev
sudo apt-get install git sudo apt-get install git
sudo apt-get install libopus-dev sudo apt-get install libopus-dev
sudo apt-get install libeigen3-dev
sudo apt-get install portaudio19-dev
sudo apt-get install librtaudio-dev
~~~ ~~~
Now you need to install qcustomplot. There are two versions that are commonly found in linux distros: 1.3 and 2.0. Either will work fine. If you are not sure which version your linux install comes with, simply run both commands. One will work and the other will fail, and that's fine! Now you need to install qcustomplot. There are two versions that are commonly found in linux distros: 1.3 and 2.0. Either will work fine. If you are not sure which version your linux install comes with, simply run both commands. One will work and the other will fail, and that's fine!

Wyświetl plik

@ -22,8 +22,8 @@ Debian 11 (Debian 10 is outdated)
Fedora 33 Fedora 33
Fedora 34 Fedora 34
mint 20.1 (and up?) mint 20.1 (and up?)
openSUSE 15.2 openSUSE 15.2 (outdated/deprecated)
openSUSE 15.3 (see notes at the end) openSUSE 15.3/15.4)
openSUSE Tumbleweed(s) openSUSE Tumbleweed(s)
SLES 15.x SLES 15.x
Ubuntu 20.04.2 Ubuntu 20.04.2
@ -86,16 +86,8 @@ sudo ln -s /lib/x86_64-linux-gnu/libqcustomplot.so.2.0.1 /lib/x86_64-linux-gnu/l
~~~ ~~~
### openSUSE/Tumbleweed/SLES based on 15.2: ### openSUSE/Tumbleweed/SLES based on 15.3/15.4:
~~~ ~~~
sudo zypper in libqcustomplot2 libQt5SerialPort5
wfview
~~~
### openSUSE/Tumbleweed/SLES based on 15.3:
~~~
SEE THE NOTES AT THE END. You need wfview153 here
sudo zypper in libqcustomplot2 libQt5SerialPort5 sudo zypper in libqcustomplot2 libQt5SerialPort5
wfview wfview
@ -119,14 +111,8 @@ sudo ln -s /lib/x86_64-linux-gnu/libqcustomplot.so.2.0.1 /lib/x86_64-linux-gnu/l
### notes: ### notes:
~~~ ~~~
Some newer versions of mint. ubuntu, openSUSE have different kernels and such which cause wfview to segfault. openSUSE 15.2 is deprecated; old binary has been removed
For these cases we created two binaries: one for current systems ("wfview") and one for the new systems ("wfview153")
So if you encounter a SEGFAULT at start:
go in to the dist directory, rename wfview to wfvie152; rename wfview153 to wfview and re-execute the install.sh
script
~~~ ~~~

Wyświetl plik

@ -1,37 +1,39 @@
The following highlights are in this 1.x-release: The following highlights are in this 1.41-release:
many changes/mods/updates/enhancements to rigctld New major change is the audio transport mechanism. Lower latencies.
rigctld box added in the UI About box updated to include Patreon site
build process changed: you can add the install prefix (derSuessmann) added 500 Hz step for VFO
added "do not ask again" for switching off rig and exiting wfview Added clock and UTC toggle.
added opus as audio transport Added forced manual RTS setting
dual meter support Add RIT function and other rigctl fixes
rigctl basic split support Adjusted window size for radios without spectrum. Thanks K5TUX.
rigctl prevents switching off civ transceive Allow dynamic restarting of server
added 25 kHz step New Settings tab
as a temporary measure sending multiple TX/FREQ change commands to the rig Enable High DPI Scaling
when we use rigctld. More multi-radio support (mostly working!)
people should use "fake it" in wsjtx as the split code is not reliable. Split LAN waterfall data for N1MM+ Spectrum Scope support: There is a combobox that allows you to select
tidied up udp server function for better reliability split/combine (or default). Split only makes sense for LAN and Combine for USB.
added some IC736 stuff added radio status display with meters for audio (speaker/mic)
added portaudio (you need t change wfview.pro to select selector for audio: QT, PortAudio, RealTime audio
and that lowers the latency to maybe less than 50 ms version bumped to 1.4 -- rethinking of a new version schema that makes more sense
added PBT and IF-shift temporary squashed logs; may redo later
several bugs fixed audio fixes at exit
RTS as PTT for several radios like the 706/718/736… introduction of peak decays at the scope
+ New major change is the audio transport mechanism. Lower latencies. resizing of top and bottom scope/waterfall
+ Author: Daniele Forsi <dforsi@gmail.com>/Author: Daniele Forsi <dforsi@gmail.com> various fixes on the spectrum display
+ Author: Russ Woodman - K5TUX <k5tux@k5tux.us> + 1.41 added color picker support for all kinds of vsual elements
+ About box updated to include Patreon site + 1.42 added three additional second meter choices. RxAudio, TxAdio, and TxRxAudio
+ added 500 Hz step for VFO + 1.43 fixed resizing issues.
+ Added clock and UTC toggle. + 1.44 added logging window. you can send the logs to termbin.com and share the link on the forum
+ Added forced manual RTS setting + 1.45 some more log enhancements
+ Add RIT function and other rigctl fixes moved connect button and added cancel option
+ Adjusted window size for radios without spectrum. Thanks K5TUX. add enable/disable audioSystemServerCombo
+ Allow dynamic restarting of server Fixed bug where the frequency dial skipped extra when crossing zero.
+ New Settings tab
+ Enable High DPI Scaling
+ More multi-radio support (nearly working!) Notes:
+ N1MM+ TCP add.
- We know about high CPU usage on RPi.
- try the audiostack you like the most/what works for you

Wyświetl plik

@ -15,10 +15,12 @@ aboutbox::aboutbox(QWidget *parent) :
ui->topText->setText("wfview version " + QString(WFVIEW_VERSION)); ui->topText->setText("wfview version " + QString(WFVIEW_VERSION));
QString head = QString("<html><head></head><body>"); QString head = QString("<html><head></head><body>");
QString copyright = QString("Copyright 2017-2021 Elliott H. Liggett, W6EL. All rights reserved. wfview source code is <a href=\"https://gitlab.com/eliggett/wfview/-/blob/master/LICENSE\">licensed</a> under the GNU GPLv3."); QString copyright = QString("Copyright 2017-2022 Elliott H. Liggett, W6EL. All rights reserved. wfview source code is <a href=\"https://gitlab.com/eliggett/wfview/-/blob/master/LICENSE\">licensed</a> under the GNU GPLv3.");
QString nacode = QString("<br/><br/>Networking, audio, rigctl server, and much more written by Phil Taylor, M0VSE"); QString nacode = QString("<br/><br/>Networking, audio, rigctl server, and much more written by Phil Taylor, M0VSE");
QString doctest = QString("<br/><br/>Testing, documentation, bug fixes, and development mentorship from<br/>Roeland Jansen, PA3MET, and Jim Nijkamp, PA8E."); QString doctest = QString("<br/><br/>Testing, documentation, bug fixes, and development mentorship from<br/>Roeland Jansen, PA3MET, and Jim Nijkamp, PA8E.");
QString dedication = QString("<br/><br/>This version of wfview is dedicated to the ones we lost.");
#if defined(Q_OS_LINUX) #if defined(Q_OS_LINUX)
QString ssCredit = QString("<br/><br/>Stylesheet <a href=\"https://github.com/ColinDuquesnoy/QDarkStyleSheet/tree/master/qdarkstyle\" style=\"color: cyan;\">qdarkstyle</a> used under MIT license, stored in /usr/share/wfview/stylesheets/."); QString ssCredit = QString("<br/><br/>Stylesheet <a href=\"https://github.com/ColinDuquesnoy/QDarkStyleSheet/tree/master/qdarkstyle\" style=\"color: cyan;\">qdarkstyle</a> used under MIT license, stored in /usr/share/wfview/stylesheets/.");
#else #else
@ -83,7 +85,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.");
// String it all together: // String it all together:
QString aboutText = head + copyright + "\n" + nacode + "\n" + doctest + wfviewcommunityack; QString aboutText = head + copyright + "\n" + nacode + "\n" + doctest + dedication + wfviewcommunityack;
aboutText.append(website + "\n" + donate + "\n"+ docs + support + contact +"\n"); aboutText.append(website + "\n" + donate + "\n"+ docs + support + contact +"\n");
aboutText.append("\n" + ssCredit + "\n" + rsCredit + "\n"); aboutText.append("\n" + ssCredit + "\n" + rsCredit + "\n");

Wyświetl plik

@ -157,7 +157,14 @@ bool audioConverter::convert(audioPacket audio)
if (samplesF.size() > 0) if (samplesF.size() > 0)
{ {
audio.amplitude = samplesF.array().abs().maxCoeff(); audio.amplitudePeak = samplesF.array().abs().maxCoeff();
//audio.amplitudeRMS = samplesF.array().abs().mean(); // zero for tx audio
//audio.amplitudeRMS = samplesF.norm() / sqrt(samplesF.size()); // too high values. Zero for tx audio.
//audio.amplitudeRMS = samplesF.squaredNorm(); // tx not zero. Values higher than peak sometimes
//audio.amplitudeRMS = samplesF.norm(); // too small values. also too small on TX
//audio.amplitudeRMS = samplesF.blueNorm(); // scale same as norm, too small.
// Set the volume // Set the volume
samplesF *= audio.volume; samplesF *= audio.volume;

Wyświetl plik

@ -29,7 +29,8 @@ struct audioPacket {
quint16 sent; quint16 sent;
QByteArray data; QByteArray data;
quint8 guid[GUIDLEN]; quint8 guid[GUIDLEN];
float amplitude; float amplitudePeak;
float amplitudeRMS;
qreal volume = 1.0; qreal volume = 1.0;
}; };

Wyświetl plik

@ -18,23 +18,24 @@ audioHandler::audioHandler(QObject* parent) : QObject(parent)
audioHandler::~audioHandler() audioHandler::~audioHandler()
{ {
if (converterThread != Q_NULLPTR) {
converterThread->quit();
converterThread->wait();
}
if (isInitialized) { if (isInitialized) {
stop(); stop();
} }
if (audioInput != Q_NULLPTR) { if (audioInput != Q_NULLPTR) {
audioInput = Q_NULLPTR;
delete audioInput; delete audioInput;
audioInput = Q_NULLPTR;
} }
if (audioOutput != Q_NULLPTR) { if (audioOutput != Q_NULLPTR) {
delete audioOutput; delete audioOutput;
audioOutput = Q_NULLPTR; audioOutput = Q_NULLPTR;
} }
if (converterThread != Q_NULLPTR) {
converterThread->quit();
converterThread->wait();
}
}bool audioHandler::init(audioSetup setup) }bool audioHandler::init(audioSetup setup)
{ {
if (isInitialized) { if (isInitialized) {
@ -229,7 +230,6 @@ void audioHandler::stop()
void audioHandler::setVolume(unsigned char volume) void audioHandler::setVolume(unsigned char volume)
{ {
this->volume = audiopot[volume]; this->volume = audiopot[volume];
qDebug(logAudio()) << (setup.isinput ? "Input" : "Output") << "setVolume: " << volume << "(" << this->volume << ")";
} }
@ -269,9 +269,8 @@ void audioHandler::convertedOutput(audioPacket packet) {
} }
*/ */
lastSentSeq = packet.seq; lastSentSeq = packet.seq;
emit haveLevels(getAmplitude(), setup.latency, currentLatency, isUnderrun, isOverrun); amplitude = packet.amplitudePeak;
emit haveLevels(getAmplitude(), static_cast<quint16>(packet.amplitudeRMS * 255.0), setup.latency, currentLatency, isUnderrun, isOverrun);
amplitude = packet.amplitude;
} }
} }
@ -311,8 +310,8 @@ void audioHandler::convertedInput(audioPacket audio)
qDebug(logAudio()) << (setup.isinput ? "Input" : "Output") << "Time since last audio packet" << lastReceived.msecsTo(QTime::currentTime()) << "Expected around" << setup.blockSize ; qDebug(logAudio()) << (setup.isinput ? "Input" : "Output") << "Time since last audio packet" << lastReceived.msecsTo(QTime::currentTime()) << "Expected around" << setup.blockSize ;
} }
lastReceived = QTime::currentTime(); lastReceived = QTime::currentTime();
amplitude = audio.amplitude; amplitude = audio.amplitudePeak;
emit haveLevels(getAmplitude(), setup.latency, currentLatency, isUnderrun, isOverrun); emit haveLevels(getAmplitude(), audio.amplitudeRMS, setup.latency, currentLatency, isUnderrun, isOverrun);
} }
} }

Wyświetl plik

@ -70,7 +70,7 @@ signals:
void audioMessage(QString message); void audioMessage(QString message);
void sendLatency(quint16 newSize); void sendLatency(quint16 newSize);
void haveAudioData(const audioPacket& data); void haveAudioData(const audioPacket& data);
void haveLevels(quint16 amplitude,quint16 latency,quint16 current,bool under,bool over); void haveLevels(quint16 amplitudePeak, quint16 amplitudeRMS, quint16 latency,quint16 current,bool under,bool over);
void setupConverter(QAudioFormat in, QAudioFormat out, quint8 opus, quint8 resamp); void setupConverter(QAudioFormat in, QAudioFormat out, quint8 opus, quint8 resamp);
void sendToConverter(audioPacket audio); void sendToConverter(audioPacket audio);

38
colorprefs.h 100644
Wyświetl plik

@ -0,0 +1,38 @@
#ifndef COLORPREFS_H
#define COLORPREFS_H
#include <QColor>
#include <QString>
struct colorPrefsType{
int presetNum = -1;
QString *presetName = Q_NULLPTR;
// Spectrum line plot:
QColor gridColor;
QColor axisColor;
QColor textColor;
QColor spectrumLine;
QColor spectrumFill;
QColor underlayLine;
QColor underlayFill;
QColor plotBackground;
QColor tuningLine;
// Waterfall:
QColor wfBackground;
QColor wfGrid;
QColor wfAxis;
QColor wfText;
// Meters:
QColor meterLevel;
QColor meterAverage;
QColor meterPeakLevel;
QColor meterPeakScale;
QColor meterLowerLine;
QColor meterLowText;
};
#endif // COLORPREFS_H

Wyświetl plik

@ -3,6 +3,8 @@
Q_LOGGING_CATEGORY(logSystem, "system") Q_LOGGING_CATEGORY(logSystem, "system")
Q_LOGGING_CATEGORY(logSerial, "serial") Q_LOGGING_CATEGORY(logSerial, "serial")
Q_LOGGING_CATEGORY(logGui, "gui") Q_LOGGING_CATEGORY(logGui, "gui")
Q_LOGGING_CATEGORY(logLogger, "log")
Q_LOGGING_CATEGORY(logUser, "user")
Q_LOGGING_CATEGORY(logRig, "rig") Q_LOGGING_CATEGORY(logRig, "rig")
Q_LOGGING_CATEGORY(logAudio, "audio") Q_LOGGING_CATEGORY(logAudio, "audio")
Q_LOGGING_CATEGORY(logUdp, "udp") Q_LOGGING_CATEGORY(logUdp, "udp")

Wyświetl plik

@ -6,6 +6,8 @@
Q_DECLARE_LOGGING_CATEGORY(logSystem) Q_DECLARE_LOGGING_CATEGORY(logSystem)
Q_DECLARE_LOGGING_CATEGORY(logSerial) Q_DECLARE_LOGGING_CATEGORY(logSerial)
Q_DECLARE_LOGGING_CATEGORY(logGui) Q_DECLARE_LOGGING_CATEGORY(logGui)
Q_DECLARE_LOGGING_CATEGORY(logLogger)
Q_DECLARE_LOGGING_CATEGORY(logUser)
Q_DECLARE_LOGGING_CATEGORY(logRig) Q_DECLARE_LOGGING_CATEGORY(logRig)
Q_DECLARE_LOGGING_CATEGORY(logAudio) Q_DECLARE_LOGGING_CATEGORY(logAudio)
Q_DECLARE_LOGGING_CATEGORY(logUdp) Q_DECLARE_LOGGING_CATEGORY(logUdp)

211
loggingwindow.cpp 100644
Wyświetl plik

@ -0,0 +1,211 @@
#include "loggingwindow.h"
#include "ui_loggingwindow.h"
loggingWindow::loggingWindow(QWidget *parent) :
QWidget(parent),
ui(new Ui::loggingWindow)
{
ui->setupUi(this);
this->setWindowTitle("Log");
ui->logTextDisplay->setReadOnly(true);
ui->userAnnotationText->setFocus();
ui->annotateBtn->setDefault(true);
ui->logTextDisplay->setFocusPolicy(Qt::NoFocus);
ui->annotateBtn->setFocusPolicy(Qt::NoFocus);
QFont font("Monospace");
font.setStyleHint(QFont::TypeWriter);
ui->logTextDisplay->setFont(font);
ui->userAnnotationText->setFont(font);
#ifdef Q_OS_MAC
logFilename = QStandardPaths::standardLocations(QStandardPaths::DownloadLocation)[0] + "/wfview.log";
logDirectory = QStandardPaths::standardLocations(QStandardPaths::DownloadLocation)[0];
#else
logFilename= QStandardPaths::standardLocations(QStandardPaths::TempLocation)[0] + "/wfview.log";
logDirectory = QStandardPaths::standardLocations(QStandardPaths::TempLocation)[0];
#endif
clipboard = QApplication::clipboard();
socket = new QTcpSocket(this);
connect(socket, SIGNAL(connected()), this, SLOT(connectedToHost()));
connect(socket, SIGNAL(disconnected()), this, SLOT(disconnectedFromHost()));
connect(socket, SIGNAL(readyRead()), this, SLOT(handleDataFromLoggingHost()));
connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(handleLoggingHostError(QAbstractSocket::SocketError)));
vertLogScroll = ui->logTextDisplay->verticalScrollBar();
horizLogScroll = ui->logTextDisplay->horizontalScrollBar();
vertLogScroll->setValue(vertLogScroll->maximum());
horizLogScroll->setValue(horizLogScroll->minimum());
}
loggingWindow::~loggingWindow()
{
QMutexLocker lock(&textMutex);
delete ui;
}
void loggingWindow::showEvent(QShowEvent *event)
{
(void)event;
on_toBottomBtn_clicked();
}
void loggingWindow::setInitialDebugState(bool debugModeEnabled)
{
ui->debugBtn->blockSignals(true);
ui->debugBtn->setChecked(debugModeEnabled);
ui->debugBtn->blockSignals(false);
}
void loggingWindow::acceptLogText(QString text)
{
QMutexLocker lock(&textMutex);
ui->logTextDisplay->appendPlainText(text);
if(vertLogScroll->value() == vertLogScroll->maximum())
{
horizLogScroll->setValue(horizLogScroll->minimum());
}
}
void loggingWindow::sendToTermbin()
{
qInfo(logLogger()) << "Sending data to termbin.com. Standby.";
socket->connectToHost("termbin.com", 9999);
ui->sendToPasteBtn->setDisabled(true);
}
void loggingWindow::handleDataFromLoggingHost()
{
qInfo(logLogger()) << "Receiving data from logging host.";
QString URL;
QByteArray data = socket->readAll();
if(data.length() < 256)
{
URL = QString(data).trimmed();
if(!URL.isEmpty())
{
clipboard->setText(URL);
qInfo(logLogger()) << "Sent log to URL: " << URL;
URLmsgBox.setText("Your log has been posted, and the URL has been copied to the clipboard.");
URLmsgBox.setInformativeText("<b>" + URL + "</b>");
URLmsgBox.exec();
// For whatever reason, showing the message box hides this window.
this->show();
this->raise();
this->activateWindow();
}
} else {
qDebug(logLogger()) << "Error, return from logging host too large. Received " << data.length() << " bytes.";
}
}
void loggingWindow::disconnectedFromHost()
{
qInfo(logLogger()) << "Disconnected from logging host";
ui->sendToPasteBtn->setDisabled(false);
}
void loggingWindow::connectedToHost()
{
qInfo(logLogger()) << "Connected to logging host";
QMutexLocker lock(&textMutex);
QTextStream outText(socket);
outText << ui->logTextDisplay->toPlainText();
outText << "\n----------\nSent from wfview version ";
outText << WFVIEW_VERSION << "\n----------\n";
outText.flush();
}
void loggingWindow::handleLoggingHostError(QAbstractSocket::SocketError error)
{
switch(error)
{
case QAbstractSocket::RemoteHostClosedError:
//qInfo(logLogger()) << "Disconnected from logging host.";
break;
default:
qWarning(logLogger()) << "Error connecting to logging host. Check internet connection. Error code: " << error;
break;
}
}
void loggingWindow::on_clearDisplayBtn_clicked()
{
QMutexLocker lock(&textMutex);
// Only clears the displayed text, not the log file.
ui->logTextDisplay->clear();
}
void loggingWindow::on_openDirBtn_clicked()
{
QString cmd;
int rtnval = 0;
#ifdef Q_OS_MAC
cmd = "open " + logDirectory;
#endif
#ifdef Q_OS_LINUX
cmd = "xdg-open " + logDirectory;
#endif
#ifdef Q_OS_WIN
cmd = "start " + logDirectory;
#endif
rtnval = system(cmd.toLocal8Bit().data());
if(rtnval)
qInfo(logLogger()) << "Error, open log directory command returned error code " << rtnval;
}
void loggingWindow::on_openLogFileBtn_clicked()
{
QString cmd;
int rtnval = 0;
#ifdef Q_OS_MAC
cmd = "open " + logFilename;
#endif
#ifdef Q_OS_LINUX
cmd = "xdg-open " + logFilename;
#endif
#ifdef Q_OS_WIN
cmd = "notepad " + logFilename;
#endif
rtnval = system(cmd.toLocal8Bit().data());
if(rtnval)
qInfo(logLogger()) << "Error, open log file command returned error code " << rtnval;
}
void loggingWindow::on_sendToPasteBtn_clicked()
{
sendToTermbin();
}
void loggingWindow::on_annotateBtn_clicked()
{
QMutexLocker lock(&textMutex);
if(ui->userAnnotationText->text().isEmpty())
return;
qInfo(logUser()) << ui->userAnnotationText->text();
ui->userAnnotationText->clear();
}
void loggingWindow::on_userAnnotationText_returnPressed()
{
on_annotateBtn_clicked();
}
void loggingWindow::on_copyPathBtn_clicked()
{
clipboard->setText(logFilename);
}
void loggingWindow::on_debugBtn_clicked(bool checked)
{
emit setDebugMode(checked);
}
void loggingWindow::on_toBottomBtn_clicked()
{
vertLogScroll->setValue(vertLogScroll->maximum());
horizLogScroll->setValue(horizLogScroll->minimum());
}

72
loggingwindow.h 100644
Wyświetl plik

@ -0,0 +1,72 @@
#ifndef LOGGINGWINDOW_H
#define LOGGINGWINDOW_H
#include <QWidget>
#include <QMutexLocker>
#include <QMutex>
#include <QStandardPaths>
#include <QClipboard>
#include <QTcpSocket>
#include <QTextStream>
#include <QMessageBox>
#include <QScrollBar>
#include "logcategories.h"
namespace Ui {
class loggingWindow;
}
class loggingWindow : public QWidget
{
Q_OBJECT
public:
explicit loggingWindow(QWidget *parent = nullptr);
~loggingWindow();
void acceptLogText(QString text);
public slots:
void setInitialDebugState(bool debugModeEnabled);
private slots:
void connectedToHost();
void disconnectedFromHost();
void handleDataFromLoggingHost();
void handleLoggingHostError(QAbstractSocket::SocketError);
void showEvent(QShowEvent* event);
void on_clearDisplayBtn_clicked();
void on_openDirBtn_clicked();
void on_openLogFileBtn_clicked();
void on_sendToPasteBtn_clicked();
void on_annotateBtn_clicked();
void on_userAnnotationText_returnPressed();
void on_copyPathBtn_clicked();
void on_debugBtn_clicked(bool checked);
void on_toBottomBtn_clicked();
signals:
void setDebugMode(bool debugOn);
private:
Ui::loggingWindow *ui;
QClipboard *clipboard;
QMessageBox URLmsgBox;
QScrollBar *vertLogScroll;
QScrollBar *horizLogScroll;
QMutex textMutex;
QString logFilename;
QString logDirectory;
QTcpSocket *socket;
void sendToTermbin();
};
#endif // LOGGINGWINDOW_H

191
loggingwindow.ui 100644
Wyświetl plik

@ -0,0 +1,191 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>loggingWindow</class>
<widget class="QWidget" name="loggingWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>625</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPlainTextEdit" name="logTextDisplay">
<property name="undoRedoEnabled">
<bool>false</bool>
</property>
<property name="lineWrapMode">
<enum>QPlainTextEdit::NoWrap</enum>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="annotateLabel">
<property name="minimumSize">
<size>
<width>75</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>75</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Annotation:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="userAnnotationText">
<property name="minimumSize">
<size>
<width>290</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>You may enter your own log notes here.</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="annotateBtn">
<property name="minimumSize">
<size>
<width>85</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>85</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Adds user-text to the log.</string>
</property>
<property name="text">
<string>Annotate</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<item>
<widget class="QCheckBox" name="debugBtn">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Enable or disable debug logging. Use the &amp;quot;-d&amp;quot; or &amp;quot;--debug&amp;quot; flag to open wfview with debug logging enabled on startup. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Debug</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="toBottomBtn">
<property name="toolTip">
<string>Scroll to bottom</string>
</property>
<property name="text">
<string>Scroll Down</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="clearDisplayBtn">
<property name="toolTip">
<string>Clears the display. Does not clear the log file.</string>
</property>
<property name="text">
<string>Clear</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="openDirBtn">
<property name="toolTip">
<string>Makes a best-effort to ask the host system to open the log file directory.</string>
</property>
<property name="text">
<string>Open Log Directory</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="openLogFileBtn">
<property name="toolTip">
<string>Makes a best-effort to ask the host system to open the logfile.</string>
</property>
<property name="text">
<string>Open Log</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="copyPathBtn">
<property name="toolTip">
<string>Copy the path of the log file to your clipboard.</string>
</property>
<property name="text">
<string>Copy Path</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="sendToPasteBtn">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Sends text to termbin.com. Some personal information (such as your username) is in the log file, so do not click this button unless you are ok sharing your log file. This is a quick way to receive a URL, pointing to your log file text, that you can send to other people. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Send to termbin.com</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

Wyświetl plik

@ -12,12 +12,16 @@
#include <iostream> #include <iostream>
#include "wfmain.h" #include "wfmain.h"
// Copyright 2017-2022 Elliott H. Liggett
#include "logcategories.h" #include "logcategories.h"
// Copyright 2017-2021 Elliott H. Liggett #ifdef BUILD_WFSERVER
// Smart pointer to log file // Smart pointer to log file
QScopedPointer<QFile> logFile; QScopedPointer<QFile> m_logFile;
QMutex logMutex;
#endif
bool debugMode=false; bool debugMode=false;
#ifdef BUILD_WFSERVER #ifdef BUILD_WFSERVER
@ -32,7 +36,7 @@ bool debugMode=false;
Q_UNUSED(sig) Q_UNUSED(sig)
qDebug() << "Exiting via SIGNAL"; qDebug() << "Exiting via SIGNAL";
if (w!=Q_NULLPTR) w->deleteLater(); if (w!=Q_NULLPTR) w->deleteLater();
qApp->quit(); QCoreApplication::quit();
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
return true; return true;
@ -41,9 +45,9 @@ bool debugMode=false;
#endif #endif
} }
#endif
void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString& msg); void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString& msg);
#endif
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
@ -64,7 +68,7 @@ int main(int argc, char *argv[])
#endif #endif
#ifdef QT_DEBUG #ifdef QT_DEBUG
debugMode = true; //debugMode = true;
#endif #endif
QString serialPortCL; QString serialPortCL;
@ -159,6 +163,8 @@ int main(int argc, char *argv[])
} }
#ifdef BUILD_WFSERVER
// Set the logging file before doing anything else. // Set the logging file before doing anything else.
logFile.reset(new QFile(logFilename)); logFile.reset(new QFile(logFilename));
// Open the file logging // Open the file logging
@ -170,17 +176,19 @@ int main(int argc, char *argv[])
qDebug(logSystem()) << QString("SerialPortCL as set by parser: %1").arg(serialPortCL); qDebug(logSystem()) << QString("SerialPortCL as set by parser: %1").arg(serialPortCL);
qDebug(logSystem()) << QString("remote host as set by parser: %1").arg(hostCL); qDebug(logSystem()) << QString("remote host as set by parser: %1").arg(hostCL);
qDebug(logSystem()) << QString("CIV as set by parser: %1").arg(civCL); qDebug(logSystem()) << QString("CIV as set by parser: %1").arg(civCL);
#endif
#ifdef BUILD_WFSERVER #ifdef BUILD_WFSERVER
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
SetConsoleCtrlHandler((PHANDLER_ROUTINE)cleanup, TRUE); SetConsoleCtrlHandler((PHANDLER_ROUTINE)cleanup, TRUE);
#else #else
signal(SIGINT, cleanup); signal(SIGINT, cleanup);
signal(SIGTERM, cleanup);
signal(SIGKILL, cleanup);
#endif #endif
w = new servermain(serialPortCL, hostCL, settingsFile); w = new servermain(serialPortCL, hostCL, settingsFile);
#else #else
a.setWheelScrollLines(1); // one line per wheel click a.setWheelScrollLines(1); // one line per wheel click
wfmain w(serialPortCL, hostCL, settingsFile); wfmain w(serialPortCL, hostCL, settingsFile, debugMode);
w.show(); w.show();
#endif #endif
@ -188,6 +196,7 @@ int main(int argc, char *argv[])
} }
#ifdef BUILD_WFSERVER
void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString& msg) void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString& msg)
{ {
@ -196,9 +205,9 @@ void messageHandler(QtMsgType type, const QMessageLogContext& context, const QSt
{ {
return; return;
} }
static QMutex mutex; QMutexLocker locker(&logMutex);
QMutexLocker locker(&mutex); QTextStream out(m_logFile.data());
QTextStream out(logFile.data()); QString text;
// Write the date of recording // Write the date of recording
out << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz "); out << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz ");
@ -227,5 +236,8 @@ void messageHandler(QtMsgType type, const QMessageLogContext& context, const QSt
#ifdef BUILD_WFSERVER #ifdef BUILD_WFSERVER
std::cout << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz ").toLocal8Bit().toStdString() << msg.toLocal8Bit().toStdString() << "\n"; std::cout << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz ").toLocal8Bit().toStdString() << msg.toLocal8Bit().toStdString() << "\n";
#endif #endif
text = out.readAll();
out.flush(); // Clear the buffered data out.flush(); // Clear the buffered data
//mainwindow.handleLogText(test);
} }
#endif

156
meter.cpp
Wyświetl plik

@ -48,6 +48,26 @@ meter::meter(QWidget *parent) : QWidget(parent)
} }
void meter::setColors(QColor current, QColor peakScale, QColor peakLevel,
QColor average, QColor lowLine,
QColor lowText)
{
currentColor = current;
peakColor = peakLevel; // color for the peak level indicator
highLineColor = peakScale; // color for the red side of the scale
highTextColor = peakScale; // color for the red side of the scale's text
averageColor = average;
midScaleColor = QColor(Qt::yellow);
centerTuningColor = QColor(Qt::green);
lowLineColor = lowLine;
lowTextColor = lowText;
this->update();
}
void meter::clearMeterOnPTTtoggle() void meter::clearMeterOnPTTtoggle()
{ {
// When a meter changes type, such as the fixed S -- TxPo meter, // When a meter changes type, such as the fixed S -- TxPo meter,
@ -157,13 +177,29 @@ void meter::paintEvent(QPaintEvent *)
drawScaleId(&painter); drawScaleId(&painter);
break; break;
case meterComp: case meterComp:
label = "CMP"; label = "CMP(dB)";
peakRedLevel = 100; peakRedLevel = 100;
drawScaleComp(&painter); drawScaleComp(&painter);
break; break;
case meterNone: case meterNone:
return; return;
break; break;
case meterAudio:
label = "dBfs";
peakRedLevel = 241;
drawScale_dBFs(&painter);
break;
case meterRxAudio:
label = "Rx(dBfs)";
peakRedLevel = 241;
drawScale_dBFs(&painter);
break;
case meterTxMod:
label = "Tx(dBfs)";
peakRedLevel = 241;
drawScale_dBFs(&painter);
break;
default: default:
label = "DN"; label = "DN";
peakRedLevel = 241; peakRedLevel = 241;
@ -196,8 +232,37 @@ void meter::paintEvent(QPaintEvent *)
painter.drawRect(mXstart+peak-1,mYstart,1,barHeight); painter.drawRect(mXstart+peak-1,mYstart,1,barHeight);
} else if ( (meterType == meterAudio) ||
(meterType == meterTxMod) ||
(meterType == meterRxAudio))
{
// Log scale but still 0-255:
int logCurrent = (int)((1-audiopot[255-current])*255);
int logAverage = (int)((1-audiopot[255-average])*255);
int logPeak = (int)((1-audiopot[255-peak])*255);
// X, Y, Width, Height
painter.drawRect(mXstart,mYstart,logCurrent,barHeight);
// Average:
painter.setPen(averageColor);
painter.setBrush(averageColor);
painter.drawRect(mXstart+logAverage-1,mYstart,1,barHeight); // bar is 1 pixel wide, height = meter start?
// Peak:
painter.setPen(peakColor);
painter.setBrush(peakColor);
if(peak > peakRedLevel)
{
painter.setBrush(Qt::red);
painter.setPen(Qt::red);
}
painter.drawRect(mXstart+logPeak-1,mYstart,2,barHeight);
} else { } else {
// X, Y, Width, Height // X, Y, Width, Height
painter.drawRect(mXstart,mYstart,current,barHeight); painter.drawRect(mXstart,mYstart,current,barHeight);
@ -225,7 +290,7 @@ void meter::paintEvent(QPaintEvent *)
void meter::drawLabel(QPainter *qp) void meter::drawLabel(QPainter *qp)
{ {
qp->setPen(lowLineColor); qp->setPen(lowTextColor);
qp->drawText(0,scaleTextYstart, label ); qp->drawText(0,scaleTextYstart, label );
} }
@ -255,6 +320,22 @@ void meter::setLevel(int current)
this->update(); this->update();
} }
void meter::setLevels(int current, int peak)
{
this->current = current;
this->peak = peak;
avgLevels[(avgPosition++)%averageBalisticLength] = current;
int sum=0;
for(unsigned int i=0; i < (unsigned int)std::min(avgPosition, (int)avgLevels.size()); i++)
{
sum += avgLevels.at(i);
}
this->average = sum / std::min(avgPosition, (int)avgLevels.size());
this->update();
}
void meter::setLevels(int current, int peak, int average) void meter::setLevels(int current, int peak, int average)
{ {
this->current = current; this->current = current;
@ -287,9 +368,43 @@ void meter::drawScaleRaw(QPainter *qp)
// Line: X1, Y1 -->to--> X2, Y2 // Line: X1, Y1 -->to--> X2, Y2
qp->drawLine(mXstart,scaleLineYstart,peakRedLevel+mXstart,scaleLineYstart); qp->drawLine(mXstart,scaleLineYstart,peakRedLevel+mXstart,scaleLineYstart);
qp->setPen(Qt::red); qp->setPen(highLineColor);
qp->drawLine(peakRedLevel+mXstart,scaleLineYstart,255+mXstart,scaleLineYstart); qp->drawLine(peakRedLevel+mXstart,scaleLineYstart,255+mXstart,scaleLineYstart);
}
void meter::drawScale_dBFs(QPainter *qp)
{
qp->setPen(lowTextColor);
peakRedLevel = 193;
if(meterType==meterAudio)
qp->drawText(20+mXstart,scaleTextYstart, QString("-30"));
qp->drawText(38+mXstart+2,scaleTextYstart, QString("-24"));
qp->drawText(71+mXstart,scaleTextYstart, QString("-18"));
qp->drawText(124+mXstart,scaleTextYstart, QString("-12"));
qp->drawText(193+mXstart,scaleTextYstart, QString("-6"));
qp->drawText(255+mXstart,scaleTextYstart, QString("0"));
// Low ticks:
qp->setPen(lowLineColor);
qp->drawLine(20+mXstart,scaleTextYstart, 20+mXstart, scaleTextYstart+5);
qp->drawLine(38+mXstart,scaleTextYstart, 38+mXstart, scaleTextYstart+5);
qp->drawLine(71+mXstart,scaleTextYstart, 71+mXstart, scaleTextYstart+5);
qp->drawLine(124+mXstart,scaleTextYstart, 124+mXstart, scaleTextYstart+5);
// High ticks:
qp->setPen(highLineColor);
qp->drawLine(193+mXstart,scaleTextYstart, 193+mXstart, scaleTextYstart+5);
qp->drawLine(255+mXstart,scaleTextYstart, 255+mXstart, scaleTextYstart+5);
// Now the lines:
qp->setPen(lowLineColor);
// Line: X1, Y1 -->to--> X2, Y2
qp->drawLine(mXstart,scaleLineYstart,peakRedLevel+mXstart,scaleLineYstart);
qp->setPen(highLineColor);
qp->drawLine(peakRedLevel+mXstart,scaleLineYstart,255+mXstart,scaleLineYstart);
} }
void meter::drawScaleVd(QPainter *qp) void meter::drawScaleVd(QPainter *qp)
@ -326,7 +441,7 @@ void meter::drawScaleVd(QPainter *qp)
// Line: X1, Y1 -->to--> X2, Y2 // Line: X1, Y1 -->to--> X2, Y2
qp->drawLine(mXstart,scaleLineYstart,peakRedLevel+mXstart,scaleLineYstart); qp->drawLine(mXstart,scaleLineYstart,peakRedLevel+mXstart,scaleLineYstart);
qp->setPen(Qt::red); qp->setPen(highLineColor);
qp->drawLine(peakRedLevel+mXstart,scaleLineYstart,255+mXstart,scaleLineYstart); qp->drawLine(peakRedLevel+mXstart,scaleLineYstart,255+mXstart,scaleLineYstart);
} }
@ -337,7 +452,7 @@ void meter::drawScaleCenter(QPainter *qp)
qp->setPen(lowLineColor); qp->setPen(lowLineColor);
qp->drawText(60+mXstart,scaleTextYstart, QString("-")); qp->drawText(60+mXstart,scaleTextYstart, QString("-"));
qp->setPen(Qt::green); qp->setPen(centerTuningColor);
// Attempt to draw the zero at the actual center // Attempt to draw the zero at the actual center
qp->drawText(128-2+mXstart,scaleTextYstart, QString("0")); qp->drawText(128-2+mXstart,scaleTextYstart, QString("0"));
@ -348,7 +463,7 @@ void meter::drawScaleCenter(QPainter *qp)
qp->setPen(lowLineColor); qp->setPen(lowLineColor);
qp->drawLine(mXstart,scaleLineYstart,128-32+mXstart,scaleLineYstart); qp->drawLine(mXstart,scaleLineYstart,128-32+mXstart,scaleLineYstart);
qp->setPen(Qt::green); qp->setPen(centerTuningColor);
qp->drawLine(128-32+mXstart,scaleLineYstart,128+32+mXstart,scaleLineYstart); qp->drawLine(128-32+mXstart,scaleLineYstart,128+32+mXstart,scaleLineYstart);
qp->setPen(lowLineColor); qp->setPen(lowLineColor);
@ -382,7 +497,7 @@ void meter::drawScalePo(QPainter *qp)
//qDebug() << "meter i: " << i; //qDebug() << "meter i: " << i;
dnPerWatt = (213-143.0f) / 50.0f; // 1.4 dn per watt dnPerWatt = (213-143.0f) / 50.0f; // 1.4 dn per watt
// P=5 here. // P=5 here.
qp->setPen(Qt::yellow); qp->setPen(midScaleColor);
int k=0; int k=0;
for(i=mXstart+143; i<mXstart+213; i+=(5*dnPerWatt)) for(i=mXstart+143; i<mXstart+213; i+=(5*dnPerWatt))
{ {
@ -392,7 +507,7 @@ void meter::drawScalePo(QPainter *qp)
} }
// Now we're out past 100: // Now we're out past 100:
qp->setPen(Qt::red); qp->setPen(highTextColor);
for(i=mXstart+213; i<mXstart+255; i+=(10*dnPerWatt)) for(i=mXstart+213; i<mXstart+255; i+=(10*dnPerWatt))
{ {
@ -406,7 +521,7 @@ void meter::drawScalePo(QPainter *qp)
// Line: X1, Y1 -->to--> X2, Y2 // Line: X1, Y1 -->to--> X2, Y2
qp->drawLine(mXstart,scaleLineYstart,213+mXstart,scaleLineYstart); qp->drawLine(mXstart,scaleLineYstart,213+mXstart,scaleLineYstart);
qp->setPen(Qt::red); qp->setPen(highLineColor);
qp->drawLine(213+mXstart,scaleLineYstart,255+mXstart,scaleLineYstart); qp->drawLine(213+mXstart,scaleLineYstart,255+mXstart,scaleLineYstart);
(void)qp; (void)qp;
@ -432,7 +547,7 @@ void meter::drawScaleALC(QPainter *qp)
alc +=20; alc +=20;
} }
qp->setPen(Qt::red); qp->setPen(highTextColor);
for(; i<mXstart+120; i+=(int)(10*i)) for(; i<mXstart+120; i+=(int)(10*i))
{ {
@ -443,7 +558,7 @@ void meter::drawScaleALC(QPainter *qp)
qp->setPen(lowLineColor); qp->setPen(lowLineColor);
qp->drawLine(mXstart,scaleLineYstart,100+mXstart,scaleLineYstart); qp->drawLine(mXstart,scaleLineYstart,100+mXstart,scaleLineYstart);
qp->setPen(Qt::red); qp->setPen(highLineColor);
qp->drawLine(100+mXstart,scaleLineYstart,255+mXstart,scaleLineYstart); qp->drawLine(100+mXstart,scaleLineYstart,255+mXstart,scaleLineYstart);
(void)qp; (void)qp;
@ -465,6 +580,7 @@ void meter::drawScaleComp(QPainter *qp)
float dBperDn = (float)(highPointdB-midPointdB) / float(highPointDn-midPointDn); float dBperDn = (float)(highPointdB-midPointdB) / float(highPointDn-midPointDn);
int i=mXstart; int i=mXstart;
i+=midPointDn/4; // skip the 0 for cleaner label space
for(; i<mXstart+midPointDn; i+=midPointDn/4) for(; i<mXstart+midPointDn; i+=midPointDn/4)
{ {
qp->drawText(i,scaleTextYstart, QString("%1").arg( (int)((i-mXstart) * (float(midPointdB) / float(midPointDn)) )) ); qp->drawText(i,scaleTextYstart, QString("%1").arg( (int)((i-mXstart) * (float(midPointdB) / float(midPointDn)) )) );
@ -483,7 +599,7 @@ void meter::drawScaleComp(QPainter *qp)
// Line: X1, Y1 -->to--> X2, Y2 // Line: X1, Y1 -->to--> X2, Y2
qp->drawLine(mXstart,scaleLineYstart,peakRedLevel+mXstart,scaleLineYstart); qp->drawLine(mXstart,scaleLineYstart,peakRedLevel+mXstart,scaleLineYstart);
qp->setPen(Qt::red); qp->setPen(highLineColor);
qp->drawLine(peakRedLevel+mXstart,scaleLineYstart,255+mXstart,scaleLineYstart); qp->drawLine(peakRedLevel+mXstart,scaleLineYstart,255+mXstart,scaleLineYstart);
} }
@ -495,27 +611,29 @@ void meter::drawScaleSWR(QPainter *qp)
// 0080=SWR2.0, // 0080=SWR2.0,
// 0120=SWR3.0 // 0120=SWR3.0
qp->setPen(lowTextColor);
qp->drawText(mXstart,scaleTextYstart, QString("1.0")); qp->drawText(mXstart,scaleTextYstart, QString("1.0"));
qp->drawText(24+mXstart,scaleTextYstart, QString("1.3")); qp->drawText(24+mXstart,scaleTextYstart, QString("1.3"));
qp->drawText(48+mXstart,scaleTextYstart, QString("1.5")); qp->drawText(48+mXstart,scaleTextYstart, QString("1.5"));
qp->drawText(80+mXstart,scaleTextYstart, QString("2.0")); qp->drawText(80+mXstart,scaleTextYstart, QString("2.0"));
qp->drawText(100+mXstart,scaleTextYstart, QString("2.5")); qp->drawText(100+mXstart,scaleTextYstart, QString("2.5"));
qp->setPen(highTextColor);
qp->drawText(120+mXstart,scaleTextYstart, QString("3.0")); qp->drawText(120+mXstart,scaleTextYstart, QString("3.0"));
qp->setPen(lowLineColor);
qp->drawLine( 0+mXstart,scaleTextYstart, 0+mXstart, scaleTextYstart+5); qp->drawLine( 0+mXstart,scaleTextYstart, 0+mXstart, scaleTextYstart+5);
qp->drawLine( 24+mXstart,scaleTextYstart, 24+mXstart, scaleTextYstart+5); qp->drawLine( 24+mXstart,scaleTextYstart, 24+mXstart, scaleTextYstart+5);
qp->drawLine( 48+mXstart,scaleTextYstart, 48+mXstart, scaleTextYstart+5); qp->drawLine( 48+mXstart,scaleTextYstart, 48+mXstart, scaleTextYstart+5);
qp->drawLine( 80+mXstart,scaleTextYstart, 80+mXstart, scaleTextYstart+5); qp->drawLine( 80+mXstart,scaleTextYstart, 80+mXstart, scaleTextYstart+5);
qp->drawLine(100+mXstart,scaleTextYstart,100+mXstart, scaleTextYstart+5); // does not draw? qp->drawLine(100+mXstart,scaleTextYstart,100+mXstart, scaleTextYstart+5); // does not draw?
qp->setPen(highLineColor);
qp->drawLine(120+mXstart,scaleTextYstart,120+mXstart, scaleTextYstart+5); qp->drawLine(120+mXstart,scaleTextYstart,120+mXstart, scaleTextYstart+5);
qp->setPen(lowLineColor); qp->setPen(lowLineColor);
qp->drawLine(mXstart,scaleLineYstart,100+mXstart,scaleLineYstart); qp->drawLine(mXstart,scaleLineYstart,100+mXstart,scaleLineYstart);
qp->setPen(Qt::red); qp->setPen(highLineColor);
qp->drawLine(100+mXstart,scaleLineYstart,255+mXstart,scaleLineYstart); qp->drawLine(100+mXstart,scaleLineYstart,255+mXstart,scaleLineYstart);
} }
void meter::drawScaleId(QPainter *qp) void meter::drawScaleId(QPainter *qp)
@ -553,7 +671,7 @@ void meter::drawScaleId(QPainter *qp)
// Line: X1, Y1 -->to--> X2, Y2 // Line: X1, Y1 -->to--> X2, Y2
qp->drawLine(mXstart,scaleLineYstart,peakRedLevel+mXstart,scaleLineYstart); qp->drawLine(mXstart,scaleLineYstart,peakRedLevel+mXstart,scaleLineYstart);
qp->setPen(Qt::red); qp->setPen(highLineColor);
qp->drawLine(peakRedLevel+mXstart,scaleLineYstart,255+mXstart,scaleLineYstart); qp->drawLine(peakRedLevel+mXstart,scaleLineYstart,255+mXstart,scaleLineYstart);
} }
@ -582,7 +700,7 @@ void meter::drawScaleS(QPainter *qp)
s = 20; s = 20;
i+=20; i+=20;
qp->setPen(Qt::red); qp->setPen(highTextColor);
for(; i<mXstart+255; i+=40) for(; i<mXstart+255; i+=40)
{ {
@ -592,9 +710,7 @@ void meter::drawScaleS(QPainter *qp)
} }
qp->setPen(lowLineColor); qp->setPen(lowLineColor);
qp->drawLine(mXstart,scaleLineYstart,peakRedLevel+mXstart,scaleLineYstart); qp->drawLine(mXstart,scaleLineYstart,peakRedLevel+mXstart,scaleLineYstart);
qp->setPen(Qt::red); qp->setPen(highLineColor);
qp->drawLine(peakRedLevel+mXstart,scaleLineYstart,255+mXstart,scaleLineYstart); qp->drawLine(peakRedLevel+mXstart,scaleLineYstart,255+mXstart,scaleLineYstart);
} }

Wyświetl plik

@ -9,6 +9,7 @@
#include <cmath> #include <cmath>
#include "rigcommander.h" // for meter types #include "rigcommander.h" // for meter types
#include "audiotaper.h"
class meter : public QWidget class meter : public QWidget
{ {
@ -23,6 +24,7 @@ public slots:
void updateDrawing(int num); void updateDrawing(int num);
void setLevels(int current, int peak, int average); void setLevels(int current, int peak, int average);
void setLevels(int current, int peak); // calculate avg
void setLevel(int current); void setLevel(int current);
void clearMeterOnPTTtoggle(); void clearMeterOnPTTtoggle();
void clearMeter(); void clearMeter();
@ -30,6 +32,9 @@ public slots:
void setMeterShortString(QString); void setMeterShortString(QString);
QString getMeterShortString(); QString getMeterShortString();
meterKind getMeterType(); meterKind getMeterType();
void setColors(QColor current, QColor peakScale, QColor peakLevel,
QColor average, QColor lowLine,
QColor lowText);
private: private:
@ -68,6 +73,7 @@ private:
void drawScaleVd(QPainter *qp); void drawScaleVd(QPainter *qp);
void drawScaleId(QPainter *qp); void drawScaleId(QPainter *qp);
void drawScaleComp(QPainter *qp); void drawScaleComp(QPainter *qp);
void drawScale_dBFs(QPainter *qp);
void drawScaleRaw(QPainter *qp); void drawScaleRaw(QPainter *qp);
void drawLabel(QPainter *qp); void drawLabel(QPainter *qp);
@ -84,6 +90,9 @@ private:
QColor highTextColor; QColor highTextColor;
QColor highLineColor; QColor highLineColor;
QColor midScaleColor;
QColor centerTuningColor;
}; };
#endif // METER_H #endif // METER_H

Wyświetl plik

@ -15,17 +15,15 @@ paHandler::paHandler(QObject* parent)
paHandler::~paHandler() paHandler::~paHandler()
{ {
if (isInitialized) {
Pa_StopStream(audio);
Pa_CloseStream(audio);
}
if (converterThread != Q_NULLPTR) { if (converterThread != Q_NULLPTR) {
converterThread->quit(); converterThread->quit();
converterThread->wait(); converterThread->wait();
} }
//Pa_Terminate(); if (isInitialized) {
Pa_StopStream(audio);
Pa_CloseStream(audio);
}
} }
@ -216,14 +214,11 @@ bool paHandler::init(audioSetup setup)
void paHandler::setVolume(unsigned char volume) void paHandler::setVolume(unsigned char volume)
{ {
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
this->volume = audiopot[volume] * 5; this->volume = audiopot[volume] * 5;
#else #else
this->volume = audiopot[volume]; this->volume = audiopot[volume];
#endif #endif
qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "setVolume: " << volume << "(" << this->volume << ")";
} }
void paHandler::incomingAudio(audioPacket packet) void paHandler::incomingAudio(audioPacket packet)
@ -280,8 +275,8 @@ void paHandler::convertedOutput(audioPacket packet) {
currentLatency = packet.time.msecsTo(QTime::currentTime()) + (info->outputLatency * 1000); currentLatency = packet.time.msecsTo(QTime::currentTime()) + (info->outputLatency * 1000);
} }
amplitude = packet.amplitude; amplitude = packet.amplitudePeak;
emit haveLevels(getAmplitude(), setup.latency, currentLatency, isUnderrun, isOverrun); emit haveLevels(getAmplitude(), static_cast<quint16>(packet.amplitudeRMS * 255.0), setup.latency, currentLatency, isUnderrun, isOverrun);
} }
} }
@ -291,10 +286,10 @@ void paHandler::convertedInput(audioPacket packet)
{ {
if (packet.data.size() > 0) { if (packet.data.size() > 0) {
emit haveAudioData(packet); emit haveAudioData(packet);
amplitude = packet.amplitude; amplitude = packet.amplitudePeak;
const PaStreamInfo* info = Pa_GetStreamInfo(audio); const PaStreamInfo* info = Pa_GetStreamInfo(audio);
currentLatency = packet.time.msecsTo(QTime::currentTime()) + (info->inputLatency * 1000); currentLatency = packet.time.msecsTo(QTime::currentTime()) + (info->inputLatency * 1000);
emit haveLevels(getAmplitude(), setup.latency, currentLatency, isUnderrun, isOverrun); emit haveLevels(getAmplitude(), packet.amplitudeRMS, setup.latency, currentLatency, isUnderrun, isOverrun);
} }
} }

Wyświetl plik

@ -55,7 +55,7 @@ signals:
void audioMessage(QString message); void audioMessage(QString message);
void sendLatency(quint16 newSize); void sendLatency(quint16 newSize);
void haveAudioData(const audioPacket& data); void haveAudioData(const audioPacket& data);
void haveLevels(quint16 amplitude, quint16 latency, quint16 current, bool under, bool over); void haveLevels(quint16 amplitudePeak, quint16 amplitudeRMS, quint16 latency, quint16 current, bool under, bool over);
void setupConverter(QAudioFormat in, QAudioFormat out, quint8 opus, quint8 resamp); void setupConverter(QAudioFormat in, QAudioFormat out, quint8 opus, quint8 resamp);
void sendToConverter(audioPacket audio); void sendToConverter(audioPacket audio);

Wyświetl plik

@ -6,12 +6,14 @@ static const QString greenSS = QString("color: white;border-radius: %1;backgroun
static const QString redSS = QString("color: white;border-radius: %1;background-color: qlineargradient(spread:pad, x1:0.145, y1:0.16, x2:0.92, y2:0.988636, stop:0 rgba(255, 12, 12, 255), stop:0.869347 rgba(103, 0, 0, 255));").arg(SIZE / 2); static const QString redSS = QString("color: white;border-radius: %1;background-color: qlineargradient(spread:pad, x1:0.145, y1:0.16, x2:0.92, y2:0.988636, stop:0 rgba(255, 12, 12, 255), stop:0.869347 rgba(103, 0, 0, 255));").arg(SIZE / 2);
static const QString orangeSS = QString("color: white;border-radius: %1;background-color: qlineargradient(spread:pad, x1:0.232, y1:0.272, x2:0.98, y2:0.959773, stop:0 rgba(255, 113, 4, 255), stop:1 rgba(91, 41, 7, 255))").arg(SIZE / 2); static const QString orangeSS = QString("color: white;border-radius: %1;background-color: qlineargradient(spread:pad, x1:0.232, y1:0.272, x2:0.98, y2:0.959773, stop:0 rgba(255, 113, 4, 255), stop:1 rgba(91, 41, 7, 255))").arg(SIZE / 2);
static const QString blueSS = QString("color: white;border-radius: %1;background-color: qlineargradient(spread:pad, x1:0.04, y1:0.0565909, x2:0.799, y2:0.795, stop:0 rgba(203, 220, 255, 255), stop:0.41206 rgba(0, 115, 255, 255), stop:1 rgba(0, 49, 109, 255));").arg(SIZE / 2); static const QString blueSS = QString("color: white;border-radius: %1;background-color: qlineargradient(spread:pad, x1:0.04, y1:0.0565909, x2:0.799, y2:0.795, stop:0 rgba(203, 220, 255, 255), stop:0.41206 rgba(0, 115, 255, 255), stop:1 rgba(0, 49, 109, 255));").arg(SIZE / 2);
static const QString blankSS = QString("color: white;border-radius: %1;background-color: qlineargradient(spread:pad, x1:0.04, y1:0.0565909, x2:0.799, y2:0.795, stop:0 rgba(203, 220, 255, 0), stop:0.41206 rgba(0, 115, 255, 0), stop:1 rgba(0, 49, 109, 0));").arg(SIZE / 2);
QLedLabel::QLedLabel(QWidget* parent) : QLedLabel::QLedLabel(QWidget* parent) :
QLabel(parent) QLabel(parent)
{ {
//Set to ok by default //Set to ok by default
setState(StateOkBlue); setState(StateOkBlue);
baseColor = QColor(0, 115, 255, 255);
setFixedSize(SIZE, SIZE); setFixedSize(SIZE, SIZE);
} }
@ -29,6 +31,11 @@ void QLedLabel::setState(State state)
setStyleSheet(redSS); setStyleSheet(redSS);
break; break;
case StateOkBlue: case StateOkBlue:
setStyleSheet(blueSS);
break;
case StateBlank:
setStyleSheet(blankSS);
break;
default: default:
setStyleSheet(blueSS); setStyleSheet(blueSS);
break; break;
@ -38,4 +45,62 @@ void QLedLabel::setState(State state)
void QLedLabel::setState(bool state) void QLedLabel::setState(bool state)
{ {
setState(state ? StateOk : StateError); setState(state ? StateOk : StateError);
} }
void QLedLabel::setColor(QColor customColor, bool applyGradient=true)
{
QColor top,middle,bottom;
this->baseColor = customColor;
if(applyGradient)
{
top = customColor.lighter(200);
middle = customColor;
bottom = customColor.darker(200);
} else {
top = customColor;
middle = customColor;
bottom = customColor;
}
// Stop 0 is the upper corner color, white-ish
// Stop 0.4 is the middle color
// Stop 1 is the bottom-right corner, darker.
QString colorSS = QString("color: white;\
border-radius: %1;background-color: \
qlineargradient(spread:pad, x1:0.04, \
y1:0.0565909, x2:0.799, y2:0.795, \
stop:0 \
rgba(%2, %3, %4, %5), \
stop:0.41206 \
rgba(%6, %7, %8, %9), \
stop:1 \
rgba(%10, %11, %12, %13));").arg(SIZE / 2)
.arg(top.red()).arg(top.green()).arg(top.blue()).arg(top.alpha())
.arg(middle.red()).arg(middle.green()).arg(middle.blue()).arg(middle.alpha())
.arg(bottom.red()).arg(bottom.green()).arg(bottom.blue()).arg(bottom.alpha());
setStyleSheet(colorSS);
}
void QLedLabel::setColor(QString colorString, bool applyGradient=true)
{
QColor c = QColor(colorString);
setColor(c, applyGradient);
}
void QLedLabel::setColor(QColor c)
{
this->setColor(c, true);
}
void QLedLabel::setColor(QString s)
{
this->setColor(s, true);
}
QColor QLedLabel::getColor()
{
return baseColor;
}

Wyświetl plik

@ -13,7 +13,8 @@ public:
StateOk, StateOk,
StateOkBlue, StateOkBlue,
StateWarning, StateWarning,
StateError StateError,
StateBlank
}; };
@ -22,6 +23,14 @@ signals:
public slots: public slots:
void setState(State state); void setState(State state);
void setState(bool state); void setState(bool state);
void setColor(QColor customColor, bool applyGradient);
void setColor(QString colorString, bool applyGradient);
void setColor(QColor c);
void setColor(QString s);
QColor getColor();
private:
QColor baseColor;
}; };
#endif // QLEDLABEL_H #endif // QLEDLABEL_H

Wyświetl plik

@ -166,6 +166,8 @@ void rigCommander::commSetup(unsigned char rigCivAddr, udpPreferences prefs, aud
// Connect for errors/alerts // Connect for errors/alerts
connect(udp, SIGNAL(haveNetworkError(QString, QString)), this, SLOT(handleSerialPortError(QString, QString))); connect(udp, SIGNAL(haveNetworkError(QString, QString)), this, SLOT(handleSerialPortError(QString, QString)));
connect(udp, SIGNAL(haveNetworkStatus(networkStatus)), this, SLOT(handleStatusUpdate(networkStatus))); connect(udp, SIGNAL(haveNetworkStatus(networkStatus)), this, SLOT(handleStatusUpdate(networkStatus)));
connect(udp, SIGNAL(haveNetworkAudioLevels(networkAudioLevels)), this, SLOT(handleNetworkAudioLevels(networkAudioLevels)));
connect(ptty, SIGNAL(haveSerialPortError(QString, QString)), this, SLOT(handleSerialPortError(QString, QString))); connect(ptty, SIGNAL(haveSerialPortError(QString, QString)), this, SLOT(handleSerialPortError(QString, QString)));
connect(this, SIGNAL(getMoreDebug()), ptty, SLOT(debugThis())); connect(this, SIGNAL(getMoreDebug()), ptty, SLOT(debugThis()));
@ -245,6 +247,11 @@ void rigCommander::handleStatusUpdate(const networkStatus status)
emit haveStatusUpdate(status); emit haveStatusUpdate(status);
} }
void rigCommander::handleNetworkAudioLevels(networkAudioLevels l)
{
emit haveNetworkAudioLevels(l);
}
bool rigCommander::usingLAN() bool rigCommander::usingLAN()
{ {
return usingNativeLAN; return usingNativeLAN;
@ -3536,6 +3543,34 @@ void rigCommander::determineRigCaps()
createMode(modeCW, 0x03, "CW"), createMode(modeCW_R, 0x07, "CW-R"), createMode(modeCW, 0x03, "CW"), createMode(modeCW_R, 0x07, "CW-R"),
}; };
break; break;
case model746:
rigCaps.modelName = QString("IC-746");
rigCaps.rigctlModel = 3023;
rigCaps.hasSpectrum = false;
rigCaps.inputs.clear();
rigCaps.hasLan = false;
rigCaps.hasEthernet = false;
rigCaps.hasWiFi = false;
rigCaps.hasFDcomms = false;
rigCaps.hasATU = true;
rigCaps.hasTBPF = true;
rigCaps.hasIFShift = true;
rigCaps.hasCTCSS = true;
rigCaps.hasDTCS = true;
rigCaps.hasAntennaSel = true;
rigCaps.preamps.push_back('\x01');
rigCaps.preamps.push_back('\x02');
rigCaps.attenuators.insert(rigCaps.attenuators.end(),{ '\x20'});
// There are two HF and VHF ant, 12-01 adn 12-02 select the HF, the VHF is auto selected
// this incorrectly shows up as 2 and 3 in the drop down.
rigCaps.antennas = {0x01, 0x02};
rigCaps.bands = standardHF;
rigCaps.bands.push_back(band2m);
rigCaps.bands.push_back(bandGen);
rigCaps.modes = commonModes;
rigCaps.transceiveCommand = QByteArrayLiteral("\x1a\x05\x00\x00");
break;
case model756pro: case model756pro:
rigCaps.modelName = QString("IC-756 Pro"); rigCaps.modelName = QString("IC-756 Pro");
rigCaps.rigctlModel = 3027; rigCaps.rigctlModel = 3027;

Wyświetl plik

@ -36,6 +36,7 @@ enum meterKind {
meterRxdB, meterRxdB,
meterTxMod, meterTxMod,
meterRxAudio, meterRxAudio,
meterAudio,
meterLatency meterLatency
}; };
@ -277,6 +278,7 @@ public slots:
// Housekeeping: // Housekeeping:
void handleStatusUpdate(const networkStatus status); void handleStatusUpdate(const networkStatus status);
void handleNetworkAudioLevels(networkAudioLevels);
void radioSelection(QList<radio_cap_packet> radios); void radioSelection(QList<radio_cap_packet> radios);
void radioUsage(quint8 radio, quint8 busy, QString name, QString ip); void radioUsage(quint8 radio, quint8 busy, QString name, QString ip);
void setCurrentRadio(quint8 radio); void setCurrentRadio(quint8 radio);
@ -288,6 +290,7 @@ signals:
void commReady(); void commReady();
void haveSerialPortError(const QString port, const QString errorText); void haveSerialPortError(const QString port, const QString errorText);
void haveStatusUpdate(const networkStatus status); void haveStatusUpdate(const networkStatus status);
void haveNetworkAudioLevels(const networkAudioLevels l);
void dataForComm(const QByteArray &outData); void dataForComm(const QByteArray &outData);
void toggleRTS(bool rtsOn); void toggleRTS(bool rtsOn);
@ -397,6 +400,11 @@ private:
quint16 decodeTone(QByteArray eTone); quint16 decodeTone(QByteArray eTone);
quint16 decodeTone(QByteArray eTone, bool &tinv, bool &rinv); quint16 decodeTone(QByteArray eTone, bool &tinv, bool &rinv);
unsigned char audioLevelRxMean[50];
unsigned char audioLevelRxPeak[50];
unsigned char audioLevelTxMean[50];
unsigned char audioLevelTxPeak[50];
void parseMode(); void parseMode();
void parseSpectrum(); void parseSpectrum();
void parseWFData(); void parseWFData();

Wyświetl plik

@ -58,8 +58,8 @@ model_kind determineRadioModel(unsigned char rigID)
case model736: case model736:
rig = model736; rig = model736;
break; break;
case model910h: case model746:
rig = model910h; rig = model746;
break; break;
case model756pro: case model756pro:
rig = model756pro; rig = model756pro;
@ -70,6 +70,9 @@ model_kind determineRadioModel(unsigned char rigID)
case model756proiii: case model756proiii:
rig = model756proiii; rig = model756proiii;
break; break;
case model910h:
rig = model910h;
break;
case model9100: case model9100:
rig = model9100; rig = model9100;
break; break;

Wyświetl plik

@ -32,6 +32,7 @@ enum model_kind {
model706 = 0x58, model706 = 0x58,
model718 = 0x5E, model718 = 0x5E,
model736 = 0x40, model736 = 0x40,
model746 = 0x56,
model756pro = 0x5C, model756pro = 0x5C,
model756proii = 0x64, model756proii = 0x64,
model756proiii = 0x6E, model756proiii = 0x6E,

Wyświetl plik

@ -6,6 +6,7 @@
#include <objbase.h> #include <objbase.h>
#endif #endif
#define RT_EXCEPTION
rtHandler::rtHandler(QObject* parent) rtHandler::rtHandler(QObject* parent)
{ {
@ -15,22 +16,27 @@ rtHandler::rtHandler(QObject* parent)
rtHandler::~rtHandler() rtHandler::~rtHandler()
{ {
if (converterThread != Q_NULLPTR) {
converterThread->quit();
converterThread->wait();
}
if (isInitialized) { if (isInitialized) {
#ifdef RT_EXCEPTION
try { try {
#endif
audio->abortStream(); audio->abortStream();
audio->closeStream(); audio->closeStream();
#ifdef RT_EXCEPTION
} }
catch (RtAudioError& e) { catch (RtAudioError& e) {
qInfo(logAudio()) << "Error closing stream:" << aParams.deviceId << ":" << QString::fromStdString(e.getMessage()); qInfo(logAudio()) << "Error closing stream:" << aParams.deviceId << ":" << QString::fromStdString(e.getMessage());
} }
#endif
delete audio; delete audio;
} }
if (converterThread != Q_NULLPTR) {
converterThread->quit();
converterThread->wait();
}
} }
@ -87,14 +93,17 @@ bool rtHandler::init(audioSetup setup)
} }
aParams.firstChannel = 0; aParams.firstChannel = 0;
#ifdef RT_EXCEPTION
try { try {
#endif
info = audio->getDeviceInfo(aParams.deviceId); info = audio->getDeviceInfo(aParams.deviceId);
#ifdef RT_EXCEPTION
} }
catch (RtAudioError e) { catch (RtAudioError e) {
qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "Device exception:" << aParams.deviceId << ":" << QString::fromStdString(e.getMessage()); qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "Device exception:" << aParams.deviceId << ":" << QString::fromStdString(e.getMessage());
goto errorHandler; goto errorHandler;
} }
#endif
if (info.probed) if (info.probed)
{ {
qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << QString::fromStdString(info.name) << "(" << aParams.deviceId << ") successfully probed"; qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << QString::fromStdString(info.name) << "(" << aParams.deviceId << ") successfully probed";
@ -190,7 +199,9 @@ bool rtHandler::init(audioSetup setup)
// Per channel chunk size. // Per channel chunk size.
this->chunkSize = (outFormat.bytesForDuration(setup.blockSize * 1000) / (outFormat.sampleSize()/8) / outFormat.channelCount()); this->chunkSize = (outFormat.bytesForDuration(setup.blockSize * 1000) / (outFormat.sampleSize()/8) / outFormat.channelCount());
#ifdef RT_EXCEPTION
try { try {
#endif
if (setup.isinput) { if (setup.isinput) {
audio->openStream(NULL, &aParams, sampleFormat, outFormat.sampleRate(), &this->chunkSize, &staticWrite, this, &options); audio->openStream(NULL, &aParams, sampleFormat, outFormat.sampleRate(), &this->chunkSize, &staticWrite, this, &options);
emit setupConverter(outFormat, inFormat, 7, setup.resampleQuality); emit setupConverter(outFormat, inFormat, 7, setup.resampleQuality);
@ -205,12 +216,14 @@ bool rtHandler::init(audioSetup setup)
isInitialized = true; isInitialized = true;
qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "device successfully opened"; qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "device successfully opened";
qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "detected latency:" << audio->getStreamLatency(); qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "detected latency:" << audio->getStreamLatency();
#ifdef RT_EXCEPTION
} }
catch (RtAudioError& e) { catch (RtAudioError& e) {
qInfo(logAudio()) << "Error opening:" << QString::fromStdString(e.getMessage()); qInfo(logAudio()) << "Error opening:" << QString::fromStdString(e.getMessage());
// Try again? // Try again?
goto errorHandler; goto errorHandler;
} }
#endif
} }
else else
{ {
@ -240,10 +253,7 @@ errorHandler:
void rtHandler::setVolume(unsigned char volume) void rtHandler::setVolume(unsigned char volume)
{ {
this->volume = audiopot[volume]; this->volume = audiopot[volume];
qInfo(logAudio()) << (setup.isinput ? "Input" : "Output") << "setVolume: " << volume << "(" << this->volume << ")";
} }
void rtHandler::incomingAudio(audioPacket packet) void rtHandler::incomingAudio(audioPacket packet)
@ -318,9 +328,9 @@ void rtHandler::convertedOutput(audioPacket packet)
audioMutex.lock(); audioMutex.lock();
arrayBuffer.append(packet.data); arrayBuffer.append(packet.data);
audioMutex.unlock(); audioMutex.unlock();
amplitude = packet.amplitude; amplitude = packet.amplitudePeak;
currentLatency = packet.time.msecsTo(QTime::currentTime()) + (outFormat.durationForBytes(audio->getStreamLatency() * (outFormat.sampleSize() / 8) * outFormat.channelCount())/1000); currentLatency = packet.time.msecsTo(QTime::currentTime()) + (outFormat.durationForBytes(audio->getStreamLatency() * (outFormat.sampleSize() / 8) * outFormat.channelCount())/1000);
emit haveLevels(getAmplitude(), setup.latency, currentLatency, isUnderrun, isOverrun); emit haveLevels(getAmplitude(), packet.amplitudeRMS, setup.latency, currentLatency, isUnderrun, isOverrun);
} }
@ -329,9 +339,9 @@ void rtHandler::convertedInput(audioPacket packet)
{ {
if (packet.data.size() > 0) { if (packet.data.size() > 0) {
emit haveAudioData(packet); emit haveAudioData(packet);
amplitude = packet.amplitude; amplitude = packet.amplitudePeak;
currentLatency = packet.time.msecsTo(QTime::currentTime()) + (outFormat.durationForBytes(audio->getStreamLatency() * (outFormat.sampleSize() / 8) * outFormat.channelCount())/1000); currentLatency = packet.time.msecsTo(QTime::currentTime()) + (outFormat.durationForBytes(audio->getStreamLatency() * (outFormat.sampleSize() / 8) * outFormat.channelCount())/1000);
emit haveLevels(getAmplitude(), setup.latency, currentLatency, isUnderrun, isOverrun); emit haveLevels(getAmplitude(), static_cast<quint16>(packet.amplitudeRMS * 255.0), setup.latency, currentLatency, isUnderrun, isOverrun);
} }
} }

Wyświetl plik

@ -61,7 +61,7 @@ signals:
void audioMessage(QString message); void audioMessage(QString message);
void sendLatency(quint16 newSize); void sendLatency(quint16 newSize);
void haveAudioData(const audioPacket& data); void haveAudioData(const audioPacket& data);
void haveLevels(quint16 amplitude, quint16 latency, quint16 current, bool under, bool over); void haveLevels(quint16 amplitudePeak, quint16 amplitudeRMS, quint16 latency, quint16 current, bool under, bool over);
void setupConverter(QAudioFormat in, QAudioFormat out, quint8 opus, quint8 resamp); void setupConverter(QAudioFormat in, QAudioFormat out, quint8 opus, quint8 resamp);
void sendToConverter(audioPacket audio); void sendToConverter(audioPacket audio);

Wyświetl plik

@ -8,6 +8,8 @@ udpAudio::udpAudio(QHostAddress local, QHostAddress ip, quint16 audioPort, quint
this->localIP = local; this->localIP = local;
this->port = audioPort; this->port = audioPort;
this->radioIP = ip; this->radioIP = ip;
this->rxSetup = rxSetup;
this->txSetup = txSetup;
if (txSetup.sampleRate == 0) { if (txSetup.sampleRate == 0) {
enableTx = false; enableTx = false;
@ -16,74 +18,8 @@ udpAudio::udpAudio(QHostAddress local, QHostAddress ip, quint16 audioPort, quint
init(lport); // Perform connection init(lport); // Perform connection
QUdpSocket::connect(udp, &QUdpSocket::readyRead, this, &udpAudio::dataReceived); QUdpSocket::connect(udp, &QUdpSocket::readyRead, this, &udpAudio::dataReceived);
if (rxSetup.type == qtAudio) {
rxaudio = new audioHandler(); startAudio();
}
else if (rxSetup.type == portAudio) {
rxaudio = new paHandler();
}
else if (rxSetup.type == rtAudio) {
rxaudio = new rtHandler();
}
else
{
qCritical(logAudio()) << "Unsupported Receive Audio Handler selected!";
}
rxAudioThread = new QThread(this);
rxAudioThread->setObjectName("rxAudio()");
rxaudio->moveToThread(rxAudioThread);
rxAudioThread->start(QThread::TimeCriticalPriority);
connect(this, SIGNAL(setupRxAudio(audioSetup)), rxaudio, SLOT(init(audioSetup)));
// signal/slot not currently used.
connect(this, SIGNAL(haveAudioData(audioPacket)), rxaudio, SLOT(incomingAudio(audioPacket)));
connect(this, SIGNAL(haveChangeLatency(quint16)), rxaudio, SLOT(changeLatency(quint16)));
connect(this, SIGNAL(haveSetVolume(unsigned char)), rxaudio, SLOT(setVolume(unsigned char)));
connect(rxaudio, SIGNAL(haveLevels(quint16, quint16, quint16, bool,bool)), this, SLOT(getRxLevels(quint16, quint16, quint16, bool,bool)));
connect(rxAudioThread, SIGNAL(finished()), rxaudio, SLOT(deleteLater()));
sendControl(false, 0x03, 0x00); // First connect packet
pingTimer = new QTimer();
connect(pingTimer, &QTimer::timeout, this, &udpBase::sendPing);
pingTimer->start(PING_PERIOD); // send ping packets every 100ms
if (enableTx) {
if (txSetup.type == qtAudio) {
txaudio = new audioHandler();
}
else if (txSetup.type == portAudio) {
txaudio = new paHandler();
}
else if (txSetup.type == rtAudio) {
txaudio = new rtHandler();
}
else
{
qCritical(logAudio()) << "Unsupported Transmit Audio Handler selected!";
}
txAudioThread = new QThread(this);
rxAudioThread->setObjectName("txAudio()");
txaudio->moveToThread(txAudioThread);
txAudioThread->start(QThread::TimeCriticalPriority);
connect(this, SIGNAL(setupTxAudio(audioSetup)), txaudio, SLOT(init(audioSetup)));
connect(txaudio, SIGNAL(haveAudioData(audioPacket)), this, SLOT(receiveAudioData(audioPacket)));
connect(txaudio, SIGNAL(haveLevels(quint16, quint16, quint16, bool, bool)), this, SLOT(getTxLevels(quint16, quint16, quint16, bool, bool)));
connect(txAudioThread, SIGNAL(finished()), txaudio, SLOT(deleteLater()));
emit setupTxAudio(txSetup);
}
emit setupRxAudio(rxSetup);
watchdogTimer = new QTimer(); watchdogTimer = new QTimer();
connect(watchdogTimer, &QTimer::timeout, this, &udpAudio::watchdog); connect(watchdogTimer, &QTimer::timeout, this, &udpAudio::watchdog);
@ -96,6 +32,7 @@ udpAudio::udpAudio(QHostAddress local, QHostAddress ip, quint16 audioPort, quint
udpAudio::~udpAudio() udpAudio::~udpAudio()
{ {
if (pingTimer != Q_NULLPTR) if (pingTimer != Q_NULLPTR)
{ {
qDebug(logUdp()) << "Stopping pingTimer"; qDebug(logUdp()) << "Stopping pingTimer";
@ -145,6 +82,21 @@ void udpAudio::watchdog()
qInfo(logUdp()) << " Audio Watchdog: no audio data received for 2s, restart required?"; qInfo(logUdp()) << " Audio Watchdog: no audio data received for 2s, restart required?";
alerted = true; alerted = true;
if (rxAudioThread != Q_NULLPTR) {
qDebug(logUdp()) << "Stopping rxaudio thread";
rxAudioThread->quit();
rxAudioThread->wait();
rxAudioThread = Q_NULLPTR;
rxaudio = Q_NULLPTR;
}
if (txAudioThread != Q_NULLPTR) {
qDebug(logUdp()) << "Stopping txaudio thread";
txAudioThread->quit();
txAudioThread->wait();
txAudioThread = Q_NULLPTR;
txaudio = Q_NULLPTR;
}
} }
} }
else else
@ -207,17 +159,18 @@ void udpAudio::setVolume(unsigned char value)
emit haveSetVolume(value); emit haveSetVolume(value);
} }
void udpAudio::getRxLevels(quint16 amplitude, quint16 latency, quint16 current, bool under, bool over) { void udpAudio::getRxLevels(quint16 amplitudePeak, quint16 amplitudeRMS, quint16 latency, quint16 current, bool under, bool over) {
emit haveRxLevels(amplitude, latency, current, under, over); emit haveRxLevels(amplitudePeak, amplitudeRMS, latency, current, under, over);
} }
void udpAudio::getTxLevels(quint16 amplitude, quint16 latency, quint16 current, bool under, bool over) { void udpAudio::getTxLevels(quint16 amplitudePeak, quint16 amplitudeRMS, quint16 latency, quint16 current, bool under, bool over) {
emit haveTxLevels(amplitude, latency, current, under, over); emit haveTxLevels(amplitudePeak, amplitudeRMS, latency, current, under, over);
} }
void udpAudio::dataReceived() void udpAudio::dataReceived()
{ {
while (udp->hasPendingDatagrams()) { while (udp->hasPendingDatagrams()) {
QNetworkDatagram datagram = udp->receiveDatagram(); QNetworkDatagram datagram = udp->receiveDatagram();
//qInfo(logUdp()) << "Received: " << datagram.data().mid(0,10); //qInfo(logUdp()) << "Received: " << datagram.data().mid(0,10);
@ -258,6 +211,10 @@ void udpAudio::dataReceived()
// Prefer signal/slot to forward audio as it is thread/safe // Prefer signal/slot to forward audio as it is thread/safe
// Need to do more testing but latency appears fine. // Need to do more testing but latency appears fine.
//rxaudio->incomingAudio(tempAudio); //rxaudio->incomingAudio(tempAudio);
if (rxAudioThread == Q_NULLPTR)
{
startAudio();
}
emit haveAudioData(tempAudio); emit haveAudioData(tempAudio);
} }
break; break;
@ -270,4 +227,75 @@ void udpAudio::dataReceived()
} }
} }
void udpAudio::startAudio() {
if (rxSetup.type == qtAudio) {
rxaudio = new audioHandler();
}
else if (rxSetup.type == portAudio) {
rxaudio = new paHandler();
}
else if (rxSetup.type == rtAudio) {
rxaudio = new rtHandler();
}
else
{
qCritical(logAudio()) << "Unsupported Receive Audio Handler selected!";
}
rxAudioThread = new QThread(this);
rxAudioThread->setObjectName("rxAudio()");
rxaudio->moveToThread(rxAudioThread);
rxAudioThread->start(QThread::TimeCriticalPriority);
connect(this, SIGNAL(setupRxAudio(audioSetup)), rxaudio, SLOT(init(audioSetup)));
// signal/slot not currently used.
connect(this, SIGNAL(haveAudioData(audioPacket)), rxaudio, SLOT(incomingAudio(audioPacket)));
connect(this, SIGNAL(haveChangeLatency(quint16)), rxaudio, SLOT(changeLatency(quint16)));
connect(this, SIGNAL(haveSetVolume(unsigned char)), rxaudio, SLOT(setVolume(unsigned char)));
connect(rxaudio, SIGNAL(haveLevels(quint16, quint16, quint16, quint16, bool, bool)), this, SLOT(getRxLevels(quint16, quint16, quint16, quint16, bool, bool)));
connect(rxAudioThread, SIGNAL(finished()), rxaudio, SLOT(deleteLater()));
sendControl(false, 0x03, 0x00); // First connect packet
pingTimer = new QTimer();
connect(pingTimer, &QTimer::timeout, this, &udpBase::sendPing);
pingTimer->start(PING_PERIOD); // send ping packets every 100ms
if (enableTx) {
if (txSetup.type == qtAudio) {
txaudio = new audioHandler();
}
else if (txSetup.type == portAudio) {
txaudio = new paHandler();
}
else if (txSetup.type == rtAudio) {
txaudio = new rtHandler();
}
else
{
qCritical(logAudio()) << "Unsupported Transmit Audio Handler selected!";
}
txAudioThread = new QThread(this);
rxAudioThread->setObjectName("txAudio()");
txaudio->moveToThread(txAudioThread);
txAudioThread->start(QThread::TimeCriticalPriority);
connect(this, SIGNAL(setupTxAudio(audioSetup)), txaudio, SLOT(init(audioSetup)));
connect(txaudio, SIGNAL(haveAudioData(audioPacket)), this, SLOT(receiveAudioData(audioPacket)));
connect(txaudio, SIGNAL(haveLevels(quint16, quint16, quint16, quint16, bool, bool)), this, SLOT(getTxLevels(quint16, quint16, quint16, quint16, bool, bool)));
connect(txAudioThread, SIGNAL(finished()), txaudio, SLOT(deleteLater()));
emit setupTxAudio(txSetup);
}
emit setupRxAudio(rxSetup);
}

Wyświetl plik

@ -51,14 +51,14 @@ signals:
void haveChangeLatency(quint16 value); void haveChangeLatency(quint16 value);
void haveSetVolume(unsigned char value); void haveSetVolume(unsigned char value);
void haveRxLevels(quint16 amplitude, quint16 latency, quint16 current, bool under, bool over); void haveRxLevels(quint16 amplitudePeak, quint16 amplitudeRMS, quint16 latency, quint16 current, bool under, bool over);
void haveTxLevels(quint16 amplitude, quint16 latency, quint16 current, bool under, bool over); void haveTxLevels(quint16 amplitudePeak, quint16 amplitudeRMS, quint16 latency, quint16 current, bool under, bool over);
public slots: public slots:
void changeLatency(quint16 value); void changeLatency(quint16 value);
void setVolume(unsigned char value); void setVolume(unsigned char value);
void getRxLevels(quint16 amplitude, quint16 latency, quint16 current, bool under, bool over); void getRxLevels(quint16 amplitude, quint16 amplitudeRMS, quint16 latency, quint16 current, bool under, bool over);
void getTxLevels(quint16 amplitude, quint16 latency, quint16 current, bool under, bool over); void getTxLevels(quint16 amplitude, quint16 amplitudeRMS, quint16 latency, quint16 current, bool under, bool over);
void receiveAudioData(audioPacket audio); void receiveAudioData(audioPacket audio);
private: private:
@ -66,6 +66,9 @@ private:
void sendTxAudio(); void sendTxAudio();
void dataReceived(); void dataReceived();
void watchdog(); void watchdog();
void startAudio();
audioSetup rxSetup;
audioSetup txSetup;
uint16_t sendAudioSeq = 0; uint16_t sendAudioSeq = 0;
@ -82,4 +85,4 @@ private:
}; };
#endif #endif

Wyświetl plik

@ -37,6 +37,15 @@ struct udpPreferences {
quint8 waterfallFormat; quint8 waterfallFormat;
}; };
struct networkAudioLevels {
bool haveTxLevels = false;
bool haveRxLevels = false;
quint8 rxAudioRMS = 0;
quint8 txAudioRMS = 0;
quint8 rxAudioPeak = 0;
quint8 txAudioPeak = 0;
};
struct networkStatus { struct networkStatus {
quint8 rxAudioBufferPercent; quint8 rxAudioBufferPercent;
quint8 txAudioBufferPercent; quint8 txAudioBufferPercent;

Wyświetl plik

@ -143,20 +143,71 @@ void udpHandler::receiveDataFromUserToRig(QByteArray data)
} }
} }
void udpHandler::getRxLevels(quint16 amplitude,quint16 latency,quint16 current, bool under, bool over) { void udpHandler::getRxLevels(quint16 amplitudePeak, quint16 amplitudeRMS,quint16 latency,quint16 current, bool under, bool over) {
status.rxAudioLevel = amplitude; status.rxAudioLevel = amplitudePeak;
status.rxLatency = latency; status.rxLatency = latency;
status.rxCurrentLatency = current; status.rxCurrentLatency = current;
status.rxUnderrun = under; status.rxUnderrun = under;
status.rxOverrun = over; status.rxOverrun = over;
audioLevelsRxPeak[(audioLevelsRxPosition)%audioLevelBufferSize] = amplitudePeak;
audioLevelsRxRMS[(audioLevelsRxPosition)%audioLevelBufferSize] = amplitudeRMS;
if((audioLevelsRxPosition)%4 == 0)
{
// calculate mean and emit signal
unsigned char meanPeak = findMax(audioLevelsRxPeak);
unsigned char meanRMS = findMean(audioLevelsRxRMS);
networkAudioLevels l;
l.haveRxLevels = true;
l.rxAudioPeak = meanPeak;
l.rxAudioRMS = meanRMS;
emit haveNetworkAudioLevels(l);
}
audioLevelsRxPosition++;
} }
void udpHandler::getTxLevels(quint16 amplitude,quint16 latency, quint16 current, bool under, bool over) { void udpHandler::getTxLevels(quint16 amplitudePeak, quint16 amplitudeRMS ,quint16 latency, quint16 current, bool under, bool over) {
status.txAudioLevel = amplitude; status.txAudioLevel = amplitudePeak;
status.txLatency = latency; status.txLatency = latency;
status.txCurrentLatency = current; status.txCurrentLatency = current;
status.txUnderrun = under; status.txUnderrun = under;
status.txOverrun = over; status.txOverrun = over;
audioLevelsTxPeak[(audioLevelsTxPosition)%audioLevelBufferSize] = amplitudePeak;
audioLevelsTxRMS[(audioLevelsTxPosition)%audioLevelBufferSize] = amplitudeRMS;
if((audioLevelsTxPosition)%4 == 0)
{
// calculate mean and emit signal
unsigned char meanPeak = findMax(audioLevelsTxPeak);
unsigned char meanRMS = findMean(audioLevelsTxRMS);
networkAudioLevels l;
l.haveTxLevels = true;
l.txAudioPeak = meanPeak;
l.txAudioRMS = meanRMS;
emit haveNetworkAudioLevels(l);
}
audioLevelsTxPosition++;
}
unsigned char udpHandler::findMean(unsigned char *data)
{
unsigned int sum=0;
for(int p=0; p < audioLevelBufferSize; p++)
{
sum += data[p];
}
return sum / audioLevelBufferSize;
}
unsigned char udpHandler::findMax(unsigned char *data)
{
unsigned int max=0;
for(int p=0; p < audioLevelBufferSize; p++)
{
if(data[p] > max)
max = data[p];
}
return max;
} }
void udpHandler::dataReceived() void udpHandler::dataReceived()
@ -302,23 +353,25 @@ void udpHandler::dataReceived()
if (!streamOpened) { if (!streamOpened) {
civ = new udpCivData(localIP, radioIP, civPort, splitWf, civLocalPort); civ = new udpCivData(localIP, radioIP, civPort, splitWf, civLocalPort);
QObject::connect(civ, SIGNAL(receive(QByteArray)), this, SLOT(receiveFromCivStream(QByteArray)));
// TX is not supported // TX is not supported
if (txSampleRates < 2) { if (txSampleRates < 2) {
txSetup.sampleRate=0; txSetup.sampleRate=0;
txSetup.codec = 0; txSetup.codec = 0;
} }
streamOpened = true;
}
if (audio == Q_NULLPTR) {
audio = new udpAudio(localIP, radioIP, audioPort, audioLocalPort, rxSetup, txSetup); audio = new udpAudio(localIP, radioIP, audioPort, audioLocalPort, rxSetup, txSetup);
QObject::connect(civ, SIGNAL(receive(QByteArray)), this, SLOT(receiveFromCivStream(QByteArray)));
QObject::connect(audio, SIGNAL(haveAudioData(audioPacket)), this, SLOT(receiveAudioData(audioPacket))); QObject::connect(audio, SIGNAL(haveAudioData(audioPacket)), this, SLOT(receiveAudioData(audioPacket)));
QObject::connect(this, SIGNAL(haveChangeLatency(quint16)), audio, SLOT(changeLatency(quint16))); QObject::connect(this, SIGNAL(haveChangeLatency(quint16)), audio, SLOT(changeLatency(quint16)));
QObject::connect(this, SIGNAL(haveSetVolume(unsigned char)), audio, SLOT(setVolume(unsigned char))); QObject::connect(this, SIGNAL(haveSetVolume(unsigned char)), audio, SLOT(setVolume(unsigned char)));
QObject::connect(audio, SIGNAL(haveRxLevels(quint16, quint16, quint16,bool,bool)), this, SLOT(getRxLevels(quint16, quint16,quint16,bool,bool))); QObject::connect(audio, SIGNAL(haveRxLevels(quint16, quint16, quint16, quint16, bool, bool)), this, SLOT(getRxLevels(quint16, quint16, quint16, quint16, bool, bool)));
QObject::connect(audio, SIGNAL(haveTxLevels(quint16, quint16,quint16,bool,bool)), this, SLOT(getTxLevels(quint16, quint16,quint16,bool,bool))); QObject::connect(audio, SIGNAL(haveTxLevels(quint16, quint16, quint16, quint16, bool, bool)), this, SLOT(getTxLevels(quint16, quint16, quint16, quint16, bool, bool)));
streamOpened = true;
} }
qInfo(logUdp()) << this->metaObject()->className() << "Got serial and audio request success, device name: " << devName; qInfo(logUdp()) << this->metaObject()->className() << "Got serial and audio request success, device name: " << devName;

Wyświetl plik

@ -29,7 +29,7 @@
#include "udpcivdata.h" #include "udpcivdata.h"
#include "udpaudio.h" #include "udpaudio.h"
#define audioLevelBufferSize (4)
// Class to handle the connection/disconnection of the radio. // Class to handle the connection/disconnection of the radio.
class udpHandler: public udpBase class udpHandler: public udpBase
@ -56,9 +56,8 @@ public slots:
void setVolume(unsigned char value); void setVolume(unsigned char value);
void init(); void init();
void setCurrentRadio(quint8 radio); void setCurrentRadio(quint8 radio);
void getRxLevels(quint16 amplitude, quint16 latency, quint16 current, bool under, bool over); void getRxLevels(quint16 amplitudePeak, quint16 amplitudeRMS, quint16 latency, quint16 current, bool under, bool over);
void getTxLevels(quint16 amplitude, quint16 latency, quint16 current, bool under, bool over); void getTxLevels(quint16 amplitudePeak, quint16 amplitudeRMS, quint16 latency, quint16 current, bool under, bool over);
signals: signals:
void haveDataFromPort(QByteArray data); // emit this when we have data, connect to rigcommander void haveDataFromPort(QByteArray data); // emit this when we have data, connect to rigcommander
@ -67,6 +66,7 @@ signals:
void haveChangeLatency(quint16 value); void haveChangeLatency(quint16 value);
void haveSetVolume(unsigned char value); void haveSetVolume(unsigned char value);
void haveNetworkStatus(networkStatus); void haveNetworkStatus(networkStatus);
void haveNetworkAudioLevels(networkAudioLevels);
void haveBaudRate(quint32 baudrate); void haveBaudRate(quint32 baudrate);
void requestRadioSelection(QList<radio_cap_packet> radios); void requestRadioSelection(QList<radio_cap_packet> radios);
void setRadioUsage(quint8, quint8 busy, QString name, QString mac); void setRadioUsage(quint8, quint8 busy, QString name, QString mac);
@ -122,6 +122,19 @@ private:
quint16 txSampleRates = 0; quint16 txSampleRates = 0;
networkStatus status; networkStatus status;
bool splitWf = false; bool splitWf = false;
unsigned char audioLevelsTxPeak[audioLevelBufferSize];
unsigned char audioLevelsRxPeak[audioLevelBufferSize];
unsigned char audioLevelsTxRMS[audioLevelBufferSize];
unsigned char audioLevelsRxRMS[audioLevelBufferSize];
unsigned char audioLevelsTxPosition = 0;
unsigned char audioLevelsRxPosition = 0;
unsigned char findMean(unsigned char *d);
unsigned char findMax(unsigned char *d);
}; };

1809
wfmain.cpp

Plik diff jest za duży Load Diff

224
wfmain.h
Wyświetl plik

@ -15,6 +15,10 @@
#include <QShortcut> #include <QShortcut>
#include <QThread> #include <QThread>
#include <QMetaType> #include <QMetaType>
#include <QMutex>
#include <QMutexLocker>
#include <QColorDialog>
#include <QColor>
#include "logcategories.h" #include "logcategories.h"
#include "commhandler.h" #include "commhandler.h"
@ -34,6 +38,8 @@
#include "rigctld.h" #include "rigctld.h"
#include "aboutbox.h" #include "aboutbox.h"
#include "selectradio.h" #include "selectradio.h"
#include "colorprefs.h"
#include "loggingwindow.h"
#include <qcustomplot.h> #include <qcustomplot.h>
#include <qserialportinfo.h> #include <qserialportinfo.h>
@ -50,6 +56,7 @@
#include "rtaudio/RtAudio.h" #include "rtaudio/RtAudio.h"
#endif #endif
#define numColorPresetsTotal (5)
namespace Ui { namespace Ui {
class wfmain; class wfmain;
@ -60,10 +67,12 @@ class wfmain : public QMainWindow
Q_OBJECT Q_OBJECT
public: public:
explicit wfmain(const QString serialPortCL, const QString hostCL, const QString settingsFile, QWidget *parent = 0); explicit wfmain(const QString serialPortCL, const QString hostCL, const QString settingsFile, bool debugMode, QWidget *parent = 0);
QString serialPortCL; QString serialPortCL;
QString hostCL; QString hostCL;
~wfmain(); ~wfmain();
static void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString& msg);
void handleLogText(QString text);
signals: signals:
// Basic to rig: // Basic to rig:
@ -282,6 +291,7 @@ private slots:
void receiveFoundRigID(rigCapabilities rigCaps); void receiveFoundRigID(rigCapabilities rigCaps);
void receiveSerialPortError(QString port, QString errorText); void receiveSerialPortError(QString port, QString errorText);
void receiveStatusUpdate(networkStatus status); void receiveStatusUpdate(networkStatus status);
void receiveNetworkAudioLevels(networkAudioLevels l);
void handlePlotClick(QMouseEvent *); void handlePlotClick(QMouseEvent *);
void handlePlotDoubleClick(QMouseEvent *); void handlePlotDoubleClick(QMouseEvent *);
void handleWFClick(QMouseEvent *); void handleWFClick(QMouseEvent *);
@ -301,6 +311,8 @@ private slots:
void setBand(int band); void setBand(int band);
void setRadioTimeDateSend(); void setRadioTimeDateSend();
void logCheck();
void setDebugLogging(bool debugModeOn);
void buttonControl(const COMMAND* cmd); void buttonControl(const COMMAND* cmd);
@ -315,8 +327,6 @@ private slots:
void on_clearPeakBtn_clicked(); void on_clearPeakBtn_clicked();
void on_drawPeakChk_clicked(bool checked);
void on_fullScreenChk_clicked(bool checked); void on_fullScreenChk_clicked(bool checked);
void on_goFreqBtn_clicked(); void on_goFreqBtn_clicked();
@ -346,14 +356,8 @@ private slots:
void on_scopeEdgeCombo_currentIndexChanged(int index); void on_scopeEdgeCombo_currentIndexChanged(int index);
// void on_modeSelectCombo_currentIndexChanged(int index);
void on_useDarkThemeChk_clicked(bool checked);
void on_modeSelectCombo_activated(int index); void on_modeSelectCombo_activated(int index);
// void on_freqDial_actionTriggered(int action);
void on_freqDial_valueChanged(int value); void on_freqDial_valueChanged(int value);
void on_band6mbtn_clicked(); void on_band6mbtn_clicked();
@ -402,7 +406,6 @@ private slots:
void on_saveSettingsBtn_clicked(); void on_saveSettingsBtn_clicked();
void on_debugBtn_clicked(); void on_debugBtn_clicked();
void on_pttEnableChk_clicked(bool checked); void on_pttEnableChk_clicked(bool checked);
@ -445,7 +448,6 @@ private slots:
void on_dataModeBtn_toggled(bool checked); void on_dataModeBtn_toggled(bool checked);
void on_transmitBtn_clicked(); void on_transmitBtn_clicked();
void on_adjRefBtn_clicked(); void on_adjRefBtn_clicked();
@ -545,14 +547,14 @@ private slots:
void on_setClockBtn_clicked(); void on_setClockBtn_clicked();
void on_serverEnableCheckbox_clicked(bool checked); void on_serverEnableCheckbox_clicked(bool checked);
void on_serverUsersTable_cellClicked(int row, int col);
void on_serverControlPortText_textChanged(QString text); void on_serverControlPortText_textChanged(QString text);
void on_serverCivPortText_textChanged(QString text); void on_serverCivPortText_textChanged(QString text);
void on_serverAudioPortText_textChanged(QString text); void on_serverAudioPortText_textChanged(QString text);
void on_serverTXAudioOutputCombo_currentIndexChanged(int value); void on_serverTXAudioOutputCombo_currentIndexChanged(int value);
void on_serverRXAudioInputCombo_currentIndexChanged(int value); void on_serverRXAudioInputCombo_currentIndexChanged(int value);
void onServerPasswordChanged(); void onServerUserFieldChanged();
void on_serverUsersTable_cellChanged(int row, int column);
void on_serverAddUserBtn_clicked();
void on_useRTSforPTTchk_clicked(bool checked); void on_useRTSforPTTchk_clicked(bool checked);
@ -560,9 +562,115 @@ private slots:
void on_audioSystemCombo_currentIndexChanged(int value); void on_audioSystemCombo_currentIndexChanged(int value);
void on_topLevelSlider_valueChanged(int value);
void on_botLevelSlider_valueChanged(int value);
void on_underlayBufferSlider_valueChanged(int value);
void on_underlayNone_toggled(bool checked);
void on_underlayPeakHold_toggled(bool checked);
void on_underlayPeakBuffer_toggled(bool checked);
void on_underlayAverageBuffer_toggled(bool checked);
void on_colorSetBtnGrid_clicked();
void on_colorSetBtnPlotBackground_clicked();
void on_colorSetBtnText_clicked();
void on_colorSetBtnSpecLine_clicked();
void on_colorSetBtnSpecFill_clicked();
void on_colorEditPlotBackground_editingFinished();
void on_colorPopOutBtn_clicked();
void on_colorPresetCombo_currentIndexChanged(int index);
void on_colorEditSpecLine_editingFinished();
void on_colorEditGrid_editingFinished();
void on_colorEditText_editingFinished();
void on_colorEditSpecFill_editingFinished();
void on_colorSetBtnAxis_clicked();
void on_colorEditAxis_editingFinished();
void on_colorSetBtnUnderlayLine_clicked();
void on_colorEditUnderlayLine_editingFinished();
void on_colorSetBtnUnderlayFill_clicked();
void on_colorEditUnderlayFill_editingFinished();
void on_colorSetBtnwfBackground_clicked();
void on_colorEditWfBackground_editingFinished();
void on_colorSetBtnWfGrid_clicked();
void on_colorEditWfGrid_editingFinished();
void on_colorSetBtnWfAxis_clicked();
void on_colorEditWfAxis_editingFinished();
void on_colorSetBtnWfText_clicked();
void on_colorEditWfText_editingFinished();
void on_colorSetBtnTuningLine_clicked();
void on_colorEditTuningLine_editingFinished();
void on_colorSetBtnMeterLevel_clicked();
void on_colorEditMeterLevel_editingFinished();
void on_colorSetBtnMeterAvg_clicked();
void on_colorEditMeterAvg_editingFinished();
void on_colorSetBtnMeterScale_clicked();
void on_colorEditMeterScale_editingFinished();
void on_colorSetBtnMeterText_clicked();
void on_colorEditMeterText_editingFinished();
void on_colorRenamePresetBtn_clicked();
void on_colorRevertPresetBtn_clicked();
void on_colorSetBtnMeterPeakLevel_clicked();
void on_colorEditMeterPeakLevel_editingFinished();
void on_colorSetBtnMeterPeakScale_clicked();
void on_colorEditMeterPeakScale_editingFinished();
void on_colorSavePresetBtn_clicked();
void on_showLogBtn_clicked();
void on_audioSystemServerCombo_currentIndexChanged(int index);
private: private:
Ui::wfmain *ui; Ui::wfmain *ui;
void closeEvent(QCloseEvent *event); void closeEvent(QCloseEvent *event);
bool debugMode;
QString version;
QSettings *settings=Q_NULLPTR; QSettings *settings=Q_NULLPTR;
void loadSettings(); void loadSettings();
void saveSettings(); void saveSettings();
@ -570,14 +678,20 @@ private:
void createSettingsListItems(); void createSettingsListItems();
void connectSettingsList(); void connectSettingsList();
void initLogging();
QTimer logCheckingTimer;
int logCheckingOldPosition = 0;
QString logFilename;
QCustomPlot *plot; // line plot QCustomPlot *plot; // line plot
QCustomPlot *wf; // waterfall image QCustomPlot *wf; // waterfall image
QCPItemLine * freqIndicatorLine; QCPItemLine * freqIndicatorLine;
//commHandler *comm;
void setAppTheme(bool isCustom); void setAppTheme(bool isCustom);
void setPlotTheme(QCustomPlot *plot, bool isDark);
void prepareWf(); void prepareWf();
void prepareWf(unsigned int wfLength); void prepareWf(unsigned int wfLength);
void preparePlasma();
bool plasmaPrepared = false;
void computePlasma();
void showHideSpectrum(bool show); void showHideSpectrum(bool show);
void getInitialRigState(); void getInitialRigState();
void setBandButtons(); void setBandButtons();
@ -669,13 +783,28 @@ private:
quint16 wfLength; quint16 wfLength;
bool spectrumDrawLock; bool spectrumDrawLock;
enum underlay_t { underlayNone, underlayPeakHold, underlayPeakBuffer, underlayAverageBuffer };
QByteArray spectrumPeaks; QByteArray spectrumPeaks;
QVector <double> spectrumPlasmaLine;
QVector <QByteArray> spectrumPlasma;
unsigned int spectrumPlasmaSize = 64;
underlay_t underlayMode = underlayNone;
QMutex plasmaMutex;
void resizePlasmaBuffer(int newSize);
double plotFloor = 0;
double plotCeiling = 160;
double wfFloor = 0;
double wfCeiling = 160;
double oldPlotFloor = -1;
double oldPlotCeiling = 999;
QVector <QByteArray> wfimage; QVector <QByteArray> wfimage;
unsigned int wfLengthMax; unsigned int wfLengthMax;
bool onFullscreen; bool onFullscreen;
bool drawPeaks;
bool freqTextSelected; bool freqTextSelected;
void checkFreqSel(); void checkFreqSel();
@ -750,36 +879,15 @@ private:
datekind datesetpoint; datekind datesetpoint;
freqMemory mem; freqMemory mem;
struct colors {
QColor Dark_PlotBackground;
QColor Dark_PlotAxisPen;
QColor Dark_PlotLegendTextColor;
QColor Dark_PlotLegendBorderPen;
QColor Dark_PlotLegendBrush;
QColor Dark_PlotTickLabel;
QColor Dark_PlotBasePen;
QColor Dark_PlotTickPen;
QColor Dark_PeakPlotLine;
QColor Dark_TuningLine;
QColor Light_PlotBackground; colorPrefsType colorPreset[numColorPresetsTotal];
QColor Light_PlotAxisPen;
QColor Light_PlotLegendTextColor;
QColor Light_PlotLegendBorderPen;
QColor Light_PlotLegendBrush;
QColor Light_PlotTickLabel;
QColor Light_PlotBasePen;
QColor Light_PlotTickPen;
QColor Light_PeakPlotLine;
QColor Light_TuningLine;
} colorScheme;
struct preferences { struct preferences {
bool useFullScreen; bool useFullScreen;
bool useDarkMode;
bool useSystemTheme; bool useSystemTheme;
bool drawPeaks; bool drawPeaks;
underlay_t underlayMode = underlayNone;
int underlayBufferSize = 64;
bool wfAntiAlias; bool wfAntiAlias;
bool wfInterpolate; bool wfInterpolate;
QString stylesheetPath; QString stylesheetPath;
@ -793,18 +901,19 @@ private:
bool enableLAN; bool enableLAN;
bool enableRigCtlD; bool enableRigCtlD;
quint16 rigCtlPort; quint16 rigCtlPort;
colors colorScheme; int currentColorPresetNumber = 0;
QString virtualSerialPort; QString virtualSerialPort;
unsigned char localAFgain; unsigned char localAFgain;
unsigned int wflength; unsigned int wflength;
int wftheme; int wftheme;
int plotFloor;
int plotCeiling;
bool confirmExit; bool confirmExit;
bool confirmPowerOff; bool confirmPowerOff;
meterKind meter2Type; meterKind meter2Type;
quint16 tcpPort; quint16 tcpPort;
quint8 waterfallFormat; quint8 waterfallFormat;
audioType audioSystem; audioType audioSystem;
// plot scheme
} prefs; } prefs;
preferences defPrefs; preferences defPrefs;
@ -815,13 +924,34 @@ private:
audioSetup rxSetup; audioSetup rxSetup;
audioSetup txSetup; audioSetup txSetup;
void setDefaultColors(int presetNumber); // populate with default values
colors defaultColors;
void setDefaultColors(); // populate with default values
void useColors(); // set the plot up void useColors(); // set the plot up
void setDefPrefs(); // populate default values to default prefs void setDefPrefs(); // populate default values to default prefs
void setTuningSteps(); void setTuningSteps();
void setColorElement(QColor color, QLedLabel *led, QLabel *label);
void setColorElement(QColor color, QLedLabel *led, QLineEdit *lineText);
void setColorElement(QColor color, QLedLabel *led, QLabel *label, QLineEdit *lineText);
QColor getColorFromPicker(QColor initialColor);
void getSetColor(QLedLabel *led, QLabel *label);
void getSetColor(QLedLabel *led, QLineEdit *line);
QString setColorFromString(QString aarrggbb, QLedLabel *led);
void setDefaultColorPresets();
void loadColorPresetToUIandPlots(int presetNumber);
void useColorPreset(colorPrefsType *cp);
void useCurrentColorPreset();
void setEditAndLedFromColor(QColor c, QLineEdit *e, QLedLabel *d);
void setColorButtonOperations(QColor *colorStore, QLineEdit *e, QLedLabel *d);
void setColorLineEditOperations(QColor *colorStore, QLineEdit *e, QLedLabel *d);
void detachSettingsTab();
void reattachSettingsTab();
void prepareSettingsWindow();
QWidget *settingsWidgetWindow;
QWidget *settingsTab;
QGridLayout *settingsWidgetLayout;
QTabWidget *settingsWidgetTab;
bool settingsTabisAttached = true;
quint64 roundFrequency(quint64 frequency, unsigned int tsHz); quint64 roundFrequency(quint64 frequency, unsigned int tsHz);
quint64 roundFrequencyWithStep(quint64 oldFreq, int steps,\ quint64 roundFrequencyWithStep(quint64 oldFreq, int steps,\
@ -889,6 +1019,7 @@ private:
shuttleSetup* shut; shuttleSetup* shut;
aboutbox *abtBox; aboutbox *abtBox;
selectRadio *selRad; selectRadio *selRad;
loggingWindow *logWindow;
udpServer* udp = Q_NULLPTR; udpServer* udp = Q_NULLPTR;
rigCtlD* rigCtl = Q_NULLPTR; rigCtlD* rigCtl = Q_NULLPTR;
@ -941,6 +1072,7 @@ Q_DECLARE_METATYPE(struct SERVERCONFIG)
Q_DECLARE_METATYPE(struct timekind) Q_DECLARE_METATYPE(struct timekind)
Q_DECLARE_METATYPE(struct datekind) Q_DECLARE_METATYPE(struct datekind)
Q_DECLARE_METATYPE(struct networkStatus) Q_DECLARE_METATYPE(struct networkStatus)
Q_DECLARE_METATYPE(struct networkAudioLevels)
Q_DECLARE_METATYPE(enum rigInput) Q_DECLARE_METATYPE(enum rigInput)
Q_DECLARE_METATYPE(enum meterKind) Q_DECLARE_METATYPE(enum meterKind)
Q_DECLARE_METATYPE(enum spectrumMode) Q_DECLARE_METATYPE(enum spectrumMode)

1105
wfmain.ui

Plik diff jest za duży Load Diff

Wyświetl plik

@ -13,7 +13,7 @@ TEMPLATE = app
CONFIG += console CONFIG += console
DEFINES += WFVIEW_VERSION=\\\"1.2e\\\" DEFINES += WFVIEW_VERSION=\\\"1.45\\\"
DEFINES += BUILD_WFSERVER DEFINES += BUILD_WFSERVER
@ -22,7 +22,7 @@ CONFIG(debug, release|debug) {
# For Debug builds only: # For Debug builds only:
QMAKE_CXXFLAGS += -faligned-new QMAKE_CXXFLAGS += -faligned-new
win32:DESTDIR = wfview-release win32:DESTDIR = wfview-release
win32:LIBS += -L../portaudio/msvc/Win32/Debug/ -lportaudio_x86 win32:LIBS += -L../portaudio/msvc/Win32/Debug/ -lportaudio_x86 -ole32
} else { } else {
# For Release builds only: # For Release builds only:
linux:QMAKE_CXXFLAGS += -s linux:QMAKE_CXXFLAGS += -s
@ -31,7 +31,7 @@ CONFIG(debug, release|debug) {
QMAKE_CXXFLAGS += -faligned-new QMAKE_CXXFLAGS += -faligned-new
linux:QMAKE_LFLAGS += -O2 -s linux:QMAKE_LFLAGS += -O2 -s
win32:DESTDIR = wfview-debug win32:DESTDIR = wfview-debug
win32:LIBS += -L../portaudio/msvc/Win32/Release/ -lportaudio_x86 win32:LIBS += -L../portaudio/msvc/Win32/Release/ -lportaudio_x86 -lole32
} }
# RTAudio defines # RTAudio defines
@ -76,34 +76,6 @@ equals(QT_ARCH, x86_64): DEFINES += EIGEN_VECTORIZE_SSE3
DEFINES += PREFIX=\\\"$$PREFIX\\\" DEFINES += PREFIX=\\\"$$PREFIX\\\"
# Choose audio system, uses QTMultimedia if both are commented out.
# DEFINES += RTAUDIO
# DEFINES += PORTAUDIO
contains(DEFINES, RTAUDIO) {
# RTAudio defines
win32:DEFINES += __WINDOWS_WASAPI__
#win32:DEFINES += __WINDOWS_DS__ # Requires DirectSound libraries
linux:DEFINES += __LINUX_ALSA__
#linux:DEFINES += __LINUX_OSS__
#linux:DEFINES += __LINUX_PULSE__
macx:DEFINES += __MACOSX_CORE__
win32:SOURCES += ../rtaudio/RTAudio.cpp
win32:HEADERS += ../rtaudio/RTAUdio.h
!linux:INCLUDEPATH += ../rtaudio
linux:LIBS += -lpulse -lpulse-simple -lrtaudio -lpthread
}
contains(DEFINES, PORTAUDIO) {
CONFIG(debug, release|debug) {
win32:LIBS += -L../portaudio/msvc/Win32/Debug/ -lportaudio_x86
} else {
win32:LIBS += -L../portaudio/msvc/Win32/Release/ -lportaudio_x86
}
win32:INCLUDEPATH += ../portaudio/include
!win32:LIBS += -lportaudio
}
macx:INCLUDEPATH += /usr/local/include /opt/local/include macx:INCLUDEPATH += /usr/local/include /opt/local/include
macx:LIBS += -L/usr/local/lib -L/opt/local/lib macx:LIBS += -L/usr/local/lib -L/opt/local/lib

Wyświetl plik

@ -11,7 +11,7 @@ greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport
TARGET = wfview TARGET = wfview
TEMPLATE = app TEMPLATE = app
DEFINES += WFVIEW_VERSION=\\\"1.2e\\\" DEFINES += WFVIEW_VERSION=\\\"1.45\\\"
DEFINES += BUILD_WFVIEW DEFINES += BUILD_WFVIEW
@ -19,7 +19,7 @@ CONFIG(debug, release|debug) {
# For Debug builds only: # For Debug builds only:
QMAKE_CXXFLAGS += -faligned-new QMAKE_CXXFLAGS += -faligned-new
win32:DESTDIR = wfview-release win32:DESTDIR = wfview-release
win32:LIBS += -L../portaudio/msvc/Win32/Debug/ -lportaudio_x86 win32:LIBS += -L../portaudio/msvc/Win32/Debug/ -lportaudio_x86 -lole32
} else { } else {
# For Release builds only: # For Release builds only:
linux:QMAKE_CXXFLAGS += -s linux:QMAKE_CXXFLAGS += -s
@ -28,7 +28,7 @@ CONFIG(debug, release|debug) {
QMAKE_CXXFLAGS += -faligned-new QMAKE_CXXFLAGS += -faligned-new
linux:QMAKE_LFLAGS += -O2 -s linux:QMAKE_LFLAGS += -O2 -s
win32:DESTDIR = wfview-debug win32:DESTDIR = wfview-debug
win32:LIBS += -L../portaudio/msvc/Win32/Release/ -lportaudio_x86 win32:LIBS += -L../portaudio/msvc/Win32/Release/ -lportaudio_x86 -lole32
} }
# RTAudio defines # RTAudio defines
@ -77,30 +77,6 @@ isEmpty(PREFIX) {
DEFINES += PREFIX=\\\"$$PREFIX\\\" DEFINES += PREFIX=\\\"$$PREFIX\\\"
contains(DEFINES, RTAUDIO) {
# RTAudio defines
win32:DEFINES += __WINDOWS_WASAPI__
#win32:DEFINES += __WINDOWS_DS__ # Requires DirectSound libraries
linux:DEFINES += __LINUX_ALSA__
#linux:DEFINES += __LINUX_OSS__
#linux:DEFINES += __LINUX_PULSE__
macx:DEFINES += __MACOSX_CORE__
win32:SOURCES += ../rtaudio/RTAudio.cpp
win32:HEADERS += ../rtaudio/RTAUdio.h
!linux:INCLUDEPATH += ../rtaudio
linux:LIBS += -lpulse -lpulse-simple -lrtaudio -lpthread
}
contains(DEFINES, PORTAUDIO) {
CONFIG(debug, release|debug) {
win32:LIBS += -L../portaudio/msvc/Win32/Debug/ -lportaudio_x86
} else {
win32:LIBS += -L../portaudio/msvc/Win32/Release/ -lportaudio_x86
}
win32:INCLUDEPATH += ../portaudio/include
!win32:LIBS += -lportaudio
}
macx:INCLUDEPATH += /usr/local/include /opt/local/include macx:INCLUDEPATH += /usr/local/include /opt/local/include
macx:LIBS += -L/usr/local/lib -L/opt/local/lib macx:LIBS += -L/usr/local/lib -L/opt/local/lib
@ -115,7 +91,7 @@ QMAKE_INFO_PLIST = ../wfview/resources/Info.plist
!win32:DEFINES += HOST=\\\"`hostname`\\\" UNAME=\\\"`whoami`\\\" !win32:DEFINES += HOST=\\\"`hostname`\\\" UNAME=\\\"`whoami`\\\"
!win32:DEFINES += GITSHORT="\\\"$(shell git -C $$PWD rev-parse --short HEAD)\\\"" !win32:DEFINES += GITSHORT="\\\"$(shell git -C \"$$PWD\" rev-parse --short HEAD)\\\""
win32:DEFINES += GITSHORT=\\\"$$system(git -C $$PWD rev-parse --short HEAD)\\\" win32:DEFINES += GITSHORT=\\\"$$system(git -C $$PWD rev-parse --short HEAD)\\\"
win32:DEFINES += HOST=\\\"wfview.org\\\" win32:DEFINES += HOST=\\\"wfview.org\\\"
@ -177,6 +153,7 @@ win32:INCLUDEPATH += ../r8brain-free-src
INCLUDEPATH += resampler INCLUDEPATH += resampler
SOURCES += main.cpp\ SOURCES += main.cpp\
loggingwindow.cpp \
wfmain.cpp \ wfmain.cpp \
commhandler.cpp \ commhandler.cpp \
rigcommander.cpp \ rigcommander.cpp \
@ -208,7 +185,9 @@ SOURCES += main.cpp\
aboutbox.cpp aboutbox.cpp
HEADERS += wfmain.h \ HEADERS += wfmain.h \
colorprefs.h \
commhandler.h \ commhandler.h \
loggingwindow.h \
rigcommander.h \ rigcommander.h \
freqmemory.h \ freqmemory.h \
rigidentities.h \ rigidentities.h \
@ -245,6 +224,7 @@ HEADERS += wfmain.h \
FORMS += wfmain.ui \ FORMS += wfmain.ui \
calibrationwindow.ui \ calibrationwindow.ui \
loggingwindow.ui \
satellitesetup.ui \ satellitesetup.ui \
selectradio.ui \ selectradio.ui \
repeatersetup.ui \ repeatersetup.ui \