当前位置:网站首页>音频编解码,利用FAAC来实现AAC编码
音频编解码,利用FAAC来实现AAC编码
2022-08-11 03:09:00 【音视频开发老舅】
这里利用FAAC来实现AAC编码。另外,WAV的数据段是PCM,代码会出现很多PCM缩写。
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,后面编译的时候会用到。
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数据的最大长度
);
本文福利, C++音视频学习资料包、技术视频,内容包括(音视频开发,面试题,FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,srs)↓↓↓↓↓↓见下面↓↓文章底部点击领取↓↓
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文件了,听听看吧!~
本文福利, C++音视频学习资料包、技术视频,内容包括(音视频开发,面试题,FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,srs)↓↓↓↓↓↓见下面↓↓文章底部点击领取↓↓
边栏推荐
- A surviving spouse of the opposite sex within large turn paragraph, what for
- 言简意赅,说说 @Transactional 在项目中的使用
- 架构篇(二)架构的复杂度来源
- 索引的创建、查看、删除
- 二叉树相关代码题【较全】C语言
- 互换性与测量技术-公差原则与选用方法
- pathman_config、pathman_config_params 删除后,如何重建?
- 关于地图GIS开发事项的一次实践整理(上)
- Docker 链接sqlserver时出现en-us is an invalid culture错误解决方案
- CSAPP Data Lab
猜你喜欢

【idea 报错】 无效的目标发行版:17 的解决参考

互换性测量技术-几何误差

DOM树的遍历-----修改样式,选择元素,创建和删除节点

CSDN blog replacement skin

音视频开发,为什么要学习FFmpeg?应该怎么入手FFmpeg学习?

Environment configuration of ESP32 (arduino arduino2.0 VScode platform which is easy to use?)

AI+医疗:使用神经网络进行医学影像识别分析

入职数字ic设计后的一些工作心得

SQL 开发的十个高级概念

添加用户报错useradd: cannot open /etc/passwd
随机推荐
否定语义转化层
Add user error useradd: cannot open /etc/passwd
Some work experience after joining the digital ic design
MySQL权限控制、分区表、快速复制表
获取链表长度
Goodbye Chengdu paper invoices!The issuance of electronic invoices for accommodation expenses will soon completely replace the invoices of hotels, catering and gas stations
索引的创建、查看、删除
正式发布丨VS Code 1.70
增加对 Textbundle 的支持
AI+Medical: Using Neural Networks for Medical Image Recognition and Analysis
入职数字ic设计后的一些工作心得
Entity to Vo conversion
redis学习五redis的持久化RDB,fork,copyonwrite,AOF,RDB&AOF混合使用
互换性与测量技术——表面粗糙度选取和标注方法
《如何戒掉坏习惯》读书笔记
js中的this问题
AI+医疗:使用神经网络进行医学影像识别分析
Ten Advanced Concepts of SQL Development
Ninjutsu_v3_08_2020-安全渗透系统安装
输入起始位置,终止位置截取链表