2015-06-04 43 views
1

我知道Wave文件的結構。但我不知道PCM DATA的確切結構。[C++]我想從wav文件中獲取PCM數據

#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字節速率,立體聲通道和兩個blockAlign。上述如何改變?

+3

PCM有** no **結構。原始樣本以8,16,24或32位有符號或無符號整數相互跟隨(或者不太頻繁,作爲'float'或'double')。 –

回答

0

如在this description of wav specifications中所指示的,PCM數據使用小端字節順序和2的補碼來存儲,用於每個採樣大於8位的分辨率。換句話說,在Intel處理器上,16位採樣通常對應於signed short。另外,對於立體聲通道,數據是交錯的(左/右採樣)。考慮到這一點,假設「music.wav」確實包含16位PCM樣本,並且您正在使用編譯器在小端平臺上讀取數據,其中sizeof(short)==2,那麼您發佈的代碼應該讀取樣本正確。

+0

非常感謝!我想我應該學習更多。 – HyeonJunOh

+0

請記住,並非所有.wav文件都包含交錯的8,16,24,32整型PCM數據。檢查短整型AudioFormat,如果它不等於1,它是在其他格式,並且幾乎總是壓縮,並將有一個擴展標頭。如果沒有實現編解碼器,您將無法讀取壓縮數據。或者使用外部程序將其轉換爲PCM。 – ChocoBilly