Coverage Report

Created: 2025-11-24 06:48

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libxaac/encoder/iusace_lpc.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
21
#include <math.h>
22
#include "ixheaac_type_def.h"
23
#include "iusace_bitbuffer.h"
24
#include "iusace_cnst.h"
25
#include "iusace_tns_usac.h"
26
#include "iusace_psy_mod.h"
27
#include "iusace_block_switch_const.h"
28
#include "iusace_rom.h"
29
30
103M
static FLOAT32 iusace_lpc_eval_chebyshev_polyn(FLOAT32 x, FLOAT32 *coefs, WORD32 order) {
31
103M
  WORD32 i;
32
103M
  FLOAT32 b0, b1, b2, x2;
33
103M
  x2 = 2.0f * x;
34
103M
  b2 = 1.0f;
35
103M
  b1 = x2 + coefs[1];
36
726M
  for (i = 2; i < order; i++) {
37
622M
    b0 = x2 * b1 - b2 + coefs[i];
38
622M
    b2 = b1;
39
622M
    b1 = b0;
40
622M
  }
41
103M
  return (x * b1 - b2 + 0.5f * coefs[order]);
42
103M
}
43
44
538k
VOID iusace_lpc_2_lsp_conversion(FLOAT32 *lpc, FLOAT32 *lsp, FLOAT32 *prev_lsp) {
45
538k
  FLOAT32 sum_polyn[(ORDER_BY_2) + 1], diff_polyn[(ORDER_BY_2) + 1];
46
538k
  FLOAT32 *p1_lpc, *p2_lpc, *p_sum_polyn, *p_diff_polyn;
47
538k
  WORD32 i, j = 0, num_found_freeq = 0, is_first_polyn = 0;
48
538k
  FLOAT32 x_low, y_low, x_high, y_high, x_mid, y_mid, x_lin_interp;
49
50
538k
  p_sum_polyn = sum_polyn;
51
538k
  p_diff_polyn = diff_polyn;
52
538k
  *p_sum_polyn++ = 1.0f;
53
538k
  *p_diff_polyn++ = 1.0f;
54
538k
  sum_polyn[0] = 1.0f;
55
538k
  diff_polyn[0] = 1.0f;
56
538k
  p1_lpc = lpc + 1;
57
538k
  p2_lpc = lpc + ORDER;
58
4.84M
  for (i = 0; i <= ORDER_BY_2 - 1; i++) {
59
4.30M
    *p_sum_polyn = *p1_lpc + *p2_lpc - *(p_sum_polyn - 1);
60
4.30M
    p_sum_polyn++;
61
4.30M
    *p_diff_polyn = *p1_lpc++ - *p2_lpc-- + *(p_diff_polyn - 1);
62
4.30M
    p_diff_polyn++;
63
4.30M
  }
64
538k
  p_sum_polyn = sum_polyn;
65
538k
  x_low = iusace_chebyshev_polyn_grid[0];
66
538k
  y_low = iusace_lpc_eval_chebyshev_polyn(x_low, p_sum_polyn, ORDER_BY_2);
67
68
60.6M
  while ((num_found_freeq < ORDER) && (j < CHEBYSHEV_NUM_POINTS)) {
69
60.1M
    j++;
70
60.1M
    x_high = x_low;
71
60.1M
    y_high = y_low;
72
60.1M
    x_low = iusace_chebyshev_polyn_grid[j];
73
60.1M
    y_low = iusace_lpc_eval_chebyshev_polyn(x_low, p_sum_polyn, ORDER_BY_2);
74
75
60.1M
    if (y_low * y_high <= 0.0) /* if sign change new root exists */
76
8.61M
    {
77
8.61M
      j--;
78
43.0M
      for (i = 0; i < CHEBYSHEV_NUM_ITER; i++) {
79
34.4M
        x_mid = 0.5f * (x_low + x_high);
80
34.4M
        y_mid = iusace_lpc_eval_chebyshev_polyn(x_mid, p_sum_polyn, ORDER_BY_2);
81
34.4M
        if (y_low * y_mid <= 0.0) {
82
17.4M
          y_high = y_mid;
83
17.4M
          x_high = x_mid;
84
17.4M
        } else {
85
16.9M
          y_low = y_mid;
86
16.9M
          x_low = x_mid;
87
16.9M
        }
88
34.4M
      }
89
90
      /* linear interpolation for evaluating the root */
91
8.61M
      x_lin_interp = x_low - y_low * (x_high - x_low) / (y_high - y_low);
92
93
8.61M
      lsp[num_found_freeq] = x_lin_interp;
94
8.61M
      num_found_freeq++;
95
96
8.61M
      is_first_polyn = 1 - is_first_polyn;
97
8.61M
      p_sum_polyn = is_first_polyn ? diff_polyn : sum_polyn;
98
99
8.61M
      x_low = x_lin_interp;
100
8.61M
      y_low = iusace_lpc_eval_chebyshev_polyn(x_low, p_sum_polyn, ORDER_BY_2);
101
8.61M
    }
102
60.1M
  }
103
104
  /* Check if ORDER roots found */
105
  /* if not use the LSPs from previous frame */
106
538k
  if (num_found_freeq < ORDER) {
107
0
    for (i = 0; i < ORDER; i++) lsp[i] = prev_lsp[i];
108
0
  }
109
538k
}
110
111
7.73M
static VOID iusace_compute_coeff_poly_f(FLOAT32 *lsp, FLOAT32 *poly1, FLOAT32 *poly2) {
112
7.73M
  FLOAT32 b1, b2;
113
7.73M
  FLOAT32 *ptr_lsp;
114
7.73M
  WORD32 i, j;
115
116
7.73M
  ptr_lsp = lsp;
117
7.73M
  poly1[0] = poly2[0] = 1.0f;
118
119
69.5M
  for (i = 1; i <= ORDER_BY_2; i++) {
120
61.8M
    b1 = -2.0f * (*ptr_lsp++);
121
61.8M
    b2 = -2.0f * (*ptr_lsp++);
122
61.8M
    poly1[i] = (b1 * poly1[i - 1]) + (2.0f * poly1[i - 2]);
123
61.8M
    poly2[i] = (b2 * poly2[i - 1]) + (2.0f * poly2[i - 2]);
124
278M
    for (j = i - 1; j > 0; j--) {
125
216M
      poly1[j] += (b1 * poly1[j - 1]) + poly1[j - 2];
126
216M
      poly2[j] += (b2 * poly2[j - 1]) + poly2[j - 2];
127
216M
    }
128
61.8M
  }
129
7.73M
}
130
131
7.73M
VOID iusace_lsp_to_lp_conversion(FLOAT32 *lsp, FLOAT32 *lp_flt_coff_a) {
132
7.73M
  WORD32 i;
133
7.73M
  FLOAT32 *ppoly_f1, *ppoly_f2;
134
7.73M
  FLOAT32 *plp_flt_coff_a_bott, *plp_flt_coff_a_top;
135
7.73M
  FLOAT32 poly1[ORDER_BY_2 + 2], poly2[ORDER_BY_2 + 2];
136
137
7.73M
  poly1[0] = 0.0f;
138
7.73M
  poly2[0] = 0.0f;
139
140
7.73M
  iusace_compute_coeff_poly_f(lsp, &poly1[1], &poly2[1]);
141
142
7.73M
  ppoly_f1 = poly1 + ORDER_BY_2 + 1;
143
7.73M
  ppoly_f2 = poly2 + ORDER_BY_2 + 1;
144
145
69.5M
  for (i = 0; i < ORDER_BY_2; i++) {
146
61.8M
    ppoly_f1[0] += ppoly_f1[-1];
147
61.8M
    ppoly_f2[0] -= ppoly_f2[-1];
148
61.8M
    ppoly_f1--;
149
61.8M
    ppoly_f2--;
150
61.8M
  }
151
152
7.73M
  plp_flt_coff_a_bott = lp_flt_coff_a;
153
7.73M
  *plp_flt_coff_a_bott++ = 1.0f;
154
7.73M
  plp_flt_coff_a_top = lp_flt_coff_a + ORDER;
155
7.73M
  ppoly_f1 = poly1 + 2;
156
7.73M
  ppoly_f2 = poly2 + 2;
157
69.5M
  for (i = 0; i < ORDER_BY_2; i++) {
158
61.8M
    *plp_flt_coff_a_bott++ = 0.5f * (*ppoly_f1 + *ppoly_f2);
159
61.8M
    *plp_flt_coff_a_top-- = 0.5f * (*ppoly_f1++ - *ppoly_f2++);
160
61.8M
  }
161
7.73M
}
162
163
538k
VOID iusace_levinson_durbin_algo(FLOAT32 *auto_corr_input, FLOAT32 *lpc) {
164
538k
  WORD32 i, j;
165
538k
  FLOAT32 lpc_val, sum, sigma;
166
538k
  FLOAT32 reflection_coeffs[LEV_DUR_MAX_ORDER];
167
168
538k
  lpc[0] = 1.0f;
169
170
538k
  reflection_coeffs[0] = -auto_corr_input[1] / auto_corr_input[0];
171
538k
  lpc[1] = reflection_coeffs[0];
172
538k
  sigma = auto_corr_input[0] + auto_corr_input[1] * reflection_coeffs[0];
173
174
8.61M
  for (i = 2; i <= ORDER; i++) {
175
8.07M
    sum = 0.0f;
176
80.7M
    for (j = 0; j < i; j++) sum += auto_corr_input[i - j] * lpc[j];
177
8.07M
    reflection_coeffs[i - 1] = -sum / sigma;
178
179
8.07M
    sigma = sigma * (1.0f - reflection_coeffs[i - 1] * reflection_coeffs[i - 1]);
180
181
8.07M
    if (sigma <= 1.0E-09f) {
182
0
      for (j = i; j <= ORDER; j++) {
183
0
        reflection_coeffs[j - 1] = 0.0f;
184
0
        lpc[j] = 0.0f;
185
0
      }
186
0
      break;
187
0
    }
188
189
42.5M
    for (j = 1; j <= (i / 2); j++) {
190
34.4M
      lpc_val = lpc[j] + reflection_coeffs[i - 1] * lpc[i - j];
191
34.4M
      lpc[i - j] += reflection_coeffs[i - 1] * lpc[j];
192
34.4M
      lpc[j] = lpc_val;
193
34.4M
    }
194
195
8.07M
    lpc[i] = reflection_coeffs[i - 1];
196
8.07M
  }
197
538k
}
198
199
30.1M
VOID iusace_get_weighted_lpc(FLOAT32 *lpc, FLOAT32 *weighted_lpc) {
200
30.1M
  WORD32 i;
201
543M
  for (i = 0; i <= ORDER; i++) {
202
513M
    weighted_lpc[i] = iusace_gamma_table[i] * lpc[i];
203
513M
  }
204
30.1M
}
205
206
668k
VOID iusace_lsp_2_lsf_conversion(FLOAT32 *lsp, FLOAT32 *lsf) {
207
668k
  WORD32 i;
208
11.3M
  for (i = 0; i < ORDER; i++) {
209
10.6M
    lsf[i] = (FLOAT32)(acos(lsp[i]) * LSP_2_LSF_SCALE);
210
10.6M
  }
211
668k
}
212
213
538k
VOID iusace_lsf_2_lsp_conversion(FLOAT32 *lsf, FLOAT32 *lsp) {
214
538k
  WORD32 i;
215
9.15M
  for (i = 0; i < ORDER; i++) lsp[i] = (FLOAT32)cos((FLOAT64)lsf[i] * (FLOAT64)PI_BY_6400);
216
538k
}