Skip to content

Commit c328dd8

Browse files
singalsulgirdwood
authored andcommitted
DMIC: Add support for passing unmute ramp time from topology
The raw capture from digital microphones contain some DC signal in the beginning. The DC compensation filter is set to be quite slow to enable capturing lowest audio frequencies. The unmute gain ramp is used in DMIC driver to conceal the DC signal. The required time for clean looking start is is microphone model and platform dependent. Also since not all applications are sensitive to DC waveform it is useful to specify the ramp length in topology. This patch adds to DMIC driver feature to define the unmute ramp length in milliseconds. If the value from IPC is zero the existing hard coded 400 ms long ramp is used. If the value is non-zero and within min/max 10ms/1000ms limits the topology defined ramp length is used. The code uses the db2lin_fixed() function to convert the dB step to a linear gain update coefficient. Also the hardcoded ramp definition is simplified to use dB initial gain value and length in milliseconds instead of magic looking numbers. This patch also contains ABI minor version increase to 8. Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
1 parent 909b790 commit c328dd8

4 files changed

Lines changed: 50 additions & 15 deletions

File tree

src/drivers/intel/cavs/dmic.c

Lines changed: 46 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <sof/interrupt.h>
1010
#include <sof/pm_runtime.h>
1111
#include <sof/math/numbers.h>
12+
#include <sof/math/decibels.h>
1213
#include <sof/audio/format.h>
1314

1415
#if defined DMIC_HW_VERSION
@@ -95,15 +96,23 @@ struct pdm_controllers_configuration {
9596
/* Used in unmute ramp values calculation */
9697
#define DMIC_HW_FIR_GAIN_MAX ((1 << (DMIC_HW_BITS_FIR_GAIN - 1)) - 1)
9798

98-
/* Hardwired log ramp parameters. The first value is the initial logarithmic
99-
* gain and the second value is the multiplier for gain to achieve the linear
100-
* decibels change over time. Currently the coefficient GM needs to be
101-
* calculated manually. The 400 ms ramp should ensure clean sounding start
102-
* with any microphone.
103-
* TODO: Add ramp characteristic passing via topology.
99+
/* Hardwired log ramp parameters. The first value is the initial gain in
100+
* decibels. The second value is the default ramp time.
104101
*/
105-
#define LOGRAMP_GI 33954 /* -90 dB, Q2.30*/
106-
#define LOGRAMP_GM 16814 /* Gives 400 ms ramp for -90..0 dB, Q2.14 */
102+
#define LOGRAMP_START_DB Q_CONVERT_FLOAT(-90, DB2LIN_FIXED_INPUT_QY)
103+
#define LOGRAMP_TIME_MS 400 /* Default ramp time in milliseconds */
104+
105+
/* Limits for ramp time from topology */
106+
#define LOGRAMP_TIME_MIN_MS 10 /* Min. 10 ms */
107+
#define LOGRAMP_TIME_MAX_MS 1000 /* Max. 1s */
108+
109+
/* Simplify log ramp step calculation equation with this constant term */
110+
#define LOGRAMP_CONST_TERM ((int32_t) \
111+
((int64_t)-LOGRAMP_START_DB * DMIC_UNMUTE_RAMP_US / 1000))
112+
113+
/* Fractional shift for gain update. Gain format is Q2.30. */
114+
#define Q_SHIFT_GAIN_X_GAIN_COEF \
115+
(Q_SHIFT_BITS_32(30, DB2LIN_FIXED_OUTPUT_QY, 30))
107116

108117
/* tracing */
109118
#define trace_dmic(__e, ...) \
@@ -152,12 +161,12 @@ static uint64_t dmic_work(void *data)
152161
tracev_dmic("dmic_work()");
153162
spin_lock(&dai->lock);
154163

155-
/* Increment gain with logaritmic step.
156-
* Gain is Q2.30 and gain modifier is Q2.14.
164+
/* Increment gain with logarithmic step.
165+
* Gain is Q2.30 and gain modifier is Q12.20.
157166
*/
158167
dmic->startcount++;
159-
dmic->gain = Q_MULTSR_32X32((int64_t)dmic->gain,
160-
LOGRAMP_GM, 30, 14, 30);
168+
dmic->gain = q_multsr_sat_32x32(dmic->gain, dmic->gain_coef,
169+
Q_SHIFT_GAIN_X_GAIN_COEF);
161170

162171
/* Gain is stored as Q2.30, while HW register is Q1.19 so shift
163172
* the value right by 11.
@@ -1034,6 +1043,8 @@ static int dmic_set_config(struct dai *dai, struct sof_ipc_dai_config *config)
10341043
struct dmic_configuration cfg;
10351044
struct decim_modes modes_a;
10361045
struct decim_modes modes_b;
1046+
int32_t unmute_ramp_time_ms;
1047+
int32_t step_db;
10371048
size_t size;
10381049
int i, j, ret = 0;
10391050
int di = dai->index;
@@ -1051,6 +1062,26 @@ static int dmic_set_config(struct dai *dai, struct sof_ipc_dai_config *config)
10511062
return -EINVAL;
10521063
}
10531064

1065+
/* Compute unmute ramp gain update coefficient. Use the value from
1066+
* topology if it is non-zero, otherwise use default length.
1067+
*/
1068+
if (config->dmic.unmute_ramp_time)
1069+
unmute_ramp_time_ms = config->dmic.unmute_ramp_time;
1070+
else
1071+
unmute_ramp_time_ms = LOGRAMP_TIME_MS;
1072+
1073+
if (unmute_ramp_time_ms < LOGRAMP_TIME_MIN_MS ||
1074+
unmute_ramp_time_ms > LOGRAMP_TIME_MAX_MS) {
1075+
trace_dmic_error("dmic_set_config(): Illegal ramp time = %d",
1076+
unmute_ramp_time_ms);
1077+
return -EINVAL;
1078+
}
1079+
1080+
step_db = LOGRAMP_CONST_TERM / unmute_ramp_time_ms;
1081+
dmic->gain_coef = db2lin_fixed(step_db);
1082+
trace_dmic("dmic_set_config(): unmute_ramp_time_ms = %d",
1083+
unmute_ramp_time_ms);
1084+
10541085
/*
10551086
* "config" might contain pdm controller params for only
10561087
* the active controllers
@@ -1197,7 +1228,9 @@ static void dmic_start(struct dai *dai)
11971228
trace_dmic("dmic_start()");
11981229
dmic->state = COMP_STATE_ACTIVE;
11991230
dmic->startcount = 0;
1200-
dmic->gain = LOGRAMP_GI; /* Initial gain value */
1231+
1232+
/* Initial gain value, convert Q12.20 to Q2.30 */
1233+
dmic->gain = Q_SHIFT_LEFT(db2lin_fixed(LOGRAMP_START_DB), 20, 30);
12011234

12021235
switch (dai->index) {
12031236
case 0:

src/include/ipc/dai-intel.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,9 +174,10 @@ struct sof_ipc_dai_dmic_params {
174174

175175
uint32_t wake_up_time; /**< Time from clock start to data (us) */
176176
uint32_t min_clock_on_time; /**< Min. time that clk is kept on (us) */
177+
uint32_t unmute_ramp_time; /**< Length of logarithmic gain ramp (ms) */
177178

178179
/* reserved for future use */
179-
uint32_t reserved[6];
180+
uint32_t reserved[5];
180181

181182
/**< variable number of pdm controller config */
182183
struct sof_ipc_dai_dmic_pdm_ctrl pdm[0];

src/include/kernel/abi.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929

3030
/** \brief SOF ABI version major, minor and patch numbers */
3131
#define SOF_ABI_MAJOR 3
32-
#define SOF_ABI_MINOR 7
32+
#define SOF_ABI_MINOR 8
3333
#define SOF_ABI_PATCH 0
3434

3535
/** \brief SOF ABI version number. Format within 32bit word is MMmmmppp */

src/include/sof/dmic.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,7 @@ struct dmic_pdata {
313313
struct task dmicwork;
314314
int32_t startcount;
315315
int32_t gain;
316+
int32_t gain_coef;
316317
};
317318

318319
extern const struct dai_driver dmic_driver;

0 commit comments

Comments
 (0)