用C / C ++读取和处理WAV文件数据

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

这是我此刻阅读文件的方式:

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

提前致谢。

我的第一个建议是使用某种类型的库来帮助你。 大多数声音解决方案看起来都有些过分,所以一个简单的库(就像你的问题评论中建议的一样, libsndfile )应该可以解决问题。

如果您只是想知道如何阅读WAV文件,那么您可以自己编写(因为您的学校可能会因为您像其他普通人一样使用图书馆而嗤之以鼻),快速谷歌搜索将为您提供所有信息需要加上一些已经写过很多关于阅读.wav格式教程的人 。

如果你仍然没有得到它,这里是我自己的一些代码,我读取WAV / RIFF数据文件的标题和所有其他块,直到我到达数据块。 它完全基于WAV格式规范 。 提取实际声音数据并不是很难:您可以原始读取它并原始使用它,或者转换为内部更舒适的格式(32位PCM未压缩数据或其他内容)。

查看下面的代码时,将reader.Read...( ... )替换为等效的fread调用,以获取指定类型的整数值和字节大小。 WavChunks是一个枚举,它是WAV文件块内ID的Little Endian值,而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; } }