1. 程式人生 > >g729編解碼的總結

g729編解碼的總結

關於音訊編解碼這一塊的內容,感覺就g729這個演算法麻煩一點。

在網上查詢資料關於g729有很多內容,大致也瞭解了一下。g729演算法算是一個類,裡面細分還有很多具體的東西,在ITU官網上下載的g729包裡面,有各種各樣的:g729a、g729b、g729c等等,自己實在是不知道該使用哪一個,仔細閱讀了文件以後,才發現,g729a是適合自己的。具體來說,每個都實現的功能不同,有的演算法中提供了關於位元速率選擇,有的提供了VDA等功能,不過自己用不到,所以,就選擇了g729a這個最基本的壓縮演算法。在網上搜索了一下,g729和g729a的區別在於:g729a的演算法質量提高了,相當於g729的加強版,恩,就它了。

在linux下進行編譯的時候,發現了一個問題:壓縮後的檔案,居然比壓縮前的檔案還大,我也是醉了。在網上搜索查資料,才發現,很多人在ITU下載的東西,編譯後都遇到同樣的問題。問題的關鍵在於如何優化。好吧,繼續查詢資料,我發現很資料關於優化這一塊的內容,都是殘缺不全的。這可是有點坑呀!想要去看的話,搜尋:“g729演算法 去序列化”即可。下面我是找了很長時間才找到的,是關於bits.c檔案的修改,希望對大家有所幫助吧。

#include "stdafx.h"
#include "typedef.h"
#include "ld8a.h"
#include "tab_ld8a.h"

static void bit2byte(Word16 para,int bitlen,unsigned char * bits,int bitpos) ;
static Word16 byte2bit(int bitlen,unsigned char * bits,int bitpos) ;

void prm2bits_ld8k(Word16 *para,unsigned char *bits)
{
  int i;
  int bitpos = 0;
  for (i = 0;i<PRM_SIZE;i++)
  {
  	bit2byte(*para++,bitsno[i],bits,bitpos);
  	bitpos+=bitsno[i];
  }

}

void bit2byte(Word16 para,int bitlen,unsigned char * bits,int bitpos)
{
  int i;
  int bit = 0;
  unsigned char newbyte = 0;
  
  unsigned char *p = bits + (bitpos / 8);
  for (i = 0 ;i<bitlen;i++)
  {
  	bit = (para >> (bitlen - i -1) ) &0x01;
    newbyte = (1 << (7-bitpos%8));
    if(bit == 1)
    	*p |= newbyte;
    else
    	*p &= ~newbyte;
    bitpos++;
    if (bitpos % 8 == 0)
      p++;
  }
}

void bits2prm_ld8k(unsigned char *bits,Word16 *para)
{
  int i;
  int bitpos = 0;
  for (i = 0;i<PRM_SIZE;i++)
  {
  	*para++=byte2bit(bitsno[i],bits,bitpos);
  	bitpos += bitsno[i];
  }

}

Word16 byte2bit(int bitlen,unsigned char * bits,int bitpos)
{
  int i;
  int bit = 0;
  Word16 newbyte = 0;
  Word16 value = 0;
  
  unsigned char *p = bits + (bitpos / 8);
  for (i = 0 ;i< bitlen;i++)
  {
  	bit = (*p >> (7 - bitpos % 8)) &0x01;
    if (bit == 1) 
    {
      newbyte = (1<<(bitlen -i-1));
  	  value |= newbyte;
    }
  	bitpos++;
  	if(bitpos%8 == 0)
  		p++;
  }  
  return value;
}
這是主要的東西,也是網上找的,其他細枝末節的東西我就不往上寫了,需要的話,大家可以去搜索一下。而且自己已經測試過了,是可以進行16:1壓縮的。
ps:我遇到了一個坑爹的問題,使用memcpy函式進行復制拷貝,可是當引數為char型別的時候,可以;引數為word16型別的時候,失敗。好吧,可能是自己理解的不夠!