音訊編解碼·實戰篇(1)PCM轉至AAC(AAC編碼)
音訊編解碼·實戰篇(1)PCM轉至AAC(AAC編碼)
- 作者:柳大·Poechant
- 部落格:blog.csdn.net/poechant
- 郵箱:zhongchao.ustc@gmail.com
- 日期:April 7th, 2012
這裡利用FAAC來實現AAC編碼。
1 下載安裝 FAAC
這裡的安裝過程是在 Mac 和 Linux 上實現的,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
如果才用預設的 configure 中的 prefix path,那麼安裝後的 lib 和 .h 檔案分別在/usr/local/lib
和/usr/local/include
,後面編譯的時候會用到。
如果編譯過程中發現錯誤:
mpeg4ip.h:126: error: new declaration ‘char* strcasestr(const char*, const char*)’
解決方法:
從123行開始修改此檔案mpeg4ip.h,到129行結束。 修改前:
#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 // 返回一個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, // PCM原始資料
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 做什麼準備?
取樣率,聲道數(雙聲道還是單聲道?),還有你的PCM的單個樣本是8位的還是16位的?
3.2 開啟FAAC編碼器,做編碼前的準備
- 呼叫
faacEncOpen
開啟FAAC編碼器後,得到了單次輸入樣本數nInputSamples
和輸出資料最大位元組數nMaxOutputBytes
; - 根據
nInputSamples
和nMaxOutputBytes
,分別為PCM資料和將要得到的AAC資料建立緩衝區; - 呼叫
faacEncGetCurrentConfiguration
獲取當前配置,修改完配置後,呼叫faacEncSetConfiguration
設定新配置。
3.3 開始編碼
呼叫faacEncEncode
,該準備的剛才都準備好了,很簡單。
3.4 善後
關閉編碼器,另外別忘了釋放緩衝區,如果使用了檔案流,也別忘記了關閉。
4 測試程式
4.1 完整程式碼
將PCM
格式音訊檔案/home/michael/Development/testspace/in.pcm
轉至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; // 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++)
{
// 讀入的實際位元組數,最大不會超過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;
}
}
/*
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 編譯執行
將上述程式碼儲存為“pcm2aac.cpp”檔案,然後編譯:
g++ pcm2aac.cpp -o pcm2aac -L/usr/local/lib -lfaac -I/usr/local/include
執行:
./pcm2aac
然後就生成了out.aac
檔案了,聽聽看吧!~
5 Reference
-
轉載請註明來自柳大的CSDN部落格:blog.csdn.net/poechant
-
相關文章
- 音訊編解碼·實戰篇(1)WAV轉至AAC(AAC編碼)音訊
- ffmpeg音訊編碼之pcm轉碼aac音訊
- MediaCodec硬編碼pcm2aac
- Android音視訊(四)MediaCodec編解碼AACAndroid
- JavaCV FFmpeg AAC編碼Java
- 【秒懂音視訊開發】14_AAC編碼
- Android MediaCodec硬解碼AAC音訊檔案(實時AAC音訊幀)並播放Android音訊
- 音訊編解碼·格式篇(1)Wave PCM audio format(WAV)音訊ORM
- AAC 音訊音訊
- 相親交友原始碼中,音訊AAC解碼的實現程式碼原始碼音訊
- android 音訊採集、FLTP重取樣與AAC編碼推流Android音訊
- 萬彩動畫大師教程 | 輸出視訊音訊編碼器選擇(AAC和MP3)動畫音訊
- 從fdk_aac編碼器到自動靜態編譯FFmpeg編譯
- C++實現RTMP協議傳送H.264編碼及AAC編碼的直播軟體開發音影片C++協議
- FFMPEG視音訊編解碼學習(1)音訊
- 音訊編解碼標準音訊
- ios利用mic採集Pcm轉為AAC,AudioQueue、AudioUnit(流式)iOS
- 音訊編碼基礎詳解音訊
- Android 音視訊開發 視訊編碼,音訊編碼格式Android音訊
- Android 音視訊 - MediaCodec 編解碼音視訊Android
- 在.NET中使用Speex -- 音訊資料編解碼 (轉)音訊
- 1小時學會:最簡單的iOS直播推流(八)h264 aac 軟編碼iOS
- 1小時學會:最簡單的iOS直播推流(七)h264/aac 硬編碼iOS
- DM6446的音訊編解碼及播放實現音訊
- 轉載:iOS音視訊實時採集硬體編碼iOS
- 各種音訊視訊編碼方法音訊
- 各種音視訊編解碼學習詳解
- 音訊編解碼-speex庫的使用方法音訊
- js對flv提取h264、aac音視訊流JS
- 音訊編碼基礎知識音訊
- G711(PCM/PCMA/PCMU),G721,G723,G729等 音訊編解碼音訊
- Android 音視訊錄製硬編碼實現Android
- Android平臺aac谷歌軟解框架和流程、解碼庫學習Android谷歌框架
- ElasticSearch實戰-編碼實踐Elasticsearch
- Android音訊實時傳輸與播放(三):AMR硬編碼與硬解碼Android音訊
- ffmpeg提取aac資料
- 音視訊入門之音訊採集、編碼、播放音訊
- Netty4實戰 - 編解碼技術Netty