Coverage Report

Created: 2025-09-17 07:02

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libxaac/decoder/ixheaacd_mps_tonality.c
Line
Count
Source
1
/******************************************************************************
2
 *
3
 * Copyright (C) 2023 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 <string.h>
21
#include "ixheaac_type_def.h"
22
#include "ixheaacd_mps_struct_def.h"
23
#include "ixheaacd_mps_res_rom.h"
24
#include "ixheaacd_mps_aac_struct.h"
25
#include "ixheaac_constants.h"
26
#include "ixheaac_basic_ops32.h"
27
#include "ixheaac_basic_ops40.h"
28
#include "ixheaacd_bitbuffer.h"
29
#include "ixheaacd_error_codes.h"
30
#include "ixheaacd_common_rom.h"
31
#include "ixheaacd_sbrdecsettings.h"
32
#include "ixheaacd_sbr_scale.h"
33
#include "ixheaacd_env_extr_part.h"
34
#include "ixheaacd_sbr_rom.h"
35
#include "ixheaacd_lpp_tran.h"
36
#include "ixheaacd_hybrid.h"
37
#include "ixheaacd_ps_dec.h"
38
#include "ixheaacd_env_extr.h"
39
#include "ixheaacd_mps_polyphase.h"
40
#include "ixheaacd_config.h"
41
#include "ixheaacd_qmf_dec.h"
42
#include "ixheaacd_mps_dec.h"
43
#include "ixheaacd_mps_bitdec.h"
44
#include "ixheaacd_mps_macro_def.h"
45
#include "ixheaacd_mps_basic_op.h"
46
47
0
VOID ixheaacd_init_tonality(ia_heaac_mps_state_struct *pstr_mps_state) {
48
0
  ia_mps_dec_tonality_state_struct *ton_state = pstr_mps_state->mps_persistent_mem.ton_state;
49
0
  WORD32 cnt = pstr_mps_state->qmf_bands * 8;
50
0
  WORD32 qmf_bands = pstr_mps_state->qmf_bands;
51
52
0
  memset(ton_state->spec_prev_real, 0, cnt * sizeof(ton_state->spec_prev_real[0]));
53
0
  memset(ton_state->spec_prev_imag, 0, cnt * sizeof(ton_state->spec_prev_imag[0]));
54
0
  memset(ton_state->p_cross_real, 0, cnt * sizeof(ton_state->p_cross_real[0]));
55
0
  memset(ton_state->p_cross_imag, 0, cnt * sizeof(ton_state->p_cross_imag[0]));
56
0
  memset(ton_state->p_sum, 0, cnt * sizeof(ton_state->p_sum[0]));
57
0
  memset(ton_state->p_sum_prev, 0, cnt * sizeof(ton_state->p_sum_prev[0]));
58
59
0
  memset(ton_state->buf_real, 0, qmf_bands * 6 * sizeof(ton_state->buf_real[0][0]));
60
0
  memset(ton_state->buf_imag, 0, qmf_bands * 6 * sizeof(ton_state->buf_imag[0][0]));
61
0
  memset(ton_state->win_buf_real, 0, qmf_bands * 16 * sizeof(ton_state->win_buf_real[0][0]));
62
0
  memset(ton_state->win_buf_imag, 0, qmf_bands * 16 * sizeof(ton_state->win_buf_imag[0][0]));
63
0
}
64
65
VOID ixheaacd_zoom_fft16(WORD32 *in_real, WORD32 *in_imag, WORD32 *out_real, WORD32 *out_imag,
66
                         WORD32 qmf_band, WORD32 dfrac,
67
0
                         ia_mps_dec_mps_tables_struct *ia_mps_dec_mps_table_ptr) {
68
0
  WORD32 blackman[16];
69
70
0
  WORD32 v_real[16], v_imag[16];
71
0
  WORD32 t_real, t_imag;
72
0
  WORD32 e_real, e_imag;
73
74
0
  WORD32 temp_1, temp_2, temp3, temp4;
75
0
  const WORD32 *bitrev = ia_mps_dec_mps_table_ptr->tonality_table_ptr->bitrev;
76
0
  const WORD32 *w_real = ia_mps_dec_mps_table_ptr->tonality_table_ptr->w_real;
77
0
  const WORD32 *w_imag = ia_mps_dec_mps_table_ptr->tonality_table_ptr->w_imag;
78
0
  const WORD32 *cos_tab = ia_mps_dec_mps_table_ptr->hybrid_table_ptr->cosine_array;
79
0
  const WORD32 *sin_tab = ia_mps_dec_mps_table_ptr->hybrid_table_ptr->sine_array;
80
81
0
  WORD32 i, j, s1, s2;
82
83
0
  temp3 = TWO_PI_BY_FIFTEEN_Q15;
84
85
0
  for (i = 0; i < 16; i++) {
86
0
    temp_1 = (i << 15) + dfrac;
87
0
    temp_2 = ixheaacd_mps_mult32_shr_15(temp_1, temp3);
88
0
    temp_2 = ixheaacd_mps_cos(temp_2, cos_tab);
89
0
    temp_2 >>= 1;
90
91
0
    temp_1 <<= 1;
92
0
    temp_1 = ixheaacd_mps_cos(temp_1, cos_tab);
93
94
0
    temp_1 = ixheaacd_mps_mult32x16_shr_16(temp_1, TWO_BY_TWENTYFIVE_Q16);
95
96
0
    temp4 = POINT_FOUR_TWO_Q15 - temp_2;
97
98
0
    blackman[i] = temp_1 + temp4;
99
0
  }
100
101
0
  for (i = 0; i < 16; i++) {
102
0
    WORD32 idx = bitrev[i];
103
0
    temp_1 = ixheaacd_mps_mult32_shr_30(in_real[i], w_real[i]) -
104
0
             ixheaacd_mps_mult32_shr_30(in_imag[i], w_imag[i]);
105
0
    v_real[idx] = ixheaacd_mps_mult32_shr_30(temp_1, blackman[i]);
106
107
0
    temp_1 = ixheaacd_mps_mult32_shr_30(in_real[i], w_imag[i]) +
108
0
             ixheaacd_mps_mult32_shr_30(in_imag[i], w_real[i]);
109
0
    v_imag[idx] = ixheaacd_mps_mult32_shr_30(temp_1, blackman[i]);
110
0
  }
111
112
0
  for (s1 = 1, s2 = 16; s1 < 8; s1 <<= 1, s2 >>= 1) {
113
0
    for (i = 0; i < 16; i += 2 * s1) {
114
0
      for (j = 0; j < s1; j++) {
115
0
        t_real = ixheaacd_mps_mult32_shr_30(v_real[i + j + s1], w_real[j * s2]) -
116
0
                 ixheaacd_mps_mult32_shr_30(v_imag[i + j + s1], w_imag[j * s2]);
117
0
        t_imag = ixheaacd_mps_mult32_shr_30(v_real[i + j + s1], w_imag[j * s2]) +
118
0
                 ixheaacd_mps_mult32_shr_30(v_imag[i + j + s1], w_real[j * s2]);
119
120
0
        v_real[i + j + s1] = v_real[i + j] - t_real;
121
0
        v_imag[i + j + s1] = v_imag[i + j] - t_imag;
122
123
0
        v_real[i + j] += t_real;
124
0
        v_imag[i + j] += t_imag;
125
0
      }
126
0
    }
127
0
  }
128
129
0
  for (j = 0; j < 8; j++) {
130
0
    WORD32 idx = j << 1;
131
0
    t_real = ixheaacd_mps_mult32_shr_30(v_real[j + 8], w_real[idx]) -
132
0
             ixheaacd_mps_mult32_shr_30(v_imag[j + 8], w_imag[idx]);
133
0
    t_imag = ixheaacd_mps_mult32_shr_30(v_real[j + 8], w_imag[idx]) +
134
0
             ixheaacd_mps_mult32_shr_30(v_imag[j + 8], w_real[idx]);
135
136
0
    if ((qmf_band & ONE_BIT_MASK) == 0) {
137
0
      out_real[j] = v_real[j] + t_real;
138
0
      out_imag[j] = v_imag[j] + t_imag;
139
0
    } else {
140
0
      out_real[j] = v_real[j] - t_real;
141
0
      out_imag[j] = v_imag[j] - t_imag;
142
0
    }
143
0
  }
144
145
0
  temp3 = MINUS_PI_BY_EIGHT_Q15;
146
0
  for (i = 0; i < 8; i++) {
147
0
    if ((qmf_band & ONE_BIT_MASK) == 0) {
148
0
      temp_1 = dfrac * i;
149
0
      temp_1 = ixheaacd_mps_mult32_shr_15(temp_1, temp3);
150
0
      e_real = ixheaacd_mps_cos(temp_1, cos_tab);
151
0
      e_imag = ixheaacd_mps_sin(temp_1, sin_tab);
152
0
    } else {
153
0
      temp_1 = dfrac * (i - 8);
154
0
      temp_1 = ixheaacd_mps_mult32_shr_15(temp_1, temp3);
155
0
      e_real = ixheaacd_mps_cos(temp_1, cos_tab);
156
0
      e_imag = ixheaacd_mps_sin(temp_1, sin_tab);
157
0
    }
158
159
0
    t_real = ixheaacd_mps_mult32_shr_15(out_real[i], e_real) -
160
0
             ixheaacd_mps_mult32_shr_15(out_imag[i], e_imag);
161
0
    out_imag[i] = ixheaacd_mps_mult32_shr_15(out_real[i], e_imag) +
162
0
                  ixheaacd_mps_mult32_shr_15(out_imag[i], e_real);
163
0
    out_real[i] = t_real;
164
0
  }
165
0
}
166
167
0
VOID ixheaacd_measure_tonality(ia_heaac_mps_state_struct *pstr_mps_state, WORD32 *tonality) {
168
0
  ia_mps_dec_tonality_state_struct *ton_state = pstr_mps_state->mps_persistent_mem.ton_state;
169
170
0
  WORD32 *qmf_real;
171
0
  WORD32 *qmf_imag;
172
173
0
  WORD32 *spec_zoom_real;
174
0
  WORD32 *spec_zoom_imag;
175
176
0
  WORD32 *spec_prev_real = ton_state->spec_prev_real;
177
0
  WORD32 *spec_prev_imag = ton_state->spec_prev_imag;
178
179
0
  WORD32 *p_cross_real = ton_state->p_cross_real;
180
0
  WORD32 *p_cross_imag = ton_state->p_cross_imag;
181
182
0
  WORD32 *p_sum = ton_state->p_sum;
183
0
  WORD32 *p_sum_prev = ton_state->p_sum_prev;
184
185
0
  WORD32 *p_max;
186
187
0
  WORD32 *coh_spec;
188
0
  WORD32 *pow_spec;
189
190
0
  WORD32 *p_buf_real, *p_buf_imag, *p_buf_re, *p_buf_im;
191
0
  WORD32 *buf_real, *buf_imag;
192
0
  WORD32 g, gmax;
193
0
  WORD32 i, j, q, s, c, cnt;
194
195
0
  WORD32 const *part;
196
0
  WORD32 pstart;
197
0
  WORD32 pstop = 0;
198
0
  WORD32 pqmf, num, den, tmp_ton, beta, dwin, dfrac;
199
0
  WORD16 q_beta, q_tmp_ton;
200
201
0
  WORD32 qmf_bands = pstr_mps_state->qmf_bands;
202
0
  WORD32 time_slots = pstr_mps_state->time_slots;
203
0
  WORD32 num_input_channels = pstr_mps_state->num_input_channels;
204
0
  WORD32 num_parameter_bands = pstr_mps_state->num_parameter_bands;
205
0
  WORD32 sampling_freq = pstr_mps_state->sampling_freq;
206
0
  const WORD32 *sqrt_tab = pstr_mps_state->ia_mps_dec_mps_table.common_table_ptr->sqrt_tab;
207
208
0
  WORD32 nstart;
209
210
0
  WORD32 tmp_real, tmp_imag;
211
212
0
  WORD32 temp_1, temp;
213
0
  WORD16 qtemp1, qtemp2;
214
215
0
  spec_zoom_real = (WORD32 *)((WORD8 *)pstr_mps_state->mps_scratch_mem_v +
216
0
                              IXHEAAC_GET_SIZE_ALIGNED(SCRATCH_OFFSET_SMOOTHING, BYTE_ALIGN_8));
217
0
  spec_zoom_imag = spec_zoom_real + IXHEAAC_GET_SIZE_ALIGNED_TYPE(
218
0
                                        QMF_BANDSX8, sizeof(*spec_zoom_imag), BYTE_ALIGN_8);
219
0
  p_max =
220
0
      spec_zoom_imag + IXHEAAC_GET_SIZE_ALIGNED_TYPE(QMF_BANDSX8, sizeof(*p_max), BYTE_ALIGN_8);
221
0
  coh_spec = p_max + IXHEAAC_GET_SIZE_ALIGNED_TYPE(QMF_BANDSX8, sizeof(*coh_spec), BYTE_ALIGN_8);
222
0
  pow_spec =
223
0
      coh_spec + IXHEAAC_GET_SIZE_ALIGNED_TYPE(QMF_BANDSX8, sizeof(*pow_spec), BYTE_ALIGN_8);
224
225
0
  qmf_real =
226
0
      pow_spec + IXHEAAC_GET_SIZE_ALIGNED_TYPE(QMF_BANDSX8, sizeof(*qmf_real), BYTE_ALIGN_8);
227
0
  qmf_imag = qmf_real + IXHEAAC_GET_SIZE_ALIGNED_TYPE(QBXTS, sizeof(*qmf_imag), BYTE_ALIGN_8);
228
229
0
  switch (num_parameter_bands) {
230
0
    case PARAMETER_BANDS_4:
231
0
      part = pstr_mps_state->ia_mps_dec_mps_table.tonality_table_ptr->part4;
232
0
      break;
233
0
    case PARAMETER_BANDS_5:
234
0
      part = pstr_mps_state->ia_mps_dec_mps_table.tonality_table_ptr->part5;
235
0
      break;
236
0
    case PARAMETER_BANDS_7:
237
0
      part = pstr_mps_state->ia_mps_dec_mps_table.tonality_table_ptr->part7;
238
0
      break;
239
0
    case PARAMETER_BANDS_10:
240
0
      part = pstr_mps_state->ia_mps_dec_mps_table.tonality_table_ptr->part10;
241
0
      break;
242
0
    case PARAMETER_BANDS_14:
243
0
      part = pstr_mps_state->ia_mps_dec_mps_table.tonality_table_ptr->part14;
244
0
      break;
245
0
    case PARAMETER_BANDS_20:
246
0
      part = pstr_mps_state->ia_mps_dec_mps_table.tonality_table_ptr->part20;
247
0
      break;
248
0
    case PARAMETER_BANDS_28:
249
0
      part = pstr_mps_state->ia_mps_dec_mps_table.tonality_table_ptr->part28;
250
0
      break;
251
0
    case PARAMETER_BANDS_40:
252
0
      part = pstr_mps_state->ia_mps_dec_mps_table.tonality_table_ptr->part40;
253
0
      break;
254
0
    default:
255
0
      part = pstr_mps_state->ia_mps_dec_mps_table.tonality_table_ptr->part4;
256
0
      break;
257
0
  }
258
259
0
  temp = time_slots - 6;
260
261
0
  p_buf_real = pstr_mps_state->array_struct->buf_real;
262
0
  p_buf_imag = pstr_mps_state->array_struct->buf_imag;
263
264
0
  for (q = 0; q < qmf_bands; q++) {
265
0
    qmf_real += 6;
266
0
    qmf_imag += 6;
267
268
0
    p_buf_re = p_buf_real;
269
0
    p_buf_im = p_buf_imag;
270
0
    for (s = 0; s < time_slots; s++) {
271
0
      tmp_real = 0;
272
0
      tmp_imag = 0;
273
274
0
      buf_real = p_buf_re;
275
0
      buf_imag = p_buf_im;
276
277
0
      for (c = 0; c < num_input_channels; c++) {
278
0
        tmp_real += *buf_real;
279
0
        tmp_imag += *buf_imag;
280
281
0
        buf_real += TSXHB;
282
0
        buf_imag += TSXHB;
283
0
      }
284
285
0
      if (s == temp) {
286
0
        qmf_real -= time_slots;
287
0
        qmf_imag -= time_slots;
288
0
      }
289
290
0
      if (s + 6 < time_slots) {
291
0
        *qmf_real++ = tmp_real;
292
0
        *qmf_imag++ = tmp_imag;
293
0
      } else {
294
0
        *qmf_real++ = ton_state->buf_real[q][s + 6 - time_slots];
295
0
        *qmf_imag++ = ton_state->buf_imag[q][s + 6 - time_slots];
296
297
0
        ton_state->buf_real[q][s + 6 - time_slots] = tmp_real;
298
0
        ton_state->buf_imag[q][s + 6 - time_slots] = tmp_imag;
299
0
      }
300
0
      p_buf_re += MAX_HYBRID_BANDS;
301
0
      p_buf_re += MAX_HYBRID_BANDS;
302
0
    }
303
0
    qmf_real += temp;
304
0
    qmf_imag += temp;
305
306
0
    p_buf_real++;
307
0
    p_buf_imag++;
308
0
  }
309
310
0
  gmax = pstr_mps_state->ia_mps_dec_mps_table.tonality_table_ptr->gmax_fix[time_slots];
311
0
  dwin = pstr_mps_state->ia_mps_dec_mps_table.tonality_table_ptr->dwin_fix[time_slots];
312
313
0
  qtemp1 = 15;
314
0
  temp_1 = ixheaacd_mps_mult32(dwin, (40 * (qmf_bands)), &qtemp1, 0);
315
0
  beta = ixheaacd_mps_div_32(temp_1, sampling_freq, &q_beta);
316
0
  q_beta = q_beta + qtemp1;
317
0
  beta = ixheaacd_mps_convert_to_qn(beta, q_beta, 15);
318
319
0
  for (i = 0; i < num_parameter_bands; i++) {
320
0
    tonality[i] = ONE_IN_Q15;
321
0
  }
322
323
0
  for (g = 0; g < gmax; g++) {
324
0
    nstart = pstr_mps_state->ia_mps_dec_mps_table.tonality_table_ptr->nstart_fix[g][time_slots];
325
0
    if (time_slots <= 16)
326
0
      dfrac = 0;
327
0
    else
328
0
      dfrac =
329
0
          pstr_mps_state->ia_mps_dec_mps_table.tonality_table_ptr->dfrac_fix[g][time_slots - 16];
330
331
0
    qmf_real = pow_spec + QBX48;
332
0
    qmf_imag = qmf_real + QMF_BANDSXTSX6;
333
0
    for (q = 0; q < qmf_bands; q++) {
334
0
      for (i = 0; i < 16; i++) {
335
0
        if (nstart + i < 0) {
336
0
          ton_state->win_buf_real[q][i] = ton_state->win_buf_real[q][16 + nstart + i];
337
0
          ton_state->win_buf_imag[q][i] = ton_state->win_buf_imag[q][16 + nstart + i];
338
0
        } else {
339
0
          ton_state->win_buf_real[q][i] = qmf_real[nstart + i];
340
0
          ton_state->win_buf_imag[q][i] = qmf_imag[nstart + i];
341
0
        }
342
0
      }
343
0
      qmf_real += time_slots;
344
0
      qmf_imag += time_slots;
345
0
    }
346
347
0
    for (q = 0; q < qmf_bands; q++) {
348
0
      ixheaacd_zoom_fft16(&(ton_state->win_buf_real[q][0]), &(ton_state->win_buf_imag[q][0]),
349
0
                          &(spec_zoom_real[q * 8]), &(spec_zoom_imag[q * 8]), q, dfrac,
350
0
                          &(pstr_mps_state->ia_mps_dec_mps_table));
351
0
    }
352
353
0
    cnt = 8 * qmf_bands;
354
0
    for (i = 0; i < cnt; i++) {
355
0
      WORD64 temp;
356
0
      WORD32 one_minus_beta = ONE_IN_Q15 - beta;
357
0
      WORD32 x = *spec_zoom_real;
358
0
      WORD32 y = *spec_zoom_imag;
359
360
0
      temp = x * spec_prev_real[i] + y * spec_prev_imag[i];
361
0
      temp_1 = (WORD32)(temp >> 10);
362
0
      temp_1 = ixheaacd_mps_mult32_shr_15(temp_1, beta);
363
364
0
      p_cross_real[i] = ixheaacd_mps_mult32_shr_15(p_cross_real[i], one_minus_beta);
365
0
      p_cross_real[i] += temp_1;
366
367
0
      temp = y * spec_prev_real[i] - x * spec_prev_imag[i];
368
0
      temp_1 = (WORD32)(temp >> 10);
369
0
      temp_1 = ixheaacd_mps_mult32_shr_15(temp_1, beta);
370
371
0
      p_cross_imag[i] = ixheaacd_mps_mult32_shr_15(p_cross_imag[i], one_minus_beta);
372
0
      p_cross_imag[i] += temp_1;
373
374
0
      temp = x * x + y * y;
375
0
      temp_1 = (WORD32)(temp >> 10);
376
0
      temp_1 = ixheaacd_mps_mult32_shr_15(temp_1, beta);
377
378
0
      p_sum[i] = ixheaacd_mps_mult32_shr_15(p_sum[i], one_minus_beta);
379
0
      p_sum[i] += temp_1;
380
381
0
      *p_max = (p_sum[i] > p_sum_prev[i]) ? p_sum[i] : p_sum_prev[i];
382
383
0
      p_sum_prev[i] = p_sum[i];
384
385
0
      temp = p_cross_real[i] * p_cross_real[i] + p_cross_imag[i] * p_cross_imag[i];
386
0
      temp_1 = (WORD32)(temp >> 10);
387
0
      qtemp1 = 10;
388
0
      temp_1 = ixheaacd_mps_sqrt(temp_1, &qtemp1, sqrt_tab);
389
0
      *coh_spec = ixheaacd_mps_div_32(temp_1, *p_max++, &qtemp2);
390
0
      qtemp2 = qtemp2 + qtemp1 - 10;
391
0
      *coh_spec = ixheaacd_mps_convert_to_qn(*coh_spec, qtemp2, 10);
392
0
      coh_spec++;
393
394
0
      temp = x * x + y * y + spec_prev_real[i] * spec_prev_real[i] +
395
0
             spec_prev_imag[i] * spec_prev_imag[i];
396
0
      *pow_spec = (WORD32)(temp >> 10);
397
398
0
      spec_prev_real[i] = *spec_zoom_real++;
399
0
      spec_prev_imag[i] = *spec_zoom_imag++;
400
0
    }
401
0
    spec_zoom_real -= i;
402
0
    spec_zoom_imag -= i;
403
0
    p_max -= i;
404
0
    coh_spec -= i;
405
0
    pow_spec -= i;
406
407
0
    pstart = 0;
408
0
    pqmf = 0;
409
0
    for (i = 0; i < num_parameter_bands; i++) {
410
0
      pqmf += part[i];
411
0
      pstop = ((pqmf << 3) + ONE_IN_Q14) >> 15;
412
413
0
      num = 0;
414
0
      den = 0;
415
0
      for (j = pstart; j < pstop; j++) {
416
0
        num += ixheaacd_mps_mult32_shr_n(*pow_spec, *coh_spec, 10);
417
0
        coh_spec++;
418
0
        den += *pow_spec++;
419
0
      }
420
421
0
      tmp_ton = ixheaacd_mps_div_32(num, den, &q_tmp_ton);
422
0
      ixheaacd_mps_convert_to_qn(tmp_ton, q_tmp_ton, 15);
423
424
0
      if (tmp_ton > 32767) {
425
0
        tmp_ton = 32767;
426
0
      }
427
428
0
      if (tmp_ton < tonality[i]) tonality[i] = tmp_ton;
429
430
0
      pstart = pstop;
431
0
    }
432
0
    coh_spec -= pstop;
433
0
    pow_spec -= pstop;
434
0
  }
435
0
  return;
436
0
}