Coverage Report

Created: 2025-07-11 06:38

/src/libxaac/encoder/ixheaace_loudness_measurement.c
Line
Count
Source (jump to first uncovered line)
1
/******************************************************************************
2
 *                                                                            *
3
 * Copyright (C) 2024 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 <stdlib.h>
21
#include <string.h>
22
#include <math.h>
23
#include <float.h>
24
#include "ixheaac_type_def.h"
25
#include "ixheaac_error_standards.h"
26
#include "ixheaace_error_codes.h"
27
#include "ixheaace_api.h"
28
#include "ixheaace_loudness_measurement.h"
29
#include "iusace_cnst.h"
30
#include "ixheaac_constants.h"
31
32
FLOAT64 a_coeff_pre_flt[12][3] = {
33
    {0, -1.84460946989011, 0.85584332293064},  /* 96000Hz sample_rate*/
34
    {0, -1.83091998796233, 0.84414226108785},  /* 88200Hz sample_rate*/
35
    {0, -1.76738637827624, 0.79175893605869},  /* 64000Hz sample_rate*/
36
    {0, -1.69065929318241, 0.73248077421585},  /* 48000Hz sample_rate*/
37
    {0, -1.66365511325602, 0.71259542807323},  /* 44100Hz sample_rate*/
38
    {0, -1.53904509625064, 0.62696685598156},  /* 32000Hz sample_rate*/
39
    {0, -1.39023460519282, 0.53683848126040},  /* 24000Hz sample_rate*/
40
    {0, -1.33830533606613, 0.50824455891360},  /* 22050Hz sample_rate*/
41
    {0, -1.10153376910699, 0.39491236874986},  /* 16000Hz sample_rate*/
42
    {0, -0.82398044060334, 0.29429059828526},  /* 12000Hz sample_rate*/
43
    {0, -0.73075690963163, 0.26764083061798},  /* 11025Hz sample_rate*/
44
    {0, -0.29338078241492, 0.18687510604541}}; /* 8000Hz sample_rate*/
45
46
FLOAT64 b_coeff_pre_flt[12][3] = {
47
    {1.55971422897580, -2.92674157825108, 1.37826120231582},  /* 96000Hz sample_rate*/
48
    {1.55751537557965, -2.90562707992635, 1.36133397747221},  /* 88200Hz sample_rate*/
49
    {1.54734277602520, -2.80819560855113, 1.28522539030837},  /* 64000Hz sample_rate*/
50
    {1.53512485958697, -2.69169618940638, 1.19839281085285},  /* 48000Hz sample_rate*/
51
    {1.53084123005034, -2.65097999515473, 1.16907907992158},  /* 44100Hz sample_rate*/
52
    {1.51117789956876, -2.46488941336014, 1.04163327352229},  /* 32000Hz sample_rate*/
53
    {1.48790022096228, -2.24620546814114, 0.90490912324644},  /* 24000Hz sample_rate*/
54
    {1.47982535097775, -2.17072861285683, 0.86084248472655},  /* 22050Hz sample_rate*/
55
    {1.44329522349136, -1.83157538126046, 0.68165875741197},  /* 16000Hz sample_rate*/
56
    {1.40101638596118, -1.44343141964020, 0.51272519136094},  /* 12000Hz sample_rate*/
57
    {1.38693639705635, -1.31515305817747, 0.46510058210747},  /* 11025Hz sample_rate*/
58
    {1.32162356892998, -0.72625549131569, 0.29812624601620}}; /* 8000Hz sample_rate*/
59
60
FLOAT64 a_coeff_RLB_flt[12][3] = {
61
    {0, -1.99501754472472, 0.99502375904092},  /* 96000Hz sample_rate*/
62
    {0, -1.99457751545034, 0.99458487587805},  /* 88200Hz sample_rate*/
63
    {0, -1.99253095794890, 0.99254492277827},  /* 64000Hz sample_rate*/
64
    {0, -1.99004745483398, 0.99007225036621},  /* 48000Hz sample_rate*/
65
    {0, -1.98916967362979, 0.98919903578704},  /* 44100Hz sample_rate*/
66
    {0, -1.98508966898868, 0.98514532066955},  /* 32000Hz sample_rate*/
67
    {0, -1.98014412622893, 0.98024281785928},  /* 24000Hz sample_rate*/
68
    {0, -1.97839760259012, 0.97851441950325},  /* 22050Hz sample_rate*/
69
    {0, -1.97028952800443, 0.97051049053584},  /* 16000Hz sample_rate*/
70
    {0, -1.96048317995201, 0.96087407552357},  /* 12000Hz sample_rate*/
71
    {0, -1.95712192483092, 0.95758214578578},  /* 11025Hz sample_rate*/
72
    {0, -1.94101334282922, 0.94188430416850}}; /* 8000Hz sample_rate*/
73
74
FLOAT64 b_coeff_RLB_flt[12][3] = {
75
    {1.00247575433736, -2.00497008989074, 1.00247575433736},  /* 96000Hz sample_rate*/
76
    {1.00225631275593, -2.00453006061636, 1.00225631275593},  /* 88200Hz sample_rate*/
77
    {1.00123633620603, -2.00248350311492, 1.00123633620603},  /* 64000Hz sample_rate*/
78
    {1.0, -2.0, 1.0},                                         /* 48000Hz sample_rate*/
79
    {0.99956006454251, -1.9991201290850, 0.99956006454251},   /* 44100Hz sample_rate*/
80
    {0.99751647782627, -1.9950329556525, 0.99751647782627},   /* 32000Hz sample_rate*/
81
    {0.99508528374654, -1.99009667139495, 0.99508528374654},  /* 24000Hz sample_rate*/
82
    {0.99422108456853, -1.98835014775614, 0.99422108456853},  /* 22050Hz sample_rate*/
83
    {0.99021912008482, -1.98024207317045, 0.99021912008482},  /* 16000Hz sample_rate*/
84
    {0.98540091257869, -1.97043572511803, 0.98540091257869},  /* 12000Hz sample_rate*/
85
    {0.98375494770979, -1.96707446999694, 0.98375494770979},  /* 11025Hz sample_rate*/
86
    {0.97590602690115, -1.95096588799524, 0.97590602690115}}; /* 8000Hz sample_rate*/
87
88
static WORD32 ixheaace_map_sample_rate(WORD32 sample_rate,
89
7.61k
                                       ixheaace_loudness_struct *pstr_loudness_hdl) {
90
7.61k
  WORD32 mapped_sample_rate = sample_rate;
91
92
7.61k
  if ((mapped_sample_rate >= 0) && (mapped_sample_rate < 9391)) {
93
712
    mapped_sample_rate = 8000;
94
712
    pstr_loudness_hdl->sample_rate_idx = 11;
95
6.89k
  } else if ((mapped_sample_rate >= 9391) && (mapped_sample_rate < 11502)) {
96
191
    mapped_sample_rate = 11025;
97
191
    pstr_loudness_hdl->sample_rate_idx = 10;
98
6.70k
  } else if ((mapped_sample_rate >= 11502) && (mapped_sample_rate < 13856)) {
99
271
    mapped_sample_rate = 12000;
100
271
    pstr_loudness_hdl->sample_rate_idx = 9;
101
6.43k
  } else if ((mapped_sample_rate >= 13856) && (mapped_sample_rate < 18783)) {
102
246
    mapped_sample_rate = 16000;
103
246
    pstr_loudness_hdl->sample_rate_idx = 8;
104
6.19k
  } else if ((mapped_sample_rate >= 18783) && (mapped_sample_rate < 23004)) {
105
215
    mapped_sample_rate = 22050;
106
215
    pstr_loudness_hdl->sample_rate_idx = 7;
107
5.97k
  } else if ((mapped_sample_rate >= 23004) && (mapped_sample_rate < 27713)) {
108
484
    mapped_sample_rate = 24000;
109
484
    pstr_loudness_hdl->sample_rate_idx = 6;
110
5.49k
  } else if ((mapped_sample_rate >= 27713) && (mapped_sample_rate < 37566)) {
111
665
    mapped_sample_rate = 32000;
112
665
    pstr_loudness_hdl->sample_rate_idx = 5;
113
4.82k
  } else if ((mapped_sample_rate >= 37566) && (mapped_sample_rate < 46009)) {
114
1.20k
    mapped_sample_rate = 44100;
115
1.20k
    pstr_loudness_hdl->sample_rate_idx = 4;
116
3.62k
  } else if ((mapped_sample_rate >= 46009) && (mapped_sample_rate < 55426)) {
117
654
    mapped_sample_rate = 48000;
118
654
    pstr_loudness_hdl->sample_rate_idx = 3;
119
2.96k
  } else if ((mapped_sample_rate >= 55426) && (mapped_sample_rate < 75132)) {
120
582
    mapped_sample_rate = 64000;
121
582
    pstr_loudness_hdl->sample_rate_idx = 2;
122
2.38k
  } else if ((mapped_sample_rate >= 75132) && (mapped_sample_rate < 92017)) {
123
411
    mapped_sample_rate = 88200;
124
411
    pstr_loudness_hdl->sample_rate_idx = 1;
125
1.97k
  } else if (mapped_sample_rate >= 92017) {
126
838
    mapped_sample_rate = 96000;
127
838
    pstr_loudness_hdl->sample_rate_idx = 0;
128
1.13k
  } else {
129
1.13k
    mapped_sample_rate = 48000;
130
1.13k
    pstr_loudness_hdl->sample_rate_idx = 3;
131
1.13k
  }
132
7.61k
  return mapped_sample_rate;
133
7.61k
}
134
135
7.61k
WORD32 ixheaace_loudness_info_get_handle_size() {
136
7.61k
  return IXHEAAC_GET_SIZE_ALIGNED(sizeof(ixheaace_loudness_struct), BYTE_ALIGN_8);
137
7.61k
}
138
IA_ERRORCODE ixheaace_loudness_init_params(pVOID loudness_handle,
139
                                           ixheaace_input_config *pstr_input_config,
140
7.61k
                                           ixheaace_output_config *pstr_output_config) {
141
7.61k
  UWORD32 count = 0;
142
7.61k
  UWORD8 temp_count = 0;
143
7.61k
  IA_ERRORCODE err_code = IA_NO_ERROR;
144
7.61k
  ixheaace_loudness_struct *pstr_loudness_hdl = (ixheaace_loudness_struct *)loudness_handle;
145
7.61k
  memset(pstr_loudness_hdl, 0, sizeof(ixheaace_loudness_struct));
146
7.61k
  pstr_loudness_hdl->sample_rate =
147
7.61k
      ixheaace_map_sample_rate(pstr_input_config->i_samp_freq, pstr_loudness_hdl);
148
149
7.61k
  pstr_output_config->samp_freq = pstr_loudness_hdl->sample_rate;
150
7.61k
  pstr_loudness_hdl->length = pstr_input_config->aac_config.length;
151
7.61k
  pstr_loudness_hdl->pcm_sz = pstr_input_config->ui_pcm_wd_sz;
152
7.61k
  if (pstr_loudness_hdl->pcm_sz != 16) {
153
1.38k
    return (IA_EXHEAACE_CONFIG_FATAL_PCM_WDSZ);
154
1.38k
  }
155
6.22k
  pstr_loudness_hdl->n_channels = pstr_input_config->i_channels;
156
6.22k
  if (pstr_loudness_hdl->n_channels > 2 || pstr_loudness_hdl->n_channels < 1) {
157
130
    return (IA_EXHEAACE_CONFIG_FATAL_NUM_CHANNELS);
158
130
  }
159
6.09k
  pstr_loudness_hdl->num_samples_per_ch = (pstr_loudness_hdl->sample_rate / 10);
160
6.09k
  pstr_loudness_hdl->sum_square = 0;
161
6.09k
  pstr_loudness_hdl->mom_loudness_first_time_flag = 1;
162
163
6.09k
  pstr_loudness_hdl->count_fn_call_mmstl = 0;
164
6.09k
  pstr_loudness_hdl->sl_first_time_flag = 1;
165
6.09k
  pstr_loudness_hdl->local_sl_count = 0;
166
6.09k
  pstr_loudness_hdl->short_term_loudness_overlap = IXHEAACE_SL_OVERLAP;
167
168
6.09k
  pstr_loudness_hdl->no_of_mf = IXHEAACE_SEC_TO_100MS_FACTOR;
169
6.09k
  pstr_loudness_hdl->no_of_mf -= IXHEAACE_MOMENTARY_LOUDNESS_OVERLAP;
170
6.09k
  pstr_loudness_hdl->no_of_stf =
171
6.09k
      (((pstr_loudness_hdl->no_of_mf + IXHEAACE_MOMENTARY_LOUDNESS_OVERLAP) - 30) /
172
6.09k
       (30 - pstr_loudness_hdl->short_term_loudness_overlap)) +
173
6.09k
      1;
174
175
6.09k
  pstr_loudness_hdl->tot_int_val_stf_passing_abs_gate = 0;
176
6.09k
  pstr_loudness_hdl->curr_stf_no = 0;
177
6.09k
  pstr_loudness_hdl->loop_curr_stf_no = 0;
178
6.09k
  pstr_loudness_hdl->no_of_stf_passing_abs_gate = 0;
179
6.09k
  pstr_loudness_hdl->max_lra_count = pstr_loudness_hdl->no_of_stf;
180
6.09k
  pstr_loudness_hdl->loop_ml_count_fn_call = 0;
181
6.09k
  pstr_loudness_hdl->ml_count_fn_call = 0;
182
6.09k
  pstr_loudness_hdl->max_il_buf_size = pstr_loudness_hdl->no_of_mf;
183
6.09k
  pstr_loudness_hdl->get_intergrated_loudness = 1;
184
6.09k
  pstr_loudness_hdl->max_sample_val = FLT_EPSILON;
185
186
16.1k
  for (count = 0; count < pstr_loudness_hdl->n_channels; count++) {
187
40.0k
    for (temp_count = 0; temp_count < IXHEAACE_LOUDNESS_NUM_TAPS; temp_count++) {
188
30.0k
      pstr_loudness_hdl->w[0][count][temp_count] = 0;
189
30.0k
      pstr_loudness_hdl->w[1][count][temp_count] = 0;
190
30.0k
    }
191
10.0k
  }
192
193
30.4k
  for (count = 0; count < 4; count++) {
194
24.3k
    pstr_loudness_hdl->prev_four_sum_square[count] = 0;
195
24.3k
  }
196
197
189k
  for (count = 0; count < 30; count++) {
198
182k
    pstr_loudness_hdl->prev_thirty_sum_square[count] = 0;
199
182k
  }
200
201
6.09k
  count = 0;
202
359k
  while (count < (pstr_loudness_hdl->no_of_stf)) {
203
353k
    pstr_loudness_hdl->temp_stf_instances_loudness[count] = 0;
204
353k
    count++;
205
353k
  }
206
207
6.09k
  count = 0;
208
359k
  while (count < (pstr_loudness_hdl->no_of_stf)) {
209
353k
    pstr_loudness_hdl->stf_instances[count].short_term_loudness =
210
353k
        IXHEAACE_DEFAULT_SHORT_TERM_LOUDENSS;
211
353k
    pstr_loudness_hdl->stf_instances[count].int_val = 0;
212
353k
    pstr_loudness_hdl->stf_instances[count].passes_abs_gate = FALSE;
213
353k
    count++;
214
353k
  }
215
216
6.09k
  count = 0;
217
3.64M
  while (count < pstr_loudness_hdl->no_of_mf) {
218
3.63M
    pstr_loudness_hdl->mf_instances[count].momentary_loudness =
219
3.63M
        IXHEAACE_DEFAULT_MOMENTARY_LOUDENSS;
220
3.63M
    pstr_loudness_hdl->mf_instances[count].int_val = 0.0;
221
3.63M
    pstr_loudness_hdl->mf_instances[count].passes_abs_gate = FALSE;
222
3.63M
    count++;
223
3.63M
  }
224
6.09k
  return err_code;
225
6.22k
}
226
227
394M
static FLOAT64 ixheaace_loudness_gen_flt(FLOAT64 *a, FLOAT64 *b, FLOAT64 *w, FLOAT64 input) {
228
394M
  FLOAT64 output = 0;
229
394M
  UWORD8 count;
230
231
1.18G
  for (count = 0; count <= IXHEAACE_LOUDNESS_NUM_TAPS - 2; count++) {
232
789M
    w[count] = w[count + 1];
233
789M
  }
234
394M
  w[IXHEAACE_LOUDNESS_NUM_TAPS - 1] = 0;
235
236
1.18G
  for (count = 1; count <= IXHEAACE_LOUDNESS_NUM_TAPS - 1; count++) {
237
789M
    w[IXHEAACE_LOUDNESS_NUM_TAPS - 1] += a[count] * w[IXHEAACE_LOUDNESS_NUM_TAPS - count - 1];
238
789M
  }
239
394M
  w[IXHEAACE_LOUDNESS_NUM_TAPS - 1] = input - w[IXHEAACE_LOUDNESS_NUM_TAPS - 1];
240
241
1.57G
  for (count = 0; count <= IXHEAACE_LOUDNESS_NUM_TAPS - 1; count++) {
242
1.18G
    output += b[count] * w[IXHEAACE_LOUDNESS_NUM_TAPS - count - 1];
243
1.18G
  }
244
245
394M
  return output;
246
394M
}
247
248
static FLOAT64 ixheaace_loudness_k_flt(FLOAT64 input, ixheaace_loudness_struct *pstr_loudness_hdl,
249
197M
                                       UWORD8 channel_no) {
250
197M
  FLOAT64 temp;
251
197M
  temp = ixheaace_loudness_gen_flt(a_coeff_pre_flt[pstr_loudness_hdl->sample_rate_idx],
252
197M
                                   b_coeff_pre_flt[pstr_loudness_hdl->sample_rate_idx],
253
197M
                                   pstr_loudness_hdl->w[IXHEAACE_LOUDNESS_PRE_FLT][channel_no],
254
197M
                                   input);
255
256
197M
  temp = ixheaace_loudness_gen_flt(a_coeff_RLB_flt[pstr_loudness_hdl->sample_rate_idx],
257
197M
                                   b_coeff_RLB_flt[pstr_loudness_hdl->sample_rate_idx],
258
197M
                                   pstr_loudness_hdl->w[IXHEAACE_LOUDNESS_RLB_FLT][channel_no],
259
197M
                                   temp);
260
261
197M
  return temp;
262
197M
}
263
264
static VOID ixheaace_measure_sum_square(WORD16 **input,
265
40.9k
                                        ixheaace_loudness_struct *pstr_loudness_hdl) {
266
40.9k
  FLOAT64 tot_one_channel = 0;
267
40.9k
  FLOAT64 sum_square = 0;
268
40.9k
  UWORD32 count = 0;
269
40.9k
  FLOAT64 temp = 0;
270
40.9k
  UWORD8 channel_no = 0;
271
40.9k
  FLOAT64 input_sample;
272
98.4k
  for (channel_no = 0; channel_no < pstr_loudness_hdl->n_channels; channel_no++) {
273
57.4k
    tot_one_channel = 0;
274
197M
    for (count = 0; count < pstr_loudness_hdl->num_samples_per_ch; count++) {
275
197M
      input_sample = (FLOAT64)input[channel_no][count] / 32768.0;
276
197M
      pstr_loudness_hdl->max_sample_val =
277
197M
          MAX(fabs(input_sample), pstr_loudness_hdl->max_sample_val);
278
197M
      temp = ixheaace_loudness_k_flt(input_sample, pstr_loudness_hdl, channel_no);
279
197M
      tot_one_channel = tot_one_channel + (temp * temp);
280
197M
    }
281
57.4k
    sum_square += tot_one_channel;
282
57.4k
  }
283
40.9k
  pstr_loudness_hdl->sum_square = sum_square;
284
40.9k
}
285
286
40.9k
static FLOAT64 ixheaace_measure_momentary_loudness(ixheaace_loudness_struct *pstr_loudness_hdl) {
287
40.9k
  FLOAT64 sum = 0;
288
40.9k
  FLOAT64 momentary_loudness;
289
40.9k
  UWORD32 count = 0;
290
40.9k
  FLOAT64 old_ml_val, db_old_ml_val;
291
40.9k
  {
292
163k
    for (count = 0; count <= 2; count++) {
293
122k
      pstr_loudness_hdl->prev_four_sum_square[count] =
294
122k
          pstr_loudness_hdl->prev_four_sum_square[count + 1];
295
122k
      sum += pstr_loudness_hdl->prev_four_sum_square[count];
296
122k
    }
297
298
40.9k
    pstr_loudness_hdl->prev_four_sum_square[3] = pstr_loudness_hdl->sum_square;
299
40.9k
    sum += pstr_loudness_hdl->prev_four_sum_square[3];
300
301
40.9k
    if ((pstr_loudness_hdl->mom_loudness_first_time_flag == 1) &&
302
40.9k
        (pstr_loudness_hdl->count_fn_call_mmstl <= 2)) {
303
8.13k
      momentary_loudness = IXHEAACE_LOUDNESS_DONT_PASS;
304
32.8k
    } else {
305
32.8k
      pstr_loudness_hdl->mom_loudness_first_time_flag = 0;
306
32.8k
      momentary_loudness =
307
32.8k
          -0.691 + 10 * log10(sum / ((FLOAT64)(4 * pstr_loudness_hdl->num_samples_per_ch)));
308
309
32.8k
      if (pstr_loudness_hdl->get_intergrated_loudness == 1) {
310
32.8k
        old_ml_val =
311
32.8k
            pstr_loudness_hdl->mf_instances[pstr_loudness_hdl->loop_ml_count_fn_call].int_val;
312
32.8k
        pstr_loudness_hdl->mf_instances[pstr_loudness_hdl->loop_ml_count_fn_call].int_val =
313
32.8k
            sum / ((FLOAT64)(4 * pstr_loudness_hdl->num_samples_per_ch));
314
32.8k
        db_old_ml_val = pstr_loudness_hdl->mf_instances[pstr_loudness_hdl->loop_ml_count_fn_call]
315
32.8k
                            .momentary_loudness;
316
32.8k
        pstr_loudness_hdl->mf_instances[pstr_loudness_hdl->loop_ml_count_fn_call]
317
32.8k
            .momentary_loudness = momentary_loudness;
318
32.8k
        if (pstr_loudness_hdl->mf_instances[pstr_loudness_hdl->loop_ml_count_fn_call]
319
32.8k
                .momentary_loudness >= IXHEAACE_ABS_GATE) {
320
22.9k
          if (db_old_ml_val < IXHEAACE_ABS_GATE) {
321
22.8k
            pstr_loudness_hdl->no_of_mf_passing_abs_gate++;
322
22.8k
            old_ml_val = 0;
323
22.8k
          }
324
325
22.9k
          pstr_loudness_hdl->tot_int_val_mf_passing_abs_gate =
326
22.9k
              pstr_loudness_hdl->tot_int_val_mf_passing_abs_gate +
327
22.9k
              (pstr_loudness_hdl->mf_instances[pstr_loudness_hdl->loop_ml_count_fn_call].int_val -
328
22.9k
               old_ml_val);
329
22.9k
        } else {
330
9.93k
          if (db_old_ml_val >= IXHEAACE_ABS_GATE) {
331
90
            pstr_loudness_hdl->no_of_mf_passing_abs_gate--;
332
90
            pstr_loudness_hdl->tot_int_val_mf_passing_abs_gate =
333
90
                pstr_loudness_hdl->tot_int_val_mf_passing_abs_gate - old_ml_val;
334
90
          }
335
9.93k
        }
336
337
32.8k
        pstr_loudness_hdl->loop_ml_count_fn_call++;
338
32.8k
        if (pstr_loudness_hdl->ml_count_fn_call < pstr_loudness_hdl->max_il_buf_size)
339
32.5k
          pstr_loudness_hdl->ml_count_fn_call++;
340
341
32.8k
        pstr_loudness_hdl->loop_ml_count_fn_call =
342
32.8k
            pstr_loudness_hdl->loop_ml_count_fn_call % pstr_loudness_hdl->max_il_buf_size;
343
32.8k
      }
344
32.8k
    }
345
40.9k
  }
346
40.9k
  return (momentary_loudness);
347
40.9k
}
348
349
21
FLOAT64 ixheaace_measure_integrated_loudness(pVOID loudness_handle) {
350
21
  UWORD32 count = 0;
351
21
  FLOAT64 avg = 0;
352
21
  FLOAT64 loudness = 0;
353
21
  ixheaace_loudness_struct *pstr_loudness_hdl = (ixheaace_loudness_struct *)loudness_handle;
354
21
  pstr_loudness_hdl->no_of_mf_passing_rel_gate = 0;
355
21
  pstr_loudness_hdl->tot_int_val_mf_passing_rel_gate = 0;
356
357
21
  if (pstr_loudness_hdl->no_of_mf_passing_abs_gate) {
358
12
    avg = (pstr_loudness_hdl->tot_int_val_mf_passing_abs_gate /
359
12
           pstr_loudness_hdl->no_of_mf_passing_abs_gate);
360
12
  } else {
361
9
    avg = IXHEAACE_SUM_SQUARE_EPS / pstr_loudness_hdl->num_samples_per_ch;
362
9
  }
363
21
  pstr_loudness_hdl->rel_gate = -0.691 + 10 * log10(avg) - 10;
364
365
674
  while (count < pstr_loudness_hdl->ml_count_fn_call) {
366
653
    if (pstr_loudness_hdl->mf_instances[count].momentary_loudness >=
367
653
        pstr_loudness_hdl->rel_gate) {
368
276
      pstr_loudness_hdl->no_of_mf_passing_rel_gate++;
369
276
      pstr_loudness_hdl->tot_int_val_mf_passing_rel_gate +=
370
276
          pstr_loudness_hdl->mf_instances[count].int_val;
371
276
    }
372
653
    count++;
373
653
  }
374
375
21
  if (pstr_loudness_hdl->no_of_mf_passing_rel_gate) {
376
13
    loudness = -0.691 + 10 * log10((pstr_loudness_hdl->tot_int_val_mf_passing_rel_gate /
377
13
                                    (FLOAT64)pstr_loudness_hdl->no_of_mf_passing_rel_gate));
378
13
  } else {
379
8
    loudness =
380
8
        -0.691 + 10 * log10(IXHEAACE_SUM_SQUARE_EPS / pstr_loudness_hdl->num_samples_per_ch);
381
8
  }
382
383
21
  return loudness;
384
21
}
385
386
40.9k
FLOAT64 ixheaace_measure_loudness(pVOID loudness_handle, WORD16 **samples) {
387
40.9k
  FLOAT64 loudness_value;
388
40.9k
  ixheaace_loudness_struct *pstr_loudness_hdl = (ixheaace_loudness_struct *)loudness_handle;
389
40.9k
  ixheaace_measure_sum_square(samples, pstr_loudness_hdl);
390
40.9k
  loudness_value = ixheaace_measure_momentary_loudness(pstr_loudness_hdl);
391
40.9k
  pstr_loudness_hdl->count_fn_call_mmstl++;
392
40.9k
  return loudness_value;
393
40.9k
}
394
395
0
FLOAT32 ixheaace_measure_sample_peak_value(pVOID loudness_handle) {
396
0
  FLOAT32 sample_peak_value;
397
0
  ixheaace_loudness_struct *pstr_loudness_hdl = (ixheaace_loudness_struct *)loudness_handle;
398
0
  sample_peak_value = (FLOAT32)(20 * log10(pstr_loudness_hdl->max_sample_val));
399
0
  return sample_peak_value;
400
0
}