1/* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
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
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18/*
19
20  Pathname: trans4m_freq_2_time_fxp.c
21  Function: trans4m_freq_2_time_fxp
22
23
24------------------------------------------------------------------------------
25 REVISION HISTORY
26
27 Description:
28    changed to decrement loop
29    change wnd_shape from structure to passing parameters
30    modified window tables from UInt to UInt16 to assure proper operation
31    without dubious typecast
32    changed logic to hit most common states first.
33    modified Time_data from Int to Int32 to hold
34    possible overflow before saturation process.
35
36 Description:
37    Increase processing on some loop by using more pointers
38    changed interface to avoid passing a pointer for wnd_shape_prev_bk, this
39    element is not change in this function because of this function use
40    in the LTP module
41
42 Description:
43    Added rounding to multiplication
44
45 Description:
46    Update input description and eliminate unneeded comments
47
48 Description:
49    LONG_START_WINDOW was using SHORT_WINDOW instead of
50    HALF_SHORT_WINDOW, causing a for loop to exceed its count
51
52 Description:
53    Modified structure of code so exp is not tested before it
54    is initialized.  Also, new structure avoids double-testing
55    of exp_freq = ALL_ZEROS_BUFFER.
56
57 Description:
58    The result of a shift is undefined if the right operand is greater than
59    or equal to the number of bits in the left expression's type
60    To avoid undefined shift by 32, a check of the shift has been
61    added, so the function proceeds only when the exponent is less
62    than 32. By design the shift up is related to the global gain,
63    and controlled by the encoder, so saturation is not allowed.
64    In both short and long window, processing is skip if an all zero
65    input buffer or excessive down shift is detected.
66
67 Description:
68    Changes according to code review comments. Also, modified if-else
69    structure so the imdct_fxp is not called with an all zero input buffer
70
71 Description:
72    Replaced function buffer_normalization by buffer_adaptation, to ease
73    use of 16 bits. Function buffer_normalization becomes  obsolete.
74
75 Description:
76    Modified call to imdct_fxp to reflect extended precision use. Added
77    routine buffer_adaptation to extract 16 MSB and keep highest.
78    precision. Modify casting to ensure proper operations for different
79    platforms
80
81 Description:
82    Eliminate double access to memory by loading data directly to the
83    time array. Also reduced cycle count and added precision by combining
84    downshifting in only one operation. Added adaptive rounding factor.
85    Change exponent threshold when operations are waived. It is use to be 32
86    but by combining downshifting, this new threshold is now 16. This may
87    avoid unneeded calculations for extremely small numbers.
88
89 Description:
90    Per review comments:
91        - Added comments to clarify buffer_adaptation function
92        - Deleted  reference to include file "buffer_normalization.h"
93        - Modified IF-ELSE so long_windows case is considered first
94        - Eliminated extra IF when computing the rounding, so when exp ==0
95          less cycles are used shifting than in an extra if-else
96        - Corrected negative shift when computing rounding factor
97        - Added condition when exp > 16 (for long windows)
98
99 Description:
100    Modified IF-ELSE structure so now ALL_ZEROS_BUFFER condition is share
101    with exp > 16 condition. This avoid code duplication for both cases.
102
103 Description:
104        - Modified function interface to add output_buffer
105        - Eliminated the 32 bit version of the current output, calculations
106          are placed directly in output_buffer. In this way the buffer
107          Time_data needs only to be 1024 Int32, instead of 2048 (per channel).
108          Also, added the limit macro inside the function (this reduces access
109          to memory).
110        - Updated Pseudo - Code
111
112 Description:
113    Per review comments:
114          Corrected line sizes and mispelling,  added comments and swap
115          order or switch statement for ONLY_LONG_SEQUENCE.
116
117 Description:
118    Eliminated adaptive rounding due to potential saturation.
119
120 Description:
121    Eliminated use of buffer adaptation by shifting this functionality inside
122    the imdct_fxp() routine. Also modified the call to imdct_fxp to accomodate
123    new function interface.
124    Modified macro limit() to save cycles when testing the most common case:
125    no saturation.
126
127 Description:
128    Changed new function interface for imdct_fxp().
129
130 Description:
131    Replaced for-loop with memset and memcopy.
132
133 Who:                         Date:
134 Description:
135
136------------------------------------------------------------------------------
137 INPUT AND OUTPUT DEFINITIONS
138
139 Inputs:
140    Frequency_data    =  vector with spectral information, size 2048
141                         type Int32
142
143    Time_data         =  buffer with data from previous Frequency to Time
144                         conversion, used for overlap and add, size 1024
145                         type Int32
146
147    Output_buffer     =  place holder for current output,  size 1024
148                         type Int16
149
150    wnd_seq           =  window sequence
151                         type WINDOW_SEQUENCE
152
153    wnd_shape_prev_bk =  previous window shape type
154                         type Int
155
156    wnd_shape_this_bk =  current window shape type
157                         type Int
158
159    Q_format          =  Q format for the input frequency data
160                         type Int
161
162    freq_2_time_buffer[] =  scratch memory for computing FFT
163                         type Int32
164
165
166 Local Stores/Buffers/Pointers Needed:
167    None
168
169 Global Stores/Buffers/Pointers Needed:
170    None
171
172 Outputs:
173    None
174
175 Pointers and Buffers Modified:
176    Output_buffer
177    Time_data
178    Frequency_data
179    pWnd_shape_prev_bk
180
181 Local Stores Modified:
182    None
183
184 Global Stores Modified:
185    None
186
187------------------------------------------------------------------------------
188 FUNCTION DESCRIPTION
189
190The time/frequency representation of the signal is mapped onto the time
191domain by feeding it into the filterbank module. This module consists of
192an inverse modified discrete cosine transform (IMDCT), and a window and an
193overlap-add function. In order to adapt the time/frequency resolution of the
194filterbank to the characteristics of the input signal, a block switching tool
195is also adopted. N represents the window length, where N is a function of the
196window_sequence. For each channel, the N/2 time-frequency values are
197transformed into the N time domain values via the IMDCT. After applying the
198window function, for each channel, the first half of the sequence is added to
199the second half of the previous block windowed sequence to reconstruct the
200output samples for each channel outi,n.
201
202The adaptation of the time-frequency resolution of the filterbank to the
203characteristics of the input signal is done by shifting between transforms
204whose input lengths are either 2048 or 256 samples. By enabling the block
205switching tool, the following transitions are meaningful:
206
207from ONLY_LONG_SEQUENCE to   { LONG_START_SEQUENCE
208                               ONLY_LONG_SEQUENCE
209
210from LONG_START_SEQUENCE to  { LONG_STOP_SEQUENCE
211                               EIGHT_SHORT_SEQUENCE
212
213from LONG_STOP_SEQUENCE to   { LONG_START_SEQUENCE
214                               ONLY_LONG_SEQUENCE
215
216from EIGHT_SHORT_SEQUENCE to { LONG_STOP_SEQUENCE
217                               EIGHT_SHORT_SEQUENCE
218
219Window shape decisions are made by the encoder on a frame-by-frame-basis.
220The window selected is applicable to the second half of the window function
221only, since the first half is constrained to use the appropriate window
222shape from the preceding frame.
223The 2048 time-domain values x'(i)(n), (i window, n sample) to be windowed are
224the last 1024 values of the previous window_sequence concatenated with 1024
225values of the current block. The formula below shows this fact:
226
227                     |  x(i-1)(n+1024)      for    0 < n < 1024
228            x'(i)(n) {
229                     |  x(i)(n)             for 1024 < n < 2048
230
231
232Buffer Time_data data from previous Frequency to Time conversion, used
233for overlap and add
234
235Once the window shape is selected, the window_shape syntax element is
236initialized. Together with the chosen window_sequence all information needed
237for windowing exist.
238With the window halves described below all window_sequences can be assembled.
239For window_shape == 1, the window coefficients are given by the Kaiser -
240Bessel derived (KBD) window.
241Otherwise, for window_shape == 0, a sine window is employed.
242
243The window length N can be 2048 or 256 for the KBD and the sine window.
244All four window_sequences explained below have a total length of 2048
245samples.
246For all kinds of window_sequences the window_shape of the left half of
247the first transform window is determined by the window shape of the previous
248block.
249
250In the case of EIGHT_SHORT_SEQUENCE the processing is done in-place and
251in descendent order to avoid using extra memory.
252The ordering is as follows:
253
254                                            Pn: Previous data for window n
255                                            Cn:  Current data for window n
256
257
258                                                128 freq.
259                                                 samples
260                  FREQ                          ++++++
261IN                         ===========================
262                                                    \
263                                                      \
264                                                        ->  256 time
265                                                             samples
266
267                                                           P8    C8
268           8                                            #######++++++
269                                                    P7     C7
270           7                                     #######++++++
271           :                                :
272           :                                :
273                            P2    C2
274           2             #######++++++
275                     P1    C1
276           1      #######++++++
277                                                                          TIME
278OUT          ==============================================================
279
280------------------------------------------------------------------------------
281 REQUIREMENTS
282
283    This module shall implement a scheme to switch between window types
284
285------------------------------------------------------------------------------
286 REFERENCES
287
288    [1] ISO 14496-3:1999, pag 111
289
290------------------------------------------------------------------------------
291 PSEUDO-CODE
292
293
294
295    IF ( wnd_seq == EIGHT_SHORT_SEQUENCE)
296    THEN
297
298        FOR ( i=0; i<LONG_WINDOW; i++)
299            Time_data[LONG_WINDOW + i] = 0;
300        ENDFOR
301
302        FOR ( wnd=NUM_SHORT_WINDOWS-1; wnd>=0; wnd--)
303
304            pFreqInfo = &Frequency_data[ wnd*SHORT_WINDOW];
305
306            CALL IMDCT( pFreqInfo, SHORT_BLOCK1);
307            MODIFYING(pFreqInfo)
308
309
310            IF (wnd == 0)
311            THEN
312                pShort_Window_1 = &Short_Window[wnd_shape_prev_bk][0];
313            ELSE
314                pShort_Window_1 = &Short_Window[wnd_shape_this_bk][0];
315            ENDIF
316
317            pShort_Window_2   =
318                    &Short_Window[wnd_shape->this_bk][SHORT_WINDOW_m_1];
319
320            FOR( i=0, j=SHORT_WINDOW; i<SHORT_WINDOW; i++, j--)
321                pFreqInfo[             i]  *= pShort_Window_1[i];
322                pFreqInfo[SHORT_WINDOW+i]  *= pShort_Window_2[j];
323            ENDFOR
324
325
326            FOR( i=0; i<SHORT_BLOCK1; i++)
327                Time_data[W_L_STOP_1 + SHORT_WINDOW*wnd + i] += pFreqInfo[i];
328            ENDFOR
329
330        ENDFOR
331
332        FOR ( i=0; i<LONG_WINDOW; i++)
333            temp              = Time_data[i];
334            Output_buffer[i]  = Time_data[i];
335            Time_data[i]      = temp;
336        ENDFOR
337    ELSE
338
339        CALL IMDCT( Frequency_data, LONG_BLOCK1)
340            MODIFYING(Frequency_data)
341
342        SWITCH ( wnd_seq)
343
344            CASE ( ONLY_LONG_SEQUENCE)
345
346                pLong_Window_1 = &Long_Window[wnd_shape_prev_bk][0];
347                pLong_Window_2 =
348                        &Long_Window[wnd_shape_this_bk][LONG_WINDOW_m_1];
349
350                FOR (i=0; i<LONG_WINDOW; i++)
351                    Frequency_data[            i] *= *pLong_Window_1++;
352                    Frequency_data[LONG_WINDOW+i] *= *pLong_Window_2--;
353                ENDFOR
354
355                BREAK
356
357            CASE ( LONG_START_SEQUENCE)
358
359                pLong_Window_1 = &Long_Window[wnd_shape_prev_bk][0];
360
361                FOR ( i=0; i<LONG_WINDOW; i++)
362                    Frequency_data[ i] *= *pLong_Window_1++;
363                ENDFOR
364
365                pShort_Window_1   =
366                        &Short_Window[wnd_shape_this_bk][SHORT_WINDOW_m_1];
367
368                FOR ( i=0; i<SHORT_WINDOW; i++)
369                    Frequency_data[W_L_START_1 + i] *= *pShort_Window_1--;
370                ENDFOR
371
372                FOR ( i=W_L_START_2; i<LONG_BLOCK1; i++)
373                    Frequency_data[W_L_START_2 + i] = 0;
374                ENDFOR
375
376                BREAK
377
378
379            CASE ( LONG_STOP_SEQUENCE )
380
381                FOR ( i=0; i<W_L_STOP_1; i++)
382                    Frequency_data[ i] = 0;
383                ENDFOR
384
385                pShort_Window_1   = &Short_Window[wnd_shape_prev_bk][0];
386
387                FOR ( i=0; i<SHORT_WINDOW; i++)
388                    Frequency_data[W_L_STOP_1+ i] *= *pShort_Window_1++;
389                ENDFOR
390
391                pLong_Window_1 =
392                        &Long_Window[wnd_shape_this_bk][LONG_WINDOW_m_1];
393
394                FOR ( i=0; i<LONG_WINDOW; i++)
395                    Frequency_data[LONG_WINDOW + i]  *=  *pLong_Window_1--;
396                ENDFOR
397
398                BREAK
399
400        }
401
402
403        FOR ( i=0; i<LONG_WINDOW; i++)
404            Output_buffer[i]  = Frequency_data[i]  + Time_data[i];
405            Time_data[i] = Frequency_data[LONG_WINDOW+i];
406        ENDFOR
407
408    }
409
410    ENDIF
411
412
413
414------------------------------------------------------------------------------
415 RESOURCES USED
416   When the code is written for a specific target processor the
417     the resources used should be documented below.
418
419 STACK USAGE: [stack count for this module] + [variable to represent
420          stack usage for each subroutine called]
421
422     where: [stack usage variable] = stack usage for [subroutine
423         name] (see [filename].ext)
424
425 DATA MEMORY USED: x words
426
427 PROGRAM MEMORY USED: x words
428
429 CLOCK CYCLES: [cycle count equation for this module] + [variable
430           used to represent cycle count for each subroutine
431           called]
432
433     where: [cycle count variable] = cycle count for [subroutine
434        name] (see [filename].ext)
435
436------------------------------------------------------------------------------
437*/
438
439
440/*----------------------------------------------------------------------------
441; INCLUDES
442----------------------------------------------------------------------------*/
443
444#include "pv_audio_type_defs.h"
445#include "aac_mem_funcs.h"
446#include "window_block_fxp.h"
447#include "imdct_fxp.h"
448
449#include "fxp_mul32.h"
450
451
452/*----------------------------------------------------------------------------
453; MACROS
454; limit(x) saturates any number that exceeds a 16-bit representation into a
455; 16 bit number.
456----------------------------------------------------------------------------*/
457
458#define  ROUNDING_SCALED     (ROUNDING<<(16 - SCALING))
459
460
461#if defined(PV_ARM_V5)
462
463
464__inline Int16 sat(Int32 y)
465{
466    Int32 x;
467    Int32 z;
468    __asm
469    {
470        mov x, ROUNDING_SCALED
471        mov y, y, lsl #(15-SCALING)
472        qdadd z, x, y
473        mov y, z, lsr #16
474    }
475    return((Int16)y);
476}
477
478#define  limiter( y, x)   y = sat(x);
479
480
481
482#elif defined(PV_ARM_GCC_V5)
483
484
485__inline Int16 sat(Int32 y)
486{
487    register Int32 x;
488    register Int32 ra = (Int32)y;
489    register Int32 z = ROUNDING_SCALED;
490
491
492    asm volatile(
493        "mov %0, %1, lsl #5\n\t"    // (15-SCALING) assembler does not take symbols
494        "qdadd %0, %2, %0\n\t"
495        "mov %0, %0, lsr #16"
496    : "=&r*i"(x)
497                : "r"(ra),
498                "r"(z));
499
500    return ((Int16)x);
501}
502
503#define  limiter( y, x)   y = sat(x);
504
505
506#elif defined(PV_ARM_MSC_EVC_V5)
507
508
509#define  limiter( y, x)       z = x<< (15-SCALING); \
510                              y = _DAddSatInt( ROUNDING_SCALED, z)>>16;
511
512
513#else
514
515#define  limiter( y, x)   z = ((x + ROUNDING )>>SCALING); \
516                          if ((z>>15) != (z>>31))         \
517                          {                                    \
518                              z = (z >> 31) ^ INT16_MAX;       \
519                          } \
520                          y = (Int16)(z);
521
522#endif
523
524
525/*----------------------------------------------------------------------------
526; DEFINES
527; Include all pre-processor statements here. Include conditional
528; compile variables also.
529----------------------------------------------------------------------------*/
530
531/*----------------------------------------------------------------------------
532; LOCAL FUNCTION DEFINITIONS
533; Function Prototype declaration
534----------------------------------------------------------------------------*/
535
536
537/*----------------------------------------------------------------------------
538; LOCAL VARIABLE DEFINITIONS
539; Variable declaration - defined here and used outside this module
540----------------------------------------------------------------------------*/
541
542/*----------------------------------------------------------------------------
543; EXTERNAL FUNCTION REFERENCES
544; Declare functions defined elsewhere and referenced in this module
545----------------------------------------------------------------------------*/
546
547/*----------------------------------------------------------------------------
548; EXTERNAL VARIABLES REFERENCES
549; Declare variables used in this module but defined elsewhere
550----------------------------------------------------------------------------*/
551
552/*----------------------------------------------------------------------------
553; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
554; Declare variables used in this module but defined elsewhere
555----------------------------------------------------------------------------*/
556
557/*----------------------------------------------------------------------------
558; FUNCTION CODE
559----------------------------------------------------------------------------*/
560
561#ifdef AAC_PLUS
562
563
564void trans4m_freq_2_time_fxp_1(
565    Int32               Frequency_data[],
566    Int32               Time_data[],
567    Int16               Output_buffer[],
568    WINDOW_SEQUENCE     wnd_seq,
569    Int                 wnd_shape_prev_bk,
570    Int                 wnd_shape_this_bk,
571    Int                 Q_format,
572    Int32               abs_max_per_window[],
573    Int32               freq_2_time_buffer[])
574
575{
576    Int exp;
577    Int shift;
578
579    Int  i;
580    Int  wnd;
581#if !(defined( PV_ARM_GCC_V5)||(PV_ARM_V5))
582    Int32 z;
583#endif
584
585    Int16 *pFreqInfo;
586    Int32 temp;
587    Int32 test;
588
589    Int16 *pFreq_2_Time_data_1;
590    Int16 *pFreq_2_Time_data_2;
591
592    const Int16 *pLong_Window_1;
593    const Int16 *pLong_Window_2;
594    const Int16 *pShort_Window_1;
595    const Int16 *pShort_Window_2;
596
597    Int32 *pOverlap_and_Add_Buffer_1;
598    Int32 *pOverlap_and_Add_Buffer_2;
599
600    Int16  *pOutput_buffer;
601    Int16  *pOutput_buffer_2;
602
603    const Int16 * Long_Window_fxp[NUM_WINDOW_SHAPES];
604    const Int16 * Short_Window_fxp[NUM_WINDOW_SHAPES];
605
606    Long_Window_fxp[0] = Long_Window_sine_fxp;
607    Long_Window_fxp[1] = Long_Window_KBD_fxp;
608    Short_Window_fxp[0] = Short_Window_sine_fxp;
609    Short_Window_fxp[1] = Short_Window_KBD_fxp;
610
611
612    if (wnd_seq != EIGHT_SHORT_SEQUENCE)
613    {
614
615        pFreqInfo = (Int16 *)Frequency_data;
616
617
618        exp = imdct_fxp(
619                  (Int32 *)pFreqInfo,
620                  freq_2_time_buffer,
621                  LONG_BLOCK1,
622                  Q_format,
623                  abs_max_per_window[0]);
624
625
626
627        /*
628         *  The C Programming Language, Second Edition, Kernighan & Ritchie,
629         *  page 206.
630         *  "The result [of a shift] is undefined if the right operand is
631         *  negative, or greater than or equal to the number of bits in the
632         *  left expression's type"
633         *   => avoid shift by 32 or 16
634         */
635
636        if (exp < 16)
637        {
638
639            pFreq_2_Time_data_1 = pFreqInfo;
640
641            switch (wnd_seq)
642            {
643
644                case ONLY_LONG_SEQUENCE:
645                default:
646
647                    pOutput_buffer = Output_buffer;
648
649                    pOverlap_and_Add_Buffer_1 = Time_data;
650
651                    {
652                        const Int16 *pLong_Window_2 = &Long_Window_fxp[wnd_shape_this_bk][LONG_WINDOW_m_1];
653
654                        Int32 * pFreq2T = (Int32 *)pFreqInfo;
655                        Int32 * win = (Int32 *) & Long_Window_fxp[wnd_shape_prev_bk][0];
656                        Int shift = exp + 15 - SCALING;
657
658
659                        Int32 * pFreq2T_2 = &pFreq2T[HALF_LONG_WINDOW];
660
661
662                        for (i = HALF_LONG_WINDOW; i != 0; i--)
663                        {
664                            Int16 win1, win2;
665                            Int32  temp2, test2;
666
667                            Int32  winx;
668
669                            temp2 = *(pFreq2T++);
670                            winx = *(win++);
671
672                            test  = *(pOverlap_and_Add_Buffer_1++);
673                            test2 = *(pOverlap_and_Add_Buffer_1--);
674                            temp  =   fxp_mul_16_by_16bb(temp2, winx) >> shift;
675                            temp2 =   fxp_mul_16_by_16tt(temp2, winx) >> shift;
676                            limiter(*(pOutput_buffer++), (temp + test));
677                            limiter(*(pOutput_buffer++), (temp2 + test2));
678
679                            temp2 = *(pFreq2T_2++);
680
681                            win1  = *(pLong_Window_2--);
682                            win2  = *(pLong_Window_2--);
683                            temp  = fxp_mul_16_by_16bb(temp2, win1) >> shift;
684                            test2 = fxp_mul_16_by_16tb(temp2, win2) >> shift;
685                            *(pOverlap_and_Add_Buffer_1++) = temp;
686                            *(pOverlap_and_Add_Buffer_1++) = test2;
687
688                        }
689                    }
690
691                    break;
692
693                case LONG_START_SEQUENCE:
694
695
696                    pFreq_2_Time_data_2 =
697                        &pFreq_2_Time_data_1[ HALF_LONG_WINDOW];
698
699                    pLong_Window_1 = &Long_Window_fxp[wnd_shape_prev_bk][0];
700                    pLong_Window_2 = &pLong_Window_1[ HALF_LONG_WINDOW];
701
702                    pOverlap_and_Add_Buffer_1 = &Time_data[0];
703                    pOverlap_and_Add_Buffer_2 = &Time_data[HALF_LONG_WINDOW];
704
705                    pOutput_buffer   = Output_buffer;
706                    pOutput_buffer_2 = pOutput_buffer + HALF_LONG_WINDOW;
707
708
709                    shift = exp + 15 - SCALING;
710
711                    for (i = HALF_LONG_WINDOW; i != 0; i--)
712                    {
713
714                        Int16 win1, win2;
715                        Int16  dat1, dat2;
716                        Int32  test1, test2;
717
718                        dat1   = *(pFreq_2_Time_data_1++);
719                        win1   = *(pLong_Window_1++);
720                        test1  = *(pOverlap_and_Add_Buffer_1++);
721
722                        dat2  =  *(pFreq_2_Time_data_2++);
723                        win2  = *(pLong_Window_2++);
724                        test2 = *(pOverlap_and_Add_Buffer_2++);
725
726                        limiter(*(pOutput_buffer++), (test1 + (fxp_mul_16_by_16(dat1, win1) >> shift)));
727
728                        limiter(*(pOutput_buffer_2++), (test2 + (fxp_mul_16_by_16(dat2, win2) >> shift)));
729
730                    }
731
732                    /*
733                     *  data unchanged from  LONG_WINDOW to W_L_START_1
734                     *  only scaled accordingly
735                     */
736
737                    pOverlap_and_Add_Buffer_1 = &Time_data[0];
738                    pFreq_2_Time_data_1       = &pFreqInfo[LONG_WINDOW];
739
740                    exp -= SCALING;
741
742                    if (exp >= 0)
743                    {
744
745                        for (i = (W_L_START_1 - LONG_WINDOW) >> 1; i != 0; i--)
746                        {
747                            *(pOverlap_and_Add_Buffer_1++) =
748                                *(pFreq_2_Time_data_1++) >> exp;
749                            *(pOverlap_and_Add_Buffer_1++) =
750                                *(pFreq_2_Time_data_1++) >> exp;
751
752                        }
753
754                    }
755                    else if (exp < 0)
756                    {
757
758                        Int shift = -exp;
759                        for (i = (W_L_START_1 - LONG_WINDOW) >> 1; i != 0 ; i--)
760                        {
761                            Int32 temp2 = ((Int32) * (pFreq_2_Time_data_1++)) << shift;
762                            *(pOverlap_and_Add_Buffer_1++) = temp2;
763                            temp2 = ((Int32) * (pFreq_2_Time_data_1++)) << shift;
764                            *(pOverlap_and_Add_Buffer_1++) = temp2;
765                        }
766
767                    }
768                    else
769                    {
770
771                        for (i = (W_L_START_1 - LONG_WINDOW) >> 1; i != 0; i--)
772                        {
773                            *(pOverlap_and_Add_Buffer_1++) =
774                                *(pFreq_2_Time_data_1++);
775                            *(pOverlap_and_Add_Buffer_1++) =
776                                *(pFreq_2_Time_data_1++);
777
778                        }
779
780                    }
781
782
783                    pFreq_2_Time_data_1  = &pFreqInfo[W_L_START_1];
784                    pFreq_2_Time_data_2  =
785                        &pFreq_2_Time_data_1[HALF_SHORT_WINDOW];
786
787                    pShort_Window_1   =
788                        &Short_Window_fxp[wnd_shape_this_bk][SHORT_WINDOW_m_1];
789
790                    pShort_Window_2   = pShort_Window_1 - HALF_SHORT_WINDOW;
791
792                    pOverlap_and_Add_Buffer_2 = pOverlap_and_Add_Buffer_1 +
793                                                HALF_SHORT_WINDOW;
794
795
796                    for (i = HALF_SHORT_WINDOW; i != 0; i--)
797                    {
798                        Int16 win1, win2;
799                        Int16  dat1, dat2;
800                        Int32  temp2;
801                        dat1  = (*pFreq_2_Time_data_1++);
802                        dat2  = (*pFreq_2_Time_data_2++);
803                        win1  = *(pShort_Window_1--);
804                        win2  = *(pShort_Window_2--);
805
806                        temp   =   fxp_mul_16_by_16(dat1, win1) >> shift;
807                        *(pOverlap_and_Add_Buffer_1++) = temp;
808
809                        temp2 =   fxp_mul_16_by_16(dat2, win2) >> shift;
810                        *(pOverlap_and_Add_Buffer_2++) = temp2;
811
812
813                    }
814
815
816                    pOverlap_and_Add_Buffer_1 += HALF_SHORT_WINDOW;
817
818                    pv_memset(
819                        pOverlap_and_Add_Buffer_1,
820                        0,
821                        (LONG_BLOCK1 - W_L_START_2)
822                        *sizeof(*pOverlap_and_Add_Buffer_1));
823
824
825                    break;
826
827
828                case LONG_STOP_SEQUENCE:
829
830                    pOverlap_and_Add_Buffer_1 = &Time_data[ W_L_STOP_2];
831
832                    pOutput_buffer         = &Output_buffer[W_L_STOP_2];
833
834                    pFreq_2_Time_data_1      = &pFreqInfo[W_L_STOP_2];
835
836                    exp -= SCALING; /*  !!!! */
837
838                    if (exp > 0)
839                    {
840                        Int16 tmp1 = (*(pFreq_2_Time_data_1++) >> exp);
841                        temp = *(pOverlap_and_Add_Buffer_1++);
842
843                        for (i = (LONG_WINDOW - W_L_STOP_2); i != 0; i--)
844                        {
845                            limiter(*(pOutput_buffer++), (temp + tmp1));
846
847                            tmp1 = *(pFreq_2_Time_data_1++) >> exp;
848                            temp = *(pOverlap_and_Add_Buffer_1++);
849
850                        }
851                    }
852                    else if (exp < 0)
853                    {
854                        shift = -exp;
855                        Int32 temp1 = ((Int32) * (pFreq_2_Time_data_1++)) << shift;
856                        temp = *(pOverlap_and_Add_Buffer_1++);
857
858                        for (i = (LONG_WINDOW - W_L_STOP_2); i != 0; i--)
859                        {
860                            limiter(*(pOutput_buffer++), (temp + temp1));
861
862                            temp1 = ((Int32) * (pFreq_2_Time_data_1++)) << shift;
863                            temp = *(pOverlap_and_Add_Buffer_1++);
864
865                        }
866                    }
867                    else
868                    {
869                        Int16 tmp1 = *(pFreq_2_Time_data_1++);
870                        temp = *(pOverlap_and_Add_Buffer_1++);
871
872                        for (i = (LONG_WINDOW - W_L_STOP_2); i != 0; i--)
873                        {
874                            limiter(*(pOutput_buffer++), (temp + tmp1));
875
876                            tmp1 = *(pFreq_2_Time_data_1++);
877                            temp = *(pOverlap_and_Add_Buffer_1++);
878
879                        }
880                    }
881
882
883                    pShort_Window_1 = &Short_Window_fxp[wnd_shape_prev_bk][0];
884                    pShort_Window_2 = &pShort_Window_1[HALF_SHORT_WINDOW];
885
886                    pFreq_2_Time_data_1 = &pFreqInfo[W_L_STOP_1];
887                    pFreq_2_Time_data_2 =
888                        &pFreq_2_Time_data_1[HALF_SHORT_WINDOW];
889
890                    pOverlap_and_Add_Buffer_1 = &Time_data[ W_L_STOP_1];
891                    pOverlap_and_Add_Buffer_2 = pOverlap_and_Add_Buffer_1
892                                                + HALF_SHORT_WINDOW;
893
894                    pOutput_buffer   = &Output_buffer[W_L_STOP_1];
895                    pOutput_buffer_2 = pOutput_buffer + HALF_SHORT_WINDOW;
896
897                    exp += SCALING;  /* +8 back to what it was */
898
899                    shift = exp + 15 - SCALING;
900
901
902                    for (i = HALF_SHORT_WINDOW; i != 0; i--)
903                    {
904                        Int16 win1;
905                        Int16  dat1;
906
907                        dat1 = *(pFreq_2_Time_data_1++);
908                        win1 = *(pShort_Window_1++);
909                        temp = *(pOverlap_and_Add_Buffer_1++);
910
911                        test  = fxp_mul_16_by_16(dat1, win1);
912
913                        limiter(*(pOutput_buffer++), (temp + (test >> shift)));
914
915                        dat1 = *(pFreq_2_Time_data_2++);
916                        win1 = *(pShort_Window_2++);
917                        temp = *(pOverlap_and_Add_Buffer_2++);
918                        test =  fxp_mul_16_by_16(dat1, win1);
919                        limiter(*(pOutput_buffer_2++), (temp + (test >> shift)));
920
921                    }
922
923
924                    pFreq_2_Time_data_2 = &pFreqInfo[LONG_WINDOW];
925
926                    pOverlap_and_Add_Buffer_1 = Time_data;
927
928                    pOutput_buffer = Output_buffer;
929
930                    pLong_Window_2   =
931                        &Long_Window_fxp[wnd_shape_this_bk][LONG_WINDOW_m_1];
932
933
934                    /*
935                     *  Copy previous time in current buffer, also copy overlap
936                     *  and add buffer
937                     */
938
939                    for (i = W_L_STOP_1; i != 0; i--)
940                    {
941                        Int16 win1;
942                        Int16 dat1;
943
944                        win1 = *(pLong_Window_2--);
945                        dat1 = *pFreq_2_Time_data_2++;
946
947                        limiter(*(pOutput_buffer++), *(pOverlap_and_Add_Buffer_1));
948
949
950                        temp = fxp_mul_16_by_16(dat1, win1) >> shift;
951                        *(pOverlap_and_Add_Buffer_1++) = temp ;
952
953                    }
954
955                    for (i = (LONG_WINDOW - W_L_STOP_1); i != 0; i--)
956                    {
957                        temp = fxp_mul_16_by_16(*pFreq_2_Time_data_2++, *(pLong_Window_2--)) >> shift;
958                        *(pOverlap_and_Add_Buffer_1++) = temp ;
959                    }
960
961
962                    break;
963
964
965
966            } /* switch (wnd_seq) */
967
968        }   /*  if (exp < 16)  */
969
970        else
971        {
972            /* all zeros buffer or excessive down shift */
973
974            /* Overlap and add, setup buffer for next iteration */
975            pOverlap_and_Add_Buffer_1 = &Time_data[0];
976
977            pOutput_buffer = Output_buffer;
978
979            temp  = (*pOverlap_and_Add_Buffer_1++);
980
981            for (i = LONG_WINDOW; i != 0; i--)
982            {
983
984                limiter(*(pOutput_buffer++), temp);
985
986                temp = (*pOverlap_and_Add_Buffer_1++);
987
988            }
989
990            pv_memset(Time_data, 0, LONG_WINDOW*sizeof(Time_data[0]));
991
992
993        }
994
995    }
996    else
997    {
998
999        Int32 *pScrath_mem;
1000        Int32 *pScrath_mem_entry;
1001        Int32  *pFrequency_data = Frequency_data;
1002
1003        Int32 * pOverlap_and_Add_Buffer_1;
1004        Int32 * pOverlap_and_Add_Buffer_2;
1005        Int32 * pOverlap_and_Add_Buffer_1x;
1006        Int32 * pOverlap_and_Add_Buffer_2x;
1007
1008        /*
1009         *  Frequency_data is 2*LONG_WINDOW length but only
1010         *  the first LONG_WINDOW elements are filled in,
1011         *  then the second part can be used as scratch mem,
1012         *  then grab data from one window at a time in
1013         *  reverse order.
1014         *  The upper LONG_WINDOW Int32 are used to hold the
1015         *  computed overlap and add, used in the next call to
1016         *  this function, and also as sctrach memory
1017         */
1018
1019        /*
1020         *  Frequency_data usage for the case EIGHT_SHORT_SEQUENCE
1021
1022          |<----- Input Freq. data ----->|< Overlap & Add ->| Unused |-Scratch-|
1023          |                              |  Store for next  |        |  memory |
1024          |                              |  call            |        |         |
1025          |                              |                  |        |         |
1026          |//////////////////////////////|\\\\\\\\\\\\\\\\\\|--------|+++++++++|
1027          |                              |                  |        |         |
1028          0                         LONG_WINDOW        LONG_WINDOW   |   2*LONG_WINDOW
1029                                                            +        |         |
1030                                                       W_L_STOP_2    |         |
1031                                                                     |<--   -->|
1032                                                                      SHORT_WINDOW +
1033                                                                    HALF_SHORT_WINDOW
1034          *
1035          */
1036
1037        pOverlap_and_Add_Buffer_1  = &pFrequency_data[
1038                                         LONG_WINDOW + 3*SHORT_WINDOW + HALF_SHORT_WINDOW];
1039
1040        /*
1041         *  Initialize to zero, only the firt short window used in overlap
1042         *  and add
1043         */
1044        pv_memset(
1045            pOverlap_and_Add_Buffer_1,
1046            0,
1047            SHORT_WINDOW*sizeof(*pOverlap_and_Add_Buffer_1));
1048
1049        /*
1050         *  Showt windows are evaluated in decresing order. Windows from 7
1051         *  to 0 are break down in four cases: window numbers 7 to 5, 4, 3,
1052         *  and 2 to 0.
1053         *  The data from short windows 3 and 4 is situated at the boundary
1054         *  between the 'overlap and add' buffer and the output buffer.
1055         */
1056        for (wnd = NUM_SHORT_WINDOWS - 1; wnd >= NUM_SHORT_WINDOWS / 2 + 1; wnd--)
1057        {
1058
1059            pFreqInfo = (Int16 *) & pFrequency_data[ wnd*SHORT_WINDOW];
1060
1061            exp = imdct_fxp(
1062                      (Int32 *)pFreqInfo,
1063                      freq_2_time_buffer,
1064                      SHORT_BLOCK1,
1065                      Q_format,
1066                      abs_max_per_window[wnd]);
1067
1068            pOverlap_and_Add_Buffer_1 =
1069                &pFrequency_data[ W_L_STOP_1 + SHORT_WINDOW*wnd];
1070
1071
1072            pOverlap_and_Add_Buffer_2 =
1073                pOverlap_and_Add_Buffer_1 + SHORT_WINDOW;
1074
1075            /*
1076             *  If all element are zero or if the exponent is bigger than
1077             *  16 ( it becomes an undefined shift) ->  skip
1078             */
1079
1080            if (exp < 16)
1081            {
1082
1083
1084                pFreq_2_Time_data_1 = &pFreqInfo[0];
1085                pFreq_2_Time_data_2 = &pFreqInfo[SHORT_WINDOW];
1086
1087
1088                /*
1089                 *  Each of the eight short blocks is windowed separately.
1090                 *  Window shape decisions are made on a frame-by-frame
1091                 *  basis.
1092                 */
1093
1094                pShort_Window_1 = &Short_Window_fxp[wnd_shape_this_bk][0];
1095
1096                pShort_Window_2   =
1097                    &Short_Window_fxp[wnd_shape_this_bk][SHORT_WINDOW_m_1];
1098
1099
1100
1101
1102                /*
1103                 * For short windows from 7 to 5
1104                 *                                      |   =========================
1105                 *                                      |   |     5     6     7
1106                 *               _--_  _--_  _--_  _--_ | _-|-_  _--_  _--_  _--_
1107                 *              /    \/    \/    \/    \|/  |  \/    \/    \/    \
1108                 *             /     /\    /\    /\    /|\  |  /\    /\    /\     \
1109                 *            /     /  \  /  \  /  \  / | \ | /  \  /  \  /  \     \
1110                 *           /     /    \/    \/    \/  |  \|/    \/    \     \     \
1111                 *      --------------------------------|---[///////////////////////]--------
1112                 *
1113                 */
1114
1115
1116                shift = exp + 15 - SCALING;
1117
1118
1119                for (i = SHORT_WINDOW; i != 0; i--)
1120                {
1121                    Int16 win1, win2;
1122                    Int16  dat1, dat2;
1123
1124                    dat2 = *(pFreq_2_Time_data_2++);
1125                    win2 = *(pShort_Window_2--);
1126                    temp = *pOverlap_and_Add_Buffer_2;
1127                    dat1 = *(pFreq_2_Time_data_1++);
1128                    win1 = *(pShort_Window_1++);
1129
1130                    *(pOverlap_and_Add_Buffer_2++) =  temp + (fxp_mul_16_by_16(dat2, win2) >> shift);
1131
1132                    *(pOverlap_and_Add_Buffer_1++)  =  fxp_mul_16_by_16(dat1, win1) >> shift;
1133
1134                }
1135
1136            }   /* if (exp < 16) */
1137            else
1138            {
1139                pv_memset(
1140                    pOverlap_and_Add_Buffer_1,
1141                    0,
1142                    SHORT_WINDOW*sizeof(*pOverlap_and_Add_Buffer_1));
1143            }
1144
1145
1146        }/* for ( wnd=NUM_SHORT_WINDOWS-1; wnd>=NUM_SHORT_WINDOWS/2; wnd--) */
1147
1148
1149        wnd = NUM_SHORT_WINDOWS / 2;
1150
1151        pFreqInfo = (Int16 *) & pFrequency_data[ wnd*SHORT_WINDOW];
1152
1153        /*
1154         *  scratch memory is allocated in an unused part of memory
1155         */
1156
1157
1158        pScrath_mem = &pFrequency_data[ 2*LONG_WINDOW - HALF_SHORT_WINDOW];
1159
1160        pOverlap_and_Add_Buffer_1 = &pFrequency_data[ LONG_WINDOW];
1161
1162        pOverlap_and_Add_Buffer_2 = pOverlap_and_Add_Buffer_1
1163                                    + HALF_SHORT_WINDOW;
1164
1165
1166        exp = imdct_fxp(
1167                  (Int32 *)pFreqInfo,
1168                  freq_2_time_buffer,
1169                  SHORT_BLOCK1,
1170                  Q_format,
1171                  abs_max_per_window[wnd]);
1172
1173        /*
1174         *  If all element are zero or if the exponent is bigger than
1175         *  16 ( it becomes an undefined shift) ->  skip
1176         */
1177
1178
1179        if (exp < 16)
1180        {
1181
1182            pFreq_2_Time_data_1 = &pFreqInfo[0];
1183            pFreq_2_Time_data_2 = &pFreqInfo[SHORT_WINDOW];
1184
1185            pShort_Window_1 = &Short_Window_fxp[wnd_shape_this_bk][0];
1186
1187            pShort_Window_2 =
1188                &Short_Window_fxp[wnd_shape_this_bk][SHORT_WINDOW_m_1];
1189
1190
1191            /*
1192             * For short window 4
1193             *                                    ====|===========
1194             *                                        |   4
1195             *                                    |   |   |      |
1196             *                _--_  _--_  _--_  _-|-_ | _-|-_  _-|-_  _--_  _--_
1197             *               /    \/    \/    \/  |  \|/  |  \/  |  \/    \/    \
1198             *              /     /\    /\    /\  |  /|\  |  /\  |  /\    /\     \
1199             *             /     /  \  /  \  /  \ | / | \ | /  \ | /  \  /  \     \
1200             *            /     /    \/    \/    \|/  |  \|/    \|/    \/    \     \
1201             *      ------------------------------[\\\|\\\|//////]-------------------
1202             *           |                        | A | B |   C  |
1203             *           |
1204             *        W_L_STOP_1
1205             */
1206
1207            shift = exp + 15 - SCALING;
1208            {
1209                Int16 win1;
1210                Int16  dat1;
1211                /* -------- segment A ---------------*/
1212                dat1 = *(pFreq_2_Time_data_1++);
1213                win1 = *(pShort_Window_1++);
1214                for (i = HALF_SHORT_WINDOW; i != 0; i--)
1215                {
1216                    *(pScrath_mem++)  =  fxp_mul_16_by_16(dat1, win1) >> (shift);
1217                    dat1 = *(pFreq_2_Time_data_1++);
1218                    win1 = *(pShort_Window_1++);
1219                }
1220
1221                /* -------- segment B ---------------*/
1222                for (i = HALF_SHORT_WINDOW; i != 0; i--)
1223                {
1224                    *(pOverlap_and_Add_Buffer_1++)  =  fxp_mul_16_by_16(dat1, win1) >> shift;
1225
1226                    dat1 = *(pFreq_2_Time_data_1++);
1227                    win1 = *(pShort_Window_1++);
1228                }
1229
1230                /* -------- segment C ---------------*/
1231                temp = *pOverlap_and_Add_Buffer_2;
1232                dat1 = *(pFreq_2_Time_data_2++);
1233                win1 = *(pShort_Window_2--);
1234
1235                for (i = SHORT_WINDOW; i != 0; i--)
1236                {
1237                    *(pOverlap_and_Add_Buffer_2++)  =  temp + (fxp_mul_16_by_16(dat1, win1) >> shift);
1238
1239                    temp = *pOverlap_and_Add_Buffer_2;
1240                    dat1 = *(pFreq_2_Time_data_2++);
1241                    win1 = *(pShort_Window_2--);
1242                }
1243            }
1244
1245        }   /* if (exp < 16) */
1246        else
1247        {
1248            pv_memset(
1249                pScrath_mem,
1250                0,
1251                HALF_SHORT_WINDOW*sizeof(*pScrath_mem));
1252
1253            pv_memset(
1254                pOverlap_and_Add_Buffer_1,
1255                0,
1256                HALF_SHORT_WINDOW*sizeof(*pOverlap_and_Add_Buffer_1));
1257        }
1258
1259
1260        wnd = NUM_SHORT_WINDOWS / 2 - 1;
1261
1262        pFreqInfo = (Int16 *) & pFrequency_data[ wnd*SHORT_WINDOW];
1263
1264        pScrath_mem_entry =
1265            &pFrequency_data[2*LONG_WINDOW - HALF_SHORT_WINDOW - SHORT_WINDOW];
1266        pScrath_mem = pScrath_mem_entry;
1267
1268        pOverlap_and_Add_Buffer_1 = &pFrequency_data[ LONG_WINDOW];
1269
1270        /* point to end of buffer less HALF_SHORT_WINDOW */
1271
1272        pOutput_buffer_2 = &Output_buffer[LONG_WINDOW - HALF_SHORT_WINDOW];
1273        pOutput_buffer   = pOutput_buffer_2;
1274
1275        pOverlap_and_Add_Buffer_1x = &Time_data[W_L_STOP_1 + SHORT_WINDOW*(wnd+1)];  /* !!!! */
1276
1277        exp = imdct_fxp(
1278                  (Int32 *)pFreqInfo,
1279                  freq_2_time_buffer,
1280                  SHORT_BLOCK1,
1281                  Q_format,
1282                  abs_max_per_window[wnd]);
1283
1284        /*
1285         *  If all element are zero or if the exponent is bigger than
1286         *  16 ( it becomes an undefined shift) ->  skip
1287         */
1288
1289        if (exp < 16)
1290        {
1291
1292            pFreq_2_Time_data_1 = &pFreqInfo[0];
1293            pFreq_2_Time_data_2 = &pFreqInfo[SHORT_WINDOW];
1294
1295
1296            /*
1297             * For short window 3
1298             *                             ===========|====
1299             *                                    3   |
1300             *                             |      |   |   |
1301             *               _--_  _--_  _-|-_  _-|-_ | _-|-_  _--_  _--_  _--_
1302             *              /    \/    \/  |  \/  |  \|/  |  \/    \/    \/    \
1303             *             /     /\    /\  |  /\  |  /|\  |  /\    /\    /\     \
1304             *            /     /  \  /  \ | /  \ | / | \ | /  \  /  \  /  \     \
1305             *           /     /    \/    \|/    \|/  |  \|/    \/    \     \     \
1306             *     -----|------------------[\\\\\\|///|///]--------------------------
1307             *          |                  |   A  | B | C |
1308             *
1309             *      W_L_STOP_1
1310             */
1311
1312
1313            pShort_Window_1 = &Short_Window_fxp[wnd_shape_this_bk][0];
1314
1315            pShort_Window_2 =
1316                &Short_Window_fxp[wnd_shape_this_bk][SHORT_WINDOW_m_1];
1317
1318            shift = exp + 15 - SCALING;
1319
1320
1321            Int16 win1;
1322            Int16  dat1;
1323            /* -------- segment A ---------------*/
1324            dat1 = *(pFreq_2_Time_data_1++);
1325            win1 = *(pShort_Window_1++);
1326            for (i = SHORT_WINDOW; i != 0; i--)
1327            {
1328                *(pScrath_mem++)  =  fxp_mul_16_by_16(dat1, win1) >> shift;
1329                dat1 = *(pFreq_2_Time_data_1++);
1330                win1 = *(pShort_Window_1++);
1331            }
1332
1333            dat1 = *(pFreq_2_Time_data_2++);
1334            win1 = *(pShort_Window_2--);
1335
1336            /* -------- segment B ---------------*/
1337            for (i = HALF_SHORT_WINDOW; i != 0; i--)
1338            {
1339                test = fxp_mul_16_by_16(dat1, win1) >> shift;
1340
1341                temp =  *(pScrath_mem++) + test;
1342
1343
1344                test = *(pOverlap_and_Add_Buffer_1x++);  /* !!!! */
1345
1346                limiter(*(pOutput_buffer++), (temp + test));
1347
1348                dat1 = *(pFreq_2_Time_data_2++);
1349                win1 = *(pShort_Window_2--);
1350
1351            }
1352
1353            /* -------- segment C ---------------*/
1354            for (i = HALF_SHORT_WINDOW; i != 0; i--)
1355            {
1356                temp = fxp_mul_16_by_16(dat1, win1) >> (shift);
1357
1358                *(pOverlap_and_Add_Buffer_1++) += temp;
1359
1360                dat1 = *(pFreq_2_Time_data_2++);
1361                win1 = *(pShort_Window_2--);
1362            }
1363
1364        }   /* if (exp < 16) */
1365        else
1366        {
1367
1368            pv_memset(
1369                pScrath_mem,
1370                0,
1371                SHORT_WINDOW*sizeof(*pScrath_mem));
1372
1373            pScrath_mem += SHORT_WINDOW;
1374
1375            temp = *(pScrath_mem++);
1376            for (i = HALF_SHORT_WINDOW; i != 0; i--)
1377            {
1378                limiter(*(pOutput_buffer++), temp);
1379                temp = *(pScrath_mem++);
1380
1381
1382            }
1383        }
1384
1385
1386        for (wnd = NUM_SHORT_WINDOWS / 2 - 2; wnd >= 0; wnd--)
1387        {
1388
1389
1390            pOutput_buffer_2 -= SHORT_WINDOW;
1391            pOutput_buffer = pOutput_buffer_2;
1392
1393            /*
1394             * The same memory is used as scratch in every iteration
1395             */
1396            pScrath_mem = pScrath_mem_entry;
1397
1398            pOverlap_and_Add_Buffer_2x =
1399                &Time_data[W_L_STOP_1 + SHORT_WINDOW*(wnd+1)];
1400
1401            pFreqInfo = (Int16 *) & pFrequency_data[ wnd*SHORT_WINDOW];
1402
1403
1404
1405            exp = imdct_fxp(
1406                      (Int32 *)pFreqInfo,
1407                      freq_2_time_buffer,
1408                      SHORT_BLOCK1,
1409                      Q_format,
1410                      abs_max_per_window[wnd]);
1411
1412            /*
1413             *  If all element are zero or if the exponent is bigger than
1414             *  16 ( it becomes an undefined shift) ->  skip
1415             */
1416
1417            if (exp < 16)
1418            {
1419
1420                pFreq_2_Time_data_1 = &pFreqInfo[0];
1421                pFreq_2_Time_data_2 = &pFreqInfo[SHORT_WINDOW];
1422
1423
1424                /*
1425                 *  Each of the eight short blocks is windowed separately.
1426                 *  Window shape decisions are made on a frame-by-frame
1427                 *  basis.
1428                 */
1429
1430                pShort_Window_1 = &Short_Window_fxp[wnd_shape_this_bk][0];
1431
1432                if (wnd == 0)
1433                {
1434                    pShort_Window_1 =
1435                        &Short_Window_fxp[wnd_shape_prev_bk][0];
1436                }
1437
1438                pShort_Window_2   =
1439                    &Short_Window_fxp[wnd_shape_this_bk][SHORT_WINDOW_m_1];
1440
1441
1442                /*
1443                 * For short windows from 2 to 0
1444                 *
1445                 *          =========================
1446                 *                                       |
1447                 *                0     1     2      |   |
1448                 *               _--_  _--_  _--_  _-|-_ | _--_  _--_  _--_  _--_
1449                 *              /    \/    \/    \/  |  \|/    \/    \/    \/    \
1450                 *             /     /\    /\    /\  |  /|\    /\    /\    /\     \
1451                 *            /     /  \  /  \  /  \ | / | \  /  \  /  \  /  \     \
1452                 *           /     /    \/    \/    \|/  |  \/    \/    \     \     \
1453                 *      ----[\\\\\\\\\\\\\\\\\\\\\\\\]---|-----------------------------
1454                 *          |
1455                 *
1456                 *      W_L_STOP_1
1457                 */
1458
1459                shift = exp + 15 - SCALING;
1460
1461                Int16 dat1 = *(pFreq_2_Time_data_2++);
1462                Int16 win1 = *(pShort_Window_2--);
1463
1464                temp  =  *(pScrath_mem);
1465                for (i = SHORT_WINDOW; i != 0; i--)
1466                {
1467                    test  =  fxp_mul_16_by_16(dat1, win1) >> shift;
1468
1469                    temp += test;
1470
1471                    dat1 = *(pFreq_2_Time_data_1++);
1472                    win1 = *(pShort_Window_1++);
1473
1474                    limiter(*(pOutput_buffer++), (temp + *(pOverlap_and_Add_Buffer_2x++)));
1475
1476
1477                    *(pScrath_mem++) = fxp_mul_16_by_16(dat1, win1) >> shift;
1478                    dat1 = *(pFreq_2_Time_data_2++);
1479                    win1 = *(pShort_Window_2--);
1480                    temp  =  *(pScrath_mem);
1481
1482                }
1483
1484            }   /* if (exp < 16) */
1485            else
1486            {
1487                test  = *(pScrath_mem);
1488                temp  = *(pOverlap_and_Add_Buffer_2x++);
1489
1490                for (i = SHORT_WINDOW; i != 0; i--)
1491                {
1492                    limiter(*(pOutput_buffer++), (temp + test));
1493
1494                    *(pScrath_mem++) = 0;
1495                    test  =  *(pScrath_mem);
1496                    temp  = *(pOverlap_and_Add_Buffer_2x++);
1497
1498                }
1499            }
1500
1501        }   /* for ( wnd=NUM_SHORT_WINDOWS/2-1; wnd>=0; wnd--) */
1502
1503        pOverlap_and_Add_Buffer_2x =  &Time_data[W_L_STOP_1];
1504
1505        pScrath_mem = pScrath_mem_entry;
1506
1507        pOutput_buffer_2 -= SHORT_WINDOW;
1508        pOutput_buffer = pOutput_buffer_2;
1509
1510        test  = *(pScrath_mem++);
1511        temp  = *(pOverlap_and_Add_Buffer_2x++);
1512
1513        for (i = SHORT_WINDOW; i != 0; i--)
1514        {
1515            limiter(*(pOutput_buffer++), (temp + test));
1516
1517            test  = *(pScrath_mem++);
1518            temp  = *(pOverlap_and_Add_Buffer_2x++);
1519
1520        }
1521
1522        pOverlap_and_Add_Buffer_1x = Time_data;
1523
1524        pOutput_buffer = Output_buffer;
1525
1526
1527        temp = *(pOverlap_and_Add_Buffer_1x++);
1528
1529        for (i = W_L_STOP_1; i != 0; i--)
1530        {
1531            limiter(*(pOutput_buffer++), temp);
1532
1533            temp = *(pOverlap_and_Add_Buffer_1x++);
1534        }
1535
1536        pOverlap_and_Add_Buffer_1x = &Time_data[0];
1537
1538        pOverlap_and_Add_Buffer_2 = &pFrequency_data[LONG_WINDOW];
1539
1540        /*
1541         *  update overlap and add buffer,
1542         *  so is ready for next iteration
1543         */
1544
1545        for (int i = 0; i < W_L_STOP_2; i++)
1546        {
1547            temp = *(pOverlap_and_Add_Buffer_2++);
1548            *(pOverlap_and_Add_Buffer_1x++) = temp;
1549        }
1550
1551        pv_memset(
1552            pOverlap_and_Add_Buffer_1x,
1553            0,
1554            W_L_STOP_1*sizeof(*pOverlap_and_Add_Buffer_1x));
1555
1556    } /* if ( wnd_seq != EIGHT_SHORT_SEQUENCE) */
1557
1558}
1559
1560#endif
1561/*----------------------------------------------------------------------------
1562; FUNCTION CODE
1563----------------------------------------------------------------------------*/
1564
1565
1566
1567void trans4m_freq_2_time_fxp_2(
1568    Int32               Frequency_data[],
1569    Int32               Time_data[],
1570    WINDOW_SEQUENCE     wnd_seq,
1571    Int                 wnd_shape_prev_bk,
1572    Int                 wnd_shape_this_bk,
1573    Int                 Q_format,
1574    Int32               abs_max_per_window[],
1575    Int32               freq_2_time_buffer[],
1576    Int16               *Interleaved_output)
1577
1578{
1579
1580    Int exp;
1581    Int shift;
1582
1583    Int  i;
1584    Int  wnd;
1585#if !(defined( PV_ARM_GCC_V5)||(PV_ARM_V5))
1586    Int32 z;
1587#endif
1588    Int16 *pFreqInfo;
1589    Int32 temp;
1590    Int32 test;
1591
1592    Int16 *pFreq_2_Time_data_1;
1593    Int16 *pFreq_2_Time_data_2;
1594
1595    const Int16 *pLong_Window_1;
1596    const Int16 *pLong_Window_2;
1597    const Int16 *pShort_Window_1;
1598    const Int16 *pShort_Window_2;
1599
1600    Int32 *pOverlap_and_Add_Buffer_1;
1601    Int32 *pOverlap_and_Add_Buffer_2;
1602
1603    Int16  *pInterleaved_output;
1604    Int16  *pInterleaved_output_2;
1605
1606
1607    const Int16 * Long_Window_fxp[NUM_WINDOW_SHAPES];
1608    const Int16 * Short_Window_fxp[NUM_WINDOW_SHAPES];
1609
1610    Long_Window_fxp[0] = Long_Window_sine_fxp;
1611    Long_Window_fxp[1] = Long_Window_KBD_fxp;
1612    Short_Window_fxp[0] = Short_Window_sine_fxp;
1613    Short_Window_fxp[1] = Short_Window_KBD_fxp;
1614
1615    if (wnd_seq != EIGHT_SHORT_SEQUENCE)
1616    {
1617
1618        pFreqInfo = (Int16 *)Frequency_data;
1619
1620
1621        exp = imdct_fxp(
1622                  (Int32 *)pFreqInfo,
1623                  freq_2_time_buffer,
1624                  LONG_BLOCK1,
1625                  Q_format,
1626                  abs_max_per_window[0]);
1627
1628
1629        /*
1630         *  The C Programming Language, Second Edition, Kernighan & Ritchie,
1631         *  page 206.
1632         *  "The result [of a shift] is undefined if the right operand is
1633         *  negative, or greater than or equal to the number of bits in the
1634         *  left expression's type"
1635         *   => avoid shift by 32 or 16
1636         */
1637
1638        if (exp < 16)
1639        {
1640
1641            pFreq_2_Time_data_1 = pFreqInfo;
1642
1643
1644            switch (wnd_seq)
1645            {
1646
1647                case ONLY_LONG_SEQUENCE:
1648                default:
1649
1650                {
1651                    pOverlap_and_Add_Buffer_1 = Time_data;
1652
1653                    pInterleaved_output = Interleaved_output;
1654
1655                    {
1656
1657                        const Int16 *pLong_Window_2 = &Long_Window_fxp[wnd_shape_this_bk][LONG_WINDOW_m_1];
1658
1659                        Int32 * pFreq2T   = (Int32 *)pFreqInfo;
1660                        Int32 * pFreq2T_2 = &pFreq2T[HALF_LONG_WINDOW];
1661                        Int32 * win = (Int32 *) & Long_Window_fxp[wnd_shape_prev_bk][0];
1662
1663                        Int shift = exp + 15 - SCALING;
1664
1665                        for (i = HALF_LONG_WINDOW; i != 0; i--)
1666                        {
1667                            Int16 win1, win2;
1668                            Int32  temp2, test2;
1669
1670                            Int32  winx;
1671
1672                            temp2 = *(pFreq2T++);
1673                            winx = *(win++);
1674
1675                            test  = *(pOverlap_and_Add_Buffer_1++);
1676                            test2 = *(pOverlap_and_Add_Buffer_1--);
1677                            temp  =   fxp_mul_16_by_16bb(temp2, winx) >> shift;
1678                            temp2 =   fxp_mul_16_by_16tt(temp2, winx) >> shift;
1679
1680                            limiter(*(pInterleaved_output), (temp + test));
1681
1682                            limiter(*(pInterleaved_output + 2), (temp2 + test2));
1683                            pInterleaved_output += 4;
1684
1685                            temp2 = *(pFreq2T_2++);
1686
1687                            win1  = *(pLong_Window_2--);
1688                            win2  = *(pLong_Window_2--);
1689                            temp  = fxp_mul_16_by_16bb(temp2, win1) >> shift;
1690                            test2 = fxp_mul_16_by_16tb(temp2, win2) >> shift;
1691
1692                            *(pOverlap_and_Add_Buffer_1++) = temp;
1693                            *(pOverlap_and_Add_Buffer_1++) = test2;
1694                        }
1695
1696                    }
1697
1698                }
1699
1700                break;
1701
1702                case LONG_START_SEQUENCE:
1703
1704                    pFreq_2_Time_data_2 =
1705                        &pFreq_2_Time_data_1[ HALF_LONG_WINDOW];
1706
1707                    pLong_Window_1 = &Long_Window_fxp[wnd_shape_prev_bk][0];
1708                    pLong_Window_2 = &pLong_Window_1[ HALF_LONG_WINDOW];
1709
1710                    pOverlap_and_Add_Buffer_1 = &Time_data[0];
1711                    pOverlap_and_Add_Buffer_2 = &Time_data[HALF_LONG_WINDOW];
1712
1713
1714                    pInterleaved_output   = Interleaved_output;
1715                    pInterleaved_output_2 = pInterleaved_output + (2 * HALF_LONG_WINDOW);
1716
1717
1718                    /*
1719                     *  process first  LONG_WINDOW elements
1720                     */
1721
1722                    shift = exp + 15 - SCALING;
1723
1724                    for (i = HALF_LONG_WINDOW; i != 0; i--)
1725                    {
1726                        Int16 win1, win2;
1727                        Int16  dat1, dat2;
1728                        Int32  test1, test2;
1729
1730                        dat1   = *(pFreq_2_Time_data_1++);
1731                        win1   = *(pLong_Window_1++);
1732                        test1  = *(pOverlap_and_Add_Buffer_1++);
1733
1734                        dat2  =  *(pFreq_2_Time_data_2++);
1735                        win2  = *(pLong_Window_2++);
1736                        test2 = *(pOverlap_and_Add_Buffer_2++);
1737
1738                        limiter(*(pInterleaved_output), (test1 + (fxp_mul_16_by_16(dat1, win1) >> shift)));
1739
1740                        pInterleaved_output   += 2;
1741
1742                        limiter(*(pInterleaved_output_2), (test2 + (fxp_mul_16_by_16(dat2, win2) >> shift)));
1743
1744                        pInterleaved_output_2    += 2;
1745                    }
1746
1747
1748                    /*
1749                     *  data unchanged from  LONG_WINDOW to W_L_START_1
1750                     *  only scaled accordingly
1751                     */
1752
1753                    pOverlap_and_Add_Buffer_1 = &Time_data[0];
1754                    pFreq_2_Time_data_1       = &pFreqInfo[LONG_WINDOW];
1755
1756                    exp -= SCALING;
1757
1758                    if (exp >= 0)
1759                    {
1760
1761                        for (i = (W_L_START_1 - LONG_WINDOW) >> 1; i != 0; i--)
1762                        {
1763                            *(pOverlap_and_Add_Buffer_1++) =
1764                                *(pFreq_2_Time_data_1++) >> exp;
1765                            *(pOverlap_and_Add_Buffer_1++) =
1766                                *(pFreq_2_Time_data_1++) >> exp;
1767
1768                        }
1769
1770                    }
1771                    else if (exp < 0)
1772                    {
1773
1774                        Int shift = -exp;
1775                        for (i = (W_L_START_1 - LONG_WINDOW) >> 1; i != 0 ; i--)
1776                        {
1777                            Int32 temp2 = ((Int32) * (pFreq_2_Time_data_1++)) << shift;
1778                            *(pOverlap_and_Add_Buffer_1++) = temp2;
1779                            temp2 = ((Int32) * (pFreq_2_Time_data_1++)) << shift;
1780                            *(pOverlap_and_Add_Buffer_1++) = temp2;
1781                        }
1782
1783                    }
1784                    else
1785                    {
1786
1787                        for (i = (W_L_START_1 - LONG_WINDOW) >> 1; i != 0; i--)
1788                        {
1789                            *(pOverlap_and_Add_Buffer_1++) =
1790                                *(pFreq_2_Time_data_1++);
1791                            *(pOverlap_and_Add_Buffer_1++) =
1792                                *(pFreq_2_Time_data_1++);
1793
1794                        }
1795
1796                    }
1797
1798
1799                    pFreq_2_Time_data_1  = &pFreqInfo[W_L_START_1];
1800                    pFreq_2_Time_data_2  =
1801                        &pFreq_2_Time_data_1[HALF_SHORT_WINDOW];
1802
1803                    pShort_Window_1   =
1804                        &Short_Window_fxp[wnd_shape_this_bk][SHORT_WINDOW_m_1];
1805
1806                    pShort_Window_2   = pShort_Window_1 - HALF_SHORT_WINDOW;
1807
1808                    pOverlap_and_Add_Buffer_2 = pOverlap_and_Add_Buffer_1 +
1809                                                HALF_SHORT_WINDOW;
1810
1811                    {
1812                        Int16 win1, win2;
1813                        Int16  dat1, dat2;
1814                        Int32  temp2;
1815
1816                        for (i = HALF_SHORT_WINDOW; i != 0; i--)
1817                        {
1818
1819                            dat1  = (*pFreq_2_Time_data_1++);
1820                            dat2  = (*pFreq_2_Time_data_2++);
1821                            win1  = *(pShort_Window_1--);
1822                            win2  = *(pShort_Window_2--);
1823
1824                            temp   =   fxp_mul_16_by_16(dat1, win1) >> shift;
1825                            *(pOverlap_and_Add_Buffer_1++) = temp;
1826
1827                            temp2 =   fxp_mul_16_by_16(dat2, win2) >> shift;
1828                            *(pOverlap_and_Add_Buffer_2++) = temp2;
1829
1830                        }
1831                    }
1832
1833                    pOverlap_and_Add_Buffer_1 += HALF_SHORT_WINDOW;
1834
1835
1836                    pv_memset(
1837                        pOverlap_and_Add_Buffer_1,
1838                        0,
1839                        (LONG_BLOCK1 - W_L_START_2)
1840                        *sizeof(*pOverlap_and_Add_Buffer_1));
1841
1842
1843                    break;
1844
1845
1846                case LONG_STOP_SEQUENCE:
1847
1848                    pOverlap_and_Add_Buffer_1 = &Time_data[ W_L_STOP_2];
1849
1850                    pInterleaved_output    = &Interleaved_output[2*W_L_STOP_2];
1851
1852                    pFreq_2_Time_data_1      = &pFreqInfo[W_L_STOP_2];
1853
1854                    exp -= SCALING;
1855
1856
1857                    if (exp > 0)
1858                    {
1859                        Int16 tmp1 = (*(pFreq_2_Time_data_1++) >> exp);
1860                        temp = *(pOverlap_and_Add_Buffer_1++);
1861
1862                        for (i = (LONG_WINDOW - W_L_STOP_2); i != 0; i--)
1863                        {
1864                            limiter(*(pInterleaved_output), (temp + tmp1));
1865
1866                            pInterleaved_output += 2;
1867                            tmp1 = *(pFreq_2_Time_data_1++) >> exp;
1868                            temp = *(pOverlap_and_Add_Buffer_1++);
1869                        }
1870                    }
1871                    else if (exp < 0)
1872                    {
1873                        shift = -exp;
1874
1875                        Int32 temp1 = ((Int32) * (pFreq_2_Time_data_1++)) << shift;
1876                        temp = *(pOverlap_and_Add_Buffer_1++);
1877
1878                        for (i = (LONG_WINDOW - W_L_STOP_2); i != 0; i--)
1879                        {
1880                            limiter(*(pInterleaved_output), (temp + temp1));
1881
1882                            pInterleaved_output += 2;
1883                            temp1 = ((Int32) * (pFreq_2_Time_data_1++)) << shift;
1884                            temp = *(pOverlap_and_Add_Buffer_1++);
1885                        }
1886                    }
1887                    else
1888                    {
1889                        Int16 tmp1 = *(pFreq_2_Time_data_1++);
1890                        temp = *(pOverlap_and_Add_Buffer_1++);
1891                        for (i = (LONG_WINDOW - W_L_STOP_2); i != 0; i--)
1892                        {
1893                            limiter(*(pInterleaved_output), (temp + tmp1));
1894
1895                            pInterleaved_output += 2;
1896                            tmp1 = *(pFreq_2_Time_data_1++);
1897                            temp = *(pOverlap_and_Add_Buffer_1++);
1898                        }
1899                    }
1900
1901
1902
1903                    pShort_Window_1 = &Short_Window_fxp[wnd_shape_prev_bk][0];
1904                    pShort_Window_2 = &pShort_Window_1[HALF_SHORT_WINDOW];
1905
1906                    pFreq_2_Time_data_1 = &pFreqInfo[W_L_STOP_1];
1907                    pFreq_2_Time_data_2 =
1908                        &pFreq_2_Time_data_1[HALF_SHORT_WINDOW];
1909
1910                    pOverlap_and_Add_Buffer_1 = &Time_data[ W_L_STOP_1];
1911                    pOverlap_and_Add_Buffer_2 = pOverlap_and_Add_Buffer_1
1912                                                + HALF_SHORT_WINDOW;
1913
1914
1915                    pInterleaved_output   = &Interleaved_output[2*W_L_STOP_1];
1916                    pInterleaved_output_2 = pInterleaved_output + (2 * HALF_SHORT_WINDOW);
1917
1918                    exp += SCALING;  /* +8 back to what it was */
1919                    shift = exp + 15 - SCALING;
1920
1921
1922                    for (i = HALF_SHORT_WINDOW; i != 0; i--)
1923                    {
1924
1925                        Int16 win1;
1926                        Int16 dat1;
1927
1928                        dat1 = *(pFreq_2_Time_data_1++);
1929                        win1 = *(pShort_Window_1++);
1930                        temp = *(pOverlap_and_Add_Buffer_1++);
1931
1932                        test  = fxp_mul_16_by_16(dat1, win1);
1933
1934                        limiter(*(pInterleaved_output), (temp + (test >> shift)));
1935
1936                        pInterleaved_output += 2;
1937
1938                        dat1 = *(pFreq_2_Time_data_2++);
1939                        win1 = *(pShort_Window_2++);
1940                        temp = *(pOverlap_and_Add_Buffer_2++);
1941                        test =  fxp_mul_16_by_16(dat1, win1);
1942
1943                        limiter(*(pInterleaved_output_2), (temp + (test >> shift)));
1944
1945                        pInterleaved_output_2 += 2;
1946
1947                    }
1948
1949
1950
1951                    pFreq_2_Time_data_2 = &pFreqInfo[LONG_WINDOW];
1952
1953                    pOverlap_and_Add_Buffer_1 = Time_data;
1954
1955
1956                    pInterleaved_output = Interleaved_output;
1957
1958                    pLong_Window_2   =
1959                        &Long_Window_fxp[wnd_shape_this_bk][LONG_WINDOW_m_1];
1960
1961
1962                    /*
1963                     *  Copy previous time in current buffer, also copy overlap
1964                     *  and add buffer
1965                     */
1966
1967                    for (i = W_L_STOP_1; i != 0; i--)
1968                    {
1969
1970                        Int16 win1;
1971                        Int16 dat1;
1972
1973                        win1 = *(pLong_Window_2--);
1974                        dat1 = *pFreq_2_Time_data_2++;
1975
1976                        limiter(*(pInterleaved_output), *(pOverlap_and_Add_Buffer_1));
1977
1978                        pInterleaved_output += 2;
1979
1980                        temp = fxp_mul_16_by_16(dat1, win1) >> shift;
1981                        *(pOverlap_and_Add_Buffer_1++) = temp ;
1982
1983                    }
1984
1985                    for (i = (LONG_WINDOW - W_L_STOP_1); i != 0; i--)
1986                    {
1987
1988                        temp = fxp_mul_16_by_16(*pFreq_2_Time_data_2++, *(pLong_Window_2--)) >> shift;
1989                        *(pOverlap_and_Add_Buffer_1++) = temp ;
1990
1991                    }
1992
1993                    break;
1994
1995
1996
1997            } /* switch (wnd_seq) */
1998
1999        }   /*  if (exp < 16)  */
2000
2001        else
2002        {
2003            /* all zeros buffer or excessive down shift */
2004
2005            /* Overlap and add, setup buffer for next iteration */
2006            pOverlap_and_Add_Buffer_1 = &Time_data[0];
2007
2008            pInterleaved_output = Interleaved_output;
2009
2010
2011            temp  = (*pOverlap_and_Add_Buffer_1++);
2012            for (i = LONG_WINDOW; i != 0; i--)
2013            {
2014
2015                limiter(*(pInterleaved_output), temp);
2016
2017                pInterleaved_output += 2;
2018                temp  = (*pOverlap_and_Add_Buffer_1++);
2019            }
2020            pv_memset(Time_data, 0, LONG_WINDOW*sizeof(Time_data[0]));
2021        }
2022
2023    }
2024    else
2025    {
2026
2027        Int32 *pScrath_mem;
2028        Int32 *pScrath_mem_entry;
2029        Int32  *pFrequency_data = Frequency_data;
2030
2031        Int32 * pOverlap_and_Add_Buffer_1;
2032        Int32 * pOverlap_and_Add_Buffer_2;
2033        Int32 * pOverlap_and_Add_Buffer_1x;
2034        Int32 * pOverlap_and_Add_Buffer_2x;
2035
2036
2037        /*
2038         *  Frequency_data is 2*LONG_WINDOW length but only
2039         *  the first LONG_WINDOW elements are filled in,
2040         *  then the second part can be used as scratch mem,
2041         *  then grab data from one window at a time in
2042         *  reverse order.
2043         *  The upper LONG_WINDOW Int32 are used to hold the
2044         *  computed overlap and add, used in the next call to
2045         *  this function, and also as sctrach memory
2046         */
2047
2048        /*
2049         *  Frequency_data usage for the case EIGHT_SHORT_SEQUENCE
2050
2051          |<----- Input Freq. data ----->|< Overlap & Add ->| Unused |-Scratch-|
2052          |                              |  Store for next  |        |  memory |
2053          |                              |  call            |        |         |
2054          |                              |                  |        |         |
2055          |//////////////////////////////|\\\\\\\\\\\\\\\\\\|--------|+++++++++|
2056          |                              |                  |        |         |
2057          0                         LONG_WINDOW        LONG_WINDOW   |   2*LONG_WINDOW
2058                                                            +        |         |
2059                                                       W_L_STOP_2    |         |
2060                                                                     |<--   -->|
2061                                                                      SHORT_WINDOW +
2062                                                                    HALF_SHORT_WINDOW
2063          *
2064          */
2065
2066        pOverlap_and_Add_Buffer_1  = &pFrequency_data[
2067                                         LONG_WINDOW + 3*SHORT_WINDOW + HALF_SHORT_WINDOW];
2068
2069        /*
2070         *  Initialize to zero, only the firt short window used in overlap
2071         *  and add
2072         */
2073        pv_memset(
2074            pOverlap_and_Add_Buffer_1,
2075            0,
2076            SHORT_WINDOW*sizeof(*pOverlap_and_Add_Buffer_1));
2077
2078        /*
2079         *  Showt windows are evaluated in decresing order. Windows from 7
2080         *  to 0 are break down in four cases: window numbers 7 to 5, 4, 3,
2081         *  and 2 to 0.
2082         *  The data from short windows 3 and 4 is situated at the boundary
2083         *  between the 'overlap and add' buffer and the output buffer.
2084         */
2085        for (wnd = NUM_SHORT_WINDOWS - 1; wnd >= NUM_SHORT_WINDOWS / 2 + 1; wnd--)
2086        {
2087
2088            pFreqInfo = (Int16 *) & pFrequency_data[ wnd*SHORT_WINDOW];
2089
2090            exp = imdct_fxp(
2091                      (Int32 *)pFreqInfo,
2092                      freq_2_time_buffer,
2093                      SHORT_BLOCK1,
2094                      Q_format,
2095                      abs_max_per_window[wnd]);
2096
2097            /*  W_L_STOP_1 == (LONG_WINDOW - SHORT_WINDOW)>>1 */
2098            pOverlap_and_Add_Buffer_1 =
2099                &pFrequency_data[ W_L_STOP_1 + SHORT_WINDOW*wnd];
2100
2101
2102            pOverlap_and_Add_Buffer_2 =
2103                pOverlap_and_Add_Buffer_1 + SHORT_WINDOW;
2104
2105            /*
2106             *  If all element are zero or if the exponent is bigger than
2107             *  16 ( it becomes an undefined shift) ->  skip
2108             */
2109
2110            if (exp < 16)
2111            {
2112
2113
2114                pFreq_2_Time_data_1 = &pFreqInfo[0];
2115                pFreq_2_Time_data_2 = &pFreqInfo[SHORT_WINDOW];
2116
2117
2118                /*
2119                 *  Each of the eight short blocks is windowed separately.
2120                 *  Window shape decisions are made on a frame-by-frame
2121                 *  basis.
2122                 */
2123
2124                pShort_Window_1 = &Short_Window_fxp[wnd_shape_this_bk][0];
2125
2126                pShort_Window_2   =
2127                    &Short_Window_fxp[wnd_shape_this_bk][SHORT_WINDOW_m_1];
2128
2129
2130
2131
2132                /*
2133                 * For short windows from 7 to 5
2134                 *                                      |   =========================
2135                 *                                      |   |     5     6     7
2136                 *               _--_  _--_  _--_  _--_ | _-|-_  _--_  _--_  _--_
2137                 *              /    \/    \/    \/    \|/  |  \/    \/    \/    \
2138                 *             /     /\    /\    /\    /|\  |  /\    /\    /\     \
2139                 *            /     /  \  /  \  /  \  / | \ | /  \  /  \  /  \     \
2140                 *           /     /    \/    \/    \/  |  \|/    \/    \     \     \
2141                 *      --------------------------------|---[///////////////////////]--------
2142                 *
2143                 */
2144
2145
2146                shift = exp + 15 - SCALING;
2147
2148
2149                for (i = SHORT_WINDOW; i != 0; i--)
2150                {
2151                    Int16 win1, win2;
2152                    Int16  dat1, dat2;
2153
2154                    dat2 = *(pFreq_2_Time_data_2++);
2155                    win2 = *(pShort_Window_2--);
2156                    temp = *pOverlap_and_Add_Buffer_2;
2157                    dat1 = *(pFreq_2_Time_data_1++);
2158                    win1 = *(pShort_Window_1++);
2159
2160                    *(pOverlap_and_Add_Buffer_2++) =  temp + (fxp_mul_16_by_16(dat2, win2) >> shift);
2161
2162                    *(pOverlap_and_Add_Buffer_1++)  =  fxp_mul_16_by_16(dat1, win1) >> shift;
2163
2164                }
2165
2166            }   /* if (exp < 16) */
2167            else
2168            {
2169                pv_memset(
2170                    pOverlap_and_Add_Buffer_1,
2171                    0,
2172                    SHORT_WINDOW*sizeof(*pOverlap_and_Add_Buffer_1));
2173            }
2174
2175
2176        }/* for ( wnd=NUM_SHORT_WINDOWS-1; wnd>=NUM_SHORT_WINDOWS/2; wnd--) */
2177
2178
2179        wnd = NUM_SHORT_WINDOWS / 2;
2180
2181        pFreqInfo = (Int16 *) & pFrequency_data[ wnd*SHORT_WINDOW];
2182
2183        /*
2184         *  scratch memory is allocated in an unused part of memory
2185         */
2186
2187
2188        pScrath_mem = &pFrequency_data[ 2*LONG_WINDOW - HALF_SHORT_WINDOW];
2189
2190        pOverlap_and_Add_Buffer_1 = &pFrequency_data[ LONG_WINDOW];
2191
2192        pOverlap_and_Add_Buffer_2 = pOverlap_and_Add_Buffer_1
2193                                    + HALF_SHORT_WINDOW;
2194
2195
2196        exp = imdct_fxp(
2197                  (Int32 *)pFreqInfo,
2198                  freq_2_time_buffer,
2199                  SHORT_BLOCK1,
2200                  Q_format,
2201                  abs_max_per_window[wnd]);
2202
2203        /*
2204         *  If all element are zero or if the exponent is bigger than
2205         *  16 ( it becomes an undefined shift) ->  skip
2206         */
2207
2208
2209        if (exp < 16)
2210        {
2211
2212            pFreq_2_Time_data_1 = &pFreqInfo[0];
2213            pFreq_2_Time_data_2 = &pFreqInfo[SHORT_WINDOW];
2214
2215            pShort_Window_1 = &Short_Window_fxp[wnd_shape_this_bk][0];
2216
2217            pShort_Window_2 =
2218                &Short_Window_fxp[wnd_shape_this_bk][SHORT_WINDOW_m_1];
2219
2220
2221            /*
2222             * For short window 4
2223             *                                    ====|===========
2224             *                                        |   4
2225             *                                    |   |   |      |
2226             *                _--_  _--_  _--_  _-|-_ | _-|-_  _-|-_  _--_  _--_
2227             *               /    \/    \/    \/  |  \|/  |  \/  |  \/    \/    \
2228             *              /     /\    /\    /\  |  /|\  |  /\  |  /\    /\     \
2229             *             /     /  \  /  \  /  \ | / | \ | /  \ | /  \  /  \     \
2230             *            /     /    \/    \/    \|/  |  \|/    \|/    \/    \     \
2231             *      ------------------------------[\\\|\\\|//////]-------------------
2232             *           |                        | A | B |   C  |
2233             *           |
2234             *        W_L_STOP_1
2235             */
2236
2237            shift = exp + 15 - SCALING;
2238            {
2239                Int16 win1;
2240                Int16  dat1;
2241                /* -------- segment A ---------------*/
2242                dat1 = *(pFreq_2_Time_data_1++);
2243                win1 = *(pShort_Window_1++);
2244                for (i = HALF_SHORT_WINDOW; i != 0; i--)
2245                {
2246                    *(pScrath_mem++)  =  fxp_mul_16_by_16(dat1, win1) >> shift;
2247                    dat1 = *(pFreq_2_Time_data_1++);
2248                    win1 = *(pShort_Window_1++);
2249                }
2250
2251                /* -------- segment B ---------------*/
2252                for (i = HALF_SHORT_WINDOW; i != 0; i--)
2253                {
2254                    *(pOverlap_and_Add_Buffer_1++)  =  fxp_mul_16_by_16(dat1, win1) >> shift;
2255
2256                    dat1 = *(pFreq_2_Time_data_1++);
2257                    win1 = *(pShort_Window_1++);
2258                }
2259
2260                /* -------- segment C ---------------*/
2261                temp = *pOverlap_and_Add_Buffer_2;
2262                dat1 = *(pFreq_2_Time_data_2++);
2263                win1 = *(pShort_Window_2--);
2264
2265                for (i = SHORT_WINDOW; i != 0; i--)
2266                {
2267                    *(pOverlap_and_Add_Buffer_2++)  =  temp + (fxp_mul_16_by_16(dat1, win1) >> shift);
2268
2269                    temp = *pOverlap_and_Add_Buffer_2;
2270                    dat1 = *(pFreq_2_Time_data_2++);
2271                    win1 = *(pShort_Window_2--);
2272                }
2273            }
2274
2275        }   /* if (exp < 16) */
2276        else
2277        {
2278            pv_memset(
2279                pScrath_mem,
2280                0,
2281                HALF_SHORT_WINDOW*sizeof(*pScrath_mem));
2282
2283            pv_memset(
2284                pOverlap_and_Add_Buffer_1,
2285                0,
2286                HALF_SHORT_WINDOW*sizeof(*pOverlap_and_Add_Buffer_1));
2287        }
2288
2289
2290        wnd = NUM_SHORT_WINDOWS / 2 - 1;
2291
2292        pFreqInfo = (Int16 *) & pFrequency_data[ wnd*SHORT_WINDOW];
2293
2294        pScrath_mem_entry =
2295            &pFrequency_data[2*LONG_WINDOW - HALF_SHORT_WINDOW - SHORT_WINDOW];
2296
2297
2298        pScrath_mem = pScrath_mem_entry;
2299
2300        pOverlap_and_Add_Buffer_1 = &pFrequency_data[ LONG_WINDOW];
2301
2302        /* point to end of buffer less HALF_SHORT_WINDOW */
2303
2304        pInterleaved_output_2 = &Interleaved_output[2*(LONG_WINDOW - HALF_SHORT_WINDOW)];
2305        pInterleaved_output = pInterleaved_output_2;
2306
2307        pOverlap_and_Add_Buffer_1x = &Time_data[W_L_STOP_1 + SHORT_WINDOW*(wnd+1)];
2308
2309
2310        exp = imdct_fxp(
2311                  (Int32 *)pFreqInfo,
2312                  freq_2_time_buffer,
2313                  SHORT_BLOCK1,
2314                  Q_format,
2315                  abs_max_per_window[wnd]);
2316
2317        /*
2318         *  If all element are zero or if the exponent is bigger than
2319         *  16 ( it becomes an undefined shift) ->  skip
2320         */
2321
2322        if (exp < 16)
2323        {
2324
2325            pFreq_2_Time_data_1 = &pFreqInfo[0];
2326            pFreq_2_Time_data_2 = &pFreqInfo[SHORT_WINDOW];
2327
2328
2329            /*
2330             * For short window 3
2331             *                             ===========|====
2332             *                                    3   |
2333             *                             |      |   |   |
2334             *               _--_  _--_  _-|-_  _-|-_ | _-|-_  _--_  _--_  _--_
2335             *              /    \/    \/  |  \/  |  \|/  |  \/    \/    \/    \
2336             *             /     /\    /\  |  /\  |  /|\  |  /\    /\    /\     \
2337             *            /     /  \  /  \ | /  \ | / | \ | /  \  /  \  /  \     \
2338             *           /     /    \/    \|/    \|/  |  \|/    \/    \     \     \
2339             *     -----|------------------[\\\\\\|///|///]--------------------------
2340             *          |                  |   A  | B | C |
2341             *
2342             *      W_L_STOP_1
2343             */
2344
2345
2346            pShort_Window_1 = &Short_Window_fxp[wnd_shape_this_bk][0];
2347
2348            pShort_Window_2 =
2349                &Short_Window_fxp[wnd_shape_this_bk][SHORT_WINDOW_m_1];
2350
2351            shift = exp + 15 - SCALING;
2352
2353            Int16 win1;
2354            Int16  dat1;
2355            /* -------- segment A ---------------*/
2356            dat1 = *(pFreq_2_Time_data_1++);
2357            win1 = *(pShort_Window_1++);
2358            for (i = SHORT_WINDOW; i != 0; i--)
2359            {
2360                *(pScrath_mem++)  =  fxp_mul_16_by_16(dat1, win1) >> shift;
2361                dat1 = *(pFreq_2_Time_data_1++);
2362                win1 = *(pShort_Window_1++);
2363            }
2364
2365            dat1 = *(pFreq_2_Time_data_2++);
2366            win1 = *(pShort_Window_2--);
2367
2368
2369            /* -------- segment B ---------------*/
2370            for (i = HALF_SHORT_WINDOW; i != 0; i--)
2371            {
2372                test = fxp_mul_16_by_16(dat1, win1) >> shift;
2373
2374                temp =  *(pScrath_mem++) + test;
2375
2376                test = *(pOverlap_and_Add_Buffer_1x++);
2377                limiter(*(pInterleaved_output), (temp + test));
2378
2379
2380                pInterleaved_output += 2;
2381                dat1 = *(pFreq_2_Time_data_2++);
2382                win1 = *(pShort_Window_2--);
2383
2384            }
2385
2386            /* -------- segment C ---------------*/
2387            for (i = HALF_SHORT_WINDOW; i != 0; i--)
2388            {
2389
2390                temp = fxp_mul_16_by_16(dat1, win1) >> shift;
2391
2392                *(pOverlap_and_Add_Buffer_1++) += temp;
2393
2394                dat1 = *(pFreq_2_Time_data_2++);
2395                win1 = *(pShort_Window_2--);
2396            }
2397
2398
2399        }   /* if (exp < 16) */
2400        else
2401        {
2402
2403            pv_memset(
2404                pScrath_mem,
2405                0,
2406                SHORT_WINDOW*sizeof(*pScrath_mem));
2407
2408            pScrath_mem += SHORT_WINDOW;
2409
2410            temp = *(pScrath_mem++);
2411            for (i = HALF_SHORT_WINDOW; i != 0; i--)
2412            {
2413                limiter(*(pInterleaved_output), (temp));
2414
2415                pInterleaved_output += 2;
2416                temp = *(pScrath_mem++);
2417
2418            }
2419        }
2420
2421
2422        for (wnd = NUM_SHORT_WINDOWS / 2 - 2; wnd >= 0; wnd--)
2423        {
2424
2425
2426            pInterleaved_output_2 -= (SHORT_WINDOW * 2);
2427            pInterleaved_output = pInterleaved_output_2;
2428
2429            /*
2430             * The same memory is used as scratch in every iteration
2431             */
2432            pScrath_mem = pScrath_mem_entry;
2433
2434            pOverlap_and_Add_Buffer_2x =
2435                &Time_data[W_L_STOP_1 + SHORT_WINDOW*(wnd+1)];
2436
2437            pFreqInfo = (Int16 *) & pFrequency_data[ wnd*SHORT_WINDOW];
2438
2439
2440
2441            exp = imdct_fxp(
2442                      (Int32 *)pFreqInfo,
2443                      freq_2_time_buffer,
2444                      SHORT_BLOCK1,
2445                      Q_format,
2446                      abs_max_per_window[wnd]);
2447
2448            /*
2449             *  If all element are zero or if the exponent is bigger than
2450             *  16 ( it becomes an undefined shift) ->  skip
2451             */
2452
2453            if (exp < 16)
2454            {
2455
2456                pFreq_2_Time_data_1 = &pFreqInfo[0];
2457                pFreq_2_Time_data_2 = &pFreqInfo[SHORT_WINDOW];
2458
2459
2460                /*
2461                 *  Each of the eight short blocks is windowed separately.
2462                 *  Window shape decisions are made on a frame-by-frame
2463                 *  basis.
2464                 */
2465
2466                pShort_Window_1 = &Short_Window_fxp[wnd_shape_this_bk][0];
2467
2468                if (wnd == 0)
2469                {
2470                    pShort_Window_1 =
2471                        &Short_Window_fxp[wnd_shape_prev_bk][0];
2472                }
2473
2474                pShort_Window_2   =
2475                    &Short_Window_fxp[wnd_shape_this_bk][SHORT_WINDOW_m_1];
2476
2477
2478                /*
2479                 * For short windows from 2 to 0
2480                 *
2481                 *          =========================
2482                 *                                       |
2483                 *                0     1     2      |   |
2484                 *               _--_  _--_  _--_  _-|-_ | _--_  _--_  _--_  _--_
2485                 *              /    \/    \/    \/  |  \|/    \/    \/    \/    \
2486                 *             /     /\    /\    /\  |  /|\    /\    /\    /\     \
2487                 *            /     /  \  /  \  /  \ | / | \  /  \  /  \  /  \     \
2488                 *           /     /    \/    \/    \|/  |  \/    \/    \     \     \
2489                 *      ----[\\\\\\\\\\\\\\\\\\\\\\\\]---|-----------------------------
2490                 *          |
2491                 *
2492                 *      W_L_STOP_1
2493                 */
2494
2495                shift = exp + 15 - SCALING;
2496
2497                Int16 dat1 = *(pFreq_2_Time_data_2++);
2498                Int16 win1 = *(pShort_Window_2--);
2499
2500                temp  =  *(pScrath_mem);
2501                for (i = SHORT_WINDOW; i != 0; i--)
2502                {
2503                    test  =  fxp_mul_16_by_16(dat1, win1) >> shift;
2504
2505                    temp += test;
2506                    dat1 = *(pFreq_2_Time_data_1++);
2507                    win1 = *(pShort_Window_1++);
2508
2509                    limiter(*(pInterleaved_output), (temp + *(pOverlap_and_Add_Buffer_2x++)));
2510
2511                    pInterleaved_output += 2;
2512
2513                    *(pScrath_mem++) = fxp_mul_16_by_16(dat1, win1) >> shift;
2514                    dat1 = *(pFreq_2_Time_data_2++);
2515                    win1 = *(pShort_Window_2--);
2516                    temp  =  *(pScrath_mem);
2517
2518                }
2519
2520            }   /* if (exp < 16) */
2521            else
2522            {
2523                test  = *(pScrath_mem);
2524                temp  = *(pOverlap_and_Add_Buffer_2x++);
2525
2526                for (i = SHORT_WINDOW; i != 0; i--)
2527                {
2528                    limiter(*(pInterleaved_output), (temp + test));
2529
2530                    pInterleaved_output += 2;
2531
2532                    *(pScrath_mem++) = 0;
2533                    test  =  *(pScrath_mem);
2534                    temp  = *(pOverlap_and_Add_Buffer_2x++);
2535                }
2536            }
2537
2538        }   /* for ( wnd=NUM_SHORT_WINDOWS/2-1; wnd>=0; wnd--) */
2539
2540        pOverlap_and_Add_Buffer_2x =  &Time_data[W_L_STOP_1];
2541
2542        pScrath_mem = pScrath_mem_entry;
2543
2544        pInterleaved_output_2 -= (SHORT_WINDOW * 2);
2545        pInterleaved_output    = pInterleaved_output_2;
2546
2547        test  = *(pScrath_mem++);
2548        temp  = *(pOverlap_and_Add_Buffer_2x++);
2549
2550        for (i = SHORT_WINDOW; i != 0; i--)
2551        {
2552            limiter(*(pInterleaved_output), (temp + test));
2553
2554            pInterleaved_output += 2;
2555            test  = *(pScrath_mem++);
2556            temp  = *(pOverlap_and_Add_Buffer_2x++);
2557
2558        }
2559
2560        pOverlap_and_Add_Buffer_1x = Time_data;
2561
2562        pInterleaved_output = Interleaved_output;
2563
2564
2565        temp = *(pOverlap_and_Add_Buffer_1x++);
2566        for (i = W_L_STOP_1; i != 0; i--)
2567        {
2568            limiter(*(pInterleaved_output), temp);
2569
2570            pInterleaved_output += 2;
2571            temp = *(pOverlap_and_Add_Buffer_1x++);
2572
2573        }
2574
2575        pOverlap_and_Add_Buffer_1x = &Time_data[0];
2576
2577        pOverlap_and_Add_Buffer_2 = &pFrequency_data[LONG_WINDOW];
2578
2579        /*
2580         *  update overlap and add buffer,
2581         *  so is ready for next iteration
2582         */
2583
2584        for (int i = 0; i < W_L_STOP_2; i++)
2585        {
2586            temp = *(pOverlap_and_Add_Buffer_2++);
2587            *(pOverlap_and_Add_Buffer_1x++) = temp;
2588        }
2589
2590        pv_memset(
2591            pOverlap_and_Add_Buffer_1x,
2592            0,
2593            W_L_STOP_1*sizeof(*pOverlap_and_Add_Buffer_1x));
2594
2595    } /* if ( wnd_seq != EIGHT_SHORT_SEQUENCE) */
2596
2597
2598
2599
2600}   /* trans4m_freq_2_time_fxp */
2601
2602
2603
2604
2605