⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 loop.c

📁 MPEG 2的音频编码软件。喜欢多媒体的开发人员可以看看。
💻 C
📖 第 1 页 / 共 5 页
字号:
    {
	/*
	  Since no bands have been over-amplified, we can set scalefac_compress
	  and slen[] for the formatter
	*/
	static int log2tab[] = { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4 };

	unsigned slen1, slen2, slen3, slen4;

        cod_info->sfb_partition_table = &nr_of_sfb_block[table_number][row_in_table][0];
	for ( partition = 0; partition < 4; partition++ )
	    cod_info->slen[partition] = log2tab[max_sfac[partition]];

	/* set scalefac_compress */
	slen1 = cod_info->slen[ 0 ];
	slen2 = cod_info->slen[ 1 ];
	slen3 = cod_info->slen[ 2 ];
	slen4 = cod_info->slen[ 3 ];

	switch ( table_number )
	{
	  case 0:
	    cod_info->scalefac_compress = (((slen1 * 5) + slen2) << 4)
		+ (slen3 << 2)
		+ slen4;
	    break;

	  case 1:
	    cod_info->scalefac_compress = 400
		+ (((slen1 * 5) + slen2) << 2)
		+ slen3;
	    break;

	  case 2:
	    cod_info->scalefac_compress = 500 + (slen1 * 3) + slen2;
	    break;

	  default:
	    fprintf( stderr, "intensity stereo not implemented yet\n" );
	    exit( EXIT_FAILURE );
	    break;
	}
    }
#ifdef DEBUG
    if ( over ) 
        printf( "---WARNING !! Amplification of some bands over limits\n" );
#endif
    return over;
}


/*************************************************************************/
/*            calc_noise                                                 */
/*************************************************************************/

/*   Function: Calculate the distortion introduced by the quantization   */
/*   in each scale factor band.                                          */

void calc_noise( double xr[576], int ix[576], gr_info *cod_info,
	    double xfsf[4][CBLIMIT] )
{
    int start, end, sfb, l, i;
    double sum,step,bw;

    D192_3 *xr_s;
    I192_3 *ix_s;

    xr_s = (D192_3 *) xr;
    ix_s = (I192_3 *) ix;

    step = pow( 2.0, (cod_info->quantizerStepSize) * 0.25 );
    for ( sfb = 0; sfb < cod_info->sfb_lmax; sfb++ )
    {
        start = scalefac_band_long[ sfb ];
        end   = scalefac_band_long[ sfb+1 ];
	bw = end - start;

        for ( sum = 0.0, l = start; l < end; l++ )
        {
            double temp;
            temp = fabs( xr[l] ) - pow( (double) ix[l], 4.0 / 3.0 ) * step;
            sum += temp * temp; 
        }
        xfsf[0][sfb] = sum / bw;
    }

    for ( i = 0; i < 3; i++ )
    {
        step = pow( 2.0, (cod_info->quantizerStepSize) * 0.25 ); /* subblock_gain ? */
        for ( sfb = cod_info->sfb_smax; sfb < 12; sfb++ )
        {
            start = scalefac_band_short[ sfb ];
            end   = scalefac_band_short[ sfb+1 ];
	    bw = end - start;
            
            for ( sum = 0.0, l = start; l < end; l++ )
            {
                double temp;
                temp = fabs( (*xr_s)[l][i] ) - pow( (double) (*ix_s)[l][i], 4.0 / 3.0 ) * step;
                sum += temp * temp;
            }       
            xfsf[i+1][sfb] = sum / bw;
        }
    }
}




/*************************************************************************/
/*            calc_xmin                                                  */
/*************************************************************************/

/*
  Calculate the allowed distortion for each scalefactor band,
  as determined by the psychoacoustic model.
  xmin(sb) = ratio(sb) * en(sb) / bw(sb)
*/

void calc_xmin( double xr[2][2][576], III_psy_ratio *ratio,
	   gr_info *cod_info, III_psy_xmin *l3_xmin,
	   int gr, int ch )
{
    int start, end, sfb, l, b;
    double en, bw;

    D192_3 *xr_s;

    xr_s = (D192_3 *) xr[gr][ch] ;

    for ( sfb = cod_info->sfb_smax; sfb < SFB_SMAX - 1; sfb++ )
    {
        start = scalefac_band_short[ sfb ];
        end   = scalefac_band_short[ sfb + 1 ];
	bw = end - start;
        for ( b = 0; b < 3; b++ )
        {
            for ( en = 0.0, l = start; l < end; l++ )
                en += (*xr_s)[l][b] * (*xr_s)[l][b];
            l3_xmin->s[gr][ch][sfb][b] = ratio->s[gr][ch][sfb][b] * en / bw;
        }
    }

    for ( sfb = 0; sfb < cod_info->sfb_lmax; sfb++ )
    {
        start = scalefac_band_long[ sfb ];
        end   = scalefac_band_long[ sfb+1 ];
	bw = end - start;

        for ( en = 0.0, l = start; l < end; l++ )
            en += xr[gr][ch][l] * xr[gr][ch][l];
        l3_xmin->l[gr][ch][sfb] = ratio->l[gr][ch][sfb] * en / bw;
    }
}



/*************************************************************************/
/*            loop_break                                                 */
/*************************************************************************/

/*  Function: Returns zero if there is a scalefac which has not been
    amplified. Otherwise it returns one. 
*/

int loop_break( III_scalefac_t *scalefac, gr_info *cod_info,
	    int gr, int ch )
{
    int i, sfb, temp = 1;

    for ( sfb = 0; sfb < cod_info->sfb_lmax; sfb++ )
        if ( scalefac->l[gr][ch][sfb] == 0 )
            temp = 0;

    for ( sfb = cod_info->sfb_smax; sfb < 12; sfb++ )
        for ( i = 0; i < 3; i++ )
            if ( scalefac->s[gr][ch][sfb][i] == 0 )
                temp = 0;
#ifdef DEBUG
    if ( temp != 0 )
        printf( "---WARNING !! All scalefactor bands amplified\n" );
#endif
    return temp;
}



/*************************************************************************/
/*            preemphasis                                                */
/*************************************************************************/

/*
  See ISO 11172-3  section  C.1.5.4.3.4
*/

void preemphasis( double xr[576], double xfsf[4][CBLIMIT],
	     III_psy_xmin  *l3_xmin,
	     int gr, int ch, III_side_info_t *l3_side )
{
    int i, sfb, start, end, scfsi_band, over;
    double ifqstep;
    gr_info *cod_info = &l3_side->gr[gr].ch[ch].tt;

    if ( gr == 1 )
    {
	/*
	  If the second granule is being coded and scfsi is active in
	  at least one scfsi_band, the preemphasis in the second granule
	  is set equal to the setting in the first granule
	*/
	for ( scfsi_band = 0; scfsi_band < 4; scfsi_band++ )
	    if ( l3_side->scfsi[ch][scfsi_band] )
	    {
		cod_info->preflag = l3_side->gr[0].ch[ch].tt.preflag;
		return;
	    }
	
    }

    /*
      Preemphasis is switched on if in all the upper four scalefactor
      bands the actual distortion exceeds the threshold after the
      first call of the inner loop
    */
    if ( cod_info->block_type != 2 && cod_info->preflag == 0 )
    {	
	over = 0;
	for ( sfb = 17; sfb < 21; sfb++ )
	    if ( xfsf[0][sfb] > l3_xmin->l[gr][ch][sfb] )
		over++;

	if (over == 4 )
	{
	    cod_info->preflag = 1;
	    ifqstep = ( cod_info->scalefac_scale == 0 ) ? sqrt(2.)
		: pow( 2.0, (0.5 * (1.0 + (double) cod_info->scalefac_scale)) );

	    for ( sfb = 0; sfb < cod_info->sfb_lmax; sfb++ )
	    {
		l3_xmin->l[gr][ch][sfb] *= pow( ifqstep, 2.0 * (double) pretab[sfb] );
		start = scalefac_band_long[ sfb ];
		end   = scalefac_band_long[ sfb+1 ];
		for( i = start; i < end; i++ )
		    xr[i] *= pow( ifqstep, (double) pretab[sfb] );
	    }
	}
    }
}


/*************************************************************************/
/*            amp_scalefac_bands                                         */
/*************************************************************************/

/* 
  Amplify the scalefactor bands that violate the masking threshold.
  See ISO 11172-3 Section C.1.5.4.3.5
*/

int amp_scalefac_bands( double xr[576], double xfsf[4][CBLIMIT],
		    III_psy_xmin *l3_xmin, III_side_info_t *l3_side,
		    III_scalefac_t *scalefac,
		    int gr, int ch, int iteration )
{
    int start, end, l, sfb, i, scfsi_band, over = 0;
    double ifqstep, ifqstep2;
    D192_3 *xr_s;
    gr_info *cod_info, *gr0;
    int copySF, preventSF;
    cod_info = &l3_side->gr[gr].ch[ch].tt;
    gr0      = &l3_side->gr[0].ch[ch].tt;

    xr_s = (D192_3 *) xr;
    copySF = 0;
    preventSF = 0;

    if ( cod_info->scalefac_scale == 0 )
	ifqstep = sqrt( 2.0 );
    else
	ifqstep = pow( 2.0, 0.5 * (1.0 + (double) cod_info->scalefac_scale) );

    if ( gr == 1 )
    {
	/*
	  If the second granule is being coded and scfsi is active in at
	  least one scfsi_band...
	*/
	for ( scfsi_band = 0; scfsi_band < 4; scfsi_band++ )
	    if ( l3_side->scfsi[ch][scfsi_band] )
	    {
		/*
		  a) ifqstep has to be set similar to the
		   first granule...
		*/
		if ( gr0->scalefac_scale == 0 )
		    ifqstep = sqrt( 2.0 );
		else
		    ifqstep = pow( 2.0, 0.5 * (1.0 + (double) gr0->scalefac_scale) );

		if ( iteration == 1 )
		{
		    /*
		      b) If it is the first iteration, the scalefactors
		      of scalefactor bands in which scfsi is enabled
		      must be taken from the first granule
		    */  
		    copySF = 1;
		}
		else
		{
		    /*
		      c) If it is not the first iteration, the amplification
		      must be prevented for scalefactor bands in which
		      scfsi is enabled
		    */
		    preventSF = 1;
		}
		break;
	    }
	
    }

    ifqstep2 = ifqstep * ifqstep;
    scfsi_band = 0;
    
    for ( sfb = 0; sfb < cod_info->sfb_lmax; sfb++ )
    {
	if ( copySF || preventSF )
	{
	    if ( sfb == scfsi_band_long[scfsi_band + 1] )
		scfsi_band += 1;
	    if ( l3_side->scfsi[ch][scfsi_band] )
	    {
		if ( copySF )
		    scalefac->l[gr][ch][sfb] = scalefac->l[0][ch][sfb];
		continue;
	    }
	}	    
	if ( xfsf[0][sfb] > l3_xmin->l[gr][ch][sfb] )
	{
	    over++;
	    l3_xmin->l[gr][ch][sfb] *= ifqstep2;
	    scalefac->l[gr][ch][sfb]++;
	    start = scalefac_band_long[sfb];
	    end   = scalefac_band_long[sfb+1];
	    for ( l = start; l < end; l++ )
		xr[l] *= ifqstep;
	}
    }

    /*
      Note that scfsi is not enabled for frames containing
      short blocks
    */
    for ( i = 0; i < 3; i++ )
        for ( sfb = cod_info->sfb_smax; sfb < 12; sfb++ )
            if ( xfsf[i+1][sfb] > l3_xmin->s[gr][ch][sfb][i] )
            {
                over++;
                l3_xmin->s[gr][ch][sfb][i] *= ifqstep2;
                scalefac->s[gr][ch][sfb][i]++;
#ifdef DEBUGSC
                printf( "cod_info->scalefac[%d][%d] = %d (amp_scale)\n",
                        i,sfb,scalefac->s[gr][ch][sfb][i] );
#endif
                start = scalefac_band_short[sfb];
                end   = scalefac_band_short[sfb+1];
                for ( l = start; l < end; l++ )
                    (*xr_s)[l][i] *= ifqstep;
            }
    return over;
}




/*************************************************************************/
/*            quantize                                                   */
/*************************************************************************/

/*
  Function: Quantization of the vector xr ( -> ix)
*/

void quantize( double xr[576], int ix[576], gr_info *cod_info )
{
    int i, b, l_end, s_start;
    double step, quantizerStepSize;

    D192_3 *xr_s;
    I192_3 *ix_s;

    xr_s = (D192_3 *) xr;
    ix_s = (I192_3 *) ix;

    quantizerStepSize = (double) cod_info->quantizerStepSize;

    for ( i = 0; i < 576; i++ )
	ix[i] = 0;

    if ( cod_info->quantizerStepSize == 0.0 )
	step = 1.0;
    else
	step = pow ( 2.0, quantizerStepSize * 0.25 );

    if ( cod_info->window_switching_flag != 0 && cod_info->block_type == 2 )
	if ( cod_info->mixed_block_flag == 0 )
	{
	    l_end = 0;
	    s_start = 0;
	}
	else
	{
	    l_end = 18 * 2;
	    s_start = 6 * 2;
	}
    else
    {
	l_end = 576;
	s_start = 192;
    }

    for ( i = 0; i < l_end; i++ )
	ix[i] = nint( pow(fabs(xr[i]) / step, 0.75) - 0.0946 );
    
    if ( s_start < 192 )
	for ( b = 0; b < 3; b++ )
	{
	    step = pow( 2.0, (quantizerStepSize + 8.0 * (double) cod_info->subblock_gain[b]) * 0.25 );
	    for ( i = s_start; i < 192; i++ )
		(*ix_s)[i][b] = nint( pow(fabs((*xr_s)[i][b]) / step, 0.75) - 0.0946 );
	}
}




/*************************************************************************/
/*            ix_max                                                     */
/*************************************************************************/

/*
  Function: Calculate the maximum of ix from 0 to 575
*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -