QDM* IMDCT

Mike Melanson <[email protected]>
Newsgroups gmane.comp.video.xine.codec.devel
Message-ID <[email protected]>
Hi,
	I did a little digging in QDesign tonight and found an interesting
function. I'm no expert on the matter, but I think this may be one of them
IMDCT doohickeys that are so prevalent in perceptual audio codecs. Can
anyone "skilled in the art" (as they say in the patent literature) confirm
or deny, compare or contrast with known IMDCTs? Note that I may have a few
functional details mixed up, so don't take it as authoritative (and a few
detals are missing at the end right now).

	Have fun...
--
	-Mike Melanson
qdesign-imdct.txt (text/plain, 7.4 KB)
/* 31 float constants, organized as:
 *  16 constants
 *   8 constants
 *   4 constants
 *   2 constants
 *   1 constant  */
const float const_float[31] = { ... };

/* probably an imdct function
 *   fa = input float array
 *   outf = output float array */
void some_big_qdesign_function(float *fa, float *outf)
{
  float lf[32];  /* lf = local floats */
  float extra;
  float temp;

  extra  =  fa[0] + fa[31];
  lf[16] = (fa[0] - fa[31]) * const_float[0];

  lf[1] =  fa[1] + fa[30];
  lf[17] = (fa[1] - fa[30]) * const_float[1];

  lf[2] =  fa[3] + fa[28];
  lf[18] = (fa[3] - fa[28]) * const_float[2];

  lf[3] =  fa[2] + fa[29];
  lf[19] = (fa[2] - fa[29]) * const_float[3];

  lf[4] =  fa[7] + fa[24];
  lf[20] = (fa[7] - fa[24]) * const_float[4];

  lf[5] =  fa[6] + fa[25];
  lf[21] = (fa[6] - fa[25]) * const_float[5];

  lf[6] =  fa[4] + fa[27];
  lf[22] = (fa[4] - fa[27]) * const_float[6];

  lf[7] =  fa[5] + fa[26];
  lf[23] = (fa[5] - fa[26]) * const_float[7];

  lf[8] =  fa[15] + fa[16];
  lf[24] = (fa[15] - fa[16]) * const_float[8];

  lf[9] =  fa[14] + fa[17];
  lf[25] = (fa[14] - fa[17]) * const_float[9];

  lf[10] =  fa[12] + fa[19];
  lf[26] = (fa[12] - fa[19]) * const_float[10];

  lf[11] =  fa[13] + fa[18];
  lf[27] = (fa[13] - fa[18]) * const_float[11];

  lf[12] =  fa[8] + fa[23];
  lf[28] = (fa[8] - fa[23]) * const_float[12];

  lf[13] =  fa[9] + fa[22];
  lf[29] = (fa[9] - fa[22]) * const_float[13];

  lf[14] =  fa[11] + fa[20];
  lf[30] = (fa[11] - fa[20]) * const_float[14];

  lf[15] =  fa[10] + fa[21];
  lf[31] = (fa[10] - fa[21]) * const_float[15];

  temp = extra;
  extra += lf[8];
  temp -= lf[8];
  temp *= const_float[16];
  temp = lf[16];
  lf[16] += lf[24];
  lf[24] = (temp - lf[24]) * float_const[16];

  temp = lf[1];
  lf[1] += lf[9];
  lf[9] = (temp - lf[9]) * float_const[17];
  temp = lf[17];
  lf[17] += lf[25];
  lf[25] = (temp - lf[25]) * float_const[17];

  temp = lf[2];
  lf[2] += lf[10];
  lf[10] = (temp - lf[10]) * float_const[18];
  temp = lf[18];
  lf[18] += lf[26];
  lf[26] = (temp - lf[26]) * float_const[18];

  temp = lf[3];
  lf[3] += lf[11];
  lf[11] = (temp - lf[11]) * float_const[19];
  temp = lf[19];
  lf[19] += lf[27];
  lf[27] = (temp - lf[27]) * float_const[19];

  temp = lf[3];
  lf[3] += lf[11];
  lf[11] = (temp - lf[11]) * float_const[19];
  temp = lf[19];
  lf[19] += lf[27];
  lf[27] = (temp - lf[27]) * float_const[19];

  temp = lf[4];
  lf[4] += lf[12];
  lf[12] = (temp - lf[12]) * float_const[20];
  temp = lf[20];
  lf[20] += lf[28];
  lf[28] = (temp - lf[28]) * float_const[20];

  temp = lf[5];
  lf[5] += lf[13];
  lf[13] = (temp - lf[13]) * float_const[21];
  temp = lf[21];
  lf[21] += lf[29];
  lf[29] = (temp - lf[29]) * float_const[21];

  temp = lf[6];
  lf[6] += lf[14];
  lf[14] = (temp - lf[14]) * float_const[22];
  temp = lf[22];
  lf[22] += lf[30];
  lf[30] = (temp - lf[30]) * float_const[22];

  temp = lf[7];
  lf[7] += lf[15];
  lf[15] = (temp - lf[15]) * float_const[23];
  temp = lf[23];
  lf[23] += lf[31];
  lf[31] = (temp - lf[31]) * float_const[23];

  temp = extra;
  extra += lf[4];
  temp -= lf[4];
  temp *= const_float[24];
  lf[4] = temp;

  temp = lf[8];
  lf[8] += lf[12];
  lf[12] = (temp - lf[12]) * float_const[24];
  temp = lf[16];
  lf[16] += lf[20];
  lf[20] = (temp - lf[20]) * float_const[24];
  temp = lf[24];
  lf[24] += lf[28];
  lf[28] = (temp - lf[28]) * float_const[24];

  temp = lf[1];
  lf[1] += lf[5];
  lf[5] = (temp - lf[5]) * float_const[25];
  temp = lf[9];
  lf[9] += lf[13];
  lf[13] = (temp - lf[13]) * float_const[25];
  temp = lf[17];
  lf[17] += lf[21];
  lf[21] = (temp - lf[21]) * float_const[25];
  temp = lf[25];
  lf[25] += lf[29];
  lf[29] = (temp - lf[29]) * float_const[25];

  temp = lf[2];
  lf[2] += lf[6];
  lf[6] = (temp - lf[6]) * float_const[26];
  temp = lf[10];
  lf[10] += lf[14];
  lf[14] = (temp - lf[14]) * float_const[26];
  temp = lf[18];
  lf[18] += lf[22];
  lf[22] = (temp - lf[22]) * float_const[26];
  temp = lf[26];
  lf[26] += lf[30];
  lf[30] = (temp - lf[30]) * float_const[26];

  temp = lf[3];
  lf[3] += lf[7];
  lf[7] = (temp - lf[7]) * float_const[27];
  temp = lf[11];
  lf[11] += lf[15];
  lf[15] = (temp - lf[15]) * float_const[27];
  temp = lf[19];
  lf[19] += lf[23];
  lf[23] = (temp - lf[23]) * float_const[27];
  temp = lf[27];
  lf[27] += lf[31];
  lf[31] = (temp - lf[31]) * float_const[27];

  temp = extra;
  extra += lf[2];
  temp -= lf[2];
  temp *= const_float[28];
  lf[2] *= temp;

  temp = lf[4];
  lf[4] += lf[6];
  lf[6] = (temp - lf[6]) * float_const[28];
  temp = lf[8];
  lf[8] += lf[10];
  lf[10] = (temp - lf[10]) * float_const[28];
  temp = lf[12];
  lf[12] += lf[14];
  lf[14] = (temp - lf[14]) * float_const[28];
  temp = lf[16];
  lf[16] += lf[18];
  lf[18] = (temp - lf[18]) * float_const[28];
  temp = lf[20];
  lf[20] += lf[22];
  lf[22] = (temp - lf[22]) * float_const[28];
  temp = lf[24];
  lf[24] += lf[26];
  lf[26] = (temp - lf[26]) * float_const[28];
  temp = lf[28];
  lf[28] += lf[30];
  lf[30] = (temp - lf[30]) * float_const[28];

  temp = lf[1];
  lf[1] += lf[3];
  lf[3] = (temp - lf[3]) * float_const[29];
  temp = lf[5];
  lf[5] += lf[7];
  lf[7] = (temp - lf[7]) * float_const[29];
  temp = lf[9];
  lf[9] += lf[11];
  lf[11] = (temp - lf[11]) * float_const[29];
  temp = lf[13];
  lf[13] += lf[15];
  lf[15] = (temp - lf[15]) * float_const[29];
  temp = lf[17];
  lf[17] += lf[19];
  lf[19] = (temp - lf[19]) * float_const[29];
  temp = lf[21];
  lf[21] += lf[23];
  lf[23] = (temp - lf[23]) * float_const[29];
  temp = lf[25];
  lf[25] += lf[27];
  lf[27] = (temp - lf[27]) * float_const[29];
  temp = lf[29];
  lf[29] += lf[31];
  lf[31] = (temp - lf[31]) * float_const[29];

  temp = extra;
  extra += lf[1];
  temp -= lf[1];
  temp *= const_float[30];
  lf[1] *= temp;

  temp = lf[2];
  lf[2] += lf[3];
  lf[3] = (temp - lf[3]) * float_const[30];
  temp = lf[4];
  lf[4] += lf[5];
  lf[5] = (temp - lf[5]) * float_const[30];
  temp = lf[6];
  lf[6] += lf[7];
  lf[7] = (temp - lf[7]) * float_const[30];
  temp = lf[8];
  lf[8] += lf[9];
  lf[9] = (temp - lf[9]) * float_const[30];
  temp = lf[10];
  lf[10] += lf[11];
  lf[11] = (temp - lf[11]) * float_const[30];
  temp = lf[12];
  lf[12] += lf[13];
  lf[13] = (temp - lf[13]) * float_const[30];
  temp = lf[14];
  lf[14] += lf[15];
  lf[15] = (temp - lf[15]) * float_const[30];
  temp = lf[16];
  lf[16] += lf[17];
  lf[17] = (temp - lf[17]) * float_const[30];
  temp = lf[18];
  lf[18] += lf[19];
  lf[19] = (temp - lf[19]) * float_const[30];
  temp = lf[20];
  lf[20] += lf[21];
  lf[21] = (temp - lf[21]) * float_const[30];
  temp = lf[22];
  lf[22] += lf[23];
  lf[23] = (temp - lf[23]) * float_const[30];
  temp = lf[24];
  lf[24] += lf[25];
  lf[25] = (temp - lf[25]) * float_const[30];
  temp = lf[26];
  lf[26] += lf[27];
  lf[27] = (temp - lf[27]) * float_const[30];
  temp = lf[28];
  lf[28] += lf[29];
  lf[29] = (temp - lf[29]) * float_const[30];
  temp = lf[30];
  lf[30] += lf[31];
  lf[31] = (temp - lf[31]) * float_const[30];


  /* some more addition between the lf[] members takes place, then the
   * pieces of lf[] are stuffed in the output float array in a
   * rearranged order, sometimes with the sign bits flipped */

}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.