Behave correctly with aux data (not decoding)

Added fundamental stats system
Moved audio file operations to another class for better modularity
pull/96/head
Viproz 2019-01-19 12:26:19 +01:00
rodzic 659c5ca3fe
commit 5dcb126762
9 zmienionych plików z 392 dodań i 207 usunięć

171
m10/AudioFile.cpp 100644
Wyświetl plik

@ -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;
}

59
m10/AudioFile.h 100644
Wyświetl plik

@ -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 <stdio.h>
#include <string>
#include <cstring>
#include <cmath>
#include <vector>
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 */

Wyświetl plik

@ -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;

Wyświetl plik

@ -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<int>(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<int> 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<unsigned char, DATA_LENGTH> 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) {

Wyświetl plik

@ -17,12 +17,12 @@
#define AVG_NUM 5.
#include <stdio.h>
#include <string>
#include <cstring>
#include <cmath>
#include <vector>
#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<int> *frameSamples;
int curIndex = 0;
int samplesBufLength = 0;
int correctFrames = 0;
int totalFrames = 0;
int frameLength = 0;
std::array<unsigned char, DATA_LENGTH> frame_bytes;
std::array<unsigned char, (DATA_LENGTH)*8> frame_bits;

Wyświetl plik

@ -29,8 +29,7 @@ M10GTopParser::~M10GTopParser() {
}
void M10GTopParser::changeData(std::array<unsigned char, DATA_LENGTH> 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)

Wyświetl plik

@ -6,6 +6,7 @@
*/
#include "M10GeneralParser.h"
#include "M10PtuParser.h"
M10GeneralParser::M10GeneralParser() {
}
@ -16,6 +17,7 @@ M10GeneralParser::~M10GeneralParser() {
void M10GeneralParser::changeData(std::array<unsigned char, DATA_LENGTH> data, bool good) {
correctCRC = good;
frame_bytes = data;
frameLength = frame_bytes[0];
}
double M10GeneralParser::getLatitude() {
@ -74,4 +76,30 @@ std::array<unsigned char, DATA_LENGTH> 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();
}

Wyświetl plik

@ -35,12 +35,16 @@ public:
std::array<unsigned char, DATA_LENGTH> getFrameBytes() {return frame_bytes;}
virtual std::array<unsigned char, DATA_LENGTH> replaceWithPrevious(std::array<unsigned char, DATA_LENGTH> data);
virtual void addToStats();
virtual void printStatsFrame();
virtual void printFrame() = 0;
protected:
std::array<unsigned char, DATA_LENGTH> frame_bytes;
std::array<std::array<u_short, 0xFF+1>, DATA_LENGTH> statValues = {};
bool correctCRC;
bool dispRaw = false;
int frameLength = 0;
};
#endif /* M10GENERALDECODER_H */

Wyświetl plik

@ -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<unsigned char, DATA_LENGTH> 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<unsigned char, DATA_LENGTH> M10PtuParser::replaceWithPrevious(std::array<unsigned char, DATA_LENGTH> 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<unsigned char, DATA_LENGTH> 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]);