1159b3361Sopenharmony_ci/* 2159b3361Sopenharmony_ci * quantize_pvt source file 3159b3361Sopenharmony_ci * 4159b3361Sopenharmony_ci * Copyright (c) 1999-2002 Takehiro Tominaga 5159b3361Sopenharmony_ci * Copyright (c) 2000-2012 Robert Hegemann 6159b3361Sopenharmony_ci * Copyright (c) 2001 Naoki Shibata 7159b3361Sopenharmony_ci * Copyright (c) 2002-2005 Gabriel Bouvigne 8159b3361Sopenharmony_ci * 9159b3361Sopenharmony_ci * This library is free software; you can redistribute it and/or 10159b3361Sopenharmony_ci * modify it under the terms of the GNU Library General Public 11159b3361Sopenharmony_ci * License as published by the Free Software Foundation; either 12159b3361Sopenharmony_ci * version 2 of the License, or (at your option) any later version. 13159b3361Sopenharmony_ci * 14159b3361Sopenharmony_ci * This library is distributed in the hope that it will be useful, 15159b3361Sopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 16159b3361Sopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17159b3361Sopenharmony_ci * Library General Public License for more details. 18159b3361Sopenharmony_ci * 19159b3361Sopenharmony_ci * You should have received a copy of the GNU Library General Public 20159b3361Sopenharmony_ci * License along with this library; if not, write to the 21159b3361Sopenharmony_ci * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 22159b3361Sopenharmony_ci * Boston, MA 02111-1307, USA. 23159b3361Sopenharmony_ci */ 24159b3361Sopenharmony_ci 25159b3361Sopenharmony_ci/* $Id$ */ 26159b3361Sopenharmony_ci#ifdef HAVE_CONFIG_H 27159b3361Sopenharmony_ci# include <config.h> 28159b3361Sopenharmony_ci#endif 29159b3361Sopenharmony_ci 30159b3361Sopenharmony_ci 31159b3361Sopenharmony_ci#include "lame.h" 32159b3361Sopenharmony_ci#include "machine.h" 33159b3361Sopenharmony_ci#include "encoder.h" 34159b3361Sopenharmony_ci#include "util.h" 35159b3361Sopenharmony_ci#include "quantize_pvt.h" 36159b3361Sopenharmony_ci#include "reservoir.h" 37159b3361Sopenharmony_ci#include "lame-analysis.h" 38159b3361Sopenharmony_ci#include <float.h> 39159b3361Sopenharmony_ci 40159b3361Sopenharmony_ci 41159b3361Sopenharmony_ci#define NSATHSCALE 100 /* Assuming dynamic range=96dB, this value should be 92 */ 42159b3361Sopenharmony_ci 43159b3361Sopenharmony_ci/* 44159b3361Sopenharmony_ci The following table is used to implement the scalefactor 45159b3361Sopenharmony_ci partitioning for MPEG2 as described in section 46159b3361Sopenharmony_ci 2.4.3.2 of the IS. The indexing corresponds to the 47159b3361Sopenharmony_ci way the tables are presented in the IS: 48159b3361Sopenharmony_ci 49159b3361Sopenharmony_ci [table_number][row_in_table][column of nr_of_sfb] 50159b3361Sopenharmony_ci*/ 51159b3361Sopenharmony_ciconst int nr_of_sfb_block[6][3][4] = { 52159b3361Sopenharmony_ci { 53159b3361Sopenharmony_ci {6, 5, 5, 5}, 54159b3361Sopenharmony_ci {9, 9, 9, 9}, 55159b3361Sopenharmony_ci {6, 9, 9, 9} 56159b3361Sopenharmony_ci }, 57159b3361Sopenharmony_ci { 58159b3361Sopenharmony_ci {6, 5, 7, 3}, 59159b3361Sopenharmony_ci {9, 9, 12, 6}, 60159b3361Sopenharmony_ci {6, 9, 12, 6} 61159b3361Sopenharmony_ci }, 62159b3361Sopenharmony_ci { 63159b3361Sopenharmony_ci {11, 10, 0, 0}, 64159b3361Sopenharmony_ci {18, 18, 0, 0}, 65159b3361Sopenharmony_ci {15, 18, 0, 0} 66159b3361Sopenharmony_ci }, 67159b3361Sopenharmony_ci { 68159b3361Sopenharmony_ci {7, 7, 7, 0}, 69159b3361Sopenharmony_ci {12, 12, 12, 0}, 70159b3361Sopenharmony_ci {6, 15, 12, 0} 71159b3361Sopenharmony_ci }, 72159b3361Sopenharmony_ci { 73159b3361Sopenharmony_ci {6, 6, 6, 3}, 74159b3361Sopenharmony_ci {12, 9, 9, 6}, 75159b3361Sopenharmony_ci {6, 12, 9, 6} 76159b3361Sopenharmony_ci }, 77159b3361Sopenharmony_ci { 78159b3361Sopenharmony_ci {8, 8, 5, 0}, 79159b3361Sopenharmony_ci {15, 12, 9, 0}, 80159b3361Sopenharmony_ci {6, 18, 9, 0} 81159b3361Sopenharmony_ci } 82159b3361Sopenharmony_ci}; 83159b3361Sopenharmony_ci 84159b3361Sopenharmony_ci 85159b3361Sopenharmony_ci/* Table B.6: layer3 preemphasis */ 86159b3361Sopenharmony_ciconst int pretab[SBMAX_l] = { 87159b3361Sopenharmony_ci 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88159b3361Sopenharmony_ci 1, 1, 1, 1, 2, 2, 3, 3, 3, 2, 0 89159b3361Sopenharmony_ci}; 90159b3361Sopenharmony_ci 91159b3361Sopenharmony_ci/* 92159b3361Sopenharmony_ci Here are MPEG1 Table B.8 and MPEG2 Table B.1 93159b3361Sopenharmony_ci -- Layer III scalefactor bands. 94159b3361Sopenharmony_ci Index into this using a method such as: 95159b3361Sopenharmony_ci idx = fr_ps->header->sampling_frequency 96159b3361Sopenharmony_ci + (fr_ps->header->version * 3) 97159b3361Sopenharmony_ci*/ 98159b3361Sopenharmony_ci 99159b3361Sopenharmony_ci 100159b3361Sopenharmony_ciconst scalefac_struct sfBandIndex[9] = { 101159b3361Sopenharmony_ci { /* Table B.2.b: 22.05 kHz */ 102159b3361Sopenharmony_ci {0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, 103159b3361Sopenharmony_ci 522, 576}, 104159b3361Sopenharmony_ci {0, 4, 8, 12, 18, 24, 32, 42, 56, 74, 100, 132, 174, 192} 105159b3361Sopenharmony_ci , {0, 0, 0, 0, 0, 0, 0} /* sfb21 pseudo sub bands */ 106159b3361Sopenharmony_ci , {0, 0, 0, 0, 0, 0, 0} /* sfb12 pseudo sub bands */ 107159b3361Sopenharmony_ci }, 108159b3361Sopenharmony_ci { /* Table B.2.c: 24 kHz */ /* docs: 332. mpg123(broken): 330 */ 109159b3361Sopenharmony_ci {0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 114, 136, 162, 194, 232, 278, 332, 394, 464, 110159b3361Sopenharmony_ci 540, 576}, 111159b3361Sopenharmony_ci {0, 4, 8, 12, 18, 26, 36, 48, 62, 80, 104, 136, 180, 192} 112159b3361Sopenharmony_ci , {0, 0, 0, 0, 0, 0, 0} /* sfb21 pseudo sub bands */ 113159b3361Sopenharmony_ci , {0, 0, 0, 0, 0, 0, 0} /* sfb12 pseudo sub bands */ 114159b3361Sopenharmony_ci }, 115159b3361Sopenharmony_ci { /* Table B.2.a: 16 kHz */ 116159b3361Sopenharmony_ci {0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, 117159b3361Sopenharmony_ci 522, 576}, 118159b3361Sopenharmony_ci {0, 4, 8, 12, 18, 26, 36, 48, 62, 80, 104, 134, 174, 192} 119159b3361Sopenharmony_ci , {0, 0, 0, 0, 0, 0, 0} /* sfb21 pseudo sub bands */ 120159b3361Sopenharmony_ci , {0, 0, 0, 0, 0, 0, 0} /* sfb12 pseudo sub bands */ 121159b3361Sopenharmony_ci }, 122159b3361Sopenharmony_ci { /* Table B.8.b: 44.1 kHz */ 123159b3361Sopenharmony_ci {0, 4, 8, 12, 16, 20, 24, 30, 36, 44, 52, 62, 74, 90, 110, 134, 162, 196, 238, 288, 342, 418, 124159b3361Sopenharmony_ci 576}, 125159b3361Sopenharmony_ci {0, 4, 8, 12, 16, 22, 30, 40, 52, 66, 84, 106, 136, 192} 126159b3361Sopenharmony_ci , {0, 0, 0, 0, 0, 0, 0} /* sfb21 pseudo sub bands */ 127159b3361Sopenharmony_ci , {0, 0, 0, 0, 0, 0, 0} /* sfb12 pseudo sub bands */ 128159b3361Sopenharmony_ci }, 129159b3361Sopenharmony_ci { /* Table B.8.c: 48 kHz */ 130159b3361Sopenharmony_ci {0, 4, 8, 12, 16, 20, 24, 30, 36, 42, 50, 60, 72, 88, 106, 128, 156, 190, 230, 276, 330, 384, 131159b3361Sopenharmony_ci 576}, 132159b3361Sopenharmony_ci {0, 4, 8, 12, 16, 22, 28, 38, 50, 64, 80, 100, 126, 192} 133159b3361Sopenharmony_ci , {0, 0, 0, 0, 0, 0, 0} /* sfb21 pseudo sub bands */ 134159b3361Sopenharmony_ci , {0, 0, 0, 0, 0, 0, 0} /* sfb12 pseudo sub bands */ 135159b3361Sopenharmony_ci }, 136159b3361Sopenharmony_ci { /* Table B.8.a: 32 kHz */ 137159b3361Sopenharmony_ci {0, 4, 8, 12, 16, 20, 24, 30, 36, 44, 54, 66, 82, 102, 126, 156, 194, 240, 296, 364, 448, 550, 138159b3361Sopenharmony_ci 576}, 139159b3361Sopenharmony_ci {0, 4, 8, 12, 16, 22, 30, 42, 58, 78, 104, 138, 180, 192} 140159b3361Sopenharmony_ci , {0, 0, 0, 0, 0, 0, 0} /* sfb21 pseudo sub bands */ 141159b3361Sopenharmony_ci , {0, 0, 0, 0, 0, 0, 0} /* sfb12 pseudo sub bands */ 142159b3361Sopenharmony_ci }, 143159b3361Sopenharmony_ci { /* MPEG-2.5 11.025 kHz */ 144159b3361Sopenharmony_ci {0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, 145159b3361Sopenharmony_ci 522, 576}, 146159b3361Sopenharmony_ci {0 / 3, 12 / 3, 24 / 3, 36 / 3, 54 / 3, 78 / 3, 108 / 3, 144 / 3, 186 / 3, 240 / 3, 312 / 3, 147159b3361Sopenharmony_ci 402 / 3, 522 / 3, 576 / 3} 148159b3361Sopenharmony_ci , {0, 0, 0, 0, 0, 0, 0} /* sfb21 pseudo sub bands */ 149159b3361Sopenharmony_ci , {0, 0, 0, 0, 0, 0, 0} /* sfb12 pseudo sub bands */ 150159b3361Sopenharmony_ci }, 151159b3361Sopenharmony_ci { /* MPEG-2.5 12 kHz */ 152159b3361Sopenharmony_ci {0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464, 153159b3361Sopenharmony_ci 522, 576}, 154159b3361Sopenharmony_ci {0 / 3, 12 / 3, 24 / 3, 36 / 3, 54 / 3, 78 / 3, 108 / 3, 144 / 3, 186 / 3, 240 / 3, 312 / 3, 155159b3361Sopenharmony_ci 402 / 3, 522 / 3, 576 / 3} 156159b3361Sopenharmony_ci , {0, 0, 0, 0, 0, 0, 0} /* sfb21 pseudo sub bands */ 157159b3361Sopenharmony_ci , {0, 0, 0, 0, 0, 0, 0} /* sfb12 pseudo sub bands */ 158159b3361Sopenharmony_ci }, 159159b3361Sopenharmony_ci { /* MPEG-2.5 8 kHz */ 160159b3361Sopenharmony_ci {0, 12, 24, 36, 48, 60, 72, 88, 108, 132, 160, 192, 232, 280, 336, 400, 476, 566, 568, 570, 161159b3361Sopenharmony_ci 572, 574, 576}, 162159b3361Sopenharmony_ci {0 / 3, 24 / 3, 48 / 3, 72 / 3, 108 / 3, 156 / 3, 216 / 3, 288 / 3, 372 / 3, 480 / 3, 486 / 3, 163159b3361Sopenharmony_ci 492 / 3, 498 / 3, 576 / 3} 164159b3361Sopenharmony_ci , {0, 0, 0, 0, 0, 0, 0} /* sfb21 pseudo sub bands */ 165159b3361Sopenharmony_ci , {0, 0, 0, 0, 0, 0, 0} /* sfb12 pseudo sub bands */ 166159b3361Sopenharmony_ci } 167159b3361Sopenharmony_ci}; 168159b3361Sopenharmony_ci 169159b3361Sopenharmony_ci 170159b3361Sopenharmony_ci/* FIXME: move global variables in some struct */ 171159b3361Sopenharmony_ci 172159b3361Sopenharmony_ciFLOAT pow20[Q_MAX + Q_MAX2 + 1]; 173159b3361Sopenharmony_ciFLOAT ipow20[Q_MAX]; 174159b3361Sopenharmony_ciFLOAT pow43[PRECALC_SIZE]; 175159b3361Sopenharmony_ci/* initialized in first call to iteration_init */ 176159b3361Sopenharmony_ci#ifdef TAKEHIRO_IEEE754_HACK 177159b3361Sopenharmony_ciFLOAT adj43asm[PRECALC_SIZE]; 178159b3361Sopenharmony_ci#else 179159b3361Sopenharmony_ciFLOAT adj43[PRECALC_SIZE]; 180159b3361Sopenharmony_ci#endif 181159b3361Sopenharmony_ci 182159b3361Sopenharmony_ci/* 183159b3361Sopenharmony_cicompute the ATH for each scalefactor band 184159b3361Sopenharmony_cicd range: 0..96db 185159b3361Sopenharmony_ci 186159b3361Sopenharmony_ciInput: 3.3kHz signal 32767 amplitude (3.3kHz is where ATH is smallest = -5db) 187159b3361Sopenharmony_cilongblocks: sfb=12 en0/bw=-11db max_en0 = 1.3db 188159b3361Sopenharmony_cishortblocks: sfb=5 -9db 0db 189159b3361Sopenharmony_ci 190159b3361Sopenharmony_ciInput: 1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 (repeated) 191159b3361Sopenharmony_cilongblocks: amp=1 sfb=12 en0/bw=-103 db max_en0 = -92db 192159b3361Sopenharmony_ci amp=32767 sfb=12 -12 db -1.4db 193159b3361Sopenharmony_ci 194159b3361Sopenharmony_ciInput: 1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 (repeated) 195159b3361Sopenharmony_cishortblocks: amp=1 sfb=5 en0/bw= -99 -86 196159b3361Sopenharmony_ci amp=32767 sfb=5 -9 db 4db 197159b3361Sopenharmony_ci 198159b3361Sopenharmony_ci 199159b3361Sopenharmony_ciMAX energy of largest wave at 3.3kHz = 1db 200159b3361Sopenharmony_ciAVE energy of largest wave at 3.3kHz = -11db 201159b3361Sopenharmony_ciLet's take AVE: -11db = maximum signal in sfb=12. 202159b3361Sopenharmony_ciDynamic range of CD: 96db. Therefor energy of smallest audible wave 203159b3361Sopenharmony_ciin sfb=12 = -11 - 96 = -107db = ATH at 3.3kHz. 204159b3361Sopenharmony_ci 205159b3361Sopenharmony_ciATH formula for this wave: -5db. To adjust to LAME scaling, we need 206159b3361Sopenharmony_ciATH = ATH_formula - 103 (db) 207159b3361Sopenharmony_ciATH = ATH * 2.5e-10 (ener) 208159b3361Sopenharmony_ci 209159b3361Sopenharmony_ci*/ 210159b3361Sopenharmony_ci 211159b3361Sopenharmony_cistatic FLOAT 212159b3361Sopenharmony_ciATHmdct(SessionConfig_t const *cfg, FLOAT f) 213159b3361Sopenharmony_ci{ 214159b3361Sopenharmony_ci FLOAT ath; 215159b3361Sopenharmony_ci 216159b3361Sopenharmony_ci ath = ATHformula(cfg, f); 217159b3361Sopenharmony_ci 218159b3361Sopenharmony_ci if (cfg->ATHfixpoint > 0) { 219159b3361Sopenharmony_ci ath -= cfg->ATHfixpoint; 220159b3361Sopenharmony_ci } 221159b3361Sopenharmony_ci else { 222159b3361Sopenharmony_ci ath -= NSATHSCALE; 223159b3361Sopenharmony_ci } 224159b3361Sopenharmony_ci ath += cfg->ATH_offset_db; 225159b3361Sopenharmony_ci 226159b3361Sopenharmony_ci /* modify the MDCT scaling for the ATH and convert to energy */ 227159b3361Sopenharmony_ci ath = powf(10.0f, ath * 0.1f); 228159b3361Sopenharmony_ci return ath; 229159b3361Sopenharmony_ci} 230159b3361Sopenharmony_ci 231159b3361Sopenharmony_cistatic void 232159b3361Sopenharmony_cicompute_ath(lame_internal_flags const* gfc) 233159b3361Sopenharmony_ci{ 234159b3361Sopenharmony_ci SessionConfig_t const *const cfg = &gfc->cfg; 235159b3361Sopenharmony_ci FLOAT *const ATH_l = gfc->ATH->l; 236159b3361Sopenharmony_ci FLOAT *const ATH_psfb21 = gfc->ATH->psfb21; 237159b3361Sopenharmony_ci FLOAT *const ATH_s = gfc->ATH->s; 238159b3361Sopenharmony_ci FLOAT *const ATH_psfb12 = gfc->ATH->psfb12; 239159b3361Sopenharmony_ci int sfb, i, start, end; 240159b3361Sopenharmony_ci FLOAT ATH_f; 241159b3361Sopenharmony_ci FLOAT const samp_freq = cfg->samplerate_out; 242159b3361Sopenharmony_ci 243159b3361Sopenharmony_ci for (sfb = 0; sfb < SBMAX_l; sfb++) { 244159b3361Sopenharmony_ci start = gfc->scalefac_band.l[sfb]; 245159b3361Sopenharmony_ci end = gfc->scalefac_band.l[sfb + 1]; 246159b3361Sopenharmony_ci ATH_l[sfb] = FLOAT_MAX; 247159b3361Sopenharmony_ci for (i = start; i < end; i++) { 248159b3361Sopenharmony_ci FLOAT const freq = i * samp_freq / (2 * 576); 249159b3361Sopenharmony_ci ATH_f = ATHmdct(cfg, freq); /* freq in kHz */ 250159b3361Sopenharmony_ci ATH_l[sfb] = Min(ATH_l[sfb], ATH_f); 251159b3361Sopenharmony_ci } 252159b3361Sopenharmony_ci } 253159b3361Sopenharmony_ci 254159b3361Sopenharmony_ci for (sfb = 0; sfb < PSFB21; sfb++) { 255159b3361Sopenharmony_ci start = gfc->scalefac_band.psfb21[sfb]; 256159b3361Sopenharmony_ci end = gfc->scalefac_band.psfb21[sfb + 1]; 257159b3361Sopenharmony_ci ATH_psfb21[sfb] = FLOAT_MAX; 258159b3361Sopenharmony_ci for (i = start; i < end; i++) { 259159b3361Sopenharmony_ci FLOAT const freq = i * samp_freq / (2 * 576); 260159b3361Sopenharmony_ci ATH_f = ATHmdct(cfg, freq); /* freq in kHz */ 261159b3361Sopenharmony_ci ATH_psfb21[sfb] = Min(ATH_psfb21[sfb], ATH_f); 262159b3361Sopenharmony_ci } 263159b3361Sopenharmony_ci } 264159b3361Sopenharmony_ci 265159b3361Sopenharmony_ci for (sfb = 0; sfb < SBMAX_s; sfb++) { 266159b3361Sopenharmony_ci start = gfc->scalefac_band.s[sfb]; 267159b3361Sopenharmony_ci end = gfc->scalefac_band.s[sfb + 1]; 268159b3361Sopenharmony_ci ATH_s[sfb] = FLOAT_MAX; 269159b3361Sopenharmony_ci for (i = start; i < end; i++) { 270159b3361Sopenharmony_ci FLOAT const freq = i * samp_freq / (2 * 192); 271159b3361Sopenharmony_ci ATH_f = ATHmdct(cfg, freq); /* freq in kHz */ 272159b3361Sopenharmony_ci ATH_s[sfb] = Min(ATH_s[sfb], ATH_f); 273159b3361Sopenharmony_ci } 274159b3361Sopenharmony_ci ATH_s[sfb] *= (gfc->scalefac_band.s[sfb + 1] - gfc->scalefac_band.s[sfb]); 275159b3361Sopenharmony_ci } 276159b3361Sopenharmony_ci 277159b3361Sopenharmony_ci for (sfb = 0; sfb < PSFB12; sfb++) { 278159b3361Sopenharmony_ci start = gfc->scalefac_band.psfb12[sfb]; 279159b3361Sopenharmony_ci end = gfc->scalefac_band.psfb12[sfb + 1]; 280159b3361Sopenharmony_ci ATH_psfb12[sfb] = FLOAT_MAX; 281159b3361Sopenharmony_ci for (i = start; i < end; i++) { 282159b3361Sopenharmony_ci FLOAT const freq = i * samp_freq / (2 * 192); 283159b3361Sopenharmony_ci ATH_f = ATHmdct(cfg, freq); /* freq in kHz */ 284159b3361Sopenharmony_ci ATH_psfb12[sfb] = Min(ATH_psfb12[sfb], ATH_f); 285159b3361Sopenharmony_ci } 286159b3361Sopenharmony_ci /*not sure about the following */ 287159b3361Sopenharmony_ci ATH_psfb12[sfb] *= (gfc->scalefac_band.s[13] - gfc->scalefac_band.s[12]); 288159b3361Sopenharmony_ci } 289159b3361Sopenharmony_ci 290159b3361Sopenharmony_ci 291159b3361Sopenharmony_ci /* no-ATH mode: 292159b3361Sopenharmony_ci * reduce ATH to -200 dB 293159b3361Sopenharmony_ci */ 294159b3361Sopenharmony_ci 295159b3361Sopenharmony_ci if (cfg->noATH) { 296159b3361Sopenharmony_ci for (sfb = 0; sfb < SBMAX_l; sfb++) { 297159b3361Sopenharmony_ci ATH_l[sfb] = 1E-20; 298159b3361Sopenharmony_ci } 299159b3361Sopenharmony_ci for (sfb = 0; sfb < PSFB21; sfb++) { 300159b3361Sopenharmony_ci ATH_psfb21[sfb] = 1E-20; 301159b3361Sopenharmony_ci } 302159b3361Sopenharmony_ci for (sfb = 0; sfb < SBMAX_s; sfb++) { 303159b3361Sopenharmony_ci ATH_s[sfb] = 1E-20; 304159b3361Sopenharmony_ci } 305159b3361Sopenharmony_ci for (sfb = 0; sfb < PSFB12; sfb++) { 306159b3361Sopenharmony_ci ATH_psfb12[sfb] = 1E-20; 307159b3361Sopenharmony_ci } 308159b3361Sopenharmony_ci } 309159b3361Sopenharmony_ci 310159b3361Sopenharmony_ci /* work in progress, don't rely on it too much 311159b3361Sopenharmony_ci */ 312159b3361Sopenharmony_ci gfc->ATH->floor = 10. * log10(ATHmdct(cfg, -1.)); 313159b3361Sopenharmony_ci 314159b3361Sopenharmony_ci /* 315159b3361Sopenharmony_ci { FLOAT g=10000, t=1e30, x; 316159b3361Sopenharmony_ci for ( f = 100; f < 10000; f++ ) { 317159b3361Sopenharmony_ci x = ATHmdct( cfg, f ); 318159b3361Sopenharmony_ci if ( t > x ) t = x, g = f; 319159b3361Sopenharmony_ci } 320159b3361Sopenharmony_ci printf("min=%g\n", g); 321159b3361Sopenharmony_ci } */ 322159b3361Sopenharmony_ci} 323159b3361Sopenharmony_ci 324159b3361Sopenharmony_ci 325159b3361Sopenharmony_cistatic float const payload_long[2][4] = 326159b3361Sopenharmony_ci{ {-0.000f, -0.000f, -0.000f, +0.000f} 327159b3361Sopenharmony_ci, {-0.500f, -0.250f, -0.025f, +0.500f} 328159b3361Sopenharmony_ci}; 329159b3361Sopenharmony_cistatic float const payload_short[2][4] = 330159b3361Sopenharmony_ci{ {-0.000f, -0.000f, -0.000f, +0.000f} 331159b3361Sopenharmony_ci, {-2.000f, -1.000f, -0.050f, +0.500f} 332159b3361Sopenharmony_ci}; 333159b3361Sopenharmony_ci 334159b3361Sopenharmony_ci/************************************************************************/ 335159b3361Sopenharmony_ci/* initialization for iteration_loop */ 336159b3361Sopenharmony_ci/************************************************************************/ 337159b3361Sopenharmony_civoid 338159b3361Sopenharmony_ciiteration_init(lame_internal_flags * gfc) 339159b3361Sopenharmony_ci{ 340159b3361Sopenharmony_ci SessionConfig_t const *const cfg = &gfc->cfg; 341159b3361Sopenharmony_ci III_side_info_t *const l3_side = &gfc->l3_side; 342159b3361Sopenharmony_ci FLOAT adjust, db; 343159b3361Sopenharmony_ci int i, sel; 344159b3361Sopenharmony_ci 345159b3361Sopenharmony_ci if (gfc->iteration_init_init == 0) { 346159b3361Sopenharmony_ci gfc->iteration_init_init = 1; 347159b3361Sopenharmony_ci 348159b3361Sopenharmony_ci l3_side->main_data_begin = 0; 349159b3361Sopenharmony_ci compute_ath(gfc); 350159b3361Sopenharmony_ci 351159b3361Sopenharmony_ci pow43[0] = 0.0; 352159b3361Sopenharmony_ci for (i = 1; i < PRECALC_SIZE; i++) 353159b3361Sopenharmony_ci pow43[i] = pow((FLOAT) i, 4.0 / 3.0); 354159b3361Sopenharmony_ci 355159b3361Sopenharmony_ci#ifdef TAKEHIRO_IEEE754_HACK 356159b3361Sopenharmony_ci adj43asm[0] = 0.0; 357159b3361Sopenharmony_ci for (i = 1; i < PRECALC_SIZE; i++) 358159b3361Sopenharmony_ci adj43asm[i] = i - 0.5 - pow(0.5 * (pow43[i - 1] + pow43[i]), 0.75); 359159b3361Sopenharmony_ci#else 360159b3361Sopenharmony_ci for (i = 0; i < PRECALC_SIZE - 1; i++) 361159b3361Sopenharmony_ci adj43[i] = (i + 1) - pow(0.5 * (pow43[i] + pow43[i + 1]), 0.75); 362159b3361Sopenharmony_ci adj43[i] = 0.5; 363159b3361Sopenharmony_ci#endif 364159b3361Sopenharmony_ci for (i = 0; i < Q_MAX; i++) 365159b3361Sopenharmony_ci ipow20[i] = pow(2.0, (double) (i - 210) * -0.1875); 366159b3361Sopenharmony_ci for (i = 0; i <= Q_MAX + Q_MAX2; i++) 367159b3361Sopenharmony_ci pow20[i] = pow(2.0, (double) (i - 210 - Q_MAX2) * 0.25); 368159b3361Sopenharmony_ci 369159b3361Sopenharmony_ci huffman_init(gfc); 370159b3361Sopenharmony_ci init_xrpow_core_init(gfc); 371159b3361Sopenharmony_ci 372159b3361Sopenharmony_ci sel = 1;/* RH: all modes like vbr-new (cfg->vbr == vbr_mt || cfg->vbr == vbr_mtrh) ? 1 : 0;*/ 373159b3361Sopenharmony_ci 374159b3361Sopenharmony_ci /* long */ 375159b3361Sopenharmony_ci db = cfg->adjust_bass_db + payload_long[sel][0]; 376159b3361Sopenharmony_ci adjust = powf(10.f, db * 0.1f); 377159b3361Sopenharmony_ci for (i = 0; i <= 6; ++i) { 378159b3361Sopenharmony_ci gfc->sv_qnt.longfact[i] = adjust; 379159b3361Sopenharmony_ci } 380159b3361Sopenharmony_ci db = cfg->adjust_alto_db + payload_long[sel][1]; 381159b3361Sopenharmony_ci adjust = powf(10.f, db * 0.1f); 382159b3361Sopenharmony_ci for (; i <= 13; ++i) { 383159b3361Sopenharmony_ci gfc->sv_qnt.longfact[i] = adjust; 384159b3361Sopenharmony_ci } 385159b3361Sopenharmony_ci db = cfg->adjust_treble_db + payload_long[sel][2]; 386159b3361Sopenharmony_ci adjust = powf(10.f, db * 0.1f); 387159b3361Sopenharmony_ci for (; i <= 20; ++i) { 388159b3361Sopenharmony_ci gfc->sv_qnt.longfact[i] = adjust; 389159b3361Sopenharmony_ci } 390159b3361Sopenharmony_ci db = cfg->adjust_sfb21_db + payload_long[sel][3]; 391159b3361Sopenharmony_ci adjust = powf(10.f, db * 0.1f); 392159b3361Sopenharmony_ci for (; i < SBMAX_l; ++i) { 393159b3361Sopenharmony_ci gfc->sv_qnt.longfact[i] = adjust; 394159b3361Sopenharmony_ci } 395159b3361Sopenharmony_ci 396159b3361Sopenharmony_ci /* short */ 397159b3361Sopenharmony_ci db = cfg->adjust_bass_db + payload_short[sel][0]; 398159b3361Sopenharmony_ci adjust = powf(10.f, db * 0.1f); 399159b3361Sopenharmony_ci for (i = 0; i <= 2; ++i) { 400159b3361Sopenharmony_ci gfc->sv_qnt.shortfact[i] = adjust; 401159b3361Sopenharmony_ci } 402159b3361Sopenharmony_ci db = cfg->adjust_alto_db + payload_short[sel][1]; 403159b3361Sopenharmony_ci adjust = powf(10.f, db * 0.1f); 404159b3361Sopenharmony_ci for (; i <= 6; ++i) { 405159b3361Sopenharmony_ci gfc->sv_qnt.shortfact[i] = adjust; 406159b3361Sopenharmony_ci } 407159b3361Sopenharmony_ci db = cfg->adjust_treble_db + payload_short[sel][2]; 408159b3361Sopenharmony_ci adjust = powf(10.f, db * 0.1f); 409159b3361Sopenharmony_ci for (; i <= 11; ++i) { 410159b3361Sopenharmony_ci gfc->sv_qnt.shortfact[i] = adjust; 411159b3361Sopenharmony_ci } 412159b3361Sopenharmony_ci db = cfg->adjust_sfb21_db + payload_short[sel][3]; 413159b3361Sopenharmony_ci adjust = powf(10.f, db * 0.1f); 414159b3361Sopenharmony_ci for (; i < SBMAX_s; ++i) { 415159b3361Sopenharmony_ci gfc->sv_qnt.shortfact[i] = adjust; 416159b3361Sopenharmony_ci } 417159b3361Sopenharmony_ci } 418159b3361Sopenharmony_ci} 419159b3361Sopenharmony_ci 420159b3361Sopenharmony_ci 421159b3361Sopenharmony_ci 422159b3361Sopenharmony_ci 423159b3361Sopenharmony_ci 424159b3361Sopenharmony_ci/************************************************************************ 425159b3361Sopenharmony_ci * allocate bits among 2 channels based on PE 426159b3361Sopenharmony_ci * mt 6/99 427159b3361Sopenharmony_ci * bugfixes rh 8/01: often allocated more than the allowed 4095 bits 428159b3361Sopenharmony_ci ************************************************************************/ 429159b3361Sopenharmony_ciint 430159b3361Sopenharmony_cion_pe(lame_internal_flags * gfc, const FLOAT pe[][2], int targ_bits[2], int mean_bits, int gr, int cbr) 431159b3361Sopenharmony_ci{ 432159b3361Sopenharmony_ci SessionConfig_t const *const cfg = &gfc->cfg; 433159b3361Sopenharmony_ci int extra_bits = 0, tbits, bits; 434159b3361Sopenharmony_ci int add_bits[2] = {0, 0}; 435159b3361Sopenharmony_ci int max_bits; /* maximum allowed bits for this granule */ 436159b3361Sopenharmony_ci int ch; 437159b3361Sopenharmony_ci 438159b3361Sopenharmony_ci /* allocate targ_bits for granule */ 439159b3361Sopenharmony_ci ResvMaxBits(gfc, mean_bits, &tbits, &extra_bits, cbr); 440159b3361Sopenharmony_ci max_bits = tbits + extra_bits; 441159b3361Sopenharmony_ci if (max_bits > MAX_BITS_PER_GRANULE) /* hard limit per granule */ 442159b3361Sopenharmony_ci max_bits = MAX_BITS_PER_GRANULE; 443159b3361Sopenharmony_ci 444159b3361Sopenharmony_ci for (bits = 0, ch = 0; ch < cfg->channels_out; ++ch) { 445159b3361Sopenharmony_ci /****************************************************************** 446159b3361Sopenharmony_ci * allocate bits for each channel 447159b3361Sopenharmony_ci ******************************************************************/ 448159b3361Sopenharmony_ci targ_bits[ch] = Min(MAX_BITS_PER_CHANNEL, tbits / cfg->channels_out); 449159b3361Sopenharmony_ci 450159b3361Sopenharmony_ci add_bits[ch] = targ_bits[ch] * pe[gr][ch] / 700.0 - targ_bits[ch]; 451159b3361Sopenharmony_ci 452159b3361Sopenharmony_ci /* at most increase bits by 1.5*average */ 453159b3361Sopenharmony_ci if (add_bits[ch] > mean_bits * 3 / 4) 454159b3361Sopenharmony_ci add_bits[ch] = mean_bits * 3 / 4; 455159b3361Sopenharmony_ci if (add_bits[ch] < 0) 456159b3361Sopenharmony_ci add_bits[ch] = 0; 457159b3361Sopenharmony_ci 458159b3361Sopenharmony_ci if (add_bits[ch] + targ_bits[ch] > MAX_BITS_PER_CHANNEL) 459159b3361Sopenharmony_ci add_bits[ch] = Max(0, MAX_BITS_PER_CHANNEL - targ_bits[ch]); 460159b3361Sopenharmony_ci 461159b3361Sopenharmony_ci bits += add_bits[ch]; 462159b3361Sopenharmony_ci } 463159b3361Sopenharmony_ci if (bits > extra_bits && bits > 0) { 464159b3361Sopenharmony_ci for (ch = 0; ch < cfg->channels_out; ++ch) { 465159b3361Sopenharmony_ci add_bits[ch] = extra_bits * add_bits[ch] / bits; 466159b3361Sopenharmony_ci } 467159b3361Sopenharmony_ci } 468159b3361Sopenharmony_ci 469159b3361Sopenharmony_ci for (ch = 0; ch < cfg->channels_out; ++ch) { 470159b3361Sopenharmony_ci targ_bits[ch] += add_bits[ch]; 471159b3361Sopenharmony_ci extra_bits -= add_bits[ch]; 472159b3361Sopenharmony_ci } 473159b3361Sopenharmony_ci 474159b3361Sopenharmony_ci for (bits = 0, ch = 0; ch < cfg->channels_out; ++ch) { 475159b3361Sopenharmony_ci bits += targ_bits[ch]; 476159b3361Sopenharmony_ci } 477159b3361Sopenharmony_ci if (bits > MAX_BITS_PER_GRANULE) { 478159b3361Sopenharmony_ci int sum = 0; 479159b3361Sopenharmony_ci for (ch = 0; ch < cfg->channels_out; ++ch) { 480159b3361Sopenharmony_ci targ_bits[ch] *= MAX_BITS_PER_GRANULE; 481159b3361Sopenharmony_ci targ_bits[ch] /= bits; 482159b3361Sopenharmony_ci sum += targ_bits[ch]; 483159b3361Sopenharmony_ci } 484159b3361Sopenharmony_ci assert(sum <= MAX_BITS_PER_GRANULE); 485159b3361Sopenharmony_ci } 486159b3361Sopenharmony_ci 487159b3361Sopenharmony_ci return max_bits; 488159b3361Sopenharmony_ci} 489159b3361Sopenharmony_ci 490159b3361Sopenharmony_ci 491159b3361Sopenharmony_ci 492159b3361Sopenharmony_ci 493159b3361Sopenharmony_civoid 494159b3361Sopenharmony_cireduce_side(int targ_bits[2], FLOAT ms_ener_ratio, int mean_bits, int max_bits) 495159b3361Sopenharmony_ci{ 496159b3361Sopenharmony_ci int move_bits; 497159b3361Sopenharmony_ci FLOAT fac; 498159b3361Sopenharmony_ci 499159b3361Sopenharmony_ci assert(max_bits <= MAX_BITS_PER_GRANULE); 500159b3361Sopenharmony_ci assert(targ_bits[0] + targ_bits[1] <= MAX_BITS_PER_GRANULE); 501159b3361Sopenharmony_ci 502159b3361Sopenharmony_ci /* ms_ener_ratio = 0: allocate 66/33 mid/side fac=.33 503159b3361Sopenharmony_ci * ms_ener_ratio =.5: allocate 50/50 mid/side fac= 0 */ 504159b3361Sopenharmony_ci /* 75/25 split is fac=.5 */ 505159b3361Sopenharmony_ci /* float fac = .50*(.5-ms_ener_ratio[gr])/.5; */ 506159b3361Sopenharmony_ci fac = .33 * (.5 - ms_ener_ratio) / .5; 507159b3361Sopenharmony_ci if (fac < 0) 508159b3361Sopenharmony_ci fac = 0; 509159b3361Sopenharmony_ci if (fac > .5) 510159b3361Sopenharmony_ci fac = .5; 511159b3361Sopenharmony_ci 512159b3361Sopenharmony_ci /* number of bits to move from side channel to mid channel */ 513159b3361Sopenharmony_ci /* move_bits = fac*targ_bits[1]; */ 514159b3361Sopenharmony_ci move_bits = fac * .5 * (targ_bits[0] + targ_bits[1]); 515159b3361Sopenharmony_ci 516159b3361Sopenharmony_ci if (move_bits > MAX_BITS_PER_CHANNEL - targ_bits[0]) { 517159b3361Sopenharmony_ci move_bits = MAX_BITS_PER_CHANNEL - targ_bits[0]; 518159b3361Sopenharmony_ci } 519159b3361Sopenharmony_ci if (move_bits < 0) 520159b3361Sopenharmony_ci move_bits = 0; 521159b3361Sopenharmony_ci 522159b3361Sopenharmony_ci if (targ_bits[1] >= 125) { 523159b3361Sopenharmony_ci /* dont reduce side channel below 125 bits */ 524159b3361Sopenharmony_ci if (targ_bits[1] - move_bits > 125) { 525159b3361Sopenharmony_ci 526159b3361Sopenharmony_ci /* if mid channel already has 2x more than average, dont bother */ 527159b3361Sopenharmony_ci /* mean_bits = bits per granule (for both channels) */ 528159b3361Sopenharmony_ci if (targ_bits[0] < mean_bits) 529159b3361Sopenharmony_ci targ_bits[0] += move_bits; 530159b3361Sopenharmony_ci targ_bits[1] -= move_bits; 531159b3361Sopenharmony_ci } 532159b3361Sopenharmony_ci else { 533159b3361Sopenharmony_ci targ_bits[0] += targ_bits[1] - 125; 534159b3361Sopenharmony_ci targ_bits[1] = 125; 535159b3361Sopenharmony_ci } 536159b3361Sopenharmony_ci } 537159b3361Sopenharmony_ci 538159b3361Sopenharmony_ci move_bits = targ_bits[0] + targ_bits[1]; 539159b3361Sopenharmony_ci if (move_bits > max_bits) { 540159b3361Sopenharmony_ci targ_bits[0] = (max_bits * targ_bits[0]) / move_bits; 541159b3361Sopenharmony_ci targ_bits[1] = (max_bits * targ_bits[1]) / move_bits; 542159b3361Sopenharmony_ci } 543159b3361Sopenharmony_ci assert(targ_bits[0] <= MAX_BITS_PER_CHANNEL); 544159b3361Sopenharmony_ci assert(targ_bits[1] <= MAX_BITS_PER_CHANNEL); 545159b3361Sopenharmony_ci assert(targ_bits[0] + targ_bits[1] <= MAX_BITS_PER_GRANULE); 546159b3361Sopenharmony_ci} 547159b3361Sopenharmony_ci 548159b3361Sopenharmony_ci 549159b3361Sopenharmony_ci/** 550159b3361Sopenharmony_ci * Robert Hegemann 2001-04-27: 551159b3361Sopenharmony_ci * this adjusts the ATH, keeping the original noise floor 552159b3361Sopenharmony_ci * affects the higher frequencies more than the lower ones 553159b3361Sopenharmony_ci */ 554159b3361Sopenharmony_ci 555159b3361Sopenharmony_ciFLOAT 556159b3361Sopenharmony_ciathAdjust(FLOAT a, FLOAT x, FLOAT athFloor, float ATHfixpoint) 557159b3361Sopenharmony_ci{ 558159b3361Sopenharmony_ci /* work in progress 559159b3361Sopenharmony_ci */ 560159b3361Sopenharmony_ci FLOAT const o = 90.30873362f; 561159b3361Sopenharmony_ci FLOAT const p = (ATHfixpoint < 1.f) ? 94.82444863f : ATHfixpoint; 562159b3361Sopenharmony_ci FLOAT u = FAST_LOG10_X(x, 10.0f); 563159b3361Sopenharmony_ci FLOAT const v = a * a; 564159b3361Sopenharmony_ci FLOAT w = 0.0f; 565159b3361Sopenharmony_ci u -= athFloor; /* undo scaling */ 566159b3361Sopenharmony_ci if (v > 1E-20f) 567159b3361Sopenharmony_ci w = 1.f + FAST_LOG10_X(v, 10.0f / o); 568159b3361Sopenharmony_ci if (w < 0) 569159b3361Sopenharmony_ci w = 0.f; 570159b3361Sopenharmony_ci u *= w; 571159b3361Sopenharmony_ci u += athFloor + o - p; /* redo scaling */ 572159b3361Sopenharmony_ci 573159b3361Sopenharmony_ci return powf(10.f, 0.1f * u); 574159b3361Sopenharmony_ci} 575159b3361Sopenharmony_ci 576159b3361Sopenharmony_ci 577159b3361Sopenharmony_ci 578159b3361Sopenharmony_ci/*************************************************************************/ 579159b3361Sopenharmony_ci/* calc_xmin */ 580159b3361Sopenharmony_ci/*************************************************************************/ 581159b3361Sopenharmony_ci 582159b3361Sopenharmony_ci/* 583159b3361Sopenharmony_ci Calculate the allowed distortion for each scalefactor band, 584159b3361Sopenharmony_ci as determined by the psychoacoustic model. 585159b3361Sopenharmony_ci xmin(sb) = ratio(sb) * en(sb) / bw(sb) 586159b3361Sopenharmony_ci 587159b3361Sopenharmony_ci returns number of sfb's with energy > ATH 588159b3361Sopenharmony_ci*/ 589159b3361Sopenharmony_ci 590159b3361Sopenharmony_ciint 591159b3361Sopenharmony_cicalc_xmin(lame_internal_flags const *gfc, 592159b3361Sopenharmony_ci III_psy_ratio const *const ratio, gr_info * const cod_info, FLOAT * pxmin) 593159b3361Sopenharmony_ci{ 594159b3361Sopenharmony_ci SessionConfig_t const *const cfg = &gfc->cfg; 595159b3361Sopenharmony_ci int sfb, gsfb, j = 0, ath_over = 0, k; 596159b3361Sopenharmony_ci ATH_t const *const ATH = gfc->ATH; 597159b3361Sopenharmony_ci const FLOAT *const xr = cod_info->xr; 598159b3361Sopenharmony_ci int max_nonzero; 599159b3361Sopenharmony_ci 600159b3361Sopenharmony_ci for (gsfb = 0; gsfb < cod_info->psy_lmax; gsfb++) { 601159b3361Sopenharmony_ci FLOAT en0, xmin; 602159b3361Sopenharmony_ci FLOAT rh1, rh2, rh3; 603159b3361Sopenharmony_ci int width, l; 604159b3361Sopenharmony_ci 605159b3361Sopenharmony_ci xmin = athAdjust(ATH->adjust_factor, ATH->l[gsfb], ATH->floor, cfg->ATHfixpoint); 606159b3361Sopenharmony_ci xmin *= gfc->sv_qnt.longfact[gsfb]; 607159b3361Sopenharmony_ci 608159b3361Sopenharmony_ci width = cod_info->width[gsfb]; 609159b3361Sopenharmony_ci rh1 = xmin / width; 610159b3361Sopenharmony_ci#ifdef DBL_EPSILON 611159b3361Sopenharmony_ci rh2 = DBL_EPSILON; 612159b3361Sopenharmony_ci#else 613159b3361Sopenharmony_ci rh2 = 2.2204460492503131e-016; 614159b3361Sopenharmony_ci#endif 615159b3361Sopenharmony_ci en0 = 0.0; 616159b3361Sopenharmony_ci for (l = 0; l < width; ++l) { 617159b3361Sopenharmony_ci FLOAT const xa = xr[j++]; 618159b3361Sopenharmony_ci FLOAT const x2 = xa * xa; 619159b3361Sopenharmony_ci en0 += x2; 620159b3361Sopenharmony_ci rh2 += (x2 < rh1) ? x2 : rh1; 621159b3361Sopenharmony_ci } 622159b3361Sopenharmony_ci if (en0 > xmin) 623159b3361Sopenharmony_ci ath_over++; 624159b3361Sopenharmony_ci 625159b3361Sopenharmony_ci if (en0 < xmin) { 626159b3361Sopenharmony_ci rh3 = en0; 627159b3361Sopenharmony_ci } 628159b3361Sopenharmony_ci else if (rh2 < xmin) { 629159b3361Sopenharmony_ci rh3 = xmin; 630159b3361Sopenharmony_ci } 631159b3361Sopenharmony_ci else { 632159b3361Sopenharmony_ci rh3 = rh2; 633159b3361Sopenharmony_ci } 634159b3361Sopenharmony_ci xmin = rh3; 635159b3361Sopenharmony_ci { 636159b3361Sopenharmony_ci FLOAT const e = ratio->en.l[gsfb]; 637159b3361Sopenharmony_ci if (e > 1e-12f) { 638159b3361Sopenharmony_ci FLOAT x; 639159b3361Sopenharmony_ci x = en0 * ratio->thm.l[gsfb] / e; 640159b3361Sopenharmony_ci x *= gfc->sv_qnt.longfact[gsfb]; 641159b3361Sopenharmony_ci if (xmin < x) 642159b3361Sopenharmony_ci xmin = x; 643159b3361Sopenharmony_ci } 644159b3361Sopenharmony_ci } 645159b3361Sopenharmony_ci xmin = Max(xmin, DBL_EPSILON); 646159b3361Sopenharmony_ci cod_info->energy_above_cutoff[gsfb] = (en0 > xmin+1e-14f) ? 1 : 0; 647159b3361Sopenharmony_ci *pxmin++ = xmin; 648159b3361Sopenharmony_ci } /* end of long block loop */ 649159b3361Sopenharmony_ci 650159b3361Sopenharmony_ci 651159b3361Sopenharmony_ci 652159b3361Sopenharmony_ci 653159b3361Sopenharmony_ci /*use this function to determine the highest non-zero coeff */ 654159b3361Sopenharmony_ci max_nonzero = 0; 655159b3361Sopenharmony_ci for (k = 575; k > 0; --k) { 656159b3361Sopenharmony_ci if (fabs(xr[k]) > 1e-12f) { 657159b3361Sopenharmony_ci max_nonzero = k; 658159b3361Sopenharmony_ci break; 659159b3361Sopenharmony_ci } 660159b3361Sopenharmony_ci } 661159b3361Sopenharmony_ci if (cod_info->block_type != SHORT_TYPE) { /* NORM, START or STOP type, but not SHORT */ 662159b3361Sopenharmony_ci max_nonzero |= 1; /* only odd numbers */ 663159b3361Sopenharmony_ci } 664159b3361Sopenharmony_ci else { 665159b3361Sopenharmony_ci max_nonzero /= 6; /* 3 short blocks */ 666159b3361Sopenharmony_ci max_nonzero *= 6; 667159b3361Sopenharmony_ci max_nonzero += 5; 668159b3361Sopenharmony_ci } 669159b3361Sopenharmony_ci 670159b3361Sopenharmony_ci if (gfc->sv_qnt.sfb21_extra == 0 && cfg->samplerate_out < 44000) { 671159b3361Sopenharmony_ci int const sfb_l = (cfg->samplerate_out <= 8000) ? 17 : 21; 672159b3361Sopenharmony_ci int const sfb_s = (cfg->samplerate_out <= 8000) ? 9 : 12; 673159b3361Sopenharmony_ci int limit = 575; 674159b3361Sopenharmony_ci if (cod_info->block_type != SHORT_TYPE) { /* NORM, START or STOP type, but not SHORT */ 675159b3361Sopenharmony_ci limit = gfc->scalefac_band.l[sfb_l]-1; 676159b3361Sopenharmony_ci } 677159b3361Sopenharmony_ci else { 678159b3361Sopenharmony_ci limit = 3*gfc->scalefac_band.s[sfb_s]-1; 679159b3361Sopenharmony_ci } 680159b3361Sopenharmony_ci if (max_nonzero > limit) { 681159b3361Sopenharmony_ci max_nonzero = limit; 682159b3361Sopenharmony_ci } 683159b3361Sopenharmony_ci } 684159b3361Sopenharmony_ci cod_info->max_nonzero_coeff = max_nonzero; 685159b3361Sopenharmony_ci 686159b3361Sopenharmony_ci 687159b3361Sopenharmony_ci 688159b3361Sopenharmony_ci for (sfb = cod_info->sfb_smin; gsfb < cod_info->psymax; sfb++, gsfb += 3) { 689159b3361Sopenharmony_ci int width, b, l; 690159b3361Sopenharmony_ci FLOAT tmpATH; 691159b3361Sopenharmony_ci 692159b3361Sopenharmony_ci tmpATH = athAdjust(ATH->adjust_factor, ATH->s[sfb], ATH->floor, cfg->ATHfixpoint); 693159b3361Sopenharmony_ci tmpATH *= gfc->sv_qnt.shortfact[sfb]; 694159b3361Sopenharmony_ci 695159b3361Sopenharmony_ci width = cod_info->width[gsfb]; 696159b3361Sopenharmony_ci for (b = 0; b < 3; b++) { 697159b3361Sopenharmony_ci FLOAT en0 = 0.0, xmin = tmpATH; 698159b3361Sopenharmony_ci FLOAT rh1, rh2, rh3; 699159b3361Sopenharmony_ci 700159b3361Sopenharmony_ci rh1 = tmpATH / width; 701159b3361Sopenharmony_ci#ifdef DBL_EPSILON 702159b3361Sopenharmony_ci rh2 = DBL_EPSILON; 703159b3361Sopenharmony_ci#else 704159b3361Sopenharmony_ci rh2 = 2.2204460492503131e-016; 705159b3361Sopenharmony_ci#endif 706159b3361Sopenharmony_ci for (l = 0; l < width; ++l) { 707159b3361Sopenharmony_ci FLOAT const xa = xr[j++]; 708159b3361Sopenharmony_ci FLOAT const x2 = xa * xa; 709159b3361Sopenharmony_ci en0 += x2; 710159b3361Sopenharmony_ci rh2 += (x2 < rh1) ? x2 : rh1; 711159b3361Sopenharmony_ci } 712159b3361Sopenharmony_ci if (en0 > tmpATH) 713159b3361Sopenharmony_ci ath_over++; 714159b3361Sopenharmony_ci 715159b3361Sopenharmony_ci if (en0 < tmpATH) { 716159b3361Sopenharmony_ci rh3 = en0; 717159b3361Sopenharmony_ci } 718159b3361Sopenharmony_ci else if (rh2 < tmpATH) { 719159b3361Sopenharmony_ci rh3 = tmpATH; 720159b3361Sopenharmony_ci } 721159b3361Sopenharmony_ci else { 722159b3361Sopenharmony_ci rh3 = rh2; 723159b3361Sopenharmony_ci } 724159b3361Sopenharmony_ci xmin = rh3; 725159b3361Sopenharmony_ci { 726159b3361Sopenharmony_ci FLOAT const e = ratio->en.s[sfb][b]; 727159b3361Sopenharmony_ci if (e > 1e-12f) { 728159b3361Sopenharmony_ci FLOAT x; 729159b3361Sopenharmony_ci x = en0 * ratio->thm.s[sfb][b] / e; 730159b3361Sopenharmony_ci x *= gfc->sv_qnt.shortfact[sfb]; 731159b3361Sopenharmony_ci if (xmin < x) 732159b3361Sopenharmony_ci xmin = x; 733159b3361Sopenharmony_ci } 734159b3361Sopenharmony_ci } 735159b3361Sopenharmony_ci xmin = Max(xmin, DBL_EPSILON); 736159b3361Sopenharmony_ci cod_info->energy_above_cutoff[gsfb+b] = (en0 > xmin+1e-14f) ? 1 : 0; 737159b3361Sopenharmony_ci *pxmin++ = xmin; 738159b3361Sopenharmony_ci } /* b */ 739159b3361Sopenharmony_ci if (cfg->use_temporal_masking_effect) { 740159b3361Sopenharmony_ci if (pxmin[-3] > pxmin[-3 + 1]) 741159b3361Sopenharmony_ci pxmin[-3 + 1] += (pxmin[-3] - pxmin[-3 + 1]) * gfc->cd_psy->decay; 742159b3361Sopenharmony_ci if (pxmin[-3 + 1] > pxmin[-3 + 2]) 743159b3361Sopenharmony_ci pxmin[-3 + 2] += (pxmin[-3 + 1] - pxmin[-3 + 2]) * gfc->cd_psy->decay; 744159b3361Sopenharmony_ci } 745159b3361Sopenharmony_ci } /* end of short block sfb loop */ 746159b3361Sopenharmony_ci 747159b3361Sopenharmony_ci return ath_over; 748159b3361Sopenharmony_ci} 749159b3361Sopenharmony_ci 750159b3361Sopenharmony_ci 751159b3361Sopenharmony_cistatic FLOAT 752159b3361Sopenharmony_cicalc_noise_core_c(const gr_info * const cod_info, int *startline, int l, FLOAT step) 753159b3361Sopenharmony_ci{ 754159b3361Sopenharmony_ci FLOAT noise = 0; 755159b3361Sopenharmony_ci int j = *startline; 756159b3361Sopenharmony_ci const int *const ix = cod_info->l3_enc; 757159b3361Sopenharmony_ci 758159b3361Sopenharmony_ci if (j > cod_info->count1) { 759159b3361Sopenharmony_ci while (l--) { 760159b3361Sopenharmony_ci FLOAT temp; 761159b3361Sopenharmony_ci temp = cod_info->xr[j]; 762159b3361Sopenharmony_ci j++; 763159b3361Sopenharmony_ci noise += temp * temp; 764159b3361Sopenharmony_ci temp = cod_info->xr[j]; 765159b3361Sopenharmony_ci j++; 766159b3361Sopenharmony_ci noise += temp * temp; 767159b3361Sopenharmony_ci } 768159b3361Sopenharmony_ci } 769159b3361Sopenharmony_ci else if (j > cod_info->big_values) { 770159b3361Sopenharmony_ci FLOAT ix01[2]; 771159b3361Sopenharmony_ci ix01[0] = 0; 772159b3361Sopenharmony_ci ix01[1] = step; 773159b3361Sopenharmony_ci while (l--) { 774159b3361Sopenharmony_ci FLOAT temp; 775159b3361Sopenharmony_ci temp = fabs(cod_info->xr[j]) - ix01[ix[j]]; 776159b3361Sopenharmony_ci j++; 777159b3361Sopenharmony_ci noise += temp * temp; 778159b3361Sopenharmony_ci temp = fabs(cod_info->xr[j]) - ix01[ix[j]]; 779159b3361Sopenharmony_ci j++; 780159b3361Sopenharmony_ci noise += temp * temp; 781159b3361Sopenharmony_ci } 782159b3361Sopenharmony_ci } 783159b3361Sopenharmony_ci else { 784159b3361Sopenharmony_ci while (l--) { 785159b3361Sopenharmony_ci FLOAT temp; 786159b3361Sopenharmony_ci temp = fabs(cod_info->xr[j]) - pow43[ix[j]] * step; 787159b3361Sopenharmony_ci j++; 788159b3361Sopenharmony_ci noise += temp * temp; 789159b3361Sopenharmony_ci temp = fabs(cod_info->xr[j]) - pow43[ix[j]] * step; 790159b3361Sopenharmony_ci j++; 791159b3361Sopenharmony_ci noise += temp * temp; 792159b3361Sopenharmony_ci } 793159b3361Sopenharmony_ci } 794159b3361Sopenharmony_ci 795159b3361Sopenharmony_ci *startline = j; 796159b3361Sopenharmony_ci return noise; 797159b3361Sopenharmony_ci} 798159b3361Sopenharmony_ci 799159b3361Sopenharmony_ci 800159b3361Sopenharmony_ci/*************************************************************************/ 801159b3361Sopenharmony_ci/* calc_noise */ 802159b3361Sopenharmony_ci/*************************************************************************/ 803159b3361Sopenharmony_ci 804159b3361Sopenharmony_ci/* -oo dB => -1.00 */ 805159b3361Sopenharmony_ci/* - 6 dB => -0.97 */ 806159b3361Sopenharmony_ci/* - 3 dB => -0.80 */ 807159b3361Sopenharmony_ci/* - 2 dB => -0.64 */ 808159b3361Sopenharmony_ci/* - 1 dB => -0.38 */ 809159b3361Sopenharmony_ci/* 0 dB => 0.00 */ 810159b3361Sopenharmony_ci/* + 1 dB => +0.49 */ 811159b3361Sopenharmony_ci/* + 2 dB => +1.06 */ 812159b3361Sopenharmony_ci/* + 3 dB => +1.68 */ 813159b3361Sopenharmony_ci/* + 6 dB => +3.69 */ 814159b3361Sopenharmony_ci/* +10 dB => +6.45 */ 815159b3361Sopenharmony_ci 816159b3361Sopenharmony_ciint 817159b3361Sopenharmony_cicalc_noise(gr_info const *const cod_info, 818159b3361Sopenharmony_ci FLOAT const *l3_xmin, 819159b3361Sopenharmony_ci FLOAT * distort, calc_noise_result * const res, calc_noise_data * prev_noise) 820159b3361Sopenharmony_ci{ 821159b3361Sopenharmony_ci int sfb, l, over = 0; 822159b3361Sopenharmony_ci FLOAT over_noise_db = 0; 823159b3361Sopenharmony_ci FLOAT tot_noise_db = 0; /* 0 dB relative to masking */ 824159b3361Sopenharmony_ci FLOAT max_noise = -20.0; /* -200 dB relative to masking */ 825159b3361Sopenharmony_ci int j = 0; 826159b3361Sopenharmony_ci const int *scalefac = cod_info->scalefac; 827159b3361Sopenharmony_ci 828159b3361Sopenharmony_ci res->over_SSD = 0; 829159b3361Sopenharmony_ci 830159b3361Sopenharmony_ci 831159b3361Sopenharmony_ci for (sfb = 0; sfb < cod_info->psymax; sfb++) { 832159b3361Sopenharmony_ci int const s = 833159b3361Sopenharmony_ci cod_info->global_gain - (((*scalefac++) + (cod_info->preflag ? pretab[sfb] : 0)) 834159b3361Sopenharmony_ci << (cod_info->scalefac_scale + 1)) 835159b3361Sopenharmony_ci - cod_info->subblock_gain[cod_info->window[sfb]] * 8; 836159b3361Sopenharmony_ci FLOAT const r_l3_xmin = 1.f / *l3_xmin++; 837159b3361Sopenharmony_ci FLOAT distort_ = 0.0f; 838159b3361Sopenharmony_ci FLOAT noise = 0.0f; 839159b3361Sopenharmony_ci 840159b3361Sopenharmony_ci if (prev_noise && (prev_noise->step[sfb] == s)) { 841159b3361Sopenharmony_ci 842159b3361Sopenharmony_ci /* use previously computed values */ 843159b3361Sopenharmony_ci j += cod_info->width[sfb]; 844159b3361Sopenharmony_ci distort_ = r_l3_xmin * prev_noise->noise[sfb]; 845159b3361Sopenharmony_ci 846159b3361Sopenharmony_ci noise = prev_noise->noise_log[sfb]; 847159b3361Sopenharmony_ci 848159b3361Sopenharmony_ci } 849159b3361Sopenharmony_ci else { 850159b3361Sopenharmony_ci FLOAT const step = POW20(s); 851159b3361Sopenharmony_ci l = cod_info->width[sfb] >> 1; 852159b3361Sopenharmony_ci 853159b3361Sopenharmony_ci if ((j + cod_info->width[sfb]) > cod_info->max_nonzero_coeff) { 854159b3361Sopenharmony_ci int usefullsize; 855159b3361Sopenharmony_ci usefullsize = cod_info->max_nonzero_coeff - j + 1; 856159b3361Sopenharmony_ci 857159b3361Sopenharmony_ci if (usefullsize > 0) 858159b3361Sopenharmony_ci l = usefullsize >> 1; 859159b3361Sopenharmony_ci else 860159b3361Sopenharmony_ci l = 0; 861159b3361Sopenharmony_ci } 862159b3361Sopenharmony_ci 863159b3361Sopenharmony_ci noise = calc_noise_core_c(cod_info, &j, l, step); 864159b3361Sopenharmony_ci 865159b3361Sopenharmony_ci 866159b3361Sopenharmony_ci if (prev_noise) { 867159b3361Sopenharmony_ci /* save noise values */ 868159b3361Sopenharmony_ci prev_noise->step[sfb] = s; 869159b3361Sopenharmony_ci prev_noise->noise[sfb] = noise; 870159b3361Sopenharmony_ci } 871159b3361Sopenharmony_ci 872159b3361Sopenharmony_ci distort_ = r_l3_xmin * noise; 873159b3361Sopenharmony_ci 874159b3361Sopenharmony_ci /* multiplying here is adding in dB, but can overflow */ 875159b3361Sopenharmony_ci noise = FAST_LOG10(Max(distort_, 1E-20f)); 876159b3361Sopenharmony_ci 877159b3361Sopenharmony_ci if (prev_noise) { 878159b3361Sopenharmony_ci /* save noise values */ 879159b3361Sopenharmony_ci prev_noise->noise_log[sfb] = noise; 880159b3361Sopenharmony_ci } 881159b3361Sopenharmony_ci } 882159b3361Sopenharmony_ci *distort++ = distort_; 883159b3361Sopenharmony_ci 884159b3361Sopenharmony_ci if (prev_noise) { 885159b3361Sopenharmony_ci /* save noise values */ 886159b3361Sopenharmony_ci prev_noise->global_gain = cod_info->global_gain;; 887159b3361Sopenharmony_ci } 888159b3361Sopenharmony_ci 889159b3361Sopenharmony_ci 890159b3361Sopenharmony_ci /*tot_noise *= Max(noise, 1E-20); */ 891159b3361Sopenharmony_ci tot_noise_db += noise; 892159b3361Sopenharmony_ci 893159b3361Sopenharmony_ci if (noise > 0.0) { 894159b3361Sopenharmony_ci int tmp; 895159b3361Sopenharmony_ci 896159b3361Sopenharmony_ci tmp = Max((int) (noise * 10 + .5), 1); 897159b3361Sopenharmony_ci res->over_SSD += tmp * tmp; 898159b3361Sopenharmony_ci 899159b3361Sopenharmony_ci over++; 900159b3361Sopenharmony_ci /* multiplying here is adding in dB -but can overflow */ 901159b3361Sopenharmony_ci /*over_noise *= noise; */ 902159b3361Sopenharmony_ci over_noise_db += noise; 903159b3361Sopenharmony_ci } 904159b3361Sopenharmony_ci max_noise = Max(max_noise, noise); 905159b3361Sopenharmony_ci 906159b3361Sopenharmony_ci } 907159b3361Sopenharmony_ci 908159b3361Sopenharmony_ci res->over_count = over; 909159b3361Sopenharmony_ci res->tot_noise = tot_noise_db; 910159b3361Sopenharmony_ci res->over_noise = over_noise_db; 911159b3361Sopenharmony_ci res->max_noise = max_noise; 912159b3361Sopenharmony_ci 913159b3361Sopenharmony_ci return over; 914159b3361Sopenharmony_ci} 915159b3361Sopenharmony_ci 916159b3361Sopenharmony_ci 917159b3361Sopenharmony_ci 918159b3361Sopenharmony_ci 919159b3361Sopenharmony_ci 920159b3361Sopenharmony_ci 921159b3361Sopenharmony_ci 922159b3361Sopenharmony_ci 923159b3361Sopenharmony_ci/************************************************************************ 924159b3361Sopenharmony_ci * 925159b3361Sopenharmony_ci * set_pinfo() 926159b3361Sopenharmony_ci * 927159b3361Sopenharmony_ci * updates plotting data 928159b3361Sopenharmony_ci * 929159b3361Sopenharmony_ci * Mark Taylor 2000-??-?? 930159b3361Sopenharmony_ci * 931159b3361Sopenharmony_ci * Robert Hegemann: moved noise/distortion calc into it 932159b3361Sopenharmony_ci * 933159b3361Sopenharmony_ci ************************************************************************/ 934159b3361Sopenharmony_ci 935159b3361Sopenharmony_cistatic void 936159b3361Sopenharmony_ciset_pinfo(lame_internal_flags const *gfc, 937159b3361Sopenharmony_ci gr_info * const cod_info, const III_psy_ratio * const ratio, const int gr, const int ch) 938159b3361Sopenharmony_ci{ 939159b3361Sopenharmony_ci SessionConfig_t const *const cfg = &gfc->cfg; 940159b3361Sopenharmony_ci int sfb, sfb2; 941159b3361Sopenharmony_ci int j, i, l, start, end, bw; 942159b3361Sopenharmony_ci FLOAT en0, en1; 943159b3361Sopenharmony_ci FLOAT const ifqstep = (cod_info->scalefac_scale == 0) ? .5 : 1.0; 944159b3361Sopenharmony_ci int const *const scalefac = cod_info->scalefac; 945159b3361Sopenharmony_ci 946159b3361Sopenharmony_ci FLOAT l3_xmin[SFBMAX], xfsf[SFBMAX]; 947159b3361Sopenharmony_ci calc_noise_result noise; 948159b3361Sopenharmony_ci 949159b3361Sopenharmony_ci (void) calc_xmin(gfc, ratio, cod_info, l3_xmin); 950159b3361Sopenharmony_ci (void) calc_noise(cod_info, l3_xmin, xfsf, &noise, 0); 951159b3361Sopenharmony_ci 952159b3361Sopenharmony_ci j = 0; 953159b3361Sopenharmony_ci sfb2 = cod_info->sfb_lmax; 954159b3361Sopenharmony_ci if (cod_info->block_type != SHORT_TYPE && !cod_info->mixed_block_flag) 955159b3361Sopenharmony_ci sfb2 = 22; 956159b3361Sopenharmony_ci for (sfb = 0; sfb < sfb2; sfb++) { 957159b3361Sopenharmony_ci start = gfc->scalefac_band.l[sfb]; 958159b3361Sopenharmony_ci end = gfc->scalefac_band.l[sfb + 1]; 959159b3361Sopenharmony_ci bw = end - start; 960159b3361Sopenharmony_ci for (en0 = 0.0; j < end; j++) 961159b3361Sopenharmony_ci en0 += cod_info->xr[j] * cod_info->xr[j]; 962159b3361Sopenharmony_ci en0 /= bw; 963159b3361Sopenharmony_ci /* convert to MDCT units */ 964159b3361Sopenharmony_ci en1 = 1e15; /* scaling so it shows up on FFT plot */ 965159b3361Sopenharmony_ci gfc->pinfo->en[gr][ch][sfb] = en1 * en0; 966159b3361Sopenharmony_ci gfc->pinfo->xfsf[gr][ch][sfb] = en1 * l3_xmin[sfb] * xfsf[sfb] / bw; 967159b3361Sopenharmony_ci 968159b3361Sopenharmony_ci if (ratio->en.l[sfb] > 0 && !cfg->ATHonly) 969159b3361Sopenharmony_ci en0 = en0 / ratio->en.l[sfb]; 970159b3361Sopenharmony_ci else 971159b3361Sopenharmony_ci en0 = 0.0; 972159b3361Sopenharmony_ci 973159b3361Sopenharmony_ci gfc->pinfo->thr[gr][ch][sfb] = en1 * Max(en0 * ratio->thm.l[sfb], gfc->ATH->l[sfb]); 974159b3361Sopenharmony_ci 975159b3361Sopenharmony_ci /* there is no scalefactor bands >= SBPSY_l */ 976159b3361Sopenharmony_ci gfc->pinfo->LAMEsfb[gr][ch][sfb] = 0; 977159b3361Sopenharmony_ci if (cod_info->preflag && sfb >= 11) 978159b3361Sopenharmony_ci gfc->pinfo->LAMEsfb[gr][ch][sfb] = -ifqstep * pretab[sfb]; 979159b3361Sopenharmony_ci 980159b3361Sopenharmony_ci if (sfb < SBPSY_l) { 981159b3361Sopenharmony_ci assert(scalefac[sfb] >= 0); /* scfsi should be decoded by caller side */ 982159b3361Sopenharmony_ci gfc->pinfo->LAMEsfb[gr][ch][sfb] -= ifqstep * scalefac[sfb]; 983159b3361Sopenharmony_ci } 984159b3361Sopenharmony_ci } /* for sfb */ 985159b3361Sopenharmony_ci 986159b3361Sopenharmony_ci if (cod_info->block_type == SHORT_TYPE) { 987159b3361Sopenharmony_ci sfb2 = sfb; 988159b3361Sopenharmony_ci for (sfb = cod_info->sfb_smin; sfb < SBMAX_s; sfb++) { 989159b3361Sopenharmony_ci start = gfc->scalefac_band.s[sfb]; 990159b3361Sopenharmony_ci end = gfc->scalefac_band.s[sfb + 1]; 991159b3361Sopenharmony_ci bw = end - start; 992159b3361Sopenharmony_ci for (i = 0; i < 3; i++) { 993159b3361Sopenharmony_ci for (en0 = 0.0, l = start; l < end; l++) { 994159b3361Sopenharmony_ci en0 += cod_info->xr[j] * cod_info->xr[j]; 995159b3361Sopenharmony_ci j++; 996159b3361Sopenharmony_ci } 997159b3361Sopenharmony_ci en0 = Max(en0 / bw, 1e-20); 998159b3361Sopenharmony_ci /* convert to MDCT units */ 999159b3361Sopenharmony_ci en1 = 1e15; /* scaling so it shows up on FFT plot */ 1000159b3361Sopenharmony_ci 1001159b3361Sopenharmony_ci gfc->pinfo->en_s[gr][ch][3 * sfb + i] = en1 * en0; 1002159b3361Sopenharmony_ci gfc->pinfo->xfsf_s[gr][ch][3 * sfb + i] = en1 * l3_xmin[sfb2] * xfsf[sfb2] / bw; 1003159b3361Sopenharmony_ci if (ratio->en.s[sfb][i] > 0) 1004159b3361Sopenharmony_ci en0 = en0 / ratio->en.s[sfb][i]; 1005159b3361Sopenharmony_ci else 1006159b3361Sopenharmony_ci en0 = 0.0; 1007159b3361Sopenharmony_ci if (cfg->ATHonly || cfg->ATHshort) 1008159b3361Sopenharmony_ci en0 = 0; 1009159b3361Sopenharmony_ci 1010159b3361Sopenharmony_ci gfc->pinfo->thr_s[gr][ch][3 * sfb + i] = 1011159b3361Sopenharmony_ci en1 * Max(en0 * ratio->thm.s[sfb][i], gfc->ATH->s[sfb]); 1012159b3361Sopenharmony_ci 1013159b3361Sopenharmony_ci /* there is no scalefactor bands >= SBPSY_s */ 1014159b3361Sopenharmony_ci gfc->pinfo->LAMEsfb_s[gr][ch][3 * sfb + i] 1015159b3361Sopenharmony_ci = -2.0 * cod_info->subblock_gain[i]; 1016159b3361Sopenharmony_ci if (sfb < SBPSY_s) { 1017159b3361Sopenharmony_ci gfc->pinfo->LAMEsfb_s[gr][ch][3 * sfb + i] -= ifqstep * scalefac[sfb2]; 1018159b3361Sopenharmony_ci } 1019159b3361Sopenharmony_ci sfb2++; 1020159b3361Sopenharmony_ci } 1021159b3361Sopenharmony_ci } 1022159b3361Sopenharmony_ci } /* block type short */ 1023159b3361Sopenharmony_ci gfc->pinfo->LAMEqss[gr][ch] = cod_info->global_gain; 1024159b3361Sopenharmony_ci gfc->pinfo->LAMEmainbits[gr][ch] = cod_info->part2_3_length + cod_info->part2_length; 1025159b3361Sopenharmony_ci gfc->pinfo->LAMEsfbits[gr][ch] = cod_info->part2_length; 1026159b3361Sopenharmony_ci 1027159b3361Sopenharmony_ci gfc->pinfo->over[gr][ch] = noise.over_count; 1028159b3361Sopenharmony_ci gfc->pinfo->max_noise[gr][ch] = noise.max_noise * 10.0; 1029159b3361Sopenharmony_ci gfc->pinfo->over_noise[gr][ch] = noise.over_noise * 10.0; 1030159b3361Sopenharmony_ci gfc->pinfo->tot_noise[gr][ch] = noise.tot_noise * 10.0; 1031159b3361Sopenharmony_ci gfc->pinfo->over_SSD[gr][ch] = noise.over_SSD; 1032159b3361Sopenharmony_ci} 1033159b3361Sopenharmony_ci 1034159b3361Sopenharmony_ci 1035159b3361Sopenharmony_ci/************************************************************************ 1036159b3361Sopenharmony_ci * 1037159b3361Sopenharmony_ci * set_frame_pinfo() 1038159b3361Sopenharmony_ci * 1039159b3361Sopenharmony_ci * updates plotting data for a whole frame 1040159b3361Sopenharmony_ci * 1041159b3361Sopenharmony_ci * Robert Hegemann 2000-10-21 1042159b3361Sopenharmony_ci * 1043159b3361Sopenharmony_ci ************************************************************************/ 1044159b3361Sopenharmony_ci 1045159b3361Sopenharmony_civoid 1046159b3361Sopenharmony_ciset_frame_pinfo(lame_internal_flags * gfc, const III_psy_ratio ratio[2][2]) 1047159b3361Sopenharmony_ci{ 1048159b3361Sopenharmony_ci SessionConfig_t const *const cfg = &gfc->cfg; 1049159b3361Sopenharmony_ci int ch; 1050159b3361Sopenharmony_ci int gr; 1051159b3361Sopenharmony_ci 1052159b3361Sopenharmony_ci /* for every granule and channel patch l3_enc and set info 1053159b3361Sopenharmony_ci */ 1054159b3361Sopenharmony_ci for (gr = 0; gr < cfg->mode_gr; gr++) { 1055159b3361Sopenharmony_ci for (ch = 0; ch < cfg->channels_out; ch++) { 1056159b3361Sopenharmony_ci gr_info *const cod_info = &gfc->l3_side.tt[gr][ch]; 1057159b3361Sopenharmony_ci int scalefac_sav[SFBMAX]; 1058159b3361Sopenharmony_ci memcpy(scalefac_sav, cod_info->scalefac, sizeof(scalefac_sav)); 1059159b3361Sopenharmony_ci 1060159b3361Sopenharmony_ci /* reconstruct the scalefactors in case SCFSI was used 1061159b3361Sopenharmony_ci */ 1062159b3361Sopenharmony_ci if (gr == 1) { 1063159b3361Sopenharmony_ci int sfb; 1064159b3361Sopenharmony_ci for (sfb = 0; sfb < cod_info->sfb_lmax; sfb++) { 1065159b3361Sopenharmony_ci if (cod_info->scalefac[sfb] < 0) /* scfsi */ 1066159b3361Sopenharmony_ci cod_info->scalefac[sfb] = gfc->l3_side.tt[0][ch].scalefac[sfb]; 1067159b3361Sopenharmony_ci } 1068159b3361Sopenharmony_ci } 1069159b3361Sopenharmony_ci 1070159b3361Sopenharmony_ci set_pinfo(gfc, cod_info, &ratio[gr][ch], gr, ch); 1071159b3361Sopenharmony_ci memcpy(cod_info->scalefac, scalefac_sav, sizeof(scalefac_sav)); 1072159b3361Sopenharmony_ci } /* for ch */ 1073159b3361Sopenharmony_ci } /* for gr */ 1074159b3361Sopenharmony_ci} 1075