转载请声明出处:http://blog.csdn.net/andrexpert/article/77683776
一、Mp3编码格式分析
MP3,全称MPEG Audio Layer3,是一种高效的计算机音频编码方案,它以较大的压缩比(1:10至1:12)将音频文件转换成较小的扩展名为.mp3的文件,且能基本保持原文件的音质。假如有一个4分钟的CD音质的WAV音频,其音频参数为44.1kHz抽样、立体声、采样精度为16位(2字节),那么该音频所占空间为441000*2(声道)*2(字节)*60(秒)*4(分钟)=40.4MB,而对于MP3格式来说,MP3音频只占4MB左右,有利于存储和网络传输。
1. MP3文件结构
MP3文件有由帧(frame)构成的,帧是MP3文件最小的组成单位。MP3音频文件本身没有头部,当希望读取有关MP3音频文件的信息时,可以读取第一帧的头部信息,因此可以切割MP3音频文件的任何部分进行正确播放。整个MP3文件结构大体包括三部分,即TAG_V2(ID3V2)、Frame、TAG_V1(ID3V1),具体描述如下:
2. MP3帧格式
每个帧都是独立的,它由帧头、附加信息和声音数据组成,其长度随位率的不同而不等,通常每个帧的播放时间为0.026秒。MP3帧结构如下:
每帧的帧头占4字节(32位),帧头后面可能有两个字节的CRC校验,这两个字节的是否存在取决于帧头部的第16bit,如果为0,则帧头后面无校验,为1则有校验。帧头结构如下:
typedefstruct-tagHeader{
unsigned int sync: 占11位 //同步信息
unsigned int version: 2; //版本
unsigned int layer: 2; //层
unsigned int error2protection: 1; //CRC校正
unsigned int bit2rate2index: 4; //位率索引
unsigned int sample2rate2index: 2; //采样率索引
unsigned int padding: 1; //空白字
unsigned int extension: 1; //私有标志
unsigned int channel2mode: 2; //立体声模式
unsigned int modeextension: 2 ;//保留
unsigned int copyright: 1; //版权标志
unsigned int original: 1; //原始媒体
unsigned int emphasis: 2 ;//强调方式
} HEADER;
其中,sync为同步信息,占11位,全部被设置为1;channel2mode为立体声通道模式,占2为,11表示Single立体声(Mono);其他参数请看这篇文章。
二、lame编译与封装
1. Lame库简介
Lame是Mike Cheng于1998年发起的一个开源项目,是目前最好的MP3编码引擎。Lame编码出来的MP3音色纯厚、空间宽广、低音清晰、细节表现良好,它独创的心理音响模型技术保证了CD音频还原的真实性,配合VBR和ABR参数,音质几乎可以媲美CD音频,但文件体积却非常小。
最新版下载:https://sourceforge.net/projects/lame/files/lame/3.99/
2. Lame库编译与封装
(1) 移植Lame库到Android工程
a. 解压lame-3.99.5,将源码中的libmp3lame目录拷贝到Android工程的cpp目录下;
b. 将libmp3lame重命名为lame,并删除i386目录、vector目录、depcomp、lame.rc、logoe.ico、Makefile.am、Makefile.in文件;
c. 拷贝源码中inlude目录下lame.h文件到Android工程cpp目录下lame目录中,lame.h头文件包含了所有调用函数的声明;
d. 配置CMakeLists.txt文件
set(SRC_DIR src/main/cpp/lame)
include_directories(src/main/cpp/lame)
aux_source_directory(src/main/cpp/lame SRC_LIST)
add_library(...... ${SRC_LIST})
(2) LameMp3.java,创建调用lame库函数的native方法
/** JNI调用lame库实现mp3文件封装
* Created by Jiangdg on 2017/6/9.
*/
public class LameMp3 {
// 静态加载共享库LameMp3
static {
System.loadLibrary("LameMp3");
}