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

相关推荐
crary,记忆2 小时前
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
前端·webpack·angular·angular.js
这个家伙很笨2 小时前
了解Android studio 初学者零基础推荐(4)
android·ide·android studio
漂流瓶jz2 小时前
让数据"流动"起来!Node.js实现流式渲染/流式传输与背后的HTTP原理
前端·javascript·node.js
SamHou03 小时前
手把手 CSS 盒子模型——从零开始的奶奶级 Web 开发教程2
前端·css·web
我不吃饼干3 小时前
从 Vue3 源码中了解你所不知道的 never
前端·typescript
开航母的李大3 小时前
【中间件】Web服务、消息队列、缓存与微服务治理:Nginx、Kafka、Redis、Nacos 详解
前端·redis·nginx·缓存·微服务·kafka
Bruk.Liu3 小时前
《Minio 分片上传实现(基于Spring Boot)》
前端·spring boot·minio
鱼樱前端3 小时前
Vue3+d3-cloud+d3-scale+d3-scale-chromatic实现词云组件
前端·javascript·vue.js
zhangxingchao4 小时前
Flutter入门:Flutter开发必备Dart基础
前端