xref: /aosp_15_r20/external/libxaac/encoder/iusace_tcx_mdct.c (revision 15dc779a375ca8b5125643b829a8aa4b70d7f451)
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