内容提要】 《用JAVA编写MP3解码器》系列文章将对JAVA实现MP3解码的技术细节作介绍,本着开源的精神,文中给出完整的MPEG 1.0/2.0/2.5 Audio Layer I/II/III 解码的JAVA源代码。在哈夫曼解码、逆量化和重排序、多相合成滤波等模块中采用了卓有成效方法来提高程序运行效率;采用了IMDCT、DCT经典的快速算法,根据自己对算法的理解编写代码,对快速算法有详细的推导和说明;整个程序采用模块化设计,程序结构比较清晰。即使你之前对JAVA语言不太熟悉,由于JAVA的语法类似于C语言,也是很容易看懂的。

  对解码规范理解不到位导致的错误和疏漏之处再所难免,欢迎批评指正。

 

  【许可协议】   文中给出的MPEG 1.0/2.0/2.5 Audio Layer I/II/III 解码的JAVA源代码是一个自由软件,你可以重新发布和(或)修改,必须遵守GPL v3.0(GNU Lesser General Public License version 3)协议。发布这一程序的目的是希望它有用,但不提供任何担保;甚至不包括用于商业的和为特殊目的在内的任何保证。你可以从“ GNU公用通用许可3.0版 ”或者通过阅读本文附件中的GPLv3.txt中找到更多细节。

 

  【文件下载】   请到 http://jmp123.sf.net/ 下载本程序、源码和MP3解码文档。

 

  【目录】 《用JAVA编写MP3解码器》系列共18篇,每篇的第一个网址是本站论坛,第二个是我的博客。

 

(一)用JAVA编写MP3解码器——前言
http://www.iteye.com/topic/739585

http://lfp001.iteye.com/blog/739585

 

(二)用JAVA编写MP3解码器——帧头信息解码
http://www.iteye.com/topic/739606

http://lfp001.iteye.com/blog/739606

 

(三)用JAVA编写MP3解码器——读取位流
http://www.iteye.com/topic/739678

http://lfp001.iteye.com/blog/739678

 

(四)用JAVA编写MP3解码器——读取文件
http://www.iteye.com/topic/740090

http://lfp001.iteye.com/blog/740090

 

(五)用JAVA编写MP3解码器——解析文件信息
http://www.iteye.com/topic/740930

http://lfp001.iteye.com/blog/740930

 

(六)用JAVA编写MP3解码器——帧数据结构
http://www.iteye.com/topic/741558

http://lfp001.iteye.com/blog/741558

 

(七)用JAVA编写MP3解码器——解码帧边信息
http://www.iteye.com/topic/742913

http://lfp001.iteye.com/blog/742913

 

(八)用JAVA编写MP3解码器——解码增益因子
http://www.iteye.com/topic/743318

http://lfp001.iteye.com/blog/743318

 

(九)用JAVA编写MP3解码器——哈夫曼解码
http://www.iteye.com/topic/744000

http://lfp001.iteye.com/blog/744000

 

(十)用JAVA编写MP3解码器——逆量化和重排序
http://www.iteye.com/topic/744417  

http://lfp001.iteye.com/blog/744417

 

(十一)用JAVA编写MP3解码器——立体声处理
http://www.iteye.com/topic/746850

http://lfp001.iteye.com/blog/746850

 

(十二)用JAVA编写MP3解码器——消混叠处理
http://www.iteye.com/topic/748157

http://lfp001.iteye.com/blog/748157

 

(十三)用JAVA编写MP3解码器——IMDCT快速算法
http://www.iteye.com/topic/749785

http://lfp001.iteye.com/blog/749785

 

(十四)用JAVA编写MP3解码器——多相合成滤波
http://www.iteye.com/topic/749974

http://lfp001.iteye.com/blog/749974

 

(十五)用JAVA编写MP3解码器——音频输出
http://www.iteye.com/topic/750060

http://lfp001.iteye.com/blog/750060

 

(十六)用JAVA编写MP3解码器——解码Layer2
http://www.iteye.com/topic/750070

http://lfp001.iteye.com/blog/750070

 

(十七)用JAVA编写MP3解码器——解码Layer1
http://www.iteye.com/topic/750076

http://lfp001.iteye.com/blog/750076

 

(十八)用JAVA编写MP3解码器——迷你播放器
http://www.iteye.com/topic/751013

http://lfp001.iteye.com/blog/751013

 

【附录】  

1.源码测试   不提供测试源码的任何担保,甚至不包括用于商业的和为特殊目的在内的任何保证。

MP3解码的JAVA源码和原理简介在本站论坛和本站我的博客上陆续写出来,这需要一个比较漫长的过程。

(1)Windows操作系统,JDK安装在F:\jdk1.6.0_12,各源文件(*.java)的目录结构如下:

F:\JMP123\SRC
├─decoder
│      Decoder.java
│      HuffmanBits.java
│      BitStream.java
│      Layer3.java
│      Synthesis.java
│      Header.java
│      Layer2.java
│      ILayer123.java
│      Layer1.java

├─test
│      Player.java

├─instream
│      IRandomAccess.java
│      BuffRandAcceFile.java
│      HttpReader.java
│      BuffRandAcceURL.java
│      IWriterCallBack.java
│      Writer.java
│      TagThread.java

├─tag
│      ID3Tag.java

└─output
        Audio.java

 

(2)建立文件F:\jmp123\manifest.mf,第一行:

Main-Class: test.Player

第二行是空行。

 

(3)Windows平台下,建立对各源文件编译、打包的批命令文件F:\jmp123\build-win32.cmd,内容如下:

@echo off
echo 稍候...
rem ----------------------------------------------------------------
rem          JAVA mini MP3 Player WIN32 Build Script
rem ----------------------------------------------------------------
set JAVA_HOME=F:\jdk1.6.0_12
set JML=.
set LIB_PATH=%JML%\bin
if not exist %LIB_PATH% md %LIB_PATH%
rem set CLASSPATH=%JAVA_HOME%\lib\tools.jar
set PATH=%PATH%;%JAVA_HOME%\bin
set SRC_DECODER=%JML%\src\decoder
set SRC_INSTREAM=%JML%\src\instream
set SRC_OUTPUT=%JML%\src\output
set SRC_TAG=%JML%\src\tag
set SRC_PLAYER=%JML%\src\test
rem ----------------------------------------------------------------
javac -classpath %LIB_PATH% -d %LIB_PATH% %SRC_TAG%\*.java
javac -classpath %LIB_PATH% -d %LIB_PATH% %SRC_INSTREAM%\*.java
javac -classpath %LIB_PATH% -d %LIB_PATH% %SRC_OUTPUT%\*.java
javac -classpath %LIB_PATH% -d %LIB_PATH% %SRC_DECODER%\*.java
javac -classpath %LIB_PATH% -d %LIB_PATH% %SRC_PLAYER%\*.java
rem ----------------------------------------------------------------
cd %LIB_PATH%
jar cvfm ..\jmp123.jar ..\manifest.mf *
cd %JML%
rem ----------------------------------------------------------------
pause
echo on

 

(4)在 http://jmp123.sourceforge.net/ 下载源码,建立好manifest.mf文件之后,运行build-win32.cmd,在F:\jmp123目录下生成jmp123.jar文件。播放单个MP3的命令行示例:

java -jar jmp123.jar  E:\MP3\a2.mp3

java -jar jmp123.jar  http://www.cssc.com.cn/mp3/汤潮-那滋味.mp3

 

播放某目录下MP3文件批命令示例:

@echo off
echo JAVA mini MPEG 1.0/2.0/2.5 Audio Layer I/II/III Player
echo.
rem ########################设置路径#############################
set mp3path=E:\MP3\

 

set df="%mp3path%%%a"
for /f "delims=*" %%a in ('dir %mp3path%*.mp3 /b') do @echo 正在播放:%df% & java -jar jmp123.jar %df% & echo.
pause
@echo on

 

2.无论用什么样的编程语言,编写出MPEG 1.0/2.0/2.5音频解码器是不难的;编写出兼顾速度和存储开销的高效的解码器是很难的。

      我所知道的解码器,解码结果没有区别,不同的是效率问题。有人对不同的播放器作出这样的主观听感上不同评价:柔和、甜美、声音发干、偏冷等。这样的评价是值得商榷的,如果解码器是开源的,调试运行可以直接看到解码最后一步送入音频硬件的PCM数据,如果解码器不是开源的,可以编程抓取其PCM数据出来看,我测试几个解码器的结果是没的区别的。解码中间过程的计算误差是存在的,不同的解码器对同一输入解码出的中间结果(float/double类型)不同,经过最后一步乘上32767再取整得到16位整型的PCM,不同的解码器对同一输入结果就是相同的了,包括最古老的Xing MP3解码器和最新的MPG123、LIBMAD。所以不要担心你美妙的歌曲被解码器折腾得不动听了,如果追求好的音质,用专业的声卡配高品质的音箱才行。

      3.本程序运行屏幕截图~~很酷喔~~

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐