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 <string.h>
22 #include "iusace_type_def.h"
23
24 #include "ixheaace_mps_common_define.h"
25 #include "iusace_cnst.h"
26 #include "iusace_bitbuffer.h"
27 #include "impd_drc_common_enc.h"
28 #include "impd_drc_uni_drc.h"
29 #include "impd_drc_api.h"
30 #include "impd_drc_uni_drc_eq.h"
31 #include "impd_drc_uni_drc_filter_bank.h"
32 #include "impd_drc_gain_enc.h"
33 #include "impd_drc_struct_def.h"
34
35 #include "iusace_cnst.h"
36 #include "iusace_tns_usac.h"
37 #include "iusace_psy_mod.h"
38 #include "iusace_ms.h"
39
40 #include "ixheaace_adjust_threshold_data.h"
41 #include "iusace_fd_qc_util.h"
42 #include "ixheaace_memory_standards.h"
43 #include "iusace_config.h"
44 #include "iusace_fft.h"
45 #include "iusace_arith_enc.h"
46 #include "iusace_fd_quant.h"
47 #include "iusace_signal_classifier.h"
48 #include "iusace_block_switch_const.h"
49 #include "iusace_block_switch_struct_def.h"
50 #include "ixheaace_sbr_header.h"
51 #include "ixheaace_config.h"
52 #include "ixheaace_asc_write.h"
53 #include "iusace_main.h"
54 #include "iusace_windowing.h"
55 #include "ixheaac_error_standards.h"
56
iusace_fd_mdct_short(ia_usac_data_struct * pstr_usac_data,ia_usac_encoder_config_struct * pstr_usac_config,WORD32 ch_idx)57 static IA_ERRORCODE iusace_fd_mdct_short(ia_usac_data_struct *pstr_usac_data,
58 ia_usac_encoder_config_struct *pstr_usac_config,
59 WORD32 ch_idx) {
60 IA_ERRORCODE err_code = 0;
61 iusace_scratch_mem *pstr_scratch = &pstr_usac_data->str_scratch;
62 IA_ERRORCODE err_code_2 = 0;
63 FLOAT64 *ptr_windowed_buf = pstr_scratch->p_fd_mdct_windowed_short_buf;
64 WORD32 n_long = pstr_usac_config->ccfl;
65 WORD32 n_short = pstr_usac_config->ccfl >> 3;
66 FLOAT64 *ptr_in_data = pstr_usac_data->ptr_time_data[ch_idx];
67 FLOAT64 *ptr_out_mdct = pstr_usac_data->spectral_line_vector[ch_idx];
68 FLOAT64 *ptr_out_mdst = pstr_usac_data->mdst_spectrum[ch_idx];
69 WORD32 window_shape = pstr_usac_config->window_shape_prev[ch_idx];
70 FLOAT64 *ptr_win_gen_medium = NULL, *ptr_win_gen_short = NULL;
71 FLOAT64 *ptr_overlap = pstr_usac_data->overlap_buf[ch_idx];
72 WORD32 nflat_ls;
73 WORD32 i, k;
74 WORD32 data_size = (OVERLAP_WIN_SIZE_576 * n_long) / LEN_SUPERFRAME;
75
76 memset(ptr_windowed_buf, 0, 2 * n_short * sizeof(FLOAT64));
77 nflat_ls = (n_long - n_short) >> 1;
78 err_code = iusace_calc_window(&ptr_win_gen_short, n_short, window_shape);
79 if (err_code) return err_code;
80 err_code = iusace_calc_window(&ptr_win_gen_medium, n_short, 0);
81 if (err_code) return err_code;
82 ptr_overlap += nflat_ls;
83
84 for (k = MAX_SHORT_WINDOWS - 1; k-- >= 0;) {
85 for (i = 0; i < n_short; i++) {
86 ptr_windowed_buf[i] = ptr_win_gen_short[i] * ptr_overlap[i];
87 }
88 for (i = 0; i < n_short; i++) {
89 ptr_windowed_buf[i + n_short] =
90 ptr_win_gen_medium[n_short - 1 - i] * ptr_overlap[i + n_short];
91 }
92
93 ptr_win_gen_medium = ptr_win_gen_short;
94
95 // Compute MDCT
96 err_code = iusace_fft_based_mdct(ptr_windowed_buf, ptr_out_mdct, n_short, MDCT_TX_FLAG,
97 pstr_scratch);
98
99 if (err_code) {
100 return err_code;
101 }
102
103 // Compute MDST
104 err_code_2 = iusace_fft_based_mdct(ptr_windowed_buf, ptr_out_mdst, n_short, MDST_TX_FLAG,
105 pstr_scratch);
106
107 if (err_code_2) {
108 return err_code_2;
109 }
110
111 ptr_out_mdct += n_short;
112 ptr_out_mdst += n_short;
113 ptr_overlap += n_short;
114 }
115
116 ptr_overlap = pstr_usac_data->overlap_buf[ch_idx];
117 memcpy(ptr_overlap, ptr_overlap + n_long, data_size * sizeof(*ptr_overlap));
118 memcpy(ptr_overlap + data_size, ptr_in_data, n_long * sizeof(*ptr_overlap));
119
120 return err_code;
121 }
122
iusace_fd_mdct_long(ia_usac_data_struct * pstr_usac_data,ia_usac_encoder_config_struct * pstr_usac_config,WORD32 ch_idx,WORD32 window_sequence)123 static IA_ERRORCODE iusace_fd_mdct_long(ia_usac_data_struct *pstr_usac_data,
124 ia_usac_encoder_config_struct *pstr_usac_config,
125 WORD32 ch_idx, WORD32 window_sequence) {
126 IA_ERRORCODE err_code = 0;
127 iusace_scratch_mem *pstr_scratch = &pstr_usac_data->str_scratch;
128 IA_ERRORCODE err_code_2 = 0;
129 FLOAT64 *ptr_windowed_buf = pstr_scratch->p_fd_mdct_windowed_long_buf;
130 WORD32 n_long = pstr_usac_config->ccfl;
131 WORD32 n_short = pstr_usac_config->ccfl >> 3;
132 WORD32 prev_mode = (pstr_usac_data->core_mode_prev[ch_idx] == CORE_MODE_TD);
133 WORD32 next_mode = (pstr_usac_data->core_mode_next[ch_idx] == CORE_MODE_TD);
134 FLOAT64 *ptr_in_data = pstr_usac_data->ptr_time_data[ch_idx];
135 FLOAT64 *ptr_out_mdct = pstr_usac_data->spectral_line_vector[ch_idx];
136 FLOAT64 *ptr_out_mdst = pstr_usac_data->mdst_spectrum[ch_idx];
137 WORD32 window_shape = pstr_usac_config->window_shape_prev[ch_idx];
138 FLOAT64 *ptr_win_long = NULL, *ptr_win_med = NULL;
139 WORD32 win_len;
140 FLOAT64 *ptr_overlap = pstr_usac_data->overlap_buf[ch_idx];
141
142 WORD32 nflat_ls;
143
144 memset(ptr_windowed_buf, 0, 2 * n_long * sizeof(*ptr_windowed_buf));
145
146 switch (window_sequence) {
147 case ONLY_LONG_SEQUENCE:
148 err_code = iusace_calc_window(&ptr_win_long, n_long, window_shape);
149 if (err_code) return err_code;
150 iusace_windowing_long(ptr_overlap, ptr_win_long, ptr_windowed_buf, ptr_in_data, n_long);
151 break;
152
153 case LONG_START_SEQUENCE:
154 win_len = n_short << next_mode;
155 nflat_ls = (n_long - win_len) >> 1;
156 err_code = iusace_calc_window(&ptr_win_long, n_long, window_shape);
157 if (err_code) return err_code;
158 err_code = iusace_calc_window(&ptr_win_med, win_len, 0);
159 if (err_code) return err_code;
160
161 iusace_windowing_long_start(ptr_overlap, ptr_win_long, ptr_windowed_buf, ptr_in_data,
162 n_long, nflat_ls, ptr_win_med, win_len);
163 break;
164
165 case LONG_STOP_SEQUENCE:
166 win_len = n_short << prev_mode;
167 nflat_ls = (n_long - win_len) >> 1;
168 err_code = iusace_calc_window(&ptr_win_long, n_long, window_shape);
169 if (err_code) return err_code;
170 err_code = iusace_calc_window(&ptr_win_med, win_len, 1);
171 if (err_code) return err_code;
172 iusace_windowing_long_stop(ptr_overlap, ptr_win_long, ptr_windowed_buf, ptr_in_data, n_long,
173 nflat_ls, ptr_win_med, win_len);
174 break;
175
176 case STOP_START_SEQUENCE:
177 win_len = n_short << (prev_mode | next_mode);
178 err_code = iusace_calc_window(&ptr_win_med, win_len, window_shape);
179 if (err_code) return err_code;
180
181 iusace_windowing_stop_start(ptr_overlap, ptr_windowed_buf, ptr_win_med, win_len, n_long);
182 break;
183 }
184
185 // Compute MDCT
186 err_code =
187 iusace_fft_based_mdct(ptr_windowed_buf, ptr_out_mdct, n_long, MDCT_TX_FLAG, pstr_scratch);
188 if (err_code) {
189 return err_code;
190 }
191
192 // Compute MDST
193 err_code_2 =
194 iusace_fft_based_mdct(ptr_windowed_buf, ptr_out_mdst, n_long, MDST_TX_FLAG, pstr_scratch);
195
196 if (err_code_2) {
197 return err_code_2;
198 }
199
200 return IA_NO_ERROR;
201 }
202
iusace_fd_mdct(ia_usac_data_struct * pstr_usac_data,ia_usac_encoder_config_struct * pstr_usac_config,WORD32 ch_idx)203 WORD32 iusace_fd_mdct(ia_usac_data_struct *pstr_usac_data,
204 ia_usac_encoder_config_struct *pstr_usac_config, WORD32 ch_idx) {
205 IA_ERRORCODE err_code = 0;
206 WORD32 window_sequence = pstr_usac_config->window_sequence[ch_idx];
207
208 if (window_sequence != EIGHT_SHORT_SEQUENCE) {
209 err_code = iusace_fd_mdct_long(pstr_usac_data, pstr_usac_config, ch_idx, window_sequence);
210 } else {
211 err_code = iusace_fd_mdct_short(pstr_usac_data, pstr_usac_config, ch_idx);
212 }
213
214 return err_code;
215 }
216