轉(zhuǎn)載自:http://blog.csdn.net/Poechant/article/details/7435054
這里利用FAAC來實(shí)現(xiàn)AAC編碼。
1 下載安裝 FAAC
這里的安裝過程是在 Mac 和 Linux 上實(shí)現(xiàn)的,Windows可以類似參考。
wget http://downloads.sourceforge.net/faac/faac-1.28.tar.gz
tar zxvf faac-1.28.tar.gz
cd faac-1.28
./configure
make
sudo make install
如果才用默認(rèn)的 configure 中的 prefix path,那么安裝后的 lib 和 .h 文件分別在/usr/local/lib
和/usr/local/include
,后面編譯的時(shí)候會(huì)用到。
如果編譯過程中發(fā)現(xiàn)錯(cuò)誤:
mpeg4ip.h:126: error: new declaration ‘char* strcasestr(const char*, const char*)’
解決方法:
從123行開始修改此文件mpeg4ip.h,到129行結(jié)束。 修改前:
#ifdef __cplusplus
extern "C" {
#endif
char *strcasestr(const char *haystack, const char *needle);
#ifdef __cplusplus
}
#endif
修改后:
#ifdef __cplusplus
extern "C++" {
#endif
const char *strcasestr(const char *haystack, const char *needle);
#ifdef __cplusplus
}
#endif
2 FAAC API
2.1 Open FAAC engine
Prototype:
faacEncHandle faacEncOpen // 返回一個(gè)FAAC的handle
(
unsigned long nSampleRate, // 采樣率,單位是bps
unsigned long nChannels, // 聲道,1為單聲道,2為雙聲道
unsigned long &nInputSamples, // 傳引用,得到每次調(diào)用編碼時(shí)所應(yīng)接收的原始數(shù)據(jù)長(zhǎng)度
unsigned long &nMaxOutputBytes // 傳引用,得到每次調(diào)用編碼時(shí)生成的AAC數(shù)據(jù)的最大長(zhǎng)度
);
2.2 Get/Set encoding configuration
Prototype:
獲取編碼器的配置:
faacEncConfigurationPtr faacEncGetCurrentConfiguration // 得到指向當(dāng)前編碼器配置的指針
(
faacEncHandle hEncoder // FAAC的handle
);
設(shè)定編碼器的配置:
int FAACAPI faacEncSetConfiguration
(
faacDecHandle hDecoder, // 此前得到的FAAC的handle
faacEncConfigurationPtr config // FAAC編碼器的配置
);
2.3 Encode
Prototype:
int faacEncEncode
(
faacEncHandle hEncoder, // FAAC的handle
short *inputBuffer, // PCM原始數(shù)據(jù)
unsigned int samplesInput, // 調(diào)用faacEncOpen時(shí)得到的nInputSamples值
unsigned char *outputBuffer,// 至少具有調(diào)用faacEncOpen時(shí)得到的nMaxOutputBytes字節(jié)長(zhǎng)度的緩沖區(qū)
unsigned int bufferSize // outputBuffer緩沖區(qū)的實(shí)際大小
);
2.4 Close FAAC engine
Prototype
void faacEncClose
(
faacEncHandle hEncoder // 此前得到的FAAC handle
);
3 流程
3.1 做什么準(zhǔn)備?
采樣率,聲道數(shù)(雙聲道還是單聲道?),還有你的PCM的單個(gè)樣本是8位的還是16位的?
3.2 開啟FAAC編碼器,做編碼前的準(zhǔn)備
- 調(diào)用
faacEncOpen
開啟FAAC編碼器后,得到了單次輸入樣本數(shù)nInputSamples
和輸出數(shù)據(jù)最大字節(jié)數(shù)nMaxOutputBytes
; - 根據(jù)
nInputSamples
和nMaxOutputBytes
,分別為PCM數(shù)據(jù)和將要得到的AAC數(shù)據(jù)創(chuàng)建緩沖區(qū); - 調(diào)用
faacEncGetCurrentConfiguration
獲取當(dāng)前配置,修改完配置后,調(diào)用faacEncSetConfiguration
設(shè)置新配置。
3.3 開始編碼
調(diào)用faacEncEncode
,該準(zhǔn)備的剛才都準(zhǔn)備好了,很簡(jiǎn)單。
3.4 善后
關(guān)閉編碼器,另外別忘了釋放緩沖區(qū),如果使用了文件流,也別忘記了關(guān)閉。
4 測(cè)試程序
4.1 完整代碼
將PCM
格式音頻文件/home/michael/Development/testspace/in.pcm
轉(zhuǎn)至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; // 聲道數(shù)
UINT nPCMBitSize = 16; // 單樣本位數(shù)
ULONG nInputSamples = 0;
ULONG nMaxOutputBytes = 0;
int nRet;
faacEncHandle hEncoder;
faacEncConfigurationPtr pConfiguration;
int nBytesRead;
int nPCMBufferSize;
BYTE* pbPCMBuffer;
BYTE* pbAACBuffer;
FILE* fpIn; // PCM file for input
FILE* fpOut; // AAC file for output
fpIn = fopen("/home/michael/Development/testspace/in.pcm", "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++)
{
// 讀入的實(shí)際字節(jié)數(shù),最大不會(huì)超過nPCMBufferSize,一般只有讀到文件尾時(shí)才不是這個(gè)值
nBytesRead = fread(pbPCMBuffer, 1, nPCMBufferSize, fpIn);
// 輸入樣本數(shù),用實(shí)際讀入字節(jié)數(shù)計(jì)算,一般只有讀到文件尾時(shí)才不是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;
}
}
/*
while(1)
{
// (3) Flushing
nRet = faacEncEncode(
hEncoder, (int*) pbPCMBuffer, 0, pbAACBuffer, nMaxOutputBytes);
if(nRet <= 0)
{
break;
}
}
*/
// (4) Close FAAC engine
nRet = faacEncClose(hEncoder);
delete[] pbPCMBuffer;
delete[] pbAACBuffer;
fclose(fpIn);
fclose(fpOut);
//getchar();
return 0;
}
4.2 編譯運(yùn)行
將上述代碼保存為“pcm2aac.cpp”文件,然后編譯:
g++ pcm2aac.cpp -o pcm2aac -L/usr/local/lib -lfaac -I/usr/local/include
運(yùn)行:
./pcm2aac
然后就生成了out.aac
文件了,聽聽看吧!~
5 Reference
- AudioCoding.com - FAAC
- Dogfoot – ??? ??
-
轉(zhuǎn)載請(qǐng)注明來自柳大的CSDN博客:blog.csdn.net/poechant