xref: /aosp_15_r20/external/libxaac/encoder/ixheaace_fd_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 <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