[C++]我想从wav文件中获取PCM数据
Posted
技术标签:
【中文标题】[C++]我想从wav文件中获取PCM数据【英文标题】:[C++]I want to get PCM data from wav file 【发布时间】:2015-06-04 12:53:32 【问题描述】:我知道 Wave 文件的结构。但我不知道 PCM DATA 的确切结构。
#include<iostream>
#include<fstream>
using namespace std;
struct WAVE_HEADER
char Chunk[4];
int ChunkSize;
char format[4];
char Sub_chunk1ID[4];
int Sub_chunk1Size;
short int AudioFormat;
short int NumChannels;
int SampleRate;
int ByteRate;
short int BlockAlign;
short int BitsPerSample;
char Sub_chunk2ID[4];
int Sub_chunk2Size;
;
struct WAVE_HEADER waveheader;
int main()
FILE *sound;
sound = fopen("music.wav","rb");
short D;
fread(&waveheader,sizeof(waveheader),1,sound);
cout << "BitsPerSample : " << waveheader.BitsPerSample << endl;
while(!feof(sound))
fread(&D,sizeof(waveheader.BitsPerSample),1,sound);
cout << int(D) << endl;
上面的代码是我到目前为止所做的。此外,此代码可以准确读取标题。但我不知道这是否可以准确读取 PCM 数据部分。有没有PCM数据结构的参考?没找到。
“music.wav”每个样本有 16 位,16 字节速率,立体声通道和两个块对齐。以上应该怎么改?
【问题讨论】:
PCM 具有 no 结构。原始样本作为 8、16、24 或 32 位有符号或无符号整数(或者,不太常见的是float
s 或 double
s。)
【参考方案1】:
如this description of wav specifications 中所述,PCM 数据使用 little-endian 字节顺序和二进制补码存储,分辨率大于每个样本 8 位。换句话说,在 Intel 处理器上,16 位样本通常对应于signed short
。此外,对于立体声通道,数据是交错的(左/右样本)。
考虑到这一点,假设“music.wav”确实包含 16 位 PCM 样本,并且您正在使用 sizeof(short)==2
的编译器在 little-endian 平台上读取数据,那么您发布的代码应该读取正确采样。
【讨论】:
请记住,并非所有 .wav 文件都包含交错的 8、16、24、32 int PCM 数据。检查 short int AudioFormat,如果它不等于 1,则它是其他格式,并且几乎总是被压缩并且会有一个扩展的 header。如果不为其实现编解码器,您将无法读取压缩数据。或者使用外部程序将其转换为 PCM。以上是关于[C++]我想从wav文件中获取PCM数据的主要内容,如果未能解决你的问题,请参考以下文章