Your file seems to go like:
51A0
52A0
52A0
53A0
53A0
_
52A0 = 20:02:36
53A0 = 20:02:38 in dos time
If its dos time it would make sense why every pattern(51A0, 52A0) is shown 2 times since dos time doesnt accept odd numbers as seconds.
Theory 1:
I dont think anything natural such as sound would go DA,5A,DA,5A,DA,5A,DA,5A,DA,5A.
So I assume that DA shows the lower part and 5A is the higher part. (DA=+0 and 5A=+1)
5A 52 A0 = 20:02:36
DA 52 A0 = 20:02:37
5A 53 A0 = 20:02:38
DA 53 A0 = 20:02:39
I'm dont know alot about measuring sound but I can make assumptions based on the first byte too. But this maybe wrong since you didnt give any information about the sound you captured.
1st byte is Max: 0x47(71) Min: 0x8(8) on your file.
On the amazon page it says (30 ~ 130 Db)
8 wouldnt fit those ranges so I assume the first byte is an offset.
130-30=100 -> 0 > x > 100.
Every 4 byte has this information:
struct Frame{
char SoundOffset;
char TimeOffset;
char DosTime[2];
}
I wrote a sample code for your data.
#define _CRT_SECURE_NO_WARNINGS
#include <Windows.h>
#include <string>
#include <iostream>
#include <fstream>
#include <iostream>
using namespace std;
struct DosTime{
int hour, minute, second;
DosTime(char a1, char a2){
char y[2] = { a1, a2 };
INT16 * b = (INT16*)y;
second = 2 * (*b & 31);
minute = (*b & 2016) >> 5;
hour = (*b & 63488) >> 11;
}
DosTime(){
hour = 0;
minute = 0;
second = 0;
}
};
struct Frame{
char SoundOffset;
char TimeOffset;
char DosTime[2];
};
struct ConvertedFrame{
int soundDB;
DosTime time;
void print(){
cout << "Sound Level: " << soundDB << " dB @ ";
cout.fill('0'); cout.width(2); cout << time.hour;
cout << ":";
cout.fill('0'); cout.width(2); cout << time.minute;
cout << ":";
cout.fill('0'); cout.width(2); cout << time.second;
cout << endl;
}
};
int main(int argc, char* argv[])
{
int bytecount = 0;
ifstream inFile;
inFile.open("FG8U0235.wsn", ios::in | ios::binary | ios::ate);
inFile.seekg(0, ios::end);
bytecount = inFile.tellg();
inFile.seekg(0, ios::beg);
char * buffer = new char[bytecount];
inFile.read(buffer, bytecount);
ConvertedFrame * frames = new ConvertedFrame[bytecount / 4];
for (int i = 0; i < bytecount; i += 4){
ConvertedFrame _con;
Frame f;
memcpy(&f, &buffer[i], 4);
DosTime _t = DosTime(f.DosTime[0], f.DosTime[1]);
if (f.TimeOffset == '\xDA')
_t.second++;
_con.time = _t;
_con.soundDB = ((int)f.SoundOffset) + 30;
frames[i / 4] = _con;
_con.print();
}
system("pause");
return 0;
}
Which outputs:
Sound Level: 61 dB @ 20:02:35
Sound Level: 55 dB @ 20:02:36
Sound Level: 55 dB @ 20:02:37
Sound Level: 70 dB @ 20:02:36
Sound Level: 70 dB @ 20:02:39
Sound Level: 66 dB @ 20:02:40
Sound Level: 56 dB @ 20:02:41
Sound Level: 72 dB @ 20:02:42
Sound Level: 68 dB @ 20:02:43
Sound Level: 68 dB @ 20:02:44
Sound Level: 38 dB @ 20:02:45
Sound Level: 101 dB @ 20:02:46
Sound Level: 83 dB @ 20:02:47
Sound Level: 80 dB @ 20:02:48
Sound Level: 89 dB @ 20:02:49
Theory 2:
On the site you gave us (http://opensource.ebswift.com/RaspiMonitor/wensn/), there was this function (dB = (byte1 + ((byte2 & 3) * 256)) * 0.1 + 30) that made me think that maybe the 2nd byte is actually not the timeoffset but the 2nd byte for the dB.
This makes dB Float instead of Integer which would make much more sense. Also the output I got from the 2nd theory felt much better so I assume this is the correct answer.
#define _CRT_SECURE_NO_WARNINGS
#include <Windows.h>
#include <string>
#include <fstream>
#include <iostream>
using namespace std;
struct DosTime{
int hour, minute, second;
INT16 data;
DosTime(char a1, char a2){
char y[2] = { a1, a2 };
INT16 * b = (INT16*)y;
second = 2 * (*b & 31);
minute = (*b & 2016) >> 5;
hour = (*b & 63488) >> 11;
data = *b;
}
DosTime(){
hour = 0;
minute = 0;
second = 0;
}
};
struct Frame{
char SoundOffset;
char precisionOffset;
char DosTime[2];
};
struct ConvertedFrame{
float soundDB;
DosTime time;
void print(){
cout << "Sound Level: ";
cout << soundDB;
if ((((int)soundDB) - soundDB) == 0) cout << ".0";
cout << " dB @ ";
cout.fill('0'); cout.width(2); cout << time.hour;
cout << ":";
cout.fill('0'); cout.width(2); cout << time.minute;
cout << ":";
cout.fill('0'); cout.width(2); cout << time.second;
cout << endl;
}
};
int main(int argc, char* argv[])
{
int bytecount = 0;
ifstream inFile;
inFile.open("FG8U0235.wsn", ios::in | ios::binary | ios::ate);
inFile.seekg(0, ios::end);
bytecount = inFile.tellg();
inFile.seekg(0, ios::beg);
char * buffer = new char[bytecount];
inFile.read(buffer, bytecount);
ConvertedFrame * frames = new ConvertedFrame[bytecount / 4];
INT16 lastTime = 0;
for (int i = 0; i < bytecount; i += 4){
ConvertedFrame _con;
Frame f;
memcpy(&f, &buffer[i], 4);
DosTime _t = DosTime(f.DosTime[0], f.DosTime[1]);
if (lastTime == _t.data) _t.second++;
lastTime = _t.data;
_con.time = _t;
_con.soundDB = (f.SoundOffset + ((f.precisionOffset & 3) * 256)) * 0.1 + 30;
frames[i / 4] = _con;
_con.print();
}
system("pause");
return 0;
}
Output:
Sound Level: 84.3 dB @ 20:02:34
Sound Level: 83.7 dB @ 20:02:36
Sound Level: 83.7 dB @ 20:02:37
Sound Level: 85.2 dB @ 20:02:38
Sound Level: 85.2 dB @ 20:02:39
Sound Level: 84.8 dB @ 20:02:40
Sound Level: 83.8 dB @ 20:02:41
Sound Level: 85.4 dB @ 20:02:42
Sound Level: 85.0 dB @ 20:02:43
Sound Level: 85.0 dB @ 20:02:44
Sound Level: 82.0 dB @ 20:02:45
Sound Level: 88.3 dB @ 20:02:46
Sound Level: 86.5 dB @ 20:02:47
Sound Level: 86.2 dB @ 20:02:48
Sound Level: 87.1 dB @ 20:02:49
Notes:
To find which one is the correct one you need to write dB into a paper or something and then compare with the output you get from both codes.
Also you need to do the cleanup of ConvertedFrame * frames and char * buffer if you use this code and want to prevent memory leaks. I wrote this code pretty fast @ 4 am just to test the theory.