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 <malladi.sastry@intel.com>
This commit is contained in:
shastry 2023-12-05 08:24:06 +05:30 committed by Liam Girdwood
parent 8852db8b6c
commit 3ed4ddd02f
5 changed files with 23 additions and 18 deletions

View File

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

View File

@ -6,7 +6,7 @@
#include <sof/audio/component.h>
#include <sof/audio/format.h>
#include <sof/math/decibels.h>
#include <sof/math/exp_fcn.h>
#include <sof/math/numbers.h>
#include <stdint.h>
@ -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 */

View File

@ -6,7 +6,7 @@
#include <sof/audio/component.h>
#include <sof/audio/format.h>
#include <sof/math/decibels.h>
#include <sof/math/exp_fcn.h>
#include <sof/math/numbers.h>
#include <stdint.h>
@ -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 */

View File

@ -6,7 +6,7 @@
#include <sof/audio/component.h>
#include <sof/audio/format.h>
#include <sof/math/decibels.h>
#include <sof/math/exp_fcn.h>
#include <sof/math/numbers.h>
#include <stdint.h>
@ -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 */

View File

@ -6,6 +6,7 @@
#include <sof/audio/format.h>
#include <sof/math/decibels.h>
#include <sof/math/exp_fcn.h>
#include <sof/math/numbers.h>
#include <sof/math/trig.h>
@ -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