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 */
}