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/ )