/src/libxaac/decoder/ixheaacd_mps_temp_reshape.c
Line | Count | Source |
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 "ixheaac_type_def.h" |
22 | | #include "ixheaac_constants.h" |
23 | | #include "ixheaacd_bitbuffer.h" |
24 | | #include "ixheaacd_common_rom.h" |
25 | | #include "ixheaacd_sbrdecsettings.h" |
26 | | #include "ixheaacd_sbr_scale.h" |
27 | | #include "ixheaacd_env_extr_part.h" |
28 | | #include "ixheaacd_sbr_rom.h" |
29 | | #include "ixheaacd_hybrid.h" |
30 | | #include "ixheaacd_ps_dec.h" |
31 | | #include "ixheaacd_config.h" |
32 | | #include "ixheaacd_qmf_dec.h" |
33 | | #include "ixheaacd_mps_polyphase.h" |
34 | | #include "ixheaacd_mps_struct_def.h" |
35 | | #include "ixheaacd_mps_res_rom.h" |
36 | | #include "ixheaacd_mps_aac_struct.h" |
37 | | #include "ixheaacd_mps_dec.h" |
38 | | |
39 | 19.4k | #define DIR_DIFF_IN 0 |
40 | 9.73k | #define DOWNMIX_IN 1 |
41 | | |
42 | | #define LAMDA (4.0f) |
43 | 10.6M | #define GES_ALPHA (0.99637864f) |
44 | 1.06M | #define GES_BETA (0.9643691f) |
45 | | |
46 | | extern const WORD32 |
47 | | ixheaacd_hybrid_band_71_to_processing_band_20_map[MAX_HYBRID_BANDS_MPS]; |
48 | | |
49 | 2.29k | VOID ixheaacd_mps_env_init(ia_mps_dec_state_struct *self) { |
50 | 2.29k | WORD32 i; |
51 | 9.19k | for (i = 0; i < 3; i++) { |
52 | 6.89k | self->guided_env_shaping.avg_energy_prev[i] = 32768.f * 32768.f; |
53 | 6.89k | } |
54 | 2.29k | } |
55 | | |
56 | | static VOID ixheaacd_mps_est_normalized_envelope(ia_mps_dec_state_struct *self, |
57 | | WORD32 inp, WORD32 ch, |
58 | 14.5k | FLOAT32 *env) { |
59 | 14.5k | FLOAT32 slot_energy[MAX_TIME_SLOTS][MAX_PARAMETER_BANDS] = {{0}}; |
60 | 14.5k | FLOAT32 pb_energy[MAX_PARAMETER_BANDS] = {0}; |
61 | 14.5k | FLOAT32 whitening_weight[MAX_PARAMETER_BANDS]; |
62 | 14.5k | WORD32 ii, jj, param_band; |
63 | | |
64 | 14.5k | WORD32 k_start = 10; |
65 | 14.5k | WORD32 k_stop = 18; |
66 | | |
67 | 14.5k | FLOAT32 total_energy = 0, avg_energy = 0; |
68 | | |
69 | 14.5k | WORD32 ch_offset; |
70 | | |
71 | 14.5k | switch (inp) { |
72 | 9.73k | case DIR_DIFF_IN: |
73 | 9.73k | ch_offset = 0; |
74 | 363k | for (ii = 0; ii < self->time_slots; ii++) { |
75 | 14.0M | for (jj = 0; jj < self->hyb_band_count_max; jj++) { |
76 | 13.7M | slot_energy[ii] |
77 | 13.7M | [ixheaacd_hybrid_band_71_to_processing_band_20_map[jj]] += |
78 | 13.7M | ((self->hyb_dir_out[ch][ii][jj].re + |
79 | 13.7M | self->hyb_diff_out[ch][ii][jj].re) * |
80 | 13.7M | (self->hyb_dir_out[ch][ii][jj].re + |
81 | 13.7M | self->hyb_diff_out[ch][ii][jj].re)) + |
82 | 13.7M | ((self->hyb_dir_out[ch][ii][jj].im + |
83 | 13.7M | self->hyb_diff_out[ch][ii][jj].im) * |
84 | 13.7M | (self->hyb_dir_out[ch][ii][jj].im + |
85 | 13.7M | self->hyb_diff_out[ch][ii][jj].im)); |
86 | 13.7M | } |
87 | 353k | } |
88 | 9.73k | break; |
89 | 4.86k | case DOWNMIX_IN: |
90 | 4.86k | ch_offset = self->out_ch_count; |
91 | 4.86k | if ((self->pre_mix_req | self->bs_tsd_enable)) { |
92 | 19.4k | for (ii = 0; ii < self->time_slots; ii++) { |
93 | 1.04M | for (jj = 0; jj < self->hyb_band_count_max; jj++) { |
94 | 1.02M | slot_energy |
95 | 1.02M | [ii][ixheaacd_hybrid_band_71_to_processing_band_20_map[jj]] += |
96 | 1.02M | self->hyb_in[ch][jj][ii].re * self->hyb_in[ch][jj][ii].re + |
97 | 1.02M | self->hyb_in[ch][jj][ii].im * self->hyb_in[ch][jj][ii].im; |
98 | 1.02M | } |
99 | 18.8k | } |
100 | 4.27k | } else { |
101 | 162k | for (ii = 0; ii < self->time_slots; ii++) { |
102 | 5.99M | for (jj = 0; jj < self->hyb_band_count_max; jj++) { |
103 | 5.83M | slot_energy |
104 | 5.83M | [ii][ixheaacd_hybrid_band_71_to_processing_band_20_map[jj]] += |
105 | 5.83M | self->w_dir[ch][ii][jj].re * self->w_dir[ch][ii][jj].re + |
106 | 5.83M | self->w_dir[ch][ii][jj].im * self->w_dir[ch][ii][jj].im; |
107 | 5.83M | } |
108 | 157k | } |
109 | 4.27k | } |
110 | | |
111 | 4.86k | break; |
112 | 0 | default: |
113 | 0 | ch_offset = 0; |
114 | 0 | break; |
115 | 14.5k | } |
116 | | |
117 | 145k | for (param_band = k_start; param_band <= k_stop; param_band++) |
118 | 131k | pb_energy[param_band] = |
119 | 131k | self->guided_env_shaping.pb_energy_prev[ch + ch_offset][param_band]; |
120 | | |
121 | 14.5k | avg_energy = self->guided_env_shaping.avg_energy_prev[ch + ch_offset]; |
122 | | |
123 | 544k | for (ii = 0; ii < self->time_slots; ii++) { |
124 | 530k | total_energy = 0; |
125 | 5.30M | for (param_band = k_start; param_band <= k_stop; param_band++) { |
126 | 4.77M | pb_energy[param_band] = (1 - GES_ALPHA) * slot_energy[ii][param_band] + |
127 | 4.77M | GES_ALPHA * pb_energy[param_band]; |
128 | | |
129 | 4.77M | total_energy += slot_energy[ii][param_band]; |
130 | 4.77M | } |
131 | 530k | total_energy /= (k_stop - k_start + 1); |
132 | | |
133 | 530k | total_energy = |
134 | 530k | (1 - GES_ALPHA) * total_energy + |
135 | 530k | GES_ALPHA * self->guided_env_shaping.frame_energy_prev[ch + ch_offset]; |
136 | | |
137 | 530k | self->guided_env_shaping.frame_energy_prev[ch + ch_offset] = total_energy; |
138 | | |
139 | 5.30M | for (param_band = k_start; param_band <= k_stop; param_band++) { |
140 | 4.77M | whitening_weight[param_band] = |
141 | 4.77M | total_energy / (pb_energy[param_band] + ABS_THR); |
142 | 4.77M | } |
143 | | |
144 | 530k | env[ii] = 0; |
145 | 5.30M | for (param_band = k_start; param_band <= k_stop; param_band++) { |
146 | 4.77M | env[ii] += slot_energy[ii][param_band] * whitening_weight[param_band]; |
147 | 4.77M | } |
148 | | |
149 | 530k | avg_energy = (1 - GES_BETA) * env[ii] + GES_BETA * avg_energy; |
150 | | |
151 | 530k | env[ii] = (FLOAT32)sqrt(env[ii] / (avg_energy + ABS_THR)); |
152 | 530k | } |
153 | | |
154 | 145k | for (param_band = k_start; param_band <= k_stop; param_band++) |
155 | 131k | self->guided_env_shaping.pb_energy_prev[ch + ch_offset][param_band] = |
156 | 131k | pb_energy[param_band]; |
157 | | |
158 | 14.5k | self->guided_env_shaping.avg_energy_prev[ch + ch_offset] = avg_energy; |
159 | 14.5k | } |
160 | | |
161 | 4.86k | VOID ixheaacd_mps_time_env_shaping(ia_mps_dec_state_struct *self) { |
162 | 4.86k | FLOAT32 dir_energy[MAX_TIME_SLOTS]; |
163 | 4.86k | FLOAT32 dmx_energy[MAX_TIME_SLOTS]; |
164 | 4.86k | WORD32 ch, time_slot, jj; |
165 | | |
166 | 4.86k | WORD32 band_start; |
167 | 4.86k | FLOAT32 gain, ratio; |
168 | | |
169 | 4.86k | FLOAT32 amp_direct = 0; |
170 | 4.86k | FLOAT32 amp_diff = 0; |
171 | 4.86k | FLOAT32 amp_ratio; |
172 | | |
173 | 4.86k | band_start = 6; |
174 | | |
175 | 4.86k | ixheaacd_mps_est_normalized_envelope(self, DOWNMIX_IN, 0, dmx_energy); |
176 | | |
177 | 14.5k | for (ch = 0; ch < self->out_ch_count; ch++) { |
178 | 9.73k | ixheaacd_mps_est_normalized_envelope(self, DIR_DIFF_IN, ch, dir_energy); |
179 | | |
180 | 9.73k | if (self->temp_shape_enable_ch_ges[ch]) { |
181 | 33.0k | for (time_slot = 0; time_slot < self->time_slots; time_slot++) { |
182 | 32.0k | gain = self->env_shape_data[ch][time_slot] * dmx_energy[time_slot] / |
183 | 32.0k | (dir_energy[time_slot] + 1e-9f); |
184 | | |
185 | 32.0k | amp_direct = 0; |
186 | 32.0k | amp_diff = 0; |
187 | | |
188 | 1.20M | for (jj = band_start; jj < self->hyb_band_count_max; jj++) { |
189 | 1.17M | amp_direct += self->hyb_dir_out[ch][time_slot][jj].re * |
190 | 1.17M | self->hyb_dir_out[ch][time_slot][jj].re + |
191 | 1.17M | self->hyb_dir_out[ch][time_slot][jj].im * |
192 | 1.17M | self->hyb_dir_out[ch][time_slot][jj].im; |
193 | | |
194 | 1.17M | amp_diff += self->hyb_diff_out[ch][time_slot][jj].re * |
195 | 1.17M | self->hyb_diff_out[ch][time_slot][jj].re + |
196 | 1.17M | self->hyb_diff_out[ch][time_slot][jj].im * |
197 | 1.17M | self->hyb_diff_out[ch][time_slot][jj].im; |
198 | 1.17M | } |
199 | | |
200 | 32.0k | amp_ratio = (FLOAT32)sqrt(amp_diff / (amp_direct + ABS_THR)); |
201 | | |
202 | 32.0k | ratio = min(max((gain + amp_ratio * (gain - 1)), 1 / LAMDA), LAMDA); |
203 | | |
204 | 1.20M | for (jj = band_start; jj < self->hyb_band_count_max; jj++) { |
205 | 1.17M | self->hyb_dir_out[ch][time_slot][jj].re *= ratio; |
206 | 1.17M | self->hyb_dir_out[ch][time_slot][jj].im *= ratio; |
207 | 1.17M | } |
208 | 32.0k | } |
209 | 943 | } |
210 | 9.73k | } |
211 | 4.86k | } |