diff --git a/m10/AudioFile.cpp b/m10/AudioFile.cpp new file mode 100644 index 0000000..6ff5351 --- /dev/null +++ b/m10/AudioFile.cpp @@ -0,0 +1,171 @@ +/* + * File: AudioFile.cpp + * Author: Viproz + * Used code from rs1729 + * Created on January 6, 2019, 10:23 AM + */ + +#include "AudioFile.h" + +AudioFile::AudioFile(std::string filename, int baudrate, int* errors) { + baudRate = baudrate; + if (filename == "" || filename == "-") + fp = stdin; + else + fp = fopen(filename.c_str(), "rb"); + + if (!fp) { + fprintf(stderr, "%s could not be opened.\n", filename.c_str()); + *errors = -1; + return; + } + + if (read_wav_header()) { + fprintf(stderr, "Could not read the header.\n"); + *errors = -1; + return; + } + + *errors = 0; +} + +AudioFile::~AudioFile() { + if (fp) + fclose(fp); +} + +int AudioFile::read_wav_header() { + char txt[4 + 1] = "\0\0\0\0"; + unsigned char dat[4]; + int byte, p = 0; + + if (fread(txt, 1, 4, fp) < 4) return -1; + if (strncmp(txt, "RIFF", 4)) return -1; + if (fread(txt, 1, 4, fp) < 4) return -1; + // pos_WAVE = 8L + if (fread(txt, 1, 4, fp) < 4) return -1; + if (strncmp(txt, "WAVE", 4)) return -1; + // pos_fmt = 12L + for (;;) { + if ((byte = fgetc(fp)) == EOF) return -1; + txt[p % 4] = byte; + p++; + if (p == 4) p = 0; + if (findstr(txt, "fmt ", p) == 4) break; + } + if (fread(dat, 1, 4, fp) < 4) return -1; + if (fread(dat, 1, 2, fp) < 2) return -1; + + if (fread(dat, 1, 2, fp) < 2) return -1; + channels = dat[0] + (dat[1] << 8); + + if (fread(dat, 1, 4, fp) < 4) return -1; + memcpy(&sample_rate, dat, 4); //sample_rate = dat[0]|(dat[1]<<8)|(dat[2]<<16)|(dat[3]<<24); + + if (fread(dat, 1, 4, fp) < 4) return -1; + if (fread(dat, 1, 2, fp) < 2) return -1; + //byte = dat[0] + (dat[1] << 8); + + if (fread(dat, 1, 2, fp) < 2) return -1; + bits_sample = dat[0] + (dat[1] << 8); + + // pos_dat = 36L + info + for (;;) { + if ((byte = fgetc(fp)) == EOF) return -1; + txt[p % 4] = byte; + p++; + if (p == 4) p = 0; + if (findstr(txt, "data", p) == 4) break; + } + if (fread(dat, 1, 4, fp) < 4) return -1; + + + fprintf(stderr, "sample_rate: %d\n", sample_rate); + fprintf(stderr, "bits : %d\n", bits_sample); + fprintf(stderr, "channels : %d\n", channels); + + if ((bits_sample != 8) && (bits_sample != 16)) + return -1; + + samplesPerBit = sample_rate / (double) baudRate; + + fprintf(stderr, "samples/bit: %.2f\n", samplesPerBit); + + return 0; +} + +int AudioFile::findstr(char* buf, const char* str, int pos) { + int i; + for (i = 0; i < 4; i++) { + if (buf[(pos + i) % 4] != str[i]) break; + } + return i; +} + +int AudioFile::readSignedSample() { + int byte, i, sample = 0, s = 0; // EOF -> 0x1000000 + + for (i = 0; i < channels; i++) { + // i = 0: links bzw. mono + byte = fgetc(fp); + if (byte == EOF) + return EOF_INT; + if (i == targetedChannel) + sample = byte; + + if (bits_sample == 16) { + byte = fgetc(fp); + if (byte == EOF) + return EOF_INT; + if (i == targetedChannel) + sample += byte << 8; + } + + } + + if (bits_sample == 8) s = sample - 128; // 8bit: 00..FF, centerpoint 0x80=128 + if (bits_sample == 16) s = (short) sample; + + return s; +} + +int AudioFile::readSignedSampleAveraged() { + return averageSample(readSignedSample()); +} + +int AudioFile::readSignedSampleNormalized() { + return normalizeSample(readSignedSample()); +} + +int AudioFile::readSignedSampleAveragedNormalized() { + return averageNormalizeSample(readSignedSample()); +} + +int AudioFile::averageSample(int sample) { + if (sample == EOF_INT) + return EOF_INT; + // Average over the last AVG_NUM samples to comply with a global offset + activeSum = (activeSum + (double) sample)*(samplesPerBit * AVG_NUM) / (samplesPerBit * AVG_NUM + 1.); + return sample - activeSum / (samplesPerBit * AVG_NUM); +} + +int AudioFile::normalizeSample(int sample) { + if (sample == EOF_INT) + return EOF_INT; + return sample > 0 ? 1 : -1; +} + +int AudioFile::averageNormalizeSample(int sample) { + if (sample == EOF_INT) + return EOF_INT; + // Average over the last AVG_NUM samples to comply with a global offset + activeSum = (activeSum + (double) sample)*(samplesPerBit * AVG_NUM) / (samplesPerBit * AVG_NUM + 1.); + sample = sample - activeSum / (samplesPerBit * AVG_NUM); + return sample > 0 ? 1 : -1; +} + +void AudioFile::resetActiveSum() { + activeSum = 0; +} + + diff --git a/m10/AudioFile.h b/m10/AudioFile.h new file mode 100644 index 0000000..56e6dc2 --- /dev/null +++ b/m10/AudioFile.h @@ -0,0 +1,59 @@ +/* + * File: AudioFile.h + * Author: Viproz + * Used code from rs1729 + * Created on January 6, 2019, 10:23 AM + */ + +#ifndef AUDIOFILE_H +#define AUDIOFILE_H +#define EOF_INT 0x1000000 +#define AVG_NUM 5. + +#include +#include +#include +#include +#include + +class AudioFile { +public: + AudioFile(std::string filename, int baudrate, int* errors); + virtual ~AudioFile(); + + int read_wav_header(); + + int readSignedSample(); + int readSignedSampleAveraged(); + int readSignedSampleNormalized(); + int readSignedSampleAveragedNormalized(); + + int averageSample(int sample); + int normalizeSample(int sample); + int averageNormalizeSample(int sample); + + void resetActiveSum(); + + // Getters + int getSampleRate() { return sample_rate; } + double getSamplesPerBit() { return samplesPerBit; } + + // Setters + void setTargetedChannel(int channel) { targetedChannel = channel; } + void setBaudRate(int baudv) { baudRate = baudv; } +private: + int findstr(char* buf, const char* str, int pos); + + double activeSum = 0; + int targetedChannel = 0; + int sample_rate = 0; + int bits_sample = 0; + int channels = 0; + int baudRate; + double samplesPerBit = 0; + + FILE *fp; +}; + +#endif /* AUDIOFILE_H */ + diff --git a/m10/M10.cpp b/m10/M10.cpp index 8e7f400..f579286 100644 --- a/m10/M10.cpp +++ b/m10/M10.cpp @@ -27,9 +27,10 @@ int main(int argc, char** argv) { fprintf(stderr, " options:\n"); fprintf(stderr, " -v, --verbose Display even when CRC is wrong\n"); fprintf(stderr, " -R Show result at the end decoded/total\n"); - fprintf(stderr, " -r Display raw information\n"); + fprintf(stderr, " -r, --raw Display raw information\n"); fprintf(stderr, " -b Try alternative method after main method if it failed\n"); fprintf(stderr, " -b2 Try to repair data with the previous line\n"); + fprintf(stderr, " -s Try to repair data with stats if no data has been correctly decoded\n"); fprintf(stderr, " --ch2 Decode the second channel\n"); return 0; @@ -41,12 +42,13 @@ int main(int argc, char** argv) { decoder.setTryMethodSign(true); } else if (strcmp(*argv, "-b2") == 0) { decoder.setTryMethodRepair(true); + } else if (strcmp(*argv, "-s") == 0) { + decoder.setTryStats(true); } else if (strcmp(*argv, "-R") == 0) { decoder.setDispResult(true); } else if (strcmp(*argv, "--ch2") == 0) { - decoder.setChannel(1); - }// right channel (default: 0=left) - else { + decoder.setChannel(1); // right channel (default: 0=left) + } else { filename = *argv; } ++argv; diff --git a/m10/M10Decoder.cpp b/m10/M10Decoder.cpp index b9e4b11..2e0bab7 100644 --- a/m10/M10Decoder.cpp +++ b/m10/M10Decoder.cpp @@ -21,49 +21,47 @@ M10Decoder::~M10Decoder() { delete m10GTop; delete m10Ptu; - if (samplesPerBit != 0) + if (audioFile) delete frameSamples; + + if (audioFile) + delete audioFile; } int M10Decoder::startDecode(std::string fname) { filename = fname; - if (filename == "" || filename == "-") - fp = stdin; - else - fp = fopen(filename.c_str(), "rb"); + int error = 0; - if (fp == NULL) { - fprintf(stderr, "%s could not be opened.\n", filename.c_str()); - return -1; + audioFile = new AudioFile(fname, baudRate, &error); + + if (error) { + return error; } - if (read_wav_header()) { - fprintf(stderr, "Could not read the header.\n"); - return -1; - } + samplesPerBit = audioFile->getSamplesPerBit(); samplesBufLength = (DATA_LENGTH * 8 + 100) * samplesPerBit * 2; frameSamples = new std::vector(samplesBufLength); double res = 1; - int c = 0; - int correct = 0; bool supported = true; - while (res) { + while (res != EOF_INT) { res = findFrameStart(); - if (res == 0) + if (res == EOF_INT) break; - c++; + + totalFrames++; if (decodeMessage(res) == EOF_INT) break; - long sondeType = ((long) frame_bytes[0] << 16) + ((long) frame_bytes[1] << 8) + (long) frame_bytes[2]; + long sondeType = ((long) frame_bytes[1] << 8) + (long) frame_bytes[2]; + frameLength = frame_bytes[0]; supported = true; switch (sondeType) { - case 0x64AF02: + case 0xAF02: m10Parser = m10GTop; break; - case 0x649F20: + case 0x9F20: m10Parser = m10Ptu; break; default: @@ -77,19 +75,26 @@ int M10Decoder::startDecode(std::string fname) { continue; } if (correctCRC) { - correct++; + correctFrames++; lastGoodFrame = frame_bytes; } m10Parser->changeData(frame_bytes, correctCRC); m10Parser->printFrame(); - if (!correctCRC && tryRepair) - m10Parser->changeData(lastGoodFrame, true); + if (!correctCRC) { + if (correctFrames == 0 && tryStats) // Add the frame to the record + m10Parser->addToStats(); + else if (tryRepair && correctFrames != 0) // Put the last correct to repair + m10Parser->changeData(lastGoodFrame, correctFrames > 0); + } } } + if (tryStats && verboseLevel >= 1) + m10Parser->printStatsFrame(); + if (dispResult) - fprintf(stderr, "Result of %i/%i decoding\n", correct, c); + fprintf(stderr, "Result of %i/%i decoding\n", correctFrames, totalFrames); return 0; } @@ -108,11 +113,12 @@ double M10Decoder::findFrameStart() { int smallBufLen = (int) (samplesPerBit * 5.); std::vector vals(smallBufLen); int valIndex = 0; + double activeSum = 0; for (int j = 0; 1; ++j) { - v = readSignedSample(false); + v = audioFile->readSignedSample(); vals[valIndex++ % smallBufLen] = v; if (v == EOF_INT) - return 0; + return EOF_INT; // Average over the last 6 samples to comply with a global offset activeSum = (activeSum + (double) v)*(samplesPerBit * AVG_NUM) / (samplesPerBit * AVG_NUM + 1.); v = v - activeSum / (samplesPerBit * AVG_NUM); @@ -127,36 +133,31 @@ double M10Decoder::findFrameStart() { else decoded[currentIndex] = '0'; + // Store the position of the start of the bit posData[currentIndex] = (double) j - (1. - (double) i / round((double) len / samplesPerBit))*(double) len; char normal = 1; char inv = 1; int headerIndex = 0; - // currentIndex to the end - for (int l = currentIndex + 1; l < headerLength; ++l) { - if (decoded[l] == header[headerIndex]) - inv = 0; - else - normal = 0; - headerIndex++; - } - // The start to currentIndex - for (int l = 0; l < currentIndex; ++l) { - if (decoded[l] == header[headerIndex]) - inv = 0; - else - normal = 0; - headerIndex++; - } - if (normal || inv) { - // Calculate the real position of the data averaging over the 16 samples - double pos = 0; - for (int k = currentIndex; k < headerLength; ++k) - pos += posData[k] + (double) (headerLength - k) * samplesPerBit; - for (int k = 0; k < currentIndex; ++k) - pos += posData[k] + (double) (headerLength - k) * samplesPerBit; - pos /= headerLength; + // Check if the header is correct + for (int k = 0; k < headerLength; ++k) { + if (decoded[(k + currentIndex + 1) % headerLength] == header[headerIndex]) + inv = 0; + else + normal = 0; + headerIndex++; + } + + if (normal || inv) { + // Calculate the real position of the data averaging over the headerLength samples + double pos = 0; + for (int k = 0; k < headerLength; ++k) { + pos += posData[(k + currentIndex + 1) % headerLength] + (double) (headerLength - k) * samplesPerBit; + //fprintf(stderr, "%.2f\n", posData[(k + currentIndex + 1) % headerLength] + (double) (headerLength - k) * samplesPerBit); + } + + pos /= (double) headerLength; int tmpIndex = 0; valIndex--; @@ -171,8 +172,8 @@ double M10Decoder::findFrameStart() { frameSamples->at(curIndex) = vals.at(tmpIndex); } - pos = pos - (int) pos; - return pos; + // Only the weight of the first bit is useful, they are stored already + return pos - (int) pos; } currentIndex = (currentIndex + 1) % headerLength; @@ -180,13 +181,13 @@ double M10Decoder::findFrameStart() { len = 0; prevV = v; } - return 0; } int M10Decoder::decodeMessage(double initialPos) { + std::array frameBackup; int v; for (; curIndex < samplesBufLength; ++curIndex) { - v = readSignedSample(false); + v = audioFile->readSignedSample(); if (v == EOF_INT) return EOF_INT; frameSamples->at(curIndex) = v; @@ -203,10 +204,12 @@ int M10Decoder::decodeMessage(double initialPos) { if (ret == EOF_INT) return EOF_INT; - if (tryRepair) { + if ((tryRepair && correctFrames != 0) || (correctFrames == 0 && tryStats)) { + frameBackup = frame_bytes; frame_bytes = m10Parser->replaceWithPrevious(frame_bytes); if (checkCRC()) return 0; + frame_bytes = frameBackup; } if (trySign) { @@ -218,10 +221,12 @@ int M10Decoder::decodeMessage(double initialPos) { if (ret == EOF_INT) return EOF_INT; - if (tryRepair) { + if ((tryRepair && correctFrames != 0) || (correctFrames == 0 && tryStats)) { + frameBackup = frame_bytes; frame_bytes = m10Parser->replaceWithPrevious(frame_bytes); if (checkCRC()) return 0; + frame_bytes = frameBackup; } } @@ -233,9 +238,8 @@ int M10Decoder::decodeMethodCompare(double initialPos) { double j = initialPos; double sum = 0; - int val = readSignedSample(); // Read the first value - fpos_t tmp; - fgetpos(fp, &tmp); + int val = getNextBufferValue(); // Read the first value + if (val == EOF_INT) return EOF_INT; for (int k = 0; k < FRAME_LEN * 8 + AUX_LEN * 8 + 8; ++k) { // Iterate through needed bits @@ -243,12 +247,12 @@ int M10Decoder::decodeMethodCompare(double initialPos) { // Add the first part of the value weighted correctly sum = (1. - (j - floor(j)))*(double) val; for (int i = ceil(j); i < j + samplesPerBit - 1; ++i) { // Full vals in the middle - val = readSignedSample(); + val = getNextBufferValue(); if (val == EOF_INT) return EOF_INT; sum += (double) val; } - val = readSignedSample(); + val = getNextBufferValue(); if (val == EOF_INT) return EOF_INT; // Add the rest of the value @@ -261,12 +265,12 @@ int M10Decoder::decodeMethodCompare(double initialPos) { // Same for the second bit sum = (1 - (j - floor(j)))*(double) val; for (int i = ceil(j); i < j + samplesPerBit - 1; ++i) { // Full vals in the middle - val = readSignedSample(); + val = getNextBufferValue(); if (val == EOF_INT) return EOF_INT; sum += (double) val; } - val = readSignedSample(); + val = getNextBufferValue(); if (val == EOF_INT) return EOF_INT; sum += (j + samplesPerBit - floor(j + samplesPerBit))*(double) val; @@ -299,9 +303,8 @@ int M10Decoder::decodeMethodSign(double initialPos) { double j = initialPos; double sum = 0; - int val = readSignedSampleNormalized(); // Read the first value - fpos_t tmp; - fgetpos(fp, &tmp); + int val = audioFile->averageNormalizeSample(getNextBufferValue()); // Read the first value + if (val == EOF_INT) return EOF_INT; for (int k = 0; k < FRAME_LEN * 8 + AUX_LEN * 8 + 8; ++k) { // Iterate through needed bits @@ -309,13 +312,13 @@ int M10Decoder::decodeMethodSign(double initialPos) { // Add the first part of the value weighted correctly sum = (1. - (j - floor(j)))*(double) val; for (int i = ceil(j); i < j + samplesPerBit - 1; ++i) { // Full vals in the middle - val = readSignedSampleNormalized(); + val = audioFile->averageNormalizeSample(getNextBufferValue()); if (val == EOF_INT) return EOF_INT; sum += val; } - val = readSignedSampleNormalized(); + val = audioFile->averageNormalizeSample(getNextBufferValue()); if (val == EOF_INT) return EOF_INT; @@ -329,12 +332,12 @@ int M10Decoder::decodeMethodSign(double initialPos) { // Same for the second bit sum = (1 - (j - floor(j)))*(double) val; for (int i = ceil(j); i < j + samplesPerBit - 1; ++i) { // Full vals in the middle - val = readSignedSampleNormalized(); + val = audioFile->averageNormalizeSample(getNextBufferValue()); if (val == EOF_INT) return EOF_INT; sum += (double) val; } - val = readSignedSampleNormalized(); + val = audioFile->averageNormalizeSample(getNextBufferValue()); if (val == EOF_INT) return EOF_INT; sum += (j + samplesPerBit - floor(j + samplesPerBit))*(double) val; @@ -368,125 +371,24 @@ void M10Decoder::setRaw(bool b) { m10Ptu->setRaw(b); } -int M10Decoder::read_wav_header() { - char txt[4 + 1] = "\0\0\0\0"; - unsigned char dat[4]; - int byte, p = 0; - - if (fread(txt, 1, 4, fp) < 4) return -1; - if (strncmp(txt, "RIFF", 4)) return -1; - if (fread(txt, 1, 4, fp) < 4) return -1; - // pos_WAVE = 8L - if (fread(txt, 1, 4, fp) < 4) return -1; - if (strncmp(txt, "WAVE", 4)) return -1; - // pos_fmt = 12L - for (;;) { - if ((byte = fgetc(fp)) == EOF) return -1; - txt[p % 4] = byte; - p++; - if (p == 4) p = 0; - if (findstr(txt, "fmt ", p) == 4) break; - } - if (fread(dat, 1, 4, fp) < 4) return -1; - if (fread(dat, 1, 2, fp) < 2) return -1; - - if (fread(dat, 1, 2, fp) < 2) return -1; - channels = dat[0] + (dat[1] << 8); - - if (fread(dat, 1, 4, fp) < 4) return -1; - memcpy(&sample_rate, dat, 4); //sample_rate = dat[0]|(dat[1]<<8)|(dat[2]<<16)|(dat[3]<<24); - - if (fread(dat, 1, 4, fp) < 4) return -1; - if (fread(dat, 1, 2, fp) < 2) return -1; - //byte = dat[0] + (dat[1] << 8); - - if (fread(dat, 1, 2, fp) < 2) return -1; - bits_sample = dat[0] + (dat[1] << 8); - - // pos_dat = 36L + info - for (;;) { - if ((byte = fgetc(fp)) == EOF) return -1; - txt[p % 4] = byte; - p++; - if (p == 4) p = 0; - if (findstr(txt, "data", p) == 4) break; - } - if (fread(dat, 1, 4, fp) < 4) return -1; - - - fprintf(stderr, "sample_rate: %d\n", sample_rate); - fprintf(stderr, "bits : %d\n", bits_sample); - fprintf(stderr, "channels : %d\n", channels); - - if ((bits_sample != 8) && (bits_sample != 16)) return -1; - - samplesPerBit = sample_rate / (double) baudRate; - - fprintf(stderr, "samples/bit: %.2f\n", samplesPerBit); - - return 0; -} - -int M10Decoder::readSignedSample(bool buffer) { - if (buffer) { - if (curIndex < samplesBufLength) - return frameSamples->at(curIndex++); - else { - fprintf(stderr, "Error, end of buffer.\n"); - return EOF_INT; - } - } - - int byte, i, sample = 0, s = 0; // EOF -> 0x1000000 - - for (i = 0; i < channels; i++) { - // i = 0: links bzw. mono - byte = fgetc(fp); - if (byte == EOF) return EOF_INT; - if (i == targetedChannel) sample = byte; - - if (bits_sample == 16) { - byte = fgetc(fp); - if (byte == EOF) return EOF_INT; - if (i == targetedChannel) sample += byte << 8; - } - - } - - if (bits_sample == 8) s = sample - 128; // 8bit: 00..FF, centerpoint 0x80=128 - if (bits_sample == 16) s = (short) sample; - - return s; -} - -int M10Decoder::readSignedSampleNormalized(bool buffer) { - int v = readSignedSample(buffer); - if (v == EOF_INT) +int M10Decoder::getNextBufferValue() { + if (curIndex < samplesBufLength) + return frameSamples->at(curIndex++); + else { + fprintf(stderr, "Error, end of buffer.\n"); return EOF_INT; - // Average over the last 6 samples to comply with a global offset - activeSum = (activeSum + (double) v)*(samplesPerBit * AVG_NUM) / (samplesPerBit * AVG_NUM + 1.); - v = v - activeSum / (samplesPerBit * AVG_NUM); - return v > 0 ? 1 : -1; - -} - -int M10Decoder::findstr(char* buf, const char* str, int pos) { - int i; - for (i = 0; i < 4; i++) { - if (buf[(pos + i) % 4] != str[i]) break; } - return i; } bool M10Decoder::checkCRC() { int i, cs; cs = 0; - for (i = 0; i < pos_Check; i++) { + for (i = 0; i < frameLength-1; i++) { cs = update_checkM10(cs, frame_bytes[i]); } - return ((cs & 0xFFFF) != 0) && ((cs & 0xFFFF) == ((frame_bytes[pos_Check] << 8) | frame_bytes[pos_Check + 1])); + return ((cs & 0xFFFF) != 0) && ((cs & 0xFFFF) == ((frame_bytes[frameLength-1] << 8) | frame_bytes[frameLength])); } int M10Decoder::update_checkM10(int c, unsigned short b) { diff --git a/m10/M10Decoder.h b/m10/M10Decoder.h index 35f9916..201731d 100644 --- a/m10/M10Decoder.h +++ b/m10/M10Decoder.h @@ -17,12 +17,12 @@ #define AVG_NUM 5. -#include #include #include #include #include #include "M10GeneralParser.h" +#include "AudioFile.h" class M10Decoder { public: @@ -37,14 +37,13 @@ public: void setChannel(int c) {targetedChannel = c;} void setTryMethodSign(bool b) {trySign = b;} void setTryMethodRepair(bool b) {tryRepair = b;} + void setTryStats(bool b) {tryStats = b;} void setVerboseLevel(int level) {verboseLevel = level;} -private: + +protected: int decodeMethodCompare(double initialPos); int decodeMethodSign(double initialPos); - int read_wav_header(); - int readSignedSample(bool buffer = true); - int readSignedSampleNormalized(bool buffer = true); - int findstr(char *buf, const char *str, int pos); + int getNextBufferValue(); bool checkCRC(); int update_checkM10(int c, unsigned short b); void bits2bytes(); @@ -52,25 +51,27 @@ private: M10GeneralParser *m10Parser; M10GeneralParser *m10GTop; M10GeneralParser *m10Ptu; - FILE *fp; + + AudioFile *audioFile; + bool dispResult = false; bool dispRaw = false; bool trySign = false; bool tryRepair = false; + bool tryStats = false; int verboseLevel = 0; int targetedChannel = 0; - int sample_rate = 0; - int bits_sample = 0; - int channels = 0; double samplesPerBit = 0; double baudRate = 9615; - double activeSum = 0; static char header[]; std::string filename; std::vector *frameSamples; int curIndex = 0; int samplesBufLength = 0; + int correctFrames = 0; + int totalFrames = 0; + int frameLength = 0; std::array frame_bytes; std::array frame_bits; diff --git a/m10/M10GTopParser.cpp b/m10/M10GTopParser.cpp index 59f5988..e168294 100644 --- a/m10/M10GTopParser.cpp +++ b/m10/M10GTopParser.cpp @@ -29,8 +29,7 @@ M10GTopParser::~M10GTopParser() { } void M10GTopParser::changeData(std::array data, bool good) { - correctCRC = good; - frame_bytes = data; + M10GeneralParser::changeData(data, good); int i; unsigned short bytes[4]; @@ -236,7 +235,7 @@ std::string M10GTopParser::getdxlSerialNumber() { void M10GTopParser::printFrame() { if (dispRaw) { - for (int i = 0; i < FRAME_LEN; ++i) { + for (int i = 0; i < frameLength + 1; ++i) { printf("%02X", frame_bytes[i]); } if (correctCRC) diff --git a/m10/M10GeneralParser.cpp b/m10/M10GeneralParser.cpp index 00974e2..42c4804 100644 --- a/m10/M10GeneralParser.cpp +++ b/m10/M10GeneralParser.cpp @@ -6,6 +6,7 @@ */ #include "M10GeneralParser.h" +#include "M10PtuParser.h" M10GeneralParser::M10GeneralParser() { } @@ -16,6 +17,7 @@ M10GeneralParser::~M10GeneralParser() { void M10GeneralParser::changeData(std::array data, bool good) { correctCRC = good; frame_bytes = data; + frameLength = frame_bytes[0]; } double M10GeneralParser::getLatitude() { @@ -74,4 +76,30 @@ std::array M10GeneralParser::replaceWithPrevious(std return data; } +void M10GeneralParser::addToStats() { + for (int i = 0; i < DATA_LENGTH; ++i) { + ++statValues[i][frame_bytes[i]]; + } +} +void M10GeneralParser::printStatsFrame() { + u_short valMax; + u_short posMax; + + for (int i = 0; i < FRAME_LEN; ++i) { + valMax = 0; + posMax = 0; + for (u_short k = 0; k < 0xFF+1; ++k) { // Find maximum + if (statValues[i][k] > valMax) { + valMax = statValues[i][k]; + posMax = k; + } + } + frame_bytes[i] = posMax; + } + + changeData(frame_bytes, false); + + printf("Stats frame:\n"); + printFrame(); +} diff --git a/m10/M10GeneralParser.h b/m10/M10GeneralParser.h index 55fa4df..288c869 100644 --- a/m10/M10GeneralParser.h +++ b/m10/M10GeneralParser.h @@ -35,12 +35,16 @@ public: std::array getFrameBytes() {return frame_bytes;} virtual std::array replaceWithPrevious(std::array data); + virtual void addToStats(); + virtual void printStatsFrame(); virtual void printFrame() = 0; protected: std::array frame_bytes; + std::array, DATA_LENGTH> statValues = {}; bool correctCRC; bool dispRaw = false; + int frameLength = 0; }; #endif /* M10GENERALDECODER_H */ diff --git a/m10/M10PtuParser.cpp b/m10/M10PtuParser.cpp index 677ebe7..7ea758d 100644 --- a/m10/M10PtuParser.cpp +++ b/m10/M10PtuParser.cpp @@ -22,7 +22,7 @@ #include "M10PtuParser.h" char M10PtuParser::similarData[] = "xxxx----------------------xxxxxxxxxxxxxxxxxxxxxxxxxxx---xxxxxxx--xxxx-----xx----xxxxx------xxxxxxx---"; -char M10PtuParser::insertSpaces[] = "---xx-x-x-x---x---x---x---x-----x-x-----------x---x--x--x-----xx-x-x-x-xx-x-x-x-x----x---x-x-x----xx-"; +char M10PtuParser::insertSpaces[] = "---xx-x-x-x---x---x---x---x-----x-x-----------x---x--x--x-----xx-x-x-x-xx-x-x-x-x----x---x-x-x----xxxx-x-------------x"; M10PtuParser::M10PtuParser() { } @@ -31,8 +31,7 @@ M10PtuParser::~M10PtuParser() { } void M10PtuParser::changeData(std::array data, bool good) { - correctCRC = good; - frame_bytes = data; + M10GeneralParser::changeData(data, good); int i; unsigned byte; @@ -248,7 +247,7 @@ double M10PtuParser::getTemperature() { unsigned char scT; // {0,1,2}, range/scale voltage divider unsigned short ADC_RT; // ADC12 P6.7(A7) , adr_0377h,adr_0376h - unsigned short Tcal[2]; // adr_1000h[scT*4] + //unsigned short Tcal[2]; // adr_1000h[scT*4] float adc_max = 4095.0; // ADC12 float x, R; @@ -257,8 +256,8 @@ double M10PtuParser::getTemperature() { scT = frame_bytes[0x3E]; // adr_0455h ADC_RT = (frame_bytes[0x40] << 8) | frame_bytes[0x3F]; ADC_RT -= 0xA000; - Tcal[0] = (frame_bytes[0x42] << 8) | frame_bytes[0x41]; - Tcal[1] = (frame_bytes[0x44] << 8) | frame_bytes[0x43]; + //Tcal[0] = (frame_bytes[0x42] << 8) | frame_bytes[0x41]; // Unused for now + //Tcal[1] = (frame_bytes[0x44] << 8) | frame_bytes[0x43]; x = (adc_max - ADC_RT) / ADC_RT; // (Vcc-Vout)/Vout if (scT < 3) @@ -354,11 +353,31 @@ std::string M10PtuParser::getdxlSerialNumber() { } std::array M10PtuParser::replaceWithPrevious(std::array data) { - for (int i = 0; i < FRAME_LEN; ++i) { - if (similarData[i] == 'x') { - if(data[i] != frame_bytes[i]) + u_short valMax; + u_short posMax; + + if (!correctCRC) { // Use probabilities + int threshold = statValues[0][0x64] / 2; // more than 50% + if (threshold > 4) { // Meaning less under 4 values + for (int i = 0; i < FRAME_LEN; ++i) { + if (similarData[i] == 'x') { + valMax = 0; + posMax = 0; + for (u_short k = 0; k < 0xFF + 1; ++k) { // Find maximum + if (statValues[i][k] > valMax) { + valMax = statValues[i][k]; + posMax = k; + } + } + data[i] = posMax; + } + } + } + } else { // Use correct frame + for (int i = 0; i < FRAME_LEN; ++i) { + if (similarData[i] == 'x') { data[i] = frame_bytes[i]; - data[i] = frame_bytes[i]; + } } } return data; @@ -366,7 +385,7 @@ std::array M10PtuParser::replaceWithPrevious(std::ar void M10PtuParser::printFrame() { if (dispRaw) { - for (int i = 0; i < FRAME_LEN; ++i) { + for (int i = 0; i < frameLength + 1; ++i) { if (insertSpaces[i] == 'x') printf(" "); printf("%02X", frame_bytes[i]);