1 /******************************************************************************
2  *                                                                            *
3  * Copyright (C) 2018 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 #include <math.h>
21 #include "ixheaacd_type_def.h"
22 #include "ixheaacd_bitbuffer.h"
23 #include "ixheaacd_interface.h"
24 #include "ixheaacd_tns_usac.h"
25 #include "ixheaacd_cnst.h"
26 #include "ixheaacd_acelp_info.h"
27 #include "ixheaacd_sbrdecsettings.h"
28 #include "ixheaacd_info.h"
29 #include "ixheaacd_sbr_common.h"
30 #include "ixheaacd_drc_data_struct.h"
31 #include "ixheaacd_drc_dec.h"
32 #include "ixheaacd_sbrdecoder.h"
33 #include "ixheaacd_mps_polyphase.h"
34 #include "ixheaacd_main.h"
35 #include "ixheaacd_arith_dec.h"
36 #include "ixheaacd_func_def.h"
37 #include "ixheaacd_acelp_com.h"
38 
39 #include "ixheaacd_basic_op.h"
40 #include "ixheaacd_constants.h"
41 #include "ixheaacd_basic_ops32.h"
42 #include "ixheaacd_basic_ops40.h"
43 
44 #define LSF_GAP 50.0f
45 #define FREQ_MAX 6400.0f
46 #define FREQ_DIV 400.0f
47 
48 static const FLOAT32 factor_table[4] = {60.0f, 65.0f, 64.0f, 63.0f};
49 
ixheaacd_lsf_weight_2st_flt(FLOAT32 * lsfq,FLOAT32 * w,WORD32 mode)50 VOID ixheaacd_lsf_weight_2st_flt(FLOAT32 *lsfq, FLOAT32 *w, WORD32 mode) {
51   WORD32 i;
52   FLOAT32 d[ORDER + 1];
53 
54   d[0] = lsfq[0];
55   d[ORDER] = FREQ_MAX - lsfq[ORDER - 1];
56   for (i = 1; i < ORDER; i++) {
57     d[i] = lsfq[i] - lsfq[i - 1];
58   }
59 
60   for (i = 0; i < ORDER; i++) {
61     w[i] = (FLOAT32)(factor_table[mode] / (FREQ_DIV / sqrt(d[i] * d[i + 1])));
62   }
63 
64   return;
65 }
66 
ixheaacd_decoding_avq_tool(WORD32 * read_arr,WORD32 * nvecq)67 static WORD32 ixheaacd_decoding_avq_tool(WORD32 *read_arr, WORD32 *nvecq) {
68   WORD32 i, k, n, qn, nk, kv[8] = {0};
69   WORD32 code_book_idx;
70   WORD32 *ptr_kv = &kv[0];
71 
72   WORD32 position = 2;
73 
74   for (k = 0; k < 2; k++) {
75     qn = read_arr[k];
76 
77     nk = 0;
78     n = qn;
79     if (qn > 4) {
80       nk = (qn - 3) >> 1;
81       n = qn - nk * 2;
82     }
83 
84     if (qn > 0) {
85       code_book_idx = read_arr[position++];
86 
87       ptr_kv = &read_arr[position];
88       position += 8;
89 
90     } else {
91       code_book_idx = 0;
92       for (i = 0; i < 8; i++) ptr_kv = &kv[0];
93     }
94 
95     ixheaacd_rotated_gosset_mtx_dec(qn, code_book_idx, ptr_kv, &nvecq[k * 8]);
96   }
97 
98   return position;
99 }
100 
ixheaacd_avq_first_approx_abs(FLOAT32 * lsf,WORD32 * indx)101 static WORD32 ixheaacd_avq_first_approx_abs(FLOAT32 *lsf, WORD32 *indx) {
102   WORD32 i;
103   extern const FLOAT32 ixheaacd_dico_lsf_abs_8b_flt[];
104   extern const FLOAT32 ixheaacd_weight_table_avq[];
105   WORD32 position = 0;
106   WORD32 avq[ORDER];
107   FLOAT32 d[ORDER + 1], lsf_min;
108   const FLOAT32 *ptr_w;
109 
110   ptr_w = &ixheaacd_weight_table_avq[(indx[0] * ORDER)];
111 
112   position++;
113 
114   for (i = 0; i < ORDER; i++) {
115     lsf[i] = ixheaacd_dico_lsf_abs_8b_flt[indx[0] * ORDER + i];
116   }
117 
118   position += ixheaacd_decoding_avq_tool(&indx[position], avq);
119 
120   d[0] = lsf[0];
121   d[ORDER] = FREQ_MAX - lsf[ORDER - 1];
122   for (i = 1; i < ORDER; i++) {
123     d[i] = lsf[i] - lsf[i - 1];
124   }
125 
126   lsf_min = LSF_GAP;
127   for (i = 0; i < ORDER; i++) {
128     lsf[i] += (ptr_w[i] * avq[i]);
129 
130     if (lsf[i] < lsf_min) lsf[i] = lsf_min;
131 
132     lsf_min = lsf[i] + LSF_GAP;
133   }
134 
135   return position;
136 }
137 
ixheaacd_avq_first_approx_rel(FLOAT32 * lsf,WORD32 * indx,WORD32 mode)138 WORD32 ixheaacd_avq_first_approx_rel(FLOAT32 *lsf, WORD32 *indx, WORD32 mode) {
139   WORD32 i;
140   FLOAT32 w[ORDER];
141   WORD32 avq[ORDER];
142   WORD32 position = 0;
143   FLOAT32 lsf_min;
144 
145   ixheaacd_lsf_weight_2st_flt(lsf, w, mode);
146 
147   position = ixheaacd_decoding_avq_tool(indx, avq);
148 
149   lsf_min = LSF_GAP;
150 
151   for (i = 0; i < ORDER; i++) {
152     lsf[i] += (w[i] * avq[i]);
153 
154     if (lsf[i] < lsf_min) lsf[i] = lsf_min;
155 
156     lsf_min = lsf[i] + LSF_GAP;
157   }
158 
159   return position;
160 }
161 
ixheaacd_alg_vec_dequant(ia_td_frame_data_struct * pstr_td_frame_data,WORD32 first_lpd_flag,FLOAT32 * lsf,WORD32 mod[])162 VOID ixheaacd_alg_vec_dequant(ia_td_frame_data_struct *pstr_td_frame_data,
163                               WORD32 first_lpd_flag, FLOAT32 *lsf,
164                               WORD32 mod[]) {
165   WORD32 i;
166   WORD32 *lpc_index, mode_lpc, pos = 0;
167 
168   lpc_index = pstr_td_frame_data->lpc_first_approx_idx;
169 
170   pos = ixheaacd_avq_first_approx_abs(&lsf[4 * ORDER], &lpc_index[0]);
171 
172   lpc_index += pos;
173 
174   if (first_lpd_flag) {
175     mode_lpc = lpc_index[0];
176     lpc_index++;
177 
178     if (mode_lpc == 0) {
179       pos = ixheaacd_avq_first_approx_abs(&lsf[0], &lpc_index[0]);
180 
181     } else if (mode_lpc == 1) {
182       for (i = 0; i < ORDER; i++) lsf[i] = lsf[4 * ORDER + i];
183       pos = ixheaacd_avq_first_approx_rel(&lsf[0], &lpc_index[0], 3);
184     }
185 
186     lpc_index += pos;
187   }
188 
189   if (mod[0] < 3) {
190     mode_lpc = lpc_index[0];
191     lpc_index++;
192 
193     if (mode_lpc == 0) {
194       pos = ixheaacd_avq_first_approx_abs(&lsf[2 * ORDER], &lpc_index[0]);
195     } else if (mode_lpc == 1) {
196       for (i = 0; i < ORDER; i++) lsf[2 * ORDER + i] = lsf[4 * ORDER + i];
197       pos = ixheaacd_avq_first_approx_rel(&lsf[2 * ORDER], &lpc_index[0], 3);
198     }
199 
200     lpc_index += pos;
201   }
202 
203   if (mod[0] < 2) {
204     mode_lpc = lpc_index[0];
205     lpc_index++;
206 
207     if (mode_lpc == 1) {
208       for (i = 0; i < ORDER; i++)
209         lsf[ORDER + i] = 0.5f * (lsf[i] + lsf[2 * ORDER + i]);
210     } else {
211       if (mode_lpc == 0) {
212         pos = ixheaacd_avq_first_approx_abs(&lsf[ORDER], &lpc_index[0]);
213       } else if (mode_lpc == 2) {
214         for (i = 0; i < ORDER; i++) lsf[ORDER + i] = lsf[2 * ORDER + i];
215         pos = ixheaacd_avq_first_approx_rel(&lsf[ORDER], &lpc_index[0], 2);
216       }
217 
218       lpc_index += pos;
219     }
220   }
221 
222   if (mod[2] < 2) {
223     mode_lpc = lpc_index[0];
224     lpc_index++;
225 
226     if (mode_lpc == 0) {
227       pos = ixheaacd_avq_first_approx_abs(&lsf[3 * ORDER], &lpc_index[0]);
228     } else if (mode_lpc == 1) {
229       for (i = 0; i < ORDER; i++)
230         lsf[3 * ORDER + i] = 0.5f * (lsf[2 * ORDER + i] + lsf[4 * ORDER + i]);
231       pos = ixheaacd_avq_first_approx_rel(&lsf[3 * ORDER], &lpc_index[0], 1);
232     } else if (mode_lpc == 2) {
233       for (i = 0; i < ORDER; i++) lsf[3 * ORDER + i] = lsf[2 * ORDER + i];
234       pos = ixheaacd_avq_first_approx_rel(&lsf[3 * ORDER], &lpc_index[0], 2);
235     } else if (mode_lpc == 3) {
236       for (i = 0; i < ORDER; i++) lsf[3 * ORDER + i] = lsf[4 * ORDER + i];
237       pos = ixheaacd_avq_first_approx_rel(&lsf[3 * ORDER], &lpc_index[0], 2);
238     }
239 
240     lpc_index += pos;
241   }
242 }