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

【音视频 | AAC】AAC编码库faac介绍、使用步骤、例子代码

😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀
🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C++、数据结构、音视频🍭
🤣本文内容🤣:🍭介绍faac编码库的使用 🍭
⏰发布时间⏰: 2025-03-05 18:47:37

本文未经允许,不得转发!!!

目录

  • 🎄一、概述
  • 🎄二、下载、编译、交叉编译
    • ✨2.1 faac 下载
    • ✨2.2 faac 在Ubuntu下编译
    • ✨2.3 faac 交叉编译
  • 🎄三、faac 编码库使用流程
  • 🎄四、faac 编码的例子代码
  • 🎄五、总结


在这里插入图片描述

在这里插入图片描述

🎄一、概述

faac 的全称是 Freeware Advanced Audio (AAC) Coder,faac 是一个用于将原始音频数据(如 PCM 格式)编码为 AAC 格式的开源库。它实现了 AAC 编码算法,能够对音频信号进行高效的压缩,同时尽可能保留音频的原始质量。FAAC 提供了简单易用的 API,方便开发者在不同的应用程序中集成 AAC 编码功能。

faac 支持多种 AAC 音频格式,包括 LC - AAC(Low Complexity AAC)、HE - AAC(High Efficiency AAC)、HE - AAC v2 、MAIN 、 LTP等。这使得开发者可以根据不同的应用需求选择合适的编码标准,以平衡音频质量和文件大小。例如,在对音频质量要求较高且带宽充足的场景下,可以选择 LC - AAC;而在带宽有限的情况下,HE - AAC 或 HE - AAC v2 则能提供更好的压缩比。


在这里插入图片描述

🎄二、下载、编译、交叉编译

✨2.1 faac 下载

faac 的源码在Github托管,下载地址:https://github.com/knik0/faac/tags。本文下载的是倒数第二个版本:faac-1_30.tar.gz,见下图。如果GitHub访问不了可以点击这个链接下载:https://download.csdn.net/download/wkd_007/90456911
在这里插入图片描述


✨2.2 faac 在Ubuntu下编译

这个小节介绍 faac 的源码在 Ubuntu 18.04 系统下编译的步骤:

  • 将源码解压缩

    tar zxf faac-1_30.tar.gz
    
  • 进入源码目录,执行下面命令生成Makefile:

    cd faac-1_30/
    ./bootstrap
    ./configure --prefix=`pwd`/../result_gcc
    
  • 执行make 、make install

    make
    make install
    

编译成功后,会在源码目录的上一级目录生成一个result_gcc目录,里面就是我们的编译结果。


✨2.3 faac 交叉编译

这个小节介绍 faac 的源码在 Ubuntu 18.04 系统下使用 aarch64-mix210-linux-gcc 交叉编译的步骤:

  • 将源码解压缩
    tar zxf faac-1_30.tar.gz
    
  • 进入源码目录,执行下面命令生成Makefile:
    cd faac-1_30/
    ./bootstrap
    ./configure --prefix=`pwd`/../result_mix210 --host=aarch64-mix210-linux CC=aarch64-mix210-linux-gcc
    
  • 执行make 、make install
    make
    make install
    

编译成功后,会在源码目录的上一级目录生成一个result_mix210目录,里面就是我们的编译结果。


在这里插入图片描述

🎄三、faac 编码库使用流程

在 faac 源码里有一个pdf文件,介绍了 faac 库的使用,文件路径:faac-1_30\docs\libfaac.pdf,文件介绍了faac常用的的API函数和简单使用流程,感兴趣的可以自己去看,下面是我总结的使用流程:

  • 1、打开 FAAC 编码器句柄:faacEncOpen

    faacEncHandle pFaacEncHandle = faacEncOpen(u64PcmSampleRate, u32PcmChannels, &u64PcmInSampleCnt, &u64AacOutMaxBytes);
    
  • 2、设置编码器的配置信息

    pFaacEncConf = faacEncGetCurrentConfiguration(pFaacEncHandle);
    ...
    // 设置编码器的配置信息
    faacEncSetConfiguration(pFaacEncHandle, pFaacEncConf);
    
  • 3、调用 faacEncEncode()对数据进行编码

    s32EncAacBytes = faacEncEncode(pFaacEncHandle, (int32_t*)pu8PcmInBuf, u32PcmInSampleCnt, 
    													pu8AacEncBuf, (unsigned int)u64AacOutMaxBytes);
    
  • 4、关闭 FAAC 编码器句柄

    /* 用完了就关闭编码器 */
    faacEncClose(pFaacEncHandle);
    

在这里插入图片描述

🎄四、faac 编码的例子代码

下面是根据流程写的例子,保存后,执行 gcc pcm2aac.c -I result_gcc/include/ result_gcc/lib/libfaac.a -lm 编译。
代码来自:音频demo:使用faac将PCM数据编码成aac数据

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>


#include "faac.h"


//#define DEBUG(fmt, args...)
#define DEBUG(fmt, args...) 	printf(fmt, ##args)


void print_usage(const char *process)
{
	printf("sample: \n"
		   "\t %s -h\n"
		   "\t %s --help\n"
		   "\t %s -i ./audio/test_8000_16_1.pcm -r 8000 -b 16 -c 1 -o out_8khz_1ch.aac\n"
		   "\t %s --input_pcmfile=./audio/test_44100_16_2.pcm --sample_rate=44100 --sample_bits=16 --channels=2 --output_aacfile=out_44.1khz_2ch.aac\n",
		   process, process, process, process);
}


int main(int argc, char *argv[])
{
	/* 输入/输出文件 */
	FILE *fpPcm = NULL;
	FILE *fpAac = NULL;
	char pcmFileName[128] = {0};
	char aacFileName[128] = {0};

	/* PCM参数 */
	unsigned long u64PcmSampleRate = 0; // 采样率
	unsigned int  u32PcmSampleBits = 0; // 采样位数
	unsigned int  u32PcmChannels   = 0; // 声道数

	/* aac编码器相关 */
	faacEncHandle           pFaacEncHandle = NULL;
	faacEncConfigurationPtr pFaacEncConf   = NULL;

	/* 编码相关参数 */
	unsigned long u64PcmInSampleCnt = 0; // 打开编码器时传出的参数,编码传入的PCM采样数(不是字节)
	unsigned long u64AacOutMaxBytes = 0; // 打开编码器时传出的参数,编码传出最大字节数
	unsigned char *pu8PcmInBuf   = NULL; // 读取pcm并传递进去编码的缓存指针,后面根据编码器传出参数malloc分配
	unsigned char *pu8AacEncBuf  = NULL; // 编码得到的aac缓存,后面根据编码器传出参数malloc分配


	/* 判断输入参数 */
	if(argc == 1)
	{
		print_usage(argv[0]);
		return -1;
	}	

	/* 解析命令行参数 */
	char option = 0;
	int option_index = 0;
	char *short_options = "hi:r:b:c:o:";
	struct option long_options[] =
	{
		{"help",          no_argument,       NULL, 'h'},
		{"input_pcmfile", required_argument, NULL, 'i'},
		{"sample_rate",   required_argument, NULL, 'r'},
		{"sample_bits",   required_argument, NULL, 'b'},
		{"channels",      required_argument, NULL, 'c'},
		{"output_aacfile",required_argument, NULL, 'o'},
		{NULL,            0,                 NULL,  0 },
	};
	while((option = getopt_long_only(argc, argv, short_options, long_options, &option_index)) != -1)
	{
		switch(option)
		{
			case 'h':
				print_usage(argv[0]);
				return 0;
			case 'i':
				strncpy(pcmFileName, optarg, 128);
				break;
			case 'r':
				u64PcmSampleRate = atoi(optarg);
				break;
			case 'c':
				u32PcmChannels = atoi(optarg);
				break;
			case 'b':
				u32PcmSampleBits = atoi(optarg);
				break;
			case 'o':
				strncpy(aacFileName, optarg, 128);
				break;
			defalut:
				printf("Unknown argument!\n");
				break;
		}
 	}
	printf("\n**************************************\n"
		   "input: \n"
		   "\t file name: %s\n"
		   "\t sample rate: %lu Hz\n"
		   "\t sample bits: %d bits\n"
		   "\t channels: %d\n"
		   "\t bits per second: %lu bps\n"
		   "output: \n"
		   "\t file name: %s\n"
		   "**************************************\n\n",
		   pcmFileName, u64PcmSampleRate, u32PcmSampleBits, u32PcmChannels,
		   u64PcmSampleRate*u32PcmSampleBits*u32PcmChannels, aacFileName);

	/* 先打开输入/输出文件 */
	fpPcm = fopen(pcmFileName, "rb");
	if(fpPcm == NULL)
	{
		char errMsg[128] = {0};
		snprintf(errMsg, 128, "open file(%s) error", pcmFileName);
		perror(errMsg);
		return -1;
	}
	fpAac = fopen(aacFileName, "wb");
	if(fpAac == NULL)
	{
		char errMsg[128] = {0};
		snprintf(errMsg, 128, "open file(%s) error", aacFileName);
		perror(errMsg);
		return -1;
	}

	/* AAC编码 1/6:传递参数进去打开编码器 */
	pFaacEncHandle = faacEncOpen(u64PcmSampleRate, u32PcmChannels, &u64PcmInSampleCnt, &u64AacOutMaxBytes);
	if(pFaacEncHandle == NULL)
	{
		printf("faacEncOpen(...) error!\n");
		goto error_exit;
	}

	/* 根据上面打开编码器传出的参数分配对应大小的缓存 */
	pu8PcmInBuf = (unsigned char*)malloc(u64PcmSampleRate*u32PcmSampleBits/8);
	pu8AacEncBuf = (unsigned char*)malloc(u64AacOutMaxBytes);

	/* AAC编码 2/6:设置编码器配置 */
	// 设置编码器配置 a/c: 先获取当前配置
	pFaacEncConf = faacEncGetCurrentConfiguration(pFaacEncHandle);
	// 设置编码器配置 b/c: 填充配置
	/*
		PCM Sample Input Format
		0	FAAC_INPUT_NULL			invalid, signifies a misconfigured config
		1	FAAC_INPUT_16BIT		native endian 16bit
		2	FAAC_INPUT_24BIT		native endian 24bit in 24 bits		(not implemented)
		3	FAAC_INPUT_32BIT		native endian 24bit in 32 bits		(DEFAULT)
		4	FAAC_INPUT_FLOAT		32bit floating point
    */
	pFaacEncConf->inputFormat = FAAC_INPUT_16BIT;
#if 0
	/* 下面参数不用设置,保存默认即可 */
	pFaacEncConf->aacObjectType = LOW; 	// MAIN:1  LOW:2  SSR:3  LTP:4
	pFaacEncConf->mpegVersion = MPEG4; 	// MPEG2:0  MPEG4:1
	pFaacEncConf->useTns = 1; 			/* Use Temporal Noise Shaping */
	pFaacEncConf->shortctl = 0; 		// SHORTCTL_NORMAL:0  SHORTCTL_NOSHORT:1  SHORTCTL_NOLONG:2
	pFaacEncConf->allowMidside = 1; 	/* Allow mid/side coding */
	pFaacEncConf->quantqual = 0; 		/* Quantizer quality */
	pFaacEncConf->outputFormat = 1; 	// 0:Raw  1:ADTS
	pFaacEncConf->bandWidth = 32000;//0 /* AAC file frequency bandwidth */
	pFaacEncConf->bitRate = 48000;//0 	/* bitrate / channel of AAC file */
#endif
	// 设置编码器配置 c/c: 重新设置编码器的配置信息
	faacEncSetConfiguration(pFaacEncHandle, pFaacEncConf);

	/* 循环操作 */
	while(1)
	{
		unsigned int u32PcmInSampleCnt = 0;
		int s32ReadPcmBytes = 0;
		int s32EncAacBytes = 0;

		/* AAC编码 3/6:从文件里读出指定大小(大小由编码器传出参数决定)PCM数据 */
		s32ReadPcmBytes = fread(pu8PcmInBuf, 1, u64PcmInSampleCnt*u32PcmSampleBits/8, fpPcm);
		if(s32ReadPcmBytes <= 0)
		{
			break;
		}
		DEBUG("Read PCM bytes: %d\n", s32ReadPcmBytes);

		// 编码传递进去的是采样数,不是字节数
		u32PcmInSampleCnt = s32ReadPcmBytes/(u32PcmSampleBits/8);
		DEBUG("Encode PCM sample count: %d\n", u32PcmInSampleCnt);

		/* AAC编码 4/6:将PCM数据(pucPcmInBuf)传进去编码得到aac数据(pucAacEncBuf)传出 */
		s32EncAacBytes = faacEncEncode(pFaacEncHandle, (int32_t*)pu8PcmInBuf, u32PcmInSampleCnt, 
														pu8AacEncBuf, (unsigned int)u64AacOutMaxBytes);
		DEBUG("Encode return aac bytes: %d\n", s32EncAacBytes);
		
		/* AAC编码 5/6:将解码得到的数据写入到AAC文件中 */
		fwrite(pu8AacEncBuf, 1, s32EncAacBytes, fpAac);
	}


	/* 记得释放内存 */
	free(pu8PcmInBuf);
	free(pu8AacEncBuf);

	/* AAC编码 6/6:用完了就关闭编码器 */
	faacEncClose(pFaacEncHandle);

error_exit:

	fclose(fpPcm);
	fclose(fpAac);

	printf("\n\033[32m%s ==> %s Success!\033[0m\n", pcmFileName, aacFileName);

	return 0;
}

在这里插入图片描述

🎄五、总结

本文介绍了AAC音频编码库 faac ,并介绍了其使用流程,最后给出了使用例子源码.

在这里插入图片描述
如果文章有帮助的话,点赞👍、收藏⭐,支持一波,谢谢 😁😁😁

参考:
音频demo:使用faac将PCM数据编码成aac数据

相关文章:

  • 【AD】5-16 泪滴的添加
  • Python 2025:AI霸主地位受挑战?最新技术趋势与未来展望
  • 一周热点-Claude 3.7 Sonnet-在响应和思考模型之间切换
  • 电脑如何在系统默认的壁纸中切换自己喜欢的
  • 从技术角度看大语言模型进化技术路线与落地应用详解:未来的最佳实践方向是什么?
  • 什么是Hash碰撞?怎么解决哈希碰撞?
  • vue安装stylelint
  • 在 Spring Boot 2.7.x 中引入 Kafka-0.9 的实践
  • 数学之约数个数定理-阶乘约数
  • # 深入理解RNN(一):循环神经网络的核心计算机制
  • Android15 Camera框架中的StatusTracker
  • OpenCV常用函数以及使用场景
  • Qt开发:nativeEvent事件的使用
  • STM32-I2C通信外设
  • 2025最新群智能优化算法:海市蜃楼搜索优化(Mirage Search Optimization, MSO)算法求解23个经典函数测试集,MATLAB
  • TinyWebServer项目笔记——01 线程同步机制封装类
  • 模型微调——模型性能提升方法及注意事项(自用)
  • 【微知】Centos如何迁移到Anolis系统的失败记录?(yum -y install centos2anolis、centos2anolis.py)
  • 正版Windows10/11系统盘制作详细教程
  • 基于单片机及传感器的机器人设计与实现
  • 电子网站模板/天津百度关键词推广公司
  • 建设网站的网站安全/模板建站公司
  • 网站网业设计/上海营销seo
  • 网站聚合搜索怎么做/厦门seo起梦网络科技
  • 做网站的 深圳/网店推广软文范例
  • 网站建设 南通/网页生成app