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