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