• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <math.h>
22 
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_filter_bank.h"
30 #include "impd_drc_rom.h"
impd_signal_peak_level_info(ia_drc_config * pstr_drc_config,ia_drc_loudness_info_set_struct * pstr_loudness_info,ia_drc_instructions_struct * str_drc_instruction_str,WORD32 requested_dwnmix_id,WORD32 album_mode,WORD32 num_compression_eq_count,WORD32 * num_compression_eq_id,WORD32 * peak_info_count,WORD32 eq_set_id[],FLOAT32 signal_peak_level[],WORD32 explicit_peak_information_present[])31 WORD32 impd_signal_peak_level_info(
32     ia_drc_config* pstr_drc_config,
33     ia_drc_loudness_info_set_struct* pstr_loudness_info,
34     ia_drc_instructions_struct* str_drc_instruction_str,
35     WORD32 requested_dwnmix_id, WORD32 album_mode,
36     WORD32 num_compression_eq_count, WORD32* num_compression_eq_id,
37     WORD32* peak_info_count, WORD32 eq_set_id[], FLOAT32 signal_peak_level[],
38     WORD32 explicit_peak_information_present[]) {
39   WORD32 c, d, i, k, n, base_channel_count, mode;
40   WORD32 pre_lim_count;
41   WORD32 peak_count = 0;
42   WORD32 loudness_info_count = 0;
43   ia_loudness_info_struct* loudness_info;
44   FLOAT32 sum, max_sum;
45   WORD32 drc_set_id_requested = str_drc_instruction_str->drc_set_id;
46   WORD32 loudness_drc_set_id_requested;
47   WORD32 match_found_flag = 0;
48 
49   FLOAT32 signal_peak_level_tmp;
50   eq_set_id[0] = 0;
51   signal_peak_level[0] = 0.0f;
52   explicit_peak_information_present[0] = 0;
53 
54   k = 0;
55   if (drc_set_id_requested < 0) {
56     for (k = 0; k < num_compression_eq_count; k++) {
57       eq_set_id[k] = num_compression_eq_id[k];
58       signal_peak_level[k] = 0.0f;
59       explicit_peak_information_present[k] = 0;
60     }
61   }
62   eq_set_id[k] = 0;
63   signal_peak_level[k] = 0.0f;
64   explicit_peak_information_present[k] = 0;
65   k++;
66 
67   pre_lim_count = k;
68 
69   if (drc_set_id_requested < 0) {
70     loudness_drc_set_id_requested = 0;
71   } else {
72     loudness_drc_set_id_requested = drc_set_id_requested;
73   }
74 
75   if (album_mode == 1) {
76     mode = 1;
77     loudness_info_count = pstr_loudness_info->loudness_info_album_count;
78   } else {
79     mode = 0;
80     loudness_info_count = pstr_loudness_info->loudness_info_count;
81   }
82 
83   for (n = 0; n < loudness_info_count; n++) {
84     if (mode == 1) {
85       loudness_info = &(pstr_loudness_info->str_loudness_info_album[n]);
86     } else {
87       loudness_info = &(pstr_loudness_info->loudness_info[n]);
88     }
89     if (loudness_drc_set_id_requested == loudness_info->drc_set_id &&
90         requested_dwnmix_id == loudness_info->downmix_id) {
91       if (loudness_info->true_peak_level_present) {
92         eq_set_id[peak_count] = loudness_info->eq_set_id;
93 
94         signal_peak_level[peak_count] = loudness_info->true_peak_level;
95         explicit_peak_information_present[peak_count] = 1;
96 
97         match_found_flag = 1;
98         peak_count++;
99       }
100       if (match_found_flag == 0) {
101         if (loudness_info->sample_peak_level_present) {
102           eq_set_id[peak_count] = loudness_info->eq_set_id;
103 
104           signal_peak_level[peak_count] = loudness_info->sample_peak_level;
105           explicit_peak_information_present[peak_count] = 1;
106 
107           match_found_flag = 1;
108           peak_count++;
109         }
110       }
111     }
112   }
113   if (match_found_flag == 0) {
114     for (n = 0; n < loudness_info_count; n++) {
115       if (mode == 1) {
116         loudness_info = &(pstr_loudness_info->str_loudness_info_album[n]);
117       } else {
118         loudness_info = &(pstr_loudness_info->loudness_info[n]);
119       }
120       if (ID_FOR_ANY_DRC == loudness_info->drc_set_id &&
121           requested_dwnmix_id == loudness_info->downmix_id) {
122         if (loudness_info->true_peak_level_present) {
123           eq_set_id[peak_count] = loudness_info->eq_set_id;
124 
125           signal_peak_level[peak_count] = loudness_info->true_peak_level;
126           explicit_peak_information_present[peak_count] = 1;
127 
128           match_found_flag = 1;
129           peak_count++;
130         }
131         if (match_found_flag == 0) {
132           if (loudness_info->sample_peak_level_present) {
133             eq_set_id[peak_count] = loudness_info->eq_set_id;
134 
135             signal_peak_level[peak_count] = loudness_info->sample_peak_level;
136             explicit_peak_information_present[peak_count] = 1;
137 
138             match_found_flag = 1;
139             peak_count++;
140           }
141         }
142       }
143     }
144   }
145   if (match_found_flag == 0) {
146     for (i = 0; i < str_drc_instruction_str->dwnmix_id_count; i++) {
147       if (requested_dwnmix_id == str_drc_instruction_str->downmix_id[0] ||
148           ID_FOR_ANY_DOWNMIX == str_drc_instruction_str->downmix_id[0]) {
149         if (str_drc_instruction_str->limiter_peak_target_present) {
150           if (str_drc_instruction_str->requires_eq == 1) {
151             for (d = 0;
152                  d < pstr_drc_config->str_drc_config_ext.eq_instructions_count;
153                  d++) {
154               ia_eq_instructions_struct* eq_instructions =
155                   &pstr_drc_config->str_drc_config_ext.str_eq_instructions[d];
156               for (c = 0; c < eq_instructions->drc_set_id_count; c++) {
157                 if ((eq_instructions->drc_set_id[c] ==
158                      loudness_drc_set_id_requested) ||
159                     (eq_instructions->drc_set_id[c] == ID_FOR_ANY_DRC)) {
160                   for (i = 0; i < eq_instructions->dwnmix_id_count; i++) {
161                     if ((eq_instructions->downmix_id[i] ==
162                          requested_dwnmix_id) ||
163                         (eq_instructions->downmix_id[i] ==
164                          ID_FOR_ANY_DOWNMIX)) {
165                       eq_set_id[peak_count] = eq_instructions->eq_set_id;
166                       signal_peak_level[peak_count] =
167                           str_drc_instruction_str->limiter_peak_target;
168                       explicit_peak_information_present[peak_count] = 1;
169                       match_found_flag = 1;
170                       peak_count++;
171                     }
172                   }
173                 }
174               }
175             }
176           } else
177 
178           {
179             eq_set_id[peak_count] = 0;
180             signal_peak_level[peak_count] =
181                 str_drc_instruction_str->limiter_peak_target;
182             explicit_peak_information_present[peak_count] = 1;
183             match_found_flag = 1;
184             peak_count++;
185           }
186         }
187       }
188     }
189   }
190   if (match_found_flag == 0) {
191     for (i = 1; i < str_drc_instruction_str->dwnmix_id_count; i++) {
192       if (requested_dwnmix_id == str_drc_instruction_str->downmix_id[i]) {
193         if (str_drc_instruction_str->limiter_peak_target_present) {
194           {
195             eq_set_id[peak_count] = 0;
196             signal_peak_level[peak_count] =
197                 str_drc_instruction_str->limiter_peak_target;
198             explicit_peak_information_present[peak_count] = 1;
199             match_found_flag = 1;
200             peak_count++;
201           }
202         }
203       }
204     }
205   }
206   if (match_found_flag == 0) {
207     if (requested_dwnmix_id != ID_FOR_BASE_LAYOUT) {
208       signal_peak_level_tmp = 0.f;
209       for (i = 0; i < pstr_drc_config->dwnmix_instructions_count; i++) {
210         if (pstr_drc_config->dwnmix_instructions[i].downmix_id ==
211             requested_dwnmix_id) {
212           if (pstr_drc_config->dwnmix_instructions[i]
213                   .downmix_coefficients_present) {
214             base_channel_count =
215                 pstr_drc_config->channel_layout.base_channel_count;
216             max_sum = 0.0f;
217             for (c = 0;
218                  c <
219                  pstr_drc_config->dwnmix_instructions[i].target_channel_count;
220                  c++) {
221               sum = 0.0f;
222               for (d = 0; d < base_channel_count; d++) {
223                 sum += pstr_drc_config->dwnmix_instructions[i]
224                            .downmix_coefficient[c * base_channel_count + d];
225               }
226               if (max_sum < sum) max_sum = sum;
227             }
228             signal_peak_level_tmp = 20.0f * (FLOAT32)log10(max_sum);
229           } else {
230           }
231           break;
232         }
233       }
234       for (n = 0; n < loudness_info_count; n++) {
235         if (mode == 1) {
236           loudness_info = &(pstr_loudness_info->str_loudness_info_album[n]);
237         } else {
238           loudness_info = &(pstr_loudness_info->loudness_info[n]);
239         }
240         if (loudness_drc_set_id_requested == loudness_info->drc_set_id &&
241             ID_FOR_BASE_LAYOUT == loudness_info->downmix_id) {
242           if (loudness_info->true_peak_level_present) {
243             eq_set_id[peak_count] = loudness_info->eq_set_id;
244 
245             signal_peak_level[peak_count] =
246                 loudness_info->true_peak_level + signal_peak_level_tmp;
247             explicit_peak_information_present[peak_count] = 0;
248 
249             match_found_flag = 1;
250             peak_count++;
251           }
252           if (match_found_flag == 0) {
253             if (loudness_info->sample_peak_level_present) {
254               eq_set_id[peak_count] = loudness_info->eq_set_id;
255 
256               signal_peak_level[peak_count] =
257                   loudness_info->sample_peak_level + signal_peak_level_tmp;
258               explicit_peak_information_present[peak_count] = 0;
259 
260               match_found_flag = 1;
261               peak_count++;
262             }
263           }
264         }
265       }
266       if (match_found_flag == 0) {
267         for (n = 0; n < loudness_info_count; n++) {
268           if (mode == 1) {
269             loudness_info = &(pstr_loudness_info->str_loudness_info_album[n]);
270           } else {
271             loudness_info = &(pstr_loudness_info->loudness_info[n]);
272           }
273           if (ID_FOR_ANY_DRC == loudness_info->drc_set_id &&
274               ID_FOR_BASE_LAYOUT == loudness_info->downmix_id) {
275             if (loudness_info->true_peak_level_present) {
276               eq_set_id[peak_count] = loudness_info->eq_set_id;
277 
278               signal_peak_level[peak_count] =
279                   loudness_info->true_peak_level + signal_peak_level_tmp;
280               explicit_peak_information_present[peak_count] = 0;
281 
282               match_found_flag = 1;
283               peak_count++;
284             }
285             if (match_found_flag == 0) {
286               if (loudness_info->sample_peak_level_present) {
287                 eq_set_id[peak_count] = loudness_info->eq_set_id;
288 
289                 signal_peak_level[peak_count] =
290                     loudness_info->sample_peak_level + signal_peak_level_tmp;
291                 explicit_peak_information_present[peak_count] = 0;
292 
293                 match_found_flag = 1;
294                 peak_count++;
295               }
296             }
297           }
298         }
299       }
300       if (match_found_flag == 0) {
301         ia_drc_instructions_struct* drc_instructions_drc_tmp;
302         for (n = 0; n < pstr_drc_config->drc_instructions_count_plus; n++) {
303           drc_instructions_drc_tmp =
304               &pstr_drc_config->str_drc_instruction_str[n];
305           if (loudness_drc_set_id_requested ==
306               drc_instructions_drc_tmp->drc_set_id) {
307             for (k = 0; k < drc_instructions_drc_tmp->dwnmix_id_count; k++) {
308               if (ID_FOR_BASE_LAYOUT ==
309                   drc_instructions_drc_tmp->downmix_id[k]) {
310                 if (drc_instructions_drc_tmp->limiter_peak_target_present) {
311                   eq_set_id[peak_count] = -1;
312                   signal_peak_level[peak_count] =
313                       drc_instructions_drc_tmp->limiter_peak_target +
314                       signal_peak_level_tmp;
315                   explicit_peak_information_present[peak_count] = 0;
316                   match_found_flag = 1;
317                   peak_count++;
318                 }
319               }
320               break;
321             }
322           }
323         }
324       }
325     }
326   }
327   if (peak_count > 0) {
328     *peak_info_count = peak_count;
329   } else {
330     *peak_info_count = pre_lim_count;
331   }
332   return (0);
333 }
334 
335 WORD32
impd_extract_loudness_peak_to_average_info(ia_loudness_info_struct * loudness_info,WORD32 dyn_range_measurement_type,WORD32 * loudness_peak_2_avg_value_present,FLOAT32 * loudness_peak_2_avg_value)336 impd_extract_loudness_peak_to_average_info(
337     ia_loudness_info_struct* loudness_info, WORD32 dyn_range_measurement_type,
338     WORD32* loudness_peak_2_avg_value_present,
339     FLOAT32* loudness_peak_2_avg_value) {
340   WORD32 k;
341   WORD32 program_loudness_present = 0;
342   WORD32 peak_loudness_present = 0;
343   WORD32 match_measure_program_loudness = 0;
344   WORD32 match_measure_peak_loudness = 0;
345   FLOAT32 program_loudness = 0.0f;
346   FLOAT32 peak_loudness = 0.0f;
347   ia_loudness_measure_struct* loudness_measure = NULL;
348 
349   for (k = 0; k < loudness_info->measurement_count; k++) {
350     loudness_measure = &(loudness_info->loudness_measure[k]);
351     if (loudness_measure->method_def == METHOD_DEFINITION_PROGRAM_LOUDNESS) {
352       if (match_measure_program_loudness <
353           measurement_method_prog_loudness_tbl[loudness_measure
354                                                    ->measurement_system]) {
355         program_loudness = loudness_measure->method_val;
356         program_loudness_present = 1;
357         match_measure_program_loudness =
358             measurement_method_prog_loudness_tbl[loudness_measure
359                                                      ->measurement_system];
360       }
361     }
362     switch (dyn_range_measurement_type) {
363       case SHORT_TERM_LOUDNESS_TO_AVG:
364         if (loudness_measure->method_def ==
365             METHOD_DEFINITION_SHORT_TERM_LOUDNESS_MAX) {
366           if (match_measure_peak_loudness <
367               measurement_method_peak_loudness_tbl[loudness_measure
368                                                        ->measurement_system]) {
369             peak_loudness = loudness_measure->method_val;
370             peak_loudness_present = 1;
371             match_measure_peak_loudness =
372                 measurement_method_peak_loudness_tbl[loudness_measure
373                                                          ->measurement_system];
374           }
375         }
376         break;
377 
378       case MOMENTARY_LOUDNESS_TO_AVG:
379         if (loudness_measure->method_def ==
380             METHOD_DEFINITION_MOMENTARY_LOUDNESS_MAX) {
381           if (match_measure_peak_loudness <
382               measurement_method_peak_loudness_tbl[loudness_measure
383                                                        ->measurement_system]) {
384             peak_loudness = loudness_measure->method_val;
385             peak_loudness_present = 1;
386             match_measure_peak_loudness =
387                 measurement_method_peak_loudness_tbl[loudness_measure
388                                                          ->measurement_system];
389           }
390         }
391         break;
392 
393       case TOP_OF_LOUDNESS_RANGE_TO_AVG:
394         if (loudness_measure->method_def ==
395             METHOD_DEFINITION_MAX_OF_LOUDNESS_RANGE) {
396           if (match_measure_peak_loudness <
397               measurement_method_peak_loudness_tbl[loudness_measure
398                                                        ->measurement_system]) {
399             peak_loudness = loudness_measure->method_val;
400             peak_loudness_present = 1;
401             match_measure_peak_loudness =
402                 measurement_method_peak_loudness_tbl[loudness_measure
403                                                          ->measurement_system];
404           }
405         }
406         break;
407 
408       default:
409         return (UNEXPECTED_ERROR);
410 
411         break;
412     }
413   }
414   if ((program_loudness_present == 1) && (peak_loudness_present == 1)) {
415     *loudness_peak_2_avg_value = peak_loudness - program_loudness;
416     *loudness_peak_2_avg_value_present = 1;
417   }
418   return (0);
419 }
420 
impd_loudness_peak_to_average_info(ia_drc_loudness_info_set_struct * pstr_loudness_info,ia_drc_instructions_struct * str_drc_instruction_str,WORD32 requested_dwnmix_id,WORD32 dyn_range_measurement_type,WORD32 album_mode,WORD32 * loudness_peak_2_avg_value_present,FLOAT32 * loudness_peak_2_avg_value)421 WORD32 impd_loudness_peak_to_average_info(
422     ia_drc_loudness_info_set_struct* pstr_loudness_info,
423     ia_drc_instructions_struct* str_drc_instruction_str,
424     WORD32 requested_dwnmix_id, WORD32 dyn_range_measurement_type,
425     WORD32 album_mode, WORD32* loudness_peak_2_avg_value_present,
426     FLOAT32* loudness_peak_2_avg_value) {
427   WORD32 n, err;
428   WORD32 drc_set_id = max(0, str_drc_instruction_str->drc_set_id);
429 
430   *loudness_peak_2_avg_value_present = 0;
431 
432   if (album_mode == 1) {
433     for (n = 0; n < pstr_loudness_info->loudness_info_album_count; n++) {
434       ia_loudness_info_struct* loudness_info =
435           &(pstr_loudness_info->str_loudness_info_album[n]);
436       if (drc_set_id == loudness_info->drc_set_id) {
437         if (requested_dwnmix_id == loudness_info->downmix_id) {
438           err = impd_extract_loudness_peak_to_average_info(
439               loudness_info, dyn_range_measurement_type,
440               loudness_peak_2_avg_value_present, loudness_peak_2_avg_value);
441           if (err) return (err);
442         }
443       }
444     }
445   }
446   if (*loudness_peak_2_avg_value_present == 0) {
447     for (n = 0; n < pstr_loudness_info->loudness_info_count; n++) {
448       ia_loudness_info_struct* loudness_info =
449           &(pstr_loudness_info->loudness_info[n]);
450       if (drc_set_id == loudness_info->drc_set_id) {
451         if (requested_dwnmix_id == loudness_info->downmix_id) {
452           err = impd_extract_loudness_peak_to_average_info(
453               loudness_info, dyn_range_measurement_type,
454               loudness_peak_2_avg_value_present, loudness_peak_2_avg_value);
455           if (err) return (err);
456         }
457       }
458     }
459   }
460   return (0);
461 }
462 
impd_overall_loudness_present(ia_loudness_info_struct * loudness_info,WORD32 * loudness_info_present)463 WORD32 impd_overall_loudness_present(ia_loudness_info_struct* loudness_info,
464                                      WORD32* loudness_info_present) {
465   WORD32 m;
466 
467   *loudness_info_present = 0;
468   for (m = 0; m < loudness_info->measurement_count; m++) {
469     if ((loudness_info->loudness_measure[m].method_def ==
470          METHOD_DEFINITION_PROGRAM_LOUDNESS) ||
471         (loudness_info->loudness_measure[m].method_def ==
472          METHOD_DEFINITION_ANCHOR_LOUDNESS)) {
473       *loudness_info_present = 1;
474     }
475   }
476   return (0);
477 }
478 
impd_check_loud_info(WORD32 loudness_info_count,ia_loudness_info_struct * loudness_info,WORD32 requested_dwnmix_id,WORD32 drc_set_id_requested,WORD32 * info_count,ia_loudness_info_struct * loudness_info_matching[])479 WORD32 impd_check_loud_info(WORD32 loudness_info_count,
480                             ia_loudness_info_struct* loudness_info,
481                             WORD32 requested_dwnmix_id,
482                             WORD32 drc_set_id_requested, WORD32* info_count,
483                             ia_loudness_info_struct* loudness_info_matching[]) {
484   WORD32 n, err;
485   WORD32 loudness_info_present;
486   for (n = 0; n < loudness_info_count; n++) {
487     if (requested_dwnmix_id == loudness_info[n].downmix_id) {
488       if (drc_set_id_requested == loudness_info[n].drc_set_id) {
489         err = impd_overall_loudness_present(&(loudness_info[n]),
490                                             &loudness_info_present);
491         if (err) return (err);
492         if (loudness_info_present) {
493           loudness_info_matching[*info_count] = &(loudness_info[n]);
494           (*info_count)++;
495         }
496       }
497     }
498   }
499 
500   return (0);
501 }
502 
impd_check_loud_payload(WORD32 loudness_info_count,ia_loudness_info_struct * loudness_info,WORD32 requested_dwnmix_id,WORD32 drc_set_id_requested,WORD32 * info_count,ia_loudness_info_struct * loudness_info_matching[])503 WORD32 impd_check_loud_payload(
504     WORD32 loudness_info_count, ia_loudness_info_struct* loudness_info,
505     WORD32 requested_dwnmix_id, WORD32 drc_set_id_requested, WORD32* info_count,
506     ia_loudness_info_struct* loudness_info_matching[]) {
507   WORD32 err = 0;
508 
509   err = impd_check_loud_info(loudness_info_count, loudness_info,
510                              requested_dwnmix_id, drc_set_id_requested,
511                              info_count, loudness_info_matching);
512   if (err || *info_count) goto matchEnd;
513   err = impd_check_loud_info(loudness_info_count, loudness_info,
514                              ID_FOR_ANY_DOWNMIX, drc_set_id_requested,
515                              info_count, loudness_info_matching);
516   if (err || *info_count) goto matchEnd;
517   err = impd_check_loud_info(loudness_info_count, loudness_info,
518                              requested_dwnmix_id, ID_FOR_ANY_DRC, info_count,
519                              loudness_info_matching);
520   if (err || *info_count) goto matchEnd;
521   err = impd_check_loud_info(loudness_info_count, loudness_info,
522                              requested_dwnmix_id, ID_FOR_NO_DRC, info_count,
523                              loudness_info_matching);
524   if (err || *info_count) goto matchEnd;
525   err = impd_check_loud_info(loudness_info_count, loudness_info,
526                              ID_FOR_ANY_DOWNMIX, ID_FOR_ANY_DRC, info_count,
527                              loudness_info_matching);
528   if (err || *info_count) goto matchEnd;
529   err = impd_check_loud_info(loudness_info_count, loudness_info,
530                              ID_FOR_ANY_DOWNMIX, ID_FOR_NO_DRC, info_count,
531                              loudness_info_matching);
532   if (err || *info_count) goto matchEnd;
533   err = impd_check_loud_info(loudness_info_count, loudness_info,
534                              ID_FOR_BASE_LAYOUT, drc_set_id_requested,
535                              info_count, loudness_info_matching);
536   if (err || *info_count) goto matchEnd;
537   err = impd_check_loud_info(loudness_info_count, loudness_info,
538                              ID_FOR_BASE_LAYOUT, ID_FOR_ANY_DRC, info_count,
539                              loudness_info_matching);
540   if (err || *info_count) goto matchEnd;
541   err = impd_check_loud_info(loudness_info_count, loudness_info,
542                              ID_FOR_BASE_LAYOUT, ID_FOR_NO_DRC, info_count,
543                              loudness_info_matching);
544   if (err || *info_count) goto matchEnd;
545 matchEnd:
546   return (err);
547 }
548 
impd_find_overall_loudness_info(ia_drc_sel_proc_params_struct * pstr_drc_sel_proc_params_struct,ia_drc_loudness_info_set_struct * pstr_loudness_info,WORD32 requested_dwnmix_id,WORD32 drc_set_id_requested,WORD32 * overall_loudness_info_present,WORD32 * info_count,ia_loudness_info_struct * loudness_info_matching[])549 WORD32 impd_find_overall_loudness_info(
550     ia_drc_sel_proc_params_struct* pstr_drc_sel_proc_params_struct,
551     ia_drc_loudness_info_set_struct* pstr_loudness_info,
552     WORD32 requested_dwnmix_id, WORD32 drc_set_id_requested,
553     WORD32* overall_loudness_info_present, WORD32* info_count,
554     ia_loudness_info_struct* loudness_info_matching[]) {
555   WORD32 err;
556   WORD32 loudness_drc_set_id_requested;
557 
558   *info_count = 0;
559   if (drc_set_id_requested < 0) {
560     loudness_drc_set_id_requested = ID_FOR_NO_DRC;
561   } else {
562     loudness_drc_set_id_requested = drc_set_id_requested;
563   }
564   if (pstr_drc_sel_proc_params_struct->album_mode == 1) {
565     err = impd_check_loud_payload(
566         pstr_loudness_info->loudness_info_album_count,
567         pstr_loudness_info->str_loudness_info_album, requested_dwnmix_id,
568         loudness_drc_set_id_requested, info_count, loudness_info_matching);
569     if (err) return (err);
570   }
571   if (*info_count == 0) {
572     err = impd_check_loud_payload(pstr_loudness_info->loudness_info_count,
573                                   pstr_loudness_info->loudness_info,
574                                   requested_dwnmix_id,
575                                   loudness_drc_set_id_requested,
576 
577                                   info_count, loudness_info_matching);
578     if (err) return (err);
579   }
580   *overall_loudness_info_present = (*info_count > 0);
581   return (0);
582 }
583 
584 WORD32
impd_high_pass_loudness_adjust_info(ia_loudness_info_struct * loudness_info,WORD32 * loudness_hp_adjust_present,FLOAT32 * loudness_hp_adjust)585 impd_high_pass_loudness_adjust_info(ia_loudness_info_struct* loudness_info,
586                                     WORD32* loudness_hp_adjust_present,
587                                     FLOAT32* loudness_hp_adjust) {
588   WORD32 m, k;
589 
590   *loudness_hp_adjust_present = 0;
591   *loudness_hp_adjust = 0.0f;
592   for (m = 0; m < loudness_info->measurement_count; m++) {
593     if (loudness_info->loudness_measure[m].measurement_system ==
594         MEASUREMENT_SYSTEM_BS_1770_4_PRE_PROCESSING) {
595       for (k = 0; k < loudness_info->measurement_count; k++) {
596         if (loudness_info->loudness_measure[k].measurement_system ==
597             MEASUREMENT_SYSTEM_BS_1770_4) {
598           if (loudness_info->loudness_measure[m].method_def ==
599               loudness_info->loudness_measure[k].method_def) {
600             *loudness_hp_adjust_present = 1;
601             *loudness_hp_adjust =
602                 loudness_info->loudness_measure[m].method_val -
603                 loudness_info->loudness_measure[k].method_val;
604           }
605         }
606       }
607     }
608   }
609   return (0);
610 }
611 
impd_find_high_pass_loudness_adjust(ia_drc_loudness_info_set_struct * pstr_loudness_info,WORD32 requested_dwnmix_id,WORD32 drc_set_id_requested,WORD32 album_mode,FLOAT32 device_cutoff_freq,WORD32 * loudness_hp_adjust_present,FLOAT32 * loudness_hp_adjust)612 WORD32 impd_find_high_pass_loudness_adjust(
613     ia_drc_loudness_info_set_struct* pstr_loudness_info,
614     WORD32 requested_dwnmix_id, WORD32 drc_set_id_requested, WORD32 album_mode,
615     FLOAT32 device_cutoff_freq, WORD32* loudness_hp_adjust_present,
616     FLOAT32* loudness_hp_adjust) {
617   WORD32 n, err;
618   WORD32 loudness_drc_set_id_requested;
619 
620   if (drc_set_id_requested < 0) {
621     loudness_drc_set_id_requested = 0;
622   } else {
623     loudness_drc_set_id_requested = drc_set_id_requested;
624   }
625 
626   *loudness_hp_adjust_present = 0;
627 
628   if (album_mode == 1) {
629     for (n = 0; n < pstr_loudness_info->loudness_info_album_count; n++) {
630       if ((requested_dwnmix_id ==
631            pstr_loudness_info->str_loudness_info_album[n].downmix_id) ||
632           (ID_FOR_ANY_DOWNMIX ==
633            pstr_loudness_info->str_loudness_info_album[n].downmix_id)) {
634         if (loudness_drc_set_id_requested ==
635             pstr_loudness_info->str_loudness_info_album[n].drc_set_id) {
636           err = impd_high_pass_loudness_adjust_info(
637               &(pstr_loudness_info->loudness_info[n]),
638               loudness_hp_adjust_present, loudness_hp_adjust);
639           if (err) return (err);
640         }
641       }
642     }
643   }
644   if (*loudness_hp_adjust_present == 0) {
645     for (n = 0; n < pstr_loudness_info->loudness_info_count; n++) {
646       if ((requested_dwnmix_id ==
647            pstr_loudness_info->loudness_info[n].downmix_id) ||
648           (ID_FOR_ANY_DOWNMIX ==
649            pstr_loudness_info->loudness_info[n].downmix_id)) {
650         if (loudness_drc_set_id_requested ==
651             pstr_loudness_info->loudness_info[n].drc_set_id) {
652           err = impd_high_pass_loudness_adjust_info(
653               &(pstr_loudness_info->loudness_info[n]),
654               loudness_hp_adjust_present, loudness_hp_adjust);
655           if (err) return (err);
656         }
657       }
658     }
659   }
660   if (*loudness_hp_adjust_present == 0) {
661     for (n = 0; n < pstr_loudness_info->loudness_info_count; n++) {
662       if (ID_FOR_BASE_LAYOUT ==
663           pstr_loudness_info->loudness_info[n].downmix_id) /* base layout */
664       {
665         if (loudness_drc_set_id_requested ==
666             pstr_loudness_info->loudness_info[n].drc_set_id) {
667           err = impd_high_pass_loudness_adjust_info(
668               &(pstr_loudness_info->loudness_info[n]),
669               loudness_hp_adjust_present, loudness_hp_adjust);
670           if (err) return (err);
671         }
672       }
673     }
674   }
675   if (*loudness_hp_adjust_present == 0) {
676     for (n = 0; n < pstr_loudness_info->loudness_info_count; n++) {
677       if (ID_FOR_BASE_LAYOUT ==
678           pstr_loudness_info->loudness_info[n].downmix_id) /* base layout */
679       {
680         if (0 == pstr_loudness_info->loudness_info[n].drc_set_id) {
681           err = impd_high_pass_loudness_adjust_info(
682               &(pstr_loudness_info->loudness_info[n]),
683               loudness_hp_adjust_present, loudness_hp_adjust);
684           if (err) return (err);
685         }
686       }
687     }
688   }
689   if (*loudness_hp_adjust_present == 0) {
690     *loudness_hp_adjust = 0.0f;
691   } else {
692     *loudness_hp_adjust *=
693         (max(20.0f, min(500.0f, device_cutoff_freq)) - 20.0f) /
694         (500.0f - 20.0f);
695   }
696   return (0);
697 }
698 
impd_init_loudness_control(ia_drc_sel_proc_params_struct * pstr_drc_sel_proc_params_struct,ia_drc_loudness_info_set_struct * pstr_loudness_info,WORD32 requested_dwnmix_id,WORD32 drc_set_id_requested,WORD32 num_compression_eq_count,WORD32 * num_compression_eq_id,WORD32 * loudness_info_count,WORD32 eq_set_id[],FLOAT32 loudness_normalization_gain_db[],FLOAT32 loudness[])699 WORD32 impd_init_loudness_control(
700     ia_drc_sel_proc_params_struct* pstr_drc_sel_proc_params_struct,
701     ia_drc_loudness_info_set_struct* pstr_loudness_info,
702     WORD32 requested_dwnmix_id, WORD32 drc_set_id_requested,
703     WORD32 num_compression_eq_count, WORD32* num_compression_eq_id,
704     WORD32* loudness_info_count, WORD32 eq_set_id[],
705     FLOAT32 loudness_normalization_gain_db[], FLOAT32 loudness[]) {
706   WORD32 err, k, info_count = 0, pre_lim_count;
707   WORD32 loudness_hp_adjust_present;
708   WORD32 overall_loudness_info_present;
709   FLOAT32 pre_proc_adjust;
710 
711   k = 0;
712   if (drc_set_id_requested < 0) {
713     for (k = 0; k < num_compression_eq_count; k++) {
714       eq_set_id[k] = num_compression_eq_id[k];
715       loudness[k] = UNDEFINED_LOUDNESS_VALUE;
716       loudness_normalization_gain_db[k] = 0.0f;
717     }
718   }
719   if (k >= MAX_NUM_COMPRESSION_EQ) return UNEXPECTED_ERROR;
720   eq_set_id[k] = 0;
721 
722   loudness[k] = UNDEFINED_LOUDNESS_VALUE;
723 
724   loudness_normalization_gain_db[k] = 0.0f;
725   k++;
726 
727   pre_lim_count = k;
728 
729   if (pstr_drc_sel_proc_params_struct->loudness_normalization_on == 1) {
730     WORD32 n;
731     ia_loudness_info_struct* loudness_info[16];
732     err = impd_find_overall_loudness_info(
733         pstr_drc_sel_proc_params_struct, pstr_loudness_info,
734         requested_dwnmix_id, drc_set_id_requested,
735         &overall_loudness_info_present, &info_count, loudness_info);
736     if (err) return (err);
737 
738     if (overall_loudness_info_present == 1) {
739       WORD32 requested_method_definition = METHOD_DEFINITION_PROGRAM_LOUDNESS;
740       WORD32 other_method_definition = METHOD_DEFINITION_PROGRAM_LOUDNESS;
741       WORD32 requested_measurement_system = MEASUREMENT_SYSTEM_BS_1770_4;
742       WORD32 requested_preprocessing = 0;
743 
744       const WORD32* system_bonus = measurement_system_default_tbl;
745 
746       WORD32 match_measure;
747       FLOAT32 method_val = 0;
748 
749       switch (pstr_drc_sel_proc_params_struct->loudness_measurement_method) {
750         case USER_METHOD_DEFINITION_DEFAULT:
751         case USER_METHOD_DEFINITION_PROGRAM_LOUDNESS:
752           requested_method_definition = METHOD_DEFINITION_PROGRAM_LOUDNESS;
753           other_method_definition = METHOD_DEFINITION_ANCHOR_LOUDNESS;
754           break;
755         case USER_METHOD_DEFINITION_ANCHOR_LOUDNESS:
756           requested_method_definition = METHOD_DEFINITION_ANCHOR_LOUDNESS;
757           other_method_definition = METHOD_DEFINITION_PROGRAM_LOUDNESS;
758           break;
759 
760         default:
761           return (UNEXPECTED_ERROR);
762           break;
763       }
764 
765       switch (pstr_drc_sel_proc_params_struct->loudness_measurement_system) {
766         case USER_MEASUREMENT_SYSTEM_DEFAULT:
767         case USER_MEASUREMENT_SYSTEM_BS_1770_4:
768           requested_measurement_system = MEASUREMENT_SYSTEM_BS_1770_4;
769           system_bonus = measurement_system_bs1770_3_tbl;
770           break;
771         case USER_MEASUREMENT_SYSTEM_USER:
772           requested_measurement_system = MEASUREMENT_SYSTEM_USER;
773           system_bonus = measurement_system_user_tbl;
774           break;
775         case USER_MEASUREMENT_SYSTEM_EXPERT_PANEL:
776           requested_measurement_system = MEASUREMENT_SYSTEM_EXPERT_PANEL;
777           system_bonus = measurement_system_expert_tbl;
778           break;
779         case USER_MEASUREMENT_SYSTEM_RESERVED_A:
780           requested_measurement_system = USER_MEASUREMENT_SYSTEM_RESERVED_A;
781           system_bonus = measurement_system_rms_a_tbl;
782           break;
783         case USER_MEASUREMENT_SYSTEM_RESERVED_B:
784           requested_measurement_system = USER_MEASUREMENT_SYSTEM_RESERVED_B;
785           system_bonus = measurement_system_rms_b_tbl;
786           break;
787         case USER_MEASUREMENT_SYSTEM_RESERVED_C:
788           requested_measurement_system = USER_MEASUREMENT_SYSTEM_RESERVED_C;
789           system_bonus = measurement_system_rms_c_tbl;
790           break;
791         case USER_MEASUREMENT_SYSTEM_RESERVED_D:
792           requested_measurement_system = USER_MEASUREMENT_SYSTEM_RESERVED_D;
793           system_bonus = measurement_system_rms_d_tbl;
794           break;
795         case USER_MEASUREMENT_SYSTEM_RESERVED_E:
796           requested_measurement_system = USER_MEASUREMENT_SYSTEM_RESERVED_E;
797           system_bonus = measurement_system_rms_e_tbl;
798           break;
799 
800         default:
801           return (UNEXPECTED_ERROR);
802           break;
803       }
804 
805       switch (pstr_drc_sel_proc_params_struct->loudness_measurement_pre_proc) {
806         case USER_LOUDNESS_PREPROCESSING_DEFAULT:
807         case USER_LOUDNESS_PREPROCESSING_OFF:
808           requested_preprocessing = 0;
809           break;
810         case USER_LOUDNESS_PREPROCESSING_HIGHPASS:
811           requested_preprocessing = 1;
812           break;
813 
814         default:
815           return (UNEXPECTED_ERROR);
816           break;
817       }
818 
819       for (k = 0; k < info_count; k++) {
820         match_measure = -1;
821         for (n = 0; n < loudness_info[k]->measurement_count; n++) {
822           ia_loudness_measure_struct* loudness_measure =
823               &(loudness_info[k]->loudness_measure[n]);
824           if (match_measure <
825                   system_bonus[loudness_measure->measurement_system] &&
826               requested_method_definition == loudness_measure->method_def) {
827             method_val = loudness_measure->method_val;
828             match_measure = system_bonus[loudness_measure->measurement_system];
829           }
830         }
831         if (match_measure == -1) {
832           for (n = 0; n < loudness_info[k]->measurement_count; n++) {
833             ia_loudness_measure_struct* loudness_measure =
834                 &(loudness_info[k]->loudness_measure[n]);
835             if (match_measure <
836                     system_bonus[loudness_measure->measurement_system] &&
837                 other_method_definition == loudness_measure->method_def) {
838               method_val = loudness_measure->method_val;
839               match_measure =
840                   system_bonus[loudness_measure->measurement_system];
841             }
842           }
843         }
844 
845         if (requested_preprocessing == 1) {
846           err = impd_find_high_pass_loudness_adjust(
847               pstr_loudness_info, requested_dwnmix_id, drc_set_id_requested,
848               pstr_drc_sel_proc_params_struct->album_mode,
849               (FLOAT32)
850                   pstr_drc_sel_proc_params_struct->device_cut_off_frequency,
851               &loudness_hp_adjust_present, &pre_proc_adjust);
852           if (err) return (err);
853 
854           if (loudness_hp_adjust_present == 0) {
855             pre_proc_adjust = -2.0f;
856           }
857           method_val += pre_proc_adjust;
858         }
859 
860         eq_set_id[k] = 0;
861 
862         loudness_normalization_gain_db[k] =
863             pstr_drc_sel_proc_params_struct->target_loudness - method_val;
864         loudness[k] = method_val;
865       }
866     }
867   }
868   if (info_count > 0) {
869     *loudness_info_count = info_count;
870   } else {
871     *loudness_info_count = pre_lim_count;
872   }
873 
874   return (0);
875 }
876 
877 #define MIXING_LEVEL_DEFAULT 85.0f
878 WORD32
impd_mixing_level_info(ia_drc_sel_proc_params_struct * pstr_drc_sel_proc_params_struct,ia_drc_loudness_info_set_struct * pstr_loudness_info,WORD32 requested_dwnmix_id,WORD32 drc_set_id_requested,WORD32 eq_set_id_requested,FLOAT32 * mixing_level)879 impd_mixing_level_info(
880     ia_drc_sel_proc_params_struct* pstr_drc_sel_proc_params_struct,
881     ia_drc_loudness_info_set_struct* pstr_loudness_info,
882     WORD32 requested_dwnmix_id, WORD32 drc_set_id_requested,
883     WORD32 eq_set_id_requested, FLOAT32* mixing_level) {
884   WORD32 n, k, info_count;
885   WORD32 album_mode = pstr_drc_sel_proc_params_struct->album_mode;
886   WORD32 loudness_drc_set_id_requested;
887   ia_loudness_info_struct* loudness_info;
888 
889   *mixing_level = MIXING_LEVEL_DEFAULT;
890   if (drc_set_id_requested < 0) {
891     loudness_drc_set_id_requested = 0;
892   } else {
893     loudness_drc_set_id_requested = drc_set_id_requested;
894   }
895   if (album_mode == 1) {
896     info_count = pstr_loudness_info->loudness_info_album_count;
897     loudness_info = pstr_loudness_info->str_loudness_info_album;
898   } else {
899     info_count = pstr_loudness_info->loudness_info_count;
900     loudness_info = pstr_loudness_info->loudness_info;
901   }
902   for (n = 0; n < info_count; n++) {
903     if ((requested_dwnmix_id == loudness_info[n].downmix_id) ||
904         (ID_FOR_ANY_DOWNMIX == loudness_info[n].downmix_id)) {
905       if (loudness_drc_set_id_requested == loudness_info[n].drc_set_id) {
906         if (eq_set_id_requested == loudness_info[n].eq_set_id) {
907           for (k = 0; k < loudness_info[n].measurement_count; k++) {
908             if (loudness_info[n].loudness_measure[k].method_def ==
909                 METHOD_DEFINITION_MIXING_LEVEL) {
910               *mixing_level = loudness_info[n].loudness_measure[k].method_val;
911               break;
912             }
913           }
914         }
915       }
916     }
917   }
918   return (0);
919 }
920