簡體   English   中英

C++讀取wav文件,subchunk1size = 18

[英]C++ read wav file, subchunk1size = 18

通常 wav 文件的 subchunk1size 是 16。但是,我有一些 wav 文件的 subchunk1size = 18。我有 C++ 代碼來讀取 subchunk1size = 16 的 wav 文件。現在我想讀取 subchunk1size = 18 的 wav 文件。任何幫助將不勝感激。

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文件。

Wav 文件的結構並不像您期望的那樣嚴格。 “fmt”塊不一定是第一個跟在文件頭后面的(盡管它通常是),它的大小也不一定是 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;
};

那么你的解析邏輯應該是(注意驗證你在每一步讀取的數據):

  1. 讀取wave_header
  2. 讀取riff_chunk_header
  3. 如果您讀取的塊頭的 ID 不是“fmt”,則跳過該塊(您的大小以字節為單位)並循環回到步驟 2 以讀取下一個塊頭
  4. 讀取audio_format字段
  5. 根據此audio_format解釋“fmt”塊的其余數據。 如果它是 1,你有 PCM 數據,塊應該有你預期的 16 個字節。 如果它不是 1,則必須查找有關該壓縮格式的文檔。

一般來說,優雅地忽略額外的數據也是一個好主意,所以如果你看到一個 PCM 編碼的 wav 文件,它有一個 18 字節的“fmt”塊,試着忽略最后 2 個字節,看看你在哪里。

這些文件確實具有嚴格的格式結構。 如果不遵守此結構,某些應用程序可能無法播放或打開文件進行編輯。

對於原始問題:wave 文件可以分為兩組。 第一組由具有 2 個以上音頻通道或 PCM 位深度大於 16 或兩者兼有的文件組成。 第二組由不滿足這兩個條件的文件組成,即最多 16 位的 1 或 2 個通道。 多年來,微軟一直在整合 wav 文件中包含的結構,以適應計算機音頻技術的進步。 具體來說,他們向 WAVEFORMATEX 結構添加了一個名為 cbSize 的 2 字節字段。 這就是為什么您會看到 subchunk1size 值同時為 16 和 18 的原因。兩個字節的差異取決於 cbSize 字段的存在與否。 使用當前版本的 WAVEFORMATEX 正確形成的現代音頻文件的 subchunk1size 為 18,無論通道數或位深度如何。 在 Microsoft 更改 WAVEFORMATEX 結構之前創建的舊文件的 subchunk1size 為 16。

這是我的政策:

讀取文件時,subchunk1size 可以是 16 或 18,因此代碼應相應地進行調整。 有很多舊格式的舊 wav 文件,或者使用沒有 cbSize 字段的舊 WAVEFORMATEX 結構可能會錯誤地寫入現代文件。

創建 wav 文件時,無論通道數或位深度如何,我總是使用 18 的 subchunk1size,因為 Microsoft 已永久更改 WAVEFORMATEX 結構,這使文件符合規范。

Windows Media Player 可用於確保您的 wav 文件可以打開和播放。

http://msdn.microsoft.com/en-us/library/windows/desktop/dd390970%28v=vs.85%29.aspx

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM