1.下载lame库

lame库下载地址(以下使用的是lame v3.100)

2.源码导入

解压下载的lame库,把libmp3lame文件夹下后缀为.c .h的文件(不包括子文件夹i386和vector下的)复制到cpp/lame文件夹内,同时把include目录下的lame.h也复制到cpp/lame文件夹内,此时 lame文件夹内包含42个文件。

3.修改库文件

打开刚刚拷贝的lame库文件,修改:

  1. util.h 文件,把 570 行的两处 ieee754_float32_t 改为 float 因为Android下并不支持该类型
  2. set_get.h 文件,把头部的 #include <lame.h> 改为 #include "lame.h"
  3. fft.c 文件,删除第47行 #include "vector/lame_intrin.h"
  4. id3tag.c和machine.h两个文件里,將HAVE_STRCHR和HAVE_MEMCPY的ifdef结构体删除或者注释
#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

可参考以下完整修改文件

diff --git a/VbrTag.c b/VbrTag.c
index 5800a44..36ee7b6 100644
--- a/VbrTag.c
+++ b/VbrTag.c
@@ -26,6 +26,8 @@# include <config.h>#endif+#include <stdlib.h>
+#include <string.h>#include "lame.h"#include "machine.h"#include "encoder.h"
diff --git a/bitstream.c b/bitstream.c
index aa35915..a2fe294 100644
--- a/bitstream.c
+++ b/bitstream.c
@@ -29,6 +29,7 @@#include <stdlib.h>#include <stdio.h>
+#include <string.h>#include "lame.h"#include "machine.h"
diff --git a/encoder.c b/encoder.c
index 48f46c7..437067f 100644
--- a/encoder.c
+++ b/encoder.c
@@ -30,6 +30,7 @@#endif+#include <string.h>#include "lame.h"#include "machine.h"#include "encoder.h"
diff --git a/fft.c b/fft.c
index 4eea1ad..27febdb 100644
--- a/fft.c
+++ b/fft.c
@@ -44,7 +44,7 @@#include "util.h"
--- a/fft.c
+++ b/fft.c
@@ -44,7 +44,7 @@#include "util.h"#include "fft.h"-#include "vector/lame_intrin.h"
+//#include "vector/lame_intrin.h"diff --git a/id3tag.c b/id3tag.c
index ac48510..8f148b8 100644
--- a/id3tag.c
+++ b/id3tag.c
@@ -41,17 +41,20 @@# include <string.h># include <ctype.h>#else
-# ifndef HAVE_STRCHR
-#  define strchr index
-#  define strrchr rindex
-# endif
+//# ifndef HAVE_STRCHR
+//#  define strchr index
+//#  define strrchr rindex
+//# endifchar   *strchr(), *strrchr();
-# ifndef HAVE_MEMCPY
-#  define memcpy(d, s, n) bcopy ((s), (d), (n))
-# endif
+//# ifndef HAVE_MEMCPY
+//#  define memcpy(d, s, n) bcopy ((s), (d), (n))
+//# endif#endif+#include <malloc.h>
+#include <string.h>
+#include <stdlib.h>#include "lame.h"#include "machine.h"#include "encoder.h"
diff --git a/lame.c b/lame.c
index cb82225..299fd56 100644
--- a/lame.c
+++ b/lame.c
@@ -31,6 +31,8 @@#endif+#include <malloc.h>
+#include <string.h>#include "lame.h"#include "machine.h"diff --git a/machine.h b/machine.h
index bf6fff2..c675c20 100644
--- a/machine.h
+++ b/machine.h
@@ -31,15 +31,15 @@# include <stdlib.h># include <string.h>#else
-# ifndef HAVE_STRCHR
-#  define strchr index
-#  define strrchr rindex
-# endif
+//# ifndef HAVE_STRCHR
+//#  define strchr index
+//#  define strrchr rindex
+//# endifchar   *strchr(), *strrchr();
-# ifndef HAVE_MEMCPY
-#  define memcpy(d, s, n) bcopy ((s), (d), (n))
-#  define memmove(d, s, n) bcopy ((s), (d), (n))
-# endif
+//# ifndef HAVE_MEMCPY
+//#  define memcpy(d, s, n) bcopy ((s), (d), (n))
+//#  define memmove(d, s, n) bcopy ((s), (d), (n))
+//# endif#endif#if  defined(__riscos__)  &&  defined(FPA10)
diff --git a/newmdct.c b/newmdct.c
index 596cac9..ac98abd 100644
--- a/newmdct.c
+++ b/newmdct.c
@@ -30,6 +30,7 @@# include <config.h>#endif+#include <string.h>#include "lame.h"#include "machine.h"#include "encoder.h"
diff --git a/psymodel.c b/psymodel.c
index 60076ee..1393c2a 100644
--- a/psymodel.c
+++ b/psymodel.c
@@ -145,7 +145,8 @@ blocktype_d[2]        block type to use for previous granule#endif#include <float.h>
-
+#include <stdlib.h>
+#include <string.h>#include "lame.h"#include "machine.h"#include "encoder.h"
diff --git a/quantize.c b/quantize.c
index 9ba9c16..2906c00 100644
--- a/quantize.c
+++ b/quantize.c
@@ -28,6 +28,8 @@# include <config.h>#endif+#include <stdlib.h>
+#include <string.h>#include "lame.h"#include "machine.h"#include "encoder.h"
diff --git a/quantize_pvt.c b/quantize_pvt.c
:#endif#include <float.h>
-
+#include <stdlib.h>
+#include <string.h>#include "lame.h"#include "machine.h"#include "encoder.h"
diff --git a/quantize.c b/quantize.c
index 9ba9c16..2906c00 100644
--- a/quantize.c
+++ b/quantize.c
@@ -28,6 +28,8 @@# include <config.h>#endif+#include <stdlib.h>
+#include <string.h>#include "lame.h"#include "machine.h"#include "encoder.h"
diff --git a/quantize_pvt.c b/quantize_pvt.c
index d8d6447..3cd9966 100644
--- a/quantize_pvt.c
+++ b/quantize_pvt.c
@@ -36,6 +36,7 @@#include "reservoir.h"#include "lame-analysis.h"#include <float.h>
+#include <string.h>#define NSATHSCALE 100  /* Assuming dynamic range=96dB, this value should be 92 */
diff --git a/set_get.h b/set_get.h
index 37e4bcd..99ab73c 100644
--- a/set_get.h
+++ b/set_get.h
@@ -21,7 +21,7 @@#ifndef __SET_GET_H__#define __SET_GET_H__-#include <lame.h>
+#include "lame.h"#if defined(__cplusplus)extern  "C" {
diff --git a/takehiro.c b/takehiro.c
index 67aba1b..ca02f98 100644
--- a/takehiro.c
+++ b/takehiro.c
@@ -27,6 +27,7 @@#endif+#include <string.h>#include "lame.h"#include "machine.h"#include "encoder.h"
diff --git a/util.c b/util.c
index 43b457c..e9255fe 100644
--- a/util.c
+++ b/util.c
@@ -27,6 +27,7 @@#endif#include <float.h>
+#include <malloc.h>#include "lame.h"#include "machine.h"#include "encoder.h"
diff --git a/util.h b/util.h
index 13f0cd4..b6bf306 100644
--- a/util.h
+++ b/util.h
@@ -567,7 +567,7 @@ extern  "C" {/* log/log10 approximations */extern void init_log_table(void);
-    extern ieee754_float32_t fast_log2(ieee754_float32_t x);
+    extern float fast_log2(float x);int     isResamplingNecessary(SessionConfig_t const* cfg);diff --git a/vbrquantize.c b/vbrquantize.c
index 0f703b7..60834d3 100644
--- a/vbrquantize.c
+++ b/vbrquantize.c
@@ -27,6 +27,8 @@#endif+#include <stdlib.h>
+#include <string.h>#include "lame.h"#include "machine.h"#include "encoder.h"

4.编写CmakeList.txt

cmake_minimum_required(VERSION 3.6.0)
set(CURRENT_DIR ${CMAKE_SOURCE_DIR})
message("CURRENT_DIR:" ${CMAKE_SOURCE_DIR})
include_directories(${CMAKE_SOURCE_DIR}src/main/cpp/lame)set(LAME_DIR src/main/cpp/lame)
message("LAME_DIR:" ${LAME_DIR})aux_source_directory(src/main/cpp/lame SRC_LIST)add_library(mp3lameSHAREDsrc/main/cpp/MP3Recorder.c${SRC_LIST})#add_library(mp3lame
#        SHARED
#        src/main/cpp/MP3Recorder.c
#        src/main/cpp/lame/bitstream.c
#        src/main/cpp/lame/fft.c
#        src/main/cpp/lame/id3tag.c
#        src/main/cpp/lame/mpglib_interface.c
#        src/main/cpp/lame/presets.c
#        src/main/cpp/lame/quantize.c
#        src/main/cpp/lame/reservoir.c
#        src/main/cpp/lame/tables.c
#        src/main/cpp/lame/util.c
#        src/main/cpp/lame/VbrTag.c
#        src/main/cpp/lame/encoder.c
#        src/main/cpp/lame/gain_analysis.c
#        src/main/cpp/lame/lame.c
#        src/main/cpp/lame/newmdct.c
#        src/main/cpp/lame/psymodel.c
#        src/main/cpp/lame/quantize_pvt.c
#        src/main/cpp/lame/set_get.c
#        src/main/cpp/lame/takehiro.c
#        src/main/cpp/lame/vbrquantize.c
#        src/main/cpp/lame/version.c)find_library( # Sets the name of the path variable.log-liblog)target_link_libraries(mp3lame${log-lib})

5.编写 java 类和 c 文件

public class MP3Recorder {static {System.loadLibrary("mp3lame");   }/*** 初始化 lame编码器** @param inSampleRate*              输入采样率* @param outChannel*              声道数* @param outSampleRate*              输出采样率* @param outBitrate*              比特率(kbps)* @param quality*              0~9,0最好*/public static native void init(int inSampleRate, int outChannel, int outSampleRate, int outBitrate, int quality);/***  编码,把 AudioRecord 录制的 PCM 数据转换成 mp3 格式** @param buffer_l*          左声道输入数据* @param buffer_r*          右声道输入数据* @param samples*          输入数据的size* @param mp3buf*          输出数据* @return*          输出到mp3buf的byte数量*/public static native int encode(short[] buffer_l, short[] buffer_r, int samples, byte[] mp3buf);/***  刷写** @param mp3buf*          mp3数据缓存区* @return*          返回刷写的数量*/public static native int flush(byte[] mp3buf);/*** 关闭 lame 编码器,释放资源*/public static native void close();
}

6.编写MP3Recorder.c

#include "lame/lame.h"
#include "MP3Recorder.h"static lame_global_flags *glf = NULL;
/** Class:     com_android_liblame_MP3Recorder* Method:    init* Signature: (IIIII)V*/JNIEXPORT void JNICALL Java_com_android_liblame_MP3Recorder_init(JNIEnv *env, jclass instance, jint inSamplerate, jint outChannel, jint outSamplerate,jint outBitrate, jint quality) {if (glf != NULL) {lame_close(glf);glf = NULL;}glf = lame_init();lame_set_in_samplerate(glf, inSamplerate);lame_set_num_channels(glf, outChannel);lame_set_out_samplerate(glf, outSamplerate);lame_set_brate(glf, outBitrate);lame_set_quality(glf, quality);lame_init_params(glf);}/** Class:     com_android_liblame_MP3Recorder* Method:    encode* Signature: ([S[SI[B)I*/
JNIEXPORT jint JNICALL Java_com_android_liblame_MP3Recorder_encode(JNIEnv *env, jclass instance, jshortArray buffer_l, jshortArray buffer_r, jint samples,jbyteArray mp3buf) {jshort *j_buffer_l = (*env)->GetShortArrayElements(env, buffer_l, NULL);jshort *j_buffer_r = (*env)->GetShortArrayElements(env, buffer_r, NULL);const jsize mp3buf_size = (*env)->GetArrayLength(env, mp3buf);jbyte *j_mp3buf = (*env)->GetByteArrayElements(env, mp3buf, NULL);int result = lame_encode_buffer(glf, j_buffer_l, j_buffer_r,samples, j_mp3buf, mp3buf_size);(*env)->ReleaseShortArrayElements(env, buffer_l, j_buffer_l, 0);(*env)->ReleaseShortArrayElements(env, buffer_r, j_buffer_r, 0);(*env)->ReleaseByteArrayElements(env, mp3buf, j_mp3buf, 0);return result;
}/** Class:     com_android_liblame_MP3Recorder* Method:    flush* Signature: ([B)I*/
JNIEXPORT jint JNICALL Java_com_android_liblame_MP3Recorder_flush(JNIEnv *env, jclass instance, jbyteArray mp3buf) {const jsize mp3buf_size = (*env)->GetArrayLength(env, mp3buf);jbyte *j_mp3buf = (*env)->GetByteArrayElements(env, mp3buf, NULL);int result = lame_encode_flush(glf, j_mp3buf, mp3buf_size);(*env)->ReleaseByteArrayElements(env, mp3buf, j_mp3buf, 0);return result;
}/** Class:     com_android_liblame_MP3Recorder* Method:    close* Signature: ()V*/
JNIEXPORT void JNICALL Java_com_android_liblame_MP3Recorder_close(JNIEnv *env, jclass instance) {lame_close(glf);glf = NULL;}

7.配置build.gradle

android {..........//*externalNativeBuild {cmake {path "CMakeLists.txt"}}}

原文地址:

https://www.jianshu.com/p/d979ce51d804

Android JNI:lame库的编译及使用相关推荐

  1. android lame wav 转 mp3,Android JNI Lame编解码实现wav到MP3的转换

    1.JNI简介 JNI全称为Java Native Interface(JAVA本地调用).从Java1.1开始,JNI成为java平台的一部分,它允许Java代码和其他语言写的代码(如C&C ...

  2. android lame wav 转 mp3,Android JNI Lame编解码实现wav到MP3的转换

    1.JNI简介 JNI全称为Java Native Interface(JAVA本地调用).从Java1.1开始,JNI成为java平台的一部分,它允许Java代码和其他语言写的代码(如C&C ...

  3. android JNI基本库(jsting转string和C多线程调用java方法的说明)

    1.JNI开发时经常需要使用到jstring和string的转换,还有C++多线程中使用JNIEnv,因此特意写了这个类,方便以后的开发使用. 注意:  如果要使用打印日志的LOGI和LOGE需要在m ...

  4. 【CMake】Android Studio 中使用 CMake 编译单个 C++ 源文件 ( 常用的 CMake 命令解析 )

    文章目录 一.Android Studio 中使用 CMake 编译单个 C++ 源文件 二.cmake_minimum_required 命令设置最小 CMake 版本 三.project 命令设置 ...

  5. Android直播开发之旅(4):MP3编码格式分析与lame库编译封装

    转载请声明出处:http://blog.csdn.net/andrexpert/article/77683776 一.Mp3编码格式分析 MP3,全称MPEG Audio Layer3,是一种高效的计 ...

  6. arch linux arm下载_linux系统下编译给android JNI调用的Gmssl库

    编译给android JNI调用的Gmssl库的方法,网络上并不多.按照叶大强(CSDN账号:hkNaruto)写的<GmSSL Android NDK编译 (版本95c0dba>的帖子编 ...

  7. java jni编译_从源码编译Android系统的Java类库和JNI动态库的方法

    利用源码编译Android系统Java类库 1.编写Java项目和Android.mk文件 ├── Android.mk └── src └── com └── lhw └── framework └ ...

  8. ffmpeg开发之旅(4):MP3编码格式分析与lame库编译封装

    ffmpeg开发之旅(4):MP3编码格式分析与lame库编译封装 原文链接:http://blog.csdn.net/andrexpert/article/77683776 一.Mp3编码格式分析 ...

  9. android lame音频转换,音视频开发02--使用LAME库转换pcm文件到mp3

    android 使用 AudioRecord 对麦克风进行录音得到的是 pcm 格式的原始音频数据,pcm文件是不能用来播放的,需要进行编码压缩. LAME是目前非常优秀的一种MP3编码引擎,在业界, ...

  10. android jni调用so库

    今天,讲讲android studio 使用jni调用其他so库的使用. 首先说一下在网上查找资料时,对于调用第三方so库,有人说有两种方法: 1.    对于so库的API符合JNI格式(即使用ja ...

最新文章

  1. Start Activity for Result(Bug)
  2. 使用squid配置透明代理并对上网行为进行控制
  3. asp.net学习资源列表
  4. 老赵被刷票了,但这不是老赵做的
  5. Alictf 2015决赛题目设计和解题思路
  6. Java多线程(学习总结,持续更新)
  7. 001_02-python基础习题答案
  8. android编写计算器代码,Android入门计算器编写代码
  9. matlab x~=0
  10. 下沉市场不需要巨头,但很需要社区团购
  11. H3C S3600 交换机NTP对等体模式的配置
  12. 雨落无声-开博啦........
  13. 利用原生JavaScript--实现小球无限转圈
  14. 送礼蓝牙耳机哪款合适?2021最好的蓝牙耳机排行!
  15. 做电商不一定要有团队,兼职宝妈也能玩转无货源电商
  16. 【数据挖掘】利用md5查找重复文件
  17. 深度至尊GHOST_XPSP3快速装机专业版V8.0
  18. 爬虫漫游指南:HTTP/2 网站爬取
  19. 计算机网络复习——第四章网络层
  20. cad和php哪个工资高,CAD顶级绘图员必备,人手一份的绘图命令,学会工资上万不是梦...

热门文章

  1. python爬取拉勾网_使用requests爬取拉勾网python职位数据
  2. 爬虫学习之17:爬取拉勾网网招聘信息(异步加载+Cookie模拟登陆)
  3. python数据可视化第三章图表辅助元素的定制
  4. Captura录屏没有声音解决方法
  5. Docker 报错port is already allocated
  6. 参考文献标引方式_参考文献标注方法有哪些 为什么要标注参考文献
  7. 通信原理包络是什么意思_为什么齿轮不能少于17个齿,少于17个齿,齿轮传动会如何?...
  8. 把N*N矩阵顺时针旋转90°输出(2018携程校招笔试题)
  9. 电脑能正常上网,但登不上 QQ
  10. oracle+suspend+参数,oracle数据库的挂起(Suspending)和恢复(Resuming)