Home | History | Annotate | Download | only in sbc
      1 /*
      2  *
      3  *  Bluetooth low-complexity, subband codec (SBC) library
      4  *
      5  *  Copyright (C) 2008-2010  Nokia Corporation
      6  *  Copyright (C) 2004-2010  Marcel Holtmann <marcel (at) holtmann.org>
      7  *  Copyright (C) 2004-2005  Henryk Ploetz <henryk (at) ploetzli.ch>
      8  *  Copyright (C) 2005-2006  Brad Midgley <bmidgley (at) xmission.com>
      9  *
     10  *
     11  *  This library is free software; you can redistribute it and/or
     12  *  modify it under the terms of the GNU Lesser General Public
     13  *  License as published by the Free Software Foundation; either
     14  *  version 2.1 of the License, or (at your option) any later version.
     15  *
     16  *  This library is distributed in the hope that it will be useful,
     17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     19  *  Lesser General Public License for more details.
     20  *
     21  *  You should have received a copy of the GNU Lesser General Public
     22  *  License along with this library; if not, write to the Free Software
     23  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
     24  *
     25  */
     26 
     27 /* A2DP specification: Appendix B, page 69 */
     28 static const int sbc_offset4[4][4] = {
     29 	{ -1, 0, 0, 0 },
     30 	{ -2, 0, 0, 1 },
     31 	{ -2, 0, 0, 1 },
     32 	{ -2, 0, 0, 1 }
     33 };
     34 
     35 /* A2DP specification: Appendix B, page 69 */
     36 static const int sbc_offset8[4][8] = {
     37 	{ -2, 0, 0, 0, 0, 0, 0, 1 },
     38 	{ -3, 0, 0, 0, 0, 0, 1, 2 },
     39 	{ -4, 0, 0, 0, 0, 0, 1, 2 },
     40 	{ -4, 0, 0, 0, 0, 0, 1, 2 }
     41 };
     42 
     43 
     44 #define SS4(val) ASR(val, SCALE_SPROTO4_TBL)
     45 #define SS8(val) ASR(val, SCALE_SPROTO8_TBL)
     46 #define SN4(val) ASR(val, SCALE_NPROTO4_TBL)
     47 #define SN8(val) ASR(val, SCALE_NPROTO8_TBL)
     48 
     49 static const int32_t sbc_proto_4_40m0[] = {
     50 	SS4(0x00000000), SS4(0xffa6982f), SS4(0xfba93848), SS4(0x0456c7b8),
     51 	SS4(0x005967d1), SS4(0xfffb9ac7), SS4(0xff589157), SS4(0xf9c2a8d8),
     52 	SS4(0x027c1434), SS4(0x0019118b), SS4(0xfff3c74c), SS4(0xff137330),
     53 	SS4(0xf81b8d70), SS4(0x00ec1b8b), SS4(0xfff0b71a), SS4(0xffe99b00),
     54 	SS4(0xfef84470), SS4(0xf6fb4370), SS4(0xffcdc351), SS4(0xffe01dc7)
     55 };
     56 
     57 static const int32_t sbc_proto_4_40m1[] = {
     58 	SS4(0xffe090ce), SS4(0xff2c0475), SS4(0xf694f800), SS4(0xff2c0475),
     59 	SS4(0xffe090ce), SS4(0xffe01dc7), SS4(0xffcdc351), SS4(0xf6fb4370),
     60 	SS4(0xfef84470), SS4(0xffe99b00), SS4(0xfff0b71a), SS4(0x00ec1b8b),
     61 	SS4(0xf81b8d70), SS4(0xff137330), SS4(0xfff3c74c), SS4(0x0019118b),
     62 	SS4(0x027c1434), SS4(0xf9c2a8d8), SS4(0xff589157), SS4(0xfffb9ac7)
     63 };
     64 
     65 static const int32_t sbc_proto_8_80m0[] = {
     66 	SS8(0x00000000), SS8(0xfe8d1970), SS8(0xee979f00), SS8(0x11686100),
     67 	SS8(0x0172e690), SS8(0xfff5bd1a), SS8(0xfdf1c8d4), SS8(0xeac182c0),
     68 	SS8(0x0d9daee0), SS8(0x00e530da), SS8(0xffe9811d), SS8(0xfd52986c),
     69 	SS8(0xe7054ca0), SS8(0x0a00d410), SS8(0x006c1de4), SS8(0xffdba705),
     70 	SS8(0xfcbc98e8), SS8(0xe3889d20), SS8(0x06af2308), SS8(0x000bb7db),
     71 	SS8(0xffca00ed), SS8(0xfc3fbb68), SS8(0xe071bc00), SS8(0x03bf7948),
     72 	SS8(0xffc4e05c), SS8(0xffb54b3b), SS8(0xfbedadc0), SS8(0xdde26200),
     73 	SS8(0x0142291c), SS8(0xff960e94), SS8(0xff9f3e17), SS8(0xfbd8f358),
     74 	SS8(0xdbf79400), SS8(0xff405e01), SS8(0xff7d4914), SS8(0xff8b1a31),
     75 	SS8(0xfc1417b8), SS8(0xdac7bb40), SS8(0xfdbb828c), SS8(0xff762170)
     76 };
     77 
     78 static const int32_t sbc_proto_8_80m1[] = {
     79 	SS8(0xff7c272c), SS8(0xfcb02620), SS8(0xda612700), SS8(0xfcb02620),
     80 	SS8(0xff7c272c), SS8(0xff762170), SS8(0xfdbb828c), SS8(0xdac7bb40),
     81 	SS8(0xfc1417b8), SS8(0xff8b1a31), SS8(0xff7d4914), SS8(0xff405e01),
     82 	SS8(0xdbf79400), SS8(0xfbd8f358), SS8(0xff9f3e17), SS8(0xff960e94),
     83 	SS8(0x0142291c), SS8(0xdde26200), SS8(0xfbedadc0), SS8(0xffb54b3b),
     84 	SS8(0xffc4e05c), SS8(0x03bf7948), SS8(0xe071bc00), SS8(0xfc3fbb68),
     85 	SS8(0xffca00ed), SS8(0x000bb7db), SS8(0x06af2308), SS8(0xe3889d20),
     86 	SS8(0xfcbc98e8), SS8(0xffdba705), SS8(0x006c1de4), SS8(0x0a00d410),
     87 	SS8(0xe7054ca0), SS8(0xfd52986c), SS8(0xffe9811d), SS8(0x00e530da),
     88 	SS8(0x0d9daee0), SS8(0xeac182c0), SS8(0xfdf1c8d4), SS8(0xfff5bd1a)
     89 };
     90 
     91 static const int32_t synmatrix4[8][4] = {
     92 	{ SN4(0x05a82798), SN4(0xfa57d868), SN4(0xfa57d868), SN4(0x05a82798) },
     93 	{ SN4(0x030fbc54), SN4(0xf89be510), SN4(0x07641af0), SN4(0xfcf043ac) },
     94 	{ SN4(0x00000000), SN4(0x00000000), SN4(0x00000000), SN4(0x00000000) },
     95 	{ SN4(0xfcf043ac), SN4(0x07641af0), SN4(0xf89be510), SN4(0x030fbc54) },
     96 	{ SN4(0xfa57d868), SN4(0x05a82798), SN4(0x05a82798), SN4(0xfa57d868) },
     97 	{ SN4(0xf89be510), SN4(0xfcf043ac), SN4(0x030fbc54), SN4(0x07641af0) },
     98 	{ SN4(0xf8000000), SN4(0xf8000000), SN4(0xf8000000), SN4(0xf8000000) },
     99 	{ SN4(0xf89be510), SN4(0xfcf043ac), SN4(0x030fbc54), SN4(0x07641af0) }
    100 };
    101 
    102 static const int32_t synmatrix8[16][8] = {
    103 	{ SN8(0x05a82798), SN8(0xfa57d868), SN8(0xfa57d868), SN8(0x05a82798),
    104 	  SN8(0x05a82798), SN8(0xfa57d868), SN8(0xfa57d868), SN8(0x05a82798) },
    105 	{ SN8(0x0471ced0), SN8(0xf8275a10), SN8(0x018f8b84), SN8(0x06a6d988),
    106 	  SN8(0xf9592678), SN8(0xfe70747c), SN8(0x07d8a5f0), SN8(0xfb8e3130) },
    107 	{ SN8(0x030fbc54), SN8(0xf89be510), SN8(0x07641af0), SN8(0xfcf043ac),
    108 	  SN8(0xfcf043ac), SN8(0x07641af0), SN8(0xf89be510), SN8(0x030fbc54) },
    109 	{ SN8(0x018f8b84), SN8(0xfb8e3130), SN8(0x06a6d988), SN8(0xf8275a10),
    110 	  SN8(0x07d8a5f0), SN8(0xf9592678), SN8(0x0471ced0), SN8(0xfe70747c) },
    111 	{ SN8(0x00000000), SN8(0x00000000), SN8(0x00000000), SN8(0x00000000),
    112 	  SN8(0x00000000), SN8(0x00000000), SN8(0x00000000), SN8(0x00000000) },
    113 	{ SN8(0xfe70747c), SN8(0x0471ced0), SN8(0xf9592678), SN8(0x07d8a5f0),
    114 	  SN8(0xf8275a10), SN8(0x06a6d988), SN8(0xfb8e3130), SN8(0x018f8b84) },
    115 	{ SN8(0xfcf043ac), SN8(0x07641af0), SN8(0xf89be510), SN8(0x030fbc54),
    116 	  SN8(0x030fbc54), SN8(0xf89be510), SN8(0x07641af0), SN8(0xfcf043ac) },
    117 	{ SN8(0xfb8e3130), SN8(0x07d8a5f0), SN8(0xfe70747c), SN8(0xf9592678),
    118 	  SN8(0x06a6d988), SN8(0x018f8b84), SN8(0xf8275a10), SN8(0x0471ced0) },
    119 	{ SN8(0xfa57d868), SN8(0x05a82798), SN8(0x05a82798), SN8(0xfa57d868),
    120 	  SN8(0xfa57d868), SN8(0x05a82798), SN8(0x05a82798), SN8(0xfa57d868) },
    121 	{ SN8(0xf9592678), SN8(0x018f8b84), SN8(0x07d8a5f0), SN8(0x0471ced0),
    122 	  SN8(0xfb8e3130), SN8(0xf8275a10), SN8(0xfe70747c), SN8(0x06a6d988) },
    123 	{ SN8(0xf89be510), SN8(0xfcf043ac), SN8(0x030fbc54), SN8(0x07641af0),
    124 	  SN8(0x07641af0), SN8(0x030fbc54), SN8(0xfcf043ac), SN8(0xf89be510) },
    125 	{ SN8(0xf8275a10), SN8(0xf9592678), SN8(0xfb8e3130), SN8(0xfe70747c),
    126 	  SN8(0x018f8b84), SN8(0x0471ced0), SN8(0x06a6d988), SN8(0x07d8a5f0) },
    127 	{ SN8(0xf8000000), SN8(0xf8000000), SN8(0xf8000000), SN8(0xf8000000),
    128 	  SN8(0xf8000000), SN8(0xf8000000), SN8(0xf8000000), SN8(0xf8000000) },
    129 	{ SN8(0xf8275a10), SN8(0xf9592678), SN8(0xfb8e3130), SN8(0xfe70747c),
    130 	  SN8(0x018f8b84), SN8(0x0471ced0), SN8(0x06a6d988), SN8(0x07d8a5f0) },
    131 	{ SN8(0xf89be510), SN8(0xfcf043ac), SN8(0x030fbc54), SN8(0x07641af0),
    132 	  SN8(0x07641af0), SN8(0x030fbc54), SN8(0xfcf043ac), SN8(0xf89be510) },
    133 	{ SN8(0xf9592678), SN8(0x018f8b84), SN8(0x07d8a5f0), SN8(0x0471ced0),
    134 	  SN8(0xfb8e3130), SN8(0xf8275a10), SN8(0xfe70747c), SN8(0x06a6d988) }
    135 };
    136 
    137 /* Uncomment the following line to enable high precision build of SBC encoder */
    138 
    139 /* #define SBC_HIGH_PRECISION */
    140 
    141 #ifdef SBC_HIGH_PRECISION
    142 #define FIXED_A int64_t /* data type for fixed point accumulator */
    143 #define FIXED_T int32_t /* data type for fixed point constants */
    144 #define SBC_FIXED_EXTRA_BITS 16
    145 #else
    146 #define FIXED_A int32_t /* data type for fixed point accumulator */
    147 #define FIXED_T int16_t /* data type for fixed point constants */
    148 #define SBC_FIXED_EXTRA_BITS 0
    149 #endif
    150 
    151 /* A2DP specification: Section 12.8 Tables
    152  *
    153  * Original values are premultiplied by 2 for better precision (that is the
    154  * maximum which is possible without overflows)
    155  *
    156  * Note: in each block of 8 numbers sign was changed for elements 2 and 7
    157  * in order to compensate the same change applied to cos_table_fixed_4
    158  */
    159 #define SBC_PROTO_FIXED4_SCALE \
    160 	((sizeof(FIXED_T) * CHAR_BIT - 1) - SBC_FIXED_EXTRA_BITS + 1)
    161 #define F_PROTO4(x) (FIXED_A) ((x * 2) * \
    162 	((FIXED_A) 1 << (sizeof(FIXED_T) * CHAR_BIT - 1)) + 0.5)
    163 #define F(x) F_PROTO4(x)
    164 static const FIXED_T _sbc_proto_fixed4[40] = {
    165 	F(0.00000000E+00),  F(5.36548976E-04),
    166 	-F(1.49188357E-03),  F(2.73370904E-03),
    167 	F(3.83720193E-03),  F(3.89205149E-03),
    168 	F(1.86581691E-03),  F(3.06012286E-03),
    169 
    170 	F(1.09137620E-02),  F(2.04385087E-02),
    171 	-F(2.88757392E-02),  F(3.21939290E-02),
    172 	F(2.58767811E-02),  F(6.13245186E-03),
    173 	-F(2.88217274E-02),  F(7.76463494E-02),
    174 
    175 	F(1.35593274E-01),  F(1.94987841E-01),
    176 	-F(2.46636662E-01),  F(2.81828203E-01),
    177 	F(2.94315332E-01),  F(2.81828203E-01),
    178 	F(2.46636662E-01), -F(1.94987841E-01),
    179 
    180 	-F(1.35593274E-01), -F(7.76463494E-02),
    181 	F(2.88217274E-02),  F(6.13245186E-03),
    182 	F(2.58767811E-02),  F(3.21939290E-02),
    183 	F(2.88757392E-02), -F(2.04385087E-02),
    184 
    185 	-F(1.09137620E-02), -F(3.06012286E-03),
    186 	-F(1.86581691E-03),  F(3.89205149E-03),
    187 	F(3.83720193E-03),  F(2.73370904E-03),
    188 	F(1.49188357E-03), -F(5.36548976E-04),
    189 };
    190 #undef F
    191 
    192 /*
    193  * To produce this cosine matrix in Octave:
    194  *
    195  * b = zeros(4, 8);
    196  * for i = 0:3
    197  * for j = 0:7 b(i+1, j+1) = cos((i + 0.5) * (j - 2) * (pi/4))
    198  * endfor
    199  * endfor;
    200  * printf("%.10f, ", b');
    201  *
    202  * Note: in each block of 8 numbers sign was changed for elements 2 and 7
    203  *
    204  * Change of sign for element 2 allows to replace constant 1.0 (not
    205  * representable in Q15 format) with -1.0 (fine with Q15).
    206  * Changed sign for element 7 allows to have more similar constants
    207  * and simplify subband filter function code.
    208  */
    209 #define SBC_COS_TABLE_FIXED4_SCALE \
    210 	((sizeof(FIXED_T) * CHAR_BIT - 1) + SBC_FIXED_EXTRA_BITS)
    211 #define F_COS4(x) (FIXED_A) ((x) * \
    212 	((FIXED_A) 1 << (sizeof(FIXED_T) * CHAR_BIT - 1)) + 0.5)
    213 #define F(x) F_COS4(x)
    214 static const FIXED_T cos_table_fixed_4[32] = {
    215 	F(0.7071067812),  F(0.9238795325), -F(1.0000000000),  F(0.9238795325),
    216 	F(0.7071067812),  F(0.3826834324),  F(0.0000000000),  F(0.3826834324),
    217 
    218 	-F(0.7071067812),  F(0.3826834324), -F(1.0000000000),  F(0.3826834324),
    219 	-F(0.7071067812), -F(0.9238795325), -F(0.0000000000), -F(0.9238795325),
    220 
    221 	-F(0.7071067812), -F(0.3826834324), -F(1.0000000000), -F(0.3826834324),
    222 	-F(0.7071067812),  F(0.9238795325),  F(0.0000000000),  F(0.9238795325),
    223 
    224 	F(0.7071067812), -F(0.9238795325), -F(1.0000000000), -F(0.9238795325),
    225 	F(0.7071067812), -F(0.3826834324), -F(0.0000000000), -F(0.3826834324),
    226 };
    227 #undef F
    228 
    229 /* A2DP specification: Section 12.8 Tables
    230  *
    231  * Original values are premultiplied by 4 for better precision (that is the
    232  * maximum which is possible without overflows)
    233  *
    234  * Note: in each block of 16 numbers sign was changed for elements 4, 13, 14, 15
    235  * in order to compensate the same change applied to cos_table_fixed_8
    236  */
    237 #define SBC_PROTO_FIXED8_SCALE \
    238 	((sizeof(FIXED_T) * CHAR_BIT - 1) - SBC_FIXED_EXTRA_BITS + 1)
    239 #define F_PROTO8(x) (FIXED_A) ((x * 2) * \
    240 	((FIXED_A) 1 << (sizeof(FIXED_T) * CHAR_BIT - 1)) + 0.5)
    241 #define F(x) F_PROTO8(x)
    242 static const FIXED_T _sbc_proto_fixed8[80] = {
    243 	F(0.00000000E+00),  F(1.56575398E-04),
    244 	F(3.43256425E-04),  F(5.54620202E-04),
    245 	-F(8.23919506E-04),  F(1.13992507E-03),
    246 	F(1.47640169E-03),  F(1.78371725E-03),
    247 	F(2.01182542E-03),  F(2.10371989E-03),
    248 	F(1.99454554E-03),  F(1.61656283E-03),
    249 	F(9.02154502E-04),  F(1.78805361E-04),
    250 	F(1.64973098E-03),  F(3.49717454E-03),
    251 
    252 	F(5.65949473E-03),  F(8.02941163E-03),
    253 	F(1.04584443E-02),  F(1.27472335E-02),
    254 	-F(1.46525263E-02),  F(1.59045603E-02),
    255 	F(1.62208471E-02),  F(1.53184106E-02),
    256 	F(1.29371806E-02),  F(8.85757540E-03),
    257 	F(2.92408442E-03), -F(4.91578024E-03),
    258 	-F(1.46404076E-02),  F(2.61098752E-02),
    259 	F(3.90751381E-02),  F(5.31873032E-02),
    260 
    261 	F(6.79989431E-02),  F(8.29847578E-02),
    262 	F(9.75753918E-02),  F(1.11196689E-01),
    263 	-F(1.23264548E-01),  F(1.33264415E-01),
    264 	F(1.40753505E-01),  F(1.45389847E-01),
    265 	F(1.46955068E-01),  F(1.45389847E-01),
    266 	F(1.40753505E-01),  F(1.33264415E-01),
    267 	F(1.23264548E-01), -F(1.11196689E-01),
    268 	-F(9.75753918E-02), -F(8.29847578E-02),
    269 
    270 	-F(6.79989431E-02), -F(5.31873032E-02),
    271 	-F(3.90751381E-02), -F(2.61098752E-02),
    272 	F(1.46404076E-02), -F(4.91578024E-03),
    273 	F(2.92408442E-03),  F(8.85757540E-03),
    274 	F(1.29371806E-02),  F(1.53184106E-02),
    275 	F(1.62208471E-02),  F(1.59045603E-02),
    276 	F(1.46525263E-02), -F(1.27472335E-02),
    277 	-F(1.04584443E-02), -F(8.02941163E-03),
    278 
    279 	-F(5.65949473E-03), -F(3.49717454E-03),
    280 	-F(1.64973098E-03), -F(1.78805361E-04),
    281 	-F(9.02154502E-04),  F(1.61656283E-03),
    282 	F(1.99454554E-03),  F(2.10371989E-03),
    283 	F(2.01182542E-03),  F(1.78371725E-03),
    284 	F(1.47640169E-03),  F(1.13992507E-03),
    285 	F(8.23919506E-04), -F(5.54620202E-04),
    286 	-F(3.43256425E-04), -F(1.56575398E-04),
    287 };
    288 #undef F
    289 
    290 /*
    291  * To produce this cosine matrix in Octave:
    292  *
    293  * b = zeros(8, 16);
    294  * for i = 0:7
    295  * for j = 0:15 b(i+1, j+1) = cos((i + 0.5) * (j - 4) * (pi/8))
    296  * endfor endfor;
    297  * printf("%.10f, ", b');
    298  *
    299  * Note: in each block of 16 numbers sign was changed for elements 4, 13, 14, 15
    300  *
    301  * Change of sign for element 4 allows to replace constant 1.0 (not
    302  * representable in Q15 format) with -1.0 (fine with Q15).
    303  * Changed signs for elements 13, 14, 15 allow to have more similar constants
    304  * and simplify subband filter function code.
    305  */
    306 #define SBC_COS_TABLE_FIXED8_SCALE \
    307 	((sizeof(FIXED_T) * CHAR_BIT - 1) + SBC_FIXED_EXTRA_BITS)
    308 #define F_COS8(x) (FIXED_A) ((x) * \
    309 	((FIXED_A) 1 << (sizeof(FIXED_T) * CHAR_BIT - 1)) + 0.5)
    310 #define F(x) F_COS8(x)
    311 static const FIXED_T cos_table_fixed_8[128] = {
    312 	F(0.7071067812),  F(0.8314696123),  F(0.9238795325),  F(0.9807852804),
    313 	-F(1.0000000000),  F(0.9807852804),  F(0.9238795325),  F(0.8314696123),
    314 	F(0.7071067812),  F(0.5555702330),  F(0.3826834324),  F(0.1950903220),
    315 	F(0.0000000000),  F(0.1950903220),  F(0.3826834324),  F(0.5555702330),
    316 
    317 	-F(0.7071067812), -F(0.1950903220),  F(0.3826834324),  F(0.8314696123),
    318 	-F(1.0000000000),  F(0.8314696123),  F(0.3826834324), -F(0.1950903220),
    319 	-F(0.7071067812), -F(0.9807852804), -F(0.9238795325), -F(0.5555702330),
    320 	-F(0.0000000000), -F(0.5555702330), -F(0.9238795325), -F(0.9807852804),
    321 
    322 	-F(0.7071067812), -F(0.9807852804), -F(0.3826834324),  F(0.5555702330),
    323 	-F(1.0000000000),  F(0.5555702330), -F(0.3826834324), -F(0.9807852804),
    324 	-F(0.7071067812),  F(0.1950903220),  F(0.9238795325),  F(0.8314696123),
    325 	F(0.0000000000),  F(0.8314696123),  F(0.9238795325),  F(0.1950903220),
    326 
    327 	F(0.7071067812), -F(0.5555702330), -F(0.9238795325),  F(0.1950903220),
    328 	-F(1.0000000000),  F(0.1950903220), -F(0.9238795325), -F(0.5555702330),
    329 	F(0.7071067812),  F(0.8314696123), -F(0.3826834324), -F(0.9807852804),
    330 	-F(0.0000000000), -F(0.9807852804), -F(0.3826834324),  F(0.8314696123),
    331 
    332 	F(0.7071067812),  F(0.5555702330), -F(0.9238795325), -F(0.1950903220),
    333 	-F(1.0000000000), -F(0.1950903220), -F(0.9238795325),  F(0.5555702330),
    334 	F(0.7071067812), -F(0.8314696123), -F(0.3826834324),  F(0.9807852804),
    335 	F(0.0000000000),  F(0.9807852804), -F(0.3826834324), -F(0.8314696123),
    336 
    337 	-F(0.7071067812),  F(0.9807852804), -F(0.3826834324), -F(0.5555702330),
    338 	-F(1.0000000000), -F(0.5555702330), -F(0.3826834324),  F(0.9807852804),
    339 	-F(0.7071067812), -F(0.1950903220),  F(0.9238795325), -F(0.8314696123),
    340 	-F(0.0000000000), -F(0.8314696123),  F(0.9238795325), -F(0.1950903220),
    341 
    342 	-F(0.7071067812),  F(0.1950903220),  F(0.3826834324), -F(0.8314696123),
    343 	-F(1.0000000000), -F(0.8314696123),  F(0.3826834324),  F(0.1950903220),
    344 	-F(0.7071067812),  F(0.9807852804), -F(0.9238795325),  F(0.5555702330),
    345 	-F(0.0000000000),  F(0.5555702330), -F(0.9238795325),  F(0.9807852804),
    346 
    347 	F(0.7071067812), -F(0.8314696123),  F(0.9238795325), -F(0.9807852804),
    348 	-F(1.0000000000), -F(0.9807852804),  F(0.9238795325), -F(0.8314696123),
    349 	F(0.7071067812), -F(0.5555702330),  F(0.3826834324), -F(0.1950903220),
    350 	-F(0.0000000000), -F(0.1950903220),  F(0.3826834324), -F(0.5555702330),
    351 };
    352 #undef F
    353 
    354 /*
    355  * Enforce 16 byte alignment for the data, which is supposed to be used
    356  * with SIMD optimized code.
    357  */
    358 
    359 #define SBC_ALIGN_BITS 4
    360 #define SBC_ALIGN_MASK ((1 << (SBC_ALIGN_BITS)) - 1)
    361 
    362 #ifdef __GNUC__
    363 #define SBC_ALIGNED __attribute__((aligned(1 << (SBC_ALIGN_BITS))))
    364 #else
    365 #define SBC_ALIGNED
    366 #endif
    367 
    368 /*
    369  * Constant tables for the use in SIMD optimized analysis filters
    370  * Each table consists of two parts:
    371  * 1. reordered "proto" table
    372  * 2. reordered "cos" table
    373  *
    374  * Due to non-symmetrical reordering, separate tables for "even"
    375  * and "odd" cases are needed
    376  */
    377 
    378 static const FIXED_T SBC_ALIGNED analysis_consts_fixed4_simd_even[40 + 16] = {
    379 #define C0 1.0932568993
    380 #define C1 1.3056875580
    381 #define C2 1.3056875580
    382 #define C3 1.6772280856
    383 
    384 #define F(x) F_PROTO4(x)
    385 	 F(0.00000000E+00 * C0),  F(3.83720193E-03 * C0),
    386 	 F(5.36548976E-04 * C1),  F(2.73370904E-03 * C1),
    387 	 F(3.06012286E-03 * C2),  F(3.89205149E-03 * C2),
    388 	 F(0.00000000E+00 * C3), -F(1.49188357E-03 * C3),
    389 	 F(1.09137620E-02 * C0),  F(2.58767811E-02 * C0),
    390 	 F(2.04385087E-02 * C1),  F(3.21939290E-02 * C1),
    391 	 F(7.76463494E-02 * C2),  F(6.13245186E-03 * C2),
    392 	 F(0.00000000E+00 * C3), -F(2.88757392E-02 * C3),
    393 	 F(1.35593274E-01 * C0),  F(2.94315332E-01 * C0),
    394 	 F(1.94987841E-01 * C1),  F(2.81828203E-01 * C1),
    395 	-F(1.94987841E-01 * C2),  F(2.81828203E-01 * C2),
    396 	 F(0.00000000E+00 * C3), -F(2.46636662E-01 * C3),
    397 	-F(1.35593274E-01 * C0),  F(2.58767811E-02 * C0),
    398 	-F(7.76463494E-02 * C1),  F(6.13245186E-03 * C1),
    399 	-F(2.04385087E-02 * C2),  F(3.21939290E-02 * C2),
    400 	 F(0.00000000E+00 * C3),  F(2.88217274E-02 * C3),
    401 	-F(1.09137620E-02 * C0),  F(3.83720193E-03 * C0),
    402 	-F(3.06012286E-03 * C1),  F(3.89205149E-03 * C1),
    403 	-F(5.36548976E-04 * C2),  F(2.73370904E-03 * C2),
    404 	 F(0.00000000E+00 * C3), -F(1.86581691E-03 * C3),
    405 #undef F
    406 #define F(x) F_COS4(x)
    407 	 F(0.7071067812 / C0),  F(0.9238795325 / C1),
    408 	-F(0.7071067812 / C0),  F(0.3826834324 / C1),
    409 	-F(0.7071067812 / C0), -F(0.3826834324 / C1),
    410 	 F(0.7071067812 / C0), -F(0.9238795325 / C1),
    411 	 F(0.3826834324 / C2), -F(1.0000000000 / C3),
    412 	-F(0.9238795325 / C2), -F(1.0000000000 / C3),
    413 	 F(0.9238795325 / C2), -F(1.0000000000 / C3),
    414 	-F(0.3826834324 / C2), -F(1.0000000000 / C3),
    415 #undef F
    416 
    417 #undef C0
    418 #undef C1
    419 #undef C2
    420 #undef C3
    421 };
    422 
    423 static const FIXED_T SBC_ALIGNED analysis_consts_fixed4_simd_odd[40 + 16] = {
    424 #define C0 1.3056875580
    425 #define C1 1.6772280856
    426 #define C2 1.0932568993
    427 #define C3 1.3056875580
    428 
    429 #define F(x) F_PROTO4(x)
    430 	 F(2.73370904E-03 * C0),  F(5.36548976E-04 * C0),
    431 	-F(1.49188357E-03 * C1),  F(0.00000000E+00 * C1),
    432 	 F(3.83720193E-03 * C2),  F(1.09137620E-02 * C2),
    433 	 F(3.89205149E-03 * C3),  F(3.06012286E-03 * C3),
    434 	 F(3.21939290E-02 * C0),  F(2.04385087E-02 * C0),
    435 	-F(2.88757392E-02 * C1),  F(0.00000000E+00 * C1),
    436 	 F(2.58767811E-02 * C2),  F(1.35593274E-01 * C2),
    437 	 F(6.13245186E-03 * C3),  F(7.76463494E-02 * C3),
    438 	 F(2.81828203E-01 * C0),  F(1.94987841E-01 * C0),
    439 	-F(2.46636662E-01 * C1),  F(0.00000000E+00 * C1),
    440 	 F(2.94315332E-01 * C2), -F(1.35593274E-01 * C2),
    441 	 F(2.81828203E-01 * C3), -F(1.94987841E-01 * C3),
    442 	 F(6.13245186E-03 * C0), -F(7.76463494E-02 * C0),
    443 	 F(2.88217274E-02 * C1),  F(0.00000000E+00 * C1),
    444 	 F(2.58767811E-02 * C2), -F(1.09137620E-02 * C2),
    445 	 F(3.21939290E-02 * C3), -F(2.04385087E-02 * C3),
    446 	 F(3.89205149E-03 * C0), -F(3.06012286E-03 * C0),
    447 	-F(1.86581691E-03 * C1),  F(0.00000000E+00 * C1),
    448 	 F(3.83720193E-03 * C2),  F(0.00000000E+00 * C2),
    449 	 F(2.73370904E-03 * C3), -F(5.36548976E-04 * C3),
    450 #undef F
    451 #define F(x) F_COS4(x)
    452 	 F(0.9238795325 / C0), -F(1.0000000000 / C1),
    453 	 F(0.3826834324 / C0), -F(1.0000000000 / C1),
    454 	-F(0.3826834324 / C0), -F(1.0000000000 / C1),
    455 	-F(0.9238795325 / C0), -F(1.0000000000 / C1),
    456 	 F(0.7071067812 / C2),  F(0.3826834324 / C3),
    457 	-F(0.7071067812 / C2), -F(0.9238795325 / C3),
    458 	-F(0.7071067812 / C2),  F(0.9238795325 / C3),
    459 	 F(0.7071067812 / C2), -F(0.3826834324 / C3),
    460 #undef F
    461 
    462 #undef C0
    463 #undef C1
    464 #undef C2
    465 #undef C3
    466 };
    467 
    468 static const FIXED_T SBC_ALIGNED analysis_consts_fixed8_simd_even[80 + 64] = {
    469 #define C0 2.7906148894
    470 #define C1 2.4270044280
    471 #define C2 2.8015616024
    472 #define C3 3.1710363741
    473 #define C4 2.5377944043
    474 #define C5 2.4270044280
    475 #define C6 2.8015616024
    476 #define C7 3.1710363741
    477 
    478 #define F(x) F_PROTO8(x)
    479 	 F(0.00000000E+00 * C0),  F(2.01182542E-03 * C0),
    480 	 F(1.56575398E-04 * C1),  F(1.78371725E-03 * C1),
    481 	 F(3.43256425E-04 * C2),  F(1.47640169E-03 * C2),
    482 	 F(5.54620202E-04 * C3),  F(1.13992507E-03 * C3),
    483 	-F(8.23919506E-04 * C4),  F(0.00000000E+00 * C4),
    484 	 F(2.10371989E-03 * C5),  F(3.49717454E-03 * C5),
    485 	 F(1.99454554E-03 * C6),  F(1.64973098E-03 * C6),
    486 	 F(1.61656283E-03 * C7),  F(1.78805361E-04 * C7),
    487 	 F(5.65949473E-03 * C0),  F(1.29371806E-02 * C0),
    488 	 F(8.02941163E-03 * C1),  F(1.53184106E-02 * C1),
    489 	 F(1.04584443E-02 * C2),  F(1.62208471E-02 * C2),
    490 	 F(1.27472335E-02 * C3),  F(1.59045603E-02 * C3),
    491 	-F(1.46525263E-02 * C4),  F(0.00000000E+00 * C4),
    492 	 F(8.85757540E-03 * C5),  F(5.31873032E-02 * C5),
    493 	 F(2.92408442E-03 * C6),  F(3.90751381E-02 * C6),
    494 	-F(4.91578024E-03 * C7),  F(2.61098752E-02 * C7),
    495 	 F(6.79989431E-02 * C0),  F(1.46955068E-01 * C0),
    496 	 F(8.29847578E-02 * C1),  F(1.45389847E-01 * C1),
    497 	 F(9.75753918E-02 * C2),  F(1.40753505E-01 * C2),
    498 	 F(1.11196689E-01 * C3),  F(1.33264415E-01 * C3),
    499 	-F(1.23264548E-01 * C4),  F(0.00000000E+00 * C4),
    500 	 F(1.45389847E-01 * C5), -F(8.29847578E-02 * C5),
    501 	 F(1.40753505E-01 * C6), -F(9.75753918E-02 * C6),
    502 	 F(1.33264415E-01 * C7), -F(1.11196689E-01 * C7),
    503 	-F(6.79989431E-02 * C0),  F(1.29371806E-02 * C0),
    504 	-F(5.31873032E-02 * C1),  F(8.85757540E-03 * C1),
    505 	-F(3.90751381E-02 * C2),  F(2.92408442E-03 * C2),
    506 	-F(2.61098752E-02 * C3), -F(4.91578024E-03 * C3),
    507 	 F(1.46404076E-02 * C4),  F(0.00000000E+00 * C4),
    508 	 F(1.53184106E-02 * C5), -F(8.02941163E-03 * C5),
    509 	 F(1.62208471E-02 * C6), -F(1.04584443E-02 * C6),
    510 	 F(1.59045603E-02 * C7), -F(1.27472335E-02 * C7),
    511 	-F(5.65949473E-03 * C0),  F(2.01182542E-03 * C0),
    512 	-F(3.49717454E-03 * C1),  F(2.10371989E-03 * C1),
    513 	-F(1.64973098E-03 * C2),  F(1.99454554E-03 * C2),
    514 	-F(1.78805361E-04 * C3),  F(1.61656283E-03 * C3),
    515 	-F(9.02154502E-04 * C4),  F(0.00000000E+00 * C4),
    516 	 F(1.78371725E-03 * C5), -F(1.56575398E-04 * C5),
    517 	 F(1.47640169E-03 * C6), -F(3.43256425E-04 * C6),
    518 	 F(1.13992507E-03 * C7), -F(5.54620202E-04 * C7),
    519 #undef F
    520 #define F(x) F_COS8(x)
    521 	 F(0.7071067812 / C0),  F(0.8314696123 / C1),
    522 	-F(0.7071067812 / C0), -F(0.1950903220 / C1),
    523 	-F(0.7071067812 / C0), -F(0.9807852804 / C1),
    524 	 F(0.7071067812 / C0), -F(0.5555702330 / C1),
    525 	 F(0.7071067812 / C0),  F(0.5555702330 / C1),
    526 	-F(0.7071067812 / C0),  F(0.9807852804 / C1),
    527 	-F(0.7071067812 / C0),  F(0.1950903220 / C1),
    528 	 F(0.7071067812 / C0), -F(0.8314696123 / C1),
    529 	 F(0.9238795325 / C2),  F(0.9807852804 / C3),
    530 	 F(0.3826834324 / C2),  F(0.8314696123 / C3),
    531 	-F(0.3826834324 / C2),  F(0.5555702330 / C3),
    532 	-F(0.9238795325 / C2),  F(0.1950903220 / C3),
    533 	-F(0.9238795325 / C2), -F(0.1950903220 / C3),
    534 	-F(0.3826834324 / C2), -F(0.5555702330 / C3),
    535 	 F(0.3826834324 / C2), -F(0.8314696123 / C3),
    536 	 F(0.9238795325 / C2), -F(0.9807852804 / C3),
    537 	-F(1.0000000000 / C4),  F(0.5555702330 / C5),
    538 	-F(1.0000000000 / C4), -F(0.9807852804 / C5),
    539 	-F(1.0000000000 / C4),  F(0.1950903220 / C5),
    540 	-F(1.0000000000 / C4),  F(0.8314696123 / C5),
    541 	-F(1.0000000000 / C4), -F(0.8314696123 / C5),
    542 	-F(1.0000000000 / C4), -F(0.1950903220 / C5),
    543 	-F(1.0000000000 / C4),  F(0.9807852804 / C5),
    544 	-F(1.0000000000 / C4), -F(0.5555702330 / C5),
    545 	 F(0.3826834324 / C6),  F(0.1950903220 / C7),
    546 	-F(0.9238795325 / C6), -F(0.5555702330 / C7),
    547 	 F(0.9238795325 / C6),  F(0.8314696123 / C7),
    548 	-F(0.3826834324 / C6), -F(0.9807852804 / C7),
    549 	-F(0.3826834324 / C6),  F(0.9807852804 / C7),
    550 	 F(0.9238795325 / C6), -F(0.8314696123 / C7),
    551 	-F(0.9238795325 / C6),  F(0.5555702330 / C7),
    552 	 F(0.3826834324 / C6), -F(0.1950903220 / C7),
    553 #undef F
    554 
    555 #undef C0
    556 #undef C1
    557 #undef C2
    558 #undef C3
    559 #undef C4
    560 #undef C5
    561 #undef C6
    562 #undef C7
    563 };
    564 
    565 static const FIXED_T SBC_ALIGNED analysis_consts_fixed8_simd_odd[80 + 64] = {
    566 #define C0 2.5377944043
    567 #define C1 2.4270044280
    568 #define C2 2.8015616024
    569 #define C3 3.1710363741
    570 #define C4 2.7906148894
    571 #define C5 2.4270044280
    572 #define C6 2.8015616024
    573 #define C7 3.1710363741
    574 
    575 #define F(x) F_PROTO8(x)
    576 	 F(0.00000000E+00 * C0), -F(8.23919506E-04 * C0),
    577 	 F(1.56575398E-04 * C1),  F(1.78371725E-03 * C1),
    578 	 F(3.43256425E-04 * C2),  F(1.47640169E-03 * C2),
    579 	 F(5.54620202E-04 * C3),  F(1.13992507E-03 * C3),
    580 	 F(2.01182542E-03 * C4),  F(5.65949473E-03 * C4),
    581 	 F(2.10371989E-03 * C5),  F(3.49717454E-03 * C5),
    582 	 F(1.99454554E-03 * C6),  F(1.64973098E-03 * C6),
    583 	 F(1.61656283E-03 * C7),  F(1.78805361E-04 * C7),
    584 	 F(0.00000000E+00 * C0), -F(1.46525263E-02 * C0),
    585 	 F(8.02941163E-03 * C1),  F(1.53184106E-02 * C1),
    586 	 F(1.04584443E-02 * C2),  F(1.62208471E-02 * C2),
    587 	 F(1.27472335E-02 * C3),  F(1.59045603E-02 * C3),
    588 	 F(1.29371806E-02 * C4),  F(6.79989431E-02 * C4),
    589 	 F(8.85757540E-03 * C5),  F(5.31873032E-02 * C5),
    590 	 F(2.92408442E-03 * C6),  F(3.90751381E-02 * C6),
    591 	-F(4.91578024E-03 * C7),  F(2.61098752E-02 * C7),
    592 	 F(0.00000000E+00 * C0), -F(1.23264548E-01 * C0),
    593 	 F(8.29847578E-02 * C1),  F(1.45389847E-01 * C1),
    594 	 F(9.75753918E-02 * C2),  F(1.40753505E-01 * C2),
    595 	 F(1.11196689E-01 * C3),  F(1.33264415E-01 * C3),
    596 	 F(1.46955068E-01 * C4), -F(6.79989431E-02 * C4),
    597 	 F(1.45389847E-01 * C5), -F(8.29847578E-02 * C5),
    598 	 F(1.40753505E-01 * C6), -F(9.75753918E-02 * C6),
    599 	 F(1.33264415E-01 * C7), -F(1.11196689E-01 * C7),
    600 	 F(0.00000000E+00 * C0),  F(1.46404076E-02 * C0),
    601 	-F(5.31873032E-02 * C1),  F(8.85757540E-03 * C1),
    602 	-F(3.90751381E-02 * C2),  F(2.92408442E-03 * C2),
    603 	-F(2.61098752E-02 * C3), -F(4.91578024E-03 * C3),
    604 	 F(1.29371806E-02 * C4), -F(5.65949473E-03 * C4),
    605 	 F(1.53184106E-02 * C5), -F(8.02941163E-03 * C5),
    606 	 F(1.62208471E-02 * C6), -F(1.04584443E-02 * C6),
    607 	 F(1.59045603E-02 * C7), -F(1.27472335E-02 * C7),
    608 	 F(0.00000000E+00 * C0), -F(9.02154502E-04 * C0),
    609 	-F(3.49717454E-03 * C1),  F(2.10371989E-03 * C1),
    610 	-F(1.64973098E-03 * C2),  F(1.99454554E-03 * C2),
    611 	-F(1.78805361E-04 * C3),  F(1.61656283E-03 * C3),
    612 	 F(2.01182542E-03 * C4),  F(0.00000000E+00 * C4),
    613 	 F(1.78371725E-03 * C5), -F(1.56575398E-04 * C5),
    614 	 F(1.47640169E-03 * C6), -F(3.43256425E-04 * C6),
    615 	 F(1.13992507E-03 * C7), -F(5.54620202E-04 * C7),
    616 #undef F
    617 #define F(x) F_COS8(x)
    618 	-F(1.0000000000 / C0),  F(0.8314696123 / C1),
    619 	-F(1.0000000000 / C0), -F(0.1950903220 / C1),
    620 	-F(1.0000000000 / C0), -F(0.9807852804 / C1),
    621 	-F(1.0000000000 / C0), -F(0.5555702330 / C1),
    622 	-F(1.0000000000 / C0),  F(0.5555702330 / C1),
    623 	-F(1.0000000000 / C0),  F(0.9807852804 / C1),
    624 	-F(1.0000000000 / C0),  F(0.1950903220 / C1),
    625 	-F(1.0000000000 / C0), -F(0.8314696123 / C1),
    626 	 F(0.9238795325 / C2),  F(0.9807852804 / C3),
    627 	 F(0.3826834324 / C2),  F(0.8314696123 / C3),
    628 	-F(0.3826834324 / C2),  F(0.5555702330 / C3),
    629 	-F(0.9238795325 / C2),  F(0.1950903220 / C3),
    630 	-F(0.9238795325 / C2), -F(0.1950903220 / C3),
    631 	-F(0.3826834324 / C2), -F(0.5555702330 / C3),
    632 	 F(0.3826834324 / C2), -F(0.8314696123 / C3),
    633 	 F(0.9238795325 / C2), -F(0.9807852804 / C3),
    634 	 F(0.7071067812 / C4),  F(0.5555702330 / C5),
    635 	-F(0.7071067812 / C4), -F(0.9807852804 / C5),
    636 	-F(0.7071067812 / C4),  F(0.1950903220 / C5),
    637 	 F(0.7071067812 / C4),  F(0.8314696123 / C5),
    638 	 F(0.7071067812 / C4), -F(0.8314696123 / C5),
    639 	-F(0.7071067812 / C4), -F(0.1950903220 / C5),
    640 	-F(0.7071067812 / C4),  F(0.9807852804 / C5),
    641 	 F(0.7071067812 / C4), -F(0.5555702330 / C5),
    642 	 F(0.3826834324 / C6),  F(0.1950903220 / C7),
    643 	-F(0.9238795325 / C6), -F(0.5555702330 / C7),
    644 	 F(0.9238795325 / C6),  F(0.8314696123 / C7),
    645 	-F(0.3826834324 / C6), -F(0.9807852804 / C7),
    646 	-F(0.3826834324 / C6),  F(0.9807852804 / C7),
    647 	 F(0.9238795325 / C6), -F(0.8314696123 / C7),
    648 	-F(0.9238795325 / C6),  F(0.5555702330 / C7),
    649 	 F(0.3826834324 / C6), -F(0.1950903220 / C7),
    650 #undef F
    651 
    652 #undef C0
    653 #undef C1
    654 #undef C2
    655 #undef C3
    656 #undef C4
    657 #undef C5
    658 #undef C6
    659 #undef C7
    660 };
    661