Android Faac静态库与aac编码

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;         //编码声道数
    unsigned long inputSample = 0;        //输入样本大小,在打开编码器时会得到此值
    unsigned long maxOutputBytes = 0;  //最大输出,编码后的输出数据大小不会高于这个值,也是打开编码器时获得
    unsigned int mPCMBitSize = 16;    //pcm位深,用于计算一帧pcm大小

    int mPCMBufferSize = 0;    //一帧PCM缓存大小
    int mCountSize = 0;           //计算缓存大小

    char* mPCMBuffer;           //PCM缓存
    faacEncHandle encoder;    //faac编码器句柄
    faacEncConfigurationPtr config;   //faac设置类

    //打开编码器
    encoder = faacEncOpen(sampleRate, numChannels, &inputSample, &maxOutputBytes);

    //对编码器进行设置
    config = faacEncGetCurrentConfiguration(encoder);   //获取当前编码器的设置句柄
    config->aacObjectType = LOW;    //设置AAC类型
    config->useLfe = 0;    //是否允许一个声道为低频通道
    config->useTns = 1;  //是否使用瞬时噪声定形滤波器(具体作用不是很清楚)
    config->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 声道,进而可提高此编码效率。)
    config->outputFormat = 1;  // RAW_STREAM = 0, ADTS_STREAM=1  (ADTS可以实现单帧单独解码,raw由于缺少头无法单帧解码,因此无法做实时传输)
    config->bitRate = 32000;  //设置比特率
    config->inputFormat = FAAC_INPUT_16BIT;  //设置输入PCM格式
    faacEncSetConfiguration(encoder, config);   //应用设置

    //计算PCM缓存所需大小以分配相应空间
    mPCMBufferSize = inputSample * mPCMBitSize / 8;
    mPCMBuffer = new char[mPCMBufferSize];

    //开始编码
    //判断pcm缓存区是否已满,如果没有,继续添加下一次数据,用mCountSize进行记数
    int i,tmp;
    if (mCountSize<mPCMBufferSize)
    {
        memcpy(mPCMBuffer + mCountSize, src, srclen);
        mCountSize += srclen;
    }
    else
    {
       mCountSize = 0;   //缓存区已满,重置记数
       unsigned char* aacData = new unsigned char[maxOutputBytes];   //编码后输出数据(也就是AAC数据)存放位置
       //开始编码,encoder为编码器句柄,mPCMBuffer为PCM数据,inputSample为打开编码器时得到的输入样本数据
       //aacData为编码后数据存放位置,maxOutputBytes为编码后最大输出字节数,ret为编码后数据长度
       int ret = faacEncEncode(encoder, (int32_t *)mPCMBuffer, inputSample,aacData, maxOutputBytes);
       //ret为0时不代表编码失败,而是编码速度较慢,导致缓存还未完全flush,可用一个循环继续调用编码接口,当 ret>0 时表示编码成功,且返回值为编码后数据长度
       while (ret == 0)
       {
           ret = faacEncEncode(encoder, (int32_t *)mPCMBuffer, inputSample, aacData, maxOutputBytes);
       }
       if (ret > 0)
       {
            //AIPU_LOGD(_T("encode voice success !\n"));
            //到这里已经编码成功,aacData为编码后数据
            *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;
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容