On 30.04.2018 23:22, Pierre-Louis Bossart wrote:
+/* Calculate scale and shift to use for FIR coefficients. Scale is applied
- before write to HW coef RAM. Shift will be programmed to HW
register.
- */
+static int fir_coef_scale(int32_t *fir_scale, int *fir_shift, int add_shift, + const int32_t coef[], int coef_length, int32_t gain) +{ + int32_t amax; + int32_t new_amax; + int32_t new_scale; + int32_t fir_gain; + int shift; + const int32_t coef_max_val = Q_CONVERT_FLOAT(0.9999, 20); /* Q1.20 */
+ /* Multiply gain passed from CIC with output full scale, result Q4.20 */ + fir_gain = Q_MULTSR_32X32((int64_t)gain, DMIC_HW_SENS_Q23, 20, 23, 20);
+ /* Find the largest FIR coefficient value */ + amax = find_max_abs_int32((int32_t *)coef, coef_length);
+ /* Scale with FIR gain */ + new_amax = Q_MULTSR_32X32((int64_t)amax, fir_gain, 31, 20, 20); + if (new_amax <= 0) + return -EINVAL;
+ /* Needed scale for FIR taps, target is 0.9999 max */ + new_scale = (int32_t)((((int64_t)coef_max_val << 20)) / new_amax);
+ /* Find shift value */ + if (new_scale == 0) + return -EINVAL;
+ shift = 0; + while ((new_scale << shift) < (1 << 20)) + shift++;
don't we have some sort of macro for this (find number of leading zeroes)?
I rewrote this function partially since I noticed I can do the same without the division. The shift value can be calculated from the newly made norm_int32(new_amax) function output.
The other larger change is that I updated the modes search struct to use int16_t arrays to save RAM.
It took me some time to test these but I'll email shortly the new RFC patch set!
Thanks, Seppo