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 <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 
     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 
     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 
     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 
    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