C ++读取wav文件,subchunk1size = 18 [英] C++ read wav file, subchunk1size = 18

查看:953
本文介绍了C ++读取wav文件,subchunk1size = 18的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通常,wav文件的subchunk1size是16.但是,我有一些wav文件的subchunk1size = 18。我有c ++代码来读取具有subchunk1size = 16的wav文件。现在我想读取具有subchunk1size = 18.任何帮助,将不胜感激。

  typedef struct header_file 
{
char chunk_id [4];
int chunk_size;
字符格式[4];
char subchunk1_id [4];
int subchunk1_size;
short int audio_format;
short int num_channels;
int sample_rate;
int byte_rate;
short int block_align;
short int bits_per_sample;
char subchunk2_id [4];
int subchunk2_size;
}表头;

以上是在我的代码中使用subchunk1size = 16读取wav文件的struct header_file。

解决方案

Wav文件并不像您所期望的那样严格。 fmt块不一定是第一个跟随文件头(尽管通常是),它的大小不一定是16个字节(尽管如此,情况经常是这样)。压缩音频可以存储在wav文件中,在这种情况下, audio_format 字段将不同于1,而fmt块可以具有与16个字节不同的大小。 / p>

解析wav文件的适当而灵活的方法是使用更精细的结构:

  struct wave_header 
{
char chunk_id [4];
int chunk_size;
字符格式[4];
};

struct riff_chunk_header
{
char id [4];
int size;
};

struct wave_fmt_chunk
{
short audio_format;
short num_channels;
int sample_rate;
int byte_rate;
short block_align;
short bits_per_sample;
};

然后你的解析逻辑应该是(注意验证你在每一步读到的数据) :


  1. 阅读 wave_header
  2. 阅读 riff_chunk_header
  3. 如果您读取的块头的ID不是fmt,则跳过块它的大小以字节为单位),然后循环回第2步读取下一个块头
  4. 阅读 audio_format 字段

  5. 根据 audio_format 解释其余的fmt块数据。如果它是1,你有PCM数据,并且块应该有你预期的16个字节。如果不是1,则必须查找有关该压缩格式的文档。

通常,优雅地忽略额外数据,所以如果你看到一个带有18字节的fmt块的PCM编码的wav文件,试着忽略最后2个字节,看看你得到了什么。


Usually the subchunk1size of a wav file is 16. However, I have some wav files that have subchunk1size = 18. I have c++ code to read wav file that has subchunk1size = 16. Now I want to read wav files that have subchunk1size = 18. Any help would be appreciated.

typedef struct header_file
{
    char chunk_id[4];
    int chunk_size;
    char format[4];
    char subchunk1_id[4];
    int subchunk1_size;
    short int audio_format;
    short int num_channels;
    int sample_rate;            
    int byte_rate;
    short int block_align;
    short int bits_per_sample;
    char subchunk2_id[4];
    int subchunk2_size;         
} header;

The above is struct header_file in my code to read wav file with subchunk1size = 16.

解决方案

Wav files do not have as rigid a structure as you are expecting. The "fmt " chunk is not necessarily the first to follow the file header (though it usually is), and its size is not necessarily 16 bytes (though again that's often the case). Compressed audio can be stored in a wav file, in which case the audio_format field will be different than 1 and the "fmt " chunk can have a different size than 16 bytes.

The proper and flexible way to parse wav files is to use more granular structures:

struct wave_header
{
    char chunk_id[4];
    int chunk_size;
    char format[4];     
};

struct riff_chunk_header
{
    char id[4];
    int size;
};

struct wave_fmt_chunk
{
    short audio_format;
    short num_channels;
    int sample_rate;            
    int byte_rate;
    short block_align;
    short bits_per_sample;
};

Then your parsing logic should be (taking care to validate the data you've read at each step):

  1. Read a wave_header
  2. Read a riff_chunk_header
  3. If the ID of the chunk header you've read is not "fmt ", skip the chunk (you have its size in bytes) and loop back to step 2 to read the next chunk header
  4. Read the audio_format field
  5. Interpret the rest of the "fmt " chunk's data based on this audio_format. If it's 1, you have PCM data and the chunk should have your expected 16 bytes. If it's not 1, you have to find documentation on that compression format.

In general, it's also a good idea to gracefully ignore additional data, so if you do see a PCM-encoded wav file with a "fmt " chunk of 18 bytes, try to ignore the last 2 bytes and see where that gets you.

这篇关于C ++读取wav文件,subchunk1size = 18的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆