`
lfp001
  • 浏览: 98550 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论
文章列表
  【内容提要】 《用JAVA编写MP3解码器》系列文章将对JAVA实现MP3解码的技术细节作介绍,本着开源的精神,文中给出完整的MPEG 1.0/2.0/2.5 Audio Layer I/II/III 解码的JAVA源代码。在哈夫曼解码、逆量化和重排序、多相合成滤波等模块中采用了卓有成效方法来提高程序运行效率;采用了IMDCT、DCT经典的快速算法,根据自己对算法的理解编写代码,对快速算法有详细的推导和说明;整个程序采用模块化设计,程序结构比较清晰。即使你之前对JAVA语言不太熟悉,由于JAVA的语法类似于C语言,也是很容易看懂的。   对解码规范理解不到位导致的错误和疏漏之处再所难免 ...
以下代码是开源(GPL)程序jmp123的一部分。   (一)简单的GUI   在jmp123.jar所在目录为当前目录启动jmp123.jar,启动时自动加载default.m3u、bk1.jpg、bk2.jpg; 为方便测试MP3解码器,简体中文环境时播放器有网络搜索MP3功能,出于对某MP3网站的尊重,源代码中未附上搜索功能的源代码,请谅解。请勿对程序反相查看源代码,请自觉遵守:) (二)解码速度测试  完全解码但不播放输出: java -cp jmp123.jar jmp123.test.Test1 <MP3文件名> 这个纯JAVA解码器的速度 ...
  1.定义解码一帧的接口   ILayer123   Layer1、Layer2和Layer3这三个类都实现了ILayer123的decodeFrame方法。 // ILayer123.java package jmp123.decoder; public interface ILayer123 { public void decodeFrame(int intFirstChannel, int intLastChannel) throws Exception; }     2.封装解码器 对帧头解码之后可以知道当前待解码的文件是采用MPEG Audio的哪一层压缩 ...
      Layer1的编码更简单,解码端的代码也就比Layer2还简单不少。网络上还有部分老歌是采用Layer2压缩的,但Layer1编码方式的就很难找到了,手头的编码器没有Layer1编码方式,所以这些代码没有经过测试,不详细讲解解码过程了。作为一个完整的MPEG Audio解码器,我还是加入了这部分代码。解码Layer1的源码: /* * Layer1.java -- MPEG 1.0 Audio Layer I Decoder * * This program is free software: you can redistribute it and/or modify * ...
      MPEG 1.0/2.0/2.5 对声音的压缩分三层:Layer I、Layer II和Layer III。相比于Layer3,Layer2的解码就简单得多了。       1.变量初始化  申明的成员变量在构造方法内初始化,这些常量值是从解码规范的文档里直接COPY过来的。       2.帧的数据结构  以Layer2编码的文件按帧存放,解码时也是逐帧解码。每一帧内依次存放位分配信息、增益因子选择信息、增益因子、主数据。采用标准立体声编码的Layer2一帧内的主数据有12个粒度组(granule),一个粒度组内最多可有32个子带(subband),每个子带两个声道。每个声道 ...
解码一帧Layer3第10步:音频输出  -- class Audio         这里给出音频输出的示例代码,后文给出的播放器是基于命令行,所以音频输出模块就写得很简单,如果你想了解音频输出细节,请查阅《Java API文档》中javax.sound.sampled库相关方法的文档。源码中第37行调用objSDL.open方法时设置了音频缓冲区大小为176400字节。音频缓冲应该设置多大比较好呢?这和你的音频硬件有关,缓冲区设置为合适的值有利于提高性能(官方文档上是这么说的)。前面讲到采用标准立体声编码的MP3一帧有2304个PCM样本,16位PCM输出时长度为4608字节。若PCM ...
解码一帧Layer3第8步:多相频率倒置 (Inverse Quantize Samples)       也可以称为频率倒相(Frequency Inversion),在数据进入多相滤波器前进行频率倒相,把奇数序号子带的奇数号样本乘上-1,这样做的目的是校正多相滤波器组对频率的倒相。为了充分利用decodeFrame方法内的循环,把这部分简短的代码放进decodeFrame内。   解码一帧Layer3第9步:多相合成滤波 (Poly Phase Synthesis Filterbank)        多相合成滤波是调用频度最高的一个模块,采用标准立体声编码 ...
解码一帧Layer3第7步:IMDCT和子带混合 -- class Layer3内的hybrid方法         这一步可细分为3个步骤:       1.初始化加窗系数floatWinIMDCT[][]  初始化floatWinIMDCT[][]时直接代入相关公式,我这事先另外编程用公式把加窗系数计算出来,供程序中直接查表使用,而不是运行时进行初始化。初始化floatWinIMDCT[][]的代码正好还留着,就顺便贴出来: public class InitIMDCT { public static void main(String args[]) { int i, j ...
解码一帧Layer3第6步:消混叠处理 -- class Layer3的antialias方法         消混叠(antialias)处理就是消除伪信号。相邻两个子带间互相干扰造成失真,为了减小这种影响,在信号送入IMDCT之前作消混叠处理。消混叠通过对子带作8点的蝶形变换实现。原理如下图:  图1  图2       经过逆量化后得到频域信号,一个粒度组内一个声道内共576个频谱值,将576个频谱值被分为18个子带,每个子带32条频率线。8点的的蝶形变换在相邻的两个子带之间进行。图中cai、csi就是源码中的cs[i]和cs[i]。cs[i]和ca[i]我们在构造函数 ...
解码一帧Layer3第5步:立体声处理 -- class Layer3的ms_stereo和i_stereo方法         MP3采用的立体声编码方式有中侧立体和强度立体声两种。       1.中侧立体声(Middle/Side stereo)简称MS_stereo,在这种模式中,用中/侧声道规格化 ...
解码一帧Layer3第4步:逆量化和重排序 -- requantizer方法         1.逆量化  逆量化的功能是把哈夫曼解码得到的值还原成576个频谱值。长块、短块分别用不同的公式: 其中ISi为第i个哈夫曼码值,XRi为第i个逆量化值。     长块  576个频谱值分为21个增益因子(scale factor)频带(band),由intWidthLong[]保存这21个频带的子带(subband)宽度。intWidthLong[]的初始化见《(六)用JAVA编写MP3解码器——帧数据结构》Layer3.java第203--204行。     短块  576个频谱 ...
解码一帧Layer3第3步:哈夫曼解码 -- huffmanDecoder方法     1.哈夫曼码表 共有33张码表,从ISO/IEC 11172-3复制一张码表出来,看看码表的庐山真面目,下面说到的哈夫曼树的构造及解码过程都以这一张表为例。码表如下所示: Huffman code table 6 x y hlen hcod No. 0 0 3 111 0 0 1 3 011 1 0 2 5 00101 2 0 3 7 0000001 3 1 0 3 110 4 1 1 2 10 5 1 2 4 0011 6 1 3 5 00010 7 2 0 4 0101 8 2 1 4 010 ...
解码一帧Layer3第2步:解码增益因子  -- getScaleFactors_1()和getScaleFactors_2()方法         增益因子(Scale Factor)数据存储在帧内的主信息中。主信息包含增益因子和用哈夫曼编码的主数据(main_data)。增益因子简单讲就是逆量化公式的指数中的一个因子。手册中解码主数据的伪码算法如下,其中MPEG 1.0由ISO/IEC 11172-3给出,MPEG 2.0由ISO/IEC 13818-3给出。官方并没有MPEG2.5这个版本,这个版本是民间版本。         解码MPEG 1.0的增益因子时用到的输入值: ...
解码一帧Layer3第1步:帧边信息解码 -- getSideInfo()方法         帧边信息用于描述一帧内的主信息(增益因子和主数据)特征,而后文讲到的解码的增益因子、主数据是描述一个声道的,换一种说法,帧边信息每帧连续存储在一 ...
      MP3文件按帧(frame)依次存储,解码时也是逐帧解码,所以我们应该首先弄清MP3帧内的数据的封装形式。帧的结构如下图所示:         图中sync表示帧同步字,每一帧以同步字开始;side info表示帧边信息;main_data_end是帧边信息结构中的一个成员。       每一帧依次存放帧头(header)、帧边信息(side information)、主信息(main information)。其中的主信息由增益因子(scale factor)和主数据(main data)组成。       每一帧的帧头长4字节,如果帧头信息中的protection_ ...
Global site tag (gtag.js) - Google Analytics