Android 编译Lame&简单使用

标签: ndk
3066人阅读 评论(1) 收藏 举报
分类:

上一篇文章介绍了AndroidStudio2.0搭建Ndk环境&成功编译使用,这一篇我们开始实战编译一个项目,并使用它。那接下来要介绍一下这个项目Lame,来看看他的介绍

LAME是目前最好的MP3编码引擎。LAME编码出来的MP3音色纯厚、空间宽广、低音清晰、细节表现良好,它独创的心理音响模型技术保证了CD音频还原的真实性,配合VBR和ABR参数,音质几乎可以媲美CD音频,但文件体积却非常小。对于一个免费引擎,LAME的优势不言而喻。关于LAME的介绍可以在百度百科,维基百科中找到,我在这里不再赘述了,但是要知道LAME可以帮助我们将wav无损音频文件转码成mp3这种体积相对较小的音频格式文件。
当我们在跨平台上使用,mp3无疑是最好的音频选择,因为无论android和ios都默认支持播放

那我们来看看怎么根据源码进行编译和使用吧
在官网http://lame.sourceforge.net/ 下载最新版的版本 lame-3.99.5 下载完进行解压,然后把libmp3lame目录下的文件拷贝到jni下面,去除i386文件夹,和非.c .h的文件

然后创建一个Activity,编写一个wav转换成mp3的本地方法

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main_activity);
    convertmp3("/sdcard/1KHz-stero.wav","/sdcard/bubugao.mp3");
}

static {
    System.loadLibrary("lalala");
}

/**
 * wav转换成mp3的本地方法
 *
 * @param wav
 * @param mp3
 */
public native void convertmp3(String wav, String mp3);

然后根据javah命令生成.h文件com_wjj_lame_MainActivity.h,然后根据新建一个.c的文件,实现定义头里面的方法函数

/**
 * wav转换mp3
 */
JNIEXPORT void JNICALL Java_com_wjj_lame_MainActivity_convertmp3
(JNIEnv * env, jobject obj, jstring jwav, jstring jmp3) {
   char* cwav =Jstring2CStr(env,jwav) ;
   char* cmp3=Jstring2CStr(env,jmp3);
   LOGI("amr = %s", cwav);
   LOGI("mp3 = %s", cmp3);

   //1.打开 wav,MP3文件
   FILE* fwav = fopen(cwav,"rb");
   FILE* fmp3 = fopen(cmp3,"wb");

   short int wav_buffer[8192*2];
   unsigned char mp3_buffer[8192];

   //1.初始化lame的编码器
   lame_t lame =  lame_init();
   //2. 设置lame mp3编码的采样率
   lame_set_in_samplerate(lame , 8000);
   lame_set_num_channels(lame,1);
   lame_set_out_samplerate(lame, 8000);
   lame_set_brate(lame, 8);
   lame_set_quality(lame, 7);
   // 3. 设置MP3的编码方式
   //lame_set_VBR(lame, vbr_default);
   lame_init_params(lame);
   LOGI("lame init finish");
   int read ; int write; //代表读了多少个次 和写了多少次
   int total=0; // 当前读的wav文件的byte数目
   do{
      if(flag==404){
         return;
      }
      read = fread(wav_buffer,sizeof(short int)*2, 8192,fwav);
      total +=  read* sizeof(short int)*2;
      LOGI("converting ....%d", total);
      if(read!=0){
         write = lame_encode_buffer_interleaved(lame,wav_buffer,read,mp3_buffer,8192);
         //把转化后的mp3数据写到文件里
         fwrite(mp3_buffer,sizeof(unsigned char),write,fmp3);
      }
      if(read==0){
         lame_encode_flush(lame,mp3_buffer,8192);
      }
   }while(read!=0);
   LOGI("convert  finish");

   lame_close(lame);
   fclose(fwav);
   fclose(fmp3);
}

下面是Android.mk文件

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := lalala

LOCAL_SRC_FILES := bitstream.c com_wjj_lame_MainActivity.c encoder.c fft.c gain_analysis.c id3tag.c lame.c mpglib_interface.c newmdct.c presets.c psymodel.c quantize.c quantize_pvt.c reservoir.c set_get.c tables.c takehiro.c util.c vbrquantize.c VbrTag.c version.c

LOCAL_LDLIBS += -llog

include $(BUILD_SHARED_LIBRARY)

Application.mk文件

APP_ABI := all
APP_PLATFORM := android-8
APP_CFLAGS += -DSTDC_HEADERS

最下面的这个比较重要,当你去掉的时候,你试试会发生什么,可以试试

编译一下生成.so文件,然后运行一下,打印一下log信息

04-26 14:50:23.847 19249-19249/com.wjj.lame I/System.out.c: amr = /sdcard/1KHz-stero.wav
04-26 14:50:23.847 19249-19249/com.wjj.lame I/System.out.c: mp3 = /sdcard/bubugao.mp3
04-26 14:50:23.917 19249-19249/com.wjj.lame I/System.out.c: lame init finish
04-26 14:50:23.927 19249-19249/com.wjj.lame I/System.out.c: converting ....32768
04-26 14:50:24.037 19249-19249/com.wjj.lame I/System.out.c: converting ....65536
04-26 14:50:24.137 19249-19249/com.wjj.lame I/System.out.c: converting ....98304
04-26 14:52:40.207 19249-19249/com.wjj.lame I/System.out.c: convert  finish

然后在手机文件中也找到了我们所转换后的mp3文件,音乐的质量差不多,但是体积小了不少。

然后有人会问既然lame能够转换成mp3那能不能把amr数据也通过这种方式转换为mp3啊,听着还挺合理的,大家可以转转试试,结果呢,转换出来的文件声音很短,有问题,这是为什么呢?(这里要感谢 少-数字广播 的讲解支持)
原因呢是这样的,音频分为解码和编码,为什么wma可以直接通过方法转为mp3数据,而amr不行呢,因为wma就是原始的pcm数据加了一个数据头组成的,而amr的格式是pcm数据的压缩格式,并不能直接转为mp3数据,需要先对amr数据进行解码,生成pcm原始音频数据,然后对pcm进行mp3的编码过程,然后把编码后的mp3数据放到一个文件中,就可以了。

参考资料:
http://stackoverflow.com/questions/27893149/android-ndk-for-x86-64-has-no-reference-for-bcopy-and-index
http://www.cnblogs.com/ct2011/p/4080193.html
http://blog.csdn.net/allen315410/article/details/42456661

查看评论

Android JNI开发之使用Lame将录音转MP3

由于在写之前在网上搜了搜,发现GIthub上已经有AndroidStudio版使用Lame转Mp3的了,所以这篇博客写的例子是Eclipse版本,所以如果是AS的请移步到别人之前已经写好的Github...
  • Airsaid
  • Airsaid
  • 2016-06-10 19:36:36
  • 4021

Android Lame 3.99.5 生成so文件 来实现录音功能

前言就省略了, 主要是讲讲 我使用lame开源库来实现在Android平台中 将录音转MP3的方式。 使用ndk工具的时候 发生了很多的问题。 首先 电脑中已经配置了NDK工具, 并且将D:\xxxx...
  • zy987654zy
  • zy987654zy
  • 2016-05-13 13:58:25
  • 1963

Android Studio下编译lame

Android Studio项目实装lame的开源库实现录音转码mp3的功能。
  • railguninhere
  • railguninhere
  • 2016-05-11 15:49:08
  • 1598

Android 之NDK实战系列(3)——Android Studio下使用lame 进行简单的转换

首先,介绍下今天使用的工具——Lame LAME 是最好的MP3编码器,编码高品质MP3的最好也是唯一的选择。LAME本身是控制台程序,需要加外壳程序才比较容易使用,也可以在别的软件(比如EAC)中间...
  • Adrian24
  • Adrian24
  • 2016-12-05 14:57:08
  • 1342

lame静态库使用

拖入上篇博文制作的lame静态库到工程,包括libmp3lame.a lame.h两个文件,如下图左侧 附lame使用工具类LameTool #import @interface La...
  • callzjy
  • callzjy
  • 2016-11-29 16:30:53
  • 1379

使用lame转换音频时遇到的杂音问题

最近项目增加了录音功能,ios端需要将WAV格式音频转换成MP3然后上传到服务器,项目中用到了lame,音频转换都成功了,但是出现了杂音的问题,经过查资料和自己研究解决了问题,新手发表,有错误请多指教...
  • lixin5683
  • lixin5683
  • 2017-05-05 11:25:36
  • 1013

将lame移植到Android

一. 下载lame源码 二. 编写Android.mk ,放在lame源码根目录,编译 以下是Android.mk的内容: LOCAL_PATH := $(call my-dir) ######...
  • zcy33415
  • zcy33415
  • 2014-11-27 18:05:32
  • 326

android Studio下Lame的简单使用

  • 2016年12月05日 14:52
  • 30.66MB
  • 下载

Android移植lame库(采用CMake)

貌似许多人都是从lame库开始入门Android NDK开发的,在网上一搜一大堆详细教程。本篇的亮点是采用Google推荐的CMake工具(不是ndk-builder)来移植lame项目。重点写一下与...
  • javine
  • javine
  • 2017-06-15 15:57:45
  • 725

android studio 移植lame

前面了解jni的基本调用。 移植了lame练习一下。 lame是音频转码的非常好的库。 去网上搜一下,下载,需要自备梯子翻墙。地址https://sourceforge.net/projects/...
  • spinchao
  • spinchao
  • 2016-08-04 16:23:04
  • 167
    个人资料
    专栏达人
    等级:
    访问量: 21万+
    积分: 2362
    排名: 1万+
    博客专栏