Added audio channel support.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

105
AudioDevice.hpp Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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