AAC音頻編碼


轉載

原文地址:https://www.jianshu.com/p/5452165f98b0

AAC(Advanced Audio Coding),中文名:高級 音頻 編碼,出現於1997年,基於 MPEG-2的音頻編碼技術。由 Fraunhofer IIS杜比實驗室AT&TSony等公司共同開發,目的是取代 MP3格式。2000年, MPEG-4標准出現后,AAC重新集成了其特性,加入了SBR技術和PS技術,為了區別於傳統的MPEG-2 AAC又稱為 MPEG-4 AAC。

定義

AAC,全稱Advanced Audio Coding,是一種專為聲音數據設計的文件壓縮格式。與MP3不同,它采用了全新的算法進行編碼,更加高效,具有更高的“性價比”。利用AAC格式,可使人感覺聲音質量沒有明顯降低的前提下,更加小巧。蘋果ipod諾基亞手機支持AAC格式的音頻文件。

優點:相對於mp3,AAC格式的音質更佳,文件更小。

不足:AAC屬於有損壓縮的格式,與時下流行的APEFLAC無損格式相比音質存在“本質上”的差距。加之,傳輸速度更快的USB3.0和16G以上大容量MP3正在加速普及,也使得AAC頭上“小巧”的光環不復存在。

特點

①提升的壓縮率:可以以更小的文件大小獲得更高的音質;
②支持多聲道:可提供最多48個全音域聲道;
③更高的解析度:最高支持96KHz的采樣頻率;
④提升的解碼效率:解碼播放所占的資源更少;
杜比實驗室的結論
①128Kbps的AAC立體聲音樂被專家認為不易察覺到與原來未壓縮音源的區別;
②AAC格式在96Kbps碼率的表現超過了128Kbps的MP3格式;
③同樣是128Kbps,AAC格式的音質明顯好於MP3;
④AAC是唯一一個,能夠在所有的EBU試聽測試項目的獲得“優秀”的網絡廣播格式。
總的來講,AAC可以說是極為全面的編碼方式,一方面,多聲道和高采樣率的特點使得它非常適合未來的DVD-Audio;另一方面,低碼率下的高音質則使它也適合移動通訊、網絡電話、在線廣播等領域,真是全能的編碼方式。

AAC 規格介紹

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

  • MPEG-2 AAC LC 低復雜度規格(Low Complexity)--比較簡單,沒有增益控制,但提高了編碼效率,在中等碼率的編碼效率以及音質方面,都能找到平衡點
  • MPEG-2 AAC Main 主規格
  • MPEG-2 AAC SSR 可變采樣率規格(Scaleable Sample Rate)
  • MPEG-4 AAC LC 低復雜度規格(Low Complexity)------現在的手機比較常見的MP4文件中
  • 的音頻部份就包括了該規格音頻文件
  • 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)-----這種規格適合用於低碼率編碼,有Nero ACC 編碼器支持

AAC音頻文件格式

AAC的音頻文件格式有ADIF & ADTS:

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

  • ADTS:Audio Data Transport Stream 音頻數據傳輸流。這種格式的特征是它是一個有同步字的比特流,解碼可以在這個流中任何位置開始。它的特征類似於mp3數據流格式。(簡單說,ADTS可以在任意幀解碼,也就是說它每一幀都有頭信息。ADIF只有一個統一的頭,所以必須得到所有的數據后解碼。且這兩種的header的格式也是不同的,目前一般編碼后的和抽取出的都是ADTS格式的音頻流。兩者具體的組織結構如下所示)

 

AAC的ADIF格式見下圖:


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


 

ADTS 文件格式

AAC音頻文件的每一幀由ADTS Header和AAC Audio Data組成。


 

而ADTS的 Header部分分成兩部分,固定部分和可變部分

固定部分 adts_fixed_header
 
  • yncword :總是0xFFF, 代表一個ADTS幀的開始, 用於同步.
    解碼器可通過0xFFF確定每個ADTS的開始位置.
    因為它的存在,解碼可以在這個流中任何位置開始, 即可以在任意幀解碼。
  • ID:MPEG 版本: 0 代表 MPEG-4,1 代表 MPEG-2
  • Layer:總是: '00'
  • protection_absent:設置0,進行crc校驗,1不進行crc校驗,進行crc校驗導致固定部分邊長成28+16 = 44bits
  • profile:表示使用哪個級別的AAC
    如01 Low Complexity(LC) -- AAC LC。

注意 profile的值等於 Audio Object Type的值減1.
profile = MPEG-4 Audio Object Type - 1


  • sampling_frequency_index:采樣率的下標

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

這里注意,聲道數量這里有3個bits表示

 

其他沒有介紹的位都是0,保留

可變部分adts_variable_header
 
  • aac_frame_length 一個ADTS幀的長度包括ADTS頭和AAC原始流。就是該幀的總長度。
    aac_frame_length = (protection_absent == 1 ? 7 : 9) + size(AACFrame)
  • 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個采樣及相關數據

總體結構

AAAAAAAA AAAABCCD EEFFFFGH HHIJKLMM MMMMMMMM MMMOOOOO OOOOOOPP (QQQQQQQQ QQQQQQQQ)

頭部分是7字節或者9字節(有crc就是9字節沒有就是7字節)

Letter Length (bits) Description
A 12 syncword 0xFFF, 所有位數都是1
B 1 MPEG 版本: 0 代表 MPEG-4, 1 代表 MPEG-2
C 2 Layer: 總是 0
D 1 protection absent, 1 代表不用crc,0代表用crc
E 2 profile, MPEG-4 Audio Object Type 減去 1
F 4 MPEG-4 Sampling Frequency Index
G 1 私有位置,不會被mpeg適用,編碼時候設置0,解碼忽略
H 3 MPEG-4 Channel Configuration (在0的情況下,通過帶內的PCE發送通道配置)
I 1 originality, 編碼設置0,解碼忽略
J 1 home, 編碼設置0,解碼忽略
K 1 copyrighted id bit,編碼時候設置0,解碼忽略
L 1 copyright id start, 編碼時候設置0,解碼忽略
M 13 frame length,幀長度,該值保護7或者9個字節的頭
FrameLength =(ProtectionAbsent == 1?7:9)+ size(AACFrame)
O 11 Buffer fullness ,緩沖充滿度
P 2 ADTS 幀中的AAC幀數-1
為了實現最大的兼容性,每個ADTS幀始終使用一個AAC
也就是說改為始終是0
Q 16 protection absent 是0, 就有q的位置,是1,就沒有q的位置

這段代碼寫的很清楚可惜不是oc寫的

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;  
} 

這里是LFLiveKit中的代碼封裝。

- (NSData *)adtsData:(NSInteger)channel rawDataLength:(NSInteger)rawDataLength {
    int adtsLength = 7;
    char *packet = malloc(sizeof(char) * adtsLength);
    
    // Variables Recycled by addADTStoPacket
    int profile = 2;  //AAC LC
    //39=MediaCodecInfo.CodecProfileLevel.AACObjectELD;
    NSInteger freqIdx = [self sampleRateIndex:self.configuration.audioSampleRate];  //44.1KHz
    int chanCfg = (int)channel;  //MPEG-4 Audio Channel Configuration. 1 Channel front-center
    NSUInteger fullLength = adtsLength + rawDataLength;
    // fill in ADTS data
    packet[0] = (char)0xFF;     // 11111111     = syncword
    packet[1] = (char)0xF9;     // 1111 1 00 1  = syncword MPEG-2 Layer CRC
    packet[2] = (char)(((profile-1)<<6) + (freqIdx<<2) +(chanCfg>>2));
    packet[3] = (char)(((chanCfg&3)<<6) + (fullLength>>11));
    packet[4] = (char)((fullLength&0x7FF) >> 3);
    packet[5] = (char)(((fullLength&7)<<5) + 0x1F);
    packet[6] = (char)0xFC;
    NSData *data = [NSData dataWithBytesNoCopy:packet length:adtsLength freeWhenDone:YES];
    return data;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM