天天看點

ADPCM 編碼 及WAV解析 及執行個體

wav檔案詳解

  1. WAV頭分析

WAV是微軟公司(Microsoft)開發的一種聲音檔案格式,在多媒體中使用的聲波檔案格式之一,它是以RIFF(Resource Interchange File Format 資源互動檔案格式) 格式為标準的。每個WAV檔案的頭四個位元組就是“RIFF”。WAV檔案由檔案頭和資料體兩大部分組成。其中檔案頭又分為RIFF/WAV檔案辨別段和聲音資料格式說明段兩部分,檔案頭中還包含了音頻流的編碼參數。

如下圖所示

ADPCM 編碼 及WAV解析 及執行個體

//wav頭

typedef __packed struct

{

  ChunkRIFF riff;   //riff塊

  ChunkFMT fmt;     //fmt塊

  ChunkFACT fact;   //fact塊 線性PCM,沒有這個結構體

  ChunkDATA data;   //data塊     

}__WaveHeader;

WAV檔案頭包含三部分,RIFF,fmt,fact,資料存儲大小端定義按上圖中的定義,規律大概是這樣的,如果是字元串常量,則按閱讀習慣,采用大端存儲模式,如果是十六進制資料的純資料,則按一般處理器處理規律小端模式存儲。

 WAV檔案是非常簡單的一種RIFF檔案,它的格式類型為“WAVE ”。RIFF塊包含兩個子塊,這兩個子塊的ID分别是“fmt ”和“data ” 。其中“fmt ”子塊由結構PCMWAVEFORMAT所組成,其子塊的大小就是sizeof(PCMWAVEFORMAT),資料組成就是PCMWAVEFORMAT結構中的資料。

    1. RIFF結構如下,定義,

 typedef __packed struct

{

    u32 ChunkID;        //chunk id;這裡固定為"RIFF",即0X46464952

    u32 ChunkSize ;         //集合大小;檔案總大小-8

    u32 Format;            //格式;WAVE,即0X45564157

}ChunkRIFF ;

    1. fmt結構

//fmt塊

typedef __packed struct

{

    u32 ChunkID;          //chunk id;這裡固定為"fmt ",即0X20746D66

    u32 ChunkSize ;       //子集合大小(不包括ID和Size);這裡為:20.

    u16 AudioFormat;   //音頻格式;0X01,表示線性PCM;0X11表示IMA ADPCM

  u16 NumOfChannels;      //通道數量;1,表示單聲道;2,表示雙聲道;

  u32 SampleRate;         //采樣率;0X1F40,表示8Khz

  u32 ByteRate;        //位元組速率;

  u16 BlockAlign;         //塊對齊(位元組);

  u16 BitsPerSample;      //單個采樣資料大小;4位ADPCM,設定為4

  u16 ByteExtraData;   //附加的資料位元組;2個; 線性PCM,沒有這個參數

  u16 sampleperblock;      //一般是一個資料塊中的采樣數量 如:0x01F9

}ChunkFMT; 

ByteExtraData這個資料重點說一下,在原始線性PCM編碼格式,不需要這個參數,隻有壓縮的PCM編碼格式,一般都是按塊存儲的,需要知道一個塊内的采樣數量。

    1. fact結構

//fact塊

typedef __packed struct

{

    u32 ChunkID;        //chunk id;這裡固定為"fact",即0X74636166;

    u32 ChunkSize ;         //子集合大小(不包括ID和Size);這裡為:4.

    u32 NumOfSamples;       //采樣的數量;

}ChunkFACT;

“All (compressed) non-PCM formats must have a Fact chunk (Rev. 3documentation). The chunk contains at least one value, the number of samples in the file.”

雖然标準協定要求”所有非PCM編碼的WAV檔案要求有fact塊”,但實際分析了兩個wav檔案的檔案頭,一種PCM編碼,一種IMA-ADPCM編碼,這兩個檔案都沒有fact塊,但是window可以正常播放;說明fact塊對這兩種類型的wav檔案也不是必須的。

  1. 音頻資料
    1. data結構

//data塊

typedef __packed struct

{

    u32 ChunkID;        //chunk id;這裡固定為"data",即0X5453494C

    u32 ChunkSize ;      // 音頻資料塊大小。(除去WAV頭的所有資料)

}ChunkDATA;

    1. 資料塊BLOCK結構

IMA-ADPCM壓縮的音頻資料是以資料塊存儲的,存儲格式如下:

//ADPCM壓縮的資料塊結構

typedef __packed struct

{

    u16 presample;      //第一個采樣值16bit

    u8 index ;          //上一個資料塊的最後一個 index

    u8 rsv;             //保留

    u8 dat[sampleperblock-1];

}DATA_BLOCK;

為了資料存儲對齊,友善處理,一般一個音頻BLOCK的大小是16的整數倍;如果設定BLOCK大小為256Byte,減去資料塊頭長度4位元組,還剩252位元組,4bit表示一個采樣的話,可存儲共252x2+1=505個采樣點(加上資料頭裡的一個采樣值)。

對于PCM編碼的WAV檔案,隻需要按照順序存儲原始采樣值即可,不需要分塊。

PCM編碼的WAV檔案實際例子:

ADPCM 編碼 及WAV解析 及執行個體

IMA-ADPCM編碼的WAV檔案實際例子:

ADPCM 編碼 及WAV解析 及執行個體
  1. ADPCM編解碼

Windows自帶的一個小工具

ADPCM 編碼 及WAV解析 及執行個體

這個小工具我試過了,轉換成不是ima-adpcm格式, 而是轉換成microsoft adpcm格式,這2種格式之間有什麼差別 我不知道 ,但是市面上大多數是ima-adpcm格式,是以我就不研究這個microsoft adpcm格式了。

相容性問題:

1, cooledit生成的IMA ADPCM 編譯的WAV檔案, foobar.exe不能播放,

2. 錄音筆錄制的 ADPCM WAV就可以播放,

對比發現,  cooledit生成的wav檔案好像更符合标準,有fact部分,而錄音筆錄音的wav沒有fact部分,标準規定如果是壓縮的wav格式的話,要求有fact部分,但實際是有這部分播放器就不識别,放不出來,而沒有這部分,大多數播放器就可以很好的播放。 或許是cooledit相容性不好。

ADPCM 編碼 及WAV解析 及執行個體

繼續閱讀