• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_time_2_freq_fxp.c
21   Function: trans4m_time_2_freq_fxp
22 
23 ------------------------------------------------------------------------------
24  REVISION HISTORY
25 
26  Description:
27         Modified normalization, so it now happen per window basis, eliminated
28         shifts left or rigth to accomodate TNS inverse filtering. The output
29         is 32 bits but only the lowest 16 are being used.
30         Modified fuction interface
31 
32  Description: Modified variable names with leading "p" for pointers
33 
34  Description:
35         Modified call to mdct_fxp to reflect extended precision use. Added routine
36         buffer_adaptation to extract 16 MSB and keep highest precision.
37         Modify casting to ensure proper operations for different platforms
38 
39  Description:
40         Added comments according to code review
41 
42  Description:
43         Removed include file "buffer_normalization.h"
44 
45  Description:
46         Eliminated buffer_adaptation() and embedded its functionality in other
47         functions. Commented out the short window section given that this is
48         not supported by the standards
49 
50  Description:
51         Added shift down operation for case when the window was equal to one.
52         This was not needed previuosly because buffer_adaptation() was doing
53         it.
54 
55  Description: Created local version of vectors Long_Window_fxp and
56               Short_Window_fxp. This solve linking problem when using the
57               /ropi option (Read-only position independent) for some
58               compilers.
59 
60 
61  Who:                       Date:
62  Description:
63 
64 ------------------------------------------------------------------------------
65  INPUT AND OUTPUT DEFINITIONS
66 
67  Inputs:
68     Time2Freq_data    =  buffer with data in the time domain, it holds 2048
69                          points of input time data
70                          Output holds frequency (first 1024 points )
71                          type Int32
72 
73     wnd_seq           =  window sequence
74                          type WINDOW_SEQUENCE
75 
76     wnd_shape_prev_bk =  previous window shape type
77                          type Int
78 
79     wnd_shape_this_bk =  current window shape type
80                          type Int
81 
82     pQ_format          =  Holds the Q format of the data in, and data out
83                          type Int *
84 
85     mem_4_in_place_FFT[] =  scratch memory for computing FFT, 1024 point
86                          type Int32
87 
88 
89 
90  Local Stores/Buffers/Pointers Needed:
91     None
92 
93  Global Stores/Buffers/Pointers Needed:
94     None
95 
96  Outputs:
97     None
98 
99  Pointers and Buffers Modified:
100     Frequency information (1024 pts.) is returned in Time2Freq_data
101     pQ_format content spectral coefficients Q format
102 
103  Local Stores Modified:
104     None
105 
106  Global Stores Modified:
107     None
108 
109 ------------------------------------------------------------------------------
110  FUNCTION DESCRIPTION
111 
112 The time/frequency representation of the signal is mapped onto the frequency
113 domain by feeding it into the filterbank module. This module consists of
114 a modified discrete cosine transform (MDCT), (windowing and DCT).
115 In order to adapt the time/frequency resolution of the filterbank to the
116  characteristics of the input signal, a block switching tool is also
117 adopted. N represents the window length, where N is a function of the
118 window_sequence. For each channel, the N time values are transformed into the
119 N/2 frequency domain values via the MDCT.
120 
121 The adaptation of the time-frequency resolution of the filterbank to the
122 characteristics of the input signal is done by shifting between transforms
123 whose input lengths are either 2048 or 256 samples. By enabling the block
124 switching tool, the following transitions are meaningful:
125 
126 from ONLY_LONG_SEQUENCE to   { LONG_START_SEQUENCE
127                                ONLY_LONG_SEQUENCE
128 
129 from LONG_START_SEQUENCE to  { LONG_STOP_SEQUENCE
130                                EIGHT_SHORT_SEQUENCE
131 
132 from LONG_STOP_SEQUENCE to   { LONG_START_SEQUENCE
133                                ONLY_LONG_SEQUENCE
134 
135 from EIGHT_SHORT_SEQUENCE to { LONG_STOP_SEQUENCE
136                                EIGHT_SHORT_SEQUENCE
137 
138 Window shape decisions are made by the encoder on a frame-by-frame-basis.
139 The window selected is applicable to the second half of the window function
140 only, since the first half is constrained to use the appropriate window
141 shape from the preceding frame.
142 The 2048 time-domain values x'(i)(n), (i window, n sample) to be windowed are
143 the last 1024 values of the previous window_sequence concatenated with 1024
144 values of the current block. The formula below shows this fact:
145 
146                      |  x(i-1)(n+1024)      for    0 < n < 1024
147             x'(i)(n) {
148                      |  x(i)(n)             for 1024 < n < 2048
149 
150 
151 
152 Once the window shape is selected, the window_shape syntax element is
153 initialized. Together with the chosen window_sequence all information needed
154 for windowing exist.
155 With the window halves described below all window_sequences can be assembled.
156 For window_shape == 1, the window coefficients are given by the Kaiser -
157 Bessel derived (KBD) window.
158 Otherwise, for window_shape == 0, a sine window is employed.
159 
160 The window length N can be 2048 or 256 for the KBD and the sine window.
161 All four window_sequences explained below have a total length of 2048
162 samples.
163 For all kinds of window_sequences the window_shape of the left half of
164 the first transform window is determined by the window shape of the previous
165 block.
166 ------------------------------------------------------------------------------
167  REQUIREMENTS
168 
169     This module shall implement a scheme to switch between window types and
170     in turn perform time to frequency transformations
171 
172 
173 ------------------------------------------------------------------------------
174  REFERENCES
175 
176     [1] ISO 14496-3:1999, pag 111
177 
178 ------------------------------------------------------------------------------
179  PSEUDO-CODE
180 
181     IF ( wnd_seq == EIGHT_SHORT_SEQUENCE)
182     THEN
183 
184 
185         FOR ( wnd=0; wnd<NUM_SHORT_WINDOWS; wnd++)
186 
187             time_info = &Time2Freq_data[ W_L_STOP_1 + wnd*SHORT_WINDOW]
188 
189             FOR( i=0; i<SHORT_BLOCK1; i++)
190                 aux_temp[i] = time_info[i]
191             ENDFOR
192 
193 
194             IF (wnd == 0)
195             THEN
196                 pShort_Window_1 = &Short_Window[wnd_shape_prev_bk][0]
197             ELSE
198                 pShort_Window_1 = &Short_Window[wnd_shape_this_bk][0]
199             ENDIF
200 
201 
202             pShort_Window_2   =
203                     &Short_Window[wnd_shape->this_bk][SHORT_WINDOW_m_1]
204 
205             FOR( i=0, j=SHORT_WINDOW; i<SHORT_WINDOW; i++, j--)
206                 aux_temp[             i]  *= pShort_Window_1[i]
207                 aux_temp[SHORT_WINDOW+i]  *= pShort_Window_2[j]
208             ENDFOR
209 
210 
211             CALL MDCT( aux_temp, SHORT_BLOCK1)
212             MODIFYING( aux_temp)
213 
214             FOR( i=0; i<SHORT_WINDOW; i++)
215                 Time2Freq_data[wnd*SHORT_WINDOW + i] = aux_temp[i];
216             ENDFOR
217 
218         ENDFOR
219 
220     ELSE
221 
222         SWITCH ( wnd_seq)
223 
224             CASE ( ONLY_LONG_SEQUENCE)
225 
226                 pLong_Window_1 = &Long_Window[wnd_shape_prev_bk][0]
227                 pLong_Window_2 =
228                         &Long_Window[wnd_shape_this_bk][LONG_WINDOW_m_1]
229 
230                 FOR (i=0; i<LONG_WINDOW; i++)
231                     Time2Freq_data[            i] *= *pLong_Window_1++
232                     Time2Freq_data[LONG_WINDOW+i] *= *pLong_Window_2--
233                 ENDFOR
234 
235                 BREAK
236 
237 
238             CASE ( LONG_START_SEQUENCE)
239 
240                 pLong_Window_1 = &Long_Window[wnd_shape_prev_bk][0];
241 
242                 FOR ( i=0; i<LONG_WINDOW; i++)
243                     Time2Freq_data[ i] *= *pLong_Window_1++;
244                 ENDFOR
245 
246 
247                 pShort_Window_1   =
248                         &Short_Window[wnd_shape->this_bk][SHORT_WINDOW_m_1];
249 
250                 FOR ( i=0; i<SHORT_WINDOW; i++)
251                     Time2Freq_data[W_L_START_1 + i] *= *pShort_Window_1--;
252                 ENDFOR
253 
254 
255                 FOR ( i=W_L_START_2; i<LONG_BLOCK1; i++)
256                     Time2Freq_data[W_L_START_2 + i] = 0;
257                 ENDFOR
258 
259                 BREAK
260 
261 
262             CASE ( LONG_STOP_SEQUENCE )
263 
264                 FOR ( i=0; i<W_L_STOP_1; i++)
265                     Time2Freq_data[ i] = 0;
266                 ENDFOR
267 
268 
269                 pShort_Window_1   = &Short_Window[wnd_shape->prev_bk][0];
270 
271                 FOR ( i=0; i<SHORT_WINDOW; i++)
272                     Time2Freq_data[W_L_STOP_1+ i] *= *pShort_Window_1++;
273                 ENDFOR
274 
275 
276                 pLong_Window_1 =
277                         &Long_Window[wnd_shape->this_bk][LONG_WINDOW_m_1];
278 
279                 FOR ( i=0; i<LONG_WINDOW; i++)
280                     Time2Freq_data[LONG_WINDOW + i]  *=  *pLong_Window_1--;
281                 ENDFOR
282 
283                 BREAK
284 
285 
286         }
287 
288         MDCT( Time2Freq_data, LONG_BLOCK1);
289         MODIFYING( Time2Freq_data)
290 
291     ENDIF
292 
293 ------------------------------------------------------------------------------
294  RESOURCES USED
295    When the code is written for a specific target processor the
296      the resources used should be documented below.
297 
298  STACK USAGE: [stack count for this module] + [variable to represent
299           stack usage for each subroutine called]
300 
301      where: [stack usage variable] = stack usage for [subroutine
302          name] (see [filename].ext)
303 
304  DATA MEMORY USED: x words
305 
306  PROGRAM MEMORY USED: x words
307 
308  CLOCK CYCLES: [cycle count equation for this module] + [variable
309            used to represent cycle count for each subroutine
310            called]
311 
312      where: [cycle count variable] = cycle count for [subroutine
313         name] (see [filename].ext)
314 
315 ------------------------------------------------------------------------------
316 */
317 
318 
319 /*----------------------------------------------------------------------------
320 ; INCLUDES
321 ----------------------------------------------------------------------------*/
322 
323 #include "pv_audio_type_defs.h"
324 #include "aac_mem_funcs.h"
325 #include "window_block_fxp.h"
326 #include "mdct_fxp.h"
327 #include "long_term_prediction.h"
328 #include    "fxp_mul32.h"
329 
330 
331 /*----------------------------------------------------------------------------
332 ; MACROS
333 ; Define module specific macros here
334 ----------------------------------------------------------------------------*/
335 
336 /*----------------------------------------------------------------------------
337 ; DEFINES
338 ; Include all pre-processor statements here. Include conditional
339 ; compile variables also.
340 ----------------------------------------------------------------------------*/
341 /*----------------------------------------------------------------------------
342 ; LOCAL FUNCTION DEFINITIONS
343 ; Function Prototype declaration
344 ----------------------------------------------------------------------------*/
345 
346 /*----------------------------------------------------------------------------
347 ; LOCAL VARIABLE DEFINITIONS
348 ; Variable declaration - defined here and used outside this module
349 ----------------------------------------------------------------------------*/
350 
351 /*----------------------------------------------------------------------------
352 ; EXTERNAL FUNCTION REFERENCES
353 ; Declare functions defined elsewhere and referenced in this module
354 ----------------------------------------------------------------------------*/
355 
356 /*----------------------------------------------------------------------------
357 ; EXTERNAL VARIABLES REFERENCES
358 ; Declare variables used in this module but defined elsewhere
359 ----------------------------------------------------------------------------*/
360 
361 /*----------------------------------------------------------------------------
362 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
363 ; Declare variables used in this module but defined elsewhere
364 ----------------------------------------------------------------------------*/
365 
366 /*----------------------------------------------------------------------------
367 ; FUNCTION CODE
368 ----------------------------------------------------------------------------*/
trans4m_time_2_freq_fxp(Int32 Time2Freq_data[],WINDOW_SEQUENCE wnd_seq,Int wnd_shape_prev_bk,Int wnd_shape_this_bk,Int * pQ_format,Int32 mem_4_in_place_FFT[])369 void trans4m_time_2_freq_fxp(
370     Int32   Time2Freq_data[],       /* time data size 2048 */
371     WINDOW_SEQUENCE wnd_seq,        /* window sequence */
372     Int     wnd_shape_prev_bk,      /* window shape, current and previous  */
373     Int     wnd_shape_this_bk,
374     Int     *pQ_format,
375     Int32   mem_4_in_place_FFT[])   /* scratch memory for computing FFT */
376 {
377 
378     Int  i;
379 
380     Int32   *pAux_temp_1;
381     Int32   *pAux_temp_2;
382     Int32   *pAux_temp;
383 //    Int32   temp;
384     const   Int16 *pLong_Window_1;
385     const   Int16 *pLong_Window_2;
386     const   Int16 *pShort_Window_1;
387     const   Int16 *pShort_Window_2;
388     Int     shift = *pQ_format - 1;
389 
390     const Int16 * Long_Window_fxp[NUM_WINDOW_SHAPES];
391     const Int16 * Short_Window_fxp[NUM_WINDOW_SHAPES];
392 
393     Long_Window_fxp[0] = Long_Window_sine_fxp;
394     Long_Window_fxp[1] = Long_Window_KBD_fxp;
395     Short_Window_fxp[0] = Short_Window_sine_fxp;
396     Short_Window_fxp[1] = Short_Window_KBD_fxp;
397 
398     if (wnd_seq != EIGHT_SHORT_SEQUENCE)
399     {
400 
401         pAux_temp = Time2Freq_data;
402 
403         *pQ_format = LTP_Q_FORMAT - *pQ_format;
404 
405         pAux_temp_1 = pAux_temp;
406 
407         switch (wnd_seq)
408         {
409 
410             case LONG_START_SEQUENCE:
411 
412                 pAux_temp_2 = &pAux_temp_1[HALF_LONG_WINDOW];
413 
414                 pLong_Window_1 = &Long_Window_fxp[wnd_shape_prev_bk][0];
415                 pLong_Window_2 = &pLong_Window_1[ HALF_LONG_WINDOW];
416 
417 
418 
419 
420                 for (i = HALF_LONG_WINDOW; i > 0; i--)
421                 {
422 
423                     *pAux_temp_1 = fxp_mul32_by_16((*pAux_temp_1), *pLong_Window_1++) >> shift;
424                     pAux_temp_1++;
425                     *pAux_temp_2 = fxp_mul32_by_16((*pAux_temp_2), *pLong_Window_2++) >> shift;
426                     pAux_temp_2++;
427 
428                 }
429 
430 
431                 /* data unchanged from  LONG_WINDOW to W_L_START_1 */
432                 pAux_temp_1 = &pAux_temp[LONG_WINDOW];
433                 if (shift)
434                 {
435                     for (i = (W_L_START_1 - LONG_WINDOW) >> 1; i != 0; i--)
436                     {
437                         *(pAux_temp_1++) >>= shift;
438                         *(pAux_temp_1++) >>= shift;
439                     }
440                 }
441 
442 
443                 pAux_temp_1 = &pAux_temp[W_L_START_1];
444                 pAux_temp_2 = &pAux_temp_1[HALF_SHORT_WINDOW];
445 
446                 pShort_Window_1   =
447                     &Short_Window_fxp[wnd_shape_this_bk][SHORT_WINDOW_m_1];
448 
449                 pShort_Window_2   = pShort_Window_1 - HALF_SHORT_WINDOW;
450 
451                 for (i = HALF_SHORT_WINDOW; i > 0; i--)
452                 {
453 
454                     *pAux_temp_1 = fxp_mul32_by_16((*pAux_temp_1), *pShort_Window_1--) >> shift;
455                     pAux_temp_1++;
456                     *pAux_temp_2 = fxp_mul32_by_16((*pAux_temp_2), *pShort_Window_2--) >> shift;
457                     pAux_temp_2++;
458 
459                 }
460 
461                 pAux_temp_1 = &pAux_temp[W_L_START_2];
462 
463                 pv_memset(
464                     pAux_temp_1,
465                     0,
466                     (LONG_BLOCK1 - W_L_START_2)*sizeof(*pAux_temp_1));
467 
468                 break;
469 
470 
471             case LONG_STOP_SEQUENCE:
472 
473                 pv_memset(
474                     pAux_temp_1,
475                     0,
476                     (W_L_STOP_1)*sizeof(*pAux_temp_1));
477 
478                 pShort_Window_1   = &Short_Window_fxp[wnd_shape_prev_bk][0];
479                 pShort_Window_2   = &pShort_Window_1[HALF_SHORT_WINDOW];
480 
481                 pAux_temp_1      = &pAux_temp_1[W_L_STOP_1];
482                 pAux_temp_2      = pAux_temp_1 + HALF_SHORT_WINDOW;
483 
484                 for (i = HALF_SHORT_WINDOW; i > 0; i--)
485                 {
486 
487                     *pAux_temp_1 = fxp_mul32_by_16((*pAux_temp_1), *pShort_Window_1++) >> shift;
488                     pAux_temp_1++;
489                     *pAux_temp_2 = fxp_mul32_by_16((*pAux_temp_2), *pShort_Window_2++) >> shift;
490                     pAux_temp_2++;
491 
492 
493                 }
494 
495                 /* data unchanged from  W_L_STOP_2 to LONG_WINDOW */
496                 pAux_temp_1 = &pAux_temp[W_L_STOP_2];
497 
498                 if (shift)
499                 {
500                     for (i = ((LONG_WINDOW - W_L_STOP_2) >> 1); i != 0; i--)
501                     {
502                         *(pAux_temp_1++) >>= shift;
503                         *(pAux_temp_1++) >>= shift;
504                     }
505                 }
506 
507 
508 
509                 pAux_temp_1 = &pAux_temp[LONG_WINDOW];
510                 pAux_temp_2 =  pAux_temp_1 + HALF_LONG_WINDOW;
511 
512                 pLong_Window_1 =
513                     &Long_Window_fxp[wnd_shape_this_bk][LONG_WINDOW_m_1];
514 
515 
516                 pLong_Window_2   = &pLong_Window_1[-HALF_LONG_WINDOW];
517 
518                 for (i = HALF_LONG_WINDOW; i > 0; i--)
519                 {
520                     *pAux_temp_1 = fxp_mul32_by_16((*pAux_temp_1), *pLong_Window_1--) >> shift;
521                     pAux_temp_1++;
522                     *pAux_temp_2 = fxp_mul32_by_16((*pAux_temp_2), *pLong_Window_2--) >> shift;
523                     pAux_temp_2++;
524 
525                 }
526 
527                 break;
528 
529             case ONLY_LONG_SEQUENCE:
530             default:
531 
532                 pAux_temp_2 = &pAux_temp[LONG_WINDOW];
533 
534                 pLong_Window_1 = &Long_Window_fxp[wnd_shape_prev_bk][0];
535 
536 
537                 pLong_Window_2 =
538                     &Long_Window_fxp[wnd_shape_this_bk][LONG_WINDOW_m_1];
539 
540 
541                 for (i = LONG_WINDOW; i > 0; i--)
542                 {
543 
544                     *pAux_temp_1 = fxp_mul32_by_16((*pAux_temp_1), *pLong_Window_1++) >> shift;
545                     pAux_temp_1++;
546                     *pAux_temp_2 = fxp_mul32_by_16((*pAux_temp_2), *pLong_Window_2--) >> shift;
547                     pAux_temp_2++;
548                 }
549 
550                 break;
551 
552         }   /* end switch ( wnd_seq)  */
553 
554 
555 
556         *pQ_format += mdct_fxp(
557                           pAux_temp,
558                           mem_4_in_place_FFT,
559                           LONG_BLOCK1);
560 
561 
562     }   /* end if( wnd_seq != EIGHT_SHORT_SEQUENCE) */
563 
564 
565 
566     /*****************************************/
567     /* decoding process for short window */
568     /*****************************************/
569 
570     /*
571      * For short window the following code will be applied
572      * in the future when short window is supported in the
573      * standards
574      */
575     /*-------------------------------------------------------------------------
576 
577     *        pAux_temp = &mem_4_in_place_FFT[(2*SHORT_BLOCK1)];
578     *
579     *        for ( wnd=0; wnd<NUM_SHORT_WINDOWS; wnd++)
580     *        {
581     *
582     *            pShort_Window_1 = &Short_Window_fxp[wnd_shape_this_bk][0];
583     *
584     *            if (wnd == 0)
585     *            {
586     *                pShort_Window_1 = &Short_Window_fxp[wnd_shape_prev_bk][0];
587     *            }
588     *
589     *            pShort_Window_2   =
590     *                    &Short_Window_fxp[wnd_shape_this_bk][SHORT_WINDOW_m_1];
591     *
592     *            pAux_temp_1 =  pAux_temp;
593     *            pAux_temp_2 = pAux_temp_1 + SHORT_WINDOW;
594     *
595     *            Q_aux = 0;
596     *
597     *            buffer_adaptation (
598     *                &Q_aux,
599     *                &Time2Freq_data[ W_L_STOP_1 + wnd*SHORT_WINDOW],
600     *                (void *) pAux_temp,
601     *                SHORT_BLOCK1,
602     *                USING_INT,
603     *                16);
604     *
605     *
606     *            for ( i=SHORT_WINDOW; i>0; i--)
607     *            {
608     *                temp           = (*pAux_temp_1) * *pShort_Window_1++;
609     *                *pAux_temp_1++ = (temp + 0x08000L) >> 16;
610     *
611     *                temp           = (*pAux_temp_2) * *pShort_Window_2--;
612     *                *pAux_temp_2++ = (temp + 0x08000L) >> 16;
613     *
614     *            }
615     *
616     *
617     *            exp = mdct_fxp(
618     *                pAux_temp,
619     *                mem_4_in_place_FFT,
620     *                SHORT_BLOCK1);
621     *
622     *
623     *            exp += Q_aux;
624     *
625     *            pAux_temp_1  =  pAux_temp;
626     *            pAux_temp_2  =  pAux_temp_1  +  HALF_SHORT_WINDOW;
627     *            pTime_data_1 = &Time2Freq_data[wnd*SHORT_WINDOW];
628     *            pTime_data_2 =  pTime_data_1 + HALF_SHORT_WINDOW;
629     *
630     *
631     *            if (exp > 0)
632     *            {
633     *                for ( i=HALF_SHORT_WINDOW; i>0; i--)
634     *                {
635     *                    *pTime_data_1++ = (*pAux_temp_1++>>exp);
636     *                    *pTime_data_2++ = (*pAux_temp_2++>>exp);
637     *                }
638     *            }
639     *            else if (exp < 0)
640     *            {
641     *                exp = -exp;
642     *                for ( i=HALF_SHORT_WINDOW; i>0; i--)
643     *                {
644     *                    *pTime_data_1++ = (*pAux_temp_1++<<exp);
645     *                    *pTime_data_2++ = (*pAux_temp_2++<<exp);
646     *                }
647     *            }
648     *            else
649     *            {
650     *                for ( i=HALF_SHORT_WINDOW; i>0; i--)
651     *                {
652     *                    *pTime_data_1++ = (*pAux_temp_1++);
653     *                    *pTime_data_2++ = (*pAux_temp_2++);
654     *                }
655     *            }
656     *
657     *        }
658     *
659     *    }
660     *
661     *--------------------------------------------------------------------------*/
662 
663 }   /* trans4m_time_2_freq_fxp */
664