Split generic RS implementation from DVB-specific code

pull/4/head
pabr 2017-01-28 18:32:13 +01:00
rodzic adc50bf825
commit 17c5918a7c
2 zmienionych plików z 107 dodań i 106 usunięć

Wyświetl plik

@ -4,6 +4,7 @@
#include "leansdr/viterbi.h"
#include "leansdr/convolutional.h"
#include "leansdr/sdr.h"
#include "leansdr/rs.h"
namespace leansdr {
@ -856,6 +857,112 @@ namespace leansdr {
struct tspacket { u8 data[SIZE_TSPACKET]; };
// RS ENCODER
struct rs_encoder : runnable {
rs_encoder(scheduler *sch,
pipebuf<tspacket> &_in, pipebuf< rspacket<u8> > &_out)
: runnable(sch, "RS encoder"),
in(_in), out(_out) { }
void run() {
while ( in.readable()>=1 && out.writable()>=1 ) {
u8 *pin = in.rd()->data;
u8 *pout = out.wr()->data;
// The first 188 bytes are the uncoded message P(X)
memcpy(pout, pin, SIZE_TSPACKET);
// Append 16 RS parity bytes R(X) = - (P(X)*X^16 mod G(X))
// so that G(X) divides the coded message S(X) = P(X)*X^16 - R(X).
rs.encode(pout);
in.read(1);
out.written(1);
}
}
private:
rs_engine rs;
pipereader<tspacket> in;
pipewriter< rspacket<u8> > out;
}; // rs_encoder
// RS DECODER
template<typename Tbyte, int BYTE_ERASED>
struct rs_decoder : runnable {
rs_engine rs;
rs_decoder(scheduler *sch,
pipebuf< rspacket<Tbyte> > &_in,
pipebuf<tspacket> &_out,
pipebuf<int> *_bitcount=NULL,
pipebuf<int> *_errcount=NULL)
: runnable(sch, "RS decoder"),
in(_in), out(_out) {
bitcount = _bitcount ? new pipewriter<int>(*_bitcount) : NULL;
errcount = _errcount ? new pipewriter<int>(*_errcount) : NULL;
}
void run() {
if ( bitcount && bitcount->writable()<1 ) return;
if ( errcount && errcount->writable()<1 ) return;
int nbits=0, nerrs=0;
while ( in.readable()>=1 && out.writable()>=1 ) {
Tbyte *pin = in.rd()->data;
u8 *pout = out.wr()->data;
nbits += SIZE_RSPACKET * 8;
// The message is the first 188 bytes.
if ( sizeof(Tbyte) == 1 )
memcpy(pout, pin, SIZE_TSPACKET);
else
fail("Erasures not implemented");
u8 synd[16];
bool corrupted = rs.syndromes(pin, synd);
#if 0
if ( ! corrupted ) {
// Test BM
fprintf(stderr, "Simulating errors\n");
pin[203] ^= 42;
pin[202] ^= 99;
corrupted = rs.syndromes(pin, synd);
}
#endif
if ( ! corrupted ) {
if ( sch->debug )
fprintf(stderr, "_"); // Packet received without errors.
} else {
corrupted = rs.correct(synd, pout, pin, &nerrs);
if ( sch->debug ) {
if ( ! corrupted )
fprintf(stderr, "."); // Errors were corrected.
else
fprintf(stderr, "!"); // Packet still corrupted.
}
}
in.read(1);
// Output corrupted packets (with a special mark)
// otherwise the derandomizer will lose synchronization.
if ( corrupted ) pout[0] ^= MPEG_SYNC_CORRUPTED;
out.written(1);
}
if ( nbits ) {
if ( bitcount ) { *bitcount->wr()=nbits; bitcount->written(1); }
if ( errcount ) { *errcount->wr()=nerrs; errcount->written(1); }
}
}
private:
pipereader< rspacket<Tbyte> > in;
pipewriter<tspacket> out;
pipewriter<int> *bitcount, *errcount;
}; // rs_decoder
// RANDOMIZER
struct randomizer : runnable {

Wyświetl plik

@ -254,112 +254,6 @@ namespace leansdr {
};
// RS ENCODER
struct rs_encoder : runnable {
rs_encoder(scheduler *sch,
pipebuf<tspacket> &_in, pipebuf< rspacket<u8> > &_out)
: runnable(sch, "RS encoder"),
in(_in), out(_out) { }
void run() {
while ( in.readable()>=1 && out.writable()>=1 ) {
u8 *pin = in.rd()->data;
u8 *pout = out.wr()->data;
// The first 188 bytes are the uncoded message P(X)
memcpy(pout, pin, SIZE_TSPACKET);
// Append 16 RS parity bytes R(X) = - (P(X)*X^16 mod G(X))
// so that G(X) divides the coded message S(X) = P(X)*X^16 - R(X).
rs.encode(pout);
in.read(1);
out.written(1);
}
}
private:
rs_engine rs;
pipereader<tspacket> in;
pipewriter< rspacket<u8> > out;
}; // rs_encoder
// RS DECODER
template<typename Tbyte, int BYTE_ERASED>
struct rs_decoder : runnable {
rs_engine rs;
rs_decoder(scheduler *sch,
pipebuf< rspacket<Tbyte> > &_in,
pipebuf<tspacket> &_out,
pipebuf<int> *_bitcount=NULL,
pipebuf<int> *_errcount=NULL)
: runnable(sch, "RS decoder"),
in(_in), out(_out) {
bitcount = _bitcount ? new pipewriter<int>(*_bitcount) : NULL;
errcount = _errcount ? new pipewriter<int>(*_errcount) : NULL;
}
void run() {
if ( bitcount && bitcount->writable()<1 ) return;
if ( errcount && errcount->writable()<1 ) return;
int nbits=0, nerrs=0;
while ( in.readable()>=1 && out.writable()>=1 ) {
Tbyte *pin = in.rd()->data;
u8 *pout = out.wr()->data;
nbits += SIZE_RSPACKET * 8;
// The message is the first 188 bytes.
if ( sizeof(Tbyte) == 1 )
memcpy(pout, pin, SIZE_TSPACKET);
else
fail("Erasures not implemented");
u8 synd[16];
bool corrupted = rs.syndromes(pin, synd);
#if 0
if ( ! corrupted ) {
// Test BM
fprintf(stderr, "Simulating errors\n");
pin[203] ^= 42;
pin[202] ^= 99;
corrupted = rs.syndromes(pin, synd);
}
#endif
if ( ! corrupted ) {
if ( sch->debug )
fprintf(stderr, "_"); // Packet received without errors.
} else {
corrupted = rs.correct(synd, pout, pin, &nerrs);
if ( sch->debug ) {
if ( ! corrupted )
fprintf(stderr, "."); // Errors were corrected.
else
fprintf(stderr, "!"); // Packet still corrupted.
}
}
in.read(1);
// Output corrupted packets (with a special mark)
// otherwise the derandomizer will lose synchronization.
if ( corrupted ) pout[0] ^= MPEG_SYNC_CORRUPTED;
out.written(1);
}
if ( nbits ) {
if ( bitcount ) { *bitcount->wr()=nbits; bitcount->written(1); }
if ( errcount ) { *errcount->wr()=nerrs; errcount->written(1); }
}
}
private:
pipereader< rspacket<Tbyte> > in;
pipewriter<tspacket> out;
pipewriter<int> *bitcount, *errcount;
}; // rs_decoder
} // namespace
#endif // LEANSDR_RS_H