/src/libxaac/encoder/ixheaace_fd_mdct.c
Line | Count | Source (jump to first uncovered line) |
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 | | |
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 | 165k | WORD32 ch_idx) { |
60 | 165k | IA_ERRORCODE err_code = 0; |
61 | 165k | iusace_scratch_mem *pstr_scratch = &pstr_usac_data->str_scratch; |
62 | 165k | IA_ERRORCODE err_code_2 = 0; |
63 | 165k | FLOAT64 *ptr_windowed_buf = pstr_scratch->p_fd_mdct_windowed_short_buf; |
64 | 165k | WORD32 n_long = pstr_usac_config->ccfl; |
65 | 165k | WORD32 n_short = pstr_usac_config->ccfl >> 3; |
66 | 165k | FLOAT64 *ptr_in_data = pstr_usac_data->ptr_time_data[ch_idx]; |
67 | 165k | FLOAT64 *ptr_out_mdct = pstr_usac_data->spectral_line_vector[ch_idx]; |
68 | 165k | FLOAT64 *ptr_out_mdst = pstr_usac_data->mdst_spectrum[ch_idx]; |
69 | 165k | WORD32 window_shape = pstr_usac_config->window_shape_prev[ch_idx]; |
70 | 165k | FLOAT64 *ptr_win_gen_medium = NULL, *ptr_win_gen_short = NULL; |
71 | 165k | FLOAT64 *ptr_overlap = pstr_usac_data->overlap_buf[ch_idx]; |
72 | 165k | WORD32 nflat_ls; |
73 | 165k | WORD32 i, k; |
74 | 165k | WORD32 data_size = (OVERLAP_WIN_SIZE_576 * n_long) / LEN_SUPERFRAME; |
75 | | |
76 | 165k | memset(ptr_windowed_buf, 0, 2 * n_short * sizeof(FLOAT64)); |
77 | 165k | nflat_ls = (n_long - n_short) >> 1; |
78 | 165k | err_code = iusace_calc_window(&ptr_win_gen_short, n_short, window_shape); |
79 | 165k | if (err_code) return err_code; |
80 | 165k | err_code = iusace_calc_window(&ptr_win_gen_medium, n_short, 0); |
81 | 165k | if (err_code) return err_code; |
82 | 165k | ptr_overlap += nflat_ls; |
83 | | |
84 | 1.48M | for (k = MAX_SHORT_WINDOWS - 1; k-- >= 0;) { |
85 | 149M | for (i = 0; i < n_short; i++) { |
86 | 148M | ptr_windowed_buf[i] = ptr_win_gen_short[i] * ptr_overlap[i]; |
87 | 148M | } |
88 | 149M | for (i = 0; i < n_short; i++) { |
89 | 148M | ptr_windowed_buf[i + n_short] = |
90 | 148M | ptr_win_gen_medium[n_short - 1 - i] * ptr_overlap[i + n_short]; |
91 | 148M | } |
92 | | |
93 | 1.32M | ptr_win_gen_medium = ptr_win_gen_short; |
94 | | |
95 | | // Compute MDCT |
96 | 1.32M | err_code = iusace_fft_based_mdct(ptr_windowed_buf, ptr_out_mdct, n_short, MDCT_TX_FLAG, |
97 | 1.32M | pstr_scratch); |
98 | | |
99 | 1.32M | if (err_code) { |
100 | 0 | return err_code; |
101 | 0 | } |
102 | | |
103 | | // Compute MDST |
104 | 1.32M | err_code_2 = iusace_fft_based_mdct(ptr_windowed_buf, ptr_out_mdst, n_short, MDST_TX_FLAG, |
105 | 1.32M | pstr_scratch); |
106 | | |
107 | 1.32M | if (err_code_2) { |
108 | 0 | return err_code_2; |
109 | 0 | } |
110 | | |
111 | 1.32M | ptr_out_mdct += n_short; |
112 | 1.32M | ptr_out_mdst += n_short; |
113 | 1.32M | ptr_overlap += n_short; |
114 | 1.32M | } |
115 | | |
116 | 165k | ptr_overlap = pstr_usac_data->overlap_buf[ch_idx]; |
117 | 165k | memcpy(ptr_overlap, ptr_overlap + n_long, data_size * sizeof(*ptr_overlap)); |
118 | 165k | memcpy(ptr_overlap + data_size, ptr_in_data, n_long * sizeof(*ptr_overlap)); |
119 | | |
120 | 165k | return err_code; |
121 | 165k | } |
122 | | |
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 | 330k | WORD32 ch_idx, WORD32 window_sequence) { |
126 | 330k | IA_ERRORCODE err_code = 0; |
127 | 330k | iusace_scratch_mem *pstr_scratch = &pstr_usac_data->str_scratch; |
128 | 330k | IA_ERRORCODE err_code_2 = 0; |
129 | 330k | FLOAT64 *ptr_windowed_buf = pstr_scratch->p_fd_mdct_windowed_long_buf; |
130 | 330k | WORD32 n_long = pstr_usac_config->ccfl; |
131 | 330k | WORD32 n_short = pstr_usac_config->ccfl >> 3; |
132 | 330k | WORD32 prev_mode = (pstr_usac_data->core_mode_prev[ch_idx] == CORE_MODE_TD); |
133 | 330k | WORD32 next_mode = (pstr_usac_data->core_mode_next[ch_idx] == CORE_MODE_TD); |
134 | 330k | FLOAT64 *ptr_in_data = pstr_usac_data->ptr_time_data[ch_idx]; |
135 | 330k | FLOAT64 *ptr_out_mdct = pstr_usac_data->spectral_line_vector[ch_idx]; |
136 | 330k | FLOAT64 *ptr_out_mdst = pstr_usac_data->mdst_spectrum[ch_idx]; |
137 | 330k | WORD32 window_shape = pstr_usac_config->window_shape_prev[ch_idx]; |
138 | 330k | FLOAT64 *ptr_win_long = NULL, *ptr_win_med = NULL; |
139 | 330k | WORD32 win_len; |
140 | 330k | FLOAT64 *ptr_overlap = pstr_usac_data->overlap_buf[ch_idx]; |
141 | | |
142 | 330k | WORD32 nflat_ls; |
143 | | |
144 | 330k | memset(ptr_windowed_buf, 0, 2 * n_long * sizeof(*ptr_windowed_buf)); |
145 | | |
146 | 330k | switch (window_sequence) { |
147 | 222k | case ONLY_LONG_SEQUENCE: |
148 | 222k | err_code = iusace_calc_window(&ptr_win_long, n_long, window_shape); |
149 | 222k | if (err_code) return err_code; |
150 | 222k | iusace_windowing_long(ptr_overlap, ptr_win_long, ptr_windowed_buf, ptr_in_data, n_long); |
151 | 222k | break; |
152 | | |
153 | 56.6k | case LONG_START_SEQUENCE: |
154 | 56.6k | win_len = n_short << next_mode; |
155 | 56.6k | nflat_ls = (n_long - win_len) >> 1; |
156 | 56.6k | err_code = iusace_calc_window(&ptr_win_long, n_long, window_shape); |
157 | 56.6k | if (err_code) return err_code; |
158 | 56.6k | err_code = iusace_calc_window(&ptr_win_med, win_len, 0); |
159 | 56.6k | if (err_code) return err_code; |
160 | | |
161 | 56.6k | iusace_windowing_long_start(ptr_overlap, ptr_win_long, ptr_windowed_buf, ptr_in_data, |
162 | 56.6k | n_long, nflat_ls, ptr_win_med, win_len); |
163 | 56.6k | break; |
164 | | |
165 | 50.8k | case LONG_STOP_SEQUENCE: |
166 | 50.8k | win_len = n_short << prev_mode; |
167 | 50.8k | nflat_ls = (n_long - win_len) >> 1; |
168 | 50.8k | err_code = iusace_calc_window(&ptr_win_long, n_long, 1); |
169 | 50.8k | if (err_code) return err_code; |
170 | 50.8k | err_code = iusace_calc_window(&ptr_win_med, win_len, window_shape); |
171 | 50.8k | if (err_code) return err_code; |
172 | 50.8k | iusace_windowing_long_stop(ptr_overlap, ptr_win_long, ptr_windowed_buf, ptr_in_data, n_long, |
173 | 50.8k | nflat_ls, ptr_win_med, win_len); |
174 | 50.8k | break; |
175 | | |
176 | 0 | case STOP_START_SEQUENCE: |
177 | 0 | win_len = n_short << (prev_mode | next_mode); |
178 | 0 | err_code = iusace_calc_window(&ptr_win_med, win_len, window_shape); |
179 | 0 | if (err_code) return err_code; |
180 | | |
181 | 0 | iusace_windowing_stop_start(ptr_overlap, ptr_windowed_buf, ptr_win_med, win_len, n_long); |
182 | 0 | break; |
183 | 330k | } |
184 | | |
185 | | // Compute MDCT |
186 | 330k | err_code = |
187 | 330k | iusace_fft_based_mdct(ptr_windowed_buf, ptr_out_mdct, n_long, MDCT_TX_FLAG, pstr_scratch); |
188 | 330k | if (err_code) { |
189 | 0 | return err_code; |
190 | 0 | } |
191 | | |
192 | | // Compute MDST |
193 | 330k | err_code_2 = |
194 | 330k | iusace_fft_based_mdct(ptr_windowed_buf, ptr_out_mdst, n_long, MDST_TX_FLAG, pstr_scratch); |
195 | | |
196 | 330k | if (err_code_2) { |
197 | 0 | return err_code_2; |
198 | 0 | } |
199 | | |
200 | 330k | return IA_NO_ERROR; |
201 | 330k | } |
202 | | |
203 | | WORD32 iusace_fd_mdct(ia_usac_data_struct *pstr_usac_data, |
204 | 495k | ia_usac_encoder_config_struct *pstr_usac_config, WORD32 ch_idx) { |
205 | 495k | IA_ERRORCODE err_code = 0; |
206 | 495k | WORD32 window_sequence = pstr_usac_config->window_sequence[ch_idx]; |
207 | | |
208 | 495k | if (window_sequence != EIGHT_SHORT_SEQUENCE) { |
209 | 330k | err_code = iusace_fd_mdct_long(pstr_usac_data, pstr_usac_config, ch_idx, window_sequence); |
210 | 330k | } else { |
211 | 165k | err_code = iusace_fd_mdct_short(pstr_usac_data, pstr_usac_config, ch_idx); |
212 | 165k | } |
213 | | |
214 | 495k | return err_code; |
215 | 495k | } |