日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

常见音频编码格式解析

發布時間:2023/12/10 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 常见音频编码格式解析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

常見音頻編碼格式解析

文章目錄

  • 常見音頻編碼格式解析
    • 1.MP3編碼格式
      • 1.1.MP3概述
      • 1.2.MPEG音頻壓縮基礎
      • 1.3.MPEG Layer3編/解碼的基本原理
      • 1.4.整個MP3文件結構
        • 1.4.1.ID3V2
        • 1.4.2.音頻數據幀
        • 1.4.3.ID3v1
    • 2.AAC編碼格式
      • 2.1.AAC概述
      • 2.2.AAC擴展名
      • 2.3.AAC規格
      • 2.4.AAC特點
      • 2.5.AAC音頻格式解析
        • 2.5.1.AAC音頻格式有ADIF、ADTS、LATM
        • 2.5.2.ADIF和ADTS的header
        • 2.5.3.ADIF和ADTS數據信息
        • 2.5.4.將AAC打包成ADTS格式
        • 2.5.5.AAC文件處理流程
      • 2.6.AAC解碼流程
    • 3.WMA 編碼格式
      • 3.1.WMA概述
      • 3.2.WMA音頻格式解析
    • 4.WAV編碼格式
      • 4.1.WAV概述
      • 4.2.WAV特點
      • 4.3.剖析WAV
    • 5.ALAC編碼格式
    • 6.AC-3編碼格式
      • 6.1.AC-3概述
      • 6.2.AC-3比特流的特征
    • 7.APE編碼格式
      • 7.1.APE簡單介紹
      • 7.2.APE文件結構
        • 7.2.1.Header句法結構
        • 7.2.2.Header句法元素含義
        • 7.2.3.APE Tag結構
    • 8.FLAC編碼格式
      • 8.1.FLAC概述
      • 8.2.FLAC編碼過程及相關定義
        • 8.2.1.FLAC編碼過程
        • 8.2.2.定義
      • 8.3.FLAC格式解析
        • 8.3.1.FLAC文件結構
        • 8.3.2.FLAC格式
    • 9.AMR編碼格式
      • 9.1.AMR概述
      • 9.2.AMR編碼方式
      • 9.3.AMR文件結構解析
      • 9.4.AMR幀格式解析
      • 9.5.異常幀分析
      • 9.6.AMR幀讀取算法
      • 9.7.AMR解碼流程
      • 9.8.AMR模式選擇的自適應機制
    • 10.ATRAC編碼格式
    • 11.DTS編碼格式
    • 12.OGG編碼格式
      • 12.1.OGG概述
      • 12.2.OGG/OGV文件結構
      • 12.3.OGG/OGV文件封裝過程
      • 12.4.OGG/OGV文件Header信息
      • 12.5.OGG Vorbis 比特流的結構
      • 12.6.實例解析
    • 13.PCM編碼格式
      • 13.1.PCM概述
      • 13.2.PCM數據格式
    • 14.RealAudio

1.MP3編碼格式

1.1.MP3概述

MPEG-1 or MPEG-2 Audio Layer III是一種音頻壓縮技術,其全稱是動態影像專家壓縮標準音頻層面3(Moving Picture Experts Group Audio Layer III),簡稱為MP3,是目前最流行的音頻編碼格式。
  MP3文件是由幀(frame)構成的,幀是MP3文件最小的組成單位。MPEG音頻文件是MPEG1標準中的聲音部分,也叫MPEG音頻層,它根據壓縮質量和編碼復雜程度劃分為三層,即 Layer-1、Layer2、Layer3,且分別對應MP1、MP2、MP3這三種聲音文件,并根據不同的用途,使用不同層次的編碼。MPEG音頻編碼的層次越高,編碼器越復雜,壓縮率也越高,MP1和MP2的壓縮率分別為4:1和6:1-8:1,而MP3的壓縮率則高達10:1-12:1,也就是說,一分鐘CD音質的音樂,未經壓縮需要10MB的存儲空間,而經過MP3壓縮編碼后只有1MB左右。不過MP3對音頻信號采用的是有損壓縮方式,為了降低聲音失真度,MP3采取了“感官編碼技術”,即編碼時先對音頻文件進行頻譜分析,然后用過濾器濾掉噪音電平,接著通過量化的方式將剩下的每一位打散排列,最后形成具有較高壓縮比的MP3文件,并使壓縮后的文件在回放時能夠達到比較接近原音源的聲音效果。根據MPEG規范的說法,MPEG-4中的AAC(Advanced audio coding)將是MP3格式的下一代。

1.2.MPEG音頻壓縮基礎

在眾多音頻壓縮方法中,這些方法在保持聲音質量的同時盡量壓縮數字音頻使之占用更小的存儲空間。MPEG壓縮是該領域中效果最好的一個。這種壓縮是有損壓縮,這意味著,當運用這一方法壓縮時肯定會丟失一部分音頻信息。但是,由于壓縮方法的控制很難發現這種損失。使用幾個非常復雜和苛刻的數學算法,使得只有原始音頻中幾乎聽不到的部分損失掉。這就給重要的信息剩下了更多的空間。通過這種方法可以將音頻壓縮12倍(可以選擇壓縮率),效果顯著。正是應為他的質量,MPEG音頻變得流行起來。
  MPEG-1,MPEG-2和MPEG-4都是人們熟悉的MPEG標準,MP3只涉及到前兩中,另外還有一個非官方標準MPEG-2.5用于擴展MPEG-2/LSF到更低的采樣率。
  MPEG-1音頻(ISO/IEC 11172-3)描述了具有如下屬性的三層音頻編碼:

  • 1或2個聲道;
  • 采樣頻率為32kHz,44.1kHz或48kHz;
  • 位率從32kbps到448kbps;

每一層都有自己的優點。
  MPEG-2音頻(ISO/IEC 13818-3)有兩個MPEG-1的擴展,通常叫做MPEG-2/LSF和MPEG-2/Multichannel。
  MPEG-2/LSF有如下特點:

  • 1或2個聲道;
  • 采樣頻率為MPEG-1的一半;
  • 波特率從8kbps256kbps;

MPEG-2/Mutichannel有如下特點:

  • 多達5個聲道和1個LFE-通道(低頻增強 不是重低音);
  • 同MPEG-1一樣的采樣頻率;
  • 5.1的最高波特率可能達到1Mbps;

1.3.MPEG Layer3編/解碼的基本原理

音樂CD具有44.1KHz 16Bits立體聲的音頻質量,一張CD可以存儲74分鐘的歌曲(大約15首左右)。如何將這些歌曲無損或基本無損地進行壓縮,以使在同樣的媒體上存儲更多的歌曲,一直困擾著軟件業。當MPEG協會提出MPEG Audio Layer1~Layer3后,機會產生了。通過使用MPEG1 Layer3編碼技術,制作者得以用大約12∶1的壓縮率記錄16KHz帶寬的有損音樂信號。不過,同CD原聲區別不大。人的聽力系統具有非常優越的性能,其動態范圍超過96dB。你既可以聽到扣子掉在地上這樣小的聲音,也可以聽到波音747的強大的轟鳴聲。但當我們站在飛機場聽著波音747的轟鳴時,你還能分辨出扣子掉在地上的聲音嗎?不可能。人的聽力系統適應聲音的動態變化,人們對這種適應及屏蔽特性音質研究后得出對聲音壓縮非常有用的理論。人們很早以前就知道利用這種特性來為磁帶錄音降低噪音了(當沒有音樂時嘶嘶聲很容易聽到,而當音樂信號電平很高時嘶嘶聲不容易聽到)。當聲音較強時產生屏蔽效應。在閾值曲線下的噪音或小信號聲音無法被人耳聽到。在較強信號出現時,允許通過更多的信號。在此時增加被量化過的小信號數據(使用無用的位來攜帶更多的信息)可以達到一定程度的壓縮的目的。通常情況下,MP3壓縮器將原始聲音通過FFT(快速傅立葉變換)變化到頻域,然后通過一定的算法算出何種頻率聲音可以攜帶更多的信息。而在還原時解碼器所需要做的僅僅是將其從頻域再變換回來。

1.4.整個MP3文件結構

MP3文件大體分為三部分:TAG_V2(ID3V2),音頻數據,TAG_V1(ID3V1)

表格 1-1

sectiondescription
ID3V2在文件開始的位置,包含了作者,作曲,專輯等信息,長度不固定,擴展了ID3V1的信息量
Frame
.
.
.
Frame
一系列的幀,在文件的中間位置,個數由文件大小和幀長決定;
每個FRAME的長度可能不固定,也可能固定,由位率bitrate決定;
每個FRAME又分為幀頭和數據實體兩部分;
幀頭記錄了mp3的位率,采樣率,版本等信息,每個幀之間相互獨立。

1.4.1.ID3V2

ID3V2到現在一共有4個版本,但流行的播放軟件一般只支持第3版,即ID3v2.3。由于ID3V1記錄在MP3文件的末尾,ID3V2就只好記錄在MP3文件的首部了(如果有一天發布ID3V3,真不知道該記錄在哪里)。也正是由于這個原因,對ID3V2的操作比ID3V1要慢。而且ID3V2結構比ID3V1的結構要復雜得多,但比前者全面且可以伸縮和擴展。
  下面就介紹一下ID3V2.3:
  每個ID3V2.3的標簽都由一個標簽頭和若干個標簽幀或一個擴展標簽頭組成。關于曲目的信息如標題、作者等都存放在不同的標簽幀中,擴展標簽頭和標簽幀并不是必要的,但每個標簽至少要有一個標簽幀。標簽頭和標簽幀一起順序存放在MP3文件的首部。
(一)標簽頭
  在文件的首部順序記錄10個字節的ID3V2.3的頭部。數據結構如下:
  char Header[3];     //必須為"ID3"否則認為標簽不存在
  char Ver;       //版本號 ID3V2.3就記錄3
  char Revision;     //副版本號 此版本記錄為0
  char Flag;       //存放標志的字節,這個版本只定義了三位,稍后詳細解說
  char Size[4];      //標簽大小,包括標簽頭的10 個字節和所有的標簽幀的大小
  注:對這里我有疑惑,因為在實際尋找首幀的過程中,我發現有的mp3文件的標簽大小是不包含標簽頭的,但有的又是包含的,可能是某些mp3編碼器寫標簽的BUG,所以為了兼容只好認為其是包含的,如果按大小找不到,再向后搜索,直到找到首幀為止。


                  圖 1-1
藍色部分即為ID3V2.3的頭部:前4個字節就是ID30x03(第3版)
第5個字節:副版本號,為0
注:文中關于mp3文件數據截圖均為“紫藤花.mp3”文件中的數據截圖。
(1)標志字節
標志字節一般為0,定義如下:
abc00000
a – 表示是否使用Unsynchronisation(一般不設置)
b – 表示是否有擴展頭部,一般沒有(至少Winamp 沒有記錄),所以一般也不設置
c – 表示是否為測試標簽(99.99%的標簽都不是測試用的啦,所以一般也不設置)
上圖藍色部分第6個字節:存放標志的字節,只定義了三位,這里值為0。
(2)標簽大小
一共四個字節,但每個字節只用7位,最高位不使用恒為0。所以格式如下:
0xxxxxxx 0xxxxxxx 0xxxxxxx 0xxxxxxx
計算大小時要將0去掉,得到一個28位的二進制數,就是標簽大小,計算公式如下:
int total_size;
total_size = (Size[0]&0x7F)*0x200000 + (Size[1]&0x7F)*0x4000 + (Size[2]&0x7F)*0x80 + (Size[3]&0x7F)

上圖藍色部分第7到10字節:表示ID3標簽的大小,這里為
total_size =(0x00&0x7F)*0x200000 + (0x00&0x7F)*0x4000 + (0x10&0x7F)*0x80 + (0x72 &0x7F) = 0x872 = 2162

(二)標簽幀
  每個標簽幀都由一個10個字節的幀頭和至少一個字節的不固定長度的內容組成。它們也是順序存放在文件中,和標簽頭及其他的標簽幀也沒有特殊的字符分隔。得到一個完整的幀的內容只有從幀頭中得到內容大小后才能讀出,讀取時要注意大小,不要將其他幀的內容或幀頭讀入。

幀頭的定義如下:
  char ID[4];    /用四個字符標識一個幀,說明其內容,稍后有常用的標識對照表/
  char Size[4];   /幀內容的大小,不包括幀頭,不得小于1/
  char Flags[2];   /存放標志,只定義了6位,稍后詳細解說/


                  圖 1-2
藍色部分是一個歌曲標題的標簽幀
(1)幀標識
  用四個字符標識一個幀,說明一個幀的內容含義,常用的對照如下:
  TIT2 = 標題   //表示內容為這首歌的標題,下同
  TPE1=作者
  TALB=專集
  TRCK=音軌    //格式:N/M其中N 為專集中的第N首,M為專集中共M首,N和M為ASCII碼表示的數字
  TYER=年代   //是用ASCII 碼表示的數字
  TCON=類型   //直接用字符串表示
  COMM=備注   //格式:“eng\0備注內容”,其中eng表示備注所使用的自然語言
  注:前4個字節為幀標識,這里是54 49 54 32(TIT2)是標題的標簽幀。

表1-2 標簽幀的標識以及其意義對照表

indexcontentindexcontent
AENC[Audio encryption]TKEY[Initial key]
APIC[Attached picture]TLAN[Language(s)]
COMM[Comments]TLEN[Length]
COMR[Commercial frame]TMED[Media type]
ENCR[Encryption method registration]TOAL[Original album/movie/show title]
EQUA[Equalization]TOFN[Original filename]
ETCO[Event timing codes]TOLY[Original lyricist(s)/text writer(s)]
GEOB[General encapsulated object]TOPE[Original artist(s)/performer(s)]
GRID[Group identification registration]TORY[Original release year]
IPLS[Involved people list]TOWN[File owner/licensee]
LINK[Linked information]TPE1[Lead performer(s)/Soloist(s)]
MCDI[Music CD identifier]TPE2[Band/orchestra/accompaniment]
MLLT[MPEG location lookup table]TPE3[Conductor/performer refinement]
OWNE[Ownership frame]TPE4[Interpreted, remixed, or otherwise modified by]
PRIV[Private frame]TPOS[Part of a set]
PCNT[Play counter]TPUB[Publisher]
POPM[Popularimeter]TRCK[Track number/Position in set]
POSS[Position synchronisation frame]TRDA[Recording dates]
RBUF[Recommended buffer size]TRSN[Internet radio station name]
RVAD[Relative volume adjustment]TRSO[Internet radio station owner]
RVRB[Reverb]TSIZ[Size]
SYL[Synchronized lyric/text]TSRC[ISRC (international standard recording code)]
SYTC[Synchronized tempo codes]TSSE[Software/Hardware and settings used for]
TALB[Album/Movie/Show title]TYER[Year]
TBPM[BPM (beats per minute)]TXXX[User defined text information frame]
TCOM[Composer]UFID[Unique file identifier]
TCON[Content type]USER[Terms of use]
TCOP[Copyright message]USLT[Unsychronized lyric/text transcription]
TDAT[Date]WCOM[Commercial information]
TDLY[Playlist delay]WCOP[Copyright/Legal information]
TENC[Encoded by]WOAF[Official audio file webpage]
TEXT[Lyricist/Text writer]WOAR[Official artist/performer webpage]
TFLT[File type]WOAS[Official audio source webpage]
TIME[Time]WORS[Official internet radio station homepage]
TIT1[Content group description]WPAY[Payment]
TIT2[Title/songname/content description]WPUB[Publishers official webpage]
TIT3[Subtitle/Description refinement]WXXX[User defined URL link frame]
(2)大小
這個可沒有標簽頭的算法那么麻煩,每個字節的8 位全用,格式如下
xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
算法如下:
int FSize;
FSize = Size[0]*0x100000000 + Size[1]*0x10000+ Size[2]*0x100 + Size[3];
第5到8字節為標簽幀的大小,這里為
FSize = 0x00*0x100000000+ 0x00*0x10000 + 0x00*0x100 + 0x24 = 0x24 = 36
注意:這里的幀大小,并不包含幀頭的10個字節,只表示幀內容的大小。
(3)標志
只定義了6位,另外的10位為0,但大部分的情況下16位都為0就可以了。格式如下:abc00000ijk00000
  • a – 標簽保護標志,設置時認為此幀作廢
  • b – 文件保護標志,設置時認為此幀作廢
  • c – 只讀標志,設置時認為此幀不能修改
  • i – 壓縮標志,設置時一個字節存放兩個BCD碼表示數字
  • j – 加密標志
  • k – 組標志,設置時說明此幀和其他的某幀是一組

值得一提的是winamp在保存和讀取幀內容的時候會在內容前面加個’‘\0’',并把這個字節計算在幀內容的大小中。
  第9到10字節為標簽幀的標記,如上所述,這里為00。

幀內容是歌曲標題,標題的36個字節的內容為:紫藤花☆ゞ忍音.地帶[renyin.12u.cn]。

1.4.2.音頻數據幀

每個幀都有一個幀頭Header,長度是4Byte(32bit),幀頭后面可能有兩個字節的CRC 校驗值,這兩個字節的校驗值是否存在決定于Header信息的第16bit,為1則幀頭后面無校驗,為0則有校驗,校驗值長度為2個字節,緊跟在Header后面的就是幀的實體數據,也就是壓縮的聲音數據,當解碼器讀到此處時就進行解碼了。格式如下:
(1)幀頭格式
  幀頭長4字節,對于固定位率的MP3文件,所有幀的幀頭(即CBR幀頭)格式一樣,其數據結構如下(注:此結構要自己定義):

typedef struct frameHeader {unsigned int sync: 11; //同步信息unsigned int version: 2; //版本unsigned int layer: 2; //層unsigned int error protection: 1; // CRC校驗unsigned int bitrate_index: 4; //位率unsigned int sampling_frequency: 2; //采樣頻率unsigned int padding: 1; //幀長調節unsigned int private: 1; //保留字unsigned int mode: 2; //聲道模式unsigned int mode extension: 2; //擴充模式unsigned int copyright: 1; //版權unsigned int original: 1; //原版標志unsigned int emphasis: 2; //強調模式 }FHEADER, *LPHEADER;

表1-3 MP3幀頭字節使用說明

 
名字位長說明
同步信息11第1、2字節所有位均為1,第1字節恒為FF。
版本200-MPEG2.5 01-未定義  10-MPEG 2  11-MPEG 1
200-未定義  01-Layer 3  10-Layer 2  11-Layer 1
CRC校驗10-校驗  1-不校驗
位率4第3字節 取樣率,單位是kbps,例如采用MPEG-1 Layer 3,64kbps是,值為0101。 
bitsV1,L1V1,L2V1,L3V2,L1V2,L2V2,L3
0000freefreefreefreefreefree
000132323232(32)32(8)8(8)
001064484064(48)48(16)16(16)
001196564896(56)56(24)24(24)
01001286456128(64)64(32)32(32)
01011608064160(80)80(40)60(40)
01101929680192(96)96(48)80(48)
011122411296224(112)112(56)56(56)
1000256128112256(128)128(64)64(64)
1001288160128288(144)160(80)128(80)
1010320192160320(160)192(96)160(96)
1011352224192352(176)224(112)112(112)
1100384256224384(192)256(128)128(128)
1101416320256416(224)320(114)256(114)
1110448384320448(256)384(160)320(160)
1111badbadbadbadbadbad
V1 - MPEG 1  V2 - MPEG 2 and MPEG 2.5 L1 - Layer 1   L2 - Layer 2  L3 - Layer 3 "free" 表示位率可變   "bad" 表示不允許值
采樣率2采樣頻率,對于MPEG-1: 00-44.1kHz 01-48kHz 10-32kHz 11-未定義 對于MPEG-2: 00-22.05kHz 01-24kHz 10-16kHz 11-未定義 對于MPEG-2.5: 00-11.025kHz 01-12kHz 10-8kHz 11-未定義
幀長調節1用來調整文件頭長度,0-無需調整,1-調整,具體調整計算方法見下文。
保留字1沒有使用。
聲道模式2第4字節表示聲道, 00-立體聲Stereo 01-Joint Stereo      10-雙聲道Dual channel 11-單聲道Single channel 
擴充模式2當聲道模式為01是才使用。
Value強度立體聲MS立體聲
00offoff
01onoff
10offon
11onon
版權1文件是否合法,0-不合法 1-合法
原版標志1是否原版,0-非原版 1-原版
強調方式2用于聲音經降噪壓縮后再補償的分類,很少用到,今后也可能不會用。 00-未定義 01-50/15ms 10-保留 11-CCITT J.17

注意:關于讀取幀頭也可以使用下面的方法

定義一個結構體

typedef struct frameHeader { unsigned int sync1:8; //同步信息1unsigned int error_protection:1; //CRC校驗 unsigned int layer:2; //層 unsigned int version:2; //版本 unsigned int sync2:3; //同步信息2unsigned int extension:1; //版權 unsigned int padding:1; //填充空白字 unsigned int sample_rate_index:2; //采樣率索引 unsigned int bit_rate_index:4; //位率索引unsigned int emphasis:2; //強調方式 unsigned int original:1; //原始媒體 unsigned int copyright:1; //版權標志 unsigned int mode_extension:2; //擴展模式,僅用于聯合立體聲 unsigned int channel_mode:2; //聲道模式}FHEADER, *pFHEADER;

請注意該結構體將同步信息分成了兩個部分,而且其他的位的順序也和上表列出的有所差別,這個主要是因為c語言在存取數據時總是從低位開始,而這個幀頭是需要從高位來讀取的。
讀取方式如下:
FHEADER header;
fread( &header, sizeof( FHEADER ), 1, streams );  //這里假設文件已打開,讀取位置已經指向幀頭所在的位置
這樣一次就可以讀入幀頭的所有信息了。


                  圖 1-3

第1幀數據:幀頭為FF FB 90 04
11111111 11111011 10010000 00000010
前11位:同步信息
第12到13位:版本,其值為11 ->MPEG 1
第14到15位:層,其值為01->Layer 3
第16位:CRC檢驗標識,其值為1 ->不校驗
第17到20位:位率,其值為1001,從前面可知本幀為V1,L3類型, ->128K
第21到22位:采樣率,其值為00,從前面知本幀為 MPEG 1-> 44.1K
第23位:幀長調節,其值為0 ->無需調整
第24位:未使用
第25到26位:聲道模式,其值為00->立體聲Stereo
第27到28位:擴充模式,當聲道模式為01(聯合立體聲)時才使用,此處未使用
第29位:版權,其值為0->無版權
第30位:原版標志,其值為1->是原版文件
第31到32位:強調方式,其值為00->未定義
(2)計算幀長度
  我們首先區分兩個術語:幀大小和幀長度。幀大小即每幀采樣數表示一幀中采樣的個數,這是恒定值。其值如下表所示

MPEG1MPEG2(LSF)MPEG2.5(LSF)
Layer1384384384
Layer2115211521152
Layer31152576576

幀長度是壓縮時每一幀的長度,包括幀頭。它將填充的空位也計算在內。LayerI的一個空位長4字節,LayerII和LayerIII的空位是1字節。當讀取MPEG文件時必須計算該值以便找到相鄰的幀。注意:因為有填充和比特率變換,幀長度可能變化。
  從頭中讀取比特率,采樣頻率和填充的值后可以進行計算,
LyaerI使用公式:
            幀長度(字節) = (( 每幀采樣數/ 8 * 比特率 ) / 采樣頻率 ) + 填充 * 4
LyerII和LyaerIII使用公式:
             幀長度(字節)= (( 每幀采樣數/ 8 * 比特率 ) / 采樣頻率 ) + 填充
例如圖1-3中,比特率為128K,采樣率為44.1K,填充0,則其幀長度為:
                  (1152 / 8 * 128K)/44.1K = 417 (字節)
(3)每幀的持續時間
  每幀的持續時間可以通過計算獲得,下面給出計算公式
               每幀持續時間(毫秒) = 每幀采樣數 / 采樣頻率 * 1000ms
  如圖1-3中,其每幀時間為:
                 1152 / 44.1K * 1000 = 26.12 (約等于26ms)
  如果是MPEG2 Layer III 采樣率為16KHz的話那一幀要持續36毫秒,這個相差還是蠻大的,所以還是應該通過計算來獲的。
(4)CRC校驗
  如果幀頭的校驗位為0,則幀頭后就有一個16位的CRC值,這個值是big-endian的值,把這個值和該幀通過計算得出的CRC值進行比較就可以得知該幀是否有效。
(5)幀數據
  在幀頭后邊是Side Info(姑且稱之為通道信息)。對標準的立體聲MP3文件來說其長度為32字節。通道信息后面是Scale factor(增益因子)信息。當解碼器在讀到上述信息后,就可以進行解碼了。對應圖1-3中地址0x880到0x89F(含),此處數據全為0。當MP3文件被打開后,播放器首先試圖對幀進行同步,然后分別讀取通道信息及增益因子等數據,再進行霍夫曼解碼,至此我們已經獲得解壓后的數據。但這些數據仍然不能進行播放,它們還處于頻域,要想聽到歌曲還要將它由頻域通過特定的手段轉換到時域。接下來的處理分別為立體化處理;抗鋸齒處理;IMDCT變換;IDCT變換及窗口化滑動處理。
  對于mp3來說現在有兩種編碼方式:一種是CBR,也就是固定位率,固定位率的幀的大小在整個文件中都是固定的(公式如上所述),只要知道文件總長度,和從第一幀幀頭讀出的信息,就可以通過計算得出這個mp3文件的信息,比如總的幀數,總的播放時間等等,要定位到某一幀或某個時間點也很方便,這種編碼方式不需要文件頭,第一幀開始就是音頻數據;另一種是VBR,就是可變位率,VBR是XING公司推出的算法,所以在MP3的FRAME里會有“Xing”這個關鍵字(也有用“Info”來標識的,現在很多流行的小軟件也可以進行VBR壓縮,它們是否遵守這個約定,那就不得而知了),它存放在MP3文件中的第一個有效幀的數據區里,它標識了這個MP3文件是VBR的。同時第一個幀里存放了MP3文件的幀的總個數,這就很容易獲得播放總時間,同時還有100個字節存放了播放總時間的100個時間分段的幀索引,假設4分鐘的MP3歌曲,240s,分成100段,每兩個相鄰INDEX的時間差就是2.4s,所以通過這個INDEX,只要前后處理少數的FRAME,就能快速找出我們需要快進的幀頭。其實這第一幀就相當于文件頭了。不過現在有些編碼器在編碼CBR文件時也像VBR那樣將信息記入第一幀,比如著名的lame,它使用“Info”來做CBR的標記。
  CBR總播放時長計算公式:
                   播放時長 = (文件大小 – ID3標簽大小) * 8 / 比特率
  VBR總播放時長計算公式:
                  播放時長 = 有效數據幀總幀數 * 每幀采樣數 / 采樣率
(6)VBR頭
  這里列出VBR的第一幀存儲文件信息的頭的格式。有兩種格式,一種是常見的XINGHeader(頭部包含字符‘Xing’),另一種是VBRIHeader(頭部包含字符‘VBRI’)鑒于VBRIHeader不常見,下面只說XINGHeader。VBR的第一幀不包含聲音數據,其長度是156個字節,用來存放標準的聲音幀頭(4字節)、VBR文件標識、幀數、文件字節數等信息,具體結構說明見表1-4。

表1-4 VBR文件第一幀結構

字節說明
0 - 3與CBR相同的標準聲音幀頭
4 - x存放VBR文件標識“Xing”(58 69 6E 67),此標識具體位置視采用的MPEG標準和聲道模式而定。標識的前后字節沒有使用。
36 - 39MPEG-1和非單聲道(常見)
21 - 24MPEG-1和單聲道
21 - 24MPEG-2和非單聲道
13 - 16MPEG-2和非單聲道
40 - 43指示VBR頭具體內容的標志, 組合方式為邏輯或。區域是強制的,說明是否存儲了幀數、文件長度、目錄表和VBR規模信息,如果存儲了,則分別為0x0001、0x0002、0x0004、0x0008。 如0x0007(意味總幀數,文件長度,目錄表的存儲區有效)
44 - 47幀數(包括第一幀),存儲總幀數的Big-Endian值
48 - 51文件長度,存儲文件長度Big-Endian值,單位為字節
52 - 151目錄表,用來按時間進行字節定位。 100字節的 TOC 索引,用于快速定位。 對于這個區域的存儲內容,我認為可有可無,因為用1個字節來索引一個幾兆文件的一幀是不可能做到準確定位的,就我所見基本上所有的VBR的mp3文件的 TOC都幾乎是相同的,就是把256平均分成100份然后填進去,其實和正確的值差不到哪里去,如果懶的話這么做也成吧,反正也是不準確的定位。 TCO索引的計算方式如下 `(TOC[i] / 256) * 文件長度` 比如文件持續240秒,我需要跳到60秒,文件長度為5000000字節 計算如下 `TOC[(60/240)*100] = TOC[25]` 然后相對于文件中的位置大約是在 `(TOC[25]/256) * 5000000` 如果要自己重建的話,基本是把這個步驟反過來做就可以了。要求準確的話,就需要根據時間點找到正確幀的位置然后再計算,我定位幀的做法都是從第一幀開始搜索,這樣偏差我認為不會超過1幀,也比較準確,不過計算出來的TOC的值還是和偷懶的做法大同小異。
152 -155VBR規模,用于位率變動

在VBR格式的第一幀中,XING Header包括幀頭一共最多只需要156個字節就夠了,當然也可以在XING Header后面存儲編碼器的信息,比如lame在其后就是存儲其版本,這需要給第一幀留足夠的空間才行。
至于mp3的信息用從XING Header讀出的信息就可以計算,比如:
總持續時間 = 總幀數 * 每幀采樣數 / 采樣率 (結果為秒)
平均位率 = 文件長度 / 總持續時間 * 8

1.4.3.ID3v1

ID3V1標準并不周全,存放的信息少,無法存放歌詞,無法錄入專輯封面、圖片等。ID3V2是一個相當完備的標準,但給編寫軟件帶來困難,雖然贊成此格式的人很多,在軟件中絕大多數MP3仍在使用ID3V1標準。ID3v1標簽包含藝術家,標題,唱片集,發布年代和流派。另外還有額外的注釋空間。位于音頻文件的最后固定為128字節。可以讀取該文件的最后這128字節獲得標簽。
ID3V1結構如下:
AAABBBBB BBBBBBBB BBBBBBBB BBBBBBBB BCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCD DDDDDDDD DDDDDDDD DDDDDDDD DDDDDEEE EFFFFFFF FFFFFFFF FFFFFFFF FFFFFGHI

表1-5 ID3V1.0文件尾說明

字節長度(字節)說明
1-3(A)3存放“TAG”字符,表示ID3 V1.0標準,緊接其后的是歌曲信息。
4-33(B)30歌名
34-63?30作者
64-93(D)30專輯名
94-97(E)4年份
98-125(F)28附注
126(G)1保留位
127(H)1音軌號
128(I)1MP3音樂類別(即流派),共147種

ID3V1的各項信息都是順序存放,沒有任何標識將其分開,比如標題信息不足30個字節,則使用’‘\0’'填充,數據結構定義如下:

typedef struct tagID3V1 {charHeader[3]; /*標簽頭必須是"TAG"否則認為沒有標簽*/charTitle[30]; /*標題*/charArtist[30]; /*作者*/charAlbum[30]; /*專集*/charYear[4];  /*出品年代*/charComment[28];  /*備注*/charreserve;  /*保留*/chartrack; /*音軌*/charGenre; /*類型*/ }ID3V1, *pID3V1;

表1-6 MP3音樂類別(紅色為Winamp擴充,藍色為其他擴充)

| num | 類別 | num | 類別 | num | 類別 | num | 類別 |
|--------|--------|--------|--------|--------|--------|--------|--------|--------|
|0 | ‘Blues’ |37 |‘Sound Clip’ |74 |‘Acid Jazz’ |111 |“SlowJam”|
|1 |‘Classic Rock’ |38 |‘Gospel’ |75 |‘Polka’ |112 |“Club”|
|2 |‘Country’ |39 |‘Noise’ |76 |‘Retro’ |113 |“Tango”|
|3 |‘Dance’ |40 |‘AlternRock’ |77 |‘Musical’ |114 |“Samba”|
|4 |‘Disco’ |41 |‘Bass’ |78 |‘Rock & Roll’ |115 |“Folklore”|
|5 |‘Funk’ |42 |‘Soul’ |79 |‘Hard Rock’ |116 |“Ballad”|
|6 |‘Grunge’ |43 |‘Punk’ |80 |“Folk” |117 |“PowerBallad”|
|7 |‘Hip-Hop’ |44 |‘Space’ |81 |“Folk-Rock” |118 |“RhythmicSoul”|
|8 |‘Jazz’ |45 |‘Meditative’ |82 |“NationalFolk” |119 |“Freestyle”|
|9 |‘Metal’ |46 |‘Instrumental Pop’ |83 |“Swing” |120 |“Duet”|
|10 |‘New Age’ |47 |‘Instrumental Rock’ |84 |“FastFusion” |121 |“PunkRock”|
|11 |‘Oldies’ |48 |‘Ethnic’ |85 |“Bebob” |122 |“DrumSolo”|
|12 |‘Other’ |49 |‘Gothic’ |86 |“Latin” |123 |“Acapella”|
|13 |‘Pop’ |50 |‘Darkwave’ |87 |“Revival” |124 |“Euro-House”|
|14 |‘R&B’ |51 |‘Techno-Industrial’ |88 |“Celtic” |125 |“DanceHall”|
|15 |‘Rap’ |52 |‘Electronic’ |89 |“Bluegrass” |126 |“Goa”|
|16 |‘Reggae’ |53 |‘Pop-Folk’ |90 |“Avantgarde” |127 |“Drum&Bass”|
|17 |‘Rock’ |54 |‘Eurodance’ |91 |“GothicRock” |128 |“Club-House”|
|18 |‘Techno’ |55 |‘Dream’ |92 |“ProgessiveRock” |129 |“Hardcore”|
|19 |‘Industrial’ |56 |‘Southern Rock’ |93 |“PsychedelicRock” |130 |“Terror”|
|20 |‘Alternative’ |57 |‘Comedy’ |94 |“SymphonicRock” |131 |“Indie”|
|21 |‘Ska’ |58 |‘Cult’ |95 |“SlowRock” |132 |“BritPop”|
|22 |‘Death Metal’ |59 |‘Gangsta’ |96 |“BigBand” |133 |“Negerpunk”|
|23 |‘Pranks’ |60 |‘Top 40’ |97 |“Chorus” |134 |“PolskPunk”|
|24 |‘Soundtrack’ |61 |‘Christian Rap’ |98 |“EasyListening” |135 |“Beat”|
|25 |‘Euro-Techno’ |62 |‘Pop/Funk’ |99 |“Acoustic” |136 |“ChristianGangstaRap”|
|26 |‘Ambient’ |63 |‘Jungle’ |100|“Humour” |137 |“Heavyl”|
|27 |‘Trip-Hop’ |64 |‘Native American’ |101|“Speech” |138 |“Blackl”|
|28 |‘Vocal’ |65 |‘Cabaret’ |102|“Chanson” |139 |“Crossover”|
|29 |‘Jazz+Funk’ |66 |‘New Wave’ |103|“Opera” |140 |“ContemporaryChristian”|
|30 |‘Fusion’ |67 |‘Psychadelic’ |104|“ChamberMusic” |141 |“ChristianRock”|
|31 |‘Trance’ |68 |‘Rave’ |105|“Sonata” |142 |“Merengue”|
|32 |‘Classical’ |69 |‘Showtunes’ |106|“Symphony” |143 |“Salsa”|
|33 |‘Instrumental’ |70 |‘Trailer’ |107|“BootyBass” |144 |“Trashl”|
|34 |‘Acid’ |71 |‘Lo-Fi’ |108|“Primus” |145 |“Anime”|
|35 |‘House’ |72 |‘Tribal’ |109|“PornGroove” |146 |“JPop”|
|36 |‘Game’ |73 |‘Acid Punk’ |110|“Satire” |147 |“Synthpop”|

其他任何的數值都認為是“unknown”

補充:
APEV2:一般存在于ID3V1之前,
標簽頭:

headerID[8]; //固定為“APETAGEX” version[4]; //表示版版本 size[4]; //所有標簽幀和尾標簽的總長度,低位在前。 Count[4]; //標簽幀的個數,低位在前。 Flags[4]; // Reserved[8]; //保留位

標簽尾:與標簽頭一樣.
標簽結構:

Size 4個字節大小 //幀內容的長度,低位在前 Flags 4個字節大小 // Id //真標識,長度不固定 Pre //恒為0 Value //

Lyrics3v2:這個幀結構是用來保存歌詞的。如果它存在的話,一般就是放在APEV2與ID3V1之間。結構如下:

開始標志 25字節 //“LYRICSBEGININD000003110LYR”,固定的。 歌詞大小 5字節 //歌詞的長度 歌詞內容 x字節 //歌詞的內容,長度肯定不固定。 幀大小 6字節 //前3項的長度,也就是25+5+歌詞內容長度 結尾標識 9字節 //“LYRICS200”固定的

這個標簽很有用,在我們計算幀大小的時候就很有必要了,因為比如一個MP3是6M,但是可能歌詞就占了1.5M,所以實際的幀只有4.5,所以在計算一些必要的信息時,我們需要把歌詞的部分去掉。例如,我們可以從尾部移動137個字節(128+9),然后獲取9個字節,判斷是否與尾部標識匹配,如果匹配,則再移動6個字節,計算出尾部歌詞的大小。我們就可以算出尾部歌詞的字節數了。

2.AAC編碼格式

2.1.AAC概述

AAC是高級音頻編碼(Advanced Audio Coding)的縮寫,出現于1997年,最初是基于MPEG-2的音頻編碼技術。由Fraunhofer IIS、Dolby Laboratories、AT&T、Sony等公司共同開發,目的是取代MP3格式。2000年,MPEG-4標準出臺,AAC重新集成了其它技術(PS,SBR),為區別于傳統的MPEG-2 AAC,故含有SBR或PS特性的AAC又稱為MPEG-4 AAC。
  AAC是新一代的音頻有損壓縮技術,它通過一些附加的編碼技術(比如PS,SBR等),衍生出了LC-AAC,HE-AAC,HE-AACv2三種主要的編碼,LC-AAC就是比較傳統的AAC,相對而言,主要用于中高碼率(>=80Kbps),HE-AAC(相當于AAC+SBR)主要用于中低碼率(<=80Kbps),而新近推出的HE-AACv2(相當于AAC+SBR+PS)主要用于低碼率(<=48Kbps),事實上大部分編碼器設成<=48Kbps自動啟用PS技術,而>48Kbps就不加PS,就相當于普通的HE-AAC。

2.2.AAC擴展名

AAC編碼的主要擴展名有三種:
  1).AAC—使用MPEG-2 Audio Transport Stream( ADTS,參見MPEG-2 )容器,區別于使用MPEG-4容器的MP4/M4A格式,屬于傳統的AAC編碼(FAAC默認的封裝,但FAAC亦可輸出 MPEG-4 封裝的AAC)
  2).MP4—使用了MPEG-4 Part 14的簡化版即3GPP Media Release 6 Basic (3gp6,參見3GP ) 進行封裝的AAC編碼(Nero AAC 編碼器僅能輸出MPEG-4封裝的AAC);
  3).M4A - 為了區別純音頻MP4文件和包含視頻的MP4文件而由蘋果(Apple)公司使用的擴展名,Apple iTunes 對純音頻MP4文件采用了".M4A"命名。M4A的本質和音頻MP4相同,故音頻MP4文件亦可直接更改擴展名為M4A。

2.3.AAC規格

AAC共有9種規格,以適應不同的場合的需要:

表1 AAC規則

文件規格
MPEG-2 AAC LC低復雜度規格(Low Complexity)
MPEG-2 AAC Main主規格
MPEG-2 AAC SSR可變采樣率規格(Scaleable Sample Rate)
MPEG-4 AAC LC低復雜度規格(Low Complexity)
MPEG-4 AAC Main主規格
MPEG-4 AAC SSR變采樣率規格(Scaleable Sample Rate)
MPEG-4 AAC LTP長時期預測規格(Long Term Predicition)
MPEG-4 AAC LD低延遲規格(Low Delay)
MPEG-4 AAC HE高效率規格(High Efficiency)

其中: MPEG-2 AAC LC 比較簡單,無增益控制,但提高了編碼效率,在中等碼率(96kbps-192kbps)的編碼效率以及音質方面,都能找到平衡點。
  MPEG-4 AAC LC常用于MP4文件中的音頻編碼。
  MPEG-4 AAC Main包含了除增益控制之外的全部功能,其音質最好。
  MPEG-4 AAC HE適合用于低碼率(32kbps-96kbps)編碼。
  目前使用最多的是LC和HE(適合低碼率)。流行的Nero AAC編碼程序只支持LC,HE,HEv2這三種規格,編碼后的AAC音頻,規格顯示都是LC。HE其實就是AAC(LC)+SBR技術,HEv2就是AAC(LC)+SBR+PS技術。


           圖 2-1

HE:“High Efficiency”(高效性)。HE-AAC v1(又稱AACPlusV1,SBR),用容器的方法實現了AAC(LC)+SBR技術。SBR其實代表的是Spectral Band Replication(頻段復制)。簡要敘述一下,音樂的主要頻譜集中在低頻段,高頻段幅度很小,但很重要,決定了音質。如果對整個頻段編碼,若是為了保護高頻就會造成低頻段編碼過細以致文件巨大;若是保存了低頻的主要成分而失去高頻成分就會喪失音質。SBR把頻譜切割開來,低頻單獨編碼保存主要成分,高頻單獨放大編碼保存音質,“統籌兼顧”了,在減少文件大小的情況下還保存了音質,完美的化解這一矛盾。
  HEv2:用容器的方法包含了HE-AAC v1和PS技術。PS指“parametric stereo”(參數立體聲)。原來的立體聲文件文件大小是一個聲道的兩倍。但是兩個聲道的聲音存在某種相似性,根據香農信息熵編碼定理,相關性應該被去掉才能減小文件大小。所以PS技術存儲了一個聲道的全部信息,然后,花很少的字節用參數描述另一個聲道和它不同的地方。

2.4.AAC特點

1)AAC是一種高壓縮比的音頻壓縮算法,但它的壓縮比要遠超過較老的音頻壓縮算法,如AC-3、MP3等。并且其質量可以同未壓縮的CD音質相媲美。
  2)同其他類似的音頻編碼算法一樣,AAC也是采用了變換編碼算法,但AAC使用了分辨率更高的濾波器組,因此它可以達到更高的壓縮比。
  3)AAC使用了臨時噪聲重整、后向自適應線性預測、聯合立體聲技術和量化哈夫曼編碼等技術,這些技術的使用都使壓縮比得到進一步的提高。(壓縮比通常為18:1)
  4)AAC支持更多種采樣率和比特率、支持1個到48個音軌、支持多達15個低頻音軌、具有多種語言的兼容能力、還有多達15個內嵌數據流。
  5)AAC支持更寬的聲音頻率范圍,最高可達到96kHz,最低可達8KHz,遠寬于MP3的16KHz-48kHz的范圍。
  6)不同于MP3及WMA,AAC幾乎不損失聲音頻率中的甚高、甚低頻率成分,并且比WMA在頻譜結構上更接近于原始音頻,因而聲音的保真度更好。
  7)AAC采用優化的算法達到了更高的解碼效率,解碼時只需較少的處理能力。
  8)不足:屬于有損壓縮,與APE、FLAC等無損格式相比,音質有“本質上”差距,同時USB3.0和大容量存儲空間等技術的普及,AAC的優勢不明顯。

2.5.AAC音頻格式解析

2.5.1.AAC音頻格式有ADIF、ADTS、LATM

  • ADIF:Audio Data Interchange Format音頻數據交換格式。這種格式的特征是可以確定的找到這個音頻數據的開始,不需進行在音頻數據流中間開始的解碼,即它的解碼必須在明確定義的開始處進行。故這種格式常用在磁盤文件中。

  • ADTS:Audio Data Transport Stream音頻數據傳輸流。這種格式的特征是它是一個有同步字的比特流,解碼可以在這個流中任何位置開始。它的特征類似于mp3數據流格式。

  • LATM 的全稱為“Low-overhead MPEG-4 Audio TransportMultiplex”(低開銷音頻傳輸復用),是MPEG-4 AAC制定的一種高效率的碼流傳輸方式,MPEG-2 TS流也采用LATM作為AAC音頻碼流的封裝格式之一。

LATM作為AAC音頻碼流的封裝格式之一。
  LATM格式也以幀為單位,主要由AudioSpecificConfig(音頻特定配置單元)與音頻負載組成。AudioSpecificConfig描述了一個LATM幀的信息,音頻負載主要由PayloadLengthInfo(負載長度信息)和PayloadMux(負載凈荷)組成。AudioSpecificConfig結構說明如下:
The Audio Specific Config is the global header for MPEG-4 Audio:

5 bits: object type if (object type == 31)6 bits + 32: object type 4 bits: frequency index if (frequency index == 15)24 bits: frequency 4 bits: channel configuration var bits: AOT Specific Config

AudioSpecificConfig 信息可以是帶內傳,也可以是帶外傳。所謂帶內傳,就是指每一個LATM 幀,都含有一個AudioSpecificConfig 信息;而帶外傳,則每一個LATM幀都不含有AudioSpecificConfig信息,而通過其他方式把AudioSpecificConfig信息發送到解碼端,由于AudioSpecificConfig信息一般是不變的,所以只需發送一次即可。由此可見,AudioSpecificConfig信息采用帶內傳輸可適應音頻編碼信息不斷變化的情況,而采用帶外傳輸,可以節省音頻傳輸碼率。帶內或帶外傳,由muxconfigPresent 標志位決定。例如流媒體應用中,muxconfigPresent可設置為0,這樣LATM幀中將不含有AudioSpecificConfig信息,LATM幀通過RTP包發送出去,AudioSpecificConfig 可通過SDP文件一次性傳送到解碼端。

AudioSpecificConfig 主要參數

參數含義
numSubFrames子幀的數目
numProgram復用的節目數
numLayer復用的層數
frameLengthType負載的幀長度類型,包括固定長度與可變長度
audioObjectType音頻對象類型
samplingFrequency采樣率
channelConfiguration聲道配置

音頻負載由若干子幀組成,每個子幀由PayloadLengthInfo和PayloadMux組成,與ADTS幀凈荷一樣,音頻負載主要包含原始幀數據。
  AAC打包成TS流通常有兩種方式,分別是先打包成ADTS或LATM。ADTS的每一幀都有個幀頭,在每個幀頭信息都一樣的狀況下,會有很大的冗余。LATM格式具有很大的靈活性,每幀的音頻配置單元既可以帶內傳輸,又可以帶外傳輸。正因為如此,LATM不僅適用于流傳輸還可以用于RTP傳輸,RTP傳輸時,若音頻數據配置信息是保持不變,可以先通過SDP會話先傳輸StreamMuxConfig(AudioSpecificConfig)信息,由于LATM流由一個包含了一個或多個音頻幀的audioMuxElements序列組成。一個完整或部分完整的audioMuxElement可直接映射到一個RTP負載上。
  簡單說,ADTS可以在任意幀解碼,也就是說它每一幀都有頭信息。ADIF只有一個統一的頭,所以必須得到所有的數據后解碼。且這兩種的header的格式也是不同的,目前一般編碼后的和抽取出的都是ADTS格式的音頻流。兩者具體的組織結構如下所示:

AAC的ADIF格式見下圖:

header()raw_data_stream()

AAC的ADTS的一般格式見下圖:

syncwordheader()error_check()raw_data_block()

圖中表示出了ADTS一幀的簡明結構,其兩邊的空白矩形表示一幀前后的數據。

2.5.2.ADIF和ADTS的header

(1)ADIF的頭信息:

ADIF頭信息位于AAC文件的起始處,接下來就是連續的raw data blocks。
  組成ADIF頭信息的各個域如下所示:

Field nameSize(bits)Comment
adif_id32(bits)Always: “ADIF”
copyright_id_present1
copyright_id72Only if copyright_id_present == 1
original_copy1
home1
bitstream_type10: CBR, 1: VBR
bitrate23For CBR: bitrate, for VBR: peak bitrate, 0 means unknown
num_program_config_elements4
The next 2 fields come (num_program_config_elements + 1) times
buffer_fullness20Only if bitstream_type == 0
program_config_elementVAR

(2)下面分析下ADTS頭文件結構和信息:
  AAC音頻文件的每一幀由ADTS Header和AAC Audio Data組成。

一般情況下ADTS的頭信息都是7個字節,分為2部分:其一為固定頭信息,緊接著是可變頭信息。固定頭信息中的數據每一幀都相同,而可變頭信息則在幀與幀之間可變。

adts_fixed_header(); adts_variable_header();

ADTS的固定頭信息:

  • Syncword:同步字,總是0xFFF,all bits must be 1,代表著一個ADTS幀的開始;解碼器可通過0xFFF確定每個ADTS的開始位置,因為它的存在,解碼可以在這個流中任何位置開始, 即可以在任意幀解碼。
  • ID:MPEG Version: 0 for MPEG-4,1 for MPEG-2
  • Layer:always: ‘00’
  • protection_absent:Warning, set to 1 if there is no CRC and 0 if there is CRC
  • profile:表示使用哪個級別的AAC,如01 Low Complexity(LC) – AAC LC。

profile的值等于 Audio Object Type的值減1。
  profile = MPEG-4 Audio Object Type - 1

在MPEG-2 AAC中定義了3種:

  • sampling_frequency_index:表示使用的采樣率下標,通過這個下標在Sampling Frequencies[ ]數組中查找得知采樣率的值。

There are 13 supported frequencies:

  • channel_configuration:表示聲道數,比如2表示立體聲雙聲道

ADTS的可變頭信息:

  • aac_frame_length:一個ADTS幀的長度包括ADTS頭和AAC原始流。
  • adts_buffer_fullness:0x7FF說明是碼率可變的碼流。
  • number_of_raw_data_blocks_in_frame:

表示ADTS幀中有number_of_raw_data_blocks_in_frame + 1個AAC原始幀。所以說number_of_raw_data_blocks_in_frame == 0 表示說ADTS幀中有一個AAC數據塊。(一個AAC原始幀包含一段時間內1024個采樣及相關數據)
組成ADTS頭信息的各個域如下所示:

序號域長度(bits)說明
1Syncword12all bits must be 1
2MPEG version10 for MPEG-4, 1 for MPEG-2
3Layer2always “00”
4Protection Absent1et to 1 if there is no CRC and 0 if there is CRC
5Profile2the MPEG-4 Audio Object Type minus 1
6MPEG-4 Sampling Frequency Index4MPEG-4 Sampling Frequency Index (15 is forbidden)
7Private Stream1set to 0 when encoding, ignore when decoding
8MPEG-4 Channel Configuration3MPEG-4 Channel Configuration (in the case of 0, the channel configuration is sent via an inband PCE)
9Originality1set to 0 when encoding, ignore when decoding
10Home1set to 0 when encoding, ignore when decoding
11Copyrighted Stream1set to 0 when encoding, ignore when decoding
12Copyrighted Start1set to 0 when encoding, ignore when decoding
13Frame Length13this value must include 7 or 9 bytes of header length: FrameLength = (ProtectionAbsent == 1 ? 7 : 9) + size(AACFrame)
14Buffer Fullness11buffer fullness
15Number of AAC Frames2number of AAC frames (RDBs) in ADTS frame minus 1, for maximum compatibility always use 1 AAC frame per ADTS frame
16CRC16CRC if protection absent is 0

2.5.3.ADIF和ADTS數據信息

在AAC中,原始數據塊的組成可能有六種不同的元素:
  SCE:Single Channel Element單通道元素。單通道元素基本上只由一個ICS組成。一個原始數據塊最可能由16個SCE組成。
  CPE:Channel Pair Element 雙通道元素,由兩個可能共享邊信息的ICS和一些聯合立體聲編碼信息組成。一個原始數據塊最多可能由16個SCE組成。
  CCE:Coupling Channel Element 藕合通道元素。代表一個塊的多通道聯合立體聲信息或者多語種程序的對話信息。
  LFE:Low Frequency Element 低頻元素。包含了一個加強低采樣頻率的通道。
  DSE:Data Stream Element 數據流元素,包含了一些并不屬于音頻的附加信息。
  PCE:Program Config Element 程序配置元素。包含了聲道的配置信息。它可能出現在ADIF 頭部信息中。
  FIL:Fill Element 填充元素。包含了一些擴展信息。如SBR,動態范圍控制信息等。

2.5.4.將AAC打包成ADTS格式

如果是通過嵌入式高清解碼芯片做產品的話,一般情況的解碼工作都是由硬件來完成的。所以大部分的工作是把AAC原始流打包成ADTS的格式,然后丟給硬件就行了。通過對ADTS格式的了解,很容易就能把AAC打包成ADTS。我們只需得到封裝格式里面關于音頻采樣率、聲道數、元數據長度、aac格式類型等信息。然后在每個AAC原始流前面加上個ADTS頭就OK了。
  貼上ffmpeg中添加ADTS頭的代碼,就可以很清晰的了解ADTS頭的結構:

int ff_adts_write_frame_header(ADTSContext *ctx, uint8_t *buf, int size, int pce_size) {PutBitContext pb;init_put_bits(&pb, buf, ADTS_HEADER_SIZE);/* adts_fixed_header */put_bits(&pb, 12, 0xfff); /* syncword */put_bits(&pb, 1, 0); /* ID */put_bits(&pb, 2, 0); /* layer */put_bits(&pb, 1, 1); /* protection_absent */put_bits(&pb, 2, ctx->objecttype); /* profile_objecttype */put_bits(&pb, 4, ctx->sample_rate_index);put_bits(&pb, 1, 0); /* private_bit */put_bits(&pb, 3, ctx->channel_conf); /* channel_configuration */put_bits(&pb, 1, 0); /* original_copy */put_bits(&pb, 1, 0); /* home *//* adts_variable_header */put_bits(&pb, 1, 0); /* copyright_identification_bit */put_bits(&pb, 1, 0); /* copyright_identification_start */put_bits(&pb, 13, ADTS_HEADER_SIZE + size + pce_size); /* aac_frame_length */put_bits(&pb, 11, 0x7ff); /* adts_buffer_fullness */put_bits(&pb, 2, 0); /* number_of_raw_data_blocks_in_frame */flush_put_bits(&pb);return 0; }

2.5.5.AAC文件處理流程

(1)判斷文件格式,確定為ADIF或ADTS;
  (2)若為ADIF,解ADIF頭信息,跳至第6步;
  (3)若為ADTS,尋找同步頭;
  (4)解ADTS幀頭信息;
  (5)若有錯誤檢測,進行錯誤檢測;
  (6)解塊信息;
  (7)解元素信息。

2.6.AAC解碼流程

語音系統對實時性要求較高,基本是這樣一個流程,采集音頻數據,本地編碼,數據上傳,服務器處理,數據下發,本地解碼。
  ADTS是幀序列,本身具備流特征,在音頻流的傳輸與處理方面更加合適。
  下面是AAC解碼流程圖:


          圖2-2 AAC解碼流程圖

在主控模塊開始運行后,主控模塊將AAC比特流的一部分放入輸入緩沖區,通過查找同步字得到一幀的起始,找到后,根據ISO/IEC 13818-7所述的語法開始進行Noisless Decoding(無噪解碼),無噪解碼實際上就是哈夫曼解碼,通過反量化(Dequantize)、聯合立體聲(Joint Stereo),知覺噪聲替換(PNS),瞬時噪聲整形(TNS),反離散余弦變換(IMDCT),頻段復制(SBR)這幾個模塊之后,得出左右聲道的PCM碼流,再由主控模塊將其放入輸出緩沖區輸出到聲音播放設備。

技術解析:
1、主控模塊:
  所謂的主控模塊,它的主要任務是操作輸入輸出緩沖區,調用其它各模塊協同工作。其中,輸入輸出緩沖區均由DSP控制模塊提供接口。輸出緩沖區中將存放的數據為解碼出來的PCM數據,代表了聲音的振幅。它由一塊固定長度的緩沖區構成,通過調用DSP控制模塊的接口函數,得到頭指針,在完成輸出緩沖區的填充后,調用中斷處理輸出至I2S接口所連接的音頻ADC芯片(立體聲音頻DAC和DirectDrive耳機放大器)輸出模擬聲音。

3.WMA 編碼格式

3.1.WMA概述

WMA(Windows Media Audio),它是微軟公司推出的與MP3格式齊名的一種新的音頻格式。由于WMA在壓縮比和音質方面都超過了MP3,更是遠勝于RA(Real Audio),即使在較低的采樣頻率下也能產生較好的音質。一般使用Windows Media Audio編碼格式的文件以WMA作為擴展名,一些使用Windows Media Audio編碼格式編碼其所有內容的純音頻ASF文件也使用WMA作為擴展名。
  WMA格式是以減少數據流量但保持音質的方法來達到更高的壓縮率目的,其壓縮率一般可以達到1:18,生成的文件大小只有相應MP3文件的一半。
  所需頻寬:320~112kbps(壓縮10~12倍)
  特性:當Bitrate小于128K時,WMA幾乎在同級別的所有有損編碼格式中表現得最出色,但似乎128k是WMA一個檻,當Bitrate再往上提升時,不會有太多的音質改變。
  優點:當Bitrate小于128K時,WMA最為出色且編碼后得到的音頻文件很小。
  缺點:當Bitrate大于128K時,WMA音質損失過大。WMA標準不開放,由微軟掌握。
  應用領域:voip

3.2.WMA音頻格式解析

WMA是微軟定義的一種媒體文件格式,它是一種流媒體。由于WMA協議是不公開的,所以我們就只能通過大量的文件來做分析,簡單的分析網上一般都可以找到,下邊我就引用別人的一些:


               WMA 文件結構示意圖

如圖1,每一個WMA文件,它的頭16個字節是固定的,為十六進制的“30 26 B2 75 8E 66 CF 11 A6 D9 00 AA 00 62 CE 6C”,用來標識這個是否為WMA文件。接下來的8個字節為一個整數(高位存在后面),表示整個WMA文件頭部的大小,這個頭部里面包含了Tag信息等所有非音頻信息,頭部后面的是音頻信息,我們在這里就不深入了解了。那個整數接下來的6個字節還沒搞清楚是什么用的,不過不影響我們對Tag信息的讀寫。
  也就是說從文件開始偏移量為31開始,里面存放了很多幀,有我們需要的標準Tag信息,擴展Tag信息,WMA文件控制信息等等。每個幀不是等長的,但是幀頭是固定的24個字節,其中前16字節是用來標識這個幀的名字,后8個字節是用來表示這個幀(包括幀頭)的大小。這一點和MP3文件的ID3V2信息比較像。
  由于我們只需要讀寫Tag信息,而Tag信息又分別保存在兩個幀里,分別為標準Tag幀和擴展Tag幀,所以我們只需要處理這兩個幀,其他幀完全可以根據獲得的幀長度來跳過。
  如圖2,標準Tag幀只包含歌曲標題,藝術家,版權,備注四個內容。它的幀名是十六進制的“33 26 B2 75 8E 66 CF 11 A6 D9 00 AA 00 62 CE 6C”,在24個字節的幀頭后緊跟著5個分別為2個字節的整數,前四個分別表示歌曲標題,藝術家,版權,備注的大小,第五個還不清楚有什么用的,大部分情況下是不使用的,即它的大小為0。在這10個字節后,這五個信息的內容就按順序存放了。記住,在WMA文件里,所有的文字都是按Unicode寬字符的編碼方式儲存的,而且每個字符串后面都有一個0結束字符的。
  如圖3,再看擴展Tag幀,這里就比較麻煩了,里面包含的信息的個數是不確定的,每個信息也是按照像幀一樣的方式組織起來的。擴展Tag幀的幀名是十六進制的“40 A4 D0 D2 07 E3 D2 11 97 F0 00 A0 C9 5E A8 50”,在24字節的幀頭(HeadFlag:16,HeadSize:8)后先有一個兩個字節的整數表示這個幀里一共有的擴展信息個數(ExNo)。緊接著是擴展信息。
  如圖4,每一個擴展信息包含擴展信息名字和對應的值。先有一個2個字節的整數來表示擴展信息名字的大小,接著是擴展信息名稱,然后有一個2個字節的整數標志(Flag),這個后面再講。然后又是一個2個字節的整數,表示值的大小,接著就是這個值。
  當擴展信息名字為WMFSDKVersion時,這個值表示的是這個WMA文件的版本;當擴展信息名字為WM/AlbumTitle時,這個值代表的就是專輯名;當擴展信息名字為WM/Genre時,這個值代表的就是流派;同理,很容易從擴展信息的名字看出這個值的用途的。這些擴展信息的名字和值幾乎都是用Unicode的字符串來存儲的,到現在為止只發現對下面兩個情況例外。(關于所有擴展信息的名字可以從很多地方查到,比如SDK幫助,MSDN)
  下面再來看看那個標志Flag,這個基本上是沒什么用的(通常值為0),只對WM/TrackNumber和WM/Track這兩個擴展信息名字有用,當Flag為3的時候后面的值(也就是曲目信息)是以4個字節的整數的形式表示,當Flag為0的時候,曲目信息是以普通的字符串形式表示的。

4.WAV編碼格式

4.1.WAV概述

WAV為微軟公司(Microsoft)開發的一種聲音文件格式,它符合RIFF文件規范,用于保存Windows平臺的音頻信息資源,被Windows平臺及其應用程序所廣泛支持,該格式也支持MSADPCM,CCITTALAW等多種壓縮運算法,支持多種音頻數字,取樣頻率和聲道,標準格式化的WAV文件和CD格式一樣,也是44.1K的取樣頻率,16位量化數字,因此在聲音文件質量和CD相差無幾。WAV打開工具是WINDOWS的媒體播放器。
  通常使用三個參數來表示聲音:量化位數、取樣頻率和采樣點振幅。量化位數分為8位、16位、24位三種,聲道有單聲道和立體聲之分,取樣頻率一般有11025Hz(11kHz)、22050Hz(22kHz)和44100Hz(44kHz)三種,不過盡管音質出色,但在壓縮后的文件體積過大!相對其他音頻格式而言是一個缺點,其文件大小的計算方式為:WAV格式文件所占容量(B) = (取樣頻率 *量化位數* 聲道) * 時間 / 8 (1字節= 8bit) 每一分鐘WAV格式的音頻文件的大小為10MB,其大小不隨音量大小及清晰度的變化而變化。
  WAV是最接近無損的音樂格式,所以文件大小相對也比較大。

4.2.WAV特點

WAV音頻格式的優點包括:簡單的編/解碼(幾乎直接存儲來自模/數轉換器(ADC)的信號)、普遍的認同/支持以及無損耗存儲。WAV格式的主要缺點是需要音頻存儲空間。對于小的存儲限制或小帶寬應用而言,這可能是一個重要的問題。WAV格式的另外一個潛在缺陷是在32位WAV文件中的2G限制,這種限制已在為SoundForge開發的W64格式中得到了改善。
  常見的WAV文件使用PCM無壓縮編碼,這使WAV文件的質量極高,體積也出奇大,對于PCM WAV,恐怕也只有無損壓縮的音頻才能和其有相同的質量,平時我們見的什么mp3,wma(不含wmalossless)和wav的質量都是差很遠的!這點可以通過頻譜看出,即使320kbps的mp3和wav一比,也要自卑了!

4.3.剖析WAV

WAVE是錄音時用的標準的WINDOWS文件格式,文件的擴展名為“WAV”,數據本身的格式為PCM或壓縮型,屬于無損音樂格式的一種。
  符合RIFF(Resource Interchange File Format資源互換文件格式)規范,RIFF文件是windows環境下大部分多媒體文件遵循的一種文件結構,RIFF文件所包含的數據類型由該文件的擴展名來標識,能以RIFF文件存儲的數據包括:音頻視頻交錯格式數據(.AVI)、波形格式數據(.WAV)、位圖格式數據(.RDI)、MIDI格式數據(.RMI)、調色板格式(.PAL)、多媒體電影(.RMN)、動畫光標(.ANI)及其它RIFF文件(.BND)。每個WAV文件的頭四個字節便是“RIFF”。
  WAV文件由文件頭和數據體兩大部分組成。其中文件頭又分為RIFF/WAV文件標識段和聲音數據格式說明段兩部分。WAV文件各部分內容及格式見下表。常見的聲音文件主要有兩種,分別對應于單聲道(11.025KHz采樣率、8Bit的采樣值)和雙聲道(44.1KHz采樣率、16Bit的采樣值)。采樣率是指:聲音信號在“模→數”轉換過程中單位時間內采樣的次數。采樣值是指每一次采樣周期內聲音模擬信號的積分值。對于單聲道聲音文件,采樣數據為八位的短整數(short int 00H-FFH);而對于雙聲道立體聲聲音文件,每次采樣數據為一個16位的整數(int),高八位和低八位分別代表左右兩個聲道。WAV文件數據塊包含以脈沖編碼調制(PCM)格式表示的樣本。WAV文件是由樣本組織而成的。在單聲道WAV文件中,聲道0代表左聲道,聲道1代表右聲道。在多聲道WAV文件中,樣本是交替出現的。WAV對音頻流的編碼沒有硬性規定,除了PCM之外,還有幾乎所有支持ACM規范的編碼都可以為WAV的音頻流進行編碼。數據塊的記錄方式是little-endian字節順序,標志符并不是字符串而是單獨的符號。


            圖4-1 WAV音頻文件格式

  • 文件頭
  • RIFF/WAV文件標識段
  • 聲音數據格式說明段
  • 數據體:由PCM(脈沖編碼調制)格式表示的樣本組成。

WAVE文件是由若干個Chunk組成的。按照在文件中的出現位置包括:
  RIFF WAVE Chunk, Format Chunk, Fact Chunk(可選), Data Chunk。具體見下表(圖4-1無Fact Chunk):

表4-1 WAV文件的組成

偏移地址大小字節數據塊類型內容
00H~03H4char資源交換文件標志(RIFF)
04H~07H4long從下個地址開始到文件尾的總字節數(little-endian 32-bit 正整數,整個檔案的大小,扣掉辨識字符和長度,共8個字節。)
08H~0BH4charWAV文件標志(WAVE)
0CH~0FH4char波形格式標志(fmt),最后一位空格。
10H~13H4不定過濾字節(一般為00000010H),若為00000012H則說明數據頭攜帶附加信息(見“附加信息”)。
14H~15H2int格式種類(值為1時表示數據為線性PCM編碼,大于1時表示有壓縮的編碼)
16H~17H2int通道數,單聲道為1,雙聲道為2
18H~1BH4long采樣頻率
1CH~1FH4long波形數據傳輸速率(每秒平均字節數):Byte率=采樣頻率*音頻通道數*每次采樣得到的樣本位數/8
20H~21H2intDATA數據塊長度,字節。塊對齊=通道數*nSamplesPerBlock*每次采樣得到的樣本位數/8
22H~23H2intPCM位寬,即樣本數據位數
隨后2字節2int附加信息(可選,由上方過濾字節確定)
隨后不定長度字符“fact”,該部分是可選部分,一般當WAV文件是由某些軟件轉換而來時,包含該部分。若包含該部分:(1)該部分的前4字節為數據頭,一般為4個字母。(2)隨后4個字節表示長度,即除去頭(4字節)和長度(4字節)之后,數據本身的長度。(3)最后的字節為數據本身。例如:“66 61 73 74 04 00 00 00F8 2F 14 00” 。“66 61 73 74”是fact字段的數據頭,“04 00 00 00”是數據本身的長度,“F8 2F 14 00”是數據本身。(注意是little-endian字節順序)
隨后4字節4char數據標志符(data)
隨后4字節4intDATA總數據長度 字節
隨后不定DATA數據塊

WAV文件作為最經典的Windows多媒體音頻格式,應用非常廣泛,它使用三個參數來表示聲音:采樣位數、采樣頻率和聲道數。
舉例:我們使用UE打開這個音頻文件

注意,我們的PC都是小端模式,所以注意讀取數據的真實內容。
我們解讀一下這個wav文件
  00H ~ 03H 52 49 46 46 對應的是RIFF
  04H ~ 07H 48 10 03 00 對應的是后面文件的大小,小端模式所以是00031048 ,換算為十進制的200776
  08H ~ 0BH 57 41 56 45 對應的是標示符WAVE
  0CH ~ 0FH 66 6d 74 20 對應是波形格式標示符fmt
  10H ~ 13H 12 00 00 00 對應的是過濾字節,不知道是什么作用,由于本文件不是標準的采樣率,所以可能和上面的不一致
  14H ~ 15H 01 00 對應的十進制是1 線性的PCM編碼,我們這里只探討PCM編碼
  16H ~ 17H 01 00 對應的十進制是1 表示單聲道,MONO
  18H ~ 1BH 80 3E 00 00 對應的十進制是16000.表示采樣率是16000的
  1CH ~ 1FH 00 7D 00 00 對應的十進制是32000,波形數據傳輸率,每秒多少個字節,可以用(200776 -72)/32000 = 6.272s
  20H ~ 21H 02 00 對應的十進制是2,數據的調整數
  22H ~ 23H 10 00 對應的十進制是16,樣本數據的位數,表示用16位表示一個樣本

我們的和表4-1之間有一些差距,是ffmpeg轉碼的數據,所以中間夾著了一些ffmpeg的信息
  48H ~ 4BH 64 61 74 71 對應的ACSCII碼是data
  4CH ~ 4FH 00 10 03 00 對應的十進制是200704,表示采樣數據的總數
  從50H開始就是真正的數據部分

在使用ffmpeg解包的時候總共是有49個包,每個包的大小為4096, 49*4096 =200704,
  怎么計算出來包的大小,需要進一步的分析。

對于Data塊,根據聲道數和采樣率的不同情況,布局如下(每列代表8bits):

采樣率和聲道數采樣1采樣2
8 Bit 單聲道數據1數據2
8 Bit 雙聲道聲道1數據1聲道2數據1聲道1數據2聲道2數據2
16 Bit 單聲道數據1低字節數據1高字節數據2低字節數據2高字節
16 Bit 雙聲道聲道1數據1低字節聲道1數據1高字節聲道2數據1低字節聲道2數據1高字節聲道1數據2低字節聲道1數據2高字節聲道2數據2低字節聲道2數據2高字節

PCM數據的存放方式:
  WAV文件的每個樣本值包含在一個整數i中,i的長度為容納指定樣本長度所需的最小字節數。首先存儲低有效字節,表示樣本幅度的位放在i的高有效位上,剩下的位置為0,這樣8位和16位的PCM波形樣本的數據格式如下所示。

樣本大小數據格式最大值最小值
8位PCMUnsigned int2250
16位PCMint32767-32767

下面我們看一個具體的例子,wav音頻文件如下:(十六進制的形式)

對應的分析如下圖所示:

補充:RIFF概念
  在Windows環境下,大部分的多媒體文件都依循著一種結構來存放信息,這種結構稱為“資源互換文件格式”(Resources lnterchange File Format),簡稱RIFF。例如聲音的WAV文件、視頻的AVI文件等等均是由此結構衍生出來的。RIFF可以看做是一種樹狀結構,其基本構成單位為chunk,猶如樹狀結構中的節點,每個chunk由“辨別碼”、“數據大小”及“數據”所組成。

塊的標志符(4BYTES)
數據大小 (4BYTES)
數據

圖一、 塊的結構示意圖

辨別碼由4個ASCII碼所構成,數據大小則標示出緊跟其后數據的長度(單位為Byte),而數據大小本身也用掉4個Byte,所以事實上一個chunk的長度為數據大小加8。一般而言,chunk本身并不允許內部再包含chunk,但有兩種例外,分別為以“RIFF”及“LIST”為辨別碼的chunk。而針對此兩種chunk,RIFF又從原先的“數據”中切出4個Byte。 此4個Byte稱為“格式辨別碼”,然而RIFF又規定文件中僅能有一個以“RIFF”為辨別碼的chunk。

RIFF/LIST標志符(4BYTES)
數據1大小 (4BYTES)
數據1格式/列表類型
數據

圖二、RIFF/LIST塊結構

只要依循此一結構的文件,我們均稱之為RIFF檔。此種結構提供了一種系統化的分類。如果和MS-DOS文件系統作比較,“RIFF”chunk就好比是一臺硬盤的根目錄,其格式辨別碼便是此硬盤的邏輯代碼(C:或D:),而“LIST”chunk即為其下的子目錄,其他的chunk則為一般的文件。至于在RIFF文件的處理方面,微軟提供了相關的函數。視窗下的各種多媒體文件格式就如同在磁盤機下規定僅能放怎樣的目錄,而在該目錄下僅能放何種數據。

5.ALAC編碼格式

ALAC(Apple Lossless Audio Codec)蘋果的無損音頻壓縮編碼格式,ALAC與MP3的主要分別在于編碼過程中,MP3會取消小部分高頻及低頻部分的音頻數據,而ALAC則會如實記錄,不會刪除音頻中任何細節數據。由于資料無損,ALAC音頻文件大小會比MP3大,通常每片音樂CD(約70至80分鐘)經ALAC編碼后,音頻文件大小約300MB。
  常見ALAC編碼音頻文件同AAC編碼音頻均采用m4a容器封裝,需注意查看編碼信息可區分它們。

6.AC-3編碼格式

6.1.AC-3概述

AC-3(Digital Audio Compression Standard)音頻編碼格式,傳說中的杜比實驗室的杰作,著名的有損數據壓縮的多媒體儲存格式。可以包括多達6個獨立的聲道。最知名的是5.1聲道技術。在5.1聲道技術中,5代表著5個基本聲道,獨立連接至五個不同的喇叭(20至20,000 Hz),分別是右前(RF),中(C),左前(LF),右后(RR),左后(LR);而1則代表1個低頻聲效,連接至低音輔助喇叭(20至120 Hz)每個AC-3 的音頻幀都是以0x0B77為同步頭。開源解碼庫liba52。
  AC-3是一種靈活的音頻數據壓縮技術,它具有將多種聲軌格式編碼為一種低碼率比特流的能力。支持8種不同的聲道配置方式,從傳統的單聲道、立體聲到擁有6個分離聲道的環繞聲格式(左聲道、中置聲道、右聲道、左環繞聲道、右環繞聲道及低音效果聲道)。AC-3的比特流所允許的采樣頻率可以為48 kHz、44.1 kHz、或32 kHz中的任何一種,并且所支持的碼率從32 kbps(千比特位/秒)到640 kbps不等。

6.2.AC-3比特流的特征

AC-3的比特流是由幀(Frame)構成的(詳見圖6-1),在恒定的時間間隔內,其所有編碼的聲道所包含的信息就能體現在1536個PCM采樣值的信息。每一個AC-3的幀(Frame)都具有固定的尺寸,只由采樣頻率及編碼數據率決定。同時,每個幀(Frame)都是獨立的實體而且并不與前一個幀(Frame)分享數據,除了在MDCT所固有的去交迭變換。

SYNCCRC#1SIBSIAUDIO BLOCK 0AUDIO BLOCK 1AUDIO BLOCK 2AUDIO BLOCK 3AUDIO BLOCK 4AUDIO BLOCK 5AUX DATACRC#2

圖6-1 AC-3幀結構

Block Switch FlagsDither FlagsDynamic Range ControlCoupling StrategyCoupling CoordinatesExponent StrategyExponentsBit Allocation ParametersMantissas

圖6-2 AC-3聲音塊結構

在每個AC-3幀(Frame)的開頭是SI域(同步信息Sync Information)及BSI域(比特流信息)。SI域及BSI域描述了比特流的結構,包括采樣頻率、數據碼率、編碼聲道的數目及其他一些系統描述的元素。每個幀用兩個CRC(循環冗余碼校驗字)字來提供偵錯手段,一個位于幀的起始處,另一個位于幀的結尾。每個幀有6個聲音塊,每個塊表示為每個編碼聲道包含256個PCM取樣(sample)(詳見圖6-2)。聲音塊中所含內容包括塊轉換標志,耦合坐標、指數、位分配參數、尾數。允許在幀的內部進行數據分享,比如在聲音塊0中的數據可以被同一幀內的后續塊所使用。在每個幀的結尾處有一個可選的輔助數據域,在這個區域內允許系統設計者在AC-3比特流中嵌入可在整個系統內傳遞的、自有的控制字及狀態字信息。AC-3的編/解碼器被設計成一個完整的音頻子系統的解決方案,它擁有普通的低碼率編/解碼所沒有的許多特性。這些特性包括適用于消費類音頻回放系統的動態范圍壓縮特性(Dynamic Range Compression)、對話歸一(Dialog Normalization)以及縮混特性(Downmixing),縮混特性可以將多聲道音頻進行轉換為特定數目的聲道輸出。動態范圍控制(Dynamic Range Control)的控制字是嵌入在AC-3比特流內,并被解碼器應用,可以使同一個比特流源在不同模式下進行還音。

7.APE編碼格式

7.1.APE簡單介紹

APE是Monkey’s Audio提供的一種無損壓縮音頻格式。與mp3、ogg有損壓縮方式不同,龐大的WAV音頻文件通過Monkey’s Audio軟件進行“瘦身”壓縮,壓縮比大約為2:1(為源文件的60%左右)。由于采用特殊算法,保證音質不受損失,通過解壓縮可以得到與源文件一致的品質,即通過Monkey’還原成WAV,還可把APE音頻格式刻錄成CD保存。而還原后的音樂文件與壓縮前一模一樣,沒有任何音質損失,因此可以用它來保存、復制CD。因為被壓縮后的APE文件容量要比WAV源文件小一半多,如用于網絡音頻文件傳輸,可以節約傳輸所用的時間且能保持音質。其特點如下所示:
  (1)Monkey’s Audio是高優化和高效率的;
  (2)無損壓縮,沒有質量損失;
  (3)可以被大多數的流行players和rippers支持,如Media Center、Foobar、WMP、Winamp等;
  (4)完全免費和開源。

7.2.APE文件結構

7.2.1.Header句法結構

Header的內容包括:文件的屬性、sound的參數(如聲道數、采樣率等)、內部結構(如幀數、Seek Table,甚至可能包括WAV的header)。Header的句法結構如下圖所示:



7.2.2.Header句法元素含義

(1)tag:此元素的值為四個字符“MAC”,是APE文件的標志。可以通過該標志來判斷一個媒體文件是否為APE文件。
(2)compression_level:壓縮等級,對應的等級如下所示:

(3)format_flags:APE文件標記,標記了APE文件以及APE編碼格式的一些屬性,如sample的位數、是否含有CRC校驗、是否含有WAVE Header等等。ffmpeg對format_flags值的定義如下所示,這也是在句法結構圖中的那些數字的含義。

#define MAC_FORMAT_FLAG_8_BIT 1 // is 8-bit [OBSOLETE] #define MAC_FORMAT_FLAG_CRC 2 // uses the new CRC32 error detection [OBSOLETE] #define MAC_FORMAT_FLAG_HAS_PEAK_LEVEL 4 // uint32 nPeakLevel after the header [OBSOLETE] #define MAC_FORMAT_FLAG_24_BIT 8 // is 24-bit [OBSOLETE] #define MAC_FORMAT_FLAG_HAS_SEEK_ELEMENTS 16 // has the number of seek elements after the peak level #define MAC_FORMAT_FLAG_CREATE_WAV_HEADER 32 // create the wave header on decompression (not stored)

(4)seek_table_length:標識了seek_table的長度。在file_version大于等于3980的版本中,seek_table_length是seek_table所占用的字節數;而在file_version小于3980的版本中,seek_table_length是seek_table包含的數組元素個數,與seek_table包含字節數為四倍的關系。
(5)seek_table:seek_table中存放的是每個frame在APE文件中的position。但是,在真正去讀取frame的時候,需要考慮四字節對齊的問題。
(6)total_frames:包含frame的個數。
(7)blocks_per_frame:標識每個frame包含的block的個數,這只對前total _frames - 1的frame有效。對于最后一個frame,它所包含的block的個數由句法元素final_frame_blocks的值來指定。
(8)final_frame_blocks:最后一個frame包含的block的個數。

7.2.3.APE Tag結構

APE tag用來存放metadata數據,比如歌名、演唱者、專輯名等等,這些信息就稱為tag(標簽)信息。APE tag有兩個版本,即APEV1與APEV2。APEV1一般放在文件的末尾,而APEV2具有與ID3v2一樣的靈活性和可括展性,字段名可自定義,字段長度可擴展,同時格式定義又不像ID3v2那么繁瑣。APEV2的格式很簡單,實現起來也很方便,tag存放位置是可選的,既可以在文件頭也可以在文件尾。APEV1與APEV2的區別主要有兩個方面:
  (a)APEV1使用的是ACSII編碼,而APEV2使用的是UTF-8編碼,使得可以實現unicode支持。
  (b)APEV2標準里增加了一個APE Tags Header,APEV1里面沒有。
APEV1與APEV2的結構分別如下圖所示:

(1)APE Tags Header
  APE Tags Header只在APEV2中才有,其內容包括整個tag的長度、item的個數等。最開始是固定的8個字符“APETAGEX”,用來標識tag header的開始。APE Tags Header與APE Tags Footer的結構相似,唯一的不同就是Tags Flag中的一個bit,這也是用于區分APE Tags Header與APE Tags Footer的一個標記。APE Tags Header的結構如下所示:

Preamble64 bits{‘A’, ‘P’, ‘E’, ‘T’, ‘A’, ‘G’, ‘E’, ‘X’}
Version Number, Bits 0...7 Version Number, Bits 8...15 Version Number, Bits 16...23 Version Number, Bits 24...3132 bits1000 = Version 1.000 (old) 2000 = Version 2.000 (new)
Tag Size, Bits 0...7 Tag Size, Bits 8...15 Tag Size, Bits 16...23 Tag Size, Bits 24...3132 bitsTag size in bytes including footer and all tag items excluding the header to be as compatible as possible with APE Tags 1.000
Item Count, Bits 0...7 Item Count, Bits 8...15 Item Count, Bits 16...23 Item Count, Bits 24...3132 bitsNumber of items in the Tag (n)
Tags Flags, Bits 0...7 Tags Flags, Bits 8...15 Tags Flags, Bits 16...23 Tags Flags, Bits 24...3132 bitsGlobal flags of all items (there are also private flags for every item)
Reserved64 bitsMust be zero

(2)APE Tag Item
  APE Tag Item存在于APEV1和APEV2中,其結構如下所示:

Size of the Item Value, Bits 0...7 Size of the Item Value, Bits 8...15 Size of the Item Value, Bits 16...23 Size of the Item Value, Bits 24...3132 bitsLength len of the assigned value in bytes
Tags Flags, Bits 0...7 Tags Flags, Bits 8...15 Tags Flags, Bits 16...23 Tags Flags, Bits 24...3132 bitsItem flags
Item Keym bytesItem key, can contain ASCII characters from 0x20 (Space) up to 0x7E (Tilde)
0x001 byteItem key terminator
Item Valuelen bytesItem value, can be binary data or UTF-8 string

(3)APE Tags Footer
  APE Tags Footer與APE Tags Header的結構相似,但它可以存在于APEV1和APEV2中。唯一的不同就是Tags Flag中的一個bit位,這也是用于區分APE Tags Header與APE Tags Footer的一個標記。最開始是固定的8個字符“APETAGEX”,用來標識tag footer的開始。APE Tags Footer的結構如下所示:

Preamble64 bits{‘A’, ‘P’, ‘E’, ‘T’, ‘A’, ‘G’, ‘E’, ‘X’}
Version Number, Bits 0...7 Version Number, Bits 8...15 Version Number, Bits 16...23 Version Number, Bits 24...3132 bits1000 = Version 1.000 (old) 2000 = Version 2.000 (new)
Tag Size, Bits 0...7 Tag Size, Bits 8...15 Tag Size, Bits 16...23 Tag Size, Bits 24...3132 bitsTag size in bytes including footer and all tag items excluding the header to be as compatible as possible with APE Tags 1.000
Item Count, Bits 0...7 Item Count, Bits 8...15 Item Count, Bits 16...23 Item Count, Bits 24...3132 bitsNumber of items in the Tag (n)
Tags Flags, Bits 0...7 Tags Flags, Bits 8...15 Tags Flags, Bits 16...23 Tags Flags, Bits 24...3132 bitsGlobal flags of all items (there are also private flags for every item)
Reserved64 bitsMust be zero

(4)一個簡單的示例
  上面的幾個圖來自wiki,可能有點抽象。我們以一個簡單的示例來說明一下,這樣比較直觀。如下圖所示,圖為在Linux平臺用ghex打開的一個APE文件。

從圖中可以看出,該tag為APEV2 tag。
a、APE Tags Header
  首先是APE Tags Header,從圖中可以很容易的找到,以“APTTAGEX”開始,然后是4個字節的version,0x00 00 07 D0,即version為2000。
  然后是四個字節的tag size,為0x00 00 00 72,即整個APE tag包括114個字節,其中不包括APE Tags Header的長度。可以從圖中數一下,確實是114個字節。
  在然后的四個字節是item的個數,0x00 00 00 03,即包括三個item。
  緊接著是4個字節的flags,為0xA0 00 00 00。
  最后是reserved的8個字節,全部為0。
b、APE Tag Item
  由對APE Tags Header的分析可以知道,該tag中包括了三個item,從圖中也可以看的出來,分別為Title、Artist和Album。我們可以以Title這個item為例進行分析。APE Tags Header為固定的32個字節,因此,跳過32個字節之后便是Title這個item的內容。
  首先是四個字節的length,0x00 00 00 0C,即為12個字節。這個12表示該item的value占12個字節。
  然后是四個字節的flags,這里為0x00 00 00 00。
  接著是item的key,這里為Title,是ASCII編碼。item的key后面是一個字節的標志位,為0x00,用于標識item的key結束。
  最后是item的value,由上面的分析可以知道為12個字節。
c、APE Tags Footer
  APE Tags Footer的結構和APE Tags Header的結構是一樣的,而且內容幾乎一樣,唯一的區別就在于flag。APE Tags Header的flag為0xA0 00 00 00,而APE Tags Footer的flag為0x80 00 00 00。查看了幾個APE文件,APE Tags Header的flag都為0xA0 00 00 00,而APE Tags Footer的flag都為0x80 00 00 00,這兩個flag的值可能是固定的值(個人猜測),以此來區分APE Tags Footer與APE Tags Header。

8.FLAC編碼格式

8.1.FLAC概述

FLAC(Free Lossless Audio Codec)中文可解釋為無損音頻壓縮編碼。FLAC是一套著名的自由音頻壓縮編碼,其特點是無損壓縮。不同于其他有損壓縮編碼如MP3 及AAC,它不會破壞任何原有的音頻資訊,所以可以還原音樂光盤音質。2012年以來它已被很多軟件及硬件音頻產品(如CD等)所支持。
  解析區別: FLAC與MP3不同,MP3是有損音頻壓縮編碼,但FLAC是無損壓縮,也就是說音頻以FLAC編碼壓縮后不會丟失任何信息,將FLAC文件還原為WAV文件后,與壓縮前的WAV文件內容相同。這種壓縮與ZIP的方式類似,但FLAC的壓縮比率大于ZIP和RAR,因為FLAC是專門針對PCM音頻的特點設計的壓縮方式。而且可以使用播放器直接播放FLAC壓縮的文件,就像通常播放你的MP3文件一樣(近幾年已經有許多汽車播放器和家用音響設備支持FLAC,在FLAC的網站上你可以找到這些設備廠家的鏈接)。

8.2.FLAC編碼過程及相關定義

8.2.1.FLAC編碼過程

Flac把未壓縮的音頻流劃分為塊(block),并獨立壓縮,壓縮后的數據塊形成數據幀(frame),把數據幀連接形成壓縮后的flac數據流(stream)。
  分塊(blocking): flac分塊大小是可變的。分塊大小應適當選擇,太小影響壓縮率(太多幀頭信息),太大難以得到高效的壓縮模型。一般44.1k線性采樣,分塊大小2~6k較合適(默認4096)。
  聲道內解相關性: 立體聲的左右聲道數據之間有許多相關性,可以利用這種相關性壓縮數據。Flac有四種方式表示聲道數據。

  • 獨立模式:左右聲道獨立編碼;
  • Mid-side模式:轉換表達式:mid = (left + right) / 2, side = left - right.。
  • Left-side:Left不變,s
  • Right-side:Right不變

建模(modeling): 編碼器嘗試使用一個數學方法(近似)描述原始信號,這種描述信息一般來說比原始信息小得多,這些數學方法是編碼器和解碼器都已知的(flac現在有4個種類的預測方法,并可以加入更多方法)flac運行在各個塊中使用不同的預測算法。大多時候不能完全精確的描述原始信息,此時還會剩下少量數據殘渣(residual, residue, or error)。Flac有兩種產生近似值的方法:1)為信號找個合適的多項式。2)簡單線性預測(LPC)。前者更快但不精確。
  數據殘渣編碼: 對建模后剩余的數據進行編碼,保證數據的無損。目前flac只使用一種編碼方法。
  幀(framing): 一個音頻幀被一個幀頭(frame header)和幀腳(frame footer)包圍。幀頭以同步字開始,包含了解碼這幀的最小信息如采樣率,采樣位數等,同時包含了這幀里的分塊數或采樣數及一個8位CRC校驗碼。幀頭可以用來進行再同步。幀尾包含一個16位CRC校驗碼。如果解碼器檢測到CRC錯誤將產生一個silent block。

8.2.2.定義

(block、subblock 指沒有被編碼的原始數據;frame、subframe指編碼后的數據)

  • Block:一組或多組跨所有聲道的采樣點(flac采樣組數范圍16~65535)。
  • Subblock:一個或多個單聲道的采樣點,一個Block包含幾個聲道就有幾個subblock,同個block內subblock的采樣點數相同。
  • Blocksize:一個block中任意subblock的采樣點個數(與聲道數無關)。
  • Frame:一個frame幀頭加一個或多個Subframe
  • Subframe:一個subframe幀頭加某一聲道上一個或多個編碼后的采樣點,一個frame中的所有subframe包含的采樣點數一樣。

(每次一個subblock被編碼成一個subframe,多個subframe組成一個frame)

8.3.FLAC格式解析

8.3.1.FLAC文件結構

表8-1 FLAC文件結構

Field NameLength(bit)Description
文件標記“fLaC”32“fLaC”標志,用于識別flac數據流 0x66 0x41 0x61 0x43
METADATA BLOCK34*8STREAMINFO,必選的metadata block,說明Stream的基本特性(采樣率、聲道數…)。
METADATA BLOCK一個或者多個metadata block,可選。(解碼時可以不用識別)
AUDIO FRAMES一個或者多個Audio Frame

8.3.2.FLAC格式

Flac中所有數值都是整形,大端模式,除非特別指出,否則數值都是unsigned的。
(1)概述
  Flac比特流以“flaC”開始,接著是必須的metadata塊(STREAMINFO),然后是其他可選的metadata塊,接著是音頻幀。
Flac最多可以支持到128類metadata,已經定義的包括下面幾種:
  A.STREAMINFO:包含整個比特流的一些信息,如采樣率、聲道數、采樣總數等。它一定是第一個metadata而且必須有。之后可以接其他metadata,這些metadata可以不用識別直接跳過。
  B.APPLICATION:包含第三方應用軟件信息,這個段里的32位識別碼是flac維護組織提供的,是唯一的。
  C.PADDING:沒有意義的東西,主要用來后期添加其他metadata。
  D.SEEKTABLE:保存快速定位點,一個點由18bytes組成(2k就可以精確到1%的定位),表里可以有任意多個定位點。
  E.VORBIS_COMMENT:存儲了一系列可讀的“名/值”的鍵值對,使用UTF-8編碼。這是flac唯一官方支持的標簽段。
  F.CUESHEET:存儲用在cue sheet中的各種信息。可以用來劃分音軌,在備份CD時十分有用。
  G.PICTURE:保存相關圖片,同時還有url、分辨率等信息,可以有不止一個picture block。
音頻數據由一個或多個音頻幀組成,每一幀包含一個幀頭:同步字,塊大小,采樣率,聲道數…然后是8bitCRC校驗碼;同時幀頭還包含本幀第一個采樣點的采樣序號(blocksize變長的文件)或本幀的序號(blocksize定長的文件),他們用于精確定位。接著是編碼后的subframes,每個subframe代表一個聲道。最后是一些有0填充的邊界。每個subframe有它自己的幀頭用于指出它是怎樣被編碼的。
  當從一個文件中間開始解碼時需要知道一個幀的起始點。可以通過一個14bit的同步字來判斷。但是它可能會出現在subframe里面,此時可以通過檢測剩余數據(沒有無效數據)和CRC8。同樣當從中間某幀開始解碼時,沒有讀取STREAMINFO,為了得到采樣率和聲道數等信息,需要再幀頭里加入相關信息,為了減少數據,使用了查表的方法來定義常用的采樣率。
(2)格式





9.AMR編碼格式

9.1.AMR概述

AMR(Adaptive Multi-Rate)自適應多速率音頻壓縮音頻編碼格式,是一個使語音編碼最優化的專利,專用于有效地壓縮語音頻率。
  AMR音頻主要用于移動設備的音頻壓縮,壓縮比非常高,但是音質比較差,主要用于語音類的音頻壓縮,不適合對音質要求較高的音樂類音頻的壓縮。AMR被標準語音編碼 3GPP在1998年10月選用,現在廣泛在GSM和UMTS中使用。它使用1-8個不同的位速編碼。之前的手機里有很多amr的音頻文件,可分成:

  • AMR-NB(AMR-NarrowBind),語音帶寬范圍:300-3700Hz,8KHz采樣頻率,每20ms編碼一幀,每個幀中包含160個語音樣點;
  • AMR-WB(Adaptive Multi-Rate - Wideband Speech Codec),語音帶寬范圍50-7000Hz,16KHz采樣頻率。但考慮語音的短時相關性,每幀長度均為20ms;
  • AMR-WB+(Extended Adaptive Multi-Rate - Wideband Speech Codec):amr-nb和amr-wb都屬于speech codec,對audio的編碼效果并不好,為了提高對audio的編碼效果,出現了amr-wb+。amr-wb+可以支持更高的采樣率,對speech和audio采用不同的編碼算法,對speech采用ACELP編碼,對audio采用變換編碼。amr-wb+在低比特率上對audio的編碼效果與he aac+相當。amr-wb+包含amr-wb,但復雜度更高。

9.2.AMR編碼方式

(1)AMR-NB一共有16種編碼方式。0-7對應8種不同的編碼方式,每種編碼方式的采樣頻率不同;8-15 用于噪音或者保留用。

說明:
  比特率是指將數字聲音由模擬格式轉化成數字格式的采樣率,采樣率越高,還原后的音質就越好。
  比特率值與現實音頻對照:

  • 16kbps=電話音質
  • 24kbps=增加電話音質,短波廣播,長波廣播,歐洲制式中波廣播
  • 40kbps=美國制式中波廣播
  • 56kbps=話音
  • 64kbps=增加話音(手機鈴聲最佳比特率設定值,手機單聲道MP3播放器最佳設定值)
  • 112kbps=FM調頻立體聲廣播
  • 128kbps=磁帶(手機立體聲MP3播放器最佳設定值,低檔MP3播放器最佳設定值)
  • 160kbps=HIFI高保真(中高檔MP3播放器最佳設定值)
  • 192kbps=CD(高檔MP3播放器最佳設定值)
  • 256kbps=Studio音樂工作室(音樂發燒友適用)

(2)AMR-WB全稱為“Adaptive Multi-rate–Wideband”,即“自適應多速率寬帶編碼”,采樣頻率為16kHz,是一種同時被國際標準化組織ITU-T和3GPP采用的寬帶語音編碼標準,也稱為G722.2標準。
  AMR-WB支持9種不同的編碼方式:6.6kb/s、8.85kb/s、12.65kb/s、14.25kb/s、15.85kb/s、18.25kb/s、19.85kb/s、23.05kb/s、23.85kb,提供的語音帶寬范圍達到50~7000Hz,人聲感覺比以前更加自然、舒適和易于分辨。

9.3.AMR文件結構解析

下面我們來看一個實際的AMR文件(http://download.csdn.net/detail/ce123/6701049):

從圖中可以看出,所有AMR文件頭標志是6個字節(最后一個字節是換行符"/n")。幀頭為0x2C,后面就緊跟的是音頻幀。這個文件是每幀21字節。

文件頭
語音幀1
語音幀2
...

文件頭:
  單聲道和多聲道情況下文件的頭部是不一致的,單聲道情況下的文件頭只包括一個Magic number,而多聲道情況下文件頭既包含Magic number,在其之后還包含一個32位的Chanel description field。多聲道情況下的32位通道描述字符,前28位都是保留字符,必須設置成0,最后4位說明使用的聲道個數。
語音數據:
  文件頭之后就是時間上連續的語音幀塊了,每個幀塊包含若干個8位組對齊的語音幀,相對于若干個聲道,從第一個聲道開始依次排列。每一個語音幀都是從一個8位的幀頭開始,其中P為填充位必須設為0,每個幀都是8位組對齊的。
  對于不同的編碼模式,它的音頻幀的大小是不同的,比特率也是不同的;如下圖所示:

音頻數據幀大小的計算:amr一幀對應20ms,那么一秒有50幀的音頻數據。由于比特率不同,每幀的數據大小也不同。如果比特率是12.2kbs,那么每秒采樣的音頻數據位數為:12200 / 50 = 244bit = 30.5byte,取整為31字節。取整要四舍五入,再加上一個字節的幀頭,這樣數據幀的大小為32字節。

9.4.AMR幀格式解析

AMR語音幀格式為幀頭和語音數據組成;并且分為兩種類型的幀格式:AMR IF1和 AMR IF2。

幀頭語音數據

具體如下:

(1)AMR IF1的幀格式如下圖:

a . AMR語音幀頭Header占1個字節,如下圖所示:

其中:
  P = 0;
  FT:Frame Type,對應不同編碼模式,占4bits。(參見“9.2. AMR編碼方式”表格中說明)
  Q:幀質量指示器,0表示為壞幀;占1bits;
  后面的2個P補0。
b. 幀頭后面就是輔助信息。此輔助信息針對自適應模式及差錯檢測。
c. 輔助信息后面就是語音數據。每一幀的數據有分為三個部分:Class A ,Class B ,Class C;

  • Class A:是一幀中最敏感、最重要的數據。這部分數據如有損壞,整個幀將無法解碼。所以,一般在無線傳輸的時候要使用各種冗余的方式對這部分數據加以保護。
  • Class B:相對而言,比Class A不重要的數據。
  • Class C:比Class B還不重要的數據。

(2)AMR IF2的幀格式如下圖所示:

相對于IF1格式,IF2省去了Frame Quality Indicator,Mode Indication,Mode Request和CRC校驗。但是增加了bit填充。因為AMR幀中數據的長度并不是字節(8bit)的整數倍,所以在有些幀的末尾需要增加bit填充,以使整個幀的長度達到字節的整數倍。

9.5.異常幀分析

下圖是一個出現異常幀的示例:(zbc1217.amr)

從上圖可以看見,本amr音頻幀頭都是0x3C,但是在0x000091e6處,幀頭字節為0x44。與0x3C不一致。而在0x00009243處,才恢復到0x3C。
  對異常幀的簡單處理辦法是,遇到異常幀就跳過異常幀。后面的讀幀算法有描述。

9.6.AMR幀讀取算法

因為可能存在異常幀,所以不一定所有的語音幀大小一致,對于跟正常幀大小不一致的,或者幀頭跟正常幀頭不一致的,就不交給解碼器,直接拋棄該壞幀。下面是算法描述流程圖:

9.7.AMR解碼流程

AMR Payload Decode原理分析如圖中Payload Parse模塊-----解碼出編碼語音數據;
  AMR Speech Decode原理分析如圖中Speech Decode模塊----解碼語音幀;
  AMR DTX decode原理分析如圖中DTX Decode模塊-----解碼噪音幀;
  AMR Post-Processing原理分析如圖中的Post-Processing模塊-----語音后處理;

9.8.AMR模式選擇的自適應機制

自適應的基本概念是以更加智能的方式解決信源和信道編碼的速率分配問題,使得無線資源的配置和利用更加靈活和高效。實際的語音編碼速率取決于信道的條件,它是信道質量的函數。而這部分的工作是解碼器根據噪聲等測量參數協助基站來完成,選擇模式,決定速率快慢。原則上在信道很差的時候采用速率比較低的編碼器,這樣就能分配給信道編碼更多的比特數來實現糾錯,實現更可靠的差錯控制,從而有效地抑制錯誤發生,提高話音質量。


          自適應過程實現框圖

10.ATRAC編碼格式

ATRAC(Adaptive Transform Acoustic Coding)是Sony 公司開發的一種相對老的音頻編碼格式,又細分成ATRAC1、ATRAC2、ATRAC3、ATRAC3plus,這些都是獨立的技術,后來Sony把這些技術統稱為ATRAC。在rmvb的封裝格式中也能看到這種音頻編碼格式。

11.DTS編碼格式

DTS(Digital Theater Systems)大名鼎鼎的DTS(數碼影院系統)是由DTS公司開發,一種多通道的音頻技術,低損,環繞立體聲,被廣泛的應用在DVD等高清片源上。同樣也需要授權,與杜比公司是競爭對手。最常見的是DTS 5.1:保存5條音頻通道的數據用于環繞立體聲,分別是center,left-front,right-front,left-rear,and right-rear。除此之外DTS公司還開發了DTS 70 mm、DTS 70 ES、DTS NEO:6、DTS 96/24、DTS-HD Master Audio、DTS-HD High Resolution Audio、DTS Connect、DTS Surround Sensation等技術。由于版權比較嚴格,而且文檔很難從網上找到。

12.OGG編碼格式

12.1.OGG概述

OGG是一個自由且開放標準的容器格式,由Xiph.Org 基金會所維護,“Ogg”意指一種文件格式,可以納入各式各樣自由和開放源代碼的編解碼器,包含音效、視頻、文字(像字幕)與元數據的處理。
  一般說到OGG,都是指Ogg_Vorbis,這就是咱們常見的.ogg結尾的音頻文件,Vorbis是一種有損音訊壓縮格式,由Xiph.Org基金會所領導并開放源代碼。Vorbis通常以Ogg作為容器格式,所以常合稱為Ogg Vorbis。其實,OGG不僅僅只能包含Vorbis格式,它可以包含視頻格式。因此,為了區分只包含音頻格式的文件格式,產生了一種新的文件格式OGV,這種格式既包含音頻格式,也包含視頻格式。但是OGV文件格式的壓縮方法和OGG是一樣的,可以采用同一種方式進行解析。
  為了說明簡單,下面統稱OGG。
優點與缺點:
  優點: ① Ogg Vorbis的音質和MP3不相上下,但無法和FLAC比。
      ② Ogg Vorbis支持類似于MP3的ID3信息;
      ③ Ogg Vorbis格式支持流式播放;
      ④ Ogg Vorbis避免了像MP3文件的ID3標記那樣煩瑣的操作(有很多針對MP3的ID3修改軟件標記早已不繁瑣)。
  缺點: ① 播放兼容性差。mp3已經成了便攜隨身聽的代名詞。絕大多數播放器、包括手機、pad等設備都支持mp3格式(其實mp3專利芯片授權費極低),而支持ogg格式的播放器很少。
     ② mp3是1997年以前就已經誕生,將近20年壟斷了消費機市場。ogg音頻普及性非常差,相對于mp3而言音質也沒有競爭力,普及的可能性極低。
     ③ 相對于已經普及的微軟WMA格式,ogg沒有任何優勢。不管是播放軟件兼容性,碼率,流媒體等方面。
     ④ 多聲道系統已經由DOLBY、DTS兩家公司壟斷,他們都有完整的制作發行體系。大型多聲道電影、電視、音樂制作都是基于這兩家公司的技術和標準。ogg只能望洋興嘆了。
     ⑤ 很多專業音頻制作軟件不支持ogg文件格式。
     ⑥ 現今HIFI已經被HIRES(高解析)代替,隨著存儲、網速等限制,用戶的聆聽設備已經上了一個臺階,有損格式已經漸漸失去市場。

12.2.OGG/OGV文件結構

首先介紹一下幾個相關的概念:
  (1)Packet:Packet一個解碼單元,或者是一幀數據。
  (2)Segment:Segment是由Packet分割而成,一個Segment最多只包含255格式bytes。Segment沒有Header。
  (3)Page:Page是OGG/OGV文件格式的基本組成單元,是對Segment的封裝。給一個或者幾個連續的Segments添加一個Page Header就構成了一個Page。
  OGG文件解碼后,按應用要求的時序關系合成若干物理流,一個物理流由若干邏輯流組成,一個邏輯流由若干包(Packet)組成。
  但OG文件本身是由頁(page)組成的,這樣,在形成OGG文件的時候,就要將邏輯流的各個包分割為若干區段(segment)后再進行頁封裝,每頁都加上頁頭。一個區段的長度最多為255字節,一頁最多封裝255個區段。如果幾個包的總長度≤255個區段,那么這幾個包的區段可以封裝在一頁;如果一個包長度>255個區段,那么就會被被封裝成兩頁或多頁,下一個包必須用新的頁開始封裝。每個頁之間相互獨立,都包含了各自應有的信息,頁的大小是可變的,通常為4K-8KB,最大值不能超過65307 bytes(27+255+255*255=65307)。

下面看一下OGG/OGV的文件格式,如下圖所示:

OGG/OGV文件就是由一個個的Page組成的。在解析的時候,通過Page的Header標記(“OggS”)將Page解析出來。下面看一些Page的Header結構,如下圖所示。

表12-1 Page的Header結構

(1)頁標識Page Starter:“OggS”ASCII字符分別為0x4f ‘O’ 0x67 ‘g’ 0x67 ‘g’ 0x53 ‘S’,4個字節大小,它標識著一個頁的開始。其作用是分離Ogg封裝格式還原媒體編碼時識別新頁的作用。
(2)版本ID:一般當前版本默認為0,1個字節。
(3)Header Type:這個變量用來標識一個Page的類型。可以設置3種數值。

  • 0x01:設置,說明該page和前面的一個page屬于同一個packet;如果不設置,說明該page屬于一個新的packet。
  • 0x02:設置,說明該page是該stream的第一個page,如果不設置,說明不是。
  • 0x04:設置,說明該page是該stream的最后一個page,如果不設置,說明不是。

(4)Granule Position:媒體編碼相關的參數信息,8個字節,對于音頻流來說,它存儲著到本頁為止邏輯流在PCM輸出中采樣碼的數目,可以由它來算得時間戳。對于視頻流來說,它存儲著到本頁為止視頻幀編碼的數目。若此值為-1,說明,該page不是當前packet的最后一個page。
  一個Page Header占用的字節數是不固定的,主要是因為Segment Table的長度不固定。因此我們可以得到頁頭的長度和整個頁的長度:

Header_size = 27 + Seg Numbers; (byte)
Page_size = Header_size + Segment_table中每個segment的大小;

OGG/OGV的封裝格式比較簡單。不過到這里,會有一個疑問,解碼的時候是以packet為單位的,那么解析出pages之后,該如何獲得packets呢?了解了OGG/OGV文件格式的封裝過程之后,這個問題就比較簡單了。

12.3.OGG/OGV文件封裝過程

OGG/OGV文件格式的封裝主要分為四個過程:
  第一、從編碼器獲得Packets;
  第二:將Packets分割成Segments;
  第三:將Segments打包成Pages;
  第四:將不同stream的pages組合在一起從而獲得OGG/OGV文件。對于只含有一個stream的文件,這個過程可以沒有。

封裝過程如下圖所示:

Packets分割成Segments之后,由于Segment的最大長度只能為255,而且一個Segment不能包含兩個Packet中的數據,因此,如果某個Segment的長度小于255,這個Segment就是Packet的最后一個Segment。有一種特殊的情況,那就是Segment的長度為0。如果一個Packet的長度正好是255的整數倍,那么就會用一個長度為0的Segment作為與下一個Packet的分界。以圖中的seg_5為例,它是packet_1和packet_2的分界,它的長度必須小于255,包括0。
  圖中只是給出了一個比較簡單的情況。在真正深入到OGG/OGV文件中去之后才發現,Packets和Pages的關系還是比較復雜的。圖中的情況是一個Packet包含在一個或者多個Pages中,而一個Page只涉及到一個Packet的數據。實際的情況是,一個Page可能涉及到多個Packets的數據,而且還有可能不是整個Packet的數據。舉個例子,還是上圖中的Packets和Segments,只是Pages重新打包。例如:
  page_1:packet_1的seg_1、seg_2、seg_3、seg_4
  page_2:packet_1的seg_5和packet_2的seg_1
  page_3:packet_2的seg_2、seg_3和packet_3的seg_1、seg_2
  因此,在解析OGG/OGV文件的時候,就需要做相應的處理。

12.4.OGG/OGV文件Header信息

OGG/OGV文件是由Pages組成的,因此,與文件、stream有關的信息,也是保存在Pages中的,這些Pages一般放在文件的開始位置。那么,如何判斷Pages中放的Header信息呢?這個其實比較簡單,可以通過Page的Header之后的幾個字節來判斷。這幾個字節不僅可以判斷Page中的數據是否為Header信息,還可以判斷Header信息的類型。這幾個字節是以ASCII的形式存在的,比如:“\001virbis、“\200theora”、“fishead”等等。OGG/OGV文件包含的Header的信息類型比較多,關于各個Header的類型、結構、解析方法等,可以去參考一下ffmpeg。
  對于只包含vorbis音頻格式的OGG文件,包含的Header一般比較少。而在OGV文件中,就比較多了。

12.5.OGG Vorbis 比特流的結構

Ogg文件解碼后形成比特流,比特流最前面是三個包頭,按照在文件中的順序依次是:標識頭(identification header)、注釋頭(comment header)和裝備頭(Setup Header)。標識頭設置了版本和流的簡單音頻特性(如采樣率和聲道數目等),注釋頭包括用戶文本注釋和供應商以及封裝軟件產生的字符串,裝備頭包括所需的解碼器裝備信息,以及完整的VQ和譯碼本。通常情況下,標識頭分割在ogg文件第1頁,注釋頭和裝備頭分割在ogg文件第2頁,這些包頭數據也就是所在頁的頁數據。從第3頁開始的頁數據才是真正的媒體流的壓縮數據。三個包頭的結構分別見表12-2、表12-3、表12-5。

表12-2 標識頭結構

域名稱占用字節描述
header_type_flag1=1:包頭類型為標識包
packet_pattern6=76 6F 72 62 69 73,包頭標識,vorbis的Ascii碼
vorbis_version4版本
audio_channels1聲道數目,必須>0
audio_sample_rate4音頻采樣率,必須>0
bitrate_maximum4最大比特率
bitrate_nominal4標稱比特率
bitrate_minimum4最小比特率
blocksize_0塊大小0: 占用4位,與blocksize_1共占用1字節
blocksize_1塊大小1: 占用4位,必須≥blocksize_0
framing_flag1=1,邊界標志,表示標識頭結束

說明:
  ①比特率域僅作為提示。尤其是標稱比特率,是純粹VBR流,只有>0,該域才是有意義的。如果三個比特率域設置為相同的值,意味著固定速率比特流,或者有嚴格邊界但接近固定速率的比特流。僅設置標稱比特率意味著只有一個 VBR(可變位速率) 或 ABR(平均位速率) 流。設置最大或最小比特率意味著一個 VBR 比特流,遵守比特率限制。沒有設置表明由編碼器自行處理。
  ②塊大小域不知為何意

12-3 注釋頭的結構

域名稱占用字節描述
header_type_flag1=3:包頭類型為注釋包
packet_pattern6=76 6F 72 62 69 73,包頭標識,vorbis 的Ascii碼
companyinfolength4制作軟件信息所占用的字節數
companyinfo制作軟件信息
retention_byte4保留字節
comment[1]_length4注釋[1]字符串所占用的字節數
comment[1]注釋[1]內容
……
comment[N]_length4注釋[N]字符串所占用的字節數
framing_flag1=1,邊界標志,表示注釋頭結束

說明:
  ①注釋名稱后面用等號連接注釋內容。
  ②常用的注釋名稱見表5。
  ③注釋名稱是可以重復的。例如:如果一個曲目由三個藝術家共同演唱,那么以下情況是允許的:
  ARTIST=張三
  ARTIST=李四
  ARTIST=王五

表12-4 常用注釋名稱

注釋名稱中譯義
ALBUM專輯
ARTIST藝術家
COPYRIGHT版權
DATE日期
DESCRIPTION描述
GENRE風格
CONTACT聯系人
ISRC國際標準記錄代碼
LICENSE許可證
LOCATION聲道位置
ORGANIZATION公司名
PERFORMER表演者
TITLE標題
TRACKNUMBER曲目號
YEAR年代
VERSION版本

說明:
  用戶也可以自己創新注釋名稱。

表12-5 裝備頭的結構

域名稱占用字描述
header_type_flag1=5:包頭類型為裝備包
packet_pattern6=76 6F 72 62 69 73,包頭標識,vorbis的Ascii碼
lists of codebook configurations碼本結構表
time-domain transform configurations時間戳轉換配置
floor configurations底層配置
residue configurations剩余配置
channel mapping configurations信道映射配置
mode configurations模式配置
說明:
裝備頭后面緊接著的就是真正的媒體壓縮數據流了。

12.6.實例解析

下面是我手機里的 Lock.ogg 的部分數據:

----------------------------------------------------------------------------------------- 0000: 4F 67 67 53 00 02 00 00 00 00 00 00 00 00 82 78 OggS..........倄 0010: 00 00 00 00 00 00 12 85 4E 81 01 1E 01 76 6F 72 .......匩....vor 0020: 62 69 73 00 00 00 00 01 44 AC 00 00 FF FF FF FF bis.....D....... 0030: 00 F4 01 00 FF FF FF FF B8 01 4F 67 67 53 00 00 ..........OggS.. 0040: 00 00 00 00 00 00 00 00 82 78 00 00 01 00 00 00 ........倄...... 0050: CC 63 C9 DB 0F 4D FF FF FF FF FF FF FF FF FF FF 蘡邵.M.......... 0060: FF FF FF E8 03 76 6F 72 62 69 73 1D 00 00 00 58 .....vorbis....X 0070: 69 70 68 2E 4F 72 67 20 6C 69 62 56 6F 72 62 69 iph.Org libVorbi 0080: 73 20 49 20 32 30 30 34 30 36 32 39 01 00 00 00 s I 20040629.... 0090: 1C 00 00 00 45 4E 43 4F 44 45 52 3D 41 64 6F 62 ....ENCODER=Adob 00A0: 65 28 52 29 20 41 75 64 69 74 69 6F 6E 28 52 29 e(R) Audition(R) 00B0: 01 05 76 6F 72 62 69 73 29 42 43 56 01 00 08 00 ..vorbis)BCV.... …… ------------------------------------------------------------------------------------------

解析:
0000-0039:第一頁
 0000-001B:頁頭部
  0000-0003=4F 67 67 53:頁標識,OggS的Ascii字符
  0004=00:版本號為0
  0005=02:頁頭部類型:本頁為邏輯流的第一頁bos
  0006-000D=0:區段位置為0
  000E-0011=82 78 00 00:邏輯流ID
  0012-0015=0:本頁在邏輯流中的序號為0
  0016-0019=12 85 4E 81:循環冗余校驗碼校驗和
  001A=01:區段表中有1個區段
  001B=1E:區段表中的區段長度為 1E
 001C-0039:頁數據(0039=1C+1E-1)
  001C=01:包頭類型為標識包,包長度為1E(001C-0039),是區段表中區段的長度
  001D-0022=76 6F 72 62 69 73:包頭標識,vorbis的Ascii碼
  0023-0026=0:版本號為0
  0027=01:單聲道
  0028-002B=44 AC 00 00:音頻采樣率為44.1KHZ(&HAC44=44100)
  002C-002F=FF FF FF FF:最大比特率未設置
  0030-0033=00 F4 01 00:標稱比特率
  0034-0037=FF FF FF FF:最小比特率未設置
  0038=B8:塊大小0為二進制的1011,塊大小1為二進制的1000
  0039=01:標識包結束
003A-0E8B:第二頁
 003A-0063:頁頭部
  003A-003D=4F 67 67 53:頁標識,OggS的Ascii字符
  003E=00:版本號為0
  003F=00:頁頭部類型:本頁為新包,不是邏輯流的第一頁,也不是最后一頁
  0040-0047=0:區段位置為0
  0048-004B=82 78 00 00:邏輯流ID
  004C-004F=01 00 00 00:本頁在邏輯流中的序號為1
  0050-0053=CC 63 C9 DB:循環冗余校驗碼校驗和
  0054=0F:區段表中有15個區段
  0055-0063=4D FF FF FF FF FF FF FF FF FF FF FF FF FF E8:區段表中15個區段的長度
 0064-0E8B:頁數據(0E8B=64+4D+FF*D+E8-1)
  0064=03:包頭類型為注釋包,包長度為4D(0064-00B0),是區段表中第1個區段的長度
  0065-006A=76 6F 72 62 69 73:包頭標識,vorbis的Ascii碼
  006B-006E=1D 00 00 00:制作軟件信息]的長度為29字節
  006F-008B=制作軟件信息字符串:Xiph.Org libVorbis I 20040629
  008C-008F=01 00 00 00:保留字節
  0094-00AF=注釋[1]字符串:ENCODER=Adobe? Audition?
  00B0=01:注釋包結束
  00B1=05:包頭類型為裝備包
  00B2-00B7=76 6F 72 62 69 73:包頭標識,vorbis的Ascii碼
  ……

13.PCM編碼格式

13.1.PCM概述

PCM (Pulse Code Modulated Audio)也被稱為脈沖編碼調制,是目前計算機應用中最高保真水平的音頻編碼格式。PCM音頻數據是未經壓縮的音頻采樣數據裸流,它是由模擬信號經過采樣、量化、編碼轉換成的標準的數字音頻數據。PCM約定俗成了無損編碼,能做到最大程度的無限接近絕對保真。被廣泛用于素材保存及音樂欣賞,CD、DVD以及我們常見的WAV文件中均有應用,優點是音質好,缺點是體積大。
  做嵌入式音視頻產品時,一般情況的音視頻都是芯片負責解碼。如果遇到版權問題,例如AC3、DTS,有些時候芯片廠商要求很嚴格,用戶會采取軟解的方法,軟解也就是把AC3 DTS等音頻解成PCM,然后在送給芯片。
  PCM編碼方式:

13.2.PCM數據格式

如果是單聲道的音頻文件,采樣數據按時間的先后順序依次存入(有的時候也會采用LRLRLR方式存儲,只是另一個聲道的數據為0),如果是雙聲道的話就按照LRLRLR的方式存儲,存儲的時候還和機器的大小端有關。大端模式如下圖所示:

14.RealAudio

Real Audio是Real networks推出的一種音樂壓縮格式,它的壓縮比可達到1:96,因此在網上比較流行。經過壓縮的音樂文件可以在通過速率為14.4kbps的 Modem上網的計算機中流暢回放,其最大特點是可以實現網上實時回訪,也就是說邊下載邊播放。
  網絡中非常常見,在rmvb、rm封裝格式中,或者是.ra 、.ram音頻文件,由RealNetworks發展的一種多媒體音頻文件格式,目前已有很多版本:
  lpcJ, 14_4: IS-54 VSELP (RealAudio 1)
  28_8: G.728 LD-CELP (RealAudio 2)
  dnet: Dolby AC3 (RealAudio 3)
  sipr: Sipro Lab Telecom ACELP-NET (RealAudio 4/5)
  cook: G2/Cook Codec (RealAudio 6)
  atrc: Sony ATRAC3 (RealAudio 8)
  raac: MPEG-4 LC-AAC (RealAudio 9)
  racp: MPEG-4 HE-AAC (RealAudio 10)
  ralf: RealAudio Lossless Format (RealAudio 10)

總結

以上是生活随笔為你收集整理的常见音频编码格式解析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。