Android音视频-Lame编译(Android 15 16K)对齐 和 addr2line使用

一、简介

目前的项目需要使用Android的录音功能,而Android AudioRecord 无法直接录出mp3格式,因此需要我们进行对pcm数据进行编码格式处理。目前比较优秀的mp3编码库,比较推荐的是 Lame

二、Lame编译

1、Lame下载

我们可以直接去官方网站上下载最新版本的 Lame 3.100版本

2、Android studio创建C++项目

当我们创建好Android C++项目后,需要进行如下配置:

1、在cpp目录下新增lame目录。

2、将刚刚下载lame 3.100解压

  • 复制 libmp3lame 文件夹里面 .c 和 .h结尾的文件到新增lame目录下
  • 复制 vector 文件夹里面的 lame_intrin.h 到新增lame目录下
  • 复制 include文件夹里面的 lame.h 到新增lame目录下

3、编写 CMakeLists.txt

bash 复制代码
cmake_minimum_required(VERSION 3.4.1)

SET(lame_dir ${CMAKE_SOURCE_DIR}/lame)
# 将给定目录添加到编译器用于搜索包含文件的目录中。相对路径被解释为相对于当前源目录
# 是用来提供编译搜索头文件路径的
include_directories(${lame_dir})
#设定一个目录
aux_source_directory(${lame_dir} SRC_LIST)

set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)

#确保生成的 .so 文件包含完整的调试信息和符号表
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g")

#生成以 libLames.so 文件文件名的so文件
add_library( # Sets the name of the library.
        Lame
        # Sets the library as a shared library.
        SHARED
        # Provides a relative path to your source file(s).
        ${SRC_LIST}
        Lame.cpp)

find_library( # Sets the name of the path variable.
        log-lib
        # Specifies the name of the NDK library that
        # you want CMake to locate.
        log)

target_link_libraries( # Specifies the target library.
        Lame
        # Links the target library to the log library
        # included in the NDK.
        ${log-lib})
# 16K 对齐
target_link_options(Lame PRIVATE "-Wl,-z,max-page-size=16384")

4、编写Lame.cpp

arduino 复制代码
#include <jni.h>
#include <string>
#include "lame.h"

extern "C"
JNIEXPORT jstring JNICALL
Java_com_hql_lame_LameUtils_getVersion(JNIEnv *env, jobject thiz) {
    throw "a";
    return (*env).NewStringUTF(get_lame_version());
}

5、build.gradle.kts 配置

ini 复制代码
plugins {
    alias(libs.plugins.android.library)
    alias(libs.plugins.kotlin.android)
}

android {
    namespace = "com.hql.he.lame"
    compileSdk = 35

    defaultConfig {
        minSdk = 26

        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
        consumerProguardFiles("consumer-rules.pro")

        ndk {
            abiFilters.addAll(arrayOf("arm64-v8a"))
        }

        //解决.c 里面的警告
        externalNativeBuild {
            cmake {
                cFlags("-DSTDC_HEADERS")
            }
        }
    }

    externalNativeBuild {
        cmake {
            path = file("src/main/cpp/CMakeLists.txt")
            version = "3.22.1"
        }
    }

    buildTypes {
        release {
            isMinifyEnabled = false
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_17
        targetCompatibility = JavaVersion.VERSION_17
    }
    kotlinOptions {
        jvmTarget = "17"
    }
}

6、错误解决

  • unknown type name 'ieee754_float32_t'

    将util.h的570行改为

    arduino 复制代码
    extern ieee754_float32_t fast_log2(ieee754_float32_t x);
    改为
    extern float fast_log2(float x);
  • fft.c报错

修改为:

arduino 复制代码
#include "lame_intrin.h"

三、编写 LameUtils

kotlin 复制代码
object LameUtils {

    init {
        System.loadLibrary("Lame")
    }

    external fun getVersion(): String
}

四、运行

这时候运行,会报如下错误:

addr2line 定位和解决报错

  • 找到addr2line 在命令行输入如下命令:
bash 复制代码
aarch64-linux-android-addr2line -f -C -e /xxx/arm64-v8a/libLame.so 000000000006bf3c

结果:

bash 复制代码
Java_com_hql_lame_LameUtils_getVersion
/xxx/LameMp3/lame_mp3/src/main/cpp/Lame.cpp:8

删除该行,即可解决错误。在运行,即显示如下:

出现上述结果 3.100,即表示成功编译。

编译lame.so可以使用如下命令:

  • assemble
  • assembleRelease

最终生成so文件路径为:

五、总结

  • 1、编译lame
  • 2、Android 16k对齐
  • 3、addr2line的使用

六、其他

1、如何查看so文件是否包含符号表

a、使用file命令

复制代码
file libLame.so

结果

scala 复制代码
libLame.so: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=ec26f0b295b66218ff61cd04a6d8e2657e6ccf5e, with debug_info, not stripped

not stripped 即代表有符号表。

b、使用llvm-vm命令

复制代码
llvm-vm libLame.so

表示有符号表

2、如何查看so文件是否16k对齐

相关推荐
Mores5 分钟前
开源 | ImageMinify:轻量级智能图片压缩工具,为你的项目瘦身加速
前端
执梦起航7 分钟前
webpack理解与使用
前端·webpack·node.js
ai大师7 分钟前
Cursor怎么使用,3分钟上手Cursor:比ChatGPT更懂需求,用聊天的方式写代码,GPT4、Claude 3.5等先进LLM辅助编程
前端
Json_10 分钟前
使用vue2技术写了一个纯前端的静态网站商城-鲜花销售商城
前端·vue.js·html
1024熙10 分钟前
【Qt】——理解信号与槽,学会使用connect
前端·数据库·c++·qt5
少糖研究所12 分钟前
ColorThief库是如何实现图片取色的?
前端
冴羽12 分钟前
SvelteKit 最新中文文档教程(22)—— 最佳实践之无障碍与 SEO
前端·javascript·svelte
ZYLAB14 分钟前
我写了一个简易的 SEO 教程,希望能让新手朋友看完以后, SEO 能做到 80 分
前端·seo
IvanCodes15 分钟前
MySQL 视图
android·数据库·sql·mysql·oracle
KevinWang_19 分钟前
Java 和 Kotlin 混编导致的 bug
android·kotlin