您的位置:首页 > 编程语言 > Java开发

(八)用JAVA编写MP3解码器——解码增益因子

2013-12-18 12:03 393 查看
解码一帧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的增益因子时用到的输入值:

slen0[]、slen1[]:从上图中看出增益因子的值为位流中读取0..5位的值,当前究竟应该取几位,由这两个常量表给出。
粒度组信息gri:用于判断块的类型的成员变量block_type、mixed_block_flag值已经在上一步中初始化。
scfsi:其值已在上一步初始化,若scfsi[0..3]=1表示增益因子共用。

解码MPEG 2.0的增益因子时用到的输入值:

i_slen2[]:强度立体声(intensity stereo)的增益因子(scalefactor)比特数,变量名中的2表示是MPEG 2.0版。从伪码算法看出解码时需要从位流中读入0..4位,这个常量表的值给出当前应该读多少位。

n_slen2[]:正常(normal)编码的增益因子(scalefactor,简称sf)比特数,这个常量表的值给出当前应该读多少位。

常量表i_slen2[]和n_slen2[]的取值见ISO/IEC 13818-3 subclause 2.4.3.2 slenx x=1..4,这两个常量表已经在Layer3的构造方法内被初始化。

nr_of_sfb[3][6][4]:MPEG 2.0的增益因子被分割为4部分,故nr_of_sfb的第3维长度为4;根据块的类型和scalefac_compress值增益因子频带(简称sfb)每部分的个数(number)分为6种情况,6种情况下其个数各不相同,故nr_of_sfb的第2维长度为6;根据帧边信息中block_type和mixed_block_flag这两个成员的值,共分为3种不同的块类型,故nr_of_sfb的第1维长度为3。我把nr_of_sfb设计为这样的结构,是考虑到和逆量化取得增益因子的值顺序一致。

解码增益因子得到的值:

增益因子用去的比特数保存在part2_bits中,供后续的哈夫曼解码时计算主数据的比特数。
解码得到的增益因子的值,长块的放入scfL[2][23];
得到的增益因子的值,短块(包括纯短块和混合块中的短块)的值保存在scfS[2][3][13]中,得到的这些值供后续的逆量化使用,这些值在数组中的存放顺序要和逆量化时读取的顺序一致,这样效率更高一些。

  解码MPEG 1.0和MPEG 2.0/2.5增益因子的方法差别很大,这里定义了两个版本的方法。这里涉及到的“纯短块”、“长块”、“混合块”、“窗”概念,在逆量化中再作说明。根据上面对常量及变量值的描述中提及的“共用”、“块的类型”、“窗”就很容易看懂getScaleFactors_x()方法中的if语句和for语句的作用;短块内每个子带分3窗,所以有2重循环。

class Layer3内定义的getScaleFactors_x()方法源码:

//2.
//>>>>SCALE FACTORS========================================================
private static int[][] scfL;		// [2][23];
private static int[][][] scfS;		// [2][3][13];
private static int[] i_slen2;		// MPEG 2.0 slen for intensity stereo
private static int[] n_slen2;		// MPEG 2.0 slen for 'normal' mode
// slen: 增益因子(scalefactor)比特数
private static byte[][][] nr_of_sfb;//[3][6][4]

/*
* MPEG 2.0/2.5
*/
private void getScaleFactors_2(final int ch, final int gr) {
byte[] nr;
int i, bandIdx, win, slen, num, n = 0, scf = 0;
boolean i_stereo = objHeader.isIStereo();
GRInfo gri = objSI.ch[ch].gr[gr];
int[] l = scfL[ch];
int[][] s = scfS[ch];

rzero_bandL = 0;
if ((ch > 0) && i_stereo)
slen = i_slen2[gri.scalefac_compress >> 1];
else
slen = n_slen2[gri.scalefac_compress];

gri.preflag = (slen >> 15) & 0x1;
gri.part2_bits = 0;
if (gri.block_type == 2) {
n++;
if ((gri.mixed_block_flag) != 0)
n++;
nr = nr_of_sfb
[(slen >> 12) & 0x7];

for (i = 0; i < 4; i++) {
num = slen & 0x7;
slen >>= 3;
if (num != 0) {
for (bandIdx = 0; bandIdx < nr[i]; bandIdx += 3) {
for (win = 0; win < 3; win++)
s[win][scf] = bsMainInfo.getBits17(num);
scf++;
}
gri.part2_bits += nr[i] * num;
} else {
for (bandIdx = 0; bandIdx < nr[i]; bandIdx += 3) {
for (win = 0; win < 3; win++)
s[win][scf] = 0;
scf++;
}
}
}

n = (n << 1) + 1;
for (i = 0; i < n; i += 3) {
for (win = 0; win < 3; win++)
s[win][scf] = 0;
scf++;
}
} else {
nr = nr_of_sfb
[(slen >> 12) & 0x7];
for (i = 0; i < 4; i++) {
num = slen & 0x7;
slen >>= 3;
if (num != 0) {
for (bandIdx = 0; bandIdx < nr[i]; bandIdx++)
l[scf++] = bsMainInfo.getBits17(num);
gri.part2_bits += nr[i] * num;
} else {
for (bandIdx = 0; bandIdx < nr[i]; bandIdx++)
l[scf++] = 0;
}
}

n = (n << 1) + 1;
for (i = 0; i < n; i++)
l[scf++] = 0;
}
}

/*
* MPEG 1.0
*/
private static final int slen0[] = { 0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4 };
private static final int slen1[] = { 0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3 };

private void getScaleFactors_1(final int ch, final int gr) {
GRInfo gri = objSI.ch[ch].gr[gr];
int scale_comp = gri.scalefac_compress;
int length0 = slen0[scale_comp];
int length1 = slen1[scale_comp];
int sfb, win;
int[] l = scfL[ch];
int[][] s = scfS[ch];

gri.part2_bits = 0;

if (gri.window_switching_flag != 0 && gri.block_type == 2) {
if (gri.mixed_block_flag != 0) {
// MIXED block
gri.part2_bits = 17 * length0 + 18 * length1;
for (sfb = 0; sfb < 8; sfb++)
l[sfb] = bsMainInfo.getBits9(length0);

for (sfb = 3; sfb < 6; sfb++)
for (win = 0; win < 3; win++)
s[win][sfb] = bsMainInfo.getBits9(length0);

for (sfb = 6; sfb < 12; sfb++)
for (win = 0; win < 3; win++)
s[win][sfb] = bsMainInfo.getBits9(length1);
} else {
// pure SHORT block
gri.part2_bits = 18 * (length0 + length1);
for (sfb = 0; sfb < 6; sfb++)
for (win = 0; win < 3; win++)
s[win][sfb] = bsMainInfo.getBits9(length0);
for (sfb = 6; sfb < 12; sfb++)
for (win = 0; win < 3; win++)
s[win][sfb] = bsMainInfo.getBits9(length1);
}
} else {
// LONG types 0,1,3
int[] scfsi = objSI.ch[ch].scfsi;
if (gr == 0) {
gri.part2_bits = 10 * (length0 + length1) + length0;
for (sfb = 0; sfb < 11; sfb++)
l[sfb] = bsMainInfo.getBits9(length0);
for (sfb = 11; sfb < 21; sfb++)
l[sfb] = bsMainInfo.getBits9(length1);
} else {
gri.part2_bits = 0;
if (scfsi[0] == 0) {
for (sfb = 0; sfb < 6; sfb++)
l[sfb] = bsMainInfo.getBits9(length0);
gri.part2_bits += 6 * length0;
}
if (scfsi[1] == 0) {
for (sfb = 6; sfb < 11; sfb++)
l[sfb] = bsMainInfo.getBits9(length0);
gri.part2_bits += 5 * length0;
}
if (scfsi[2] == 0) {
for (sfb = 11; sfb < 16; sfb++)
l[sfb] = bsMainInfo.getBits9(length1);
gri.part2_bits += 5 * length1;
}
if (scfsi[3] == 0) {
for (sfb = 16; sfb < 21; sfb++)
l[sfb] = bsMainInfo.getBits9(length1);
gri.part2_bits += 5 * length1;
}
}
}
}
//<<<<SCALE FACTORS========================================================
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: