blob: a154a2f9b0b0430ad1a8eb4ed741b9f10a650624 [file] [log] [blame]
Mans Rullgard219e2622011-04-22 09:22:33 +03001/*
2 ** Copyright 2003-2010, VisualOn, Inc.
3 **
4 ** Licensed under the Apache License, Version 2.0 (the "License");
5 ** you may not use this file except in compliance with the License.
6 ** You may obtain a copy of the License at
7 **
8 ** http://www.apache.org/licenses/LICENSE-2.0
9 **
10 ** Unless required by applicable law or agreed to in writing, software
11 ** distributed under the License is distributed on an "AS IS" BASIS,
12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 ** See the License for the specific language governing permissions and
14 ** limitations under the License.
15 */
16/*******************************************************************************
17 File: transform.c
18
19 Content: MDCT Transform functionss
20
James Dong17299ab2010-05-14 15:45:22 -070021*******************************************************************************/
22
Mans Rullgard219e2622011-04-22 09:22:33 +030023#include "basic_op.h"
James Dong17299ab2010-05-14 15:45:22 -070024#include "psy_const.h"
25#include "transform.h"
26#include "aac_rom.h"
Mans Rullgard219e2622011-04-22 09:22:33 +030027
28
29#define LS_TRANS ((FRAME_LEN_LONG-FRAME_LEN_SHORT)/2) /* 448 */
30#define SQRT1_2 0x5a82799a /* sqrt(1/2) in Q31 */
31#define swap2(p0,p1) \
32 t = p0; t1 = *(&(p0)+1); \
33 p0 = p1; *(&(p0)+1) = *(&(p1)+1); \
Mans Rullgard62a62ef2011-04-05 17:40:06 +030034 p1 = t; *(&(p1)+1) = t1
James Dong17299ab2010-05-14 15:45:22 -070035
36/*********************************************************************************
37*
38* function name: Shuffle
39* description: Shuffle points prepared function for fft
40*
41**********************************************************************************/
Mans Rullgard219e2622011-04-22 09:22:33 +030042static void Shuffle(int *buf, int num, const unsigned char* bitTab)
43{
44 int *part0, *part1;
45 int i, j;
46 int t, t1;
47
48 part0 = buf;
49 part1 = buf + num;
Mans Rullgard62a62ef2011-04-05 17:40:06 +030050
Mans Rullgard219e2622011-04-22 09:22:33 +030051 while ((i = *bitTab++) != 0) {
52 j = *bitTab++;
53
Mans Rullgard62a62ef2011-04-05 17:40:06 +030054 swap2(part0[4*i+0], part0[4*j+0]);
55 swap2(part0[4*i+2], part1[4*j+0]);
56 swap2(part1[4*i+0], part0[4*j+2]);
57 swap2(part1[4*i+2], part1[4*j+2]);
Mans Rullgard219e2622011-04-22 09:22:33 +030058 }
59
60 do {
Mans Rullgard62a62ef2011-04-05 17:40:06 +030061 swap2(part0[4*i+2], part1[4*i+0]);
Mans Rullgard219e2622011-04-22 09:22:33 +030062 } while ((i = *bitTab++) != 0);
63}
64
65#if !defined(ARMV5E) && !defined(ARMV7Neon)
James Dong17299ab2010-05-14 15:45:22 -070066
67/*****************************************************************************
68*
69* function name: Radix4First
70* description: Radix 4 point prepared function for fft
71*
Mans Rullgard219e2622011-04-22 09:22:33 +030072**********************************************************************************/
73static void Radix4First(int *buf, int num)
74{
75 int r0, r1, r2, r3;
76 int r4, r5, r6, r7;
Mans Rullgard62a62ef2011-04-05 17:40:06 +030077
78 for (; num != 0; num--)
Mans Rullgard219e2622011-04-22 09:22:33 +030079 {
80 r0 = buf[0] + buf[2];
81 r1 = buf[1] + buf[3];
82 r2 = buf[0] - buf[2];
83 r3 = buf[1] - buf[3];
84 r4 = buf[4] + buf[6];
85 r5 = buf[5] + buf[7];
86 r6 = buf[4] - buf[6];
87 r7 = buf[5] - buf[7];
88
89 buf[0] = r0 + r4;
90 buf[1] = r1 + r5;
91 buf[4] = r0 - r4;
92 buf[5] = r1 - r5;
93 buf[2] = r2 + r7;
94 buf[3] = r3 - r6;
95 buf[6] = r2 - r7;
96 buf[7] = r3 + r6;
97
98 buf += 8;
99 }
100}
101
James Dong17299ab2010-05-14 15:45:22 -0700102/*****************************************************************************
103*
104* function name: Radix8First
105* description: Radix 8 point prepared function for fft
106*
Mans Rullgard219e2622011-04-22 09:22:33 +0300107**********************************************************************************/
108static void Radix8First(int *buf, int num)
109{
110 int r0, r1, r2, r3;
111 int i0, i1, i2, i3;
112 int r4, r5, r6, r7;
113 int i4, i5, i6, i7;
114 int t0, t1, t2, t3;
115
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300116 for ( ; num != 0; num--)
Mans Rullgard219e2622011-04-22 09:22:33 +0300117 {
118 r0 = buf[0] + buf[2];
119 i0 = buf[1] + buf[3];
120 r1 = buf[0] - buf[2];
121 i1 = buf[1] - buf[3];
122 r2 = buf[4] + buf[6];
123 i2 = buf[5] + buf[7];
124 r3 = buf[4] - buf[6];
125 i3 = buf[5] - buf[7];
126
127 r4 = (r0 + r2) >> 1;
128 i4 = (i0 + i2) >> 1;
129 r5 = (r0 - r2) >> 1;
130 i5 = (i0 - i2) >> 1;
131 r6 = (r1 - i3) >> 1;
132 i6 = (i1 + r3) >> 1;
133 r7 = (r1 + i3) >> 1;
134 i7 = (i1 - r3) >> 1;
135
136 r0 = buf[ 8] + buf[10];
137 i0 = buf[ 9] + buf[11];
138 r1 = buf[ 8] - buf[10];
139 i1 = buf[ 9] - buf[11];
140 r2 = buf[12] + buf[14];
141 i2 = buf[13] + buf[15];
142 r3 = buf[12] - buf[14];
143 i3 = buf[13] - buf[15];
144
145 t0 = (r0 + r2) >> 1;
146 t1 = (i0 + i2) >> 1;
147 t2 = (r0 - r2) >> 1;
148 t3 = (i0 - i2) >> 1;
149
150 buf[ 0] = r4 + t0;
151 buf[ 1] = i4 + t1;
152 buf[ 8] = r4 - t0;
153 buf[ 9] = i4 - t1;
154 buf[ 4] = r5 + t3;
155 buf[ 5] = i5 - t2;
156 buf[12] = r5 - t3;
157 buf[13] = i5 + t2;
158
159 r0 = r1 - i3;
160 i0 = i1 + r3;
161 r2 = r1 + i3;
162 i2 = i1 - r3;
163
164 t0 = MULHIGH(SQRT1_2, r0 - i0);
165 t1 = MULHIGH(SQRT1_2, r0 + i0);
166 t2 = MULHIGH(SQRT1_2, r2 - i2);
167 t3 = MULHIGH(SQRT1_2, r2 + i2);
168
169 buf[ 6] = r6 - t0;
170 buf[ 7] = i6 - t1;
171 buf[14] = r6 + t0;
172 buf[15] = i6 + t1;
173 buf[ 2] = r7 + t3;
174 buf[ 3] = i7 - t2;
175 buf[10] = r7 - t3;
176 buf[11] = i7 + t2;
177
178 buf += 16;
179 }
180}
181
James Dong17299ab2010-05-14 15:45:22 -0700182/*****************************************************************************
183*
184* function name: Radix4FFT
185* description: Radix 4 point fft core function
186*
Mans Rullgard219e2622011-04-22 09:22:33 +0300187**********************************************************************************/
188static void Radix4FFT(int *buf, int num, int bgn, int *twidTab)
189{
190 int r0, r1, r2, r3;
191 int r4, r5, r6, r7;
192 int t0, t1;
193 int sinx, cosx;
194 int i, j, step;
195 int *xptr, *csptr;
196
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300197 for (num >>= 2; num != 0; num >>= 2)
Mans Rullgard219e2622011-04-22 09:22:33 +0300198 {
199 step = 2*bgn;
200 xptr = buf;
201
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300202 for (i = num; i != 0; i--)
Mans Rullgard219e2622011-04-22 09:22:33 +0300203 {
204 csptr = twidTab;
205
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300206 for (j = bgn; j != 0; j--)
Mans Rullgard219e2622011-04-22 09:22:33 +0300207 {
208 r0 = xptr[0];
209 r1 = xptr[1];
210 xptr += step;
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300211
Mans Rullgard219e2622011-04-22 09:22:33 +0300212 t0 = xptr[0];
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300213 t1 = xptr[1];
Mans Rullgard219e2622011-04-22 09:22:33 +0300214 cosx = csptr[0];
215 sinx = csptr[1];
216 r2 = MULHIGH(cosx, t0) + MULHIGH(sinx, t1); /* cos*br + sin*bi */
217 r3 = MULHIGH(cosx, t1) - MULHIGH(sinx, t0); /* cos*bi - sin*br */
218 xptr += step;
219
220 t0 = r0 >> 2;
221 t1 = r1 >> 2;
222 r0 = t0 - r2;
223 r1 = t1 - r3;
224 r2 = t0 + r2;
225 r3 = t1 + r3;
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300226
Mans Rullgard219e2622011-04-22 09:22:33 +0300227 t0 = xptr[0];
228 t1 = xptr[1];
229 cosx = csptr[2];
230 sinx = csptr[3];
231 r4 = MULHIGH(cosx, t0) + MULHIGH(sinx, t1); /* cos*cr + sin*ci */
232 r5 = MULHIGH(cosx, t1) - MULHIGH(sinx, t0); /* cos*ci - sin*cr */
233 xptr += step;
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300234
Mans Rullgard219e2622011-04-22 09:22:33 +0300235 t0 = xptr[0];
236 t1 = xptr[1];
237 cosx = csptr[4];
238 sinx = csptr[5];
239 r6 = MULHIGH(cosx, t0) + MULHIGH(sinx, t1); /* cos*cr + sin*ci */
240 r7 = MULHIGH(cosx, t1) - MULHIGH(sinx, t0); /* cos*ci - sin*cr */
241 csptr += 6;
242
243 t0 = r4;
244 t1 = r5;
245 r4 = t0 + r6;
246 r5 = r7 - t1;
247 r6 = t0 - r6;
248 r7 = r7 + t1;
249
250 xptr[0] = r0 + r5;
251 xptr[1] = r1 + r6;
252 xptr -= step;
253
254 xptr[0] = r2 - r4;
255 xptr[1] = r3 - r7;
256 xptr -= step;
257
258 xptr[0] = r0 - r5;
259 xptr[1] = r1 - r6;
260 xptr -= step;
261
262 xptr[0] = r2 + r4;
263 xptr[1] = r3 + r7;
264 xptr += 2;
265 }
266 xptr += 3*step;
267 }
268 twidTab += 3*step;
269 bgn <<= 2;
270 }
271}
272
James Dong17299ab2010-05-14 15:45:22 -0700273/*********************************************************************************
274*
275* function name: PreMDCT
276* description: prepare MDCT process for next FFT compute
277*
Mans Rullgard219e2622011-04-22 09:22:33 +0300278**********************************************************************************/
279static void PreMDCT(int *buf0, int num, const int *csptr)
280{
281 int i;
282 int tr1, ti1, tr2, ti2;
283 int cosa, sina, cosb, sinb;
284 int *buf1;
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300285
Mans Rullgard219e2622011-04-22 09:22:33 +0300286 buf1 = buf0 + num - 1;
287
288 for(i = num >> 2; i != 0; i--)
289 {
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300290 cosa = *csptr++;
291 sina = *csptr++;
292 cosb = *csptr++;
293 sinb = *csptr++;
Mans Rullgard219e2622011-04-22 09:22:33 +0300294
295 tr1 = *(buf0 + 0);
296 ti2 = *(buf0 + 1);
297 tr2 = *(buf1 - 1);
298 ti1 = *(buf1 + 0);
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300299
Mans Rullgard219e2622011-04-22 09:22:33 +0300300 *buf0++ = MULHIGH(cosa, tr1) + MULHIGH(sina, ti1);
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300301 *buf0++ = MULHIGH(cosa, ti1) - MULHIGH(sina, tr1);
302
303 *buf1-- = MULHIGH(cosb, ti2) - MULHIGH(sinb, tr2);
Mans Rullgard219e2622011-04-22 09:22:33 +0300304 *buf1-- = MULHIGH(cosb, tr2) + MULHIGH(sinb, ti2);
305 }
306}
307
James Dong17299ab2010-05-14 15:45:22 -0700308/*********************************************************************************
309*
310* function name: PostMDCT
311* description: post MDCT process after next FFT for MDCT
312*
Mans Rullgard219e2622011-04-22 09:22:33 +0300313**********************************************************************************/
314static void PostMDCT(int *buf0, int num, const int *csptr)
315{
316 int i;
317 int tr1, ti1, tr2, ti2;
318 int cosa, sina, cosb, sinb;
319 int *buf1;
320
321 buf1 = buf0 + num - 1;
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300322
Mans Rullgard219e2622011-04-22 09:22:33 +0300323 for(i = num >> 2; i != 0; i--)
324 {
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300325 cosa = *csptr++;
326 sina = *csptr++;
327 cosb = *csptr++;
Mans Rullgard219e2622011-04-22 09:22:33 +0300328 sinb = *csptr++;
329
330 tr1 = *(buf0 + 0);
331 ti1 = *(buf0 + 1);
332 ti2 = *(buf1 + 0);
333 tr2 = *(buf1 - 1);
334
335 *buf0++ = MULHIGH(cosa, tr1) + MULHIGH(sina, ti1);
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300336 *buf1-- = MULHIGH(sina, tr1) - MULHIGH(cosa, ti1);
337
Mans Rullgard219e2622011-04-22 09:22:33 +0300338 *buf0++ = MULHIGH(sinb, tr2) - MULHIGH(cosb, ti2);
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300339 *buf1-- = MULHIGH(cosb, tr2) + MULHIGH(sinb, ti2);
Mans Rullgard219e2622011-04-22 09:22:33 +0300340 }
341}
342#endif
343
344
James Dong17299ab2010-05-14 15:45:22 -0700345/**********************************************************************************
346*
347* function name: Mdct_Long
348* description: the long block mdct, include long_start block, end_long block
349*
Mans Rullgard219e2622011-04-22 09:22:33 +0300350**********************************************************************************/
351void Mdct_Long(int *buf)
352{
353 PreMDCT(buf, 1024, cossintab + 128);
354
355 Shuffle(buf, 512, bitrevTab + 17);
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300356 Radix8First(buf, 512 >> 3);
Mans Rullgard219e2622011-04-22 09:22:33 +0300357 Radix4FFT(buf, 512 >> 3, 8, (int *)twidTab512);
358
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300359 PostMDCT(buf, 1024, cossintab + 128);
Mans Rullgard219e2622011-04-22 09:22:33 +0300360}
361
362
James Dong17299ab2010-05-14 15:45:22 -0700363/**********************************************************************************
364*
365* function name: Mdct_Short
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300366* description: the short block mdct
James Dong17299ab2010-05-14 15:45:22 -0700367*
Mans Rullgard219e2622011-04-22 09:22:33 +0300368**********************************************************************************/
369void Mdct_Short(int *buf)
370{
371 PreMDCT(buf, 128, cossintab);
372
373 Shuffle(buf, 64, bitrevTab);
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300374 Radix4First(buf, 64 >> 2);
375 Radix4FFT(buf, 64 >> 2, 4, (int *)twidTab64);
Mans Rullgard219e2622011-04-22 09:22:33 +0300376
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300377 PostMDCT(buf, 128, cossintab);
Mans Rullgard219e2622011-04-22 09:22:33 +0300378}
James Dong17299ab2010-05-14 15:45:22 -0700379
380
381/*****************************************************************************
382*
383* function name: shiftMdctDelayBuffer
384* description: the mdct delay buffer has a size of 1600,
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300385* so the calculation of LONG,STOP must be spilt in two
James Dong17299ab2010-05-14 15:45:22 -0700386* passes with 1024 samples and a mid shift,
387* the SHORT transforms can be completed in the delay buffer,
388* and afterwards a shift
389*
390**********************************************************************************/
391static void shiftMdctDelayBuffer(Word16 *mdctDelayBuffer, /*! start of mdct delay buffer */
392 Word16 *timeSignal, /*! pointer to new time signal samples, interleaved */
393 Word16 chIncrement /*! number of channels */
394 )
395{
396 Word32 i;
397 Word16 *srBuf = mdctDelayBuffer;
398 Word16 *dsBuf = mdctDelayBuffer+FRAME_LEN_LONG;
399
400 for(i = 0; i < BLOCK_SWITCHING_OFFSET-FRAME_LEN_LONG; i+= 8)
401 {
402 *srBuf++ = *dsBuf++; *srBuf++ = *dsBuf++;
403 *srBuf++ = *dsBuf++; *srBuf++ = *dsBuf++;
404 *srBuf++ = *dsBuf++; *srBuf++ = *dsBuf++;
405 *srBuf++ = *dsBuf++; *srBuf++ = *dsBuf++;
406 }
407
408 srBuf = mdctDelayBuffer + BLOCK_SWITCHING_OFFSET-FRAME_LEN_LONG;
409 dsBuf = timeSignal;
410
411 for(i=0; i<FRAME_LEN_LONG; i+=8)
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300412 {
James Dong17299ab2010-05-14 15:45:22 -0700413 *srBuf++ = *dsBuf; dsBuf += chIncrement;
414 *srBuf++ = *dsBuf; dsBuf += chIncrement;
415 *srBuf++ = *dsBuf; dsBuf += chIncrement;
416 *srBuf++ = *dsBuf; dsBuf += chIncrement;
417 *srBuf++ = *dsBuf; dsBuf += chIncrement;
418 *srBuf++ = *dsBuf; dsBuf += chIncrement;
419 *srBuf++ = *dsBuf; dsBuf += chIncrement;
420 *srBuf++ = *dsBuf; dsBuf += chIncrement;
421 }
Mans Rullgard219e2622011-04-22 09:22:33 +0300422}
423
424
James Dong17299ab2010-05-14 15:45:22 -0700425/*****************************************************************************
426*
427* function name: getScalefactorOfShortVectorStride
428* description: Calculate max possible scale factor for input vector of shorts
429* returns: Maximum scale factor
430*
Mans Rullgard219e2622011-04-22 09:22:33 +0300431**********************************************************************************/
432static Word16 getScalefactorOfShortVectorStride(const Word16 *vector, /*!< Pointer to input vector */
433 Word16 len, /*!< Length of input vector */
434 Word16 stride) /*!< Stride of input vector */
435{
436 Word16 maxVal = 0;
437 Word16 absVal;
438 Word16 i;
439
440 for(i=0; i<len; i++){
441 absVal = abs_s(vector[i*stride]);
442 maxVal |= absVal;
443 }
444
445 return( maxVal ? norm_s(maxVal) : 15);
446}
James Dong17299ab2010-05-14 15:45:22 -0700447
448
449/*****************************************************************************
450*
451* function name: Transform_Real
452* description: Calculate transform filter for input vector of shorts
453* returns: TRUE if success
454*
455**********************************************************************************/
456void Transform_Real(Word16 *mdctDelayBuffer,
457 Word16 *timeSignal,
458 Word16 chIncrement,
459 Word32 *realOut,
460 Word16 *mdctScale,
461 Word16 blockType
462 )
463{
464 Word32 i,w;
465 Word32 timeSignalSample;
466 Word32 ws1,ws2;
Mans Rullgard219e2622011-04-22 09:22:33 +0300467 Word16 *dctIn0, *dctIn1;
468 Word32 *outData0, *outData1;
James Dong17299ab2010-05-14 15:45:22 -0700469 Word32 *winPtr;
470
471 Word32 delayBufferSf,timeSignalSf,minSf;
472 Word32 headRoom=0;
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300473
James Dong17299ab2010-05-14 15:45:22 -0700474 switch(blockType){
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300475
476
James Dong17299ab2010-05-14 15:45:22 -0700477 case LONG_WINDOW:
478 /*
479 we access BLOCK_SWITCHING_OFFSET (1600 ) delay buffer samples + 448 new timeSignal samples
480 and get the biggest scale factor for next calculate more precise
481 */
482 delayBufferSf = getScalefactorOfShortVectorStride(mdctDelayBuffer,BLOCK_SWITCHING_OFFSET,1);
483 timeSignalSf = getScalefactorOfShortVectorStride(timeSignal,2*FRAME_LEN_LONG-BLOCK_SWITCHING_OFFSET,chIncrement);
484 minSf = min(delayBufferSf,timeSignalSf);
485 minSf = min(minSf,14);
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300486
James Dong17299ab2010-05-14 15:45:22 -0700487 dctIn0 = mdctDelayBuffer;
488 dctIn1 = mdctDelayBuffer + FRAME_LEN_LONG - 1;
489 outData0 = realOut + FRAME_LEN_LONG/2;
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300490
James Dong17299ab2010-05-14 15:45:22 -0700491 /* add windows and pre add for mdct to last buffer*/
492 winPtr = (int *)LongWindowKBD;
493 for(i=0;i<FRAME_LEN_LONG/2;i++){
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300494 timeSignalSample = (*dctIn0++) << minSf;
James Dong17299ab2010-05-14 15:45:22 -0700495 ws1 = timeSignalSample * (*winPtr >> 16);
496 timeSignalSample = (*dctIn1--) << minSf;
497 ws2 = timeSignalSample * (*winPtr & 0xffff);
498 winPtr ++;
499 /* shift 2 to avoid overflow next */
500 *outData0++ = (ws1 >> 2) - (ws2 >> 2);
501 }
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300502
James Dong17299ab2010-05-14 15:45:22 -0700503 shiftMdctDelayBuffer(mdctDelayBuffer,timeSignal,chIncrement);
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300504
James Dong17299ab2010-05-14 15:45:22 -0700505 /* add windows and pre add for mdct to new buffer*/
506 dctIn0 = mdctDelayBuffer;
507 dctIn1 = mdctDelayBuffer + FRAME_LEN_LONG - 1;
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300508 outData0 = realOut + FRAME_LEN_LONG/2 - 1;
James Dong17299ab2010-05-14 15:45:22 -0700509 winPtr = (int *)LongWindowKBD;
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300510 for(i=0;i<FRAME_LEN_LONG/2;i++){
James Dong17299ab2010-05-14 15:45:22 -0700511 timeSignalSample = (*dctIn0++) << minSf;
512 ws1 = timeSignalSample * (*winPtr & 0xffff);
513 timeSignalSample = (*dctIn1--) << minSf;
514 ws2 = timeSignalSample * (*winPtr >> 16);
515 winPtr++;
516 /* shift 2 to avoid overflow next */
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300517 *outData0-- = -((ws1 >> 2) + (ws2 >> 2));
James Dong17299ab2010-05-14 15:45:22 -0700518 }
519
Mans Rullgard219e2622011-04-22 09:22:33 +0300520 Mdct_Long(realOut);
521 /* update scale factor */
James Dong17299ab2010-05-14 15:45:22 -0700522 minSf = 14 - minSf;
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300523 *mdctScale=minSf;
James Dong17299ab2010-05-14 15:45:22 -0700524 break;
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300525
James Dong17299ab2010-05-14 15:45:22 -0700526 case START_WINDOW:
527 /*
528 we access BLOCK_SWITCHING_OFFSET (1600 ) delay buffer samples + no timeSignal samples
529 and get the biggest scale factor for next calculate more precise
530 */
531 minSf = getScalefactorOfShortVectorStride(mdctDelayBuffer,BLOCK_SWITCHING_OFFSET,1);
532 minSf = min(minSf,14);
533
534 dctIn0 = mdctDelayBuffer;
535 dctIn1 = mdctDelayBuffer + FRAME_LEN_LONG - 1;
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300536 outData0 = realOut + FRAME_LEN_LONG/2;
James Dong17299ab2010-05-14 15:45:22 -0700537 winPtr = (int *)LongWindowKBD;
538
539 /* add windows and pre add for mdct to last buffer*/
540 for(i=0;i<FRAME_LEN_LONG/2;i++){
541 timeSignalSample = (*dctIn0++) << minSf;
542 ws1 = timeSignalSample * (*winPtr >> 16);
543 timeSignalSample = (*dctIn1--) << minSf;
544 ws2 = timeSignalSample * (*winPtr & 0xffff);
545 winPtr ++;
Mans Rullgard219e2622011-04-22 09:22:33 +0300546 *outData0++ = (ws1 >> 2) - (ws2 >> 2); /* shift 2 to avoid overflow next */
James Dong17299ab2010-05-14 15:45:22 -0700547 }
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300548
James Dong17299ab2010-05-14 15:45:22 -0700549 shiftMdctDelayBuffer(mdctDelayBuffer,timeSignal,chIncrement);
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300550
551 outData0 = realOut + FRAME_LEN_LONG/2 - 1;
James Dong17299ab2010-05-14 15:45:22 -0700552 for(i=0;i<LS_TRANS;i++){
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300553 *outData0-- = -mdctDelayBuffer[i] << (15 - 2 + minSf);
James Dong17299ab2010-05-14 15:45:22 -0700554 }
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300555
James Dong17299ab2010-05-14 15:45:22 -0700556 /* add windows and pre add for mdct to new buffer*/
557 dctIn0 = mdctDelayBuffer + LS_TRANS;
558 dctIn1 = mdctDelayBuffer + FRAME_LEN_LONG - 1 - LS_TRANS;
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300559 outData0 = realOut + FRAME_LEN_LONG/2 - 1 -LS_TRANS;
James Dong17299ab2010-05-14 15:45:22 -0700560 winPtr = (int *)ShortWindowSine;
561 for(i=0;i<FRAME_LEN_SHORT/2;i++){
562 timeSignalSample= (*dctIn0++) << minSf;
563 ws1 = timeSignalSample * (*winPtr & 0xffff);
564 timeSignalSample= (*dctIn1--) << minSf;
565 ws2 = timeSignalSample * (*winPtr >> 16);
566 winPtr++;
Mans Rullgard219e2622011-04-22 09:22:33 +0300567 *outData0-- = -((ws1 >> 2) + (ws2 >> 2)); /* shift 2 to avoid overflow next */
James Dong17299ab2010-05-14 15:45:22 -0700568 }
569
570 Mdct_Long(realOut);
571 /* update scale factor */
572 minSf = 14 - minSf;
573 *mdctScale= minSf;
574 break;
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300575
James Dong17299ab2010-05-14 15:45:22 -0700576 case STOP_WINDOW:
577 /*
578 we access BLOCK_SWITCHING_OFFSET-LS_TRANS (1600-448 ) delay buffer samples + 448 new timeSignal samples
579 and get the biggest scale factor for next calculate more precise
580 */
581 delayBufferSf = getScalefactorOfShortVectorStride(mdctDelayBuffer+LS_TRANS,BLOCK_SWITCHING_OFFSET-LS_TRANS,1);
582 timeSignalSf = getScalefactorOfShortVectorStride(timeSignal,2*FRAME_LEN_LONG-BLOCK_SWITCHING_OFFSET,chIncrement);
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300583 minSf = min(delayBufferSf,timeSignalSf);
James Dong17299ab2010-05-14 15:45:22 -0700584 minSf = min(minSf,13);
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300585
James Dong17299ab2010-05-14 15:45:22 -0700586 outData0 = realOut + FRAME_LEN_LONG/2;
587 dctIn1 = mdctDelayBuffer + FRAME_LEN_LONG - 1;
588 for(i=0;i<LS_TRANS;i++){
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300589 *outData0++ = -(*dctIn1--) << (15 - 2 + minSf);
James Dong17299ab2010-05-14 15:45:22 -0700590 }
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300591
James Dong17299ab2010-05-14 15:45:22 -0700592 /* add windows and pre add for mdct to last buffer*/
593 dctIn0 = mdctDelayBuffer + LS_TRANS;
594 dctIn1 = mdctDelayBuffer + FRAME_LEN_LONG - 1 - LS_TRANS;
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300595 outData0 = realOut + FRAME_LEN_LONG/2 + LS_TRANS;
James Dong17299ab2010-05-14 15:45:22 -0700596 winPtr = (int *)ShortWindowSine;
597 for(i=0;i<FRAME_LEN_SHORT/2;i++){
598 timeSignalSample = (*dctIn0++) << minSf;
599 ws1 = timeSignalSample * (*winPtr >> 16);
600 timeSignalSample= (*dctIn1--) << minSf;
601 ws2 = timeSignalSample * (*winPtr & 0xffff);
602 winPtr++;
Mans Rullgard219e2622011-04-22 09:22:33 +0300603 *outData0++ = (ws1 >> 2) - (ws2 >> 2); /* shift 2 to avoid overflow next */
James Dong17299ab2010-05-14 15:45:22 -0700604 }
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300605
James Dong17299ab2010-05-14 15:45:22 -0700606 shiftMdctDelayBuffer(mdctDelayBuffer,timeSignal,chIncrement);
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300607
James Dong17299ab2010-05-14 15:45:22 -0700608 /* add windows and pre add for mdct to new buffer*/
609 dctIn0 = mdctDelayBuffer;
610 dctIn1 = mdctDelayBuffer + FRAME_LEN_LONG - 1;
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300611 outData0 = realOut + FRAME_LEN_LONG/2 - 1;
James Dong17299ab2010-05-14 15:45:22 -0700612 winPtr = (int *)LongWindowKBD;
613 for(i=0;i<FRAME_LEN_LONG/2;i++){
614 timeSignalSample= (*dctIn0++) << minSf;
615 ws1 = timeSignalSample *(*winPtr & 0xffff);
616 timeSignalSample= (*dctIn1--) << minSf;
617 ws2 = timeSignalSample * (*winPtr >> 16);
Mans Rullgard219e2622011-04-22 09:22:33 +0300618 *outData0-- = -((ws1 >> 2) + (ws2 >> 2)); /* shift 2 to avoid overflow next */
619 winPtr++;
James Dong17299ab2010-05-14 15:45:22 -0700620 }
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300621
James Dong17299ab2010-05-14 15:45:22 -0700622 Mdct_Long(realOut);
623 minSf = 14 - minSf;
624 *mdctScale= minSf; /* update scale factor */
625 break;
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300626
James Dong17299ab2010-05-14 15:45:22 -0700627 case SHORT_WINDOW:
628 /*
629 we access BLOCK_SWITCHING_OFFSET (1600 ) delay buffer samples + no new timeSignal samples
630 and get the biggest scale factor for next calculate more precise
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300631 */
James Dong17299ab2010-05-14 15:45:22 -0700632 minSf = getScalefactorOfShortVectorStride(mdctDelayBuffer+TRANSFORM_OFFSET_SHORT,9*FRAME_LEN_SHORT,1);
633 minSf = min(minSf,10);
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300634
635
James Dong17299ab2010-05-14 15:45:22 -0700636 for(w=0;w<TRANS_FAC;w++){
637 dctIn0 = mdctDelayBuffer+w*FRAME_LEN_SHORT+TRANSFORM_OFFSET_SHORT;
638 dctIn1 = mdctDelayBuffer+w*FRAME_LEN_SHORT+TRANSFORM_OFFSET_SHORT + FRAME_LEN_SHORT-1;
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300639 outData0 = realOut + FRAME_LEN_SHORT/2;
640 outData1 = realOut + FRAME_LEN_SHORT/2 - 1;
James Dong17299ab2010-05-14 15:45:22 -0700641
642 winPtr = (int *)ShortWindowSine;
643 for(i=0;i<FRAME_LEN_SHORT/2;i++){
644 timeSignalSample= *dctIn0 << minSf;
645 ws1 = timeSignalSample * (*winPtr >> 16);
646 timeSignalSample= *dctIn1 << minSf;
647 ws2 = timeSignalSample * (*winPtr & 0xffff);
Mans Rullgard219e2622011-04-22 09:22:33 +0300648 *outData0++ = (ws1 >> 2) - (ws2 >> 2); /* shift 2 to avoid overflow next */
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300649
James Dong17299ab2010-05-14 15:45:22 -0700650 timeSignalSample= *(dctIn0 + FRAME_LEN_SHORT) << minSf;
651 ws1 = timeSignalSample * (*winPtr & 0xffff);
652 timeSignalSample= *(dctIn1 + FRAME_LEN_SHORT) << minSf;
653 ws2 = timeSignalSample * (*winPtr >> 16);
Mans Rullgard219e2622011-04-22 09:22:33 +0300654 *outData1-- = -((ws1 >> 2) + (ws2 >> 2)); /* shift 2 to avoid overflow next */
655
656 winPtr++;
657 dctIn0++;
658 dctIn1--;
James Dong17299ab2010-05-14 15:45:22 -0700659 }
660
661 Mdct_Short(realOut);
662 realOut += FRAME_LEN_SHORT;
663 }
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300664
James Dong17299ab2010-05-14 15:45:22 -0700665 minSf = 11 - minSf;
666 *mdctScale = minSf; /* update scale factor */
Mans Rullgard62a62ef2011-04-05 17:40:06 +0300667
James Dong17299ab2010-05-14 15:45:22 -0700668 shiftMdctDelayBuffer(mdctDelayBuffer,timeSignal,chIncrement);
669 break;
670 }
671}
672