📄 mpadecl3.cpp
字号:
n1 = n2 = nsamp[igr][1]; /* total number bands */
if( side_info.gr[igr][1].block_type == 2 ) { /* long bands */
n1 = 0;
if( side_info.gr[igr][1].mixed_block_flag )
n1 = sfBandIndex[0][ncbl_mixed-1];
}
if( n1 > band_limit ) n1 = band_limit;
if( n2 > band_limit ) n2 = band_limit;
igr_prev = igr^1;
nsamp[igr][1] = hybrid(sample[1][igr], sample[1][igr_prev],
yout, side_info.gr[igr][1].block_type, n1, n2, nsamp[igr_prev][1], band_limit_nsb);
FreqInvert(yout, nsamp[igr][1]);
sbt_L3(yout, pcm, 0, vbuf, vb_ptr);
}
/*--------------------------------------------------------------------*/
void CMpaDecoderL3::Xform_dual(unsigned char *pcm, int igr)
{
int ch;
int igr_prev, n1, n2;
/*--- hybrid + sbt ---*/
igr_prev = igr^1;
for(ch=0;ch<nchan;ch++) {
n1 = n2 = nsamp[igr][ch]; /* total number bands */
if( side_info.gr[igr][ch].block_type == 2 ) { /* long bands */
n1 = 0;
if( side_info.gr[igr][ch].mixed_block_flag )
n1 = sfBandIndex[0][ncbl_mixed-1];
}
if( n1 > band_limit ) n1 = band_limit;
if( n2 > band_limit ) n2 = band_limit;
nsamp[igr][ch] = hybrid(sample[ch][igr], sample[ch][igr_prev],
yout, side_info.gr[igr][ch].block_type, n1, n2, nsamp[igr_prev][ch], band_limit_nsb);
FreqInvert(yout, nsamp[igr][ch]);
sbt_L3(yout, pcm, ch, vbuf, vb_ptr);
}
}
/*--------------------------------------------------------------------*/
void CMpaDecoderL3::Xform_dual_mono(unsigned char *pcm, int igr)
{
int igr_prev, n1, n2, n3;
/*--- hybrid + sbt ---*/
igr_prev = igr^1;
if( (side_info.gr[igr][0].block_type == side_info.gr[igr][1].block_type)
&& (side_info.gr[igr][0].mixed_block_flag == 0)
&& (side_info.gr[igr][1].mixed_block_flag == 0) )
{
n2 = nsamp[igr][0]; /* total number bands max of L R */
if( n2 < nsamp[igr][1] ) n2 = nsamp[igr][1];
if( n2 > band_limit ) n2 = band_limit;
n1 = n2; /* n1 = number long bands */
if( side_info.gr[igr][0].block_type == 2 ) n1 = 0;
sum_f_bands(sample[0][igr], sample[1][igr], n2);
n3 = nsamp[igr][0] = hybrid(sample[0][igr], sample[0][igr_prev],
yout, side_info.gr[igr][0].block_type, n1, n2, nsamp[igr_prev][0], band_limit_nsb);
}
else
{ /* transform and then sum (not tested - never happens in test)*/
/*-- left chan --*/
n1 = n2 = nsamp[igr][0]; /* total number bands */
if( side_info.gr[igr][0].block_type == 2 ) {
n1 = 0; /* long bands */
if( side_info.gr[igr][0].mixed_block_flag )
n1 = sfBandIndex[0][ncbl_mixed-1];
}
n3 = nsamp[igr][0] = hybrid(sample[0][igr], sample[0][igr_prev],
yout, side_info.gr[igr][0].block_type, n1, n2, nsamp[igr_prev][0], band_limit_nsb);
/*-- right chan --*/
n1 = n2 = nsamp[igr][1]; /* total number bands */
if( side_info.gr[igr][1].block_type == 2 ) {
n1 = 0; /* long bands */
if( side_info.gr[igr][1].mixed_block_flag )
n1 = sfBandIndex[0][ncbl_mixed-1];
}
nsamp[igr][1] = hybrid_sum(sample[1][igr], sample[0][igr],
yout, side_info.gr[igr][1].block_type, n1, n2);
if( n3 < nsamp[igr][1] ) n1 = nsamp[igr][1];
}
/*--------*/
FreqInvert(yout, n3);
sbt_L3(yout, pcm, 0, vbuf, vb_ptr);
}
/*------------------------------------------------------------------*/
/*==================================================================*/
/*====================concealment/reformatted frames================*/
/*==================================================================*/
#ifdef REFORMAT
// test routine - reformats frame
IN_OUT CMpaDecoderL3::audio_decode_reformat(unsigned char *bs,
unsigned char *bs_out)
{
if( h_id ) {
return L3reformat_MPEG1(bs, bs_out);
}
else {
return L3reformat_MPEG2(bs, bs_out);
}
}
//============================================================
// test routine - reformats frame
IN_OUT CMpaDecoderL3::L3reformat_MPEG1(unsigned char *bs,
unsigned char *bs_out)
{
int sync;
IN_OUT in_out;
int side_bytes;
int nbytes, nbytes_r;
//iframe++;
bitget_init(bs); /* initialize bit getter */
/* test sync */
in_out.in_bytes = 0; /* assume fail */
in_out.out_bytes = 0;
sync = bitget(&bitdat, 12);
if( sync != 0xFFF ) return in_out; /* sync fail */
/*-----------*/
/*-- unpack side info --*/
side_bytes = unpack_side_MPEG1();
if( framebytes <= 0 ) return in_out; // fail bad sr or br index
padframebytes = framebytes+pad;
in_out.in_bytes = padframebytes;
/*-- load main data and update buf pointer --*/
/*-------------------------------------------
if start point < 0, must just cycle decoder
if jumping into middle of stream,
---------------------------------------------*/
nbytes_r = reformat_side_bytes + reformat_bytes - side_info.main_data_begin;
if( nbytes_r > 0 ) {
memmove(bs_out, reformat_buf, nbytes_r);
in_out.out_bytes = nbytes_r;
}
buf_ptr0 = buf_ptr1 - side_info.main_data_begin; /* decode start point */
if( buf_ptr1 > BUF_TRIGGER ) { /* shift buffer */
memmove(buf, buf+buf_ptr0, side_info.main_data_begin);
buf_ptr0 = 0;
buf_ptr1 = side_info.main_data_begin;
}
nbytes = padframebytes - side_bytes - crcbytes;
memmove(buf+buf_ptr1, bs+side_bytes+crcbytes, nbytes);
buf_ptr1 += nbytes;
/*-----------------------*/
if( buf_ptr0 >= 0 ) {
reformat_side_bytes = side_bytes+crcbytes;
memmove(reformat_buf, bs, reformat_side_bytes);
reformat_buf[4+crcbytes] = 0; // set main data begin = 0
reformat_buf[4+crcbytes+1] &= 0x7F; // set main data begin = 0
reformat_bytes = buf_ptr1 - buf_ptr0;
if( reformat_bytes > 0 ) {
memmove(reformat_buf+reformat_side_bytes,
buf+buf_ptr0, reformat_bytes);
}
}
else {
reformat_side_bytes = 0;
reformat_bytes = 0;
}
return in_out;
}
/*=========================================================*/
// test routine - reformats frame
IN_OUT CMpaDecoderL3::L3reformat_MPEG2(unsigned char *bs,
unsigned char *bs_out)
{
int sync;
IN_OUT in_out;
int side_bytes;
int nbytes, nbytes_r;
//iframe++;
bitget_init(bs); /* initialize bit getter */
/* test sync */
in_out.in_bytes = 0; /* assume fail */
in_out.out_bytes = 0;
sync = bitget(&bitdat, 12);
//if( sync != 0xFFF ) return in_out; /* sync fail */
mpeg25_flag = 0;
if( sync != 0xFFF ) {
mpeg25_flag = 1; /* mpeg 2.5 sync */
if( sync != 0xFFE ) return in_out; /* sync fail */
}
/*-- unpack side info --*/
side_bytes = unpack_side_MPEG2(igr);
if( framebytes <= 0 ) return in_out; // fail bad sr or br index
padframebytes = framebytes+pad;
in_out.in_bytes = padframebytes;
nbytes_r = reformat_side_bytes + reformat_bytes - side_info.main_data_begin;
if( nbytes_r > 0 ) {
memmove(bs_out, reformat_buf, nbytes_r);
in_out.out_bytes = nbytes_r;
}
buf_ptr0 = buf_ptr1 - side_info.main_data_begin; /* decode start point */
if( buf_ptr1 > BUF_TRIGGER ) { /* shift buffer */
memmove(buf, buf+buf_ptr0, side_info.main_data_begin);
buf_ptr0 = 0;
buf_ptr1 = side_info.main_data_begin;
}
nbytes = padframebytes - side_bytes - crcbytes;
memmove(buf+buf_ptr1, bs+side_bytes+crcbytes, nbytes);
buf_ptr1 += nbytes;
/*-----------------------*/
if( buf_ptr0 >= 0 ) {
reformat_side_bytes = side_bytes+crcbytes;
memmove(reformat_buf, bs, reformat_side_bytes);
reformat_buf[4+crcbytes] = 0; // set main data begin = 0
reformat_bytes = buf_ptr1 - buf_ptr0;
if( reformat_bytes > 0 ) {
memmove(reformat_buf+reformat_side_bytes,
buf+buf_ptr0, reformat_bytes);
}
}
else {
reformat_side_bytes = 0;
reformat_bytes = 0;
}
//igr = igr^1; // must be done by decode_reformatted
return in_out;
}
#endif // REFORMAT
//=========================================================================
//=========================================================================
IN_OUT CMpaDecoderL3::audio_decode(unsigned char *bs, unsigned char *pcm, int size)
{
if (!size)
return audio_decode(bs, pcm);
// overloaded for reformatted frames. main_data_begin == 0
if( h_id ) {
return L3audio_decode_reformattedMPEG1(bs, pcm, size);
}
else {
return L3audio_decode_reformattedMPEG2(bs, pcm, size);
}
}
/*====================================================================*/
IN_OUT CMpaDecoderL3::L3audio_decode_reformattedMPEG1(unsigned char *bs,
unsigned char *pcm, int size)
{
int sync;
IN_OUT in_out;
int side_bytes;
// decode reformatted (self contained) frame
// fails if main_data_begin != 0
iframe++;
in_out.in_bytes = 0; // assume fail e.g. sync fail
in_out.out_bytes = 0;
if( size > 0 ) {
bitget_init(&bitdat, bs); /* initialize bit getter */
/* test sync */
sync = bitget(&bitdat, 12);
if( sync != 0xFFF ) return in_out; /* sync fail */
/*-----------*/
/*-- unpack side info --*/
side_bytes = unpack_side_MPEG1();
if( framebytes <= 0 ) return in_out; // fail bad sr or br index
if( side_info.main_data_begin ) return in_out; // fail if data not self contained
in_out.in_bytes = size;
in_out.out_bytes = outbytes;
main_pos_bit = (side_bytes+crcbytes) << 3; // set for unpack_main
unpack_main(bs, 0); // first granule
conceal_insert(0);
Xform(pcm, 0);
unpack_main(bs, 1); // second granule
conceal_insert(1);
Xform(pcm+half_outbytes, 1);
}
else { // size <= 0, missing frame
in_out.in_bytes = size;
in_out.out_bytes = outbytes;
conceal_fixup(0);
Xform(pcm, 0);
conceal_fixup(1);
Xform(pcm+half_outbytes, 1);
}
return in_out;
}
//=========================================================================
IN_OUT CMpaDecoderL3::L3audio_decode_reformattedMPEG2(unsigned char *bs,
unsigned char *pcm, int size)
{
int sync;
IN_OUT in_out;
int side_bytes;
// decode reformatted (self contained) frame
// fails if main_data_begin != 0
iframe++;
in_out.in_bytes = 0; /* assume fail */
in_out.out_bytes = 0;
if( size > 0 ) {
bitget_init(&bitdat, bs); /* initialize bit getter */
/* test sync */
sync = bitget(&bitdat, 12);
//if( sync != 0xFFF ) return in_out; /* sync fail */
mpeg25_flag = 0;
if( sync != 0xFFF ) {
mpeg25_flag = 1; /* mpeg 2.5 sync */
if( sync != 0xFFE ) return in_out; /* sync fail */
}
/*-- unpack side info --*/
side_bytes = unpack_side_MPEG2(igr);
if( framebytes <= 0 ) return in_out; // fail bad sr or br index
if( side_info.main_data_begin ) return in_out; // fail if data not self contained
in_out.in_bytes = size;
in_out.out_bytes = outbytes;
main_pos_bit = (side_bytes+crcbytes) << 3; // set for unpack_main
unpack_main(bs, igr);
conceal_insert(igr);
Xform(pcm, igr);
}
else { // size <= 0, missing frame
in_out.in_bytes = size;
in_out.out_bytes = outbytes;
conceal_fixup(igr);
Xform(pcm, igr);
}
igr = igr^1;
return in_out;
}
/*====================================================================*/
void CMpaDecoderL3::conceal_insert(int igr)
{
int ch, nlines, blockType, i;
if( conceal_flag ) {
for(ch=0;ch<nchan;ch++) {
#if defined (MP3_CONCEAL_LOSS)
conceal[ch]->insert(&sample[ch][igr][0].x,
side_info.gr[igr][ch].block_type, nsamp[igr][ch]);
nlines = conceal[ch]->retrieve(&sample[ch][igr][0].x, blockType);
#endif //MP3_CONCEAL_LOSS
side_info.gr[igr][ch].mixed_block_flag = 0;
side_info.gr[igr][ch].block_type = blockType;
side_info.gr[igr][ch].window_switching_flag = (blockType != 0) ? 1 : 0;
nsamp[igr][ch] = nlines;
for(i=nlines;i<576;i++) sample[ch][igr][i].x = 0.0f;
}
}
}
/*====================================================================*/
void CMpaDecoderL3::conceal_fixup(int igr)
{
int ch, nlines, blockType, i;
if( conceal_flag ) {
for(ch=0;ch<nchan;ch++) {
#if defined (MP3_CONCEAL_LOSS)
conceal[ch]->insert();
nlines = conceal[ch]->retrieve(&sample[ch][igr][0].x, blockType);
#endif //MP3_CONCEAL_LOSS
side_info.gr[igr][ch].mixed_block_flag = 0;
side_info.gr[igr][ch].block_type = blockType;
side_info.gr[igr][ch].window_switching_flag = (blockType != 0) ? 1 : 0;
nsamp[igr][ch] = nlines;
for(i=nlines;i<576;i++) sample[ch][igr][i].x = 0.0f;
}
}
else { // mute
for(ch=0;ch<nchan;ch++) {
side_info.gr[igr][ch].mixed_block_flag = 0;
side_info.gr[igr][ch].block_type = 0;
side_info.gr[igr][ch].window_switching_flag = 0;
for(i=0;i<576;i++) sample[ch][igr][i].x = 0.0f;
}
}
}
/*====================================================================*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -