这个是每一帧解码时候获得ancillary data长度的代码:
anc_len = (int)((double)samplesPerFrame /
s_freq[info.version][info.sampling_frequency] *
(double)bitrate[info.version][info.lay-1][info.bitrate_index] /
(double)bitsPerSlot);
if (info.padding)
anc_len++;
anc_len *= bitsPerSlot;
anc_len -= sstell(&bs)-gotBits+SYNC_WORD_LNGTH;
for (j=0; j<anc_len; j++)
get1bit(&bs);
这说明anc_len是在采样率,Bitrate确定之后,其初始长度是固定的,由main data里的slots数决定,然后再减去当前已经用掉的(读出的)bit stream的长度,由此得到实际的ancillary data长度,也就是最终得到的那个“anc_len”。
但我看了看在这段代码之前,读main data的处理过程,代码如下:
for (; nSlots > 0; nSlots--) /* read main data. */
hputbuf((unsigned int) getbits(&bs,8), 8);
而nSlots是由main_data_nSlots函数计算出来的,计算过程如下:
nSlots = (144 * bitrate[fr_ps.header->version][2][fr_ps.header->bitrate_index])
/ s_freq[fr_ps.header->version][fr_ps.header->sampling_frequency];
if ( fr_ps.header->version != MPEG_PHASE2_LSF ) {
if (fr_ps.stereo == 1) nSlots -= 17; else nSlots -=32;
}
else
{
nSlots = nSlots / 2;
if (fr_ps.stereo == 1) nSlots -= 9; else nSlots -=17;
}
if (fr_ps.header->padding) nSlots++;
nSlots -= 4;
if (fr_ps.header->error_protection) nSlots -= 2;
return(nSlots);
由上nSlots的计算过程可以看出,它貌似和anc_len初始值的计算过程是一样的。
这导致了一个什么问题呢????
我觉得在Read main data的时候,所有的nslots个main data都被读完了,很明显,再次之后,anc_len要计算的是剩下的没有被读的main data个数,但以上代码似乎很明显的反映出——main data都被读完了——那么anc_len怎么可能不为0啊???
照这么说anc_len应该就一直是0啊!!
那么ancillary data有不为0的时候吗??
你可以找几个MP3文件调试下,观察变量 anc_len 值得变化。
这个值基本上都是0、、、、、不过可能我找的MP3不多,但我调试了几个,发现每一帧这个anc_len的值都是0
而且代码貌似也指向anc_len总是0,所以我很怀疑。。。到底什么时候anc_len才不为0
@Writers: 从字面意思理解 ancillary data 是辅助数据的意思,也就是额外信息,所以可能为0。
@Launcher: 我是觉得辅助信息的长度anc_len压根就不可能算出不为0...既然都不可能出现不为0的情况,不知道为啥定义这个ancillary data,感觉反正它也没用。。
@Writers: 此部分数据是可能有的,比如一些描述信息之类的。因此这要视MP3文件中具体的数据来看。如果在解码中不去管这部分数据,那么遇到有这部分数据的MP3文件,程序就会出错。
ancillary data是为了扩展应用和算法使用的。
比如歌手,专辑,歌词等,但是没人这么用。曾经一个美国工作室用它做过什么
还有就是算法扩展。比如。有个一音频编解码标准叫mp3pro。
是fraunfor IIS开发的,就是mp3+sbr。sbr数据就是用ancillary data传输的