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" #include "commons.h"
Detector::Detector (unsigned frameRate, unsigned periodLengthInSeconds, unsigned bytesPerSignal, QObject * parent) Detector::Detector (unsigned frameRate, unsigned periodLengthInSeconds, unsigned framesPerSignal, QObject * parent)
: QIODevice (parent) : AudioDevice (parent)
, m_frameRate (frameRate) , m_frameRate (frameRate)
, m_period (periodLengthInSeconds) , m_period (periodLengthInSeconds)
, m_bytesPerSignal (bytesPerSignal) , m_framesPerSignal (framesPerSignal)
, m_monitoring (false) , m_monitoring (false)
, m_starting (false) , m_starting (false)
{ {
@ -37,28 +37,25 @@ void Detector::clear ()
qint64 Detector::writeData (char const * data, qint64 maxSize) qint64 Detector::writeData (char const * data, qint64 maxSize)
{ {
Q_ASSERT (!(maxSize % static_cast<qint64> (sizeof (frame_t)))); // no torn frames Q_ASSERT (!(maxSize % static_cast<qint64> (bytesPerFrame ()))); // 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));
qint64 framesAcceptable (sizeof (jt9com_.d2) / sizeof (jt9com_.d2[0]) - jt9com_.kin); 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!"; 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; jt9com_.kin += framesAccepted;
unsigned currentSignalIndex (jt9com_.kin * sizeof (jt9com_.d2[0]) / m_bytesPerSignal); unsigned currentSignalIndex (jt9com_.kin / m_framesPerSignal);
if (currentSignalIndex != lastSignalIndex && m_monitoring) if (currentSignalIndex != lastSignalIndex && m_monitoring)
{ {
Q_EMIT bytesWritten (currentSignalIndex * m_bytesPerSignal); Q_EMIT framesWritten (currentSignalIndex * m_framesPerSignal);
} }
if (!secondInPeriod ()) if (!secondInPeriod ())

View File

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

View File

@ -10,6 +10,15 @@
extern float gran(); // Noise generator (for tests only) 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; double const Modulator::m_twoPi = 2.0 * 3.141592653589793238462;
// float wpm=20.0; // 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 unsigned const Modulator::m_nspd = 2048 + 512; // 22.5 WPM
Modulator::Modulator (unsigned frameRate, unsigned periodLengthInSeconds, QObject * parent) Modulator::Modulator (unsigned frameRate, unsigned periodLengthInSeconds, QObject * parent)
: QIODevice (parent) : AudioDevice (parent)
, m_frameRate (frameRate) , m_frameRate (frameRate)
, m_period (periodLengthInSeconds) , m_period (periodLengthInSeconds)
, m_framesSent (0) , m_framesSent (0)
@ -30,11 +39,13 @@ Modulator::Modulator (unsigned frameRate, unsigned periodLengthInSeconds, QObjec
qsrand (QDateTime::currentMSecsSinceEpoch()); // Initialize random seed 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 // Time according to this computer which becomes our base time
qint64 ms0 = QDateTime::currentMSecsSinceEpoch() % 86400000; qint64 ms0 = QDateTime::currentMSecsSinceEpoch() % 86400000;
qDebug () << "Modulator: Using soft keying for CW is " << SOFT_KEYING;;
m_symbolsLength = symbolsLength; m_symbolsLength = symbolsLength;
m_framesSent = 0; 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"; // 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)); Q_EMIT stateChanged ((m_state = (synchronize && m_silentFrames) ? Synchronizing : Active));
} }
qint64 Modulator::readData (char * data, qint64 maxSize) qint64 Modulator::readData (char * data, qint64 maxSize)
{ {
Q_ASSERT (!(maxSize % static_cast<qint64> (sizeof (frame_t)))); // no torn frames Q_ASSERT (!(maxSize % static_cast<qint64> (bytesPerFrame ()))); // no torn frames
Q_ASSERT (!(reinterpret_cast<size_t> (data) % __alignof__ (frame_t))); // data is aligned as frame_t would be Q_ASSERT (isOpen ());
frame_t * frames (reinterpret_cast<frame_t *> (data)); qint64 numFrames (maxSize / bytesPerFrame ());
qint64 numFrames (maxSize / sizeof (frame_t)); 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; // 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 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); numFrames = qMin (m_silentFrames, numFrames);
qFill (frames, frames + numFrames, frame); for ( ; samples != end; samples = load (0, samples)) // silence
{
}
m_silentFrames -= numFrames; m_silentFrames -= numFrames;
return numFrames * sizeof (frame_t); return numFrames * bytesPerFrame ();
} }
Q_EMIT stateChanged ((m_state = Active)); Q_EMIT stateChanged ((m_state = Active));
m_ramp = 0; // prepare for CW wave shaping
} }
// fall through // fall through
@ -114,7 +125,8 @@ qint64 Modulator::readData (char * data, qint64 maxSize)
unsigned const ic0 = m_symbolsLength * 4 * m_nsps; unsigned const ic0 = m_symbolsLength * 4 * m_nsps;
unsigned j (0); unsigned j (0);
qint64 framesGenerated (0); qint64 framesGenerated (0);
for (unsigned i = 0; i < numFrames; ++i)
while (samples != end)
{ {
m_phi += m_dphi; m_phi += m_dphi;
if (m_phi > m_twoPi) if (m_phi > m_twoPi)
@ -122,28 +134,31 @@ qint64 Modulator::readData (char * data, qint64 maxSize)
m_phi -= m_twoPi; m_phi -= m_twoPi;
} }
frame_t frame; qint16 sample ((SOFT_KEYING ? qAbs (m_ramp - 1) : (m_ramp ? 32767 : 0)) * qSin (m_phi));
for (unsigned c = 0; c < NUM_CHANNELS; ++c)
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 (j < NUM_CW_SYMBOLS) // stop condition
{ {
if (!icw[j]) // if (!m_ramp && !icw[j])
{ // {
for (unsigned c = 0; c < NUM_CHANNELS; ++c) // sample = 0;
{ // }
frame.channel[c] = 0;
}
}
frame = postProcessFrame (frame); samples = load (postProcessSample (sample), samples);
*frames++ = frame;
++framesGenerated; ++framesGenerated;
++m_ic; ++m_ic;
} }
} }
@ -154,7 +169,7 @@ qint64 Modulator::readData (char * data, qint64 maxSize)
} }
m_framesSent += framesGenerated; m_framesSent += framesGenerated;
return framesGenerated * sizeof (frame_t); return framesGenerated * bytesPerFrame ();
} }
double const baud (12000.0 / m_nsps); double const baud (12000.0 / m_nsps);
@ -186,15 +201,7 @@ qint64 Modulator::readData (char * data, qint64 maxSize)
m_amp = 0.0; m_amp = 0.0;
} }
frame_t frame; samples = load (postProcessSample (m_amp * qSin (m_phi)), samples);
for (unsigned c = 0; c < NUM_CHANNELS; ++c)
{
frame.channel[c] = m_amp * qSin (m_phi);
}
frame = postProcessFrame (frame);
*frames++ = frame;
++m_ic; ++m_ic;
} }
@ -206,7 +213,7 @@ qint64 Modulator::readData (char * data, qint64 maxSize)
// no CW ID to send // no CW ID to send
Q_EMIT stateChanged ((m_state = Idle)); Q_EMIT stateChanged ((m_state = Idle));
m_framesSent += numFrames; m_framesSent += numFrames;
return numFrames * sizeof (frame_t); return numFrames * bytesPerFrame ();
} }
m_phi = 0.0; m_phi = 0.0;
@ -214,7 +221,7 @@ qint64 Modulator::readData (char * data, qint64 maxSize)
// done for this chunk - continue on next call // done for this chunk - continue on next call
m_framesSent += numFrames; m_framesSent += numFrames;
return numFrames * sizeof (frame_t); return numFrames * bytesPerFrame ();
} }
Q_EMIT stateChanged ((m_state = Idle)); Q_EMIT stateChanged ((m_state = Idle));
// fall through // fall through
@ -227,35 +234,24 @@ qint64 Modulator::readData (char * data, qint64 maxSize)
return 0; return 0;
} }
Modulator::frame_t Modulator::postProcessFrame (frame_t frame) const qint16 Modulator::postProcessSample (qint16 sample) const
{ {
if (m_muted) // silent frame if (m_muted) // silent frame
{ {
for (unsigned c = 0; c < NUM_CHANNELS; ++c) sample = 0;
{
frame.channel[c] = 0;
}
} }
else if (m_addNoise) else if (m_addNoise)
{ {
qint32 f[NUM_CHANNELS]; qint32 s = m_fac * (gran () + sample * m_snr / 32768.0);
for (unsigned c = 0; c < NUM_CHANNELS; ++c) if (s > std::numeric_limits<qint16>::max ())
{ {
f[c] = m_fac * (gran () + frame.channel[c] * m_snr / 32768.0); s = std::numeric_limits<qint16>::max ();
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 ();
}
} }
if (s < std::numeric_limits<qint16>::min ())
for (unsigned c = 0; c < NUM_CHANNELS; ++c)
{ {
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__ #ifndef MODULATOR_HPP__
#define MODULATOR_HPP__ #define MODULATOR_HPP__
#include <QIODevice> #include "AudioDevice.hpp"
#ifdef UNIX #ifdef UNIX
# define NUM_CHANNELS 2 # define NUM_CHANNELS 2
@ -16,7 +16,7 @@
// Output can be muted while underway, preserving waveform timing when // Output can be muted while underway, preserving waveform timing when
// transmission is resumed. // transmission is resumed.
// //
class Modulator : public QIODevice class Modulator : public AudioDevice
{ {
Q_OBJECT; Q_OBJECT;
@ -24,33 +24,18 @@ class Modulator : public QIODevice
Q_PROPERTY (bool tuning READ isTuning WRITE tune); Q_PROPERTY (bool tuning READ isTuning WRITE tune);
Q_PROPERTY (bool muted READ isMuted WRITE mute); Q_PROPERTY (bool muted READ isMuted WRITE mute);
private:
Q_DISABLE_COPY (Modulator);
public: public:
enum ModulatorState {Synchronizing, Active, Idle};
Modulator (unsigned frameRate, unsigned periodLengthInSeconds, QObject * parent = 0); Modulator (unsigned frameRate, unsigned periodLengthInSeconds, QObject * parent = 0);
bool open () {return QIODevice::open (QIODevice::ReadOnly | QIODevice::Unbuffered);} Q_SLOT void open (unsigned symbolsLength, double framesPerSymbol, unsigned frequency, AudioDevice::Channel, bool synchronize = true, double dBSNR = 99.);
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));}
bool isTuning () const {return m_tuning;} bool isTuning () const {return m_tuning;}
Q_SLOT void tune (bool newState = true) {m_tuning = newState;}
bool isMuted () const {return m_muted;} bool isMuted () const {return m_muted;}
Q_SLOT void mute (bool newState = true) {m_muted = newState;}
unsigned frequency () const {return m_frequency;} 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 isActive () const {return m_state != Idle;}
bool isSequential () const {return true;}
protected: protected:
qint64 readData (char * data, qint64 maxSize); qint64 readData (char * data, qint64 maxSize);
qint64 writeData (char const * /* data */, qint64 /* maxSize */) qint64 writeData (char const * /* data */, qint64 /* maxSize */)
@ -59,12 +44,22 @@ protected:
} }
private: 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]; Q_EMIT stateChanged ((m_state = Idle));
} frame_t; 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; unsigned m_symbolsLength;
@ -88,6 +83,7 @@ private:
unsigned m_ic; unsigned m_ic;
double m_fac; double m_fac;
unsigned m_isym0; unsigned m_isym0;
qint16 m_ramp;
}; };
#endif #endif

View File

@ -1,127 +1,127 @@
#pragma once #pragma once
// Main header file for the external interface to the PSK Reporter API // Main header file for the external interface to the PSK Reporter API
// For documentation see http://psk.gladstonefamily.net/PSKReporterAPI.pdf // For documentation see http://psk.gladstonefamily.net/PSKReporterAPI.pdf
/* /*
Copyright (c) 2008 Philip Gladstone Copyright (c) 2008 Philip Gladstone
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
*/ */
#ifdef _DLL_OPTION_PSKREPORTER_EXPORT #ifdef _DLL_OPTION_PSKREPORTER_EXPORT
#define DllImportExport __declspec ( dllexport ) #define DllImportExport __declspec ( dllexport )
#else #else
#define DllImportExport __declspec ( dllimport ) #define DllImportExport __declspec ( dllimport )
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#define REPORTER_SOURCE_MASK 0x07 #define REPORTER_SOURCE_MASK 0x07
#define REPORTER_SOURCE_AUTOMATIC 0x01 #define REPORTER_SOURCE_AUTOMATIC 0x01
#define REPORTER_SOURCE_LOG 0x02 #define REPORTER_SOURCE_LOG 0x02
#define REPORTER_SOURCE_MANUAL 0x03 #define REPORTER_SOURCE_MANUAL 0x03
#define REPORTER_SOURCE_TENTATIVE 0x40 #define REPORTER_SOURCE_TENTATIVE 0x40
#define REPORTER_SOURCE_TEST 0x80 #define REPORTER_SOURCE_TEST 0x80
typedef struct { typedef struct {
wchar_t hostname[256]; wchar_t hostname[256];
wchar_t port[32]; wchar_t port[32];
bool connected; bool connected;
unsigned int callsigns_sent; unsigned int callsigns_sent;
unsigned int callsigns_buffered; unsigned int callsigns_buffered;
unsigned int callsigns_discarded; unsigned int callsigns_discarded;
unsigned int last_send_time; unsigned int last_send_time;
unsigned int next_send_time; unsigned int next_send_time;
wchar_t last_callsign_queued[24]; wchar_t last_callsign_queued[24];
unsigned int bytes_sent; unsigned int bytes_sent;
unsigned int bytes_sent_total; unsigned int bytes_sent_total;
unsigned int packets_sent; unsigned int packets_sent;
unsigned int packets_sent_total; unsigned int packets_sent_total;
} REPORTER_STATISTICS; } REPORTER_STATISTICS;
unsigned long DllImportExport __cdecl ReporterInitialize( unsigned long DllImportExport __cdecl ReporterInitialize(
const wchar_t *hostname, const wchar_t *hostname,
const wchar_t *port const wchar_t *port
); );
unsigned long DllImportExport __cdecl ReporterSeenCallsign( unsigned long DllImportExport __cdecl ReporterSeenCallsign(
const wchar_t *remoteInformation, const wchar_t *remoteInformation,
const wchar_t *localInformation, const wchar_t *localInformation,
unsigned long flags unsigned long flags
); );
unsigned long DllImportExport __cdecl ReporterTickle( unsigned long DllImportExport __cdecl ReporterTickle(
); );
unsigned long DllImportExport __cdecl ReporterGetInformation( unsigned long DllImportExport __cdecl ReporterGetInformation(
wchar_t *buffer, wchar_t *buffer,
unsigned long maxlen unsigned long maxlen
); );
unsigned long DllImportExport __cdecl ReporterGetStatistics( unsigned long DllImportExport __cdecl ReporterGetStatistics(
REPORTER_STATISTICS *buffer, REPORTER_STATISTICS *buffer,
unsigned long maxlen unsigned long maxlen
); );
unsigned long DllImportExport __cdecl ReporterUninitialize( unsigned long DllImportExport __cdecl ReporterUninitialize(
); );
unsigned long DllImportExport __stdcall ReporterInitializeSTD( unsigned long DllImportExport __stdcall ReporterInitializeSTD(
const char *hostname, const char *hostname,
const char *port const char *port
); );
unsigned long DllImportExport __stdcall ReporterSeenCallsignSTD( unsigned long DllImportExport __stdcall ReporterSeenCallsignSTD(
const char *remoteInformation, const char *remoteInformation,
const char *localInformation, const char *localInformation,
unsigned long flags unsigned long flags
); );
unsigned long DllImportExport __stdcall ReporterTickleSTD( unsigned long DllImportExport __stdcall ReporterTickleSTD(
); );
unsigned long DllImportExport __stdcall ReporterGetInformationSTD( unsigned long DllImportExport __stdcall ReporterGetInformationSTD(
char *buffer, char *buffer,
unsigned long maxlen unsigned long maxlen
); );
unsigned long DllImportExport __stdcall ReporterGetStatisticsSTD( unsigned long DllImportExport __stdcall ReporterGetStatisticsSTD(
REPORTER_STATISTICS *buffer, REPORTER_STATISTICS *buffer,
unsigned long maxlen unsigned long maxlen
); );
unsigned long DllImportExport __stdcall ReporterUninitializeSTD( unsigned long DllImportExport __stdcall ReporterUninitializeSTD(
); );
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

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

View File

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

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"> <ui version="4.0">
<class>DialogSndCard</class> <class>DevSetup</class>
<widget class="QDialog" name="DialogSndCard"> <widget class="QDialog" name="DevSetup">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
@ -1137,77 +1137,8 @@
</spacer> </spacer>
</item> </item>
<item> <item>
<layout class="QVBoxLayout" name="verticalLayout_6"> <layout class="QGridLayout" name="gridLayout_3">
<item> <item row="2" 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="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="QHBoxLayout" name="horizontalLayout"> <layout class="QHBoxLayout" name="horizontalLayout">
<item> <item>
<widget class="QLabel" name="label_10"> <widget class="QLabel" name="label_10">
@ -1240,6 +1171,136 @@
</item> </item>
</layout> </layout>
</item> </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> </layout>
</item> </item>
</layout> </layout>
@ -1807,7 +1868,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>510</width> <width>308</width>
<height>449</height> <height>449</height>
</rect> </rect>
</property> </property>
@ -2519,7 +2580,7 @@
<connection> <connection>
<sender>buttonBox</sender> <sender>buttonBox</sender>
<signal>accepted()</signal> <signal>accepted()</signal>
<receiver>DialogSndCard</receiver> <receiver>DevSetup</receiver>
<slot>accept()</slot> <slot>accept()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">
@ -2535,7 +2596,7 @@
<connection> <connection>
<sender>buttonBox</sender> <sender>buttonBox</sender>
<signal>rejected()</signal> <signal>rejected()</signal>
<receiver>DialogSndCard</receiver> <receiver>DevSetup</receiver>
<slot>reject()</slot> <slot>reject()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">

View File

@ -1,284 +1,284 @@
#include <windows.h> #include <windows.h>
#include <tlhelp32.h> #include <tlhelp32.h>
#include <iostream> #include <iostream>
int killbyname(const char *szToTerminate) int killbyname(const char *szToTerminate)
// Created: 6/23/2000 (Ravi Kochhar) // Created: 6/23/2000 (Ravi Kochhar)
// Last modified: 3/10/2002 (RK) // Last modified: 3/10/2002 (RK)
// Please report any problems or bugs to kochhar@physiology.wisc.edu // Please report any problems or bugs to kochhar@physiology.wisc.edu
// The latest version of this routine can be found at: // The latest version of this routine can be found at:
// http://www.neurophys.wisc.edu/ravi/software/killproc/ // http://www.neurophys.wisc.edu/ravi/software/killproc/
// Terminate the process "szToTerminate" if it is currently running // Terminate the process "szToTerminate" if it is currently running
// This works for Win/95/98/ME and also Win/NT/2000/XP // This works for Win/95/98/ME and also Win/NT/2000/XP
// The process name is case-insensitive, i.e. "notepad.exe" and "NOTEPAD.EXE" // The process name is case-insensitive, i.e. "notepad.exe" and "NOTEPAD.EXE"
// will both work (for szToTerminate) // will both work (for szToTerminate)
// Return codes are as follows: // Return codes are as follows:
// 0 = Process was successfully terminated // 0 = Process was successfully terminated
// 602 = Unable to terminate process for some other reason // 602 = Unable to terminate process for some other reason
// 603 = Process was not currently running // 603 = Process was not currently running
// 604 = No permission to terminate process // 604 = No permission to terminate process
// 605 = Unable to load PSAPI.DLL // 605 = Unable to load PSAPI.DLL
// 606 = Unable to identify system type // 606 = Unable to identify system type
// 607 = Unsupported OS // 607 = Unsupported OS
// 632 = Invalid process name // 632 = Invalid process name
// 700 = Unable to get procedure address from PSAPI.DLL // 700 = Unable to get procedure address from PSAPI.DLL
// 701 = Unable to get process list, EnumProcesses failed // 701 = Unable to get process list, EnumProcesses failed
// 702 = Unable to load KERNEL32.DLL // 702 = Unable to load KERNEL32.DLL
// 703 = Unable to get procedure address from KERNEL32.DLL // 703 = Unable to get procedure address from KERNEL32.DLL
// 704 = CreateToolhelp32Snapshot failed // 704 = CreateToolhelp32Snapshot failed
{ {
BOOL bResult,bResultm; BOOL bResult,bResultm;
DWORD aiPID[1000],iCb=1000,iNumProc; //,iV2000=0; DWORD aiPID[1000],iCb=1000,iNumProc; //,iV2000=0;
DWORD iCbneeded,i,iFound=0; DWORD iCbneeded,i,iFound=0;
char szName[MAX_PATH],szToTermUpper[MAX_PATH]; char szName[MAX_PATH],szToTermUpper[MAX_PATH];
HANDLE hProc,hSnapShot,hSnapShotm; HANDLE hProc,hSnapShot,hSnapShotm;
OSVERSIONINFO osvi; OSVERSIONINFO osvi;
HINSTANCE hInstLib; HINSTANCE hInstLib;
// int iLen,iLenP,indx; // int iLen,iLenP,indx;
int iLenP,indx; int iLenP,indx;
HMODULE hMod; HMODULE hMod;
PROCESSENTRY32 procentry; PROCESSENTRY32 procentry;
MODULEENTRY32 modentry; MODULEENTRY32 modentry;
// Transfer Process name into "szToTermUpper" and convert to upper case // Transfer Process name into "szToTermUpper" and convert to upper case
iLenP=strlen(szToTerminate); iLenP=strlen(szToTerminate);
if(iLenP<1 || iLenP>MAX_PATH) return 632; if(iLenP<1 || iLenP>MAX_PATH) return 632;
for(indx=0;indx<iLenP;indx++) for(indx=0;indx<iLenP;indx++)
szToTermUpper[indx]=toupper(szToTerminate[indx]); szToTermUpper[indx]=toupper(szToTerminate[indx]);
szToTermUpper[iLenP]=0; szToTermUpper[iLenP]=0;
// PSAPI Function Pointers. // PSAPI Function Pointers.
BOOL (WINAPI *lpfEnumProcesses)( DWORD *, DWORD cb, DWORD * ); BOOL (WINAPI *lpfEnumProcesses)( DWORD *, DWORD cb, DWORD * );
BOOL (WINAPI *lpfEnumProcessModules)( HANDLE, HMODULE *, BOOL (WINAPI *lpfEnumProcessModules)( HANDLE, HMODULE *,
DWORD, LPDWORD ); DWORD, LPDWORD );
DWORD (WINAPI *lpfGetModuleBaseName)( HANDLE, HMODULE, DWORD (WINAPI *lpfGetModuleBaseName)( HANDLE, HMODULE,
LPTSTR, DWORD ); LPTSTR, DWORD );
// ToolHelp Function Pointers. // ToolHelp Function Pointers.
HANDLE (WINAPI *lpfCreateToolhelp32Snapshot)(DWORD,DWORD) ; HANDLE (WINAPI *lpfCreateToolhelp32Snapshot)(DWORD,DWORD) ;
BOOL (WINAPI *lpfProcess32First)(HANDLE,LPPROCESSENTRY32) ; BOOL (WINAPI *lpfProcess32First)(HANDLE,LPPROCESSENTRY32) ;
BOOL (WINAPI *lpfProcess32Next)(HANDLE,LPPROCESSENTRY32) ; BOOL (WINAPI *lpfProcess32Next)(HANDLE,LPPROCESSENTRY32) ;
BOOL (WINAPI *lpfModule32First)(HANDLE,LPMODULEENTRY32) ; BOOL (WINAPI *lpfModule32First)(HANDLE,LPMODULEENTRY32) ;
BOOL (WINAPI *lpfModule32Next)(HANDLE,LPMODULEENTRY32) ; BOOL (WINAPI *lpfModule32Next)(HANDLE,LPMODULEENTRY32) ;
// First check what version of Windows we're in // First check what version of Windows we're in
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
bResult=GetVersionEx(&osvi); bResult=GetVersionEx(&osvi);
if(!bResult) return 606; // Unable to identify system version if(!bResult) return 606; // Unable to identify system version
// At Present we only support Win/NT/2000/XP or Win/9x/ME // At Present we only support Win/NT/2000/XP or Win/9x/ME
// Seems to work OK in Win7 // Seems to work OK in Win7
if((osvi.dwPlatformId != VER_PLATFORM_WIN32_NT) && if((osvi.dwPlatformId != VER_PLATFORM_WIN32_NT) &&
(osvi.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS)) return 607; (osvi.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS)) return 607;
if(osvi.dwPlatformId==VER_PLATFORM_WIN32_NT) if(osvi.dwPlatformId==VER_PLATFORM_WIN32_NT)
{ {
// Win/NT or 2000 or XP // Win/NT or 2000 or XP
// Load library and get the procedures explicitly. We do // Load library and get the procedures explicitly. We do
// this so that we don't have to worry about modules using // this so that we don't have to worry about modules using
// this code failing to load under Windows 9x, because // this code failing to load under Windows 9x, because
// it can't resolve references to the PSAPI.DLL. // it can't resolve references to the PSAPI.DLL.
hInstLib = LoadLibraryA("PSAPI.DLL"); hInstLib = LoadLibraryA("PSAPI.DLL");
if(hInstLib == NULL) return 605; if(hInstLib == NULL) return 605;
// Get procedure addresses. // Get procedure addresses.
lpfEnumProcesses = (BOOL(WINAPI *)(DWORD *,DWORD,DWORD*)) lpfEnumProcesses = (BOOL(WINAPI *)(DWORD *,DWORD,DWORD*))
GetProcAddress( hInstLib, "EnumProcesses" ) ; GetProcAddress( hInstLib, "EnumProcesses" ) ;
lpfEnumProcessModules = (BOOL(WINAPI *)(HANDLE, HMODULE *, lpfEnumProcessModules = (BOOL(WINAPI *)(HANDLE, HMODULE *,
DWORD, LPDWORD)) GetProcAddress( hInstLib, "EnumProcessModules" ) ; DWORD, LPDWORD)) GetProcAddress( hInstLib, "EnumProcessModules" ) ;
lpfGetModuleBaseName =(DWORD (WINAPI *)(HANDLE, HMODULE, LPTSTR, lpfGetModuleBaseName =(DWORD (WINAPI *)(HANDLE, HMODULE, LPTSTR,
DWORD )) GetProcAddress( hInstLib, "GetModuleBaseNameA" ) ; DWORD )) GetProcAddress( hInstLib, "GetModuleBaseNameA" ) ;
if(lpfEnumProcesses == NULL || lpfEnumProcessModules == NULL || if(lpfEnumProcesses == NULL || lpfEnumProcessModules == NULL ||
lpfGetModuleBaseName == NULL) { lpfGetModuleBaseName == NULL) {
FreeLibrary(hInstLib); FreeLibrary(hInstLib);
return 700; return 700;
} }
bResult=lpfEnumProcesses(aiPID,iCb,&iCbneeded); bResult=lpfEnumProcesses(aiPID,iCb,&iCbneeded);
if(!bResult) { if(!bResult) {
// Unable to get process list, EnumProcesses failed // Unable to get process list, EnumProcesses failed
FreeLibrary(hInstLib); FreeLibrary(hInstLib);
return 701; return 701;
} }
// How many processes are there? // How many processes are there?
iNumProc=iCbneeded/sizeof(DWORD); iNumProc=iCbneeded/sizeof(DWORD);
// Get and match the name of each process // Get and match the name of each process
for(i=0;i<iNumProc;i++) { for(i=0;i<iNumProc;i++) {
// Get the (module) name for this process // Get the (module) name for this process
strcpy(szName,"Unknown"); strcpy(szName,"Unknown");
// First, get a handle to the process // First, get a handle to the process
hProc=OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,FALSE, hProc=OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,FALSE,
aiPID[i]); aiPID[i]);
// Now, get the process name // Now, get the process name
if(hProc) { if(hProc) {
if(lpfEnumProcessModules(hProc,&hMod,sizeof(hMod),&iCbneeded) ) { if(lpfEnumProcessModules(hProc,&hMod,sizeof(hMod),&iCbneeded) ) {
// iLen=lpfGetModuleBaseName(hProc,hMod,szName,MAX_PATH); // iLen=lpfGetModuleBaseName(hProc,hMod,szName,MAX_PATH);
lpfGetModuleBaseName(hProc,hMod,szName,MAX_PATH); lpfGetModuleBaseName(hProc,hMod,szName,MAX_PATH);
} }
} }
CloseHandle(hProc); CloseHandle(hProc);
// We will match regardless of lower or upper case // We will match regardless of lower or upper case
if(strcmp(_strupr(szName),szToTermUpper)==0) { if(strcmp(_strupr(szName),szToTermUpper)==0) {
// Process found, now terminate it // Process found, now terminate it
iFound=1; iFound=1;
// First open for termination // First open for termination
hProc=OpenProcess(PROCESS_TERMINATE,FALSE,aiPID[i]); hProc=OpenProcess(PROCESS_TERMINATE,FALSE,aiPID[i]);
if(hProc) { if(hProc) {
if(TerminateProcess(hProc,0)) { if(TerminateProcess(hProc,0)) {
// process terminated // process terminated
CloseHandle(hProc); CloseHandle(hProc);
FreeLibrary(hInstLib); FreeLibrary(hInstLib);
return 0; return 0;
} else { } else {
// Unable to terminate process // Unable to terminate process
CloseHandle(hProc); CloseHandle(hProc);
FreeLibrary(hInstLib); FreeLibrary(hInstLib);
return 602; return 602;
} }
} else { } else {
// Unable to open process for termination // Unable to open process for termination
FreeLibrary(hInstLib); FreeLibrary(hInstLib);
return 604; return 604;
} }
} }
} }
} }
if(osvi.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS) if(osvi.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS)
{ {
// Win/95 or 98 or ME // Win/95 or 98 or ME
hInstLib = LoadLibraryA("Kernel32.DLL"); hInstLib = LoadLibraryA("Kernel32.DLL");
if( hInstLib == NULL ) if( hInstLib == NULL )
return 702; return 702;
// Get procedure addresses. // Get procedure addresses.
// We are linking to these functions of Kernel32 // We are linking to these functions of Kernel32
// explicitly, because otherwise a module using // explicitly, because otherwise a module using
// this code would fail to load under Windows NT, // this code would fail to load under Windows NT,
// which does not have the Toolhelp32 // which does not have the Toolhelp32
// functions in the Kernel 32. // functions in the Kernel 32.
lpfCreateToolhelp32Snapshot= lpfCreateToolhelp32Snapshot=
(HANDLE(WINAPI *)(DWORD,DWORD)) (HANDLE(WINAPI *)(DWORD,DWORD))
GetProcAddress( hInstLib, GetProcAddress( hInstLib,
"CreateToolhelp32Snapshot" ) ; "CreateToolhelp32Snapshot" ) ;
lpfProcess32First= lpfProcess32First=
(BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32)) (BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))
GetProcAddress( hInstLib, "Process32First" ) ; GetProcAddress( hInstLib, "Process32First" ) ;
lpfProcess32Next= lpfProcess32Next=
(BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32)) (BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))
GetProcAddress( hInstLib, "Process32Next" ) ; GetProcAddress( hInstLib, "Process32Next" ) ;
lpfModule32First= lpfModule32First=
(BOOL(WINAPI *)(HANDLE,LPMODULEENTRY32)) (BOOL(WINAPI *)(HANDLE,LPMODULEENTRY32))
GetProcAddress( hInstLib, "Module32First" ) ; GetProcAddress( hInstLib, "Module32First" ) ;
lpfModule32Next= lpfModule32Next=
(BOOL(WINAPI *)(HANDLE,LPMODULEENTRY32)) (BOOL(WINAPI *)(HANDLE,LPMODULEENTRY32))
GetProcAddress( hInstLib, "Module32Next" ) ; GetProcAddress( hInstLib, "Module32Next" ) ;
if( lpfProcess32Next == NULL || if( lpfProcess32Next == NULL ||
lpfProcess32First == NULL || lpfProcess32First == NULL ||
lpfModule32Next == NULL || lpfModule32Next == NULL ||
lpfModule32First == NULL || lpfModule32First == NULL ||
lpfCreateToolhelp32Snapshot == NULL ) lpfCreateToolhelp32Snapshot == NULL )
{ {
FreeLibrary(hInstLib); FreeLibrary(hInstLib);
return 703; return 703;
} }
// The Process32.. and Module32.. routines return names in all uppercase // The Process32.. and Module32.. routines return names in all uppercase
// Get a handle to a Toolhelp snapshot of all the systems processes. // Get a handle to a Toolhelp snapshot of all the systems processes.
hSnapShot = lpfCreateToolhelp32Snapshot( hSnapShot = lpfCreateToolhelp32Snapshot(
TH32CS_SNAPPROCESS, 0 ) ; TH32CS_SNAPPROCESS, 0 ) ;
if( hSnapShot == INVALID_HANDLE_VALUE ) if( hSnapShot == INVALID_HANDLE_VALUE )
{ {
FreeLibrary(hInstLib); FreeLibrary(hInstLib);
return 704; return 704;
} }
// Get the first process' information. // Get the first process' information.
procentry.dwSize = sizeof(PROCESSENTRY32); procentry.dwSize = sizeof(PROCESSENTRY32);
bResult=lpfProcess32First(hSnapShot,&procentry); bResult=lpfProcess32First(hSnapShot,&procentry);
// While there are processes, keep looping and checking. // While there are processes, keep looping and checking.
while(bResult) while(bResult)
{ {
// Get a handle to a Toolhelp snapshot of this process. // Get a handle to a Toolhelp snapshot of this process.
hSnapShotm = lpfCreateToolhelp32Snapshot( hSnapShotm = lpfCreateToolhelp32Snapshot(
TH32CS_SNAPMODULE, procentry.th32ProcessID) ; TH32CS_SNAPMODULE, procentry.th32ProcessID) ;
if( hSnapShotm == INVALID_HANDLE_VALUE ) if( hSnapShotm == INVALID_HANDLE_VALUE )
{ {
CloseHandle(hSnapShot); CloseHandle(hSnapShot);
FreeLibrary(hInstLib); FreeLibrary(hInstLib);
return 704; return 704;
} }
// Get the module list for this process // Get the module list for this process
modentry.dwSize=sizeof(MODULEENTRY32); modentry.dwSize=sizeof(MODULEENTRY32);
bResultm=lpfModule32First(hSnapShotm,&modentry); bResultm=lpfModule32First(hSnapShotm,&modentry);
// While there are modules, keep looping and checking // While there are modules, keep looping and checking
while(bResultm) while(bResultm)
{ {
if(strcmp(modentry.szModule,szToTermUpper)==0) if(strcmp(modentry.szModule,szToTermUpper)==0)
{ {
// Process found, now terminate it // Process found, now terminate it
iFound=1; iFound=1;
// First open for termination // First open for termination
hProc=OpenProcess(PROCESS_TERMINATE,FALSE,procentry.th32ProcessID); hProc=OpenProcess(PROCESS_TERMINATE,FALSE,procentry.th32ProcessID);
if(hProc) if(hProc)
{ {
if(TerminateProcess(hProc,0)) if(TerminateProcess(hProc,0))
{ {
// process terminated // process terminated
CloseHandle(hSnapShotm); CloseHandle(hSnapShotm);
CloseHandle(hSnapShot); CloseHandle(hSnapShot);
CloseHandle(hProc); CloseHandle(hProc);
FreeLibrary(hInstLib); FreeLibrary(hInstLib);
return 0; return 0;
} }
else else
{ {
// Unable to terminate process // Unable to terminate process
CloseHandle(hSnapShotm); CloseHandle(hSnapShotm);
CloseHandle(hSnapShot); CloseHandle(hSnapShot);
CloseHandle(hProc); CloseHandle(hProc);
FreeLibrary(hInstLib); FreeLibrary(hInstLib);
return 602; return 602;
} }
} }
else else
{ {
// Unable to open process for termination // Unable to open process for termination
CloseHandle(hSnapShotm); CloseHandle(hSnapShotm);
CloseHandle(hSnapShot); CloseHandle(hSnapShot);
FreeLibrary(hInstLib); FreeLibrary(hInstLib);
return 604; return 604;
} }
} }
else else
{ // Look for next modules for this process { // Look for next modules for this process
modentry.dwSize=sizeof(MODULEENTRY32); modentry.dwSize=sizeof(MODULEENTRY32);
bResultm=lpfModule32Next(hSnapShotm,&modentry); bResultm=lpfModule32Next(hSnapShotm,&modentry);
} }
} }
//Keep looking //Keep looking
CloseHandle(hSnapShotm); CloseHandle(hSnapShotm);
procentry.dwSize = sizeof(PROCESSENTRY32); procentry.dwSize = sizeof(PROCESSENTRY32);
bResult = lpfProcess32Next(hSnapShot,&procentry); bResult = lpfProcess32Next(hSnapShot,&procentry);
} }
CloseHandle(hSnapShot); CloseHandle(hSnapShot);
} }
if(iFound==0) if(iFound==0)
{ {
FreeLibrary(hInstLib); FreeLibrary(hInstLib);
return 603; return 603;
} }
FreeLibrary(hInstLib); FreeLibrary(hInstLib);
return 0; return 0;
} }

View File

@ -1,59 +1,59 @@
subroutine afc65b(cx,npts,fsample,nflip,a,ccfbest,dtbest) subroutine afc65b(cx,npts,fsample,nflip,a,ccfbest,dtbest)
! Find delta f, f1, f2 ==> a(1:3) ! Find delta f, f1, f2 ==> a(1:3)
complex cx(npts) complex cx(npts)
real a(5),deltaa(5) real a(5),deltaa(5)
a(1)=0. a(1)=0.
a(2)=0. a(2)=0.
a(3)=0. a(3)=0.
a(4)=0. a(4)=0.
deltaa(1)=2.0 deltaa(1)=2.0
deltaa(2)=2.0 deltaa(2)=2.0
deltaa(3)=2.0 deltaa(3)=2.0
deltaa(4)=0.05 deltaa(4)=0.05
nterms=3 !Maybe 2 is enough? nterms=3 !Maybe 2 is enough?
! Start the iteration ! Start the iteration
chisqr=0. chisqr=0.
chisqr0=1.e6 chisqr0=1.e6
do iter=1,3 !One iteration is enough? do iter=1,3 !One iteration is enough?
do j=1,nterms do j=1,nterms
chisq1=fchisq65(cx,npts,fsample,nflip,a,ccfmax,dtmax) chisq1=fchisq65(cx,npts,fsample,nflip,a,ccfmax,dtmax)
fn=0. fn=0.
delta=deltaa(j) delta=deltaa(j)
10 a(j)=a(j)+delta 10 a(j)=a(j)+delta
chisq2=fchisq65(cx,npts,fsample,nflip,a,ccfmax,dtmax) chisq2=fchisq65(cx,npts,fsample,nflip,a,ccfmax,dtmax)
if(chisq2.eq.chisq1) go to 10 if(chisq2.eq.chisq1) go to 10
if(chisq2.gt.chisq1) then if(chisq2.gt.chisq1) then
delta=-delta !Reverse direction delta=-delta !Reverse direction
a(j)=a(j)+delta a(j)=a(j)+delta
tmp=chisq1 tmp=chisq1
chisq1=chisq2 chisq1=chisq2
chisq2=tmp chisq2=tmp
endif endif
20 fn=fn+1.0 20 fn=fn+1.0
a(j)=a(j)+delta a(j)=a(j)+delta
chisq3=fchisq65(cx,npts,fsample,nflip,a,ccfmax,dtmax) chisq3=fchisq65(cx,npts,fsample,nflip,a,ccfmax,dtmax)
if(chisq3.lt.chisq2) then if(chisq3.lt.chisq2) then
chisq1=chisq2 chisq1=chisq2
chisq2=chisq3 chisq2=chisq3
go to 20 go to 20
endif endif
! Find minimum of parabola defined by last three points ! Find minimum of parabola defined by last three points
delta=delta*(1./(1.+(chisq1-chisq2)/(chisq3-chisq2))+0.5) delta=delta*(1./(1.+(chisq1-chisq2)/(chisq3-chisq2))+0.5)
a(j)=a(j)-delta a(j)=a(j)-delta
deltaa(j)=deltaa(j)*fn/3. deltaa(j)=deltaa(j)*fn/3.
enddo enddo
chisqr=fchisq65(cx,npts,fsample,nflip,a,ccfmax,dtmax) chisqr=fchisq65(cx,npts,fsample,nflip,a,ccfmax,dtmax)
if(chisqr/chisqr0.gt.0.9999) go to 30 if(chisqr/chisqr0.gt.0.9999) go to 30
chisqr0=chisqr chisqr0=chisqr
enddo enddo
30 ccfbest=ccfmax * (1378.125/fsample)**2 30 ccfbest=ccfmax * (1378.125/fsample)**2
dtbest=dtmax dtbest=dtmax
return return
end subroutine afc65b end subroutine afc65b

View File

@ -1,58 +1,58 @@
subroutine afc9(c3,npts,fsample,a,syncpk) subroutine afc9(c3,npts,fsample,a,syncpk)
complex c3(0:npts-1) complex c3(0:npts-1)
real a(3),deltaa(3) real a(3),deltaa(3)
a(1)=0. !f0 a(1)=0. !f0
a(2)=0. !f1 a(2)=0. !f1
a(3)=0. !f2 a(3)=0. !f2
deltaa(1)=0.2 deltaa(1)=0.2
deltaa(2)=0.01 deltaa(2)=0.01
deltaa(3)=0.01 deltaa(3)=0.01
nterms=3 nterms=3
! Start the iteration ! Start the iteration
chisqr=0. chisqr=0.
chisqr0=1.e6 chisqr0=1.e6
do iter=1,4 !One iteration is enough? do iter=1,4 !One iteration is enough?
do j=1,nterms do j=1,nterms
chisq1=fchisq(c3,npts,fsample,a) chisq1=fchisq(c3,npts,fsample,a)
fn=0. fn=0.
delta=deltaa(j) delta=deltaa(j)
10 a(j)=a(j)+delta 10 a(j)=a(j)+delta
chisq2=fchisq(c3,npts,fsample,a) chisq2=fchisq(c3,npts,fsample,a)
if(chisq2.eq.chisq1) go to 10 if(chisq2.eq.chisq1) go to 10
if(chisq2.gt.chisq1) then if(chisq2.gt.chisq1) then
delta=-delta !Reverse direction delta=-delta !Reverse direction
a(j)=a(j)+delta a(j)=a(j)+delta
tmp=chisq1 tmp=chisq1
chisq1=chisq2 chisq1=chisq2
chisq2=tmp chisq2=tmp
endif endif
20 fn=fn+1.0 20 fn=fn+1.0
a(j)=a(j)+delta a(j)=a(j)+delta
chisq3=fchisq(c3,npts,fsample,a) chisq3=fchisq(c3,npts,fsample,a)
if(chisq3.lt.chisq2) then if(chisq3.lt.chisq2) then
chisq1=chisq2 chisq1=chisq2
chisq2=chisq3 chisq2=chisq3
go to 20 go to 20
endif endif
! Find minimum of parabola defined by last three points ! Find minimum of parabola defined by last three points
delta=delta*(1./(1.+(chisq1-chisq2)/(chisq3-chisq2))+0.5) delta=delta*(1./(1.+(chisq1-chisq2)/(chisq3-chisq2))+0.5)
a(j)=a(j)-delta a(j)=a(j)-delta
deltaa(j)=deltaa(j)*fn/3. deltaa(j)=deltaa(j)*fn/3.
! write(*,4000) iter,j,a,deltaa,-chisq2 ! write(*,4000) iter,j,a,deltaa,-chisq2
!4000 format(i1,i2,6f10.4,f9.3) !4000 format(i1,i2,6f10.4,f9.3)
enddo enddo
chisqr=fchisq(c3,npts,fsample,a) chisqr=fchisq(c3,npts,fsample,a)
if(chisqr/chisqr0.gt.0.9999) exit if(chisqr/chisqr0.gt.0.9999) exit
chisqr0=chisqr chisqr0=chisqr
enddo enddo
syncpk=-chisqr syncpk=-chisqr
! write(*,4001) a,deltaa,-chisq2 ! write(*,4001) a,deltaa,-chisq2
!4001 format(3x,6f10.4,f9.3) !4001 format(3x,6f10.4,f9.3)
return return
end subroutine afc9 end subroutine afc9

View File

@ -1,28 +1,28 @@
#include <stdlib.h> #include <stdlib.h>
#include <math.h> #include <math.h>
/* Generate gaussian random float with mean=0 and std_dev=1 */ /* Generate gaussian random float with mean=0 and std_dev=1 */
float gran_() float gran_()
{ {
float fac,rsq,v1,v2; float fac,rsq,v1,v2;
static float gset; static float gset;
static int iset; static int iset;
if(iset){ if(iset){
/* Already got one */ /* Already got one */
iset = 0; iset = 0;
return gset; return gset;
} }
/* Generate two evenly distributed numbers between -1 and +1 /* Generate two evenly distributed numbers between -1 and +1
* that are inside the unit circle * that are inside the unit circle
*/ */
do { do {
v1 = 2.0 * (float)rand() / RAND_MAX - 1; v1 = 2.0 * (float)rand() / RAND_MAX - 1;
v2 = 2.0 * (float)rand() / RAND_MAX - 1; v2 = 2.0 * (float)rand() / RAND_MAX - 1;
rsq = v1*v1 + v2*v2; rsq = v1*v1 + v2*v2;
} while(rsq >= 1.0 || rsq == 0.0); } while(rsq >= 1.0 || rsq == 0.0);
fac = sqrt(-2.0*log(rsq)/rsq); fac = sqrt(-2.0*log(rsq)/rsq);
gset = v1*fac; gset = v1*fac;
iset++; iset++;
return v2*fac; return v2*fac;
} }

View File

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

View File

@ -1,70 +1,70 @@
#include <math.h> #include <math.h>
#include <stdio.h> #include <stdio.h>
#include <float.h> #include <float.h>
#include <limits.h> #include <limits.h>
#include <stdlib.h> #include <stdlib.h>
#include "rs.h" #include "rs.h"
static void *rs; static void *rs;
static int first=1; static int first=1;
void rs_encode_(int *dgen, int *sent) void rs_encode_(int *dgen, int *sent)
// Encode JT65 data dgen[12], producing sent[63]. // Encode JT65 data dgen[12], producing sent[63].
{ {
int dat1[12]; int dat1[12];
int b[51]; int b[51];
int i; int i;
if(first) { if(first) {
// Initialize the JT65 codec // Initialize the JT65 codec
rs=init_rs_int(6,0x43,3,1,51,0); rs=init_rs_int(6,0x43,3,1,51,0);
first=0; first=0;
} }
// Reverse data order for the Karn codec. // Reverse data order for the Karn codec.
for(i=0; i<12; i++) { for(i=0; i<12; i++) {
dat1[i]=dgen[11-i]; dat1[i]=dgen[11-i];
} }
// Compute the parity symbols // Compute the parity symbols
encode_rs_int(rs,dat1,b); encode_rs_int(rs,dat1,b);
// Move parity symbols and data into sent[] array, in reverse order. // Move parity symbols and data into sent[] array, in reverse order.
for (i = 0; i < 51; i++) sent[50-i] = b[i]; for (i = 0; i < 51; i++) sent[50-i] = b[i];
for (i = 0; i < 12; i++) sent[i+51] = dat1[11-i]; for (i = 0; i < 12; i++) sent[i+51] = dat1[11-i];
} }
void rs_decode_(int *recd0, int *era0, int *numera0, int *decoded, int *nerr) void rs_decode_(int *recd0, int *era0, int *numera0, int *decoded, int *nerr)
// Decode JT65 received data recd0[63], producing decoded[12]. // Decode JT65 received data recd0[63], producing decoded[12].
// Erasures are indicated in era0[numera]. The number of corrected // Erasures are indicated in era0[numera]. The number of corrected
// errors is *nerr. If the data are uncorrectable, *nerr=-1 is returned. // errors is *nerr. If the data are uncorrectable, *nerr=-1 is returned.
{ {
int numera; int numera;
int i; int i;
int era_pos[50]; int era_pos[50];
int recd[63]; int recd[63];
if(first) { if(first) {
rs=init_rs_int(6,0x43,3,1,51,0); rs=init_rs_int(6,0x43,3,1,51,0);
first=0; first=0;
} }
numera=*numera0; numera=*numera0;
for(i=0; i<12; i++) recd[i]=recd0[62-i]; for(i=0; i<12; i++) recd[i]=recd0[62-i];
for(i=0; i<51; i++) recd[12+i]=recd0[50-i]; for(i=0; i<51; i++) recd[12+i]=recd0[50-i];
if(numera) if(numera)
for(i=0; i<numera; i++) era_pos[i]=era0[i]; for(i=0; i<numera; i++) era_pos[i]=era0[i];
*nerr=decode_rs_int(rs,recd,era_pos,numera); *nerr=decode_rs_int(rs,recd,era_pos,numera);
for(i=0; i<12; i++) decoded[i]=recd[11-i]; for(i=0; i<12; i++) decoded[i]=recd[11-i];
} }
void rs_encode__(int *dgen, int *sent) void rs_encode__(int *dgen, int *sent)
{ {
rs_encode_(dgen, sent); rs_encode_(dgen, sent);
} }
void rs_decode__(int *recd0, int *era0, int *numera0, int *decoded, int *nerr) void rs_decode__(int *recd0, int *era0, int *numera0, int *decoded, int *nerr)
{ {
rs_decode_(recd0, era0, numera0, decoded, nerr); rs_decode_(recd0, era0, numera0, decoded, nerr);
} }

View File

@ -1,174 +1,197 @@
#include "logqso.h" #include "logqso.h"
#include "ui_logqso.h" #include "ui_logqso.h"
#include <QString> #include <QString>
#include <QDebug> #include <QDebug>
LogQSO::LogQSO(QWidget *parent) : LogQSO::LogQSO(QSettings * settings, QWidget *parent) :
QDialog(parent), QDialog(parent),
ui(new Ui::LogQSO) ui(new Ui::LogQSO),
{ m_settings (settings)
ui->setupUi(this); {
} ui->setupUi(this);
LogQSO::~LogQSO() loadSettings ();
{ }
delete ui;
} LogQSO::~LogQSO ()
{
void LogQSO::initLogQSO(QString hisCall, QString hisGrid, QString mode, }
QString rptSent, QString rptRcvd, QDateTime dateTime,
double dialFreq, QString myCall, QString myGrid, void LogQSO::loadSettings ()
bool noSuffix, bool toRTTY, bool dBtoComments) {
{ m_settings->beginGroup ("LogQSO");
ui->call->setText(hisCall); restoreGeometry (m_settings->value ("geometry", saveGeometry ()).toByteArray ());
ui->grid->setText(hisGrid); ui->cbTxPower->setChecked (m_settings->value ("SaveTxPower", false).toBool ());
ui->txPower->setText(""); ui->cbComments->setChecked (m_settings->value ("SaveComments", false).toBool ());
ui->comments->setText(""); m_txPower = m_settings->value ("TxPower", "").toString ();
if(m_saveTxPower) ui->txPower->setText(m_txPower); m_comments = m_settings->value ("LogComments", "").toString();
if(m_saveComments) ui->comments->setText(m_comments); m_settings->endGroup ();
if(dBtoComments) { }
QString t=mode;
if(rptSent!="") t+=" Sent: " + rptSent; void LogQSO::storeSettings () const
if(rptRcvd!="") t+=" Rcvd: " + rptRcvd; {
ui->comments->setText(t); m_settings->beginGroup ("LogQSO");
} m_settings->setValue ("geometry", saveGeometry ());
if(noSuffix and mode.mid(0,3)=="JT9") mode="JT9"; m_settings->setValue ("SaveTxPower", ui->cbTxPower->isChecked ());
if(toRTTY and mode.mid(0,3)=="JT9") mode="RTTY"; m_settings->setValue ("SaveComments", ui->cbComments->isChecked ());
ui->mode->setText(mode); m_settings->setValue ("TxPower", m_txPower);
ui->sent->setText(rptSent); m_settings->setValue ("LogComments", m_comments);
ui->rcvd->setText(rptRcvd); m_settings->endGroup ();
m_dateTime=dateTime; }
QString date=dateTime.toString("yyyy-MM-dd");
ui->date->setText(date); void LogQSO::initLogQSO(QString hisCall, QString hisGrid, QString mode,
QString time=dateTime.toString("hhmm"); QString rptSent, QString rptRcvd, QDateTime dateTime,
ui->time->setText(time); double dialFreq, QString myCall, QString myGrid,
m_dialFreq=dialFreq; bool noSuffix, bool toRTTY, bool dBtoComments)
m_myCall=myCall; {
m_myGrid=myGrid; ui->call->setText(hisCall);
QString band=""; ui->grid->setText(hisGrid);
if(dialFreq>0.135 and dialFreq<0.139) band="2200m"; ui->txPower->setText("");
if(dialFreq>0.45 and dialFreq<0.55) band="630m"; ui->comments->setText("");
if(dialFreq>1.8 and dialFreq<2.0) band="160m"; if (ui->cbTxPower->isChecked ()) ui->txPower->setText(m_txPower);
if(dialFreq>3.5 and dialFreq<4.0) band="80m"; if (ui->cbComments->isChecked ()) ui->comments->setText(m_comments);
if(dialFreq>5.1 and dialFreq<5.45) band="60m"; if(dBtoComments) {
if(dialFreq>7.0 and dialFreq<7.3) band="40m"; QString t=mode;
if(dialFreq>10.0 and dialFreq<10.15) band="30m"; if(rptSent!="") t+=" Sent: " + rptSent;
if(dialFreq>14.0 and dialFreq<14.35) band="20m"; if(rptRcvd!="") t+=" Rcvd: " + rptRcvd;
if(dialFreq>18.068 and dialFreq<18.168) band="17m"; ui->comments->setText(t);
if(dialFreq>21.0 and dialFreq<21.45) band="15m"; }
if(dialFreq>24.890 and dialFreq<24.990) band="12m"; if(noSuffix and mode.mid(0,3)=="JT9") mode="JT9";
if(dialFreq>28.0 and dialFreq<29.7) band="10m"; if(toRTTY and mode.mid(0,3)=="JT9") mode="RTTY";
if(dialFreq>50.0 and dialFreq<54.0) band="6m"; ui->mode->setText(mode);
if(dialFreq>70.0 and dialFreq<71.0) band="4m"; ui->sent->setText(rptSent);
if(dialFreq>144.0 and dialFreq<148.0) band="2m"; ui->rcvd->setText(rptRcvd);
if(dialFreq>222.0 and dialFreq<225.0) band="1.25m"; m_dateTime=dateTime;
if(dialFreq>420.0 and dialFreq<450.0) band="70cm"; QString date=dateTime.toString("yyyy-MM-dd");
if(dialFreq>902.0 and dialFreq<928.0) band="33cm"; ui->date->setText(date);
if(dialFreq>1240.0 and dialFreq<1300.0) band="23cm"; QString time=dateTime.toString("hhmm");
if(dialFreq>2300.0 and dialFreq<2450.0) band="13cm"; ui->time->setText(time);
if(dialFreq>3300.0 and dialFreq<3500.0) band="9cm"; m_dialFreq=dialFreq;
if(dialFreq>5650.0 and dialFreq<5925.0) band="6cm"; m_myCall=myCall;
if(dialFreq>10000.0 and dialFreq<10500.0) band="3cm"; m_myGrid=myGrid;
if(dialFreq>24000.0 and dialFreq<24250.0) band="1.25cm"; QString band="";
if(dialFreq>47000.0 and dialFreq<47200.0) band="6mm"; if(dialFreq>0.135 and dialFreq<0.139) band="2200m";
if(dialFreq>75500.0 and dialFreq<81000.0) band="4mm"; if(dialFreq>0.45 and dialFreq<0.55) band="630m";
ui->band->setText(band); if(dialFreq>1.8 and dialFreq<2.0) band="160m";
ui->cbTxPower->setChecked(m_saveTxPower); if(dialFreq>3.5 and dialFreq<4.0) band="80m";
ui->cbComments->setChecked(m_saveComments); if(dialFreq>5.1 and dialFreq<5.45) band="60m";
} if(dialFreq>7.0 and dialFreq<7.3) band="40m";
if(dialFreq>10.0 and dialFreq<10.15) band="30m";
void LogQSO::accept() if(dialFreq>14.0 and dialFreq<14.35) band="20m";
{ if(dialFreq>18.068 and dialFreq<18.168) band="17m";
QString hisCall,hisGrid,mode,rptSent,rptRcvd,date,time,band; if(dialFreq>21.0 and dialFreq<21.45) band="15m";
QString comments,name; if(dialFreq>24.890 and dialFreq<24.990) band="12m";
if(dialFreq>28.0 and dialFreq<29.7) band="10m";
hisCall=ui->call->text(); if(dialFreq>50.0 and dialFreq<54.0) band="6m";
hisGrid=ui->grid->text(); if(dialFreq>70.0 and dialFreq<71.0) band="4m";
mode=ui->mode->text(); if(dialFreq>144.0 and dialFreq<148.0) band="2m";
rptSent=ui->sent->text(); if(dialFreq>222.0 and dialFreq<225.0) band="1.25m";
rptRcvd=ui->rcvd->text(); if(dialFreq>420.0 and dialFreq<450.0) band="70cm";
date=ui->date->text(); if(dialFreq>902.0 and dialFreq<928.0) band="33cm";
date=date.mid(0,4) + date.mid(5,2) + date.mid(8,2); if(dialFreq>1240.0 and dialFreq<1300.0) band="23cm";
time=ui->time->text(); if(dialFreq>2300.0 and dialFreq<2450.0) band="13cm";
band=ui->band->text(); if(dialFreq>3300.0 and dialFreq<3500.0) band="9cm";
name=ui->name->text(); if(dialFreq>5650.0 and dialFreq<5925.0) band="6cm";
m_txPower=ui->txPower->text(); if(dialFreq>10000.0 and dialFreq<10500.0) band="3cm";
comments=ui->comments->text(); if(dialFreq>24000.0 and dialFreq<24250.0) band="1.25cm";
m_comments=comments; if(dialFreq>47000.0 and dialFreq<47200.0) band="6mm";
QString strDialFreq(QString::number(m_dialFreq,'f',6)); if(dialFreq>75500.0 and dialFreq<81000.0) band="4mm";
ui->band->setText(band);
//Log this QSO to file "wsjtx_log.adi"
QFile f2("wsjtx_log.adi"); show ();
if(!f2.open(QIODevice::Text | QIODevice::Append)) { }
QMessageBox m;
m.setText("Cannot open file \"wsjtx_log.adi\"."); void LogQSO::accept()
m.exec(); {
} else { QString hisCall,hisGrid,mode,rptSent,rptRcvd,date,time,band;
QTextStream out(&f2); QString comments,name;
if(f2.size()==0) out << "WSJT-X ADIF Export<eoh>" << endl;
hisCall=ui->call->text();
QString t; hisGrid=ui->grid->text();
t="<call:" + QString::number(hisCall.length()) + ">" + hisCall; mode=ui->mode->text();
t+=" <gridsquare:" + QString::number(hisGrid.length()) + ">" + hisGrid; rptSent=ui->sent->text();
t+=" <mode:" + QString::number(mode.length()) + ">" + mode; rptRcvd=ui->rcvd->text();
t+=" <rst_sent:" + QString::number(rptSent.length()) + ">" + rptSent; date=ui->date->text();
t+=" <rst_rcvd:" + QString::number(rptRcvd.length()) + ">" + rptRcvd; date=date.mid(0,4) + date.mid(5,2) + date.mid(8,2);
t+=" <qso_date:8>" + date; time=ui->time->text();
t+=" <time_on:4>" + time; band=ui->band->text();
t+=" <band:" + QString::number(band.length()) + ">" + band; name=ui->name->text();
t+=" <freq:" + QString::number(strDialFreq.length()) + ">" + strDialFreq; m_txPower=ui->txPower->text();
t+=" <station_callsign:" + QString::number(m_myCall.length()) + ">" + comments=ui->comments->text();
m_myCall; m_comments=comments;
t+=" <my_gridsquare:" + QString::number(m_myGrid.length()) + ">" + QString strDialFreq(QString::number(m_dialFreq,'f',6));
m_myGrid;
if(m_txPower!="") t+= " <tx_pwr:" + QString::number(m_txPower.length()) + //Log this QSO to file "wsjtx_log.adi"
">" + m_txPower; QFile f2("wsjtx_log.adi");
if(comments!="") t+=" <comment:" + QString::number(comments.length()) + if(!f2.open(QIODevice::Text | QIODevice::Append)) {
">" + comments; QMessageBox m;
if(name!="") t+=" <name:" + QString::number(name.length()) + m.setText("Cannot open file \"wsjtx_log.adi\".");
">" + name; m.exec();
t+=" <eor>"; } else {
out << t << endl; QTextStream out(&f2);
f2.close(); if(f2.size()==0) out << "WSJT-X ADIF Export<eoh>" << endl;
}
QString t;
//Log this QSO to file "wsjtx.log" t="<call:" + QString::number(hisCall.length()) + ">" + hisCall;
QFile f("wsjtx.log"); t+=" <gridsquare:" + QString::number(hisGrid.length()) + ">" + hisGrid;
if(!f.open(QIODevice::Text | QIODevice::Append)) { t+=" <mode:" + QString::number(mode.length()) + ">" + mode;
QMessageBox m; t+=" <rst_sent:" + QString::number(rptSent.length()) + ">" + rptSent;
m.setText("Cannot open file \"wsjtx.log\"."); t+=" <rst_rcvd:" + QString::number(rptRcvd.length()) + ">" + rptRcvd;
m.exec(); t+=" <qso_date:8>" + date;
} else { t+=" <time_on:4>" + time;
QString logEntry=m_dateTime.date().toString("yyyy-MMM-dd,") + t+=" <band:" + QString::number(band.length()) + ">" + band;
m_dateTime.time().toString("hh:mm,") + hisCall + "," + t+=" <freq:" + QString::number(strDialFreq.length()) + ">" + strDialFreq;
hisGrid + "," + strDialFreq + "," + mode + t+=" <station_callsign:" + QString::number(m_myCall.length()) + ">" +
"," + rptSent + "," + rptRcvd; m_myCall;
if(m_txPower!="") logEntry += "," + m_txPower; t+=" <my_gridsquare:" + QString::number(m_myGrid.length()) + ">" +
if(comments!="") logEntry += "," + comments; m_myGrid;
if(name!="") logEntry += "," + name; if(m_txPower!="") t+= " <tx_pwr:" + QString::number(m_txPower.length()) +
QTextStream out(&f); ">" + m_txPower;
out << logEntry << endl; if(comments!="") t+=" <comment:" + QString::number(comments.length()) +
f.close(); ">" + comments;
} if(name!="") t+=" <name:" + QString::number(name.length()) +
">" + name;
//Clean up and finish logging t+=" <eor>";
emit(acceptQSO(true)); out << t << endl;
QDialog::accept(); f2.close();
} }
void LogQSO::reject() //Log this QSO to file "wsjtx.log"
{ QFile f("wsjtx.log");
emit(acceptQSO(false)); if(!f.open(QIODevice::Text | QIODevice::Append)) {
QDialog::reject(); QMessageBox m;
} m.setText("Cannot open file \"wsjtx.log\".");
m.exec();
void LogQSO::on_cbTxPower_toggled(bool checked) } else {
{ QString logEntry=m_dateTime.date().toString("yyyy-MMM-dd,") +
m_saveTxPower=checked; m_dateTime.time().toString("hh:mm,") + hisCall + "," +
} hisGrid + "," + strDialFreq + "," + mode +
"," + rptSent + "," + rptRcvd;
void LogQSO::on_cbComments_toggled(bool checked) if(m_txPower!="") logEntry += "," + m_txPower;
{ if(comments!="") logEntry += "," + comments;
m_saveComments=checked; if(name!="") logEntry += "," + name;
} QTextStream out(&f);
out << logEntry << endl;
f.close();
}
//Clean up and finish logging
emit(acceptQSO(true));
QDialog::accept();
}
void LogQSO::reject()
{
emit(acceptQSO(false));
QDialog::reject();
}
// 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)
{
storeSettings ();
QDialog::hideEvent (e);
}

107
logqso.h
View File

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

View File

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

View File

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

View File

@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>760</width> <width>760</width>
<height>552</height> <height>523</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy"> <property name="sizePolicy">
@ -1148,6 +1148,19 @@ p, li { white-space: pre-wrap; }
</item> </item>
</layout> </layout>
</item> </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"> <item row="5" column="3" rowspan="2" colspan="2">
<widget class="QLabel" name="labUTC"> <widget class="QLabel" name="labUTC">
<property name="sizePolicy"> <property name="sizePolicy">
@ -1193,6 +1206,16 @@ p, li { white-space: pre-wrap; }
</property> </property>
</widget> </widget>
</item> </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"> <item row="0" column="8" rowspan="7">
<widget class="QFrame" name="frame_2"> <widget class="QFrame" name="frame_2">
<property name="sizePolicy"> <property name="sizePolicy">
@ -2062,16 +2085,19 @@ p, li { white-space: pre-wrap; }
</item> </item>
</layout> </layout>
</item> </item>
<item row="1" column="6"> <item row="1" column="2">
<widget class="QPushButton" name="pbTxMode"> <widget class="QPushButton" name="readFreq">
<property name="enabled"> <property name="maximumSize">
<bool>false</bool> <size>
<width>15</width>
<height>15</height>
</size>
</property> </property>
<property name="toolTip"> <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>
<property name="text"> <property name="text">
<string>Tx JT9</string> <string/>
</property> </property>
</widget> </widget>
</item> </item>
@ -2091,32 +2117,6 @@ p, li { white-space: pre-wrap; }
</property> </property>
</spacer> </spacer>
</item> </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"> <item row="0" column="0" colspan="3">
<widget class="QComboBox" name="bandComboBox"> <widget class="QComboBox" name="bandComboBox">
<property name="sizePolicy"> <property name="sizePolicy">
@ -2225,6 +2225,35 @@ p, li { white-space: pre-wrap; }
</item> </item>
</widget> </widget>
</item> </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> </layout>
</item> </item>
</layout> </layout>
@ -2235,7 +2264,7 @@ p, li { white-space: pre-wrap; }
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>760</width> <width>760</width>
<height>20</height> <height>25</height>
</rect> </rect>
</property> </property>
<widget class="QMenu" name="menuFile"> <widget class="QMenu" name="menuFile">

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -38,12 +38,15 @@ bool SoundInput::audioError () const
return result; 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(); stop();
QAudioFormat format (device.preferredFormat()); QAudioFormat format (device.preferredFormat());
format.setChannelCount (1); format.setChannelCount (channels);
format.setCodec ("audio/pcm"); format.setCodec ("audio/pcm");
format.setSampleRate (12000); format.setSampleRate (12000);
format.setSampleType (QAudioFormat::SignedInt); format.setSampleType (QAudioFormat::SignedInt);

View File

@ -32,7 +32,7 @@ Q_SIGNALS:
public Q_SLOTS: public Q_SLOTS:
// sink must exist from the start call to any following stop () call // 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(); void stop();
private: private:

View File

@ -3,6 +3,7 @@
#include <QDateTime> #include <QDateTime>
#include <QAudioDeviceInfo> #include <QAudioDeviceInfo>
#include <QAudioOutput> #include <QAudioOutput>
#include <qmath.h>
#include <QDebug> #include <QDebug>
#if defined (WIN32) #if defined (WIN32)
@ -52,18 +53,15 @@ SoundOutput::SoundOutput (QIODevice * source)
Q_ASSERT (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 ()); QAudioFormat format (device.preferredFormat ());
#ifdef UNIX format.setChannelCount (channels);
format.setChannelCount (2);
#else
format.setChannelCount (1);
#endif
format.setCodec ("audio/pcm"); format.setCodec ("audio/pcm");
format.setSampleRate (48000); format.setSampleRate (48000);
format.setSampleType (QAudioFormat::SignedInt); format.setSampleType (QAudioFormat::SignedInt);
@ -79,6 +77,7 @@ void SoundOutput::startStream (QAudioDeviceInfo const& device)
m_stream.reset (new QAudioOutput (device, format, this)); m_stream.reset (new QAudioOutput (device, format, this));
audioError (); audioError ();
m_stream->setVolume (m_volume);
connect (m_stream.data(), &QAudioOutput::stateChanged, this, &SoundOutput::handleStateChanged); 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 // This buffer size is critical since for proper sound streaming. If
// thread. If it is too short; high activity levels on the GUI can // it is too short; high activity levels on the machine can starve
// starve the audio buffer. On the other hand the Windows // the audio buffer. On the other hand the Windows implementation
// implementation seems to take the length of the buffer in time to // seems to take the length of the buffer in time to stop the audio
// stop the audio stream even if reset() is used. // 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. // where things are probably broken.
// //
// we have to set this before every start on the stream because the // 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 () void SoundOutput::stopStream ()
{ {
if (m_stream) if (m_stream)

View File

@ -17,6 +17,7 @@ class SoundOutput : public QObject
Q_OBJECT; Q_OBJECT;
Q_PROPERTY(bool running READ isRunning); Q_PROPERTY(bool running READ isRunning);
Q_PROPERTY(unsigned attenuation READ attenuation WRITE setAttenuation RESET resetAttenuation);
private: private:
Q_DISABLE_COPY (SoundOutput); Q_DISABLE_COPY (SoundOutput);
@ -26,12 +27,18 @@ class SoundOutput : public QObject
~SoundOutput (); ~SoundOutput ();
bool isRunning() const {return m_active;} bool isRunning() const {return m_active;}
qreal attenuation () const;
public Q_SLOTS: private Q_SLOTS:
void startStream (QAudioDeviceInfo const& device); /* 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 suspend ();
void resume (); void resume ();
void stopStream (); void stopStream ();
void setAttenuation (qreal); /* unsigned */
void resetAttenuation (); /* to zero */
Q_SIGNALS: Q_SIGNALS:
void error (QString message) const; void error (QString message) const;
@ -49,6 +56,7 @@ private:
QIODevice * m_source; QIODevice * m_source;
bool volatile m_active; bool volatile m_active;
QAudioDeviceInfo m_currentDevice; QAudioDeviceInfo m_currentDevice;
qreal m_volume;
}; };
#endif #endif

View File

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

View File

@ -1,88 +1,93 @@
#ifndef WIDEGRAPH_H #ifndef WIDEGRAPH_H
#define WIDEGRAPH_H #define WIDEGRAPH_H
#include <QDialog>
#include <QDialog>
namespace Ui { #include <QScopedPointer>
class WideGraph;
} namespace Ui {
class WideGraph;
class WideGraph : public QDialog }
{
Q_OBJECT class QSettings;
public: class WideGraph : public QDialog
explicit WideGraph(QWidget *parent = 0); {
~WideGraph(); Q_OBJECT
void dataSink2(float s[], float df3, int ihsym, int ndiskdata); public:
void setRxFreq(int n); explicit WideGraph(QSettings *, QWidget *parent = 0);
int rxFreq(); ~WideGraph ();
int nSpan();
int nStartFreq(); void dataSink2(float s[], float df3, int ihsym, int ndiskdata);
int getFmin(); void setRxFreq(int n);
int getFmax(); int rxFreq();
float fSpan(); int nSpan();
void saveSettings(); int nStartFreq();
void setRxRange(int fMin); int getFmin();
void setFmin(int n); int getFmax();
void setFsample(int n); float fSpan();
void setPeriod(int ntrperiod, int nsps); void saveSettings();
void setTxFreq(int n); void setRxRange(int fMin);
void setMode(QString mode); void setFsample(int n);
void setModeTx(QString modeTx); void setPeriod(int ntrperiod, int nsps);
void setSlope(double d); void setTxFreq(int n);
void setLockTxFreq(bool b); void setMode(QString mode);
double getSlope(); void setModeTx(QString modeTx);
double fGreen(); void setSlope(double d);
void readPalette(QString fileName); void setLockTxFreq(bool b);
double getSlope();
qint32 m_rxFreq; double fGreen();
qint32 m_txFreq; void readPalette(QString fileName);
signals: signals:
void freezeDecode2(int n); void freezeDecode2(int n);
void f11f12(int n); void f11f12(int n);
void setXIT2(int n); void setXIT2(int n);
void setFreq3(int rxFreq, int txFreq); void setFreq3(int rxFreq, int txFreq);
public slots: public slots:
void wideFreezeDecode(int n); void wideFreezeDecode(int n);
void setFreq2(int rxFreq, int txFreq); void setFreq2(int rxFreq, int txFreq);
void setDialFreq(double d); void setDialFreq(double d);
protected: protected:
virtual void keyPressEvent( QKeyEvent *e ); virtual void keyPressEvent( QKeyEvent *e );
void closeEvent (QCloseEvent *);
private slots:
void on_waterfallAvgSpinBox_valueChanged(int arg1); private slots:
void on_freqSpanSpinBox_valueChanged(int arg1); void on_waterfallAvgSpinBox_valueChanged(int arg1);
void on_zeroSpinBox_valueChanged(int arg1); void on_freqSpanSpinBox_valueChanged(int arg1);
void on_gainSpinBox_valueChanged(int arg1); void on_zeroSpinBox_valueChanged(int arg1);
void on_spec2dComboBox_currentIndexChanged(const QString &arg1); void on_gainSpinBox_valueChanged(int arg1);
void on_fMinSpinBox_valueChanged(int n); void on_spec2dComboBox_currentIndexChanged(const QString &arg1);
void on_slopeSpinBox_valueChanged(double d); void on_fMinSpinBox_valueChanged(int n);
void on_fStartSpinBox_valueChanged(int n); void on_slopeSpinBox_valueChanged(double d);
void on_paletteComboBox_activated(const QString &palette); void on_fStartSpinBox_valueChanged(int n);
void on_paletteComboBox_activated(const QString &palette);
private:
double m_slope; private:
double m_dialFreq; QScopedPointer<Ui::WideGraph> ui;
QSettings * m_settings;
qint32 m_waterfallAvg;
qint32 m_fSample; qint32 m_rxFreq;
qint32 m_TRperiod; qint32 m_txFreq;
qint32 m_nsps;
qint32 m_ntr0; double m_slope;
qint32 m_fMin; double m_dialFreq;
qint32 m_fMax;
qint32 m_waterfallAvg;
bool m_lockTxFreq; qint32 m_fSample;
qint32 m_TRperiod;
QString m_mode; qint32 m_nsps;
QString m_modeTx; qint32 m_ntr0;
QString m_waterfallPalette; qint32 m_fMin;
qint32 m_fMax;
Ui::WideGraph *ui;
}; bool m_lockTxFreq;
#endif // WIDEGRAPH_H QString m_mode;
QString m_modeTx;
QString m_waterfallPalette;
};
#endif // WIDEGRAPH_H

View File

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