Android移植lame库(采用CMake)

作者: Javine_Kuang | 来源:发表于2017-06-15 16:22 被阅读397次

    貌似许多人都是从lame库开始入门Android NDK开发的,在网上一搜一大堆详细教程。本篇的亮点是采用Google推荐的CMake工具(不是ndk-builder)来移植lame项目。重点写一下与ndk-builder的差异,而非教程。

    1.CMake是什么?

    这个是AndroidStudio 2.2以上的版本才可使用的,跟ndk-builder一样是一款原生构建工具。
    与ndk-builder不同的是,ndk-builder需要用到mk文件,而CMake则使用CMakeLists文件。
    具体可阅读官方介绍 向您的项目中添加C代码 以及 CMake(不读的话,可能看不懂怎么移植哦)

    在这里要说的就是,如果你使用的是AndroidStudio 2.2以上的版本,那么只要在创建项目时选择“Include C++ Support”选项,然后不停点击下一步就可以创建一个使用CMake工具构建C\C++代码的项目。
    当然前提是,你在SDK Manager中安装了CMake。

    由于本文重点在移植lame项目,对CMake的介绍就不多说了。

    2.将lame的代码放入项目

    现在假设你已经创建了一个采用CMake的NDK项目,那么你可以找到两个很重要的东西:cpp文件夹和CMakeLists.txt文件。前者是用来放C\C++源码的,后者则是CMake的构建脚本文件。
    如果你看完了向您的项目中添加C代码 文章,那你肯定知道CMakeLists.txt脚本中的大体内容了。

    好了,先下载lame吧。
    http://lame.sourceforge.net/download.php
    http://sourceforge.net/projects/lame/files/lame/3.99/lame-3.99.5.tar.gz
    下载完之后解压,然后找到libmp3lame文件夹,将里面的.c和.h文件全部复制到项目的cpp目录中。
    注意:libmp3lame文件夹内还包含其他文件夹,不用管它。
    然后,再找到include文件夹,将lame.h文件拷贝到cpp目录中。(总共43个文件)

    接下来需要将源文件加入到项目中,通过CMakeLists.txt脚本来控制
    在CMakeLists中修改add_library 方法的最后一个参数,通过AndroidStudio创建的ndk项目中会有一个native-lib.cpp文件,在此文件后将lame相关的所有.c文件添加进来。这一步是指定源代码的位置。
    像下面这样:

    add_library(native-lib
                 SHARED
                 native-lib.cpp bitstream.c encoder.c gain_analysis.c lame.c id3tag.c 
                 mpglib_interface.c newmdct.c presets.c psymodel.c quantize.c fft.c
                 quantize_pvt.c reservoir.c set_get.c tables.c takehiro.c util.c  
                 vbrquantize.c VbrTag.c version.c)
    

    不过,这里要注意,AndroidStudio默认的CMakeLists文件的位置在项目目录中,我将它放到cpp目录中去了。所以才能直接添加.c文件名,否则需要添加相对路径“src/main/cpp/xxx.c”
    到此,lame项目就已经被放入我们的ndk项目中了。

    3.移植修改

    首先,需要对lame中的三个文件进行一些小改动。
    1)删除fft.c文件的47行的"include "vector/lame_intrin.h""

    2)修改set_get.h文件的24行的#include“lame.h"

    3)将util.h文件的574行的"extern ieee754_float32_t fast_log2(ieee754_float32_t x);"
    替换为 "extern float fast_log2(float x);"

    这些跟ndk-builder是一样的,网上有很多教程。

    然后,需要修改app -> build.gradle文件

    android {
    ...
        defaultConfig {
        ...
            externalNativeBuild{
                cmake{
                    cFlags "-DSTDC_HEADERS"
                }
            }
        }
    }
    

    没错,就是添加这个-DSTDC_HEADERS编译标识。

    大家可以试一下,如果不加这个标志,我们的项目编译会报错,比如undefined symbol bcopy...之类的。

    这里说明一下我的调查结果:
    首先,添加-D标志的意思就是给编译器添加宏定义。那么-DSTDC_HEADERS就相当于给项目增加一句”#define STDC_HEADERS“。

    我们打开machine.h文件看一下第34行:

    #ifdef STDC_HEADERS
    # include <stdlib.h>
    # include <string.h>
    #else
    # ifndef HAVE_STRCHR
    #  define strchr index
    #  define strrchr rindex
    # endif
    char   *strchr(), *strrchr();
    # ifndef HAVE_MEMCPY
    #  define memcpy(d, s, n) bcopy ((s), (d), (n))
    #  define memmove(d, s, n) bcopy ((s), (d), (n))
    # endif
    #endif
    

    意思很明白,如果没有定义STDC_HEADERS这个宏则会用到bcopy方法,而这个方法我们根本没有,于是就报错了。

    4.测试

    到现在我们的移植工作就已经做完了,接下来可以简单测试一下。

    打开项目中的native-lib.cpp文件,做如下修改:

    #include <jni.h>
    #include <string>
    #include "lame.h"
    
    extern "C"
    jstring
    Java_com_javine_mylameproject_MainActivity_stringFromJNI(
            JNIEnv *env,
            jobject /* this */) {
        return env->NewStringUTF(get_lame_version());
    }
    
    

    运行项目,如无意外我们的app会显示lame的版本号 3.99.5

    相关文章

      网友评论

        本文标题:Android移植lame库(采用CMake)

        本文链接:https://www.haomeiwen.com/subject/sohuqxtx.html