1a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/*
2a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *
4a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *  Use of this source code is governed by a BSD-style license
5a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *  that can be found in the LICENSE file in the root of the source
6a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *  tree. An additional intellectual property rights grant can be found
7a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *  in the file PATENTS.  All contributing project authors may
8a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *  be found in the AUTHORS file in the root of the source tree.
9a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin */
10a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
11a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/*
12a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * fft.c
13a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *
14a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * Fast Fourier Transform
15a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *
16a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin */
17a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
18a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
19a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin#include "fft.h"
20a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
21a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinconst WebRtc_Word16 kSortTabFft[240] = {
22a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  0, 60, 120, 180, 20, 80, 140, 200, 40, 100, 160, 220,
23a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  4, 64, 124, 184, 24, 84, 144, 204, 44, 104, 164, 224,
24a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  8, 68, 128, 188, 28, 88, 148, 208, 48, 108, 168, 228,
25a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  12, 72, 132, 192, 32, 92, 152, 212, 52, 112, 172, 232,
26a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  16, 76, 136, 196, 36, 96, 156, 216, 56, 116, 176, 236,
27a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  1, 61, 121, 181, 21, 81, 141, 201, 41, 101, 161, 221,
28a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  5, 65, 125, 185, 25, 85, 145, 205, 45, 105, 165, 225,
29a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  9, 69, 129, 189, 29, 89, 149, 209, 49, 109, 169, 229,
30a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  13, 73, 133, 193, 33, 93, 153, 213, 53, 113, 173, 233,
31a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  17, 77, 137, 197, 37, 97, 157, 217, 57, 117, 177, 237,
32a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  2, 62, 122, 182, 22, 82, 142, 202, 42, 102, 162, 222,
33a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  6, 66, 126, 186, 26, 86, 146, 206, 46, 106, 166, 226,
34a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  10, 70, 130, 190, 30, 90, 150, 210, 50, 110, 170, 230,
35a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  14, 74, 134, 194, 34, 94, 154, 214, 54, 114, 174, 234,
36a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  18, 78, 138, 198, 38, 98, 158, 218, 58, 118, 178, 238,
37a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  3, 63, 123, 183, 23, 83, 143, 203, 43, 103, 163, 223,
38a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  7, 67, 127, 187, 27, 87, 147, 207, 47, 107, 167, 227,
39a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  11, 71, 131, 191, 31, 91, 151, 211, 51, 111, 171, 231,
40a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  15, 75, 135, 195, 35, 95, 155, 215, 55, 115, 175, 235,
41a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  19, 79, 139, 199, 39, 99, 159, 219, 59, 119, 179, 239
42a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin};
43a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
44a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/* Cosine table in Q14 */
45a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinconst WebRtc_Word16 kCosTabFfftQ14[240] = {
46a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  16384,  16378, 16362,   16333,  16294,  16244,  16182,  16110,  16026,  15931,  15826,  15709,
47a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  15582,  15444, 15296,   15137,  14968,  14788,  14598,  14399,  14189,  13970,  13741,  13502,
48a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  13255,  12998, 12733,   12458,  12176,  11885,  11585,  11278,  10963,  10641,  10311,   9974,
49a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  9630,   9280,  8923,    8561,   8192,   7818,   7438,   7053,   6664,   6270,   5872,   5469,
50a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  5063,   4653,  4240,    3825,   3406,   2986,   2563,   2139,   1713,   1285,    857,    429,
51a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  0,   -429,  -857,   -1285,  -1713,  -2139,  -2563,  -2986,  -3406,  -3825,  -4240,  -4653,
52a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  -5063,  -5469, -5872,   -6270,  -6664,  -7053,  -7438,  -7818,  -8192,  -8561,  -8923,  -9280,
53a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  -9630,  -9974, -10311, -10641, -10963, -11278, -11585, -11885, -12176, -12458, -12733, -12998,
54a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  -13255, -13502, -13741, -13970, -14189, -14399, -14598, -14788, -14968, -15137, -15296, -15444,
55a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  -15582, -15709, -15826, -15931, -16026, -16110, -16182, -16244, -16294, -16333, -16362, -16378,
56a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  -16384, -16378, -16362, -16333, -16294, -16244, -16182, -16110, -16026, -15931, -15826, -15709,
57a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  -15582, -15444, -15296, -15137, -14968, -14788, -14598, -14399, -14189, -13970, -13741, -13502,
58a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  -13255, -12998, -12733, -12458, -12176, -11885, -11585, -11278, -10963, -10641, -10311,  -9974,
59a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  -9630,  -9280,  -8923,  -8561,  -8192,  -7818,  -7438,  -7053,  -6664,  -6270,  -5872,  -5469,
60a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  -5063,  -4653,  -4240,  -3825,  -3406,  -2986,  -2563,  -2139,  -1713,  -1285,   -857,   -429,
61a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  0,    429,    857,   1285,   1713,   2139,   2563,   2986,   3406,   3825,   4240,   4653,
62a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  5063,   5469,   5872,   6270,   6664,   7053,   7438,   7818,   8192,   8561,   8923,   9280,
63a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  9630,   9974,  10311,  10641,  10963,  11278,  11585,  11885,  12176,  12458,  12733,  12998,
64a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  13255,  13502,  13741,  13970,  14189,  14399,  14598,  14788,  14968,  15137,  15296,  15444,
65a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  15582,  15709,  15826,  15931,  16026,  16110,  16182,  16244,  16294,  16333,  16362,  16378
66a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin};
67a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
68a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
69a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
70a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/* Uses 16x16 mul, without rounding, which is faster. Uses WEBRTC_SPL_MUL_16_16_RSFT */
71a6451827d543eb00824bc95097e47d0aac51ae93Alexander GutkinWebRtc_Word16 WebRtcIsacfix_FftRadix16Fastest(WebRtc_Word16 RexQx[], WebRtc_Word16 ImxQx[], WebRtc_Word16 iSign) {
72a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
73a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word16 dd, ee, ff, gg, hh, ii;
74a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word16 k0, k1, k2, k3, k4, kk;
75a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word16 tmp116, tmp216;
76a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
77a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word16 ccc1Q14, ccc2Q14, ccc3Q14, sss1Q14, sss2Q14, sss3Q14;
78a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word16 sss60Q14, ccc72Q14, sss72Q14;
79a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word16 aaQx, ajQx, akQx, ajmQx, ajpQx, akmQx, akpQx;
80a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word16 bbQx, bjQx, bkQx, bjmQx, bjpQx, bkmQx, bkpQx;
81a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
82a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word16 ReDATAQx[240],  ImDATAQx[240];
83a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
84a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  sss60Q14 = kCosTabFfftQ14[20];
85a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  ccc72Q14 = kCosTabFfftQ14[48];
86a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  sss72Q14 = kCosTabFfftQ14[12];
87a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
88a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  if (iSign < 0) {
89a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    sss72Q14 = -sss72Q14;
90a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    sss60Q14 = -sss60Q14;
91a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
92a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* Complexity is: 10 cycles */
93a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
94a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* compute fourier transform */
95a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
96a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  // transform for factor of 4
97a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  for (kk=0; kk<60; kk++) {
98a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    k0 = kk;
99a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    k1 = k0 + 60;
100a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    k2 = k1 + 60;
101a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    k3 = k2 + 60;
102a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
103a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    akpQx = RexQx[k0] + RexQx[k2];
104a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    akmQx = RexQx[k0] - RexQx[k2];
105a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    ajpQx = RexQx[k1] + RexQx[k3];
106a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    ajmQx = RexQx[k1] - RexQx[k3];
107a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bkpQx = ImxQx[k0] + ImxQx[k2];
108a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bkmQx = ImxQx[k0] - ImxQx[k2];
109a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bjpQx = ImxQx[k1] + ImxQx[k3];
110a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bjmQx = ImxQx[k1] - ImxQx[k3];
111a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
112a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    RexQx[k0] = akpQx + ajpQx;
113a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    ImxQx[k0] = bkpQx + bjpQx;
114a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    ajpQx = akpQx - ajpQx;
115a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bjpQx = bkpQx - bjpQx;
116a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    if (iSign < 0) {
117a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      akpQx = akmQx + bjmQx;
118a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      bkpQx = bkmQx - ajmQx;
119a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      akmQx -= bjmQx;
120a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      bkmQx += ajmQx;
121a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    } else {
122a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      akpQx = akmQx - bjmQx;
123a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      bkpQx = bkmQx + ajmQx;
124a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      akmQx += bjmQx;
125a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      bkmQx -= ajmQx;
126a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    }
127a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
128a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    ccc1Q14 = kCosTabFfftQ14[kk];
129a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    ccc2Q14 = kCosTabFfftQ14[WEBRTC_SPL_MUL_16_16(2, kk)];
130a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    ccc3Q14 = kCosTabFfftQ14[WEBRTC_SPL_MUL_16_16(3, kk)];
131a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    sss1Q14 = kCosTabFfftQ14[kk+60];
132a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    sss2Q14 = kCosTabFfftQ14[WEBRTC_SPL_MUL_16_16(2, kk)+60];
133a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    sss3Q14 = kCosTabFfftQ14[WEBRTC_SPL_MUL_16_16(3, kk)+60];
134a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    if (iSign==1) {
135a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      sss1Q14 = -sss1Q14;
136a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      sss2Q14 = -sss2Q14;
137a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      sss3Q14 = -sss3Q14;
138a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    }
139a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
140a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    //Do several multiplications like Q14*Q16>>14 = Q16
141a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    // RexQ16[k1] = akpQ16 * ccc1Q14 - bkpQ16 * sss1Q14;
142a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    // RexQ16[k2] = ajpQ16 * ccc2Q14 - bjpQ16 * sss2Q14;
143a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    // RexQ16[k3] = akmQ16 * ccc3Q14 - bkmQ16 * sss3Q14;
144a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    // ImxQ16[k1] = akpQ16 * sss1Q14 + bkpQ16 * ccc1Q14;
145a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    // ImxQ16[k2] = ajpQ16 * sss2Q14 + bjpQ16 * ccc2Q14;
146a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    // ImxQ16[k3] = akmQ16 * sss3Q14 + bkmQ16 * ccc3Q14;
147a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
148a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    RexQx[k1] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc1Q14, akpQx, 14) -
149a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss1Q14, bkpQx, 14); // 6 non-mul + 2 mul cycles, i.e. 8 cycles (6+2*7=20 cycles if 16x32mul)
150a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    RexQx[k2] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, ajpQx, 14) -
151a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, bjpQx, 14);
152a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    RexQx[k3] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc3Q14, akmQx, 14) -
153a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss3Q14, bkmQx, 14);
154a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    ImxQx[k1] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss1Q14, akpQx, 14) +
155a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc1Q14, bkpQx, 14);
156a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    ImxQx[k2] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, ajpQx, 14) +
157a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, bjpQx, 14);
158a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    ImxQx[k3] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss3Q14, akmQx, 14) +
159a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc3Q14, bkmQx, 14);
160a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    //This mul segment needs 6*8 = 48 cycles for 16x16 muls, but 6*20 = 120 cycles for 16x32 muls
161a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
162a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
163a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
164a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* Complexity is: 51+48 = 99 cycles for 16x16 muls, but 51+120 = 171 cycles for 16x32 muls*/
165a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
166a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  // transform for factor of 3
167a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  kk=0;
168a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  k1=20;
169a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  k2=40;
170a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
171a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  for (hh=0; hh<4; hh++) {
172a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    for (ii=0; ii<20; ii++) {
173a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      akQx = RexQx[kk];
174a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      bkQx = ImxQx[kk];
175a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      ajQx = RexQx[k1] + RexQx[k2];
176a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      bjQx = ImxQx[k1] + ImxQx[k2];
177a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      RexQx[kk] = akQx + ajQx;
178a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      ImxQx[kk] = bkQx + bjQx;
179a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      tmp116 = WEBRTC_SPL_RSHIFT_W16(ajQx, 1);
180a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      tmp216 = WEBRTC_SPL_RSHIFT_W16(bjQx, 1);
181a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      akQx = akQx - tmp116;
182a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      bkQx = bkQx - tmp216;
183a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      tmp116 = RexQx[k1] - RexQx[k2];
184a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      tmp216 = ImxQx[k1] - ImxQx[k2];
185a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
186a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      ajQx = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss60Q14, tmp116, 14); // Q14*Qx>>14 = Qx
187a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      bjQx = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss60Q14, tmp216, 14); // Q14*Qx>>14 = Qx
188a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      RexQx[k1] = akQx - bjQx;
189a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      RexQx[k2] = akQx + bjQx;
190a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      ImxQx[k1] = bkQx + ajQx;
191a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      ImxQx[k2] = bkQx - ajQx;
192a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
193a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      kk++;
194a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      k1++;
195a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      k2++;
196a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    }
197a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    /* Complexity : (31+6)*20 = 740 cycles for 16x16 muls, but (31+18)*20 = 980 cycles for 16x32 muls*/
198a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    kk=kk+40;
199a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    k1=k1+40;
200a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    k2=k2+40;
201a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
202a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* Complexity : 4*(740+3) = 2972 cycles for 16x16 muls, but 4*(980+3) = 3932 cycles for 16x32 muls*/
203a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
204a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* multiply by rotation factor for odd factor 3 or 5 (not for 4)
205a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin     Same code (duplicated) for both ii=2 and ii=3 */
206a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  kk = 1;
207a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  ee = 0;
208a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  ff = 0;
209a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
210a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  for (gg=0; gg<19; gg++) {
211a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    kk += 20;
212a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    ff = ff+4;
213a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    for (hh=0; hh<2; hh++) {
214a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      ee = ff + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(hh, ff);
215a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      dd = ee + 60;
216a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      ccc2Q14 = kCosTabFfftQ14[ee];
217a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      sss2Q14 = kCosTabFfftQ14[dd];
218a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      if (iSign==1) {
219a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        sss2Q14 = -sss2Q14;
220a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      }
221a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      for (ii=0; ii<4; ii++) {
222a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        akQx = RexQx[kk];
223a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        bkQx = ImxQx[kk];
224a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        RexQx[kk] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, akQx, 14) - // Q14*Qx>>14 = Qx
225a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin            (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, bkQx, 14);
226a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        ImxQx[kk] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, akQx, 14) + // Q14*Qx>>14 = Qx
227a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin            (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, bkQx, 14);
228a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
229a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
230a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        kk += 60;
231a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      }
232a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      kk = kk - 220;
233a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    }
234a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    // Complexity: 2*(13+5+4*13+2) = 144 for 16x16 muls, but 2*(13+5+4*33+2) = 304 cycles for 16x32 muls
235a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    kk = kk - 59;
236a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
237a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  // Complexity: 19*144 = 2736 for 16x16 muls, but 19*304 = 5776 cycles for 16x32 muls
238a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
239a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  // transform for factor of 5
240a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  kk = 0;
241a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  ccc2Q14 = kCosTabFfftQ14[96];
242a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  sss2Q14 = kCosTabFfftQ14[84];
243a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  if (iSign==1) {
244a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    sss2Q14 = -sss2Q14;
245a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
246a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
247a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  for (hh=0; hh<4; hh++) {
248a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    for (ii=0; ii<12; ii++) {
249a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      k1 = kk + 4;
250a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      k2 = k1 + 4;
251a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      k3 = k2 + 4;
252a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      k4 = k3 + 4;
253a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
254a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      akpQx = RexQx[k1] + RexQx[k4];
255a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      akmQx = RexQx[k1] - RexQx[k4];
256a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      bkpQx = ImxQx[k1] + ImxQx[k4];
257a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      bkmQx = ImxQx[k1] - ImxQx[k4];
258a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      ajpQx = RexQx[k2] + RexQx[k3];
259a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      ajmQx = RexQx[k2] - RexQx[k3];
260a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      bjpQx = ImxQx[k2] + ImxQx[k3];
261a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      bjmQx = ImxQx[k2] - ImxQx[k3];
262a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      aaQx = RexQx[kk];
263a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      bbQx = ImxQx[kk];
264a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      RexQx[kk] = aaQx + akpQx + ajpQx;
265a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      ImxQx[kk] = bbQx + bkpQx + bjpQx;
266a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
267a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      akQx = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc72Q14, akpQx, 14) +
268a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, ajpQx, 14)  + aaQx;
269a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      bkQx = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc72Q14, bkpQx, 14) +
270a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, bjpQx, 14)  + bbQx;
271a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      ajQx = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss72Q14, akmQx, 14) +
272a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, ajmQx, 14);
273a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      bjQx = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss72Q14, bkmQx, 14) +
274a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, bjmQx, 14);
275a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      // 32+4*8=64 or 32+4*20=112
276a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
277a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      RexQx[k1] = akQx - bjQx;
278a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      RexQx[k4] = akQx + bjQx;
279a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      ImxQx[k1] = bkQx + ajQx;
280a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      ImxQx[k4] = bkQx - ajQx;
281a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
282a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      akQx = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, akpQx, 14)  +
283a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc72Q14, ajpQx, 14) + aaQx;
284a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      bkQx = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, bkpQx, 14)  +
285a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc72Q14, bjpQx, 14) + bbQx;
286a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      ajQx = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, akmQx, 14) -
287a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss72Q14, ajmQx, 14);
288a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      bjQx = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, bkmQx, 14) -
289a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss72Q14, bjmQx, 14);
290a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      // 8+4*8=40 or 8+4*20=88
291a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
292a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      RexQx[k2] = akQx - bjQx;
293a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      RexQx[k3] = akQx + bjQx;
294a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      ImxQx[k2] = bkQx + ajQx;
295a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      ImxQx[k3] = bkQx - ajQx;
296a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
297a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      kk = k4 + 4;
298a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    }
299a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    // Complexity: 12*(64+40+10) = 1368 for 16x16 muls, but 12*(112+88+10) = 2520 cycles for 16x32 muls
300a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    kk -= 239;
301a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
302a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  // Complexity: 4*1368 = 5472 for 16x16 muls, but 4*2520 = 10080 cycles for 16x32 muls
303a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
304a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* multiply by rotation factor for odd factor 3 or 5 (not for 4)
305a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin     Same code (duplicated) for both ii=2 and ii=3 */
306a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  kk = 1;
307a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  ee=0;
308a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
309a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  for (gg=0; gg<3; gg++) {
310a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    kk += 4;
311a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    dd = 12 + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16(12, gg);
312a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    ff = 0;
313a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    for (hh=0; hh<4; hh++) {
314a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      ff = ff+dd;
315a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      ee = ff+60;
316a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      for (ii=0; ii<12; ii++) {
317a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        akQx = RexQx[kk];
318a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        bkQx = ImxQx[kk];
319a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
320a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        ccc2Q14 = kCosTabFfftQ14[ff];
321a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        sss2Q14 = kCosTabFfftQ14[ee];
322a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
323a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        if (iSign==1) {
324a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin          sss2Q14 = -sss2Q14;
325a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        }
326a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
327a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        RexQx[kk] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, akQx, 14) -
328a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin            (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, bkQx, 14);
329a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        ImxQx[kk] = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(sss2Q14, akQx, 14) +
330a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin            (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(ccc2Q14, bkQx, 14);
331a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
332a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin        kk += 20;
333a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      }
334a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      kk = kk - 236;
335a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      // Complexity: 12*(12+12) = 288 for 16x16 muls, but 12*(12+32) = 528 cycles for 16x32 muls
336a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    }
337a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    kk = kk - 19;
338a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    // Complexity: 4*288+6 for 16x16 muls, but 4*528+6 cycles for 16x32 muls
339a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
340a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  // Complexity: 3*4*288+6 = 3462 for 16x16 muls, but 3*4*528+6 = 6342 cycles for 16x32 muls
341a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
342a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
343a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  // last transform for factor of 4 */
344a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  for (kk=0; kk<240; kk=kk+4) {
345a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    k1 = kk + 1;
346a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    k2 = k1 + 1;
347a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    k3 = k2 + 1;
348a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
349a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    akpQx = RexQx[kk] + RexQx[k2];
350a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    akmQx = RexQx[kk] - RexQx[k2];
351a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    ajpQx = RexQx[k1] + RexQx[k3];
352a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    ajmQx = RexQx[k1] - RexQx[k3];
353a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bkpQx = ImxQx[kk] + ImxQx[k2];
354a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bkmQx = ImxQx[kk] - ImxQx[k2];
355a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bjpQx = ImxQx[k1] + ImxQx[k3];
356a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bjmQx = ImxQx[k1] - ImxQx[k3];
357a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    RexQx[kk] = akpQx + ajpQx;
358a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    ImxQx[kk] = bkpQx + bjpQx;
359a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    ajpQx = akpQx - ajpQx;
360a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    bjpQx = bkpQx - bjpQx;
361a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    if (iSign < 0) {
362a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      akpQx = akmQx + bjmQx;
363a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      bkpQx = bkmQx - ajmQx;
364a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      akmQx -= bjmQx;
365a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      bkmQx += ajmQx;
366a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    } else {
367a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      akpQx = akmQx - bjmQx;
368a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      bkpQx = bkmQx + ajmQx;
369a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      akmQx += bjmQx;
370a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      bkmQx -= ajmQx;
371a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    }
372a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    RexQx[k1] = akpQx;
373a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    RexQx[k2] = ajpQx;
374a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    RexQx[k3] = akmQx;
375a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    ImxQx[k1] = bkpQx;
376a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    ImxQx[k2] = bjpQx;
377a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    ImxQx[k3] = bkmQx;
378a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
379a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  // Complexity: 60*45 = 2700 for 16x16 muls, but 60*45 = 2700 cycles for 16x32 muls
380a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
381a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* permute the results to normal order */
382a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  for (ii=0; ii<240; ii++) {
383a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    ReDATAQx[ii]=RexQx[ii];
384a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    ImDATAQx[ii]=ImxQx[ii];
385a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
386a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  // Complexity: 240*2=480 cycles
387a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
388a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  for (ii=0; ii<240; ii++) {
389a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    RexQx[ii]=ReDATAQx[kSortTabFft[ii]];
390a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    ImxQx[ii]=ImDATAQx[kSortTabFft[ii]];
391a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
392a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  // Complexity: 240*2*2=960 cycles
393a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
394a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  // Total complexity:
395a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  //            16x16 16x32
396a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  // Complexity:   10    10
397a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  // Complexity:   99   171
398a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  // Complexity: 2972  3932
399a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  // Complexity: 2736  5776
400a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  // Complexity: 5472 10080
401a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  // Complexity: 3462  6342
402a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  // Complexity: 2700  2700
403a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  // Complexity:  480   480
404a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  // Complexity:  960   960
405a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  // =======================
406a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  //            18891 30451
407a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  //
408a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  // If this FFT is called 2 time each frame, i.e. 67 times per second, it will correspond to
409a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  // a C54 complexity of 67*18891/1000000 = 1.27 MIPS with 16x16-muls, and 67*30451/1000000 =
410a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  // = 2.04 MIPS with 16x32-muls. Note that this routine somtimes is called 6 times during the
411a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  // encoding of a frame, i.e. the max complexity would be 7/2*1.27 = 4.4 MIPS for the 16x16 mul case.
412a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
413a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
414a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  return 0;
415a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin}
416