Merged master 8748

This commit is contained in:
Jordan Sherer
2018-08-05 11:33:30 -04:00
parent 8f8772f1bd
commit 62899069bf
1095 changed files with 31298 additions and 367679 deletions
@@ -1,420 +0,0 @@
/* DEC.C - Decoding procedures. */
/* Copyright (c) 1995-2012 by Radford M. Neal.
*
* Permission is granted for anyone to copy, use, modify, and distribute
* these programs and accompanying documents for any purpose, provided
* this copyright notice is retained and prominently displayed, and note
* is made of any changes made to these programs. These programs and
* documents are distributed without any warranty, express or implied.
* As the programs were written for research purposes only, they have not
* been tested to the degree that would be advisable in any important
* application. All use of these programs is entirely at the user's own
* risk.
*/
/* NOTE: See decoding.html for general documentation on the decoding methods */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "alloc.h"
#include "mod2sparse.h"
#include "mod2dense.h"
#include "mod2convert.h"
/*#include "rand.h"*/
#include "rcode.h"
#include "check.h"
#include "dec.h"
#include "enc.h"
/* GLOBAL VARIABLES. Declared in dec.h. */
decoding_method dec_method; /* Decoding method to use */
int ldpc_table; /* Trace option, 2 for a table of decoding details */
int block_no; /* Number of current block, from zero */
int max_iter; /* Maximum number of iteratons of decoding to do */
char *gen_file; /* Generator file for Enum_block and Enum_bit */
/* DECODE BY EXHAUSTIVE ENUMERATION. Decodes by trying all possible source
messages (and hence all possible codewords, unless the parity check matrix
was redundant). If the last argument is 1, it sets dblk to the most likely
entire block; if this argument is 0, each bit of dblk is set to the most
likely value for that bit. The marginal probabilities of each bit being 1
are returned in bitpr.
The function value returned is the total number of codewords tried (which
will be the same for all blocks). The return valued is "unsigned" because
it might conceivably be as big as 2^31.
The parity check matrix and other data are taken from the global variables
declared in rcode.h.
The number of message bits should not be greater than 31 for this procedure.
The setup procedure immediately below checks this, reads the generator file,
and outputs headers for the detailed trace file, if required.
*/
void enum_decode_setup(void)
{
read_gen(gen_file,0,0);
if (N-M>31)
{ fprintf(stderr,
"Trying to decode messages with %d bits by exhaustive enumeration is absurd!\n",
N-M);
exit(1);
}
if (ldpc_table==2)
{ printf(" block decoding likelihood\n");
}
}
unsigned enum_decode
( double *lratio, /* Likelihood ratios for bits */
char *dblk, /* Place to stored decoded message */
double *bitpr, /* Place to store marginal bit probabilities */
int max_block /* Maximize probability of whole block being correct? */
)
{
mod2dense *u, *v;
double lk, maxlk, tpr;
double *bpr, *lk0, *lk1;
char sblk[31];
char *cblk;
unsigned d;
int i, j;
if (N-M>31) abort();
/* Allocate needed space. */
bpr = bitpr;
if (bpr==0 && max_block==0)
{ bpr = chk_alloc (N, sizeof *bpr);
}
cblk = chk_alloc (N, sizeof *cblk);
if (type=='d')
{ u = mod2dense_allocate(N-M,1);
v = mod2dense_allocate(M,1);
}
if (type=='m')
{ u = mod2dense_allocate(M,1);
v = mod2dense_allocate(M,1);
}
lk0 = chk_alloc (N, sizeof *lk0);
lk1 = chk_alloc (N, sizeof *lk1);
/* Pre-compute likelihoods for bits. */
for (j = 0; j<N; j++)
{ lk0[j] = 1/(1+lratio[j]);
lk1[j] = 1 - lk0[j];
}
/* Initialize marginal bit probabilities. */
if (bpr)
{ for (j = 0; j<N; j++) bpr[j] = 0.0;
}
/* Exhaustively try all possible decoded messages. */
tpr = 0.0;
for (d = 0; d<=(1<<(N-M))-1; d++)
{
/* Unpack message into source block. */
for (i = N-M-1; i>=0; i--)
{ sblk[i] = (d>>i)&1;
}
/* Find full codeword for this message. */
switch (type)
{ case 's':
{ sparse_encode (sblk, cblk);
break;
}
case 'd':
{ dense_encode (sblk, cblk, u, v);
break;
}
case 'm':
{ mixed_encode (sblk, cblk, u, v);
break;
}
}
/* Compute likelihood for this decoding. */
lk = 1;
for (j = 0; j<N; j++)
{ lk *= cblk[j]==0 ? lk0[j] : lk1[j];
}
/* Update maximum likelihood decoding. */
if (max_block)
{ if (d==0 || lk>maxlk)
{ for (j = 0; j<N; j++)
{ dblk[j] = cblk[j];
}
maxlk = lk;
}
}
/* Update bit probabilities. */
if (bpr)
{ for (j = 0; j<N; j++)
{ if (cblk[j]==1)
{ bpr[j] += lk;
}
}
tpr += lk;
}
/* Output data to trace file. */
if (ldpc_table==2)
{ printf("%7d %10x %10.4e\n",block_no,d,lk);
}
}
/* Normalize bit probabilities. */
if (bpr)
{ for (j = 0; j<N; j++) bpr[j] /= tpr;
}
/* Decoding to maximize bit-by-bit success, if that's what's wanted.
In case of a tie, decode to a 1. */
if (!max_block)
{ for (j = 0; j<N; j++)
{ dblk[j] = bpr[j]>=0.5;
}
}
/* Free space. */
if (bpr!=0 && bpr!=bitpr) free(bpr);
free(cblk);
free(lk0);
free(lk1);
return 1<<(N-M);
}
/* DECODE USING PROBABILITY PROPAGATION. Tries to find the most probable
values for the bits of the codeword, given a parity check matrix (H), and
likelihood ratios (lratio) for each bit. If max_iter is positive, up to
that many iterations of probability propagation are done, stopping before
then if the tentative decoding is a valid codeword. If max_iter is
negative, abs(max_iter) iterations are done, regardless of whether a
codeword was found earlier.
Returns the number of iterations done (as an "unsigned" for consistency
with enum_decode). Regardless of whether or not a valid codeword was
reached, the bit vector from thresholding the bit-by-bit probabilities is
stored in dblk, and the resulting parity checks are stored in pchk (all
will be zero if the codeword is valid). The final probabilities for each
bit being a 1 are stored in bprb.
The setup procedure immediately below outputs headers for the detailed trace
file, if required.
*/
void prprp_decode_setup (void)
{
if (ldpc_table==2)
{ printf(
" block iter changed perrs loglik Eperrs Eloglik entropy\n");
}
}
unsigned prprp_decode
( mod2sparse *H, /* Parity check matrix */
double *lratio, /* Likelihood ratios for bits */
char *dblk, /* Place to store decoding */
char *pchk, /* Place to store parity checks */
double *bprb /* Place to store bit probabilities */
)
{
int N, n, c;
N = mod2sparse_cols(H);
/* Initialize probability and likelihood ratios, and find initial guess. */
initprp(H,lratio,dblk,bprb);
/* Do up to abs(max_iter) iterations of probability propagation, stopping
early if a codeword is found, unless max_iter is negative. */
for (n = 0; ; n++)
{
c = check(H,dblk,pchk);
if (ldpc_table==2)
{ printf("%7d %5d %8.1f %6d %+9.2f %8.1f %+9.2f %7.1f\n",
block_no, n, changed(lratio,dblk,N), c, loglikelihood(lratio,dblk,N),
expected_parity_errors(H,bprb), expected_loglikelihood(lratio,bprb,N),
entropy(bprb,N));
}
if (n==max_iter || n==-max_iter || (max_iter>0 && c==0))
{ break;
}
iterprp(H,lratio,dblk,bprb);
}
return n;
}
/* INITIALIZE PROBABILITY PROPAGATION. Stores initial ratios, probabilities,
and guess at decoding. */
void initprp
( mod2sparse *H, /* Parity check matrix */
double *lratio, /* Likelihood ratios for bits */
char *dblk, /* Place to store decoding */
double *bprb /* Place to store bit probabilities, 0 if not wanted */
)
{
mod2entry *e;
int N;
int j;
N = mod2sparse_cols(H);
for (j = 0; j<N; j++)
{ for (e = mod2sparse_first_in_col(H,j);
!mod2sparse_at_end(e);
e = mod2sparse_next_in_col(e))
{ e->pr = lratio[j];
e->lr = 1;
}
if (bprb) bprb[j] = 1 - 1/(1+lratio[j]);
dblk[j] = lratio[j]>=1;
}
}
/* DO ONE ITERATION OF PROBABILITY PROPAGATION. */
void iterprp
( mod2sparse *H, /* Parity check matrix */
double *lratio, /* Likelihood ratios for bits */
char *dblk, /* Place to store decoding */
double *bprb /* Place to store bit probabilities, 0 if not wanted */
)
{
double pr, dl, t;
mod2entry *e;
int N, M;
int i, j;
M = mod2sparse_rows(H);
N = mod2sparse_cols(H);
/* Recompute likelihood ratios. */
for (i = 0; i<M; i++)
{ dl = 1;
for (e = mod2sparse_first_in_row(H,i);
!mod2sparse_at_end(e);
e = mod2sparse_next_in_row(e))
{ e->lr = dl;
dl *= 2/(1+e->pr) - 1;
}
dl = 1;
for (e = mod2sparse_last_in_row(H,i);
!mod2sparse_at_end(e);
e = mod2sparse_prev_in_row(e))
{ t = e->lr * dl;
e->lr = (1-t)/(1+t);
dl *= 2/(1+e->pr) - 1;
}
}
/* Recompute probability ratios. Also find the next guess based on the
individually most likely values. */
for (j = 0; j<N; j++)
{ pr = lratio[j];
for (e = mod2sparse_first_in_col(H,j);
!mod2sparse_at_end(e);
e = mod2sparse_next_in_col(e))
{ e->pr = pr;
pr *= e->lr;
}
if (isnan(pr))
{ pr = 1;
}
if (bprb) bprb[j] = 1 - 1/(1+pr);
dblk[j] = pr>=1;
pr = 1;
for (e = mod2sparse_last_in_col(H,j);
!mod2sparse_at_end(e);
e = mod2sparse_prev_in_col(e))
{ e->pr *= pr;
if (isnan(e->pr))
{ e->pr = 1;
}
pr *= e->lr;
}
}
}
void ldpc_decode_ ( double lratio[], char decoded[], int *max_iterations, int *niterations, int *max_dither, int *ndither)
{
int i, j, itry, valid;
char dblk[N],pchk[M];
double bprb[N],lr[N];
float fac;
max_iter=*max_iterations;
srand(-1);
for (itry=0; itry< *max_dither; itry++) {
for (i=0; i<N; i++) {
if( itry == 0 ) {
fac=0.0;
} else {
fac=(rand()%1024-512)/512.0;
}
lr[i]=lratio[i]*exp(fac);
}
*niterations = prprp_decode ( H, lr, dblk, pchk, bprb );
valid = check( H, dblk, pchk )==0;
if( !valid ) {
*niterations=-1;
} else {
j=0;
for( i=M; i<N; i++ ) {
decoded[j]=dblk[cols[i]];
j=j+1;
}
*ndither=itry;
// printf("ldpc_decode %d %d \n",*niterations, *ndither);
return;
}
}
}
@@ -0,0 +1,300 @@
#ifndef CONFIGURATION_HPP_
#define CONFIGURATION_HPP_
#include <QObject>
#include <QFont>
#include "Radio.hpp"
#include "IARURegions.hpp"
#include "AudioDevice.hpp"
#include "Transceiver.hpp"
#include "pimpl_h.hpp"
class QSettings;
class QWidget;
class QAudioDeviceInfo;
class QString;
class QDir;
class Bands;
class FrequencyList_v2;
class StationList;
class QStringListModel;
class QHostAddress;
//
// Class Configuration
//
// Encapsulates the control, access and, persistence of user defined
// settings for the wsjtx GUI. Setting values are accessed through a
// QDialog window containing concept orientated tab windows.
//
// Responsibilities
//
// Provides management of the CAT and PTT rig interfaces, providing
// control access via a minimal generic set of Qt slots and status
// updates via Qt signals. Internally the rig control capability is
// farmed out to a separate thread since many of the rig control
// functions are blocking.
//
// All user settings required by the wsjtx GUI are exposed through
// query methods. Settings only become visible once they have been
// accepted by the user which is done by clicking the "OK" button on
// the settings dialog.
//
// The QSettings instance passed to the constructor is used to read
// and write user settings.
//
// Pointers to three QAbstractItemModel objects are provided to give
// access to amateur band information, user working frequencies and,
// user operating band information. These porovide consistent data
// models that can be used in GUI lists or tables or simply queried
// for user defined bands, default operating frequencies and, station
// descriptions.
//
class Configuration final
: public QObject
{
Q_OBJECT
Q_ENUMS (DataMode Type2MsgGen)
public:
using MODE = Transceiver::MODE;
using TransceiverState = Transceiver::TransceiverState;
using Frequency = Radio::Frequency;
using port_type = quint16;
enum DataMode {data_mode_none, data_mode_USB, data_mode_data};
Q_ENUM (DataMode)
enum Type2MsgGen {type_2_msg_1_full, type_2_msg_3_full, type_2_msg_5_only};
Q_ENUM (Type2MsgGen)
explicit Configuration (QDir const& temp_directory, QSettings * settings,
QWidget * parent = nullptr);
~Configuration ();
void select_tab (int);
int exec ();
bool is_active () const;
QDir temp_dir () const;
QDir doc_dir () const;
QDir data_dir () const;
QDir writeable_data_dir () const;
QAudioDeviceInfo const& audio_input_device () const;
AudioDevice::Channel audio_input_channel () const;
QAudioDeviceInfo const& audio_output_device () const;
AudioDevice::Channel audio_output_channel () const;
// These query methods should be used after a call to exec() to
// determine if either the audio input or audio output stream
// parameters have changed. The respective streams should be
// re-opened if they return true.
bool restart_audio_input () const;
bool restart_audio_output () const;
QString my_callsign () const;
QString my_grid () const;
QFont text_font () const;
QFont decoded_text_font () const;
qint32 id_interval () const;
qint32 ntrials() const;
qint32 aggressive() const;
qint32 RxBandwidth() const;
double degrade() const;
double txDelay() const;
bool id_after_73 () const;
bool tx_QSY_allowed () const;
bool spot_to_psk_reporter () const;
bool monitor_off_at_startup () const;
bool monitor_last_used () const;
bool log_as_RTTY () const;
bool report_in_comments () const;
bool prompt_to_log () const;
bool insert_blank () const;
bool DXCC () const;
bool ppfx() const;
bool clear_DX () const;
bool miles () const;
bool quick_call () const;
bool disable_TX_on_73 () const;
int watchdog () const;
bool TX_messages () const;
bool split_mode () const;
bool enable_VHF_features () const;
bool decode_at_52s () const;
bool single_decode () const;
bool twoPass() const;
bool bFox() const;
bool bHound() const;
bool x2ToneSpacing() const;
bool x4ToneSpacing() const;
bool contestMode() const;
bool MyDx() const;
bool CQMyN() const;
bool NDxG() const;
bool NN() const;
bool EMEonly() const;
bool post_decodes () const;
QString opCall() const;
QString udp_server_name () const;
port_type udp_server_port () const;
QString n1mm_server_name () const;
port_type n1mm_server_port () const;
bool valid_n1mm_info () const;
bool broadcast_to_n1mm() const;
bool accept_udp_requests () const;
bool udpWindowToFront () const;
bool udpWindowRestore () const;
Bands * bands ();
Bands const * bands () const;
IARURegions::Region region () const;
FrequencyList_v2 * frequencies ();
FrequencyList_v2 const * frequencies () const;
StationList * stations ();
StationList const * stations () const;
QStringListModel * macros ();
QStringListModel const * macros () const;
QDir save_directory () const;
QDir azel_directory () const;
QString rig_name () const;
Type2MsgGen type_2_msg_gen () const;
QColor color_CQ () const;
QColor color_MyCall () const;
QColor color_TxMsg () const;
QColor color_DXCC () const;
QColor color_NewCall () const;
bool pwrBandTxMemory () const;
bool pwrBandTuneMemory () const;
struct CalibrationParams
{
CalibrationParams ()
: intercept {0.}
, slope_ppm {0.}
{
}
CalibrationParams (double the_intercept, double the_slope_ppm)
: intercept {the_intercept}
, slope_ppm {the_slope_ppm}
{
}
double intercept; // Hertz
double slope_ppm; // Hertz
};
// Temporarily enable or disable calibration adjustments.
void enable_calibration (bool = true);
// Set the calibration parameters and enable calibration corrections.
void set_calibration (CalibrationParams);
// Set the dynamic grid which is only used if configuration setting is enabled.
void set_location (QString const&);
// This method queries if a CAT and PTT connection is operational.
bool is_transceiver_online () const;
// Start the rig connection, safe and normal to call when rig is
// already open.
bool transceiver_online ();
// check if a real rig is configured
bool is_dummy_rig () const;
// Frequency resolution of the rig
//
// 0 - 1Hz
// 1 - 10Hz rounded
// -1 - 10Hz truncated
// 2 - 100Hz rounded
// -2 - 100Hz truncated
int transceiver_resolution () const;
// Close down connection to rig.
void transceiver_offline ();
// Set transceiver frequency in Hertz.
Q_SLOT void transceiver_frequency (Frequency);
// Setting a non zero TX frequency means split operation
// rationalise_mode means ensure TX uses same mode as RX.
Q_SLOT void transceiver_tx_frequency (Frequency = 0u);
// Set transceiver mode.
//
// Rationalise means ensure TX uses same mode as RX.
Q_SLOT void transceiver_mode (MODE);
// Set/unset PTT.
//
// Note that this must be called even if VOX PTT is selected since
// the "Emulate Split" mode requires PTT information to coordinate
// frequency changes.
Q_SLOT void transceiver_ptt (bool = true);
// Attempt to (re-)synchronise transceiver state.
//
// Force signal guarantees either a transceiver_update or a
// transceiver_failure signal.
//
// The enforce_mode_and_split parameter ensures that future
// transceiver updates have the correct mode and split setting
// i.e. the transceiver is ready for use.
Q_SLOT void sync_transceiver (bool force_signal = false, bool enforce_mode_and_split = false);
//
// These signals indicate a font has been selected and accepted for
// the application text and decoded text respectively.
//
Q_SIGNAL void text_font_changed (QFont);
Q_SIGNAL void decoded_text_font_changed (QFont);
//
// This signal is emitted when the UDP server changes
//
Q_SIGNAL void udp_server_changed (QString const& udp_server);
Q_SIGNAL void udp_server_port_changed (port_type server_port);
//
// These signals are emitted and reflect transceiver state changes
//
// signals a change in one of the TransceiverState members
Q_SIGNAL void transceiver_update (Transceiver::TransceiverState const&) const;
// Signals a failure of a control rig CAT or PTT connection.
//
// A failed rig CAT or PTT connection is fatal and the underlying
// connections are closed automatically. The connections can be
// re-established with a call to transceiver_online(true) assuming
// the fault condition has been rectified or is transient.
Q_SIGNAL void transceiver_failure (QString const& reason) const;
private:
class impl;
pimpl<impl> m_;
};
#if QT_VERSION < 0x050500
Q_DECLARE_METATYPE (Configuration::DataMode);
Q_DECLARE_METATYPE (Configuration::Type2MsgGen);
#endif
#if !defined (QT_NO_DEBUG_STREAM)
ENUM_QDEBUG_OPS_DECL (Configuration, DataMode);
ENUM_QDEBUG_OPS_DECL (Configuration, Type2MsgGen);
#endif
ENUM_QDATASTREAM_OPS_DECL (Configuration, DataMode);
ENUM_QDATASTREAM_OPS_DECL (Configuration, Type2MsgGen);
ENUM_CONVERSION_OPS_DECL (Configuration, DataMode);
ENUM_CONVERSION_OPS_DECL (Configuration, Type2MsgGen);
#endif
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff