天天看點

Audio Codec : MPEG2 AAC -- TNS

2007 年我的項目文檔,共享分析吧

1 Temporal Noise Shaping (TNS)原理

TNS是在1996年提出的一種能夠自适應于輸入信号特性來降低前回聲效應的新技術。它利用應用于信号頻譜的處理來實作時域噪聲形狀的控制,能夠對量化噪聲的細微時域結構(甚至在一個濾波器組視窗内)進行控制。它的提出基于如下的考慮:

時域一頻域對偶性的考慮:TNS技術利用時域和頻域之間的對偶性,以一種新的形式發展了己有的預測編碼技術。衆所周知,對于具有“非平坦(non-flatness)',頻譜的信号既可以直接對頻譜值進行編碼(變換編碼),也可以對時域信号進行預測編碼。對于具有“非平坦”時域結構的信号(即瞬态信号)自然也就有兩種對應的方法。對于瞬态信号可以直接對時域值進行編碼,也可以對頻譜系數進行預測編碼。總而言之,在時域上的預測提高了編碼器的頻域分辨率,而在頻域上的預測提高了編碼器的時域分辨率。

使用預測編碼進行噪聲整形:如果對時域信号進行前向預測編碼,則可以調節解碼器最終的量化誤差的功率譜密度(PSD)以适應輸入信号的功率譜。與此相對應,在頻域上對頻譜資料進行預測編碼,則在解碼器輸出端可以調節量化誤差的時域形狀以适應輸入信号的時域形狀。這樣,可以有效地把量化誤差置于實際信号之下,并且可以由此避免瞬态信号或沖擊信号的掩蔽效應問題。是以,這種對頻譜資料的預測方法也被稱為TNS方法。

由于TNS處理既可以用于整個頻譜也可以用于部分頻譜,是以可在任何與頻率有關的地

方使用時域噪聲控制,它也可以用幾個預測濾波器作用在不同的頻率(系數)範圍。

TNS的解碼過程如下:首先經過查表得到相應的反射系數。然後把這些反射系數轉換成線性預測編碼(LPC)系數a[] o最後就是對相應的頻帶進行全極點有限沖擊響應濾波.

公式

y[n]=x[n]-a[1]*y[n一1]-…-a[order]*y[n-order]

其中x[n]為頻譜上的目前值,Y回為濾波後值,而Y[n-1]是前一濾波後值,依次類推。如圖1所示為此濾波器的框圖,其中Z為延時器,控制器根據階數(order)的大小控制其中延時器的輸出是否為零的個數。

Audio Codec : MPEG2 AAC -- TNS

                   圖1 TNS濾波器框圖

TNS解碼的運算量計算方法為:order*L次實數乘法,order*L次加(減)法,其中L是應用濾波的頻率系數的長度,一般為640:使用乘加指令能夠得到最大的解碼速度。AAC LC架構的TNS階數受限(Order最大為12),與主架構(Order最大20)相比,計算量明顯下降,這便于LC架構在系統資源受限的系統中的應用。

2  MPEG2 AAC  TNS算法應用

2.1 碼流格式

當individual_channel_stream碼流中的tns_data_present等于1時表示編碼器使用了TNS處理,碼流中存在tns_data碼流。

   TNS碼流格式如下

tns_data()
{
        for (w = 0; w < num_windows; w++) {
                n_filt[w]; 1..2
                if (n_filt[w])
                        coef_res[w]; 1
                for (filt = 0; filt < n_filt[w]; filt++) {
                        length[w][filt]; {4;6}
                        order[w][filt]; {3;5}
                        if (order[w][filt]) {
                                direction[w][filt];
                                coef_compress[w][filt];
                                for (i = 0; i < order[w][filt]; i++)
                                        coef[w][filt][i]; 2..4
                        }
                }
        }
}

語意是

n_filt[w] 每個窗中使用的filter的個數
coef_res[w]

0:傳輸的濾波器系數是3bit

1:傳輸的濾波器系數是4bit

length[w][filt] 一個filter使用的region的長度
order[w][filt] 一個filter的階數
direction[w][filt]

0:filter的方向是向上的

1:filter的方向是向下的

coef_compress[w][filt]

0:Filter系數的最高位忽略

1:Filter系數的最高位不忽略

coef[w][filt][i] Filter系數

  注意:每個碼流标志的有效位數是根據窗形确定的。

短窗 長窗,開始窗,結束窗
1位 2位
4位 6位
3位 5位

2.2 解碼過程

Step1:解碼濾波器傳輸系數,包括化為有符号數和反量化。

Step2:全極點濾波器應用到目标頻率上。

   Direction用于決定濾波器的方向,‘1’表示向下,‘0’表示向上。

TNS_MAX_ORDER:定義最大的可能的濾波器階數。

TNS_MAX_BAND:定義用于TNS的scalefactor band的最大個數。

僞碼

/* TNS decoding for one channel and frame */

tns_decode_frame()

  for (w = 0; w < num_windows; w++) {

     bottom = num_swb;

     for (f = 0; f < n_filt[w]; f++) {

       top = bottom;

       bottom = max(top - length[w][f], 0);

       tns_order = min(order[w][f], TNS_MAX_ORDER);

       if (!tns_order) continue;

       tns_decode_coef(tns_order, coef_res[w]+3, coef_compress[w][f],

                      coef[w][f], lpc[]);

       start = swb_offset[min(bottom,TNS_MAX_BANDS,max_sfb)];

       end = swb_offset[min(top,TNS_MAX_BANDS,max_sfb)];

       if ((size = end - start) <= 0) continue;

       if (direction[w][f]) {

          inc = -1; start = end - 1;

       } else {

          inc = 1;

       }

       tns_ar_filter(&spec[w][start], size, inc, lpc[], tns_order);

     }

  }

tns_decode_coef(order, coef_res_bits, coef_compress, coef[], a[])

  /* 初始化内部表格 */

  sgn_mask[] = { 0x2, 0x4, 0x8 };

  neg_mask[] = { ~0x3, ~0x7, ~0xf };

  /* size used for transmission */

  coef_res2 = coef_res_bits - coef_compress;

  s_mask = sgn_mask[coef_res2 - 2];  /* mask for sign bit */

  n_mask = neg_mask[coef_res2 - 2];  /* mask for padding neg. values */

  /* 轉換為有符号整數 */

  for (i = 0; i < order; i++)

     tmp[i] = (coef[i] & s_mask) ? (coef[i] | n_mask) : coef[i];

  /* 反量化 */

  iqfac = ((1 << (coef_res_bits-1)) - 0.5) / (p/2.0);

  iqfac_m = ((1 << (coef_res_bits-1)) + 0.5) / (p/2.0);

  for (i = 0; i < order; i++) {

     tmp2[i] = sin(tmp[i] / ((tmp[i] >= 0) ? iqfac : iqfac_m));

  /* 轉化到LPC系數 */

  a[0] = 1;

  for (m = 1; m <= order; m++) {

     for (i = 1; i < m; i++) {          /* loop only while i<m */

       b[i] = a[i] + tmp2[m-1] * a[m-i];

     for (i = 1; i < m; i++) {          /* loop only while i<m */

       a[i] = b[i];

     a[m] = tmp2[m-1];                  /* changed */

tns_ar_filter(spectrum[], size, inc, lpc[], order)

  y(n) = x(n) - lpc[1]*y(n-1) - ... - lpc[order]*y(n-order)

-每次要初始化濾波器狀态資訊為0

-輸出資料覆寫輸入資料

  - An input vector of "size" samples is processed and the index increment

   to the next data sample is given by "inc"

3 參考代碼

   ISO參考代碼中,用void tns_decode_subblock(Float *spec, int nbands, short *sfb_top, int islong,TNSinfo *tns_info)函數實作TNS操作。并定義資料結構如下

TNS 算法資料結構

typedef struct

{  

int n_filt;    tns濾波器個數
int coef_res; 濾波器系數
TNSfilt filt[TNS_MAX_FILT];

} TNSinfo;

繼續閱讀