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