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 <stdio.h>
21#include <string.h>
22#include <math.h>
23#include "impd_type_def.h"
24#include "impd_drc_extr_delta_coded_info.h"
25#include "impd_drc_common.h"
26#include "impd_drc_struct.h"
27#include "impd_drc_interface.h"
28#include "impd_drc_selection_process.h"
29#include "impd_drc_sel_proc_drc_set_sel.h"
30#include "impd_drc_loudness_control.h"
31#include "impd_drc_filter_bank.h"
32#include "impd_drc_rom.h"
33
34static WORD32 effect_types_request_table[] = {
35    EFFECT_BIT_NIGHT,    EFFECT_BIT_NOISY,   EFFECT_BIT_LIMITED,
36    EFFECT_BIT_LOWLEVEL, EFFECT_BIT_DIALOG,  EFFECT_BIT_GENERAL_COMPR,
37    EFFECT_BIT_EXPAND,   EFFECT_BIT_ARTISTIC};
38
39WORD32 impd_validate_requested_drc_feature(
40    ia_drc_sel_proc_params_struct* pstr_drc_sel_proc_params_struct) {
41  WORD32 i, j;
42
43  for (i = 0; i < pstr_drc_sel_proc_params_struct->num_drc_feature_requests;
44       i++) {
45    switch (pstr_drc_sel_proc_params_struct->drc_feature_req_type[i]) {
46      case MATCH_EFFECT_TYPE:
47        for (j = 0; j < pstr_drc_sel_proc_params_struct
48                            ->desired_num_drc_effects_of_requested[i];
49             j++) {
50          if (pstr_drc_sel_proc_params_struct
51                  ->requested_drc_effect_type[i][j] ==
52              EFFECT_TYPE_REQUESTED_NONE) {
53            if (pstr_drc_sel_proc_params_struct
54                    ->desired_num_drc_effects_of_requested[i] > 1) {
55              return (UNEXPECTED_ERROR);
56            }
57          }
58        }
59        break;
60      case MATCH_DYNAMIC_RANGE:
61        break;
62      case MATCH_DRC_CHARACTERISTIC:
63        break;
64      default:
65        return (UNEXPECTED_ERROR);
66        break;
67    }
68  }
69  return (0);
70}
71
72WORD32 impd_find_drc_instructions_uni_drc(
73    ia_drc_config* drc_config, WORD32 drc_set_id_requested,
74    ia_drc_instructions_struct** str_drc_instruction_str) {
75  WORD32 i;
76  for (i = 0; i < drc_config->drc_instructions_uni_drc_count; i++) {
77    if (drc_set_id_requested ==
78        drc_config->str_drc_instruction_str[i].drc_set_id)
79      break;
80  }
81  if (i == drc_config->drc_instructions_uni_drc_count) {
82    return (UNEXPECTED_ERROR);
83  }
84  *str_drc_instruction_str = &drc_config->str_drc_instruction_str[i];
85  return (0);
86}
87
88WORD32 impd_map_requested_effect_bit_idx(WORD32 requested_effect_type,
89                                         WORD32* effect_bit_idx) {
90  switch (requested_effect_type) {
91    case EFFECT_TYPE_REQUESTED_NONE:
92      *effect_bit_idx = EFFECT_BIT_NONE;
93      break;
94    case EFFECT_TYPE_REQUESTED_NIGHT:
95      *effect_bit_idx = EFFECT_BIT_NIGHT;
96      break;
97    case EFFECT_TYPE_REQUESTED_NOISY:
98      *effect_bit_idx = EFFECT_BIT_NOISY;
99      break;
100    case EFFECT_TYPE_REQUESTED_LIMITED:
101      *effect_bit_idx = EFFECT_BIT_LIMITED;
102      break;
103    case EFFECT_TYPE_REQUESTED_LOWLEVEL:
104      *effect_bit_idx = EFFECT_BIT_LOWLEVEL;
105      break;
106    case EFFECT_TYPE_REQUESTED_DIALOG:
107      *effect_bit_idx = EFFECT_BIT_DIALOG;
108      break;
109    case EFFECT_TYPE_REQUESTED_GENERAL_COMPR:
110      *effect_bit_idx = EFFECT_BIT_GENERAL_COMPR;
111      break;
112    case EFFECT_TYPE_REQUESTED_EXPAND:
113      *effect_bit_idx = EFFECT_BIT_EXPAND;
114      break;
115    case EFFECT_TYPE_REQUESTED_ARTISTIC:
116      *effect_bit_idx = EFFECT_BIT_ARTISTIC;
117      break;
118
119    default:
120      return (UNEXPECTED_ERROR);
121
122      break;
123  }
124  return (0);
125}
126
127WORD32 impd_get_fading_drc_set(ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc) {
128  pstr_drc_uni_sel_proc->drc_instructions_index[2] = -1;
129  if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.album_mode == 0) {
130    WORD32 n;
131    ia_drc_instructions_struct* str_drc_instruction_str = NULL;
132    for (n = 0;
133         n < pstr_drc_uni_sel_proc->drc_config.drc_instructions_uni_drc_count;
134         n++) {
135      str_drc_instruction_str =
136          &(pstr_drc_uni_sel_proc->drc_config.str_drc_instruction_str[n]);
137
138      if (str_drc_instruction_str->drc_set_effect & EFFECT_BIT_FADE) {
139        if (str_drc_instruction_str->downmix_id[0] == ID_FOR_ANY_DOWNMIX) {
140          pstr_drc_uni_sel_proc->drc_instructions_index[2] = n;
141
142        } else {
143          return (UNEXPECTED_ERROR);
144        }
145      }
146    }
147  }
148  return (0);
149}
150
151WORD32 impd_get_ducking_drc_set(ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc) {
152  WORD32 drc_instructions_index;
153  WORD32 n, k;
154  ia_drc_instructions_struct* str_drc_instruction_str;
155
156  WORD32 requested_dwnmix_id =
157      pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.active_downmix_id;
158
159  pstr_drc_uni_sel_proc->drc_instructions_index[3] = -1;
160  drc_instructions_index = -1;
161  str_drc_instruction_str = NULL;
162
163  for (n = 0;
164       n < pstr_drc_uni_sel_proc->drc_config.drc_instructions_uni_drc_count;
165       n++) {
166    str_drc_instruction_str =
167        &(pstr_drc_uni_sel_proc->drc_config.str_drc_instruction_str[n]);
168
169    if (str_drc_instruction_str->drc_set_effect &
170        (EFFECT_BIT_DUCK_OTHER | EFFECT_BIT_DUCK_SELF)) {
171      for (k = 0; k < str_drc_instruction_str->dwnmix_id_count; k++) {
172        if (str_drc_instruction_str->downmix_id[k] == requested_dwnmix_id) {
173          drc_instructions_index = n;
174        }
175      }
176    }
177  }
178  if (drc_instructions_index == -1) {
179    for (n = 0;
180         n < pstr_drc_uni_sel_proc->drc_config.drc_instructions_uni_drc_count;
181         n++) {
182      str_drc_instruction_str =
183          &(pstr_drc_uni_sel_proc->drc_config.str_drc_instruction_str[n]);
184
185      if (str_drc_instruction_str->drc_set_effect &
186          (EFFECT_BIT_DUCK_OTHER | EFFECT_BIT_DUCK_SELF)) {
187        for (k = 0; k < str_drc_instruction_str->dwnmix_id_count; k++) {
188          if (str_drc_instruction_str->downmix_id[k] == ID_FOR_BASE_LAYOUT) {
189            drc_instructions_index = n;
190          }
191        }
192      }
193    }
194  }
195  if (drc_instructions_index > -1) {
196    pstr_drc_uni_sel_proc->drc_instructions_index[2] = -1;
197    pstr_drc_uni_sel_proc->drc_instructions_index[3] = drc_instructions_index;
198  }
199  return (0);
200}
201
202WORD32 impd_get_selected_drc_set(ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc,
203                                 WORD32 drc_set_id_selected) {
204  WORD32 n;
205
206  ia_drc_instructions_struct* str_drc_instruction_str = NULL;
207
208  for (n = 0; n < pstr_drc_uni_sel_proc->drc_config.drc_instructions_count_plus;
209       n++) {
210    if (pstr_drc_uni_sel_proc->drc_config.str_drc_instruction_str[n]
211            .drc_set_id == drc_set_id_selected)
212      break;
213  }
214  if (n == pstr_drc_uni_sel_proc->drc_config.drc_instructions_count_plus) {
215    return (EXTERNAL_ERROR);
216  }
217  pstr_drc_uni_sel_proc->drc_inst_index_sel = n;
218  str_drc_instruction_str = &(
219      pstr_drc_uni_sel_proc->drc_config
220          .str_drc_instruction_str[pstr_drc_uni_sel_proc->drc_inst_index_sel]);
221
222  pstr_drc_uni_sel_proc->drc_instructions_index[0] =
223      pstr_drc_uni_sel_proc->drc_inst_index_sel;
224  return (0);
225}
226
227WORD32 impd_get_dependent_drc_set(
228    ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc) {
229  ia_drc_instructions_struct* str_drc_instruction_str = NULL;
230  str_drc_instruction_str = &(
231      pstr_drc_uni_sel_proc->drc_config
232          .str_drc_instruction_str[pstr_drc_uni_sel_proc->drc_inst_index_sel]);
233
234  if (str_drc_instruction_str->depends_on_drc_set_present == 1) {
235    WORD32 n;
236    WORD32 drc_dependent_set_id = str_drc_instruction_str->depends_on_drc_set;
237
238    for (n = 0;
239         n < pstr_drc_uni_sel_proc->drc_config.drc_instructions_count_plus;
240         n++) {
241      if (pstr_drc_uni_sel_proc->drc_config.str_drc_instruction_str[n]
242              .drc_set_id == drc_dependent_set_id)
243        break;
244    }
245    if (n == pstr_drc_uni_sel_proc->drc_config.drc_instructions_count_plus) {
246      return (UNEXPECTED_ERROR);
247    }
248    pstr_drc_uni_sel_proc->drc_instructions_index[1] = n;
249  } else {
250    pstr_drc_uni_sel_proc->drc_instructions_index[1] = -1;
251  }
252  return (0);
253}
254
255WORD32 impd_get_dependent_drc_instructions(
256    const ia_drc_config* drc_config,
257    const ia_drc_instructions_struct* str_drc_instruction_str,
258    ia_drc_instructions_struct** drc_instructions_dependent) {
259  WORD32 j;
260  ia_drc_instructions_struct* dependent_drc = NULL;
261  for (j = 0; j < drc_config->drc_instructions_uni_drc_count; j++) {
262    dependent_drc =
263        (ia_drc_instructions_struct*)&(drc_config->str_drc_instruction_str[j]);
264    if (dependent_drc->drc_set_id ==
265        str_drc_instruction_str->depends_on_drc_set) {
266      break;
267    }
268  }
269  if (j == drc_config->drc_instructions_uni_drc_count) {
270    return (UNEXPECTED_ERROR);
271  }
272  if (dependent_drc->depends_on_drc_set_present == 1) {
273    return (UNEXPECTED_ERROR);
274  }
275  *drc_instructions_dependent = dependent_drc;
276  return (0);
277}
278
279WORD32 impd_select_drcs_without_compr_effects(
280    ia_drc_config* pstr_drc_config, WORD32* match_found_flag,
281    WORD32* selection_candidate_count,
282    ia_selection_candidate_info_struct* selection_candidate_info) {
283  WORD32 i, k, n;
284  WORD32 selection_candidate_step_2_count = 0;
285  ia_selection_candidate_info_struct
286      selection_candidate_info_step_2[SELECTION_CANDIDATE_COUNT_MAX];
287  WORD32 effect_types_request_table_size;
288  WORD32 match;
289  ia_drc_instructions_struct* str_drc_instruction_str;
290
291  effect_types_request_table_size =
292      sizeof(effect_types_request_table) / sizeof(WORD32);
293
294  k = 0;
295  for (i = 0; i < *selection_candidate_count; i++) {
296    str_drc_instruction_str = &(
297        pstr_drc_config->str_drc_instruction_str[selection_candidate_info[i]
298                                                     .drc_instructions_index]);
299
300    match = 1;
301    for (n = 0; n < effect_types_request_table_size; n++) {
302      if ((str_drc_instruction_str->drc_set_effect &
303           effect_types_request_table[n]) != 0x0) {
304        match = 0;
305      }
306    }
307    if (match == 1) {
308      memcpy(&selection_candidate_info_step_2[k], &selection_candidate_info[i],
309             sizeof(ia_selection_candidate_info_struct));
310      k++;
311    }
312  }
313  selection_candidate_step_2_count = k;
314
315  if (selection_candidate_step_2_count > 0) {
316    *match_found_flag = 1;
317    for (i = 0; i < selection_candidate_step_2_count; i++) {
318      memcpy(&selection_candidate_info[i], &selection_candidate_info_step_2[i],
319             sizeof(ia_selection_candidate_info_struct));
320      *selection_candidate_count = selection_candidate_step_2_count;
321    }
322  } else {
323    *match_found_flag = 0;
324  }
325
326  return (0);
327}
328
329WORD32 impd_match_effect_type_attempt(
330    ia_drc_config* pstr_drc_config, WORD32 requested_effect_type,
331    WORD32 state_requested, WORD32* match_found_flag,
332    WORD32* selection_candidate_count,
333    ia_selection_candidate_info_struct* selection_candidate_info) {
334  WORD32 i, k, err;
335  WORD32 selection_candidate_step_2_count = 0;
336  ia_selection_candidate_info_struct
337      selection_candidate_info_step_2[SELECTION_CANDIDATE_COUNT_MAX];
338  ia_drc_instructions_struct* str_drc_instruction_str;
339  ia_drc_instructions_struct* drc_instructions_dependent;
340  WORD32 effect_bit_idx;
341
342  err =
343      impd_map_requested_effect_bit_idx(requested_effect_type, &effect_bit_idx);
344  if (err) return (err);
345
346  if (effect_bit_idx == EFFECT_BIT_NONE) {
347    err = impd_select_drcs_without_compr_effects(
348        pstr_drc_config, match_found_flag, selection_candidate_count,
349        selection_candidate_info);
350    if (err) return (err);
351  } else {
352    k = 0;
353    for (i = 0; i < *selection_candidate_count; i++) {
354      str_drc_instruction_str =
355          &(pstr_drc_config->str_drc_instruction_str
356                [selection_candidate_info[i].drc_instructions_index]);
357      if (str_drc_instruction_str->depends_on_drc_set_present == 1) {
358        err = impd_get_dependent_drc_instructions(pstr_drc_config,
359                                                  str_drc_instruction_str,
360                                                  &drc_instructions_dependent);
361        if (err) return (err);
362
363        if (state_requested == 1) {
364          if (((str_drc_instruction_str->drc_set_effect & effect_bit_idx) !=
365               0x0) ||
366              ((drc_instructions_dependent->drc_set_effect & effect_bit_idx) !=
367               0x0)) {
368            memcpy(&selection_candidate_info_step_2[k],
369                   &selection_candidate_info[i],
370                   sizeof(ia_selection_candidate_info_struct));
371            k++;
372          }
373        } else {
374          if (((str_drc_instruction_str->drc_set_effect & effect_bit_idx) ==
375               0x0) &&
376              ((drc_instructions_dependent->drc_set_effect & effect_bit_idx) ==
377               0x0)) {
378            memcpy(&selection_candidate_info_step_2[k],
379                   &selection_candidate_info[i],
380                   sizeof(ia_selection_candidate_info_struct));
381            k++;
382          }
383        }
384      } else {
385        if (state_requested == 1) {
386          if ((str_drc_instruction_str->drc_set_effect & effect_bit_idx) !=
387              0x0) {
388            memcpy(&selection_candidate_info_step_2[k],
389                   &selection_candidate_info[i],
390                   sizeof(ia_selection_candidate_info_struct));
391            k++;
392          }
393        } else {
394          if ((str_drc_instruction_str->drc_set_effect & effect_bit_idx) ==
395              0x0) {
396            memcpy(&selection_candidate_info_step_2[k],
397                   &selection_candidate_info[i],
398                   sizeof(ia_selection_candidate_info_struct));
399            k++;
400          }
401        }
402      }
403    }
404    selection_candidate_step_2_count = k;
405
406    if (selection_candidate_step_2_count > 0) {
407      *match_found_flag = 1;
408      for (i = 0; i < selection_candidate_step_2_count; i++) {
409        *selection_candidate_count = selection_candidate_step_2_count;
410        memcpy(&selection_candidate_info[i],
411               &selection_candidate_info_step_2[i],
412               sizeof(ia_selection_candidate_info_struct));
413      }
414    } else {
415      *match_found_flag = 0;
416    }
417  }
418  return (0);
419}
420
421WORD32 impd_match_effect_types(
422    ia_drc_config* pstr_drc_config, WORD32 effect_type_requested_total_count,
423    WORD32 effect_type_requested_desired_count, WORD32* requested_effect_type,
424    WORD32* selection_candidate_count,
425    ia_selection_candidate_info_struct* selection_candidate_info) {
426  WORD32 k, err;
427  WORD32 match_found_flag = 0;
428  WORD32 state_requested;
429  WORD32 desired_effect_type_found, fallback_effect_type_found;
430
431  desired_effect_type_found = 0;
432  fallback_effect_type_found = 0;
433  k = 0;
434  while (k < effect_type_requested_desired_count) {
435    state_requested = 1;
436    err = impd_match_effect_type_attempt(
437        pstr_drc_config, requested_effect_type[k], state_requested,
438        &match_found_flag, selection_candidate_count, selection_candidate_info);
439    if (err) return (err);
440    if (match_found_flag) desired_effect_type_found = 1;
441    k++;
442  }
443  if (desired_effect_type_found == 0) {
444    while ((k < effect_type_requested_total_count) && (match_found_flag == 0)) {
445      state_requested = 1;
446      err = impd_match_effect_type_attempt(
447          pstr_drc_config, requested_effect_type[k], state_requested,
448          &match_found_flag, selection_candidate_count,
449          selection_candidate_info);
450      if (err) return (err);
451      if (match_found_flag) fallback_effect_type_found = 1;
452      k++;
453    }
454  }
455
456  return (0);
457}
458
459WORD32 impd_match_dynamic_range(
460    ia_drc_config* pstr_drc_config,
461    ia_drc_loudness_info_set_struct* pstr_loudness_info,
462    ia_drc_sel_proc_params_struct* pstr_drc_sel_proc_params_struct,
463    WORD32 num_drc_requests, WORD32* selection_candidate_count,
464    ia_selection_candidate_info_struct* selection_candidate_info) {
465  ia_drc_instructions_struct* str_drc_instruction_str;
466  WORD32 err, i, k;
467  WORD32 lp_avg_present_val;
468  FLOAT32 lp_avg_val;
469  FLOAT32 deviation_min = 1000.0f;
470  WORD32 selected[DRC_INSTRUCTIONS_COUNT_MAX];
471  WORD32 dynamic_range_measurement_type =
472      pstr_drc_sel_proc_params_struct
473          ->requested_dyn_range_measur_type[num_drc_requests];
474
475  WORD32 requested_dyn_range_range_flag =
476      pstr_drc_sel_proc_params_struct
477          ->requested_dyn_range_range_flag[num_drc_requests];
478
479  FLOAT32 dynamic_range_requested =
480      pstr_drc_sel_proc_params_struct
481          ->requested_dyn_range_value[num_drc_requests];
482
483  FLOAT32 dynamic_range_min_requested =
484      pstr_drc_sel_proc_params_struct
485          ->requested_dyn_range_min_val[num_drc_requests];
486
487  FLOAT32 dynamic_range_max_requested =
488      pstr_drc_sel_proc_params_struct
489          ->requested_dyn_range_max_val[num_drc_requests];
490
491  WORD32* requested_dwnmix_id =
492      pstr_drc_sel_proc_params_struct->requested_dwnmix_id;
493
494  WORD32 album_mode = pstr_drc_sel_proc_params_struct->album_mode;
495
496  k = 0;
497  for (i = 0; i < *selection_candidate_count; i++) {
498    str_drc_instruction_str = &(
499        pstr_drc_config->str_drc_instruction_str[selection_candidate_info[i]
500                                                     .drc_instructions_index]);
501
502    err = impd_loudness_peak_to_average_info(
503        pstr_loudness_info, str_drc_instruction_str,
504        requested_dwnmix_id[selection_candidate_info[i]
505                                .downmix_id_request_index],
506        dynamic_range_measurement_type, album_mode, &lp_avg_present_val,
507        &lp_avg_val);
508    if (err) return (err);
509
510    if (lp_avg_present_val == 1) {
511      if (requested_dyn_range_range_flag == 1) {
512        if ((lp_avg_val >= dynamic_range_min_requested) &&
513            (lp_avg_val <= dynamic_range_max_requested)) {
514          selected[k] = i;
515          k++;
516        }
517      } else {
518        FLOAT32 deviation =
519            (FLOAT32)fabs((FLOAT64)(dynamic_range_requested - lp_avg_val));
520        if (deviation_min >= deviation) {
521          if (deviation_min > deviation) {
522            deviation_min = deviation;
523            k = 0;
524          }
525          selected[k] = i;
526          k++;
527        }
528      }
529    }
530  }
531  if (k > 0) {
532    for (i = 0; i < k; i++) {
533      memcpy(&selection_candidate_info[i],
534             &selection_candidate_info[selected[i]],
535             sizeof(ia_selection_candidate_info_struct));
536    }
537    *selection_candidate_count = k;
538  }
539
540  return (0);
541}
542
543WORD32 impd_match_drc_characteristic_attempt(
544    ia_drc_config* pstr_drc_config, WORD32 requested_drc_characteristic,
545    WORD32* match_found_flag, WORD32* selection_candidate_count,
546    ia_selection_candidate_info_struct* selection_candidate_info) {
547  WORD32 i, k, n, b, m;
548  WORD32 ref_count;
549  WORD32 drc_characteristic;
550  FLOAT32 match_count;
551  WORD32 drc_characteristic_request_1;
552  WORD32 drc_characteristic_request_2;
553  WORD32 drc_characteristic_request_3;
554
555  ia_drc_instructions_struct* str_drc_instruction_str = NULL;
556  ia_uni_drc_coeffs_struct* str_p_loc_drc_coefficients_uni_drc = NULL;
557  ia_gain_set_params_struct* gain_set_params = NULL;
558  *match_found_flag = 0;
559
560  if (requested_drc_characteristic < 1) {
561    return (UNEXPECTED_ERROR);
562  }
563  if (requested_drc_characteristic < 12) {
564    drc_characteristic_request_1 =
565        drc_characteristic_order_default[requested_drc_characteristic - 1][0];
566    drc_characteristic_request_2 =
567        drc_characteristic_order_default[requested_drc_characteristic - 1][1];
568    drc_characteristic_request_3 =
569        drc_characteristic_order_default[requested_drc_characteristic - 1][2];
570  } else {
571    drc_characteristic_request_1 = requested_drc_characteristic;
572    drc_characteristic_request_2 = -1;
573    drc_characteristic_request_3 = -1;
574  }
575
576  if (pstr_drc_config->drc_coefficients_drc_count) {
577    for (i = 0; i < pstr_drc_config->drc_coefficients_drc_count; i++) {
578      str_p_loc_drc_coefficients_uni_drc =
579          &(pstr_drc_config->str_p_loc_drc_coefficients_uni_drc[i]);
580      if (str_p_loc_drc_coefficients_uni_drc->drc_location == LOCATION_SELECTED)
581        break;
582    }
583
584    if (i == pstr_drc_config->drc_coefficients_drc_count) {
585      return (UNEXPECTED_ERROR);
586    }
587  }
588
589  n = 0;
590  for (i = 0; i < *selection_candidate_count; i++) {
591    ref_count = 0;
592    match_count = 0;
593
594    str_drc_instruction_str = &(
595        pstr_drc_config->str_drc_instruction_str[selection_candidate_info[i]
596                                                     .drc_instructions_index]);
597    for (k = 0; k < str_drc_instruction_str->num_drc_ch_groups; k++) {
598      gain_set_params =
599          &(str_p_loc_drc_coefficients_uni_drc->gain_set_params
600                [str_drc_instruction_str->gain_set_index_for_channel_group[k]]);
601      for (b = 0; b < gain_set_params->band_count; b++) {
602        ref_count++;
603        drc_characteristic = gain_set_params->gain_params[b].drc_characteristic;
604        if (drc_characteristic == drc_characteristic_request_1)
605          match_count += 1.0f;
606        else if (drc_characteristic == drc_characteristic_request_2)
607          match_count += 0.75f;
608        else if (drc_characteristic == drc_characteristic_request_3)
609          match_count += 0.5f;
610      }
611    }
612    if (str_drc_instruction_str->depends_on_drc_set_present == 1) {
613      WORD32 depends_on_drc_set = str_drc_instruction_str->depends_on_drc_set;
614      for (m = 0; m < pstr_drc_config->drc_instructions_uni_drc_count; m++) {
615        if (pstr_drc_config->str_drc_instruction_str[m].drc_set_id ==
616            depends_on_drc_set)
617          break;
618      }
619      if (m == pstr_drc_config->drc_instructions_uni_drc_count) {
620        return (UNEXPECTED_ERROR);
621      }
622      str_drc_instruction_str = &(pstr_drc_config->str_drc_instruction_str[m]);
623      if ((str_drc_instruction_str->drc_set_effect &
624           (EFFECT_BIT_FADE | EFFECT_BIT_DUCK_OTHER | EFFECT_BIT_DUCK_SELF)) ==
625          0) {
626        if (str_drc_instruction_str->drc_set_effect != EFFECT_BIT_CLIPPING) {
627          for (k = 0; k < str_drc_instruction_str->num_drc_ch_groups; k++) {
628            gain_set_params =
629                &(str_p_loc_drc_coefficients_uni_drc->gain_set_params
630                      [str_drc_instruction_str
631                           ->gain_set_index_for_channel_group[k]]);
632            for (b = 0; b < gain_set_params->band_count; b++) {
633              ref_count++;
634              drc_characteristic =
635                  gain_set_params->gain_params[b].drc_characteristic;
636              if (drc_characteristic == drc_characteristic_request_1)
637                match_count += 1.0f;
638              else if (drc_characteristic == drc_characteristic_request_2)
639                match_count += 0.75f;
640              else if (drc_characteristic == drc_characteristic_request_3)
641                match_count += 0.5;
642            }
643          }
644        }
645      }
646    }
647    if ((ref_count > 0) && (((FLOAT32)match_count) > 0.5f * ref_count)) {
648      memcpy(&selection_candidate_info[n], &selection_candidate_info[i],
649             sizeof(ia_selection_candidate_info_struct));
650      n++;
651    }
652  }
653  if (n > 0) {
654    *selection_candidate_count = n;
655    *match_found_flag = 1;
656  }
657
658  return (0);
659}
660
661WORD32 impd_match_drc_characteristic(
662    ia_drc_config* pstr_drc_config, WORD32 requested_drc_characteristic,
663    WORD32* selection_candidate_count,
664    ia_selection_candidate_info_struct* selection_candidate_info) {
665  WORD32 k, err;
666  WORD32 match_found_flag = 0;
667
668  WORD32* drc_characteristic_order =
669      drc_characteristic_order_default[requested_drc_characteristic - 1];
670  WORD32 drc_characteristic_order_count =
671      sizeof(drc_characteristic_order_default[requested_drc_characteristic]) /
672      sizeof(WORD32);
673  k = 0;
674  while ((k < drc_characteristic_order_count) && (match_found_flag == 0) &&
675         (drc_characteristic_order[k] > 0)) {
676    err = impd_match_drc_characteristic_attempt(
677        pstr_drc_config, drc_characteristic_order[k], &match_found_flag,
678        selection_candidate_count, selection_candidate_info);
679    if (err) return (err);
680    k++;
681  }
682  return (0);
683}
684
685WORD32 impd_drc_set_preselection(
686    ia_drc_sel_proc_params_struct* pstr_drc_sel_proc_params_struct,
687    ia_drc_config* pstr_drc_config,
688    ia_drc_loudness_info_set_struct* pstr_loudness_info,
689    WORD32 restrict_to_drc_with_album_loudness,
690    ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc,
691    WORD32* selection_candidate_count,
692    ia_selection_candidate_info_struct* selection_candidate_info) {
693  WORD32 i, j, k, l, d, n, err;
694  WORD32 downmix_id_match = 0;
695
696  WORD32 selection_candidate_step_2_count;
697  ia_selection_candidate_info_struct
698      selection_candidate_info_step_2[SELECTION_CANDIDATE_COUNT_MAX];
699
700  WORD32 num_downmix_id_requests =
701      pstr_drc_sel_proc_params_struct->num_downmix_id_requests;
702  WORD32* requested_dwnmix_id =
703      pstr_drc_sel_proc_params_struct->requested_dwnmix_id;
704  FLOAT32 output_peak_level_max =
705      pstr_drc_sel_proc_params_struct->output_peak_level_max;
706  WORD32 loudness_deviation_max =
707      pstr_drc_sel_proc_params_struct->loudness_deviation_max;
708  WORD32* drc_set_id_valid_flag = pstr_drc_uni_sel_proc->drc_set_id_valid_flag;
709  WORD32* eq_set_id_valid_flag = pstr_drc_uni_sel_proc->eq_set_id_valid_flag;
710
711  FLOAT32 output_peak_level_min = 1000.0f;
712  FLOAT32 adjustment;
713  WORD32 loudness_drc_set_id_requested;
714
715  WORD32 num_compression_eq_count = 0;
716  WORD32 num_compression_eq_id[16];
717
718  WORD32 loudness_info_count = 0;
719  WORD32 eq_set_id_loudness[16];
720  FLOAT32 loudness_normalization_gain_db[16];
721  FLOAT32 loudness[16];
722  WORD32 peak_info_count;
723  WORD32 eq_set_id_Peak[16];
724  FLOAT32 signal_peak_level[16];
725  WORD32 explicit_peak_information_present[16];
726
727  ia_uni_drc_coeffs_struct* str_p_loc_drc_coefficients_uni_drc = NULL;
728  ia_drc_instructions_struct* str_drc_instruction_str = NULL;
729
730  impd_select_drc_coeff3(pstr_drc_config, &str_p_loc_drc_coefficients_uni_drc);
731
732  k = 0;
733  for (d = 0; d < num_downmix_id_requests; d++) {
734    err = impd_find_eq_set_no_compression(
735        pstr_drc_config, requested_dwnmix_id[d], &num_compression_eq_count,
736        num_compression_eq_id);
737    if (err) return (err);
738    for (i = 0; i < pstr_drc_config->drc_instructions_count_plus; i++) {
739      downmix_id_match = 0;
740      str_drc_instruction_str = &(pstr_drc_config->str_drc_instruction_str[i]);
741
742      for (j = 0; j < str_drc_instruction_str->dwnmix_id_count; j++) {
743        if ((str_drc_instruction_str->downmix_id[j] ==
744             requested_dwnmix_id[d]) ||
745            ((str_drc_instruction_str->downmix_id[j] == ID_FOR_BASE_LAYOUT) &&
746             (str_drc_instruction_str->drc_set_id > 0)) ||
747            (str_drc_instruction_str->downmix_id[j] == ID_FOR_ANY_DOWNMIX)) {
748          downmix_id_match = 1;
749        }
750      }
751      if (downmix_id_match == 1) {
752        if (pstr_drc_sel_proc_params_struct->dynamic_range_control_on == 1) {
753          if ((str_drc_instruction_str->drc_set_effect != EFFECT_BIT_FADE) &&
754              (str_drc_instruction_str->drc_set_effect !=
755               EFFECT_BIT_DUCK_OTHER) &&
756              (str_drc_instruction_str->drc_set_effect !=
757               EFFECT_BIT_DUCK_SELF) &&
758              (str_drc_instruction_str->drc_set_effect != 0 ||
759               str_drc_instruction_str->drc_set_id < 0) &&
760              (((str_drc_instruction_str->depends_on_drc_set_present == 0) &&
761                (str_drc_instruction_str->no_independent_use == 0)) ||
762               (str_drc_instruction_str->depends_on_drc_set_present == 1))) {
763            WORD32 drc_is_permitted = 1;
764            if (str_drc_instruction_str->drc_set_id > 0) {
765              drc_is_permitted =
766                  drc_set_id_valid_flag[str_drc_instruction_str->drc_set_id];
767            }
768            if (drc_is_permitted == 1) {
769              err = impd_init_loudness_control(
770                  pstr_drc_sel_proc_params_struct, pstr_loudness_info,
771                  requested_dwnmix_id[d], str_drc_instruction_str->drc_set_id,
772
773                  num_compression_eq_count, num_compression_eq_id,
774                  &loudness_info_count, eq_set_id_loudness,
775                  loudness_normalization_gain_db, loudness);
776              if (err) return (err);
777
778              err = impd_signal_peak_level_info(
779                  pstr_drc_config, pstr_loudness_info, str_drc_instruction_str,
780                  requested_dwnmix_id[d],
781                  pstr_drc_sel_proc_params_struct->album_mode,
782                  num_compression_eq_count, num_compression_eq_id,
783                  &peak_info_count, eq_set_id_Peak, signal_peak_level,
784                  explicit_peak_information_present);
785              if (err) return (err);
786
787              for (l = 0; l < loudness_info_count; l++) {
788                WORD32 match_found_flag = 0;
789                WORD32 p;
790                selection_candidate_info[k].loudness_norm_db_gain_adjusted =
791                    loudness_normalization_gain_db[l];
792
793                selection_candidate_info[k]
794                    .loudness_norm_db_gain_adjusted = min(
795                    selection_candidate_info[k].loudness_norm_db_gain_adjusted,
796                    pstr_drc_sel_proc_params_struct->loudness_norm_gain_db_max);
797
798                if (loudness[l] != UNDEFINED_LOUDNESS_VALUE) {
799                  selection_candidate_info[k].output_loudness =
800                      loudness[l] +
801                      selection_candidate_info[k]
802                          .loudness_norm_db_gain_adjusted;
803                } else {
804                  selection_candidate_info[k].output_loudness =
805                      UNDEFINED_LOUDNESS_VALUE;
806                }
807
808                for (p = 0; p < peak_info_count; p++) {
809                  if (eq_set_id_Peak[p] == eq_set_id_loudness[l]) {
810                    if (eq_set_id_valid_flag[eq_set_id_Peak[p]] == 1)
811
812                    {
813                      match_found_flag = 1;
814                      break;
815                    }
816                  }
817                }
818                if (match_found_flag == 1) {
819                  selection_candidate_info[k].output_peak_level =
820                      signal_peak_level[p] +
821                      selection_candidate_info[k]
822                          .loudness_norm_db_gain_adjusted;
823                } else {
824                  selection_candidate_info[k].output_peak_level =
825                      selection_candidate_info[k]
826                          .loudness_norm_db_gain_adjusted;
827                }
828                if ((str_drc_instruction_str->requires_eq == 1) &&
829                    (eq_set_id_valid_flag[eq_set_id_loudness[l]] == 0))
830                  continue;
831                selection_candidate_info[k].drc_instructions_index = i;
832                selection_candidate_info[k].downmix_id_request_index = d;
833                selection_candidate_info[k].eq_set_id = eq_set_id_loudness[l];
834                if (explicit_peak_information_present[p] == 1) {
835                  selection_candidate_info[k].selection_flags =
836                      SELECTION_FLAG_EXPLICIT_PEAK_INFO_PRESENT;
837                } else {
838                  selection_candidate_info[k].selection_flags = 0;
839                }
840                impd_mixing_level_info(
841                    pstr_drc_sel_proc_params_struct, pstr_loudness_info,
842                    requested_dwnmix_id[d], str_drc_instruction_str->drc_set_id,
843                    eq_set_id_loudness[l],
844                    &selection_candidate_info[k].mixing_level);
845                if (str_drc_instruction_str->drc_set_target_loudness_present &&
846                    ((pstr_drc_sel_proc_params_struct
847                          ->loudness_normalization_on &&
848                      str_drc_instruction_str
849                              ->drc_set_target_loudness_value_upper >=
850                          pstr_drc_sel_proc_params_struct->target_loudness &&
851                      str_drc_instruction_str
852                              ->drc_set_target_loudness_value_lower <
853                          pstr_drc_sel_proc_params_struct->target_loudness) ||
854                     !pstr_drc_sel_proc_params_struct
855                          ->loudness_normalization_on)) {
856                  selection_candidate_info[k].selection_flags |=
857                      SELECTION_FLAG_DRC_TARGET_LOUDNESS_MATCH;
858                  if (!explicit_peak_information_present[p]) {
859                    if (pstr_drc_sel_proc_params_struct
860                            ->loudness_normalization_on) {
861                      selection_candidate_info[k].output_peak_level =
862                          pstr_drc_sel_proc_params_struct->target_loudness -
863                          str_drc_instruction_str
864                              ->drc_set_target_loudness_value_upper;
865                    } else {
866                      selection_candidate_info[k].output_peak_level = 0.0f;
867                    }
868                  }
869                }
870                if ((selection_candidate_info[k].selection_flags &
871                         (SELECTION_FLAG_DRC_TARGET_LOUDNESS_MATCH |
872                          SELECTION_FLAG_EXPLICIT_PEAK_INFO_PRESENT) ||
873                     !str_drc_instruction_str
874                          ->drc_set_target_loudness_present)) {
875                  k++;
876                } else {
877                }
878              }
879            }
880          }
881        } else {
882          if (str_drc_instruction_str->drc_set_id < 0) {
883            err = impd_init_loudness_control(
884                pstr_drc_sel_proc_params_struct, pstr_loudness_info,
885                requested_dwnmix_id[d], str_drc_instruction_str->drc_set_id,
886                num_compression_eq_count, num_compression_eq_id,
887                &loudness_info_count, eq_set_id_loudness,
888                loudness_normalization_gain_db, loudness);
889            if (err) return (err);
890
891            err = impd_signal_peak_level_info(
892                pstr_drc_config, pstr_loudness_info, str_drc_instruction_str,
893                requested_dwnmix_id[d],
894                pstr_drc_sel_proc_params_struct->album_mode,
895                num_compression_eq_count, num_compression_eq_id,
896                &peak_info_count, eq_set_id_Peak, signal_peak_level,
897                explicit_peak_information_present);
898            if (err) return (err);
899            for (l = 0; l < loudness_info_count; l++) {
900              WORD32 match_found_flag = 0;
901              WORD32 p;
902              for (p = 0; p < peak_info_count; p++) {
903                if (eq_set_id_Peak[p] == eq_set_id_loudness[l]) {
904                  if (eq_set_id_valid_flag[eq_set_id_Peak[p]] == 1) {
905                    match_found_flag = 1;
906                    break;
907                  }
908                }
909              }
910              if (match_found_flag == 1) {
911                adjustment = max(
912                    0.0f,
913                    signal_peak_level[p] + loudness_normalization_gain_db[l] -
914                        pstr_drc_sel_proc_params_struct->output_peak_level_max);
915                adjustment = min(adjustment, max(0.0f, loudness_deviation_max));
916                selection_candidate_info[k].loudness_norm_db_gain_adjusted =
917                    loudness_normalization_gain_db[l] - adjustment;
918
919                selection_candidate_info[k]
920                    .loudness_norm_db_gain_adjusted = min(
921                    selection_candidate_info[k].loudness_norm_db_gain_adjusted,
922                    pstr_drc_sel_proc_params_struct->loudness_norm_gain_db_max);
923
924                selection_candidate_info[k].output_peak_level =
925                    signal_peak_level[p] +
926                    selection_candidate_info[k].loudness_norm_db_gain_adjusted;
927                if (loudness[l] != UNDEFINED_LOUDNESS_VALUE) {
928                  selection_candidate_info[k].output_loudness =
929                      loudness[l] +
930                      selection_candidate_info[k]
931                          .loudness_norm_db_gain_adjusted;
932                } else {
933                  selection_candidate_info[k].output_loudness =
934                      UNDEFINED_LOUDNESS_VALUE;
935                }
936                selection_candidate_info[k].drc_instructions_index = i;
937                selection_candidate_info[k].downmix_id_request_index = d;
938                selection_candidate_info[k].eq_set_id = eq_set_id_loudness[l];
939                if (explicit_peak_information_present[p] == 1) {
940                  selection_candidate_info[k].selection_flags =
941                      SELECTION_FLAG_EXPLICIT_PEAK_INFO_PRESENT;
942                } else {
943                  selection_candidate_info[k].selection_flags = 0;
944                }
945                impd_mixing_level_info(
946                    pstr_drc_sel_proc_params_struct, pstr_loudness_info,
947                    requested_dwnmix_id[d], str_drc_instruction_str->drc_set_id,
948                    eq_set_id_loudness[l],
949                    &selection_candidate_info[k].mixing_level);
950                k++;
951              }
952            }
953          }
954        }
955      }
956    }
957  }
958  *selection_candidate_count = k;
959
960  if (*selection_candidate_count > SELECTION_CANDIDATE_COUNT_MAX) {
961    return UNEXPECTED_ERROR;
962  } else if (pstr_drc_sel_proc_params_struct->dynamic_range_control_on == 1) {
963    n = 0;
964    for (k = 0; k < *selection_candidate_count; k++) {
965      str_drc_instruction_str =
966          &(pstr_drc_config->str_drc_instruction_str
967                [selection_candidate_info[k].drc_instructions_index]);
968
969      if (pstr_drc_sel_proc_params_struct->eq_set_purpose_request !=
970          EQ_PURPOSE_EQ_OFF) {
971        WORD32 matching_eq_set_count = 0;
972        WORD32 matching_eq_instrucions_index[64];
973        err = impd_match_eq_set(
974            pstr_drc_config, requested_dwnmix_id[selection_candidate_info[k]
975                                                     .downmix_id_request_index],
976            str_drc_instruction_str->drc_set_id, eq_set_id_valid_flag,
977            &matching_eq_set_count, matching_eq_instrucions_index);
978        if (err) return (err);
979        for (j = 0; j < matching_eq_set_count; j++) {
980          memcpy(&selection_candidate_info_step_2[n],
981                 &selection_candidate_info[k],
982                 sizeof(ia_selection_candidate_info_struct));
983          selection_candidate_info_step_2[n].eq_set_id =
984              pstr_drc_config->str_drc_config_ext
985                  .str_eq_instructions[matching_eq_instrucions_index[j]]
986                  .eq_set_id;
987          n++;
988        }
989      }
990      if (str_drc_instruction_str->requires_eq == 0) {
991        memcpy(&selection_candidate_info_step_2[n],
992               &selection_candidate_info[k],
993               sizeof(ia_selection_candidate_info_struct));
994        selection_candidate_info_step_2[n].eq_set_id = 0;
995        n++;
996      }
997    }
998    for (k = 0; k < n; k++) {
999      memcpy(&selection_candidate_info[k], &selection_candidate_info_step_2[k],
1000             sizeof(ia_selection_candidate_info_struct));
1001    }
1002    *selection_candidate_count = n;
1003    n = 0;
1004    for (k = 0; k < *selection_candidate_count; k++) {
1005      if ((selection_candidate_info[k].selection_flags &
1006           SELECTION_FLAG_DRC_TARGET_LOUDNESS_MATCH) &&
1007          !(selection_candidate_info[k].selection_flags &
1008            SELECTION_FLAG_EXPLICIT_PEAK_INFO_PRESENT)) {
1009        memcpy(&selection_candidate_info_step_2[n],
1010               &selection_candidate_info[k],
1011               sizeof(ia_selection_candidate_info_struct));
1012        n++;
1013      } else {
1014        if (selection_candidate_info[k].output_peak_level <=
1015            output_peak_level_max) {
1016          memcpy(&selection_candidate_info_step_2[n],
1017                 &selection_candidate_info[k],
1018                 sizeof(ia_selection_candidate_info_struct));
1019          n++;
1020        }
1021        if (selection_candidate_info[k].output_peak_level <
1022            output_peak_level_min) {
1023          output_peak_level_min = selection_candidate_info[k].output_peak_level;
1024        }
1025      }
1026    }
1027    selection_candidate_step_2_count = n;
1028    if (selection_candidate_step_2_count == 0) {
1029      n = 0;
1030      for (k = 0; k < *selection_candidate_count; k++) {
1031        if ((selection_candidate_info[k].selection_flags &
1032             SELECTION_FLAG_DRC_TARGET_LOUDNESS_MATCH) &&
1033            (selection_candidate_info[k].selection_flags &
1034             SELECTION_FLAG_EXPLICIT_PEAK_INFO_PRESENT)) {
1035          memcpy(&selection_candidate_info_step_2[n],
1036                 &selection_candidate_info[k],
1037                 sizeof(ia_selection_candidate_info_struct));
1038          n++;
1039        }
1040      }
1041      selection_candidate_step_2_count = n;
1042    }
1043    if (selection_candidate_step_2_count == 0) {
1044      n = 0;
1045      for (k = 0; k < *selection_candidate_count; k++) {
1046        if (selection_candidate_info_step_2[k].output_peak_level <
1047            output_peak_level_min + 1.0f) {
1048          memcpy(&selection_candidate_info_step_2[n],
1049                 &selection_candidate_info[k],
1050                 sizeof(ia_selection_candidate_info_struct));
1051          adjustment =
1052              max(0.0f, selection_candidate_info_step_2[n].output_peak_level -
1053                            output_peak_level_max);
1054          adjustment = min(adjustment, max(0.0f, loudness_deviation_max));
1055          selection_candidate_info_step_2[n].loudness_norm_db_gain_adjusted -=
1056              adjustment;
1057          selection_candidate_info_step_2[n].output_peak_level -= adjustment;
1058          selection_candidate_info_step_2[n].output_loudness -= adjustment;
1059          n++;
1060        }
1061      }
1062      selection_candidate_step_2_count = n;
1063    }
1064
1065    for (n = 0; n < selection_candidate_step_2_count; n++) {
1066      memcpy(&selection_candidate_info[n], &selection_candidate_info_step_2[n],
1067             sizeof(ia_selection_candidate_info_struct));
1068    }
1069    *selection_candidate_count = selection_candidate_step_2_count;
1070  }
1071
1072  if (restrict_to_drc_with_album_loudness == 1) {
1073    j = 0;
1074    for (k = 0; k < *selection_candidate_count; k++) {
1075      loudness_drc_set_id_requested =
1076          max(0, pstr_drc_config
1077                     ->str_drc_instruction_str[selection_candidate_info[k]
1078                                                   .drc_instructions_index]
1079                     .drc_set_id);
1080      for (n = 0; n < pstr_loudness_info->loudness_info_album_count; n++) {
1081        if (loudness_drc_set_id_requested ==
1082            pstr_loudness_info->str_loudness_info_album[n].drc_set_id) {
1083          memcpy(&selection_candidate_info[j], &selection_candidate_info[k],
1084                 sizeof(ia_selection_candidate_info_struct));
1085          j++;
1086          break;
1087        }
1088      }
1089    }
1090    *selection_candidate_count = j;
1091  }
1092  return (0);
1093}
1094
1095WORD32 impd_drc_set_final_selection(
1096    ia_drc_config* pstr_drc_config,
1097    ia_drc_sel_proc_params_struct* pstr_drc_sel_proc_params_struct,
1098    WORD32* selection_candidate_count,
1099    ia_selection_candidate_info_struct* selection_candidate_info,
1100    WORD32* eq_set_id_valid_flag) {
1101  WORD32 k, i, n, err;
1102  WORD32 selection_candidate_step_2_count;
1103  ia_selection_candidate_info_struct
1104      selection_candidate_info_step_2[SELECTION_CANDIDATE_COUNT_MAX];
1105  WORD32 drc_set_id_max;
1106  FLOAT32 output_level_max;
1107  FLOAT32 output_level_min;
1108  WORD32 effect_count, effect_count_min;
1109  WORD32 effect_types_request_table_size;
1110  WORD32 drc_set_target_loudness_val_upper_min;
1111  ia_drc_instructions_struct* str_drc_instruction_str;
1112  ia_drc_instructions_struct* drc_instructions_dependent;
1113
1114  if (pstr_drc_sel_proc_params_struct->eq_set_purpose_request > 0) {
1115    WORD32 eq_purpose_requested =
1116        pstr_drc_sel_proc_params_struct->eq_set_purpose_request;
1117
1118    impd_match_eq_set_purpose(pstr_drc_config, eq_purpose_requested,
1119                              eq_set_id_valid_flag, selection_candidate_count,
1120                              selection_candidate_info,
1121                              selection_candidate_info_step_2);
1122  }
1123
1124  output_level_min = 10000.0f;
1125  k = 0;
1126  for (i = 0; i < *selection_candidate_count; i++) {
1127    if (output_level_min >= selection_candidate_info[i].output_peak_level) {
1128      if (output_level_min > selection_candidate_info[i].output_peak_level) {
1129        output_level_min = selection_candidate_info[i].output_peak_level;
1130        k = 0;
1131      }
1132      memcpy(&selection_candidate_info_step_2[k], &selection_candidate_info[i],
1133             sizeof(ia_selection_candidate_info_struct));
1134      k++;
1135    }
1136  }
1137  selection_candidate_step_2_count = k;
1138
1139  if (output_level_min <= 0.0f) {
1140    selection_candidate_step_2_count = *selection_candidate_count;
1141    k = 0;
1142    for (i = 0; i < selection_candidate_step_2_count; i++) {
1143      if (selection_candidate_info[i].output_peak_level <= 0.0f) {
1144        memcpy(&selection_candidate_info_step_2[k],
1145               &selection_candidate_info[i],
1146               sizeof(ia_selection_candidate_info_struct));
1147        k++;
1148      }
1149    }
1150    selection_candidate_step_2_count = k;
1151
1152    k = 0;
1153    for (i = 0; i < selection_candidate_step_2_count; i++) {
1154      str_drc_instruction_str =
1155          &(pstr_drc_config->str_drc_instruction_str
1156                [selection_candidate_info_step_2[i].drc_instructions_index]);
1157      for (n = 0; n < str_drc_instruction_str->dwnmix_id_count; n++) {
1158        if (pstr_drc_sel_proc_params_struct->requested_dwnmix_id
1159                [selection_candidate_info_step_2[i].downmix_id_request_index] ==
1160            str_drc_instruction_str->downmix_id[n]) {
1161          memcpy(&selection_candidate_info_step_2[k],
1162                 &selection_candidate_info_step_2[i],
1163                 sizeof(ia_selection_candidate_info_struct));
1164          k++;
1165        }
1166      }
1167    }
1168    if (k > 0) {
1169      selection_candidate_step_2_count = k;
1170    }
1171
1172    effect_types_request_table_size =
1173        sizeof(effect_types_request_table) / sizeof(WORD32);
1174    effect_count_min = 100;
1175    k = 0;
1176    for (i = 0; i < selection_candidate_step_2_count; i++) {
1177      str_drc_instruction_str =
1178          &(pstr_drc_config->str_drc_instruction_str
1179                [selection_candidate_info_step_2[i].drc_instructions_index]);
1180      effect_count = 0;
1181      if (str_drc_instruction_str->depends_on_drc_set_present == 1) {
1182        err = impd_get_dependent_drc_instructions(pstr_drc_config,
1183                                                  str_drc_instruction_str,
1184                                                  &drc_instructions_dependent);
1185        if (err) return (err);
1186
1187        for (n = 0; n < effect_types_request_table_size; n++) {
1188          if (effect_types_request_table[n] != EFFECT_BIT_GENERAL_COMPR) {
1189            if (((str_drc_instruction_str->drc_set_effect &
1190                  effect_types_request_table[n]) != 0x0) ||
1191                ((drc_instructions_dependent->drc_set_effect &
1192                  effect_types_request_table[n]) != 0x0)) {
1193              effect_count++;
1194            }
1195          }
1196        }
1197      } else {
1198        for (n = 0; n < effect_types_request_table_size; n++) {
1199          if (effect_types_request_table[n] != EFFECT_BIT_GENERAL_COMPR) {
1200            if ((str_drc_instruction_str->drc_set_effect &
1201                 effect_types_request_table[n]) != 0x0) {
1202              effect_count++;
1203            }
1204          }
1205        }
1206      }
1207      if (effect_count_min >= effect_count) {
1208        if (effect_count_min > effect_count) {
1209          effect_count_min = effect_count;
1210          k = 0;
1211        }
1212        memcpy(&selection_candidate_info_step_2[k],
1213               &selection_candidate_info_step_2[i],
1214               sizeof(ia_selection_candidate_info_struct));
1215        k++;
1216      }
1217    }
1218    selection_candidate_step_2_count = k;
1219
1220    drc_set_target_loudness_val_upper_min = 100;
1221    k = 0;
1222    for (i = 0; i < selection_candidate_step_2_count; i++) {
1223      if (selection_candidate_info_step_2[i].selection_flags &
1224          SELECTION_FLAG_DRC_TARGET_LOUDNESS_MATCH) {
1225        k++;
1226      }
1227    }
1228    if (k != 0 && k != selection_candidate_step_2_count) {
1229      k = 0;
1230      for (i = 0; i < selection_candidate_step_2_count; i++) {
1231        if (!(selection_candidate_info_step_2[i].selection_flags &
1232              SELECTION_FLAG_DRC_TARGET_LOUDNESS_MATCH)) {
1233          memcpy(&selection_candidate_info_step_2[k],
1234                 &selection_candidate_info_step_2[i],
1235                 sizeof(ia_selection_candidate_info_struct));
1236          k++;
1237        }
1238      }
1239      selection_candidate_step_2_count = k;
1240    } else if (k == selection_candidate_step_2_count) {
1241      k = 0;
1242      for (i = 0; i < selection_candidate_step_2_count; i++) {
1243        str_drc_instruction_str =
1244            &(pstr_drc_config->str_drc_instruction_str
1245                  [selection_candidate_info_step_2[i].drc_instructions_index]);
1246        if (str_drc_instruction_str->drc_set_target_loudness_present != 1) {
1247          return UNEXPECTED_ERROR;
1248        }
1249        if (drc_set_target_loudness_val_upper_min >=
1250            str_drc_instruction_str->drc_set_target_loudness_value_upper) {
1251          if (drc_set_target_loudness_val_upper_min >
1252              str_drc_instruction_str->drc_set_target_loudness_value_upper) {
1253            drc_set_target_loudness_val_upper_min =
1254                str_drc_instruction_str->drc_set_target_loudness_value_upper;
1255            k = 0;
1256          }
1257          memcpy(&selection_candidate_info_step_2[k],
1258                 &selection_candidate_info_step_2[i],
1259                 sizeof(ia_selection_candidate_info_struct));
1260          k++;
1261        }
1262      }
1263      selection_candidate_step_2_count = k;
1264    }
1265
1266    k = 0;
1267    for (i = 0; i < selection_candidate_step_2_count; i++) {
1268      str_drc_instruction_str =
1269          &(pstr_drc_config->str_drc_instruction_str
1270                [selection_candidate_info_step_2[i].drc_instructions_index]);
1271      if (str_drc_instruction_str->drc_set_target_loudness_present &&
1272          pstr_drc_sel_proc_params_struct->loudness_normalization_on &&
1273          str_drc_instruction_str->drc_set_target_loudness_value_upper >=
1274              pstr_drc_sel_proc_params_struct->target_loudness &&
1275          str_drc_instruction_str->drc_set_target_loudness_value_lower <
1276              pstr_drc_sel_proc_params_struct->target_loudness) {
1277        k++;
1278      }
1279    }
1280    if (k != 0 && k != selection_candidate_step_2_count) {
1281      k = 0;
1282      for (i = 0; i < selection_candidate_step_2_count; i++) {
1283        str_drc_instruction_str =
1284            &(pstr_drc_config->str_drc_instruction_str
1285                  [selection_candidate_info_step_2[i].drc_instructions_index]);
1286        if (str_drc_instruction_str->drc_set_target_loudness_present &&
1287            pstr_drc_sel_proc_params_struct->loudness_normalization_on &&
1288            str_drc_instruction_str->drc_set_target_loudness_value_upper >=
1289                pstr_drc_sel_proc_params_struct->target_loudness &&
1290            str_drc_instruction_str->drc_set_target_loudness_value_lower <
1291                pstr_drc_sel_proc_params_struct->target_loudness) {
1292          memcpy(&selection_candidate_info_step_2[k],
1293                 &selection_candidate_info_step_2[i],
1294                 sizeof(ia_selection_candidate_info_struct));
1295          k++;
1296        }
1297      }
1298      selection_candidate_step_2_count = k;
1299      drc_set_target_loudness_val_upper_min = 100;
1300      k = 0;
1301      for (i = 0; i < selection_candidate_step_2_count; i++) {
1302        str_drc_instruction_str =
1303            &(pstr_drc_config->str_drc_instruction_str
1304                  [selection_candidate_info_step_2[i].drc_instructions_index]);
1305        if (str_drc_instruction_str->drc_set_target_loudness_present != 1) {
1306          return UNEXPECTED_ERROR;
1307        }
1308        if (drc_set_target_loudness_val_upper_min >=
1309            str_drc_instruction_str->drc_set_target_loudness_value_upper) {
1310          if (drc_set_target_loudness_val_upper_min >
1311              str_drc_instruction_str->drc_set_target_loudness_value_upper) {
1312            drc_set_target_loudness_val_upper_min =
1313                str_drc_instruction_str->drc_set_target_loudness_value_upper;
1314            k = 0;
1315          }
1316          memcpy(&selection_candidate_info_step_2[k],
1317                 &selection_candidate_info_step_2[i],
1318                 sizeof(ia_selection_candidate_info_struct));
1319          k++;
1320        }
1321      }
1322      selection_candidate_step_2_count = k;
1323    } else if (k == selection_candidate_step_2_count) {
1324      drc_set_target_loudness_val_upper_min = 100;
1325      k = 0;
1326      for (i = 0; i < selection_candidate_step_2_count; i++) {
1327        str_drc_instruction_str =
1328            &(pstr_drc_config->str_drc_instruction_str
1329                  [selection_candidate_info_step_2[i].drc_instructions_index]);
1330        if (str_drc_instruction_str->drc_set_target_loudness_present != 1) {
1331          return UNEXPECTED_ERROR;
1332        }
1333        if (drc_set_target_loudness_val_upper_min >=
1334            str_drc_instruction_str->drc_set_target_loudness_value_upper) {
1335          if (drc_set_target_loudness_val_upper_min >
1336              str_drc_instruction_str->drc_set_target_loudness_value_upper) {
1337            drc_set_target_loudness_val_upper_min =
1338                str_drc_instruction_str->drc_set_target_loudness_value_upper;
1339            k = 0;
1340          }
1341          memcpy(&selection_candidate_info_step_2[k],
1342                 &selection_candidate_info_step_2[i],
1343                 sizeof(ia_selection_candidate_info_struct));
1344          k++;
1345        }
1346      }
1347      selection_candidate_step_2_count = k;
1348    }
1349    k = 0;
1350    output_level_max = -1000.0f;
1351    for (i = 0; i < selection_candidate_step_2_count; i++) {
1352      if ((selection_candidate_info_step_2[i].output_peak_level <= 0.0f) &&
1353          (output_level_max <=
1354           selection_candidate_info_step_2[i].output_peak_level)) {
1355        if (output_level_max <
1356            selection_candidate_info_step_2[i].output_peak_level) {
1357          output_level_max =
1358              selection_candidate_info_step_2[i].output_peak_level;
1359          k = 0;
1360        }
1361        memcpy(&selection_candidate_info_step_2[k],
1362               &selection_candidate_info_step_2[i],
1363               sizeof(ia_selection_candidate_info_struct));
1364        k++;
1365        output_level_max = selection_candidate_info_step_2[i].output_peak_level;
1366      }
1367    }
1368    selection_candidate_step_2_count = k;
1369  }
1370
1371  drc_set_id_max = -1000;
1372  for (i = 0; i < selection_candidate_step_2_count; i++) {
1373    str_drc_instruction_str =
1374        &(pstr_drc_config->str_drc_instruction_str
1375              [selection_candidate_info_step_2[i].drc_instructions_index]);
1376    if (drc_set_id_max < str_drc_instruction_str->drc_set_id) {
1377      drc_set_id_max = str_drc_instruction_str->drc_set_id;
1378      memcpy(&selection_candidate_info_step_2[0],
1379             &selection_candidate_info_step_2[i],
1380             sizeof(ia_selection_candidate_info_struct));
1381    }
1382  }
1383  memcpy(&selection_candidate_info[0], &selection_candidate_info_step_2[0],
1384         sizeof(ia_selection_candidate_info_struct));
1385  *selection_candidate_count = 1;
1386
1387  return 0;
1388}
1389
1390WORD32 impd_select_drc_set(ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc,
1391                           WORD32* drc_set_id_selected,
1392                           WORD32* eq_set_id_selected, WORD32* loud_eq_id_sel) {
1393  WORD32 i, err;
1394
1395  ia_drc_sel_proc_params_struct* pstr_drc_sel_proc_params_struct =
1396      &pstr_drc_uni_sel_proc->uni_drc_sel_proc_params;
1397  ia_drc_config* pstr_drc_config = &pstr_drc_uni_sel_proc->drc_config;
1398  ia_drc_loudness_info_set_struct* pstr_loudness_info =
1399      &pstr_drc_uni_sel_proc->loudness_info_set;
1400
1401  WORD32 selection_candidate_count = 0;
1402  WORD32 restrict_to_drc_with_album_loudness = 0;
1403  ia_selection_candidate_info_struct
1404      selection_candidate_info[SELECTION_CANDIDATE_COUNT_MAX];
1405
1406  //    WORD32 selected_eq_set_count = 0;
1407
1408  if (pstr_drc_sel_proc_params_struct->album_mode == 1) {
1409    restrict_to_drc_with_album_loudness = 1;
1410  }
1411
1412  while (!selection_candidate_count) {
1413    impd_drc_set_preselection(
1414        pstr_drc_sel_proc_params_struct, pstr_drc_config, pstr_loudness_info,
1415        restrict_to_drc_with_album_loudness, pstr_drc_uni_sel_proc,
1416        &selection_candidate_count, selection_candidate_info);
1417
1418    if (selection_candidate_count == 0) {
1419      if (restrict_to_drc_with_album_loudness == 1) {
1420        restrict_to_drc_with_album_loudness = 0;
1421        continue;
1422      } else {
1423        return (UNEXPECTED_ERROR);
1424      }
1425    }
1426
1427    err = impd_validate_requested_drc_feature(pstr_drc_sel_proc_params_struct);
1428    if (err) return (err);
1429
1430    if (pstr_drc_sel_proc_params_struct->dynamic_range_control_on == 1) {
1431      if (pstr_drc_sel_proc_params_struct->num_drc_feature_requests > 0) {
1432        for (i = 0;
1433             i < pstr_drc_sel_proc_params_struct->num_drc_feature_requests;
1434             i++) {
1435          switch (pstr_drc_sel_proc_params_struct->drc_feature_req_type[i]) {
1436            case MATCH_EFFECT_TYPE:
1437              err = impd_match_effect_types(
1438                  pstr_drc_config,
1439                  pstr_drc_sel_proc_params_struct->requested_num_drc_effects[i],
1440                  pstr_drc_sel_proc_params_struct
1441                      ->desired_num_drc_effects_of_requested[i],
1442                  pstr_drc_sel_proc_params_struct->requested_drc_effect_type[i],
1443                  &selection_candidate_count, selection_candidate_info);
1444              if (err) return (err);
1445              break;
1446            case MATCH_DYNAMIC_RANGE:
1447              err = impd_match_dynamic_range(
1448                  pstr_drc_config, pstr_loudness_info,
1449                  pstr_drc_sel_proc_params_struct, i,
1450                  &selection_candidate_count, selection_candidate_info);
1451              if (err) return (err);
1452              break;
1453            case MATCH_DRC_CHARACTERISTIC:
1454              err = impd_match_drc_characteristic(
1455                  pstr_drc_config, pstr_drc_sel_proc_params_struct
1456                                       ->requested_drc_characteristic[i],
1457                  &selection_candidate_count, selection_candidate_info);
1458              if (err) return (err);
1459              break;
1460
1461            default:
1462              return (UNEXPECTED_ERROR);
1463              break;
1464          }
1465        }
1466      } else {
1467        WORD32 match_found_flag = 0;
1468
1469        err = impd_select_drcs_without_compr_effects(
1470            pstr_drc_config, &match_found_flag, &selection_candidate_count,
1471            selection_candidate_info);
1472        if (err) return (err);
1473
1474        if (match_found_flag == 0) {
1475          WORD32 requested_num_drc_effects = 5;
1476          WORD32 desired_num_drc_effects_of_requested = 1;
1477          WORD32 requested_drc_effect_type[5] = {
1478              EFFECT_TYPE_REQUESTED_GENERAL_COMPR, EFFECT_TYPE_REQUESTED_NIGHT,
1479              EFFECT_TYPE_REQUESTED_NOISY, EFFECT_TYPE_REQUESTED_LIMITED,
1480              EFFECT_TYPE_REQUESTED_LOWLEVEL};
1481
1482          err = impd_match_effect_types(
1483              pstr_drc_config, requested_num_drc_effects,
1484              desired_num_drc_effects_of_requested, requested_drc_effect_type,
1485              &selection_candidate_count, selection_candidate_info);
1486          if (err) return (err);
1487        }
1488      }
1489
1490      if (selection_candidate_count > 0) {
1491        err = impd_drc_set_final_selection(
1492            pstr_drc_config, pstr_drc_sel_proc_params_struct,
1493            &selection_candidate_count, selection_candidate_info,
1494            pstr_drc_uni_sel_proc->eq_set_id_valid_flag);
1495        if (err) return (err);
1496      } else {
1497        selection_candidate_count = 0;
1498        return (UNEXPECTED_ERROR);
1499      }
1500    }
1501
1502    if (selection_candidate_count == 0) {
1503      if (restrict_to_drc_with_album_loudness == 1) {
1504        restrict_to_drc_with_album_loudness = 0;
1505      } else {
1506        return (UNEXPECTED_ERROR);
1507      }
1508    }
1509  }
1510  *drc_set_id_selected =
1511      pstr_drc_config
1512          ->str_drc_instruction_str[selection_candidate_info[0]
1513                                        .drc_instructions_index]
1514          .drc_set_id;
1515  *eq_set_id_selected = selection_candidate_info[0].eq_set_id;
1516
1517  impd_select_loud_eq(
1518      pstr_drc_config,
1519      pstr_drc_sel_proc_params_struct->requested_dwnmix_id
1520          [selection_candidate_info[0].downmix_id_request_index],
1521      *drc_set_id_selected, *eq_set_id_selected, loud_eq_id_sel);
1522  if (selection_candidate_count > 0) {
1523    pstr_drc_uni_sel_proc->uni_drc_sel_proc_output
1524        .loudness_normalization_gain_db =
1525        selection_candidate_info[0].loudness_norm_db_gain_adjusted;
1526    pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.output_peak_level_db =
1527        selection_candidate_info[0].output_peak_level;
1528    pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.output_loudness =
1529        selection_candidate_info[0].output_loudness;
1530    pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.active_downmix_id =
1531        pstr_drc_sel_proc_params_struct->requested_dwnmix_id
1532            [selection_candidate_info[0].downmix_id_request_index];
1533    pstr_drc_uni_sel_proc->uni_drc_sel_proc_output.mixing_level =
1534        selection_candidate_info[0].mixing_level;
1535  }
1536  return (0);
1537}
1538