Hi,
even a year ago, I would like to answer, since there is no other discussion place, regarding this issue.
I downloaded you attached file an found the following first few bytes
a8 61 00 00 b4 01 ff 07 3a b6 00 82 10 69 00 00
88 15 04 2a 48 12 00 00 e9 ab
The meaning of this as follow (taken from
http://www.etsi.org/deliver/etsi_i_ets%5C300700_300799%5C300799%5C01_60%5Cets_300799e01p.pdf)
a8 61 00 00 // number of frames in file (not defined in standard)
b4 01 // len of next file 0x01B4 = 436 (not defined in standard)
ff 07 3a b6 // header (Chapter 6.1)
00 82 10 69 // Frame Characterization field (FC) 0x82 and 0x7F = 2 NST (Number of Stream Characterization)
00 00 88 15 // 1. Stream Characterization (STC)
04 2a 48 12 // 2. Stream Characterization (STC)
00 00 e9 ab // EOH (End Of Header 0xe9 0xab = CRC Checksum
On Page
http://www.sdr-j.tk/index.html you can find the download link to a DAB software. In the software in the file "fic_handler.cpp" is the following code included, which does the bit-wise CRC calculation, corresponding to the picture on Annex D of ETS 300 799 linked above.
As you see there is a different loop back made.
In standard CRC the
- next new bit is made from the XOR of the Input and the MSB of the current CRC
- the CRC stages are XOR'ed, if the MSB by the current CRC is "1"
In the ETI standard
- next new bit is made from the XOR of the Input and the MSB of the current CRC (same as above)
- the CRC stages are XOR'ed, if the next new bit is one.
static
const uint8_t crcPolynome [] =
{0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0}; // MSB .. LSB
bool ficHandler::check_ficCRC (uint8_t *in, int16_t size) {
int16_t i, f;
uint8_t b [16];
int16_t Sum = 0;
memset (b, 1, 16);
for (i = size - 16; i < size; i ++) //inversion of the CRC, as it is inverted transmitted
in [i] ^= 1;
for (i = 0; i < size; i++) {
if ((b [0] ^ in [i]) == 1) { // this is the difference to the "standard" CRC
for (f = 0; f < 15; f++)
b [f] = crcPolynome [f] ^ b[f + 1];
b [15] = 1;
}
else {
memmove (&b [0], &b[1], sizeof (uint8_t ) * 15); // Shift
b [15] = 0;
}
}
for (i = 0; i < 16; i++)
Sum += b [i];
return Sum == 0;
}
the above given data passed to this function (after a byte to bit string conversion!!) will calculate the correct CRC wich is 0.
My problem with the code above is, that it is painful slow.
The standard CRC alogrithm offers the possibility to pre calculate a table with 256 entries (one for each possible input byte combinations) and a charming fast single line calculation of the CRC
return = Hi(CRCOld) ^ CRCETITable[b ^ Lo(CRCOld)];
Due to the fact that the ETI calculation of CRC words uses the xor'ed input bit and MSB of the current state as input, instead of a direct linkback in the standard CRC, this approach does not work.
Question: Is there any simple approach to fix this? I think there must be an other possibility instead of building a 16MByte table for every CRC state and every input Byte.
Best regard
Ekkehard Domning