Added audio channel support.

Audio input can be mono, left of stereo pair or, right of stereo
pair. Audio output can be mono, left of stereo pair, right of stereo
pair or, both of stereo pair (the same output goes to both channels in
both mode). Settings are remembered between sessions.

Stream channel suport is implemented mainly in the new AudioDevice
class which is now the base class of Modulator and Detector.

Audio channels are selected on the configuration screen. Only
supported channel configurations per device can be selected.

Audio output volume (actually attenuation) is now possible from the
GUI. I have added a slider control to the main window; I don't
necessarily propose this as a final release location for the widget as
I understand that changes to the main screen are sensitive. This
location is just a starting suggestion for a trial. The volume
(attenuation) setting is remembered between sessions and is not device
dependent. This addresses all issues of volume setting on *nix
versions since there is no need to use pavucontrol to set audio
levels. The volume (attenuation) action is logarithmic.

Shaped CW keying has been implemented in Modulator although it is
currently disabled as I am not 100% happy wth the implementation. If
you want to try it define the C++ preprocessor macro WSJT_SOFT_KEYING
in your build.

The Modulator instance has been moved to the same thread as the
SoundOutput instance as it should have been since the output callback
already operates in that thread. Cross thread slots are now correctly
called in a thread safe way as a result.

A number of files where in the SVN repository with DOS line endings
which I have removed. SVN users on Windows need set the config for
native line endings so that DOS line endings are automatically
stripped on checkin.

The DevSetup class now holds it's UI o the heap to reduce imapact on
build dependencies.

The application settings are now passed to objects from the main.cpp
file. Management of settings are moved to the responsible classes (top
level windows). This has involved a few settings moving groups so
users will see some settings reverting to default values on the first
run of an update.

Persistance of top level windows geometry and position is now handled
in the recommened manner (constructor for load, closeEvent for store
in modal windows and, hideEvent for store in modeless dialogs).

The MainWindow class now holds its children as members rather than
global variables.

The LogQSO class now hides its implementation and takes responsibility
for its own settings and widows rendering parameters. A new settings
file group is implemented to persist the LogQSO class settings.

The WideGraph class now hides its implementation and manages its own
settings and window rendering parameters.

  --This line, and those below, will be ignored--

M    Modulator.cpp
M    rigclass.cpp
M    widegraph.cpp
M    signalmeter.cpp
M    soundin.cpp
M    soundout.cpp
M    mainwindow.h
M    main.cpp
M    meterwidget.h
M    devsetup.cpp
M    mainwindow.ui
M    Detector.cpp
M    logqso.h
M    rigclass.h
M    mainwindow.cpp
M    meterwidget.cpp
M    soundin.h
M    devsetup.ui
M    wsjtx.pro
M    devsetup.h
M    logqso.cpp
M    Modulator.hpp
M    psk_reporter.cpp
M    killbyname.cpp
M    Detector.hpp
M    signalmeter.h
M    widegraph.h
M    psk_reporter.h
M    soundout.h
M    PSKReporter.h
M    lib/afc65b.f90
M    lib/gran.c
M    lib/usleep.c
M    lib/afc9.f90
M    lib/wrapkarn.c
A    AudioDevice.hpp


git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@3542 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
Bill Somerville 2013-08-10 15:29:55 +00:00
parent 67f19ac73f
commit 4f4c535c4e
36 changed files with 2877 additions and 2574 deletions

105
AudioDevice.hpp Normal file
View File

@ -0,0 +1,105 @@
#ifndef AUDIODEVICE_HPP__
#define AUDIODEVICE_HPP__
#include <QIODevice>
class QDataStream;
//
// abstract base class for audio devices
//
class AudioDevice : public QIODevice
{
public:
enum Channel {Mono, Left, Right, Both}; // these are mapped to combobox index so don't change
static char const * toString (Channel c)
{
return Mono == c ? "Mono" : Left == c ? "Left" : Right == c ? "Right" : "Both";
}
static Channel fromString (QString const& str)
{
QString s (str.toCaseFolded ().trimmed ().toLatin1 ());
return "both" == s ? Both : "right" == s ? Right : "left" == s ? Left : Mono;
}
bool open (OpenMode mode, Channel channel)
{
m_channel = channel;
// ensure we are unbuffered
return QIODevice::open (mode | QIODevice::Unbuffered);
}
bool isSequential () const {return true;}
size_t bytesPerFrame () const {return sizeof (qint16) * (Mono == m_channel ? 1 : 2);}
Channel channel () const {return m_channel;}
void channel (Channel newChannel) {m_channel = newChannel;}
protected:
AudioDevice (QObject * parent = 0)
: QIODevice (parent)
{
}
void store (char const * source, qint64 numFrames, qint16 * dest)
{
qint16 const * begin (reinterpret_cast<qint16 const *> (source));
for ( qint16 const * i = begin; i != begin + numFrames * (bytesPerFrame () / sizeof (qint16)); i += bytesPerFrame () / sizeof (qint16))
{
switch (m_channel)
{
case Mono:
*dest++ = *i;
break;
case Right:
*dest++ = *(i + 1);
break;
case Both: // should be able to happen but if it
// does we'll take left
Q_ASSERT (Both == m_channel);
case Left:
*dest++ = *i;
break;
}
}
}
qint16 * load (qint16 const sample, qint16 * dest)
{
switch (m_channel)
{
case Mono:
*dest++ = sample;
break;
case Left:
*dest++ = sample;
*dest++ = 0;
break;
case Right:
*dest++ = 0;
*dest++ = sample;
break;
case Both:
*dest++ = sample;
*dest++ = sample;
break;
}
return dest;
}
private:
Channel m_channel;
};
Q_DECLARE_METATYPE (AudioDevice::Channel);
#endif

View File

@ -6,11 +6,11 @@
#include "commons.h"
Detector::Detector (unsigned frameRate, unsigned periodLengthInSeconds, unsigned bytesPerSignal, QObject * parent)
: QIODevice (parent)
Detector::Detector (unsigned frameRate, unsigned periodLengthInSeconds, unsigned framesPerSignal, QObject * parent)
: AudioDevice (parent)
, m_frameRate (frameRate)
, m_period (periodLengthInSeconds)
, m_bytesPerSignal (bytesPerSignal)
, m_framesPerSignal (framesPerSignal)
, m_monitoring (false)
, m_starting (false)
{
@ -37,28 +37,25 @@ void Detector::clear ()
qint64 Detector::writeData (char const * data, qint64 maxSize)
{
Q_ASSERT (!(maxSize % static_cast<qint64> (sizeof (frame_t)))); // no torn frames
Q_ASSERT (!(reinterpret_cast<size_t> (data) % __alignof__ (frame_t))); // data is aligned as frame_t would be
frame_t const * frames (reinterpret_cast<frame_t const *> (data));
Q_ASSERT (!(maxSize % static_cast<qint64> (bytesPerFrame ()))); // no torn frames
qint64 framesAcceptable (sizeof (jt9com_.d2) / sizeof (jt9com_.d2[0]) - jt9com_.kin);
qint64 framesAccepted (qMin (static_cast<qint64> (maxSize / sizeof (jt9com_.d2[0])), framesAcceptable));
qint64 framesAccepted (qMin (static_cast<qint64> (maxSize / bytesPerFrame ()), framesAcceptable));
if (framesAccepted < static_cast<qint64> (maxSize / sizeof (jt9com_.d2[0])))
if (framesAccepted < static_cast<qint64> (maxSize / bytesPerFrame ()))
{
qDebug () << "dropped " << maxSize / sizeof (jt9com_.d2[0]) - framesAccepted << " frames of data on the floor!";
}
qCopy (frames, frames + framesAccepted, &jt9com_.d2[jt9com_.kin]);
store (data, framesAccepted, &jt9com_.d2[jt9com_.kin]);
unsigned lastSignalIndex (jt9com_.kin * sizeof (jt9com_.d2[0]) / m_bytesPerSignal);
unsigned lastSignalIndex (jt9com_.kin / m_framesPerSignal);
jt9com_.kin += framesAccepted;
unsigned currentSignalIndex (jt9com_.kin * sizeof (jt9com_.d2[0]) / m_bytesPerSignal);
unsigned currentSignalIndex (jt9com_.kin / m_framesPerSignal);
if (currentSignalIndex != lastSignalIndex && m_monitoring)
{
Q_EMIT bytesWritten (currentSignalIndex * m_bytesPerSignal);
Q_EMIT framesWritten (currentSignalIndex * m_framesPerSignal);
}
if (!secondInPeriod ())

View File

@ -1,9 +1,7 @@
#ifndef DETECTOR_HPP__
#define DETECTOR_HPP__
#include <stdint.h>
#include <QIODevice>
#include "AudioDevice.hpp"
//
// output device that distributes data in predefined chunks via a signal
@ -11,38 +9,28 @@
// the underlying device for this abstraction is just the buffer that
// stores samples throughout a receiving period
//
class Detector : public QIODevice
class Detector : public AudioDevice
{
Q_OBJECT;
Q_PROPERTY (bool monitoring READ isMonitoring WRITE setMonitoring);
private:
Q_DISABLE_COPY (Detector);
public:
//
// if the data buffer were not global storage and fixed size then we
// might want maximum size passed as constructor arguments
//
Detector (unsigned frameRate, unsigned periodLengthInSeconds, unsigned bytesPerSignal, QObject * parent = 0);
Detector (unsigned frameRate, unsigned periodLengthInSeconds, unsigned framesPerSignal, QObject * parent = 0);
bool open ()
{
// we only support data consumption and want it as fast as possible
return QIODevice::open (QIODevice::WriteOnly | QIODevice::Unbuffered);
}
bool isSequential () const
{
return true;
}
bool open (Channel channel = Mono) {return AudioDevice::open (QIODevice::WriteOnly, channel);}
bool isMonitoring () const {return m_monitoring;}
void setMonitoring (bool newState) {m_monitoring = newState;}
bool reset ();
Q_SIGNAL void framesWritten (qint64);
protected:
qint64 readData (char * /* data */, qint64 /* maxSize */)
{
@ -52,14 +40,12 @@ protected:
qint64 writeData (char const * data, qint64 maxSize);
private:
typedef qint16 frame_t;
void clear (); // discard buffer contents
unsigned secondInPeriod () const;
unsigned m_frameRate;
unsigned m_period;
unsigned m_bytesPerSignal;
unsigned m_framesPerSignal;
bool m_monitoring;
bool m_starting;
};

View File

@ -10,6 +10,15 @@
extern float gran(); // Noise generator (for tests only)
// MUST be an integral factor of 2^16
#define RAMP_INCREMENT 64
#if defined (WSJT_SOFT_KEYING)
# define SOFT_KEYING true
#else
# define SOFT_KEYING false
#endif
double const Modulator::m_twoPi = 2.0 * 3.141592653589793238462;
// float wpm=20.0;
@ -18,7 +27,7 @@ double const Modulator::m_twoPi = 2.0 * 3.141592653589793238462;
unsigned const Modulator::m_nspd = 2048 + 512; // 22.5 WPM
Modulator::Modulator (unsigned frameRate, unsigned periodLengthInSeconds, QObject * parent)
: QIODevice (parent)
: AudioDevice (parent)
, m_frameRate (frameRate)
, m_period (periodLengthInSeconds)
, m_framesSent (0)
@ -30,11 +39,13 @@ Modulator::Modulator (unsigned frameRate, unsigned periodLengthInSeconds, QObjec
qsrand (QDateTime::currentMSecsSinceEpoch()); // Initialize random seed
}
void Modulator::send (unsigned symbolsLength, double framesPerSymbol, unsigned frequency, bool synchronize, double dBSNR)
void Modulator::open (unsigned symbolsLength, double framesPerSymbol, unsigned frequency, Channel channel, bool synchronize, double dBSNR)
{
// Time according to this computer which becomes our base time
qint64 ms0 = QDateTime::currentMSecsSinceEpoch() % 86400000;
qDebug () << "Modulator: Using soft keying for CW is " << SOFT_KEYING;;
m_symbolsLength = symbolsLength;
m_framesSent = 0;
@ -67,16 +78,19 @@ void Modulator::send (unsigned symbolsLength, double framesPerSymbol, unsigned f
}
// qDebug () << "Modulator: starting at " << m_ic / m_frameRate << " sec, sending " << m_silentFrames << " silent frames";
AudioDevice::open (QIODevice::ReadOnly, channel);
Q_EMIT stateChanged ((m_state = (synchronize && m_silentFrames) ? Synchronizing : Active));
}
qint64 Modulator::readData (char * data, qint64 maxSize)
{
Q_ASSERT (!(maxSize % static_cast<qint64> (sizeof (frame_t)))); // no torn frames
Q_ASSERT (!(reinterpret_cast<size_t> (data) % __alignof__ (frame_t))); // data is aligned as frame_t would be
Q_ASSERT (!(maxSize % static_cast<qint64> (bytesPerFrame ()))); // no torn frames
Q_ASSERT (isOpen ());
frame_t * frames (reinterpret_cast<frame_t *> (data));
qint64 numFrames (maxSize / sizeof (frame_t));
qint64 numFrames (maxSize / bytesPerFrame ());
qint16 * samples (reinterpret_cast<qint16 *> (data));
qint16 * end (samples + numFrames * (bytesPerFrame () / sizeof (qint16)));
// qDebug () << "Modulator: " << numFrames << " requested, m_ic = " << m_ic << ", tune mode is " << m_tuning;
@ -86,19 +100,16 @@ qint64 Modulator::readData (char * data, qint64 maxSize)
{
if (m_silentFrames) // send silence up to first second
{
frame_t frame;
for (unsigned c = 0; c < NUM_CHANNELS; ++c)
{
frame.channel[c] = 0; // silence
}
numFrames = qMin (m_silentFrames, numFrames);
qFill (frames, frames + numFrames, frame);
for ( ; samples != end; samples = load (0, samples)) // silence
{
}
m_silentFrames -= numFrames;
return numFrames * sizeof (frame_t);
return numFrames * bytesPerFrame ();
}
Q_EMIT stateChanged ((m_state = Active));
m_ramp = 0; // prepare for CW wave shaping
}
// fall through
@ -114,7 +125,8 @@ qint64 Modulator::readData (char * data, qint64 maxSize)
unsigned const ic0 = m_symbolsLength * 4 * m_nsps;
unsigned j (0);
qint64 framesGenerated (0);
for (unsigned i = 0; i < numFrames; ++i)
while (samples != end)
{
m_phi += m_dphi;
if (m_phi > m_twoPi)
@ -122,28 +134,31 @@ qint64 Modulator::readData (char * data, qint64 maxSize)
m_phi -= m_twoPi;
}
frame_t frame;
for (unsigned c = 0; c < NUM_CHANNELS; ++c)
qint16 sample ((SOFT_KEYING ? qAbs (m_ramp - 1) : (m_ramp ? 32767 : 0)) * qSin (m_phi));
j = (m_ic - ic0 - 1) / m_nspd + 1;
bool l0 (icw[j] && icw[j] <= 1); // first element treated specially as it's a count
j = (m_ic - ic0) / m_nspd + 1;
if ((m_ramp != 0 && m_ramp != std::numeric_limits<qint16>::min ()) || !!icw[j] != l0)
{
frame.channel[c] = std::numeric_limits<qint16>::max () * qSin (m_phi);
if (!!icw[j] != l0)
{
Q_ASSERT (m_ramp == 0 || m_ramp == std::numeric_limits<qint16>::min ());
}
m_ramp += RAMP_INCREMENT; // ramp
}
j = (m_ic - ic0) / m_nspd + 1;
if (j < NUM_CW_SYMBOLS) // stop condition
{
if (!icw[j])
{
for (unsigned c = 0; c < NUM_CHANNELS; ++c)
{
frame.channel[c] = 0;
}
}
// if (!m_ramp && !icw[j])
// {
// sample = 0;
// }
frame = postProcessFrame (frame);
samples = load (postProcessSample (sample), samples);
*frames++ = frame;
++framesGenerated;
++m_ic;
}
}
@ -154,7 +169,7 @@ qint64 Modulator::readData (char * data, qint64 maxSize)
}
m_framesSent += framesGenerated;
return framesGenerated * sizeof (frame_t);
return framesGenerated * bytesPerFrame ();
}
double const baud (12000.0 / m_nsps);
@ -186,15 +201,7 @@ qint64 Modulator::readData (char * data, qint64 maxSize)
m_amp = 0.0;
}
frame_t frame;
for (unsigned c = 0; c < NUM_CHANNELS; ++c)
{
frame.channel[c] = m_amp * qSin (m_phi);
}
frame = postProcessFrame (frame);
*frames++ = frame;
samples = load (postProcessSample (m_amp * qSin (m_phi)), samples);
++m_ic;
}
@ -206,7 +213,7 @@ qint64 Modulator::readData (char * data, qint64 maxSize)
// no CW ID to send
Q_EMIT stateChanged ((m_state = Idle));
m_framesSent += numFrames;
return numFrames * sizeof (frame_t);
return numFrames * bytesPerFrame ();
}
m_phi = 0.0;
@ -214,7 +221,7 @@ qint64 Modulator::readData (char * data, qint64 maxSize)
// done for this chunk - continue on next call
m_framesSent += numFrames;
return numFrames * sizeof (frame_t);
return numFrames * bytesPerFrame ();
}
Q_EMIT stateChanged ((m_state = Idle));
// fall through
@ -227,35 +234,24 @@ qint64 Modulator::readData (char * data, qint64 maxSize)
return 0;
}
Modulator::frame_t Modulator::postProcessFrame (frame_t frame) const
qint16 Modulator::postProcessSample (qint16 sample) const
{
if (m_muted) // silent frame
{
for (unsigned c = 0; c < NUM_CHANNELS; ++c)
{
frame.channel[c] = 0;
}
sample = 0;
}
else if (m_addNoise)
{
qint32 f[NUM_CHANNELS];
for (unsigned c = 0; c < NUM_CHANNELS; ++c)
qint32 s = m_fac * (gran () + sample * m_snr / 32768.0);
if (s > std::numeric_limits<qint16>::max ())
{
f[c] = m_fac * (gran () + frame.channel[c] * m_snr / 32768.0);
if (f[c] > std::numeric_limits<qint16>::max ())
{
f[c] = std::numeric_limits<qint16>::max ();
}
if (f[c] < std::numeric_limits<qint16>::min ())
{
f[c] = std::numeric_limits<qint16>::min ();
}
s = std::numeric_limits<qint16>::max ();
}
for (unsigned c = 0; c < NUM_CHANNELS; ++c)
if (s < std::numeric_limits<qint16>::min ())
{
frame.channel[c] = f[c];
s = std::numeric_limits<qint16>::min ();
}
sample = s;
}
return frame;
return sample;
}

View File

@ -1,7 +1,7 @@
#ifndef MODULATOR_HPP__
#define MODULATOR_HPP__
#include <QIODevice>
#include "AudioDevice.hpp"
#ifdef UNIX
# define NUM_CHANNELS 2
@ -16,7 +16,7 @@
// Output can be muted while underway, preserving waveform timing when
// transmission is resumed.
//
class Modulator : public QIODevice
class Modulator : public AudioDevice
{
Q_OBJECT;
@ -24,33 +24,18 @@ class Modulator : public QIODevice
Q_PROPERTY (bool tuning READ isTuning WRITE tune);
Q_PROPERTY (bool muted READ isMuted WRITE mute);
private:
Q_DISABLE_COPY (Modulator);
public:
enum ModulatorState {Synchronizing, Active, Idle};
Modulator (unsigned frameRate, unsigned periodLengthInSeconds, QObject * parent = 0);
bool open () {return QIODevice::open (QIODevice::ReadOnly | QIODevice::Unbuffered);}
Q_SLOT void send (unsigned symbolsLength, double framesPerSymbol, unsigned frequency, bool synchronize = true, double dBSNR = 99.);
Q_SLOT void stop () {Q_EMIT stateChanged ((m_state = Idle));}
Q_SLOT void open (unsigned symbolsLength, double framesPerSymbol, unsigned frequency, AudioDevice::Channel, bool synchronize = true, double dBSNR = 99.);
bool isTuning () const {return m_tuning;}
Q_SLOT void tune (bool newState = true) {m_tuning = newState;}
bool isMuted () const {return m_muted;}
Q_SLOT void mute (bool newState = true) {m_muted = newState;}
unsigned frequency () const {return m_frequency;}
Q_SLOT void setFrequency (unsigned newFrequency) {m_frequency = newFrequency;}
enum ModulatorState {Synchronizing, Active, Idle};
Q_SIGNAL void stateChanged (ModulatorState);
bool isActive () const {return m_state != Idle;}
bool isSequential () const {return true;}
protected:
qint64 readData (char * data, qint64 maxSize);
qint64 writeData (char const * /* data */, qint64 /* maxSize */)
@ -59,12 +44,22 @@ protected:
}
private:
typedef struct
/* private because we epect to run in a thread and don't want direct
C++ calls made, instead they must be invoked via the Qt
signal/slot mechanism which is thread safe */
Q_SLOT void close ()
{
qint16 channel[NUM_CHANNELS];
} frame_t;
Q_EMIT stateChanged ((m_state = Idle));
AudioDevice::close ();
}
frame_t postProcessFrame (frame_t frame) const;
Q_SLOT void tune (bool newState = true) {m_tuning = newState;}
Q_SLOT void mute (bool newState = true) {m_muted = newState;}
Q_SLOT void setFrequency (unsigned newFrequency) {m_frequency = newFrequency;}
Q_SIGNAL void stateChanged (ModulatorState);
private:
qint16 postProcessSample (qint16 sample) const;
unsigned m_symbolsLength;
@ -88,6 +83,7 @@ private:
unsigned m_ic;
double m_fac;
unsigned m_isym0;
qint16 m_ramp;
};
#endif

View File

@ -1,13 +1,17 @@
#include "devsetup.h"
#include "ui_devsetup.h"
#include <iterator>
#include <algorithm>
#include <tr1/functional>
#include <QDebug>
#include <QSettings>
#include <QAudioDeviceInfo>
#include <QAudioInput>
#include <QMap>
#define MAXDEVICES 100
extern double dFreq[16];
qint32 g2_iptt;
qint32 g2_COMportOpen;
@ -15,10 +19,11 @@ qint32 g2_COMportOpen;
//----------------------------------------------------------- DevSetup()
DevSetup::DevSetup(QWidget *parent)
: QDialog(parent)
, ui (new Ui::DevSetup)
, m_audioInputDevices (QAudioDeviceInfo::availableDevices (QAudio::AudioInput))
, m_audioOutputDevices (QAudioDeviceInfo::availableDevices (QAudio::AudioOutput))
{
ui.setupUi(this); //setup the dialog form
ui->setupUi(this); //setup the dialog form
m_restartSoundIn=false;
m_restartSoundOut=false;
m_firstCall=true;
@ -42,182 +47,165 @@ void DevSetup::initDlg()
settings.endGroup();
//
// load combo boxes with setup choices
// load combo boxes with audio setup choices
//
{
int currentIndex = -1;
int defaultIndex = 0;
for (AudioDevices::const_iterator p = m_audioInputDevices.begin (); p != m_audioInputDevices.end (); ++p)
{
ui.comboBoxSndIn->addItem (p->deviceName ());
if (*p == m_audioInputDevice)
{
currentIndex = p - m_audioInputDevices.begin ();
}
else if (*p == QAudioDeviceInfo::defaultInputDevice ())
{
defaultIndex = p - m_audioInputDevices.begin ();
}
}
ui.comboBoxSndIn->setCurrentIndex (currentIndex != -1 ? currentIndex : defaultIndex);
}
loadAudioDevices (m_audioInputDevices, ui->comboBoxSndIn);
loadAudioDevices (m_audioOutputDevices, ui->comboBoxSndOut);
{
int currentIndex = -1;
int defaultIndex = 0;
for (AudioDevices::const_iterator p = m_audioOutputDevices.begin (); p != m_audioOutputDevices.end (); ++p)
{
ui.comboBoxSndOut->addItem (p->deviceName ());
if (*p == m_audioOutputDevice)
{
currentIndex = p - m_audioOutputDevices.begin ();
}
else if (*p == QAudioDeviceInfo::defaultOutputDevice ())
{
defaultIndex = p - m_audioOutputDevices.begin ();
}
}
ui.comboBoxSndOut->setCurrentIndex (currentIndex != -1 ? currentIndex : defaultIndex);
using namespace std::tr1;
using namespace std::tr1::placeholders;
function<void (int)> cb (bind (&DevSetup::updateAudioChannels, this, ui->comboBoxSndIn, _1, ui->audioInputChannel, false));
connect (ui->comboBoxSndIn, static_cast<void (QComboBox::*)(int)> (&QComboBox::currentIndexChanged), cb);
cb = bind (&DevSetup::updateAudioChannels, this, ui->comboBoxSndOut, _1, ui->audioOutputChannel, true);
connect (ui->comboBoxSndOut, static_cast<void (QComboBox::*)(int)> (&QComboBox::currentIndexChanged), cb);
updateAudioChannels (ui->comboBoxSndIn, ui->comboBoxSndIn->currentIndex (), ui->audioInputChannel, false);
updateAudioChannels (ui->comboBoxSndOut, ui->comboBoxSndOut->currentIndex (), ui->audioOutputChannel, true);
ui->audioInputChannel->setCurrentIndex (m_audioInputChannel);
ui->audioOutputChannel->setCurrentIndex (m_audioOutputChannel);
}
enumerateRigs ();
QPalette pal(ui.myCallEntry->palette());
QPalette pal(ui->myCallEntry->palette());
if(m_myCall=="") {
pal.setColor(QPalette::Base,"#ffccff");
} else {
pal.setColor(QPalette::Base,Qt::white);
}
ui.myCallEntry->setPalette(pal);
ui.myGridEntry->setPalette(pal);
ui.myCallEntry->setText(m_myCall);
ui.myGridEntry->setText(m_myGrid);
ui->myCallEntry->setPalette(pal);
ui->myGridEntry->setPalette(pal);
ui->myCallEntry->setText(m_myCall);
ui->myGridEntry->setText(m_myGrid);
ui.idIntSpinBox->setValue(m_idInt);
ui.pttMethodComboBox->setCurrentIndex(m_pttMethodIndex);
ui.saveDirEntry->setText(m_saveDir);
ui.cbID73->setChecked(m_After73);
ui.cbPSKReporter->setChecked(m_pskReporter);
ui.cbSplit->setChecked(m_bSplit and m_catEnabled);
ui.cbXIT->setChecked(m_bXIT);
ui.cbXIT->setVisible(false);
ui->idIntSpinBox->setValue(m_idInt);
ui->pttMethodComboBox->setCurrentIndex(m_pttMethodIndex);
ui->saveDirEntry->setText(m_saveDir);
ui->cbID73->setChecked(m_After73);
ui->cbPSKReporter->setChecked(m_pskReporter);
ui->cbSplit->setChecked(m_bSplit and m_catEnabled);
ui->cbXIT->setChecked(m_bXIT);
ui->cbXIT->setVisible(false);
enableWidgets();
ui.catPortComboBox->setCurrentIndex(m_catPortIndex);
ui.serialRateComboBox->setCurrentIndex(m_serialRateIndex);
ui.dataBitsComboBox->setCurrentIndex(m_dataBitsIndex);
ui.stopBitsComboBox->setCurrentIndex(m_stopBitsIndex);
ui.handshakeComboBox->setCurrentIndex(m_handshakeIndex);
ui.rbData->setChecked(m_pttData);
ui.pollSpinBox->setValue(m_poll);
ui->catPortComboBox->setCurrentIndex(m_catPortIndex);
ui->serialRateComboBox->setCurrentIndex(m_serialRateIndex);
ui->dataBitsComboBox->setCurrentIndex(m_dataBitsIndex);
ui->stopBitsComboBox->setCurrentIndex(m_stopBitsIndex);
ui->handshakeComboBox->setCurrentIndex(m_handshakeIndex);
ui->rbData->setChecked(m_pttData);
ui->pollSpinBox->setValue(m_poll);
// PY2SDR -- Per OS serial port names
m_tmp=m_pttPort;
ui.pttComboBox->clear();
ui.catPortComboBox->clear();
ui.pttComboBox->addItem("None");
ui.catPortComboBox->addItem("None");
ui->pttComboBox->clear();
ui->catPortComboBox->clear();
ui->pttComboBox->addItem("None");
ui->catPortComboBox->addItem("None");
#ifdef WIN32
for ( int i = 1; i < 100; i++ ) {
ui.pttComboBox->addItem("COM" + QString::number(i));
ui.catPortComboBox->addItem("COM" + QString::number(i));
ui->pttComboBox->addItem("COM" + QString::number(i));
ui->catPortComboBox->addItem("COM" + QString::number(i));
}
ui.pttComboBox->addItem("USB");
ui.catPortComboBox->addItem("USB");
ui->pttComboBox->addItem("USB");
ui->catPortComboBox->addItem("USB");
#else
ui.catPortComboBox->addItem("/dev/ttyS0");
ui.catPortComboBox->addItem("/dev/ttyS1");
ui.catPortComboBox->addItem("/dev/ttyS2");
ui.catPortComboBox->addItem("/dev/ttyS3");
ui.catPortComboBox->addItem("/dev/ttyS4");
ui.catPortComboBox->addItem("/dev/ttyS5");
ui.catPortComboBox->addItem("/dev/ttyS6");
ui.catPortComboBox->addItem("/dev/ttyS7");
ui.catPortComboBox->addItem("/dev/ttyUSB0");
ui.catPortComboBox->addItem("/dev/ttyUSB1");
ui.catPortComboBox->addItem("/dev/ttyUSB2");
ui.catPortComboBox->addItem("/dev/ttyUSB3");
ui.catPortComboBox->addItem(catPortDriver);
ui->catPortComboBox->addItem("/dev/ttyS0");
ui->catPortComboBox->addItem("/dev/ttyS1");
ui->catPortComboBox->addItem("/dev/ttyS2");
ui->catPortComboBox->addItem("/dev/ttyS3");
ui->catPortComboBox->addItem("/dev/ttyS4");
ui->catPortComboBox->addItem("/dev/ttyS5");
ui->catPortComboBox->addItem("/dev/ttyS6");
ui->catPortComboBox->addItem("/dev/ttyS7");
ui->catPortComboBox->addItem("/dev/ttyUSB0");
ui->catPortComboBox->addItem("/dev/ttyUSB1");
ui->catPortComboBox->addItem("/dev/ttyUSB2");
ui->catPortComboBox->addItem("/dev/ttyUSB3");
ui->catPortComboBox->addItem(catPortDriver);
ui.pttComboBox->addItem("/dev/ttyS0");
ui.pttComboBox->addItem("/dev/ttyS1");
ui.pttComboBox->addItem("/dev/ttyS2");
ui.pttComboBox->addItem("/dev/ttyS3");
ui.pttComboBox->addItem("/dev/ttyS4");
ui.pttComboBox->addItem("/dev/ttyS5");
ui.pttComboBox->addItem("/dev/ttyS6");
ui.pttComboBox->addItem("/dev/ttyS7");
ui.pttComboBox->addItem("/dev/ttyUSB0");
ui.pttComboBox->addItem("/dev/ttyUSB1");
ui.pttComboBox->addItem("/dev/ttyUSB2");
ui.pttComboBox->addItem("/dev/ttyUSB3");
ui->pttComboBox->addItem("/dev/ttyS0");
ui->pttComboBox->addItem("/dev/ttyS1");
ui->pttComboBox->addItem("/dev/ttyS2");
ui->pttComboBox->addItem("/dev/ttyS3");
ui->pttComboBox->addItem("/dev/ttyS4");
ui->pttComboBox->addItem("/dev/ttyS5");
ui->pttComboBox->addItem("/dev/ttyS6");
ui->pttComboBox->addItem("/dev/ttyS7");
ui->pttComboBox->addItem("/dev/ttyUSB0");
ui->pttComboBox->addItem("/dev/ttyUSB1");
ui->pttComboBox->addItem("/dev/ttyUSB2");
ui->pttComboBox->addItem("/dev/ttyUSB3");
#endif
ui.pttComboBox->setCurrentIndex(m_tmp);
ui.catPortComboBox->setCurrentIndex(m_catPortIndex);
ui->pttComboBox->setCurrentIndex(m_tmp);
ui->catPortComboBox->setCurrentIndex(m_catPortIndex);
int n=m_macro.length();
if(n>=1) ui.macro1->setText(m_macro[0].toUpper());
if(n>=2) ui.macro2->setText(m_macro[1].toUpper());
if(n>=3) ui.macro3->setText(m_macro[2].toUpper());
if(n>=4) ui.macro4->setText(m_macro[3].toUpper());
if(n>=5) ui.macro5->setText(m_macro[4].toUpper());
if(n>=6) ui.macro6->setText(m_macro[5].toUpper());
if(n>=7) ui.macro7->setText(m_macro[6].toUpper());
if(n>=8) ui.macro8->setText(m_macro[7].toUpper());
if(n>=8) ui.macro9->setText(m_macro[8].toUpper());
if(n>=10) ui.macro10->setText(m_macro[9].toUpper());
if(n>=1) ui->macro1->setText(m_macro[0].toUpper());
if(n>=2) ui->macro2->setText(m_macro[1].toUpper());
if(n>=3) ui->macro3->setText(m_macro[2].toUpper());
if(n>=4) ui->macro4->setText(m_macro[3].toUpper());
if(n>=5) ui->macro5->setText(m_macro[4].toUpper());
if(n>=6) ui->macro6->setText(m_macro[5].toUpper());
if(n>=7) ui->macro7->setText(m_macro[6].toUpper());
if(n>=8) ui->macro8->setText(m_macro[7].toUpper());
if(n>=8) ui->macro9->setText(m_macro[8].toUpper());
if(n>=10) ui->macro10->setText(m_macro[9].toUpper());
ui.f1->setText(m_dFreq[0]);
ui.f2->setText(m_dFreq[1]);
ui.f3->setText(m_dFreq[2]);
ui.f4->setText(m_dFreq[3]);
ui.f5->setText(m_dFreq[4]);
ui.f6->setText(m_dFreq[5]);
ui.f7->setText(m_dFreq[6]);
ui.f8->setText(m_dFreq[7]);
ui.f9->setText(m_dFreq[8]);
ui.f10->setText(m_dFreq[9]);
ui.f11->setText(m_dFreq[10]);
ui.f12->setText(m_dFreq[11]);
ui.f13->setText(m_dFreq[12]);
ui.f14->setText(m_dFreq[13]);
ui.f15->setText(m_dFreq[14]);
ui.f16->setText(m_dFreq[15]);
ui->f1->setText(m_dFreq[0]);
ui->f2->setText(m_dFreq[1]);
ui->f3->setText(m_dFreq[2]);
ui->f4->setText(m_dFreq[3]);
ui->f5->setText(m_dFreq[4]);
ui->f6->setText(m_dFreq[5]);
ui->f7->setText(m_dFreq[6]);
ui->f8->setText(m_dFreq[7]);
ui->f9->setText(m_dFreq[8]);
ui->f10->setText(m_dFreq[9]);
ui->f11->setText(m_dFreq[10]);
ui->f12->setText(m_dFreq[11]);
ui->f13->setText(m_dFreq[12]);
ui->f14->setText(m_dFreq[13]);
ui->f15->setText(m_dFreq[14]);
ui->f16->setText(m_dFreq[15]);
ui.AntDescription1->setText(m_antDescription[0]);
ui.AntDescription2->setText(m_antDescription[1]);
ui.AntDescription3->setText(m_antDescription[2]);
ui.AntDescription4->setText(m_antDescription[3]);
ui.AntDescription5->setText(m_antDescription[4]);
ui.AntDescription6->setText(m_antDescription[5]);
ui.AntDescription7->setText(m_antDescription[6]);
ui.AntDescription8->setText(m_antDescription[7]);
ui.AntDescription9->setText(m_antDescription[8]);
ui.AntDescription10->setText(m_antDescription[9]);
ui.AntDescription11->setText(m_antDescription[10]);
ui.AntDescription12->setText(m_antDescription[11]);
ui.AntDescription13->setText(m_antDescription[12]);
ui.AntDescription14->setText(m_antDescription[13]);
ui.AntDescription15->setText(m_antDescription[14]);
ui.AntDescription16->setText(m_antDescription[15]);
ui->AntDescription1->setText(m_antDescription[0]);
ui->AntDescription2->setText(m_antDescription[1]);
ui->AntDescription3->setText(m_antDescription[2]);
ui->AntDescription4->setText(m_antDescription[3]);
ui->AntDescription5->setText(m_antDescription[4]);
ui->AntDescription6->setText(m_antDescription[5]);
ui->AntDescription7->setText(m_antDescription[6]);
ui->AntDescription8->setText(m_antDescription[7]);
ui->AntDescription9->setText(m_antDescription[8]);
ui->AntDescription10->setText(m_antDescription[9]);
ui->AntDescription11->setText(m_antDescription[10]);
ui->AntDescription12->setText(m_antDescription[11]);
ui->AntDescription13->setText(m_antDescription[12]);
ui->AntDescription14->setText(m_antDescription[13]);
ui->AntDescription15->setText(m_antDescription[14]);
ui->AntDescription16->setText(m_antDescription[15]);
ui.Band1->setText(m_bandDescription[0]);
ui.Band2->setText(m_bandDescription[1]);
ui.Band3->setText(m_bandDescription[2]);
ui.Band4->setText(m_bandDescription[3]);
ui.Band5->setText(m_bandDescription[4]);
ui.Band6->setText(m_bandDescription[5]);
ui.Band7->setText(m_bandDescription[6]);
ui.Band8->setText(m_bandDescription[7]);
ui.Band9->setText(m_bandDescription[8]);
ui.Band10->setText(m_bandDescription[9]);
ui.Band11->setText(m_bandDescription[10]);
ui.Band12->setText(m_bandDescription[11]);
ui.Band13->setText(m_bandDescription[12]);
ui.Band14->setText(m_bandDescription[13]);
ui.Band15->setText(m_bandDescription[14]);
ui.Band16->setText(m_bandDescription[15]);
ui->Band1->setText(m_bandDescription[0]);
ui->Band2->setText(m_bandDescription[1]);
ui->Band3->setText(m_bandDescription[2]);
ui->Band4->setText(m_bandDescription[3]);
ui->Band5->setText(m_bandDescription[4]);
ui->Band6->setText(m_bandDescription[5]);
ui->Band7->setText(m_bandDescription[6]);
ui->Band8->setText(m_bandDescription[7]);
ui->Band9->setText(m_bandDescription[8]);
ui->Band10->setText(m_bandDescription[9]);
ui->Band11->setText(m_bandDescription[10]);
ui->Band12->setText(m_bandDescription[11]);
ui->Band13->setText(m_bandDescription[12]);
ui->Band14->setText(m_bandDescription[13]);
ui->Band15->setText(m_bandDescription[14]);
ui->Band16->setText(m_bandDescription[15]);
}
@ -228,90 +216,106 @@ void DevSetup::accept()
// Check to see whether SoundInThread must be restarted,
// and save user parameters.
if (m_audioInputDevice != m_audioInputDevices[ui.comboBoxSndIn->currentIndex ()])
m_restartSoundIn = m_restartSoundOut = false;
if (m_audioInputDevice != m_audioInputDevices[ui->comboBoxSndIn->currentIndex ()])
{
m_audioInputDevice = m_audioInputDevices[ui.comboBoxSndIn->currentIndex ()];
m_audioInputDevice = m_audioInputDevices[ui->comboBoxSndIn->currentIndex ()];
m_restartSoundIn = true;
}
if (m_audioOutputDevice != m_audioOutputDevices[ui.comboBoxSndOut->currentIndex ()])
if (m_audioOutputDevice != m_audioOutputDevices[ui->comboBoxSndOut->currentIndex ()])
{
m_audioOutputDevice = m_audioOutputDevices[ui.comboBoxSndOut->currentIndex ()];
m_audioOutputDevice = m_audioOutputDevices[ui->comboBoxSndOut->currentIndex ()];
m_restartSoundOut = true;
}
m_myCall=ui.myCallEntry->text();
m_myGrid=ui.myGridEntry->text();
m_idInt=ui.idIntSpinBox->value();
m_pttMethodIndex=ui.pttMethodComboBox->currentIndex();
m_pttPort=ui.pttComboBox->currentIndex();
m_saveDir=ui.saveDirEntry->text();
if (m_audioInputChannel != static_cast<AudioDevice::Channel> (ui->audioInputChannel->currentIndex ()))
{
m_audioInputChannel = static_cast<AudioDevice::Channel> (ui->audioInputChannel->currentIndex ());
m_restartSoundIn = true;
}
Q_ASSERT (m_audioInputChannel <= AudioDevice::Right);
if (m_audioOutputChannel != static_cast<AudioDevice::Channel> (ui->audioOutputChannel->currentIndex ()))
{
m_audioOutputChannel = static_cast<AudioDevice::Channel> (ui->audioOutputChannel->currentIndex ());
m_restartSoundOut = true;
}
Q_ASSERT (m_audioOutputChannel <= AudioDevice::Both);
m_myCall=ui->myCallEntry->text();
m_myGrid=ui->myGridEntry->text();
m_idInt=ui->idIntSpinBox->value();
m_pttMethodIndex=ui->pttMethodComboBox->currentIndex();
m_pttPort=ui->pttComboBox->currentIndex();
m_saveDir=ui->saveDirEntry->text();
m_macro.clear();
m_macro.append(ui.macro1->text());
m_macro.append(ui.macro2->text());
m_macro.append(ui.macro3->text());
m_macro.append(ui.macro4->text());
m_macro.append(ui.macro5->text());
m_macro.append(ui.macro6->text());
m_macro.append(ui.macro7->text());
m_macro.append(ui.macro8->text());
m_macro.append(ui.macro9->text());
m_macro.append(ui.macro10->text());
m_macro.append(ui->macro1->text());
m_macro.append(ui->macro2->text());
m_macro.append(ui->macro3->text());
m_macro.append(ui->macro4->text());
m_macro.append(ui->macro5->text());
m_macro.append(ui->macro6->text());
m_macro.append(ui->macro7->text());
m_macro.append(ui->macro8->text());
m_macro.append(ui->macro9->text());
m_macro.append(ui->macro10->text());
m_dFreq.clear();
m_dFreq.append(ui.f1->text());
m_dFreq.append(ui.f2->text());
m_dFreq.append(ui.f3->text());
m_dFreq.append(ui.f4->text());
m_dFreq.append(ui.f5->text());
m_dFreq.append(ui.f6->text());
m_dFreq.append(ui.f7->text());
m_dFreq.append(ui.f8->text());
m_dFreq.append(ui.f9->text());
m_dFreq.append(ui.f10->text());
m_dFreq.append(ui.f11->text());
m_dFreq.append(ui.f12->text());
m_dFreq.append(ui.f13->text());
m_dFreq.append(ui.f14->text());
m_dFreq.append(ui.f15->text());
m_dFreq.append(ui.f16->text());
m_dFreq.append(ui->f1->text());
m_dFreq.append(ui->f2->text());
m_dFreq.append(ui->f3->text());
m_dFreq.append(ui->f4->text());
m_dFreq.append(ui->f5->text());
m_dFreq.append(ui->f6->text());
m_dFreq.append(ui->f7->text());
m_dFreq.append(ui->f8->text());
m_dFreq.append(ui->f9->text());
m_dFreq.append(ui->f10->text());
m_dFreq.append(ui->f11->text());
m_dFreq.append(ui->f12->text());
m_dFreq.append(ui->f13->text());
m_dFreq.append(ui->f14->text());
m_dFreq.append(ui->f15->text());
m_dFreq.append(ui->f16->text());
m_antDescription.clear();
m_antDescription.append(ui.AntDescription1->text());
m_antDescription.append(ui.AntDescription2->text());
m_antDescription.append(ui.AntDescription3->text());
m_antDescription.append(ui.AntDescription4->text());
m_antDescription.append(ui.AntDescription5->text());
m_antDescription.append(ui.AntDescription6->text());
m_antDescription.append(ui.AntDescription7->text());
m_antDescription.append(ui.AntDescription8->text());
m_antDescription.append(ui.AntDescription9->text());
m_antDescription.append(ui.AntDescription10->text());
m_antDescription.append(ui.AntDescription11->text());
m_antDescription.append(ui.AntDescription12->text());
m_antDescription.append(ui.AntDescription13->text());
m_antDescription.append(ui.AntDescription14->text());
m_antDescription.append(ui.AntDescription15->text());
m_antDescription.append(ui.AntDescription16->text());
m_antDescription.append(ui->AntDescription1->text());
m_antDescription.append(ui->AntDescription2->text());
m_antDescription.append(ui->AntDescription3->text());
m_antDescription.append(ui->AntDescription4->text());
m_antDescription.append(ui->AntDescription5->text());
m_antDescription.append(ui->AntDescription6->text());
m_antDescription.append(ui->AntDescription7->text());
m_antDescription.append(ui->AntDescription8->text());
m_antDescription.append(ui->AntDescription9->text());
m_antDescription.append(ui->AntDescription10->text());
m_antDescription.append(ui->AntDescription11->text());
m_antDescription.append(ui->AntDescription12->text());
m_antDescription.append(ui->AntDescription13->text());
m_antDescription.append(ui->AntDescription14->text());
m_antDescription.append(ui->AntDescription15->text());
m_antDescription.append(ui->AntDescription16->text());
m_bandDescription.clear();
m_bandDescription.append(ui.Band1->text());
m_bandDescription.append(ui.Band2->text());
m_bandDescription.append(ui.Band3->text());
m_bandDescription.append(ui.Band4->text());
m_bandDescription.append(ui.Band5->text());
m_bandDescription.append(ui.Band6->text());
m_bandDescription.append(ui.Band7->text());
m_bandDescription.append(ui.Band8->text());
m_bandDescription.append(ui.Band9->text());
m_bandDescription.append(ui.Band10->text());
m_bandDescription.append(ui.Band11->text());
m_bandDescription.append(ui.Band12->text());
m_bandDescription.append(ui.Band13->text());
m_bandDescription.append(ui.Band14->text());
m_bandDescription.append(ui.Band15->text());
m_bandDescription.append(ui.Band16->text());
m_bandDescription.append(ui->Band1->text());
m_bandDescription.append(ui->Band2->text());
m_bandDescription.append(ui->Band3->text());
m_bandDescription.append(ui->Band4->text());
m_bandDescription.append(ui->Band5->text());
m_bandDescription.append(ui->Band6->text());
m_bandDescription.append(ui->Band7->text());
m_bandDescription.append(ui->Band8->text());
m_bandDescription.append(ui->Band9->text());
m_bandDescription.append(ui->Band10->text());
m_bandDescription.append(ui->Band11->text());
m_bandDescription.append(ui->Band12->text());
m_bandDescription.append(ui->Band13->text());
m_bandDescription.append(ui->Band14->text());
m_bandDescription.append(ui->Band15->text());
m_bandDescription.append(ui->Band16->text());
if(m_bRigOpen) {
@ -338,39 +342,39 @@ void DevSetup::msgBox(QString t) //msgBox
void DevSetup::on_myCallEntry_editingFinished()
{
QString t=ui.myCallEntry->text();
ui.myCallEntry->setText(t.toUpper());
QString t=ui->myCallEntry->text();
ui->myCallEntry->setText(t.toUpper());
}
void DevSetup::on_myGridEntry_editingFinished()
{
QString t=ui.myGridEntry->text();
QString t=ui->myGridEntry->text();
t=t.mid(0,4).toUpper()+t.mid(4,2).toLower();
ui.myGridEntry->setText(t);
ui->myGridEntry->setText(t);
}
void DevSetup::setEnableAntennaDescriptions(bool enable)
{
ui.AntDescription1->setEnabled(enable);
ui.AntDescription2->setEnabled(enable);
ui.AntDescription3->setEnabled(enable);
ui.AntDescription4->setEnabled(enable);
ui.AntDescription5->setEnabled(enable);
ui.AntDescription6->setEnabled(enable);
ui.AntDescription7->setEnabled(enable);
ui.AntDescription8->setEnabled(enable);
ui.AntDescription9->setEnabled(enable);
ui.AntDescription10->setEnabled(enable);
ui.AntDescription11->setEnabled(enable);
ui.AntDescription12->setEnabled(enable);
ui.AntDescription13->setEnabled(enable);
ui.AntDescription14->setEnabled(enable);
ui.AntDescription15->setEnabled(enable);
ui.AntDescription16->setEnabled(enable);
ui->AntDescription1->setEnabled(enable);
ui->AntDescription2->setEnabled(enable);
ui->AntDescription3->setEnabled(enable);
ui->AntDescription4->setEnabled(enable);
ui->AntDescription5->setEnabled(enable);
ui->AntDescription6->setEnabled(enable);
ui->AntDescription7->setEnabled(enable);
ui->AntDescription8->setEnabled(enable);
ui->AntDescription9->setEnabled(enable);
ui->AntDescription10->setEnabled(enable);
ui->AntDescription11->setEnabled(enable);
ui->AntDescription12->setEnabled(enable);
ui->AntDescription13->setEnabled(enable);
ui->AntDescription14->setEnabled(enable);
ui->AntDescription15->setEnabled(enable);
ui->AntDescription16->setEnabled(enable);
if (enable)
ui.AntDescriptionColumnLabel->setText("Antenna description");
ui->AntDescriptionColumnLabel->setText("Antenna description");
else
ui.AntDescriptionColumnLabel->setText("Antenna description (enable PSK Reporter)");
ui->AntDescriptionColumnLabel->setText("Antenna description (enable PSK Reporter)");
}
void DevSetup::on_cbPSKReporter_clicked(bool b)
@ -388,48 +392,48 @@ void DevSetup::on_pttMethodComboBox_activated(int index)
void DevSetup::on_catPortComboBox_activated(int index)
{
m_catPortIndex=index;
m_catPort=ui.catPortComboBox->itemText(index);
m_catPort=ui->catPortComboBox->itemText(index);
}
void DevSetup::on_cbEnableCAT_toggled(bool b)
{
m_catEnabled=b;
enableWidgets();
ui.cbSplit->setChecked(m_bSplit and m_catEnabled);
ui->cbSplit->setChecked(m_bSplit and m_catEnabled);
}
void DevSetup::on_serialRateComboBox_activated(int index)
{
m_serialRateIndex=index;
m_serialRate=ui.serialRateComboBox->itemText(index).toInt();
m_serialRate=ui->serialRateComboBox->itemText(index).toInt();
}
void DevSetup::on_handshakeComboBox_activated(int index)
{
m_handshakeIndex=index;
m_handshake=ui.handshakeComboBox->itemText(index);
m_handshake=ui->handshakeComboBox->itemText(index);
}
void DevSetup::on_handshakeComboBox_currentIndexChanged(int index)
{
ui.RTSCheckBox->setEnabled(index != 2);
ui->RTSCheckBox->setEnabled(index != 2);
}
void DevSetup::on_dataBitsComboBox_activated(int index)
{
m_dataBitsIndex=index;
m_dataBits=ui.dataBitsComboBox->itemText(index).toInt();
m_dataBits=ui->dataBitsComboBox->itemText(index).toInt();
}
void DevSetup::on_stopBitsComboBox_activated(int index)
{
m_stopBitsIndex=index;
m_stopBits=ui.stopBitsComboBox->itemText(index).toInt();
m_stopBits=ui->stopBitsComboBox->itemText(index).toInt();
}
void DevSetup::on_rigComboBox_activated(int index)
{
m_rig = ui.rigComboBox->itemData (index).toInt ();
m_rig = ui->rigComboBox->itemData (index).toInt ();
enableWidgets();
}
@ -452,7 +456,7 @@ void DevSetup::on_testCATButton_clicked()
int(1000000.0*fMHz));
if(m_poll>0) {
m_catEnabled=false;
ui.cbEnableCAT->setChecked(false);
ui->cbEnableCAT->setChecked(false);
}
}
msgBox(t);
@ -492,7 +496,7 @@ void DevSetup::openRig()
rig->setConf("stop_bits",buf);
rig->setConf("serial_handshake",m_handshake.toLatin1().data());
rig->setConf("dtr_state",m_bDTR ? "ON" : "OFF");
if(ui.RTSCheckBox->isEnabled()) {
if(ui->RTSCheckBox->isEnabled()) {
rig->setConf("rts_state",m_bRTS ? "ON" : "OFF");
}
}
@ -504,7 +508,7 @@ void DevSetup::openRig()
t="Open rig failed";
msgBox(t);
m_catEnabled=false;
ui.cbEnableCAT->setChecked(false);
ui->cbEnableCAT->setChecked(false);
return;
}
}
@ -558,62 +562,117 @@ void DevSetup::on_pttMethodComboBox_currentIndexChanged(int index)
{
m_pttMethodIndex=index;
bool b=m_pttMethodIndex==1 or m_pttMethodIndex==2;
ui.pttComboBox->setEnabled(b);
ui->pttComboBox->setEnabled(b);
}
void DevSetup::enableWidgets()
{
ui.cbEnableCAT->setChecked(m_catEnabled);
ui.rigComboBox->setEnabled(m_catEnabled);
ui.testCATButton->setEnabled(m_catEnabled);
ui.label_4->setEnabled(m_catEnabled);
ui.label_47->setEnabled(m_catEnabled);
ui.cbSplit->setEnabled(m_catEnabled);
ui->cbEnableCAT->setChecked(m_catEnabled);
ui->rigComboBox->setEnabled(m_catEnabled);
ui->testCATButton->setEnabled(m_catEnabled);
ui->label_4->setEnabled(m_catEnabled);
ui->label_47->setEnabled(m_catEnabled);
ui->cbSplit->setEnabled(m_catEnabled);
if(m_rig==9999) { //No Split Tx with HRD
ui.cbSplit->setChecked(false);
ui.cbSplit->setEnabled(false);
ui->cbSplit->setChecked(false);
ui->cbSplit->setEnabled(false);
}
ui.cbXIT->setEnabled(m_catEnabled);
ui->cbXIT->setEnabled(m_catEnabled);
bool bSerial=m_catEnabled and (m_rig<9900);
ui.catPortComboBox->setEnabled(bSerial);
ui.serialRateComboBox->setEnabled(bSerial);
ui.dataBitsComboBox->setEnabled(bSerial);
ui.stopBitsComboBox->setEnabled(bSerial);
ui.handshakeComboBox->setEnabled(bSerial);
ui.DTRCheckBox->setEnabled(bSerial);
ui.DTRCheckBox->setChecked(m_bDTR);
ui.RTSCheckBox->setEnabled(bSerial && m_handshakeIndex != 2);
ui.RTSCheckBox->setChecked(m_bRTS);
ui.rbData->setEnabled(bSerial);
ui.rbMic->setEnabled(bSerial);
ui.label_21->setEnabled(bSerial);
ui.label_22->setEnabled(bSerial);
ui.label_23->setEnabled(bSerial);
ui.label_24->setEnabled(bSerial);
ui.label_25->setEnabled(bSerial);
ui->catPortComboBox->setEnabled(bSerial);
ui->serialRateComboBox->setEnabled(bSerial);
ui->dataBitsComboBox->setEnabled(bSerial);
ui->stopBitsComboBox->setEnabled(bSerial);
ui->handshakeComboBox->setEnabled(bSerial);
ui->DTRCheckBox->setEnabled(bSerial);
ui->DTRCheckBox->setChecked(m_bDTR);
ui->RTSCheckBox->setEnabled(bSerial && m_handshakeIndex != 2);
ui->RTSCheckBox->setChecked(m_bRTS);
ui->rbData->setEnabled(bSerial);
ui->rbMic->setEnabled(bSerial);
ui->label_21->setEnabled(bSerial);
ui->label_22->setEnabled(bSerial);
ui->label_23->setEnabled(bSerial);
ui->label_24->setEnabled(bSerial);
ui->label_25->setEnabled(bSerial);
ui.pollSpinBox->setEnabled(m_catEnabled);
ui->pollSpinBox->setEnabled(m_catEnabled);
bool b1=(m_pttMethodIndex==1 or m_pttMethodIndex==2);
ui.pttComboBox->setEnabled(b1);
ui->pttComboBox->setEnabled(b1);
b1=b1 and (m_pttPort!=0);
bool b2 = (m_catEnabled and m_pttMethodIndex==1 and m_rig<9900) or
(m_catEnabled and m_pttMethodIndex==2 and m_rig<9900);
bool b3 = (m_catEnabled and m_pttMethodIndex==0);
ui.testPTTButton->setEnabled(b1 or b2 or b3); //Include PTT via HRD or Commander
ui->testPTTButton->setEnabled(b1 or b2 or b3); //Include PTT via HRD or Commander
setEnableAntennaDescriptions(m_pskReporter);
}
void DevSetup::on_cbSplit_toggled(bool checked)
{
m_bSplit=checked;
if(m_bSplit and m_bXIT) ui.cbXIT->setChecked(false);
if(m_bSplit and m_bXIT) ui->cbXIT->setChecked(false);
}
void DevSetup::on_cbXIT_toggled(bool checked)
{
m_bXIT=checked;
if(m_bSplit and m_bXIT) ui.cbSplit->setChecked(false);
if(m_bSplit and m_bXIT) ui->cbSplit->setChecked(false);
}
void DevSetup::loadAudioDevices (AudioDevices const& d, QComboBox * cb)
{
using std::copy;
using std::back_inserter;
int currentIndex = -1;
int defaultIndex = 0;
for (AudioDevices::const_iterator p = d.cbegin (); p != d.cend (); ++p)
{
// convert supported channel counts into something we can store in the item model
QList<QVariant> channelCounts;
QList<int> scc (p->supportedChannelCounts ());
copy (scc.cbegin (), scc.cend (), back_inserter (channelCounts));
cb->addItem (p->deviceName (), channelCounts);
if (*p == m_audioInputDevice)
{
currentIndex = p - d.cbegin ();
}
else if (*p == QAudioDeviceInfo::defaultInputDevice ())
{
defaultIndex = p - d.cbegin ();
}
}
cb->setCurrentIndex (currentIndex != -1 ? currentIndex : defaultIndex);
}
void DevSetup::updateAudioChannels (QComboBox const * srcCb, int index, QComboBox * cb, bool allowBoth)
{
// disable all items
for (int i (0); i < cb->count (); ++i)
{
cb->setItemData (i, 0, Qt::UserRole - 1); // undocumented model internals allows disable
}
Q_FOREACH (QVariant const& v, srcCb->itemData (index).toList ())
{
// enable valid options
int n (v.toInt ());
if (2 == n)
{
cb->setItemData (AudioDevice::Left, 32 | 1, Qt::UserRole - 1); // undocumented model internals allows enable
cb->setItemData (AudioDevice::Right, 32 | 1, Qt::UserRole - 1);
if (allowBoth)
{
cb->setItemData (AudioDevice::Both, 32 | 1, Qt::UserRole - 1);
}
}
else if (1 == n)
{
cb->setItemData (AudioDevice::Mono, 32 | 1, Qt::UserRole - 1);
}
}
}
typedef QMap<QString, int> RigList;
@ -641,10 +700,10 @@ void DevSetup::enumerateRigs ()
for (RigList::const_iterator r = rigs.cbegin (); r != rigs.cend (); ++r)
{
ui.rigComboBox->addItem (r.key (), r.value ());
ui->rigComboBox->addItem (r.key (), r.value ());
}
ui.rigComboBox->addItem ("DX Lab Suite Commander", 9998);
ui.rigComboBox->addItem ("Ham Radio Deluxe", 9999);
ui.rigComboBox->setCurrentIndex (ui.rigComboBox->findData (m_rig));
ui->rigComboBox->addItem ("DX Lab Suite Commander", 9998);
ui->rigComboBox->addItem ("Ham Radio Deluxe", 9999);
ui->rigComboBox->setCurrentIndex (ui->rigComboBox->findData (m_rig));
}

View File

@ -1,8 +1,6 @@
#ifndef DEVSETUP_H
#define DEVSETUP_H
#include "ui_devsetup.h"
#include <QDialog>
#include <QProcess>
#include <QMessageBox>
@ -11,12 +9,23 @@
#include <hamlib/rig.h>
#include "rigclass.h"
#include "AudioDevice.hpp"
int rigCallback (rig_caps const *, void *);
namespace Ui {
class DevSetup;
}
class QComboBox;
class DevSetup : public QDialog
{
Q_OBJECT
Q_OBJECT;
private:
Ui::DevSetup * ui;
public:
DevSetup(QWidget *parent=0);
~DevSetup();
@ -47,6 +56,8 @@ public:
QAudioDeviceInfo m_audioOutputDevice; /* selected output device */
bool m_restartSoundIn;
bool m_restartSoundOut;
AudioDevice::Channel m_audioInputChannel;
AudioDevice::Channel m_audioOutputChannel;
bool m_pskReporter;
bool m_firstCall;
@ -99,19 +110,18 @@ private slots:
void on_pollSpinBox_valueChanged(int n);
void on_pttComboBox_currentIndexChanged(int index);
void on_pttMethodComboBox_currentIndexChanged(int index);
void on_cbSplit_toggled(bool checked);
void on_cbXIT_toggled(bool checked);
private:
void loadAudioDevices (AudioDevices const&, QComboBox *);
void updateAudioChannels (QComboBox const *, int, QComboBox *, bool);
void enumerateRigs ();
Rig* rig;
void msgBox(QString t);
void setEnableAntennaDescriptions(bool enable);
void enableWidgets();
void openRig();
Ui::DialogSndCard ui;
friend int rigCallback (rig_caps const *, void *);
};

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DialogSndCard</class>
<widget class="QDialog" name="DialogSndCard">
<class>DevSetup</class>
<widget class="QDialog" name="DevSetup">
<property name="geometry">
<rect>
<x>0</x>
@ -1137,77 +1137,8 @@
</spacer>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label_6">
<property name="minimumSize">
<size>
<width>90</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>90</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Audio In:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBoxSndIn">
<property name="enabled">
<bool>true</bool>
</property>
<property name="toolTip">
<string>Select audio input device and driver API</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="label_7">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>90</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>90</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Audio Out:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBoxSndOut">
<property name="toolTip">
<string>select audio output device and driver API</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QGridLayout" name="gridLayout_3">
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_10">
@ -1240,6 +1171,136 @@
</item>
</layout>
</item>
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label_6">
<property name="minimumSize">
<size>
<width>90</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>90</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Audio In:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBoxSndIn">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Select audio input device and driver API</string>
</property>
</widget>
</item>
<item alignment="Qt::AlignRight">
<widget class="QComboBox" name="audioInputChannel">
<item>
<property name="text">
<string>Mono</string>
</property>
</item>
<item>
<property name="text">
<string>Left</string>
</property>
</item>
<item>
<property name="text">
<string>Right</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="label_7">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>90</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>90</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Audio Out:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBoxSndOut">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>select audio output device and driver API</string>
</property>
</widget>
</item>
<item alignment="Qt::AlignRight">
<widget class="QComboBox" name="audioOutputChannel">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>Mono</string>
</property>
</item>
<item>
<property name="text">
<string>Left</string>
</property>
</item>
<item>
<property name="text">
<string>Right</string>
</property>
</item>
<item>
<property name="text">
<string>Both</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
@ -1807,7 +1868,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>510</width>
<width>308</width>
<height>449</height>
</rect>
</property>
@ -2519,7 +2580,7 @@
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>DialogSndCard</receiver>
<receiver>DevSetup</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
@ -2535,7 +2596,7 @@
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>DialogSndCard</receiver>
<receiver>DevSetup</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">

View File

@ -4,16 +4,40 @@
#include <QDebug>
LogQSO::LogQSO(QWidget *parent) :
LogQSO::LogQSO(QSettings * settings, QWidget *parent) :
QDialog(parent),
ui(new Ui::LogQSO)
ui(new Ui::LogQSO),
m_settings (settings)
{
ui->setupUi(this);
loadSettings ();
}
LogQSO::~LogQSO()
LogQSO::~LogQSO ()
{
delete ui;
}
void LogQSO::loadSettings ()
{
m_settings->beginGroup ("LogQSO");
restoreGeometry (m_settings->value ("geometry", saveGeometry ()).toByteArray ());
ui->cbTxPower->setChecked (m_settings->value ("SaveTxPower", false).toBool ());
ui->cbComments->setChecked (m_settings->value ("SaveComments", false).toBool ());
m_txPower = m_settings->value ("TxPower", "").toString ();
m_comments = m_settings->value ("LogComments", "").toString();
m_settings->endGroup ();
}
void LogQSO::storeSettings () const
{
m_settings->beginGroup ("LogQSO");
m_settings->setValue ("geometry", saveGeometry ());
m_settings->setValue ("SaveTxPower", ui->cbTxPower->isChecked ());
m_settings->setValue ("SaveComments", ui->cbComments->isChecked ());
m_settings->setValue ("TxPower", m_txPower);
m_settings->setValue ("LogComments", m_comments);
m_settings->endGroup ();
}
void LogQSO::initLogQSO(QString hisCall, QString hisGrid, QString mode,
@ -25,8 +49,8 @@ void LogQSO::initLogQSO(QString hisCall, QString hisGrid, QString mode,
ui->grid->setText(hisGrid);
ui->txPower->setText("");
ui->comments->setText("");
if(m_saveTxPower) ui->txPower->setText(m_txPower);
if(m_saveComments) ui->comments->setText(m_comments);
if (ui->cbTxPower->isChecked ()) ui->txPower->setText(m_txPower);
if (ui->cbComments->isChecked ()) ui->comments->setText(m_comments);
if(dBtoComments) {
QString t=mode;
if(rptSent!="") t+=" Sent: " + rptSent;
@ -74,8 +98,8 @@ void LogQSO::initLogQSO(QString hisCall, QString hisGrid, QString mode,
if(dialFreq>47000.0 and dialFreq<47200.0) band="6mm";
if(dialFreq>75500.0 and dialFreq<81000.0) band="4mm";
ui->band->setText(band);
ui->cbTxPower->setChecked(m_saveTxPower);
ui->cbComments->setChecked(m_saveComments);
show ();
}
void LogQSO::accept()
@ -163,12 +187,11 @@ void LogQSO::reject()
QDialog::reject();
}
void LogQSO::on_cbTxPower_toggled(bool checked)
// closeEvent is only called from the system menu close widget for a
// modeless dialog so we use the hideEvent override to store the
// window settings
void LogQSO::hideEvent (QHideEvent * e)
{
m_saveTxPower=checked;
}
void LogQSO::on_cbComments_toggled(bool checked)
{
m_saveComments=checked;
storeSettings ();
QDialog::hideEvent (e);
}

View File

@ -7,34 +7,26 @@
#include <QtGui>
#endif
#include <QScopedPointer>
namespace Ui {
class LogQSO;
class LogQSO;
}
class QSettings;
class LogQSO : public QDialog
{
Q_OBJECT
public:
explicit LogQSO(QWidget *parent = 0);
explicit LogQSO(QSettings *, QWidget *parent = 0);
~LogQSO();
void initLogQSO(QString hisCall, QString hisGrid, QString mode,
QString rptSent, QString rptRcvd, QDateTime dateTime,
double dialFreq, QString myCall, QString myGrid,
bool noSuffix, bool toRTTY, bool dBtoComments);
double m_dialFreq;
bool m_saveTxPower;
bool m_saveComments;
QString m_myCall;
QString m_myGrid;
QString m_txPower;
QString m_comments;
QDateTime m_dateTime;
public slots:
void accept();
void reject();
@ -42,12 +34,21 @@ public slots:
signals:
void acceptQSO(bool accepted);
private slots:
void on_cbTxPower_toggled(bool checked);
void on_cbComments_toggled(bool checked);
protected:
void hideEvent (QHideEvent *);
private:
Ui::LogQSO *ui;
void loadSettings ();
void storeSettings () const;
QScopedPointer<Ui::LogQSO> ui;
QSettings * m_settings;
QString m_txPower;
QString m_comments;
double m_dialFreq;
QString m_myCall;
QString m_myGrid;
QDateTime m_dateTime;
};
#endif // LogQSO_H

View File

@ -5,6 +5,7 @@
#endif
#include <QApplication>
#include <QObject>
#include <QSettings>
#include "mainwindow.h"
@ -18,6 +19,10 @@ int main(int argc, char *argv[])
{
QApplication a(argc, argv);
qRegisterMetaType<AudioDevice::Channel> ("AudioDevice::Channel");
QSettings settings(a.applicationDirPath() + "/wsjtx.ini", QSettings::IniFormat);
QFile f("fonts.txt");
qint32 fontSize,fontWeight,fontSize2,fontWeight2; // Defaults 8 50 10 50
fontSize2=10;
@ -51,7 +56,7 @@ int main(int argc, char *argv[])
memset(to,0,size); //Zero all decoding params in shared memory
// Multiple instances: Call MainWindow() with the UUID key
MainWindow w(&mem_jt9, &my_key, fontSize2, fontWeight2);
MainWindow w(&settings, &mem_jt9, &my_key, fontSize2, fontWeight2);
w.show();
QObject::connect (&a, SIGNAL (lastWindowClosed()), &a, SLOT (quit()));

View File

@ -15,7 +15,6 @@
#include "logqso.h"
#ifdef QT5
#include <QtConcurrent/QtConcurrentMap>
#include <QtConcurrent/QtConcurrentRun>
#endif
@ -30,8 +29,6 @@ static int nc1=1;
wchar_t buffer[256];
WideGraph* g_pWideGraph = NULL;
LogQSO* logDlg = NULL;
Rig* rig = NULL;
QTextEdit* pShortcuts;
QTcpSocket* commanderSocket = new QTcpSocket(0);
@ -42,49 +39,73 @@ QString Program_Title_Version=" WSJT-X v1.2, r" + rev.mid(6,4) +
//-------------------------------------------------- MainWindow constructor
// Multiple instances: new arg *thekey
MainWindow::MainWindow(QSharedMemory *shdmem, QString *thekey, \
qint32 fontSize2, qint32 fontWeight2, \
MainWindow::MainWindow(QSettings * settings, QSharedMemory *shdmem, QString *thekey,
qint32 fontSize2, qint32 fontWeight2,
QWidget *parent) :
QMainWindow(parent),
m_settings (settings),
ui(new Ui::MainWindow),
m_detector (RX_SAMPLE_RATE, NTMAX / 2, 6912 / 2 * sizeof (jt9com_.d2[0]), this),
m_wideGraph (new WideGraph (settings)),
m_logDlg (new LogQSO (settings, this)),
m_detector (RX_SAMPLE_RATE, NTMAX / 2, 6912 / 2, this),
m_audioInputDevice (QAudioDeviceInfo::defaultInputDevice ()), // start with default
m_modulator (TX_SAMPLE_RATE, NTMAX / 2),
m_audioOutputDevice (QAudioDeviceInfo::defaultOutputDevice ()), // start with default
m_soundOutput (&m_modulator)
{
ui->setupUi(this);
m_detector.open ();
m_modulator.open ();
connect (this, &MainWindow::finished, this, &MainWindow::close);
// start sound out thread and hook up slots & signals for shutdown management
// these two objects need to be in the other thread so that invoking
// their slots is done in a thread safe way
m_soundOutput.moveToThread (&m_soundOutputThread);
m_modulator.moveToThread (&m_soundOutputThread);
connect (this, &MainWindow::finished, &m_soundOutputThread, &QThread::quit); // quit thread event loop
connect (&m_soundOutputThread, &QThread::finished, &m_soundOutputThread, &QThread::deleteLater); // disposal
// hook up sound output stream slots & signals
connect (this, &MainWindow::startAudioOutputStream, &m_soundOutput, &SoundOutput::startStream);
connect (this, &MainWindow::stopAudioOutputStream, &m_soundOutput, &SoundOutput::stopStream);
connect (this, SIGNAL (startAudioOutputStream (QAudioDeviceInfo const&, unsigned)), &m_soundOutput, SLOT (startStream (QAudioDeviceInfo const&, unsigned)));
connect (this, SIGNAL (stopAudioOutputStream ()), &m_soundOutput, SLOT (stopStream ()));
connect (&m_soundOutput, &SoundOutput::error, this, &MainWindow::showSoundOutError);
// connect (&m_soundOutput, &SoundOutput::status, this, &MainWindow::showStatusMessage);
connect (this, SIGNAL (outAttenuationChanged (qreal)), &m_soundOutput, SLOT (setAttenuation (qreal)));
// hook up Modulator slots
connect (this, &MainWindow::muteAudioOutput, &m_modulator, &Modulator::mute);
connect (this, &MainWindow::transmitFrequency, &m_modulator, &Modulator::setFrequency);
connect (this, &MainWindow::endTransmitMessage, &m_modulator, &Modulator::stop);
connect (this, &MainWindow::tune, &m_modulator, &Modulator::tune);
connect (this, SIGNAL (muteAudioOutput (bool)), &m_modulator, SLOT (mute (bool)));
connect (this, SIGNAL(transmitFrequency (unsigned)), &m_modulator, SLOT (setFrequency (unsigned)));
connect (this, SIGNAL (endTransmitMessage ()), &m_modulator, SLOT (close ()));
connect (this, SIGNAL (tune (bool)), &m_modulator, SLOT (tune (bool)));
connect (
this
, SIGNAL (sendMessage (unsigned, double, unsigned, bool, double))
, SIGNAL (sendMessage (unsigned, double, unsigned, AudioDevice::Channel, bool, double))
, &m_modulator
, SLOT (send (unsigned, double, unsigned, bool, double))
, SLOT (open (unsigned, double, unsigned, AudioDevice::Channel, bool, double))
);
// start the sound output thread
m_soundOutputThread.start (QThread::HighPriority);
// setup the waterfall
connect(m_wideGraph.data (), SIGNAL(freezeDecode2(int)),this,
SLOT(freezeDecode(int)));
connect(m_wideGraph.data (), SIGNAL(f11f12(int)),this,
SLOT(bumpFqso(int)));
connect(m_wideGraph.data (), SIGNAL(setXIT2(int)),this,
SLOT(setXIT(int)));
// connect(m_wideGraph.data (), SIGNAL(dialFreqChanged(double)),this,
// SLOT(dialFreqChanged2(double)));
connect (this, &MainWindow::finished, m_wideGraph.data (), &WideGraph::close);
// setup the log QSO dialog
connect (m_logDlg.data (), SIGNAL (acceptQSO (bool)), this, SLOT (acceptQSO2 (bool)));
on_EraseButton_clicked();
QActionGroup* modeGroup = new QActionGroup(this);
@ -117,7 +138,7 @@ MainWindow::MainWindow(QSharedMemory *shdmem, QString *thekey, \
SLOT(doubleClickOnCall2(bool,bool)));
setWindowTitle(Program_Title_Version);
connect(&m_detector, &Detector::bytesWritten, this, &MainWindow::dataSink);
connect(&m_detector, &Detector::framesWritten, this, &MainWindow::dataSink);
connect(&m_soundInput, SIGNAL(error(QString)), this,
SLOT(showSoundInError(QString)));
// connect(&m_soundInput, SIGNAL(status(QString)), this,
@ -165,6 +186,7 @@ MainWindow::MainWindow(QSharedMemory *shdmem, QString *thekey, \
ptt0Timer = new QTimer(this);
ptt0Timer->setSingleShot(true);
connect (ptt0Timer, SIGNAL (timeout ()), &m_modulator, SLOT (close ()));
connect(ptt0Timer, SIGNAL(timeout()), this, SLOT(stopTx2()));
ptt1Timer = new QTimer(this);
ptt1Timer->setSingleShot(true);
@ -176,6 +198,7 @@ MainWindow::MainWindow(QSharedMemory *shdmem, QString *thekey, \
tuneButtonTimer= new QTimer(this);
tuneButtonTimer->setSingleShot(true);
connect (tuneButtonTimer, SIGNAL (timeout ()), &m_modulator, SLOT (close ()));
connect(tuneButtonTimer, SIGNAL(timeout()), this,
SLOT(on_stopTxButton_clicked()));
@ -318,15 +341,14 @@ MainWindow::MainWindow(QSharedMemory *shdmem, QString *thekey, \
ui->txrb6->setChecked(true);
if(m_mode!="JT9" and m_mode!="JT65" and m_mode!="JT9+JT65") m_mode="JT9";
on_actionWide_Waterfall_triggered(); //###
g_pWideGraph->setRxFreq(m_rxFreq);
g_pWideGraph->setTxFreq(m_txFreq);
g_pWideGraph->setLockTxFreq(m_lockTxFreq);
g_pWideGraph->setFmin(m_fMin);
g_pWideGraph->setModeTx(m_mode);
g_pWideGraph->setModeTx(m_modeTx);
m_wideGraph->setRxFreq(m_rxFreq);
m_wideGraph->setTxFreq(m_txFreq);
m_wideGraph->setLockTxFreq(m_lockTxFreq);
m_wideGraph->setModeTx(m_mode);
m_wideGraph->setModeTx(m_modeTx);
dialFreqChanged2(m_dialFreq);
connect(g_pWideGraph, SIGNAL(setFreq3(int,int)),this,
connect(m_wideGraph.data (), SIGNAL(setFreq3(int,int)),this,
SLOT(setFreq4(int,int)));
if(m_mode=="JT9") on_actionJT9_1_triggered();
@ -341,7 +363,9 @@ MainWindow::MainWindow(QSharedMemory *shdmem, QString *thekey, \
watcher2 = new QFutureWatcher<void>;
connect(watcher2, SIGNAL(finished()),this,SLOT(diskWriteFinished()));
m_soundInput.start(m_audioInputDevice, RX_SAMPLE_RATE / 10, &m_detector);
m_detector.open (m_audioInputChannel);
m_soundInput.start(m_audioInputDevice, AudioDevice::Mono == m_audioInputChannel ? 1 : 2, RX_SAMPLE_RATE / 10, &m_detector);
Q_EMIT transmitFrequency (m_txFreq - (m_bSplit || m_bXIT ? m_XIT : 0));
Q_EMIT muteAudioOutput (false);
m_monitoring=!m_monitorStartOFF; // Start with Monitoring ON/OFF
@ -400,125 +424,113 @@ MainWindow::~MainWindow()
//-------------------------------------------------------- writeSettings()
void MainWindow::writeSettings()
{
QString inifile = m_appDir + "/wsjtx.ini";
QSettings settings(inifile, QSettings::IniFormat);
m_settings->beginGroup("MainWindow");
m_settings->setValue ("geometry", saveGeometry ());
m_settings->setValue ("state", saveState ());
m_settings->setValue("MRUdir", m_path);
m_settings->setValue("TxFirst",m_txFirst);
m_settings->setValue("DXcall",ui->dxCallEntry->text());
m_settings->setValue("DXgrid",ui->dxGridEntry->text());
m_settings->endGroup();
settings.beginGroup("MainWindow");
settings.setValue("geometry", saveGeometry());
settings.setValue("MRUdir", m_path);
settings.setValue("TxFirst",m_txFirst);
settings.setValue("DXcall",ui->dxCallEntry->text());
settings.setValue("DXgrid",ui->dxGridEntry->text());
if(g_pWideGraph->isVisible()) {
m_wideGraphGeom = g_pWideGraph->geometry();
settings.setValue("WideGraphGeom",m_wideGraphGeom);
m_fMin=g_pWideGraph->getFmin();
}
settings.endGroup();
m_settings->beginGroup("Common");
m_settings->setValue("MyCall",m_myCall);
m_settings->setValue("MyGrid",m_myGrid);
m_settings->setValue("IDint",m_idInt);
m_settings->setValue("PTTmethod",m_pttMethodIndex);
m_settings->setValue("PTTport",m_pttPort);
m_settings->setValue("SaveDir",m_saveDir);
m_settings->setValue("SoundInName", m_audioInputDevice.deviceName ());
m_settings->setValue("SoundOutName", m_audioOutputDevice.deviceName ());
settings.beginGroup("Common");
settings.setValue("MyCall",m_myCall);
settings.setValue("MyGrid",m_myGrid);
settings.setValue("IDint",m_idInt);
settings.setValue("PTTmethod",m_pttMethodIndex);
settings.setValue("PTTport",m_pttPort);
settings.setValue("SaveDir",m_saveDir);
settings.setValue("SoundInName", m_audioInputDevice.deviceName ());
settings.setValue("SoundOutName", m_audioOutputDevice.deviceName ());
settings.setValue("Mode",m_mode);
settings.setValue("ModeTx",m_modeTx);
settings.setValue("SaveNone",ui->actionNone->isChecked());
settings.setValue("SaveDecoded",ui->actionSave_decoded->isChecked());
settings.setValue("SaveAll",ui->actionSave_all->isChecked());
settings.setValue("NDepth",m_ndepth);
settings.setValue("MonitorOFF",m_monitorStartOFF);
settings.setValue("DialFreq",m_dialFreq);
settings.setValue("RxFreq",m_rxFreq);
settings.setValue("TxFreq",m_txFreq);
settings.setValue("InGain",m_inGain);
settings.setValue("PSKReporter",m_pskReporter);
settings.setValue("After73",m_After73);
settings.setValue("Macros",m_macro);
m_settings->setValue ("AudioInputChannel", AudioDevice::toString (m_audioInputChannel));
m_settings->setValue ("AudioOutputChannel", AudioDevice::toString (m_audioOutputChannel));
m_settings->setValue("Mode",m_mode);
m_settings->setValue("ModeTx",m_modeTx);
m_settings->setValue("SaveNone",ui->actionNone->isChecked());
m_settings->setValue("SaveDecoded",ui->actionSave_decoded->isChecked());
m_settings->setValue("SaveAll",ui->actionSave_all->isChecked());
m_settings->setValue("NDepth",m_ndepth);
m_settings->setValue("MonitorOFF",m_monitorStartOFF);
m_settings->setValue("DialFreq",m_dialFreq);
m_settings->setValue("RxFreq",m_rxFreq);
m_settings->setValue("TxFreq",m_txFreq);
m_settings->setValue("InGain",m_inGain);
m_settings->setValue("OutAttenuation", ui->outAttenuation->value ());
m_settings->setValue("PSKReporter",m_pskReporter);
m_settings->setValue("After73",m_After73);
m_settings->setValue("Macros",m_macro);
//Band Settings
settings.setValue("BandFrequencies",m_dFreq);
settings.setValue("BandDescriptions",m_bandDescription);
settings.setValue("AntennaDescriptions",m_antDescription);
settings.setValue("toRTTY",m_toRTTY);
settings.setValue("NoSuffix",m_noSuffix);
settings.setValue("dBtoComments",m_dBtoComments);
settings.setValue("catEnabled",m_catEnabled);
settings.setValue("Rig",m_rig);
settings.setValue("RigIndex",m_rigIndex);
settings.setValue("CATport",m_catPort);
settings.setValue("CATportIndex",m_catPortIndex);
settings.setValue("SerialRate",m_serialRate);
settings.setValue("SerialRateIndex",m_serialRateIndex);
settings.setValue("DataBits",m_dataBits);
settings.setValue("DataBitsIndex",m_dataBitsIndex);
settings.setValue("StopBits",m_stopBits);
settings.setValue("StopBitsIndex",m_stopBitsIndex);
settings.setValue("Handshake",m_handshake);
settings.setValue("HandshakeIndex",m_handshakeIndex);
settings.setValue("BandIndex",m_band);
settings.setValue("PromptToLog",m_promptToLog);
settings.setValue("InsertBlank",m_insertBlank);
settings.setValue("DXCCEntity",m_displayDXCCEntity);
settings.setValue("ClearCallGrid",m_clearCallGrid);
settings.setValue("Miles",m_bMiles);
settings.setValue("GUItab",ui->tabWidget->currentIndex());
settings.setValue("QuickCall",m_quickCall);
settings.setValue("73TxDisable",m_73TxDisable);
settings.setValue("Runaway",m_runaway);
settings.setValue("Tx2QSO",m_tx2QSO);
settings.setValue("MultipleOK",m_bMultipleOK);
settings.setValue("DTR",m_bDTR);
settings.setValue("RTS",m_bRTS); settings.setValue("pttData",m_pttData);
settings.setValue("LogQSOgeom",m_logQSOgeom);
settings.setValue("Polling",m_poll);
settings.setValue("OutBufSize",outBufSize);
settings.setValue("LockTxFreq",m_lockTxFreq);
settings.setValue("SaveTxPower",m_saveTxPower);
settings.setValue("SaveComments",m_saveComments);
settings.setValue("TxPower",m_txPower);
settings.setValue("LogComments",m_logComments);
settings.setValue("Fmin",m_fMin);
settings.setValue("TxSplit",m_bSplit);
settings.setValue("UseXIT",m_bXIT);
settings.setValue("XIT",m_XIT);
settings.setValue("Plus2kHz",m_plus2kHz);
settings.endGroup();
m_settings->setValue("BandFrequencies",m_dFreq);
m_settings->setValue("BandDescriptions",m_bandDescription);
m_settings->setValue("AntennaDescriptions",m_antDescription);
m_settings->setValue("toRTTY",m_toRTTY);
m_settings->setValue("NoSuffix",m_noSuffix);
m_settings->setValue("dBtoComments",m_dBtoComments);
m_settings->setValue("catEnabled",m_catEnabled);
m_settings->setValue("Rig",m_rig);
m_settings->setValue("RigIndex",m_rigIndex);
m_settings->setValue("CATport",m_catPort);
m_settings->setValue("CATportIndex",m_catPortIndex);
m_settings->setValue("SerialRate",m_serialRate);
m_settings->setValue("SerialRateIndex",m_serialRateIndex);
m_settings->setValue("DataBits",m_dataBits);
m_settings->setValue("DataBitsIndex",m_dataBitsIndex);
m_settings->setValue("StopBits",m_stopBits);
m_settings->setValue("StopBitsIndex",m_stopBitsIndex);
m_settings->setValue("Handshake",m_handshake);
m_settings->setValue("HandshakeIndex",m_handshakeIndex);
m_settings->setValue("BandIndex",m_band);
m_settings->setValue("PromptToLog",m_promptToLog);
m_settings->setValue("InsertBlank",m_insertBlank);
m_settings->setValue("DXCCEntity",m_displayDXCCEntity);
m_settings->setValue("ClearCallGrid",m_clearCallGrid);
m_settings->setValue("Miles",m_bMiles);
m_settings->setValue("GUItab",ui->tabWidget->currentIndex());
m_settings->setValue("QuickCall",m_quickCall);
m_settings->setValue("73TxDisable",m_73TxDisable);
m_settings->setValue("Runaway",m_runaway);
m_settings->setValue("Tx2QSO",m_tx2QSO);
m_settings->setValue("MultipleOK",m_bMultipleOK);
m_settings->setValue("DTR",m_bDTR);
m_settings->setValue("RTS",m_bRTS); m_settings->setValue("pttData",m_pttData);
m_settings->setValue("Polling",m_poll);
m_settings->setValue("OutBufSize",outBufSize);
m_settings->setValue("LockTxFreq",m_lockTxFreq);
m_settings->setValue("TxSplit",m_bSplit);
m_settings->setValue("UseXIT",m_bXIT);
m_settings->setValue("XIT",m_XIT);
m_settings->setValue("Plus2kHz",m_plus2kHz);
m_settings->endGroup();
}
//---------------------------------------------------------- readSettings()
void MainWindow::readSettings()
{
QString inifile = m_appDir + "/wsjtx.ini";
QSettings settings(inifile, QSettings::IniFormat);
settings.beginGroup("MainWindow");
restoreGeometry(settings.value("geometry").toByteArray());
ui->dxCallEntry->setText(settings.value("DXcall","").toString());
ui->dxGridEntry->setText(settings.value("DXgrid","").toString());
m_wideGraphGeom = settings.value("WideGraphGeom", \
QRect(45,30,726,301)).toRect();
m_path = settings.value("MRUdir", m_appDir + "/save").toString();
m_txFirst = settings.value("TxFirst",false).toBool();
m_settings->beginGroup("MainWindow");
restoreGeometry (m_settings->value ("geometry", saveGeometry ()).toByteArray ());
restoreState (m_settings->value ("state", saveState ()).toByteArray ());
ui->dxCallEntry->setText(m_settings->value("DXcall","").toString());
ui->dxGridEntry->setText(m_settings->value("DXgrid","").toString());
m_path = m_settings->value("MRUdir", m_appDir + "/save").toString();
m_txFirst = m_settings->value("TxFirst",false).toBool();
ui->txFirstCheckBox->setChecked(m_txFirst);
settings.endGroup();
m_settings->endGroup();
settings.beginGroup("Common");
m_myCall=settings.value("MyCall","").toString();
m_settings->beginGroup("Common");
m_myCall=m_settings->value("MyCall","").toString();
morse_(m_myCall.toLatin1().data(),icw,&m_ncw,m_myCall.length());
m_myGrid=settings.value("MyGrid","").toString();
m_idInt=settings.value("IDint",0).toInt();
m_pttMethodIndex=settings.value("PTTmethod",1).toInt();
m_pttPort=settings.value("PTTport",0).toInt();
m_saveDir=settings.value("SaveDir",m_appDir + "/save").toString();
m_myGrid=m_settings->value("MyGrid","").toString();
m_idInt=m_settings->value("IDint",0).toInt();
m_pttMethodIndex=m_settings->value("PTTmethod",1).toInt();
m_pttPort=m_settings->value("PTTport",0).toInt();
m_saveDir=m_settings->value("SaveDir",m_appDir + "/save").toString();
{
//
// retrieve audio input device
//
QString savedName = settings.value( "SoundInName").toString();
QString savedName = m_settings->value( "SoundInName").toString();
QList<QAudioDeviceInfo> audioInputDevices (QAudioDeviceInfo::availableDevices (QAudio::AudioInput)); // available audio input devices
for (QList<QAudioDeviceInfo>::const_iterator p = audioInputDevices.begin (); p != audioInputDevices.end (); ++p)
{
@ -533,7 +545,7 @@ void MainWindow::readSettings()
//
// retrieve audio output device
//
QString savedName = settings.value("SoundOutName").toString();
QString savedName = m_settings->value("SoundOutName").toString();
QList<QAudioDeviceInfo> audioOutputDevices (QAudioDeviceInfo::availableDevices (QAudio::AudioOutput)); // available audio output devices
for (QList<QAudioDeviceInfo>::const_iterator p = audioOutputDevices.begin (); p != audioOutputDevices.end (); ++p)
{
@ -543,95 +555,98 @@ void MainWindow::readSettings()
}
}
m_mode=settings.value("Mode","JT9").toString();
m_modeTx=settings.value("ModeTx","JT9").toString();
// retrieve audio channel info
m_audioInputChannel = AudioDevice::fromString (m_settings->value ("AudioInputChannel", "Mono").toString ());
m_audioOutputChannel = AudioDevice::fromString (m_settings->value ("AudioOutputChannel", "Mono").toString ());
m_mode=m_settings->value("Mode","JT9").toString();
m_modeTx=m_settings->value("ModeTx","JT9").toString();
if(m_modeTx=="JT9") ui->pbTxMode->setText("Tx JT9 @");
if(m_modeTx=="JT65") ui->pbTxMode->setText("Tx JT65 #");
ui->actionNone->setChecked(settings.value("SaveNone",true).toBool());
ui->actionSave_decoded->setChecked(settings.value(
ui->actionNone->setChecked(m_settings->value("SaveNone",true).toBool());
ui->actionSave_decoded->setChecked(m_settings->value(
"SaveDecoded",false).toBool());
ui->actionSave_all->setChecked(settings.value("SaveAll",false).toBool());
m_dialFreq=settings.value("DialFreq",14.078).toDouble();
m_rxFreq=settings.value("RxFreq",1500).toInt();
ui->actionSave_all->setChecked(m_settings->value("SaveAll",false).toBool());
m_dialFreq=m_settings->value("DialFreq",14.078).toDouble();
m_rxFreq=m_settings->value("RxFreq",1500).toInt();
ui->RxFreqSpinBox->setValue(m_rxFreq);
m_txFreq=settings.value("TxFreq",1500).toInt();
m_txFreq=m_settings->value("TxFreq",1500).toInt();
ui->TxFreqSpinBox->setValue(m_txFreq);
Q_EMIT transmitFrequency (m_txFreq - (m_bSplit || m_bXIT ? m_XIT : 0));
m_saveDecoded=ui->actionSave_decoded->isChecked();
m_saveAll=ui->actionSave_all->isChecked();
m_ndepth=settings.value("NDepth",3).toInt();
m_inGain=settings.value("InGain",0).toInt();
m_ndepth=m_settings->value("NDepth",3).toInt();
m_inGain=m_settings->value("InGain",0).toInt();
ui->inGain->setValue(m_inGain);
m_monitorStartOFF=settings.value("MonitorOFF",false).toBool();
// setup initial value of tx attenuator
ui->outAttenuation->setValue (m_settings->value ("OutAttenuation", 0).toInt ());
on_outAttenuation_valueChanged (ui->outAttenuation->value ());
m_monitorStartOFF=m_settings->value("MonitorOFF",false).toBool();
ui->actionMonitor_OFF_at_startup->setChecked(m_monitorStartOFF);
m_pskReporter=settings.value("PSKReporter",false).toBool();
m_After73=settings.value("After73",false).toBool();
m_macro=settings.value("Macros","TNX 73 GL").toStringList();
m_pskReporter=m_settings->value("PSKReporter",false).toBool();
m_After73=m_settings->value("After73",false).toBool();
m_macro=m_settings->value("Macros","TNX 73 GL").toStringList();
//Band Settings
m_dFreq=settings.value("BandFrequencies","").toStringList();
m_bandDescription=settings.value("BandDescriptions","").toStringList();
m_antDescription=settings.value("AntennaDescriptions","").toStringList();
m_toRTTY=settings.value("toRTTY",false).toBool();
m_dFreq=m_settings->value("BandFrequencies","").toStringList();
m_bandDescription=m_settings->value("BandDescriptions","").toStringList();
m_antDescription=m_settings->value("AntennaDescriptions","").toStringList();
m_toRTTY=m_settings->value("toRTTY",false).toBool();
ui->actionConvert_JT9_x_to_RTTY->setChecked(m_toRTTY);
m_noSuffix=settings.value("NoSuffix",false).toBool();
m_dBtoComments=settings.value("dBtoComments",false).toBool();
m_noSuffix=m_settings->value("NoSuffix",false).toBool();
m_dBtoComments=m_settings->value("dBtoComments",false).toBool();
ui->actionLog_dB_reports_to_Comments->setChecked(m_dBtoComments);
m_rig=settings.value("Rig",214).toInt();
m_rigIndex=settings.value("RigIndex",100).toInt();
m_catPort=settings.value("CATport","None").toString();
m_catPortIndex=settings.value("CATportIndex",0).toInt();
m_serialRate=settings.value("SerialRate",4800).toInt();
m_serialRateIndex=settings.value("SerialRateIndex",1).toInt();
m_dataBits=settings.value("DataBits",8).toInt();
m_dataBitsIndex=settings.value("DataBitsIndex",1).toInt();
m_stopBits=settings.value("StopBits",2).toInt();
m_stopBitsIndex=settings.value("StopBitsIndex",1).toInt();
m_handshake=settings.value("Handshake","None").toString();
m_handshakeIndex=settings.value("HandshakeIndex",0).toInt();
m_band=settings.value("BandIndex",7).toInt();
m_rig=m_settings->value("Rig",214).toInt();
m_rigIndex=m_settings->value("RigIndex",100).toInt();
m_catPort=m_settings->value("CATport","None").toString();
m_catPortIndex=m_settings->value("CATportIndex",0).toInt();
m_serialRate=m_settings->value("SerialRate",4800).toInt();
m_serialRateIndex=m_settings->value("SerialRateIndex",1).toInt();
m_dataBits=m_settings->value("DataBits",8).toInt();
m_dataBitsIndex=m_settings->value("DataBitsIndex",1).toInt();
m_stopBits=m_settings->value("StopBits",2).toInt();
m_stopBitsIndex=m_settings->value("StopBitsIndex",1).toInt();
m_handshake=m_settings->value("Handshake","None").toString();
m_handshakeIndex=m_settings->value("HandshakeIndex",0).toInt();
m_band=m_settings->value("BandIndex",7).toInt();
ui->bandComboBox->setCurrentIndex(m_band);
dialFreqChanged2(m_dialFreq);
m_catEnabled=settings.value("catEnabled",false).toBool();
m_promptToLog=settings.value("PromptToLog",false).toBool();
m_catEnabled=m_settings->value("catEnabled",false).toBool();
m_promptToLog=m_settings->value("PromptToLog",false).toBool();
ui->actionPrompt_to_log_QSO->setChecked(m_promptToLog);
m_insertBlank=settings.value("InsertBlank",false).toBool();
m_insertBlank=m_settings->value("InsertBlank",false).toBool();
ui->actionBlank_line_between_decoding_periods->setChecked(m_insertBlank);
m_displayDXCCEntity=settings.value("DXCCEntity",false).toBool();
m_displayDXCCEntity=m_settings->value("DXCCEntity",false).toBool();
ui->actionEnable_DXCC_entity->setChecked(m_displayDXCCEntity);
m_clearCallGrid=settings.value("ClearCallGrid",false).toBool();
m_clearCallGrid=m_settings->value("ClearCallGrid",false).toBool();
ui->actionClear_DX_Call_and_Grid_after_logging->setChecked(m_clearCallGrid);
m_bMiles=settings.value("Miles",false).toBool();
m_bMiles=m_settings->value("Miles",false).toBool();
ui->actionDisplay_distance_in_miles->setChecked(m_bMiles);
int n=settings.value("GUItab",0).toInt();
int n=m_settings->value("GUItab",0).toInt();
ui->tabWidget->setCurrentIndex(n);
m_quickCall=settings.value("QuickCall",false).toBool();
m_quickCall=m_settings->value("QuickCall",false).toBool();
ui->actionDouble_click_on_call_sets_Tx_Enable->setChecked(m_quickCall);
m_73TxDisable=settings.value("73TxDisable",false).toBool();
m_73TxDisable=m_settings->value("73TxDisable",false).toBool();
ui->action_73TxDisable->setChecked(m_73TxDisable);
m_runaway=settings.value("Runaway",false).toBool();
m_runaway=m_settings->value("Runaway",false).toBool();
ui->actionRunaway_Tx_watchdog->setChecked(m_runaway);
m_tx2QSO=settings.value("Tx2QSO",false).toBool();
m_tx2QSO=m_settings->value("Tx2QSO",false).toBool();
ui->actionTx2QSO->setChecked(m_tx2QSO);
m_bMultipleOK=settings.value("MultipleOK",false).toBool();
m_bMultipleOK=m_settings->value("MultipleOK",false).toBool();
ui->actionAllow_multiple_instances->setChecked(m_bMultipleOK);
m_bDTR=settings.value("DTR",false).toBool();
m_bRTS=settings.value("RTS",false).toBool(); m_pttData=settings.value("pttData",false).toBool();
m_poll=settings.value("Polling",0).toInt();
m_logQSOgeom=settings.value("LogQSOgeom",QRect(500,400,424,283)).toRect();
outBufSize=settings.value("OutBufSize",4096).toInt();
m_lockTxFreq=settings.value("LockTxFreq",false).toBool();
m_bDTR=m_settings->value("DTR",false).toBool();
m_bRTS=m_settings->value("RTS",false).toBool(); m_pttData=m_settings->value("pttData",false).toBool();
m_poll=m_settings->value("Polling",0).toInt();
outBufSize=m_settings->value("OutBufSize",4096).toInt();
m_lockTxFreq=m_settings->value("LockTxFreq",false).toBool();
ui->cbTxLock->setChecked(m_lockTxFreq);
m_saveTxPower=settings.value("SaveTxPower",false).toBool();
m_saveComments=settings.value("SaveComments",false).toBool();
m_txPower=settings.value("TxPower","").toString();
m_logComments=settings.value("LogComments","").toString();
m_fMin=settings.value("fMin",2500).toInt();
m_bSplit=settings.value("TxSplit",false).toBool();
m_bXIT=settings.value("UseXIT",false).toBool();
m_XIT=settings.value("XIT",0).toInt();
m_plus2kHz=settings.value("Plus2kHz",false).toBool();
m_bSplit=m_settings->value("TxSplit",false).toBool();
m_bXIT=m_settings->value("UseXIT",false).toBool();
m_XIT=m_settings->value("XIT",0).toInt();
m_plus2kHz=m_settings->value("Plus2kHz",false).toBool();
ui->cbPlus2kHz->setChecked(m_plus2kHz);
settings.endGroup();
m_settings->endGroup();
if(m_ndepth==1) ui->actionQuickDecode->setChecked(true);
if(m_ndepth==2) ui->actionMediumDecode->setChecked(true);
@ -641,7 +656,7 @@ void MainWindow::readSettings()
}
//-------------------------------------------------------------- dataSink()
void MainWindow::dataSink(qint64 bytes)
void MainWindow::dataSink(qint64 frames)
{
static float s[NSMAX];
static int ihsym=0;
@ -661,8 +676,8 @@ void MainWindow::dataSink(qint64 bytes)
// Get power, spectrum, and ihsym
trmin=m_TRperiod/60;
slope=0.0;
if(g_pWideGraph!=NULL) slope=(float)g_pWideGraph->getSlope();
int k (bytes / sizeof (jt9com_.d2[0]) - 1);
slope=(float)m_wideGraph->getSlope();
int k (frames - 1);
symspec_(&k,&trmin,&m_nsps,&m_inGain,&slope,&px,s,&df3,&ihsym,&npts8);
if(ihsym <=0) return;
QString t;
@ -670,7 +685,7 @@ void MainWindow::dataSink(qint64 bytes)
t.sprintf(" Rx noise: %5.1f ",px);
signalMeter->setValue(px); // Update thermometer
if(m_monitoring || m_diskData) {
g_pWideGraph->dataSink2(s,df3,ihsym,m_diskData);
m_wideGraph->dataSink2(s,df3,ihsym,m_diskData);
}
if(ihsym == m_hsymStop) {
@ -716,6 +731,8 @@ void MainWindow::on_actionDeviceSetup_triggered() //Setup Dialog
dlg.m_saveDir=m_saveDir;
dlg.m_audioInputDevice = m_audioInputDevice;
dlg.m_audioOutputDevice = m_audioOutputDevice;
dlg.m_audioInputChannel = m_audioInputChannel;
dlg.m_audioOutputChannel = m_audioOutputChannel;
dlg.m_pskReporter=m_pskReporter;
dlg.m_After73=m_After73;
dlg.m_macro=m_macro;
@ -761,6 +778,8 @@ void MainWindow::on_actionDeviceSetup_triggered() //Setup Dialog
m_saveDir=dlg.m_saveDir;
m_audioInputDevice = dlg.m_audioInputDevice;
m_audioOutputDevice = dlg.m_audioOutputDevice;
m_audioInputChannel = dlg.m_audioInputChannel;
m_audioOutputChannel = dlg.m_audioOutputChannel;
m_macro=dlg.m_macro;
m_dFreq=dlg.m_dFreq;
m_antDescription=dlg.m_antDescription;
@ -796,7 +815,10 @@ void MainWindow::on_actionDeviceSetup_triggered() //Setup Dialog
m_After73=dlg.m_After73;
if(dlg.m_restartSoundIn) {
m_soundInput.start(m_audioInputDevice, RX_SAMPLE_RATE / 10, &m_detector);
m_soundInput.stop ();
m_detector.close ();
m_detector.open (m_audioInputChannel);
m_soundInput.start(m_audioInputDevice, AudioDevice::Mono == m_audioInputChannel ? 1 : 2, RX_SAMPLE_RATE / 10, &m_detector);
}
if(dlg.m_restartSoundOut) {
@ -832,7 +854,7 @@ void MainWindow::on_monitorButton_clicked() //Monitor
{
m_monitoring=true;
m_detector.setMonitoring(true);
m_soundInput.start(m_audioInputDevice, RX_SAMPLE_RATE / 10, &m_detector);
// m_soundInput.start(m_audioInputDevice, AudioDevice::Mono == m_audioInputChannel ? 1 : 2, RX_SAMPLE_RATE / 10, &m_detector);
m_diskData=false;
}
@ -963,13 +985,13 @@ void MainWindow::bumpFqso(int n) //bumpFqso()
int i;
bool ctrl = (n>=100);
n=n%100;
i=g_pWideGraph->rxFreq();
i=m_wideGraph->rxFreq();
if(n==11) i--;
if(n==12) i++;
g_pWideGraph->setRxFreq(i);
m_wideGraph->setRxFreq(i);
if(ctrl) {
ui->TxFreqSpinBox->setValue(i);
g_pWideGraph->setTxFreq(i);
m_wideGraph->setTxFreq(i);
}
}
@ -992,7 +1014,7 @@ void MainWindow::dialFreqChanged2(double f)
}
ui->labDialFreq->setText(t);
statusChanged();
if(g_pWideGraph!=NULL) g_pWideGraph->setDialFreq(m_dialFreq);
m_wideGraph->setDialFreq(m_dialFreq);
}
void MainWindow::statusChanged()
@ -1047,16 +1069,16 @@ void MainWindow::on_actionExit_triggered() //Exit()
OnExit();
}
void MainWindow::closeEvent(QCloseEvent*)
void MainWindow::closeEvent(QCloseEvent * e)
{
writeSettings ();
OnExit();
QMainWindow::closeEvent (e);
}
void MainWindow::OnExit()
{
m_guiTimer.stop ();
g_pWideGraph->saveSettings();
writeSettings();
if(m_fname != "") killFile();
m_killAll=true;
mem_jt9->detach();
@ -1076,7 +1098,6 @@ void MainWindow::on_stopButton_clicked() //stopButton
{
m_monitoring=false;
m_detector.setMonitoring(m_monitoring);
m_soundInput.stop ();
m_loopall=false;
}
@ -1095,24 +1116,7 @@ void MainWindow::on_actionOnline_Users_Guide_triggered() //Display manual
void MainWindow::on_actionWide_Waterfall_triggered() //Display Waterfalls
{
if(g_pWideGraph==NULL) {
g_pWideGraph = new WideGraph(0);
g_pWideGraph->setWindowTitle("Wide Graph");
g_pWideGraph->setGeometry(m_wideGraphGeom);
Qt::WindowFlags flags = Qt::WindowCloseButtonHint |
Qt::WindowMinimizeButtonHint;
g_pWideGraph->setWindowFlags(flags);
connect(g_pWideGraph, SIGNAL(freezeDecode2(int)),this,
SLOT(freezeDecode(int)));
connect(g_pWideGraph, SIGNAL(f11f12(int)),this,
SLOT(bumpFqso(int)));
connect(g_pWideGraph, SIGNAL(setXIT2(int)),this,
SLOT(setXIT(int)));
// connect(g_pWideGraph, SIGNAL(dialFreqChanged(double)),this,
// SLOT(dialFreqChanged2(double)));
connect (this, &MainWindow::finished, g_pWideGraph, &WideGraph::close);
}
g_pWideGraph->show();
m_wideGraph->show();
}
void MainWindow::on_actionOpen_triggered() //Open File
@ -1295,10 +1299,10 @@ void MainWindow::on_DecodeButton_clicked() //Decode request
void MainWindow::freezeDecode(int n) //freezeDecode()
{
bool ctrl = (n>=100);
int i=g_pWideGraph->rxFreq();
int i=m_wideGraph->rxFreq();
if(ctrl) {
ui->TxFreqSpinBox->setValue(i);
g_pWideGraph->setTxFreq(i);
m_wideGraph->setTxFreq(i);
}
if((n%100)==2) on_DecodeButton_clicked();
}
@ -1316,13 +1320,13 @@ void MainWindow::decode() //decode()
jt9com_.nutc=100*ihr + imin;
}
jt9com_.nfqso=g_pWideGraph->rxFreq();
jt9com_.nfqso=m_wideGraph->rxFreq();
jt9com_.ndepth=m_ndepth;
jt9com_.ndiskdat=0;
if(m_diskData) jt9com_.ndiskdat=1;
jt9com_.nfa=g_pWideGraph->nStartFreq();
jt9com_.nfSplit=g_pWideGraph->getFmin();
jt9com_.nfb=g_pWideGraph->getFmax();
jt9com_.nfa=m_wideGraph->nStartFreq();
jt9com_.nfSplit=m_wideGraph->getFmin();
jt9com_.nfb=m_wideGraph->getFmax();
jt9com_.ntol=20;
if(jt9com_.nutc < m_nutc0) m_RxLog |= 1; //Date and Time to all.txt
m_nutc0=jt9com_.nutc;
@ -1420,7 +1424,7 @@ void MainWindow::readFromStdout() //readFromStdout
QString bg="white";
if(t.indexOf(" CQ ")>0) bg="#66ff66"; //green
if(m_myCall!="" and t.indexOf(" "+m_myCall+" ")>0) bg="#ff6666"; //red
bool bQSO=abs(t.mid(14,4).toInt() - g_pWideGraph->rxFreq()) <= 10;
bool bQSO=abs(t.mid(14,4).toInt() - m_wideGraph->rxFreq()) <= 10;
QString t1=t.replace("\n","").mid(0,t.length()-4);
// if enabled add the DXCC entity and B4 status to the end of the preformated text line t1
@ -1752,7 +1756,6 @@ void MainWindow::guiUpdate()
signalMeter->setValue(0);
m_monitoring=false;
m_detector.setMonitoring(false);
m_soundInput.stop ();
m_btxok=true;
Q_EMIT muteAudioOutput (false);
m_transmitting=true;
@ -1881,7 +1884,6 @@ void MainWindow::startTx2()
signalMeter->setValue(0);
m_monitoring=false;
m_detector.setMonitoring(false);
m_soundInput.stop ();
m_btxok=true;
Q_EMIT muteAudioOutput (false);
m_transmitting=true;
@ -1900,7 +1902,6 @@ void MainWindow::stopTx()
lab1->setText("");
ptt0Timer->start(200); //Sequencer delay
m_monitoring=true;
m_soundInput.start(m_audioInputDevice, RX_SAMPLE_RATE / 10, &m_detector);
m_detector.setMonitoring(true);
}
@ -2046,7 +2047,7 @@ void MainWindow::doubleClickOnCall(bool shift, bool ctrl)
int nfreq=t4.at(3).toInt();
if(t4.at(1)=="Tx") nfreq=t4.at(2).toInt();
g_pWideGraph->setRxFreq(nfreq); //Set Rx freq
m_wideGraph->setRxFreq(nfreq); //Set Rx freq
if(t4.at(1)=="Tx") {
if(ctrl) ui->TxFreqSpinBox->setValue(nfreq); //Set Tx freq
return;
@ -2054,12 +2055,12 @@ void MainWindow::doubleClickOnCall(bool shift, bool ctrl)
if(t4.at(4)=="@") {
m_modeTx="JT9";
ui->pbTxMode->setText("Tx JT9 @");
g_pWideGraph->setModeTx(m_modeTx);
m_wideGraph->setModeTx(m_modeTx);
}
if(t4.at(4)=="#") {
m_modeTx="JT65";
ui->pbTxMode->setText("Tx JT65 #");
g_pWideGraph->setModeTx(m_modeTx);
m_wideGraph->setModeTx(m_modeTx);
}
QString firstcall=t4.at(5);
// Don't change Tx freq if a station is calling me, unless m_lockTxFreq
@ -2470,27 +2471,14 @@ void MainWindow::on_logQSOButton_clicked() //Log QSO button
if(m_hisCall=="") return;
m_dateTimeQSO=QDateTime::currentDateTimeUtc();
logDlg = new LogQSO(0);
logDlg->m_saveTxPower=m_saveTxPower;
logDlg->m_saveComments=m_saveComments;
logDlg->m_txPower=m_txPower;
logDlg->m_comments=m_logComments;
logDlg->initLogQSO(m_hisCall,m_hisGrid,m_modeTx,m_rptSent,m_rptRcvd,
m_logDlg->initLogQSO(m_hisCall,m_hisGrid,m_modeTx,m_rptSent,m_rptRcvd,
m_dateTimeQSO,m_dialFreq+m_txFreq/1.0e6,
m_myCall,m_myGrid,m_noSuffix,m_toRTTY,m_dBtoComments);
connect(logDlg, SIGNAL(acceptQSO(bool)),this,SLOT(acceptQSO2(bool)));
if(m_logQSOgeom != QRect(500,400,424,283)) logDlg->setGeometry(m_logQSOgeom);
logDlg->show();
}
void MainWindow::acceptQSO2(bool accepted)
{
if(accepted) {
m_logQSOgeom=logDlg->geometry();
m_saveTxPower=logDlg->m_saveTxPower;
m_saveComments=logDlg->m_saveComments;
m_txPower=logDlg->m_txPower;
m_logComments=logDlg->m_comments;
m_logBook.addAsWorked(m_hisCall);
if(m_clearCallGrid) {
m_hisCall="";
@ -2516,9 +2504,9 @@ void MainWindow::on_actionJT9_1_triggered()
lab2->setStyleSheet("QLabel{background-color: #ff6ec7}");
lab2->setText(m_mode);
ui->actionJT9_1->setChecked(true);
g_pWideGraph->setPeriod(m_TRperiod,m_nsps);
g_pWideGraph->setMode(m_mode);
g_pWideGraph->setModeTx(m_modeTx);
m_wideGraph->setPeriod(m_TRperiod,m_nsps);
m_wideGraph->setMode(m_mode);
m_wideGraph->setModeTx(m_modeTx);
ui->pbTxMode->setEnabled(false);
}
@ -2533,9 +2521,9 @@ void MainWindow::on_actionJT65_triggered()
lab2->setStyleSheet("QLabel{background-color: #ffff00}");
lab2->setText(m_mode);
ui->actionJT65->setChecked(true);
g_pWideGraph->setPeriod(m_TRperiod,m_nsps);
g_pWideGraph->setMode(m_mode);
g_pWideGraph->setModeTx(m_modeTx);
m_wideGraph->setPeriod(m_TRperiod,m_nsps);
m_wideGraph->setMode(m_mode);
m_wideGraph->setModeTx(m_modeTx);
ui->pbTxMode->setEnabled(false);
}
@ -2550,16 +2538,16 @@ void MainWindow::on_actionJT9_JT65_triggered()
lab2->setStyleSheet("QLabel{background-color: #ffa500}");
lab2->setText(m_mode);
ui->actionJT9_JT65->setChecked(true);
g_pWideGraph->setPeriod(m_TRperiod,m_nsps);
g_pWideGraph->setMode(m_mode);
g_pWideGraph->setModeTx(m_modeTx);
m_wideGraph->setPeriod(m_TRperiod,m_nsps);
m_wideGraph->setMode(m_mode);
m_wideGraph->setModeTx(m_modeTx);
ui->pbTxMode->setEnabled(true);
}
void MainWindow::on_TxFreqSpinBox_valueChanged(int n)
{
m_txFreq=n;
if(g_pWideGraph!=NULL) g_pWideGraph->setTxFreq(n);
m_wideGraph->setTxFreq(n);
if(m_lockTxFreq) ui->RxFreqSpinBox->setValue(n);
Q_EMIT transmitFrequency (m_txFreq - (m_bSplit || m_bXIT ? m_XIT : 0));
}
@ -2567,7 +2555,7 @@ void MainWindow::on_TxFreqSpinBox_valueChanged(int n)
void MainWindow::on_RxFreqSpinBox_valueChanged(int n)
{
m_rxFreq=n;
if(g_pWideGraph!=NULL) g_pWideGraph->setRxFreq(n);
m_wideGraph->setRxFreq(n);
if(m_lockTxFreq) ui->TxFreqSpinBox->setValue(n);
}
@ -2719,10 +2707,9 @@ void MainWindow::on_bandComboBox_activated(int index)
ret=rig->setFreq(MHz(m_dialFreq));
if(m_bSplit or m_bXIT) setXIT(m_txFreq);
if(g_pWideGraph!=NULL) {
bumpFqso(11);
bumpFqso(12);
}
bumpFqso(11);
bumpFqso(12);
if(ret!=RIG_OK) {
rt.sprintf("Set rig frequency failed: %d",ret);
msgBox(rt);
@ -2973,13 +2960,13 @@ void MainWindow::on_actionAllow_multiple_instances_triggered(bool checked)
void MainWindow::on_pbR2T_clicked()
{
int n=g_pWideGraph->rxFreq();
int n=m_wideGraph->rxFreq();
ui->TxFreqSpinBox->setValue(n);
}
void MainWindow::on_pbT2R_clicked()
{
g_pWideGraph->setRxFreq(m_txFreq);
m_wideGraph->setRxFreq(m_txFreq);
}
@ -3009,7 +2996,7 @@ void MainWindow::on_pbTxMode_clicked()
m_modeTx="JT9";
ui->pbTxMode->setText("Tx JT9 @");
}
g_pWideGraph->setModeTx(m_modeTx);
m_wideGraph->setModeTx(m_modeTx);
statusChanged();
}
@ -3045,7 +3032,7 @@ void MainWindow::setFreq4(int rxFreq, int txFreq)
void MainWindow::on_cbTxLock_clicked(bool checked)
{
m_lockTxFreq=checked;
g_pWideGraph->setLockTxFreq(m_lockTxFreq);
m_wideGraph->setLockTxFreq(m_lockTxFreq);
if(m_lockTxFreq) on_pbR2T_clicked();
}
@ -3089,11 +3076,18 @@ void MainWindow::transmit (double snr)
{
if (m_modeTx == "JT65")
{
Q_EMIT sendMessage (NUM_JT65_SYMBOLS, 4096.0 * 12000.0 / 11025.0, m_txFreq - (m_bSplit || m_bXIT ? m_XIT : 0), true, snr);
Q_EMIT sendMessage (NUM_JT65_SYMBOLS, 4096.0 * 12000.0 / 11025.0, m_txFreq - (m_bSplit || m_bXIT ? m_XIT : 0), m_audioOutputChannel, true, snr);
}
else
{
Q_EMIT sendMessage (NUM_JT9_SYMBOLS, m_nsps, m_txFreq - (m_bSplit || m_bXIT ? m_XIT : 0), true, snr);
Q_EMIT sendMessage (NUM_JT9_SYMBOLS, m_nsps, m_txFreq - (m_bSplit || m_bXIT ? m_XIT : 0), m_audioOutputChannel, true, snr);
}
Q_EMIT startAudioOutputStream (m_audioOutputDevice);
Q_EMIT startAudioOutputStream (m_audioOutputDevice, AudioDevice::Mono == m_audioOutputChannel ? 1 : 2);
}
void MainWindow::on_outAttenuation_valueChanged (int a)
{
qreal dBAttn (a / 10.); // slider interpreted as hundredths of a dB
ui->outAttenuation->setToolTip (tr ("Transmit digital gain ") + (a ? QString::number (-dBAttn, 'f', 1) : "0") + "dB");
Q_EMIT outAttenuationChanged (dBAttn);
}

View File

@ -10,6 +10,7 @@
#include <QDateTime>
#include <QList>
#include <QAudioDeviceInfo>
#include <QScopedPointer>
#include "soundin.h"
#include "soundout.h"
@ -39,13 +40,17 @@ namespace Ui {
class MainWindow;
}
class QSettings;
class WideGraph;
class LogQSO;
class MainWindow : public QMainWindow
{
Q_OBJECT
// Multiple instances: call MainWindow() with *thekey
public:
explicit MainWindow(QSharedMemory *shdmem, QString *thekey, \
explicit MainWindow(QSettings *, QSharedMemory *shdmem, QString *thekey, \
qint32 fontSize2, qint32 fontWeight2, \
QWidget *parent = 0);
~MainWindow();
@ -54,7 +59,7 @@ public slots:
void showSoundInError(const QString& errorMsg);
void showSoundOutError(const QString& errorMsg);
void showStatusMessage(const QString& statusMsg);
void dataSink(qint64 bytes);
void dataSink(qint64 frames);
void diskDat();
void diskWriteFinished();
void freezeDecode(int n);
@ -175,20 +180,27 @@ private slots:
void on_cbTxLock_clicked(bool checked);
void on_actionTx2QSO_triggered(bool checked);
void on_cbPlus2kHz_toggled(bool checked);
void on_outAttenuation_valueChanged (int);
private:
Q_SIGNAL void startAudioOutputStream (QAudioDeviceInfo);
Q_SIGNAL void startAudioOutputStream (QAudioDeviceInfo, unsigned channels);
Q_SIGNAL void stopAudioOutputStream ();
Q_SIGNAL void finished ();
Q_SIGNAL void muteAudioOutput (bool = true);
Q_SIGNAL void transmitFrequency (unsigned);
Q_SIGNAL void endTransmitMessage ();
Q_SIGNAL void tune (bool = true);
Q_SIGNAL void sendMessage (unsigned symbolsLength, double framesPerSymbol, unsigned frequency, bool synchronize = true, double dBSNR = 99.);
Q_SIGNAL void sendMessage (unsigned symbolsLength, double framesPerSymbol, unsigned frequency, AudioDevice::Channel, bool synchronize = true, double dBSNR = 99.);
Q_SIGNAL void outAttenuationChanged (qreal);
private:
QSettings * m_settings;
Ui::MainWindow *ui;
// other windows
QScopedPointer<WideGraph> m_wideGraph;
QScopedPointer<LogQSO> m_logDlg;
double m_dialFreq;
qint64 m_msErase;
@ -213,10 +225,12 @@ private:
Detector m_detector;
QAudioDeviceInfo m_audioInputDevice;
AudioDevice::Channel m_audioInputChannel;
SoundInput m_soundInput;
Modulator m_modulator;
QAudioDeviceInfo m_audioOutputDevice;
AudioDevice::Channel m_audioOutputChannel;
SoundOutput m_soundOutput;
QThread m_soundOutputThread;
@ -242,7 +256,6 @@ private:
qint32 m_repeatMsg;
qint32 m_watchdogLimit;
qint32 m_poll;
qint32 m_fMin;
qint32 m_fMax;
qint32 m_bad;
@ -292,8 +305,6 @@ private:
bool m_pttData;
bool m_dontReadFreq;
bool m_lockTxFreq;
bool m_saveTxPower;
bool m_saveComments;
bool m_tx2QSO;
bool m_CATerror;
bool m_bSplit;
@ -304,9 +315,6 @@ private:
float m_pctZap;
QRect m_wideGraphGeom;
QRect m_logQSOgeom;
QLabel* lab1; // labels in status bar
QLabel* lab2;
QLabel* lab3;
@ -361,8 +369,6 @@ private:
QString m_msgSent0;
QString m_fileToSave;
QString m_QSOmsg;
QString m_txPower;
QString m_logComments;
QStringList m_macro;
QStringList m_dFreq; // per band frequency in MHz as a string

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>760</width>
<height>552</height>
<height>523</height>
</rect>
</property>
<property name="sizePolicy">
@ -1148,6 +1148,19 @@ p, li { white-space: pre-wrap; }
</item>
</layout>
</item>
<item row="1" column="6">
<widget class="QPushButton" name="pbTxMode">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Toggle Tx mode</string>
</property>
<property name="text">
<string>Tx JT9</string>
</property>
</widget>
</item>
<item row="5" column="3" rowspan="2" colspan="2">
<widget class="QLabel" name="labUTC">
<property name="sizePolicy">
@ -1193,6 +1206,16 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QCheckBox" name="cbPlus2kHz">
<property name="toolTip">
<string>Add 2 kHz to requested dial frequency</string>
</property>
<property name="text">
<string>+2 kHz</string>
</property>
</widget>
</item>
<item row="0" column="8" rowspan="7">
<widget class="QFrame" name="frame_2">
<property name="sizePolicy">
@ -2062,16 +2085,19 @@ p, li { white-space: pre-wrap; }
</item>
</layout>
</item>
<item row="1" column="6">
<widget class="QPushButton" name="pbTxMode">
<property name="enabled">
<bool>false</bool>
<item row="1" column="2">
<widget class="QPushButton" name="readFreq">
<property name="maximumSize">
<size>
<width>15</width>
<height>15</height>
</size>
</property>
<property name="toolTip">
<string>Toggle Tx mode</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;If orange, click to read dial frequency&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Tx JT9</string>
<string/>
</property>
</widget>
</item>
@ -2091,32 +2117,6 @@ p, li { white-space: pre-wrap; }
</property>
</spacer>
</item>
<item row="1" column="0" colspan="2">
<widget class="QCheckBox" name="cbPlus2kHz">
<property name="toolTip">
<string>Add 2 kHz to requested dial frequency</string>
</property>
<property name="text">
<string>+2 kHz</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="readFreq">
<property name="maximumSize">
<size>
<width>15</width>
<height>15</height>
</size>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;If orange, click to read dial frequency&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="0" colspan="3">
<widget class="QComboBox" name="bandComboBox">
<property name="sizePolicy">
@ -2225,6 +2225,35 @@ p, li { white-space: pre-wrap; }
</item>
</widget>
</item>
<item row="0" column="9">
<widget class="QLabel" name="label">
<property name="text">
<string>Pwr</string>
</property>
</widget>
</item>
<item row="1" column="9" rowspan="6">
<widget class="QSlider" name="outAttenuation">
<property name="value">
<number>0</number>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="invertedAppearance">
<bool>true</bool>
</property>
<property name="invertedControls">
<bool>true</bool>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
<property name="tickInterval">
<number>0</number>
</property>
</widget>
</item>
</layout>
</item>
</layout>
@ -2235,7 +2264,7 @@ p, li { white-space: pre-wrap; }
<x>0</x>
<y>0</y>
<width>760</width>
<height>20</height>
<height>25</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">

View File

@ -38,12 +38,15 @@ bool SoundInput::audioError () const
return result;
}
bool SoundInput::start(QAudioDeviceInfo const& device, int framesPerBuffer, QIODevice * sink)
bool SoundInput::start(QAudioDeviceInfo const& device, unsigned channels, int framesPerBuffer, QIODevice * sink)
{
Q_ASSERT (0 < channels && channels < 3);
Q_ASSERT (sink);
stop();
QAudioFormat format (device.preferredFormat());
format.setChannelCount (1);
format.setChannelCount (channels);
format.setCodec ("audio/pcm");
format.setSampleRate (12000);
format.setSampleType (QAudioFormat::SignedInt);

View File

@ -32,7 +32,7 @@ Q_SIGNALS:
public Q_SLOTS:
// sink must exist from the start call to any following stop () call
bool start(QAudioDeviceInfo const&, int framesPerBuffer, QIODevice * sink);
bool start(QAudioDeviceInfo const&, unsigned channels, int framesPerBuffer, QIODevice * sink);
void stop();
private:

View File

@ -3,6 +3,7 @@
#include <QDateTime>
#include <QAudioDeviceInfo>
#include <QAudioOutput>
#include <qmath.h>
#include <QDebug>
#if defined (WIN32)
@ -52,18 +53,15 @@ SoundOutput::SoundOutput (QIODevice * source)
Q_ASSERT (source);
}
void SoundOutput::startStream (QAudioDeviceInfo const& device)
void SoundOutput::startStream (QAudioDeviceInfo const& device, unsigned channels)
{
if (!m_stream || device != m_currentDevice)
Q_ASSERT (0 < channels && channels < 3);
if (!m_stream || device != m_currentDevice || channels != static_cast<unsigned> (m_stream->format ().channelCount ()))
{
QAudioFormat format (device.preferredFormat ());
#ifdef UNIX
format.setChannelCount (2);
#else
format.setChannelCount (1);
#endif
format.setChannelCount (channels);
format.setCodec ("audio/pcm");
format.setSampleRate (48000);
format.setSampleType (QAudioFormat::SignedInt);
@ -79,6 +77,7 @@ void SoundOutput::startStream (QAudioDeviceInfo const& device)
m_stream.reset (new QAudioOutput (device, format, this));
audioError ();
m_stream->setVolume (m_volume);
connect (m_stream.data(), &QAudioOutput::stateChanged, this, &SoundOutput::handleStateChanged);
@ -86,13 +85,13 @@ void SoundOutput::startStream (QAudioDeviceInfo const& device)
}
//
// This buffer size is critical since we are running in the GUI
// thread. If it is too short; high activity levels on the GUI can
// starve the audio buffer. On the other hand the Windows
// implementation seems to take the length of the buffer in time to
// stop the audio stream even if reset() is used.
// This buffer size is critical since for proper sound streaming. If
// it is too short; high activity levels on the machine can starve
// the audio buffer. On the other hand the Windows implementation
// seems to take the length of the buffer in time to stop the audio
// stream even if reset() is used.
//
// 1 seconds seems a reasonable compromise except for Windows
// 2 seconds seems a reasonable compromise except for Windows
// where things are probably broken.
//
// we have to set this before every start on the stream because the
@ -121,6 +120,31 @@ void SoundOutput::resume ()
}
}
qreal SoundOutput::attenuation () const
{
return -(10. * qLn (m_volume) / qLn (10.));
}
void SoundOutput::setAttenuation (qreal a)
{
Q_ASSERT (0. <= a && a <= 99.);
m_volume = qPow (10., -a / 10.);
qDebug () << "SoundOut: attn = " << a << ", vol = " << m_volume;
if (m_stream)
{
m_stream->setVolume (m_volume);
}
}
void SoundOutput::resetAttenuation ()
{
m_volume = 1.;
if (m_stream)
{
m_stream->setVolume (m_volume);
}
}
void SoundOutput::stopStream ()
{
if (m_stream)

View File

@ -17,6 +17,7 @@ class SoundOutput : public QObject
Q_OBJECT;
Q_PROPERTY(bool running READ isRunning);
Q_PROPERTY(unsigned attenuation READ attenuation WRITE setAttenuation RESET resetAttenuation);
private:
Q_DISABLE_COPY (SoundOutput);
@ -26,12 +27,18 @@ class SoundOutput : public QObject
~SoundOutput ();
bool isRunning() const {return m_active;}
qreal attenuation () const;
public Q_SLOTS:
void startStream (QAudioDeviceInfo const& device);
private Q_SLOTS:
/* private because we expect to run in a thread and don't want direct
C++ calls made, instead they must be invoked via the Qt
signal/slot mechanism which is thread safe */
void startStream (QAudioDeviceInfo const& device, unsigned channels);
void suspend ();
void resume ();
void stopStream ();
void setAttenuation (qreal); /* unsigned */
void resetAttenuation (); /* to zero */
Q_SIGNALS:
void error (QString message) const;
@ -49,6 +56,7 @@ private:
QIODevice * m_source;
bool volatile m_active;
QAudioDeviceInfo m_currentDevice;
qreal m_volume;
};
#endif

View File

@ -4,16 +4,20 @@
#define MAX_SCREENSIZE 2048
WideGraph::WideGraph(QWidget *parent) :
WideGraph::WideGraph(QSettings * settings, QWidget *parent) :
QDialog(parent),
ui(new Ui::WideGraph)
ui(new Ui::WideGraph),
m_settings (settings)
{
installEventFilter (parent);
setWindowTitle ("Wide Graph");
setWindowFlags (Qt::WindowCloseButtonHint | Qt::WindowMinimizeButtonHint);
setMaximumWidth (MAX_SCREENSIZE);
setMaximumHeight (880);
ui->setupUi(this);
this->setWindowFlags(Qt::Dialog);
this->installEventFilter(parent); //Installing the filter
ui->widePlot->setCursor(Qt::CrossCursor);
this->setMaximumWidth(MAX_SCREENSIZE);
this->setMaximumHeight(880);
ui->widePlot->setMaximumHeight(800);
ui->widePlot->m_bCurrent=false;
@ -23,38 +27,35 @@ WideGraph::WideGraph(QWidget *parent) :
connect(ui->widePlot, SIGNAL(setFreq1(int,int)),this,
SLOT(setFreq2(int,int)));
m_fMin=3000;
ui->fMinSpinBox->setValue(m_fMin);
//Restore user's settings
QString inifile(QApplication::applicationDirPath());
inifile += "/wsjtx.ini";
QSettings settings(inifile, QSettings::IniFormat);
settings.beginGroup("WideGraph");
ui->widePlot->setPlotZero(settings.value("PlotZero", 0).toInt());
ui->widePlot->setPlotGain(settings.value("PlotGain", 0).toInt());
m_settings->beginGroup("WideGraph");
restoreGeometry (m_settings->value ("geometry", saveGeometry ()).toByteArray ());
ui->widePlot->setPlotZero(m_settings->value("PlotZero", 0).toInt());
ui->widePlot->setPlotGain(m_settings->value("PlotGain", 0).toInt());
ui->zeroSpinBox->setValue(ui->widePlot->getPlotZero());
ui->gainSpinBox->setValue(ui->widePlot->getPlotGain());
int n = settings.value("FreqSpan",2).toInt();
int w = settings.value("PlotWidth",1000).toInt();
int n = m_settings->value("FreqSpan",2).toInt();
int w = m_settings->value("PlotWidth",1000).toInt();
ui->widePlot->m_w=w;
ui->freqSpanSpinBox->setValue(n);
ui->widePlot->setNSpan(n);
m_waterfallAvg = settings.value("WaterfallAvg",5).toInt();
m_waterfallAvg = m_settings->value("WaterfallAvg",5).toInt();
ui->waterfallAvgSpinBox->setValue(m_waterfallAvg);
ui->widePlot->m_bCurrent=settings.value("Current",false).toBool();
ui->widePlot->m_bCumulative=settings.value("Cumulative",true).toBool();
ui->widePlot->m_bCurrent=m_settings->value("Current",false).toBool();
ui->widePlot->m_bCumulative=m_settings->value("Cumulative",true).toBool();
if(ui->widePlot->m_bCurrent) ui->spec2dComboBox->setCurrentIndex(0);
if(ui->widePlot->m_bCumulative) ui->spec2dComboBox->setCurrentIndex(1);
int nbpp=settings.value("BinsPerPixel",2).toInt();
int nbpp=m_settings->value("BinsPerPixel",2).toInt();
ui->widePlot->setBinsPerPixel(nbpp);
m_slope=settings.value("Slope",0.0).toDouble();
m_slope=m_settings->value("Slope",0.0).toDouble();
ui->slopeSpinBox->setValue(m_slope);
ui->widePlot->setStartFreq(settings.value("StartFreq",0).toInt());
ui->widePlot->setStartFreq(m_settings->value("StartFreq",0).toInt());
ui->fStartSpinBox->setValue(ui->widePlot->startFreq());
m_waterfallPalette=settings.value("WaterfallPalette","Default").toString();
settings.endGroup();
m_waterfallPalette=m_settings->value("WaterfallPalette","Default").toString();
int m_fMin = m_settings->value ("fMin", 2500).toInt ();
ui->fMinSpinBox->setValue (m_fMin);
setRxRange (m_fMin);
m_settings->endGroup();
QDir recoredDir("Palettes");
QStringList allFiles = recoredDir.entryList(QDir::NoDotAndDotDot |
@ -73,32 +74,33 @@ WideGraph::WideGraph(QWidget *parent) :
readPalette("Palettes/" + m_waterfallPalette + ".pal");
}
WideGraph::~WideGraph()
WideGraph::~WideGraph ()
{
saveSettings();
delete ui;
}
void WideGraph::closeEvent (QCloseEvent * e)
{
saveSettings ();
QDialog::closeEvent (e);
}
void WideGraph::saveSettings()
{
//Save user's settings
QString inifile(QApplication::applicationDirPath());
inifile += "/wsjtx.ini";
QSettings settings(inifile, QSettings::IniFormat);
settings.beginGroup("WideGraph");
settings.setValue("PlotZero",ui->widePlot->m_plotZero);
settings.setValue("PlotGain",ui->widePlot->m_plotGain);
settings.setValue("PlotWidth",ui->widePlot->plotWidth());
settings.setValue("FreqSpan",ui->freqSpanSpinBox->value());
settings.setValue("WaterfallAvg",ui->waterfallAvgSpinBox->value());
settings.setValue("Current",ui->widePlot->m_bCurrent);
settings.setValue("Cumulative",ui->widePlot->m_bCumulative);
settings.setValue("BinsPerPixel",ui->widePlot->binsPerPixel());
settings.setValue("Slope",m_slope);
settings.setValue("StartFreq",ui->widePlot->startFreq());
settings.setValue("WaterfallPalette",m_waterfallPalette);
settings.endGroup();
m_settings->beginGroup ("WideGraph");
m_settings->setValue ("geometry", saveGeometry ());
m_settings->setValue ("PlotZero", ui->widePlot->m_plotZero);
m_settings->setValue ("PlotGain", ui->widePlot->m_plotGain);
m_settings->setValue ("PlotWidth", ui->widePlot->plotWidth ());
m_settings->setValue ("FreqSpan", ui->freqSpanSpinBox->value ());
m_settings->setValue ("WaterfallAvg", ui->waterfallAvgSpinBox->value ());
m_settings->setValue ("Current", ui->widePlot->m_bCurrent);
m_settings->setValue ("Cumulative", ui->widePlot->m_bCumulative);
m_settings->setValue ("BinsPerPixel", ui->widePlot->binsPerPixel ());
m_settings->setValue ("Slope", m_slope);
m_settings->setValue ("StartFreq", ui->widePlot->startFreq ());
m_settings->setValue ("WaterfallPalette", m_waterfallPalette);
m_settings->setValue ("Fmin", m_fMin);
m_settings->endGroup ();
}
void WideGraph::dataSink2(float s[], float df3, int ihsym,
@ -238,13 +240,6 @@ int WideGraph::getFmax()
return n;
}
void WideGraph::setFmin(int n)
{
m_fMin = n;
ui->fMinSpinBox->setValue(n);
setRxRange(m_fMin);
}
double WideGraph::fGreen()
{
return ui->widePlot->fGreen();

View File

@ -1,18 +1,22 @@
#ifndef WIDEGRAPH_H
#define WIDEGRAPH_H
#include <QDialog>
#include <QScopedPointer>
namespace Ui {
class WideGraph;
}
class QSettings;
class WideGraph : public QDialog
{
Q_OBJECT
public:
explicit WideGraph(QWidget *parent = 0);
~WideGraph();
explicit WideGraph(QSettings *, QWidget *parent = 0);
~WideGraph ();
void dataSink2(float s[], float df3, int ihsym, int ndiskdata);
void setRxFreq(int n);
@ -24,7 +28,6 @@ public:
float fSpan();
void saveSettings();
void setRxRange(int fMin);
void setFmin(int n);
void setFsample(int n);
void setPeriod(int ntrperiod, int nsps);
void setTxFreq(int n);
@ -36,9 +39,6 @@ public:
double fGreen();
void readPalette(QString fileName);
qint32 m_rxFreq;
qint32 m_txFreq;
signals:
void freezeDecode2(int n);
void f11f12(int n);
@ -52,6 +52,7 @@ public slots:
protected:
virtual void keyPressEvent( QKeyEvent *e );
void closeEvent (QCloseEvent *);
private slots:
void on_waterfallAvgSpinBox_valueChanged(int arg1);
@ -65,6 +66,12 @@ private slots:
void on_paletteComboBox_activated(const QString &palette);
private:
QScopedPointer<Ui::WideGraph> ui;
QSettings * m_settings;
qint32 m_rxFreq;
qint32 m_txFreq;
double m_slope;
double m_dialFreq;
@ -81,8 +88,6 @@ private:
QString m_mode;
QString m_modeTx;
QString m_waterfallPalette;
Ui::WideGraph *ui;
};
#endif // WIDEGRAPH_H

View File

@ -67,7 +67,7 @@ SOURCES += killbyname.cpp
HEADERS += mainwindow.h plotter.h soundin.h soundout.h \
about.h devsetup.h widegraph.h getfile.h \
commons.h sleep.h displaytext.h logqso.h \
Detector.hpp Modulator.hpp psk_reporter.h rigclass.h \
AudioDevice.hpp Detector.hpp Modulator.hpp psk_reporter.h rigclass.h \
signalmeter.h \
meterwidget.h \
logbook/logbook.h \