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 <stdlib.h>
22 #include <math.h>
23 #include "impd_type_def.h"
24 #include "impd_error_standards.h"
25 #include "impd_drc_extr_delta_coded_info.h"
26 #include "impd_drc_common.h"
27 #include "impd_drc_struct.h"
28 #include "impd_drc_filter_bank.h"
29 #include "impd_drc_multi_band.h"
30 #include "impd_drc_rom.h"
31 
impd_fcenter_norm_sb_init(WORD32 num_subbands,FLOAT32 * fcenter_norm_subband)32 IA_ERRORCODE impd_fcenter_norm_sb_init(WORD32 num_subbands,
33                                        FLOAT32* fcenter_norm_subband) {
34   WORD32 s;
35   for (s = 0; s < num_subbands; s++) {
36     fcenter_norm_subband[s] = (s + 0.5f) / (2.0f * num_subbands);
37   }
38   return (0);
39 }
40 
impd_generate_slope(WORD32 num_sub_bands,FLOAT32 * fcenter_norm_subband,FLOAT32 fcross_norm_lo,FLOAT32 fcross_norm_hi,FLOAT32 * response)41 IA_ERRORCODE impd_generate_slope(WORD32 num_sub_bands,
42                                  FLOAT32* fcenter_norm_subband,
43                                  FLOAT32 fcross_norm_lo, FLOAT32 fcross_norm_hi,
44                                  FLOAT32* response) {
45   WORD32 i;
46   FLOAT32 filter_slope = -24.0f;
47   FLOAT32 inv_log10_2 = 3.32192809f;
48   FLOAT32 norm = 0.05f * filter_slope * inv_log10_2;
49 
50   for (i = 0; i < num_sub_bands; i++) {
51     if (fcenter_norm_subband[i] < fcross_norm_lo) {
52       response[i] = (FLOAT32)pow(
53           10.0, norm * log10(fcross_norm_lo / fcenter_norm_subband[i]));
54     } else if (fcenter_norm_subband[i] < fcross_norm_hi) {
55       response[i] = 1.0f;
56     } else {
57       response[i] = (FLOAT32)pow(
58           10.0, norm * log10(fcenter_norm_subband[i] / fcross_norm_hi));
59     }
60   }
61   return (0);
62 }
63 
impd_generate_overlap_weights(WORD32 num_drc_bands,WORD32 drc_band_type,ia_gain_params_struct * gain_params,WORD32 dec_subband_count,ia_group_overlap_params_struct * pstr_group_overlap_params)64 IA_ERRORCODE impd_generate_overlap_weights(
65     WORD32 num_drc_bands, WORD32 drc_band_type,
66     ia_gain_params_struct* gain_params, WORD32 dec_subband_count,
67     ia_group_overlap_params_struct* pstr_group_overlap_params) {
68   FLOAT32 fcenter_norm_subband[AUDIO_CODEC_SUBBAND_COUNT_MAX];
69   FLOAT32 w_norm[AUDIO_CODEC_SUBBAND_COUNT_MAX];
70   FLOAT32 fcross_norm_lo, fcross_norm_hi;
71   WORD32 err, b, s, start_subband_index = 0, stop_sub_band_index = 0;
72   err = impd_fcenter_norm_sb_init(dec_subband_count, fcenter_norm_subband);
73 
74   if (drc_band_type == 1) {
75     fcross_norm_lo = 0.0f;
76     for (b = 0; b < num_drc_bands; b++) {
77       if (b < num_drc_bands - 1) {
78         fcross_norm_hi =
79             normal_cross_freq[gain_params[b + 1].crossover_freq_idx]
80                 .f_cross_norm;
81       } else {
82         fcross_norm_hi = 0.5f;
83       }
84       impd_generate_slope(
85           dec_subband_count, fcenter_norm_subband, fcross_norm_lo,
86           fcross_norm_hi,
87           pstr_group_overlap_params->str_band_overlap_params[b].overlap_weight);
88 
89       fcross_norm_lo = fcross_norm_hi;
90     }
91     for (s = 0; s < dec_subband_count; s++) {
92       w_norm[s] = pstr_group_overlap_params->str_band_overlap_params[0]
93                       .overlap_weight[s];
94       for (b = 1; b < num_drc_bands; b++) {
95         w_norm[s] += pstr_group_overlap_params->str_band_overlap_params[b]
96                          .overlap_weight[s];
97       }
98     }
99 
100     for (s = 0; s < dec_subband_count; s++) {
101       for (b = 0; b < num_drc_bands; b++) {
102         pstr_group_overlap_params->str_band_overlap_params[b]
103             .overlap_weight[s] /= w_norm[s];
104       }
105     }
106   } else {
107     start_subband_index = 0;
108     for (b = 0; b < num_drc_bands; b++) {
109       if (b < num_drc_bands - 1) {
110         stop_sub_band_index = gain_params[b + 1].start_subband_index - 1;
111       } else {
112         stop_sub_band_index = dec_subband_count - 1;
113       }
114       for (s = 0; s < dec_subband_count; s++) {
115         if (s >= start_subband_index && s <= stop_sub_band_index) {
116           pstr_group_overlap_params->str_band_overlap_params[b]
117               .overlap_weight[s] = 1.0;
118         } else {
119           pstr_group_overlap_params->str_band_overlap_params[b]
120               .overlap_weight[s] = 0.0;
121         }
122       }
123       start_subband_index = stop_sub_band_index + 1;
124     }
125   }
126 
127   return (0);
128 }
129 
impd_init_overlap_weight(ia_uni_drc_coeffs_struct * str_p_loc_drc_coefficients_uni_drc,ia_drc_instructions_struct * str_drc_instruction_str,WORD32 sub_band_domain_mode,ia_overlap_params_struct * pstr_overlap_params)130 IA_ERRORCODE impd_init_overlap_weight(
131     ia_uni_drc_coeffs_struct* str_p_loc_drc_coefficients_uni_drc,
132     ia_drc_instructions_struct* str_drc_instruction_str,
133     WORD32 sub_band_domain_mode,
134     ia_overlap_params_struct* pstr_overlap_params) {
135   WORD32 err = 0, g;
136   WORD32 dec_subband_count = 0;
137   switch (sub_band_domain_mode) {
138     case SUBBAND_DOMAIN_MODE_QMF64:
139       dec_subband_count = AUDIO_CODEC_SUBBAND_COUNT_QMF64;
140       break;
141     case SUBBAND_DOMAIN_MODE_QMF71:
142       dec_subband_count = AUDIO_CODEC_SUBBAND_COUNT_QMF71;
143       break;
144     case SUBBAND_DOMAIN_MODE_STFT256:
145       dec_subband_count = AUDIO_CODEC_SUBBAND_COUNT_STFT256;
146       break;
147   }
148 
149   for (g = 0; g < str_drc_instruction_str->num_drc_ch_groups; g++) {
150     if (str_drc_instruction_str->band_count_of_ch_group[g] > 1) {
151       err = impd_generate_overlap_weights(
152           str_drc_instruction_str->band_count_of_ch_group[g],
153           str_p_loc_drc_coefficients_uni_drc
154               ->gain_set_params[str_drc_instruction_str
155                                     ->gain_set_index_for_channel_group[g]]
156               .drc_band_type,
157           str_p_loc_drc_coefficients_uni_drc
158               ->gain_set_params[str_drc_instruction_str
159                                     ->gain_set_index_for_channel_group[g]]
160               .gain_params,
161           dec_subband_count,
162           &(pstr_overlap_params->str_group_overlap_params[g]));
163       if (err) return (err);
164     }
165   }
166 
167   return (0);
168 }
169