这里利用FAAC来实现AAC编码。另外,WAV的数据段是PCM,代码会出现很多PCM缩写。
这里的安装过程是在 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,后面编译的时候会用到。
Prototype:
- faacEncHandle faacEncOpen // 返回一个FAAC的handle
- (
- unsigned long nSampleRate, // 采样率,单位是bps
- unsigned long nChannels, // 声道,1为单声道,2为双声道
- unsigned long &nInputSamples, // 传引用,得到每次调用编码时所应接收的原始数据长度
- unsigned long &nMaxOutputBytes // 传引用,得到每次调用编码时生成的AAC数据的最大长度
- );
-
本文福利, C++音视频学习资料包、技术视频,内容包括(音视频开发,面试题,FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,srs)↓↓↓↓↓↓见下面↓↓文章底部点击领取↓↓
Prototype:
获取编码器的配置:
- faacEncConfigurationPtr faacEncGetCurrentConfiguration // 得到指向当前编码器配置的指针
- (
- faacEncHandle hEncoder // FAAC的handle
- );
-
设定编码器的配置:
- int FAACAPI faacEncSetConfiguration
- (
- faacDecHandle hDecoder, // 此前得到的FAAC的handle
- faacEncConfigurationPtr config // FAAC编码器的配置
- );
-
Prototype:
- int faacEncEncode
- (
- faacEncHandle hEncoder, // FAAC的handle
- short *inputBuffer, // WAV原始数据
- unsigned int samplesInput, // 调用faacEncOpen时得到的nInputSamples值
- unsigned char *outputBuffer,// 至少具有调用faacEncOpen时得到的nMaxOutputBytes字节长度的缓冲区
- unsigned int bufferSize // outputBuffer缓冲区的实际大小
- );
-
Prototype
- void faacEncClose
- (
- faacEncHandle hEncoder // 此前得到的FAAC handle
- );
-
采样率,声道数(双声道还是单声道?),还有你的WAV的单个样本是8位的还是16位的?
faacEncOpen开启FAAC编码器后,得到了单次输入样本数nInputSamples和输出数据最大字节数nMaxOutputBytes;nInputSamples和nMaxOutputBytes,分别为WAV数据和将要得到的AAC数据创建缓冲区;faacEncGetCurrentConfiguration获取当前配置,修改完配置后,调用faacEncSetConfiguration设置新配置。调用faacEncEncode,该准备的刚才都准备好了,很简单。
关闭编码器,另外别忘了释放缓冲区,如果使用了文件流,也别忘记了关闭。
将WAV格式音频文件/home/michael/Development/testspace/in.wav转至AAC格式文件/home/michael/Development/testspace/out.aac。
- #include
- #include
-
- 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;
- }
-
将上述代码保存为“wav2aac.cpp”文件,然后编译:
g++ wav2aac.cpp -o wav2aac -L/usr/local/lib -lfaac -I/usr/local/include
运行:
./wav2aac
然后就生成了out.aac文件了,听听看吧!~
本文福利, C++音视频学习资料包、技术视频,内容包括(音视频开发,面试题,FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,srs)↓↓↓↓↓↓见下面↓↓文章底部点击领取↓↓