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对齐

相关推荐
wx_lidysun3 小时前
Nextjs学习笔记
前端·react·next
无羡仙6 小时前
从零构建 Vue 弹窗组件
前端·vue.js
xiaolizi5674897 小时前
安卓远程安卓(通过frp与adb远程)完全免费
android·远程工作
阿杰100017 小时前
ADB(Android Debug Bridge)是 Android SDK 核心调试工具,通过电脑与 Android 设备(手机、平板、嵌入式设备等)建立通信,对设备进行控制、文件传输、命令等操作。
android·adb
梨落秋霜7 小时前
Python入门篇【文件处理】
android·java·python
源心锁7 小时前
👋 手搓 gzip 实现的文件分块压缩上传
前端·javascript
源心锁7 小时前
丧心病狂!在浏览器全天候记录用户行为排障
前端·架构
GIS之路8 小时前
GDAL 实现投影转换
前端
烛阴8 小时前
从“无”到“有”:手动实现一个 3D 渲染循环全过程
前端·webgl·three.js
BD_Marathon8 小时前
SpringBoot——辅助功能之切换web服务器
服务器·前端·spring boot