xref: /aosp_15_r20/external/libxaac/encoder/ixheaace_fd_mdct.c (revision 15dc779a375ca8b5125643b829a8aa4b70d7f451)
1*15dc779aSAndroid Build Coastguard Worker /******************************************************************************
2*15dc779aSAndroid Build Coastguard Worker  *                                                                            *
3*15dc779aSAndroid Build Coastguard Worker  * Copyright (C) 2023 The Android Open Source Project
4*15dc779aSAndroid Build Coastguard Worker  *
5*15dc779aSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
6*15dc779aSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
7*15dc779aSAndroid Build Coastguard Worker  * You may obtain a copy of the License at:
8*15dc779aSAndroid Build Coastguard Worker  *
9*15dc779aSAndroid Build Coastguard Worker  * http://www.apache.org/licenses/LICENSE-2.0
10*15dc779aSAndroid Build Coastguard Worker  *
11*15dc779aSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
12*15dc779aSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
13*15dc779aSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*15dc779aSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
15*15dc779aSAndroid Build Coastguard Worker  * limitations under the License.
16*15dc779aSAndroid Build Coastguard Worker  *
17*15dc779aSAndroid Build Coastguard Worker  *****************************************************************************
18*15dc779aSAndroid Build Coastguard Worker  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19*15dc779aSAndroid Build Coastguard Worker  */
20*15dc779aSAndroid Build Coastguard Worker 
21*15dc779aSAndroid Build Coastguard Worker #include <string.h>
22*15dc779aSAndroid Build Coastguard Worker #include "iusace_type_def.h"
23*15dc779aSAndroid Build Coastguard Worker 
24*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_mps_common_define.h"
25*15dc779aSAndroid Build Coastguard Worker #include "iusace_cnst.h"
26*15dc779aSAndroid Build Coastguard Worker #include "iusace_bitbuffer.h"
27*15dc779aSAndroid Build Coastguard Worker #include "impd_drc_common_enc.h"
28*15dc779aSAndroid Build Coastguard Worker #include "impd_drc_uni_drc.h"
29*15dc779aSAndroid Build Coastguard Worker #include "impd_drc_api.h"
30*15dc779aSAndroid Build Coastguard Worker #include "impd_drc_uni_drc_eq.h"
31*15dc779aSAndroid Build Coastguard Worker #include "impd_drc_uni_drc_filter_bank.h"
32*15dc779aSAndroid Build Coastguard Worker #include "impd_drc_gain_enc.h"
33*15dc779aSAndroid Build Coastguard Worker #include "impd_drc_struct_def.h"
34*15dc779aSAndroid Build Coastguard Worker 
35*15dc779aSAndroid Build Coastguard Worker #include "iusace_cnst.h"
36*15dc779aSAndroid Build Coastguard Worker #include "iusace_tns_usac.h"
37*15dc779aSAndroid Build Coastguard Worker #include "iusace_psy_mod.h"
38*15dc779aSAndroid Build Coastguard Worker #include "iusace_ms.h"
39*15dc779aSAndroid Build Coastguard Worker 
40*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_adjust_threshold_data.h"
41*15dc779aSAndroid Build Coastguard Worker #include "iusace_fd_qc_util.h"
42*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_memory_standards.h"
43*15dc779aSAndroid Build Coastguard Worker #include "iusace_config.h"
44*15dc779aSAndroid Build Coastguard Worker #include "iusace_fft.h"
45*15dc779aSAndroid Build Coastguard Worker #include "iusace_arith_enc.h"
46*15dc779aSAndroid Build Coastguard Worker #include "iusace_fd_quant.h"
47*15dc779aSAndroid Build Coastguard Worker #include "iusace_signal_classifier.h"
48*15dc779aSAndroid Build Coastguard Worker #include "iusace_block_switch_const.h"
49*15dc779aSAndroid Build Coastguard Worker #include "iusace_block_switch_struct_def.h"
50*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_sbr_header.h"
51*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_config.h"
52*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_asc_write.h"
53*15dc779aSAndroid Build Coastguard Worker #include "iusace_main.h"
54*15dc779aSAndroid Build Coastguard Worker #include "iusace_windowing.h"
55*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_error_standards.h"
56*15dc779aSAndroid Build Coastguard Worker 
iusace_fd_mdct_short(ia_usac_data_struct * pstr_usac_data,ia_usac_encoder_config_struct * pstr_usac_config,WORD32 ch_idx)57*15dc779aSAndroid Build Coastguard Worker static IA_ERRORCODE iusace_fd_mdct_short(ia_usac_data_struct *pstr_usac_data,
58*15dc779aSAndroid Build Coastguard Worker                                          ia_usac_encoder_config_struct *pstr_usac_config,
59*15dc779aSAndroid Build Coastguard Worker                                          WORD32 ch_idx) {
60*15dc779aSAndroid Build Coastguard Worker   IA_ERRORCODE err_code = 0;
61*15dc779aSAndroid Build Coastguard Worker   iusace_scratch_mem *pstr_scratch = &pstr_usac_data->str_scratch;
62*15dc779aSAndroid Build Coastguard Worker   IA_ERRORCODE err_code_2 = 0;
63*15dc779aSAndroid Build Coastguard Worker   FLOAT64 *ptr_windowed_buf = pstr_scratch->p_fd_mdct_windowed_short_buf;
64*15dc779aSAndroid Build Coastguard Worker   WORD32 n_long = pstr_usac_config->ccfl;
65*15dc779aSAndroid Build Coastguard Worker   WORD32 n_short = pstr_usac_config->ccfl >> 3;
66*15dc779aSAndroid Build Coastguard Worker   FLOAT64 *ptr_in_data = pstr_usac_data->ptr_time_data[ch_idx];
67*15dc779aSAndroid Build Coastguard Worker   FLOAT64 *ptr_out_mdct = pstr_usac_data->spectral_line_vector[ch_idx];
68*15dc779aSAndroid Build Coastguard Worker   FLOAT64 *ptr_out_mdst = pstr_usac_data->mdst_spectrum[ch_idx];
69*15dc779aSAndroid Build Coastguard Worker   WORD32 window_shape = pstr_usac_config->window_shape_prev[ch_idx];
70*15dc779aSAndroid Build Coastguard Worker   FLOAT64 *ptr_win_gen_medium = NULL, *ptr_win_gen_short = NULL;
71*15dc779aSAndroid Build Coastguard Worker   FLOAT64 *ptr_overlap = pstr_usac_data->overlap_buf[ch_idx];
72*15dc779aSAndroid Build Coastguard Worker   WORD32 nflat_ls;
73*15dc779aSAndroid Build Coastguard Worker   WORD32 i, k;
74*15dc779aSAndroid Build Coastguard Worker   WORD32 data_size = (OVERLAP_WIN_SIZE_576 * n_long) / LEN_SUPERFRAME;
75*15dc779aSAndroid Build Coastguard Worker 
76*15dc779aSAndroid Build Coastguard Worker   memset(ptr_windowed_buf, 0, 2 * n_short * sizeof(FLOAT64));
77*15dc779aSAndroid Build Coastguard Worker   nflat_ls = (n_long - n_short) >> 1;
78*15dc779aSAndroid Build Coastguard Worker   err_code = iusace_calc_window(&ptr_win_gen_short, n_short, window_shape);
79*15dc779aSAndroid Build Coastguard Worker   if (err_code) return err_code;
80*15dc779aSAndroid Build Coastguard Worker   err_code = iusace_calc_window(&ptr_win_gen_medium, n_short, 0);
81*15dc779aSAndroid Build Coastguard Worker   if (err_code) return err_code;
82*15dc779aSAndroid Build Coastguard Worker   ptr_overlap += nflat_ls;
83*15dc779aSAndroid Build Coastguard Worker 
84*15dc779aSAndroid Build Coastguard Worker   for (k = MAX_SHORT_WINDOWS - 1; k-- >= 0;) {
85*15dc779aSAndroid Build Coastguard Worker     for (i = 0; i < n_short; i++) {
86*15dc779aSAndroid Build Coastguard Worker       ptr_windowed_buf[i] = ptr_win_gen_short[i] * ptr_overlap[i];
87*15dc779aSAndroid Build Coastguard Worker     }
88*15dc779aSAndroid Build Coastguard Worker     for (i = 0; i < n_short; i++) {
89*15dc779aSAndroid Build Coastguard Worker       ptr_windowed_buf[i + n_short] =
90*15dc779aSAndroid Build Coastguard Worker           ptr_win_gen_medium[n_short - 1 - i] * ptr_overlap[i + n_short];
91*15dc779aSAndroid Build Coastguard Worker     }
92*15dc779aSAndroid Build Coastguard Worker 
93*15dc779aSAndroid Build Coastguard Worker     ptr_win_gen_medium = ptr_win_gen_short;
94*15dc779aSAndroid Build Coastguard Worker 
95*15dc779aSAndroid Build Coastguard Worker     // Compute MDCT
96*15dc779aSAndroid Build Coastguard Worker     err_code = iusace_fft_based_mdct(ptr_windowed_buf, ptr_out_mdct, n_short, MDCT_TX_FLAG,
97*15dc779aSAndroid Build Coastguard Worker                                      pstr_scratch);
98*15dc779aSAndroid Build Coastguard Worker 
99*15dc779aSAndroid Build Coastguard Worker     if (err_code) {
100*15dc779aSAndroid Build Coastguard Worker       return err_code;
101*15dc779aSAndroid Build Coastguard Worker     }
102*15dc779aSAndroid Build Coastguard Worker 
103*15dc779aSAndroid Build Coastguard Worker     // Compute MDST
104*15dc779aSAndroid Build Coastguard Worker     err_code_2 = iusace_fft_based_mdct(ptr_windowed_buf, ptr_out_mdst, n_short, MDST_TX_FLAG,
105*15dc779aSAndroid Build Coastguard Worker                                        pstr_scratch);
106*15dc779aSAndroid Build Coastguard Worker 
107*15dc779aSAndroid Build Coastguard Worker     if (err_code_2) {
108*15dc779aSAndroid Build Coastguard Worker       return err_code_2;
109*15dc779aSAndroid Build Coastguard Worker     }
110*15dc779aSAndroid Build Coastguard Worker 
111*15dc779aSAndroid Build Coastguard Worker     ptr_out_mdct += n_short;
112*15dc779aSAndroid Build Coastguard Worker     ptr_out_mdst += n_short;
113*15dc779aSAndroid Build Coastguard Worker     ptr_overlap += n_short;
114*15dc779aSAndroid Build Coastguard Worker   }
115*15dc779aSAndroid Build Coastguard Worker 
116*15dc779aSAndroid Build Coastguard Worker   ptr_overlap = pstr_usac_data->overlap_buf[ch_idx];
117*15dc779aSAndroid Build Coastguard Worker   memcpy(ptr_overlap, ptr_overlap + n_long, data_size * sizeof(*ptr_overlap));
118*15dc779aSAndroid Build Coastguard Worker   memcpy(ptr_overlap + data_size, ptr_in_data, n_long * sizeof(*ptr_overlap));
119*15dc779aSAndroid Build Coastguard Worker 
120*15dc779aSAndroid Build Coastguard Worker   return err_code;
121*15dc779aSAndroid Build Coastguard Worker }
122*15dc779aSAndroid Build Coastguard Worker 
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*15dc779aSAndroid Build Coastguard Worker static IA_ERRORCODE iusace_fd_mdct_long(ia_usac_data_struct *pstr_usac_data,
124*15dc779aSAndroid Build Coastguard Worker                                         ia_usac_encoder_config_struct *pstr_usac_config,
125*15dc779aSAndroid Build Coastguard Worker                                         WORD32 ch_idx, WORD32 window_sequence) {
126*15dc779aSAndroid Build Coastguard Worker   IA_ERRORCODE err_code = 0;
127*15dc779aSAndroid Build Coastguard Worker   iusace_scratch_mem *pstr_scratch = &pstr_usac_data->str_scratch;
128*15dc779aSAndroid Build Coastguard Worker   IA_ERRORCODE err_code_2 = 0;
129*15dc779aSAndroid Build Coastguard Worker   FLOAT64 *ptr_windowed_buf = pstr_scratch->p_fd_mdct_windowed_long_buf;
130*15dc779aSAndroid Build Coastguard Worker   WORD32 n_long = pstr_usac_config->ccfl;
131*15dc779aSAndroid Build Coastguard Worker   WORD32 n_short = pstr_usac_config->ccfl >> 3;
132*15dc779aSAndroid Build Coastguard Worker   WORD32 prev_mode = (pstr_usac_data->core_mode_prev[ch_idx] == CORE_MODE_TD);
133*15dc779aSAndroid Build Coastguard Worker   WORD32 next_mode = (pstr_usac_data->core_mode_next[ch_idx] == CORE_MODE_TD);
134*15dc779aSAndroid Build Coastguard Worker   FLOAT64 *ptr_in_data = pstr_usac_data->ptr_time_data[ch_idx];
135*15dc779aSAndroid Build Coastguard Worker   FLOAT64 *ptr_out_mdct = pstr_usac_data->spectral_line_vector[ch_idx];
136*15dc779aSAndroid Build Coastguard Worker   FLOAT64 *ptr_out_mdst = pstr_usac_data->mdst_spectrum[ch_idx];
137*15dc779aSAndroid Build Coastguard Worker   WORD32 window_shape = pstr_usac_config->window_shape_prev[ch_idx];
138*15dc779aSAndroid Build Coastguard Worker   FLOAT64 *ptr_win_long = NULL, *ptr_win_med = NULL;
139*15dc779aSAndroid Build Coastguard Worker   WORD32 win_len;
140*15dc779aSAndroid Build Coastguard Worker   FLOAT64 *ptr_overlap = pstr_usac_data->overlap_buf[ch_idx];
141*15dc779aSAndroid Build Coastguard Worker 
142*15dc779aSAndroid Build Coastguard Worker   WORD32 nflat_ls;
143*15dc779aSAndroid Build Coastguard Worker 
144*15dc779aSAndroid Build Coastguard Worker   memset(ptr_windowed_buf, 0, 2 * n_long * sizeof(*ptr_windowed_buf));
145*15dc779aSAndroid Build Coastguard Worker 
146*15dc779aSAndroid Build Coastguard Worker   switch (window_sequence) {
147*15dc779aSAndroid Build Coastguard Worker     case ONLY_LONG_SEQUENCE:
148*15dc779aSAndroid Build Coastguard Worker       err_code = iusace_calc_window(&ptr_win_long, n_long, window_shape);
149*15dc779aSAndroid Build Coastguard Worker       if (err_code) return err_code;
150*15dc779aSAndroid Build Coastguard Worker       iusace_windowing_long(ptr_overlap, ptr_win_long, ptr_windowed_buf, ptr_in_data, n_long);
151*15dc779aSAndroid Build Coastguard Worker       break;
152*15dc779aSAndroid Build Coastguard Worker 
153*15dc779aSAndroid Build Coastguard Worker     case LONG_START_SEQUENCE:
154*15dc779aSAndroid Build Coastguard Worker       win_len = n_short << next_mode;
155*15dc779aSAndroid Build Coastguard Worker       nflat_ls = (n_long - win_len) >> 1;
156*15dc779aSAndroid Build Coastguard Worker       err_code = iusace_calc_window(&ptr_win_long, n_long, window_shape);
157*15dc779aSAndroid Build Coastguard Worker       if (err_code) return err_code;
158*15dc779aSAndroid Build Coastguard Worker       err_code = iusace_calc_window(&ptr_win_med, win_len, 0);
159*15dc779aSAndroid Build Coastguard Worker       if (err_code) return err_code;
160*15dc779aSAndroid Build Coastguard Worker 
161*15dc779aSAndroid Build Coastguard Worker       iusace_windowing_long_start(ptr_overlap, ptr_win_long, ptr_windowed_buf, ptr_in_data,
162*15dc779aSAndroid Build Coastguard Worker                                   n_long, nflat_ls, ptr_win_med, win_len);
163*15dc779aSAndroid Build Coastguard Worker       break;
164*15dc779aSAndroid Build Coastguard Worker 
165*15dc779aSAndroid Build Coastguard Worker     case LONG_STOP_SEQUENCE:
166*15dc779aSAndroid Build Coastguard Worker       win_len = n_short << prev_mode;
167*15dc779aSAndroid Build Coastguard Worker       nflat_ls = (n_long - win_len) >> 1;
168*15dc779aSAndroid Build Coastguard Worker       err_code = iusace_calc_window(&ptr_win_long, n_long, window_shape);
169*15dc779aSAndroid Build Coastguard Worker       if (err_code) return err_code;
170*15dc779aSAndroid Build Coastguard Worker       err_code = iusace_calc_window(&ptr_win_med, win_len, 1);
171*15dc779aSAndroid Build Coastguard Worker       if (err_code) return err_code;
172*15dc779aSAndroid Build Coastguard Worker       iusace_windowing_long_stop(ptr_overlap, ptr_win_long, ptr_windowed_buf, ptr_in_data, n_long,
173*15dc779aSAndroid Build Coastguard Worker                                  nflat_ls, ptr_win_med, win_len);
174*15dc779aSAndroid Build Coastguard Worker       break;
175*15dc779aSAndroid Build Coastguard Worker 
176*15dc779aSAndroid Build Coastguard Worker     case STOP_START_SEQUENCE:
177*15dc779aSAndroid Build Coastguard Worker       win_len = n_short << (prev_mode | next_mode);
178*15dc779aSAndroid Build Coastguard Worker       err_code = iusace_calc_window(&ptr_win_med, win_len, window_shape);
179*15dc779aSAndroid Build Coastguard Worker       if (err_code) return err_code;
180*15dc779aSAndroid Build Coastguard Worker 
181*15dc779aSAndroid Build Coastguard Worker       iusace_windowing_stop_start(ptr_overlap, ptr_windowed_buf, ptr_win_med, win_len, n_long);
182*15dc779aSAndroid Build Coastguard Worker       break;
183*15dc779aSAndroid Build Coastguard Worker   }
184*15dc779aSAndroid Build Coastguard Worker 
185*15dc779aSAndroid Build Coastguard Worker   // Compute MDCT
186*15dc779aSAndroid Build Coastguard Worker   err_code =
187*15dc779aSAndroid Build Coastguard Worker       iusace_fft_based_mdct(ptr_windowed_buf, ptr_out_mdct, n_long, MDCT_TX_FLAG, pstr_scratch);
188*15dc779aSAndroid Build Coastguard Worker   if (err_code) {
189*15dc779aSAndroid Build Coastguard Worker     return err_code;
190*15dc779aSAndroid Build Coastguard Worker   }
191*15dc779aSAndroid Build Coastguard Worker 
192*15dc779aSAndroid Build Coastguard Worker   // Compute MDST
193*15dc779aSAndroid Build Coastguard Worker   err_code_2 =
194*15dc779aSAndroid Build Coastguard Worker       iusace_fft_based_mdct(ptr_windowed_buf, ptr_out_mdst, n_long, MDST_TX_FLAG, pstr_scratch);
195*15dc779aSAndroid Build Coastguard Worker 
196*15dc779aSAndroid Build Coastguard Worker   if (err_code_2) {
197*15dc779aSAndroid Build Coastguard Worker     return err_code_2;
198*15dc779aSAndroid Build Coastguard Worker   }
199*15dc779aSAndroid Build Coastguard Worker 
200*15dc779aSAndroid Build Coastguard Worker   return IA_NO_ERROR;
201*15dc779aSAndroid Build Coastguard Worker }
202*15dc779aSAndroid Build Coastguard Worker 
iusace_fd_mdct(ia_usac_data_struct * pstr_usac_data,ia_usac_encoder_config_struct * pstr_usac_config,WORD32 ch_idx)203*15dc779aSAndroid Build Coastguard Worker WORD32 iusace_fd_mdct(ia_usac_data_struct *pstr_usac_data,
204*15dc779aSAndroid Build Coastguard Worker                       ia_usac_encoder_config_struct *pstr_usac_config, WORD32 ch_idx) {
205*15dc779aSAndroid Build Coastguard Worker   IA_ERRORCODE err_code = 0;
206*15dc779aSAndroid Build Coastguard Worker   WORD32 window_sequence = pstr_usac_config->window_sequence[ch_idx];
207*15dc779aSAndroid Build Coastguard Worker 
208*15dc779aSAndroid Build Coastguard Worker   if (window_sequence != EIGHT_SHORT_SEQUENCE) {
209*15dc779aSAndroid Build Coastguard Worker     err_code = iusace_fd_mdct_long(pstr_usac_data, pstr_usac_config, ch_idx, window_sequence);
210*15dc779aSAndroid Build Coastguard Worker   } else {
211*15dc779aSAndroid Build Coastguard Worker     err_code = iusace_fd_mdct_short(pstr_usac_data, pstr_usac_config, ch_idx);
212*15dc779aSAndroid Build Coastguard Worker   }
213*15dc779aSAndroid Build Coastguard Worker 
214*15dc779aSAndroid Build Coastguard Worker   return err_code;
215*15dc779aSAndroid Build Coastguard Worker }
216