Compare commits
384 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b60dfb0ec0 | |||
| d78a59f12d | |||
| da1e684eda | |||
| ef8c2a5725 | |||
| 26766283c3 | |||
| 40573a38bb | |||
| 718e35eacd | |||
| fb727ccfc7 | |||
| 8699ec2129 | |||
| d28d556309 | |||
| 98760a6d42 | |||
| 8800befef8 | |||
| 4df475db32 | |||
| ded608107d | |||
| 92cf749129 | |||
| 9de2e59b46 | |||
| b5b759538b | |||
| c6b327dba7 | |||
| f6ebfccc96 | |||
| f0e1a4c4b6 | |||
| 18e1235a2e | |||
| 1f3168b115 | |||
| b34956457c | |||
| c269d96bed | |||
| 0bcfdfef04 | |||
| a21e46cb4a | |||
| 649910302c | |||
| 726c145187 | |||
| c1a3975231 | |||
| bf5570cacd | |||
| 24f1c5f343 | |||
| 7a4663e742 | |||
| 7728483481 | |||
| a62194b4d1 | |||
| ee264e2e01 | |||
| bf49b9b167 | |||
| 4e3d5b0d89 | |||
| 201252bb88 | |||
| c036a72636 | |||
| ee9ed66f82 | |||
| cc63277adb | |||
| c6407b2479 | |||
| 5b9c71f380 | |||
| 77405cc968 | |||
| 7dc0298b18 | |||
| 8e0e94e8bb | |||
| 699af49718 | |||
| 69c03c5e94 | |||
| 5215fd324d | |||
| f706685cc9 | |||
| 3be107b348 | |||
| 04fa0f42ad | |||
| 618616af91 | |||
| bc3e507af1 | |||
| ca5012c3b2 | |||
| 6a0ef6d407 | |||
| 811ecccea3 | |||
| ec5e4f9978 | |||
| 2e52b6d8f2 | |||
| 1e41c5e792 | |||
| eaff44aa38 | |||
| d3fa09f20b | |||
| cfeed7fc87 | |||
| f332177034 | |||
| 08d1f007fa | |||
| 88d8070db4 | |||
| b961d03045 | |||
| 2159ea0cfb | |||
| cb7f84d952 | |||
| 670faf3397 | |||
| 138063a112 | |||
| 1f7d6a9f3a | |||
| fb956d9141 | |||
| c1fd31dc24 | |||
| 35b478f791 | |||
| fc4a6d35a5 | |||
| 43a6dbc42d | |||
| f1ffc1de9d | |||
| 8ec88432bd | |||
| 1a03619a2f | |||
| 2a320ddcdd | |||
| 41321561bc | |||
| 7bc78d3496 | |||
| 70bc0e7784 | |||
| 16da1235a0 | |||
| d6e79ad902 | |||
| 71d52dad63 | |||
| 26f16b5a99 | |||
| 6d6212a8c0 | |||
| 3fb66f888c | |||
| 16b5193216 | |||
| 30f18c69d8 | |||
| fcf40e6f3b | |||
| d9ecd5a94e | |||
| d01d230f07 | |||
| 5eb5e77668 | |||
| a1ad346cea | |||
| ba3e521cf3 | |||
| 28fbce38b4 | |||
| ea76d0e8d2 | |||
| 8aa0430834 | |||
| f635ba3a33 | |||
| 9e761ba144 | |||
| cd1f961cac | |||
| 2f9e1201b3 | |||
| 145cb16fde | |||
| f450683e6e | |||
| 09da8a22c7 | |||
| 49da619a8f | |||
| ddc1380b1e | |||
| b389013945 | |||
| 1621670d1f | |||
| e855a84bb9 | |||
| 06fef4f811 | |||
| 6181928c6c | |||
| 5d7ef702ab | |||
| 471e85ee97 | |||
| 3afcbd32c1 | |||
| d0d7aaa286 | |||
| eada85c04d | |||
| 865cfa31f9 | |||
| 5b43050a3a | |||
| 1719954071 | |||
| e4cfb820a3 | |||
| 34c6f83642 | |||
| 05c45ed794 | |||
| d7985797a0 | |||
| 18dec96843 | |||
| d75c8fdc83 | |||
| b8ccd5d810 | |||
| 305c0fdb12 | |||
| b54e3e89aa | |||
| 084dd77b42 | |||
| 9f3f9b267b | |||
| 54d9afd69d | |||
| 36437e57bf | |||
| c001303bba | |||
| cc6e28d5a7 | |||
| 2add8ff1b7 | |||
| 0d785888d8 | |||
| 473a49428d | |||
| 2a65e10300 | |||
| 0569bb0167 | |||
| f7d253e7e3 | |||
| 31137082f9 | |||
| a43c913a19 | |||
| 9e77bc5d28 | |||
| 6472314329 | |||
| 9858403a95 | |||
| 7b3d8539d5 | |||
| e5f07e3a0d | |||
| e3ac4b22c3 | |||
| 7128daf79e | |||
| 6b8662f7b8 | |||
| 28c6e2af0a | |||
| 720bd6b22a | |||
| f4ae642cec | |||
| d11dcd0830 | |||
| 980ffcb22c | |||
| 7a248b69c4 | |||
| bd357ed4c4 | |||
| 862e827ddf | |||
| eb778d4df9 | |||
| c72857aa76 | |||
| 4fc50629e6 | |||
| 2d7317aea4 | |||
| 7fff608c18 | |||
| a24e4429ea | |||
| fdac8556f5 | |||
| 3a46548527 | |||
| dc6d161c6f | |||
| 471c303174 | |||
| 854cf81f36 | |||
| b351b72037 | |||
| 0ca7b0e5ed | |||
| b526e274f8 | |||
| e032713690 | |||
| 816bfa4b63 | |||
| 952d9d7080 | |||
| 56d457a056 | |||
| feeb6540a7 | |||
| de2889c057 | |||
| 5cbcb5b8a0 | |||
| 4c386248da | |||
| 3841e1901f | |||
| d2afa493aa | |||
| cbffb413a5 | |||
| 066cdb8423 | |||
| d0c61578f0 | |||
| e7b3a5d41c | |||
| 7c34fd3c4a | |||
| e211185977 | |||
| 24392fdaf3 | |||
| 5313706818 | |||
| 0426b3a6ce | |||
| 4d219d62f0 | |||
| 4411d9210e | |||
| e7e7b49a5d | |||
| e4d4487d23 | |||
| 1ad0efa634 | |||
| 54a7085c47 | |||
| 2fd5493572 | |||
| 70f5e6c337 | |||
| 7bf4f6c172 | |||
| 05a625dfe8 | |||
| 8bec6fdce0 | |||
| e37089c78a | |||
| 8ceef83f2e | |||
| b3df2985b7 | |||
| e3439fd4af | |||
| 9a097e20c9 | |||
| fed50180eb | |||
| 48a11bf491 | |||
| 3e853f4250 | |||
| 8901406755 | |||
| aa3327342d | |||
| fe31f54b97 | |||
| 581d40010f | |||
| 9dc2c99ebd | |||
| 722dd5571a | |||
| a8d97d09b4 | |||
| 52da12da01 | |||
| a6e6ec7a8a | |||
| 6f111cdb73 | |||
| aee8de2b64 | |||
| 01e64db6b7 | |||
| b7718ca528 | |||
| 6ddbd47f81 | |||
| 510628420b | |||
| 6215afd18d | |||
| 160f02ba15 | |||
| 587ec5ee3c | |||
| 3a0e5341df | |||
| 481b07c682 | |||
| fe3b2ab80f | |||
| c5451a2029 | |||
| 3058dcb152 | |||
| 094d820882 | |||
| 477adc81ac | |||
| 81e5aa00f0 | |||
| 7aff060ec7 | |||
| b216063f60 | |||
| 9055d50e76 | |||
| 8d4db7d376 | |||
| bb91fac20d | |||
| 335b6d13f6 | |||
| 8851cf5fa9 | |||
| 2d88671034 | |||
| 74ab440249 | |||
| 18b59e1b52 | |||
| a882e1d9a5 | |||
| 8b62c5b9a8 | |||
| 6bbf7321ce | |||
| 40eb00eff3 | |||
| eedd62cf0b | |||
| c24e931f09 | |||
| daa8cc2c3e | |||
| d2210dc8c9 | |||
| 32fcabd2af | |||
| 3b847a58c6 | |||
| 15bf364e5e | |||
| d7c7ab4e25 | |||
| 0647972591 | |||
| 3d590e93d5 | |||
| 19e9428218 | |||
| 7a63002ccd | |||
| 5ba0ee48d2 | |||
| eb3bc0f1f5 | |||
| 3c9bc48f74 | |||
| f54e632d99 | |||
| 62a464d1ac | |||
| e5883a14b9 | |||
| b4b1abd62d | |||
| 811e0edf19 | |||
| 378bbcd6e3 | |||
| 2c28d6f6f7 | |||
| 33c26a5f05 | |||
| 9dc708900e | |||
| 925aade1a2 | |||
| 6aad422cd8 | |||
| c27923b425 | |||
| a9e44b5d4e | |||
| c5236ed22f | |||
| 6f43f37228 | |||
| 39b67706e4 | |||
| d1bd82af26 | |||
| d91f96da42 | |||
| 63627b8b92 | |||
| 541f89a96e | |||
| 87eff6070d | |||
| 6cd22b48a9 | |||
| 7ab8e9a8d6 | |||
| 962a94bb87 | |||
| f179c01210 | |||
| 27cdd98cb7 | |||
| 4334bffa25 | |||
| 87e63e2817 | |||
| 2399563041 | |||
| 72bf58ad4c | |||
| 22432c7fea | |||
| 38ab24ba79 | |||
| ae6dccc183 | |||
| 88455247a4 | |||
| fd29d6a931 | |||
| c9f0cce564 | |||
| ad748865a6 | |||
| f304d3c6e1 | |||
| 219d434006 | |||
| b94f93780f | |||
| ce0aceb33c | |||
| 6439395833 | |||
| f5afb50041 | |||
| 52416fbf9a | |||
| aa065ec32d | |||
| 6aef6bddb8 | |||
| 56a2b13615 | |||
| ae640ed40c | |||
| a1eb193278 | |||
| 3022c1eee8 | |||
| a24318538b | |||
| 960d1b5e5b | |||
| 460f960a87 | |||
| 7cc063737c | |||
| e85eac086b | |||
| 3f8a84cd0f | |||
| 0f225c2be4 | |||
| 401ea39e5b | |||
| 9d9dd36b26 | |||
| 9515a069f3 | |||
| 4bd52f2e04 | |||
| a14b524056 | |||
| b192496ba5 | |||
| 9915fd497b | |||
| e8b5566c7a | |||
| db6feba19c | |||
| 4a3bd4b385 | |||
| f5ae800916 | |||
| 9423640e52 | |||
| 952cc0b844 | |||
| 0bd7a74103 | |||
| 82a0cdd0cf | |||
| 7f187f4cf8 | |||
| f2ba541f09 | |||
| e9d2d59842 | |||
| bda9a5202e | |||
| 40e1bfab0e | |||
| b031a2cdbe | |||
| a2c6451b47 | |||
| 3f6c87b200 | |||
| fa4c39495d | |||
| 5f3b74338c | |||
| d1ccbc599b | |||
| 6e036b7d58 | |||
| 1629415dc1 | |||
| 08cf869125 | |||
| 03bd44ae39 | |||
| 14626978c0 | |||
| dd43f0db84 | |||
| 5646268faf | |||
| 5d21fdf1dc | |||
| 5d2ba76c17 | |||
| 7bd86ca177 | |||
| 59b1a3b011 | |||
| ce2c045458 | |||
| 218c5b3d47 | |||
| 27ae28a889 | |||
| 1a2596224a | |||
| 82915540b4 | |||
| 73c6dd50fb | |||
| ee48d8fd86 | |||
| d8a16f4a42 | |||
| 5ef440faf6 | |||
| 9d9ae62526 | |||
| 6b9c9b4ceb | |||
| 1febb18495 | |||
| 43401c3c26 | |||
| 55928be661 | |||
| a5f8593b3d | |||
| 07f1594d0a | |||
| b6dd6aadc8 | |||
| b9b334c6cf | |||
| fec45aa0ad | |||
| 2ef4e90710 | |||
| a0dc7bc013 |
@@ -242,6 +242,13 @@ void APRSISClient::processQueue(bool disconnect){
|
||||
// don't process queue if there's nothing to process
|
||||
if(m_frameQueue.isEmpty()) return;
|
||||
|
||||
// don't process queue if there's no host
|
||||
if(m_host.isEmpty() || m_port == 0){
|
||||
// no host, so let's clear the queue and exit
|
||||
m_frameQueue.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
// 1. connect (and read)
|
||||
// 2. login (and read)
|
||||
// 3. for each raw frame in queue, send
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
#include "AudioDecoder.h"
|
||||
|
||||
AudioDecoder::AudioDecoder(QObject *parent) :
|
||||
QIODevice(parent),
|
||||
m_state { AudioDecoder::Stopped },
|
||||
m_input { &m_data, this },
|
||||
m_output { &m_data, this },
|
||||
m_init { false },
|
||||
m_isDecodingFinished { false }
|
||||
{
|
||||
setOpenMode(QIODevice::ReadOnly);
|
||||
|
||||
m_decoder = new QAudioDecoder(this);
|
||||
connect(m_decoder, &QAudioDecoder::bufferReady, this, &AudioDecoder::bufferReady);
|
||||
connect(m_decoder, static_cast<void(QAudioDecoder::*)(QAudioDecoder::Error)>(&QAudioDecoder::error), this, &AudioDecoder::errored);
|
||||
connect(m_decoder, &QAudioDecoder::finished, this, &AudioDecoder::finished);
|
||||
}
|
||||
|
||||
AudioDecoder::~AudioDecoder(){
|
||||
stop();
|
||||
}
|
||||
|
||||
// initialize an audio device
|
||||
void AudioDecoder::init(const QAudioFormat &format) {
|
||||
m_decoder->setAudioFormat(format);
|
||||
|
||||
if (!m_output.open(QIODevice::ReadOnly) || !m_input.open(QIODevice::WriteOnly)){
|
||||
m_init = false;
|
||||
return;
|
||||
}
|
||||
|
||||
m_init = true;
|
||||
emit initialized();
|
||||
}
|
||||
|
||||
// play an audio file
|
||||
void AudioDecoder::start(const QString &filePath){
|
||||
if(!m_init){
|
||||
return;
|
||||
}
|
||||
|
||||
if(m_state == AudioDecoder::Decoding){
|
||||
return;
|
||||
}
|
||||
|
||||
m_state = AudioDecoder::Decoding;
|
||||
m_decoder->setSourceFilename(filePath);
|
||||
m_decoder->start();
|
||||
}
|
||||
|
||||
// Stop playing audio
|
||||
void AudioDecoder::stop() {
|
||||
m_state = AudioDecoder::Stopped;
|
||||
m_decoder->stop();
|
||||
m_data.clear();
|
||||
m_isDecodingFinished = false;
|
||||
}
|
||||
|
||||
|
||||
// io device, read into buffer.
|
||||
qint64 AudioDecoder::readData(char* data, qint64 maxlen) {
|
||||
memset(data, 0, maxlen);
|
||||
|
||||
if (m_state == AudioDecoder::Decoding){
|
||||
m_output.read(data, maxlen);
|
||||
|
||||
// Emulate QAudioProbe behaviour for audio data that is sent to output device
|
||||
if (maxlen > 0){
|
||||
QByteArray buff(data, maxlen);
|
||||
emit newData(buff);
|
||||
}
|
||||
|
||||
// Is finish of file
|
||||
if (atEnd()){
|
||||
stop();
|
||||
}
|
||||
}
|
||||
|
||||
return maxlen;
|
||||
}
|
||||
|
||||
// io device, unused.
|
||||
qint64 AudioDecoder::writeData(const char* data, qint64 len) {
|
||||
Q_UNUSED(data);
|
||||
Q_UNUSED(len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// io device, at end of device
|
||||
bool AudioDecoder::atEnd() const {
|
||||
bool value = m_output.size()
|
||||
&& m_output.atEnd()
|
||||
&& m_isDecodingFinished;
|
||||
return value;
|
||||
}
|
||||
|
||||
// handle buffered data ready
|
||||
void AudioDecoder::bufferReady() {
|
||||
const QAudioBuffer &buffer = m_decoder->read();
|
||||
if(!buffer.isValid()){
|
||||
return;
|
||||
}
|
||||
|
||||
const int length = buffer.byteCount();
|
||||
const char *data = buffer.constData<char>();
|
||||
|
||||
m_input.write(data, length);
|
||||
}
|
||||
|
||||
// handle buffered data decoding is finished
|
||||
void AudioDecoder::finished() {
|
||||
m_isDecodingFinished = true;
|
||||
}
|
||||
|
||||
// handle buffered data decoding error
|
||||
void AudioDecoder::errored(QAudioDecoder::Error /*error*/) {
|
||||
stop();
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
#ifndef AUDIODECODER_H
|
||||
#define AUDIODECODER_H
|
||||
|
||||
#include <QAudioDecoder>
|
||||
#include <QAudioFormat>
|
||||
#include <QBuffer>
|
||||
#include <QIODevice>
|
||||
#include <QPointer>
|
||||
|
||||
|
||||
class AudioDecoder :
|
||||
public QIODevice
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum State { Decoding, Stopped };
|
||||
explicit AudioDecoder(QObject *parent = 0);
|
||||
~AudioDecoder();
|
||||
|
||||
bool atEnd() const override;
|
||||
|
||||
public slots:
|
||||
void init(const QAudioFormat &format);
|
||||
void start(const QString &filePath);
|
||||
void stop();
|
||||
|
||||
protected:
|
||||
qint64 readData(char* data, qint64 maxlen) override;
|
||||
qint64 writeData(const char* data, qint64 len) override;
|
||||
|
||||
private:
|
||||
State m_state;
|
||||
QPointer<QAudioDecoder> m_decoder;
|
||||
QBuffer m_input;
|
||||
QBuffer m_output;
|
||||
QByteArray m_data;
|
||||
bool m_init;
|
||||
bool m_isDecodingFinished;
|
||||
|
||||
private slots:
|
||||
void bufferReady();
|
||||
void finished();
|
||||
void errored(QAudioDecoder::Error);
|
||||
|
||||
signals:
|
||||
void initialized();
|
||||
void newData(const QByteArray& data);
|
||||
};
|
||||
|
||||
#endif // AUDIODECODER_H
|
||||
@@ -180,6 +180,7 @@ set (wsjt_qt_CXXSRCS
|
||||
NetworkMessage.cpp
|
||||
Message.cpp
|
||||
MessageClient.cpp
|
||||
TCPClient.cpp
|
||||
LettersSpinBox.cpp
|
||||
HintedSpinBox.cpp
|
||||
RestrictedSpinBox.cpp
|
||||
@@ -226,10 +227,6 @@ set (wsjtx_CXXSRCS
|
||||
signalmeter.cpp
|
||||
plotter.cpp
|
||||
widegraph.cpp
|
||||
echograph.cpp
|
||||
echoplot.cpp
|
||||
fastgraph.cpp
|
||||
fastplot.cpp
|
||||
about.cpp
|
||||
astro.cpp
|
||||
messageaveraging.cpp
|
||||
@@ -243,6 +240,7 @@ set (wsjtx_CXXSRCS
|
||||
messagereplydialog.cpp
|
||||
keyeater.cpp
|
||||
APRSISClient.cpp
|
||||
SpotClient.cpp
|
||||
Inbox.cpp
|
||||
messagewindow.cpp
|
||||
mainwindow.cpp
|
||||
@@ -250,6 +248,13 @@ set (wsjtx_CXXSRCS
|
||||
main.cpp
|
||||
wsprnet.cpp
|
||||
WSPRBandHopping.cpp
|
||||
TransmitTextEdit.cpp
|
||||
WaveUtils.cpp
|
||||
WaveFile.cpp
|
||||
AudioDecoder.cpp
|
||||
NotificationAudio.cpp
|
||||
ProcessThread.cpp
|
||||
Decoder.cpp
|
||||
)
|
||||
|
||||
set (wsjt_CXXSRCS
|
||||
@@ -284,7 +289,6 @@ set (wsjt_FSRCS
|
||||
lib/jt4_decode.f90
|
||||
lib/jt65_decode.f90
|
||||
lib/jt65_mod.f90
|
||||
lib/ft8_decode.f90
|
||||
lib/jt9_decode.f90
|
||||
lib/options.f90
|
||||
lib/packjt.f90
|
||||
@@ -293,6 +297,16 @@ set (wsjt_FSRCS
|
||||
lib/timer_impl.f90
|
||||
lib/timer_module.f90
|
||||
lib/wavhdr.f90
|
||||
lib/js8a_module.f90
|
||||
lib/js8a_decode.f90
|
||||
lib/js8b_module.f90
|
||||
lib/js8b_decode.f90
|
||||
lib/js8c_module.f90
|
||||
lib/js8c_decode.f90
|
||||
lib/js8e_module.f90
|
||||
lib/js8e_decode.f90
|
||||
lib/js8i_module.f90
|
||||
lib/js8i_decode.f90
|
||||
|
||||
# remaining non-module sources
|
||||
lib/addit.f90
|
||||
@@ -304,11 +318,9 @@ set (wsjt_FSRCS
|
||||
lib/astro.f90
|
||||
lib/astrosub.f90
|
||||
lib/astro0.f90
|
||||
lib/avecho.f90
|
||||
lib/averms.f90
|
||||
lib/azdist.f90
|
||||
lib/badmsg.f90
|
||||
lib/ft8/baseline.f90
|
||||
lib/bpdecode40.f90
|
||||
lib/bpdecode144.f90
|
||||
lib/ft8/bpdecode174.f90
|
||||
@@ -348,7 +360,6 @@ set (wsjt_FSRCS
|
||||
lib/ft8/extractmessage174.f90
|
||||
lib/fano232.f90
|
||||
lib/fast9.f90
|
||||
lib/fast_decode.f90
|
||||
lib/fchisq.f90
|
||||
lib/fchisq0.f90
|
||||
lib/fchisq65.f90
|
||||
@@ -359,7 +370,6 @@ set (wsjt_FSRCS
|
||||
lib/filbig.f90
|
||||
lib/ft8/filt8.f90
|
||||
lib/fitcal.f90
|
||||
lib/fix_contest_msg.f90
|
||||
lib/flat1.f90
|
||||
lib/flat1a.f90
|
||||
lib/flat1b.f90
|
||||
@@ -375,20 +385,8 @@ set (wsjt_FSRCS
|
||||
lib/fqso_first.f90
|
||||
lib/freqcal.f90
|
||||
lib/ft8/ft8apset.f90
|
||||
lib/ft8/ft8b.f90
|
||||
lib/ft8/ft8code.f90
|
||||
lib/ft8/ft8_downsample.f90
|
||||
lib/ft8/ft8sim.f90
|
||||
lib/gen4.f90
|
||||
lib/gen65.f90
|
||||
lib/gen9.f90
|
||||
lib/geniscat.f90
|
||||
lib/ft8/genft8.f90
|
||||
lib/genmsk144.f90
|
||||
lib/genmsk40.f90
|
||||
lib/genqra64.f90
|
||||
lib/ft8/genft8refsig.f90
|
||||
lib/genwspr.f90
|
||||
lib/js8/genjs8.f90
|
||||
lib/geodist.f90
|
||||
lib/getlags.f90
|
||||
lib/getmet4.f90
|
||||
@@ -399,7 +397,6 @@ set (wsjt_FSRCS
|
||||
lib/ft8/h1.f90
|
||||
lib/hash.f90
|
||||
lib/hint65.f90
|
||||
lib/hspec.f90
|
||||
lib/indexx.f90
|
||||
lib/init_random_seed.f90
|
||||
lib/interleave4.f90
|
||||
@@ -410,8 +407,11 @@ set (wsjt_FSRCS
|
||||
lib/jplsubs.f
|
||||
lib/jt9fano.f90
|
||||
lib/jtmsg.f90
|
||||
lib/ldpcsim144.f90
|
||||
lib/ft8/ldpcsim174.f90
|
||||
lib/js8/ldpcsim174js8a.f90
|
||||
lib/js8/ldpcsim174js8b.f90
|
||||
lib/js8/ldpcsim174js8c.f90
|
||||
lib/js8/ldpcsim174js8e.f90
|
||||
lib/js8/ldpcsim174js8i.f90
|
||||
lib/ldpcsim40.f90
|
||||
lib/libration.f90
|
||||
lib/lorentzian.f90
|
||||
@@ -421,20 +421,6 @@ set (wsjt_FSRCS
|
||||
lib/moondopjpl.f90
|
||||
lib/morse.f90
|
||||
lib/move.f90
|
||||
lib/msk144d2.f90
|
||||
lib/msk40decodeframe.f90
|
||||
lib/msk144decodeframe.f90
|
||||
lib/msk144sd.f90
|
||||
lib/msk40spd.f90
|
||||
lib/msk144spd.f90
|
||||
lib/msk40sync.f90
|
||||
lib/msk144sync.f90
|
||||
lib/msk40_freq_search.f90
|
||||
lib/msk144_freq_search.f90
|
||||
lib/mskrtd.f90
|
||||
lib/msk144signalquality.f90
|
||||
lib/msk144sim.f90
|
||||
lib/mskrtd.f90
|
||||
lib/ft8/osd174.f90
|
||||
lib/pctile.f90
|
||||
lib/peakdt9.f90
|
||||
@@ -463,7 +449,6 @@ set (wsjt_FSRCS
|
||||
lib/spec9f.f90
|
||||
lib/stdmsg.f90
|
||||
lib/subtract65.f90
|
||||
lib/ft8/subtractft8.f90
|
||||
lib/sun.f90
|
||||
lib/symspec.f90
|
||||
lib/symspec2.f90
|
||||
@@ -471,8 +456,6 @@ set (wsjt_FSRCS
|
||||
lib/sync4.f90
|
||||
lib/sync64.f90
|
||||
lib/sync65.f90
|
||||
lib/ft8/sync8.f90
|
||||
lib/ft8/sync8d.f90
|
||||
lib/sync9.f90
|
||||
lib/sync9f.f90
|
||||
lib/sync9w.f90
|
||||
@@ -500,46 +483,24 @@ set (wsjt_FSRCS
|
||||
# temporary workaround for a gfortran v7.3 ICE on Fedora 27 64-bit
|
||||
set_source_files_properties (lib/slasubs.f PROPERTIES COMPILE_FLAGS -O2)
|
||||
|
||||
set (ka9q_CSRCS
|
||||
lib/ftrsd/decode_rs.c
|
||||
lib/ftrsd/encode_rs.c
|
||||
lib/ftrsd/init_rs.c
|
||||
)
|
||||
set_source_files_properties (${ka9q_CSRCS} PROPERTIES COMPILE_FLAGS -Wno-sign-compare)
|
||||
|
||||
set (qra_CSRCS
|
||||
lib/qra/qra64/qra64.c
|
||||
lib/qra/qra64/qra64_subs.c
|
||||
lib/qra/qracodes/npfwht.c
|
||||
lib/qra/qracodes/pdmath.c
|
||||
lib/qra/qracodes/qra12_63_64_irr_b.c
|
||||
lib/qra/qracodes/qra13_64_64_irr_e.c
|
||||
lib/qra/qracodes/qracodes.c
|
||||
lib/qra/qracodes/normrnd.c
|
||||
)
|
||||
|
||||
set (sqlite3_CSRCS
|
||||
vendor/sqlite3/sqlite3.c
|
||||
)
|
||||
|
||||
set (wsjt_CSRCS
|
||||
${ka9q_CSRCS}
|
||||
lib/ftrsd/ftrsdap.c
|
||||
lib/sgran.c
|
||||
lib/golay24_table.c
|
||||
lib/gran.c
|
||||
lib/igray.c
|
||||
lib/init_random_seed.c
|
||||
lib/ldpc32_table.c
|
||||
lib/wsprd/nhash.c
|
||||
lib/nhash.c
|
||||
lib/tab.c
|
||||
lib/tmoonsub.c
|
||||
lib/usleep.c
|
||||
lib/vit213.c
|
||||
lib/wisdom.c
|
||||
lib/wrapkarn.c
|
||||
${ldpc_CSRCS}
|
||||
${qra_CSRCS}
|
||||
)
|
||||
|
||||
set (wsjt_qt_UISRCS
|
||||
@@ -551,8 +512,6 @@ set (wsjtx_UISRCS
|
||||
messagewindow.ui
|
||||
about.ui
|
||||
astro.ui
|
||||
echograph.ui
|
||||
fastgraph.ui
|
||||
messageaveraging.ui
|
||||
widegraph.ui
|
||||
logqso.ui
|
||||
@@ -1021,8 +980,20 @@ endif (WIN32)
|
||||
add_library (wsjt_qtmm STATIC ${wsjt_qtmm_CXXSRCS} ${wsjt_qtmm_GENUISRCS})
|
||||
target_link_libraries (wsjt_qtmm Qt5::Multimedia)
|
||||
|
||||
add_executable (ldpcsim174 lib/ft8/ldpcsim174.f90 wsjtx.rc)
|
||||
target_link_libraries (ldpcsim174 wsjt_fort wsjt_cxx)
|
||||
add_executable (ldpcsim174js8a lib/js8/ldpcsim174js8a.f90 wsjtx.rc)
|
||||
target_link_libraries (ldpcsim174js8a wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (ldpcsim174js8b lib/js8/ldpcsim174js8b.f90 wsjtx.rc)
|
||||
target_link_libraries (ldpcsim174js8b wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (ldpcsim174js8c lib/js8/ldpcsim174js8c.f90 wsjtx.rc)
|
||||
target_link_libraries (ldpcsim174js8c wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (ldpcsim174js8e lib/js8/ldpcsim174js8e.f90 wsjtx.rc)
|
||||
target_link_libraries (ldpcsim174js8e wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (ldpcsim174js8i lib/js8/ldpcsim174js8i.f90 wsjtx.rc)
|
||||
target_link_libraries (ldpcsim174js8i wsjt_fort wsjt_cxx)
|
||||
|
||||
add_executable (js8 ${js8_FSRCS} ${js8_CXXSRCS} wsjtx.rc)
|
||||
if (${OPENMP_FOUND} OR APPLE)
|
||||
@@ -1086,7 +1057,7 @@ set_target_properties (js8call PROPERTIES
|
||||
MACOSX_BUNDLE_BUNDLE_NAME "${PROJECT_NAME}"
|
||||
MACOSX_BUNDLE_BUNDLE_EXECUTABLE_NAME "${PROJECT_NAME}"
|
||||
MACOSX_BUNDLE_COPYRIGHT "${PROJECT_COPYRIGHT}"
|
||||
MACOSX_BUNDLE_GUI_IDENTIFIER "org.k1jt.wsjtx"
|
||||
MACOSX_BUNDLE_GUI_IDENTIFIER "org.kn4crd.js8call"
|
||||
)
|
||||
|
||||
target_include_directories (js8call PRIVATE ${FFTW3_INCLUDE_DIRS})
|
||||
|
||||
@@ -24,29 +24,29 @@ Finally, every program is threatened constantly by software patents. States shou
|
||||
|
||||
The precise terms and conditions for copying, distribution and modification follow.
|
||||
|
||||
TERMS AND CONDITIONS 0. Definitions. “This License” refers to version 3 of the GNU General Public License.
|
||||
TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
“Copyright” also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.
|
||||
|
||||
“The Program” refers to any copyrightable work licensed under this License. Each licensee is addressed as “you”. “Licensees” and “recipients” may be individuals or organizations.
|
||||
"The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations.
|
||||
|
||||
To “modify” a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version” of the earlier work or a work “based on” the earlier work.
|
||||
To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work.
|
||||
|
||||
A “covered work” means either the unmodified Program or a work based on the Program.
|
||||
A "covered work" means either the unmodified Program or a work based on the Program.
|
||||
|
||||
To “propagate” a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.
|
||||
To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.
|
||||
|
||||
To “convey” a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.
|
||||
To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays “Appropriate Legal Notices” to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.
|
||||
An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code. The “source code” for a work means the preferred form of the work for making modifications to it. “Object code” means any non-source form of a work.
|
||||
1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work.
|
||||
|
||||
A “Standard Interface” means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.
|
||||
A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.
|
||||
|
||||
The “System Libraries” of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Component”, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.
|
||||
The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.
|
||||
The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.
|
||||
|
||||
@@ -68,15 +68,15 @@ You may charge any price or no price for each copy that you convey, and you may
|
||||
|
||||
5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all notices”. c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.
|
||||
a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.
|
||||
|
||||
A “User Product” is either (1) a “consumer product”, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used” refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.
|
||||
A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.
|
||||
|
||||
“Installation Information” for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.
|
||||
"Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).
|
||||
|
||||
@@ -84,13 +84,13 @@ The requirement to provide Installation Information does not include a requireme
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms. “Additional permissions” are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.
|
||||
7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered “further restrictions” within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.
|
||||
a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.
|
||||
|
||||
@@ -108,23 +108,23 @@ Termination of your rights under this section does not terminate the licenses of
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.
|
||||
|
||||
An “entity transaction” is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.
|
||||
An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents. A “contributor” is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor version”.
|
||||
11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's “essential patent claims” are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control” includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.
|
||||
A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a “patent license” is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant” such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.
|
||||
In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying” means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.
|
||||
If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.
|
||||
|
||||
A patent license is “discriminatory” if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.
|
||||
A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.
|
||||
|
||||
@@ -134,13 +134,13 @@ Nothing in this License shall be construed as excluding or limiting any implied
|
||||
|
||||
14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.
|
||||
Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.
|
||||
|
||||
15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ auto CallsignValidator::validate (QString& input, int& pos) const -> State
|
||||
{
|
||||
auto match = re_.match (input, 0, QRegularExpression::PartialPreferCompleteMatch);
|
||||
input = input.toUpper ();
|
||||
if (input.count(QLatin1Char('/')) > 1) return Invalid;
|
||||
if (input.count(QLatin1Char('/')) > 2) return Invalid;
|
||||
if (match.hasMatch ()) return Acceptable;
|
||||
if (!input.size () || match.hasPartialMatch ()) return Intermediate;
|
||||
pos = input.size ();
|
||||
|
||||
@@ -86,6 +86,12 @@ public:
|
||||
AudioDevice::Channel audio_input_channel () const;
|
||||
QAudioDeviceInfo const& audio_output_device () const;
|
||||
AudioDevice::Channel audio_output_channel () const;
|
||||
QAudioDeviceInfo const& notification_audio_output_device () const;
|
||||
AudioDevice::Channel notification_audio_output_channel () const;
|
||||
|
||||
bool notifications_enabled() const;
|
||||
QString notification_path(const QString &key) const;
|
||||
Q_SIGNAL void test_notify(const QString &key);
|
||||
|
||||
// These query methods should be used after a call to exec() to
|
||||
// determine if either the audio input or audio output stream
|
||||
@@ -93,6 +99,7 @@ public:
|
||||
// re-opened if they return true.
|
||||
bool restart_audio_input () const;
|
||||
bool restart_audio_output () const;
|
||||
bool restart_notification_audio_output () const;
|
||||
|
||||
bool use_dynamic_grid() const;
|
||||
QString my_callsign () const;
|
||||
@@ -102,8 +109,12 @@ public:
|
||||
void removeGroup(QString const &group);
|
||||
QSet<QString> auto_whitelist() const;
|
||||
QSet<QString> auto_blacklist() const;
|
||||
QSet<QString> hb_blacklist() const;
|
||||
QSet<QString> primary_highlight_words() const;
|
||||
QSet<QString> secondary_highlight_words() const;
|
||||
int activity_aging() const;
|
||||
int callsign_aging() const;
|
||||
QString eot() const;
|
||||
QString my_info () const;
|
||||
QString cq_message () const;
|
||||
QString reply_message () const;
|
||||
@@ -118,12 +129,14 @@ public:
|
||||
qint32 RxBandwidth() const;
|
||||
double degrade() const;
|
||||
double txDelay() const;
|
||||
bool reset_activity() const;
|
||||
bool check_for_updates() const;
|
||||
bool id_after_73 () const;
|
||||
bool tx_qsy_allowed () const;
|
||||
bool spot_to_reporting_networks () const;
|
||||
void set_spot_to_reporting_networks (bool);
|
||||
bool transmit_directed() const;
|
||||
bool autoreply_off_at_startup () const;
|
||||
bool autoreply_on_at_startup () const;
|
||||
bool heartbeat_anywhere() const;
|
||||
bool heartbeat_qso_pause() const;
|
||||
bool relay_off() const;
|
||||
@@ -137,6 +150,8 @@ public:
|
||||
bool ppfx() const;
|
||||
bool clear_callsign () const;
|
||||
bool miles () const;
|
||||
bool hold_ptt() const;
|
||||
bool avoid_forced_identify() const;
|
||||
bool avoid_allcall () const;
|
||||
bool set_avoid_allcall (bool avoid);
|
||||
bool spellcheck() const;
|
||||
@@ -172,6 +187,10 @@ public:
|
||||
port_type n1mm_server_port () const;
|
||||
bool valid_n1mm_info () const;
|
||||
bool broadcast_to_n1mm() const;
|
||||
QString n3fjp_server_name () const;
|
||||
port_type n3fjp_server_port () const;
|
||||
bool valid_n3fjp_info () const;
|
||||
bool broadcast_to_n3fjp() const;
|
||||
bool accept_udp_requests () const;
|
||||
bool udpWindowToFront () const;
|
||||
bool udpWindowRestore () const;
|
||||
@@ -188,14 +207,13 @@ public:
|
||||
QStringListModel const * macros () const;
|
||||
QDir save_directory () const;
|
||||
QDir azel_directory () const;
|
||||
QString sound_cq_path() const;
|
||||
QString sound_dm_path() const;
|
||||
QString sound_am_path() const;
|
||||
QString rig_name () const;
|
||||
Type2MsgGen type_2_msg_gen () const;
|
||||
QColor color_table_background() const;
|
||||
QColor color_table_highlight() const;
|
||||
QColor color_table_foreground() const;
|
||||
QColor color_primary_highlight () const;
|
||||
QColor color_secondary_highlight () const;
|
||||
QColor color_CQ () const;
|
||||
QColor color_MyCall () const;
|
||||
QColor color_rx_background () const;
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSMicrophoneUsageDescription</key>
|
||||
<string>Allow access to audio input devices</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
|
||||
@@ -1,108 +1,26 @@
|
||||
Some versions of Mac OS need special system settings to allow a shared memory
|
||||
segment to be created (this is how the application communicates with the decoder).
|
||||
|
||||
Notes on JS8Call Installation for Mac OS X
|
||||
(replace all instances of WSJT-X with JS8Call)
|
||||
Included in this DMG is a sysctl.conf file that you can use to increase the
|
||||
shared memory that the operating system allows to be allocated. You only have to do this process once.
|
||||
|
||||
Notes on WSJT-X Installation for Mac OS X
|
||||
-----------------------------------------
|
||||
To install:
|
||||
|
||||
Updated 16 July 2017
|
||||
--------------------
|
||||
0) Caution! Read through these instructions completely before proceeding.
|
||||
If you are at all uncomfortable modifying your system, please feel free to
|
||||
email me and I will help you walk though steps: kn4crd@gmail.com
|
||||
|
||||
If you have already downloaded a previous version of WSJT-X then I suggest
|
||||
you change the name in the Applications folder from WSJT-X to WSJT-X_previous
|
||||
before proceeding.
|
||||
1) Copy the sysctl.conf file to your desktop
|
||||
|
||||
If you have installed a previous version of WSJT-X before then there is no
|
||||
need to change anything on your system so proceed to NEXT.
|
||||
2) Open a Terminal window (Applications -> Utilities -> Terminal.app)
|
||||
|
||||
BEGIN:
|
||||
3) Run these commands in the Terminal window to install the sysctl.conf
|
||||
|
||||
There are some system matters you must deal with first. Open a Terminal window
|
||||
by going to Applications->Utilities and clicking on Terminal.
|
||||
sudo cp $HOME/Desktop/sysctl.conf /etc/sysctl.conf
|
||||
sudo chown root:wheel /etc/sysctl.conf
|
||||
sudo chmod 0664 /etc/sysctl.conf
|
||||
|
||||
Along with this ReadMe file there is a file: sysctl.conf. Drag this file to your Desktop.
|
||||
|
||||
WSJT-X makes use of a block of memory which is shared between different parts of
|
||||
the code. The normal allocation of shared memory on a Mac is insufficient and this
|
||||
has to be increased. You should use a Mac editor to examine sysctl.conf.
|
||||
|
||||
There are two important parameters that you need to consider. shmmax determines the
|
||||
amount of shared memory that must be allocated for WSJT-X to operate. This is 14680064 (14MB)
|
||||
and this is defined in the sysctl.conf file and should not be changed.
|
||||
|
||||
It is possible to run more than one instance of WSJT-X simultaneously. See
|
||||
"Section 14. Platform Dependencies" in the User Guide. The second important parameter
|
||||
shmall=17920 determines how many instances are permitted. This is calculated as:
|
||||
(shmall x 4096/14680064) = 5.
|
||||
The sysctl.conf file is configured to permit up to 5 instances of wsjtx to run simultaneously.
|
||||
If this limitation is acceptable then you can continue to install the sysctl.conf file without making any
|
||||
alterations. Otherwise you must edit the file to increase shmall according to this calculation.
|
||||
|
||||
Now move this file into place for the system to use by typing: (Note this assumes that
|
||||
you really did drag this file to your Desktop as required earlier.)
|
||||
|
||||
sudo cp $HOME/Desktop/sysctl.conf /etc/
|
||||
sudo chmod 664 /etc/sysctl.conf
|
||||
sudo chown root:wheel /etc/sysctl.conf
|
||||
|
||||
and then reboot your Mac. This is necessary to install the changes. After the
|
||||
reboot you should re-open the Terminal window as before and you can check that the
|
||||
change has been made by typing:
|
||||
|
||||
sysctl -a | grep sysv.shm
|
||||
|
||||
If shmmax is not shown as 14680064 then contact me since WSJT-X will fail to load with
|
||||
an error message: "Unable to create shared memory segment".
|
||||
|
||||
You are now finished with system changes. You should make certain that NO error messages
|
||||
have been produced during these steps. You can now close the Terminal window. It will
|
||||
not be necessary to repeat this procedure again, even when you download an updated
|
||||
version of WSJT-X.
|
||||
|
||||
NEXT:
|
||||
|
||||
Drag the WSJT-X app to your preferred location, such as Applications.
|
||||
|
||||
You need to configure your sound card. Visit Applications > Utilities > Audio MIDI
|
||||
Setup and select your sound card and then set Format to be "48000Hz 2ch-16bit" for
|
||||
input and output.
|
||||
|
||||
Now double-click on the WSJT-X app and two windows will appear. Select Preferences
|
||||
under the WSJT-X Menu and fill in various station details on the General panel.
|
||||
I recommend checking the 4 boxes under the Display heading and the first 4 boxes under
|
||||
the Behaviour heading.
|
||||
|
||||
Next visit the Audio panel and select the Audio Codec you use to communicate between
|
||||
WSJT-X and your rig. There are so many audio interfaces available that it is not
|
||||
possible to give detailed advice on selection. If you have difficulties contact me.
|
||||
Note the location of the Save Directory. Decoded wave forms are located here.
|
||||
|
||||
Look at the Reporting panel. If you check the "Prompt me" box, a logging panel will appear
|
||||
at the end of the QSO. Two log files are provided in Library/Application Support/WSJT-X.
|
||||
These are a simple wsjtx.log file and wsjtx_log.adi which is formatted for use with
|
||||
logging databases. The "File" menu bar items include a button "Open log directory"
|
||||
to open the log directory in Finder for you, ready for processing by any logging
|
||||
application you use.
|
||||
|
||||
Finally, visit the Radio panel. WSJT-X is most effective when operated with CAT
|
||||
control. You will need to install the relevant Mac driver for your rig. This must
|
||||
be located in the device driver directory /dev. You should install your driver
|
||||
and then re-launch WSJT-X. Return to the the Radio panel in Preferences and in
|
||||
the "Serial port" panel select your driver from the list that is presented. If
|
||||
for some reason your driver is not shown, then insert the full name
|
||||
of your driver in the Serial Port panel. Such as: /dev/tty.PL2303-00002226 or
|
||||
whatever driver you have. The /dev/ prefix is mandatory. Set the relevant
|
||||
communication parameters as required by your transceiver and click "Test CAT" to
|
||||
check.
|
||||
|
||||
WSJT-X needs the Mac clock to be accurate. Visit System Preferences > Date & Time
|
||||
and make sure that date and time are set automatically. The drop-down menu will
|
||||
normally offer you several time servers to choose from.
|
||||
|
||||
On the Help menu, have a look at the new Online User's Guide for operational hints
|
||||
and tips.
|
||||
|
||||
Please email me if you have problems.
|
||||
|
||||
--- John G4KLA (g4kla@rmnjmn.co.uk)
|
||||
4) Reboot your system.
|
||||
|
||||
If you run into any problems, feel free to reach out to me and I will help you
|
||||
walk through the steps: Jordan Sherer <kn4crd@gmail.com>
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
/**
|
||||
* This file is part of JS8Call.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* (C) 2019 Jordan Sherer <kn4crd@gmail.com> - All Rights Reserved
|
||||
*
|
||||
**/
|
||||
|
||||
#include "Decoder.h"
|
||||
|
||||
#include "commons.h"
|
||||
|
||||
#include <QTimer>
|
||||
|
||||
|
||||
Decoder::Decoder(QObject *parent):
|
||||
QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
Decoder::~Decoder(){
|
||||
}
|
||||
|
||||
//
|
||||
void Decoder::lock(){
|
||||
// NOOP
|
||||
}
|
||||
|
||||
//
|
||||
void Decoder::unlock(){
|
||||
// NOOP
|
||||
}
|
||||
|
||||
//
|
||||
Worker* Decoder::createWorker(){
|
||||
auto worker = new Worker();
|
||||
worker->moveToThread(&m_thread);
|
||||
connect(&m_thread, &QThread::finished, worker, &QObject::deleteLater);
|
||||
connect(this, &Decoder::startWorker, worker, &Worker::start);
|
||||
connect(this, &Decoder::quitWorker, worker, &Worker::quit);
|
||||
connect(worker, &Worker::ready, this, &Decoder::processReady);
|
||||
connect(worker, &Worker::error, this, &Decoder::processError);
|
||||
connect(worker, &Worker::finished, this, &Decoder::processFinished);
|
||||
return worker;
|
||||
}
|
||||
|
||||
//
|
||||
void Decoder::start(QThread::Priority priority){
|
||||
m_thread.start(priority);
|
||||
}
|
||||
|
||||
//
|
||||
void Decoder::quit(){
|
||||
m_thread.quit();
|
||||
}
|
||||
|
||||
//
|
||||
bool Decoder::wait(){
|
||||
return m_thread.wait();
|
||||
}
|
||||
|
||||
//
|
||||
void Decoder::processStart(QString path, QStringList args){
|
||||
if(m_worker.isNull()){
|
||||
m_worker = createWorker();
|
||||
}
|
||||
|
||||
emit startWorker(path, args);
|
||||
}
|
||||
|
||||
//
|
||||
void Decoder::processReady(QByteArray t){
|
||||
emit ready(t);
|
||||
}
|
||||
|
||||
//
|
||||
void Decoder::processQuit(){
|
||||
emit quitWorker();
|
||||
}
|
||||
|
||||
//
|
||||
void Decoder::processError(int errorCode, QString errorString){
|
||||
if(JS8_DEBUG_DECODE) qDebug() << "decoder process error" << errorCode << errorString;
|
||||
emit error(errorCode, errorString);
|
||||
}
|
||||
|
||||
//
|
||||
void Decoder::processFinished(int exitCode, int statusCode, QString errorString){
|
||||
if(JS8_DEBUG_DECODE) qDebug() << "decoder process finished" << exitCode << statusCode << errorString;
|
||||
emit finished(exitCode, statusCode, errorString);
|
||||
}
|
||||
|
||||
////////////////////////////////////////
|
||||
//////////////// WORKER ////////////////
|
||||
////////////////////////////////////////
|
||||
|
||||
//
|
||||
Worker::~Worker(){
|
||||
}
|
||||
|
||||
//
|
||||
void Worker::setProcess(QProcess *proc, int msecs){
|
||||
if(!m_proc.isNull()){
|
||||
bool b = m_proc->waitForFinished(msecs);
|
||||
if(!b) m_proc->close();
|
||||
m_proc.reset();
|
||||
}
|
||||
|
||||
if(proc){
|
||||
m_proc.reset(proc);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
void Worker::start(QString path, QStringList args){
|
||||
if(JS8_DEBUG_DECODE) qDebug() << "decoder process starting...";
|
||||
|
||||
auto proc = new QProcess(this);
|
||||
|
||||
connect(proc, &QProcess::readyReadStandardOutput,
|
||||
[this, proc](){
|
||||
while(proc->canReadLine()){
|
||||
emit ready(proc->readLine());
|
||||
}
|
||||
});
|
||||
|
||||
connect(proc, static_cast<void (QProcess::*) (QProcess::ProcessError)> (&QProcess::error),
|
||||
[this, proc] (QProcess::ProcessError errorCode) {
|
||||
emit error(int(errorCode), proc->errorString());
|
||||
});
|
||||
|
||||
connect(proc, static_cast<void (QProcess::*) (int, QProcess::ExitStatus)> (&QProcess::finished),
|
||||
[this, proc] (int exitCode, QProcess::ExitStatus status) {
|
||||
emit finished(exitCode, int(status), QString{proc->readAllStandardError()});
|
||||
});
|
||||
|
||||
QProcessEnvironment env {QProcessEnvironment::systemEnvironment ()};
|
||||
env.insert ("OMP_STACKSIZE", "4M");
|
||||
proc->setProcessEnvironment (env);
|
||||
proc->start(path, args, QIODevice::ReadWrite | QIODevice::Unbuffered);
|
||||
|
||||
setProcess(proc);
|
||||
}
|
||||
|
||||
//
|
||||
void Worker::quit(){
|
||||
setProcess(nullptr);
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
#ifndef DECODER_H
|
||||
#define DECODER_H
|
||||
|
||||
/**
|
||||
* (C) 2019 Jordan Sherer <kn4crd@gmail.com> - All Rights Reserved
|
||||
**/
|
||||
|
||||
#include "ProcessThread.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QByteArray>
|
||||
#include <QPointer>
|
||||
#include <QProcess>
|
||||
|
||||
|
||||
class Worker : public QObject{
|
||||
Q_OBJECT
|
||||
public:
|
||||
~Worker();
|
||||
public slots:
|
||||
void start(QString path, QStringList args);
|
||||
void quit();
|
||||
|
||||
QProcess* process() const { return m_proc.data(); }
|
||||
private:
|
||||
void setProcess(QProcess *proc, int msecs=1000);
|
||||
|
||||
signals:
|
||||
void ready(QByteArray t);
|
||||
void error(int errorCode, QString errorString);
|
||||
void finished(int exitCode, int statusCode, QString errorString);
|
||||
|
||||
private:
|
||||
QScopedPointer<QProcess> m_proc;
|
||||
};
|
||||
|
||||
|
||||
class Decoder: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Decoder(QObject *parent=nullptr);
|
||||
~Decoder();
|
||||
|
||||
void lock();
|
||||
void unlock();
|
||||
|
||||
QString program() const {
|
||||
if(!m_worker.isNull() && m_worker->process() != nullptr){
|
||||
return m_worker->process()->program();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
QStringList arguments() const {
|
||||
if(!m_worker.isNull() && m_worker->process() != nullptr){
|
||||
return m_worker->process()->arguments();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
private:
|
||||
Worker* createWorker();
|
||||
|
||||
public slots:
|
||||
void start(QThread::Priority priority);
|
||||
void quit();
|
||||
bool wait();
|
||||
|
||||
void processStart(QString path, QStringList args);
|
||||
void processReady(QByteArray t);
|
||||
void processQuit();
|
||||
|
||||
void processError(int errorCode, QString errorString);
|
||||
void processFinished(int exitCode, int statusCode, QString errorString);
|
||||
|
||||
signals:
|
||||
void startWorker(QString path, QStringList args);
|
||||
void quitWorker();
|
||||
|
||||
void ready(QByteArray t);
|
||||
void error(int errorCode, QString errorString);
|
||||
void finished(int exitCode, int statusCode, QString errorString);
|
||||
|
||||
private:
|
||||
QPointer<Worker> m_worker;
|
||||
QThread m_thread;
|
||||
};
|
||||
|
||||
|
||||
#endif // DECODER_H
|
||||
@@ -43,12 +43,22 @@ bool Detector::reset ()
|
||||
|
||||
void Detector::clear ()
|
||||
{
|
||||
QMutexLocker mutex(&m_lock);
|
||||
|
||||
#if JS8_RING_BUFFER
|
||||
// set index to roughly where we are in time (1ms resolution)
|
||||
// qint64 now (DriftingDateTime::currentMSecsSinceEpoch ());
|
||||
// unsigned msInPeriod ((now % 86400000LL) % (m_period * 1000));
|
||||
// dec_data.params.kin = qMin ((msInPeriod * m_frameRate) / 1000, static_cast<unsigned> (sizeof (dec_data.d2) / sizeof (dec_data.d2[0])));
|
||||
qint64 now (DriftingDateTime::currentMSecsSinceEpoch ());
|
||||
unsigned msInPeriod ((now % 86400000LL) % (m_period * 1000));
|
||||
int prevKin = dec_data.params.kin;
|
||||
dec_data.params.kin = qMin ((msInPeriod * m_frameRate) / 1000, static_cast<unsigned> (sizeof (dec_data.d2) / sizeof (dec_data.d2[0])));
|
||||
m_bufferPos = 0;
|
||||
m_ns=secondInPeriod();
|
||||
memset(dec_data.d2, 0, sizeof(dec_data.d2));
|
||||
qDebug() << "advancing detector buffer from" << prevKin << "to" << dec_data.params.kin << "delta" << dec_data.params.kin - prevKin;
|
||||
#else
|
||||
dec_data.params.kin = 0;
|
||||
m_bufferPos = 0;
|
||||
#endif
|
||||
|
||||
// fill buffer with zeros (G4WJS commented out because it might cause decoder hangs)
|
||||
// qFill (dec_data.d2, dec_data.d2 + sizeof (dec_data.d2) / sizeof (dec_data.d2[0]), 0);
|
||||
@@ -56,6 +66,8 @@ void Detector::clear ()
|
||||
|
||||
qint64 Detector::writeData (char const * data, qint64 maxSize)
|
||||
{
|
||||
QMutexLocker mutex(&m_lock);
|
||||
|
||||
int ns=secondInPeriod();
|
||||
if(ns < m_ns) { // When ns has wrapped around to zero, restart the buffers
|
||||
dec_data.params.kin = 0;
|
||||
@@ -117,8 +129,6 @@ qint64 Detector::writeData (char const * data, qint64 maxSize)
|
||||
remaining -= numFramesProcessed;
|
||||
}
|
||||
|
||||
|
||||
|
||||
return maxSize; // we drop any data past the end of the buffer on
|
||||
// the floor until the next period starts
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
#define DETECTOR_HPP__
|
||||
#include "AudioDevice.hpp"
|
||||
#include <QScopedArrayPointer>
|
||||
#include <QMutex>
|
||||
#include <QMutexLocker>
|
||||
|
||||
//
|
||||
// output device that distributes data in predefined chunks via a signal
|
||||
@@ -24,12 +26,17 @@ public:
|
||||
//
|
||||
Detector (unsigned frameRate, unsigned periodLengthInSeconds, unsigned downSampleFactor = 4u, QObject * parent = 0);
|
||||
|
||||
QMutex * getMutex(){ return &m_lock; }
|
||||
unsigned period() const {return m_period;}
|
||||
void setTRPeriod(unsigned p) {m_period=p;}
|
||||
bool reset () override;
|
||||
|
||||
Q_SIGNAL void framesWritten (qint64) const;
|
||||
Q_SLOT void setBlockSize (unsigned);
|
||||
|
||||
void clear (); // discard buffer contents
|
||||
unsigned secondInPeriod () const;
|
||||
|
||||
protected:
|
||||
qint64 readData (char * /* data */, qint64 /* maxSize */) override
|
||||
{
|
||||
@@ -39,9 +46,6 @@ protected:
|
||||
qint64 writeData (char const * data, qint64 maxSize) override;
|
||||
|
||||
private:
|
||||
void clear (); // discard buffer contents
|
||||
unsigned secondInPeriod () const;
|
||||
|
||||
unsigned m_frameRate;
|
||||
unsigned m_period;
|
||||
unsigned m_downSampleFactor;
|
||||
@@ -54,6 +58,7 @@ private:
|
||||
// data (a signals worth) at
|
||||
// the input sample rate
|
||||
unsigned m_bufferPos;
|
||||
QMutex m_lock;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -14,7 +14,11 @@ extern "C"
|
||||
{
|
||||
typedef struct rig RIG;
|
||||
struct rig_caps;
|
||||
#ifdef JS8_USE_LEGACY_HAMLIB
|
||||
typedef int vfo_t;
|
||||
#else
|
||||
typedef unsigned int vfo_t;
|
||||
#endif
|
||||
}
|
||||
|
||||
// hamlib transceiver and PTT mostly delegated directly to hamlib Rig class
|
||||
|
||||
@@ -71,7 +71,22 @@ void Modulator::start (unsigned symbolsLength, double framesPerSymbol,
|
||||
m_toneSpacing = toneSpacing;
|
||||
m_bFastMode=fastMode;
|
||||
m_TRperiod=TRperiod;
|
||||
unsigned delay_ms = 1920 == m_nsps && 15 == m_period ? 500 : 1000;
|
||||
unsigned delay_ms = 0;
|
||||
if(m_TRperiod == JS8A_TX_SECONDS){
|
||||
delay_ms = JS8A_START_DELAY_MS;
|
||||
}
|
||||
else if(m_TRperiod == JS8B_TX_SECONDS){
|
||||
delay_ms = JS8B_START_DELAY_MS;
|
||||
}
|
||||
else if(m_TRperiod == JS8C_TX_SECONDS){
|
||||
delay_ms = JS8C_START_DELAY_MS;
|
||||
}
|
||||
else if(m_TRperiod == JS8E_TX_SECONDS){
|
||||
delay_ms = JS8E_START_DELAY_MS;
|
||||
}
|
||||
else if(m_TRperiod == JS8I_TX_SECONDS){
|
||||
delay_ms = JS8I_START_DELAY_MS;
|
||||
}
|
||||
|
||||
// noise generator parameters
|
||||
if (m_addNoise) {
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
#include "NotificationAudio.h"
|
||||
#include "WaveFile.h"
|
||||
|
||||
|
||||
NotificationAudio::NotificationAudio(QObject *parent):
|
||||
QObject(parent)
|
||||
{
|
||||
m_file = new BWFFile(QAudioFormat{}, this);
|
||||
|
||||
m_stream = new SoundOutput();
|
||||
|
||||
connect(m_stream, &SoundOutput::status, this, &NotificationAudio::status);
|
||||
connect(m_stream, &SoundOutput::error, this, &NotificationAudio::error);
|
||||
}
|
||||
|
||||
NotificationAudio::~NotificationAudio(){
|
||||
// stop the audio
|
||||
stop();
|
||||
|
||||
// clean cache
|
||||
foreach(auto pair, m_cache){
|
||||
delete pair.second;
|
||||
}
|
||||
}
|
||||
|
||||
void NotificationAudio::status(QString message){
|
||||
if(message == "Idle"){
|
||||
stop();
|
||||
}
|
||||
}
|
||||
|
||||
void NotificationAudio::error(QString message){
|
||||
qDebug() << "notification error:" << message;
|
||||
}
|
||||
|
||||
void NotificationAudio::setDevice(const QAudioDeviceInfo &device, unsigned channels, unsigned msBuffer){
|
||||
m_device = device;
|
||||
m_channels = channels;
|
||||
m_msBuffer = msBuffer;
|
||||
m_stream->setFormat(device, channels, msBuffer);
|
||||
}
|
||||
|
||||
void NotificationAudio::play(const QString &filePath){
|
||||
if(m_cache.contains(filePath)){
|
||||
auto pair = m_cache.value(filePath);
|
||||
auto format = pair.first;
|
||||
auto bytes = pair.second;
|
||||
|
||||
qDebug() << "notification: playing" << filePath << "with format" << format << "from cache";
|
||||
playBytes(format, bytes);
|
||||
return;
|
||||
}
|
||||
|
||||
if(m_file->isOpen()){
|
||||
m_file->close();
|
||||
}
|
||||
m_file->setFileName(filePath);
|
||||
if(m_file->open(BWFFile::ReadOnly)){
|
||||
QAudioFormat format = m_file->format();
|
||||
QByteArray *bytes = new QByteArray(m_file->readAll());
|
||||
|
||||
qDebug() << "notification: playing" << filePath << "with format" << format << "from disk";
|
||||
playBytes(format, bytes);
|
||||
|
||||
// cache the buffer
|
||||
m_cache.insert(filePath, {format, bytes});
|
||||
}
|
||||
}
|
||||
|
||||
void NotificationAudio::playBytes(const QAudioFormat &format, QByteArray *bytes){
|
||||
if(bytes == nullptr){
|
||||
return;
|
||||
}
|
||||
|
||||
if(m_buffer.isOpen()){
|
||||
m_buffer.close();
|
||||
}
|
||||
|
||||
m_buffer.setBuffer(bytes);
|
||||
|
||||
if(!m_buffer.open(QIODevice::ReadOnly)){
|
||||
return;
|
||||
}
|
||||
|
||||
m_stream->setDeviceFormat(m_device, format, format.channelCount(), m_msBuffer);
|
||||
m_stream->restart(&m_buffer);
|
||||
}
|
||||
|
||||
void NotificationAudio::stop(){
|
||||
m_stream->stop();
|
||||
|
||||
if(m_file->isOpen()){
|
||||
m_file->close();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
#ifndef NOTIFICATIONAUDIO_H
|
||||
#define NOTIFICATIONAUDIO_H
|
||||
|
||||
#include <QIODevice>
|
||||
#include <QBuffer>
|
||||
#include <QAudioDeviceInfo>
|
||||
#include <QAudioFormat>
|
||||
#include <QAudioOutput>
|
||||
#include <QFile>
|
||||
#include <QPair>
|
||||
#include <QPointer>
|
||||
#include <QByteArray>
|
||||
#include <QCache>
|
||||
#include <QScopedPointer>
|
||||
|
||||
#include "AudioDevice.hpp"
|
||||
#include "AudioDecoder.h"
|
||||
#include "Audio/BWFFile.hpp"
|
||||
#include "soundout.h"
|
||||
|
||||
|
||||
class NotificationAudio :
|
||||
public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
NotificationAudio(QObject * parent=nullptr);
|
||||
~NotificationAudio();
|
||||
|
||||
public slots:
|
||||
void status(QString message);
|
||||
void error(QString message);
|
||||
void setDevice(const QAudioDeviceInfo &device, unsigned channels, unsigned msBuffer=0);
|
||||
void play(const QString &filePath);
|
||||
void stop();
|
||||
|
||||
private:
|
||||
void playBytes(const QAudioFormat &format, QByteArray *bytes);
|
||||
|
||||
private:
|
||||
QMap<QString, QPair<QAudioFormat, QByteArray*>> m_cache;
|
||||
QPointer<SoundOutput> m_stream;
|
||||
QPointer<AudioDecoder> m_decoder;
|
||||
QPointer<BWFFile> m_file;
|
||||
QAudioDeviceInfo m_device;
|
||||
QBuffer m_buffer;
|
||||
unsigned m_channels;
|
||||
unsigned m_msBuffer;
|
||||
};
|
||||
|
||||
#endif // NOTIFICATIONAUDIO_H
|
||||
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* This file is part of JS8Call.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* (C) 2019 Jordan Sherer <kn4crd@gmail.com> - All Rights Reserved
|
||||
*
|
||||
**/
|
||||
#include "ProcessThread.h"
|
||||
|
||||
ProcessThread::ProcessThread(QObject *parent):
|
||||
QThread(parent)
|
||||
{
|
||||
}
|
||||
|
||||
ProcessThread::~ProcessThread(){
|
||||
setProcess(nullptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ProcessThread::setProcess
|
||||
* @param proc - process to move to this thread and take ownership
|
||||
*/
|
||||
void ProcessThread::setProcess(QProcess *proc, int msecs){
|
||||
if(!m_proc.isNull()){
|
||||
bool b = m_proc->waitForFinished(msecs);
|
||||
if(!b) m_proc->close();
|
||||
m_proc.reset();
|
||||
}
|
||||
|
||||
if(proc){
|
||||
proc->moveToThread(this);
|
||||
m_proc.reset(proc);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
#ifndef PROCESSTHREAD_H
|
||||
#define PROCESSTHREAD_H
|
||||
|
||||
/**
|
||||
* (C) 2019 Jordan Sherer <kn4crd@gmail.com> - All Rights Reserved
|
||||
**/
|
||||
|
||||
#include <QScopedPointer>
|
||||
#include <QProcess>
|
||||
#include <QThread>
|
||||
|
||||
|
||||
class ProcessThread : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ProcessThread(QObject *parent=nullptr);
|
||||
~ProcessThread();
|
||||
|
||||
void setProcess(QProcess *proc, int msecs=1000);
|
||||
QProcess * process(){
|
||||
return m_proc.data();
|
||||
}
|
||||
|
||||
protected:
|
||||
QScopedPointer<QProcess> m_proc;
|
||||
};
|
||||
|
||||
#endif // PROCESSTHREAD_H
|
||||
@@ -39,3 +39,13 @@ JS8Call is a derivative of the WSJT-X application, restructured and redesigned f
|
||||
* October 31, 2018 - Version 0.8 released - ~7000 testers
|
||||
* November 15, 2018 - Version 0.9 released - ~7500 testers
|
||||
* November 30, 2018 - Version 0.10 released - ~7800 testers
|
||||
* December 18, 2018 - Version 0.11 released - ~8200 testers
|
||||
* January 1, 2019 - Version 0.12 released - ~9000 testers
|
||||
* January 23, 2019 - Version 0.13 released - ~9250 testers
|
||||
* February 7, 2019 - Version 0.14 released - ~9600 testers
|
||||
* February 21, 2019 - Version 1.0.0-RC1 released - ~10000 testers
|
||||
* March 11, 2019 - Version 1.0.0-RC2 released - >10000 testers
|
||||
* March 26, 2019 - Version 1.0.0-RC3 released - >11000 testers
|
||||
* April 1, 2019 - Version 1.0.0 general availability - Public Release!
|
||||
* June 6, 2019 - Version 1.1.0 general availability
|
||||
* November 29, 2019 - Version 2.0.0 general availability - Fast and Turbo speeds introduced!
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
#include "SpotClient.h"
|
||||
#include "Message.h"
|
||||
|
||||
#include "moc_SpotClient.cpp"
|
||||
|
||||
SpotClient::SpotClient(MessageClient *client, QObject *parent):
|
||||
QObject(parent),
|
||||
m_client { client }
|
||||
{
|
||||
prepare();
|
||||
|
||||
connect(&m_timer, &QTimer::timeout, this, &SpotClient::processSpots);
|
||||
m_timer.setInterval(60 * 1000);
|
||||
m_timer.setSingleShot(false);
|
||||
m_timer.start();
|
||||
}
|
||||
|
||||
void SpotClient::prepare(){
|
||||
QHostInfo::lookupHost("spot.js8call.com", this, SLOT(dnsLookupResult(QHostInfo)));
|
||||
}
|
||||
|
||||
void SpotClient::dnsLookupResult(QHostInfo info){
|
||||
if (info.addresses().isEmpty()) {
|
||||
qDebug() << "SpotClient Error:" << info.errorString();
|
||||
return;
|
||||
}
|
||||
|
||||
m_address = info.addresses().at(0);
|
||||
qDebug() << "SpotClient Resolve:" << m_address.toString();
|
||||
}
|
||||
|
||||
void SpotClient::setLocalStation(QString callsign, QString grid, QString info, QString version){
|
||||
bool changed = false;
|
||||
|
||||
if(m_call != callsign){
|
||||
m_call = callsign;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if(m_grid != grid){
|
||||
m_grid = grid;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if(m_info != info){
|
||||
m_info = info;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if(m_version != version){
|
||||
m_version = version;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
// send local information to network on change, or once every 15 minutes
|
||||
if(changed || m_seq % 15 == 0){
|
||||
enqueueLocalSpot(callsign, grid, info, version);
|
||||
}
|
||||
}
|
||||
|
||||
void SpotClient::enqueueLocalSpot(QString callsign, QString grid, QString info, QString version){
|
||||
auto m = Message("RX.LOCAL", "", {
|
||||
{"CALLSIGN", QVariant(callsign)},
|
||||
{"GRID", QVariant(grid)},
|
||||
{"INFO", QVariant(info)},
|
||||
{"VERSION", QVariant(version)},
|
||||
});
|
||||
|
||||
m_queue.enqueue(m.toJson());
|
||||
}
|
||||
|
||||
void SpotClient::enqueueSpot(QString callsign, QString grid, int submode, int frequency, int snr){
|
||||
auto m = Message("RX.SPOT", "", {
|
||||
{"BY", QVariant(QMap<QString, QVariant>{
|
||||
{"CALLSIGN", QVariant(m_call)},
|
||||
{"GRID", QVariant(m_grid)},
|
||||
})},
|
||||
{"CALLSIGN", QVariant(callsign)},
|
||||
{"GRID", QVariant(grid)},
|
||||
{"FREQ", QVariant(frequency)},
|
||||
{"SNR", QVariant(snr)},
|
||||
{"SPEED", QVariant(submode)},
|
||||
});
|
||||
|
||||
m_queue.enqueue(m.toJson());
|
||||
}
|
||||
|
||||
void SpotClient::enqueueCmd(QString cmd, QString from, QString to, QString relayPath, QString text, QString grid, QString extra, int submode, int frequency, int snr){
|
||||
auto m = Message("RX.DIRECTED", "", {
|
||||
{"BY", QVariant(QMap<QString, QVariant>{
|
||||
{"CALLSIGN", QVariant(m_call)},
|
||||
{"GRID", QVariant(m_grid)},
|
||||
})},
|
||||
{"CMD", QVariant(cmd)},
|
||||
{"FROM", QVariant(from)},
|
||||
{"TO", QVariant(to)},
|
||||
{"PATH", QVariant(relayPath)},
|
||||
{"TEXT", QVariant(text)},
|
||||
{"GRID", QVariant(grid)},
|
||||
{"EXTRA", QVariant(extra)},
|
||||
{"FREQ", QVariant(frequency)},
|
||||
{"SNR", QVariant(snr)},
|
||||
{"SPEED", QVariant(submode)},
|
||||
});
|
||||
|
||||
m_queue.enqueue(m.toJson());
|
||||
}
|
||||
|
||||
void SpotClient::processSpots(){
|
||||
if(m_address.isNull()){
|
||||
prepare();
|
||||
return;
|
||||
}
|
||||
|
||||
while(!m_queue.isEmpty()){
|
||||
sendRawSpot(m_queue.dequeue());
|
||||
}
|
||||
|
||||
m_seq++;
|
||||
}
|
||||
|
||||
void SpotClient::sendRawSpot(QByteArray payload){
|
||||
if(!m_address.isNull()){
|
||||
m_client->send_raw_datagram(payload, m_address, 50000);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
#ifndef JS8SPOTCLIENT_H
|
||||
#define JS8SPOTCLIENT_H
|
||||
|
||||
#include "MessageClient.hpp"
|
||||
|
||||
#include <QObject>
|
||||
#include <QHostInfo>
|
||||
#include <QQueue>
|
||||
#include <QTimer>
|
||||
|
||||
class SpotClient : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SpotClient(MessageClient *client, QObject *parent = nullptr);
|
||||
|
||||
void prepare();
|
||||
void setLocalStation(QString callsign, QString grid, QString info, QString version);
|
||||
void enqueueLocalSpot(QString callsign, QString grid, QString info, QString version);
|
||||
void enqueueCmd(QString cmd, QString from, QString to, QString relayPath, QString text, QString grid, QString extra, int submode, int frequency, int snr);
|
||||
void enqueueSpot(QString callsign, QString grid, int submode, int frequency, int snr);
|
||||
void sendRawSpot(QByteArray payload);
|
||||
|
||||
public slots:
|
||||
void processSpots();
|
||||
void dnsLookupResult(QHostInfo);
|
||||
|
||||
private:
|
||||
int m_seq;
|
||||
QString m_call;
|
||||
QString m_grid;
|
||||
QString m_info;
|
||||
QString m_version;
|
||||
|
||||
QHostAddress m_address;
|
||||
MessageClient *m_client;
|
||||
QTimer m_timer;
|
||||
QQueue<QByteArray> m_queue;
|
||||
};
|
||||
|
||||
#endif // JS8SPOTCLIENT_H
|
||||
@@ -0,0 +1,78 @@
|
||||
#include "TCPClient.h"
|
||||
|
||||
#include <QTcpSocket>
|
||||
#include <QDebug>
|
||||
|
||||
#include "pimpl_impl.hpp"
|
||||
|
||||
#include "moc_TCPClient.cpp"
|
||||
|
||||
|
||||
class TCPClient::impl
|
||||
: public QTcpSocket
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
using port_type = quint16;
|
||||
|
||||
impl (TCPClient * self)
|
||||
: self_ {self}
|
||||
{
|
||||
}
|
||||
|
||||
~impl ()
|
||||
{
|
||||
}
|
||||
|
||||
bool isConnected(QString host, port_type port){
|
||||
if(host_ != host || port_ != port){
|
||||
disconnectFromHost();
|
||||
return false;
|
||||
}
|
||||
return state() == QTcpSocket::ConnectedState ;
|
||||
}
|
||||
|
||||
void connectToHost(QString host, port_type port){
|
||||
host_ = host;
|
||||
port_ = port;
|
||||
|
||||
QTcpSocket::connectToHost(host_, port_);
|
||||
}
|
||||
|
||||
qint64 send(QByteArray const &message, bool crlf){
|
||||
return write(message + (crlf ? "\r\f" : ""));
|
||||
}
|
||||
|
||||
TCPClient * self_;
|
||||
QString host_;
|
||||
port_type port_;
|
||||
};
|
||||
|
||||
#include "TCPClient.moc"
|
||||
|
||||
TCPClient::TCPClient(QObject *parent) : QObject(parent)
|
||||
, m_ {this}
|
||||
{
|
||||
}
|
||||
|
||||
bool TCPClient::ensureConnected(QString host, port_type port, int msecs){
|
||||
if(!m_->isConnected(host, port)){
|
||||
m_->connectToHost(host, port);
|
||||
}
|
||||
|
||||
return m_->waitForConnected(msecs);
|
||||
}
|
||||
|
||||
bool TCPClient::sendNetworkMessage(QString host, port_type port, QByteArray const &message, bool crlf, int msecs){
|
||||
if(!ensureConnected(host, port, msecs)){
|
||||
return false;
|
||||
}
|
||||
|
||||
qint64 n = m_->send(message, crlf);
|
||||
if(n <= 0){
|
||||
return false;
|
||||
}
|
||||
|
||||
return m_->flush();
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#ifndef TCPCLIENT_H
|
||||
#define TCPCLIENT_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QTcpSocket>
|
||||
|
||||
#include "pimpl_h.hpp"
|
||||
|
||||
class TCPClient : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
using port_type = quint16;
|
||||
|
||||
explicit TCPClient(QObject *parent = nullptr);
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
Q_SLOT bool ensureConnected(QString host, port_type port, int msecs = 5000);
|
||||
Q_SLOT bool sendNetworkMessage(QString host, port_type port, QByteArray const &message, bool crlf=true, int msecs=5000);
|
||||
|
||||
private:
|
||||
class impl;
|
||||
pimpl<impl> m_;
|
||||
};
|
||||
|
||||
#endif // TCPCLIENT_H
|
||||
@@ -0,0 +1,520 @@
|
||||
#include "TransmitTextEdit.h"
|
||||
|
||||
#include "commons.h"
|
||||
#include "varicode.h"
|
||||
|
||||
#include <iterator>
|
||||
#include <QDebug>
|
||||
|
||||
|
||||
void setTextEditFont(QTextEdit *edit, QFont font){
|
||||
// all uppercase
|
||||
font.setCapitalization(QFont::AllUppercase);
|
||||
|
||||
edit->setFont(font);
|
||||
edit->setFontFamily(font.family());
|
||||
edit->setFontItalic(font.italic());
|
||||
edit->setFontPointSize(font.pointSize());
|
||||
edit->setFontUnderline(font.underline());
|
||||
edit->setFontWeight(font.weight());
|
||||
|
||||
auto d = edit->document();
|
||||
d->setDefaultFont(font);
|
||||
edit->setDocument(d);
|
||||
|
||||
auto c = edit->textCursor();
|
||||
c.select(QTextCursor::Document);
|
||||
auto cf = c.blockCharFormat();
|
||||
cf.setFont(font);
|
||||
cf.setFontCapitalization(QFont::AllUppercase);
|
||||
c.mergeBlockCharFormat(cf);
|
||||
|
||||
edit->updateGeometry();
|
||||
}
|
||||
|
||||
void setTextEditStyle(QTextEdit *edit, QColor fg, QColor bg, QFont font){
|
||||
edit->setStyleSheet(QString("QTextEdit { color:%1; background: %2; %3; }").arg(fg.name()).arg(bg.name()).arg(font_as_stylesheet(font)));
|
||||
|
||||
//QTimer::singleShot(10, nullptr, [edit, fg, bg](){
|
||||
QPalette p = edit->palette();
|
||||
p.setColor(QPalette::Base, bg);
|
||||
p.setColor(QPalette::Active, QPalette::Base, bg);
|
||||
p.setColor(QPalette::Disabled, QPalette::Base, bg);
|
||||
p.setColor(QPalette::Inactive, QPalette::Base, bg);
|
||||
|
||||
p.setColor(QPalette::Text, fg);
|
||||
p.setColor(QPalette::Active, QPalette::Text, fg);
|
||||
p.setColor(QPalette::Disabled, QPalette::Text, fg);
|
||||
p.setColor(QPalette::Inactive, QPalette::Text, fg);
|
||||
|
||||
edit->setBackgroundRole(QPalette::Base);
|
||||
edit->setForegroundRole(QPalette::Text);
|
||||
edit->setPalette(p);
|
||||
|
||||
edit->updateGeometry();
|
||||
edit->update();
|
||||
//});
|
||||
}
|
||||
|
||||
void highlightBlock(QTextBlock block, QFont font, QColor foreground, QColor background){
|
||||
QTextCursor cursor(block);
|
||||
|
||||
// Set background color
|
||||
QTextBlockFormat blockFormat = cursor.blockFormat();
|
||||
blockFormat.setBackground(background);
|
||||
cursor.setBlockFormat(blockFormat);
|
||||
|
||||
// Set font
|
||||
/*
|
||||
for (QTextBlock::iterator it = cursor.block().begin(); !(it.atEnd()); ++it) {
|
||||
QTextCharFormat charFormat = it.fragment().charFormat();
|
||||
charFormat.setFont(font);
|
||||
charFormat.setFontCapitalization(QFont::AllUppercase);
|
||||
charFormat.setForeground(QBrush(foreground));
|
||||
|
||||
QTextCursor tempCursor = cursor;
|
||||
tempCursor.setPosition(it.fragment().position());
|
||||
tempCursor.setPosition(it.fragment().position() + it.fragment().length(), QTextCursor::KeepAnchor);
|
||||
tempCursor.setCharFormat(charFormat);
|
||||
}
|
||||
*/
|
||||
cursor.select(QTextCursor::BlockUnderCursor);
|
||||
|
||||
auto charFormat = cursor.charFormat();
|
||||
charFormat.setFont(font);
|
||||
charFormat.setFontCapitalization(QFont::AllUppercase);
|
||||
charFormat.setForeground(QBrush(foreground));
|
||||
cursor.setCharFormat(charFormat);
|
||||
}
|
||||
|
||||
|
||||
TransmitTextEdit::TransmitTextEdit(QWidget *parent):
|
||||
QTextEdit(parent),
|
||||
m_sent { 0 },
|
||||
m_protected { false }
|
||||
{
|
||||
connect(this, &QTextEdit::selectionChanged, this, &TransmitTextEdit::on_selectionChanged);
|
||||
connect(this, &QTextEdit::cursorPositionChanged, this, &TransmitTextEdit::on_selectionChanged);
|
||||
connect(this->document(), &QTextDocument::contentsChange, this, &TransmitTextEdit::on_textContentsChanged);
|
||||
installEventFilter(this);
|
||||
}
|
||||
|
||||
void TransmitTextEdit::setCharsSent(int n){
|
||||
// never can send more than the document length
|
||||
n = qMin(n, document()->characterCount());
|
||||
|
||||
// update sent display
|
||||
auto c = textCursor();
|
||||
c.movePosition(QTextCursor::Start);
|
||||
c.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, n);
|
||||
|
||||
// keep track of sent text
|
||||
m_textSent = c.selectedText().toUpper();
|
||||
m_sent = n;
|
||||
|
||||
// highlight the sent text
|
||||
highlight();
|
||||
}
|
||||
|
||||
// override
|
||||
QString TransmitTextEdit::toPlainText() const {
|
||||
return QTextEdit::toPlainText().toUpper();
|
||||
}
|
||||
|
||||
// override
|
||||
void TransmitTextEdit::setPlainText(const QString &text){
|
||||
QTextEdit::setPlainText(text);
|
||||
m_textSent.clear();
|
||||
m_sent = 0;
|
||||
}
|
||||
|
||||
//
|
||||
void TransmitTextEdit::replaceUnsentText(const QString &text, bool keepCursor){
|
||||
auto rel = relativeTextCursorPosition(textCursor());
|
||||
auto c = textCursor();
|
||||
c.movePosition(QTextCursor::Start);
|
||||
c.movePosition(QTextCursor::NextCharacter, QTextCursor::MoveAnchor, m_sent);
|
||||
c.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
|
||||
c.removeSelectedText();
|
||||
c.insertText(text);
|
||||
|
||||
// keep cursor
|
||||
if(keepCursor){
|
||||
c.movePosition(QTextCursor::End);
|
||||
c.movePosition(QTextCursor::PreviousCharacter, QTextCursor::MoveAnchor, rel.first);
|
||||
c.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, rel.second - rel.first);
|
||||
setTextCursor(c);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
void TransmitTextEdit::replacePlainText(const QString &text, bool keepCursor){
|
||||
auto rel = relativeTextCursorPosition(textCursor());
|
||||
auto c = textCursor();
|
||||
c.movePosition(QTextCursor::Start);
|
||||
c.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
|
||||
c.removeSelectedText();
|
||||
c.insertText(text);
|
||||
|
||||
// keep cursor
|
||||
if(keepCursor){
|
||||
c.movePosition(QTextCursor::End);
|
||||
c.movePosition(QTextCursor::PreviousCharacter, QTextCursor::MoveAnchor, rel.first);
|
||||
c.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, rel.second - rel.first);
|
||||
setTextCursor(c);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
void TransmitTextEdit::setFont(QFont f){
|
||||
m_font = f;
|
||||
|
||||
// then rehighlight
|
||||
highlight();
|
||||
}
|
||||
|
||||
//
|
||||
void TransmitTextEdit::setFont(QFont f, QColor fg, QColor bg){
|
||||
m_font = f;
|
||||
m_fg = fg;
|
||||
m_bg = bg;
|
||||
|
||||
// then rehighlight
|
||||
highlight();
|
||||
}
|
||||
|
||||
// override
|
||||
void TransmitTextEdit::clear(){
|
||||
QTextEdit::clear();
|
||||
m_textSent.clear();
|
||||
m_sent = 0;
|
||||
}
|
||||
|
||||
void TransmitTextEdit::setProtected(bool protect){
|
||||
m_protected = protect;
|
||||
}
|
||||
|
||||
bool TransmitTextEdit::cursorShouldBeProtected(QTextCursor c){
|
||||
int start = c.selectionStart();
|
||||
int end = c.selectionEnd();
|
||||
if(end < start){
|
||||
int x = end;
|
||||
end = start;
|
||||
start = x;
|
||||
}
|
||||
|
||||
//qDebug() << "selection" << start << end << m_sent;
|
||||
|
||||
if(m_sent && start <= m_sent){
|
||||
qDebug() << "cursor in protected zone" << start << "<=" << m_sent;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// slot
|
||||
void TransmitTextEdit::on_selectionChanged(){
|
||||
auto c = textCursor();
|
||||
|
||||
auto shouldProtect = cursorShouldBeProtected(c);
|
||||
|
||||
if(shouldProtect){
|
||||
blockSignals(true);
|
||||
{
|
||||
int end = c.selectionEnd();
|
||||
c.movePosition(QTextCursor::Start);
|
||||
c.movePosition(QTextCursor::NextCharacter, QTextCursor::MoveAnchor, m_sent);
|
||||
c.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, qMax(0, end-m_sent));
|
||||
setTextCursor(c);
|
||||
}
|
||||
blockSignals(false);
|
||||
}
|
||||
|
||||
setProtected(shouldProtect);
|
||||
}
|
||||
|
||||
// slot
|
||||
void TransmitTextEdit::on_textContentsChanged(int /*pos*/, int rem, int add){
|
||||
if(rem == 0 && add == 0){
|
||||
return;
|
||||
}
|
||||
|
||||
QString text = toPlainText();
|
||||
if(text == m_lastText){
|
||||
return;
|
||||
}
|
||||
|
||||
#if JS8_ALLOW_EXTENDED
|
||||
QString normalized = text;
|
||||
#else
|
||||
QString normalized = text.normalized(QString::NormalizationForm_KD);
|
||||
#endif
|
||||
|
||||
QString result;
|
||||
std::copy_if(normalized.begin(), normalized.end(), std::back_inserter(result), [](QChar& c) {
|
||||
#if JS8_ALLOW_UNICODE
|
||||
return (c == 10 || c == 0x1A || (c > 31 && c < 128)) || c.isPrint());
|
||||
#elif JS8_ALLOW_EXTENDED
|
||||
return c.toLatin1() != 0 && (c == 10 || c == 0x1A || (c > 31 && c < 128) || Varicode::extendedChars().contains(c.toUpper()));
|
||||
#else
|
||||
return c.toLatin1() != 0 && (c == 10 || c == 0x1A || (c > 31 && c < 128));
|
||||
#endif
|
||||
});
|
||||
|
||||
if(result != text){
|
||||
bool blocked = signalsBlocked();
|
||||
blockSignals(true);
|
||||
{
|
||||
replacePlainText(result, true);
|
||||
text = result;
|
||||
}
|
||||
blockSignals(blocked);
|
||||
}
|
||||
|
||||
highlight();
|
||||
|
||||
m_dirty = true;
|
||||
m_lastText = text;
|
||||
}
|
||||
|
||||
void TransmitTextEdit::highlightBase(){
|
||||
auto d = document();
|
||||
if(!d){
|
||||
return;
|
||||
}
|
||||
|
||||
auto block = d->firstBlock();
|
||||
while(block.isValid()){
|
||||
highlightBlock(block, m_font, m_fg, m_bg);
|
||||
block = block.next();
|
||||
}
|
||||
}
|
||||
|
||||
void TransmitTextEdit::highlightCharsSent(){
|
||||
if(!m_sent){
|
||||
return;
|
||||
}
|
||||
|
||||
auto d = document();
|
||||
if(!d){
|
||||
return;
|
||||
}
|
||||
|
||||
// highlight sent text
|
||||
auto c = textCursor();
|
||||
if(c.isNull()){
|
||||
return;
|
||||
}
|
||||
c.movePosition(QTextCursor::Start);
|
||||
c.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, m_sent);
|
||||
|
||||
auto ch = c.charFormat();
|
||||
ch.setFontStrikeOut(true);
|
||||
c.mergeCharFormat(ch);
|
||||
}
|
||||
|
||||
void TransmitTextEdit::highlight(){
|
||||
highlightBase();
|
||||
highlightCharsSent();
|
||||
}
|
||||
|
||||
QTextCursor::MoveOperation deleteKeyEventToMoveOperation(QKeyEvent *e){
|
||||
QTextCursor::MoveOperation op = QTextCursor::NoMove;
|
||||
|
||||
#if 0
|
||||
if (e == QKeySequence::Delete) {
|
||||
op = QTextCursor::PreviousCharacter;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (e == QKeySequence::DeleteStartOfWord) {
|
||||
op = QTextCursor::StartOfWord;
|
||||
}
|
||||
else if (e == QKeySequence::DeleteEndOfWord) {
|
||||
op = QTextCursor::EndOfWord;
|
||||
}
|
||||
else if (e == QKeySequence::DeleteCompleteLine) {
|
||||
op = QTextCursor::StartOfLine;
|
||||
}
|
||||
else if (e == QKeySequence::DeleteEndOfLine) {
|
||||
op = QTextCursor::EndOfLine;
|
||||
}
|
||||
|
||||
return op;
|
||||
}
|
||||
|
||||
bool isDeleteKeyEvent(QKeyEvent *e){
|
||||
return deleteKeyEventToMoveOperation(e) != QTextCursor::NoMove;
|
||||
}
|
||||
|
||||
QTextCursor::MoveOperation movementKeyEventToMoveOperation(QKeyEvent *e){
|
||||
QTextCursor::MoveOperation op = QTextCursor::NoMove;
|
||||
|
||||
if (e == QKeySequence::Delete) {
|
||||
op = QTextCursor::PreviousCharacter;
|
||||
}
|
||||
else if (e == QKeySequence::DeleteStartOfWord) {
|
||||
op = QTextCursor::StartOfWord;
|
||||
}
|
||||
else if (e == QKeySequence::DeleteEndOfWord) {
|
||||
op = QTextCursor::EndOfWord;
|
||||
}
|
||||
else if (e == QKeySequence::DeleteCompleteLine) {
|
||||
op = QTextCursor::StartOfLine;
|
||||
}
|
||||
else if (e == QKeySequence::DeleteEndOfLine) {
|
||||
op = QTextCursor::EndOfLine;
|
||||
}
|
||||
else if (e == QKeySequence::MoveToNextChar) {
|
||||
op = QTextCursor::Right;
|
||||
}
|
||||
else if (e == QKeySequence::MoveToPreviousChar) {
|
||||
op = QTextCursor::Left;
|
||||
}
|
||||
else if (e == QKeySequence::SelectNextChar) {
|
||||
op = QTextCursor::Right;
|
||||
}
|
||||
else if (e == QKeySequence::SelectPreviousChar) {
|
||||
op = QTextCursor::Left;
|
||||
}
|
||||
else if (e == QKeySequence::SelectNextWord) {
|
||||
op = QTextCursor::WordRight;
|
||||
}
|
||||
else if (e == QKeySequence::SelectPreviousWord) {
|
||||
op = QTextCursor::WordLeft;
|
||||
}
|
||||
else if (e == QKeySequence::SelectStartOfLine) {
|
||||
op = QTextCursor::StartOfLine;
|
||||
}
|
||||
else if (e == QKeySequence::SelectEndOfLine) {
|
||||
op = QTextCursor::EndOfLine;
|
||||
}
|
||||
else if (e == QKeySequence::SelectStartOfBlock) {
|
||||
op = QTextCursor::StartOfBlock;
|
||||
}
|
||||
else if (e == QKeySequence::SelectEndOfBlock) {
|
||||
op = QTextCursor::EndOfBlock;
|
||||
}
|
||||
else if (e == QKeySequence::SelectStartOfDocument) {
|
||||
op = QTextCursor::Start;
|
||||
}
|
||||
else if (e == QKeySequence::SelectEndOfDocument) {
|
||||
op = QTextCursor::End;
|
||||
}
|
||||
else if (e == QKeySequence::SelectPreviousLine) {
|
||||
op = QTextCursor::Up;
|
||||
}
|
||||
else if (e == QKeySequence::SelectNextLine) {
|
||||
op = QTextCursor::Down;
|
||||
}
|
||||
else if (e == QKeySequence::MoveToNextWord) {
|
||||
op = QTextCursor::WordRight;
|
||||
}
|
||||
else if (e == QKeySequence::MoveToPreviousWord) {
|
||||
op = QTextCursor::WordLeft;
|
||||
}
|
||||
else if (e == QKeySequence::MoveToEndOfBlock) {
|
||||
op = QTextCursor::EndOfBlock;
|
||||
}
|
||||
else if (e == QKeySequence::MoveToStartOfBlock) {
|
||||
op = QTextCursor::StartOfBlock;
|
||||
}
|
||||
else if (e == QKeySequence::MoveToNextLine) {
|
||||
op = QTextCursor::Down;
|
||||
}
|
||||
else if (e == QKeySequence::MoveToPreviousLine) {
|
||||
op = QTextCursor::Up;
|
||||
}
|
||||
else if (e == QKeySequence::MoveToPreviousLine) {
|
||||
op = QTextCursor::Up;
|
||||
}
|
||||
else if (e == QKeySequence::MoveToStartOfLine) {
|
||||
op = QTextCursor::StartOfLine;
|
||||
}
|
||||
else if (e == QKeySequence::MoveToEndOfLine) {
|
||||
op = QTextCursor::EndOfLine;
|
||||
}
|
||||
else if (e == QKeySequence::MoveToStartOfDocument) {
|
||||
op = QTextCursor::Start;
|
||||
}
|
||||
else if (e == QKeySequence::MoveToEndOfDocument) {
|
||||
op = QTextCursor::End;
|
||||
}
|
||||
|
||||
return op;
|
||||
}
|
||||
|
||||
bool isMovementKeyEvent(QKeyEvent * k){
|
||||
return movementKeyEventToMoveOperation(k) != QTextCursor::NoMove;
|
||||
}
|
||||
|
||||
bool TransmitTextEdit::eventFilter(QObject */*o*/, QEvent *e){
|
||||
if(e->type() != QEvent::KeyPress){
|
||||
return false;
|
||||
}
|
||||
|
||||
// -1. don't filter the escape key, return key, or enter key here
|
||||
QKeyEvent *k = static_cast<QKeyEvent *>(e);
|
||||
if(k->key() == Qt::Key_Escape){
|
||||
return false;
|
||||
}
|
||||
|
||||
if(k->key() == Qt::Key_Return || k->key() == Qt::Key_Enter){
|
||||
return false;
|
||||
}
|
||||
|
||||
auto c = textCursor();
|
||||
|
||||
auto c2 = QTextCursor(c);
|
||||
|
||||
auto op = movementKeyEventToMoveOperation(k);
|
||||
c2.movePosition(op);
|
||||
|
||||
bool shouldBeProtected = cursorShouldBeProtected(c2);
|
||||
|
||||
// -1. if this is a delete event (like Ctrl+Backspace) and it should be protected, force protection
|
||||
if(isDeleteKeyEvent(k)){
|
||||
// if we technically shouldn't be protected...check to see if the previous character is a space
|
||||
// if it is, let's try the move operation from before the space, since the space can cause
|
||||
// word coallescing in the qtextdocument making the operation not actually move the cursor
|
||||
if(!shouldBeProtected){
|
||||
auto c3 = QTextCursor(c);
|
||||
c3.movePosition(QTextCursor::PreviousCharacter);
|
||||
if(c.document()->characterAt(qMin(c3.selectionStart(), c3.selectionEnd())).isSpace()){
|
||||
c3.movePosition(op);
|
||||
shouldBeProtected = cursorShouldBeProtected(c3);
|
||||
}
|
||||
}
|
||||
|
||||
if(shouldBeProtected){
|
||||
k->ignore();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// 0. only filter when in a protected range
|
||||
// 0b. but only if we're not moving/deleting _into_ the protected range :/
|
||||
if(!isProtected() && !shouldBeProtected){
|
||||
return false;
|
||||
}
|
||||
|
||||
// 1. do not filter movement sequences
|
||||
if(isMovementKeyEvent(k)){
|
||||
return false;
|
||||
}
|
||||
|
||||
// 2. if on the edge, do not filter if not a backspace
|
||||
int start = qMin(c.selectionStart(), c.selectionEnd());
|
||||
if(start == m_sent && k->key() != Qt::Key_Backspace){
|
||||
return false;
|
||||
}
|
||||
|
||||
// 3. if on the edge, do not filter if a backspace and there is text selected
|
||||
int end = qMax(c.selectionStart(), c.selectionEnd());
|
||||
if(start == m_sent && start != end && k->key() == Qt::Key_Backspace){
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
#ifndef TRANSMITTEXTEDIT_H
|
||||
#define TRANSMITTEXTEDIT_H
|
||||
|
||||
#include "qt_helpers.hpp"
|
||||
|
||||
#include <QTextEdit>
|
||||
#include <QTextBlock>
|
||||
#include <QTextCursor>
|
||||
#include <QBrush>
|
||||
#include <QColor>
|
||||
#include <QFont>
|
||||
|
||||
void setTextEditFont(QTextEdit *edit, QFont font);
|
||||
void setTextEditStyle(QTextEdit *edit, QColor fg, QColor bg, QFont font);
|
||||
void highlightBlock(QTextBlock block, QFont font, QColor foreground, QColor background);
|
||||
|
||||
class TransmitTextEdit : public QTextEdit
|
||||
{
|
||||
public:
|
||||
TransmitTextEdit(QWidget *parent);
|
||||
|
||||
static QPair<int,int> relativeTextCursorPosition(QTextCursor cursor){
|
||||
auto c = QTextCursor(cursor);
|
||||
c.movePosition(QTextCursor::End);
|
||||
int last = c.position();
|
||||
|
||||
auto cc = QTextCursor(cursor);
|
||||
int relstart = last - qMin(cc.selectionStart(), cc.selectionEnd());
|
||||
int relend = last - qMax(cc.selectionStart(), cc.selectionEnd());
|
||||
|
||||
return {relstart, relend};
|
||||
}
|
||||
|
||||
int charsSent() const {
|
||||
return m_sent;
|
||||
}
|
||||
void setCharsSent(int n);
|
||||
|
||||
QString sentText() const {
|
||||
return m_textSent;
|
||||
}
|
||||
|
||||
QString unsentText() const {
|
||||
return toPlainText().mid(charsSent());
|
||||
}
|
||||
|
||||
QString toPlainText() const;
|
||||
void setPlainText(const QString &text);
|
||||
void replaceUnsentText(const QString &text, bool keepCursor);
|
||||
void replacePlainText(const QString &text, bool keepCursor);
|
||||
|
||||
void setFont(QFont f);
|
||||
void setFont(QFont f, QColor fg, QColor bg);
|
||||
void clear();
|
||||
|
||||
bool isProtected() const {
|
||||
return m_protected;
|
||||
}
|
||||
void setProtected(bool protect);
|
||||
bool cursorShouldBeProtected(QTextCursor c);
|
||||
|
||||
bool isEmpty() const {
|
||||
return toPlainText().isEmpty();
|
||||
}
|
||||
bool isDirty() const {
|
||||
return m_dirty;
|
||||
}
|
||||
void setClean(){
|
||||
m_dirty = false;
|
||||
}
|
||||
|
||||
void highlightBase();
|
||||
void highlightCharsSent();
|
||||
void highlight();
|
||||
|
||||
bool eventFilter(QObject */*o*/, QEvent *e);
|
||||
|
||||
public slots:
|
||||
void on_selectionChanged();
|
||||
void on_textContentsChanged(int pos, int rem, int add);
|
||||
|
||||
private:
|
||||
QString m_lastText;
|
||||
int m_sent;
|
||||
QString m_textSent;
|
||||
bool m_protected;
|
||||
bool m_dirty;
|
||||
QFont m_font;
|
||||
QColor m_fg;
|
||||
QColor m_bg;
|
||||
};
|
||||
|
||||
#endif // TRANSMITTEXTEDIT_H
|
||||
@@ -1,6 +1,6 @@
|
||||
# Version number components
|
||||
set (WSJTX_VERSION_MAJOR 1)
|
||||
set (WSJTX_VERSION_MINOR 0)
|
||||
set (WSJTX_VERSION_PATCH 0)
|
||||
set (WSJTX_RC 1) # release candidate number, comment out or zero for development versions
|
||||
set (WSJTX_VERSION_IS_RELEASE 0) # set to 1 for final release build
|
||||
set (WSJTX_VERSION_MAJOR 2)
|
||||
set (WSJTX_VERSION_MINOR 1)
|
||||
set (WSJTX_VERSION_PATCH 1)
|
||||
set (WSJTX_RC 0) # release candidate number, comment out or zero for development versions
|
||||
set (WSJTX_VERSION_IS_RELEASE 1) # set to 1 for final release build
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of The Qt Company Ltd nor the names of its
|
||||
** contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <qendian.h>
|
||||
#include <QVector>
|
||||
#include <QDebug>
|
||||
#include "WaveFile.h"
|
||||
|
||||
struct chunk
|
||||
{
|
||||
char id[4];
|
||||
quint32 size;
|
||||
};
|
||||
|
||||
struct RIFFHeader
|
||||
{
|
||||
chunk descriptor; // "RIFF"
|
||||
char type[4]; // "WAVE"
|
||||
};
|
||||
|
||||
struct WAVEHeader
|
||||
{
|
||||
chunk descriptor;
|
||||
quint16 audioFormat;
|
||||
quint16 numChannels;
|
||||
quint32 sampleRate;
|
||||
quint32 byteRate;
|
||||
quint16 blockAlign;
|
||||
quint16 bitsPerSample;
|
||||
};
|
||||
|
||||
struct DATAHeader
|
||||
{
|
||||
chunk descriptor;
|
||||
};
|
||||
|
||||
struct CombinedHeader
|
||||
{
|
||||
RIFFHeader riff;
|
||||
WAVEHeader wave;
|
||||
};
|
||||
|
||||
WaveFile::WaveFile(QObject *parent)
|
||||
: QFile(parent)
|
||||
, m_headerLength(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool WaveFile::open(const QString &fileName)
|
||||
{
|
||||
close();
|
||||
setFileName(fileName);
|
||||
return QFile::open(QIODevice::ReadOnly) && readHeader();
|
||||
}
|
||||
|
||||
const QAudioFormat &WaveFile::fileFormat() const
|
||||
{
|
||||
return m_fileFormat;
|
||||
}
|
||||
|
||||
qint64 WaveFile::headerLength() const
|
||||
{
|
||||
return m_headerLength;
|
||||
}
|
||||
|
||||
bool WaveFile::readHeader()
|
||||
{
|
||||
seek(0);
|
||||
CombinedHeader header;
|
||||
bool result = read(reinterpret_cast<char *>(&header), sizeof(CombinedHeader)) == sizeof(CombinedHeader);
|
||||
if (result) {
|
||||
if ((memcmp(&header.riff.descriptor.id, "RIFF", 4) == 0
|
||||
|| memcmp(&header.riff.descriptor.id, "RIFX", 4) == 0)
|
||||
&& memcmp(&header.riff.type, "WAVE", 4) == 0
|
||||
&& memcmp(&header.wave.descriptor.id, "fmt ", 4) == 0
|
||||
&& (header.wave.audioFormat == 1 || header.wave.audioFormat == 0)) {
|
||||
|
||||
// Read off remaining header information
|
||||
DATAHeader dataHeader;
|
||||
|
||||
if (qFromLittleEndian<quint32>(header.wave.descriptor.size) > sizeof(WAVEHeader)) {
|
||||
// Extended data available
|
||||
quint16 extraFormatBytes;
|
||||
if (peek((char*)&extraFormatBytes, sizeof(quint16)) != sizeof(quint16))
|
||||
return false;
|
||||
const qint64 throwAwayBytes = sizeof(quint16) + qFromLittleEndian<quint16>(extraFormatBytes);
|
||||
if (read(throwAwayBytes).size() != throwAwayBytes)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (read((char*)&dataHeader, sizeof(DATAHeader)) != sizeof(DATAHeader))
|
||||
return false;
|
||||
|
||||
// Establish format
|
||||
if (memcmp(&header.riff.descriptor.id, "RIFF", 4) == 0)
|
||||
m_fileFormat.setByteOrder(QAudioFormat::LittleEndian);
|
||||
else
|
||||
m_fileFormat.setByteOrder(QAudioFormat::BigEndian);
|
||||
|
||||
int bps = qFromLittleEndian<quint16>(header.wave.bitsPerSample);
|
||||
m_fileFormat.setChannelCount(qFromLittleEndian<quint16>(header.wave.numChannels));
|
||||
m_fileFormat.setCodec("audio/pcm");
|
||||
m_fileFormat.setSampleRate(qFromLittleEndian<quint32>(header.wave.sampleRate));
|
||||
m_fileFormat.setSampleSize(qFromLittleEndian<quint16>(header.wave.bitsPerSample));
|
||||
m_fileFormat.setSampleType(bps == 8 ? QAudioFormat::UnSignedInt : QAudioFormat::SignedInt);
|
||||
} else {
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
m_headerLength = pos();
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of The Qt Company Ltd nor the names of its
|
||||
** contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef WAVEFILE_H
|
||||
#define WAVEFILE_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QFile>
|
||||
#include <QAudioFormat>
|
||||
|
||||
class WaveFile : public QFile
|
||||
{
|
||||
public:
|
||||
WaveFile(QObject *parent = 0);
|
||||
|
||||
using QFile::open;
|
||||
bool open(const QString &fileName);
|
||||
const QAudioFormat &fileFormat() const;
|
||||
qint64 headerLength() const;
|
||||
|
||||
private:
|
||||
bool readHeader();
|
||||
|
||||
private:
|
||||
QAudioFormat m_fileFormat;
|
||||
qint64 m_headerLength;
|
||||
};
|
||||
|
||||
#endif // WAVEFILE_H
|
||||
@@ -0,0 +1,138 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of The Qt Company Ltd nor the names of its
|
||||
** contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QAudioFormat>
|
||||
#include "WaveUtils.h"
|
||||
|
||||
qint64 audioDuration(const QAudioFormat &format, qint64 bytes)
|
||||
{
|
||||
return (bytes * 1000000) /
|
||||
(format.sampleRate() * format.channelCount() * (format.sampleSize() / 8));
|
||||
}
|
||||
|
||||
qint64 audioLength(const QAudioFormat &format, qint64 microSeconds)
|
||||
{
|
||||
qint64 result = (format.sampleRate() * format.channelCount() * (format.sampleSize() / 8))
|
||||
* microSeconds / 1000000;
|
||||
result -= result % (format.channelCount() * format.sampleSize());
|
||||
return result;
|
||||
}
|
||||
|
||||
qreal nyquistFrequency(const QAudioFormat &format)
|
||||
{
|
||||
return format.sampleRate() / 2;
|
||||
}
|
||||
|
||||
QString formatToString(const QAudioFormat &format)
|
||||
{
|
||||
QString result;
|
||||
|
||||
if (QAudioFormat() != format) {
|
||||
if (format.codec() == "audio/pcm") {
|
||||
Q_ASSERT(format.sampleType() == QAudioFormat::SignedInt);
|
||||
|
||||
const QString formatEndian = (format.byteOrder() == QAudioFormat::LittleEndian)
|
||||
? QString("LE") : QString("BE");
|
||||
|
||||
QString formatType;
|
||||
switch (format.sampleType()) {
|
||||
case QAudioFormat::SignedInt:
|
||||
formatType = "signed";
|
||||
break;
|
||||
case QAudioFormat::UnSignedInt:
|
||||
formatType = "unsigned";
|
||||
break;
|
||||
case QAudioFormat::Float:
|
||||
formatType = "float";
|
||||
break;
|
||||
case QAudioFormat::Unknown:
|
||||
formatType = "unknown";
|
||||
break;
|
||||
}
|
||||
|
||||
QString formatChannels = QString("%1 channels").arg(format.channelCount());
|
||||
switch (format.channelCount()) {
|
||||
case 1:
|
||||
formatChannels = "mono";
|
||||
break;
|
||||
case 2:
|
||||
formatChannels = "stereo";
|
||||
break;
|
||||
}
|
||||
|
||||
result = QString("%1 Hz %2 bit %3 %4 %5")
|
||||
.arg(format.sampleRate())
|
||||
.arg(format.sampleSize())
|
||||
.arg(formatType)
|
||||
.arg(formatEndian)
|
||||
.arg(formatChannels);
|
||||
} else {
|
||||
result = format.codec();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool isPCM(const QAudioFormat &format)
|
||||
{
|
||||
return (format.codec() == "audio/pcm");
|
||||
}
|
||||
|
||||
bool isPCMS16LE(const QAudioFormat &format)
|
||||
{
|
||||
return isPCM(format) &&
|
||||
format.sampleType() == QAudioFormat::SignedInt &&
|
||||
format.sampleSize() == 16 &&
|
||||
format.byteOrder() == QAudioFormat::LittleEndian;
|
||||
}
|
||||
|
||||
const qint16 PCMS16MaxValue = 32767;
|
||||
const quint16 PCMS16MaxAmplitude = 32768; // because minimum is -32768
|
||||
|
||||
qreal pcmToReal(qint16 pcm)
|
||||
{
|
||||
return qreal(pcm) / PCMS16MaxAmplitude;
|
||||
}
|
||||
|
||||
qint16 realToPcm(qreal real)
|
||||
{
|
||||
return real * PCMS16MaxValue;
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of The Qt Company Ltd nor the names of its
|
||||
** contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef WAVEUTILS_H
|
||||
#define WAVEUTILS_H
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
#include <QDebug>
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QAudioFormat)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Miscellaneous utility functions
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
qint64 audioDuration(const QAudioFormat &format, qint64 bytes);
|
||||
qint64 audioLength(const QAudioFormat &format, qint64 microSeconds);
|
||||
|
||||
QString formatToString(const QAudioFormat &format);
|
||||
|
||||
qreal nyquistFrequency(const QAudioFormat &format);
|
||||
|
||||
// Scale PCM value to [-1.0, 1.0]
|
||||
qreal pcmToReal(qint16 pcm);
|
||||
|
||||
// Scale real value in [-1.0, 1.0] to PCM
|
||||
qint16 realToPcm(qreal real);
|
||||
|
||||
// Check whether the audio format is PCM
|
||||
bool isPCM(const QAudioFormat &format);
|
||||
|
||||
// Check whether the audio format is signed, little-endian, 16-bit PCM
|
||||
bool isPCMS16LE(const QAudioFormat &format);
|
||||
|
||||
// Compile-time calculation of powers of two
|
||||
|
||||
template<int N> class PowerOfTwo
|
||||
{ public: static const int Result = PowerOfTwo<N-1>::Result * 2; };
|
||||
|
||||
template<> class PowerOfTwo<0>
|
||||
{ public: static const int Result = 1; };
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Debug output
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class NullDebug
|
||||
{
|
||||
public:
|
||||
template <typename T>
|
||||
NullDebug& operator<<(const T&) { return *this; }
|
||||
};
|
||||
|
||||
inline NullDebug nullDebug() { return NullDebug(); }
|
||||
|
||||
#ifdef LOG_ENGINE
|
||||
# define ENGINE_DEBUG qDebug()
|
||||
#else
|
||||
# define ENGINE_DEBUG nullDebug()
|
||||
#endif
|
||||
|
||||
#ifdef LOG_SPECTRUMANALYSER
|
||||
# define SPECTRUMANALYSER_DEBUG qDebug()
|
||||
#else
|
||||
# define SPECTRUMANALYSER_DEBUG nullDebug()
|
||||
#endif
|
||||
|
||||
#ifdef LOG_WAVEFORM
|
||||
# define WAVEFORM_DEBUG qDebug()
|
||||
#else
|
||||
# define WAVEFORM_DEBUG nullDebug()
|
||||
#endif
|
||||
|
||||
#endif // WAVEUTILS_H
|
||||
@@ -23,7 +23,7 @@ CAboutDlg::CAboutDlg(QWidget *parent) :
|
||||
"development group. <br/>JS8Call is "
|
||||
"licensed under and in accordance with the terms "
|
||||
"of the <a href=\"https://www.gnu.org/licenses/gpl-3.0.txt\">GPLv3 license</a>.<br/>"
|
||||
"The source code modifications are public and can be found in <a href=\"https://bitbucket.org/widefido/wsjtx/\">this repository</a>.<br/><br/>"
|
||||
"The source code modifications are public and can be found in <a href=\"https://bitbucket.org/widefido/js8call/\">this repository</a>.<br/><br/>"
|
||||
|
||||
"JS8Call is heavily inspired by WSJT-X, Fldigi, "
|
||||
"and FSQCall <br/>and would not exist without the hard work and "
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
viewBox="0 0 270.93333 270.93334"
|
||||
version="1.1"
|
||||
id="svg16"
|
||||
inkscape:export-filename="/home/jordan/bitmap.png"
|
||||
inkscape:export-xdpi="300.06662"
|
||||
inkscape:export-ydpi="300.06662"
|
||||
inkscape:export-filename="/home/jordan/jtsdk/src/wsjtx/artwork/js8call_icon.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"
|
||||
sodipodi:docname="icon_1024.svg">
|
||||
<defs
|
||||
@@ -38,11 +38,11 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.48333333"
|
||||
inkscape:cx="1350"
|
||||
inkscape:cy="512"
|
||||
inkscape:zoom="0.82"
|
||||
inkscape:cx="619.41789"
|
||||
inkscape:cy="491.10861"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
inkscape:current-layer="g5633"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1053"
|
||||
@@ -50,7 +50,8 @@
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
units="px"
|
||||
inkscape:pagecheckerboard="true" />
|
||||
inkscape:pagecheckerboard="true"
|
||||
showguides="false" />
|
||||
<metadata
|
||||
id="metadata13">
|
||||
<rdf:RDF>
|
||||
@@ -71,25 +72,91 @@
|
||||
<g
|
||||
id="g6030"
|
||||
transform="matrix(1.5635065,0,0,1.5635065,-28.822499,6.8392367)">
|
||||
<circle
|
||||
inkscape:export-ydpi="300.06662"
|
||||
inkscape:export-xdpi="300.06662"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
r="81.642853"
|
||||
cy="98.940475"
|
||||
cx="105.07738"
|
||||
id="path18" />
|
||||
<text
|
||||
id="text24"
|
||||
y="152.33945"
|
||||
x="52.539673"
|
||||
style="font-style:normal;font-weight:normal;font-size:7.09937859px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.17748445"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:176.3888855px;font-family:wasy10;-inkscape-font-specification:wasy10;fill:#000000;stroke-width:0.17748445"
|
||||
y="152.33945"
|
||||
x="52.539673"
|
||||
id="tspan22"
|
||||
sodipodi:role="line">⌁</tspan></text>
|
||||
<g
|
||||
id="g4254">
|
||||
<g
|
||||
id="g5633">
|
||||
<circle
|
||||
inkscape:export-ydpi="300.06662"
|
||||
inkscape:export-xdpi="300.06662"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
r="81.642853"
|
||||
cy="98.940475"
|
||||
cx="105.07738"
|
||||
id="path18" />
|
||||
<g
|
||||
aria-label="J"
|
||||
style="font-style:normal;font-weight:normal;font-size:6.76897335px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.49728441;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="text5787"
|
||||
transform="matrix(1.1302083,0,0,1.1302083,-44.033339,14.076171)">
|
||||
<path
|
||||
d="m 129.49154,20.211895 v 83.918925 c 0,4.1513 0.10921,9.06732 -2.40339,12.78165 -1.85716,2.73112 -5.39174,5.2316 -8.81448,5.26817 -3.95778,0.0423 -7.64506,-2.87946 -10.32017,-5.87252 -3.94648,-0.11707 -3.15405,2.04693 -4.89921,4.20943 4.04204,4.80676 9.83203,6.34006 15.8405,6.34006 6.44543,0 12.34465,-1.97028 15.51276,-7.86948 2.62187,-4.91602 2.62187,-10.05053 2.62187,-14.96655 V 20.211895 Z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-size:67.68972778px;font-family:Inconsolata;-inkscape-font-specification:'Inconsolata Medium';fill:#000000;stroke:#000000;stroke-width:2.4164753;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path5791"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cscaccscscc" />
|
||||
</g>
|
||||
<g
|
||||
id="g5677"
|
||||
transform="matrix(0.79962948,0,0,0.79962948,21.054409,19.824756)">
|
||||
<g
|
||||
aria-label="8"
|
||||
style="font-style:normal;font-weight:normal;font-size:7.09937859px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.17748445"
|
||||
id="text4763"
|
||||
transform="translate(-162.89081,-6.63358)">
|
||||
<path
|
||||
d="m 243.16443,104.08489 c -16.24554,7.31049 -27.34665,23.82678 -27.34665,40.88459 0,20.30692 16.78705,46.57053 52.25647,46.57053 35.46941,0 52.25647,-26.26361 52.25647,-46.57053 0,-13.53794 -7.85201,-32.22031 -27.34665,-40.88459 16.78705,-9.205807 24.3683,-25.7221 24.3683,-40.072323 0,-24.368302 -21.38996,-44.404461 -49.27812,-44.404461 -27.88817,0 -49.27813,20.036159 -49.27813,44.404461 0,23.014508 17.05782,36.281693 24.36831,40.072323 z m 24.90982,-71.751115 c 16.51629,0 34.65714,10.559597 34.65714,31.949551 0,20.577677 -17.05781,33.574105 -34.65714,33.574105 -21.1192,0 -34.65714,-17.057811 -34.65714,-33.574105 0,-12.996428 9.47656,-31.949551 34.65714,-31.949551 z m 0,78.249325 c 24.63906,0 37.63548,18.14085 37.63548,34.38638 0,18.14085 -16.24553,33.84487 -37.63548,33.84487 -21.38996,0 -37.63549,-15.70402 -37.63549,-33.84487 0,-15.97477 12.45491,-34.38638 37.63549,-34.38638 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:270.75891113px;font-family:Courier;-inkscape-font-specification:Courier;fill:#4d4d4d;stroke-width:0.17748445"
|
||||
id="path4765"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<g
|
||||
id="g4796"
|
||||
transform="translate(-163.22926,-6.63358)"
|
||||
style="fill:#808080">
|
||||
<g
|
||||
transform="translate(271.30057,21.863906)"
|
||||
id="text24-5"
|
||||
style="font-style:normal;font-weight:normal;font-size:7.09937811px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#808080;fill-opacity:1;stroke:none;stroke-width:0.17748445"
|
||||
aria-label="8">
|
||||
<path
|
||||
sodipodi:nodetypes="csccscc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4709"
|
||||
d="m 31.577508,38.696619 c 0.1257,1.202533 0.192036,2.442881 0.192036,3.722935 0,20.313754 -16.62316,33.238021 -33.980381,33.566241 8.5005546,1.026719 16.405272,2.973663 24.232789,6.235189 16.787053,-9.205803 24.368303,-25.7219 24.368303,-40.072123 0,-1.161245 -0.04955,-2.31239 -0.145093,-3.452242 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:270.75891113px;font-family:Courier;-inkscape-font-specification:Courier;fill:#808080;stroke-width:0.17748445" />
|
||||
</g>
|
||||
<g
|
||||
transform="translate(0.12624987,0.06768044)"
|
||||
aria-label="8"
|
||||
style="font-style:normal;font-weight:normal;font-size:7.09937859px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#808080;fill-opacity:1;stroke:#ffff00;stroke-width:0;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
id="g4772">
|
||||
<path
|
||||
sodipodi:nodetypes="ccscsccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4770"
|
||||
d="m 1979.2539,532 c 0.2424,0.12732 0.5072,0.2765 0.7461,0.40039 -96,43.2 -161.5996,140.79962 -161.5996,241.59961 v 0.01 c 4.6991,-1.2883 9.9036,-2.01 15.3945,-2.01 h 71.0293 C 1905.847,678.75347 1978.3944,572.381 2124,570.83789 2072.8628,564.05663 2024.3217,559.36095 1979.2539,532 Z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:270.75891113px;font-family:Courier;-inkscape-font-specification:Courier;fill:#808080;stroke-width:0;stroke:#ffff00;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
transform="matrix(0.16922433,0,0,0.16922433,-91.899735,13.989866)" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<rect
|
||||
style="opacity:1;fill:#ffffff;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect5817"
|
||||
width="16.71962"
|
||||
height="2.8891957"
|
||||
x="129.76146"
|
||||
y="62.946335" />
|
||||
<rect
|
||||
style="opacity:1;fill:#ffffff;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect5817-3"
|
||||
width="16.71962"
|
||||
height="2.8891957"
|
||||
x="63.206753"
|
||||
y="127.60851" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 8.7 KiB |
@@ -15,11 +15,11 @@
|
||||
viewBox="0 0 33.866666 33.866667"
|
||||
version="1.1"
|
||||
id="svg16"
|
||||
inkscape:export-filename="/home/jordan/bitmap.png"
|
||||
inkscape:export-xdpi="300.06662"
|
||||
inkscape:export-ydpi="300.06662"
|
||||
inkscape:export-filename="/home/jordan/jtsdk/src/wsjtx/artwork/js8call_icon.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"
|
||||
sodipodi:docname="icon_1024.svg">
|
||||
sodipodi:docname="icon_128.svg">
|
||||
<defs
|
||||
id="defs10">
|
||||
<linearGradient
|
||||
@@ -38,11 +38,11 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.48333333"
|
||||
inkscape:cx="1350"
|
||||
inkscape:cy="512"
|
||||
inkscape:zoom="0.82"
|
||||
inkscape:cx="619.41789"
|
||||
inkscape:cy="491.10861"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
inkscape:current-layer="g5633"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1053"
|
||||
@@ -50,7 +50,8 @@
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
units="px"
|
||||
inkscape:pagecheckerboard="true" />
|
||||
inkscape:pagecheckerboard="true"
|
||||
showguides="false" />
|
||||
<metadata
|
||||
id="metadata13">
|
||||
<rdf:RDF>
|
||||
@@ -70,26 +71,96 @@
|
||||
transform="translate(0,-263.13332)">
|
||||
<g
|
||||
id="g6030"
|
||||
transform="matrix(0.19543832,0,0,0.19543832,-3.6028125,260.72988)">
|
||||
<circle
|
||||
inkscape:export-ydpi="300.06662"
|
||||
inkscape:export-xdpi="300.06662"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
r="81.642853"
|
||||
cy="98.940475"
|
||||
cx="105.07738"
|
||||
id="path18" />
|
||||
<text
|
||||
id="text24"
|
||||
y="152.33945"
|
||||
x="52.539673"
|
||||
style="font-style:normal;font-weight:normal;font-size:7.09937859px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.17748445"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:176.3888855px;font-family:wasy10;-inkscape-font-specification:wasy10;fill:#000000;stroke-width:0.17748445"
|
||||
y="152.33945"
|
||||
x="52.539673"
|
||||
id="tspan22"
|
||||
sodipodi:role="line">⌁</tspan></text>
|
||||
transform="matrix(1.5635065,0,0,1.5635065,-28.822499,6.8392367)">
|
||||
<g
|
||||
id="g4254">
|
||||
<g
|
||||
id="g5633">
|
||||
<g
|
||||
id="g5908"
|
||||
transform="matrix(0.125,0,0,0.125,16.130209,162.38541)">
|
||||
<circle
|
||||
id="path18"
|
||||
cx="105.07738"
|
||||
cy="98.940475"
|
||||
r="81.642853"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
inkscape:export-xdpi="300.06662"
|
||||
inkscape:export-ydpi="300.06662" />
|
||||
<g
|
||||
transform="matrix(1.1302083,0,0,1.1302083,-44.033339,14.076171)"
|
||||
id="text5787"
|
||||
style="font-style:normal;font-weight:normal;font-size:6.76897335px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.49728441;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
aria-label="J">
|
||||
<path
|
||||
sodipodi:nodetypes="cscaccscscc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5791"
|
||||
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-size:67.68972778px;font-family:Inconsolata;-inkscape-font-specification:'Inconsolata Medium';fill:#000000;stroke:#000000;stroke-width:2.4164753;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 129.49154,20.211895 v 83.918925 c 0,4.1513 0.10921,9.06732 -2.40339,12.78165 -1.85716,2.73112 -5.39174,5.2316 -8.81448,5.26817 -3.95778,0.0423 -7.64506,-2.87946 -10.32017,-5.87252 -3.94648,-0.11707 -3.15405,2.04693 -4.89921,4.20943 4.04204,4.80676 9.83203,6.34006 15.8405,6.34006 6.44543,0 12.34465,-1.97028 15.51276,-7.86948 2.62187,-4.91602 2.62187,-10.05053 2.62187,-14.96655 V 20.211895 Z" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(0.79962948,0,0,0.79962948,21.054409,19.824756)"
|
||||
id="g5677">
|
||||
<g
|
||||
transform="translate(-162.89081,-6.63358)"
|
||||
id="text4763"
|
||||
style="font-style:normal;font-weight:normal;font-size:7.09937859px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.17748445"
|
||||
aria-label="8">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4765"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:270.75891113px;font-family:Courier;-inkscape-font-specification:Courier;fill:#4d4d4d;stroke-width:0.17748445"
|
||||
d="m 243.16443,104.08489 c -16.24554,7.31049 -27.34665,23.82678 -27.34665,40.88459 0,20.30692 16.78705,46.57053 52.25647,46.57053 35.46941,0 52.25647,-26.26361 52.25647,-46.57053 0,-13.53794 -7.85201,-32.22031 -27.34665,-40.88459 16.78705,-9.205807 24.3683,-25.7221 24.3683,-40.072323 0,-24.368302 -21.38996,-44.404461 -49.27812,-44.404461 -27.88817,0 -49.27813,20.036159 -49.27813,44.404461 0,23.014508 17.05782,36.281693 24.36831,40.072323 z m 24.90982,-71.751115 c 16.51629,0 34.65714,10.559597 34.65714,31.949551 0,20.577677 -17.05781,33.574105 -34.65714,33.574105 -21.1192,0 -34.65714,-17.057811 -34.65714,-33.574105 0,-12.996428 9.47656,-31.949551 34.65714,-31.949551 z m 0,78.249325 c 24.63906,0 37.63548,18.14085 37.63548,34.38638 0,18.14085 -16.24553,33.84487 -37.63548,33.84487 -21.38996,0 -37.63549,-15.70402 -37.63549,-33.84487 0,-15.97477 12.45491,-34.38638 37.63549,-34.38638 z" />
|
||||
</g>
|
||||
<g
|
||||
style="fill:#808080"
|
||||
transform="translate(-163.22926,-6.63358)"
|
||||
id="g4796">
|
||||
<g
|
||||
aria-label="8"
|
||||
style="font-style:normal;font-weight:normal;font-size:7.09937811px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#808080;fill-opacity:1;stroke:none;stroke-width:0.17748445"
|
||||
id="text24-5"
|
||||
transform="translate(271.30057,21.863906)">
|
||||
<path
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:270.75891113px;font-family:Courier;-inkscape-font-specification:Courier;fill:#808080;stroke-width:0.17748445"
|
||||
d="m 31.577508,38.696619 c 0.1257,1.202533 0.192036,2.442881 0.192036,3.722935 0,20.313754 -16.62316,33.238021 -33.980381,33.566241 8.5005546,1.026719 16.405272,2.973663 24.232789,6.235189 16.787053,-9.205803 24.368303,-25.7219 24.368303,-40.072123 0,-1.161245 -0.04955,-2.31239 -0.145093,-3.452242 z"
|
||||
id="path4709"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="csccscc" />
|
||||
</g>
|
||||
<g
|
||||
id="g4772"
|
||||
style="font-style:normal;font-weight:normal;font-size:7.09937859px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#808080;fill-opacity:1;stroke:#ffff00;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
aria-label="8"
|
||||
transform="translate(0.12624987,0.06768044)">
|
||||
<path
|
||||
transform="matrix(0.16922433,0,0,0.16922433,-91.899735,13.989866)"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:270.75891113px;font-family:Courier;-inkscape-font-specification:Courier;fill:#808080;stroke:#ffff00;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 1979.2539,532 c 0.2424,0.12732 0.5072,0.2765 0.7461,0.40039 -96,43.2 -161.5996,140.79962 -161.5996,241.59961 v 0.01 c 4.6991,-1.2883 9.9036,-2.01 15.3945,-2.01 h 71.0293 C 1905.847,678.75347 1978.3944,572.381 2124,570.83789 2072.8628,564.05663 2024.3217,559.36095 1979.2539,532 Z"
|
||||
id="path4770"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccscsccc" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<rect
|
||||
y="62.946335"
|
||||
x="129.76146"
|
||||
height="2.8891957"
|
||||
width="16.71962"
|
||||
id="rect5817"
|
||||
style="opacity:1;fill:#ffffff;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<rect
|
||||
y="127.60851"
|
||||
x="63.206753"
|
||||
height="2.8891957"
|
||||
width="16.71962"
|
||||
id="rect5817-3"
|
||||
style="opacity:1;fill:#ffffff;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 9.0 KiB |
@@ -16,7 +16,10 @@
|
||||
version="1.1"
|
||||
id="svg16"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"
|
||||
sodipodi:docname="icon_1024.svg">
|
||||
sodipodi:docname="installer_logo.svg"
|
||||
inkscape:export-filename="/home/jordan/jtsdk/src/wsjtx/artwork/installer_logo.svg.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96">
|
||||
<defs
|
||||
id="defs10">
|
||||
<linearGradient
|
||||
@@ -36,8 +39,8 @@
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.48333333"
|
||||
inkscape:cx="1350"
|
||||
inkscape:cy="512"
|
||||
inkscape:cx="263.79309"
|
||||
inkscape:cy="880.82504"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
@@ -65,28 +68,106 @@
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-26.06665)">
|
||||
<rect
|
||||
style="opacity:1;fill:#ffffff;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect129"
|
||||
width="714.375"
|
||||
height="270.93332"
|
||||
x="-1.5894572e-07"
|
||||
y="26.06665" />
|
||||
<g
|
||||
id="g6030"
|
||||
transform="matrix(1.4906384,0,0,1.4906384,-20.910237,15.983062)">
|
||||
<circle
|
||||
inkscape:export-ydpi="300.06662"
|
||||
inkscape:export-xdpi="300.06662"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
r="81.642853"
|
||||
cy="98.940475"
|
||||
cx="105.07738"
|
||||
id="path18" />
|
||||
<text
|
||||
id="text24"
|
||||
y="152.33945"
|
||||
x="52.539673"
|
||||
style="font-style:normal;font-weight:normal;font-size:7.09937859px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.17748445"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:176.3888855px;font-family:wasy10;-inkscape-font-specification:wasy10;fill:#000000;stroke-width:0.17748445"
|
||||
y="152.33945"
|
||||
x="52.539673"
|
||||
id="tspan22"
|
||||
sodipodi:role="line">⌁</tspan></text>
|
||||
transform="matrix(0.97656252,0,0,0.97656252,7.9375003,3.2567706)"
|
||||
id="layer1-7"
|
||||
inkscape:label="Layer 1">
|
||||
<g
|
||||
transform="matrix(1.5635065,0,0,1.5635065,-28.822499,6.8392367)"
|
||||
id="g6030">
|
||||
<g
|
||||
id="g4254">
|
||||
<g
|
||||
id="g5633">
|
||||
<circle
|
||||
id="path18"
|
||||
cx="105.07738"
|
||||
cy="98.940475"
|
||||
r="81.642853"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
inkscape:export-xdpi="300.06662"
|
||||
inkscape:export-ydpi="300.06662" />
|
||||
<g
|
||||
transform="matrix(1.1302083,0,0,1.1302083,-44.033339,14.076171)"
|
||||
id="text5787"
|
||||
style="font-style:normal;font-weight:normal;font-size:6.76897335px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.49728441;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
aria-label="J">
|
||||
<path
|
||||
sodipodi:nodetypes="cscaccscscc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5791"
|
||||
style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-size:67.68972778px;font-family:Inconsolata;-inkscape-font-specification:'Inconsolata Medium';fill:#000000;stroke:#000000;stroke-width:2.4164753;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 129.49154,20.211895 v 83.918925 c 0,4.1513 0.10921,9.06732 -2.40339,12.78165 -1.85716,2.73112 -5.39174,5.2316 -8.81448,5.26817 -3.95778,0.0423 -7.64506,-2.87946 -10.32017,-5.87252 -3.94648,-0.11707 -3.15405,2.04693 -4.89921,4.20943 4.04204,4.80676 9.83203,6.34006 15.8405,6.34006 6.44543,0 12.34465,-1.97028 15.51276,-7.86948 2.62187,-4.91602 2.62187,-10.05053 2.62187,-14.96655 V 20.211895 Z" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(0.79962948,0,0,0.79962948,21.054409,19.824756)"
|
||||
id="g5677">
|
||||
<g
|
||||
transform="translate(-162.89081,-6.63358)"
|
||||
id="text4763"
|
||||
style="font-style:normal;font-weight:normal;font-size:7.09937859px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.17748445"
|
||||
aria-label="8">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4765"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:270.75891113px;font-family:Courier;-inkscape-font-specification:Courier;fill:#4d4d4d;stroke-width:0.17748445"
|
||||
d="m 243.16443,104.08489 c -16.24554,7.31049 -27.34665,23.82678 -27.34665,40.88459 0,20.30692 16.78705,46.57053 52.25647,46.57053 35.46941,0 52.25647,-26.26361 52.25647,-46.57053 0,-13.53794 -7.85201,-32.22031 -27.34665,-40.88459 16.78705,-9.205807 24.3683,-25.7221 24.3683,-40.072323 0,-24.368302 -21.38996,-44.404461 -49.27812,-44.404461 -27.88817,0 -49.27813,20.036159 -49.27813,44.404461 0,23.014508 17.05782,36.281693 24.36831,40.072323 z m 24.90982,-71.751115 c 16.51629,0 34.65714,10.559597 34.65714,31.949551 0,20.577677 -17.05781,33.574105 -34.65714,33.574105 -21.1192,0 -34.65714,-17.057811 -34.65714,-33.574105 0,-12.996428 9.47656,-31.949551 34.65714,-31.949551 z m 0,78.249325 c 24.63906,0 37.63548,18.14085 37.63548,34.38638 0,18.14085 -16.24553,33.84487 -37.63548,33.84487 -21.38996,0 -37.63549,-15.70402 -37.63549,-33.84487 0,-15.97477 12.45491,-34.38638 37.63549,-34.38638 z" />
|
||||
</g>
|
||||
<g
|
||||
style="fill:#808080"
|
||||
transform="translate(-163.22926,-6.63358)"
|
||||
id="g4796">
|
||||
<g
|
||||
aria-label="8"
|
||||
style="font-style:normal;font-weight:normal;font-size:7.09937811px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#808080;fill-opacity:1;stroke:none;stroke-width:0.17748445"
|
||||
id="text24-5"
|
||||
transform="translate(271.30057,21.863906)">
|
||||
<path
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:270.75891113px;font-family:Courier;-inkscape-font-specification:Courier;fill:#808080;stroke-width:0.17748445"
|
||||
d="m 31.577508,38.696619 c 0.1257,1.202533 0.192036,2.442881 0.192036,3.722935 0,20.313754 -16.62316,33.238021 -33.980381,33.566241 8.5005546,1.026719 16.405272,2.973663 24.232789,6.235189 16.787053,-9.205803 24.368303,-25.7219 24.368303,-40.072123 0,-1.161245 -0.04955,-2.31239 -0.145093,-3.452242 z"
|
||||
id="path4709"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="csccscc" />
|
||||
</g>
|
||||
<g
|
||||
id="g4772"
|
||||
style="font-style:normal;font-weight:normal;font-size:7.09937859px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#808080;fill-opacity:1;stroke:#ffff00;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
aria-label="8"
|
||||
transform="translate(0.12624987,0.06768044)">
|
||||
<path
|
||||
transform="matrix(0.16922433,0,0,0.16922433,-91.899735,13.989866)"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:270.75891113px;font-family:Courier;-inkscape-font-specification:Courier;fill:#808080;stroke:#ffff00;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 1979.2539,532 c 0.2424,0.12732 0.5072,0.2765 0.7461,0.40039 -96,43.2 -161.5996,140.79962 -161.5996,241.59961 v 0.01 c 4.6991,-1.2883 9.9036,-2.01 15.3945,-2.01 h 71.0293 C 1905.847,678.75347 1978.3944,572.381 2124,570.83789 2072.8628,564.05663 2024.3217,559.36095 1979.2539,532 Z"
|
||||
id="path4770"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccscsccc" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<rect
|
||||
y="62.946335"
|
||||
x="129.76146"
|
||||
height="2.8891957"
|
||||
width="16.71962"
|
||||
id="rect5817"
|
||||
style="opacity:1;fill:#ffffff;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<rect
|
||||
y="127.60851"
|
||||
x="63.206753"
|
||||
height="2.8891957"
|
||||
width="16.71962"
|
||||
id="rect5817-3"
|
||||
style="opacity:1;fill:#ffffff;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 9.3 KiB |
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 115 KiB After Width: | Height: | Size: 75 KiB |
@@ -2,9 +2,70 @@
|
||||
#define COMMONS_H
|
||||
|
||||
#define NSMAX 6827
|
||||
#define NTMAX 300
|
||||
#define NTMAX 60
|
||||
|
||||
#define RX_SAMPLE_RATE 12000
|
||||
|
||||
#define JS8_USE_REFSPEC 0 // compute the signal refspec
|
||||
#define JS8_USE_IHSYM 0 // compute ihsym manually instead of from symspec
|
||||
#define JS8_RING_BUFFER 1 // use a ring buffer instead of clearing the decode frames
|
||||
#define JS8_SINGLE_DECODE 0 // single submode decode per instantiation of the decoder
|
||||
#define JS8_DECODE_THREAD 1 // use a separate thread for decode process handling
|
||||
#define JS8_ALLOW_EXTENDED 1 // allow extended latin-1 capital charset
|
||||
|
||||
#ifdef QT_DEBUG
|
||||
#define JS8_DEBUG_DECODE 0 // emit debug statements for the decode pipeline
|
||||
#else
|
||||
#define JS8_DEBUG_DECODE 0
|
||||
#endif
|
||||
|
||||
#define JS8_NUM_SYMBOLS 79
|
||||
#define JS8_ENABLE_JS8A 1
|
||||
#define JS8_ENABLE_JS8B 1
|
||||
#define JS8_ENABLE_JS8C 1
|
||||
#define JS8_ENABLE_JS8E 1
|
||||
#define JS8_ENABLE_JS8I 0
|
||||
|
||||
#define JS8A_SYMBOL_SAMPLES 1920
|
||||
#define JS8A_TX_SECONDS 15
|
||||
#define JS8A_START_DELAY_MS 500
|
||||
|
||||
#define JS8B_SYMBOL_SAMPLES 1200
|
||||
#define JS8B_TX_SECONDS 10
|
||||
#define JS8B_START_DELAY_MS 200
|
||||
|
||||
#define JS8C_SYMBOL_SAMPLES 600
|
||||
#define JS8C_TX_SECONDS 6
|
||||
#define JS8C_START_DELAY_MS 100
|
||||
|
||||
#define JS8E_SYMBOL_SAMPLES 3840
|
||||
#define JS8E_TX_SECONDS 30
|
||||
#define JS8E_START_DELAY_MS 500
|
||||
|
||||
#define JS8I_SYMBOL_SAMPLES 384
|
||||
#define JS8I_TX_SECONDS 4
|
||||
#define JS8I_START_DELAY_MS 100
|
||||
|
||||
#ifndef TEST_FOX_WAVE_GEN
|
||||
#define TEST_FOX_WAVE_GEN 0
|
||||
#endif
|
||||
|
||||
#ifndef TEST_FOX_WAVE_GEN_SLOTS
|
||||
#if TEST_FOX_WAVE_GEN
|
||||
#define TEST_FOX_WAVE_GEN_SLOTS 2
|
||||
#else
|
||||
#define TEST_FOX_WAVE_GEN_SLOTS 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef TEST_FOX_WAVE_GEN_OFFSET
|
||||
#if TEST_FOX_WAVE_GEN
|
||||
#define TEST_FOX_WAVE_GEN_OFFSET 25
|
||||
#else
|
||||
#define TEST_FOX_WAVE_GEN_OFFSET 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <cstdbool>
|
||||
extern "C" {
|
||||
@@ -17,28 +78,38 @@ extern "C" {
|
||||
* sync with lib/jt9com.f90
|
||||
*/
|
||||
extern struct dec_data {
|
||||
float ss[184*NSMAX];
|
||||
float ss[184*NSMAX]; // symbol spectra
|
||||
float savg[NSMAX];
|
||||
float sred[5760];
|
||||
short int d2[NTMAX*RX_SAMPLE_RATE];
|
||||
short int d2[NTMAX*RX_SAMPLE_RATE]; // sample frame buffer for sample collection
|
||||
struct
|
||||
{
|
||||
int nutc; //UTC as integer, HHMM
|
||||
bool ndiskdat; //true ==> data read from *.wav file
|
||||
int ntrperiod; //TR period (seconds)
|
||||
int nQSOProgress; /* QSO state machine state */
|
||||
int nfqso; //User-selected QSO freq (kHz)
|
||||
int nftx; /* Transmit audio offset where
|
||||
replies might be expected */
|
||||
bool newdat; //true ==> new data, must do long FFT
|
||||
int npts8; //npts for c0() array
|
||||
int nfa; //Low decode limit (Hz)
|
||||
int nfSplit; //JT65 | JT9 split frequency
|
||||
int nfb; //High decode limit (Hz)
|
||||
int ntol; //+/- decoding range around fQSO (Hz)
|
||||
int kin;
|
||||
int nzhsym;
|
||||
int nsubmode;
|
||||
int nutc; // UTC as integer, HHMM
|
||||
bool ndiskdat; // true ==> data read from *.wav file
|
||||
int ntrperiod; // TR period (seconds)
|
||||
int nQSOProgress; // QSO state machine state
|
||||
int nfqso; // User-selected QSO freq (kHz)
|
||||
int nftx; // Transmit audio offset where replies might be expected
|
||||
bool newdat; // true ==> new data, must do long FFT
|
||||
int npts8; // npts for c0() array
|
||||
int nfa; // Low decode limit (Hz) (filter min)
|
||||
int nfSplit; // JT65 | JT9 split frequency
|
||||
int nfb; // High decode limit (Hz) (filter max)
|
||||
int ntol; // +/- decoding range around fQSO (Hz)
|
||||
int kin; // number of frames written to d2
|
||||
int kposA; // starting position of decode for submode A
|
||||
int kposB; // starting position of decode for submode B
|
||||
int kposC; // starting position of decode for submode C
|
||||
int kposE; // starting position of decode for submode E
|
||||
int kposI; // starting position of decode for submode I
|
||||
int kszA; // number of frames for decode for submode A
|
||||
int kszB; // number of frames for decode for submode B
|
||||
int kszC; // number of frames for decode for submode C
|
||||
int kszE; // number of frames for decode for submode E
|
||||
int kszI; // number of frames for decode for submode I
|
||||
int nzhsym; // half symbol stop index
|
||||
int nsubmode; // which submode to decode (-1 if using nsubmodes)
|
||||
int nsubmodes; // which submodes to decode
|
||||
bool nagain;
|
||||
int ndepth;
|
||||
bool lft8apon;
|
||||
@@ -64,6 +135,7 @@ extern struct dec_data {
|
||||
char mygrid[6];
|
||||
char hiscall[12];
|
||||
char hisgrid[6];
|
||||
int ndebug;
|
||||
} params;
|
||||
} dec_data;
|
||||
|
||||
@@ -73,13 +145,6 @@ extern struct {
|
||||
float filter[3457];
|
||||
} spectra_;
|
||||
|
||||
extern struct {
|
||||
int nclearave;
|
||||
int nsum;
|
||||
float blue[4096];
|
||||
float red[4096];
|
||||
} echocom_;
|
||||
|
||||
extern struct {
|
||||
float wave[606720];
|
||||
int nslots;
|
||||
|
||||
@@ -25,6 +25,7 @@ DecodedText::DecodedText (QString const& the_string, bool contest_mode, QString
|
||||
, isHeartbeat_(false)
|
||||
, isAlt_(false)
|
||||
, bits_{0}
|
||||
, submode_{ string_.mid(column_mode + padding_, 3).trimmed().at(0).cell() - 'A' }
|
||||
{
|
||||
if(message_.length() >= 1) {
|
||||
message_ = message_.left (21).remove (QRegularExpression {"[<>]"});
|
||||
@@ -61,20 +62,16 @@ DecodedText::DecodedText (QString const& the_string, bool contest_mode, QString
|
||||
|
||||
bits_ = bits();
|
||||
|
||||
// don't even try to unpack -24dB frames...they are *very* likely to be false decodes...
|
||||
if(snr() <= -24){
|
||||
return;
|
||||
}
|
||||
|
||||
tryUnpack();
|
||||
}
|
||||
|
||||
DecodedText::DecodedText (QString const& js8callmessage, int bits):
|
||||
DecodedText::DecodedText (QString const& js8callmessage, int bits, int submode):
|
||||
frameType_(Varicode::FrameUnknown),
|
||||
message_(js8callmessage),
|
||||
isHeartbeat_(false),
|
||||
isAlt_(false),
|
||||
bits_(bits)
|
||||
bits_(bits),
|
||||
submode_(submode)
|
||||
{
|
||||
is_standard_ = QRegularExpression("^(CQ|DE|QRZ)\\s").match(message_).hasMatch();
|
||||
|
||||
@@ -89,9 +86,13 @@ bool DecodedText::tryUnpack(){
|
||||
|
||||
bool unpacked = false;
|
||||
if(!unpacked){
|
||||
unpacked = tryUnpackData();
|
||||
unpacked = tryUnpackFastData();
|
||||
}
|
||||
|
||||
if(!unpacked){
|
||||
unpacked = tryUnpackData();
|
||||
}
|
||||
|
||||
if(!unpacked){
|
||||
unpacked = tryUnpackHeartbeat();
|
||||
}
|
||||
@@ -115,6 +116,10 @@ bool DecodedText::tryUnpackHeartbeat(){
|
||||
return false;
|
||||
}
|
||||
|
||||
if((bits_ & Varicode::JS8CallData) == Varicode::JS8CallData){
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isAlt = false;
|
||||
quint8 type = Varicode::FrameUnknown;
|
||||
quint8 bits3 = 0;
|
||||
@@ -159,6 +164,10 @@ bool DecodedText::tryUnpackCompound(){
|
||||
return false;
|
||||
}
|
||||
|
||||
if((bits_ & Varicode::JS8CallData) == Varicode::JS8CallData){
|
||||
return false;
|
||||
}
|
||||
|
||||
QStringList cmp;
|
||||
if(!parts.at(0).isEmpty()){
|
||||
cmp.append(parts.at(0));
|
||||
@@ -188,6 +197,10 @@ bool DecodedText::tryUnpackDirected(){
|
||||
return false;
|
||||
}
|
||||
|
||||
if((bits_ & Varicode::JS8CallData) == Varicode::JS8CallData){
|
||||
return false;
|
||||
}
|
||||
|
||||
quint8 type = Varicode::FrameUnknown;
|
||||
QStringList parts = Varicode::unpackDirectedMessage(m, &type);
|
||||
|
||||
@@ -206,8 +219,6 @@ bool DecodedText::tryUnpackDirected(){
|
||||
message_ = QString(parts.join(""));
|
||||
}
|
||||
|
||||
message_ = message_.replace("APRS: ", "APRS:");
|
||||
|
||||
directed_ = parts;
|
||||
frameType_ = type;
|
||||
return true;
|
||||
@@ -218,7 +229,11 @@ bool DecodedText::tryUnpackData(){
|
||||
|
||||
// data frames calls will always be 12+ chars and contain no spaces.
|
||||
if(m.length() < 12 || m.contains(' ')){
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
if((bits_ & Varicode::JS8CallData) == Varicode::JS8CallData){
|
||||
return false;
|
||||
}
|
||||
|
||||
QString data = Varicode::unpackDataMessage(m);
|
||||
@@ -232,6 +247,38 @@ bool DecodedText::tryUnpackData(){
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DecodedText::tryUnpackFastData(){
|
||||
QString m = message().trimmed();
|
||||
|
||||
// data frames calls will always be 12+ chars and contain no spaces.
|
||||
if(m.length() < 12 || m.contains(' ')){
|
||||
return false;
|
||||
}
|
||||
|
||||
if((bits_ & Varicode::JS8CallData) != Varicode::JS8CallData){
|
||||
return false;
|
||||
}
|
||||
|
||||
if(
|
||||
submode_ != Varicode::JS8CallFast &&
|
||||
submode_ != Varicode::JS8CallTurbo &&
|
||||
submode_ != Varicode::JS8CallSlow &&
|
||||
submode_ != Varicode::JS8CallUltra
|
||||
){
|
||||
return false;
|
||||
}
|
||||
|
||||
QString data = Varicode::unpackFastDataMessage(m);
|
||||
|
||||
if(data.isEmpty()){
|
||||
return false;
|
||||
}
|
||||
|
||||
message_ = data;
|
||||
frameType_ = Varicode::FrameData;
|
||||
return true;
|
||||
}
|
||||
|
||||
QStringList DecodedText::messageWords () const
|
||||
{
|
||||
if (is_standard_)
|
||||
|
||||
@@ -31,13 +31,14 @@ class DecodedText
|
||||
{
|
||||
public:
|
||||
explicit DecodedText (QString const& message, bool, QString const& my_grid);
|
||||
explicit DecodedText (QString const& js8callmessage, int bits);
|
||||
explicit DecodedText (QString const& js8callmessage, int bits, int submode);
|
||||
|
||||
bool tryUnpack();
|
||||
bool tryUnpackHeartbeat();
|
||||
bool tryUnpackCompound();
|
||||
bool tryUnpackDirected();
|
||||
bool tryUnpackData();
|
||||
bool tryUnpackFastData();
|
||||
|
||||
quint8 frameType() const { return frameType_; }
|
||||
|
||||
@@ -73,6 +74,7 @@ public:
|
||||
bool hasBits() const { return !string_.right(5).trimmed().isEmpty(); }
|
||||
int bits() const { return string_.right(5).trimmed().toShort(); }
|
||||
float dt() const;
|
||||
int submode() const { return submode_; }
|
||||
|
||||
// find and extract any report. Returns true if this is a standard message
|
||||
bool report(QString const& myBaseCall, QString const& dxBaseCall, /*mod*/QString& report) const;
|
||||
@@ -110,6 +112,7 @@ private:
|
||||
QString message_;
|
||||
bool is_standard_;
|
||||
int bits_;
|
||||
int submode_;
|
||||
};
|
||||
|
||||
#endif // DECODEDTEXT_H
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
#include "echograph.h"
|
||||
#include "commons.h"
|
||||
#include <QSettings>
|
||||
#include <QApplication>
|
||||
#include "echoplot.h"
|
||||
#include "ui_echograph.h"
|
||||
#include "moc_echograph.cpp"
|
||||
|
||||
#define NSMAX2 1366
|
||||
|
||||
EchoGraph::EchoGraph(QSettings * settings, QWidget *parent) :
|
||||
QDialog {parent, Qt::Window | Qt::WindowTitleHint | Qt::WindowCloseButtonHint | Qt::WindowMinimizeButtonHint},
|
||||
m_settings (settings),
|
||||
ui(new Ui::EchoGraph)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setWindowTitle (QApplication::applicationName () + " - " + tr ("Echo Graph"));
|
||||
installEventFilter(parent); //Installing the filter
|
||||
ui->echoPlot->setCursor(Qt::CrossCursor);
|
||||
setMaximumWidth(2048);
|
||||
setMaximumHeight(880);
|
||||
ui->echoPlot->setMaximumHeight(800);
|
||||
|
||||
//Restore user's settings
|
||||
m_settings->beginGroup("EchoGraph");
|
||||
restoreGeometry (m_settings->value ("geometry", saveGeometry ()).toByteArray ());
|
||||
ui->echoPlot->setPlotZero(m_settings->value("PlotZero", 0).toInt());
|
||||
ui->echoPlot->setPlotGain(m_settings->value("PlotGain", 0).toInt());
|
||||
ui->zeroSlider->setValue(ui->echoPlot->getPlotZero());
|
||||
ui->gainSlider->setValue(ui->echoPlot->getPlotGain());
|
||||
int n=m_settings->value("Smooth",0).toInt();
|
||||
ui->echoPlot->m_smooth=n;
|
||||
ui->smoothSpinBox->setValue(n);
|
||||
n=m_settings->value("EchoBPP",1).toInt();
|
||||
ui->echoPlot->m_binsPerPixel=n;
|
||||
ui->binsPerPixelSpinBox->setValue(n);
|
||||
ui->echoPlot->m_blue=m_settings->value("BlueCurve",false).toBool();
|
||||
m_nColor=m_settings->value("EchoColors",0).toInt();
|
||||
m_settings->endGroup();
|
||||
ui->echoPlot->setColors(m_nColor);
|
||||
}
|
||||
|
||||
EchoGraph::~EchoGraph()
|
||||
{
|
||||
saveSettings();
|
||||
}
|
||||
|
||||
void EchoGraph::closeEvent (QCloseEvent * e)
|
||||
{
|
||||
saveSettings ();
|
||||
QDialog::closeEvent (e);
|
||||
}
|
||||
|
||||
void EchoGraph::saveSettings()
|
||||
{
|
||||
//Save user's settings
|
||||
m_settings->beginGroup("EchoGraph");
|
||||
m_settings->setValue ("geometry", saveGeometry ());
|
||||
m_settings->setValue("PlotZero",ui->echoPlot->m_plotZero);
|
||||
m_settings->setValue("PlotGain",ui->echoPlot->m_plotGain);
|
||||
m_settings->setValue("Smooth",ui->echoPlot->m_smooth);
|
||||
m_settings->setValue("EchoBPP",ui->echoPlot->m_binsPerPixel);
|
||||
m_settings->setValue("BlueCurve",ui->echoPlot->m_blue);
|
||||
m_settings->setValue("EchoColors",m_nColor);
|
||||
m_settings->endGroup();
|
||||
}
|
||||
|
||||
void EchoGraph::plotSpec()
|
||||
{
|
||||
ui->echoPlot->draw();
|
||||
ui->nsum_label->setText("N: " + QString::number(echocom_.nsum));
|
||||
}
|
||||
|
||||
void EchoGraph::on_smoothSpinBox_valueChanged(int n)
|
||||
{
|
||||
ui->echoPlot->setSmooth(n);
|
||||
ui->echoPlot->draw();
|
||||
}
|
||||
|
||||
void EchoGraph::on_gainSlider_valueChanged(int value)
|
||||
{
|
||||
ui->echoPlot->setPlotGain(value);
|
||||
ui->echoPlot->draw();
|
||||
}
|
||||
|
||||
void EchoGraph::on_zeroSlider_valueChanged(int value)
|
||||
{
|
||||
ui->echoPlot->setPlotZero(value);
|
||||
ui->echoPlot->draw();
|
||||
}
|
||||
|
||||
void EchoGraph::on_binsPerPixelSpinBox_valueChanged(int n)
|
||||
{
|
||||
ui->echoPlot->m_binsPerPixel=n;
|
||||
ui->echoPlot->DrawOverlay();
|
||||
ui->echoPlot->draw();
|
||||
}
|
||||
|
||||
void EchoGraph::on_pbColors_clicked()
|
||||
{
|
||||
m_nColor = (m_nColor+1) % 6;
|
||||
ui->echoPlot->setColors(m_nColor);
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
#ifndef ECHOGRAPH_H
|
||||
#define ECHOGRAPH_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QScopedPointer>
|
||||
|
||||
namespace Ui {
|
||||
class EchoGraph;
|
||||
}
|
||||
|
||||
class QSettings;
|
||||
|
||||
class EchoGraph : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
protected:
|
||||
void closeEvent (QCloseEvent *) override;
|
||||
|
||||
public:
|
||||
explicit EchoGraph(QSettings *, QWidget *parent = 0);
|
||||
~EchoGraph();
|
||||
|
||||
void plotSpec();
|
||||
void saveSettings();
|
||||
|
||||
private slots:
|
||||
void on_smoothSpinBox_valueChanged(int n);
|
||||
void on_gainSlider_valueChanged(int value);
|
||||
void on_zeroSlider_valueChanged(int value);
|
||||
void on_binsPerPixelSpinBox_valueChanged(int n);
|
||||
void on_pbColors_clicked();
|
||||
|
||||
private:
|
||||
QSettings * m_settings;
|
||||
qint32 m_nColor;
|
||||
|
||||
QScopedPointer<Ui::EchoGraph> ui;
|
||||
};
|
||||
|
||||
#endif // ECHOGRAPH_H
|
||||
@@ -1,294 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>EchoGraph</class>
|
||||
<widget class="QDialog" name="EchoGraph">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>625</width>
|
||||
<height>336</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>570</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Echo Graph</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="EPlotter" name="echoPlot">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>273</width>
|
||||
<height>200</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Sunken</enum>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Expanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="binsPerPixelSpinBox">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Compression factor for frequency scale</p></body></html></string>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string>Bins/Pixel </string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>10</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Gain</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="gainSlider">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Echo spectrum gain</p></body></html></string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-30</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>30</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_7">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Zero</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="zeroSlider">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Echo spectrum zero</p></body></html></string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-150</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>150</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="smoothSpinBox">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Smoothing of echo spectrum</p></body></html></string>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string>Smooth </string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="nsum_label">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>30</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Number of echo transmissions averaged</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>N: 0</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbColors">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Click to cycle through a sequence of colors and line widths.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Colors</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Expanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>EPlotter</class>
|
||||
<extends>QFrame</extends>
|
||||
<header>plotter.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -1,324 +0,0 @@
|
||||
#include "echoplot.h"
|
||||
#include "commons.h"
|
||||
#include <math.h>
|
||||
#include <QDebug>
|
||||
#include "moc_echoplot.cpp"
|
||||
|
||||
#define MAX_SCREENSIZE 2048
|
||||
|
||||
|
||||
EPlotter::EPlotter(QWidget *parent) : //EPlotter Constructor
|
||||
QFrame(parent)
|
||||
{
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
setFocusPolicy(Qt::StrongFocus);
|
||||
setAttribute(Qt::WA_PaintOnScreen,false);
|
||||
setAutoFillBackground(false);
|
||||
setAttribute(Qt::WA_OpaquePaintEvent, false);
|
||||
setAttribute(Qt::WA_NoSystemBackground, true);
|
||||
|
||||
m_StartFreq = -200;
|
||||
m_fftBinWidth=12000.0/32768.0;
|
||||
m_binsPerPixel=1;
|
||||
m_fSpan=1000.0;
|
||||
m_hdivs = HORZ_DIVS;
|
||||
m_Running = false;
|
||||
m_paintEventBusy=false;
|
||||
m_2DPixmap = QPixmap(0,0);
|
||||
m_ScalePixmap = QPixmap(0,0);
|
||||
m_OverlayPixmap = QPixmap(0,0);
|
||||
m_Size = QSize(0,0);
|
||||
m_TxFreq = 1500;
|
||||
m_line = 0;
|
||||
m_dBStepSize=10;
|
||||
}
|
||||
|
||||
EPlotter::~EPlotter() { } // Destructor
|
||||
|
||||
QSize EPlotter::minimumSizeHint() const
|
||||
{
|
||||
return QSize(50, 50);
|
||||
}
|
||||
|
||||
QSize EPlotter::sizeHint() const
|
||||
{
|
||||
return QSize(180, 180);
|
||||
}
|
||||
|
||||
void EPlotter::resizeEvent(QResizeEvent* ) //resizeEvent()
|
||||
{
|
||||
if(!size().isValid()) return;
|
||||
if( m_Size != size() ) { //if changed, resize pixmaps to new screensize
|
||||
m_Size = size();
|
||||
m_w = m_Size.width();
|
||||
m_h = m_Size.height();
|
||||
m_h1=30;
|
||||
m_h2=m_h-m_h1;
|
||||
m_2DPixmap = QPixmap(m_Size.width(), m_h2);
|
||||
m_2DPixmap.fill(Qt::black);
|
||||
m_OverlayPixmap = QPixmap(m_Size.width(), m_h2);
|
||||
m_ScalePixmap = QPixmap(m_w,30);
|
||||
m_ScalePixmap.fill(Qt::white);
|
||||
m_fSpan=m_w*m_fftBinWidth*m_binsPerPixel;
|
||||
m_StartFreq=50 * int((-0.5*m_fSpan)/50.0 - 0.5);
|
||||
}
|
||||
DrawOverlay();
|
||||
draw();
|
||||
}
|
||||
|
||||
void EPlotter::paintEvent(QPaintEvent *) // paintEvent()
|
||||
{
|
||||
if(m_paintEventBusy) return;
|
||||
m_paintEventBusy=true;
|
||||
QPainter painter(this);
|
||||
painter.drawPixmap(0,0,m_ScalePixmap);
|
||||
painter.drawPixmap(0,m_h1,m_2DPixmap);
|
||||
m_paintEventBusy=false;
|
||||
}
|
||||
|
||||
void EPlotter::draw() //draw()
|
||||
{
|
||||
int i,j,y;
|
||||
float blue[4096],red[4096];
|
||||
float gain = pow(10.0,(m_plotGain/20.0));
|
||||
QPen penBlue(QColor(0,255,255),1);
|
||||
QPen penRed(Qt::red,1);
|
||||
QPen penRed2(Qt::red,2);
|
||||
QPen penBlack(Qt::black,1);
|
||||
QPen penBlack2(Qt::black,2);
|
||||
|
||||
if(m_2DPixmap.size().width()==0) return;
|
||||
QPainter painter2D(&m_2DPixmap);
|
||||
QRect tmp(0,0,m_w,m_h2);
|
||||
if(m_nColor < 2) {
|
||||
painter2D.fillRect(tmp,Qt::black);
|
||||
} else {
|
||||
painter2D.fillRect(tmp,Qt::white);
|
||||
painter2D.setPen(penBlack);
|
||||
painter2D.drawLine(0,0,m_w,0);
|
||||
}
|
||||
|
||||
QPoint LineBuf[MAX_SCREENSIZE];
|
||||
|
||||
if(m_binsPerPixel==0) m_binsPerPixel=1;
|
||||
j=0;
|
||||
for(i=0; i<4096/m_binsPerPixel; i++) {
|
||||
blue[i]=0.0;
|
||||
red[i]=0.0;
|
||||
for(int k=0; k<m_binsPerPixel; k++) {
|
||||
blue[i]+=echocom_.blue[j];
|
||||
red[i]+=echocom_.red[j];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
if(m_smooth>0) {
|
||||
for(i=0; i<m_smooth; i++) {
|
||||
int n4096=4096;
|
||||
smo121_(blue,&n4096);
|
||||
smo121_(red,&n4096);
|
||||
}
|
||||
}
|
||||
|
||||
// check i0 value! ...
|
||||
int i0=2048/m_binsPerPixel + int(m_StartFreq/(m_fftBinWidth*m_binsPerPixel));
|
||||
if(m_blue) {
|
||||
painter2D.setPen(penBlue);
|
||||
j=0;
|
||||
for(i=0; i<m_w; i++) {
|
||||
y = 0.9*m_h2 - gain*(m_h/10.0)*(blue[i0+i]-1.0) - 0.01*m_h2*m_plotZero;
|
||||
LineBuf[j].setX(i);
|
||||
LineBuf[j].setY(y);
|
||||
j++;
|
||||
}
|
||||
painter2D.drawPolyline(LineBuf,j);
|
||||
}
|
||||
switch (m_nColor) {
|
||||
case 0: painter2D.setPen(penRed); break;
|
||||
case 1: painter2D.setPen(penRed2); break;
|
||||
case 2: painter2D.setPen(penRed); break;
|
||||
case 3: painter2D.setPen(penRed2); break;
|
||||
case 4: painter2D.setPen(penBlack); break;
|
||||
case 5: painter2D.setPen(penBlack2); break;
|
||||
}
|
||||
|
||||
j=0;
|
||||
for(int i=0; i<m_w; i++) {
|
||||
y = 0.9*m_h2 - gain*(m_h/10.0)*(red[i0+i]-1.0) - 0.01*m_h2*m_plotZero;
|
||||
LineBuf[j].setX(i);
|
||||
LineBuf[j].setY(y);
|
||||
j++;
|
||||
}
|
||||
painter2D.drawPolyline(LineBuf,j);
|
||||
update(); //trigger a new paintEvent
|
||||
}
|
||||
|
||||
void EPlotter::DrawOverlay() //DrawOverlay()
|
||||
{
|
||||
if(m_OverlayPixmap.isNull() or m_2DPixmap.isNull()) return;
|
||||
// int w = m_WaterfallPixmap.width();
|
||||
int x,y;
|
||||
|
||||
QRect rect;
|
||||
QPainter painter(&m_OverlayPixmap);
|
||||
painter.initFrom(this);
|
||||
QLinearGradient gradient(0, 0, 0 ,m_h2); //fill background with gradient
|
||||
gradient.setColorAt(1, Qt::black);
|
||||
gradient.setColorAt(0, Qt::darkBlue);
|
||||
painter.setBrush(gradient);
|
||||
painter.drawRect(0, 0, m_w, m_h2);
|
||||
painter.setBrush(Qt::SolidPattern);
|
||||
|
||||
m_fSpan = m_w*m_fftBinWidth*m_binsPerPixel;
|
||||
m_freqPerDiv=20;
|
||||
if(m_fSpan>250) m_freqPerDiv=50;
|
||||
if(m_fSpan>500) m_freqPerDiv=100;
|
||||
if(m_fSpan>1000) m_freqPerDiv=200;
|
||||
if(m_fSpan>2000) m_freqPerDiv=500;
|
||||
|
||||
// m_StartFreq=50 * int((-0.5*m_fSpan)/50.0 - 0.5);
|
||||
m_StartFreq=m_freqPerDiv * int((-0.5*m_fSpan)/m_freqPerDiv - 0.5);
|
||||
|
||||
float pixPerHdiv = m_freqPerDiv/(m_fftBinWidth*m_binsPerPixel);
|
||||
float pixPerVdiv = float(m_h2)/float(VERT_DIVS);
|
||||
|
||||
m_hdivs = m_w*m_fftBinWidth*m_binsPerPixel/m_freqPerDiv + 0.9999;
|
||||
|
||||
painter.setPen(QPen(Qt::white, 1,Qt::DotLine));
|
||||
for( int i=1; i<m_hdivs; i++) //draw vertical grids
|
||||
{
|
||||
x=int(i*pixPerHdiv);
|
||||
painter.drawLine(x,0,x,m_h2);
|
||||
}
|
||||
|
||||
for( int i=1; i<VERT_DIVS; i++) //draw horizontal grids
|
||||
{
|
||||
y = (int)( (float)i*pixPerVdiv );
|
||||
painter.drawLine(0,y,m_w,y);
|
||||
}
|
||||
|
||||
QRect rect0;
|
||||
QPainter painter0(&m_ScalePixmap);
|
||||
painter0.initFrom(this);
|
||||
|
||||
//create Font to use for scales
|
||||
QFont Font("Arial");
|
||||
Font.setPointSize(12);
|
||||
QFontMetrics metrics(Font);
|
||||
Font.setWeight(QFont::Normal);
|
||||
painter0.setFont(Font);
|
||||
painter0.setPen(Qt::black);
|
||||
|
||||
m_ScalePixmap.fill(Qt::white);
|
||||
painter0.drawRect(0, 0, m_w, 30);
|
||||
|
||||
//draw tick marks on upper scale
|
||||
for( int i=1; i<m_hdivs; i++) { //major ticks
|
||||
x = (int)( (float)i*pixPerHdiv );
|
||||
painter0.drawLine(x,18,x,30);
|
||||
}
|
||||
int minor=5;
|
||||
if(m_freqPerDiv==200) minor=4;
|
||||
for( int i=1; i<minor*m_hdivs; i++) { //minor ticks
|
||||
x = i*pixPerHdiv/minor;
|
||||
painter0.drawLine(x,24,x,30);
|
||||
}
|
||||
|
||||
//draw frequency values
|
||||
MakeFrequencyStrs();
|
||||
for( int i=0; i<=m_hdivs; i++) {
|
||||
if(0==i) {
|
||||
//left justify the leftmost text
|
||||
x = (int)( (float)i*pixPerHdiv);
|
||||
rect0.setRect(x,0, (int)pixPerHdiv, 20);
|
||||
painter0.drawText(rect0, Qt::AlignLeft|Qt::AlignVCenter,
|
||||
m_HDivText[i]);
|
||||
}
|
||||
else if(m_hdivs == i) {
|
||||
//right justify the rightmost text
|
||||
x = (int)( (float)i*pixPerHdiv - pixPerHdiv);
|
||||
rect0.setRect(x,0, (int)pixPerHdiv, 20);
|
||||
painter0.drawText(rect0, Qt::AlignRight|Qt::AlignVCenter,
|
||||
m_HDivText[i]);
|
||||
} else {
|
||||
//center justify the rest of the text
|
||||
x = (int)( (float)i*pixPerHdiv - pixPerHdiv/2);
|
||||
rect0.setRect(x,0, (int)pixPerHdiv, 20);
|
||||
painter0.drawText(rect0, Qt::AlignHCenter|Qt::AlignVCenter,
|
||||
m_HDivText[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
QPen pen1(Qt::red, 3); //Mark Tx Freq with red tick
|
||||
painter0.setPen(pen1);
|
||||
x = XfromFreq(m_TxFreq);
|
||||
painter0.drawLine(x,17,x,30);
|
||||
*/
|
||||
}
|
||||
|
||||
void EPlotter::MakeFrequencyStrs() //MakeFrequencyStrs
|
||||
{
|
||||
float freq;
|
||||
for(int i=0; i<=m_hdivs; i++) {
|
||||
freq=m_StartFreq + i*m_freqPerDiv;
|
||||
m_HDivText[i].setNum((int)freq);
|
||||
}
|
||||
}
|
||||
|
||||
int EPlotter::XfromFreq(float f) //XfromFreq()
|
||||
{
|
||||
int x = (int) m_w * (f - m_StartFreq)/m_fSpan;
|
||||
if(x<0 ) return 0;
|
||||
if(x>m_w) return m_w;
|
||||
return x;
|
||||
}
|
||||
|
||||
float EPlotter::FreqfromX(int x) //FreqfromX()
|
||||
{
|
||||
return float(m_StartFreq + x*m_fftBinWidth*m_binsPerPixel);
|
||||
}
|
||||
|
||||
void EPlotter::SetRunningState(bool running) //SetRunningState()
|
||||
{
|
||||
m_Running = running;
|
||||
}
|
||||
|
||||
void EPlotter::setPlotZero(int plotZero) //setPlotZero()
|
||||
{
|
||||
m_plotZero=plotZero;
|
||||
}
|
||||
|
||||
int EPlotter::getPlotZero() //getPlotZero()
|
||||
{
|
||||
return m_plotZero;
|
||||
}
|
||||
|
||||
void EPlotter::setPlotGain(int plotGain) //setPlotGain()
|
||||
{
|
||||
m_plotGain=plotGain;
|
||||
}
|
||||
|
||||
int EPlotter::getPlotGain() //getPlotGain()
|
||||
{
|
||||
return m_plotGain;
|
||||
}
|
||||
|
||||
void EPlotter::setSmooth(int n) //setSmooth()
|
||||
{
|
||||
m_smooth=n;
|
||||
}
|
||||
|
||||
int EPlotter::getSmooth() //getSmooth()
|
||||
{
|
||||
return m_smooth;
|
||||
}
|
||||
|
||||
void EPlotter::setColors(qint32 n) //setSmooth()
|
||||
{
|
||||
m_nColor=n;
|
||||
draw();
|
||||
}
|
||||
|
||||
int EPlotter::plotWidth(){return m_2DPixmap.width();}
|
||||
|
||||
void EPlotter::UpdateOverlay() {DrawOverlay();}
|
||||
@@ -1,125 +0,0 @@
|
||||
#include "fastgraph.h"
|
||||
|
||||
#include "commons.h"
|
||||
#include <QSettings>
|
||||
#include <QApplication>
|
||||
#include "fastplot.h"
|
||||
#include "SettingsGroup.hpp"
|
||||
|
||||
#include "ui_fastgraph.h"
|
||||
#include "moc_fastgraph.cpp"
|
||||
|
||||
#define NSMAX2 1366
|
||||
|
||||
FastGraph::FastGraph(QSettings * settings, QWidget *parent) :
|
||||
QDialog {parent, Qt::Window | Qt::WindowTitleHint |
|
||||
Qt::WindowCloseButtonHint |
|
||||
Qt::WindowMinimizeButtonHint},
|
||||
m_settings {settings},
|
||||
m_ave {40},
|
||||
ui {new Ui::FastGraph}
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setWindowTitle (QApplication::applicationName () + " - " + tr ("Fast Graph"));
|
||||
installEventFilter(parent); //Installing the filter
|
||||
ui->fastPlot->setCursor(Qt::CrossCursor);
|
||||
|
||||
//Restore user's settings
|
||||
SettingsGroup g {m_settings, "FastGraph"};
|
||||
restoreGeometry (m_settings->value ("geometry", saveGeometry ()).toByteArray ());
|
||||
ui->fastPlot->setPlotZero(m_settings->value("PlotZero", 0).toInt());
|
||||
ui->fastPlot->setPlotGain(m_settings->value("PlotGain", 0).toInt());
|
||||
ui->zeroSlider->setValue(ui->fastPlot->m_plotZero);
|
||||
ui->gainSlider->setValue(ui->fastPlot->m_plotGain);
|
||||
ui->fastPlot->setGreenZero(m_settings->value("GreenZero", 0).toInt());
|
||||
ui->greenZeroSlider->setValue(ui->fastPlot->m_greenZero);
|
||||
// ui->controls_widget->setVisible (!m_settings->value("HideControls", false).toBool ());
|
||||
ui->controls_widget->setVisible(true);
|
||||
connect (ui->fastPlot, &FPlotter::fastPick, this, &FastGraph::fastPick);
|
||||
}
|
||||
|
||||
void FastGraph::closeEvent (QCloseEvent * e)
|
||||
{
|
||||
saveSettings ();
|
||||
QDialog::closeEvent (e);
|
||||
}
|
||||
|
||||
FastGraph::~FastGraph ()
|
||||
{
|
||||
}
|
||||
|
||||
void FastGraph::saveSettings()
|
||||
{
|
||||
//Save user's settings
|
||||
SettingsGroup g {m_settings, "FastGraph"};
|
||||
m_settings->setValue ("geometry", saveGeometry ());
|
||||
m_settings->setValue("PlotZero",ui->fastPlot->m_plotZero);
|
||||
m_settings->setValue("PlotGain",ui->fastPlot->m_plotGain);
|
||||
m_settings->setValue("GreenZero",ui->fastPlot->m_greenZero);
|
||||
m_settings->setValue("GreenGain",ui->fastPlot->m_greenGain);
|
||||
// m_settings->setValue ("HideControls", ui->controls_widget->isHidden ());
|
||||
}
|
||||
|
||||
void FastGraph::plotSpec(bool diskData, int UTCdisk)
|
||||
{
|
||||
ui->fastPlot->m_diskData=diskData;
|
||||
ui->fastPlot->m_UTCdisk=UTCdisk;
|
||||
ui->fastPlot->draw();
|
||||
}
|
||||
|
||||
void FastGraph::on_gainSlider_valueChanged(int value)
|
||||
{
|
||||
ui->fastPlot->setPlotGain(value);
|
||||
ui->fastPlot->draw();
|
||||
}
|
||||
|
||||
void FastGraph::on_zeroSlider_valueChanged(int value)
|
||||
{
|
||||
ui->fastPlot->setPlotZero(value);
|
||||
ui->fastPlot->draw();
|
||||
}
|
||||
|
||||
void FastGraph::on_greenZeroSlider_valueChanged(int value)
|
||||
{
|
||||
ui->fastPlot->setGreenZero(value);
|
||||
ui->fastPlot->draw();
|
||||
}
|
||||
|
||||
void FastGraph::setTRPeriod(int n)
|
||||
{
|
||||
m_TRperiod=n;
|
||||
ui->fastPlot->setTRperiod(m_TRperiod);
|
||||
}
|
||||
|
||||
void FastGraph::on_pbAutoLevel_clicked()
|
||||
{
|
||||
float sum=0.0;
|
||||
for(int i=0; i<=fast_jh; i++) {
|
||||
sum += fast_green[i];
|
||||
}
|
||||
m_ave=sum/fast_jh;
|
||||
ui->gainSlider->setValue(127-int(2.2*m_ave));
|
||||
ui->zeroSlider->setValue(int(m_ave)+20);
|
||||
ui->greenZeroSlider->setValue(160-int(3.3*m_ave));
|
||||
}
|
||||
|
||||
void FastGraph::setMode(QString mode) //setMode
|
||||
{
|
||||
ui->fastPlot->setMode(mode);
|
||||
}
|
||||
|
||||
void FastGraph::keyPressEvent(QKeyEvent *e)
|
||||
{
|
||||
switch(e->key())
|
||||
{
|
||||
/*
|
||||
case Qt::Key_M:
|
||||
if(e->modifiers() & Qt::ControlModifier) {
|
||||
ui->controls_widget->setVisible (!ui->controls_widget->isVisible ());
|
||||
}
|
||||
break;
|
||||
*/
|
||||
default:
|
||||
QDialog::keyPressEvent (e);
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
#ifndef FASTGRAPH_H
|
||||
#define FASTGRAPH_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QScopedPointer>
|
||||
|
||||
namespace Ui {
|
||||
class FastGraph;
|
||||
}
|
||||
|
||||
class QSettings;
|
||||
|
||||
class FastGraph : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit FastGraph(QSettings *, QWidget *parent = 0);
|
||||
~FastGraph ();
|
||||
|
||||
void plotSpec(bool diskData, int UTCdisk);
|
||||
void saveSettings();
|
||||
void setTRPeriod(int n);
|
||||
void setMode(QString mode);
|
||||
|
||||
signals:
|
||||
void fastPick(int x0, int x1, int y);
|
||||
|
||||
private slots:
|
||||
void on_gainSlider_valueChanged(int value);
|
||||
void on_zeroSlider_valueChanged(int value);
|
||||
void on_greenZeroSlider_valueChanged(int value);
|
||||
void on_pbAutoLevel_clicked();
|
||||
|
||||
protected:
|
||||
void closeEvent (QCloseEvent *) override;
|
||||
void keyPressEvent( QKeyEvent *e ) override;
|
||||
|
||||
private:
|
||||
QSettings * m_settings;
|
||||
float m_ave;
|
||||
qint32 m_TRperiod;
|
||||
|
||||
QScopedPointer<Ui::FastGraph> ui;
|
||||
};
|
||||
|
||||
extern float fast_green[703];
|
||||
extern int fast_jh;
|
||||
|
||||
#endif // FASTGRAPH_H
|
||||
@@ -1,238 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>FastGraph</class>
|
||||
<widget class="QDialog" name="FastGraph">
|
||||
<property name="windowTitle">
|
||||
<string>Fast Graph</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetFixedSize</enum>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="FPlotter" name="fastPlot">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>703</width>
|
||||
<height>220</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>703</width>
|
||||
<height>220</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Sunken</enum>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="controls_widget" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Expanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>99</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="gainSlider">
|
||||
<property name="toolTip">
|
||||
<string>Waterfall gain</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-60</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>140</number>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<number>40</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_7">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="zeroSlider">
|
||||
<property name="toolTip">
|
||||
<string>Waterfall zero</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-60</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>120</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>60</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="greenZeroSlider">
|
||||
<property name="toolTip">
|
||||
<string>Spectrum zero</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-100</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>160</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>30</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbAutoLevel">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Set reasonable levels for gain and zero sliders.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Auto Level</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Expanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>99</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>FPlotter</class>
|
||||
<extends>QFrame</extends>
|
||||
<header>fastplot.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 7.9 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 571 B After Width: | Height: | Size: 830 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 75 KiB |
|
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 7.9 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 571 B After Width: | Height: | Size: 830 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 75 KiB |
|
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 7.9 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 282 KiB After Width: | Height: | Size: 286 KiB |
@@ -63,7 +63,7 @@ SOURCES += \
|
||||
getfile.cpp soundout.cpp soundin.cpp meterwidget.cpp signalmeter.cpp \
|
||||
WFPalette.cpp plotter.cpp widegraph.cpp about.cpp WsprTxScheduler.cpp mainwindow.cpp \
|
||||
main.cpp decodedtext.cpp wsprnet.cpp messageaveraging.cpp \
|
||||
echoplot.cpp echograph.cpp fastgraph.cpp fastplot.cpp Modes.cpp \
|
||||
Modes.cpp \
|
||||
WSPRBandHopping.cpp MessageAggregator.cpp qt_helpers.cpp\
|
||||
MultiSettings.cpp PhaseEqualizationDialog.cpp IARURegions.cpp MessageBox.cpp \
|
||||
EqualizationToolsDialog.cpp \
|
||||
@@ -71,7 +71,6 @@ SOURCES += \
|
||||
NetworkMessage.cpp \
|
||||
MessageClient.cpp \
|
||||
SelfDestructMessageBox.cpp \
|
||||
APRSISClient.cpp \
|
||||
messagereplydialog.cpp \
|
||||
keyeater.cpp \
|
||||
DriftingDateTime.cpp \
|
||||
@@ -81,7 +80,18 @@ SOURCES += \
|
||||
jsc_checker.cpp \
|
||||
Message.cpp \
|
||||
Inbox.cpp \
|
||||
messagewindow.cpp
|
||||
messagewindow.cpp \
|
||||
SpotClient.cpp \
|
||||
TCPClient.cpp \
|
||||
TransmitTextEdit.cpp \
|
||||
NotificationAudio.cpp \
|
||||
CallsignValidator.cpp \
|
||||
AudioDecoder.cpp \
|
||||
WaveFile.cpp \
|
||||
WaveUtils.cpp \
|
||||
ProcessThread.cpp \
|
||||
DecoderThread.cpp \
|
||||
Decoder.cpp
|
||||
|
||||
HEADERS += qt_helpers.hpp \
|
||||
pimpl_h.hpp pimpl_impl.hpp \
|
||||
@@ -95,7 +105,7 @@ HEADERS += qt_helpers.hpp \
|
||||
EmulateSplitTransceiver.hpp DXLabSuiteCommanderTransceiver.hpp HamlibTransceiver.hpp \
|
||||
Configuration.hpp wsprnet.h signalmeter.h meterwidget.h \
|
||||
logbook/logbook.h logbook/countrydat.h logbook/countriesworked.h logbook/adif.h \
|
||||
messageaveraging.h echoplot.h echograph.h fastgraph.h fastplot.h Modes.hpp WSPRBandHopping.hpp \
|
||||
messageaveraging.h Modes.hpp WSPRBandHopping.hpp \
|
||||
WsprTxScheduler.h MultiSettings.hpp PhaseEqualizationDialog.hpp \
|
||||
IARURegions.hpp MessageBox.hpp EqualizationToolsDialog.hpp \
|
||||
qorderedmap.h \
|
||||
@@ -105,7 +115,6 @@ HEADERS += qt_helpers.hpp \
|
||||
NetworkMessage.hpp \
|
||||
MessageClient.hpp \
|
||||
SelfDestructMessageBox.h \
|
||||
APRSISClient.h \
|
||||
messagereplydialog.h \
|
||||
keyeater.h \
|
||||
DriftingDateTime.h \
|
||||
@@ -113,7 +122,18 @@ HEADERS += qt_helpers.hpp \
|
||||
jsc_checker.h \
|
||||
Message.h \
|
||||
Inbox.h \
|
||||
messagewindow.h
|
||||
messagewindow.h \
|
||||
SpotClient.h \
|
||||
TCPClient.h \
|
||||
logbook/n3fjp.h \
|
||||
TransmitTextEdit.h \
|
||||
NotificationAudio.h \
|
||||
AudioDecoder.h \
|
||||
WaveFile.h \
|
||||
WaveUtils.h \
|
||||
ProcessThread.h \
|
||||
DecoderThread.h \
|
||||
Decoder.h
|
||||
|
||||
|
||||
INCLUDEPATH += qmake_only
|
||||
@@ -124,8 +144,7 @@ HEADERS += OmniRigTransceiver.hpp
|
||||
}
|
||||
|
||||
FORMS += mainwindow.ui about.ui Configuration.ui widegraph.ui astro.ui \
|
||||
logqso.ui wf_palette_design_dialog.ui messageaveraging.ui echograph.ui \
|
||||
fastgraph.ui \
|
||||
logqso.ui wf_palette_design_dialog.ui messageaveraging.ui \
|
||||
messagereplydialog.ui \
|
||||
messagewindow.ui
|
||||
|
||||
@@ -58,13 +58,17 @@ QList<CodewordPair> JSC::compress(QString text){
|
||||
|
||||
QString space(" ");
|
||||
|
||||
foreach(QString w, text.split(" ", QString::KeepEmptyParts)){
|
||||
bool ok = false;
|
||||
QStringList words = text.split(" ", QString::KeepEmptyParts);
|
||||
|
||||
for(int i = 0, len = words.length(); i < len; i++){
|
||||
QString w = words[i];
|
||||
|
||||
bool isLastWord = (i == len - 1);
|
||||
bool ok = false;
|
||||
bool isSpaceCharacter = false;
|
||||
|
||||
// if this is an empty part, it should be a space.
|
||||
if(w.isEmpty()){
|
||||
// if this is an empty part, it should be a space, unless its the last word.
|
||||
if(w.isEmpty() && !isLastWord){
|
||||
w = space;
|
||||
isSpaceCharacter = true;
|
||||
}
|
||||
@@ -77,10 +81,12 @@ QList<CodewordPair> JSC::compress(QString text){
|
||||
}
|
||||
|
||||
auto t = JSC::map[index];
|
||||
|
||||
w = QString(w).mid(t.size);
|
||||
|
||||
bool isLast = w.isEmpty();
|
||||
bool shouldAppendSpace = isLast && !isSpaceCharacter;
|
||||
bool shouldAppendSpace = isLast && !isSpaceCharacter && !isLastWord;
|
||||
|
||||
out.append({ codeword(index, shouldAppendSpace, b, s, c), (quint32)t.size + (shouldAppendSpace ? 1 : 0) /* for the space that follows */});
|
||||
}
|
||||
}
|
||||
@@ -106,7 +112,7 @@ QString JSC::decompress(Codeword const& bitvec){
|
||||
base[7] = base[6] + s*c*c*c*c*c*c;
|
||||
|
||||
QList<quint64> bytes;
|
||||
QList<int> separators;
|
||||
QList<quint32> separators;
|
||||
|
||||
int i = 0;
|
||||
int count = bitvec.count();
|
||||
@@ -127,25 +133,30 @@ QString JSC::decompress(Codeword const& bitvec){
|
||||
}
|
||||
}
|
||||
|
||||
int start = 0;
|
||||
while(start < bytes.length()){
|
||||
int k = 0;
|
||||
int j = 0;
|
||||
quint32 start = 0;
|
||||
while(start < (quint32)bytes.length()){
|
||||
quint32 k = 0;
|
||||
quint32 j = 0;
|
||||
|
||||
while(start + k < bytes.length() && bytes[start + k] >= s){
|
||||
while(start + k < (quint32)bytes.length() && bytes[start + k] >= s){
|
||||
j = j*c + (bytes[start + k] - s);
|
||||
k++;
|
||||
}
|
||||
if(j >= JSC::size){
|
||||
break;
|
||||
}
|
||||
|
||||
if(start + k >= bytes.length()){
|
||||
if(start + k >= (quint32)bytes.length()){
|
||||
break;
|
||||
}
|
||||
j = j*s + bytes[start + k] + base[k];
|
||||
|
||||
if(j >= (int)JSC::size){
|
||||
if(j >= JSC::size){
|
||||
break;
|
||||
}
|
||||
auto word = QString(JSC::map[j].str);
|
||||
|
||||
// map is in latin1 format, not utf-8
|
||||
auto word = QLatin1String(JSC::map[j].str);
|
||||
|
||||
out.append(word);
|
||||
if(!separators.isEmpty() && separators.first() == start + k){
|
||||
|
||||
@@ -40,8 +40,8 @@ public:
|
||||
static const Tuple map[262144];
|
||||
static const Tuple list[262144];
|
||||
|
||||
static const quint32 prefixSize = 69;
|
||||
static const Tuple prefix[69];
|
||||
static const quint32 prefixSize = 103;
|
||||
static const Tuple prefix[103];
|
||||
};
|
||||
|
||||
#endif // JSC_H
|
||||
|
||||
@@ -58,7 +58,7 @@ bool cursorHasProperty(const QTextCursor &cursor, int property){
|
||||
QString nextChar(QTextCursor c){
|
||||
QTextCursor cur(c);
|
||||
cur.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
|
||||
return cur.selectedText();
|
||||
return cur.selectedText().toUpper();
|
||||
}
|
||||
|
||||
bool isNumeric(QString s){
|
||||
@@ -80,7 +80,7 @@ void JSCChecker::checkRange(QTextEdit* edit, int start, int end)
|
||||
// stop contentsChange signals from being emitted due to changed charFormats
|
||||
edit->document()->blockSignals(true);
|
||||
|
||||
qDebug() << "checking range " << start << " - " << end;
|
||||
//qDebug() << "checking range " << start << " - " << end;
|
||||
|
||||
QTextCharFormat errorFmt;
|
||||
errorFmt.setFontUnderline(true);
|
||||
@@ -97,7 +97,7 @@ void JSCChecker::checkRange(QTextEdit* edit, int start, int end)
|
||||
bool correct = false;
|
||||
|
||||
cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
|
||||
if(cursor.selectedText() == "@"){
|
||||
if(cursor.selectedText()/*.toUpper()*/ == "@"){
|
||||
cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
|
||||
cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
|
||||
}
|
||||
@@ -105,7 +105,7 @@ void JSCChecker::checkRange(QTextEdit* edit, int start, int end)
|
||||
if(cursorHasProperty(cursor, CORRECT)){
|
||||
correct = true;
|
||||
} else {
|
||||
QString word = cursor.selectedText();
|
||||
QString word = cursor.selectedText().toUpper();
|
||||
|
||||
// three or less is always "correct"
|
||||
if(word.length() < 4 || isNumeric(word)){
|
||||
@@ -121,6 +121,8 @@ void JSCChecker::checkRange(QTextEdit* edit, int start, int end)
|
||||
correct = Varicode::isValidCallsign(word, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
//qDebug() << "word" << word << "correct" << correct;
|
||||
}
|
||||
|
||||
if(correct){
|
||||
@@ -203,7 +205,7 @@ QMap<quint32, QString> candidates(QString word, bool includeTwoEdits){
|
||||
QStringList JSCChecker::suggestions(QString word, int n, bool *pFound){
|
||||
QStringList s;
|
||||
|
||||
qDebug() << "computing suggestions for word" << word;
|
||||
// qDebug() << "computing suggestions for word" << word;
|
||||
|
||||
QMap<quint32, QString> m;
|
||||
|
||||
@@ -227,7 +229,7 @@ QStringList JSCChecker::suggestions(QString word, int n, bool *pFound){
|
||||
if(i >= n){
|
||||
break;
|
||||
}
|
||||
qDebug() << "suggest" << m[key] << key;
|
||||
//qDebug() << "suggest" << m[key] << key;
|
||||
s.append(m[key]);
|
||||
i++;
|
||||
}
|
||||
|
||||
@@ -61083,7 +61083,7 @@ const Tuple JSC::list[262144] = {
|
||||
{"ROSIERE", 7, 190612},
|
||||
{"ROSIER", 6, 168300},
|
||||
{"ROSIE", 5, 49485},
|
||||
{"ROSIDS", 6, 262143},
|
||||
{"ROSIDS", 6, 262143},
|
||||
{"ROSICRUCIAN", 11, 159215},
|
||||
{"ROSHOLT", 7, 221740},
|
||||
{"ROSHO", 5, 245639},
|
||||
@@ -145937,7 +145937,7 @@ const Tuple JSC::list[262144] = {
|
||||
{"JSTR", 4, 190085},
|
||||
{"JSTOR", 5, 75164},
|
||||
{"JSTL", 4, 132651},
|
||||
{"JSQSO", 5, 72},
|
||||
{"\x1A", 1, 72}, // FYI: This used to be JSQSO in JS8 2.0
|
||||
{"JSQCALL", 7, 73},
|
||||
{"JSPWIKI", 7, 154802},
|
||||
{"JSPS", 4, 113215},
|
||||
@@ -180080,8 +180080,8 @@ const Tuple JSC::list[262144] = {
|
||||
{"FTAD", 4, 112460},
|
||||
{"FTAC", 4, 68872},
|
||||
{"FTAB", 4, 72752},
|
||||
{"\\", 1, 69},
|
||||
{"FT8", 3, 68},
|
||||
{"\n", 1, 69}, // FYI: this used to be "\" in JS8 1.0
|
||||
{"\\", 1, 68}, // FYI: this used to be FT8 in JS8 1.0
|
||||
{"FSYW", 4, 155790},
|
||||
{"FSYT", 4, 186523},
|
||||
{"FSYS", 4, 69541},
|
||||
@@ -239508,38 +239508,38 @@ const Tuple JSC::list[262144] = {
|
||||
{"BO94", 4, 10738},
|
||||
{"BO93", 4, 10737},
|
||||
{"BO92", 4, 10736},
|
||||
{"BO91", 4, 10735},
|
||||
{"BO90", 4, 10734},
|
||||
{"BO89", 4, 10733},
|
||||
{"BO88", 4, 10732},
|
||||
{"BO87", 4, 10731},
|
||||
{"BO86", 4, 10730},
|
||||
{"BO85", 4, 10729},
|
||||
{"BO84", 4, 10728},
|
||||
{"BO83", 4, 10727},
|
||||
{"BO82", 4, 10726},
|
||||
{"BO81", 4, 10725},
|
||||
{"BO80", 4, 10724},
|
||||
{"BO79", 4, 10723},
|
||||
{"BO78", 4, 10722},
|
||||
{"BO77", 4, 10721},
|
||||
{"BO76", 4, 10720},
|
||||
{"BO75", 4, 10719},
|
||||
{"BO74", 4, 10718},
|
||||
{"BO73", 4, 10717},
|
||||
{"BO72", 4, 10716},
|
||||
{"BO71", 4, 10715},
|
||||
{"BO70", 4, 10714},
|
||||
{"BO69", 4, 10713},
|
||||
{"BO68", 4, 10712},
|
||||
{"BO67", 4, 10711},
|
||||
{"BO66", 4, 10710},
|
||||
{"BO65", 4, 10709},
|
||||
{"BO64", 4, 10708},
|
||||
{"BO63", 4, 10707},
|
||||
{"BO62", 4, 10706},
|
||||
{"BO61", 4, 10705},
|
||||
{"BO60", 4, 10704},
|
||||
{"\xde" /* Þ - "BO91" */, 1, 10735},
|
||||
{"\xdd" /* Ý - "BO90" */, 1, 10734},
|
||||
{"\xdc" /* Ü - "BO89" */, 1, 10733},
|
||||
{"\xdb" /* Û - "BO88" */, 1, 10732},
|
||||
{"\xda" /* Ú - "BO87" */, 1, 10731},
|
||||
{"\xd9" /* Ù - "BO86" */, 1, 10730},
|
||||
{"\xd8" /* Ø - "BO85" */, 1, 10729},
|
||||
{"\xd6" /* Ö - "BO84" */, 1, 10728},
|
||||
{"\xd5" /* Õ - "BO83" */, 1, 10727},
|
||||
{"\xd4" /* Ô - "BO82" */, 1, 10726},
|
||||
{"\xd3" /* Ó - "BO81" */, 1, 10725},
|
||||
{"\xd2" /* Ò - "BO80" */, 1, 10724},
|
||||
{"\xd1" /* Ñ - "BO79" */, 1, 10723},
|
||||
{"\xd0" /* Ð - "BO78" */, 1, 10722},
|
||||
{"\xcf" /* Ï - "BO77" */, 1, 10721},
|
||||
{"\xce" /* Î - "BO76" */, 1, 10720},
|
||||
{"\xcd" /* Í - "BO75" */, 1, 10719},
|
||||
{"\xcc" /* Ì - "BO74" */, 1, 10718},
|
||||
{"\xcb" /* Ë - "BO73" */, 1, 10717},
|
||||
{"\xca" /* Ê - "BO72" */, 1, 10716},
|
||||
{"\xc9" /* É - "BO71" */, 1, 10715},
|
||||
{"\xc8" /* È - "BO70" */, 1, 10714},
|
||||
{"\xc7" /* Ç - "BO69" */, 1, 10713},
|
||||
{"\xc6" /* Æ - "BO68" */, 1, 10712},
|
||||
{"\xc5" /* Å - "BO67" */, 1, 10711},
|
||||
{"\xc4" /* Ä - "BO66" */, 1, 10710},
|
||||
{"\xc3" /* Ã - "BO65" */, 1, 10709},
|
||||
{"\xc2" /* Â - "BO64" */, 1, 10708},
|
||||
{"\xc1" /* Á - "BO63" */, 1, 10707},
|
||||
{"\xc0" /* À - "BO62" */, 1, 10706},
|
||||
{"\xbf" /* ¿ - "BO61" */, 1, 10705},
|
||||
{"\xa1" /* ¡ - "BO60" */, 1, 10704},
|
||||
{"BO59", 4, 10703},
|
||||
{"BO58", 4, 10702},
|
||||
{"BO57", 4, 10701},
|
||||
@@ -262167,7 +262167,7 @@ const Tuple JSC::list[262144] = {
|
||||
{"!", 1, 28},
|
||||
};
|
||||
|
||||
const Tuple JSC::prefix[69] = {
|
||||
const Tuple JSC::prefix[103] = {
|
||||
{"!", 1, 262143},
|
||||
{"\"", 1, 262142},
|
||||
{"#", 1, 262141},
|
||||
@@ -262205,11 +262205,13 @@ const Tuple JSC::prefix[69] = {
|
||||
{"C", 17608, 216261},
|
||||
{"D", 13749, 202512},
|
||||
{"E", 12403, 190109},
|
||||
{"\\", 1, 180059},
|
||||
{"\\", 1, 180060},
|
||||
{"\n", 1, 180059},
|
||||
{"F", 11252, 178857},
|
||||
{"G", 10672, 168185},
|
||||
{"H", 9060, 159125},
|
||||
{"I", 9503, 149622},
|
||||
{"\x1A", 1, 145916},
|
||||
{"J", 4262, 145360},
|
||||
{"K", 7986, 137374},
|
||||
{"L", 12241, 125133},
|
||||
@@ -262237,4 +262239,37 @@ const Tuple JSC::prefix[69] = {
|
||||
{"|", 1, 2},
|
||||
{"}", 1, 1},
|
||||
{"~", 1, 0},
|
||||
|
||||
{"\xa1" /* ¡ */, 1, 239518},
|
||||
{"\xbf" /* ¿ */, 1, 239517},
|
||||
{"\xc0" /* À */, 1, 239516},
|
||||
{"\xc1" /* Á */, 1, 239515},
|
||||
{"\xc2" /* Â */, 1, 239514},
|
||||
{"\xc3" /* Ã */, 1, 239513},
|
||||
{"\xc4" /* Ä */, 1, 239512},
|
||||
{"\xc5" /* Å */, 1, 239511},
|
||||
{"\xc6" /* Æ */, 1, 239510},
|
||||
{"\xc7" /* Ç */, 1, 239509},
|
||||
{"\xc8" /* È */, 1, 239508},
|
||||
{"\xc9" /* É */, 1, 239507},
|
||||
{"\xca" /* Ê */, 1, 239506},
|
||||
{"\xcb" /* Ë */, 1, 239505},
|
||||
{"\xcc" /* Ì */, 1, 239504},
|
||||
{"\xcd" /* Í */, 1, 239503},
|
||||
{"\xce" /* Î */, 1, 239502},
|
||||
{"\xcf" /* Ï */, 1, 239501},
|
||||
{"\xd0" /* Ð */, 1, 239500},
|
||||
{"\xd1" /* Ñ */, 1, 239499},
|
||||
{"\xd2" /* Ò */, 1, 239498},
|
||||
{"\xd3" /* Ó */, 1, 239497},
|
||||
{"\xd4" /* Ô */, 1, 239496},
|
||||
{"\xd5" /* Õ */, 1, 239495},
|
||||
{"\xd6" /* Ö */, 1, 239494},
|
||||
{"\xd8" /* Ø */, 1, 239493},
|
||||
{"\xd9" /* Ù */, 1, 239492},
|
||||
{"\xda" /* Ú */, 1, 239491},
|
||||
{"\xdb" /* Û */, 1, 239490},
|
||||
{"\xdc" /* Ü */, 1, 239489},
|
||||
{"\xdd" /* Ý */, 1, 239488},
|
||||
{"\xde" /* Þ */, 1, 239487},
|
||||
};
|
||||
|
||||
@@ -89,12 +89,12 @@ const Tuple JSC::map[262144] = {
|
||||
{"`", 1, 65},
|
||||
{"~", 1, 66},
|
||||
{" ", 1, 67},
|
||||
{"FT8", 3, 68},
|
||||
{"\\", 1, 69},
|
||||
{"\\", 1, 68}, // FYI: this used to be FT8 in JS8 1.0
|
||||
{"\n", 1, 69}, // FYI: this used to be "\" in JS8 1.0
|
||||
{"JS8", 3, 70},
|
||||
{"JS8CALL", 7, 71},
|
||||
{"JSQSO", 5, 72},
|
||||
{"JSQCALL", 7, 73},
|
||||
{"\x1A", 1, 72}, // FYI: this used to be JSQSO in JS8 1.0, it is now a substitute flag
|
||||
{"JSQCALL", 7, 73},
|
||||
{"JORDAN", 6, 74},
|
||||
{"KN4CRD", 6, 75},
|
||||
{"599", 3, 76},
|
||||
@@ -10725,38 +10725,38 @@ const Tuple JSC::map[262144] = {
|
||||
{"BO57", 4, 10701},
|
||||
{"BO58", 4, 10702},
|
||||
{"BO59", 4, 10703},
|
||||
{"BO60", 4, 10704},
|
||||
{"BO61", 4, 10705},
|
||||
{"BO62", 4, 10706},
|
||||
{"BO63", 4, 10707},
|
||||
{"BO64", 4, 10708},
|
||||
{"BO65", 4, 10709},
|
||||
{"BO66", 4, 10710},
|
||||
{"BO67", 4, 10711},
|
||||
{"BO68", 4, 10712},
|
||||
{"BO69", 4, 10713},
|
||||
{"BO70", 4, 10714},
|
||||
{"BO71", 4, 10715},
|
||||
{"BO72", 4, 10716},
|
||||
{"BO73", 4, 10717},
|
||||
{"BO74", 4, 10718},
|
||||
{"BO75", 4, 10719},
|
||||
{"BO76", 4, 10720},
|
||||
{"BO77", 4, 10721},
|
||||
{"BO78", 4, 10722},
|
||||
{"BO79", 4, 10723},
|
||||
{"BO80", 4, 10724},
|
||||
{"BO81", 4, 10725},
|
||||
{"BO82", 4, 10726},
|
||||
{"BO83", 4, 10727},
|
||||
{"BO84", 4, 10728},
|
||||
{"BO85", 4, 10729},
|
||||
{"BO86", 4, 10730},
|
||||
{"BO87", 4, 10731},
|
||||
{"BO88", 4, 10732},
|
||||
{"BO89", 4, 10733},
|
||||
{"BO90", 4, 10734},
|
||||
{"BO91", 4, 10735},
|
||||
{"\xa1" /* ¡ - "BO60" */, 1, 10704},
|
||||
{"\xbf" /* ¿ - "BO61" */, 1, 10705},
|
||||
{"\xc0" /* À - "BO62" */, 1, 10706},
|
||||
{"\xc1" /* Á - "BO63" */, 1, 10707},
|
||||
{"\xc2" /* Â - "BO64" */, 1, 10708},
|
||||
{"\xc3" /* Ã - "BO65" */, 1, 10709},
|
||||
{"\xc4" /* Ä - "BO66" */, 1, 10710},
|
||||
{"\xc5" /* Å - "BO67" */, 1, 10711},
|
||||
{"\xc6" /* Æ - "BO68" */, 1, 10712},
|
||||
{"\xc7" /* Ç - "BO69" */, 1, 10713},
|
||||
{"\xc8" /* È - "BO70" */, 1, 10714},
|
||||
{"\xc9" /* É - "BO71" */, 1, 10715},
|
||||
{"\xca" /* Ê - "BO72" */, 1, 10716},
|
||||
{"\xcb" /* Ë - "BO73" */, 1, 10717},
|
||||
{"\xcc" /* Ì - "BO74" */, 1, 10718},
|
||||
{"\xcd" /* Í - "BO75" */, 1, 10719},
|
||||
{"\xce" /* Î - "BO76" */, 1, 10720},
|
||||
{"\xcf" /* Ï - "BO77" */, 1, 10721},
|
||||
{"\xd0" /* Ð - "BO78" */, 1, 10722},
|
||||
{"\xd1" /* Ñ - "BO79" */, 1, 10723},
|
||||
{"\xd2" /* Ò - "BO80" */, 1, 10724},
|
||||
{"\xd3" /* Ó - "BO81" */, 1, 10725},
|
||||
{"\xd4" /* Ô - "BO82" */, 1, 10726},
|
||||
{"\xd5" /* Õ - "BO83" */, 1, 10727},
|
||||
{"\xd6" /* Ö - "BO84" */, 1, 10728},
|
||||
{"\xd8" /* Ø - "BO85" */, 1, 10729},
|
||||
{"\xd9" /* Ù - "BO86" */, 1, 10730},
|
||||
{"\xda" /* Ú - "BO87" */, 1, 10731},
|
||||
{"\xdb" /* Û - "BO88" */, 1, 10732},
|
||||
{"\xdc" /* Ü - "BO89" */, 1, 10733},
|
||||
{"\xdd" /* Ý - "BO90" */, 1, 10734},
|
||||
{"\xde" /* Þ - "BO91" */, 1, 10735},
|
||||
{"BO92", 4, 10736},
|
||||
{"BO93", 4, 10737},
|
||||
{"BO94", 4, 10738},
|
||||
@@ -262164,5 +262164,5 @@ const Tuple JSC::map[262144] = {
|
||||
{"YANAI", 5, 262140},
|
||||
{"YOGIBEAR", 8, 262141},
|
||||
{"UWED", 4, 262142},
|
||||
{"ROSIDS", 6, 262143},
|
||||
{"ROSIDS", 1, 262143},
|
||||
};
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
#include "keyeater.h"
|
||||
|
||||
|
||||
bool KeyPressEater::eventFilter(QObject *obj, QEvent *event){
|
||||
if (event->type() == QEvent::KeyPress) {
|
||||
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
|
||||
bool processed = false;
|
||||
emit this->keyPressed(obj, keyEvent, &processed);
|
||||
if(processed){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// standard event processing
|
||||
//return QObject::eventFilter(obj, event);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EscapeKeyPressEater::eventFilter(QObject *obj, QEvent *event){
|
||||
if (event->type() == QEvent::KeyPress) {
|
||||
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
|
||||
@@ -9,7 +25,8 @@ bool EscapeKeyPressEater::eventFilter(QObject *obj, QEvent *event){
|
||||
}
|
||||
|
||||
// standard event processing
|
||||
return QObject::eventFilter(obj, event);
|
||||
//return QObject::eventFilter(obj, event);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EnterKeyPressEater::eventFilter(QObject *obj, QEvent *event){
|
||||
@@ -25,7 +42,8 @@ bool EnterKeyPressEater::eventFilter(QObject *obj, QEvent *event){
|
||||
}
|
||||
|
||||
// standard event processing
|
||||
return QObject::eventFilter(obj, event);
|
||||
//return QObject::eventFilter(obj, event);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MousePressEater::eventFilter(QObject *obj, QEvent *event){
|
||||
@@ -39,6 +57,21 @@ bool MousePressEater::eventFilter(QObject *obj, QEvent *event){
|
||||
}
|
||||
|
||||
// standard event processing
|
||||
return QObject::eventFilter(obj, event);
|
||||
//return QObject::eventFilter(obj, event);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MouseDoubleClickEater::eventFilter(QObject *obj, QEvent *event){
|
||||
if (event->type() == QEvent::MouseButtonDblClick) {
|
||||
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
|
||||
bool processed = false;
|
||||
emit this->mouseDoubleClicked(obj, mouseEvent, &processed);
|
||||
if(processed){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// standard event processing
|
||||
//return QObject::eventFilter(obj, event);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,20 @@
|
||||
#include <QKeyEvent>
|
||||
#include <QMouseEvent>
|
||||
|
||||
class KeyPressEater : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
KeyPressEater(){}
|
||||
virtual ~KeyPressEater(){}
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *obj, QEvent *event);
|
||||
|
||||
public:
|
||||
Q_SIGNAL void keyPressed(QObject *obj, QKeyEvent *evt, bool *pProcessed);
|
||||
};
|
||||
|
||||
class EscapeKeyPressEater : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -44,7 +58,19 @@ public:
|
||||
Q_SIGNAL void mousePressed(QObject *obj, QMouseEvent *evt, bool *pProcessed);
|
||||
};
|
||||
|
||||
class MouseDoubleClickEater : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MouseDoubleClickEater(){}
|
||||
virtual ~MouseDoubleClickEater(){}
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *obj, QEvent *event);
|
||||
|
||||
public:
|
||||
Q_SIGNAL void mouseDoubleClicked(QObject *obj, QMouseEvent *evt, bool *pProcessed);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
Before using the new "CQ nnn ..." feature in JTMSK mode, I suggest
|
||||
performing the following tests of the necessary CAT control for your
|
||||
radio. (I'm assuming that you already have some experience with
|
||||
JTMSK.)
|
||||
|
||||
TEST 1:
|
||||
--------------------------------------------------------------------------
|
||||
1. Start WSJT-X
|
||||
2. Settings: "Enable VHF/UHF/Microwave features, "Rx frequency offset
|
||||
with 'CQ nnn ...'", Split=Rig, or Split="Fake it"
|
||||
3. Main screen settings: Band=50.280, mode=JTMSK, T/R=15 s
|
||||
4. Activate CQRx, set CQ Rx=265
|
||||
==> Rx dial should now read 50.265 and Tx6 should be queued
|
||||
5. Click "Enable Tx"
|
||||
==> Tx sequences should occur at 50.280, Rx at 50.265
|
||||
|
||||
With most rigs, this test should work with Split configured as either
|
||||
"Rig" or "Fake it".
|
||||
|
||||
TEST 2:
|
||||
--------------------------------------------------------------------------
|
||||
1. Start WSJT-X
|
||||
2. Settings: MyCall=K1JT, "Enable VHF/UHF/Microwave features,
|
||||
"Rx frequency offset with 'CQ nnn ...'", Split=Rig or "Fake it"
|
||||
4. Main screen settings: Band=50.280, mode=JTMSK, T/R=15 s
|
||||
5. Open file 150826_120515.wav
|
||||
==> see decoded message "K1JT VE1SKY FN74"
|
||||
6. Click "Monitor" to restart monitoring
|
||||
7. Activate CQRx, set CQ Rx=265
|
||||
==> Rx dial should now read 50.265; Tx6 should be queued
|
||||
8. Click "Enable Tx"
|
||||
==> Tx sequences should occur at 50.280, Rx at 50.265
|
||||
9. After the start of a transmission, double-click on the decoded message
|
||||
"K1JT VE1SKY FN74"
|
||||
==> Tx2 should be generated and queued; transmission will pause
|
||||
briefly, Tx freq changed to 50.265, then Tx resumed.
|
||||
|
||||
The test file is posted at
|
||||
http://physics.princeton.edu/pulsar/K1JT/150826_120515.wav
|
||||
@@ -1,186 +0,0 @@
|
||||
White Paper: FT8 for DXpeditions
|
||||
-----------------------------------
|
||||
Joe Taylor, K1JT - October 27, 2017
|
||||
|
||||
Assumptions:
|
||||
|
||||
1. WSJT-X will have two distinct options that enable the maximum-rate
|
||||
QSO exchanges described below. Fox must select "Fox"; all Hounds must
|
||||
select "Hound".
|
||||
|
||||
2. There will be an announced basic dial frequency for each band, say
|
||||
f0=14082 kHz for 20m. This is the basic Channel.
|
||||
|
||||
3. Fox always transmits in the 1st sequence, 200-800 Hz above f0.
|
||||
|
||||
4. Hounds call in 2nd sequence, 1000-5000 Hz above f0. Hounds
|
||||
transmitting below f0+1000 Hz will not be answered.
|
||||
|
||||
5. If found necessary, additional Channels may be defined in which
|
||||
Hounds can transmit. (However, I suggest that CQ-by-call-area may
|
||||
be easier to implement and use; and the software could be made to
|
||||
prevent Hounds in the wrong area from transmitting.)
|
||||
|
||||
6. Ideally, Fox and Hounds should all use CAT control configured with
|
||||
*Split Operation* set to *Rig* or *Fake It*, and transceiver dial
|
||||
frequencies should best be calibrated to within a few Hz. (WSJT-X
|
||||
provides tools that make this fairly easy to do.)
|
||||
|
||||
|
||||
When Fox is running a pileup, QSOs will look something like the
|
||||
following exchanges. Here I've assumed the Fox callsign is KH1DX,
|
||||
his locator AJ10:
|
||||
|
||||
------------------------------------------------------------------------
|
||||
Fox Hounds
|
||||
------------------------------------------------------------------------
|
||||
1. CQ KH1DX AJ10
|
||||
2. KH1DX K1ABC FN42, KH1DX W9XYZ EN37, ...
|
||||
3. K1ABC KH1DX -13
|
||||
4. KH1DX K1ABC R-11
|
||||
5. K1ABC RR73; W9XYZ <KH1DX> -17
|
||||
6. ... no copy from W9XYZ ...
|
||||
7. W9XYZ KH1DX -17
|
||||
8. ... no copy from W9XYZ ...
|
||||
9. G4AAA KH1DX -11
|
||||
10. KH1DX G4AAA R-03
|
||||
11. G4AAA RR73; DL3BBB <KH1DX> -12
|
||||
12. KH1DX DL3BBB R-09
|
||||
13. DL3BBB RR73; DE <KH1DX>
|
||||
14. ...
|
||||
------------------------------------------------------------------------
|
||||
|
||||
All messages except those containing "<...>" are standard FT8 messages
|
||||
(i3bit=0, iFreeText=0). Hounds transmit only standard messages.
|
||||
|
||||
Fox transmits standard messages and also special messages with
|
||||
i3bit=1. The special messages contain a callsign whose completed QSO
|
||||
is being acknowledged; a callsign for the next station to be worked; a
|
||||
hash code corresponding to the Fox callsign; and a signal report.
|
||||
Users will see the Fox callsign enclosed in angle brackets, <KH1DX>.
|
||||
The 72-bit message payload contains two 28-bit callsigns, a 10-bit
|
||||
hash code, and a 6-bit signal report. If no call has been queued up
|
||||
by Fox for the next QSO, the acknowledgment message takes the
|
||||
abbreviated form shown in line 13 above.
|
||||
|
||||
When a Hound receives a message with i3bit=1, the decoder interprets
|
||||
the remaining 72 bits as described above. If the 10-bit hash code
|
||||
matches that for Fox's callsign, the message is displayed as in the
|
||||
QSO exchanges shown above. Otherwise the message is considered a
|
||||
false decode and is not displayed.
|
||||
|
||||
|
||||
Station Setup and Operation for FOX
|
||||
-----------------------------------
|
||||
|
||||
A wide Rx bandwidth (up to 5 kHz) is selected. The basic dial
|
||||
frequency is set 1 kHz above f0 (thus 14083 kHz in my example) and the
|
||||
audio TxFreq somewhere between -200 and -800 Hz. (Yes, negative
|
||||
numbers are OK. *Split Operation* will reset the Tx dial frequency as
|
||||
needed and will keep the generated Tx audio frequency between 1500 and
|
||||
2000 Hz.) Hounds with audio TxFreq set to N Hz will be received by Fox
|
||||
at N-1000 Hz.
|
||||
|
||||
WSJT-X at Fox will maintain and display a list of all decoded Hounds
|
||||
calling Fox in the past 2 to 4 Rx cycles. The list might look
|
||||
something like this (but typically will be much longer):
|
||||
|
||||
----------------------------
|
||||
Call Grid Rpt Freq
|
||||
----------------------------
|
||||
AA2UK FM29 -11 240
|
||||
AD9H EN61 +02 1260
|
||||
K0TPP EM48 -15 1980
|
||||
N2BJ EN61 +11 540
|
||||
N4NDR EL98 -17 4620
|
||||
NX4E EM70 +00 3780
|
||||
ON3LA JN29 -10 3300
|
||||
PD9BG JO21 -21 2100
|
||||
PJ4/KA1XYZ FK60 -07 1020
|
||||
VE1SKY FN74 +03 1620
|
||||
WB2REM EL97 -13 3060
|
||||
...
|
||||
----------------------------
|
||||
|
||||
Fox can choose to have the list sorted on any column.
|
||||
|
||||
Fox selects a Hound to call next by clicking on a line. Or he can hit
|
||||
"F1" to have the program select a caller according to one of these
|
||||
criteria (maybe others as well?):
|
||||
|
||||
- Weakest caller
|
||||
- Strongest caller
|
||||
- Strongest one below -N dB (with N selectable)
|
||||
- Choose a call at random
|
||||
- Random choice with S/N between snrMin and snrMax dB.
|
||||
|
||||
After a particular Hound has been called, Fox's Auto-Sequencer looks
|
||||
for a response containing "R+rpt" originating from that same callsign.
|
||||
If such a message is received, Fox's next transmission will be the
|
||||
special "acknowledge-and-call-next" type, with i3bit=1. If the
|
||||
expected message is not received, as in example line 6 above, the
|
||||
report is sent to the same station again. If the second attempt fails
|
||||
and another Hound callsign has been queued up, the QSO is aborted and
|
||||
the next Hound is called.
|
||||
|
||||
|
||||
Station Setup and Operation for Hounds
|
||||
--------------------------------------
|
||||
|
||||
Dial frequency is set to f0, 14082 kHz in my example. Rx bandwidth and
|
||||
displayed range on the Wide Graph can be anything convenient, say 200
|
||||
to 2600 Hz. (Signal from Fox will be expected between 200 and 800
|
||||
Hz.) Enter callsign and locator of Fox on WSJT-X main window as *DX
|
||||
Call* and *DX Grid*. Choose a TxFreq offset of 1000 + 60*N for some N
|
||||
in the range 1 to 80 (maybe even higher?). Move TxFreq as desired,
|
||||
hoping to find a clear slot, by using Shift+F11 and Shift+F12.
|
||||
|
||||
- Hit F1 to call Fox in your next Tx sequence. Yes, you must hit F1
|
||||
repeatedly, in order to keep calling.
|
||||
|
||||
- The Auto-sequencer will watch for a decoded message that contains
|
||||
"MyCall DXcall rpt" or "MyCall <DXcall> rpt". When one of these is
|
||||
received, your next transmission will be "DXcall MyCall R+rpt",
|
||||
sent automatically.
|
||||
|
||||
- After you send the "R+rpt" message, AutoSeq will watch for a
|
||||
message that starts with "MyCall RR73; ...". When that is
|
||||
received, you're in his log, and you'll be prompted to log the QSO.
|
||||
|
||||
Random thoughts
|
||||
---------------
|
||||
|
||||
Fox's decoder has access to signals in a 4 kHz (maybe even 5 kHz?)
|
||||
window. At 60 Hz intervals, that's enough for around 65 (or 80?)
|
||||
non-overlapping Hound signals. If the pileup becomes too deep, more
|
||||
spectrum might be used; but note that WSJT-X can't access more than 5
|
||||
kHz at one time. A better solution might be for Fox to call "CQ n
|
||||
KH1DX AJ10", where n is a single digit indicating call area. The
|
||||
decoder could then limit the list of eligible calls to those in the
|
||||
specified call area. After decoding such a CQ, the software at Hound
|
||||
could refuse to transmit unless MyCall falls in the specified call
|
||||
area. (Other special CQ formats can be imagined that would limit the
|
||||
eligible Hound callsigns even further.)
|
||||
|
||||
We haven't thought much, yet, about logging issues for Fox. I imagine
|
||||
we could do what's necessary to join a N1MM+ logging network, if that's
|
||||
deemed desirable.
|
||||
|
||||
A few questions:
|
||||
|
||||
Q1: Should the Auto-Sequencer allow for other cases in which a QSO has
|
||||
been initiated by Fox, but one of next two messages is not copied by
|
||||
either Fox or Hound? For example, what if K1ABC does not copy message
|
||||
#5? Should he keep sending his message "KH1DX K1ABC R-11" ? If Fox
|
||||
receives this message again, should he acknowledge again? And poor
|
||||
W9XYZ, who never received an acknowledgment, will probably keep
|
||||
sending "KH1DX W9XYZ R-19", or whatever. If Fox eventually copies the
|
||||
message, should the program remember that W9XYZ had been called, and
|
||||
thus send him an acknowledgment?
|
||||
|
||||
Q2: Should we provide a stack for several to-be-called callsigns,
|
||||
rather than just one? Should re-ordering of calls in the stack be
|
||||
permitted?
|
||||
|
||||
Q3: Can we handle WSJT-X "Type 1" and "Type 2" compound callsigns, for
|
||||
Hounds?
|
||||
@@ -1,71 +0,0 @@
|
||||
Auto-Sequencing algorithm for DXpedition station:
|
||||
|
||||
Start:
|
||||
CQMsg = "CQ KH1DX" (or "CQ UP KH1DX", "CQ 116 KH1DX", etc.)
|
||||
TxMsg = CQMsg
|
||||
Ntry = 0
|
||||
QCALL = "" # Callsign of current QSO partner
|
||||
go to Transmit
|
||||
|
||||
Transmit:
|
||||
TX # (... takes 13.6 s)
|
||||
go to Receive
|
||||
|
||||
Receive:
|
||||
RX # (... takes ~14 s)
|
||||
N = number of decodes # RxMsg[i], i=1,N
|
||||
if(N == 0)
|
||||
go to Transmit
|
||||
J = index of a reply from current QCALL # RxMsg[J] = "KH1DX QCALL R<rpt>"
|
||||
|
||||
if(QCALL == "") # No QSO in progress
|
||||
Select new QCALL # Op chooses a caller
|
||||
if(QCALL == "")
|
||||
TxMsg = CQMsg # No callers, we'll CQ again
|
||||
else # QSO in progress
|
||||
if(J >= 1) # Expected message was received
|
||||
log the QSO with QCALL
|
||||
QCALL = ""
|
||||
Select new QCALL # Op chooses a new caller
|
||||
if(QCALL != "")
|
||||
TxMsg = "73 NOW QCALL <rpt>" # Start a new QSO
|
||||
else
|
||||
TxMsg = "73 " + CQMsg # No callers, we'll CQ again
|
||||
else
|
||||
Ntry = Ntry + 1 # Expected msg not received
|
||||
if(Ntry <= NtryMax)
|
||||
go to Transmit # Ask for a repeat
|
||||
else
|
||||
QCALL = "" # Max tries exceeded, abort this QSO
|
||||
Select new QCALL # Choose a new caller
|
||||
if(QCALL != "")
|
||||
TxMsg = "NIL NOW QCALL <rpt>" # Start a new QSO
|
||||
else
|
||||
TxMsg = "NIL " + CQMSG # No callers, we'll CQ again
|
||||
go to Transmit
|
||||
|
||||
|
||||
Auto-Sequencing algorithm for those calling the DXpedition:
|
||||
|
||||
Start:
|
||||
TxMsg = "KH1DX MyCall"
|
||||
InQSO = false
|
||||
|
||||
Transmit:
|
||||
TX # (... takes 13.6 s)
|
||||
go to Receive
|
||||
|
||||
Receive:
|
||||
RX # (... takes ~14 s)
|
||||
if(RxMsg[i] contains "MyCall <rpt>")
|
||||
InQSO = true
|
||||
TxMsg = "KH1DX MyCall R<rpt>"
|
||||
go to Transmit
|
||||
|
||||
if(RxMsg[i] contains "<rpt>")
|
||||
TxEnable = false
|
||||
go to Receive
|
||||
|
||||
if(RxMsg[i] contains "CQ KH1DX")
|
||||
TxEnable = true
|
||||
go to Transmit
|
||||
@@ -1,395 +0,0 @@
|
||||
Fast Modes in WSJT-X
|
||||
--------------------
|
||||
|
||||
#######################################################################
|
||||
|
||||
IMPORTANT - IMPORTANT - IMPORTANT - IMPORTANT - IMPORTANT - IMPORTANT
|
||||
|
||||
Third-party individuals (i.e., others not part of the WSJT development
|
||||
team) have been compiling WSJT-X from the open source code and making
|
||||
unauthorized "releases" of their builds. I do NOT reccommend use of
|
||||
unauthorized builds on the air. If a program revision has been released
|
||||
in an official way, you will see it listed here.
|
||||
|
||||
If you operate with an unauthorized "rXXXX" code revisions in our
|
||||
experimental code branch you have no idea what you've got. Quite
|
||||
possibly, the program was built from an intermediate temporary "save"
|
||||
of various files, and was not even supposed to produce a usable
|
||||
program. Your observetions about what works or does not work are then
|
||||
worse than useless -- they waste your time and ours.
|
||||
|
||||
So please, PLEASE, *PLEASE*: use *authorized*, "released* revisions
|
||||
of this still-in-development software, like the revisions described here.
|
||||
|
||||
*ALSO:* If you choose to try an experimental release of JTMSK, please
|
||||
accept the responsibility of reporting on your results. You can send
|
||||
reports to the "wsjtgroup" reflector, wsjtgroup@yahoogroups.com, or
|
||||
email them directly to me. All suggestions for improvements are
|
||||
welcome!
|
||||
|
||||
Bug reports should include details on how to reproduce the undesirable
|
||||
program behavior. Reports on decoding performance are especially
|
||||
useful when accompanied by example *.wav files with signals that
|
||||
you think should have decoded, but did not.
|
||||
|
||||
#######################################################################
|
||||
|
||||
September 18, 2015
|
||||
-----------------
|
||||
|
||||
New alpha release of experimental WSJT-X v1.6.1, r5910
|
||||
------------------------------------------------------
|
||||
Changes since revision 5889 include the following:
|
||||
|
||||
1. Improved behavior for auto-QSY with "CQ nnn ..." feature. (May not
|
||||
be exactly correct, yet, for all radios. Please report if you find
|
||||
problems with your rig.)
|
||||
|
||||
2. Allow optional use of Wide Graph in fast modes.
|
||||
|
||||
3. Add UTC labels to Fast Graph spectrograms.
|
||||
|
||||
4. Display correct DXCC entiry for "CQ nnn ..." messages.
|
||||
|
||||
5. Implement "Save Decoded" for fast modes.
|
||||
|
||||
6. Select Tx6 when "CQ Rx nnn" is enabled.
|
||||
|
||||
7. Fix bug in setting of TRperiod after switch to ISCAT mode.
|
||||
|
||||
8. Display proper symbol '&' in Tx messages in JTMSK mode.
|
||||
|
||||
|
||||
To download this alpha release for Windows, paste the following link
|
||||
into your browser:
|
||||
http://physics.princeton.edu/pulsar/K1JT/wsjtx-1.6.1-r5910-win32.exe
|
||||
|
||||
-- 73, Joe, K1JT
|
||||
|
||||
#######################################################################
|
||||
|
||||
September 12, 2015
|
||||
-----------------
|
||||
|
||||
New alpha release of experimental WSJT-X v1.6.1, r5889
|
||||
------------------------------------------------------
|
||||
|
||||
A principal new feature in this release is designed to promote the use
|
||||
of an agreed "calling frequency" for transmissions of the form
|
||||
|
||||
CQ 265 K1ABC FN42
|
||||
|
||||
signifying that K1ABC will listen for replies on 50.265 (or 144.265,
|
||||
or whatever) and will complete the QSO there. The feature uses the
|
||||
rig-control features of WSJT-X to handle the necessary frequency
|
||||
switching.
|
||||
|
||||
##########################################################################
|
||||
Changes since revision 5865 include the following:
|
||||
|
||||
1. New features that allow automatic rig control when you transmit or
|
||||
respond to messages of the form "CQ 265 K1ABC FN42" on an agreed
|
||||
calling frequency. This feature should be especially useful for
|
||||
meteor scatter.
|
||||
|
||||
2. Yellow-highlighted "Tx" messages in the right text window are now
|
||||
properly labeled with 6-digit UTC (hhmmss) in all fast modes.
|
||||
|
||||
3. Fixed a bug (introduced in r5865) that inhibited transmitting in
|
||||
JT4 mode.
|
||||
|
||||
4. Fixed a bug that caused Wide Graph to continue issuing green
|
||||
separator lines at short (e.g. 15 s) intervals after you have switched
|
||||
to a slow mode.
|
||||
|
||||
5. Fixed several more GUI appearance bugs associated with changing
|
||||
modes or submodes.
|
||||
|
||||
6. Fixed a bug in which double-clicking on the Fast Graph could cause
|
||||
program crashes.
|
||||
|
||||
7. Fixed a bug that sometimes caused "high tones" to be emitted in
|
||||
JTMSK mode.
|
||||
|
||||
#######################################################################
|
||||
Here's a brief description of how to use the "CQ nnn ..." features.
|
||||
|
||||
1. On program startup, go to the Settings | General tab and tick the
|
||||
box labeled 'Rx frequency offset with "CQ nnn ..."'
|
||||
|
||||
2. Select JTMSK mode and 50.280 (or your some other agreed calling
|
||||
frequency) from the drop-down band menu. Remember that this menu is
|
||||
not pre-populated with preferred frequencies for all modes on all
|
||||
bands. Use Settings | Frequencies to add your desired modes and
|
||||
frequencies to the list.
|
||||
|
||||
3. Tick the unlabeled checkbox just under the "Report: spinner to
|
||||
activate the "CQ Rx nnn" spinner. Set this control to your desired
|
||||
QSO frequency in kHz above the nominal band edge. On 6 meters, for
|
||||
example, "265" means "50.265".
|
||||
|
||||
4. Your transceiver dial frequency should now show 50.265. Changes to
|
||||
the "CQ Rx nnn" spinner value should be reflected immediately in the
|
||||
transceiver dial frequency, the displayed value on the WSJT-X main
|
||||
screen, and in Tx message #6, the "CQ nnn... " message.
|
||||
|
||||
5. When you transmit the Tx6 message, the Tx frequency will be set at
|
||||
the calling frequency. Otherwise (when receiving, or when
|
||||
transmitting any of the messages Tx1 through Tx5) the offset frequency
|
||||
(50.265 in my example) will be used.
|
||||
|
||||
6. If you double-click on a received "CQ nnn ..." message on the
|
||||
calling frequency, your rig will QSY to specified response frequency,
|
||||
e.g. 50.265, for both Rx and Tx.
|
||||
|
||||
7. To go back to listening on the calling frequency, uncheck the box
|
||||
that activated the "CQ Rx nnn" spinner.
|
||||
|
||||
#######################################################################
|
||||
|
||||
Fair warning: I have not yet tested all possible combinations of
|
||||
"Split Operation" configuration (i.e., "None", "Rig", and "Fake it").
|
||||
If you normally use Split operation, that should be OK for the "CQ
|
||||
nnn ..." feature.
|
||||
|
||||
|
||||
As always, please report any bugs that you find in r5889, including
|
||||
pertinent details on your settings and the exact series of steps
|
||||
required to reproduce the bug.
|
||||
|
||||
|
||||
To download this alpha release for Windows, paste the following link
|
||||
into your browser:
|
||||
http://physics.princeton.edu/pulsar/K1JT/wsjtx-1.6.1-r5889-win32.exe
|
||||
|
||||
|
||||
-- 73, Joe, K1JT
|
||||
|
||||
#######################################################################
|
||||
|
||||
New alpha release of experimental WSJT-X v1.6.1, r5865
|
||||
------------------------------------------------------
|
||||
|
||||
This alpha release of WSJT-X includes major improvements to the JTMSK
|
||||
decoder. Changes since revision 5823 include the following:
|
||||
|
||||
1. On-screen controls labeled "Rx nnnn Hz" and "F Tol" (Rx frequency
|
||||
and tolerance) now function as expected in JTMSK mode. The frequency
|
||||
search range can be up to 500 Hz, but note that sensitivity is
|
||||
necessarily reduced for signals off frequency by more than about 250
|
||||
Hz. Normally you should leave Rx Freq set at 1500 Hz; suitable values
|
||||
for F Tol are 100 to 500 Hz.
|
||||
|
||||
2. The JTMSK decoder now makes good use of strong, short pings (as
|
||||
short as 0.1 s) as well as weak pings several times longer.
|
||||
|
||||
3. Improved calculation of S/N and frequency of decoded signals.
|
||||
|
||||
4. Unified appearance of window titles on all non-modal windows.
|
||||
|
||||
5. CW ID is disabled (for now, at least) when operating in any of the
|
||||
WSJT fast modes.
|
||||
|
||||
6. In WSPR mode, display of "Receiving ... <band>" messages is
|
||||
disabled when band-hopping is not in use.
|
||||
|
||||
7. Fixed several bugs affecting status and visibility of certain
|
||||
on-screen controls after changes in operating mode.
|
||||
|
||||
8. Fixed a bug allowing display of duplicate decodes for the same
|
||||
signal.
|
||||
|
||||
9. Fixed a bug preventing compilation on 64-bit systems, and cleaned
|
||||
up some harmless compiler warnings.
|
||||
|
||||
#######################################################################
|
||||
Summary Description of JTMSK Protocol
|
||||
|
||||
JTMSK uses the same standard message structure as slow modes JT4, JT9,
|
||||
and JT65. User information is "source encoded" to 72 bits. A 15-bit
|
||||
CRC is appended and a convolutional code with constraint length K=13
|
||||
and rate r=1/2 is applied, making a total of (72+15+12)*2 = 198
|
||||
information bits. Three copies of the "Barker-11" code and three
|
||||
even-parity bits are added for synchronization, making a total of
|
||||
198+33+3 = 234 channel symbols. Modulation uses a constant-envelope,
|
||||
continuous-phase "minimum-shift keying" (MSK) waveform, with tone
|
||||
frequencies of 1000 and 2000 Hz.
|
||||
|
||||
#######################################################################
|
||||
|
||||
To download this alpha release for Windows, paste the following link
|
||||
into your browser:
|
||||
http://physics.princeton.edu/pulsar/K1JT/wsjtx-1.6.1-r5865-win32.exe
|
||||
|
||||
-- 73, Joe, K1JT
|
||||
|
||||
August 28, 2015
|
||||
---------------
|
||||
|
||||
New release of experimental WSJT-X v1.6.1, r5823
|
||||
------------------------------------------------
|
||||
|
||||
To download for Windows, paste the following link into your browser:
|
||||
http://physics.princeton.edu/pulsar/K1JT/wsjtx-1.6.1-r5823-win32.exe
|
||||
|
||||
This experimental version of WSJT-X introduces a new fast mode called
|
||||
JTMSK. The letters MS, of course, imply meteor scatter; the three
|
||||
letters MSK mean "Minimum Shift Keying", the modulation scheme used in
|
||||
this mode.
|
||||
|
||||
Revision 5823 also includes a number of (mostly minor) bug fixes
|
||||
relative to r5789.
|
||||
|
||||
IMPORTANT: If you choose to try JTMSK, please accept the
|
||||
responsibility of reporting on your results. You can send reports to
|
||||
the "wsjtgroup" reflector, wsjtgroup@yahoogroups.com or email them
|
||||
directly to me. All suggestions for improvements are welcome! Bug
|
||||
reports should include details on how to reproduce the undesirable
|
||||
program behavior.
|
||||
|
||||
The present JTMSK decoder has been optimized for short pings. It does
|
||||
not yet do a wide search for proper frequency alignment; you and your
|
||||
QSO partner need to be "on frequency" to within +/- 100 Hz or better.
|
||||
The decoder does not (yet) attempt to make optimal use of weak, slowly
|
||||
varying signals. These and other characteristics may be improved in
|
||||
coming revisions.
|
||||
|
||||
KNOWN BUG: At present you should use T/R sequence lengths 15 s in
|
||||
JTMSK mode. If you have a program crash, open Windows Task Manager,
|
||||
select the "Processes" tab, right-click on wsjtx.exe, and select "End
|
||||
Process Tree". Then restart the program.
|
||||
|
||||
I view JTMSK as a candidate for replacing both FSK441 and JTMS for all
|
||||
meteor scatter work. JTMSK has the major advantage of including
|
||||
strong forward error correction (FEC), similar in usage to the schemes
|
||||
used for many years in JT4, JT9, and JT65. The structure of user
|
||||
messages and the format of minimal QSOs is also identical to those
|
||||
other modes. But JTMSK is very fast, transmitting its full encoded
|
||||
message content in 0.117 s, in a 2 kHz bandwidth. JTMSK therefore
|
||||
makes much better use of short pings than (for example) JT9H can do.
|
||||
|
||||
The Tx waveform of JTMSK has been carefully designed to have a number
|
||||
of desirable features. All messages are exactly the same length: 72
|
||||
bits of user information are followed by a 15-bit CRC and encoded into
|
||||
198 channel bits with a convolutional code (constraint length K=13,
|
||||
rate r=1/2). Three sequences of the "Barker-11" code are added, along
|
||||
with three parity bits, making a total of 234 channel bits in each
|
||||
message. The MSK symbols for these bits are transmitted at 2000 baud,
|
||||
and the full encoded message is repeated every 117 ms.
|
||||
|
||||
A summary description of modulation parameters for all WSJT(-X) modes
|
||||
is shown in a table posted here:
|
||||
http://physics.princeton.edu/pulsar/K1JT/wsjt_modes.txt and
|
||||
illustrated graphically here:
|
||||
http://physics.princeton.edu/pulsar/K1JT/wsjt_modes.pdf
|
||||
|
||||
-- 73, Joe, K1jT
|
||||
|
||||
August 15, 2015
|
||||
---------------
|
||||
|
||||
New release of experimental WSJT-X v1.6.1, r5789
|
||||
|
||||
Changes since WSJT-X v1.6.1, revision 5779:
|
||||
|
||||
1. Major speedup (5x) of fast-JT9 decoder.
|
||||
2. Corrected logic for Auto-Sequencing operation.
|
||||
3. Stop after sending 73 five times in auto-sequence mode.
|
||||
4. Add an "Auto-Level" control to Fast Graph window.
|
||||
5. Send fast-mode decodes to PSKreporter web site.
|
||||
6. Support automatic logging via JTAlert-X.
|
||||
7. Send fast-mode output to file ALL.TXT.
|
||||
8. Better definition of dB levels for fast-JT9 signals.
|
||||
9. Rationalize the GUI behavior when changing mode, submode, fast/slow
|
||||
status, and T/R period.
|
||||
10. Correct a flaw in the display of multiple decodes in a single
|
||||
fast-JT9 sequence.
|
||||
11. Fix minor bugs reported by G3WDG, ND0B, OZ1PIF, and others.
|
||||
|
||||
To download for Windows, paste the following link into your browser:
|
||||
http://physics.princeton.edu/pulsar/K1JT/wsjtx-1.6.1-r5789-win32.exe
|
||||
|
||||
Please keep in mind that this is an experimental version of WSJT-X.
|
||||
Bug reports and other feedback will be much appreciated, and will help
|
||||
to make the program better!
|
||||
|
||||
-- 73, Joe, K1JT
|
||||
|
||||
|
||||
August 11, 2015
|
||||
---------------
|
||||
|
||||
Since its origin in the dark ages (ca. 2001) WSJT has supported "fast"
|
||||
modes (designed for meteor scatter, etc.) and "slow" modes (optimized
|
||||
for EME and other weak-signal propagation types). The most recent new
|
||||
mode, JT9, now has *both* fast and slow submodes.
|
||||
|
||||
JT9A (the "original" JT9) is like JT65 and JT4: its T/R sequences are
|
||||
one minute long, and its primary goal is best possible sensitivity for
|
||||
very weak, approximately steady signals. The new experimental JT9
|
||||
submodes use the same message structure, encoding, and modulation type
|
||||
(9-tone FSK) as JT9A, but wider tone spacing and (optionally) faster
|
||||
keying rates.
|
||||
|
||||
You can download an experimental version of WSJT-X (v1.6.1, r5779) here:
|
||||
http://physics.princeton.edu/pulsar/K1JT/wsjtx-1.6.1-r5779-win32.exe
|
||||
|
||||
The fast submodes currently being tested, JT9E - JT9H, have been found
|
||||
highly effective for meteors and ionoscatter propagation on 6 and 10
|
||||
meters. Sensitivity is similar to ISCAT, or slightly better.
|
||||
Decoding is much more reliable, because the JT9 protocol includes
|
||||
strong forward error correction. Decoding results are like those for
|
||||
all the WSJT "slow" modes: you should see messages exactly as they
|
||||
were transmitted, or nothing at all. A potential side benefit is
|
||||
automatic reporting of decodes to PSKreporter.
|
||||
|
||||
For details on the modulation parameters of the JT9 submodes, see the
|
||||
table posted at
|
||||
http://physics.princeton.edu/pulsar/K1JT/wsjt_modes.txt.
|
||||
|
||||
WSJT-X v1.6.1 r5779 has the following changes from r5769:
|
||||
|
||||
1. Numerous bug fixes
|
||||
2. Double-click on decoded message now behaves properly
|
||||
3. Faster decoding (further optimization still to come)
|
||||
4. Decoded text is highlighted as in WSJT-X slow modes
|
||||
5. Optional auto-sequencing
|
||||
|
||||
Fair warning: auto-sequencing is basically functional, but scarcely
|
||||
tested. Please watch what it is doing, and tell us how you think it
|
||||
should be improved!
|
||||
|
||||
If you use WSJT-X also for other modes and other purposes, you may
|
||||
want to save several different sets of configuration settings. In
|
||||
that case it's convenient to use the "-r xxx" option and start the
|
||||
program from a command-prompt window. For example:
|
||||
|
||||
C:\Users\joe> cd \wsjt\wsjtx\bin
|
||||
C:\WSJT\wsjtx\bin> wsjtx -r xxx
|
||||
|
||||
... where "xxx" can be anything you like, for example "ISCAT",
|
||||
"FAST9", etc.
|
||||
|
||||
Proper configuration for the JT9 fast modes includes the following
|
||||
settings:
|
||||
|
||||
On the Settings | General tab:
|
||||
|
||||
- check "Enable VHF/UHF/Microwave features"
|
||||
|
||||
Main window settings:
|
||||
|
||||
- Mode JT9
|
||||
- Tx 700 Hz
|
||||
- Rx 700 Hz
|
||||
- Sync 0
|
||||
- Submode G ... or E, F, and H (H not legal in US on 10m)
|
||||
- Tick "Fast"
|
||||
- T/R 30 s (also 5, 10, 15 s)
|
||||
- FTol 500
|
||||
|
||||
Please keep in mind that this is an experimental version of WSJT-X.
|
||||
It still has some rough edges, and no doubt some bugs. Your feedback
|
||||
will be much appreciated, and will help to make the program better!
|
||||
|
||||
-- 73, Joe, K1JT
|
||||
@@ -1,71 +0,0 @@
|
||||
CC = gcc
|
||||
CXX = g++
|
||||
FC = gfortran
|
||||
|
||||
FFLAGS = -O2 -fbounds-check -Wall -Wno-conversion
|
||||
CFLAGS = -O2 -I.
|
||||
|
||||
# Default rules
|
||||
%.o: %.c
|
||||
${CC} ${CFLAGS} -c $<
|
||||
%.o: %.f
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.F
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.f90
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.F90
|
||||
${FC} ${FFLAGS} -c $<
|
||||
|
||||
#all: qratest.exe tplt.exe
|
||||
all: qra64d.exe
|
||||
|
||||
OBJS1 = qratest.o qra64a.o ana64.o sync64a.o four2a.o smo.o smo121.o averms.o \
|
||||
timer_module.o packjt.o twkfreq.o spec64.o fmtmsg.o pctile.o \
|
||||
grid2deg.o deg2grid.o shell.o badmsg.o qra64_subs.o \
|
||||
qracodes.o npfwht.o pdmath.o qra12_63_64_irr_b.o \
|
||||
qra13_64_64_irr_e.o qra64.o image.o \
|
||||
zplt64a.o zplt64b.o lorentzian.o fchisq0.o peakup.o sync64.o
|
||||
|
||||
qra64_subs.o: qra/qra64/qra64_subs.c
|
||||
gcc -c -O2 -o qra64_subs.o qra/qra64/qra64_subs.c
|
||||
|
||||
qracodes.o: qra/qracodes/qracodes.c
|
||||
gcc -c -O2 -o qracodes.o qra/qracodes/qracodes.c
|
||||
|
||||
qra64.o: qra/qra64/qra64.c
|
||||
gcc -c -O2 -o qra64.o qra/qra64/qra64.c
|
||||
|
||||
npfwht.o: qra/qracodes/npfwht.c
|
||||
gcc -c -O2 -o npfwht.o qra/qracodes/npfwht.c
|
||||
|
||||
pdmath.o: qra/qracodes/pdmath.c
|
||||
gcc -c -O2 -o pdmath.o qra/qracodes/pdmath.c
|
||||
|
||||
qra12_63_64_irr_b.o: qra/qracodes/qra12_63_64_irr_b.c
|
||||
gcc -c -O2 -o qra12_63_64_irr_b.o qra/qracodes/qra12_63_64_irr_b.c
|
||||
|
||||
qra13_64_64_irr_e.o: qra/qracodes/qra13_64_64_irr_e.c
|
||||
gcc -c -O2 -o qra13_64_64_irr_e.o qra/qracodes/qra13_64_64_irr_e.c
|
||||
|
||||
qratest.exe: $(OBJS1)
|
||||
$(FC) -o qratest.exe $(OBJS1) C:\JTSDK\fftw3f\libfftw3f-3.dll
|
||||
|
||||
OBJS2 = tplt.o zplt64.o image.o
|
||||
tplt.exe: $(OBJS2)
|
||||
$(FC) -o tplt.exe $(OBJS2)
|
||||
|
||||
OBJS3 = qra64d.o sync64a.o four2a.o smo.o smo121.o averms.o \
|
||||
timer_module.o packjt.o twkfreq.o spec64.o fmtmsg.o pctile.o \
|
||||
grid2deg.o deg2grid.o shell.o badmsg.o qra64_subs.o \
|
||||
qracodes.o npfwht.o pdmath.o qra12_63_64_irr_b.o \
|
||||
qra13_64_64_irr_e.o qra64.o image.o \
|
||||
zplt64a.o zplt64b.o lorentzian.o fchisq0.o peakup.o sync64.o
|
||||
|
||||
qra64d.exe: $(OBJS3)
|
||||
$(FC) -o qra64d.exe $(OBJS3) C:\JTSDK\fftw3f\libfftw3f-3.dll
|
||||
|
||||
.PHONY : clean
|
||||
|
||||
clean:
|
||||
$(RM) *.o qratest.exe tplt.exe
|
||||
@@ -1,153 +0,0 @@
|
||||
# Makefile for MinGW on Windows
|
||||
#
|
||||
# Needed libraries are located using the following variables:
|
||||
#
|
||||
# QT_DIR - point this at the root of your Qt installation
|
||||
# FFTW3_DIR - point this at the fftw v3 installation directory
|
||||
#
|
||||
# e.g.
|
||||
# make -f Makefile.MinGW \
|
||||
# QT_DIR=c:/Qt/5.2.1/mingw48_32 \
|
||||
# FFTW3_DIR = c:/fftw-3.3.3-dll32-2
|
||||
#
|
||||
# Windows re-direct:
|
||||
# C> make > junk1 2>&1
|
||||
|
||||
# Set paths
|
||||
EXE_DIR = ..\\..\\wsjtx_install
|
||||
QT_DIR = C:/wsjt-env/Qt5/5.2.1/mingw48_32
|
||||
FFTW3_DIR = ..
|
||||
|
||||
INCPATH = -I${QT_DIR}/include/QtCore -I${QT_DIR}/include
|
||||
|
||||
# Compilers
|
||||
CC = gcc
|
||||
CXX = g++
|
||||
FC = gfortran
|
||||
AR = ar cr
|
||||
RANLIB = ranlib
|
||||
MKDIR = mkdir -p
|
||||
CP = cp
|
||||
RM = rm -f
|
||||
|
||||
FFLAGS = -O2 -fbounds-check -Wall -Wno-precision-loss -fno-second-underscore
|
||||
CFLAGS = -I. -fbounds-check -mno-stack-arg-probe
|
||||
|
||||
# Default rules
|
||||
%.o: %.c
|
||||
${CC} ${CFLAGS} -c $<
|
||||
%.o: %.f
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.F
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.f90
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.F90
|
||||
${FC} ${FFLAGS} -c $<
|
||||
|
||||
all: libjt9.a libastro.a jt9.exe jt9code.exe jt65code.exe
|
||||
|
||||
OBJS1 = prog_args.o options.o pctile.o graycode.o sort.o ssort.o chkmsg.o \
|
||||
unpackmsg.o igray.o unpackcall.o unpackgrid.o \
|
||||
fmtmsg.o grid2k.o unpacktext.o getpfx2.o packmsg.o deg2grid.o \
|
||||
packtext.o getpfx1.o packcall.o k2grid.o packgrid.o \
|
||||
nchar.o four2a.o grid2deg.o pfxdump.o f77_wisdom.o \
|
||||
symspec.o analytic.o db.o genjt9.o flat1.o smo.o \
|
||||
packbits.o unpackbits.o encode232.o interleave9.o \
|
||||
entail.o fano232.o gran.o sync9.o decode9.o \
|
||||
fil3.o decoder.o grid2n.o n2grid.o timer.o \
|
||||
softsym.o getlags.o afc9.o fchisq.o twkfreq.o downsam9.o \
|
||||
peakdt9.o symspec2.o stdmsg.o morse.o azdist.o geodist.o \
|
||||
fillcom.o chkss2.o zplot9.o flat2.o \
|
||||
jt65a.o symspec65.o flat65.o ccf65.o decode65a.o \
|
||||
filbig.o fil6521.o afc65b.o decode65b.o setup65.o \
|
||||
extract.o fchisq65.o demod64a.o chkhist.o interleave63.o ccf2.o \
|
||||
move.o indexx.o graycode65.o twkfreq65.o smo121.o \
|
||||
wrapkarn.o init_rs.o encode_rs.o decode_rs.o gen65.o fil4.o \
|
||||
flat3.o polfit.o determ.o baddata.o
|
||||
|
||||
libjt9.a: $(OBJS1)
|
||||
$(AR) libjt9.a $(OBJS1)
|
||||
$(RANLIB) libjt9.a
|
||||
|
||||
OBJS2 = jt9.o jt9a.o jt9b.o jt9c.o ipcomm.o sec_midn.o usleep.o
|
||||
LIBS2 = -L${QT_DIR}/lib -lQt5Core
|
||||
jt9.exe: $(OBJS2) libjt9.a
|
||||
$(CXX) -o jt9.exe $(OBJS2) $(LIBS2) libjt9.a \
|
||||
-L$(FFTW3_DIR) -lfftw3f-3 $(shell $(FC) -print-file-name=lib$(FC).a)
|
||||
-$(MKDIR) $(EXE_DIR)
|
||||
$(CP) jt9.exe $(EXE_DIR)
|
||||
|
||||
OBJS3 = jt9sim.o
|
||||
jt9sim.exe: $(OBJS3) libjt9.a
|
||||
$(FC) -o jt9sim.exe $(OBJS3) libjt9.a
|
||||
|
||||
OBJS4 = jt9code.o
|
||||
jt9code.exe: $(OBJS4) libjt9.a
|
||||
$(FC) -o jt9code.exe $(OBJS4) libjt9.a
|
||||
$(CP) jt9code.exe $(EXE_DIR)
|
||||
|
||||
OBJS5 = jt65.o
|
||||
jt65.exe: $(OBJS5) libjt9.a
|
||||
$(FC) -o jt65.exe $(OBJS5) libjt9.a -L$(FFTW3_DIR) -lfftw3f-3
|
||||
|
||||
OBJS7 = astrosub.o astro0.o astro.o tm2.o grid2deg.o sun.o moondop.o \
|
||||
coord.o dot.o moon2.o tmoonsub.o toxyz.o geocentric.o \
|
||||
dcoord.o
|
||||
|
||||
libastro.a: $(OBJS7)
|
||||
$(AR) libastro.a $(OBJS7)
|
||||
$(RANLIB) libastro.a
|
||||
|
||||
OBJS6 = jt65code.o
|
||||
jt65code.exe: $(OBJS6) libjt9.a
|
||||
$(FC) -o jt65code.exe $(OBJS6) libjt9.a
|
||||
$(CP) jt65code.exe $(EXE_DIR)
|
||||
|
||||
sync9.o: sync9.f90 jt9sync.f90
|
||||
$(FC) $(FFLAGS) -c sync9.f90
|
||||
|
||||
spec9.o: spec9.f90 jt9sync.f90
|
||||
$(FC) $(FFLAGS) -c spec9.f90
|
||||
|
||||
peakdt9.o: peakdt9.f90 jt9sync.f90
|
||||
$(FC) $(FFLAGS) -c peakdt9.f90
|
||||
|
||||
jt9sim.o: jt9sim.f90 jt9sync.f90
|
||||
$(FC) $(FFLAGS) -c jt9sim.f90
|
||||
|
||||
genjt9.o: genjt9.f90 jt9sync.f90
|
||||
$(FC) $(FFLAGS) -c genjt9.f90
|
||||
|
||||
redsync.o: redsync.f90 jt9sync.f90
|
||||
$(FC) $(FFLAGS) -c redsync.f90
|
||||
|
||||
unpackmsg.o: unpackmsg.f90
|
||||
$(FC) -c -O0 -fbounds-check -Wall -Wno-precision-loss unpackmsg.f90
|
||||
|
||||
ipcomm.o: ipcomm.cpp
|
||||
$(CXX) -c $(INCPATH) ipcomm.cpp
|
||||
|
||||
sec_midn.o: sec_midn.f90
|
||||
$(FC) -c -fno-second-underscore sec_midn.f90
|
||||
|
||||
#rig_control.o: rig_control.c
|
||||
# $(CC) -c -Wall -I..\..\..\hamlib-1.2.15.3\include rig_control.c
|
||||
|
||||
tstrig.o: tstrig.c
|
||||
$(CC) -c -Wall -I..\..\..\hamlib-1.2.15.3\include tstrig.c
|
||||
|
||||
init_rs.o: init_rs.c
|
||||
$(CC) -c -DBIGSYM=1 -o init_rs.o init_rs.c
|
||||
|
||||
encode_rs.o: encode_rs.c
|
||||
$(CC) -c -DBIGSYM=1 -o encode_rs.o encode_rs.c
|
||||
|
||||
decode_rs.o: decode_rs.c
|
||||
$(CC) -c -DBIGSYM=1 -o decode_rs.o decode_rs.c
|
||||
|
||||
|
||||
.PHONY : clean
|
||||
|
||||
clean:
|
||||
$(RM) *.o libjt9.a wsjtx.exe jt9sim.exe jt9.exe jt65.exe
|
||||
@@ -1,122 +0,0 @@
|
||||
# Makefile for MinGW on Windows
|
||||
# Windows re-direct:
|
||||
# C> make > junk1 2>&1
|
||||
|
||||
# Set paths
|
||||
EXE_DIR = ../../wsjtx_install
|
||||
INCPATH = -I'c:/QtSDK/Desktop/Qt/4.7.4/mingw/include/QtCore' \
|
||||
-I'c:/QtSDK/Desktop/Qt/4.7.4/mingw/include' \
|
||||
-I'c:/QtSDK/Desktop/Qt/4.7.4/mingw/include/ActiveQt' \
|
||||
-I'release' -I'.' -I'c:/QtSDK/Desktop/Qt/4.7.4/mingw/mkspecs/win32-g++'
|
||||
|
||||
# Compilers
|
||||
CC = gcc
|
||||
CXX = g++
|
||||
FC = g95
|
||||
|
||||
FFLAGS = -O2 -fbounds-check -Wall -Wno-precision-loss -fno-second-underscore
|
||||
CFLAGS = -I. -fbounds-check -mno-stack-arg-probe
|
||||
|
||||
# Default rules
|
||||
%.o: %.c
|
||||
${CC} ${CFLAGS} -c $<
|
||||
%.o: %.f
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.F
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.f90
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.F90
|
||||
${FC} ${FFLAGS} -c $<
|
||||
|
||||
all: libjt9.a jt9sim.exe jt9.exe jt9code.exe jt65.exe
|
||||
|
||||
OBJS1 = pctile.o graycode.o sort.o ssort.o \
|
||||
unpackmsg.o igray.o unpackcall.o unpackgrid.o \
|
||||
grid2k.o unpacktext.o getpfx2.o packmsg.o deg2grid.o \
|
||||
packtext.o getpfx1.o packcall.o k2grid.o packgrid.o \
|
||||
nchar.o four2a.o grid2deg.o pfxdump.o f77_wisdom.o \
|
||||
symspec.o analytic.o db.o genjt9.o \
|
||||
packbits.o unpackbits.o encode232.o interleave9.o \
|
||||
entail.o fano232.o gran.o sync9.o decode9.o \
|
||||
fil3.o decoder.o grid2n.o n2grid.o timer.o \
|
||||
softsym.o getlags.o afc9.o fchisq.o twkfreq.o downsam9.o \
|
||||
peakdt9.o symspec2.o stdmsg.o morse.o azdist.o geodist.o \
|
||||
fillcom.o chkss2.o zplot9.o flat2.o \
|
||||
jt65a.o symspec65.o flat65.o ccf65.o decode65a.o \
|
||||
filbig.o fil6521.o afc65b.o decode65b.o setup65.o \
|
||||
extract.o fchisq65.o demod64a.o chkhist.o interleave63.o ccf2.o \
|
||||
move.o indexx.o graycode65.o twkfreq65.o smo121.o \
|
||||
wrapkarn.o init_rs.o encode_rs.o decode_rs.o gen65.o
|
||||
|
||||
libjt9.a: $(OBJS1)
|
||||
ar cr libjt9.a $(OBJS1)
|
||||
ranlib libjt9.a
|
||||
|
||||
OBJS2 = jt9.o jt9a.o jt9b.o jt9c.o ipcomm.o sec_midn.o usleep.o
|
||||
LIBS2 = -L'c:/QtSDK/Desktop/Qt/4.7.4/mingw/lib' -lQtCore4
|
||||
jt9.exe: $(OBJS2) libjt9.a
|
||||
$(CXX) -o jt9.exe $(OBJS2) $(LIBS2) libjt9.a ../libfftw3f_win.a \
|
||||
c:/MinGW/lib/libf95.a
|
||||
mkdir -p $(EXE_DIR)
|
||||
cp jt9.exe $(EXE_DIR)
|
||||
|
||||
OBJS3 = jt9sim.o
|
||||
jt9sim.exe: $(OBJS3) libjt9.a
|
||||
$(FC) -o jt9sim.exe $(OBJS3) libjt9.a
|
||||
|
||||
OBJS4 = jt9code.o
|
||||
jt9code.exe: $(OBJS4) libjt9.a
|
||||
$(FC) -o jt9code.exe $(OBJS4) libjt9.a
|
||||
|
||||
OBJS5 = jt65.o
|
||||
jt65.exe: $(OBJS5) libjt9.a
|
||||
$(FC) -o jt65.exe $(OBJS5) libjt9.a ../libfftw3f_win.a
|
||||
|
||||
sync9.o: sync9.f90 jt9sync.f90
|
||||
$(FC) $(FFLAGS) -c sync9.f90
|
||||
|
||||
spec9.o: spec9.f90 jt9sync.f90
|
||||
$(FC) $(FFLAGS) -c spec9.f90
|
||||
|
||||
peakdt9.o: peakdt9.f90 jt9sync.f90
|
||||
$(FC) $(FFLAGS) -c peakdt9.f90
|
||||
|
||||
jt9sim.o: jt9sim.f90 jt9sync.f90
|
||||
$(FC) $(FFLAGS) -c jt9sim.f90
|
||||
|
||||
genjt9.o: genjt9.f90 jt9sync.f90
|
||||
$(FC) $(FFLAGS) -c genjt9.f90
|
||||
|
||||
redsync.o: redsync.f90 jt9sync.f90
|
||||
$(FC) $(FFLAGS) -c redsync.f90
|
||||
|
||||
unpackmsg.o: unpackmsg.f90
|
||||
$(FC) -c -O0 -fbounds-check -Wall -Wno-precision-loss unpackmsg.f90
|
||||
|
||||
ipcomm.o: ipcomm.cpp
|
||||
$(CXX) -c $(INCPATH) ipcomm.cpp
|
||||
|
||||
sec_midn.o: sec_midn.f90
|
||||
$(FC) -c -fno-second-underscore sec_midn.f90
|
||||
|
||||
#rig_control.o: rig_control.c
|
||||
# $(CC) -c -Wall -I..\..\..\hamlib-1.2.15.3\include rig_control.c
|
||||
|
||||
tstrig.o: tstrig.c
|
||||
$(CC) -c -Wall -I..\..\..\hamlib-1.2.15.3\include tstrig.c
|
||||
|
||||
init_rs.o: init_rs.c
|
||||
$(CC) -c -DBIGSYM=1 -o init_rs.o init_rs.c
|
||||
|
||||
encode_rs.o: encode_rs.c
|
||||
$(CC) -c -DBIGSYM=1 -o encode_rs.o encode_rs.c
|
||||
|
||||
decode_rs.o: decode_rs.c
|
||||
$(CC) -c -DBIGSYM=1 -o decode_rs.o decode_rs.c
|
||||
|
||||
|
||||
.PHONY : clean
|
||||
|
||||
clean:
|
||||
rm -f *.o libjt9.a wsjtx.exe jt9sim.exe jt9.exe jt65.exe
|
||||
@@ -1,84 +0,0 @@
|
||||
# Set paths
|
||||
EXE_DIR = ../../wsjtx_exp_install_latest
|
||||
QT_DIR = /usr/include/qt5
|
||||
INCPATH = -I${QT_DIR} -I${QT_DIR}/QtCore
|
||||
|
||||
CC = gcc
|
||||
CXX = g++
|
||||
FC = gfortran
|
||||
AR = ar cr
|
||||
MKDIR = mkdir -p
|
||||
CP = cp
|
||||
RANLIB = ranlib
|
||||
RM = rm -f
|
||||
|
||||
FFLAGS = -I/opt/local/include -O3 -funroll-loops -Wall -Wno-conversion -fno-second-underscore -DUNIX
|
||||
CFLAGS = -I. -fbounds-check -fPIE
|
||||
|
||||
# Default rules
|
||||
%.o: %.c
|
||||
${CC} ${CFLAGS} -c $<
|
||||
%.o: %.f
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.F
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.f90
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.F90
|
||||
${FC} ${FFLAGS} -c $<
|
||||
|
||||
all: libjt9.a jt65 jt65sim t3
|
||||
|
||||
OBJS1 = astrosub.o astro0.o astro.o sun.o coord.o tmoonsub.o \
|
||||
fmtmsg.o deg2grid.o\
|
||||
prog_args.o options.o pctile.o graycode.o sort.o chkmsg.o \
|
||||
igray.o fftw3mod.o packjt.o\
|
||||
four2a.o grid2deg.o wisdom.o \
|
||||
symspec.o analytic.o db.o \
|
||||
encode232.o interleave9.o\
|
||||
entail.o fano232.o gran.o sync9.o \
|
||||
fil3.o decoder.o fqso_first.o \
|
||||
twkfreq.o symspec2.o shell.o sync65.o peakup.o slope.o xcor.o\
|
||||
chkss2.o zplot9.o flat1.o flat2.o \
|
||||
symspec65.o flat65.o ccf65.o decode65a.o \
|
||||
filbig.o fil6521.o afc65b.o decode65b.o setup65.o \
|
||||
extract.o fchisq65.o demod64a.o chkhist.o interleave63.o ccf2.o \
|
||||
move.o indexx.o graycode65.o twkfreq65.o smo.o smo121.o \
|
||||
wrapkarn.o init_rs.o encode_rs.o decode_rs.o gen65.o fil4.o \
|
||||
flat4.o determ.o baddata.o subtract65.o
|
||||
|
||||
libjt9.a: $(OBJS1)
|
||||
$(AR) libjt9.a $(OBJS1)
|
||||
$(RANLIB) libjt9.a
|
||||
|
||||
OBJS7 = jt65.o
|
||||
jt65: $(OBJS7) libjt9.a libsfrsd.a
|
||||
$(FC) -o jt65 $(OBJS7) -L. -L/opt/local/lib -L./sfrsd2 -ljt9 -lsfrsd -lfftw3f_threads -lfftw3f
|
||||
$(CP) jt65 $(EXE_DIR)
|
||||
|
||||
OBJS2 = jt65sim.o wavhdr.o
|
||||
jt65sim: $(OBJS2) libjt9.a
|
||||
$(FC) -o jt65sim $(OBJS2) -L. -L/opt/local/lib -ljt9 -lfftw3f
|
||||
$(CP) jt65sim $(EXE_DIR)
|
||||
|
||||
OBJS3 = t3.o
|
||||
t3: $(OBJS3) libjt9.a
|
||||
$(FC) -o t3 $(OBJS3) -L. -L/opt/local/lib -ljt9
|
||||
|
||||
OBJS6 = jt65code.o
|
||||
jt65code: $(OBJS6) libjt9.a
|
||||
$(FC) -o jt65code $(OBJS6) libjt9.a
|
||||
|
||||
init_rs.o: init_rs.c
|
||||
$(CC) -c -DBIGSYM=1 -o init_rs.o init_rs.c
|
||||
|
||||
encode_rs.o: encode_rs.c
|
||||
$(CC) -c -DBIGSYM=1 -o encode_rs.o encode_rs.c
|
||||
|
||||
decode_rs.o: decode_rs.c
|
||||
$(CC) -c -DBIGSYM=1 -o decode_rs.o decode_rs.c
|
||||
|
||||
.PHONY : clean
|
||||
|
||||
clean:
|
||||
$(RM) *.o libjt9.a jt65
|
||||
@@ -1,76 +0,0 @@
|
||||
# Set paths
|
||||
EXE_DIR = C:/JTSDK/wsjtx_exp/install/Debug/bin
|
||||
QT_DIR = /usr/include/qt5
|
||||
INCPATH = -I${QT_DIR} -I${QT_DIR}/QtCore
|
||||
|
||||
CC = gcc
|
||||
CXX = g++
|
||||
FC = gfortran
|
||||
AR = ar cr
|
||||
MKDIR = mkdir -p
|
||||
CP = cp
|
||||
RANLIB = ranlib
|
||||
RM = rm -f
|
||||
|
||||
FFLAGS = -O2 -Wall -Wno-conversion -fno-second-underscore
|
||||
CFLAGS = -I. -fbounds-check -fPIE -DBIGSYM
|
||||
|
||||
# Default rules
|
||||
%.o: %.c
|
||||
${CC} ${CFLAGS} -c $<
|
||||
%.o: %.f
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.F
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.f90
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.F90
|
||||
${FC} ${FFLAGS} -c $<
|
||||
|
||||
all: libjt9.a jt65 jt65sim
|
||||
|
||||
OBJS1 = astrosub.o astro0.o astro.o sun.o coord.o tmoonsub.o \
|
||||
fmtmsg.o deg2grid.o\
|
||||
prog_args.o options.o pctile.o graycode.o sort.o chkmsg.o \
|
||||
igray.o fftw3mod.o packjt.o\
|
||||
four2a.o grid2deg.o wisdom.o \
|
||||
symspec.o analytic.o db.o \
|
||||
encode232.o interleave9.o \
|
||||
entail.o fano232.o gran.o sync9.o decjt9.o \
|
||||
fil3.o decoder.o timer.o exp_decode65.o fqso_first.o \
|
||||
twkfreq.o symspec2.o shell.o sync65.o peakup.o slope.o xcor.o\
|
||||
fillcom.o chkss2.o zplot9.o flat1.o flat2.o \
|
||||
jt65a.o symspec65.o flat65.o ccf65.o decode65a.o \
|
||||
filbig.o fil6521.o afc65b.o decode65b.o setup65.o \
|
||||
extract.o fchisq65.o demod64a.o chkhist.o interleave63.o ccf2.o \
|
||||
move.o indexx.o graycode65.o twkfreq65.o smo.o smo121.o \
|
||||
wrapkarn.o init_rs.o encode_rs.o decode_rs.o gen65.o fil4.o \
|
||||
flat4.o determ.o baddata.o subtract65.o
|
||||
|
||||
libjt9.a: $(OBJS1)
|
||||
$(AR) libjt9.a $(OBJS1)
|
||||
$(RANLIB) libjt9.a
|
||||
|
||||
OBJS7 = jt65.o
|
||||
jt65: $(OBJS7) libjt9.a libsfrsd.a
|
||||
$(FC) -o jt65 $(OBJS7) -L. -L./sfrsd2 -ljt9 -lsfrsd \
|
||||
C:\JTSDK\fftw3f\libfftw3f-3.dll
|
||||
|
||||
OBJS2 = jt65sim.o wavhdr.o
|
||||
jt65sim: $(OBJS2) libjt9.a
|
||||
$(FC) -o jt65sim $(OBJS2) -L. -ljt9 C:\JTSDK\fftw3f\libfftw3f-3.dll
|
||||
$(CP) jt65sim.exe $(EXE_DIR)
|
||||
|
||||
init_rs.o: init_rs.c
|
||||
$(CC) -c -DBIGSYM=1 -o init_rs.o init_rs.c
|
||||
|
||||
encode_rs.o: encode_rs.c
|
||||
$(CC) -c -DBIGSYM=1 -o encode_rs.o encode_rs.c
|
||||
|
||||
decode_rs.o: decode_rs.c
|
||||
$(CC) -c -DBIGSYM=1 -o decode_rs.o decode_rs.c
|
||||
|
||||
.PHONY : clean
|
||||
|
||||
clean:
|
||||
$(RM) *.o libjt9.a jt65
|
||||
@@ -1,74 +0,0 @@
|
||||
# Set paths
|
||||
EXE_DIR = ../../wsjtx_install
|
||||
|
||||
CC = clang
|
||||
CXX = g++
|
||||
FC = gfortran
|
||||
AR = ar cr
|
||||
MKDIR = mkdir -p
|
||||
CP = cp
|
||||
RANLIB = ranlib
|
||||
RM = rm -f
|
||||
|
||||
FFLAGS = -I/opt/local/include -Wall -Wno-conversion -fno-second-underscore -DUNIX
|
||||
CFLAGS = -I. -fbounds-check -fPIE
|
||||
|
||||
# Default rules
|
||||
%.o: %.c
|
||||
${CC} ${CFLAGS} -c $<
|
||||
%.o: %.f
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.F
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.f90
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.F90
|
||||
${FC} ${FFLAGS} -c $<
|
||||
|
||||
all: libjt9.a jt65 jt65sim
|
||||
|
||||
OBJS1 = astrosub.o astro0.o astro.o sun.o coord.o tmoonsub.o \
|
||||
fmtmsg.o deg2grid.o\
|
||||
prog_args.o options.o pctile.o graycode.o sort.o chkmsg.o \
|
||||
igray.o fftw3mod.o packjt.o\
|
||||
four2a.o grid2deg.o wisdom.o \
|
||||
symspec.o analytic.o db.o \
|
||||
encode232.o interleave9.o\
|
||||
entail.o fano232.o sgran.o gran.o sync9.o decjt9.o \
|
||||
fil3.o decoder.o timer.o exp_decode65.o fqso_first.o\
|
||||
twkfreq.o symspec2.o shell.o sync65.o peakup.o slope.o xcor.o\
|
||||
fillcom.o chkss2.o zplot9.o flat1.o flat2.o \
|
||||
jt65a.o symspec65.o flat65.o ccf65.o decode65a.o \
|
||||
filbig.o fil6521.o afc65b.o decode65b.o setup65.o \
|
||||
extract.o fchisq65.o demod64a.o chkhist.o interleave63.o ccf2.o \
|
||||
move.o indexx.o graycode65.o twkfreq65.o smo.o smo121.o \
|
||||
wrapkarn.o init_rs.o encode_rs.o decode_rs.o gen65.o fil4.o \
|
||||
flat4.o determ.o baddata.o subtract65.o
|
||||
|
||||
libjt9.a: $(OBJS1)
|
||||
$(AR) libjt9.a $(OBJS1)
|
||||
$(RANLIB) libjt9.a
|
||||
|
||||
OBJS7 = jt65.o
|
||||
jt65: $(OBJS7) libjt9.a libftrsd.a
|
||||
$(FC) -o jt65 $(OBJS7) -L. -L/opt/local/lib -L./ftrsd -ljt9 -lftrsd -lfftw3f_threads -lfftw3f
|
||||
$(CP) jt65 $(EXE_DIR)
|
||||
|
||||
OBJS2 = jt65sim.o wavhdr.o
|
||||
jt65sim: $(OBJS2) libjt9.a
|
||||
$(FC) -o jt65sim $(OBJS2) -L. -L/opt/local/lib -ljt9 -lfftw3f
|
||||
$(CP) jt65sim $(EXE_DIR)
|
||||
|
||||
init_rs.o: init_rs.c
|
||||
$(CC) -c -DBIGSYM=1 -o init_rs.o init_rs.c
|
||||
|
||||
encode_rs.o: encode_rs.c
|
||||
$(CC) -c -DBIGSYM=1 -o encode_rs.o encode_rs.c
|
||||
|
||||
decode_rs.o: decode_rs.c
|
||||
$(CC) -c -DBIGSYM=1 -o decode_rs.o decode_rs.c
|
||||
|
||||
.PHONY : clean
|
||||
|
||||
clean:
|
||||
$(RM) *.o libjt9.a jt65
|
||||
@@ -1,58 +0,0 @@
|
||||
|
||||
# Set paths
|
||||
EXE_DIR = ..\\..\\wsjtx_install
|
||||
QT_DIR = C:/wsjt-env/Qt5/5.2.1/mingw48_32
|
||||
FFTW3_DIR = ..
|
||||
|
||||
INCPATH = -I${QT_DIR}/include/QtCore -I${QT_DIR}/include
|
||||
|
||||
# Compilers
|
||||
CC = gcc
|
||||
CXX = g++
|
||||
FC = gfortran
|
||||
AR = ar cr
|
||||
RANLIB = ranlib
|
||||
MKDIR = mkdir -p
|
||||
CP = cp
|
||||
RM = rm -f
|
||||
|
||||
FFLAGS = -O2 -fbounds-check -Wall -Wno-conversion
|
||||
CFLAGS = -O2 -I.
|
||||
|
||||
# Default rules
|
||||
%.o: %.c
|
||||
${CC} ${CFLAGS} -c $<
|
||||
%.o: %.f
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.F
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.f90
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.F90
|
||||
${FC} ${FFLAGS} -c $<
|
||||
|
||||
all: jt9w
|
||||
|
||||
OBJS1 = jt9w.o smo.o sync9w.o pctile.o shell.o lorentzian.o fchisq0.o \
|
||||
softsym9w.o four2a.o interleave9.o jt9fano.o fano232.o packjt.o \
|
||||
deg2grid.o grid2deg.o fmtmsg.o db.o decode9w.o
|
||||
|
||||
jt9w: $(OBJS1)
|
||||
$(FC) -o jt9w $(OBJS1) -lfftw3f
|
||||
|
||||
OBJS2 = t1.o four2a.o db.o
|
||||
t1: $(OBJS2)
|
||||
$(FC) -o t1 $(OBJS2) -lfftw3f
|
||||
|
||||
OBJS3 = t2.o four2a.o db.o
|
||||
t2: $(OBJS3)
|
||||
$(FC) -o t2 $(OBJS3) -lfftw3f
|
||||
|
||||
OBJS4 = t3.o four2a.o db.o
|
||||
t3: $(OBJS4)
|
||||
$(FC) -o t3 $(OBJS4) -lfftw3f
|
||||
|
||||
.PHONY : clean
|
||||
|
||||
clean:
|
||||
$(RM) *.o JTMSKcode JTMSKcode.exe
|
||||
@@ -1,58 +0,0 @@
|
||||
|
||||
# Set paths
|
||||
EXE_DIR = ..\\..\\wsjtx_install
|
||||
QT_DIR = C:/wsjt-env/Qt5/5.2.1/mingw48_32
|
||||
FFTW3_DIR = ..
|
||||
|
||||
INCPATH = -I${QT_DIR}/include/QtCore -I${QT_DIR}/include
|
||||
|
||||
# Compilers
|
||||
CC = gcc
|
||||
CXX = g++
|
||||
FC = gfortran
|
||||
AR = ar cr
|
||||
RANLIB = ranlib
|
||||
MKDIR = mkdir -p
|
||||
CP = cp
|
||||
RM = rm -f
|
||||
|
||||
FFLAGS = -O2 -fbounds-check -Wall -Wno-conversion
|
||||
CFLAGS = -O2 -I.
|
||||
|
||||
# Default rules
|
||||
%.o: %.c
|
||||
${CC} ${CFLAGS} -c $<
|
||||
%.o: %.f
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.F
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.f90
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.F90
|
||||
${FC} ${FFLAGS} -c $<
|
||||
|
||||
all: jt9w
|
||||
|
||||
OBJS1 = jt9w.o smo.o sync9w.o pctile.o shell.o lorentzian.o fchisq0.o \
|
||||
softsym9w.o four2a.o interleave9.o jt9fano.o fano232.o packjt.o \
|
||||
deg2grid.o grid2deg.o fmtmsg.o db.o decode9w.o
|
||||
|
||||
jt9w: $(OBJS1)
|
||||
$(FC) -o jt9w $(OBJS1) -lfftw3f
|
||||
|
||||
OBJS2 = t1.o four2a.o db.o
|
||||
t1: $(OBJS2)
|
||||
$(FC) -o t1 $(OBJS2) -lfftw3f
|
||||
|
||||
OBJS3 = t2.o four2a.o db.o
|
||||
t2: $(OBJS3)
|
||||
$(FC) -o t2 $(OBJS3) -lfftw3f
|
||||
|
||||
OBJS4 = t3.o
|
||||
t3: $(OBJS4)
|
||||
$(FC) -o t3 $(OBJS4) -L. -ljt9 C:\JTSDK\fftw3f\libfftw3f-3.dll
|
||||
|
||||
.PHONY : clean
|
||||
|
||||
clean:
|
||||
$(RM) *.o JTMSKcode JTMSKcode.exe
|
||||
@@ -1,137 +0,0 @@
|
||||
# Makefile for MinGW on Windows
|
||||
# Windows re-direct:
|
||||
# C> make > junk1 2>&1
|
||||
|
||||
# Set paths
|
||||
EXE_DIR = ../../wsjtx_install
|
||||
|
||||
INCPATH = -I'C:/JTSDK/Qt5/5.2.1/mingw48_32/include/QtCore' \
|
||||
-I'C:/JTSDK/Qt5/5.2.1/mingw48_32/include/'
|
||||
|
||||
# Compilers
|
||||
CC = c:/JTSDK/Qt5/Tools/mingw48_32/bin/gcc
|
||||
FC = c:/JTSDK/Qt5/Tools/mingw48_32/bin/gfortran
|
||||
CXX = c:/JTSDK/Qt5/Tools/mingw48_32/bin/g++
|
||||
|
||||
FFLAGS = -O3 -Wall -Wno-conversion -fno-second-underscore -DWIN32
|
||||
CFLAGS = -I. -DWIN32
|
||||
|
||||
# Default rules
|
||||
%.o: %.c
|
||||
${CC} ${CFLAGS} -c $<
|
||||
%.o: %.f
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.F
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.f90
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.F90
|
||||
${FC} ${FFLAGS} -c $<
|
||||
|
||||
all: libjt9.a libastro.a jt9.exe jt9code.exe jt65code.exe jt9sim.exe
|
||||
|
||||
OBJS1 = pctile.o graycode.o sort.o chkmsg.o \
|
||||
unpackmsg.o igray.o unpackcall.o unpackgrid.o \
|
||||
grid2k.o unpacktext.o getpfx2.o packmsg.o deg2grid.o \
|
||||
packtext.o getpfx1.o packcall.o k2grid.o packgrid.o \
|
||||
nchar.o four2a.o grid2deg.o pfxdump.o wisdom.o \
|
||||
symspec.o analytic.o db.o genjt9.o flat1.o smo.o \
|
||||
packbits.o unpackbits.o encode232.o interleave9.o \
|
||||
entail.o fano232.o gran.o sync9.o jt9fano.o \
|
||||
fil3.o decoder.o grid2n.o n2grid.o timer.o \
|
||||
softsym.o getlags.o afc9.o fchisq.o twkfreq.o downsam9.o \
|
||||
peakdt9.o symspec2.o stdmsg.o morse.o azdist.o geodist.o \
|
||||
fillcom.o chkss2.o zplot9.o flat2.o \
|
||||
jt65a.o symspec65.o flat65.o ccf65.o decode65a.o \
|
||||
filbig.o fil6521.o afc65b.o decode65b.o setup65.o \
|
||||
extract.o fchisq65.o demod64a.o chkhist.o interleave63.o ccf2.o \
|
||||
move.o indexx.o graycode65.o twkfreq65.o smo121.o \
|
||||
wrapkarn.o init_rs.o encode_rs.o decode_rs.o gen65.o fil4.o \
|
||||
flat4.o polfit.o determ.o baddata.o prog_args.o \
|
||||
options.o fmtmsg.o decjt9.o
|
||||
|
||||
libjt9.a: $(OBJS1)
|
||||
ar cr libjt9.a $(OBJS1)
|
||||
ranlib libjt9.a
|
||||
|
||||
OBJS2 = jt9.o jt9a.o jt9b.o jt9c.o ipcomm.o sec_midn.o usleep.o
|
||||
LIBS2 = -L'C:/JTSDK/Qt5/5.2.1/mingw48_32/lib' -lQt5Core
|
||||
jt9.exe: $(OBJS2) libjt9.a
|
||||
$(CXX) -o jt9.exe -static $(OBJS2) $(LIBS2) libjt9.a \
|
||||
C:\JTSDK\fftw3f\libfftw3f-3.dll -lgfortran
|
||||
# mkdir -p $(EXE_DIR)
|
||||
cp jt9.exe $(EXE_DIR)
|
||||
|
||||
OBJS3 = jt9sim.o
|
||||
jt9sim.exe: $(OBJS3) libjt9.a
|
||||
$(FC) -o jt9sim.exe $(OBJS3) libjt9.a
|
||||
|
||||
OBJS4 = jt9code.o
|
||||
jt9code.exe: $(OBJS4) libjt9.a
|
||||
$(FC) -o jt9code.exe $(OBJS4) libjt9.a
|
||||
cp jt9code.exe $(EXE_DIR)
|
||||
|
||||
OBJS5 = jt65.o
|
||||
jt65.exe: $(OBJS5) libjt9.a
|
||||
$(FC) -o jt65.exe $(OBJS5) libjt9.a ../libfftw3f_win.a
|
||||
|
||||
OBJS7 = astrosub.o astro0.o astro.o tm2.o grid2deg.o sun.o moondop.o \
|
||||
coord.o dot.o moon2.o tmoonsub.o toxyz.o geocentric.o \
|
||||
dcoord.o
|
||||
|
||||
libastro.a: $(OBJS7)
|
||||
ar cr libastro.a $(OBJS7)
|
||||
ranlib libastro.a
|
||||
|
||||
OBJS6 = jt65code.o
|
||||
jt65code.exe: $(OBJS6) libjt9.a
|
||||
$(FC) -o jt65code.exe $(OBJS6) libjt9.a
|
||||
cp jt65code.exe $(EXE_DIR)
|
||||
|
||||
sync9.o: sync9.f90 jt9sync.f90
|
||||
$(FC) $(FFLAGS) -c sync9.f90
|
||||
|
||||
spec9.o: spec9.f90 jt9sync.f90
|
||||
$(FC) $(FFLAGS) -c spec9.f90
|
||||
|
||||
peakdt9.o: peakdt9.f90 jt9sync.f90
|
||||
$(FC) $(FFLAGS) -c peakdt9.f90
|
||||
|
||||
jt9sim.o: jt9sim.f90 jt9sync.f90
|
||||
$(FC) $(FFLAGS) -c jt9sim.f90
|
||||
|
||||
genjt9.o: genjt9.f90 jt9sync.f90
|
||||
$(FC) $(FFLAGS) -c genjt9.f90
|
||||
|
||||
redsync.o: redsync.f90 jt9sync.f90
|
||||
$(FC) $(FFLAGS) -c redsync.f90
|
||||
|
||||
unpackmsg.o: unpackmsg.f90
|
||||
$(FC) -c -O0 -fbounds-check -Wall -Wno-precision-loss unpackmsg.f90
|
||||
|
||||
ipcomm.o: ipcomm.cpp
|
||||
$(CXX) -c $(INCPATH) ipcomm.cpp
|
||||
|
||||
sec_midn.o: sec_midn.f90
|
||||
$(FC) -c -fno-second-underscore sec_midn.f90
|
||||
|
||||
#rig_control.o: rig_control.c
|
||||
# $(CC) -c -Wall -I..\..\..\hamlib-1.2.15.3\include rig_control.c
|
||||
|
||||
tstrig.o: tstrig.c
|
||||
$(CC) -c -Wall -I..\..\..\hamlib-1.2.15.3\include tstrig.c
|
||||
|
||||
init_rs.o: init_rs.c
|
||||
$(CC) -c -DBIGSYM=1 -o init_rs.o init_rs.c
|
||||
|
||||
encode_rs.o: encode_rs.c
|
||||
$(CC) -c -DBIGSYM=1 -o encode_rs.o encode_rs.c
|
||||
|
||||
decode_rs.o: decode_rs.c
|
||||
$(CC) -c -DBIGSYM=1 -o decode_rs.o decode_rs.c
|
||||
|
||||
|
||||
.PHONY : clean
|
||||
|
||||
clean:
|
||||
rm -f *.o libjt9.a wsjtx.exe jt9sim.exe jt9.exe jt65.exe
|
||||
@@ -1,115 +0,0 @@
|
||||
# Set paths
|
||||
EXE_DIR = ../../wsjtx_install
|
||||
QT_DIR = /usr/include/qt5
|
||||
INCPATH = -I${QT_DIR} -I${QT_DIR}/QtCore
|
||||
|
||||
CC = gcc
|
||||
CXX = g++
|
||||
FC = gfortran
|
||||
AR = ar cr
|
||||
MKDIR = mkdir -p
|
||||
CP = cp
|
||||
RANLIB = ranlib
|
||||
RM = rm -f
|
||||
|
||||
FFLAGS = -O3 -funroll-loops -Wall -Wno-conversion -fno-second-underscore -DUNIX
|
||||
CFLAGS = -I. -fbounds-check -fPIE
|
||||
|
||||
# Default rules
|
||||
%.o: %.c
|
||||
${CC} ${CFLAGS} -c $<
|
||||
%.o: %.f
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.F
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.f90
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.F90
|
||||
${FC} ${FFLAGS} -c $<
|
||||
|
||||
all: libjt9.a jt9sim jt9 jt9code jt65code
|
||||
|
||||
OBJS1 = astrosub.o astro0.o astro.o tm2.o sun.o moondop.o coord.o tmoonsub.o \
|
||||
fmtmsg.o geocentric.o moon2.o toxyz.o dot.o dcoord.o \
|
||||
prog_args.o options.o pctile.o graycode.o sort.o chkmsg.o \
|
||||
unpackmsg.o igray.o unpackcall.o unpackgrid.o \
|
||||
grid2k.o unpacktext.o getpfx2.o packmsg.o deg2grid.o \
|
||||
packtext.o getpfx1.o packcall.o k2grid.o packgrid.o \
|
||||
nchar.o four2a.o grid2deg.o pfxdump.o wisdom.o \
|
||||
symspec.o analytic.o db.o genjt9.o jt9fano.o \
|
||||
packbits.o unpackbits.o encode232.o interleave9.o \
|
||||
entail.o fano232.o gran.o sync9.o decjt9.o \
|
||||
fil3.o decoder.o grid2n.o n2grid.o timer.o \
|
||||
softsym.o peakdt9.o getlags.o afc9.o fchisq.o \
|
||||
twkfreq.o downsam9.o symspec2.o ipcomm.o sleep_msec.o \
|
||||
stdmsg.o sec_midn.o usleep.o azdist.o geodist.o morse.o \
|
||||
fillcom.o chkss2.o zplot9.o flat1.o flat2.o \
|
||||
jt65a.o symspec65.o flat65.o ccf65.o decode65a.o \
|
||||
filbig.o fil6521.o afc65b.o decode65b.o setup65.o \
|
||||
extract.o fchisq65.o demod64a.o chkhist.o interleave63.o ccf2.o \
|
||||
move.o indexx.o graycode65.o twkfreq65.o smo.o smo121.o \
|
||||
wrapkarn.o init_rs.o encode_rs.o decode_rs.o gen65.o fil4.o \
|
||||
flat4.o polfit.o determ.o baddata.o
|
||||
|
||||
libjt9.a: $(OBJS1)
|
||||
$(AR) libjt9.a $(OBJS1)
|
||||
$(RANLIB) libjt9.a
|
||||
|
||||
OBJS2 = jt9.o jt9a.o jt9b.o jt9c.o
|
||||
|
||||
jt9: $(OBJS2) libjt9.a
|
||||
$(CXX) -o jt9 $(OBJS2) -L. -ljt9 -lQt5Core -lfftw3f_threads -lfftw3f `$(FC) -print-file-name=libgfortran.so`
|
||||
$(MKDIR) -p $(EXE_DIR)
|
||||
$(CP) jt9 $(EXE_DIR)
|
||||
|
||||
OBJS3 = jt9sim.o
|
||||
jt9sim: $(OBJS3) libjt9.a
|
||||
$(FC) -o jt9sim $(OBJS3) -L. -ljt9
|
||||
|
||||
OBJS4 = jt9code.o
|
||||
jt9code: $(OBJS4) libjt9.a
|
||||
$(FC) -o jt9code $(OBJS4) -L. -ljt9
|
||||
$(CP) jt9code $(EXE_DIR)
|
||||
|
||||
OBJS6 = jt65code.o
|
||||
jt65code: $(OBJS6) libjt9.a
|
||||
$(FC) -o jt65code $(OBJS6) libjt9.a
|
||||
$(CP) jt65code $(EXE_DIR)
|
||||
|
||||
sync9.o: sync9.f90 jt9sync.f90
|
||||
$(FC) $(FFLAGS) -c sync9.f90
|
||||
|
||||
peakdf9.o: peakdf9.f90 jt9sync.f90
|
||||
$(FC) $(FFLAGS) -c peakdf9.f90
|
||||
|
||||
peakdt9.o: peakdt9.f90 jt9sync.f90
|
||||
$(FC) $(FFLAGS) -c peakdt9.f90
|
||||
|
||||
jt9sim.o: jt9sim.f90 jt9sync.f90
|
||||
$(FC) $(FFLAGS) -c jt9sim.f90
|
||||
|
||||
genjt9.o: genjt9.f90 jt9sync.f90
|
||||
$(FC) $(FFLAGS) -c genjt9.f90
|
||||
|
||||
redsync.o: redsync.f90 jt9sync.f90
|
||||
$(FC) $(FFLAGS) -c redsync.f90
|
||||
|
||||
ipcomm.o: ipcomm.cpp
|
||||
$(CXX) -c $(INCPATH) -fPIE ipcomm.cpp
|
||||
|
||||
sec_midn.o: sec_midn.f90
|
||||
$(FC) -c -fno-second-underscore sec_midn.f90
|
||||
|
||||
init_rs.o: init_rs.c
|
||||
$(CC) -c -DBIGSYM=1 -o init_rs.o init_rs.c
|
||||
|
||||
encode_rs.o: encode_rs.c
|
||||
$(CC) -c -DBIGSYM=1 -o encode_rs.o encode_rs.c
|
||||
|
||||
decode_rs.o: decode_rs.c
|
||||
$(CC) -c -DBIGSYM=1 -o decode_rs.o decode_rs.c
|
||||
|
||||
.PHONY : clean
|
||||
|
||||
clean:
|
||||
$(RM) *.o libjt9.a wsjtx jt9sim jt9 jt9code
|
||||
@@ -1,71 +0,0 @@
|
||||
|
||||
# Set paths
|
||||
EXE_DIR = ..\\..\\wsjtx_install
|
||||
QT_DIR = C:/wsjt-env/Qt5/5.2.1/mingw48_32
|
||||
FFTW3_DIR = ..
|
||||
|
||||
INCPATH = -I${QT_DIR}/include/QtCore -I${QT_DIR}/include
|
||||
|
||||
# Compilers
|
||||
CC = gcc
|
||||
CXX = g++
|
||||
FC = gfortran
|
||||
AR = ar cr
|
||||
RANLIB = ranlib
|
||||
MKDIR = mkdir -p
|
||||
CP = cp
|
||||
RM = rm -f
|
||||
|
||||
FFLAGS = -O2 -fbounds-check -Wall -Wno-conversion
|
||||
CFLAGS = -O2 -I.
|
||||
|
||||
# Default rules
|
||||
%.o: %.c
|
||||
${CC} ${CFLAGS} -c $<
|
||||
%.o: %.f
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.F
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.f90
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.F90
|
||||
${FC} ${FFLAGS} -c $<
|
||||
|
||||
#all: jt9code JTMSKcode
|
||||
all: jtmsk JTMSKcode
|
||||
|
||||
OBJS4 = jt9code.o packjt.o fmtmsg.o gen9.o deg2grid.o grid2deg.o \
|
||||
entail.o encode232.o interleave9.o graycode.o igray.o
|
||||
jt9code: $(OBJS4)
|
||||
$(FC) -o jt9code $(OBJS4)
|
||||
|
||||
OBJS5 = JTMSKcode.o packjt.o fmtmsg.o genmsk.o deg2grid.o grid2deg.o \
|
||||
entail.o nhash.o tab.o vit213.o
|
||||
JTMSKcode: $(OBJS5)
|
||||
$(FC) -o JTMSKcode $(OBJS5)
|
||||
|
||||
OBJS6 = jtmsk.o jtmsk.o analytic.o four2a.o db.o mskdf.o pctile.o \
|
||||
sort.o tweak1.o syncmsk.o genmsk.o packjt.o fmtmsg.o indexx.o \
|
||||
deg2grid.o grid2deg.o entail.o nhash.o tab.o vit213.o
|
||||
jtmsk: $(OBJS6)
|
||||
$(FC) -o jtmsk $(OBJS6) -lfftw3f
|
||||
|
||||
OBJS1 = t1.o four2a.o db.o
|
||||
t1: $(OBJS1)
|
||||
$(FC) -o t1 $(OBJS1) -lfftw3f
|
||||
|
||||
OBJS2 = t2.o four2a.o db.o
|
||||
t2: $(OBJS2)
|
||||
$(FC) -o t2 $(OBJS2) -lfftw3f
|
||||
|
||||
OBJS6 = t6.o four2a.o db.o
|
||||
t6: $(OBJS6)
|
||||
$(FC) -o t6 $(OBJS6) -lfftw3f
|
||||
|
||||
nhash.o: wsprd/nhash.h wsprd/nhash.c
|
||||
$(CC) -c -O2 wsprd/nhash.c
|
||||
|
||||
.PHONY : clean
|
||||
|
||||
clean:
|
||||
$(RM) *.o JTMSKcode JTMSKcode.exe
|
||||
@@ -1,75 +0,0 @@
|
||||
|
||||
# Set paths
|
||||
EXE_DIR = ..\\..\\wsjtx_install
|
||||
QT_DIR = C:/wsjt-env/Qt5/5.2.1/mingw48_32
|
||||
FFTW3_DIR = ..
|
||||
|
||||
INCPATH = -I${QT_DIR}/include/QtCore -I${QT_DIR}/include
|
||||
|
||||
# Compilers
|
||||
CC = gcc
|
||||
CXX = g++
|
||||
FC = gfortran
|
||||
AR = ar cr
|
||||
RANLIB = ranlib
|
||||
MKDIR = mkdir -p
|
||||
CP = cp
|
||||
RM = rm -f
|
||||
|
||||
FFLAGS = -O2 -fbounds-check -Wall -Wno-conversion
|
||||
CFLAGS = -O2 -I.
|
||||
|
||||
# Default rules
|
||||
%.o: %.c
|
||||
${CC} ${CFLAGS} -c $<
|
||||
%.o: %.f
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.F
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.f90
|
||||
${FC} ${FFLAGS} -c $<
|
||||
%.o: %.F90
|
||||
${FC} ${FFLAGS} -c $<
|
||||
|
||||
#all: jt9code JTMSKcode.exe
|
||||
all: jtmsk.exe JTMSKsim.exe JTMSKcode.exe fixwav.exe
|
||||
|
||||
OBJS3 = JTMSKsim.o wavhdr.o gran.o four2a.o db.o
|
||||
JTMSKsim.exe: $(OBJS3)
|
||||
$(FC) -o JTMSKsim.exe $(OBJS3) C:\JTSDK\fftw3f\libfftw3f-3.dll
|
||||
|
||||
OBJS4 = jt9code.o packjt.o fmtmsg.o gen9.o deg2grid.o grid2deg.o \
|
||||
entail.o encode232.o interleave9.o graycode.o igray.o
|
||||
jt9code: $(OBJS4)
|
||||
$(FC) -o jt9code $(OBJS4)
|
||||
|
||||
OBJS5 = JTMSKcode.o packjt.o fmtmsg.o genmsk.o deg2grid.o grid2deg.o \
|
||||
entail.o tab.o vit213.o hashing.o nhash.o
|
||||
JTMSKcode.exe: $(OBJS5)
|
||||
$(FC) -o JTMSKcode.exe $(OBJS5)
|
||||
|
||||
OBJS6 = jtmsk.o analytic.o four2a.o db.o pctile.o \
|
||||
shell.o tweak1.o syncmsk.o genmsk.o packjt.o fmtmsg.o indexx.o \
|
||||
deg2grid.o grid2deg.o entail.o hashing.o nhash.o tab.o vit213.o \
|
||||
mskdt.o rectify_msk.o timer.o jtmsk_decode.o genmsk_short.o \
|
||||
jtmsk_short.o golay24_table.o hash.o
|
||||
|
||||
jtmsk.exe: $(OBJS6)
|
||||
$(FC) -o jtmsk.exe $(OBJS6) C:\JTSDK\fftw3f\libfftw3f-3.dll
|
||||
|
||||
OBJS1 = fixwav.o wavhdr.o
|
||||
fixwav.exe: $(OBJS1)
|
||||
$(FC) -o fixwav.exe $(OBJS1)
|
||||
|
||||
OBJS2 = t2.o four2a.o db.o
|
||||
t2: $(OBJS2)
|
||||
$(FC) -o t2 $(OBJS2) C:\JTSDK\fftw3f\libfftw3f-3.dll
|
||||
|
||||
OBJS6 = t6.o four2a.o db.o
|
||||
t6: $(OBJS6)
|
||||
$(FC) -o t6 $(OBJS6) C:\JTSDK\fftw3f\libfftw3f-3.dll
|
||||
|
||||
.PHONY : clean
|
||||
|
||||
clean:
|
||||
$(RM) *.o JTMSKcode JTMSKcode.exe
|
||||