/**
* Choose the Huffman table that will encode ix[begin..end] with
* the fewest bits.
* Note: This code contains knowledge about the sizes and characteristics
* of the Huffman tables as defined in the IS (Table B.7), and will not work
* with any arbitrary tables.
*
* 选取合适的 huffman table.
*
* ix[samp_per_frame2] 量化后的信号
* begin address_begin
* end address_end
*/
int new_choose_table( int ix[samp_per_frame2],
unsigned int begin,
unsigned int end )
{
int i, max; //
int choice[2]; //
int sum[2]; /*
* sum[0] 记录table[index]下ix[begin, end]编码所需要的位元数
* sum[1] 记录table[index+1]下ix[begin, end]编码所需要的位元数
*
* index是通过 "对[0, 14]号表进行循环" 计算得来的.
*/
/* 从region中查找出最大的值, 该值是用来和15做比较的, 之后选表的时候需要用到该值得 */
max = ix_max( ix, begin, end );
/* 如果查出最大的值是0, 那么这个区段估计就是zero区段, 而不是big_value或者count1了 */
if( !max ) return 0;
/*
*
*/
choice[0] = 0;
choice[1] = 0;
/*
* linbits are used when values larger than 15 has to be encoded
*
* 由于标准中所提供的32个表中,并非所有的表都能用,而且有大量的码表只是linbits不同。
* 因此如何存储这些码表,并能够很方便地进行查询、编码,是编码过程中很关键的问题之一。
* 但提出的“多级索引”方法可以很好地的解决这一问题。过程如图2所示。对可能的表有不同的
* 处理方式
*
* 正常表 如表15,即每一级索引都是对应于表15的各项信息。
* 无效表 如表14,其最终的指向是码表零,即相当于无效表。
* 雷同表 如表16和17实际上只是在第II级索引的linbits不同,其最后的Huffman数据是相
* 同的。通过这样的多级码表地址索引可以很好的解决程序的模块化实现。
*
* 参考 << MP3编码法之研究与实现 >> Page26
*
* huffman表共有34个, 其中2个表给count1使用, 另外32个表给big_value使用. big_value区间
* 分成3个子区间region0, region1, region2. 各个region拥有各自的huffmantable.
* huffman表0-14的最大值不超过15(也就是说只能针对最大值不超过15的子区间编码), 表15-31的最
* 小值皆为15, 如果要针对超过15的频线编码, 就需要使用linbits的方法.
*
* 何谓linbits方法?
* ESCAPE = 量化后的值 - 15
* 可编码之最大值 = 15 + pow(2, linbits);
*
* ----------------------------------------------------------------------
* [0, 14]号表供max<15的region使用
* [15, 31]号表供max>=15的region使用
* [32, 33]号表供count1使用
*/
if( max < 15 )
{
/* try tables with no linbits. 不使用linbits方法, 此时使用huffmantable 0-14
* 如果max小于15, 则表在[0,14]范围上选表. 0-14号表是为这样的频谱设计的.
* 这时候不需要使用 linbits 机制.
*/
/*
*
*/
for ( i=14; i--; ) // 对[0, 14]号表进行循环
{
/* 为什么是 ht[i].xlen > max
* 而不是 ht[i].ylen > max 呢?
*
*/
if ( ht[i].xlen > max )
{
choice[ 0 ] = i;
break;
}
}
/* 计算ix[begin, end]编码所需要的位元数. */
sum[ 0 ] = count_bit( ix, begin, end, choice[0] );
/*
* [0,14]号表并不是全使用的, 只有2,5,7,10,13号表可能被使用.
* 其他表有什么作用还不清楚.
*
* 这个观点是错误的, 起初我认为只有2,5,7,10,13号表是可被使用的, 现在发现
* 不是这样的, 似乎是所有的表都是可用的. 而一些论文上也确实是说 2,5,7,10,13号表
* 被使用, 有一部分不被使用。
* 从shine的代码实现上来看似乎所有表都可使用. 这里需要深究.
*/
switch ( choice[0] )
{
/*
* 注意这里的逻辑, 觉得好奇怪.
* 之前是有通过 "对[0, 14]号表进行循环" 来查找到合适的huffman table的
* 但是这里会根据查找到的table[index]而来再用table[index+1]计算
* table[index+1]下ix[begin, end]编码所需要的位元数. 而且对于不同的
* table[index], 其逻辑是不一样的, 不知道规范是如何对此定义的.
* 日后定要回来温习这里的疑惑!
*
* ????????????????????????
*
* 看它的逻辑, 好象是table[index] 与 table[index+1] 都可以用来对ix[begin, end]
* 进行编码的, 但是要找更合适的, 那就是看在使用哪个table的时候所需要的位元数更小.
*
*/
case 2:
// table[2], table[3]是同一个阶层的.
// 所谓同一个阶层的意思就是, 一个给定的ix[begin, end]如果可以使用
// table[2]编码的话, 那使用table[3]也是可以的, 至于是选table[2]
// 还是选table[3], 那就要看二者哪个所需要的位元数更低了.
//
// 往下看的话会发现table[5]和table[6]是一个阶层的
// table[7], table[8]和table[9]是一个阶层的
// table[10], table[11]和table[12]是一个阶层的
// table[13]和table[15]是一个阶层的
sum[ 1 ] = count_bit( ix, begin, end, 3 );
if ( sum[1] <= sum[0] )
choice[ 0 ] = 3;
break;
case 5:
sum[ 1 ] = count_bit( ix, begin, end, 6 );
if ( sum[1] <= sum[0] )
choice[ 0 ] = 6;
break;
case 7:
/* 对比采用table[7], table[8], table[9]哪个码表才能占用位元数更小 */
sum[ 1 ] = count_bit( ix, begin, end, 8 );
if ( sum[1] <= sum[0] )
{
choice[ 0 ] = 8;
sum[ 0 ] = sum[ 1 ];
}
sum[ 1 ] = count_bit( ix, begin, end, 9 );
if ( sum[1] <= sum[0] )
choice[ 0 ] = 9;
break;
case 10:
sum[ 1 ] = count_bit( ix, begin, end, 11 );
if ( sum[1] <= sum[0] )
{
choice[ 0 ] = 11;
sum[ 0 ] = sum[ 1 ];
}
sum[ 1 ] = count_bit( ix, begin, end, 12 );
if ( sum[1] <= sum[0] )
choice[ 0 ] = 12;
break;
case 13:
sum[ 1 ] = count_bit( ix, begin, end, 15 );
if ( sum[1] <= sum[0] )
choice[ 0 ] = 15;
break;
}
}
else
{
/* try tables with linbits
* max>=15就需要从[15,31]号表范围内选了, [32, 33]是提供为count1使用的.
* 这时候就需要使用 linbits 机制了.
*
* 何谓linbits方法?
* ESCAPE = 量化后的值 - 15
* 可编码之最大值 = 15 + pow(2, linbits);
*/
max -= 15;
/* [15,31]号表又可分为[15, 23], [24, 31]两个部分
*
* 先从[15,23]号表中选出合适的table[index_1]
* 再从[24,31]号表中选出合适的table[index_2]
*
* 然后比较采用table[index_1]压缩ix[begin, end]还是
* 采用table[index_2]压缩ix[begin, end]能使用更少的位元数.
*/
for( i=15; i<24; i++ )
{
if( ht[i].linmax >= max )
{
choice[ 0 ] = i;
break;
}
}
for(i=24; i<32; i++)
{
if( ht[i].linmax >= max )
{
choice[ 1 ] = i;
break;
}
}
sum[0] = count_bit( ix, begin, end, choice[0] );
sum[1] = count_bit( ix, begin, end, choice[1] );
if ( sum[1] < sum[0] ) choice[0] = choice[1];
}
return choice[0];
}
其中
1.
sum[ 0 ] = count_bit( ix, begin, end, choice[0] );
这个函数是计算使用choice[0]这个表的时候, 压缩ix[begin,---end]所需要的位元数, 暂不考虑其实现
2
.huffmantable需要要规范中去查找到。
3.
/*
注意观察就知道了,哈哈!!!!
查看 标准<< 11172_3_ANNEXAB >> 之 Table 3-B.7. Huffman codes for Layer III
*table
static HUFFBITS t1HB[] = {1, 1, 1, 0};
{1, 001,01, 000}
*********************************************
*hlen
static unsigned char t1l[] = {1, 3, 2, 3};
*********************************************
Huffman code table 1
x y hlen hcod
0 0 1 1
0 1 3 001
1 0 2 01
1 1 3 000
*/
// -----------------------------------------------------------------------------------
#define NOREF -1
struct huffcodetab ht[HTN] =
{
/* xlen ylen linbits linmax *table *hlen */
// ------------ [0, 14]使用 ------------
{0, 0, 0, 0, NULL, NULL},
{2, 2, 0, 0, t1HB, t1l},
{3, 3, 0, 0, t2HB, t2l},
{3, 3, 0, 0, t3HB, t3l},
{0, 0, 0, 0, NULL, NULL},// Apparently not used
{4, 4, 0, 0, t5HB, t5l},
{4, 4, 0, 0, t6HB, t6l},
{6, 6, 0, 0, t7HB, t7l},
{6, 6, 0, 0, t8HB, t8l},
{6, 6, 0, 0, t9HB, t9l},
{8, 8, 0, 0, t10HB, t10l},
{8, 8, 0, 0, t11HB, t11l},
{8, 8, 0, 0, t12HB, t12l},
{16, 16, 0, 0, t13HB, t13l},
{0, 0, 0, 0, NULL, NULL},// Apparently not used
// ------------ [15, 31]使用 ------------
{16, 16, 0, 0, t15HB, t15l},
{16, 16, 1, 1, t16HB, t16l},
{16, 16, 2, 3, t16HB, t16l},
{16, 16, 3, 7, t16HB, t16l},
{16, 16, 4, 15, t16HB, t16l},
{16, 16, 6, 63, t16HB, t16l},
{16, 16, 8, 255, t16HB, t16l},
{16, 16, 10, 1023, t16HB, t16l},
{16, 16, 13, 8191, t16HB, t16l},
{16, 16, 4, 15, t24HB, t24l},
{16, 16, 5, 31, t24HB, t24l},
{16, 16, 6, 63, t24HB, t24l},
{16, 16, 7, 127, t24HB, t24l},
{16, 16, 8, 255, t24HB, t24l},
{16, 16, 9, 511, t24HB, t24l},
{16, 16, 11, 2047, t24HB, t24l},
{16, 16, 13, 8191, t24HB, t24l},
// ------------ [32, 33]count1使用 ------------
{1, 16, 0, 0, t32HB, t32l},
{1, 16, 0, 0, t33HB, t33l},
};
请注意查看shine的实现