当前位置: 首页 > news >正文

音频demo:使用faad2将AAC数据解码出PCM数据

1、README

前言

本demo是使用的开源项目faad2将aac数据解码成pcm数据。

a. 编译使用

faad2的编译:(faad2下载地址:https://sourceforge.net/projects/faac/files/faad2-src/faad2-2.8.0/)

tar xzf faad2-2.8.8.tar.gz
cd faad2-2.8.8/
./configure --prefix=$PWD/_install
make
make install

demo的编译使用:

$ make clean && make
$ 
$ ./aac2pcm 
Usage:./aac2pcm <in aac file> <out pcm file>
Examples:./aac2pcm ./audio/test1_44100_stereo.aac  out1_44100_16bit_stereo.pcm./aac2pcm ./audio/test2_8000_mono.aac     out2_16000_16bit_stereo.pcm  # output [samplerate] and [channels] will be auto configured.
b. 参考文章
  • 用faad解码AAC(ADTS封装)_gavinr的博客-CSDN博客_faad解码aac
c. demo目录架构
$ tree
.
├── aac_adts.c
├── aac_adts.h
├── audio
│   ├── out1_44100_16bit_stereo.pcm
│   ├── out2_16000_16bit_stereo.pcm
│   ├── test1_44100_stereo.aac
│   └── test2_8000_mono.aac
├── docs
│   └── 用faad解码AAC(ADTS封装)_gavinr的博客-CSDN博客_faad解码aac.mhtml
├── include
│   ├── faad.h
│   └── neaacdec.h
├── lib
│   └── libfaad.a
├── main.c
├── Makefile
└── README.md

2、主要代码片段

aac_adts.c
#include "aac_adts.h"int getAdtsFrame(FILE *fp, uint8_t *pAdtsFrameData, T_AdtsHeader *ptAdtsHeaderInfo)
{uint32_t readBytes = 0;if(!fp || !pAdtsFrameData || !ptAdtsHeaderInfo)return -1;// ADTS header size is AAC_ADTS_HEADER_SIZE(=7) bytesreadBytes = fread(pAdtsFrameData, 1, AAC_ADTS_HEADER_SIZE, fp);if(readBytes <= 0)return -2;ptAdtsHeaderInfo->syncword              = (pAdtsFrameData[0] << 4 ) | (pAdtsFrameData[1]  >> 4);ptAdtsHeaderInfo->id                    = (pAdtsFrameData[1] & 0x08) >> 3;ptAdtsHeaderInfo->layer                 = (pAdtsFrameData[1] & 0x06) >> 1;ptAdtsHeaderInfo->protection_absent     =  pAdtsFrameData[1] & 0x01;ptAdtsHeaderInfo->profile               = (pAdtsFrameData[2] & 0xc0) >> 6;ptAdtsHeaderInfo->sampling_freq_index   = (pAdtsFrameData[2] & 0x3c) >> 2;ptAdtsHeaderInfo->private_bit           = (pAdtsFrameData[2] & 0x02) >> 1;ptAdtsHeaderInfo->channel_configuration = (((pAdtsFrameData[2] & 0x01) << 2) | ((pAdtsFrameData[3] & 0xc0) >> 6));ptAdtsHeaderInfo->original_copy         = (pAdtsFrameData[3] & 0x20) >> 5;ptAdtsHeaderInfo->home                  = (pAdtsFrameData[3] & 0x10) >> 4;ptAdtsHeaderInfo->copyright_identification_bit   = (pAdtsFrameData[3] & 0x08) >> 3;ptAdtsHeaderInfo->copyright_identification_start = (pAdtsFrameData[3] & 0x04) >> 2;ptAdtsHeaderInfo->aac_frame_length = ((pAdtsFrameData[3] & 0x03) << 11) |((pAdtsFrameData[4] & 0xFF) << 3) |((pAdtsFrameData[5] & 0xE0) >> 5);ptAdtsHeaderInfo->adts_buffer_fullness = ((pAdtsFrameData[5] & 0x1f) << 6 | (pAdtsFrameData[6] & 0xfc) >> 2);ptAdtsHeaderInfo->number_of_raw_data_blocks_in_frame = (pAdtsFrameData[6] & 0x03);if (ptAdtsHeaderInfo->syncword != 0xFFF)return -3;/* read the remaining frame of ADTS data outside the AAC_ADTS_HEADER_SIZE(=7) bytes header,* and it should be written after offsetting the header by AAC_ADTS_HEADER_SIZE(=7) bytes*/readBytes = fread(pAdtsFrameData + AAC_ADTS_HEADER_SIZE, 1, ptAdtsHeaderInfo->aac_frame_length - AAC_ADTS_HEADER_SIZE, fp);if(readBytes <= 0)return -4;return 0;
}
aac_adts.h
#ifndef __AAC_ADTS_H__
#define __AAC_ADTS_H__#include <stdio.h>
#include <stdint.h>#define AAC_ADTS_HEADER_SIZE 	(7)#define MAX_ADTS_SIZE 			(1024) /* 1K Bytes */typedef enum{MPEG_4 = 0x0,MPEG_2 = 0x1,
}aac_id_t;typedef enum{SFI_96000 = 0x0,SFI_88200 = 0x1,SFI_64000 = 0x2,SFI_48000 = 0x3,SFI_44100 = 0x4,SFI_32000 = 0x5,SFI_24000 = 0x6,SFI_22050 = 0x7,SFI_16000 = 0x8,SFI_12000 = 0x9,SFI_11025 = 0xa,SFI_8000  = 0xb,SFI_7350  = 0xc,SFI_ERROR = 0xd,
}sampling_freq_index_t;/* AAC(ADTS) Header element member.* [Note: It is not stored as defined type size!!!]*/
typedef struct{/* fixed header */uint32_t syncword;              // 12bit  '1111 1111 1111' is stand by ADTS frameuint32_t id;                    // 1 bit  0 for MPEG-4, 1 for MPEG-2uint32_t layer;                 // 2 bit  always '00'uint32_t protection_absent;     // 1 bit  1 not crc, 0 have crc 1uint32_t profile;               // 2 bit  AAC profile, '01' for AAC-LCuint32_t sampling_freq_index;   // 4 bit  reference to 'sampling_freq_index_t'uint32_t private_bit;           // 1 bit  always '0'uint32_t channel_configuration; // 3 bit  channels countuint32_t original_copy;         // 1 bit  always '0'uint32_t home;                  // 1 bit/* varible header */uint32_t copyright_identification_bit;   // 1 bit  always '0'uint32_t copyright_identification_start; // 1 bit  always '0'uint32_t aac_frame_length;               // 13bit  length of [adts header] + [adts data]uint32_t adts_buffer_fullness;           // 11bit  0x7FF stand by varible bit rateuint32_t number_of_raw_data_blocks_in_frame;  // 2 bit  always '00', number of AAC Frames(RDBs) in ADTS frame minus 1
}T_AdtsHeader, *PT_AdtsHeader;/************************************************************************* function describe: get one frame aac(adts, include adts header) from*                    aac file.* params:*   [fp]: aac file handler.(in)*   [pAdtsFrameData]: the function will fill the aac data in it, must be*                     alloced memory before call this function.(out)*   [ptAdtsHeaderInfo]: AAC-ADTS header information in this frame.(out)* return: 0-success  other-error************************************************************************/
int getAdtsFrame(FILE *fp, uint8_t *pAdtsFrameData, T_AdtsHeader *ptAdtsHeaderInfo);#endif /*  __AAC_ADTS_H__ */
main.c
#include <stdio.h>
#include <stdlib.h>#include "aac_adts.h"
#include "faad.h"#define MAX_DEC_SIZE   (128 * 1024)int main(int argc, char *argv[])
{int ret = -1;FILE *fpAAC = NULL;FILE *fpPCM = NULL;unsigned char *aacBuf = NULL;unsigned char *pcmPtr = NULL;unsigned char channels = 0;unsigned long sampleRate = 0;T_AdtsHeader adtsHeader = {};NeAACDecHandle aacDecHandler = 0;NeAACDecFrameInfo aacDecFrameInfo = {};uint32_t audioSampleRate = -1;if(argc != 3){printf("Usage:\n""    %s <in aac file> <out pcm file>\n""Examples:\n""    %s ./audio/test1_44100_stereo.aac  out1_44100_16bit_stereo.pcm\n""    %s ./audio/test2_8000_mono.aac     out2_16000_16bit_stereo.pcm  # output [samplerate] and [channels] will be auto configured.\n",argv[0], argv[0], argv[0]);return -1;}/* open file */fpAAC = fopen(argv[1], "rb");fpPCM = fopen(argv[2], "wb");if(!fpAAC || !fpPCM){printf("[%s:%d] open <%s> or <%s> file failed!\n", __FUNCTION__, __LINE__, argv[1], argv[2]);goto exit;}/* alloc memory */aacBuf = (unsigned char *)malloc(MAX_DEC_SIZE);if(!aacBuf){printf("[%s:%d] alloc memory for aacBuf failed!\n", __FUNCTION__, __LINE__);goto exit;}/* aac decode 1/4: open aac decoder */aacDecHandler = NeAACDecOpen();/* use to configure decoder params */ret = getAdtsFrame(fpAAC, aacBuf, &adtsHeader);if(ret < 0){if(ret == -2){printf("aac file end!\n");goto exit;}else{printf("[%s:%d] get adts frame failed with %d!\n", __FUNCTION__, __LINE__, ret);goto exit;}}else{fseek(fpAAC, 0, SEEK_SET); // reset/* aac decode 2/4: init aac decoder params */NeAACDecInit(aacDecHandler, aacBuf, adtsHeader.aac_frame_length, &sampleRate, &channels);printf("\e[32m>>> will be decoded output with [samplerate: %lu], [channels: %d]<<<\e[0m\n", sampleRate, channels);}while(1){ret = getAdtsFrame(fpAAC, aacBuf, &adtsHeader);if(ret < 0){if(ret == -2){printf("aac file end!\n");break;}else{printf("[%s:%d] get adts frame failed with %d!\n", __FUNCTION__, __LINE__, ret);goto exit;}}//printf("get one adts frame with size: %d\n", adtsHeader.aac_frame_length);/* aac decode 3/4: decode */pcmPtr = (unsigned char*)NeAACDecDecode(aacDecHandler, &aacDecFrameInfo, aacBuf, adtsHeader.aac_frame_length/* include header */);if(aacDecFrameInfo.error > 0){printf("[%s:%d] %s\n", __FUNCTION__, __LINE__, NeAACDecGetErrorMessage(aacDecFrameInfo.error));goto exit;}else if(pcmPtr && aacDecFrameInfo.samples > 0){printf("<in> [aac frame size: %lu] [header type: %s] ""[profile: %s]    |    <out> [samplerate: %lu] [samples cnt: %lu] [channels: %d] \n",aacDecFrameInfo.bytesconsumed, aacDecFrameInfo.header_type == 2 ? "ADTS" : "Other", aacDecFrameInfo.object_type == 2 ? "LC" : "Other", aacDecFrameInfo.samplerate,aacDecFrameInfo.samples,aacDecFrameInfo.channels);fwrite(pcmPtr, 1, aacDecFrameInfo.samples * aacDecFrameInfo.channels, fpPCM);}else{printf("[%s:%d] Unknown decode error!\n", __FUNCTION__, __LINE__);}}/* aac decode 1/4: close aac decoder */NeAACDecClose(aacDecHandler);printf("\e[32mSuccess!\e[0m\n");exit:if(fpAAC) fclose(fpAAC);if(fpPCM) {fflush(fpPCM); fclose(fpPCM);}if(aacBuf) free(aacBuf);return 0;
}

3、demo下载地址(任选一个)

  • https://download.csdn.net/download/weixin_44498318/89525143

  • https://gitee.com/linriming/audio_aac2pcm_with_faad2

  • https://github.com/linriming20/audio_aac2pcm_with_faad2.git

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 电子设备常用的胶水有哪些?
  • sdbusplus:将文件描述符作为method的返回值
  • React-native优质开源项目
  • VsCode崩溃无法打开解决办法
  • 【Spring Boot】统一异常处理
  • 从零到一:构建股票预测模型的Python实战教程
  • Redis-Redis可视化工具Redis Insight下载及安装
  • Android TV跨平台开发心得
  • DataExcelServer局域网文件共享服务器增加两个函数
  • 【Android高级UI】计算不规则图形面积
  • 【人工智能】-- 法律与伦理
  • 对数据采集、数据存储和数据处理流程
  • 字节码编程javassist之增加异常捕获
  • 如何安全隐藏IP地址,防止网络攻击?
  • Open3D 从体素网格构建八叉树
  • 【跃迁之路】【519天】程序员高效学习方法论探索系列(实验阶段276-2018.07.09)...
  • 【跃迁之路】【585天】程序员高效学习方法论探索系列(实验阶段342-2018.09.13)...
  • Angularjs之国际化
  • HashMap ConcurrentHashMap
  • HTML5新特性总结
  • webpack+react项目初体验——记录我的webpack环境配置
  • 从零搭建Koa2 Server
  • 多线程事务回滚
  • 基于HAProxy的高性能缓存服务器nuster
  • 两列自适应布局方案整理
  • 模仿 Go Sort 排序接口实现的自定义排序
  • 实习面试笔记
  • 算法系列——算法入门之递归分而治之思想的实现
  • 它承受着该等级不该有的简单, leetcode 564 寻找最近的回文数
  • 为视图添加丝滑的水波纹
  • 小程序开发中的那些坑
  • 做一名精致的JavaScripter 01:JavaScript简介
  • 说说我为什么看好Spring Cloud Alibaba
  • ​​​​​​​​​​​​​​Γ函数
  • ​Java并发新构件之Exchanger
  • ​LeetCode解法汇总518. 零钱兑换 II
  • ​Spring Boot 分片上传文件
  • # Apache SeaTunnel 究竟是什么?
  • # windows 运行框输入mrt提示错误:Windows 找不到文件‘mrt‘。请确定文件名是否正确后,再试一次
  • # 移动硬盘误操作制作为启动盘数据恢复问题
  • #vue3 实现前端下载excel文件模板功能
  • ()、[]、{}、(())、[[]]等各种括号的使用
  • (1)虚拟机的安装与使用,linux系统安装
  • (Matalb回归预测)PSO-BP粒子群算法优化BP神经网络的多维回归预测
  • (solr系列:一)使用tomcat部署solr服务
  • (SpringBoot)第七章:SpringBoot日志文件
  • (超简单)使用vuepress搭建自己的博客并部署到github pages上
  • (二)十分简易快速 自己训练样本 opencv级联lbp分类器 车牌识别
  • (附源码)c#+winform实现远程开机(广域网可用)
  • (附源码)ssm考生评分系统 毕业设计 071114
  • (附源码)ssm码农论坛 毕业设计 231126
  • (蓝桥杯每日一题)平方末尾及补充(常用的字符串函数功能)
  • (一)u-boot-nand.bin的下载
  • (原創) 系統分析和系統設計有什麼差別? (OO)
  • (转)chrome浏览器收藏夹(书签)的导出与导入