FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/aacpsy.c
Date: 2026-08-31 23:16:59
Exec Total Coverage
Lines: 457 542 84.3%
Functions: 19 21 90.5%
Branches: 328 425 77.2%

Line Branch Exec Source
1 /*
2 * AAC encoder psychoacoustic model
3 * Copyright (C) 2008 Konstantin Shishkov
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 /**
23 * @file
24 * AAC encoder psychoacoustic model
25 */
26
27 #include "libavutil/attributes.h"
28 #include "libavutil/ffmath.h"
29 #include "libavutil/mem.h"
30
31 #include "avcodec.h"
32 #include "aac.h"
33 #include "psymodel.h"
34
35 /***********************************
36 * TODOs:
37 * try other bitrate controlling mechanism (maybe use ratecontrol.c?)
38 * control quality for quality-based output
39 **********************************/
40
41 /**
42 * constants for 3GPP AAC psychoacoustic model
43 * @{
44 */
45 #define PSY_3GPP_THR_SPREAD_HI 1.5f // spreading factor for low-to-hi threshold spreading (15 dB/Bark)
46 #define PSY_3GPP_THR_SPREAD_LOW 3.0f // spreading factor for hi-to-low threshold spreading (30 dB/Bark)
47 /* spreading factor for low-to-hi energy spreading, long block, > 22kbps/channel (20dB/Bark) */
48 #define PSY_3GPP_EN_SPREAD_HI_L1 2.0f
49 /* spreading factor for low-to-hi energy spreading, long block, <= 22kbps/channel (15dB/Bark) */
50 #define PSY_3GPP_EN_SPREAD_HI_L2 1.5f
51 /* spreading factor for low-to-hi energy spreading, short block (15 dB/Bark) */
52 #define PSY_3GPP_EN_SPREAD_HI_S 1.5f
53 /* spreading factor for hi-to-low energy spreading, long block (30dB/Bark) */
54 #define PSY_3GPP_EN_SPREAD_LOW_L 3.0f
55 /* spreading factor for hi-to-low energy spreading, short block (20dB/Bark) */
56 #define PSY_3GPP_EN_SPREAD_LOW_S 2.0f
57
58 #define PSY_3GPP_RPEMIN 0.01f
59 #define PSY_3GPP_RPELEV 2.0f
60
61 #define PSY_3GPP_C1 3.0f /* log2(8) */
62 #define PSY_3GPP_C2 1.3219281f /* log2(2.5) */
63 #define PSY_3GPP_C3 0.55935729f /* 1 - C2 / C1 */
64
65 #define PSY_SNR_1DB 7.9432821e-1f /* -1dB */
66 #define PSY_SNR_25DB 3.1622776e-3f /* -25dB */
67
68 #define PSY_3GPP_SAVE_SLOPE_L -0.46666667f
69 #define PSY_3GPP_SAVE_SLOPE_S -0.36363637f
70 #define PSY_3GPP_SAVE_ADD_L -0.84285712f
71 #define PSY_3GPP_SAVE_ADD_S -0.75f
72 #define PSY_3GPP_SPEND_SLOPE_L 0.66666669f
73 #define PSY_3GPP_SPEND_SLOPE_S 0.81818181f
74 #define PSY_3GPP_SPEND_ADD_L -0.35f
75 #define PSY_3GPP_SPEND_ADD_S -0.26111111f
76 #define PSY_3GPP_CLIP_LO_L 0.2f
77 #define PSY_3GPP_CLIP_LO_S 0.2f
78 #define PSY_3GPP_CLIP_HI_L 0.95f
79 #define PSY_3GPP_CLIP_HI_S 0.75f
80
81 #define PSY_3GPP_AH_THR_LONG 0.5f
82 #define PSY_3GPP_AH_THR_SHORT 0.63f
83
84 #define PSY_PE_FORGET_SLOPE 511
85
86 enum {
87 PSY_3GPP_AH_NONE,
88 PSY_3GPP_AH_INACTIVE,
89 PSY_3GPP_AH_ACTIVE
90 };
91
92 #define PSY_3GPP_BITS_TO_PE(bits) ((bits) * 1.18f)
93 #define PSY_3GPP_PE_TO_BITS(bits) ((bits) / 1.18f)
94
95 /* LAME psy model constants */
96 #define PSY_LAME_FIR_LEN 21 ///< LAME psy model FIR order
97 #define AAC_BLOCK_SIZE_LONG 1024 ///< long block size
98 #define AAC_BLOCK_SIZE_SHORT 128 ///< short block size
99 #define AAC_NUM_BLOCKS_SHORT 8 ///< number of blocks in a short sequence
100 #define PSY_LAME_NUM_SUBBLOCKS 2 ///< Number of sub-blocks in each short block
101
102 /* Pre-echo-aware attack detection: the LAME ratio test misses gentler attacks after a quiet
103 * gap, which then stay long and pre-echo. For an isolated onset (long for PSY_LAME_PE_GAP
104 * frames) whose pre-onset is below PSY_LAME_PE_QUIET of the frame peak, scale the threshold by
105 * PSY_LAME_PE_RED so it switches short; dense-transient content never qualifies. */
106 #define PSY_LAME_PE_GAP 12 ///< min consecutive long frames before the relaxation applies
107 #define PSY_LAME_PE_QUIET 0.4f ///< pre-onset must be below this fraction of the frame peak
108 #define PSY_LAME_PE_RED 0.45f ///< attack-threshold multiplier for a qualifying isolated onset
109
110 /* The novelty check must see at least one full period of a pulse train to
111 * recognize its pulses as repeats; 30 sub-blocks reaches down to ~23Hz. */
112 #define PSY_LAME_HIST 32 ///< HP sub-block peak history depth
113 #define PSY_LAME_NOV_BACK 30 ///< novelty look-back in sub-blocks
114
115 /**
116 * @}
117 */
118
119 /**
120 * information for single band used by 3GPP TS26.403-inspired psychoacoustic model
121 */
122 typedef struct AacPsyBand{
123 float energy; ///< band energy
124 float thr; ///< energy threshold
125 float thr_quiet; ///< threshold in quiet
126 float nz_lines; ///< number of non-zero spectral lines
127 float active_lines; ///< number of active spectral lines
128 float pe; ///< perceptual entropy
129 float pe_const; ///< constant part of the PE calculation
130 float norm_fac; ///< normalization factor for linearization
131 int avoid_holes; ///< hole avoidance flag
132 }AacPsyBand;
133
134 /**
135 * single/pair channel context for psychoacoustic model
136 */
137 typedef struct AacPsyChannel{
138 AacPsyBand band[128]; ///< bands information
139 AacPsyBand prev_band[128]; ///< bands information from the previous frame
140
141 float win_energy; ///< sliding average of channel energy
142 float iir_state[2]; ///< hi-pass IIR filter state
143 uint8_t next_grouping; ///< stored grouping scheme for the next frame (in case of 8 short window sequence)
144 enum WindowSequence next_window_seq; ///< window sequence to be used in the next frame
145 /* LAME psy model specific members */
146 float attack_threshold; ///< attack threshold for this channel
147 float prev_energy_subshort[AAC_NUM_BLOCKS_SHORT * PSY_LAME_NUM_SUBBLOCKS];
148 float hp_env_hist[PSY_LAME_HIST]; ///< rolling HP sub-block peak envelope
149 int prev_attack; ///< attack value for the last short block in the previous sequence
150 int next_attack0_zero; ///< whether attack[0] of the next frame is zero
151 int frames_since_short; ///< consecutive long frames (pre-echo-aware isolated-onset gate)
152 float prev_frame_energy; ///< previous frame's full-band lookahead energy (attack veto)
153 int64_t win_count; ///< window() calls so far (frame counter for pair sync)
154 int64_t last_att; ///< win_count value of this channel's last own attack
155
156 /* rate-loop re-analysis rewind state, see psy_3gpp_analyze() */
157 int64_t rc_frame_num; ///< frame this channel last saved rewind state for
158 AacPsyBand rc_prev_band[128]; ///< prev_band as it was entering the frame
159 }AacPsyChannel;
160
161 /**
162 * psychoacoustic model frame type-dependent coefficients
163 */
164 typedef struct AacPsyCoeffs{
165 float ath; ///< absolute threshold of hearing per bands
166 float barks; ///< Bark value for each spectral band in long frame
167 float spread_low[2]; ///< spreading factor for low-to-high threshold spreading in long frame
168 float spread_hi [2]; ///< spreading factor for high-to-low threshold spreading in long frame
169 float min_snr; ///< minimal SNR
170 }AacPsyCoeffs;
171
172 /**
173 * 3GPP TS26.403-inspired psychoacoustic model specific data
174 */
175 typedef struct AacPsyContext{
176 int chan_bitrate; ///< bitrate per channel
177 int frame_bits; ///< average bits per frame
178 int fill_level; ///< bit reservoir fill level
179 struct {
180 float min; ///< minimum allowed PE for bit factor calculation
181 float max; ///< maximum allowed PE for bit factor calculation
182 float previous; ///< allowed PE of the previous frame
183 float correction; ///< PE correction factor
184 } pe;
185 AacPsyCoeffs psy_coef[2][64];
186 AacPsyChannel *ch;
187 float global_quality; ///< normalized global quality taken from avctx
188
189 /* rate-loop re-analysis rewind state, see psy_3gpp_analyze() */
190 int64_t rc_frame_num; ///< frame the rewind state was saved for
191 int rc_first_ch; ///< first channel analyzed in that frame
192 int rc_fill_level;
193 float rc_pe_min, rc_pe_max, rc_pe_previous;
194 }AacPsyContext;
195
196 /**
197 * LAME psy model preset struct
198 */
199 typedef struct PsyLamePreset {
200 int quality; ///< Quality to map the rest of the values to.
201 /* This is overloaded to be both kbps per channel in ABR mode, and
202 * requested quality in constant quality mode.
203 */
204 float st_lrm; ///< short threshold for L, R, and M channels
205 } PsyLamePreset;
206
207 /**
208 * LAME psy model preset table for ABR
209 */
210 static const PsyLamePreset psy_abr_map[] = {
211 /* TODO: Tuning. These were taken from LAME. */
212 /* kbps/ch st_lrm */
213 { 8, 7.60},
214 { 16, 7.60},
215 { 24, 7.60},
216 { 32, 7.60},
217 { 40, 7.60},
218 { 48, 7.60},
219 { 56, 7.60},
220 { 64, 7.40},
221 { 80, 7.00},
222 { 96, 6.60},
223 {112, 6.20},
224 {128, 6.20},
225 {160, 6.20}
226 };
227
228 /**
229 * LAME psy model preset table for constant quality
230 */
231 static const PsyLamePreset psy_vbr_map[] = {
232 /* vbr_q st_lrm */
233 { 0, 4.20},
234 { 1, 4.20},
235 { 2, 4.20},
236 { 3, 4.20},
237 { 4, 4.20},
238 { 5, 4.20},
239 { 6, 4.20},
240 { 7, 4.20},
241 { 8, 4.20},
242 { 9, 4.20},
243 {10, 4.20}
244 };
245
246 /**
247 * LAME psy model FIR coefficient table
248 */
249 static const float psy_fir_coeffs[] = {
250 -8.65163e-18 * 2, -0.00851586 * 2, -6.74764e-18 * 2, 0.0209036 * 2,
251 -3.36639e-17 * 2, -0.0438162 * 2, -1.54175e-17 * 2, 0.0931738 * 2,
252 -5.52212e-17 * 2, -0.313819 * 2
253 };
254
255 /**
256 * Calculate the ABR attack threshold from the above LAME psymodel table.
257 */
258 117 static float lame_calc_attack_threshold(int bitrate)
259 {
260 /* Assume max bitrate to start with */
261 117 int lower_range = 12, upper_range = 12;
262 117 int lower_range_kbps = psy_abr_map[12].quality;
263 117 int upper_range_kbps = psy_abr_map[12].quality;
264 int i;
265
266 /* Determine which bitrates the value specified falls between.
267 * If the loop ends without breaking our above assumption of 320kbps was correct.
268 */
269
2/2
✓ Branch 0 taken 864 times.
✓ Branch 1 taken 4 times.
868 for (i = 1; i < 13; i++) {
270
2/2
✓ Branch 0 taken 113 times.
✓ Branch 1 taken 751 times.
864 if (FFMAX(bitrate, psy_abr_map[i].quality) != bitrate) {
271 113 upper_range = i;
272 113 upper_range_kbps = psy_abr_map[i ].quality;
273 113 lower_range = i - 1;
274 113 lower_range_kbps = psy_abr_map[i - 1].quality;
275 113 break; /* Upper range found */
276 }
277 }
278
279 /* Determine which range the value specified is closer to */
280
2/2
✓ Branch 0 taken 71 times.
✓ Branch 1 taken 46 times.
117 if ((upper_range_kbps - bitrate) > (bitrate - lower_range_kbps))
281 71 return psy_abr_map[lower_range].st_lrm;
282 46 return psy_abr_map[upper_range].st_lrm;
283 }
284
285 /**
286 * LAME psy model specific initialization
287 */
288 23 static av_cold void lame_window_init(AacPsyContext *ctx, AVCodecContext *avctx)
289 {
290 int i, j;
291
292
2/2
✓ Branch 0 taken 117 times.
✓ Branch 1 taken 23 times.
140 for (i = 0; i < avctx->ch_layout.nb_channels; i++) {
293 117 AacPsyChannel *pch = &ctx->ch[i];
294
295
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 117 times.
117 if (avctx->flags & AV_CODEC_FLAG_QSCALE)
296 pch->attack_threshold = psy_vbr_map[av_clip(avctx->global_quality / FF_QP2LAMBDA, 0, 10)].st_lrm;
297 else
298 117 pch->attack_threshold = lame_calc_attack_threshold(avctx->bit_rate / avctx->ch_layout.nb_channels / 1000);
299
300
2/2
✓ Branch 0 taken 1872 times.
✓ Branch 1 taken 117 times.
1989 for (j = 0; j < AAC_NUM_BLOCKS_SHORT * PSY_LAME_NUM_SUBBLOCKS; j++)
301 1872 pch->prev_energy_subshort[j] = 10.0f;
302
2/2
✓ Branch 0 taken 3744 times.
✓ Branch 1 taken 117 times.
3861 for (j = 0; j < PSY_LAME_HIST; j++)
303 3744 pch->hp_env_hist[j] = 10.0f;
304 }
305 23 }
306
307 /**
308 * Calculate Bark value for given line.
309 */
310 1472 static av_cold float calc_bark(float f)
311 {
312 1472 return 13.3f * atanf(0.00076f * f) + 3.5f * atanf((f / 7500.0f) * (f / 7500.0f));
313 }
314
315 #define ATH_ADD 4
316 /**
317 * Calculate ATH value for given frequency.
318 * Borrowed from Lame.
319 */
320 30001 static av_cold float ath(float f, float add)
321 {
322 30001 f /= 1000.0f;
323 30001 return 3.64 * pow(f, -0.8)
324 30001 - 6.8 * exp(-0.6 * (f - 3.4) * (f - 3.4))
325 30001 + 6.0 * exp(-0.15 * (f - 8.7) * (f - 8.7))
326 30001 + (0.6 + 0.04 * add) * 0.001 * f * f * f * f;
327 }
328
329 23 static av_cold int psy_3gpp_init(FFPsyContext *ctx) {
330 AacPsyContext *pctx;
331 float bark;
332 int i, j, g, start;
333 float prev, minscale, minath, minsnr, pe_min;
334
1/2
✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
23 int chan_bitrate = ctx->avctx->bit_rate / ((ctx->avctx->flags & AV_CODEC_FLAG_QSCALE) ? 2.0f : ctx->avctx->ch_layout.nb_channels);
335
336
1/8
✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
23 const int bandwidth = ctx->cutoff ? ctx->cutoff : AAC_CUTOFF(ctx->avctx);
337 23 const float num_bark = calc_bark((float)bandwidth);
338
339
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23 times.
23 if (bandwidth <= 0)
340 return AVERROR(EINVAL);
341
342 23 ctx->model_priv_data = av_mallocz(sizeof(AacPsyContext));
343
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23 times.
23 if (!ctx->model_priv_data)
344 return AVERROR(ENOMEM);
345 23 pctx = ctx->model_priv_data;
346
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23 times.
23 pctx->global_quality = (ctx->avctx->global_quality ? ctx->avctx->global_quality : 120) * 0.01f;
347
348
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23 times.
23 if (ctx->avctx->flags & AV_CODEC_FLAG_QSCALE) {
349 /* Use the target average bitrate to compute spread parameters */
350 chan_bitrate = (int)(chan_bitrate / 120.0 * (ctx->avctx->global_quality ? ctx->avctx->global_quality : 120));
351 }
352
353 23 pctx->chan_bitrate = chan_bitrate;
354 23 pctx->frame_bits = FFMIN(2560, chan_bitrate * AAC_BLOCK_SIZE_LONG / ctx->avctx->sample_rate);
355 23 pctx->pe.min = 8.0f * AAC_BLOCK_SIZE_LONG * bandwidth / (ctx->avctx->sample_rate * 2.0f);
356 23 pctx->pe.max = 12.0f * AAC_BLOCK_SIZE_LONG * bandwidth / (ctx->avctx->sample_rate * 2.0f);
357 23 ctx->bitres.size = 6144 - pctx->frame_bits;
358 23 ctx->bitres.size -= ctx->bitres.size % 8;
359 23 pctx->fill_level = ctx->bitres.size;
360 23 minath = ath(3410 - 0.733 * ATH_ADD, ATH_ADD);
361
2/2
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 23 times.
69 for (j = 0; j < 2; j++) {
362 46 AacPsyCoeffs *coeffs = pctx->psy_coef[j];
363 46 const uint8_t *band_sizes = ctx->bands[j];
364
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 23 times.
46 float line_to_frequency = ctx->avctx->sample_rate / (j ? 256.f : 2048.0f);
365
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 23 times.
46 float avg_chan_bits = chan_bitrate * (j ? 128.0f : 1024.0f) / ctx->avctx->sample_rate;
366 /* reference encoder uses 2.4% here instead of 60% like the spec says */
367 46 float bark_pe = 0.024f * PSY_3GPP_BITS_TO_PE(avg_chan_bits) / num_bark;
368
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 23 times.
46 float en_spread_low = j ? PSY_3GPP_EN_SPREAD_LOW_S : PSY_3GPP_EN_SPREAD_LOW_L;
369 /* High energy spreading for long blocks <= 22kbps/channel and short blocks are the same. */
370
3/4
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 23 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 23 times.
46 float en_spread_hi = (j || (chan_bitrate <= 22.0f)) ? PSY_3GPP_EN_SPREAD_HI_S : PSY_3GPP_EN_SPREAD_HI_L1;
371
372 46 i = 0;
373 46 prev = 0.0;
374
2/2
✓ Branch 0 taken 1449 times.
✓ Branch 1 taken 46 times.
1495 for (g = 0; g < ctx->num_bands[j]; g++) {
375 1449 i += band_sizes[g];
376 1449 bark = calc_bark((i-1) * line_to_frequency);
377 1449 coeffs[g].barks = (bark + prev) / 2.0;
378 1449 prev = bark;
379 }
380
2/2
✓ Branch 0 taken 1403 times.
✓ Branch 1 taken 46 times.
1449 for (g = 0; g < ctx->num_bands[j] - 1; g++) {
381 1403 AacPsyCoeffs *coeff = &coeffs[g];
382 1403 float bark_width = coeffs[g+1].barks - coeffs->barks;
383 1403 coeff->spread_low[0] = ff_exp10(-bark_width * PSY_3GPP_THR_SPREAD_LOW);
384 1403 coeff->spread_hi [0] = ff_exp10(-bark_width * PSY_3GPP_THR_SPREAD_HI);
385 1403 coeff->spread_low[1] = ff_exp10(-bark_width * en_spread_low);
386 1403 coeff->spread_hi [1] = ff_exp10(-bark_width * en_spread_hi);
387 1403 pe_min = bark_pe * bark_width;
388 1403 minsnr = exp2(pe_min / band_sizes[g]) - 1.5f;
389 1403 coeff->min_snr = av_clipf(1.0f / minsnr, PSY_SNR_25DB, PSY_SNR_1DB);
390 }
391 46 start = 0;
392
2/2
✓ Branch 0 taken 1449 times.
✓ Branch 1 taken 46 times.
1495 for (g = 0; g < ctx->num_bands[j]; g++) {
393 1449 minscale = ath(start * line_to_frequency, ATH_ADD);
394
2/2
✓ Branch 0 taken 25047 times.
✓ Branch 1 taken 1449 times.
26496 for (i = 1; i < band_sizes[g]; i++)
395
2/2
✓ Branch 1 taken 3482 times.
✓ Branch 2 taken 21565 times.
25047 minscale = FFMIN(minscale, ath((start + i) * line_to_frequency, ATH_ADD));
396 1449 coeffs[g].ath = minscale - minath;
397 1449 start += band_sizes[g];
398 }
399 }
400
401 23 pctx->ch = av_calloc(ctx->avctx->ch_layout.nb_channels, sizeof(*pctx->ch));
402
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23 times.
23 if (!pctx->ch) {
403 av_freep(&ctx->model_priv_data);
404 return AVERROR(ENOMEM);
405 }
406
407 23 pctx->rc_frame_num = -1;
408
2/2
✓ Branch 0 taken 117 times.
✓ Branch 1 taken 23 times.
140 for (i = 0; i < ctx->avctx->ch_layout.nb_channels; i++)
409 117 pctx->ch[i].rc_frame_num = -1;
410
411 23 lame_window_init(pctx, ctx->avctx);
412
413 23 return 0;
414 }
415
416 /**
417 * IIR filter used in block switching decision
418 */
419 static float iir_filter(int in, float state[2])
420 {
421 float ret;
422
423 ret = 0.7548f * (in - state[0]) + 0.5095f * state[1];
424 state[0] = in;
425 state[1] = ret;
426 return ret;
427 }
428
429 /**
430 * window grouping information stored as bits (0 - new group, 1 - group continues)
431 */
432 static const uint8_t window_grouping[9] = {
433 0xB6, 0x6C, 0xD8, 0xB2, 0x66, 0xC6, 0x96, 0x36, 0x36
434 };
435
436 /**
437 * Tell encoder which window types to use.
438 * @see 3GPP TS26.403 5.4.1 "Blockswitching"
439 */
440 av_unused static FFPsyWindowInfo psy_3gpp_window(FFPsyContext *ctx,
441 const int16_t *audio,
442 const int16_t *la,
443 int channel, int prev_type)
444 {
445 int i, j;
446 int br = ((AacPsyContext*)ctx->model_priv_data)->chan_bitrate;
447 int attack_ratio = br <= 16000 ? 18 : 10;
448 AacPsyContext *pctx = (AacPsyContext*) ctx->model_priv_data;
449 AacPsyChannel *pch = &pctx->ch[channel];
450 uint8_t grouping = 0;
451 int next_type = pch->next_window_seq;
452 FFPsyWindowInfo wi = { { 0 } };
453
454 if (la) {
455 float s[8], v;
456 int switch_to_eight = 0;
457 float sum = 0.0, sum2 = 0.0;
458 int attack_n = 0;
459 int stay_short = 0;
460 for (i = 0; i < 8; i++) {
461 for (j = 0; j < 128; j++) {
462 v = iir_filter(la[i*128+j], pch->iir_state);
463 sum += v*v;
464 }
465 s[i] = sum;
466 sum2 += sum;
467 }
468 for (i = 0; i < 8; i++) {
469 if (s[i] > pch->win_energy * attack_ratio) {
470 attack_n = i + 1;
471 switch_to_eight = 1;
472 break;
473 }
474 }
475 pch->win_energy = pch->win_energy*7/8 + sum2/64;
476
477 wi.window_type[1] = prev_type;
478 switch (prev_type) {
479 case ONLY_LONG_SEQUENCE:
480 wi.window_type[0] = switch_to_eight ? LONG_START_SEQUENCE : ONLY_LONG_SEQUENCE;
481 next_type = switch_to_eight ? EIGHT_SHORT_SEQUENCE : ONLY_LONG_SEQUENCE;
482 break;
483 case LONG_START_SEQUENCE:
484 wi.window_type[0] = EIGHT_SHORT_SEQUENCE;
485 grouping = pch->next_grouping;
486 next_type = switch_to_eight ? EIGHT_SHORT_SEQUENCE : LONG_STOP_SEQUENCE;
487 break;
488 case LONG_STOP_SEQUENCE:
489 wi.window_type[0] = switch_to_eight ? LONG_START_SEQUENCE : ONLY_LONG_SEQUENCE;
490 next_type = switch_to_eight ? EIGHT_SHORT_SEQUENCE : ONLY_LONG_SEQUENCE;
491 break;
492 case EIGHT_SHORT_SEQUENCE:
493 stay_short = next_type == EIGHT_SHORT_SEQUENCE || switch_to_eight;
494 wi.window_type[0] = stay_short ? EIGHT_SHORT_SEQUENCE : LONG_STOP_SEQUENCE;
495 grouping = next_type == EIGHT_SHORT_SEQUENCE ? pch->next_grouping : 0;
496 next_type = switch_to_eight ? EIGHT_SHORT_SEQUENCE : LONG_STOP_SEQUENCE;
497 break;
498 }
499
500 pch->next_grouping = window_grouping[attack_n];
501 pch->next_window_seq = next_type;
502 } else {
503 for (i = 0; i < 3; i++)
504 wi.window_type[i] = prev_type;
505 grouping = (prev_type == EIGHT_SHORT_SEQUENCE) ? window_grouping[0] : 0;
506 }
507
508 wi.window_shape = 1;
509 if (wi.window_type[0] != EIGHT_SHORT_SEQUENCE) {
510 wi.num_windows = 1;
511 wi.grouping[0] = 1;
512 } else {
513 int lastgrp = 0;
514 wi.num_windows = 8;
515 for (i = 0; i < 8; i++) {
516 if (!((grouping >> i) & 1))
517 lastgrp = i;
518 wi.grouping[lastgrp]++;
519 }
520 }
521
522 return wi;
523 }
524
525 /* 5.6.1.2 "Calculation of Bit Demand" */
526 10196 static int calc_bit_demand(AacPsyContext *ctx, float pe, int bits, int size,
527 int short_window)
528 {
529
2/2
✓ Branch 0 taken 325 times.
✓ Branch 1 taken 9871 times.
10196 const float bitsave_slope = short_window ? PSY_3GPP_SAVE_SLOPE_S : PSY_3GPP_SAVE_SLOPE_L;
530
2/2
✓ Branch 0 taken 325 times.
✓ Branch 1 taken 9871 times.
10196 const float bitsave_add = short_window ? PSY_3GPP_SAVE_ADD_S : PSY_3GPP_SAVE_ADD_L;
531
2/2
✓ Branch 0 taken 325 times.
✓ Branch 1 taken 9871 times.
10196 const float bitspend_slope = short_window ? PSY_3GPP_SPEND_SLOPE_S : PSY_3GPP_SPEND_SLOPE_L;
532
2/2
✓ Branch 0 taken 325 times.
✓ Branch 1 taken 9871 times.
10196 const float bitspend_add = short_window ? PSY_3GPP_SPEND_ADD_S : PSY_3GPP_SPEND_ADD_L;
533 10196 const float clip_low = short_window ? PSY_3GPP_CLIP_LO_S : PSY_3GPP_CLIP_LO_L;
534
2/2
✓ Branch 0 taken 325 times.
✓ Branch 1 taken 9871 times.
10196 const float clip_high = short_window ? PSY_3GPP_CLIP_HI_S : PSY_3GPP_CLIP_HI_L;
535 float clipped_pe, bit_save, bit_spend, bit_factor, fill_level, forgetful_min_pe;
536
537 10196 ctx->fill_level += ctx->frame_bits - bits;
538 10196 ctx->fill_level = av_clip(ctx->fill_level, 0, size);
539 10196 fill_level = av_clipf((float)ctx->fill_level / size, clip_low, clip_high);
540 10196 clipped_pe = av_clipf(pe, ctx->pe.min, ctx->pe.max);
541 10196 bit_save = (fill_level + bitsave_add) * bitsave_slope;
542 assert(bit_save <= 0.3f && bit_save >= -0.05000001f);
543 10196 bit_spend = (fill_level + bitspend_add) * bitspend_slope;
544 assert(bit_spend <= 0.5f && bit_spend >= -0.1f);
545 /* The bit factor graph in the spec is obviously incorrect.
546 * bit_spend + ((bit_spend - bit_spend))...
547 * The reference encoder subtracts everything from 1, but also seems incorrect.
548 * 1 - bit_save + ((bit_spend + bit_save))...
549 * Hopefully below is correct.
550 */
551 10196 bit_factor = 1.0f - bit_save + ((bit_spend - bit_save) / (ctx->pe.max - ctx->pe.min)) * (clipped_pe - ctx->pe.min);
552 /* NOTE: The reference encoder attempts to center pe max/min around the current pe.
553 * Here we do that by slowly forgetting pe.min when pe stays in a range that makes
554 * it unlikely (ie: above the mean)
555 */
556
2/2
✓ Branch 0 taken 55 times.
✓ Branch 1 taken 10141 times.
10196 ctx->pe.max = FFMAX(pe, ctx->pe.max);
557 20392 forgetful_min_pe = ((ctx->pe.min * PSY_PE_FORGET_SLOPE)
558
2/2
✓ Branch 0 taken 3305 times.
✓ Branch 1 taken 6891 times.
10196 + FFMAX(ctx->pe.min, pe * (pe / ctx->pe.max))) / (PSY_PE_FORGET_SLOPE + 1);
559
2/2
✓ Branch 0 taken 10172 times.
✓ Branch 1 taken 24 times.
10196 ctx->pe.min = FFMIN(pe, forgetful_min_pe);
560
561 /* NOTE: allocate a minimum of 1/8th average frame bits, to avoid
562 * reservoir starvation from producing zero-bit frames
563 */
564
6/6
✓ Branch 0 taken 10182 times.
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 1156 times.
✓ Branch 3 taken 9040 times.
✓ Branch 4 taken 1142 times.
✓ Branch 5 taken 14 times.
10196 return FFMIN(
565 ctx->frame_bits * bit_factor,
566 FFMAX(ctx->frame_bits + size - bits, ctx->frame_bits / 8));
567 }
568
569 1760255 static float calc_pe_3gpp(AacPsyBand *band)
570 {
571 float pe, a;
572
573 1760255 band->pe = 0.0f;
574 1760255 band->pe_const = 0.0f;
575 1760255 band->active_lines = 0.0f;
576
2/2
✓ Branch 0 taken 1733055 times.
✓ Branch 1 taken 27200 times.
1760255 if (band->energy > band->thr) {
577 1733055 a = log2f(band->energy);
578 1733055 pe = a - log2f(band->thr);
579 1733055 band->active_lines = band->nz_lines;
580
2/2
✓ Branch 0 taken 801038 times.
✓ Branch 1 taken 932017 times.
1733055 if (pe < PSY_3GPP_C1) {
581 801038 pe = pe * PSY_3GPP_C3 + PSY_3GPP_C2;
582 801038 a = a * PSY_3GPP_C3 + PSY_3GPP_C2;
583 801038 band->active_lines *= PSY_3GPP_C3;
584 }
585 1733055 band->pe = pe * band->nz_lines;
586 1733055 band->pe_const = a * band->nz_lines;
587 }
588
589 1760255 return band->pe;
590 }
591
592 26749 static float calc_reduction_3gpp(float a, float desired_pe, float pe,
593 float active_lines)
594 {
595 float thr_avg, reduction;
596
597
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 26745 times.
26749 if(active_lines == 0.0)
598 4 return 0;
599
600 26745 thr_avg = exp2f((a - pe) / (4.0f * active_lines));
601 26745 reduction = exp2f((a - desired_pe) / (4.0f * active_lines)) - thr_avg;
602
603
2/2
✓ Branch 0 taken 23058 times.
✓ Branch 1 taken 3687 times.
26745 return FFMAX(reduction, 0.0f);
604 }
605
606 1240176 static float calc_reduced_thr_3gpp(AacPsyBand *band, float min_snr,
607 float reduction)
608 {
609 1240176 float thr = band->thr;
610
611
2/2
✓ Branch 0 taken 1221567 times.
✓ Branch 1 taken 18609 times.
1240176 if (band->energy > thr) {
612 1221567 thr = sqrtf(thr);
613 1221567 thr = sqrtf(thr) + reduction;
614 1221567 thr *= thr;
615 1221567 thr *= thr;
616
617 /* This deviates from the 3GPP spec to match the reference encoder.
618 * It performs min(thr_reduced, max(thr, energy/min_snr)) only for bands
619 * that have hole avoidance on (active or inactive). It always reduces the
620 * threshold of bands with hole avoidance off.
621 */
622
4/4
✓ Branch 0 taken 354551 times.
✓ Branch 1 taken 867016 times.
✓ Branch 2 taken 354483 times.
✓ Branch 3 taken 68 times.
1221567 if (thr > band->energy * min_snr && band->avoid_holes != PSY_3GPP_AH_NONE) {
623
2/2
✓ Branch 0 taken 5955 times.
✓ Branch 1 taken 348528 times.
354483 thr = FFMAX(band->thr, band->energy * min_snr);
624 354483 band->avoid_holes = PSY_3GPP_AH_ACTIVE;
625 }
626 }
627
628 1240176 return thr;
629 }
630
631 10196 static void calc_thr_3gpp(const FFPsyWindowInfo *wi, const int num_bands, AacPsyChannel *pch,
632 const uint8_t *band_sizes, const float *coefs, const int cutoff)
633 {
634 int i, w, g;
635 10196 int start = 0, wstart = 0;
636
2/2
✓ Branch 0 taken 12471 times.
✓ Branch 1 taken 10196 times.
22667 for (w = 0; w < wi->num_windows*16; w += 16) {
637 12471 wstart = 0;
638
2/2
✓ Branch 0 taken 520079 times.
✓ Branch 1 taken 12471 times.
532550 for (g = 0; g < num_bands; g++) {
639 520079 AacPsyBand *band = &pch->band[w+g];
640
641 520079 float form_factor = 0.0f;
642 float Temp;
643 520079 band->energy = 0.0f;
644
2/2
✓ Branch 0 taken 515105 times.
✓ Branch 1 taken 4974 times.
520079 if (wstart < cutoff) {
645
2/2
✓ Branch 0 taken 10193344 times.
✓ Branch 1 taken 515105 times.
10708449 for (i = 0; i < band_sizes[g]; i++) {
646 10193344 band->energy += coefs[start+i] * coefs[start+i];
647 10193344 form_factor += sqrtf(fabs(coefs[start+i]));
648 }
649 }
650
2/2
✓ Branch 0 taken 513989 times.
✓ Branch 1 taken 6090 times.
520079 Temp = band->energy > 0 ? sqrtf((float)band_sizes[g] / band->energy) : 0;
651 520079 band->thr = band->energy * 0.001258925f;
652 520079 band->nz_lines = form_factor * sqrtf(Temp);
653
654 520079 start += band_sizes[g];
655 520079 wstart += band_sizes[g];
656 }
657 }
658 10196 }
659
660 6934 static void psy_hp_filter(const float *firbuf, float *hpfsmpl, const float *psy_fir_coeffs)
661 {
662 int i, j;
663
2/2
✓ Branch 0 taken 7100416 times.
✓ Branch 1 taken 6934 times.
7107350 for (i = 0; i < AAC_BLOCK_SIZE_LONG; i++) {
664 float sum1, sum2;
665 7100416 sum1 = firbuf[i + (PSY_LAME_FIR_LEN - 1) / 2];
666 7100416 sum2 = 0.0;
667
2/2
✓ Branch 0 taken 35502080 times.
✓ Branch 1 taken 7100416 times.
42602496 for (j = 0; j < ((PSY_LAME_FIR_LEN - 1) / 2) - 1; j += 2) {
668 35502080 sum1 += psy_fir_coeffs[j] * (firbuf[i + j] + firbuf[i + PSY_LAME_FIR_LEN - j]);
669 35502080 sum2 += psy_fir_coeffs[j + 1] * (firbuf[i + j + 1] + firbuf[i + PSY_LAME_FIR_LEN - j - 1]);
670 }
671 /* NOTE: The LAME psymodel expects it's input in the range -32768 to 32768.
672 * Tuning this for normalized floats would be difficult. */
673 7100416 hpfsmpl[i] = (sum1 + sum2) * 32768.0f;
674 }
675 6934 }
676
677 /**
678 * Calculate band thresholds as suggested in 3GPP TS26.403
679 */
680 10196 static void psy_3gpp_analyze_channel(FFPsyContext *ctx, int channel,
681 const float *coefs, const FFPsyWindowInfo *wi)
682 {
683 10196 AacPsyContext *pctx = (AacPsyContext*) ctx->model_priv_data;
684 10196 AacPsyChannel *pch = &pctx->ch[channel];
685 int i, w, g;
686 10196 float desired_bits, desired_pe, delta_pe, reduction= NAN, spread_en[128] = {0};
687 10196 float a = 0.0f, active_lines = 0.0f, norm_fac = 0.0f;
688
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 10196 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
10196 float pe = pctx->chan_bitrate > 32000 ? 0.0f : FFMAX(50.0f, 100.0f - pctx->chan_bitrate * 100.0f / 32000.0f);
689
2/2
✓ Branch 0 taken 325 times.
✓ Branch 1 taken 9871 times.
10196 const int num_bands = ctx->num_bands[wi->num_windows == 8];
690
2/2
✓ Branch 0 taken 325 times.
✓ Branch 1 taken 9871 times.
10196 const uint8_t *band_sizes = ctx->bands[wi->num_windows == 8];
691 10196 uint8_t s2l[16] = {0};
692
2/2
✓ Branch 0 taken 325 times.
✓ Branch 1 taken 9871 times.
10521 int start_after_long = wi->num_windows == 8 &&
693
2/2
✓ Branch 0 taken 290 times.
✓ Branch 1 taken 35 times.
325 wi->window_type[1] == LONG_START_SEQUENCE;
694 { /* short->long grid band map for cross-transition pre-echo control */
695
2/2
✓ Branch 0 taken 290 times.
✓ Branch 1 taken 9906 times.
10196 if (start_after_long) {
696 290 const uint8_t *ls = ctx->bands[0];
697 290 const int ln = ctx->num_bands[0];
698 290 const uint8_t *ss = ctx->bands[1];
699 290 int lacc = 0, sacc = 0, gl = 0;
700
3/4
✓ Branch 0 taken 4060 times.
✓ Branch 1 taken 290 times.
✓ Branch 2 taken 4060 times.
✗ Branch 3 not taken.
4350 for (int gs = 0; gs < num_bands && gs < 16; gs++) {
701 4060 int center8 = (sacc + ss[gs] / 2) * 8;
702
4/4
✓ Branch 0 taken 17690 times.
✓ Branch 1 taken 290 times.
✓ Branch 2 taken 13920 times.
✓ Branch 3 taken 3770 times.
17980 while (gl < ln - 1 && lacc + ls[gl] <= center8) { lacc += ls[gl]; gl++; }
703 4060 s2l[gs] = gl;
704 4060 sacc += ss[gs];
705 }
706 }
707 }
708 10196 AacPsyCoeffs *coeffs = pctx->psy_coef[wi->num_windows == 8];
709
2/2
✓ Branch 0 taken 325 times.
✓ Branch 1 taken 9871 times.
10196 const float avoid_hole_thr = wi->num_windows == 8 ? PSY_3GPP_AH_THR_SHORT : PSY_3GPP_AH_THR_LONG;
710
1/8
✓ Branch 0 taken 10196 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
10196 const int bandwidth = ctx->cutoff ? ctx->cutoff : AAC_CUTOFF(ctx->avctx);
711 10196 const int cutoff = bandwidth * 2048 / wi->num_windows / ctx->avctx->sample_rate;
712
713 //calculate energies, initial thresholds and related values - 5.4.2 "Threshold Calculation"
714 10196 calc_thr_3gpp(wi, num_bands, pch, band_sizes, coefs, cutoff);
715
716 //modify thresholds and energies - spread, threshold in quiet, pre-echo control
717
2/2
✓ Branch 0 taken 12471 times.
✓ Branch 1 taken 10196 times.
22667 for (w = 0; w < wi->num_windows*16; w += 16) {
718 12471 AacPsyBand *bands = &pch->band[w];
719
720 /* 5.4.2.3 "Spreading" & 5.4.3 "Spread Energy Calculation" */
721 12471 spread_en[0] = bands[0].energy;
722
2/2
✓ Branch 0 taken 507608 times.
✓ Branch 1 taken 12471 times.
520079 for (g = 1; g < num_bands; g++) {
723
2/2
✓ Branch 0 taken 500940 times.
✓ Branch 1 taken 6668 times.
507608 bands[g].thr = FFMAX(bands[g].thr, bands[g-1].thr * coeffs[g].spread_hi[0]);
724
2/2
✓ Branch 0 taken 501435 times.
✓ Branch 1 taken 6173 times.
507608 spread_en[w+g] = FFMAX(bands[g].energy, spread_en[w+g-1] * coeffs[g].spread_hi[1]);
725 }
726
2/2
✓ Branch 0 taken 507608 times.
✓ Branch 1 taken 12471 times.
520079 for (g = num_bands - 2; g >= 0; g--) {
727
2/2
✓ Branch 0 taken 503515 times.
✓ Branch 1 taken 4093 times.
507608 bands[g].thr = FFMAX(bands[g].thr, bands[g+1].thr * coeffs[g].spread_low[0]);
728
2/2
✓ Branch 0 taken 500764 times.
✓ Branch 1 taken 6844 times.
507608 spread_en[w+g] = FFMAX(spread_en[w+g], spread_en[w+g+1] * coeffs[g].spread_low[1]);
729 }
730 //5.4.2.4 "Threshold in quiet"
731
2/2
✓ Branch 0 taken 520079 times.
✓ Branch 1 taken 12471 times.
532550 for (g = 0; g < num_bands; g++) {
732 520079 AacPsyBand *band = &bands[g];
733
734
2/2
✓ Branch 0 taken 383288 times.
✓ Branch 1 taken 136791 times.
520079 band->thr_quiet = band->thr = FFMAX(band->thr, coeffs[g].ath);
735 //5.4.2.5 "Pre-echo control"
736
6/6
✓ Branch 0 taken 504399 times.
✓ Branch 1 taken 15680 times.
✓ Branch 2 taken 472549 times.
✓ Branch 3 taken 31850 times.
✓ Branch 4 taken 468489 times.
✓ Branch 5 taken 4060 times.
520079 if (!(wi->window_type[0] == LONG_STOP_SEQUENCE || (!w && wi->window_type[1] == LONG_START_SEQUENCE)))
737
6/6
✓ Branch 0 taken 83537 times.
✓ Branch 1 taken 416802 times.
✓ Branch 2 taken 23026 times.
✓ Branch 3 taken 477313 times.
✓ Branch 4 taken 60511 times.
✓ Branch 5 taken 416802 times.
500339 band->thr = FFMAX(PSY_3GPP_RPEMIN*band->thr, FFMIN(band->thr,
738 PSY_3GPP_RPELEV*pch->prev_band[w+g].thr_quiet));
739
3/4
✓ Branch 0 taken 19740 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4060 times.
✓ Branch 3 taken 15680 times.
19740 else if (!w && start_after_long)
740 /* w0 after a START frame: grid-mapped, scaled continuity
741 * clamp instead of the spec's skip (cannot bind on noise
742 * content - see memory - but correct for tonal) */
743
6/6
✓ Branch 0 taken 251 times.
✓ Branch 1 taken 3809 times.
✓ Branch 2 taken 153 times.
✓ Branch 3 taken 3907 times.
✓ Branch 4 taken 98 times.
✓ Branch 5 taken 3809 times.
4060 band->thr = FFMAX(PSY_3GPP_RPEMIN*band->thr, FFMIN(band->thr,
744 PSY_3GPP_RPELEV*pch->prev_band[s2l[FFMIN(g,15)]].thr / 8.0f));
745
746 /* 5.6.1.3.1 "Preparatory steps of the perceptual entropy calculation" */
747 520079 pe += calc_pe_3gpp(band);
748 520079 a += band->pe_const;
749 520079 active_lines += band->active_lines;
750
751 /* 5.6.1.3.3 "Selection of the bands for avoidance of holes" */
752
3/4
✓ Branch 0 taken 519973 times.
✓ Branch 1 taken 106 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 519973 times.
520079 if (spread_en[w+g] * avoid_hole_thr > band->energy || coeffs[g].min_snr > 1.0f)
753 106 band->avoid_holes = PSY_3GPP_AH_NONE;
754 else
755 519973 band->avoid_holes = PSY_3GPP_AH_INACTIVE;
756 }
757 }
758
759 /* 5.6.1.3.2 "Calculation of the desired perceptual entropy" */
760 10196 ctx->ch[channel].entropy = pe;
761
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10196 times.
10196 if (ctx->avctx->flags & AV_CODEC_FLAG_QSCALE) {
762 /* (2.5 * 120) achieves almost transparent rate, and we want to give
763 * ample room downwards, so we make that equivalent to QSCALE=2.4
764 */
765 desired_pe = pe * (ctx->avctx->global_quality ? ctx->avctx->global_quality : 120) / (2 * 2.5f * 120.0f);
766 desired_bits = FFMIN(2560, PSY_3GPP_PE_TO_BITS(desired_pe));
767 desired_pe = PSY_3GPP_BITS_TO_PE(desired_bits); // reflect clipping
768
769 /* PE slope smoothing */
770 if (ctx->bitres.bits > 0) {
771 desired_bits = FFMIN(2560, PSY_3GPP_PE_TO_BITS(desired_pe));
772 desired_pe = PSY_3GPP_BITS_TO_PE(desired_bits); // reflect clipping
773 }
774
775 pctx->pe.max = FFMAX(pe, pctx->pe.max);
776 pctx->pe.min = FFMIN(pe, pctx->pe.min);
777 } else {
778 10196 desired_bits = calc_bit_demand(pctx, pe, ctx->bitres.bits, ctx->bitres.size, wi->num_windows == 8);
779 10196 desired_pe = PSY_3GPP_BITS_TO_PE(desired_bits);
780
781 /* NOTE: PE correction is kept simple. During initial testing it had very
782 * little effect on the final bitrate. Probably a good idea to come
783 * back and do more testing later.
784 */
785
2/2
✓ Branch 0 taken 10049 times.
✓ Branch 1 taken 147 times.
10196 if (ctx->bitres.bits > 0)
786 10049 desired_pe *= av_clipf(pctx->pe.previous / PSY_3GPP_BITS_TO_PE(ctx->bitres.bits),
787 0.85f, 1.15f);
788 }
789 10196 pctx->pe.previous = PSY_3GPP_BITS_TO_PE(desired_bits);
790 10196 ctx->bitres.alloc = desired_bits;
791
792
2/2
✓ Branch 0 taken 10172 times.
✓ Branch 1 taken 24 times.
10196 if (desired_pe < pe) {
793 /* 5.6.1.3.4 "First Estimation of the reduction value" */
794
2/2
✓ Branch 0 taken 12447 times.
✓ Branch 1 taken 10172 times.
22619 for (w = 0; w < wi->num_windows*16; w += 16) {
795 12447 reduction = calc_reduction_3gpp(a, desired_pe, pe, active_lines);
796 12447 pe = 0.0f;
797 12447 a = 0.0f;
798 12447 active_lines = 0.0f;
799
2/2
✓ Branch 0 taken 518903 times.
✓ Branch 1 taken 12447 times.
531350 for (g = 0; g < num_bands; g++) {
800 518903 AacPsyBand *band = &pch->band[w+g];
801
802 518903 band->thr = calc_reduced_thr_3gpp(band, coeffs[g].min_snr, reduction);
803 /* recalculate PE */
804 518903 pe += calc_pe_3gpp(band);
805 518903 a += band->pe_const;
806 518903 active_lines += band->active_lines;
807 }
808 }
809
810 /* 5.6.1.3.5 "Second Estimation of the reduction value" */
811
2/2
✓ Branch 0 taken 14302 times.
✓ Branch 1 taken 4130 times.
18432 for (i = 0; i < 2; i++) {
812 14302 float pe_no_ah = 0.0f, desired_pe_no_ah;
813 14302 active_lines = a = 0.0f;
814
2/2
✓ Branch 0 taken 16577 times.
✓ Branch 1 taken 14302 times.
30879 for (w = 0; w < wi->num_windows*16; w += 16) {
815
2/2
✓ Branch 0 taken 721273 times.
✓ Branch 1 taken 16577 times.
737850 for (g = 0; g < num_bands; g++) {
816 721273 AacPsyBand *band = &pch->band[w+g];
817
818
2/2
✓ Branch 0 taken 581779 times.
✓ Branch 1 taken 139494 times.
721273 if (band->avoid_holes != PSY_3GPP_AH_ACTIVE) {
819 581779 pe_no_ah += band->pe;
820 581779 a += band->pe_const;
821 581779 active_lines += band->active_lines;
822 }
823 }
824 }
825
2/2
✓ Branch 0 taken 14237 times.
✓ Branch 1 taken 65 times.
14302 desired_pe_no_ah = FFMAX(desired_pe - (pe - pe_no_ah), 0.0f);
826
1/2
✓ Branch 0 taken 14302 times.
✗ Branch 1 not taken.
14302 if (active_lines > 0.0f)
827 14302 reduction = calc_reduction_3gpp(a, desired_pe_no_ah, pe_no_ah, active_lines);
828
829 14302 pe = 0.0f;
830
2/2
✓ Branch 0 taken 16577 times.
✓ Branch 1 taken 14302 times.
30879 for (w = 0; w < wi->num_windows*16; w += 16) {
831
2/2
✓ Branch 0 taken 721273 times.
✓ Branch 1 taken 16577 times.
737850 for (g = 0; g < num_bands; g++) {
832 721273 AacPsyBand *band = &pch->band[w+g];
833
834
1/2
✓ Branch 0 taken 721273 times.
✗ Branch 1 not taken.
721273 if (active_lines > 0.0f)
835 721273 band->thr = calc_reduced_thr_3gpp(band, coeffs[g].min_snr, reduction);
836 721273 pe += calc_pe_3gpp(band);
837
1/2
✓ Branch 0 taken 721273 times.
✗ Branch 1 not taken.
721273 if (band->thr > 0.0f)
838 721273 band->norm_fac = band->active_lines / band->thr;
839 else
840 band->norm_fac = 0.0f;
841 721273 norm_fac += band->norm_fac;
842 }
843 }
844 14302 delta_pe = desired_pe - pe;
845
2/2
✓ Branch 0 taken 6042 times.
✓ Branch 1 taken 8260 times.
14302 if (fabs(delta_pe) > 0.05f * desired_pe)
846 6042 break;
847 }
848
849
2/2
✓ Branch 0 taken 5825 times.
✓ Branch 1 taken 4347 times.
10172 if (pe < 1.15f * desired_pe) {
850 /* 6.6.1.3.6 "Final threshold modification by linearization" */
851
1/2
✓ Branch 0 taken 5825 times.
✗ Branch 1 not taken.
5825 norm_fac = norm_fac ? 1.0f / norm_fac : 0;
852
2/2
✓ Branch 0 taken 5825 times.
✓ Branch 1 taken 5825 times.
11650 for (w = 0; w < wi->num_windows*16; w += 16) {
853
2/2
✓ Branch 0 taken 285425 times.
✓ Branch 1 taken 5825 times.
291250 for (g = 0; g < num_bands; g++) {
854 285425 AacPsyBand *band = &pch->band[w+g];
855
856
2/2
✓ Branch 0 taken 281524 times.
✓ Branch 1 taken 3901 times.
285425 if (band->active_lines > 0.5f) {
857 281524 float delta_sfb_pe = band->norm_fac * norm_fac * delta_pe;
858 281524 float thr = band->thr;
859
860 281524 thr *= exp2f(delta_sfb_pe / band->active_lines);
861
4/4
✓ Branch 0 taken 28511 times.
✓ Branch 1 taken 253013 times.
✓ Branch 2 taken 93 times.
✓ Branch 3 taken 28418 times.
281524 if (thr > coeffs[g].min_snr * band->energy && band->avoid_holes == PSY_3GPP_AH_INACTIVE)
862
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 93 times.
93 thr = FFMAX(band->thr, coeffs[g].min_snr * band->energy);
863 281524 band->thr = thr;
864 }
865 }
866 }
867 } else {
868 /* 5.6.1.3.7 "Further perceptual entropy reduction" */
869 4347 g = num_bands;
870
4/4
✓ Branch 0 taken 205520 times.
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 201189 times.
✓ Branch 3 taken 4331 times.
205536 while (pe > desired_pe && g--) {
871
2/2
✓ Branch 0 taken 233039 times.
✓ Branch 1 taken 201189 times.
434228 for (w = 0; w < wi->num_windows*16; w+= 16) {
872 233039 AacPsyBand *band = &pch->band[w+g];
873
4/4
✓ Branch 0 taken 232987 times.
✓ Branch 1 taken 52 times.
✓ Branch 2 taken 657 times.
✓ Branch 3 taken 232330 times.
233039 if (band->avoid_holes != PSY_3GPP_AH_NONE && coeffs[g].min_snr < PSY_SNR_1DB) {
874 657 coeffs[g].min_snr = PSY_SNR_1DB;
875 657 band->thr = band->energy * PSY_SNR_1DB;
876 657 pe += band->active_lines * 1.5f - band->pe;
877 }
878 }
879 }
880 /* TODO: allow more holes (unused without mid/side) */
881 }
882 }
883
884
2/2
✓ Branch 0 taken 12471 times.
✓ Branch 1 taken 10196 times.
22667 for (w = 0; w < wi->num_windows*16; w += 16) {
885
2/2
✓ Branch 0 taken 520079 times.
✓ Branch 1 taken 12471 times.
532550 for (g = 0; g < num_bands; g++) {
886 520079 AacPsyBand *band = &pch->band[w+g];
887 520079 FFPsyBand *psy_band = &ctx->ch[channel].psy_bands[w+g];
888
889 520079 psy_band->threshold = band->thr;
890 520079 psy_band->energy = band->energy;
891 520079 psy_band->spread = band->active_lines * 2.0f / band_sizes[g];
892 520079 psy_band->bits = PSY_3GPP_PE_TO_BITS(band->pe);
893 }
894 }
895
896 10196 memcpy(pch->prev_band, pch->band, sizeof(pch->band));
897 10196 }
898
899 5511 static void psy_3gpp_analyze(FFPsyContext *ctx, int channel,
900 const float **coeffs, const FFPsyWindowInfo *wi)
901 {
902 int ch;
903 5511 FFPsyChannelGroup *group = ff_psy_find_group(ctx, channel);
904 5511 AacPsyContext *pctx = ctx->model_priv_data;
905
906 /* The encoder's rate-control loop may re-run the analysis for the same
907 * frame; carried state (bit reservoir, PE history, previous-frame
908 * thresholds) must advance exactly once per frame, so save it on the
909 * frame's first run and rewind on re-runs. */
910
2/2
✓ Branch 0 taken 3492 times.
✓ Branch 1 taken 2019 times.
5511 if (ctx->avctx->frame_num != pctx->rc_frame_num) {
911 3492 pctx->rc_frame_num = ctx->avctx->frame_num;
912 3492 pctx->rc_first_ch = channel;
913 3492 pctx->rc_fill_level = pctx->fill_level;
914 3492 pctx->rc_pe_min = pctx->pe.min;
915 3492 pctx->rc_pe_max = pctx->pe.max;
916 3492 pctx->rc_pe_previous = pctx->pe.previous;
917
2/2
✓ Branch 0 taken 1395 times.
✓ Branch 1 taken 624 times.
2019 } else if (channel == pctx->rc_first_ch) {
918 1395 pctx->fill_level = pctx->rc_fill_level;
919 1395 pctx->pe.min = pctx->rc_pe_min;
920 1395 pctx->pe.max = pctx->rc_pe_max;
921 1395 pctx->pe.previous = pctx->rc_pe_previous;
922 }
923
924
2/2
✓ Branch 0 taken 10196 times.
✓ Branch 1 taken 5511 times.
15707 for (ch = 0; ch < group->num_ch; ch++) {
925 10196 AacPsyChannel *pch = &pctx->ch[channel + ch];
926
2/2
✓ Branch 0 taken 7270 times.
✓ Branch 1 taken 2926 times.
10196 if (ctx->avctx->frame_num != pch->rc_frame_num) {
927 7270 pch->rc_frame_num = ctx->avctx->frame_num;
928 7270 memcpy(pch->rc_prev_band, pch->prev_band, sizeof(pch->prev_band));
929 } else {
930 2926 memcpy(pch->prev_band, pch->rc_prev_band, sizeof(pch->prev_band));
931 }
932 10196 psy_3gpp_analyze_channel(ctx, channel + ch, coeffs[ch], &wi[ch]);
933 }
934 5511 }
935
936 23 static av_cold void psy_3gpp_end(FFPsyContext *apc)
937 {
938 23 AacPsyContext *pctx = (AacPsyContext*) apc->model_priv_data;
939
1/2
✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
23 if (pctx)
940 23 av_freep(&pctx->ch);
941 23 av_freep(&apc->model_priv_data);
942 23 }
943
944 7150 static void lame_apply_block_type(AacPsyChannel *ctx, FFPsyWindowInfo *wi, int uselongblock)
945 {
946 7150 int blocktype = ONLY_LONG_SEQUENCE;
947
2/2
✓ Branch 0 taken 6837 times.
✓ Branch 1 taken 313 times.
7150 if (uselongblock) {
948
2/2
✓ Branch 0 taken 278 times.
✓ Branch 1 taken 6559 times.
6837 if (ctx->next_window_seq == EIGHT_SHORT_SEQUENCE)
949 278 blocktype = LONG_STOP_SEQUENCE;
950 } else {
951 313 blocktype = EIGHT_SHORT_SEQUENCE;
952
2/2
✓ Branch 0 taken 278 times.
✓ Branch 1 taken 35 times.
313 if (ctx->next_window_seq == ONLY_LONG_SEQUENCE)
953 278 ctx->next_window_seq = LONG_START_SEQUENCE;
954
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 313 times.
313 if (ctx->next_window_seq == LONG_STOP_SEQUENCE)
955 ctx->next_window_seq = EIGHT_SHORT_SEQUENCE;
956 }
957
958 7150 wi->window_type[0] = ctx->next_window_seq;
959 7150 ctx->next_window_seq = blocktype;
960 7150 }
961
962 /* Attack detection half of the LAME window decision: everything up to (and
963 * excluding) the block-type state machine. Fills attacks[] and returns the raw
964 * uselongblock; mutates only the detection history. Split out so a channel
965 * pair can be detected first and DECIDED together (synced block switching). */
966 7150 static int psy_lame_detect(AacPsyContext *pctx, AacPsyChannel *pch,
967 const float *la, int channel, int prev_type,
968 int attacks[AAC_NUM_BLOCKS_SHORT + 1])
969 {
970 7150 int uselongblock = 1;
971 int i;
972
973
2/2
✓ Branch 0 taken 6934 times.
✓ Branch 1 taken 216 times.
7150 if (la) {
974 float hpfsmpl[AAC_BLOCK_SIZE_LONG];
975 6934 const float *pf = hpfsmpl;
976 float attack_intensity[(AAC_NUM_BLOCKS_SHORT + 1) * PSY_LAME_NUM_SUBBLOCKS];
977 float energy_subshort[(AAC_NUM_BLOCKS_SHORT + 1) * PSY_LAME_NUM_SUBBLOCKS];
978 6934 float energy_short[AAC_NUM_BLOCKS_SHORT + 1] = { 0 };
979 6934 const float *firbuf = la + (AAC_BLOCK_SIZE_SHORT/4 - PSY_LAME_FIR_LEN);
980 6934 int att_sum = 0;
981
982 /* LAME comment: apply high pass filter of fs/4 */
983 6934 psy_hp_filter(firbuf, hpfsmpl, psy_fir_coeffs);
984
985 /* Calculate the energies of each sub-shortblock */
986
2/2
✓ Branch 0 taken 13868 times.
✓ Branch 1 taken 6934 times.
20802 for (i = 0; i < PSY_LAME_NUM_SUBBLOCKS; i++) {
987 13868 energy_subshort[i] = pch->prev_energy_subshort[i + ((AAC_NUM_BLOCKS_SHORT - 1) * PSY_LAME_NUM_SUBBLOCKS)];
988 assert(pch->prev_energy_subshort[i + ((AAC_NUM_BLOCKS_SHORT - 1) * PSY_LAME_NUM_SUBBLOCKS - 2)] > 0);
989 13868 attack_intensity[i] = energy_subshort[i] / pch->prev_energy_subshort[i + ((AAC_NUM_BLOCKS_SHORT - 1) * PSY_LAME_NUM_SUBBLOCKS - 2)];
990 13868 energy_short[0] += energy_subshort[i];
991 }
992
993
2/2
✓ Branch 0 taken 110944 times.
✓ Branch 1 taken 6934 times.
117878 for (i = 0; i < AAC_NUM_BLOCKS_SHORT * PSY_LAME_NUM_SUBBLOCKS; i++) {
994 110944 const float *const pfe = pf + AAC_BLOCK_SIZE_LONG / (AAC_NUM_BLOCKS_SHORT * PSY_LAME_NUM_SUBBLOCKS);
995 110944 float p = 1.0f;
996
2/2
✓ Branch 0 taken 7100416 times.
✓ Branch 1 taken 110944 times.
7211360 for (; pf < pfe; pf++)
997
2/2
✓ Branch 0 taken 6475032 times.
✓ Branch 1 taken 625384 times.
7100416 p = FFMAX(p, fabsf(*pf));
998 110944 pch->prev_energy_subshort[i] = energy_subshort[i + PSY_LAME_NUM_SUBBLOCKS] = p;
999 110944 energy_short[1 + i / PSY_LAME_NUM_SUBBLOCKS] += p;
1000
1001 /* NOTE: The indexes below are [i + 3 - 2] in the LAME source. Compare each sub-block to sub-block - 2 */
1002
2/2
✓ Branch 0 taken 55448 times.
✓ Branch 1 taken 55496 times.
110944 if (p > energy_subshort[i + PSY_LAME_NUM_SUBBLOCKS - 2])
1003 55448 p = p / energy_subshort[i + PSY_LAME_NUM_SUBBLOCKS - 2];
1004
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 55440 times.
55496 else if (energy_subshort[i + PSY_LAME_NUM_SUBBLOCKS - 2] > p * 10.0f)
1005 56 p = energy_subshort[i + PSY_LAME_NUM_SUBBLOCKS - 2] / (p * 10.0f);
1006 else
1007 55440 p = 0.0;
1008
1009 110944 attack_intensity[i + PSY_LAME_NUM_SUBBLOCKS] = p;
1010 }
1011
1012 { /* pre-echo-aware threshold relaxation + periodicity/novelty check
1013 * (a pulse train repeats its peak; a real onset towers) */
1014 6934 float frame_peak = 1.0f;
1015 float env[PSY_LAME_HIST + AAC_NUM_BLOCKS_SHORT * PSY_LAME_NUM_SUBBLOCKS];
1016 6934 const float nov_gate = 1.25f;
1017 6934 memcpy(env, pch->hp_env_hist, sizeof(pch->hp_env_hist));
1018 6934 memcpy(env + PSY_LAME_HIST, energy_subshort + PSY_LAME_NUM_SUBBLOCKS,
1019 AAC_NUM_BLOCKS_SHORT * PSY_LAME_NUM_SUBBLOCKS * sizeof(*env));
1020
2/2
✓ Branch 0 taken 110944 times.
✓ Branch 1 taken 6934 times.
117878 for (i = PSY_LAME_NUM_SUBBLOCKS; i < (AAC_NUM_BLOCKS_SHORT + 1) * PSY_LAME_NUM_SUBBLOCKS; i++)
1021
2/2
✓ Branch 0 taken 83484 times.
✓ Branch 1 taken 27460 times.
110944 frame_peak = FFMAX(frame_peak, energy_subshort[i]);
1022
2/2
✓ Branch 0 taken 124812 times.
✓ Branch 1 taken 6934 times.
131746 for (i = 0; i < (AAC_NUM_BLOCKS_SHORT + 1) * PSY_LAME_NUM_SUBBLOCKS; i++)
1023
2/2
✓ Branch 0 taken 124607 times.
✓ Branch 1 taken 205 times.
124812 if (!attacks[i / PSY_LAME_NUM_SUBBLOCKS]) {
1024 124607 float thr = pch->attack_threshold;
1025
2/2
✓ Branch 0 taken 110754 times.
✓ Branch 1 taken 13853 times.
124607 if (i >= PSY_LAME_NUM_SUBBLOCKS &&
1026
2/2
✓ Branch 0 taken 64255 times.
✓ Branch 1 taken 46499 times.
110754 pch->frames_since_short >= PSY_LAME_PE_GAP &&
1027
2/2
✓ Branch 0 taken 4999 times.
✓ Branch 1 taken 59256 times.
64255 energy_subshort[i - PSY_LAME_NUM_SUBBLOCKS] < PSY_LAME_PE_QUIET * frame_peak)
1028 4999 thr *= PSY_LAME_PE_RED;
1029
2/2
✓ Branch 0 taken 414 times.
✓ Branch 1 taken 124193 times.
124607 if (attack_intensity[i] > thr) {
1030 /* An attack must tower over the recent HP envelope:
1031 * within ~12ms always (pitch-rate trains), within
1032 * ~44ms only from steady long-window state (slow
1033 * pulse trains, where an isolated short excursion
1034 * is an audible click). */
1035
3/4
✓ Branch 0 taken 414 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 388 times.
✓ Branch 3 taken 26 times.
414 if (nov_gate > 0.0f && i >= PSY_LAME_NUM_SUBBLOCKS) {
1036 388 const int pos = PSY_LAME_HIST + i - PSY_LAME_NUM_SUBBLOCKS;
1037 388 float nearmax = 1.0f, deepmax = 1.0f;
1038
2/2
✓ Branch 0 taken 2328 times.
✓ Branch 1 taken 388 times.
2716 for (int k = 3; k <= 8; k++)
1039
2/2
✓ Branch 0 taken 1095 times.
✓ Branch 1 taken 1233 times.
2328 nearmax = FFMAX(nearmax, env[pos - k]);
1040
2/2
✓ Branch 0 taken 10864 times.
✓ Branch 1 taken 388 times.
11252 for (int k = 3; k <= PSY_LAME_NOV_BACK; k++)
1041
2/2
✓ Branch 0 taken 7169 times.
✓ Branch 1 taken 3695 times.
10864 deepmax = FFMAX(deepmax, env[pos - k]);
1042
2/2
✓ Branch 0 taken 268 times.
✓ Branch 1 taken 120 times.
388 if (energy_subshort[i] < nov_gate * nearmax ||
1043
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 247 times.
268 (energy_subshort[i] < nov_gate * deepmax &&
1044
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 pch->frames_since_short >= PSY_LAME_PE_GAP))
1045 141 continue; /* periodic, not an onset */
1046 }
1047 273 attacks[i / PSY_LAME_NUM_SUBBLOCKS] = (i % PSY_LAME_NUM_SUBBLOCKS) + 1;
1048 }
1049 }
1050 }
1051
1052 /* should have energy change between short blocks, in order to avoid periodic signals */
1053 /* Good samples to show the effect are Trumpet test songs */
1054 /* GB: tuned (1) to avoid too many short blocks for test sample TRUMPET */
1055 /* RH: tuned (2) to let enough short blocks through for test sample FSOL and SNAPS */
1056
2/2
✓ Branch 0 taken 55472 times.
✓ Branch 1 taken 6934 times.
62406 for (i = 1; i < AAC_NUM_BLOCKS_SHORT + 1; i++) {
1057 55472 const float u = energy_short[i - 1];
1058 55472 const float v = energy_short[i];
1059
2/2
✓ Branch 0 taken 27922 times.
✓ Branch 1 taken 27550 times.
55472 const float m = FFMAX(u, v);
1060
2/2
✓ Branch 0 taken 53092 times.
✓ Branch 1 taken 2380 times.
55472 if (m < 40000) { /* (2) */
1061
4/4
✓ Branch 0 taken 52767 times.
✓ Branch 1 taken 325 times.
✓ Branch 2 taken 52186 times.
✓ Branch 3 taken 581 times.
53092 if (u < 2.3f * v && v < 2.3f * u) { /* (1) */
1062
3/4
✓ Branch 0 taken 6398 times.
✓ Branch 1 taken 45788 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6398 times.
52186 if (i == 1 && attacks[0] < attacks[i])
1063 attacks[0] = 0;
1064 52186 attacks[i] = 0;
1065 }
1066 }
1067 55472 att_sum += attacks[i];
1068 }
1069
1070 /* roll the HP sub-block peak history */
1071 6934 memmove(pch->hp_env_hist,
1072 6934 pch->hp_env_hist + AAC_NUM_BLOCKS_SHORT * PSY_LAME_NUM_SUBBLOCKS,
1073 (PSY_LAME_HIST - AAC_NUM_BLOCKS_SHORT * PSY_LAME_NUM_SUBBLOCKS) *
1074 sizeof(*pch->hp_env_hist));
1075 6934 memcpy(pch->hp_env_hist + PSY_LAME_HIST - AAC_NUM_BLOCKS_SHORT * PSY_LAME_NUM_SUBBLOCKS,
1076 energy_subshort + PSY_LAME_NUM_SUBBLOCKS,
1077 AAC_NUM_BLOCKS_SHORT * PSY_LAME_NUM_SUBBLOCKS * sizeof(*pch->hp_env_hist));
1078
1079
2/2
✓ Branch 0 taken 6784 times.
✓ Branch 1 taken 150 times.
6934 if (pch->next_attack0_zero)
1080 6784 attacks[0] = 0;
1081 6934 pch->next_attack0_zero = !attacks[AAC_NUM_BLOCKS_SHORT];
1082
1083
2/2
✓ Branch 0 taken 6910 times.
✓ Branch 1 taken 24 times.
6934 if (attacks[0] <= pch->prev_attack)
1084 6910 attacks[0] = 0;
1085
1086 6934 att_sum += attacks[0];
1087
1088 /* If the previous attack happened in the last sub-block of the previous sequence,
1089 * or if there's a new attack, use short window */
1090
4/4
✓ Branch 0 taken 6933 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 218 times.
✓ Branch 3 taken 6715 times.
6934 if (pch->prev_attack == PSY_LAME_NUM_SUBBLOCKS || att_sum) {
1091 219 uselongblock = 0;
1092
1093
2/2
✓ Branch 0 taken 1752 times.
✓ Branch 1 taken 219 times.
1971 for (i = 1; i < AAC_NUM_BLOCKS_SHORT + 1; i++)
1094
3/4
✓ Branch 0 taken 201 times.
✓ Branch 1 taken 1551 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 201 times.
1752 if (attacks[i] && attacks[i-1])
1095 attacks[i] = 0;
1096 }
1097
1098 } else {
1099 /* We have no lookahead info, so just use same type as the previous sequence. */
1100 216 uselongblock = !(prev_type == EIGHT_SHORT_SEQUENCE);
1101 }
1102 7150 return uselongblock;
1103 }
1104
1105 /* Decision half: the block-type state machine and window/grouping fill,
1106 * given the (possibly pair-synced) final uselongblock. */
1107 7150 static FFPsyWindowInfo psy_lame_apply(AacPsyContext *pctx, AacPsyChannel *pch,
1108 int uselongblock,
1109 const int attacks[AAC_NUM_BLOCKS_SHORT + 1],
1110 int prev_type, int have_la)
1111 {
1112 7150 int grouping = 0;
1113 int i;
1114 7150 FFPsyWindowInfo wi = { { 0 } };
1115
1116
2/2
✓ Branch 0 taken 6934 times.
✓ Branch 1 taken 216 times.
7150 if (have_la)
1117
2/2
✓ Branch 0 taken 6621 times.
✓ Branch 1 taken 313 times.
6934 pch->frames_since_short = uselongblock ? pch->frames_since_short + 1 : 0;
1118
1119 7150 lame_apply_block_type(pch, &wi, uselongblock);
1120
1121 7150 wi.window_type[1] = prev_type;
1122
2/2
✓ Branch 0 taken 6837 times.
✓ Branch 1 taken 313 times.
7150 if (wi.window_type[0] != EIGHT_SHORT_SEQUENCE) {
1123
1124 6837 wi.num_windows = 1;
1125 6837 wi.grouping[0] = 1;
1126
2/2
✓ Branch 0 taken 278 times.
✓ Branch 1 taken 6559 times.
6837 if (wi.window_type[0] == LONG_START_SEQUENCE)
1127 278 wi.window_shape = 0;
1128 else
1129 6559 wi.window_shape = 1;
1130
1131 } else {
1132 313 int lastgrp = 0;
1133
1134 313 wi.num_windows = 8;
1135 313 wi.window_shape = 0;
1136
2/2
✓ Branch 0 taken 2504 times.
✓ Branch 1 taken 313 times.
2817 for (i = 0; i < 8; i++) {
1137
2/2
✓ Branch 0 taken 1217 times.
✓ Branch 1 taken 1287 times.
2504 if (!((pch->next_grouping >> i) & 1))
1138 1217 lastgrp = i;
1139 2504 wi.grouping[lastgrp]++;
1140 }
1141 }
1142
1143 /* Determine grouping, based on the location of the first attack, and save for
1144 * the next frame.
1145 * FIXME: Move this to analysis.
1146 * TODO: Tune groupings depending on attack location
1147 * TODO: Handle more than one attack in a group
1148 */
1149
2/2
✓ Branch 0 taken 62728 times.
✓ Branch 1 taken 6838 times.
69566 for (i = 0; i < 9; i++) {
1150
2/2
✓ Branch 0 taken 312 times.
✓ Branch 1 taken 62416 times.
62728 if (attacks[i]) {
1151 312 grouping = i;
1152 312 break;
1153 }
1154 }
1155 7150 pch->next_grouping = window_grouping[grouping];
1156
1157 7150 pch->prev_attack = attacks[AAC_NUM_BLOCKS_SHORT - 1];
1158
1159 7150 return wi;
1160 }
1161
1162 834 static FFPsyWindowInfo psy_lame_window(FFPsyContext *ctx, const float *audio,
1163 const float *la, int channel, int prev_type)
1164 {
1165 834 AacPsyContext *pctx = (AacPsyContext*) ctx->model_priv_data;
1166 834 AacPsyChannel *pch = &pctx->ch[channel];
1167 834 int attacks[AAC_NUM_BLOCKS_SHORT + 1] = { 0 };
1168 834 int uselongblock = psy_lame_detect(pctx, pch, la, channel, prev_type, attacks);
1169
1170 834 return psy_lame_apply(pctx, pch, uselongblock, attacks, prev_type, !!la);
1171 }
1172
1173 /* Pair-synced block switching: either channel's attack switches both. */
1174 3158 static void psy_lame_window_pair(FFPsyContext *ctx,
1175 const float *audio0, const float *la0,
1176 const float *audio1, const float *la1,
1177 int channel0, int channel1,
1178 int prev_type0, int prev_type1,
1179 FFPsyWindowInfo wi[2])
1180 {
1181 3158 AacPsyContext *pctx = (AacPsyContext*) ctx->model_priv_data;
1182 3158 AacPsyChannel *pch0 = &pctx->ch[channel0];
1183 3158 AacPsyChannel *pch1 = &pctx->ch[channel1];
1184 3158 int att0[AAC_NUM_BLOCKS_SHORT + 1] = { 0 };
1185 3158 int att1[AAC_NUM_BLOCKS_SHORT + 1] = { 0 };
1186 int merged[AAC_NUM_BLOCKS_SHORT + 1];
1187 3158 int u0 = psy_lame_detect(pctx, pch0, la0, channel0, prev_type0, att0);
1188 3158 int u1 = psy_lame_detect(pctx, pch1, la1, channel1, prev_type1, att1);
1189
4/4
✓ Branch 0 taken 3046 times.
✓ Branch 1 taken 112 times.
✓ Branch 2 taken 3007 times.
✓ Branch 3 taken 39 times.
3158 int u = u0 && u1;
1190
1191
2/2
✓ Branch 0 taken 159 times.
✓ Branch 1 taken 2999 times.
3158 if (ctx->pair_decoupled[(channel0 >> 1) & 15]) {
1192 /* Joint tools are dead on this pair (encoder-fed state): each channel
1193 * windows for ITS transients - divergence costs nothing there, while
1194 * union-syncing forces the steady channel short at every event in
1195 * the other. Correlated content keeps the sync. */
1196 159 wi[0] = psy_lame_apply(pctx, pch0, u0, att0, prev_type0, !!la0);
1197 159 wi[1] = psy_lame_apply(pctx, pch1, u1, att1, prev_type1, !!la1);
1198 159 return;
1199 }
1200
1201 /* One merged attack map for both channels: the grouping (and with it
1202 * common_window) must match across the pair, and the group boundary
1203 * should isolate the first attack heard in EITHER channel. */
1204
2/2
✓ Branch 0 taken 26991 times.
✓ Branch 1 taken 2999 times.
29990 for (int i = 0; i < AAC_NUM_BLOCKS_SHORT + 1; i++)
1205
2/2
✓ Branch 0 taken 119 times.
✓ Branch 1 taken 26872 times.
26991 merged[i] = att0[i] ? att0[i] : att1[i];
1206
1207 2999 wi[0] = psy_lame_apply(pctx, pch0, u, merged, prev_type0, !!la0);
1208 2999 wi[1] = psy_lame_apply(pctx, pch1, u, merged, prev_type1, !!la1);
1209 }
1210
1211 const FFPsyModel ff_aac_psy_model =
1212 {
1213 .name = "3GPP TS 26.403-inspired model",
1214 .init = psy_3gpp_init,
1215 .window = psy_lame_window,
1216 .analyze = psy_3gpp_analyze,
1217 .end = psy_3gpp_end,
1218 .window_pair = psy_lame_window_pair,
1219 };
1220