inv_mdct.cpp
上传用户:tuheem
上传日期:2007-05-01
资源大小:21889k
文件大小:13k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. /* inv_mdct.cpp
  2.  *
  3.  * Inverse Discrete Cosine Transform for hybrid
  4.  * synthesis in MPEG Audio Layer III. Based on the public_c source,
  5.  * but almost completely redone by Jeff Tsay and Francois-Raymond Boyer.
  6.  *
  7.  * Tomilla's 9 point IDCT algorithm has been replaced with Boyer's, which
  8.  * is faster. The final output multiplications required by Lee's FDCT
  9.  * have been folded into the multiplication by the window.
  10.  *
  11.  * Last modified : 08/02/97
  12.  */
  13. #include "all.h"
  14. #include "inv_mdct.h"
  15. /*
  16.  * This uses Byeong Gi Lee's Fast Cosine Transform algorithm to
  17.  * decompose the 36 point and 12 point IDCT's into 9 point and 3
  18.  * point IDCT's, respectively. Then the 9 point IDCT is computed
  19.  * by Francois-Raymond Boyer's algorithm. See his comments before
  20.  * the first 9 point IDCT. The 3 point IDCT is already efficient
  21.  * to implement. -- Jeff Tsay. 
  22.  */
  23. #ifdef COOLPRO
  24. #pragma optimize("",off) // If full optimizations are done,
  25. #pragma optimize("t",on) // VC 5.0 generates bad code
  26. #endif
  27. real win[4][36] =
  28. {
  29.  { -1.6141214951E-02f, -5.3603178919E-02f, -1.0070713296E-01f, -1.6280817573E-01f,
  30.    -4.9999999679E-01f, -3.8388735032E-01f, -6.2061144372E-01f, -1.1659756083E+00f,
  31.    -3.8720752656E+00f, -4.2256286556E+00f, -1.5195289984E+00f, -9.7416483388E-01f,
  32.    -7.3744074053E-01f, -1.2071067773E+00f, -5.1636156596E-01f, -4.5426052317E-01f,
  33.    -4.0715656898E-01f, -3.6969460527E-01f, -3.3876269197E-01f, -3.1242222492E-01f,
  34.    -2.8939587111E-01f, -2.6880081906E-01f, -5.0000000266E-01f, -2.3251417468E-01f,
  35.    -2.1596714708E-01f, -2.0004979098E-01f, -1.8449493497E-01f, -1.6905846094E-01f,
  36.    -1.5350360518E-01f, -1.3758624925E-01f, -1.2103922149E-01f, -2.0710679058E-01f,
  37.    -8.4752577594E-02f, -6.4157525656E-02f, -4.1131172614E-02f, -1.4790705759E-02f },
  38.  { -1.6141214951E-02f, -5.3603178919E-02f, -1.0070713296E-01f, -1.6280817573E-01f,
  39.    -4.9999999679E-01f, -3.8388735032E-01f, -6.2061144372E-01f, -1.1659756083E+00f,
  40.    -3.8720752656E+00f, -4.2256286556E+00f, -1.5195289984E+00f, -9.7416483388E-01f,
  41.    -7.3744074053E-01f, -1.2071067773E+00f, -5.1636156596E-01f, -4.5426052317E-01f,
  42.    -4.0715656898E-01f, -3.6969460527E-01f, -3.3908542600E-01f, -3.1511810350E-01f,
  43.    -2.9642226150E-01f, -2.8184548650E-01f, -5.4119610000E-01f, -2.6213228100E-01f, 
  44.    -2.5387916537E-01f, -2.3296291359E-01f, -1.9852728987E-01f, -1.5233534808E-01f, 
  45.    -9.6496400054E-02f, -3.3423828516E-02f, 0.0000000000E+00f, 0.0000000000E+00f,
  46.    0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f },
  47.  { -4.8300800645E-02f, -1.5715656932E-01f, -2.8325045177E-01f, -4.2953747763E-01f, 
  48.    -1.2071067795E+00f, -8.2426483178E-01f, -1.1451749106E+00f, -1.7695290101E+00f,
  49.    -4.5470225061E+00f, -3.4890531002E+00f, -7.3296292804E-01f, -1.5076514758E-01f, 
  50.    0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f,
  51.    0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f,
  52.    0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f,
  53.    0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f, 
  54.    0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f,
  55.    0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f },
  56.  { 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f, 0.0000000000E+00f,
  57.    0.0000000000E+00f, 0.0000000000E+00f, -1.5076513660E-01f, -7.3296291107E-01f,
  58.    -3.4890530566E+00f, -4.5470224727E+00f, -1.7695290031E+00f, -1.1451749092E+00f,
  59.    -8.3137738100E-01f, -1.3065629650E+00f, -5.4142014250E-01f, -4.6528974900E-01f,
  60.    -4.1066990750E-01f, -3.7004680800E-01f, -3.3876269197E-01f, -3.1242222492E-01f,
  61.    -2.8939587111E-01f, -2.6880081906E-01f, -5.0000000266E-01f, -2.3251417468E-01f,
  62.    -2.1596714708E-01f, -2.0004979098E-01f, -1.8449493497E-01f, -1.6905846094E-01f,
  63.    -1.5350360518E-01f, -1.3758624925E-01f, -1.2103922149E-01f, -2.0710679058E-01f,
  64.    -8.4752577594E-02f, -6.4157525656E-02f, -4.1131172614E-02f, -1.4790705759E-02f }
  65. };
  66. void inv_mdct(real *in, real *out, int32 block_type)
  67. {
  68.  real    tmp[18];
  69.  real    *win_bt;
  70.     int32   i;
  71.  if(block_type == 2){
  72.    for(int32 p=0;p<36;p+=9) {
  73.     out[p]   = out[p+1] = out[p+2] = out[p+3] =
  74.       out[p+4] = out[p+5] = out[p+6] = out[p+7] =
  75.       out[p+8] = 0.0f;
  76.    }
  77.      int32 six_i = 0;
  78.    for(i=0;i<3;i++)
  79.     {
  80.        // 12 point IMDCT
  81.          // Begin 12 point IDCT
  82.     // Input aliasing for 12 pt IDCT
  83.     in[15+i] += in[12+i]; in[12+i] += in[9+i]; in[9+i]  +=  in[6+i];
  84.     in[6+i]  += in[3+i];  in[3+i]  += in[0+i];
  85.     // Input aliasing on odd indices (for 6 point IDCT)
  86.     in[15+i] += in[9+i];  in[9+i]  += in[3+i];
  87.     // 3 point IDCT on even indices
  88.          {
  89.       real  pp1, pp2, sum;
  90. pp2 = in[12+i] * 0.500000000f;
  91.     pp1 = in[ 6+i] * 0.866025403f;
  92.     sum = in[0+i] + pp2;
  93.     tmp[1] = in[0+i] - in[12+i];
  94.     tmp[0] = sum + pp1;
  95.     tmp[2] = sum - pp1;
  96.        // End 3 point IDCT on even indices
  97.     // 3 point IDCT on odd indices (for 6 point IDCT)
  98. pp2 = in[15+i] * 0.500000000f;
  99.     pp1 = in[ 9+i] * 0.866025403f;
  100.     sum = in[ 3+i] + pp2;
  101.     tmp[4] = in[3+i] - in[15+i];
  102.     tmp[5] = sum + pp1;
  103.     tmp[3] = sum - pp1;
  104.          }
  105.        // End 3 point IDCT on odd indices
  106.     // Twiddle factors on odd indices (for 6 point IDCT)
  107.     tmp[3] *= 1.931851653f;
  108.     tmp[4] *= 0.707106781f;
  109.     tmp[5] *= 0.517638090f;
  110.     // Output butterflies on 2 3 point IDCT's (for 6 point IDCT)
  111.          {
  112.     real save = tmp[0];
  113.     tmp[0] += tmp[5];
  114.     tmp[5] = save - tmp[5];
  115.     save = tmp[1];
  116.     tmp[1] += tmp[4];
  117.     tmp[4] = save - tmp[4];
  118.     save = tmp[2];
  119.     tmp[2] += tmp[3];
  120.     tmp[3] = save - tmp[3];
  121.          }
  122.     // End 6 point IDCT
  123.     // Twiddle factors on indices (for 12 point IDCT)
  124.     tmp[0]  *=  0.504314480f;
  125.     tmp[1]  *=  0.541196100f;
  126.     tmp[2]  *=  0.630236207f;
  127.     tmp[3]  *=  0.821339815f;
  128.     tmp[4]  *=  1.306562965f;
  129.     tmp[5]  *=  3.830648788f;
  130.        // End 12 point IDCT
  131.     // Shift to 12 point modified IDCT, multiply by window type 2
  132.     tmp[8]  = -tmp[0] * 0.793353340f;
  133.     tmp[9]  = -tmp[0] * 0.608761429f;
  134.     tmp[7]  = -tmp[1] * 0.923879532f;
  135.     tmp[10] = -tmp[1] * 0.382683432f;
  136.     tmp[6]  = -tmp[2] * 0.991444861f;
  137.     tmp[11] = -tmp[2] * 0.130526192f;
  138.     tmp[0]  =  tmp[3];
  139.     tmp[1]  =  tmp[4] * 0.382683432f;
  140.     tmp[2]  =  tmp[5] * 0.608761429f;
  141.     tmp[3]  = -tmp[5] * 0.793353340f;
  142.     tmp[4]  = -tmp[4] * 0.923879532f;
  143.     tmp[5]  = -tmp[0] * 0.991444861f;
  144.     tmp[0] *= 0.130526192f;
  145.     out[six_i + 6]  += tmp[0];
  146. out[six_i + 7]  += tmp[1];
  147.     out[six_i + 8]  += tmp[2];
  148. out[six_i + 9]  += tmp[3];
  149.     out[six_i + 10] += tmp[4];
  150. out[six_i + 11] += tmp[5];
  151.     out[six_i + 12] += tmp[6];
  152. out[six_i + 13] += tmp[7];
  153.     out[six_i + 14] += tmp[8];
  154. out[six_i + 15] += tmp[9];
  155.     out[six_i + 16] += tmp[10];
  156. out[six_i + 17] += tmp[11];
  157.     six_i += 6;
  158.     }
  159.  } else {
  160.    // 36 point IDCT
  161.    // input aliasing for 36 point IDCT
  162.    in[17]+=in[16]; in[16]+=in[15]; in[15]+=in[14]; in[14]+=in[13];
  163.    in[13]+=in[12]; in[12]+=in[11]; in[11]+=in[10]; in[10]+=in[9];
  164.    in[9] +=in[8];  in[8] +=in[7];  in[7] +=in[6];  in[6] +=in[5];
  165.    in[5] +=in[4];  in[4] +=in[3];  in[3] +=in[2];  in[2] +=in[1];
  166.    in[1] +=in[0];
  167.    // 18 point IDCT for odd indices
  168.    // input aliasing for 18 point IDCT
  169.    in[17]+=in[15]; in[15]+=in[13]; in[13]+=in[11]; in[11]+=in[9];
  170.    in[9] +=in[7];  in[7] +=in[5];  in[5] +=in[3];  in[3] +=in[1];
  171. {
  172.    real tmp0,tmp1,tmp2,tmp3,tmp4,tmp0_,tmp1_,tmp2_,tmp3_;
  173.    real tmp0o,tmp1o,tmp2o,tmp3o,tmp4o,tmp0_o,tmp1_o,tmp2_o,tmp3_o;
  174. // Fast 9 Point Inverse Discrete Cosine Transform
  175. //
  176. // By  Francois-Raymond Boyer
  177. //         mailto:boyerf@iro.umontreal.ca
  178. //         http://www.iro.umontreal.ca/~boyerf
  179. //
  180. // The code has been optimized for Intel processors
  181. //  (takes a lot of time to convert float to and from iternal FPU representation)
  182. //
  183. // It is a simple "factorization" of the IDCT matrix.
  184.    // 9 point IDCT on even indices
  185.    {
  186. // 5 points on odd indices (not realy an IDCT)
  187.    real i0 = in[0]+in[0];
  188.    real i0p12 = i0 + in[12];
  189.    tmp0 = i0p12 + in[4]*1.8793852415718f  + in[8]*1.532088886238f   + in[16]*0.34729635533386f;
  190.    tmp1 = i0    + in[4]                   - in[8] - in[12] - in[12] - in[16];
  191.    tmp2 = i0p12 - in[4]*0.34729635533386f - in[8]*1.8793852415718f  + in[16]*1.532088886238f;
  192.    tmp3 = i0p12 - in[4]*1.532088886238f   + in[8]*0.34729635533386f - in[16]*1.8793852415718f;
  193.    tmp4 = in[0] - in[4]                   + in[8] - in[12]          + in[16];
  194. // 4 points on even indices
  195.    real i6_ = in[6]*1.732050808f; // Sqrt[3]
  196.    tmp0_ = in[2]*1.9696155060244f  + i6_ + in[10]*1.2855752193731f  + in[14]*0.68404028665134f;
  197.    tmp1_ = (in[2]                        - in[10]                   - in[14])*1.732050808f;
  198.    tmp2_ = in[2]*1.2855752193731f  - i6_ - in[10]*0.68404028665134f + in[14]*1.9696155060244f;
  199.    tmp3_ = in[2]*0.68404028665134f - i6_ + in[10]*1.9696155060244f  - in[14]*1.2855752193731f;
  200.    }
  201.    // 9 point IDCT on odd indices
  202.    {
  203. // 5 points on odd indices (not realy an IDCT)
  204.    real i0 = in[0+1]+in[0+1];
  205.    real i0p12 = i0 + in[12+1];
  206.    tmp0o = i0p12   + in[4+1]*1.8793852415718f  + in[8+1]*1.532088886238f       + in[16+1]*0.34729635533386f;
  207.    tmp1o = i0      + in[4+1]                   - in[8+1] - in[12+1] - in[12+1] - in[16+1];
  208.    tmp2o = i0p12   - in[4+1]*0.34729635533386f - in[8+1]*1.8793852415718f      + in[16+1]*1.532088886238f;
  209.    tmp3o = i0p12   - in[4+1]*1.532088886238f   + in[8+1]*0.34729635533386f     - in[16+1]*1.8793852415718f;
  210.    tmp4o = (in[0+1] - in[4+1]                   + in[8+1] - in[12+1]            + in[16+1])*0.707106781f; // Twiddled
  211. // 4 points on even indices
  212.    real i6_ = in[6+1]*1.732050808f; // Sqrt[3]
  213.    tmp0_o = in[2+1]*1.9696155060244f  + i6_ + in[10+1]*1.2855752193731f  + in[14+1]*0.68404028665134f;
  214.    tmp1_o = (in[2+1]                        - in[10+1]                   - in[14+1])*1.732050808f;
  215.    tmp2_o = in[2+1]*1.2855752193731f  - i6_ - in[10+1]*0.68404028665134f + in[14+1]*1.9696155060244f;
  216.    tmp3_o = in[2+1]*0.68404028665134f - i6_ + in[10+1]*1.9696155060244f  - in[14+1]*1.2855752193731f;
  217.    }
  218.    // Twiddle factors on odd indices
  219.    // and
  220.    // Butterflies on 9 point IDCT's
  221.    // and
  222.    // twiddle factors for 36 point IDCT
  223.    real e, o;
  224.    e = tmp0 + tmp0_; o = (tmp0o + tmp0_o)*0.501909918f; tmp[0] = e + o;    tmp[17] = e - o;
  225.    e = tmp1 + tmp1_; o = (tmp1o + tmp1_o)*0.517638090f; tmp[1] = e + o;    tmp[16] = e - o;
  226.    e = tmp2 + tmp2_; o = (tmp2o + tmp2_o)*0.551688959f; tmp[2] = e + o;    tmp[15] = e - o;
  227.    e = tmp3 + tmp3_; o = (tmp3o + tmp3_o)*0.610387294f; tmp[3] = e + o;    tmp[14] = e - o;
  228.    tmp[4] = tmp4 + tmp4o; tmp[13] = tmp4 - tmp4o;
  229.    e = tmp3 - tmp3_; o = (tmp3o - tmp3_o)*0.871723397f; tmp[5] = e + o;    tmp[12] = e - o;
  230.    e = tmp2 - tmp2_; o = (tmp2o - tmp2_o)*1.183100792f; tmp[6] = e + o;    tmp[11] = e - o;
  231.    e = tmp1 - tmp1_; o = (tmp1o - tmp1_o)*1.931851653f; tmp[7] = e + o;    tmp[10] = e - o;
  232.    e = tmp0 - tmp0_; o = (tmp0o - tmp0_o)*5.736856623f; tmp[8] = e + o;    tmp[9] =  e - o;
  233.    }
  234.    // end 36 point IDCT */
  235. // shift to modified IDCT
  236.    win_bt = win[block_type];
  237. out[0] =-tmp[9]  * win_bt[0];
  238.    out[1] =-tmp[10] * win_bt[1];
  239. out[2] =-tmp[11] * win_bt[2];
  240.    out[3] =-tmp[12] * win_bt[3];
  241.    out[4] =-tmp[13] * win_bt[4];
  242. out[5] =-tmp[14] * win_bt[5];
  243. out[6] =-tmp[15] * win_bt[6];
  244. out[7] =-tmp[16] * win_bt[7];
  245. out[8] =-tmp[17] * win_bt[8];
  246.    out[9] = tmp[17] * win_bt[9];
  247.    out[10]= tmp[16] * win_bt[10];
  248. out[11]= tmp[15] * win_bt[11];
  249. out[12]= tmp[14] * win_bt[12];
  250. out[13]= tmp[13] * win_bt[13];
  251. out[14]= tmp[12] * win_bt[14];
  252.    out[15]= tmp[11] * win_bt[15];
  253. out[16]= tmp[10] * win_bt[16];
  254. out[17]= tmp[9]  * win_bt[17];
  255. out[18]= tmp[8]  * win_bt[18];
  256.    out[19]= tmp[7]  * win_bt[19];
  257. out[20]= tmp[6]  * win_bt[20];
  258.    out[21]= tmp[5]  * win_bt[21];
  259. out[22]= tmp[4]  * win_bt[22];
  260. out[23]= tmp[3]  * win_bt[23];
  261.   out[24]= tmp[2]  * win_bt[24];
  262.    out[25]= tmp[1]  * win_bt[25];
  263. out[26]= tmp[0]  * win_bt[26];
  264.    out[27]= tmp[0]  * win_bt[27];
  265. out[28]= tmp[1]  * win_bt[28];
  266. out[29]= tmp[2]  * win_bt[29];
  267. out[30]= tmp[3]  * win_bt[30];
  268. out[31]= tmp[4]  * win_bt[31];
  269.    out[32]= tmp[5]  * win_bt[32];
  270. out[33]= tmp[6]  * win_bt[33];
  271. out[34]= tmp[7]  * win_bt[34];
  272. out[35]= tmp[8]  * win_bt[35];
  273. }
  274. }
  275. #ifdef COOLPRO
  276. #pragma optimize("",on)  // Restore optimizations for VC 5.0
  277. #endif