您的位置:首页 > 移动开发 > Android开发

Android 编译Lame&简单使用

2016-05-04 10:18 591 查看
上一篇文章介绍了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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: