我编写了一个从.wav文件中读取信息的程序。我收到了以下结果。
chunkId :RIFF
chunkSize :7828798
format :WAVE
Junk chunk :JUNK
Junk size :92
Format chunk :fmt
format chunk size :65536
Audioformat :1
numberofchanels :48000
samplerate :1996488704
Byterate :131073
BlockAlign :16
bitspersample :0
subchunk2Id :
subchunk2Size :0
我不知道为什么wav标题会那样。我使用sox程序来查看这个wav文件的标题。 这是结果
Input File : 'AUDIO00001.wav'
Channels : 1
Sample Rate : 48000
Precision : 16-bit
Duration : 00:01:17.28 = 3709621 samples ~ 5796.28 CDDA sectors
File Size : 7.83M
Bit Rate : 810k
Sample Encoding: 16-bit Signed Integer PCM
为什么我的程序错了?
我更新了我的问题: 我的wav标题结构:
struct WAVHEADER
{
char chunkID[4];
unsigned int chunkSize;
char format[4];
char junkChunk[4];
int junkSize;
char junkData[92];
char bext[4];
unsigned int bextSize;
char bextData[602];
char subchunk1ID[4];
unsigned int subchunk1Size;
unsigned short audioFormat;
unsigned short numberOfChanels;
unsigned int sampleRate;
unsigned int byteRate;
unsigned short blockAlign;
unsigned short bitsPerSample;
char subchunk2ID[4];
unsigned int subchunk2Size;
};
wav class:
wav::wav(const char* filepath)
{
std::ifstream wavFile(filepath);
if(wavFile.is_open())
{
wavFile.read((char*)&wavHeader,sizeof(WAVHEADER));
}
}
令我困惑的是,当subChunk1ID正确(“fmt”)时,为什么subchunk1Size看起来不对?
答案 0 :(得分:0)
编译器似乎在subchunk1ID
和subchunk1Size
之间插入了2个字节的填充。这是我的假设,因为
sizeof(WAVHEADER)
比它应该大2个字节。我不是C ++编译器专家所以我不能告诉你它为什么会这样做,除非它确实允许这样做。
为了直观地显示,那时结构应该是什么样的:
... subchunk1ID: 01100110 01101101 01110100 00100000 subchunk1Size: 00101000 00000000 00000000 00000000 audioFormat: 00000001 00000000 numberOfChanels: 00000001 00000000 ...
但相反,你得到的是:
... subchunk1ID: 01100110 01101101 01110100 00100000 2 bytes of pad: 00101000 00000000 subchunk1Size: 00000000 00000000 00000001 00000000 audioFormat: 00000001 00000000 ...
00000000 00000000 00000001 00000000
是小端字节顺序的数字65536。
你真正发现的是这个结构转换不是读取文件的可靠方法。你应该用“艰难的方式”来读它(一次一个数字)。还有其他一些陷阱,例如:
JUNK
和bext
需要出现在文件中,也不需要在程序编译时知道大小。