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 <stdlib.h>
22 #include <string.h>
23 #include <math.h>
24 #include <float.h>
25 #include "ixheaac_type_def.h"
26 #include "ixheaac_error_standards.h"
27 #include "ixheaace_error_codes.h"
28
29 #include "iusace_cnst.h"
30 #include "iusace_bitbuffer.h"
31 #include "impd_drc_common_enc.h"
32 #include "impd_drc_uni_drc.h"
33 #include "impd_drc_api.h"
34 #include "impd_drc_uni_drc_eq.h"
35 #include "impd_drc_uni_drc_filter_bank.h"
36 #include "impd_drc_gain_enc.h"
37 #include "impd_drc_struct_def.h"
38 #include "impd_drc_tables.h"
39 #include "impd_drc_enc.h"
40 #include "impd_drc_mux.h"
41 #include "iusace_block_switch_const.h"
42
43 #include "iusace_tns_usac.h"
44 #include "iusace_psy_mod.h"
45 #include "ixheaace_sbr_header.h"
46 #include "ixheaace_config.h"
47 #include "iusace_config.h"
48 #include "ixheaace_common_utils.h"
49
impd_drc_limit_drc_gain(const WORD32 gain_coding_profile,const FLOAT32 gain)50 static FLOAT32 impd_drc_limit_drc_gain(const WORD32 gain_coding_profile, const FLOAT32 gain) {
51 FLOAT32 limited_drc_gain;
52
53 switch (gain_coding_profile) {
54 case GAIN_CODING_PROFILE_CONSTANT:
55 limited_drc_gain = gain;
56 break;
57 case GAIN_CODING_PROFILE_CLIPPING:
58 limited_drc_gain =
59 MAX(MIN(MAX_DRC_GAIN_CODING_PROFILE2, gain), MIN_DRC_GAIN_CODING_PROFILE2);
60 break;
61 case GAIN_CODING_PROFILE_FADING:
62 limited_drc_gain =
63 MAX(MIN(MAX_DRC_GAIN_CODING_PROFILE1, gain), MIN_DRC_GAIN_CODING_PROFILE1);
64 break;
65 case GAIN_CODING_PROFILE_REGULAR:
66 limited_drc_gain =
67 MAX(MIN(MAX_DRC_GAIN_CODING_PROFILE0, gain), MIN_DRC_GAIN_CODING_PROFILE0);
68 break;
69 default:
70 limited_drc_gain = gain;
71 break;
72 }
73
74 return limited_drc_gain;
75 }
76
impd_drc_get_quantized_delta_drc_gain(const WORD32 gain_coding_profile,const FLOAT32 delta_gain,FLOAT32 * delta_gain_quant,WORD32 * num_bits,WORD32 * gain_code)77 static VOID impd_drc_get_quantized_delta_drc_gain(const WORD32 gain_coding_profile,
78 const FLOAT32 delta_gain,
79 FLOAT32 *delta_gain_quant, WORD32 *num_bits,
80 WORD32 *gain_code) {
81 LOOPIDX idx;
82 WORD32 num_entries, opt_index;
83 WORD32 min_pos_diff_idx = 0;
84 WORD32 min_neg_diff_idx = 0;
85 FLOAT32 difference;
86 FLOAT32 min_pos_diff = 1000.0f;
87 FLOAT32 min_neg_diff = -1000.0f;
88 ia_drc_delta_gain_code_entry_struct const *pstr_delta_gain_code_table;
89
90 impd_drc_get_delta_gain_code_table(gain_coding_profile, &pstr_delta_gain_code_table,
91 &num_entries);
92 for (idx = 0; idx < num_entries; idx++) {
93 difference = delta_gain - pstr_delta_gain_code_table[idx].value;
94 if (difference <= 0.0f) {
95 if (difference > min_neg_diff) {
96 min_neg_diff = difference;
97 min_neg_diff_idx = idx;
98 }
99 } else {
100 if (difference < min_pos_diff) {
101 min_pos_diff = difference;
102 min_pos_diff_idx = idx;
103 }
104 }
105 }
106 if (min_pos_diff >= -min_neg_diff) {
107 opt_index = min_neg_diff_idx;
108 } else {
109 opt_index = min_pos_diff_idx;
110 }
111
112 *delta_gain_quant = pstr_delta_gain_code_table[opt_index].value;
113 *num_bits = pstr_delta_gain_code_table[opt_index].size;
114 *gain_code = pstr_delta_gain_code_table[opt_index].code;
115 }
116
impd_drc_check_overshoot(const WORD32 t_gain_step,const FLOAT32 gain_0,const FLOAT32 gain_1,const FLOAT32 slope_0,const FLOAT32 slope_1,const WORD32 time_delta_min,WORD32 * overshoot_left,WORD32 * overshoot_right)117 static VOID impd_drc_check_overshoot(const WORD32 t_gain_step, const FLOAT32 gain_0,
118 const FLOAT32 gain_1, const FLOAT32 slope_0,
119 const FLOAT32 slope_1, const WORD32 time_delta_min,
120 WORD32 *overshoot_left, WORD32 *overshoot_right) {
121 WORD32 t_connect;
122 FLOAT32 norm_slope_0, norm_slope_1;
123 FLOAT32 gain_left, gain_right;
124 FLOAT32 t_gain_step_inv, t_gain_step_inv_2;
125 FLOAT32 temp_a, temp_b, temp_c, temp_d;
126 FLOAT32 curve_left, curve_right;
127 FLOAT32 max_val, min_val;
128 FLOAT32 tmp, tmp2;
129 FLOAT32 g_extreme, t_extreme;
130 FLOAT32 k1, k2;
131 FLOAT32 slope_norm = 1.0f / (FLOAT32)time_delta_min;
132 FLOAT32 margin = 0.2f;
133 FLOAT32 step_inv_2 = ixheaace_div32(2.0f, (FLOAT32)t_gain_step);
134
135 *overshoot_left = FALSE;
136 *overshoot_right = FALSE;
137
138 gain_left = (FLOAT32)pow((FLOAT64)10.0, (FLOAT64)(0.05f * gain_0));
139 gain_right = (FLOAT32)pow((FLOAT64)10.0, (FLOAT64)(0.05f * gain_1));
140
141 norm_slope_0 = slope_0 * slope_norm * SLOPE_FACTOR_DB_TO_LINEAR * gain_left;
142 norm_slope_1 = slope_1 * slope_norm * SLOPE_FACTOR_DB_TO_LINEAR * gain_right;
143
144 if ((FLOAT32)fabs((FLOAT64)norm_slope_0) < (FLOAT32)fabs((FLOAT64)norm_slope_1)) {
145 t_connect = (WORD32)(0.5f + 2.0f * (gain_left - gain_right + norm_slope_0 * t_gain_step) /
146 (norm_slope_0 - norm_slope_1));
147 t_connect = t_gain_step - t_connect;
148 if ((t_connect >= 0) && (t_connect < t_gain_step)) {
149 return;
150 }
151 } else if ((FLOAT32)fabs((FLOAT64)norm_slope_0) > (FLOAT32)fabs((FLOAT64)norm_slope_1)) {
152 t_connect = (WORD32)(0.5f + 2.0f * (gain_right - gain_left - norm_slope_1 * t_gain_step) /
153 (norm_slope_0 - norm_slope_1));
154 if ((t_connect >= 0) && (t_connect < t_gain_step)) {
155 return;
156 }
157 }
158
159 tmp = 1.5f * step_inv_2 * (gain_right - gain_left) - norm_slope_1 - norm_slope_0;
160 curve_left = step_inv_2 * (tmp - norm_slope_0);
161 curve_right = step_inv_2 * (norm_slope_1 - tmp);
162
163 tmp = -norm_slope_0 * t_gain_step - gain_left + gain_right;
164 if (curve_left >= 0.0f) {
165 if (tmp + margin < 0.0f) {
166 *overshoot_left = TRUE;
167 }
168 } else {
169 if (tmp - margin > 0.0f) {
170 *overshoot_left = TRUE;
171 }
172 }
173 tmp = norm_slope_1 * t_gain_step - gain_right + gain_left;
174 if (curve_right >= 0.0f) {
175 if (tmp + margin < 0.0f) {
176 *overshoot_right = TRUE;
177 }
178 } else {
179 if (tmp - margin > 0.0f) {
180 *overshoot_right = TRUE;
181 }
182 }
183
184 if ((!*overshoot_left) && (!*overshoot_right)) {
185 t_gain_step_inv = ixheaace_div32(1.0f, (FLOAT32)t_gain_step);
186 t_gain_step_inv_2 = t_gain_step_inv * t_gain_step_inv;
187 k1 = (gain_right - gain_left) * t_gain_step_inv_2;
188 k2 = norm_slope_1 + norm_slope_0;
189
190 temp_a = t_gain_step_inv * (t_gain_step_inv * k2 - 2.0f * k1);
191 temp_b = 3.0f * k1 - t_gain_step_inv * (k2 + norm_slope_0);
192 temp_c = norm_slope_0;
193 temp_d = gain_left;
194 tmp = temp_b * temp_b - 3.0f * temp_a * temp_c;
195
196 if (!((tmp < 0.0f) || (temp_a == 0.0f))) {
197 max_val = MAX(gain_left, gain_right) + margin;
198 min_val = MIN(gain_left, gain_right) - margin;
199 tmp = (FLOAT32)sqrt((FLOAT64)tmp);
200 tmp2 = (1.0f / (3.0f * temp_a));
201
202 t_extreme = tmp2 * (-temp_b + tmp);
203 if ((t_extreme > 0.0f) && (t_extreme < t_gain_step)) {
204 g_extreme = (((temp_a * t_extreme + temp_b) * t_extreme + temp_c) * t_extreme) + temp_d;
205 if ((g_extreme > max_val) || (g_extreme < min_val)) {
206 *overshoot_left = TRUE;
207 }
208 }
209
210 t_extreme = tmp2 * (-temp_b - tmp);
211 if ((t_extreme > 0.0f) && (t_extreme < t_gain_step)) {
212 g_extreme = (((temp_a * t_extreme + temp_b) * t_extreme + temp_c) * t_extreme) + temp_d;
213 if ((g_extreme > max_val) || (g_extreme < min_val)) {
214 *overshoot_left = TRUE;
215 }
216 }
217 }
218 }
219 }
220
impd_drc_quantize_slope(const FLOAT32 slope,FLOAT32 * slope_quant,WORD32 * slope_code_index)221 static VOID impd_drc_quantize_slope(const FLOAT32 slope, FLOAT32 *slope_quant,
222 WORD32 *slope_code_index) {
223 LOOPIDX idx = 0;
224 const ia_drc_slope_code_table_entry_struct *pstr_slope_code_table =
225 impd_drc_get_slope_code_table_by_value();
226
227 while ((idx < 14) && (slope > pstr_slope_code_table[idx].value)) {
228 idx++;
229 }
230 if (idx > 0 && ((pstr_slope_code_table[idx].value - slope) >
231 (slope - pstr_slope_code_table[idx - 1].value))) {
232 idx--;
233 }
234
235 *slope_quant = pstr_slope_code_table[idx].value;
236 *slope_code_index = pstr_slope_code_table[idx].index;
237 }
238
impd_drc_get_preliminary_nodes(const ia_drc_gain_enc_struct * pstr_gain_enc,const FLOAT32 * ptr_drc_gain_per_sample,FLOAT32 * ptr_drc_gain_per_sample_with_prev_frame,ia_drc_group_struct * pstr_drc_group,const WORD32 full_frame,VOID * pstr_scratch)239 static VOID impd_drc_get_preliminary_nodes(const ia_drc_gain_enc_struct *pstr_gain_enc,
240 const FLOAT32 *ptr_drc_gain_per_sample,
241 FLOAT32 *ptr_drc_gain_per_sample_with_prev_frame,
242 ia_drc_group_struct *pstr_drc_group,
243 const WORD32 full_frame, VOID *pstr_scratch) {
244 LOOPIDX n, k;
245 WORD32 t, index;
246 WORD32 drc_frame_size = pstr_gain_enc->drc_frame_size;
247 WORD32 time_delta_min = pstr_gain_enc->delta_tmin;
248 WORD32 num_values = drc_frame_size / time_delta_min;
249 WORD32 offset = time_delta_min / 2;
250 WORD32 num_gain_values;
251 WORD32 n_left, n_right;
252
253 FLOAT32 gain, gain_quant, gain_quant_prev;
254 FLOAT32 quant_error_prev = -1.0f;
255 FLOAT32 quant_error;
256 FLOAT32 slope_prev, slope_next;
257 FLOAT32 f0 = 0.9f;
258 FLOAT32 f1 = 1.0f - f0;
259
260 WORD32 *ptr_time_at_node = pstr_drc_group->ts_gain;
261 FLOAT32 *ptr_gain_at_node = pstr_drc_group->drc_gain;
262 FLOAT32 *ptr_slope_at_node = pstr_drc_group->slope;
263 FLOAT32 *ptr_gain = ptr_drc_gain_per_sample_with_prev_frame + drc_frame_size;
264 iusace_scratch_mem *ptr_scratch = (iusace_scratch_mem *)(pstr_scratch);
265 FLOAT32 *ptr_slope = (FLOAT32 *)ptr_scratch->ptr_drc_scratch_buf;
266
267 memcpy(ptr_drc_gain_per_sample_with_prev_frame,
268 &(ptr_drc_gain_per_sample_with_prev_frame[drc_frame_size]),
269 drc_frame_size * sizeof(FLOAT32));
270 memcpy(&(ptr_drc_gain_per_sample_with_prev_frame[drc_frame_size]), ptr_drc_gain_per_sample,
271 drc_frame_size * sizeof(FLOAT32));
272
273 for (n = 0; n < drc_frame_size; n++) {
274 ptr_gain[n] *= SCALE_APPROXIMATE_DB;
275 }
276 for (n = 0; n < drc_frame_size; n++) {
277 ptr_gain[n] = f0 * ptr_gain[n - 1] + f1 * ptr_gain[n];
278 }
279
280 if (pstr_drc_group->gain_prev_node < 0.f) {
281 gain_quant_prev =
282 GAIN_QUANT_STEP_SIZE *
283 ((WORD32)(-0.5f + GAIN_QUANT_STEP_SIZE_INV * pstr_drc_group->gain_prev_node));
284 } else {
285 gain_quant_prev =
286 GAIN_QUANT_STEP_SIZE *
287 ((WORD32)(0.5f + GAIN_QUANT_STEP_SIZE_INV * pstr_drc_group->gain_prev_node));
288 }
289
290 k = -1;
291 for (n = 1; n < num_values + 1; n++) {
292 gain = ptr_gain[n * time_delta_min - 1];
293 if (gain < 0.f) {
294 gain_quant = GAIN_QUANT_STEP_SIZE * ((WORD32)(-0.5f + GAIN_QUANT_STEP_SIZE_INV * gain));
295 } else {
296 gain_quant = GAIN_QUANT_STEP_SIZE * ((WORD32)(0.5f + GAIN_QUANT_STEP_SIZE_INV * gain));
297 }
298 quant_error = (FLOAT32)fabs((FLOAT64)(gain - gain_quant));
299
300 slope_prev = (gain - ptr_gain[(n - 1) * time_delta_min - 1]);
301 if (n == num_values) {
302 slope_next = 0.2f;
303 } else {
304 slope_next = (ptr_gain[(n + 1) * time_delta_min - 1] - gain);
305 }
306
307 if (gain_quant_prev != gain_quant) {
308 k++;
309 quant_error_prev = quant_error;
310 gain_quant_prev = gain_quant;
311 ptr_time_at_node[k] = n * time_delta_min - 1;
312 if ((FLOAT32)fabs((FLOAT64)slope_prev) > 0.1f) {
313 gain_quant_prev = 1000.0f;
314 }
315 } else {
316 if ((FLOAT32)fabs((FLOAT64)slope_next) > 0.1f) {
317 if (k < 0) {
318 k = 0;
319 }
320 ptr_time_at_node[k] = n * time_delta_min - 1;
321 } else {
322 if (quant_error_prev > quant_error) {
323 if (k < 0) {
324 k = 0;
325 }
326 quant_error_prev = quant_error;
327 ptr_time_at_node[k] = n * time_delta_min - 1;
328 }
329 }
330 }
331 }
332 if (full_frame == 1) {
333 if (ptr_time_at_node[k] != drc_frame_size - 1) {
334 k++;
335 ptr_time_at_node[k] = drc_frame_size - 1;
336 }
337 }
338
339 num_gain_values = k + 1;
340 if (num_gain_values <= 0) {
341 if (k < 0) {
342 k = 0;
343 }
344 n = num_values / 2;
345 index = offset + n * time_delta_min - 1;
346 ptr_slope[n] =
347 ptr_drc_gain_per_sample[index + time_delta_min] - ptr_drc_gain_per_sample[index];
348 t = (n + 1) * time_delta_min - 1;
349 ptr_time_at_node[k] = t;
350 ptr_slope_at_node[k] = ptr_slope[n];
351 ptr_gain_at_node[k] = ptr_drc_gain_per_sample[t];
352 num_gain_values++;
353 }
354
355 for (k = 0; k < num_gain_values; k++) {
356 n_left = MAX(0, ptr_time_at_node[k] - time_delta_min);
357 n_right = n_left + time_delta_min;
358 ptr_slope_at_node[k] = ptr_gain[n_right] - ptr_gain[n_left];
359 ptr_gain_at_node[k] = ptr_gain[ptr_time_at_node[k]];
360 }
361
362 pstr_drc_group->n_gain_values = num_gain_values;
363 }
364
impd_drc_advance_nodes(ia_drc_gain_enc_struct * pstr_gain_enc,ia_drc_gain_seq_buf_struct * pstr_drc_gain_seq_buf)365 static VOID impd_drc_advance_nodes(ia_drc_gain_enc_struct *pstr_gain_enc,
366 ia_drc_gain_seq_buf_struct *pstr_drc_gain_seq_buf) {
367 LOOPIDX idx;
368 ia_drc_group_struct *pstr_drc_group = &(pstr_drc_gain_seq_buf->str_drc_group);
369 ia_drc_group_for_output_struct *pstr_drc_group_for_output =
370 &(pstr_drc_gain_seq_buf->str_drc_group_for_output);
371
372 if (pstr_drc_group_for_output->n_gain_values > 0) {
373 pstr_drc_group_for_output->time_quant_prev =
374 pstr_drc_group_for_output->ts_gain_quant[pstr_drc_group_for_output->n_gain_values - 1] -
375 pstr_gain_enc->drc_frame_size;
376 pstr_drc_group_for_output->slope_code_index_prev =
377 pstr_drc_group_for_output->slope_code_index[pstr_drc_group_for_output->n_gain_values - 1];
378 pstr_drc_group_for_output->drc_gain_quant_prev =
379 pstr_drc_group_for_output->drc_gain_quant[pstr_drc_group_for_output->n_gain_values - 1];
380 }
381 for (idx = 0; idx < pstr_drc_group->n_gain_values; idx++) {
382 pstr_drc_group_for_output->ts_gain_quant[idx] = pstr_drc_group->ts_gain_quant[idx];
383 pstr_drc_group_for_output->time_delta_quant[idx] = pstr_drc_group->time_delta_quant[idx];
384 pstr_drc_group_for_output->slope_quant[idx] = pstr_drc_group->slope_quant[idx];
385 pstr_drc_group_for_output->slope_code_index[idx] = pstr_drc_group->slope_code_index[idx];
386 pstr_drc_group_for_output->gain_code[idx] = pstr_drc_group->gain_code[idx];
387 pstr_drc_group_for_output->gain_code_length[idx] = pstr_drc_group->gain_code_length[idx];
388 pstr_drc_group_for_output->drc_gain_quant[idx] = pstr_drc_group->drc_gain_quant[idx];
389 }
390 pstr_drc_group_for_output->n_gain_values = pstr_drc_group->n_gain_values;
391 }
392
impd_drc_post_process_nodes(ia_drc_gain_enc_struct * pstr_gain_enc,ia_drc_delta_time_code_table_entry_struct * pstr_delta_time_code_table,ia_drc_gain_seq_buf_struct * pstr_drc_gain_seq_buf,VOID * pstr_scratch)393 static IA_ERRORCODE impd_drc_post_process_nodes(
394 ia_drc_gain_enc_struct *pstr_gain_enc,
395 ia_drc_delta_time_code_table_entry_struct *pstr_delta_time_code_table,
396 ia_drc_gain_seq_buf_struct *pstr_drc_gain_seq_buf, VOID *pstr_scratch) {
397 LOOPIDX k, n;
398 WORD32 time_mandatory_node;
399 WORD32 n_removed, move_on;
400 WORD32 idx_left, idx_right;
401 WORD32 idx_0, idx_1, idx_2, idx_3;
402 WORD32 left, mid, right;
403 WORD32 overshoot_right, overshoot_left;
404 WORD32 cod_slope_zero = 0x7;
405 WORD32 slope_changed = TRUE;
406 WORD32 repeat_check = TRUE;
407 WORD32 time_prev = -1;
408 WORD32 time_delta_min = pstr_gain_enc->delta_tmin;
409
410 FLOAT32 delta_gain;
411 FLOAT32 delta_gain_quant;
412 FLOAT32 gain_value_quant = 0;
413 FLOAT32 slope_average;
414 FLOAT32 slope_of_nodes_left;
415 FLOAT32 slope_of_nodes_right;
416 FLOAT32 thr_low, thr_high;
417 FLOAT32 delta_left, delta_right;
418 FLOAT32 slope_0, slope_1, slope_2;
419 IA_ERRORCODE err_code = IA_NO_ERROR;
420
421 const ia_drc_slope_code_table_entry_struct *pstr_slope_code_table;
422 ia_drc_group_for_output_struct *pstr_drc_group_for_output =
423 &(pstr_drc_gain_seq_buf->str_drc_group_for_output);
424 WORD32 num_gain_values = pstr_drc_group_for_output->n_gain_values;
425 FLOAT32 drc_gain_quant_prev = pstr_drc_group_for_output->drc_gain_quant_prev;
426
427 iusace_scratch_mem *ptr_scratch = (iusace_scratch_mem *)(pstr_scratch);
428 FLOAT32 *ptr_gain_buf = (FLOAT32 *)((UWORD8 *)ptr_scratch->ptr_drc_scratch_buf);
429 WORD32 *ptr_time_buf =
430 (WORD32 *)(((UWORD8 *)ptr_gain_buf) + (N_UNIDRC_GAIN_MAX + 2) * sizeof(ptr_gain_buf[0]));
431 WORD32 *ptr_slope_code_index_buf =
432 (WORD32 *)(((UWORD8 *)ptr_time_buf) + (N_UNIDRC_GAIN_MAX + 2) * sizeof(ptr_time_buf[0]));
433 WORD32 *ptr_remove = (WORD32 *)(((UWORD8 *)ptr_slope_code_index_buf) +
434 (N_UNIDRC_GAIN_MAX + 2) * sizeof(ptr_slope_code_index_buf[0]));
435
436 if (pstr_drc_gain_seq_buf->str_gain_set_params.full_frame != 1) {
437 time_mandatory_node = 99999999;
438 } else {
439 time_mandatory_node = pstr_gain_enc->drc_frame_size - 1;
440 }
441
442 ptr_time_buf[0] = pstr_drc_group_for_output->time_quant_prev;
443 ptr_gain_buf[0] = pstr_drc_group_for_output->drc_gain_quant_prev;
444 for (k = 0; k < num_gain_values; k++) {
445 ptr_time_buf[k + 1] = pstr_drc_group_for_output->ts_gain_quant[k];
446 ptr_gain_buf[k + 1] = pstr_drc_group_for_output->drc_gain_quant[k];
447 }
448 ptr_time_buf[k + 1] = pstr_drc_group_for_output->time_quant_next;
449 ptr_gain_buf[k + 1] = pstr_drc_group_for_output->drc_gain_quant_next;
450
451 if (num_gain_values > 1) {
452 idx_left = 0;
453 idx_right = 2;
454 n_removed = 0;
455 for (k = 0; k <= num_gain_values + 1; k++) {
456 ptr_remove[k] = FALSE;
457 }
458 while (idx_right <= num_gain_values + 1) {
459 if ((ptr_gain_buf[idx_left] == ptr_gain_buf[idx_right - 1]) &&
460 (ptr_gain_buf[idx_right - 1] == ptr_gain_buf[idx_right]) &&
461 (num_gain_values - n_removed > 1) &&
462 (ptr_time_buf[idx_right - 1] != time_mandatory_node)) {
463 ptr_remove[idx_right - 1] = TRUE;
464 idx_right++;
465 n_removed++;
466 } else {
467 idx_left = idx_right - 1;
468 idx_right++;
469 }
470 }
471
472 n = 1;
473 for (k = 1; k <= num_gain_values + 1; k++) {
474 if (!ptr_remove[k]) {
475 ptr_time_buf[n] = ptr_time_buf[k];
476 ptr_gain_buf[n] = ptr_gain_buf[k];
477 n++;
478 }
479 }
480
481 n = 0;
482 for (k = 0; k < num_gain_values; k++) {
483 if (!ptr_remove[k + 1]) {
484 pstr_drc_group_for_output->ts_gain_quant[n] = pstr_drc_group_for_output->ts_gain_quant[k];
485 pstr_drc_group_for_output->time_delta_quant[n] =
486 pstr_drc_group_for_output->time_delta_quant[k];
487 pstr_drc_group_for_output->slope_quant[n] = pstr_drc_group_for_output->slope_quant[k];
488 pstr_drc_group_for_output->slope_code_index[n] =
489 pstr_drc_group_for_output->slope_code_index[k];
490 pstr_drc_group_for_output->gain_code[n] = pstr_drc_group_for_output->gain_code[k];
491 pstr_drc_group_for_output->gain_code_length[n] =
492 pstr_drc_group_for_output->gain_code_length[k];
493 pstr_drc_group_for_output->drc_gain_quant[n] =
494 pstr_drc_group_for_output->drc_gain_quant[k];
495 n++;
496 }
497 }
498 num_gain_values = n;
499 }
500
501 if (num_gain_values > 2) {
502 move_on = FALSE;
503 idx_0 = 0;
504 idx_1 = 1;
505 idx_2 = 2;
506 idx_3 = 3;
507 n_removed = 0;
508 for (k = 0; k <= num_gain_values + 1; k++) {
509 ptr_remove[k] = FALSE;
510 }
511 while (idx_3 < num_gain_values + 1) {
512 if (move_on) {
513 move_on = FALSE;
514 idx_0 = idx_1;
515 idx_1 = idx_2;
516 idx_2 = idx_3;
517 idx_3++;
518 }
519 if (ptr_gain_buf[idx_1] != ptr_gain_buf[idx_2]) {
520 move_on = TRUE;
521 } else {
522 delta_left = ptr_gain_buf[idx_1] - ptr_gain_buf[idx_0];
523 delta_right = ptr_gain_buf[idx_3] - ptr_gain_buf[idx_2];
524
525 if (((FLOAT32)fabs((FLOAT64)delta_left) < 0.26f) ||
526 ((FLOAT32)fabs((FLOAT64)delta_right) < 0.26f)) {
527 if ((delta_left > 0.0f) && (delta_right > 0.0f) &&
528 (ptr_time_buf[idx_1] != time_mandatory_node)) {
529 ptr_remove[idx_1] = TRUE;
530 pstr_drc_group_for_output->gain_code[idx_2 - 1] =
531 pstr_drc_group_for_output->gain_code[idx_1 - 1];
532 pstr_drc_group_for_output->gain_code_length[idx_2 - 1] =
533 pstr_drc_group_for_output->gain_code_length[idx_1 - 1];
534 idx_1 = idx_2;
535 idx_2 = idx_3;
536 idx_3++;
537 n_removed++;
538 } else if ((delta_left < 0.0f) && (delta_right < 0.0f) &&
539 (ptr_time_buf[idx_2] != time_mandatory_node)) {
540 ptr_remove[idx_2] = TRUE;
541 idx_2 = idx_3;
542 idx_3++;
543 n_removed++;
544 } else {
545 move_on = TRUE;
546 }
547 } else {
548 move_on = TRUE;
549 }
550 }
551 }
552
553 n = 1;
554 for (k = 1; k <= num_gain_values + 1; k++) {
555 if (!ptr_remove[k]) {
556 ptr_gain_buf[n] = ptr_gain_buf[k];
557 ptr_time_buf[n] = ptr_time_buf[k];
558 n++;
559 }
560 }
561
562 n = 0;
563 for (k = 0; k < num_gain_values; k++) {
564 if (!ptr_remove[k + 1]) {
565 pstr_drc_group_for_output->ts_gain_quant[n] = pstr_drc_group_for_output->ts_gain_quant[k];
566 pstr_drc_group_for_output->time_delta_quant[n] =
567 pstr_drc_group_for_output->time_delta_quant[k];
568 pstr_drc_group_for_output->slope_quant[n] = pstr_drc_group_for_output->slope_quant[k];
569 pstr_drc_group_for_output->slope_code_index[n] =
570 pstr_drc_group_for_output->slope_code_index[k];
571 pstr_drc_group_for_output->gain_code[n] = pstr_drc_group_for_output->gain_code[k];
572 pstr_drc_group_for_output->gain_code_length[n] =
573 pstr_drc_group_for_output->gain_code_length[k];
574 pstr_drc_group_for_output->drc_gain_quant[n] =
575 pstr_drc_group_for_output->drc_gain_quant[k];
576 n++;
577 }
578 }
579 num_gain_values = n;
580 }
581
582 for (k = 1; k <= num_gain_values; k++) {
583 if ((ptr_gain_buf[k - 1] < ptr_gain_buf[k]) && (ptr_gain_buf[k] > ptr_gain_buf[k + 1])) {
584 pstr_drc_group_for_output->slope_code_index[k - 1] = cod_slope_zero;
585 pstr_drc_group_for_output->slope_quant[k - 1] = 0.0f;
586 }
587 if ((ptr_gain_buf[k - 1] > ptr_gain_buf[k]) && (ptr_gain_buf[k] < ptr_gain_buf[k + 1])) {
588 pstr_drc_group_for_output->slope_code_index[k - 1] = cod_slope_zero;
589 pstr_drc_group_for_output->slope_quant[k - 1] = 0.0f;
590 }
591 }
592
593 if (ptr_gain_buf[0] == ptr_gain_buf[1]) {
594 pstr_drc_group_for_output->slope_code_index[0] = cod_slope_zero;
595 pstr_drc_group_for_output->slope_quant[0] = 0.0f;
596 }
597 for (k = 0; k < num_gain_values - 1; k++) {
598 if (ptr_gain_buf[k + 1] == ptr_gain_buf[k + 2]) {
599 pstr_drc_group_for_output->slope_code_index[k] = cod_slope_zero;
600 pstr_drc_group_for_output->slope_code_index[k + 1] = cod_slope_zero;
601 pstr_drc_group_for_output->slope_quant[k] = 0.0f;
602 pstr_drc_group_for_output->slope_quant[k + 1] = 0.0f;
603 }
604 }
605 if (ptr_gain_buf[k + 1] == ptr_gain_buf[k + 2]) {
606 pstr_drc_group_for_output->slope_code_index[k] = cod_slope_zero;
607 pstr_drc_group_for_output->slope_quant[k] = 0.0f;
608 }
609
610 ptr_slope_code_index_buf[0] = pstr_drc_group_for_output->slope_code_index_prev;
611 for (k = 0; k < num_gain_values; k++) {
612 ptr_slope_code_index_buf[k + 1] = pstr_drc_group_for_output->slope_code_index[k];
613 }
614 ptr_slope_code_index_buf[k + 1] = pstr_drc_group_for_output->slope_code_index_next;
615
616 for (k = 0; k <= num_gain_values + 1; k++) {
617 ptr_remove[k] = FALSE;
618 }
619
620 if (num_gain_values > 1) {
621 left = 0;
622 mid = 1;
623 right = 2;
624 n_removed = 0;
625 while ((right <= num_gain_values + 1) && (num_gain_values - n_removed > 1)) {
626 if (((ptr_time_buf[mid] - ptr_time_buf[left]) > 0) &&
627 (FLOAT32)fabs((FLOAT64)(ptr_gain_buf[left] - ptr_gain_buf[right])) <
628 MAX_DRC_GAIN_DELTA_BEFORE_QUANT) {
629 slope_of_nodes_left =
630 (ptr_gain_buf[mid] - ptr_gain_buf[left]) / (ptr_time_buf[mid] - ptr_time_buf[left]);
631 slope_of_nodes_right =
632 (ptr_gain_buf[right] - ptr_gain_buf[mid]) / (ptr_time_buf[right] - ptr_time_buf[mid]);
633
634 if (slope_of_nodes_left >= 0.0f) {
635 if ((slope_of_nodes_left < slope_of_nodes_right * SLOPE_CHANGE_THR) &&
636 (slope_of_nodes_left * SLOPE_CHANGE_THR > slope_of_nodes_right)) {
637 slope_average = 0.5f * time_delta_min * (slope_of_nodes_left + slope_of_nodes_right);
638 thr_low = slope_average / SLOPE_QUANT_THR;
639 thr_high = slope_average * SLOPE_QUANT_THR;
640 slope_0 = impd_drc_decode_slope_idx_value(ptr_slope_code_index_buf[left]);
641 slope_1 = impd_drc_decode_slope_idx_value(ptr_slope_code_index_buf[mid]);
642 slope_2 = impd_drc_decode_slope_idx_value(ptr_slope_code_index_buf[right]);
643
644 if (((slope_0 < thr_high) && (slope_0 > thr_low)) &&
645 ((slope_1 < thr_high) && (slope_1 > thr_low)) &&
646 ((slope_2 < thr_high) && (slope_2 > thr_low)) &&
647 (ptr_time_buf[mid] != time_mandatory_node)) {
648 ptr_remove[mid] = TRUE;
649 n_removed++;
650 mid = right;
651 right++;
652 } else {
653 left = mid;
654 mid = right;
655 right++;
656 }
657 } else {
658 left = mid;
659 mid = right;
660 right++;
661 }
662 } else {
663 if ((-slope_of_nodes_left < -slope_of_nodes_right * SLOPE_CHANGE_THR) &&
664 (-slope_of_nodes_left * SLOPE_CHANGE_THR > -slope_of_nodes_right)) {
665 slope_average = -0.5f * time_delta_min * (slope_of_nodes_left + slope_of_nodes_right);
666 thr_low = slope_average / SLOPE_QUANT_THR;
667 thr_high = slope_average * SLOPE_QUANT_THR;
668 slope_0 = -impd_drc_decode_slope_idx_value(ptr_slope_code_index_buf[left]);
669 slope_1 = -impd_drc_decode_slope_idx_value(ptr_slope_code_index_buf[mid]);
670 slope_2 = -impd_drc_decode_slope_idx_value(ptr_slope_code_index_buf[right]);
671
672 if (((slope_0 < thr_high) && (slope_0 > thr_low)) &&
673 ((slope_1 < thr_high) && (slope_1 > thr_low)) &&
674 ((slope_2 < thr_high) && (slope_2 > thr_low)) &&
675 (ptr_time_buf[mid] != time_mandatory_node)) {
676 ptr_remove[mid] = TRUE;
677 n_removed++;
678 mid = right;
679 right++;
680 } else {
681 left = mid;
682 mid = right;
683 right++;
684 }
685 } else {
686 left = mid;
687 mid = right;
688 right++;
689 }
690 }
691 } else {
692 left = mid;
693 mid = right;
694 right++;
695 }
696 }
697
698 n = 1;
699 for (k = 1; k <= num_gain_values + 1; k++) {
700 if (!ptr_remove[k]) {
701 ptr_time_buf[n] = ptr_time_buf[k];
702 ptr_gain_buf[n] = ptr_gain_buf[k];
703 ptr_slope_code_index_buf[n] = ptr_slope_code_index_buf[k];
704 n++;
705 }
706 }
707
708 n = 0;
709 for (k = 0; k < num_gain_values; k++) {
710 if (!ptr_remove[k + 1]) {
711 pstr_drc_group_for_output->ts_gain_quant[n] = pstr_drc_group_for_output->ts_gain_quant[k];
712 pstr_drc_group_for_output->time_delta_quant[n] =
713 pstr_drc_group_for_output->time_delta_quant[k];
714 pstr_drc_group_for_output->gain_code[n] = pstr_drc_group_for_output->gain_code[k];
715 pstr_drc_group_for_output->gain_code_length[n] =
716 pstr_drc_group_for_output->gain_code_length[k];
717 pstr_drc_group_for_output->slope_quant[n] = pstr_drc_group_for_output->slope_quant[k];
718 pstr_drc_group_for_output->slope_code_index[n] =
719 pstr_drc_group_for_output->slope_code_index[k];
720 pstr_drc_group_for_output->drc_gain_quant[n] =
721 pstr_drc_group_for_output->drc_gain_quant[k];
722 n++;
723 }
724 }
725 num_gain_values = n;
726 }
727 pstr_drc_group_for_output->n_gain_values = num_gain_values;
728
729 k = 0;
730 while (repeat_check) {
731 repeat_check = FALSE;
732
733 while (k < num_gain_values) {
734 if (slope_changed) {
735 slope_changed = FALSE;
736 } else {
737 k++;
738 }
739 if ((ptr_slope_code_index_buf[k] != cod_slope_zero) ||
740 (ptr_slope_code_index_buf[k + 1] != cod_slope_zero)) {
741 impd_drc_check_overshoot(ptr_time_buf[k + 1] - ptr_time_buf[k], ptr_gain_buf[k],
742 ptr_gain_buf[k + 1],
743 impd_drc_decode_slope_idx_value(ptr_slope_code_index_buf[k]),
744 impd_drc_decode_slope_idx_value(ptr_slope_code_index_buf[k + 1]),
745 time_delta_min, &overshoot_left, &overshoot_right);
746
747 if (overshoot_right || overshoot_left) {
748 if ((k == 0) ||
749 (impd_drc_decode_slope_idx_magnitude(ptr_slope_code_index_buf[k]) <
750 impd_drc_decode_slope_idx_magnitude(ptr_slope_code_index_buf[k + 1]))) {
751 if (ptr_slope_code_index_buf[k + 1] < cod_slope_zero) {
752 ptr_slope_code_index_buf[k + 1] = ptr_slope_code_index_buf[k + 1] + 1;
753 slope_changed = TRUE;
754 } else if (ptr_slope_code_index_buf[k + 1] > cod_slope_zero) {
755 ptr_slope_code_index_buf[k + 1] = ptr_slope_code_index_buf[k + 1] - 1;
756 slope_changed = TRUE;
757 }
758 } else if ((k == num_gain_values) ||
759 (impd_drc_decode_slope_idx_magnitude(ptr_slope_code_index_buf[k]) >
760 impd_drc_decode_slope_idx_magnitude(ptr_slope_code_index_buf[k + 1]))) {
761 if (ptr_slope_code_index_buf[k] < cod_slope_zero) {
762 ptr_slope_code_index_buf[k] = ptr_slope_code_index_buf[k] + 1;
763 slope_changed = TRUE;
764 repeat_check = TRUE;
765 } else if (ptr_slope_code_index_buf[k] > cod_slope_zero) {
766 ptr_slope_code_index_buf[k] = ptr_slope_code_index_buf[k] - 1;
767 slope_changed = TRUE;
768 repeat_check = TRUE;
769 }
770 }
771 }
772 }
773 }
774 }
775 for (k = 0; k < num_gain_values; k++) {
776 pstr_drc_group_for_output->slope_code_index[k] = ptr_slope_code_index_buf[k + 1];
777 pstr_drc_group_for_output->slope_quant[k] =
778 impd_drc_decode_slope_idx_value(ptr_slope_code_index_buf[k + 1]);
779 }
780
781 for (n = 0; n < num_gain_values; n++) {
782 pstr_drc_group_for_output->time_delta_code_index[n] =
783 MAX((pstr_drc_group_for_output->ts_gain_quant[n] - time_prev) / time_delta_min, 1);
784
785 time_prev += (pstr_drc_group_for_output->time_delta_code_index[n]) * time_delta_min;
786
787 if (n != 0) {
788 delta_gain = pstr_drc_group_for_output->drc_gain_quant[n] - drc_gain_quant_prev;
789 impd_drc_get_quantized_delta_drc_gain(
790 pstr_drc_gain_seq_buf->str_gain_set_params.gain_coding_profile, delta_gain,
791 &delta_gain_quant, &(pstr_drc_group_for_output->gain_code_length[n]),
792 &(pstr_drc_group_for_output->gain_code[n]));
793 gain_value_quant = delta_gain_quant + drc_gain_quant_prev;
794 } else {
795 err_code = impd_drc_enc_initial_gain(
796 pstr_drc_gain_seq_buf->str_gain_set_params.gain_coding_profile,
797 pstr_drc_group_for_output->drc_gain_quant[n], &gain_value_quant,
798 &(pstr_drc_group_for_output->gain_code_length[n]),
799 &(pstr_drc_group_for_output->gain_code[n]));
800 if (err_code) {
801 return err_code;
802 }
803 }
804 drc_gain_quant_prev = gain_value_quant;
805 pstr_drc_group_for_output->drc_gain_quant[n] = gain_value_quant;
806 }
807
808 pstr_drc_group_for_output->coding_mode = 1;
809 if (num_gain_values == 1) {
810 if (pstr_drc_gain_seq_buf->str_gain_set_params.gain_interpolation_type !=
811 GAIN_INTERPOLATION_TYPE_SPLINE) {
812 if (pstr_drc_group_for_output->time_delta_code_index[0] >
813 (pstr_gain_enc->drc_frame_size / pstr_gain_enc->delta_tmin)) {
814 pstr_drc_group_for_output->coding_mode = 0;
815 }
816 } else {
817 if (impd_drc_decode_slope_idx_magnitude(ptr_slope_code_index_buf[1]) == 0.0f) {
818 if ((pstr_drc_group_for_output->time_delta_code_index[0] == 0) ||
819 (pstr_drc_group_for_output->time_delta_code_index[0] > 28)) {
820 pstr_drc_group_for_output->coding_mode = 0;
821 }
822 if ((impd_drc_decode_slope_idx_magnitude(ptr_slope_code_index_buf[0]) == 0.0f) &&
823 (impd_drc_decode_slope_idx_magnitude(ptr_slope_code_index_buf[2]) == 0.0f) &&
824 ((FLOAT32)fabs((FLOAT64)(ptr_gain_buf[1] - ptr_gain_buf[0])) < 0.126f) &&
825 ((FLOAT32)fabs((FLOAT64)(ptr_gain_buf[2] - ptr_gain_buf[1])) < 0.126f)) {
826 pstr_drc_group_for_output->coding_mode = 0;
827 }
828 }
829 }
830 }
831
832 if (pstr_drc_group_for_output->coding_mode == 1) {
833 pstr_slope_code_table = impd_drc_get_slope_code_table_by_value();
834 for (n = 0; n < num_gain_values; n++) {
835 pstr_drc_group_for_output->slope_code_size[n] =
836 pstr_slope_code_table[ptr_slope_code_index_buf[n + 1]].size;
837 pstr_drc_group_for_output->slope_code[n] =
838 pstr_slope_code_table[ptr_slope_code_index_buf[n + 1]].code;
839 }
840
841 for (n = 0; n < num_gain_values; n++) {
842 pstr_drc_group_for_output->time_delta_code_size[n] =
843 pstr_delta_time_code_table[pstr_drc_group_for_output->time_delta_code_index[n]].size;
844 pstr_drc_group_for_output->time_delta_code[n] =
845 pstr_delta_time_code_table[pstr_drc_group_for_output->time_delta_code_index[n]].code;
846 }
847 }
848 return err_code;
849 }
850
impd_drc_quantize_drc_frame(const WORD32 drc_frame_size,const WORD32 time_delta_min,const WORD32 num_gain_values_max,const FLOAT32 * ptr_drc_gain_per_sample_with_prev_frame,const WORD32 * ptr_delta_time_quant_table,const WORD32 gain_coding_profile,ia_drc_group_struct * pstr_drc_group,ia_drc_group_for_output_struct * pstr_drc_group_for_output)851 static IA_ERRORCODE impd_drc_quantize_drc_frame(
852 const WORD32 drc_frame_size, const WORD32 time_delta_min, const WORD32 num_gain_values_max,
853 const FLOAT32 *ptr_drc_gain_per_sample_with_prev_frame,
854 const WORD32 *ptr_delta_time_quant_table, const WORD32 gain_coding_profile,
855 ia_drc_group_struct *pstr_drc_group,
856 ia_drc_group_for_output_struct *pstr_drc_group_for_output) {
857 LOOPIDX i, n;
858 WORD32 t, k = 0;
859 WORD32 num_bits = 0, code = 0, tmp;
860 WORD32 t_left, t_right;
861 WORD32 time_delta_left, time_delta_right;
862 WORD32 restart = TRUE;
863 WORD32 num_drc_gain_values = pstr_drc_group->n_gain_values;
864
865 FLOAT32 slope;
866 FLOAT32 delta_gain;
867 FLOAT32 gain_value_quant = 0;
868 FLOAT32 delta_gain_quant;
869 FLOAT32 max_time_deviation;
870 FLOAT32 drc_gain_per_sample_limited;
871
872 WORD32 *ptr_time_at_node = pstr_drc_group->ts_gain;
873 WORD32 *ptr_ts_gain_quant = pstr_drc_group->ts_gain_quant;
874 WORD32 *ptr_slope_code_index = pstr_drc_group->slope_code_index;
875 FLOAT32 *drc_gain_quant_prev = &(pstr_drc_group->drc_gain_quant_prev);
876 FLOAT32 *ptr_gain_at_node = pstr_drc_group->drc_gain;
877 FLOAT32 *ptr_slope_at_node = pstr_drc_group->slope;
878 FLOAT32 *ptr_slope_quant = pstr_drc_group->slope_quant;
879 const FLOAT32 *ptr_drc_gain_per_sample =
880 ptr_drc_gain_per_sample_with_prev_frame + drc_frame_size;
881 IA_ERRORCODE err_code = IA_NO_ERROR;
882
883 while (restart) {
884 n = 0;
885 restart = FALSE;
886 while ((n < num_drc_gain_values) && (restart == FALSE)) {
887 if (n == 0) {
888 time_delta_left = ptr_time_at_node[n];
889 time_delta_right = ptr_time_at_node[n + 1] - ptr_time_at_node[n];
890 } else if (n < num_drc_gain_values - 1) {
891 time_delta_left = ptr_time_at_node[n] - ptr_time_at_node[n - 1];
892 time_delta_right = ptr_time_at_node[n + 1] - ptr_time_at_node[n];
893 } else {
894 time_delta_left = ptr_time_at_node[n] - ptr_time_at_node[n - 1];
895 time_delta_right = drc_frame_size - ptr_time_at_node[n];
896 }
897 max_time_deviation = MAX_TIME_DEVIATION_FACTOR * MIN(time_delta_left, time_delta_right);
898 max_time_deviation = MAX(time_delta_min, max_time_deviation);
899
900 i = 0;
901 while ((i < num_gain_values_max - 2) && (ptr_delta_time_quant_table[i] < time_delta_left)) {
902 i++;
903 }
904 if (i > 0) {
905 if (ptr_delta_time_quant_table[i] - time_delta_left >
906 time_delta_left - ptr_delta_time_quant_table[i - 1]) {
907 i--;
908 }
909 if (ptr_delta_time_quant_table[i] >= drc_frame_size) {
910 i--;
911 }
912 }
913 if (abs(ptr_delta_time_quant_table[i] - time_delta_left) > max_time_deviation) {
914 if (ptr_delta_time_quant_table[i] > time_delta_left) {
915 i--;
916 }
917 for (k = num_drc_gain_values; k > n; k--) {
918 ptr_time_at_node[k] = ptr_time_at_node[k - 1];
919 ptr_slope_at_node[k] = ptr_slope_at_node[k - 1];
920 ptr_gain_at_node[k] = ptr_gain_at_node[k - 1];
921 }
922 if (n <= 0) {
923 ptr_time_at_node[n] = ptr_delta_time_quant_table[i];
924 } else {
925 ptr_time_at_node[n] = ptr_time_at_node[n - 1] + ptr_delta_time_quant_table[i];
926 }
927
928 t = ptr_time_at_node[n];
929 ptr_gain_at_node[n] = ptr_drc_gain_per_sample[t];
930 t_left = MAX(0, t - time_delta_min / 2);
931 t_right = MIN(drc_frame_size, t_left + time_delta_min / 2);
932 ptr_slope_at_node[n] = ptr_drc_gain_per_sample[t_right] - ptr_drc_gain_per_sample[t_left];
933 num_drc_gain_values++;
934 restart = TRUE;
935 }
936 n++;
937 }
938 }
939
940 ptr_ts_gain_quant[0] =
941 (WORD32)(time_delta_min * (ptr_time_at_node[0] + 0.5f) / (FLOAT32)time_delta_min);
942 k = 1;
943 for (n = 1; n < num_drc_gain_values; n++) {
944 tmp = (WORD32)(time_delta_min * (ptr_time_at_node[n] + 0.5f) / (FLOAT32)time_delta_min);
945 if (tmp > ptr_ts_gain_quant[k - 1]) {
946 ptr_ts_gain_quant[k] = tmp;
947 k++;
948 }
949 }
950
951 num_drc_gain_values = k;
952 pstr_drc_group->n_gain_values = num_drc_gain_values;
953 for (n = 0; n < num_drc_gain_values; n++) {
954 ptr_gain_at_node[n] = ptr_drc_gain_per_sample[ptr_ts_gain_quant[n]];
955 drc_gain_per_sample_limited =
956 impd_drc_limit_drc_gain(gain_coding_profile, ptr_gain_at_node[n]);
957
958 if (n != 0) {
959 delta_gain = drc_gain_per_sample_limited - *drc_gain_quant_prev;
960 impd_drc_get_quantized_delta_drc_gain(gain_coding_profile, delta_gain, &delta_gain_quant,
961 &num_bits, &code);
962 gain_value_quant = delta_gain_quant + *drc_gain_quant_prev;
963 } else {
964 err_code = impd_drc_enc_initial_gain(gain_coding_profile, drc_gain_per_sample_limited,
965 &gain_value_quant, &num_bits, &code);
966 if (err_code) {
967 return err_code;
968 }
969 }
970 pstr_drc_group->gain_code[n] = code;
971 pstr_drc_group->gain_code_length[n] = num_bits;
972 pstr_drc_group->drc_gain_quant[n] = gain_value_quant;
973 *drc_gain_quant_prev = gain_value_quant;
974
975 t_right = MIN(drc_frame_size - 1, ptr_ts_gain_quant[n] + time_delta_min / 2);
976 t_left = t_right - time_delta_min;
977 slope = ptr_drc_gain_per_sample[t_right] - ptr_drc_gain_per_sample[t_left];
978 ptr_slope_at_node[n] = slope;
979 impd_drc_quantize_slope(slope, &(ptr_slope_quant[n]), &(ptr_slope_code_index[n]));
980 }
981
982 pstr_drc_group->n_gain_values = num_drc_gain_values;
983 pstr_drc_group->gain_prev_node = ptr_gain_at_node[num_drc_gain_values - 1];
984 pstr_drc_group_for_output->time_quant_next = pstr_drc_group->ts_gain_quant[0] + drc_frame_size;
985 pstr_drc_group_for_output->slope_code_index_next = pstr_drc_group->slope_code_index[0];
986 pstr_drc_group_for_output->drc_gain_quant_next = pstr_drc_group->drc_gain_quant[0];
987 pstr_drc_group_for_output->drc_gain_quant_prev = pstr_drc_group->drc_gain_quant_prev;
988
989 return err_code;
990 }
991
impd_drc_quantize_and_encode_drc_gain(ia_drc_gain_enc_struct * pstr_gain_enc,const FLOAT32 * ptr_drc_gain_per_sample,FLOAT32 * ptr_drc_gain_per_sample_with_prev_frame,ia_drc_delta_time_code_table_entry_struct * pstr_delta_time_code_table,ia_drc_gain_seq_buf_struct * pstr_drc_gain_seq_buf,VOID * pstr_scratch)992 IA_ERRORCODE impd_drc_quantize_and_encode_drc_gain(
993 ia_drc_gain_enc_struct *pstr_gain_enc, const FLOAT32 *ptr_drc_gain_per_sample,
994 FLOAT32 *ptr_drc_gain_per_sample_with_prev_frame,
995 ia_drc_delta_time_code_table_entry_struct *pstr_delta_time_code_table,
996 ia_drc_gain_seq_buf_struct *pstr_drc_gain_seq_buf, VOID *pstr_scratch) {
997 WORD32 drc_frame_size = pstr_gain_enc->drc_frame_size;
998 const WORD32 *ptr_delta_time_quant_table = pstr_gain_enc->delta_time_quant_table;
999 ia_drc_group_struct *pstr_drc_group;
1000 ia_drc_group_for_output_struct *pstr_drc_group_for_output;
1001 IA_ERRORCODE err_code = IA_NO_ERROR;
1002 impd_drc_advance_nodes(pstr_gain_enc, pstr_drc_gain_seq_buf);
1003
1004 pstr_drc_group = &(pstr_drc_gain_seq_buf->str_drc_group);
1005 pstr_drc_group_for_output = &(pstr_drc_gain_seq_buf->str_drc_group_for_output);
1006
1007 impd_drc_get_preliminary_nodes(
1008 pstr_gain_enc, ptr_drc_gain_per_sample, ptr_drc_gain_per_sample_with_prev_frame,
1009 pstr_drc_group, pstr_drc_gain_seq_buf->str_gain_set_params.full_frame, pstr_scratch);
1010
1011 err_code = impd_drc_quantize_drc_frame(
1012 drc_frame_size, pstr_gain_enc->delta_tmin,
1013 pstr_gain_enc->drc_frame_size / pstr_gain_enc->delta_tmin,
1014 ptr_drc_gain_per_sample_with_prev_frame, ptr_delta_time_quant_table,
1015 pstr_drc_gain_seq_buf->str_gain_set_params.gain_coding_profile, pstr_drc_group,
1016 pstr_drc_group_for_output);
1017
1018 if (err_code) {
1019 return err_code;
1020 }
1021
1022 err_code = impd_drc_post_process_nodes(pstr_gain_enc, pstr_delta_time_code_table,
1023 pstr_drc_gain_seq_buf, pstr_scratch);
1024 return err_code;
1025 }
1026