Merged master 8748
This commit is contained in:
@@ -1,771 +0,0 @@
|
||||
#include "plotter.h"
|
||||
#include <math.h>
|
||||
#include <QDebug>
|
||||
#include "commons.h"
|
||||
#include "moc_plotter.cpp"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
#define MAX_SCREENSIZE 2048
|
||||
|
||||
CPlotter::CPlotter(QWidget *parent) : //CPlotter Constructor
|
||||
QFrame {parent},
|
||||
m_set_freq_action {new QAction {tr ("&Set Rx && Tx Offset"), this}},
|
||||
m_bScaleOK {false},
|
||||
m_bReference {false},
|
||||
m_bReference0 {false},
|
||||
m_fSpan {2000.0},
|
||||
m_plotZero {0},
|
||||
m_plotGain {0},
|
||||
m_plot2dGain {0},
|
||||
m_plot2dZero {0},
|
||||
m_nSubMode {0},
|
||||
m_Running {false},
|
||||
m_paintEventBusy {false},
|
||||
m_fftBinWidth {1500.0/2048.0},
|
||||
m_dialFreq {0.},
|
||||
m_sum {},
|
||||
m_dBStepSize {10},
|
||||
m_FreqUnits {1},
|
||||
m_hdivs {HORZ_DIVS},
|
||||
m_line {0},
|
||||
m_fSample {12000},
|
||||
m_nsps {6912},
|
||||
m_Percent2DScreen {30}, //percent of screen used for 2D display
|
||||
m_Percent2DScreen0 {0},
|
||||
m_rxFreq {1020},
|
||||
m_txFreq {0},
|
||||
m_startFreq {0}
|
||||
{
|
||||
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);
|
||||
|
||||
// contextual pop up menu
|
||||
setContextMenuPolicy (Qt::CustomContextMenu);
|
||||
connect (this, &QWidget::customContextMenuRequested, [this] (QPoint const& pos) {
|
||||
QMenu menu {this};
|
||||
menu.addAction (m_set_freq_action);
|
||||
auto const& connection = connect (m_set_freq_action, &QAction::triggered, [this, pos] () {
|
||||
int newFreq = FreqfromX (pos.x ()) + .5;
|
||||
emit setFreq1 (newFreq, newFreq);
|
||||
});
|
||||
menu.exec (mapToGlobal (pos));
|
||||
disconnect (connection);
|
||||
});
|
||||
}
|
||||
|
||||
CPlotter::~CPlotter() { } // Destructor
|
||||
|
||||
QSize CPlotter::minimumSizeHint() const
|
||||
{
|
||||
return QSize(50, 50);
|
||||
}
|
||||
|
||||
QSize CPlotter::sizeHint() const
|
||||
{
|
||||
return QSize(180, 180);
|
||||
}
|
||||
|
||||
void CPlotter::resizeEvent(QResizeEvent* ) //resizeEvent()
|
||||
{
|
||||
if(!size().isValid()) return;
|
||||
if( m_Size != size() or (m_bReference != m_bReference0) or
|
||||
m_Percent2DScreen != m_Percent2DScreen0) {
|
||||
m_Size = size();
|
||||
m_w = m_Size.width();
|
||||
m_h = m_Size.height();
|
||||
m_h2 = m_Percent2DScreen*m_h/100.0;
|
||||
if(m_h2>m_h-30) m_h2=m_h-30;
|
||||
if(m_bReference) m_h2=m_h-30;
|
||||
if(m_h2<1) m_h2=1;
|
||||
m_h1=m_h-m_h2;
|
||||
m_2DPixmap = QPixmap(m_Size.width(), m_h2);
|
||||
m_2DPixmap.fill(Qt::black);
|
||||
m_WaterfallPixmap = QPixmap(m_Size.width(), m_h1);
|
||||
m_OverlayPixmap = QPixmap(m_Size.width(), m_h2);
|
||||
m_OverlayPixmap.fill(Qt::black);
|
||||
m_WaterfallPixmap.fill(Qt::black);
|
||||
m_2DPixmap.fill(Qt::black);
|
||||
m_ScalePixmap = QPixmap(m_w,30);
|
||||
m_ScalePixmap.fill(Qt::white);
|
||||
m_Percent2DScreen0 = m_Percent2DScreen;
|
||||
}
|
||||
DrawOverlay();
|
||||
}
|
||||
|
||||
void CPlotter::paintEvent(QPaintEvent *) // paintEvent()
|
||||
{
|
||||
if(m_paintEventBusy) return;
|
||||
m_paintEventBusy=true;
|
||||
QPainter painter(this);
|
||||
painter.drawPixmap(0,0,m_ScalePixmap);
|
||||
painter.drawPixmap(0,30,m_WaterfallPixmap);
|
||||
painter.drawPixmap(0,m_h1,m_2DPixmap);
|
||||
m_paintEventBusy=false;
|
||||
}
|
||||
|
||||
void CPlotter::draw(float swide[], bool bScroll, bool bRed)
|
||||
{
|
||||
int j,j0;
|
||||
static int ktop=0;
|
||||
float y,y2,ymin;
|
||||
double fac = sqrt(m_binsPerPixel*m_waterfallAvg/15.0);
|
||||
double gain = fac*pow(10.0,0.02*m_plotGain);
|
||||
double gain2d = pow(10.0,0.02*(m_plot2dGain));
|
||||
|
||||
if(m_bReference != m_bReference0) resizeEvent(NULL);
|
||||
m_bReference0=m_bReference;
|
||||
|
||||
//move current data down one line (must do this before attaching a QPainter object)
|
||||
if(bScroll) m_WaterfallPixmap.scroll(0,1,0,0,m_w,m_h1);
|
||||
QPainter painter1(&m_WaterfallPixmap);
|
||||
m_2DPixmap = m_OverlayPixmap.copy(0,0,m_w,m_h2);
|
||||
QPainter painter2D(&m_2DPixmap);
|
||||
if(!painter2D.isActive()) return;
|
||||
QFont Font("Arial");
|
||||
Font.setPointSize(12);
|
||||
Font.setWeight(QFont::Normal);
|
||||
painter2D.setFont(Font);
|
||||
|
||||
if(m_bLinearAvg) {
|
||||
painter2D.setPen(Qt::yellow);
|
||||
} else if(m_bReference) {
|
||||
painter2D.setPen(Qt::blue);
|
||||
} else {
|
||||
painter2D.setPen(Qt::green);
|
||||
}
|
||||
static QPoint LineBuf[MAX_SCREENSIZE];
|
||||
static QPoint LineBuf2[MAX_SCREENSIZE];
|
||||
j=0;
|
||||
j0=int(m_startFreq/m_fftBinWidth + 0.5);
|
||||
int iz=XfromFreq(5000.0);
|
||||
int jz=iz*m_binsPerPixel;
|
||||
m_fMax=FreqfromX(iz);
|
||||
|
||||
m_line++;
|
||||
if(bScroll) {
|
||||
flat4_(swide,&iz,&m_Flatten);
|
||||
flat4_(&dec_data.savg[j0],&jz,&m_Flatten);
|
||||
}
|
||||
|
||||
ymin=1.e30;
|
||||
if(swide[0]>1.e29 and swide[0]< 1.5e30) painter1.setPen(Qt::green);
|
||||
if(swide[0]>1.4e30) painter1.setPen(Qt::yellow);
|
||||
for(int i=0; i<iz; i++) {
|
||||
y=swide[i];
|
||||
if(y<ymin) ymin=y;
|
||||
int y1 = 10.0*gain*y + 10*m_plotZero +40;
|
||||
if (y1<0) y1=0;
|
||||
if (y1>254) y1=254;
|
||||
if (swide[i]<1.e29) painter1.setPen(g_ColorTbl[y1]);
|
||||
painter1.drawPoint(i,0);
|
||||
}
|
||||
|
||||
float y2min=1.e30;
|
||||
float y2max=-1.e30;
|
||||
for(int i=0; i<iz; i++) {
|
||||
y=swide[i] - ymin;
|
||||
y2=0;
|
||||
if(m_bCurrent) y2 = gain2d*y + m_plot2dZero; //Current
|
||||
|
||||
if(bScroll) {
|
||||
float sum=0.0;
|
||||
int j=j0+m_binsPerPixel*i;
|
||||
for(int k=0; k<m_binsPerPixel; k++) {
|
||||
sum+=dec_data.savg[j++];
|
||||
}
|
||||
m_sum[i]=sum;
|
||||
}
|
||||
if(m_bCumulative) y2=gain2d*(m_sum[i]/m_binsPerPixel + m_plot2dZero);
|
||||
if(m_Flatten==0) y2 += 15; //### could do better! ###
|
||||
|
||||
if(m_bLinearAvg) { //Linear Avg (yellow)
|
||||
float sum=0.0;
|
||||
int j=j0+m_binsPerPixel*i;
|
||||
for(int k=0; k<m_binsPerPixel; k++) {
|
||||
sum+=spectra_.syellow[j++];
|
||||
}
|
||||
y2=gain2d*sum/m_binsPerPixel + m_plot2dZero;
|
||||
}
|
||||
|
||||
if(m_bReference) { //Reference (red)
|
||||
float df_ref=12000.0/6912.0;
|
||||
int j=FreqfromX(i)/df_ref + 0.5;
|
||||
y2=spectra_.ref[j] + m_plot2dZero;
|
||||
// if(gain2d>1.5) y2=spectra_.filter[j] + m_plot2dZero;
|
||||
|
||||
}
|
||||
|
||||
if(i==iz-1) {
|
||||
painter2D.drawPolyline(LineBuf,j);
|
||||
if(m_mode=="QRA64") {
|
||||
painter2D.setPen(Qt::red);
|
||||
painter2D.drawPolyline(LineBuf2,ktop);
|
||||
}
|
||||
}
|
||||
LineBuf[j].setX(i);
|
||||
LineBuf[j].setY(int(0.9*m_h2-y2*m_h2/70.0));
|
||||
if(y2<y2min) y2min=y2;
|
||||
if(y2>y2max) y2max=y2;
|
||||
j++;
|
||||
}
|
||||
|
||||
if(swide[0]>1.0e29) m_line=0;
|
||||
if(m_line == painter1.fontMetrics ().height ()) {
|
||||
painter1.setPen(Qt::white);
|
||||
QString t;
|
||||
qint64 ms = QDateTime::currentMSecsSinceEpoch() % 86400000;
|
||||
int n=(ms/1000) % m_TRperiod;
|
||||
QDateTime t1=QDateTime::currentDateTimeUtc().addSecs(-n);
|
||||
if(m_TRperiod < 60) {
|
||||
t=t1.toString("hh:mm:ss") + " " + m_rxBand;
|
||||
} else {
|
||||
t=t1.toString("hh:mm") + " " + m_rxBand;
|
||||
}
|
||||
painter1.drawText (5, painter1.fontMetrics ().ascent (), t);
|
||||
}
|
||||
|
||||
if(m_mode=="JT4" or m_mode=="QRA64") {
|
||||
QPen pen3(Qt::yellow); //Mark freqs of JT4 single-tone msgs
|
||||
painter2D.setPen(pen3);
|
||||
Font.setWeight(QFont::Bold);
|
||||
painter2D.setFont(Font);
|
||||
int x1=XfromFreq(m_rxFreq);
|
||||
y=0.2*m_h2;
|
||||
painter2D.drawText(x1-4,y,"T");
|
||||
x1=XfromFreq(m_rxFreq+250);
|
||||
painter2D.drawText(x1-4,y,"M");
|
||||
x1=XfromFreq(m_rxFreq+500);
|
||||
painter2D.drawText(x1-4,y,"R");
|
||||
x1=XfromFreq(m_rxFreq+750);
|
||||
painter2D.drawText(x1-4,y,"73");
|
||||
}
|
||||
|
||||
if(bRed) {
|
||||
std::ifstream f;
|
||||
f.open(m_redFile.toLatin1());
|
||||
if(f) {
|
||||
int x,y;
|
||||
float freq,sync;
|
||||
float slimit=6.0;
|
||||
QPen pen0(Qt::red,1);
|
||||
painter1.setPen(pen0);
|
||||
for(int i=0; i<99999; i++) {
|
||||
f >> freq >> sync;
|
||||
if(f.eof()) break;
|
||||
x=XfromFreq(freq);
|
||||
y=(sync-slimit)*3.0;
|
||||
if(y>0) {
|
||||
if(y>15.0) y=15.0;
|
||||
if(x>=0 and x<=m_w) {
|
||||
painter1.setPen(pen0);
|
||||
painter1.drawLine(x,0,x,y);
|
||||
}
|
||||
}
|
||||
}
|
||||
f.close();
|
||||
}
|
||||
// m_bDecodeFinished=false;
|
||||
}
|
||||
|
||||
update(); //trigger a new paintEvent
|
||||
m_bScaleOK=true;
|
||||
}
|
||||
|
||||
void CPlotter::drawRed(int ia, int ib, float swide[])
|
||||
{
|
||||
m_ia=ia;
|
||||
m_ib=ib;
|
||||
draw(swide,false,true);
|
||||
}
|
||||
|
||||
void CPlotter::DrawOverlay() //DrawOverlay()
|
||||
{
|
||||
if(m_OverlayPixmap.isNull()) return;
|
||||
if(m_WaterfallPixmap.isNull()) return;
|
||||
int w = m_WaterfallPixmap.width();
|
||||
int x,y,x1,x2,x3,x4,x5,x6;
|
||||
float pixperdiv;
|
||||
|
||||
double df = m_binsPerPixel*m_fftBinWidth;
|
||||
QRect rect;
|
||||
QPen penOrange(QColor(255,165,0),3);
|
||||
QPen penGreen(Qt::green, 3); //Mark Tol range with green line
|
||||
QPen penRed(Qt::red, 3); //Mark Tx freq with red
|
||||
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 = w*df;
|
||||
// int n=m_fSpan/10;
|
||||
m_freqPerDiv=10;
|
||||
if(m_fSpan>100) 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>2500) m_freqPerDiv=500;
|
||||
|
||||
pixperdiv = m_freqPerDiv/df;
|
||||
m_hdivs = w*df/m_freqPerDiv + 1.9999;
|
||||
|
||||
float xx0=float(m_startFreq)/float(m_freqPerDiv);
|
||||
xx0=xx0-int(xx0);
|
||||
int x0=xx0*pixperdiv+0.5;
|
||||
for( int i=1; i<m_hdivs; i++) { //draw vertical grids
|
||||
x = (int)((float)i*pixperdiv ) - x0;
|
||||
if(x >= 0 and x<=m_w) {
|
||||
painter.setPen(QPen(Qt::white, 1,Qt::DotLine));
|
||||
painter.drawLine(x, 0, x , m_h2);
|
||||
}
|
||||
}
|
||||
|
||||
pixperdiv = (float)m_h2 / (float)VERT_DIVS;
|
||||
painter.setPen(QPen(Qt::white, 1,Qt::DotLine));
|
||||
for( int i=1; i<VERT_DIVS; i++) { //draw horizontal grids
|
||||
y = (int)( (float)i*pixperdiv );
|
||||
painter.drawLine(0, y, w, y);
|
||||
}
|
||||
|
||||
QRect rect0;
|
||||
QPainter painter0(&m_ScalePixmap);
|
||||
painter0.initFrom(this);
|
||||
|
||||
//create Font to use for scales
|
||||
QFont Font("Arial");
|
||||
Font.setPointSize(12);
|
||||
Font.setWeight(QFont::Normal);
|
||||
painter0.setFont(Font);
|
||||
painter0.setPen(Qt::black);
|
||||
|
||||
if(m_binsPerPixel < 1) m_binsPerPixel=1;
|
||||
m_hdivs = w*df/m_freqPerDiv + 0.9999;
|
||||
|
||||
m_ScalePixmap.fill(Qt::white);
|
||||
painter0.drawRect(0, 0, w, 30);
|
||||
MakeFrequencyStrs();
|
||||
|
||||
//draw tick marks on upper scale
|
||||
pixperdiv = m_freqPerDiv/df;
|
||||
for( int i=0; i<m_hdivs; i++) { //major ticks
|
||||
x = (int)((m_xOffset+i)*pixperdiv );
|
||||
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*pixperdiv/minor;
|
||||
painter0.drawLine(x,24,x,30);
|
||||
}
|
||||
|
||||
//draw frequency values
|
||||
for( int i=0; i<=m_hdivs; i++) {
|
||||
x = (int)((m_xOffset+i)*pixperdiv - pixperdiv/2);
|
||||
if(int(x+pixperdiv/2) > 70) {
|
||||
rect0.setRect(x,0, (int)pixperdiv, 20);
|
||||
painter0.drawText(rect0, Qt::AlignHCenter|Qt::AlignVCenter,m_HDivText[i]);
|
||||
}
|
||||
}
|
||||
|
||||
float bw=9.0*12000.0/m_nsps; //JT9
|
||||
|
||||
if(m_mode=="FT8") bw=7*12000.0/1920.0; //FT8
|
||||
|
||||
if(m_mode=="JT4") { //JT4
|
||||
bw=3*11025.0/2520.0; //Max tone spacing (3/4 of actual BW)
|
||||
if(m_nSubMode==1) bw=2*bw;
|
||||
if(m_nSubMode==2) bw=4*bw;
|
||||
if(m_nSubMode==3) bw=9*bw;
|
||||
if(m_nSubMode==4) bw=18*bw;
|
||||
if(m_nSubMode==5) bw=36*bw;
|
||||
if(m_nSubMode==6) bw=72*bw;
|
||||
|
||||
painter0.setPen(penGreen);
|
||||
x1=XfromFreq(m_rxFreq-m_tol);
|
||||
x2=XfromFreq(m_rxFreq+m_tol);
|
||||
painter0.drawLine(x1,29,x2,29);
|
||||
for(int i=0; i<4; i++) {
|
||||
x1=XfromFreq(m_rxFreq+bw*i/3.0);
|
||||
int j=24;
|
||||
if(i==0) j=18;
|
||||
painter0.drawLine(x1,j,x1,30);
|
||||
}
|
||||
painter0.setPen(penRed);
|
||||
for(int i=0; i<4; i++) {
|
||||
x1=XfromFreq(m_txFreq+bw*i/3.0);
|
||||
painter0.drawLine(x1,12,x1,18);
|
||||
}
|
||||
}
|
||||
|
||||
if(m_modeTx=="JT9" and m_nSubMode>0) { //JT9
|
||||
bw=8.0*12000.0/m_nsps;
|
||||
if(m_nSubMode==1) bw=2*bw; //B
|
||||
if(m_nSubMode==2) bw=4*bw; //C
|
||||
if(m_nSubMode==3) bw=8*bw; //D
|
||||
if(m_nSubMode==4) bw=16*bw; //E
|
||||
if(m_nSubMode==5) bw=32*bw; //F
|
||||
if(m_nSubMode==6) bw=64*bw; //G
|
||||
if(m_nSubMode==7) bw=128*bw; //H
|
||||
}
|
||||
|
||||
if(m_mode=="QRA64") { //QRA64
|
||||
bw=63.0*12000.0/m_nsps;
|
||||
if(m_nSubMode==1) bw=2*bw; //B
|
||||
if(m_nSubMode==2) bw=4*bw; //C
|
||||
if(m_nSubMode==3) bw=8*bw; //D
|
||||
if(m_nSubMode==4) bw=16*bw; //E
|
||||
}
|
||||
|
||||
if(m_modeTx=="JT65") { //JT65
|
||||
bw=65.0*11025.0/4096.0;
|
||||
if(m_nSubMode==1) bw=2*bw; //B
|
||||
if(m_nSubMode==2) bw=4*bw; //C
|
||||
}
|
||||
|
||||
painter0.setPen(penGreen);
|
||||
if(m_mode=="WSPR") {
|
||||
x1=XfromFreq(1400);
|
||||
x2=XfromFreq(1600);
|
||||
painter0.drawLine(x1,29,x2,29);
|
||||
}
|
||||
|
||||
if(m_mode=="WSPR-LF") {
|
||||
x1=XfromFreq(1600);
|
||||
x2=XfromFreq(1700);
|
||||
painter0.drawLine(x1,29,x2,29);
|
||||
}
|
||||
|
||||
if(m_mode=="FreqCal") { //FreqCal
|
||||
x1=XfromFreq(m_rxFreq-m_tol);
|
||||
x2=XfromFreq(m_rxFreq+m_tol);
|
||||
painter0.drawLine(x1,29,x2,29);
|
||||
x1=XfromFreq(m_rxFreq);
|
||||
painter0.drawLine(x1,24,x1,30);
|
||||
}
|
||||
|
||||
if(m_mode=="JT9" or m_mode=="JT65" or m_mode=="JT9+JT65" or m_mode=="QRA64" or m_mode=="FT8") {
|
||||
|
||||
if(m_mode=="QRA64" or (m_mode=="JT65" and m_bVHF)) {
|
||||
painter0.setPen(penGreen);
|
||||
x1=XfromFreq(m_rxFreq-m_tol);
|
||||
x2=XfromFreq(m_rxFreq+m_tol);
|
||||
painter0.drawLine(x1,28,x2,28);
|
||||
x1=XfromFreq(m_rxFreq);
|
||||
painter0.drawLine(x1,24,x1,30);
|
||||
|
||||
if(m_mode=="JT65") {
|
||||
painter0.setPen(penOrange);
|
||||
x3=XfromFreq(m_rxFreq+20.0*bw/65.0); //RO
|
||||
painter0.drawLine(x3,24,x3,30);
|
||||
x4=XfromFreq(m_rxFreq+30.0*bw/65.0); //RRR
|
||||
painter0.drawLine(x4,24,x4,30);
|
||||
x5=XfromFreq(m_rxFreq+40.0*bw/65.0); //73
|
||||
painter0.drawLine(x5,24,x5,30);
|
||||
}
|
||||
painter0.setPen(penGreen);
|
||||
x6=XfromFreq(m_rxFreq+bw); //Highest tone
|
||||
painter0.drawLine(x6,24,x6,30);
|
||||
|
||||
} else {
|
||||
painter0.setPen(penGreen);
|
||||
x1=XfromFreq(m_rxFreq);
|
||||
x2=XfromFreq(m_rxFreq+bw);
|
||||
painter0.drawLine(x1,24,x1,30);
|
||||
painter0.drawLine(x1,28,x2,28);
|
||||
painter0.drawLine(x2,24,x2,30);
|
||||
}
|
||||
}
|
||||
|
||||
if(m_mode=="JT9" or m_mode=="JT65" or m_mode=="JT9+JT65" or
|
||||
m_mode.mid(0,4)=="WSPR" or m_mode=="QRA64" or m_mode=="FT8") {
|
||||
painter0.setPen(penRed);
|
||||
x1=XfromFreq(m_txFreq);
|
||||
x2=XfromFreq(m_txFreq+bw);
|
||||
if(m_mode=="WSPR") {
|
||||
bw=4*12000.0/8192.0; //WSPR
|
||||
x1=XfromFreq(m_txFreq-0.5*bw);
|
||||
x2=XfromFreq(m_txFreq+0.5*bw);
|
||||
}
|
||||
if(m_mode=="WSPR-LF") {
|
||||
bw=3*12000.0/8640.0; //WSPR-LF
|
||||
x1=XfromFreq(m_txFreq-0.5*bw);
|
||||
x2=XfromFreq(m_txFreq+0.5*bw);
|
||||
}
|
||||
painter0.drawLine(x1,17,x1,21);
|
||||
painter0.drawLine(x1,17,x2,17);
|
||||
painter0.drawLine(x2,17,x2,21);
|
||||
}
|
||||
|
||||
if(m_mode=="JT9+JT65") {
|
||||
QPen pen2(Qt::blue, 3); //Mark the JT65 | JT9 divider
|
||||
painter0.setPen(pen2);
|
||||
x1=XfromFreq(m_fMin);
|
||||
if(x1<2) x1=2;
|
||||
x2=x1+30;
|
||||
painter0.drawLine(x1,8,x1,28);
|
||||
}
|
||||
|
||||
if(m_dialFreq>10.13 and m_dialFreq< 10.15 and m_mode.mid(0,4)!="WSPR") {
|
||||
float f1=1.0e6*(10.1401 - m_dialFreq);
|
||||
float f2=f1+200.0;
|
||||
x1=XfromFreq(f1);
|
||||
x2=XfromFreq(f2);
|
||||
if(x1<=m_w and x2>=0) {
|
||||
painter0.setPen(penOrange); //Mark WSPR sub-band orange
|
||||
painter0.drawLine(x1,9,x2,9);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CPlotter::MakeFrequencyStrs() //MakeFrequencyStrs
|
||||
{
|
||||
int f=(m_startFreq+m_freqPerDiv-1)/m_freqPerDiv;
|
||||
f*=m_freqPerDiv;
|
||||
m_xOffset=float(f-m_startFreq)/m_freqPerDiv;
|
||||
for(int i=0; i<=m_hdivs; i++) {
|
||||
m_HDivText[i].setNum(f);
|
||||
f+=m_freqPerDiv;
|
||||
}
|
||||
}
|
||||
|
||||
int CPlotter::XfromFreq(float f) //XfromFreq()
|
||||
{
|
||||
// float w = m_WaterfallPixmap.width();
|
||||
int x = int(m_w * (f - m_startFreq)/m_fSpan + 0.5);
|
||||
if(x<0 ) return 0;
|
||||
if(x>m_w) return m_w;
|
||||
return x;
|
||||
}
|
||||
|
||||
float CPlotter::FreqfromX(int x) //FreqfromX()
|
||||
{
|
||||
return float(m_startFreq + x*m_binsPerPixel*m_fftBinWidth);
|
||||
}
|
||||
|
||||
void CPlotter::SetRunningState(bool running) //SetRunningState()
|
||||
{
|
||||
m_Running = running;
|
||||
}
|
||||
|
||||
void CPlotter::setPlotZero(int plotZero) //setPlotZero()
|
||||
{
|
||||
m_plotZero=plotZero;
|
||||
}
|
||||
|
||||
int CPlotter::plotZero() //PlotZero()
|
||||
{
|
||||
return m_plotZero;
|
||||
}
|
||||
|
||||
void CPlotter::setPlotGain(int plotGain) //setPlotGain()
|
||||
{
|
||||
m_plotGain=plotGain;
|
||||
}
|
||||
|
||||
int CPlotter::plotGain() //plotGain()
|
||||
{
|
||||
return m_plotGain;
|
||||
}
|
||||
|
||||
int CPlotter::plot2dGain() //plot2dGain
|
||||
{
|
||||
return m_plot2dGain;
|
||||
}
|
||||
|
||||
void CPlotter::setPlot2dGain(int n) //setPlot2dGain
|
||||
{
|
||||
m_plot2dGain=n;
|
||||
update();
|
||||
}
|
||||
|
||||
int CPlotter::plot2dZero() //plot2dZero
|
||||
{
|
||||
return m_plot2dZero;
|
||||
}
|
||||
|
||||
void CPlotter::setPlot2dZero(int plot2dZero) //setPlot2dZero
|
||||
{
|
||||
m_plot2dZero=plot2dZero;
|
||||
}
|
||||
|
||||
void CPlotter::setStartFreq(int f) //SetStartFreq()
|
||||
{
|
||||
m_startFreq=f;
|
||||
resizeEvent(NULL);
|
||||
update();
|
||||
}
|
||||
|
||||
int CPlotter::startFreq() //startFreq()
|
||||
{
|
||||
return m_startFreq;
|
||||
}
|
||||
|
||||
int CPlotter::plotWidth(){return m_WaterfallPixmap.width();} //plotWidth
|
||||
void CPlotter::UpdateOverlay() {DrawOverlay();} //UpdateOverlay
|
||||
void CPlotter::setDataFromDisk(bool b) {m_dataFromDisk=b;} //setDataFromDisk
|
||||
|
||||
void CPlotter::setRxRange(int fMin) //setRxRange
|
||||
{
|
||||
m_fMin=fMin;
|
||||
}
|
||||
|
||||
void CPlotter::setBinsPerPixel(int n) //setBinsPerPixel
|
||||
{
|
||||
m_binsPerPixel = n;
|
||||
DrawOverlay(); //Redraw scales and ticks
|
||||
update(); //trigger a new paintEvent}
|
||||
}
|
||||
|
||||
int CPlotter::binsPerPixel() //binsPerPixel
|
||||
{
|
||||
return m_binsPerPixel;
|
||||
}
|
||||
|
||||
void CPlotter::setWaterfallAvg(int n) //setBinsPerPixel
|
||||
{
|
||||
m_waterfallAvg = n;
|
||||
}
|
||||
|
||||
void CPlotter::setRxFreq (int x) //setRxFreq
|
||||
{
|
||||
m_rxFreq = x; // x is freq in Hz
|
||||
DrawOverlay();
|
||||
update();
|
||||
}
|
||||
|
||||
int CPlotter::rxFreq() {return m_rxFreq;} //rxFreq
|
||||
|
||||
void CPlotter::mouseReleaseEvent (QMouseEvent * event)
|
||||
{
|
||||
if (Qt::LeftButton == event->button ()) {
|
||||
int x=event->x();
|
||||
if(x<0) x=0;
|
||||
if(x>m_Size.width()) x=m_Size.width();
|
||||
bool ctrl = (event->modifiers() & Qt::ControlModifier);
|
||||
bool shift = (event->modifiers() & Qt::ShiftModifier);
|
||||
int newFreq = int(FreqfromX(x)+0.5);
|
||||
int oldTxFreq = m_txFreq;
|
||||
int oldRxFreq = m_rxFreq;
|
||||
if (ctrl) {
|
||||
emit setFreq1 (newFreq, newFreq);
|
||||
} else if (shift) {
|
||||
emit setFreq1 (oldRxFreq, newFreq);
|
||||
} else {
|
||||
emit setFreq1(newFreq,oldTxFreq);
|
||||
}
|
||||
|
||||
int n=1;
|
||||
if(ctrl) n+=100;
|
||||
emit freezeDecode1(n);
|
||||
}
|
||||
else {
|
||||
event->ignore (); // let parent handle
|
||||
}
|
||||
}
|
||||
|
||||
void CPlotter::mouseDoubleClickEvent (QMouseEvent * event)
|
||||
{
|
||||
if (Qt::LeftButton == event->button ()) {
|
||||
bool ctrl = (event->modifiers() & Qt::ControlModifier);
|
||||
int n=2;
|
||||
if(ctrl) n+=100;
|
||||
emit freezeDecode1(n);
|
||||
}
|
||||
else {
|
||||
event->ignore (); // let parent handle
|
||||
}
|
||||
}
|
||||
|
||||
void CPlotter::setNsps(int ntrperiod, int nsps) //setNsps
|
||||
{
|
||||
m_TRperiod=ntrperiod;
|
||||
m_nsps=nsps;
|
||||
m_fftBinWidth=1500.0/2048.0;
|
||||
if(m_nsps==15360) m_fftBinWidth=1500.0/2048.0;
|
||||
if(m_nsps==40960) m_fftBinWidth=1500.0/6144.0;
|
||||
if(m_nsps==82944) m_fftBinWidth=1500.0/12288.0;
|
||||
if(m_nsps==252000) m_fftBinWidth=1500.0/32768.0;
|
||||
DrawOverlay(); //Redraw scales and ticks
|
||||
update(); //trigger a new paintEvent}
|
||||
}
|
||||
|
||||
void CPlotter::setTxFreq(int n) //setTxFreq
|
||||
{
|
||||
m_txFreq=n;
|
||||
DrawOverlay();
|
||||
update();
|
||||
}
|
||||
|
||||
void CPlotter::setMode(QString mode) //setMode
|
||||
{
|
||||
m_mode=mode;
|
||||
}
|
||||
|
||||
void CPlotter::setSubMode(int n) //setSubMode
|
||||
{
|
||||
m_nSubMode=n;
|
||||
}
|
||||
|
||||
void CPlotter::setModeTx(QString modeTx) //setModeTx
|
||||
{
|
||||
m_modeTx=modeTx;
|
||||
}
|
||||
|
||||
int CPlotter::Fmax()
|
||||
{
|
||||
return m_fMax;
|
||||
}
|
||||
|
||||
void CPlotter::setDialFreq(double d)
|
||||
{
|
||||
m_dialFreq=d;
|
||||
DrawOverlay();
|
||||
update();
|
||||
}
|
||||
|
||||
void CPlotter::setRxBand(QString band)
|
||||
{
|
||||
m_rxBand=band;
|
||||
}
|
||||
|
||||
void CPlotter::setFlatten(bool b1, bool b2)
|
||||
{
|
||||
m_Flatten=0;
|
||||
if(b1) m_Flatten=1;
|
||||
if(b2) m_Flatten=2;
|
||||
}
|
||||
|
||||
void CPlotter::setTol(int n) //setTol()
|
||||
{
|
||||
m_tol=n;
|
||||
DrawOverlay();
|
||||
}
|
||||
|
||||
void CPlotter::setColours(QVector<QColor> const& cl)
|
||||
{
|
||||
g_ColorTbl = cl;
|
||||
}
|
||||
|
||||
void CPlotter::SetPercent2DScreen(int percent)
|
||||
{
|
||||
m_Percent2DScreen=percent;
|
||||
resizeEvent(NULL);
|
||||
update();
|
||||
}
|
||||
void CPlotter::setVHF(bool bVHF)
|
||||
{
|
||||
m_bVHF=bVHF;
|
||||
}
|
||||
|
||||
void CPlotter::setRedFile(QString fRed)
|
||||
{
|
||||
m_redFile=fRed;
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
File diff suppressed because it is too large
Load Diff
@@ -1,165 +0,0 @@
|
||||
#include "MessageAggregatorMainWindow.hpp"
|
||||
|
||||
#include <QtWidgets>
|
||||
#include <QDateTime>
|
||||
|
||||
#include "DecodesModel.hpp"
|
||||
#include "BeaconsModel.hpp"
|
||||
#include "ClientWidget.hpp"
|
||||
|
||||
using port_type = MessageServer::port_type;
|
||||
|
||||
namespace
|
||||
{
|
||||
char const * const headings[] = {
|
||||
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Time On"),
|
||||
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Time Off"),
|
||||
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Callsign"),
|
||||
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Grid"),
|
||||
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Name"),
|
||||
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Frequency"),
|
||||
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Mode"),
|
||||
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Sent"),
|
||||
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Rec'd"),
|
||||
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Power"),
|
||||
QT_TRANSLATE_NOOP ("MessageAggregatorMainWindow", "Comments"),
|
||||
};
|
||||
}
|
||||
|
||||
MessageAggregatorMainWindow::MessageAggregatorMainWindow ()
|
||||
: log_ {new QStandardItemModel {0, 11, this}}
|
||||
, decodes_model_ {new DecodesModel {this}}
|
||||
, beacons_model_ {new BeaconsModel {this}}
|
||||
, server_ {new MessageServer {this}}
|
||||
, multicast_group_line_edit_ {new QLineEdit}
|
||||
, log_table_view_ {new QTableView}
|
||||
{
|
||||
// logbook
|
||||
int column {0};
|
||||
for (auto const& heading : headings)
|
||||
{
|
||||
log_->setHeaderData (column++, Qt::Horizontal, tr (heading));
|
||||
}
|
||||
connect (server_, &MessageServer::qso_logged, this, &MessageAggregatorMainWindow::log_qso);
|
||||
|
||||
// menu bar
|
||||
auto file_menu = menuBar ()->addMenu (tr ("&File"));
|
||||
|
||||
auto exit_action = new QAction {tr ("E&xit"), this};
|
||||
exit_action->setShortcuts (QKeySequence::Quit);
|
||||
exit_action->setToolTip (tr ("Exit the application"));
|
||||
file_menu->addAction (exit_action);
|
||||
connect (exit_action, &QAction::triggered, this, &MessageAggregatorMainWindow::close);
|
||||
|
||||
view_menu_ = menuBar ()->addMenu (tr ("&View"));
|
||||
|
||||
// central layout
|
||||
auto central_layout = new QVBoxLayout;
|
||||
|
||||
// server details
|
||||
auto port_spin_box = new QSpinBox;
|
||||
port_spin_box->setMinimum (1);
|
||||
port_spin_box->setMaximum (std::numeric_limits<port_type>::max ());
|
||||
auto group_box_layout = new QFormLayout;
|
||||
group_box_layout->addRow (tr ("Port number:"), port_spin_box);
|
||||
group_box_layout->addRow (tr ("Multicast Group (blank for unicast server):"), multicast_group_line_edit_);
|
||||
auto group_box = new QGroupBox {tr ("Server Details")};
|
||||
group_box->setLayout (group_box_layout);
|
||||
central_layout->addWidget (group_box);
|
||||
|
||||
log_table_view_->setModel (log_);
|
||||
log_table_view_->verticalHeader ()->hide ();
|
||||
central_layout->addWidget (log_table_view_);
|
||||
|
||||
// central widget
|
||||
auto central_widget = new QWidget;
|
||||
central_widget->setLayout (central_layout);
|
||||
|
||||
// main window setup
|
||||
setCentralWidget (central_widget);
|
||||
setDockOptions (AnimatedDocks | AllowNestedDocks | AllowTabbedDocks);
|
||||
setTabPosition (Qt::BottomDockWidgetArea, QTabWidget::North);
|
||||
|
||||
// connect up server
|
||||
connect (server_, &MessageServer::error, [this] (QString const& message) {
|
||||
QMessageBox::warning (this, QApplication::applicationName (), tr ("Network Error"), message);
|
||||
});
|
||||
connect (server_, &MessageServer::client_opened, this, &MessageAggregatorMainWindow::add_client);
|
||||
connect (server_, &MessageServer::client_closed, this, &MessageAggregatorMainWindow::remove_client);
|
||||
connect (server_, &MessageServer::client_closed, decodes_model_, &DecodesModel::clear_decodes);
|
||||
connect (server_, &MessageServer::client_closed, beacons_model_, &BeaconsModel::clear_decodes);
|
||||
connect (server_, &MessageServer::decode, [this] (bool is_new, QString const& id, QTime time
|
||||
, qint32 snr, float delta_time
|
||||
, quint32 delta_frequency, QString const& mode
|
||||
, QString const& message, bool low_confidence) {
|
||||
decodes_model_->add_decode (is_new, id, time, snr, delta_time, delta_frequency, mode, message
|
||||
, low_confidence, dock_widgets_[id]->fast_mode ());});
|
||||
connect (server_, &MessageServer::WSPR_decode, beacons_model_, &BeaconsModel::add_beacon_spot);
|
||||
connect (server_, &MessageServer::clear_decodes, decodes_model_, &DecodesModel::clear_decodes);
|
||||
connect (server_, &MessageServer::clear_decodes, beacons_model_, &BeaconsModel::clear_decodes);
|
||||
connect (decodes_model_, &DecodesModel::reply, server_, &MessageServer::reply);
|
||||
|
||||
// UI behaviour
|
||||
connect (port_spin_box, static_cast<void (QSpinBox::*)(int)> (&QSpinBox::valueChanged)
|
||||
, [this] (port_type port) {server_->start (port);});
|
||||
connect (multicast_group_line_edit_, &QLineEdit::editingFinished, [this, port_spin_box] () {
|
||||
server_->start (port_spin_box->value (), QHostAddress {multicast_group_line_edit_->text ()});
|
||||
});
|
||||
|
||||
port_spin_box->setValue (2237); // start up in unicast mode
|
||||
show ();
|
||||
}
|
||||
|
||||
void MessageAggregatorMainWindow::log_qso (QString const& /*id*/, QDateTime timeOff, QString const& dx_call, QString const& dx_grid
|
||||
, Frequency dial_frequency, QString const& mode, QString const& report_sent
|
||||
, QString const& report_received, QString const& tx_power, QString const& comments
|
||||
, QString const& name, QDateTime timeOn)
|
||||
{
|
||||
QList<QStandardItem *> row;
|
||||
row << new QStandardItem {timeOn.toString ("dd-MMM-yyyy hh:mm:ss")}
|
||||
<< new QStandardItem {timeOff.toString ("dd-MMM-yyyy hh:mm:ss")}
|
||||
<< new QStandardItem {dx_call}
|
||||
<< new QStandardItem {dx_grid}
|
||||
<< new QStandardItem {name}
|
||||
<< new QStandardItem {Radio::frequency_MHz_string (dial_frequency)}
|
||||
<< new QStandardItem {mode}
|
||||
<< new QStandardItem {report_sent}
|
||||
<< new QStandardItem {report_received}
|
||||
<< new QStandardItem {tx_power}
|
||||
<< new QStandardItem {comments};
|
||||
log_->appendRow (row);
|
||||
log_table_view_->resizeColumnsToContents ();
|
||||
log_table_view_->horizontalHeader ()->setStretchLastSection (true);
|
||||
log_table_view_->scrollToBottom ();
|
||||
}
|
||||
|
||||
void MessageAggregatorMainWindow::add_client (QString const& id, QString const& version, QString const& revision)
|
||||
{
|
||||
auto dock = new ClientWidget {decodes_model_, beacons_model_, id, version, revision, this};
|
||||
dock->setAttribute (Qt::WA_DeleteOnClose);
|
||||
auto view_action = dock->toggleViewAction ();
|
||||
view_action->setEnabled (true);
|
||||
view_menu_->addAction (view_action);
|
||||
addDockWidget (Qt::BottomDockWidgetArea, dock);
|
||||
connect (server_, &MessageServer::status_update, dock, &ClientWidget::update_status);
|
||||
connect (server_, &MessageServer::decode, dock, &ClientWidget::decode_added);
|
||||
connect (server_, &MessageServer::WSPR_decode, dock, &ClientWidget::beacon_spot_added);
|
||||
connect (dock, &ClientWidget::do_reply, decodes_model_, &DecodesModel::do_reply);
|
||||
connect (dock, &ClientWidget::do_halt_tx, server_, &MessageServer::halt_tx);
|
||||
connect (dock, &ClientWidget::do_free_text, server_, &MessageServer::free_text);
|
||||
connect (view_action, &QAction::toggled, dock, &ClientWidget::setVisible);
|
||||
dock_widgets_[id] = dock;
|
||||
server_->replay (id);
|
||||
}
|
||||
|
||||
void MessageAggregatorMainWindow::remove_client (QString const& id)
|
||||
{
|
||||
auto iter = dock_widgets_.find (id);
|
||||
if (iter != std::end (dock_widgets_))
|
||||
{
|
||||
(*iter)->close ();
|
||||
dock_widgets_.erase (iter);
|
||||
}
|
||||
}
|
||||
|
||||
#include "moc_MessageAggregatorMainWindow.cpp"
|
||||
@@ -1,180 +0,0 @@
|
||||
48 128
|
||||
9 4
|
||||
9 9 9 9 9 8 8 8 8 8 9 9 8 8 9 9 8 8 8 8 9 9 9 8 9 9 9 9 9 9 8 8 8 9 8 9 9 9 8 9 8 8 8 9 8 8 8 9
|
||||
3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
|
||||
1 17 34 51 66 81 99 111 124
|
||||
2 18 35 50 67 82 100 112 125
|
||||
3 19 36 52 68 82 101 111 126
|
||||
2 20 36 51 69 83 102 113 127
|
||||
4 19 37 53 66 84 103 114 128
|
||||
5 21 38 54 70 85 92 114 0
|
||||
6 22 39 55 66 85 96 110 0
|
||||
7 23 32 56 71 86 103 115 0
|
||||
8 20 40 55 72 86 104 116 0
|
||||
9 19 41 57 73 87 105 116 0
|
||||
10 24 36 56 74 88 105 117 125
|
||||
10 17 33 47 75 89 106 118 128
|
||||
11 21 42 51 76 87 107 119 0
|
||||
1 25 40 58 74 84 107 113 0
|
||||
12 22 42 49 77 90 108 118 125
|
||||
13 26 43 59 68 89 104 120 124
|
||||
13 22 44 57 75 91 109 113 0
|
||||
12 23 37 46 78 88 107 112 0
|
||||
3 27 34 60 65 87 109 118 0
|
||||
6 27 45 61 79 89 98 112 0
|
||||
14 28 34 62 72 92 106 112 127
|
||||
8 27 42 59 71 92 110 121 126
|
||||
15 20 46 57 79 93 101 115 124
|
||||
9 29 45 62 74 94 108 121 0
|
||||
8 30 38 63 73 95 109 111 128
|
||||
16 29 47 64 69 96 109 117 126
|
||||
16 23 48 63 76 94 110 116 125
|
||||
7 25 39 52 70 97 106 117 124
|
||||
4 26 45 63 67 83 90 119 123
|
||||
15 28 39 50 76 88 103 121 123
|
||||
15 26 33 58 65 97 102 122 0
|
||||
14 31 47 52 77 81 93 116 0
|
||||
14 24 37 61 71 82 99 122 0
|
||||
4 31 40 54 80 91 106 115 122
|
||||
5 32 41 58 77 98 104 117 0
|
||||
9 18 49 65 79 85 104 119 128
|
||||
10 30 43 60 69 84 108 115 123
|
||||
1 18 43 48 73 91 98 114 127
|
||||
3 21 46 64 67 86 108 113 0
|
||||
5 24 48 55 75 93 107 120 126
|
||||
2 32 44 62 80 95 99 114 0
|
||||
16 28 41 59 80 83 100 118 0
|
||||
11 33 35 53 72 96 105 111 0
|
||||
11 25 44 60 78 90 100 120 122
|
||||
6 31 35 56 70 95 102 121 0
|
||||
12 17 50 54 68 94 105 119 0
|
||||
13 29 38 53 78 97 110 123 0
|
||||
7 30 49 61 64 81 101 120 127
|
||||
1 14 38 0
|
||||
2 4 41 0
|
||||
3 19 39 0
|
||||
5 29 34 0
|
||||
6 35 40 0
|
||||
7 20 45 0
|
||||
8 28 48 0
|
||||
9 22 25 0
|
||||
10 24 36 0
|
||||
11 12 37 0
|
||||
13 43 44 0
|
||||
15 18 46 0
|
||||
16 17 47 0
|
||||
21 32 33 0
|
||||
23 30 31 0
|
||||
26 27 42 0
|
||||
1 12 46 0
|
||||
2 36 38 0
|
||||
3 5 10 0
|
||||
4 9 23 0
|
||||
6 13 39 0
|
||||
7 15 17 0
|
||||
8 18 27 0
|
||||
11 33 40 0
|
||||
14 28 44 0
|
||||
16 29 31 0
|
||||
19 20 22 0
|
||||
21 30 42 0
|
||||
24 26 47 0
|
||||
25 37 48 0
|
||||
32 34 45 0
|
||||
8 35 41 0
|
||||
12 31 43 0
|
||||
1 19 21 0
|
||||
2 43 45 0
|
||||
3 4 11 0
|
||||
5 18 33 0
|
||||
6 25 47 0
|
||||
7 28 30 0
|
||||
9 14 34 0
|
||||
10 35 42 0
|
||||
13 15 22 0
|
||||
16 37 38 0
|
||||
17 41 44 0
|
||||
20 24 29 0
|
||||
18 23 39 0
|
||||
12 26 32 0
|
||||
27 38 40 0
|
||||
15 36 48 0
|
||||
2 30 46 0
|
||||
1 4 13 0
|
||||
3 28 32 0
|
||||
5 43 47 0
|
||||
6 34 46 0
|
||||
7 9 40 0
|
||||
8 11 45 0
|
||||
10 17 23 0
|
||||
14 31 35 0
|
||||
16 22 42 0
|
||||
19 37 44 0
|
||||
20 33 48 0
|
||||
21 24 41 0
|
||||
25 27 29 0
|
||||
26 39 48 0
|
||||
19 31 36 0
|
||||
1 5 7 0
|
||||
2 29 39 0
|
||||
3 16 46 0
|
||||
4 26 37 0
|
||||
6 28 45 0
|
||||
8 22 33 0
|
||||
9 21 43 0
|
||||
10 25 38 0
|
||||
11 14 24 0
|
||||
12 17 40 0
|
||||
13 27 30 0
|
||||
15 32 35 0
|
||||
18 44 47 0
|
||||
20 23 36 0
|
||||
34 41 42 0
|
||||
1 32 48 0
|
||||
2 3 33 0
|
||||
4 29 42 0
|
||||
5 14 37 0
|
||||
6 7 36 0
|
||||
8 9 39 0
|
||||
10 13 19 0
|
||||
11 18 30 0
|
||||
12 16 20 0
|
||||
15 29 44 0
|
||||
17 34 38 0
|
||||
6 21 22 0
|
||||
23 32 40 0
|
||||
24 27 46 0
|
||||
25 41 45 0
|
||||
7 26 43 0
|
||||
28 31 47 0
|
||||
20 35 38 0
|
||||
1 33 41 0
|
||||
2 42 44 0
|
||||
3 23 48 0
|
||||
4 31 45 0
|
||||
5 8 30 0
|
||||
9 16 35 36
|
||||
10 11 43 46
|
||||
12 21 28 34
|
||||
13 14 18 40
|
||||
15 24 37 39
|
||||
17 19 25 26
|
||||
7 22 27 47
|
||||
1 3 25 43
|
||||
2 18 20 21
|
||||
4 14 17 39
|
||||
5 6 38 41
|
||||
8 23 34 37
|
||||
9 10 27 32
|
||||
11 26 28 35
|
||||
12 15 19 42
|
||||
13 29 36 46
|
||||
16 40 44 48
|
||||
22 24 30 45
|
||||
31 33 34 44
|
||||
29 30 37 47
|
||||
1 16 23 28
|
||||
2 11 15 27
|
||||
3 22 26 40
|
||||
4 21 38 48
|
||||
5 12 25 36
|
||||
@@ -0,0 +1,482 @@
|
||||
subroutine bpdecode204(llr,apmask,maxiterations,decoded,cw,nharderror,iter)
|
||||
!
|
||||
! A log-domain belief propagation decoder for the (204,68) code.
|
||||
!
|
||||
integer, parameter:: N=204, K=68, M=N-K
|
||||
integer*1 codeword(N),cw(N),apmask(N)
|
||||
integer colorder(N)
|
||||
integer*1 decoded(K)
|
||||
integer Nm(6,M) ! 4, 5, or 6 bits per check
|
||||
integer Mn(3,N) ! 3 checks per bit
|
||||
integer synd(M)
|
||||
real tov(3,N)
|
||||
real toc(6,M)
|
||||
real tanhtoc(6,M)
|
||||
real zn(N)
|
||||
real llr(N)
|
||||
real Tmn
|
||||
integer nrw(M)
|
||||
|
||||
data colorder/ &
|
||||
0, 1, 2, 3, 4, 5, 47, 6, 7, 8, 9, 10, 11, 12, 58, 55, 13, &
|
||||
14, 15, 46, 17, 18, 60, 19, 20, 21, 22, 23, 24, 25, 57, 26, 27, 49, &
|
||||
28, 52, 65, 16, 50, 73, 59, 68, 63, 29, 30, 31, 32, 51, 62, 56, 66, &
|
||||
45, 33, 34, 53, 67, 35, 36, 37, 61, 69, 54, 38, 71, 82, 39, 77, 80, &
|
||||
83, 78, 84, 48, 41, 85, 40, 64, 75, 96, 74, 72, 76, 86, 87, 89, 90, &
|
||||
79, 70, 92, 99, 93,101, 95,100, 97, 94, 42, 98,103,105,102, 43,104, &
|
||||
88, 44,106, 81,107,110,108,111,112,109,113,114,117,118,116,121,115, &
|
||||
119,122,120,125,129,124,127,126,128, 91,123,133,131,130,134,135,137, &
|
||||
136,132,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152, &
|
||||
153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169, &
|
||||
170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186, &
|
||||
187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203/
|
||||
|
||||
data Mn/ &
|
||||
1, 38, 107, &
|
||||
2, 7, 114, &
|
||||
3, 48, 106, &
|
||||
4, 79, 94, &
|
||||
5, 97, 108, &
|
||||
6, 50, 122, &
|
||||
8, 78, 134, &
|
||||
9, 55, 65, &
|
||||
10, 62, 100, &
|
||||
11, 16, 99, &
|
||||
12, 113, 119, &
|
||||
13, 31, 125, &
|
||||
14, 15, 127, &
|
||||
17, 87, 103, &
|
||||
18, 81, 98, &
|
||||
19, 43, 77, &
|
||||
20, 102, 130, &
|
||||
21, 36, 111, &
|
||||
22, 23, 60, &
|
||||
24, 39, 112, &
|
||||
25, 37, 42, &
|
||||
26, 41, 51, &
|
||||
27, 67, 70, &
|
||||
28, 64, 136, &
|
||||
29, 61, 68, &
|
||||
30, 91, 124, &
|
||||
32, 80, 121, &
|
||||
33, 40, 117, &
|
||||
34, 35, 90, &
|
||||
44, 88, 93, &
|
||||
45, 128, 133, &
|
||||
46, 56, 69, &
|
||||
47, 49, 52, &
|
||||
53, 76, 131, &
|
||||
54, 104, 116, &
|
||||
57, 84, 86, &
|
||||
58, 120, 135, &
|
||||
59, 75, 92, &
|
||||
63, 71, 109, &
|
||||
66, 74, 126, &
|
||||
72, 85, 105, &
|
||||
73, 82, 95, &
|
||||
83, 89, 123, &
|
||||
96, 115, 118, &
|
||||
101, 110, 129, &
|
||||
52, 99, 132, &
|
||||
1, 3, 20, &
|
||||
2, 77, 89, &
|
||||
4, 72, 75, &
|
||||
5, 34, 79, &
|
||||
6, 24, 130, &
|
||||
7, 48, 88, &
|
||||
8, 36, 116, &
|
||||
9, 71, 114, &
|
||||
10, 87, 101, &
|
||||
11, 22, 121, &
|
||||
12, 50, 64, &
|
||||
13, 39, 53, &
|
||||
14, 41, 78, &
|
||||
15, 68, 96, &
|
||||
16, 83, 90, &
|
||||
17, 23, 45, &
|
||||
18, 47, 126, &
|
||||
19, 70, 91, &
|
||||
21, 57, 76, &
|
||||
25, 110, 117, &
|
||||
26, 82, 135, &
|
||||
27, 46, 58, &
|
||||
28, 37, 56, &
|
||||
29, 66, 102, &
|
||||
30, 62, 125, &
|
||||
31, 85, 93, &
|
||||
32, 104, 113, &
|
||||
33, 81, 92, &
|
||||
35, 100, 118, &
|
||||
38, 95, 133, &
|
||||
40, 86, 109, &
|
||||
42, 61, 124, &
|
||||
43, 59, 119, &
|
||||
44, 49, 134, &
|
||||
51, 97, 122, &
|
||||
54, 105, 107, &
|
||||
55, 128, 136, &
|
||||
60, 67, 84, &
|
||||
63, 112, 115, &
|
||||
65, 74, 131, &
|
||||
69, 80, 94, &
|
||||
73, 98, 123, &
|
||||
103, 130, 134, &
|
||||
46, 106, 111, &
|
||||
1, 84, 108, &
|
||||
120, 129, 132, &
|
||||
65, 75, 127, &
|
||||
2, 80, 101, &
|
||||
3, 118, 119, &
|
||||
4, 52, 124, &
|
||||
5, 13, 68, &
|
||||
6, 27, 81, &
|
||||
7, 51, 76, &
|
||||
8, 77, 108, &
|
||||
9, 31, 58, &
|
||||
10, 18, 57, &
|
||||
11, 63, 105, &
|
||||
12, 14, 132, &
|
||||
15, 56, 123, &
|
||||
16, 21, 128, &
|
||||
17, 37, 59, &
|
||||
19, 85, 126, &
|
||||
20, 71, 91, &
|
||||
22, 26, 117, &
|
||||
23, 79, 98, &
|
||||
24, 32, 95, &
|
||||
25, 90, 93, &
|
||||
28, 49, 109, &
|
||||
29, 116, 120, &
|
||||
30, 54, 136, &
|
||||
33, 53, 107, &
|
||||
34, 64, 103, &
|
||||
35, 39, 67, &
|
||||
36, 71, 73, &
|
||||
38, 47, 125, &
|
||||
40, 66, 94, &
|
||||
41, 70, 104, &
|
||||
42, 55, 112, &
|
||||
43, 44, 82, &
|
||||
29, 45, 88, &
|
||||
48, 86, 127, &
|
||||
50, 72, 135, &
|
||||
60, 74, 96, &
|
||||
61, 121, 131, &
|
||||
62, 78, 92, &
|
||||
69, 100, 133, &
|
||||
83, 122, 129, &
|
||||
87, 97, 106, &
|
||||
89, 102, 113, &
|
||||
24, 99, 108, &
|
||||
20, 72, 110, &
|
||||
111, 115, 117, &
|
||||
35, 52, 114, &
|
||||
1, 44, 94, &
|
||||
2, 23, 107, &
|
||||
3, 81, 136, &
|
||||
4, 8, 96, &
|
||||
5, 37, 70, &
|
||||
6, 43, 131, &
|
||||
7, 103, 115, &
|
||||
9, 94, 122, &
|
||||
10, 68, 82, &
|
||||
11, 56, 88, &
|
||||
12, 46, 126, &
|
||||
13, 16, 75, &
|
||||
14, 79, 112, &
|
||||
15, 47, 110, &
|
||||
17, 36, 39, &
|
||||
18, 63, 120, &
|
||||
19, 22, 55, &
|
||||
21, 49, 113, &
|
||||
25, 54, 57, &
|
||||
26, 89, 125, &
|
||||
27, 101, 109, &
|
||||
28, 31, 60, &
|
||||
30, 74, 97, &
|
||||
32, 92, 93, &
|
||||
33, 83, 91, &
|
||||
34, 58, 121, &
|
||||
38, 65, 111, &
|
||||
40, 99, 118, &
|
||||
3, 41, 61, &
|
||||
42, 50, 100, &
|
||||
45, 78, 106, &
|
||||
48, 95, 129, &
|
||||
51, 85, 133, &
|
||||
53, 59, 69, &
|
||||
11, 62, 66, &
|
||||
64, 73, 124, &
|
||||
67, 123, 134, &
|
||||
76, 104, 132, &
|
||||
77, 100, 127, &
|
||||
36, 80, 119, &
|
||||
84, 102, 135, &
|
||||
86, 105, 124, &
|
||||
4, 87, 128, &
|
||||
90, 106, 116, &
|
||||
65, 98, 130, &
|
||||
92, 108, 114, &
|
||||
1, 52, 121, &
|
||||
2, 84, 117, &
|
||||
5, 83, 105, &
|
||||
6, 15, 63, &
|
||||
7, 28, 82, &
|
||||
8, 32, 135, &
|
||||
9, 104, 134, &
|
||||
9, 10, 89, &
|
||||
12, 62, 107, &
|
||||
13, 40, 103, &
|
||||
14, 31, 95, &
|
||||
16, 27, 74, &
|
||||
17, 90, 132, &
|
||||
18, 34, 69, &
|
||||
19, 103, 129, &
|
||||
20, 76, 87, &
|
||||
21, 22, 130, &
|
||||
23, 25, 99, &
|
||||
24, 101, 126/
|
||||
|
||||
data Nm/ &
|
||||
1, 47, 91, 140, 186, 0, &
|
||||
2, 48, 94, 141, 187, 0, &
|
||||
3, 47, 95, 142, 168, 0, &
|
||||
4, 49, 96, 143, 182, 0, &
|
||||
5, 50, 97, 144, 188, 0, &
|
||||
6, 51, 98, 145, 189, 0, &
|
||||
2, 52, 99, 146, 190, 0, &
|
||||
7, 53, 100, 143, 191, 0, &
|
||||
8, 54, 101, 147, 192, 193, &
|
||||
9, 55, 102, 148, 193, 0, &
|
||||
10, 56, 103, 149, 174, 0, &
|
||||
11, 57, 104, 150, 194, 0, &
|
||||
12, 58, 97, 151, 195, 0, &
|
||||
13, 59, 104, 152, 196, 0, &
|
||||
13, 60, 105, 153, 189, 0, &
|
||||
10, 61, 106, 151, 197, 0, &
|
||||
14, 62, 107, 154, 198, 0, &
|
||||
15, 63, 102, 155, 199, 0, &
|
||||
16, 64, 108, 156, 200, 0, &
|
||||
17, 47, 109, 137, 201, 0, &
|
||||
18, 65, 106, 157, 202, 0, &
|
||||
19, 56, 110, 156, 202, 0, &
|
||||
19, 62, 111, 141, 203, 0, &
|
||||
20, 51, 112, 136, 204, 0, &
|
||||
21, 66, 113, 158, 203, 0, &
|
||||
22, 67, 110, 159, 0, 0, &
|
||||
23, 68, 98, 160, 197, 0, &
|
||||
24, 69, 114, 161, 190, 0, &
|
||||
25, 70, 115, 126, 0, 0, &
|
||||
26, 71, 116, 162, 0, 0, &
|
||||
12, 72, 101, 161, 196, 0, &
|
||||
27, 73, 112, 163, 191, 0, &
|
||||
28, 74, 117, 164, 0, 0, &
|
||||
29, 50, 118, 165, 199, 0, &
|
||||
29, 75, 119, 139, 0, 0, &
|
||||
18, 53, 120, 154, 179, 0, &
|
||||
21, 69, 107, 144, 0, 0, &
|
||||
1, 76, 121, 166, 0, 0, &
|
||||
20, 58, 119, 154, 0, 0, &
|
||||
28, 77, 122, 167, 195, 0, &
|
||||
22, 59, 123, 168, 0, 0, &
|
||||
21, 78, 124, 169, 0, 0, &
|
||||
16, 79, 125, 145, 0, 0, &
|
||||
30, 80, 125, 140, 0, 0, &
|
||||
31, 62, 126, 170, 0, 0, &
|
||||
32, 68, 90, 150, 0, 0, &
|
||||
33, 63, 121, 153, 0, 0, &
|
||||
3, 52, 127, 171, 0, 0, &
|
||||
33, 80, 114, 157, 0, 0, &
|
||||
6, 57, 128, 169, 0, 0, &
|
||||
22, 81, 99, 172, 0, 0, &
|
||||
33, 46, 96, 139, 186, 0, &
|
||||
34, 58, 117, 173, 0, 0, &
|
||||
35, 82, 116, 158, 0, 0, &
|
||||
8, 83, 124, 156, 0, 0, &
|
||||
32, 69, 105, 149, 0, 0, &
|
||||
36, 65, 102, 158, 0, 0, &
|
||||
37, 68, 101, 165, 0, 0, &
|
||||
38, 79, 107, 173, 0, 0, &
|
||||
19, 84, 129, 161, 0, 0, &
|
||||
25, 78, 130, 168, 0, 0, &
|
||||
9, 71, 131, 174, 194, 0, &
|
||||
39, 85, 103, 155, 189, 0, &
|
||||
24, 57, 118, 175, 0, 0, &
|
||||
8, 86, 93, 166, 184, 0, &
|
||||
40, 70, 122, 174, 0, 0, &
|
||||
23, 84, 119, 176, 0, 0, &
|
||||
25, 60, 97, 148, 0, 0, &
|
||||
32, 87, 132, 173, 199, 0, &
|
||||
23, 64, 123, 144, 0, 0, &
|
||||
39, 54, 109, 120, 0, 0, &
|
||||
41, 49, 128, 137, 0, 0, &
|
||||
42, 88, 120, 175, 0, 0, &
|
||||
40, 86, 129, 162, 197, 0, &
|
||||
38, 49, 93, 151, 0, 0, &
|
||||
34, 65, 99, 177, 201, 0, &
|
||||
16, 48, 100, 178, 0, 0, &
|
||||
7, 59, 131, 170, 0, 0, &
|
||||
4, 50, 111, 152, 0, 0, &
|
||||
27, 87, 94, 179, 0, 0, &
|
||||
15, 74, 98, 142, 0, 0, &
|
||||
42, 67, 125, 148, 190, 0, &
|
||||
43, 61, 133, 164, 188, 0, &
|
||||
36, 84, 91, 180, 187, 0, &
|
||||
41, 72, 108, 172, 0, 0, &
|
||||
36, 77, 127, 181, 0, 0, &
|
||||
14, 55, 134, 182, 201, 0, &
|
||||
30, 52, 126, 149, 0, 0, &
|
||||
43, 48, 135, 159, 193, 0, &
|
||||
29, 61, 113, 183, 198, 0, &
|
||||
26, 64, 109, 164, 0, 0, &
|
||||
38, 74, 131, 163, 185, 0, &
|
||||
30, 72, 113, 163, 0, 0, &
|
||||
4, 87, 122, 140, 147, 0, &
|
||||
42, 76, 112, 171, 196, 0, &
|
||||
44, 60, 129, 143, 0, 0, &
|
||||
5, 81, 134, 162, 0, 0, &
|
||||
15, 88, 111, 184, 0, 0, &
|
||||
10, 46, 136, 167, 203, 0, &
|
||||
9, 75, 132, 169, 178, 0, &
|
||||
45, 55, 94, 160, 204, 0, &
|
||||
17, 70, 135, 180, 0, 0, &
|
||||
14, 89, 118, 146, 195, 200, &
|
||||
35, 73, 123, 177, 192, 0, &
|
||||
41, 82, 103, 181, 188, 0, &
|
||||
3, 90, 134, 170, 183, 0, &
|
||||
1, 82, 117, 141, 194, 0, &
|
||||
5, 91, 100, 136, 185, 0, &
|
||||
39, 77, 114, 160, 0, 0, &
|
||||
45, 66, 137, 153, 0, 0, &
|
||||
18, 90, 138, 166, 0, 0, &
|
||||
20, 85, 124, 152, 0, 0, &
|
||||
11, 73, 135, 157, 0, 0, &
|
||||
2, 54, 139, 185, 0, 0, &
|
||||
44, 85, 138, 146, 0, 0, &
|
||||
35, 53, 115, 183, 0, 0, &
|
||||
28, 66, 110, 138, 187, 0, &
|
||||
44, 75, 95, 167, 0, 0, &
|
||||
11, 79, 95, 179, 0, 0, &
|
||||
37, 92, 115, 155, 0, 0, &
|
||||
27, 56, 130, 165, 186, 0, &
|
||||
6, 81, 133, 147, 0, 0, &
|
||||
43, 88, 105, 176, 0, 0, &
|
||||
26, 78, 96, 175, 181, 0, &
|
||||
12, 71, 121, 159, 0, 0, &
|
||||
40, 63, 108, 150, 204, 0, &
|
||||
13, 93, 127, 178, 0, 0, &
|
||||
31, 83, 106, 182, 0, 0, &
|
||||
45, 92, 133, 171, 200, 0, &
|
||||
17, 51, 89, 184, 202, 0, &
|
||||
34, 86, 130, 145, 0, 0, &
|
||||
46, 92, 104, 177, 198, 0, &
|
||||
31, 76, 132, 172, 0, 0, &
|
||||
7, 80, 89, 176, 192, 0, &
|
||||
37, 67, 128, 180, 191, 0, &
|
||||
24, 83, 116, 142, 0, 0/
|
||||
|
||||
data nrw/ &
|
||||
5,5,5,5,5,5,5,5,6,5,5,5,5,5,5,5,5, &
|
||||
5,5,5,5,5,5,5,5,4,5,5,4,4,5,5,4,5, &
|
||||
4,5,4,4,4,5,4,4,4,4,4,4,4,4,4,4,4, &
|
||||
5,4,4,4,4,4,4,4,4,4,5,5,4,5,4,4,4, &
|
||||
5,4,4,4,4,5,4,5,4,4,4,4,4,5,5,5,4, &
|
||||
4,5,4,5,5,4,5,4,5,5,4,4,4,5,5,5,4, &
|
||||
6,5,5,5,5,5,4,4,4,4,4,4,4,4,5,4,4, &
|
||||
4,5,4,4,5,4,5,4,4,5,5,4,5,4,5,5,4/
|
||||
|
||||
ncw=3
|
||||
|
||||
decoded=0
|
||||
toc=0
|
||||
tov=0
|
||||
tanhtoc=0
|
||||
! initialize messages to checks
|
||||
do j=1,M
|
||||
do i=1,nrw(j)
|
||||
toc(i,j)=llr((Nm(i,j)))
|
||||
enddo
|
||||
enddo
|
||||
|
||||
ncnt=0
|
||||
|
||||
do iter=0,maxiterations
|
||||
|
||||
! Update bit log likelihood ratios (tov=0 in iteration 0).
|
||||
do i=1,N
|
||||
if( apmask(i) .ne. 1 ) then
|
||||
zn(i)=llr(i)+sum(tov(1:ncw,i))
|
||||
else
|
||||
zn(i)=llr(i)
|
||||
endif
|
||||
enddo
|
||||
|
||||
! Check to see if we have a codeword (check before we do any iteration).
|
||||
cw=0
|
||||
where( zn .gt. 0. ) cw=1
|
||||
ncheck=0
|
||||
do i=1,M
|
||||
synd(i)=sum(cw(Nm(1:nrw(i),i)))
|
||||
if( mod(synd(i),2) .ne. 0 ) ncheck=ncheck+1
|
||||
! if( mod(synd(i),2) .ne. 0 ) write(*,*) 'check ',i,' unsatisfied'
|
||||
enddo
|
||||
! write(*,*) 'number of unsatisfied parity checks ',ncheck
|
||||
if( ncheck .eq. 0 ) then ! we have a codeword - reorder the columns and return it
|
||||
codeword=cw(colorder+1)
|
||||
decoded=codeword(M+1:N)
|
||||
nerr=0
|
||||
do i=1,N
|
||||
if( (2*cw(i)-1)*llr(i) .lt. 0.0 ) nerr=nerr+1
|
||||
enddo
|
||||
nharderror=nerr
|
||||
return
|
||||
endif
|
||||
|
||||
if( iter.gt.0 ) then ! this code block implements an early stopping criterion
|
||||
! if( iter.gt.10000 ) then ! this code block implements an early stopping criterion
|
||||
nd=ncheck-nclast
|
||||
if( nd .lt. 0 ) then ! # of unsatisfied parity checks decreased
|
||||
ncnt=0 ! reset counter
|
||||
else
|
||||
ncnt=ncnt+1
|
||||
endif
|
||||
! write(*,*) iter,ncheck,nd,ncnt
|
||||
if( ncnt .ge. 5 .and. iter .ge. 10 .and. ncheck .gt. 15) then
|
||||
nharderror=-1
|
||||
return
|
||||
endif
|
||||
endif
|
||||
nclast=ncheck
|
||||
|
||||
! Send messages from bits to check nodes
|
||||
do j=1,M
|
||||
do i=1,nrw(j)
|
||||
ibj=Nm(i,j)
|
||||
toc(i,j)=zn(ibj)
|
||||
do kk=1,ncw ! subtract off what the bit had received from the check
|
||||
if( Mn(kk,ibj) .eq. j ) then
|
||||
toc(i,j)=toc(i,j)-tov(kk,ibj)
|
||||
endif
|
||||
enddo
|
||||
enddo
|
||||
enddo
|
||||
|
||||
! send messages from check nodes to variable nodes
|
||||
do i=1,M
|
||||
tanhtoc(1:6,i)=tanh(-toc(1:6,i)/2)
|
||||
enddo
|
||||
|
||||
do j=1,N
|
||||
do i=1,ncw
|
||||
ichk=Mn(i,j) ! Mn(:,j) are the checks that include bit j
|
||||
Tmn=product(tanhtoc(1:nrw(ichk),ichk),mask=Nm(1:nrw(ichk),ichk).ne.j)
|
||||
call platanh(-Tmn,y)
|
||||
! y=atanh(-Tmn)
|
||||
tov(i,j)=2*y
|
||||
enddo
|
||||
enddo
|
||||
|
||||
enddo
|
||||
nharderror=-1
|
||||
return
|
||||
end subroutine bpdecode204
|
||||
Reference in New Issue
Block a user