Merged master 8748
This commit is contained in:
@@ -1,444 +0,0 @@
|
||||
#include "MessageServer.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include <QUdpSocket>
|
||||
#include <QString>
|
||||
#include <QTimer>
|
||||
#include <QHash>
|
||||
|
||||
#include "Radio.hpp"
|
||||
#include "NetworkMessage.hpp"
|
||||
#include "qt_helpers.hpp"
|
||||
|
||||
#include "pimpl_impl.hpp"
|
||||
|
||||
#include "moc_MessageServer.cpp"
|
||||
|
||||
class MessageServer::impl
|
||||
: public QUdpSocket
|
||||
{
|
||||
Q_OBJECT;
|
||||
|
||||
public:
|
||||
impl (MessageServer * self, QString const& version, QString const& revision)
|
||||
: self_ {self}
|
||||
, version_ {version}
|
||||
, revision_ {revision}
|
||||
, port_ {0u}
|
||||
, clock_ {new QTimer {this}}
|
||||
{
|
||||
// register the required types with Qt
|
||||
Radio::register_types ();
|
||||
|
||||
connect (this, &QIODevice::readyRead, this, &MessageServer::impl::pending_datagrams);
|
||||
connect (this, static_cast<void (impl::*) (SocketError)> (&impl::error)
|
||||
, [this] (SocketError /* e */)
|
||||
{
|
||||
Q_EMIT self_->error (errorString ());
|
||||
});
|
||||
connect (clock_, &QTimer::timeout, this, &impl::tick);
|
||||
clock_->start (NetworkMessage::pulse * 1000);
|
||||
}
|
||||
|
||||
enum StreamStatus {Fail, Short, OK};
|
||||
|
||||
void leave_multicast_group ();
|
||||
void join_multicast_group ();
|
||||
void parse_message (QHostAddress const& sender, port_type sender_port, QByteArray const& msg);
|
||||
void tick ();
|
||||
void pending_datagrams ();
|
||||
StreamStatus check_status (QDataStream const&) const;
|
||||
void send_message (QDataStream const& out, QByteArray const& message, QHostAddress const& address, port_type port)
|
||||
{
|
||||
if (OK == check_status (out))
|
||||
{
|
||||
writeDatagram (message, address, port);
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_EMIT self_->error ("Error creating UDP message");
|
||||
}
|
||||
}
|
||||
|
||||
MessageServer * self_;
|
||||
QString version_;
|
||||
QString revision_;
|
||||
port_type port_;
|
||||
QHostAddress multicast_group_address_;
|
||||
static BindMode constexpr bind_mode_ = ShareAddress | ReuseAddressHint;
|
||||
struct Client
|
||||
{
|
||||
Client () = default;
|
||||
Client (QHostAddress const& sender_address, port_type const& sender_port)
|
||||
: sender_address_ {sender_address}
|
||||
, sender_port_ {sender_port}
|
||||
, negotiated_schema_number_ {2} // not 1 because it's broken
|
||||
, last_activity_ {QDateTime::currentDateTime ()}
|
||||
{
|
||||
}
|
||||
Client (Client const&) = default;
|
||||
Client& operator= (Client const&) = default;
|
||||
|
||||
QHostAddress sender_address_;
|
||||
port_type sender_port_;
|
||||
quint32 negotiated_schema_number_;
|
||||
QDateTime last_activity_;
|
||||
};
|
||||
QHash<QString, Client> clients_; // maps id to Client
|
||||
QTimer * clock_;
|
||||
};
|
||||
|
||||
MessageServer::impl::BindMode constexpr MessageServer::impl::bind_mode_;
|
||||
|
||||
#include "MessageServer.moc"
|
||||
|
||||
void MessageServer::impl::leave_multicast_group ()
|
||||
{
|
||||
if (!multicast_group_address_.isNull () && BoundState == state ())
|
||||
{
|
||||
leaveMulticastGroup (multicast_group_address_);
|
||||
}
|
||||
}
|
||||
|
||||
void MessageServer::impl::join_multicast_group ()
|
||||
{
|
||||
if (BoundState == state ()
|
||||
&& !multicast_group_address_.isNull ())
|
||||
{
|
||||
if (IPv4Protocol == multicast_group_address_.protocol ()
|
||||
&& IPv4Protocol != localAddress ().protocol ())
|
||||
{
|
||||
close ();
|
||||
bind (QHostAddress::AnyIPv4, port_, bind_mode_);
|
||||
}
|
||||
if (!joinMulticastGroup (multicast_group_address_))
|
||||
{
|
||||
multicast_group_address_.clear ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MessageServer::impl::pending_datagrams ()
|
||||
{
|
||||
while (hasPendingDatagrams ())
|
||||
{
|
||||
QByteArray datagram;
|
||||
datagram.resize (pendingDatagramSize ());
|
||||
QHostAddress sender_address;
|
||||
port_type sender_port;
|
||||
if (0 <= readDatagram (datagram.data (), datagram.size (), &sender_address, &sender_port))
|
||||
{
|
||||
parse_message (sender_address, sender_port, datagram);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MessageServer::impl::parse_message (QHostAddress const& sender, port_type sender_port, QByteArray const& msg)
|
||||
{
|
||||
try
|
||||
{
|
||||
//
|
||||
// message format is described in NetworkMessage.hpp
|
||||
//
|
||||
NetworkMessage::Reader in {msg};
|
||||
|
||||
auto id = in.id ();
|
||||
if (OK == check_status (in))
|
||||
{
|
||||
if (!clients_.contains (id))
|
||||
{
|
||||
auto& client = (clients_[id] = {sender, sender_port});
|
||||
QByteArray client_version;
|
||||
QByteArray client_revision;
|
||||
|
||||
if (NetworkMessage::Heartbeat == in.type ())
|
||||
{
|
||||
// negotiate a working schema number
|
||||
in >> client.negotiated_schema_number_;
|
||||
if (OK == check_status (in))
|
||||
{
|
||||
auto sn = NetworkMessage::Builder::schema_number;
|
||||
client.negotiated_schema_number_ = std::min (sn, client.negotiated_schema_number_);
|
||||
|
||||
// reply to the new client informing it of the
|
||||
// negotiated schema number
|
||||
QByteArray message;
|
||||
NetworkMessage::Builder hb {&message, NetworkMessage::Heartbeat, id, client.negotiated_schema_number_};
|
||||
hb << NetworkMessage::Builder::schema_number // maximum schema number accepted
|
||||
<< version_.toUtf8 () << revision_.toUtf8 ();
|
||||
if (impl::OK == check_status (hb))
|
||||
{
|
||||
writeDatagram (message, client.sender_address_, client.sender_port_);
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_EMIT self_->error ("Error creating UDP message");
|
||||
}
|
||||
}
|
||||
// we don't care if this fails to read
|
||||
in >> client_version >> client_revision;
|
||||
}
|
||||
Q_EMIT self_->client_opened (id, QString::fromUtf8 (client_version),
|
||||
QString::fromUtf8 (client_revision));
|
||||
}
|
||||
clients_[id].last_activity_ = QDateTime::currentDateTime ();
|
||||
|
||||
//
|
||||
// message format is described in NetworkMessage.hpp
|
||||
//
|
||||
switch (in.type ())
|
||||
{
|
||||
case NetworkMessage::Heartbeat:
|
||||
//nothing to do here as time out handling deals with lifetime
|
||||
break;
|
||||
|
||||
case NetworkMessage::Clear:
|
||||
Q_EMIT self_->clear_decodes (id);
|
||||
break;
|
||||
|
||||
case NetworkMessage::Status:
|
||||
{
|
||||
// unpack message
|
||||
Frequency f;
|
||||
QByteArray mode;
|
||||
QByteArray dx_call;
|
||||
QByteArray report;
|
||||
QByteArray tx_mode;
|
||||
bool tx_enabled {false};
|
||||
bool transmitting {false};
|
||||
bool decoding {false};
|
||||
qint32 rx_df {-1};
|
||||
qint32 tx_df {-1};
|
||||
QByteArray de_call;
|
||||
QByteArray de_grid;
|
||||
QByteArray dx_grid;
|
||||
bool watchdog_timeout {false};
|
||||
QByteArray sub_mode;
|
||||
bool fast_mode {false};
|
||||
in >> f >> mode >> dx_call >> report >> tx_mode >> tx_enabled >> transmitting >> decoding
|
||||
>> rx_df >> tx_df >> de_call >> de_grid >> dx_grid >> watchdog_timeout >> sub_mode
|
||||
>> fast_mode;
|
||||
if (check_status (in) != Fail)
|
||||
{
|
||||
Q_EMIT self_->status_update (id, f, QString::fromUtf8 (mode), QString::fromUtf8 (dx_call)
|
||||
, QString::fromUtf8 (report), QString::fromUtf8 (tx_mode)
|
||||
, tx_enabled, transmitting, decoding, rx_df, tx_df
|
||||
, QString::fromUtf8 (de_call), QString::fromUtf8 (de_grid)
|
||||
, QString::fromUtf8 (dx_grid), watchdog_timeout
|
||||
, QString::fromUtf8 (sub_mode), fast_mode);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case NetworkMessage::Decode:
|
||||
{
|
||||
// unpack message
|
||||
bool is_new {true};
|
||||
QTime time;
|
||||
qint32 snr;
|
||||
float delta_time;
|
||||
quint32 delta_frequency;
|
||||
QByteArray mode;
|
||||
QByteArray message;
|
||||
in >> is_new >> time >> snr >> delta_time >> delta_frequency >> mode >> message;
|
||||
if (check_status (in) != Fail)
|
||||
{
|
||||
Q_EMIT self_->decode (is_new, id, time, snr, delta_time, delta_frequency
|
||||
, QString::fromUtf8 (mode), QString::fromUtf8 (message));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case NetworkMessage::WSPRDecode:
|
||||
{
|
||||
// unpack message
|
||||
bool is_new {true};
|
||||
QTime time;
|
||||
qint32 snr;
|
||||
float delta_time;
|
||||
Frequency frequency;
|
||||
qint32 drift;
|
||||
QByteArray callsign;
|
||||
QByteArray grid;
|
||||
qint32 power;
|
||||
in >> is_new >> time >> snr >> delta_time >> frequency >> drift >> callsign >> grid >> power;
|
||||
if (check_status (in) != Fail)
|
||||
{
|
||||
Q_EMIT self_->WSPR_decode (is_new, id, time, snr, delta_time, frequency, drift
|
||||
, QString::fromUtf8 (callsign), QString::fromUtf8 (grid), power);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case NetworkMessage::QSOLogged:
|
||||
{
|
||||
QDateTime timeOff;
|
||||
QByteArray dx_call;
|
||||
QByteArray dx_grid;
|
||||
Frequency dial_frequency;
|
||||
QByteArray mode;
|
||||
QByteArray report_sent;
|
||||
QByteArray report_received;
|
||||
QByteArray tx_power;
|
||||
QByteArray comments;
|
||||
QByteArray name;
|
||||
QDateTime timeOn; // Note: LOTW uses TIME_ON for their +/- 30-minute time window
|
||||
in >> timeOff >> dx_call >> dx_grid >> dial_frequency >> mode >> report_sent >> report_received
|
||||
>> tx_power >> comments >> name >> timeOn;
|
||||
if (check_status (in) != Fail)
|
||||
{
|
||||
Q_EMIT self_->qso_logged (id, timeOff, QString::fromUtf8 (dx_call), QString::fromUtf8 (dx_grid)
|
||||
, dial_frequency, QString::fromUtf8 (mode), QString::fromUtf8 (report_sent)
|
||||
, QString::fromUtf8 (report_received), QString::fromUtf8 (tx_power)
|
||||
, QString::fromUtf8 (comments), QString::fromUtf8 (name), timeOn);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case NetworkMessage::Close:
|
||||
Q_EMIT self_->client_closed (id);
|
||||
clients_.remove (id);
|
||||
break;
|
||||
|
||||
default:
|
||||
// Ignore
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_EMIT self_->error ("MessageServer warning: invalid UDP message received");
|
||||
}
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
Q_EMIT self_->error (QString {"MessageServer exception: %1"}.arg (e.what ()));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
Q_EMIT self_->error ("Unexpected exception in MessageServer");
|
||||
}
|
||||
}
|
||||
|
||||
void MessageServer::impl::tick ()
|
||||
{
|
||||
auto now = QDateTime::currentDateTime ();
|
||||
auto iter = std::begin (clients_);
|
||||
while (iter != std::end (clients_))
|
||||
{
|
||||
if (now > (*iter).last_activity_.addSecs (NetworkMessage::pulse))
|
||||
{
|
||||
Q_EMIT self_->clear_decodes (iter.key ());
|
||||
Q_EMIT self_->client_closed (iter.key ());
|
||||
iter = clients_.erase (iter); // safe while iterating as doesn't rehash
|
||||
}
|
||||
else
|
||||
{
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto MessageServer::impl::check_status (QDataStream const& stream) const -> StreamStatus
|
||||
{
|
||||
auto stat = stream.status ();
|
||||
StreamStatus result {Fail};
|
||||
switch (stat)
|
||||
{
|
||||
case QDataStream::ReadPastEnd:
|
||||
result = Short;
|
||||
break;
|
||||
|
||||
case QDataStream::ReadCorruptData:
|
||||
Q_EMIT self_->error ("Message serialization error: read corrupt data");
|
||||
break;
|
||||
|
||||
case QDataStream::WriteFailed:
|
||||
Q_EMIT self_->error ("Message serialization error: write error");
|
||||
break;
|
||||
|
||||
default:
|
||||
result = OK;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
MessageServer::MessageServer (QObject * parent, QString const& version, QString const& revision)
|
||||
: QObject {parent}
|
||||
, m_ {this, version, revision}
|
||||
{
|
||||
}
|
||||
|
||||
void MessageServer::start (port_type port, QHostAddress const& multicast_group_address)
|
||||
{
|
||||
if (port != m_->port_
|
||||
|| multicast_group_address != m_->multicast_group_address_)
|
||||
{
|
||||
m_->leave_multicast_group ();
|
||||
if (impl::BoundState == m_->state ())
|
||||
{
|
||||
m_->close ();
|
||||
}
|
||||
m_->multicast_group_address_ = multicast_group_address;
|
||||
auto address = m_->multicast_group_address_.isNull ()
|
||||
|| impl::IPv4Protocol != m_->multicast_group_address_.protocol () ? QHostAddress::Any : QHostAddress::AnyIPv4;
|
||||
if (port && m_->bind (address, port, m_->bind_mode_))
|
||||
{
|
||||
m_->port_ = port;
|
||||
m_->join_multicast_group ();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_->port_ = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MessageServer::reply (QString const& id, QTime time, qint32 snr, float delta_time, quint32 delta_frequency, QString const& mode, QString const& message_text)
|
||||
{
|
||||
auto iter = m_->clients_.find (id);
|
||||
if (iter != std::end (m_->clients_))
|
||||
{
|
||||
QByteArray message;
|
||||
NetworkMessage::Builder out {&message, NetworkMessage::Reply, id, (*iter).negotiated_schema_number_};
|
||||
out << time << snr << delta_time << delta_frequency << mode.toUtf8 () << message_text.toUtf8 ();
|
||||
m_->send_message (out, message, iter.value ().sender_address_, (*iter).sender_port_);
|
||||
}
|
||||
}
|
||||
|
||||
void MessageServer::replay (QString const& id)
|
||||
{
|
||||
auto iter = m_->clients_.find (id);
|
||||
if (iter != std::end (m_->clients_))
|
||||
{
|
||||
QByteArray message;
|
||||
NetworkMessage::Builder out {&message, NetworkMessage::Replay, id, (*iter).negotiated_schema_number_};
|
||||
m_->send_message (out, message, iter.value ().sender_address_, (*iter).sender_port_);
|
||||
}
|
||||
}
|
||||
|
||||
void MessageServer::halt_tx (QString const& id, bool auto_only)
|
||||
{
|
||||
auto iter = m_->clients_.find (id);
|
||||
if (iter != std::end (m_->clients_))
|
||||
{
|
||||
QByteArray message;
|
||||
NetworkMessage::Builder out {&message, NetworkMessage::HaltTx, id, (*iter).negotiated_schema_number_};
|
||||
out << auto_only;
|
||||
m_->send_message (out, message, iter.value ().sender_address_, (*iter).sender_port_);
|
||||
}
|
||||
}
|
||||
|
||||
void MessageServer::free_text (QString const& id, QString const& text, bool send)
|
||||
{
|
||||
auto iter = m_->clients_.find (id);
|
||||
if (iter != std::end (m_->clients_))
|
||||
{
|
||||
QByteArray message;
|
||||
NetworkMessage::Builder out {&message, NetworkMessage::FreeText, id, (*iter).negotiated_schema_number_};
|
||||
out << text.toUtf8 () << send;
|
||||
m_->send_message (out, message, iter.value ().sender_address_, (*iter).sender_port_);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
0; 0; 0
|
||||
0; 0; 87
|
||||
0; 79;114
|
||||
0;141; 61
|
||||
96;158; 0
|
||||
204;124; 0
|
||||
253; 50; 17
|
||||
255;138;138
|
||||
255;255;255
|
||||
@@ -1,642 +0,0 @@
|
||||
// -*- Mode: C++ -*-
|
||||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
#ifdef QT5
|
||||
#include <QtWidgets>
|
||||
#else
|
||||
#include <QtGui>
|
||||
#endif
|
||||
#include <QThread>
|
||||
#include <QTimer>
|
||||
#include <QDateTime>
|
||||
#include <QList>
|
||||
#include <QAudioDeviceInfo>
|
||||
#include <QScopedPointer>
|
||||
#include <QDir>
|
||||
#include <QProgressDialog>
|
||||
#include <QAbstractSocket>
|
||||
#include <QHostAddress>
|
||||
#include <QPointer>
|
||||
#include <QSet>
|
||||
#include <QVector>
|
||||
#include <QFuture>
|
||||
#include <QFutureWatcher>
|
||||
|
||||
#include "AudioDevice.hpp"
|
||||
#include "commons.h"
|
||||
#include "Radio.hpp"
|
||||
#include "Modes.hpp"
|
||||
#include "FrequencyList.hpp"
|
||||
#include "Configuration.hpp"
|
||||
#include "WSPRBandHopping.hpp"
|
||||
#include "Transceiver.hpp"
|
||||
#include "DisplayManual.hpp"
|
||||
#include "psk_reporter.h"
|
||||
#include "logbook/logbook.h"
|
||||
#include "decodedtext.h"
|
||||
#include "commons.h"
|
||||
#include "astro.h"
|
||||
#include "MessageBox.hpp"
|
||||
#include "NetworkAccessManager.hpp"
|
||||
|
||||
#define NUM_JT4_SYMBOLS 206 //(72+31)*2, embedded sync
|
||||
#define NUM_JT65_SYMBOLS 126 //63 data + 63 sync
|
||||
#define NUM_JT9_SYMBOLS 85 //69 data + 16 sync
|
||||
#define NUM_WSPR_SYMBOLS 162 //(50+31)*2, embedded sync
|
||||
#define NUM_WSPR_LF_SYMBOLS 412 //300 data + 109 sync + 3 ramp
|
||||
#define NUM_ISCAT_SYMBOLS 1291 //30*11025/256
|
||||
#define NUM_MSK144_SYMBOLS 144 //s8 + d48 + s8 + d80
|
||||
#define NUM_QRA64_SYMBOLS 84 //63 data + 21 sync
|
||||
#define NUM_FT8_SYMBOLS 79
|
||||
#define NUM_CW_SYMBOLS 250
|
||||
#define TX_SAMPLE_RATE 48000
|
||||
#define N_WIDGETS 24
|
||||
|
||||
extern int volatile itone[NUM_ISCAT_SYMBOLS]; //Audio tones for all Tx symbols
|
||||
extern int volatile icw[NUM_CW_SYMBOLS]; //Dits for CW ID
|
||||
|
||||
//--------------------------------------------------------------- MainWindow
|
||||
namespace Ui {
|
||||
class MainWindow;
|
||||
}
|
||||
|
||||
class QSettings;
|
||||
class QLineEdit;
|
||||
class QFont;
|
||||
class QHostInfo;
|
||||
class EchoGraph;
|
||||
class FastGraph;
|
||||
class WideGraph;
|
||||
class LogQSO;
|
||||
class Transceiver;
|
||||
class MessageAveraging;
|
||||
class MessageClient;
|
||||
class QTime;
|
||||
class WSPRBandHopping;
|
||||
class HelpTextWindow;
|
||||
class WSPRNet;
|
||||
class SoundOutput;
|
||||
class Modulator;
|
||||
class SoundInput;
|
||||
class Detector;
|
||||
class SampleDownloader;
|
||||
class MultiSettings;
|
||||
class EqualizationToolsDialog;
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT;
|
||||
|
||||
public:
|
||||
using Frequency = Radio::Frequency;
|
||||
using FrequencyDelta = Radio::FrequencyDelta;
|
||||
using Mode = Modes::Mode;
|
||||
|
||||
explicit MainWindow(QDir const& temp_directory, bool multiple, MultiSettings *,
|
||||
QSharedMemory *shdmem, unsigned downSampleFactor,
|
||||
QSplashScreen *,
|
||||
QWidget *parent = nullptr);
|
||||
~MainWindow();
|
||||
|
||||
public slots:
|
||||
void showSoundInError(const QString& errorMsg);
|
||||
void showSoundOutError(const QString& errorMsg);
|
||||
void showStatusMessage(const QString& statusMsg);
|
||||
void dataSink(qint64 frames);
|
||||
void fastSink(qint64 frames);
|
||||
void diskDat();
|
||||
void freezeDecode(int n);
|
||||
void guiUpdate();
|
||||
void doubleClickOnCall(bool shift, bool ctrl);
|
||||
void doubleClickOnCall2(bool shift, bool ctrl);
|
||||
void readFromStdout();
|
||||
void p1ReadFromStdout();
|
||||
void setXIT(int n, Frequency base = 0u);
|
||||
void setFreq4(int rxFreq, int txFreq);
|
||||
void msgAvgDecode2();
|
||||
void fastPick(int x0, int x1, int y);
|
||||
|
||||
protected:
|
||||
void keyPressEvent (QKeyEvent *) override;
|
||||
void closeEvent(QCloseEvent *) override;
|
||||
void childEvent(QChildEvent *) override;
|
||||
bool eventFilter(QObject *, QEvent *) override;
|
||||
|
||||
private slots:
|
||||
void on_tx1_editingFinished();
|
||||
void on_tx2_editingFinished();
|
||||
void on_tx3_editingFinished();
|
||||
void on_tx4_editingFinished();
|
||||
void on_tx5_currentTextChanged (QString const&);
|
||||
void on_tx6_editingFinished();
|
||||
void on_actionSettings_triggered();
|
||||
void on_monitorButton_clicked (bool);
|
||||
void on_actionAbout_triggered();
|
||||
void on_autoButton_clicked (bool);
|
||||
void on_stopTxButton_clicked();
|
||||
void on_stopButton_clicked();
|
||||
void on_actionRelease_Notes_triggered ();
|
||||
void on_actionOnline_User_Guide_triggered();
|
||||
void on_actionLocal_User_Guide_triggered();
|
||||
void on_actionWide_Waterfall_triggered();
|
||||
void on_actionOpen_triggered();
|
||||
void on_actionOpen_next_in_directory_triggered();
|
||||
void on_actionDecode_remaining_files_in_directory_triggered();
|
||||
void on_actionDelete_all_wav_files_in_SaveDir_triggered();
|
||||
void on_actionOpen_log_directory_triggered ();
|
||||
void on_actionNone_triggered();
|
||||
void on_actionSave_all_triggered();
|
||||
void on_actionKeyboard_shortcuts_triggered();
|
||||
void on_actionSpecial_mouse_commands_triggered();
|
||||
void on_DecodeButton_clicked (bool);
|
||||
void decode();
|
||||
void decodeBusy(bool b);
|
||||
void on_EraseButton_clicked();
|
||||
void on_txFirstCheckBox_stateChanged(int arg1);
|
||||
void set_dateTimeQSO(int m_ntx);
|
||||
void set_ntx(int n);
|
||||
void on_txrb1_toggled(bool status);
|
||||
void on_txrb1_doubleClicked ();
|
||||
void on_txrb2_toggled(bool status);
|
||||
void on_txrb3_toggled(bool status);
|
||||
void on_txrb4_toggled(bool status);
|
||||
void on_txrb4_doubleClicked ();
|
||||
void on_txrb5_toggled(bool status);
|
||||
void on_txrb5_doubleClicked ();
|
||||
void on_txrb6_toggled(bool status);
|
||||
void on_txb1_clicked();
|
||||
void on_txb1_doubleClicked ();
|
||||
void on_txb2_clicked();
|
||||
void on_txb3_clicked();
|
||||
void on_txb4_clicked();
|
||||
void on_txb4_doubleClicked ();
|
||||
void on_txb5_clicked();
|
||||
void on_txb5_doubleClicked ();
|
||||
void on_txb6_clicked();
|
||||
void on_lookupButton_clicked();
|
||||
void on_addButton_clicked();
|
||||
void on_dxCallEntry_textChanged (QString const&);
|
||||
void on_dxGridEntry_textChanged (QString const&);
|
||||
void on_dxCallEntry_returnPressed ();
|
||||
void on_genStdMsgsPushButton_clicked();
|
||||
void on_logQSOButton_clicked();
|
||||
void on_actionJT9_triggered();
|
||||
void on_actionJT65_triggered();
|
||||
void on_actionJT9_JT65_triggered();
|
||||
void on_actionJT4_triggered();
|
||||
void on_actionFT8_triggered();
|
||||
void on_TxFreqSpinBox_valueChanged(int arg1);
|
||||
void on_actionSave_decoded_triggered();
|
||||
void on_actionQuickDecode_toggled (bool);
|
||||
void on_actionMediumDecode_toggled (bool);
|
||||
void on_actionDeepestDecode_toggled (bool);
|
||||
void bumpFqso(int n);
|
||||
void on_actionErase_ALL_TXT_triggered();
|
||||
void on_actionErase_wsjtx_log_adi_triggered();
|
||||
void startTx2();
|
||||
void startP1();
|
||||
void stopTx();
|
||||
void stopTx2();
|
||||
void on_pbCallCQ_clicked();
|
||||
void on_pbAnswerCaller_clicked();
|
||||
void on_pbSendRRR_clicked();
|
||||
void on_pbAnswerCQ_clicked();
|
||||
void on_pbSendReport_clicked();
|
||||
void on_pbSend73_clicked();
|
||||
void on_rbGenMsg_clicked(bool checked);
|
||||
void on_rbFreeText_clicked(bool checked);
|
||||
void on_freeTextMsg_currentTextChanged (QString const&);
|
||||
void on_rptSpinBox_valueChanged(int n);
|
||||
void killFile();
|
||||
void on_tuneButton_clicked (bool);
|
||||
void on_pbR2T_clicked();
|
||||
void on_pbT2R_clicked();
|
||||
void acceptQSO2(QDateTime const&, QString const& call, QString const& grid
|
||||
, Frequency dial_freq, QString const& mode
|
||||
, QString const& rpt_sent, QString const& rpt_received
|
||||
, QString const& tx_power, QString const& comments
|
||||
, QString const& name, QDateTime const&);
|
||||
void on_bandComboBox_currentIndexChanged (int index);
|
||||
void on_bandComboBox_activated (int index);
|
||||
void on_readFreq_clicked();
|
||||
void on_pbTxMode_clicked();
|
||||
void on_RxFreqSpinBox_valueChanged(int n);
|
||||
void on_cbTxLock_clicked(bool checked);
|
||||
void on_outAttenuation_valueChanged (int);
|
||||
void rigOpen ();
|
||||
void handle_transceiver_update (Transceiver::TransceiverState const&);
|
||||
void handle_transceiver_failure (QString const& reason);
|
||||
void on_actionAstronomical_data_toggled (bool);
|
||||
void on_actionShort_list_of_add_on_prefixes_and_suffixes_triggered();
|
||||
void band_changed (Frequency);
|
||||
void monitor (bool);
|
||||
void stop_tuning ();
|
||||
void stopTuneATU();
|
||||
void auto_tx_mode(bool);
|
||||
void on_actionMessage_averaging_triggered();
|
||||
void on_actionInclude_averaging_toggled (bool);
|
||||
void on_actionInclude_correlation_toggled (bool);
|
||||
void on_actionEnable_AP_DXcall_toggled (bool);
|
||||
void VHF_features_enabled(bool b);
|
||||
void on_sbSubmode_valueChanged(int n);
|
||||
void on_cbShMsgs_toggled(bool b);
|
||||
void on_cbSWL_toggled(bool b);
|
||||
void on_cbTx6_toggled(bool b);
|
||||
void on_cbMenus_toggled(bool b);
|
||||
void on_cbFirst_toggled(bool b);
|
||||
void on_cbAutoSeq_toggled(bool b);
|
||||
void networkError (QString const&);
|
||||
void on_ClrAvgButton_clicked();
|
||||
void on_actionWSPR_triggered();
|
||||
void on_actionWSPR_LF_triggered();
|
||||
void on_syncSpinBox_valueChanged(int n);
|
||||
void on_TxPowerComboBox_currentIndexChanged(const QString &arg1);
|
||||
void on_sbTxPercent_valueChanged(int n);
|
||||
void on_cbUploadWSPR_Spots_toggled(bool b);
|
||||
void WSPR_config(bool b);
|
||||
void uploadSpots();
|
||||
void TxAgain();
|
||||
void uploadResponse(QString response);
|
||||
void on_WSPRfreqSpinBox_valueChanged(int n);
|
||||
void on_pbTxNext_clicked(bool b);
|
||||
void on_actionEcho_Graph_triggered();
|
||||
void on_actionEcho_triggered();
|
||||
void on_actionISCAT_triggered();
|
||||
void on_actionFast_Graph_triggered();
|
||||
void fast_decode_done();
|
||||
void on_actionMeasure_reference_spectrum_triggered();
|
||||
void on_actionErase_reference_spectrum_triggered();
|
||||
void on_actionMeasure_phase_response_triggered();
|
||||
void on_sbTR_valueChanged (int);
|
||||
void on_sbFtol_valueChanged (int);
|
||||
void on_cbFast9_clicked(bool b);
|
||||
void on_sbCQTxFreq_valueChanged(int n);
|
||||
void on_cbCQTx_toggled(bool b);
|
||||
void on_actionMSK144_triggered();
|
||||
void on_actionQRA64_triggered();
|
||||
void on_actionFreqCal_triggered();
|
||||
void splash_done ();
|
||||
|
||||
private:
|
||||
Q_SIGNAL void initializeAudioOutputStream (QAudioDeviceInfo,
|
||||
unsigned channels, unsigned msBuffered) const;
|
||||
Q_SIGNAL void stopAudioOutputStream () const;
|
||||
Q_SIGNAL void startAudioInputStream (QAudioDeviceInfo const&,
|
||||
int framesPerBuffer, AudioDevice * sink,
|
||||
unsigned downSampleFactor, AudioDevice::Channel) const;
|
||||
Q_SIGNAL void suspendAudioInputStream () const;
|
||||
Q_SIGNAL void resumeAudioInputStream () const;
|
||||
Q_SIGNAL void startDetector (AudioDevice::Channel) const;
|
||||
Q_SIGNAL void FFTSize (unsigned) const;
|
||||
Q_SIGNAL void detectorClose () const;
|
||||
Q_SIGNAL void finished () const;
|
||||
Q_SIGNAL void transmitFrequency (double) const;
|
||||
Q_SIGNAL void endTransmitMessage (bool quick = false) const;
|
||||
Q_SIGNAL void tune (bool = true) const;
|
||||
Q_SIGNAL void sendMessage (unsigned symbolsLength, double framesPerSymbol,
|
||||
double frequency, double toneSpacing,
|
||||
SoundOutput *, AudioDevice::Channel = AudioDevice::Mono,
|
||||
bool synchronize = true, bool fastMode = false, double dBSNR = 99.,
|
||||
int TRperiod=60) const;
|
||||
Q_SIGNAL void outAttenuationChanged (qreal) const;
|
||||
Q_SIGNAL void toggleShorthand () const;
|
||||
|
||||
private:
|
||||
void astroUpdate ();
|
||||
void writeAllTxt(QString message);
|
||||
void auto_sequence (QString const& message, unsigned start_tolerance, unsigned stop_tolerance);
|
||||
void hideMenus(bool b);
|
||||
|
||||
NetworkAccessManager m_network_manager;
|
||||
bool m_valid;
|
||||
QSplashScreen * m_splash;
|
||||
QString m_revision;
|
||||
bool m_multiple;
|
||||
MultiSettings * m_multi_settings;
|
||||
QPushButton * m_configurations_button;
|
||||
QSettings * m_settings;
|
||||
QScopedPointer<Ui::MainWindow> ui;
|
||||
|
||||
// other windows
|
||||
Configuration m_config;
|
||||
WSPRBandHopping m_WSPR_band_hopping;
|
||||
bool m_WSPR_tx_next;
|
||||
MessageBox m_rigErrorMessageBox;
|
||||
QScopedPointer<SampleDownloader> m_sampleDownloader;
|
||||
QScopedPointer<EqualizationToolsDialog> m_equalizationToolsDialog;
|
||||
|
||||
QScopedPointer<WideGraph> m_wideGraph;
|
||||
QScopedPointer<EchoGraph> m_echoGraph;
|
||||
QScopedPointer<FastGraph> m_fastGraph;
|
||||
QScopedPointer<LogQSO> m_logDlg;
|
||||
QScopedPointer<Astro> m_astroWidget;
|
||||
QScopedPointer<HelpTextWindow> m_shortcuts;
|
||||
QScopedPointer<HelpTextWindow> m_prefixes;
|
||||
QScopedPointer<HelpTextWindow> m_mouseCmnds;
|
||||
QScopedPointer<MessageAveraging> m_msgAvgWidget;
|
||||
|
||||
Transceiver::TransceiverState m_rigState;
|
||||
Frequency m_lastDialFreq;
|
||||
QString m_lastBand;
|
||||
QString m_lastCallsign;
|
||||
Frequency m_dialFreqRxWSPR; // best guess at WSPR QRG
|
||||
|
||||
Detector * m_detector;
|
||||
unsigned m_FFTSize;
|
||||
SoundInput * m_soundInput;
|
||||
Modulator * m_modulator;
|
||||
SoundOutput * m_soundOutput;
|
||||
QThread m_audioThread;
|
||||
|
||||
qint64 m_msErase;
|
||||
qint64 m_secBandChanged;
|
||||
qint64 m_freqMoon;
|
||||
Frequency m_freqNominal;
|
||||
Frequency m_freqTxNominal;
|
||||
Astro::Correction m_astroCorrection;
|
||||
|
||||
double m_s6;
|
||||
double m_tRemaining;
|
||||
|
||||
float m_DTtol;
|
||||
float m_t0;
|
||||
float m_t1;
|
||||
float m_t0Pick;
|
||||
float m_t1Pick;
|
||||
float m_fCPUmskrtd;
|
||||
|
||||
qint32 m_waterfallAvg;
|
||||
qint32 m_ntx;
|
||||
bool m_gen_message_is_cq;
|
||||
bool m_send_RR73;
|
||||
qint32 m_timeout;
|
||||
qint32 m_XIT;
|
||||
qint32 m_setftx;
|
||||
qint32 m_ndepth;
|
||||
qint32 m_sec0;
|
||||
qint32 m_RxLog;
|
||||
qint32 m_nutc0;
|
||||
qint32 m_ntr;
|
||||
qint32 m_tx;
|
||||
qint32 m_hsym;
|
||||
qint32 m_TRperiod;
|
||||
qint32 m_nsps;
|
||||
qint32 m_hsymStop;
|
||||
qint32 m_inGain;
|
||||
qint32 m_ncw;
|
||||
qint32 m_secID;
|
||||
qint32 m_idleMinutes;
|
||||
qint32 m_nSubMode;
|
||||
qint32 m_nclearave;
|
||||
qint32 m_minSync;
|
||||
qint32 m_dBm;
|
||||
qint32 m_pctx;
|
||||
qint32 m_nseq;
|
||||
qint32 m_nWSPRdecodes;
|
||||
qint32 m_k0;
|
||||
qint32 m_kdone;
|
||||
qint32 m_nPick;
|
||||
FrequencyList_v2::const_iterator m_frequency_list_fcal_iter;
|
||||
qint32 m_nTx73;
|
||||
qint32 m_UTCdisk;
|
||||
qint32 m_wait;
|
||||
|
||||
bool m_btxok; //True if OK to transmit
|
||||
bool m_diskData;
|
||||
bool m_loopall;
|
||||
bool m_decoderBusy;
|
||||
bool m_txFirst;
|
||||
bool m_auto;
|
||||
bool m_restart;
|
||||
bool m_startAnother;
|
||||
bool m_saveDecoded;
|
||||
bool m_saveAll;
|
||||
bool m_widebandDecode;
|
||||
bool m_call3Modified;
|
||||
bool m_dataAvailable;
|
||||
bool m_bDecoded;
|
||||
bool m_noSuffix;
|
||||
bool m_blankLine;
|
||||
bool m_decodedText2;
|
||||
bool m_freeText;
|
||||
bool m_sentFirst73;
|
||||
int m_currentMessageType;
|
||||
QString m_currentMessage;
|
||||
int m_lastMessageType;
|
||||
QString m_lastMessageSent;
|
||||
bool m_lockTxFreq;
|
||||
bool m_bShMsgs;
|
||||
bool m_bSWL;
|
||||
bool m_uploadSpots;
|
||||
bool m_uploading;
|
||||
bool m_txNext;
|
||||
bool m_grid6;
|
||||
bool m_tuneup;
|
||||
bool m_bTxTime;
|
||||
bool m_rxDone;
|
||||
bool m_bSimplex; // not using split even if it is available
|
||||
bool m_bEchoTxOK;
|
||||
bool m_bTransmittedEcho;
|
||||
bool m_bEchoTxed;
|
||||
bool m_bFastMode;
|
||||
bool m_bFast9;
|
||||
bool m_bFastDecodeCalled;
|
||||
bool m_bDoubleClickAfterCQnnn;
|
||||
bool m_bRefSpec;
|
||||
bool m_bClearRefSpec;
|
||||
bool m_bTrain;
|
||||
bool m_bUseRef;
|
||||
bool m_bFastDone;
|
||||
bool m_bAltV;
|
||||
bool m_bNoMoreFiles;
|
||||
bool m_bQRAsyncWarned;
|
||||
bool m_bDoubleClicked;
|
||||
bool m_bCallingCQ;
|
||||
bool m_bAutoReply;
|
||||
enum
|
||||
{
|
||||
CALLING,
|
||||
REPLYING,
|
||||
REPORT,
|
||||
ROGER_REPORT,
|
||||
ROGERS,
|
||||
SIGNOFF
|
||||
}
|
||||
m_QSOProgress;
|
||||
|
||||
int m_ihsym;
|
||||
int m_nzap;
|
||||
int m_npts8;
|
||||
float m_px;
|
||||
float m_pxmax;
|
||||
float m_df3;
|
||||
int m_iptt0;
|
||||
bool m_btxok0;
|
||||
int m_nsendingsh;
|
||||
double m_onAirFreq0;
|
||||
bool m_first_error;
|
||||
|
||||
char m_msg[100][80];
|
||||
|
||||
// labels in status bar
|
||||
QLabel tx_status_label;
|
||||
QLabel config_label;
|
||||
QLabel mode_label;
|
||||
QLabel last_tx_label;
|
||||
QLabel auto_tx_label;
|
||||
QLabel band_hopping_label;
|
||||
QProgressBar progressBar;
|
||||
QLabel watchdog_label;
|
||||
|
||||
QFuture<void> m_wav_future;
|
||||
QFutureWatcher<void> m_wav_future_watcher;
|
||||
QFutureWatcher<void> watcher3;
|
||||
QFutureWatcher<QString> m_saveWAVWatcher;
|
||||
|
||||
QProcess proc_jt9;
|
||||
QProcess p1;
|
||||
QProcess p3;
|
||||
|
||||
WSPRNet *wsprNet;
|
||||
|
||||
QTimer m_guiTimer;
|
||||
QTimer ptt1Timer; //StartTx delay
|
||||
QTimer ptt0Timer; //StopTx delay
|
||||
QTimer logQSOTimer;
|
||||
QTimer killFileTimer;
|
||||
QTimer tuneButtonTimer;
|
||||
QTimer uploadTimer;
|
||||
QTimer tuneATU_Timer;
|
||||
QTimer TxAgainTimer;
|
||||
QTimer minuteTimer;
|
||||
QTimer splashTimer;
|
||||
QTimer p1Timer;
|
||||
|
||||
QString m_path;
|
||||
QString m_baseCall;
|
||||
QString m_hisCall;
|
||||
QString m_hisGrid;
|
||||
QString m_appDir;
|
||||
QString m_palette;
|
||||
QString m_dateTime;
|
||||
QString m_mode;
|
||||
QString m_modeTx;
|
||||
QString m_fnameWE; // save path without extension
|
||||
QString m_rpt;
|
||||
QString m_rptSent;
|
||||
QString m_rptRcvd;
|
||||
QString m_qsoStart;
|
||||
QString m_qsoStop;
|
||||
QString m_cmnd;
|
||||
QString m_cmndP1;
|
||||
QString m_msgSent0;
|
||||
QString m_fileToSave;
|
||||
QString m_calls;
|
||||
|
||||
QSet<QString> m_pfx;
|
||||
QSet<QString> m_sfx;
|
||||
|
||||
QDateTime m_dateTimeQSOOn;
|
||||
|
||||
QSharedMemory *mem_jt9;
|
||||
LogBook m_logBook;
|
||||
DecodedText m_QSOText;
|
||||
unsigned m_msAudioOutputBuffered;
|
||||
unsigned m_framesAudioInputBuffered;
|
||||
unsigned m_downSampleFactor;
|
||||
QThread::Priority m_audioThreadPriority;
|
||||
bool m_bandEdited;
|
||||
bool m_splitMode;
|
||||
bool m_monitoring;
|
||||
bool m_tx_when_ready;
|
||||
bool m_transmitting;
|
||||
bool m_tune;
|
||||
bool m_tx_watchdog; // true when watchdog triggered
|
||||
bool m_block_pwr_tooltip;
|
||||
bool m_PwrBandSetOK;
|
||||
bool m_bVHFwarned;
|
||||
Frequency m_lastMonitoredFrequency;
|
||||
double m_toneSpacing;
|
||||
int m_firstDecode;
|
||||
QProgressDialog m_optimizingProgress;
|
||||
QTimer m_heartbeat;
|
||||
MessageClient * m_messageClient;
|
||||
PSK_Reporter *psk_Reporter;
|
||||
DisplayManual m_manual;
|
||||
QHash<QString, QVariant> m_pwrBandTxMemory; // Remembers power level by band
|
||||
QHash<QString, QVariant> m_pwrBandTuneMemory; // Remembers power level by band for tuning
|
||||
QByteArray m_geometryNoControls;
|
||||
QVector<double> m_phaseEqCoefficients;
|
||||
|
||||
//---------------------------------------------------- private functions
|
||||
void readSettings();
|
||||
void setDecodedTextFont (QFont const&);
|
||||
void writeSettings();
|
||||
void createStatusBar();
|
||||
void updateStatusBar();
|
||||
void genStdMsgs(QString rpt, bool unconditional = false);
|
||||
void genCQMsg();
|
||||
void clearDX ();
|
||||
void lookup();
|
||||
void ba2msg(QByteArray ba, char* message);
|
||||
void msgtype(QString t, QLineEdit* tx);
|
||||
void stub();
|
||||
void statusChanged();
|
||||
void fixStop();
|
||||
bool shortList(QString callsign);
|
||||
void transmit (double snr = 99.);
|
||||
void rigFailure (QString const& reason);
|
||||
void pskSetLocal ();
|
||||
void pskPost(DecodedText decodedtext);
|
||||
void displayDialFrequency ();
|
||||
void transmitDisplay (bool);
|
||||
void processMessage(QString const& messages, qint32 position, bool ctrl = false, bool alt = false);
|
||||
void replyToCQ (QTime, qint32 snr, float delta_time, quint32 delta_frequency, QString const& mode, QString const& message_text);
|
||||
void replayDecodes ();
|
||||
void postDecode (bool is_new, QString const& message);
|
||||
void postWSPRDecode (bool is_new, QStringList message_parts);
|
||||
void enable_DXCC_entity (bool on);
|
||||
void switch_mode (Mode);
|
||||
void WSPR_scheduling ();
|
||||
void freqCalStep();
|
||||
void setRig (Frequency = 0); // zero frequency means no change
|
||||
void WSPR_history(Frequency dialFreq, int ndecodes);
|
||||
QString WSPR_hhmm(int n);
|
||||
void fast_config(bool b);
|
||||
void CQTxFreq();
|
||||
QString save_wave_file (QString const& name
|
||||
, short const * data
|
||||
, int seconds
|
||||
, QString const& my_callsign
|
||||
, QString const& my_grid
|
||||
, QString const& mode
|
||||
, qint32 sub_mode
|
||||
, Frequency frequency
|
||||
, QString const& his_call
|
||||
, QString const& his_grid) const;
|
||||
void read_wav_file (QString const& fname);
|
||||
void decodeDone ();
|
||||
void subProcessFailed (QProcess *, int exit_code, QProcess::ExitStatus);
|
||||
void subProcessError (QProcess *, QProcess::ProcessError);
|
||||
void statusUpdate () const;
|
||||
void update_watchdog_label ();
|
||||
void on_the_minute ();
|
||||
void add_child_to_event_filter (QObject *);
|
||||
void remove_child_from_event_filter (QObject *);
|
||||
void setup_status_bar (bool vhf);
|
||||
void tx_watchdog (bool triggered);
|
||||
int nWidgets(QString t);
|
||||
void displayWidgets(int n);
|
||||
void vhfWarning();
|
||||
QChar current_submode () const; // returns QChar {0} if sub mode is
|
||||
// not appropriate
|
||||
void write_transmit_entry (QString const& file_name);
|
||||
};
|
||||
|
||||
extern int killbyname(const char* progName);
|
||||
extern void getDev(int* numDevices,char hostAPI_DeviceName[][50],
|
||||
int minChan[], int maxChan[],
|
||||
int minSpeed[], int maxSpeed[]);
|
||||
extern int next_tx_state(int pctx);
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
@@ -1,10 +0,0 @@
|
||||
! LDPC (174,87) code
|
||||
parameter (KK=87) !Information bits (75 + CRC12)
|
||||
parameter (ND=58) !Data symbols
|
||||
parameter (NS=21) !Sync symbols (3 @ Costas 7x7)
|
||||
parameter (NN=NS+ND) !Total channel symbols (79)
|
||||
parameter (NSPS=2048) !Samples per symbol at 12000 S/s
|
||||
parameter (NZ=NSPS*NN) !Samples in full 15 s waveform (161,792)
|
||||
parameter (NMAX=15*12000) !Samples in iwave (180,000)
|
||||
parameter (NFFT1=2*NSPS, NH1=NFFT1/2) !Length of FFTs for symbol spectra
|
||||
parameter (NHSYM=2*NMAX/NH1-1) !Number of symbol spectra (1/2-symbol steps)
|
||||
@@ -0,0 +1,40 @@
|
||||
subroutine slope(y,npts,xpk)
|
||||
|
||||
! Remove best-fit slope from data in y(i). When fitting the straight line,
|
||||
! ignore the peak around xpk +/- 4 bins
|
||||
|
||||
real y(npts)
|
||||
|
||||
sumw=0.
|
||||
sumx=0.
|
||||
sumy=0.
|
||||
sumx2=0.
|
||||
sumxy=0.
|
||||
sumy2=0.
|
||||
do i=1,npts
|
||||
if(abs(i-xpk).gt.4.0) then
|
||||
sumw=sumw + 1.0
|
||||
x=i
|
||||
sumx=sumx + x
|
||||
sumy=sumy + y(i)
|
||||
sumx2=sumx2 + x*x
|
||||
sumxy=sumxy + x*y(i)
|
||||
sumy2=sumy2 + y(i)**2
|
||||
endif
|
||||
enddo
|
||||
|
||||
delta=sumw*sumx2 - sumx**2
|
||||
a=(sumx2*sumy - sumx*sumxy) / delta
|
||||
b=(sumw*sumxy - sumx*sumy) / delta
|
||||
|
||||
sq=0.
|
||||
do i=1,npts
|
||||
y(i)=y(i)-(a + b*i)
|
||||
if(abs(i-xpk).gt.4.0) sq=sq + y(i)**2
|
||||
enddo
|
||||
rms=sqrt(sq/(sumw-4.0))
|
||||
y=y/rms
|
||||
|
||||
return
|
||||
end subroutine slope
|
||||
|
||||
Reference in New Issue
Block a user