1 
2 /* -----------------------------------------------------------------------------------------------------------
3 Software License for The Fraunhofer FDK AAC Codec Library for Android
4 
5 � Copyright  1995 - 2013 Fraunhofer-Gesellschaft zur F�rderung der angewandten Forschung e.V.
6   All rights reserved.
7 
8  1.    INTRODUCTION
9 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
10 the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
11 This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
12 
13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
14 audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
15 independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
16 of the MPEG specifications.
17 
18 Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
19 may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
20 individually for the purpose of encoding or decoding bit streams in products that are compliant with
21 the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
22 these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
23 software may already be covered under those patent licenses when it is used for those licensed purposes only.
24 
25 Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
26 are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
27 applications information and documentation.
28 
29 2.    COPYRIGHT LICENSE
30 
31 Redistribution and use in source and binary forms, with or without modification, are permitted without
32 payment of copyright license fees provided that you satisfy the following conditions:
33 
34 You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
35 your modifications thereto in source code form.
36 
37 You must retain the complete text of this software license in the documentation and/or other materials
38 provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
39 You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
40 modifications thereto to recipients of copies in binary form.
41 
42 The name of Fraunhofer may not be used to endorse or promote products derived from this library without
43 prior written permission.
44 
45 You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
46 software or your modifications thereto.
47 
48 Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
49 and the date of any change. For modified versions of the FDK AAC Codec, the term
50 "Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
51 "Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
52 
53 3.    NO PATENT LICENSE
54 
55 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
56 ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
57 respect to this software.
58 
59 You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
60 by appropriate patent licenses.
61 
62 4.    DISCLAIMER
63 
64 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
65 "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
66 of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
67 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
68 including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
69 or business interruption, however caused and on any theory of liability, whether in contract, strict
70 liability, or tort (including negligence), arising in any way out of the use of this software, even if
71 advised of the possibility of such damage.
72 
73 5.    CONTACT INFORMATION
74 
75 Fraunhofer Institute for Integrated Circuits IIS
76 Attention: Audio and Multimedia Departments - FDK AAC LL
77 Am Wolfsmantel 33
78 91058 Erlangen, Germany
79 
80 www.iis.fraunhofer.de/amm
81 amm-info@iis.fraunhofer.de
82 ----------------------------------------------------------------------------------------------------------- */
83 
84 #if (QMF_NO_POLY==5)
85 
86 #define FUNCTION_qmfForwardModulationLP_odd
87 
88 #ifdef FUNCTION_qmfForwardModulationLP_odd
89 static void
qmfForwardModulationLP_odd(HANDLE_QMF_FILTER_BANK anaQmf,const FIXP_QMF * timeIn,FIXP_QMF * rSubband)90 qmfForwardModulationLP_odd( HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank  */
91                             const FIXP_QMF *timeIn,        /*!< Time Signal */
92                             FIXP_QMF *rSubband )           /*!< Real Output */
93 {
94   int i;
95   int L = anaQmf->no_channels;
96   int M = L>>1;
97   int shift = (anaQmf->no_channels>>6) + 1;
98   int rSubband_e = 0;
99 
100   FIXP_QMF *rSubbandPtr0 = &rSubband[M+0];                /* runs with increment */
101   FIXP_QMF *rSubbandPtr1 = &rSubband[M-1];                /* runs with decrement */
102   FIXP_QMF *timeIn0 = (FIXP_DBL *) &timeIn[0];            /* runs with increment */
103   FIXP_QMF *timeIn1 = (FIXP_DBL *) &timeIn[L];            /* runs with increment */
104   FIXP_QMF *timeIn2 = (FIXP_DBL *) &timeIn[L-1];          /* runs with decrement */
105   FIXP_QMF *timeIn3 = (FIXP_DBL *) &timeIn[2*L-1];        /* runs with decrement */
106 
107   for (i = 0; i < M; i++)
108   {
109     *rSubbandPtr0++ = (*timeIn2-- >> 1) - (*timeIn0++ >> shift);
110     *rSubbandPtr1-- = (*timeIn1++ >> 1) + (*timeIn3-- >> shift);
111   }
112 
113   dct_IV(rSubband,L, &rSubband_e);
114 }
115 #endif /* FUNCTION_qmfForwardModulationLP_odd */
116 
117 
118 /* NEON optimized QMF currently builts only with RVCT toolchain */
119 
120 #if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_5TE__)
121 
122 #if (SAMPLE_BITS == 16)
123 #define FUNCTION_qmfAnaPrototypeFirSlot
124 #endif
125 
126 #ifdef FUNCTION_qmfAnaPrototypeFirSlot
127 
128 #if defined(__GNUC__)	/* cppp replaced: elif */
129 
SMULBB(const SHORT a,const LONG b)130 inline INT SMULBB (const SHORT a, const LONG b)
131 {
132   INT result ;
133   __asm__ ("smulbb %0, %1, %2"
134      : "=r" (result)
135      : "r" (a), "r" (b)) ;
136   return result ;
137 }
SMULBT(const SHORT a,const LONG b)138 inline INT SMULBT (const SHORT a, const LONG b)
139 {
140   INT result ;
141   __asm__ ("smulbt %0, %1, %2"
142      : "=r" (result)
143      : "r" (a), "r" (b)) ;
144   return result ;
145 }
146 
SMLABB(const LONG accu,const SHORT a,const LONG b)147 inline INT SMLABB(const LONG accu, const SHORT a, const LONG b)
148 {
149   INT result ;
150   __asm__ ("smlabb %0, %1, %2,%3"
151      : "=r" (result)
152      : "r" (a), "r" (b), "r" (accu)) ;
153   return result;
154 }
SMLABT(const LONG accu,const SHORT a,const LONG b)155 inline INT SMLABT(const LONG accu, const SHORT a, const LONG b)
156 {
157   INT result ;
158   __asm__ ("smlabt %0, %1, %2,%3"
159      : "=r" (result)
160      : "r" (a), "r" (b), "r" (accu)) ;
161   return result;
162 }
163 #endif /* compiler selection  */
164 
165 
qmfAnaPrototypeFirSlot(FIXP_QMF * analysisBuffer,int no_channels,const FIXP_PFT * p_filter,int p_stride,FIXP_QAS * RESTRICT pFilterStates)166 void qmfAnaPrototypeFirSlot( FIXP_QMF *analysisBuffer,
167                              int       no_channels,             /*!< Number channels of analysis filter */
168                              const FIXP_PFT *p_filter,
169                              int       p_stride,                /*!< Stide of analysis filter    */
170                              FIXP_QAS *RESTRICT pFilterStates
171                             )
172 {
173   LONG *p_flt = (LONG *) p_filter;
174   LONG flt;
175   FIXP_QMF *RESTRICT pData_0 = analysisBuffer + 2*no_channels - 1;
176   FIXP_QMF *RESTRICT pData_1 = analysisBuffer;
177 
178   FIXP_QAS *RESTRICT sta_0 = (FIXP_QAS *)pFilterStates;
179   FIXP_QAS *RESTRICT sta_1 = (FIXP_QAS *)pFilterStates + (2*QMF_NO_POLY*no_channels) - 1;
180 
181   FIXP_DBL accu0, accu1;
182   FIXP_QAS sta0, sta1;
183 
184   int staStep1 =  no_channels<<1;
185   int staStep2 = (no_channels<<3) - 1; /* Rewind one less */
186 
187   if (p_stride == 1)
188   {
189     /* FIR filter 0 */
190     flt = *p_flt++;
191     sta1 = *sta_1;  sta_1 -= staStep1;
192     accu1 = SMULBB(        sta1, flt);
193     sta1 = *sta_1;  sta_1 -= staStep1;
194     accu1 = SMLABT( accu1, sta1, flt);
195 
196     flt = *p_flt++;
197     sta1 = *sta_1;  sta_1 -= staStep1;
198     accu1 = SMLABB( accu1, sta1, flt);
199     sta1 = *sta_1;  sta_1 -= staStep1;
200     accu1 = SMLABT( accu1, sta1, flt);
201 
202     flt = *p_flt++;
203     sta1 = *sta_1;  sta_1 += staStep2;
204     accu1 = SMLABB( accu1, sta1, flt);
205     *pData_1++ = FX_DBL2FX_QMF(accu1<<1);
206 
207     /* FIR filters 1..63 127..65 or 1..31 63..33 */
208     no_channels >>= 1;
209     for (; --no_channels; )
210     {
211       sta0 = *sta_0; sta_0 += staStep1;  /* 1,3,5, ... 29/61 */
212       sta1 = *sta_1; sta_1 -= staStep1;
213       accu0 = SMULBT(        sta0, flt);
214       accu1 = SMULBT(        sta1, flt);
215 
216       flt = *p_flt++;
217       sta0 = *sta_0; sta_0 += staStep1;
218       sta1 = *sta_1; sta_1 -= staStep1;
219       accu0 = SMLABB( accu0, sta0, flt);
220       accu1 = SMLABB( accu1, sta1, flt);
221 
222       sta0 = *sta_0; sta_0 += staStep1;
223       sta1 = *sta_1; sta_1 -= staStep1;
224       accu0 = SMLABT( accu0, sta0, flt);
225       accu1 = SMLABT( accu1, sta1, flt);
226 
227       flt = *p_flt++;
228       sta0 = *sta_0; sta_0 += staStep1;
229       sta1 = *sta_1; sta_1 -= staStep1;
230       accu0 = SMLABB( accu0, sta0, flt);
231       accu1 = SMLABB( accu1, sta1, flt);
232 
233       sta0 = *sta_0; sta_0 -= staStep2;
234       sta1 = *sta_1; sta_1 += staStep2;
235       accu0 = SMLABT( accu0, sta0, flt);
236       accu1 = SMLABT( accu1, sta1, flt);
237 
238       *pData_0-- = FX_DBL2FX_QMF(accu0<<1);
239       *pData_1++ = FX_DBL2FX_QMF(accu1<<1);
240 
241       /* Same sequence as above, but mix B=bottom with T=Top */
242 
243       flt = *p_flt++;
244       sta0 = *sta_0; sta_0 += staStep1;  /* 2,4,6, ... 30/62 */
245       sta1 = *sta_1; sta_1 -= staStep1;
246       accu0 = SMULBB(        sta0, flt);
247       accu1 = SMULBB(        sta1, flt);
248 
249       sta0 = *sta_0; sta_0 += staStep1;
250       sta1 = *sta_1; sta_1 -= staStep1;
251       accu0 = SMLABT( accu0, sta0, flt);
252       accu1 = SMLABT( accu1, sta1, flt);
253 
254       flt = *p_flt++;
255       sta0 = *sta_0; sta_0 += staStep1;
256       sta1 = *sta_1; sta_1 -= staStep1;
257       accu0 = SMLABB( accu0, sta0, flt);
258       accu1 = SMLABB( accu1, sta1, flt);
259 
260       sta0 = *sta_0; sta_0 += staStep1;
261       sta1 = *sta_1; sta_1 -= staStep1;
262       accu0 = SMLABT( accu0, sta0, flt);
263       accu1 = SMLABT( accu1, sta1, flt);
264 
265       flt = *p_flt++;
266       sta0 = *sta_0; sta_0 -= staStep2;
267       sta1 = *sta_1; sta_1 += staStep2;
268       accu0 = SMLABB( accu0, sta0, flt);
269       accu1 = SMLABB( accu1, sta1, flt);
270 
271       *pData_0-- = FX_DBL2FX_QMF(accu0<<1);
272       *pData_1++ = FX_DBL2FX_QMF(accu1<<1);
273     }
274 
275     /* FIR filter 31/63 and 33/65 */
276     sta0 = *sta_0; sta_0 += staStep1;
277     sta1 = *sta_1; sta_1 -= staStep1;
278     accu0 = SMULBT(        sta0, flt);
279     accu1 = SMULBT(        sta1, flt);
280 
281     flt = *p_flt++;
282     sta0 = *sta_0; sta_0 += staStep1;
283     sta1 = *sta_1; sta_1 -= staStep1;
284     accu0 = SMLABB( accu0, sta0, flt);
285     accu1 = SMLABB( accu1, sta1, flt);
286 
287     sta0 = *sta_0; sta_0 += staStep1;
288     sta1 = *sta_1; sta_1 -= staStep1;
289     accu0 = SMLABT( accu0, sta0, flt);
290     accu1 = SMLABT( accu1, sta1, flt);
291 
292     flt = *p_flt++;
293     sta0 = *sta_0; sta_0 += staStep1;
294     sta1 = *sta_1; sta_1 -= staStep1;
295     accu0 = SMLABB( accu0, sta0, flt);
296     accu1 = SMLABB( accu1, sta1, flt);
297 
298     sta0 = *sta_0; sta_0 -= staStep2;
299     sta1 = *sta_1; sta_1 += staStep2;
300     accu0 = SMLABT( accu0, sta0, flt);
301     accu1 = SMLABT( accu1, sta1, flt);
302 
303     *pData_0-- = FX_DBL2FX_QMF(accu0<<1);
304     *pData_1++ = FX_DBL2FX_QMF(accu1<<1);
305 
306     /* FIR filter 32/64 */
307     flt = *p_flt++;
308     sta0 = *sta_0; sta_0 += staStep1;
309     sta1 = *sta_1; sta_1 -= staStep1;
310     accu0 = SMULBB(        sta0, flt);
311     accu1 = SMULBB(        sta1, flt);
312 
313     sta0 = *sta_0; sta_0 += staStep1;
314     sta1 = *sta_1; sta_1 -= staStep1;
315     accu0 = SMLABT( accu0, sta0, flt);
316     accu1 = SMLABT( accu1, sta1, flt);
317 
318     flt = *p_flt++;
319     sta0 = *sta_0; sta_0 += staStep1;
320     sta1 = *sta_1; sta_1 -= staStep1;
321     accu0 = SMLABB( accu0, sta0, flt);
322     accu1 = SMLABB( accu1, sta1, flt);
323 
324     sta0 = *sta_0; sta_0 += staStep1;
325     sta1 = *sta_1; sta_1 -= staStep1;
326     accu0 = SMLABT( accu0, sta0, flt);
327     accu1 = SMLABT( accu1, sta1, flt);
328 
329     flt = *p_flt;
330     sta0 = *sta_0;
331     sta1 = *sta_1;
332     accu0 = SMLABB( accu0, sta0, flt);
333     accu1 = SMLABB( accu1, sta1, flt);
334 
335     *pData_0-- = FX_DBL2FX_QMF(accu0<<1);
336     *pData_1++ = FX_DBL2FX_QMF(accu1<<1);
337   }
338   else
339   {
340     int pfltStep = QMF_NO_POLY * (p_stride-1);
341 
342     flt = p_flt[0];
343     sta1 = *sta_1;  sta_1 -= staStep1;
344     accu1 = SMULBB(        sta1, flt);
345     sta1 = *sta_1;  sta_1 -= staStep1;
346     accu1 = SMLABT( accu1, sta1, flt);
347 
348     flt = p_flt[1];
349     sta1 = *sta_1;  sta_1 -= staStep1;
350     accu1 = SMLABB( accu1, sta1, flt);
351     sta1 = *sta_1;  sta_1 -= staStep1;
352     accu1 = SMLABT( accu1, sta1, flt);
353 
354     flt = p_flt[2]; p_flt += pfltStep;
355     sta1 = *sta_1;  sta_1 += staStep2;
356     accu1 = SMLABB( accu1, sta1, flt);
357     *pData_1++ = FX_DBL2FX_QMF(accu1<<1);
358 
359     /* FIR filters 1..63 127..65 or 1..31 63..33 */
360     for (; --no_channels; )
361     {
362       flt = p_flt[0];
363       sta0 = *sta_0; sta_0 += staStep1;
364       sta1 = *sta_1; sta_1 -= staStep1;
365       accu0 = SMULBB(        sta0, flt);
366       accu1 = SMULBB(        sta1, flt);
367 
368       sta0 = *sta_0; sta_0 += staStep1;
369       sta1 = *sta_1; sta_1 -= staStep1;
370       accu0 = SMLABT( accu0, sta0, flt);
371       accu1 = SMLABT( accu1, sta1, flt);
372 
373       flt = p_flt[1];
374       sta0 = *sta_0; sta_0 += staStep1;
375       sta1 = *sta_1; sta_1 -= staStep1;
376       accu0 = SMLABB( accu0, sta0, flt);
377       accu1 = SMLABB( accu1, sta1, flt);
378 
379       sta0 = *sta_0; sta_0 += staStep1;
380       sta1 = *sta_1; sta_1 -= staStep1;
381       accu0 = SMLABT( accu0, sta0, flt);
382       accu1 = SMLABT( accu1, sta1, flt);
383 
384       flt = p_flt[2]; p_flt += pfltStep;
385       sta0 = *sta_0; sta_0 -= staStep2;
386       sta1 = *sta_1; sta_1 += staStep2;
387       accu0 = SMLABB( accu0, sta0, flt);
388       accu1 = SMLABB( accu1, sta1, flt);
389 
390       *pData_0-- = FX_DBL2FX_QMF(accu0<<1);
391       *pData_1++ = FX_DBL2FX_QMF(accu1<<1);
392     }
393 
394     /* FIR filter 32/64 */
395     flt = p_flt[0];
396     sta0 = *sta_0; sta_0 += staStep1;
397     accu0 = SMULBB(        sta0, flt);
398     sta0 = *sta_0; sta_0 += staStep1;
399     accu0 = SMLABT( accu0, sta0, flt);
400 
401     flt = p_flt[1];
402     sta0 = *sta_0; sta_0 += staStep1;
403     accu0 = SMLABB( accu0, sta0, flt);
404     sta0 = *sta_0; sta_0 += staStep1;
405     accu0 = SMLABT( accu0, sta0, flt);
406 
407     flt = p_flt[2];
408     sta0 = *sta_0;
409     accu0 = SMLABB( accu0, sta0, flt);
410     *pData_0-- = FX_DBL2FX_QMF(accu0<<1);
411   }
412 }
413 #endif /* FUNCTION_qmfAnaPrototypeFirSlot */
414 #endif /* #if defined(__CC_ARM) && defined(__ARM_ARCH_6__) */
415 
416 #if ( defined(__ARM_ARCH_5TE__) && (SAMPLE_BITS == 16) ) && !defined(QMF_TABLE_FULL)
417 
418 #define FUNCTION_qmfSynPrototypeFirSlot
419 
420 #if defined(FUNCTION_qmfSynPrototypeFirSlot)
421 
422 #if defined(__GNUC__)	/* cppp replaced: elif */
423 
SMULWB(const LONG a,const LONG b)424 inline INT SMULWB (const LONG a, const LONG b)
425 {
426   INT result ;
427   __asm__ ("smulwb %0, %1, %2"
428     : "=r" (result)
429     : "r" (a), "r" (b)) ;
430 
431   return result ;
432 }
SMULWT(const LONG a,const LONG b)433 inline INT SMULWT (const LONG a, const LONG b)
434 {
435   INT result ;
436   __asm__ ("smulwt %0, %1, %2"
437     : "=r" (result)
438     : "r" (a), "r" (b)) ;
439 
440   return result ;
441 }
442 
SMLAWB(const LONG accu,const LONG a,const LONG b)443 inline INT SMLAWB(const LONG accu, const LONG a, const LONG b)
444 {
445   INT result;
446   asm("smlawb %0, %1, %2, %3 "
447         : "=r" (result)
448         : "r" (a), "r" (b), "r" (accu) );
449   return result ;
450 }
451 
SMLAWT(const LONG accu,const LONG a,const LONG b)452 inline INT SMLAWT(const LONG accu, const LONG a, const LONG b)
453 {
454   INT result;
455   asm("smlawt %0, %1, %2, %3 "
456         : "=r" (result)
457         : "r" (a), "r" (b), "r" (accu) );
458   return result ;
459 }
460 
461 #endif /* ARM compiler selector */
462 
463 
qmfSynPrototypeFirSlot1_filter(FIXP_QMF * RESTRICT realSlot,FIXP_QMF * RESTRICT imagSlot,const FIXP_DBL * RESTRICT p_flt,FIXP_QSS * RESTRICT sta,FIXP_DBL * pMyTimeOut,int no_channels)464 static void qmfSynPrototypeFirSlot1_filter(FIXP_QMF *RESTRICT realSlot,
465                                            FIXP_QMF *RESTRICT imagSlot,
466                                            const FIXP_DBL *RESTRICT p_flt,
467                                            FIXP_QSS *RESTRICT sta,
468                                            FIXP_DBL *pMyTimeOut,
469                                            int no_channels)
470 {
471   /* This code was the base for the above listed assembler sequence */
472   /* It can be used for debugging purpose or further optimizations  */
473   const FIXP_DBL *RESTRICT p_fltm = p_flt + 155;
474 
475   do
476   {
477      FIXP_DBL result;
478      FIXP_DBL A, B, real, imag, sta0;
479 
480      real = *--realSlot;
481      imag = *--imagSlot;
482      B = p_flt[4];                        /* Bottom=[8] Top=[9]     */
483      A = p_fltm[3];                       /* Bottom=[316] Top=[317] */
484      sta0 = sta[0];                       /* save state[0]          */
485      *sta++ = SMLAWT( sta[1], imag, B );  /* index=9...........319  */
486      *sta++ = SMLAWB( sta[1], real, A );  /* index=316...........6  */
487      *sta++ = SMLAWB( sta[1], imag, B );  /* index=8,18,    ...318  */
488      B = p_flt[3];                        /* Bottom=[6] Top=[7]     */
489      *sta++ = SMLAWT( sta[1], real, A );  /* index=317...........7  */
490      A = p_fltm[4];                       /* Bottom=[318] Top=[319] */
491      *sta++ = SMLAWT( sta[1], imag, B );  /* index=7...........317  */
492      *sta++ = SMLAWB( sta[1], real, A );  /* index=318...........8  */
493      *sta++ = SMLAWB( sta[1], imag, B );  /* index=6...........316  */
494      B = p_flt[2];                        /* Bottom=[X] Top=[5]     */
495      *sta++ = SMLAWT( sta[1], real, A );  /* index=9...........319  */
496      A = p_fltm[2];                       /* Bottom=[X] Top=[315]   */
497      *sta++ =         SMULWT( imag, B );  /* index=5,15, ...   315  */
498      result = SMLAWT( sta0,   real, A );  /* index=315...........5  */
499 
500      *pMyTimeOut++ = result;
501 
502      real = *--realSlot;
503      imag = *--imagSlot;
504      A = p_fltm[0];                       /* Bottom=[310] Top=[311] */
505      B = p_flt[7];                        /* Bottom=[14]  Top=[15]  */
506      result = SMLAWB( sta[0], real, A );  /* index=310...........0  */
507      *sta++ = SMLAWB( sta[1], imag, B );  /* index=14..........324  */
508      *pMyTimeOut++ = result;
509      B = p_flt[6];                        /* Bottom=[12]  Top=[13]  */
510      *sta++ = SMLAWT( sta[1], real, A );  /* index=311...........1  */
511      A = p_fltm[1];                       /* Bottom=[312] Top=[313] */
512      *sta++ = SMLAWT( sta[1], imag, B );  /* index=13..........323  */
513      *sta++ = SMLAWB( sta[1], real, A );  /* index=312...........2  */
514      *sta++ = SMLAWB( sta[1], imag, B );  /* index=12..........322  */
515      *sta++ = SMLAWT( sta[1], real, A );  /* index=313...........3  */
516      A = p_fltm[2];                       /* Bottom=[314] Top=[315] */
517      B = p_flt[5];                        /* Bottom=[10]  Top=[11]  */
518      *sta++ = SMLAWT( sta[1], imag, B );  /* index=11..........321  */
519      *sta++ = SMLAWB( sta[1], real, A );  /* index=314...........4  */
520      *sta++ =         SMULWB( imag, B );  /* index=10..........320  */
521 
522 
523      p_flt    += 5;
524      p_fltm   -= 5;
525   }
526   while ((--no_channels) != 0);
527 
528 }
529 
530 
531 
qmfSynPrototypeFirSlot2(HANDLE_QMF_FILTER_BANK qmf,FIXP_QMF * RESTRICT realSlot,FIXP_QMF * RESTRICT imagSlot,INT_PCM * RESTRICT timeOut,INT stride)532 INT qmfSynPrototypeFirSlot2(
533                              HANDLE_QMF_FILTER_BANK qmf,
534                              FIXP_QMF *RESTRICT realSlot,            /*!< Input: Pointer to real Slot */
535                              FIXP_QMF *RESTRICT imagSlot,            /*!< Input: Pointer to imag Slot */
536                              INT_PCM  *RESTRICT timeOut,             /*!< Time domain data */
537                              INT       stride                        /*!< Time output buffer stride factor*/
538                             )
539 {
540   FIXP_QSS *RESTRICT sta = (FIXP_QSS*)qmf->FilterStates;
541   int no_channels = qmf->no_channels;
542   int scale = ((DFRACT_BITS-SAMPLE_BITS)-1-qmf->outScalefactor);
543 
544   /* We map an arry of 16-bit values upon an array of 2*16-bit values to read 2 values in one shot */
545   const FIXP_DBL *RESTRICT p_flt  = (FIXP_DBL *) qmf->p_filter;           /* low=[0],   high=[1]   */
546   const FIXP_DBL *RESTRICT p_fltm = (FIXP_DBL *) qmf->p_filter + 155;     /* low=[310], high=[311] */
547 
548   FDK_ASSERT(SAMPLE_BITS-1-qmf->outScalefactor >= 0); //   (DFRACT_BITS-SAMPLE_BITS)-1-qmf->outScalefactor >= 0);
549   FDK_ASSERT(qmf->p_stride==2 && qmf->no_channels == 32);
550 
551   FDK_ASSERT((no_channels&3) == 0);  /* should be a multiple of 4 */
552 
553   realSlot += no_channels-1;    // ~~"~~
554   imagSlot += no_channels-1;    // no_channels-1 .. 0
555 
556   FIXP_DBL MyTimeOut[32];
557   FIXP_DBL *pMyTimeOut = &MyTimeOut[0];
558 
559   for (no_channels = no_channels; no_channels--;)
560   {
561      FIXP_DBL result;
562      FIXP_DBL A, B, real, imag;
563 
564      real = *realSlot--;
565      imag = *imagSlot--;
566      A = p_fltm[0];                       /* Bottom=[310] Top=[311] */
567      B = p_flt[7];                        /* Bottom=[14]  Top=[15]  */
568      result = SMLAWB( sta[0], real, A );  /* index=310...........0  */
569      *sta++ = SMLAWB( sta[1], imag, B );  /* index=14..........324  */
570      B = p_flt[6];                        /* Bottom=[12]  Top=[13]  */
571      *sta++ = SMLAWT( sta[1], real, A );  /* index=311...........1  */
572      A = p_fltm[1];                       /* Bottom=[312] Top=[313] */
573      *sta++ = SMLAWT( sta[1], imag, B );  /* index=13..........323  */
574      *sta++ = SMLAWB( sta[1], real, A );  /* index=312...........2  */
575      *sta++ = SMLAWB( sta[1], imag, B );  /* index=12..........322  */
576      *sta++ = SMLAWT( sta[1], real, A );  /* index=313...........3  */
577      A = p_fltm[2];                       /* Bottom=[314] Top=[315] */
578      B = p_flt[5];                        /* Bottom=[10]  Top=[11]  */
579      *sta++ = SMLAWT( sta[1], imag, B );  /* index=11..........321  */
580      *sta++ = SMLAWB( sta[1], real, A );  /* index=314...........4  */
581      *sta++ =         SMULWB( imag, B );  /* index=10..........320  */
582 
583      *pMyTimeOut++ = result;
584 
585      p_fltm   -= 5;
586      p_flt    += 5;
587   }
588 
589   pMyTimeOut = &MyTimeOut[0];
590 #if (SAMPLE_BITS == 16)
591   const FIXP_DBL max_pos = (FIXP_DBL) 0x00007FFF << scale;
592   const FIXP_DBL max_neg = (FIXP_DBL) 0xFFFF8001 << scale;
593 #else
594   scale = -scale;
595   const FIXP_DBL max_pos = (FIXP_DBL) 0x7FFFFFFF >> scale;
596   const FIXP_DBL max_neg = (FIXP_DBL) 0x80000001 >> scale;
597 #endif
598   const FIXP_DBL add_neg = (1 << scale) - 1;
599 
600   no_channels = qmf->no_channels;
601 
602   timeOut += no_channels*stride;
603 
604   FDK_ASSERT(scale >= 0);
605 
606   if (qmf->outGain != 0x80000000)
607   {
608     FIXP_DBL gain = qmf->outGain;
609     for (no_channels>>=2; no_channels--;)
610     {
611       FIXP_DBL result1, result2;
612 
613       result1 = *pMyTimeOut++;
614       result2 = *pMyTimeOut++;
615 
616       result1 = fMult(result1,gain);
617       timeOut -= stride;
618       if (result1 < 0)        result1 += add_neg;
619       if (result1 < max_neg)  result1 = max_neg;
620       if (result1 > max_pos)  result1 = max_pos;
621 #if (SAMPLE_BITS == 16)
622       timeOut[0] = result1 >> scale;
623 #else
624       timeOut[0] = result1 << scale;
625 #endif
626 
627       result2 = fMult(result2,gain);
628       timeOut -= stride;
629       if (result2 < 0)        result2 += add_neg;
630       if (result2 < max_neg)  result2 = max_neg;
631       if (result2 > max_pos)  result2 = max_pos;
632 #if (SAMPLE_BITS == 16)
633       timeOut[0] = result2 >> scale;
634 #else
635       timeOut[0] = result2 << scale;
636 #endif
637 
638       result1 = *pMyTimeOut++;
639       result2 = *pMyTimeOut++;
640 
641       result1 = fMult(result1,gain);
642       timeOut -= stride;
643       if (result1 < 0)        result1 += add_neg;
644       if (result1 < max_neg)  result1 = max_neg;
645       if (result1 > max_pos)  result1 = max_pos;
646 #if (SAMPLE_BITS == 16)
647       timeOut[0] = result1 >> scale;
648 #else
649       timeOut[0] = result1 << scale;
650 #endif
651 
652       result2 = fMult(result2,gain);
653       timeOut -= stride;
654       if (result2 < 0)        result2 += add_neg;
655       if (result2 < max_neg)  result2 = max_neg;
656       if (result2 > max_pos)  result2 = max_pos;
657 #if (SAMPLE_BITS == 16)
658       timeOut[0] = result2 >> scale;
659 #else
660       timeOut[0] = result2 << scale;
661 #endif
662     }
663   }
664   else
665   {
666     for (no_channels>>=2; no_channels--;)
667     {
668       FIXP_DBL result1, result2;
669       result1 = *pMyTimeOut++;
670       result2 = *pMyTimeOut++;
671       timeOut -= stride;
672       if (result1 < 0)        result1 += add_neg;
673       if (result1 < max_neg)  result1 = max_neg;
674       if (result1 > max_pos)  result1 = max_pos;
675 #if (SAMPLE_BITS == 16)
676       timeOut[0] = result1 >> scale;
677 #else
678       timeOut[0] = result1 << scale;
679 #endif
680 
681       timeOut -= stride;
682       if (result2 < 0)        result2 += add_neg;
683       if (result2 < max_neg)  result2 = max_neg;
684       if (result2 > max_pos)  result2 = max_pos;
685 #if (SAMPLE_BITS == 16)
686       timeOut[0] = result2 >> scale;
687 #else
688       timeOut[0] = result2 << scale;
689 #endif
690 
691       result1 = *pMyTimeOut++;
692       result2 = *pMyTimeOut++;
693       timeOut -= stride;
694       if (result1 < 0)        result1 += add_neg;
695       if (result1 < max_neg)  result1 = max_neg;
696       if (result1 > max_pos)  result1 = max_pos;
697 #if (SAMPLE_BITS == 16)
698       timeOut[0] = result1 >> scale;
699 #else
700       timeOut[0] = result1 << scale;
701 #endif
702 
703       timeOut -= stride;
704       if (result2 < 0)        result2 += add_neg;
705       if (result2 < max_neg)  result2 = max_neg;
706       if (result2 > max_pos)  result2 = max_pos;
707 #if (SAMPLE_BITS == 16)
708       timeOut[0] = result2 >> scale;
709 #else
710       timeOut[0] = result2 << scale;
711 #endif
712     }
713   }
714   return 0;
715 }
716 
717 static
718 void qmfSynPrototypeFirSlot_fallback( HANDLE_QMF_FILTER_BANK qmf,
719                              FIXP_DBL *realSlot,      /*!< Input: Pointer to real Slot */
720                              FIXP_DBL *imagSlot,      /*!< Input: Pointer to imag Slot */
721                              INT_PCM  *timeOut,             /*!< Time domain data */
722                              const int       stride
723                             );
724 
725 /*!
726   \brief Perform Synthesis Prototype Filtering on a single slot of input data.
727 
728   The filter takes 2 * #MAX_SYNTHESIS_CHANNELS of input data and
729   generates #MAX_SYNTHESIS_CHANNELS time domain output samples.
730 */
731 
732 static
qmfSynPrototypeFirSlot(HANDLE_QMF_FILTER_BANK qmf,FIXP_DBL * realSlot,FIXP_DBL * imagSlot,INT_PCM * timeOut,const int stride)733 void qmfSynPrototypeFirSlot( HANDLE_QMF_FILTER_BANK qmf,
734                              FIXP_DBL *realSlot,      /*!< Input: Pointer to real Slot */
735                              FIXP_DBL *imagSlot,      /*!< Input: Pointer to imag Slot */
736                              INT_PCM  *timeOut,             /*!< Time domain data */
737                              const int       stride
738                             )
739 {
740     INT err = -1;
741 
742     switch (qmf->p_stride) {
743     case 2:
744       err = qmfSynPrototypeFirSlot2(qmf, realSlot, imagSlot, timeOut, stride);
745       break;
746     default:
747       err = -1;
748     }
749 
750     /* fallback if configuration not available or failed */
751     if(err!=0) {
752         qmfSynPrototypeFirSlot_fallback(qmf, realSlot, imagSlot, timeOut, stride);
753     }
754 }
755 #endif /* FUNCTION_qmfSynPrototypeFirSlot */
756 
757 #endif  /*  ( defined(__CC_ARM) && defined(__ARM_ARCH_5TE__) && (SAMPLE_BITS == 16) ) && !defined(QMF_TABLE_FULL) */
758 
759 
760 
761 /* #####################################################################################*/
762 
763 
764 
765 #endif  /* (QMF_NO_POLY==5) */
766 
767