通常wav文件的subchunk1size是16.但是,我有一些wav文件有subchunk1size = 18.我有c ++代码来读取有subchunk1size = 16的wav文件。现在我想读取有subchunk1size的wav文件= 18.任何帮助将不胜感激。
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;
以上是我的代码中的struct header_file,用于读取带有subchunk1size = 16的wav文件。
答案 0 :(得分:4)
Wav文件没有您期望的那样严格的结构。 " fmt" chunk不一定是第一个跟随文件头的(虽然它通常是),并且它的大小不一定是16个字节(尽管通常情况也是如此)。压缩音频可以存储在wav文件中,在这种情况下,audio_format
字段将不同于1和" fmt"块可以具有不同于16个字节的大小。
解析wav文件的正确而灵活的方法是使用更细粒度的结构:
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;
};
然后你的解析逻辑应该是(注意验证你在每一步中读过的数据):
wave_header
riff_chunk_header
audio_format
字段audio_format
。如果它是1,那么你有PCM数据,并且块应该有你预期的16个字节。如果它不是1,您必须找到有关该压缩格式的文档。一般来说,优雅地忽略其他数据也是一个好主意,所以如果你确实看到一个带有" fmt"的PCM编码的wav文件。大块的18个字节,尝试忽略最后2个字节并查看它的位置。
答案 1 :(得分:1)
文件确实有严格的格式结构。如果不遵守此结构,某些应用程序可能无法播放或打开文件进行编辑。
原始问题:wave文件可以分为两组。第一组由具有多于2个音频通道的OR或具有大于16的PCM位深度的文件组成。第二组由不满足这两个条件的文件组成,即1或2个通道,最多16位。多年来,微软已经克服了wav文件中包含的结构,以适应计算机音频技术的进步。具体来说,他们在WAVEFORMATEX结构中添加了一个名为cbSize的2字节字段。这就是您看到16和18的subchunk1size值的原因。双字节差异取决于cbSize字段的存在与否。使用当前版本的WAVEFORMATEX正确形成的现代音频文件将具有18的子组块大小,而不管通道数或位深度。在Microsoft更改WAVEFORMATEX结构之前创建的旧文件的subchunk1size为16。
这是我的政策:
当读取文件时,subchunk1size可以是16或18,因此代码应该相应地进行调整。有很多旧格式的旧wav文件,或者现有文件可能使用旧的WAVEFORMATEX结构错误地写入而没有cbSize字段。
创建wav文件时,无论通道数或位深度如何,我总是使用18的subchunk1size,因为Microsoft已永久更改了WAVEFORMATEX结构并使文件符合规范。
Windows Media Player对于确保您的wav文件可以打开和播放非常有用。
http://msdn.microsoft.com/en-us/library/windows/desktop/dd390970%28v=vs.85%29.aspx