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.
Public Member Functions | Static Private Member Functions | Private Attributes | List of all members
leansdr::s2_interleaver Struct Reference

#include <dvbs2.h>

+ Inheritance diagram for leansdr::s2_interleaver:
+ Collaboration diagram for leansdr::s2_interleaver:

Public Member Functions

 s2_interleaver (scheduler *sch, pipebuf< fecframe< hard_sb >> &_in, pipebuf< plslot< hard_ss >> &_out)
 
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 ()
 

Static Private Member Functions

static void serialize_qpsk (const hard_sb *pin, int nslots, plslot< hard_ss > *pout)
 
static void interleave (int bps, int rows, const hard_sb *pin, int nslots, bool msb_first, plslot< hard_ss > *pout)
 
template<int MSB_FIRST, int BPS>
static void interleave (int rows, const hard_sb *pin, int nslots, plslot< hard_ss > *pout)
 
template<int BPS>
static void split_byte (const hard_sb *pi, int stride, hard_sb accs[BPS])
 
template<int MSB_FIRST, int BPS>
static void pop_symbols (hard_sb accs[BPS], hard_ss **ps, int ns)
 
static void interleave4050 (const hard_sb *pin, int nslots, plslot< hard_ss > *pout)
 

Private Attributes

pipereader< fecframe< hard_sb > > in
 
pipewriter< plslot< hard_ss > > out
 

Additional Inherited Members

- Public Attributes inherited from leansdr::runnable_common
const char * name
 
- Protected Attributes inherited from leansdr::runnable
schedulersch
 

Detailed Description

Definition at line 1227 of file dvbs2.h.

Constructor & Destructor Documentation

◆ s2_interleaver()

leansdr::s2_interleaver::s2_interleaver ( scheduler sch,
pipebuf< fecframe< hard_sb >> &  _in,
pipebuf< plslot< hard_ss >> &  _out 
)
inline

Definition at line 1229 of file dvbs2.h.

1232  : runnable(sch, "S2 interleaver"),
1233  in(_in), out(_out, 1 + 360)
1234  {
1235  }
runnable(scheduler *_sch, const char *name)
Definition: framework.h:193
pipereader< fecframe< hard_sb > > in
Definition: dvbs2.h:1551
scheduler * sch
Definition: framework.h:199
pipewriter< plslot< hard_ss > > out
Definition: dvbs2.h:1552

Member Function Documentation

◆ interleave() [1/2]

static void leansdr::s2_interleaver::interleave ( int  bps,
int  rows,
const hard_sb pin,
int  nslots,
bool  msb_first,
plslot< hard_ss > *  pout 
)
inlinestaticprivate

Definition at line 1368 of file dvbs2.h.

References leansdr::fail().

1371  {
1372  void (*func)(int rows, const hard_sb *pin, int nslots,
1373  plslot<hard_ss> *pout) = 0;
1374  if (msb_first)
1375  switch (bps)
1376  {
1377  case 2:
1378  func = interleave<1, 2>;
1379  break;
1380  case 3:
1381  func = interleave<1, 3>;
1382  break;
1383  case 4:
1384  func = interleave<1, 4>;
1385  break;
1386  case 5:
1387  func = interleave<1, 5>;
1388  break;
1389  default:
1390  fail("Bad bps");
1391  }
1392  else
1393  switch (bps)
1394  {
1395  case 2:
1396  func = interleave<0, 2>;
1397  break;
1398  case 3:
1399  func = interleave<0, 3>;
1400  break;
1401  case 4:
1402  func = interleave<0, 4>;
1403  break;
1404  case 5:
1405  func = interleave<0, 5>;
1406  break;
1407  default:
1408  fail("Bad bps");
1409  }
1410  (*func)(rows, pin, nslots, pout);
1411  }
void fail(const char *s)
Definition: framework.cpp:11
uint8_t hard_sb
Definition: softword.h:21
+ Here is the call graph for this function:

◆ interleave() [2/2]

template<int MSB_FIRST, int BPS>
static void leansdr::s2_interleaver::interleave ( int  rows,
const hard_sb pin,
int  nslots,
plslot< hard_ss > *  pout 
)
inlinestaticprivate

Definition at line 1413 of file dvbs2.h.

References leansdr::fatal(), i, leansdr::plslot< SOFTSYMB >::is_pls, and leansdr::plslot< SOFTSYMB >::symbols.

1415  {
1416  if (BPS == 4 && rows == 4050 && MSB_FIRST)
1417  return interleave4050(pin, nslots, pout);
1418  if (rows % 8)
1419  fatal("modcod/framesize combination not supported\n");
1420  int stride = rows / 8; // Offset to next column, in bytes
1421  if (nslots % 4)
1422  fatal("Bug: Truncated byte");
1423  // plslot::symbols[] are not packed across slots,
1424  // so we need tos split bytes at boundaries.
1425  for (; nslots; nslots -= 4)
1426  {
1427  const hard_sb *pi;
1428  hard_sb accs[BPS]; // One accumulator per column
1429  hard_ss *ps;
1430  // Slot 0 (mod 4): 88+2
1431  pout->is_pls = false;
1432  ps = pout->symbols;
1433  for (int i = 0; i < 11; ++i)
1434  {
1435  split_byte<BPS>(pin++, stride, accs);
1436  pop_symbols<MSB_FIRST, BPS>(accs, &ps, 8);
1437  }
1438  split_byte<BPS>(pin++, stride, accs);
1439  pop_symbols<MSB_FIRST, BPS>(accs, &ps, 2);
1440  ++pout;
1441  // Slot 1 (mod 4): 6+80+4
1442  pout->is_pls = false;
1443  ps = pout->symbols;
1444  pop_symbols<MSB_FIRST, BPS>(accs, &ps, 6);
1445  for (int i = 0; i < 10; ++i)
1446  {
1447  split_byte<BPS>(pin++, stride, accs);
1448  pop_symbols<MSB_FIRST, BPS>(accs, &ps, 8);
1449  }
1450  split_byte<BPS>(pin++, stride, accs);
1451  pop_symbols<MSB_FIRST, BPS>(accs, &ps, 4);
1452  ++pout;
1453  // Slot 2 (mod 4): 4+80+6
1454  pout->is_pls = false;
1455  ps = pout->symbols;
1456  pop_symbols<MSB_FIRST, BPS>(accs, &ps, 4);
1457  for (int i = 0; i < 10; ++i)
1458  {
1459  split_byte<BPS>(pin++, stride, accs);
1460  pop_symbols<MSB_FIRST, BPS>(accs, &ps, 8);
1461  }
1462  split_byte<BPS>(pin++, stride, accs);
1463  pop_symbols<MSB_FIRST, BPS>(accs, &ps, 6);
1464  ++pout;
1465  // Slot 3 (mod 4): 2+88
1466  pout->is_pls = false;
1467  ps = pout->symbols;
1468  pop_symbols<MSB_FIRST, BPS>(accs, &ps, 2);
1469  for (int i = 0; i < 11; ++i)
1470  {
1471  split_byte<BPS>(pin++, stride, accs);
1472  pop_symbols<MSB_FIRST, BPS>(accs, &ps, 8);
1473  }
1474  ++pout;
1475  }
1476  }
static void interleave4050(const hard_sb *pin, int nslots, plslot< hard_ss > *pout)
Definition: dvbs2.h:1506
bool is_pls
Definition: dvbs2.h:210
int32_t i
Definition: decimators.h:244
uint8_t hard_ss
Definition: sdr.h:423
void fatal(const char *s)
Definition: framework.cpp:6
uint8_t hard_sb
Definition: softword.h:21
SOFTSYMB symbols[LENGTH]
Definition: dvbs2.h:213
+ Here is the call graph for this function:

◆ interleave4050()

static void leansdr::s2_interleaver::interleave4050 ( const hard_sb pin,
int  nslots,
plslot< hard_ss > *  pout 
)
inlinestaticprivate

Definition at line 1506 of file dvbs2.h.

References leansdr::plslot< SOFTSYMB >::is_pls, leansdr::plslot< SOFTSYMB >::LENGTH, and leansdr::plslot< SOFTSYMB >::symbols.

1508  {
1509  const hard_sb *pin0 = pin;
1510  int rows = 4050;
1511  hard_sb accs[4]; // One accumulator per column
1512  int nacc = 0; // Bits in each column accumulator
1513  for (; nslots; --nslots, ++pout)
1514  {
1515  pout->is_pls = false;
1516  hard_ss *ps = pout->symbols;
1517  for (int ns = pout->LENGTH; ns--; ++ps)
1518  {
1519  if (!nacc)
1520  {
1521  if (nslots == 1 && ns == 1)
1522  {
1523  // Special case just to avoid reading beyond end of buffer
1524  accs[0] = pin[0];
1525  accs[1] = (pin[506] << 2) | (pin[507] >> 6);
1526  accs[2] = (pin[1012] << 4) | (pin[1013] >> 4);
1527  accs[3] = (pin[1518] << 6);
1528  }
1529  else
1530  {
1531  accs[0] = pin[0];
1532  accs[1] = (pin[506] << 2) | (pin[507] >> 6);
1533  accs[2] = (pin[1012] << 4) | (pin[1013] >> 4);
1534  accs[3] = (pin[1518] << 6) | (pin[1519] >> 2);
1535  }
1536  ++pin;
1537  nacc = 8;
1538  }
1539  hard_ss symb = 0;
1540  for (int b = 0; b < 4; ++b)
1541  {
1542  symb = (symb << 1) | (accs[b] >> 7);
1543  accs[b] <<= 1;
1544  }
1545  --nacc;
1546  *ps = symb;
1547  }
1548  }
1549  }
bool is_pls
Definition: dvbs2.h:210
uint8_t hard_ss
Definition: sdr.h:423
uint8_t hard_sb
Definition: softword.h:21
static const int LENGTH
Definition: dvbs2.h:209
SOFTSYMB symbols[LENGTH]
Definition: dvbs2.h:213

◆ pop_symbols()

template<int MSB_FIRST, int BPS>
static void leansdr::s2_interleaver::pop_symbols ( hard_sb  accs[BPS],
hard_ss **  ps,
int  ns 
)
inlinestaticprivate

Definition at line 1486 of file dvbs2.h.

References i.

1487  {
1488  for (int i = 0; i < ns; ++i)
1489  {
1490  hard_ss symb = 0;
1491  // Check unrolling and constant propagation.
1492  for (int b = 0; b < BPS; ++b)
1493  if (MSB_FIRST)
1494  symb = (symb << 1) | (accs[b] >> 7);
1495  else
1496  symb = (symb << 1) | (accs[BPS - 1 - b] >> 7);
1497  for (int b = 0; b < BPS; ++b)
1498  accs[b] <<= 1;
1499  *(*ps)++ = symb;
1500  }
1501  }
int32_t i
Definition: decimators.h:244
uint8_t hard_ss
Definition: sdr.h:423

◆ run()

void leansdr::s2_interleaver::run ( )
inlinevirtual

Reimplemented from leansdr::runnable_common.

Definition at line 1236 of file dvbs2.h.

References leansdr::check_modcod(), leansdr::FEC35, leansdr::s2_pls::framebits(), leansdr::plslot< SOFTSYMB >::is_pls, leansdr::s2_pls::modcod, leansdr::modcod_info::nslots_nf, leansdr::modcod_info::nsymbols, leansdr::plslot< SOFTSYMB >::pls, leansdr::modcod_info::rate, leansdr::pipereader< T >::rd(), leansdr::pipereader< T >::read(), leansdr::pipereader< T >::readable(), leansdr::s2_pls::sf, leansdr::pipewriter< T >::wr(), leansdr::pipewriter< T >::writable(), and leansdr::pipewriter< T >::written().

1237  {
1238  while (in.readable() >= 1)
1239  {
1240  const s2_pls *pls = &in.rd()->pls;
1241  const modcod_info *mcinfo = check_modcod(pls->modcod);
1242  int nslots = pls->sf ? mcinfo->nslots_nf / 4 : mcinfo->nslots_nf;
1243  if (out.writable() < 1 + nslots)
1244  return;
1245  const hard_sb *pbytes = in.rd()->bytes;
1246  // Output pseudo slot with PLS.
1247  plslot<hard_ss> *ppls = out.wr();
1248  ppls->is_pls = true;
1249  ppls->pls = *pls;
1250  out.written(1);
1251  // Interleave
1252  plslot<hard_ss> *pout = out.wr();
1253  if (mcinfo->nsymbols == 4)
1254  serialize_qpsk(pbytes, nslots, pout);
1255  else
1256  {
1257  int bps = log2(mcinfo->nsymbols);
1258  int rows = pls->framebits() / bps;
1259  if (mcinfo->nsymbols == 8 && mcinfo->rate == FEC35)
1260  interleave(bps, rows, pbytes, nslots, false, pout);
1261  else
1262  interleave(bps, rows, pbytes, nslots, true, pout);
1263  }
1264  in.read(1);
1265  out.written(nslots);
1266  }
1267  }
static void interleave(int bps, int rows, const hard_sb *pin, int nslots, bool msb_first, plslot< hard_ss > *pout)
Definition: dvbs2.h:1368
pipereader< fecframe< hard_sb > > in
Definition: dvbs2.h:1551
uint8_t hard_sb
Definition: softword.h:21
pipewriter< plslot< hard_ss > > out
Definition: dvbs2.h:1552
static void serialize_qpsk(const hard_sb *pin, int nslots, plslot< hard_ss > *pout)
Definition: dvbs2.h:1271
const modcod_info * check_modcod(int m)
Definition: dvbs2.h:285
+ Here is the call graph for this function:

◆ serialize_qpsk()

static void leansdr::s2_interleaver::serialize_qpsk ( const hard_sb pin,
int  nslots,
plslot< hard_ss > *  pout 
)
inlinestaticprivate

Definition at line 1271 of file dvbs2.h.

References leansdr::fail(), leansdr::fatal(), i, leansdr::plslot< SOFTSYMB >::is_pls, leansdr::plslot< SOFTSYMB >::LENGTH, and leansdr::plslot< SOFTSYMB >::symbols.

1273  {
1274 #if 0 // For reference
1275  hard_sb acc;
1276  int nacc = 0;
1277  for ( ; nslots; --nslots,++pout ) {
1278  pout->is_pls = false;
1279  hard_ss *ps = pout->symbols;
1280  for ( int ns=pout->LENGTH; ns--; ++ps ) {
1281  if ( nacc < 2 ) { acc=*pin++; nacc=8; }
1282  *ps = acc>>6;
1283  acc <<= 2;
1284  nacc -= 2;
1285  }
1286  }
1287  if ( nacc ) fail("Bug: s2_interleaver");
1288 #else
1289  if (nslots % 2)
1290  fatal("Bug: Truncated byte");
1291  for (; nslots; nslots -= 2)
1292  {
1293  hard_sb b;
1294  hard_ss *ps;
1295  // Slot 0 (mod 2)
1296  pout->is_pls = false;
1297  ps = pout->symbols;
1298  for (int i = 0; i < 22; ++i)
1299  {
1300  b = *pin++;
1301  *ps++ = (b >> 6);
1302  *ps++ = (b >> 4) & 3;
1303  *ps++ = (b >> 2) & 3;
1304  *ps++ = (b)&3;
1305  }
1306  b = *pin++;
1307  *ps++ = (b >> 6);
1308  *ps++ = (b >> 4) & 3;
1309  // Slot 1 (mod 2)
1310  ++pout;
1311  pout->is_pls = false;
1312  ps = pout->symbols;
1313  *ps++ = (b >> 2) & 3;
1314  *ps++ = (b)&3;
1315  for (int i = 0; i < 22; ++i)
1316  {
1317  b = *pin++;
1318  *ps++ = (b >> 6);
1319  *ps++ = (b >> 4) & 3;
1320  *ps++ = (b >> 2) & 3;
1321  *ps++ = (b)&3;
1322  }
1323  ++pout;
1324  }
1325 #endif
1326  }
void fail(const char *s)
Definition: framework.cpp:11
bool is_pls
Definition: dvbs2.h:210
int32_t i
Definition: decimators.h:244
uint8_t hard_ss
Definition: sdr.h:423
void fatal(const char *s)
Definition: framework.cpp:6
uint8_t hard_sb
Definition: softword.h:21
static const int LENGTH
Definition: dvbs2.h:209
SOFTSYMB symbols[LENGTH]
Definition: dvbs2.h:213
+ Here is the call graph for this function:

◆ split_byte()

template<int BPS>
static void leansdr::s2_interleaver::split_byte ( const hard_sb pi,
int  stride,
hard_sb  accs[BPS] 
)
inlinestaticprivate

Definition at line 1478 of file dvbs2.h.

1480  {
1481  // TBD Pass stride as template parameter.
1482  for (int b = 0; b < BPS; ++b, pi += stride)
1483  accs[b] = *pi;
1484  }

Member Data Documentation

◆ in

pipereader<fecframe<hard_sb> > leansdr::s2_interleaver::in
private

Definition at line 1551 of file dvbs2.h.

◆ out

pipewriter<plslot<hard_ss> > leansdr::s2_interleaver::out
private

Definition at line 1552 of file dvbs2.h.


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