1
votes

I know the Wave file's structure. But I don't know the exact structure of 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;
    }
}

The above code is what I made so far. Also, this code can read header exactly. But I don't know if this can read PCM data part precisely. Is there any reference of PCM data structure? I couldn't find it.

"music.wav" has 16 bits per sample, 16 byte rate, stereo channal and two blockAlign. How should the above be changed?

1
PCM has no structure. The raw samples follow each other as 8, 16, 24 or 32 bit signed or unsigned integers (or, less frequently, as floats or doubles.)The Paramagnetic Croissant

1 Answers

1
votes

As indicated in this description of wav specifications, PCM data are stored using little-endian byte order and two's-complement for resolutions greater than 8 bit per sample. In other words, on an Intel processor, 16-bit samples typically corresponds to signed short. Additionally, for stereo channels the data is interleaved (left/right samples).

With that in mind, assuming "music.wav" does indeed contain 16-bit PCM samples and you are reading the data on a little-endian platform using a compiler where sizeof(short)==2, then the code you posted should read the samples correctly.