• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "ixheaacd_sbr_common.h"
21 #include <ixheaacd_type_def.h>
22 #include "string.h"
23 #include "ixheaacd_constants.h"
24 #include <ixheaacd_basic_ops32.h>
25 #include <ixheaacd_basic_ops16.h>
26 #include <ixheaacd_basic_ops40.h>
27 #include "ixheaacd_basic_ops.h"
28 
29 #include "ixheaacd_bitbuffer.h"
30 
31 #include "ixheaacd_error_codes.h"
32 #include "ixheaacd_defines.h"
33 #include <ixheaacd_aac_rom.h>
34 #include "ixheaacd_common_rom.h"
35 #include "ixheaacd_basic_funcs.h"
36 #include "ixheaacd_aac_imdct.h"
37 #include <ixheaacd_basic_op.h>
38 #include "ixheaacd_intrinsics.h"
39 
40 #include "ixheaacd_pulsedata.h"
41 
42 #include "ixheaacd_pns.h"
43 #include "ixheaacd_drc_data_struct.h"
44 
45 #include "ixheaacd_lt_predict.h"
46 #include "ixheaacd_channelinfo.h"
47 #include "ixheaacd_cnst.h"
48 #include "ixheaacd_drc_dec.h"
49 #include "ixheaacd_sbrdecoder.h"
50 #include "ixheaacd_block.h"
51 
52 #include "ixheaacd_channel.h"
53 
54 #include "ixheaacd_audioobjtypes.h"
55 #include "ixheaacd_latmdemux.h"
56 #include "ixheaacd_aacdec.h"
57 #include "ixheaacd_tns.h"
58 #include "ixheaacd_function_selector.h"
59 
60 #include <string.h>
61 #include <stdio.h>
62 #include <stdlib.h>
63 
ixheaacd_is_correlation(ia_aac_dec_channel_info_struct * ptr_aac_dec_channel_info,WORD16 pns_band)64 static PLATFORM_INLINE WORD16 ixheaacd_is_correlation(
65     ia_aac_dec_channel_info_struct *ptr_aac_dec_channel_info, WORD16 pns_band) {
66   ia_pns_correlation_info_struct *ptr_corr_info =
67       ptr_aac_dec_channel_info->pstr_pns_corr_info;
68 
69   return ((ptr_corr_info->correlated[(pns_band >> PNS_BAND_FLAGS_SHIFT)] >>
70            (pns_band & PNS_BAND_FLAGS_MASK)) &
71           1);
72 }
73 
ixheaacd_gen_rand_vec(WORD32 scale,WORD shift,WORD32 * ptr_spec_coef,WORD32 sfb_width,WORD32 * seed)74 VOID ixheaacd_gen_rand_vec(WORD32 scale, WORD shift, WORD32 *ptr_spec_coef,
75                            WORD32 sfb_width, WORD32 *seed) {
76   WORD nrg_scale;
77   WORD32 nrg = 0;
78   WORD32 *spec = ptr_spec_coef;
79   WORD32 sfb;
80 
81   for (sfb = 0; sfb <= sfb_width; sfb++) {
82     *seed = (WORD32)(((WORD64)1664525 * (WORD64)(*seed)) + (WORD64)1013904223);
83 
84     *spec = (*seed >> 3);
85 
86     nrg = ixheaacd_add32_sat(nrg, ixheaacd_mult32_shl_sat(*spec, *spec));
87 
88     spec++;
89   }
90 
91   nrg_scale = ixheaacd_norm32(nrg);
92 
93   if (nrg_scale > 0) {
94     nrg_scale &= ~1;
95     nrg = ixheaacd_shl32_sat(nrg, nrg_scale);
96     shift = shift - (nrg_scale >> 1);
97   }
98 
99   nrg = ixheaacd_sqrt(nrg);
100   scale = ixheaacd_div32_pos_normb(scale, nrg);
101 
102   spec = ptr_spec_coef;
103 
104   for (sfb = 0; sfb <= sfb_width; sfb++) {
105     *spec = ixheaacd_shr32_dir_sat_limit(ixheaacd_mult32_shl_sat(*spec, scale),
106                                          shift);
107     spec++;
108   }
109 }
110 
ixheaacd_pns_process(ia_aac_dec_channel_info_struct * ptr_aac_dec_channel_info[],WORD32 channel,ia_aac_dec_tables_struct * ptr_aac_tables)111 VOID ixheaacd_pns_process(
112     ia_aac_dec_channel_info_struct *ptr_aac_dec_channel_info[], WORD32 channel,
113     ia_aac_dec_tables_struct *ptr_aac_tables) {
114   ia_pns_info_struct *ptr_pns_info =
115       &ptr_aac_dec_channel_info[channel]->str_pns_info;
116   ia_ics_info_struct *ptr_ics_info =
117       &ptr_aac_dec_channel_info[channel]->str_ics_info;
118   WORD32 *ptr_scale_mant_tab =
119       ptr_aac_tables->pstr_block_tables->scale_mant_tab;
120 
121   if (ptr_pns_info->pns_active) {
122     const WORD16 *swb_offset =
123         ptr_aac_tables->str_aac_sfb_info[ptr_ics_info->window_sequence]
124             .sfb_index;
125 
126     WORD num_win_group, grp_len, sfb;
127     WORD32 *spec = &ptr_aac_dec_channel_info[channel]->ptr_spec_coeff[0];
128 
129     for (num_win_group = 0; num_win_group < ptr_ics_info->num_window_groups;
130          num_win_group++) {
131       grp_len = ptr_ics_info->window_group_length[num_win_group];
132 
133       for (grp_len = 0;
134            grp_len < ptr_ics_info->window_group_length[num_win_group];
135            grp_len++) {
136         for (sfb = 0; sfb < ptr_ics_info->max_sfb; sfb++) {
137           WORD16 pns_band = ((num_win_group << 4) + sfb);
138 
139           if (ptr_aac_dec_channel_info[channel]
140                   ->str_pns_info.pns_used[pns_band]) {
141             WORD32 scale_mant;
142             WORD32 scale_exp;
143             WORD32 sfb_width = swb_offset[sfb + 1] - swb_offset[sfb] - 1;
144             WORD32 *ptr_spec = &spec[swb_offset[sfb]];
145 
146             scale_mant = ptr_scale_mant_tab[ptr_aac_dec_channel_info[channel]
147                                                 ->ptr_scale_factor[pns_band] &
148                                             PNS_SCALE_MANT_TAB_MASK];
149             scale_exp = add_d(sub_d(31, (ptr_aac_dec_channel_info[channel]
150                                              ->ptr_scale_factor[pns_band] >>
151                                          PNS_SCALEFACTOR_SCALING)),
152                               PNS_SCALE_MANT_TAB_SCALING);
153 
154             if (ixheaacd_is_correlation(ptr_aac_dec_channel_info[LEFT],
155                                         pns_band)) {
156               if (channel == 0) {
157                 ptr_aac_dec_channel_info[LEFT]
158                     ->pstr_pns_corr_info->random_vector[pns_band] =
159                     ptr_aac_dec_channel_info[LEFT]
160                         ->pstr_pns_rand_vec_data->current_seed;
161 
162                 ixheaacd_gen_rand_vec(
163                     scale_mant, scale_exp, ptr_spec, sfb_width,
164                     &(ptr_aac_dec_channel_info[LEFT]
165                           ->pstr_pns_rand_vec_data->current_seed));
166               }
167 
168               else {
169                 ixheaacd_gen_rand_vec(
170                     scale_mant, scale_exp, ptr_spec, sfb_width,
171                     &(ptr_aac_dec_channel_info[LEFT]
172                           ->pstr_pns_corr_info->random_vector[pns_band]));
173               }
174 
175             }
176 
177             else {
178               ixheaacd_gen_rand_vec(
179                   scale_mant, scale_exp, ptr_spec, sfb_width,
180                   &(ptr_aac_dec_channel_info[LEFT]
181                         ->pstr_pns_rand_vec_data->current_seed));
182             }
183           }
184         }
185 
186         spec += 128;
187       }
188     }
189   }
190 
191   if (channel == 0) {
192     ptr_aac_dec_channel_info[0]->pstr_pns_rand_vec_data->pns_frame_number++;
193   }
194 }
195 
ixheaacd_tns_decode_coef(const ia_filter_info_struct * filter,WORD16 * parcor_coef,ia_aac_dec_tables_struct * ptr_aac_tables)196 VOID ixheaacd_tns_decode_coef(const ia_filter_info_struct *filter,
197                               WORD16 *parcor_coef,
198                               ia_aac_dec_tables_struct *ptr_aac_tables) {
199   WORD order, resolution;
200   WORD16 *ptr_par_coef = parcor_coef;
201   WORD16 *tns_coeff_ptr;
202   WORD8 ixheaacd_drc_offset = 4;
203   WORD8 *ptr_coef = (WORD8 *)filter->coef;
204 
205   resolution = filter->resolution;
206   tns_coeff_ptr = ptr_aac_tables->pstr_block_tables->tns_coeff3_16;
207 
208   if (resolution) {
209     tns_coeff_ptr = ptr_aac_tables->pstr_block_tables->tns_coeff4_16;
210     ixheaacd_drc_offset = ixheaacd_drc_offset << 1;
211   }
212 
213   for (order = 0; order < filter->order; order++) {
214     WORD8 temp = *ptr_coef++;
215     *ptr_par_coef++ = tns_coeff_ptr[temp + ixheaacd_drc_offset];
216   }
217 }
218 
ixheaacd_tns_decode_coef_ld(const ia_filter_info_struct * filter,WORD32 * parcor_coef,ia_aac_dec_tables_struct * ptr_aac_tables)219 VOID ixheaacd_tns_decode_coef_ld(const ia_filter_info_struct *filter,
220                                  WORD32 *parcor_coef,
221                                  ia_aac_dec_tables_struct *ptr_aac_tables) {
222   WORD order, resolution;
223   WORD32 *ptr_par_coef = parcor_coef;
224   WORD32 *tns_coeff_ptr;
225   WORD8 offset = 4;
226   WORD8 *ptr_coef = (WORD8 *)filter->coef;
227 
228   resolution = filter->resolution;
229   tns_coeff_ptr = ptr_aac_tables->pstr_block_tables->tns_coeff3;
230 
231   if (resolution) {
232     tns_coeff_ptr = ptr_aac_tables->pstr_block_tables->tns_coeff4;
233     offset = offset << 1;
234   }
235 
236   for (order = 0; order < filter->order; order++) {
237     WORD8 temp = *ptr_coef++;
238     *ptr_par_coef++ = tns_coeff_ptr[temp + offset];
239   }
240 }
241 
ixheaacd_aac_tns_process(ia_aac_dec_channel_info_struct * ptr_aac_dec_channel_info,WORD32 num_ch,ia_aac_dec_tables_struct * ptr_aac_tables,WORD32 object_type,WORD32 ar_flag,WORD32 * predicted_spectrum)242 VOID ixheaacd_aac_tns_process(
243     ia_aac_dec_channel_info_struct *ptr_aac_dec_channel_info, WORD32 num_ch,
244     ia_aac_dec_tables_struct *ptr_aac_tables, WORD32 object_type,
245     WORD32 ar_flag, WORD32 *predicted_spectrum) {
246   WORD i;
247   WORD16 scale_lpc;
248 
249   ia_tns_info_aac_struct *ptr_tns_info =
250       &ptr_aac_dec_channel_info->str_tns_info;
251   WORD32 *spec = ptr_aac_dec_channel_info->ptr_spec_coeff;
252   WORD32 *scratch_buf = ptr_aac_dec_channel_info->scratch_buf_ptr;
253 
254   WORD win, filt, start, stop, size, scale_spec;
255   ia_ics_info_struct *ptr_ics_info = &ptr_aac_dec_channel_info->str_ics_info;
256   WORD num_window, tns_max_bands, win_seq;
257   WORD position;
258 
259   WORD32 parcor_coef[MAX_ORDER + 1];
260   WORD16 parcor_coef_16[MAX_ORDER + 1];
261 
262   WORD32 lpc_coef[MAX_ORDER + 1];
263   WORD16 lpc_coef_16[MAX_ORDER + 1];
264 
265   const WORD16 *ptr_sfb_table;
266 
267   win_seq = ptr_ics_info->window_sequence == 0
268                 ? 0
269                 : (ptr_ics_info->window_sequence % 2 == 0);
270 
271   if (ar_flag)
272     spec = ptr_aac_dec_channel_info->ptr_spec_coeff;
273   else {
274     spec = predicted_spectrum;
275   }
276 
277   if (object_type == AOT_ER_AAC_ELD || object_type == AOT_ER_AAC_LD ||
278       object_type == AOT_AAC_LTP) {
279     if (512 == ptr_ics_info->frame_length) {
280       tns_max_bands =
281           ptr_aac_tables->pstr_block_tables
282               ->tns_max_bands_tbl_ld[ptr_ics_info->sampling_rate_index];
283       win_seq = 1;
284       num_window = win_seq;
285     } else if (480 == ptr_ics_info->frame_length) {
286       tns_max_bands =
287           ptr_aac_tables->pstr_block_tables
288               ->tns_max_bands_tbl_480[ptr_ics_info->sampling_rate_index];
289       win_seq = 1;
290       num_window = win_seq;
291     } else {
292       tns_max_bands =
293           ptr_aac_tables->pstr_block_tables
294               ->tns_max_bands_tbl[ptr_ics_info->sampling_rate_index][win_seq];
295 
296       num_window = win_seq ? 8 : 1;
297     }
298   } else {
299     tns_max_bands =
300         ptr_aac_tables->pstr_block_tables
301             ->tns_max_bands_tbl[ptr_ics_info->sampling_rate_index][win_seq];
302 
303     num_window = win_seq ? 8 : 1;
304   }
305 
306   ptr_sfb_table =
307       ptr_aac_tables->str_aac_sfb_info[ptr_ics_info->window_sequence].sfb_index;
308 
309   for (win = 0; win < num_window; win++) {
310     WORD n_filt = ptr_tns_info->n_filt[win];
311 
312     for (filt = 0; filt < n_filt; filt++) {
313       ia_filter_info_struct *filter = &ptr_tns_info->str_filter[win][filt];
314 
315       if (filter->order <= 0) {
316         continue;
317       }
318 
319       if ((object_type == AOT_ER_AAC_LD) || (object_type == AOT_AAC_LTP) ||
320           (num_ch > 2)) {
321         ixheaacd_tns_decode_coefficients(filter, parcor_coef, ptr_aac_tables);
322 
323       } else {
324         ixheaacd_tns_decode_coef(filter, parcor_coef_16, ptr_aac_tables);
325       }
326 
327       start = ixheaacd_min32(ixheaacd_min32(filter->start_band, tns_max_bands),
328                              ptr_ics_info->max_sfb);
329 
330       start = ptr_sfb_table[start];
331 
332       stop = ixheaacd_min32(ixheaacd_min32(filter->stop_band, tns_max_bands),
333                             ptr_ics_info->max_sfb);
334 
335       stop = ptr_sfb_table[stop];
336 
337       size = (stop - start);
338 
339       if (size <= 0) {
340         continue;
341       }
342       if ((object_type == AOT_ER_AAC_LD) || (object_type == AOT_AAC_LTP) ||
343           (num_ch > 2)) {
344         ixheaacd_tns_parcor_to_lpc(parcor_coef, lpc_coef, &scale_lpc,
345                                    filter->order);
346 
347       } else {
348         (*ixheaacd_tns_parcor_lpc_convert)(parcor_coef_16, lpc_coef_16,
349                                            &scale_lpc, filter->order);
350       }
351 
352       {
353         WORD32 *ptr_tmp = spec + (win << 7) + start;
354         scale_spec = (*ixheaacd_calc_max_spectral_line)(ptr_tmp, size);
355       }
356 
357       if (filter->direction == -1) {
358         position = stop - 1;
359       } else {
360         position = start;
361       }
362 
363       if ((num_ch <= 2) &&
364           ((object_type != AOT_ER_AAC_LD) && (object_type != AOT_AAC_LTP)))
365         scale_spec = ((scale_spec - 4) - scale_lpc);
366       else {
367         if (scale_spec > 17)
368           scale_spec = ((scale_spec - 6) - scale_lpc);
369         else if (scale_spec > 11)
370           scale_spec = ((scale_spec - 5) - scale_lpc);
371         else
372           scale_spec = ((scale_spec - 4) - scale_lpc);
373       }
374 
375       if (scale_spec > 0) {
376         scale_spec = ixheaacd_min32(scale_spec, 31);
377 
378         if ((object_type == AOT_ER_AAC_LD) || (object_type == AOT_AAC_LTP) ||
379             (num_ch > 2)) {
380           if (ar_flag)
381             (*ixheaacd_tns_ar_filter_fixed)(&spec[(win << 7) + position], size,
382                                             filter->direction,
383                                             (WORD32 *)lpc_coef, filter->order,
384                                             (WORD32)scale_lpc, scale_spec);
385           else
386             ixheaacd_tns_ma_filter_fixed_ld(&spec[(win << 7) + position], size,
387                                             filter->direction, lpc_coef,
388                                             filter->order, scale_lpc);
389 
390         } else {
391           if (object_type == AOT_ER_AAC_ELD) scale_spec = scale_spec - 1;
392 
393           (*ixheaacd_tns_ar_filter)(&spec[(win << 7) + position], size,
394                                     filter->direction, lpc_coef_16,
395                                     filter->order, (WORD32)scale_lpc,
396                                     scale_spec, scratch_buf);
397         }
398 
399       }
400 
401       else {
402         WORD32 *ptr_tmp = spec + (win << 7) + start;
403 
404         scale_spec = -scale_spec;
405         scale_spec = ixheaacd_min32(scale_spec, 31);
406 
407         for (i = size; i != 0; i--) {
408           *ptr_tmp = (*ptr_tmp >> scale_spec);
409           ptr_tmp++;
410         }
411 
412         if ((object_type == AOT_ER_AAC_LD) || (object_type == AOT_AAC_LTP) ||
413             num_ch > 2) {
414           if (ar_flag)
415             (*ixheaacd_tns_ar_filter_fixed)(
416                 &spec[(win << 7) + position], size, filter->direction,
417                 (WORD32 *)lpc_coef, filter->order, scale_lpc, 0);
418 
419           else
420             ixheaacd_tns_ma_filter_fixed_ld(&spec[(win << 7) + position], size,
421                                             filter->direction, lpc_coef,
422                                             filter->order, scale_lpc);
423         } else {
424           if (object_type == AOT_ER_AAC_ELD) {
425             scale_lpc = scale_lpc - 1;
426           }
427           (*ixheaacd_tns_ar_filter)(&spec[(win << 7) + position], size,
428                                     filter->direction, lpc_coef_16,
429                                     filter->order, scale_lpc, 0, scratch_buf);
430         }
431 
432         ptr_tmp = spec + (win << 7) + start;
433 
434         for (i = size; i != 0; i--) {
435           *ptr_tmp = (*ptr_tmp << scale_spec);
436           ptr_tmp++;
437         }
438       }
439     }
440   }
441 }
442