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