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