SDRAngel  4.11.5
Developer docs for <a href="https://github.com/f4exb/sdrangel">SDRangel<\a>, an Open Source Qt5 / OpenGL 3.0+ SDR and signal analyzer frontend to various hardware.
Classes | Public Types | Public Member Functions | Public Attributes | Private Attributes | Static Private Attributes | List of all members
leansdr::viterbi_sync Struct Reference

#include <dvb.h>

+ Inheritance diagram for leansdr::viterbi_sync:
+ Collaboration diagram for leansdr::viterbi_sync:

Classes

struct  sync
 

Public Types

typedef uint8_t TS
 
typedef uint8_t TCS
 
typedef uint8_t TUS
 
typedef int32_t TBM
 
typedef int32_t TPM
 
typedef viterbi_dec_interface< TUS, TCS, TBM, TPMdvb_dec_interface
 
typedef bitpath< uint32_t, TUS, 1, 32 > path_12
 
typedef trellis< TS, 64, TUS, 2, 4 > trellis_12
 
typedef viterbi_dec< TS, 64, TUS, 2, TCS, 4, TBM, TPM, path_12dvb_dec_12
 
typedef bitpath< uint64_t, TUS, 3, 21 > path_23
 
typedef trellis< TS, 64, TUS, 4, 8 > trellis_23
 
typedef viterbi_dec< TS, 64, TUS, 4, TCS, 8, TBM, TPM, path_23dvb_dec_23
 
typedef bitpath< uint64_t, TUS, 4, 16 > path_46
 
typedef trellis< TS, 64, TUS, 16, 64 > trellis_46
 
typedef viterbi_dec< TS, 64, TUS, 16, TCS, 64, TBM, TPM, path_46dvb_dec_46
 
typedef bitpath< uint64_t, TUS, 3, 21 > path_34
 
typedef trellis< TS, 64, TUS, 8, 16 > trellis_34
 
typedef viterbi_dec< TS, 64, TUS, 8, TCS, 16, TBM, TPM, path_34dvb_dec_34
 
typedef bitpath< uint64_t, TUS, 4, 16 > path_45
 
typedef trellis< TS, 64, TUS, 16, 32 > trellis_45
 
typedef viterbi_dec< TS, 64, TUS, 16, TCS, 32, TBM, TPM, path_45dvb_dec_45
 
typedef bitpath< uint64_t, TUS, 5, 12 > path_56
 
typedef trellis< TS, 64, TUS, 32, 64 > trellis_56
 
typedef viterbi_dec< TS, 64, TUS, 32, TCS, 64, TBM, TPM, path_56dvb_dec_56
 
typedef bitpath< uint64_t, TUS, 7, 9 > path_78
 
typedef trellis< TS, 64, TUS, 128, 256 > trellis_78
 
typedef viterbi_dec< TS, 64, TUS, 128, TCS, 256, TBM, TPM, path_78dvb_dec_78
 

Public Member Functions

 viterbi_sync (scheduler *sch, pipebuf< eucl_ss > &_in, pipebuf< unsigned char > &_out, cstln_lut< eucl_ss, 256 > *_cstln, code_rate cr)
 
TCSinit_map (bool conj, float angle)
 
TUS update_sync (int s, eucl_ss *pin, TPM *discr)
 
void run ()
 
- Public Member Functions inherited from leansdr::runnable
 runnable (scheduler *_sch, const char *name)
 
- Public Member Functions inherited from leansdr::runnable_common
 runnable_common (const char *_name)
 
virtual ~runnable_common ()
 
virtual void shutdown ()
 

Public Attributes

int resync_period
 
- Public Attributes inherited from leansdr::runnable_common
const char * name
 

Private Attributes

pipereader< eucl_ssin
 
pipewriter< unsigned char > out
 
cstln_lut< eucl_ss, 256 > * cstln
 
fec_spec * fec
 
int bits_per_symbol
 
int nsyncs
 
int nshifts
 
struct leansdr::viterbi_sync::syncsyncs
 
int current_sync
 
int resync_phase
 

Static Private Attributes

static const int chunk_size = 128
 

Additional Inherited Members

- Protected Attributes inherited from leansdr::runnable
schedulersch
 

Detailed Description

Definition at line 1466 of file dvb.h.

Member Typedef Documentation

◆ dvb_dec_12

Definition at line 1476 of file dvb.h.

◆ dvb_dec_23

Definition at line 1481 of file dvb.h.

◆ dvb_dec_34

Definition at line 1491 of file dvb.h.

◆ dvb_dec_45

Definition at line 1496 of file dvb.h.

◆ dvb_dec_46

Definition at line 1486 of file dvb.h.

◆ dvb_dec_56

Definition at line 1501 of file dvb.h.

◆ dvb_dec_78

Definition at line 1506 of file dvb.h.

◆ dvb_dec_interface

Definition at line 1471 of file dvb.h.

◆ path_12

Definition at line 1474 of file dvb.h.

◆ path_23

Definition at line 1479 of file dvb.h.

◆ path_34

Definition at line 1489 of file dvb.h.

◆ path_45

Definition at line 1494 of file dvb.h.

◆ path_46

Definition at line 1484 of file dvb.h.

◆ path_56

Definition at line 1499 of file dvb.h.

◆ path_78

Definition at line 1504 of file dvb.h.

◆ TBM

Definition at line 1469 of file dvb.h.

◆ TCS

Definition at line 1468 of file dvb.h.

◆ TPM

Definition at line 1470 of file dvb.h.

◆ trellis_12

Definition at line 1475 of file dvb.h.

◆ trellis_23

Definition at line 1480 of file dvb.h.

◆ trellis_34

Definition at line 1490 of file dvb.h.

◆ trellis_45

Definition at line 1495 of file dvb.h.

◆ trellis_46

Definition at line 1485 of file dvb.h.

◆ trellis_56

Definition at line 1500 of file dvb.h.

◆ trellis_78

Definition at line 1505 of file dvb.h.

◆ TS

Definition at line 1468 of file dvb.h.

◆ TUS

Definition at line 1468 of file dvb.h.

Constructor & Destructor Documentation

◆ viterbi_sync()

leansdr::viterbi_sync::viterbi_sync ( scheduler sch,
pipebuf< eucl_ss > &  _in,
pipebuf< unsigned char > &  _out,
cstln_lut< eucl_ss, 256 > *  _cstln,
code_rate  cr 
)
inline

Definition at line 1531 of file dvb.h.

References leansdr::fail(), leansdr::FEC12, leansdr::FEC23, leansdr::FEC34, leansdr::FEC45, leansdr::FEC46, leansdr::FEC56, leansdr::FEC78, i, leansdr::trellis< TS, NSTATES, TUS, NUS, NCS >::init_convolutional(), leansdr::log2i(), M_PI, leansdr::cstln_base::nrotations, leansdr::cstln_base::nsymbols, and leansdr::deconvol_sync< Tbyte, BYTE_ERASED >::syncs.

1535  : runnable(sch, "viterbi_sync"),
1536  in(_in),
1537  out(_out, chunk_size),
1538  cstln(_cstln),
1539  current_sync(0),
1540  resync_phase(0),
1541  resync_period(32) // 1/32 = 9% synchronization overhead TBD
1542  {
1543  bits_per_symbol = log2i(cstln->nsymbols);
1544  fec = &fec_specs[cr];
1545 
1546  { // Sanity check: FEC block size must be a multiple of label size.
1547  int symbols_per_block = fec->bits_out / bits_per_symbol;
1548  if (bits_per_symbol * symbols_per_block != fec->bits_out)
1549  fail("Code rate not suitable for this constellation");
1550  }
1551 
1552  int nconj;
1553 
1554  switch (cstln->nsymbols)
1555  {
1556  case 2:
1557  nconj = 1;
1558  break; // Conjugation is not relevant for BPSK
1559  default:
1560  nconj = 2;
1561  break;
1562  }
1563 
1564  int nrotations;
1565 
1566  switch (cstln->nsymbols)
1567  {
1568  case 2:
1569  case 4:
1570  // For BPSK and QPSK, 180° rotation is handled as
1571  // polarity inversion in mpeg_sync.
1572  nrotations = cstln->nrotations / 2;
1573  break;
1574  default:
1575  nrotations = cstln->nrotations;
1576  break;
1577  }
1578 
1579  nshifts = fec->bits_out / bits_per_symbol;
1580  nsyncs = nconj * nrotations * nshifts;
1581 
1582  // TBD Many HOM constellations are labelled in such a way
1583  // that certain rot/conj combinations are equivalent to
1584  // polarity inversion. We could reduce nsyncs.
1585 
1586  syncs = new sync[nsyncs];
1587 
1588  for (int s = 0; s < nsyncs; ++s)
1589  {
1590  // Bit pattern [shift|conj|rot]
1591  int rot = s % nrotations;
1592  int conj = (s / nrotations) % nconj;
1593  int shift = s / nrotations / nconj;
1594  syncs[s].shift = shift;
1595 
1596  if (shift) // Reuse identical map
1597  syncs[s].map = syncs[conj * nrotations + rot].map;
1598  else
1599  syncs[s].map = init_map(conj,
1600  2 * M_PI * rot / cstln->nrotations);
1601 #if 0
1602  fprintf(stderr, "sync %3d: conj%d offs%d rot%d/%d map:",
1603  s, conj, syncs[s].shift, rot, cstln->nrotations);
1604  for ( int i=0; i<cstln->nsymbols; ++i )
1605  fprintf(stderr, " %2d", syncs[s].map[i]);
1606  fprintf(stderr, "\n");
1607 #endif
1608  }
1609 
1610  if (cr == FEC12)
1611  {
1612  trellis_12 *trell = new trellis_12();
1613  trell->init_convolutional(fec->polys);
1614  for (int s = 0; s < nsyncs; ++s)
1615  syncs[s].dec = new dvb_dec_12(trell);
1616  }
1617  else if (cr == FEC23)
1618  {
1619  trellis_23 *trell = new trellis_23();
1620  trell->init_convolutional(fec->polys);
1621  for (int s = 0; s < nsyncs; ++s)
1622  syncs[s].dec = new dvb_dec_23(trell);
1623  }
1624  else if (cr == FEC46)
1625  {
1626  trellis_46 *trell = new trellis_46();
1627  trell->init_convolutional(fec->polys);
1628  for (int s = 0; s < nsyncs; ++s)
1629  syncs[s].dec = new dvb_dec_46(trell);
1630  }
1631  else if (cr == FEC34)
1632  {
1633  trellis_34 *trell = new trellis_34();
1634  trell->init_convolutional(fec->polys);
1635  for (int s = 0; s < nsyncs; ++s)
1636  syncs[s].dec = new dvb_dec_34(trell);
1637  }
1638  else if (cr == FEC45)
1639  {
1640  trellis_45 *trell = new trellis_45();
1641  trell->init_convolutional(fec->polys);
1642  for (int s = 0; s < nsyncs; ++s)
1643  syncs[s].dec = new dvb_dec_45(trell);
1644  }
1645  else if (cr == FEC56)
1646  {
1647  trellis_56 *trell = new trellis_56();
1648  trell->init_convolutional(fec->polys);
1649  for (int s = 0; s < nsyncs; ++s)
1650  syncs[s].dec = new dvb_dec_56(trell);
1651  }
1652  else if (cr == FEC78)
1653  {
1654  trellis_78 *trell = new trellis_78();
1655  trell->init_convolutional(fec->polys);
1656  for (int s = 0; s < nsyncs; ++s)
1657  syncs[s].dec = new dvb_dec_78(trell);
1658  }
1659  else
1660  {
1661  fail("CR not supported");
1662  }
1663  }
viterbi_dec< TS, 64, TUS, 8, TCS, 16, TBM, TPM, path_34 > dvb_dec_34
Definition: dvb.h:1491
trellis< TS, 64, TUS, 128, 256 > trellis_78
Definition: dvb.h:1505
trellis< TS, 64, TUS, 16, 32 > trellis_45
Definition: dvb.h:1495
trellis< TS, 64, TUS, 32, 64 > trellis_56
Definition: dvb.h:1500
trellis< TS, 64, TUS, 2, 4 > trellis_12
Definition: dvb.h:1475
int log2i(uint64_t x)
Definition: math.cpp:48
viterbi_dec< TS, 64, TUS, 16, TCS, 32, TBM, TPM, path_45 > dvb_dec_45
Definition: dvb.h:1496
runnable(scheduler *_sch, const char *name)
Definition: framework.h:193
viterbi_dec< TS, 64, TUS, 4, TCS, 8, TBM, TPM, path_23 > dvb_dec_23
Definition: dvb.h:1481
TCS * init_map(bool conj, float angle)
Definition: dvb.h:1665
trellis< TS, 64, TUS, 16, 64 > trellis_46
Definition: dvb.h:1485
trellis< TS, 64, TUS, 8, 16 > trellis_34
Definition: dvb.h:1490
void fail(const char *s)
Definition: framework.cpp:11
viterbi_dec< TS, 64, TUS, 2, TCS, 4, TBM, TPM, path_12 > dvb_dec_12
Definition: dvb.h:1476
int32_t i
Definition: decimators.h:244
trellis< TS, 64, TUS, 4, 8 > trellis_23
Definition: dvb.h:1480
pipereader< eucl_ss > in
Definition: dvb.h:1509
#define M_PI
Definition: dvb.h:28
cstln_lut< eucl_ss, 256 > * cstln
Definition: dvb.h:1511
viterbi_dec< TS, 64, TUS, 32, TCS, 64, TBM, TPM, path_56 > dvb_dec_56
Definition: dvb.h:1501
fec_spec * fec
Definition: dvb.h:1512
viterbi_dec< TS, 64, TUS, 16, TCS, 64, TBM, TPM, path_46 > dvb_dec_46
Definition: dvb.h:1486
viterbi_dec< TS, 64, TUS, 128, TCS, 256, TBM, TPM, path_78 > dvb_dec_78
Definition: dvb.h:1506
static const int chunk_size
Definition: dvb.h:1525
struct leansdr::viterbi_sync::sync * syncs
scheduler * sch
Definition: framework.h:199
pipewriter< unsigned char > out
Definition: dvb.h:1510
+ Here is the call graph for this function:

Member Function Documentation

◆ init_map()

TCS* leansdr::viterbi_sync::init_map ( bool  conj,
float  angle 
)
inline

Definition at line 1665 of file dvb.h.

References i, leansdr::complex< T >::im, leansdr::cstln_lut< SOFTSYMB, R >::lookup(), leansdr::cstln_base::nsymbols, leansdr::complex< T >::re, leansdr::cstln_lut< SOFTSYMB, R >::result::ss, and leansdr::cstln_base::symbols.

1666  {
1667  // Each constellation has its own pattern for labels.
1668  // Here we simply tabulate systematically.
1669  TCS *map = new TCS[cstln->nsymbols];
1670  float ca = cosf(angle), sa = sinf(angle);
1671 
1672  for (int i = 0; i < cstln->nsymbols; ++i)
1673  {
1674  int8_t I = cstln->symbols[i].re;
1675  int8_t Q = cstln->symbols[i].im;
1676 
1677  if (conj)
1678  Q = -Q;
1679 
1680  int8_t RI = I * ca - Q * sa;
1681  int8_t RQ = I * sa + Q * ca;
1682  cstln_lut<eucl_ss, 256>::result *pr = cstln->lookup(RI, RQ);
1683  map[i] = pr->ss.nearest;
1684  }
1685 
1686  return map;
1687  }
int32_t i
Definition: decimators.h:244
char int8_t
Definition: rtptypes_win.h:41
cstln_lut< eucl_ss, 256 > * cstln
Definition: dvb.h:1511
+ Here is the call graph for this function:

◆ run()

void leansdr::viterbi_sync::run ( )
inlinevirtual

Reimplemented from leansdr::runnable_common.

Definition at line 1705 of file dvb.h.

References leansdr::scheduler::debug, leansdr::fail(), leansdr::pipereader< T >::rd(), leansdr::pipereader< T >::read(), leansdr::pipereader< T >::readable(), leansdr::runnable::sch, leansdr::pipewriter< T >::writable(), and leansdr::pipewriter< T >::write().

1706  {
1707  // Number of FEC blocks to fill the bitpath depth.
1708  // Before that we cannot discriminate between synchronizers
1709  int discr_delay = 64 / fec->bits_in;
1710 
1711  // Process [chunk_size] FEC blocks at a time
1712 
1713  TPM *totaldiscr = new TPM[nsyncs];
1714 
1715  while ((long)in.readable() >= nshifts * chunk_size + (nshifts - 1) && (long)out.writable() * 8 >= fec->bits_in * chunk_size)
1716  {
1717  for (int s = 0; s < nsyncs; ++s)
1718  totaldiscr[s] = 0;
1719 
1720  uint64_t outstream = 0;
1721  int nout = 0;
1722  eucl_ss *pin = in.rd();
1723 
1724  for (int blocknum = 0; blocknum < chunk_size; ++blocknum, pin += nshifts)
1725  {
1726  TPM discr;
1727  TUS result = update_sync(current_sync, pin, &discr);
1728  outstream = (outstream << fec->bits_in) | result;
1729  nout += fec->bits_in;
1730 
1731  if (blocknum >= discr_delay)
1732  totaldiscr[current_sync] += discr;
1733 
1734  if (!resync_phase)
1735  {
1736  // Every [resync_period] chunks, also run the other decoders.
1737  for (int s = 0; s < nsyncs; ++s)
1738  {
1739  if (s == current_sync)
1740  continue;
1741 
1742  TPM discr;
1743  (void)update_sync(s, pin, &discr);
1744 
1745  if (blocknum >= discr_delay)
1746  totaldiscr[s] += discr;
1747  }
1748  }
1749 
1750  while (nout >= 8)
1751  {
1752  out.write(outstream >> (nout - 8));
1753  nout -= 8;
1754  }
1755  } // chunk_size
1756 
1757  in.read(chunk_size * nshifts);
1758 
1759  if (nout)
1760  fail("overlapping out");
1761 
1762  if (!resync_phase)
1763  {
1764  // Switch to another decoder ?
1765  int best = current_sync;
1766 
1767  for (int s = 0; s < nsyncs; ++s)
1768  if (totaldiscr[s] > totaldiscr[best])
1769  best = s;
1770 
1771  if (best != current_sync)
1772  {
1773  if (sch->debug)
1774  fprintf(stderr, "{%d->%d}", current_sync, best);
1775  current_sync = best;
1776  }
1777  }
1778 
1779  if (++resync_phase >= resync_period)
1780  resync_phase = 0;
1781  }
1782 
1783  delete[] totaldiscr;
1784  }
void fail(const char *s)
Definition: framework.cpp:11
pipereader< eucl_ss > in
Definition: dvb.h:1509
fec_spec * fec
Definition: dvb.h:1512
static const int chunk_size
Definition: dvb.h:1525
scheduler * sch
Definition: framework.h:199
void write(const T &e)
Definition: framework.h:319
pipewriter< unsigned char > out
Definition: dvb.h:1510
TUS update_sync(int s, eucl_ss *pin, TPM *discr)
Definition: dvb.h:1689
unsigned __int64 uint64_t
Definition: rtptypes_win.h:48
+ Here is the call graph for this function:

◆ update_sync()

TUS leansdr::viterbi_sync::update_sync ( int  s,
eucl_ss pin,
TPM discr 
)
inline

Definition at line 1689 of file dvb.h.

References leansdr::eucl_ss::discr2, i, leansdr::eucl_ss::nearest, and leansdr::deconvol_sync< Tbyte, BYTE_ERASED >::syncs.

1690  {
1691  // Read one FEC ouput block
1692  pin += syncs[s].shift;
1693  TCS cs = 0;
1694  TBM cost = 0;
1695 
1696  for (int i = 0; i < nshifts; ++i, ++pin)
1697  {
1698  cs = (cs << bits_per_symbol) | syncs[s].map[pin->nearest];
1699  cost -= pin->discr2;
1700  }
1701 
1702  return syncs[s].dec->update(cs, cost, discr);
1703  }
virtual TUS update(TBM *costs, TPM *quality=NULL)=0
int32_t i
Definition: decimators.h:244
dvb_dec_interface * dec
Definition: dvb.h:1520
struct leansdr::viterbi_sync::sync * syncs

Member Data Documentation

◆ bits_per_symbol

int leansdr::viterbi_sync::bits_per_symbol
private

Definition at line 1513 of file dvb.h.

◆ chunk_size

const int leansdr::viterbi_sync::chunk_size = 128
staticprivate

Definition at line 1525 of file dvb.h.

◆ cstln

cstln_lut<eucl_ss, 256>* leansdr::viterbi_sync::cstln
private

Definition at line 1511 of file dvb.h.

◆ current_sync

int leansdr::viterbi_sync::current_sync
private

Definition at line 1524 of file dvb.h.

◆ fec

fec_spec* leansdr::viterbi_sync::fec
private

Definition at line 1512 of file dvb.h.

◆ in

pipereader<eucl_ss> leansdr::viterbi_sync::in
private

Definition at line 1509 of file dvb.h.

◆ nshifts

int leansdr::viterbi_sync::nshifts
private

Definition at line 1515 of file dvb.h.

◆ nsyncs

int leansdr::viterbi_sync::nsyncs
private

Definition at line 1514 of file dvb.h.

◆ out

pipewriter<unsigned char> leansdr::viterbi_sync::out
private

Definition at line 1510 of file dvb.h.

◆ resync_period

int leansdr::viterbi_sync::resync_period

Definition at line 1529 of file dvb.h.

◆ resync_phase

int leansdr::viterbi_sync::resync_phase
private

Definition at line 1526 of file dvb.h.

◆ syncs

struct leansdr::viterbi_sync::sync * leansdr::viterbi_sync::syncs
private

The documentation for this struct was generated from the following file: