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 * WebRtcIsacfix_kTransform.c
13a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *
14a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * Transform functions
15a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin *
16a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin */
17a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
18a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin#include "fft.h"
19a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin#include "codec.h"
20a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin#include "settings.h"
21a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
22a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
23a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/* Cosine table 1 in Q14 */
24a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinstatic const WebRtc_Word16 kCosTab1[FRAMESAMPLES/2] = {
25a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  16384,  16383,  16378,  16371,  16362,  16349,  16333,  16315,  16294,  16270,
26a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  16244,  16214,  16182,  16147,  16110,  16069,  16026,  15980,  15931,  15880,
27a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  15826,  15769,  15709,  15647,  15582,  15515,  15444,  15371,  15296,  15218,
28a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  15137,  15053,  14968,  14879,  14788,  14694,  14598,  14500,  14399,  14295,
29a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  14189,  14081,  13970,  13856,  13741,  13623,  13502,  13380,  13255,  13128,
30a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  12998,  12867,  12733,  12597,  12458,  12318,  12176,  12031,  11885,  11736,
31a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  11585,  11433,  11278,  11121,  10963,  10803,  10641,  10477,  10311,  10143,
32a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  9974,   9803,   9630,   9456,   9280,   9102,   8923,   8743,   8561,   8377,
33a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  8192,   8006,   7818,   7629,   7438,   7246,   7053,   6859,   6664,   6467,
34a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  6270,   6071,   5872,   5671,   5469,   5266,   5063,   4859,   4653,   4447,
35a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  4240,   4033,   3825,   3616,   3406,   3196,   2986,   2775,   2563,   2351,
36a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  2139,   1926,   1713,   1499,   1285,   1072,    857,    643,    429,    214,
37a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  0,   -214,   -429,   -643,   -857,  -1072,  -1285,  -1499,  -1713,  -1926,
38a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  -2139,  -2351,  -2563,  -2775,  -2986,  -3196,  -3406,  -3616,  -3825,  -4033,
39a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  -4240,  -4447,  -4653,  -4859,  -5063,  -5266,  -5469,  -5671,  -5872,  -6071,
40a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  -6270,  -6467,  -6664,  -6859,  -7053,  -7246,  -7438,  -7629,  -7818,  -8006,
41a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  -8192,  -8377,  -8561,  -8743,  -8923,  -9102,  -9280,  -9456,  -9630,  -9803,
42a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  -9974, -10143, -10311, -10477, -10641, -10803, -10963, -11121, -11278, -11433,
43a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  -11585, -11736, -11885, -12031, -12176, -12318, -12458, -12597, -12733, -12867,
44a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  -12998, -13128, -13255, -13380, -13502, -13623, -13741, -13856, -13970, -14081,
45a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  -14189, -14295, -14399, -14500, -14598, -14694, -14788, -14879, -14968, -15053,
46a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  -15137, -15218, -15296, -15371, -15444, -15515, -15582, -15647, -15709, -15769,
47a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  -15826, -15880, -15931, -15980, -16026, -16069, -16110, -16147, -16182, -16214,
48a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  -16244, -16270, -16294, -16315, -16333, -16349, -16362, -16371, -16378, -16383
49a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin};
50a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
51a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
52a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/* Sine table 1 in Q14 */
53a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinstatic const WebRtc_Word16 kSinTab1[FRAMESAMPLES/2] = {
54a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  0,   214,   429,   643,   857,  1072,  1285,  1499,  1713,  1926,
55a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  2139,  2351,  2563,  2775,  2986,  3196,  3406,  3616,  3825,  4033,
56a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  4240,  4447,  4653,  4859,  5063,  5266,  5469,  5671,  5872,  6071,
57a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  6270,  6467,  6664,  6859,  7053,  7246,  7438,  7629,  7818,  8006,
58a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  8192,  8377,  8561,  8743,  8923,  9102,  9280,  9456,  9630,  9803,
59a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  9974, 10143, 10311, 10477, 10641, 10803, 10963, 11121, 11278, 11433,
60a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  11585, 11736, 11885, 12031, 12176, 12318, 12458, 12597, 12733, 12867,
61a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  12998, 13128, 13255, 13380, 13502, 13623, 13741, 13856, 13970, 14081,
62a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  14189, 14295, 14399, 14500, 14598, 14694, 14788, 14879, 14968, 15053,
63a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  15137, 15218, 15296, 15371, 15444, 15515, 15582, 15647, 15709, 15769,
64a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  15826, 15880, 15931, 15980, 16026, 16069, 16110, 16147, 16182, 16214,
65a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  16244, 16270, 16294, 16315, 16333, 16349, 16362, 16371, 16378, 16383,
66a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  16384, 16383, 16378, 16371, 16362, 16349, 16333, 16315, 16294, 16270,
67a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  16244, 16214, 16182, 16147, 16110, 16069, 16026, 15980, 15931, 15880,
68a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  15826, 15769, 15709, 15647, 15582, 15515, 15444, 15371, 15296, 15218,
69a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  15137, 15053, 14968, 14879, 14788, 14694, 14598, 14500, 14399, 14295,
70a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  14189, 14081, 13970, 13856, 13741, 13623, 13502, 13380, 13255, 13128,
71a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  12998, 12867, 12733, 12597, 12458, 12318, 12176, 12031, 11885, 11736,
72a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  11585, 11433, 11278, 11121, 10963, 10803, 10641, 10477, 10311, 10143,
73a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  9974,  9803,  9630,  9456,  9280,  9102,  8923,  8743,  8561,  8377,
74a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  8192,  8006,  7818,  7629,  7438,  7246,  7053,  6859,  6664,  6467,
75a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  6270,  6071,  5872,  5671,  5469,  5266,  5063,  4859,  4653,  4447,
76a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  4240,  4033,  3825,  3616,  3406,  3196,  2986,  2775,  2563,  2351,
77a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  2139,  1926,  1713,  1499,  1285,  1072,   857,   643,   429,   214
78a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin};
79a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
80a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
81a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/* Cosine table 2 in Q14 */
82a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinstatic const WebRtc_Word16 kCosTab2[FRAMESAMPLES/4] = {
83a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  107,   -322,   536,   -750,   965,  -1179,  1392,  -1606,  1819,  -2032,
84a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  2245,  -2457,  2669,  -2880,  3091,  -3301,  3511,  -3720,  3929,  -4137,
85a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  4344,  -4550,  4756,  -4961,  5165,  -5368,  5570,  -5771,  5971,  -6171,
86a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  6369,  -6566,  6762,  -6957,  7150,  -7342,  7534,  -7723,  7912,  -8099,
87a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  8285,  -8469,  8652,  -8833,  9013,  -9191,  9368,  -9543,  9717,  -9889,
88a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  10059, -10227, 10394, -10559, 10722, -10883, 11042, -11200, 11356, -11509,
89a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  11661, -11810, 11958, -12104, 12247, -12389, 12528, -12665, 12800, -12933,
90a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  13063, -13192, 13318, -13441, 13563, -13682, 13799, -13913, 14025, -14135,
91a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  14242, -14347, 14449, -14549, 14647, -14741, 14834, -14924, 15011, -15095,
92a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  15178, -15257, 15334, -15408, 15480, -15549, 15615, -15679, 15739, -15798,
93a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  15853, -15906, 15956, -16003, 16048, -16090, 16129, -16165, 16199, -16229,
94a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  16257, -16283, 16305, -16325, 16342, -16356, 16367, -16375, 16381, -16384
95a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin};
96a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
97a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
98a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/* Sine table 2 in Q14 */
99a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinstatic const WebRtc_Word16 kSinTab2[FRAMESAMPLES/4] = {
100a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  16384, -16381, 16375, -16367, 16356, -16342, 16325, -16305, 16283, -16257,
101a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  16229, -16199, 16165, -16129, 16090, -16048, 16003, -15956, 15906, -15853,
102a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  15798, -15739, 15679, -15615, 15549, -15480, 15408, -15334, 15257, -15178,
103a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  15095, -15011, 14924, -14834, 14741, -14647, 14549, -14449, 14347, -14242,
104a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  14135, -14025, 13913, -13799, 13682, -13563, 13441, -13318, 13192, -13063,
105a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  12933, -12800, 12665, -12528, 12389, -12247, 12104, -11958, 11810, -11661,
106a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  11509, -11356, 11200, -11042, 10883, -10722, 10559, -10394, 10227, -10059,
107a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  9889,  -9717,  9543,  -9368,  9191,  -9013,  8833,  -8652,  8469,  -8285,
108a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  8099,  -7912,  7723,  -7534,  7342,  -7150,  6957,  -6762,  6566,  -6369,
109a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  6171,  -5971,  5771,  -5570,  5368,  -5165,  4961,  -4756,  4550,  -4344,
110a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  4137,  -3929,  3720,  -3511,  3301,  -3091,  2880,  -2669,  2457,  -2245,
111a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  2032,  -1819,  1606,  -1392,  1179,   -965,   750,   -536,   322,   -107
112a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin};
113a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
114a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
115a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
116a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinvoid WebRtcIsacfix_Time2Spec(WebRtc_Word16 *inre1Q9,
117a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                             WebRtc_Word16 *inre2Q9,
118a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                             WebRtc_Word16 *outreQ7,
119a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin                             WebRtc_Word16 *outimQ7)
120a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin{
121a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
122a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  int k;
123a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word32 tmpreQ16[FRAMESAMPLES/2], tmpimQ16[FRAMESAMPLES/2];
124a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word16 tmp1rQ14, tmp1iQ14;
125a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word32 xrQ16, xiQ16, yrQ16, yiQ16;
126a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word32 v1Q16, v2Q16;
127a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word16 factQ19, sh;
128a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
129a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* Multiply with complex exponentials and combine into one complex vector */
130a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  factQ19 = 16921; // 0.5/sqrt(240) in Q19 is round(.5/sqrt(240)*(2^19)) = 16921
131a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  for (k = 0; k < FRAMESAMPLES/2; k++) {
132a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    tmp1rQ14 = kCosTab1[k];
133a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    tmp1iQ14 = kSinTab1[k];
134a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    xrQ16 = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(tmp1rQ14, inre1Q9[k]) + WEBRTC_SPL_MUL_16_16(tmp1iQ14, inre2Q9[k]), 7);
135a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    xiQ16 = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_16(tmp1rQ14, inre2Q9[k]) - WEBRTC_SPL_MUL_16_16(tmp1iQ14, inre1Q9[k]), 7);
136a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    tmpreQ16[k] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(factQ19, xrQ16)+4, 3); // (Q16*Q19>>16)>>3 = Q16
137a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    tmpimQ16[k] = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL_16_32_RSFT16(factQ19, xiQ16)+4, 3); // (Q16*Q19>>16)>>3 = Q16
138a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
139a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
140a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
141a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  xrQ16  = WebRtcSpl_MaxAbsValueW32(tmpreQ16, FRAMESAMPLES/2);
142a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  yrQ16 = WebRtcSpl_MaxAbsValueW32(tmpimQ16, FRAMESAMPLES/2);
143a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  if (yrQ16>xrQ16) {
144a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    xrQ16 = yrQ16;
145a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
146a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
147a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  sh = WebRtcSpl_NormW32(xrQ16);
148a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  sh = sh-24; //if sh becomes >=0, then we should shift sh steps to the left, and the domain will become Q(16+sh)
149a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  //if sh becomes <0, then we should shift -sh steps to the right, and the domain will become Q(16+sh)
150a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
151a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  //"Fastest" vectors
152a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  if (sh>=0) {
153a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    for (k=0; k<FRAMESAMPLES/2; k++) {
154a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      inre1Q9[k] = (WebRtc_Word16) WEBRTC_SPL_LSHIFT_W32(tmpreQ16[k], sh); //Q(16+sh)
155a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      inre2Q9[k] = (WebRtc_Word16) WEBRTC_SPL_LSHIFT_W32(tmpimQ16[k], sh); //Q(16+sh)
156a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    }
157a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  } else {
158a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    WebRtc_Word32 round = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)1, -sh-1);
159a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    for (k=0; k<FRAMESAMPLES/2; k++) {
160a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      inre1Q9[k] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmpreQ16[k]+round, -sh); //Q(16+sh)
161a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      inre2Q9[k] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(tmpimQ16[k]+round, -sh); //Q(16+sh)
162a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    }
163a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
164a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
165a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* Get DFT */
166a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtcIsacfix_FftRadix16Fastest(inre1Q9, inre2Q9, -1); // real call
167a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
168a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  //"Fastest" vectors
169a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  if (sh>=0) {
170a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    for (k=0; k<FRAMESAMPLES/2; k++) {
171a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      tmpreQ16[k] = WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32)inre1Q9[k], sh); //Q(16+sh) -> Q16
172a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      tmpimQ16[k] = WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32)inre2Q9[k], sh); //Q(16+sh) -> Q16
173a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    }
174a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  } else {
175a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    for (k=0; k<FRAMESAMPLES/2; k++) {
176a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      tmpreQ16[k] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)inre1Q9[k], -sh); //Q(16+sh) -> Q16
177a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      tmpimQ16[k] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)inre2Q9[k], -sh); //Q(16+sh) -> Q16
178a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    }
179a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
180a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
181a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
182a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* Use symmetry to separate into two complex vectors and center frames in time around zero */
183a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  for (k = 0; k < FRAMESAMPLES/4; k++) {
184a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    xrQ16 = tmpreQ16[k] + tmpreQ16[FRAMESAMPLES/2 - 1 - k];
185a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    yiQ16 = -tmpreQ16[k] + tmpreQ16[FRAMESAMPLES/2 - 1 - k];
186a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    xiQ16 = tmpimQ16[k] - tmpimQ16[FRAMESAMPLES/2 - 1 - k];
187a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    yrQ16 = tmpimQ16[k] + tmpimQ16[FRAMESAMPLES/2 - 1 - k];
188a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    tmp1rQ14 = kCosTab2[k];
189a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    tmp1iQ14 = kSinTab2[k];
190a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    v1Q16 = WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, xrQ16) - WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, xiQ16);
191a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    v2Q16 = WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, xrQ16) + WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, xiQ16);
192a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    outreQ7[k] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(v1Q16, 9);
193a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    outimQ7[k] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(v2Q16, 9);
194a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    v1Q16 = -WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, yrQ16) - WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, yiQ16);
195a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    v2Q16 = -WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, yrQ16) + WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, yiQ16);
196a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    outreQ7[FRAMESAMPLES/2 - 1 - k] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(v1Q16, 9); //CalcLrIntQ(v1Q16, 9);
197a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    outimQ7[FRAMESAMPLES/2 - 1 - k] = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(v2Q16, 9); //CalcLrIntQ(v2Q16, 9);
198a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
199a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
200a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin}
201a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
202a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
203a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinvoid WebRtcIsacfix_Spec2Time(WebRtc_Word16 *inreQ7, WebRtc_Word16 *inimQ7, WebRtc_Word32 *outre1Q16, WebRtc_Word32 *outre2Q16)
204a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin{
205a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
206a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  int k;
207a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word16 tmp1rQ14, tmp1iQ14;
208a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word32 xrQ16, xiQ16, yrQ16, yiQ16;
209a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word32 tmpInRe, tmpInIm, tmpInRe2, tmpInIm2;
210a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word16 factQ11;
211a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtc_Word16 sh;
212a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
213a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  for (k = 0; k < FRAMESAMPLES/4; k++) {
214a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    /* Move zero in time to beginning of frames */
215a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    tmp1rQ14 = kCosTab2[k];
216a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    tmp1iQ14 = kSinTab2[k];
217a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
218a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    tmpInRe = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32) inreQ7[k], 9);  // Q7 -> Q16
219a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    tmpInIm = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32) inimQ7[k], 9);  // Q7 -> Q16
220a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    tmpInRe2 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32) inreQ7[FRAMESAMPLES/2 - 1 - k], 9);  // Q7 -> Q16
221a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    tmpInIm2 = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32) inimQ7[FRAMESAMPLES/2 - 1 - k], 9);  // Q7 -> Q16
222a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
223a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    xrQ16 = WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, tmpInRe) + WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, tmpInIm);
224a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    xiQ16 = WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, tmpInIm) - WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, tmpInRe);
225a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    yrQ16 = -WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, tmpInIm2) - WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, tmpInRe2);
226a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    yiQ16 = -WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, tmpInRe2) + WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, tmpInIm2);
227a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
228a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    /* Combine into one vector,  z = x + j * y */
229a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    outre1Q16[k] = xrQ16 - yiQ16;
230a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    outre1Q16[FRAMESAMPLES/2 - 1 - k] = xrQ16 + yiQ16;
231a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    outre2Q16[k] = xiQ16 + yrQ16;
232a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    outre2Q16[FRAMESAMPLES/2 - 1 - k] = -xiQ16 + yrQ16;
233a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
234a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
235a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* Get IDFT */
236a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  tmpInRe  = WebRtcSpl_MaxAbsValueW32(outre1Q16, 240);
237a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  tmpInIm = WebRtcSpl_MaxAbsValueW32(outre2Q16, 240);
238a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  if (tmpInIm>tmpInRe) {
239a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    tmpInRe = tmpInIm;
240a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
241a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
242a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  sh = WebRtcSpl_NormW32(tmpInRe);
243a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  sh = sh-24; //if sh becomes >=0, then we should shift sh steps to the left, and the domain will become Q(16+sh)
244a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  //if sh becomes <0, then we should shift -sh steps to the right, and the domain will become Q(16+sh)
245a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
246a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  //"Fastest" vectors
247a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  if (sh>=0) {
248a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    for (k=0; k<240; k++) {
249a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      inreQ7[k] = (WebRtc_Word16) WEBRTC_SPL_LSHIFT_W32(outre1Q16[k], sh); //Q(16+sh)
250a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      inimQ7[k] = (WebRtc_Word16) WEBRTC_SPL_LSHIFT_W32(outre2Q16[k], sh); //Q(16+sh)
251a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    }
252a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  } else {
253a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    WebRtc_Word32 round = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)1, -sh-1);
254a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    for (k=0; k<240; k++) {
255a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      inreQ7[k] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(outre1Q16[k]+round, -sh); //Q(16+sh)
256a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      inimQ7[k] = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(outre2Q16[k]+round, -sh); //Q(16+sh)
257a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    }
258a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
259a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
260a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  WebRtcIsacfix_FftRadix16Fastest(inreQ7, inimQ7, 1); // real call
261a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
262a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  //"Fastest" vectors
263a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  if (sh>=0) {
264a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    for (k=0; k<240; k++) {
265a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      outre1Q16[k] = WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32)inreQ7[k], sh); //Q(16+sh) -> Q16
266a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      outre2Q16[k] = WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32)inimQ7[k], sh); //Q(16+sh) -> Q16
267a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    }
268a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  } else {
269a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    for (k=0; k<240; k++) {
270a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      outre1Q16[k] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)inreQ7[k], -sh); //Q(16+sh) -> Q16
271a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin      outre2Q16[k] = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)inimQ7[k], -sh); //Q(16+sh) -> Q16
272a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    }
273a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
274a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
275a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* Divide through by the normalizing constant: */
276a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* scale all values with 1/240, i.e. with 273 in Q16 */
277a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* 273/65536 ~= 0.0041656                            */
278a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /*     1/240 ~= 0.0041666                            */
279a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  for (k=0; k<240; k++) {
280a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    outre1Q16[k] = WEBRTC_SPL_MUL_16_32_RSFT16(273, outre1Q16[k]);
281a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    outre2Q16[k] = WEBRTC_SPL_MUL_16_32_RSFT16(273, outre2Q16[k]);
282a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
283a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin
284a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  /* Demodulate and separate */
285a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  factQ11 = 31727; // sqrt(240) in Q11 is round(15.49193338482967*2048) = 31727
286a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  for (k = 0; k < FRAMESAMPLES/2; k++) {
287a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    tmp1rQ14 = kCosTab1[k];
288a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    tmp1iQ14 = kSinTab1[k];
289a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    xrQ16 = WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, outre1Q16[k]) - WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, outre2Q16[k]);
290a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    xiQ16 = WEBRTC_SPL_MUL_16_32_RSFT14(tmp1rQ14, outre2Q16[k]) + WEBRTC_SPL_MUL_16_32_RSFT14(tmp1iQ14, outre1Q16[k]);
291a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    xrQ16 = WEBRTC_SPL_MUL_16_32_RSFT11(factQ11, xrQ16);
292a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    xiQ16 = WEBRTC_SPL_MUL_16_32_RSFT11(factQ11, xiQ16);
293a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    outre2Q16[k] = xiQ16;
294a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin    outre1Q16[k] = xrQ16;
295a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin  }
296a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin}
297