configure: bump to 1.2rc3
[speexdsp.git] / tmv / filterbank_tm.h
1 /* Copyright (C) 2007 Hong Zhiqian */\r
2 /**\r
3    @file filterbank_tm.h\r
4    @author Hong Zhiqian\r
5    @brief Various compatibility routines for Speex (TriMedia version)\r
6 */\r
7 /*\r
8    Redistribution and use in source and binary forms, with or without\r
9    modification, are permitted provided that the following conditions\r
10    are met:\r
11    \r
12    - Redistributions of source code must retain the above copyright\r
13    notice, this list of conditions and the following disclaimer.\r
14    \r
15    - Redistributions in binary form must reproduce the above copyright\r
16    notice, this list of conditions and the following disclaimer in the\r
17    documentation and/or other materials provided with the distribution.\r
18    \r
19    - Neither the name of the Xiph.org Foundation nor the names of its\r
20    contributors may be used to endorse or promote products derived from\r
21    this software without specific prior written permission.\r
22    \r
23    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
24    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
25    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
26    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\r
27    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
28    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r
29    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\r
30    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
31    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
32    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
33    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
34 */\r
35 #include <ops/custom_defs.h>\r
36 #include "profile_tm.h"\r
37 \r
38 #ifdef FIXED_POINT\r
39 \r
40 #define OVERRIDE_FILTERBANK_COMPUTE_BANK32\r
41 void filterbank_compute_bank32(FilterBank * restrict bank, spx_word32_t * restrict ps, spx_word32_t * restrict mel)\r
42 {\r
43         register int i, j, k, banks, len, zero, s;\r
44         register int * restrict left;\r
45         register int * restrict right; \r
46         register int * restrict bleft;\r
47         register int * restrict bright;\r
48 \r
49         left = (int*)bank->filter_left;\r
50         right = (int*)bank->filter_right;\r
51         bleft = (int*)bank->bank_left;\r
52         bright = (int*)bank->bank_right;\r
53 \r
54         TMDEBUG_ALIGNMEM(ps);\r
55         TMDEBUG_ALIGNMEM(mel);\r
56         TMDEBUG_ALIGNMEM(left);\r
57         TMDEBUG_ALIGNMEM(right);\r
58         TMDEBUG_ALIGNMEM(bleft);\r
59         TMDEBUG_ALIGNMEM(bright);\r
60 \r
61         FILTERBANKCOMPUTEBANK32_START();\r
62 \r
63         banks = bank->nb_banks << 2;\r
64         zero = 0;\r
65         len = bank->len;\r
66         s = (1<<((15))>>1);\r
67 \r
68 #if (TM_UNROLL && TM_UNROLL_FILTERBANKCOMPUTEBANK32)\r
69 #pragma TCS_unroll=2\r
70 #pragma TCS_unrollexact=1\r
71 #endif\r
72         for ( i=0 ; i<banks ; i+=4 )\r
73         {       st32d(i, mel, zero);\r
74         }\r
75 #if (TM_UNROLL && TM_UNROLL_FILTERBANKCOMPUTEBANK32)\r
76 #pragma TCS_unrollexact=0\r
77 #pragma TCS_unroll=0\r
78 #endif\r
79 \r
80 #if (TM_UNROLL && TM_UNROLL_FILTERBANKCOMPUTEBANK32)\r
81 #pragma TCS_unroll=2\r
82 #pragma TCS_unrollexact=1\r
83 #endif\r
84    for ( i=0,j=1,k=0 ; i<len ; i+=2,j+=2,++k )\r
85    {    register int ps1, ps0, _mel, ps0_msb, ps0_lsb, ps1_msb, ps1_lsb; \r
86                 register int left10, right10, left1, left0, right1, right0;\r
87                 register int il1, ir1, il0, ir0;\r
88 \r
89                 ps0             = ld32x(ps,i);\r
90                 il0             = ld32x(bleft,i);\r
91                 _mel    = ld32x(mel,il0);\r
92                 left10  = ld32x(left,k);                \r
93                 ir0             = ld32x(bright,i);\r
94                 right10 = ld32x(right,k);\r
95 \r
96                 ps0_msb = ps0 >> 15;\r
97                 ps0_lsb = ps0 & 0x00007fff;\r
98                 left0   = sex16(left10);\r
99                 right0  = sex16(right10);\r
100 \r
101                 _mel    += left0 * ps0_msb + ((left0 * ps0_lsb + s ) >> 15);\r
102                 mel[il0]= _mel;\r
103                 _mel    = ld32x(mel,ir0);\r
104                 _mel    += right0 * ps0_msb + ((right0 * ps0_lsb + s ) >> 15);\r
105                 mel[ir0]= _mel;\r
106 \r
107                 ps1             = ld32x(ps,j);\r
108                 il1             = ld32x(bleft,j);\r
109                 _mel    = ld32x(mel,il1);\r
110                 ir1             = ld32x(bright,j);\r
111 \r
112                 left1   = asri(16,left10);\r
113                 right1  = asri(16,right10);\r
114                 ps1_msb = ps1 >> 15;\r
115                 ps1_lsb = ps1 & 0x00007fff;\r
116 \r
117                 _mel    += left1 * ps1_msb + ((left1 * ps1_lsb + s ) >> 15);\r
118                 mel[il1]= _mel;\r
119                 _mel    = ld32x(mel,ir1);\r
120                 _mel    += right1 * ps1_msb + ((right1 * ps1_lsb + s ) >> 15);\r
121                 mel[ir1]= _mel;\r
122    }\r
123 #if (TM_UNROLL && TM_UNROLL_FILTERBANKCOMPUTEBANK32)\r
124 #pragma TCS_unrollexact=0\r
125 #pragma TCS_unroll=0\r
126 #endif\r
127 \r
128    FILTERBANKCOMPUTEBANK32_STOP();\r
129 }\r
130 \r
131 #define OVERRIDE_FILTERBANK_COMPUTE_PSD16\r
132 void filterbank_compute_psd16(FilterBank * restrict bank, spx_word16_t * restrict mel, spx_word16_t * restrict ps)\r
133 {\r
134         register int i, j, k, len, s;\r
135         register int * restrict left;\r
136         register int * restrict right; \r
137         register int * restrict bleft;\r
138         register int * restrict bright;\r
139 \r
140         left = (int*)bank->filter_left;\r
141         right = (int*)bank->filter_right;\r
142         bleft = (int*)bank->bank_left;\r
143         bright = (int*)bank->bank_right;\r
144 \r
145         TMDEBUG_ALIGNMEM(ps);\r
146         TMDEBUG_ALIGNMEM(mel);\r
147         TMDEBUG_ALIGNMEM(left);\r
148         TMDEBUG_ALIGNMEM(right);\r
149         TMDEBUG_ALIGNMEM(bleft);\r
150         TMDEBUG_ALIGNMEM(bright);\r
151 \r
152         FILTERBANKCOMPUTEPSD16_START();\r
153 \r
154         len = bank->len;\r
155         s = (1<<((15))>>1);\r
156 \r
157 #if (TM_UNROLL && TM_UNROLL_FILTERBANKCOMPUTEPSD16)\r
158 #pragma TCS_unroll=2\r
159 #pragma TCS_unrollexact=1\r
160 #endif\r
161         for ( i=0,j=0,k=0 ; i<len ; i+=2,j+=4,++k )\r
162         {\r
163                 register int mell0, melr0, mel1, mel0, mell1, melr1;\r
164                 register int il1, ir1, il0, ir0;\r
165                 register int left10, right10, lr1, lr0;\r
166                 register int acc0, acc1, ps10;\r
167 \r
168                 acc0 = acc1 = s;\r
169 \r
170                 il0             = ld32x(bleft, i);\r
171                 ir0             = ld32x(bright,i);\r
172                 mell0   = mel[il0]; \r
173                 melr0   = mel[ir0];\r
174                 left10  = ld32x(left,  k);\r
175                 right10 = ld32x(right, k);\r
176                 mel0    = pack16lsb(mell0, melr0);\r
177                 lr0             = pack16lsb(left10, right10);\r
178                 \r
179                 acc0    += ifir16(mel0, lr0);\r
180                 acc0    >>= 15;\r
181                 \r
182                 il1             = ld32x(bleft, i+1);\r
183                 ir1             = ld32x(bright,i+1);\r
184                 mell1   = mel[il1];\r
185                 melr1   = mel[ir1];\r
186                 mel1    = pack16lsb(mell1, melr1);\r
187                 lr1             = pack16msb(left10, right10);\r
188                         \r
189                 acc1    += ifir16(mel1, lr1);\r
190                 acc1    >>= 15;\r
191 \r
192                 ps10    = pack16lsb(acc1, acc0);\r
193                 \r
194                 st32d(j, ps, ps10);\r
195         }\r
196 #if (TM_UNROLL && TM_UNROLL_FILTERBANKCOMPUTEPSD16)\r
197 #pragma TCS_unrollexact=0\r
198 #pragma TCS_unroll=0\r
199 #endif\r
200 \r
201         FILTERBANKCOMPUTEPSD16_STOP();\r
202 }\r
203 \r
204 #else\r
205 \r
206 #define OVERRIDE_FILTERBANK_COMPUTE_BANK32\r
207 void filterbank_compute_bank32(FilterBank * restrict bank, float * restrict ps, float * restrict mel)\r
208 {\r
209         register int i, banks, len;\r
210         register int * restrict bleft, * restrict bright;\r
211         register float * restrict left, * restrict right;\r
212 \r
213         banks = bank->nb_banks;\r
214         len      = bank->len;\r
215         bleft = bank->bank_left;\r
216         bright= bank->bank_right;\r
217         left     = bank->filter_left;\r
218         right = bank->filter_right;\r
219 \r
220         FILTERBANKCOMPUTEBANK32_START();\r
221 \r
222         memset(mel, 0, banks * sizeof(float));\r
223 \r
224 #if (TM_UNROLL && TM_UNROLL_FILTERBANKCOMPUTEBANK32)\r
225 #pragma TCS_unroll=4\r
226 #pragma TCS_unrollexact=1\r
227 #endif\r
228    for ( i=0 ; i<len ; ++i)\r
229    {\r
230       register int id1, id2;\r
231           register float psi;\r
232 \r
233       id1 = bleft[i];\r
234       id2 = bright[i];\r
235       psi = ps[i];\r
236           \r
237           mel[id1] += left[i] * psi;\r
238       mel[id2] += right[i] * psi;\r
239    }\r
240 #if (TM_UNROLL && TM_UNROLL_FILTERBANKCOMPUTEBANK32)\r
241 #pragma TCS_unrollexact=0\r
242 #pragma TCS_unroll=0\r
243 #endif\r
244 \r
245    FILTERBANKCOMPUTEBANK32_STOP();\r
246 }\r
247 \r
248 #define OVERRIDE_FILTERBANK_COMPUTE_PSD16\r
249 void filterbank_compute_psd16(FilterBank * restrict bank, float * restrict mel, float * restrict ps)\r
250 {\r
251         register int i, len;\r
252         register int * restrict bleft, * restrict bright;\r
253         register float * restrict left, * restrict right;\r
254 \r
255         len       = bank->len;\r
256         bleft = bank->bank_left;\r
257         bright= bank->bank_right;\r
258         left  = bank->filter_left;\r
259         right = bank->filter_right;\r
260 \r
261         FILTERBANKCOMPUTEPSD16_START();\r
262 \r
263 #if (TM_UNROLL && TM_UNROLL_FILTERBANKCOMPUTEPSD16)\r
264 #pragma TCS_unroll=4\r
265 #pragma TCS_unrollexact=1\r
266 #endif\r
267         for ( i=0 ; i<len ; ++i )\r
268         {\r
269                 register float acc;\r
270                 register int id1, id2;\r
271 \r
272                 id1 = bleft[i];\r
273                 id2 = bright[i];\r
274 \r
275                 acc = mel[id1] * left[i];\r
276                 acc += mel[id2] * right[i];\r
277                 \r
278                 ps[i] = acc;\r
279         }\r
280 #if (TM_UNROLL && TM_UNROLL_FILTERBANKCOMPUTEPSD16)\r
281 #pragma TCS_unrollexact=0\r
282 #pragma TCS_unroll=0\r
283 #endif\r
284 \r
285          FILTERBANKCOMPUTEPSD16_STOP();\r
286 }\r
287 \r
288 \r
289 #endif\r