• 音频编解码,利用FAAC来实现AAC编码


    这里利用FAAC来实现AAC编码。另外,WAV的数据段是PCM,代码会出现很多PCM缩写。

    1 下载安装 FAAC

    这里的安装过程是在 Mac 和 Linux 上实现的,Windows可以类似参考。

    1. wget http://downloads.sourceforge.net/faac/faac-1.28.tar.gz
    2. tar zxvf faac-1.28.tar.gz
    3. cd faac-1.28
    4. ./configure
    5. make
    6. sudo make install

    如果才用默认的 configure 中的 prefix path,那么安装后的 lib 和 .h 文件分别在/usr/local/lib/usr/local/include,后面编译的时候会用到。

    2 FAAC API

    2.1 Open FAAC engine

    Prototype:

    1. faacEncHandle faacEncOpen // 返回一个FAAC的handle
    2. (
    3. unsigned long nSampleRate, // 采样率,单位是bps
    4. unsigned long nChannels, // 声道,1为单声道,2为双声道
    5. unsigned long &nInputSamples, // 传引用,得到每次调用编码时所应接收的原始数据长度
    6. unsigned long &nMaxOutputBytes // 传引用,得到每次调用编码时生成的AAC数据的最大长度
    7. );

    本文福利, C++音视频学习资料包、技术视频,内容包括(音视频开发,面试题,FFmpeg webRTC rtmp hls rtsp ffplay srs↓↓↓↓↓↓见下面↓↓文章底部点击领取↓↓

    2.2 Get/Set encoding configuration

    Prototype:

    获取编码器的配置:

    1. faacEncConfigurationPtr faacEncGetCurrentConfiguration // 得到指向当前编码器配置的指针
    2. (
    3. faacEncHandle hEncoder // FAAC的handle
    4. );

    设定编码器的配置:

    1. int FAACAPI faacEncSetConfiguration
    2. (
    3. faacDecHandle hDecoder, // 此前得到的FAAC的handle
    4. faacEncConfigurationPtr config // FAAC编码器的配置
    5. );

    2.3 Encode

    Prototype:

    1. int faacEncEncode
    2. (
    3. faacEncHandle hEncoder, // FAAC的handle
    4. short *inputBuffer, // WAV原始数据
    5. unsigned int samplesInput, // 调用faacEncOpen时得到的nInputSamples值
    6. unsigned char *outputBuffer,// 至少具有调用faacEncOpen时得到的nMaxOutputBytes字节长度的缓冲区
    7. unsigned int bufferSize // outputBuffer缓冲区的实际大小
    8. );

    2.4 Close FAAC engine

    Prototype

    1. void faacEncClose
    2. (
    3. faacEncHandle hEncoder // 此前得到的FAAC handle
    4. );

    3 流程

    3.1 做什么准备?

    采样率,声道数(双声道还是单声道?),还有你的WAV的单个样本是8位的还是16位的?

    3.2 开启FAAC编码器,做编码前的准备

    1. 调用faacEncOpen开启FAAC编码器后,得到了单次输入样本数nInputSamples和输出数据最大字节数nMaxOutputBytes
    2. 根据nInputSamplesnMaxOutputBytes,分别为WAV数据和将要得到的AAC数据创建缓冲区;
    3. 调用faacEncGetCurrentConfiguration获取当前配置,修改完配置后,调用faacEncSetConfiguration设置新配置。

    3.3 开始编码

    调用faacEncEncode,该准备的刚才都准备好了,很简单。

    3.4 善后

    关闭编码器,另外别忘了释放缓冲区,如果使用了文件流,也别忘记了关闭。

    4 测试程序

    4.1 完整代码

    WAV格式音频文件/home/michael/Development/testspace/in.wav转至AAC格式文件/home/michael/Development/testspace/out.aac

    1. #include
    2. #include
    3. typedef unsigned long ULONG;
    4. typedef unsigned int UINT;
    5. typedef unsigned char BYTE;
    6. typedef char _TCHAR;
    7. int main(int argc, _TCHAR* argv[])
    8. {
    9. ULONG nSampleRate = 11025; // 采样率
    10. UINT nChannels = 1; // 声道数
    11. UINT nPCMBitSize = 16; // 单样本位数
    12. ULONG nInputSamples = 0;
    13. ULONG nMaxOutputBytes = 0;
    14. int nRet;
    15. faacEncHandle hEncoder;
    16. faacEncConfigurationPtr pConfiguration;
    17. int nBytesRead;
    18. int nPCMBufferSize;
    19. BYTE* pbPCMBuffer;
    20. BYTE* pbAACBuffer;
    21. FILE* fpIn; // WAV file for input
    22. FILE* fpOut; // AAC file for output
    23. fpIn = fopen("/home/michael/Development/testspace/in.wav", "rb");
    24. fpOut = fopen("/home/michael/Development/testspace/out.aac", "wb");
    25. // (1) Open FAAC engine
    26. hEncoder = faacEncOpen(nSampleRate, nChannels, &nInputSamples, &nMaxOutputBytes);
    27. if(hEncoder == NULL)
    28. {
    29. printf("[ERROR] Failed to call faacEncOpen()\n");
    30. return -1;
    31. }
    32. nPCMBufferSize = nInputSamples * nPCMBitSize / 8;
    33. pbPCMBuffer = new BYTE [nPCMBufferSize];
    34. pbAACBuffer = new BYTE [nMaxOutputBytes];
    35. // (2.1) Get current encoding configuration
    36. pConfiguration = faacEncGetCurrentConfiguration(hEncoder);
    37. pConfiguration->inputFormat = FAAC_INPUT_16BIT;
    38. // (2.2) Set encoding configuration
    39. nRet = faacEncSetConfiguration(hEncoder, pConfiguration);
    40. for(int i = 0; 1; i++)
    41. {
    42. // 读入的实际字节数,最大不会超过nPCMBufferSize,一般只有读到文件尾时才不是这个值
    43. nBytesRead = fread(pbPCMBuffer, 1, nPCMBufferSize, fpIn);
    44. // 输入样本数,用实际读入字节数计算,一般只有读到文件尾时才不是nPCMBufferSize/(nPCMBitSize/8);
    45. nInputSamples = nBytesRead / (nPCMBitSize / 8);
    46. // (3) Encode
    47. nRet = faacEncEncode(
    48. hEncoder, (int*) pbPCMBuffer, nInputSamples, pbAACBuffer, nMaxOutputBytes);
    49. fwrite(pbAACBuffer, 1, nRet, fpOut);
    50. printf("%d: faacEncEncode returns %d\n", i, nRet);
    51. if(nBytesRead <= 0)
    52. {
    53. break;
    54. }
    55. }
    56. // (4) Close FAAC engine
    57. nRet = faacEncClose(hEncoder);
    58. delete[] pbPCMBuffer;
    59. delete[] pbAACBuffer;
    60. fclose(fpIn);
    61. fclose(fpOut);
    62. //getchar();
    63. return 0;
    64. }

    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↓↓↓↓↓↓见下面↓↓文章底部点击领取↓↓

  • 相关阅读:
    Kafka入门04——原理分析
    快速理解二分查找算法,附java代码实现
    基于双级阈值及过零率的语音激活检测(VAD)
    2023年IB生物有什么变化?
    Lab【1】:Blitz
    ⑧电子产品拆解分析-1拖4USB拓展坞
    设计模式篇---桥接模式
    SpringCloud feign 的三种超时时间配置
    java计算机毕业设计花卉网站源码+mysql数据库+系统+lw文档+部署
    计算机操作系统学习(一)引言
  • 原文地址:https://blog.csdn.net/m0_60259116/article/details/126271383