文档章节

(十七)用JAVA编写MP3解码器——解码Layer1

暗之幻影
 暗之幻影
发布于 2015/01/04 15:29
字数 654
阅读 11
收藏 0

      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
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*
* If you would like to negotiate alternate licensing terms, you may do
* so by contacting the author: <http://jmp123.sourceforge.net/>
*/
package decoder;

public final class Layer1 implements ILayer123 {
	Header header;
	BitStream bs;
	Synthesis filter;
	float[] factor;
	byte[][] allocation;	//[2][32]
	byte[][] scalefactor;	//[2][32]
	float[][] syin;			//[2][32]

	public Layer1(BitStream bitstream,Header h, Synthesis filter, int wch) {
		header = h;
		bs = bitstream;
		this.filter = filter;
		allocation = new byte[2][32];
		scalefactor = new byte[2][32];
		syin = new float[2][32];
		factor = Layer2.factor;		// ISO/IEC 11172-3 Table 3-B.1.
	}

	/*
	 * 逆量化公式:
	 * s'' = (2^nb / (2^nb - 1)) * (s''' + 2^(-nb + 1))
	 * s' = factor * s''
	 */
	float requantization(int ch, int sb, int nb) {
		int samplecode = bs.getBits17(nb);
		int nlevels = (1 << nb);
		float requ = 2.0f * samplecode / nlevels - 1.0f;	//s'''
		requ += (float)Math.pow(2, 1-nb);
		requ *= nlevels / (nlevels - 1);		//s''
		requ *= factor[scalefactor[ch][sb]];	//s'
		return requ;
	}

	public void decodeFrame() throws Exception {
		int sb, gr, ch, nb;
		int nch = header.getChannels();
		int bound = (header.getMode() == 1) ? ((header.getModeExtension() + 1) * 4) : 32;
		int slots = header.getMainDataSlots();
		bs.append(slots);
		int maindata_begin = bs.getBytePos();

		//1. Bit allocation decoding
		for (sb = 0; sb < bound; sb++)
			for (ch = 0; ch < nch; ++ch) {
				nb = bs.getBits9(4);
				if (nb == 15)
					throw new Exception("decodeFrame()->nb=15");
				allocation[ch][sb] = (byte)((nb != 0) ? (nb + 1) : 0);
			}
		for (sb = bound; sb < 32; sb++) {
			nb = bs.getBits9(4);
			if (nb == 15)
				throw new Exception("decodeFrame()->nb=15");
			allocation[0][sb] = (byte)((nb != 0) ? (nb + 1) : 0);
		}

		//2. Scalefactor decoding
		for (sb = 0; sb < 32; sb++)
			for (ch = 0; ch < nch; ch++)
				if (allocation[ch][sb] != 0)
					scalefactor[ch][sb] = (byte)bs.getBits9(6);

		for (gr = 0; gr < 12; gr++) {
			//3. Requantization of subband samples
			for (sb = 0; sb < bound; sb++)
				for (ch = 0; ch < nch; ch++){
					nb = allocation[ch][sb];
					if(nb == 0)
						syin[ch][sb] = 0;
					else
						syin[ch][sb] = requantization(ch, sb, nb);
				}
			//mode=1(Joint Stereo)
			for (sb = bound; sb < 32; ++sb)
				if ((nb = allocation[0][sb]) != 0)
					for (ch = 0; ch < nch; ++ch)
						syin[ch][sb] = requantization(ch, sb, nb);
				else
					for (ch = 0; ch < nch; ++ch)
						syin[ch][sb] = 0;
			
			//4. Synthesis subband filter
			for (ch = 0; ch < nch; ch++)
				filter.synthesisSubBand(syin[ch], ch);
		}

		//5. Ancillary bits
		int discard = slots + maindata_begin - bs.getBytePos();
		bs.skipBytes(discard);
	}
}

 

 

上一篇:(十六)用JAVA编写MP3解码器——解码Layer2

下一篇:(十八)用JAVA编写MP3解码器——迷你播放器 

 

【下载地址】http://jmp123.sourceforge.net/

本文转载自:http://lfp001.iteye.com/blog/750076

暗之幻影
粉丝 20
博文 377
码字总数 71245
作品 0
南京
高级程序员
私信 提问
(五)用JAVA编写MP3解码器——解析文件信息

前文提到解析MP3标签,程序源码中也已经出现了调用解析MP3标签、打印MP3文件信息的功能,这儿先说说MP3文件信息的解析。 解析MP3的文件信息对MP3解码器来说只是一个附加功能,如果不加入这部...

暗之幻影
2015/01/04
61
0
疯狂Spring Cloud连载(11)——Feign的编码器与解码器

本文节选自《疯狂Spring Cloud微服务架构实战》 京东购买地址:https://item.jd.com/12256011.html 当当网购买地址:http://product.dangdang.com/25201393.html Spring Cloud教学视频:htt...

杨大仙的程序空间
2017/10/23
3.1K
5
Java8 BASE64编解码

Java8 BASE64编解码 Base64是一种用64个字符来表示任意二进制数据的方法。 Base64是一种最常见的二进制编码方法。 Java一直缺少BASE64编码 API,以至于通常在项目开发中会选用第三方的API...

秋风醉了
2015/04/02
1K
0
【直播预告】阿里特邀专家徐雷Java Spring Boot开发实战系列课程(第18讲):制作Java Docker镜像与推送到DockerHub和阿里云Docker仓库

主讲人:徐雷(阿里云栖特邀Java专家) 徐雷,花名:徐雷frank;资深架构师,MongoDB中文社区联席主席,吉林大学计算机学士,上海交通大学硕士。从事了 10年+开发工作,专注于分布式架构,J...

李博bluemind
03/05
0
0
Spring Cloud OpenFeign集成Protocol Buffer

本文作者张天,著有《Spring Cloud 微服务架构进阶》一书。 背景  在之前的文章中,我们介绍过基于Spring Cloud微服务架构,其中,微服务实例之间的交互方式一般为RESTful HTTP请求或RPC调用...

aoho
2018/10/07
0
0

没有更多内容

加载失败,请刷新页面

加载更多

springboot 403 问题

添加WebAppConfigurer 配置 @Configuration@EnableAutoConfigurationpublic class WebAppConfigurer extends WebMvcConfigurerAdapter { public WebAppConfigurer() { } ......

布袋和尚_爱吃鱼
11分钟前
3
0
Python自动更换壁纸爬虫与tkinter结合

直接上代码 import ctypesimport timeimport requestsimport osfrom threading import Threadfrom tkinter import Tk, Label, Button,Entry,StringVar,messagebox# '放到AppData\Roami......

物种起源-达尔文
12分钟前
2
0
Postgresql Study 笔记

Postgresql 安装 Windows, MAC Install Postgresql 下载地址: https://www.enterprisedb.com/downloads/postgres-postgresql-downloads Linux Install sudo apt-get update sudo apt-get in......

slagga
14分钟前
3
0
layer.open 打开新页面传参问题

如图所示,点击出售,把A页面的数据传到弹框上面,因为弹框比较复杂,所以使用引入一个新页面。 A.html a.js B.html b.js 1、第一种方案 sellInte: function (){ var obj = document.g...

木九天
16分钟前
3
0
沙龙报名 | 区块链数据服务技术应用实践

京东云是国内首家提供区块链数据在线分析服务产品的公司,也是行业内首家对区块链数据服务进行开源的公司。 本次沙龙是京东云BDS开源后,首次在深圳举办线下沙龙,我们将邀请京东云BDS团队核...

京东云技术新知
17分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部