diff --git a/README.md b/README.md index 592e033..3db1a69 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,13 @@ Quick start: -Encode file ```uncoded.dat``` with ```64800``` bits to ```encoded.wav``` [WAV](https://en.wikipedia.org/wiki/WAV) audio file with 8000 Hz sample rate, 16 bits and only 1 (real) channel: +Create file ```uncoded.dat``` with ```64768``` bits of random data: + +``` +dd if=/dev/urandom of=uncoded.dat bs=1 count=8096 +``` + +Encode file ```uncoded.dat``` to ```encoded.wav``` [WAV](https://en.wikipedia.org/wiki/WAV) audio file with 8000 Hz sample rate, 16 bits and only 1 (real) channel: ``` ./encode encoded.wav 8000 16 1 uncoded.dat diff --git a/decode.cc b/decode.cc index 7011dac..7786ef1 100644 --- a/decode.cc +++ b/decode.cc @@ -174,7 +174,8 @@ struct Decoder DSP::Resampler resample; DSP::BipBuffer input_hist; SchmidlCox correlator; - CODE::CRC crc; + CODE::CRC crc0; + CODE::CRC crc1; CODE::OrderedStatisticsDecoder<255, 71, 4> osddec; int8_t genmat[255*71]; cmplx head[symbol_len], tail[symbol_len]; @@ -232,7 +233,7 @@ struct Decoder return sum / (count * symbol_len/2); } Decoder(uint8_t *out, DSP::ReadPCM *pcm, int skip_count) : - pcm(pcm), resample(rate, (rate * 19) / 40, 2), correlator(mls0_seq()), crc(0xA8F4) + pcm(pcm), resample(rate, (rate * 19) / 40, 2), correlator(mls0_seq()), crc0(0xA8F4), crc1(0xD419CC15) { CODE::BoseChaudhuriHocquenghemGenerator<255, 71>::matrix(genmat, true, { 0b100011101, 0b101110111, 0b111110011, 0b101101001, @@ -287,9 +288,9 @@ struct Decoder uint16_t cs = 0; for (int i = 0; i < 16; ++i) cs |= (uint16_t)CODE::get_be_bit(data, i+55) << i; - crc.reset(); - if (crc(md<<9) != cs) { - std::cerr << "CRC error." << std::endl; + crc0.reset(); + if (crc0(md<<9) != cs) { + std::cerr << "header CRC error." << std::endl; return; } if ((md&255) != 2) { @@ -339,6 +340,11 @@ struct Decoder } } } + crc1.reset(); + for (int i = 0; i < data_bits / 8; ++i) + crc1(out[i]); + if (crc1()) + std::cerr << "payload CRC error." << std::endl; } }; @@ -366,8 +372,8 @@ int main(int argc, char **argv) if (argc > 3) skip_count = std::atoi(argv[3]); - const int length = 64800 / 8; - uint8_t *output_data = new uint8_t[length]; + const int code_len = 64800 / 8; + uint8_t *output_data = new uint8_t[code_len]; switch (input_file.rate()) { case 8000: @@ -392,7 +398,8 @@ int main(int argc, char **argv) std::cerr << "Couldn't open file \"" << output_name << "\" for writing." << std::endl; return 1; } - for (int i = 0; i < length; ++i) + const int data_len = code_len - 32 / 8; + for (int i = 0; i < data_len; ++i) output_file.put(output_data[i]); delete []output_data; return 0; diff --git a/encode.cc b/encode.cc index 188dfb1..46b82b6 100644 --- a/encode.cc +++ b/encode.cc @@ -36,7 +36,8 @@ struct Encoder static const int mls2_poly = 0b100101010001; DSP::WritePCM *pcm; DSP::FastFourierTransform bwd; - CODE::CRC crc; + CODE::CRC crc0; + CODE::CRC crc1; CODE::BoseChaudhuriHocquenghemEncoder<255, 71> bchenc; cmplx fdom[symbol_len]; cmplx tdom[symbol_len]; @@ -109,8 +110,8 @@ struct Encoder uint8_t data[9] = { 0 }, parity[23] = { 0 }; for (int i = 0; i < 55; ++i) CODE::set_be_bit(data, i, (md>>i)&1); - crc.reset(); - uint16_t cs = crc(md << 9); + crc0.reset(); + uint16_t cs = crc0(md << 9); for (int i = 0; i < 16; ++i) CODE::set_be_bit(data, i+55, (cs>>i)&1); bchenc(data, parity); @@ -130,7 +131,7 @@ struct Encoder symbol(); } Encoder(DSP::WritePCM *pcm, uint8_t *inp, int freq_off, uint64_t call_sign) : - pcm(pcm), crc(0xA8F4), bchenc({ + pcm(pcm), crc0(0xA8F4), crc1(0xD419CC15), bchenc({ 0b100011101, 0b101110111, 0b111110011, 0b101101001, 0b110111101, 0b111100111, 0b100101011, 0b111010111, 0b000010011, 0b101100101, 0b110001011, 0b101100011, @@ -146,6 +147,11 @@ struct Encoder schmidl_cox(); meta_data((call_sign << 8) | 2); pilot_block(); + crc1.reset(); + for (int i = 0; i < (data_bits-32)/8; ++i) + crc1(inp[i]); + for (int i = 0; i < 4; ++i) + inp[(data_bits-32)/8+i] = (crc1() >> (8*i)) & 255; for (int j = 0; j < data_rows; ++j) { for (int i = 0; i < data_cols; ++i) { value tmp[Mod::BITS]; @@ -225,9 +231,10 @@ int main(int argc, char **argv) std::cerr << "Couldn't open file \"" << input_name << "\" for reading." << std::endl; return 1; } - const int length = 64800 / 8; - uint8_t *input_data = new uint8_t[length]; - for (int i = 0; i < length; ++i) + const int code_len = 64800 / 8; + const int data_len = code_len - 32 / 8; + uint8_t *input_data = new uint8_t[code_len]; + for (int i = 0; i < data_len; ++i) input_data[i] = input_file.get(); DSP::WriteWAV output_file(output_name, output_rate, output_bits, output_chan);