音频编解码·实战篇(1)PCM转至AAC(AAC编码)
来源:互联网 发布:电路分析仿真软件 编辑:程序博客网 时间:2024/06/05 16:32
转载请注明来自柳大的CSDN博客:blog.csdn.net/poechant
- 作者:柳大·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.gztar zxvf faac-1.28.tar.gzcd faac-1.28./configuremakesudo 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 __cplusplusextern "C" {#endifchar *strcasestr(const char *haystack, const char *needle);#ifdef __cplusplus}#endif
修改后:
#ifdef __cplusplusextern "C++" {#endifconst 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
- AudioCoding.com - FAAC
- Dogfoot – 재밌는 개발
-
转载请注明来自柳大的CSDN博客:blog.csdn.net/poechant
0 0
- (转)音频编解码·实战篇(1)PCM转至AAC(AAC编码)
- 音频编解码·实战篇(1)PCM转至AAC(AAC编码)
- 音频编解码·实战篇(1)PCM转至AAC(AAC编码)
- 音频编解码·实战篇(1)PCM转至AAC(AAC编码)
- 音频编解码·实战篇(1)WAV转至AAC(AAC编码)
- 音频编解码·实战篇(1)WAV转至AAC(AAC编码)
- 音频编解码(使用faac库)--WAV转至AAC(AAC编码)
- 嵌入式linux:音频编解码PCM转至AAC
- FFmepg 音频编码(PCM数据编码成AAC android)
- ffmpeg实战教程(三)音频PCM采样为AAC,视频YUV编码为H264/HEVC
- aac(高级音频编码)
- aac (高级音频编码)
- 最简单的基于FFMPEG的音频编码器(PCM编码为AAC)
- 最简单的基于FFMPEG的音频编码器(PCM编码为AAC)
- 最简单的基于FFMPEG的音频编码器(PCM编码为AAC)
- 编解码学习笔记(五):Mpeg系列——AAC音频
- 各种音视频编解码学习详解(5)--Mpeg系列——AAC音频
- 编解码学习笔记(五):Mpeg系列——AAC音频
- Graham算法(计算凸包周长)
- 8 Things Programmers Can Do at Weekends
- 生活依然还要继续
- CF 86D Powerful array 【分块算法,n*sqrt(n)】
- android acra错误日志上报
- 音频编解码·实战篇(1)PCM转至AAC(AAC编码)
- oracle
- tomcat下面web应用发布路径配置( 即虚拟目录配置 )
- poj 3155 Hard Life 分数规划+最大权闭合图
- UVa 10258 - Contest Scoreboard
- java字符串反转相关算法
- 好多书的读书笔记
- github入门资料
- apache配置https协议