build_android.sh
#!/bin/bash
export NDK_HOME=/android-ndk-r10e
export SYSROOT=$NDK_HOME/platforms/android-9/arch-arm/
export TOOLCHAIN=$NDK_HOME/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64
export CPU=arm
export PREFIX=$(pwd)/android/$CPU
CFLAGS="-fpic -DANDROID -fpic -mthumb-interwork -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -Wno-psabi -march=armv5te -mtune=xscale -msoft-float -mthumb -Os -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 -DANDROID -Wa,--noexecstack -MMD -MP "
CROSS_COMPILE=$TOOLCHAIN/bin/arm-linux-androideabi-
export CPPFLAGS="$CFLAGS"
export CFLAGS="$CFLAGS"
export CXXFLAGS="$CFLAGS"
export CXX="${CROSS_COMPILE}g++ --sysroot=${SYSROOT}"
export LDFLAGS="$LDFLAGS"
export CC="${CROSS_COMPILE}gcc --sysroot=${SYSROOT}"
export NM="${CROSS_COMPILE}nm"
export STRIP="${CROSS_COMPILE}strip"
export RANLIB="${CROSS_COMPILE}ranlib"
export AR="${CROSS_COMPILE}ar"
#export LIBS="-lm"
./configure --prefix=$PREFIX \
--without-mp4v2 \
--host=arm-linux
make clean
make
make install
編碼
#include <string.h>
#include <faac.h>
#include <faaccfg.h>
int aac_Encode(char *src, char *dest, int srclen, int *dstlen)
{
unsigned long sampleRate = 16000; //編碼采樣率
unsigned int numChannels = 2; //編碼聲道數(shù)
unsigned long inputSample = 0; //輸入樣本大小,在打開編碼器時會得到此值
unsigned long maxOutputBytes = 0; //最大輸出跳夭,編碼后的輸出數(shù)據(jù)大小不會高于這個值涂圆,也是打開編碼器時獲得
unsigned int mPCMBitSize = 16; //pcm位深,用于計(jì)算一幀pcm大小
int mPCMBufferSize = 0; //一幀PCM緩存大小
int mCountSize = 0; //計(jì)算緩存大小
char* mPCMBuffer; //PCM緩存
faacEncHandle encoder; //faac編碼器句柄
faacEncConfigurationPtr config; //faac設(shè)置類
//打開編碼器
encoder = faacEncOpen(sampleRate, numChannels, &inputSample, &maxOutputBytes);
//對編碼器進(jìn)行設(shè)置
config = faacEncGetCurrentConfiguration(encoder); //獲取當(dāng)前編碼器的設(shè)置句柄
config->aacObjectType = LOW; //設(shè)置AAC類型
config->useLfe = 0; //是否允許一個聲道為低頻通道
config->useTns = 1; //是否使用瞬時噪聲定形濾波器(具體作用不是很清楚)
config->allowMidside = 0; //是否允許midSide coding (在MPEG-2 AAC 系統(tǒng)中币叹,M/S(Mid/Side) Stereo coding被提供在多聲道信號中润歉,每個聲道對(channel pair)的組合,也就是每個通道對颈抚,是對稱地排列在人耳聽覺的左右兩邊踩衩,其方式簡單,且對位串不會引起較顯著的負(fù)擔(dān)贩汉。 一般其在左右聲道數(shù)據(jù)相似度大時常被用到驱富,并需記載每一頻帶的四種能量臨界組合,分別為左匹舞、右褐鸥、左右聲道音頻合并(L+R)及相減(L-R)的兩種新的能量。一般策菜,若所轉(zhuǎn)換的Sid聲道的能量較小時晶疼,M/S Stereo coding 可以節(jié)省此通道的位數(shù),而將多余的位應(yīng)用于另一個所轉(zhuǎn)換的聲道又憨,即Mid 聲道翠霍,進(jìn)而可提高此編碼效率。)
config->outputFormat = 1; // RAW_STREAM = 0, ADTS_STREAM=1 (ADTS可以實(shí)現(xiàn)單幀單獨(dú)解碼蠢莺,raw由于缺少頭無法單幀解碼寒匙,因此無法做實(shí)時傳輸)
config->bitRate = 32000; //設(shè)置比特率
config->inputFormat = FAAC_INPUT_16BIT; //設(shè)置輸入PCM格式
faacEncSetConfiguration(encoder, config); //應(yīng)用設(shè)置
//計(jì)算PCM緩存所需大小以分配相應(yīng)空間
mPCMBufferSize = inputSample * mPCMBitSize / 8;
mPCMBuffer = new char[mPCMBufferSize];
//開始編碼
//判斷pcm緩存區(qū)是否已滿,如果沒有,繼續(xù)添加下一次數(shù)據(jù)锄弱,用mCountSize進(jìn)行記數(shù)
int i,tmp;
if (mCountSize<mPCMBufferSize)
{
memcpy(mPCMBuffer + mCountSize, src, srclen);
mCountSize += srclen;
}
else
{
mCountSize = 0; //緩存區(qū)已滿考蕾,重置記數(shù)
unsigned char* aacData = new unsigned char[maxOutputBytes]; //編碼后輸出數(shù)據(jù)(也就是AAC數(shù)據(jù))存放位置
//開始編碼,encoder為編碼器句柄会宪,mPCMBuffer為PCM數(shù)據(jù)肖卧,inputSample為打開編碼器時得到的輸入樣本數(shù)據(jù)
//aacData為編碼后數(shù)據(jù)存放位置,maxOutputBytes為編碼后最大輸出字節(jié)數(shù)掸鹅,ret為編碼后數(shù)據(jù)長度
int ret = faacEncEncode(encoder, (int32_t *)mPCMBuffer, inputSample,aacData, maxOutputBytes);
//ret為0時不代表編碼失敗塞帐,而是編碼速度較慢,導(dǎo)致緩存還未完全flush巍沙,可用一個循環(huán)繼續(xù)調(diào)用編碼接口葵姥,當(dāng) ret>0 時表示編碼成功,且返回值為編碼后數(shù)據(jù)長度
while (ret == 0)
{
ret = faacEncEncode(encoder, (int32_t *)mPCMBuffer, inputSample, aacData, maxOutputBytes);
}
if (ret > 0)
{
//AIPU_LOGD(_T("encode voice success !\n"));
//到這里已經(jīng)編碼成功句携,aacData為編碼后數(shù)據(jù)
*dstlen=0;
tmp = ret;
for(i=0; i<tmp; i++)
{
dest[i] = aacData[i];
}
*dstlen = ret;
}
else
{
//AIPU_LOGE(_T("encode failed !\n"));
}
}
return 0;
}