你的文件看起来像:
51A0
52A0
52A0
53A0
53A0
_
52A0 = 20:02:36
53A0 = 20:02:38 in dos time
如果它的 dos 时间是有意义的,为什么每个模式(51A0,52A0)显示 2 次,因为 dos 时间不接受奇数作为秒。
理论1:
我不认为任何自然的声音会变成 DA,5A,DA,5A,DA,5A,DA,5A,DA,5A。
所以我假设 DA 显示较低的部分,而 5A 是较高的部分。(DA=+0 和 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
我不太了解测量声音,但我也可以根据第一个字节做出假设。但这可能是错误的,因为您没有提供有关您捕获的声音的任何信息。
第一个字节是您的文件中的最大值:0x47(71) 最小值:0x8(8)。
在亚马逊页面上写着 (30 ~ 130 Db)
8 不适合这些范围,所以我假设第一个字节是一个偏移量。
130-30=100 -> 0 > x > 100。
每 4 个字节都有以下信息:
struct Frame{
char SoundOffset;
char TimeOffset;
char DosTime[2];
}
我为您的数据编写了示例代码。
#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;
}
哪些输出:
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
理论2:
在您给我们的网站 ( http://opensource.ebswift.com/RaspiMonitor/wensn/ ) 上,有这个函数 ( dB = (byte1 + ((byte2 & 3) * 256)) * 0.1 + 30 )我认为也许第二个字节实际上不是时间偏移,而是 dB 的第二个字节。
这使得 dB Float 而不是 Integer 更有意义。我从第二个理论中得到的输出感觉好多了,所以我认为这是正确的答案。
#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;
}
输出:
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
注意:
要找出哪个是正确的,您需要将 dB 写到纸或其他东西中,然后与从两个代码中获得的输出进行比较。
如果您使用此代码并希望防止内存泄漏,您还需要清理 ConvertedFrame * 帧和 char * 缓冲区。我在凌晨 4 点写这段代码的速度非常快,只是为了测试理论。