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

MPNet:旋转机械轻量化故障诊断模型详解python代码复现

目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录

ASP.NET Core 是一个跨平台的开源框架&#xff0c;用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录&#xff0c;以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

【力扣数据库知识手册笔记】索引

索引 索引的优缺点 优点1. 通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度&#xff08;创建索引的主要原因&#xff09;。3. 可以加速表和表之间的连接&#xff0c;实现数据的参考完整性。4. 可以在查询过程中&#xff0c;…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元&#xff08;GRU&#xff09;长短期记忆神经网络&#xff08;LSTM&#xff09…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

【分享】推荐一些办公小工具

1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由&#xff1a;大部分的转换软件需要收费&#xff0c;要么功能不齐全&#xff0c;而开会员又用不了几次浪费钱&#xff0c;借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...

Python Einops库:深度学习中的张量操作革命

Einops&#xff08;爱因斯坦操作库&#xff09;就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库&#xff0c;用类似自然语言的表达式替代了晦涩的API调用&#xff0c;彻底改变了深度学习工程…...

Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?

Pod IP 的本质与特性 Pod IP 的定位 纯端点地址&#xff1a;Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址&#xff08;如 10.244.1.2&#xff09;无特殊名称&#xff1a;在 Kubernetes 中&#xff0c;它通常被称为 “Pod IP” 或 “容器 IP”生命周期&#xff1a;与 Pod …...

Linux 下 DMA 内存映射浅析

序 系统 I/O 设备驱动程序通常调用其特定子系统的接口为 DMA 分配内存&#xff0c;但最终会调到 DMA 子系统的dma_alloc_coherent()/dma_alloc_attrs() 等接口。 关于 dma_alloc_coherent 接口详细的代码讲解、调用流程&#xff0c;可以参考这篇文章&#xff0c;我觉得写的非常…...