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

相关推荐
RobinDevNotes14 分钟前
从 Electron 到 GPUI,9 个跨平台桌面方案该怎么选
前端·javascript·rust·electron·openresty·前端开发工具
jay神1 小时前
基于 YOLOv8 的轴承缺陷检测(Web 版)
前端·人工智能·yolo
jay神1 小时前
基于 YOLOv8 的森林火灾检测系统(Web 版)
前端·yolo
code2cat1 小时前
HTML基础篇之第一张网页:从index.html到浏览器里的任务清单
前端·html
miss2 小时前
AI 改完不敢上线?OpenSpec 规约驱动开发实战
前端·代码规范·前端工程化
AiMan3 小时前
腾讯ima还是不可以导出左侧所有对话,只能单条导出,方法不对吗
前端
去伪存真3 小时前
并发量一高就装死?Agent 全链路“防猝死”手册
前端·agent
Moment3 小时前
AI 编程时代,聊聊我的 Mac mini 双屏桌面
前端·后端
AiMan3 小时前
先确认能不能一次把Microsofat Copilot所有内容打包一个文件导出
前端
总要学点什么3 小时前
第97篇:三维数据加载-城市建筑白模自定义着色器——让一条光带沿高度扫上去,快慢却由帧率说了算
前端·gis·webgl·cesium·着色器·空间分析·白模