当前位置: 首页 > 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

相关文章:

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

1、README 前言 本demo是使用的开源项目faad2将aac数据解码成pcm数据。 a. 编译使用 faad2的编译&#xff1a;(faad2下载地址&#xff1a;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 …...

力扣 hot100 -- 多维动态规划

&#x1f447;woc&#xff0c;这不是最熟悉那种&#xff0c;记忆化 dfs 或者 普通的深度优先搜索&#xff1f;&#xff1f;都适用于二维地图&#x1f447; DFS&#xff08;深度优先搜索&#xff09;8种题型_dfs典型问题-CSDN博客 目录 &#x1f943;不同路径 &#x1f33c;最…...

[misc]-流量包-wireshark-icmp

wireshark打开&#xff0c;大部分都是icmp,查看data部分 提取data长度&#xff1a; tshark.exe -r 1.pcapng -T fields -e data.len > length.txt 使用python解析这个文件&#xff0c;剔除异常值&#xff0c;每8个取一个值&#xff0c;得到flag ds [] with open(length.tx…...

探索性数据分析:使用Python与Pandas库实现数据洞察

探索性数据分析&#xff1a;使用Python与Pandas库实现数据洞察 引言 在当今数据驱动的时代&#xff0c;数据分析已成为决策制定、策略规划和业务优化的关键环节。无论是商业智能、金融分析还是市场研究&#xff0c;数据分析都扮演着至关重要的角色。Pandas库作为Python生态系统…...

枚举的高阶用法之枚举里写方法以及注入spring的bean

1、前言 一般我们使用枚举都是用来定义一些常量。比如我们需要一个表示订单类(pc订单、手机订单)的常量,那我们就可以使用枚举来实现,如下: AllArgsConstructor public enum OrderTypeEnum{PC("PC", "电脑端"),PHONE("PHONE", "手机端&quo…...

游戏开发面试题2

网络游戏分为客户端和服务端&#xff0c;你能说说客户端和服务端都干了一些什么工作吗&#xff1f; 客户端&#xff08;Client&#xff09; 客户端是玩家直接交互的部分&#xff0c;主要负责用户界面、输入处理、渲染和部分逻辑处理。具体工作包括&#xff1a; 用户界面&…...

华为机试题-单车道汽车通行时间-Java

代码在最后面 1 题目描述 M&#xff08;1 ≤ M ≤ 20&#xff09;辆车需要在一条不能超车的单行道到达终点&#xff0c;起点到终点的距离为 N&#xff08;1 ≤ N ≤ 400&#xff09;。 速度快的车追上前车后&#xff0c;只能以前车的速度继续行驶&#xff0c;求最后一辆车到达…...

6-5,web3浏览器链接区块链(react+区块链实战)

6-5&#xff0c;web3浏览器链接区块链&#xff08;react区块链实战&#xff09; 6-5 web3浏览器链接区块链&#xff08;调用读写合约与metamask联动&#xff09; 6-5 web3浏览器链接区块链&#xff08;调用读写合约与metamask联动&#xff09; 这里就是浏览器端和智能合约的交…...

C# 多态性

C# 多态性 介绍 多态性是面向对象编程(OOP)的一个核心概念,它允许不同类的对象对同一消息做出响应,并产生不同的结果。在C#中,多态性主要通过继承、接口和虚方法来实现。本文将深入探讨C#中的多态性,包括其原理、实现方式以及在实际编程中的应用。 原理 多态性允许将…...

Visual Studio 安装程序无法执行修复或更新

一.问题场景 出现问题的场景&#xff1a;当你的VS已经安装但是无法在工具中下载新组件或者卸载了当时一直无法安装。 二.问题原因 如果计算机上的 Visual Studio 实例已损坏&#xff0c;则可能会出现此问题。 三.解决方法 如果之前尝试修复或更新 Visual Studio 失败&…...

C#与PLC通信——如何设置电脑IP地址

前言&#xff1a; 我们与PLC通过以太网通信时&#xff0c;首先要做的就是先设置好电脑的IP&#xff0c;这样才能实现上位机电脑与PLC之间的通信&#xff0c;并且电脑的ip地址和PLC的Ip地址要同处于一个网段&#xff0c;比如电脑的Ip地址为192.168.1.1&#xff0c;那么PLC的Ip地…...

Milvus 核心设计(1) ---- 数据一致性的等级及使用场景

目录 背景 Milvus的数据一致性 设置数据一致性等级 等级类型 PACELC定理 level 详细解释 Strong Bounded staleness Session Eventually 总结 背景 分布式上的可扩展性是个比较重要的concept。Chroma 核心之前写过了,他的最大优势在于轻量级且好用。Milvus相对Ch…...

EasyCVR视频技术:城市电力抢险的“千里眼”,助力抢险可视化

随着城市化进程的加速和电力需求的不断增长&#xff0c;电力系统的稳定运行对于城市的正常运转至关重要。然而&#xff0c;自然灾害、设备故障等因素常常导致电力中断&#xff0c;给城市居民的生活和企业的生产带来严重影响。在这种情况下&#xff0c;快速、高效的电力抢险工作…...

【Wamp】局域网设备访问WampServer | 使用域名访问Wamp | Wamp配置HTTPS

局域网设备访问WampServer 参考&#xff1a;https://www.jianshu.com/p/d431a845e5cb 修改Apache的httpd.conf文件 D:\Academic\Wamp\program\bin\apache\apache2.4.54.2\conf\httpd.conf 搜索 Require local 和Require all denied&#xff0c;改为Require all granted <…...

采用自动微分进行模型的训练

自动微分训练模型 简单代码实现&#xff1a; import torch import torch.nn as nn import torch.optim as optim# 定义一个简单的线性回归模型 class LinearRegression(nn.Module):def __init__(self):super(LinearRegression, self).__init__()self.linear nn.Linear(1, 1) …...

k8s怎么配置secret呢?

在Kubernetes中&#xff0c;配置Secret主要涉及到创建、查看和使用Secret的过程。以下是配置Secret的详细步骤和相关信息&#xff1a; ### 1. Secret的概念 * Secret是Kubernetes用来保存密码、token、密钥等敏感数据的资源对象。 * 这些敏感数据可以存放在Pod或镜像中&#x…...

算法篇 滑动窗口 leetcode 长度最小的子数组

长度最小的子数组 1. 题目描述2. 算法图分析2.1 暴力图解2.2 滑动窗口图解 3. 代码演示 1. 题目描述 2. 算法图分析 2.1 暴力图解 2.2 滑动窗口图解 3. 代码演示...

数据库作业d8

要求&#xff1a; 一备份 1 mysqldump -u root -p booksDB > booksDB_all_tables.sql 2 mysqldump -u root -p booksDB books > booksDB_books_table.sql 3 mysqldump -u root -p --databases booksDB test > booksDB_and_test_databases.sql 4 mysql -u roo…...

前后端数据交互设计到的跨域问题

前后端分离项目的跨域问题及解决办法 一、跨域简述 1、问题描述 这里前端vue项目的端口号为9000&#xff0c;后端springboot项目的端口号为8080 2、什么是跨域 当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域 当前页面url被请求页面url是否…...

非洲猪瘟监测设备的作用是什么?

TH-H160非洲猪瘟监测设备的主要作用是迅速、准确地检测出非洲猪瘟病毒&#xff0c;从而帮助控制和预防疫情的扩散。这些设备利用先进的生物传感技术和PCR分子生物学方法&#xff0c;能够在极短的时间内提供精确的检测结果<sup>1</sup><sup>2</sup><…...

移动硬盘损坏无法读取?专业恢复策略全解析

在数字化信息爆炸的今天&#xff0c;移动硬盘作为我们存储和传输大量数据的重要工具&#xff0c;其安全性和稳定性直接关系到个人与企业的数据安全。然而&#xff0c;当移动硬盘突然遭遇损坏&#xff0c;无法正常读取时&#xff0c;我们该如何应对&#xff1f;本文将深入探讨移…...

神经网络以及简单的神经网络模型实现

神经网络基本概念&#xff1a; 神经元&#xff08;Neuron&#xff09;&#xff1a; 神经网络的基本单元&#xff0c;接收输入&#xff0c;应用权重并通过激活函数生成输出。 层&#xff08;Layer&#xff09;&#xff1a; 神经网络由多层神经元组成。常见的层包括输入层、隐藏层…...

java中压缩文件的解析方式(解析文件)

背景了解&#xff1a;java中存在IO流的方式&#xff0c;支持我们对文件进行读取&#xff08;Input&#xff0c;从磁盘到内存&#xff09;或写入&#xff08;output&#xff0c;从内存到磁盘&#xff09;&#xff0c;那么我们在面对 “zip”格式或者 “rar” 格式的压缩文件&…...

巧用 VScode 网页版 IDE 搭建个人笔记知识库!

[ 知识是人生的灯塔&#xff0c;只有不断学习&#xff0c;才能照亮前行的道路 ] 巧用 VScode 网页版 IDE 搭建个人笔记知识库! 描述&#xff1a;最近自己在腾讯云轻量云服务器中部署了一个使用在线 VScode 搭建部署的个人Markdown在线笔记&#xff0c;考虑到在线 VScode 支持终…...

Jupyter Lab 使用

Jupyter Lab 使用详解 Jupyter Lab 是一个基于 Web 的交互式开发环境&#xff0c;提供了比 Jupyter Notebook 更加灵活和强大的用户界面和功能。以下是使用 Jupyter Lab 的详细指南&#xff0c;包括安装、基本使用、设置根目录和扩展功能等内容。 一、Jupyter Lab 安装与启动…...

MyBatis where标签内嵌foreach标签查询报错‘缺失右括号‘或‘命令未正确结束‘

MyBatis <where>标签内嵌<foreach>标签查询报错’缺失右括号’或’命令未正确结束’ <where>标签内嵌<foreach>标签 截取一段脱敏xml&#xff0c;写明大概意思 <select id"queryLogByIds" resultMap"BaseResultMap">SELE…...

重生奇迹MU 群战王牌

圣导师是重生奇迹MU游戏中八大职业之一&#xff0c;拥有风度翩翩、潇洒自如的形象和神一样的实力。无论是刷怪、PK、打boss还是混战&#xff0c;圣导师都表现出压制其他职业的强大气势。因此&#xff0c;这个职业在游戏中备受欢迎&#xff0c;人气非常高。 实力强大的二代隐藏…...

SpinalHDL之VHDL 和 Verilog 生成

本文作为SpinalHDL学习笔记第十六篇&#xff0c;记录使用SpinalHDL代码生成Verilog/VHDL代码的方法。 SpinalHDL学习笔记总纲链接如下&#xff1a; SpinalHDL 学习笔记_spinalhdl blackbox-CSDN博客 目录&#xff1a; 1.从 SpinalHDL 组件生成 VHDL 和 Verilog 2.生成的 VHD…...

c语言中的字符串函数

strstr函数 函数介绍 strstr 用于在一个字符串中查找另一个字符串的首次出现。 我们来看这个函数的参数名字&#xff1a;haysytack&#xff08;干草堆&#xff09;needle&#xff08;针&#xff09;,这个其实就是外国的一句谚语&#xff1a;在干草堆中找一根针&#xff0c;就…...

[AI 大模型] 百度 文心一言

文章目录 [AI 大模型] 百度 文心一言简介模型架构发展新技术和优势API 代码示例 [AI 大模型] 百度 文心一言 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0DwAIh0T-1720667576892)(https://i-blog.csdnimg.cn/direct/283919e5d78b4951ba1ade5dcfc…...