xref: /aosp_15_r20/external/libxaac/encoder/ixheaace_group_data.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 <stdlib.h>
23 #include "ixheaac_type_def.h"
24 #include "ixheaac_constants.h"
25 #include "ixheaace_psy_const.h"
26 #include "ixheaace_tns.h"
27 #include "ixheaace_tns_params.h"
28 #include "ixheaace_rom.h"
29 #include "ixheaace_common_rom.h"
30 #include "ixheaace_bitbuffer.h"
31 #include "ixheaace_aac_constants.h"
32 #include "ixheaace_block_switch.h"
33 #include "ixheaace_psy_data.h"
34 #include "ixheaace_interface.h"
35 #include "ixheaace_group_data.h"
36 
37 #include "ixheaac_basic_ops32.h"
38 #include "ixheaac_basic_ops16.h"
39 #include "ixheaac_basic_ops40.h"
40 #include "ixheaac_basic_ops.h"
41 
iaace_group_short_data(FLOAT32 * ptr_mdct_spectrum,FLOAT32 * ptr_tmp_spectrum,ixheaace_sfb_energy * pstr_sfb_threshold,ixheaace_sfb_energy * pstr_sfb_energy,ixheaace_sfb_energy * pstr_sfb_energy_ms,ixheaace_sfb_energy * pstr_sfb_spreaded_energy,const WORD32 sfb_cnt,const WORD32 * ptr_sfb_offset,const FLOAT32 * ptr_sfb_min_snr,WORD32 * ptr_grouped_sfb_offset,WORD32 * ptr_max_sfb_per_group,FLOAT32 * ptr_grouped_sfb_min_snr,const WORD32 no_of_groups,const WORD32 * ptr_group_len,WORD32 frame_length)42 VOID iaace_group_short_data(FLOAT32 *ptr_mdct_spectrum, FLOAT32 *ptr_tmp_spectrum,
43                             ixheaace_sfb_energy *pstr_sfb_threshold,
44                             ixheaace_sfb_energy *pstr_sfb_energy,
45                             ixheaace_sfb_energy *pstr_sfb_energy_ms,
46                             ixheaace_sfb_energy *pstr_sfb_spreaded_energy, const WORD32 sfb_cnt,
47                             const WORD32 *ptr_sfb_offset, const FLOAT32 *ptr_sfb_min_snr,
48                             WORD32 *ptr_grouped_sfb_offset, WORD32 *ptr_max_sfb_per_group,
49                             FLOAT32 *ptr_grouped_sfb_min_snr, const WORD32 no_of_groups,
50                             const WORD32 *ptr_group_len, WORD32 frame_length) {
51   WORD32 i, j;
52   WORD32 line;
53   WORD32 sfb;
54   WORD32 grp;
55   WORD32 wnd;
56   WORD32 offset;
57   WORD32 highest_sfb;
58 
59   /* For short: regroup and cumulate energies und thresholds group-wise */
60   /* Calculate sfb_cnt */
61 
62   highest_sfb = 0;
63 
64   for (wnd = 0; wnd < TRANS_FAC; wnd++) {
65     for (sfb = sfb_cnt - 1; sfb >= highest_sfb; sfb--) {
66       for (line = ptr_sfb_offset[sfb + 1] - 1; line >= ptr_sfb_offset[sfb]; line--) {
67         if (ptr_mdct_spectrum[wnd * (frame_length / 8) + line] != 0.0) {
68           break;
69         }
70       }
71 
72       if (line >= ptr_sfb_offset[sfb]) {
73         break;
74       }
75     }
76     highest_sfb = MAX(highest_sfb, sfb);
77   }
78 
79   highest_sfb = highest_sfb > 0 ? highest_sfb : 0;
80 
81   *ptr_max_sfb_per_group = highest_sfb + 1;
82 
83   /* Calculate ptr_sfb_offset */
84   i = 0;
85   offset = 0;
86 
87   for (grp = 0; grp < no_of_groups; grp++) {
88     for (sfb = 0; sfb < sfb_cnt; sfb++) {
89       ptr_grouped_sfb_offset[i++] = offset + ptr_sfb_offset[sfb] * ptr_group_len[grp];
90     }
91 
92     offset += ptr_group_len[grp] * (frame_length / 8);
93   }
94 
95   ptr_grouped_sfb_offset[i++] = frame_length;
96 
97   /* Calculate min SNR */
98 
99   i = 0;
100   offset = 0;
101 
102   for (grp = 0; grp < no_of_groups; grp++) {
103     memcpy(&ptr_grouped_sfb_min_snr[i], &ptr_sfb_min_snr[0], sfb_cnt * sizeof(*ptr_sfb_min_snr));
104     i += sfb_cnt;
105 
106     offset += ptr_group_len[grp] * (frame_length / 8);
107   }
108 
109   wnd = 0;
110   i = 0;
111 
112   for (grp = 0; grp < no_of_groups; grp++) {
113     for (sfb = 0; sfb < sfb_cnt; sfb++) {
114       FLOAT32 thresh = pstr_sfb_threshold->short_nrg[wnd][sfb];
115 
116       for (j = 1; j < ptr_group_len[grp]; j++) {
117         thresh += pstr_sfb_threshold->short_nrg[wnd + j][sfb];
118       }
119 
120       pstr_sfb_threshold->long_nrg[i++] = thresh;
121     }
122     wnd += ptr_group_len[grp];
123   }
124 
125   /* Sum up sfb energies -  left/right */
126   wnd = 0;
127   i = 0;
128 
129   for (grp = 0; grp < no_of_groups; grp++) {
130     for (sfb = 0; sfb < sfb_cnt; sfb++) {
131       FLOAT32 energy = pstr_sfb_energy->short_nrg[wnd][sfb];
132 
133       for (j = 1; j < ptr_group_len[grp]; j++) {
134         energy += pstr_sfb_energy->short_nrg[wnd + j][sfb];
135       }
136 
137       pstr_sfb_energy->long_nrg[i++] = energy;
138     }
139     wnd += ptr_group_len[grp];
140   }
141 
142   /* Sum up sfb energies mid/side */
143   wnd = 0;
144   i = 0;
145 
146   for (grp = 0; grp < no_of_groups; grp++) {
147     for (sfb = 0; sfb < sfb_cnt; sfb++) {
148       FLOAT32 energy = pstr_sfb_energy_ms->short_nrg[wnd][sfb];
149 
150       for (j = 1; j < ptr_group_len[grp]; j++) {
151         energy += pstr_sfb_energy_ms->short_nrg[wnd + j][sfb];
152       }
153 
154       pstr_sfb_energy_ms->long_nrg[i++] = energy;
155     }
156     wnd += ptr_group_len[grp];
157   }
158 
159   /* Sum up sfb spreaded energies */
160   wnd = 0;
161   i = 0;
162 
163   for (grp = 0; grp < no_of_groups; grp++) {
164     for (sfb = 0; sfb < sfb_cnt; sfb++) {
165       FLOAT32 energy = pstr_sfb_spreaded_energy->short_nrg[wnd][sfb];
166 
167       for (j = 1; j < ptr_group_len[grp]; j++) {
168         energy += pstr_sfb_spreaded_energy->short_nrg[wnd + j][sfb];
169       }
170       pstr_sfb_spreaded_energy->long_nrg[i++] = energy;
171     }
172     wnd += ptr_group_len[grp];
173   }
174 
175   /* Re-group spectrum */
176   wnd = 0;
177   i = 0;
178 
179   for (grp = 0; grp < no_of_groups; grp++) {
180     for (sfb = 0; sfb < sfb_cnt; sfb++) {
181       for (j = 0; j < ptr_group_len[grp]; j++) {
182         for (line = ptr_sfb_offset[sfb]; line < ptr_sfb_offset[sfb + 1]; line++) {
183           ptr_tmp_spectrum[i++] = ptr_mdct_spectrum[(wnd + j) * (frame_length / 8) + line];
184         }
185       }
186     }
187     wnd += ptr_group_len[grp];
188   }
189 
190   memcpy(ptr_mdct_spectrum, ptr_tmp_spectrum, frame_length * sizeof(*ptr_mdct_spectrum));
191 }
192