www.pudn.com > MPEG_crack.rar > fastimdct.c, change:1999-03-22,size:8953b


#include "mp3dec.h" 
 
/* An Inverse Modified Discrete Cosinus Transform is applied to 18 values 
   at a time. The 18 frequency values generate 36 time domain values,  
   where half of these are overlapped with half of the previously generated 
   values to produce 18 output values. These can later be fed into the 
   subband synthesis. 
 
   The multiply-add loop here is very time critical. It uses a total of 
   684*32=21888 MAC operations per imdct, 4 times per frame. With 38 
   frames per second, thats 3.33 million MAC's. 
 
   Using some small trigonometric tricks, we can do this in 360*32*4*38= 
   1.75 million MAC's per second instead. 
 
*/ 
 
extern mpfloat Granule_imdct_previous[2][576];  /* used for overlapping */ 
extern mpfloat Granule_9x9_idct[72]; 
extern mpfloat Granule_imdct_win[4][36]; 
 
mpfloat Granule_twiddles_short[23] = { 
    0.866025403f, 0.5f, 
    1.931851653f, 0.707106781f, 0.517638090f, 
 
    0.504314480f, 0.541196100f, 0.630236207f, 
    0.821339815f, 1.306562965f, 3.830648788f, 
    0.793353340f, 0.608761429f, 0.923879532f, 
    0.382683432f, 0.991444861f, 0.130526192f,  
    0.382683432f, 0.608761429f, 0.793353340f, 
    0.923879532f, 0.991444861f, 0.130526192f 
}; 
 
mpfloat Granule_twiddles_normal[] = { 
    5.736856623f, 1.931851653f, 1.183100792f, 
    0.871723397f, 0.707106781f, 0.610387294f,  
    0.551688959f, 0.517638090f, 0.501909918f, 
 
    -0.500476342f, -0.504314480f, -0.512139757f, 
    -0.524264562f, -0.541196100f, -0.563690973f,  
    -0.592844523f, -0.630236207f, -0.678170852f,  
    -0.740093616f, -0.821339815f, -0.930579498f, 
    -1.082840285f, -1.306562965f, -1.662754762f,  
    -2.310113158f, -3.830648788f, -11.46279281f 
}; 
 
void 
Granule_imdct(Granule *gr, int ch, Granule_floatfreqs X) 
{ 
    int sb, i, j, k, l, window; 
    mpfloat save, sum, sum2, pp1; 
    mpfloat s; 
    mpfloat x[36], t[18]; 
    mpfloat *v, *prev, *z, *twid; 
 
    prev = Granule_imdct_previous[ch]; 
 
    /* process each subband */ 
 
    for(sb = 0; sb < NUM_SUBBANDS; sb++) { 
 
	for(i = 0; i < 36; i++) 
	    x[i] = (mpfloat)0.0f; 
	 
	/* decode the block_type - it's in block_type, but we have to think 
	   about the mixed blocks lower 2 subbands */ 
	 
	if(gr->block_type == BLOCKTYPE_3WIN && 
	   !(gr->window_switching_flag &&  
	     gr->mixed_block_flag && sb < 2)) { 
 
	    /* process the 3 windows separately, each window has 12 values */ 
 
	    for(window = 0; window < 3; window++) { 
 
#ifdef LEE_IMDCT 
		/* 30*3=90 adds, 25*3=75 muls */ 
 
		X[15+window] += X[12+window]; 
		X[12+window] += X[9+window]; 
		X[9+window] += X[6+window]; 
		X[6+window] += X[3+window]; 
		X[3+window] += X[window]; 
 
		X[15+window] += X[9+window]; 
		X[9+window] += X[3+window]; 
 
		twid = Granule_twiddles_short; 
 
		/* do a 3x3 IDCT on the even part */ 
 
		pp1 = X[6+window] * twid[0]; 
		sum = X[window] + X[12+window] * twid[1]; 
		t[1] = X[window] - X[12+window]; 
		t[0] = sum + pp1; 
		t[2] = sum - pp1; 
 
		/* 3x3 IDCT for odd part */ 
 
		pp1 = X[9+window] * twid[0]; 
		sum = X[3+window] + X[15+window] * twid[1]; 
		t[4] = X[3+window] - X[15+window]; 
		t[5] = sum + pp1; 
		t[3] = sum - pp1; 
 
		/* scale the odd part */ 
 
		t[3] *= twid[2]; 
		t[4] *= twid[3]; 
		t[5] *= twid[4]; 
 
		save = t[0]; 
		t[0] += t[5]; 
		t[5] = save - t[5]; 
 
		save = t[1]; 
		t[1] += t[4]; 
		t[4] = save - t[4]; 
 
		save = t[2]; 
		t[2] += t[3]; 
		t[3] = save - t[3]; 
 
		t[0]  *= twid[5]; 
		t[1]  *= twid[6]; 
		t[2]  *= twid[7]; 
		t[3]  *= twid[8]; 
		t[4]  *= twid[9]; 
		t[5]  *= twid[10]; 
 
		t[6]  = -t[2] * twid[15]; 
		t[7]  = -t[1] * twid[13]; 
		t[8]  = -t[0] * twid[11]; 
		t[9]  = -t[0] * twid[12]; 
		t[10] = -t[1] * twid[14]; 
		t[11] = -t[2] * twid[16]; 
		 
		t[0]  =  t[3]; 
		t[1]  =  t[4] * twid[17]; 
		t[2]  =  t[5] * twid[18]; 
		 
		t[3]  = -t[5] * twid[19]; 
		t[4]  = -t[4] * twid[20]; 
		t[5]  = -t[0] * twid[21]; 
		 
		t[0] *= twid[22]; 
 
		z = &x[window * 6 + 6]; 
		z[0]  += t[0]; 
		z[1]  += t[1]; 
		z[2]  += t[2]; 
		z[3]  += t[3]; 
		z[4]  += t[4]; 
		z[5]  += t[5]; 
		z[6]  += t[6]; 
		z[7]  += t[7]; 
		z[8]  += t[8]; 
		z[9]  += t[9]; 
		z[10]  += t[10]; 
		z[11]  += t[11]; 
 
#else 
		/* uses 3*6*6+3*12=144 MAC's */ 
		v = Granule_imdct_bigCOS2; 
		for(i = 0; i < 6; i++) { 
		    s = X[window] * *(v++);  
		    s += X[window + 3] * *(v++); 
		    s += X[window + 6] * *(v++); 
		    s += X[window + 9] * *(v++); 
		    s += X[window + 12] * *(v++); 
		    s += X[window + 15] * *(v++); 
		    ISCALE(s); 
		    t[i] = s; 
		} 
 
		/* periodic expansion */ 
		z = &x[window * 6 + 6]; 
		z[0] -= t[3] * Granule_imdct_win[2][0]; 
		z[1] -= t[4] * Granule_imdct_win[2][1]; 
		z[2] -= t[5] * Granule_imdct_win[2][2]; 
		z[3] += t[5] * Granule_imdct_win[2][3]; 
		z[4] += t[4] * Granule_imdct_win[2][4]; 
		z[5] += t[3] * Granule_imdct_win[2][5]; 
		z[6] += t[2] * Granule_imdct_win[2][6]; 
		z[7] += t[1] * Granule_imdct_win[2][7]; 
		z[8] += t[0] * Granule_imdct_win[2][8]; 
		z[9] += t[0] * Granule_imdct_win[2][9]; 
		z[10] += t[1] * Granule_imdct_win[2][10]; 
		z[11] += t[2] * Granule_imdct_win[2][11]; 
#endif 
	    } 
 
#ifdef INT_MATH 
	    for(i = 0; i < 36; i++) 
		ISCALE(x[i]); 
#endif 
 
	} else { 
 
#ifdef LEE_IMDCT 
	     
	    /* uses 207 muls, 189 adds */ 
		  
	    X[17] += X[16]; 
	    X[16] += X[15]; 
	    X[15] += X[14]; 
	    X[14] += X[13]; 
	    X[13] += X[12]; 
	    X[12] += X[11]; 
	    X[11] += X[10]; 
	    X[10] += X[9]; 
	    X[9] += X[8]; 
	    X[8] += X[7]; 
	    X[7] += X[6]; 
	    X[6] += X[5]; 
	    X[5] += X[4]; 
	    X[4] += X[3]; 
	    X[3] += X[2]; 
	    X[2] += X[1]; 
	    X[1] += X[0]; 
 
	    X[17] += X[15]; 
	    X[15] += X[13]; 
	    X[13] += X[11]; 
	    X[11] += X[9]; 
	    X[9] += X[7]; 
	    X[7] += X[5]; 
	    X[5] += X[3]; 
	    X[3] += X[1]; 
 
	    for(i = 0, j = 0; i < 9; i++, j += 8) { 
#ifdef USE_INLINE_ASM 
__asm { 
	mov eax, X 
	mov ecx, j 
	lea ebx, [Granule_9x9_idct + ecx*4] 
	fld dword ptr [eax] 
	fld dword ptr [eax + 4] 
 
	fld dword ptr [ebx] 
	fld st(0) 
	fmul dword ptr [eax + 8] 
	faddp st(3), st 
	fmul dword ptr [eax + 12] 
	faddp st(1), st 
 
	fld dword ptr [ebx + 4] 
	fld st(0) 
	fmul dword ptr [eax + 16] 
	faddp st(3), st 
	fmul dword ptr [eax + 20] 
	faddp st(1), st 
 
	fld dword ptr [ebx + 8] 
	fld st(0) 
	fmul dword ptr [eax + 24] 
	faddp st(3), st 
	fmul dword ptr [eax + 28] 
	faddp st(1), st 
 
	fld dword ptr [ebx + 12] 
	fld st(0) 
	fmul dword ptr [eax + 32] 
	faddp st(3), st 
	fmul dword ptr [eax + 36] 
	faddp st(1), st 
 
	fld dword ptr [ebx + 16] 
	fld st(0) 
	fmul dword ptr [eax + 40] 
	faddp st(3), st 
	fmul dword ptr [eax + 44] 
	faddp st(1), st 
 
	fld dword ptr [ebx + 20] 
	fld st(0) 
	fmul dword ptr [eax + 48] 
	faddp st(3), st 
	fmul dword ptr [eax + 52] 
	faddp st(1), st 
 
	fld dword ptr [ebx + 24] 
	fld st(0) 
	fmul dword ptr [eax + 56] 
	faddp st(3), st 
	fmul dword ptr [eax + 60] 
	faddp st(1), st 
 
	fld dword ptr [ebx + 28] 
	fld st(0) 
	fmul dword ptr [eax + 64] 
	faddp st(3), st 
	fmul dword ptr [eax + 68] 
	faddp st(1), st 
 
	fstp dword ptr [sum2] 
	fstp dword ptr [sum] 
} 
#else 
                        sum = X[0]; 
			sum2 = X[1]; 
			for(l = 0, k = 0; l < 16; l += 2, k++) { 
			    s = Granule_9x9_idct[j+k]; 
			    sum += X[2+l] * s; 
			    sum2 += X[3+l] * s; 
			} 
#endif 
			t[i] = sum; 
			t[17-i] = sum2; 
	    } 
 
	    twid = Granule_twiddles_normal; 
	     
	    for(i = 0; i < 9; i++) 
		t[9+i] *= twid[i]; 
 
	    for(i = 0; i < 9; i++) { 
		save = t[i]; 
		t[i] += t[17-i]; 
		t[17-i] = save - t[17-i]; 
	    } 
 
	    for(i = 0; i < 18; i++) 
		t[i] *= twid[9+i]; 
 
#else 
	    /* this loop uses 19*36=684 MAC operations */ 
 
	    /* do a 18x18 IMDCT */ 
	    /* 324 muls and 324 adds */ 
 
	    v = Granule_imdct_bigCOS; 
	    for(i = 0; i < 18; i++) { 
		s = (mpfloat)0.0f; 
		k = 0; 
		do { 
		    s += X[k] * v[k]; 
		    s += X[k+1] * v[k+1]; 
		    s += X[k+2] * v[k+2]; 
		    s += X[k+3] * v[k+3]; 
		    s += X[k+4] * v[k+4]; 
		    s += X[k+5] * v[k+5]; 
		    k += 6; 
		} while(k < 18); 
		v += 18; 
		ISCALE(s); 
		t[i] = s; 
	    } 
#endif 
	    /* correct the transform into the 18x36 IMDCT we need */ 
	    /* 36 muls */ 
 
	    for(i = 0; i < 9; i++) { 
		x[i] = t[i+9] * Granule_imdct_win[gr->block_type][i]; 
		ISCALE(x[i]); 
		x[i+9] = t[17-i] * Granule_imdct_win[gr->block_type][i+9]; 
		ISCALE(x[i+9]); 
		x[i+18] = t[8-i] * Granule_imdct_win[gr->block_type][i+18]; 
		ISCALE(x[i+18]); 
		x[i+27] = t[i] * Granule_imdct_win[gr->block_type][i+27]; 
		ISCALE(x[i+27]); 
	    } 
 
	} 
	 
	/* Overlap and add with previous block - 
	   The first half of the 36 values is overlapped with the second half 
	   of the previous block. The second half of the actual block is stored 
	   to be used in the next block. 
	   */ 
	 
	for(i = 0; i < 18; i++) { 
	    *(X++) = x[i] + *prev;  /* produce an output value */ 
	    *(prev++) = x[i+18];  
	} 
    }	 
     
}