From 3ed4ddd02fd6375fd37ab46be4bba86df6f4b1ed Mon Sep 17 00:00:00 2001 From: shastry Date: Tue, 5 Dec 2023 08:24:06 +0530 Subject: [PATCH] Audio: DRC: Use fast exponent functions The exp_fixed() function is replaced by fast sofm_exp_fixed() and sofm_db2lin() functions. It saves 40 MCPS, from 123 to 83 MCPS in a test run in TGL platform. Signed-off-by: shastry --- src/audio/drc/Kconfig | 2 +- src/audio/drc/drc_generic.c | 14 ++++++++------ src/audio/drc/drc_hifi3.c | 11 ++++++----- src/audio/drc/drc_hifi4.c | 11 ++++++----- src/audio/drc/drc_math_generic.c | 3 ++- 5 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/audio/drc/Kconfig b/src/audio/drc/Kconfig index c34da85e1..985feede9 100644 --- a/src/audio/drc/Kconfig +++ b/src/audio/drc/Kconfig @@ -4,7 +4,7 @@ config COMP_DRC bool "Dynamic Range Compressor component" select CORDIC_FIXED select NUMBERS_NORM - select MATH_DECIBELS + select MATH_EXP select COMP_BLOB default n help diff --git a/src/audio/drc/drc_generic.c b/src/audio/drc/drc_generic.c index 1ad0c5073..bc16fc670 100644 --- a/src/audio/drc/drc_generic.c +++ b/src/audio/drc/drc_generic.c @@ -6,7 +6,7 @@ #include #include -#include +#include #include #include @@ -36,7 +36,7 @@ static int32_t knee_curveK(const struct sof_drc_params *p, int32_t x) * beta = -expf(k * linear_threshold) / k * gamma = -k * x */ - knee_exp_gamma = exp_fixed(Q_MULTSR_32X32((int64_t)x, -p->K, 31, 20, 27)); /* Q12.20 */ + knee_exp_gamma = sofm_exp_fixed(Q_MULTSR_32X32((int64_t)x, -p->K, 31, 20, 27)); /* Q12.20 */ return p->knee_alpha + Q_MULTSR_32X32((int64_t)p->knee_beta, knee_exp_gamma, 24, 20, 24); } @@ -66,8 +66,10 @@ static int32_t volume_gain(const struct sof_drc_params *p, int32_t x) * => y/x = ratio_base * x^(s - 1) * => y/x = ratio_base * e^(log(x) * (s - 1)) */ - exp_knee = exp_fixed(Q_MULTSR_32X32((int64_t)drc_log_fixed(Q_SHIFT_RND(x, 31, 26)), - (p->slope - ONE_Q30), 26, 30, 27)); /* Q12.20 */ + exp_knee = sofm_exp_fixed(Q_MULTSR_32X32((int64_t) + drc_log_fixed(Q_SHIFT_RND(x, 31, 26)), + (p->slope - ONE_Q30), + 26, 30, 27)); /* Q12.20 */ y = Q_MULTSR_32X32((int64_t)p->ratio_base, exp_knee, 30, 20, 30); } @@ -149,7 +151,7 @@ void drc_update_detector_average(struct drc_state *state, p->sat_release_frames_inv_neg, 21, 30, 24); /* Q8.24 */ sat_release_rate = - db2lin_fixed(db_per_frame) - ONE_Q20; /* Q12.20 */ + sofm_db2lin_fixed(db_per_frame) - ONE_Q20; /* Q12.20 */ detector_average += Q_MULTSR_32X32((int64_t)gain_diff, sat_release_rate, 30, 20, 30); } @@ -226,7 +228,7 @@ void drc_update_envelope(struct drc_state *state, const struct sof_drc_params *p /* db_per_frame = kSpacingDb / release_frames */ db_per_frame = drc_inv_fixed(release_frames, 12, 30); /* Q2.30 */ db_per_frame = Q_MULTSR_32X32((int64_t)db_per_frame, p->kSpacingDb, 30, 0, 24); - envelope_rate = db2lin_fixed(db_per_frame); /* Q12.20 */ + envelope_rate = sofm_db2lin_fixed(db_per_frame); /* Q12.20 */ } else { int32_t sat32; /* Attack mode - compression_diff_db should be positive dB */ diff --git a/src/audio/drc/drc_hifi3.c b/src/audio/drc/drc_hifi3.c index 5cb2920fc..73f171fd7 100644 --- a/src/audio/drc/drc_hifi3.c +++ b/src/audio/drc/drc_hifi3.c @@ -6,7 +6,7 @@ #include #include -#include +#include #include #include @@ -42,7 +42,7 @@ static int32_t knee_curveK(const struct sof_drc_params *p, int32_t x) * gamma = -k * x */ gamma = drc_mult_lshift(x, -p->K, drc_get_lshift(31, 20, 27)); - knee_exp_gamma = exp_fixed(gamma); + knee_exp_gamma = sofm_exp_fixed(gamma); knee_curve_k = drc_mult_lshift(p->knee_beta, knee_exp_gamma, drc_get_lshift(24, 20, 24)); knee_curve_k = AE_ADD32(knee_curve_k, p->knee_alpha); return knee_curve_k; @@ -78,7 +78,7 @@ static int32_t volume_gain(const struct sof_drc_params *p, int32_t x) tmp = AE_SRAI32R(x, 5); /* Q1.31 -> Q5.26 */ tmp = drc_log_fixed(tmp); /* Q6.26 */ tmp2 = AE_SUB32(p->slope, ONE_Q30); /* Q2.30 */ - exp_knee = exp_fixed(drc_mult_lshift(tmp, tmp2, drc_get_lshift(26, 30, 27))); + exp_knee = sofm_exp_fixed(drc_mult_lshift(tmp, tmp2, drc_get_lshift(26, 30, 27))); y = drc_mult_lshift(p->ratio_base, exp_knee, drc_get_lshift(30, 20, 30)); } @@ -159,7 +159,8 @@ void drc_update_detector_average(struct drc_state *state, db_per_frame = drc_mult_lshift(drc_lin2db_fixed(gain), p->sat_release_frames_inv_neg, drc_get_lshift(21, 30, 24)); - sat_release_rate = AE_SUB32(db2lin_fixed(db_per_frame), ONE_Q20); + sat_release_rate = AE_SUB32(sofm_db2lin_fixed(db_per_frame), + ONE_Q20); tmp = drc_mult_lshift(gain_diff, sat_release_rate, drc_get_lshift(30, 20, 30)); } @@ -254,7 +255,7 @@ void drc_update_envelope(struct drc_state *state, const struct sof_drc_params *p tmp = p->kSpacingDb << 16; /* Q16.16 */ lshift = drc_get_lshift(30, 16, 24); db_per_frame = drc_mult_lshift(db_per_frame, tmp, lshift); /* Q8.24 */ - envelope_rate = db2lin_fixed(db_per_frame); /* Q12.20 */ + envelope_rate = sofm_db2lin_fixed(db_per_frame); /* Q12.20 */ } else { /* Attack mode - compression_diff_db should be positive dB */ diff --git a/src/audio/drc/drc_hifi4.c b/src/audio/drc/drc_hifi4.c index b0c34ea5e..b414831a3 100644 --- a/src/audio/drc/drc_hifi4.c +++ b/src/audio/drc/drc_hifi4.c @@ -6,7 +6,7 @@ #include #include -#include +#include #include #include @@ -65,7 +65,7 @@ static int32_t knee_curveK(const struct sof_drc_params *p, int32_t x) * gamma = -k * x */ gamma = drc_mult_lshift(x, -p->K, LSHIFT_QX31_QY20_QZ27); - knee_exp_gamma = exp_fixed(gamma); + knee_exp_gamma = sofm_exp_fixed(gamma); knee_curve_k = drc_mult_lshift(p->knee_beta, knee_exp_gamma, LSHIFT_QX24_QY20_QZ24); knee_curve_k = AE_ADD32(knee_curve_k, p->knee_alpha); return knee_curve_k; @@ -101,7 +101,7 @@ static int32_t volume_gain(const struct sof_drc_params *p, int32_t x) tmp = AE_SRAI32R(x, 5); /* Q1.31 -> Q5.26 */ tmp = drc_log_fixed(tmp); /* Q6.26 */ tmp2 = AE_SUB32(p->slope, ONE_Q30); /* Q2.30 */ - exp_knee = exp_fixed(drc_mult_lshift(tmp, tmp2, LSHIFT_QX26_QY30_QZ27)); + exp_knee = sofm_exp_fixed(drc_mult_lshift(tmp, tmp2, LSHIFT_QX26_QY30_QZ27)); y = drc_mult_lshift(p->ratio_base, exp_knee, LSHIFT_QX30_QY20_QZ30); } @@ -185,7 +185,8 @@ void drc_update_detector_average(struct drc_state *state, db_per_frame = drc_mult_lshift(drc_lin2db_fixed(gain), p->sat_release_frames_inv_neg, LSHIFT_QX21_QY30_QZ24); - sat_release_rate = AE_SUB32(db2lin_fixed(db_per_frame), ONE_Q20); + sat_release_rate = AE_SUB32(sofm_db2lin_fixed(db_per_frame), + ONE_Q20); tmp = drc_mult_lshift(gain_diff, sat_release_rate, LSHIFT_QX30_QY20_QZ30); } @@ -278,7 +279,7 @@ void drc_update_envelope(struct drc_state *state, const struct sof_drc_params *p tmp = p->kSpacingDb << 16; /* Q16.16 */ /* Q8.24 */ db_per_frame = drc_mult_lshift(db_per_frame, tmp, LSHIFT_QX30_QY16_QZ24); - envelope_rate = db2lin_fixed(db_per_frame); /* Q12.20 */ + envelope_rate = sofm_db2lin_fixed(db_per_frame); /* Q12.20 */ } else { /* Attack mode - compression_diff_db should be positive dB */ diff --git a/src/audio/drc/drc_math_generic.c b/src/audio/drc/drc_math_generic.c index 7ebcae51a..436ee444c 100644 --- a/src/audio/drc/drc_math_generic.c +++ b/src/audio/drc/drc_math_generic.c @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -234,7 +235,7 @@ inline int32_t drc_pow_fixed(int32_t x, int32_t y) return 0; /* x^y = expf(y * log(x)) */ - return exp_fixed(q_mult(y, drc_log_fixed(x), 30, 26, 27)); + return sofm_exp_fixed(q_mult(y, drc_log_fixed(x), 30, 26, 27)); } #undef q_multq