Android 音频开发 目录

  1. Android音频开发(1):音频相关知识
  2. Android音频开发(2):使用AudioRecord录制pcm格式音频
  3. Android音频开发(3):使用AudioRecord实现录音的暂停和恢复
  4. Android音频开发(4):PCM转WAV格式音频
  5. Android音频开发(5):Mp3的录制 - 编译Lame源码
  6. Android音频开发(6):Mp3的录制 - 使用Lame实时录制MP3格式音频
  7. Android音频开发(7):音乐可视化-FFT频谱图

项目地址

https://github.com/zhaolewei/ZlwAudioRecorder


编译 so包

1.下载lame

官网(科学上网): http://lame.sourceforge.net/download.php
lame-3.100:https://pan.baidu.com/s/1U77GAq1nn3bVXFMEhRyo8g

2.使用ndk-build编译源码

2.1 在任意位置创建如下的目录结构:

Android音频开发(5):Mp3的录制 - 编译Lame源码_第1张图片 image

文件夹名称随意,与.mk 文件中路径一致即可

2.2 解压下载好的lame源码
解压后将其/lame-3.100/libmp3lame/目录中.c和.h文件和/lame-3.100//include/中的 lame.h拷贝到/jni/lame-3.100_libmp3lame中

3.100版本 有42个文件

2.3 修改部分文件

  1. 删除fft.c文件的47行的#include "vector/lame_intrin.h"
  2. 删除set_get.h文件的24行的#include
  3. 将util.h文件的570行的extern ieee754_float32_t fast_log2(ieee754_float32_t x); 替换为 extern float fast_log2(float x);

2.4 编写Mp3Encoder.c 和 Mp3Encoder.h 对接java代码

2.4.1 Mp3Encoder.c

  • 注意修改包名
#include "lame-3.100_libmp3lame/lame.h"#include "Mp3Encoder.h"static lame_global_flags *glf = NULL;//TODO这里包名要与java中对接文件的路径一致(这里是路径是com.zlw.main.recorderlib.recorder.mp3,java文件: Mp3Encoder.java),下同JNIEXPORT void JNICALL Java_com_zlw_main_recorderlib_recorder_mp3_Mp3Encoder_init(        JNIEnv *env, jclass cls, 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);}JNIEXPORT jint JNICALL Java_com_zlw_main_recorderlib_recorder_mp3_Mp3Encoder_encode(        JNIEnv *env, jclass cls, 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;}JNIEXPORT jint JNICALL Java_com_zlw_main_recorderlib_recorder_mp3_Mp3Encoder_flush(        JNIEnv *env, jclass cls, 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;}JNIEXPORT void JNICALL Java_com_zlw_main_recorderlib_recorder_mp3_Mp3Encoder_close(        JNIEnv *env, jclass cls) {    lame_close(glf);    glf = NULL;}

2.4.2 Mp3Encoder.h

  • 注意修改包名
/* DO NOT EDIT THIS FILE - it is machine generated */#include #ifndef _Included_Mp3Encoder#define _Included_Mp3Encoder#ifdef __cplusplusextern "C" {#endif/* * Class:     com.zlw.main.recorderlib.recorder.mp3.Mp3Encoder * Method:    init */JNIEXPORT void JNICALL Java_com_zlw_main_recorderlib_recorder_mp3_Mp3Encoder_init  (JNIEnv *, jclass, jint, jint, jint, jint, jint);JNIEXPORT jint JNICALL Java_com_zlw_main_recorderlib_recorder_mp3_Mp3Encoder_encode  (JNIEnv *, jclass, jshortArray, jshortArray, jint, jbyteArray);JNIEXPORT jint JNICALL Java_com_zlw_main_recorderlib_recorder_mp3_Mp3Encoder_flush  (JNIEnv *, jclass, jbyteArray);JNIEXPORT void JNICALL Java_com_zlw_main_recorderlib_recorder_mp3_Mp3Encoder_close  (JNIEnv *, jclass);#ifdef __cplusplus}#endif#endif

2.5 编写Android.mk 和Application.mk

  • 路径与创建的目录应当一致

2.5.1 Android.mk

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LAME_LIBMP3_DIR := lame-3.100_libmp3lameLOCAL_MODULE    := mp3lameLOCAL_SRC_FILES :=\$(LAME_LIBMP3_DIR)/bitstream.c \$(LAME_LIBMP3_DIR)/fft.c \$(LAME_LIBMP3_DIR)/id3tag.c \$(LAME_LIBMP3_DIR)/mpglib_interface.c \$(LAME_LIBMP3_DIR)/presets.c \$(LAME_LIBMP3_DIR)/quantize.c \$(LAME_LIBMP3_DIR)/reservoir.c \$(LAME_LIBMP3_DIR)/tables.c  \$(LAME_LIBMP3_DIR)/util.c \$(LAME_LIBMP3_DIR)/VbrTag.c \$(LAME_LIBMP3_DIR)/encoder.c \$(LAME_LIBMP3_DIR)/gain_analysis.c \$(LAME_LIBMP3_DIR)/lame.c \$(LAME_LIBMP3_DIR)/newmdct.c \$(LAME_LIBMP3_DIR)/psymodel.c \$(LAME_LIBMP3_DIR)/quantize_pvt.c \$(LAME_LIBMP3_DIR)/set_get.c \$(LAME_LIBMP3_DIR)/takehiro.c \$(LAME_LIBMP3_DIR)/vbrquantize.c \$(LAME_LIBMP3_DIR)/version.c \MP3Encoder.cinclude $(BUILD_SHARED_LIBRARY)

2.5.2 Application.mk

  • 若只需要编译armeabi的so包可将其他删除
APP_ABI := armeabi  armeabi-v7a  arm64-v8a  x86  x86_64  mips  mips64APP_MODULES := mp3lameAPP_CFLAGS += -DSTDC_HEADERSAPP_PLATFORM := android-21

编译

到达这一步,所有的文件都已经准备好了
在命令行中切换到jni目录中,执行ndk-build开始编译


Android音频开发(5):Mp3的录制 - 编译Lame源码_第2张图片 image

若果不能识别ndk-build命令 需要配置下环境变量

更多相关文章

  1. 分享10个Android游戏源码,要的赶紧来哈
  2. Android音频开发(4):PCM转WAV格式音频
  3. Android音频开发(2):使用AudioRecord录制pcm格式音频
  4. Android音频开发(7):音乐可视化-FFT频谱图
  5. android动画源码合集、动态主题框架、社交app源码等
  6. Android音频开发(3):使用AudioRecord实现录音的暂停和恢复
  7. Android 无闪烁启动画面程序源码
  8. Android xml资源文件中@、@android:type、@*、?、@+的含义和区别
  9. android 布局文件详解

随机推荐

  1. Android自适应屏幕大小和layout布局
  2. Android(安卓)ListView元素间隙线自定义
  3. Android读写XML(下)――创建XML文档
  4. 菜单 Android(安卓)Menu
  5. Simple Guide for Porting Android(安卓)
  6. android命令行下创建虚拟设备avd
  7. Android(安卓)ThreadLocal及InheritableT
  8. Android(安卓)资源简介(四) ClipDrawable
  9. Android获取webView快照与屏幕截屏的方法
  10. 自定义android的tab样式