Hi all,
        played a bit with calcnoise2.  Just tweaked the inner most loops
to check first whether ix[]=0 (which is pretty common).  This then skips the
pow43 table look up and calculation.
        This gives about a 25-30% speedup for this routine.

        one note about this routine, is that the diff[] values can sometimes be
negative. In calc_noise1 this really didn't matter as we were squaring the
difference. in calcnoise2 however, we're doing a combination of the two
differences in a mid/side fashion. bug or feature?

later
mike
-----------------------------

/*************************************************************************/
/*            calc_noise2                                                */
/*************************************************************************/
/*   Improved version of calc_noise for dual channel.  This routine is */
/*   used when you are quantizaing mid and side channels using masking */
/*   thresholds from L and R channels.  mt 5/99 */

void calc_noise2( double xr[2][576], int ix[2][576], gr_info *cod_info[2],
            double xfsf[2][4][CBLIMIT], double distort[2][4][CBLIMIT],
            III_psy_xmin *l3_xmin,int gr,int stereo, int over[2], 
            double over_noise[2], double tot_noise[2], double max_noise[2])
{
    int start, end, sfb, l, i;
    double sum[2],step_s[3][2],step[2],bw;

    D192_3 *xr_s[2];
    I192_3 *ix_s[2];

    static double pow43[PRECALC_SIZE];
    int ch;
    static int init=0;
    double diff[2], qcoeff;
    double noise;
    int index;
    
    if (init==0) {
      init++;
      for(i=0;i<PRECALC_SIZE;i++)
        pow43[i] = pow((double)i, 4.0/3.0);
    }
    
    

    /* calc_noise2: we can assume block types of both channels must be the same
*/
    if (cod_info[0]->block_type != 2) {
    for (ch=0 ; ch < stereo ; ch ++ ) {
      over[ch]=0;
      over_noise[ch]=0;
      tot_noise[ch]=0;
      max_noise[ch]=-999;
      step[ch] = pow( 2.0, (cod_info[ch]->quantizerStepSize) * 0.25 );
    }
    for ( sfb = 0; sfb < SFB_LMAX-1; sfb++ ) {
      start = scalefac_band_long[ sfb ];
      end   = scalefac_band_long[ sfb+1 ];
      bw = end - start;

      //      for (ch=0 ; ch < stereo ; ch ++ ) sum[ch]=0;
      for ( sum[0]=0, sum[1]=0, l = start; l < end; l++ ) {
          index=ix[0][l];
          if (index==0) {
            diff[0]=xr[0][l];
          } else {
            if (xr[0][l]<0) {
              diff[0]=xr[0][l] + pow43[index] * step[0];
            } else
              diff[0]=xr[0][l] - pow43[index] * step[0];
          }
          index=ix[1][l];
          if (index==0) {
            diff[1]=xr[1][l];
          } else {
            if (xr[1][l]<0) {
              diff[1]=xr[1][l] + pow43[index] * step[1];
            } else
              diff[1]=xr[1][l] - pow43[index] * step[1];
          }
        sum[0] += (diff[0]+diff[1])*(diff[0]+diff[1]);
        sum[1] += (diff[0]-diff[1])*(diff[0]-diff[1]);
      }      
      sum[0] *= 0.5;
      sum[1] *= 0.5;

      for (ch=0 ; ch < stereo ; ch ++ ) {
        xfsf[ch][0][sfb] = sum[ch] / bw;
        noise = 10*log10(Max(.001,xfsf[ch][0][sfb]/l3_xmin->l[gr][ch][sfb]));
        distort[ch][0][sfb] =  noise;
        if (noise>0) {
          over[ch]++;
          //over_noise[ch] += xfsf[ch][0][sfb] - l3_xmin->l[gr][ch][sfb];
          over_noise[ch] += noise;
        }
        tot_noise[ch] += noise;
        max_noise[ch] = Max(max_noise[ch],noise);
      }

      /* if there is audible distortion in left or right channel, set flags
       * to denote distortion in both mid and side channels */
      for (ch=0 ; ch < stereo ; ch ++ ) {
        distort[ch][0][sfb] = Max(distort[0][0][sfb],distort[1][0][sfb]);
      }
    }
    }

    /* calc_noise2: we can assume block types of both channels must be the same
*/
    if (cod_info[0]->block_type == 2) {
    for (ch=0 ; ch < stereo ; ch ++ ) {

      for (i=0;i<3;i++){
        step_s[i][ch] = pow( 2.0, (cod_info[ch]->quantizerStepSize) * 0.25 );
/* subblock_gain ? */
        if (cod_info[ch]->subblock_gain[i] )
          step_s[i][ch] *= pow(2.0,-2.0*cod_info[ch]->subblock_gain[i]);
      }

      over[ch] = 0;
      xr_s[ch] = (D192_3 *) xr[ch];
      ix_s[ch] = (I192_3 *) ix[ch];
    }

    for ( sfb = 0 ; sfb < SFB_SMAX-1; sfb++ ) {
      start = scalefac_band_short[ sfb ];
      end   = scalefac_band_short[ sfb+1 ];
      bw = end - start;
      for ( i = 0; i < 3; i++ ) {           
        for (ch=0 ; ch < stereo ; ch ++ ) sum[ch] = 0.0;
        for ( l = start; l < end; l++ )           {
            index=(*ix_s[0])[l][i];
            if (index==0)
              diff[0] = (*xr_s[0])[l][i];
            else {
              if ((*xr_s[0])[l][i] < 0) {
                diff[0] = (*xr_s[0])[l][i] + pow43[index] * step_s[i][0]; 
              } else {
                diff[0] = (*xr_s[0])[l][i] - pow43[index] * step_s[i][0]; 
              }
            }
            index=(*ix_s[1])[l][i];
            if (index==0)
              diff[1] = (*xr_s[1])[l][i];
            else {
              if ((*xr_s[1])[l][i] < 0) {
                diff[1] = (*xr_s[1])[l][i] + pow43[index] * step_s[i][1]; 
              } else {
                diff[1] = (*xr_s[1])[l][i] - pow43[index] * step_s[i][1]; 
              }
            }     
          sum[0] += (diff[0]+diff[1])*(diff[0]+diff[1])/(2.0);
          sum[1] += (diff[0]-diff[1])*(diff[0]-diff[1])/(2.0);
        }

        for (ch=0 ; ch < stereo ; ch ++ ) {
          xfsf[ch][i+1][sfb] = sum[ch] / bw;
          noise =
10*log10(Max(.001,xfsf[ch][i+1][sfb]/l3_xmin->s[gr][ch][sfb][i]));
          distort[ch][i+1][sfb] = noise>0;
          if (noise>0) {
            over[ch]++;
            //over_noise[ch] += xfsf[ch][i+1][sfb]-l3_xmin->s[gr][ch][sfb][i];
            over_noise[ch] += noise;
          }
          tot_noise[ch] += noise;
          max_noise[ch]=Max(max_noise[ch],noise);
        }
        /* if there is audible distortion in left or right channel, set flags
         * to denote distortion in both mid and side channels */
        for (ch=0 ; ch < stereo ; ch ++ ) 
          distort[ch][i+1][sfb] = Max
            (distort[0][i+1][sfb],distort[1][i+1][sfb]  );
      }
    }
    }
}
    
--
MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )

Reply via email to