Coverage Report

Created: 2025-12-10 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libxaac/encoder/ixheaace_mps_frame_windowing.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 <stdlib.h>
22
#include <string.h>
23
#include "ixheaac_type_def.h"
24
#include "ixheaac_error_standards.h"
25
#include "ixheaace_error_codes.h"
26
#include "ixheaace_mps_common_fix.h"
27
#include "ixheaace_mps_defines.h"
28
29
#include "ixheaace_mps_common_define.h"
30
#include "ixheaace_mps_bitstream.h"
31
#include "ixheaace_mps_frame_windowing.h"
32
33
static IA_ERRORCODE ixheaace_mps_212_frame_window_list_limit(
34
    ixheaace_mps_pstr_frame_win_list const pstr_frame_win_list, const WORD32 lower_limit,
35
0
    const WORD32 upper_limit) {
36
0
  IA_ERRORCODE error = IA_NO_ERROR;
37
0
  WORD32 list_cnt = 0;
38
0
  for (list_cnt = 0; list_cnt < pstr_frame_win_list->win_list_cnt; list_cnt++) {
39
0
    if (pstr_frame_win_list->dat[list_cnt].slot < lower_limit ||
40
0
        pstr_frame_win_list->dat[list_cnt].slot > upper_limit) {
41
0
      if (list_cnt == MAX_NUM_PARAMS - 1) {
42
0
        pstr_frame_win_list->dat[list_cnt].hold = IXHEAACE_MPS_FRAME_WINDOWING_INTP;
43
0
        pstr_frame_win_list->dat[list_cnt].slot = -1;
44
0
      } else {
45
0
        WORD32 param = 0;
46
0
        for (param = list_cnt; param < MAX_NUM_PARAMS - 1; param++) {
47
0
          pstr_frame_win_list->dat[param] = pstr_frame_win_list->dat[param + 1];
48
0
        }
49
0
      }
50
51
0
      pstr_frame_win_list->win_list_cnt--;
52
0
      --list_cnt;
53
0
    }
54
0
  }
55
0
  return error;
56
0
}
57
58
static IA_ERRORCODE ixheaace_mps_212_frame_window_list_add(
59
    ixheaace_mps_pstr_frame_win_list const pstr_frame_win_list, const WORD32 slot,
60
81.4k
    const WORD32 hold) {
61
81.4k
  IA_ERRORCODE error = IA_NO_ERROR;
62
63
81.4k
  if (pstr_frame_win_list->win_list_cnt >= MAX_NUM_PARAMS) {
64
0
    return IA_EXHEAACE_CONFIG_NONFATAL_MPS_PARAM_ERROR;
65
81.4k
  } else if (pstr_frame_win_list->win_list_cnt > 0 &&
66
0
             pstr_frame_win_list->dat[pstr_frame_win_list->win_list_cnt - 1].slot - slot > 0) {
67
0
    return IA_EXHEAACE_CONFIG_NONFATAL_MPS_PARAM_ERROR;
68
81.4k
  } else {
69
81.4k
    pstr_frame_win_list->dat[pstr_frame_win_list->win_list_cnt].hold = hold;
70
81.4k
    pstr_frame_win_list->dat[pstr_frame_win_list->win_list_cnt].slot = slot;
71
81.4k
    pstr_frame_win_list->win_list_cnt++;
72
81.4k
  }
73
81.4k
  return error;
74
81.4k
}
75
76
IA_ERRORCODE
77
ixheaace_mps_212_frame_window_init(
78
    ixheaace_mps_pstr_frame_win pstr_frame_win,
79
1.15k
    const ixheaace_mps_pstr_frame_win_config pstr_frame_win_config) {
80
1.15k
  IA_ERRORCODE error = IA_NO_ERROR;
81
1.15k
  WORD32 slot;
82
1.15k
  WORD32 time_slots = pstr_frame_win_config->num_time_slots_max;
83
1.15k
  pstr_frame_win->frame_keep_flag = pstr_frame_win_config->frame_keep_flag;
84
1.15k
  pstr_frame_win->num_time_slots_max = pstr_frame_win_config->num_time_slots_max;
85
1.15k
  pstr_frame_win->start_slope = 0;
86
1.15k
  pstr_frame_win->start_rect = time_slots >> 1;
87
1.15k
  pstr_frame_win->stop_slope = ((3 * time_slots) >> 1) - 1;
88
1.15k
  pstr_frame_win->stop_rect = time_slots;
89
19.9k
  for (slot = 0; slot<time_slots>> 1; slot++) {
90
18.8k
    pstr_frame_win->p_tapper_sync_flt[slot] = (FLOAT32)slot / time_slots;
91
18.8k
  }
92
1.15k
  pstr_frame_win->p_tapper_sync_flt[time_slots >> 1] = 1.0f;
93
1.15k
  pstr_frame_win->taper_syn_len = time_slots >> 1;
94
1.15k
  pstr_frame_win->taper_ana_len = pstr_frame_win->start_rect - pstr_frame_win->start_slope;
95
19.9k
  for (slot = 0; slot < pstr_frame_win->taper_ana_len; slot++) {
96
18.8k
    pstr_frame_win->p_taper_ana_flt[slot] = 1.0f;
97
18.8k
  }
98
99
1.15k
  return error;
100
1.15k
}
101
102
IA_ERRORCODE ixheaace_mps_212_frame_window_get_window(
103
    ixheaace_mps_pstr_frame_win pstr_frame_win, WORD32 tr_pos[MAX_NUM_PARAMS],
104
    const WORD32 time_slots, ixheaace_mps_framing_info *const pstr_framing_info,
105
    FLOAT32 *ptr_window_ana[MAX_NUM_PARAMS],
106
81.4k
    ixheaace_mps_pstr_frame_win_list const pstr_frame_win_list, const WORD32 avoid_keep) {
107
81.4k
  IA_ERRORCODE error = IA_NO_ERROR;
108
81.4k
  WORD32 win_cnt = 0;
109
81.4k
  WORD32 w, ps;
110
81.4k
  WORD32 idx;
111
81.4k
  WORD32 param;
112
81.4k
  WORD32 start_slope = pstr_frame_win->start_slope;
113
81.4k
  WORD32 start_rect = pstr_frame_win->start_rect;
114
81.4k
  WORD32 stop_slope = pstr_frame_win->stop_slope;
115
81.4k
  WORD32 stop_rect = pstr_frame_win->stop_rect;
116
81.4k
  WORD32 taper_ana_len = pstr_frame_win->taper_ana_len;
117
81.4k
  FLOAT32 apply_right_window_gain[MAX_NUM_PARAMS];
118
81.4k
  FLOAT32 *p_taper_ana = pstr_frame_win->p_taper_ana_flt;
119
120
81.4k
  if ((time_slots > pstr_frame_win->num_time_slots_max) || (time_slots < 0)) {
121
0
    return IA_EXHEAACE_CONFIG_NONFATAL_MPS_INVALID_CONFIG;
122
0
  }
123
124
81.4k
  pstr_frame_win_list->win_list_cnt = 0;
125
651k
  for (param = 0; param < MAX_NUM_PARAMS; param++) {
126
570k
    pstr_frame_win_list->dat[param].slot = -1;
127
570k
    pstr_frame_win_list->dat[param].hold = IXHEAACE_MPS_FRAME_WINDOWING_INTP;
128
570k
  }
129
81.4k
  memset(apply_right_window_gain, 0, sizeof(apply_right_window_gain));
130
81.4k
  if (tr_pos[0] <= 0) {
131
81.4k
    win_cnt = 0;
132
81.4k
    error = ixheaace_mps_212_frame_window_list_add(pstr_frame_win_list, time_slots - 1,
133
81.4k
                                                   IXHEAACE_MPS_FRAME_WINDOWING_INTP);
134
81.4k
    if (error) {
135
0
      return error;
136
0
    }
137
81.4k
    for (idx = 0; idx < start_slope; idx++) {
138
0
      ptr_window_ana[win_cnt][idx] = 0.0f;
139
0
    }
140
1.48M
    for (idx = 0; idx < taper_ana_len; idx++) {
141
1.40M
      ptr_window_ana[win_cnt][start_slope + idx] = p_taper_ana[idx];
142
1.40M
    }
143
144
1.49M
    for (idx = 0; idx < time_slots - start_rect; idx++) {
145
1.41M
      ptr_window_ana[win_cnt][start_rect + idx] = 1.0f;
146
1.41M
    }
147
148
81.4k
    apply_right_window_gain[win_cnt] = 1.0f;
149
81.4k
    win_cnt++;
150
81.4k
  } else {
151
0
    WORD32 p_l = tr_pos[0];
152
0
    win_cnt = 0;
153
0
    error = ixheaace_mps_212_frame_window_list_add(pstr_frame_win_list, p_l - 1,
154
0
                                                   IXHEAACE_MPS_FRAME_WINDOWING_HOLD);
155
0
    if (error) {
156
0
      return error;
157
0
    }
158
0
    error = ixheaace_mps_212_frame_window_list_add(pstr_frame_win_list, p_l,
159
0
                                                   IXHEAACE_MPS_FRAME_WINDOWING_INTP);
160
0
    if (error) {
161
0
      return error;
162
0
    }
163
164
0
    error = ixheaace_mps_212_frame_window_list_limit(pstr_frame_win_list, 0, time_slots - 1);
165
0
    if (error) {
166
0
      return error;
167
0
    }
168
169
0
    error = ixheaace_mps_212_frame_window_list_add(pstr_frame_win_list, time_slots - 1,
170
0
                                                   IXHEAACE_MPS_FRAME_WINDOWING_HOLD);
171
0
    if (error) {
172
0
      return error;
173
0
    }
174
175
0
    if (pstr_frame_win_list->win_list_cnt > MAX_NUM_PARAMS) {
176
0
      return IA_EXHEAACE_CONFIG_NONFATAL_MPS_INVALID_CONFIG;
177
0
    }
178
0
    for (ps = 0; ps < pstr_frame_win_list->win_list_cnt - 1; ps++) {
179
0
      if (IXHEAACE_MPS_FRAME_WINDOWING_HOLD != pstr_frame_win_list->dat[ps].hold) {
180
0
        WORD32 start = pstr_frame_win_list->dat[ps].slot;
181
0
        WORD32 stop = pstr_frame_win_list->dat[ps + 1].slot;
182
183
0
        for (idx = 0; idx < start; idx++) {
184
0
          ptr_window_ana[win_cnt][idx] = 0.0f;
185
0
        }
186
0
        for (idx = 0; idx < stop - start + 1; idx++) {
187
0
          ptr_window_ana[win_cnt][start + idx] = 1.0f;
188
0
        }
189
0
        for (idx = 0; idx < time_slots - stop - 1; idx++) {
190
0
          ptr_window_ana[win_cnt][stop + 1 + idx] = 0.0f;
191
0
        }
192
193
0
        apply_right_window_gain[win_cnt] = ptr_window_ana[win_cnt][time_slots - 1];
194
0
        win_cnt++;
195
0
      }
196
0
    }
197
198
0
    if (pstr_frame_win_list->win_list_cnt - 1 < 0 ||
199
0
        pstr_frame_win_list->win_list_cnt - 1 >= MAX_NUM_PARAMS) {
200
0
      return IA_EXHEAACE_CONFIG_NONFATAL_MPS_PARAM_ERROR;
201
0
    } else if (pstr_frame_win_list->win_list_cnt > 0) {
202
0
      if (pstr_frame_win_list->win_list_cnt - 1 == MAX_NUM_PARAMS - 1) {
203
0
        pstr_frame_win_list->dat[pstr_frame_win_list->win_list_cnt - 1].slot = -1;
204
0
        pstr_frame_win_list->dat[pstr_frame_win_list->win_list_cnt - 1].hold =
205
0
            IXHEAACE_MPS_FRAME_WINDOWING_INTP;
206
0
      } else {
207
0
        for (param = pstr_frame_win_list->win_list_cnt - 1; param < MAX_NUM_PARAMS - 1; param++) {
208
0
          pstr_frame_win_list->dat[param] = pstr_frame_win_list->dat[param + 1];
209
0
        }
210
0
      }
211
0
      pstr_frame_win_list->win_list_cnt--;
212
0
    }
213
0
    if (error) {
214
0
      return error;
215
0
    }
216
0
  }
217
218
162k
  for (w = 0; w < win_cnt; w++) {
219
81.4k
    if (apply_right_window_gain[w] <= 0) {
220
0
      for (idx = 0; idx < time_slots; idx++) {
221
0
        ptr_window_ana[w][time_slots + idx] = 0.0f;
222
0
      }
223
81.4k
    } else {
224
81.4k
      if (tr_pos[1] < 0) {
225
162k
        for (idx = 0; idx < stop_rect - time_slots + 1; idx++) {
226
81.4k
          ptr_window_ana[w][time_slots + idx] = 1.0f;
227
81.4k
        }
228
1.48M
        for (idx = 0; idx < taper_ana_len; idx++) {
229
1.40M
          ptr_window_ana[w][stop_rect + idx] = p_taper_ana[taper_ana_len - 1 - idx];
230
1.40M
        }
231
1.49M
        for (idx = 0; idx < 2 * time_slots - stop_slope - 1; idx++) {
232
1.41M
          ptr_window_ana[w][stop_slope + 1 + idx] = 0.0f;
233
1.41M
        }
234
81.4k
      } else {
235
0
        WORD32 p_r = tr_pos[1];
236
0
        for (idx = 0; idx < p_r - time_slots; idx++) {
237
0
          ptr_window_ana[w][time_slots + idx] = 1.0f;
238
0
        }
239
0
        for (idx = 0; idx < 2 * time_slots - p_r; idx++) {
240
0
          ptr_window_ana[w][p_r + idx] = 0.0f;
241
0
        }
242
0
      }
243
81.4k
      if (apply_right_window_gain[w] < 1.0f) {
244
0
        WORD32 slot;
245
0
        for (slot = 0; slot < time_slots; slot++) {
246
0
          ptr_window_ana[w][time_slots + slot] =
247
0
              ptr_window_ana[w][time_slots + slot] * apply_right_window_gain[w];
248
0
        }
249
0
      }
250
81.4k
    }
251
81.4k
  }
252
81.4k
  if (pstr_frame_win->frame_keep_flag == 1) {
253
2.90M
    for (idx = 0; idx < time_slots; idx++) {
254
2.82M
      ptr_window_ana[0][2 * time_slots + idx] = ptr_window_ana[0][time_slots + idx];
255
2.82M
      ptr_window_ana[0][time_slots + idx] = ptr_window_ana[0][idx];
256
2.82M
    }
257
81.4k
    if (avoid_keep == 0) {
258
1.21M
      for (idx = 0; idx < time_slots; idx++) {
259
1.18M
        ptr_window_ana[0][idx] = 1.0f;
260
1.18M
      }
261
48.1k
    } else {
262
1.68M
      for (idx = 0; idx < time_slots; idx++) {
263
1.63M
        ptr_window_ana[0][idx] = 0.0f;
264
1.63M
      }
265
48.1k
    }
266
81.4k
  }
267
81.4k
  pstr_framing_info->num_param_sets = pstr_frame_win_list->win_list_cnt;
268
81.4k
  pstr_framing_info->bs_framing_type = 1;
269
162k
  for (ps = 0; ps < pstr_framing_info->num_param_sets; ps++) {
270
81.4k
    pstr_framing_info->bs_param_slots[ps] = pstr_frame_win_list->dat[ps].slot;
271
81.4k
  }
272
81.4k
  if ((pstr_framing_info->num_param_sets == 1) &&
273
81.4k
      (pstr_framing_info->bs_param_slots[0] == time_slots - 1)) {
274
81.4k
    pstr_framing_info->bs_framing_type = 0;
275
81.4k
  }
276
81.4k
  return error;
277
81.4k
}
278
279
VOID ixheaace_mps_212_analysis_windowing(
280
    const WORD32 num_time_slots, const WORD32 start_time_slot, FLOAT32 *ptr_window_ana,
281
    ixheaace_cmplx_str pp_cmplx_data_in[MAX_ANA_TIME_SLOT][MAX_QMF_BANDS],
282
    ixheaace_cmplx_str pp_cmplx_data_out[MAX_ANA_TIME_SLOT][MAX_QMF_BANDS],
283
162k
    const WORD32 num_hybrid_bands) {
284
162k
  WORD32 band, slot;
285
162k
  FLOAT32 win;
286
287
11.0M
  for (slot = start_time_slot; slot < num_time_slots; slot++) {
288
10.8M
    win = ptr_window_ana[slot];
289
10.8M
    if (win != 1.0f) {
290
0
      for (band = 0; band < num_hybrid_bands; band++) {
291
0
        pp_cmplx_data_out[slot][band].re = win * pp_cmplx_data_in[slot][band].re;
292
0
        pp_cmplx_data_out[slot][band].im = win * pp_cmplx_data_in[slot][band].im;
293
0
      }
294
10.8M
    } else {
295
704M
      for (band = 0; band < num_hybrid_bands; band++) {
296
693M
        pp_cmplx_data_out[slot][band].re = pp_cmplx_data_in[slot][band].re;
297
693M
        pp_cmplx_data_out[slot][band].im = pp_cmplx_data_in[slot][band].im;
298
693M
      }
299
10.8M
    }
300
10.8M
  }
301
162k
}