1 /******************************************************************************
2 * *
3 * Copyright (C) 2023 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *****************************************************************************
18 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20
21 #include "ixheaac_type_def.h"
22 #include "iusace_block_switch_const.h"
23 #include "iusace_cnst.h"
24 #include "iusace_rom.h"
25 #include "iusace_bitbuffer.h"
26
27 /* DRC */
28 #include "impd_drc_common_enc.h"
29 #include "impd_drc_uni_drc.h"
30 #include "impd_drc_tables.h"
31 #include "impd_drc_api.h"
32 #include "impd_drc_uni_drc_eq.h"
33 #include "impd_drc_uni_drc_filter_bank.h"
34 #include "impd_drc_gain_enc.h"
35 #include "impd_drc_struct_def.h"
36
37 #include "iusace_tns_usac.h"
38 #include "iusace_psy_mod.h"
39 #include "iusace_tns_usac.h"
40 #include "iusace_config.h"
41 #include "iusace_fft.h"
42 #include "iusace_tcx_mdct.h"
43
iusace_tcx_mdct_main(FLOAT32 * ptr_in,FLOAT32 * ptr_out,WORD32 l,WORD32 m,WORD32 r,iusace_scratch_mem * pstr_scratch)44 VOID iusace_tcx_mdct_main(FLOAT32 *ptr_in, FLOAT32 *ptr_out, WORD32 l, WORD32 m, WORD32 r,
45 iusace_scratch_mem *pstr_scratch) {
46 WORD32 length = l / 2 + m + r / 2;
47 FLOAT32 *input = pstr_scratch->p_tcx_input;
48 WORD32 i;
49
50 for (i = 0; i < m / 2; i++) {
51 input[m / 2 + r / 2 + i] = -ptr_in[l + m / 2 - 1 - i];
52 }
53 for (i = 0; i < l / 2; i++) {
54 input[m / 2 + r / 2 + m / 2 + i] = ptr_in[i] - ptr_in[l - 1 - i];
55 }
56 for (i = 0; i < m / 2; i++) {
57 input[m / 2 + r / 2 - 1 - i] = -ptr_in[l + m / 2 + i];
58 }
59 for (i = 0; i < r / 2; i++) {
60 input[m / 2 + r / 2 - 1 - m / 2 - i] = -ptr_in[l + m + i] - ptr_in[l + m + r - 1 - i];
61 }
62
63 iusace_tcx_mdct(input, ptr_out, length, pstr_scratch);
64
65 return;
66 }
67
iusace_tcx_imdct(FLOAT32 * ptr_in,FLOAT32 * ptr_out,WORD32 l,WORD32 m,WORD32 r,iusace_scratch_mem * pstr_scratch)68 VOID iusace_tcx_imdct(FLOAT32 *ptr_in, FLOAT32 *ptr_out, WORD32 l, WORD32 m, WORD32 r,
69 iusace_scratch_mem *pstr_scratch) {
70 WORD32 length = l / 2 + m + r / 2;
71 FLOAT32 *output = pstr_scratch->p_tcx_output;
72 iusace_tcx_mdct(ptr_in, output, length, pstr_scratch);
73
74 WORD32 i;
75
76 for (i = 0; i < m / 2; i++) {
77 ptr_out[l + m / 2 - 1 - i] = -1.0f * output[m / 2 + r / 2 + i];
78 }
79 for (i = 0; i < l / 2; i++) {
80 ptr_out[i] = output[m / 2 + r / 2 + m / 2 + i];
81 ptr_out[l - 1 - i] = -1.0f * output[m / 2 + r / 2 + m / 2 + i];
82 }
83 for (i = 0; i < m / 2; i++) {
84 ptr_out[l + m / 2 + i] = -1.0f * output[m / 2 + r / 2 - 1 - i];
85 }
86 for (i = 0; i < r / 2; i++) {
87 ptr_out[l + m + i] = -1.0f * output[m / 2 + r / 2 - 1 - m / 2 - i];
88 ptr_out[l + m + r - 1 - i] = -1.0f * output[m / 2 + r / 2 - 1 - m / 2 - i];
89 }
90 return;
91 }
92
iusace_get_pre_post_twid(FLOAT32 ** ptr_pre_twid_re,FLOAT32 ** ptr_pre_twid_im,FLOAT32 ** ptr_post_twid_re,FLOAT32 ** ptr_post_twid_im,WORD32 length)93 static VOID iusace_get_pre_post_twid(FLOAT32 **ptr_pre_twid_re, FLOAT32 **ptr_pre_twid_im,
94 FLOAT32 **ptr_post_twid_re, FLOAT32 **ptr_post_twid_im,
95 WORD32 length) {
96 switch (length) {
97 case 512:
98 *ptr_pre_twid_re = (FLOAT32 *)&iusace_pre_post_twid_cos_sin_256[0][0];
99 *ptr_pre_twid_im = (FLOAT32 *)&iusace_pre_post_twid_cos_sin_256[1][0];
100 *ptr_post_twid_re = (FLOAT32 *)&iusace_pre_post_twid_cos_sin_256[2][0];
101 *ptr_post_twid_im = (FLOAT32 *)&iusace_pre_post_twid_cos_sin_256[3][0];
102 break;
103 case 256:
104 *ptr_pre_twid_re = (FLOAT32 *)&iusace_pre_post_twid_cos_sin_128[0][0];
105 *ptr_pre_twid_im = (FLOAT32 *)&iusace_pre_post_twid_cos_sin_128[1][0];
106 *ptr_post_twid_re = (FLOAT32 *)&iusace_pre_post_twid_cos_sin_128[2][0];
107 *ptr_post_twid_im = (FLOAT32 *)&iusace_pre_post_twid_cos_sin_128[3][0];
108 break;
109 case 128:
110 *ptr_pre_twid_re = (FLOAT32 *)&iusace_pre_post_twid_cos_sin_64[0][0];
111 *ptr_pre_twid_im = (FLOAT32 *)&iusace_pre_post_twid_cos_sin_64[1][0];
112 *ptr_post_twid_re = (FLOAT32 *)&iusace_pre_post_twid_cos_sin_64[2][0];
113 *ptr_post_twid_im = (FLOAT32 *)&iusace_pre_post_twid_cos_sin_64[3][0];
114 break;
115 case 64:
116 *ptr_pre_twid_re = (FLOAT32 *)&iusace_pre_post_twid_cos_sin_32[0][0];
117 *ptr_pre_twid_im = (FLOAT32 *)&iusace_pre_post_twid_cos_sin_32[1][0];
118 *ptr_post_twid_re = (FLOAT32 *)&iusace_pre_post_twid_cos_sin_32[2][0];
119 *ptr_post_twid_im = (FLOAT32 *)&iusace_pre_post_twid_cos_sin_32[3][0];
120 break;
121 default:
122 *ptr_pre_twid_re = (FLOAT32 *)&iusace_pre_post_twid_cos_sin_512[0][0];
123 *ptr_pre_twid_im = (FLOAT32 *)&iusace_pre_post_twid_cos_sin_512[1][0];
124 *ptr_post_twid_re = (FLOAT32 *)&iusace_pre_post_twid_cos_sin_512[2][0];
125 *ptr_post_twid_im = (FLOAT32 *)&iusace_pre_post_twid_cos_sin_512[3][0];
126 }
127
128 return;
129 }
130
iusace_pre_twid(FLOAT32 * ptr_twid_re,FLOAT32 * ptr_twid_im,FLOAT32 * ptr_in,WORD32 length)131 static VOID iusace_pre_twid(FLOAT32 *ptr_twid_re, FLOAT32 *ptr_twid_im, FLOAT32 *ptr_in,
132 WORD32 length) {
133 WORD32 i;
134 for (i = 0; i < length; i++) {
135 FLOAT32 temp = ptr_in[2 * i] * ptr_twid_re[i] - ptr_in[2 * i + 1] * ptr_twid_im[i];
136
137 ptr_in[2 * i + 1] = ptr_in[2 * i] * ptr_twid_im[i] + ptr_in[2 * i + 1] * ptr_twid_re[i];
138
139 ptr_in[2 * i] = temp;
140 }
141 return;
142 }
143
iusace_post_twid(FLOAT32 * ptr_twid_re,FLOAT32 * ptr_twid_im,FLOAT32 * ptr_in,WORD32 length)144 static VOID iusace_post_twid(FLOAT32 *ptr_twid_re, FLOAT32 *ptr_twid_im, FLOAT32 *ptr_in,
145 WORD32 length) {
146 WORD32 i;
147 for (i = 0; i < length; i++) {
148 FLOAT32 temp = ptr_in[2 * i] * ptr_twid_re[i] - ptr_in[2 * i + 1] * ptr_twid_im[i];
149
150 ptr_in[2 * i + 1] = -ptr_in[2 * i] * ptr_twid_im[i] - ptr_in[2 * i + 1] * ptr_twid_re[i];
151 ptr_in[2 * i] = temp;
152 }
153 return;
154 }
155
iusace_tcx_mdct(FLOAT32 * ptr_in,FLOAT32 * ptr_out,WORD32 length,iusace_scratch_mem * pstr_scratch)156 VOID iusace_tcx_mdct(FLOAT32 *ptr_in, FLOAT32 *ptr_out, WORD32 length,
157 iusace_scratch_mem *pstr_scratch) {
158 FLOAT32 *ptr_pre_twid_re, *ptr_pre_twid_im;
159 FLOAT32 *ptr_post_twid_re, *ptr_post_twid_im;
160 WORD32 i;
161 FLOAT32 *ptr_real = pstr_scratch->p_temp_mdct;
162 WORD32 len_by_2 = length >> 1;
163
164 iusace_get_pre_post_twid(&ptr_pre_twid_re, &ptr_pre_twid_im, &ptr_post_twid_re,
165 &ptr_post_twid_im, length);
166
167 for (i = 0; i < len_by_2; i++) {
168 ptr_real[2 * i] = ptr_in[2 * i];
169 ptr_real[2 * i + 1] = ptr_in[length - 1 - 2 * i];
170 }
171
172 /* pre twiddle */
173 iusace_pre_twid(ptr_pre_twid_re, ptr_pre_twid_im, ptr_real, len_by_2);
174
175 iusace_complex_fft(ptr_real, len_by_2, pstr_scratch);
176
177 /* post twiddle */
178 iusace_post_twid(ptr_post_twid_re, ptr_post_twid_im, ptr_real, len_by_2);
179
180 for (i = 0; i < len_by_2; i++) {
181 ptr_out[2 * i] = ptr_real[2 * i];
182 ptr_out[length - 1 - 2 * i] = ptr_real[2 * i + 1];
183 }
184
185 return;
186 }
187