ilbc編解碼


      針對國內的博客或者技術論壇對 ILBC的論述都是把文章抄來抄去, 本人在此對 ILBC的具體代碼實現詳細列出代碼.

      ILBC是由Global IP Sound公司提出的一種專為包交換網絡通信設計的編解碼,優於目前流行的G.729A、G.723.1,對丟包進行了特殊處理,既使在丟包率相當高的網絡環境下,仍可獲得非常清晰的語音效果。
    ILBC 對於20 ms的幀,共使用了304個比特來表示編碼后的語音信號,被封裝在38個字節中;對於30ms的幀,共使用了480個比特,封裝在50個字節中。

1.  ILBC的編譯

     ILBC代碼部分是網絡上找的,    點此下載.

     dll和lib(使用的是20 ms的幀)  點此下載.

 

2. 與PCM結合編解碼.

    ILBC對WaveFormat的值有要求, 即下列代碼的@FFormat, 取其他值時會有問題.

    PCMFormat: TWaveFormatEx = (
    wFormatTag: WAVE_FORMAT_PCM;
    nChannels: 1;
    nSamplesPerSec: 8000; 
    nAvgBytesPerSec: 16000;
    nBlockAlign: 2;
    wBitsperSample: 16; 
    cbSize: 0 );  

   由於使用的是20 ms的幀, 1秒應該是回調50次, 每次的語音數據為320字節.

   即FRecBufferSize的值取50

  

FDataSize:= FFormat.nAvgBytesPerSec div DWORD(RecBufferSize);
      GetMem(FWaveID,sizeof(HWaveIn));
      i := WaveInOpen(FWaveID, WAVE_MAPPER, @FFormat, DWORD(@waveInCallback),
                 DWORD(Self), CALLBACK_FUNCTION);
      if i=MMSYSERR_NOERROR then
      else begin
        FActive := False;
        Exit;
      end;
      for I:= 1 to FRecBufferSize do
        AddPrepareBuffer;
      WaveInStart(FWaveID^);
      FActive:= True;

以下函數為PCM數據回調后編碼

procedure TTalkClass.DoRecordData(Data: Pointer; size: Integer);
var
  pEncodeBuf: array[0..37] of Byte;
  eSize: Integer;
begin
  //先進行編碼 壓縮
  eSize := ilbc_encoder(Data, @pEncodeBuf);
  if Assigned(FOnTalkData) then
    FOnTalkData(@pEncodeBuf, eSize); //已經編碼的數據  320->38 壓縮后的
end;

然后進行ilbc解碼和播放

function TTalkClass.PlayData(pData: PByte; size: Integer): Boolean;
var
  pDecodeBuf: array [0..160-1] of SHORT;
  eSize: Integer;
begin
  //傳入的是編碼后的數據  先解碼
  eSize := ilbc_decoder(pData, @pDecodeBuf);
  FWaveOut.WriteData(@pDecodeBuf, eSize*2);
end;

這個地方必須要注意eSize*2, 由於ilbc_decoder這個函數解碼后的數據為short型數組, 返回值eSize表示的是數組長度.
這個地方不注意的話, 就很有問題了.

再貼一下delphi中引用這個dll的代碼

const
  Dll = 'ilbc.dll';

  function ilbc_init(): Boolean; stdcall; external Dll name '_ilbc_init@0';
  function ilbc_encoder(pin: Pointer; pout: PByte): Integer; stdcall; external Dll name '_ilbc_encoder@8';
  function ilbc_decoder(pin: PByte; pout: Pointer): Integer; stdcall; external Dll name '_ilbc_decoder@8';


需要編碼后的ilbc語音數據的點此下載.  用文件流讀取時記得每次取38字節進行解碼.

最后聲明下我說的只是個人這幾天的心得, 有什么說的不對的請指正.

 

 

  

 


免責聲明!

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



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