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