C++ 在C/C+中读取和处理WAV文件数据+;

C++ 在C/C+中读取和处理WAV文件数据+;,c++,c,voice,voice-recognition,C++,C,Voice,Voice Recognition,我目前正在做一个非常重要的学校项目。我需要在C/C++中提取波形文件的信息,并使用这些信息获得语音信号的LPC。但是,为了做到这一点,我需要对信号进行一些预处理,比如过零和能量分析等。这意味着我需要符号和实际值。问题是我不知道如何获得有用的信息和正确的格式。我已经阅读了文件中的每一个字段,但我不确定我做得是否正确。请给我一些建议好吗 这是我目前阅读文件的方式: readI=fread(和bps,1,2,音频); printf(“每个样本的位数=%d\n”,bps) 提前谢谢。我的第一个建议是使用

我目前正在做一个非常重要的学校项目。我需要在C/C++中提取波形文件的信息,并使用这些信息获得语音信号的LPC。但是,为了做到这一点,我需要对信号进行一些预处理,比如过零和能量分析等。这意味着我需要符号和实际值。问题是我不知道如何获得有用的信息和正确的格式。我已经阅读了文件中的每一个字段,但我不确定我做得是否正确。请给我一些建议好吗

这是我目前阅读文件的方式:

readI=fread(和bps,1,2,音频); printf(“每个样本的位数=%d\n”,bps)


提前谢谢。

我的第一个建议是使用某种库来帮助您。大多数合理的解决方案似乎有些过头了,所以一个简单的库(就像在你的问题的评论中推荐的库)应该可以做到这一点

如果你只是想知道如何阅读WAV文件,这样你就可以自己写(因为你的学校可能会拒绝让你像其他普通人一样使用图书馆),谷歌快速搜索将为你提供所需的所有信息

如果您仍然不明白,下面是我自己的一些代码,我在这里读取WAV/RIFF数据文件的头和所有其他块,直到到达数据块。它是基于。提取实际的声音数据并不困难:您可以读取原始数据并使用原始数据,也可以将其转换为更适合内部使用的格式(32位PCM未压缩数据或其他)

查看以下代码时,请将
reader.Read…(…)
替换为指定类型的整数值和字节大小的等效
fread
调用
WavChunks
是一个枚举,它是WAV文件块内部ID的小端值,
format
变量是可以包含在WAV文件格式中的WAV格式类型之一:

enum class WavChunks {
    RiffHeader = 0x46464952,
    WavRiff = 0x54651475,
    Format = 0x020746d66,
    LabeledText = 0x478747C6,
    Instrumentation = 0x478747C6,
    Sample = 0x6C706D73,
    Fact = 0x47361666,
    Data = 0x61746164,
    Junk = 0x4b4e554a,
};

enum class WavFormat {
    PulseCodeModulation = 0x01,
    IEEEFloatingPoint = 0x03,
    ALaw = 0x06,
    MuLaw = 0x07,
    IMAADPCM = 0x11,
    YamahaITUG723ADPCM = 0x16,
    GSM610 = 0x31,
    ITUG721ADPCM = 0x40,
    MPEG = 0x50,
    Extensible = 0xFFFE
};

int32 chunkid = 0;
bool datachunk = false;
while ( !datachunk ) {
    chunkid = reader.ReadInt32( );
    switch ( (WavChunks)chunkid ) {
    case WavChunks::Format:
        formatsize = reader.ReadInt32( );
        format = (WavFormat)reader.ReadInt16( );
        channels = (Channels)reader.ReadInt16( );
        channelcount = (int)channels;
        samplerate = reader.ReadInt32( );
        bitspersecond = reader.ReadInt32( );
        formatblockalign = reader.ReadInt16( );
        bitdepth = reader.ReadInt16( );
        if ( formatsize == 18 ) {
            int32 extradata = reader.ReadInt16( );
            reader.Seek( extradata, SeekOrigin::Current );
        }
        break;
    case WavChunks::RiffHeader:
        headerid = chunkid;
        memsize = reader.ReadInt32( );
        riffstyle = reader.ReadInt32( );
        break;
    case WavChunks::Data:
        datachunk = true;
        datasize = reader.ReadInt32( );
        break;
    default:
        int32 skipsize = reader.ReadInt32( );
        reader.Seek( skipsize, SeekOrigin::Current );
        break;
    }
}

有两个库可以帮助您使用WAVS为什么RIFF是用十六进制写的?我知道little/big endian,但我使用的所有十六进制编辑器都将其显示为RIFF,而不是FFIR,它们是在幕后进行一些奇怪的转换,还是发生了其他事情?我相信@MarcusJ是对的,应该阅读RIFF,这里是波形格式的描述,所以我认为它应该是RiffHeader=0x52494646,因为格式说明它是一个大端字段