wav 文件解析

WAVE文件格式说明表:

 

偏移地址

字节数

数据类型

内   容

 

文件头

00H

4

char

"RIFF"标志

04H

4

long int

文件长度

08H

4

char

"WAVE"标志

0CH

4

char

"fmt"标志

10H

4

 

过渡字节(不定)

14H

2

int

格式类别(10H为PCM形式的声音数据)

16H

2

int

通道数,单声道为1,双声道为2

18H

4

int

采样率(每秒样本数),表示每个通道的播放速度,

1CH

4

long int

波形音频数据传送速率,其值为通道数×每秒数据位数×每样本的数据位数/8。播放软件利用此值可以估计缓冲区的大小。

20H

2

int

数据块的调整数(按字节算的),其值为通道数×每样本的数据位值/8。播放软件需要一次处理多个该值大小的字节数据,以便将其值用于缓冲区的调整。

22H

2

 

每样本的数据位数,表示每个声道中各个样本的数据位数。如果有多个声道,对每个声道而言,样本大小都一样。

24H

4

char

数据标记符"data"

28H

4

long int

语音数据的长度

  PCM数据的存放方式:

 

样本1

样本2

8位单声道

0声道

0声道

8位立体声

0声道(左)

1声道(右)

0声道(左)

1声道(右)

16位单声道

0声道低字节

0声道高字节

0声道低字节

0声道高字节

16位立体声

0声道(左)低字节

0声道(左)高字节

1声道(右)低字节

1声道(右)高字节


读取wav文件所有字段,并原封不动写入一个新的wav文件: wav_write.cpp

#include <iostream>
#include <fstream>
#include <string.h>
#include<math.h>
#include<cmath>
#include<stdlib.h>
#include <bitset>
#include <iomanip>
using namespace std;
struct my_wave
{
 unsigned long chunckId;
 unsigned long chunkSize;
 unsigned long format;
 unsigned long subChunk1Id;
 unsigned long subChunk1Size;
 unsigned short audioFormat;
 unsigned short numChannels;
 unsigned long sampleRate;
 unsigned long byteRate;
 unsigned short blockAlign;
 unsigned short bitsPerSampel;
 unsigned long subChunk2Id;
 unsigned long subChunk2Size;
 unsigned char *z_data;
};
int main(int argc, char **argv)
{
 ifstream fs;
 ofstream ofs;
 my_wave MW;
 //读取原始文件
 fs.open("F:\\wave.wav", ios::binary | ios::in);   //这句需要修改成您的文件路径
 ofs.open("F:\\waveout.wav", ios::binary | ios::out);  //读取的文件写入新文件
 
 //读取wav文件的所有字段
 fs.seekg(0);       
 fs.read((char*)&MW.chunckId, sizeof(MW.chunckId));
 fs.seekg(0x04);        
 fs.read((char*)&MW.chunkSize, sizeof(MW.chunkSize));
 
 fs.seekg(0x08);      
 fs.read((char*)&MW.format, sizeof(MW.format));
 fs.seekg(0x0c);       
 fs.read((char*)&MW.subChunk1Id, sizeof(MW.subChunk1Id));
 fs.seekg(0x10);       
 fs.read((char*)&MW.subChunk1Size, sizeof(MW.subChunk1Size));
 fs.seekg(0x14);
 fs.read((char*)&MW.audioFormat, sizeof(MW.audioFormat));
 fs.seekg(0x16);       
 fs.read((char*)&MW.numChannels, sizeof(MW.numChannels));
 fs.seekg(0x18);        
 fs.read((char*)&MW.sampleRate, sizeof(MW.sampleRate));
 fs.seekg(0x1c);        
 fs.read((char*)&MW.byteRate, sizeof(MW.byteRate));
 fs.seekg(0x20);       
 fs.read((char*)&MW.blockAlign, sizeof(MW.blockAlign));
 fs.seekg(0x22);      
 fs.read((char*)&MW.bitsPerSampel, sizeof(MW.bitsPerSampel));
 fs.seekg(0x24);        
 fs.read((char*)&MW.subChunk2Id, sizeof(MW.subChunk2Id));
 fs.seekg(0x28);        
 fs.read((char*)&MW.subChunk2Size, sizeof(MW.subChunk2Size));
 MW.z_data = new unsigned char[MW.subChunk2Size];
 fs.seekg(0x2c);        
 fs.read((char *)MW.z_data, sizeof(char)*MW.subChunk2Size);
    
 //输出wav文件的所有字段,以供测试
 cout << MW.chunckId << endl;
 cout << MW.chunkSize << endl;
 cout << MW.format << endl;
 cout << MW.subChunk1Id << endl;
 cout << MW.subChunk1Size << endl;
 cout << MW.audioFormat << endl;
 cout << MW.numChannels << endl;
 cout << MW.sampleRate << endl;
 cout << MW.byteRate << endl;
 cout << MW.blockAlign << endl;
 cout << MW.bitsPerSampel << endl;
 cout << MW.subChunk2Id << endl;
 cout << MW.subChunk2Size << endl;
 cout << "采样数据:" << endl;
 for (int k = 0; k < MW.subChunk2Size; k++){
  printf("%x  ",MW.z_data[k]);
 }
 //将每个字段原封不动得写入新的.wav文件中
 ofs.write((char*)&MW.chunckId, sizeof(MW.chunckId));
 ofs.write((char*)&MW.chunkSize, sizeof(MW.chunkSize));
 ofs.write((char*)&MW.format, sizeof(MW.format));
 ofs.write((char*)&MW.subChunk1Id, sizeof(MW.subChunk1Id));
 ofs.write((char*)&MW.subChunk1Size, sizeof(MW.subChunk1Size));
 ofs.write((char*)&MW.audioFormat, sizeof(MW.audioFormat));
 ofs.write((char*)&MW.numChannels, sizeof(MW.numChannels));
 ofs.write((char*)&MW.sampleRate, sizeof(MW.sampleRate));
 ofs.write((char*)&MW.byteRate, sizeof(MW.byteRate));
 ofs.write((char*)&MW.blockAlign, sizeof(MW.blockAlign));
 ofs.write((char*)&MW.bitsPerSampel, sizeof(MW.bitsPerSampel));
 ofs.write((char*)&MW.subChunk2Id, sizeof(MW.subChunk2Id));
 ofs.write((char*)&MW.subChunk2Size, sizeof(MW.subChunk2Size));
 ofs.write((char*)MW.z_data, sizeof(char)*MW.subChunk2Size);
 fs.close();
 ofs.close();
 delete[] MW.z_data;
 system("pause");
}

你可能感兴趣的:(wav 文件解析)