简体   繁体   English

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

[英]Reading and processing WAV file data in C/C++

I'm currently doing a very very important school project. 我目前正在做一个非常重要的学校项目。 I need to extract the information of a WAVE file in C/C++ and use the information to obtain the LPC of a voice signal. 我需要在C / C ++中提取WAVE文件的信息,并使用该信息来获取语音信号的LPC。 But, in order to do that, I need to do some pre-processing to the signal, like doing Zero crossing and energy analysis, among other things. 但是,为了做到这一点,我需要对信号进行一些预处理,比如进行零交叉和能量分析等。 Which means that I need the sign and a real value. 这意味着我需要标志和真正的价值。 The problem is that I don't know how to obtain useful information and the correct format for that. 问题是我不知道如何获得有用的信息和正确的格式。 I have already read every single field in the file, but I'm not sure I am doing it right. 我已经读过文件中的每个字段,但我不确定我做得对。 Suggestions, please? 建议好吗?

This is the way I read the file at the moment: 这是我此刻阅读文件的方式:

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

Thanks in advance. 提前致谢。

My first recommendation would be to use some kind of library to help you out. 我的第一个建议是使用某种类型的库来帮助你。 Most sound solutions seem overkill, so a simple library (like the one recommended in the comment of your question, libsndfile ) should do the trick. 大多数声音解决方案看起来都是矫枉过正的,所以一个简单的库(就像你的问题评论中建议的一样, libsndfile )应该可以解决问题。

If you just want to know how to read WAV files so you can write your own (since your school might turn its nose up at having you use a library like any other regular person), a quick google search will give you all the info you need plus some people who have already wrote many tutorials on reading the .wav format . 如果你只是想知道如何阅读WAV文件,这样你就可以自己编写(因为你的学校可能会因为你像其他普通人一样使用图书馆而嗤之以鼻),快速谷歌搜索会给你所有的信息需要加上一些已经写过许多关于阅读.wav格式教程的人

If you still don't get it, here's some of my own code where I read the header and all other chunks of the WAV/RIFF data file until I get to the data chunk. 如果你仍然没有得到它,这里是我自己的一些代码,我读取WAV / RIFF数据文件的标题和所有其他块,直到我到达数据块。 It's based exclusively off the WAV Format Specification . 完全基于WAV格式规范 Extracting the actual sound data is not very hard: you can either read it raw and use it raw or do a conversion to a format you'd have more comfort with internally (32-bit PCM uncompressed data or something). 提取实际的声音数据并不是很难:您既可以原始读取也可以原始使用它,或者转换为内部更舒适的格式(32位PCM未压缩数据或其他内容)。

When looking at the below code, replace reader.Read...( ... ) with equivalent fread calls for integer values and byte sizes of the indicated type. 查看下面的代码时,将reader.Read...( ... )替换为等效的fread调用,以获取指定类型的整数值和字节大小。 WavChunks is an enum that is the Little Endian values of the IDs inside of a WAV file chunk, and the format variable is one of the types of the Wav Format Types that can be contained in the WAV File Format: 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;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM