kopia lustrzana https://github.com/pabr/leansdr
Split generic RS implementation from DVB-specific code
rodzic
adc50bf825
commit
17c5918a7c
|
@ -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 {
|
||||
|
|
106
src/leansdr/rs.h
106
src/leansdr/rs.h
|
@ -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
|
||||
|
|
Ładowanie…
Reference in New Issue