這裡利用FAAC來實現AAC編碼。另外,WAV的資料區段是PCM,代碼會出現很多PCM縮寫。 1 下載安裝 FAAC
這裡的安裝過程是在 Mac 和 Linux 上實現的,Windows可以類似參考。
wget http://downloads.sourceforge.net/faac/faac-1.28.tar.gztar zxvf faac-1.28.tar.gzcd faac-1.28./configuremakesudo make install
如果才用預設的 configure 中的 prefix path,那麼安裝後的 lib 和 .h 檔案分別在/usr/local/lib和/usr/local/include,後面編譯的時候會用到。 2 FAAC API 2.1 Open FAAC engine Prototype:
faacEncHandle faacEncOpen // 返回一個FAAC的handle( unsigned long nSampleRate, // 採樣率,單位是bps unsigned long nChannels, // 聲道,1為單聲道,2為雙聲道 unsigned long &nInputSamples, // 傳引用,得到每次調用編碼時所應接收的未經處理資料長度 unsigned long &nMaxOutputBytes // 傳引用,得到每次調用編碼時產生的AAC資料的最大長度);
2.2 Get/Set encoding configuration
Prototype:
擷取編碼器的配置:
faacEncConfigurationPtr faacEncGetCurrentConfiguration // 得到指向當前編碼器配置的指標( faacEncHandle hEncoder // FAAC的handle);
設定編碼器的配置:
int FAACAPI faacEncSetConfiguration( faacDecHandle hDecoder, // 此前得到的FAAC的handle faacEncConfigurationPtr config // FAAC編碼器的配置);
2.3 Encode
Prototype:
int faacEncEncode( faacEncHandle hEncoder, // FAAC的handle short *inputBuffer, // WAV未經處理資料 unsigned int samplesInput, // 調用faacEncOpen時得到的nInputSamples值 unsigned char *outputBuffer,// 至少具有調用faacEncOpen時得到的nMaxOutputBytes位元組長度的緩衝區 unsigned int bufferSize // outputBuffer緩衝區的實際大小);
2.4 Close FAAC engine
Prototype
void faacEncClose( faacEncHandle hEncoder // 此前得到的FAAC handle);
3 流程
3.1 做什麼準備。
採樣率,聲道數(雙聲道還是單聲道。),還有你的WAV的單個樣本是8位的還是16位的。 3.2 開啟FAAC編碼器,做編碼前的準備 調用faacEncOpen開啟FAAC編碼器後,得到了單次輸入樣本數nInputSamples和輸出資料最大位元組數nMaxOutputBytes; 根據nInputSamples和nMaxOutputBytes,分別為WAV資料和將要得到的AAC資料建立緩衝區; 調用faacEncGetCurrentConfiguration擷取當前配置,修改完配置後,調用faacEncSetConfiguration設定新配置。 3.3 開始編碼
調用faacEncEncode,該準備的剛才都準備好了,很簡單。 3.4 善後
關閉編碼器,另外別忘了釋放緩衝區,如果使用了檔案流,也別忘記了關閉。 4 測試程式 4.1 完整代碼
將WAV格式音頻檔案/home/michael/Development/testspace/in.wav轉至AAC格式檔案/home/michael/Development/testspace/out.aac。
#include <faac.h>#include <stdio.h>typedef unsigned long ULONG;typedef unsigned int UINT;typedef unsigned char BYTE;typedef char _TCHAR;int main(int argc, _TCHAR* argv[]){ ULONG nSampleRate = 11025; // 採樣率 UINT nChannels = 1; // 聲道數 UINT nPCMBitSize = 16; // 單樣本位元 ULONG nInputSamples = 0; ULONG nMaxOutputBytes = 0; int nRet; faacEncHandle hEncoder; faacEncConfigurationPtr pConfiguration; int nBytesRead; int nPCMBufferSize; BYTE* pbPCMBuffer; BYTE* pbAACBuffer; FILE* fpIn; // WAV file for input FILE* fpOut; // AAC file for output fpIn = fopen("/home/michael/Development/testspace/in.wav", "rb"); fpOut = fopen("/home/michael/Development/testspace/out.aac", "wb"); // (1) Open FAAC engine hEncoder = faacEncOpen(nSampleRate, nChannels, &nInputSamples, &nMaxOutputBytes); if(hEncoder == NULL) { printf("[ERROR] Failed to call faacEncOpen()\n"); return -1; } nPCMBufferSize = nInputSamples * nPCMBitSize / 8; pbPCMBuffer = new BYTE [nPCMBufferSize]; pbAACBuffer = new BYTE [nMaxOutputBytes]; // (2.1) Get current encoding configuration pConfiguration = faacEncGetCurrentConfiguration(hEncoder); pConfiguration->inputFormat = FAAC_INPUT_16BIT; // (2.2) Set encoding configuration nRet = faacEncSetConfiguration(hEncoder, pConfiguration); for(int i = 0; 1; i++) { // 讀入的實際位元組數,最大不會超過nPCMBufferSize,一般只有讀到檔案尾時才不是這個值 nBytesRead = fread(pbPCMBuffer, 1, nPCMBufferSize, fpIn); // 輸入樣本數,用實際讀入位元組數計算,一般只有讀到檔案尾時才不是nPCMBufferSize/(nPCMBitSize/8); nInputSamples = nBytesRead / (nPCMBitSize / 8); // (3) Encode nRet = faacEncEncode( hEncoder, (int*) pbPCMBuffer, nInputSamples, pbAACBuffer, nMaxOutputBytes); fwrite(pbAACBuffer, 1, nRet, fpOut); printf("%d: faacEncEncode returns %d\n", i, nRet); if(nBytesRead <= 0) { break; } } // (4) Close FAAC engine nRet = faacEncClose(hEncoder); delete[] pbPCMBuffer; delete[] pbAACBuffer; fclose(fpIn); fclose(fpOut); //getchar(); return 0;}
4.2 編譯運行
將上述代碼儲存為“wav2aac.cpp”檔案,然後編譯:
g++ wav2aac.cpp -o wav2aac -L/usr/local/lib -lfaac -I/usr/local/include
運行:
./wav2aac
然後就產生了out.aac檔案了,聽聽看吧。~ 5 Reference AudioCoding.com -FAAC Dogfoot – 재밌는 개발