最近在实验室做实验使用了AD采集器采集水听器的输出信号,用U盘把数据拷回来后发现生成wav的wav文件并不能用MATLAB的audioread函数读取,用UltraEdit打开后发现文件头是$DPACKS$开头,于是研究了一下这个文件格式。
参考大神求救啊-CSDN论坛
对于DPACK文件结构的介绍
写了一个能够把AD采集器生成的wav文件转换成dat文件用于MATLAB读取数据作后续处理
wavread.cpp
#include#include #include #include "wavread.h" void saveInfo(HeadInfo hinfo, const char* str) { FILE* fp; char file[100]; sprintf_s(file, "%s.m", str); fopen_s(&fp, file, "wb"); fprintf(fp, "dat.Name='%s';n", hinfo.Name); fprintf(fp, "dat.DeltaX=%lf;n", hinfo.DeltaX); fprintf(fp, "dat.OffsetX=%lf;n", hinfo.OffsetX); fprintf(fp, "dat.UnitX='%s';n", hinfo.UnitX); fprintf(fp, "dat.DeltaY=%lf;n", hinfo.DeltaY); fprintf(fp, "dat.OffsetY=%lf;n", hinfo.OffsetY); fprintf(fp, "dat.UnitY='%s';n", hinfo.UnitY); fprintf(fp, "dat.dat=load('%s.dat');", str); fclose(fp); } void wav2dat(const char* wav, const char* fdat) { FILE* fp; fopen_s(&fp, wav, "rb"); Tfilehead head; fread(&head, sizeof(Tfilehead), 1, fp); //short** dat = new short* [head.BLKNum]; for (int i = 0; i < head.BLKNum; i++) { using namespace std; cout << "正在读取数据块" << i << endl; fseek(fp, head.BLKoft[i], SEEK_SET); HeadInfo hinfo; fread(&hinfo, sizeof(HeadInfo), 1, fp); fseek(fp, hinfo.DataStart, SEEK_CUR); short* dat = new short[hinfo.DataEnd - hinfo.DataStart]; fread(dat, sizeof(short), hinfo.DataEnd - hinfo.DataStart, fp); fclose(fp); char str[100]; sprintf_s(str, "%s_%0.3d.dat", fdat, i); char name[100]; sprintf_s(name, "%s_%0.3d", fdat, i); saveInfo(hinfo, name); fopen_s(&fp, str, "wt"); for (int j = 0; j < hinfo.DataEnd - hinfo.DataStart; j++) { fprintf(fp, "%dn", *(dat + j)); } fclose(fp); } }
头文件wavread.h
#pragma once
#pragma pack(1)
struct Tfilehead
{
char Fstr[8];
short BLKNum;
long BLKoft[256];
};
#pragma pack(1)
struct HeadInfo
{
char Name[10]; // 8 charactors permited
long DataStart;
long DataEnd; // Data_Start related to trigger point
double DeltaX;
double OffsetX; // normal == 0;
char UnitX[5]; // max 2 charactors permitted
double DeltaY; // 65536 * DeltaY = full Range (OffsetY != 0)
double OffsetY; // a constant united with UnitY[]
char UnitY[5]; // max 4 charactors permitted
__int64 DataStartEx;
__int64 DataEndEx;
short int LenFlag; // 0x55AA
char resvd[2]; // reserved for development
};
void wav2dat(const char* wav, const char* dat);
我这里使用的是Visual Studio,如果换用dev-C++之类的别的环境可能不支持scanf_s这些函数,稍微更改一下都可以使用
另外,这里面有一点需要注意的是,VS的工程默认结构体是4字节对齐,而采集器生成的时候没有做字节对齐,如果不加上#pragma pack(1)强制使用1字节对齐,就会导致文件头中的short型BLKnum读入后舍弃了后面两个字节,数据读入出错
另外这个函数顺便把matlab载入数据的代码也一并生成了,生成的.m脚本文件可以直接执行,数据和AD采样的各种量化信息都保存在dat结构体里
生成的matlab代码
dat.Name='CH1';
dat.DeltaX=0.000002;
dat.OffsetX=0.000000;
dat.UnitX='s';
dat.DeltaY=0.000003;
dat.OffsetY=0.000000;
dat.UnitY='V';
dat.dat=load('testwww_000.dat');



