要向Android系统添加一种音频格式,需要对stagefright有一定的了解,在android源码里的libstagefright文件夹里面,可以看到一大堆的Extractor,也就是各种格式的解码器了。我们就是要这里写一个APEExtractor

撇开Android框架不说,我们还不知道要如何把APE格式的数据解为pcm,所以重中之重是先找到解析APE的方法。

##Monkey’s audio

开源的力量很强大,APE的解码器不用自己苦逼的实现了,只要到http://www.monkeysaudio.com/下载源码,然后根据android平台修改下,编译成库,供框架调用就可以了。

说起来轻松,有些知识还是需要知道的。所以现在的目标就是把APE解码器编译成libmonkeysaudio.so

##Android.mk

要编译成库,最主要是写好Android.mk。下载下来的解码器的源码版本是4.12,也就是MAC_SDK_412.zip,解压后发现其代码没有Makefile,而且project只有vs2012和xcode两个版本。忍了。

Readme.txt 中有这么一句话

If you use C++, it’s recommended that you simply statically link to maclib.lib

所以熟悉其源码后发现用到的代码目录只有两个MACLibShared,其他可以扔垃圾桶了。

把这两个文件夹放到一个叫做libmonkeysaudio文件夹中,然后移到android源码中external目录,开始做代码修改。

首先是在MACLib 目录把md5.h改名为MD5.h,在Shared目录的All.h 里定义好环境为LINUX。

libmonkeysaudio文件夹下编写Android.mk文件,内容如下

:::sh
LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE:=libmonkeysaudio

LOCAL_SRC_FILES := \
    MACLib/APECompressCore.cpp \
    MACLib/APECompress.cpp \
    MACLib/APECompressCreate.cpp \
    MACLib/APEDecompress.cpp \
    MACLib/APEHeader.cpp \
    MACLib/APEInfo.cpp \
    MACLib/APELink.cpp \
    MACLib/APESimple.cpp \
    MACLib/APEtag.cpp \
    MACLib/BitArray.cpp \
    MACLib/MACLib.cpp \
    MACLib/MACProgressHelper.cpp \
    MACLib/md5.cpp \
    MACLib/NewPredictor.cpp \
    MACLib/NNFilter.cpp \
    MACLib/Prepare.cpp \
    MACLib/UnBitArrayBase.cpp \
    MACLib/UnBitArray.cpp \
    MACLib/WAVInputSource.cpp \
    Shared/CharacterHelper.cpp \
    Shared/CircleBuffer.cpp \
    Shared/GlobalFunctions.cpp \
    Shared/StdLibFileIO.cpp \
    Shared/WinFileIO.cpp 

LOCAL_C_INCLUDES += \
    external/libmonkeysaudio/MACLib \
    external/libmonkeysaudio/Shared 

include $(BUILD_SHARED_LIBRARY)

PS:好好利用下面命令可以快速整理好要编译的文件。

:::sh
ls -l | awk '{print $9}' > all.txt

使用mm编译,毫无以外的一大堆错误,看来代码还是不完善,只好手工修改了。

###错误一 external/libmonkeysaudio/Shared/SmartPtr.h:67:5: error: ‘__forceinline’ does not name a type

老老实实去提示的代码那里把__forceinline改外inline,谁叫你不是编来给windows用的呢。

###错误二

has virtual functions and accessible non-virtual destructor

说是析构函数不是虚拟的。那就在MACLib.h 的100行后加个虚拟的虚构函数就可以了。

:::cpp
virtual ~IAPEProgressCallback(){};

###错误三

error: exception handling disabled, use -fexceptions to enable

在Android.mk 加上下面代码开启异常捕获

:::sh
LOCAL_CPPFLAGS += -fexceptions

###错误四

error: extra qualification ‘APE::CCircleBuffer::’ on member ‘GetDirectWritePointer’ [-fpermissive]

在Android.mk 加入

:::sh
LOCAL_CPPFLAGS += -fpermissive

###错误五

一堆链接错误,例如

error: undefined reference to ‘__cxa_end_cleanup’

这些源代码需要一个完整的c++静态库,于是在Android.mk加上这些链接库

:::sh
LOCAL_LDFLAGS += -Lprebuilts/ndk/current/sources/cxx-stl/gnu-libstdc++/libs/armeabi-v7a -lsupc++

这样,在Android4.2.2上就能编过了。

:::sh
Install: /home/gavin/workspace/min210/cm10/out/target/product/tiny210/system/lib/libmonkeysaudio.so 

到此编译解码库成功了。