C++ 读取 WAV 文件的数据部分

标签 c++ wav

我计划创建一个程序来可视化 .wav 文件的音频波形。

到目前为止,我已经开始正确阅读上述 wav 文件的标题部分。我使用的代码是这样的:

#include <iostream>
#include <string>
#include <fstream>

using namespace std;
using std::string;
using std::fstream;

typedef struct  WAV_HEADER{
    char                RIFF[4];        // RIFF Header      Magic header
    unsigned long       ChunkSize;      // RIFF Chunk Size  
    char                WAVE[4];        // WAVE Header      
    char                fmt[4];         // FMT header       
    unsigned long       Subchunk1Size;  // Size of the fmt chunk                                
    unsigned short      AudioFormat;    // Audio format 1=PCM,6=mulaw,7=alaw, 257=IBM Mu-Law, 258=IBM A-Law, 259=ADPCM 
    unsigned short      NumOfChan;      // Number of channels 1=Mono 2=Sterio                   
    unsigned long       SamplesPerSec;  // Sampling Frequency in Hz                             
    unsigned long       bytesPerSec;    // bytes per second 
    unsigned short      blockAlign;     // 2=16-bit mono, 4=16-bit stereo 
    unsigned short      bitsPerSample;  // Number of bits per sample      
    char                Subchunk2ID[4]; // "data"  string   
    unsigned long       Subchunk2Size;  // Sampled data length    

}wav_hdr; 

// Function prototypes 
int getFileSize(FILE *inFile); 

int main(int argc,char *argv[]){
    wav_hdr wavHeader;
    FILE *wavFile;
    int headerSize = sizeof(wav_hdr),filelength = 0;

    string answer;

    do{
        string input;
        string answer;

        const char* filePath;

        cout << "Pick wav file from the Windows Media File: ";
        cin >> input;
        cin.get();

        cout << endl;

        path = "C:\\Windows\\Media\\" + input + ".wav";
        filePath = path.c_str();

        wavFile = fopen( filePath , "r" );

        if(wavFile == NULL){
            printf("Can not able to open wave file\n");
            //exit(EXIT_FAILURE);
        }

        fread(&wavHeader,headerSize,1,wavFile);
        filelength = getFileSize(wavFile);
        fclose(wavFile);

        cout << "File is                    :" << filelength << " bytes." << endl;

        cout << "RIFF header                :" << wavHeader.RIFF[0] 
                                                << wavHeader.RIFF[1] 
                                                << wavHeader.RIFF[2] 
                                                << wavHeader.RIFF[3] << endl;

        cout << "WAVE header                :" << wavHeader.WAVE[0] 
                                                << wavHeader.WAVE[1] 
                                                << wavHeader.WAVE[2] 
                                                << wavHeader.WAVE[3] 
                                                << endl;

        cout << "FMT                        :" << wavHeader.fmt[0] 
                                                << wavHeader.fmt[1] 
                                                << wavHeader.fmt[2] 
                                                << wavHeader.fmt[3] 
                                                << endl;

        cout << "Data size                  :" << wavHeader.ChunkSize << endl;

        // Display the sampling Rate form the header
        cout << "Sampling Rate              :" << wavHeader.SamplesPerSec << endl;
        cout << "Number of bits used        :" << wavHeader.bitsPerSample << endl;
        cout << "Number of channels         :" << wavHeader.NumOfChan << endl;
        cout << "Number of bytes per second :" << wavHeader.bytesPerSec << endl;
        cout << "Data length                :" << wavHeader.Subchunk2Size << endl;
        cout << "Audio Format               :" << wavHeader.AudioFormat << endl;
        // Audio format 1=PCM,6=mulaw,7=alaw, 257=IBM Mu-Law, 258=IBM A-Law, 259=ADPCM 


        cout << "Block align                :" << wavHeader.blockAlign << endl;

        cout << "Data string                :" << wavHeader.Subchunk2ID[0] 
                                                << wavHeader.Subchunk2ID[1]
                                                << wavHeader.Subchunk2ID[2] 
                                                << wavHeader.Subchunk2ID[3] 
                                                << endl;

        cout << endl << endl << "Try something else? (y/n)";
        cin >> answer;
        //cin.get();
        cout << endl << endl;

    }while( answer == "y" );


    getchar();
    return 0;
} 
// find the file size 
int getFileSize(FILE *inFile){
    int fileSize = 0;
    fseek(inFile,0,SEEK_END);

    fileSize=ftell(inFile);

    fseek(inFile,0,SEEK_SET);
    return fileSize;
}

我已经尝试了几次,它提供的数据通过 Windows 文件夹中 Media 文件夹中的不同 wav 文件似乎是一致的。

下一步就是将 wav 文件的实际数据存储在 vector 中。但是,我对如何做到这一点一无所知。我发现的在线解决方案只能读取头文件。

关于如何存储(并希望显示)wav 文件的实际数据的任何想法? 谢谢!

最佳答案

此图片取自 a Stanford course

WAV File Format

因此您可以看到音频数据紧接在您已经读取的 header 之后,并且会有 Subchunk2Size 字节的音频数据。

这个的伪代码是

ReadRIFF();
ReadFMT();
int32 chunk2Id = Read32(BigEndian);
int32 chunk2Size = Read32(LittleEndian);
for (int i = 0; i < chunk2Size; i++)
{
    audioData[i] = ReadByte();
}

如果音频是立体声,您将在 data 中有两个音频流。如果音频经过压缩(mp3、aac 等),您必须先对其进行解压缩。

关于C++ 读取 WAV 文件的数据部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13660777/

相关文章:

c++ - 如何修复此错误 : set a breakpoint in malloc_error_break to debug

c++ - 如何让派生类调用其他派生类的方法?面向对象设计

c++ - C++ 中的正则表达式(正则表达式)错误: "terminate called after throwing an instance of ' std::regex_error' what(): regex_error 中止(核心转储)

asp.net - 在浏览器(Asp.net)中播放流式音频

audio - libsndfile 用法加入和混合 .wav 文件

c++ - Lua 函数什么都不做

c++ - DirectShow Amcap 工作正常,黑色屏幕与 playcap

r - 在r中查找wav文件的持续时间

matlab - 使用MATLAB将.mid转换为.wav

python - 通过低通滤波器后,音频文件听起来不佳/嘈杂