xref: /aosp_15_r20/external/libxaac/encoder/iusace_esbr_pvc.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 <math.h>
23*15dc779aSAndroid Build Coastguard Worker 
24*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_type_def.h"
25*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_constants.h"
26*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_aac_constants.h"
27*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_basic_ops32.h"
28*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_basic_ops16.h"
29*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_basic_ops40.h"
30*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_error_standards.h"
31*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_error_codes.h"
32*15dc779aSAndroid Build Coastguard Worker 
33*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_bitbuffer.h"
34*15dc779aSAndroid Build Coastguard Worker #include "iusace_esbr_pvc.h"
35*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_common_utils.h"
36*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_sbr_cmondata.h"
37*15dc779aSAndroid Build Coastguard Worker 
ixheaace_pvc_enc_init(ixheaace_pvc_enc * pstr_pvc_enc,WORD32 sbr_pvc_rate)38*15dc779aSAndroid Build Coastguard Worker IA_ERRORCODE ixheaace_pvc_enc_init(ixheaace_pvc_enc *pstr_pvc_enc, WORD32 sbr_pvc_rate) {
39*15dc779aSAndroid Build Coastguard Worker   pstr_pvc_enc->pvc_prv_param.pvc_flag = IXHEAACE_ESBR_PVC_FLAG_PREV_DFLT;
40*15dc779aSAndroid Build Coastguard Worker   pstr_pvc_enc->pvc_prv_param.pvc_id = IXHEAACE_ESBR_PVC_ID_PREV_DFLT;
41*15dc779aSAndroid Build Coastguard Worker   pstr_pvc_enc->pvc_prv_param.pvc_rate = IXHEAACE_ESBR_PVC_RATE_PREV_DFLT;
42*15dc779aSAndroid Build Coastguard Worker   pstr_pvc_enc->pvc_prv_param.start_band = IXHEAACE_ESBR_PVC_STRT_BAND_PREV_DFLT;
43*15dc779aSAndroid Build Coastguard Worker   pstr_pvc_enc->pvc_param.pvc_rate = (UWORD8)sbr_pvc_rate;
44*15dc779aSAndroid Build Coastguard Worker 
45*15dc779aSAndroid Build Coastguard Worker   return IA_NO_ERROR;
46*15dc779aSAndroid Build Coastguard Worker }
47*15dc779aSAndroid Build Coastguard Worker 
ixheaace_pvc_sb_grouping(ixheaace_pvc_enc * pstr_pvc_enc,UWORD8 start_band,FLOAT32 * ptr_qmf_low,FLOAT32 * ptr_sb_grp_energy,WORD32 first_pvc_ts)48*15dc779aSAndroid Build Coastguard Worker static VOID ixheaace_pvc_sb_grouping(ixheaace_pvc_enc *pstr_pvc_enc, UWORD8 start_band,
49*15dc779aSAndroid Build Coastguard Worker                                      FLOAT32 *ptr_qmf_low, FLOAT32 *ptr_sb_grp_energy,
50*15dc779aSAndroid Build Coastguard Worker                                      WORD32 first_pvc_ts) {
51*15dc779aSAndroid Build Coastguard Worker   WORD32 ksg, ts, band;
52*15dc779aSAndroid Build Coastguard Worker   FLOAT32 tmp_sb_grp_energy;
53*15dc779aSAndroid Build Coastguard Worker   WORD32 lbw, sb;
54*15dc779aSAndroid Build Coastguard Worker   WORD32 nqmf_lb;
55*15dc779aSAndroid Build Coastguard Worker   FLOAT32 *ptr_tmp_qmfl;
56*15dc779aSAndroid Build Coastguard Worker 
57*15dc779aSAndroid Build Coastguard Worker   ixheaace_pvc_params *pstr_params = &pstr_pvc_enc->pvc_param;
58*15dc779aSAndroid Build Coastguard Worker   ixheaace_pvc_prv_frm_params *pstr_prv_params = &pstr_pvc_enc->pvc_prv_param;
59*15dc779aSAndroid Build Coastguard Worker 
60*15dc779aSAndroid Build Coastguard Worker   nqmf_lb = IXHEAACE_ESBR_PVC_NUM_QMF_BANDS / pstr_params->pvc_rate;
61*15dc779aSAndroid Build Coastguard Worker   lbw = 8 / pstr_params->pvc_rate;
62*15dc779aSAndroid Build Coastguard Worker 
63*15dc779aSAndroid Build Coastguard Worker   for (ts = 0; ts < IXHEAACE_ESBR_PVC_NUM_TS; ts++) {
64*15dc779aSAndroid Build Coastguard Worker     sb = start_band - lbw * pstr_params->num_grp_core;
65*15dc779aSAndroid Build Coastguard Worker     ksg = 0;
66*15dc779aSAndroid Build Coastguard Worker     while (ksg < pstr_params->num_grp_core) {
67*15dc779aSAndroid Build Coastguard Worker       tmp_sb_grp_energy = 0.0f;
68*15dc779aSAndroid Build Coastguard Worker       if (sb >= 0) {
69*15dc779aSAndroid Build Coastguard Worker         ptr_tmp_qmfl = &ptr_qmf_low[ts * nqmf_lb + sb];
70*15dc779aSAndroid Build Coastguard Worker         band = 0;
71*15dc779aSAndroid Build Coastguard Worker         while (band < lbw) {
72*15dc779aSAndroid Build Coastguard Worker           tmp_sb_grp_energy += ptr_tmp_qmfl[band];
73*15dc779aSAndroid Build Coastguard Worker           band++;
74*15dc779aSAndroid Build Coastguard Worker         }
75*15dc779aSAndroid Build Coastguard Worker         tmp_sb_grp_energy /= lbw;
76*15dc779aSAndroid Build Coastguard Worker       }
77*15dc779aSAndroid Build Coastguard Worker 
78*15dc779aSAndroid Build Coastguard Worker       tmp_sb_grp_energy = max(IXHEAACE_ESBR_PVC_POW_THRS, tmp_sb_grp_energy);
79*15dc779aSAndroid Build Coastguard Worker       ptr_sb_grp_energy[(ts + IXHEAACE_ESBR_PVC_NUM_TS - 1) * 3 + ksg] =
80*15dc779aSAndroid Build Coastguard Worker           10 * (FLOAT32)log10(tmp_sb_grp_energy);
81*15dc779aSAndroid Build Coastguard Worker       sb += lbw;
82*15dc779aSAndroid Build Coastguard Worker       ksg++;
83*15dc779aSAndroid Build Coastguard Worker     }
84*15dc779aSAndroid Build Coastguard Worker   }
85*15dc779aSAndroid Build Coastguard Worker 
86*15dc779aSAndroid Build Coastguard Worker   if ((pstr_prv_params->pvc_flag == 0) ||
87*15dc779aSAndroid Build Coastguard Worker       ((start_band * pstr_params->pvc_rate) !=
88*15dc779aSAndroid Build Coastguard Worker        (pstr_prv_params->start_band * pstr_prv_params->pvc_rate))) {
89*15dc779aSAndroid Build Coastguard Worker     for (ts = 0; ts < IXHEAACE_ESBR_PVC_NUM_TS - 1 + first_pvc_ts; ts++) {
90*15dc779aSAndroid Build Coastguard Worker       memcpy(&ptr_sb_grp_energy[ts * 3],
91*15dc779aSAndroid Build Coastguard Worker              &ptr_sb_grp_energy[(IXHEAACE_ESBR_PVC_NUM_TS - 1 + first_pvc_ts) * 3],
92*15dc779aSAndroid Build Coastguard Worker              pstr_params->num_grp_core * sizeof(ptr_sb_grp_energy[0]));
93*15dc779aSAndroid Build Coastguard Worker     }
94*15dc779aSAndroid Build Coastguard Worker   }
95*15dc779aSAndroid Build Coastguard Worker 
96*15dc779aSAndroid Build Coastguard Worker   return;
97*15dc779aSAndroid Build Coastguard Worker }
98*15dc779aSAndroid Build Coastguard Worker 
ixheaace_set_pvc_mode_param(ixheaace_pvc_params * pstr_pvc_param,ixheaace_pvc_coef_tabs * pstr_pvc_tabs)99*15dc779aSAndroid Build Coastguard Worker static IA_ERRORCODE ixheaace_set_pvc_mode_param(ixheaace_pvc_params *pstr_pvc_param,
100*15dc779aSAndroid Build Coastguard Worker                                                 ixheaace_pvc_coef_tabs *pstr_pvc_tabs) {
101*15dc779aSAndroid Build Coastguard Worker   pstr_pvc_param->num_grp_core = IXHEAACE_ESBR_PVC_NUM_BANDS_CORE;
102*15dc779aSAndroid Build Coastguard Worker   pstr_pvc_param->num_pvc_id = IXHEAACE_ESBR_PVC_NUM_PVCID;
103*15dc779aSAndroid Build Coastguard Worker 
104*15dc779aSAndroid Build Coastguard Worker   switch (pstr_pvc_param->pvc_mode) {
105*15dc779aSAndroid Build Coastguard Worker     case IXHEAACE_ESBR_PVC_MODE_1:
106*15dc779aSAndroid Build Coastguard Worker       pstr_pvc_param->num_grp_sbr = IXHEAACE_ESBR_PVC_NUM_BANDS_SBR_MODE1;
107*15dc779aSAndroid Build Coastguard Worker       pstr_pvc_param->hbw = 8 / pstr_pvc_param->pvc_rate;
108*15dc779aSAndroid Build Coastguard Worker       pstr_pvc_tabs->pvc_pred_coef_kb_012 =
109*15dc779aSAndroid Build Coastguard Worker           (UWORD8 *)ixheaace_pvc_tabs.pvc_prd_coef_kb_012_mode_1;
110*15dc779aSAndroid Build Coastguard Worker       pstr_pvc_tabs->pvc_pred_coef_kb_3 = (UWORD8 *)ixheaace_pvc_tabs.pvc_prd_coef_kb_3_mode_1;
111*15dc779aSAndroid Build Coastguard Worker       pstr_pvc_tabs->pvc_idx_tab = ixheaace_pvc_tabs.pvc_idx_mode_1;
112*15dc779aSAndroid Build Coastguard Worker       pstr_pvc_tabs->scaling_coef = ixheaace_pvc_tabs.pvc_scaling_coef_mode_1;
113*15dc779aSAndroid Build Coastguard Worker       break;
114*15dc779aSAndroid Build Coastguard Worker 
115*15dc779aSAndroid Build Coastguard Worker     case IXHEAACE_ESBR_PVC_MODE_2:
116*15dc779aSAndroid Build Coastguard Worker       pstr_pvc_param->num_grp_sbr = IXHEAACE_ESBR_PVC_NUM_BANDS_SBR_MODE2;
117*15dc779aSAndroid Build Coastguard Worker       pstr_pvc_param->hbw = 12 / pstr_pvc_param->pvc_rate;
118*15dc779aSAndroid Build Coastguard Worker       pstr_pvc_tabs->pvc_pred_coef_kb_012 =
119*15dc779aSAndroid Build Coastguard Worker           (UWORD8 *)ixheaace_pvc_tabs.pvc_prd_coef_kb_012_mode_2;
120*15dc779aSAndroid Build Coastguard Worker       pstr_pvc_tabs->pvc_pred_coef_kb_3 = (UWORD8 *)ixheaace_pvc_tabs.pvc_prd_coef_kb_3_mode_2;
121*15dc779aSAndroid Build Coastguard Worker       pstr_pvc_tabs->pvc_idx_tab = ixheaace_pvc_tabs.pvc_idx_mode_2;
122*15dc779aSAndroid Build Coastguard Worker       pstr_pvc_tabs->scaling_coef = ixheaace_pvc_tabs.pvc_scaling_coef_mode_2;
123*15dc779aSAndroid Build Coastguard Worker       break;
124*15dc779aSAndroid Build Coastguard Worker 
125*15dc779aSAndroid Build Coastguard Worker     default:
126*15dc779aSAndroid Build Coastguard Worker       return IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_PVC_MODE;
127*15dc779aSAndroid Build Coastguard Worker   }
128*15dc779aSAndroid Build Coastguard Worker   return IA_NO_ERROR;
129*15dc779aSAndroid Build Coastguard Worker }
130*15dc779aSAndroid Build Coastguard Worker 
ixheaace_pvc_sb_grouping_ref(ixheaace_pvc_params * pstr_pvc_param,UWORD8 start_band,UWORD8 stop_band,FLOAT32 * ptr_qmf_high,FLOAT32 * ptr_sb_grp_energy)131*15dc779aSAndroid Build Coastguard Worker static VOID ixheaace_pvc_sb_grouping_ref(ixheaace_pvc_params *pstr_pvc_param, UWORD8 start_band,
132*15dc779aSAndroid Build Coastguard Worker                                          UWORD8 stop_band, FLOAT32 *ptr_qmf_high,
133*15dc779aSAndroid Build Coastguard Worker                                          FLOAT32 *ptr_sb_grp_energy) {
134*15dc779aSAndroid Build Coastguard Worker   WORD32 ksg, ts, band;
135*15dc779aSAndroid Build Coastguard Worker   UWORD8 min_sb;
136*15dc779aSAndroid Build Coastguard Worker   WORD32 sb, eb;
137*15dc779aSAndroid Build Coastguard Worker   FLOAT32 tmp_sb_grp_energy;
138*15dc779aSAndroid Build Coastguard Worker 
139*15dc779aSAndroid Build Coastguard Worker   min_sb = start_band + pstr_pvc_param->num_grp_sbr * pstr_pvc_param->hbw - 1;
140*15dc779aSAndroid Build Coastguard Worker   stop_band = max(stop_band, min_sb);
141*15dc779aSAndroid Build Coastguard Worker 
142*15dc779aSAndroid Build Coastguard Worker   for (ts = 0; ts < IXHEAACE_ESBR_PVC_NUM_TS; ts++) {
143*15dc779aSAndroid Build Coastguard Worker     sb = start_band;
144*15dc779aSAndroid Build Coastguard Worker     eb = min((sb + pstr_pvc_param->hbw - 1), (IXHEAACE_ESBR_PVC_NUM_QMF_BANDS - 1));
145*15dc779aSAndroid Build Coastguard Worker 
146*15dc779aSAndroid Build Coastguard Worker     for (ksg = 0; ksg < (pstr_pvc_param->num_grp_sbr - 2); ksg++) {
147*15dc779aSAndroid Build Coastguard Worker       tmp_sb_grp_energy = 0.0f;
148*15dc779aSAndroid Build Coastguard Worker       band = sb;
149*15dc779aSAndroid Build Coastguard Worker       while (band <= eb) {
150*15dc779aSAndroid Build Coastguard Worker         tmp_sb_grp_energy += ptr_qmf_high[ts * IXHEAACE_ESBR_PVC_NUM_QMF_BANDS + band];
151*15dc779aSAndroid Build Coastguard Worker         band++;
152*15dc779aSAndroid Build Coastguard Worker       }
153*15dc779aSAndroid Build Coastguard Worker       tmp_sb_grp_energy = tmp_sb_grp_energy / (eb - sb + 1);
154*15dc779aSAndroid Build Coastguard Worker 
155*15dc779aSAndroid Build Coastguard Worker       ptr_sb_grp_energy[ts * pstr_pvc_param->num_grp_sbr + ksg] =
156*15dc779aSAndroid Build Coastguard Worker           max(IXHEAACE_ESBR_PVC_POW_THRS, tmp_sb_grp_energy);
157*15dc779aSAndroid Build Coastguard Worker       sb += pstr_pvc_param->hbw;
158*15dc779aSAndroid Build Coastguard Worker       eb = min((sb + pstr_pvc_param->hbw - 1), stop_band);
159*15dc779aSAndroid Build Coastguard Worker       eb = min(eb, (IXHEAACE_ESBR_PVC_NUM_QMF_BANDS - 1));
160*15dc779aSAndroid Build Coastguard Worker     }
161*15dc779aSAndroid Build Coastguard Worker 
162*15dc779aSAndroid Build Coastguard Worker     while (ksg < pstr_pvc_param->num_grp_sbr) {
163*15dc779aSAndroid Build Coastguard Worker       tmp_sb_grp_energy = 0.0f;
164*15dc779aSAndroid Build Coastguard Worker       band = sb;
165*15dc779aSAndroid Build Coastguard Worker       while (band <= eb) {
166*15dc779aSAndroid Build Coastguard Worker         tmp_sb_grp_energy += ptr_qmf_high[ts * IXHEAACE_ESBR_PVC_NUM_QMF_BANDS + band];
167*15dc779aSAndroid Build Coastguard Worker         band++;
168*15dc779aSAndroid Build Coastguard Worker       }
169*15dc779aSAndroid Build Coastguard Worker       tmp_sb_grp_energy = tmp_sb_grp_energy / (eb - sb + 1);
170*15dc779aSAndroid Build Coastguard Worker 
171*15dc779aSAndroid Build Coastguard Worker       ptr_sb_grp_energy[ts * pstr_pvc_param->num_grp_sbr + ksg] =
172*15dc779aSAndroid Build Coastguard Worker           max(IXHEAACE_ESBR_PVC_POW_THRS, tmp_sb_grp_energy);
173*15dc779aSAndroid Build Coastguard Worker       sb += pstr_pvc_param->hbw;
174*15dc779aSAndroid Build Coastguard Worker       eb = min(stop_band, (IXHEAACE_ESBR_PVC_NUM_QMF_BANDS - 1));
175*15dc779aSAndroid Build Coastguard Worker       ksg++;
176*15dc779aSAndroid Build Coastguard Worker     }
177*15dc779aSAndroid Build Coastguard Worker   }
178*15dc779aSAndroid Build Coastguard Worker   return;
179*15dc779aSAndroid Build Coastguard Worker }
180*15dc779aSAndroid Build Coastguard Worker 
ixheaace_pvc_calc_grp_energy_below_sbr(ixheaace_pvc_enc * pstr_pvc_enc,WORD32 ts,FLOAT32 * ptr_sb_grp_ene_blsbr)181*15dc779aSAndroid Build Coastguard Worker static VOID ixheaace_pvc_calc_grp_energy_below_sbr(ixheaace_pvc_enc *pstr_pvc_enc, WORD32 ts,
182*15dc779aSAndroid Build Coastguard Worker                                                    FLOAT32 *ptr_sb_grp_ene_blsbr) {
183*15dc779aSAndroid Build Coastguard Worker   WORD32 ksg = 0, idx;
184*15dc779aSAndroid Build Coastguard Worker   ixheaace_pvc_params *pstr_pvc_params = &pstr_pvc_enc->pvc_param;
185*15dc779aSAndroid Build Coastguard Worker 
186*15dc779aSAndroid Build Coastguard Worker   memset(ptr_sb_grp_ene_blsbr, 0,
187*15dc779aSAndroid Build Coastguard Worker          pstr_pvc_params->num_grp_core * sizeof(ptr_sb_grp_ene_blsbr[0]));
188*15dc779aSAndroid Build Coastguard Worker 
189*15dc779aSAndroid Build Coastguard Worker   while (ksg < pstr_pvc_params->num_grp_core) {
190*15dc779aSAndroid Build Coastguard Worker     for (idx = 0; idx < pstr_pvc_params->time_smth_ts; idx++) {
191*15dc779aSAndroid Build Coastguard Worker       ptr_sb_grp_ene_blsbr[ksg] +=
192*15dc779aSAndroid Build Coastguard Worker           pstr_pvc_enc->sb_grp_energy[ts + IXHEAACE_ESBR_PVC_NUM_TS - 1 - idx][ksg] *
193*15dc779aSAndroid Build Coastguard Worker           pstr_pvc_enc->pvc_tabs.smoothing_coef[idx];
194*15dc779aSAndroid Build Coastguard Worker     }
195*15dc779aSAndroid Build Coastguard Worker     ksg++;
196*15dc779aSAndroid Build Coastguard Worker   }
197*15dc779aSAndroid Build Coastguard Worker   return;
198*15dc779aSAndroid Build Coastguard Worker }
199*15dc779aSAndroid Build Coastguard Worker 
ixheaace_pvc_predict(ixheaace_pvc_enc * pstr_pvc_enc,WORD32 ts,FLOAT32 * ptr_sb_grp_ene_blsbr,FLOAT32 * ptr_sb_grp_energy_high)200*15dc779aSAndroid Build Coastguard Worker static VOID ixheaace_pvc_predict(ixheaace_pvc_enc *pstr_pvc_enc, WORD32 ts,
201*15dc779aSAndroid Build Coastguard Worker                                  FLOAT32 *ptr_sb_grp_ene_blsbr, FLOAT32 *ptr_sb_grp_energy_high) {
202*15dc779aSAndroid Build Coastguard Worker   ixheaace_pvc_params *pstr_pvc_params = &(pstr_pvc_enc->pvc_param);
203*15dc779aSAndroid Build Coastguard Worker   ixheaace_pvc_coef_tabs *pstr_pvc_tabs = &(pstr_pvc_enc->pvc_tabs);
204*15dc779aSAndroid Build Coastguard Worker 
205*15dc779aSAndroid Build Coastguard Worker   WORD32 ksg, kb, idx_tab_1, idx_tab_2;
206*15dc779aSAndroid Build Coastguard Worker   const UWORD8 *ptr_tab;
207*15dc779aSAndroid Build Coastguard Worker   FLOAT32 prod;
208*15dc779aSAndroid Build Coastguard Worker 
209*15dc779aSAndroid Build Coastguard Worker   idx_tab_2 = pstr_pvc_params->pvc_id[ts];
210*15dc779aSAndroid Build Coastguard Worker 
211*15dc779aSAndroid Build Coastguard Worker   if (idx_tab_2 < pstr_pvc_tabs->pvc_idx_tab[0]) {
212*15dc779aSAndroid Build Coastguard Worker     idx_tab_1 = 0;
213*15dc779aSAndroid Build Coastguard Worker   } else if (idx_tab_2 < pstr_pvc_tabs->pvc_idx_tab[1]) {
214*15dc779aSAndroid Build Coastguard Worker     idx_tab_1 = 1;
215*15dc779aSAndroid Build Coastguard Worker   } else {
216*15dc779aSAndroid Build Coastguard Worker     idx_tab_1 = 2;
217*15dc779aSAndroid Build Coastguard Worker   }
218*15dc779aSAndroid Build Coastguard Worker 
219*15dc779aSAndroid Build Coastguard Worker   memset(ptr_sb_grp_energy_high, 0,
220*15dc779aSAndroid Build Coastguard Worker          pstr_pvc_params->num_grp_sbr * sizeof(ptr_sb_grp_energy_high[0]));
221*15dc779aSAndroid Build Coastguard Worker 
222*15dc779aSAndroid Build Coastguard Worker   ptr_tab = &(pstr_pvc_tabs->pvc_pred_coef_kb_012[idx_tab_1 * pstr_pvc_params->num_grp_core *
223*15dc779aSAndroid Build Coastguard Worker                                                   pstr_pvc_params->num_grp_sbr]);
224*15dc779aSAndroid Build Coastguard Worker 
225*15dc779aSAndroid Build Coastguard Worker   for (kb = 0; kb < pstr_pvc_params->num_grp_core; kb++) {
226*15dc779aSAndroid Build Coastguard Worker     prod = pstr_pvc_tabs->scaling_coef[kb] * ptr_sb_grp_ene_blsbr[kb];
227*15dc779aSAndroid Build Coastguard Worker     for (ksg = 0; ksg < pstr_pvc_params->num_grp_sbr; ksg++) {
228*15dc779aSAndroid Build Coastguard Worker       ptr_sb_grp_energy_high[ksg] += ((FLOAT32)(WORD8)(*(ptr_tab++)) * prod);
229*15dc779aSAndroid Build Coastguard Worker     }
230*15dc779aSAndroid Build Coastguard Worker   }
231*15dc779aSAndroid Build Coastguard Worker 
232*15dc779aSAndroid Build Coastguard Worker   ptr_tab = &(pstr_pvc_tabs->pvc_pred_coef_kb_3[idx_tab_2 * pstr_pvc_params->num_grp_sbr]);
233*15dc779aSAndroid Build Coastguard Worker   prod = pstr_pvc_tabs->scaling_coef[pstr_pvc_params->num_grp_core];
234*15dc779aSAndroid Build Coastguard Worker 
235*15dc779aSAndroid Build Coastguard Worker   for (ksg = 0; ksg < pstr_pvc_params->num_grp_sbr; ksg++) {
236*15dc779aSAndroid Build Coastguard Worker     ptr_sb_grp_energy_high[ksg] += (FLOAT32)(WORD8)(*(ptr_tab++)) * prod;
237*15dc779aSAndroid Build Coastguard Worker   }
238*15dc779aSAndroid Build Coastguard Worker 
239*15dc779aSAndroid Build Coastguard Worker   return;
240*15dc779aSAndroid Build Coastguard Worker }
241*15dc779aSAndroid Build Coastguard Worker 
ixheaace_pvc_packing(ixheaace_pvc_enc * pstr_pvc_enc,WORD32 const usac_indep_flag)242*15dc779aSAndroid Build Coastguard Worker static VOID ixheaace_pvc_packing(ixheaace_pvc_enc *pstr_pvc_enc, WORD32 const usac_indep_flag) {
243*15dc779aSAndroid Build Coastguard Worker   UWORD16 *ptr_pvc_bs;
244*15dc779aSAndroid Build Coastguard Worker   ixheaace_pvc_params *pstr_params = &pstr_pvc_enc->pvc_param;
245*15dc779aSAndroid Build Coastguard Worker   ixheaace_pvc_prv_frm_params *pstr_prv_params = &pstr_pvc_enc->pvc_prv_param;
246*15dc779aSAndroid Build Coastguard Worker   ixheaace_pvc_bs_info *pstr_pvc_bs_info = &pstr_pvc_enc->pvc_bs_info;
247*15dc779aSAndroid Build Coastguard Worker 
248*15dc779aSAndroid Build Coastguard Worker   ptr_pvc_bs = pstr_pvc_bs_info->pvc_id_bs;
249*15dc779aSAndroid Build Coastguard Worker 
250*15dc779aSAndroid Build Coastguard Worker   pstr_pvc_bs_info->ns_mode = pstr_params->ns_mode;
251*15dc779aSAndroid Build Coastguard Worker 
252*15dc779aSAndroid Build Coastguard Worker   if ((usac_indep_flag == 1) || (pstr_params->pvc_id[1] != pstr_prv_params->pvc_id)) {
253*15dc779aSAndroid Build Coastguard Worker     pstr_pvc_bs_info->grid_info[0] = 1;
254*15dc779aSAndroid Build Coastguard Worker     *(ptr_pvc_bs++) = pstr_params->pvc_id[0];
255*15dc779aSAndroid Build Coastguard Worker   } else {
256*15dc779aSAndroid Build Coastguard Worker     pstr_pvc_bs_info->grid_info[0] = 0;
257*15dc779aSAndroid Build Coastguard Worker   }
258*15dc779aSAndroid Build Coastguard Worker 
259*15dc779aSAndroid Build Coastguard Worker   if (pstr_params->pvc_id[8] == pstr_params->pvc_id[7]) {
260*15dc779aSAndroid Build Coastguard Worker     pstr_pvc_bs_info->div_mode = 0;
261*15dc779aSAndroid Build Coastguard Worker   } else {
262*15dc779aSAndroid Build Coastguard Worker     pstr_pvc_bs_info->div_mode = 4;
263*15dc779aSAndroid Build Coastguard Worker     pstr_pvc_bs_info->num_grid_info = 2;
264*15dc779aSAndroid Build Coastguard Worker     pstr_pvc_bs_info->grid_info[1] = 1;
265*15dc779aSAndroid Build Coastguard Worker     *(ptr_pvc_bs++) = pstr_params->pvc_id[8];
266*15dc779aSAndroid Build Coastguard Worker   }
267*15dc779aSAndroid Build Coastguard Worker   return;
268*15dc779aSAndroid Build Coastguard Worker }
269*15dc779aSAndroid Build Coastguard Worker 
ixheaace_pvc_calc_res(FLOAT32 * ptr_org,FLOAT32 * ptr_prd,UWORD8 ng_sb_sbr)270*15dc779aSAndroid Build Coastguard Worker static FLOAT32 ixheaace_pvc_calc_res(FLOAT32 *ptr_org, FLOAT32 *ptr_prd, UWORD8 ng_sb_sbr) {
271*15dc779aSAndroid Build Coastguard Worker   FLOAT32 residual = 0, diff;
272*15dc779aSAndroid Build Coastguard Worker   WORD32 band = 0;
273*15dc779aSAndroid Build Coastguard Worker 
274*15dc779aSAndroid Build Coastguard Worker   while (band < ng_sb_sbr) {
275*15dc779aSAndroid Build Coastguard Worker     diff = ptr_org[band] - ptr_prd[band];
276*15dc779aSAndroid Build Coastguard Worker     residual += diff * diff;
277*15dc779aSAndroid Build Coastguard Worker     band++;
278*15dc779aSAndroid Build Coastguard Worker   }
279*15dc779aSAndroid Build Coastguard Worker   residual = (FLOAT32)sqrt(residual);
280*15dc779aSAndroid Build Coastguard Worker 
281*15dc779aSAndroid Build Coastguard Worker   return residual;
282*15dc779aSAndroid Build Coastguard Worker }
283*15dc779aSAndroid Build Coastguard Worker 
ixheaace_pvc_calc_grp_energy(ixheaace_pvc_enc * pstr_pvc_enc,FLOAT32 * ptr_sb_grp_energy_hi_ref)284*15dc779aSAndroid Build Coastguard Worker VOID ixheaace_pvc_calc_grp_energy(ixheaace_pvc_enc *pstr_pvc_enc,
285*15dc779aSAndroid Build Coastguard Worker                                   FLOAT32 *ptr_sb_grp_energy_hi_ref) {
286*15dc779aSAndroid Build Coastguard Worker   WORD32 ts, res_init_flg = 1, pvc_id, i;
287*15dc779aSAndroid Build Coastguard Worker   FLOAT32 res_all[128] = {0}, res_min, sb_grp_energy_blwsbr[3], sb_grp_energy_hi[8], res = 0;
288*15dc779aSAndroid Build Coastguard Worker   UWORD16 *ptr_pvc_id, tmp = 0;
289*15dc779aSAndroid Build Coastguard Worker 
290*15dc779aSAndroid Build Coastguard Worker   ptr_pvc_id = pstr_pvc_enc->pvc_param.pvc_id;
291*15dc779aSAndroid Build Coastguard Worker   for (ts = 0; ts < IXHEAACE_ESBR_PVC_NUM_TS; ts++) {
292*15dc779aSAndroid Build Coastguard Worker     ixheaace_pvc_calc_grp_energy_below_sbr(pstr_pvc_enc, ts, sb_grp_energy_blwsbr);
293*15dc779aSAndroid Build Coastguard Worker     for (pvc_id = 0; pvc_id < pstr_pvc_enc->pvc_param.num_pvc_id; pvc_id++) {
294*15dc779aSAndroid Build Coastguard Worker       pstr_pvc_enc->pvc_param.pvc_id[ts] = (UWORD16)pvc_id;
295*15dc779aSAndroid Build Coastguard Worker       ixheaace_pvc_predict(pstr_pvc_enc, ts, sb_grp_energy_blwsbr, sb_grp_energy_hi);
296*15dc779aSAndroid Build Coastguard Worker 
297*15dc779aSAndroid Build Coastguard Worker       res = ixheaace_pvc_calc_res(
298*15dc779aSAndroid Build Coastguard Worker           &(ptr_sb_grp_energy_hi_ref[ts * pstr_pvc_enc->pvc_param.num_grp_sbr]), sb_grp_energy_hi,
299*15dc779aSAndroid Build Coastguard Worker           pstr_pvc_enc->pvc_param.num_grp_sbr);
300*15dc779aSAndroid Build Coastguard Worker       if (res_init_flg) {
301*15dc779aSAndroid Build Coastguard Worker         res_all[pvc_id] = res;
302*15dc779aSAndroid Build Coastguard Worker       } else {
303*15dc779aSAndroid Build Coastguard Worker         res_all[pvc_id] += res;
304*15dc779aSAndroid Build Coastguard Worker       }
305*15dc779aSAndroid Build Coastguard Worker     }
306*15dc779aSAndroid Build Coastguard Worker 
307*15dc779aSAndroid Build Coastguard Worker     res_init_flg = 0;
308*15dc779aSAndroid Build Coastguard Worker     if ((ts & (IXHEAACE_ESBR_PVC_NTS_GRP_ID - 1)) == (IXHEAACE_ESBR_PVC_NTS_GRP_ID - 1)) {
309*15dc779aSAndroid Build Coastguard Worker       res_min = IXHEAACE_ESBR_PVC_RESIDUAL_VAL;
310*15dc779aSAndroid Build Coastguard Worker       pvc_id = 0;
311*15dc779aSAndroid Build Coastguard Worker       while (pvc_id < pstr_pvc_enc->pvc_param.num_pvc_id) {
312*15dc779aSAndroid Build Coastguard Worker         if (res_all[pvc_id] < res_min) {
313*15dc779aSAndroid Build Coastguard Worker           tmp = (UWORD16)pvc_id;
314*15dc779aSAndroid Build Coastguard Worker           res_min = res_all[pvc_id];
315*15dc779aSAndroid Build Coastguard Worker         }
316*15dc779aSAndroid Build Coastguard Worker         pvc_id++;
317*15dc779aSAndroid Build Coastguard Worker       }
318*15dc779aSAndroid Build Coastguard Worker       for (i = 0; i < IXHEAACE_ESBR_PVC_NTS_GRP_ID; i++) {
319*15dc779aSAndroid Build Coastguard Worker         *(ptr_pvc_id++) = tmp;
320*15dc779aSAndroid Build Coastguard Worker       }
321*15dc779aSAndroid Build Coastguard Worker       res_init_flg = 1;
322*15dc779aSAndroid Build Coastguard Worker     }
323*15dc779aSAndroid Build Coastguard Worker   }
324*15dc779aSAndroid Build Coastguard Worker 
325*15dc779aSAndroid Build Coastguard Worker   for (ts = 0; ts < 15; ts++) {
326*15dc779aSAndroid Build Coastguard Worker     memcpy(&pstr_pvc_enc->sb_grp_energy[ts][0],
327*15dc779aSAndroid Build Coastguard Worker            &pstr_pvc_enc->sb_grp_energy[ts + IXHEAACE_ESBR_PVC_NUM_TS][0],
328*15dc779aSAndroid Build Coastguard Worker            IXHEAACE_ESBR_PVC_NUM_BANDS_CORE * sizeof(pstr_pvc_enc->sb_grp_energy[ts][0]));
329*15dc779aSAndroid Build Coastguard Worker   }
330*15dc779aSAndroid Build Coastguard Worker }
331*15dc779aSAndroid Build Coastguard Worker 
ixheaace_pvc_calc_ref_ene_update_tabs(ixheaace_pvc_enc * pstr_pvc_enc,FLOAT32 * ptr_sb_grp_energy_hi_ref)332*15dc779aSAndroid Build Coastguard Worker VOID ixheaace_pvc_calc_ref_ene_update_tabs(ixheaace_pvc_enc *pstr_pvc_enc,
333*15dc779aSAndroid Build Coastguard Worker                                            FLOAT32 *ptr_sb_grp_energy_hi_ref) {
334*15dc779aSAndroid Build Coastguard Worker   WORD32 ts, band;
335*15dc779aSAndroid Build Coastguard Worker   FLOAT32 sum, prev_sum = 0;
336*15dc779aSAndroid Build Coastguard Worker   pstr_pvc_enc->pvc_param.ns_mode = 0;
337*15dc779aSAndroid Build Coastguard Worker 
338*15dc779aSAndroid Build Coastguard Worker   switch (pstr_pvc_enc->pvc_param.pvc_mode) {
339*15dc779aSAndroid Build Coastguard Worker     case 1: {
340*15dc779aSAndroid Build Coastguard Worker       pstr_pvc_enc->pvc_param.time_smth_ts = IXHEAACE_ESBR_PVC_NUM_TS;
341*15dc779aSAndroid Build Coastguard Worker       pstr_pvc_enc->pvc_tabs.smoothing_coef = ixheaace_pvc_tabs.pvc_smth_win_ns_16;
342*15dc779aSAndroid Build Coastguard Worker       break;
343*15dc779aSAndroid Build Coastguard Worker     }
344*15dc779aSAndroid Build Coastguard Worker     case 2: {
345*15dc779aSAndroid Build Coastguard Worker       pstr_pvc_enc->pvc_param.time_smth_ts = 12;
346*15dc779aSAndroid Build Coastguard Worker       pstr_pvc_enc->pvc_tabs.smoothing_coef = ixheaace_pvc_tabs.pvc_smth_win_ns_12;
347*15dc779aSAndroid Build Coastguard Worker       break;
348*15dc779aSAndroid Build Coastguard Worker     }
349*15dc779aSAndroid Build Coastguard Worker     default: {
350*15dc779aSAndroid Build Coastguard Worker       // No assignment
351*15dc779aSAndroid Build Coastguard Worker       break;
352*15dc779aSAndroid Build Coastguard Worker     }
353*15dc779aSAndroid Build Coastguard Worker   }
354*15dc779aSAndroid Build Coastguard Worker 
355*15dc779aSAndroid Build Coastguard Worker   for (ts = 0; ts < IXHEAACE_ESBR_PVC_NUM_TS; ts++) {
356*15dc779aSAndroid Build Coastguard Worker     FLOAT32 *ptr_grp_energy =
357*15dc779aSAndroid Build Coastguard Worker         &(ptr_sb_grp_energy_hi_ref[ts * pstr_pvc_enc->pvc_param.num_grp_sbr]);
358*15dc779aSAndroid Build Coastguard Worker     sum = 0.0f;
359*15dc779aSAndroid Build Coastguard Worker     for (band = 0; band < pstr_pvc_enc->pvc_param.num_grp_sbr; band++) {
360*15dc779aSAndroid Build Coastguard Worker       sum += *ptr_grp_energy;
361*15dc779aSAndroid Build Coastguard Worker 
362*15dc779aSAndroid Build Coastguard Worker       *ptr_grp_energy = 10 * (FLOAT32)log10(*ptr_grp_energy);
363*15dc779aSAndroid Build Coastguard Worker       ptr_grp_energy++;
364*15dc779aSAndroid Build Coastguard Worker     }
365*15dc779aSAndroid Build Coastguard Worker     if (ts && (sum > prev_sum * IXHEAACE_ESBR_PVC_NS_MODE_PRD_THRS)) {
366*15dc779aSAndroid Build Coastguard Worker       pstr_pvc_enc->pvc_param.ns_mode = 1;
367*15dc779aSAndroid Build Coastguard Worker     }
368*15dc779aSAndroid Build Coastguard Worker     prev_sum = sum;
369*15dc779aSAndroid Build Coastguard Worker   }
370*15dc779aSAndroid Build Coastguard Worker 
371*15dc779aSAndroid Build Coastguard Worker   if (pstr_pvc_enc->pvc_param.ns_mode == 1) {
372*15dc779aSAndroid Build Coastguard Worker     switch (pstr_pvc_enc->pvc_param.pvc_mode) {
373*15dc779aSAndroid Build Coastguard Worker       case 1: {
374*15dc779aSAndroid Build Coastguard Worker         pstr_pvc_enc->pvc_param.time_smth_ts = 4;
375*15dc779aSAndroid Build Coastguard Worker         pstr_pvc_enc->pvc_tabs.smoothing_coef = ixheaace_pvc_tabs.pvc_smth_win_ns_4;
376*15dc779aSAndroid Build Coastguard Worker         break;
377*15dc779aSAndroid Build Coastguard Worker       }
378*15dc779aSAndroid Build Coastguard Worker       case 2: {
379*15dc779aSAndroid Build Coastguard Worker         pstr_pvc_enc->pvc_param.time_smth_ts = 3;
380*15dc779aSAndroid Build Coastguard Worker         pstr_pvc_enc->pvc_tabs.smoothing_coef = ixheaace_pvc_tabs.pvc_smth_win_ns_3;
381*15dc779aSAndroid Build Coastguard Worker         break;
382*15dc779aSAndroid Build Coastguard Worker       }
383*15dc779aSAndroid Build Coastguard Worker       default: {
384*15dc779aSAndroid Build Coastguard Worker         // No assignment
385*15dc779aSAndroid Build Coastguard Worker         break;
386*15dc779aSAndroid Build Coastguard Worker       }
387*15dc779aSAndroid Build Coastguard Worker     }
388*15dc779aSAndroid Build Coastguard Worker   }
389*15dc779aSAndroid Build Coastguard Worker }
390*15dc779aSAndroid Build Coastguard Worker 
ixheaace_pvc_encode_frame(ixheaace_pvc_enc * pstr_pvc_enc,UWORD8 pvc_mode,FLOAT32 * ptr_qmf_low,FLOAT32 * ptr_qmf_high,UWORD8 start_band,UWORD8 stop_band)391*15dc779aSAndroid Build Coastguard Worker IA_ERRORCODE ixheaace_pvc_encode_frame(ixheaace_pvc_enc *pstr_pvc_enc, UWORD8 pvc_mode,
392*15dc779aSAndroid Build Coastguard Worker                                        FLOAT32 *ptr_qmf_low, FLOAT32 *ptr_qmf_high,
393*15dc779aSAndroid Build Coastguard Worker                                        UWORD8 start_band, UWORD8 stop_band) {
394*15dc779aSAndroid Build Coastguard Worker   IA_ERRORCODE ret;
395*15dc779aSAndroid Build Coastguard Worker   FLOAT32 sb_grp_energy_hi_ref[IXHEAACE_ESBR_PVC_NUM_TS * 8];
396*15dc779aSAndroid Build Coastguard Worker 
397*15dc779aSAndroid Build Coastguard Worker   pstr_pvc_enc->pvc_param.pvc_mode = pvc_mode;
398*15dc779aSAndroid Build Coastguard Worker   /* PVC encoding process */
399*15dc779aSAndroid Build Coastguard Worker   if (pstr_pvc_enc->pvc_param.pvc_mode) {
400*15dc779aSAndroid Build Coastguard Worker     ret = ixheaace_set_pvc_mode_param(&(pstr_pvc_enc->pvc_param), &(pstr_pvc_enc->pvc_tabs));
401*15dc779aSAndroid Build Coastguard Worker     if (IA_NO_ERROR != ret) {
402*15dc779aSAndroid Build Coastguard Worker       return ret;
403*15dc779aSAndroid Build Coastguard Worker     }
404*15dc779aSAndroid Build Coastguard Worker 
405*15dc779aSAndroid Build Coastguard Worker     ixheaace_pvc_sb_grouping(pstr_pvc_enc, start_band, ptr_qmf_low,
406*15dc779aSAndroid Build Coastguard Worker                              (FLOAT32 *)pstr_pvc_enc->sb_grp_energy, 0);
407*15dc779aSAndroid Build Coastguard Worker 
408*15dc779aSAndroid Build Coastguard Worker     ixheaace_pvc_sb_grouping_ref(&(pstr_pvc_enc->pvc_param), start_band, stop_band, ptr_qmf_high,
409*15dc779aSAndroid Build Coastguard Worker                                  sb_grp_energy_hi_ref);
410*15dc779aSAndroid Build Coastguard Worker     ixheaace_pvc_calc_ref_ene_update_tabs(pstr_pvc_enc, sb_grp_energy_hi_ref);
411*15dc779aSAndroid Build Coastguard Worker 
412*15dc779aSAndroid Build Coastguard Worker     ixheaace_pvc_calc_grp_energy(pstr_pvc_enc, sb_grp_energy_hi_ref);
413*15dc779aSAndroid Build Coastguard Worker 
414*15dc779aSAndroid Build Coastguard Worker     ixheaace_pvc_packing(pstr_pvc_enc, pstr_pvc_enc->pvc_param.usac_indep_flag);
415*15dc779aSAndroid Build Coastguard Worker   }
416*15dc779aSAndroid Build Coastguard Worker 
417*15dc779aSAndroid Build Coastguard Worker   pstr_pvc_enc->pvc_prv_param.pvc_id =
418*15dc779aSAndroid Build Coastguard Worker       (pstr_pvc_enc->pvc_param.pvc_mode == 0)
419*15dc779aSAndroid Build Coastguard Worker           ? 0xFF
420*15dc779aSAndroid Build Coastguard Worker           : pstr_pvc_enc->pvc_param.pvc_id[IXHEAACE_ESBR_PVC_NUM_TS - 1];
421*15dc779aSAndroid Build Coastguard Worker   pstr_pvc_enc->pvc_prv_param.start_band = start_band;
422*15dc779aSAndroid Build Coastguard Worker   pstr_pvc_enc->pvc_prv_param.pvc_flag = (pstr_pvc_enc->pvc_param.pvc_mode == 0) ? 0 : 1;
423*15dc779aSAndroid Build Coastguard Worker   pstr_pvc_enc->pvc_prv_param.pvc_rate = pstr_pvc_enc->pvc_param.pvc_rate;
424*15dc779aSAndroid Build Coastguard Worker 
425*15dc779aSAndroid Build Coastguard Worker   return IA_NO_ERROR;
426*15dc779aSAndroid Build Coastguard Worker }
427