|
|
|
|
@ -120,6 +120,30 @@ uint16_t rds_decoder_redsea_impl::calc_syndrome(uint32_t message,uint8_t mlen) {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//redsea stuff:
|
|
|
|
|
// Section B.1.1: '-- calculated by the modulo-two addition of all the rows of
|
|
|
|
|
// the -- matrix for which the corresponding coefficient in the -- vector is 1.'
|
|
|
|
|
uint32_t matrixMultiply(uint32_t vec, const std::vector<uint32_t>& matrix) { |
|
|
|
|
uint32_t result = 0; |
|
|
|
|
|
|
|
|
|
for (size_t k=0; k < matrix.size(); k++) |
|
|
|
|
if ((vec >> k) & 0x01) |
|
|
|
|
result ^= matrix[matrix.size() - 1 - k]; |
|
|
|
|
|
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Section B.2.1: 'The calculation of the syndromes -- can easily be done by
|
|
|
|
|
// multiplying each word with the parity matrix H.'
|
|
|
|
|
uint32_t calcSyndrome_vec(uint32_t vec) { |
|
|
|
|
static const std::vector<uint32_t> parity_check_matrix({ |
|
|
|
|
0x200, 0x100, 0x080, 0x040, 0x020, 0x010, 0x008, 0x004, |
|
|
|
|
0x002, 0x001, 0x2dc, 0x16e, 0x0b7, 0x287, 0x39f, 0x313, |
|
|
|
|
0x355, 0x376, 0x1bb, 0x201, 0x3dc, |
|
|
|
|
0x1ee, 0x0f7, 0x2a7, 0x38f, 0x31b |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
return matrixMultiply(vec, parity_check_matrix); |
|
|
|
|
} |
|
|
|
|
const unsigned kBitmask16 = 0x000FFFF; |
|
|
|
|
const unsigned kBitmask26 = 0x3FFFFFF; |
|
|
|
|
const unsigned kBitmask28 = 0xFFFFFFF; |
|
|
|
|
@ -144,8 +168,8 @@ static const char * const offset_name[]={"A","B","C","D","c"};*/
|
|
|
|
|
for (uint32_t e : {0x1,0x3}) {//fix up to 2-bit burst errors (as book says)
|
|
|
|
|
for (int shift=0; shift < 26; shift++) { |
|
|
|
|
uint32_t errvec = ((e << shift) & kBitmask26); |
|
|
|
|
//uint16_t sy = calc_syndrome(errvec ^ offset_word[offset_num],26);
|
|
|
|
|
uint32_t sy = calc_syndrome(errvec ^ offset_word[offset_num],26);//why uint32 and not uint16 as everywhere else???
|
|
|
|
|
//uint32_t sy = calcSyndrome_vec(errvec ^ offset_word[offset_num]);
|
|
|
|
|
result.insert({{sy, offset_name[offset_num]}, errvec}); |
|
|
|
|
//dout << "adding sy:"<<sy<<"\t\toffset:"<<offset_name[offset_num]<<"\terrvec:"<<std::bitset<32>(errvec) <<std::endl;
|
|
|
|
|
} |
|
|
|
|
@ -155,14 +179,15 @@ static const char * const offset_name[]={"A","B","C","D","c"};*/
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
uint32_t rds_decoder_redsea_impl::correctBurstErrors(uint32_t block, char offset) { |
|
|
|
|
uint16_t syndrome = calc_syndrome(block,26); |
|
|
|
|
uint32_t syndrome = calc_syndrome(block,26); |
|
|
|
|
//uint32_t syndrome = calcSyndrome_vec(block);
|
|
|
|
|
uint32_t corrected_block = block; |
|
|
|
|
//dout << "trying to correct sy:"<<syndrome<<"\t\toffset:"<<offset;//<<std::endl;
|
|
|
|
|
//dout << "\tcount:"<<kErrorLookup.count({(uint16_t)syndrome, (char)offset})<<std::endl;
|
|
|
|
|
if (kErrorLookup.count({(uint16_t)syndrome, (char)offset}) > 0) { |
|
|
|
|
uint32_t err = kErrorLookup.at({(uint16_t)syndrome, (char)offset}); |
|
|
|
|
if (kErrorLookup.count({syndrome, offset}) > 0) { |
|
|
|
|
uint32_t err = kErrorLookup.at({syndrome, offset}); |
|
|
|
|
//dout << "correcting"<<std::endl;
|
|
|
|
|
err=0;//correction disabled
|
|
|
|
|
//err=0;//correction disabled
|
|
|
|
|
corrected_block ^= err; |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|