ref: 00626046473379e2be1594539504f8c43761ba61
dir: /libfaad/ps_dec.c/
/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR and PS decoding ** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com. ** ** $Id: ps_dec.c,v 1.1 2004/03/10 19:53:40 menno Exp $ **/ #include "common.h" #ifdef PS_DEC #include <stdlib.h> #include "ps_dec.h" /* constants */ #define NEGATE_IPD_MASK (0x1000) #define DECAY_SLOPE FRAC_CONST(0.05) #define CSQRT2 COEF_CONST(sqrt(2.0)) #define FRSQRT2 FRAC_CONST(1.0/sqrt(2.0)) /* tables */ /* filters are mirrored in coef 6, second half left out */ static const real_t p8_13_20[7] = { FRAC_CONST(0.00746082949812), FRAC_CONST(0.02270420949825), FRAC_CONST(0.04546865930473), FRAC_CONST(0.07266113929591), FRAC_CONST(0.09885108575264), FRAC_CONST(0.11793710567217), FRAC_CONST(0.125) }; static const real_t p2_13_20[7] = { FRAC_CONST(0.0), FRAC_CONST(0.01899487526049), FRAC_CONST(0.0), FRAC_CONST(-0.07293139167538), FRAC_CONST(0.0), FRAC_CONST(0.30596630545168), FRAC_CONST(0.5) }; static const real_t p12_13_34[7] = { FRAC_CONST(0.04081179924692), FRAC_CONST(0.03812810994926), FRAC_CONST(0.05144908135699), FRAC_CONST(0.06399831151592), FRAC_CONST(0.07428313801106), FRAC_CONST(0.08100347892914), FRAC_CONST(0.08333333333333) }; static const real_t p8_13_34[7] = { FRAC_CONST(0.01565675600122), FRAC_CONST(0.03752716391991), FRAC_CONST(0.05417891378782), FRAC_CONST(0.08417044116767), FRAC_CONST(0.10307344158036), FRAC_CONST(0.12222452249753), FRAC_CONST(0.125) }; static const real_t p4_13_34[7] = { FRAC_CONST(-0.05908211155639), FRAC_CONST(-0.04871498374946), FRAC_CONST(0.0), FRAC_CONST(0.07778723915851), FRAC_CONST(0.16486303567403), FRAC_CONST(0.23279856662996), FRAC_CONST(0.25) }; static const uint8_t delay_length_d[2][NO_ALLPASS_LINKS] = { { 1, 2, 3 } /* d_24kHz */, { 3, 4, 5 } /* d_48kHz */ }; static const real_t filter_a[NO_ALLPASS_LINKS] = { /* a(m) = exp(-d_48kHz(m)/7) */ FRAC_CONST(0.65143905753106), FRAC_CONST(0.56471812200776), FRAC_CONST(0.48954165955695) }; #if 0 #if 0 float f_center_20[12] = { 0.5/4, 1.5/4, 2.5/4, 3.5/4, 4.5/4*0, 5.5/4*0, -1.5/4, -0.5/4, 3.5/2, 2.5/2, 4.5/2, 5.5/2 }; #else float f_center_20[12] = { 0.5/8, 1.5/8, 2.5/8, 3.5/8, 4.5/8*0, 5.5/8*0, -1.5/8, -0.5/8, 3.5/4, 2.5/4, 4.5/4, 5.5/4 }; #endif float f_center_34[32] = { 1/12, 3/12, 5/12, 7/12, 9/12, 11/12, 13/12, 15/12, 17/12, -5/12, -3/12, -1/12, 17/8, 19/8, 5/8, 7/8, 9/8, 11/8, 13/8, 15/8, 9/4, 11/4, 13/4, 7/4, 17/4, 11/4, 13/4, 15/4, 17/4, 19/4, 21/4, 15/4 }; static const real_t frac_delay_q[] = { FRAC_CONST(0.43), FRAC_CONST(0.75), FRAC_CONST(0.347) }; #endif /* RE(ps->Phi_Fract_Qmf[j]) = (float)cos(M_PI*(j+0.5)*(0.39)); */ /* IM(ps->Phi_Fract_Qmf[j]) = (float)sin(M_PI*(j+0.5)*(0.39)); */ static const complex_t Phi_Fract_Qmf[] = { { FRAC_CONST(0.8181497455), FRAC_CONST(0.5750052333) }, { FRAC_CONST(-0.2638730407), FRAC_CONST(0.9645574093) }, { FRAC_CONST(-0.9969173074), FRAC_CONST(0.0784590989) }, { FRAC_CONST(-0.4115143716), FRAC_CONST(-0.9114032984) }, { FRAC_CONST(0.7181262970), FRAC_CONST(-0.6959127784) }, { FRAC_CONST(0.8980275989), FRAC_CONST(0.4399391711) }, { FRAC_CONST(-0.1097343117), FRAC_CONST(0.9939609766) }, { FRAC_CONST(-0.9723699093), FRAC_CONST(0.2334453613) }, { FRAC_CONST(-0.5490227938), FRAC_CONST(-0.8358073831) }, { FRAC_CONST(0.6004202366), FRAC_CONST(-0.7996846437) }, { FRAC_CONST(0.9557930231), FRAC_CONST(0.2940403223) }, { FRAC_CONST(0.0471064523), FRAC_CONST(0.9988898635) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(-0.6730124950), FRAC_CONST(-0.7396311164) }, { FRAC_CONST(0.4679298103), FRAC_CONST(-0.8837656379) }, { FRAC_CONST(0.9900236726), FRAC_CONST(0.1409012377) }, { FRAC_CONST(0.2027872950), FRAC_CONST(0.9792228341) }, { FRAC_CONST(-0.8526401520), FRAC_CONST(0.5224985480) }, { FRAC_CONST(-0.7804304361), FRAC_CONST(-0.6252426505) }, { FRAC_CONST(0.3239174187), FRAC_CONST(-0.9460853338) }, { FRAC_CONST(0.9998766184), FRAC_CONST(-0.0157073177) }, { FRAC_CONST(0.3534748554), FRAC_CONST(0.9354440570) }, { FRAC_CONST(-0.7604059577), FRAC_CONST(0.6494480371) }, { FRAC_CONST(-0.8686315417), FRAC_CONST(-0.4954586625) }, { FRAC_CONST(0.1719291061), FRAC_CONST(-0.9851093292) }, { FRAC_CONST(0.9851093292), FRAC_CONST(-0.1719291061) }, { FRAC_CONST(0.4954586625), FRAC_CONST(0.8686315417) }, { FRAC_CONST(-0.6494480371), FRAC_CONST(0.7604059577) }, { FRAC_CONST(-0.9354440570), FRAC_CONST(-0.3534748554) }, { FRAC_CONST(0.0157073177), FRAC_CONST(-0.9998766184) }, { FRAC_CONST(0.9460853338), FRAC_CONST(-0.3239174187) }, { FRAC_CONST(0.6252426505), FRAC_CONST(0.7804304361) }, { FRAC_CONST(-0.5224985480), FRAC_CONST(0.8526401520) }, { FRAC_CONST(-0.9792228341), FRAC_CONST(-0.2027872950) }, { FRAC_CONST(-0.1409012377), FRAC_CONST(-0.9900236726) }, { FRAC_CONST(0.8837656379), FRAC_CONST(-0.4679298103) }, { FRAC_CONST(0.7396311164), FRAC_CONST(0.6730124950) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(-0.9988898635), FRAC_CONST(-0.0471064523) }, { FRAC_CONST(-0.2940403223), FRAC_CONST(-0.9557930231) }, { FRAC_CONST(0.7996846437), FRAC_CONST(-0.6004202366) }, { FRAC_CONST(0.8358073831), FRAC_CONST(0.5490227938) }, { FRAC_CONST(-0.2334453613), FRAC_CONST(0.9723699093) }, { FRAC_CONST(-0.9939609766), FRAC_CONST(0.1097343117) }, { FRAC_CONST(-0.4399391711), FRAC_CONST(-0.8980275989) }, { FRAC_CONST(0.6959127784), FRAC_CONST(-0.7181262970) }, { FRAC_CONST(0.9114032984), FRAC_CONST(0.4115143716) }, { FRAC_CONST(-0.0784590989), FRAC_CONST(0.9969173074) }, { FRAC_CONST(-0.9645574093), FRAC_CONST(0.2638730407) }, { FRAC_CONST(-0.5750052333), FRAC_CONST(-0.8181497455) }, { FRAC_CONST(0.5750052333), FRAC_CONST(-0.8181497455) }, { FRAC_CONST(0.9645574093), FRAC_CONST(0.2638730407) }, { FRAC_CONST(0.0784590989), FRAC_CONST(0.9969173074) }, { FRAC_CONST(-0.9114032984), FRAC_CONST(0.4115143716) }, { FRAC_CONST(-0.6959127784), FRAC_CONST(-0.7181262970) }, { FRAC_CONST(0.4399391711), FRAC_CONST(-0.8980275989) }, { FRAC_CONST(0.9939609766), FRAC_CONST(0.1097343117) }, { FRAC_CONST(0.2334453613), FRAC_CONST(0.9723699093) }, { FRAC_CONST(-0.8358073831), FRAC_CONST(0.5490227938) }, { FRAC_CONST(-0.7996846437), FRAC_CONST(-0.6004202366) }, { FRAC_CONST(0.2940403223), FRAC_CONST(-0.9557930231) }, { FRAC_CONST(0.9988898635), FRAC_CONST(-0.0471064523) }, { FRAC_CONST(0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(-0.7396311164), FRAC_CONST(0.6730124950) } }; /* RE(Phi_Fract_SubQmf20[j]) = (float)cos(M_PI*f_center_20[j]*0.39); */ /* IM(Phi_Fract_SubQmf20[j]) = (float)sin(M_PI*f_center_20[j]*0.39); */ static const complex_t Phi_Fract_SubQmf20[] = { { FRAC_CONST(0.9882950187), FRAC_CONST(0.1525546312) }, { FRAC_CONST(0.8962930441), FRAC_CONST(0.4434623122) }, { FRAC_CONST(0.7208535671), FRAC_CONST(0.6930873394) }, { FRAC_CONST(0.4783087075), FRAC_CONST(0.8781917691) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(0.8962930441), FRAC_CONST(-0.4434623122) }, { FRAC_CONST(0.9882950187), FRAC_CONST(-0.1525546312) }, { FRAC_CONST(-0.5424415469), FRAC_CONST(0.8400935531) }, { FRAC_CONST(0.0392598175), FRAC_CONST(0.9992290139) }, { FRAC_CONST(-0.9268565774), FRAC_CONST(0.3754155636) }, { FRAC_CONST(-0.9741733670), FRAC_CONST(-0.2258012742) } }; /* RE(Phi_Fract_SubQmf34[j]) = (float)cos(M_PI*f_center_34[j]*0.39); */ /* IM(Phi_Fract_SubQmf34[j]) = (float)sin(M_PI*f_center_34[j]*0.39); */ static const complex_t Phi_Fract_SubQmf34[] = { { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(0.3387379348), FRAC_CONST(0.9408807755) }, { FRAC_CONST(0.3387379348), FRAC_CONST(0.9408807755) }, { FRAC_CONST(0.3387379348), FRAC_CONST(0.9408807755) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(-0.7705132365), FRAC_CONST(0.6374239922) }, { FRAC_CONST(-0.7705132365), FRAC_CONST(0.6374239922) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(0.3387379348), FRAC_CONST(0.9408807755) }, { FRAC_CONST(0.3387379348), FRAC_CONST(0.9408807755) }, { FRAC_CONST(0.3387379348), FRAC_CONST(0.9408807755) }, { FRAC_CONST(0.3387379348), FRAC_CONST(0.9408807755) }, { FRAC_CONST(-0.7705132365), FRAC_CONST(0.6374239922) }, { FRAC_CONST(-0.7705132365), FRAC_CONST(0.6374239922) }, { FRAC_CONST(-0.8607420325), FRAC_CONST(-0.5090414286) }, { FRAC_CONST(0.3387379348), FRAC_CONST(0.9408807755) }, { FRAC_CONST(0.1873813123), FRAC_CONST(-0.9822872281) }, { FRAC_CONST(-0.7705132365), FRAC_CONST(0.6374239922) }, { FRAC_CONST(-0.8607420325), FRAC_CONST(-0.5090414286) }, { FRAC_CONST(-0.8607420325), FRAC_CONST(-0.5090414286) }, { FRAC_CONST(0.1873813123), FRAC_CONST(-0.9822872281) }, { FRAC_CONST(0.1873813123), FRAC_CONST(-0.9822872281) }, { FRAC_CONST(0.9876883626), FRAC_CONST(-0.1564344615) }, { FRAC_CONST(-0.8607420325), FRAC_CONST(-0.5090414286) } }; /* RE(Q_Fract_allpass_Qmf[j][i]) = (float)cos(M_PI*(j+0.5)*(frac_delay_q[i])); */ /* IM(Q_Fract_allpass_Qmf[j][i]) = (float)sin(M_PI*(j+0.5)*(frac_delay_q[i])); */ static const complex_t Q_Fract_allpass_Qmf[][3] = { { { FRAC_CONST(0.7804303765), FRAC_CONST(0.6252426505) }, { FRAC_CONST(0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(0.8550928831), FRAC_CONST(0.5184748173) } }, { { FRAC_CONST(-0.4399392009), FRAC_CONST(0.8980275393) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(-0.0643581524), FRAC_CONST(0.9979268909) } }, { { FRAC_CONST(-0.9723699093), FRAC_CONST(-0.2334454209) }, { FRAC_CONST(0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(-0.9146071672), FRAC_CONST(0.4043435752) } }, { { FRAC_CONST(0.0157073960), FRAC_CONST(-0.9998766184) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(-0.7814115286), FRAC_CONST(-0.6240159869) } }, { { FRAC_CONST(0.9792228341), FRAC_CONST(-0.2027871907) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(0.1920081824), FRAC_CONST(-0.9813933372) } }, { { FRAC_CONST(0.4115142524), FRAC_CONST(0.9114032984) }, { FRAC_CONST(0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(0.9589683414), FRAC_CONST(-0.2835132182) } }, { { FRAC_CONST(-0.7996847630), FRAC_CONST(0.6004201174) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(0.6947838664), FRAC_CONST(0.7192186117) } }, { { FRAC_CONST(-0.7604058385), FRAC_CONST(-0.6494481564) }, { FRAC_CONST(0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(-0.3164770305), FRAC_CONST(0.9486001730) } }, { { FRAC_CONST(0.4679299891), FRAC_CONST(-0.8837655187) }, { FRAC_CONST(0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(-0.9874414206), FRAC_CONST(0.1579856575) } }, { { FRAC_CONST(0.9645573497), FRAC_CONST(0.2638732493) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(-0.5966450572), FRAC_CONST(-0.8025052547) } }, { { FRAC_CONST(-0.0471066870), FRAC_CONST(0.9988898635) }, { FRAC_CONST(0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(0.4357025325), FRAC_CONST(-0.9000906944) } }, { { FRAC_CONST(-0.9851093888), FRAC_CONST(0.1719288528) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(0.9995546937), FRAC_CONST(-0.0298405960) } }, { { FRAC_CONST(-0.3826831877), FRAC_CONST(-0.9238796234) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(0.4886211455), FRAC_CONST(0.8724960685) } }, { { FRAC_CONST(0.8181498647), FRAC_CONST(-0.5750049949) }, { FRAC_CONST(0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(-0.5477093458), FRAC_CONST(0.8366686702) } }, { { FRAC_CONST(0.7396308780), FRAC_CONST(0.6730127335) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(-0.9951074123), FRAC_CONST(-0.0987988561) } }, { { FRAC_CONST(-0.4954589605), FRAC_CONST(0.8686313629) }, { FRAC_CONST(0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(-0.3725017905), FRAC_CONST(-0.9280315042) } }, { { FRAC_CONST(-0.9557929039), FRAC_CONST(-0.2940406799) }, { FRAC_CONST(0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(0.6506417990), FRAC_CONST(-0.7593847513) } }, { { FRAC_CONST(0.0784594864), FRAC_CONST(-0.9969173074) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(0.9741733670), FRAC_CONST(0.2258014232) } }, { { FRAC_CONST(0.9900237322), FRAC_CONST(-0.1409008205) }, { FRAC_CONST(0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(0.2502108514), FRAC_CONST(0.9681913853) } }, { { FRAC_CONST(0.3534744382), FRAC_CONST(0.9354441762) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(-0.7427945137), FRAC_CONST(0.6695194840) } }, { { FRAC_CONST(-0.8358076215), FRAC_CONST(0.5490224361) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(-0.9370992780), FRAC_CONST(-0.3490629196) } }, { { FRAC_CONST(-0.7181259394), FRAC_CONST(-0.6959131360) }, { FRAC_CONST(0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(-0.1237744763), FRAC_CONST(-0.9923103452) } }, { { FRAC_CONST(0.5224990249), FRAC_CONST(-0.8526399136) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(0.8226406574), FRAC_CONST(-0.5685616732) } }, { { FRAC_CONST(0.9460852146), FRAC_CONST(0.3239179254) }, { FRAC_CONST(0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(0.8844994903), FRAC_CONST(0.4665412009) } }, { { FRAC_CONST(-0.1097348556), FRAC_CONST(0.9939609170) }, { FRAC_CONST(0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(-0.0047125919), FRAC_CONST(0.9999889135) } }, { { FRAC_CONST(-0.9939610362), FRAC_CONST(0.1097337380) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(-0.8888573647), FRAC_CONST(0.4581840038) } }, { { FRAC_CONST(-0.3239168525), FRAC_CONST(-0.9460855722) }, { FRAC_CONST(0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(-0.8172453642), FRAC_CONST(-0.5762898922) } }, { { FRAC_CONST(0.8526405096), FRAC_CONST(-0.5224980116) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(0.1331215799), FRAC_CONST(-0.9910997152) } }, { { FRAC_CONST(0.6959123611), FRAC_CONST(0.7181267142) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(0.9403476119), FRAC_CONST(-0.3402152061) } }, { { FRAC_CONST(-0.5490233898), FRAC_CONST(0.8358070254) }, { FRAC_CONST(0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(0.7364512086), FRAC_CONST(0.6764906645) } }, { { FRAC_CONST(-0.9354437590), FRAC_CONST(-0.3534754813) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(-0.2593250275), FRAC_CONST(0.9657900929) } }, { { FRAC_CONST(0.1409019381), FRAC_CONST(-0.9900235534) }, { FRAC_CONST(0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(-0.9762582779), FRAC_CONST(0.2166097313) } }, { { FRAC_CONST(0.9969173670), FRAC_CONST(-0.0784583688) }, { FRAC_CONST(0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(-0.6434556246), FRAC_CONST(-0.7654833794) } }, { { FRAC_CONST(0.2940396070), FRAC_CONST(0.9557932615) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(0.3812320232), FRAC_CONST(-0.9244794250) } }, { { FRAC_CONST(-0.8686318994), FRAC_CONST(0.4954580069) }, { FRAC_CONST(0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(0.9959943891), FRAC_CONST(-0.0894154981) } }, { { FRAC_CONST(-0.6730118990), FRAC_CONST(-0.7396316528) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(0.5397993922), FRAC_CONST(0.8417937160) } }, { { FRAC_CONST(0.5750059485), FRAC_CONST(-0.8181492686) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(-0.4968227744), FRAC_CONST(0.8678520322) } }, { { FRAC_CONST(0.9238792062), FRAC_CONST(0.3826842010) }, { FRAC_CONST(0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(-0.9992290139), FRAC_CONST(-0.0392601527) } }, { { FRAC_CONST(-0.1719299555), FRAC_CONST(0.9851091504) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(-0.4271997511), FRAC_CONST(-0.9041572809) } }, { { FRAC_CONST(-0.9988899231), FRAC_CONST(0.0471055657) }, { FRAC_CONST(0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(0.6041822433), FRAC_CONST(-0.7968461514) } }, { { FRAC_CONST(-0.2638721764), FRAC_CONST(-0.9645576477) }, { FRAC_CONST(0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(0.9859085083), FRAC_CONST(0.1672853529) } }, { { FRAC_CONST(0.8837660551), FRAC_CONST(-0.4679289758) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(0.3075223565), FRAC_CONST(0.9515408874) } }, { { FRAC_CONST(0.6494473219), FRAC_CONST(0.7604066133) }, { FRAC_CONST(0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(-0.7015317082), FRAC_CONST(0.7126382589) } }, { { FRAC_CONST(-0.6004210114), FRAC_CONST(0.7996840477) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(-0.9562535882), FRAC_CONST(-0.2925389707) } }, { { FRAC_CONST(-0.9114028811), FRAC_CONST(-0.4115152657) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(-0.1827499419), FRAC_CONST(-0.9831594229) } }, { { FRAC_CONST(0.2027882934), FRAC_CONST(-0.9792225957) }, { FRAC_CONST(0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(0.7872582674), FRAC_CONST(-0.6166234016) } }, { { FRAC_CONST(0.9998766780), FRAC_CONST(-0.0157062728) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(0.9107555747), FRAC_CONST(0.4129458666) } }, { { FRAC_CONST(0.2334443331), FRAC_CONST(0.9723701477) }, { FRAC_CONST(0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(0.0549497530), FRAC_CONST(0.9984891415) } }, { { FRAC_CONST(-0.8980280757), FRAC_CONST(0.4399381876) }, { FRAC_CONST(0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(-0.8599416018), FRAC_CONST(0.5103924870) } }, { { FRAC_CONST(-0.6252418160), FRAC_CONST(-0.7804310918) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(-0.8501682281), FRAC_CONST(-0.5265110731) } }, { { FRAC_CONST(0.6252435446), FRAC_CONST(-0.7804297209) }, { FRAC_CONST(0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(0.0737608299), FRAC_CONST(-0.9972759485) } }, { { FRAC_CONST(0.8980270624), FRAC_CONST(0.4399402142) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(0.9183775187), FRAC_CONST(-0.3957053721) } }, { { FRAC_CONST(-0.2334465086), FRAC_CONST(0.9723696709) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(0.7754954696), FRAC_CONST(0.6313531399) } }, { { FRAC_CONST(-0.9998766184), FRAC_CONST(-0.0157085191) }, { FRAC_CONST(0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(-0.2012493610), FRAC_CONST(0.9795400500) } }, { { FRAC_CONST(-0.2027861029), FRAC_CONST(-0.9792230725) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(-0.9615978599), FRAC_CONST(0.2744622827) } }, { { FRAC_CONST(0.9114037752), FRAC_CONST(-0.4115132093) }, { FRAC_CONST(0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(-0.6879743338), FRAC_CONST(-0.7257350087) } }, { { FRAC_CONST(0.6004192233), FRAC_CONST(0.7996854186) }, { FRAC_CONST(0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(0.3254036009), FRAC_CONST(-0.9455752373) } }, { { FRAC_CONST(-0.6494490504), FRAC_CONST(0.7604051232) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(0.9888865948), FRAC_CONST(-0.1486719251) } }, { { FRAC_CONST(-0.8837650418), FRAC_CONST(-0.4679309726) }, { FRAC_CONST(0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(0.5890548825), FRAC_CONST(0.8080930114) } }, { { FRAC_CONST(0.2638743520), FRAC_CONST(-0.9645570517) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(-0.4441666007), FRAC_CONST(0.8959442377) } }, { { FRAC_CONST(0.9988898039), FRAC_CONST(0.0471078083) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(-0.9997915030), FRAC_CONST(0.0204183888) } }, { { FRAC_CONST(0.1719277352), FRAC_CONST(0.9851095676) }, { FRAC_CONST(0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(-0.4803760946), FRAC_CONST(-0.8770626187) } }, { { FRAC_CONST(-0.9238800406), FRAC_CONST(0.3826821446) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(0.5555707216), FRAC_CONST(-0.8314692974) } }, { { FRAC_CONST(-0.5750041008), FRAC_CONST(-0.8181505203) }, { FRAC_CONST(0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(0.9941320419), FRAC_CONST(0.1081734300) } } }; /* RE(Q_Fract_allpass_SubQmf20[j][i]) = (float)cos(M_PI*f_center_20[j]*frac_delay_q[i]); */ /* IM(Q_Fract_allpass_SubQmf20[j][i]) = (float)sin(M_PI*f_center_20[j]*frac_delay_q[i]); */ static const complex_t Q_Fract_allpass_SubQmf20[][3] = { { { FRAC_CONST(0.9857769012), FRAC_CONST(0.1680592746) }, { FRAC_CONST(0.9569403529), FRAC_CONST(0.2902846634) }, { FRAC_CONST(0.9907300472), FRAC_CONST(0.1358452588) } }, { { FRAC_CONST(0.8744080663), FRAC_CONST(0.4851911962) }, { FRAC_CONST(0.6343932748), FRAC_CONST(0.7730104327) }, { FRAC_CONST(0.9175986052), FRAC_CONST(0.3975082636) } }, { { FRAC_CONST(0.6642524004), FRAC_CONST(0.7475083470) }, { FRAC_CONST(0.0980171412), FRAC_CONST(0.9951847196) }, { FRAC_CONST(0.7767338753), FRAC_CONST(0.6298289299) } }, { { FRAC_CONST(0.3790524006), FRAC_CONST(0.9253752232) }, { FRAC_CONST(-0.4713967443), FRAC_CONST(0.8819212914) }, { FRAC_CONST(0.5785340071), FRAC_CONST(0.8156582713) } }, { { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) } }, { { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) } }, { { FRAC_CONST(0.8744080663), FRAC_CONST(-0.4851911962) }, { FRAC_CONST(0.6343932748), FRAC_CONST(-0.7730104327) }, { FRAC_CONST(0.9175986052), FRAC_CONST(-0.3975082636) } }, { { FRAC_CONST(0.9857769012), FRAC_CONST(-0.1680592746) }, { FRAC_CONST(0.9569403529), FRAC_CONST(-0.2902846634) }, { FRAC_CONST(0.9907300472), FRAC_CONST(-0.1358452588) } }, { { FRAC_CONST(-0.7126385570), FRAC_CONST(0.7015314102) }, { FRAC_CONST(-0.5555702448), FRAC_CONST(-0.8314695954) }, { FRAC_CONST(-0.3305967748), FRAC_CONST(0.9437720776) } }, { { FRAC_CONST(-0.1175374240), FRAC_CONST(0.9930684566) }, { FRAC_CONST(-0.9807852507), FRAC_CONST(0.1950903237) }, { FRAC_CONST(0.2066311091), FRAC_CONST(0.9784189463) } }, { { FRAC_CONST(-0.9947921634), FRAC_CONST(0.1019244045) }, { FRAC_CONST(0.5555702448), FRAC_CONST(-0.8314695954) }, { FRAC_CONST(-0.7720130086), FRAC_CONST(0.6356067061) } }, { { FRAC_CONST(-0.8400934935), FRAC_CONST(-0.5424416065) }, { FRAC_CONST(0.9807852507), FRAC_CONST(0.1950903237) }, { FRAC_CONST(-0.9896889329), FRAC_CONST(0.1432335079) } } }; /* RE(Q_Fract_allpass_SubQmf34[j][i]) = (float)cos(M_PI*f_center_34[j]*frac_delay_q[i]); */ /* IM(Q_Fract_allpass_SubQmf34[j][i]) = (float)sin(M_PI*f_center_34[j]*frac_delay_q[i]); */ static const complex_t Q_Fract_allpass_SubQmf34[][3] = { { { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) } }, { { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) } }, { { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) } }, { { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) } }, { { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) } }, { { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) } }, { { FRAC_CONST(0.2181432247), FRAC_CONST(0.9759167433) }, { FRAC_CONST(-0.7071067691), FRAC_CONST(0.7071067691) }, { FRAC_CONST(0.4623677433), FRAC_CONST(0.8866882324) } }, { { FRAC_CONST(0.2181432247), FRAC_CONST(0.9759167433) }, { FRAC_CONST(-0.7071067691), FRAC_CONST(0.7071067691) }, { FRAC_CONST(0.4623677433), FRAC_CONST(0.8866882324) } }, { { FRAC_CONST(0.2181432247), FRAC_CONST(0.9759167433) }, { FRAC_CONST(-0.7071067691), FRAC_CONST(0.7071067691) }, { FRAC_CONST(0.4623677433), FRAC_CONST(0.8866882324) } }, { { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) } }, { { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) } }, { { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) } }, { { FRAC_CONST(-0.9048270583), FRAC_CONST(0.4257792532) }, { FRAC_CONST(-0.0000000000), FRAC_CONST(-1.0000000000) }, { FRAC_CONST(-0.5724321604), FRAC_CONST(0.8199520707) } }, { { FRAC_CONST(-0.9048270583), FRAC_CONST(0.4257792532) }, { FRAC_CONST(-0.0000000000), FRAC_CONST(-1.0000000000) }, { FRAC_CONST(-0.5724321604), FRAC_CONST(0.8199520707) } }, { { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) } }, { { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) } }, { { FRAC_CONST(0.2181432247), FRAC_CONST(0.9759167433) }, { FRAC_CONST(-0.7071067691), FRAC_CONST(0.7071067691) }, { FRAC_CONST(0.4623677433), FRAC_CONST(0.8866882324) } }, { { FRAC_CONST(0.2181432247), FRAC_CONST(0.9759167433) }, { FRAC_CONST(-0.7071067691), FRAC_CONST(0.7071067691) }, { FRAC_CONST(0.4623677433), FRAC_CONST(0.8866882324) } }, { { FRAC_CONST(0.2181432247), FRAC_CONST(0.9759167433) }, { FRAC_CONST(-0.7071067691), FRAC_CONST(0.7071067691) }, { FRAC_CONST(0.4623677433), FRAC_CONST(0.8866882324) } }, { { FRAC_CONST(0.2181432247), FRAC_CONST(0.9759167433) }, { FRAC_CONST(-0.7071067691), FRAC_CONST(0.7071067691) }, { FRAC_CONST(0.4623677433), FRAC_CONST(0.8866882324) } }, { { FRAC_CONST(-0.9048270583), FRAC_CONST(0.4257792532) }, { FRAC_CONST(-0.0000000000), FRAC_CONST(-1.0000000000) }, { FRAC_CONST(-0.5724321604), FRAC_CONST(0.8199520707) } }, { { FRAC_CONST(-0.9048270583), FRAC_CONST(0.4257792532) }, { FRAC_CONST(-0.0000000000), FRAC_CONST(-1.0000000000) }, { FRAC_CONST(-0.5724321604), FRAC_CONST(0.8199520707) } }, { { FRAC_CONST(-0.6129069924), FRAC_CONST(-0.7901550531) }, { FRAC_CONST(0.7071067691), FRAC_CONST(0.7071067691) }, { FRAC_CONST(-0.9917160273), FRAC_CONST(-0.1284494549) } }, { { FRAC_CONST(0.2181432247), FRAC_CONST(0.9759167433) }, { FRAC_CONST(-0.7071067691), FRAC_CONST(0.7071067691) }, { FRAC_CONST(0.4623677433), FRAC_CONST(0.8866882324) } }, { { FRAC_CONST(0.6374240518), FRAC_CONST(-0.7705131769) }, { FRAC_CONST(-1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(-0.3446428776), FRAC_CONST(-0.9387338758) } }, { { FRAC_CONST(-0.9048270583), FRAC_CONST(0.4257792532) }, { FRAC_CONST(-0.0000000000), FRAC_CONST(-1.0000000000) }, { FRAC_CONST(-0.5724321604), FRAC_CONST(0.8199520707) } }, { { FRAC_CONST(-0.6129069924), FRAC_CONST(-0.7901550531) }, { FRAC_CONST(0.7071067691), FRAC_CONST(0.7071067691) }, { FRAC_CONST(-0.9917160273), FRAC_CONST(-0.1284494549) } }, { { FRAC_CONST(-0.6129069924), FRAC_CONST(-0.7901550531) }, { FRAC_CONST(0.7071067691), FRAC_CONST(0.7071067691) }, { FRAC_CONST(-0.9917160273), FRAC_CONST(-0.1284494549) } }, { { FRAC_CONST(0.6374240518), FRAC_CONST(-0.7705131769) }, { FRAC_CONST(-1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(-0.3446428776), FRAC_CONST(-0.9387338758) } }, { { FRAC_CONST(0.6374240518), FRAC_CONST(-0.7705131769) }, { FRAC_CONST(-1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(-0.3446428776), FRAC_CONST(-0.9387338758) } }, { { FRAC_CONST(0.8910064697), FRAC_CONST(0.4539906085) }, { FRAC_CONST(0.7071067691), FRAC_CONST(-0.7071067691) }, { FRAC_CONST(0.6730125546), FRAC_CONST(-0.7396310568) } }, { { FRAC_CONST(-0.6129069924), FRAC_CONST(-0.7901550531) }, { FRAC_CONST(0.7071067691), FRAC_CONST(0.7071067691) }, { FRAC_CONST(-0.9917160273), FRAC_CONST(-0.1284494549) } } }; static float quant_rho[8] = { FRAC_CONST(1.0), FRAC_CONST(0.937), FRAC_CONST(0.84118), FRAC_CONST(0.60092), FRAC_CONST(0.36764), FRAC_CONST(0.0), FRAC_CONST(-0.589), FRAC_CONST(-1.0) }; static const uint8_t quant_iid_normal[7] = { 2, 4, 7, 10, 14, 18, 25 }; static const uint8_t quant_iid_fine[15] = { 2, 4, 6, 8, 10, 13, 16, 19, 22, 25, 30, 35, 40, 45, 50 }; static const real_t cos_alphas[] = { COEF_CONST(1.0000000000), COEF_CONST(0.9841239700), COEF_CONST(0.9594738210), COEF_CONST(0.8946843079), COEF_CONST(0.8269340931), COEF_CONST(0.7071067812), COEF_CONST(0.4533210856), COEF_CONST(0.0000000000) }; static const real_t sin_alphas[] = { COEF_CONST(0.0000000000), COEF_CONST(0.1774824264), COEF_CONST(0.2817977763), COEF_CONST(0.4466989918), COEF_CONST(0.5622988580), COEF_CONST(0.7071067812), COEF_CONST(0.8913472911), COEF_CONST(1.0000000000) }; static const real_t cos_betas_normal[][8] = { { COEF_CONST(1.0000000000), COEF_CONST(1.0000000000), COEF_CONST(1.0000000000), COEF_CONST(1.0000000000), COEF_CONST(1.0000000000), COEF_CONST(1.0000000000), COEF_CONST(1.0000000000), COEF_CONST(1.0000000000) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9995871699), COEF_CONST(0.9989419133), COEF_CONST(0.9972204583), COEF_CONST(0.9953790839), COEF_CONST(0.9920112747), COEF_CONST(0.9843408180), COEF_CONST(0.9681727381) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9984497744), COEF_CONST(0.9960279377), COEF_CONST(0.9895738413), COEF_CONST(0.9826814632), COEF_CONST(0.9701058164), COEF_CONST(0.9416098832), COEF_CONST(0.8822105900) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9959398908), COEF_CONST(0.9896038018), COEF_CONST(0.9727589768), COEF_CONST(0.9548355329), COEF_CONST(0.9223070404), COEF_CONST(0.8494349490), COEF_CONST(0.7013005535) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9932417400), COEF_CONST(0.9827071856), COEF_CONST(0.9547730996), COEF_CONST(0.9251668930), COEF_CONST(0.8717461589), COEF_CONST(0.7535520592), COEF_CONST(0.5198827312) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9902068095), COEF_CONST(0.9749613872), COEF_CONST(0.9346538534), COEF_CONST(0.8921231300), COEF_CONST(0.8158851259), COEF_CONST(0.6495964302), COEF_CONST(0.3313370772) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9880510933), COEF_CONST(0.9694670261), COEF_CONST(0.9204347876), COEF_CONST(0.8688622825), COEF_CONST(0.7768516704), COEF_CONST(0.5782161800), COEF_CONST(0.2069970356) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9858996945), COEF_CONST(0.9639898866), COEF_CONST(0.9063034786), COEF_CONST(0.8458214608), COEF_CONST(0.7384262300), COEF_CONST(0.5089811277), COEF_CONST(0.0905465944) } }; static const real_t sin_betas_normal[][8] = { { COEF_CONST(0.0000000000), COEF_CONST(0.0000000000), COEF_CONST(0.0000000000), COEF_CONST(0.0000000000), COEF_CONST(0.0000000000), COEF_CONST(0.0000000000), COEF_CONST(0.0000000000), COEF_CONST(0.0000000000) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.0287313368), COEF_CONST(-0.0459897147), COEF_CONST(-0.0745074328), COEF_CONST(-0.0960233266), COEF_CONST(-0.1261492408), COEF_CONST(-0.1762757894), COEF_CONST(-0.2502829383) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.0556601118), COEF_CONST(-0.0890412670), COEF_CONST(-0.1440264301), COEF_CONST(-0.1853028382), COEF_CONST(-0.2426823129), COEF_CONST(-0.3367058477), COEF_CONST(-0.4708550466) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.0900207420), COEF_CONST(-0.1438204281), COEF_CONST(-0.2318188366), COEF_CONST(-0.2971348264), COEF_CONST(-0.3864579191), COEF_CONST(-0.5276933461), COEF_CONST(-0.7128657193) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.1160639735), COEF_CONST(-0.1851663774), COEF_CONST(-0.2973353800), COEF_CONST(-0.3795605619), COEF_CONST(-0.4899577884), COEF_CONST(-0.6573882369), COEF_CONST(-0.8542376401) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.1396082894), COEF_CONST(-0.2223742196), COEF_CONST(-0.3555589603), COEF_CONST(-0.4517923427), COEF_CONST(-0.5782140273), COEF_CONST(-0.7602792104), COEF_CONST(-0.9435124489) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.1541266914), COEF_CONST(-0.2452217065), COEF_CONST(-0.3908961522), COEF_CONST(-0.4950538699), COEF_CONST(-0.6296836366), COEF_CONST(-0.8158836002), COEF_CONST(-0.9783415698) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.1673373610), COEF_CONST(-0.2659389001), COEF_CONST(-0.4226275012), COEF_CONST(-0.5334660781), COEF_CONST(-0.6743342664), COEF_CONST(-0.8607776784), COEF_CONST(-0.9958922202) } }; static const real_t cos_betas_fine[][8] = { { COEF_CONST(1.0000000000), COEF_CONST(1.0000000000), COEF_CONST(1.0000000000), COEF_CONST(1.0000000000), COEF_CONST(1.0000000000), COEF_CONST(1.0000000000), COEF_CONST(1.0000000000), COEF_CONST(1.0000000000) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9995871699), COEF_CONST(0.9989419133), COEF_CONST(0.9972204583), COEF_CONST(0.9953790839), COEF_CONST(0.9920112747), COEF_CONST(0.9843408180), COEF_CONST(0.9681727381) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9984497744), COEF_CONST(0.9960279377), COEF_CONST(0.9895738413), COEF_CONST(0.9826814632), COEF_CONST(0.9701058164), COEF_CONST(0.9416098832), COEF_CONST(0.8822105900) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9968361371), COEF_CONST(0.9918968104), COEF_CONST(0.9787540479), COEF_CONST(0.9647515190), COEF_CONST(0.9392903010), COEF_CONST(0.8820167114), COEF_CONST(0.7645325390) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9950262915), COEF_CONST(0.9872675041), COEF_CONST(0.9666584578), COEF_CONST(0.9447588606), COEF_CONST(0.9050918405), COEF_CONST(0.8165997379), COEF_CONST(0.6383824796) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9932417400), COEF_CONST(0.9827071856), COEF_CONST(0.9547730996), COEF_CONST(0.9251668930), COEF_CONST(0.8717461589), COEF_CONST(0.7535520592), COEF_CONST(0.5198827312) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9908827998), COEF_CONST(0.9766855904), COEF_CONST(0.9391249214), COEF_CONST(0.8994531782), COEF_CONST(0.8282352693), COEF_CONST(0.6723983174), COEF_CONST(0.3719473225) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9890240165), COEF_CONST(0.9719459866), COEF_CONST(0.9268448110), COEF_CONST(0.8793388536), COEF_CONST(0.7944023271), COEF_CONST(0.6101812098), COEF_CONST(0.2621501145) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9876350461), COEF_CONST(0.9684073447), COEF_CONST(0.9176973944), COEF_CONST(0.8643930070), COEF_CONST(0.7693796058), COEF_CONST(0.5646720713), COEF_CONST(0.1838899556) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9866247085), COEF_CONST(0.9658349704), COEF_CONST(0.9110590761), COEF_CONST(0.8535668048), COEF_CONST(0.7513165426), COEF_CONST(0.5320914819), COEF_CONST(0.1289530943) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9858996945), COEF_CONST(0.9639898866), COEF_CONST(0.9063034786), COEF_CONST(0.8458214608), COEF_CONST(0.7384262300), COEF_CONST(0.5089811277), COEF_CONST(0.0905465944) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9851245614), COEF_CONST(0.9620180268), COEF_CONST(0.9012265590), COEF_CONST(0.8375623272), COEF_CONST(0.7247108045), COEF_CONST(0.4845204297), COEF_CONST(0.0504115003) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9846869856), COEF_CONST(0.9609052357), COEF_CONST(0.8983639533), COEF_CONST(0.8329098386), COEF_CONST(0.7169983441), COEF_CONST(0.4708245354), COEF_CONST(0.0281732509) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9844406325), COEF_CONST(0.9602788522), COEF_CONST(0.8967533934), COEF_CONST(0.8302936455), COEF_CONST(0.7126658102), COEF_CONST(0.4631492839), COEF_CONST(0.0157851140) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9843020502), COEF_CONST(0.9599265269), COEF_CONST(0.8958477331), COEF_CONST(0.8288229094), COEF_CONST(0.7102315840), COEF_CONST(0.4588429315), COEF_CONST(0.0088578059) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9842241136), COEF_CONST(0.9597283916), COEF_CONST(0.8953385094), COEF_CONST(0.8279961409), COEF_CONST(0.7088635748), COEF_CONST(0.4564246834), COEF_CONST(0.0049751355) } }; static const real_t sin_betas_fine[][8] = { { COEF_CONST(0.0000000000), COEF_CONST(0.0000000000), COEF_CONST(0.0000000000), COEF_CONST(0.0000000000), COEF_CONST(0.0000000000), COEF_CONST(0.0000000000), COEF_CONST(0.0000000000), COEF_CONST(0.0000000000) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.0287313368), COEF_CONST(-0.0459897147), COEF_CONST(-0.0745074328), COEF_CONST(-0.0960233266), COEF_CONST(-0.1261492408), COEF_CONST(-0.1762757894), COEF_CONST(-0.2502829383) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.0556601118), COEF_CONST(-0.0890412670), COEF_CONST(-0.1440264301), COEF_CONST(-0.1853028382), COEF_CONST(-0.2426823129), COEF_CONST(-0.3367058477), COEF_CONST(-0.4708550466) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.0794840594), COEF_CONST(-0.1270461238), COEF_CONST(-0.2050378347), COEF_CONST(-0.2631625097), COEF_CONST(-0.3431234916), COEF_CONST(-0.4712181245), COEF_CONST(-0.6445851354) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.0996126459), COEF_CONST(-0.1590687758), COEF_CONST(-0.2560691819), COEF_CONST(-0.3277662204), COEF_CONST(-0.4252161335), COEF_CONST(-0.5772043556), COEF_CONST(-0.7697193058) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.1160639735), COEF_CONST(-0.1851663774), COEF_CONST(-0.2973353800), COEF_CONST(-0.3795605619), COEF_CONST(-0.4899577884), COEF_CONST(-0.6573882369), COEF_CONST(-0.8542376401) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.1347266752), COEF_CONST(-0.2146747714), COEF_CONST(-0.3435758752), COEF_CONST(-0.4370171396), COEF_CONST(-0.5603805303), COEF_CONST(-0.7401895046), COEF_CONST(-0.9282538388) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.1477548470), COEF_CONST(-0.2352041647), COEF_CONST(-0.3754446647), COEF_CONST(-0.4761965776), COEF_CONST(-0.6073919186), COEF_CONST(-0.7922618830), COEF_CONST(-0.9650271071) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.1567705832), COEF_CONST(-0.2493736450), COEF_CONST(-0.3972801182), COEF_CONST(-0.5028167951), COEF_CONST(-0.6387918458), COEF_CONST(-0.8253153651), COEF_CONST(-0.9829468369) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.1630082348), COEF_CONST(-0.2591578860), COEF_CONST(-0.4122758299), COEF_CONST(-0.5209834064), COEF_CONST(-0.6599420072), COEF_CONST(-0.8466868694), COEF_CONST(-0.9916506943) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.1673373610), COEF_CONST(-0.2659389001), COEF_CONST(-0.4226275012), COEF_CONST(-0.5334660781), COEF_CONST(-0.6743342664), COEF_CONST(-0.8607776784), COEF_CONST(-0.9958922202) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.1718417832), COEF_CONST(-0.2729859267), COEF_CONST(-0.4333482310), COEF_CONST(-0.5463417868), COEF_CONST(-0.6890531546), COEF_CONST(-0.8747799456), COEF_CONST(-0.9987285320) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.1743316967), COEF_CONST(-0.2768774604), COEF_CONST(-0.4392518725), COEF_CONST(-0.5534087104), COEF_CONST(-0.6970748701), COEF_CONST(-0.8822268738), COEF_CONST(-0.9996030552) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.1757175038), COEF_CONST(-0.2790421580), COEF_CONST(-0.4425306221), COEF_CONST(-0.5573261722), COEF_CONST(-0.7015037013), COEF_CONST(-0.8862802834), COEF_CONST(-0.9998754073) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.1764921355), COEF_CONST(-0.2802517850), COEF_CONST(-0.4443611583), COEF_CONST(-0.5595110229), COEF_CONST(-0.7039681080), COEF_CONST(-0.8885173967), COEF_CONST(-0.9999607689) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.1769262394), COEF_CONST(-0.2809295540), COEF_CONST(-0.4453862969), COEF_CONST(-0.5607337966), COEF_CONST(-0.7053456119), COEF_CONST(-0.8897620516), COEF_CONST(-0.9999876239) } }; static const real_t sf_iid_normal[] = { COEF_CONST(1.4119827747), COEF_CONST(1.4031381607), COEF_CONST(1.3868767023), COEF_CONST(1.3483997583), COEF_CONST(1.2912493944), COEF_CONST(1.1960374117), COEF_CONST(1.1073724031), COEF_CONST(1.0000000000), COEF_CONST(0.8796171546), COEF_CONST(0.7546485662), COEF_CONST(0.5767799020), COEF_CONST(0.4264014363), COEF_CONST(0.2767182887), COEF_CONST(0.1766446233), COEF_CONST(0.0794016272) }; static const real_t sf_iid_fine[] = { COEF_CONST(1.4142065048), COEF_CONST(1.4141912460), COEF_CONST(1.4141428471), COEF_CONST(1.4139900208), COEF_CONST(1.4135069847), COEF_CONST(1.4119827747), COEF_CONST(1.4097729921), COEF_CONST(1.4053947926), COEF_CONST(1.3967796564), COEF_CONST(1.3800530434), COEF_CONST(1.3483997583), COEF_CONST(1.3139201403), COEF_CONST(1.2643101215), COEF_CONST(1.1960374117), COEF_CONST(1.1073724031), COEF_CONST(1.0000000000), COEF_CONST(0.8796171546), COEF_CONST(0.7546485662), COEF_CONST(0.6336560845), COEF_CONST(0.5230810642), COEF_CONST(0.4264014363), COEF_CONST(0.3089554012), COEF_CONST(0.2213746458), COEF_CONST(0.1576878875), COEF_CONST(0.1119822487), COEF_CONST(0.0794016272), COEF_CONST(0.0446990170), COEF_CONST(0.0251446925), COEF_CONST(0.0141414283), COEF_CONST(0.0079525812), COEF_CONST(0.0044721137) }; static const uint8_t group_border20[10+12 + 1] = { 6, 7, 0, 1, 2, 3, /* 6 subqmf subbands */ 9, 8, /* 2 subqmf subbands */ 10, 11, /* 2 subqmf subbands */ 3, 4, 5, 6, 7, 8, 9, 11, 14, 18, 23, 35, 64 }; static const uint8_t group_border34[32+18 + 1] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, /* 12 subqmf subbands */ 12, 13, 14, 15, 16, 17, 18, 19, /* 8 subqmf subbands */ 20, 21, 22, 23, /* 4 subqmf subbands */ 24, 25, 26, 27, /* 4 subqmf subbands */ 28, 29, 30, 31, /* 4 subqmf subbands */ 32-27, 33-27, 34-27, 35-27, 36-27, 37-27, 38-27, 40-27, 42-27, 44-27, 46-27, 48-27, 51-27, 54-27, 57-27, 60-27, 64-27, 68-27, 91-27 }; static const uint16_t map_bins2group20[10+12] = { (NEGATE_IPD_MASK | 1), (NEGATE_IPD_MASK | 0), 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }; static const uint16_t map_bins2group34[32+18] = { 0, 1, 2, 3, 4, 5, 6, 6, 7, (NEGATE_IPD_MASK | 2), (NEGATE_IPD_MASK | 1), (NEGATE_IPD_MASK | 0), 10, 10, 4, 5, 6, 7, 8, 9, 10, 11, 12, 9, 14, 11, 12, 13, 14, 15, 16, 13, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33 }; /* type definitions */ typedef struct { uint8_t frame_len; uint8_t resolution20[3]; uint8_t resolution34[5]; qmf_t *work; qmf_t **buffer; qmf_t **temp; } hyb_info; /* static function declarations */ static void ps_data_decode(ps_info *ps); static hyb_info *hybrid_init(); static void channel_filter2(hyb_info *hyb, uint8_t frame_len, const real_t *filter, qmf_t *buffer, qmf_t **X_hybrid); static void INLINE DCT3_4_unscaled(real_t *y, real_t *x); static void channel_filter8(hyb_info *hyb, uint8_t frame_len, const real_t *filter, qmf_t *buffer, qmf_t **X_hybrid); static void hybrid_analysis(hyb_info *hyb, qmf_t X[32][64], qmf_t X_hybrid[32][32], uint8_t use34); static void hybrid_synthesis(hyb_info *hyb, qmf_t X[32][64], qmf_t X_hybrid[32][32], uint8_t use34); static int8_t delta_clip(int8_t i, int8_t min, int8_t max); static void delta_decode(uint8_t enable, int8_t *index, uint8_t *index_prev, uint8_t dt_flag, uint8_t nr_par, uint8_t stride, int8_t min_index, int8_t max_index); static void map20indexto34(int8_t *index, uint8_t bins); #ifdef PS_LOW_POWER static void map34indexto20(int8_t *index, uint8_t bins); #endif static void ps_data_decode(ps_info *ps); static void ps_decorrelate(ps_info *ps, qmf_t X_left[38][64], qmf_t X_right[38][64], qmf_t X_hybrid_left[32][32], qmf_t X_hybrid_right[32][32]); static void ps_mix_phase(ps_info *ps, qmf_t X_left[38][64], qmf_t X_right[38][64], qmf_t X_hybrid_left[32][32], qmf_t X_hybrid_right[32][32]); /* */ static hyb_info *hybrid_init() { uint8_t i; hyb_info *hyb = (hyb_info*)faad_malloc(sizeof(hyb_info)); hyb->resolution34[0] = 12; hyb->resolution34[1] = 8; hyb->resolution34[2] = 4; hyb->resolution34[3] = 4; hyb->resolution34[4] = 4; hyb->resolution20[0] = 8; hyb->resolution20[1] = 2; hyb->resolution20[2] = 2; hyb->frame_len = 32; hyb->work = (qmf_t*)faad_malloc((hyb->frame_len+12) * sizeof(qmf_t)); memset(hyb->work, 0, (hyb->frame_len+12) * sizeof(qmf_t)); hyb->buffer = (qmf_t**)faad_malloc(5 * sizeof(qmf_t*)); for (i = 0; i < 5; i++) { hyb->buffer[i] = (qmf_t*)faad_malloc(hyb->frame_len * sizeof(qmf_t)); memset(hyb->buffer[i], 0, hyb->frame_len * sizeof(qmf_t)); } hyb->temp = (qmf_t**)faad_malloc(hyb->frame_len * sizeof(qmf_t*)); for (i = 0; i < hyb->frame_len; i++) { hyb->temp[i] = (qmf_t*)faad_malloc(12 /*max*/ * sizeof(qmf_t)); } return hyb; } /* real filter, size 2 */ static void channel_filter2(hyb_info *hyb, uint8_t frame_len, const real_t *filter, qmf_t *buffer, qmf_t **X_hybrid) { uint8_t i; for (i = 0; i < frame_len; i++) { /* q = 0 */ QMF_RE(X_hybrid[i][0]) = MUL_F(filter[0],(QMF_RE(buffer[0+i]) + QMF_RE(buffer[12+i]))) + MUL_F(filter[1],(QMF_RE(buffer[1+i]) + QMF_RE(buffer[11+i]))) + MUL_F(filter[2],(QMF_RE(buffer[2+i]) + QMF_RE(buffer[10+i]))) + MUL_F(filter[3],(QMF_RE(buffer[3+i]) + QMF_RE(buffer[9+i]))) + MUL_F(filter[4],(QMF_RE(buffer[4+i]) + QMF_RE(buffer[8+i]))) + MUL_F(filter[5],(QMF_RE(buffer[5+i]) + QMF_RE(buffer[7+i]))) + MUL_F(filter[6],QMF_RE(buffer[6+i])); QMF_IM(X_hybrid[i][0]) = MUL_F(filter[0],(QMF_IM(buffer[0+i]) + QMF_IM(buffer[12+i]))) + MUL_F(filter[1],(QMF_IM(buffer[1+i]) + QMF_IM(buffer[11+i]))) + MUL_F(filter[2],(QMF_IM(buffer[2+i]) + QMF_IM(buffer[10+i]))) + MUL_F(filter[3],(QMF_IM(buffer[3+i]) + QMF_IM(buffer[9+i]))) + MUL_F(filter[4],(QMF_IM(buffer[4+i]) + QMF_IM(buffer[8+i]))) + MUL_F(filter[5],(QMF_IM(buffer[5+i]) + QMF_IM(buffer[7+i]))) + MUL_F(filter[6],QMF_IM(buffer[6+i])); /* q = 1 */ QMF_RE(X_hybrid[i][1]) = MUL_F(filter[0],(QMF_RE(buffer[0+i]) + QMF_RE(buffer[12+i]))) - MUL_F(filter[1],(QMF_RE(buffer[1+i]) + QMF_RE(buffer[11+i]))) + MUL_F(filter[2],(QMF_RE(buffer[2+i]) + QMF_RE(buffer[10+i]))) - MUL_F(filter[3],(QMF_RE(buffer[3+i]) + QMF_RE(buffer[9+i]))) + MUL_F(filter[4],(QMF_RE(buffer[4+i]) + QMF_RE(buffer[8+i]))) - MUL_F(filter[5],(QMF_RE(buffer[5+i]) + QMF_RE(buffer[7+i]))) + MUL_F(filter[6],QMF_RE(buffer[6+i])); QMF_IM(X_hybrid[i][1]) = MUL_F(filter[0],(QMF_IM(buffer[0+i]) + QMF_IM(buffer[12+i]))) - MUL_F(filter[1],(QMF_IM(buffer[1+i]) + QMF_IM(buffer[11+i]))) + MUL_F(filter[2],(QMF_IM(buffer[2+i]) + QMF_IM(buffer[10+i]))) - MUL_F(filter[3],(QMF_IM(buffer[3+i]) + QMF_IM(buffer[9+i]))) + MUL_F(filter[4],(QMF_IM(buffer[4+i]) + QMF_IM(buffer[8+i]))) - MUL_F(filter[5],(QMF_IM(buffer[5+i]) + QMF_IM(buffer[7+i]))) + MUL_F(filter[6],QMF_IM(buffer[6+i])); } } static void INLINE DCT3_4_unscaled(real_t *y, real_t *x) { real_t f0, f1, f2, f3, f4, f5, f6, f7, f8; f0 = MUL_F(x[2], FRAC_CONST(0.7071067811865476)); f1 = x[0] - f0; f2 = x[0] + f0; f3 = x[1] + x[3]; f4 = MUL_C(x[1], COEF_CONST(1.3065629648763766)); f5 = MUL_F(f3, FRAC_CONST(-0.9238795325112866)); f6 = MUL_F(x[3], FRAC_CONST(-0.5411961001461967)); f7 = f4 + f5; f8 = f6 - f5; y[3] = f2 - f8; y[0] = f2 + f8; y[2] = f1 - f7; y[1] = f1 + f7; } /* complex filter, size 8 */ static void channel_filter8(hyb_info *hyb, uint8_t frame_len, const real_t *filter, qmf_t *buffer, qmf_t **X_hybrid) { uint8_t i, n; real_t input_re1[4], input_re2[4], input_im1[4], input_im2[4]; real_t x[4]; for (i = 0; i < frame_len; i++) { input_re1[0] = MUL_F(filter[6],QMF_RE(buffer[6+i])); input_re1[1] = MUL_F(filter[5],(QMF_RE(buffer[5+i]) + QMF_RE(buffer[7+i]))); input_re1[2] = -MUL_F(filter[0],(QMF_RE(buffer[0+i]) + QMF_RE(buffer[12+i]))) + MUL_F(filter[4],(QMF_RE(buffer[4+i]) + QMF_RE(buffer[8+i]))); input_re1[3] = -MUL_F(filter[1],(QMF_RE(buffer[1+i]) + QMF_RE(buffer[11+i]))) + MUL_F(filter[3],(QMF_RE(buffer[3+i]) + QMF_RE(buffer[9+i]))); input_im1[0] = MUL_F(filter[5],(QMF_IM(buffer[7+i]) - QMF_IM(buffer[5+i]))); input_im1[1] = MUL_F(filter[0],(QMF_IM(buffer[12+i]) - QMF_IM(buffer[0+i]))) + MUL_F(filter[4],(QMF_IM(buffer[8+i]) - QMF_IM(buffer[4+i]))); input_im1[2] = MUL_F(filter[1],(QMF_IM(buffer[11+i]) - QMF_IM(buffer[1+i]))) + MUL_F(filter[3],(QMF_IM(buffer[9+i]) - QMF_IM(buffer[3+i]))); input_im1[3] = MUL_F(filter[2],(QMF_IM(buffer[10+i]) - QMF_IM(buffer[2+i]))); for (n = 0; n < 4; n++) { x[n] = input_re1[n] - input_im1[3-n]; } DCT3_4_unscaled(x, x); QMF_RE(X_hybrid[i][7]) = x[0]; QMF_RE(X_hybrid[i][5]) = x[2]; QMF_RE(X_hybrid[i][3]) = x[3]; QMF_RE(X_hybrid[i][1]) = x[1]; for (n = 0; n < 4; n++) { x[n] = input_re1[n] + input_im1[3-n]; } DCT3_4_unscaled(x, x); QMF_RE(X_hybrid[i][6]) = x[1]; QMF_RE(X_hybrid[i][4]) = x[3]; QMF_RE(X_hybrid[i][2]) = x[2]; QMF_RE(X_hybrid[i][0]) = x[0]; input_im2[0] = MUL_F(filter[6],QMF_IM(buffer[6+i])); input_im2[1] = MUL_F(filter[5],(QMF_IM(buffer[5+i]) + QMF_IM(buffer[7+i]))); input_im2[2] = -MUL_F(filter[0],(QMF_IM(buffer[0+i]) + QMF_IM(buffer[12+i]))) + MUL_F(filter[4],(QMF_IM(buffer[4+i]) + QMF_IM(buffer[8+i]))); input_im2[3] = -MUL_F(filter[1],(QMF_IM(buffer[1+i]) + QMF_IM(buffer[11+i]))) + MUL_F(filter[3],(QMF_IM(buffer[3+i]) + QMF_IM(buffer[9+i]))); input_re2[0] = MUL_F(filter[5],(QMF_RE(buffer[7+i]) - QMF_RE(buffer[5+i]))); input_re2[1] = MUL_F(filter[0],(QMF_RE(buffer[12+i]) - QMF_RE(buffer[0+i]))) + MUL_F(filter[4],(QMF_RE(buffer[8+i]) - QMF_RE(buffer[4+i]))); input_re2[2] = MUL_F(filter[1],(QMF_RE(buffer[11+i]) - QMF_RE(buffer[1+i]))) + MUL_F(filter[3],(QMF_RE(buffer[9+i]) - QMF_RE(buffer[3+i]))); input_re2[3] = MUL_F(filter[2],(QMF_RE(buffer[10+i]) - QMF_RE(buffer[2+i]))); for (n = 0; n < 4; n++) { x[n] = input_im2[n] + input_re2[3-n]; } DCT3_4_unscaled(x, x); QMF_IM(X_hybrid[i][7]) = x[0]; QMF_IM(X_hybrid[i][5]) = x[2]; QMF_IM(X_hybrid[i][3]) = x[3]; QMF_IM(X_hybrid[i][1]) = x[1]; for (n = 0; n < 4; n++) { x[n] = input_im2[n] - input_re2[3-n]; } DCT3_4_unscaled(x, x); QMF_IM(X_hybrid[i][6]) = x[1]; QMF_IM(X_hybrid[i][4]) = x[3]; QMF_IM(X_hybrid[i][2]) = x[2]; QMF_IM(X_hybrid[i][0]) = x[0]; } } /* Hybrid analysis: further split up QMF subbands * to improve frequency resolution */ static void hybrid_analysis(hyb_info *hyb, qmf_t X[32][64], qmf_t X_hybrid[32][32], uint8_t use34) { uint8_t k, n, band; uint8_t offset = 0; uint8_t qmf_bands = (use34) ? 5 : 3; uint8_t *resolution = (use34) ? hyb->resolution34 : hyb->resolution20; for (band = 0; band < qmf_bands; band++) { /* build working buffer */ memcpy(hyb->work, hyb->buffer[band], 12 * sizeof(qmf_t)); /* add new samples */ for (n = 0; n < hyb->frame_len; n++) { QMF_RE(hyb->work[12 + n]) = QMF_RE(X[n + 6 /*delay*/][band]); QMF_IM(hyb->work[12 + n]) = QMF_IM(X[n + 6 /*delay*/][band]); } /* store samples */ memcpy(hyb->buffer[band], hyb->work + hyb->frame_len, 12 * sizeof(qmf_t)); switch(resolution[band]) { case 2: channel_filter2(hyb, hyb->frame_len, p2_13_20, hyb->work, hyb->temp); break; case 4: channel_filter2(hyb, hyb->frame_len, p4_13_34, hyb->work, hyb->temp); break; case 8: channel_filter8(hyb, hyb->frame_len, (use34) ? p8_13_34 : p8_13_20, hyb->work, hyb->temp); break; case 12: channel_filter2(hyb, hyb->frame_len, p12_13_34, hyb->work, hyb->temp); break; } for (n = 0; n < hyb->frame_len; n++) { for (k = 0; k < resolution[band]; k++) { QMF_RE(X_hybrid[n][offset + k]) = QMF_RE(hyb->temp[n][k]); QMF_IM(X_hybrid[n][offset + k]) = QMF_IM(hyb->temp[n][k]); } } offset += resolution[band]; } /* group hybrid channels */ if (!use34) { for (n = 0; n < 32 /*30?*/; n++) { QMF_RE(X_hybrid[n][3]) += QMF_RE(X_hybrid[n][4]); QMF_IM(X_hybrid[n][3]) += QMF_IM(X_hybrid[n][4]); QMF_RE(X_hybrid[n][4]) = 0; QMF_IM(X_hybrid[n][4]) = 0; QMF_RE(X_hybrid[n][2]) += QMF_RE(X_hybrid[n][5]); QMF_IM(X_hybrid[n][2]) += QMF_IM(X_hybrid[n][5]); QMF_RE(X_hybrid[n][5]) = 0; QMF_IM(X_hybrid[n][5]) = 0; } } } static void hybrid_synthesis(hyb_info *hyb, qmf_t X[32][64], qmf_t X_hybrid[32][32], uint8_t use34) { uint8_t k, n, band; uint8_t offset = 0; uint8_t qmf_bands = (use34) ? 5 : 3; uint8_t *resolution = (use34) ? hyb->resolution34 : hyb->resolution20; for(band = 0; band < qmf_bands; band++) { for (n = 0; n < hyb->frame_len; n++) { QMF_RE(X[n][band]) = 0; QMF_IM(X[n][band]) = 0; for (k = 0; k < resolution[band]; k++) { QMF_RE(X[n][band]) += QMF_RE(X_hybrid[n][offset + k]); QMF_IM(X[n][band]) += QMF_IM(X_hybrid[n][offset + k]); } } offset += resolution[band]; } } /* limits the value i to the range [min,max] */ static int8_t delta_clip(int8_t i, int8_t min, int8_t max) { if (i < min) return min; else if (i > max) return max; else return i; } /* delta decode array */ static void delta_decode(uint8_t enable, int8_t *index, uint8_t *index_prev, uint8_t dt_flag, uint8_t nr_par, uint8_t stride, int8_t min_index, int8_t max_index) { int8_t i; if (enable == 1) { if (dt_flag == 0) { /* delta coded in frequency direction */ index[0] = 0 + index[0]; index[0] = delta_clip(index[0], min_index, max_index); for (i = 1; i < nr_par; i++) { index[i] = index[i-1] + index[i]; index[i] = delta_clip(index[i], min_index, max_index); } } else { /* delta coded in time direction */ for (i = 0; i < nr_par; i++) { index[i] = index_prev[i*stride] + index[i]; index[i] = delta_clip(index[i], min_index, max_index); } } } else { /* set indices to zero */ for (i = 0; i < nr_par; i++) { index[i] = 0; } } /* coarse */ if (stride == 2) { for (i = (nr_par<<1)-1; i > 0; i--) { index[i] = index[i>>1]; } } } #ifdef PS_LOW_POWER static void map34indexto20(int8_t *index, uint8_t bins) { index[0] = (2*index[0]+index[1])/3; index[1] = (index[1]+2*index[2])/3; index[2] = (2*index[3]+index[4])/3; index[3] = (index[4]+2*index[5])/3; index[4] = (index[6]+index[7])/2; index[5] = (index[8]+index[9])/2; index[6] = index[10]; index[7] = index[11]; index[8] = (index[12]+index[13])/2; index[9] = (index[14]+index[15])/2; index[10] = index[16]; if (bins == 34) { index[11] = index[17]; index[12] = index[18]; index[13] = index[19]; index[14] = (index[20]+index[21])/2; index[15] = (index[22]+index[23])/2; index[16] = (index[24]+index[25])/2; index[17] = (index[26]+index[27])/2; index[18] = (index[28]+index[29]+index[30]+index[31])/4; index[19] = (index[32]+index[33])/2; } } #endif static void map20indexto34(int8_t *index, uint8_t bins) { index[0] = index[0]; index[1] = (index[0] + index[1])/2; index[2] = index[1]; index[3] = index[2]; index[4] = (index[2] + index[3])/2; index[5] = index[3]; index[6] = index[4]; index[7] = index[4]; index[8] = index[5]; index[9] = index[5]; index[10] = index[6]; index[11] = index[7]; index[12] = index[8]; index[13] = index[8]; index[14] = index[9]; index[15] = index[9]; index[16] = index[10]; if (bins == 34) { index[17] = index[11]; index[18] = index[12]; index[19] = index[13]; index[20] = index[14]; index[21] = index[14]; index[22] = index[15]; index[23] = index[15]; index[24] = index[16]; index[25] = index[16]; index[26] = index[17]; index[27] = index[17]; index[28] = index[18]; index[29] = index[18]; index[30] = index[18]; index[31] = index[18]; index[32] = index[19]; index[33] = index[19]; } } /* parse the bitstream data decoded in ps_data() */ static void ps_data_decode(ps_info *ps) { uint8_t env, bin; /* ps data not available, use data from previous frame */ if (ps->ps_data_available == 0) { ps->num_env = 0; } for (env = 0; env < ps->num_env; env++) { int8_t *iid_index_prev; int8_t *icc_index_prev; int8_t *ipd_index_prev; int8_t *opd_index_prev; int8_t num_iid_steps = (ps->iid_mode < 3) ? 7 : 15 /*fine quant*/; if (env == 0) { /* take last envelope from previous frame */ iid_index_prev = ps->iid_index_prev; icc_index_prev = ps->icc_index_prev; ipd_index_prev = ps->ipd_index_prev; opd_index_prev = ps->opd_index_prev; } else { /* take index values from previous envelope */ iid_index_prev = ps->iid_index[env - 1]; icc_index_prev = ps->icc_index[env - 1]; ipd_index_prev = ps->ipd_index[env - 1]; opd_index_prev = ps->opd_index[env - 1]; } /* delta decode iid parameters */ delta_decode(ps->enable_iid, ps->iid_index[env], iid_index_prev, ps->iid_dt[env], ps->nr_iid_par, (ps->iid_mode == 0 || ps->iid_mode == 3) ? 2 : 1, -num_iid_steps, num_iid_steps); /* delta decode icc parameters */ delta_decode(ps->enable_icc, ps->icc_index[env], icc_index_prev, ps->icc_dt[env], ps->nr_icc_par, (ps->icc_mode == 0 || ps->icc_mode == 3) ? 2 : 1, 0, 7); /* delta decode ipd parameters */ delta_decode(ps->enable_ipdopd, ps->ipd_index[env], ipd_index_prev, ps->ipd_dt[env], ps->nr_ipdopd_par, 1, -8, 8); /* delta decode opd parameters */ delta_decode(ps->enable_ipdopd, ps->opd_index[env], opd_index_prev, ps->opd_dt[env], ps->nr_ipdopd_par, 1, -8, 8); } /* handle error case */ if (ps->num_env == 0) { /* force to 1 */ ps->num_env = 1; if (ps->enable_iid) { for (bin = 0; bin < 34; bin++) ps->iid_index[0][bin] = ps->iid_index_prev[bin]; } else { for (bin = 0; bin < 34; bin++) ps->iid_index[0][bin] = 0; } if (ps->enable_icc) { for (bin = 0; bin < 34; bin++) ps->icc_index[0][bin] = ps->icc_index_prev[bin]; } else { for (bin = 0; bin < 34; bin++) ps->icc_index[0][bin] = 0; } if (ps->enable_ipdopd) { for (bin = 0; bin < 17; bin++) { ps->ipd_index[0][bin] = ps->ipd_index_prev[bin]; ps->opd_index[0][bin] = ps->opd_index_prev[bin]; } } else { for (bin = 0; bin < 17; bin++) { ps->ipd_index[0][bin] = 0; ps->opd_index[0][bin] = 0; } } } /* update previous indices */ for (bin = 0; bin < 34; bin++) ps->iid_index_prev[bin] = ps->iid_index[ps->num_env-1][bin]; for (bin = 0; bin < 34; bin++) ps->icc_index_prev[bin] = ps->icc_index[ps->num_env-1][bin]; for (bin = 0; bin < 17; bin++) { ps->ipd_index_prev[bin] = ps->ipd_index[ps->num_env-1][bin]; ps->opd_index_prev[bin] = ps->opd_index[ps->num_env-1][bin]; } ps->ps_data_available = 0; if (ps->frame_class == 0) { ps->border_position[0] = 0; for (env = 1; env < ps->num_env; env++) { ps->border_position[env] = (env * 32 /* 30 for 960? */) / ps->num_env; } ps->border_position[ps->num_env] = 32 /* 30 for 960? */; } else { ps->border_position[0] = 0; if (ps->border_position[ps->num_env] < 32 /* 30 for 960? */) { ps->num_env++; ps->border_position[ps->num_env] = 32 /* 30 for 960? */; for (bin = 0; bin < 34; bin++) { ps->iid_index[ps->num_env][bin] = ps->iid_index[ps->num_env-1][bin]; ps->icc_index[ps->num_env][bin] = ps->icc_index[ps->num_env-1][bin]; } for (bin = 0; bin < 17; bin++) { ps->ipd_index[ps->num_env][bin] = ps->ipd_index[ps->num_env-1][bin]; ps->opd_index[ps->num_env][bin] = ps->opd_index[ps->num_env-1][bin]; } } for (env = 1; env < ps->num_env; env++) { int8_t thr = 32 /* 30 for 960? */ - (ps->num_env - env); if (ps->border_position[env] > thr) { ps->border_position[env] = thr; } else { thr = ps->border_position[env-1]+1; if (ps->border_position[env] < thr) { ps->border_position[env] = thr; } } } } /* make sure that the indices of all parameters can be mapped * to the same hybrid synthesis filterbank */ #ifdef PS_LOW_POWER for (env = 0; env < ps->num_env; env++) { if (ps->iid_mode == 2 || ps->iid_mode == 5) map34indexto20(ps->iid_index[env], 34); if (ps->icc_mode == 2 || ps->icc_mode == 5) map34indexto20(ps->icc_index[env], 34); /* disable ipd/opd */ for (bin = 0; bin < 17; bin++) { ps->aaIpdIndex[env][bin] = 0; ps->aaOpdIndex[env][bin] = 0; } } #else if (ps->use34hybrid_bands) { for (env = 0; env < ps->num_env; env++) { if (ps->iid_mode != 2 && ps->iid_mode != 5) map20indexto34(ps->iid_index[env], 34); if (ps->icc_mode != 2 && ps->icc_mode != 5) map20indexto34(ps->icc_index[env], 34); if (ps->ipd_mode != 2 && ps->ipd_mode != 5) { map20indexto34(ps->ipd_index[env], 17); map20indexto34(ps->opd_index[env], 17); } } } #endif #if 0 for (env = 0; env < ps->num_env; env++) { printf("iid[env:%d]:", env); for (bin = 0; bin < 34; bin++) { printf(" %d", ps->iid_index[env][bin]); } printf("\n"); } for (env = 0; env < ps->num_env; env++) { printf("icc[env:%d]:", env); for (bin = 0; bin < 34; bin++) { printf(" %d", ps->icc_index[env][bin]); } printf("\n"); } for (env = 0; env < ps->num_env; env++) { printf("ipd[env:%d]:", env); for (bin = 0; bin < 17; bin++) { printf(" %d", ps->ipd_index[env][bin]); } printf("\n"); } for (env = 0; env < ps->num_env; env++) { printf("opd[env:%d]:", env); for (bin = 0; bin < 17; bin++) { printf(" %d", ps->opd_index[env][bin]); } printf("\n"); } printf("\n"); #endif } /* decorrelate the mono signal using an allpass filter */ static void ps_decorrelate(ps_info *ps, qmf_t X_left[38][64], qmf_t X_right[38][64], qmf_t X_hybrid_left[32][32], qmf_t X_hybrid_right[32][32]) { uint8_t gr, m, n, bk; uint8_t temp_delay; uint8_t sb, maxsb; const complex_t *Phi_Fract_SubQmf; uint8_t temp_delay_ser[NO_ALLPASS_LINKS]; real_t P_SmoothPeakDecayDiffNrg, nrg; real_t P[32][34]; real_t G_TransientRatio[32][34]; complex_t inputLeft; /* chose hybrid filterbank: 20 or 34 band case */ if (ps->use34hybrid_bands) { Phi_Fract_SubQmf = Phi_Fract_SubQmf34; } else{ Phi_Fract_SubQmf = Phi_Fract_SubQmf20; } for (n = 0; n < 32; n++) { for (bk = 0; bk < 34; bk++) { P[n][bk] = 0; } } for (gr = 0; gr < ps->num_groups; gr++) { bk = (~NEGATE_IPD_MASK) & ps->map_bins2group[gr]; maxsb = (gr < ps->num_hybrid_groups) ? ps->group_border[gr]+1 : ps->group_border[gr+1]; for (sb = ps->group_border[gr]; sb < maxsb; sb++) { for (n = ps->border_position[0] ; n < ps->border_position[ps->num_env] ; n++) { if (gr < ps->num_hybrid_groups) { RE(inputLeft) = QMF_RE(X_hybrid_left[n][sb]); IM(inputLeft) = QMF_IM(X_hybrid_left[n][sb]); } else { RE(inputLeft) = QMF_RE(X_left[n][sb]); IM(inputLeft) = QMF_IM(X_left[n][sb]); } P[n][bk] += MUL_R(RE(inputLeft),RE(inputLeft)) + MUL_R(IM(inputLeft),IM(inputLeft)); } } } for (bk = 0; bk < ps->nr_par_bands; bk++) { for (n = ps->border_position[0]; n < ps->border_position[ps->num_env]; n++) { const real_t gamma = COEF_CONST(1.5); ps->P_PeakDecayNrg[bk] = MUL_F(ps->P_PeakDecayNrg[bk], ps->alpha_decay); if (ps->P_PeakDecayNrg[bk] < P[n][bk]) ps->P_PeakDecayNrg[bk] = P[n][bk]; P_SmoothPeakDecayDiffNrg = ps->P_SmoothPeakDecayDiffNrg_prev[bk]; P_SmoothPeakDecayDiffNrg += MUL_F((ps->P_PeakDecayNrg[bk] - P[n][bk] - ps->P_SmoothPeakDecayDiffNrg_prev[bk]), ps->alpha_smooth); ps->P_SmoothPeakDecayDiffNrg_prev[bk] = P_SmoothPeakDecayDiffNrg; nrg = ps->P_prev[bk]; nrg += MUL_F((P[n][bk] - ps->P_prev[bk]), ps->alpha_smooth); ps->P_prev[bk] = nrg; if (MUL_C(P_SmoothPeakDecayDiffNrg, gamma) <= nrg) { G_TransientRatio[n][bk] = REAL_CONST(1.0); } else { G_TransientRatio[n][bk] = SBR_DIV(nrg, (MUL_C(P_SmoothPeakDecayDiffNrg, gamma))); } } } for (gr = 0; gr < ps->num_groups; gr++) { if (gr < ps->num_hybrid_groups) maxsb = ps->group_border[gr] + 1; else maxsb = ps->group_border[gr + 1]; /* QMF channel */ for (sb = ps->group_border[gr]; sb < maxsb; sb++) { real_t g_DecaySlope; /* g_DecaySlope: [0..1] */ if (gr < ps->num_hybrid_groups || sb <= ps->decay_cutoff) { g_DecaySlope = FRAC_CONST(1.0); } else { int8_t decay = ps->decay_cutoff - sb; if (decay <= -20 /* -1/DECAY_SLOPE */) { g_DecaySlope = 0; } else { /* decay(int)*decay_slope(frac) = g_DecaySlope(frac) */ g_DecaySlope = FRAC_CONST(1.0) + DECAY_SLOPE * decay; } } /* set delay indices */ temp_delay = ps->saved_delay; for (n = 0; n < NO_ALLPASS_LINKS; n++) temp_delay_ser[n] = ps->delay_buf_index_ser[n]; for (n = ps->border_position[0]; n < ps->border_position[ps->num_env]; n++) { complex_t tmp, tmp0, R0; if (gr < ps->num_hybrid_groups) { RE(inputLeft) = QMF_RE(X_hybrid_left[n][sb]); IM(inputLeft) = QMF_IM(X_hybrid_left[n][sb]); } else { RE(inputLeft) = QMF_RE(X_left[n][sb]); IM(inputLeft) = QMF_IM(X_left[n][sb]); } if (sb > ps->nr_allpass_bands && gr >= ps->num_hybrid_groups) { /* delay */ /* never SubQMF here */ RE(tmp) = RE(ps->delay_Qmf[ps->delay_buf_index_delay[sb]][sb]); IM(tmp) = IM(ps->delay_Qmf[ps->delay_buf_index_delay[sb]][sb]); RE(R0) = RE(tmp); IM(R0) = IM(tmp); RE(ps->delay_Qmf[ps->delay_buf_index_delay[sb]][sb]) = RE(inputLeft); IM(ps->delay_Qmf[ps->delay_buf_index_delay[sb]][sb]) = IM(inputLeft); } else { /* allpass filter */ uint8_t m; complex_t Phi_Fract; /* fetch parameters */ if (gr < ps->num_hybrid_groups) { RE(tmp0) = RE(ps->delay_SubQmf[temp_delay][sb]); IM(tmp0) = IM(ps->delay_SubQmf[temp_delay][sb]); RE(ps->delay_SubQmf[temp_delay][sb]) = RE(inputLeft); IM(ps->delay_SubQmf[temp_delay][sb]) = IM(inputLeft); RE(Phi_Fract) = RE(Phi_Fract_SubQmf[sb]); IM(Phi_Fract) = IM(Phi_Fract_SubQmf[sb]); } else { RE(tmp0) = RE(ps->delay_Qmf[temp_delay][sb]); IM(tmp0) = IM(ps->delay_Qmf[temp_delay][sb]); RE(ps->delay_Qmf[temp_delay][sb]) = RE(inputLeft); IM(ps->delay_Qmf[temp_delay][sb]) = IM(inputLeft); RE(Phi_Fract) = RE(Phi_Fract_Qmf[sb]); IM(Phi_Fract) = IM(Phi_Fract_Qmf[sb]); } /* delay by fraction */ ComplexMult(&RE(tmp), &IM(tmp), RE(tmp0), IM(tmp0), RE(Phi_Fract), IM(Phi_Fract)); RE(R0) = RE(tmp); IM(R0) = IM(tmp); for (m = 0; m < NO_ALLPASS_LINKS ; m++) { complex_t Q_Fract_allpass, tmp2; /* fetch parameters */ if (gr < ps->num_hybrid_groups) { RE(tmp0) = RE(ps->delay_SubQmf_ser[m][temp_delay_ser[m]][sb]); IM(tmp0) = IM(ps->delay_SubQmf_ser[m][temp_delay_ser[m]][sb]); if (ps->use34hybrid_bands) { RE(Q_Fract_allpass) = RE(Q_Fract_allpass_SubQmf34[sb][m]); IM(Q_Fract_allpass) = IM(Q_Fract_allpass_SubQmf34[sb][m]); } else { RE(Q_Fract_allpass) = RE(Q_Fract_allpass_SubQmf20[sb][m]); IM(Q_Fract_allpass) = IM(Q_Fract_allpass_SubQmf20[sb][m]); } } else { RE(tmp0) = RE(ps->delay_Qmf_ser[m][temp_delay_ser[m]][sb]); IM(tmp0) = IM(ps->delay_Qmf_ser[m][temp_delay_ser[m]][sb]); RE(Q_Fract_allpass) = RE(Q_Fract_allpass_Qmf[sb][m]); IM(Q_Fract_allpass) = IM(Q_Fract_allpass_Qmf[sb][m]); } ComplexMult(&RE(tmp), &IM(tmp), RE(tmp0), IM(tmp0), RE(Q_Fract_allpass), IM(Q_Fract_allpass)); RE(tmp) += -MUL_F(g_DecaySlope, MUL_F(filter_a[m], RE(R0))); IM(tmp) += -MUL_F(g_DecaySlope, MUL_F(filter_a[m], IM(R0))); RE(tmp2) = RE(R0) + MUL_F(g_DecaySlope, MUL_F(filter_a[m], RE(tmp))); IM(tmp2) = IM(R0) + MUL_F(g_DecaySlope, MUL_F(filter_a[m], IM(tmp))); if (gr < ps->num_hybrid_groups) { RE(ps->delay_SubQmf_ser[m][temp_delay_ser[m]][sb]) = RE(tmp2); IM(ps->delay_SubQmf_ser[m][temp_delay_ser[m]][sb]) = IM(tmp2); } else { RE(ps->delay_Qmf_ser[m][temp_delay_ser[m]][sb]) = RE(tmp2); IM(ps->delay_Qmf_ser[m][temp_delay_ser[m]][sb]) = IM(tmp2); } RE(R0) = RE(tmp); IM(R0) = IM(tmp); } } bk = (~NEGATE_IPD_MASK) & ps->map_bins2group[gr]; /* duck if a past transient is found */ if (gr < ps->num_hybrid_groups) { QMF_RE(X_hybrid_right[n][sb]) = MUL_R(G_TransientRatio[n][bk], RE(R0)); QMF_IM(X_hybrid_right[n][sb]) = MUL_R(G_TransientRatio[n][bk], IM(R0)); } else { QMF_RE(X_right[n][sb]) = MUL_R(G_TransientRatio[n][bk], RE(R0)); QMF_IM(X_right[n][sb]) = MUL_R(G_TransientRatio[n][bk], IM(R0)); } /* Update delay buffer index */ if (++temp_delay >= 2) temp_delay = 0; if (sb > ps->nr_allpass_bands && gr >= ps->num_hybrid_groups) { if (++ps->delay_buf_index_delay[sb] >= ps->delay_D[sb]) { ps->delay_buf_index_delay[sb] = 0; } } for (m = 0; m < NO_ALLPASS_LINKS; m++) { if (++temp_delay_ser[m] >= ps->num_sample_delay_ser[m]) temp_delay_ser[m] = 0; } } } } ps->saved_delay = temp_delay; for (m = 0; m < NO_ALLPASS_LINKS; m++) ps->delay_buf_index_ser[m] = temp_delay_ser[m]; } static void ps_mix_phase(ps_info *ps, qmf_t X_left[38][64], qmf_t X_right[38][64], qmf_t X_hybrid_left[32][32], qmf_t X_hybrid_right[32][32]) { uint8_t i; uint8_t gr; uint8_t bk = 0; uint8_t sb, maxsb; uint8_t env; uint8_t nr_ipdopd_par; real_t scaleL, scaleR; complex_t h11, h12, h21, h22; complex_t H11, H12, H21, H22; complex_t deltaH11, deltaH12, deltaH21, deltaH22; complex_t tempLeft; complex_t tempRight; real_t L; const real_t *sf_iid; const uint8_t *quant_iid; uint8_t no_iid_steps; if (ps->iid_mode >= 3) { no_iid_steps = 15; sf_iid = sf_iid_fine; quant_iid = quant_iid_fine; } else { no_iid_steps = 7; sf_iid = sf_iid_normal; quant_iid = quant_iid_normal; } if (ps->ipd_mode == 0 || ps->ipd_mode == 3) { nr_ipdopd_par = 11; /* resolution */ } else { nr_ipdopd_par = ps->nr_ipdopd_par; } for (gr = 0; gr < ps->num_groups; gr++) { bk = (~NEGATE_IPD_MASK) & ps->map_bins2group[gr]; /* use one channel per group in the subqmf domain */ maxsb = (gr < ps->num_hybrid_groups) ? ps->group_border[gr] + 1 : ps->group_border[gr + 1]; for (env = 0; env < ps->num_env; env++) { if (ps->icc_mode < 3) { /* type 'A' mixing */ real_t cosa, sina; real_t cosb, sinb; real_t ab1, ab2; real_t ab3, ab4; scaleR = sf_iid[no_iid_steps + ps->iid_index[env][bk]]; scaleL = sf_iid[no_iid_steps - ps->iid_index[env][bk]]; cosa = cos_alphas[ps->icc_index[env][bk]]; sina = sin_alphas[ps->icc_index[env][bk]]; if (ps->iid_mode >= 3) { if (ps->iid_index[env][bk] < 0) { cosb = cos_betas_fine[-ps->iid_index[env][bk]][ps->icc_index[env][bk]]; sinb = -sin_betas_fine[-ps->iid_index[env][bk]][ps->icc_index[env][bk]]; } else { cosb = cos_betas_fine[ps->iid_index[env][bk]][ps->icc_index[env][bk]]; sinb = sin_betas_fine[ps->iid_index[env][bk]][ps->icc_index[env][bk]]; } } else { if (ps->iid_index[env][bk] < 0) { cosb = cos_betas_normal[-ps->iid_index[env][bk]][ps->icc_index[env][bk]]; sinb = -sin_betas_normal[-ps->iid_index[env][bk]][ps->icc_index[env][bk]]; } else { cosb = cos_betas_normal[ps->iid_index[env][bk]][ps->icc_index[env][bk]]; sinb = sin_betas_normal[ps->iid_index[env][bk]][ps->icc_index[env][bk]]; } } ab1 = MUL_C(cosb, cosa); ab2 = MUL_C(sinb, sina); ab3 = MUL_C(sinb, cosa); ab4 = MUL_C(cosb, sina); /* hxx: COEF */ RE(h11) = MUL_C(scaleL, (ab1 - ab2)); RE(h12) = MUL_C(scaleR, (ab1 + ab2)); RE(h21) = MUL_C(scaleL, (ab3 + ab4)); RE(h22) = MUL_C(scaleR, (ab3 - ab4)); //printf("%d %f %f %f %f\n", ps->iid_index[env][bin], scaleR, scaleL, alpha, beta); } else { /* type 'B' mixing */ float c, rho, mu, alpha, gamma; uint8_t i; i = ps->iid_index[env][bk]; c = (float)pow(10.0, ((i)?(((i>0)?1:-1)*quant_iid[((i>0)?i:-i)-1]):0.)/20.0); rho = quant_rho[ps->icc_index[env][bk]]; rho = max(rho, 0.05f); if (rho == 0.0f && c == 1.) { alpha = (float)M_PI/4.0f; } else { if (rho <= 0.0f) { rho = 0.05f; } alpha = 0.5f*(float)atan( (2.0f*c*rho) / (c*c-1.0f) ); if (alpha < 0.) { alpha += (float)M_PI/2.0f; } if (rho < 0.) { /* alpha = -alpha; */ alpha += (float)M_PI; } } mu = c+1.0f/c; mu = 1+(4.0f*rho*rho-4.0f)/(mu*mu); gamma = (float)atan(sqrt((1.0f-sqrt(mu))/(1.0f+sqrt(mu)))); RE(h11) = ( float )(CSQRT2 * cos(alpha) * cos(gamma)); RE(h12) = ( float )(CSQRT2 * sin(alpha) * cos(gamma)); RE(h21) = ( float )(CSQRT2 * -cos(alpha) * sin(gamma)); RE(h22) = ( float )(CSQRT2 * sin(alpha) * sin(gamma)); } if ((ps->enable_ipdopd) && (bk < nr_ipdopd_par)) { real_t ipd, opd; ipd = (float)( M_PI/8.0 * 2.0f ) * ps->ipd_index[env][bk]; opd = (float)( M_PI/8.0 * 2.0f ) * ps->opd_index[env][bk]; i = ps->phase_hist; RE(tempLeft) = 0.25f * RE(ps->ipd_prev[bk][i]); IM(tempLeft) = 0.25f * IM(ps->ipd_prev[bk][i]); RE(tempRight) = 0.25f * RE(ps->opd_prev[bk][i]); IM(tempRight) = 0.25f * IM(ps->opd_prev[bk][i]); RE(ps->ipd_prev[bk][i]) = (float)cos(ipd); IM(ps->ipd_prev[bk][i]) = (float)sin(ipd); RE(ps->opd_prev[bk][i]) = (float)cos(opd); IM(ps->opd_prev[bk][i]) = (float)sin(opd); RE(tempLeft) += RE(ps->ipd_prev[bk][i]); IM(tempLeft) += IM(ps->ipd_prev[bk][i]); RE(tempRight) += RE(ps->opd_prev[bk][i]); IM(tempRight) += IM(ps->opd_prev[bk][i]); if (i == 0) { i = 2; } i--; RE(tempLeft) += 0.5f * RE(ps->ipd_prev[bk][i]); IM(tempLeft) += 0.5f * IM(ps->ipd_prev[bk][i]); RE(tempRight) += 0.5f * RE(ps->opd_prev[bk][i]); IM(tempRight) += 0.5f * IM(ps->opd_prev[bk][i]); ipd = (float)atan2(IM(tempLeft), RE(tempLeft)); opd = (float)atan2(IM(tempRight), RE(tempRight)); /* phase rotation */ RE(tempLeft) = (float)cos(opd); IM(tempLeft) = (float)sin(opd); opd -= ipd; RE(tempRight) = (float)cos(opd); IM(tempRight) = (float)sin(opd); IM(h11) = RE(h11) * IM(tempLeft); IM(h12) = RE(h12) * IM(tempRight); IM(h21) = RE(h21) * IM(tempLeft); IM(h22) = RE(h22) * IM(tempRight); RE(h11) *= RE(tempLeft); RE(h12) *= RE(tempRight); RE(h21) *= RE(tempLeft); RE(h22) *= RE(tempRight); } /* length of the envelope (in time samples) */ L = (real_t)(ps->border_position[env + 1] - ps->border_position[env]); RE(deltaH11) = (RE(h11) - RE(ps->h11_prev[gr])) / L; RE(deltaH12) = (RE(h12) - RE(ps->h12_prev[gr])) / L; RE(deltaH21) = (RE(h21) - RE(ps->h21_prev[gr])) / L; RE(deltaH22) = (RE(h22) - RE(ps->h22_prev[gr])) / L; RE(H11) = RE(ps->h11_prev[gr]); RE(H12) = RE(ps->h12_prev[gr]); RE(H21) = RE(ps->h21_prev[gr]); RE(H22) = RE(ps->h22_prev[gr]); RE(ps->h11_prev[gr]) = RE(h11); RE(ps->h12_prev[gr]) = RE(h12); RE(ps->h21_prev[gr]) = RE(h21); RE(ps->h22_prev[gr]) = RE(h22); if ((ps->enable_ipdopd) && (bk < nr_ipdopd_par)) { IM(deltaH11) = (IM(h11) - IM(ps->h11_prev[gr])) / L; IM(deltaH12) = (IM(h12) - IM(ps->h12_prev[gr])) / L; IM(deltaH21) = (IM(h21) - IM(ps->h21_prev[gr])) / L; IM(deltaH22) = (IM(h22) - IM(ps->h22_prev[gr])) / L; IM(H11) = IM(ps->h11_prev[gr]); IM(H12) = IM(ps->h12_prev[gr]); IM(H21) = IM(ps->h21_prev[gr]); IM(H22) = IM(ps->h22_prev[gr]); if ((NEGATE_IPD_MASK & ps->map_bins2group[gr]) != 0) { IM(deltaH11) = -IM(deltaH11); IM(deltaH12) = -IM(deltaH12); IM(deltaH21) = -IM(deltaH21); IM(deltaH22) = -IM(deltaH22); IM(H11) = -IM(H11); IM(H12) = -IM(H12); IM(H21) = -IM(H21); IM(H22) = -IM(H22); } IM(ps->h11_prev[gr]) = IM(h11); IM(ps->h12_prev[gr]) = IM(h12); IM(ps->h21_prev[gr]) = IM(h21); IM(ps->h22_prev[gr]) = IM(h22); } for (i = ps->border_position[env]; i < ps->border_position[env + 1]; i++) { RE(H11) += RE(deltaH11); RE(H12) += RE(deltaH12); RE(H21) += RE(deltaH21); RE(H22) += RE(deltaH22); if ((ps->enable_ipdopd) && (bk < nr_ipdopd_par)) { IM(H11) += IM(deltaH11); IM(H12) += IM(deltaH12); IM(H21) += IM(deltaH21); IM(H22) += IM(deltaH22); } /* channel is an alias to the subband */ for (sb = ps->group_border[gr]; sb < maxsb; sb++) { complex_t inLeft, inRight; if (gr < ps->num_hybrid_groups) { RE(inLeft) = RE(X_hybrid_left[i][sb]); IM(inLeft) = IM(X_hybrid_left[i][sb]); RE(inRight) = RE(X_hybrid_right[i][sb]); IM(inRight) = IM(X_hybrid_right[i][sb]); } else { RE(inLeft) = RE(X_left[i][sb]); IM(inLeft) = IM(X_left[i][sb]); RE(inRight) = RE(X_right[i][sb]); IM(inRight) = IM(X_right[i][sb]); } RE(tempLeft) = RE(H11) * RE(inLeft) + RE(H21) * RE(inRight); IM(tempLeft) = RE(H11) * IM(inLeft) + RE(H21) * IM(inRight); RE(tempRight) = RE(H12) * RE(inLeft) + RE(H22) * RE(inRight); IM(tempRight) = RE(H12) * IM(inLeft) + RE(H22) * IM(inRight); if ((ps->enable_ipdopd) && (bk < nr_ipdopd_par)) { RE(tempLeft) -= IM(H11) * IM(inLeft) + IM(H21) * IM(inRight); IM(tempLeft) += IM(H11) * RE(inLeft) + IM(H21) * RE(inRight); RE(tempRight) -= IM(H12) * IM(inLeft) + IM(H22) * IM(inRight); IM(tempRight) += IM(H12) * RE(inLeft) + IM(H22) * RE(inRight); } if (gr < ps->num_hybrid_groups) { RE(X_hybrid_left[i][sb]) = RE(tempLeft); IM(X_hybrid_left[i][sb]) = IM(tempLeft); RE(X_hybrid_right[i][sb]) = RE(tempRight); IM(X_hybrid_right[i][sb]) = IM(tempRight); } else { RE(X_left[i][sb]) = RE(tempLeft); IM(X_left[i][sb]) = IM(tempLeft); RE(X_right[i][sb]) = RE(tempRight); IM(X_right[i][sb]) = IM(tempRight); } } } /* shift phase smoother's circular buffer index */ ps->phase_hist++; if (ps->phase_hist == 2) { ps->phase_hist = 0; } } } } ps_info *ps_init(uint8_t sr_index) { uint8_t i; uint8_t short_delay_band; ps_info *ps = (ps_info*)faad_malloc(sizeof(ps_info)); memset(ps, 0, sizeof(ps_info)); ps->hyb = hybrid_init(); ps->ps_data_available = 0; /* delay stuff*/ ps->saved_delay = 0; for (i = 0; i < 64; i++) { ps->delay_buf_index_delay[i] = 0; } for (i = 0; i < NO_ALLPASS_LINKS; i++) { ps->delay_buf_index_ser[i] = 0; if (sr_index <= 5) /* >= 32 kHz*/ { ps->num_sample_delay_ser[i] = delay_length_d[1][i]; } else { ps->num_sample_delay_ser[i] = delay_length_d[0][i]; } } if (sr_index <= 5) /* >= 32 kHz*/ { short_delay_band = 35; ps->nr_allpass_bands = 22; ps->alpha_decay = FRAC_CONST(0.76592833836465); ps->alpha_smooth = FRAC_CONST(0.25); } else { short_delay_band = 64; ps->nr_allpass_bands = 45; ps->alpha_decay = FRAC_CONST(0.58664621951003); ps->alpha_smooth = FRAC_CONST(0.6); } for (i = 0; i < short_delay_band; i++) { ps->delay_D[i] = 14; } for (i = short_delay_band; i < 64; i++) { ps->delay_D[i] = 1; } /* mixing and phase */ for (i = 0; i < 50; i++) { RE(ps->h11_prev[i]) = 1; IM(ps->h12_prev[i]) = 1; RE(ps->h11_prev[i]) = 1; IM(ps->h12_prev[i]) = 1; } ps->phase_hist = 0; for (i = 0; i < 20; i++) { RE(ps->ipd_prev[i][0]) = 0; IM(ps->ipd_prev[i][0]) = 0; RE(ps->ipd_prev[i][1]) = 0; IM(ps->ipd_prev[i][1]) = 0; RE(ps->opd_prev[i][0]) = 0; IM(ps->opd_prev[i][0]) = 0; RE(ps->opd_prev[i][1]) = 0; IM(ps->opd_prev[i][1]) = 0; } return ps; } /* main Parametric Stereo decoding function */ uint8_t ps_decode(ps_info *ps, qmf_t X_left[38][64], qmf_t X_right[38][64]) { qmf_t X_hybrid_left[32][32] = {{0}}; qmf_t X_hybrid_right[32][32] = {{0}}; /* delta decoding of the bitstream data */ ps_data_decode(ps); /* set up some parameters depending on filterbank type */ if (ps->use34hybrid_bands) { ps->group_border = (uint8_t*)group_border34; ps->map_bins2group = (uint16_t*)map_bins2group34; ps->num_groups = 32+18; ps->num_hybrid_groups = 32; ps->nr_par_bands = 34; ps->decay_cutoff = 5; } else { ps->group_border = (uint8_t*)group_border20; ps->map_bins2group = (uint16_t*)map_bins2group20; ps->num_groups = 10+12; ps->num_hybrid_groups = 10; ps->nr_par_bands = 20; ps->decay_cutoff = 3; } /* Perform further analysis on the lowest subbands to get a higher * frequency resolution */ hybrid_analysis((hyb_info*)ps->hyb, X_left, X_hybrid_left, ps->use34hybrid_bands); /* decorrelate mono signal */ ps_decorrelate(ps, X_left, X_right, X_hybrid_left, X_hybrid_right); /* apply mixing and phase parameters */ ps_mix_phase(ps, X_left, X_right, X_hybrid_left, X_hybrid_right); /* hybrid synthesis, to rebuild the SBR QMF matrices */ hybrid_synthesis((hyb_info*)ps->hyb, X_left, X_hybrid_left, ps->use34hybrid_bands); hybrid_synthesis((hyb_info*)ps->hyb, X_right, X_hybrid_right, ps->use34hybrid_bands); return 0; } #endif