diff options
Diffstat (limited to 'encoder/drc_src/impd_drc_gain_calculator.c')
-rw-r--r-- | encoder/drc_src/impd_drc_gain_calculator.c | 165 |
1 files changed, 91 insertions, 74 deletions
diff --git a/encoder/drc_src/impd_drc_gain_calculator.c b/encoder/drc_src/impd_drc_gain_calculator.c index 24514c3..5a1305a 100644 --- a/encoder/drc_src/impd_drc_gain_calculator.c +++ b/encoder/drc_src/impd_drc_gain_calculator.c @@ -18,6 +18,7 @@ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ #include <math.h> +#include <float.h> #include "ixheaac_type_def.h" #include "ixheaac_error_standards.h" #include "ixheaace_error_codes.h" @@ -45,6 +46,7 @@ #include "impd_drc_gain_enc.h" #include "impd_drc_struct_def.h" #include "impd_drc_enc.h" +#include "ixheaace_common_utils.h" static VOID impd_drc_compand_update_volume(ia_drc_compand_chan_param_struct *pstr_channel_param, FLOAT64 in_value) { @@ -67,7 +69,12 @@ static FLOAT64 impd_drc_compand_get_volume(ia_drc_compand_struct *pstr_drc_compa return pstr_drc_compand->out_min_lin; } - in_log = log(in_lin); + if (fabs(in_lin) <= FLT_EPSILON) { + in_log = log(FLT_EPSILON); + } + else { + in_log = log(fabs(in_lin)); + } for (idx = 1; idx < pstr_drc_compand->nb_segments; idx++) { if (in_log <= pstr_drc_compand->str_segment[idx].x) { @@ -121,8 +128,6 @@ IA_ERRORCODE impd_drc_td_drc_gain_calc_init(ia_drc_gain_enc_struct *pstr_drc_gai pstr_drc_compand = &pstr_drc_gain_enc->str_drc_compand[drc_coefficients_uni_drc_idx][gain_set_idx]; - pstr_drc_compand->nb_segments = (pstr_drc_compand->nb_points + 4) * 2; - for (i = 0; i < pstr_drc_compand->nb_points; i++) { if (i && pstr_drc_compand->str_segment[2 * ((i - 1) + 1)].x > pstr_drc_compand->str_segment[2 * ((i) + 1)].x) { @@ -161,6 +166,7 @@ IA_ERRORCODE impd_drc_td_drc_gain_calc_init(ia_drc_gain_enc_struct *pstr_drc_gai } } + pstr_drc_compand->nb_segments = num_points * 2; for (i = 0; i < pstr_drc_compand->nb_segments; i += 2) { pstr_drc_compand->str_segment[i].y += pstr_drc_compand->gain_db; pstr_drc_compand->str_segment[i].x *= M_LN10_DIV_20; @@ -168,35 +174,33 @@ IA_ERRORCODE impd_drc_td_drc_gain_calc_init(ia_drc_gain_enc_struct *pstr_drc_gai } for (i = 4; i < pstr_drc_compand->nb_segments; i += 2) { + FLOAT64 num = 0.0; + FLOAT64 den = 0.0f; + + num = pstr_drc_compand->str_segment[i - 2].y - pstr_drc_compand->str_segment[i - 4].y; + den = pstr_drc_compand->str_segment[i - 2].x - pstr_drc_compand->str_segment[i - 4].x; + length = hypot(num, den); + if (length < FLT_EPSILON) { + return IA_EXHEAACE_EXE_NONFATAL_USAC_INVALID_GAIN_POINTS; + } pstr_drc_compand->str_segment[i - 4].a = 0; - pstr_drc_compand->str_segment[i - 4].b = - (pstr_drc_compand->str_segment[i - 2].y - pstr_drc_compand->str_segment[i - 4].y) / - (pstr_drc_compand->str_segment[i - 2].x - pstr_drc_compand->str_segment[i - 4].x); - - pstr_drc_compand->str_segment[i - 2].a = 0; - pstr_drc_compand->str_segment[i - 2].b = - (pstr_drc_compand->str_segment[i].y - pstr_drc_compand->str_segment[i - 2].y) / - (pstr_drc_compand->str_segment[i].x - pstr_drc_compand->str_segment[i - 2].x); - - theta = - atan2(pstr_drc_compand->str_segment[i - 2].y - pstr_drc_compand->str_segment[i - 4].y, - pstr_drc_compand->str_segment[i - 2].x - pstr_drc_compand->str_segment[i - 4].x); - length = - hypot(pstr_drc_compand->str_segment[i - 2].x - pstr_drc_compand->str_segment[i - 4].x, - pstr_drc_compand->str_segment[i - 2].y - pstr_drc_compand->str_segment[i - 4].y); - + pstr_drc_compand->str_segment[i - 4].b = ixheaace_div64(num, den); + theta = atan2(num, den); r = MIN(radius, length); pstr_drc_compand->str_segment[i - 3].x = pstr_drc_compand->str_segment[i - 2].x - r * cos(theta); pstr_drc_compand->str_segment[i - 3].y = pstr_drc_compand->str_segment[i - 2].y - r * sin(theta); - theta = - atan2(pstr_drc_compand->str_segment[i].y - pstr_drc_compand->str_segment[i - 2].y, - pstr_drc_compand->str_segment[i - 0].x - pstr_drc_compand->str_segment[i - 2].x); - length = hypot(pstr_drc_compand->str_segment[i].x - pstr_drc_compand->str_segment[i - 2].x, - pstr_drc_compand->str_segment[i].y - pstr_drc_compand->str_segment[i - 2].y); - + num = pstr_drc_compand->str_segment[i].y - pstr_drc_compand->str_segment[i - 2].y; + den = pstr_drc_compand->str_segment[i].x - pstr_drc_compand->str_segment[i - 2].x; + length = hypot(num, den); + if (length < FLT_EPSILON) { + return IA_EXHEAACE_EXE_NONFATAL_USAC_INVALID_GAIN_POINTS; + } + pstr_drc_compand->str_segment[i - 2].a = 0; + pstr_drc_compand->str_segment[i - 2].b = ixheaace_div64(num, den); + theta = atan2(num, den); r = MIN(radius, length / 2); x = pstr_drc_compand->str_segment[i - 2].x + r * cos(theta); y = pstr_drc_compand->str_segment[i - 2].y + r * sin(theta); @@ -213,9 +217,14 @@ IA_ERRORCODE impd_drc_td_drc_gain_calc_init(ia_drc_gain_enc_struct *pstr_drc_gai out_1 = cy - pstr_drc_compand->str_segment[i - 3].y; inp_2 = pstr_drc_compand->str_segment[i - 2].x - pstr_drc_compand->str_segment[i - 3].x; out_2 = pstr_drc_compand->str_segment[i - 2].y - pstr_drc_compand->str_segment[i - 3].y; - pstr_drc_compand->str_segment[i - 3].a = (out_2 / inp_2 - out_1 / inp_1) / (inp_2 - inp_1); - pstr_drc_compand->str_segment[i - 3].b = - out_1 / inp_1 - pstr_drc_compand->str_segment[i - 3].a * inp_1; + + num = (out_2 * inp_1) - (inp_2 * out_1); + den = (inp_2 - inp_1) * inp_1 * inp_2; + pstr_drc_compand->str_segment[i - 3].a = ixheaace_div64(num, den); + + num = out_1 - (pstr_drc_compand->str_segment[i - 3].a * inp_1 * inp_1); + den = inp_1; + pstr_drc_compand->str_segment[i - 3].b = ixheaace_div64(num, den); } pstr_drc_compand->str_segment[i - 3].x = 0; pstr_drc_compand->str_segment[i - 3].y = pstr_drc_compand->str_segment[i - 3].y; @@ -325,7 +334,7 @@ IA_ERRORCODE impd_drc_stft_drc_gain_calc_init(ia_drc_gain_enc_struct *pstr_drc_g WORD32 gain_set_idx, WORD32 band_idx) { ULOOPIDX i, j; UWORD32 num_points; - FLOAT32 width_e; + FLOAT32 width_e, tmp; FLOAT64 g1, g2; FLOAT64 x, y, cx, cy, r; FLOAT64 inp_1, inp_2, out_1, out_2, theta, len; @@ -343,8 +352,6 @@ IA_ERRORCODE impd_drc_stft_drc_gain_calc_init(ia_drc_gain_enc_struct *pstr_drc_g width_e = (FLOAT32)(pstr_drc_stft_gain_handle->width_db * M_LN10_DIV_20); - pstr_drc_stft_gain_handle->nb_segments = (pstr_drc_stft_gain_handle->nb_points + 4) * 2; - for (i = 0; i < pstr_drc_stft_gain_handle->nb_points; i++) { if (i && pstr_drc_stft_gain_handle->str_segment[2 * ((i - 1) + 1)].x > pstr_drc_stft_gain_handle->str_segment[2 * (i + 1)].x) { @@ -384,7 +391,7 @@ IA_ERRORCODE impd_drc_stft_drc_gain_calc_init(ia_drc_gain_enc_struct *pstr_drc_g pstr_drc_stft_gain_handle->str_segment[2 * (j + 1)]; } } - + pstr_drc_stft_gain_handle->nb_segments = num_points * 2; for (i = 0; i < pstr_drc_stft_gain_handle->nb_segments; i += 2) { pstr_drc_stft_gain_handle->str_segment[i].y += pstr_drc_stft_gain_handle->gain_db; pstr_drc_stft_gain_handle->str_segment[i].x *= M_LN10_DIV_20; @@ -392,42 +399,39 @@ IA_ERRORCODE impd_drc_stft_drc_gain_calc_init(ia_drc_gain_enc_struct *pstr_drc_g } for (i = 4; i < pstr_drc_stft_gain_handle->nb_segments; i += 2) { + FLOAT64 denominator; + FLOAT64 numerator; + + denominator = pstr_drc_stft_gain_handle->str_segment[i - 2].x - + pstr_drc_stft_gain_handle->str_segment[i - 4].x; + numerator = pstr_drc_stft_gain_handle->str_segment[i - 2].y - + pstr_drc_stft_gain_handle->str_segment[i - 4].y; + len = hypot(denominator , numerator); + if (len < FLT_EPSILON) { + return IA_EXHEAACE_EXE_NONFATAL_USAC_INVALID_GAIN_POINTS; + } pstr_drc_stft_gain_handle->str_segment[i - 4].a = 0; - pstr_drc_stft_gain_handle->str_segment[i - 4].b = - (pstr_drc_stft_gain_handle->str_segment[i - 2].y - - pstr_drc_stft_gain_handle->str_segment[i - 4].y) / - (pstr_drc_stft_gain_handle->str_segment[i - 2].x - - pstr_drc_stft_gain_handle->str_segment[i - 4].x); + pstr_drc_stft_gain_handle->str_segment[i - 4].b = ixheaace_div64(numerator, denominator); + theta = atan2(numerator, denominator); + r = MIN(width_e / (2.0f * cos(theta)), len / 2); - pstr_drc_stft_gain_handle->str_segment[i - 2].a = 0; - pstr_drc_stft_gain_handle->str_segment[i - 2].b = - (pstr_drc_stft_gain_handle->str_segment[i].y - - pstr_drc_stft_gain_handle->str_segment[i - 2].y) / - (pstr_drc_stft_gain_handle->str_segment[i].x - - pstr_drc_stft_gain_handle->str_segment[i - 2].x); - - theta = atan2(pstr_drc_stft_gain_handle->str_segment[i - 2].y - - pstr_drc_stft_gain_handle->str_segment[i - 4].y, - pstr_drc_stft_gain_handle->str_segment[i - 2].x - - pstr_drc_stft_gain_handle->str_segment[i - 4].x); - len = hypot(pstr_drc_stft_gain_handle->str_segment[i - 2].x - - pstr_drc_stft_gain_handle->str_segment[i - 4].x, - pstr_drc_stft_gain_handle->str_segment[i - 2].y - - pstr_drc_stft_gain_handle->str_segment[i - 4].y); - r = MIN(width_e / (2.0f * cos(theta)), len); pstr_drc_stft_gain_handle->str_segment[i - 3].x = - pstr_drc_stft_gain_handle->str_segment[i - 2].x - r * cos(theta); + pstr_drc_stft_gain_handle->str_segment[i - 2].x - r * cos(theta); pstr_drc_stft_gain_handle->str_segment[i - 3].y = - pstr_drc_stft_gain_handle->str_segment[i - 2].y - r * sin(theta); - - theta = atan2(pstr_drc_stft_gain_handle->str_segment[i].y - - pstr_drc_stft_gain_handle->str_segment[i - 2].y, - pstr_drc_stft_gain_handle->str_segment[i].x - - pstr_drc_stft_gain_handle->str_segment[i - 2].x); - len = hypot(pstr_drc_stft_gain_handle->str_segment[i].x - - pstr_drc_stft_gain_handle->str_segment[i - 2].x, - pstr_drc_stft_gain_handle->str_segment[i].y - - pstr_drc_stft_gain_handle->str_segment[i - 2].y); + pstr_drc_stft_gain_handle->str_segment[i - 2].y - r * sin(theta); + + denominator = pstr_drc_stft_gain_handle->str_segment[i].x - + pstr_drc_stft_gain_handle->str_segment[i - 2].x; + numerator = pstr_drc_stft_gain_handle->str_segment[i].y - + pstr_drc_stft_gain_handle->str_segment[i - 2].y; + len = hypot(denominator, numerator); + if (len < FLT_EPSILON) { + return IA_EXHEAACE_EXE_NONFATAL_USAC_INVALID_GAIN_POINTS; + } + pstr_drc_stft_gain_handle->str_segment[i - 2].a = 0; + pstr_drc_stft_gain_handle->str_segment[i - 2].b = ixheaace_div64(numerator, denominator); + + theta = atan2(numerator, denominator); r = MIN(width_e / (2.0f * cos(theta)), len / 2); x = pstr_drc_stft_gain_handle->str_segment[i - 2].x + r * cos(theta); y = pstr_drc_stft_gain_handle->str_segment[i - 2].y + r * sin(theta); @@ -448,10 +452,13 @@ IA_ERRORCODE impd_drc_stft_drc_gain_calc_init(ia_drc_gain_enc_struct *pstr_drc_g pstr_drc_stft_gain_handle->str_segment[i - 3].x; out_2 = pstr_drc_stft_gain_handle->str_segment[i - 2].y - pstr_drc_stft_gain_handle->str_segment[i - 3].y; - pstr_drc_stft_gain_handle->str_segment[i - 3].a = - (out_2 / inp_2 - out_1 / inp_1) / (inp_2 - inp_1); - pstr_drc_stft_gain_handle->str_segment[i - 3].b = - out_1 / inp_1 - pstr_drc_stft_gain_handle->str_segment[i - 3].a * inp_1; + numerator = (out_2 * inp_1) - (inp_2 * out_1); + denominator = (inp_2 - inp_1) * inp_2 * inp_1; + pstr_drc_stft_gain_handle->str_segment[i - 3].a = ixheaace_div64(numerator, denominator); + + numerator = out_1 - (pstr_drc_stft_gain_handle->str_segment[i - 3].a * inp_1 * inp_1); + denominator = inp_1; + pstr_drc_stft_gain_handle->str_segment[i - 3].b = ixheaace_div64(numerator, denominator); } pstr_drc_stft_gain_handle->str_segment[i - 3].x = 0; pstr_drc_stft_gain_handle->str_segment[i - 3].y = @@ -470,13 +477,23 @@ IA_ERRORCODE impd_drc_stft_drc_gain_calc_init(ia_drc_gain_enc_struct *pstr_drc_g pstr_drc_stft_gain_handle->yl_z1[i] = 0.0f; } - pstr_drc_stft_gain_handle->alpha_a = - expf(-1.0f / ((pstr_drc_stft_gain_handle->attack_ms / (FLOAT32)STFT256_HOP_SIZE) * - (FLOAT32)pstr_drc_gain_enc->sample_rate * 0.001f)); + tmp = (pstr_drc_stft_gain_handle->attack_ms / STFT256_HOP_SIZE) * + pstr_drc_gain_enc->sample_rate * 0.001f; + if ((fabs(tmp) < FLT_EPSILON) && (tmp >= 0.0f)) { + pstr_drc_stft_gain_handle->alpha_a = 0; + } + else { + pstr_drc_stft_gain_handle->alpha_a = expf(ixheaace_div32(-1.0f, tmp)); + } - pstr_drc_stft_gain_handle->alpha_r = - expf(-1.0f / ((pstr_drc_stft_gain_handle->release_ms / (FLOAT32)STFT256_HOP_SIZE) * - (FLOAT32)pstr_drc_gain_enc->sample_rate * 0.001f)); + tmp = (pstr_drc_stft_gain_handle->release_ms / STFT256_HOP_SIZE) * + pstr_drc_gain_enc->sample_rate * 0.001f; + if ((fabs(tmp) < FLT_EPSILON) && (tmp >= 0.0f)) { + pstr_drc_stft_gain_handle->alpha_r = 0; + } + else { + pstr_drc_stft_gain_handle->alpha_r = expf(ixheaace_div32(-1.0f, tmp)); + } return IA_NO_ERROR; } |