1、首先去下载FAAC的源码
faac-1.28
去网上下载这个版本的faac
2、移植文件
需要开源里面的include和libfaac里面的头文件和C文件,libfaac的并不是全部都需要。
aacquant.c aacquant.h
backpred.c backpred.h
bitstream.c bitstream.h
channels.c channels.h
coder.h faac.h
faaccfg.h fft.c fft.h filtbank.c filtbank.h
frame.c frame.h huffman.c
huffman.h hufftab.h
ltp.c ltp.h midside.c midside.h
psych.h psychkni.c
tns.c tns.h util.c util.h version.h
需要这些文件
3、编写faac的转换的代码,调用faac的api接口
#include <faac.h>
#include <stdio.h>
typedef unsigned long ULONG;
typedef unsigned int UINT;
typedef unsigned char BYTE;
typedef char _TCHAR;
int main(int argc, _TCHAR* argv[])
{
ULONG nSampleRate = 16000; // 采样率
UINT nChannels = 1; // 声道数
UINT nPCMBitSize = 16; // 单样本位数
ULONG nInputSamples = 0;
ULONG nMaxOutputBytes = 0;
int nRet;
faacEncHandle hEncoder;
faacEncConfigurationPtr pConfiguration;
int nBytesRead;
int nPCMBufferSize;
BYTE* pbPCMBuffer;
BYTE* pbAACBuffer;
FILE* fpIn; // PCM file for input
FILE* fpOut; // AAC file for output
fpIn = fopen("./ai_record.pcm", "rb");
fpOut = fopen("./out.aac", "wb");
// (1) Open FAAC engine
hEncoder = faacEncOpen(nSampleRate, nChannels, &nInputSamples, &nMaxOutputBytes);
if(hEncoder == NULL)
{
printf("[ERROR] Failed to call faacEncOpen()\n");
return -1;
}
nPCMBufferSize = nInputSamples * nPCMBitSize / 8;
pbPCMBuffer = (char*)malloc(nPCMBufferSize);
pbAACBuffer = (char*)malloc(nMaxOutputBytes);
// (2.1) Get current encoding configuration
pConfiguration = faacEncGetCurrentConfiguration(hEncoder);
pConfiguration->aacObjectType = LOW; //设置AAC类型
pConfiguration->useLfe = 0; //是否允许一个声道为低频通道
pConfiguration->useTns = 1; //是否使用瞬时噪声定形滤波器(具体作用不是很清楚)
pConfiguration->allowMidside = 0; //是否允许midSide coding (在MPEG-2 AAC 系统中,M/S(Mid/Side) Stereo coding被提供在多声道信号中,每个声道对(channel pair)的组合,也就是每个通道对,是对称地排列在人耳听觉的左右两边,其方式简单,且对位串不会引起较显著的负担。 一般其在左右声道数据相似度大时常被用到,并需记载每一频带的四种能量临界组合,分别为左、右、左右声道音频合并(L+R)及相减(L-R)的两种新的能量。一般,若所转换的Sid声道的能量较小时,M/S Stereo coding 可以节省此通道的位数,而将多余的位应用于另一个所转换的声道,即Mid 声道,进而可提高此编码效率。)
pConfiguration->outputFormat =1; // RAW_STREAM = 0, ADTS_STREAM=1 (ADTS可以实现单帧单独解码,raw由于缺少头无法单帧解码,因此无法做实时传输)
pConfiguration->bitRate =8000; //设置比特率
pConfiguration->inputFormat = FAAC_INPUT_16BIT; //设置输入PCM格式
// (2.2) Set encoding configuration
nRet = faacEncSetConfiguration(hEncoder, pConfiguration);
for(int i = 0; 1; i++)
{
// 读入的实际字节数,最大不会超过nPCMBufferSize,一般只有读到文件尾时才不是这个值
nBytesRead = fread(pbPCMBuffer, 1, nPCMBufferSize, fpIn);
// 输入样本数,用实际读入字节数计算,一般只有读到文件尾时才不是nPCMBufferSize/(nPCMBitSize/8);
nInputSamples = nBytesRead / (nPCMBitSize / 8);
// (3) Encode
nRet = faacEncEncode(
hEncoder, (int*) pbPCMBuffer, nInputSamples, pbAACBuffer, nMaxOutputBytes);
fwrite(pbAACBuffer, 1, nRet, fpOut);
printf("nPCMBufferSize %d: faacEncEncode returns %d\n", nPCMBufferSize, nRet);
if(nBytesRead <= 0)
{
break;
}
}
// (4) Close FAAC engine
nRet = faacEncClose(hEncoder);
free(pbPCMBuffer);
free(pbAACBuffer);
fclose(fpIn);
fclose(fpOut);
return 0;
}
4、编写Makefile
CONFIG_UCLIBC_BUILD=y
CROSS_COMPILE ?= mips-linux-uclibc-gnu-
CC = $(CROSS_COMPILE)gcc
CPLUSPLUS = $(CROSS_COMPILE)g++
LD = $(CROSS_COMPILE)ld
AR = $(CROSS_COMPILE)ar cr
STRIP = $(CROSS_COMPILE)strip
CFLAGS = $(INCLUDES)
INCLUDES = -I ./
LDFLAG += -Wl,-gc-sections
OBJS = faac_test.o aacquant.o channels.o filtbank.o midside.o util.o backpred.o frame.o psychkni.o bitstream.o fft.o huffman.o ltp.o tns.o
TAR = demo
all: $(TAR)
$(TAR) : $(OBJS)
$(CC) $(LDFLAG) -o $@ $^ -lm -lrt -ldl
%.o:%.c
$(CC) -c $(CFLAGS) $< -o $@ -lm -lrt -ldl -std=c99
clean:
rm -f *.o *~
distclean: clean
rm -f
编译完之后直接放入一个PCM文件,选对采样率和通道数那些参数,然后运行这个demo