Mercurial > libavcodec.hg
annotate aacpsy.c @ 12483:0159a19bfff7 libavcodec
aacdec: Rework channel mapping compatibility hacks.
For a PCE based configuration map the channels solely based on tags.
For an indexed configuration map the channels solely based on position.
This works with all known exotic samples including al17, elem_id0, bad_concat,
and lfe_is_sce.
author | alexc |
---|---|
date | Fri, 10 Sep 2010 18:01:48 +0000 |
parents | 94b578d0af10 |
children |
rev | line source |
---|---|
7606 | 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 /** | |
11644
7dd2a45249a9
Remove explicit filename from Doxygen @file commands.
diego
parents:
9944
diff
changeset
|
23 * @file |
7606 | 24 * AAC encoder psychoacoustic model |
25 */ | |
26 | |
27 #include "avcodec.h" | |
28 #include "aactab.h" | |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
29 #include "psymodel.h" |
7606 | 30 |
31 /*********************************** | |
32 * TODOs: | |
33 * thresholds linearization after their modifications for attaining given bitrate | |
34 * try other bitrate controlling mechanism (maybe use ratecontrol.c?) | |
35 * control quality for quality-based output | |
36 **********************************/ | |
37 | |
38 /** | |
39 * constants for 3GPP AAC psychoacoustic model | |
40 * @{ | |
41 */ | |
42 #define PSY_3GPP_SPREAD_LOW 1.5f // spreading factor for ascending threshold spreading (15 dB/Bark) | |
43 #define PSY_3GPP_SPREAD_HI 3.0f // spreading factor for descending threshold spreading (30 dB/Bark) | |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
44 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
45 #define PSY_3GPP_RPEMIN 0.01f |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
46 #define PSY_3GPP_RPELEV 2.0f |
12408 | 47 |
48 /* LAME psy model constants */ | |
49 #define PSY_LAME_FIR_LEN 21 ///< LAME psy model FIR order | |
50 #define AAC_BLOCK_SIZE_LONG 1024 ///< long block size | |
51 #define AAC_BLOCK_SIZE_SHORT 128 ///< short block size | |
52 #define AAC_NUM_BLOCKS_SHORT 8 ///< number of blocks in a short sequence | |
53 #define PSY_LAME_NUM_SUBBLOCKS 3 ///< Number of sub-blocks in each short block | |
54 | |
7606 | 55 /** |
56 * @} | |
57 */ | |
58 | |
59 /** | |
60 * information for single band used by 3GPP TS26.403-inspired psychoacoustic model | |
61 */ | |
12406 | 62 typedef struct AacPsyBand{ |
7606 | 63 float energy; ///< band energy |
64 float ffac; ///< form factor | |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
65 float thr; ///< energy threshold |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
66 float min_snr; ///< minimal SNR |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
67 float thr_quiet; ///< threshold in quiet |
12406 | 68 }AacPsyBand; |
7606 | 69 |
70 /** | |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
71 * single/pair channel context for psychoacoustic model |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
72 */ |
12406 | 73 typedef struct AacPsyChannel{ |
74 AacPsyBand band[128]; ///< bands information | |
75 AacPsyBand prev_band[128]; ///< bands information from the previous frame | |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
76 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
77 float win_energy; ///< sliding average of channel energy |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
78 float iir_state[2]; ///< hi-pass IIR filter state |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
79 uint8_t next_grouping; ///< stored grouping scheme for the next frame (in case of 8 short window sequence) |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
80 enum WindowSequence next_window_seq; ///< window sequence to be used in the next frame |
12408 | 81 /* LAME psy model specific members */ |
82 float attack_threshold; ///< attack threshold for this channel | |
83 float prev_energy_subshort[AAC_NUM_BLOCKS_SHORT * PSY_LAME_NUM_SUBBLOCKS]; | |
84 int prev_attack; ///< attack value for the last short block in the previous sequence | |
12406 | 85 }AacPsyChannel; |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
86 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
87 /** |
7606 | 88 * psychoacoustic model frame type-dependent coefficients |
89 */ | |
12406 | 90 typedef struct AacPsyCoeffs{ |
7606 | 91 float ath [64]; ///< absolute threshold of hearing per bands |
92 float barks [64]; ///< Bark value for each spectral band in long frame | |
93 float spread_low[64]; ///< spreading factor for low-to-high threshold spreading in long frame | |
94 float spread_hi [64]; ///< spreading factor for high-to-low threshold spreading in long frame | |
12406 | 95 }AacPsyCoeffs; |
7606 | 96 |
97 /** | |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
98 * 3GPP TS26.403-inspired psychoacoustic model specific data |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
99 */ |
12406 | 100 typedef struct AacPsyContext{ |
101 AacPsyCoeffs psy_coef[2]; | |
102 AacPsyChannel *ch; | |
103 }AacPsyContext; | |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
104 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
105 /** |
12408 | 106 * LAME psy model preset struct |
107 */ | |
108 typedef struct { | |
109 int quality; ///< Quality to map the rest of the vaules to. | |
110 /* This is overloaded to be both kbps per channel in ABR mode, and | |
111 * requested quality in constant quality mode. | |
112 */ | |
113 float st_lrm; ///< short threshold for L, R, and M channels | |
114 } PsyLamePreset; | |
115 | |
116 /** | |
117 * LAME psy model preset table for ABR | |
118 */ | |
119 static const PsyLamePreset psy_abr_map[] = { | |
120 /* TODO: Tuning. These were taken from LAME. */ | |
121 /* kbps/ch st_lrm */ | |
122 { 8, 6.60}, | |
123 { 16, 6.60}, | |
124 { 24, 6.60}, | |
125 { 32, 6.60}, | |
126 { 40, 6.60}, | |
127 { 48, 6.60}, | |
128 { 56, 6.60}, | |
129 { 64, 6.40}, | |
130 { 80, 6.00}, | |
131 { 96, 5.60}, | |
132 {112, 5.20}, | |
133 {128, 5.20}, | |
134 {160, 5.20} | |
135 }; | |
136 | |
137 /** | |
138 * LAME psy model preset table for constant quality | |
139 */ | |
140 static const PsyLamePreset psy_vbr_map[] = { | |
141 /* vbr_q st_lrm */ | |
142 { 0, 4.20}, | |
143 { 1, 4.20}, | |
144 { 2, 4.20}, | |
145 { 3, 4.20}, | |
146 { 4, 4.20}, | |
147 { 5, 4.20}, | |
148 { 6, 4.20}, | |
149 { 7, 4.20}, | |
150 { 8, 4.20}, | |
151 { 9, 4.20}, | |
152 {10, 4.20} | |
153 }; | |
154 | |
155 /** | |
156 * LAME psy model FIR coefficient table | |
157 */ | |
158 static const float psy_fir_coeffs[] = { | |
159 -8.65163e-18 * 2, -0.00851586 * 2, -6.74764e-18 * 2, 0.0209036 * 2, | |
160 -3.36639e-17 * 2, -0.0438162 * 2, -1.54175e-17 * 2, 0.0931738 * 2, | |
161 -5.52212e-17 * 2, -0.313819 * 2 | |
162 }; | |
163 | |
164 /** | |
165 * calculates the attack threshold for ABR from the above table for the LAME psy model | |
166 */ | |
167 static float lame_calc_attack_threshold(int bitrate) | |
168 { | |
169 /* Assume max bitrate to start with */ | |
170 int lower_range = 12, upper_range = 12; | |
171 int lower_range_kbps = psy_abr_map[12].quality; | |
172 int upper_range_kbps = psy_abr_map[12].quality; | |
173 int i; | |
174 | |
175 /* Determine which bitrates the value specified falls between. | |
176 * If the loop ends without breaking our above assumption of 320kbps was correct. | |
177 */ | |
178 for (i = 1; i < 13; i++) { | |
179 if (FFMAX(bitrate, psy_abr_map[i].quality) != bitrate) { | |
180 upper_range = i; | |
181 upper_range_kbps = psy_abr_map[i ].quality; | |
182 lower_range = i - 1; | |
183 lower_range_kbps = psy_abr_map[i - 1].quality; | |
184 break; /* Upper range found */ | |
185 } | |
186 } | |
187 | |
188 /* Determine which range the value specified is closer to */ | |
189 if ((upper_range_kbps - bitrate) > (bitrate - lower_range_kbps)) | |
190 return psy_abr_map[lower_range].st_lrm; | |
191 return psy_abr_map[upper_range].st_lrm; | |
192 } | |
193 | |
194 /** | |
195 * LAME psy model specific initialization | |
196 */ | |
197 static void lame_window_init(AacPsyContext *ctx, AVCodecContext *avctx) { | |
198 int i; | |
199 | |
200 for (i = 0; i < avctx->channels; i++) { | |
201 AacPsyChannel *pch = &ctx->ch[i]; | |
202 | |
203 if (avctx->flags & CODEC_FLAG_QSCALE) | |
204 pch->attack_threshold = psy_vbr_map[avctx->global_quality / FF_QP2LAMBDA].st_lrm; | |
205 else | |
206 pch->attack_threshold = lame_calc_attack_threshold(avctx->bit_rate / avctx->channels / 1000); | |
207 | |
208 for (i = 0; i < AAC_NUM_BLOCKS_SHORT * PSY_LAME_NUM_SUBBLOCKS; i++) | |
209 pch->prev_energy_subshort[i] = 10.0f; | |
210 } | |
211 } | |
212 | |
213 /** | |
7606 | 214 * Calculate Bark value for given line. |
215 */ | |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
216 static av_cold float calc_bark(float f) |
7606 | 217 { |
218 return 13.3f * atanf(0.00076f * f) + 3.5f * atanf((f / 7500.0f) * (f / 7500.0f)); | |
219 } | |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
220 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
221 #define ATH_ADD 4 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
222 /** |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
223 * Calculate ATH value for given frequency. |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
224 * Borrowed from Lame. |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
225 */ |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
226 static av_cold float ath(float f, float add) |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
227 { |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
228 f /= 1000.0f; |
9937
3e39dbd2d9eb
cosmetics: prettyprinting, K&R style, break overly long lines
diego
parents:
9936
diff
changeset
|
229 return 3.64 * pow(f, -0.8) |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
230 - 6.8 * exp(-0.6 * (f - 3.4) * (f - 3.4)) |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
231 + 6.0 * exp(-0.15 * (f - 8.7) * (f - 8.7)) |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
232 + (0.6 + 0.04 * add) * 0.001 * f * f * f * f; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
233 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
234 |
9936 | 235 static av_cold int psy_3gpp_init(FFPsyContext *ctx) { |
12406 | 236 AacPsyContext *pctx; |
12159
25ac974ce96d
aacenc: psy_3gpp_init(): Calculate barks on demand.
alexc
parents:
11998
diff
changeset
|
237 float bark; |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
238 int i, j, g, start; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
239 float prev, minscale, minath; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
240 |
12406 | 241 ctx->model_priv_data = av_mallocz(sizeof(AacPsyContext)); |
242 pctx = (AacPsyContext*) ctx->model_priv_data; | |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
243 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
244 minath = ath(3410, ATH_ADD); |
9936 | 245 for (j = 0; j < 2; j++) { |
12406 | 246 AacPsyCoeffs *coeffs = &pctx->psy_coef[j]; |
12162
f948f8cf97db
aacenc: psy_3gpp_init(): Fix line_to_frequency for short windows.
alexc
parents:
12161
diff
changeset
|
247 float line_to_frequency = ctx->avctx->sample_rate / (j ? 256.f : 2048.0f); |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
248 i = 0; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
249 prev = 0.0; |
9936 | 250 for (g = 0; g < ctx->num_bands[j]; g++) { |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
251 i += ctx->bands[j][g]; |
12161
d34f0f3ac678
aacenc: aac_psy_init(): Factorize line_to_frequency.
alexc
parents:
12160
diff
changeset
|
252 bark = calc_bark((i-1) * line_to_frequency); |
12159
25ac974ce96d
aacenc: psy_3gpp_init(): Calculate barks on demand.
alexc
parents:
11998
diff
changeset
|
253 coeffs->barks[g] = (bark + prev) / 2.0; |
25ac974ce96d
aacenc: psy_3gpp_init(): Calculate barks on demand.
alexc
parents:
11998
diff
changeset
|
254 prev = bark; |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
255 } |
9936 | 256 for (g = 0; g < ctx->num_bands[j] - 1; g++) { |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
257 coeffs->spread_low[g] = pow(10.0, -(coeffs->barks[g+1] - coeffs->barks[g]) * PSY_3GPP_SPREAD_LOW); |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
258 coeffs->spread_hi [g] = pow(10.0, -(coeffs->barks[g+1] - coeffs->barks[g]) * PSY_3GPP_SPREAD_HI); |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
259 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
260 start = 0; |
9936 | 261 for (g = 0; g < ctx->num_bands[j]; g++) { |
12161
d34f0f3ac678
aacenc: aac_psy_init(): Factorize line_to_frequency.
alexc
parents:
12160
diff
changeset
|
262 minscale = ath(start * line_to_frequency, ATH_ADD); |
9938
6c1ac45b3097
cosmetics: Remove unnecessary {} around if/for blocks;
diego
parents:
9937
diff
changeset
|
263 for (i = 1; i < ctx->bands[j][g]; i++) |
12161
d34f0f3ac678
aacenc: aac_psy_init(): Factorize line_to_frequency.
alexc
parents:
12160
diff
changeset
|
264 minscale = FFMIN(minscale, ath((start + i) * line_to_frequency, ATH_ADD)); |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
265 coeffs->ath[g] = minscale - minath; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
266 start += ctx->bands[j][g]; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
267 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
268 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
269 |
12406 | 270 pctx->ch = av_mallocz(sizeof(AacPsyChannel) * ctx->avctx->channels); |
12408 | 271 |
272 lame_window_init(pctx, ctx->avctx); | |
273 | |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
274 return 0; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
275 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
276 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
277 /** |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
278 * IIR filter used in block switching decision |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
279 */ |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
280 static float iir_filter(int in, float state[2]) |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
281 { |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
282 float ret; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
283 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
284 ret = 0.7548f * (in - state[0]) + 0.5095f * state[1]; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
285 state[0] = in; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
286 state[1] = ret; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
287 return ret; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
288 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
289 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
290 /** |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
291 * window grouping information stored as bits (0 - new group, 1 - group continues) |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
292 */ |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
293 static const uint8_t window_grouping[9] = { |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
294 0xB6, 0x6C, 0xD8, 0xB2, 0x66, 0xC6, 0x96, 0x36, 0x36 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
295 }; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
296 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
297 /** |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
298 * Tell encoder which window types to use. |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
299 * @see 3GPP TS26.403 5.4.1 "Blockswitching" |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
300 */ |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
301 static FFPsyWindowInfo psy_3gpp_window(FFPsyContext *ctx, |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
302 const int16_t *audio, const int16_t *la, |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
303 int channel, int prev_type) |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
304 { |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
305 int i, j; |
9937
3e39dbd2d9eb
cosmetics: prettyprinting, K&R style, break overly long lines
diego
parents:
9936
diff
changeset
|
306 int br = ctx->avctx->bit_rate / ctx->avctx->channels; |
3e39dbd2d9eb
cosmetics: prettyprinting, K&R style, break overly long lines
diego
parents:
9936
diff
changeset
|
307 int attack_ratio = br <= 16000 ? 18 : 10; |
12406 | 308 AacPsyContext *pctx = (AacPsyContext*) ctx->model_priv_data; |
309 AacPsyChannel *pch = &pctx->ch[channel]; | |
9937
3e39dbd2d9eb
cosmetics: prettyprinting, K&R style, break overly long lines
diego
parents:
9936
diff
changeset
|
310 uint8_t grouping = 0; |
11998 | 311 int next_type = pch->next_window_seq; |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
312 FFPsyWindowInfo wi; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
313 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
314 memset(&wi, 0, sizeof(wi)); |
9936 | 315 if (la) { |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
316 float s[8], v; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
317 int switch_to_eight = 0; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
318 float sum = 0.0, sum2 = 0.0; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
319 int attack_n = 0; |
11998 | 320 int stay_short = 0; |
9936 | 321 for (i = 0; i < 8; i++) { |
322 for (j = 0; j < 128; j++) { | |
11728 | 323 v = iir_filter(la[(i*128+j)*ctx->avctx->channels], pch->iir_state); |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
324 sum += v*v; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
325 } |
9937
3e39dbd2d9eb
cosmetics: prettyprinting, K&R style, break overly long lines
diego
parents:
9936
diff
changeset
|
326 s[i] = sum; |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
327 sum2 += sum; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
328 } |
9936 | 329 for (i = 0; i < 8; i++) { |
330 if (s[i] > pch->win_energy * attack_ratio) { | |
9937
3e39dbd2d9eb
cosmetics: prettyprinting, K&R style, break overly long lines
diego
parents:
9936
diff
changeset
|
331 attack_n = i + 1; |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
332 switch_to_eight = 1; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
333 break; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
334 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
335 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
336 pch->win_energy = pch->win_energy*7/8 + sum2/64; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
337 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
338 wi.window_type[1] = prev_type; |
9936 | 339 switch (prev_type) { |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
340 case ONLY_LONG_SEQUENCE: |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
341 wi.window_type[0] = switch_to_eight ? LONG_START_SEQUENCE : ONLY_LONG_SEQUENCE; |
11998 | 342 next_type = switch_to_eight ? EIGHT_SHORT_SEQUENCE : ONLY_LONG_SEQUENCE; |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
343 break; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
344 case LONG_START_SEQUENCE: |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
345 wi.window_type[0] = EIGHT_SHORT_SEQUENCE; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
346 grouping = pch->next_grouping; |
11998 | 347 next_type = switch_to_eight ? EIGHT_SHORT_SEQUENCE : LONG_STOP_SEQUENCE; |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
348 break; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
349 case LONG_STOP_SEQUENCE: |
11998 | 350 wi.window_type[0] = switch_to_eight ? LONG_START_SEQUENCE : ONLY_LONG_SEQUENCE; |
351 next_type = switch_to_eight ? EIGHT_SHORT_SEQUENCE : ONLY_LONG_SEQUENCE; | |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
352 break; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
353 case EIGHT_SHORT_SEQUENCE: |
11998 | 354 stay_short = next_type == EIGHT_SHORT_SEQUENCE || switch_to_eight; |
355 wi.window_type[0] = stay_short ? EIGHT_SHORT_SEQUENCE : LONG_STOP_SEQUENCE; | |
356 grouping = next_type == EIGHT_SHORT_SEQUENCE ? pch->next_grouping : 0; | |
357 next_type = switch_to_eight ? EIGHT_SHORT_SEQUENCE : LONG_STOP_SEQUENCE; | |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
358 break; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
359 } |
11998 | 360 |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
361 pch->next_grouping = window_grouping[attack_n]; |
11998 | 362 pch->next_window_seq = next_type; |
9936 | 363 } else { |
364 for (i = 0; i < 3; i++) | |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
365 wi.window_type[i] = prev_type; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
366 grouping = (prev_type == EIGHT_SHORT_SEQUENCE) ? window_grouping[0] : 0; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
367 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
368 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
369 wi.window_shape = 1; |
9936 | 370 if (wi.window_type[0] != EIGHT_SHORT_SEQUENCE) { |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
371 wi.num_windows = 1; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
372 wi.grouping[0] = 1; |
9936 | 373 } else { |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
374 int lastgrp = 0; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
375 wi.num_windows = 8; |
9936 | 376 for (i = 0; i < 8; i++) { |
377 if (!((grouping >> i) & 1)) | |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
378 lastgrp = i; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
379 wi.grouping[lastgrp]++; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
380 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
381 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
382 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
383 return wi; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
384 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
385 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
386 /** |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
387 * Calculate band thresholds as suggested in 3GPP TS26.403 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
388 */ |
9937
3e39dbd2d9eb
cosmetics: prettyprinting, K&R style, break overly long lines
diego
parents:
9936
diff
changeset
|
389 static void psy_3gpp_analyze(FFPsyContext *ctx, int channel, |
12442 | 390 const float *coefs, const FFPsyWindowInfo *wi) |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
391 { |
12406 | 392 AacPsyContext *pctx = (AacPsyContext*) ctx->model_priv_data; |
393 AacPsyChannel *pch = &pctx->ch[channel]; | |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
394 int start = 0; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
395 int i, w, g; |
9937
3e39dbd2d9eb
cosmetics: prettyprinting, K&R style, break overly long lines
diego
parents:
9936
diff
changeset
|
396 const int num_bands = ctx->num_bands[wi->num_windows == 8]; |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
397 const uint8_t* band_sizes = ctx->bands[wi->num_windows == 8]; |
12406 | 398 AacPsyCoeffs *coeffs = &pctx->psy_coef[wi->num_windows == 8]; |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
399 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
400 //calculate energies, initial thresholds and related values - 5.4.2 "Threshold Calculation" |
9936 | 401 for (w = 0; w < wi->num_windows*16; w += 16) { |
402 for (g = 0; g < num_bands; g++) { | |
12406 | 403 AacPsyBand *band = &pch->band[w+g]; |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
404 band->energy = 0.0f; |
9936 | 405 for (i = 0; i < band_sizes[g]; i++) |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
406 band->energy += coefs[start+i] * coefs[start+i]; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
407 band->energy *= 1.0f / (512*512); |
9937
3e39dbd2d9eb
cosmetics: prettyprinting, K&R style, break overly long lines
diego
parents:
9936
diff
changeset
|
408 band->thr = band->energy * 0.001258925f; |
3e39dbd2d9eb
cosmetics: prettyprinting, K&R style, break overly long lines
diego
parents:
9936
diff
changeset
|
409 start += band_sizes[g]; |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
410 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
411 ctx->psy_bands[channel*PSY_MAX_BANDS+w+g].energy = band->energy; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
412 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
413 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
414 //modify thresholds - spread, threshold in quiet - 5.4.3 "Spreaded Energy Calculation" |
9936 | 415 for (w = 0; w < wi->num_windows*16; w += 16) { |
12406 | 416 AacPsyBand *band = &pch->band[w]; |
9938
6c1ac45b3097
cosmetics: Remove unnecessary {} around if/for blocks;
diego
parents:
9937
diff
changeset
|
417 for (g = 1; g < num_bands; g++) |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
418 band[g].thr = FFMAX(band[g].thr, band[g-1].thr * coeffs->spread_low[g-1]); |
9938
6c1ac45b3097
cosmetics: Remove unnecessary {} around if/for blocks;
diego
parents:
9937
diff
changeset
|
419 for (g = num_bands - 2; g >= 0; g--) |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
420 band[g].thr = FFMAX(band[g].thr, band[g+1].thr * coeffs->spread_hi [g]); |
9936 | 421 for (g = 0; g < num_bands; g++) { |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
422 band[g].thr_quiet = FFMAX(band[g].thr, coeffs->ath[g]); |
9938
6c1ac45b3097
cosmetics: Remove unnecessary {} around if/for blocks;
diego
parents:
9937
diff
changeset
|
423 if (wi->num_windows != 8 && wi->window_type[1] != EIGHT_SHORT_SEQUENCE) |
9944
c5ca5e520fe1
Change fminf/fmaxf to FFMIN/FFMAX to fix the build on broken operating systems.
alexc
parents:
9938
diff
changeset
|
424 band[g].thr_quiet = FFMAX(PSY_3GPP_RPEMIN*band[g].thr_quiet, |
c5ca5e520fe1
Change fminf/fmaxf to FFMIN/FFMAX to fix the build on broken operating systems.
alexc
parents:
9938
diff
changeset
|
425 FFMIN(band[g].thr_quiet, |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
426 PSY_3GPP_RPELEV*pch->prev_band[w+g].thr_quiet)); |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
427 band[g].thr = FFMAX(band[g].thr, band[g].thr_quiet * 0.25); |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
428 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
429 ctx->psy_bands[channel*PSY_MAX_BANDS+w+g].threshold = band[g].thr; |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
430 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
431 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
432 memcpy(pch->prev_band, pch->band, sizeof(pch->band)); |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
433 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
434 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
435 static av_cold void psy_3gpp_end(FFPsyContext *apc) |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
436 { |
12406 | 437 AacPsyContext *pctx = (AacPsyContext*) apc->model_priv_data; |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
438 av_freep(&pctx->ch); |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
439 av_freep(&apc->model_priv_data); |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
440 } |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
441 |
12408 | 442 static void lame_apply_block_type(AacPsyChannel *ctx, FFPsyWindowInfo *wi, int uselongblock) |
443 { | |
444 int blocktype = ONLY_LONG_SEQUENCE; | |
445 if (uselongblock) { | |
446 if (ctx->next_window_seq == EIGHT_SHORT_SEQUENCE) | |
447 blocktype = LONG_STOP_SEQUENCE; | |
448 } else { | |
449 blocktype = EIGHT_SHORT_SEQUENCE; | |
450 if (ctx->next_window_seq == ONLY_LONG_SEQUENCE) | |
451 ctx->next_window_seq = LONG_START_SEQUENCE; | |
452 if (ctx->next_window_seq == LONG_STOP_SEQUENCE) | |
453 ctx->next_window_seq = EIGHT_SHORT_SEQUENCE; | |
454 } | |
455 | |
456 wi->window_type[0] = ctx->next_window_seq; | |
457 ctx->next_window_seq = blocktype; | |
458 } | |
459 | |
460 static FFPsyWindowInfo psy_lame_window(FFPsyContext *ctx, | |
461 const int16_t *audio, const int16_t *la, | |
462 int channel, int prev_type) | |
463 { | |
464 AacPsyContext *pctx = (AacPsyContext*) ctx->model_priv_data; | |
465 AacPsyChannel *pch = &pctx->ch[channel]; | |
466 int grouping = 0; | |
467 int uselongblock = 1; | |
468 int attacks[AAC_NUM_BLOCKS_SHORT + 1] = { 0 }; | |
469 int i; | |
470 FFPsyWindowInfo wi; | |
471 | |
472 memset(&wi, 0, sizeof(wi)); | |
473 if (la) { | |
474 float hpfsmpl[AAC_BLOCK_SIZE_LONG]; | |
475 float const *pf = hpfsmpl; | |
476 float attack_intensity[(AAC_NUM_BLOCKS_SHORT + 1) * PSY_LAME_NUM_SUBBLOCKS]; | |
477 float energy_subshort[(AAC_NUM_BLOCKS_SHORT + 1) * PSY_LAME_NUM_SUBBLOCKS]; | |
478 float energy_short[AAC_NUM_BLOCKS_SHORT + 1] = { 0 }; | |
479 int chans = ctx->avctx->channels; | |
480 const int16_t *firbuf = la + (AAC_BLOCK_SIZE_SHORT/4 - PSY_LAME_FIR_LEN) * chans; | |
481 int j, att_sum = 0; | |
482 | |
483 /* LAME comment: apply high pass filter of fs/4 */ | |
484 for (i = 0; i < AAC_BLOCK_SIZE_LONG; i++) { | |
485 float sum1, sum2; | |
486 sum1 = firbuf[(i + ((PSY_LAME_FIR_LEN - 1) / 2)) * chans]; | |
487 sum2 = 0.0; | |
488 for (j = 0; j < ((PSY_LAME_FIR_LEN - 1) / 2) - 1; j += 2) { | |
489 sum1 += psy_fir_coeffs[j] * (firbuf[(i + j) * chans] + firbuf[(i + PSY_LAME_FIR_LEN - j) * chans]); | |
490 sum2 += psy_fir_coeffs[j + 1] * (firbuf[(i + j + 1) * chans] + firbuf[(i + PSY_LAME_FIR_LEN - j - 1) * chans]); | |
491 } | |
492 hpfsmpl[i] = sum1 + sum2; | |
493 } | |
494 | |
495 /* Calculate the energies of each sub-shortblock */ | |
496 for (i = 0; i < PSY_LAME_NUM_SUBBLOCKS; i++) { | |
497 energy_subshort[i] = pch->prev_energy_subshort[i + ((AAC_NUM_BLOCKS_SHORT - 1) * PSY_LAME_NUM_SUBBLOCKS)]; | |
498 assert(pch->prev_energy_subshort[i + ((AAC_NUM_BLOCKS_SHORT - 2) * PSY_LAME_NUM_SUBBLOCKS + 1)] > 0); | |
499 attack_intensity[i] = energy_subshort[i] / pch->prev_energy_subshort[i + ((AAC_NUM_BLOCKS_SHORT - 2) * PSY_LAME_NUM_SUBBLOCKS + 1)]; | |
500 energy_short[0] += energy_subshort[i]; | |
501 } | |
502 | |
503 for (i = 0; i < AAC_NUM_BLOCKS_SHORT * PSY_LAME_NUM_SUBBLOCKS; i++) { | |
504 float const *const pfe = pf + AAC_BLOCK_SIZE_LONG / (AAC_NUM_BLOCKS_SHORT * PSY_LAME_NUM_SUBBLOCKS); | |
505 float p = 1.0f; | |
506 for (; pf < pfe; pf++) | |
507 if (p < fabsf(*pf)) | |
508 p = fabsf(*pf); | |
509 pch->prev_energy_subshort[i] = energy_subshort[i + PSY_LAME_NUM_SUBBLOCKS] = p; | |
510 energy_short[1 + i / PSY_LAME_NUM_SUBBLOCKS] += p; | |
511 /* FIXME: The indexes below are [i + 3 - 2] in the LAME source. | |
512 * Obviously the 3 and 2 have some significance, or this would be just [i + 1] | |
513 * (which is what we use here). What the 3 stands for is ambigious, as it is both | |
514 * number of short blocks, and the number of sub-short blocks. | |
515 * It seems that LAME is comparing each sub-block to sub-block + 1 in the | |
516 * previous block. | |
517 */ | |
518 if (p > energy_subshort[i + 1]) | |
519 p = p / energy_subshort[i + 1]; | |
520 else if (energy_subshort[i + 1] > p * 10.0f) | |
521 p = energy_subshort[i + 1] / (p * 10.0f); | |
522 else | |
523 p = 0.0; | |
524 attack_intensity[i + PSY_LAME_NUM_SUBBLOCKS] = p; | |
525 } | |
526 | |
527 /* compare energy between sub-short blocks */ | |
528 for (i = 0; i < (AAC_NUM_BLOCKS_SHORT + 1) * PSY_LAME_NUM_SUBBLOCKS; i++) | |
529 if (!attacks[i / PSY_LAME_NUM_SUBBLOCKS]) | |
530 if (attack_intensity[i] > pch->attack_threshold) | |
531 attacks[i / PSY_LAME_NUM_SUBBLOCKS] = (i % PSY_LAME_NUM_SUBBLOCKS) + 1; | |
532 | |
533 /* should have energy change between short blocks, in order to avoid periodic signals */ | |
534 /* Good samples to show the effect are Trumpet test songs */ | |
535 /* GB: tuned (1) to avoid too many short blocks for test sample TRUMPET */ | |
536 /* RH: tuned (2) to let enough short blocks through for test sample FSOL and SNAPS */ | |
537 for (i = 1; i < AAC_NUM_BLOCKS_SHORT + 1; i++) { | |
538 float const u = energy_short[i - 1]; | |
539 float const v = energy_short[i]; | |
540 float const m = FFMAX(u, v); | |
541 if (m < 40000) { /* (2) */ | |
542 if (u < 1.7f * v && v < 1.7f * u) { /* (1) */ | |
543 if (i == 1 && attacks[0] < attacks[i]) | |
544 attacks[0] = 0; | |
545 attacks[i] = 0; | |
546 } | |
547 } | |
548 att_sum += attacks[i]; | |
549 } | |
550 | |
551 if (attacks[0] <= pch->prev_attack) | |
552 attacks[0] = 0; | |
553 | |
554 att_sum += attacks[0]; | |
555 /* 3 below indicates the previous attack happened in the last sub-block of the previous sequence */ | |
556 if (pch->prev_attack == 3 || att_sum) { | |
557 uselongblock = 0; | |
558 | |
559 if (attacks[1] && attacks[0]) | |
560 attacks[1] = 0; | |
561 if (attacks[2] && attacks[1]) | |
562 attacks[2] = 0; | |
563 if (attacks[3] && attacks[2]) | |
564 attacks[3] = 0; | |
565 if (attacks[4] && attacks[3]) | |
566 attacks[4] = 0; | |
567 if (attacks[5] && attacks[4]) | |
568 attacks[5] = 0; | |
569 if (attacks[6] && attacks[5]) | |
570 attacks[6] = 0; | |
571 if (attacks[7] && attacks[6]) | |
572 attacks[7] = 0; | |
573 if (attacks[8] && attacks[7]) | |
574 attacks[8] = 0; | |
575 } | |
576 } else { | |
577 /* We have no lookahead info, so just use same type as the previous sequence. */ | |
578 uselongblock = !(prev_type == EIGHT_SHORT_SEQUENCE); | |
579 } | |
580 | |
581 lame_apply_block_type(pch, &wi, uselongblock); | |
582 | |
583 wi.window_type[1] = prev_type; | |
584 if (wi.window_type[0] != EIGHT_SHORT_SEQUENCE) { | |
585 wi.num_windows = 1; | |
586 wi.grouping[0] = 1; | |
587 if (wi.window_type[0] == LONG_START_SEQUENCE) | |
588 wi.window_shape = 0; | |
589 else | |
590 wi.window_shape = 1; | |
591 } else { | |
592 int lastgrp = 0; | |
593 | |
594 wi.num_windows = 8; | |
595 wi.window_shape = 0; | |
596 for (i = 0; i < 8; i++) { | |
597 if (!((pch->next_grouping >> i) & 1)) | |
598 lastgrp = i; | |
599 wi.grouping[lastgrp]++; | |
600 } | |
601 } | |
602 | |
603 /* Determine grouping, based on the location of the first attack, and save for | |
604 * the next frame. | |
605 * FIXME: Move this to analysis. | |
606 * TODO: Tune groupings depending on attack location | |
607 * TODO: Handle more than one attack in a group | |
608 */ | |
609 for (i = 0; i < 9; i++) { | |
610 if (attacks[i]) { | |
611 grouping = i; | |
612 break; | |
613 } | |
614 } | |
615 pch->next_grouping = window_grouping[grouping]; | |
616 | |
617 pch->prev_attack = attacks[8]; | |
618 | |
619 return wi; | |
620 } | |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
621 |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
622 const FFPsyModel ff_aac_psy_model = |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
623 { |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
624 .name = "3GPP TS 26.403-inspired model", |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
625 .init = psy_3gpp_init, |
12408 | 626 .window = psy_lame_window, |
9935
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
627 .analyze = psy_3gpp_analyze, |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
628 .end = psy_3gpp_end, |
d09283aeeef8
Merge the AAC encoder from SoC svn. It is still considered experimental.
alexc
parents:
8718
diff
changeset
|
629 }; |