xref: /aosp_15_r20/external/libxaac/decoder/ixheaacd_mps_smoothing.c (revision 15dc779a375ca8b5125643b829a8aa4b70d7f451)
1 /******************************************************************************
2  *                                                                            *
3  * Copyright (C) 2018 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************
18  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20 #include "ixheaac_type_def.h"
21 #include "ixheaacd_bitbuffer.h"
22 #include "ixheaacd_common_rom.h"
23 #include "ixheaacd_sbrdecsettings.h"
24 #include "ixheaacd_sbr_scale.h"
25 #include "ixheaacd_env_extr_part.h"
26 #include "ixheaacd_sbr_rom.h"
27 #include "ixheaacd_hybrid.h"
28 #include "ixheaacd_ps_dec.h"
29 #include "ixheaacd_config.h"
30 #include "ixheaacd_qmf_dec.h"
31 #include "ixheaacd_mps_polyphase.h"
32 #include "ixheaacd_mps_struct_def.h"
33 #include "ixheaacd_mps_res_rom.h"
34 #include "ixheaacd_mps_aac_struct.h"
35 #include "ixheaac_constants.h"
36 #include "ixheaac_basic_ops32.h"
37 #include "ixheaac_basic_ops40.h"
38 #include "ixheaacd_mps_dec.h"
39 #include "ixheaac_error_standards.h"
40 #include "ixheaacd_error_codes.h"
41 #include "ixheaacd_mps_macro_def.h"
42 #include "ixheaacd_mps_smoothing.h"
43 #include "ixheaacd_mps_tonality.h"
44 #ifndef MULT
45 #define MULT(a, b) (a * b)
46 #endif
47 #define ONE_BY_128_IN_Q30 (8388608)
48 #define ONE_IN_Q30 (1073741824)
49 #define PI_IN_Q27 (421657440)
50 #define FIFTY_X_PI_BY_180_Q27 (117127067)
51 #define TWENTY_FIVE_X_PI_BY_180_Q27 (58563533)
52 #define Q28_VALUE (1 << 28)
53 #define Q28_FLOAT_VAL ((FLOAT32)(1 << 28))
54 #define ONE_BY_Q28_FLOAT_VAL (1.0f / Q28_FLOAT_VAL)
55 
ixheaacd_mps_pre_matrix_mix_matrix_smoothing(ia_mps_dec_state_struct * self)56 VOID ixheaacd_mps_pre_matrix_mix_matrix_smoothing(
57     ia_mps_dec_state_struct *self) {
58   WORD32 smooth_band;
59   FLOAT32 delta, one_minus_delta;
60   WORD32 ps = 0, pb, row, col;
61   WORD32 res_bands = 0;
62   WORD32 *p_smoothing_data;
63 
64   if (self->residual_coding) res_bands = self->max_res_bands;
65 
66   p_smoothing_data = &self->smoothing_data[ps][res_bands];
67 
68   delta = self->param_slot_diff[ps] * self->inv_smoothing_time[ps];
69   one_minus_delta = 1.0f - delta;
70 
71   for (pb = res_bands; pb < self->bs_param_bands; pb++) {
72     smooth_band = *p_smoothing_data++;
73     if (smooth_band) {
74       for (row = 0; row < MAX_M_OUTPUT; row++) {
75         for (col = 0; col < MAX_M_INPUT; col++) {
76           self->m1_param_re[ps][pb][row][col] =
77               (MULT(delta, self->m1_param_re[ps][pb][row][col]) +
78                MULT(one_minus_delta, self->m1_param_re_prev[pb][row][col]));
79           self->m1_param_im[ps][pb][row][col] =
80               (MULT(delta, self->m1_param_im[ps][pb][row][col]) +
81                MULT(one_minus_delta, self->m1_param_im_prev[pb][row][col]));
82           self->m2_decor_re[ps][pb][row][col] =
83               (MULT(delta, self->m2_decor_re[ps][pb][row][col]) +
84                MULT(one_minus_delta, self->m2_decor_re_prev[pb][row][col]));
85           self->m2_decor_im[ps][pb][row][col] =
86               (MULT(delta, self->m2_decor_im[ps][pb][row][col]) +
87                MULT(one_minus_delta, self->m2_decor_im_prev[pb][row][col]));
88           self->m2_resid_re[ps][pb][row][col] =
89               (MULT(delta, self->m2_resid_re[ps][pb][row][col]) +
90                MULT(one_minus_delta, self->m2_resid_re_prev[pb][row][col]));
91           self->m2_resid_im[ps][pb][row][col] =
92               (MULT(delta, self->m2_resid_im[ps][pb][row][col]) +
93                MULT(one_minus_delta, self->m2_resid_im_prev[pb][row][col]));
94         }
95       }
96       self->pre_mix_req++;
97     }
98   }
99 
100   for (ps = 1; ps < self->num_parameter_sets; ps++) {
101     delta = self->param_slot_diff[ps] * self->inv_smoothing_time[ps];
102     one_minus_delta = 1.0f - delta;
103 
104     p_smoothing_data = &self->smoothing_data[ps][res_bands];
105 
106     for (pb = res_bands; pb < self->bs_param_bands; pb++) {
107       smooth_band = *p_smoothing_data++;
108       if (smooth_band) {
109         for (row = 0; row < MAX_M_OUTPUT; row++) {
110           for (col = 0; col < MAX_M_INPUT; col++) {
111             self->m1_param_re[ps][pb][row][col] =
112                 (MULT(delta, self->m1_param_re[ps][pb][row][col]) +
113                  MULT(one_minus_delta,
114                       self->m1_param_re[ps - 1][pb][row][col]));
115             self->m1_param_im[ps][pb][row][col] =
116                 (MULT(delta, self->m1_param_im[ps][pb][row][col]) +
117                  MULT(one_minus_delta,
118                       self->m1_param_im[ps - 1][pb][row][col]));
119             self->m2_resid_re[ps][pb][row][col] =
120                 (MULT(delta, self->m2_resid_re[ps][pb][row][col]) +
121                  MULT(one_minus_delta,
122                       self->m2_resid_re[ps - 1][pb][row][col]));
123             self->m2_decor_re[ps][pb][row][col] =
124                 (MULT(delta, self->m2_decor_re[ps][pb][row][col]) +
125                  MULT(one_minus_delta,
126                       self->m2_decor_re[ps - 1][pb][row][col]));
127             self->m2_decor_im[ps][pb][row][col] =
128                 (MULT(delta, self->m2_decor_im[ps][pb][row][col]) +
129                  MULT(one_minus_delta,
130                       self->m2_decor_im[ps - 1][pb][row][col]));
131             self->m2_resid_im[ps][pb][row][col] =
132                 (MULT(delta, self->m2_resid_im[ps][pb][row][col]) +
133                  MULT(one_minus_delta,
134                       self->m2_resid_im[ps - 1][pb][row][col]));
135           }
136         }
137         self->pre_mix_req++;
138       }
139     }
140   }
141 }
142 
ixheaacd_mps_smoothing_opd(ia_mps_dec_state_struct * self)143 VOID ixheaacd_mps_smoothing_opd(ia_mps_dec_state_struct *self) {
144   WORD32 ps, pb;
145   WORD32 delta, one_minus_delta;
146 
147   if (self->opd_smoothing_mode == 0) {
148     for (pb = 0; pb < self->bs_param_bands; pb++) {
149       self->opd_smooth.smooth_l_phase[pb] =
150           ((WORD32)(self->phase_l[self->num_parameter_sets - 1][pb] *
151                     Q28_VALUE)) >>
152           1;
153       self->opd_smooth.smooth_r_phase[pb] =
154           ((WORD32)(self->phase_r[self->num_parameter_sets - 1][pb] *
155                     Q28_VALUE)) >>
156           1;
157     }
158     return;
159   }
160   for (ps = 0; ps < self->num_parameter_sets; ps++) {
161     WORD32 thr = self->bs_frame.ipd_data.bs_quant_coarse_xxx[ps]
162                   ? FIFTY_X_PI_BY_180_Q27
163                   : TWENTY_FIVE_X_PI_BY_180_Q27;
164 
165     delta = self->param_slot_diff[ps] * ONE_BY_128_IN_Q30;
166     one_minus_delta = ONE_IN_Q30 - delta;
167 
168     for (pb = 0; pb < self->bs_param_bands; pb++) {
169       WORD32 ltemp, rtemp, tmp;
170       ltemp = ((WORD32)(self->phase_l[ps][pb] * Q28_FLOAT_VAL)) >> 1;
171       rtemp = ((WORD32)(self->phase_r[ps][pb] * Q28_FLOAT_VAL)) >> 1;
172 
173       while (ltemp > self->opd_smooth.smooth_l_phase[pb] + PI_IN_Q27)
174         ltemp -= 2 * PI_IN_Q27;
175       while (ltemp < self->opd_smooth.smooth_l_phase[pb] - PI_IN_Q27)
176         ltemp += 2 * PI_IN_Q27;
177       while (rtemp > self->opd_smooth.smooth_r_phase[pb] + PI_IN_Q27)
178         rtemp -= 2 * PI_IN_Q27;
179       while (rtemp < self->opd_smooth.smooth_r_phase[pb] - PI_IN_Q27)
180         rtemp += 2 * PI_IN_Q27;
181 
182       self->opd_smooth.smooth_l_phase[pb] =
183           (ixheaac_mult32_shl(delta, ltemp) +
184            ixheaac_mult32_shl(one_minus_delta,
185                                self->opd_smooth.smooth_l_phase[pb]))
186           << 1;
187       self->opd_smooth.smooth_r_phase[pb] =
188           (ixheaac_mult32_shl(delta, rtemp) +
189            ixheaac_mult32_shl(one_minus_delta,
190                                self->opd_smooth.smooth_r_phase[pb]))
191           << 1;
192 
193       tmp = (ltemp - rtemp) - (self->opd_smooth.smooth_l_phase[pb] -
194                                self->opd_smooth.smooth_r_phase[pb]);
195       while (tmp > PI_IN_Q27) tmp -= 2 * PI_IN_Q27;
196       while (tmp < -PI_IN_Q27) tmp += 2 * PI_IN_Q27;
197 
198       if (ixheaac_abs32(tmp) > thr) {
199         self->opd_smooth.smooth_l_phase[pb] = ltemp;
200         self->opd_smooth.smooth_r_phase[pb] = rtemp;
201       }
202 
203       while (self->opd_smooth.smooth_l_phase[pb] > 2 * PI_IN_Q27)
204         self->opd_smooth.smooth_l_phase[pb] -= 2 * PI_IN_Q27;
205       while (self->opd_smooth.smooth_l_phase[pb] < 0)
206         self->opd_smooth.smooth_l_phase[pb] += 2 * PI_IN_Q27;
207       while (self->opd_smooth.smooth_r_phase[pb] > 2 * PI_IN_Q27)
208         self->opd_smooth.smooth_r_phase[pb] -= 2 * PI_IN_Q27;
209       while (self->opd_smooth.smooth_r_phase[pb] < 0)
210         self->opd_smooth.smooth_r_phase[pb] += 2 * PI_IN_Q27;
211 
212       self->phase_l[ps][pb] =
213           (self->opd_smooth.smooth_l_phase[pb] << 1) * ONE_BY_Q28_FLOAT_VAL;
214       self->phase_r[ps][pb] =
215           (self->opd_smooth.smooth_r_phase[pb] << 1) * ONE_BY_Q28_FLOAT_VAL;
216     }
217   }
218 }
219 
ixheaacd_calc_filter_coeff(ia_heaac_mps_state_struct * pstr_mps_state,WORD32 ps,WORD32 * delta)220 static VOID ixheaacd_calc_filter_coeff(
221     ia_heaac_mps_state_struct *pstr_mps_state, WORD32 ps, WORD32 *delta) {
222   WORD32 d_slots;
223   WORD32 *param_slot = pstr_mps_state->aux_struct->param_slot;
224   WORD32 *smg_time = pstr_mps_state->aux_struct->smg_time;
225 
226   if (ps == 0)
227     d_slots = param_slot[ps] + 1;
228   else
229     d_slots = param_slot[ps] - param_slot[ps - 1];
230 
231   if (pstr_mps_state->smooth_control) {
232     switch (smg_time[ps]) {
233       case SMG_TIME_64:
234         *delta = d_slots << 9;
235         break;
236       case SMG_TIME_128:
237         *delta = d_slots << 8;
238         break;
239       case SMG_TIME_256:
240         *delta = d_slots << 7;
241         break;
242       case SMG_TIME_512:
243         *delta = d_slots << 6;
244         break;
245       default:
246         break;
247     }
248   } else {
249     *delta = d_slots << 7;
250   }
251 
252   return;
253 }
254 
ixheaacd_smooth_m1m2(ia_heaac_mps_state_struct * pstr_mps_state)255 VOID ixheaacd_smooth_m1m2(ia_heaac_mps_state_struct *pstr_mps_state) {
256   ia_heaac_mps_state_struct *curr_state = pstr_mps_state;
257   ia_mps_persistent_mem *persistent_mem = &curr_state->mps_persistent_mem;
258   ia_mps_dec_auxilary_struct *p_aux_struct = pstr_mps_state->aux_struct;
259   ia_mps_dec_m2_param_struct *m2_param = p_aux_struct->m2_param;
260   ia_mps_dec_m1_param_struct *m1_param = pstr_mps_state->array_struct->m1_param;
261   WORD32 *m1_param_real_prev = persistent_mem->m1_param_real_prev;
262   WORD32 *m2_decor_real_prev = persistent_mem->m2_decor_real_prev;
263   WORD32 *m2_resid_real_prev = persistent_mem->m2_resid_real_prev;
264 
265   WORD32 num_parameter_bands = curr_state->num_parameter_bands;
266   WORD32 num_direct_signals = curr_state->num_direct_signals;
267   WORD32 num_decor_signals = curr_state->num_decor_signals;
268   WORD32 m1_param_imag_present = curr_state->m1_param_imag_present;
269   WORD32 m2_param_imag_present = curr_state->m2_param_imag_present;
270   WORD32 col_counter = num_direct_signals + num_decor_signals;
271   WORD32 num_parameter_sets = curr_state->num_parameter_sets;
272   WORD32 num_output_channels = curr_state->num_output_channels;
273   WORD32 num_v_channels = curr_state->num_v_channels;
274   WORD32 num_x_channels = curr_state->num_x_channels;
275   WORD32 smooth_control = curr_state->smooth_control;
276   WORD32 smooth_config = curr_state->smooth_config;
277   WORD32 resid_col_counter;
278   WORD32 smooth_band_arr[MAX_PARAMETER_SETS][MAX_PARAMETER_BANDS];
279 
280   WORD32 *delta, *one_minus_delta, *delta_ptr, *one_minus_delta_ptr;
281   WORD32 *param_r, *param_i, *param_prev_r, *param_prev_i;
282 
283   WORD32 *ton;
284   WORD32 i, ps, pb, row, col;
285   WORD32 res_bands = 0;
286   WORD32 idx = 0;
287 
288   WORD32 *m2_decor_imag_prev = persistent_mem->m2_decor_imag_prev;
289   WORD32 *m2_resid_imag_prev = persistent_mem->m2_resid_imag_prev;
290   WORD32 *m1_param_imag_prev = persistent_mem->m1_param_imag_prev;
291 
292   ton = pstr_mps_state->mps_scratch_mem_v;
293   delta = delta_ptr =
294       ton + IXHEAAC_GET_SIZE_ALIGNED_TYPE(MAX_PARAMETER_BANDS, sizeof(*delta), BYTE_ALIGN_8);
295   one_minus_delta = one_minus_delta_ptr =
296       delta +
297       IXHEAAC_GET_SIZE_ALIGNED_TYPE(MAX_PARAMETER_SETS, sizeof(*one_minus_delta), BYTE_ALIGN_8);
298 
299   param_r = curr_state->res_bands;
300   if (curr_state->residual_coding) {
301     for (i = 0; i < MAX_RESIDUAL_CHANNELS_MPS; i++) {
302       if (param_r[i] > res_bands) {
303         res_bands = param_r[i];
304       }
305     }
306   }
307 
308   if (curr_state->arbitrary_downmix == 2) {
309     if (res_bands < curr_state->arbdmx_residual_bands) {
310       res_bands = curr_state->arbdmx_residual_bands;
311     }
312   }
313 
314   if (smooth_config) {
315     ixheaacd_measure_tonality(pstr_mps_state, ton);
316   }
317 
318   for (ps = 0; ps < num_parameter_sets; ps++) {
319     ixheaacd_calc_filter_coeff(pstr_mps_state, ps, delta);
320     *one_minus_delta++ = (1 << 15) - *delta++;
321   }
322 
323   if (smooth_control) {
324     for (ps = 0; ps < num_parameter_sets; ps++) {
325       if (ps < 8) {
326         for (pb = 0; pb < num_parameter_bands; pb++) {
327           smooth_band_arr[ps][pb] = pstr_mps_state->aux_struct->smg_data[ps][pb];
328         }
329       }
330     }
331   } else if (smooth_config) {
332     for (ps = 0; ps < num_parameter_sets; ps++) {
333       for (pb = 0; pb < num_parameter_bands; pb++) {
334         smooth_band_arr[ps][pb] = (ton[pb] > POINT_EIGHT_Q15);
335       }
336     }
337   }
338 
339   if (!(smooth_control == 0 && smooth_config == 0)) {
340     if (m1_param_imag_present) {
341       WORD32 *ptr_r1 = &m1_param->m1_param_real[0][0][0][0];
342       WORD32 *ptr_i1 = &m1_param->m1_param_imag[0][0][0][0];
343       for (row = 0; row < num_v_channels; row++) {
344         WORD32 *ptr_r2 = ptr_r1;
345         WORD32 *ptr_i2 = ptr_i1;
346         for (col = 0; col < num_x_channels; col++) {
347           param_r = ptr_r2;
348           param_i = ptr_i2;
349           m1_param_real_prev += res_bands;
350           m1_param_imag_prev += res_bands;
351 
352           for (pb = res_bands; pb < num_parameter_bands; pb++) {
353             if (smooth_band_arr[0][pb]) {
354               WORD64 acc;
355 
356               acc = (WORD64)((WORD64)param_r[pb] * (WORD64)(*delta_ptr) +
357                              (WORD64)(*m1_param_real_prev) *
358                                  (WORD64)(*one_minus_delta_ptr));
359 
360               acc >>= 15;
361 
362               param_r[pb] = (WORD32)acc;
363 
364               acc = (WORD64)((WORD64)param_i[pb] * (WORD64)(*delta_ptr) +
365                              (WORD64)(*m1_param_imag_prev) *
366                                  (WORD64)(*one_minus_delta_ptr));
367 
368               acc >>= 15;
369 
370               param_i[pb] = (WORD32)acc;
371             }
372             m1_param_real_prev++;
373             m1_param_imag_prev++;
374           }
375           param_r += MAX_PARAMETER_BANDS;
376           param_i += MAX_PARAMETER_BANDS;
377 
378           for (ps = 1; ps < num_parameter_sets; ps++) {
379             WORD32 del = delta_ptr[ps];
380             WORD32 one_minus_del = one_minus_delta_ptr[ps];
381 
382             param_prev_r = param_r - MAX_PARAMETER_BANDS;
383             param_prev_i = param_i - MAX_PARAMETER_BANDS;
384 
385             for (pb = res_bands; pb < num_parameter_bands; pb++) {
386               if (smooth_band_arr[ps][pb]) {
387                 WORD64 acc;
388 
389                 acc = (WORD64)((WORD64)param_r[pb] * (WORD64)(del) +
390                                (WORD64)param_prev_r[pb] *
391                                    (WORD64)(one_minus_del));
392 
393                 acc >>= 15;
394 
395                 param_r[pb] = (WORD32)acc;
396 
397                 acc = (WORD64)((WORD64)param_i[pb] * (WORD64)(del) +
398                                (WORD64)param_prev_i[pb] *
399                                    (WORD64)(one_minus_del));
400 
401                 acc >>= 15;
402 
403                 param_i[pb] = (WORD32)acc;
404               }
405             }
406             param_r += MAX_PARAMETER_BANDS;
407             param_i += MAX_PARAMETER_BANDS;
408           }
409           ptr_r2 += PBXPS;
410           ptr_i2 += PBXPS;
411         }
412         ptr_r1 += INCHXPBXPS;
413         ptr_i1 += INCHXPBXPS;
414       }
415     } else {
416       WORD32 *ptr1 = (WORD32 *)m1_param;
417 
418       for (row = 0; row < num_v_channels; row++) {
419         WORD32 *ptr2 = ptr1;
420 
421         for (col = 0; col < num_x_channels; col++) {
422           WORD32 *param_r = ptr2;
423 
424           WORD32 del = delta_ptr[0];
425           WORD32 one_minus_del = one_minus_delta_ptr[0];
426 
427           m1_param_real_prev += res_bands;
428 
429           for (pb = res_bands; pb < num_parameter_bands; pb++) {
430             if (smooth_band_arr[0][pb]) {
431               WORD64 acc;
432 
433               acc = (WORD64)((WORD64)(param_r[pb]) * (WORD64)(del)) +
434                     (WORD64)((WORD64)(*m1_param_real_prev) *
435                              (WORD64)(one_minus_del));
436 
437               param_r[pb] = (WORD32)(acc >> 15);
438             }
439             m1_param_real_prev++;
440           }
441           param_r += MAX_PARAMETER_BANDS;
442 
443           for (ps = 1; ps < num_parameter_sets; ps++) {
444             WORD32 del = delta_ptr[ps];
445             WORD32 one_minus_del = one_minus_delta_ptr[ps];
446 
447             param_prev_r = param_r - MAX_PARAMETER_BANDS;
448 
449             for (pb = res_bands; pb < num_parameter_bands; pb++) {
450               if (smooth_band_arr[ps][pb]) {
451                 WORD64 acc;
452 
453                 acc = (WORD64)((WORD64)(param_r[pb]) * (WORD64)del) +
454                       (WORD64)((WORD64)(param_prev_r[pb]) *
455                                (WORD64)one_minus_del);
456 
457                 param_r[pb] = (WORD32)(acc >> 15);
458               }
459             }
460             param_r += MAX_PARAMETER_BANDS;
461           }
462           ptr2 += PBXPS;
463         }
464         ptr1 += INCHXPBXPS;
465       }
466     }
467 
468     if (curr_state->residual_coding)
469       resid_col_counter = col_counter;
470     else
471       resid_col_counter = num_direct_signals;
472 
473     idx = 0;
474     if (m2_param_imag_present) {
475       WORD32 *ptr_r1 = &m2_param->m2_resid_real[0][0][0];
476       WORD32 *ptr_i1 = &m2_param->m2_resid_imag[0][0][0];
477       for (row = 0; row < num_output_channels; row++) {
478         for (col = 0; col < resid_col_counter; col++) {
479           if (curr_state->m2_param_present[row][col] & 2) {
480             WORD32 del = *delta_ptr;
481             WORD32 one_minus_del = *one_minus_delta_ptr;
482 
483             param_r = ptr_r1;
484             param_i = ptr_i1;
485 
486             m2_resid_real_prev += res_bands;
487             m2_resid_imag_prev += res_bands;
488 
489             for (pb = res_bands; pb < num_parameter_bands; pb++) {
490               if (smooth_band_arr[0][pb]) {
491                 WORD64 acc;
492                 acc = (WORD64)((WORD64)(param_r[pb]) * (WORD64)(del) +
493                                (WORD64)(*m2_resid_real_prev) *
494                                    (WORD64)(one_minus_del));
495 
496                 acc >>= 15;
497                 param_r[pb] = (WORD32)acc;
498 
499                 acc = (WORD64)((WORD64)(param_i[pb]) * (WORD64)(del) +
500                                (WORD64)(*m2_resid_imag_prev) *
501                                    (WORD64)(one_minus_del));
502 
503                 acc >>= 15;
504                 param_i[pb] = (WORD32)acc;
505               }
506 
507               m2_resid_real_prev++;
508               m2_resid_imag_prev++;
509             }
510 
511             param_r += MAX_PARAMETER_BANDS;
512             param_i += MAX_PARAMETER_BANDS;
513 
514             for (ps = 1; ps < num_parameter_sets; ps++) {
515               WORD32 del = delta_ptr[ps];
516               WORD32 one_minus_del = one_minus_delta_ptr[ps];
517 
518               param_prev_r = param_r - MAX_PARAMETER_BANDS;
519               param_prev_i = param_i - MAX_PARAMETER_BANDS;
520               for (pb = res_bands; pb < num_parameter_bands; pb++) {
521                 if (smooth_band_arr[ps][pb]) {
522                   WORD64 acc;
523                   acc = (WORD64)((WORD64)(param_r[pb]) * (WORD64)(del) +
524                                  (WORD64)(param_prev_r[pb]) *
525                                      (WORD64)(one_minus_del));
526 
527                   acc >>= 15;
528                   param_r[pb] = (WORD32)acc;
529 
530                   acc = (WORD64)((WORD64)(param_i[pb]) * (WORD64)(del) +
531                                  (WORD64)(param_prev_i[pb]) *
532                                      (WORD64)(one_minus_del));
533 
534                   acc >>= 15;
535                   param_i[pb] = (WORD32)acc;
536                 }
537               }
538               param_r += MAX_PARAMETER_BANDS;
539               param_i += MAX_PARAMETER_BANDS;
540             }
541             idx++;
542             ptr_r1 += PBXPS;
543             ptr_i1 += PBXPS;
544           }
545         }
546       }
547 
548       idx = 0;
549 
550       ptr_r1 = &m2_param->m2_resid_real[0][0][0];
551       ptr_i1 = &m2_param->m2_resid_imag[0][0][0];
552       for (row = 0; row < num_output_channels; row++) {
553         for (col = num_direct_signals; col < col_counter; col++) {
554           if (curr_state->m2_param_present[row][col] & 1) {
555             WORD32 del = *delta_ptr;
556             WORD32 one_minus_del = *one_minus_delta_ptr;
557             m2_decor_real_prev += res_bands;
558             m2_decor_imag_prev += res_bands;
559 
560             param_r = ptr_r1;
561             param_i = ptr_i1;
562 
563             for (pb = res_bands; pb < num_parameter_bands; pb++) {
564               if (smooth_band_arr[0][pb]) {
565                 WORD64 acc;
566                 acc = (WORD64)((WORD64)(param_r[pb]) * (WORD64)del +
567                                (WORD64)(*m2_decor_real_prev) *
568                                    (WORD64)one_minus_del);
569                 acc >>= 15;
570                 param_r[pb] = (WORD32)acc;
571 
572                 acc = (WORD64)((WORD64)(param_i[pb]) * (WORD64)del +
573                                (WORD64)(*m2_decor_imag_prev) *
574                                    (WORD64)one_minus_del);
575                 acc >>= 15;
576                 param_i[pb] = (WORD32)acc;
577               }
578               m2_decor_real_prev++;
579               m2_decor_imag_prev++;
580             }
581 
582             param_r += MAX_PARAMETER_BANDS;
583             param_i += MAX_PARAMETER_BANDS;
584 
585             for (ps = 1; ps < num_parameter_sets; ps++) {
586               WORD32 del = delta_ptr[ps];
587               WORD32 one_minus_del = one_minus_delta_ptr[ps];
588               param_prev_r = param_r - MAX_PARAMETER_BANDS;
589               param_prev_i = param_i - MAX_PARAMETER_BANDS;
590               for (pb = res_bands; pb < num_parameter_bands; pb++) {
591                 if (smooth_band_arr[ps][pb]) {
592                   WORD64 acc;
593 
594                   acc = (WORD64)((WORD64)(param_r[pb]) * (WORD64)del +
595                                  (WORD64)(param_prev_r[pb]) *
596                                      (WORD64)one_minus_del);
597                   acc >>= 15;
598                   param_r[pb] = (WORD32)acc;
599 
600                   acc = (WORD64)((WORD64)(param_i[pb]) * (WORD64)del +
601                                  (WORD64)(param_prev_i[pb]) *
602                                      (WORD64)one_minus_del);
603                   acc >>= 15;
604                   param_i[pb] = (WORD32)acc;
605                 }
606               }
607               param_r += MAX_PARAMETER_BANDS;
608               param_i += MAX_PARAMETER_BANDS;
609             }
610 
611             idx++;
612             ptr_r1 += PBXPS;
613             ptr_i1 += PBXPS;
614           }
615         }
616       }
617     } else {
618       WORD32 *ptr1 = &m2_param->m2_resid_real[0][0][0];
619 
620       for (row = 0; row < num_output_channels; row++) {
621         for (col = 0; col < resid_col_counter; col++) {
622           if (curr_state->m2_param_present[row][col] & 2) {
623             WORD32 *ptr2 = ptr1;
624             WORD32 del = *delta_ptr;
625             WORD32 one_minus_del = *one_minus_delta_ptr;
626             m2_resid_real_prev += res_bands;
627 
628             for (pb = res_bands; pb < num_parameter_bands; pb++) {
629               if (smooth_band_arr[0][pb]) {
630                 WORD64 acc;
631 
632                 acc = (WORD64)((WORD64)(ptr2[pb]) * (WORD64)(del) +
633                                (WORD64)(*m2_resid_real_prev) *
634                                    (WORD64)(one_minus_del));
635 
636                 acc >>= 15;
637                 ptr2[pb] = (WORD32)acc;
638               }
639 
640               m2_resid_real_prev++;
641             }
642 
643             ptr2 += MAX_PARAMETER_BANDS;
644 
645             for (ps = 1; ps < num_parameter_sets; ps++) {
646               WORD32 del = delta_ptr[ps];
647               WORD32 one_minus_del = one_minus_delta_ptr[ps];
648 
649               param_prev_r = ptr2 - MAX_PARAMETER_BANDS;
650 
651               for (pb = res_bands; pb < num_parameter_bands; pb++) {
652                 if (smooth_band_arr[ps][pb]) {
653                   WORD64 acc;
654 
655                   acc = (WORD64)((WORD64)(ptr2[pb]) * (WORD64)(del) +
656                                  (WORD64)(*param_prev_r) *
657                                      (WORD64)(one_minus_del));
658 
659                   acc >>= 15;
660                   ptr2[pb] = (WORD32)acc;
661                 }
662 
663                 param_prev_r++;
664               }
665               ptr2 += MAX_PARAMETER_BANDS;
666             }
667             idx++;
668             ptr1 += PBXPS;
669           }
670         }
671       }
672       idx = 0;
673       ptr1 = &m2_param->m2_decor_real[0][0][0];
674 
675       for (row = 0; row < num_output_channels; row++) {
676         for (col = num_direct_signals; col < col_counter; col++) {
677           if (curr_state->m2_param_present[row][col] & 1) {
678             WORD32 *ptr2 = ptr1;
679             m2_decor_real_prev += res_bands;
680 
681             param_r = &m2_param->m2_decor_real[idx][0][res_bands];
682             for (pb = res_bands; pb < num_parameter_bands; pb++) {
683               if (smooth_band_arr[0][pb]) {
684                 WORD64 acc;
685                 acc = (WORD64)((WORD64)(ptr2[pb]) * (WORD64)*delta_ptr +
686                                (WORD64)(*m2_decor_real_prev) *
687                                    (WORD64)*one_minus_delta_ptr);
688                 acc >>= 15;
689                 ptr2[pb] = (WORD32)acc;
690               }
691               m2_decor_real_prev++;
692             }
693             ptr2 += MAX_PARAMETER_BANDS;
694 
695             for (ps = 1; ps < num_parameter_sets; ps++) {
696               WORD32 del = delta_ptr[ps];
697               WORD32 one_minus_del = one_minus_delta_ptr[ps];
698 
699               param_prev_r = ptr2 - MAX_PARAMETER_BANDS;
700               for (pb = res_bands; pb < num_parameter_bands; pb++) {
701                 if (smooth_band_arr[ps][pb]) {
702                   WORD64 acc;
703 
704                   acc =
705                       (WORD64)((WORD64)(ptr2[pb]) * (WORD64)del +
706                                (WORD64)(*param_prev_r) * (WORD64)one_minus_del);
707                   acc >>= 15;
708                   ptr2[pb] = (WORD32)acc;
709                 }
710 
711                 param_prev_r++;
712               }
713 
714               ptr2 += MAX_PARAMETER_BANDS;
715             }
716 
717             idx++;
718 
719             ptr1 += PBXPS;
720           }
721         }
722       }
723     }
724   }
725   return;
726 }
727